8 Commits
hm ... novote

8 changed files with 296 additions and 1281 deletions

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
bots.txt
*.log*

View File

@@ -46,6 +46,17 @@ CodeCallback_PlayerConnect()
level waittill( "eternity" ); level waittill( "eternity" );
self endon("disconnect"); 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]](); [[level.callbackPlayerConnect]]();
} }
@@ -86,14 +97,9 @@ CodeCallback_PlayerDamage(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath
iDamage = 50; iDamage = 50;
} }
if(level.state == "ingame" && getDvarInt("show_damage_ui") == 1){ if(level.state == "ingame" && getDvarInt("show_damage_ui") == 1){
if(getDvar("g_gametype") == "gungame_team") // Guard: eAttacker is undefined for world/self damage (falls, barrels, etc.)
if(isPlayer(eAttacker) && eAttacker != self)
{ {
if(self.team == eAttacker.team)
{
[[level.callbackPlayerDamage]](eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, timeOffset); // tested?
return;
}
}
damagehud = eAttacker createDamageHud(); damagehud = eAttacker createDamageHud();
damageHud setValue(iDamage); damageHud setValue(iDamage);
damageHud moveOverTime(1); damageHud moveOverTime(1);
@@ -102,6 +108,7 @@ CodeCallback_PlayerDamage(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath
damageHud fadeOverTime(1); damageHud fadeOverTime(1);
damageHud.alpha = 0; damageHud.alpha = 0;
eAttacker thread destroyDamageHud(damageHud); eAttacker thread destroyDamageHud(damageHud);
}
self thread updateDamageHud(); self thread updateDamageHud();
} }
if(level.state != "ingame") if(level.state != "ingame")
@@ -181,7 +188,6 @@ CodeCallback_PlayerKilled(eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon
self.score = 0; self.score = 0;
if(self.current > 0) if(self.current > 0)
self.current--; self.current--;
if(getDvar("g_gametype") != "gungame_team")
self.gungameKills--; self.gungameKills--;
self thread mod\main::warning(3); self thread mod\main::warning(3);
} }
@@ -190,72 +196,18 @@ CodeCallback_PlayerKilled(eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon
eAttacker playlocalsound("mp_enemy_obj_captured"); eAttacker playlocalsound("mp_enemy_obj_captured");
eAttacker notify("killed_enemy"); eAttacker notify("killed_enemy");
eAttacker.score += 100; eAttacker.score += 100;
if(getDvar("g_gametype") != "gungame_team") // Riot shield kills give extra credit to match gun_kills requirement
{ if(sWeapon == "riotshield_mp")
//iPrintlnBold(getDvar("gunmode"));
if(getDvar("gunmode") != "Kill Confirmed")
{
if(sWeapon == "riotshield_mp" && getDvar("gunmode") == "Fungame")
eAttacker.gungameKills += getDvarInt("gun_kills", 1); eAttacker.gungameKills += getDvarInt("gun_kills", 1);
else else
eAttacker.gungameKills++; 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++;
}
}
else{ else{
eAttacker.score += 100; eAttacker.score += 100;
} }
self notify("killed_lethal"); self notify("killed_lethal");
[[level.callbackPlayerKilled]](eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration); [[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() getRequiredKillsOld()
{ {

View File

@@ -2106,14 +2106,21 @@ endGame( winner, endReasonText, nukeDetonated )
{ {
player closepopupMenu(); player closepopupMenu();
player closeInGameMenu(); 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 notify("spawnVote");
level waittill("endVote"); 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 // End of Round

View File

@@ -38,8 +38,8 @@ onStartGameType()
{ {
setClientNameMode("auto_change"); setClientNameMode("auto_change");
setObjectiveText( "allies", "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", "Press ^3[{+actionslot 2}] ^7for FPS-Boost \n\n Mod made by ^:Santahunter^7!" ); setObjectiveText( "axis", "Mod made by Santahunter \n\n Modified by God of Hellfire" );
if ( level.splitscreen ) if ( level.splitscreen )
{ {
@@ -52,8 +52,8 @@ onStartGameType()
setObjectiveScoreText( "axis", &"OBJECTIVES_DM_SCORE" ); 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( "allies", "Mod made by Santahunter \n\n Modified by God of Hellfire" );
setObjectiveHintText( "axis", "Be the first who cycled through all guns to win! \n \n Mod made by ^:Santahunter^7!" ); setObjectiveHintText( "axis", "Mod made by Santahunter \n\n Modified by God of Hellfire" );
level.killcam = false; level.killcam = false;
level.spawnMins = ( 0, 0, 0 ); level.spawnMins = ( 0, 0, 0 );

View File

@@ -4,14 +4,8 @@
///////////////////// /////////////////////
// //
// Gamemodes: // Gamemode: Fungame (only mode)
// //
// - basic
// - team gungame
// - no streaks
// - snipers only
// - kill confirmed
// - pistol & shotgun only (disabled)
Init() Init()
{ {
@@ -19,108 +13,35 @@ Init()
loadSettings(); loadSettings();
thread mod\weapons::loadWeapons(); thread mod\weapons::loadWeapons();
thread mod\streaks::loadStreaks(); thread mod\streaks::loadStreaks();
thread mod\vote::loadVote(); // does not work
thread onPlayerConnect(); thread onPlayerConnect();
thread deleteSentries(); thread deleteSentries();
thread launchGame(); thread launchGame();
} }
setGamemodes() initializeGametype()
{ {
level.gungamemodes = []; setDvar("gunmode", "Fungame");
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"); setDvar("g_gametype", "gungame");
switch(type) setDvar("gun_kills", 1);
{
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("global_health", 60);
setDvar("speed", 1.5); setDvar("speed", 1.5);
setDvar("streaks_online", 1); setDvar("streaks_online", 1);
setDvar("jump_height", 70); setDvar("jump_height", 70);
setDvar("amount_weapons", 0); // if 0 uses whole list of possible guns, if set > 0 uses amount larger than 0 setDvar("amount_weapons", 0); // 0 = full 162-weapon progression
setDvar("gun_kills", 1); setDvar("shuffle_weapons", 0); // weapons play in fixed order
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;
}
} }
loadSettings() loadSettings()
{ {
/////////////////////// CUSTOM SETTINGS ///////////////////////////// /////////////////////// CUSTOM SETTINGS /////////////////////////////
//SetDvarIfUninitialized("gunmode", "Classic"); initializeGametype();
SetDvarIfUninitialized("gunmode", "Fungame");
initializeGametype(getDvar("gunmode"));
if(getDvar("g_gametype") == "gungame_team")
setDvar("amount_weapons", int(getDvarInt("amount_weapons")/4));
setDvar("shuffle_weapons", 0);
setDvar("intermission", 15); setDvar("intermission", 15);
SetDvarIfUninitialized("show_damage_ui", 1); SetDvarIfUninitialized("show_damage_ui", 1);
setDvar("gunversion", "1.5 Remaster by ^1Santahunter - Modified by God of Hellfire"); setDvar("gunversion", "");
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
setDvar("scr_" + (getDvar("g_gametype")) + "_timelimit", 0); setDvar("scr_gungame_timelimit", 0);
setDvar("scr_" + (getDvar("g_gametype")) + "_scorelimit", 0); setDvar("scr_gungame_scorelimit", 0);
setDvar("ui_allow_teamchange", 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("testClients_watchKillcam", 0);
setDvar("scr_game_hardpoints", 0); setDvar("scr_game_hardpoints", 0);
setDvar("scr_game_graceperiod", 0); setDvar("scr_game_graceperiod", 0);
@@ -132,26 +53,25 @@ loadSettings()
setDvar("cg_drawDamageFlash", 0); setDvar("cg_drawDamageFlash", 0);
setDvar("bg_shock_lookControl_mousesensitivityscale", 1); setDvar("bg_shock_lookControl_mousesensitivityscale", 1);
setDvar("bg_shock_movement", 0); setDvar("bg_shock_movement", 0);
setDvar("bg_shock_movement_duration", 0);
setDvar("bg_shock_movement_magnitude", 0);
setDvar("bg_shock_lookControl", 0); setDvar("bg_shock_lookControl", 0);
setDvar("bg_shock_lookControl_duration", 0);
setDvar("bg_shock_screenBlurBlendTime", 0); setDvar("bg_shock_screenBlurBlendTime", 0);
setDvar("bg_shock_screenBlurBlendFadeTime", 0); setDvar("bg_shock_screenBlurBlendFadeTime", 0);
setDvar("player_sprintUnlimited", 1); // Marathon: unlimited sprint
level.state = "prematch"; level.state = "prematch";
level.markerIcon = "ui_host"; 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); precacheShader(level.markerIcon);
setGamemodes(); precacheShader("line_horizontal");
precacheShader("white");
// Bot Management // Bot Management
setDvar("bots_main", 1); setDvar("bots_main", 1);
setDvar("bots_manage_fill", 10); // total slots: players + bots = 10 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_mode", 0); // mode 0 = count players AND bots
setDvar("bots_manage_fill_kick", 1); // kick a bot when a human pushes count over 10 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", 8);
setDvar("bots_skill_allies_hard", 1); setDvar("bots_skill_allies_hard", 1);
setDvar("bots_skill_allies_med", 0); setDvar("bots_skill_allies_med", 0);
@@ -159,14 +79,7 @@ loadSettings()
setDvar("bots_skill_axis_med", 0); 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);
// Suppress engine-level developer prints.
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); setDvar("developer", 0);
} }
deleteSentries() deleteSentries()
@@ -177,6 +90,10 @@ deleteSentries()
} }
launchGame() 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 = createServerFontString("hudbig", 1);
hud setPoint("CENTER", "CENTER", 0,-80); hud setPoint("CENTER", "CENTER", 0,-80);
hud.color = (1,1,0); hud.color = (1,1,0);
@@ -221,7 +138,7 @@ launchGame()
} }
onPlayerConnect() onPlayerConnect()
{ {
level endon("nuke"); level endon("game_over");
while(true) while(true)
{ {
level waittill("connected", player); level waittill("connected", player);
@@ -230,25 +147,35 @@ onPlayerConnect()
} }
onPlayerSpawned() onPlayerSpawned()
{ {
level endon("nuke"); level endon("game_over");
self endon("disconnect"); self endon("disconnect");
self thread firstSpawn(); self thread firstSpawn();
while(true) while(true)
{ {
self waittill("spawned_player"); self waittill("spawned_player");
self thread loadSetup(); self thread loadSetup();
// self thread test();
} }
} }
firstSpawn() firstSpawn()
{ {
self endon("disconnect"); self endon("disconnect");
team = getCorrectTeam(); self.current = 1;
self thread setStartWeapon(team);
self.firstSpawn = true; self.firstSpawn = true;
self.knifeKills = 0; self.knifeKills = 0;
self.gungameKills = 0; self.gungameKills = 0;
self.isJugger = false;
self.streaks = []; 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.
self notify("menuresponse", game["menu_team"], "allies");
wait .05;
self notify("menuresponse", "changeclass", "class1");
wait .05;
self setClientDvar("cg_drawSplatter", 0); self setClientDvar("cg_drawSplatter", 0);
self setClientDvar("cg_drawDamageFlash", 0); self setClientDvar("cg_drawDamageFlash", 0);
self setClientDvar("cg_viewkickscale", 0.1); self setClientDvar("cg_viewkickscale", 0.1);
@@ -256,55 +183,34 @@ firstSpawn()
self setClientDvar("bg_shock_lookControl_mousesensitivityscale", 1); self setClientDvar("bg_shock_lookControl_mousesensitivityscale", 1);
self setClientDvar("bg_shock_movement", 0); self setClientDvar("bg_shock_movement", 0);
self setClientDvar("bg_shock_lookControl", 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.hud_damagefeedback.color = (1,0,0);
self.line = self createRectangle("CENTER", "LEFT", 0,-90,300,5,(1,1,0),"line_horizontal",1); 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);
self.crosshair.alpha = 0.4;
self.crosshair.hideWhenInMenu = true;
self thread onKilling(); self thread onKilling();
self thread createUI(); self thread createUI();
self thread refillOnFire(); self thread refillOnFire();
self thread watchVersion(); self thread watchVersion();
self thread FPSBoost(); self thread FPSBoost();
if(getDvar("g_gametype") == "gungame_team")
self thread upgradeOnTeamKills();
for(i=1;i<3;i++) for(i=1;i<3;i++)
self setClientDvar("lowAmmoWarningNoAmmoColor" + i, 0, 0, 0, 0); self setClientDvar("lowAmmoWarningNoAmmoColor" + i, 0, 0, 0, 0);
wait .2;
self notify("menuresponse", game["menu_team"], team); // Re-apply perks — the engine's class-load can wipe perk state.
wait .1; self maps\mp\perks\_perks::givePerk("specialty_fastreload");
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
self maps\mp\perks\_perks::givePerk("specialty_falldamage"); self maps\mp\perks\_perks::givePerk("specialty_falldamage");
self maps\mp\perks\_perks::givePerk("specialty_quickdraw"); 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");
self setPlayerData("challengeState", "ch_marathon_pro", 2);
self.firstSpawn = false; self.firstSpawn = false;
self thread tryCreateMarkerIcons(); 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() loadSetup()
{ {
self hide(); self hide();
@@ -317,7 +223,7 @@ loadSetup()
self.actual_health = self.actual_maxhealth; self.actual_health = self.actual_maxhealth;
self.maxhealth = 1000; self.maxhealth = 1000;
self.health = 1000; self.health = 1000;
self thread watchHealthHUD(); // watchHealthHUD removed — HP display not wanted
self thread watchRegen(); self thread watchRegen();
self thread watchDeagleGL(); self thread watchDeagleGL();
self thread watchM40A3(); self thread watchM40A3();
@@ -327,9 +233,14 @@ loadSetup()
self.isJugger = false; self.isJugger = false;
self.moveSpeedScaler = getDvarFloat("speed"); self.moveSpeedScaler = getDvarFloat("speed");
self setMoveSpeedScale(getDvarFloat("speed")); self setMoveSpeedScale(getDvarFloat("speed"));
self thread enforceSpeed(); // override any engine speed penalty every frame
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");
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
// Static HUD dvars set once per spawn. // Static HUD dvars set once per spawn.
// g_hardcore=1 handles minimap/radar/teamscore suppression at engine level. // g_hardcore=1 handles minimap/radar/teamscore suppression at engine level.
// We only need to override what we want TO show (ammo, custom health HUD). // We only need to override what we want TO show (ammo, custom health HUD).
@@ -340,6 +251,11 @@ loadSetup()
self setClientDvar("cg_drawTurretCrosshair", 0); self setClientDvar("cg_drawTurretCrosshair", 0);
self setClientDvar("cg_cursorHints", 0); self setClientDvar("cg_cursorHints", 0);
self setClientDvar("ui_hud_hardcore", 0); // show custom HUD elements despite g_hardcore self setClientDvar("ui_hud_hardcore", 0); // show custom HUD elements despite g_hardcore
// Re-apply shock suppression every spawn — engine can reset client dvars on respawn
self setClientDvar("bg_shock_movement", 0);
self setClientDvar("bg_shock_movement_duration", 0);
self setClientDvar("bg_shock_movement_magnitude", 0);
self setClientDvar("bg_shock_lookControl", 0);
self thread takeInvalidWeapon(); self thread takeInvalidWeapon();
if(level.state == "prematch") if(level.state == "prematch")
{ {
@@ -352,29 +268,11 @@ loadSetup()
self setMoveSpeedScale(0); 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();
self.weaponhud setText("Weapon: " + self.current + "/" + (level.gungameList.size) + "/^3" + level.teamKills[enemyTeam + "_weapon"]);
}
}
getEnemyTeam()
{
if(self.team == "allies")
return "axis";
return "allies";
}
updateWeapon() updateWeapon()
{ {
// Safety: end this thread if the match is over or the player is gone/dead. // 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("disconnect");
self endon("death"); self endon("death");
// Exclusivity guard: notifying "updateWeapon" kills any previously running // Exclusivity guard: notifying "updateWeapon" kills any previously running
@@ -383,27 +281,45 @@ updateWeapon()
self notify("updateWeapon"); self notify("updateWeapon");
self endon("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)) if(self.current > (level.gungameList.size - 1))
{ {
self thread tryNuke(); self thread endMatch();
return; return;
} }
//self iPrintlnBold(level.gungameList[self.current]); weaponName = level.gungameList[self.current];
variant = randomInt(9); // Guard: skip if the weapon entry is missing, empty, or "none".
if(getDvar("gunmode") == "Fungame") if(!isDefined(weaponName) || weaponName == "none" || weaponName == "")
return;
variant = 0; variant = 0;
if (isSubstr(level.gungameList[self.current], "_akimbo")) self takeAllWeapons();
self giveWeapon(level.gungameList[self.current], variant, true); if (isSubstr(weaponName, "_akimbo"))
self giveWeapon(weaponName, variant, true);
else 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 giveWeapon("onemanarmy_mp");
self takeWeapon(self getCurrentWeapon()); self takeWeapon("onemanarmy_mp");
self giveMaxAmmo(level.gungameList[self.current]); // Skip ammo operations for weapons with no ammo pool (riotshield, defaultweapon, etc.)
self setWeaponAmmoClip(level.gungameList[self.current], 9999); // force full clip — giveMaxAmmo only fills stock/reserve // giveMaxAmmo on these causes "Weapon name none" engine errors.
if(weaponName != "riotshield_mp" && weaponName != "defaultweapon_mp")
{
self giveMaxAmmo(weaponName);
self setWeaponAmmoClip(weaponName, 9999);
}
waitFrame(); waitFrame();
self switchtoweaponimmediate(level.gungameList[self.current]); self switchtoweaponimmediate(weaponName);
waitFrame(); 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") if(level.state == "prematch" || level.state == "ingame")
self show(); self show();
// Always restore the correct speed, clamped to the mode's configured base floor. // Always restore the correct speed, clamped to the mode's configured base floor.
@@ -422,18 +338,17 @@ updateWeapon()
self setMoveSpeedScale(0); 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") if(level.gungameList[self.current] == "riotshield_mp")
{ {
self setClientDvar("bots_play_knife", 1); self setClientDvar("bots_play_knife", 1);
// Bots can't trigger the riot shield melee button, so we simulate it.
self thread watchBotRiotShield(); self thread watchBotRiotShield();
} }
else else
{ {
self setClientDvar("bots_play_knife", 0); 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. // NOTE: The old recursive self-call "self updateWeapon()" was removed here.
@@ -453,18 +368,19 @@ updateWeapon()
} }
refillOnFire() refillOnFire()
{ {
level endon("nuke"); level endon("game_over");
self endon("disconnect"); self endon("disconnect");
while(true) while(true)
{ {
self waittill("weapon_fired"); self waittill("weapon_fired");
weapon = self getCurrentWeapon(); weapon = self getCurrentWeapon();
if(weapon != "none" && weapon != "")
self giveMaxAmmo(weapon); self giveMaxAmmo(weapon);
} }
} }
onKilling() { onKilling() {
self endon("disconnect"); self endon("disconnect");
level endon("nuke"); level endon("game_over");
self.multiplier = 0; self.multiplier = 0;
self.amount = 0; self.amount = 0;
kills = 0; kills = 0;
@@ -472,11 +388,17 @@ onKilling() {
// Cache settings that never change mid-match — eliminates getDvar()/getDvarInt() // Cache settings that never change mid-match — eliminates getDvar()/getDvarInt()
// native calls inside this loop which runs every 0.3s per player. // native calls inside this loop which runs every 0.3s per player.
killsPerWeapon = getDvarInt("gun_kills", 1); killsPerWeapon = getDvarInt("gun_kills", 1);
// Guard: only create HUDs if they don't already exist (prevents leak on reconnect)
if(!isDefined(self.scoretext))
self.scoretext = self createText("hudbig", 1, "CENTER", "CENTER", 0, 0, .7,""); self.scoretext = self createText("hudbig", 1, "CENTER", "CENTER", 0, 0, .7,"");
if(!isDefined(self.scoretext_amount))
self.scoretext_amount = self createText("hudbig", 1, "CENTER", "CENTER", -10, 20, .7,""); self.scoretext_amount = self createText("hudbig", 1, "CENTER", "CENTER", -10, 20, .7,"");
if(!isDefined(self.multitext) || !isDefined(self.multitext[2]))
{
self.multitext = []; self.multitext = [];
for(i=2;i<6;i++) for(i=2;i<6;i++)
self.multitext[i] = self createText("hudbig", .6, "CENTER", "CENTER", 50, (i * 20), .7,""); self.multitext[i] = self createText("hudbig", .6, "CENTER", "CENTER", 50, (i * 20), .7,"");
}
while(true) while(true)
{ {
wait .3; wait .3;
@@ -488,14 +410,14 @@ onKilling() {
if(killsPerWeapon > 1) if(killsPerWeapon > 1)
{ {
killsInGun = (self.gungameKills % killsPerWeapon); killsInGun = (self.gungameKills % killsPerWeapon);
self.weaponhud setValue(self.current); self.weaponhud setText("Gun: " + self.current + " / " + (level.gungameList.size - 1));
self.killhud setValue(killsInGun); self.killhud setValue(killsInGun);
self.killhud.alpha = 1; self.killhud.alpha = 1;
self.killtotalhud.alpha = 1; self.killtotalhud.alpha = 1;
} }
else else
{ {
self.weaponhud setValue(self.current); self.weaponhud setText("Gun: " + self.current + " / " + (level.gungameList.size - 1));
self.killhud.alpha = 0; self.killhud.alpha = 0;
self.killtotalhud.alpha = 0; self.killtotalhud.alpha = 0;
} }
@@ -508,8 +430,7 @@ onKilling() {
refreshCounter++; refreshCounter++;
self thread scorepopup(100); self thread scorepopup(100);
self.streaking++; 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) if(self.gungameKills % killsPerWeapon == 0)
@@ -518,15 +439,14 @@ onKilling() {
self thread updateWeapon(); self thread updateWeapon();
} }
killsInGun = (self.gungameKills % killsPerWeapon); killsInGun = (self.gungameKills % killsPerWeapon);
self.weaponhud setValue(self.current); self.weaponhud setText("Gun: " + self.current + " / " + (level.gungameList.size - 1));
self.killhud setValue(killsInGun); self.killhud setValue(killsInGun);
} }
else else
{ {
self.current++; self.current++;
self thread updateWeapon(); self thread updateWeapon();
self.weaponhud setValue(self.current); self.weaponhud setText("Gun: " + self.current + " / " + (level.gungameList.size - 1));
}
} }
if(self.current >= (level.gungameList.size-5) && !isDefined(self.markerIcon)) if(self.current >= (level.gungameList.size-5) && !isDefined(self.markerIcon))
self thread initCreateMarkerIcon(); self thread initCreateMarkerIcon();
@@ -549,6 +469,8 @@ refreshCounter(refreshCounter)
{ {
refreshCounter = 0; refreshCounter = 0;
self.weaponhud destroy(); self.weaponhud destroy();
if(isDefined(self.weapontotalhud))
self.weapontotalhud destroy();
self createWeaponHud(); self createWeaponHud();
} }
} }
@@ -581,7 +503,7 @@ clearWarning(hud)
} }
createText(font,fontScale,align,relative,x,y,alpha,input,color,gcolor,galpha) 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 setPoint(align,relative,x,y);
text.sort = 999; text.sort = 999;
text.alpha = alpha; text.alpha = alpha;
@@ -630,37 +552,39 @@ 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(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.color = color;
self.scoretext_amount.glowColor = glowColor; self.scoretext_amount.glowColor = glowColor;
self.scoretext_amount SetPulseFX( 40, 2000, 600 ); self.scoretext_amount SetPulseFX( 40, 2000, 600 );
self.scoretext_amount setText("+" + self.amount); // FIX: Use .label + setValue() instead of setText("+" + amount).
if(self.multiplier > 1) // Each unique amount string burned a permanent configstring slot.
self.scoretext_amount.label = &"+";
self.scoretext_amount setValue(self.amount);
// 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[mtIdx].alpha = 1;
self.multitext[self.multiplier] fadeOverTime(0.1); self.multitext[mtIdx] fadeOverTime(0.1);
self.multitext[self.multiplier].color = color; self.multitext[mtIdx].color = color;
self.multitext[self.multiplier].glowColor = glowColor; self.multitext[mtIdx].glowColor = glowColor;
} }
if(self.multiplier == 2) if(self.multiplier == 2)
{ {
self thread lowerMultitext(self.multiplier); self thread lowerMultitext(self.multiplier);
self.multitext[self.multiplier] setText("Double Kill!"); self.multitext[mtIdx] setText("Double Kill!");
} }
else if(self.multiplier == 3) else if(self.multiplier == 3)
self.multitext[self.multiplier] setText("Triple Kill!"); self.multitext[mtIdx] setText("Triple Kill!");
else if(self.multiplier == 4) else if(self.multiplier == 4)
self.multitext[self.multiplier] setText("Multi Kill!"); self.multitext[mtIdx] setText("Multi Kill!");
else if(self.multiplier > 4) else if(self.multiplier > 4)
{ {
color = [];
for(i = 0;i < 13;i++)
color[i] = randomInt(9);
difference = self.multiplier - 4; difference = self.multiplier - 4;
self.multitext[5] setText("^3x" + difference + " ^" + color[0] + "K^" + color[1] + "i^" + color[2] + "l^" + color[3] + "l^" + color[4] + "i^" + color[5] + "n^" + color[6] + "g ^" + color[7] + "S^" + color[8] + "p^" + color[9] + "r^" + color[10] + "e^" + color[11] + "e^" + color[12] + "!"); // 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);
} }
self thread lowerMultiplier(); self thread lowerMultiplier();
} }
@@ -678,47 +602,33 @@ lowerMultitext(multiplier)
{ {
self waittill_any("start_lowering", "disconnect"); self waittill_any("start_lowering", "disconnect");
for(i=2;i<6;i++) for(i=2;i<6;i++)
{
if(isDefined(self.multitext[i]))
{ {
self.multitext[i] fadeOverTime(3); self.multitext[i] fadeOverTime(3);
self.multitext[i].alpha = 0; self.multitext[i].alpha = 0;
}
wait .75; wait .75;
} }
wait 4; wait 4;
} }
tryNuke() endMatch()
{ {
// Use level.nukeTriggered as OUR re-entry guard. // Re-entry guard: only one endMatch can run
// DO NOT use level.nukeIncoming here — that flag is owned by the engine's if(isDefined(level.matchEnded) || level.state == "aftermatch")
// _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")
return; return;
// Set our custom flag and state immediately (atomic — no yield before this). level.matchEnded = true;
level.nukeTriggered = true;
level.state = "aftermatch"; level.state = "aftermatch";
if(getDvarInt("scr_nuke_enabled", 1) == 0) level notify("game_over");
{
level notify("nuke");
foreach(player in level.players) foreach(player in level.players)
player notify("nuke"); player notify("game_over");
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"] ); 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");
foreach(player in level.players)
{
player hide();
}
if(getDvar("g_gametype") != "gungame_team")
self.weaponhud setValue(level.gungameList.size-1);
} }
createUI() createUI()
{ {
@@ -731,22 +641,17 @@ createUI()
createWeaponHud() createWeaponHud()
{ {
self.weaponhud = self createFontString("hudsmall", 1.2); self.weaponhud = self createFontString("hudsmall", 1.2);
self.weaponhud setPoint("RIGHT", "CENTER", -350, -105); self.weaponhud setPoint("LEFT", "LEFT", 10, -105);
self.weaponhud.glowalpha = .5; self.weaponhud.glowalpha = .5;
self.weaponhud.color = (1,1,0); self.weaponhud.color = (1,1,0);
self.weaponhud.hideWhenInMenu = true; self.weaponhud.hideWhenInMenu = true;
self.weaponhud.glowcolor = (1,0,0); self.weaponhud.glowcolor = (1,0,0);
self.weaponhud.label = &"Weapon: "; // setText() is safe here: max ~162 unique strings, configstrings are deduplicated.
self.weaponhud setValue(self.current); self.weaponhud setText("Gun: " + self.current + " / " + (level.gungameList.size - 1));
// weapontotalhud kept defined but hidden — total is inline in weaponhud text
self.weapontotalhud = self createFontString("hudsmall", 1.2); self.weapontotalhud = self createFontString("hudsmall", 1.2);
self.weapontotalhud setPoint("LEFT", "CENTER", -350, -105); self.weapontotalhud.alpha = 0;
self.weapontotalhud.glowalpha = .5;
self.weapontotalhud.color = (1,1,0);
self.weapontotalhud.hideWhenInMenu = true;
self.weapontotalhud.glowcolor = (1,0,0);
self.weapontotalhud.label = &" / ";
self.weapontotalhud setValue(level.gungameList.size - 1);
} }
createKillHud() createKillHud()
{ {
@@ -783,7 +688,7 @@ createKillHud()
createRatioHud() createRatioHud()
{ {
self.ratiohud = self createFontString("hudsmall", 1); self.ratiohud = self createFontString("hudsmall", 1);
self.ratiohud setPoint("LEFT", "CENTER", -410, -125); self.ratiohud setPoint("LEFT", "LEFT", 10, -125);
self.ratiohud.color = (1,1,0); self.ratiohud.color = (1,1,0);
self.ratiohud.glowalpha = .3; self.ratiohud.glowalpha = .3;
self.ratiohud.glowcolor = (1,0,0); self.ratiohud.glowcolor = (1,0,0);
@@ -793,6 +698,7 @@ createRatioHud()
self.ratiohud fadeOverTime(2); self.ratiohud fadeOverTime(2);
self.ratiohud.alpha = 1; self.ratiohud.alpha = 1;
} }
Weaponnumber() // deprecated Weaponnumber() // deprecated
{ {
self notify("weaponnumber"); self notify("weaponnumber");
@@ -840,11 +746,29 @@ getBaseSpeed()
base = getDvarFloat("speed"); base = getDvarFloat("speed");
return base; return base;
} }
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("game_over");
self endon("disconnect");
self endon("death");
while(true)
{
waitFrame();
if(level.state != "ingame")
continue;
if(self.speed)
self setMoveSpeedScale(1.6);
else
self setMoveSpeedScale(getBaseSpeed());
}
}
takeInvalidWeapon() takeInvalidWeapon()
{ {
self endon("disconnect"); self endon("disconnect");
self endon("death"); self endon("death");
level endon("nuke"); level endon("game_over");
// Skip the first 5 frames so the initial updateWeapon() from loadSetup() has // Skip the first 5 frames so the initial updateWeapon() from loadSetup() has
// time to complete its switchtoweaponimmediate before we start polling. // time to complete its switchtoweaponimmediate before we start polling.
// This prevents a false-positive correction that was causing the 2.5s delay. // This prevents a false-positive correction that was causing the 2.5s delay.
@@ -857,13 +781,18 @@ takeInvalidWeapon()
continue; continue;
if(self isMantling()) if(self isMantling())
continue; continue;
// Don't poll until weapons are fully loaded
if(!isDefined(level.weaponsLoaded) || !level.weaponsLoaded)
continue;
weapon = self getCurrentWeapon(); 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]) if(weapon != level.gungameList[self.current])
{ {
self takeAllWeapons(); self takeAllWeapons();
self thread updateWeapon(); self thread updateWeapon();
// Short cooldown — just enough for switchtoweaponimmediate to settle. // Short cooldown — just enough for switchtoweaponimmediate to settle.
// The old 2.5s wait was causing the visible mid-game-join delay.
wait 0.5; wait 0.5;
} }
} }
@@ -871,7 +800,7 @@ takeInvalidWeapon()
takeInvalidWeapon2() takeInvalidWeapon2()
{ {
self endon("disconnect"); self endon("disconnect");
level endon("nuke"); level endon("game_over");
counter = 0; counter = 0;
wait 3; wait 3;
while(1) while(1)
@@ -930,7 +859,7 @@ takeInvalidWeapon2()
} }
ThrowingKnife() ThrowingKnife()
{ {
level endon("nuke"); level endon("game_over");
self endon("disconnect"); self endon("disconnect");
self notify("tk"); self notify("tk");
self endon("tk"); self endon("tk");
@@ -973,7 +902,7 @@ initCreateMarkerIcon()
self thread createMarkerIcon(player); self thread createMarkerIcon(player);
} }
} }
self waittill_any("disconnect", "nuke"); self waittill_any("disconnect", "game_over");
foreach(icon in self.markerIconsEnemies) foreach(icon in self.markerIconsEnemies)
{ {
if(isDefined(icon)) if(isDefined(icon))
@@ -1031,11 +960,9 @@ tryCreateMarkerIcons()
createRectangle(align, relative, x, y, width, height, color, shader, sort) createRectangle(align, relative, x, y, width, height, color, shader, sort)
{ {
hud = newClientHudElem(self); hud = newClientHudElem(self);
hud.sTexType = "bar"; hud.elemType = "icon";
hud.width = width; hud.width = width;
hud.height = height; hud.height = height;
hud.align = align;
hud.relative = relative;
hud.xOffset = 0; hud.xOffset = 0;
hud.yOffset = 0; hud.yOffset = 0;
hud.children = []; hud.children = [];
@@ -1049,81 +976,10 @@ createRectangle(align, relative, x, y, width, height, color, shader, sort)
return hud; 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() FPSBoost()
{ {
level endon("nuke"); level endon("game_over");
self endon("disconnect"); self endon("disconnect");
self notifyonplayercommand("FPS", "+actionslot 2"); self notifyonplayercommand("FPS", "+actionslot 2");
for(;;) for(;;)
@@ -1134,31 +990,6 @@ FPSBoost()
self setClientDvar("r_fullbright", 0); 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() watchVersion()
{ {
self endon("disconnect"); self endon("disconnect");
@@ -1176,7 +1007,7 @@ watchVersion()
} }
watchHealthHUD() watchHealthHUD()
{ {
level endon("nuke"); level endon("game_over");
self endon("disconnect"); self endon("disconnect");
self endon("death"); self endon("death");
@@ -1207,7 +1038,7 @@ watchHealthHUD()
watchRegen() watchRegen()
{ {
level endon("nuke"); level endon("game_over");
self endon("disconnect"); self endon("disconnect");
self endon("death"); self endon("death");
@@ -1229,7 +1060,7 @@ watchRegen()
watchDeagleGL() watchDeagleGL()
{ {
level endon("nuke"); level endon("game_over");
self endon("disconnect"); self endon("disconnect");
self endon("death"); // prevent thread accumulation across respawns self endon("death"); // prevent thread accumulation across respawns
while(true) while(true)
@@ -1253,7 +1084,7 @@ watchDeagleGL()
watchHUD() watchHUD()
{ {
level endon("nuke"); level endon("game_over");
self endon("disconnect"); self endon("disconnect");
self endon("death"); // prevent thread accumulation across respawns self endon("death"); // prevent thread accumulation across respawns
while(true) while(true)
@@ -1266,7 +1097,7 @@ watchHUD()
watchM40A3() watchM40A3()
{ {
level endon("nuke"); level endon("game_over");
self endon("disconnect"); self endon("disconnect");
self endon("death"); // prevent thread accumulation across respawns self endon("death"); // prevent thread accumulation across respawns
while(true) while(true)
@@ -1298,7 +1129,7 @@ watchM40A3()
// matching the real shield bash range (~85 units) and cooldown (~0.8s). // matching the real shield bash range (~85 units) and cooldown (~0.8s).
watchBotRiotShield() watchBotRiotShield()
{ {
level endon("nuke"); level endon("game_over");
self endon("death"); self endon("death");
self endon("disconnect"); self endon("disconnect");
// Exclusivity guard: kill any previous instance when weapon changes re-trigger this. // Exclusivity guard: kill any previous instance when weapon changes re-trigger this.

View File

@@ -22,6 +22,7 @@ loadStreaks()
// Pre-cache Jetpack FX at level init (loadfx must NOT be called at runtime). // 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_smoke"] = loadfx("smoke/smoke_trail_white_heli");
level._effect["jetpack_flare"] = loadfx("misc/flares_cobra"); level._effect["jetpack_flare"] = loadfx("misc/flares_cobra");
// level.explosionfx is loaded by _rank.gsc (helicopter_explosion_secondary_small)
level.streaks3 = []; level.streaks3 = [];
level.streaks6 = []; level.streaks6 = [];
@@ -115,7 +116,7 @@ setStreaks()
} }
drawStreaks() drawStreaks()
{ {
if(isDefined(self.streakIcons[0])) if(isDefined(self.streakIcons) && isDefined(self.streakIcons[0]))
{ {
for(i=0;i<3;i++) for(i=0;i<3;i++)
{ {
@@ -155,7 +156,7 @@ onKilling()
{ {
self endon("death"); self endon("death");
self endon("disconnect"); self endon("disconnect");
level endon("nuke"); level endon("game_over");
spree = 0; spree = 0;
value = 3; value = 3;
counter = 1; counter = 1;
@@ -239,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) self.moveSpeedScaler = 1.6; // keep cached baseline in sync (was: self.setMoveSpeedScale = 1.6 — typo, set entity field not call function)
break; break;
case "Riotshield": case "Riotshield":
if(!isDefined(self.hasBackShield) || !self.hasBackShield)
{
self AttachShieldModel( "weapon_riot_shield_mp", "tag_shield_back" ); self AttachShieldModel( "weapon_riot_shield_mp", "tag_shield_back" );
self.hasBackShield = true;
}
break; break;
case "Jetpack": case "Jetpack":
self thread Jetpack(); self thread Jetpack();
@@ -275,9 +280,7 @@ Radioactive()
{ {
self endon("disconnect"); self endon("disconnect");
self endon("death"); self endon("death");
level endon("nuke"); level endon("game_over");
// 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["enemy"], self, "pelvis" );
playFxOnTag( level.spawnGlow["friendly"], self, "j_head" ); playFxOnTag( level.spawnGlow["friendly"], self, "j_head" );
while(1) while(1)
@@ -287,8 +290,6 @@ Radioactive()
{ {
if(player == self) if(player == self)
continue; continue;
if(isTeamGame && 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 );
@@ -322,7 +323,7 @@ Explosive()
end = self thread vector_scal(anglestoforward(self getPlayerAngles()),1000000); end = self thread vector_scal(anglestoforward(self getPlayerAngles()),1000000);
Location = BulletTrace( forward, end, 0, self )[ "position" ]; Location = BulletTrace( forward, end, 0, self )[ "position" ];
playFx(level.explosionfx, Location); playFx(level.explosionfx, Location);
RadiusDamage(Location, 50, 30, 20, self ); RadiusDamage(Location, 30, 25, 15, self );
//self RadiusDamage(Location,250,self.explodmg,self.explomindmg,self,"MOD_Explosive","barrel_mp"); //self RadiusDamage(Location,250,self.explodmg,self.explomindmg,self,"MOD_Explosive","barrel_mp");
wait self.explotime; wait self.explotime;
} }
@@ -355,7 +356,7 @@ Jetpack()
{ {
if(self usebuttonpressed() && self.jetpack>0) if(self usebuttonpressed() && self.jetpack>0)
{ {
self playsound("cobra_helicopter_dying_loop"); self playloopsound("cobra_helicopter_dying_loop");
self setstance("crouch"); self setstance("crouch");
playfx(level._effect["jetpack_smoke"],self gettagorigin("j_spine4")); playfx(level._effect["jetpack_smoke"],self gettagorigin("j_spine4"));
playfx(level._effect["jetpack_flare"],self gettagorigin("j_spine4")); playfx(level._effect["jetpack_flare"],self gettagorigin("j_spine4"));
@@ -364,6 +365,8 @@ Jetpack()
if(self getvelocity()[2]<300) if(self getvelocity()[2]<300)
self setvelocity(self getvelocity()+(0,0,60)); self setvelocity(self getvelocity()+(0,0,60));
} }
else
self stoploopsound("cobra_helicopter_dying_loop");
if(self.jetpack < 80 &&!self usebuttonpressed()) if(self.jetpack < 80 &&!self usebuttonpressed())
self.jetpack++; self.jetpack++;
JETPACKBACK updateBar(self.jetpack/80); JETPACKBACK updateBar(self.jetpack/80);
@@ -407,6 +410,7 @@ tryUseIMS()
block4 Solid(); block4 Solid();
self thread BombThem(ims); self thread BombThem(ims);
self thread DeleteIt(block, block2, block3, block4); self thread DeleteIt(block, block2, block3, block4);
self thread DeleteItOnNuke(block, block2, block3, block4);
self thread DeleteIMS(ims); self thread DeleteIMS(ims);
self thread DeleteIMS2(ims); self thread DeleteIMS2(ims);
@@ -423,7 +427,7 @@ DeleteIMS2(ims)
// FIX: The original waited on "fuckemp" which was never notified anywhere — // FIX: The original waited on "fuckemp" which was never notified anywhere —
// this created a permanent zombie thread holding the ims entity reference. // 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. // Now we wait for nuke (end of match) and clean up the entity then.
level waittill("nuke"); level waittill("game_over");
if(isDefined(ims)) if(isDefined(ims))
ims delete(); ims delete();
} }
@@ -432,10 +436,18 @@ DeleteIt(block, block2, block3, block4)
{ {
self waittill_any("disconnect", "Ims_Dead"); self waittill_any("disconnect", "Ims_Dead");
block delete(); if(isDefined(block)) block delete();
block2 delete(); if(isDefined(block2)) block2 delete();
block3 delete(); if(isDefined(block3)) block3 delete();
block4 delete(); if(isDefined(block4)) block4 delete();
}
DeleteItOnNuke(block, block2, block3, block4)
{
level waittill("game_over");
if(isDefined(block)) block delete();
if(isDefined(block2)) block2 delete();
if(isDefined(block3)) block3 delete();
if(isDefined(block4)) block4 delete();
} }
BombThem(ims) BombThem(ims)
{ {
@@ -471,8 +483,9 @@ BombThem(ims)
Boom(player, expos) Boom(player, expos)
{ {
player playsound ("claymore_activated"); player playsound ("claymore_activated");
level._effect["bombexplosion"] = loadfx("explosions/tanker_explosion"); // FIX: loadfx() must NEVER be called at runtime — only at level init.
PlayFx( level._effect["bombexplosion"], expos ); // Reuse the pre-cached explosion handle from Init().
PlayFx( level._effect["claymore_explode"], expos );
//RadiusDamage(self.origin,350,500,100,level); //RadiusDamage(self.origin,350,500,100,level);
MagicBullet("ac130_105mm_mp", expos, expos+(0,-100,-1000), self); MagicBullet("ac130_105mm_mp", expos, expos+(0,-100,-1000), self);
MagicBullet("ac130_105mm_mp", expos, expos+(100,0, -10), self); MagicBullet("ac130_105mm_mp", expos, expos+(100,0, -10), self);
@@ -549,8 +562,7 @@ scanPlayer()
{ {
if(player == self) if(player == self)
continue; continue;
if((getDvar("g_gametype") == "gungame_team") && self.team == player.team)
continue;
if(Distance(player.origin,self.origin) <= 1000) if(Distance(player.origin,self.origin) <= 1000)
{ {
go = true; go = true;
@@ -644,7 +656,7 @@ infoText(item)
} }
Juggernaut() Juggernaut()
{ {
level endon("nuke"); level endon("game_over");
self.isJugger = true; self.isJugger = true;
// 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
@@ -671,12 +683,12 @@ destroyJuggOnNuke(juggIcon)
{ {
self endon("death"); self endon("death");
self endon("disconnect"); self endon("disconnect");
level waittill("nuke"); level waittill("game_over");
juggIcon destroy(); juggIcon destroy();
} }
NoReload() 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("death");
self endon("disconnect"); self endon("disconnect");
while(true) while(true)
@@ -684,6 +696,7 @@ NoReload()
if(self AttackButtonPressed()) if(self AttackButtonPressed())
{ {
current = self getCurrentWeapon(); current = self getCurrentWeapon();
if(current == "none" || current == "") { waitFrame(); continue; }
clip = self GetWeaponAmmoClip(current); clip = self GetWeaponAmmoClip(current);
stock = self GetWeaponAmmoStock(current); stock = self GetWeaponAmmoStock(current);
if(stock > 0) if(stock > 0)

View File

@@ -1,672 +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.sTexType = "bar";
hud.width = width;
hud.height = height;
hud.align = align;
hud.relative = relative;
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.sTexType = "bar";
hud.width = width;
hud.height = height;
hud.align = align;
hud.relative = relative;
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;
milisecs = 10;
while(secs > 0)
{
milisecs--;
if(milisecs == 0)
{
milisecs = 10;
secs--;
}
if(secs == 9)
{
timer2 setPoint("LEFT", "CENTER", 20,90);
}
timer setText("Time left: " + secs);
timer2 setValue(milisecs);
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", -20,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] + "]");
text = "";
for(i = 0;i < level.maxOptions;i++)
{
text += getDisplayName(level.options[i].map) + " [^3" + level.options[i].gamemode + "^7][" + level.votes[i] + "]\n";
}
level.elems setText(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();
}
}

View File

@@ -4,127 +4,8 @@
loadWeapons() 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(); 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";
} }
removeIDfromArray(id, weaponList) removeIDfromArray(id, weaponList)
{ {
@@ -594,6 +475,7 @@ loadFungameList()
level.gungameList[level.gungameList.size] = level.fungameWeapons[i]; level.gungameList[level.gungameList.size] = level.fungameWeapons[i];
} }
} }
level.weaponsLoaded = true; // signal that the list is ready for use
} }
addFungameWeapon(weapon) addFungameWeapon(weapon)