v1.2.3.b9
- #### Fixes
- **Pyro** - Fire damage killed the holder at low health. The regeneration now runs before the damage is applied instead of after.
- **Iana** - The clone did not absorb a lethal hit, same cause as Pyro.
- **Dracula** - Lifesteal used the raw damage, so an AWP headshot healed for 400. It is now capped to the health the victim actually had, works on the killing blow, and can no longer leave the attacker alive at 0 HP.
- **RobinHood** - Stolen money used the raw damage and a hardcoded 16000 cap. It is now capped to the victim's real health, works on the killing blow, and respects `mp_maxmoney`. The victim loses exactly what the attacker gains.
- **Voodoo** - Reflected damage used the raw damage, now capped to the victim's real health.
- **Config** - The `Rifle`, `Pistol` and `Grenade` weapon pools grew every time the config was loaded, so removed weapons came back on the next start.
- **Use button** - Skills no longer trigger when a CT presses `Use` while looking at a planted C4, so the skill key no longer competes with the defuse key.
- #### Other
- Built against CounterStrikeSharp 1.0.373.
This commit is contained in:
parent
d5fefbe178
commit
a62ec611ca
17 changed files with 150 additions and 62 deletions
|
|
@ -7,7 +7,7 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="CounterStrikeSharp.API" Version="1.0.371" />
|
<PackageReference Include="CounterStrikeSharp.API" Version="1.0.373" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="CounterStrikeSharp.API" Version="1.0.371" />
|
<PackageReference Include="CounterStrikeSharp.API" Version="1.0.373" />
|
||||||
<PackageReference Include="MaxMind.Db" Version="5.1.0">
|
<PackageReference Include="MaxMind.Db" Version="5.1.0">
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ namespace src
|
||||||
public override string ModuleName => "[CS2] [ jRandomSkills ]";
|
public override string ModuleName => "[CS2] [ jRandomSkills ]";
|
||||||
public override string ModuleAuthor => "D3X (Original), Juzlus (Modifier), ByDexterTR (Contributor)";
|
public override string ModuleAuthor => "D3X (Original), Juzlus (Modifier), ByDexterTR (Contributor)";
|
||||||
public override string ModuleDescription => "Plugin adds random skills every round for CS2 by D3X. Modified by Juzlus.";
|
public override string ModuleDescription => "Plugin adds random skills every round for CS2 by D3X. Modified by Juzlus.";
|
||||||
public override string ModuleVersion => "1.2.3.b8";
|
public override string ModuleVersion => "1.2.3.b9";
|
||||||
|
|
||||||
public override void Load(bool hotReload)
|
public override void Load(bool hotReload)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
using CounterStrikeSharp.API;
|
using CounterStrikeSharp.API;
|
||||||
using CounterStrikeSharp.API.Core;
|
using CounterStrikeSharp.API.Core;
|
||||||
using CounterStrikeSharp.API.Core.Attributes;
|
using CounterStrikeSharp.API.Core.Attributes;
|
||||||
using CounterStrikeSharp.API.Modules.Memory;
|
using CounterStrikeSharp.API.Modules.Memory;
|
||||||
|
|
@ -89,6 +89,7 @@ namespace src.player
|
||||||
lock (setLock)
|
lock (setLock)
|
||||||
{
|
{
|
||||||
CountDamageResolution(info);
|
CountDamageResolution(info);
|
||||||
|
SkillUtils.TrackHealthBeforeHit(entity, info);
|
||||||
|
|
||||||
object[] args = [entity, info];
|
object[] args = [entity, info];
|
||||||
DispatchOnTakeDamage(entity, info, args);
|
DispatchOnTakeDamage(entity, info, args);
|
||||||
|
|
|
||||||
|
|
@ -798,6 +798,8 @@ namespace src.player
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (designer == "planted_c4" && player.Team == CsTeam.CounterTerrorist) return;
|
||||||
|
|
||||||
if (designer.Contains("button") || designer.Contains("weapon") || designer.Contains("blocker")) return;
|
if (designer.Contains("button") || designer.Contains("weapon") || designer.Contains("blocker")) return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
using CounterStrikeSharp.API;
|
using CounterStrikeSharp.API;
|
||||||
using CounterStrikeSharp.API.Core;
|
using CounterStrikeSharp.API.Core;
|
||||||
using CounterStrikeSharp.API.Core.Attributes;
|
using CounterStrikeSharp.API.Core.Attributes;
|
||||||
using CounterStrikeSharp.API.Modules.Admin;
|
using CounterStrikeSharp.API.Modules.Admin;
|
||||||
|
|
@ -182,6 +182,7 @@ namespace src.player
|
||||||
Instance.RemoveListener<CheckTransmit>(CheckTransmit);
|
Instance.RemoveListener<CheckTransmit>(CheckTransmit);
|
||||||
|
|
||||||
Fortnite.skillInThisRound = false;
|
Fortnite.skillInThisRound = false;
|
||||||
|
SkillUtils.ClearHealthBeforeHit();
|
||||||
|
|
||||||
EntityManager.SuppressKills = true;
|
EntityManager.SuppressKills = true;
|
||||||
try
|
try
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
using CounterStrikeSharp.API;
|
using CounterStrikeSharp.API;
|
||||||
using CounterStrikeSharp.API.Core;
|
using CounterStrikeSharp.API.Core;
|
||||||
using CounterStrikeSharp.API.Modules.Utils;
|
using CounterStrikeSharp.API.Modules.Utils;
|
||||||
using src.utils;
|
using src.utils;
|
||||||
|
|
@ -9,7 +9,6 @@ namespace src.player.skills
|
||||||
public class Dracula : ISkill
|
public class Dracula : ISkill
|
||||||
{
|
{
|
||||||
private const Skills skillName = Skills.Dracula;
|
private const Skills skillName = Skills.Dracula;
|
||||||
|
|
||||||
public static void LoadSkill()
|
public static void LoadSkill()
|
||||||
{
|
{
|
||||||
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
|
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
|
||||||
|
|
@ -20,11 +19,11 @@ namespace src.player.skills
|
||||||
var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
|
var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
|
||||||
var victim = PlayerManager.GetPlayerEvent(@event.Userid);
|
var victim = PlayerManager.GetPlayerEvent(@event.Userid);
|
||||||
|
|
||||||
if (!Instance.IsPlayerValid(attacker) || !Instance.IsPlayerValid(victim) || attacker == victim) return;
|
if (!Instance.IsPlayerValid(attacker) || victim == null || !victim.IsValid || attacker == victim) return;
|
||||||
var playerInfo = PlayerManager.GetPlayerByIndex(attacker!.Index);
|
var playerInfo = PlayerManager.GetPlayerByIndex(attacker!.Index);
|
||||||
|
if (playerInfo?.Skill != skillName) return;
|
||||||
|
|
||||||
if (playerInfo?.Skill == skillName && victim!.PawnIsAlive)
|
HealAttacker(attacker!, SkillUtils.CapToVictimHealth(victim, @event.DmgHealth));
|
||||||
HealAttacker(attacker!, @event.DmgHealth);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void DisableSkill(CCSPlayerController player)
|
public static void DisableSkill(CCSPlayerController player)
|
||||||
|
|
@ -46,14 +45,21 @@ namespace src.player.skills
|
||||||
|
|
||||||
private static void HealAttacker(CCSPlayerController attacker, float damage)
|
private static void HealAttacker(CCSPlayerController attacker, float damage)
|
||||||
{
|
{
|
||||||
var attackerPawn = attacker.PlayerPawn?.Value;
|
int extraHealth = (int)(damage * SkillsInfo.GetValue<float>(skillName, "healthRegainScale"));
|
||||||
|
if (extraHealth <= 0) return;
|
||||||
|
|
||||||
|
uint attackerIndex = attacker.Index;
|
||||||
|
|
||||||
|
Server.NextFrame(() =>
|
||||||
|
{
|
||||||
|
var target = Utilities.GetPlayerFromIndex((int)attackerIndex);
|
||||||
|
if (target == null || !target.IsValid) return;
|
||||||
|
|
||||||
|
var attackerPawn = target.PlayerPawn?.Value;
|
||||||
if (attackerPawn == null || !attackerPawn.IsValid) return;
|
if (attackerPawn == null || !attackerPawn.IsValid) return;
|
||||||
|
|
||||||
if (attackerPawn.LifeState != (byte)LifeState_t.LIFE_ALIVE || attackerPawn.Health <= 0) return;
|
if (attackerPawn.LifeState != (byte)LifeState_t.LIFE_ALIVE || attackerPawn.Health <= 0) return;
|
||||||
|
|
||||||
int extraHealth = (int)(damage * SkillsInfo.GetValue<float>(skillName, "healthRegainScale"));
|
|
||||||
if (extraHealth <= 0) return;
|
|
||||||
|
|
||||||
attackerPawn.Health += extraHealth;
|
attackerPawn.Health += extraHealth;
|
||||||
Utilities.SetStateChanged(attackerPawn, "CBaseEntity", "m_iHealth");
|
Utilities.SetStateChanged(attackerPawn, "CBaseEntity", "m_iHealth");
|
||||||
|
|
||||||
|
|
@ -62,6 +68,7 @@ namespace src.player.skills
|
||||||
attackerPawn.MaxHealth = attackerPawn.Health;
|
attackerPawn.MaxHealth = attackerPawn.Health;
|
||||||
Utilities.SetStateChanged(attackerPawn, "CBaseEntity", "m_iMaxHealth");
|
Utilities.SetStateChanged(attackerPawn, "CBaseEntity", "m_iMaxHealth");
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#FA050D", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float? hudDuration = null, float? descriptionHudDuration = null, int maxPerServer = -1, Rarity rarity = Rarity.Common, float healthRegainScale = .3f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, hudDuration, descriptionHudDuration, maxPerServer, rarity)
|
public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#FA050D", CsTeam onlyTeam = CsTeam.None, bool disableOnFreezeTime = false, bool needsTeammates = false, string requiredPermission = "", float? hudDuration = null, float? descriptionHudDuration = null, int maxPerServer = -1, Rarity rarity = Rarity.Common, float healthRegainScale = .3f) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, hudDuration, descriptionHudDuration, maxPerServer, rarity)
|
||||||
|
|
|
||||||
|
|
@ -302,13 +302,43 @@ namespace src.player.skills
|
||||||
return shooter != null && shooter.IsValid ? shooter : null;
|
return shooter != null && shooter.IsValid ? shooter : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void AbsorbWithClone(CBaseEntity damagedEntity, CTakeDamageInfo damageInfo)
|
||||||
|
{
|
||||||
|
if (damageInfo.Damage <= 0) return;
|
||||||
|
|
||||||
|
CCSPlayerPawn victimPawn = new(damagedEntity.Handle);
|
||||||
|
if (!victimPawn.IsValid || victimPawn.DesignerName != "player") return;
|
||||||
|
|
||||||
|
var victimController = victimPawn.Controller?.Value;
|
||||||
|
if (victimController == null || !victimController.IsValid) return;
|
||||||
|
|
||||||
|
var victim = PlayerManager.GetPlayerEvent(victimController.As<CCSPlayerController>());
|
||||||
|
if (victim == null || !victim.IsValid) return;
|
||||||
|
|
||||||
|
if (PlayerManager.GetPlayerByIndex(victim.Index)?.Skill != skillName) return;
|
||||||
|
if (!playersInfo.TryGetValue(victim.Index, out var playerSkill)) return;
|
||||||
|
|
||||||
|
bool hasClone = playerSkill.CloneProp != null;
|
||||||
|
if (!hasClone && playerSkill.LastHit + 4 <= Server.TickCount) return;
|
||||||
|
|
||||||
|
damageInfo.Damage = 0;
|
||||||
|
|
||||||
|
if (!hasClone) return;
|
||||||
|
|
||||||
|
KillClone(playerSkill);
|
||||||
|
playerSkill.LastHit = Server.TickCount;
|
||||||
|
}
|
||||||
|
|
||||||
public static void OnTakeDamage(CBaseEntity damagedEntity, CTakeDamageInfo damageInfo)
|
public static void OnTakeDamage(CBaseEntity damagedEntity, CTakeDamageInfo damageInfo)
|
||||||
{
|
{
|
||||||
if (damagedEntity == null || damagedEntity.Entity == null || damageInfo == null)
|
if (damagedEntity == null || damagedEntity.Entity == null || damageInfo == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(damagedEntity.Entity.Name)) return;
|
if (string.IsNullOrEmpty(damagedEntity.Entity.Name) || !damagedEntity.Entity.Name.StartsWith("IanaClone_"))
|
||||||
if (!damagedEntity.Entity.Name.StartsWith("IanaClone_")) return;
|
{
|
||||||
|
AbsorbWithClone(damagedEntity, damageInfo);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var nameParams = damagedEntity.Entity.Name.Split('_')[2];
|
var nameParams = damagedEntity.Entity.Name.Split('_')[2];
|
||||||
_ = uint.TryParse(nameParams, out uint userIndex);
|
_ = uint.TryParse(nameParams, out uint userIndex);
|
||||||
|
|
@ -357,26 +387,6 @@ namespace src.player.skills
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void PlayerHurt(EventPlayerHurt @event)
|
|
||||||
{
|
|
||||||
var victim = PlayerManager.GetPlayerEvent(@event.Userid);
|
|
||||||
if (victim == null || !victim.IsValid) return;
|
|
||||||
|
|
||||||
if (PlayerManager.GetPlayerByIndex(victim.Index)?.Skill != skillName) return;
|
|
||||||
|
|
||||||
if (playersInfo.TryGetValue(victim.Index, out var playerSkill))
|
|
||||||
{
|
|
||||||
if (playerSkill.CloneProp != null)
|
|
||||||
{
|
|
||||||
KillClone(playerSkill);
|
|
||||||
playerSkill.LastHit = Server.TickCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (playerSkill.LastHit + 4 > Server.TickCount)
|
|
||||||
SkillUtils.RestoreHealth(victim);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void BlockWeapon(CCSPlayerController player, bool block)
|
private static void BlockWeapon(CCSPlayerController player, bool block)
|
||||||
{
|
{
|
||||||
if (player == null || !player.IsValid) return;
|
if (player == null || !player.IsValid) return;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
using CounterStrikeSharp.API.Core;
|
using CounterStrikeSharp.API.Core;
|
||||||
using CounterStrikeSharp.API.Modules.Entities.Constants;
|
using CounterStrikeSharp.API.Modules.Entities.Constants;
|
||||||
using CounterStrikeSharp.API.Modules.Utils;
|
using CounterStrikeSharp.API.Modules.Utils;
|
||||||
using src.utils;
|
using src.utils;
|
||||||
|
|
@ -17,19 +17,46 @@ namespace src.player.skills
|
||||||
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
|
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void PlayerHurt(EventPlayerHurt @event)
|
private const string infernoDamage = "inferno";
|
||||||
|
|
||||||
|
private static bool IsInfernoDamage(CTakeDamageInfo damageInfo)
|
||||||
{
|
{
|
||||||
var victim = PlayerManager.GetPlayerEvent(@event.Userid);
|
var ability = damageInfo.Ability?.Value;
|
||||||
int damage = @event.DmgHealth;
|
if (ability != null && ability.IsValid && ability.DesignerName == infernoDamage) return true;
|
||||||
string weapon = @event.Weapon;
|
|
||||||
|
|
||||||
if (weapon != "inferno" || !Instance.IsPlayerValid(victim)) return;
|
var inflictor = damageInfo.Inflictor?.Value;
|
||||||
var victimInfo = PlayerManager.GetPlayerByIndex(victim!.Index);
|
return inflictor != null && inflictor.IsValid && inflictor.DesignerName == infernoDamage;
|
||||||
|
}
|
||||||
|
|
||||||
if (victimInfo == null || victimInfo.Skill != skillName) return;
|
public static void OnTakeDamage(CBaseEntity damagedEntity, CTakeDamageInfo damageInfo)
|
||||||
|
{
|
||||||
|
if (damagedEntity == null || !damagedEntity.IsValid || damageInfo == null) return;
|
||||||
|
if (damageInfo.Damage <= 0 || !IsInfernoDamage(damageInfo)) return;
|
||||||
|
|
||||||
var pawn = victim!.PlayerPawn.Value;
|
CCSPlayerPawn victimPawn = new(damagedEntity.Handle);
|
||||||
SkillUtils.AddHealth(pawn, (int)(damage * SkillsInfo.GetValue<float>(skillName, "regenerationMultiplier")));
|
if (!victimPawn.IsValid || victimPawn.DesignerName != "player") return;
|
||||||
|
|
||||||
|
var victimController = victimPawn.Controller?.Value;
|
||||||
|
if (victimController == null || !victimController.IsValid) return;
|
||||||
|
|
||||||
|
var victim = PlayerManager.GetPlayerEvent(victimController.As<CCSPlayerController>());
|
||||||
|
if (victim == null || !victim.IsValid) return;
|
||||||
|
|
||||||
|
if (PlayerManager.GetPlayerByIndex(victim.Index)?.Skill != skillName) return;
|
||||||
|
|
||||||
|
float damage = damageInfo.Damage;
|
||||||
|
float net = damage * (SkillsInfo.GetValue<float>(skillName, "regenerationMultiplier") - 1f);
|
||||||
|
|
||||||
|
if (net < 0)
|
||||||
|
{
|
||||||
|
damageInfo.Damage = -net;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
damageInfo.Damage = 0;
|
||||||
|
|
||||||
|
int heal = (int)MathF.Round(net);
|
||||||
|
if (heal > 0) SkillUtils.AddHealth(victimPawn, heal);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void GrenadeThrown(EventGrenadeThrown @event)
|
public static void GrenadeThrown(EventGrenadeThrown @event)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
using CounterStrikeSharp.API;
|
using CounterStrikeSharp.API;
|
||||||
using CounterStrikeSharp.API.Core;
|
using CounterStrikeSharp.API.Core;
|
||||||
using CounterStrikeSharp.API.Modules.Utils;
|
using CounterStrikeSharp.API.Modules.Utils;
|
||||||
using static src.jRandomSkills;
|
using static src.jRandomSkills;
|
||||||
|
|
@ -26,7 +26,6 @@ namespace src.player.skills
|
||||||
{
|
{
|
||||||
var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
|
var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
|
||||||
var victim = PlayerManager.GetPlayerEvent(@event.Userid);
|
var victim = PlayerManager.GetPlayerEvent(@event.Userid);
|
||||||
int damage = @event.DmgHealth;
|
|
||||||
|
|
||||||
if (!Instance.IsPlayerValid(attacker) || !Instance.IsPlayerValid(victim) || attacker == victim) return;
|
if (!Instance.IsPlayerValid(attacker) || !Instance.IsPlayerValid(victim) || attacker == victim) return;
|
||||||
var attackerInfo = PlayerManager.GetPlayerByIndex(attacker!.Index);
|
var attackerInfo = PlayerManager.GetPlayerByIndex(attacker!.Index);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
using CounterStrikeSharp.API;
|
using CounterStrikeSharp.API;
|
||||||
using CounterStrikeSharp.API.Core;
|
using CounterStrikeSharp.API.Core;
|
||||||
|
using CounterStrikeSharp.API.Modules.Cvars;
|
||||||
using CounterStrikeSharp.API.Modules.Utils;
|
using CounterStrikeSharp.API.Modules.Utils;
|
||||||
using src.utils;
|
using src.utils;
|
||||||
using static src.jRandomSkills;
|
using static src.jRandomSkills;
|
||||||
|
|
@ -15,16 +16,18 @@ namespace src.player.skills
|
||||||
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
|
SkillUtils.RegisterSkill(skillName, SkillsInfo.GetValue<string>(skillName, "color"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int GetMaxMoney() => ConVar.Find("mp_maxmoney")?.GetPrimitiveValue<int>() ?? 16000;
|
||||||
|
|
||||||
public static void PlayerHurt(EventPlayerHurt @event)
|
public static void PlayerHurt(EventPlayerHurt @event)
|
||||||
{
|
{
|
||||||
var victim = PlayerManager.GetPlayerEvent(@event.Userid);
|
var victim = PlayerManager.GetPlayerEvent(@event.Userid);
|
||||||
var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
|
var attacker = PlayerManager.GetPlayerEvent(@event.Attacker);
|
||||||
var damage = @event.DmgHealth;
|
if (!Instance.IsPlayerValid(attacker) || victim == null || !victim.IsValid || attacker == victim) return;
|
||||||
if (!Instance.IsPlayerValid(attacker) || !Instance.IsPlayerValid(victim) || attacker == victim) return;
|
|
||||||
|
|
||||||
var attackerInfo = PlayerManager.GetPlayerByIndex(attacker!.Index);
|
var attackerInfo = PlayerManager.GetPlayerByIndex(attacker!.Index);
|
||||||
if (attackerInfo?.Skill != skillName) return;
|
if (attackerInfo?.Skill != skillName) return;
|
||||||
|
|
||||||
|
int damage = SkillUtils.CapToVictimHealth(victim, @event.DmgHealth);
|
||||||
int moneyToSteal = damage * SkillsInfo.GetValue<int>(skillName, "moneyMultiplier");
|
int moneyToSteal = damage * SkillsInfo.GetValue<int>(skillName, "moneyMultiplier");
|
||||||
StealMoney(victim!, attacker!, moneyToSteal);
|
StealMoney(victim!, attacker!, moneyToSteal);
|
||||||
}
|
}
|
||||||
|
|
@ -35,11 +38,17 @@ namespace src.player.skills
|
||||||
var attackerMoneyServices = attacker?.InGameMoneyServices;
|
var attackerMoneyServices = attacker?.InGameMoneyServices;
|
||||||
if (victimMoneyServices == null || attackerMoneyServices == null) return;
|
if (victimMoneyServices == null || attackerMoneyServices == null) return;
|
||||||
|
|
||||||
var moneyToAdd = victimMoneyServices.Account < money ? victimMoneyServices.Account : money;
|
int maxMoney = GetMaxMoney();
|
||||||
victimMoneyServices.Account = Math.Max(victimMoneyServices.Account - money, 0);
|
int headroom = Math.Max(maxMoney - attackerMoneyServices.Account, 0);
|
||||||
|
|
||||||
|
int transfer = Math.Min(money, victimMoneyServices.Account);
|
||||||
|
transfer = Math.Min(transfer, headroom);
|
||||||
|
if (transfer <= 0) return;
|
||||||
|
|
||||||
|
victimMoneyServices.Account -= transfer;
|
||||||
Utilities.SetStateChanged(victim!, "CCSPlayerController", "m_pInGameMoneyServices");
|
Utilities.SetStateChanged(victim!, "CCSPlayerController", "m_pInGameMoneyServices");
|
||||||
|
|
||||||
attackerMoneyServices.Account = Math.Min(attackerMoneyServices.Account + moneyToAdd, 16000);
|
attackerMoneyServices.Account += transfer;
|
||||||
Utilities.SetStateChanged(attacker!, "CCSPlayerController", "m_pInGameMoneyServices");
|
Utilities.SetStateChanged(attacker!, "CCSPlayerController", "m_pInGameMoneyServices");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
using CounterStrikeSharp.API;
|
using CounterStrikeSharp.API;
|
||||||
using CounterStrikeSharp.API.Core;
|
using CounterStrikeSharp.API.Core;
|
||||||
using CounterStrikeSharp.API.Modules.Utils;
|
using CounterStrikeSharp.API.Modules.Utils;
|
||||||
using jRandomSkills.src.utils;
|
using jRandomSkills.src.utils;
|
||||||
|
|
@ -138,7 +138,7 @@ namespace src.player.skills
|
||||||
if (victimPawn == null || !victimPawn.IsValid || victimPawn.Health <= 0) return;
|
if (victimPawn == null || !victimPawn.IsValid || victimPawn.Health <= 0) return;
|
||||||
if (victimPawn.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
|
if (victimPawn.LifeState != (byte)LifeState_t.LIFE_ALIVE) return;
|
||||||
|
|
||||||
int reflected = (int)MathF.Round(@event.DmgHealth * SkillsInfo.GetValue<float>(skillName, "reflectPercent"));
|
int reflected = (int)MathF.Round(SkillUtils.CapToVictimHealth(owner, @event.DmgHealth) * SkillsInfo.GetValue<float>(skillName, "reflectPercent"));
|
||||||
if (reflected < 1) return;
|
if (reflected < 1) return;
|
||||||
|
|
||||||
SkillUtils.TakeHealth(victimPawn, reflected, owner, KillfeedIcons.Fist);
|
SkillUtils.TakeHealth(victimPawn, reflected, owner, KillfeedIcons.Fist);
|
||||||
|
|
|
||||||
|
|
@ -290,8 +290,11 @@ namespace src.utils
|
||||||
|
|
||||||
public class WeaponPools
|
public class WeaponPools
|
||||||
{
|
{
|
||||||
|
[JsonProperty(ObjectCreationHandling = ObjectCreationHandling.Replace)]
|
||||||
public required List<string> Rifle { get; set; }
|
public required List<string> Rifle { get; set; }
|
||||||
|
[JsonProperty(ObjectCreationHandling = ObjectCreationHandling.Replace)]
|
||||||
public required List<string> Pistol { get; set; }
|
public required List<string> Pistol { get; set; }
|
||||||
|
[JsonProperty(ObjectCreationHandling = ObjectCreationHandling.Replace)]
|
||||||
public required List<string> Grenade { get; set; }
|
public required List<string> Grenade { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ using RayTraceAPI;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using TraceOptions = RayTraceAPI.TraceOptions;
|
using TraceOptions = RayTraceAPI.TraceOptions;
|
||||||
|
using TraceResult = RayTraceAPI.TraceResult;
|
||||||
using Vector = CounterStrikeSharp.API.Modules.Utils.Vector;
|
using Vector = CounterStrikeSharp.API.Modules.Utils.Vector;
|
||||||
|
|
||||||
namespace src.utils
|
namespace src.utils
|
||||||
|
|
|
||||||
|
|
@ -619,6 +619,34 @@ namespace src.utils
|
||||||
.Cast<CCSPlayerController>()];
|
.Cast<CCSPlayerController>()];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static readonly ConcurrentDictionary<uint, int> healthBeforeHit = [];
|
||||||
|
|
||||||
|
public static void TrackHealthBeforeHit(CBaseEntity? damagedEntity, CTakeDamageInfo? damageInfo)
|
||||||
|
{
|
||||||
|
if (damagedEntity == null || damageInfo == null || damageInfo.Damage <= 0) return;
|
||||||
|
|
||||||
|
CCSPlayerPawn victimPawn = new(damagedEntity.Handle);
|
||||||
|
if (!victimPawn.IsValid || victimPawn.DesignerName != "player") return;
|
||||||
|
|
||||||
|
var victimController = victimPawn.Controller?.Value;
|
||||||
|
if (victimController == null || !victimController.IsValid) return;
|
||||||
|
|
||||||
|
var victim = PlayerManager.GetPlayerEvent(victimController.As<CCSPlayerController>());
|
||||||
|
if (victim == null || !victim.IsValid) return;
|
||||||
|
|
||||||
|
healthBeforeHit[victim.Index] = victimPawn.Health;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int CapToVictimHealth(CCSPlayerController? victim, int dmgHealth)
|
||||||
|
{
|
||||||
|
if (victim == null || !victim.IsValid) return dmgHealth;
|
||||||
|
if (!healthBeforeHit.TryGetValue(victim.Index, out int healthBefore) || healthBefore <= 0) return dmgHealth;
|
||||||
|
|
||||||
|
return dmgHealth > healthBefore ? healthBefore : dmgHealth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ClearHealthBeforeHit() => healthBeforeHit.Clear();
|
||||||
|
|
||||||
public static bool TakeHealth(CCSPlayerPawn? pawn, int damage, CCSPlayerController? damageAttacker = null, KillfeedIcons? killfeedIcon = null)
|
public static bool TakeHealth(CCSPlayerPawn? pawn, int damage, CCSPlayerController? damageAttacker = null, KillfeedIcons? killfeedIcon = null)
|
||||||
{
|
{
|
||||||
if (pawn == null || !pawn.IsValid || pawn.LifeState != (byte)LifeState_t.LIFE_ALIVE)
|
if (pawn == null || !pawn.IsValid || pawn.LifeState != (byte)LifeState_t.LIFE_ALIVE)
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue