408 lines
19 KiB
Plaintext
408 lines
19 KiB
Plaintext
#using scripts\shared\animation_debug_shared;
|
|
#using scripts\shared\clientfield_shared;
|
|
#using scripts\shared\flag_shared;
|
|
#using scripts\shared\flagsys_shared;
|
|
#using scripts\shared\postfx_shared;
|
|
#using scripts\shared\shaderanim_shared;
|
|
#using scripts\shared\system_shared;
|
|
|
|
|
|
|
|
|
|
#namespace animation;
|
|
|
|
|
|
|
|
function autoexec __init__sytem__() { system::register("animation",&__init__,undefined,undefined); }
|
|
|
|
function __init__()
|
|
{
|
|
clientfield::register( "scriptmover", "cracks_on", 1, GetMinBitCountForNum( 4 ), "int", &cf_cracks_on, !true, !true );
|
|
clientfield::register( "scriptmover", "cracks_off", 1, GetMinBitCountForNum( 4 ), "int", &cf_cracks_off, !true, !true );
|
|
|
|
setup_notetracks();
|
|
}
|
|
|
|
/@
|
|
"Name: first_frame( <ents>, <scene>, [str_tag], [animname_override] )"
|
|
"Summary: Puts the animating models or AI or vehicles into the first frame of the animated scene. The animation is played relative to the entity that calls the scene"
|
|
"Module: Animation"
|
|
"CallOn: The root entity that is the point of relativity for the scene, be it node, ai, vehicle, etc."
|
|
"MandatoryArg: <ents> Array of entities that will animate."
|
|
"MandatoryArg: <scene> The animation scene name."
|
|
"OptionalArg: [str_tag] The str_tag to animate relative to (must exist in the entity this function is called on)."
|
|
"OptionalArg: [animname_override] Animname to use instead of ent.animname"
|
|
"Example: node first_frame( guys, "rappel_sequence" );"
|
|
"SPMP: singleplayer"
|
|
@/
|
|
function first_frame( animation, v_origin_or_ent, v_angles_or_tag )
|
|
{
|
|
self thread play( animation, v_origin_or_ent, v_angles_or_tag, 0 );
|
|
}
|
|
|
|
function play( animation, v_origin_or_ent, v_angles_or_tag, n_rate = 1, n_blend_in = .2, n_blend_out = .2, n_lerp, b_link = false )
|
|
{
|
|
self endon( "entityshutdown" );
|
|
self thread _play( animation, v_origin_or_ent, v_angles_or_tag, n_rate, n_blend_in, n_blend_out, n_lerp, b_link );
|
|
self waittill( "scriptedanim" );
|
|
}
|
|
|
|
function _play( animation, v_origin_or_ent, v_angles_or_tag, n_rate = 1, n_blend_in = .2, n_blend_out = .2, n_lerp, b_link = false )
|
|
{
|
|
self endon( "entityshutdown" );
|
|
|
|
self notify( "new_scripted_anim" );
|
|
self endon( "new_scripted_anim" );
|
|
|
|
flagsys::set_val( "firstframe", n_rate == 0 );
|
|
flagsys::set( "scripted_anim_this_frame" );
|
|
flagsys::set( "scriptedanim" );
|
|
|
|
if(!isdefined(v_origin_or_ent))v_origin_or_ent=self;
|
|
|
|
if ( IsVec( v_origin_or_ent ) && IsVec( v_angles_or_tag ) )
|
|
{
|
|
self AnimScripted( "_anim_notify_", v_origin_or_ent, v_angles_or_tag, animation, n_blend_in, n_rate );
|
|
}
|
|
else
|
|
{
|
|
if ( IsString( v_angles_or_tag ) )
|
|
{
|
|
Assert( isdefined( v_origin_or_ent.model ), "Cannot align animation '" + animation + "' to tag '" + v_angles_or_tag + "' because the animation is not aligned to a model." );
|
|
|
|
v_pos = v_origin_or_ent GetTagOrigin( v_angles_or_tag );
|
|
v_ang = v_origin_or_ent GetTagAngles( v_angles_or_tag );
|
|
|
|
self.origin = v_pos;
|
|
self.angles = v_ang;
|
|
|
|
b_link = true;
|
|
|
|
// self LinkTo( v_origin_or_ent, v_angles_or_tag, ( 0, 0, 0 ), ( 0, 0, 0 ) ); // TODO: LinkTo with animation is broken client side and will mis-align the entities
|
|
self AnimScripted( "_anim_notify_", self.origin, self.angles, animation, n_blend_in, n_rate );
|
|
}
|
|
else
|
|
{
|
|
v_angles = ( isdefined( v_origin_or_ent.angles ) ? v_origin_or_ent.angles : ( 0, 0, 0 ) );
|
|
self AnimScripted( "_anim_notify_", v_origin_or_ent.origin, v_angles, animation, n_blend_in, n_rate );
|
|
}
|
|
}
|
|
|
|
if ( !b_link )
|
|
{
|
|
self Unlink();
|
|
}
|
|
|
|
/#
|
|
self thread anim_info_render_thread( animation, v_origin_or_ent, v_angles_or_tag, n_rate, n_blend_in, n_blend_out, n_lerp );
|
|
#/
|
|
|
|
// if ( !IsAnimLooping( animation ) && ( n_blend_out > 0 ) && ( n_rate > 0 ) )
|
|
// {
|
|
// self thread _blend_out( animation, n_blend_out, n_rate );
|
|
// }
|
|
|
|
self thread handle_notetracks();
|
|
|
|
self waittill_end();
|
|
|
|
if ( b_link )
|
|
{
|
|
self Unlink();
|
|
}
|
|
|
|
flagsys::clear( "scriptedanim" );
|
|
flagsys::clear( "firstframe" );
|
|
|
|
waittillframeend;
|
|
|
|
flagsys::clear( "scripted_anim_this_frame" );
|
|
}
|
|
|
|
function private waittill_end()
|
|
{
|
|
level endon("demo_jump"); // end when theater mode rewinds
|
|
|
|
self waittillmatch( "_anim_notify_", "end" );
|
|
}
|
|
|
|
//function _blend_out( animation, n_blend, n_rate )
|
|
//{
|
|
// self endon( "death" );
|
|
// self endon( "scriptedanim" );
|
|
//
|
|
// n_len = GetAnimLength( animation );
|
|
// n_wait = ( n_len - n_blend ) * ( 1 / n_rate );
|
|
//
|
|
// if ( n_wait > n_len )
|
|
// {
|
|
// wait n_wait;
|
|
//
|
|
// self StopAnimScripted( n_blend );
|
|
// }
|
|
//}
|
|
|
|
function _get_align_ent( e_align )
|
|
{
|
|
e = self;
|
|
if ( isdefined( e_align ) )
|
|
{
|
|
e = e_align;
|
|
}
|
|
|
|
if(!isdefined(e.angles))e.angles=( 0, 0, 0 );
|
|
return e;
|
|
}
|
|
|
|
function _get_align_pos( v_origin_or_ent, v_angles_or_tag )
|
|
{
|
|
if(!isdefined(v_origin_or_ent))v_origin_or_ent=self.origin;
|
|
if(!isdefined(v_angles_or_tag))v_angles_or_tag=(isdefined(self.angles)?self.angles:( 0, 0, 0 ));
|
|
|
|
s = SpawnStruct();
|
|
|
|
if ( IsVec( v_origin_or_ent ) )
|
|
{
|
|
Assert( IsVec( v_angles_or_tag ), "Angles must be a vector if origin is." );
|
|
|
|
s.origin = v_origin_or_ent;
|
|
s.angles = v_angles_or_tag;
|
|
}
|
|
else
|
|
{
|
|
e_align = _get_align_ent( v_origin_or_ent );
|
|
|
|
if ( IsString( v_angles_or_tag ) )
|
|
{
|
|
s.origin = e_align GetTagOrigin( v_angles_or_tag );
|
|
s.angles = e_align GetTagAngles( v_angles_or_tag );
|
|
}
|
|
else
|
|
{
|
|
s.origin = e_align.origin;
|
|
s.angles = e_align.angles;
|
|
}
|
|
}
|
|
|
|
if(!isdefined(s.angles))s.angles=( 0, 0, 0 );
|
|
|
|
return s;
|
|
}
|
|
|
|
function play_siege( str_anim, str_shot = "default", n_rate = 1, b_loop = false )
|
|
{
|
|
level endon("demo_jump"); // end when theater mode rewinds
|
|
self endon( "entityshutdown" );
|
|
|
|
if(!isdefined(str_shot))str_shot="default";
|
|
|
|
if ( n_rate == 0 )
|
|
{
|
|
self SiegeCmd( "set_anim", str_anim, "set_shot", str_shot, "pause", "goto_start" );
|
|
}
|
|
else
|
|
{
|
|
self SiegeCmd( "set_anim", str_anim, "set_shot", str_shot, "unpause", "set_playback_speed", n_rate, "send_end_events", true, ( b_loop ? "loop" : "unloop" ) );
|
|
}
|
|
|
|
self waittill( "end" );
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Notetrack Handling
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
function add_notetrack_func( funcname, func )
|
|
{
|
|
if(!isdefined(level._animnotifyfuncs))level._animnotifyfuncs=[];
|
|
|
|
Assert( !isdefined( level._animnotifyfuncs[ funcname ] ), "Notetrack function already exists." );
|
|
|
|
level._animnotifyfuncs[ funcname ] = func;
|
|
}
|
|
|
|
function add_global_notetrack_handler( str_note, func, ... )
|
|
{
|
|
if(!isdefined(level._animnotetrackhandlers))level._animnotetrackhandlers=[];
|
|
if(!isdefined(level._animnotetrackhandlers[ str_note ]))level._animnotetrackhandlers[ str_note ]=[];
|
|
|
|
if ( !isdefined( level._animnotetrackhandlers[ str_note ] ) ) level._animnotetrackhandlers[ str_note ] = []; else if ( !IsArray( level._animnotetrackhandlers[ str_note ] ) ) level._animnotetrackhandlers[ str_note ] = array( level._animnotetrackhandlers[ str_note ] ); level._animnotetrackhandlers[ str_note ][level._animnotetrackhandlers[ str_note ].size]=array( func, vararg );;
|
|
}
|
|
|
|
function call_notetrack_handler( str_note )
|
|
{
|
|
if ( isdefined( level._animnotetrackhandlers ) && isdefined( level._animnotetrackhandlers[ str_note ] ) )
|
|
{
|
|
foreach ( handler in level._animnotetrackhandlers[ str_note ] )
|
|
{
|
|
func = handler[0];
|
|
args = handler[1];
|
|
|
|
switch ( args.size )
|
|
{
|
|
case 6:
|
|
self [[ func ]]( args[0], args[1], args[2], args[3], args[4], args[5] );
|
|
break;
|
|
case 5:
|
|
self [[ func ]]( args[0], args[1], args[2], args[3], args[4] );
|
|
break;
|
|
case 4:
|
|
self [[ func ]]( args[0], args[1], args[2], args[3] );
|
|
break;
|
|
case 3:
|
|
self [[ func ]]( args[0], args[1], args[2] );
|
|
break;
|
|
case 2:
|
|
self [[ func ]]( args[0], args[1] );
|
|
break;
|
|
case 1:
|
|
self [[ func ]]( args[0] );
|
|
break;
|
|
case 0:
|
|
self [[ func ]]();
|
|
break;
|
|
default: AssertMsg( "Too many args passed to notetrack handler." );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function setup_notetracks()
|
|
{
|
|
add_notetrack_func( "flag::set", &flag::set );
|
|
add_notetrack_func( "flag::clear", &flag::clear );
|
|
|
|
add_notetrack_func( "postfx::PlayPostFxBundle", &postfx::PlayPostFxBundle );
|
|
add_notetrack_func( "postfx::StopPostFxBundle", &postfx::StopPostFxBundle );
|
|
|
|
add_global_notetrack_handler( "red_cracks_on", &cracks_on, "red" );
|
|
add_global_notetrack_handler( "green_cracks_on", &cracks_on, "green" );
|
|
add_global_notetrack_handler( "blue_cracks_on", &cracks_on, "blue" );
|
|
add_global_notetrack_handler( "all_cracks_on", &cracks_on, "all" );
|
|
|
|
add_global_notetrack_handler( "red_cracks_off", &cracks_off, "red" );
|
|
add_global_notetrack_handler( "green_cracks_off", &cracks_off, "green" );
|
|
add_global_notetrack_handler( "blue_cracks_off", &cracks_off, "blue" );
|
|
add_global_notetrack_handler( "all_cracks_off", &cracks_off, "all" );
|
|
}
|
|
|
|
function handle_notetracks()
|
|
{
|
|
level endon("demo_jump"); // end when theater mode rewinds
|
|
self endon( "entityshutdown" );
|
|
|
|
while ( true )
|
|
{
|
|
self waittill( "_anim_notify_", str_note );
|
|
|
|
if ( str_note != "end" && str_note != "loop_end" )
|
|
{
|
|
self thread call_notetrack_handler( str_note );
|
|
}
|
|
else
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function cracks_on( str_type )
|
|
{
|
|
switch ( str_type )
|
|
{
|
|
case "red":
|
|
cf_cracks_on( self.localClientNum, 0, 1 );
|
|
break;
|
|
case "green":
|
|
cf_cracks_on( self.localClientNum, 0, 3 );
|
|
break;
|
|
case "blue":
|
|
cf_cracks_on( self.localClientNum, 0, 2 );
|
|
break;
|
|
case "all":
|
|
cf_cracks_on( self.localClientNum, 0, 4 );
|
|
break;
|
|
}
|
|
}
|
|
|
|
function cracks_off( str_type )
|
|
{
|
|
switch ( str_type )
|
|
{
|
|
case "red":
|
|
cf_cracks_off( self.localClientNum, 0, 1 );
|
|
break;
|
|
case "green":
|
|
cf_cracks_off( self.localClientNum, 0, 3 );
|
|
break;
|
|
case "blue":
|
|
cf_cracks_off( self.localClientNum, 0, 2 );
|
|
break;
|
|
case "all":
|
|
cf_cracks_off( self.localClientNum, 0, 4 );
|
|
break;
|
|
}
|
|
}
|
|
|
|
function cf_cracks_on( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
|
|
{
|
|
const delay = 0;
|
|
const duration = 3;
|
|
const start = 0;
|
|
const end = 1;
|
|
|
|
switch ( newVal )
|
|
{
|
|
case 1:
|
|
shaderanim::animate_crack( localClientNum, "scriptVector1", delay, duration, start, end );
|
|
break;
|
|
case 3:
|
|
shaderanim::animate_crack( localClientNum, "scriptVector2", delay, duration, start, end );
|
|
break;
|
|
case 2:
|
|
shaderanim::animate_crack( localClientNum, "scriptVector3", delay, duration, start, end );
|
|
break;
|
|
case 4:
|
|
shaderanim::animate_crack( localClientNum, "scriptVector1", delay, duration, start, end );
|
|
shaderanim::animate_crack( localClientNum, "scriptVector2", delay, duration, start, end );
|
|
shaderanim::animate_crack( localClientNum, "scriptVector3", delay, duration, start, end );
|
|
}
|
|
}
|
|
|
|
function cf_cracks_off( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
|
|
{
|
|
const delay = 0;
|
|
const duration = 0;
|
|
const start = 1;
|
|
const end = 0;
|
|
|
|
switch ( newVal )
|
|
{
|
|
case 1:
|
|
shaderanim::animate_crack( localClientNum, "scriptVector1", delay, duration, start, end );
|
|
break;
|
|
case 3:
|
|
shaderanim::animate_crack( localClientNum, "scriptVector2", delay, duration, start, end );
|
|
break;
|
|
case 2:
|
|
shaderanim::animate_crack( localClientNum, "scriptVector3", delay, duration, start, end );
|
|
break;
|
|
case 4:
|
|
shaderanim::animate_crack( localClientNum, "scriptVector1", delay, duration, start, end );
|
|
shaderanim::animate_crack( localClientNum, "scriptVector2", delay, duration, start, end );
|
|
shaderanim::animate_crack( localClientNum, "scriptVector3", delay, duration, start, end );
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// !Notetrack Handling
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|