boiii-scripts/shared/scene_shared.gsc
2023-04-13 17:30:38 +02:00

6212 lines
156 KiB
Plaintext

/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// http://tawiki/display/Design/Scene+System /////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
#using scripts\codescripts\struct;
#using scripts\shared\ai_shared;
#using scripts\shared\animation_shared;
#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\laststand_shared;
#using scripts\shared\player_shared;
#using scripts\shared\scene_debug_shared;
#using scripts\shared\scriptbundle_shared;
#using scripts\shared\spawner_shared;
#using scripts\shared\system_shared;
#using scripts\shared\trigger_shared;
#using scripts\shared\util_shared;
#using scripts\shared\lui_shared;
#precache( "lui_menu", "CPSkipSceneMenu" );
#precache( "lui_menu_data", "showSkipButton" );
#precache( "lui_menu_data", "hostIsSkipping" );
#precache( "lui_menu_data", "sceneSkipEndTime" );
#namespace scene;
#using_animtree( "all_player" );
function private prepare_player_model_anim( ent )
{
if ( !( ent.animtree === "all_player" ) )
{
ent UseAnimTree( #animtree );
ent.animtree = "all_player";
}
}
#using_animtree( "generic" );
function private prepare_generic_model_anim( ent )
{
if ( !( ent.animtree === "generic" ) )
{
ent UseAnimTree( #animtree );
ent.animtree = "generic";
}
}
// Player weapon animation indexes defined in code
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ___ ___ ___ _ _ ___ ___ ___ _ ___ ___ _____
// / __| / __| | __| | \| | | __| / _ \ | _ ) _ | | | __| / __| |_ _|
// \__ \ | (__ | _| | .` | | _| | (_) | | _ \ | || | | _| | (__ | |
// |___/ \___| |___| |_|\_| |___| \___/ |___/ \__/ |___| \___| |_|
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class cSceneObject : cScriptBundleObjectBase
{
var _b_spawnonce_used;
var _is_valid;
var _str_name;
var _str_state;
var _player;
var _str_death_anim;
var _str_death_anim_loop;
var _b_set_goal;
constructor()
{
_is_valid = true;
_b_spawnonce_used = false;
_b_set_goal = true;
}
destructor()
{
}
function first_init( s_objdef, o_scene, e_ent )
{
cScriptBundleObjectBase::init( s_objdef, o_scene, e_ent );
_assign_unique_name();
return self;
}
function initialize( b_force_first_frame = false )
{
if ( has_init_state() || b_force_first_frame )
{
flagsys::clear( "ready" ); flagsys::clear( "done" ); flagsys::clear( "main_done" ); _str_state = "init"; self notify( "new_state" ); self endon( "new_state" ); self notify("init"); log( "init" ); waittillframeend;;
//Exclude the player since now need to spawn or init him.
if ( ( !( isdefined( _s.sharedIGC ) && _s.sharedIGC ) && !( isdefined( _s.player ) && _s.player ) ) && ( isdefined( _s.spawnoninit ) && _s.spawnoninit ) || b_force_first_frame )
{
_spawn( undefined, ( isdefined( _s.firstframe ) && _s.firstframe ) || isdefined( _s.initanim ) || isdefined( _s.initanimloop ) );
}
if ( ( isdefined( _s.firstframe ) && _s.firstframe ) || b_force_first_frame )
{
if ( !error( !isdefined( _s.mainanim ), "No animation defined for first frame." ) )
{
_str_death_anim = _s.mainanimdeath;
_str_death_anim_loop = _s.mainanimdeathloop;
_play_anim( _s.mainanim, 0, 0, 0 );
}
}
else if ( isdefined( _s.initanim ) )
{
_str_death_anim = _s.initanimdeath;
_str_death_anim_loop = _s.initanimdeathloop;
_play_anim( _s.initanim, _s.initdelaymin, _s.initdelaymax, 1 );
if ( is_alive() )
{
if ( isdefined( _s.initanimloop ) )
{
_str_death_anim = _s.initanimloopdeath;
_str_death_anim_loop = _s.initanimloopdeathloop;
_play_anim( _s.initanimloop, 0, 0, 1 );
}
}
}
else if ( isdefined( _s.initanimloop ) )
{
_str_death_anim = _s.initanimloopdeath;
_str_death_anim_loop = _s.initanimloopdeathloop;
_play_anim( _s.initanimloop, _s.initdelaymin, _s.initdelaymax, 1 );
}
}
else
{
flagsys::set( "ready" );
}
if ( !_is_valid )
{
flagsys::set( "done" );
}
}
function play()
{
/#
if( GetDvarInt("debug_scene") > 0)
{
if(isdefined(_s.name))
{
PrintTopRightln("csceneobject::play : " + _s.name);
}
else
{
PrintTopRightln("csceneobject::play : " + _s.model);
}
}
#/
flagsys::clear( "ready" ); flagsys::clear( "done" ); flagsys::clear( "main_done" ); _str_state = "play"; self notify( "new_state" ); self endon( "new_state" ); self notify("play"); log( "play" ); waittillframeend;;
if( ( isdefined( _s.hide ) && _s.hide ) && _is_valid )
{
_spawn( undefined, false, false );
_e Hide();
}
else if ( isdefined( _s.mainanim ) && _is_valid )
{
_str_death_anim = _s.mainanimdeath;
_str_death_anim_loop = _s.mainanimdeathloop;
//if it is a starting of a scene and no value is provided, do a default 0.2 animation blend.
if ( !( isdefined( _s.IsCutScene ) && _s.IsCutScene ) )
{
if( !isdefined( _s.MainBlend ) || _s.MainBlend == 0 )
{
_s.mainblend = 0.2;
}
else if(_s.MainBlend == 0.001) //MALI - A hack to enable 0 blending between cuts, this should be removed once we ship TU5 and _s.MainBlend = 0 should mean 0 not 0.2.
{
_s.MainBlend = 0;
}
}
_play_anim( _s.mainanim, _s.maindelaymin, _s.maindelaymax, 1, _s.mainblend, _o_bundle.n_start_time );
flagsys::set( "main_done" );
if ( isdefined( _e ) && ( isdefined( _s.DynamicPaths ) && _s.DynamicPaths ) )
{
if ( Distance2DSquared( _e.origin, _e.scene_orig_origin ) > 4 )
{
_e DisconnectPaths( 2, false );
}
}
if ( is_alive() )
{
if ( !isdefined( _s.EndBlend ) || _s.EndBlend == 0 )
{
_s.EndBlend = 0.2;
}
if ( isdefined( _s.endanim ) )
{
_str_death_anim = _s.endanimdeath;
_str_death_anim_loop = _s.endanimdeathloop;
_play_anim( _s.endanim, 0, 0, 1, _s.EndBlend );
if ( is_alive() )
{
if ( isdefined( _s.endanimloop ) )
{
_str_death_anim = _s.endanimloopdeath;
_str_death_anim_loop = _s.endanimloopdeathloop;
_play_anim( _s.endanimloop, 0, 0, 1 );
}
}
}
else if ( isdefined( _s.endanimloop ) )
{
_str_death_anim = _s.endanimloopdeath;
_str_death_anim_loop = _s.endanimloopdeathloop;
_play_anim( _s.endanimloop, 0, 0, 1 );
}
}
}
thread finish();
}
function stop( b_clear = false, b_dont_clear_anim = false, b_finished = false )
{
/#
if ( GetDvarInt( "debug_scene" ) > 0 )
{
PrintTopRightln( "csceneobject::stop : " + ( isdefined( _s.name ) ? _s.name : _s.model ) );
}
#/
if ( IsAlive( _e ) )
{
if ( is_shared_player() )
{
foreach ( player in level.players )
{
player StopAnimScripted( .2 );
}
}
else if ( !( isdefined( _s.DieWhenFinished ) && _s.DieWhenFinished ) || !b_finished )
{
if ( !b_dont_clear_anim || IsPlayer( _e ) )
{
_e StopAnimScripted( .2 );
}
}
}
finish( b_clear, !b_finished );
}
function get_align_ent()
{
e_align = undefined;
if ( isdefined( _s.aligntarget ) && !( _s.aligntarget === _o_bundle._s.aligntarget ) )
{
a_scene_ents = [[_o_bundle]]->get_ents();
if ( isdefined( a_scene_ents[ _s.aligntarget ] ) )
{
e_align = a_scene_ents[ _s.aligntarget ];
}
else
{
e_align = scene::get_existing_ent( _s.aligntarget, false, true );
}
if ( !isdefined( e_align ) )
{
str_msg = "Align target '" + (isdefined(_s.aligntarget)?""+_s.aligntarget:"") + "' doesn't exist for scene object.";
if ( !warning( _o_bundle._testing, str_msg ) )
{
error( GetDvarInt( "scene_align_errors", 1 ), str_msg );
}
}
}
if ( !isdefined( e_align ) )
{
e_align = [[scene()]]->get_align_ent();
}
return e_align;
}
function get_align_tag()
{
if ( isdefined( _s.AlignTargetTag ) )
{
return _s.AlignTargetTag;
}
else
{
if ( isdefined( _o_bundle._e_root.e_scene_link ) )
{
return "tag_origin";
}
else
{
return _o_bundle._s.AlignTargetTag;
}
}
}
/* Scene Helpers */
function scene()
{
return _o_bundle;
}
/* internal functions */
function _on_damage_run_scene_thread()
{
self endon( "play" );
self endon( "done" );
str_damage_types = ( !isdefined( _s.runsceneondmg0 ) || _s.runsceneondmg0 == "none" ? "" : _s.runsceneondmg0 ) + ( !isdefined( _s.runsceneondmg1 ) || _s.runsceneondmg1 == "none" ? "" : _s.runsceneondmg1 ) + ( !isdefined( _s.runsceneondmg2 ) || _s.runsceneondmg2 == "none" ? "" : _s.runsceneondmg2 ) + ( !isdefined( _s.runsceneondmg3 ) || _s.runsceneondmg3 == "none" ? "" : _s.runsceneondmg3 ) + ( !isdefined( _s.runsceneondmg4 ) || _s.runsceneondmg4 == "none" ? "" : _s.runsceneondmg4 );
if ( str_damage_types != "" )
{
b_run_scene = false;
while ( !b_run_scene )
{
_e waittill( "damage", n_amount, e_attacker, v_org, v_dir, str_mod );
switch ( str_mod )
{
case "MOD_PISTOL_BULLET":
case "MOD_RIFLE_BULLET":
if ( IsSubStr( str_damage_types, "bullet" ) )
{
b_run_scene = true;
}
break;
case "MOD_GRENADE":
case "MOD_GRENADE_SPLASH":
case "MOD_EXPLOSIVE":
if ( IsSubStr( str_damage_types, "explosive" ) )
{
b_run_scene = true;
}
break;
case "MOD_PROJECTILE":
case "MOD_PROJECTILE_SPLASH":
if ( IsSubStr( str_damage_types, "projectile" ) )
{
b_run_scene = true;
}
break;
case "MOD_MELEE":
if ( IsSubStr( str_damage_types, "melee" ) )
{
b_run_scene = true;
}
break;
default:
if ( IsSubStr( str_damage_types, "all" ) )
{
b_run_scene = true;
}
}
}
thread [[scene()]]->play();
}
}
function _assign_unique_name()
{
if ( is_player() )
{
_str_name = "player " + _s.player;
}
else
{
if ( [[scene()]]->allows_multiple() )
{
if ( isdefined( _s.name ) )
{
_str_name = _s.name + "_gen" + level.scene_object_id;
}
else
{
_str_name = [[scene()]]->get_name() + "_noname" + level.scene_object_id;
}
level.scene_object_id++;
}
else
{
if ( isdefined( _s.name ) )
{
_str_name = _s.name;
}
else
{
_str_name = [[scene()]]->get_name() + "_noname" + [[scene()]]->get_object_id();
}
}
}
}
function get_name()
{
return _str_name;
}
function get_orig_name()
{
return _s.name;
}
function _spawn( e_spawner, b_hide = true, b_set_ready_when_spawned = true )
{
if ( isdefined( e_spawner ) )
{
_e = e_spawner;
}
if ( isdefined( _e ) && ( isdefined( _e.isDying ) && _e.isDying ) )
{
_e Delete(); // previous ent is marked for cleanup, do it now so it doesn't delete a frame later when we don't want it to
}
if ( is_player() )
{
if ( IsPlayer( _e ) )
{
_player = _e;
}
else
{
n_player = GetDvarInt( "scene_debug_player", 0 );
if ( n_player > 0 )
{
n_player--;
if ( n_player == _s.player )
{
_player = level.activeplayers[ 0 ];
}
}
else
{
_player = level.activeplayers[ _s.player ];
}
}
}
b_skip = ( _s.type === "actor" ) && IsSubStr( _o_bundle._str_mode, "noai" );
b_skip = b_skip || ( ( _s.type === "player" ) && IsSubStr( _o_bundle._str_mode, "noplayers" ) );
if(!b_skip && _should_skip_entity())
{
b_skip = true;
}
if ( !b_skip )
{
if ( !isdefined( _e ) && is_player() && ( isdefined( _s.newplayermethod ) && _s.newplayermethod ) )
{
_e = _player;
}
else if ( !isdefined( _e ) || IsSpawner( _e ) )
{
b_allows_multiple = [[scene()]]->allows_multiple();
if ( /*error( !b_allows_multiple && !isdefined( _s.name ), "Scene that don't allow multiple instances must specify a name for all objects." )
|| */error( b_allows_multiple && ( isdefined( _s.nospawn ) && _s.nospawn ), "Scene that allow multiple instances must be allowed to spawn (uncheck 'Do Not Spawn')." ) )
{
return;
}
if ( !IsSpawner( _e ) )
{
e = scene::get_existing_ent( _str_name, b_allows_multiple );
if ( !isdefined( e ) && isdefined( _s.name ) )
{
e = scene::get_existing_ent( _s.name, b_allows_multiple );
}
if ( IsPlayer( e ) )
{
if ( !( isdefined( _s.newplayermethod ) && _s.newplayermethod ) )
{
e = undefined;
}
}
if ( ( !isdefined( e ) || IsSpawner( e ) ) && ( ( !( isdefined( _s.nospawn ) && _s.nospawn ) && !_b_spawnonce_used ) || _o_bundle._testing ) )
{
e_spawned = spawn_ent( e );
}
}
else
{
e_spawned = spawn_ent( _e );
}
if ( isdefined( e_spawned ) )
{
if ( b_hide && !_o_bundle._s scene::is_igc() )
{
e_spawned Hide(); // Hide teleporting glitches and for any delay set on this object
}
e_spawned DontInterpolate();
e_spawned.scene_spawned = _o_bundle._s.name;
if ( !isdefined( e_spawned.targetname ) )
{
e_spawned.targetname = _s.name;
}
if ( is_player() )
{
e_spawned Hide();
}
}
_e = ( isdefined( e_spawned ) ? e_spawned : e );
if ( ( isdefined( _s.spawnonce ) && _s.spawnonce ) && _b_spawnonce_used )
{
return;
}
}
error( !is_player() && !( isdefined( _s.nospawn ) && _s.nospawn ) && ( !isdefined( _e ) || IsSpawner( _e ) ), "Object failed to spawn or doesn't exist." );
}
if ( isdefined( _e ) && !IsSpawner( _e ) )
{
[[self]]->_prepare();
if ( b_set_ready_when_spawned )
{
flagsys::set( "ready" );
}
if ( ( isdefined( _s.spawnonce ) && _s.spawnonce ) )
{
_b_spawnonce_used = true;
}
}
else
{
flagsys::set( "ready" );
flagsys::set( "done" );
finish();
}
}
function _prepare()
{
if ( ( isdefined( _s.DynamicPaths ) && _s.DynamicPaths ) && ( _str_state == "play" ) )
{
_e.scene_orig_origin = _e.origin;
_e ConnectPaths();
}
if ( ( _e.current_scene === _o_bundle._str_name ) )
{
//Since we do not fire the "scene_sequence_started" on init state, we need to do so here.
[[_o_bundle]]->trigger_scene_sequence_started( self, _e );
return false; // already prepared this entity for this scene
}
_e endon( "death" );
if ( !( isdefined( _s.IgnoreAliveCheck ) && _s.IgnoreAliveCheck ) && error( IsAI( _e ) && !IsAlive( _e ), "Trying to play a scene on a dead AI." ) )
{
return;
}
// cleanup any current/previous scenes
if ( isdefined( _e._o_scene ) )
{
foreach ( obj in _e._o_scene._a_objects )
{
if ( obj._e === _e )
{
[[ obj ]]->finish();
break;
}
}
}
if ( !IsAI( _e ) && !IsPlayer( _e ) )
{
if ( !is_player() || !( isdefined( _s.newplayermethod ) && _s.newplayermethod ) )
{
if ( is_player_model() )
{
scene::prepare_player_model_anim( _e );
}
else
{
scene::prepare_generic_model_anim( _e );
}
}
}
if ( !is_player() )
{
if ( !isdefined( _e._scene_old_takedamage ) )
{
_e._scene_old_takedamage = _e.takedamage;
}
if ( IsSentient( _e ) )
{
// For sentients, don't override if damage/death is turned off
_e.takedamage = ( isdefined( _e.takedamage ) && _e.takedamage ) && ( isdefined( _s.takedamage ) && _s.takedamage );
if ( !( isdefined( _e.magic_bullet_shield ) && _e.magic_bullet_shield ) )
{
_e.allowdeath = ( isdefined( _s.allowdeath ) && _s.allowdeath );
}
if ( ( isdefined( _s.OverrideAICharacter ) && _s.OverrideAICharacter ) )
{
_e DetachAll();
_e SetModel( _s.model );
}
}
else
{
_e.health = ( _e.health > 0 ? _e.health : 1 );
if ( _s.type === "actor" ) // Drone
{
_e MakeFakeAI();
if ( !( isdefined( _s.RemoveWeapon ) && _s.RemoveWeapon ) )
{
_e animation::attach_weapon( GetWeapon( "ar_standard" ) );
// TODO: see if we can get the weapon from the aitype if using one for the character model
}
}
_e.takedamage = ( isdefined( _s.takedamage ) && _s.takedamage );
_e.allowdeath = ( isdefined( _s.allowdeath ) && _s.allowdeath );
}
set_objective();
if ( ( isdefined( _s.DynamicPaths ) && _s.DynamicPaths ) )
{
_e DisconnectPaths( 2, false );
}
}
else if ( !is_shared_player() )
{
player = ( IsPlayer( _player ) ? _player : _e );
_prepare_player( player );
}
if ( ( isdefined( _s.RemoveWeapon ) && _s.RemoveWeapon ) )
{
if ( !( isdefined( _e.gun_removed ) && _e.gun_removed ) )
{
if ( IsPlayer( _e ) )
{
_e player::take_weapons();
}
else
{
_e animation::detach_weapon();
}
}
else
{
_e._scene_old_gun_removed = true;
}
}
// TODO: refactor all of this stuff so it can be set/cleared on all players in a shared animation
_e.animname = _str_name;
_e.anim_debug_name = _s.name;
_e flagsys::set( "scene" );
_e flagsys::set( _o_bundle._str_name );
_e.current_scene = _o_bundle._str_name;
_e.finished_scene = undefined;
_e._o_scene = scene();
//only shared IGC can skip the scene if it is just started
[[_o_bundle]]->trigger_scene_sequence_started( self, _e );
if ( ( isdefined( _e.takedamage ) && _e.takedamage ) )
{
thread _on_damage_run_scene_thread();
thread _on_death();
}
if ( IsActor( _e ) )
{
thread _track_goal();
if ( ( isdefined( _s.LookAtPlayer ) && _s.LookAtPlayer ) )
{
_e LookAtEntity( level.activeplayers[0] );
}
}
if ( _o_bundle._s scene::is_igc() || [[ _o_bundle ]]->has_player() )
{
if ( !IsPlayer( _e ) ) // players handled in _prepare_player
{
_e SetHighDetail( true );
}
}
return true;
}
function _prepare_player( player )
{
/#
if( GetDvarInt("debug_scene") > 0)
{
PrintTopRightln("csceneobject::_prepare_player");
}
#/
if ( ( isdefined( player.play_scene_transition_effect ) && player.play_scene_transition_effect ) )
{
player.play_scene_transition_effect = undefined;
play_regroup_fx_for_scene( player );
}
if ( ( player.current_player_scene === _o_bundle._str_name ) )
{
//Since we do not fire the "scene_sequence_started" on init state, we need to do so here.
[[_o_bundle]]->trigger_scene_sequence_started( self, player );
return false; // already prepared this entity for this scene
}
player SetHighDetail( true );
// close the mobile armory if it's open
if ( player flagsys::get( "mobile_armory_in_use" ) )
{
player flagsys::set("cancel_mobile_armory");
player CloseMenu( "ChooseClass_InGame" );
player notify( "menuresponse", "ChooseClass_InGame", "cancel" );
}
//if player was starting to interact with an armory and never finished
if( player flagsys::get( "mobile_armory_begin_use" ) )
{
player util::_enableWeapon();
player flagsys::clear( "mobile_armory_begin_use" );
}
if( GetDvarInt("scene_hide_player") > 0 )
{
player Hide();
}
player.current_player_scene = _o_bundle._str_name;
if ( !( isdefined( player.magic_bullet_shield ) && player.magic_bullet_shield ) )
{
player.allowdeath = ( isdefined( _s.allowdeath ) && _s.allowdeath );
}
player.scene_takedamage = ( isdefined( _s.takedamage ) && _s.takedamage );
if ( isdefined( player.hijacked_vehicle_entity ) )
{
player.hijacked_vehicle_entity Delete();
}
else if ( player IsInVehicle() )
{
vh_occupied = player GetVehicleOccupied();
n_seat = vh_occupied GetOccupantSeat( player );
vh_occupied UseVehicle( player, n_seat ); // make player exit vehicle
}
revive_player( player );
player thread scene::scene_disable_player_stuff( !( isdefined( _s.ShowHUD ) && _s.ShowHUD ) );
if ( ( isdefined( _s.FirstWeaponRaise ) && _s.FirstWeaponRaise ) )
{
//SetDvar( "playerWeaponRaisePostIGC", WEAP_FIRST_RAISE );
}
player.player_anim_look_enabled = !( isdefined( _s.LockView ) && _s.LockView );
player.player_anim_clamp_right = (isdefined(_s.viewClampRight)?_s.viewClampRight:0);
player.player_anim_clamp_left = (isdefined(_s.viewClampLeft)?_s.viewClampLeft:0);
player.player_anim_clamp_top = (isdefined(_s.viewClampBottom)?_s.viewClampBottom:0);
player.player_anim_clamp_bottom = (isdefined(_s.viewClampBottom)?_s.viewClampBottom:0);
if ( ( !( isdefined( _s.RemoveWeapon ) && _s.RemoveWeapon ) || ( isdefined( _s.ShowWeaponInFirstPerson ) && _s.ShowWeaponInFirstPerson ) ) && !( isdefined( _s.DisablePrimaryWeaponSwitch ) && _s.DisablePrimaryWeaponSwitch ) )
{
player player::switch_to_primary_weapon( true );
}
set_player_stance( player );
}
function revive_player( player )
{
if ( player.sessionstate === "spectator" )
{
player thread [[ level.spawnPlayer ]]();
}
else if ( player laststand::player_is_in_laststand() )
{
player notify( "auto_revive" ); // currently CP only
}
}
function set_player_stance( player )
{
if ( _s.PlayerStance === "crouch" )
{
player AllowStand( false );
player AllowCrouch( true );
player AllowProne( false );
}
else if ( _s.PlayerStance === "prone" )
{
player AllowStand( false );
player AllowCrouch( false );
player AllowProne( true );
}
else // default to stand
{
player AllowStand( true );
player AllowCrouch( false );
player AllowProne( false );
}
}
function finish( b_clear = false, b_canceled = false )
{
/#
if( GetDvarInt("debug_scene") > 0)
{
PrintTopRightln("csceneobject::finish: " + ((isdefined(_s.name))? _s.name : _s.model));
}
#/
if ( isdefined( _str_state ) )
{
_str_state = undefined;
self notify( "new_state" );
if ( !is_shared_player() && !is_alive() ) //TU1: need to only skip this if SHARED scene, not just for !is_player
{
_cleanup();
_e = undefined;
_is_valid = false;
}
else
{
if ( !is_player() )
{
if ( isdefined( _e._scene_old_takedamage ) )
{
_e.takedamage = _e._scene_old_takedamage;
}
if ( !( isdefined( _e.magic_bullet_shield ) && _e.magic_bullet_shield ) )
{
_e.allowdeath = true;
}
_e._scene_old_takedamage = undefined;
_e._scene_old_gun_removed = undefined;
}
else
{
if ( is_shared_player() )
{
foreach ( player in level.players )
{
if( player flagsys::get( "shared_igc" ) )
{
_finish_player( player );
}
}
}
else
{
player = ( IsPlayer( _player ) ? _player : _e );
_finish_player( player );
}
}
if ( ( isdefined( _s.RemoveWeapon ) && _s.RemoveWeapon ) && !( isdefined( _e._scene_old_gun_removed ) && _e._scene_old_gun_removed ) )
{
if ( IsPlayer( _e ) )
{
/#
if( GetDvarInt("debug_scene") > 0)
{
PrintTopRightln("csceneobject::finish::giveweapon : " + ((isdefined(_s.name))? _s.name : _s.model));
}
#/
_e player::give_back_weapons();
}
else
{
/#
if( GetDvarInt("debug_scene") > 0)
{
PrintTopRightln("csceneobject::finish::giveweapon : " + ((isdefined(_s.name))? _s.name : _s.model));
}
#/
_e animation::attach_weapon();
}
}
if ( !IsPlayer( _e ) ) // players are handled in _finish_player
{
if ( isdefined( _e ) )
{
_e SetHighDetail( false );
}
}
}
flagsys::set( "ready" );
flagsys::set( "done" );
if ( isdefined( _e ) )
{
if ( !is_player() )
{
if ( is_alive() && ( ( isdefined( _s.DeleteWhenFinished ) && _s.DeleteWhenFinished ) || b_clear ) )
{
_e thread scene::synced_delete();
}
else if ( is_alive() && ( isdefined( _s.DieWhenFinished ) && _s.DieWhenFinished ) && !b_canceled )
{
_e.skipdeath = true;
_e.allowdeath = true;
_e.skipscenedeath = true;
_e Kill();
}
}
if ( IsActor( _e ) && IsAlive( _e ) )
{
if ( ( isdefined( _s.DelayMovementAtEnd ) && _s.DelayMovementAtEnd ) )
{
_e PathMode( "move delayed", true, RandomFloatRange( 2, 3 ) );
}
else
{
_e PathMode( "move allowed" );
}
if ( ( isdefined( _s.LookAtPlayer ) && _s.LookAtPlayer ) )
{
_e LookAtEntity();
}
}
}
_cleanup();
}
}
function _finish_player( player )
{
/#
if( GetDvarInt("debug_scene") > 0)
{
PrintTopRightln("csceneobject::_finish_player");
}
#/
/*
/#
PrintTopRightln("SetVisibleToAll : " + GetTime(), BLUE, -1);
#/
*/
player.scene_set_visible_time = level.time;
player SetVisibleToAll();
player flagsys::clear( "shared_igc" );
if ( !( isdefined( player.magic_bullet_shield ) && player.magic_bullet_shield ) )
{
player.allowdeath = true;
}
player.current_player_scene = undefined;
player.scene_takedamage = undefined;
player._scene_old_gun_removed = undefined;
player thread scene::scene_enable_player_stuff( !( isdefined( _s.ShowHUD ) && _s.ShowHUD ) );
//SetDvar( "playerWeaponRaisePostIGC", WEAP_RAISE );
if(!([[_o_bundle]]->has_next_scene()) )
{
if([[_o_bundle]]->is_player_anim_ending_early())
{
if(![[_o_bundle]]->is_skipping_scene() && [[_o_bundle]]->is_scene_shared_sequence()) //if we are not skipping a scene then just notify that the scene sequence has ended
{
[[_o_bundle]]->init_scene_sequence_started(false);
}
_o_bundle thread cscene::_stop_camera_anim_on_player(player);
}
else if(_o_bundle._s scene::is_igc())
{
_o_bundle thread cscene::_stop_camera_anim_on_player(player);
}
}
n_camera_tween_out = get_camera_tween_out();
if ( n_camera_tween_out > 0 )
{
player StartCameraTween( n_camera_tween_out );
}
if ( !( isdefined( _s.DontReloadAmmo ) && _s.DontReloadAmmo ) )
{
player player::fill_current_clip();
}
player AllowStand( true );
player AllowCrouch( true );
player AllowProne( true );
player SetHighDetail( false );
}
function set_objective()
{
if ( !isdefined( _e.script_objective ) )
{
if ( isdefined( _o_bundle._e_root.script_objective ) )
{
_e.script_objective = _o_bundle._e_root.script_objective;
}
else if ( isdefined( _o_bundle._s.script_objective ) )
{
_e.script_objective = _o_bundle._s.script_objective;
}
}
}
function _on_death()
{
self endon( "cleanup" );
_e waittill( "death" );
if ( isdefined( _e ) && !( isdefined( _e.skipscenedeath ) && _e.skipscenedeath ) )
{
self thread do_death_anims();
}
}
function do_death_anims()
{
ent = _e;
if ( IsAI( ent ) && !isdefined( _str_death_anim ) && !isdefined( _str_death_anim_loop ) )
{
ent StopAnimScripted();
if ( IsActor( ent ) )
{
ent StartRagDoll();
}
}
if ( isdefined( _str_death_anim ) )
{
ent.skipdeath = true;
ent animation::play( _str_death_anim, ent, undefined, 1, .2, 0 );
}
if ( isdefined( _str_death_anim_loop ) )
{
ent.skipdeath = true;
ent animation::play( _str_death_anim_loop, ent, undefined, 1, 0, 0 );
}
}
function _cleanup()
{
if ( isdefined( _e ) && isdefined( _e.current_scene ) )
{
_e flagsys::clear( _o_bundle._str_name );
if ( _e.current_scene == _o_bundle._str_name )
{
_e flagsys::clear( "scene" );
_e.finished_scene = _o_bundle._str_name;
_e.current_scene = undefined;
_e._o_scene = undefined;
if ( is_player() )
{
if ( !( isdefined( _s.newplayermethod ) && _s.newplayermethod ) )
{
_e Delete();
thread reset_player();
}
_e.animname = undefined;
}
}
}
self notify( "death" );
self endon( "new_state" );
waittillframeend; // allow death anims and other things to execute before killing those threads
self notify( "cleanup" );
if ( IsAI( _e ) )
{
_set_goal();
}
if ( isdefined( _o_bundle ) && ( isdefined( _o_bundle.scene_stopping ) && _o_bundle.scene_stopping ) ) // don't clear this if the scene is looping
{
_o_bundle = undefined;
}
}
function _set_goal()
{
if ( !( ( _e.scene_spawned === _o_bundle._s.name ) && isdefined( _e.target ) ) )
{
if ( !isdefined( _e.script_forcecolor ) )
{
if ( !_e flagsys::get( "anim_reach" ) )
{
if ( isdefined( _e.scenegoal ) )
{
_e SetGoal( _e.scenegoal ); // use secene goal
_e.scenegoal = undefined;
}
else if ( _b_set_goal )
{
_e SetGoal( _e.origin ); // default to current location
}
}
}
}
}
function _track_goal()
{
// disable setting goal when animation is done if goal is changed any time during animation
// (assume scripter knows what they are doing and don't override it)
self endon( "cleanup" );
_e endon( "death" );
_e waittill( "goal_changed" );
_b_set_goal = false;
}
function _play_anim( animation, n_delay_min = 0, n_delay_max = 0, n_rate = 1, n_blend = 0.2, n_time = 0 )
{
/#
if ( GetDvarInt( "debug_scene" ) > 0 )
{
if ( isdefined( _s.name ) )
{
PrintTopRightln( "csceneobject::_play_anim : " + _s.name );
}
else
{
PrintTopRightln( "csceneobject::_play_anim : " + _s.model );
}
}
#/
if ( _should_skip_anim( animation ) )
{
return;
}
if ( n_time != 0 )
{
n_time = [[ _o_bundle ]]->get_anim_relative_start_time( animation, n_time );
}
n_delay = n_delay_min;
if ( n_delay_max > n_delay_min )
{
n_delay = RandomFloatRange( n_delay_min, n_delay_max );
}
do_reach = ( ( n_time == 0 ) && ( ( isdefined( _s.doreach ) && _s.doreach ) && ( !( isdefined( _o_bundle._testing ) && _o_bundle._testing ) || GetDvarInt( "scene_test_with_reach", 0 ) ) ) );
_spawn( undefined, !do_reach, !do_reach );
if ( !IsActor( _e ) )
{
do_reach = false;
}
if ( n_delay > 0 )
{
if ( n_delay > 0 )
{
wait n_delay;
}
}
if ( do_reach )
{
[[scene()]]->wait_till_scene_ready( self );
if ( ( isdefined( _s.DisableArrivalInReach ) && _s.DisableArrivalInReach ) )
{
_e animation::reach( animation, get_align_ent(), get_align_tag(), true );
}
else
{
_e animation::reach( animation, get_align_ent(), get_align_tag() );
}
flagsys::set( "ready" );
}
else if ( n_rate > 0 ) // Go ahead and first-frame the anim right away without waiting
{
[[scene()]]->wait_till_scene_ready();
}
else if ( isdefined( _s.aligntarget ) )
{
foreach ( o_obj in _o_bundle._a_objects )
{
// If align target is an object in this scene, wait for it to spawn
if ( o_obj._str_name == _s.aligntarget )
{
o_obj flagsys::wait_till( "ready" );
break;
}
}
}
if ( is_alive() )
{
align = get_align_ent();
tag = get_align_tag();
if ( align == level )
{
align = ( 0, 0, 0 );
tag = ( 0, 0, 0 );
}
if ( is_shared_player() )
{
_play_shared_player_anim( animation, align, tag, n_rate, n_time );
}
else
{
if ( is_player() && !( isdefined( _s.newplayermethod ) && _s.newplayermethod ) )
{
thread link_player();
}
if ( ( /*!is_player() && */_o_bundle._s scene::is_igc() ) || ( _e.scene_spawned === _o_bundle._s.name ) )
{
_e DontInterpolate();
_e Show();
}
// Lerping and camera tween
n_lerp = get_lerp_time();
if ( IsPlayer( _e ) && !_o_bundle._s scene::is_igc() )
{
n_camera_tween = get_camera_tween();
if ( n_camera_tween > 0 )
{
_e StartCameraTween( n_camera_tween );
}
}
///////////////////
if ( ![[ _o_bundle ]]->has_next_scene() )
{
n_blend_out = ( IsAI( _e ) ? .2 : 0 );
}
else
{
n_blend_out = 0;
}
if ( ( isdefined( _s.DieWhenFinished ) && _s.DieWhenFinished ) )
{
n_blend_out = 0;
}
/#
if ( GetDvarInt( "debug_scene" ) > 0 )
{
PrintTopRightln( "csceneobject::_play_anim : ::animation::play: " + ( ( isdefined( _s.name ) )? _s.name : _s.model ) + " : " + animation );
}
#/
/#
if ( GetDvarInt( "debug_scene_skip" ) > 0 )
{
if ( !isdefined( level.animation_played ) )
{
level.animation_played = [];
animation_played_name = ( ( isdefined( _s.name ) )? _s.name : _s.model ) + " : " + animation;
if ( !isdefined( level.animation_played ) ) level.animation_played = []; else if ( !IsArray( level.animation_played ) ) level.animation_played = array( level.animation_played ); level.animation_played[level.animation_played.size]=animation_played_name;;
}
}
#/
self.current_playing_anim = animation;
//skip the new animation if we are skipping the scene
if ( ( isdefined( [[ _o_bundle ]]->is_skipping_scene() ) && [[ _o_bundle ]]->is_skipping_scene() ) && n_rate != 0 )
{
thread skip_scene( true );
}
_e animation::play( animation, align, tag, n_rate, n_blend, n_blend_out, n_lerp, n_time, _s.ShowWeaponInFirstPerson );
if ( !isdefined( _e ) || !_e IsPlayingAnimScripted() )
{
self.current_playing_anim = undefined;
}
/#
if ( GetDvarInt( "debug_scene_skip" ) > 0 )
{
if(isdefined(level.animation_played))
{
for ( i = 0; i < level.animation_played.size; i++ )
{
animation_played_name = ( isdefined( _s.name ) ? _s.name : _s.model ) + " : " + animation;
if ( level.animation_played[ i ] == animation_played_name )
{
ArrayRemoveValue( level.animation_played, animation_played_name );
i--;
continue;
}
}
}
}
#/
/#
if ( GetDvarInt( "debug_scene" ) > 0 )
{
PrintTopRightln("csceneobject::_play_anim : ::animation::Stop: " + ((isdefined(_s.name))? _s.name : _s.model) + " : " + animation);
}
#/
}
}
else
{
/# log( "No entity for animation '" + animation + "' so not playing it." ); #/
}
_is_valid = ( is_alive() && !in_a_different_scene() );
}
function spawn_ent( e )
{
b_disable_throttle = ( _o_bundle._s scene::is_igc() || ( isdefined( _o_bundle._s.DontThrottle ) && _o_bundle._s.DontThrottle ) );
if ( is_player() && !( isdefined( _s.newplayermethod ) && _s.newplayermethod ) )
{
system::wait_till( "loadout" );
m_player = util::spawn_anim_model( level.player_interactive_model );
return m_player;
}
else if ( isdefined( e ) )
{
if ( IsSpawner( e ) )
{
/#
if ( _o_bundle._testing )
{
e.count++;
}
#/
if ( !error( e.count < 1, "Trying to spawn AI for scene with spawner count < 1" ) )
{
return e spawner::spawn( true, undefined, undefined, undefined, b_disable_throttle );
}
}
}
else if ( isdefined( _s.model ) )
{
new_model = undefined;
if ( is_player_model() )
{
new_model = util::spawn_anim_player_model( _s.model, _o_bundle._e_root.origin, _o_bundle._e_root.angles );
}
else
{
new_model = util::spawn_anim_model( _s.model, _o_bundle._e_root.origin, _o_bundle._e_root.angles, undefined, !b_disable_throttle );
}
return new_model;
}
}
function _play_shared_player_anim( animation, align, tag, n_rate, n_time )
{
/#
if( GetDvarInt("debug_scene") > 0)
{
PrintTopRightln("csceneobject::_play_shared_player_anim: " + animation);
}
#/
self.player_animation = animation;
self.player_animation_notify = animation + "_notify";
self.player_animation_length = GetAnimLength( animation );
self.player_align = align;
self.player_tag = tag;
self.player_rate = n_rate;
self.player_time_frac = n_time;
self.player_start_time = GetTime();
callback::on_loadout( &_play_shared_player_anim_for_player, self );
foreach ( player in level.players )
{
if ( player flagsys::get( "loadout_given" ) && ( player.sessionstate !== "spectator" ) )
{
self thread _play_shared_player_anim_for_player( player );
}
else if( ( isdefined( player.initialLoadoutGiven ) && player.initialLoadoutGiven ) )
{
revive_player( player );
}
}
waittillframeend;
do
{
b_playing = false;
a_players = ArrayCopy( level.activeplayers );
foreach ( player in a_players )
{
if ( isdefined( player ) && player flagsys::get( self.player_animation_notify ) )
{
b_playing = true;
player flagsys::wait_till_clear( self.player_animation_notify );
break;
}
}
}
while ( b_playing );
callback::remove_on_loadout( &_play_shared_player_anim_for_player, self );
thread [[_o_bundle]]->_call_state_funcs( "players_done" );
}
function _play_shared_player_anim_for_player( player )
{
player endon( "death" );
/#
//PrintTopRightln( __FUNCTION__ );
#/
/#
if( GetDvarInt("debug_scene") > 0)
{
PrintTopRightln("csceneobject::_play_shared_player_anim_for_player: " + self.player_animation);
}
#/
if ( !isdefined( _o_bundle ) )
return;
player flagsys::set( "shared_igc" );
//Do not clear the flag for the init state
if( player flagsys::get( self.player_animation_notify ) )
{
player flagsys::set( self.player_animation_notify + "_skip_init_clear" );
}
player flagsys::set( self.player_animation_notify );
if ( isdefined( player GetLinkedEnt() ) )
{
player Unlink();
}
if ( !( isdefined( _s.DisableTransitionIn ) && _s.DisableTransitionIn ) )
{
if ( ( player != _player ) || GetDvarInt( "scr_player1_postfx", 0 ) )
{
if ( !isdefined( player.screen_fade_menus ) )
{
if ( !( isdefined( level.chyron_text_active ) && level.chyron_text_active ) )
{
if ( !( isdefined( player.fullscreen_black_active ) && player.fullscreen_black_active ) )
{
player.play_scene_transition_effect = true;
}
}
}
}
}
player Show(); // Make sure the player is not hidden before hidding to the other players
player SetInvisibleToAll();
/*
/#
PrintTopRightln("SetInvisibleToAll : " + GetTime(), ORANGE, -1);
#/
*/
_prepare_player( player );
n_time_passed = ( GetTime() - self.player_start_time ) / 1000;
n_start_time = self.player_time_frac * self.player_animation_length;
n_time_left = self.player_animation_length - n_time_passed - n_start_time;
n_time_frac = 1 - ( n_time_left / self.player_animation_length );
if ( isdefined( _e ) && ( player != _e ) )
{
// Teleport coop players to the player who is triggering this scene
// so that the camera tween and lerping happens from the same place
player DontInterpolate();
player SetOrigin( _e.origin );
player SetPlayerAngles( _e GetPlayerAngles() );
}
// Lerping and camera tween
n_lerp = get_lerp_time();
if ( !_o_bundle._s scene::is_igc() )
{
n_camera_tween = get_camera_tween();
if ( n_camera_tween > 0 )
{
player StartCameraTween( n_camera_tween );
}
}
///////////////////
if ( n_time_frac < 1 )
{
// scene_set_visible_time = player.scene_set_visible_time;
// if ( isdefined( scene_set_visible_time ) )
// {
// Assert( scene_set_visible_time == level.time );
// }
//// player.scene_set_visible_time = undefined;
/#
if( GetDvarInt("scene_hide_player") > 0 )
{
player Hide();
}
if( GetDvarInt("debug_scene") > 0)
{
PrintTopRightln("csceneobject::_play_shared_player_anim_for_player::animation::play: " + _s.name + " : " + self.player_animation);
}
#/
str_animation = self.player_animation;
// load gender specific player animation
if ( player util::is_female() )
{
if ( isdefined( _o_bundle._s.s_female_bundle ) )
{
s_bundle = _o_bundle._s.s_female_bundle;
}
}
else
{
if ( isdefined( _o_bundle._s.s_male_bundle ) )
{
s_bundle = _o_bundle._s.s_male_bundle;
}
}
if ( isdefined( s_bundle ) )
{
foreach ( s_object in s_bundle.objects )
{
if ( isdefined( s_object ) && ( s_object.type === "player" ) )
{
str_animation = s_object.mainanim;
break;
}
}
}
player_num = player GetEntityNumber();
if(!isdefined(self.current_playing_anim))
{
self.current_playing_anim = [];
}
self.current_playing_anim[player_num] = str_animation;
//skip the new animation if we are skipping the scene
if ( ( isdefined( [[ _o_bundle ]]->is_skipping_scene() ) && [[ _o_bundle ]]->is_skipping_scene() ) )
{
thread skip_scene( true );
}
//////////////////////////////////////////
player animation::play( str_animation, self.player_align, self.player_tag, self.player_rate, 0, 0, n_lerp, n_time_frac, _s.ShowWeaponInFirstPerson );
if( !(player flagsys::get( self.player_animation_notify + "_skip_init_clear" )) )
{
player flagsys::clear( self.player_animation_notify ); // all players use the same aniamtion name for the flag to track when they are done
}
else
{
player flagsys::clear( self.player_animation_notify + "_skip_init_clear" );
}
if ( !player IsPlayingAnimScripted() )
{
self.current_playing_anim[player_num] = undefined;
}
/#
if ( GetDvarInt( "debug_scene" ) > 0 )
{
PrintTopRightln( "csceneobject::_play_shared_player_anim_for_player::animation::Stopped: " + _s.name + " : " + self.player_animation );
}
#/
}
}
function play_regroup_fx_for_scene( e_player )
{
align = get_align_ent();
v_origin = align.origin;
v_angles = align.angles;
tag = get_align_tag();
if ( isdefined( tag ) )
{
v_origin = align GetTagOrigin( tag );
v_angles = align GetTagAngles( tag );
}
v_start = GetStartOrigin( v_origin, v_angles, _s.mainanim );
n_dist_sq = DistanceSquared( e_player.origin, v_start );
if ( ( n_dist_sq > 500 * 500 || isdefined( e_player.hijacked_vehicle_entity ) ) && ( !( isdefined( e_player.force_short_scene_transition_effect ) && e_player.force_short_scene_transition_effect ) ) )
{
self thread regroup_invulnerability( e_player );
e_player clientfield::increment_to_player( "postfx_igc", 1 ); // full effect
}
else
{
e_player clientfield::increment_to_player( "postfx_igc", 3 ); // minimal effect
}
util::wait_network_frame(); // make sure postfx capture frame before we teleport
}
function regroup_invulnerability( e_player )
{
e_player endon( "disconnect" );
e_player.ignoreme = true;
e_player.b_teleport_invulnerability = true;
e_player util::streamer_wait( undefined, 0, 7 );
e_player.ignoreme = false;
e_player.b_teleport_invulnerability = undefined;
}
function get_lerp_time()
{
if ( IsPlayer( _e ) )
{
return ( isdefined( _s.LerpTime ) ? _s.LerpTime : 0 );
}
else
{
return ( isdefined( _s.EntityLerpTime ) ? _s.EntityLerpTime : 0 );
}
}
function get_camera_tween()
{
return ( isdefined( _s.CameraTween ) ? _s.CameraTween : 0 );
}
function get_camera_tween_out()
{
return ( isdefined( _s.CameraTweenOut ) ? _s.CameraTweenOut : 0 );
}
function link_player()
{
self endon( "done" );
level flag::wait_till( "all_players_spawned" );
player = _player;
player Hide();
e_linked = player GetLinkedEnt();
if ( isdefined( e_linked ) && ( e_linked == _e ) )
{
// Update link/clamp if linking to same entity
if ( ( isdefined( _s.lockview ) && _s.lockview ) )
{
player PlayerLinkToAbsolute( _e, "tag_player" );
}
else
{
player LerpViewAngleClamp( .2, .1, .1, (isdefined(_s.viewclampright)?_s.viewclampright:0), (isdefined(_s.viewclampleft)?_s.viewclampleft:0), (isdefined(_s.viewclamptop)?_s.viewclamptop:0), (isdefined(_s.viewclampbottom)?_s.viewclampbottom:0) );
}
return;
}
player DisableUsability();
player DisableOffhandWeapons();
// player DisableWeapons( true );
player DisableWeapons(); //TODO_CODE: QUICK weapon switch only supported for SP at the momement
util::wait_network_frame();
if ( _s.cameratween > 0 )
{
// player StartCameraTween( _s.cameratween ); //TODO_CODE: only supported for SP at the momement
}
player notify( "scene_link" );
waittillframeend; // allow level script to do custom stuff before linking
if ( ( isdefined( _s.lockview ) && _s.lockview ) )
{
player PlayerLinkToAbsolute( _e, "tag_player" );
}
else
{
player PlayerLinkToDelta( _e, "tag_player", 1, (isdefined(_s.viewclampright)?_s.viewclampright:0), (isdefined(_s.viewclampleft)?_s.viewclampleft:0), (isdefined(_s.viewclamptop)?_s.viewclamptop:0), (isdefined(_s.viewclampbottom)?_s.viewclampbottom:0), 1, 1 );
// player SetPlayerViewRateScale( 100 ); //TODO_CODE: only supported for SP at the momement
}
wait ( _s.cameratween > .2 ? _s.cameratween : .2 );
_e Show();
}
function reset_player()
{
level flag::wait_till( "all_players_spawned" );
player = _player;
// player StartCameraTween( .2 ); //TODO_CODE: only supported for SP at the momement
// player ShowViewModel(); //TODO_CODE: only supported for SP at the momement
// player SetLowReady( false ); //TODO_CODE: only supported for SP at the momement
// player ResetPlayerViewRateScale(); //TODO_CODE: only supported for SP at the momement
player EnableUsability();
player EnableOffhandWeapons();
player EnableWeapons();
player Show();
}
function has_init_state()
{
return _s scene::_has_init_state();
}
function is_alive()
{
return ( isdefined( _e ) && ( _e.health > 0 || _s.IgnoreAliveCheck === true ) );
}
function is_player()
{
return ( IsDefined( _s.player ) );
}
function is_player_model()
{
return _s.type === "player model";
}
function is_shared_player()
{
return ( IsDefined( _s.player ) && ( isdefined( _s.SharedIGC ) && _s.SharedIGC ) );
}
function in_a_different_scene()
{
return ( isdefined( _e ) && isdefined( _e.current_scene ) && ( _e.current_scene != _o_bundle._str_name ) );
}
function _should_skip_anim( animation )
{
if(!( isdefined( _s.player ) && _s.player ) && !( isdefined( _s.sharedigc ) && _s.sharedigc ) && !( isdefined( _s.KeepWhileSkipping ) && _s.KeepWhileSkipping ) && ( isdefined( [[_o_bundle]]->is_skipping_scene() ) && [[_o_bundle]]->is_skipping_scene() ) && ( isdefined( _s.DeleteWhenFinished ) && _s.DeleteWhenFinished ))
{
if( !AnimHasImportantNotifies(animation) )
{
if ( !IsSpawner( _e ) )
{
b_allows_multiple = [[scene()]]->allows_multiple();
e = scene::get_existing_ent( _str_name, b_allows_multiple );
if( isdefined(e) )
{
return false;
}
}
return true;
}
}
return false;
}
function _should_skip_entity()
{
if(!( isdefined( _s.player ) && _s.player ) && !( isdefined( _s.sharedigc ) && _s.sharedigc ) && !( isdefined( _s.KeepWhileSkipping ) && _s.KeepWhileSkipping ) && ( isdefined( [[_o_bundle]]->is_skipping_scene() ) && [[_o_bundle]]->is_skipping_scene() ) && ( isdefined( _s.DeleteWhenFinished ) && _s.DeleteWhenFinished ))
{
if( isdefined(_s.initanim) && AnimHasImportantNotifies(_s.initanim) )
{
return false;
}
if( isdefined(_s.mainanim) && AnimHasImportantNotifies(_s.mainanim) )
{
return false;
}
if( isdefined(_s.endanim) && AnimHasImportantNotifies(_s.endanim) )
{
return false;
}
if ( !IsSpawner( _e ) )
{
b_allows_multiple = [[scene()]]->allows_multiple();
e = scene::get_existing_ent( _str_name, b_allows_multiple );
if( isdefined(e) )
{
return false;
}
}
return true;
}
return false;
}
function private skip_anim_on_client(entity, anim_name)
{
if(!isdefined(anim_name))
return;
if(!isdefined(entity))
return;
if(!( entity IsPlayingAnimScripted()))
return;
is_looping = IsAnimLooping(anim_name);
if(is_looping)
return;
entity clientfield::increment( "player_scene_animation_skip" );
}
function private skip_anim_on_server( entity, anim_name )
{
if(!isdefined(anim_name))
return;
if(!isdefined(entity))
return;
//@ToDo : change this to check on the anim_name
if(!( entity IsPlayingAnimScripted()))
return;
is_looping = IsAnimLooping(anim_name);
if(is_looping)
{
entity animation::stop();
}
else
{
entity SetAnimTimebyName(anim_name, 1);
}
entity stopsounds();
}
function skip_scene_on_client()
{
if(isdefined(self.current_playing_anim))
{
/#
if( GetDvarInt("debug_scene_skip") > 0)
{
PrintTopRightln( "csceneobject::skip_scene_on_client: " + _s.mainanim + " : " + GetTime(), (0.8, 0.8 , 0.8) );
}
#/
if ( is_shared_player() )
{
foreach ( player in level.players )
{
skip_anim_on_client(player, self.current_playing_anim[player GetEntityNumber()]);
}
}
else
{
skip_anim_on_client(_e, self.current_playing_anim );
}
return true;
}
return false;
}
function skip_scene_on_server()
{
if(isdefined(self.current_playing_anim))
{
/#
if( GetDvarInt("debug_scene_skip") > 0)
{
PrintTopRightln("csceneobject::skip_scene: " + _s.mainanim + " : " + GetTime(), ( 1, 1, 1 ));
}
#/
if ( is_shared_player() )
{
foreach ( player in level.players )
{
//ToDo: follow up
//player EnableInvulnerability();
skip_anim_on_server(player, self.current_playing_anim[player GetEntityNumber()]);
}
}
else
{
/*
*ToDo: follow up
if(IsPlayer( _e) )
{
player EnableInvulnerability();
}
*/
skip_anim_on_server(_e, self.current_playing_anim );
}
}
}
function skip_scene(b_wait_one_frame)
{
if(isdefined(b_wait_one_frame)) //wait for the animation to start
{
wait 0.05;
}
if(skip_scene_on_client())
{
wait 0.05;
}
skip_scene_on_server();
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ___ ___ ___ _ _ ___
// / __| / __| | __| | \| | | __|
// \__ \ | (__ | _| | .` | | _|
// |___/ \___| |___| |_|\_| |___|
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class cScene : cScriptBundleBase
{
var _e_root;
var _str_state;
var _n_object_id;
var _str_mode;
var _str_notify_name;
var _n_request_time;
var _n_streamer_req;
constructor()
{
_n_object_id = 0;
_str_mode = "";
_n_streamer_req = -1;
}
destructor()
{
}
function init( str_scenedef, s_scenedef, e_align, a_ents, b_test_run )
{
/#
if( GetDvarInt("debug_scene") > 0)
{
PrintTopRightln("cscene::init : " + str_scenedef);
}
if( isdefined( level.scriptbundles[ "scene" ][ s_scenedef.name ] ) )
{
level.scriptbundles[ "scene" ][ s_scenedef.name ].used = true;
}
#/
cScriptBundleBase::init( str_scenedef, s_scenedef, b_test_run );
if( isdefined( s_scenedef.streamerhint ) && s_scenedef.streamerhint != "" && !is_skipping_scene())
{
_n_streamer_req = streamerRequest( "set", s_scenedef.streamerhint );
}
_str_notify_name = ( IsString( _s.MaleBundle ) ? _s.MaleBundle : _str_name );
if ( !isdefined( a_ents ) ) a_ents = []; else if ( !IsArray( a_ents ) ) a_ents = array( a_ents );;
if ( !error( a_ents.size > _s.objects.size, "Trying to use more entities than scene supports." ) )
{
_e_root = e_align;
if ( !isdefined( level.active_scenes[ _str_name ] ) ) level.active_scenes[ _str_name ] = []; else if ( !IsArray( level.active_scenes[ _str_name ] ) ) level.active_scenes[ _str_name ] = array( level.active_scenes[ _str_name ] ); level.active_scenes[ _str_name ][level.active_scenes[ _str_name ].size]=_e_root;;
if ( !isdefined( _e_root.scenes ) ) _e_root.scenes = []; else if ( !IsArray( _e_root.scenes ) ) _e_root.scenes = array( _e_root.scenes ); _e_root.scenes[_e_root.scenes.size]=self;;
a_objs = get_valid_object_defs();
foreach ( s_obj in a_objs )
{
add_object( [[ [[self]]->new_object() ]]->first_init( s_obj, self ) );
}
_n_request_time = GetTime();
if ( !( isdefined( _s.DontSync ) && _s.DontSync ) )
{
add_to_sync_list();
}
self thread initialize( a_ents );
}
}
function add_to_sync_list()
{
if(!isdefined(level.scene_sync_list))level.scene_sync_list=[];
if(!isdefined(level.scene_sync_list[ _n_request_time ]))level.scene_sync_list[ _n_request_time ]=[];
array::add( level.scene_sync_list[ _n_request_time ], self, false );
}
function remove_from_sync_list()
{
if ( isdefined(level.scene_sync_list) && isdefined( level.scene_sync_list[ _n_request_time ] ) )
{
ArrayRemoveValue( level.scene_sync_list[ _n_request_time ], self );
if ( !level.scene_sync_list[ _n_request_time ].size )
{
level.scene_sync_list[ _n_request_time ] = undefined;
}
}
}
function new_object()
{
return new cSceneObject();
}
function get_valid_object_defs()
{
a_obj_defs = [];
foreach ( s_obj in _s.objects )
{
if ( _s.vmtype == "server" || s_obj.vmtype == "server" )
{
if ( isdefined( s_obj.name ) || isdefined( s_obj.model ) || isdefined( s_obj.initanim ) || isdefined( s_obj.mainanim ) )
{
if ( !( isdefined( s_obj.disabled ) && s_obj.disabled ) )
{
if ( !isdefined( a_obj_defs ) ) a_obj_defs = []; else if ( !IsArray( a_obj_defs ) ) a_obj_defs = array( a_obj_defs ); a_obj_defs[a_obj_defs.size]=s_obj;;
}
}
}
}
return a_obj_defs;
}
function initialize( a_ents, b_playing = false )
{
self notify( "new_state" );
self endon( "new_state" );
self thread sync_with_client_scene( "init", _testing );
assign_ents( a_ents );
if ( get_valid_objects().size > 0 )
{
level flagsys::set( _str_name + "_initialized" );
_str_state = "init";
foreach ( o_obj in _a_objects )
{
thread [[o_obj]]->initialize();
}
}
if ( !b_playing )
{
thread _call_state_funcs( "init" );
}
wait_till_scene_ready();
level flagsys::set( _str_notify_name + "_ready" );
// stops the scene if all objects die in the initialize state
array::flagsys_wait( _a_objects, "done" );
thread stop();
}
function get_object_id()
{
_n_object_id++;
return _n_object_id;
}
function sync_with_client_scene( str_state, b_test_run = false )
{
if ( _s.vmtype == "both" && !_s scene::is_igc() )
{
self endon( "new_state" );
wait_till_scene_ready();
n_val = undefined;
if ( b_test_run )
{
switch ( str_state )
{
case "stop":
n_val = 3;
break;
case "init":
n_val = 4;
break;
case "play":
n_val = 5;
break;
}
}
else
{
switch ( str_state )
{
case "stop":
n_val = 0;
break;
case "init":
n_val = 1;
break;
case "play":
n_val = 2;
break;
}
}
level clientfield::set( _s.name, n_val );
}
}
function assign_ents( a_ents )
{
if ( !isdefined( a_ents ) ) a_ents = []; else if ( !IsArray( a_ents ) ) a_ents = array( a_ents );;
a_objects = ArrayCopy( _a_objects );
if ( _assign_ents_by_name( a_objects, a_ents ) )
{
if ( _assign_ents_by_type( a_objects, a_ents, "player", &_is_ent_player ) )
{
if ( _assign_ents_by_type( a_objects, a_ents, "actor", &_is_ent_actor ) )
{
if ( _assign_ents_by_type( a_objects, a_ents, "vehicle", &_is_ent_vehicle ) )
{
if ( _assign_ents_by_type( a_objects, a_ents, "prop" ) )
{
foreach ( ent in a_ents )
{
obj = array::pop( a_objects );
if ( !error( !isdefined( obj ), "No scene object to assign entity too. You might have passed in more than the scene supports." ) )
{
obj._e = ent;
}
}
}
}
}
}
}
}
function _assign_ents_by_name( &a_objects, &a_ents )
{
if ( a_ents.size )
{
foreach ( str_name, e_ent in ArrayCopy( a_ents ) )
{
foreach ( i, o_obj in ArrayCopy( a_objects ) )
{
if ( isdefined( o_obj._s.name ) && ( (isdefined(o_obj._s.name)?""+o_obj._s.name:"") == ToLower( (isdefined(str_name)?""+str_name:"") ) ) )
{
o_obj._e = e_ent;
ArrayRemoveIndex( a_ents, str_name, true );
ArrayRemoveIndex( a_objects, i );
break;
}
}
}
/#
// Check for any remaining entities with specific names that don't have objects to assign them to
foreach ( i, ent in a_ents )
{
error( IsString( i ), "No scene object with name '" + i + "'." );
}
#/
}
return a_ents.size;
}
function _assign_ents_by_type( &a_objects, &a_ents, str_type, func_test )
{
if ( a_ents.size )
{
a_objects_of_type = get_objects( str_type );
if ( a_objects_of_type.size )
{
foreach ( ent in ArrayCopy( a_ents ) )
{
if ( isdefined( func_test ) && [[ func_test ]]( ent ) )
{
obj = array::pop_front( a_objects_of_type );
if ( isdefined( obj ) )
{
obj._e = ent;
ArrayRemoveValue( a_ents, ent, true );
ArrayRemoveValue( a_objects, obj );
}
else
{
break;
}
}
}
}
}
return a_ents.size;
}
function _is_ent_player( ent )
{
return ( IsPlayer( ent ) );
}
function _is_ent_actor( ent )
{
return ( IsActor( ent ) || IsActorSpawner( ent ) );
}
function _is_ent_vehicle( ent )
{
return ( IsVehicle( ent ) || IsVehicleSpawner( ent ) );
}
function get_objects( str_type )
{
a_ret = [];
foreach ( obj in _a_objects )
{
if ( obj._s.type == str_type )
{
if ( !isdefined( a_ret ) ) a_ret = []; else if ( !IsArray( a_ret ) ) a_ret = array( a_ret ); a_ret[a_ret.size]=obj;;
}
}
return a_ret;
}
function get_anim_relative_start_time(animation, n_time)
{
if(!isdefined(self.n_start_time) || self.n_start_time == 0 || !isdefined(self.longest_anim_length) || self.longest_anim_length == 0)
return n_time;
anim_length = GetAnimLength(animation);
is_looping = IsAnimLooping(animation);
n_time = self.longest_anim_length / anim_length * n_time;
if(is_looping)
{
if(n_time > 0.95)
n_time = 0.95;
}
else
{
if(n_time > 0.99)
n_time = 0.99;
}
return n_time;
}
function is_player_anim_ending_early()
{
max_anim_length = -1;
player_anim_length = -1;
foreach ( obj in _a_objects )
{
if(isdefined(obj._s.MainAnim))
{
anim_length = GetAnimLength( obj._s.MainAnim );
}
if ( ( obj._s.type === "player" ) )
{
player_anim_length = anim_length;
}
if(anim_length > max_anim_length)
{
max_anim_length = anim_length;
}
}
return player_anim_length < max_anim_length;
}
function play( str_state = "play", a_ents, b_testing = false, str_mode = "" )
{
/#
if( GetDvarInt("debug_scene") > 0)
{
PrintTopRightln("cscene::play : " + _s.name);
}
#/
self notify( "new_state" );
self endon( "new_state" );
if(str_mode == "skip_scene")
{
thread skip_scene( true );
}
else if(str_mode == "skip_scene_player")
{
self.b_player_scene = true;
thread skip_scene( true );
}
else if(!is_skipping_scene() && is_scene_shared_sequence() && !is_scene_shared()) //stop the shared sequence if the next (current) scene is not shared.
{
init_scene_sequence_started( false);
}
update_scene_sequence();
_testing = b_testing;
_str_mode = str_mode;
if(( isdefined( _s.SpectateOnJoin ) && _s.SpectateOnJoin ))
{
level.scene_should_spectate_on_hot_join = true;
}
assign_ents( a_ents );
if ( StrStartsWith( _str_mode, "capture" ) )
{
/* First-frame the scene and move player to align node to stream the scene */
if ( get_valid_objects().size )
{
foreach ( o_obj in _a_objects )
{
thread [[o_obj]]->initialize( true );
}
}
thread loop_camera_anim_to_set_up_for_capture(); // put player camera in a more accurate postiion for streaming
// move the player to the align node and link them so they don't fall if there's nothing under them
capture_player = level.players[ 0 ];
v_origin = get_align_ent().origin;
if ( !isdefined( capture_player.e_capture_link ) )
{
capture_player.e_capture_link = util::spawn_model( "tag_origin", v_origin );
capture_player SetOrigin( v_origin );
capture_player Linkto( level.players[ 0 ].e_capture_link );
}
else
{
capture_player.e_capture_link.origin = v_origin;
}
wait 15; // give scene time in the init state to load textures, also the code needs time in between captures
thread _stop_camera_anims();
}
self thread sync_with_client_scene( "play", b_testing );
/* Get animation start time from the mode string */
self.n_start_time = 0;
if ( IsSubStr( str_mode, "skipto" ) )
{
args = StrTok( str_mode, ":" );
if ( isdefined( args[1] ) )
{
self.n_start_time = Float( args[1] );
}
else
{
// skip to end of animation - can't go all the way to 1 because looping animations will assert
self.n_start_time = .95;
}
self.longest_anim_length = 0;
foreach ( s_obj in _a_objects )
{
if ( isdefined( s_obj._s.MainAnim ) )
{
anim_length = GetAnimLength( s_obj._s.MainAnim );
if ( anim_length > self.longest_anim_length )
{
self.longest_anim_length = anim_length;
}
}
}
}
/* ---------------------------------------------- */
if ( get_valid_objects().size || _s scene::is_igc() )
{
level flagsys::set( _str_name + "_playing" );
_str_state = "play";
foreach ( o_obj in _a_objects )
{
thread [[o_obj]]->play();
}
wait_till_scene_ready();
level flagsys::set( _str_notify_name + "_ready" );
if ( StrStartsWith( _str_mode, "capture" ) )
{
/# AddDebugCommand( "startGfxCapture sceneFinal 0 30 tga captures/" + _str_name + " " + _str_name ); #/
}
if ( self.n_start_time == 0 )
{
self thread _play_camera_anims();
}
/#
if ( is_scene_shared() )
{
display_dev_info();
}
#/
if( _n_streamer_req != -1 && !is_skipping_scene())
{
streamerRequest( "play", _s.streamerhint );
}
thread _call_state_funcs( "play" );
if ( _s scene::is_igc() )
{
if ( !( isdefined( _s.DisableSceneSkipping ) && _s.DisableSceneSkipping ) && _str_state != "init" )
{
trigger_scene_sequence_started(self); //send self as cscene to force triggering the sequnce
}
if ( IsString( _s.cameraswitcher ) )
{
_wait_for_camera_animation( _s.cameraswitcher, self.n_start_time );
}
else if ( IsString( _s.extraCamSwitcher1 ) )
{
_wait_for_camera_animation( _s.extraCamSwitcher1, self.n_start_time );
}
else if ( IsString( _s.extraCamSwitcher2 ) )
{
_wait_for_camera_animation( _s.extraCamSwitcher2, self.n_start_time );
}
else if ( IsString( _s.extraCamSwitcher3 ) )
{
_wait_for_camera_animation( _s.extraCamSwitcher3, self.n_start_time );
}
else if ( IsString( _s.extraCamSwitcher4 ) )
{
_wait_for_camera_animation( _s.extraCamSwitcher4, self.n_start_time );
}
foreach ( o_obj in _a_objects )
{
thread [[o_obj]]->stop( false, ( isdefined( o_obj._s.DontClamp ) && o_obj._s.DontClamp ), true );
}
_e_root notify( "scene_done", _str_notify_name );
thread _call_state_funcs( "done" );
if ( ( isdefined( _s.SpectateOnJoin ) && _s.SpectateOnJoin ) )
{
level.scene_should_spectate_on_hot_join = undefined;
}
}
else
{
array::flagsys_wait_any_flag( _a_objects, "done", "main_done" );
if ( isdefined( _e_root ) )
{
_e_root notify( "scene_done", _str_notify_name );
}
thread _call_state_funcs( "done" );
if ( ( isdefined( _s.SpectateOnJoin ) && _s.SpectateOnJoin ) )
{
level.scene_should_spectate_on_hot_join = undefined;
}
array::flagsys_wait( _a_objects, "done" );
}
if ( is_looping() || ( StrEndsWith( _str_mode, "loop" ) ) )
{
if ( has_init_state() )
{
level flagsys::clear( _str_name + "_playing" );
thread initialize();
}
else
{
level flagsys::clear( _str_name + "_initialized" );
thread play( str_state, undefined, b_testing, str_mode );
}
}
else
{
if ( !StrEndsWith( _str_mode, "single" ) )
{
thread run_next();
}
else
{
if( !is_skipping_scene() ) //if we are not skipping a scene then just notify that a scene sequence has ended
{
if(is_scene_shared_sequence())
{
init_scene_sequence_started(false);
}
}
else if(isdefined(level.linked_scenes)) //if we are skipping a scene, remove it from the linked scenes if it exists
{
ArrayRemoveValue(level.linked_scenes, _s.name );
}
streamer_request_completed();
}
if ( !_s scene::is_igc() || !( isdefined( _s.holdCameraLastFrame ) && _s.holdCameraLastFrame ) )
{
// Scenes set to hold camera last frame must be stopped manually with scene::stop()
thread stop( false, true );
}
}
}
else
{
thread stop( false, true );
}
}
function _wait_server_time( n_time, n_start_time = 0 )
{
n_len = ( n_time - ( n_time * n_start_time ) ); // get the length we need to wait from the desired start time fraction
n_len = n_len / .05;
n_len_int = Int( n_len );
if ( n_len_int != n_len )
{
n_len = Floor( n_len );
}
n_server_length = n_len * .05; // clamp to full server frames.
wait n_server_length;
}
function _wait_for_camera_animation( str_cam, n_start_time )
{
self endon( "skip_camera_anims" );
if ( IsCamAnimLooping( str_cam ) )
{
level waittill( "forever" );
}
else
{
_wait_server_time( GetCamAnimTime( str_cam ) / 1000, n_start_time );
}
}
function _play_camera_anims()
{
level endon( "stop_camera_anims" );
waittillframeend;
e_align = get_align_ent();
v_origin = ( isdefined( e_align.origin ) ? e_align.origin : ( 0, 0, 0 ) );
v_angles = ( isdefined( e_align.angles ) ? e_align.angles : ( 0, 0, 0 ) );
xcam_players = [];
if(( isdefined( _s.LinkXCamToOnePlayer ) && _s.LinkXCamToOnePlayer ))
{
foreach ( o_obj in _a_objects )
{
if( isdefined(o_obj) && [[o_obj]]->is_player() && ![[o_obj]]->is_shared_player() )
{
if ( !isdefined( xcam_players ) ) xcam_players = []; else if ( !IsArray( xcam_players ) ) xcam_players = array( xcam_players ); xcam_players[xcam_players.size]=o_obj._player;;
}
}
if(xcam_players.size == 0)
{
xcam_players = level.players;
}
else
{
self.a_xcam_players = xcam_players;
}
}
else
{
xcam_players = level.players;
}
if ( IsString( _s.cameraswitcher ) )
{
if(!( isdefined( _s.LinkXCamToOnePlayer ) && _s.LinkXCamToOnePlayer ))
{
callback::on_loadout( &_play_camera_anim_on_player_callback, self );
}
self.camera_v_origin = v_origin;
self.camera_v_angles = v_angles;
self.camera_start_time = GetTime();
array::thread_all_ents( xcam_players, &_play_camera_anim_on_player, v_origin, v_angles, false );
// hide_players();
/#display_dev_info();#/
}
if ( IsString( _s.extraCamSwitcher1 ) )
{
array::thread_all_ents( xcam_players, &_play_extracam_on_player, 0, _s.extraCamSwitcher1, v_origin, v_angles );
}
if ( IsString( _s.extraCamSwitcher2 ) )
{
array::thread_all_ents( xcam_players, &_play_extracam_on_player, 1, _s.extraCamSwitcher2, v_origin, v_angles );
}
if ( IsString( _s.extraCamSwitcher3 ) )
{
array::thread_all_ents( xcam_players, &_play_extracam_on_player, 2, _s.extraCamSwitcher3, v_origin, v_angles );
}
if ( IsString( _s.extraCamSwitcher4 ) )
{
array::thread_all_ents( xcam_players, &_play_extracam_on_player, 3, _s.extraCamSwitcher4, v_origin, v_angles );
}
}
function _play_camera_anim_on_player_callback( player )
{
self thread _play_camera_anim_on_player(player, self.camera_v_origin, self.camera_v_angles, true);
}
function _play_camera_anim_on_player( player, v_origin, v_angles, ignore_initial_notetracks )
{
player notify( "new_camera_switcher" );
player DontInterpolate();
player thread scene::scene_disable_player_stuff();
self.played_camera_anims = true;
n_start_time = self.camera_start_time;
if(!isdefined(_s.cameraSwitcherGraphicContents) || IsMature( player ))
{
//@ToDo - Enable once the new exe populated (8/14/2015)
CamAnimScripted( player, _s.cameraswitcher, n_start_time, v_origin, v_angles );
//CamAnimScripted( player, _s.cameraswitcher, n_start_time, v_origin, v_angles, 0, "", ignore_initial_notetracks );
}
else
{
//@ToDo - Enable once the new exe populated (8/14/2015)
CamAnimScripted( player, _s.cameraSwitcherGraphicContents, n_start_time, v_origin, v_angles );
//CamAnimScripted( player, _s.cameraSwitcherGraphicContents, n_start_time, v_origin, v_angles, 0, "", ignore_initial_notetracks );
}
}
function loop_camera_anim_to_set_up_for_capture()
{
level endon( "stop_camera_anims" );
while ( true )
{
_play_camera_anims();
_wait_for_camera_animation( _s.cameraswitcher );
}
}
function _play_extracam_on_player( player, n_index, str_camera_anim, v_origin, v_angles )
{
self.played_camera_anims = true;
ExtraCamAnimScripted( player, n_index, str_camera_anim, GetTime(), v_origin, v_angles );
}
function _stop_camera_anims()
{
if(!( isdefined( self.played_camera_anims ) && self.played_camera_anims )) //no camera anims were played to be stopped
{
return;
}
level notify( "stop_camera_anims" );
xcam_players = [];
if(isdefined(self.a_xcam_players))
{
xcam_players = self.a_xcam_players;
}
else
{
xcam_players = GetPlayers();
}
foreach ( player in xcam_players )
{
if ( isdefined( player ) )
{
self thread _stop_camera_anim_on_player( player );
}
}
// show_players();
}
function _stop_camera_anim_on_player( player )
{
player endon( "disconnect" );
if ( IsString( _s.cameraswitcher ) )
{
player endon( "new_camera_switcher" );
player DontInterpolate();
EndCamAnimScripted( player );
player thread scene::scene_enable_player_stuff();
if(!( isdefined( _s.LinkXCamToOnePlayer ) && _s.LinkXCamToOnePlayer ))
{
callback::remove_on_loadout( &_play_camera_anim_on_player_callback, self );
}
}
// TODO: do we want the extracam animations to stop?
if ( IsString( _s.extraCamSwitcher1 ) )
{
EndExtraCamAnimScripted( player, 0 );
}
if ( IsString( _s.extraCamSwitcher2 ) )
{
EndExtraCamAnimScripted( player, 1 );
}
if ( IsString( _s.extraCamSwitcher3 ) )
{
EndExtraCamAnimScripted( player, 2 );
}
if ( IsString( _s.extraCamSwitcher4 ) )
{
EndExtraCamAnimScripted( player, 3 );
}
}
function display_dev_info()
{
if ( IsString( _s.devstate ) && GetDvarInt( "scr_show_shot_info_for_igcs", 0 ) )
{
if ( !isdefined( level.hud_scene_dev_info1 ) )
{
level.hud_scene_dev_info1 = NewHudElem();
level.hud_scene_dev_info1.alignX = "right";
level.hud_scene_dev_info1.alignY = "bottom";
level.hud_scene_dev_info1.horzAlign = "user_right";
level.hud_scene_dev_info1.y = 400;
level.hud_scene_dev_info1.fontScale = 1.3;
level.hud_scene_dev_info1.color = (112/255,128/255,144/255);
level.hud_scene_dev_info1 SetText( "SCENE: " + ToUpper( _s.name ) );
}
if ( !isdefined( level.hud_scene_dev_info2 ) )
{
level.hud_scene_dev_info2 = NewHudElem();
level.hud_scene_dev_info2.alignX = "right";
level.hud_scene_dev_info2.alignY = "bottom";
level.hud_scene_dev_info2.horzAlign = "user_right";
level.hud_scene_dev_info2.y = 420;
level.hud_scene_dev_info2.fontScale = 1.3;
level.hud_scene_dev_info2.color = (112/255,128/255,144/255);
}
level.hud_scene_dev_info2 SetText( "SHOT: " + ToUpper( _s.name ) );
if ( !isdefined( level.hud_scene_dev_info3 ) )
{
level.hud_scene_dev_info3 = NewHudElem();
level.hud_scene_dev_info3.alignX = "right";
level.hud_scene_dev_info3.alignY = "bottom";
level.hud_scene_dev_info3.horzAlign = "user_right";
level.hud_scene_dev_info3.y = 440;
level.hud_scene_dev_info3.fontScale = 1.3;
level.hud_scene_dev_info3.color = (112/255,128/255,144/255);
level.hud_scene_dev_info3 SetText( "STATE: " + ToUpper( _s.devstate ) );
}
}
else
{
destroy_dev_info();
}
}
function destroy_dev_info()
{
if ( isdefined( level.hud_scene_dev_info1 ) )
{
level.hud_scene_dev_info1 Destroy();
}
if ( isdefined( level.hud_scene_dev_info2 ) )
{
level.hud_scene_dev_info2 Destroy();
}
if ( isdefined( level.hud_scene_dev_info3 ) )
{
level.hud_scene_dev_info3 Destroy();
}
}
function is_skipping_scene()
{
if( _s.name == "cin_ram_02_04_interview_part04" )//HACK - TU1, remove this later and enable the commented out section below
{
return false;
}
return ( ( ( isdefined( self.skipping_scene ) && self.skipping_scene ) || self._str_mode == "skip_scene" || self._str_mode == "skip_scene_player" ) /*&& !IS_TRUE( _s.disablesceneskipping )*/ );//TU1 - add this in later
}
function is_skipping_player_scene()
{
return ( ( isdefined( self.b_player_scene ) && self.b_player_scene ) || self._str_mode == "skip_scene_player") && !array::contains(level.linked_scenes, _s.name);
}
function has_next_scene()
{
return isdefined(_s.nextscenebundle);
}
function run_next()
{
/#
if( GetDvarInt("debug_scene") > 0)
{
PrintTopRightln("cscene::run_next : " + GetTime());
}
#/
b_run_next_scene = false;
if ( isdefined( _s.nextscenebundle ) )
{
self waittill( "stopped", b_finished );
if ( b_finished )
{
b_skip_scene = is_skipping_scene();
if(b_skip_scene)
{
self util::waittill_any_timeout( 5, "scene_skip_completed");
/#
if( GetDvarInt("debug_scene_skip") > 0)
{
PrintTopRightln("cscene::run_next - scene skipped : " + _s.nextscenebundle + " : " + GetTime(), (1, 1, 0));
}
#/
}
/#
if( GetDvarInt("debug_scene_skip") > 0)
{
PrintTopRightln("cscene::run_next : " + _s.nextscenebundle + " : " + GetTime(), ( 1, 0, 0 ));
}
#/
if ( _s.scenetype == "fxanim" && ( _s.nextscenemode === "init" ) )
{
if ( !error( !has_init_state(), "Scene can't init next scene '" + _s.nextscenebundle + "' because it doesn't have an init state." ) )
{
if ( allows_multiple() )
{
_e_root thread scene::init( _s.nextscenebundle, get_ents() );
}
else
{
_e_root thread scene::init( _s.nextscenebundle );
}
}
}
else
{
if(b_skip_scene)
{
if( is_skipping_player_scene() )
{
_str_mode = "skip_scene_player";
}
else
{
_str_mode = "skip_scene";
}
}
else
{
b_run_next_scene = true;
}
if ( allows_multiple() )
{
_e_root thread scene::play( _s.nextscenebundle, get_ents(), undefined, undefined, undefined, _str_mode );
}
else
{
_e_root thread scene::play( _s.nextscenebundle, undefined, undefined, undefined, undefined, _str_mode );
}
}
}
}
if( !( isdefined( b_run_next_scene ) && b_run_next_scene ) )
{
if(!is_skipping_scene()) //if we are not skipping a scene then just notify that the scene sequence has ended
{
if(is_scene_shared_sequence())
{
init_scene_sequence_started(false);
}
}
else if(isdefined(level.linked_scenes)) //if we are skipping a scene, remove it from the linked scenes if it exists
{
ArrayRemoveValue(level.linked_scenes, _s.name );
}
streamer_request_completed();
}
}
function streamer_request_completed()
{
if( IsString( _s._endStreamerHint ) )
{
if( GetDvarInt("scene_hide_player") > 0 )
{
foreach(player in level.players)
{
player Show();
}
}
streamerRequest( "clear", _s._endStreamerHint );
}
}
function stop( b_clear = false, b_finished = false )
{
/#
if( GetDvarInt("debug_scene") > 0)
{
PrintTopRightln("cscene::stop : " + _s.name);
}
#/
if ( isdefined( _str_state ) )
{
/#
if( GetDvarInt("debug_scene") > 0)
{
PrintTopRightln("cscene::stop : " + _s.name + " : "+ _str_state);
}
#/
/#
if ( StrStartsWith( _str_mode, "capture" ) )
{
AddDebugCommand( "stopGfxCapture 1" );
}
#/
if ( !b_finished )
{
streamer_request_completed();
}
//Handle the case where the scene was explicitly stopped
if(!is_skipping_scene())
{
if ( !isdefined( _s.nextscenebundle ) && is_scene_shared_sequence())
{
init_scene_sequence_started(false);
}
}
self thread sync_with_client_scene( "stop", b_clear );
_str_state = undefined;
self notify( "new_state" );
self notify( "death" );
level flagsys::clear( _str_name + "_playing" );
level flagsys::clear( _str_name + "_initialized" );
thread _call_state_funcs( "stop" );
self.scene_stopping = true;
if ( IsDefined( _a_objects ) && !b_finished )
{
foreach ( o_obj in _a_objects )
{
if ( isdefined( o_obj ) && ![[ o_obj ]]->in_a_different_scene() )
{
thread [[o_obj]]->stop( b_clear );
}
}
}
self thread _stop_camera_anims();
/#
if ( !isdefined( _s.nextscenebundle ) || !b_finished )
{
destroy_dev_info();
}
#/
/#
if( GetDvarInt("debug_scene") > 0)
{
PrintTopRightln("cscene::stopped notify sent : " + _s.name);
}
#/
self.scene_stopped = true;
self notify( "stopped", b_finished );
remove_from_sync_list();
ArrayRemoveValue( level.active_scenes[ _str_name ], _e_root );
if ( level.active_scenes[ _str_name ].size == 0 )
{
level.active_scenes[ _str_name ] = undefined;
}
if ( isdefined( _e_root ) )
{
ArrayRemoveValue( _e_root.scenes, self );
if ( _e_root.scenes.size == 0 )
{
_e_root.scenes = undefined;
}
_e_root notify( "scene_done", _str_notify_name );
_e_root.scene_played = true;
}
}
if(( isdefined( _s.SpectateOnJoin ) && _s.SpectateOnJoin ))
{
level.scene_should_spectate_on_hot_join = undefined;
}
self thread _release_object();
}
function _release_object()
{
// HACK: Make sure all the objects release their handle to the scene
{wait(.05);};
foreach ( o_obj in _a_objects )
{
o_obj._o_bundle = undefined;
}
}
// function hide_players()
// {
// if ( IS_TRUE( _s.HidePlayers ) )
// {
// foreach ( player in level.players )
// {
// player SetInvisibleToAll();
// }
// }
// }
// function show_players()
// {
// if ( IS_TRUE( _s.HidePlayers ) )
// {
// foreach ( player in level.players )
// {
// player SetVisibleToAll();
// }
// }
// }
function has_init_state()
{
b_has_init_state = false;
foreach ( o_scene_object in _a_objects )
{
if ( [[o_scene_object]]->has_init_state() )
{
b_has_init_state = true;
break;
}
}
return b_has_init_state;
}
function _call_state_funcs( str_state )
{
self endon( "stopped" );
wait_till_scene_ready( undefined, true );
if ( str_state == "play" )
{
waittillframeend; // HACK: need to allow init callbacks to happen first if init and play happen on same frame
}
level notify( _str_notify_name + "_" + str_state );
if ( isdefined( level.scene_funcs ) && isdefined( level.scene_funcs[ _str_notify_name ] ) && isdefined( level.scene_funcs[ _str_notify_name ][ str_state ] ) )
{
a_ents = get_ents();
foreach ( handler in level.scene_funcs[ _str_notify_name ][ str_state ] )
{
func = handler[0];
args = handler[1];
switch ( args.size )
{
case 6:
_e_root thread [[ func ]]( a_ents, args[0], args[1], args[2], args[3], args[4], args[5] );
break;
case 5:
_e_root thread [[ func ]]( a_ents, args[0], args[1], args[2], args[3], args[4] );
break;
case 4:
_e_root thread [[ func ]]( a_ents, args[0], args[1], args[2], args[3] );
break;
case 3:
_e_root thread [[ func ]]( a_ents, args[0], args[1], args[2] );
break;
case 2:
_e_root thread [[ func ]]( a_ents, args[0], args[1] );
break;
case 1:
_e_root thread [[ func ]]( a_ents, args[0] );
break;
case 0:
_e_root thread [[ func ]]( a_ents );
break;
default: AssertMsg( "Too many args passed to scene func." );
}
}
}
}
function get_ents()
{
a_ents = [];
foreach ( o_obj in _a_objects )
{
ent = [[o_obj]]->get_ent();
if ( isdefined( o_obj._s.name ) )
{
a_ents[ o_obj._s.name ] = ent;
}
else
{
if ( !isdefined( a_ents ) ) a_ents = []; else if ( !IsArray( a_ents ) ) a_ents = array( a_ents ); a_ents[a_ents.size]=ent;;
}
}
return a_ents;
}
function get_root()
{
return _e_root;
}
function get_align_ent()
{
e_align = _e_root;
if ( isdefined( _s.aligntarget ) )
{
e_gdt_align = scene::get_existing_ent( _s.aligntarget, false, true );
if ( isdefined( e_gdt_align ) )
{
e_align = e_gdt_align;
}
if ( !isdefined( e_gdt_align ) )
{
str_msg = "Align target '" + (isdefined(_s.aligntarget)?""+_s.aligntarget:"") + "' doesn't exist for scene.";
if ( !warning( _testing, str_msg ) )
{
error( GetDvarInt( "scene_align_errors", 1 ), str_msg );
}
}
}
else if ( isdefined( _e_root.e_scene_link ) )
{
e_align = _e_root.e_scene_link;
}
return e_align;
}
function allows_multiple()
{
return ( isdefined( _s.allowmultiple ) && _s.allowmultiple );
}
function is_looping()
{
return ( isdefined( _s.looping ) && _s.looping );
}
function wait_till_scene_ready( o_exclude, b_ignore_streamer = false )
{
a_objects = [];
if ( isdefined( o_exclude ) )
{
a_objects = array::exclude( _a_objects, o_exclude );
}
else
{
a_objects = _a_objects;
}
wait_till_objects_ready( a_objects );
if ( _n_streamer_req != -1 )
{
if ( !b_ignore_streamer )
{
if ( isdefined( level.wait_for_streamer_hint_scenes ) )
{
if ( IsInArray( level.wait_for_streamer_hint_scenes, _s.name ) )
{
if ( !is_skipping_scene() )
{
level util::streamer_wait( _n_streamer_req, 0, 5 );
}
}
}
}
}
flagsys::set( "ready" );
sync_with_other_scenes();
}
function wait_till_objects_ready( &array )
{
do
{
recheck = false;
foreach ( ent in array )
{
if ( isdefined( ent ) && !ent flagsys::get( "ready" ) )
{
ent util::waittill_either( "death", "ready" );
recheck = true;
break;
}
}
}
while ( recheck );
}
function sync_with_other_scenes()
{
if ( !( isdefined( _s.DontSync ) && _s.DontSync ) && isdefined(level.scene_sync_list) && IsArray(level.scene_sync_list[ _n_request_time ]) )
{
// Wait for all scene objects that were requested to start on the same frame
wait_till_objects_ready( level.scene_sync_list[ _n_request_time ] );
}
}
function get_valid_objects()
{
a_obj = [];
foreach ( obj in _a_objects )
{
if ( obj._is_valid )
{
if ( !isdefined( a_obj ) ) a_obj = []; else if ( !IsArray( a_obj ) ) a_obj = array( a_obj ); a_obj[a_obj.size]=obj;;
}
}
return a_obj;
}
function on_error()
{
stop();
}
function get_state()
{
return _str_state;
}
function is_scene_shared()
{
if( !( isdefined( _s.skip_scene ) && _s.skip_scene ) && !(_s scene::is_igc()) )
{
foreach ( o_scene_object in _a_objects )
{
if ( o_scene_object._is_valid && [[o_scene_object]]->is_shared_player())
{
b_shared_player = true;
}
}
if(!isdefined(b_shared_player))
{
/#
if( GetDvarInt("debug_scene_skip") > 0)
{
PrintTopRightln("Cannot skip scene..cscene::level.players[0].skipping_scene = undefined : " + GetTime(), ( 1, 0, 0 ));
}
#/
self notify("scene_skip_completed");
return false;
}
}
return true;
}
function skip_scene( b_sequence )
{
if(( isdefined( b_sequence ) && b_sequence ) && ( isdefined( _s.DisableSceneSkipping ) && _s.DisableSceneSkipping ))
{
/#
if( GetDvarInt("debug_scene_skip") > 0)
{
PrintTopRightln("cscene::skip_scene DisableSceneSkipping - Abort: " + _s.name + " : " + GetTime(), ( 1, 0, 0 ));
}
#/
finish_skip_scene();
return;
}
/#
if( GetDvarInt("debug_scene_skip") > 0)
{
PrintTopRightln("cscene::skip_scene: " + _s.name + " : " + GetTime(), ( 0, 1, 0 ));
}
#/
if( !( isdefined( b_sequence ) && b_sequence ) )
{
if(_str_state == "init")
{
while(_str_state == "init")
{
wait 0.05;
}
}
if( is_skipping_player_scene() )
{
/#
if( GetDvarInt("debug_scene_skip") > 0)
{
PrintTopRightln("cscene::lui::screen_fade BLACK : " + GetTime());
}
#/
/#
if(GetDvarInt("scene_skip_no_fade") == 0)
{
b_skip_fading = false;
}
else
{
b_skip_fading = true;
}
#/
if(!( isdefined( b_skip_fading ) && b_skip_fading ))
{
//Freeze player controls
foreach(player in level.players)
{
player FreezeControls( true );
}
level.suspend_scene_skip_until_fade = true;
level thread lui::screen_fade( 1, 1, 0, "black", false, "scene_system" );
wait 1;
level.suspend_scene_skip_until_fade = undefined;
}
SetPauseWorld( false );
}
while(( isdefined( level.suspend_scene_skip_until_fade ) && level.suspend_scene_skip_until_fade ))
{
wait 0.05;
}
}
if(isdefined( _s.nextscenebundle ))
{
bNextSceneExist = true;
}
else
{
bNextSceneExist = false;
}
wait_till_scene_ready();
wait 0.05;
/#
if( GetDvarInt("debug_scene_skip") > 0)
{
PrintTopRightln("cscene::skip_scene - READY: " + _s.name + " : " + GetTime(), ( 0, 0, 1 ));
}
#/
_call_state_funcs("skip_started");
thread _skip_scene();
/#
if( GetDvarInt("debug_scene_skip") > 0)
{
PrintTopRightln("cscene::skip_scene - Waiting for stopped event : " + GetTime(), ( 0, 1, 0 ));
}
#/
/#
if( GetDvarInt("debug_scene_skip") > 0)
{
if(isdefined(level.animation_played))
{
for(i = 0 ; i < level.animation_played.size; i++)
{
PrintTopRightln("NON-STOPPED-ANIMATIONS : " + level.animation_played[i], ( 1, 0, 0 ), -1);
}
}
}
#/
scene_skip_timeout = GetTime() + 4000;
while( !( isdefined( self.scene_stopped ) && self.scene_stopped ) && GetTime() < scene_skip_timeout )
{
wait 0.05;
}
/#
if( GetDvarInt("debug_scene_skip") > 0)
{
PrintTopRightln("cscene::skip_scene - END: " + _s.name + " : " + GetTime(), ( 1, .5, 0 ));
}
#/
_call_state_funcs("skip_completed");
self notify("scene_skip_completed");
if(!bNextSceneExist)
{
if(is_skipping_player_scene())
{
if(isdefined(level.linked_scenes))
{
linked_scenes_timeout = GetTime() + 4000;
while(level.linked_scenes.size > 0 && GetTime() < linked_scenes_timeout)
{
wait 0.05;
}
}
finish_skip_scene();
}
else if(( isdefined( self.skipping_scene ) && self.skipping_scene ))
{
self.skipping_scene = undefined;
if(isdefined(level.linked_scenes))
{
//level.skipping_linked_scenes--;
ArrayRemoveValue(level.linked_scenes, _s.name );
}
}
}
else
{
if(is_skipping_player_scene())
{
if( _s scene::is_igc() )
{
foreach(player in level.players)
{
player stopsounds();
}
}
}
}
}
function private finish_skip_scene()
{
/#
if( GetDvarInt("debug_scene_skip") > 0)
{
PrintTopRightln("cscene::scene_sequence_ended : " + GetTime(), ( 1, 0, 0 ));
}
#/
if(isdefined(level.player_skipping_scene))
{
//Send a notify to the client that the skipping is completed.
foreach(player in level.players)
{
player clientfield::increment_to_player( "player_scene_skip_completed" );
player FreezeControls( false );
//Stop sounds on the player
player stopsounds();
}
self.b_player_scene = undefined;
self.skipping_scene = undefined;
level.player_skipping_scene = undefined;
level.linked_scenes = undefined;
init_scene_sequence_started( false );
level notify("scene_skip_sequence_ended");
if( IsDefined( level.BZM_SceneSeqEndedCallback ) ) level thread [[level.BZM_SceneSeqEndedCallback]](_s.name);;
/#
if( GetDvarInt("debug_scene_skip") > 0)
{
PrintTopRightln("cscene::lui::screen_fade BLACK : " + GetTime());
}
#/
/#
if(GetDvarInt("scene_skip_no_fade") == 0)
{
b_skip_fading = false;
}
else
{
b_skip_fading = true;
}
#/
if ( !( isdefined( b_skip_fading ) && b_skip_fading ) )
{
if ( !( isdefined( level.level_ending ) && level.level_ending ) )
{
level thread lui::screen_fade( 1, 0, 1, "black", false, "scene_system" );
}
}
}
}
function private _skip_scene()
{
self endon( "stopped" );
wait 0.05; //wait one frame to make sure all entities spawned since clientfields cannot be sent on the same spawn frame.
//animations on clients
foreach ( o_scene_object in _a_objects )
{
if ( o_scene_object._is_valid )
{
[[o_scene_object]]->skip_scene_on_client();
}
}
wait 0.05; //wait one frame to give the clients a chance to process their animations
//animations on server
foreach ( o_scene_object in _a_objects )
{
if ( o_scene_object._is_valid )
{
[[o_scene_object]]->skip_scene_on_server();
}
}
self notify( "skip_camera_anims" );
}
function should_skip_linked_to_players_scene()
{
if(isdefined(level.player_skipping_scene) && !( isdefined( _s.DisableSceneSkipping ) && _s.DisableSceneSkipping ) && array::contains(level.linked_scenes, _s.name))
{
return true;
}
return false;
}
function private is_scene_shared_sequence()
{
return isdefined(level.shared_scene_sequence_started) && isdefined(_s.shared_scene_sequence);
}
function private update_scene_sequence()
{
if(isdefined(_s.shared_scene_sequence))
{
if(isdefined(level.shared_scene_sequence_started))
{
level.shared_scene_sequence_name = _s.name;
}
else
{
level.shared_scene_sequence_name = undefined;
}
}
}
function private init_scene_sequence_started( b_started)
{
if(( isdefined( b_started ) && b_started ))
{
scene::waittill_skip_sequence_completed();
if(isdefined(level.shared_scene_sequence_started))
{
return;
}
_s.shared_scene_sequence = true;
if(isdefined(_s.s_female_bundle))
{
_s.s_female_bundle.shared_scene_sequence = _s.shared_scene_sequence;
}
if ( IsString( _s.nextscenebundle ) )
{
s_cur_bundle = scene::get_scenedef( _s.nextscenebundle );
while( true )
{
s_cur_bundle.shared_scene_sequence = _s.shared_scene_sequence;
if(isdefined(s_cur_bundle.s_female_bundle))
{
s_cur_bundle.s_female_bundle.shared_scene_sequence = _s.shared_scene_sequence;
}
if ( IsString( s_cur_bundle.nextscenebundle ) )
{
s_cur_bundle = scene::get_scenedef( s_cur_bundle.nextscenebundle );
}
else
{
break;
}
}
}
level.shared_scene_sequence_started = true;
update_scene_sequence();
level notify("scene_sequence_started");
}
else
{
if(!isdefined(level.shared_scene_sequence_started))
{
return;
}
if(isdefined(_s.shared_scene_sequence))
{
level.shared_scene_sequence_started = undefined;
update_scene_sequence();
level notify("scene_sequence_ended", _s.name);
}
}
}
function private trigger_scene_sequence_started( scene_object, entity )
{
if(self === scene_object)
{
if(!is_skipping_scene())
{
init_scene_sequence_started( true );
}
return;
}
if ( IsPlayer( entity ) )
{
if ( !( isdefined( _s.DisableSceneSkipping ) && _s.DisableSceneSkipping ) && !is_skipping_scene())
{
if ( [[scene_object]]->is_shared_player() || (_s scene::is_igc()) )
{
if(_str_state != "init" || (isdefined(scene_object._s.initanim) || isdefined(scene_object._s.initanimloop)))
{
init_scene_sequence_started( true );
}
}
}
}
}
function has_player()
{
foreach ( obj in _a_objects )
{
if ( ( obj._s.type === "player" ) )
{
return true;
}
}
return false;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// _ __ __ _ ___ ___ _ _ ___ ___ ___ ___ ___ ___ _ _ ___ ___ ___ _ ___ ___ _____
// /_\ \ \ / / /_\ | _ \ | __| | \| | | __| / __| / __| / __| / __| | __| | \| | | __| / _ \ | _ ) _ | | | __| / __| |_ _|
// / _ \ \ \/\/ / / _ \ | / | _| | .` | | _| \__ \ \__ \ \__ \ | (__ | _| | .` | | _| | (_) | | _ \ | || | | _| | (__ | |
// /_/ \_\ \_/\_/ /_/ \_\ |_|_\ |___| |_|\_| |___| |___/ |___/ |___/ \___| |___| |_|\_| |___| \___/ |___/ \__/ |___| \___| |_|
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class cAwarenessSceneObject : cSceneObject
{
function play( str_alert_state )
{
flagsys::clear( "ready" ); flagsys::clear( "done" ); flagsys::clear( "main_done" ); _str_state = "play"; self notify( "new_state" ); self endon( "new_state" ); self notify("play"); log( "play" ); waittillframeend;;
switch ( str_alert_state )
{
case "low_alert":
log( "LOW ALERT" );
if ( isdefined( _s.LowAlertAnim ) )
{
_str_death_anim = _s.LowAlertAnimDeath;
_str_death_anim_loop = _s.LowAlertAnimDeathLoop;
_play_anim( _s.LowAlertAnim );
}
break;
case "high_alert":
log( "HIGH ALERT" );
if ( isdefined( _s.HighAlertAnim ) )
{
_str_death_anim = _s.HighAlertAnimDeath;
_str_death_anim_loop = _s.HighAlertAnimDeathLoop;
_play_anim( _s.HighAlertAnim );
}
break;
case "combat":
log( "COMBAT ALERT" );
if ( isdefined( _s.CombatAlertAnim ) )
{
_str_death_anim = _s.CombatAlertAnimDeath;
_str_death_anim_loop = _s.CombatAlertAnimDeathLoop;
_play_anim( _s.CombatAlertAnim );
}
break;
default: error( 1, "Unsupported alert state" );
}
thread finish();
}
function _prepare()
{
if ( cSceneObject::_prepare() )
{
if ( IsAI( _e ) )
{
thread _on_alert_run_scene_thread();
}
}
}
function _on_alert_run_scene_thread()
{
self endon( "play" );
self endon( "done" );
_e waittill( "alert", str_alert_state );
/#
if ( GetDvarInt( "anim_debug", 0 ) )
{
Print3d( _e.origin, "ALERT", ( 1, 0, 0 ), 1, .5, 20 );
}
#/
thread [[scene()]]->play( str_alert_state );
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// _ __ __ _ ___ ___ _ _ ___ ___ ___ ___ ___ ___ _ _ ___
// /_\ \ \ / / /_\ | _ \ | __| | \| | | __| / __| / __| / __| / __| | __| | \| | | __|
// / _ \ \ \/\/ / / _ \ | / | _| | .` | | _| \__ \ \__ \ \__ \ | (__ | _| | .` | | _|
// /_/ \_\ \_/\_/ /_/ \_\ |_|_\ |___| |_|\_| |___| |___/ |___/ |___/ \___| |___| |_|\_| |___|
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class cAwarenessScene : cScene
{
function new_object()
{
return new cAwarenessSceneObject();
}
function init( str_scenedef, s_scenedef, e_align, a_ents, b_test_run )
{
cScene::init( str_scenedef, s_scenedef, e_align, a_ents, b_test_run );
}
function play( str_awareness_state = "low_alert" )
{
self notify( "new_state" );
self endon( "new_state" );
if ( get_valid_objects().size > 0 )
{
foreach ( o_obj in _a_objects )
{
thread [[o_obj]]->play( str_awareness_state );
}
level flagsys::set( _str_name + "_playing" );
_str_state = "play";
wait_till_scene_ready();
thread _call_state_funcs( str_awareness_state );
array::flagsys_wait_any_flag( _a_objects, "done", "main_done" );
if ( is_looping() )
{
if ( has_init_state() )
{
// TODO: do this on return to unaware?
//level flagsys::clear( _str_name + "_playing" );
//thread initialize();
}
}
else
{
thread stop();
}
}
else
{
thread stop( false, true );
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// _ _ ___ _ ___ ___ ___ ___
// | || | | __| | | | _ \ | __| | _ \ / __|
// | __ | | _| | |__ | _/ | _| | / \__ \
// |_||_| |___| |____| |_| |___| |_|_\ |___/
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function get_existing_ent( str_name, b_spawner_only = false, b_nodes_and_structs = false )
{
e = undefined;
if ( b_spawner_only )
{
e_array = GetSpawnerArray( str_name, "script_animname" ); // a spawner exists with script_animname
if ( e_array.size == 0 )
{
e_array = GetSpawnerArray( str_name, "targetname" ); // lastly grab any ent with targetname
}
Assert( e_array.size <= 1, "Multiple spawners found." );
foreach ( ent in e_array )
{
if ( !isdefined( ent.isDying ) )
{
e = ent;
break;
}
}
}
else
{
e = GetEnt( str_name, "animname", false ); // entity already exists
if ( !is_valid_ent( e ) )
{
e = GetEnt( str_name, "script_animname" ); // a spawner exists with script_animname
if ( !is_valid_ent( e ) )
{
e = GetEnt( str_name + "_ai", "targetname", true ); // any already spawned AI
if ( !is_valid_ent( e ) )
{
e = GetEnt( str_name + "_vh", "targetname", true ); // any already spawned vehicles
if ( !is_valid_ent( e ) )
{
e = GetEnt( str_name, "targetname", true ); // any spawned ents that don't have a targetname suffix
if ( !is_valid_ent( e ) )
{
e = GetEnt( str_name, "targetname" ); // lastly grab any ent with targetname
if ( !is_valid_ent( e ) && b_nodes_and_structs )
{
e = GetNode( str_name, "targetname" ); // if no ent, grab node with targetname
if ( !is_valid_ent( e ) )
{
e = struct::get( str_name, "targetname" ); // if no node, grab struct with targetname
}
}
}
}
}
}
}
}
if ( !is_valid_ent( e ) )
{
e = undefined;
}
return e;
}
function is_valid_ent( ent )
{
return ( isdefined( ent ) && ( ( !isdefined( ent.isDying ) && !ent ai::is_dead_sentient() ) || self._s.IgnoreAliveCheck === true ) );
}
function synced_delete()
{
self endon( "death" );
self.isDying = true;
if ( isdefined( self.targetname ) )
{
self.targetname = self.targetname + "_sync_deleting";
}
if ( isdefined( self.animname ) )
{
self.animname = self.animname + "_sync_deleting";
}
if ( isdefined( self.script_animname ) )
{
self.script_animname = self.script_animname + "_sync_deleting";
}
if(!IsPlayer(self))
{
SetHideonClientWhenScriptedAnimCompleted( self );
self StopAnimScripted();
}
else
{
{wait(.05);};
self Ghost();
}
self NotSolid();
if(isAlive(self))
{
if(isSentient( self ))
{
self.ignoreall = true;
}
if(IsActor(self))
{
self PathMode("dont move");
}
}
wait 1; //this will make the server wait until the client syned the transition to the next shot
self delete();
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// _ _ _____ ___ _ ___ _____ __ __
// | | | | |_ _| |_ _| | | |_ _| |_ _| \ \ / /
// | |_| | | | | | | |__ | | | | \ V /
// \___/ |_| |___| |____| |___| |_| |_|
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function autoexec __init__sytem__() { system::register("scene",&__init__,&__main__,undefined); }
function __init__()
{
/* INIT SYSTEM VARS */
level.scene_object_id = 0;
level.active_scenes = [];
level.sceneSkippedCount = 0;
level.wait_for_streamer_hint_scenes = [];
streamerRequest( "clear" );
foreach ( s_scenedef in struct::get_script_bundles( "scene" ) )
{
s_scenedef.editaction = undefined; // only used in the asset editor
s_scenedef.newobject = undefined; // only used in the asset editor
if ( IsString( s_scenedef.FemaleBundle ) )
{
// Set the MaleBundle attribute of female bundles so they know which male bundle they are associated with
s_female_bundle = struct::get_script_bundle( "scene", s_scenedef.FemaleBundle );
s_female_bundle.MaleBundle = s_scenedef.name;
s_scenedef.s_female_bundle = s_female_bundle;
s_female_bundle.s_male_bundle = s_scenedef;
}
if ( IsString( s_scenedef.NextSceneBundle ) )
{
foreach ( i, s_object in s_scenedef.objects )
{
// Disable transition fx between shots in chained bundles
if ( ( s_object.type === "player" ) )
{
s_object.DisableTransitionOut = true;
}
}
s_next_bundle = struct::get_script_bundle( "scene", s_scenedef.NextSceneBundle );
s_next_bundle.DontSync = true;
foreach ( i, s_object in s_next_bundle.objects )
{
// Disable transition fx between shots in chained bundles
if ( ( s_object.type === "player" ) )
{
s_object.DisableTransitionIn = true;
}
//let he next scene know that it is a isCutScene (a scene was played before it);
s_object.isCutScene = true;
}
// Do the same for the female bundle if one exists
if ( isdefined( s_next_bundle.FemaleBundle ) )
{
s_next_female_bundle = struct::get_script_bundle( "scene", s_next_bundle.FemaleBundle );
if ( isdefined( s_next_female_bundle ) )
{
s_next_female_bundle.DontSync = true;
foreach ( i, s_object in s_next_female_bundle.objects )
{
// Disable transition fx between shots in chained bundles
if ( ( s_object.type === "player" ) )
{
s_object.DisableTransitionIn = true;
}
//let he next scene know that it is a isCutScene (a scene was played before it);
s_object.isCutScene = true;
}
}
}
}
// if this bundle has a streamer hint then loop through the next bundles
// and give them the same streamer hint
if ( IsString( s_scenedef.streamerHint ) )
{
s_cur_bundle = s_scenedef;
while( true )
{
s_cur_bundle._endStreamerHint = s_scenedef.streamerHint;
if ( IsString( s_cur_bundle.NextSceneBundle ) )
{
s_cur_bundle = struct::get_script_bundle( "scene", s_cur_bundle.NextSceneBundle );
}
else
{
break;
}
}
}
foreach ( i, s_object in s_scenedef.objects )
{
if ( ( s_object.type === "player" ) )
{
if(!isdefined(s_object.cameratween))s_object.cameratween=0;
if ( isdefined( s_object.player ) )
{
s_object.player--; // adjust for zero-based level.players index
}
else
{
s_object.player = 0;
}
s_object.name = "player " + ( s_object.player + 1 );
s_object.NewPlayerMethod = true; // Fully switching over to new method, no longer supporting ol-style player linkto method
}
else
{
s_object.player = undefined;
}
}
if ( s_scenedef.vmtype == "both" && !s_scenedef is_igc() )
{
n_clientbits = GetMinBitCountForNum( 3 );
/#
n_clientbits = GetMinBitCountForNum( 6 );
#/
clientfield::register( "world", s_scenedef.name, 1, n_clientbits, "int" );
}
}
clientfield::register( "toplayer", "postfx_igc", 1, 2, "counter" );
clientfield::register( "world", "in_igc", 1, 4, "int" );
clientfield::register( "toplayer", "player_scene_skip_completed", 1, 2, "counter" );
clientfield::register( "allplayers", "player_scene_animation_skip", 1, 2, "counter" );
clientfield::register( "actor", "player_scene_animation_skip", 1, 2, "counter" );
clientfield::register( "vehicle", "player_scene_animation_skip", 1, 2, "counter" );
clientfield::register( "scriptmover", "player_scene_animation_skip", 1, 2, "counter" );
callback::on_connect( &on_player_connect );
callback::on_disconnect( &on_player_disconnect );
}
function remove_invalid_scene_objects( s_scenedef )
{
a_invalid_object_indexes = [];
foreach ( i, s_object in s_scenedef.objects )
{
if ( !isdefined( s_object.name ) && !isdefined( s_object.model ) && !( s_object.type === "player" ) )
{
if ( !isdefined( a_invalid_object_indexes ) ) a_invalid_object_indexes = []; else if ( !IsArray( a_invalid_object_indexes ) ) a_invalid_object_indexes = array( a_invalid_object_indexes ); a_invalid_object_indexes[a_invalid_object_indexes.size]=i;;
}
}
for ( i = a_invalid_object_indexes.size - 1; i >= 0 ; i-- )
{
ArrayRemoveIndex( s_scenedef.objects, a_invalid_object_indexes[i] );
}
return s_scenedef;
}
function __main__()
{
/* RUN INSTANCES */
a_instances = ArrayCombine(
struct::get_array( "scriptbundle_scene", "classname" ),
struct::get_array( "scriptbundle_fxanim", "classname" ),
false, false
);
foreach ( s_instance in a_instances )
{
if ( isdefined( s_instance.linkto ) )
{
s_instance thread _scene_link();
}
if ( isdefined( s_instance.script_flag_set ) )
{
level flag::init( s_instance.script_flag_set );
}
if ( isdefined( s_instance.scriptgroup_initscenes ) )
{
foreach ( trig in GetEntArray( s_instance.scriptgroup_initscenes, "scriptgroup_initscenes" ) )
{
s_instance thread _trigger_init( trig );
}
}
if ( isdefined( s_instance.scriptgroup_playscenes ) )
{
foreach ( trig in GetEntArray( s_instance.scriptgroup_playscenes, "scriptgroup_playscenes" ) )
{
s_instance thread _trigger_play( trig );
}
}
if ( isdefined( s_instance.scriptgroup_stopscenes ) )
{
foreach ( trig in GetEntArray( s_instance.scriptgroup_stopscenes, "scriptgroup_stopscenes" ) )
{
s_instance thread _trigger_stop( trig );
}
}
}
level thread on_load_wait();
level thread run_instances();
}
function private _scene_link()
{
self.e_scene_link = util::spawn_model( "tag_origin", self.origin, self.angles );
e_linkto = GetEnt( self.linkto, "linkname" );
self.e_scene_link LinkTo( e_linkto );
util::waittill_any_ents_two( self, "death", e_linkto, "death" ); // Delete link ent when either the scene root entity dies or the entity that it's linked to
self.e_scene_link Delete();
}
function on_load_wait()
{
// wait for client script so "both" type scenes will work properly on load.
util::wait_network_frame();
util::wait_network_frame();
level flagsys::set( "scene_on_load_wait" );
}
function run_instances()
{
foreach ( s_instance in struct::get_script_bundle_instances( "scene" ) )
{
if ( (isdefined(s_instance.spawnflags)&&((s_instance.spawnflags & 2) == 2)) )
{
s_instance thread play();
}
else if ( (isdefined(s_instance.spawnflags)&&((s_instance.spawnflags & 1) == 1)) )
{
s_instance thread init();
}
}
}
function _trigger_init( trig )
{
trig endon( "death" );
trig trigger::wait_till();
a_ents = [];
if ( get_player_count( self.scriptbundlename ) > 0 )
{
if ( IsPlayer( trig.who ) )
{
a_ents[ 0 ] = trig.who;
}
}
self thread _init_instance( undefined, a_ents );
}
function _trigger_play( trig )
{
trig endon( "death" );
do
{
trig trigger::wait_till();
a_ents = [];
if ( get_player_count( self.scriptbundlename ) > 0 )
{
if ( IsPlayer( trig.who ) )
{
a_ents[ 0 ] = trig.who;
}
}
self thread play( a_ents );
}
while ( ( isdefined( get_scenedef( self.scriptbundlename ).looping ) && get_scenedef( self.scriptbundlename ).looping ) );
}
function _trigger_stop( trig )
{
trig endon( "death" );
trig trigger::wait_till();
self thread stop();
}
/@
"Summary: Adds a function to be called when a scene starts"
"SPMP: shared"
"Name: add_scene_func( str_scenedef, func, str_state = "play" )"
"CallOn: level"
"MandatoryArg: <str_scenedef> Name of scene"
"MandatoryArg: <func> function to call when scene starts"
"OptionalArg: [str_state] set to "init" or "done" if you want to the function to get called in one of those states"
"Example: level scene::init( "my_scenes", "targetname" );"
@/
function add_scene_func( str_scenedef, func, str_state = "play", ... )
{
/#
Assert( isdefined( get_scenedef( str_scenedef ) ), "Trying to add a scene function for scene '" + str_scenedef + "' that doesn't exist." );
#/
if(!isdefined(level.scene_funcs))level.scene_funcs=[];
if(!isdefined(level.scene_funcs[ str_scenedef ]))level.scene_funcs[ str_scenedef ]=[];
if(!isdefined(level.scene_funcs[ str_scenedef ][ str_state ]))level.scene_funcs[ str_scenedef ][ str_state ]=[];
array::add( level.scene_funcs[ str_scenedef ][ str_state ], Array( func, vararg ), false );
}
/@
"Summary: Removes a function to be called when a scene starts"
"SPMP: shared"
"Name: remove_scene_func( str_scenedef, func, str_state = "play" )"
"CallOn: level"
"MandatoryArg: <str_scenedef> Name of scene"
"MandatoryArg: <func> function to remove"
"OptionalArg: [str_state] set to "init" or "done" if you want to the function to get removed from one of those states"
"Example: level scene::init( "my_scenes", "targetname" );"
@/
function remove_scene_func( str_scenedef, func, str_state = "play" )
{
/#
Assert( isdefined( get_scenedef( str_scenedef ) ), "Trying to remove a scene function for scene '" + str_scenedef + "' that doesn't exist." );
#/
if(!isdefined(level.scene_funcs))level.scene_funcs=[];
if ( isdefined( level.scene_funcs[ str_scenedef ] ) && isdefined( level.scene_funcs[ str_scenedef ][ str_state ] ) )
{
for ( i = level.scene_funcs[ str_scenedef ][ str_state ].size - 1; i >= 0; i-- )
{
if ( level.scene_funcs[ str_scenedef ][ str_state ][ i ][ 0 ] == func )
{
ArrayRemoveIndex( level.scene_funcs[ str_scenedef ][ str_state ], i );
}
}
}
}
function get_scenedef( str_scenedef )
{
return struct::get_script_bundle( "scene", str_scenedef );
}
function get_scenedefs( str_type = "scene" )
{
a_scenedefs = [];
foreach ( s_scenedef in struct::get_script_bundles( "scene" ) )
{
if ( s_scenedef.sceneType == str_type )
{
if ( !isdefined( a_scenedefs ) ) a_scenedefs = []; else if ( !IsArray( a_scenedefs ) ) a_scenedefs = array( a_scenedefs ); a_scenedefs[a_scenedefs.size]=s_scenedef;;
}
}
return a_scenedefs;
}
/@
"Summary: Spawns a scene"
"SPMP: shared"
"Name: spawn( str_scenedef, v_origin, v_angles, ents )"
"CallOn: NA
"MandatoryArg: <str_scenedef> Name of scene to spawn"
"OptionalArg: [v_origin] The origin to spawn the scene at - defaults to (0, 0, 0)"
"OptionalArg: [v_angles] The angles to spawn the scene at - defaults to (0, 0, 0)"
"OptionalArg: [a_ents] Entities to use for the scene"
"Example: level scene::spawn( "my_scene", (99, 45, 156) );"
"Name: spawn( str_scenedef, ents, v_origin, v_angles )"
"CallOn: NA
"MandatoryArg: <str_scenedef> Name of scene to spawn"
"OptionalArg: [a_ents] Entities to use for the scene"
"OptionalArg: [v_origin] The origin to spawn the scene at - defaults to (0, 0, 0)"
"OptionalArg: [v_angles] The angles to spawn the scene at - defaults to (0, 0, 0)"
"Example: level scene::spawn( "my_scene", array( my_ent1, my_ent2 ) );"
@/
function spawn( arg1, arg2, arg3, arg4, b_test_run )
{
str_scenedef = arg1;
Assert( isdefined( str_scenedef ), "Cannot create a scene without a scene def." );
if ( IsVec( arg2 ) )
{
v_origin = arg2;
v_angles = arg3;
a_ents = arg4;
}
else // overloaded the params so you can put them in different orders
{
a_ents = arg2;
v_origin = arg3;
v_angles = arg4;
}
s_instance = SpawnStruct();
s_instance.origin = ( isdefined( v_origin ) ? v_origin : (0, 0, 0) );
s_instance.angles = ( isdefined( v_angles ) ? v_angles : (0, 0, 0) );
s_instance.classname = "scriptbundle_scene";
s_instance.scriptbundlename = str_scenedef;
s_instance struct::init();
s_instance scene::init( str_scenedef, a_ents, undefined, b_test_run );
return s_instance;
}
/@
"Summary: Initializes a scene or multiple scenes"
"SPMP: shared"
"Name: init( str_val, str_key, ents )"
"CallOn: level using KVP to specify the scene instances"
"MandatoryArg: <str_val> value of the KVP of the scene entity"
"MandatoryArg: <str_key> key of the KVP of the scene entity"
"OptionalArg: [ents] override the entities used for this scene"
"Example: level scene::init( "my_scenes", "targetname" );"
"Name: init( str_scenedef, ents )"
"CallOn: level"
"MandatoryArg: <str_scenedef> specify the scene name, will play all instances of this scene"
"OptionalArg: [ents] override the entities used for this scene"
"Example: level scene::init( "level1_scene_3" );"
"Name: init( str_scenedef, ents )"
"CallOn: Any entity (script_origin, script_struct, ai, script_model, script_brushmodel, player)"
"OptionalArg: [str_scenedef] specify the scene name if needed"
"OptionalArg: [ents] override the entities used for this scene"
"Example: e_scene_root scene::init( "level1_scene_3" );"
"Name: init( ents, str_scenedef )"
"CallOn: Any entity (script_origin, script_struct, ai, script_model, script_brushmodel, player)"
"OptionalArg: [ents] override the entities used for this scene"
"OptionalArg: [str_scenedef] specify the scene name if needed"
"Example: s_scene_object scene::init( array( e_guy1, e_guy2 ) );"
@/
function init( arg1, arg2, arg3, b_test_run )
{
if ( self == level )
{
if ( IsString( arg1 ) )
{
if ( IsString( arg2 ) )
{
str_value = arg1;
str_key = arg2;
a_ents = arg3;
}
else
{
str_value = arg1;
a_ents = arg2;
}
if ( isdefined( str_key ) )
{
a_instances = struct::get_array( str_value, str_key );
/#
Assert( a_instances.size, "No scene instances with KVP '" + str_key + "'/'" + str_value + "'." );
#/
}
else
{
a_instances = struct::get_array( str_value, "targetname" );
if ( !a_instances.size )
{
a_instances = struct::get_array( str_value, "scriptbundlename" );
}
}
if ( !a_instances.size )
{
_init_instance( str_value, a_ents, b_test_run );
}
else
{
foreach ( s_instance in a_instances )
{
if ( isdefined( s_instance ) )
{
s_instance thread _init_instance( undefined, a_ents, b_test_run );
}
}
}
}
}
else
{
if ( IsString( arg1 ) )
{
_init_instance( arg1, arg2, b_test_run );
}
else
{
_init_instance( arg2, arg1, b_test_run );
}
return self;
}
}
function _init_instance( str_scenedef, a_ents, b_test_run = false )
{
level flagsys::wait_till( "scene_on_load_wait" );
if(!isdefined(str_scenedef))str_scenedef=self.scriptbundlename;
/#
if ( array().size && !IsInArray( array(), str_scenedef ) )
{
return;
}
#/
s_bundle = get_scenedef( str_scenedef );
/#
Assert( isdefined( str_scenedef ), "Scene at (" + ( isdefined( self.origin ) ? self.origin : "level" ) + ") is missing its scene def." );
Assert( isdefined( s_bundle ), "Scene at (" + ( isdefined( self.origin ) ? self.origin : "level" ) + ") is using a scene name '" + str_scenedef + "' that doesn't exist." );
#/
o_scene = get_active_scene( str_scenedef );
if ( !isdefined( o_scene ) )
{
if ( s_bundle.scenetype == "awareness" )
{
o_scene = new cAwarenessScene();
}
else
{
o_scene = new cScene();
}
s_bundle = _load_female_scene( s_bundle, a_ents );
[[o_scene]]->init( s_bundle.name, s_bundle, self, a_ents, b_test_run );
}
else
{
thread [[o_scene]]->initialize( a_ents, true );
}
return o_scene;
}
function private _load_female_scene( s_bundle, a_ents )
{
/* Check if this bundle has a player object */
b_has_player = false;
foreach ( s_object in s_bundle.objects )
{
if ( !isDefined( s_object ) )
continue;
if ( ( s_object.type === "player" ) )
{
b_has_player = true;
break;
}
}
/* Check if if a player was passed in to use for the scene */
if ( b_has_player )
{
e_player = undefined;
if ( IsPlayer( a_ents ) )
{
e_player = a_ents;
}
else if ( IsArray( a_ents ) )
{
foreach ( ent in a_ents )
{
if ( IsPlayer( ent ) )
{
e_player = ent;
break;
}
}
}
/* Default to first player none are passed in */
if ( !isdefined( e_player ) )
{
e_player = level.activeplayers[0];
}
if ( IsPlayer( e_player ) && e_player util::is_female() )
{
if ( isdefined( s_bundle.FemaleBundle ) )
{
s_female_bundle = struct::get_script_bundle( "scene", s_bundle.FemaleBundle );
if ( isdefined( s_female_bundle ) )
{
return s_female_bundle;
}
}
}
}
return s_bundle;
}
/@
"Summary: Plays a scene or multiple scenes"
"SPMP: shared"
"Name: play( str_val, str_key, ents )"
"CallOn: level using KVP to specify the scene instances"
"MandatoryArg: <str_val> value of the KVP of the scene entity"
"MandatoryArg: <str_key> key of the KVP of the scene entity"
"OptionalArg: [ents] override the entities used for this scene"
"Example: level scene::play( "my_scenes", "targetname" );"
"Name: play( str_scenedef, ents )"
"CallOn: level"
"MandatoryArg: <str_scenedef> specify the scene name, will play all instances of this scene"
"OptionalArg: [ents] override the entities used for this scene"
"Example: level scene::play( "level1_scene_3" );"
"Name: play( str_scenedef, ents )"
"CallOn: Any entity (script_origin, script_struct, ai, script_model, script_brushmodel, player)"
"OptionalArg: [str_scenedef] specify the scene name if needed"
"OptionalArg: [ents] override the entities used for this scene"
"Example: e_scene_root scene::play( "level1_scene_3" );"
"Name: play( ents, str_scenedef )"
"CallOn: Any entity (script_origin, script_struct, ai, script_model, script_brushmodel, player)"
"OptionalArg: [ents] override the entities used for this scene"
"OptionalArg: [str_scenedef] specify the scene name if needed"
"Example: s_scene_object scene::play( array( e_guy1, e_guy2 ) );"
@/
function play( arg1, arg2, arg3, b_test_run = false, str_state, str_mode = "" )
{
/#
if( GetDvarInt("debug_scene") > 0)
{
if(isdefined(arg1) && IsString(arg1) )
{
PrintTopRightln("scene::play : " + arg1);
}
else
{
PrintTopRightln("scene::play");
}
}
#/
if(isdefined(arg1) && IsString(arg1) && arg1 == "p7_fxanim_zm_castle_rocket_bell_tower_bundle")
{
arg1 = arg1;
}
s_tracker = SpawnStruct();
s_tracker.n_scene_count = 1;
if ( self == level )
{
if ( IsString( arg1 ) )
{
if ( IsString( arg2 ) )
{
str_value = arg1;
str_key = arg2;
a_ents = arg3;
}
else
{
str_value = arg1;
a_ents = arg2;
}
str_scenedef = str_value;
if ( isdefined( str_key ) )
{
a_instances = struct::get_array( str_value, str_key );
str_scenedef = undefined; // use struct scenedef
/#
Assert( a_instances.size, "No scene instances with KVP '" + str_key + "'/'" + str_value + "'." );
#/
}
else
{
a_instances = struct::get_array( str_value, "targetname" );
if ( !a_instances.size )
{
a_instances = struct::get_array( str_value, "scriptbundlename" );
}
else
{
str_scenedef = undefined; // use struct scenedef
}
}
if ( isdefined( str_scenedef ) )
{
a_active_instances = get_active_scenes( str_scenedef );
a_instances = ArrayCombine( a_active_instances, a_instances, false, false );
}
if ( !a_instances.size )
{
self thread _play_instance( s_tracker, str_scenedef, a_ents, b_test_run, undefined, str_mode );
}
else
{
s_tracker.n_scene_count = a_instances.size;
foreach ( s_instance in a_instances )
{
if ( isdefined( s_instance ) )
{
s_instance thread _play_instance( s_tracker, str_scenedef, a_ents, b_test_run, str_state, str_mode );
}
}
}
}
}
else
{
if ( IsString( arg1 ) )
{
self thread _play_instance( s_tracker, arg1, arg2, b_test_run, str_state, str_mode );
}
else
{
self thread _play_instance( s_tracker, arg2, arg1, b_test_run, str_state, str_mode );
}
}
for ( i = 0; i < s_tracker.n_scene_count; i++ )
{
s_tracker waittill( "scene_done" );
}
}
function _play_instance( s_tracker, str_scenedef, a_ents, b_test_run = false, str_state, str_mode )
{
/#
if ( array().size && !IsInArray( array(), str_scenedef ) )
{
return;
}
#/
if(!isdefined(str_scenedef))str_scenedef=self.scriptbundlename;
if ( self.scriptbundlename === str_scenedef ) // Radiant placed scene, only play once unless specified to play more than once
{
if ( !( isdefined( self.script_play_multiple ) && self.script_play_multiple ) )
{
if ( ( isdefined( self.scene_played ) && self.scene_played ) && !b_test_run )
{
waittillframeend;
while ( is_playing( str_scenedef ) )
{
{wait(.05);};
}
s_tracker notify( "scene_done" );
return;
}
}
self.scene_played = true;
}
o_scene = _init_instance( str_scenedef, a_ents, b_test_run );
if ( IsDefined(o_scene) )
{
if( (!isdefined(str_mode) || str_mode == "") && [[o_scene]]->should_skip_linked_to_players_scene() )
{
skip_scene( o_scene._s.name, false, false, true);
}
thread [[o_scene]]->play( str_state, a_ents, b_test_run, str_mode );
}
self waittillmatch( "scene_done", str_scenedef );
if ( isdefined( self ) )
{
if ( isdefined( self.scriptbundlename ) && ( isdefined( get_scenedef( self.scriptbundlename ).looping ) && get_scenedef( self.scriptbundlename ).looping ) )
{
self.scene_played = false;
}
if ( isdefined( self.script_flag_set ) )
{
level flag::set( self.script_flag_set );
}
}
s_tracker notify( "scene_done" );
}
/@
"Summary: Skipts a scene or multiple scenes to the end state (last frame or looping animation). Look at scene::play() for all the various ways this can be called."
"SPMP: shared"
"OptionalArg: [n_time] Value between 0 and 1 to only skip through a portion of the scene. 0 will start at the beginning of the scene, 1 skips completely to the end."
"Example: level scene::skipto_end( "my_scene" );"
@/
function skipto_end( arg1, arg2, arg3, n_time, b_include_players = false )
{
str_mode = "skipto";
if ( !b_include_players )
{
str_mode += "_noplayers";
}
if ( isdefined( n_time ) )
{
str_mode += ":" + n_time;
}
play( arg1, arg2, arg3, false, undefined, str_mode );
}
/@
"Summary: Skipts a scene or multiple scenes to the end state (last frame or looping animation), but skips AI. Look at scene::play() for all the various ways this can be called."
"SPMP: shared"
"OptionalArg: [n_time] Value between 0 and 1 to only skip through a portion of the scene. 0 will start at the beginning of the scene, 1 skips completely to the end."
"Example: level scene::skipto_end_noai( "my_scene" );"
@/
function skipto_end_noai( arg1, arg2, arg3, n_time )
{
str_mode = "skipto_noai_noplayers";
if ( isdefined( n_time ) )
{
str_mode += ":" + n_time;
}
play( arg1, arg2, arg3, false, undefined, str_mode );
}
/@
"Summary: Stops a scene or multiple scenes"
"SPMP: shared"
"Name: stop( str_val, str_key, b_clear )"
"CallOn: level using KVP to specify the scene instances"
"MandatoryArg: <str_val> value of the KVP of the scene entity"
"MandatoryArg: <str_key> key of the KVP of the scene entity"
"OptionalArg: [b_clear] optionally delete the ents if they were spawned by the scene, regardless of options in scene definition"
"Example: level scene::stop( "my_scenes", "targetname" );"
"Name: stop( str_scenedef, b_clear )"
"CallOn: level"
"MandatoryArg: <str_scenedef> specify the scene name, will stop all instances of this scene"
"OptionalArg: [b_clear] optionally delete the ents if they were spawned by the scene, regardless of options in scene definition"
"Example: level scene::stop( "level1_scene_3" );"
"Name: stop( str_scenedef, b_clear )"
"CallOn: Any entity (script_origin, script_struct, ai, script_model, script_brushmodel, player)"
"OptionalArg: [str_scenedef] specify the scene name if multiple scenes are running on the entity"
"OptionalArg: [b_clear] optionally delete the ents if they were spawned by the scene, regardless of options in scene definition"
"Example: e_my_scene scene::stop( "level1_scene_3" );"
"Name: stop( b_clear, str_scenedef )"
"CallOn: Any entity (script_origin, script_struct, ai, script_model, script_brushmodel, player)"
"OptionalArg: [b_clear] optionally delete the ents if they were spawned by the scene, regardless of options in scene definition"
"OptionalArg: [str_scenedef] specify the scene name if multiple scenes are running on the entity"
"Example: s_scene_object scene::stop( true );"
@/
function stop( arg1, arg2, arg3 )
{
if ( self == level )
{
if ( IsString( arg1 ) )
{
if ( IsString( arg2 ) )
{
str_value = arg1;
str_key = arg2;
b_clear = arg3;
}
else
{
str_value = arg1;
b_clear = arg2;
}
if ( isdefined( str_key ) )
{
a_instances = struct::get_array( str_value, str_key );
/#
Assert( a_instances.size, "No scene instances with KVP '" + str_key + "'/'" + str_value + "'." );
#/
str_value = undefined;
}
else
{
a_instances = struct::get_array( str_value, "targetname" );
if ( !a_instances.size )
{
a_instances = get_active_scenes( str_value );
}
else
{
str_value = undefined;
}
}
foreach ( s_instance in ArrayCopy( a_instances ) )
{
if ( isdefined( s_instance ) )
{
s_instance _stop_instance( b_clear, str_value );
}
}
}
}
else
{
if ( IsString( arg1 ) )
{
_stop_instance( arg2, arg1 );
}
else
{
_stop_instance( arg1 );
}
}
}
function _stop_instance( b_clear = false, str_scenedef )
{
if ( isdefined( self.scenes ) )
{
foreach ( o_scene in ArrayCopy( self.scenes ) )
{
str_scene_name = [[o_scene]]->get_name();
if ( !isdefined( str_scenedef ) || ( str_scene_name == str_scenedef ) )
{
thread [[o_scene]]->stop( b_clear );
}
}
}
}
function has_init_state( str_scenedef )
{
s_scenedef = get_scenedef( str_scenedef );
foreach ( s_obj in s_scenedef.objects )
{
if ( !( isdefined( s_obj.disabled ) && s_obj.disabled ) && s_obj _has_init_state() )
{
return true;
}
}
return false;
}
function _has_init_state()
{
return ( ( isdefined( self.spawnoninit ) && self.spawnoninit ) || isdefined( self.initanim ) || isdefined( self.initanimloop ) || ( isdefined( self.firstframe ) && self.firstframe ) );
}
/@
"Summary: returns the number of props defined for a scene"
"SPMP: shared"
"Name: get_prop_count( str_scenedef )"
"CallOn: Any"
"MandatoryArg: <str_scenedef> scene definition name (from gdt)"
"Example: level scene::get_prop_count( "my_scene" );"
"Name: get_prop_count()"
"CallOn: scene object"
"Example: s_scene scene::get_prop_count();"
@/
function get_prop_count( str_scenedef )
{
return _get_type_count( "prop", str_scenedef );
}
/@
"Summary: returns the number of vehicles defined for a scene"
"SPMP: shared"
"Name: get_vehicle_count( str_scenedef )"
"CallOn: Any"
"MandatoryArg: <str_scenedef> scene definition name (from gdt)"
"Example: level scene::get_vehicle_count( "my_scene" );"
"Name: get_vehicle_count()"
"CallOn: scene object"
"Example: s_scene scene::get_vehicle_count();"
@/
function get_vehicle_count( str_scenedef )
{
return _get_type_count( "vehicle", str_scenedef );
}
/@
"Summary: returns the number of actors defined for a scene"
"SPMP: shared"
"Name: get_actor_count( str_scenedef )"
"CallOn: Any"
"MandatoryArg: <str_scenedef> scene definition name (from gdt)"
"Example: level scene::get_actor_count( "my_scene" );"
"Name: get_actor_count()"
"CallOn: scene object"
"Example: s_scene scene::get_actor_count();"
@/
function get_actor_count( str_scenedef )
{
return _get_type_count( "actor", str_scenedef );
}
/@
"Summary: returns the number of players defined for a scene"
"SPMP: shared"
"Name: get_player_count( str_scenedef )"
"CallOn: Any"
"MandatoryArg: <str_scenedef> scene definition name (from gdt)"
"Example: level scene::get_player_count( "my_scene" );"
"Name: get_player_count()"
"CallOn: scene object"
"Example: s_scene scene::get_player_count();"
@/
function get_player_count( str_scenedef )
{
return _get_type_count( "player", str_scenedef );
}
function _get_type_count( str_type, str_scenedef )
{
s_scenedef = ( isdefined( str_scenedef ) ? get_scenedef( str_scenedef ) : get_scenedef( self.scriptbundlename ) );
n_count = 0;
foreach ( s_obj in s_scenedef.objects )
{
if ( isdefined( s_obj.type ) )
{
if ( ToLower( s_obj.type ) == ToLower( str_type ) )
{
n_count++;
}
}
}
return n_count;
}
/@
"Summary: Checks if a scene is playing"
"SPMP: shared"
"Name: is_active( str_scenedef )"
"CallOn: level or a scene instance"
"OptionalArg: [str_scenedef] The name of the scene to check"
"Example: level scene::is_active( "my_scene" );"
"Example: s_scene scene::is_active();"
@/
function is_active( str_scenedef )
{
if ( self == level )
{
return ( get_active_scenes( str_scenedef ).size > 0 );
}
else
{
return ( isdefined( get_active_scene( str_scenedef ) ) );
}
}
/@
"Summary: Checks if a scene is playing"
"SPMP: shared"
"Name: is_playing( str_scenedef )"
"OptionalArg: [str_scenedef] The name of the scene to check"
"Example: s_scene scene::is_playing( "my_scene" );"
"Example: s_scene scene::is_playing();"
@/
function is_playing( str_scenedef )
{
if ( self == level )
{
return ( level flagsys::get( str_scenedef + "_playing" ) );
}
else
{
if(!isdefined(str_scenedef))str_scenedef=self.scriptbundlename;
o_scene = get_active_scene( str_scenedef );
if ( isdefined( o_scene ) )
{
return ( ( o_scene._str_state === "play" ) );
}
}
return false;
}
/@
"Summary: Checks if a scene is ready"
"SPMP: shared"
"Name: is_ready( str_scenedef )"
"OptionalArg: [str_scenedef] The name of the scene to check"
"Example: s_scene scene::is_ready( "my_scene" );"
"Example: s_scene scene::is_ready();"
@/
function is_ready( str_scenedef )
{
if ( self == level )
{
return ( level flagsys::get( str_scenedef + "_ready" ) );
}
else
{
if(!isdefined(str_scenedef))str_scenedef=self.scriptbundlename;
o_scene = get_active_scene( str_scenedef );
if ( isdefined( o_scene ) )
{
return ( o_scene flagsys::get( "ready" ) );
}
}
return false;
}
function get_active_scenes( str_scenedef )
{
if(!isdefined(level.active_scenes))level.active_scenes=[];
if ( isdefined( str_scenedef ) )
{
return ( isdefined( level.active_scenes[ str_scenedef ] ) ? level.active_scenes[ str_scenedef ] : [] );
}
else
{
a_active_scenes = [];
foreach ( str_scenedef, _ in level.active_scenes )
{
a_active_scenes = ArrayCombine( a_active_scenes, level.active_scenes[ str_scenedef ], false, false );
}
return a_active_scenes;
}
}
function get_active_scene( str_scenedef )
{
if ( isdefined( str_scenedef ) && isdefined( self.scenes ) )
{
foreach ( o_scene in self.scenes )
{
if ( [[o_scene]]->get_name() == str_scenedef )
{
return o_scene;
}
}
}
}
//TODO: this should be turned into something more automatic and part of the system
function delete_scene_data( str_scenename )
{
if(IsDefined( level.scriptbundles["scene"][str_scenename] ))
{
level.scriptbundles["scene"][str_scenename] = undefined;
}
}
function is_igc()
{
return ( IsString( self.cameraswitcher )
|| IsString( self.extraCamSwitcher1 )
|| IsString( self.extraCamSwitcher2 )
|| IsString( self.extraCamSwitcher3 )
|| IsString( self.extraCamSwitcher4 ) );
}
function scene_disable_player_stuff( b_hide_hud = true )
{
/#
if( GetDvarInt("debug_scene") > 0)
{
PrintTopRightln("scene::scene_disable_player_stuff");
}
#/
self notify( "scene_disable_player_stuff" );
self notify( "kill_hint_text" );
self DisableOffhandWeapons();
if ( b_hide_hud )
{
set_igc_active( true );
level notify( "disable_cybercom", self, true );
self util::show_hud( 0 );
util::wait_network_frame(); // let "in_igc" get set so deleted weapon objects can bypass HUD effects
self notify( "delete_weapon_objects" );
}
}
function scene_enable_player_stuff( b_hide_hud = true )
{
/#
if( GetDvarInt("debug_scene") > 0)
{
PrintTopRightln("scene::scene_enable_player_stuff");
}
#/
self endon( "scene_disable_player_stuff" );
self endon( "disconnect" );
wait .5;
self EnableOffhandWeapons();
if ( b_hide_hud )
{
set_igc_active( false );
level notify( "enable_cybercom", self );
self notify( "scene_enable_cybercom" ); //TU1: Need to track when the scene system is turning it on per player.
self util::show_hud( 1 );
}
}
function updateIGCViewtime(b_in_igc)
{
if (b_in_igc && !isDefined(level.igcStartTime))
{
level.igcStartTime = GetTime();
}
else if (!b_in_igc && isDefined(level.igcStartTime))
{
igcViewtimeSec = GetTime() - level.igcStartTime;
level.igcStartTime = undefined;
foreach (player in level.players)
{
if (!isDefined(player.totalIGCViewtime))
{
player.totalIGCViewtime = 0;
}
player.totalIGCViewtime += int(igcViewtimeSec / 1000);
}
}
}
function set_igc_active( b_in_igc )
{
n_ent_num = self GetEntityNumber();
n_players_in_igc_field = level clientfield::get( "in_igc" );
if ( b_in_igc )
{
n_players_in_igc_field |= ( 1 << n_ent_num );
}
else
{
n_players_in_igc_field &= ~( 1 << n_ent_num );
}
updateIGCViewtime(b_in_igc);
level clientfield::set( "in_igc", n_players_in_igc_field );
/#
//PrintTopRightln( "SERVER " + n_ent_num + ": setting 'in_igc' to " + b_in_igc, RED, -1 );
#/
}
function is_igc_active()
{
n_players_in_igc = level clientfield::get( "in_igc" );
n_entnum = self GetEntityNumber();
return ( n_players_in_igc & ( 1 << n_entnum ) );
}
function is_capture_mode()
{
str_mode = GetDvarString( "scene_menu_mode", "default" );
if ( IsSubStr( str_mode, "capture" ) )
{
return true;
}
else
{
return false;
}
}
function should_spectate_on_join()
{
return ( isdefined( level.scene_should_spectate_on_hot_join ) && level.scene_should_spectate_on_hot_join );
}
function wait_until_spectate_on_join_completes()
{
while(( isdefined( level.scene_should_spectate_on_hot_join ) && level.scene_should_spectate_on_hot_join ))
{
wait 0.05;
}
}
//-----------------------------------------------------------------SCENE-SKIPPING--------------------------------------------------------------------------------
function skip_scene( scene_name, b_sequence, b_player_scene, b_check_linked_scene )
{
if(!isdefined(scene_name))
{
if(isdefined(level.shared_scene_sequence_name))
{
scene_name = level.shared_scene_sequence_name;
}
if(!isdefined(scene_name))
{
if(isdefined(level.players) && isdefined(level.players[0].current_scene))
{
scene_name = level.players[0].current_scene;
}
if(!isdefined(scene_name))
{
foreach(player in level.players)
{
if(isdefined(player.current_scene))
{
scene_name = player.current_scene;
break;
}
}
}
}
}
/#
if( GetDvarInt("debug_scene_skip") > 0)
{
if(isdefined(scene_name))
{
PrintTopRightln("scene::skip_scene: SCENE NAME " + scene_name + " : " + GetTime(), ( 1, .5, 0 ));
}
else
{
PrintTopRightln("scene::skip_scene: CANNOT FIND SCENE NAME : " + GetTime(), ( 1, .5, 0 ));
}
}
#/
//check if it is a player scene
if(!( isdefined( b_sequence ) && b_sequence ) && !isdefined(b_player_scene) )
{
foreach(player in level.players)
{
if(isdefined(player.current_scene) && player.current_scene == scene_name)
{
b_player_scene = true;
break;
}
}
}
//start skipping player scenes and the scenes linked to it.
if(!( isdefined( b_sequence ) && b_sequence ) && ( isdefined( b_player_scene ) && b_player_scene ))
{
//start the player scene
a_instances = get_active_scenes( scene_name );
b_can_skip_player_scene = false;
foreach ( s_instance in ArrayCopy( a_instances ) )
{
if ( isdefined( s_instance ) )
{
b_shared_scene = (s_instance _skip_scene( scene_name, b_sequence, true, false ));
if(b_shared_scene == 2)
break;
if(b_shared_scene == 1)
{
b_can_skip_player_scene = true;
break;
}
}
}
//if it is a player skippable scene, we need to skip all the scenes that are associated with it.
if( ( isdefined( b_can_skip_player_scene ) && b_can_skip_player_scene ) )
{
a_instances = get_active_scenes();
foreach ( s_instance in ArrayCopy( a_instances ) )
{
if ( isdefined( s_instance ) )
{
s_instance _skip_scene( scene_name, b_sequence, false, true );
}
}
}
else
{
level.shared_scene_sequence_started = undefined;
level.shared_scene_sequence_name = undefined;
}
return;
}
a_instances = struct::get_array( scene_name, "targetname" );
if ( !a_instances.size )
{
a_instances = get_active_scenes( scene_name );
}
foreach ( s_instance in ArrayCopy( a_instances ) )
{
if ( isdefined( s_instance ) )
{
s_instance _skip_scene( scene_name, b_sequence, b_player_scene, b_check_linked_scene );
}
}
}
function _skip_scene( skipped_scene_name, b_sequence, b_player_scene, b_check_linked_scene )
{
b_shared_scene = 0;
if ( isdefined( self.scenes ) )
{
foreach ( o_scene in ArrayCopy( self.scenes ) )
{
//scene is skipping already
if( ( isdefined( o_scene.skipping_scene ) && o_scene.skipping_scene ) )
continue;
//If a player scene skipping is starting, we can only skip the shared IGCs ones
if( !( isdefined( b_sequence ) && b_sequence ) && ( isdefined( b_player_scene ) && b_player_scene ) && !( isdefined( b_check_linked_scene ) && b_check_linked_scene ) )
{
if(o_scene._s.name === skipped_scene_name)
{
if(( isdefined( o_scene._s.DisableSceneSkipping ) && o_scene._s.DisableSceneSkipping ))
{
return 2;
}
else
{
if(o_scene._str_state === "init")
continue;
b_shared_scene = 1;
}
}
else if(!isdefined(skipped_scene_name))
{
if([[o_scene]]->is_scene_shared())
{
if(( isdefined( o_scene._s.DisableSceneSkipping ) && o_scene._s.DisableSceneSkipping ))
{
return 2;
}
else
{
if(o_scene._str_state === "init")
continue;
b_shared_scene = 1;
}
}
else
{
continue;
}
}
else
{
continue;
}
}
str_scene_name = [[o_scene]]->get_name();
if( !( isdefined( b_sequence ) && b_sequence ) )
{
b_linked_scene = array::contains(level.linked_scenes, str_scene_name);
//ignore non linked player scenes
if( ( isdefined( b_check_linked_scene ) && b_check_linked_scene ) && (!b_linked_scene || ( isdefined( o_scene._s.DisableSceneSkipping ) && o_scene._s.DisableSceneSkipping )) )
{
continue;
}
if( !b_linked_scene && o_scene._str_state === "init" )
{
continue;
}
if ( ( !isdefined(skipped_scene_name) || str_scene_name == skipped_scene_name ) || (b_linked_scene && !( isdefined( o_scene._s.DisableSceneSkipping ) && o_scene._s.DisableSceneSkipping )) )
{
if( ( !isdefined(skipped_scene_name) || str_scene_name == skipped_scene_name) && ( isdefined( b_player_scene ) && b_player_scene ) && !( isdefined( b_check_linked_scene ) && b_check_linked_scene ) && !b_linked_scene) //if player scene
{
b_shared_scene = 1;
o_scene.b_player_scene = true;
level.player_skipping_scene = str_scene_name;
}
o_scene.skipping_scene = true;
thread [[o_scene]]->skip_scene( b_sequence );
}
}
else
{
o_scene.b_player_scene = b_player_scene;
o_scene.skipping_scene = true;
thread [[o_scene]]->skip_scene( b_sequence);
}
}
}
return b_shared_scene;
}
function add_player_linked_scene(linked_scene_str)
{
if(!isdefined(level.linked_scenes))level.linked_scenes=[];
array::add(level.linked_scenes, linked_scene_str);
}
function remove_player_linked_scene(linked_scene_str)
{
if(isdefined(level.linked_scenes))
{
ArrayRemoveValue( level.linked_scenes, linked_scene_str );
}
}
function waittill_skip_sequence_completed()
{
while(isdefined(level.player_skipping_scene))
{
wait 0.05;
}
}
function is_skipping_in_progress()
{
return isdefined(level.player_skipping_scene);
}
function watch_scene_skip_requests()
{
self endon( "disconnect" );
while(1)
{
level waittill("scene_sequence_started");
self thread should_skip_scene_loop();
self thread watch_scene_ending();
self thread watch_scene_skipping();
level waittill( "scene_sequence_ended" );
}
}
function clear_scene_skipping_ui()
{
level endon("scene_sequence_started");
if(isdefined(self.scene_skip_timer))
{
//PrintTopRightln("Hide Skip Scene Button", WHITE, 10000);
self.scene_skip_timer = undefined;
}
if(isdefined(self.scene_skip_start_time))
{
self.scene_skip_start_time = undefined;
}
foreach(player in level.players)
{
if(isdefined(player.skip_scene_menu_handle))
{
player CloseLuiMenu( player.skip_scene_menu_handle );
player.skip_scene_menu_handle = undefined;
}
}
}
function watch_scene_ending()
{
self endon( "disconnect" );
self endon( "scene_being_skipped");
level waittill( "scene_sequence_ended" );
clear_scene_skipping_ui();
}
function watch_scene_skipping()
{
self endon( "disconnect" );
level endon( "scene_sequence_ended");
self waittill( "scene_being_skipped");
level.sceneSkippedCount++;
clear_scene_skipping_ui();
}
function should_skip_scene_loop()
{
self endon( "disconnect" );
level endon( "scene_sequence_ended" );
b_skip_scene = false;
clear_scene_skipping_ui();
wait 0.05; //wait a frame for the menus to be closed
foreach(player in level.players)
{
if(isdefined(player.skip_scene_menu_handle))
{
player CloseLuiMenu( player.skip_scene_menu_handle );
wait 0.05; //wait a frame for the menus to be closed
}
player.skip_scene_menu_handle = player OpenLuiMenu( "CPSkipSceneMenu" );
player SetLUIMenuData( player.skip_scene_menu_handle, "showSkipButton", 0 );
player SetLUIMenuData( player.skip_scene_menu_handle, "hostIsSkipping", 0 );
player SetLUIMenuData( player.skip_scene_menu_handle, "sceneSkipEndTime", 0 );
}
while(1)
{
if((self any_button_pressed()) && !( isdefined( level.chyron_text_active ) && level.chyron_text_active ))
{
if(!isdefined(self.scene_skip_timer))
{
//PrintTopRightln("Show Skip Scene Button", ORANGE , 10000);
self SetLUIMenuData( self.skip_scene_menu_handle, "showSkipButton", 1 );
}
self.scene_skip_timer = GetTime();
}
else if(isdefined(self.scene_skip_timer))
{
if((GetTime() - self.scene_skip_timer) > 3000)
{
//PrintTopRightln("Hide Skip Scene Button", WHITE, 10000);
self SetLUIMenuData( self.skip_scene_menu_handle, "showSkipButton", 2 );
self.scene_skip_timer = undefined;
}
}
if((self PrimaryButtonPressedLocal()) && !( isdefined( level.chyron_text_active ) && level.chyron_text_active ))
{
if( !isdefined(self.scene_skip_start_time) )
{
foreach(player in level.players)
{
if(player IsHost())
{
player SetLUIMenuData( player.skip_scene_menu_handle, "sceneSkipEndTime", GetTime() + 2500 );
continue;
}
if(isdefined(player.skip_scene_menu_handle))
{
player SetLUIMenuData( player.skip_scene_menu_handle, "hostIsSkipping", 1 );
}
}
//PrintTopRightln("Scene is being skipped....", GREEN, 10000);
self.scene_skip_start_time = GetTime();
}
else if((GetTime() - self.scene_skip_start_time) > 2500)
{
b_skip_scene = true;
break;
}
}
else if( isdefined(self.scene_skip_start_time) )
{
foreach(player in level.players)
{
if(player IsHost())
{
player SetLUIMenuData( player.skip_scene_menu_handle, "sceneSkipEndTime", 0 );
continue;
}
if(isdefined(player.skip_scene_menu_handle))
{
player SetLUIMenuData( player.skip_scene_menu_handle, "hostIsSkipping", 2 );
}
}
//PrintTopRightln("Scene skipping cancelled", (0, 1, 1) , 10000);
self.scene_skip_start_time = undefined;
}
if(( isdefined( level.chyron_text_active ) && level.chyron_text_active ))
{
while(( isdefined( level.chyron_text_active ) && level.chyron_text_active ))
{
wait 0.05;
}
//give Chyron text a chance to fade out
wait 3;
}
wait 0.05;
}
if(b_skip_scene)
{
//PrintTopRightln("SCENE SKIPPED", RED, 10000);
self playsound( "uin_igc_skip" ); //C.Ayers: Plays a skip sound with a duck to cover up the switch
self notify("scene_being_skipped");
level notify("scene_skip_sequence_started");
scene::skip_scene(level.shared_scene_sequence_name, false, true);
}
}
function any_button_pressed()
{
//DPad
if( self ActionSlotOneButtonPressed() )
{
return true;
}
else if( self ActionSlotTwoButtonPressed() )
{
return true;
}
else if( self ActionSlotThreeButtonPressed() )
{
return true;
}
else if( self ActionSlotFourButtonPressed() )
{
return true;
}
//Action Buttons
else if(self JumpButtonPressed() )
{
return true;
}
else if(self StanceButtonPressed() )
{
return true;
}
else if(self WeaponSwitchButtonPressed() )
{
return true;
}
else if(self ReloadButtonPressed() )
{
return true;
}
//Triggers
else if(self fragbuttonpressed() )
{
return true;
}
else if(self throwbuttonpressed() )
{
return true;
}
else if(self AttackButtonPressed())
{
return true;
}
else if(self secondaryoffhandbuttonpressed() )
{
return true;
}
//Sticks
else if(self meleebuttonpressed() )
{
return true;
}
return false;
}
function on_player_connect()
{
if( self IsHost() )
{
self thread watch_scene_skip_requests();
}
}
function on_player_disconnect()
{
// Clear out the igc active level flag so if somebody hot joins in they don't think they are in an igc
self set_igc_active( false );
}
//-------------------------------------------------------------------------------------------------------------------------------------------------
function add_scene_ordered_notetrack( group_name, str_note )
{
if(!isdefined(level.scene_ordered_notetracks))level.scene_ordered_notetracks=[];
group_obj = level.scene_ordered_notetracks[group_name];
if(!isdefined( group_obj ))
{
group_obj = SpawnStruct();
group_obj.count = 0;
group_obj.current_count = 0;
level.scene_ordered_notetracks[group_name] = group_obj;
}
group_obj.count++;
//PrintTopRightln("Registered " + str_note, WHITE, -1);
self thread _wait_for_ordered_notify( group_obj.count - 1, group_obj, group_name, str_note );
}
function private _wait_for_ordered_notify( id, group_obj, group_name, str_note )
{
self waittill(str_note);
//PrintTopRightln("Received " + str_note, ORANGE, -1);
if( group_obj.current_count == id )
{
group_obj.current_count++;
self notify("scene_" + str_note);
//PrintTopRightln("FIRE " + str_note, BLUE, -1);
wait 0.05;
//if we fired all notifies, release all arrays
if(group_obj.current_count == group_obj.count)
{
group_obj.pending_notifies = undefined;
level.scene_ordered_notetracks[group_name] = undefined;
}
else if( isdefined(group_obj.pending_notifies) && ((group_obj.current_count + group_obj.pending_notifies.size) == group_obj.count) )
{
self thread _fire_ordered_notitifes( group_obj, group_name);
}
}
else
{
if( !isdefined(group_obj.pending_notifies) )
{
group_obj.pending_notifies = [];
}
//out of order notetrack fired...insert it in it's ordered position
notetrack = SpawnStruct();
notetrack.id = id;
notetrack.str_note = str_note;
i = 0;
while(i < group_obj.pending_notifies.size && group_obj.pending_notifies[i].id < id)
{
i++;
}
ArrayInsert(group_obj.pending_notifies, notetrack, i);
if( (group_obj.current_count + group_obj.pending_notifies.size) == group_obj.count )
{
self thread _fire_ordered_notitifes( group_obj, group_name);
}
}
}
function private _fire_ordered_notitifes( group_obj, group_name )
{
if( isdefined(group_obj.pending_notifies) )
{
while( group_obj.pending_notifies.size > 0)
{
self notify("scene_" + group_obj.pending_notifies[0].str_note);
//PrintTopRightln("FIRE " + group_obj.pending_notifies[0].str_note, BLUE, -1);
ArrayRemoveIndex(group_obj.pending_notifies, 0);
wait 0.05;
}
}
group_obj.pending_notifies = undefined;
level.scene_ordered_notetracks[group_name] = undefined;
}
function add_wait_for_streamer_hint_scene( str_scene_name )
{
if(!isdefined(level.wait_for_streamer_hint_scenes))level.wait_for_streamer_hint_scenes=[];
array::add( level.wait_for_streamer_hint_scenes, str_scene_name );
}