961 lines
30 KiB
Plaintext
961 lines
30 KiB
Plaintext
#using scripts\shared\array_shared;
|
|
#using scripts\shared\callbacks_shared;
|
|
#using scripts\shared\clientfield_shared;
|
|
#using scripts\shared\flag_shared;
|
|
#using scripts\shared\flagsys_shared;
|
|
#using scripts\shared\hud_util_shared;
|
|
#using scripts\shared\lui_shared;
|
|
#using scripts\shared\scene_shared;
|
|
#using scripts\shared\string_shared;
|
|
#using scripts\shared\system_shared;
|
|
#using scripts\shared\util_shared;
|
|
|
|
|
|
|
|
|
|
#using scripts\cp\gametypes\_loadout;
|
|
#using scripts\cp\gametypes\_globallogic;
|
|
#using scripts\cp\gametypes\_globallogic_player;
|
|
#using scripts\cp\gametypes\_save;
|
|
#using scripts\cp\gametypes\_spectating;
|
|
|
|
#using scripts\cp\_util;
|
|
#using scripts\cp\teams\_teams;
|
|
|
|
#precache( "string", "MP_HALFTIME" );
|
|
#precache( "string", "MP_OVERTIME" );
|
|
#precache( "string", "MP_ROUNDEND" );
|
|
#precache( "string", "MP_INTERMISSION" );
|
|
#precache( "string", "MP_SWITCHING_SIDES_CAPS" );
|
|
#precache( "string", "MP_FRIENDLY_FIRE_WILL_NOT" );
|
|
#precache( "string", "MP_RAMPAGE" );
|
|
#precache( "string", "MP_ENDED_GAME" );
|
|
#precache( "string", "MP_HOST_ENDED_GAME" );
|
|
|
|
#precache( "eventstring", "medal_received" );
|
|
#precache( "eventstring", "killstreak_received" );
|
|
#precache( "eventstring", "player_callout" );
|
|
#precache( "eventstring", "score_event" );
|
|
#precache( "eventstring", "rank_up" );
|
|
#precache( "eventstring", "client_rank_up" );
|
|
#precache( "eventstring", "weapon_unlocked" );
|
|
#precache( "eventstring", "token_unlocked" );
|
|
#precache( "eventstring", "gun_level_complete" );
|
|
#precache( "eventstring", "challenge_complete" );
|
|
|
|
#precache( "menu", "InitialBlack" );
|
|
|
|
|
|
|
|
#namespace globallogic_ui;
|
|
|
|
//REGISTER_SYSTEM( "globallogic_ui", &__init__, undefined )
|
|
|
|
function init()
|
|
{
|
|
callback::add_callback( #"on_player_spawned", &on_player_spawn);
|
|
clientfield::register( "clientuimodel", "hudItems.cybercoreSelectMenuDisabled", 1, 1, "int" );
|
|
clientfield::register( "clientuimodel", "hudItems.playerInCombat", 1, 1, "int" );
|
|
clientfield::register( "clientuimodel", "playerAbilities.repulsorIndicatorDirection", 1, 2, "int" );
|
|
clientfield::register( "clientuimodel", "playerAbilities.repulsorIndicatorIntensity", 1, 2, "int" );
|
|
clientfield::register( "clientuimodel", "playerAbilities.proximityIndicatorDirection", 1, 2, "int" );
|
|
clientfield::register( "clientuimodel", "playerAbilities.proximityIndicatorIntensity", 1, 2, "int" );
|
|
clientfield::register( "clientuimodel", "serverDifficulty", 1, 3, "int" );
|
|
}
|
|
|
|
function on_player_spawn()
|
|
{
|
|
self thread watch_player_in_combat();
|
|
|
|
assert( isdefined( level.gameSkill ) );
|
|
|
|
self clientfield::set_player_uimodel( "serverDifficulty", level.gameSkill );
|
|
}
|
|
|
|
function IsAnyAIAttackingThePlayer( playerEnt )
|
|
{
|
|
ais = GetAITeamArray( "axis" );
|
|
ais = ArrayCombine( ais, GetAITeamArray( "team3" ), false, false ); // sometimes enemy AI is on team 3 as well
|
|
|
|
foreach( ai in ais )
|
|
{
|
|
if ( IsSentient( ai ) )
|
|
{
|
|
if ( ai AttackedRecently( playerEnt, 10 ) )
|
|
{
|
|
return true;
|
|
}
|
|
else if ( ai.enemy === playerEnt &&
|
|
IsDefined( ai.weapon ) &&
|
|
ai.weapon.name === "none" &&
|
|
DistanceSquared( ai.origin, playerEnt.origin ) < ( (240) * (240) ) )
|
|
{
|
|
// Melee AI is close to the player.
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
function IsAnyAIAwareOfPlayer( playerEnt )
|
|
{
|
|
ais = GetAITeamArray( "axis" );
|
|
ais = ArrayCombine( ais, GetAITeamArray( "team3" ), false, false ); // sometimes enemy AI is on team 3 as well
|
|
|
|
foreach( ai in ais )
|
|
{
|
|
if ( IsSentient( ai ) )
|
|
{
|
|
// Has known about player recently?
|
|
if ( ( ai LastKnownTime( playerEnt ) + 4000 ) >= GetTime() )
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
function IsPlayerHurt( playerEnt )
|
|
{
|
|
return playerEnt.health < playerEnt.maxhealth;
|
|
}
|
|
|
|
function watch_player_in_combat()
|
|
{
|
|
self endon("kill_watch_player_in_combat");
|
|
self endon( "disconnect" );
|
|
|
|
while( true )
|
|
{
|
|
if ( IsPlayerHurt( self ) || IsAnyAIAttackingThePlayer( self ) )
|
|
{
|
|
self clientfield::set_player_uimodel( "hudItems.playerInCombat", 1 );
|
|
}
|
|
else
|
|
{
|
|
self clientfield::set_player_uimodel( "hudItems.playerInCombat", 0 );
|
|
}
|
|
|
|
wait( 0.5 );
|
|
}
|
|
}
|
|
|
|
function SetupCallbacks()
|
|
{
|
|
level.autoassign =&menuAutoAssign;
|
|
level.spectator =&menuSpectator;
|
|
level.curClass =&menuClass;
|
|
level.teamMenu =&menuTeam;
|
|
}
|
|
|
|
function freeGameplayHudElems()
|
|
{
|
|
// free up some hud elems so we have enough for other things.
|
|
|
|
// perk icons
|
|
if ( isdefined( self.perkicon ) )
|
|
{
|
|
for ( numSpecialties = 0; numSpecialties < level.maxSpecialties; numSpecialties++ )
|
|
{
|
|
if ( isdefined( self.perkicon[ numSpecialties ] ) )
|
|
{
|
|
self.perkicon[ numSpecialties ] hud::destroyElem();
|
|
self.perkname[ numSpecialties ] hud::destroyElem();
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( isdefined( self.perkHudelem ) )
|
|
{
|
|
self.perkHudelem hud::destroyElem();
|
|
}
|
|
|
|
// Killstreak icons
|
|
if ( isdefined( self.killstreakicon ) )
|
|
{
|
|
if ( isdefined( self.killstreakicon[0] ) )
|
|
{
|
|
self.killstreakicon[0] hud::destroyElem();
|
|
}
|
|
if ( isdefined( self.killstreakicon[1] ) )
|
|
{
|
|
self.killstreakicon[1] hud::destroyElem();
|
|
}
|
|
if ( isdefined( self.killstreakicon[2] ) )
|
|
{
|
|
self.killstreakicon[2] hud::destroyElem();
|
|
}
|
|
if ( isdefined( self.killstreakicon[3] ) )
|
|
{
|
|
self.killstreakicon[3] hud::destroyElem();
|
|
}
|
|
if ( isdefined( self.killstreakicon[4] ) )
|
|
{
|
|
self.killstreakicon[4] hud::destroyElem();
|
|
}
|
|
}
|
|
|
|
// lower message
|
|
if ( isdefined( self.lowerMessage ) )
|
|
self.lowerMessage hud::destroyElem();
|
|
if ( isdefined( self.lowerTimer ) )
|
|
self.lowerTimer hud::destroyElem();
|
|
|
|
// progress bar
|
|
if ( isdefined( self.proxBar ) )
|
|
self.proxBar hud::destroyElem();
|
|
if ( isdefined( self.proxBarText ) )
|
|
self.proxBarText hud::destroyElem();
|
|
|
|
// carry icon
|
|
if ( isdefined( self.carryIcon ) )
|
|
self.carryIcon hud::destroyElem();
|
|
}
|
|
|
|
function teamPlayerCountsEqual( playerCounts )
|
|
{
|
|
count = undefined;
|
|
|
|
foreach( team in level.teams )
|
|
{
|
|
if ( !isdefined( count ) )
|
|
{
|
|
count = playerCounts[team];
|
|
continue;
|
|
}
|
|
if ( count != playerCounts[team] )
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
function teamWithLowestPlayerCount( playerCounts, ignore_team )
|
|
{
|
|
count = 9999;
|
|
lowest_team = undefined;
|
|
|
|
foreach( team in level.teams )
|
|
{
|
|
if ( count > playerCounts[team] )
|
|
{
|
|
count = playerCounts[team];
|
|
lowest_team = team;
|
|
}
|
|
}
|
|
|
|
return lowest_team;
|
|
}
|
|
|
|
function menuAutoAssign( comingFromMenu )
|
|
{
|
|
teamKeys = GetArrayKeys( level.teams );
|
|
assignment = teamKeys[randomInt(teamKeys.size)];
|
|
|
|
self closeMenus();
|
|
|
|
assignment = "allies";
|
|
|
|
if ( level.teamBased )
|
|
{
|
|
if ( assignment == self.pers["team"] && (self.sessionstate == "playing" || self.sessionstate == "dead") )
|
|
{
|
|
self beginClassChoice();
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( GetDvarint( "party_autoteams" ) == 1 )
|
|
{
|
|
// after they have spawned in once then we should let the random team assignment logic handle itself.
|
|
if( level.allow_teamchange != "1" || ( !self.hasSpawned && !comingFromMenu ) )
|
|
{
|
|
team = getAssignedTeam( self );
|
|
if( isdefined( level.teams[team] ) )
|
|
{
|
|
assignment = team;
|
|
}
|
|
else if ( team == "spectator" && (!level.forceAutoAssign) )
|
|
{
|
|
self SetClientScriptMainMenu( game[ "menu_start_menu" ] );
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( assignment != self.pers["team"] && (self.sessionstate == "playing" || self.sessionstate == "dead") )
|
|
{
|
|
self.switching_teams = true;
|
|
self.switchedTeamsResetGadgets = true;
|
|
self.joining_team = assignment;
|
|
self.leaving_team = self.pers["team"];
|
|
self suicide();
|
|
}
|
|
|
|
self.pers["team"] = assignment;
|
|
self.team = assignment;
|
|
self.pers["class"] = undefined;
|
|
self.curClass = undefined;
|
|
self.pers["weapon"] = undefined;
|
|
self.pers["savedmodel"] = undefined;
|
|
|
|
self updateObjectiveText();
|
|
|
|
self.sessionteam = assignment;
|
|
|
|
if ( !isAlive( self ) )
|
|
self.statusicon = "hud_status_dead";
|
|
|
|
self notify("joined_team");
|
|
level notify( "joined_team" );
|
|
callback::callback( #"on_joined_team" );
|
|
self notify("end_respawn");
|
|
|
|
self beginClassChoice();
|
|
self SetClientScriptMainMenu( game[ "menu_start_menu" ] );
|
|
|
|
}
|
|
|
|
function teamScoresEqual( )
|
|
{
|
|
score = undefined;
|
|
|
|
foreach( team in level.teams )
|
|
{
|
|
if ( !isdefined( score ) )
|
|
{
|
|
score = getTeamScore(team);
|
|
continue;
|
|
}
|
|
if ( score != getTeamScore(team) )
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
function teamWithLowestScore()
|
|
{
|
|
score = 99999999;
|
|
lowest_team = undefined;
|
|
|
|
foreach( team in level.teams )
|
|
{
|
|
if ( score > getTeamScore(team ) )
|
|
lowest_team = team;
|
|
}
|
|
|
|
return lowest_team;
|
|
}
|
|
|
|
function pickTeamFromScores(teams)
|
|
{
|
|
assignment = "allies";
|
|
|
|
if ( teamScoresEqual() )
|
|
assignment = teams[randomInt(teams.size)];
|
|
else
|
|
assignment = teamWithLowestScore();
|
|
|
|
return assignment;
|
|
}
|
|
|
|
function get_splitscreen_team()
|
|
{
|
|
for ( index = 0; index < level.players.size; index++ )
|
|
{
|
|
if ( !isdefined(level.players[index]) )
|
|
continue;
|
|
|
|
if ( level.players[index] == self )
|
|
continue;
|
|
|
|
if ( !(self IsPlayerOnSameMachine( level.players[index] )) )
|
|
continue;
|
|
|
|
team = level.players[index].sessionteam;
|
|
|
|
// going to assume first non-spectator
|
|
if ( team != "spectator" )
|
|
return team;
|
|
}
|
|
|
|
return "";
|
|
}
|
|
|
|
function updateObjectiveText()
|
|
{
|
|
if ( SessionModeIsZombiesGame() || (self.pers["team"] == "spectator") )
|
|
{
|
|
self SetClientCGObjectiveText( "" );
|
|
return;
|
|
}
|
|
|
|
if( level.scorelimit > 0 )
|
|
{
|
|
self SetClientCGObjectiveText( util::getObjectiveScoreText( self.pers["team"] ) );
|
|
}
|
|
else
|
|
{
|
|
self SetClientCGObjectiveText( util::getObjectiveText( self.pers["team"] ) );
|
|
}
|
|
}
|
|
|
|
|
|
function closeMenus()
|
|
{
|
|
self closeInGameMenu();
|
|
}
|
|
|
|
function beginClassChoice()
|
|
{
|
|
assert( isdefined( level.teams[self.pers["team"]] ) );
|
|
|
|
team = self.pers["team"];
|
|
|
|
self CloseMenu( game["menu_start_menu"] );
|
|
|
|
if ( !GetDvarInt( "art_review", 0 ) )
|
|
{
|
|
self thread fullscreen_black();
|
|
}
|
|
|
|
b_disable_cac = GetDvarInt( "force_no_cac", 0 );
|
|
|
|
if ( !GetDvarInt( "force_cac", 0 ) || b_disable_cac )
|
|
{
|
|
prevclass = self savegame::get_player_data( "playerClass", undefined );
|
|
prevHeroWeapons = self savegame::get_player_data( savegame::get_mission_name() + "hero_weapon", undefined );
|
|
|
|
if ( isdefined( prevclass ) || b_disable_cac
|
|
|| ( isdefined( level.disableClassSelection ) && level.disableClassSelection )
|
|
|| ( isdefined( self.disableClassSelection ) && self.disableClassSelection )
|
|
|| GetDvarint( "migration_soak" ) == 1 )
|
|
{
|
|
self.curClass = (isdefined(prevclass)?prevclass:level.defaultClass);
|
|
self.pers[ "class" ] = self.curClass;
|
|
|
|
{wait(.05);};
|
|
|
|
if ( self.sessionstate != "playing" && game[ "state" ] == "playing" )
|
|
{
|
|
self thread [[ level.spawnClient ]]();
|
|
}
|
|
|
|
globallogic::updateTeamStatus();
|
|
self thread spectating::set_permissions_for_machine();
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
// menu_changeclass_team is the one where you choose one of the n classes to play as.
|
|
// menu_class_team is where you can choose to change your team, class, controls, or leave game.
|
|
self CloseMenu( game[ "menu_changeclass" ] );
|
|
self openMenu( game[ "menu_changeclass_" + team ] );
|
|
|
|
//if ( level.rankedMatch )
|
|
// self openMenu( game[ "menu_changeclass_" + team ] );
|
|
//else
|
|
// self openMenu( game[ "menu_start_menu" ] );
|
|
}
|
|
|
|
function fullscreen_black()
|
|
{
|
|
self endon( "disconnect" );
|
|
|
|
util::show_hud( 0 );
|
|
|
|
self CloseMenu( "InitialBlack" );
|
|
self OpenMenu( "InitialBlack" );
|
|
|
|
b_hot_joining = false;
|
|
if ( level flag::get( "all_players_spawned" ) )
|
|
{
|
|
b_hot_joining = true;
|
|
}
|
|
|
|
self.fullscreen_black_active = true;
|
|
self thread fullscreen_black_checkpoint_restore(); //this thread makes sure the fullscreen black is held up even if you restore from checkpoint and it needs to be held up
|
|
|
|
self Hide();
|
|
|
|
{wait(.05);};
|
|
|
|
if ( isdefined( level.str_level_start_flag ) || isdefined( level.str_player_start_flag ) )
|
|
{
|
|
init_start_flags();
|
|
|
|
self thread fullscreen_black_freeze_controls();
|
|
|
|
if ( isdefined( level.str_level_start_flag ) )
|
|
{
|
|
level flag::wait_till( level.str_level_start_flag );
|
|
}
|
|
|
|
if ( isdefined( level.str_player_start_flag ) )
|
|
{
|
|
self flag::wait_till( level.str_player_start_flag );
|
|
}
|
|
}
|
|
|
|
if ( b_hot_joining && !( isdefined( level.is_safehouse ) && level.is_safehouse ) )
|
|
{
|
|
while ( self.sessionstate !== "playing" )
|
|
{
|
|
{wait(.05);};
|
|
}
|
|
|
|
self thread fullscreen_black_freeze_controls();
|
|
|
|
while ( self IsLoadingCinematicPlaying() )
|
|
{
|
|
{wait(.05);};
|
|
}
|
|
|
|
self flag::wait_till( "loadout_given" );
|
|
waittillframeend; // if we are hot-joining an IGC wait until we can detect that
|
|
|
|
wait 2;
|
|
|
|
// hold black and wait for streamer
|
|
self util::streamer_wait( undefined, 5, 5 );
|
|
|
|
self thread lui::screen_fade_in( .3, "black", "hot_join" );
|
|
}
|
|
|
|
if ( !flagsys::get( "shared_igc" ) )
|
|
{
|
|
self Show();
|
|
}
|
|
|
|
self flagsys::set( "kill_fullscreen_black" );
|
|
|
|
self clientfield::set_to_player( "sndLevelStartSnapOff", 1 );
|
|
self CloseMenu( "InitialBlack" );
|
|
|
|
self.fullscreen_black_active = undefined;
|
|
|
|
util::show_hud( 1 );
|
|
|
|
/#
|
|
PrintTopRightln( "["+GetTime()+"] KILL INITIAL BLACKSCREEN: PLAYER " + self GetEntityNumber(), ( 1, 1, 1 ) );
|
|
streamerSkiptoDebug( GetSkiptos() );
|
|
#/
|
|
}
|
|
|
|
function fullscreen_black_checkpoint_restore()
|
|
{
|
|
self endon( "disconnect" );
|
|
self endon( "kill_fullscreen_black" ); //this seems to be set when the initial fullscreen is done
|
|
|
|
b_fullscreen_black = self.fullscreen_black_active;
|
|
|
|
level waittill( "save_restore" );
|
|
|
|
if( ( isdefined( b_fullscreen_black ) && b_fullscreen_black ) )
|
|
{
|
|
self CloseMenu( "InitialBlack" );
|
|
self OpenMenu( "InitialBlack" );
|
|
}
|
|
}
|
|
|
|
function init_start_flags()
|
|
{
|
|
if ( isdefined( level.str_player_start_flag ) && !self flag::exists( level.str_player_start_flag ) )
|
|
{
|
|
self flag::init( level.str_player_start_flag );
|
|
}
|
|
|
|
if ( isdefined( level.str_level_start_flag ) && !level flag::exists( level.str_level_start_flag ) )
|
|
{
|
|
level flag::init( level.str_level_start_flag );
|
|
}
|
|
}
|
|
|
|
function fullscreen_black_freeze_controls()
|
|
{
|
|
self endon( "disconnect" );
|
|
|
|
self.b_game_start_invulnerability = true;
|
|
|
|
self flagsys::wait_till( "loadout_given" );
|
|
|
|
self DisableWeapons();
|
|
self FreezeControls( true );
|
|
|
|
wait 0.1; // Several other scripts unfreeze controls when spawning, need to wait
|
|
waittillframeend;
|
|
|
|
self FreezeControls( true );
|
|
self DisableWeapons();
|
|
|
|
self flagsys::wait_till( "kill_fullscreen_black" );
|
|
|
|
self EnableWeapons();
|
|
self FreezeControls( false );
|
|
|
|
self.b_game_start_invulnerability = undefined;
|
|
}
|
|
|
|
function showMainMenuForTeam()
|
|
{
|
|
assert( isdefined( level.teams[self.pers["team"]] ) );
|
|
|
|
team = self.pers["team"];
|
|
|
|
// menu_changeclass_team is the one where you choose one of the n classes to play as.
|
|
// menu_class_team is where you can choose to change your team, class, controls, or leave game.
|
|
|
|
self openMenu( game[ "menu_changeclass_" + team ] );
|
|
}
|
|
|
|
function menuTeam( team )
|
|
{
|
|
self closeMenus();
|
|
|
|
if ( !level.console && level.allow_teamchange == "0" && (isdefined(self.hasDoneCombat) && self.hasDoneCombat) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if(self.pers["team"] != team)
|
|
{
|
|
// allow respawn when switching teams during grace period.
|
|
if ( level.inGracePeriod && (!isdefined(self.hasDoneCombat) || !self.hasDoneCombat) )
|
|
self.hasSpawned = false;
|
|
|
|
if(self.sessionstate == "playing")
|
|
{
|
|
self.switching_teams = true;
|
|
self.switchedTeamsResetGadgets = true;
|
|
self.joining_team = team;
|
|
self.leaving_team = self.pers["team"];
|
|
self suicide();
|
|
}
|
|
|
|
self.pers["team"] = team;
|
|
self.team = team;
|
|
self.pers["class"] = undefined;
|
|
self.curClass = undefined;
|
|
self.pers["weapon"] = undefined;
|
|
self.pers["savedmodel"] = undefined;
|
|
|
|
self updateObjectiveText();
|
|
|
|
if ( !level.rankedMatch && !level.leagueMatch )
|
|
{
|
|
self.sessionstate = "spectator";
|
|
}
|
|
|
|
self.sessionteam = team;
|
|
|
|
self SetClientScriptMainMenu( game[ "menu_start_menu" ] );
|
|
|
|
self notify("joined_team");
|
|
level notify( "joined_team" );
|
|
callback::callback( #"on_joined_team" );
|
|
self notify("end_respawn");
|
|
}
|
|
|
|
self beginClassChoice();
|
|
}
|
|
|
|
function menuSpectator()
|
|
{
|
|
self closeMenus();
|
|
|
|
if(self.pers["team"] != "spectator")
|
|
{
|
|
if(isAlive(self))
|
|
{
|
|
self.switching_teams = true;
|
|
self.switchedTeamsResetGadgets = true;
|
|
self.joining_team = "spectator";
|
|
self.leaving_team = self.pers["team"];
|
|
self suicide();
|
|
}
|
|
|
|
self.pers["team"] = "spectator";
|
|
self.team = "spectator";
|
|
self.pers["class"] = undefined;
|
|
self.curClass = undefined;
|
|
self.pers["weapon"] = undefined;
|
|
self.pers["savedmodel"] = undefined;
|
|
|
|
self updateObjectiveText();
|
|
|
|
self.sessionteam = "spectator";
|
|
|
|
[[level.spawnSpectator]]();
|
|
|
|
self thread globallogic_player::spectate_player_watcher();
|
|
|
|
self SetClientScriptMainMenu( game[ "menu_start_menu" ] );
|
|
|
|
self notify("joined_spectators");
|
|
callback::callback( #"on_joined_spectate" );
|
|
}
|
|
}
|
|
|
|
function menuClass( response )
|
|
{
|
|
self closeMenus();
|
|
|
|
// this should probably be an assert
|
|
if ( !isdefined( self.pers[ "team" ] ) || !( isdefined( level.teams[ self.pers[ "team" ]] ) ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
//-- mobile armory handles these changes within the system
|
|
if ( flagsys::get( "mobile_armory_in_use" ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
playerclass = "";
|
|
|
|
if ( response == "cancel" )
|
|
{
|
|
prevclass = self savegame::get_player_data( "playerClass", undefined );
|
|
|
|
if ( isdefined( prevclass ) )
|
|
{
|
|
playerclass = prevclass;
|
|
}
|
|
else
|
|
{
|
|
playerclass = level.defaultClass;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
responseArray = strtok( response, "," );
|
|
if( responseArray.size > 1 )
|
|
{
|
|
str_class_chosen = responseArray[0];
|
|
clientNum = Int( responseArray[1] );
|
|
|
|
altPlayer = util::getPlayerFromClientNum( clientNum );
|
|
}
|
|
else
|
|
{
|
|
str_class_chosen = response;
|
|
}
|
|
|
|
playerclass = self loadout::getClassChoice( str_class_chosen );
|
|
|
|
if( IsDefined( altPlayer ) )
|
|
{
|
|
xuid = altPlayer GetXUID();
|
|
self savegame::set_player_data( "altPlayerID", xuid );
|
|
}
|
|
else
|
|
{
|
|
self savegame::set_player_data( "altPlayerID", undefined );
|
|
}
|
|
|
|
self savegame::set_player_data( "saved_weapon", undefined );
|
|
self savegame::set_player_data( "saved_weapondata", undefined );
|
|
self savegame::set_player_data( "lives", undefined );
|
|
self savegame::set_player_data( "saved_rig1", undefined );
|
|
self savegame::set_player_data( "saved_rig1_upgraded", undefined );
|
|
self savegame::set_player_data( "saved_rig2", undefined );
|
|
self savegame::set_player_data( "saved_rig2_upgraded", undefined );
|
|
}
|
|
|
|
if( (isdefined( self.pers["class"] ) && self.pers["class"] == playerclass) )
|
|
return;
|
|
|
|
self.pers["changed_class"] = true;
|
|
self notify ( "changed_class" );
|
|
waittillframeend;
|
|
//The player selected the class they are currently using
|
|
if( isdefined(self.curClass) && self.curClass == playerclass )
|
|
{
|
|
self.pers["changed_class"] = false;
|
|
}
|
|
|
|
if ( self.sessionstate == "playing" )
|
|
{
|
|
self savegame::set_player_data( "playerClass", playerClass );
|
|
self.pers["class"] = playerClass;
|
|
self.curClass = playerclass;
|
|
self.pers["weapon"] = undefined;
|
|
|
|
if ( game["state"] == "postgame" )
|
|
return;
|
|
|
|
supplyStationClassChange = isdefined( self.usingSupplyStation ) && self.usingSupplyStation;
|
|
self.usingSupplyStation = false;
|
|
|
|
if ( ( level.inGracePeriod && !self.hasDoneCombat ) || supplyStationClassChange ) // used weapons check?
|
|
{
|
|
self loadout::setClass( self.pers["class"] );
|
|
self.tag_stowed_back = undefined;
|
|
self.tag_stowed_hip = undefined;
|
|
self loadout::giveLoadout( self.pers["team"], self.pers["class"] );
|
|
}
|
|
else if ( !( self IsSplitScreen() ) )
|
|
{
|
|
self IPrintLnBold( game["strings"]["change_class"] );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
self savegame::set_player_data( "playerClass",playerClass);
|
|
self.pers["class"] = playerclass;
|
|
self.curClass = playerclass;
|
|
self.pers["weapon"] = undefined;
|
|
|
|
if ( game["state"] == "postgame" )
|
|
return;
|
|
|
|
if ( self.sessionstate != "spectator" )
|
|
{
|
|
if ( self IsInVehicle() )
|
|
return;
|
|
|
|
if ( self IsRemoteControlling() )
|
|
return;
|
|
|
|
if ( self IsWeaponViewOnlyLinked() )
|
|
return false;
|
|
}
|
|
|
|
if ( game["state"] == "playing" )
|
|
{
|
|
timePassed = undefined;
|
|
|
|
if ( isdefined( self.respawnTimerStartTime ) )
|
|
{
|
|
timePassed = (gettime() - self.respawnTimerStartTime) / 1000;
|
|
}
|
|
|
|
self thread [[level.spawnClient]](timePassed);
|
|
|
|
self.respawnTimerStartTime = undefined;
|
|
|
|
}
|
|
}
|
|
|
|
globallogic::updateTeamStatus();
|
|
|
|
self thread spectating::set_permissions_for_machine();
|
|
self notify("class_changed");
|
|
}
|
|
|
|
|
|
/*
|
|
function showSafeSpawnMessage()
|
|
{
|
|
if ( level.splitscreen )
|
|
return;
|
|
|
|
// don't show it if they've already asked for a safe spawn
|
|
if ( self.wantSafeSpawn )
|
|
return;
|
|
|
|
if ( !isdefined( self.safeSpawnMsg ) )
|
|
{
|
|
self.safeSpawnMsg = hud::createFontString( "default", 1.4 );
|
|
self.safeSpawnMsg hud::setPoint( "CENTER", level.lowerTextYAlign, 0, level.lowerTextY + 50 );
|
|
self.safeSpawnMsg setText( &"PLATFORM_PRESS_TO_SAFESPAWN" );
|
|
self.safeSpawnMsg.archived = false;
|
|
}
|
|
self.safeSpawnMsg.alpha = 1;
|
|
}
|
|
function hideSafeSpawnMessage()
|
|
{
|
|
if ( !isdefined( self.safeSpawnMsg ) )
|
|
return;
|
|
|
|
self.safeSpawnMsg.alpha = 0;
|
|
}
|
|
*/
|
|
|
|
|
|
function removeSpawnMessageShortly( delay )
|
|
{
|
|
self endon("disconnect");
|
|
|
|
waittillframeend; // so we don't endon the end_respawn from spawning as a spectator
|
|
|
|
self endon("end_respawn");
|
|
|
|
wait delay;
|
|
|
|
self util::clearLowerMessage( 2.0 );
|
|
}
|
|
|
|
// weakpoint helpers
|
|
#precache( "eventstring", "weakpoint_update" );
|
|
|
|
// self = entity
|
|
function weakpoint_anim_watch( precachedBoneName )
|
|
{
|
|
self endon( "death" );
|
|
self endon( "weakpoint_destroyed" );
|
|
|
|
while(true)
|
|
{
|
|
self waittill( "weakpoint_update", boneName, event );
|
|
|
|
if ( boneName == precachedBoneName )
|
|
{
|
|
if ( event == "damage" )
|
|
{
|
|
LUINotifyEvent( &"weakpoint_update", 3, 2, self getEntityNumber(), precachedBoneName );
|
|
}
|
|
else if ( event == "repulse" )
|
|
{
|
|
LUINotifyEvent( &"weakpoint_update", 3, 3, self getEntityNumber(), precachedBoneName );
|
|
}
|
|
|
|
wait 0.5;
|
|
}
|
|
}
|
|
}
|
|
|
|
// self = entity
|
|
function destroyWeakpointWidget( precachedBoneName )
|
|
{
|
|
LUINotifyEvent( &"weakpoint_update", 3, 0, self getEntityNumber(), precachedBoneName );
|
|
self notify( "weakpoint_destroyed" );
|
|
}
|
|
|
|
// self = entity
|
|
function createWeakpointWidget( precachedBoneName, closeStateMaxDistance = undefined, mediumStateMaxDistance = undefined )
|
|
{
|
|
if ( !isdefined( closeStateMaxDistance ) )
|
|
{
|
|
closeStateMaxDistance = GetDVarInt( "ui_weakpointIndicatorNear", 1050 );
|
|
}
|
|
|
|
if ( !isdefined( mediumStateMaxDistance ) )
|
|
{
|
|
mediumStateMaxDistance = GetDVarInt( "ui_weakpointIndicatorMedium", 1900 );
|
|
}
|
|
|
|
LUINotifyEvent( &"weakpoint_update", 5, 1, self getEntityNumber(), precachedBoneName, closeStateMaxDistance, mediumStateMaxDistance );
|
|
|
|
self thread weakpoint_anim_watch( precachedBoneName );
|
|
}
|
|
|
|
// self = entity
|
|
function triggerWeakpointDamage( precachedBoneName )
|
|
{
|
|
self notify( "weakpoint_update", precachedBoneName, "damage" );
|
|
}
|
|
|
|
// self = entity
|
|
function triggerWeakpointRepulsed( precachedBoneName )
|
|
{
|
|
self notify( "weakpoint_update", precachedBoneName, "repulse" );
|
|
}
|