From ab5ea7895799f1b9104e31ce7940ea3454efdcba Mon Sep 17 00:00:00 2001 From: Kibi Kelburton Date: Sun, 10 May 2026 04:27:29 +0200 Subject: [PATCH 1/3] testing to fix memleak and disabling voting requires maprotation --- maps/mp/gametypes/_callbacksetup.gsc | 20 +++--- maps/mp/gametypes/_gamelogic.gsc | 13 +++- mod/main.gsc | 92 +++++++++++++++++++--------- mod/streaks.gsc | 11 +++- mod/vote.gsc | 8 +-- mod/weapons.gsc | 2 + 6 files changed, 98 insertions(+), 48 deletions(-) diff --git a/maps/mp/gametypes/_callbacksetup.gsc b/maps/mp/gametypes/_callbacksetup.gsc index ff4074b..ebb384d 100755 --- a/maps/mp/gametypes/_callbacksetup.gsc +++ b/maps/mp/gametypes/_callbacksetup.gsc @@ -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") diff --git a/maps/mp/gametypes/_gamelogic.gsc b/maps/mp/gametypes/_gamelogic.gsc index 0052f01..fa55e62 100755 --- a/maps/mp/gametypes/_gamelogic.gsc +++ b/maps/mp/gametypes/_gamelogic.gsc @@ -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 diff --git a/mod/main.gsc b/mod/main.gsc index a8d413f..e24fbf1 100755 --- a/mod/main.gsc +++ b/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 = []; diff --git a/mod/streaks.gsc b/mod/streaks.gsc index 2275717..35a4c92 100755 --- a/mod/streaks.gsc +++ b/mod/streaks.gsc @@ -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) diff --git a/mod/vote.gsc b/mod/vote.gsc index 49ebc3f..4fa41ab 100755 --- a/mod/vote.gsc +++ b/mod/vote.gsc @@ -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; diff --git a/mod/weapons.gsc b/mod/weapons.gsc index 0887ad8..3977163 100755 --- a/mod/weapons.gsc +++ b/mod/weapons.gsc @@ -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) -- 2.50.1 From 6faeadc3d5f3efa314c2c53499f13c19d111d24c Mon Sep 17 00:00:00 2001 From: Kibi Kelburton Date: Sun, 10 May 2026 23:58:54 +0200 Subject: [PATCH 2/3] foobarbaz --- maps/mp/gametypes/_callbacksetup.gsc | 75 +-- maps/mp/gametypes/gungame.gsc | 2 +- mod/main.gsc | 421 ++++------------- mod/streaks.gsc | 28 +- mod/vote.gsc | 667 --------------------------- mod/weapons.gsc | 122 +---- 6 files changed, 98 insertions(+), 1217 deletions(-) delete mode 100755 mod/vote.gsc diff --git a/maps/mp/gametypes/_callbacksetup.gsc b/maps/mp/gametypes/_callbacksetup.gsc index ebb384d..56d7b76 100755 --- a/maps/mp/gametypes/_callbacksetup.gsc +++ b/maps/mp/gametypes/_callbacksetup.gsc @@ -86,14 +86,6 @@ CodeCallback_PlayerDamage(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath iDamage = 50; } if(level.state == "ingame" && getDvarInt("show_damage_ui") == 1){ - if(getDvar("g_gametype") == "gungame_team") - { - if(self.team == eAttacker.team) - { - [[level.callbackPlayerDamage]](eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, timeOffset); // tested? - return; - } - } // Guard: eAttacker is undefined for world/self damage (falls, barrels, etc.) if(isPlayer(eAttacker) && eAttacker != self) { @@ -185,8 +177,7 @@ CodeCallback_PlayerKilled(eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon self.score = 0; if(self.current > 0) self.current--; - if(getDvar("g_gametype") != "gungame_team") - self.gungameKills--; + self.gungameKills--; self thread mod\main::warning(3); } else if(sMeansOfDeath != "MOD_MELEE" || sWeapon == "riotshield_mp") @@ -194,48 +185,11 @@ CodeCallback_PlayerKilled(eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon eAttacker playlocalsound("mp_enemy_obj_captured"); eAttacker notify("killed_enemy"); eAttacker.score += 100; - if(getDvar("g_gametype") != "gungame_team") - { - //iPrintlnBold(getDvar("gunmode")); - if(getDvar("gunmode") != "Kill Confirmed") - { - if(sWeapon == "riotshield_mp" && getDvar("gunmode") == "Fungame") - eAttacker.gungameKills += getDvarInt("gun_kills", 1); - else - eAttacker.gungameKills++; - } - else - thread mod\main::spawnDogTag(self, eAttacker); - } - else if(eAttacker.team != self) - { - if(eAttacker.team == "allies") - { - level.teamKills["allies"]++; - if(level.teamKills["allies"] >= getRequiredKills()) - { - level.teamKills["allies"] = 0; - level.teamKills["allies_weapon"]++; - level notify("upgrade_allies"); - thread mod\main::upgradeTeamUI("allies"); - thread mod\main::upgradeEnemyWeaponUI("axis"); - } - } - else - { - level.teamKills["axis"]++; - if(level.teamKills["axis"] >= eAttacker getRequiredKills()) - { - level.teamKills["axis"] = 0; - level.teamKills["axis_weapon"]++; - level notify("upgrade_axis"); - thread mod\main::upgradeTeamUI("axis"); - thread mod\main::upgradeEnemyWeaponUI("allies"); - } - } - eAttacker thread mod\main::scorepopup(100); - eAttacker.streaking++; - } + // Riot shield kills give extra credit to match gun_kills requirement + if(sWeapon == "riotshield_mp") + eAttacker.gungameKills += getDvarInt("gun_kills", 1); + else + eAttacker.gungameKills++; } else{ eAttacker.score += 100; @@ -243,23 +197,6 @@ CodeCallback_PlayerKilled(eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon self notify("killed_lethal"); [[level.callbackPlayerKilled]](eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration); } -getRequiredKills() -{ - allies = 0; - axis = 0; - foreach(player in level.players) - { - if(player.team == "allies") - allies++; - else if(player.team == "axis") - axis++; - } - if(self.team == "allies") - return allies; - else if(self.team == "axis") - return axis; - return 9999; -} getRequiredKillsOld() { diff --git a/maps/mp/gametypes/gungame.gsc b/maps/mp/gametypes/gungame.gsc index deeca33..bba783f 100755 --- a/maps/mp/gametypes/gungame.gsc +++ b/maps/mp/gametypes/gungame.gsc @@ -55,7 +55,7 @@ onStartGameType() setObjectiveHintText( "allies", "Be the first who cycled through all guns to win! \n \n Mod made by ^:Santahunter^7!" ); setObjectiveHintText( "axis", "Be the first who cycled through all guns to win! \n \n Mod made by ^:Santahunter^7!" ); - level.killcam = false; + level.killcam = true; // enables final killcam at end of game level.spawnMins = ( 0, 0, 0 ); level.spawnMaxs = ( 0, 0, 0 ); maps\mp\gametypes\_spawnlogic::addSpawnPoints( "allies", "mp_dm_spawn" ); diff --git a/mod/main.gsc b/mod/main.gsc index e24fbf1..b671bf9 100755 --- a/mod/main.gsc +++ b/mod/main.gsc @@ -4,14 +4,8 @@ ///////////////////// // -// Gamemodes: -// -// - basic -// - team gungame -// - no streaks -// - snipers only -// - kill confirmed -// - pistol & shotgun only (disabled) +// Gamemode: Fungame (only mode) +// Init() { @@ -19,109 +13,35 @@ Init() loadSettings(); thread mod\weapons::loadWeapons(); thread mod\streaks::loadStreaks(); - thread mod\vote::loadVote(); // does not work thread onPlayerConnect(); thread deleteSentries(); thread launchGame(); } -setGamemodes() +initializeGametype() { - level.gungamemodes = []; - level.gungamemodes[level.gungamemodes.size] = "Fungame"; // God of Hellfire addition - level.gungamemodes[level.gungamemodes.size] = "Classic"; - // level.gungamemodes[level.gungamemodes.size] = "Classic"; // raising the chance - // level.gungamemodes[level.gungamemodes.size] = "Classic"; - // level.gungamemodes[level.gungamemodes.size] = "No Streaks"; - // level.gungamemodes[level.gungamemodes.size] = "Snipers only"; - //level.gungamemodes[level.gungamemodes.size] = "Pistol & Shotguns only"; // works but is it fun? - // level.gungamemodes[level.gungamemodes.size] = "Team Gungame"; - // level.gungamemodes[level.gungamemodes.size] = "Kill Confirmed"; -} -initializeGametype(type) // called in vote.gsc after first map -{ - setDvar("gunmode", type); - setDvar("gun_kills", 1); // Default to 1 kill per weapon - if(type == "Team Gungame") - setDvar("g_gametype", "gungame_team"); - else - setDvar("g_gametype", "gungame"); - switch(type) - { - case "Classic": - setDvar("global_health", 60); - setDvar("speed", 1.2); - setDvar("streaks_online", 1); - setDvar("jump_height", 60); - setDvar("amount_weapons", 100); - setDvar("shuffle_weapons", 1); - break; - case "No Streaks": - setDvar("global_health", 70); - setDvar("speed", 1.2); - setDvar("streaks_online", 0); - setDvar("jump_height", 70); - break; - case "Snipers only": - setDvar("global_health", 70); - setDvar("speed", 1.2); - setDvar("streaks_online", 1); - setDvar("jump_height", 70); - break; - case "Pistol & Shotguns only": - setDvar("global_health", 70); - setDvar("speed", 1.2); - setDvar("streaks_online", 1); - setDvar("jump_height", 70); - break; - case "Team Gungame": - setDvar("global_health", 70); - setDvar("speed", 1.2); - setDvar("streaks_online", 1); - setDvar("jump_height", 70); - break; - case "Kill Confirmed": - setDvar("global_health", 100); - setDvar("speed", 1); - setDvar("streaks_online", 1); - setDvar("jump_height", 70); - break; - case "Fungame": - setDvar("global_health", 60); - setDvar("speed", 1.5); - setDvar("streaks_online", 1); - setDvar("jump_height", 70); - setDvar("amount_weapons", 0); // 0 = full 162-weapon progression - setDvar("shuffle_weapons", 0); // weapons play in fixed order - setDvar("gun_kills", 1); - break; - default: // not required - setDvar("global_health", 70); - setDvar("speed", 1.2); - setDvar("streaks_online", 1); - setDvar("jump_height", 70); - setDvar("amount_weapons", 100); - break; - } + setDvar("gunmode", "Fungame"); + setDvar("g_gametype", "gungame"); + setDvar("gun_kills", 1); + setDvar("global_health", 60); + setDvar("speed", 1.5); + setDvar("streaks_online", 1); + setDvar("jump_height", 70); + setDvar("amount_weapons", 0); // 0 = full 162-weapon progression + setDvar("shuffle_weapons", 0); // weapons play in fixed order } loadSettings() { /////////////////////// CUSTOM SETTINGS ///////////////////////////// - //SetDvarIfUninitialized("gunmode", "Classic"); - SetDvarIfUninitialized("gunmode", "Fungame"); - initializeGametype(getDvar("gunmode")); + initializeGametype(); - if(getDvar("g_gametype") == "gungame_team") - setDvar("amount_weapons", int(getDvarInt("amount_weapons")/4)); - - setDvar("shuffle_weapons", 0); setDvar("intermission", 15); SetDvarIfUninitialized("show_damage_ui", 1); setDvar("gunversion", "1.5 Remaster by ^1Santahunter - Modified by God of Hellfire"); ///////////////////////////////////////////////////////////////////// - setDvar("scr_" + (getDvar("g_gametype")) + "_timelimit", 0); - setDvar("scr_" + (getDvar("g_gametype")) + "_scorelimit", 0); + setDvar("scr_gungame_timelimit", 0); + setDvar("scr_gungame_scorelimit", 0); setDvar("ui_allow_teamchange", 0); - setDvar("scr_game_allowkillcam", 0); + setDvar("scr_game_allowkillcam", 1); // needed for final killcam setDvar("testClients_watchKillcam", 0); setDvar("scr_game_hardpoints", 0); setDvar("scr_game_graceperiod", 0); @@ -143,20 +63,13 @@ loadSettings() level.state = "prematch"; level.markerIcon = "ui_host"; - level.teamKills = []; - level.teamKills["allies"] = 0; - level.teamKills["axis"] = 0; - level.teamKills["allies_weapon"] = 1; - level.teamKills["axis_weapon"] = 1; precacheShader(level.markerIcon); - setGamemodes(); // Bot Management setDvar("bots_main", 1); 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); @@ -164,17 +77,7 @@ loadSettings() setDvar("bots_skill_axis_med", 0); setDvar("bots_play_knife", 0); 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"); - // 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. + // Suppress engine-level developer prints. setDvar("developer", 0); } deleteSentries() @@ -233,7 +136,7 @@ launchGame() } onPlayerConnect() { - level endon("nuke"); + level endon("game_over"); while(true) { level waittill("connected", player); @@ -242,26 +145,32 @@ onPlayerConnect() } onPlayerSpawned() { - level endon("nuke"); + level endon("game_over"); self endon("disconnect"); self thread firstSpawn(); while(true) { self waittill("spawned_player"); self thread loadSetup(); - // self thread test(); } } firstSpawn() { self endon("disconnect"); - team = getCorrectTeam(); - self thread setStartWeapon(team); + self.current = 1; self.firstSpawn = true; self.knifeKills = 0; self.gungameKills = 0; self.isJugger = false; self.streaks = []; + + // Join team + select class IMMEDIATELY — must happen before any waits + // so the engine has a valid class when it auto-spawns mid-game joiners. + self notify("menuresponse", game["menu_team"], "allies"); + wait .05; + self notify("menuresponse", "changeclass", "class1"); + wait .05; + self setClientDvar("cg_drawSplatter", 0); self setClientDvar("cg_drawDamageFlash", 0); self setClientDvar("cg_viewkickscale", 0.1); @@ -269,7 +178,7 @@ firstSpawn() self setClientDvar("bg_shock_lookControl_mousesensitivityscale", 1); self setClientDvar("bg_shock_movement", 0); self setClientDvar("bg_shock_lookControl", 0); - self setClientDvar("scr_game_allowkillcam", 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); @@ -283,51 +192,20 @@ firstSpawn() self thread refillOnFire(); self thread watchVersion(); self thread FPSBoost(); - if(getDvar("g_gametype") == "gungame_team") - self thread upgradeOnTeamKills(); for(i=1;i<3;i++) self setClientDvar("lowAmmoWarningNoAmmoColor" + i, 0, 0, 0, 0); - wait .2; - self notify("menuresponse", game["menu_team"], team); - wait .1; - self notify("menuresponse", "changeclass", "class1"); - wait .1; - // Re-apply perks here — the engine's class-load triggered by changeclass above - // can wipe perk state before loadSetup() gets a chance to set them on first spawn. - self maps\mp\perks\_perks::givePerk("specialty_fastreload"); // Sleight of Hand + + // Re-apply perks — the engine's class-load can wipe perk state. + self maps\mp\perks\_perks::givePerk("specialty_fastreload"); self maps\mp\perks\_perks::givePerk("specialty_falldamage"); self maps\mp\perks\_perks::givePerk("specialty_quickdraw"); self maps\mp\perks\_perks::givePerk("specialty_lightweight"); self maps\mp\perks\_perks::givePerk("specialty_marathon"); - self maps\mp\perks\_perks::givePerk("specialty_fastmantle"); // Marathon Pro: faster mantle - self setPlayerData("challengeState", "ch_marathon_pro", 2); // unlock Marathon Pro + self maps\mp\perks\_perks::givePerk("specialty_fastmantle"); + self setPlayerData("challengeState", "ch_marathon_pro", 2); self.firstSpawn = false; self thread tryCreateMarkerIcons(); } -getCorrectTeam() -{ - if(getDvar("g_gametype") != "gungame_team") - return "allies"; - allies = 0; - axis = 0; - foreach(player in level.players) - { - if(player.team == "allies") - allies++; - else if(player.team == "axis") - axis++; - } - if(allies >= axis) - return "allies"; - return "axis"; -} -setStartWeapon(team) -{ - if(getDvar("g_gametype") != "gungame_team") - self.current = 1; - else - self.current = level.teamKills[team + "_weapon"]; -} loadSetup() { self hide(); @@ -385,31 +263,11 @@ loadSetup() self setMoveSpeedScale(0); } } -upgradeOnTeamKills() -{ - self endon("disconnect"); - while(true) - { - level waittill("upgrade_" + self.team); - wait .3; - enemyTeam = self getEnemyTeam(); - self.current = level.teamKills[self.team + "_weapon"]; - self thread updateWeapon(); - // setText() is safe here: bounded to ~N unique strings where N = weapon count. - // Configstrings are deduplicated, so all players sharing the same weapon# reuse one slot. - self.weaponhud setText("Gun: " + self.current + " / " + (level.gungameList.size) + " / ^3" + level.teamKills[enemyTeam + "_weapon"]); - } -} -getEnemyTeam() -{ - if(self.team == "allies") - return "axis"; - return "allies"; -} + updateWeapon() { // Safety: end this thread if the match is over or the player is gone/dead. - level endon("nuke"); + level endon("game_over"); self endon("disconnect"); self endon("death"); // Exclusivity guard: notifying "updateWeapon" kills any previously running @@ -423,17 +281,15 @@ updateWeapon() return; if(self.current > (level.gungameList.size - 1)) { - self thread tryNuke(); + self thread endMatch(); 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; + variant = 0; + self takeAllWeapons(); // Strip any engine-assigned class weapons (race with spawn) if (isSubstr(weaponName, "_akimbo")) self giveWeapon(weaponName, variant, true); else @@ -477,18 +333,17 @@ updateWeapon() self setMoveSpeedScale(0); } - if(isDefined(self.pers["isBot"]) && self.pers["isBot"] && getDvar("gunmode") == "Fungame") + if(isDefined(self.pers["isBot"]) && self.pers["isBot"]) { if(level.gungameList[self.current] == "riotshield_mp") { self setClientDvar("bots_play_knife", 1); - // Bots can't trigger the riot shield melee button, so we simulate it. self thread watchBotRiotShield(); } else { self setClientDvar("bots_play_knife", 0); - self notify("botshield"); // shut down any running shield bash thread + self notify("botshield"); } } // NOTE: The old recursive self-call "self updateWeapon()" was removed here. @@ -508,7 +363,7 @@ updateWeapon() } refillOnFire() { - level endon("nuke"); + level endon("game_over"); self endon("disconnect"); while(true) { @@ -520,7 +375,7 @@ refillOnFire() } onKilling() { self endon("disconnect"); - level endon("nuke"); + level endon("game_over"); self.multiplier = 0; self.amount = 0; kills = 0; @@ -570,25 +425,23 @@ onKilling() { refreshCounter++; self thread scorepopup(100); self.streaking++; - if(!level.isTeamGame) // cached in loadSettings — avoids getDvar() per kill + // Always upgrade weapon on kill (Fungame mode) + if(killsPerWeapon > 1) { - if(killsPerWeapon > 1) - { - if(self.gungameKills % killsPerWeapon == 0) - { - self.current++; - self thread updateWeapon(); - } - killsInGun = (self.gungameKills % killsPerWeapon); - self.weaponhud setText("Gun: " + self.current + " / " + (level.gungameList.size - 1)); - self.killhud setValue(killsInGun); - } - else + if(self.gungameKills % killsPerWeapon == 0) { self.current++; self thread updateWeapon(); - self.weaponhud setText("Gun: " + self.current + " / " + (level.gungameList.size - 1)); } + killsInGun = (self.gungameKills % killsPerWeapon); + self.weaponhud setText("Gun: " + self.current + " / " + (level.gungameList.size - 1)); + self.killhud setValue(killsInGun); + } + else + { + self.current++; + self thread updateWeapon(); + self.weaponhud setText("Gun: " + self.current + " / " + (level.gungameList.size - 1)); } if(self.current >= (level.gungameList.size-5) && !isDefined(self.markerIcon)) self thread initCreateMarkerIcon(); @@ -694,10 +547,7 @@ scorepopup(amount) self.scoretext.color = color; self.scoretext.glowColor = glowColor; self.scoretext SetPulseFX( 40, 2000, 600 ); - if(level.isKillConfirmed) // cached in loadSettings — avoids getDvar() per popup - self.scoretext setText("Upgraded!^3"); - else - self.scoretext setText("Killed!^3"); + self.scoretext setText("Killed!^3"); self.scoretext_amount.color = color; self.scoretext_amount.glowColor = glowColor; self.scoretext_amount SetPulseFX( 40, 2000, 600 ); @@ -757,40 +607,23 @@ lowerMultitext(multiplier) } wait 4; } -tryNuke() +endMatch() { - // Use level.nukeTriggered as OUR re-entry guard. - // DO NOT use level.nukeIncoming here — that flag is owned by the engine's - // _nuke.gsc::tryUseNuke(). Setting it before calling tryUseNuke causes the - // engine to see "nuke already on its way" and abort without firing the nuke. - if(isDefined(level.nukeTriggered) || level.state == "aftermatch") + // Re-entry guard: only one endMatch can run + if(isDefined(level.matchEnded) || level.state == "aftermatch") return; - // Set our custom flag and state immediately (atomic — no yield before this). - level.nukeTriggered = true; + level.matchEnded = true; level.state = "aftermatch"; - - if(getDvarInt("scr_nuke_enabled", 1) == 0) - { - level notify("nuke"); - foreach(player in level.players) - player notify("nuke"); - thread maps\mp\gametypes\_gamelogic::endGame( self, game["strings"]["score_limit_reached"] ); - return; - } - - iPrintLnBold("^1NUKE INCOMING!!"); - self thread maps\mp\killstreaks\_nuke::tryUseNuke(undefined, false); - - level notify("nuke"); + level notify("game_over"); foreach(player in level.players) - { - player hide(); - } + player notify("game_over"); - if(getDvar("g_gametype") != "gungame_team") - self.weaponhud setText("Gun: " + (level.gungameList.size - 1)); + self.weaponhud setText("Gun: " + (level.gungameList.size - 1)); + + // Normal end game screen — _mv.gsc hooks endGame for mapvoting + thread maps\mp\gametypes\_gamelogic::endGame( self, game["strings"]["score_limit_reached"] ); } createUI() { @@ -912,7 +745,7 @@ enforceSpeed() { // Calls setMoveSpeedScale every server frame — brute-forces over any engine // speed penalty (bullet pain, bg_shock, mantle exit, etc.) with no gaps. - level endon("nuke"); + level endon("game_over"); self endon("disconnect"); self endon("death"); while(true) @@ -930,7 +763,7 @@ takeInvalidWeapon() { self endon("disconnect"); self endon("death"); - level endon("nuke"); + level endon("game_over"); // Skip the first 5 frames so the initial updateWeapon() from loadSetup() has // time to complete its switchtoweaponimmediate before we start polling. // This prevents a false-positive correction that was causing the 2.5s delay. @@ -962,7 +795,7 @@ takeInvalidWeapon() takeInvalidWeapon2() { self endon("disconnect"); - level endon("nuke"); + level endon("game_over"); counter = 0; wait 3; while(1) @@ -1021,7 +854,7 @@ takeInvalidWeapon2() } ThrowingKnife() { - level endon("nuke"); + level endon("game_over"); self endon("disconnect"); self notify("tk"); self endon("tk"); @@ -1064,7 +897,7 @@ initCreateMarkerIcon() self thread createMarkerIcon(player); } } - self waittill_any("disconnect", "nuke"); + self waittill_any("disconnect", "game_over"); foreach(icon in self.markerIconsEnemies) { if(isDefined(icon)) @@ -1138,81 +971,10 @@ createRectangle(align, relative, x, y, width, height, color, shader, sort) return hud; } -upgradeTeamUI(team) -{ - fontElem = newTeamHudElem( team ); - fontElem.elemType = "font"; - fontElem.font = "default"; - fontElem.fontscale = 1.6; - fontElem.baseFontScale = 1.6; - fontElem.glowAlpha = 1; - fontElem.color = (1,1,0); - fontElem.glowColor = (1,0,0); - fontElem.x = 0; - fontElem.y = 0; - fontElem.width = 0; - fontElem.height = int(level.fontHeight * 1.6); - fontElem.xOffset = 0; - fontElem.yOffset = 0; - fontElem.children = []; - fontElem setParent( level.uiParent ); - fontElem.hidden = false; - fontElem setText("Weaponupgrade for your team!"); - fontElem setPoint("CENTER", "TOP", 0,200); - wait 3; - fontElem fadeOverTime(2); - fontElem.alpha = 0; - wait 2; - fontElem destroy(); -} -upgradeEnemyWeaponUI(team) -{ - foreach(player in level.players) - { - if(player.team == team) - { - player.weaponhud setText("Weapon: " + player.current + "/" + (level.gungameList.size) + "/^3" + level.teamKills[player getEnemyTeam() + "_weapon"]); - } - } -} -spawnDogTag(victim, attacker) -{ - picked = false; - dogtag = spawn("script_model", victim.origin+(0,0,30)); - //dogtag setModel("test_sphere_silver"); - //playFxOnTag( level.spawnGlow["enemy"], self, "pelvis" ); - //playFxOnTag( level.spawnGlow["friendly"], self, "j_head" ); - fx = spawnFx(level.dogtag, dogtag.origin); - fx2 = spawnFx(level.dogtag2, dogtag.origin); - triggerFx(fx); - triggerFx(fx2); - while(!isDefined(level.startNuke) && !picked) - { - foreach(player in level.players) - { - if(Distance(player.origin, dogtag.origin) < 75 && isAlive(player)) - { - if(player != victim) - player.gungameKills++; - dogtag delete(); - fx delete(); - fx2 delete(); - picked = true; - } - } - wait .1; - } - if(isDefined(fx)) - { - fx delete(); - fx2 delete(); - } - if(!picked) - dogtag delete(); -} + FPSBoost() { - level endon("nuke"); + level endon("game_over"); self endon("disconnect"); self notifyonplayercommand("FPS", "+actionslot 2"); for(;;) @@ -1223,31 +985,6 @@ FPSBoost() self setClientDvar("r_fullbright", 0); } } -test() -{ - self notifyOnPlayerCommand("F", "+activate"); - self thread test2(); - while(true) - { - self waittill("F"); - //self thread tryNuke(); - // setDvar("g_gametype", "gungame_team"); - // map("mp_rust"); - self suicide(); - } -} -test2() -{ - self notifyOnPlayerCommand("G", "+frag"); - self thread test2(); - while(true) - { - self waittill("G"); - setDvar("g_gametype", "gungame"); - setDvar("gunmode", "Kill Confirmed"); - map("mp_rust"); - } -} watchVersion() { self endon("disconnect"); @@ -1265,7 +1002,7 @@ watchVersion() } watchHealthHUD() { - level endon("nuke"); + level endon("game_over"); self endon("disconnect"); self endon("death"); @@ -1296,7 +1033,7 @@ watchHealthHUD() watchRegen() { - level endon("nuke"); + level endon("game_over"); self endon("disconnect"); self endon("death"); @@ -1318,7 +1055,7 @@ watchRegen() watchDeagleGL() { - level endon("nuke"); + level endon("game_over"); self endon("disconnect"); self endon("death"); // prevent thread accumulation across respawns while(true) @@ -1342,7 +1079,7 @@ watchDeagleGL() watchHUD() { - level endon("nuke"); + level endon("game_over"); self endon("disconnect"); self endon("death"); // prevent thread accumulation across respawns while(true) @@ -1355,7 +1092,7 @@ watchHUD() watchM40A3() { - level endon("nuke"); + level endon("game_over"); self endon("disconnect"); self endon("death"); // prevent thread accumulation across respawns while(true) @@ -1387,7 +1124,7 @@ watchM40A3() // matching the real shield bash range (~85 units) and cooldown (~0.8s). watchBotRiotShield() { - level endon("nuke"); + level endon("game_over"); self endon("death"); self endon("disconnect"); // Exclusivity guard: kill any previous instance when weapon changes re-trigger this. diff --git a/mod/streaks.gsc b/mod/streaks.gsc index 35a4c92..7fc5775 100755 --- a/mod/streaks.gsc +++ b/mod/streaks.gsc @@ -22,8 +22,7 @@ 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.explosionfx is loaded by _rank.gsc (helicopter_explosion_secondary_small) level.streaks3 = []; level.streaks6 = []; @@ -157,7 +156,7 @@ onKilling() { self endon("death"); self endon("disconnect"); - level endon("nuke"); + level endon("game_over"); spree = 0; value = 3; counter = 1; @@ -277,9 +276,7 @@ Radioactive() { self endon("disconnect"); self endon("death"); - level endon("nuke"); - // Cache once \u2014 getDvar() inside the inner foreach would cost ~120 native calls/sec. - isTeamGame = (getDvar("g_gametype") == "gungame_team"); + level endon("game_over"); playFxOnTag( level.spawnGlow["enemy"], self, "pelvis" ); playFxOnTag( level.spawnGlow["friendly"], self, "j_head" ); while(1) @@ -289,8 +286,6 @@ Radioactive() { if(player == self) 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 ); @@ -323,8 +318,8 @@ 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["bullet_explode"], Location); - RadiusDamage(Location, 50, 30, 20, self ); + playFx(level.explosionfx, Location); + RadiusDamage(Location, 30, 25, 15, self ); //self RadiusDamage(Location,250,self.explodmg,self.explomindmg,self,"MOD_Explosive","barrel_mp"); wait self.explotime; } @@ -428,7 +423,7 @@ DeleteIMS2(ims) // FIX: The original waited on "fuckemp" which was never notified anywhere — // this created a permanent zombie thread holding the ims entity reference. // Now we wait for nuke (end of match) and clean up the entity then. - level waittill("nuke"); + level waittill("game_over"); if(isDefined(ims)) ims delete(); } @@ -444,7 +439,7 @@ DeleteIt(block, block2, block3, block4) } DeleteItOnNuke(block, block2, block3, block4) { - level waittill("nuke"); + level waittill("game_over"); if(isDefined(block)) block delete(); if(isDefined(block2)) block2 delete(); if(isDefined(block3)) block3 delete(); @@ -563,8 +558,7 @@ scanPlayer() { if(player == self) continue; - if((getDvar("g_gametype") == "gungame_team") && self.team == player.team) - continue; + if(Distance(player.origin,self.origin) <= 1000) { go = true; @@ -658,7 +652,7 @@ infoText(item) } Juggernaut() { - level endon("nuke"); + level endon("game_over"); self.isJugger = true; // FIX: Use the custom health system (actual_maxhealth/actual_health) instead of // the raw engine maxhealth. Setting engine maxhealth directly broke the HUD display @@ -685,12 +679,12 @@ destroyJuggOnNuke(juggIcon) { self endon("death"); self endon("disconnect"); - level waittill("nuke"); + level waittill("game_over"); juggIcon destroy(); } NoReload() { - level endon("nuke"); // FIX: was missing — thread survived past match end + level endon("game_over"); // FIX: was missing — thread survived past match end self endon("death"); self endon("disconnect"); while(true) diff --git a/mod/vote.gsc b/mod/vote.gsc deleted file mode 100755 index 4fa41ab..0000000 --- a/mod/vote.gsc +++ /dev/null @@ -1,667 +0,0 @@ -#include common_scripts\utility; -#include maps\mp\_utility; -#include maps\mp\gametypes\_hud_util; - -// ========================================================= -// FileName: vote.gsc -// Date: 11.05.2019 -// -// Author Of Code: Santahunter -// -// ========================================================= - - -/* - -ALPHA -so_killspree_trainer "The Pit" -so_rooftop_contingency "Sniper Fi" -so_killspree_favela "O Cristo Redentor" -so_forest_contingency "Evasion" -so_crossing_so_bridge "Suspension" - -BRAVO -so_ac139_co_hunted "Overwatch" (Two-Players Min) -so_killspree_invasion "Body Count" -so_defuse_favela_escape "Bomb Squad" -so_snowrace1_cliffhanger "Race" -so_chopper_invasion "Big Brother" (Two-Players Min) /////////////////// BURGERTOWN - -CHARLIE -so_hidden_so_ghillies "Hidden" -so_showers_gulag "Breach & Clear" -so_snowrace2_cliffhanger "Time Trial" -so_defuse_invasion "Homeland Security" -so_intel_boneyard "Snatch & Grab" - -DELTA -so_download_arcadia "Wardriving" -so_demo_so_bridge "Wreckage" -so_sabotage_cliffhanger "Acceptable Losses" -so_escape_airport "Terminal" -so_takeover_estate "Estate Takedown" - -ECHO -so_assault_oilrig "Wetwork" -so_juggernauts_favela "High Explosive" -so_takeover_oilrig "Armor Piercing" - -*/ - -loadVote() -{ - precacheShader("line_horizontal"); - precacheShader("hudscoreboardscroll_uparrow"); - precacheShader("hudscoreboardscroll_downarrow"); - level.maxOptions = 8; - maps(); - thread startVote(); -} -maps() -{ - level.maps = []; - // MW2 Base Maps - level.maps[level.maps.size] = "mp_rust"; - level.maps[level.maps.size] = "mp_afghan"; - level.maps[level.maps.size] = "mp_terminal"; - level.maps[level.maps.size] = "mp_highrise"; - //level.maps[level.maps.size] = "mp_derail"; //fuck derail - level.maps[level.maps.size] = "mp_rundown"; - level.maps[level.maps.size] = "mp_brecourt"; //Wasteland - level.maps[level.maps.size] = "mp_boneyard"; //Scrapyard - level.maps[level.maps.size] = "mp_quarry"; - level.maps[level.maps.size] = "mp_nightshift"; //Skidrow - level.maps[level.maps.size] = "mp_estate"; - level.maps[level.maps.size] = "mp_invasion"; - level.maps[level.maps.size] = "mp_checkpoint"; //Karachi - level.maps[level.maps.size] = "mp_subbase"; - level.maps[level.maps.size] = "mp_favela"; - level.maps[level.maps.size] = "mp_underpass"; - //level.maps[level.maps.size] = "iw4_credits"; // no - - // MW2 DLC Maps - level.maps[level.maps.size] = "mp_complex"; //Bailout Stimulus DLC - level.maps[level.maps.size] = "mp_crash"; //Crash - level.maps[level.maps.size] = "mp_overgrown"; //Overgrown - level.maps[level.maps.size] = "mp_compact"; //Salvage Stimulus DLC - level.maps[level.maps.size] = "mp_storm"; //Storm - - level.maps[level.maps.size] = "mp_abandon"; //Carnival - //level.maps[level.maps.size] = "mp_fuel2"; // hell no - level.maps[level.maps.size] = "mp_strike"; //Strike - level.maps[level.maps.size] = "mp_trailerpark"; //Trailerpark - level.maps[level.maps.size] = "mp_vacant"; //Vacant - - level.maps[level.maps.size] = "mp_nuked"; //Nuketown - - level.maps[level.maps.size] = "mp_cross_fire"; - level.maps[level.maps.size] = "mp_bloc"; - level.maps[level.maps.size] = "mp_cargoship"; - - level.maps[level.maps.size] = "mp_killhouse"; - level.maps[level.maps.size] = "mp_bog_sh"; - - level.maps[level.maps.size] = "mp_cargoship_sh"; - - level.maps[level.maps.size] = "mp_shipment_long"; - level.maps[level.maps.size] = "mp_rust_long"; - level.maps[level.maps.size] = "mp_firingrange"; - - level.maps[level.maps.size] = "mp_storm_spring"; - level.maps[level.maps.size] = "mp_fav_tropical"; - level.maps[level.maps.size] = "mp_estate_tropical"; - level.maps[level.maps.size] = "mp_crash_tropical"; - level.maps[level.maps.size] = "mp_bloc_sh"; - - ////////////// NOT VANILLA ///////////////////////// - - //level.maps[level.maps.size] = "af_caves"; - //level.maps[level.maps.size] = "af_chase"; - //level.maps[level.maps.size] = "airport"; - //level.maps[level.maps.size] = "arcadia"; - //level.maps[level.maps.size] = "boneyard"; - //level.maps[level.maps.size] = "ending"; - //level.maps[level.maps.size] = "cliffhanger"; - //level.maps[level.maps.size] = "co_hunted"; - //level.maps[level.maps.size] = "so_forest_contingency"; - //level.maps[level.maps.size] = "dcburning"; - //level.maps[level.maps.size] = "dcemp"; - //level.maps[level.maps.size] = "estate"; - //level.maps[level.maps.size] = "favela"; - //level.maps[level.maps.size] = "so_showers_gulag"; - level.maps[level.maps.size] = "oilrig"; - //level.maps[level.maps.size] = "roadkill"; - //level.maps[level.maps.size] = "so_hidden_so_ghillies"; - //level.maps[level.maps.size] = "trainer"; - - /////////////// TAUROS ////////////////////////////// - - //level.maps[level.maps.size] = "so_chopper_invasion"; // Burgertown // so_killspree_invasion - //level.maps[level.maps.size] = "so_killspree_trainer"; // Startmission // The Pit - - /////////////// DRAGONITE ////////////////////////////// - //level.maps[level.maps.size] = "so_defuse_favela_escape"; - //level.maps[level.maps.size] = "dc_whitehouse"; - //level.maps[level.maps.size] = "so_crossing_so_bridge"; - - level.mapStruct = []; - - foreach(map in level.maps) - { - level.mapStruct[level.mapStruct.size] = spawnStruct(); - level.mapStruct[level.mapStruct.size-1].mapname = map; - level.mapStruct[level.mapStruct.size-1].displayName = getDisplayName(map); - } - -} -getDisplayName(map) -{ - if(map == "mp_afghan") - return "Afghan"; - if(map == "mp_rust") - return "Rust"; - if(map == "mp_terminal") - return "Terminal"; - if(map == "mp_highrise") - return "Highrise"; - if(map == "mp_derail") - return "Derail"; - if(map == "mp_rundown") - return "Rundown"; - if(map == "mp_brecourt") - return "Wasteland"; - if(map == "mp_boneyard") - return "Scrapyard"; - if(map == "mp_quarry") - return "Quarry"; - if(map == "mp_estate") - return "Estate"; - if(map == "mp_nightshift") - return "Skidrow"; - if(map == "mp_invasion") - return "Invasion"; - if(map == "mp_checkpoint") - return "Karachi"; - if(map == "mp_subbase") - return "Subbase"; - if(map == "mp_favela") - return "Favela"; - if(map == "mp_underpass") - return "Underpass"; - if(map == "iw4_credits") - return "Testmap"; - if(map == "mp_abandon") - return "Carnival"; - if(map == "mp_fuel2") - return "Fuel"; - if(map == "mp_strike") - return "Strike"; - if(map == "mp_trailerpark") - return "Trailerpark"; - if(map == "mp_vacant") - return "Vacant"; - if(map == "mp_complex") - return "Bailout"; - if(map == "mp_crash") - return "Crash"; - if(map == "mp_overgrown") - return "Overgrown"; - if(map == "mp_compact") - return "Salvage"; - if(map == "mp_storm") - return "Storm"; - if(map == "mp_nuked") - return "Nuketown"; - if(map == "mp_cross_fire") - return "Crossfire"; - if(map == "mp_cargoship") - return "Cargoship"; - if(map == "mp_bloc") - return "Bloc"; - if(map == "mp_killhouse") - return "Killhouse"; - if(map == "mp_bog_sh") - return "Bog"; - if(map == "mp_cargoship_sh") - return "Freighter"; - if(map == "mp_shipment_long") - return "Shipment Long"; - if(map == "mp_rust_long") - return "Rust Long"; - if(map == "mp_firingrange") - return "Firing Range"; - if(map == "mp_storm_spring") - return "Chemical Storm"; - if(map == "mp_fav_tropical") - return "Tropical Favela"; - if(map == "mp_estate_tropical") - return "Tropical Estate"; - if(map == "mp_crash_tropical") - return "Tropical Crash"; - if(map == "mp_bloc_sh") - return "Ruin City"; - if(map == "af_caves") - return "Afghanistan Caves"; - if(map == "af_chase") - return "Afghanistan Hunt"; - if(map == "airport") - return "Airport"; - if(map == "arcadia") - return "Arcadia"; - if(map == "boneyard") - return "Airplane Scrapyard"; - if(map == "ending") - return "Museum"; - if(map == "cliffhanger") - return "Cliffhanger"; - if(map == "co_hunted") - return "Hunted"; - if(map == "contingency" || map == "so_forest_contingency") - return "Contingency"; - if(map == "dcburning") - return "DC Burning"; - if(map == "dcemp") - return "DC Dark"; - if(map == "estate") - return "Makarovs House"; - if(map == "favela") - return "Rojas Favelas"; - if(map == "favela_escape" || map == "so_defuse_favela_escape") - { - return "Favels Escape"; - } - if(map == "gulag" || map == "so_showers_gulag") - return "Gulag"; - if(map == "invasion") - return "School"; - if(map == "oilrig") - return "Oilrig"; - if(map == "roadkill") - return "School"; - if(map == "so_hidden_so_ghillies") - return "Chernobyl"; - if(map == "trainer" || map == "so_killspree_trainer") - return "The Pit"; - if(map == "so_chopper_invasion" || map == "so_killspree_invasion") - return "Burgertown"; - if(map == "dc_whitehouse") - { - return "DC Whitehouse"; - } - if(map == "so_crossing_so_bridge") - return "Bridge"; - return map; -} - -createRectangle(shader,align, relative, x, y, width, height) -{ - hud = newHudElem(); - hud.elemType = "icon"; - hud.width = width; - hud.height = height; - hud.alpha = 1; - hud.xOffset = 0; - hud.yOffset = 0; - hud.children = []; - hud.sort = 1; - hud setParent(level.uiParent); - hud setShader(shader,width,height); - hud.hidden = false; - hud.HideWhenInMenu = true; - hud setPoint(align,relative,x,y); - return hud; -} -createPlayerRectangle(shader,align, relative, x, y, width, height) -{ - hud = newClientHudElem(self); - hud.elemType = "icon"; - hud.width = width; - hud.height = height; - hud.alpha = 1; - hud.xOffset = 0; - hud.yOffset = 0; - hud.children = []; - hud.sort = 1; - hud setParent(level.uiParent); - hud setShader(shader,width,height); - hud.hidden = false; - hud.HideWhenInMenu = true; - hud setPoint(align,relative,x,y); - return hud; -} -/////////////////////////////////////////////////////////////////////// -doCountdown(timer,timer2) -{ - secs = 20; - timer.label = &"Time left: "; - timer2.alpha = 0; // subsecond display removed - for(secs = 20; secs > 0; secs--) - { - timer setValue(secs); - wait 1; - } - level notify("finishVote"); -} -startVote() -{ - //level waittill ( "game_ended" ); - //level waittill ( "spawning_intermission" ); - level waittill("spawnVote"); - //setDvar("g_hardcore", 1); - setSlowMotion( 0.25, 1, 2.0 ); - thread killGungameHUD(); - background = createRectangle("black","CENTER", "CENTER", 0,0,250,350); - background.alpha = .7; - line = createRectangle("line_horizontal","CENTER", "CENTER", 0,-145,180,3); - line.sort = 2; - //line.color = (1,0,0); - line2 = createRectangle("line_horizontal","CENTER", "CENTER", 0,70,180,3); - line2.sort = 2; - //line2.color = (1,0,0); - line3 = createRectangle("line_horizontal","CENTER", "CENTER", 0,110,180,3); - line3.sort = 2; - //line3.color = (1,0,0); - - //background2 = createRectangle("black","CENTER", "CENTER", -200,0,75,180); - //background2.alpha = .7; - arrowUp = createRectangle("hudscoreboardscroll_uparrow","CENTER", "CENTER", -100,-125,25,25); - arrowDown = createRectangle("hudscoreboardscroll_downarrow","CENTER", "CENTER", 100,-125,25,25); - arrowUp.sort = 2; - arrowDown.sort = 2; - controls = level createServerFontString("default", 1.5); - controls setPoint("CENTER", "CENTER", -100,-100); - controls.hideWhenInMenu = true; - controls setText("[{+forward}]"); - controls2 = level createServerFontString("default", 1.5); - controls2 setPoint("CENTER", "CENTER", 100,-100); - controls2.hideWhenInMenu = true; - controls2 setText("[{+back}]"); - controls3 = level createServerFontString("default", 1.3); - controls3 setPoint("CENTER", "CENTER", 0,-125); - controls3.hideWhenInMenu = true; - controls3 setText("[{+gostand}] to select"); - - - //background3 = createRectangle("black","CENTER", "CENTER", 225,0,180,75); - //background3.alpha = .7; - timer = level createServerFontString("default", 1.8); - timer setPoint("CENTER", "CENTER", 0,90); - timer.hideWhenInMenu = true; - - timer2 = level createServerFontString("default", 1.8); - timer2 setPoint("CENTER", "CENTER", 30,90); - timer2.hideWhenInMenu = true; - timer2.label = &": "; - timer2.sort = 3; - - credits = level createServerFontString("default", 1.6); - credits setPoint("CENTER", "CENTER", 0,130); - credits.hideWhenInMenu = true; - credits setText("Made by ^:Santahunter"); // if you change this credits Im gonna come to your house and smack ur sister... for real, dont change it, it took many hours and days to come to this point - - thread doCountdown(timer,timer2); - - header = createServerFontString("default", 2); - header setPoint("CENTER", "CENTER", 0,-155); - header.hideWhenInMenu = false; - header setText("Votemap"); - - level.options = []; - level.votes = []; - level.invalidMaps = []; - text = ""; - level.elems = createServerFontString("default", 1.5); - level.elems setPoint("CENTER", "CENTER", 20,-75); - level.elems.hideWhenInMenu = true; - //level.elems = []; - // FIX: Added maxRetries guard. If the map pool is smaller than maxOptions, the - // i-- retry would loop forever (no wait = instant VM instruction-count crash). - maxRetries = level.maps.size * 3; - retries = 0; - for(i = 0;i < level.maxOptions;i++) - { - retries++; - if(retries > maxRetries) - break; // pool exhausted: accept fewer options rather than loop forever - valid = true; - map = level.maps[randomInt(level.maps.size-1)]; - gamemode = level.gungamemodes[randomInt(level.gungamemodes.size)]; - foreach(invalid in level.invalidMaps) - { - if(map == invalid) - valid = false; - } - if(!valid) - i--; - else - { - text += getDisplayName(map) + "[^3" + gamemode + "^7] [0]\n"; - level.votes[i] = 0; - level.options[i] = spawnstruct(); - level.options[i].map = map; - level.options[i].gamemode = gamemode; - level.invalidMaps[level.invalidMaps.size] = map; - } - } - level.elems setText(text); - foreach(player in level.players) - { - player.scrollbarY = -75; - player.scrollbar = player createPlayerRectangle("line_horizontal","CENTER", "CENTER", 0,player.scrollbarY,220,11); - player.scrollbar.color = (0,1,0); - player.scrollbar.sort = 2; - player thread doControls(); - } - level waittill("finishVote"); - background destroy(); - - //background2 destroy(); - //background3 destroy(); - header destroy(); - timer destroy(); - timer2 destroy(); - controls destroy(); - controls2 destroy(); - controls3 destroy(); - arrowUp destroy(); - arrowDown destroy(); - line destroy(); - line2 destroy(); - line3 destroy(); - credits destroy(); - maps = []; - level.elems destroy(); - foreach(player in level.players) - player.scrollbar destroy(); - - sameVote = -1; - altVote = ""; - number = 0; - maxVote = level.votes[0]; - for(i = 1;i < level.votes.size;i++) - { - if(level.votes[i] >= maxVote) - { - maxVote = level.votes[i]; - sameVote = -1; - number = i; - } - } - mod\main::initializeGametype(level.options[number].gamemode); - setDvar("sv_mapRotationCurrent", "map " + level.options[number].map); - setDvar("sv_mapRotation", "map " + level.options[number].map); - level notify("endVote"); - wait 0.1; - map(level.options[number].map); -} -doControls() -{ - self endon("disconnect"); - level endon("finishVote"); - self.totalVotes = 0; - self.position = 0; - self.oldPosition = self.position; - voted = false; - self thread onForward(); - self thread onBackward(); - self notifyOnPlayerCommand("Stand", "+gostand"); - while(true) - { - self waittill("Stand"); - if(self.totalVotes > 3) - { - self iPrintln("^1Maximal votes done"); - continue; - } - self.totalVotes++; - if(voted) - { - level.votes[self.oldPosition]--; - //level.elems[self.oldPosition] setText(getDisplayName(level.options[self.oldPosition]) + " [" + level.votes[self.oldPosition] + "]"); - - } - self.oldPosition = self.position; - //voted = level.options[self.position]; - voted = true; - level.votes[self.position]++; - //level.elems[self.position] setText(getDisplayName(level.options[self.position]) + " [" + level.votes[self.position] + "]"); - // FIX: Rebuild vote text only if it actually changed, and cap total rebuilds. - // Each unique setText() string permanently burns a configstring slot (512 limit). - text = ""; - for(i = 0;i < level.maxOptions;i++) - { - text += getDisplayName(level.options[i].map) + " [^3" + level.options[i].gamemode + "^7][" + level.votes[i] + "]\n"; - } - if(!isDefined(level._lastVoteText) || level._lastVoteText != text) - { - level.elems setText(text); - level._lastVoteText = text; - } - } -} -onForward() -{ - self endon("disconnect"); - level endon("finishVote"); - self notify("onForward"); - self endon("onForward"); - self notifyOnPlayerCommand("Forward", "+forward"); - while(true) - { - self waittill("Forward"); - self.position--; - self.scrollbar destroy(); - if(self.position < 0) - { - self.position = level.maxOptions-1; - self.scrollbarY = 51; - } - else - self.scrollbarY -= 18; - - //self.scrollbar = self createPlayerRectangle("line_horizontal","CENTER", "CENTER", level.elems[self.position].x,level.elems[self.position].y,220,8); - self.scrollbar = self createPlayerRectangle("line_horizontal","CENTER", "CENTER", 0,self.scrollbarY,220,11); - self.scrollbar.color = (0,1,0); - self.scrollbar.sort = 2; - } -} -onBackward() -{ - self endon("disconnect"); - level endon("finishVote"); - self notify("onBackward"); - self endon("onBackward"); - self notifyOnPlayerCommand("Backward", "+back"); - while(true) - { - self waittill("Backward"); - self.position++; - if(self.position > level.maxOptions-1) - { - self.position = 0; - self.scrollbarY = -75; - } - else - self.scrollbarY += 18; - //iPrintln(self.scrollbarY); - self.scrollbar destroy(); - //self.scrollbar = self createPlayerRectangle("line_horizontal","CENTER", "CENTER", level.elems[self.position].x,level.elems[self.position].y,220,8); - self.scrollbar = self createPlayerRectangle("line_horizontal","CENTER", "CENTER", 0,self.scrollbarY,220,11); - self.scrollbar.color = (0,1,0); - self.scrollbar.sort = 2; - } -} -killGungameHUD() -{ - foreach(player in level.players) - { - for(i=2;i<6;i++) - { - if(isDefined(player.multitext[i])) - player.multitext[i] destroy(); - } - - if(isdefined(player.scoretext)) - player.scoretext destroy(); - if(isdefined(player.scoretext_amount)) - player.scoretext_amount destroy(); - if(isdefined(player.weaponhud)) - player.weaponhud destroy(); - if(isdefined(player.weapontotalhud)) - player.weapontotalhud destroy(); - if(isdefined(player.killhud)) - player.killhud destroy(); - if(isdefined(player.killtotalhud)) - player.killtotalhud destroy(); - if(isdefined(player.ratiohud)) - player.ratiohud destroy(); - if(isDefined(player.streakText)) - player.streakText destroy(); - - if(isDefined(player.streakIcons)) - { - foreach(icon in player.streakIcons) - { - if(isDefined(icon)) - icon destroy(); - } - } - - if(isDefined(player.markerIconsEnemies)) - { - foreach(icon in player.markerIconsEnemies) - { - if(isDefined(icon)) - icon destroy(); - } - } - - if(isDefined(player.healthHUD)) - player.healthHUD destroy(); - - if(isDefined(player.versionText)) - player.versionText destroy(); - - if(isDefined(player.line)) - player.line destroy(); - - if(isDefined(player.crosshair)) - player.crosshair destroy(); - } -} - - - - - - - - - - - - - - - - diff --git a/mod/weapons.gsc b/mod/weapons.gsc index 3977163..b491d7d 100755 --- a/mod/weapons.gsc +++ b/mod/weapons.gsc @@ -5,127 +5,7 @@ loadWeapons() { - level.gungameList = []; - weaponList = []; - amount_of_weapons = getDvarInt("amount_weapons"); - - if(getDvar("gunmode") == "Snipers only") - { - amount_of_weapons = int(amount_of_weapons/2); - weaponList[weaponList.size] = "barrett_mp"; - weaponList[weaponList.size] = "wa2000_mp"; - weaponList[weaponList.size] = "m21_mp"; - weaponList[weaponList.size] = "cheytac_mp"; - } - else if(getDvar("gunmode") == "Pistol & Shotguns only") - { - amount_of_weapons = int(amount_of_weapons/2); - weaponList[weaponList.size] = "deserteagle_mp"; - weaponList[weaponList.size] = "coltanaconda_mp"; - weaponList[weaponList.size] = "beretta_mp"; - // semi auto pistols - weaponList[weaponList.size] = "tmp_mp"; - weaponList[weaponList.size] = "glock_mp"; - weaponList[weaponList.size] = "beretta393_mp"; - weaponList[weaponList.size] = "pp2000_mp"; - // shotguns - weaponList[weaponList.size] = "ranger_mp"; - weaponList[weaponList.size] = "model1887_mp"; - weaponList[weaponList.size] = "striker_mp"; - weaponList[weaponList.size] = "aa12_mp"; - weaponList[weaponList.size] = "m1014_mp"; - weaponList[weaponList.size] = "spas12_mp"; - } - else if(getDvar("gunmode") == "Fungame") - { - loadFungameList(); - return; - } - else - { - // pistols - weaponList[weaponList.size] = "usp_mp"; - weaponList[weaponList.size] = "deserteagle_mp"; - weaponList[weaponList.size] = "deserteagle_akimbo_mp"; // GL deagle - weaponList[weaponList.size] = "coltanaconda_mp"; - weaponList[weaponList.size] = "beretta_mp"; - // semi auto pistols - weaponList[weaponList.size] = "tmp_mp"; - weaponList[weaponList.size] = "glock_mp"; - weaponList[weaponList.size] = "beretta393_mp"; - weaponList[weaponList.size] = "pp2000_mp"; - // shotguns - weaponList[weaponList.size] = "ranger_mp"; - weaponList[weaponList.size] = "model1887_mp"; - weaponList[weaponList.size] = "striker_mp"; - weaponList[weaponList.size] = "aa12_mp"; - weaponList[weaponList.size] = "m1014_mp"; - weaponList[weaponList.size] = "spas12_mp"; - // rocket launcher - weaponList[weaponList.size] = "m79_mp"; - weaponList[weaponList.size] = "rpg_mp"; - weaponList[weaponList.size] = "at4_mp"; - //weaponList[weaponList.size] = "javelin_mp"; - // assault rifles - weaponList[weaponList.size] = "ak47_mp"; - weaponList[weaponList.size] = "m16_mp"; - weaponList[weaponList.size] = "m4_mp"; - weaponList[weaponList.size] = "fn2000_mp"; - weaponList[weaponList.size] = "masada_mp"; - weaponList[weaponList.size] = "famas_mp"; - weaponList[weaponList.size] = "fal_mp"; - weaponList[weaponList.size] = "scar_mp"; - weaponList[weaponList.size] = "tavor_mp"; - weaponList[weaponList.size] = "ak47classic_mp"; - // sub machine guns - weaponList[weaponList.size] = "mp5k_mp"; - weaponList[weaponList.size] = "uzi_mp"; - weaponList[weaponList.size] = "p90_mp"; - weaponList[weaponList.size] = "kriss_mp"; - weaponList[weaponList.size] = "ump45_mp"; - weaponList[weaponList.size] = "ak74u_mp"; - // light machine guns - weaponList[weaponList.size] = "rpd_mp"; - weaponList[weaponList.size] = "sa80_mp"; - weaponList[weaponList.size] = "mg4_mp"; - weaponList[weaponList.size] = "m240_mp"; - weaponList[weaponList.size] = "aug_mp"; - // sniper - weaponList[weaponList.size] = "barrett_mp"; - weaponList[weaponList.size] = "wa2000_mp"; - weaponList[weaponList.size] = "m21_mp"; - weaponList[weaponList.size] = "cheytac_mp"; - weaponList[weaponList.size] = "dragunov_mp"; - weaponList[weaponList.size] = "m40a3_mp"; - // special - weaponList[weaponList.size] = "ac130_mp"; - //weaponList[weaponList.size] = "riotshield_mp"; - - } - - shuffle = getDvarInt("shuffle_weapons"); - level.gungameList[0] = "defaultweapon_mp"; - for(i = 1; i <= amount_of_weapons; i++) - { - if(weaponList.size <= 0) break; - - if(shuffle) - id = randomInt(weaponList.size); - else - id = (i - 1) % weaponList.size; - - level.gungameList[level.gungameList.size] = setWeapon(weaponList[id]); - - // Only remove specific weapons if we still have enough unique ones left - if(weaponList.size > 5) - { - if(weaponList[id] == "m79_mp" || weaponList[id] == "at4_mp" || weaponList[id] == "rpg_mp" || weaponList[id] == "riotshield_mp" || weaponList[id] == "dragunov_mp" || weaponList[id] == "m40a3_mp" || weaponList[id] == "peacekeeper_mp" || weaponList[id] == "deserteagle_akimbo_mp") - weaponList = removeIDfromArray(id, weaponList); - } - } - //level.gungameList[1] = setWeapon("rpg_mp"); - //level.gungameList[1] = "rpg_mp"; - level.weaponsLoaded = true; + loadFungameList(); } removeIDfromArray(id, weaponList) { -- 2.50.1 From b2a48a1fc428ddd8678b50e766955ae4487a7ea3 Mon Sep 17 00:00:00 2001 From: Kibi Kelburton Date: Mon, 11 May 2026 02:47:34 +0200 Subject: [PATCH 3/3] idk man --- maps/mp/gametypes/_callbacksetup.gsc | 11 +++++++++++ maps/mp/gametypes/gungame.gsc | 10 +++++----- mod/main.gsc | 9 +++++++-- mod/streaks.gsc | 6 +++++- 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/maps/mp/gametypes/_callbacksetup.gsc b/maps/mp/gametypes/_callbacksetup.gsc index 56d7b76..030bbd9 100755 --- a/maps/mp/gametypes/_callbacksetup.gsc +++ b/maps/mp/gametypes/_callbacksetup.gsc @@ -46,6 +46,17 @@ CodeCallback_PlayerConnect() level waittill( "eternity" ); self endon("disconnect"); + // Initialize pers values before any engine/bot system can check them + if(!isDefined(self.pers["lastEarnedStreak"])) + self.pers["lastEarnedStreak"] = ""; + if(!isDefined(self.pers["team"])) + self.pers["team"] = "allies"; + if(!isDefined(self.pers["deaths"])) + self.pers["deaths"] = 0; + if(!isDefined(self.pers["kills"])) + self.pers["kills"] = 0; + if(!isDefined(self.team)) + self.team = "allies"; [[level.callbackPlayerConnect]](); } diff --git a/maps/mp/gametypes/gungame.gsc b/maps/mp/gametypes/gungame.gsc index bba783f..a6ef533 100755 --- a/maps/mp/gametypes/gungame.gsc +++ b/maps/mp/gametypes/gungame.gsc @@ -38,8 +38,8 @@ onStartGameType() { setClientNameMode("auto_change"); - setObjectiveText( "allies", "Press ^3[{+actionslot 2}] ^7for FPS-Boost \n\n Mod made by ^:Santahunter^7!" ); - setObjectiveText( "axis", "Press ^3[{+actionslot 2}] ^7for FPS-Boost \n\n Mod made by ^:Santahunter^7!" ); + setObjectiveText( "allies", "Mod made by Santahunter \n\n Modified by God of Hellfire" ); + setObjectiveText( "axis", "Mod made by Santahunter \n\n Modified by God of Hellfire" ); if ( level.splitscreen ) { @@ -52,10 +52,10 @@ onStartGameType() setObjectiveScoreText( "axis", &"OBJECTIVES_DM_SCORE" ); } - setObjectiveHintText( "allies", "Be the first who cycled through all guns to win! \n \n Mod made by ^:Santahunter^7!" ); - setObjectiveHintText( "axis", "Be the first who cycled through all guns to win! \n \n Mod made by ^:Santahunter^7!" ); + setObjectiveHintText( "allies", "Mod made by Santahunter \n\n Modified by God of Hellfire" ); + setObjectiveHintText( "axis", "Mod made by Santahunter \n\n Modified by God of Hellfire" ); - level.killcam = true; // enables final killcam at end of game + level.killcam = false; level.spawnMins = ( 0, 0, 0 ); level.spawnMaxs = ( 0, 0, 0 ); maps\mp\gametypes\_spawnlogic::addSpawnPoints( "allies", "mp_dm_spawn" ); diff --git a/mod/main.gsc b/mod/main.gsc index b671bf9..c596a9d 100755 --- a/mod/main.gsc +++ b/mod/main.gsc @@ -36,7 +36,7 @@ loadSettings() setDvar("intermission", 15); SetDvarIfUninitialized("show_damage_ui", 1); - setDvar("gunversion", "1.5 Remaster by ^1Santahunter - Modified by God of Hellfire"); + setDvar("gunversion", ""); ///////////////////////////////////////////////////////////////////// setDvar("scr_gungame_timelimit", 0); setDvar("scr_gungame_scorelimit", 0); @@ -64,6 +64,8 @@ loadSettings() level.state = "prematch"; level.markerIcon = "ui_host"; precacheShader(level.markerIcon); + precacheShader("line_horizontal"); + precacheShader("white"); // Bot Management setDvar("bots_main", 1); @@ -163,6 +165,9 @@ firstSpawn() self.gungameKills = 0; self.isJugger = false; self.streaks = []; + self.pers["lastEarnedStreak"] = ""; // prevent bot chat crash on undefined comparison + self.pers["team"] = "allies"; + self.team = "allies"; // Join team + select class IMMEDIATELY — must happen before any waits // so the engine has a valid class when it auto-spawns mid-game joiners. @@ -289,7 +294,7 @@ updateWeapon() if(!isDefined(weaponName) || weaponName == "none" || weaponName == "") return; variant = 0; - self takeAllWeapons(); // Strip any engine-assigned class weapons (race with spawn) + self takeAllWeapons(); if (isSubstr(weaponName, "_akimbo")) self giveWeapon(weaponName, variant, true); else diff --git a/mod/streaks.gsc b/mod/streaks.gsc index 7fc5775..3ab87f4 100755 --- a/mod/streaks.gsc +++ b/mod/streaks.gsc @@ -240,7 +240,11 @@ giveStreak(streak) self.moveSpeedScaler = 1.6; // keep cached baseline in sync (was: self.setMoveSpeedScale = 1.6 — typo, set entity field not call function) break; case "Riotshield": - self AttachShieldModel( "weapon_riot_shield_mp", "tag_shield_back" ); + if(!isDefined(self.hasBackShield) || !self.hasBackShield) + { + self AttachShieldModel( "weapon_riot_shield_mp", "tag_shield_back" ); + self.hasBackShield = true; + } break; case "Jetpack": self thread Jetpack(); -- 2.50.1