Bump version, return SkillAction result & i18n
Bump module version to 1.2.1.b7 and change SkillAction to return the invoked method result (object?) or null when not found. Add and normalize many localization entries across multiple language files (aimlock, homingnades, hotbomb, illiterate, illusionist, magneticdecoy, magneto, miner, planter_planting, teleporter chance string, throwingknife, weightless, wildthrow, smoker, etc.) and clean up duplicate/obsolete entries. Update server plugin binaries and configs (WASDMenuAPI.dll, jRandomSkills.dll, config.json, skillsInfo.json) and remove playersLanguage.json.
This commit is contained in:
parent
3954fc3af4
commit
abd3aed8fd
33 changed files with 1159 additions and 324 deletions
|
|
@ -44,6 +44,7 @@ public interface ISkill
|
|||
|
||||
public static void OnTriggerEnter(CBaseTrigger _, CBaseEntity __) { }
|
||||
public static void OnTriggerExit(CBaseTrigger _, CBaseEntity __) { }
|
||||
public static bool OnWeaponCanAcquire(DynamicHook _, CCSPlayerController __, CEconItemView ___, CCSWeaponBaseVData ____) { return false; }
|
||||
|
||||
public class SkillConfig { }
|
||||
}
|
||||
|
|
@ -52,7 +53,7 @@ public enum Skills
|
|||
{
|
||||
None,
|
||||
Aimbot,
|
||||
AimLock, // <-
|
||||
AimLock,
|
||||
Anomaly,
|
||||
AntyFlash,
|
||||
AntyHead,
|
||||
|
|
@ -81,7 +82,7 @@ public enum Skills
|
|||
Dracula,
|
||||
Duplicator,
|
||||
Dwarf,
|
||||
Earthquake, // <-
|
||||
Earthquake,
|
||||
EnemySpawn,
|
||||
ExplosiveShot,
|
||||
FalconEye,
|
||||
|
|
@ -98,11 +99,11 @@ public enum Skills
|
|||
Glue,
|
||||
GodMode,
|
||||
Grenadier,
|
||||
HealingChicken, // <-
|
||||
HealingChicken,
|
||||
HealingSmoke,
|
||||
Hermit,
|
||||
HolyHandGrenade,
|
||||
HomingNades, // <-
|
||||
HomingNades,
|
||||
HotBomb,
|
||||
Iana,
|
||||
Illiterate,
|
||||
|
|
@ -134,7 +135,7 @@ public enum Skills
|
|||
PawelJumper,
|
||||
Phoenix,
|
||||
PsychicDefusing,
|
||||
Pilot, // <-
|
||||
Pilot,
|
||||
Planter,
|
||||
Poison,
|
||||
PrimaryBan,
|
||||
|
|
@ -145,7 +146,7 @@ public enum Skills
|
|||
RadarHack,
|
||||
Rambo,
|
||||
RandomWeapon,
|
||||
RCMelon, // <-
|
||||
RCMelon,
|
||||
ReZombie,
|
||||
ReactiveArmor,
|
||||
Regeneration,
|
||||
|
|
@ -158,10 +159,10 @@ public enum Skills
|
|||
Saper,
|
||||
SecondLife,
|
||||
Shade,
|
||||
ShortBomb, // <- short
|
||||
ShortBomb,
|
||||
Silent,
|
||||
Smoker, // <- nie dziala
|
||||
SniperElite, // <- nie dziala
|
||||
Smoker,
|
||||
SniperElite,
|
||||
Soldier,
|
||||
SoundMaker,
|
||||
Spectator,
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ namespace src.player
|
|||
|
||||
VirtualFunctions.CBaseTrigger_StartTouchFunc.Hook(OnTriggerEnter, HookMode.Post);
|
||||
VirtualFunctions.CBaseTrigger_EndTouchFunc.Hook(OnTriggerExit, HookMode.Pre);
|
||||
VirtualFunctions.CCSPlayer_ItemServices_CanAcquireFunc.Hook(OnWeaponCanAcquire, HookMode.Pre);
|
||||
}
|
||||
|
||||
private static HookResult PlayerMakeSound(UserMessage um)
|
||||
|
|
@ -388,6 +389,44 @@ namespace src.player
|
|||
}
|
||||
}
|
||||
|
||||
private static HookResult OnWeaponCanAcquire(DynamicHook hook)
|
||||
{
|
||||
lock (setLock)
|
||||
{
|
||||
CCSPlayer_ItemServices itemServices = hook.GetParam<CCSPlayer_ItemServices>(0);
|
||||
if (itemServices == null || itemServices.Pawn.Value == null || !itemServices.Pawn.Value.IsValid) return HookResult.Continue;
|
||||
|
||||
CEconItemView econItem = hook.GetParam<CEconItemView>(1);
|
||||
if (econItem == null) return HookResult.Continue;
|
||||
|
||||
CBasePlayerPawn pawn = itemServices.Pawn.Value;
|
||||
if (pawn == null || !pawn.IsValid || pawn.Controller.Value == null || !pawn.Controller.Value.IsValid) return HookResult.Continue;
|
||||
|
||||
CCSPlayerController player = pawn.Controller.Value.As<CCSPlayerController>();
|
||||
if (player == null || !player.IsValid) return HookResult.Continue;
|
||||
|
||||
CCSWeaponBaseVData vdata = VirtualFunctions.GetCSWeaponDataFromKeyFunc.Invoke(-1, econItem.ItemDefinitionIndex.ToString());
|
||||
if (vdata == null) return HookResult.Continue;
|
||||
|
||||
var activeSkills = Instance.SkillPlayer
|
||||
.Where(p => !p.IsDrawing)
|
||||
.Select(p => p.Skill.ToString())
|
||||
.Distinct();
|
||||
|
||||
bool block = false;
|
||||
foreach (string skillName in activeSkills)
|
||||
{
|
||||
bool? result = (bool?)Instance.SkillAction(skillName, "OnWeaponCanAcquire", [hook, player, econItem, vdata]);
|
||||
if (result == true)
|
||||
{
|
||||
block = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return block ? HookResult.Stop : HookResult.Continue;
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnTick()
|
||||
{
|
||||
lock (setLock)
|
||||
|
|
@ -827,10 +866,6 @@ namespace src.player
|
|||
}
|
||||
}
|
||||
|
||||
if (randomSkill.Display)
|
||||
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(randomSkill.Skill)}{ChatColors.Lime}: {player.GetSkillDescription(randomSkill.Skill)}",
|
||||
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && !p.IsBot && p != player) ? "tb" : "t");
|
||||
|
||||
Instance?.SkillAction(skillPlayer.Skill.ToString(), "DisableSkill", [player]);
|
||||
skillPlayer.Skill = randomSkill.Skill;
|
||||
skillPlayer.SpecialSkill = Skills.None;
|
||||
|
|
@ -840,6 +875,10 @@ namespace src.player
|
|||
|
||||
Instance?.AddTimer(.2f, () =>
|
||||
{
|
||||
if (randomSkill.Display)
|
||||
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(randomSkill.Skill)}{ChatColors.Lime}: {player.GetSkillDescription(randomSkill.Skill)}",
|
||||
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && !p.IsBot && p != player) ? "tb" : "t");
|
||||
|
||||
if (SkillsInfo.GetValue<bool>(randomSkill.Skill, "disableOnFreezeTime") && SkillUtils.IsFreezeTime())
|
||||
Instance?.AddTimer(Config.LoadedConfig.SkillTimeBeforeStart, () =>
|
||||
{
|
||||
|
|
@ -1016,10 +1055,10 @@ namespace src.player
|
|||
}
|
||||
|
||||
var config = Config.LoadedConfig.HtmlHudCustomisation;
|
||||
var emptySymbol = $"<font class='fontSize-{(string.IsNullOrEmpty(headerLine) ? "l" : "ml")}'> </font>";
|
||||
var emptySymbol = $"<font class='fontSize-{(string.IsNullOrEmpty(headerLine) || string.IsNullOrEmpty(config.HeaderLineSize) ? "l" : "ml")}'> </font>";
|
||||
var emptySymbol2 = $"<font class='fontSize-ml'> </font>";
|
||||
|
||||
string infoLine = string.IsNullOrEmpty(headerLine)
|
||||
string infoLine = string.IsNullOrEmpty(headerLine) || string.IsNullOrEmpty(config.HeaderLineSize)
|
||||
? ""
|
||||
: $"<font class='fontWeight-Bold fontSize-{config.HeaderLineSize}' color='{config.HeaderLineColor}'>{headerLine}:</font><br>";
|
||||
|
||||
|
|
@ -1030,6 +1069,7 @@ namespace src.player
|
|||
: $"<br>{emptySymbol}<font class='fontSize-{(isDescription ? config.SkillDescriptionLineSize : config.InfoLineSize)}' color='{(isDescription ? config.SkillDescriptionLineColor : config.InfoLineColor)}'>{extraLine}</font>{emptySymbol}";
|
||||
|
||||
var hudContent = infoLine + skillLine + remainingLine;
|
||||
|
||||
player.PrintToCenterHtml(hudContent);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ namespace src.player
|
|||
var observeredPlayerSpecialSkillInfo = SkillData.Skills.FirstOrDefault(s => s.Skill == observeredPlayerSkill.SpecialSkill);
|
||||
if (observeredPlayerSpecialSkillInfo == null) return;
|
||||
|
||||
string pName = observeredPlayerSkill.PlayerName;
|
||||
string pName = System.Net.WebUtility.HtmlEncode(observeredPlayerSkill.PlayerName);
|
||||
if (pName.Length > 18)
|
||||
pName = $"{pName[..17]}...";
|
||||
var observerSkill = player.GetTranslation("observer_skill");
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ namespace src.player.skills
|
|||
}
|
||||
|
||||
string distanceColor = closetDistance > 1500 ? "#00FF00" : closetDistance > 600 ? "#FFFF00" : "#FF0000";
|
||||
playerInfo.PrintHTML = $"{closetEnemy}: <font color='{distanceColor}'>{(closetDistance > 3000 ? "3000+" : closetDistance)}</font>";
|
||||
playerInfo.PrintHTML = $"{System.Net.WebUtility.HtmlEncode(closetEnemy)}: <font color='{distanceColor}'>{(closetDistance > 3000 ? "3000+" : closetDistance)}</font>";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
using CounterStrikeSharp.API;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Modules.Entities.Constants;
|
||||
using CounterStrikeSharp.API.Modules.Memory;
|
||||
using CounterStrikeSharp.API.Modules.Timers;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
|
|
@ -20,7 +19,7 @@ namespace src.player.skills
|
|||
|
||||
public static void LoadSkill()
|
||||
{
|
||||
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
|
||||
// SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
|
||||
}
|
||||
|
||||
public static void NewRound()
|
||||
|
|
|
|||
|
|
@ -27,8 +27,10 @@ namespace src.player.skills
|
|||
{
|
||||
var player = @event.Userid;
|
||||
if (player == null || !player.IsValid) return;
|
||||
|
||||
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
|
||||
if (playerInfo?.Skill != skillName) return;
|
||||
|
||||
smokes.TryAdd(new Vector(@event.X, @event.Y, @event.Z), 0);
|
||||
}
|
||||
|
||||
|
|
@ -36,8 +38,10 @@ namespace src.player.skills
|
|||
{
|
||||
var player = @event.Userid;
|
||||
if (player == null || !player.IsValid) return;
|
||||
|
||||
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
|
||||
if (playerInfo?.Skill != skillName) return;
|
||||
|
||||
foreach (var smoke in smokes.Keys.Where(v => v.X == @event.X && v.Y == @event.Y && v.Z == @event.Z))
|
||||
smokes.TryRemove(smoke, out _);
|
||||
}
|
||||
|
|
@ -71,12 +75,20 @@ namespace src.player.skills
|
|||
public static void OnTick()
|
||||
{
|
||||
int tick = SkillsInfo.GetValue<int>(skillName, "tickCooldown");
|
||||
if (Server.TickCount % tick != 0) return;
|
||||
|
||||
float smokeRadius = SkillsInfo.GetValue<float>(skillName, "smokeRadius");
|
||||
int smokeHeal = SkillsInfo.GetValue<int>(skillName, "smokeHeal");
|
||||
|
||||
foreach (Vector smokePos in smokes.Keys)
|
||||
foreach (var player in Utilities.GetPlayers())
|
||||
if (Server.TickCount % tick == 0)
|
||||
if (player.PlayerPawn.Value != null && player.PlayerPawn.Value.IsValid && player.PlayerPawn.Value.AbsOrigin != null)
|
||||
if (SkillUtils.GetDistance(smokePos, player.PlayerPawn.Value.AbsOrigin) <= SkillsInfo.GetValue<float>(skillName, "smokeRadius"))
|
||||
AddHealth(player.PlayerPawn.Value, SkillsInfo.GetValue<int>(skillName, "smokeHeal"));
|
||||
foreach (var player in Utilities.GetPlayers().Where(p => p.IsValid && p.PawnIsAlive))
|
||||
{
|
||||
var pawn = player.PlayerPawn.Value;
|
||||
if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) continue;
|
||||
|
||||
if (SkillUtils.GetDistance(smokePos, pawn.AbsOrigin) <= smokeRadius)
|
||||
AddHealth(pawn, smokeHeal);
|
||||
}
|
||||
}
|
||||
|
||||
public static void EnableSkill(CCSPlayerController player)
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ namespace src.player.skills
|
|||
{
|
||||
private const Skills skillName = Skills.Illiterate;
|
||||
private static bool isActive = false;
|
||||
private static int offset = jRandomSkills.Instance.Random.Next(0, 26);
|
||||
private static int offset = jRandomSkills.Instance.Random.Next(2, 26);
|
||||
|
||||
public static void LoadSkill()
|
||||
{
|
||||
|
|
@ -55,7 +55,7 @@ namespace src.player.skills
|
|||
{
|
||||
if (string.IsNullOrEmpty(input)) return null;
|
||||
if (Server.TickCount % 64 == 0)
|
||||
offset = jRandomSkills.Instance.Random.Next(1, 26);
|
||||
offset = jRandomSkills.Instance.Random.Next(2, 26);
|
||||
|
||||
return new string([.. input.Select(c =>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ namespace src.player.skills
|
|||
if (playerInfo == null || playerInfo.Skill != skillName) continue;
|
||||
var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray();
|
||||
|
||||
ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => ($"{e.PlayerName} : {(e.InGameMoneyServices == null ? 0 : e.InGameMoneyServices.Account)}$", e.Index.ToString())));
|
||||
ConcurrentBag<(string, string)> menuItems = [.. enemies.Select(e => ($"{e.PlayerName} : {(e.InGameMoneyServices == null ? 0 : e.InGameMoneyServices.Account + e.InGameMoneyServices.CashSpentThisRound)}$", e.Index.ToString()))];
|
||||
SkillUtils.UpdateMenu(player, menuItems);
|
||||
}
|
||||
}
|
||||
|
|
@ -74,7 +74,7 @@ namespace src.player.skills
|
|||
var enemies = Utilities.GetPlayers().Where(p => p.PawnIsAlive && p.Team != player.Team && p.IsValid && !p.IsBot && !p.IsHLTV && p.Team != CsTeam.Spectator && p.Team != CsTeam.None).ToArray();
|
||||
if (enemies.Length > 0)
|
||||
{
|
||||
ConcurrentBag<(string, string)> menuItems = new(enemies.Select(e => ($"{e.PlayerName} : {(e.InGameMoneyServices == null ? 0 : e.InGameMoneyServices.Account)}$", e.Index.ToString())));
|
||||
ConcurrentBag<(string, string)> menuItems = [.. enemies.Select(e => ($"{e.PlayerName} : {(e.InGameMoneyServices == null ? 0 : e.InGameMoneyServices.Account + e.InGameMoneyServices.CashSpentThisRound)}$", e.Index.ToString()))];
|
||||
SkillUtils.CreateMenu(player, menuItems);
|
||||
}
|
||||
else
|
||||
|
|
@ -90,7 +90,7 @@ namespace src.player.skills
|
|||
if (playerMoneyServices == null || enemyMoneyServices == null) return;
|
||||
|
||||
int playerMoney = playerMoneyServices.Account;
|
||||
playerMoneyServices.Account = enemyMoneyServices.Account;
|
||||
playerMoneyServices.Account = enemyMoneyServices.Account + enemyMoneyServices.CashSpentThisRound;
|
||||
Utilities.SetStateChanged(player, "CCSPlayerController", "m_pInGameMoneyServices");
|
||||
|
||||
enemyMoneyServices.Account = playerMoney;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
using CounterStrikeSharp.API;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
using src.utils;
|
||||
|
|
@ -12,7 +13,19 @@ namespace src.player.skills
|
|||
|
||||
public static void LoadSkill()
|
||||
{
|
||||
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
|
||||
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"), false);
|
||||
}
|
||||
|
||||
public static void EnableSkill(CCSPlayerController player)
|
||||
{
|
||||
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
|
||||
if (playerInfo == null) return;
|
||||
|
||||
float newChance = (float)Instance.Random.NextDouble() * (SkillsInfo.GetValue<float>(skillName, "ChanceTo") - SkillsInfo.GetValue<float>(skillName, "ChanceFrom")) + SkillsInfo.GetValue<float>(skillName, "ChanceFrom");
|
||||
playerInfo.SkillChance = newChance;
|
||||
|
||||
SkillUtils.PrintToChat(player, $"{ChatColors.DarkRed}{player.GetSkillName(skillName)}{ChatColors.Lime}: {player.GetSkillDescription(skillName, newChance)}",
|
||||
border: !Utilities.GetPlayers().Any(p => p.Team == player.Team && !p.IsBot && p != player) ? "tb" : "t");
|
||||
}
|
||||
|
||||
public static void PlayerHurt(EventPlayerHurt @event)
|
||||
|
|
@ -24,7 +37,8 @@ namespace src.player.skills
|
|||
var attackerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == attacker?.SteamID);
|
||||
|
||||
if (attackerInfo?.Skill == skillName)
|
||||
TeleportPlayers(attacker!, victim!);
|
||||
if (Instance.Random.NextDouble() <= attackerInfo.SkillChance)
|
||||
TeleportPlayers(attacker!, victim!);
|
||||
}
|
||||
|
||||
private static void TeleportPlayers(CCSPlayerController attacker, CCSPlayerController victim)
|
||||
|
|
@ -46,8 +60,10 @@ namespace src.player.skills
|
|||
attackerPawn.Teleport(victimPosition, victimAngles, victimVelocity);
|
||||
}
|
||||
|
||||
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#8A2BE2", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "") : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
|
||||
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#8A2BE2", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float chanceFrom = .5f, float chanceTo = .6f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
|
||||
{
|
||||
public float ChanceFrom { get; set; } = chanceFrom;
|
||||
public float ChanceTo { get; set; } = chanceTo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,19 +1,22 @@
|
|||
using CounterStrikeSharp.API;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Core.Attributes;
|
||||
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
|
||||
using CounterStrikeSharp.API.Modules.Timers;
|
||||
using CounterStrikeSharp.API.Modules.UserMessages;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
using src.utils;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Drawing;
|
||||
using static src.jRandomSkills;
|
||||
using Timer = CounterStrikeSharp.API.Modules.Timers.Timer;
|
||||
|
||||
namespace src.player.skills
|
||||
{
|
||||
public class ThrowingKnife : ISkill
|
||||
{
|
||||
private const Skills skillName = Skills.ThrowingKnife;
|
||||
private readonly static ConcurrentDictionary<uint, uint> triggers = [];
|
||||
private readonly static ConcurrentDictionary<uint, uint> glows = [];
|
||||
private readonly static ConcurrentDictionary<uint, KnifeInfo> knivesInfo = [];
|
||||
|
||||
public static void LoadSkill()
|
||||
{
|
||||
|
|
@ -22,40 +25,134 @@ namespace src.player.skills
|
|||
|
||||
public static void NewRound()
|
||||
{
|
||||
foreach (var player in Utilities.GetPlayers())
|
||||
DisableSkill(player);
|
||||
triggers.Clear();
|
||||
glows.Clear();
|
||||
foreach (var knifeInfo in knivesInfo.Values)
|
||||
DisableKnifeSkill(knifeInfo);
|
||||
knivesInfo.Clear();
|
||||
}
|
||||
|
||||
public static void EnableSkill(CCSPlayerController player)
|
||||
public static void PlayerMakeSound(UserMessage um)
|
||||
{
|
||||
var soundevent = um.ReadUInt("soundevent_hash");
|
||||
var userIndex = um.ReadUInt("source_entity_index");
|
||||
|
||||
if (soundevent != 3208928088 || userIndex != 0) return;
|
||||
|
||||
byte[] packedParams = um.ReadBytes("packed_params");
|
||||
|
||||
Vector? soundPos = null;
|
||||
if (packedParams != null && packedParams.Length >= 19)
|
||||
{
|
||||
try
|
||||
{
|
||||
float x = BitConverter.ToSingle(packedParams, 7);
|
||||
float y = BitConverter.ToSingle(packedParams, 11);
|
||||
float z = BitConverter.ToSingle(packedParams, 15);
|
||||
soundPos = new Vector(x, y, z);
|
||||
} catch { }
|
||||
}
|
||||
if (soundPos == null) return;
|
||||
|
||||
(var knife, var knifeInfo) = GetClosetKnife(soundPos);
|
||||
if (knife == null || knife.AbsRotation == null || knifeInfo == null || knifeInfo.InitialLook == null) return;
|
||||
|
||||
knifeInfo.IsDropped = false;
|
||||
QAngle rotation = new(knifeInfo.InitialLook?.X, knifeInfo.InitialLook?.Y, knife.AbsRotation.Z);
|
||||
Vector offset = SkillUtils.GetForwardVector(new QAngle(rotation.X - 90, rotation.Y, rotation.Z)) * 2;
|
||||
|
||||
knife.Teleport(
|
||||
new Vector(soundPos.X - offset.X, soundPos.Y - offset.Y, soundPos.Z - offset.Z),
|
||||
rotation,
|
||||
Vector.Zero
|
||||
);
|
||||
|
||||
var world = Utilities.GetEntityFromIndex<CBaseEntity>(0);
|
||||
knife.AcceptInput("SetParent", world, world, "!activator");
|
||||
|
||||
if (knifeInfo.Timer != null)
|
||||
knifeInfo.Timer?.Kill();
|
||||
|
||||
knifeInfo.Timer =
|
||||
Instance.AddTimer(3f, () =>
|
||||
{
|
||||
if (knife != null && knife.IsValid)
|
||||
knife.AcceptInput("ClearParent");
|
||||
}, TimerFlags.STOP_ON_MAPCHANGE);
|
||||
}
|
||||
|
||||
public static bool OnWeaponCanAcquire(DynamicHook hook, CCSPlayerController player, CEconItemView econItem, CCSWeaponBaseVData vdata)
|
||||
{
|
||||
string weaponName = vdata.Name;
|
||||
if (string.IsNullOrEmpty(weaponName)) return false;
|
||||
|
||||
if (!weaponName.Contains("knife") && !weaponName.Contains("bayonet"))
|
||||
return false;
|
||||
|
||||
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
|
||||
if (playerInfo?.Skill != skillName) return false;
|
||||
|
||||
if (knivesInfo.TryGetValue(player.Index, out KnifeInfo? knifeInfo) && knifeInfo != null && knifeInfo.KnifeId == econItem.ItemID)
|
||||
{
|
||||
knifeInfo.IsDropped = false;
|
||||
if (knifeInfo.Timer != null)
|
||||
{
|
||||
knifeInfo.Timer?.Kill();
|
||||
knifeInfo.Timer = null;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
hook.SetReturn(AcquireResult.InvalidItem);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void EnableSkill(CCSPlayerController _)
|
||||
{
|
||||
Event.EnableTransmit();
|
||||
}
|
||||
|
||||
public static void DisableSkill(CCSPlayerController player)
|
||||
{
|
||||
var playersTriggers = triggers.Where(t => t.Value == player.Index).Select(t => t.Key).ToList();
|
||||
foreach (var triggerIndex in playersTriggers)
|
||||
if (triggers.TryRemove(triggerIndex, out _))
|
||||
{
|
||||
var entity = Utilities.GetEntityFromIndex<CTriggerMultiple>((int)triggerIndex);
|
||||
if (entity != null && entity.IsValid)
|
||||
Server.NextFrame(() =>
|
||||
{
|
||||
if (entity.IsValid)
|
||||
entity.AcceptInput("Kill");
|
||||
});
|
||||
}
|
||||
if (knivesInfo.TryRemove(player.Index, out KnifeInfo? knifeInfo) && knifeInfo != null)
|
||||
DisableKnifeSkill(knifeInfo);
|
||||
}
|
||||
|
||||
if (glows.TryRemove(player.Index, out uint glowIndex))
|
||||
public static void DisableKnifeSkill(KnifeInfo knifeInfo)
|
||||
{
|
||||
if (knifeInfo.Timer != null)
|
||||
knifeInfo.Timer?.Kill();
|
||||
knifeInfo.Timer = null;
|
||||
|
||||
if (knifeInfo.TriggerIndex != null)
|
||||
{
|
||||
var entity = Utilities.GetEntityFromIndex<CTriggerMultiple>((int)glowIndex);
|
||||
if (entity != null && entity.IsValid)
|
||||
var trigger = Utilities.GetEntityFromIndex<CTriggerMultiple>((int)knifeInfo.TriggerIndex);
|
||||
if (trigger != null && trigger.IsValid)
|
||||
Server.NextFrame(() =>
|
||||
{
|
||||
if (entity.IsValid)
|
||||
entity.AcceptInput("Kill");
|
||||
if (trigger.IsValid)
|
||||
trigger.AcceptInput("Kill");
|
||||
});
|
||||
}
|
||||
|
||||
if (knifeInfo.GlowIndex != null)
|
||||
{
|
||||
var glow = Utilities.GetEntityFromIndex<CTriggerMultiple>((int)knifeInfo.GlowIndex);
|
||||
if (glow != null && glow.IsValid)
|
||||
Server.NextFrame(() =>
|
||||
{
|
||||
if (glow.IsValid)
|
||||
glow.AcceptInput("Kill");
|
||||
});
|
||||
}
|
||||
|
||||
if (knifeInfo.RelayIndex != null)
|
||||
{
|
||||
var relay = Utilities.GetEntityFromIndex<CTriggerMultiple>((int)knifeInfo.RelayIndex);
|
||||
if (relay != null && relay.IsValid)
|
||||
Server.NextFrame(() =>
|
||||
{
|
||||
if (relay.IsValid)
|
||||
relay.AcceptInput("Kill");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -88,12 +185,12 @@ namespace src.player.skills
|
|||
private static void ThrowKnife(CCSPlayerController player, CBasePlayerWeapon knife)
|
||||
{
|
||||
if (player == null || !player.IsValid) return;
|
||||
|
||||
var pawn = player.PlayerPawn.Value;
|
||||
if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) return;
|
||||
if (knife == null || !knife.IsValid || knife.AbsOrigin == null) return;
|
||||
|
||||
float force = 2000;
|
||||
var pawn = player.PlayerPawn.Value;
|
||||
if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) return;
|
||||
|
||||
float force = 2000f;
|
||||
|
||||
Vector pos = new(pawn.AbsOrigin.X, pawn.AbsOrigin.Y, pawn.AbsOrigin.Z + pawn.ViewOffset.Z);
|
||||
QAngle angle = new(0, 0, 0);
|
||||
|
|
@ -102,35 +199,61 @@ namespace src.player.skills
|
|||
knife.Collision.CollisionAttribute.InteractsWith = pawn.Collision.CollisionAttribute.InteractsWith;
|
||||
|
||||
knife.Teleport(pos, angle, vel);
|
||||
CreateTrigger(player, knife);
|
||||
CreateGlow(player, knife);
|
||||
|
||||
if (!knivesInfo.ContainsKey(player.Index))
|
||||
{
|
||||
uint? triggerIndex = CreateTrigger(player, knife);
|
||||
(uint? relayIndex, uint? glowIndex) = CreateGlow(player, knife);
|
||||
|
||||
knivesInfo.TryAdd(player.Index, new KnifeInfo
|
||||
{
|
||||
PlayerIndex = player.Index,
|
||||
KnifeIndex = knife.Index,
|
||||
KnifeId = knife.AttributeManager.Item.ItemID,
|
||||
TriggerIndex = triggerIndex,
|
||||
GlowIndex = glowIndex,
|
||||
RelayIndex = relayIndex
|
||||
});
|
||||
}
|
||||
|
||||
if (knivesInfo.TryGetValue(player.Index, out KnifeInfo? knifeInfo))
|
||||
{
|
||||
knifeInfo.IsDropped = true;
|
||||
knifeInfo.InitialLook = new QAngle(pawn.V_angle.X + 90, pawn.V_angle.Y, pawn.V_angle.Z);
|
||||
}
|
||||
}
|
||||
|
||||
private static void CreateTrigger(CCSPlayerController player, CBaseEntity knife)
|
||||
private static uint? CreateTrigger(CCSPlayerController player, CBasePlayerWeapon knife)
|
||||
{
|
||||
if (player == null || !player.IsValid) return;
|
||||
if (triggers.Any(t => t.Value == player.Index)) return;
|
||||
|
||||
var pawn = player.PlayerPawn.Value;
|
||||
if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) return;
|
||||
|
||||
if (knife == null || !knife.IsValid || knife.AbsOrigin == null) return;
|
||||
|
||||
if (player == null || !player.IsValid) return null;
|
||||
if (knife == null || !knife.IsValid || knife.AbsOrigin == null) return null;
|
||||
|
||||
var trigger = SkillUtils.CreateTrigger($"trowingknife", 10, knife.AbsOrigin);
|
||||
if (trigger == null || !trigger.IsValid) return;
|
||||
if (trigger == null || !trigger.IsValid) return null;
|
||||
|
||||
trigger.AcceptInput("SetParent", knife, knife, "!activator");
|
||||
triggers.TryAdd(trigger.Index, player.Index);
|
||||
return trigger.Index;
|
||||
}
|
||||
|
||||
private static void CreateGlow(CCSPlayerController player, CBaseEntity knife)
|
||||
private static (uint?, uint?) CreateGlow(CCSPlayerController player, CBaseEntity knife)
|
||||
{
|
||||
if (player == null || !player.IsValid) return;
|
||||
if (glows.ContainsKey(player.Index)) return;
|
||||
if (knife == null || !knife.IsValid || knife.AbsOrigin == null) return;
|
||||
if (player == null || !player.IsValid) return (null, null);
|
||||
if (knife == null || !knife.IsValid || knife.AbsOrigin == null) return (null, null);
|
||||
|
||||
var modelRelay = Utilities.CreateEntityByName<CPhysicsPropMultiplayer>("prop_physics_multiplayer");
|
||||
if (modelRelay == null) return (null, null);
|
||||
|
||||
modelRelay.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags = (uint)(modelRelay.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags & ~(1 << 2));
|
||||
modelRelay.SetModel(knife!.CBodyComponent!.SceneNode!.GetSkeletonInstance().ModelState.ModelName);
|
||||
modelRelay.Spawnflags = 256u;
|
||||
modelRelay.Render = Color.FromArgb(1, 255, 255, 255);
|
||||
modelRelay.DispatchSpawn();
|
||||
|
||||
modelRelay.Teleport(knife.AbsOrigin, knife.AbsRotation, knife.AbsVelocity);
|
||||
modelRelay.AcceptInput("SetParent", knife, modelRelay, "!activator");
|
||||
|
||||
var modelGlow = Utilities.CreateEntityByName<CPhysicsPropMultiplayer>("prop_physics_multiplayer");
|
||||
if (modelGlow == null) return;
|
||||
if (modelGlow == null) return (null, null);
|
||||
|
||||
modelGlow.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags = (uint)(modelGlow.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags & ~(1 << 2));
|
||||
|
||||
|
|
@ -144,9 +267,9 @@ namespace src.player.skills
|
|||
modelGlow.Glow.GlowRangeMin = 10;
|
||||
|
||||
modelGlow.Teleport(knife.AbsOrigin, knife.AbsRotation, knife.AbsVelocity);
|
||||
modelGlow.AcceptInput("SetParent", knife, modelGlow, "!activator");
|
||||
modelGlow.AcceptInput("SetParent", modelRelay, modelGlow, "!activator");
|
||||
|
||||
glows.TryAdd(player.Index, modelGlow.Index);
|
||||
return (modelRelay.Index, modelGlow.Index);
|
||||
}
|
||||
|
||||
public static void OnTriggerEnter(CBaseTrigger trigger, CBaseEntity entity)
|
||||
|
|
@ -155,20 +278,25 @@ namespace src.player.skills
|
|||
|
||||
string triggerName = trigger.Globalname;
|
||||
if (entity.DesignerName != "player" || string.IsNullOrEmpty(triggerName) || !triggerName.StartsWith("trowingknife")) return;
|
||||
|
||||
if (triggers.TryGetValue(trigger.Index, out var throwerIndex))
|
||||
|
||||
CCSPlayerPawn victimPawn = entity.As<CCSPlayerPawn>();
|
||||
if (victimPawn == null || !victimPawn.IsValid || victimPawn.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
|
||||
|
||||
KnifeInfo? knifeInfo = knivesInfo.Values.FirstOrDefault(ki => ki.TriggerIndex == trigger.Index);
|
||||
|
||||
if (knifeInfo != null)
|
||||
{
|
||||
var thrower = Utilities.GetPlayerFromIndex((int)throwerIndex);
|
||||
var thrower = Utilities.GetPlayerFromIndex((int)knifeInfo.PlayerIndex);
|
||||
if (thrower == null || !thrower.IsValid) return;
|
||||
|
||||
CCSPlayerPawn victimPawn = entity.As<CCSPlayerPawn>();
|
||||
if (victimPawn == null || !victimPawn.IsValid || victimPawn.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
|
||||
|
||||
if (thrower != null && thrower.Pawn.Value != null && victimPawn.Index == thrower.Pawn.Index) return;
|
||||
|
||||
bool friendlyFire = SkillsInfo.GetValue<bool>(skillName, "friendlyFire");
|
||||
if (!friendlyFire && thrower?.TeamNum == victimPawn.TeamNum) return;
|
||||
|
||||
if (CheckHasKnife(thrower!)) return;
|
||||
|
||||
SkillUtils.TakeHealth(victimPawn, 99999);
|
||||
Server.PrintToChatAll($"HIT");
|
||||
SkillUtils.TakeHealth(victimPawn, SkillsInfo.GetValue<int>(skillName, "damage"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -179,6 +307,31 @@ namespace src.player.skills
|
|||
return pawn.WeaponServices.MyWeapons.Any(w => w.IsValid && w != null && w.Value != null && w.Value.IsValid && (w.Value.DesignerName.Contains("knife") || w.Value.DesignerName.Contains("bayonet")));
|
||||
}
|
||||
|
||||
private static (CBaseEntity?, KnifeInfo?) GetClosetKnife(Vector pos)
|
||||
{
|
||||
double minDistance = double.MaxValue;
|
||||
KnifeInfo? minKnifeInfo = null;
|
||||
CBaseEntity? closet = null;
|
||||
|
||||
foreach (var knifeInfo in knivesInfo.Values)
|
||||
{
|
||||
if (!knifeInfo.IsDropped) continue;
|
||||
|
||||
var knifeEntity = Utilities.GetEntityFromIndex<CBaseEntity>((int)knifeInfo.KnifeIndex);
|
||||
if (knifeEntity == null || !knifeEntity.IsValid || knifeEntity.AbsOrigin == null) continue;
|
||||
|
||||
double distance = SkillUtils.GetDistance(knifeEntity.AbsOrigin, pos);
|
||||
if (distance < minDistance)
|
||||
{
|
||||
minDistance = distance;
|
||||
closet = knifeEntity;
|
||||
minKnifeInfo = knifeInfo;
|
||||
}
|
||||
}
|
||||
|
||||
return (closet, minKnifeInfo);
|
||||
}
|
||||
|
||||
public static void CheckTransmit([CastFrom(typeof(nint))] CCheckTransmitInfoList infoList)
|
||||
{
|
||||
foreach (var (info, player) in infoList)
|
||||
|
|
@ -186,19 +339,35 @@ namespace src.player.skills
|
|||
if (player == null || !player.IsValid) continue;
|
||||
var observedPlayer = Utilities.GetPlayers().FirstOrDefault(p => p?.Pawn?.Value?.Handle == player?.Pawn?.Value?.ObserverServices?.ObserverTarget?.Value?.Handle);
|
||||
|
||||
foreach (var glow in glows)
|
||||
foreach ((uint playerIndex, KnifeInfo knifeInfo) in knivesInfo)
|
||||
{
|
||||
if (glow.Key == player.Index || (observedPlayer != null && observedPlayer.IsValid && glow.Key == observedPlayer.Index)) continue;
|
||||
if (playerIndex == player.Index || (observedPlayer != null && observedPlayer.IsValid && playerIndex == observedPlayer.Index)) continue;
|
||||
if (knifeInfo.GlowIndex == null) continue;
|
||||
|
||||
var glowEntity = Utilities.GetEntityFromIndex<CBaseEntity>((int)glow.Value);
|
||||
var glowEntity = Utilities.GetEntityFromIndex<CBaseEntity>((int)knifeInfo.GlowIndex);
|
||||
if (glowEntity == null || !glowEntity.IsValid) continue;
|
||||
info.TransmitEntities.Remove(glowEntity.Index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#8f108f", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "") : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
|
||||
public class KnifeInfo()
|
||||
{
|
||||
public required uint PlayerIndex { get; set; }
|
||||
public required uint KnifeIndex { get; set; }
|
||||
public required ulong KnifeId { get; set; }
|
||||
public required uint? TriggerIndex { get; set; }
|
||||
public required uint? GlowIndex { get; set; }
|
||||
public required uint? RelayIndex { get; set; }
|
||||
public bool IsDropped { get; set; } = false;
|
||||
public QAngle? InitialLook { get; set; } = null;
|
||||
public Timer? Timer { get; set; } = null;
|
||||
}
|
||||
|
||||
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#8f108f", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = true, bool needsTeammates = false, string requiredPermission = "", bool friendlyFire = false, int damage = 9999) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
|
||||
{
|
||||
public bool FriendlyFire { get; set; } = friendlyFire;
|
||||
public int Damage { get; set; } = damage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,6 @@ using CounterStrikeSharp.API.Modules.Entities.Constants;
|
|||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
using src.utils;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Runtime.InteropServices;
|
||||
using static src.jRandomSkills;
|
||||
|
||||
namespace src.player.skills
|
||||
|
|
@ -12,51 +11,39 @@ namespace src.player.skills
|
|||
public class ToxicSmoke : ISkill
|
||||
{
|
||||
private const Skills skillName = Skills.ToxicSmoke;
|
||||
private static readonly ConcurrentDictionary<CCSPlayerController, byte> players = [];
|
||||
private static readonly ConcurrentDictionary<CTriggerMultiple, byte> triggers = [];
|
||||
|
||||
private const string triggerName = "toxic_smoke";
|
||||
private static readonly ConcurrentDictionary<Vector, byte> smokes = [];
|
||||
|
||||
public static void LoadSkill()
|
||||
{
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
|
||||
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
|
||||
}
|
||||
|
||||
public static void NewRound()
|
||||
{
|
||||
players.Clear();
|
||||
triggers.Clear();
|
||||
smokes.Clear();
|
||||
}
|
||||
|
||||
public static void EnableSkill(CCSPlayerController player)
|
||||
public static void SmokegrenadeDetonate(EventSmokegrenadeDetonate @event)
|
||||
{
|
||||
SkillUtils.TryGiveWeapon(player, CsItem.SmokeGrenade);
|
||||
var player = @event.Userid;
|
||||
if (player == null || !player.IsValid) return;
|
||||
|
||||
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
|
||||
if (playerInfo?.Skill != skillName) return;
|
||||
|
||||
smokes.TryAdd(new Vector(@event.X, @event.Y, @event.Z), 0);
|
||||
}
|
||||
|
||||
public static void OnTriggerEnter(CBaseTrigger trigger, CBaseEntity entity)
|
||||
public static void SmokegrenadeExpired(EventSmokegrenadeExpired @event)
|
||||
{
|
||||
if (!trigger.Globalname.StartsWith(triggerName) || entity.DesignerName != "player") return;
|
||||
var player = @event.Userid;
|
||||
if (player == null || !player.IsValid) return;
|
||||
|
||||
CCSPlayerPawn playerPawn = new(entity.Handle);
|
||||
if (playerPawn == null || playerPawn.Controller?.Value == null)return;
|
||||
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
|
||||
if (playerInfo?.Skill != skillName) return;
|
||||
|
||||
CCSPlayerController player = playerPawn.Controller.Value.As<CCSPlayerController>();
|
||||
if (player == null) return;
|
||||
|
||||
players.TryAdd(player, 0);
|
||||
}
|
||||
|
||||
public static void OnTriggerExit(CBaseTrigger trigger, CBaseEntity entity)
|
||||
{
|
||||
if (!trigger.Globalname.StartsWith(triggerName) || entity.DesignerName != "player") return;
|
||||
|
||||
CCSPlayerPawn playerPawn = new(entity.Handle);
|
||||
if (playerPawn == null || playerPawn.Controller?.Value == null) return;
|
||||
CCSPlayerController player = playerPawn.Controller.Value.As<CCSPlayerController>();
|
||||
if (player == null) return;
|
||||
|
||||
players.TryRemove(player, out _);
|
||||
foreach (var smoke in smokes.Keys.Where(v => v.X == @event.X && v.Y == @event.Y && v.Z == @event.Z))
|
||||
smokes.TryRemove(smoke, out _);
|
||||
}
|
||||
|
||||
public static void OnEntitySpawned(CEntityInstance entity)
|
||||
|
|
@ -85,30 +72,28 @@ namespace src.player.skills
|
|||
});
|
||||
}
|
||||
|
||||
public static void SmokegrenadeDetonate(EventSmokegrenadeDetonate @event)
|
||||
public static void OnTick()
|
||||
{
|
||||
var player = @event.Userid;
|
||||
if (player == null || !player.IsValid) return;
|
||||
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
|
||||
if (playerInfo?.Skill != skillName) return;
|
||||
int tick = SkillsInfo.GetValue<int>(skillName, "tickCooldown");
|
||||
if (Server.TickCount % tick != 0) return;
|
||||
|
||||
var trigger = SkillUtils.CreateTrigger(triggerName, SkillsInfo.GetValue<float>(skillName, "smokeRadius"), new Vector(@event.X, @event.Y, @event.Z));
|
||||
if (trigger == null) return;
|
||||
triggers.TryAdd(trigger, 0);
|
||||
float smokeRadius = SkillsInfo.GetValue<float>(skillName, "smokeRadius");
|
||||
int smokeDamage = SkillsInfo.GetValue<int>(skillName, "smokeDamage");
|
||||
|
||||
foreach (Vector smokePos in smokes.Keys)
|
||||
foreach (var player in Utilities.GetPlayers().Where(p => p.IsValid && p.PawnIsAlive))
|
||||
{
|
||||
var pawn = player.PlayerPawn.Value;
|
||||
if (pawn == null || !pawn.IsValid || pawn.AbsOrigin == null) continue;
|
||||
|
||||
if (SkillUtils.GetDistance(smokePos, pawn.AbsOrigin) <= smokeRadius)
|
||||
AddHealth(pawn, -smokeDamage);
|
||||
}
|
||||
}
|
||||
|
||||
public static void SmokegrenadeExpired(EventSmokegrenadeExpired @event)
|
||||
public static void EnableSkill(CCSPlayerController player)
|
||||
{
|
||||
var player = @event.Userid;
|
||||
if (player == null || !player.IsValid) return;
|
||||
var playerInfo = Instance.SkillPlayer.FirstOrDefault(p => p.SteamID == player.SteamID);
|
||||
if (playerInfo?.Skill != skillName) return;
|
||||
|
||||
foreach (var trigger in triggers.Keys.Where(t => t.AbsOrigin?.X == @event.X && t.AbsOrigin?.Y == @event.Y && t.AbsOrigin?.Z == @event.Z))
|
||||
{
|
||||
triggers.TryRemove(trigger, out _);
|
||||
trigger.AcceptInput("Kill");
|
||||
}
|
||||
SkillUtils.TryGiveWeapon(player, CsItem.SmokeGrenade);
|
||||
}
|
||||
|
||||
private static void AddHealth(CCSPlayerPawn player, int health)
|
||||
|
|
@ -124,20 +109,11 @@ namespace src.player.skills
|
|||
player.CommitSuicide(false, true);
|
||||
}
|
||||
|
||||
public static void OnTick()
|
||||
{
|
||||
if (Server.TickCount % 17 != 0) return;
|
||||
foreach (var player in players.Keys)
|
||||
{
|
||||
if (player == null || !player.IsValid || player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid || !player.PawnIsAlive) return;
|
||||
AddHealth(player.PlayerPawn.Value, -SkillsInfo.GetValue<int>(skillName, "smokeDamage"));
|
||||
}
|
||||
}
|
||||
|
||||
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#507529", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int smokeDamage = 2, float smokeRadius = 180) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
|
||||
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#507529", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", int smokeDamage = 2, float smokeRadius = 180, int tickCooldown = 17) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission)
|
||||
{
|
||||
public int SmokeDamage { get; set; } = smokeDamage;
|
||||
public float SmokeRadius { get; set; } = smokeRadius;
|
||||
public int TickCooldown { get; set; } = tickCooldown;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue