391 lines
9.5 KiB
Plaintext
391 lines
9.5 KiB
Plaintext
#include maps\mp\_utility;
|
|
#include common_scripts\utility;
|
|
|
|
main()
|
|
{
|
|
maps\mp\mp_chasm_precache::main();
|
|
maps\createart\mp_chasm_art::main();
|
|
maps\mp\mp_chasm_fx::main();
|
|
|
|
level thread maps\mp\_movers::main();
|
|
maps\mp\_movers::script_mover_add_parameters("falling_elevator", "delay_till_trigger=1");
|
|
maps\mp\_movers::script_mover_add_parameters("falling_elevator_cables", "delay_till_trigger=1");
|
|
maps\mp\_movers::script_mover_add_parameters("elevator_drop_1", "move_time=.7;accel_time=.7");
|
|
maps\mp\_movers::script_mover_add_parameters("elevator_drop_2", "move_time=1.2;accel_time=1.2;name=elevator_end");
|
|
|
|
maps\mp\_load::main();
|
|
thread maps\mp\_fx::func_glass_handler();
|
|
|
|
maps\mp\_compass::setupMiniMap( "compass_map_mp_chasm" );
|
|
|
|
setdvar( "r_lightGridEnableTweaks", 1 );
|
|
setdvar( "r_lightGridIntensity", 1.33 );
|
|
// dvar_name current_gen_val next_gen_val
|
|
setdvar_cg_ng( "r_specularColorScale", 2.5 , 5 );
|
|
|
|
game["attackers"] = "allies";
|
|
game["defenders"] = "axis";
|
|
|
|
if ( level.gametype == "sd"
|
|
|| level.gameType == "sr" )
|
|
{
|
|
level.srKillCamOverridePosition = [];
|
|
level.srKillCamOverridePosition["_b"] = (384, 278, 1716);
|
|
}
|
|
|
|
level thread falling_elevator();
|
|
level thread setupBus();
|
|
level thread initExtraCollision();
|
|
}
|
|
|
|
initExtraCollision()
|
|
{
|
|
gryphonTrig1Ent = spawn( "trigger_radius", (-2304, -3072, 512), 0, 1024, 2048 );
|
|
gryphonTrig1Ent.radius = 1024;
|
|
gryphonTrig1Ent.height = 2048;
|
|
gryphonTrig1Ent.angles = (0,0,0);
|
|
gryphonTrig1Ent.targetname = "remote_heli_range";
|
|
|
|
collision1 = GetEnt( "clip256x256x8", "targetname" );
|
|
collision1Ent = spawn( "script_model", (-1216, 2112, 1376) );
|
|
collision1Ent.angles = ( 0, 0, 0);
|
|
collision1Ent CloneBrushmodelToScriptmodel( collision1 );
|
|
|
|
placeableBarrier = spawn( "script_model", (-2304, -936, 1492) );
|
|
placeableBarrier setModel( "placeable_barrier" );
|
|
placeableBarrier.angles = (0,0,12);
|
|
|
|
collision2 = GetEnt( "clip32x32x32", "targetname" );
|
|
collision2Ent = spawn( "script_model", (-1438, -1424, 1030) );
|
|
collision2Ent.angles = ( 0, 0, 0);
|
|
collision2Ent CloneBrushmodelToScriptmodel( collision2 );
|
|
}
|
|
|
|
BUS_FALL_DELAY = 1.0;
|
|
setupBus()
|
|
{
|
|
bus = GetEnt( "falling_bus", "targetname" );
|
|
busCol = GetEnt( "bus_collision", "targetname" );
|
|
bus.collision = busCol;
|
|
|
|
busInterior = GetEntArray( "falling_bus_parts", "targetname" );
|
|
|
|
foreach ( item in busInterior )
|
|
{
|
|
item LinkTo( bus );
|
|
}
|
|
bus.unresolved_collision_func = maps\mp\_movers::unresolved_collision_void;
|
|
|
|
bus thread explosive_damage_watch( bus, "bus_start_fall" );
|
|
if ( IsDefined( busCol ) )
|
|
{
|
|
busCol LinkTo( bus );
|
|
bus thread explosive_damage_watch( busCol, "bus_start_fall" );
|
|
}
|
|
|
|
// get the positions
|
|
ent = bus;
|
|
ent.keyframes = [];
|
|
keyframeName = ent.target;
|
|
i = 0;
|
|
while ( IsDefined( keyframeName ) )
|
|
{
|
|
struct = getstruct( keyframeName, "targetname" );
|
|
if ( IsDefined( struct ) )
|
|
{
|
|
ent.keyframes[i] = struct;
|
|
|
|
i++;
|
|
keyframeName = struct.target;
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( ent.keyframes.size > 2 )
|
|
{
|
|
// !!! this is also a hack, but a quick way to tune
|
|
// start falling
|
|
ent.keyframes[1].script_duration = 0.75;
|
|
ent.keyframes[1].script_accel = 0.75;
|
|
ent.keyframes[1].script_decel = 0;
|
|
ent.keyframes[1].shakeMag = .5;
|
|
ent.keyframes[1].shakeDuration = 1.5;
|
|
ent.keyframes[1].shakeDistance = 1000;
|
|
|
|
// tip over the edge
|
|
ent.keyframes[2].script_duration = 4.0;
|
|
ent.keyframes[2].script_accel = 0.0;
|
|
ent.keyframes[2].script_decel = 0;
|
|
}
|
|
|
|
bus.pathBlocker = GetEnt( "pathBlocker", "targetname" );
|
|
wait(0.05);
|
|
bus.pathBlocker elevatorClearPath();
|
|
|
|
bus thread moverDoMove( "bus_start_fall" );
|
|
}
|
|
|
|
moverDoMove( waitString ) // self == mover entity
|
|
{
|
|
level endon ( "game_ended" );
|
|
|
|
self waittill( waitString, attacker );
|
|
|
|
self PlaySound( "scn_bus_groan" );
|
|
|
|
// Earthquake( 0.15, 1.5, self.origin, 1500 );
|
|
self.pathBlocker elevatorBlockPath();
|
|
|
|
self busSlidingEffect();
|
|
|
|
self.collision killLinkedEntities( attacker );
|
|
|
|
for ( i = 1 ; i < self.keyframes.size; i++ )
|
|
{
|
|
kf = self.keyframes[i];
|
|
|
|
self MoveTo( kf.origin, kf.script_duration, kf.script_accel, kf.script_decel );
|
|
self RotateTo( kf.angles, kf.script_duration, kf.script_accel, kf.script_decel );
|
|
|
|
if ( IsDefined( kf.shakeMag ) )
|
|
{
|
|
Earthquake( kf.shakeMag, kf.shakeDuration, self.origin, kf.shakeDistance );
|
|
}
|
|
|
|
self waittill( "movedone" );
|
|
}
|
|
|
|
// play another sound?
|
|
|
|
// shake?
|
|
fakeBusPos = self.origin + (0, 0, 2000);
|
|
|
|
Earthquake( 0.25, .5, fakeBusPos, 3000 );
|
|
|
|
StopFXOnTag( getFx("vfx_bus_fall_dust"), self.busDust, "tag_origin" );
|
|
self.busDust Delete();
|
|
|
|
PlaySoundAtPos(fakeBusPos, "scn_bus_crash");
|
|
}
|
|
|
|
busSlidingEffect() // self = bus
|
|
{
|
|
// wait (BUS_FALL_DELAY);
|
|
|
|
busDust = GetEnt( "busDustEffect2", "targetname" );
|
|
busDust SetModel( "tag_origin" );
|
|
busDust LinkTo( self );
|
|
PlayFXOnTag( getfx( "vfx_bus_fall_dust" ), busDust, "tag_origin" );
|
|
self.busDust = busDust;
|
|
|
|
// find the entity
|
|
scrapeDustLoc = GetEnt( "busDustEffect", "targetname" );
|
|
if ( IsDefined( scrapeDustLoc ) )
|
|
{
|
|
PlayFX( getFX( "vfx_bus_scrape_dust"), scrapeDustLoc.origin, AnglesToForward( scrapeDustLoc.angles ) );
|
|
scrapeDustLoc PlaySound( "scn_bus_slide" );
|
|
}
|
|
}
|
|
|
|
killLinkedEntities( attacker ) // self == collision
|
|
{
|
|
linkedObjs = self GetLinkedChildren();
|
|
foreach ( obj in linkedObjs )
|
|
{
|
|
if ( IsDefined( obj.owner ) )
|
|
{
|
|
// not sure what the inflictor should be
|
|
obj DoDamage( 1000, self.origin, attacker, self, "MOD_CRUSH" );
|
|
}
|
|
}
|
|
}
|
|
|
|
falling_elevator()
|
|
{
|
|
elevator = GetEnt("falling_elevator", "targetname");
|
|
cables = GetEnt("falling_elevator_cables", "targetname");
|
|
|
|
elevatorPathBlocker1 = GetEnt( "elevatorBlockPaths1", "targetname" );
|
|
elevatorPathBlocker1 elevatorBlockPath();
|
|
|
|
if(!IsDefined(elevator) || !IsDefined(cables))
|
|
return;
|
|
|
|
while(!IsDefined(elevator.linked_ents))
|
|
wait .05;
|
|
|
|
elevator.state = 1;
|
|
|
|
// Set up damage watchers
|
|
elevator thread falling_elevator_cables(cables);
|
|
elevator thread explosive_damage_watch(elevator, "next_stage");
|
|
foreach(ent in elevator.linked_ents)
|
|
{
|
|
elevator thread explosive_damage_watch(ent, "next_stage");
|
|
}
|
|
|
|
cablePos = cables.origin;
|
|
|
|
// wait a little for the second blocker--doesn't seem to be catching
|
|
wait ( 0.05 );
|
|
elevatorPathBlocker2 = GetEnt( "elevatorBlockPaths2", "targetname" );
|
|
elevatorPathBlocker2 elevatorClearPath();
|
|
elevatorPathBlocker2 SetContents(0); // so that dogs don't actually hit these things
|
|
|
|
// connect effect emmiters
|
|
elevator.dustEffect = GetEntArray( "dustEffect", "targetname" );
|
|
foreach (ent in elevator.dustEffect)
|
|
{
|
|
ent LinkTo( cables );
|
|
}
|
|
elevator.sparkEffect = GetEntArray( "sparkEffect", "targetname" );
|
|
foreach (ent in elevator.sparkEffect)
|
|
{
|
|
ent LinkTo( cables );
|
|
}
|
|
|
|
while(1)
|
|
{
|
|
elevator waittill("next_stage", attacker );
|
|
|
|
if(elevator.moving)
|
|
continue;
|
|
|
|
elevator.state++;
|
|
|
|
elevator notify("trigger"); //Move to next state
|
|
if(IsDefined(cables))
|
|
cables notify("trigger");
|
|
|
|
// start falling
|
|
if (elevator.state == 2)
|
|
{
|
|
elevator PlaySoundOnMovingEnt( "scn_elevator_fall_move" );
|
|
cables notify( "stop_watching_cable" );
|
|
elevatorPathBlocker1 elevatorClearPath();
|
|
elevatorPathBlocker1 SetContents(0); // so that dogs don't actually hit these things
|
|
//elevator maps\mp\_movers::notify_moving_platform_invalid(); (this line stops the elevator model from moving.)
|
|
|
|
foreach (ent in elevator.dustEffect)
|
|
{
|
|
PlayFX( getfx( "vfx_elevator_fall_dust" ), ent.origin );
|
|
}
|
|
}
|
|
else if (elevator.state == 3)
|
|
{
|
|
playSoundAtPos( cablePos, "scn_elevator_fall_cable_snap" );
|
|
elevatorPathBlocker2 SetContents(1);
|
|
elevatorPathBlocker2 elevatorBlockPath();
|
|
|
|
|
|
foreach (ent in elevator.sparkEffect)
|
|
{
|
|
PlayFX( getfx( "vfx_spark_drip_child" ), ent.origin );
|
|
}
|
|
|
|
// get rid of any placed satcom, ims, etc
|
|
elevator killLinkedEntities( attacker );
|
|
}
|
|
|
|
elevator waittill ( "move_end" );
|
|
|
|
// end falling
|
|
if (elevator.state == 2)
|
|
{
|
|
playSoundAtPos( cablePos, "scn_elevator_fall_cable_stress" );
|
|
PlayFX( getfx( "vfx_elevator_shaft_dust" ), elevator.origin );
|
|
Earthquake( 0.5, 1.5, elevator.origin, 1000 );
|
|
}
|
|
else if (elevator.state == 3)
|
|
{
|
|
elevator PlaySoundOnMovingEnt( "scn_elevator_fall_crash" );
|
|
Earthquake( 0.75, 1.5, elevator.origin, 1000 );
|
|
elevatorPathBlocker1 SetContents(1);
|
|
elevatorPathBlocker1 elevatorBlockPath();
|
|
}
|
|
}
|
|
}
|
|
|
|
explosive_damage_watch(ent, note)
|
|
{
|
|
if(!IsDefined(note))
|
|
note = "explosive_damage";
|
|
|
|
ent SetCanDamage(true);
|
|
while(1)
|
|
{
|
|
ent.health = 1000000;
|
|
ent waittill("damage", amount, attacker, direction_vec, point, type);
|
|
if(!is_explosive(type))
|
|
{
|
|
continue;
|
|
}
|
|
self notify(note, attacker);
|
|
}
|
|
}
|
|
|
|
falling_elevator_cables(cables)
|
|
{
|
|
cables endon ("stop_watching_cable");
|
|
|
|
large_health = 1000000;
|
|
cables SetCanDamage(true);
|
|
cables.health = large_health;
|
|
cables.fake_health = 50;
|
|
|
|
while(1)
|
|
{
|
|
cables waittill("damage", amount, attacker, direction_vec, point, type);
|
|
|
|
if(cables.moving || (self.state==2 && !is_explosive(type)))
|
|
{
|
|
cables.health = cables.health + amount;
|
|
continue;
|
|
}
|
|
|
|
if(cables.health>large_health-cables.fake_health)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
self notify("next_stage");
|
|
break;
|
|
}
|
|
}
|
|
|
|
is_explosive( cause )
|
|
{
|
|
if(!IsDefined(cause))
|
|
return false;
|
|
|
|
cause = tolower( cause );
|
|
switch( cause )
|
|
{
|
|
case "mod_grenade_splash":
|
|
case "mod_projectile_splash":
|
|
case "mod_explosive":
|
|
case "splash":
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
elevatorClearPath() // self == blockingEnt
|
|
{
|
|
self ConnectPaths();
|
|
self Hide();
|
|
}
|
|
|
|
elevatorBlockPath()
|
|
{
|
|
self Show();
|
|
self DisconnectPaths();
|
|
}
|
|
|
|
|