New skills (9)
- Bounty: put a cash price on an enemy's head, the killer collects it.
- EmpGrenade: grenade victims lose radar and crosshair for a while.
- GravityDecoy: the decoy alters gravity for everyone in its radius.
- Heavyweight: immune to push and slow effects from other skills.
- Nemesis: the marked player takes extra damage from everyone.
- Punisher: banks part of the damage you take and releases it on your next hit.
- Rewind: drop a marker and teleport back to it shortly after.
- TrueArmor: armor absorbs part of incoming damage instead of health.
- Voodoo: the marked enemy shares the damage you take.
Shared systems
- DecoyRing: reusable ground ring so decoy skills show their real area of effect. Adopted by FireRain, FrozenDecoy, GravityDecoy and MagneticDecoy.
- WeaponPool: single cached weapon classification (rifle/pistol/grenade) with a normalizing lookup, backed by the new config Weapons section. Replaces the duplicated hardcoded arrays in Assassin, Chicken, Ghost, NoNades, PrimaryBan, RandomWeapon, SniperElite and WeaponsSwap. [because of compatibility with WeaponRestrict]
- HUD suppression registry in SkillUtils: crosshair and radar hiding is now refcounted per owner, so overlapping skills (Glitch, Jammer, EmpGrenade) cannot restore each other's state early.
- SkillUtils.ResolveHiddenPawns: shared invisible-pawn resolution for C4Camouflage, Ghost and Ninja.
- Config gained a Weapons section with automatic migration for existing installs, plus a per-skill DisableOnPistolRound switch honoured by both the round draw and css_setskill.
Sound
- Volume rebalance
- Add SkillUtils.EmitSoundToPlayer with a private RecipientFilter. A null filter had been broadcasting every skill sound to all clients. Migrated 16 call sites: Poison, DemonEye, ToxicSmoke, CarefulBullets, Thorns, HotBomb, LastGasp, LongKnife, Nightmare, Jester, Tripwire, Medic, HealingSmoke, Rewind, Watchmaker.
- New effects: LongKnife knife-hit feedback (Weapon_Knife.Hit.Heavy/Light), Grapple hook impact, Fortnite barricade placement, Ricochet bounce, Nightmare cursed tone, Replicator/Illusionist spawn, PsychicDefusing defuse cue, TakeAmmo pickup, Tripwire and Jammer trigger tones.
- 29 skills gained a configurable SoundVolume, LongKnife also HitSoundVolume.
- Grapple: emit the hook impact at the hook entity instead of at the owner so the enemy team can locate it.
- PawelJumper: the engine already plays the first jump, only extra jumps emit.
Models and visuals
- Grapple: real hook model with configurable hookScale and hookEmbed so the hook sits in the surface it hit.
- Pilot: glowing exhaust trail parented to the pawn, active only while airborne.
Performance
- SkillsInfo.GetValue now resolves through a ConcurrentDictionary cache instead of reflecting on every call; invalidated on config reload.
- HUD render cache keyed on player, config, description flag and the three source lines; identical frames skip the rebuild.
- Glaz.CheckTransmit: hoist smoke index resolution out of the per-viewer loop and build the pawn-owner map lazily.
- playersSkills switched from ConcurrentBag to HashSet<Skills>, turning the NoRepeat filter from an O(n) scan into a set lookup.
Fixes
- NoRepeat could hand a player two or three skills in one round because the history bag was never deduplicated; the HashSet rewrite closes it.
- SniperElite: restore the saved weapon after the halftime team swap instead of dropping it on the pistol round.
- Illiterate: the holder alert now reaches chat and is exempt from its own scrambler via PrintToChat(ignoreIlliterate).
- EntityManager.DestroyBeam: zero out width and render colour before the kill so beams cannot linger visibly, with a next-frame Remove fallback.
- Ricochet: drop all 18 diagnostic Trace calls and the Trace helper; the skill measured stable over 48h and the tracing dominated the debug log.
Debug
- Tag round start, round end and freeze-time-end lines with [WARMUP] so warmup load is separable from live rounds.
## 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.
## Added
- **`CurseSkillPerPlayer`** (config.json) — limits how many curse skills (Darkness, JumpBan, PrimaryBan, Bankrupt and 14 others) can be stacked on a single player per round. `null` = unlimited (default), `1` = one curse per player, `2` = two. When the limit is reached the target is rejected and the curser gets a chat warning. Enforced centrally in `SkillAction`, so no per-skill code is needed.
- **Tripwire cooldown mode** — replaces the fixed wire limit with a Replicator-style cooldown. Players can place as many wires as they want as long as the cooldown is up; remaining time is shown on the HUD. Configurable via `Cooldown` in skillsInfo.json (default 20s).
- **Tripwire team colors** — T wires red (255, 64, 64), CT wires blue (64, 128, 255).
## Fixed
- **ExpensiveAmmo** also charged money for knife swings and grenade throws. It now only charges when a bullet-firing weapon is fired.
- **Knockback** also triggered on grenade throws; bound to the same allowlist.
## Removed
- Dead code: `Earthquake.cs` and `HealingChicken.cs` (neither was registered in the `Skills` enum, so neither ever ran), `EntityManager.CreateTrackedEnvShake`, `EntityManager.CreateTrackedChicken`, `PlayerManager.UpdatePlayerSkill`.
## Changed
- **Tripwire wires are now removed when the owner dies or loses the skill.** Previously they stayed on the map until the end of the round.
- `PlayerEvents.cs` split into three partial files: player events in `PlayerEvents.cs`, round and skill dispatch in `RoundEvents.cs`, entity and weapon hooks in `EntityEvents.cs`. Behaviour is unchanged; all members stay in the same `Event` class.
- 28 copy-pasted enemy-gathering LINQ chains reduced to the shared helper (Bankrupt, CarefulBullets, Darkness, Deactivator, Deaf, ExpensiveAmmo, Giant, Glitch, Jammer, JumpBan, JumpCurse, LifeSwap, Magnifier, MoneySwap, Nightmare, Poison, PrimaryBan, WildThrow).
Revive skills (Second Chance / Phoenix / Re-Zombie) — unified "on death" logic:
- Intercept the lethal hit before it is applied. Previously they reacted after the death was already committed, so one-shots, fall damage and skill-based kills were missed (Phoenix and Re-Zombie were rewritten from a post-death handler to pre-damage interception).
Killer Flash:
- Kills through real damage instead of forcing a suicide, so revive skills can intercept.
Baseball:
- Fixed a rare server crash from decoy grenades: a freed decoy's entity index could be reused by another entity and written to (use-after-free). Decoy tracking is now validated per tick (DesignerName gate) and cleared every round.
Native crash hardening:
- Aimbot: guard the hit-group native pointer before writing (avoids writing to freed/null memory).
- Wallhack: detach the glow when the target dies or disconnects (stale FollowEntity on a freed pawn).
- Spectator / Cypher / FalconEye / ThirdEye: null-guard the camera SceneNode walk and re-validate the target before teleport/parent (cross-frame freed-entity deref).
- CServerSideClient.ForceFullUpdate now bails on a null client handle.
Performance:
- Added a per-tick player/bomb cache (PlayerManager.GetTickPlayers / GetTickBomb).
- Migrated 82 skills from per-skill Utilities.GetPlayers() to the one shared per-tick scan, and the HUD loop reuses it. Much lower per-tick cost at high player counts (verified 10v10).
RayTrace:
- Prints a single notice when the module is not installed; dependent skills (Long Zeus, Long Knife, Iana, Cypher, Noclip, Shade + the skill-use aim check) no-op instead of failing silently (#43).
General:
- Jester's no-damage state no longer applies to players who do not hold the
skill. The shared health helper checked Jester's internal table without
verifying the current assignment, so a single stale entry silently cancelled
damage across every skill that deals damage through it.
- Jester's per-round reset no longer aborts when the holder is dead, which
previously left the table populated for the following rounds.
- The per-round reset now covers every skill used on the current map instead of
only the ones held in the round that just ended, so a skill nobody drew still
clears state left over from an earlier round.
- Skills that track another player as a target are now notified when that player
disconnects. Controller indexes are reused, so a leftover entry applied to
whoever connected into that index next. Affects Poison, Deaf, Darkness,
Glitch, Magnifier, Legless, No Rifles, Jammer and Jester.
- Aimbot no longer retains raw native pointers after a hit is handled. They were
never cleared and were written back to later, which could corrupt memory the
engine had already freed.
- An exception inside a skill's OnTick no longer cancels the tick of every skill
after it in the same frame.
- Cooldowns configured low enough to truncate to zero no longer throw (Poison,
Regeneration, Hot Bomb, Healing Smoke, Toxic Smoke).
- Round changes are cheaper: Long Knife no longer detaches a detour it never
attached, and Wild Throw skips its player sweep when it has nothing to unwind.
Skill improvements:
- Second Chance: now survives several lethal hits landing in the same tick
(shotgun, two attackers) and restores health inside the damage hook instead of
a frame later. It also runs after skills that modify damage, so One-Shot and
Soldier are seen at their final value instead of the raw one.
- Spectator: returning to your own view no longer leaves the camera handle set,
which made the tick handler reset the weapon cooldown every frame and play as
rapid fire. The manual toggle is unchanged.
- Radar Hack: players hidden behind a replacement model (Chicken) are shown on
the radar again. Only Ghost, Ninja and C4 Camouflage hide the pawn itself, so
render alpha alone no longer decides.
- Focus: weapon_accuracy_nospread is reference counted, so one holder losing the
skill no longer removes the effect from the others still holding it.
- Friendly Fire: mp_autokick is restored at the end of the round instead of
staying disabled for the rest of the map, and is no longer executed on every
friendly hit.
- Reactive Armor / Iana: no longer restore health for a player who no longer
holds the skill.
- Free Planter / Short Fuse: each restores mp_c4timer only when it actually
changed it, so overlapping rounds cannot write back the wrong value.
- Illusionist: the replica movement timer now stops on map change.
- Ghost / Ninja / C4 Camouflage: the bomb is located once per transmit instead of
once per receiver and hidden player, and the pass is skipped when nobody is
hidden.
Introduce optional `HudDuration` and `DescriptionHudDuration` fields in skill config metadata and propagate them through all skill config constructors and `skillsInfo.json`.
- #### General:
- ###### Updated the GitHub source code to implement the changes introduced in merge request (https://github.com/Juzlus/jRandomSkills/pull/32).
- #### Skill improvements:
- ###### Ninja:
- ###### Removed debug chat messages that were used for testing.
## 📋 Changelog
- #### General:
- ###### Updated Chinese language translation by [by: [@Ericzzrbb](hhttps://github.com/Ericzzrbb)].
- ###### Fixed a bug where a player could be given multiple skills at once while the HUD displayed only one (the player list was never cleared on map change and had no duplicate protection on join). [by: [@ByDexterTR](https://github.com/ByDexterTR)]
- ###### Fixed skill names and descriptions showing the raw translation key on Turkish servers (culture-sensitive lowercasing) - affected skills starting with "I" (e.g. Illiterate, Impostor, InfiniteAmmo, Iana). [by: [@ByDexterTR](https://github.com/ByDexterTR)]
- ###### RayTrace-based skills and the skill-use button no longer throw when the RayTrace module is not installed - they now degrade gracefully instead of crashing. [by: [@ByDexterTR](https://github.com/ByDexterTR)]
- ###### Fixed the skill-use button (when bound to Use/E) blocking option selection inside WSAD target menus. [by: [@ByDexterTR](https://github.com/ByDexterTR)]
- ###### Performance: cached reflection lookups in `SkillAction` and `SkillsInfo.GetValue`, and de-duplicated the repeated event-dispatch logic on hot paths (OnTick, OnTakeDamage, etc.). [by: [@ByDexterTR](https://github.com/ByDexterTR)]
- ###### Stability: removed dead methods that threw `NotImplementedException`, hardened team-score handling, and reset all skill state on round start / map change. [by: [@ByDexterTR](https://github.com/ByDexterTR)]
- ###### Build: post-build copy paths now follow the active `$(Configuration)` and `$(TargetFramework)`. [by: [@ByDexterTR](https://github.com/ByDexterTR)]
- ###### Added new Turkish translation strings for the skill notifications listed below. [by: [@ByDexterTR](https://github.com/ByDexterTR)]
- ###### Fixed bot-related messages so they now display correctly in the chat of the controlling player.
- ###### When a player takes control of a bot, all active skill effects affecting that bot are now correctly transferred to the controlling player.
- ###### Prevented bots from automatically using skills while being controlled by a player.
- #### Skill improvements:
- ###### Wallhack:
- ###### Fixed enemy outlines briefly flashing for everyone when the skill holder dies. [by: [@ByDexterTR](https://github.com/ByDexterTR)]
- ###### Area Reaper:
- ###### Teammates (CT) are now notified which bombsite (A/B) was sealed. [by: [@ByDexterTR](https://github.com/ByDexterTR)]
- ###### Wild Throw:
- ###### Now notifies the targeted player, consistent with other targeted skills. [by: [@ByDexterTR](https://github.com/ByDexterTR)]
- ###### Careful Bullets / Darkness / Deaf / Glitch / Jammer / Jump Ban / Magnifier / Poison / Primary Ban / Wild Throw:
- ###### The targeted player is now notified when the effect ends after the skill holder dies. [by: [@ByDexterTR](https://github.com/ByDexterTR)]
- ###### Careful Bullets:
- ###### Added damage-taken sound effects when missing a shot
- ###### C4 Camouflage / Ninja:
- ###### Fixed a bug where dying with invisibility active and taking control of a bot would grant invisibility to the bot as well.
- ###### Poison:
- ###### Added damage-taken sound effects.
- ###### Primary Ban:
- ###### Changed mechanic to directly block shooting weapons instead of forcing a weapon switch to the knife.
- ###### Hot Bomb:
- ###### Replaced the bomb-burning sound effects.
- ###### Added a notification when the burning effect ends and the bomb returns to its normal color.
Refactored command handling to improve player and skill lookup logic, replaced some list operations with direct queries, and updated method signatures for clarity and null safety. The vote system was reworked to support more robust vote tracking, cooldowns, and localized chat messages. Language files were updated to add new vote-related translations. Various code style and nullability improvements were made throughout the plugin.