diff --git a/jRandomSkills - SRC Files/src/jRandomSkills.cs b/jRandomSkills - SRC Files/src/jRandomSkills.cs index e3ad2b8..f80a684 100644 --- a/jRandomSkills - SRC Files/src/jRandomSkills.cs +++ b/jRandomSkills - SRC Files/src/jRandomSkills.cs @@ -44,7 +44,7 @@ namespace src public override string ModuleName => "[CS2] [ jRandomSkills ]"; 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 ModuleVersion => "1.2.4.b3-panorama1"; + public override string ModuleVersion => "1.2.4.b3-panorama2"; public override void Load(bool hotReload) { diff --git a/jRandomSkills - SRC Files/src/player/skills/BlastShot.cs b/jRandomSkills - SRC Files/src/player/skills/BlastShot.cs index 2a2b233..4d3d070 100644 --- a/jRandomSkills - SRC Files/src/player/skills/BlastShot.cs +++ b/jRandomSkills - SRC Files/src/player/skills/BlastShot.cs @@ -68,15 +68,23 @@ namespace src.player.skills var buttons = player.Buttons; bool isAttack2 = (buttons & PlayerButtons.Attack2) != 0; - if (skillInfo.CanUse && isAttack2 && !freezeTime) + bool pressed = isAttack2 && !skillInfo.WasAttack2; + skillInfo.WasAttack2 = isAttack2; + + // With the cooldown override there's no cooldown, so fire once per press instead of every tick. + bool noCooldown = CooldownOverride.Has(player); + if ((noCooldown ? pressed : skillInfo.CanUse && isAttack2) && !freezeTime) { var weapon = playerPawn.WeaponServices?.ActiveWeapon?.Value; if (weapon == null || !weapon.IsValid) continue; if (!allowedWeapons.Contains(SkillUtils.GetDesignerName(weapon))) continue; - skillInfo.CanUse = false; - skillInfo.Cooldown = DateTime.Now; + if (!noCooldown) + { + skillInfo.CanUse = false; + skillInfo.Cooldown = DateTime.Now; + } SpawnExplosion(player); } @@ -191,6 +199,7 @@ namespace src.player.skills public ulong SteamID { get; set; } public bool CanUse { get; set; } public DateTime Cooldown { get; set; } + public bool WasAttack2 { get; set; } } public class SkillConfig(Skills skill = skillName, bool active = true, string color = "#7740c9", 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 explosionRadius = 400.0f, int explosionDamage = 60, float dmgReductionForTeamates = 0.5f, float cooldown = 10f, float force = 1000f, bool friendlyFire = true) : SkillsInfo.DefaultSkillInfo(skill, active, color, onlyTeam, disableOnFreezeTime, needsTeammates, requiredPermission, hudDuration, descriptionHudDuration, maxPerServer, rarity) diff --git a/jRandomSkills - SRC Files/src/player/skills/Dash.cs b/jRandomSkills - SRC Files/src/player/skills/Dash.cs index beaaa3a..5510b38 100644 --- a/jRandomSkills - SRC Files/src/player/skills/Dash.cs +++ b/jRandomSkills - SRC Files/src/player/skills/Dash.cs @@ -109,11 +109,15 @@ namespace src.player.skills skillInfo.Jumps = 0; else if (!isOnGround && jumpPressed && skillInfo.Jumps < 1) { - if (skillInfo.JumpReleasedTicks >= 3 && skillInfo.CanUse) + bool noCooldown = CooldownOverride.Has(eventPlayer); + if (skillInfo.JumpReleasedTicks >= 3 && (skillInfo.CanUse || noCooldown)) { skillInfo.Jumps++; - skillInfo.CanUse = false; - skillInfo.Cooldown = DateTime.Now; + if (!noCooldown) + { + skillInfo.CanUse = false; + skillInfo.Cooldown = DateTime.Now; + } float moveX = 0; float moveY = 0; diff --git a/jRandomSkills - SRC Files/src/utils/CooldownOverride.cs b/jRandomSkills - SRC Files/src/utils/CooldownOverride.cs index 2c86e24..0a8992e 100644 --- a/jRandomSkills - SRC Files/src/utils/CooldownOverride.cs +++ b/jRandomSkills - SRC Files/src/utils/CooldownOverride.cs @@ -8,7 +8,8 @@ namespace src.utils // Per-player cooldown bypass (css_setoverride). Skills keep their cooldown in their own static // per-player state, so instead of touching every skill this clears that state just before the // skill's UseSkill runs. Resetting only at use time (not every tick) matters: AimLock and Noclip - // reuse their Cooldown timestamp as the start of the active effect. + // reuse their Cooldown timestamp as the start of the active effect. Skills that trigger from + // OnTick rather than UseSkill (BlastShot, Dash) check Has themselves. public static class CooldownOverride { private static readonly HashSet _players = []; @@ -17,12 +18,20 @@ namespace src.utils // Toggles the override and returns the new state. public static bool Toggle(CCSPlayerController player) { - if (_players.Remove(player.SteamID)) return false; - _players.Add(player.SteamID); + if (_players.Remove(Key(player))) return false; + _players.Add(Key(player)); return true; } - public static bool Has(CCSPlayerController player) => _players.Contains(player.SteamID); + // A bot a human has taken over counts as that human, since skills run on the bot's controller. + public static bool Has(CCSPlayerController? player) + { + player = PlayerManager.GetPlayerFromEvent(player); + return player != null && _players.Contains(Key(player)); + } + + // Bots all have SteamID 0, so key them by slot instead (a SteamID64 is never that small). + private static ulong Key(CCSPlayerController player) => player.IsBot ? player.Index : player.SteamID; public static void ResetBeforeUse(Type skillType, CCSPlayerController player) {