#using scripts\codescripts\struct; #using scripts\shared\callbacks_shared; #using scripts\shared\clientfield_shared; #using scripts\shared\flag_shared; #using scripts\shared\flagsys_shared; #using scripts\shared\system_shared; #using scripts\shared\util_shared; #using scripts\shared\visionset_mgr_shared; #using scripts\shared\abilities\_ability_player; #using scripts\shared\abilities\_ability_power; #using scripts\shared\abilities\_ability_util; #namespace flashback; #precache( "fx", "player/fx_plyr_flashback_trail_impact" ); function autoexec __init__sytem__() { system::register("gadget_flashback",&__init__,undefined,undefined); } function __init__() { clientfield::register( "scriptmover", "flashback_trail_fx", 1, 1, "int" ); clientfield::register( "playercorpse", "flashback_clone" , 1, 1, "int" ); clientfield::register( "allplayers", "flashback_activated" , 1, 1, "int" ); ability_player::register_gadget_activation_callbacks( 16, &gadget_flashback_on, &gadget_flashback_off ); ability_player::register_gadget_possession_callbacks( 16, &gadget_flashback_on_give, &gadget_flashback_on_take ); ability_player::register_gadget_flicker_callbacks( 16, &gadget_flashback_on_flicker ); ability_player::register_gadget_is_inuse_callbacks( 16, &gadget_flashback_is_inuse ); ability_player::register_gadget_is_flickering_callbacks( 16, &gadget_flashback_is_flickering ); ability_player::register_gadget_primed_callbacks( 16, &gadget_flashback_is_primed ); callback::on_connect( &gadget_flashback_on_connect ); callback::on_spawned( &gadget_flashback_spawned ); if ( !IsDefined( level.vsmgr_prio_overlay_flashback_warp ) ) { level.vsmgr_prio_overlay_flashback_warp = 27; } visionset_mgr::register_info( "overlay", "flashback_warp", 1, level.vsmgr_prio_overlay_flashback_warp, 1, true, &visionset_mgr::ramp_in_out_thread_per_player_death_shutdown, false ); } function gadget_flashback_spawned() { self clientfield::set( "flashback_activated", 0 ); } function gadget_flashback_is_inuse( slot ) { // returns true when local script gadget state is on return self flagsys::get( "gadget_flashback_on" ); } function gadget_flashback_is_flickering( slot ) { // returns true when local script gadget state is flickering return self GadgetFlickering( slot ); } function gadget_flashback_on_flicker( slot, weapon ) { } function gadget_flashback_on_give( slot, weapon ) { // executed when gadget is added to the players inventory } function gadget_flashback_on_take( slot, weapon ) { // executed when gadget is removed from the players inventory } //self is the player function gadget_flashback_on_connect() { // setup up stuff on player connect } function clone_watch_death() { self endon ( "death" ); wait( 1.0 ); // do not delete the clones // player corpses should never get deleted self clientfield::set( "flashback_clone", 0 ); self ghost(); } /# function debug_star( origin, seconds, color ) { if ( !isdefined( seconds ) ) { seconds = 1; } if ( !isdefined( color ) ) { color = ( 1, 0, 0 ); } frames = Int( 20 * seconds ); DebugStar( origin, frames, color ); } #/ function drop_unlinked_grenades( linkedGrenades ) { waittillframeend; foreach( grenade in linkedGrenades ) { grenade launch( (RandomFloatRange( -5, 5 ),RandomFloatRange( -5, 5 ),5) ); } } function unlink_grenades( oldpos ) { radius = 32; origin = oldpos; grenades = getentarray( "grenade", "classname" ); radiusSq = radius * radius; linkedGrenades = []; foreach( grenade in grenades ) { if( DistanceSquared( origin, grenade.origin ) < radiusSq ) { if ( IsDefined( grenade.stuckToPlayer ) && ( grenade.stuckToPlayer == self ) ) { grenade unlink(); linkedGrenades[linkedGrenades.size] = grenade; } } } thread drop_unlinked_grenades( linkedGrenades ); } function gadget_flashback_on( slot, weapon ) { // excecutes when the gadget is turned on self flagsys::set( "gadget_flashback_on" ); self GadgetSetActivateTime( slot, GetTime() ); visionset_mgr::activate( "overlay", "flashback_warp", self, 0.8, 0.8 ); self.flashbackTime = GetTime(); self notify("flashback"); clone = self CreateFlashbackClone(); clone thread clone_watch_death(); clone clientfield::set( "flashback_clone", 1 ); self thread watchClientfields(); oldpos = self GetTagOrigin( "j_spineupper" ); offset = oldpos - self.origin; self unlink_grenades( oldpos ); newpos = self flashbackstart( weapon ) + offset; self NotSolid(); if ( isdefined ( newpos ) && isdefined ( oldpos ) ) { self thread flashbackTrailFx( slot, weapon, oldpos, newpos ); flashbackTrailImpact( newpos, oldpos, 8 ); flashbackTrailImpact( oldpos, newpos, 8 ); if ( isdefined( level.playGadgetSuccess ) ) { self [[ level.playGadgetSuccess ]]( weapon, "flashbackSuccessDelay" ); } } self thread deactivateFlashbackWarpAfterTime( 0.8 ); } function watchClientfields() { self endon ( "death" ); self endon ( "disconnect" ); util::wait_network_frame(); self clientfield::set( "flashback_activated", 1 ); util::wait_network_frame(); self clientfield::set( "flashback_activated", 0 ); } function flashBackTrailImpact( startPos, endPos, recursionDepth ) { recursionDepth--; if ( recursionDepth <= 0 ) { return; } trace = BulletTrace( startPos, endPos, false, self ); if ( trace[ "fraction" ] < 1.0 && trace[ "normal" ] != ( 0,0,0 ) ) { PlayFx( "player/fx_plyr_flashback_trail_impact", trace[ "position" ], trace[ "normal" ] ); newStartPos = trace[ "position" ] - trace[ "normal" ]; /# // debug_star( trace[ "position" ], 100 ); #/ flashBackTrailImpact( newStartPos, endPos, recursionDepth ); } } function deactivateFlashbackWarpAfterTime( time ) { self endon( "disconnect" ); self util::waittill_any_timeout( time, "death" ); visionset_mgr::deactivate( "overlay", "flashback_warp", self ); } function flashbackTrailFx( slot, weapon, oldpos, newPos ) { dirVec = newPos - oldPos; if ( dirVec == (0,0,0) ) { dirVec = (0,0,1); } dirVec = VectorNormalize( dirVec ); angles = VectorToAngles( dirVec ); fxOrg = spawn( "script_model", oldpos, 0, angles ); fxOrg.angles = angles; fxOrg setowner( self ); fxOrg SetModel( "tag_origin" ); fxOrg clientfield::set( "flashback_trail_fx", 1 ); util::wait_network_frame(); tagPos = self GetTagOrigin( "j_spineupper" ); fxOrg MoveTo( tagPos, 0.1 ); fxOrg waittill( "movedone" ); wait( 1 ); fxOrg clientfield::set( "flashback_trail_fx", 0 ); util::wait_network_frame(); fxOrg delete(); } function gadget_flashback_is_primed( slot, weapon ) { } function gadget_flashback_off( slot, weapon ) { // excecutes when the gadget is turned off self flagsys::clear( "gadget_flashback_on" ); self Solid(); self flashbackfinish(); if( level.gameEnded ) { self FreezeControls( true ); } }