cod5-sdk/raw/maps/oki3_util.gsc

2382 lines
49 KiB
Text
Raw Normal View History

2008-11-20 00:00:00 +00:00
#include common_scripts\utility;
#include maps\_utility;
#include maps\_anim;
//ent = GetEnt( "myent", "targetname" );
//ai SetGoalPos( ent.origin, ent.angles ); // THE NEW HOTNESS, note the second parameter
//ai waittill( "goal" ); // wait for him to get to the goal area
//ai waittill( "orientdone" ); // wait for him to rotate to the angles you specified
/*------------------------------------
slides open the paper stye doors in the main castle building
------------------------------------*/
open_door(door,direction,move_x,wait_trig)
{
if(isDefined(wait_trig))
{
trigger_wait(wait_trig,"targetname");
}
else
{
wait(randomfloat(3));
}
door1 = getent(door,"targetname");
if (direction == "r")
{
door1 connectpaths();
if(move_x)
{
door1 MoveTo( door1.origin + (56,0,0), randomfloatrange(1,1.5), 0, .05 );
}
else
{
door1 MoveTo( door1.origin + (0,56,0), randomfloatrange(1,1.5), 0, .05 );
}
}
if(direction == "l")
{
door connectpaths();
if(move_x)
{
door1 MoveTo( door1.origin + (-56,0,0), randomfloatrange(1,1.5), 0, .05 );
}
else
{
door1 MoveTo( door1.origin + (0,-56,0), randomfloatrange(1,1.5), 0, .05 );
}
}
}
remove_grenades_from_everyone()
{
//removes grenades from all enemies, everyone!!
guys = getspawnerarray();
for(i=0;i<guys.size;i++)
{
guys[i].grenadeAmmo = 0;
}
}
/*--------------------------------------------------
setup the friendlies ,used for start/skipto points
--------------------------------------------------*/
setup_friendlies(area)
{
spawn_friendlies();
}
/*------------------------------------
spawn in the friendly sqad and set them up
------------------------------------*/
spawn_friendlies()
{
//spawn in the friendlies
simple_spawn("squad");
wait(.35);
//the guy who is going to get sniped later
pawn = false;
//grab them and set up the hero characters
guys = get_ai_group_ai("friends");
for(i=0;i<guys.size;i++)
{
//remove all their grenades
guys[i].grenadeAmmo = 0;
guys[i].MaxSightDistSqrd = (1500 * 1500);
if(guys[i].classname == "actor_ally_us_usmc_roebuck"|| guys[i].classname == "actor_ally_us_usmc_polonsky")
{
guys[i] thread magic_bullet_shield();
if(guys[i].classname == "actor_ally_us_usmc_roebuck")
{
level.sarge = guys[i];
guys[i].animname = "sarge";
}
else
{
level.polonsky = guys[i];
}
}
if(!pawn && guys[i].classname != "actor_ally_us_usmc_roebuck" && guys[i].classname != "actor_ally_us_usmc_polonsky")
{
guys[i].script_noteworthy = "sniper_pawn";
if(randomint(100)>50)
{
guys[i].name = "Pvt. Zaring";
}
else
{
guys[i].name = "Pvt. Pierro";
}
level.sniper_pawn = guys[i];
pawn = true;
}
}
level.sarge PushPlayer( true );
level.polonsky PushPlayer(true);
}
toggle_ignoreall(all)
{
if(isDefined(all))
{
guys = getaiarray("allies");
}
else
{
guys = get_ai_group_ai("friends");
}
for(i=0;i<guys.size;i++)
{
if(guys[i].ignoreall == true)
{
guys[i].ignoreall = false;
}
else
{
guys[i].ignoreall = true;
}
}
}
ignoreall_on(guys)
{
for(i=0;i<guys.size;i++)
{
guys[i].ignoreall = true;
}
}
ignoreall_off(guys)
{
for(i=0;i<guys.size;i++)
{
guys[i].ignoreall = false;
}
}
/*------------------------------------
returns a group of spawners
------------------------------------*/
get_spawners(value, key)
{
spawners = getentarray(value,key);
guys = undefined;
for(x=0;x<spawners.size;x++)
{
if(!isSentient(spawners[x]))
{
guys = add_to_array(guys, spawners[x]);
}
}
return guys;
}
/*------------------------------------
moves the players after spawning them in
used in skipto's/starts
------------------------------------*/
move_players(spots)
{
players = get_players();
points = getentarray(spots,"targetname");
if(!points.size > 0)
{
points = getstructarray(spots,"targetname");
}
for(x =0;x<players.size;x++)
{
players[x] setorigin(points[x].origin);
if(isDefined(points[x].angles))
{
players[x] setplayerangles( points[x].angles);
}
}
}
//uses a script_struct like a trigger radius ( keep down those ent counts! )
org_trigger(org,radius,notification)
{
trig = false;
while(!trig)
{
players = get_players();
for(i=0;i<players.size;i++)
{
if( distancesquared(players[i].origin,org) < radius * radius)
{
trig = true;
}
}
wait(.1);
}
if(isDefined(notification))
{
level notify(notification);
}
}
/*------------------------------------
moves the ai after spawning them in
used in skipto's/starts
------------------------------------*/
move_ai(spots)
{
ai = get_ai_group_ai("friends"); //getaiarray("allies");
if(ai.size < 3)
{
ai = getaiarray("allies");
}
points = getentarray(spots,"targetname");
if(!points.size > 0)
{
points = getstructarray(spots,"targetname");
}
sarge_point = undefined;
polonsky_point = undefined;
pawn_point = undefined;
//remove sarge from the array if we've set up node for sarge to start at
for(i=0;i<points.size;i++)
{
if(isDefined(points[i].script_noteworthy) && points[i].script_noteworthy == "sarge")
{
sarge_point = points[i];
}
if(isDefined(points[i].script_noteworthy) && points[i].script_noteworthy == "polonsky")
{
polonsky_point = points[i];
}
if(isDefined(points[i].script_noteworthy) && points[i].script_noteworthy == "pawn")
{
pawn_point = points[i];
}
}
if(isDefined(sarge_point))
{
points = array_remove(points,sarge_point);
ai = array_remove(ai,level.sarge);
level.sarge.anchor = spawn("script_origin",level.sarge.origin);
level.sarge linkto( level.sarge.anchor);
level.sarge.anchor moveto(sarge_point.origin,.05);
level.sarge.anchor waittill("movedone");
level.sarge.anchor.angles = sarge_point.angles;
level.sarge unlink();
level.sarge.anchor delete();
sarge_point= undefined;
}
if(isDefined(polonsky_point))
{
points = array_remove(points,polonsky_point);
ai = array_remove(ai,level.polonsky);
level.polonsky.anchor = spawn("script_origin",level.polonsky.origin);
level.polonsky.anchor.angles= level.polonsky.angles;
level.polonsky linkto( level.polonsky.anchor);
level.polonsky.anchor moveto(polonsky_point.origin,.05);
level.polonsky.anchor waittill("movedone");
level.polonsky.anchor.angles = polonsky_point.angles;
level.polonsky unlink();
level.polonsky.anchor delete();
polonsky_point= undefined;
}
if(isDefined(pawn_point))
{
points = array_remove(points,pawn_point);
ai = array_remove(ai,level.sniper_pawn);
level.sniper_pawn.anchor = spawn("script_origin",level.sniper_pawn.origin);
level.sniper_pawn linkto( level.sniper_pawn.anchor);
level.sniper_pawn.anchor moveto(pawn_point.origin,.05);
level.sniper_pawn.anchor waittill("movedone");
level.sniper_pawn.anchor.angles = pawn_point.angles;
level.sniper_pawn unlink();
level.sniper_pawn.anchor delete();
pawn_point= undefined;
}
for(x=0;x<ai.size;x++)
{
ai[x].anchor = spawn("script_origin",ai[x].origin);
ai[x] linkto( ai[x].anchor);
ai[x].anchor moveto(points[x].origin,.05);
ai[x].anchor waittill("movedone");
if(isDefined(points[x].angles))
{
ai[x].anchor.angles = points[x].angles;
}
ai[x] unlink();
ai[x].anchor delete();
}
}
/*------------------------------------
fake death
self = guy getting worked
------------------------------------*/
bloody_death( die, delay )
{
self endon( "death" );
if( !is_active_ai( self ) )
{
return;
}
if( IsDefined( self.bloody_death ) && self.bloody_death )
{
return;
}
self.bloody_death = true;
if( IsDefined( delay ) )
{
wait( RandomFloat( delay ) );
}
tags = [];
tags[0] = "j_hip_le";
tags[1] = "j_hip_ri";
tags[2] = "j_head";
tags[3] = "j_spine4";
tags[4] = "j_elbow_le";
tags[5] = "j_elbow_ri";
tags[6] = "j_clavicle_le";
tags[7] = "j_clavicle_ri";
for( i = 0; i < 2; i++ )
{
random = RandomIntRange( 0, tags.size );
//vec = self GetTagOrigin( tags[random] );
self thread bloody_death_fx( tags[random], undefined );
wait( RandomFloat( 0.1 ) );
}
//if( die )
//{
self DoDamage( self.health + 150, self.origin );
//}
}
/*------------------------------------
play the bloody fx on a guy
self = the AI on which we're playing fx
------------------------------------*/
bloody_death_fx( tag, fxName )
{
if( !IsDefined( fxName ) )
{
fxName = level._effect["flesh_hit"];
}
PlayFxOnTag( fxName, self, tag );
}
is_active_ai( suspect )
{
if( IsDefined( suspect ) && IsSentient( suspect ) && IsAlive( suspect ) )
{
return true;
}
else
{
return false;
}
}
wait_for_goal(notification)
{
self endon("death");
self waittill("goal");
level notify(notification);
}
/*------------------------------------
kill a mans
self = guy
------------------------------------*/
random_death(min,max)
{
self endon("death");
wait(randomfloatrange(min,max));
self bloody_death();
}
///*------------------------------------
//setup the drones
//------------------------------------*/
//drones_init()
//{
//
// // Setup the drones
// character\char_jap_rifle::precache();
// level.drone_spawnFunction["axis"] = character\char_jap_rifle::main;
// maps\_drones::init();
//
//}
//manual_fire_mg(mg_script_noteworthy,end_on,start_on)
//{
//
// level endon(end_on);
//
// if(isDefined(start_on))
// {
// level waittill(start_on);
// }
// mg = getEnt(mg_script_noteworthy, "script_noteworthy");
// mg thread maps\_mgturret::burst_fire_unmanned();
// mg setmode( "auto_nonai" );
// mg setTurretTeam( "axis" );
// mg thread mg_think(end_on);
//}
//mg_think(endon_notify)
//{
//
// level waittill(endon_notify);
// self setmode("auto_ai");
// self notify("death");
//}
/*------------------------------------
make sure the players run into the bunker
and stay there
------------------------------------*/
check_players_in_bunker()
{
players = get_players();
bunkers = getentarray("bunker_volume","targetname");
shock_time = 8 * 1000;
//go thru all the players and check to see if they are
//inside the bunker
for(i=0;i<players.size;i++)
{
player = players[i];
player_safe = false;
//unsafe_players = [];
if( !IsDefined( player.shocked_time ) )
{
player.shocked_time = 0;
}
for(x =0;x<bunkers.size;x++)
{
if( player isTouching(bunkers[x]))
{
player_safe = true;
}
}
if(!player_safe)
{
if( GetTime() > player.shocked_time )
{
player.shocked_time = GetTime() + shock_time;
ent = spawnstruct();
ent.origin = player.origin;
ent.is_struct = true;
min_dmg = 25;
max_dmg = 50;
dmg_mod = 1;
for(q=0;q<players.size;q++)
{
if(players[q] != player && distance(players[q].origin,ent.origin) <256)
{
dmg_mod ++;
}
}
min_dmg = min_dmg /dmg_mod;
max_dmg = max_dmg /dmg_mod;
if(!isDefined(player.not_in_bunker))
{
ent thread maps\_mortar::explosion_activate( "first_mortar", 256, min_dmg, max_dmg, 0.2, 3, 512 );
}
}
}
}
}
get_players_in_bunker()
{
players = get_players();
bunkers = getentarray("bunker_volume","targetname");
guys = [];
for(i=0;i<players.size;i++)
{
player = players[i];
for(x =0;x<bunkers.size;x++)
{
if( player isTouching(bunkers[x]))
{
guys[guys.size] = player;
}
}
}
return guys;
}
empty_spawners(guys)
{
spawners = getentarray(guys,"targetname");
if(isDefined(spawners))
{
for(i=0;i<spawners.size;i++)
{
if(!isSentient(spawners[i]))
{
spawners[i] delete();
}
}
}
}
/*------------------------------------
set stances on the friendlies
------------------------------------*/
set_friendly_stances(a,b,c)
{
friends = get_ai_group_ai("friends");
for(i=0;i<friends.size;i++)
{
if(isDefined(a))
{
if(isDefined(b))
{
if(isDefined(c))
{
friends[i] allowedstances(a,b,c);
}
else
{
friends[i] allowedstances(a,b);
}
}
else
{
friends[i] allowedstances(a);
}
}
}
}
set_friendly_poses()
{
ai = getaiarray("allies");
for(i=0;i<ai.size;i++)
{
ai[i] allowedstances("stand");
ai[i].a.pose = "stand";
}
}
/*------------------------------------
plays dialogue/animation on a guy
------------------------------------*/
do_dialogue(dialogue ,aname,anim_node,lookTarget)
{
if(self == level.sarge)
{
aname = "sarge";
}
else if(self == level.polonsky)
{
aname = "polonsky";
}
else
{
self.old_animname = self.animname;
}
self.animname = aname;
if(isDefined(anim_node))
{
anim_node anim_single_solo( self, dialogue );
}
else
{
self thread maps\_anim::anim_facialFiller( "dialogue_done", lookTarget );
self animscripts\face::SaySpecificDialogue( undefined, level.scr_sound[aname][dialogue], 1.0, "dialogue_done" );
self waittill("dialogue_done");
}
if(isdefined(self.old_animname))
{
self.animname = self.old_animname;
}
}
/*------------------------------------
do animation/dialogue on random non-hero character
------------------------------------*/
do_redshirt_dialogue(dialogue,trig)
{
guys = getaiarray("allies");
redshirts = undefined;
redshirt = undefined;
for(i=0;i<guys.size;i++)
{
if(guys[i] != level.sarge && guys[i] != level.polonsky)
{
if(isDefined(trig))
{
if(guys[i] istouching(getent(trig,"targetname")))
{
add_to_array(redshirts,guys[i]);
}
}
else
{
add_to_array(redshirts,guys[i]);
}
}
}
if(isDefined(redshirts))
{
redshirt = redshirts[randomint(redshirts.size)];
}
if(isDefined(redshirt))
{
redshirt thread do_dialogue(dialogue,"redshirt");
}
}
//trim_dialogue(dialogue,aname)
//{
//
// strng = level.scr_sound[aname][dialogue];
// newstr = "";
// for(x=strng.size -1;x>5;x--)
// {
// newstr = strng[x] + newstr;
// }
// return (newstr);
//
//}
///*------------------------------------
//USED WITH SQUAD_MANAGER TO
//MONITOR WAVES OF GUYS
//------------------------------------*/
//monitor_squads(guys,maxWaves,strEndon)
//{
// level endon(strEndon);
//
// waves = 0;
// while(waves < maxWaves)
// {
// level waittill(guys + " min threshold reached");
// waves++;
// }
// level notify(strEndon);
//}
/*------------------------------------
------------------------------------*/
#using_animtree ("supply_drop");
do_supply_drop(drop,plane)
{
//grab and hide the supply drop that lands in the bunker
//landed_drop = getent("bunker_chute_landed","targetname");
//landed_drop hide();
supply_drop = getent("supply_drop" + drop, "targetname");
org1 = supply_drop.origin;
if(drop == 4)
{
org1 = supply_drop.origin;//(5717.5, 3154.5, -754);//supply_drop.origin;
}
supply_drop.origin = plane.origin;
supply_drop show();
supply_drop.animname = "drop";
supply_drop useanimtree(#animtree);
supply_drop moveto( org1 + (0,0,-80) , randomfloatrange(3.5,5) );
supply_drop waittill("movedone");
supply_drop notify("stop_looping");
supply_drop playsound("supply_box_land");
the_anim = undefined;
chance = randomint(100);
if(chance > 50)
{
the_anim = level.scr_anim["drop"]["landing"];
}
else
{
the_anim = level.scr_anim["drop"]["landingb"];
}
supply_drop SetFlaggedAnimKnobRestart( "drop_landing", the_anim, 1.0, 0.2, 1.0 );
wait(5);
supply_drop delete();
}
/*------------------------------------
temp until animation gets done
------------------------------------*/
#using_animtree ("supply_drop");
do_drop_idle_anim()
{
//self.animname = "drop1";
self useanimtree(#animtree);
self endon("movedone");
self endon("stop_looping");
while(1)
{
self maps\_anim::anim_single_solo(self,"drop");
self waittill("single anim");
}
}
/*------------------------------------
Check to see if the attacker is one of the players
attacker = entitiy
------------------------------------*/
is_player(attacker)
{
players = get_players();
attackerIsPlayer = false;
for( i = 0; i < players.size; i++ )
{
player = players[i];
if( attacker == player )
{
attackerIsPlayer = true;
break;
}
}
return attackerIsPlayer;
}
/*------------------------------------
give the user a hint to show the airstrike
------------------------------------*/
air_strike_user_notify()
{
self endon("death");
self endon("disconnect");
//removed the icon
//self thread do_airstrike_hud_elem();
text = &"OKI3_AIRSTRIKE_HOWTO";
self setup_client_hintelem();
self.hintelem setText(text);
wait(3.5);
self.hintelem settext("");
}
do_airstrike_hud_elem()
{
self endon("death");
self endon("disconnect");
elem = newclienthudelem(self);
elem.x = 280;
elem.y = 240;
elem.alpha = 0;
//elem.horzAlign = "fullscreen";
//elem.vertAlign = "fullscreen";
elem.foreground = true;
elem SetShader( "hud_icon_airstrike", 64, 64);
// Fade into white
elem FadeOverTime( 0.2 );
elem.alpha = 1;
wait 5;
elem MoveOverTime( 1.5 );
elem.y = 420;
elem.x = elem.x + 80;
elem ScaleOverTime( 1.5, 8, 8 );
wait 2;
elem FadeOverTime( 0.2 );
elem.alpha = 0;
wait 0.2;
elem destroy();
}
/*------------------------------------
wait for player to use the mortars in the pits ------------------------------------*/
mortar_round_think(trig)
{
self endon("stop_thinking");
ent = getent("use_mortars_" + trig,"targetname");
ent sethintstring(&"OKI3_USE_MORTAR");
ent thread mortar_hint();
while(1)
{
ent waittill("trigger",user);
//fix berzerker collectible issue
if(isDefined(user.collectibles_berserker_mode_on) && user.collectibles_berserker_mode_on )
{
continue;
}
else
{
//prevent mortar spamming
if(!isDefined(user.hasmortar))
{
user GiveWeapon( "mortar_round" );
user SwitchToWeapon( "mortar_round" );
user setweaponammoclip("mortar_round",1);
user allowMelee(false);
user thread watch_mortar_weapon();
user thread watch_player_mortar_death();
}
}
}
}
watch_player_mortar_death()
{
self endon("disconnect");
self endon("mortar_dropped");
self waittill("death");
self allowMelee(true);
self.hasmortar = undefined;
}
watch_mortar_weapon()
{
self endon("death");
self endon("disconnect");
self endon("mortar_dropped");
self.disableBerserker = true;
while ( self getcurrentweapon() != "mortar_round")
{
wait_network_frame();
}
while( self getcurrentweapon() == "mortar_round" || self getcurrentweapon() == "none" )
{
self.hasmortar = true;
if(!isDefined(self.mortar_hint_given))
{
self thread hud_mortar_hint();
self.mortar_hint_given = true;
}
wait_network_frame();
}
if(self getcurrentweapon() != "syrette")
{
self takeweapon("mortar_round");
}
self allowMelee(true);
dropped = true;
self.hasmortar = undefined;
self.disableBerserker = undefined;
//self SetClientDvar( "ammoCounterHide", "0" );
self notify("mortar_dropped");
}
hud_mortar_hint()
{
self endon("death");
self endon("disconnect");
text = &"OKI3_MORTAR_HINT";
self setup_client_hintelem();
self.hintelem setText(text);
wait(5);
self.hintelem settext("");
}
/*------------------------------------
notify a trigger
------------------------------------*/
trigger_array_notify(no_wait)
{
if(!isDefined(no_wait))
{
wait(randomfloat(2));
}
self notify("trigger");
}
mortar_hint()
{
level endon ("mortar_hint_given");
while(1)
{
players = get_players();
for(i=0;i<players.size;i++)
{
if(isAlive(players[i]) && distancesquared(players[i].origin, self.origin) < 256 * 256)
{
if(isDefined(level.sarge))
{
level.sarge thread do_dialogue("mortar_nag" +randomint(2));
level notify("mortar_hint_given");
break;
}
}
}
wait(1);
}
}
//----------------------------------
//SQUAD LEADER STUFFS
//----------------------------------
/*------------------------------------
treat a group of enemies as a squad by
assigning a leader to one of them
------------------------------------*/
squad_leader_manager(guys)
{
if(isDefined(guys))
{
//select the leader
leader = select_leader(guys);
if(isDefined(leader))
{
//remove the leader from the array so we only track the followers
guys = array_remove(guys,leader);
leader thread debug_leader();
//monitor the leader to see where he goes
leader thread monitor_leader();
//allow other guys in the squad to be promoted to leader if the leader dies
level thread squad_promotion(guys,leader);
//make the guys follow the leader
for(i=0;i<guys.size;i++)
{
guys[i].goalradius = 256;
guys[i] thread follow_the_leader(leader);
}
}
}
}
/*------------------------------------
makes a guy follow the leader
self = guy following
------------------------------------*/
follow_the_leader(leader)
{
self endon("death");
level endon("new leader");
while(isDefined(leader) && isAlive(leader))
{
//wait until the leader gets a new node that
//is far away, then go to where the leader is going
leader waittill("node_changed",new_org);
if(distancesquared(new_org,self.origin) > 384*384)
{
self notify("new_position");
self thread goto_new_position(new_org);
}
}
}
/*------------------------------------
makes the guy run to a new position
self = guy following the leader
------------------------------------*/
goto_new_position(new_org)
{
self endon("new_position");
self endon("death");
self.goalradius = 256;
self setgoalpos(new_org);
self.ignoreall = true;
self waittill("goal");
self.ignoreall = false;
self findcovernode();
}
/*------------------------------------
monitors for the leader to choose a new position
------------------------------------*/
monitor_leader()
{
self endon("death");
//make sure the leader always has a large goalradius
self.goalradius = level.default_goalradius;
while(1)
{
//check to see if the leader has a node already
if(isDefined(self.node) && isDefined(self.node.origin))
{
self.a.old_node_origin = self.node.origin;
}
wait(.25);
//check to see if the leader wants to run to a new node which is farther than 128 units away from his current position.
if(isDefined(self.node) && isDefined(self.node.origin) && isDefined(self.a.old_node_origin))
{
if( self.a.old_node_origin != self.node.origin && distancesquared(self.node.origin,self.origin) > 128*128)
{
self notify("node_changed",self.node.origin);
}
}
}
}
/*------------------------------------
promote a new guy to a leader when the old
leader gets killed
------------------------------------*/
squad_promotion(guys,leader)
{
squadname = guys[0].script_aigroup;
//wait until the leader kicks it
leader waittill("death");
//grab all the guys left in the squad and pick a new leader if there are more than 1
guys = get_ai_group_ai(squadname);
level notify("new leader");
if(isDefined(guys) && guys.size > 1)
{
iprintln("promoting a new leader for " + squadname );
level thread squad_leader_manager(guys);
}
}
/*------------------------------------
select the leader from the guys
------------------------------------*/
select_leader(guys)
{
leader = undefined;
for(i=0;i<guys.size;i++)
{
//if the guy is an officer or has a script_noteworthy of "leader" , he will be a squad leader
if(issubstr(guys[i].classname,"officer") || isDefined(guys[i].script_noteworthy) && guys[i].script_noteworthy == "leader")
{
leader = guys[i];
break;
}
}
if(!isDefined(leader))
{
leader = guys[randomint(guys.size)];
}
return leader;
}
/*------------------------------------
show the leader
------------------------------------*/
debug_leader()
{
/#
self endon("death");
while( 1 )
{
print3d( self.origin + ( 0, 0, 32 ), "leader" );
wait( 0.05 );
}
#/
}
/*------------------------------------
throws smoke grenades over the wall
to kick off the spiderhole ambush
------------------------------------*/
throw_smoke_from_pos( force,start_pos )
{
wait(randomfloatrange(.1,1.0));
smoke = self;
if(isDefined(start_pos))
{
smoke = getstruct(start_pos,"targetname");
}
throw_force = 980;
if(isDefined(force))
{
throw_force = force;
}
smoke1 = spawn("script_origin",smoke.origin);
smoke1.angles = smoke.angles;
forward = AnglesToForward( smoke1.angles );
target_pos = smoke1.origin + vectorscale( forward, throw_force );
///////// Math
gravity = GetDvarInt( "g_gravity" );
gravity = gravity * -1;
dist = Distance( smoke1.origin, target_pos );
time = 1;
delta = target_pos - smoke1.origin;
drop = 0.5 * gravity * ( time * time );
velocity = ( ( delta[0] / time ), ( delta[1] / time ), ( delta[2] - drop ) / time );
/////////
smoke1 thread smoke_trailFX();
smoke1 MagicGrenadeType( "m8_white_smoke_light", smoke1.origin, velocity, 3 );
//smoke1 MagicGrenadeType( "fraggrenade", smoke1.origin, velocity, 3 );
}
smoke_trailFX()
{
self waittill ( "grenade_fire", grenade, weaponName );
{
ent = spawn("script_model",grenade.origin);
ent.angles = grenade.angles;
ent setmodel("tag_origin");
ent linkto(grenade);
playfxontag(level._effect["smoke_grn_trail"],ent,"TAG_ORIGIN");
wait(5);
ent delete();
}
}
/*------------------------------------
put a guy into banzai mode
------------------------------------*/
setup_banzai_guys(no_wait)
{
self endon("death");
if(!isDefined(no_wait))
{
no_wait = false;
}
if(!no_wait)
{
wait(3);
}
self maps\_banzai::banzai_force();
}
//stolen from MikeD
// Returns a random element from the given array
get_random( array )
{
return array[RandomInt( array.size )];
}
// Sets up the AI for force gibbing
set_random_gib()
{
refs = [];
refs[refs.size] = "right_leg";
// refs [refs.size] = "head";
//refs[refs.size] = "left_leg";
refs[refs.size] = "right_arm";
//refs[refs.size] = "left_arm";
refs[refs.size] = "guts";
//refs[refs.size] = "no_legs";
self.a.gib_ref = get_random( refs );
}
/*------------------------------------
wait for the spiderholes to open, then play a sound
TODO - fix the deleting stuff, it should look better
------------------------------------*/
init_spiderholes()
{
level.no_spider_lid_drop = true;
ents = getentarray("spiderhole_lid","script_noteworthy");
array_thread(ents,::monitor_spiderhole_lid);
}
monitor_spiderhole_lid()
{
//self endon("guy_dead");
self waittill("emerge");
self playsound("spider_hole_open");
self waittill("out_of_spiderhole");
wait(3);
self unlink();
if(isDefined(self.tag_lid))
{
self.tag_lid delete();
}
self notsolid();
self moveto(self.origin + (0,0,-200),8);
self waittill("movedone");
self delete();
}
/*------------------------------------
picks a ranom non-hero friendly AI
who is within range of a specific target.
Can optionally pass in someone to exclude from the selection as well
------------------------------------*/
choose_random_redshirt(target,dist_from_target,excluder)
{
guys = getaiarray("allies");
targ = getent(target,"targetname");
excluded_guy = level.sarge;
if(isDefined(excluder))
{
excluded_guy = excluder;
}
for(i=0;i<guys.size;i++)
{
if(guys[i] != level.polonsky && guys[i] != level.sarge && guys[i] != excluded_guy)
{
if(distance ( guys[i].origin,targ.origin) < dist_from_target)
{
return guys[i];
}
}
}
}
choose_random_guy()
{
guys = getaiarray("allies");
excluded_guy = level.sarge;
for(i=0;i<guys.size;i++)
{
if(guys[i] != level.polonsky && guys[i] != level.sarge)
{
if(!isDefined(guys[i].notme))
{
return guys[i];
}
}
}
}
/*------------------------------------
spawn in guys thru script.
------------------------------------*/
simple_spawn( name, spawn_func ,delay)
{
spawners = getEntArray( name, "targetname" );
// add spawn function to each spawner if specified
if( isdefined( spawn_func ) )
{
for( i = 0; i < spawners.size; i++ )
{
spawners[i] add_spawn_function( spawn_func );
}
}
ai_array = [];
for( i = 0; i < spawners.size; i++ )
{
if( i % 2)
{
//wait for a new network frame to be sent out before spawning in
//another guy
wait_network_frame();
}
// check if we want to forcespawn him
if( IsDefined( spawners[i].script_forcespawn ) )
{
ai = spawners[i] StalingradSpawn();
}
else
{
ai = spawners[i] DoSpawn();
}
spawn_failed( ai );
// for debug purposes (so entinfo displays their name)
if( isdefined( ai ) )
{
ai.targetname = name + "_alive";
if(isDefined(spawners[i].script_noteworthy))
{
ai.script_noteworthy = spawners[i].script_noteworthy;
}
}
ai_array = add_to_array( ai_array, ai );
}
return ai_array;
}
simple_floodspawn(name)
{
defenders = getentarray(name,"targetname");
for(i=0;i<defenders.size;i++)
{
if(i % 2)
{
wait_network_frame();
}
defenders[i] thread maps\_spawner::flood_spawner_think();
}
}
/*------------------------------------
sets the players ammo loadout at the beginning of the map
------------------------------------*/
set_player_ammo_loadout()
{
players = get_players();
for(i=0;i<players.size;i++)
{
//take away all ammo/grenades...these guys had it rough
players[i] SetWeaponAmmoClip( "thompson", 0 );
players[i] SetWeaponAmmoClip( "m1garand", 0 );
players[i] SetWeaponAmmoStock( "thompson", 0 );
players[i] setweaponammostock( "m1garand",0);
players[i] setweaponammostock("fraggrenade",0);
players[i] setweaponammoclip("fraggrenade",0);
players[i] setweaponammostock("m8_white_smoke",0);
players[i] setweaponammoclip("m8_white_smoke",0);
players[i] setweaponammoclip("air_support",0);
players[i] setweaponammostock("air_support",0);
players[i] takeweapon("thompson");
players[i] takeweapon("air_support");
//make sure all this stuff is turned on
players[i] setclientDvar("miniscoreboardhide","0");
players[i] setclientDvar("compass","1");
players[i] SetClientDvar( "hud_showStance", "1" );
players[i] SetClientDvar( "ammoCounterHide", "0" );
}
}
/*------------------------------------
warps all players to script_struct markers
exclude = player to not warp
------------------------------------*/
warp_players(warpto_positions,exclude)
{
ents = getstructarray(warpto_positions,"targetname");
if(ents.size == 0)
{
ents = getentarray(warpto_positions,"targetname");
}
assertex(isDefined(ents.size > 0), "no warpto positions found");
players = get_players();
count = 0;
for(i=0;i<players.size;i++)
{
if(isDefined(exclude))
{
if( players[i] != exclude )
{
players[i] warp_player( ents[count] );
count++;
}
}
else
{
players[i] warp_player( ents[count] );
count++;
}
}
set_breadcrumbs(ents);
}
/*------------------------------------
warp a player to a new position when playing
co-op.
------------------------------------*/
warp_player(pos)
{
self endon("death");
self endon("disconnect");
if(!isDefined(self.warpblack))
{
self.warpblack = NewClientHudElem( self );
self.warpblack.x = 0;
self.warpblack.y = 0;
self.warpblack.horzAlign = "fullscreen";
self.warpblack.vertAlign = "fullscreen";
self.warpblack.foreground = false;
self.sort = 50;
self.warpblack.alpha = 0;
self.warpblack SetShader( "black", 640, 480 );
}
self.warpblack FadeOverTime( .75 );
self.warpblack.alpha = 1;
wait(.75);
self setorigin(pos.origin);
if(isDefined(pos.angles))
{
self setplayerangles( pos.angles);
}
self.warpblack FadeOverTime( .75 );
self.warpblack.alpha = 0;
}
hud_fade_to_black(time)
{
self endon("death");
self endon("disconnect");
if(!isDefined(time))
{
time = 1;
}
if(!isDefined(self.warpblack))
{
self.warpblack = NewClientHudElem( self );
self.warpblack.x = 0;
self.warpblack.y = 0;
self.warpblack.horzAlign = "fullscreen";
self.warpblack.vertAlign = "fullscreen";
self.warpblack.foreground = false;
self.warpblack.sort = 50;
self.warpblack.alpha = 0;
self.warpblack SetShader( "black", 640, 480 );
}
self.warpblack FadeOverTime( time );
self.warpblack.alpha = 1;
}
hud_fade_in(time)
{
self.warpblack FadeOverTime( time );
self.warpblack.alpha = 0;
}
/*------------------------------------
resest the run /combat anims back to default
------------------------------------*/
reset_run_anim()
{
self endon ("death");
self.a.combatrunanim = undefined;
self.run_noncombatanim = self.a.combatrunanim;
self.walk_combatanim = self.a.combatrunanim;
self.walk_noncombatanim = self.a.combatrunanim;
self.preCombatRunEnabled = false;
}
/*------------------------------------
monitors a goal volume for enemies, can optionally
send out a level notification and a trigger notify
when the volume is empty
------------------------------------*/
monitor_volume_for_enemies(volume,level_notify,auto_trigger)
{
volume = getent(volume,"targetname");
guys_dead = false;
while(!guys_dead && isDefined(volume) )
{
count = 0;
ai = getaiarray("axis");
for(i =0;i<ai.size;i++)
{
if( ai[i] istouching(volume))
{
count++;
}
}
if(count == 0)
{
guys_dead = true;
}
wait(1);
}
if(isDefined(level_notify))
{
level notify(level_notify);
}
if( isDefined(auto_trigger) && auto_trigger == "mortarpits_front_chain")
{
ent = getent("mortar_block","targetname");
if(isDefined(ent))
{
ent connectpaths();
ent delete();
}
}
if(isDefined(auto_trigger))
{
trig = getent(auto_trigger,"targetname");
trig notify("trigger");
}
}
/*------------------------------------
sends a guy to a new node and gives him a new
goalvolume
------------------------------------*/
guy_retreats(target_node,new_goalvolume)
{
self endon("death");
self.goalradius = 32;
self.script_goalvolume = new_goalvolume;
self setgoalnode(target_node);
self.pacifist = true;
self thread retreat_interrupt();
self waittill("goal");
self.goalradius = 1024;
self.pacifist = false;
}
retreat_interrupt()
{
self notify( "stop_fallback_interrupt" );
self endon( "stop_fallback_interrupt" );
self endon( "goal" );
self endon( "death" );
while(1)
{
origin = self.origin;
wait 2;
if ( self.origin == origin )
{
self.pacifist = false;
self.goalradius = 64;
self thread charge_at_players();
return;
}
}
}
charge_at_players()
{
self endon("death");
while(1)
{
self setgoalentity( get_closest_player(self.origin) );
wait(3);
}
}
// Sets the players movement speed.
set_player_speed( player_speed, time )
{
self notify( "stop_set_player_speed" );
self endon( "stop_set_player_speed" );
base_speed = 180;
level.player_speed = player_speed;
if( !IsDefined( time ) )
{
time = 0;
}
steps = abs( int( time * 4 ) );
target_speed_scale = player_speed / base_speed;
players = get_players();
for( i = 0; i < players.size; i++ )
{
players[i] thread set_player_speed_internal( target_speed_scale, steps );
}
}
set_player_speed_internal( target_speed_scale, steps )
{
self endon( "death" );
self endon( "disconnect" );
self notify( "stop_set_player_speed" );
self endon( "stop_set_player_speed" );
if( !IsDefined( self.move_speed_scale ) )
{
self.move_speed_scale = 1;
}
// Don't set the speedscale if it's already set to it
if( self.move_speed_scale == target_speed_scale )
{
return;
}
difference = self.move_speed_scale - target_speed_scale;
for( i = 0; i < steps; i++ )
{
self.move_speed_scale -= difference / steps;
self SetMoveSpeedScale( self.move_speed_scale );
wait( 0.5 );
}
self.move_speed_scale = target_speed_scale;
self SetMoveSpeedScale( self.move_speed_scale );
}
//random_path_up_stairs()
//{
//
// trig = getent("take_random_path","targetname");
// while(1)
// {
// trig waittill("trigger",user);
// user thread take_random_path();
// wait(1);
// }
//
//}
//
//take_random_path()
//{
//
// self endon("death");
// desired_goalpos = self.goalpos;
// paths = getnodearray("stairs_paths","targetname");
//
// self.goalradius = 32;
// goal = paths[randomint(paths.size)];
// self setgoalnode(goal);
// self waittill("goal");
// at_pos = false;
// while(!at_pos)
// {
// while(distance(self.origin,goal.origin) > 32)
// {
// wait(.05);
// }
// new_node = getnode(goal.target,"targetname");
// self setgoalnode(new_node);
// while(distance(self.origin,new_node.origin) > 32)
// {
// wait(.05);
// }
// at_pos = true;
// wait(1);
// }
//
// self setgoalpos(desired_goalpos);
//}
/*------------------------------------
guy jumps off his mortar and take cover
------------------------------------*/
mortar_guy_alert()
{
self endon("death");
node = getnode(self.target,"targetname");
trig = undefined;
ents = getentarray(self.target,"targetname");
for(i=0;i<ents.size;i++)
{
if(ents[i].classname == "trigger_radius")
{
trig = ents[i];
}
}
if(isDefined(trig))
{
trig = getent(self.target,"targetname");
trig waittill("trigger");
goto_node = getnode(trig.target,"targetname");
node notify("stop_mortar");
self stopanimscripted();
if(isDefined(self.mortarAmmo) && self.mortarAmmo)
{
self detach(level.prop_mortar_ammunition, "TAG_WEAPON_RIGHT");
self.mortarAmmo = false;
}
self.goalradius = 8;
self animscripts\shared::placeWeaponOn( self.weapon, "right" );
self setgoalnode(goto_node);
self.pacifist = false;
self.ignoreall = false;
self.ignoreme = false;
}
}
kill_beginning_guys()
{
group1 = get_ai_group_ai("forward_squad");
array_thread(group1,maps\oki3_util::bloody_death);
}
rush_player()
{
self endon("death");
self.goalradius = 256;
while(isAlive(self))
{
self SetGoalEntity( get_closest_player(self.origin) );
wait(5);
if(self.goalradius > 128)
{
self.goalradius = self.goalradius - 64;
}
}
}
sniper_leafy_conceal()
{
trees = getstructarray( "treesniper_origin", "targetname" );
for(i=0;i<trees.size;i++)
{
wait(.15);
// play the looping fx of fronds that hide the tree sniper
model_tag_origin = spawn( "script_model", trees[i].origin + (-50,80,0));
model_tag_origin setmodel("tag_origin");
//model_tag_origin linkto( trees[i], "tag_origin", ( 0, 0, 0 ), ( 0, 0, 0 ) );
playfxontag( level._effect["sniper_leaf_loop"], model_tag_origin, "TAG_ORIGIN" );
trees[i].tag_origin = model_tag_origin;
trees[i] thread tree_fx();
}
}
/*------------------------------------
palm fronds that fall from treetops when the snipers kick off
------------------------------------*/
tree_fx()
{
flag_wait( "do_tree_fx" );
wait(randomfloatrange(0.1,5));
// delete the looping fx
self.tag_origin delete();
playfx( level._effect["sniper_leaf_canned"], self.origin );
}
//HUD STUFF FOR SHOWING HINTS
init_tunnel_hint()
{
players = get_players();
array_thread(players,::setup_client_hintelem);
}
// Tell the player to go prone during tunnel crawl
setup_client_hintelem()
{
self endon("death");
self endon("disconnect");
if(!isDefined(self.hintelem))
{
self.hintelem = newclienthudelem(self);
}
self.hintelem init_hint_hudelem(320, 220, "center", "bottom", 1.3, 1.0);
}
hint_trigger_think()
{
level endon("stop_hint");
trig = getent( "show_prone","targetname");
while(1)
{
trig waittill("trigger",ent);
ent give_hint(&"OKI3_HINT_PRONE", "crouch");
}
}
give_hint(text, stance)
{
self endon("death");
self endon("disconnect");
self thread watch_hint_stance(stance,text);
}
watch_hint_stance(stance,text)
{
self endon("death");
self endon("disconnect");
hintshown = false;
while( self getstance() != stance )
{
wait(.05);
if(!hintshown)
{
self.hintelem setText(text);
hintshown = true;
}
}
wait(.5);
self.hintelem setText("");
}
init_hint_hudelem(x, y, alignX, alignY, fontscale, alpha)
{
self.x = x;
self.y = y;
self.alignX = alignX;
self.alignY = alignY;
self.fontScale = fontScale;
self.alpha = alpha;
self.sort = 20;
//self.font = "objective";
}
/////////////////////
////
//// Protect the grass guys from all damage except from the player
////
/////////////////////////////////
//
//grass_surprise_half_shield( delay_time )
//{
//
// level endon( "stop_grass_half_shields" );
//
// self thread grass_camo_halfshield_delay( delay_time );
//
// self.pel2_real_health = self.health;
// self.health = 10000;
//
// attacker = undefined;
//
// while( self.health > 0 )
// {
//
// self waittill( "damage", amount, attacker, direction_vec, point, type, modelName, tagName );
//
// type = tolower( type );
//
// // if it's not the player, and also a bullet weapon (non-player friendlies should still be able to kill them with their grenades)
// if( !isplayer(attacker) && issubstr( type, "bullet" ) )
// {
// //iprintln( "attacked by non-player!" );
// self.health = 10000; // give back health for these things
// }
// else
// {
// self.health = self.pel2_real_health;
// self dodamage( amount, (0,0,0) );
// self.pel2_real_health = self.health;
// // put ff shield back on
// self.health = 10000;
// }
// }
//
//}
//
//
//
//grass_camo_ignore_delay( wait_time )
//{
// self endon( "death" );
//
// wait( wait_time );
// self.ignoreme = 0;
//}
//
//
//
//grass_camo_halfshield_delay( delay_time )
//{
// self endon( "death" );
//
// wait( delay_time );
// level notify( "stop_grass_half_shields" );
// self.health = self.pel2_real_health;
//}
grass_surprise_damage( which_flag )
{
level endon( which_flag );
while( 1 )
{
self waittill( "damage", amount, attacker );
// POLISH: if player throws a grenade into the grass, it should kill the dudes, not just alert them and stop their MBS
if( isplayer( attacker ) )
{
flag_set( which_flag );
}
}
}
//// Conserva's fix for prone-to-run banzai transition. should be added in _anim at some point?
//old_play_anim_end_early( the_anim, how_early )
//{
// self animscripted( "anim single", self.origin, self.angles, the_anim );
// animtime = getanimlength( the_anim );
//
// animtime -= how_early;
// wait(animtime);
//
// self stopanimscripted();
//}
/*------------------------------------
sWaittill = level notification sent out by sm to spawn a new group of guys
squadname = the name of the squad for sm to use
a,b,c = script_noteworthy value on the spawners to determine which 'squads' to use as spawners for sm
------------------------------------*/
squad_manager_think(sm_notify,tgtname,sEndon,sWaittill,squadname,a,b,c)
{
level endon(sEndon);
while(1)
{
squads = [];
squads[0] = "squad_a";
if(isDefined(b))
{
squads[1] = "squad_b";
}
if (isDefined(c))
{
squads[2] = "squad_c";
}
noteworthy = squads[randomint(squads.size)];
//turn off all spawners first
og_spawners = getspawnerarray();
for(i=0;i<og_spawners.size;i++)
{
if(isDefined(og_spawners[i].targetname) && og_spawners[i].targetname == tgtname)
{
if(isDefined(og_spawners[i].script_squadname))
{
og_spawners[i].script_squadname = undefined;
}
if(isDefined(og_spawners[i].script_noteworthy) && og_spawners[i].script_noteworthy == noteworthy)
{
og_spawners[i].script_squadname = squadname;
}
}
}
if(isDefined(sm_notify))
{
level notify(sm_notify);
}
level waittill(sWaittill);
}
}
set_goal_to_nearest()
{
self endon("death");
while(issentient(self))
{
players = get_players();
squad = getaiarray( "allies" );
combined = array_combine( players, squad );
guy = get_closest_living( self.origin, combined );
if(isDefined(guy))
{
self setgoalpos(guy.origin);
}
wait(3);
if(self.goalradius > 128)
{
self.goalradius = self.goalradius - 128;
}
}
}
#using_animtree("generic_human");
flamedeath(attacker)
{
anima[0] = %ai_flame_death_a;
anima[1] = %ai_flame_death_b;
anima[2] = %ai_flame_death_c;
anima[3] = %ai_flame_death_d;
self.deathanim = anima[randomint(anima.size)];
self thread death_flame_fx();
self dodamage(self.health + 100, self.origin,attacker);
wait(3);
self StartTanning();
}
/*------------------------------------
play some flame effects on the guys in the bunker
who burn up
------------------------------------*/
death_flame_fx()
{
tagArray = [];
tagArray[tagArray.size] = "J_Wrist_RI";
tagArray[tagArray.size] = "J_Wrist_LE";
tagArray[tagArray.size] = "J_Elbow_LE";
tagArray[tagArray.size] = "J_Elbow_RI";
tagArray[tagArray.size] = "J_Knee_RI";
tagArray[tagArray.size] = "J_Knee_LE";
tagArray[tagArray.size] = "J_Ankle_RI";
tagArray[tagArray.size] = "J_Ankle_LE";
for( i = 0; i < 3; i++ )
{
PlayFxOnTag( level._effect["flame_death1"], self, tagArray[randomint(tagArray.size)] );
PlayFxOnTag( level._effect["flame_death2"], self, "J_SpineLower" );
}
}
get_ai_by_animname(aname)
{
axis = getaiarray("allies");
allies = getaiarray("axis");
guys = [];
ai = array_combine(axis,allies);
for(i=0;i<ai.size;i++)
{
if( isDefined(ai[i]) && isDefined(ai[i].animname) && ai[i].animname == aname)
{
guys[guys.size]= ai[i];
}
}
return guys;
}
//stole this from deathanim script, except I removed the huge amount of random force that is used in that one
oki3_pop_helmet()
{
if( !isdefined( self ) )
{
return;
}
if( !isdefined( self.hatModel ) || !ModelHasPhysPreset( self.hatModel ) )
{
return;
}
// used to check self removableHat() in cod2... probably not necessary though
partName = GetPartName( self.hatModel, 0 );
origin = self GetTagOrigin( partName ); //self . origin +( 0, 0, 64 );
angles = self GetTagAngles( partName ); //( -90, 0 + randomint( 90 ), 0 + randomint( 90 ) );
oki3_helmet_launch( self.hatModel, origin, angles, self.damageDir );
hatModel = self.hatModel;
self.hatModel = undefined;
self.helmetPopper = self.attacker;
wait 0.05;
if( !isdefined( self ) )
{
return;
}
self detach( hatModel, "" );
}
oki3_helmet_launch( model, origin, angles, damageDir )
{
launchForce = damageDir;
launchForce = launchForce * randomFloatRange( 1000, 1500 );
forcex = launchForce[0];
forcey = launchForce[1];
forcez = randomFloatRange( 900, 1800 );
contactPoint = self.origin +( randomfloatrange( -1, 1 ), randomfloatrange( -1, 1 ), randomfloatrange( -1, 1 ) ) * 5;
CreateDynEntAndLaunch( model, origin, angles, contactPoint, ( forcex, forcey, forcez ) );
}
disable_player_weapons()
{
players = get_players();
for(i=0;i<players.size;i++)
{
players[i] disableweapons();
}
}
enable_player_weapons(guy)
{
wait(1);
players = get_players();
for(i=0;i<players.size;i++)
{
players[i] enableweapons();
}
}
/*------------------------------------
for fixing the outro when a player might be in last stand
when the level ends
------------------------------------*/
player_prevent_bleedout()
{
self endon( "death" );
self endon( "disconnect" );
while(1)
{
if( self maps\_laststand::player_is_in_laststand() )
{
self.bleedout_time = 1000000;
self RevivePlayer();
}
wait_network_frame();
}
}
outro_delete_grenade()
{
self waittill( "grenade_fire", what );
what Delete(); // SO THERE
}
/*------------------------------------
see if any other players are using the radio
------------------------------------*/
is_radio_available(player)
{
players = get_players();
radio_used = false;
for(i=0;i<players.size;i++)
{
if(players[i] != player && players[i] getcurrentweapon() == "air_support")
{
radio_used= true;
}
}
if(radio_used)
{
return false;
}
else
{
return true;
}
}