testing to fix memleak and disabling voting requires maprotation
This commit is contained in:
@@ -94,14 +94,18 @@ CodeCallback_PlayerDamage(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath
|
||||
return;
|
||||
}
|
||||
}
|
||||
damagehud = eAttacker createDamageHud();
|
||||
damageHud setValue(iDamage);
|
||||
damageHud moveOverTime(1);
|
||||
damageHud.x -= 300;
|
||||
damageHud.y += (-1 * randomInt(150));
|
||||
damageHud fadeOverTime(1);
|
||||
damageHud.alpha = 0;
|
||||
eAttacker thread destroyDamageHud(damageHud);
|
||||
// Guard: eAttacker is undefined for world/self damage (falls, barrels, etc.)
|
||||
if(isPlayer(eAttacker) && eAttacker != self)
|
||||
{
|
||||
damagehud = eAttacker createDamageHud();
|
||||
damageHud setValue(iDamage);
|
||||
damageHud moveOverTime(1);
|
||||
damageHud.x -= 300;
|
||||
damageHud.y += (-1 * randomInt(150));
|
||||
damageHud fadeOverTime(1);
|
||||
damageHud.alpha = 0;
|
||||
eAttacker thread destroyDamageHud(damageHud);
|
||||
}
|
||||
self thread updateDamageHud();
|
||||
}
|
||||
if(level.state != "ingame")
|
||||
|
||||
@@ -2106,14 +2106,21 @@ endGame( winner, endReasonText, nukeDetonated )
|
||||
{
|
||||
player closepopupMenu();
|
||||
player closeInGameMenu();
|
||||
//player notify ( "reset_outcome" ); // opens da scoreboard
|
||||
//player thread maps\mp\gametypes\_playerlogic::spawnIntermission();
|
||||
}
|
||||
if(level.players.size > 0)
|
||||
if(level.players.size > 0 && getDvarInt("vote_enabled", 1))
|
||||
{
|
||||
level notify("spawnVote");
|
||||
level waittill("endVote");
|
||||
}
|
||||
else
|
||||
{
|
||||
// No vote — show the normal scoreboard and leaderboard
|
||||
foreach ( player in level.players )
|
||||
{
|
||||
player notify ( "reset_outcome" );
|
||||
player thread maps\mp\gametypes\_playerlogic::spawnIntermission();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// End of Round
|
||||
|
||||
92
mod/main.gsc
92
mod/main.gsc
@@ -166,6 +166,9 @@ loadSettings()
|
||||
setDvar("bots_main_chat", 0);
|
||||
|
||||
SetDvarIfUninitialized("scr_nuke_enabled", 1);
|
||||
// Map voting: set to 1 to show custom vote screen at end of game,
|
||||
// 0 to use the normal leaderboard + server map rotation instead.
|
||||
SetDvarIfUninitialized("vote_enabled", 0);
|
||||
// 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");
|
||||
@@ -182,6 +185,10 @@ deleteSentries()
|
||||
}
|
||||
launchGame()
|
||||
{
|
||||
// Wait for gametype to initialize _hud_util globals (level.fontHeight, level.uiParent).
|
||||
// launchGame runs from Init() which fires before the gametype callback.
|
||||
while(!isDefined(level.fontHeight) || !isDefined(level.uiParent))
|
||||
waitFrame();
|
||||
hud = createServerFontString("hudbig", 1);
|
||||
hud setPoint("CENTER", "CENTER", 0,-80);
|
||||
hud.color = (1,1,0);
|
||||
@@ -253,6 +260,7 @@ firstSpawn()
|
||||
self.firstSpawn = true;
|
||||
self.knifeKills = 0;
|
||||
self.gungameKills = 0;
|
||||
self.isJugger = false;
|
||||
self.streaks = [];
|
||||
self setClientDvar("cg_drawSplatter", 0);
|
||||
self setClientDvar("cg_drawDamageFlash", 0);
|
||||
@@ -262,7 +270,8 @@ firstSpawn()
|
||||
self setClientDvar("bg_shock_movement", 0);
|
||||
self setClientDvar("bg_shock_lookControl", 0);
|
||||
self setClientDvar("scr_game_allowkillcam", 0);
|
||||
self.hud_damagefeedback.color = (1,0,0);
|
||||
if(isDefined(self.hud_damagefeedback))
|
||||
self.hud_damagefeedback.color = (1,0,0);
|
||||
self.line = self createRectangle("CENTER", "LEFT", 0,-90,300,5,(1,1,0),"line_horizontal",1);
|
||||
// Subtle crosshair dot — light blue, low alpha
|
||||
self.crosshair = self createRectangle("CENTER", "CENTER", 0, 0, 3, 3, (0.5, 0.85, 1.0), "white", 1);
|
||||
@@ -409,27 +418,47 @@ updateWeapon()
|
||||
self notify("updateWeapon");
|
||||
self endon("updateWeapon");
|
||||
|
||||
// Don't proceed until the weapon list is fully built
|
||||
if(!isDefined(level.weaponsLoaded) || !level.weaponsLoaded)
|
||||
return;
|
||||
if(self.current > (level.gungameList.size - 1))
|
||||
{
|
||||
self thread tryNuke();
|
||||
return;
|
||||
}
|
||||
//self iPrintlnBold(level.gungameList[self.current]);
|
||||
weaponName = level.gungameList[self.current];
|
||||
// Guard: skip if the weapon entry is missing, empty, or "none".
|
||||
if(!isDefined(weaponName) || weaponName == "none" || weaponName == "")
|
||||
return;
|
||||
variant = randomInt(9);
|
||||
if(getDvar("gunmode") == "Fungame")
|
||||
variant = 0;
|
||||
if (isSubstr(level.gungameList[self.current], "_akimbo"))
|
||||
self giveWeapon(level.gungameList[self.current], variant, true);
|
||||
if (isSubstr(weaponName, "_akimbo"))
|
||||
self giveWeapon(weaponName, variant, true);
|
||||
else
|
||||
self giveWeapon(level.gungameList[self.current], variant, false);
|
||||
self giveWeapon(weaponName, variant, false);
|
||||
// Verify the weapon was actually loaded — giveWeapon silently fails if
|
||||
// the weapon asset doesn't exist in the engine.
|
||||
if(!self hasWeapon(weaponName))
|
||||
{
|
||||
self.current++;
|
||||
return;
|
||||
}
|
||||
self giveWeapon("onemanarmy_mp");
|
||||
self takeWeapon(self getCurrentWeapon());
|
||||
self giveMaxAmmo(level.gungameList[self.current]);
|
||||
self setWeaponAmmoClip(level.gungameList[self.current], 9999); // force full clip — giveMaxAmmo only fills stock/reserve
|
||||
self takeWeapon("onemanarmy_mp");
|
||||
// Skip ammo operations for weapons with no ammo pool (riotshield, defaultweapon, etc.)
|
||||
// giveMaxAmmo on these causes "Weapon name none" engine errors.
|
||||
if(weaponName != "riotshield_mp" && weaponName != "defaultweapon_mp")
|
||||
{
|
||||
self giveMaxAmmo(weaponName);
|
||||
self setWeaponAmmoClip(weaponName, 9999);
|
||||
}
|
||||
waitFrame();
|
||||
self switchtoweaponimmediate(level.gungameList[self.current]);
|
||||
self switchtoweaponimmediate(weaponName);
|
||||
waitFrame();
|
||||
self setWeaponAmmoClip(level.gungameList[self.current], 9999); // re-apply after switch to prevent forced reload
|
||||
if(weaponName != "riotshield_mp" && weaponName != "defaultweapon_mp")
|
||||
self setWeaponAmmoClip(weaponName, 9999);
|
||||
if(level.state == "prematch" || level.state == "ingame")
|
||||
self show();
|
||||
// Always restore the correct speed, clamped to the mode's configured base floor.
|
||||
@@ -485,7 +514,8 @@ refillOnFire()
|
||||
{
|
||||
self waittill("weapon_fired");
|
||||
weapon = self getCurrentWeapon();
|
||||
self giveMaxAmmo(weapon);
|
||||
if(weapon != "none" && weapon != "")
|
||||
self giveMaxAmmo(weapon);
|
||||
}
|
||||
}
|
||||
onKilling() {
|
||||
@@ -615,7 +645,7 @@ clearWarning(hud)
|
||||
}
|
||||
createText(font,fontScale,align,relative,x,y,alpha,input,color,gcolor,galpha)
|
||||
{
|
||||
text = self createFontString(font,fontScale,self);
|
||||
text = self createFontString(font,fontScale);
|
||||
text setPoint(align,relative,x,y);
|
||||
text.sort = 999;
|
||||
text.alpha = alpha;
|
||||
@@ -675,28 +705,28 @@ scorepopup(amount)
|
||||
// Each unique amount string burned a permanent configstring slot.
|
||||
self.scoretext_amount.label = &"+";
|
||||
self.scoretext_amount setValue(self.amount);
|
||||
if(self.multiplier > 1)
|
||||
// Clamp multitext index to the valid range [2..5] to prevent undefined access
|
||||
mtIdx = self.multiplier;
|
||||
if(mtIdx > 5) mtIdx = 5;
|
||||
if(self.multiplier > 1 && isDefined(self.multitext[mtIdx]))
|
||||
{
|
||||
self.multitext[self.multiplier].alpha = 1;
|
||||
self.multitext[self.multiplier] fadeOverTime(0.1);
|
||||
self.multitext[self.multiplier].color = color;
|
||||
self.multitext[self.multiplier].glowColor = glowColor;
|
||||
self.multitext[mtIdx].alpha = 1;
|
||||
self.multitext[mtIdx] fadeOverTime(0.1);
|
||||
self.multitext[mtIdx].color = color;
|
||||
self.multitext[mtIdx].glowColor = glowColor;
|
||||
}
|
||||
if(self.multiplier == 2)
|
||||
{
|
||||
self thread lowerMultitext(self.multiplier);
|
||||
self.multitext[self.multiplier] setText("Double Kill!");
|
||||
self.multitext[mtIdx] setText("Double Kill!");
|
||||
}
|
||||
else if(self.multiplier == 3)
|
||||
self.multitext[self.multiplier] setText("Triple Kill!");
|
||||
self.multitext[mtIdx] setText("Triple Kill!");
|
||||
else if(self.multiplier == 4)
|
||||
self.multitext[self.multiplier] setText("Multi Kill!");
|
||||
self.multitext[mtIdx] setText("Multi Kill!");
|
||||
else if(self.multiplier > 4)
|
||||
{
|
||||
difference = self.multiplier - 4;
|
||||
// FIX: Use a fixed string instead of randomized color codes.
|
||||
// The old rainbow text generated a unique configstring for every kill spree
|
||||
// (random colors = unique string every time = configstring leak).
|
||||
// FIX: Use .label + setValue() to avoid configstring leak per spree level.
|
||||
self.multitext[5].label = &"^1K^2i^3l^4l^5i^6n^7g ^1S^2p^3r^4e^5e ^3x";
|
||||
self.multitext[5] setValue(difference);
|
||||
@@ -718,8 +748,11 @@ lowerMultitext(multiplier)
|
||||
self waittill_any("start_lowering", "disconnect");
|
||||
for(i=2;i<6;i++)
|
||||
{
|
||||
self.multitext[i] fadeOverTime(3);
|
||||
self.multitext[i].alpha = 0;
|
||||
if(isDefined(self.multitext[i]))
|
||||
{
|
||||
self.multitext[i] fadeOverTime(3);
|
||||
self.multitext[i].alpha = 0;
|
||||
}
|
||||
wait .75;
|
||||
}
|
||||
wait 4;
|
||||
@@ -910,13 +943,18 @@ takeInvalidWeapon()
|
||||
continue;
|
||||
if(self isMantling())
|
||||
continue;
|
||||
// Don't poll until weapons are fully loaded
|
||||
if(!isDefined(level.weaponsLoaded) || !level.weaponsLoaded)
|
||||
continue;
|
||||
weapon = self getCurrentWeapon();
|
||||
// Skip if player is in a weapon transition ("none" is normal during switches)
|
||||
if(weapon == "none" || weapon == "")
|
||||
continue;
|
||||
if(weapon != level.gungameList[self.current])
|
||||
{
|
||||
self takeAllWeapons();
|
||||
self thread updateWeapon();
|
||||
// Short cooldown — just enough for switchtoweaponimmediate to settle.
|
||||
// The old 2.5s wait was causing the visible mid-game-join delay.
|
||||
wait 0.5;
|
||||
}
|
||||
}
|
||||
@@ -1084,11 +1122,9 @@ tryCreateMarkerIcons()
|
||||
createRectangle(align, relative, x, y, width, height, color, shader, sort)
|
||||
{
|
||||
hud = newClientHudElem(self);
|
||||
hud.sTexType = "bar";
|
||||
hud.elemType = "icon";
|
||||
hud.width = width;
|
||||
hud.height = height;
|
||||
hud.align = align;
|
||||
hud.relative = relative;
|
||||
hud.xOffset = 0;
|
||||
hud.yOffset = 0;
|
||||
hud.children = [];
|
||||
|
||||
@@ -22,6 +22,8 @@ loadStreaks()
|
||||
// Pre-cache Jetpack FX at level init (loadfx must NOT be called at runtime).
|
||||
level._effect["jetpack_smoke"] = loadfx("smoke/smoke_trail_white_heli");
|
||||
level._effect["jetpack_flare"] = loadfx("misc/flares_cobra");
|
||||
// Small bullet-impact explosion for the Explosive Bullets streak.
|
||||
level._effect["bullet_explode"] = loadfx("explosions/grenadeExp_default");
|
||||
|
||||
level.streaks3 = [];
|
||||
level.streaks6 = [];
|
||||
@@ -115,7 +117,7 @@ setStreaks()
|
||||
}
|
||||
drawStreaks()
|
||||
{
|
||||
if(isDefined(self.streakIcons[0]))
|
||||
if(isDefined(self.streakIcons) && isDefined(self.streakIcons[0]))
|
||||
{
|
||||
for(i=0;i<3;i++)
|
||||
{
|
||||
@@ -321,7 +323,7 @@ Explosive()
|
||||
forward = self getTagOrigin("j_head");
|
||||
end = self thread vector_scal(anglestoforward(self getPlayerAngles()),1000000);
|
||||
Location = BulletTrace( forward, end, 0, self )[ "position" ];
|
||||
playFx(level._effect["claymore_explode"], Location);
|
||||
playFx(level._effect["bullet_explode"], Location);
|
||||
RadiusDamage(Location, 50, 30, 20, self );
|
||||
//self RadiusDamage(Location,250,self.explodmg,self.explomindmg,self,"MOD_Explosive","barrel_mp");
|
||||
wait self.explotime;
|
||||
@@ -355,7 +357,7 @@ Jetpack()
|
||||
{
|
||||
if(self usebuttonpressed() && self.jetpack>0)
|
||||
{
|
||||
self playsound("cobra_helicopter_dying_loop");
|
||||
self playloopsound("cobra_helicopter_dying_loop");
|
||||
self setstance("crouch");
|
||||
playfx(level._effect["jetpack_smoke"],self gettagorigin("j_spine4"));
|
||||
playfx(level._effect["jetpack_flare"],self gettagorigin("j_spine4"));
|
||||
@@ -364,6 +366,8 @@ Jetpack()
|
||||
if(self getvelocity()[2]<300)
|
||||
self setvelocity(self getvelocity()+(0,0,60));
|
||||
}
|
||||
else
|
||||
self stoploopsound("cobra_helicopter_dying_loop");
|
||||
if(self.jetpack < 80 &&!self usebuttonpressed())
|
||||
self.jetpack++;
|
||||
JETPACKBACK updateBar(self.jetpack/80);
|
||||
@@ -694,6 +698,7 @@ NoReload()
|
||||
if(self AttackButtonPressed())
|
||||
{
|
||||
current = self getCurrentWeapon();
|
||||
if(current == "none" || current == "") { waitFrame(); continue; }
|
||||
clip = self GetWeaponAmmoClip(current);
|
||||
stock = self GetWeaponAmmoStock(current);
|
||||
if(stock > 0)
|
||||
|
||||
@@ -296,11 +296,9 @@ getDisplayName(map)
|
||||
createRectangle(shader,align, relative, x, y, width, height)
|
||||
{
|
||||
hud = newHudElem();
|
||||
hud.sTexType = "bar";
|
||||
hud.elemType = "icon";
|
||||
hud.width = width;
|
||||
hud.height = height;
|
||||
hud.align = align;
|
||||
hud.relative = relative;
|
||||
hud.alpha = 1;
|
||||
hud.xOffset = 0;
|
||||
hud.yOffset = 0;
|
||||
@@ -316,11 +314,9 @@ createRectangle(shader,align, relative, x, y, width, height)
|
||||
createPlayerRectangle(shader,align, relative, x, y, width, height)
|
||||
{
|
||||
hud = newClientHudElem(self);
|
||||
hud.sTexType = "bar";
|
||||
hud.elemType = "icon";
|
||||
hud.width = width;
|
||||
hud.height = height;
|
||||
hud.align = align;
|
||||
hud.relative = relative;
|
||||
hud.alpha = 1;
|
||||
hud.xOffset = 0;
|
||||
hud.yOffset = 0;
|
||||
|
||||
@@ -125,6 +125,7 @@ loadWeapons()
|
||||
}
|
||||
//level.gungameList[1] = setWeapon("rpg_mp");
|
||||
//level.gungameList[1] = "rpg_mp";
|
||||
level.weaponsLoaded = true;
|
||||
}
|
||||
removeIDfromArray(id, weaponList)
|
||||
{
|
||||
@@ -594,6 +595,7 @@ loadFungameList()
|
||||
level.gungameList[level.gungameList.size] = level.fungameWeapons[i];
|
||||
}
|
||||
}
|
||||
level.weaponsLoaded = true; // signal that the list is ready for use
|
||||
}
|
||||
|
||||
addFungameWeapon(weapon)
|
||||
|
||||
Reference in New Issue
Block a user