From 0be816107c6d816f5c9651dede49e9989e3f444a Mon Sep 17 00:00:00 2001 From: Kibi Kelburton Date: Wed, 6 May 2026 20:48:53 +0200 Subject: [PATCH] hell yeah --- gunfun/mod/main.gsc | 113 +++++++++++++++++++++++++---------------- gunfun/mod/streaks.gsc | 24 ++++----- 2 files changed, 79 insertions(+), 58 deletions(-) diff --git a/gunfun/mod/main.gsc b/gunfun/mod/main.gsc index 7f59d53..4bf2535 100755 --- a/gunfun/mod/main.gsc +++ b/gunfun/mod/main.gsc @@ -147,12 +147,26 @@ loadSettings() // Bot Management setDvar("bots_main", 1); - setDvar("bots_manage_fill", 12); - setDvar("bots_skill", 5); + setDvar("bots_manage_fill", 10); // total slots: players + bots = 10 + setDvar("bots_manage_fill_mode", 0); // mode 0 = count players AND bots + setDvar("bots_manage_fill_kick", 1); // kick a bot when a human pushes count over 10 + // Skill: 2 hard bots (1 per internal team), rest are brain dead + setDvar("bots_skill", 8); + setDvar("bots_skill_allies_hard", 1); + setDvar("bots_skill_allies_med", 0); + setDvar("bots_skill_axis_hard", 1); + setDvar("bots_skill_axis_med", 0); setDvar("bots_play_knife", 0); setDvar("bots_main_chat", 0); SetDvarIfUninitialized("scr_nuke_enabled", 1); + // Cache mode flags as level vars — avoids repeated getDvar() in hot per-player loops. + level.isTeamGame = (getDvar("g_gametype") == "gungame_team"); + level.isKillConfirmed = (getDvar("gunmode") == "Kill Confirmed"); + // Suppress engine-level developer prints (e.g. "Replacing perk X in slot Y with Z"). + // These come from native C code and cannot be silenced any other way. + // developer 0 is standard for production servers. + setDvar("developer", 0); } deleteSentries() { @@ -308,8 +322,20 @@ loadSetup() self setMoveSpeedScale(getDvarFloat("speed")); self maps\mp\perks\_perks::givePerk("specialty_fastreload"); // due to icys request :) self maps\mp\perks\_perks::givePerk("specialty_falldamage"); // due to icys request :) - self maps\mp\perks\_perks::givePerk("specialty_quickdraw"); - + self maps\mp\perks\_perks::givePerk("specialty_quickdraw"); + // Static HUD dvars set once per spawn — moved from watchHUD's 1-second polling loop. + // These values never change mid-game so there is no need to re-apply them every second. + self setClientDvar("cg_drawRadar", 1); + self setClientDvar("cg_drawStance", 0); + self setClientDvar("cg_drawTeamScores", 0); + self setClientDvar("cg_drawKillfeed", 0); + self setClientDvar("cg_drawBreathHint", 0); + self setClientDvar("cg_drawMantleHint", 0); + self setClientDvar("cg_drawTurretCrosshair", 0); + self setClientDvar("cg_cursorHints", 0); + // Keep g_hardcore=1 for server-side gameplay rules but show the normal client HUD + // so our custom health/weapon overlays render correctly without fighting hardcore suppression. + self setClientDvar("ui_hud_hardcore", 0); self thread takeInvalidWeapon(); if(level.state == "prematch") { @@ -418,28 +444,29 @@ refillOnFire() self giveMaxAmmo(weapon); } } -onKilling() { - self endon("disconnect"); - level endon("nuke"); - self.multiplier = 0; - self.amount = 0; - //kills = self.pers["kills"]; +onKilling() { + self endon("disconnect"); + level endon("nuke"); + self.multiplier = 0; + self.amount = 0; kills = 0; refreshCounter = 0; - self.scoretext = self createText("hudbig", 1, "CENTER", "CENTER", 0, 0, .7,""); - self.scoretext_amount = self createText("hudbig", 1, "CENTER", "CENTER", -10, 20, .7,""); - self.multitext = []; - for(i=2;i<6;i++) - self.multitext[i] = self createText("hudbig", .6, "CENTER", "CENTER", 50, (i * 20), .7,""); + // Cache settings that never change mid-match — eliminates getDvar()/getDvarInt() + // native calls inside this loop which runs every 0.3s per player. + killsPerWeapon = getDvarInt("gun_kills", 1); + self.scoretext = self createText("hudbig", 1, "CENTER", "CENTER", 0, 0, .7,""); + self.scoretext_amount = self createText("hudbig", 1, "CENTER", "CENTER", -10, 20, .7,""); + self.multitext = []; + for(i=2;i<6;i++) + self.multitext[i] = self createText("hudbig", .6, "CENTER", "CENTER", 50, (i * 20), .7,""); while(true) { wait .3; if(kills > self.gungameKills) // not called on team gungame { - self thread scorepopup(-100); + self thread scorepopup(-100); kills--; refreshCounter++; - killsPerWeapon = getDvarInt("gun_kills", 1); if(killsPerWeapon > 1) { killsInGun = (self.gungameKills % killsPerWeapon); @@ -462,10 +489,9 @@ onKilling() { kills++; refreshCounter++; self thread scorepopup(100); - self.streaking++; - if(getDvar("g_gametype") != "gungame_team") + self.streaking++; + if(!level.isTeamGame) // cached in loadSettings — avoids getDvar() per kill { - killsPerWeapon = getDvarInt("gun_kills", 1); if(killsPerWeapon > 1) { if(self.gungameKills % killsPerWeapon == 0) @@ -488,7 +514,7 @@ onKilling() { self thread initCreateMarkerIcon(); self refreshCounter(refreshCounter); self updateRatio(); - } + } } } updateRatio() @@ -586,8 +612,8 @@ scorepopup(amount) self.scoretext.color = color; self.scoretext.glowColor = glowColor; self.scoretext SetPulseFX( 40, 2000, 600 ); - if(getDvar("gunmode") == "Kill Confirmed") - self.scoretext setText("Upgraded!^3"); + if(level.isKillConfirmed) // cached in loadSettings — avoids getDvar() per popup + self.scoretext setText("Upgraded!^3"); else self.scoretext setText("Killed!^3"); self.scoretext_amount.color = color; @@ -679,9 +705,10 @@ tryNuke() } createUI() { - self thread createWeaponHud(); + self thread createWeaponHud(); self thread createKillHud(); - self thread Weaponnumber(); + // Weaponnumber() removed — marked deprecated, waits on "update_weaponNumber" + // which is never notified anywhere. Was a zombie thread per player. self thread createRatioHud(); } createWeaponHud() @@ -795,9 +822,9 @@ takeInvalidWeapon() level endon("nuke"); counter = 0; wait 3; - while(1) + while(1) { - waitFrame(); + wait 0.1; // was waitFrame() (~60/s) — 10/s is ample for a safety-net poller if(!isAlive(self)) continue; if(self isMantling()) @@ -1138,13 +1165,20 @@ watchHealthHUD() self.healthHUD setPoint("BOTTOM RIGHT", "BOTTOM RIGHT", -10, -10); self.healthHUD.label = &"HP: "; + lastHealth = -1; // sentinel: forces first-tick update while(true) { - self.healthHUD setValue(self.actual_health); - if(self.actual_health < (self.actual_maxhealth * 0.3)) - self.healthHUD.color = (1, 0, 0); - else - self.healthHUD.color = (1, 1, 1); + // Only push to the HUD element when the value actually changed. + // Eliminates 10 setValue() native calls/sec when player is at full health. + if(self.actual_health != lastHealth) + { + lastHealth = self.actual_health; + self.healthHUD setValue(self.actual_health); + if(self.actual_health < (self.actual_maxhealth * 0.3)) + self.healthHUD.color = (1, 0, 0); + else + self.healthHUD.color = (1, 1, 1); + } wait 0.1; } } @@ -1202,18 +1236,11 @@ watchHUD() self endon("death"); // prevent thread accumulation across respawns while(true) { + // Only re-apply dvars the engine may reset mid-game (radar via UAV, ammo via class events). + // ui_hud_hardcore is set to 0 once per spawn in loadSetup() and does not need refreshing. self setClientDvar("ui_drawradar", 1); - self setClientDvar("cg_drawRadar", 1); - self setClientDvar("cg_drawAmmo", 1); // Force ammo back on even in hardcore - self setClientDvar("cg_drawStance", 0); - self setClientDvar("cg_drawTeamScores", 0); - self setClientDvar("cg_drawKillfeed", 0); - self setClientDvar("ui_hud_hardcore", 1); - self setClientDvar("cg_drawBreathHint", 0); - self setClientDvar("cg_drawMantleHint", 0); - self setClientDvar("cg_drawTurretCrosshair", 0); - self setClientDvar("cg_cursorHints", 0); - wait 1; + self setClientDvar("cg_drawAmmo", 1); + wait 5; } } diff --git a/gunfun/mod/streaks.gsc b/gunfun/mod/streaks.gsc index 1ff5d80..3cc17b8 100755 --- a/gunfun/mod/streaks.gsc +++ b/gunfun/mod/streaks.gsc @@ -235,11 +235,9 @@ giveStreak(streak) self.speed = true; wait 1; self maps\mp\perks\_perks::givePerk("specialty_lightweight"); - self maps\mp\perks\_perks::givePerk("specialty_lightweight"); self setMoveSpeedScale(1.6); self.setMoveSpeedScale = 1.6; - //self thread spawnFireLoop(); - break; + break; case "Riotshield": self AttachShieldModel( "weapon_riot_shield_mp", "tag_shield_back" ); break; @@ -278,30 +276,26 @@ Radioactive() self endon("disconnect"); self endon("death"); level endon("nuke"); - playFxOnTag( level.spawnGlow["enemy"], self, "pelvis" ); + // Cache once \u2014 getDvar() inside the inner foreach would cost ~120 native calls/sec. + isTeamGame = (getDvar("g_gametype") == "gungame_team"); + playFxOnTag( level.spawnGlow["enemy"], self, "pelvis" ); playFxOnTag( level.spawnGlow["friendly"], self, "j_head" ); - //self SetPlayerIgnoreRadiusDamage( true ); while(1) { wait .1; - //self RadiusDamage(self.origin,120,50,40,self,"MOD_Explosive","nuke_mp"); - //RadiusDamage(self.origin, 50, 30, 20, self ); foreach(player in level.players) { if(player == self) continue; - if(getDvar("g_gametype") == "gungame_team") - { - if(player.team == self.team) - continue; - } + if(isTeamGame && player.team == self.team) + continue; if(Distance(player.origin,self.origin) < 120 && isAlive(player)) { player thread maps\mp\gametypes\_damage::finishPlayerDamageWrapper( self, self, 4, 0, "MOD_EXPLOSIVE", "none", player.origin, player.origin, "none", 0, 0 ); self thread maps\mp\gametypes\_damagefeedback::updateDamageFeedback(""); } - } - } + } + } } Suicidebomber() { @@ -655,7 +649,7 @@ Juggernaut() // FIX: Use the custom health system (actual_maxhealth/actual_health) instead of // the raw engine maxhealth. Setting engine maxhealth directly broke the HUD display // and regen logic. We double the effective HP pool through the custom system. - self.actual_maxhealth = self.maxhp * 2; + self.actual_maxhealth = self.maxhp * 5; // 5× base HP (e.g. 300 in Fungame vs normal 60) self.actual_health = self.actual_maxhealth; self setMoveSpeedScale(.7);