//checked includes match cerberus output #include maps/mp/killstreaks/_supplydrop; #include maps/mp/gametypes/_gameobjects; #include maps/mp/gametypes/ctf; #include maps/mp/gametypes/_weaponobjects; #include maps/mp/killstreaks/_rcbomb; #include maps/mp/_tacticalinsertion; #include common_scripts/utility; #include maps/mp/_utility; init() //checked partially changed to match cerberus output see info.md { precachemodel( "p6_dockside_container_lrg_white" ); crane_dvar_init(); level.crate_models = []; level.crate_models[ 0 ] = "p6_dockside_container_lrg_red"; level.crate_models[ 1 ] = "p6_dockside_container_lrg_blue"; level.crate_models[ 2 ] = "p6_dockside_container_lrg_white"; level.crate_models[ 3 ] = "p6_dockside_container_lrg_orange"; claw = getent( "claw_base", "targetname" ); claw.z_upper = claw.origin[ 2 ]; claw thread sound_wires_move(); arms_y = getentarray( "claw_arm_y", "targetname" ); arms_z = getentarray( "claw_arm_z", "targetname" ); claw.arms = arraycombine( arms_y, arms_z, 1, 0 ); foreach ( arm_z in arms_z ) { arm_y = getclosest( arm_z.origin, arms_y ); arm_z.parent = arm_y; } foreach ( arm_y in arms_y ) { arm_y.parent = claw; } claw claw_link_arms( "claw_arm_y" ); claw claw_link_arms( "claw_arm_z" ); crates = getentarray( "crate", "targetname" ); array_thread( crates, ::sound_pit_move ); crate_data = []; for ( i = 0; i < crates.size; i++ ) { crates[ i ] disconnectpaths(); data = spawnstruct(); data.origin = crates[ i ].origin; data.angles = crates[ i ].angles; crate_data[ i ] = data; } rail = getent( "crane_rail", "targetname" ); rail thread sound_ring_move(); rail.roller = getent( "crane_roller", "targetname" ); rail.roller.wheel = getent( "crane_wheel", "targetname" ); claw.wires = getentarray( "crane_wire", "targetname" ); claw.z_wire_max = rail.roller.wheel.origin[ 2 ] - 50; foreach ( wire in claw.wires ) { wire linkto( claw ); if ( wire.origin[ 2 ] > claw.z_wire_max ) { wire ghost(); } } placements = getentarray( "crate_placement", "targetname" ); foreach ( placement in placements ) { placement.angles += vectorScale( ( 0, 1, 0 ), 90 ); crates[ crates.size ] = spawn( "script_model", placement.origin ); } triggers = getentarray( "crate_kill_trigger", "targetname" ); foreach ( crate in crates ) { crate.kill_trigger = getclosest( crate.origin, triggers ); crate.kill_trigger.origin = crate.origin - vectorScale( ( 0, 0, 1 ), 5 ); crate.kill_trigger enablelinkto(); crate.kill_trigger linkto( crate ); if ( crate.model != "" ) { crate.kill_trigger.active = 1; } else { crate.kill_trigger.active = 0; } } trigger = getclosest( claw.origin, triggers ); trigger enablelinkto(); trigger linkto( claw ); trigger.active = 1; placements = array_randomize( placements ); level thread crane_think( claw, rail, crates, crate_data, placements ); } crane_dvar_init() //checked matches cerberus output { set_dvar_float_if_unset( "scr_crane_claw_move_time", "5" ); set_dvar_float_if_unset( "scr_crane_crate_lower_time", "5" ); set_dvar_float_if_unset( "scr_crane_crate_raise_time", "5" ); set_dvar_float_if_unset( "scr_crane_arm_y_move_time", "3" ); set_dvar_float_if_unset( "scr_crane_arm_z_move_time", "3" ); set_dvar_float_if_unset( "scr_crane_claw_drop_speed", "25" ); set_dvar_float_if_unset( "scr_crane_claw_drop_time_min", "5" ); } wire_render() //checked partially changed to match cerberus output see info.md { self endon( "movedone" ); for ( ;; ) { wait 0.05; foreach ( wire in self.wires ) { if ( wire.origin[ 2 ] > self.z_wire_max ) { wire ghost(); } else { wire show(); } } } } crane_think( claw, rail, crates, crate_data, placements ) //checked changed to match beta dump { wait 1; claw arms_open(); for ( ;; ) { for ( i = 0; i < crates.size - placements.size; i++ ) { crate = getclosest( crate_data[ i ].origin, crates ); rail crane_move( claw, crate_data[ i ], -318 ); level notify( "wires_move" ); claw claw_crate_grab( crate, 318 ); lower = 1; target = ( i + 1 ) % ( crates.size - placements.size ); target_crate = getclosest( crate_data[ target ].origin, crates ); if ( cointoss() ) { for ( placement_index = 0; placement_index < placements.size; placement_index++ ) { placement = placements[ placement_index ]; if ( !isDefined( placement.crate ) ) { lower = 0; break; } } } if ( !lower ) { z_dist = crate.origin[ 2 ] - placement.origin[ 2 ] - 33; rail crane_move( claw, placement, z_dist * -1 ); level notify( "wires_move" ); placement.crate = crate; } else { rail crane_move( claw, crate_data[ target ], -181 ); level notify( "wires_move" ); } claw claw_crate_move( crate ); if ( lower ) { crate crate_lower( target_crate, crate_data[ target ] ); } crate = target_crate; target = ( i + 2 ) % ( crates.size - placements.size ); target_crate = getclosest( crate_data[ target ].origin, crates ); if ( !lower ) { crate = crates[ 3 + placement_index ]; crate.origin = target_crate.origin - vectorScale( ( 0, 0, 1 ), 137 ); crate.angles = target_crate.angles; wait 0.25; claw waittill( "movedone" ); } crate crate_raise( target_crate, crate_data[ target ] ); rail crane_move( claw, crate_data[ target ], -181 ); level notify( "wires_move" ); claw claw_crate_grab( target_crate, 181 ); crate = target_crate; target = ( i + 3 ) % ( crates.size - placements.size ); rail crane_move( claw, crate_data[ target ], -318 ); level notify( "wires_move" ); claw claw_crate_drop( crate, crate_data[ target ] ); } } } crane_move( claw, desired, z_dist ) //checked changed to match cerberus output dvars taken from beta dump { self.roller linkto( self ); self.roller.wheel linkto( self.roller ); claw linkto( self.roller.wheel ); goal = ( desired.origin[ 0 ], desired.origin[ 1 ], self.origin[ 2 ] ); dir = vectornormalize( goal - self.origin ); angles = vectorToAngle( dir ); angles = ( self.angles[ 0 ], angles[ 1 ] + 90, self.angles[ 2 ] ); yawdiff = absangleclamp360( self.angles[ 1 ] - angles[ 1 ] ); time = yawdiff / 25; self rotateto( angles, time, time * 0.35, time * 0.45 ); self thread physics_move(); level notify( "wires_stop" ); level notify( "ring_move" ); self waittill( "rotatedone" ); self.roller unlink(); goal = ( desired.origin[ 0 ], desired.origin[ 1 ], self.roller.origin[ 2 ] ); diff = distance2d( goal, self.roller.origin ); speed = getDvarFloat( "scr_crane_claw_drop_speed" ); time = diff / speed; if ( time < getDvarFloat( "scr_crane_claw_drop_time_min" ) ) { time = getDvarFloat( "scr_crane_claw_drop_time_min" ); } self.roller moveto( goal, time, time * 0.25, time * 0.25 ); self.roller thread physics_move(); goal = ( desired.origin[ 0 ], desired.origin[ 1 ], self.roller.wheel.origin[ 2 ] ); self.roller.wheel unlink(); self.roller.wheel moveto( goal, time, time * 0.25, time * 0.25 ); self.roller.wheel rotateto( desired.angles + vectorScale( ( 0, 1, 0 ), 90 ), time, time * 0.25, time * 0.25 ); claw.z_initial = claw.origin[ 2 ]; claw unlink(); claw rotateto( desired.angles, time, time * 0.25, time * 0.25 ); claw.goal = ( goal[ 0 ], goal[ 1 ], claw.origin[ 2 ] + z_dist ); claw.time = time; claw moveto( claw.goal, time, time * 0.25, time * 0.25 ); level notify( "ring_stop" ); } physics_move() //checked changed to match cerberus output { self endon( "rotatedone" ); self endon( "movedone" ); for ( ;; ) { wait 0.05; crates = getentarray( "care_package", "script_noteworthy" ); foreach ( crate in crates ) { if ( crate istouching( self ) ) { crate physicslaunch( crate.origin, ( 0, 0, 0 ) ); } } } } claw_crate_grab( crate, z_dist ) //checked matches cerberus output dvars taken from beta dump { self thread wire_render(); self waittill( "movedone" ); level notify( "wires_stop" ); self playsound( "amb_crane_arms_b" ); self claw_z_arms( -33 ); self playsound( "amb_crane_arms" ); self arms_close( crate ); crate movez( 33, getDvarFloat( "scr_crane_arm_z_move_time" ) ); self claw_z_arms( 33 ); crate linkto( self ); self movez( z_dist, getDvarFloat( "scr_crane_claw_move_time" ) ); self thread wire_render(); level notify( "wires_move" ); self waittill( "movedone" ); self playsound( "amb_crane_arms" ); } sound_wires_move() //checked matches cerberus output { while ( 1 ) { level waittill( "wires_move" ); self playsound( "amb_crane_wire_start" ); self playloopsound( "amb_crane_wire_lp" ); level waittill( "wires_stop" ); self playsound( "amb_crane_wire_end" ); wait 0.1; self stoploopsound( 0.2 ); } } sound_ring_move() //checked matches cerberus output { while ( 1 ) { level waittill( "ring_move" ); self playsound( "amb_crane_ring_start" ); self playloopsound( "amb_crane_ring_lp" ); level waittill( "ring_stop" ); self playsound( "amb_crane_ring_end" ); wait 0.1; self stoploopsound( 0.2 ); } } sound_pit_move() //checked matches cerberus output { while ( 1 ) { level waittill( "pit_move" ); self playsound( "amb_crane_pit_start" ); self playloopsound( "amb_crane_pit_lp" ); level waittill( "pit_stop" ); self playsound( "amb_crane_pit_end" ); self stoploopsound( 0.2 ); wait 0.2; } } claw_crate_move( crate, claw ) //checked matches cerberus output dvars taken from beta dump { self thread wire_render(); self waittill( "movedone" ); crate unlink(); self playsound( "amb_crane_arms_b" ); level notify( "wires_stop" ); crate movez( -33, getDvarFloat( "scr_crane_arm_z_move_time" ) ); self claw_z_arms( -33 ); self playsound( "amb_crane_arms_b" ); playfxontag( level._effect[ "crane_dust" ], crate, "tag_origin" ); crate playsound( "amb_crate_drop" ); self arms_open(); level notify( "wires_move" ); self claw_z_arms( 33 ); z_dist = self.z_initial - self.origin[ 2 ]; self movez( z_dist, getDvarFloat( "scr_crane_claw_move_time" ) ); self thread wire_render(); } claw_crate_drop( target, data ) //checked matches cerberus output dvars taken from beta dump { target thread crate_drop_think( self ); self thread wire_render(); self waittill( "claw_movedone" ); target unlink(); level notify( "wires_stop" ); self playsound( "amb_crane_arms_b" ); target movez( -33, getDvarFloat( "scr_crane_arm_z_move_time" ) ); self claw_z_arms( -33 ); playfxontag( level._effect[ "crane_dust" ], target, "tag_origin" ); self playsound( "amb_crate_drop" ); target notify( "claw_done" ); self playsound( "amb_crane_arms" ); self arms_open(); level notify( "wires_move" ); target.origin = data.origin; self claw_z_arms( 33 ); self playsound( "amb_crane_arms" ); self movez( 318, getDvarFloat( "scr_crane_claw_move_time" ) ); self thread wire_render(); self waittill( "movedone" ); } crate_lower( lower, data ) //checked matches cerberus output { z_dist = abs( self.origin[ 2 ] - lower.origin[ 2 ] ); self movez( z_dist * -1, getDvarFloat( "scr_crane_crate_lower_time" ) ); lower movez( z_dist * -1, getDvarFloat( "scr_crane_crate_lower_time" ) ); level notify( "pit_move" ); lower waittill( "movedone" ); level notify( "pit_stop" ); lower ghost(); self.origin = data.origin; wait 0.25; } crate_raise( upper, data ) //checked matches cerberus output dvars taken from beta dump { self crate_set_random_model( upper ); self.kill_trigger.active = 1; self.origin = ( data.origin[ 0 ], data.origin[ 1 ], self.origin[ 2 ] ); self.angles = data.angles; wait 0.2; self show(); z_dist = abs( upper.origin[ 2 ] - self.origin[ 2 ] ); self movez( z_dist, getDvarFloat( "scr_crane_crate_raise_time" ) ); upper movez( z_dist, getDvarFloat( "scr_crane_crate_raise_time" ) ); level notify( "wires_stop" ); level notify( "pit_move" ); upper thread raise_think(); } raise_think() //checked matches cerberus output { self waittill( "movedone" ); level notify( "pit_stop" ); } crate_set_random_model( other ) //checked partially changed to match cerberus output see info.md { models = array_randomize( level.crate_models ); foreach ( model in models ) { if ( model == other.model ) { } else { self setmodel( model ); return; } } } arms_open() //checked matches cerberus output { self claw_move_arms( -15 ); self playsound( "amb_crane_arms" ); } arms_close( crate ) //checked matches cerberus output { self claw_move_arms( 15, crate ); self playsound( "amb_crane_arms" ); } claw_link_arms( name ) //checked changed to match cerberus output { foreach ( arm in self.arms ) { if ( arm.targetname == name ) { arm linkto( arm.parent ); } } } claw_unlink_arms( name ) //checked changed to match cerberus output { foreach ( arm in self.arms ) { if ( arm.targetname == name ) { arm unlink(); } } } claw_move_arms( dist, crate ) //checked changed to match cerberus output dvars taken from beta dump { claw_unlink_arms( "claw_arm_y" ); arms = []; foreach ( arm in self.arms ) { forward = anglesToForward( arm.angles ); arm.goal = arm.origin + vectorScale( forward, dist ); if ( arm.targetname == "claw_arm_y" ) { arms[ arms.size ] = arm; arm moveto( arm.goal, getDvarFloat( "scr_crane_arm_y_move_time" ) ); } } if ( dist > 0 ) { wait( getDvarFloat( "scr_crane_arm_y_move_time" ) / 2 ); foreach ( arm in self.arms ) { if ( arm.targetname == "claw_arm_y" ) { arm moveto( arm.goal, 0.1 ); self playsound( "amb_crane_arms_b" ); } } wait 0.05; playfxontag( level._effect[ "crane_spark" ], crate, "tag_origin" ); self playsound( "amb_arms_latch" ); } /* /# assert( arms.size == 4 ); #/ */ waittill_multiple_ents( arms[ 0 ], "movedone", arms[ 1 ], "movedone", arms[ 2 ], "movedone", arms[ 3 ], "movedone" ); foreach ( arm in self.arms ) { arm.origin = arm.goal; } self claw_link_arms( "claw_arm_y" ); } claw_z_arms( z ) //checked changed to match cerberus output dvars taken from beta dump { claw_unlink_arms( "claw_arm_z" ); arms = []; foreach ( arm in self.arms ) { if ( arm.targetname == "claw_arm_z" ) { arms[ arms.size ] = arm; arm movez( z, getDvarFloat( "scr_crane_arm_z_move_time" ) ); } } /* /# assert( arms.size == 4 ); #/ */ waittill_multiple_ents( arms[ 0 ], "movedone", arms[ 1 ], "movedone", arms[ 2 ], "movedone", arms[ 3 ], "movedone" ); self claw_link_arms( "claw_arm_z" ); } crate_drop_think( claw ) //checked changed at own discretion see info.md { self endon( "claw_done" ); self.disablefinalkillcam = 1; claw thread claw_drop_think(); corpse_delay = 0; for ( ;; ) { wait 0.2; entities = getdamageableentarray( self.origin, 200 ); i = 0; while ( i < entities.size ) { if ( !entities[ i ] istouching( self.kill_trigger ) ) { i++; continue; } if ( isDefined( entities[ i ].model ) && entities[ i ].model == "t6_wpn_tac_insert_world" ) { entities[ i ] maps/mp/_tacticalinsertion::destroy_tactical_insertion(); i++; continue; } if ( !isalive( entities[ i ] ) ) { i++; continue; } if ( isDefined( entities[ i ].targetname ) ) { if ( entities[ i ].targetname == "talon" ) { entities[ i ] notify( "death" ); i++; continue; } if ( entities[ i ].targetname == "rcbomb" ) { entities[ i ] maps/mp/killstreaks/_rcbomb::rcbomb_force_explode(); i++; continue; } if ( entities[ i ].targetname == "riotshield_mp" ) { entities[ i ] dodamage( 1, self.origin + ( 0, 0, 1 ), self, self, 0, "MOD_CRUSH" ); i++; continue; } } if ( isDefined( entities[ i ].helitype ) && entities[ i ].helitype == "qrdrone" ) { watcher = entities[ i ].owner maps/mp/gametypes/_weaponobjects::getweaponobjectwatcher( "qrdrone" ); watcher thread maps/mp/gametypes/_weaponobjects::waitanddetonate( entities[ i ], 0, undefined ); i++; continue; } if ( entities[ i ].classname == "grenade" ) { if ( !isDefined( entities[ i ].name ) ) { i++; continue; } if ( !isDefined( entities[ i ].owner ) ) { i++; continue; } if ( entities[ i ].name == "proximity_grenade_mp" ) { watcher = entities[ i ].owner getwatcherforweapon( entities[ i ].name ); watcher thread maps/mp/gametypes/_weaponobjects::waitanddetonate( entities[ i ], 0, undefined, "script_mover_mp" ); i++; continue; } if ( !isweaponequipment( entities[ i ].name ) ) { i++; continue; } watcher = entities[ i ].owner getwatcherforweapon( entities[ i ].name ); if ( !isDefined( watcher ) ) { i++; continue; } watcher thread maps/mp/gametypes/_weaponobjects::waitanddetonate( entities[ i ], 0, undefined, "script_mover_mp" ); i++; continue; } if ( entities[ i ].classname == "auto_turret" ) { if ( !isDefined( entities[ i ].damagedtodeath ) || !entities[ i ].damagedtodeath ) { entities[ i ] domaxdamage( self.origin + ( 0, 0, 1 ), self, self, 0, "MOD_CRUSH" ); } i++; continue; } entities[ i ] dodamage( entities[ i ].health * 2, self.origin + ( 0, 0, 1 ), self, self, 0, "MOD_CRUSH" ); if ( isplayer( entities[ i ] ) ) { claw thread claw_drop_pause(); corpse_delay = getTime() + 3000; } i++; } self destroy_supply_crates(); if ( getTime() > corpse_delay ) { self destroy_corpses(); } if ( level.gametype == "ctf" ) { foreach ( flag in level.flags ) { if ( flag.visuals[ 0 ] istouching( self.kill_trigger ) ) { flag maps/mp/gametypes/ctf::returnflag(); } } } else if ( level.gametype == "sd" && !level.multibomb ) { if ( level.sdbomb.visuals[ 0 ] istouching( self.kill_trigger ) ) { level.sdbomb maps/mp/gametypes/_gameobjects::returnhome(); } } } } claw_drop_think() //checked matches cerberus output { self endon( "claw_pause" ); self waittill( "movedone" ); self notify( "claw_movedone" ); } claw_drop_pause() //checked matches cerberus output { self notify( "claw_pause" ); self endon( "claw_pause" ); z_diff = abs( self.goal[ 2 ] - self.origin[ 2 ] ); frac = z_diff / 318; time = self.time * frac; if ( time <= 0 ) { return; } self moveto( self.origin, 0.01 ); wait 3; self thread claw_drop_think(); self moveto( self.goal, time ); } destroy_supply_crates() //checked changed to match cerberus output { crates = getentarray( "care_package", "script_noteworthy" ); foreach ( crate in crates ) { if ( distancesquared( crate.origin, self.origin ) < 40000 ) { if ( crate istouching( self ) ) { playfx( level._supply_drop_explosion_fx, crate.origin ); playsoundatposition( "wpn_grenade_explode", crate.origin ); wait 0.1; crate maps/mp/killstreaks/_supplydrop::cratedelete(); } } } } destroy_corpses() //checked changed to match cerberus output { corpses = getcorpsearray(); for ( i = 0; i < corpses.size; i++ ) { if ( distancesquared( corpses[ i ].origin, self.origin ) < 40000 ) { corpses[ i ] delete(); } } } getwatcherforweapon( weapname ) //checked partially changed to match cerberus output see info.md { if ( !isDefined( self ) ) { return undefined; } if ( !isplayer( self ) ) { return undefined; } i = 0; while ( i < self.weaponobjectwatcherarray.size ) { if ( self.weaponobjectwatcherarray[ i ].weapon != weapname ) { i++; continue; } return self.weaponobjectwatcherarray[ i ]; i++; } return undefined; }