1686 lines
50 KiB
Plaintext
1686 lines
50 KiB
Plaintext
#using scripts\shared\gameobjects_shared;
|
|
#using scripts\shared\math_shared;
|
|
#using scripts\shared\util_shared;
|
|
|
|
#using scripts\shared\clientfield_shared;
|
|
#using scripts\shared\popups_shared;
|
|
#using scripts\shared\lui_shared;
|
|
|
|
|
|
|
|
|
|
|
|
#using scripts\shared\callbacks_shared;
|
|
#using scripts\shared\system_shared;
|
|
#using scripts\mp\_pickup_items;
|
|
#using scripts\mp\gametypes\_globallogic;
|
|
#using scripts\mp\gametypes\_globallogic_audio;
|
|
#using scripts\mp\gametypes\_globallogic_score;
|
|
#using scripts\mp\gametypes\_spawning;
|
|
#using scripts\mp\gametypes\_spawnlogic;
|
|
|
|
#using scripts\mp\_util;
|
|
|
|
/*
|
|
Freerun
|
|
Objective: Make it to the goal the fastest
|
|
Map ends: When player quits
|
|
Respawning: Instant
|
|
|
|
Level requirements
|
|
------------------
|
|
Spawnpoints:
|
|
classname mp_dm_spawn
|
|
All players spawn from these. The spawnpoint chosen is dependent on the current locations of enemies at the time of spawn.
|
|
Players generally spawn away from enemies.
|
|
|
|
Spectator Spawnpoints:
|
|
classname mp_global_intermission
|
|
Spectators spawn from these and intermission is viewed from these positions.
|
|
Atleast one is required, any more and they are randomly chosen between.
|
|
*/
|
|
|
|
/*QUAKED mp_dm_spawn (1.0 0.5 0.0) (-16 -16 0) (16 16 72)
|
|
Players spawn away from enemies at one of these positions.*/
|
|
|
|
/*
|
|
- down is reset to active checkpoint
|
|
- left/right change courses
|
|
- up is to reset to start of course/reset timer
|
|
*/
|
|
|
|
/* TODO:
|
|
|
|
- top 3 scores show on track end
|
|
- timer based missile swarm that penalizes being on foot for too long
|
|
- random missile swarm that chooses areas the player is running towards
|
|
- timer value counting up every frame and incremented 5s on fault (or just add the faults at the end maybe)
|
|
- combo/speed boost methods for stringing together special moves?
|
|
- drop the ctf spawn point FX on the start and end triggers
|
|
- UI NEEDS
|
|
- timer
|
|
- top 3
|
|
- communication string billboard
|
|
- track/difficulty callout
|
|
- press X to start gate
|
|
|
|
- BUGS
|
|
- find a way to unbind score board from script or CFG maybe
|
|
- has to happen after binds are loaded from HD
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#precache( "string", "OBJECTIVES_FR" );
|
|
#precache( "string", "OBJECTIVES_FR_SCORE" );
|
|
#precache( "string", "OBJECTIVES_FR_HINT" );
|
|
#precache( "string", "OBJECTIVES_FR_NEW_RECORD" );
|
|
#precache( "string", "OBJECTIVES_FR_CHECKPOINT" );
|
|
#precache( "string", "OBJECTIVES_FR_FAULT" );
|
|
#precache( "string", "OBJECTIVES_FR_FAULTS" );
|
|
#precache( "string", "OBJECTIVES_FR_RETRY" );
|
|
#precache( "string", "OBJECTIVES_FR_RETRIES" );
|
|
|
|
#precache( "string", "FREERUN_TUTORIAL_01" );
|
|
#precache( "string", "FREERUN_TUTORIAL_02" );
|
|
#precache( "string", "FREERUN_TUTORIAL_03" );
|
|
#precache( "string", "FREERUN_TUTORIAL_04" );
|
|
#precache( "string", "FREERUN_TUTORIAL_05" );
|
|
#precache( "string", "FREERUN_TUTORIAL_06" );
|
|
#precache( "string", "FREERUN_TUTORIAL_07" );
|
|
#precache( "string", "FREERUN_TUTORIAL_08" );
|
|
#precache( "string", "FREERUN_TUTORIAL_09" );
|
|
#precache( "string", "FREERUN_TUTORIAL_10" );
|
|
#precache( "string", "FREERUN_TUTORIAL_11" );
|
|
#precache( "string", "FREERUN_TUTORIAL_12" );
|
|
#precache( "string", "FREERUN_TUTORIAL_13" );
|
|
#precache( "string", "FREERUN_TUTORIAL_14" );
|
|
#precache( "string", "FREERUN_TUTORIAL_14a" );
|
|
#precache( "string", "FREERUN_TUTORIAL_15" );
|
|
#precache( "string", "FREERUN_TUTORIAL_16" );
|
|
#precache( "string", "FREERUN_TUTORIAL_17" );
|
|
#precache( "string", "FREERUN_TUTORIAL_18" );
|
|
#precache( "string", "FREERUN_TUTORIAL_19" );
|
|
#precache( "string", "FREERUN_TUTORIAL_20" );
|
|
#precache( "string", "FREERUN_TUTORIAL_21" );
|
|
#precache( "string", "FREERUN_TUTORIAL_22" );
|
|
#precache( "string", "FREERUN_TUTORIAL_22a" );
|
|
#precache( "string", "FREERUN_TUTORIAL_23" );
|
|
#precache( "string", "FREERUN_TUTORIAL_24" );
|
|
#precache( "string", "FREERUN_TUTORIAL_25" );
|
|
#precache( "string", "FREERUN_TUTORIAL_26" );
|
|
#precache( "string", "FREERUN_WELCOME" );
|
|
#precache( "string", "FREERUN_CHECKPOINT" );
|
|
#precache( "string", "FREERUN_BEST_TIME" );
|
|
#precache( "string", "FREERUN_COMPLETE" );
|
|
#precache( "string", "FREERUN_BEST_RUN" );
|
|
|
|
#precache( "fx", "ui/fx_fr_target_demat" );
|
|
#precache( "fx", "ui/fx_fr_target_impact" );
|
|
|
|
#precache( "menu", "freerun_endgame_popup" );
|
|
|
|
function main()
|
|
{
|
|
level.trackWeaponStats = false;
|
|
globallogic::init();
|
|
|
|
clientfield::register( "world", "freerun_state", 1, 3, "int" );
|
|
clientfield::register( "world", "freerun_retries", 1, 16, "int" );
|
|
clientfield::register( "world", "freerun_faults", 1, 16, "int" );
|
|
clientfield::register( "world", "freerun_startTime", 1, 31, "int" );
|
|
clientfield::register( "world", "freerun_finishTime", 1, 31, "int" );
|
|
clientfield::register( "world", "freerun_bestTime", 1, 31, "int" );
|
|
clientfield::register( "world", "freerun_timeAdjustment", 1, 31, "int" );
|
|
clientfield::register( "world", "freerun_timeAdjustmentNegative", 1, 1, "int" );
|
|
clientfield::register( "world", "freerun_bulletPenalty", 1, 16, "int" );
|
|
clientfield::register( "world", "freerun_pausedTime", 1, 31, "int" );
|
|
clientfield::register( "world", "freerun_checkpointIndex", 1, 7, "int" );
|
|
|
|
util::registerTimeLimit( 0, 1440 );
|
|
util::registerScoreLimit( 0, 50000 );
|
|
util::registerRoundLimit( 0, 10 );
|
|
util::registerRoundWinLimit( 0, 10 );
|
|
util::registerNumLives( 0, 100 );
|
|
|
|
globallogic::registerFriendlyFireDelay( level.gameType, 0, 0, 1440 );
|
|
|
|
level.scoreRoundWinBased = ( GetGametypeSetting( "cumulativeRoundScores" ) == false );
|
|
level.teamScorePerKill = GetGametypeSetting( "teamScorePerKill" );
|
|
level.teamScorePerDeath = GetGametypeSetting( "teamScorePerDeath" );
|
|
level.teamScorePerHeadshot = GetGametypeSetting( "teamScorePerHeadshot" );
|
|
level.onStartGameType =&onStartGameType;
|
|
level.onSpawnPlayer =&onSpawnPlayer;
|
|
level.giveCustomLoadout = &giveCustomLoadout;
|
|
|
|
//level.skipGameEnd = 1;
|
|
level.postRoundTime = 0.5;
|
|
level.doEndgameScoreboard = false;
|
|
|
|
callback::on_connect( &on_player_connect );
|
|
|
|
gameobjects::register_allowed_gameobject( "dm" );
|
|
gameobjects::register_allowed_gameobject( level.gameType );
|
|
|
|
if ( !IsDefined( level.fr_target_impact_fx ) )
|
|
{
|
|
level.fr_target_impact_fx = "ui/fx_fr_target_impact";
|
|
}
|
|
if ( !IsDefined( level.fr_target_disable_fx ) )
|
|
{
|
|
level.fr_target_disable_fx = "ui/fx_fr_target_demat";
|
|
}
|
|
if ( !IsDefined( level.fr_target_disable_sound ) )
|
|
{
|
|
level.fr_target_disable_sound = "wpn_grenade_explode_default";
|
|
}
|
|
|
|
// globallogic_audio::set_leader_gametype_dialog ( "startFreeRun", "hcStartFreeRun", "gameBoost", "gameBoost" );
|
|
|
|
level.FRGame = SpawnStruct();
|
|
|
|
level.FRGame.activeTrackIndex = 0;
|
|
level.FRGame.tracks = [];
|
|
|
|
for ( i = 0; i < 1; i++ )
|
|
{
|
|
level.FRGame.tracks[i] = SpawnStruct();
|
|
|
|
level.FRGame.tracks[i].startTrigger = GetEnt( "fr_start_0" + i, "targetname" );
|
|
assert( IsDefined( level.FRGame.tracks[i].startTrigger ));
|
|
|
|
level.FRGame.tracks[i].goalTrigger = GetEnt( "fr_end_0" + i, "targetname" );
|
|
assert( IsDefined( level.FRGame.tracks[i].goalTrigger ));
|
|
|
|
level.FRGame.tracks[i].highScores = [];
|
|
}
|
|
|
|
level.FRGame.checkpointTriggers = GetEntArray( "fr_checkpoint", "targetname" );
|
|
assert( level.FRGame.checkpointTriggers.size );
|
|
|
|
// Sets the scoreboard columns and determines with data is sent across the network
|
|
globallogic::setvisiblescoreboardcolumns( "pointstowin", "kills", "deaths", "headshots", "score" );
|
|
|
|
}
|
|
|
|
function setupTeam( team )
|
|
{
|
|
util::setObjectiveText( team, &"OBJECTIVES_FR" );
|
|
|
|
if ( level.splitscreen )
|
|
{
|
|
util::setObjectiveScoreText( team, &"OBJECTIVES_FR" );
|
|
}
|
|
else
|
|
{
|
|
util::setObjectiveScoreText( team, &"OBJECTIVES_FR_SCORE" );
|
|
}
|
|
util::setObjectiveHintText( team, &"OBJECTIVES_FR_SCORE" );
|
|
|
|
spawnlogic::add_spawn_points( team, "mp_dm_spawn" );
|
|
}
|
|
|
|
function onStartGameType()
|
|
{
|
|
setClientNameMode("auto_change");
|
|
|
|
level.useXCamsForEndGame = false;
|
|
level.can_set_aar_stat = false;
|
|
level.disableBehaviorTracker = true;
|
|
level.disableStatTracking = true;
|
|
|
|
// now that the game objects have been deleted place the influencers
|
|
spawning::create_map_placed_influencers();
|
|
|
|
level.spawnMins = ( 0, 0, 0 );
|
|
level.spawnMaxs = ( 0, 0, 0 );
|
|
|
|
foreach( team in level.teams )
|
|
{
|
|
setupTeam( team );
|
|
}
|
|
|
|
spawns = spawnlogic::get_spawnpoint_array( "mp_dm_spawn" );
|
|
spawning::updateAllSpawnPoints();
|
|
|
|
foreach( index, trigger in level.FRGame.checkpointTriggers )
|
|
{
|
|
level.FRGame.checkpointTimes[index] = 0;
|
|
trigger.checkPointIndex = index;
|
|
|
|
trigger thread watchCheckpointTrigger();
|
|
|
|
closest = 99999999;
|
|
foreach( spawn in spawns )
|
|
{
|
|
dist = DistanceSquared( spawn.origin, trigger.origin );
|
|
if ( dist < closest )
|
|
{
|
|
closest = dist;
|
|
trigger.spawnPoint = spawn;
|
|
}
|
|
}
|
|
|
|
assert( IsDefined( trigger.spawnPoint ));
|
|
}
|
|
|
|
player_starts = spawnlogic::_get_spawnpoint_array( "info_player_start" );
|
|
assert( player_starts.size );
|
|
|
|
foreach( track in level.FRGame.tracks )
|
|
{
|
|
closest = 99999999;
|
|
foreach( start in player_starts )
|
|
{
|
|
dist = DistanceSquared( start.origin, track.startTrigger.origin );
|
|
if ( dist < closest )
|
|
{
|
|
closest = dist;
|
|
track.playerStart = start;
|
|
}
|
|
}
|
|
|
|
assert( IsDefined( track.playerStart ));
|
|
}
|
|
|
|
level.FRGame.deathTriggers = GetEntArray( "fr_die", "targetname" );
|
|
assert( level.FRGame.deathTriggers.size );
|
|
|
|
foreach( trigger in level.FRGame.deathTriggers )
|
|
{
|
|
trigger thread watchDeathTrigger();
|
|
}
|
|
|
|
setup_tutorial();
|
|
|
|
if(!IsDefined (level.freerun)) // this keeps suspense music from the global mp system from playing
|
|
{
|
|
level.freerun = true;
|
|
}
|
|
|
|
level.mapCenter = math::find_box_center( level.spawnMins, level.spawnMaxs );
|
|
setMapCenter( level.mapCenter );
|
|
|
|
spawnpoint = spawnlogic::get_random_intermission_point();
|
|
setDemoIntermissionPoint( spawnpoint.origin, spawnpoint.angles );
|
|
|
|
// use the new spawn logic from the start
|
|
level.useStartSpawns = false;
|
|
level.displayRoundEndText = false;
|
|
|
|
if ( !util::isOneRound() )
|
|
{
|
|
level.displayRoundEndText = true;
|
|
}
|
|
|
|
foreach( item in level.pickup_items )
|
|
{
|
|
closest = 99999999;
|
|
foreach( trigger in level.FRGame.checkpointTriggers )
|
|
{
|
|
dist = DistanceSquared( item.origin, trigger.origin );
|
|
if ( dist < closest )
|
|
{
|
|
closest = dist;
|
|
item.checkPoint = trigger;
|
|
}
|
|
}
|
|
assert( IsDefined( item.checkPoint ));
|
|
|
|
item.checkPoint.weapon = item.visuals[0].items[0].weapon;
|
|
item.checkPoint.weaponObject = item;
|
|
|
|
item.checkPoint setup_weapon_targets();
|
|
}
|
|
|
|
thread watch_for_game_end();
|
|
|
|
level.FRGame.trackIndex = GetFreerunTrackIndex( );
|
|
level.FRGame.mapUniqueId = GetMissionUniqueID( );
|
|
level.FRGame.mapVersion = GetMissionVersion( );
|
|
}
|
|
|
|
function watch_for_game_end()
|
|
{
|
|
level waittill("game_ended");
|
|
|
|
if ( !end_game_state() )
|
|
{
|
|
level clientfield::set( "freerun_finishTime", 0 );
|
|
}
|
|
self stop_tutorial_vo();
|
|
level clientfield::set( "freerun_state", 4 );
|
|
}
|
|
|
|
function on_player_connect()
|
|
{
|
|
self thread on_menu_response();
|
|
}
|
|
|
|
function on_menu_response()
|
|
{
|
|
self endon("disconnect");
|
|
|
|
for(;;)
|
|
{
|
|
self waittill("menuresponse", menu, response);
|
|
if ( response == "fr_restart" )
|
|
{
|
|
self playsoundtoplayer( "uin_freerun_reset", self );
|
|
self thread freerunMusic();
|
|
activateTrack( level.FRGame.activeTrackIndex );
|
|
}
|
|
}
|
|
}
|
|
|
|
function onSpawnPlayer(predictedSpawn) // self == player
|
|
{
|
|
spawning::onSpawnPlayer(predictedSpawn);
|
|
|
|
if ( predictedSpawn )
|
|
return;
|
|
|
|
// if we are here a second time its because the player died.
|
|
if ( IsDefined( self.FRInited ) )
|
|
{
|
|
self.body hide();
|
|
faultDeath();
|
|
return;
|
|
}
|
|
|
|
self.FRInited = true;
|
|
|
|
self thread activate_tutorial_mode();
|
|
self thread activateTrack( level.FRGame.activeTrackIndex );
|
|
self thread watchTrackSwitch();
|
|
self thread watchWeaponFire();
|
|
self thread freerunMusic();
|
|
|
|
self thread trackPlayerOrigin();
|
|
|
|
// self.overridePlayerDamage = &on_player_damage;
|
|
|
|
level.FRGame.lastPlayedFaultVOTime = 0;
|
|
|
|
self DisableWeaponCycling();
|
|
}
|
|
|
|
function on_player_damage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, modelIndex, psOffsetTime )
|
|
{
|
|
if ( iDamage >= self.health )
|
|
{
|
|
// damage function always applies at least 1 damage
|
|
self.health = self.maxHealth + 1;
|
|
faultDeath();
|
|
return 0;
|
|
}
|
|
|
|
return iDamage;
|
|
}
|
|
|
|
function trackPlayerOrigin()
|
|
{
|
|
self endon( "disconnect" );
|
|
|
|
while( 1 )
|
|
{
|
|
self.prev_origin = self.origin;
|
|
self.prev_time = GetTime();
|
|
{wait(.05);};
|
|
waittillframeend;
|
|
}
|
|
}
|
|
|
|
function readHighScores() // self == player
|
|
{
|
|
get_top_scores_stats();
|
|
|
|
updateHighScores();
|
|
}
|
|
|
|
function updateHighScores()
|
|
{
|
|
self FreerunSetHighScores( level.FRGame.activeTrack.highScores[0].time, level.FRGame.activeTrack.highScores[1].time, level.FRGame.activeTrack.highScores[2].time );
|
|
level clientfield::set( "freerun_bestTime", level.FRGame.activeTrack.highScores[0].time );
|
|
}
|
|
|
|
function activateTrack( trackIndex ) // self == player
|
|
{
|
|
level notify( "activate_track" );
|
|
|
|
/#
|
|
if ( level.FRGame.tracks.size > 1 )
|
|
{
|
|
IPrintLn( "Track " + trackIndex );
|
|
}
|
|
#/
|
|
|
|
if ( !isdefined( level.FRGame.tutorials ) || !level.FRGame.tutorials )
|
|
{
|
|
// we are not doing tutorial mode so then play the main freerun vo
|
|
self playlocalsound( "vox_tuto_tutorial_sequence_27" );
|
|
}
|
|
|
|
level.FRGame.lastPlayedFaultVOCheckpoint = -1;
|
|
|
|
level.FRGame.activeTrackIndex = trackIndex;
|
|
level.FRGame.activeTrack = level.FRGame.tracks[trackIndex];
|
|
level.FRGame.activeSpawnPoint = level.FRGame.activeTrack.playerStart;
|
|
level.FRGame.activeSpawnLocation = level.FRGame.activeTrack.playerStart.origin;
|
|
level.FRGame.activeSpawnAngles = level.FRGame.activeTrack.playerStart.angles;
|
|
level.FRGame.activeTrack.goalTrigger thread watchGoalTrigger();
|
|
level.FRGame.activeSpawnPoint.checkpointIndex = 0;
|
|
|
|
level.FRGame.faults = 0;
|
|
level.FRGame.userSpawns = 0;
|
|
level.FRGame.checkpointTimes = [];
|
|
foreach( index, trigger in level.FRGame.checkpointTriggers )
|
|
{
|
|
level.FRGame.checkpointTimes[index] = 0;
|
|
}
|
|
|
|
level clientfield::set( "freerun_faults", 0 );
|
|
level clientfield::set( "freerun_retries", 0 );
|
|
level clientfield::set( "freerun_state", 0 );
|
|
level clientfield::set( "freerun_bulletPenalty", 0 );
|
|
level clientfield::set( "freerun_pausedTime", 0 );
|
|
level clientfield::set( "freerun_checkpointIndex", 0 );
|
|
|
|
self readHighScores();
|
|
|
|
self giveCustomLoadout();
|
|
self SetOrigin( level.FRGame.activeTrack.playerStart.origin );
|
|
self SetPlayerAngles( level.FRGame.activeTrack.playerStart.angles );
|
|
self SetVelocity( (0,0,0) );
|
|
self RecordGameEvent( "start" );
|
|
|
|
ResetGlass();
|
|
reset_all_targets();
|
|
pickup_items::respawn_all_pickups();
|
|
|
|
self unfreeze();
|
|
self.respawn_position = undefined;
|
|
|
|
enable_all_tutorial_triggers();
|
|
take_players_out_of_tutorial_mode();
|
|
|
|
level.FRGame.activeTrack.startTrigger thread watchStartRun( self );
|
|
}
|
|
|
|
function startRun() // self == player
|
|
{
|
|
level.FRGame.totalPausedTime = 0;
|
|
level.FRGame.pausedAtTime = 0;
|
|
level.FRGame.bulletPenalty = 0;
|
|
level.FRGame.hasBeenPaused = false;
|
|
level.FRGame.trackStartTime = 0;
|
|
level.FRGame.trackStartTime = get_current_track_time( self );
|
|
|
|
level clientfield::set( "freerun_startTime", level.FRGame.trackStartTime );
|
|
level clientfield::set( "freerun_state", 1 );
|
|
|
|
self playsoundtoplayer( "uin_freerun_start", self );
|
|
|
|
self thread watchUserRespawn();
|
|
}
|
|
|
|
function onCheckpointTrigger( player, endOnString ) // self == trigger
|
|
{
|
|
self endon( endOnString );
|
|
|
|
level.FRGame.activeSpawnLocation = getGroundPointForOrigin( player.origin );
|
|
level.FRGame.activeSpawnAngles = player.angles;
|
|
|
|
if ( level.FRGame.activeSpawnPoint != self )
|
|
{
|
|
level.FRGame.activeSpawnPoint = self;
|
|
|
|
player take_all_player_weapons( false, false );
|
|
|
|
if ( IsDefined(self.weaponObject) )
|
|
{
|
|
self.weaponObject reset_targets();
|
|
self.weaponObject pickup_items::respawn_pickup();
|
|
}
|
|
}
|
|
}
|
|
|
|
function leaveCheckpointTrigger( player ) // self == trigger
|
|
{
|
|
self thread watchCheckpointTrigger();
|
|
}
|
|
|
|
function get_current_track_time( player ) // self == checkpoint trigger
|
|
{
|
|
curtime = GetTime();
|
|
dt = curtime - player.prev_time;
|
|
|
|
frac = getfirsttouchfraction( player, self, player.prev_origin, player.origin );
|
|
|
|
current_time = (curtime - level.FRGame.trackStartTime + (level.FRGame.bulletPenalty * 1000) + (level.FRGame.userSpawns * 5000) - level.FRGame.totalPausedTime);
|
|
|
|
return int(current_time - dt * ( 1 - frac ));
|
|
}
|
|
|
|
function watchCheckpointTrigger() // self == checkpoint trigger
|
|
{
|
|
self waittill( "trigger", player );
|
|
|
|
if ( IsPlayer( player ))
|
|
{
|
|
if ( level.FRGame.activeSpawnPoint != self )
|
|
{
|
|
checkpoint_index = self.checkpointIndex;
|
|
|
|
current_time = get_current_track_time( player );
|
|
|
|
first_time = false;
|
|
|
|
// make sure we dont double set this if they go backwards
|
|
if ( !IsDefined( level.FRGame.checkpointTimes[ checkpoint_index ] ) || level.FRGame.checkpointTimes[ checkpoint_index ] == 0 )
|
|
{
|
|
level.FRGame.checkpointTimes[ checkpoint_index ] = current_time;
|
|
first_time = true;
|
|
}
|
|
|
|
if ( first_time )
|
|
{
|
|
if ( IsDefined( level.FRGame.activeTrack.fastestRunCheckpointTimes ) )
|
|
{
|
|
if ( IsDefined( level.FRGame.activeTrack.fastestRunCheckpointTimes[checkpoint_index] ) && level.FRGame.activeTrack.fastestRunCheckpointTimes[checkpoint_index] )
|
|
{
|
|
delta_time = current_time - level.FRGame.activeTrack.fastestRunCheckpointTimes[checkpoint_index];
|
|
|
|
if ( delta_time < 0 )
|
|
{
|
|
delta_time = -delta_time;
|
|
sign = 1;
|
|
}
|
|
else
|
|
{
|
|
sign = 0;
|
|
}
|
|
|
|
level clientfield::set( "freerun_timeAdjustment", delta_time );
|
|
level clientfield::set( "freerun_timeAdjustmentNegative", sign );
|
|
}
|
|
|
|
|
|
}
|
|
|
|
//Set the checkpoint index to one above the actual checkpoint index in order to update on the first checkpoint ( 0 ), as
|
|
//Clientfields can't handle negative numbers.
|
|
level clientfield::set( "freerun_checkpointIndex", checkpoint_index + 1 );
|
|
player playsoundtoplayer( "uin_freerun_checkpoint", player );
|
|
}
|
|
}
|
|
self thread util::trigger_thread( player, &onCheckpointTrigger, &leaveCheckpointTrigger );
|
|
}
|
|
}
|
|
|
|
function watchDeathTrigger() // self == death trigger
|
|
{
|
|
while( true )
|
|
{
|
|
self waittill( "trigger", player );
|
|
|
|
if ( IsPlayer( player ))
|
|
{
|
|
player faultDeath();
|
|
}
|
|
}
|
|
}
|
|
|
|
function add_current_run_to_high_scores(player)
|
|
{
|
|
active_track = level.FRGame.activeTrack;
|
|
|
|
run_data = create_high_score_struct( get_current_track_time( player ), level.FRGame.faults, level.FRGame.userSpawns, level.FRGame.bulletPenalty );
|
|
|
|
push_score = true;
|
|
new_record = false;
|
|
|
|
if ( active_track.highScores.size > 0 )
|
|
{
|
|
for ( i = 0; i < active_track.highScores.size; i++ )
|
|
{
|
|
if ( (run_data.time < active_track.highScores[i].time) || (active_track.highScores[i].time == 0) )
|
|
{
|
|
push_score = false;
|
|
|
|
ArrayInsert( active_track.highScores, run_data, i );
|
|
|
|
if ( i == 0 )
|
|
{
|
|
new_record = true;
|
|
}
|
|
|
|
if ( i < 3 )
|
|
{
|
|
player write_high_scores_stats(i);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
new_record = true;
|
|
}
|
|
|
|
if ( push_score )
|
|
{
|
|
ArrayInsert( active_track.highScores, run_data, active_track.highScores.size );
|
|
player write_high_scores_stats( active_track.highScores.size - 1 );
|
|
}
|
|
|
|
if ( new_record )
|
|
{
|
|
player write_checkpoint_times();
|
|
}
|
|
|
|
return new_record;
|
|
}
|
|
|
|
function watchGoalTrigger() // self == goal trigger
|
|
{
|
|
level notify( "watch_goal_trigger" );
|
|
level endon( "watch_goal_trigger" );
|
|
|
|
self waittill( "trigger", player );
|
|
|
|
if ( IsPlayer( player ))
|
|
{
|
|
player playsoundtoplayer( "uin_freerun_finish", player );
|
|
|
|
player take_all_player_weapons( true, false );
|
|
|
|
new_record = add_current_run_to_high_scores(player);
|
|
|
|
// if ( new_record )
|
|
// {
|
|
// if ( level.FRGame.activeTrack.highScores.size > 1 )
|
|
// {
|
|
// level thread popups::DisplayTeamMessageToAll( &"OBJECTIVES_FR_NEW_RECORD", player );
|
|
// }
|
|
// }
|
|
|
|
tracksCompleted = player getDStat( "freerunTracksCompleted" );
|
|
|
|
if ( tracksCompleted < level.FRGame.trackIndex )
|
|
{
|
|
player setDStat( "freerunTracksCompleted", level.FRGame.trackIndex );
|
|
}
|
|
|
|
player RecordGameEvent( "completion" );
|
|
|
|
player.respawn_position = self.origin;
|
|
player thread freeze();
|
|
player thread freerunMusic(false);
|
|
player updateHighScores();
|
|
level clientfield::set( "freerun_finishTime", get_current_track_time( player ) );
|
|
level clientfield::set( "freerun_state", 2 );
|
|
level notify( "finished_track" );
|
|
|
|
// this profile setting will not work if someone can play on a remote server
|
|
if ( player IsHost() )
|
|
{
|
|
level notify("stop_tutorials");
|
|
take_players_out_of_tutorial_mode();
|
|
level.FRGame.tutorials = false;
|
|
SetLocalProfileVar( "com_firsttime_freerun", 1 );
|
|
|
|
highest_track = GetLocalProfileInt( "freerunHighestTrack" );
|
|
|
|
if ( highest_track < level.FRGame.trackIndex )
|
|
{
|
|
SetLocalProfileVar( "freerunHighestTrack", level.FRGame.trackIndex );
|
|
}
|
|
}
|
|
|
|
/#DumpHighScores();#/
|
|
|
|
wait(1.5);
|
|
|
|
UploadStats();
|
|
player uploadleaderboards();
|
|
|
|
level clientfield::set( "freerun_state", 5 );
|
|
}
|
|
}
|
|
|
|
function freeze()
|
|
{
|
|
self util::freeze_player_controls( true );
|
|
}
|
|
|
|
function unfreeze()
|
|
{
|
|
self util::freeze_player_controls( false );
|
|
}
|
|
|
|
function setup_weapon_targets() // self == checkpoint
|
|
{
|
|
target_name = self.weaponObject.visuals[0].target;
|
|
if ( !IsDefined(target_name) )
|
|
return;
|
|
|
|
self.weaponObject.targetShotTime = 0;
|
|
self.weaponObject.targets = [];
|
|
self.weaponObject.target_visuals = [];
|
|
|
|
targets = GetEntArray( target_name, "targetname" );
|
|
foreach( target in targets )
|
|
{
|
|
if ( target.script_noteworthy == "fr_target" )
|
|
{
|
|
self.weaponObject.targets[self.weaponObject.targets.size] = target;
|
|
}
|
|
if ( target.script_noteworthy == "fr_target_visual" )
|
|
{
|
|
self.weaponObject.target_visuals[self.weaponObject.target_visuals.size] = target;
|
|
}
|
|
}
|
|
|
|
foreach ( target in self.weaponObject.targets )
|
|
{
|
|
foreach( visual in self.weaponObject.target_visuals )
|
|
{
|
|
if ( target.origin == visual.origin )
|
|
{
|
|
target.visual = visual;
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach ( target in self.weaponObject.targets )
|
|
{
|
|
target.blocker = GetEnt( target.target, "targetname" );
|
|
if ( IsDefined( target.blocker ) )
|
|
{
|
|
if ( !isdefined( target.blocker.targetCount ) )
|
|
{
|
|
target.blocker.targetCount = 0;
|
|
target.blocker.activeTargetCount = 0;
|
|
}
|
|
|
|
target.blocker.targetCount++;
|
|
target.blocker.activeTargetCount++;
|
|
|
|
target.checkPoint = self;
|
|
target.disabled = false;
|
|
target thread watch_target_trigger_thread(self.weaponObject);
|
|
}
|
|
}
|
|
}
|
|
|
|
function watch_target_trigger_thread( weaponObject )
|
|
{
|
|
self endon( "death" );
|
|
|
|
while(1)
|
|
{
|
|
self waittill ( "damage", damage, attacker, direction_vec, point, type, modelName, tagName, partName, weapon, iDFlags );
|
|
|
|
if ( level.FRGame.activeSpawnPoint != self.checkPoint )
|
|
continue;
|
|
|
|
if ( weapon == level.weaponBaseMeleeHeld )
|
|
continue;
|
|
|
|
if ( self.disabled )
|
|
continue;
|
|
|
|
self turn_off_target(weapon);
|
|
|
|
PlayFx( level.fr_target_impact_fx, point, direction_vec );
|
|
weaponObject.targetShotTime = GetTime();
|
|
}
|
|
}
|
|
|
|
function turn_off_target(weapon)
|
|
{
|
|
self.disabled = true;
|
|
self.visual ghost(); // this will still stop bullet collision with ghost
|
|
self.visual notsolid();
|
|
|
|
self.blocker blocker_disable();
|
|
|
|
Playfx( level.fr_target_disable_fx, self.origin );
|
|
PlaySoundAtPosition( level.fr_target_disable_sound, self.origin );
|
|
}
|
|
|
|
function blocker_enable()
|
|
{
|
|
self.activeTargetCount = self.targetCount;
|
|
|
|
self.disabled = false;
|
|
self show();
|
|
self solid();
|
|
}
|
|
|
|
function blocker_disable()
|
|
{
|
|
self.activeTargetCount--;
|
|
|
|
if ( self.activeTargetCount == 0 )
|
|
{
|
|
self.disabled = true;
|
|
self ghost();
|
|
self notsolid();
|
|
}
|
|
}
|
|
|
|
function reset_targets()
|
|
{
|
|
foreach ( target in self.targets )
|
|
{
|
|
target.blocker blocker_enable();
|
|
target.visual show();
|
|
target.visual solid();
|
|
target.disabled = false;
|
|
}
|
|
}
|
|
|
|
function reset_all_targets()
|
|
{
|
|
foreach( trigger in level.FRGame.checkpointTriggers )
|
|
{
|
|
if ( IsDefined( trigger.weaponObject ) )
|
|
{
|
|
trigger.weaponObject reset_targets();
|
|
}
|
|
}
|
|
}
|
|
|
|
/#
|
|
function DumpHighScores()
|
|
{
|
|
for ( i = 0; i < level.FRGame.activeTrack.highScores.size; i++ )
|
|
{
|
|
println( ( i + 1 ) + ": " + level.FRGame.activeTrack.highScores[i].time );
|
|
|
|
if ( i == 0 )
|
|
{
|
|
for ( j = 0; j < level.FRGame.activeTrack.fastestRunCheckpointTimes.size; j++ )
|
|
{
|
|
println( "CP" + j + ": " + level.FRGame.activeTrack.fastestRunCheckpointTimes[ j ] );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#/
|
|
|
|
function play_fault_VO()
|
|
{
|
|
current_time = GetTime();
|
|
fault_vo_interval = 20000;
|
|
|
|
if ( current_time - level.FRGame.lastPlayedFaultVOTime < fault_vo_interval )
|
|
return;
|
|
|
|
if ( isdefined( self.lastTutorialVOPlayed ) )
|
|
return;
|
|
|
|
if ( level.FRGame.lastPlayedFaultVOCheckpoint == level.FRGame.activeSpawnPoint.checkpointIndex )
|
|
return;
|
|
|
|
level.FRGame.lastPlayedFaultVOCheckpoint = level.FRGame.activeSpawnPoint.checkpointIndex;
|
|
level.FRGame.lastPlayedFaultVOTime = current_time;
|
|
self playlocalsound( "vox_tuto_tutorial_fail" );
|
|
}
|
|
|
|
function faultDeath() // self == player
|
|
{
|
|
self play_fault_VO();
|
|
|
|
// do the fall deaths increase time in trials?
|
|
level.FRGame.faults++;
|
|
self RecordGameEvent( "fault" );
|
|
level clientfield::set( "freerun_faults", level.FRGame.faults );
|
|
self playsoundtoplayer( "uin_freerun_reset", self );
|
|
self respawnAtActiveCheckpoint();
|
|
}
|
|
|
|
function dpad_up_pressed()
|
|
{
|
|
return self ActionSlotOneButtonPressed();
|
|
}
|
|
|
|
function dpad_down_pressed()
|
|
{
|
|
return self ActionSlotTwoButtonPressed();
|
|
}
|
|
|
|
function dpad_right_pressed()
|
|
{
|
|
return self ActionSlotFourButtonPressed();
|
|
}
|
|
|
|
function dpad_left_pressed()
|
|
{
|
|
return self ActionSlotThreeButtonPressed();
|
|
}
|
|
|
|
function end_game_state()
|
|
{
|
|
state = level clientfield::get( "freerun_state" );
|
|
if ( state == 2 || state == 4 || state == 5 )
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
function watchTrackSwitch() // self == player
|
|
{
|
|
track_count = level.FRGame.tracks.size;
|
|
|
|
while( true )
|
|
{
|
|
wait .05;
|
|
|
|
switch_track = false;
|
|
|
|
if ( end_game_state() )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
/#
|
|
if ( self dpad_right_pressed() && track_count > 1 )
|
|
{
|
|
switch_track = true;
|
|
curr_track_index = level.FRGame.activeTrackIndex;
|
|
curr_track_index++;
|
|
}
|
|
else if ( self dpad_left_pressed() && track_count > 1 )
|
|
{
|
|
switch_track = true;
|
|
curr_track_index = level.FRGame.activeTrackIndex;
|
|
curr_track_index--;
|
|
}
|
|
#/
|
|
if ( !switch_track && self dpad_up_pressed())
|
|
{
|
|
switch_track = true;
|
|
curr_track_index = level.FRGame.activeTrackIndex;
|
|
self thread freerunMusic();
|
|
}
|
|
|
|
if ( switch_track )
|
|
{
|
|
if ( curr_track_index == 1 )
|
|
{
|
|
curr_track_index = 0;
|
|
}
|
|
else if ( curr_track_index < 0 )
|
|
{
|
|
curr_track_index = 1 - 1;
|
|
}
|
|
|
|
self playsoundtoplayer( "uin_freerun_reset", self );
|
|
activateTrack( curr_track_index );
|
|
|
|
while ( true )
|
|
{
|
|
wait .05;
|
|
|
|
if (!( self dpad_right_pressed() || self dpad_left_pressed() || self dpad_up_pressed() ))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function watchUserRespawn() // self == player
|
|
{
|
|
level endon( "activate_track" );
|
|
level endon( "finished_track" );
|
|
|
|
/#
|
|
wasinnoclip = false;
|
|
#/
|
|
while( true )
|
|
{
|
|
wait .05;
|
|
|
|
if ( end_game_state() )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
/#
|
|
if ( self IsInMoveMode( "noclip" ))
|
|
{
|
|
wasinnoclip = true;
|
|
continue;
|
|
}
|
|
if ( wasinnoclip && self dpad_down_pressed() )
|
|
{
|
|
continue;
|
|
}
|
|
wasinnoclip = false;
|
|
#/
|
|
|
|
if ( self dpad_down_pressed() )
|
|
{
|
|
level.FRGame.userSpawns++;
|
|
self RecordGameEvent( "retry" );
|
|
level clientfield::set( "freerun_retries", level.FRGame.userSpawns );
|
|
self playsoundtoplayer( "uin_freerun_reset", self );
|
|
self respawnAtActiveCheckpoint();
|
|
|
|
while ( true )
|
|
{
|
|
wait .05;
|
|
|
|
if (!( self dpad_down_pressed() ))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function ignoreBulletsFired(weapon)
|
|
{
|
|
if ( !IsDefined(level.FRGame.activespawnpoint) )
|
|
return false;
|
|
|
|
if ( !IsDefined(level.FRGame.activespawnpoint.weaponobject) )
|
|
return false;
|
|
|
|
grace_period = (weapon.fireTime * 4) * 1000;
|
|
|
|
if ( (level.FRGame.activespawnpoint.weaponobject.targetShotTime + grace_period) >= GetTime() )
|
|
return true;
|
|
|
|
foreach( target in level.FRGame.activespawnpoint.weaponobject.targets )
|
|
{
|
|
if ( !target.disabled )
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
function watchWeaponFire() // self == player
|
|
{
|
|
self endon("disconnect");
|
|
|
|
while(1)
|
|
{
|
|
self waittill( "weapon_fired", weapon );
|
|
|
|
if ( weapon == level.weaponBaseMeleeHeld )
|
|
continue;
|
|
|
|
if ( ignoreBulletsFired(weapon) )
|
|
continue;
|
|
|
|
level.FRGame.bulletPenalty++;
|
|
level clientfield::set( "freerun_bulletPenalty", level.FRGame.bulletPenalty );
|
|
}
|
|
}
|
|
|
|
function getGroundPointForOrigin( position )
|
|
{
|
|
trace = BulletTrace( position + (0,0,10), position - (0,0,1000), false, undefined );
|
|
return trace["position"];
|
|
}
|
|
|
|
function watchStartRun( player ) // self == start trigger
|
|
{
|
|
level endon( "activate_track" );
|
|
|
|
self waittill( "trigger", trigger_ent );
|
|
|
|
if ( trigger_ent == player )
|
|
{
|
|
player startRun();
|
|
}
|
|
}
|
|
|
|
function respawnAtActiveCheckpoint() // self == player
|
|
{
|
|
ResetGlass();
|
|
reset_all_targets();
|
|
pickup_items::respawn_all_pickups();
|
|
take_players_out_of_tutorial_mode();
|
|
|
|
self playsoundtoplayer( "evt_freerun_respawn", self );
|
|
|
|
if ( IsDefined( self.respawn_position ) )
|
|
{
|
|
self SetOrigin( self.respawn_position );
|
|
self SetVelocity( (0,0,0) );
|
|
}
|
|
else if ( IsDefined( level.FRGame.activeSpawnPoint.spawnPoint ))
|
|
{
|
|
self SetOrigin( level.FRGame.activeSpawnPoint.spawnPoint.origin );
|
|
self SetPlayerAngles( level.FRGame.activeSpawnPoint.spawnPoint.angles );
|
|
self SetVelocity( (0,0,0) );
|
|
}
|
|
else
|
|
{
|
|
// no spawn point for the track start triggers
|
|
spawn_origin = level.FRGame.activeSpawnLocation;
|
|
spawn_origin += ( 0,0, 5.0 );
|
|
|
|
self SetOrigin( spawn_origin );
|
|
self SetPlayerAngles( level.FRGame.activeSpawnAngles );
|
|
self SetVelocity( (0,0,0) );
|
|
}
|
|
|
|
self setdoublejumpenergy( 1.0 );
|
|
self take_all_player_weapons( true, true );
|
|
}
|
|
|
|
function giveCustomLoadout()
|
|
{
|
|
self TakeAllWeapons();
|
|
self clearPerks();
|
|
|
|
self SetPerk( "specialty_fallheight" );
|
|
|
|
self GiveWeapon( level.weaponBaseMeleeHeld );
|
|
self setSpawnWeapon( level.weaponBaseMeleeHeld );
|
|
|
|
return level.weaponBaseMeleeHeld;
|
|
}
|
|
|
|
function set_high_score_stat( trackIndex, slot, stat, value )
|
|
{
|
|
self setDStat( "freerunTrackTimes", "track", trackIndex, "topTimes", slot, stat, value );
|
|
}
|
|
|
|
function write_high_scores_stats(start_index)
|
|
{
|
|
active_track = level.FRGame.activeTrack;
|
|
|
|
self setDStat( "freerunTrackTimes", "track", level.FRGame.trackIndex, "mapUniqueId", level.FRGame.mapUniqueId );
|
|
self setDStat( "freerunTrackTimes", "track", level.FRGame.trackIndex, "mapVersion", level.FRGame.mapVersion );
|
|
|
|
for ( slot = start_index; slot < 3; slot++ )
|
|
{
|
|
set_high_score_stat( level.FRGame.trackIndex, slot, "time", active_track.highScores[slot].time );
|
|
set_high_score_stat( level.FRGame.trackIndex, slot, "faults", active_track.highScores[slot].faults );
|
|
set_high_score_stat( level.FRGame.trackIndex, slot, "retries", active_track.highScores[slot].retries );
|
|
set_high_score_stat( level.FRGame.trackIndex, slot, "bulletPenalty", active_track.highScores[slot].bulletPenalty );
|
|
}
|
|
}
|
|
|
|
function write_checkpoint_times()
|
|
{
|
|
level.FRGame.activeTrack.fastestRunCheckpointTimes = level.FRGame.checkpointTimes;
|
|
|
|
for ( i = 0; i < level.FRGame.checkpointTriggers.size; i++ )
|
|
{
|
|
self setDStat( "freerunTrackTimes", "track", level.FRGame.trackIndex, "checkPointTimes", "time", i, level.FRGame.checkpointTimes[i] );
|
|
}
|
|
}
|
|
|
|
function get_high_score_stat( trackIndex, slot, stat )
|
|
{
|
|
return (self getDStat( "freerunTrackTimes", "track", trackIndex, "topTimes", slot, stat ));
|
|
}
|
|
|
|
function create_high_score_struct( time, faults, retries, bulletPenalty ) // self == player
|
|
{
|
|
score_set = SpawnStruct();
|
|
|
|
score_set.time = time;
|
|
score_set.faults = faults;
|
|
score_set.retries = retries;
|
|
score_set.bulletPenalty = bulletPenalty;
|
|
|
|
return score_set;
|
|
}
|
|
|
|
function get_stats_for_track( trackIndex, slot ) // self == player
|
|
{
|
|
time = self get_high_score_stat( trackIndex, slot, "time" );
|
|
faults = self get_high_score_stat( trackIndex, slot, "faults" );
|
|
retries = self get_high_score_stat( trackIndex, slot, "retries" );
|
|
bulletPenalty = self get_high_score_stat( trackIndex, slot, "bulletPenalty" );
|
|
|
|
return create_high_score_struct( time, faults, retries, bulletPenalty);
|
|
}
|
|
|
|
function get_checkpoint_times_for_track( trackIndex ) // self == player
|
|
{
|
|
for ( i = 0; i < level.FRGame.checkpointTriggers.size; i++ )
|
|
{
|
|
level.FRGame.activeTrack.fastestRunCheckpointTimes[i] = self getDStat( "freerunTrackTimes", "track", trackIndex, "checkPointTimes", "time", i );
|
|
}
|
|
}
|
|
|
|
function get_top_scores_stats()
|
|
{
|
|
if ( isdefined(level.FRGame.activeTrack.statsRead) )
|
|
return;
|
|
|
|
mapId = self getDStat( "freerunTrackTimes", "track", level.FRGame.trackIndex, "mapUniqueId" );
|
|
mapVersion = self getDStat( "freerunTrackTimes", "track", level.FRGame.trackIndex, "mapVersion" );
|
|
|
|
if ( level.FRGame.mapUniqueId != mapId || level.FRGame.mapVersion != mapVersion )
|
|
{
|
|
for( i = 0; i < 3; i++ )
|
|
{
|
|
level.FRGame.activeTrack.highScores[i] = create_high_score_struct( 0,0,0,0 );
|
|
}
|
|
for ( i = 0; i < level.FRGame.checkpointTriggers.size; i++ )
|
|
{
|
|
level.FRGame.activeTrack.fastestRunCheckpointTimes[i] = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for( i = 0; i < 3; i++ )
|
|
{
|
|
level.FRGame.activeTrack.highScores[i] = get_stats_for_track( level.FRGame.trackIndex, i );
|
|
}
|
|
get_checkpoint_times_for_track(level.FRGame.trackIndex);
|
|
}
|
|
|
|
level.FRGame.activeTrack.statsRead = true;
|
|
}
|
|
|
|
function take_all_player_weapons( only_default, immediate ) // self == player
|
|
{
|
|
self endon("disconnect");
|
|
self endon("death");
|
|
|
|
keep_weapon = level.weaponNone;
|
|
if ( isDefined(level.FRGame.activeSpawnPoint.weapon) && !only_default )
|
|
{
|
|
keep_weapon = level.FRGame.activeSpawnPoint.weapon;
|
|
}
|
|
|
|
if ( immediate )
|
|
{
|
|
self switchtoweaponimmediate(level.weaponBaseMeleeHeld);
|
|
}
|
|
else
|
|
{
|
|
while ( self isswitchingweapons() )
|
|
{
|
|
wait(0.05);
|
|
}
|
|
|
|
current_weapon = self GetCurrentWeapon();
|
|
|
|
if ( current_weapon != level.weaponBaseMeleeHeld && keep_weapon != current_weapon )
|
|
{
|
|
self SwitchToWeapon(level.weaponBaseMeleeHeld);
|
|
while( self GetCurrentWeapon() != level.weaponBaseMeleeHeld )
|
|
{
|
|
wait(0.05);
|
|
}
|
|
}
|
|
}
|
|
|
|
weaponsList = self GetWeaponsList();
|
|
foreach( weapon in weaponsList )
|
|
{
|
|
if ( weapon != level.weaponBaseMeleeHeld && keep_weapon != weapon )
|
|
self TakeWeapon( weapon );
|
|
}
|
|
}
|
|
|
|
function freerunMusic(start=true)
|
|
{
|
|
player = self;
|
|
|
|
if( start && !( isdefined( player.musicStart ) && player.musicStart ) )
|
|
{
|
|
mapname = GetDvarString( "mapname" );
|
|
player globallogic_audio::set_music_on_player( mapname );
|
|
player.musicStart = true;
|
|
}
|
|
else if( !start )
|
|
{
|
|
player globallogic_audio::set_music_on_player( "mp_freerun_finish" );
|
|
player.musicStart = false;
|
|
}
|
|
}
|
|
|
|
function _tutorial_mode( b_tutorial_mode )
|
|
{
|
|
// self SetLowReady( b_tutorial_mode );
|
|
// self AllowDoubleJump( !b_tutorial_mode );
|
|
// self AllowJump( !b_tutorial_mode );
|
|
// self AllowSprint( !b_tutorial_mode );
|
|
}
|
|
|
|
function take_players_out_of_tutorial_mode()
|
|
{
|
|
if ( level.FRGame.tutorials )
|
|
{
|
|
if ( ( level clientfield::get( "freerun_state" ) ) == 3 )
|
|
{
|
|
// level.FRGame.totalPausedTime += GetTime() - level.FRGame.pausedAtTime;
|
|
// level.FRGame.pausedAtTime = 0;
|
|
// level clientfield::set( "freerun_pausedTime", level.FRGame.totalPausedTime );
|
|
// level clientfield::set( "freerun_state", FR_STATE_RUNNING );
|
|
}
|
|
|
|
foreach( player in level.players )
|
|
{
|
|
player _tutorial_mode( false );
|
|
}
|
|
}
|
|
}
|
|
|
|
function put_players_in_tutorial_mode()
|
|
{
|
|
if ( level.FRGame.tutorials )
|
|
{
|
|
if ( ( level clientfield::get( "freerun_state" ) ) == 1 )
|
|
{
|
|
// level.FRGame.hasBeenPaused = true;
|
|
// level.FRGame.pausedAtTime = GetTime();
|
|
// level clientfield::set( "freerun_state", FR_STATE_PAUSED );
|
|
}
|
|
|
|
foreach( player in level.players )
|
|
{
|
|
player _tutorial_mode( true );
|
|
}
|
|
}
|
|
}
|
|
|
|
function enable_all_tutorial_triggers()
|
|
{
|
|
if ( level.FRGame.tutorials )
|
|
{
|
|
foreach( trigger in level.FRGame.tutorialTriggers )
|
|
{
|
|
trigger TriggerEnable( true );
|
|
}
|
|
}
|
|
}
|
|
|
|
function activate_tutorial_mode()
|
|
{
|
|
// profile var will be 0 if never run before
|
|
// this profile setting will not work if someone can play on a remote server
|
|
if ( (!(self IsHost()) || GetLocalProfileInt( "com_firsttime_freerun" )) && !GetDvarInt( "freerun_tutorial" ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
level.FRGame.tutorials = true;
|
|
|
|
wait(1);
|
|
|
|
foreach( trigger in level.FRGame.tutorialTriggers )
|
|
{
|
|
trigger thread watchTutorialTrigger();
|
|
}
|
|
|
|
}
|
|
|
|
function setup_tutorial()
|
|
{
|
|
level.FRGame.tutorials = false;
|
|
|
|
level.FRGame.tutorialTriggers = GetEntArray( "fr_tutorial", "targetname" );
|
|
|
|
level.FRGame.tutorialFunctions = [];
|
|
|
|
register_tutorials();
|
|
}
|
|
|
|
function watchTutorialTrigger()
|
|
{
|
|
level endon("stop_tutorials");
|
|
|
|
while( true )
|
|
{
|
|
self waittill( "trigger", player );
|
|
|
|
if ( IsPlayer( player ))
|
|
{
|
|
player thread start_tutorial(self.script_noteworthy);
|
|
self TriggerEnable( false );
|
|
}
|
|
}
|
|
}
|
|
|
|
function stop_tutorial_when_restarting_track()
|
|
{
|
|
self notify("stop_tutorial_when_restarting_track");
|
|
self waittill("stop_tutorial_when_restarting_track");
|
|
|
|
level waittill( "activate_track" );
|
|
|
|
take_players_out_of_tutorial_mode();
|
|
self util::hide_hint_text(false);
|
|
|
|
self stop_tutorial_vo();
|
|
self stopsounds();
|
|
}
|
|
|
|
function start_tutorial( tutorial )
|
|
{
|
|
self endon("death");
|
|
self endon("disconnect");
|
|
level endon( "game_ended" );
|
|
level endon( "activate_track" );
|
|
if (!isdefined(level.FRGame.tutorialFunctions[tutorial]))
|
|
return;
|
|
|
|
level notify( "playing_tutorial" );
|
|
level endon( "playing_tutorial" );
|
|
|
|
self thread stop_tutorial_when_restarting_track();
|
|
|
|
put_players_in_tutorial_mode();
|
|
wait( 0.5 );
|
|
[[level.FRGame.tutorialFunctions[tutorial]]]();
|
|
take_players_out_of_tutorial_mode();
|
|
}
|
|
|
|
function stop_tutorial_vo()
|
|
{
|
|
if ( isdefined( self.lastTutorialVOPlayed ) )
|
|
{
|
|
self stopsound(self.lastTutorialVOPlayed);
|
|
self.lastTutorialVOPlayed = undefined;
|
|
}
|
|
}
|
|
|
|
function play_tutorial_vo( aliasstring )
|
|
{
|
|
self stop_tutorial_vo();
|
|
|
|
self.lastTutorialVOPlayed = aliasstring;
|
|
self playsoundwithnotify( aliasstring, "sounddone" );
|
|
self waittill( "sounddone");
|
|
wait( 1.0 );
|
|
}
|
|
|
|
function play_tutorial_vo_with_hint( aliasstring, text )
|
|
{
|
|
self stop_tutorial_vo();
|
|
|
|
self thread _show_tutorial_hint_with_vo( text );
|
|
|
|
self.lastTutorialVOPlayed = aliasstring;
|
|
self playsoundwithnotify( aliasstring, "sounddone" );
|
|
self waittill( "sounddone");
|
|
wait( 1.0 );
|
|
}
|
|
|
|
function _show_tutorial_hint_with_vo( text, time, unlock_player )
|
|
{
|
|
wait (0.5);
|
|
show_tutorial_hint( text, time, unlock_player );
|
|
}
|
|
|
|
function show_tutorial_hint( text, time, unlock_player )
|
|
{
|
|
if ( isdefined( unlock_player ) )
|
|
{
|
|
take_players_out_of_tutorial_mode();
|
|
}
|
|
|
|
if (!isdefined(time) )
|
|
{
|
|
time = 4.0;
|
|
}
|
|
self util::show_hint_text( text, false, "activate_track", 4.0);
|
|
wait( 4.0 + 0.5);
|
|
}
|
|
|
|
function show_tutorial_hint_with_full_movement( text, time )
|
|
{
|
|
show_tutorial_hint( text, time, true );
|
|
}
|
|
|
|
function register_tutorials()
|
|
{
|
|
level.FRGame.tutorialFunctions["tutorial_01"] = &tutorial_01;
|
|
level.FRGame.tutorialFunctions["tutorial_02"] = &tutorial_02;
|
|
level.FRGame.tutorialFunctions["tutorial_03"] = &tutorial_03;
|
|
//level.FRGame.tutorialFunctions["tutorial_03a"] = &tutorial_03a;
|
|
//level.FRGame.tutorialFunctions["tutorial_04"] = &tutorial_04;
|
|
//level.FRGame.tutorialFunctions["tutorial_05"] = &tutorial_05;
|
|
level.FRGame.tutorialFunctions["tutorial_06"] = &tutorial_06;
|
|
//level.FRGame.tutorialFunctions["tutorial_07"] = &tutorial_07;
|
|
level.FRGame.tutorialFunctions["tutorial_08"] = &tutorial_08;
|
|
level.FRGame.tutorialFunctions["tutorial_09"] = &tutorial_09;
|
|
level.FRGame.tutorialFunctions["tutorial_10"] = &tutorial_10;
|
|
level.FRGame.tutorialFunctions["tutorial_10a"] = &tutorial_10a;
|
|
level.FRGame.tutorialFunctions["tutorial_12"] = &tutorial_12;
|
|
level.FRGame.tutorialFunctions["tutorial_12a"] = &tutorial_12a;
|
|
level.FRGame.tutorialFunctions["tutorial_13"] = &tutorial_13;
|
|
//level.FRGame.tutorialFunctions["tutorial_13a"] = &tutorial_13a;
|
|
level.FRGame.tutorialFunctions["tutorial_14"] = &tutorial_14;
|
|
level.FRGame.tutorialFunctions["tutorial_15"] = &tutorial_15;
|
|
level.FRGame.tutorialFunctions["tutorial_16"] = &tutorial_16;
|
|
level.FRGame.tutorialFunctions["tutorial_17"] = &tutorial_17;
|
|
level.FRGame.tutorialFunctions["tutorial_17a"] = &tutorial_17a;
|
|
level.FRGame.tutorialFunctions["tutorial_18"] = &tutorial_18;
|
|
level.FRGame.tutorialFunctions["tutorial_19"] = &tutorial_19;
|
|
level.FRGame.tutorialFunctions["tutorial_20"] = &tutorial_20;
|
|
//level.FRGame.tutorialFunctions["tutorial_21"] = &tutorial_21;
|
|
//level.FRGame.tutorialFunctions["tutorial_22"] = &tutorial_22;
|
|
}
|
|
|
|
function tutorial_01()
|
|
{
|
|
self play_tutorial_vo( "vox_tuto_tutorial_sequence_1" );
|
|
self play_tutorial_vo( "vox_tuto_tutorial_sequence_2" );
|
|
self play_tutorial_vo( "vox_tuto_tutorial_sequence_6" );
|
|
}
|
|
|
|
function tutorial_02()
|
|
{
|
|
self show_tutorial_hint_with_full_movement( &"FREERUN_TUTORIAL_02" );
|
|
}
|
|
|
|
function tutorial_03()
|
|
{
|
|
self show_tutorial_hint_with_full_movement( &"FREERUN_TUTORIAL_03" );
|
|
}
|
|
|
|
function tutorial_06()
|
|
{
|
|
self thread play_tutorial_vo( "vox_tuto_tutorial_sequence_11" );
|
|
self show_tutorial_hint_with_full_movement( &"FREERUN_TUTORIAL_09" );
|
|
}
|
|
|
|
function tutorial_08()
|
|
{
|
|
self show_tutorial_hint_with_full_movement( &"FREERUN_TUTORIAL_11" );
|
|
}
|
|
|
|
function tutorial_09()
|
|
{
|
|
self play_tutorial_vo_with_hint( "vox_tuto_tutorial_sequence_28", &"FREERUN_TUTORIAL_12" );
|
|
}
|
|
|
|
function tutorial_10()
|
|
{
|
|
self play_tutorial_vo( "vox_tuto_tutorial_sequence_10" );
|
|
}
|
|
|
|
function tutorial_10a()
|
|
{
|
|
self show_tutorial_hint_with_full_movement( &"FREERUN_TUTORIAL_13" );
|
|
}
|
|
|
|
function tutorial_12()
|
|
{
|
|
self play_tutorial_vo( "vox_tuto_tutorial_sequence_16" );
|
|
}
|
|
|
|
function tutorial_12a()
|
|
{
|
|
self show_tutorial_hint_with_full_movement( &"FREERUN_TUTORIAL_14" );
|
|
}
|
|
|
|
function tutorial_13()
|
|
{
|
|
self play_tutorial_vo_with_hint( "vox_tuto_tutorial_sequence_17", &"FREERUN_TUTORIAL_14a" );
|
|
self play_tutorial_vo( "vox_tuto_tutorial_sequence_18" );
|
|
self show_tutorial_hint_with_full_movement( &"FREERUN_TUTORIAL_16" );
|
|
}
|
|
|
|
function tutorial_14()
|
|
{
|
|
self play_tutorial_vo( "vox_tuto_tutorial_sequence_19" );
|
|
self show_tutorial_hint_with_full_movement( &"FREERUN_TUTORIAL_18" );
|
|
}
|
|
|
|
function tutorial_15()
|
|
{
|
|
self play_tutorial_vo( "vox_tuto_tutorial_sequence_20" );
|
|
}
|
|
|
|
function tutorial_16()
|
|
{
|
|
self play_tutorial_vo( "vox_tuto_tutorial_sequence_29" );
|
|
}
|
|
|
|
function tutorial_17()
|
|
{
|
|
self play_tutorial_vo( "vox_tuto_tutorial_sequence_21" );
|
|
}
|
|
|
|
function tutorial_17a()
|
|
{
|
|
self show_tutorial_hint_with_full_movement( &"FREERUN_TUTORIAL_22" );
|
|
}
|
|
|
|
|
|
function tutorial_18()
|
|
{
|
|
self play_tutorial_vo_with_hint( "vox_tuto_tutorial_sequence_23", &"FREERUN_TUTORIAL_23" );
|
|
self show_tutorial_hint_with_full_movement( &"FREERUN_TUTORIAL_22a" );
|
|
}
|
|
|
|
function tutorial_19()
|
|
{
|
|
self play_tutorial_vo( "vox_tuto_tutorial_sequence_25" );
|
|
}
|
|
|
|
function tutorial_20()
|
|
{
|
|
self play_tutorial_vo( "vox_tuto_tutorial_sequence_26" );
|
|
} |