v1.2.3.b2 - Part 2

## GENERAL
- Added a css_entity admin command to check whether an entity with a given index/handle exists (prints the designer name to chat or console).
- Added a TakeDamage post-hook (OnTakeDamagePost) alongside the existing pre-hook, so skills can now react after damage has actually been applied, not just before.
- Added CreateMolotovProjectile (new CMolotovProjectile_CreateFunc signature) and CreateTrackedChicken entity helpers.
- Added a weapon_mp7 → weapon_mp5sd fallback mapping.
- Added class for KillfeedIcons

## SKILL IMPROVEMENTS
- Aimbot:
  -- Only forces a headshot hitgroup once (skips if it's already a head or an invalid hitgroup), and now restores the original hitgroup value in the new post-damage hook instead of leaving it overwritten.
- Tripwire:
  -- Reduced the default wire width from 1.5 to 0.7.

## NEW SKILLS:
- Berserker: You deal more damage and move faster as your health gets lower.
- Blast Shot: Press Attack2 with the MP5 to fire an HE grenade.
- Demon Eye: You deal damage to every enemy you are looking at.
- Fire Rain: Throw a decoy to call down a rain of Molotovs.
- Flashlight: Click [css_useSkill] to turn the flashlight on or off; its light can blind enemies.
- Healing Chicken: Your chickens heal you while you are nearby.
- Jetkick: Select a player to jetkick - every shot they fire knocks them backwards until disabled.
- Last Gasp: After you die, you deal damage to the enemy who killed you.
- Take Ammo: Click [css_useSkill] to take the active weapon's magazine from a random enemy.
- Team Teleport: Press [css_useSkill] to teleport to the teammate you're looking at.
This commit is contained in:
Juzlus 2026-07-31 20:28:02 +02:00
parent 203a0c3986
commit 8038a4d646
57 changed files with 3663 additions and 553 deletions

View file

@ -32,6 +32,8 @@ namespace src.utils
LazySig<MemoryFunctionWithReturn<IntPtr, IntPtr, IntPtr, IntPtr, IntPtr, IntPtr, IntPtr, int>>("HEGrenadeProjectile_CreateFunc", s => new(s));
private static readonly Lazy<MemoryFunctionWithReturn<IntPtr, IntPtr, IntPtr, IntPtr, IntPtr, int, int, CSmokeGrenadeProjectile>?> SmokeGrenadeProjectile_CreateFunc =
LazySig<MemoryFunctionWithReturn<IntPtr, IntPtr, IntPtr, IntPtr, IntPtr, int, int, CSmokeGrenadeProjectile>>("SmokeGrenadeProjectile_CreateFunc", s => new(s));
private static readonly Lazy<MemoryFunctionWithReturn<IntPtr, IntPtr, IntPtr, IntPtr, IntPtr, IntPtr, IntPtr, int>?> CMolotovProjectile_CreateFunc =
LazySig<MemoryFunctionWithReturn<IntPtr, IntPtr, IntPtr, IntPtr, IntPtr, IntPtr, IntPtr, int>>("CMolotovProjectile_CreateFunc", s => new(s));
private static readonly Lazy<MemoryFunctionVoid<nint, float, RoundEndReason, nint, nint>?> TerminateRoundFunc =
LazySig<MemoryFunctionVoid<nint, float, RoundEndReason, nint, nint>>("CCSGameRules_TerminateRound", s => new(s));
private static readonly Lazy<MemoryFunctionVoid<CBasePlayerPawn, QAngle>?> SnapViewAngles =
@ -310,6 +312,11 @@ namespace src.utils
SmokeGrenadeProjectile_CreateFunc.Value?.Invoke(pos.Handle, angle.Handle, vel.Handle, vel.Handle, IntPtr.Zero, 45, teamNum);
}
public static void CreateMolotovProjectile(Vector pos, QAngle angle, Vector vel, int teamNum)
{
CMolotovProjectile_CreateFunc.Value?.Invoke(pos.Handle, angle.Handle, vel.Handle, vel.Handle, IntPtr.Zero, 46, teamNum);
}
// True when this hit would be nullified by the server's friendly-fire rules (same-team hit,
// mp_friendlyfire 0 and mp_teammates_are_enemies 0). The TakeDamage pre-hook still sees the raw
// damage, so lethal victim-side skills (SecondLife/Phoenix) must skip it — otherwise they "revive"
@ -333,9 +340,9 @@ namespace src.utils
private static readonly ConcurrentDictionary<uint, (uint AttackerIndex, string? Weapon, int ExpiryTick)> pendingKillCredits = [];
public static void RegisterKillCredit(uint victimIndex, uint attackerIndex, string? weapon = null)
public static void RegisterKillCredit(uint victimIndex, uint attackerIndex, KillfeedIcons? killfeedIcon = null)
{
pendingKillCredits[victimIndex] = (attackerIndex, weapon, Server.TickCount + 64);
pendingKillCredits[victimIndex] = (attackerIndex, killfeedIcon == null ? null : KillfeedIconsExtensions.ToIcon((KillfeedIcons)killfeedIcon), Server.TickCount + 64);
}
public static bool TryConsumeKillCredit(uint victimIndex, out uint attackerIndex, out string? weapon)
@ -505,7 +512,7 @@ namespace src.utils
.Cast<CCSPlayerController>()];
}
public static bool TakeHealth(CCSPlayerPawn? pawn, int damage, CCSPlayerController? damageAttacker = null, string? damageWeapon = 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)
return false;
@ -546,9 +553,8 @@ namespace src.utils
if (pawn.Health <= 0)
{
if (damageAttacker != null && damageAttacker.IsValid && victim != null && victim.IsValid
&& damageAttacker.Index != victim.Index)
RegisterKillCredit(victim.Index, damageAttacker.Index, damageWeapon);
if (damageAttacker != null && damageAttacker.IsValid && victim != null && victim.IsValid && damageAttacker.Index != victim.Index)
RegisterKillCredit(victim.Index, damageAttacker.Index, killfeedIcon);
Server.NextFrame(() =>
{
@ -752,6 +758,7 @@ namespace src.utils
("weapon_m4a1", 60) => "weapon_m4a1_silencer",
("weapon_hkp2000", 61) => "weapon_usp_silencer",
("weapon_deagle", 64) => "weapon_revolver",
("weapon_mp7", 23) => "weapon_mp5sd",
_ => designerName
};