Updates & Fixes
# Updates & Fixes
- New Commands: Added `css_bot_place` which teleports a bot to the player's position with optional godmode and translation support.
- Miner (New Skill): Added a new skill that allows for detonating HE grenades near enemies.
- Bomb Abort Support: Introduced `BombAbortplant` support across `ISkill` and event registration; added handlers for aborting plants in Planter, ChillOut, and other skills.
- System (Rework & Optimization):
- Reworked player event dispatching to call `SkillAction` once per distinct active skill, reducing redundant invocations.
- Switched timing logic to use `Server.CurrentTime` (replacing `EngineTime`).
- Added extensive null and validity guards for player and pawn objects.
- Skill-specific Changes:
- AimLock: Fixed vector/validation issues and updated config defaults (cooldown, duration, and offset).
- AreaReaper: Now uses `BombPlantedHere` state and includes `OnTick` alerts.
- ChillOut & Planter: Improved tracking for planting players with center-print and HUD updates.
- HomingNades: Simplified callbacks and fixed detonation timing.
- Muhammed: Tweaked explosion delay handling and reduced friendly fire damage.
- Core & Utils:
- TraceRay: Implemented `CS2TraceRay` for skills to prevent activation through doors or on dropped weapons.
- Dependencies: Bumped `CounterStrikeSharp.API` to 1.0.364 and `MaxMind.Db` to 5.0.0.
- Bug Fixes: Resolved multiple HUD/print update issues and fixed various translation keys.
This commit is contained in:
parent
8634665983
commit
a8890bde6a
22 changed files with 669 additions and 149 deletions
|
|
@ -15,9 +15,9 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CounterStrikeSharp.API" Version="1.0.363" />
|
||||
<PackageReference Include="CounterStrikeSharp.API" Version="1.0.364" />
|
||||
<PackageReference Include="CS2TraceRay" Version="1.0.9" />
|
||||
<PackageReference Include="MaxMind.Db" Version="4.3.4">
|
||||
<PackageReference Include="MaxMind.Db" Version="5.0.0">
|
||||
</PackageReference>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
|
||||
</ItemGroup>
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ namespace src.command
|
|||
{ SplitCommands(config.NormalCommands.HealCommand.Alias), ("Heal", Command_Heal) },
|
||||
{ SplitCommands(config.NormalCommands.HealthCommand.Alias), ("Set heath", Command_Health) },
|
||||
{ SplitCommands(config.NormalCommands.PlantedBomb.Alias), ("Spawn planted bomb", Command_PlantedBomb) },
|
||||
{ SplitCommands(config.NormalCommands.BotPlace.Alias), ("Place bot on your position", Command_BotPlace) },
|
||||
{ SplitCommands(config.NormalCommands.HudCommand.Alias), ("Enable/Disable HUD", Command_HUD) },
|
||||
{ SplitCommands(config.NormalCommands.SetStaticSkillCommand.Alias), ("Set static skill", Command_SetStaticSkill) },
|
||||
{ SplitCommands(config.NormalCommands.ChangeLanguageCommand.Alias), ("Change language", Command_ChangeLanguage) },
|
||||
|
|
@ -337,7 +338,7 @@ namespace src.command
|
|||
if (int.TryParse(command.GetArg(1), out int health))
|
||||
SkillUtils.AddHealth(pawn, health - pawn.Health, health);
|
||||
|
||||
player.PrintToChat($" {ChatColors.Green}{player.GetTranslation("healed")}");
|
||||
player.PrintToChat($" {ChatColors.Green}{player.GetTranslation("set_health")}");
|
||||
}
|
||||
|
||||
[CommandHelper(minArgs: 0, whoCanExecute: CommandUsage.CLIENT_ONLY)]
|
||||
|
|
@ -358,7 +359,38 @@ namespace src.command
|
|||
if (!int.TryParse(command.GetArg(1), out int time))
|
||||
time = 40;
|
||||
|
||||
bomb.C4Blow = (float)Server.EngineTime + time;
|
||||
bomb.C4Blow = Server.CurrentTime + time;
|
||||
player.PrintToChat($" {ChatColors.Green}{player.GetTranslation("planted_bomb_spawned", [time])}");
|
||||
}
|
||||
|
||||
[CommandHelper(minArgs: 0, whoCanExecute: CommandUsage.CLIENT_ONLY)]
|
||||
private static void Command_BotPlace(CCSPlayerController? player, CommandInfo command)
|
||||
{
|
||||
Debug.WriteToDebug($"Player {player?.PlayerName} used the css_bot_place {command.ArgString} command.");
|
||||
if (player == null || !player.IsValid || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid || player.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
|
||||
if (!string.IsNullOrEmpty(config.NormalCommands.BotPlace.Permissions) && !AdminManager.PlayerHasPermissions(player, config.NormalCommands.BotPlace.Permissions)) return;
|
||||
|
||||
var pawn = player.PlayerPawn.Value;
|
||||
if (!player.PawnIsAlive || pawn.AbsOrigin == null || pawn.AbsRotation == null) return;
|
||||
|
||||
if (!int.TryParse(command.GetArg(1), out int botSlot))
|
||||
botSlot = -1;
|
||||
|
||||
var bot = Utilities.GetPlayers().Where(p => p != null && p.IsValid && p.IsBot && p.PawnIsAlive && (botSlot == -1 || p.Slot == botSlot)).FirstOrDefault();
|
||||
if (bot == null || bot.PlayerPawn.Value == null || !bot.PlayerPawn.Value.IsValid)
|
||||
{
|
||||
player.PrintToChat($" {ChatColors.Green}{player.GetTranslation("bot_placed_not_found")}");
|
||||
return;
|
||||
}
|
||||
|
||||
bot.PlayerPawn.Value.Teleport(new Vector(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z), new QAngle(pawn.AbsRotation.X, pawn.AbsRotation.Y, pawn.AbsRotation.Z), Vector.Zero);
|
||||
|
||||
bot.PlayerPawn.Value.TakesDamage = true;
|
||||
if ((bool.TryParse(command.GetArg(2), out bool godmode) && godmode == true)
|
||||
|| (int.TryParse(command.GetArg(2), out int godmodeInt) && godmodeInt == 1))
|
||||
bot.PlayerPawn.Value.TakesDamage = false;
|
||||
|
||||
player.PrintToChat($" {ChatColors.Green}{player.GetTranslation("bot_placed")}");
|
||||
}
|
||||
|
||||
[CommandHelper(minArgs: 0, whoCanExecute: CommandUsage.CLIENT_ONLY)]
|
||||
|
|
|
|||
|
|
@ -118,8 +118,8 @@ namespace src
|
|||
public Skills SpecialSkill { get; set; }
|
||||
public float? SkillChance { get; set; }
|
||||
public bool IsDrawing { get; set; }
|
||||
public DateTime SkillHudExpired { get; set; }
|
||||
public DateTime SkillDescriptionHudExpired { get; set; }
|
||||
public DateTime SkillHudExpired { get; set; } = Config.LoadedConfig.SkillHudDuration == -1 ? DateTime.MaxValue : DateTime.Now.AddSeconds(Config.LoadedConfig.SkillHudDuration);
|
||||
public DateTime SkillDescriptionHudExpired { get; set; } = Config.LoadedConfig.SkillDescriptionDuration == -1 ? DateTime.MaxValue : DateTime.Now.AddSeconds(Config.LoadedConfig.SkillDescriptionDuration);
|
||||
public string? PrintHTML { get; set; }
|
||||
public bool DisplayHUD { get; set; }
|
||||
public bool SkillUsed = false;
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ public interface ISkill
|
|||
public static void GrenadeThrown(EventGrenadeThrown _) { }
|
||||
|
||||
public static void BombBeginplant(EventBombBeginplant _) { }
|
||||
public static void BombAbortplant(EventBombAbortplant _) { }
|
||||
public static void BombPlanted(EventBombPlanted _) { }
|
||||
public static void BombBegindefuse(EventBombBegindefuse _) { }
|
||||
|
||||
|
|
@ -121,6 +122,7 @@ public enum Skills
|
|||
Magneto,
|
||||
Magnifier,
|
||||
Medic,
|
||||
Miner,
|
||||
MoneySwap,
|
||||
Muhammed,
|
||||
Ninja,
|
||||
|
|
|
|||
|
|
@ -8,6 +8,9 @@ using CounterStrikeSharp.API.Modules.Memory;
|
|||
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
|
||||
using CounterStrikeSharp.API.Modules.UserMessages;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
using CS2TraceRay.Class;
|
||||
using CS2TraceRay.Enum;
|
||||
using CS2TraceRay.Struct;
|
||||
using src.player.skills;
|
||||
using src.utils;
|
||||
using System.Collections.Concurrent;
|
||||
|
|
@ -58,6 +61,7 @@ namespace src.player
|
|||
Instance.RegisterEventHandler<EventGrenadeThrown>(GrenadeThrown);
|
||||
|
||||
Instance.RegisterEventHandler<EventBombBeginplant>(BombBeginplant);
|
||||
Instance.RegisterEventHandler<EventBombAbortplant>(BombAbortplant);
|
||||
Instance.RegisterEventHandler<EventBombPlanted>(BombPlanted);
|
||||
Instance.RegisterEventHandler<EventBombBegindefuse>(BombBegindefuse);
|
||||
|
||||
|
|
@ -82,9 +86,13 @@ namespace src.player
|
|||
{
|
||||
lock (setLock)
|
||||
{
|
||||
foreach (var playerSkill in Instance.SkillPlayer)
|
||||
if (!playerSkill.IsDrawing)
|
||||
Instance.SkillAction(playerSkill.Skill.ToString(), "PlayerMakeSound", [um]);
|
||||
var activeSkills = Instance.SkillPlayer
|
||||
.Where(p => !p.IsDrawing)
|
||||
.Select(p => p.Skill.ToString())
|
||||
.Distinct();
|
||||
|
||||
foreach (string skillName in activeSkills)
|
||||
Instance.SkillAction(skillName, "PlayerMakeSound", [um]);
|
||||
return HookResult.Continue;
|
||||
}
|
||||
}
|
||||
|
|
@ -93,9 +101,13 @@ namespace src.player
|
|||
{
|
||||
lock (setLock)
|
||||
{
|
||||
foreach (var playerSkill in Instance.SkillPlayer)
|
||||
if (!playerSkill.IsDrawing)
|
||||
Instance.SkillAction(playerSkill.Skill.ToString(), "WeaponFire", [@event]);
|
||||
var activeSkills = Instance.SkillPlayer
|
||||
.Where(p => !p.IsDrawing)
|
||||
.Select(p => p.Skill.ToString())
|
||||
.Distinct();
|
||||
|
||||
foreach (string skillName in activeSkills)
|
||||
Instance.SkillAction(skillName, "WeaponFire", [@event]);
|
||||
return HookResult.Continue;
|
||||
}
|
||||
}
|
||||
|
|
@ -104,9 +116,13 @@ namespace src.player
|
|||
{
|
||||
lock (setLock)
|
||||
{
|
||||
foreach (var playerSkill in Instance.SkillPlayer)
|
||||
if (!playerSkill.IsDrawing)
|
||||
Instance.SkillAction(playerSkill.Skill.ToString(), "WeaponEquip", [@event]);
|
||||
var activeSkills = Instance.SkillPlayer
|
||||
.Where(p => !p.IsDrawing)
|
||||
.Select(p => p.Skill.ToString())
|
||||
.Distinct();
|
||||
|
||||
foreach (string skillName in activeSkills)
|
||||
Instance.SkillAction(skillName, "WeaponEquip", [@event]);
|
||||
return HookResult.Continue;
|
||||
}
|
||||
}
|
||||
|
|
@ -115,9 +131,13 @@ namespace src.player
|
|||
{
|
||||
lock (setLock)
|
||||
{
|
||||
foreach (var playerSkill in Instance.SkillPlayer)
|
||||
if (!playerSkill.IsDrawing)
|
||||
Instance.SkillAction(playerSkill.Skill.ToString(), "WeaponPickup", [@event]);
|
||||
var activeSkills = Instance.SkillPlayer
|
||||
.Where(p => !p.IsDrawing)
|
||||
.Select(p => p.Skill.ToString())
|
||||
.Distinct();
|
||||
|
||||
foreach (string skillName in activeSkills)
|
||||
Instance.SkillAction(skillName, "WeaponPickup", [@event]);
|
||||
return HookResult.Continue;
|
||||
}
|
||||
}
|
||||
|
|
@ -126,9 +146,13 @@ namespace src.player
|
|||
{
|
||||
lock (setLock)
|
||||
{
|
||||
foreach (var playerSkill in Instance.SkillPlayer)
|
||||
if (!playerSkill.IsDrawing)
|
||||
Instance.SkillAction(playerSkill.Skill.ToString(), "WeaponReload", [@event]);
|
||||
var activeSkills = Instance.SkillPlayer
|
||||
.Where(p => !p.IsDrawing)
|
||||
.Select(p => p.Skill.ToString())
|
||||
.Distinct();
|
||||
|
||||
foreach (string skillName in activeSkills)
|
||||
Instance.SkillAction(skillName, "WeaponReload", [@event]);
|
||||
return HookResult.Continue;
|
||||
}
|
||||
}
|
||||
|
|
@ -137,9 +161,13 @@ namespace src.player
|
|||
{
|
||||
lock (setLock)
|
||||
{
|
||||
foreach (var playerSkill in Instance.SkillPlayer)
|
||||
if (!playerSkill.IsDrawing)
|
||||
Instance.SkillAction(playerSkill.Skill.ToString(), "GrenadeThrown", [@event]);
|
||||
var activeSkills = Instance.SkillPlayer
|
||||
.Where(p => !p.IsDrawing)
|
||||
.Select(p => p.Skill.ToString())
|
||||
.Distinct();
|
||||
|
||||
foreach (string skillName in activeSkills)
|
||||
Instance.SkillAction(skillName, "GrenadeThrown", [@event]);
|
||||
return HookResult.Continue;
|
||||
}
|
||||
}
|
||||
|
|
@ -148,9 +176,28 @@ namespace src.player
|
|||
{
|
||||
lock (setLock)
|
||||
{
|
||||
foreach (var playerSkill in Instance.SkillPlayer)
|
||||
if (!playerSkill.IsDrawing)
|
||||
Instance.SkillAction(playerSkill.Skill.ToString(), "BombBeginplant", [@event]);
|
||||
var activeSkills = Instance.SkillPlayer
|
||||
.Where(p => !p.IsDrawing)
|
||||
.Select(p => p.Skill.ToString())
|
||||
.Distinct();
|
||||
|
||||
foreach (string skillName in activeSkills)
|
||||
Instance.SkillAction(skillName, "BombBeginplant", [@event]);
|
||||
return HookResult.Continue;
|
||||
}
|
||||
}
|
||||
|
||||
private static HookResult BombAbortplant(EventBombAbortplant @event, GameEventInfo info)
|
||||
{
|
||||
lock (setLock)
|
||||
{
|
||||
var activeSkills = Instance.SkillPlayer
|
||||
.Where(p => !p.IsDrawing)
|
||||
.Select(p => p.Skill.ToString())
|
||||
.Distinct();
|
||||
|
||||
foreach (string skillName in activeSkills)
|
||||
Instance.SkillAction(skillName, "BombAbortplant", [@event]);
|
||||
return HookResult.Continue;
|
||||
}
|
||||
}
|
||||
|
|
@ -159,9 +206,13 @@ namespace src.player
|
|||
{
|
||||
lock (setLock)
|
||||
{
|
||||
foreach (var playerSkill in Instance.SkillPlayer)
|
||||
if (!playerSkill.IsDrawing)
|
||||
Instance.SkillAction(playerSkill.Skill.ToString(), "BombPlanted", [@event]);
|
||||
var activeSkills = Instance.SkillPlayer
|
||||
.Where(p => !p.IsDrawing)
|
||||
.Select(p => p.Skill.ToString())
|
||||
.Distinct();
|
||||
|
||||
foreach (string skillName in activeSkills)
|
||||
Instance.SkillAction(skillName, "BombPlanted", [@event]);
|
||||
return HookResult.Continue;
|
||||
}
|
||||
}
|
||||
|
|
@ -170,9 +221,13 @@ namespace src.player
|
|||
{
|
||||
lock (setLock)
|
||||
{
|
||||
foreach (var playerSkill in Instance.SkillPlayer)
|
||||
if (!playerSkill.IsDrawing)
|
||||
Instance.SkillAction(playerSkill.Skill.ToString(), "BombBegindefuse", [@event]);
|
||||
var activeSkills = Instance.SkillPlayer
|
||||
.Where(p => !p.IsDrawing)
|
||||
.Select(p => p.Skill.ToString())
|
||||
.Distinct();
|
||||
|
||||
foreach (string skillName in activeSkills)
|
||||
Instance.SkillAction(skillName, "BombBegindefuse", [@event]);
|
||||
return HookResult.Continue;
|
||||
}
|
||||
}
|
||||
|
|
@ -181,9 +236,13 @@ namespace src.player
|
|||
{
|
||||
lock (setLock)
|
||||
{
|
||||
foreach (var playerSkill in Instance.SkillPlayer)
|
||||
if (!playerSkill.IsDrawing)
|
||||
Instance.SkillAction(playerSkill.Skill.ToString(), "DecoyStarted", [@event]);
|
||||
var activeSkills = Instance.SkillPlayer
|
||||
.Where(p => !p.IsDrawing)
|
||||
.Select(p => p.Skill.ToString())
|
||||
.Distinct();
|
||||
|
||||
foreach (string skillName in activeSkills)
|
||||
Instance.SkillAction(skillName, "DecoyStarted", [@event]);
|
||||
return HookResult.Continue;
|
||||
}
|
||||
}
|
||||
|
|
@ -192,9 +251,13 @@ namespace src.player
|
|||
{
|
||||
lock (setLock)
|
||||
{
|
||||
foreach (var playerSkill in Instance.SkillPlayer)
|
||||
if (!playerSkill.IsDrawing)
|
||||
Instance.SkillAction(playerSkill.Skill.ToString(), "DecoyDetonate", [@event]);
|
||||
var activeSkills = Instance.SkillPlayer
|
||||
.Where(p => !p.IsDrawing)
|
||||
.Select(p => p.Skill.ToString())
|
||||
.Distinct();
|
||||
|
||||
foreach (string skillName in activeSkills)
|
||||
Instance.SkillAction(skillName, "DecoyDetonate", [@event]);
|
||||
return HookResult.Continue;
|
||||
}
|
||||
}
|
||||
|
|
@ -203,9 +266,13 @@ namespace src.player
|
|||
{
|
||||
lock (setLock)
|
||||
{
|
||||
foreach (var playerSkill in Instance.SkillPlayer)
|
||||
if (!playerSkill.IsDrawing)
|
||||
Instance.SkillAction(playerSkill.Skill.ToString(), "SmokegrenadeDetonate", [@event]);
|
||||
var activeSkills = Instance.SkillPlayer
|
||||
.Where(p => !p.IsDrawing)
|
||||
.Select(p => p.Skill.ToString())
|
||||
.Distinct();
|
||||
|
||||
foreach (string skillName in activeSkills)
|
||||
Instance.SkillAction(skillName, "SmokegrenadeDetonate", [@event]);
|
||||
return HookResult.Continue;
|
||||
}
|
||||
}
|
||||
|
|
@ -214,9 +281,13 @@ namespace src.player
|
|||
{
|
||||
lock (setLock)
|
||||
{
|
||||
foreach (var playerSkill in Instance.SkillPlayer)
|
||||
if (!playerSkill.IsDrawing)
|
||||
Instance.SkillAction(playerSkill.Skill.ToString(), "SmokegrenadeExpired", [@event]);
|
||||
var activeSkills = Instance.SkillPlayer
|
||||
.Where(p => !p.IsDrawing)
|
||||
.Select(p => p.Skill.ToString())
|
||||
.Distinct();
|
||||
|
||||
foreach (string skillName in activeSkills)
|
||||
Instance.SkillAction(skillName, "SmokegrenadeExpired", [@event]);
|
||||
return HookResult.Continue;
|
||||
}
|
||||
}
|
||||
|
|
@ -225,9 +296,13 @@ namespace src.player
|
|||
{
|
||||
lock (setLock)
|
||||
{
|
||||
foreach (var playerSkill in Instance.SkillPlayer)
|
||||
if (!playerSkill.IsDrawing)
|
||||
Instance.SkillAction(playerSkill.Skill.ToString(), "PlayerHurt", [@event]);
|
||||
var activeSkills = Instance.SkillPlayer
|
||||
.Where(p => !p.IsDrawing)
|
||||
.Select(p => p.Skill.ToString())
|
||||
.Distinct();
|
||||
|
||||
foreach (string skillName in activeSkills)
|
||||
Instance.SkillAction(skillName, "PlayerHurt", [@event]);
|
||||
return HookResult.Continue;
|
||||
}
|
||||
}
|
||||
|
|
@ -236,9 +311,13 @@ namespace src.player
|
|||
{
|
||||
lock (setLock)
|
||||
{
|
||||
foreach (var playerSkill in Instance.SkillPlayer)
|
||||
if (!playerSkill.IsDrawing)
|
||||
Instance.SkillAction(playerSkill.Skill.ToString(), "PlayerJump", [@event]);
|
||||
var activeSkills = Instance.SkillPlayer
|
||||
.Where(p => !p.IsDrawing)
|
||||
.Select(p => p.Skill.ToString())
|
||||
.Distinct();
|
||||
|
||||
foreach (string skillName in activeSkills)
|
||||
Instance.SkillAction(skillName, "PlayerJump", [@event]);
|
||||
return HookResult.Continue;
|
||||
}
|
||||
}
|
||||
|
|
@ -247,9 +326,13 @@ namespace src.player
|
|||
{
|
||||
lock (setLock)
|
||||
{
|
||||
foreach (var playerSkill in Instance.SkillPlayer)
|
||||
if (!playerSkill.IsDrawing)
|
||||
Instance.SkillAction(playerSkill.Skill.ToString(), "PlayerBlind", [@event]);
|
||||
var activeSkills = Instance.SkillPlayer
|
||||
.Where(p => !p.IsDrawing)
|
||||
.Select(p => p.Skill.ToString())
|
||||
.Distinct();
|
||||
|
||||
foreach (string skillName in activeSkills)
|
||||
Instance.SkillAction(skillName, "PlayerBlind", [@event]);
|
||||
return HookResult.Continue;
|
||||
}
|
||||
}
|
||||
|
|
@ -258,9 +341,13 @@ namespace src.player
|
|||
{
|
||||
lock (setLock)
|
||||
{
|
||||
foreach (var playerSkill in Instance.SkillPlayer)
|
||||
if (!playerSkill.IsDrawing)
|
||||
Instance.SkillAction(playerSkill.Skill.ToString(), "OnTakeDamage", [h]);
|
||||
var activeSkills = Instance.SkillPlayer
|
||||
.Where(p => !p.IsDrawing)
|
||||
.Select(p => p.Skill.ToString())
|
||||
.Distinct();
|
||||
|
||||
foreach (string skillName in activeSkills)
|
||||
Instance.SkillAction(skillName, "OnTakeDamage", [h]);
|
||||
return HookResult.Continue;
|
||||
}
|
||||
}
|
||||
|
|
@ -272,9 +359,13 @@ namespace src.player
|
|||
CBaseTrigger trigger = hook.GetParam<CBaseTrigger>(0);
|
||||
CBaseEntity entity = hook.GetParam<CBaseEntity>(1);
|
||||
|
||||
foreach (var playerSkill in Instance.SkillPlayer)
|
||||
if (!playerSkill.IsDrawing)
|
||||
Instance.SkillAction(playerSkill.Skill.ToString(), "OnTriggerEnter", [trigger, entity]);
|
||||
var activeSkills = Instance.SkillPlayer
|
||||
.Where(p => !p.IsDrawing)
|
||||
.Select(p => p.Skill.ToString())
|
||||
.Distinct();
|
||||
|
||||
foreach (string skillName in activeSkills)
|
||||
Instance.SkillAction(skillName, "OnTriggerEnter", [trigger, entity]);
|
||||
return HookResult.Continue;
|
||||
}
|
||||
}
|
||||
|
|
@ -286,9 +377,13 @@ namespace src.player
|
|||
CBaseTrigger trigger = hook.GetParam<CBaseTrigger>(0);
|
||||
CBaseEntity entity = hook.GetParam<CBaseEntity>(1);
|
||||
|
||||
foreach (var playerSkill in Instance.SkillPlayer)
|
||||
if (!playerSkill.IsDrawing)
|
||||
Instance.SkillAction(playerSkill.Skill.ToString(), "OnTriggerExit", [trigger, entity]);
|
||||
var activeSkills = Instance.SkillPlayer
|
||||
.Where(p => !p.IsDrawing)
|
||||
.Select(p => p.Skill.ToString())
|
||||
.Distinct();
|
||||
|
||||
foreach (string skillName in activeSkills)
|
||||
Instance.SkillAction(skillName, "OnTriggerExit", [trigger, entity]);
|
||||
return HookResult.Continue;
|
||||
}
|
||||
}
|
||||
|
|
@ -297,12 +392,18 @@ namespace src.player
|
|||
{
|
||||
lock (setLock)
|
||||
{
|
||||
foreach (var playerSkill in Instance.SkillPlayer)
|
||||
if (!playerSkill.IsDrawing)
|
||||
if (SkillsInfo.GetValue<bool>(playerSkill.Skill, "disableOnFreezeTime") && SkillUtils.IsFreezeTime())
|
||||
return;
|
||||
var activeSkills = Instance.SkillPlayer
|
||||
.Where(p => !p.IsDrawing)
|
||||
.Select(p => p.Skill)
|
||||
.Distinct()
|
||||
.OrderBy(skill => skill.ToString() == "AreaReaper")
|
||||
.ThenBy(skill => skill.ToString() == "ChillOut");
|
||||
|
||||
foreach (var skill in activeSkills)
|
||||
if (SkillsInfo.GetValue<bool>(skill, "disableOnFreezeTime") && SkillUtils.IsFreezeTime())
|
||||
continue;
|
||||
else
|
||||
Instance.SkillAction(playerSkill.Skill.ToString(), "OnTick");
|
||||
Instance.SkillAction(skill.ToString(), "OnTick");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -528,9 +629,13 @@ namespace src.player
|
|||
{
|
||||
lock (setLock)
|
||||
{
|
||||
foreach (var playerSkill in Instance.SkillPlayer)
|
||||
if (!playerSkill.IsDrawing)
|
||||
Instance.SkillAction(playerSkill.Skill.ToString(), "PlayerDeath", [@event]);
|
||||
var activeSkills = Instance.SkillPlayer
|
||||
.Where(p => !p.IsDrawing)
|
||||
.Select(p => p.Skill.ToString())
|
||||
.Distinct();
|
||||
|
||||
foreach (string skillName in activeSkills)
|
||||
Instance.SkillAction(skillName, "PlayerDeath", [@event]);
|
||||
|
||||
var victim = @event.Userid;
|
||||
var attacker = @event.Attacker;
|
||||
|
|
@ -562,28 +667,48 @@ namespace src.player
|
|||
|
||||
private static void CheckUseSkill(CCSPlayerController player, PlayerButtons pressed, PlayerButtons released)
|
||||
{
|
||||
if (player == null || !player.IsValid || !player.PawnIsAlive) return;
|
||||
|
||||
lock (setLock)
|
||||
{
|
||||
string? button = Config.LoadedConfig.AlternativeSkillButton;
|
||||
if (string.IsNullOrEmpty(button) || button.Length < 2) return;
|
||||
|
||||
string buttonName = $"{char.ToUpper(button[0])}{button[1..].ToLower()}";
|
||||
if (!Enum.TryParse<PlayerButtons>(buttonName, out var skillButton)) return;
|
||||
|
||||
if (Enum.TryParse<PlayerButtons>(buttonName, out var skillButton))
|
||||
{
|
||||
if (pressed != skillButton) return;
|
||||
}
|
||||
else return;
|
||||
if ((pressed & skillButton) == 0) return;
|
||||
|
||||
if (player == null) return;
|
||||
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
|
||||
if (playerInfo == null || playerInfo.IsDrawing) return;
|
||||
|
||||
if (SkillsInfo.GetValue<bool>(playerInfo.Skill, "disableOnFreezeTime") && SkillUtils.IsFreezeTime())
|
||||
return;
|
||||
|
||||
var playerPawn = player.PlayerPawn.Value;
|
||||
if (playerPawn?.CBodyComponent == null) return;
|
||||
if (!player.IsValid || !player.PawnIsAlive) return;
|
||||
if (skillButton == PlayerButtons.Use)
|
||||
{
|
||||
var pawn = player.PlayerPawn.Value;
|
||||
if (pawn == null || !pawn.IsValid) return;
|
||||
if (pawn.AbsOrigin == null || pawn.AbsRotation == null) return;
|
||||
|
||||
if (pawn.IsDefusing) return;
|
||||
|
||||
Vector eyePos = new(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z + pawn.ViewOffset.Z);
|
||||
Vector endPos = eyePos + SkillUtils.GetForwardVector(pawn.EyeAngles) * 80;
|
||||
|
||||
ulong mask = pawn.Collision.CollisionAttribute.InteractsWith | (ulong)(Contents.Solid | Contents.Hitbox | Contents.Pickup | Contents.TouchAll | Contents.CarriedObject | Contents.CarriedWeapon | Contents.Debris);
|
||||
ulong contents = 0;
|
||||
CGameTrace trace = TraceRay.TraceShape(eyePos, endPos, mask, contents, player);
|
||||
|
||||
if (trace.DidHit())
|
||||
{
|
||||
var entity = Activator.CreateInstance(typeof(CBaseEntity), trace.HitEntity) as CBaseEntity;
|
||||
if (entity == null || !entity.IsValid) return;
|
||||
|
||||
string designer = entity.DesignerName;
|
||||
if (designer.Contains("door") || designer.Contains("button") || designer.Contains("weapon") || designer.Contains("blocker")) return;
|
||||
}
|
||||
}
|
||||
|
||||
Debug.WriteToDebug($"Player {player.PlayerName} used the skill: {playerInfo.Skill} by PlayerButtons: {pressed}");
|
||||
Instance.SkillAction(playerInfo.Skill.ToString(), "UseSkill", [player]);
|
||||
|
|
@ -594,9 +719,13 @@ namespace src.player
|
|||
{
|
||||
lock (setLock)
|
||||
{
|
||||
foreach (var playerSkill in Instance.SkillPlayer)
|
||||
if (!playerSkill.IsDrawing)
|
||||
Instance.SkillAction(playerSkill.Skill.ToString(), "OnEntitySpawned", [entity]);
|
||||
var activeSkills = Instance.SkillPlayer
|
||||
.Where(p => !p.IsDrawing)
|
||||
.Select(p => p.Skill.ToString())
|
||||
.Distinct();
|
||||
|
||||
foreach (string skillName in activeSkills)
|
||||
Instance.SkillAction(skillName, "OnEntitySpawned", [entity]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -722,8 +851,12 @@ namespace src.player
|
|||
});
|
||||
|
||||
Debug.WriteToDebug($"Player {skillPlayer.PlayerName} has got the skill \"{player.GetSkillName(randomSkill.Skill)}\".");
|
||||
skillPlayer.SkillHudExpired = DateTime.Now.AddSeconds(Config.LoadedConfig.SkillHudDuration);
|
||||
skillPlayer.SkillDescriptionHudExpired = DateTime.Now.AddSeconds(Config.LoadedConfig.SkillDescriptionDuration);
|
||||
|
||||
float hudExpired = Config.LoadedConfig.SkillHudDuration;
|
||||
skillPlayer.SkillHudExpired = hudExpired == -1 ? DateTime.MaxValue : DateTime.Now.AddSeconds(hudExpired);
|
||||
|
||||
float descriptionHudExpired = Config.LoadedConfig.SkillHudDuration;
|
||||
skillPlayer.SkillDescriptionHudExpired = descriptionHudExpired == -1 ? DateTime.MaxValue : DateTime.Now.AddSeconds(descriptionHudExpired);
|
||||
|
||||
if (Config.LoadedConfig.TeamMateSkillChatInfo)
|
||||
{
|
||||
|
|
@ -859,9 +992,13 @@ namespace src.player
|
|||
{
|
||||
lock (setLock)
|
||||
{
|
||||
foreach (var playerSkill in Instance.SkillPlayer)
|
||||
if (!playerSkill.IsDrawing)
|
||||
Instance.SkillAction(playerSkill.Skill.ToString(), "CheckTransmit", [infoList]);
|
||||
var activeSkills = Instance.SkillPlayer
|
||||
.Where(p => !p.IsDrawing)
|
||||
.Select(p => p.Skill.ToString())
|
||||
.Distinct();
|
||||
|
||||
foreach (string skillName in activeSkills)
|
||||
Instance.SkillAction(skillName, "CheckTransmit", [infoList]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -121,6 +121,7 @@ namespace src.player
|
|||
if (string.IsNullOrEmpty(skillLine)) return;
|
||||
if (player == null || !player.IsValid) return;
|
||||
if (SkillUtils.HasMenu(player)) return;
|
||||
|
||||
Event.UpdateSkillHUD(player, infoLine, skillLine, remainingLine, isDescription);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,12 @@ namespace src.player.skills
|
|||
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
|
||||
if (playerInfo?.Skill == skillName)
|
||||
if (SkillPlayerInfo.TryGetValue(player.SteamID, out var skillInfo))
|
||||
{
|
||||
UpdateHUD(player, skillInfo);
|
||||
|
||||
if (skillInfo.Cooldown.AddSeconds(SkillsInfo.GetValue<float>(skillName, "duration")) > DateTime.Now)
|
||||
LookAtEnemey(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -100,7 +105,7 @@ namespace src.player.skills
|
|||
foreach (var enemy in Utilities.GetPlayers().Where(p => p.IsValid && p.PawnIsAlive && p.Team != player.Team))
|
||||
{
|
||||
var enemyPawn = enemy.PlayerPawn.Value;
|
||||
if (enemyPawn == null || !enemyPawn.IsValid || enemyPawn.AbsOrigin == null) return;
|
||||
if (enemyPawn == null || !enemyPawn.IsValid || enemyPawn.AbsOrigin == null) continue;
|
||||
|
||||
double dist = SkillUtils.GetDistance(enemyPawn.AbsOrigin, pawn.AbsOrigin);
|
||||
if (dist < minDist)
|
||||
|
|
@ -112,11 +117,13 @@ namespace src.player.skills
|
|||
|
||||
if (closetEnemy != null)
|
||||
{
|
||||
Vector enemyPos = closetEnemy.PlayerPawn.Value!.AbsOrigin!;
|
||||
Vector myPos = pawn.AbsOrigin;
|
||||
var enemyPawn = closetEnemy.PlayerPawn.Value;
|
||||
if (enemyPawn == null || enemyPawn.AbsOrigin == null) return;
|
||||
|
||||
Vector myEyePos = new(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z + pawn.ViewOffset.Z);
|
||||
Vector enemyEyePos = new(enemyPawn.AbsOrigin.X, enemyPawn.AbsOrigin.Y, enemyPawn.AbsOrigin.Z + enemyPawn.ViewOffset.Z + SkillsInfo.GetValue<float>(skillName, "offsetZ"));
|
||||
|
||||
Vector direction = enemyPos - myPos;
|
||||
Vector direction = enemyEyePos - myEyePos;
|
||||
QAngle angle = VectorToAngle(direction);
|
||||
|
||||
pawn.Look(angle);
|
||||
|
|
@ -138,9 +145,11 @@ namespace src.player.skills
|
|||
public DateTime Cooldown { get; set; }
|
||||
}
|
||||
|
||||
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#fa7b48", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = true, bool needsTeammates = false, string requiredPermission = "", float cooldown = 5f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
|
||||
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#fa7b48", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = true, bool needsTeammates = false, string requiredPermission = "", float cooldown = 20f, float duration = .3f, float offsetZ = 0) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
|
||||
{
|
||||
public float Cooldown { get; set; } = cooldown;
|
||||
public float Duration { get; set; } = duration;
|
||||
public float Offset { get; set; } = offsetZ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
using CounterStrikeSharp.API;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
using static src.jRandomSkills;
|
||||
using src.utils;
|
||||
using static src.jRandomSkills;
|
||||
|
||||
namespace src.player.skills
|
||||
{
|
||||
|
|
@ -21,7 +21,6 @@ namespace src.player.skills
|
|||
{
|
||||
foreach (var player in Utilities.GetPlayers())
|
||||
SkillUtils.CloseMenu(player);
|
||||
Instance.AddTimer(0.1f, EnableBombsite);
|
||||
}
|
||||
|
||||
public static void TypeSkill(CCSPlayerController player, string[] commands)
|
||||
|
|
@ -44,7 +43,9 @@ namespace src.player.skills
|
|||
var bombTargets = Utilities.FindAllEntitiesByDesignerName<CBombTarget>("func_bomb_target").ToArray();
|
||||
if (bombTargets.Length == 2)
|
||||
{
|
||||
bombTargets[site].AcceptInput("Disable");
|
||||
bombTargets[site].BombPlantedHere = true;
|
||||
Utilities.SetStateChanged(bombTargets[site], "CBombTarget", "m_bBombPlantedHere");
|
||||
|
||||
playerInfo.SkillUsed = true;
|
||||
player.PrintToChat($" {ChatColors.Green}{player.GetTranslation("areareaper_site_disabled", (site == 0 ? 'A' : 'B'))}");
|
||||
}
|
||||
|
|
@ -63,16 +64,43 @@ namespace src.player.skills
|
|||
public static void DisableSkill(CCSPlayerController player)
|
||||
{
|
||||
SkillUtils.CloseMenu(player);
|
||||
if (Instance.SkillPlayer.FirstOrDefault(p => p.Skill == skillName) != null) return;
|
||||
EnableBombsite();
|
||||
|
||||
Server.NextWorldUpdate(() =>
|
||||
{
|
||||
if (Instance.SkillPlayer.FirstOrDefault(p => p.Skill == skillName) != null) return;
|
||||
EnableBombsite();
|
||||
});
|
||||
}
|
||||
|
||||
private static void EnableBombsite()
|
||||
{
|
||||
var bombTargets = Utilities.FindAllEntitiesByDesignerName<CBombTarget>("func_bomb_target");
|
||||
foreach (var bombTarget in bombTargets)
|
||||
bombTarget.AcceptInput("Enable");
|
||||
{
|
||||
bombTarget.BombPlantedHere = false;
|
||||
Utilities.SetStateChanged(bombTarget, "CBombTarget", "m_bBombPlantedHere");
|
||||
}
|
||||
}
|
||||
|
||||
public static void OnTick()
|
||||
{
|
||||
var bombTargets = Utilities.FindAllEntitiesByDesignerName<CBombTarget>("func_bomb_target");
|
||||
foreach (var player in Utilities.GetPlayers().Where(p => p.Team == CsTeam.Terrorist))
|
||||
{
|
||||
if (!Instance.IsPlayerValid(player)) continue;
|
||||
|
||||
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
|
||||
if (playerInfo?.Skill == null) continue;
|
||||
|
||||
var pawn = player.PlayerPawn.Value;
|
||||
if (pawn == null || !pawn.IsValid) continue;
|
||||
|
||||
if (pawn.WeaponServices == null) continue;
|
||||
var activeWeapon = pawn.WeaponServices.ActiveWeapon.Value;
|
||||
if (activeWeapon == null || !activeWeapon.IsValid || activeWeapon.DesignerName != "weapon_c4") continue;
|
||||
|
||||
if (!pawn.InBombZone && pawn.InBombZoneTrigger)
|
||||
player.PrintToCenterAlert(player.GetTranslation("areareaper_bombsite_disabled"));
|
||||
}
|
||||
}
|
||||
|
||||
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#edf5b5", CsTeam onlyTeam = CsTeam.CounterTerrorist, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "") : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ using CounterStrikeSharp.API;
|
|||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
using src.utils;
|
||||
using System.Collections.Concurrent;
|
||||
using static src.jRandomSkills;
|
||||
|
||||
namespace src.player.skills
|
||||
|
|
@ -9,16 +10,38 @@ namespace src.player.skills
|
|||
public class ChillOut : ISkill
|
||||
{
|
||||
private const Skills skillName = Skills.ChillOut;
|
||||
private static readonly ConcurrentDictionary<ulong, float> plantingPlayers = [];
|
||||
|
||||
public static void LoadSkill()
|
||||
{
|
||||
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
|
||||
}
|
||||
|
||||
public static void NewRound()
|
||||
{
|
||||
plantingPlayers.Clear();
|
||||
}
|
||||
|
||||
public static void DisableSkill(CCSPlayerController player)
|
||||
{
|
||||
if (player == null || !player.IsValid) return;
|
||||
plantingPlayers.TryRemove(player.SteamID, out _);
|
||||
SkillUtils.ResetPrintHTML(player);
|
||||
}
|
||||
|
||||
public static void BombAbortplant(EventBombAbortplant @event)
|
||||
{
|
||||
var user = @event.Userid;
|
||||
if (user == null || !user.IsValid || !user.PawnIsAlive) return;
|
||||
plantingPlayers.TryRemove(user.SteamID, out _);
|
||||
SkillUtils.ResetPrintHTML(user);
|
||||
}
|
||||
|
||||
public static void BombBeginplant(EventBombBeginplant @event)
|
||||
{
|
||||
var player = @event.Userid;
|
||||
if (!Instance.IsPlayerValid(player)) return;
|
||||
plantingPlayers.TryAdd(player!.SteamID, Server.CurrentTime);
|
||||
|
||||
var anyChillOut = Instance.SkillPlayer.FirstOrDefault(p => p.Skill == skillName);
|
||||
if (anyChillOut != null)
|
||||
|
|
@ -33,6 +56,42 @@ namespace src.player.skills
|
|||
}
|
||||
}
|
||||
|
||||
public static void BombPlanted(EventBombPlanted @event)
|
||||
{
|
||||
var player = @event.Userid;
|
||||
if (!Instance.IsPlayerValid(player)) return;
|
||||
plantingPlayers.TryRemove(player!.SteamID, out _);
|
||||
SkillUtils.ResetPrintHTML(player);
|
||||
}
|
||||
|
||||
public static void OnTick()
|
||||
{
|
||||
float currentTime = Server.CurrentTime;
|
||||
float extraTime = SkillsInfo.GetValue<float>(skillName, "bombArmedTime");
|
||||
|
||||
foreach (var player in Utilities.GetPlayers().Where(p => p.Team == CsTeam.Terrorist))
|
||||
{
|
||||
if (!Instance.IsPlayerValid(player)) continue;
|
||||
|
||||
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
|
||||
if (playerInfo == null) continue;
|
||||
|
||||
var pawn = player.PlayerPawn.Value;
|
||||
if (pawn == null || !pawn.IsValid) continue;
|
||||
|
||||
if (pawn.WeaponServices == null) continue;
|
||||
var activeWeapon = pawn.WeaponServices.ActiveWeapon.Value;
|
||||
if (activeWeapon == null || !activeWeapon.IsValid || activeWeapon.DesignerName != "weapon_c4") continue;
|
||||
|
||||
if (plantingPlayers.TryGetValue(player.SteamID, out float plantTime))
|
||||
{
|
||||
float remaining = plantTime + extraTime - currentTime;
|
||||
playerInfo.PrintHTML = $"{player.GetTranslation("planter_planting", $"<font color='#00FF00'>{Math.Max(0, remaining):0.0}s</font>")}";
|
||||
player.PrintToCenter("");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#343deb", CsTeam onlyTeam = CsTeam.CounterTerrorist, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float bombArmedTime = 10f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
|
||||
{
|
||||
public float BombArmedTime { get; set; } = bombArmedTime;
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ namespace src.player.skills
|
|||
public class HomingNades : ISkill
|
||||
{
|
||||
private const Skills skillName = Skills.HomingNades;
|
||||
private readonly static ConcurrentDictionary<uint, (Vector, double)> nades = [];
|
||||
private readonly static ConcurrentDictionary<uint, Vector> nades = [];
|
||||
|
||||
public static void LoadSkill()
|
||||
{
|
||||
|
|
@ -30,7 +30,7 @@ namespace src.player.skills
|
|||
foreach (var index in nades.Keys.ToList())
|
||||
{
|
||||
if (!nades.TryGetValue(index, out var data)) continue;
|
||||
(Vector oldPos, double createdTime) = data;
|
||||
Vector oldPos = data;
|
||||
|
||||
var nade = Utilities.GetEntityFromIndex<CBaseCSGrenadeProjectile>((int)index);
|
||||
if (nade == null || !nade.IsValid || nade.AbsOrigin == null)
|
||||
|
|
@ -43,14 +43,13 @@ namespace src.player.skills
|
|||
double distanceMoved = SkillUtils.GetDistance(currentPos, oldPos);
|
||||
Vector calculatedVelocity = CalculateVelocity(nade, nade.TeamNum);
|
||||
|
||||
Server.PrintToChatAll($"Dist: {distanceMoved}, vel: {calculatedVelocity}");
|
||||
bool isZero = calculatedVelocity.IsZero();
|
||||
|
||||
if (distanceMoved < 4 || calculatedVelocity.IsZero())
|
||||
if (distanceMoved < 4 || isZero)
|
||||
{
|
||||
Server.PrintToChatAll($"Short, {Server.TickedTime} -> {createdTime + 3}, {createdTime + 3 - Server.TickedTime}s");
|
||||
|
||||
nade.DetonateTime = (float)createdTime + 3;
|
||||
nade.DetonateTime = isZero ? 0 : nade.CreateTime + 3;
|
||||
Utilities.SetStateChanged(nade, "CBaseGrenade", "m_flDetonateTime");
|
||||
|
||||
nades.TryRemove(index, out _);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -63,7 +62,7 @@ namespace src.player.skills
|
|||
if (speed > maxVelocity)
|
||||
newVelocity *= (maxVelocity / speed);
|
||||
|
||||
nades[index] = (currentPos, createdTime);
|
||||
nades[index] = currentPos;
|
||||
nade.Teleport(null, null, newVelocity);
|
||||
}
|
||||
}
|
||||
|
|
@ -84,9 +83,6 @@ namespace src.player.skills
|
|||
double dist = SkillUtils.GetDistance(nadePos, pawn.AbsOrigin);
|
||||
if (dist < SkillsInfo.GetValue<float>(skillName, "detonationRange"))
|
||||
{
|
||||
nade.DetonateTime = 0;
|
||||
Utilities.SetStateChanged(nade, "CBaseGrenade", "m_flDetonateTime");
|
||||
|
||||
nades.TryRemove(nade.Index, out _);
|
||||
return Vector.Zero;
|
||||
}
|
||||
|
|
@ -134,10 +130,15 @@ namespace src.player.skills
|
|||
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
|
||||
if (playerInfo?.Skill != skillName) return;
|
||||
|
||||
grenade.DetonateTime = (float)Server.TickedTime + 6;
|
||||
|
||||
Vector pos = new(grenade.AbsOrigin?.X, grenade.AbsOrigin?.Y, grenade.AbsOrigin?.Z);
|
||||
nades.TryAdd(grenade.Index, (pos, Server.TickedTime));
|
||||
nades.TryAdd(grenade.Index, pos);
|
||||
|
||||
Server.NextWorldUpdate(() =>
|
||||
{
|
||||
if (grenade == null || !grenade.IsValid) return;
|
||||
grenade.DetonateTime += 100f;
|
||||
Utilities.SetStateChanged(grenade, "CBaseGrenade", "m_flDetonateTime");
|
||||
});
|
||||
}
|
||||
|
||||
public static void EnableSkill(CCSPlayerController player)
|
||||
|
|
|
|||
113
jRandomSkills - SRC Files/src/player/skills/Miner.cs
Normal file
113
jRandomSkills - SRC Files/src/player/skills/Miner.cs
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
using CounterStrikeSharp.API;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Modules.Entities.Constants;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
using src.utils;
|
||||
using System.Collections.Concurrent;
|
||||
using static src.jRandomSkills;
|
||||
|
||||
namespace src.player.skills
|
||||
{
|
||||
public class Miner : ISkill
|
||||
{
|
||||
private const Skills skillName = Skills.Miner;
|
||||
private readonly static ConcurrentDictionary<uint, byte> nades = [];
|
||||
|
||||
public static void LoadSkill()
|
||||
{
|
||||
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
|
||||
}
|
||||
|
||||
public static void NewRound()
|
||||
{
|
||||
nades.Clear();
|
||||
}
|
||||
|
||||
public static void OnTick()
|
||||
{
|
||||
if (Server.TickCount % 10 != 0) return;
|
||||
float detonationRange = SkillsInfo.GetValue<float>(skillName, "detonationRange");
|
||||
float currentTime = Server.CurrentTime;
|
||||
|
||||
foreach (var index in nades.Keys.ToList())
|
||||
{
|
||||
var nade = Utilities.GetEntityFromIndex<CBaseCSGrenadeProjectile>((int)index);
|
||||
if (nade == null || !nade.IsValid || nade.AbsOrigin == null)
|
||||
{
|
||||
nades.TryRemove(index, out _);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nade.CreateTime + 3 > currentTime) return;
|
||||
Vector currentPos = new(nade.AbsOrigin.X, nade.AbsOrigin.Y, nade.AbsOrigin.Z);
|
||||
|
||||
foreach (var enemy in Utilities.GetPlayers().Where(p => p.IsValid && p.PawnIsAlive && p.TeamNum != nade.TeamNum))
|
||||
{
|
||||
var enemyPawn = enemy.PlayerPawn.Value;
|
||||
if (enemyPawn == null || !enemyPawn.IsValid || enemyPawn.AbsOrigin == null) continue;
|
||||
|
||||
Vector enemyPos = new(enemyPawn.AbsOrigin.X, enemyPawn.AbsOrigin.Y, enemyPawn.AbsOrigin.Z);
|
||||
double distance = SkillUtils.GetDistance(currentPos, enemyPos);
|
||||
|
||||
if (distance <= detonationRange)
|
||||
{
|
||||
Detonate(nade);
|
||||
nades.TryRemove(index, out _);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void Detonate(CBaseCSGrenadeProjectile grenade)
|
||||
{
|
||||
if (grenade == null || !grenade.IsValid || grenade.AbsOrigin == null) return;
|
||||
|
||||
Vector position = grenade.AbsOrigin;
|
||||
position.Z += 60;
|
||||
grenade.Teleport(position);
|
||||
|
||||
grenade.EmitSound("IncGrenade.Bounce_M");
|
||||
|
||||
grenade.DetonateTime = Server.CurrentTime + .5f;
|
||||
Utilities.SetStateChanged(grenade, "CBaseGrenade", "m_flDetonateTime");
|
||||
}
|
||||
|
||||
public static void OnEntitySpawned(CEntityInstance @event)
|
||||
{
|
||||
var name = @event.DesignerName;
|
||||
if (name != "hegrenade_projectile") return;
|
||||
|
||||
var grenade = @event.As<CBaseCSGrenadeProjectile>();
|
||||
if (grenade == null || !grenade.IsValid) return;
|
||||
|
||||
if (grenade.OwnerEntity.Value == null || !grenade.OwnerEntity.Value.IsValid) return;
|
||||
var pawn = grenade.OwnerEntity.Value.As<CCSPlayerPawn>();
|
||||
|
||||
if (pawn.Controller.Value == null || !pawn.Controller.Value.IsValid) return;
|
||||
var player = pawn.Controller.Value.As<CCSPlayerController>();
|
||||
|
||||
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
|
||||
if (playerInfo?.Skill != skillName) return;
|
||||
|
||||
nades.TryAdd(grenade.Index, 0);
|
||||
|
||||
Server.NextWorldUpdate(() =>
|
||||
{
|
||||
if (grenade == null || !grenade.IsValid) return;
|
||||
grenade.DetonateTime = float.MaxValue;
|
||||
Utilities.SetStateChanged(grenade, "CBaseGrenade", "m_flDetonateTime");
|
||||
});
|
||||
}
|
||||
|
||||
public static void EnableSkill(CCSPlayerController player)
|
||||
{
|
||||
SkillUtils.TryGiveWeapon(player, CsItem.HEGrenade);
|
||||
}
|
||||
|
||||
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#adf542", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float detonationRange = 130) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
|
||||
{
|
||||
public float DetonationRange { get; set; } = detonationRange;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,9 @@
|
|||
using CounterStrikeSharp.API;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
using src.utils;
|
||||
using System.Collections.Concurrent;
|
||||
using static src.jRandomSkills;
|
||||
using Vector = CounterStrikeSharp.API.Modules.Utils.Vector;
|
||||
|
||||
|
|
@ -11,20 +13,37 @@ namespace src.player.skills
|
|||
{
|
||||
private const Skills skillName = Skills.Muhammed;
|
||||
private static readonly QAngle angle = new(10, -5, 9);
|
||||
private static readonly ConcurrentDictionary<int, byte> nades = [];
|
||||
|
||||
public static void LoadSkill()
|
||||
{
|
||||
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
|
||||
}
|
||||
|
||||
public static void NewRound()
|
||||
{
|
||||
nades.Clear();
|
||||
}
|
||||
|
||||
public static void PlayerDeath(EventPlayerDeath @event)
|
||||
{
|
||||
var player = @event.Userid;
|
||||
if (!IsDeadPlayerValid(player)) return;
|
||||
|
||||
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player?.SteamID);
|
||||
if (playerInfo?.Skill == skillName)
|
||||
SpawnExplosion(player!);
|
||||
CsTeam lastTeam = player!.Team;
|
||||
|
||||
Server.NextWorldUpdate(() =>
|
||||
{
|
||||
|
||||
if (player == null || !player.IsValid || player.Team != lastTeam) return;
|
||||
|
||||
var pawn = player.PlayerPawn.Value;
|
||||
if (pawn == null || !pawn.IsValid || pawn.Health == pawn.MaxHealth) return;
|
||||
|
||||
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player?.SteamID);
|
||||
if (playerInfo?.Skill == skillName)
|
||||
SpawnExplosion(player!);
|
||||
});
|
||||
}
|
||||
|
||||
private static void SpawnExplosion(CCSPlayerController player)
|
||||
|
|
@ -32,7 +51,7 @@ namespace src.player.skills
|
|||
var pawn = player.PlayerPawn.Value;
|
||||
if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) return;
|
||||
|
||||
Vector pos = pawn.AbsOrigin;
|
||||
Vector pos = new(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z);
|
||||
pos.Z += 10;
|
||||
|
||||
SkillUtils.CreateHEGrenadeProjectile(pos, angle, new Vector(0, 0, -10), player.TeamNum);
|
||||
|
|
@ -44,6 +63,8 @@ namespace src.player.skills
|
|||
var fileNames = new[] { "radiobotfallback01", "radiobotfallback02", "radiobotfallback04" };
|
||||
var randomFile = fileNames[new Random().Next(fileNames.Length)];
|
||||
player.ExecuteClientCommand($"play vo/agents/balkan/{randomFile}.vsnd");
|
||||
|
||||
nades.AddOrUpdate(Server.TickCount, player.TeamNum, (_, _) => player.TeamNum);
|
||||
}
|
||||
|
||||
public static void OnEntitySpawned(CEntityInstance entity)
|
||||
|
|
@ -53,6 +74,8 @@ namespace src.player.skills
|
|||
var heProjectile = entity.As<CBaseCSGrenadeProjectile>();
|
||||
if (heProjectile == null || !heProjectile.IsValid || heProjectile.AbsRotation == null) return;
|
||||
|
||||
int lastTick = Server.TickCount;
|
||||
|
||||
Server.NextFrame(() =>
|
||||
{
|
||||
if (heProjectile == null || !heProjectile.IsValid) return;
|
||||
|
|
@ -63,9 +86,37 @@ namespace src.player.skills
|
|||
heProjectile.Damage = SkillsInfo.GetValue<int>(skillName, "explosionDamage");
|
||||
heProjectile.DmgRadius = SkillsInfo.GetValue<float>(skillName, "explosionRadius");
|
||||
heProjectile.DetonateTime = 0;
|
||||
|
||||
if (nades.TryRemove(lastTick, out byte teamNum))
|
||||
heProjectile.Globalname = $"muhammed_team_{teamNum}_{heProjectile.Index}";
|
||||
});
|
||||
}
|
||||
|
||||
public static void OnTakeDamage(DynamicHook h)
|
||||
{
|
||||
CEntityInstance param = h.GetParam<CEntityInstance>(0);
|
||||
CTakeDamageInfo param2 = h.GetParam<CTakeDamageInfo>(1);
|
||||
|
||||
if (param == null || param.Entity == null || param2 == null) return;
|
||||
|
||||
var nade = param2.Attacker.Value;
|
||||
if (nade == null || !nade.IsValid) return;
|
||||
|
||||
if (nade.DesignerName != "hegrenade_projectile") return;
|
||||
if (string.IsNullOrEmpty(nade.Globalname) || !nade.Globalname.StartsWith("muhammed_team_")) return;
|
||||
|
||||
if (!int.TryParse(nade.Globalname.Split('_')[2], out int nadeTeam)) return;
|
||||
|
||||
CCSPlayerPawn victimPawn = new(param.Handle);
|
||||
|
||||
if (victimPawn.DesignerName != "player") return;
|
||||
if (victimPawn == null || victimPawn.Controller?.Value == null) return;
|
||||
if (victimPawn.TeamNum != nadeTeam) return;
|
||||
|
||||
float reduction = SkillsInfo.GetValue<float>(skillName, "dmgReductionForTeamates");
|
||||
param2.Damage *= 1f - Math.Clamp(reduction, 0f, 1f);
|
||||
}
|
||||
|
||||
private static bool NearlyEquals(float a, float b, float epsilon = 0.001f) => Math.Abs(a - b) < epsilon;
|
||||
|
||||
private static bool IsDeadPlayerValid(CCSPlayerController? player)
|
||||
|
|
@ -73,12 +124,11 @@ namespace src.player.skills
|
|||
return player != null && player.IsValid && player.PlayerPawn?.Value != null;
|
||||
}
|
||||
|
||||
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#F5CB42", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float explosionRadius = 500.0f, int explosionDamage = 999, float dmgReductionForTeamates = .5f, bool explosionAfterWorldDeath = true) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
|
||||
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#F5CB42", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float explosionRadius = 500.0f, int explosionDamage = 999, float dmgReductionForTeamates = .5f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
|
||||
{
|
||||
public float ExplosionRadius { get; set; } = explosionRadius;
|
||||
public int ExplosionDamage { get; set; } = explosionDamage;
|
||||
public float DmgReductionForTeamates { get; set; } = dmgReductionForTeamates;
|
||||
public bool ExplosionAfterWorldDeath { get; set; } = explosionAfterWorldDeath;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ using CounterStrikeSharp.API.Core;
|
|||
using CounterStrikeSharp.API.Modules.Memory;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
using src.utils;
|
||||
using System.Collections.Concurrent;
|
||||
using static src.jRandomSkills;
|
||||
|
||||
namespace src.player.skills
|
||||
|
|
@ -10,42 +11,91 @@ namespace src.player.skills
|
|||
public class Planter : ISkill
|
||||
{
|
||||
private const Skills skillName = Skills.Planter;
|
||||
private static readonly ConcurrentDictionary<ulong, float> plantingPlayers = [];
|
||||
|
||||
public static void LoadSkill()
|
||||
{
|
||||
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
|
||||
}
|
||||
|
||||
public static void BombBeginplant(EventBombBeginplant @event)
|
||||
{
|
||||
var user = @event.Userid;
|
||||
if (user == null || !user.IsValid || !user.PawnIsAlive) return;
|
||||
plantingPlayers.TryAdd(user.SteamID, Server.CurrentTime);
|
||||
}
|
||||
|
||||
public static void BombAbortplant(EventBombAbortplant @event)
|
||||
{
|
||||
var user = @event.Userid;
|
||||
if (user == null || !user.IsValid || !user.PawnIsAlive) return;
|
||||
plantingPlayers.TryRemove(user.SteamID, out _);
|
||||
SkillUtils.ResetPrintHTML(user);
|
||||
}
|
||||
|
||||
public static void BombPlanted(EventBombPlanted @event)
|
||||
{
|
||||
var player = @event.Userid;
|
||||
if (!Instance.IsPlayerValid(player)) return;
|
||||
plantingPlayers.TryRemove(player!.SteamID, out _);
|
||||
|
||||
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player?.SteamID);
|
||||
if (playerInfo?.Skill != skillName) return;
|
||||
playerInfo.PrintHTML = null;
|
||||
|
||||
var plantedBomb = Utilities.FindAllEntitiesByDesignerName<CPlantedC4>("planted_c4").FirstOrDefault();
|
||||
if (plantedBomb != null)
|
||||
Server.NextFrame(() => plantedBomb.C4Blow = (float)Server.EngineTime + SkillsInfo.GetValue<int>(skillName, "extraC4BlowTime"));
|
||||
Server.NextFrame(() => plantedBomb.C4Blow = Server.CurrentTime + SkillsInfo.GetValue<int>(skillName, "extraC4BlowTime"));
|
||||
|
||||
player!.PrintToCenterAlert(player.GetTranslation("bombplanted", SkillsInfo.GetValue<int>(skillName, "extraC4BlowTime")));
|
||||
foreach (var p in Utilities.GetPlayers().Where(p => p.IsValid && p.PawnIsAlive))
|
||||
p.PrintToCenterAlert(p.GetTranslation("bombplanted", SkillsInfo.GetValue<int>(skillName, "extraC4BlowTime")));
|
||||
}
|
||||
|
||||
public static void NewRound()
|
||||
{
|
||||
foreach (var player in Utilities.GetPlayers())
|
||||
DisableSkill(player);
|
||||
plantingPlayers.Clear();
|
||||
}
|
||||
|
||||
public static void DisableSkill(CCSPlayerController player)
|
||||
{
|
||||
if (!Instance.IsPlayerValid(player)) return;
|
||||
Schema.SetSchemaValue<bool>(player!.PlayerPawn.Value!.Handle, "CCSPlayerPawn", "m_bInBombZone", false);
|
||||
if (player == null || !player.IsValid) return;
|
||||
plantingPlayers.TryRemove(player.SteamID, out _);
|
||||
SkillUtils.ResetPrintHTML(player);
|
||||
|
||||
var pawn = player.PlayerPawn.Value;
|
||||
if (pawn == null || !pawn.IsValid) return;
|
||||
|
||||
Schema.SetSchemaValue<bool>(pawn!.Handle, "CCSPlayerPawn", "m_bInBombZone", false);
|
||||
}
|
||||
|
||||
public static void OnTick()
|
||||
{
|
||||
foreach (var player in Utilities.GetPlayers())
|
||||
float currentTime = Server.CurrentTime;
|
||||
foreach (var player in Utilities.GetPlayers().Where(p => p.Team == CsTeam.Terrorist))
|
||||
{
|
||||
if (!Instance.IsPlayerValid(player)) continue;
|
||||
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
|
||||
|
||||
if (playerInfo?.Skill == skillName)
|
||||
Schema.SetSchemaValue<bool>(player!.PlayerPawn.Value!.Handle, "CCSPlayerPawn", "m_bInBombZone", true);
|
||||
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
|
||||
if (playerInfo?.Skill != skillName) continue;
|
||||
|
||||
var pawn = player.PlayerPawn.Value;
|
||||
if (pawn == null || !pawn.IsValid) continue;
|
||||
|
||||
if (pawn.WeaponServices == null) continue;
|
||||
var activeWeapon = pawn.WeaponServices.ActiveWeapon.Value;
|
||||
if (activeWeapon == null || !activeWeapon.IsValid || activeWeapon.DesignerName != "weapon_c4") continue;
|
||||
|
||||
pawn.InBombZone = true;
|
||||
Schema.SetSchemaValue<bool>(pawn.Handle, "CCSPlayerPawn", "m_bInBombZone", true);
|
||||
|
||||
if (plantingPlayers.TryGetValue(player.SteamID, out float plantTime))
|
||||
{
|
||||
float remaining = plantTime + 3f - currentTime;
|
||||
playerInfo.PrintHTML = $"{player.GetTranslation("planter_planting", $"<font color='#00FF00'>{Math.Max(0, remaining):0.0}s</font>")}";
|
||||
player.PrintToCenter("");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -61,6 +61,8 @@ namespace src.player.skills
|
|||
foreach (var item in noSpace)
|
||||
if (item.Value >= Server.TickCount)
|
||||
UpdateHUD(item.Key);
|
||||
else
|
||||
SkillUtils.ResetPrintHTML(item.Key);
|
||||
}
|
||||
|
||||
private static void UpdateHUD(CCSPlayerController player)
|
||||
|
|
@ -75,11 +77,40 @@ namespace src.player.skills
|
|||
var pawn = player.PlayerPawn.Value;
|
||||
if (pawn == null || !pawn.IsValid) return false;
|
||||
|
||||
Vector s = startPos + new Vector(0, 0, pawn.ViewOffset.Z / 2);
|
||||
Vector e = endPos + new Vector(0, 0, pawn.ViewOffset.Z / 2);
|
||||
|
||||
ulong mask = pawn.Collision.CollisionAttribute.InteractsWith;
|
||||
ulong contents = pawn.Collision.CollisionGroup;
|
||||
CGameTrace trace = TraceRay.TraceShape(startPos, endPos, mask, contents, player);
|
||||
|
||||
return !trace.HitWorld(out _);
|
||||
if (trace.DidHit()) return false;
|
||||
return IsPositionSafe(player, endPos);
|
||||
}
|
||||
|
||||
private static bool IsPositionSafe(CCSPlayerController player, Vector pos)
|
||||
{
|
||||
var playerPawn = player.PlayerPawn.Value;
|
||||
if (playerPawn == null || !playerPawn.IsValid || playerPawn.AbsOrigin == null) return false;
|
||||
|
||||
float footHeight = 0;
|
||||
float headHeight = 70;
|
||||
float innerDist = 12;
|
||||
|
||||
ulong mask = playerPawn.Collision.CollisionAttribute.InteractsWith;
|
||||
ulong contents = playerPawn.Collision.CollisionGroup;
|
||||
|
||||
Vector s1 = new(pos.X - innerDist, pos.Y - innerDist, pos.Z + footHeight);
|
||||
Vector e1 = new(pos.X + innerDist, pos.Y + innerDist, pos.Z + headHeight);
|
||||
CGameTrace t1 = TraceRay.TraceShape(s1, e1, mask, contents, player);
|
||||
if (t1.DidHit() || t1.AllSolid) return false;
|
||||
|
||||
Vector s2 = new(pos.X + innerDist, pos.Y - innerDist, pos.Z + footHeight);
|
||||
Vector e2 = new(pos.X - innerDist, pos.Y + innerDist, pos.Z + headHeight);
|
||||
CGameTrace t2 = TraceRay.TraceShape(s2, e2, mask, contents, player);
|
||||
if (t2.DidHit() || t2.AllSolid) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void TeleportAttackerBehindVictim(CCSPlayerController attacker, CCSPlayerController victim)
|
||||
|
|
@ -89,22 +120,29 @@ namespace src.player.skills
|
|||
|
||||
if (victimPawn == null || attackerPawn == null || victimPawn.AbsOrigin == null || victimPawn.AbsRotation == null) return;
|
||||
|
||||
QAngle victimAngles = victimPawn.AbsRotation;
|
||||
Vector victimEyePos = new(victimPawn.AbsOrigin.X, victimPawn.AbsOrigin.Y, victimPawn.AbsOrigin.Z + victimPawn.ViewOffset.Z);
|
||||
int[] angles = [0, 90, -90];
|
||||
Vector victimPos = new(victimPawn.AbsOrigin.X, victimPawn.AbsOrigin.Y, victimPawn.AbsOrigin.Z);
|
||||
QAngle victimAngles = new(victimPawn.AbsRotation.X, victimPawn.AbsRotation.Y, victimPawn.AbsRotation.Z);
|
||||
float distance = SkillsInfo.GetValue<float>(skillName, "teleportDistance");
|
||||
|
||||
int[] angles = [0, 90, -90];
|
||||
bool teleported = false;
|
||||
|
||||
foreach (int extraAngle in angles)
|
||||
{
|
||||
QAngle newAngle = new(victimAngles.X, victimAngles.Y + extraAngle, victimAngles.Z);
|
||||
Vector behindPosition = victimEyePos - SkillUtils.GetForwardVector(newAngle) * SkillsInfo.GetValue<float>(skillName, "teleportDistance");
|
||||
if (!CheckTeleport(victim, victimEyePos, behindPosition)) continue;
|
||||
attackerPawn.Teleport(behindPosition, newAngle, new(0, 0, 0));
|
||||
teleported = true;
|
||||
break;
|
||||
QAngle targetAngle = new(0, victimAngles.Y + extraAngle, 0);
|
||||
Vector direction = SkillUtils.GetForwardVector(targetAngle);
|
||||
Vector targetPos = victimPos - (direction * distance);
|
||||
|
||||
if (CheckTeleport(victim, victimPos, targetPos))
|
||||
{
|
||||
attackerPawn.Teleport(targetPos, targetAngle, Vector.Zero);
|
||||
teleported = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!teleported)
|
||||
noSpace.AddOrUpdate(attacker, Server.TickCount + (64 * 2), (k, v) => Server.TickCount + (64 * 2));
|
||||
noSpace.AddOrUpdate(attacker, Server.TickCount + (64 * 2), (_, _) => Server.TickCount + (64 * 2));
|
||||
}
|
||||
|
||||
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#4d4d4d", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float teleportDistance = 100f, float chanceFrom = .3f, float chanceTo = .45f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
|
||||
|
|
|
|||
|
|
@ -25,9 +25,10 @@ namespace src.player.skills
|
|||
|
||||
var plantedBomb = Utilities.FindAllEntitiesByDesignerName<CPlantedC4>("planted_c4").FirstOrDefault();
|
||||
if (plantedBomb != null)
|
||||
Server.NextFrame(() => plantedBomb.C4Blow = (float)Server.EngineTime + SkillsInfo.GetValue<int>(skillName, "detonationTime"));
|
||||
Server.NextFrame(() => plantedBomb.C4Blow = Server.CurrentTime + SkillsInfo.GetValue<int>(skillName, "detonationTime"));
|
||||
|
||||
player!.PrintToCenterAlert(player.GetTranslation("bombplanted", SkillsInfo.GetValue<int>(skillName, "detonationTime")));
|
||||
foreach (var p in Utilities.GetPlayers().Where(p => p.IsValid && p.PawnIsAlive))
|
||||
p.PrintToCenterAlert(p.GetTranslation("bombplanted", SkillsInfo.GetValue<int>(skillName, "detonationTime")));
|
||||
}
|
||||
|
||||
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#f5b74c", CsTeam onlyTeam = CsTeam.Terrorist, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int detonationTime = 20) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
|
||||
|
|
|
|||
|
|
@ -62,7 +62,6 @@ namespace src.player.skills
|
|||
return;
|
||||
}
|
||||
|
||||
Server.PrintToChatAll("Create Smoke");
|
||||
SkillUtils.CreateSmokeGrenadeProjectile(pos, QAngle.Zero, Vector.Zero, player.TeamNum);
|
||||
}, TimerFlags.REPEAT | TimerFlags.STOP_ON_MAPCHANGE);
|
||||
|
||||
|
|
|
|||
|
|
@ -165,8 +165,7 @@ namespace src.player.skills
|
|||
weaponToGive = weapon_awp + "_script";
|
||||
}
|
||||
|
||||
Server.NextFrame(() =>
|
||||
{
|
||||
Instance.AddTimer(.15f, () => {
|
||||
if (player != null && player.IsValid && player.PlayerPawn.Value != null && player.PlayerPawn.Value.IsValid)
|
||||
{
|
||||
var createdWeapon = player.PlayerPawn.Value?.ItemServices?.As<CCSPlayer_ItemServices>().GiveNamedItem<CEntityInstance>(weaponToGive.Replace("_script", ""));
|
||||
|
|
@ -190,7 +189,7 @@ namespace src.player.skills
|
|||
|
||||
DeleteDroppedAWP(player);
|
||||
isProcessing.TryRemove(steamID, out _);
|
||||
});
|
||||
}, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
|
||||
}
|
||||
catch {
|
||||
isProcessing.TryRemove(steamID, out _);
|
||||
|
|
|
|||
|
|
@ -30,8 +30,7 @@ namespace src.player.skills
|
|||
{
|
||||
if (bombPlanted) return;
|
||||
var name = entity.DesignerName;
|
||||
if (!name.EndsWith("_projectile"))
|
||||
return;
|
||||
if (!name.EndsWith("_projectile")) return;
|
||||
|
||||
var grenade = entity.As<CBaseCSGrenadeProjectile>();
|
||||
if (grenade.OwnerEntity.Value == null || !grenade.OwnerEntity.Value.IsValid) return;
|
||||
|
|
|
|||
|
|
@ -170,8 +170,9 @@ namespace src.utils
|
|||
SkillsListCommand = new NormalCommand("supermoc, skille, listamocy, supermoce, skills, listaHabilidades, habilidades, 技能列表, 超能力列表", "@jRandomSkills/admin"),
|
||||
UseSkillCommand = new NormalCommand("t, useSkill, usarHabilidade, 技能使用, 使用技能", "@jRandomSkills/admin"),
|
||||
HealCommand = new NormalCommand("heal, ulecz, curar, tratar, 治疗, 治愈", "@jRandomSkills/admin"),
|
||||
HealthCommand = new NormalCommand("sethealth, health", "@jRandomSkills/admin"),
|
||||
PlantedBomb = new NormalCommand("plantedbomb, bomb", "@jRandomSkills/admin"),
|
||||
HealthCommand = new NormalCommand("sethealth, set_health, health", "@jRandomSkills/admin"),
|
||||
PlantedBomb = new NormalCommand("plantedbomb, planted_bomb, bomb", "@jRandomSkills/admin"),
|
||||
BotPlace = new NormalCommand("botplace, bot_place", "@jRandomSkills/admin"),
|
||||
ConsoleCommand = new NormalCommand("console, sv, 控制台, 服务器", "@jRandomSkills/owner"),
|
||||
HudCommand = new NormalCommand("hud, hood", ""),
|
||||
SetStaticSkillCommand = new NormalCommand("ustawstatycznyskill, ustaw_statyczny_skill, setstaticskill, set_static_skill", "@jRandomSkills/admin"),
|
||||
|
|
@ -250,6 +251,7 @@ namespace src.utils
|
|||
public required NormalCommand HealCommand { get; set; }
|
||||
public required NormalCommand HealthCommand { get; set; }
|
||||
public required NormalCommand PlantedBomb { get; set; }
|
||||
public required NormalCommand BotPlace { get; set; }
|
||||
public required NormalCommand ConsoleCommand { get; set; }
|
||||
public required NormalCommand HudCommand { get; set; }
|
||||
public required NormalCommand SetStaticSkillCommand { get; set; }
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue