fungame #1

Merged
kibi merged 5 commits from fungame into main 2026-05-06 20:35:47 +00:00
4 changed files with 137 additions and 147 deletions
Showing only changes of commit 0be816107c - Show all commits

View File

@@ -147,12 +147,26 @@ loadSettings()
// Bot Management // Bot Management
setDvar("bots_main", 1); setDvar("bots_main", 1);
setDvar("bots_manage_fill", 12); setDvar("bots_manage_fill", 10); // total slots: players + bots = 10
setDvar("bots_skill", 5); 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_play_knife", 0);
setDvar("bots_main_chat", 0); setDvar("bots_main_chat", 0);
SetDvarIfUninitialized("scr_nuke_enabled", 1); 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() deleteSentries()
{ {
@@ -308,8 +322,20 @@ loadSetup()
self setMoveSpeedScale(getDvarFloat("speed")); self setMoveSpeedScale(getDvarFloat("speed"));
self maps\mp\perks\_perks::givePerk("specialty_fastreload"); // due to icys request :) 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_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(); self thread takeInvalidWeapon();
if(level.state == "prematch") if(level.state == "prematch")
{ {
@@ -418,28 +444,29 @@ refillOnFire()
self giveMaxAmmo(weapon); self giveMaxAmmo(weapon);
} }
} }
onKilling() { onKilling() {
self endon("disconnect"); self endon("disconnect");
level endon("nuke"); level endon("nuke");
self.multiplier = 0; self.multiplier = 0;
self.amount = 0; self.amount = 0;
//kills = self.pers["kills"];
kills = 0; kills = 0;
refreshCounter = 0; refreshCounter = 0;
self.scoretext = self createText("hudbig", 1, "CENTER", "CENTER", 0, 0, .7,""); // Cache settings that never change mid-match — eliminates getDvar()/getDvarInt()
self.scoretext_amount = self createText("hudbig", 1, "CENTER", "CENTER", -10, 20, .7,""); // native calls inside this loop which runs every 0.3s per player.
self.multitext = []; killsPerWeapon = getDvarInt("gun_kills", 1);
for(i=2;i<6;i++) self.scoretext = self createText("hudbig", 1, "CENTER", "CENTER", 0, 0, .7,"");
self.multitext[i] = self createText("hudbig", .6, "CENTER", "CENTER", 50, (i * 20), .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) while(true)
{ {
wait .3; wait .3;
if(kills > self.gungameKills) // not called on team gungame if(kills > self.gungameKills) // not called on team gungame
{ {
self thread scorepopup(-100); self thread scorepopup(-100);
kills--; kills--;
refreshCounter++; refreshCounter++;
killsPerWeapon = getDvarInt("gun_kills", 1);
if(killsPerWeapon > 1) if(killsPerWeapon > 1)
{ {
killsInGun = (self.gungameKills % killsPerWeapon); killsInGun = (self.gungameKills % killsPerWeapon);
@@ -462,10 +489,9 @@ onKilling() {
kills++; kills++;
refreshCounter++; refreshCounter++;
self thread scorepopup(100); self thread scorepopup(100);
self.streaking++; self.streaking++;
if(getDvar("g_gametype") != "gungame_team") if(!level.isTeamGame) // cached in loadSettings — avoids getDvar() per kill
{ {
killsPerWeapon = getDvarInt("gun_kills", 1);
if(killsPerWeapon > 1) if(killsPerWeapon > 1)
{ {
if(self.gungameKills % killsPerWeapon == 0) if(self.gungameKills % killsPerWeapon == 0)
@@ -488,7 +514,7 @@ onKilling() {
self thread initCreateMarkerIcon(); self thread initCreateMarkerIcon();
self refreshCounter(refreshCounter); self refreshCounter(refreshCounter);
self updateRatio(); self updateRatio();
} }
} }
} }
updateRatio() updateRatio()
@@ -586,8 +612,8 @@ scorepopup(amount)
self.scoretext.color = color; self.scoretext.color = color;
self.scoretext.glowColor = glowColor; self.scoretext.glowColor = glowColor;
self.scoretext SetPulseFX( 40, 2000, 600 ); self.scoretext SetPulseFX( 40, 2000, 600 );
if(getDvar("gunmode") == "Kill Confirmed") if(level.isKillConfirmed) // cached in loadSettings — avoids getDvar() per popup
self.scoretext setText("Upgraded!^3"); self.scoretext setText("Upgraded!^3");
else else
self.scoretext setText("Killed!^3"); self.scoretext setText("Killed!^3");
self.scoretext_amount.color = color; self.scoretext_amount.color = color;
@@ -679,9 +705,10 @@ tryNuke()
} }
createUI() createUI()
{ {
self thread createWeaponHud(); self thread createWeaponHud();
self thread createKillHud(); 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(); self thread createRatioHud();
} }
createWeaponHud() createWeaponHud()
@@ -795,9 +822,9 @@ takeInvalidWeapon()
level endon("nuke"); level endon("nuke");
counter = 0; counter = 0;
wait 3; 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)) if(!isAlive(self))
continue; continue;
if(self isMantling()) if(self isMantling())
@@ -1138,13 +1165,20 @@ watchHealthHUD()
self.healthHUD setPoint("BOTTOM RIGHT", "BOTTOM RIGHT", -10, -10); self.healthHUD setPoint("BOTTOM RIGHT", "BOTTOM RIGHT", -10, -10);
self.healthHUD.label = &"HP: "; self.healthHUD.label = &"HP: ";
lastHealth = -1; // sentinel: forces first-tick update
while(true) while(true)
{ {
self.healthHUD setValue(self.actual_health); // Only push to the HUD element when the value actually changed.
if(self.actual_health < (self.actual_maxhealth * 0.3)) // Eliminates 10 setValue() native calls/sec when player is at full health.
self.healthHUD.color = (1, 0, 0); if(self.actual_health != lastHealth)
else {
self.healthHUD.color = (1, 1, 1); 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; wait 0.1;
} }
} }
@@ -1202,18 +1236,11 @@ watchHUD()
self endon("death"); // prevent thread accumulation across respawns self endon("death"); // prevent thread accumulation across respawns
while(true) 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("ui_drawradar", 1);
self setClientDvar("cg_drawRadar", 1); self setClientDvar("cg_drawAmmo", 1);
self setClientDvar("cg_drawAmmo", 1); // Force ammo back on even in hardcore wait 5;
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;
} }
} }

View File

@@ -235,11 +235,9 @@ giveStreak(streak)
self.speed = true; self.speed = true;
wait 1; wait 1;
self maps\mp\perks\_perks::givePerk("specialty_lightweight"); 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.setMoveSpeedScale = 1.6; self.setMoveSpeedScale = 1.6;
//self thread spawnFireLoop(); break;
break;
case "Riotshield": case "Riotshield":
self AttachShieldModel( "weapon_riot_shield_mp", "tag_shield_back" ); self AttachShieldModel( "weapon_riot_shield_mp", "tag_shield_back" );
break; break;
@@ -278,30 +276,26 @@ Radioactive()
self endon("disconnect"); self endon("disconnect");
self endon("death"); self endon("death");
level endon("nuke"); 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" ); playFxOnTag( level.spawnGlow["friendly"], self, "j_head" );
//self SetPlayerIgnoreRadiusDamage( true );
while(1) while(1)
{ {
wait .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) foreach(player in level.players)
{ {
if(player == self) if(player == self)
continue; continue;
if(getDvar("g_gametype") == "gungame_team") if(isTeamGame && player.team == self.team)
{ continue;
if(player.team == self.team)
continue;
}
if(Distance(player.origin,self.origin) < 120 && isAlive(player)) 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 ); 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(""); self thread maps\mp\gametypes\_damagefeedback::updateDamageFeedback("");
} }
} }
} }
} }
Suicidebomber() Suicidebomber()
{ {
@@ -655,7 +649,7 @@ Juggernaut()
// FIX: Use the custom health system (actual_maxhealth/actual_health) instead of // FIX: Use the custom health system (actual_maxhealth/actual_health) instead of
// the raw engine maxhealth. Setting engine maxhealth directly broke the HUD display // 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. // 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.actual_health = self.actual_maxhealth;
self setMoveSpeedScale(.7); self setMoveSpeedScale(.7);