2427 lines
70 KiB
Plaintext
2427 lines
70 KiB
Plaintext
#using scripts\codescripts\struct;
|
|
|
|
#using scripts\shared\animation_shared;
|
|
#using scripts\shared\array_shared;
|
|
#using scripts\shared\clientfield_shared;
|
|
#using scripts\shared\flagsys_shared;
|
|
#using scripts\shared\postfx_shared;
|
|
#using scripts\shared\lui_shared;
|
|
#using scripts\shared\scene_debug_shared;
|
|
#using scripts\shared\scriptbundle_shared;
|
|
#using scripts\shared\system_shared;
|
|
#using scripts\shared\util_shared;
|
|
#using scripts\shared\filter_shared;
|
|
#using scripts\shared\math_shared;
|
|
#using scripts\shared\callbacks_shared;
|
|
|
|
|
|
|
|
|
|
#using_animtree( "generic" );
|
|
|
|
#namespace scene;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function player_scene_animation_skip( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
|
|
{
|
|
anim_name = self GetCurrentAnimScriptedName();
|
|
|
|
if(isdefined(anim_name) && anim_name != "")
|
|
{
|
|
is_looping = IsAnimLooping(localClientNum, anim_name);
|
|
|
|
if(!is_looping)
|
|
{
|
|
/#
|
|
if( GetDvarInt("debug_scene_skip") > 0)
|
|
{
|
|
PrintTopRightln( "player_scene_animation_skip: " + anim_name + " : " + GetTime(), (0.6, 0.6 , 0.6) );
|
|
}
|
|
#/
|
|
|
|
self SetAnimTimebyName(anim_name, 1, true);
|
|
}
|
|
}
|
|
}
|
|
|
|
function player_scene_skip_completed( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
|
|
{
|
|
//clear any on screen subtitles
|
|
flushsubtitles( localClientNum );
|
|
|
|
// assuming we are going back into gameplay, or the following scene has its own graphic content blur starts notify. clearing graphic content blur here so it doesn't affect gameplay.
|
|
SetDvar( "r_graphicContentBlur", false );
|
|
SetDvar( "r_makeDark_enable", false );
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// ___ ___ ___ _ _ ___ ___ ___ _ ___ ___ _____
|
|
// / __| / __| | __| | \| | | __| / _ \ | _ ) _ | | | __| / __| |_ _|
|
|
// \__ \ | (__ | _| | .` | | _| | (_) | | _ \ | || | | _| | (__ | |
|
|
// |___/ \___| |___| |_|\_| |___| \___/ |___/ \__/ |___| \___| |_|
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
class cSceneObject : cScriptBundleObjectBase
|
|
{
|
|
var _e_align_array; // align entities for the objects
|
|
var _str_name;
|
|
|
|
var _is_valid;
|
|
|
|
var _b_spawnonce_used;
|
|
|
|
constructor()
|
|
{
|
|
_b_spawnonce_used = false;
|
|
_is_valid = true;
|
|
}
|
|
|
|
destructor()
|
|
{
|
|
}
|
|
|
|
function first_init( s_objdef, o_scene, e_ent, localclientnum )
|
|
{
|
|
cScriptBundleObjectBase::init( s_objdef, o_scene, e_ent, localclientnum );
|
|
|
|
_assign_unique_name();
|
|
|
|
if ( _e_array.size )
|
|
{
|
|
_prepare( _n_clientnum );
|
|
}
|
|
|
|
return self;
|
|
}
|
|
|
|
function initialize()
|
|
{
|
|
if ( ( isdefined( _s.spawnoninit ) && _s.spawnoninit ) )
|
|
{
|
|
if ( isdefined( _n_clientnum ) )
|
|
{
|
|
_spawn( _n_clientnum, ( isdefined( _s.firstframe ) && _s.firstframe ) || isdefined( _s.initanim ) || isdefined( _s.initanimloop ) );
|
|
}
|
|
else
|
|
{
|
|
_spawn( 0, ( isdefined( _s.firstframe ) && _s.firstframe ) || isdefined( _s.initanim ) || isdefined( _s.initanimloop ) );
|
|
|
|
for ( clientNum = 1; clientNum < GetMaxLocalClients(); clientNum++ )
|
|
{
|
|
if ( isdefined( GetLocalPlayer( clientNum ) ) )
|
|
{
|
|
if ( ( isdefined( _s.spawnoninit ) && _s.spawnoninit ) )
|
|
{
|
|
_spawn( clientNum, ( isdefined( _s.firstframe ) && _s.firstframe ) || isdefined( _s.initanim ) || isdefined( _s.initanimloop ) );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
flagsys::clear( "ready" ); flagsys::clear( "done" ); flagsys::clear( "main_done" ); self notify( "new_state" ); self endon( "new_state" ); self notify("init"); waittillframeend;;
|
|
|
|
if ( isdefined( _n_clientnum ) )
|
|
{
|
|
thread initialize_per_client( _n_clientnum );
|
|
}
|
|
else
|
|
{
|
|
for ( clientNum = 1; clientNum < GetMaxLocalClients(); clientNum++ )
|
|
{
|
|
if ( isdefined( GetLocalPlayer( clientNum ) ) )
|
|
{
|
|
thread initialize_per_client( clientNum );
|
|
}
|
|
}
|
|
|
|
initialize_per_client( 0 );
|
|
}
|
|
}
|
|
|
|
function initialize_per_client( clientNum )
|
|
{
|
|
self endon("new_state");
|
|
|
|
if ( ( isdefined( _s.firstframe ) && _s.firstframe ) )
|
|
{
|
|
if ( !error( !isdefined( _s.mainanim ), "No animation defined for first frame." ) )
|
|
{
|
|
_play_anim( clientNum, _s.mainanim, 0, 0, 0, undefined, _s.mainshot );
|
|
}
|
|
}
|
|
else if ( isdefined( _s.initanim ) )
|
|
{
|
|
_play_anim( clientNum, _s.initanim, _s.initdelaymin, _s.initdelaymax, 1, undefined, _s.initshot );
|
|
|
|
if ( is_alive( clientNum ) )
|
|
{
|
|
if ( isdefined( _s.initanimloop ) )
|
|
{
|
|
_play_anim( clientNum, _s.initanimloop, 0, 0, 1, undefined, _s.initshotloop, true );
|
|
}
|
|
}
|
|
}
|
|
else if ( isdefined( _s.initanimloop ) )
|
|
{
|
|
_play_anim( clientNum, _s.initanimloop, _s.initdelaymin, _s.initdelaymax, 1, undefined, _s.initshotloop, true );
|
|
}
|
|
else
|
|
{
|
|
flagsys::set( "ready" );
|
|
}
|
|
|
|
if ( !_is_valid )
|
|
{
|
|
flagsys::set( "done" );
|
|
}
|
|
}
|
|
|
|
function play()
|
|
{
|
|
flagsys::clear( "ready" ); flagsys::clear( "done" ); flagsys::clear( "main_done" ); self notify( "new_state" ); self endon( "new_state" ); self notify("play"); waittillframeend;;
|
|
|
|
if ( isdefined( _n_clientnum ) )
|
|
{
|
|
play_per_client( _n_clientnum );
|
|
}
|
|
else
|
|
{
|
|
for ( clientNum = 1; clientNum < GetMaxLocalClients(); clientNum++ )
|
|
{
|
|
if ( isdefined( GetLocalPlayer( clientNum ) ) )
|
|
{
|
|
thread play_per_client( clientNum );
|
|
}
|
|
}
|
|
|
|
play_per_client( 0 );
|
|
}
|
|
}
|
|
|
|
function play_per_client( clientNum )
|
|
{
|
|
self endon("new_state");
|
|
|
|
if ( isdefined( _s.mainanim ) )
|
|
{
|
|
_play_anim( clientNum, _s.mainanim, _s.maindelaymin, _s.maindelaymax, 1, _s.mainblend, _s.mainshot );
|
|
|
|
flagsys::set( "main_done" );
|
|
|
|
if ( is_alive( clientNum ) )
|
|
{
|
|
if ( isdefined( _s.endanim ) )
|
|
{
|
|
_play_anim( clientNum, _s.endanim, 0, 0, 1, undefined, _s.endshot, true );
|
|
|
|
if ( is_alive( clientNum ) )
|
|
{
|
|
if ( isdefined( _s.endanimloop ) )
|
|
{
|
|
_play_anim( clientNum, _s.endanimloop, 0, 0, 1, undefined, _s.endshotloop, true );
|
|
}
|
|
}
|
|
}
|
|
else if ( isdefined( _s.endanimloop ) )
|
|
{
|
|
_play_anim( clientNum, _s.endanimloop, 0, 0, 1, undefined, _s.endshotloop, true );
|
|
}
|
|
}
|
|
}
|
|
|
|
thread finish_per_client( clientNum );
|
|
}
|
|
|
|
function finish( b_clear = false )
|
|
{
|
|
self notify( "new_state" );
|
|
|
|
if ( isdefined( _n_clientnum ) )
|
|
{
|
|
finish_per_client( _n_clientnum, b_clear );
|
|
}
|
|
else
|
|
{
|
|
for ( clientNum = 1; clientNum < GetMaxLocalClients(); clientNum++ )
|
|
{
|
|
if ( isdefined( GetLocalPlayer( clientNum ) ) )
|
|
{
|
|
finish_per_client( clientNum, b_clear );
|
|
}
|
|
}
|
|
|
|
finish_per_client( 0, b_clear );
|
|
}
|
|
}
|
|
|
|
function finish_per_client( clientNum, b_clear = false )
|
|
{
|
|
if ( !is_alive( clientNum ) )
|
|
{
|
|
_cleanup( clientNum );
|
|
|
|
_e_array[ clientNum ] = undefined;
|
|
_is_valid = false;
|
|
}
|
|
|
|
flagsys::set( "ready" );
|
|
flagsys::set( "done" );
|
|
|
|
if ( isdefined( _e_array[ clientNum ] ) )
|
|
{
|
|
if ( is_alive( clientNum ) && ( ( isdefined( _s.deletewhenfinished ) && _s.deletewhenfinished ) || b_clear ) )
|
|
{
|
|
_e_array[ clientNum ] Delete();
|
|
}
|
|
}
|
|
|
|
_cleanup( clientNum );
|
|
}
|
|
|
|
function get_align_ent( clientNum )
|
|
{
|
|
e_align = undefined;
|
|
|
|
if ( isdefined( _s.aligntarget ) )
|
|
{
|
|
a_scene_ents = [[_o_bundle]]->get_ents();
|
|
if ( isdefined( a_scene_ents[clientNum][ _s.aligntarget ] ) )
|
|
{
|
|
e_align = a_scene_ents[clientNum][ _s.aligntarget ];
|
|
}
|
|
else
|
|
{
|
|
e_align = scene::get_existing_ent( clientNum, _s.aligntarget );
|
|
}
|
|
|
|
error( !isdefined( e_align ), "Align target '" + (isdefined(_s.aligntarget)?""+_s.aligntarget:"") + "' doesn't exist for scene object." );
|
|
}
|
|
|
|
if ( !isdefined( e_align ) )
|
|
{
|
|
e_align = [[scene()]]->get_align_ent( clientNum );
|
|
}
|
|
|
|
return e_align;
|
|
}
|
|
|
|
/* Scene Helpers */
|
|
|
|
function scene()
|
|
{
|
|
return _o_bundle;
|
|
}
|
|
|
|
/* internal functions */
|
|
|
|
function _assign_unique_name()
|
|
{
|
|
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( clientNum, b_hide = true )
|
|
{
|
|
if ( !isdefined( _e_array[clientNum] ) )
|
|
{
|
|
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;
|
|
}
|
|
|
|
_e_array[clientNum] = scene::get_existing_ent( clientNum, _str_name );
|
|
if ( !isdefined( _e_array[clientNum] ) && isdefined( _s.name ) && !b_allows_multiple )
|
|
{
|
|
_e_array[clientNum] = scene::get_existing_ent( clientNum, _s.name );
|
|
}
|
|
|
|
if ( !isdefined( _e_array[clientNum] ) && !( isdefined( _s.nospawn ) && _s.nospawn ) && !_b_spawnonce_used )
|
|
{
|
|
_e_align = get_align_ent( clientNum );
|
|
_e_array[clientNum] = util::spawn_model( clientNum, _s.model, _e_align.origin, _e_align.angles );
|
|
|
|
if ( isdefined( _e_array[clientNum] ) )
|
|
{
|
|
if ( b_hide )
|
|
{
|
|
_e_array[clientNum] Hide(); // Hide teleporting glitches
|
|
}
|
|
|
|
_e_array[clientNum].scene_spawned = _o_bundle._s.name;
|
|
_e_array[clientNum].targetname = _s.name;
|
|
}
|
|
else
|
|
{
|
|
error( !( isdefined( _s.nospawn ) && _s.nospawn ), "No entity exists with matching name of scene object." );
|
|
}
|
|
}
|
|
|
|
if ( ( isdefined( _s.spawnonce ) && _s.spawnonce ) && _b_spawnonce_used )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ( !error( !( isdefined( _s.nospawn ) && _s.nospawn ) && !isdefined( _e_array[clientNum] ), "No entity exists with matching name of scene object. Make sure a model is specified if you want to spawn it." ) )
|
|
{
|
|
_prepare( clientNum );
|
|
}
|
|
}
|
|
|
|
if ( isdefined( _e_array[clientNum] ) )
|
|
{
|
|
flagsys::set( "ready" );
|
|
|
|
if ( ( isdefined( _s.spawnonce ) && _s.spawnonce ) )
|
|
{
|
|
_b_spawnonce_used = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
function _prepare( clientNum )
|
|
{
|
|
if ( !( isdefined( _s.issiege ) && _s.issiege ) )
|
|
{
|
|
if( !_e_array[clientNum] HasAnimTree() )
|
|
{
|
|
_e_array[clientNum] UseAnimTree( #animtree );
|
|
}
|
|
}
|
|
|
|
_e_array[clientNum].animname = _str_name;
|
|
_e_array[clientNum].anim_debug_name = _s.name;
|
|
|
|
_e_array[clientNum] flagsys::set( "scene" );
|
|
_e_array[clientNum] flagsys::set( _o_bundle._str_name );
|
|
_e_array[clientNum].current_scene = _o_bundle._str_name;
|
|
_e_array[clientNum].finished_scene = undefined;
|
|
}
|
|
|
|
function _cleanup( clientNum )
|
|
{
|
|
if ( isdefined( _e_array[clientNum] ) && isdefined( _e_array[clientNum].current_scene ) )
|
|
{
|
|
_e_array[clientNum] flagsys::clear( _o_bundle._str_name );
|
|
|
|
if ( _e_array[clientNum].current_scene == _o_bundle._str_name )
|
|
{
|
|
_e_array[clientNum] flagsys::clear( "scene" );
|
|
_e_array[clientNum].finished_scene = _o_bundle._str_name;
|
|
_e_array[clientNum].current_scene = undefined;
|
|
}
|
|
}
|
|
|
|
if ( ( clientNum === _n_clientnum ) || ( clientNum == 0 ) )
|
|
{
|
|
if ( isdefined( _o_bundle ) && ( isdefined( _o_bundle.scene_stopped ) && _o_bundle.scene_stopped ) ) // don't clear this if the scene is looping
|
|
{
|
|
_o_bundle = undefined;
|
|
}
|
|
}
|
|
}
|
|
|
|
function _play_anim( clientNum, animation, n_delay_min = 0, n_delay_max = 0, n_rate = 1, n_blend, str_siege_shot, loop )
|
|
{
|
|
n_delay = n_delay_min;
|
|
if ( n_delay_max > n_delay_min )
|
|
{
|
|
n_delay = RandomFloatRange( n_delay_min, n_delay_max );
|
|
}
|
|
|
|
if ( n_delay > 0 )
|
|
{
|
|
flagsys::set( "ready" ); // tell scene to go on without this object
|
|
|
|
wait n_delay;
|
|
_spawn( clientNum );
|
|
}
|
|
else
|
|
{
|
|
_spawn( clientNum ) ;
|
|
|
|
//[[scene()]]->wait_till_scene_ready();
|
|
}
|
|
|
|
if ( is_alive( clientNum ) )
|
|
{
|
|
/*
|
|
if ( IS_EQUAL( _e.scene_spawned, _o_bundle._s.name ) )
|
|
{
|
|
_e util::delay( .05, undefined, &Show ); // Entity was hidden to hide teleporting glitches
|
|
}
|
|
*/
|
|
_e_array[clientNum] Show();
|
|
|
|
if ( ( isdefined( _s.issiege ) && _s.issiege ) )
|
|
{
|
|
_e_array[clientNum] notify( "end" ); // make sure previous thread dies
|
|
_e_array[clientNum] animation::play_siege( animation, str_siege_shot, n_rate, loop );
|
|
}
|
|
else
|
|
{
|
|
align = get_align_ent( clientNum );
|
|
tag = get_align_tag();
|
|
|
|
if ( align == level )
|
|
{
|
|
align = ( 0, 0, 0 );
|
|
tag = ( 0, 0, 0 );
|
|
}
|
|
|
|
_e_array[clientNum] animation::play( animation, align, tag, n_rate, n_blend );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/# log( "No entity for animation '" + animation + "' so not playing it." ); #/
|
|
}
|
|
|
|
_is_valid = is_alive( clientNum );
|
|
}
|
|
|
|
function get_align_tag()
|
|
{
|
|
if ( isdefined( _s.AlignTargetTag ) )
|
|
{
|
|
return _s.AlignTargetTag;
|
|
}
|
|
else
|
|
{
|
|
return _o_bundle._s.AlignTargetTag;
|
|
}
|
|
}
|
|
|
|
function wait_till_scene_ready()
|
|
{
|
|
[[scene()]]->wait_till_scene_ready();
|
|
}
|
|
|
|
function has_init_state()
|
|
{
|
|
return _s scene::_has_init_state();
|
|
}
|
|
|
|
function is_alive( clientNum )
|
|
{
|
|
return isdefined( _e_array[ clientNum ] );
|
|
}
|
|
|
|
function in_a_different_scene()
|
|
{
|
|
if ( isdefined( _n_clientnum ) )
|
|
{
|
|
if ( isdefined( _e_array[ _n_clientnum ] ) && isdefined( _e_array[ _n_clientnum ].current_scene ) && ( _e_array[ _n_clientnum ].current_scene != _o_bundle._str_name ) )
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( isdefined( _e_array[ 0 ] ) && isdefined( _e_array[ 0 ].current_scene ) && ( _e_array[ 0 ].current_scene != _o_bundle._str_name ) )
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// ___ ___ ___ _ _ ___
|
|
// / __| / __| | __| | \| | | __|
|
|
// \__ \ | (__ | _| | .` | | _|
|
|
// |___/ \___| |___| |_|\_| |___|
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
class cScene : cScriptBundleBase
|
|
{
|
|
var _e_root;
|
|
var _str_state;
|
|
var _n_object_id;
|
|
var _str_mode;
|
|
|
|
constructor()
|
|
{
|
|
_n_object_id = 0;
|
|
_str_state = "";
|
|
}
|
|
|
|
destructor()
|
|
{
|
|
}
|
|
|
|
function init( str_scenedef, s_scenedef, e_align, a_ents, b_test_run )
|
|
{
|
|
cScriptBundleBase::init( str_scenedef, s_scenedef, b_test_run );
|
|
|
|
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 ( str_name, e_ent in ArrayCopy( a_ents ) )
|
|
{
|
|
foreach ( i, s_obj in ArrayCopy( a_objs ) )
|
|
{
|
|
if ( ( s_obj.name === (isdefined(str_name)?""+str_name:"") ) )
|
|
{
|
|
add_object( [[ new cSceneObject() ]]->first_init( s_obj, self, e_ent, _e_root.localclientnum ) );
|
|
|
|
ArrayRemoveIndex( a_ents, str_name );
|
|
ArrayRemoveIndex( a_objs, i );
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach ( s_obj in a_objs )
|
|
{
|
|
add_object( [[ new cSceneObject() ]]->first_init( s_obj, self, array::pop( a_ents ), _e_root.localclientnum ) );
|
|
}
|
|
|
|
self thread initialize();
|
|
}
|
|
}
|
|
|
|
/*
|
|
function init( str_scenedef, s_scenedef, e_align, a_ents, b_test_run )
|
|
{
|
|
cScriptBundleBase::init( str_scenedef, s_scenedef, b_test_run );
|
|
|
|
_e_root = e_align;
|
|
|
|
ARRAY_ADD( level.active_scenes[ _str_name ], _e_root );
|
|
ARRAY_ADD( _e_root.scenes, self );
|
|
|
|
a_objs = get_valid_object_defs();
|
|
|
|
foreach ( s_obj in a_objs )
|
|
{
|
|
add_object( [[new cSceneObject()]]->first_init( s_obj, self ) );
|
|
}
|
|
|
|
_e_root thread scene::debug_display();
|
|
|
|
self thread initialize();
|
|
}
|
|
*/
|
|
|
|
function get_valid_object_defs()
|
|
{
|
|
a_obj_defs = [];
|
|
foreach ( s_obj in _s.objects )
|
|
{
|
|
if ( _s.vmtype == "client" || s_obj.vmtype == "client" )
|
|
{
|
|
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( b_playing = false )
|
|
{
|
|
self notify( "new_state" );
|
|
self endon( "new_state" );
|
|
|
|
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" );
|
|
}
|
|
}
|
|
|
|
// stops the scene if all objects die in the initialize state
|
|
wait_till_scene_done();
|
|
thread stop();
|
|
}
|
|
|
|
function get_object_id()
|
|
{
|
|
_n_object_id++;
|
|
return _n_object_id;
|
|
}
|
|
|
|
function play( b_testing = false, str_mode = "" )
|
|
{
|
|
level endon("demo_jump"); // end when theater mode rewinds
|
|
self notify( "new_state" );
|
|
self endon( "new_state" );
|
|
|
|
_testing = b_testing;
|
|
_str_mode = str_mode;
|
|
|
|
if ( get_valid_objects().size > 0 )
|
|
{
|
|
foreach ( o_obj in _a_objects )
|
|
{
|
|
thread [[o_obj]]->play();
|
|
}
|
|
|
|
level flagsys::set( _str_name + "_playing" );
|
|
_str_state = "play";
|
|
|
|
wait_till_scene_ready();
|
|
|
|
thread _call_state_funcs( "play" );
|
|
|
|
wait_till_scene_done();
|
|
|
|
array::flagsys_wait_any_flag( _a_objects, "done", "main_done" );
|
|
|
|
if ( isdefined( _e_root ) )
|
|
{
|
|
_e_root notify( "scene_done", _str_name );
|
|
thread _call_state_funcs( "done" );
|
|
}
|
|
|
|
array::flagsys_wait( _a_objects, "done" );
|
|
|
|
if ( is_looping() || ( _str_mode == "loop" ) )
|
|
{
|
|
if ( has_init_state() )
|
|
{
|
|
level flagsys::clear( _str_name + "_playing" );
|
|
|
|
thread initialize();
|
|
}
|
|
else
|
|
{
|
|
level flagsys::clear( _str_name + "_initialized" );
|
|
|
|
thread play( b_testing, str_mode );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
thread run_next();
|
|
thread stop( false, true );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
thread stop( false, true );
|
|
}
|
|
}
|
|
|
|
function run_next()
|
|
{
|
|
if ( isdefined( _s.nextscenebundle ) && ( _s.vmtype != "both" ) )
|
|
{
|
|
self waittill( "stopped", b_finished );
|
|
|
|
if ( b_finished )
|
|
{
|
|
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 ( allows_multiple() )
|
|
{
|
|
_e_root thread scene::play( _s.nextscenebundle, get_ents() );
|
|
}
|
|
else
|
|
{
|
|
_e_root thread scene::play( _s.nextscenebundle );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function stop( b_clear = false, b_finished = false )
|
|
{
|
|
self notify( "new_state" );
|
|
|
|
level flagsys::clear( _str_name + "_playing" );
|
|
level flagsys::clear( _str_name + "_initialized" );
|
|
_str_state = "";
|
|
|
|
thread _call_state_funcs( "stop" );
|
|
|
|
self.scene_stopped = true;
|
|
|
|
foreach ( o_obj in _a_objects )
|
|
{
|
|
if ( isdefined( o_obj ) && ![[ o_obj ]]->in_a_different_scene() )
|
|
{
|
|
thread [[o_obj]]->finish( b_clear );
|
|
}
|
|
}
|
|
|
|
self notify( "stopped", b_finished );
|
|
|
|
if ( IsDefined( level.active_scenes[ _str_name ] ) )
|
|
{
|
|
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 ) && IsDefined( _e_root.scenes ) )
|
|
{
|
|
ArrayRemoveValue( _e_root.scenes, self );
|
|
|
|
if ( _e_root.scenes.size == 0 )
|
|
{
|
|
_e_root.scenes = undefined;
|
|
}
|
|
|
|
_e_root notify( "scene_done", _str_name );
|
|
_e_root.scene_played = true;
|
|
}
|
|
}
|
|
|
|
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();
|
|
|
|
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_name + "_" + str_state );
|
|
|
|
if ( isdefined( level.scene_funcs ) && isdefined( level.scene_funcs[ _str_name ] ) && isdefined( level.scene_funcs[ _str_name ][ str_state ] ) )
|
|
{
|
|
a_all_ents = get_ents();
|
|
|
|
foreach ( clientnum, a_ents in a_all_ents )
|
|
{
|
|
foreach ( handler in level.scene_funcs[ _str_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 = [];
|
|
|
|
for ( clientNum = 0; clientNum < GetMaxLocalClients(); clientNum++ )
|
|
{
|
|
if ( isdefined( GetLocalPlayer( clientNum ) ) )
|
|
{
|
|
a_ents[ clientNum ] = [];
|
|
|
|
foreach ( o_obj in _a_objects )
|
|
{
|
|
ent = [[ o_obj ]]->get_ent( clientNum );
|
|
|
|
if ( isdefined( o_obj._s.name ) )
|
|
{
|
|
a_ents[ clientNum ][ 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( clientNum )
|
|
{
|
|
e_align = _e_root;
|
|
|
|
if ( isdefined( _s.aligntarget ) )
|
|
{
|
|
e_gdt_align = scene::get_existing_ent( clientNum, _s.aligntarget );
|
|
if ( isdefined( e_gdt_align ) )
|
|
{
|
|
e_align = e_gdt_align;
|
|
}
|
|
}
|
|
|
|
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()
|
|
{
|
|
if ( isdefined( _a_objects ) )
|
|
{
|
|
array::flagsys_wait( _a_objects, "ready" );
|
|
}
|
|
}
|
|
|
|
function wait_till_scene_done()
|
|
{
|
|
array::flagsys_wait( _a_objects, "done" );
|
|
}
|
|
|
|
function get_valid_objects()
|
|
{
|
|
a_obj = [];
|
|
|
|
foreach ( obj in _a_objects )
|
|
{
|
|
if ( obj._is_valid && ![[obj]]->in_a_different_scene() )
|
|
{
|
|
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 get_existing_ent( clientNum, str_name )
|
|
{
|
|
e = GetEnt( clientNum, str_name, "animname" ); // entity already exists
|
|
if ( !isdefined( e ) )
|
|
{
|
|
e = GetEnt( clientNum, str_name, "script_animname" ); // a spawner exists with script_animname
|
|
if ( !isdefined( e ) )
|
|
{
|
|
e = GetEnt( clientNum, str_name, "targetname" ); // lastly grab any ent with targetname
|
|
if ( !isdefined( e ) )
|
|
{
|
|
e = struct::get( str_name, "targetname" ); // if no ent, grab struct with targetname
|
|
}
|
|
}
|
|
}
|
|
|
|
return e;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// _ _ _____ ___ _ ___ _____ __ __
|
|
// | | | | |_ _| |_ _| | | |_ _| |_ _| \ \ / /
|
|
// | |_| | | | | | | |__ | | | | \ V /
|
|
// \___/ |_| |___| |____| |___| |_| |_|
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
function autoexec __init__sytem__() { system::register("scene",&__init__,&__main__,undefined); }
|
|
|
|
function __init__()
|
|
{
|
|
a_scenedefs = struct::get_script_bundles( "scene" );
|
|
|
|
/* FIX UP STUFF FROM THE GDT */
|
|
|
|
level.server_scenes = [];
|
|
|
|
foreach ( s_scenedef in a_scenedefs )
|
|
{
|
|
s_scenedef.editaction = undefined; // only used in the asset editor
|
|
s_scenedef.newobject = undefined; // only used in the asset editor
|
|
|
|
if ( s_scenedef is_igc() )
|
|
{
|
|
level.server_scenes[ s_scenedef.name ] = s_scenedef; // This is used in code callback through xcam code to make sure client scenes sync with the xcam
|
|
}
|
|
else if ( s_scenedef.vmtype == "both" )
|
|
{
|
|
n_clientbits = GetMinBitCountForNum( 3 );
|
|
|
|
/#
|
|
n_clientbits = GetMinBitCountForNum( 6 );
|
|
#/
|
|
|
|
clientfield::register( "world", s_scenedef.name, 1, n_clientbits, "int", &cf_server_sync, !true, !true );
|
|
}
|
|
}
|
|
|
|
clientfield::register( "toplayer", "postfx_igc", 1, 2, "counter", &postfx_igc, !true, !true );
|
|
clientfield::register( "world", "in_igc", 1, 4, "int", &in_igc, !true, !true );
|
|
|
|
clientfield::register( "toplayer", "player_scene_skip_completed", 1, 2, "counter", &player_scene_skip_completed, !true, !true );
|
|
|
|
clientfield::register( "allplayers", "player_scene_animation_skip", 1, 2, "counter", &player_scene_animation_skip, !true, !true );
|
|
clientfield::register( "actor", "player_scene_animation_skip", 1, 2, "counter", &player_scene_animation_skip, !true, !true );
|
|
clientfield::register( "vehicle", "player_scene_animation_skip", 1, 2, "counter", &player_scene_animation_skip, !true, !true );
|
|
clientfield::register( "scriptmover", "player_scene_animation_skip", 1, 2, "counter", &player_scene_animation_skip, !true, !true );
|
|
|
|
|
|
/* INIT SYSTEM VARS */
|
|
|
|
level.scene_object_id = 0;
|
|
level.active_scenes = [];
|
|
|
|
callback::on_localclient_shutdown( &on_localplayer_shutdown );
|
|
}
|
|
|
|
function in_igc( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
|
|
{
|
|
player = GetLocalPlayer( localClientNum );
|
|
n_entnum = player GetEntityNumber();
|
|
|
|
b_igc_active = false;
|
|
|
|
if ( newVal & ( 1 << n_entnum ) )
|
|
{
|
|
b_igc_active = true;
|
|
}
|
|
|
|
IGCactive( localClientNum, b_igc_active );
|
|
|
|
/#
|
|
//PrintTopRightln( "CLIENT " + n_entnum + ": 'in_igc' set to " + b_igc_active, ( b_igc_active ? RED : GREEN ), -1 );
|
|
#/
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function private on_localplayer_shutdown( localClientNum )
|
|
{
|
|
localPlayer = self;
|
|
codeLocalPlayer = GetLocalPlayer( localClientNum );
|
|
if ( isdefined( localPlayer ) && isdefined( localPlayer.localClientNum ) && isdefined( codeLocalPlayer ) && localPlayer == codeLocalPlayer )
|
|
{
|
|
filter::disable_filter_base_frame_transition( localPlayer, 5 );
|
|
filter::disable_filter_sprite_transition( localPlayer, 5 );
|
|
filter::disable_filter_frame_transition( localPlayer, 5 );
|
|
|
|
localPlayer.postfx_igc_on = undefined;
|
|
localPlayer.pstfx_world_construction = false;
|
|
}
|
|
}
|
|
|
|
function postfx_igc( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
|
|
{
|
|
self endon( "entityshutdown" );
|
|
|
|
if ( ( isdefined( self.postfx_igc_on ) && self.postfx_igc_on ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if( SessionModeIsZombiesGame() )
|
|
{
|
|
postfx_igc_zombies( localClientNum );
|
|
return;
|
|
}
|
|
|
|
if( newVal == 3 ) //play shorter version of effect
|
|
{
|
|
self thread postfx_igc_short( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump );
|
|
return;
|
|
}
|
|
|
|
self.postfx_igc_on = 1;
|
|
|
|
codeImageName = "postfx_igc_image" + localClientNum;
|
|
CreateSceneCodeImage( localClientNum, codeImageName );
|
|
CaptureFrame( localClientNum, codeImageName );
|
|
|
|
filter::init_filter_base_frame_transition( self );
|
|
filter::init_filter_sprite_transition( self );
|
|
filter::init_filter_frame_transition( self );
|
|
|
|
setFilterPassCodeTexture( localClientNum, 5, 0, 0, codeImageName );
|
|
setFilterPassCodeTexture( localClientNum, 5, 1, 0, codeImageName );
|
|
setFilterPassCodeTexture( localClientNum, 5, 2, 0, codeImageName );
|
|
|
|
filter::enable_filter_base_frame_transition( self, 5 );
|
|
filter::enable_filter_sprite_transition( self, 5 );
|
|
filter::enable_filter_frame_transition( self, 5 );
|
|
|
|
filter::set_filter_base_frame_transition_warp( self, 5, 1.0 );
|
|
filter::set_filter_base_frame_transition_boost( self, 5, 0.5 );
|
|
filter::set_filter_base_frame_transition_durden( self, 5, 1.0 );
|
|
filter::set_filter_base_frame_transition_durden_blur( self, 5, 1 );
|
|
|
|
filter::set_filter_sprite_transition_elapsed( self, 5, 0 );
|
|
filter::set_filter_sprite_transition_octogons( self, 5, 1.0 );
|
|
filter::set_filter_sprite_transition_blur( self, 5, 0.0 );
|
|
filter::set_filter_sprite_transition_boost( self, 5, 0.0 );
|
|
|
|
filter::set_filter_frame_transition_light_hexagons( self, 5, 0.0 );
|
|
filter::set_filter_frame_transition_heavy_hexagons( self, 5, 0.0 );
|
|
filter::set_filter_frame_transition_flare( self, 5, 0.0 );
|
|
filter::set_filter_frame_transition_blur( self, 5, 0.0 );
|
|
filter::set_filter_frame_transition_iris( self, 5, 0.0 );
|
|
filter::set_filter_frame_transition_saved_frame_reveal( self, 5, 0.0 );
|
|
|
|
filter::set_filter_frame_transition_warp( self, 5, 0 ); //zoom in on screen
|
|
filter::set_filter_sprite_transition_move_radii( self, 5, 0, 0 ); // inner (outer - 256), outer (2000)
|
|
|
|
filter::set_filter_base_frame_transition_warp( self, 5, 1.0 );
|
|
filter::set_filter_base_frame_transition_boost( self, 5, 1.0 );
|
|
|
|
n_hex = 0;
|
|
|
|
b_streamer_wait = true;
|
|
|
|
for ( i = 0; i < 2000; i += ( .016 * 1000 ) )
|
|
{
|
|
sT = i / 1000.0; //convert ms to sec
|
|
|
|
if ( b_streamer_wait && ( sT >= .65 ) )
|
|
{
|
|
n_streamer_time_total = 0;
|
|
|
|
while ( !IsStreamerReady() && ( n_streamer_time_total < 5000 ) )
|
|
{
|
|
n_streamer_time = GetTime();
|
|
|
|
for ( j = ( .65 * 1000 ); j < ( 1.15 * 1000 ); j += ( .016 * 1000 ) )
|
|
{
|
|
jT = j / 1000.0; //convert ms to sec
|
|
filter::set_filter_frame_transition_heavy_hexagons( self, 5, MapFloat( 0.65, 1.15, 0, 1, jT ) );
|
|
{wait(.016);};
|
|
}
|
|
|
|
for ( j = ( 1.15 * 1000 ); j < ( .65 * 1000 ); j -= ( .016 * 1000 ) )
|
|
{
|
|
jT = j / 1000.0; //convert ms to sec
|
|
filter::set_filter_frame_transition_heavy_hexagons( self, 5, MapFloat( 0.65, 1.15, 0, 1, jT ) );
|
|
{wait(.016);};
|
|
}
|
|
|
|
n_streamer_time_total += ( GetTime() - n_streamer_time );
|
|
}
|
|
|
|
b_streamer_wait = false;
|
|
}
|
|
|
|
if ( sT <= 0.5 )
|
|
{
|
|
filter::set_filter_frame_transition_iris( self, 5, MapFloat( 0, 0.5, 0, 1, sT ) );
|
|
}
|
|
else if ( sT > 0.5 && sT <= 0.85 )
|
|
{
|
|
filter::set_filter_frame_transition_iris( self, 5, 1 - MapFloat( 0.5, 0.85, 0, 1, sT ) );
|
|
}
|
|
else
|
|
{
|
|
filter::set_filter_frame_transition_iris( self, 5, 0.0 );
|
|
}
|
|
|
|
if ( newVal == 2 )
|
|
{
|
|
if ( sT > 1.0 && !( isdefined( self.pstfx_world_construction ) && self.pstfx_world_construction ) )
|
|
{
|
|
self thread postfx::playpostfxbundle( "pstfx_world_construction" );
|
|
self.pstfx_world_construction = true;
|
|
}
|
|
}
|
|
|
|
//LIGHT HEX
|
|
if ( sT > 0.5 && sT <= 1.0 )
|
|
{
|
|
n_hex = MapFloat( 0.5, 1.0, 0, 1, sT );
|
|
filter::set_filter_frame_transition_light_hexagons( self, 5, n_hex );
|
|
|
|
if ( sT >= 0.8 )
|
|
{
|
|
filter::set_filter_frame_transition_flare( self, 5, MapFloat( 0.8, 1, 0, 1, sT ) );
|
|
}
|
|
}
|
|
else if ( sT > 1.0 && sT < 1.5 )
|
|
{
|
|
filter::set_filter_frame_transition_light_hexagons( self, 5, 1.0 );
|
|
filter::set_filter_frame_transition_flare( self, 5, 1.0 );
|
|
}
|
|
else
|
|
{
|
|
filter::set_filter_frame_transition_light_hexagons( self, 5, 0.0 );
|
|
filter::set_filter_frame_transition_flare( self, 5, 0.0 );
|
|
}
|
|
|
|
//HEAVY HEX
|
|
if ( sT > 0.65 && sT <= 1.15 )
|
|
{
|
|
filter::set_filter_frame_transition_heavy_hexagons( self, 5, MapFloat( 0.65, 1.15, 0, 1, sT ) );
|
|
}
|
|
else if ( sT > 1.21 && sT < 1.50 )
|
|
{
|
|
filter::set_filter_frame_transition_heavy_hexagons( self, 5, 1.0 );
|
|
}
|
|
else
|
|
{
|
|
filter::set_filter_frame_transition_heavy_hexagons( self, 5, 0.0 );
|
|
}
|
|
|
|
|
|
if ( sT > 1.21 && sT <= 1.5 )
|
|
{
|
|
filter::set_filter_frame_transition_blur( self, 5, MapFloat( 1.0, 1.5, 0, 1, sT ) );
|
|
filter::set_filter_sprite_transition_boost( self, 5, MapFloat( 1.0, 1.5, 0, 1, sT ) );
|
|
filter::set_filter_frame_transition_saved_frame_reveal( self, 5, MapFloat( 1.0, 1.5, 0, 1, sT ) );
|
|
filter::set_filter_base_frame_transition_durden_blur( self, 5, 1.0 - MapFloat( 1.0, 1.5, 0, 1, sT ) );
|
|
filter::set_filter_sprite_transition_blur( self, 5, MapFloat( 1.0, 1.5, 0, 0.1, sT ) );
|
|
}
|
|
else if ( sT > 1.5 )
|
|
{
|
|
filter::set_filter_frame_transition_blur( self, 5, 1.0 );
|
|
filter::set_filter_sprite_transition_boost( self, 5, 1.0 );
|
|
filter::set_filter_frame_transition_saved_frame_reveal( self, 5, 1.0 );
|
|
filter::set_filter_base_frame_transition_durden_blur( self, 5, 0.0 );
|
|
filter::set_filter_sprite_transition_blur( self, 5, 0.1 );
|
|
}
|
|
|
|
if ( sT > 1.0 && sT <= 1.45 )
|
|
{
|
|
filter::set_filter_base_frame_transition_boost( self, 5, MapFloat( 1.0, 1.45, 0.5, 1, sT ) );
|
|
}
|
|
else if ( sT > 1.45 && sT < 1.75)
|
|
{
|
|
filter::set_filter_base_frame_transition_boost( self, 5, 1.0 );
|
|
}
|
|
else if ( sT >= 1.75 )
|
|
{
|
|
filter::set_filter_base_frame_transition_boost( self, 5, 1.0 - MapFloat(1.75, 2.0, 0, 1, sT ) );
|
|
}
|
|
|
|
if ( sT >= 1.75 )
|
|
{
|
|
val = 1.0 - MapFloat(1.75, 2.0, 0, 1, sT );
|
|
filter::set_filter_frame_transition_blur( self, 5, val );
|
|
filter::set_filter_base_frame_transition_warp( self, 5, val );
|
|
}
|
|
|
|
if ( sT >= 1.25 )
|
|
{
|
|
val = 1.0 - MapFloat( 1.25, 1.75, 0, 1, sT );
|
|
filter::set_filter_sprite_transition_octogons( self, 5, val );
|
|
}
|
|
|
|
// RREVEAL SECRET FRAME
|
|
if ( sT >= 1.75 && sT < 2.0 )
|
|
{
|
|
filter::set_filter_base_frame_transition_durden( self, 5, 1.0 - MapFloat( 1.75, 2.0, 0, 1, sT ) );
|
|
}
|
|
|
|
// update timings
|
|
if ( sT > 1.0 )
|
|
{
|
|
filter::set_filter_sprite_transition_elapsed( self, 5, i - 1000);
|
|
|
|
outer_radii = MapFloat( 1.0, 1.50, 0, 2000, sT );
|
|
filter::set_filter_sprite_transition_move_radii( self, 5, outer_radii - 256, outer_radii );
|
|
}
|
|
|
|
if ( sT > 1.15 && sT < 1.85 )
|
|
{
|
|
filter::set_filter_frame_transition_warp( self, 5, -1 * ( MapFloat( 1.15, 1.85, 0, 1, sT ) ) );
|
|
}
|
|
else if ( sT >= 1.85 )
|
|
{
|
|
filter::set_filter_frame_transition_warp( self, 5, -1 * ( 1 - MapFloat( 1.85, 2.0, 0, 1, sT ) ) );
|
|
}
|
|
|
|
{wait(.016);};
|
|
}
|
|
|
|
|
|
filter::disable_filter_base_frame_transition( self, 5 );
|
|
filter::disable_filter_sprite_transition( self, 5 );
|
|
filter::disable_filter_frame_transition( self, 5 );
|
|
|
|
self.pstfx_world_construction = false;
|
|
|
|
FreeCodeImage( localClientNum, codeImageName );
|
|
self.postfx_igc_on = undefined;
|
|
}
|
|
|
|
function postfx_igc_zombies( localClientNum )
|
|
{
|
|
lui::screen_fade_out(0, "black");
|
|
|
|
{wait(.016);};
|
|
|
|
lui::screen_fade_in(0.3);
|
|
|
|
self.postfx_igc_on = undefined;
|
|
}
|
|
|
|
function postfx_igc_short( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
|
|
{
|
|
self endon( "entityshutdown" );
|
|
|
|
self.postfx_igc_on = 1;
|
|
|
|
codeImageName = "postfx_igc_image" + localClientNum;
|
|
CreateSceneCodeImage( localClientNum, codeImageName );
|
|
CaptureFrame( localClientNum, codeImageName );
|
|
|
|
filter::init_filter_base_frame_transition( self );
|
|
filter::init_filter_sprite_transition( self );
|
|
filter::init_filter_frame_transition( self );
|
|
|
|
setFilterPassCodeTexture( localClientNum, 5, 0, 0, codeImageName );
|
|
setFilterPassCodeTexture( localClientNum, 5, 1, 0, codeImageName );
|
|
setFilterPassCodeTexture( localClientNum, 5, 2, 0, codeImageName );
|
|
|
|
filter::enable_filter_base_frame_transition( self, 5 );
|
|
filter::enable_filter_sprite_transition( self, 5 );
|
|
filter::enable_filter_frame_transition( self, 5 );
|
|
|
|
filter::set_filter_frame_transition_iris( self, 5, 0.0 );
|
|
|
|
b_streamer_wait = true;
|
|
|
|
for ( i = 0; i < 850; i += ( .016 * 1000 ) )
|
|
{
|
|
sT = i / 1000.0; //convert ms to sec
|
|
|
|
if ( sT <= 0.5 )
|
|
{
|
|
filter::set_filter_frame_transition_iris( self, 5, MapFloat( 0, 0.5, 0, 1, sT ) );
|
|
}
|
|
else if ( sT > 0.5 && sT <= 0.85 )
|
|
{
|
|
filter::set_filter_frame_transition_iris( self, 5, 1 - MapFloat( 0.5, 0.85, 0, 1, sT ) );
|
|
}
|
|
else
|
|
{
|
|
filter::set_filter_frame_transition_iris( self, 5, 0.0 );
|
|
}
|
|
|
|
{wait(.016);};
|
|
}
|
|
|
|
filter::disable_filter_base_frame_transition( self, 5 );
|
|
filter::disable_filter_sprite_transition( self, 5 );
|
|
filter::disable_filter_frame_transition( self, 5 );
|
|
|
|
FreeCodeImage( localClientNum, codeImageName );
|
|
self.postfx_igc_on = undefined;
|
|
}
|
|
|
|
function cf_server_sync( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
|
|
{
|
|
switch ( newVal )
|
|
{
|
|
case 0:
|
|
|
|
if ( is_active( fieldName ) )
|
|
{
|
|
level thread scene::stop( fieldName );
|
|
}
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
level thread scene::init( fieldName );
|
|
break;
|
|
|
|
case 2:
|
|
|
|
level thread scene::play( fieldName );
|
|
break;
|
|
}
|
|
|
|
/#
|
|
|
|
switch ( newVal )
|
|
{
|
|
case 3:
|
|
|
|
if ( is_active( fieldName ) )
|
|
{
|
|
level thread scene::stop( fieldName, true, undefined, undefined, true );
|
|
}
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
level thread scene::init( fieldName, undefined, undefined, true );
|
|
break;
|
|
|
|
case 5:
|
|
|
|
level thread scene::play( fieldName, undefined, undefined, true );
|
|
break;
|
|
}
|
|
|
|
#/
|
|
}
|
|
|
|
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 ) )
|
|
{
|
|
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 is_igc()
|
|
{
|
|
return ( IsString( self.cameraswitcher )
|
|
|| IsString( self.extraCamSwitcher1 )
|
|
|| IsString( self.extraCamSwitcher2 )
|
|
|| IsString( self.extraCamSwitcher3 )
|
|
|| IsString( self.extraCamSwitcher4 ) );
|
|
}
|
|
|
|
function __main__()
|
|
{
|
|
wait 0.05; // wait for initialization stage to end so we can toggle client fields
|
|
|
|
/* RUN INSTANCES */
|
|
|
|
// util::waitforallclients();
|
|
|
|
if ( isdefined( level.disableFXAnimInSplitscreenCount ) )
|
|
{
|
|
if ( isdefined( level.localplayers ) )
|
|
{
|
|
if ( level.localplayers.size >= level.disableFXAnimInSplitscreenCount )
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
a_instances = ArrayCombine(
|
|
struct::get_array( "scriptbundle_scene", "classname" ),
|
|
struct::get_array( "scriptbundle_fxanim", "classname" ),
|
|
false, false
|
|
);
|
|
|
|
foreach ( s_instance in a_instances )
|
|
{
|
|
/* TODO: can we get these to work client side? The KVPs aren't currently available client side
|
|
if ( isdefined( s_instance.scriptgroup_initscenes ) )
|
|
{
|
|
trigs = GetEntArray( 0, s_instance.scriptgroup_initscenes, "scriptgroup_initscenes" );
|
|
if ( isdefined( trigs ) )
|
|
{
|
|
foreach ( trig in trigs )
|
|
{
|
|
s_instance thread _trigger_init( trig );
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( isdefined( s_instance.scriptgroup_playscenes ) )
|
|
{
|
|
trigs = GetEntArray( 0, s_instance.scriptgroup_playscenes, "scriptgroup_playscenes" );
|
|
if ( isdefined( trigs ) )
|
|
{
|
|
foreach ( trig in trigs )
|
|
{
|
|
s_instance thread _trigger_play( trig );
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( isdefined( s_instance.scriptgroup_stopscenes ) )
|
|
{
|
|
trigs = GetEntArray( 0, s_instance.scriptgroup_stopscenes, "scriptgroup_stopscenes" );
|
|
if ( isdefined( trigs ) )
|
|
{
|
|
foreach ( trig in trigs )
|
|
{
|
|
s_instance thread _trigger_stop( trig );
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
}
|
|
|
|
foreach ( s_instance in a_instances )
|
|
{
|
|
s_scenedef = struct::get_script_bundle( "scene", s_instance.scriptbundlename );
|
|
|
|
Assert( isdefined( s_scenedef ), "Scriptbundle @ " + s_instance.origin + " uses scriptbundle '" + s_instance.scriptbundlename + "' that doesn't exist." );
|
|
|
|
if ( s_scenedef.vmtype == "client" )
|
|
{
|
|
if ( isdefined( level.disableFxAnimByNameFunc ) && [[ level.disableFxAnimByNameFunc ]]( s_instance.scriptbundlename ) )
|
|
continue;
|
|
|
|
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( "entityshutdown" );
|
|
trig waittill( "trigger" );
|
|
_init_instance();
|
|
}
|
|
|
|
function _trigger_play( trig )
|
|
{
|
|
trig endon( "entityshutdown" );
|
|
|
|
do
|
|
{
|
|
trig waittill( "trigger" );
|
|
_play_instance();
|
|
}
|
|
while ( ( isdefined( get_scenedef( self.scriptbundlename ).looping ) && get_scenedef( self.scriptbundlename ).looping ) );
|
|
}
|
|
|
|
function _trigger_stop( trig )
|
|
{
|
|
trig endon( "entityshutdown" );
|
|
trig waittill( "trigger" );
|
|
_stop_instance();
|
|
}
|
|
|
|
/@
|
|
"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 ] = []; else if ( !IsArray( level.scene_funcs[ str_scenedef ][ str_state ] ) ) level.scene_funcs[ str_scenedef ][ str_state ] = array( level.scene_funcs[ str_scenedef ][ str_state ] ); level.scene_funcs[ str_scenedef ][ str_state ][level.scene_funcs[ str_scenedef ][ str_state ].size]=Array( func, vararg );;
|
|
}
|
|
|
|
/@
|
|
"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 );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/@
|
|
"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: [clientNum[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: [clientNum[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: [clientNum][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: [clientNum][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: [clientNum][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: [clientNum][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 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;
|
|
}
|
|
|
|
function _init_instance( str_scenedef, a_ents, b_test_run = false )
|
|
{
|
|
if(!isdefined(str_scenedef))str_scenedef=self.scriptbundlename;
|
|
|
|
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 ( isdefined( self.scriptbundlename ) && !b_test_run )
|
|
{
|
|
return o_scene;
|
|
}
|
|
|
|
thread [[o_scene]]->initialize( true );
|
|
}
|
|
else
|
|
{
|
|
o_scene = new cScene();
|
|
[[o_scene]]->init( str_scenedef, s_bundle, self, a_ents, b_test_run );
|
|
}
|
|
|
|
return o_scene;
|
|
}
|
|
|
|
/@
|
|
"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: [clientNum][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: [clientNum][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: [clientNum][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: [clientNum][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_mode = "" )
|
|
{
|
|
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, 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_mode );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( IsString( arg1 ) )
|
|
{
|
|
self thread _play_instance( s_tracker, arg1, arg2, b_test_run, str_mode );
|
|
}
|
|
else
|
|
{
|
|
self thread _play_instance( s_tracker, arg2, arg1, b_test_run, str_mode );
|
|
}
|
|
}
|
|
|
|
waittill_scene_done( s_tracker );
|
|
}
|
|
|
|
function private waittill_scene_done( s_tracker )
|
|
{
|
|
level endon("demo_jump"); // end when theater mode rewinds
|
|
|
|
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, str_mode )
|
|
{
|
|
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
|
|
{
|
|
str_scenedef = self.scriptbundlename;
|
|
|
|
// if ( !IS_TRUE( self.script_play_multiple ) )
|
|
// {
|
|
// if ( IS_TRUE( self.scene_played ) && !b_test_run )
|
|
// {
|
|
// waittillframeend;
|
|
// while ( is_playing( str_scenedef ) )
|
|
// {
|
|
// WAIT_SERVER_FRAME;
|
|
// }
|
|
//
|
|
// 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) )
|
|
{
|
|
thread [[o_scene]]->play( b_test_run, str_mode );
|
|
}
|
|
|
|
self waittill_instance_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;
|
|
}
|
|
}
|
|
|
|
s_tracker notify( "scene_done" );
|
|
}
|
|
|
|
function private waittill_instance_scene_done( str_scenedef )
|
|
{
|
|
level endon("demo_jump"); // end when theater mode rewinds
|
|
|
|
self waittillmatch( "scene_done", str_scenedef );
|
|
}
|
|
|
|
|
|
|
|
/@
|
|
"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, b_cancel, b_no_assert = false )
|
|
{
|
|
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( b_no_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, b_cancel );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( IsString( arg1 ) )
|
|
{
|
|
_stop_instance( arg2, arg1, b_cancel );
|
|
}
|
|
else
|
|
{
|
|
_stop_instance( arg1, arg2, b_cancel );
|
|
}
|
|
}
|
|
}
|
|
|
|
function _stop_instance( b_clear = false, str_scenedef, b_cancel = false )
|
|
{
|
|
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, b_cancel );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function cancel( arg1, arg2, arg3 )
|
|
{
|
|
stop( arg1, arg2, arg3, true );
|
|
}
|
|
|
|
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 actors 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;
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function is_capture_mode()
|
|
{
|
|
str_mode = GetDvarString( "scene_menu_mode", "default" );
|
|
|
|
if ( IsSubStr( str_mode, "capture" ) )
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|