as released 2005-09-22

This commit is contained in:
archive 2005-09-22 00:00:00 +00:00
commit 4e9e5692d3
55 changed files with 27560 additions and 0 deletions

897
AI.c Normal file
View file

@ -0,0 +1,897 @@
void() movetarget_f;
void() t_movetarget;
void() knight_walk1;
void() wiz_guard1;
void() AngelPitch;
void(entity etemp, entity stemp, entity stemp, float dmg) T_Damage;
/*
.enemy
Will be world if not currently angry at anyone.
.movetarget
The next path spot to walk toward. If .enemy, ignore .movetarget.
When an enemy is killed, the monster will try to return to it's path.
.huntt_ime
Set to time + something when the player is in sight, but movement straight for
him is blocked. This causes the monster to use wall following code for
movement direction instead of sighting on the player.
.ideal_yaw
A yaw angle of the intended direction, which will be turned towards at up
to 45 deg / state. If the enemy is in view and hunt_time is not active,
this will be the exact line towards the enemy.
.pausetime
A monster will leave it's stand state and head towards it's .movetarget when
time > .pausetime.
walkmove(angle, speed) primitive is all or nothing
*/
//
// globals
//
float current_yaw;
float walking;
//
// when a monster becomes angry at a player, that monster will be used
// as the sight target the next frame so that monsters near that one
// will wake up even if they wouldn't have noticed the player
//
entity sight_entity;
float sight_entity_time;
float(float v) anglemod =
{
while (v >= 360)
v = v - 360;
while (v < 0)
v = v + 360;
return v;
};
/*
==============================================================================
MOVETARGET CODE
The angle of the movetarget effects standing and bowing direction, but has no effect on movement, which allways heads to the next target.
targetname
must be present. The name of this movetarget.
target
the next spot to move to. If not present, stop here for good.
pausetime
The number of seconds to spend standing or bowing for path_stand or path_bow
==============================================================================
*/
void() movetarget_f =
{
if (!self.targetname)
objerror ("monster_movetarget: no targetname");
self.solid = SOLID_TRIGGER;
self.touch = t_movetarget;
setsize (self, '-8 -8 -8', '8 8 8');
};
/*QUAKED path_corner (0.5 0.3 0) (-8 -8 -8) (8 8 8)
Monsters will continue walking towards the next target corner.
*/
void() path_corner =
{
movetarget_f ();
};
/*
=============
t_movetarget
Something has bumped into a movetarget. If it is a monster
moving towards it, change the next destination and continue.
==============
*/
void() t_movetarget =
{
local entity temp;
if (other.movetarget != self)
return;
if (other.enemy)
return; // fighting, not following a path
temp = self;
self = other;
other = temp;
if (self.classname == "xmen_rogue")
sound (self, CHAN_VOICE, "ogre/ogdrag.wav", 1, ATTN_IDLE);// play chainsaw drag sound
//dprint ("t_movetarget\n");
self.goalentity = self.movetarget = find (world, targetname, other.target);
self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin);
if (!self.movetarget)
{
self.pausetime = time + 999999;
self.th_stand ();
return;
}
};
//============================================================================
/*
=============
range
returns the range catagorization of an entity reletive to self
0 melee range, will become hostile even if back is turned
1 visibility and infront, or visibility and show hostile
2 infront and show hostile
3 only triggered by damage
=============
*/
float(entity targ) range =
{
local vector spot1, spot2;
local float r;
spot1 = self.origin + self.view_ofs;
spot2 = targ.origin + targ.view_ofs;
r = vlen (spot1 - spot2);
if (r < 80)
return RANGE_MELEE;
if (r < 400)
return RANGE_NEAR;
if (r < 1300)
return RANGE_MID;
return RANGE_FAR;
};
/*
=============
visible
returns 1 if the entity is visible to self, even if not infront ()
=============
*/
float (entity targ) visible =
{
local vector spot1, spot2;
spot1 = self.origin + self.view_ofs;
spot2 = targ.origin + targ.view_ofs;
traceline (spot1, spot2, FALSE, self); // see through other monsters
if (trace_inopen && trace_inwater)
return FALSE; // sight line crossed contents
if ((trace_fraction == 1) || (trace_ent == targ))
return TRUE;
return FALSE;
};
/*
=============
infront
returns 1 if the entity is in front (in sight) of self
=============
*/
float(entity targ) infront =
{
local vector vec;
local float dot;
makevectors (self.angles);
vec = normalize (targ.origin - self.origin);
if (self.enemy != world) { // original id sight code
dot = vec * v_forward;
if ( dot > 0.3)
{
return TRUE;
}
}
else { // X-Men: allow for sideways sighting
dot = vlen(vec + v_forward);
if ( dot > 0.75)
{
return TRUE;
}
}
return FALSE;
};
//============================================================================
/*
===========
ChangeYaw
Turns towards self.ideal_yaw at self.yaw_speed
Sets the global variable current_yaw
Called every 0.1 sec by monsters
============
*/
/*
void() ChangeYaw =
{
local float ideal, move;
//current_yaw = self.ideal_yaw;
// mod down the current angle
current_yaw = anglemod( self.angles_y );
ideal = self.ideal_yaw;
if (current_yaw == ideal)
return;
move = ideal - current_yaw;
if (ideal > current_yaw)
{
if (move > 180)
move = move - 360;
}
else
{
if (move < -180)
move = move + 360;
}
if (move > 0)
{
if (move > self.yaw_speed)
move = self.yaw_speed;
}
else
{
if (move < 0-self.yaw_speed )
move = 0-self.yaw_speed;
}
current_yaw = anglemod (current_yaw + move);
self.angles_y = current_yaw;
};
*/
//============================================================================
void() HuntTarget =
{
self.goalentity = self.enemy;
self.think = self.th_run;
self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin);
self.nextthink = time + 0.1;
SUB_AttackFinished (1); // wait a while before first attack
};
void() SightSound =
{
local float rsnd;
rsnd = random();
if (self.classname == "xmen_psylocke")
FemaleSightSound();
else if (self.classname == "xmen_storm")
FemaleSightSound();
else if (self.classname == "xmen_rogue")
FemaleSightSound();
else if (self.classname == "xmen_phoenix")
FemaleSightSound();
else if (self.classname == "xmen_wolverine")
MaleSightSound(1);
else if (self.classname == "xmen_cyclops")
MaleSightSound(2);
else if (self.classname == "xmen_beast")
MaleSightSound(1);
else if (self.classname == "xmen_bishop")
MaleSightSound(2);
else if (self.classname == "xmen_angel")
MaleSightSound(2);
else if (self.classname == "xmen_iceman")
MaleSightSound(2);
else if (self.classname == "xmen_gambit")
MaleSightSound(2);
else if (self.classname == "xmen_cannonball")
MaleSightSound(2);
};
void() FoundTarget =
{
if (self.enemy.classname == "player")
{ // let other monsters see this monster for a while
sight_entity = self;
sight_entity_time = time;
}
self.show_hostile = time + 1; // wake up other monsters
SightSound ();
HuntTarget ();
};
/*
===========
FindTarget
Self is currently not attacking anything, so try to find a target
Returns TRUE if an enemy was sighted
When a player fires a missile, the point of impact becomes a fakeplayer so
that monsters that see the impact will respond as if they had seen the
player.
To avoid spending too much time, only a single client (or fakeclient) is
checked each frame. This means multi player games will have slightly
slower noticing monsters.
============
*/
float() FindTarget =
{
local entity client;
local float r;
local vector vect;
if (self.spawnflags & SPAWNFLAG_CLONE)
return;
// if the first spawnflag bit is set, the monster will only wake up on
// really seeing the player, not another monster getting angry
// spawnflags & 3 is a big hack, because zombie crucified used the first
// spawn flag prior to the ambush flag, and I forgot about it, so the second
// spawn flag works as well
if (sight_entity_time >= time - 0.1 && !(self.spawnflags & 3) )
{
client = sight_entity;
if (client.enemy == self.enemy)
return;
}
else
{
client = checkclient ();
if (!client)
return FALSE; // current check entity isn't in PVS
}
if (client == self.enemy)
return FALSE;
if (client.flags & FL_NOTARGET)
return FALSE;
if (client.items & IT_INVISIBILITY)
return FALSE;
r = range (client);
if (r == RANGE_FAR)
return FALSE;
if (r != RANGE_MELEE) {
if (!visible (client))
return FALSE;
if (!infront(client))
return FALSE;
if (r == RANGE_NEAR)
{
if (client.show_hostile > time)
return FALSE;
}
}
// x-men: 3rd bit of spawnflag disables attacking a player on sight, unless really close
traceline(self.origin, client.origin, FALSE, self);
if ((self.spawnflags & 4) && ((vlen(self.origin - client.origin) > 96) || (trace_ent != client)))
return FALSE;
//
// got one
//
self.enemy = client;
if (self.enemy.classname != "player")
{
self.enemy = self.enemy.enemy;
if (self.enemy.classname != "player")
{
self.enemy = world;
return FALSE;
}
}
FoundTarget ();
return TRUE;
};
//=============================================================================
float(float dist) ai_forward =
{
return walkmove (self.angles_y, dist);
};
float(float dist) ai_back =
{
return walkmove ( (self.angles_y+180), dist);
};
/*
=============
ai_pain
stagger back a bit
=============
*/
void(float dist) ai_pain =
{
ai_back (dist);
/*
local float away;
away = anglemod (vectoyaw (self.origin - self.enemy.origin)
+ 180*(random()- 0.5) );
walkmove (away, dist);
*/
};
/*
=============
ai_painforward
stagger back a bit
=============
*/
void(float dist) ai_painforward =
{
walkmove (self.ideal_yaw, dist);
};
/*
=============
ai_walk
The monster is walking it's beat
=============
*/
void(float dist) ai_run;
void(float dist) ai_walk =
{
local vector mtemp;
movedist = dist;
if ((self.classname == "xmen_wolverine") &&
(self.last_health_regen < (time - 1)))
{
self.health = self.health + 2;
self.last_health_regen = time;
}
if (self.enemy == world) {
// check for noticing a player
if (FindTarget ())
return;
movetogoal (dist);
}
else { // in walking frames, but still angry at someone
walking = TRUE;
ai_run(dist);
walking = FALSE;
mtemp = self.origin - self.enemy.origin;
mtemp_z = 0;
traceline(self.origin, self.enemy.origin, TRUE, self.enemy);
if (trace_fraction < 1) // enemy is getting away, so start running
self.think = self.th_run;
if ((self.classname == "xmen_wolverine") ||
(self.classname == "xmen_storm"))
self.nextthink = time + 0.05;
}
};
/*
=============
ai_stand
The monster is staying in one place for a while, with slight angle turns
=============
*/
void() ai_stand =
{
if (self.parallize_time > time)
{
return;
}
if (FindTarget ())
return;
if (time > self.pausetime)
{
self.th_walk ();
return;
}
// change angle slightly
};
/*
=============
ai_turn
don't move, but turn towards ideal_yaw
=============
*/
void() ai_turn =
{
if (FindTarget ())
return;
ChangeYaw ();
};
//=============================================================================
/*
=============
ChooseTurn
=============
*/
void(vector dest3) ChooseTurn =
{
local vector dir, newdir;
dir = self.origin - dest3;
newdir_x = trace_plane_normal_y;
newdir_y = 0 - trace_plane_normal_x;
newdir_z = 0;
if (dir * newdir > 0)
{
dir_x = 0 - trace_plane_normal_y;
dir_y = trace_plane_normal_x;
}
else
{
dir_x = trace_plane_normal_y;
dir_y = 0 - trace_plane_normal_x;
}
dir_z = 0;
self.ideal_yaw = vectoyaw(dir);
};
/*
============
FacingIdeal
============
*/
float() FacingIdeal =
{
local float delta;
delta = anglemod(self.angles_y - self.ideal_yaw);
if (delta > 45 && delta < 315)
return FALSE;
return TRUE;
};
//=============================================================================
float() StormCheckAttack;
float() WizardCheckAttack;
float() beastCheckAttack;
float() GambitCheckAttack;
float() PsylockeCheckAttack;
float() CheckAnyAttack =
{
local float ca; // xmen cl2
if (!enemy_vis)
return;
if (self.classname == "xmen_bishop")
return SoldierCheckAttack ();
if (self.classname == "xmen_rogue")
return OgreCheckAttack ();
if (self.classname == "xmen_storm")
return StormCheckAttack ();
if (self.classname == "xmen_wolverine")
return DemonCheckAttack ();
if (self.classname == "xmen_beast")
return beastCheckAttack ();
if (self.classname == "xmen_angel")
return WizardCheckAttack ();
if (self.classname == "xmen_gambit")
return GambitCheckAttack ();
if (self.classname == "xmen_psylocke")
return PsylockeCheckAttack ();
// begin xmen (cl2)
ca = CheckAttack ();
if (self.classname == "xmen_iceman") self.count = 1;
return (ca);
// End xmen (cl2)
};
/*
=============
ai_run_melee
Turn and close until within an angle to launch a melee attack
=============
*/
void() ai_run_melee =
{
self.ideal_yaw = enemy_yaw;
ChangeYaw ();
if (FacingIdeal())
{
self.th_melee ();
self.attack_state = AS_STRAIGHT;
}
};
/*
=============
ai_run_missile
Turn in place until within an angle to launch a missile attack
=============
*/
void() ai_run_missile =
{
self.ideal_yaw = enemy_yaw;
ChangeYaw ();
if (FacingIdeal())
{
self.th_missile ();
self.attack_state = AS_STRAIGHT;
}
};
/*
=============
ai_run_slide
Strafe sideways, but stay at aproximately the same range
=============
*/
void() ai_run_slide =
{
local float ofs;
self.ideal_yaw = enemy_yaw;
ChangeYaw ();
if (self.lefty)
ofs = 90;
else
ofs = -90;
if (walkmove (self.ideal_yaw + ofs, movedist))
return;
self.lefty = 1 - self.lefty;
walkmove (self.ideal_yaw - ofs, movedist);
};
/*
=============
ai_run
The monster has an enemy it is trying to kill
=============
*/
void() skeleton_animate;
void(float dist) ai_run =
{
local vector delta, vect;
local float axis, cont;
local float direct, ang_rint, ang_floor, ang_ceil;
local entity oenemy;
if (self.spawnflags & SPAWNFLAG_CLONE)
self.th_stand();
if (self.classname == "xmen_skeleton") {
skeleton_animate();
return;
}
if (self.parallize_time > time)
{
return;
}
movedist = dist;
// see if the enemy is dead
if (self.enemy.health <= 0)
{
self.enemy = world;
// FIXME: look all around for other targets
if (self.oldenemy.health > 0)
{
self.enemy = self.oldenemy;
HuntTarget ();
}
else
{
if (self.movetarget)
self.th_walk ();
else
self.th_stand ();
return;
}
}
// check if in Lava
cont = pointcontents(self.origin);
if ((cont == CONTENT_LAVA) ||
(cont == CONTENT_SLIME)) {
T_Damage(self, world, world, 100);
}
self.show_hostile = time + 1; // wake up other monsters
// check knowledge of enemy
enemy_vis = visible(self.enemy);
if (enemy_vis)
self.search_time = time + 5;
// look for other coop players
if (coop && self.search_time < time)
{
if (FindTarget ())
return;
}
enemy_infront = infront(self.enemy);
enemy_range = range(self.enemy);
enemy_yaw = vectoyaw(self.enemy.origin - self.origin);
if (self.guard_flag) {
if (self.th_guard) {
self.th_guard();
self.guard_flag = FALSE;
return;
}
}
if (self.flags & FL_FLY) {
// do pitching
AngelPitch();
ai_face();
}
if (self.attack_state == AS_MISSILE)
{
//dprint ("ai_run_missile\n");
ai_run_missile ();
return;
}
if (self.attack_state == AS_MELEE)
{
//dprint ("ai_run_melee\n");
ai_run_melee ();
return;
}
if (CheckAnyAttack ())
return; // beginning an attack
if (self.attack_state == AS_SLIDING)
{
ai_run_slide ();
// return;
dist = dist / 2;
}
if ((self.classname == "xmen_angel")) {
if (vlen(self.origin - self.enemy.origin) < 256) {
// FIXME: check there is at least 196 units behind
vect = vectoangles(self.angles);
traceline(self.origin, self.origin - vect*196, TRUE, self);
if (trace_fraction < 1)
dist = 0;
else {
dist = dist * -1;
if (self.attack_state != AS_SLIDING)
dist = dist * 0.5;
}
}
}
if (self.flags & FL_FLY) {
// check that we haven't gone TOO close to the player, and sare sitting on their head
if (vlen(self.enemy.origin - self.origin) < 60) {
ai_back(5);
return;
}
else if (vlen(self.enemy.origin - self.origin) < 68) {
return;
}
}
// remove z_ofs (Storm)
self.origin_z = self.origin_z - self.z_ofs;
// head straight in
self.oldorigin = self.origin;
//if (self.classname == "xmen_cannonball") bprint("ai_run: movetogoal\n");
movetogoal (dist);
if ((self.origin == self.oldorigin) && (vlen(self.enemy.origin - self.origin) < 70)) {
ai_face();
}
// re-apply z_ofs (Storm)
self.origin_z = self.origin_z + self.z_ofs;
// walk if really close
if ((!walking) &&
(self.classname == "xmen_wolverine")) {
delta = self.enemy.origin - self.origin;
delta_z = 0;
if (vlen(delta) < 128)
self.think = self.th_walk;
}
if ((self.classname == "xmen_wolverine") ||
(self.classname == "xmen_storm"))
self.nextthink = time + 0.05;
};

85
AMTEST.c Normal file
View file

@ -0,0 +1,85 @@
/*~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>
~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~*/
void() test_teleport_touch;
void() tele_done;
/*QUAKED test_teleport (0 .5 .8) ?
Teleporter testing
*/
void() test_teleport =
{
precache_model ("sprites/s_aball.spr");
setsize (self, self.mins, self.maxs);
self.touch = test_teleport_touch;
self.solid = 1;
if (!self.target)
objerror ("no target\n");
};
void() test_teleport_touch =
{
local entity oldself;
other.movetype = MOVETYPE_TOSS;
// other.solid = SOLID_NOT;
other.dest = '256 -128 -128';
oldself = self;
self = other;
// SUB_CalcMove (self.dest, 200, tele_done);
self.velocity = '1000 0 0 ';
self = oldself;
};
void() tele_done =
{
self.movetype = MOVETYPE_WALK;
self.solid = SOLID_SLIDEBOX;
};
/*~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>
~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~*/
void() test_goaway;
void() test_spawn;
/*QUAKED test_fodder (0 .5 .8) ?
beating guy
*/
void() test_fodder =
{
self.nextthink = time + 3;
self.think = test_spawn;
};
void() test_spawn =
{
local entity body;
makevectors (self.angles);
body = spawn();
setmodel (body, "progs/soldier.mdl");
setorigin (body, self.origin);
body.classname = "player";
body.health = 1000;
body.frags = 0;
body.takedamage = DAMAGE_AIM;
body.solid = SOLID_SLIDEBOX;
body.movetype = MOVETYPE_WALK;
body.show_hostile = 0;
body.weapon = 1;
body.velocity = v_forward * 200;
body.nextthink = time + 5;
body.think = test_goaway;
self.nextthink = time + 3;
self.think = test_spawn;
};
void() test_goaway =
{
remove (self);
};

143
BUTTONS.c Normal file
View file

@ -0,0 +1,143 @@
// button and multiple button
void() button_wait;
void() button_return;
void() button_wait =
{
self.state = STATE_TOP;
self.nextthink = self.ltime + self.wait;
self.think = button_return;
activator = self.enemy;
SUB_UseTargets();
self.frame = 1; // use alternate textures
};
void() button_done =
{
self.state = STATE_BOTTOM;
};
void() button_return =
{
self.state = STATE_DOWN;
SUB_CalcMove (self.pos1, self.speed, button_done);
self.frame = 0; // use normal textures
if (self.health)
self.takedamage = DAMAGE_YES; // can be shot again
};
void() button_blocked =
{ // do nothing, just don't ome all the way back out
};
void() button_fire =
{
if (self.state == STATE_UP || self.state == STATE_TOP)
return;
//bprint("button triggered\n");
sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
self.state = STATE_UP;
SUB_CalcMove (self.pos2, self.speed, button_wait);
};
void() button_use =
{
self.enemy = activator;
button_fire ();
};
void() button_touch =
{
if (other.classname != "player")
return;
self.enemy = other;
button_fire ();
};
void() button_killed =
{
self.enemy = damage_attacker;
self.health = self.max_health;
self.takedamage = DAMAGE_NO; // wil be reset upon return
button_fire ();
};
/*QUAKED func_button (0 .5 .8) ?
When a button is touched, it moves some distance in the direction of it's angle, triggers all of it's targets, waits some time, then returns to it's original position where it can be triggered again.
"angle" determines the opening direction
"target" all entities with a matching targetname will be used
"speed" override the default 40 speed
"wait" override the default 1 second wait (-1 = never return)
"lip" override the default 4 pixel lip remaining at end of move
"health" if set, the button must be killed instead of touched
"sounds"
0) steam metal
1) wooden clunk
2) metallic click
3) in-out
*/
void() func_button =
{
local float gtemp, ftemp;
if (self.sounds == 0)
{
precache_sound ("buttons/airbut1.wav");
self.noise = "buttons/airbut1.wav";
}
if (self.sounds == 1)
{
precache_sound ("buttons/switch21.wav");
self.noise = "buttons/switch21.wav";
}
if (self.sounds == 2)
{
precache_sound ("buttons/switch02.wav");
self.noise = "buttons/switch02.wav";
}
if (self.sounds == 3)
{
precache_sound ("buttons/switch04.wav");
self.noise = "buttons/switch04.wav";
}
SetMovedir ();
self.movetype = MOVETYPE_PUSH;
self.solid = SOLID_BSP;
setmodel (self, self.model);
self.blocked = button_blocked;
self.use = button_use;
if (self.health)
{
self.max_health = self.health;
self.th_die = button_killed;
self.takedamage = DAMAGE_YES;
}
else
self.touch = button_touch;
if (!self.speed)
self.speed = 40;
if (!self.wait)
self.wait = 1;
if (!self.lip)
self.lip = 4;
self.state = STATE_BOTTOM;
self.pos1 = self.origin;
self.pos2 = self.pos1 + self.movedir*(fabs(self.movedir*self.size) - self.lip);
};

2032
CLIENT.c Normal file

File diff suppressed because it is too large Load diff

424
COMBAT.c Normal file
View file

@ -0,0 +1,424 @@
void() T_MissileTouch;
void() info_player_start;
void(entity targ, entity attacker) ClientObituary;
void() monster_death_use;
//============================================================================
/*
============
CanDamage
Returns true if the inflictor can directly damage the target. Used for
explosions and melee attacks.
============
*/
float(entity targ, entity inflictor) CanDamage =
{
// X-Men: Lightning Bolts cannot harm Storm
if ((inflictor.classname == "info_lightning") &&
((targ.classname == "xmen_storm") || (targ.classname == "apocalypse_small") || (targ.classname == "apoc_torso"))) {
return FALSE;
}
// end
// bmodels need special checking because their origin is 0,0,0
if (targ.movetype == MOVETYPE_PUSH)
{
traceline(inflictor.origin, 0.5 * (targ.absmin + targ.absmax), TRUE, self);
if (trace_fraction == 1)
return TRUE;
if (trace_ent == targ)
return TRUE;
return FALSE;
}
traceline(inflictor.origin, targ.origin, TRUE, self);
if (trace_fraction == 1)
return TRUE;
traceline(inflictor.origin, targ.origin + '15 15 0', TRUE, self);
if (trace_fraction == 1)
return TRUE;
traceline(inflictor.origin, targ.origin + '-15 -15 0', TRUE, self);
if (trace_fraction == 1)
return TRUE;
traceline(inflictor.origin, targ.origin + '-15 15 0', TRUE, self);
if (trace_fraction == 1)
return TRUE;
traceline(inflictor.origin, targ.origin + '15 -15 0', TRUE, self);
if (trace_fraction == 1)
return TRUE;
return FALSE;
};
/*
============
Killed
============
*/
void(entity targ, entity attacker) Killed =
{
local entity oself;
oself = self;
self = targ;
if (self.health < -99)
self.health = -99; // don't let sbar look bad if a player
if (self.movetype == MOVETYPE_PUSH || self.movetype == MOVETYPE_NONE)
{ // doors, triggers, etc
self.th_die ();
self = oself;
return;
}
self.enemy = attacker;
// check for Apocalypse laugh
if ((attacker.classname == "xmen_apocalypse") &&
(targ.classname == "player")) {
sound(self, CHAN_VOICE, "apoc/alaugh.wav", 1, ATTN_NONE);
}
// bump the monster counter
if ((self.flags & FL_MONSTER) && (!(self.spawnflags & SPAWNFLAG_CLONE)) && (self.classname != "xmen_wolverine") && !(self.x_flags & X_MEGA_HIT) && (self.classname != "xmen_sinister") && (self.classname != "xmen_apocalypse") && (self.classname != "apocalypse_small") && ((self.classname != "xmen_wolverine")))
{
self.angles_z = 0;
if (!(self.spawnflags & SPAWNFLAG_CLONE)) {
killed_monsters = killed_monsters + 1;
WriteByte (MSG_ALL, SVC_KILLEDMONSTER);
}
self.skin = 3; // death skin
}
ClientObituary(self, attacker);
self.takedamage = DAMAGE_NO;
self.touch = SUB_Null;
if (self.classname != "xmen_techdude")
monster_death_use();
self.th_die ();
self = oself;
};
/*
============
T_Damage
The damage is coming from inflictor, but get mad at attacker
This should be the only function that ever reduces health.
============
*/
void(entity e) skeleton_morph;
void(entity e) iceman_melt;
void() phoenix_xattc12;
void() player_run;
void() DM_PhoenixBeamEnd;
void(entity targ, entity inflictor, entity attacker, float damage) T_Damage=
{
local vector dir;
local entity oldself;
local float save;
local float take;
//bprint("T_Damage\n");
damage_inflictor = inflictor;
// Apocalype: if hurting torso entity, change target to owner
if (targ.classname == "apoc_torso") {
targ = targ.owner;
}
// if (((targ.flags & FL_MONSTER) || (targ.classname == "player")) && (targ.health <= 0))
// return;
if (!targ.takedamage)
return;
// don't hurt clones of same type
if ((attacker.flags & FL_MONSTER) && (attacker.classname == targ.classname))
return;
if (((inflictor.classname == "proximity_ball") || (inflictor.classname == "prox_missile")) &&
(targ.classname == "xmen_bishop"))
return;
// used by buttons and triggers to set activator for target firing
damage_attacker = attacker;
if ((targ.model == "progs/skel.mdl") && (damage_attacker.weapon == IT_SUPER_NAILGUN)) {
// self.health = 1;
return;
}
// check for quad damage powerup on the attacker
if (attacker.super_damage_finished > time)
damage = damage * 2;
// Bishop not get hurt as much by Plasma and NERD
if ((targ.character == CHAR_BISHOP) &&
((inflictor.classname == "flameball") ||
(inflictor.classname == "prox_missile") ||
(inflictor.classname == "proximity_ball"))) {
damage = damage / 2;
}
// save damage based on the target's armor level
save = ceil(targ.armortype*damage);
if (save >= targ.armorvalue)
{
save = targ.armorvalue;
targ.armortype = 0; // lost all armor
targ.items = targ.items - (targ.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3));
}
targ.armorvalue = targ.armorvalue - save;
take = ceil(damage-save);
// add to the damage total for clients, which will be sent as a single
// message at the end of the frame
// FIXME: remove after combining shotgun blasts?
if (targ.flags & FL_CLIENT)
{
targ.dmg_take = targ.dmg_take + take;
targ.dmg_save = targ.dmg_save + save;
targ.dmg_inflictor = inflictor;
}
// figure momentum add
if ( (inflictor != world) && (targ.movetype == MOVETYPE_WALK) )
{
dir = targ.origin - (inflictor.absmin + inflictor.absmax) * 0.5;
dir = normalize(dir);
if (!deathmatch)
dir_z = 0;
targ.velocity = targ.velocity + (dir*damage*8);
}
// check for godmode or invincibility
if (targ.flags & FL_GODMODE) {
// first check for Pheonix abort while in Tractor Beam
if (((targ.classname == "xmen_phoenix") || (targ.character == CHAR_PHOENIX)) && (targ.start_tractor_time < (time - 0.75))) {
if ((targ.character == CHAR_PHOENIX) && (targ.move_ent != world)) {
oldself = self;
self = targ;
DM_PhoenixBeamEnd();
self = oldself;
}
if (targ.classname == "xmen_phoenix") {
targ.enemy.x_flags = targ.enemy.x_flags - (targ.enemy.x_flags & X_TRACTOR_BEAM_HOLD);
targ.enemy.velocity = normalize(targ.enemy.origin - targ.origin) * 250 + '0 0 100';
targ.think = phoenix_xattc12;
}
}
return;
}
// Check for DM Angel wing defense
if ((targ.x_flags & X_ANGEL_DEFENSE) && ((inflictor.classname == "guided_rocket") || (inflictor.classname == "orb")))
return;
if (targ.invincible_finished >= time)
{
if (self.invincible_sound < time)
{
sound (targ, CHAN_ITEM, "items/protect3.wav", 1, ATTN_NORM);
self.invincible_sound = time + 2;
}
return;
}
// team play damage avoidance
if ( (teamplay == 1) && (targ.team > 0)&&(targ.team == attacker.team) )
return;
//bprint("doing damage..\n");
// do the damage
targ.health = targ.health - take;
if ((targ.classname == "player") && (targ.armorvalue <= 0) && (targ.health < 50)) {
if (attacker.weapon == IT_SUPER_NAILGUN) {
if (targ.model != "progs/skel.mdl") {
targ.health = 1;
targ.modelindex = index_skeleton;
targ.weaponmodel = "";
targ.think = player_run;
centerprint(targ, "You have been torched!");
}
}
}
if (targ.health <= 0)
{
if (deathmatch || coop) {
if (attacker.weapon == IT_SUPER_NAILGUN) { // skeleton time!
// targ.health = 1;
targ.modelindex = index_skeleton;
targ.weaponmodel = "";
targ.think = player_run;
centerprint(targ, "You have been torched!");
}
else
Killed (targ, attacker);
}
else if ((attacker.weapon == IT_SUPER_NAILGUN) && (targ.classname != "xmen_wolverine") && ((targ.flags & FL_MONSTER) || (targ.classname == "xmen_techdude")) && (targ.classname != "xmen_sinister") && (targ.classname != "apocalypse_small")) {
if ((targ.classname != "xmen_iceman") ) {
if (targ.model != "progs/skel.mdl")
skeleton_morph(targ);
}
else
iceman_melt(targ);
}
else
Killed (targ, attacker);
return;
}
else {
SetDamageSkin(targ);
}
// react to the damage
oldself = self;
self = targ;
if ( (self.parallize_time < time) && (self.flags & FL_MONSTER) && (attacker != world) && !(attacker.flags & FL_MONSTER) && (!(self.spawnflags & SPAWNFLAG_CLONE)))
{
// get mad unless of the same class (except for soldiers)
if (self != attacker && attacker != self.enemy)
{
if (self.classname != attacker.classname)
{
if (self.enemy.classname == "player") {
self.oldenemy = self.enemy;
}
// bosses only attack player
if ((self.classname != "xmen_apocalypse") || (self.classname != "apocalypse_small") || (self.classname != "xmen_sinister")) {
if (attacker.classname == "player") {
self.enemy = attacker;
FoundTarget ();
}
}
else { // other monsters attack anything
self.enemy = attacker;
FoundTarget ();
}
}
}
}
if (self.th_pain)
{
if ((!(self.weapon_flags & W_RELOADING)) && !(self.change_weapon_status)) {
self.th_pain (attacker, take);
// nightmare mode monsters don't go into pain frames often
if (skill == 3)
self.pain_finished = time + 5;
}
}
self = oldself;
};
/*
============
T_RadiusDamage
============
*/
void(entity inflictor, entity attacker, float damage, entity ignore) T_RadiusDamage =
{
local float points;
local entity head;
local vector org;
head = findradius(inflictor.origin, damage+40);
while (head)
{
if (head != ignore)
{
if (head.takedamage)
{
org = head.origin + (head.mins + head.maxs)*0.5;
points = 0.5*vlen (inflictor.origin - org);
if (points < 0)
points = 0;
points = damage - points;
if (head == attacker)
points = points * 0.5;
if (points > 0)
{
if (CanDamage (head, inflictor))
{ // shambler takes half damage from all explosions
T_Damage (head, inflictor, attacker, points);
}
}
}
}
head = head.chain;
}
};
/*
============
T_BeamDamage
============
*/
void(entity attacker, float damage) T_BeamDamage =
{
local float points;
local entity head;
head = findradius(attacker.origin, damage+40);
while (head)
{
if (head.takedamage)
{
points = 0.5*vlen (attacker.origin - head.origin);
if (points < 0)
points = 0;
points = damage - points;
if (head == attacker)
points = points * 0.5;
if (points > 0)
{
if (CanDamage (head, attacker))
{
if (head.classname == "xmen_storm")
T_Damage (head, attacker, attacker, points*0.5);
else
T_Damage (head, attacker, attacker, points);
}
}
}
head = head.chain;
}
};

705
DEFS.c Normal file
View file

@ -0,0 +1,705 @@
/*
==============================================================================
SOURCE FOR GLOBALVARS_T C STRUCTURE
==============================================================================
*/
//
// system globals
//
entity self;
entity other;
entity world;
float time;
float frametime;
float force_retouch; // force all entities to touch triggers
// next frame. this is needed because
// non-moving things don't normally scan
// for triggers, and when a trigger is
// created (like a teleport trigger), it
// needs to catch everything.
// decremented each frame, so set to 2
// to guarantee everything is touched
string mapname;
float deathmatch;
float coop;
float teamplay;
float serverflags; // propagated from level to level, used to
// keep track of completed episodes
float total_secrets;
float total_monsters;
float found_secrets; // number of secrets found
float killed_monsters; // number of monsters killed
// spawnparms are used to encode information about clients across server
// level changes
float parm1, parm2, parm3, parm4, parm5, parm6, parm7, parm8, parm9, parm10, parm11, parm12, parm13, parm14, parm15, parm16;
//
// global variables set by built in functions
//
vector v_forward, v_up, v_right; // set by makevectors()
// set by traceline / tracebox
float trace_allsolid;
float trace_startsolid;
float trace_fraction;
vector trace_endpos;
vector trace_plane_normal;
float trace_plane_dist;
entity trace_ent;
float trace_inopen;
float trace_inwater;
entity msg_entity; // destination of single entity writes
//
// required prog functions
//
void() main; // only for testing
void() StartFrame;
void() PlayerPreThink;
void() PlayerPostThink;
void() ClientKill;
void() ClientConnect;
void() PutClientInServer; // call after setting the parm1... parms
void() ClientDisconnect;
void() SetNewParms; // called when a client first connects to
// a server. sets parms so they can be
// saved off for restarts
void() SetChangeParms; // call to set parms for self so they can
// be saved for a level transition
//================================================
void end_sys_globals; // flag for structure dumping
//================================================
/*
==============================================================================
SOURCE FOR ENTVARS_T C STRUCTURE
==============================================================================
*/
//
// system fields (*** = do not set in prog code, maintained by C code)
//
.float modelindex; // *** model index in the precached list
.vector absmin, absmax; // *** origin + mins / maxs
.float ltime; // local time for entity
.float movetype;
.float solid;
.vector origin; // ***
.vector oldorigin; // ***
.vector velocity;
.vector angles;
.vector avelocity;
.vector punchangle; // temp angle adjust from damage or recoil
.string classname; // spawn function
.string model;
.float frame;
.float skin;
.float effects;
.vector mins, maxs; // bounding box extents reletive to origin
.vector size; // maxs - mins
.void() touch;
.void() use;
.void() think;
.void() blocked; // for doors or plats, called when can't push other
.float nextthink;
.entity groundentity;
// stats
.float health;
.float frags;
.float weapon; // one of the SHOTGUN, etc flags
.string weaponmodel;
.float weaponframe;
.float currentammo;
.float ammo_shells, ammo_nails, ammo_rockets, ammo_cells;
.float items; // bit flags
.float takedamage;
.entity chain;
.float deadflag;
.vector view_ofs; // add to origin to get eye point
.float button0; // fire
.float button1; // use
.float button2; // jump
.float impulse; // weapon changes
.float fixangle;
.vector v_angle; // view / targeting angle for players
.float idealpitch; // calculated pitch angle for lookup up slopes
.string netname;
.entity enemy;
.float flags;
.float colormap;
.float team;
.float max_health; // players maximum health is stored here
.float teleport_time; // don't back up
.float armortype; // save this fraction of incoming damage
.float armorvalue;
.float waterlevel; // 0 = not in, 1 = feet, 2 = wast, 3 = eyes
.float watertype; // a contents value
.float ideal_yaw;
.float yaw_speed;
.entity aiment;
.entity goalentity; // a movetarget or an enemy
.float spawnflags;
.string target;
.string targetname;
// damage is accumulated through a frame. and sent as one single
// message, so the super shotgun doesn't generate huge messages
.float dmg_take;
.float dmg_save;
.entity dmg_inflictor;
.entity owner; // who launched a missile
.vector movedir; // mostly for doors, but also used for waterjump
.string message; // trigger messages
.float sounds; // either a cd track number or sound number
.string noise, noise1, noise2, noise3; // contains names of wavs to play
//================================================
void end_sys_fields; // flag for structure dumping
//================================================
.float respawn_time; // used for Wolvie/Demon respawn
/*
==============================================================================
VARS NOT REFERENCED BY C CODE
==============================================================================
*/
//
// constants
//
float FALSE = 0;
float TRUE = 1;
// edict.flags
float FL_FLY = 1;
float FL_SWIM = 2;
float FL_CLIENT = 8; // set for all client edicts
float FL_INWATER = 16; // for enter / leave water splash
float FL_MONSTER = 32;
float FL_GODMODE = 64; // player cheat
float FL_NOTARGET = 128; // player cheat
float FL_ITEM = 256; // extra wide size for bonus items
float FL_ONGROUND = 512; // standing on something
float FL_PARTIALGROUND = 1024; // not all corners are valid
float FL_WATERJUMP = 2048; // player jumping out of water
float FL_JUMPRELEASED = 4096; // for jump debouncing
float FL_FLAMEON = 8192; // set when flamethrower is ON
// edict.movetype values
float MOVETYPE_NONE = 0; // never moves
//float MOVETYPE_ANGLENOCLIP = 1;
//float MOVETYPE_ANGLECLIP = 2;
float MOVETYPE_WALK = 3; // players only
float MOVETYPE_STEP = 4; // discrete, not real time unless fall
float MOVETYPE_FLY = 5;
float MOVETYPE_TOSS = 6; // gravity
float MOVETYPE_PUSH = 7; // no clip to world, push and crush
float MOVETYPE_NOCLIP = 8;
float MOVETYPE_FLYMISSILE = 9; // fly with extra size against monsters
float MOVETYPE_BOUNCE = 10;
float MOVETYPE_BOUNCEMISSILE = 11; // bounce with extra size
// edict.solid values
float SOLID_NOT = 0; // no interaction with other objects
float SOLID_TRIGGER = 1; // touch on edge, but not blocking
float SOLID_BBOX = 2; // touch on edge, block
float SOLID_SLIDEBOX = 3; // touch on edge, but not an onground
float SOLID_BSP = 4; // bsp clip, touch on edge, block
// range values
float RANGE_MELEE = 0;
float RANGE_NEAR = 1;
float RANGE_MID = 2;
float RANGE_FAR = 3;
// deadflag values
float DEAD_NO = 0;
float DEAD_DYING = 1;
float DEAD_DEAD = 2;
float DEAD_RESPAWNABLE = 3;
// takedamage values
float DAMAGE_NO = 0;
float DAMAGE_YES = 1;
float DAMAGE_AIM = 2;
// items
float IT_AXE = 4096;
float IT_SHOTGUN = 1;
float IT_SUPER_SHOTGUN = 2;
float IT_NAILGUN = 4;
float IT_SUPER_NAILGUN = 8;
float IT_GRENADE_LAUNCHER = 16;
float IT_ROCKET_LAUNCHER = 32;
float IT_LIGHTNING = 64;
float IT_SPECIAL_WEAPON = 128;
float IT_SHELLS = 256;
float IT_NAILS = 512;
float IT_ROCKETS = 1024;
float IT_CELLS = 2048;
float IT_ARMOR1 = 8192;
float IT_ARMOR2 = 16384;
float IT_ARMOR3 = 32768;
float IT_SUPERHEALTH = 65536;
float IT_KEY1 = 131072;
float IT_KEY2 = 262144;
float IT_INVISIBILITY = 524288;
float IT_INVULNERABILITY = 1048576;
float IT_SUIT = 2097152;
float IT_QUAD = 4194304;
// point content values
float CONTENT_EMPTY = -1;
float CONTENT_SOLID = -2;
float CONTENT_WATER = -3;
float CONTENT_SLIME = -4;
float CONTENT_LAVA = -5;
float CONTENT_SKY = -6;
float STATE_TOP = 0;
float STATE_BOTTOM = 1;
float STATE_UP = 2;
float STATE_DOWN = 3;
vector VEC_ORIGIN = '0 0 0';
vector VEC_HULL_MIN = '-16 -16 -24';
vector VEC_HULL_MAX = '16 16 32';
vector VEC_HULL2_MIN = '-32 -32 -24';
vector VEC_HULL2_MAX = '32 32 64';
// protocol bytes
float SVC_TEMPENTITY = 23;
float SVC_KILLEDMONSTER = 27;
float SVC_FOUNDSECRET = 28;
float SVC_INTERMISSION = 30;
float SVC_FINALE = 31;
float SVC_CDTRACK = 32;
float SVC_SELLSCREEN = 33;
float TE_SPIKE = 0;
float TE_SUPERSPIKE = 1;
float TE_GUNSHOT = 2;
float TE_EXPLOSION = 3;
float TE_TAREXPLOSION = 4;
float TE_LIGHTNING1 = 5;
float TE_LIGHTNING2 = 6;
float TE_WIZSPIKE = 7;
float TE_KNIGHTSPIKE = 8;
float TE_LIGHTNING3 = 9;
float TE_LAVASPLASH = 10;
float TE_TELEPORT = 11;
// sound channels
// channel 0 never willingly overrides
// other channels (1-7) allways override a playing sound on that channel
float CHAN_AUTO = 0;
float CHAN_WEAPON = 1;
float CHAN_VOICE = 2;
float CHAN_ITEM = 3;
float CHAN_BODY = 4;
float ATTN_NONE = 0;
float ATTN_NORM = 1;
float ATTN_IDLE = 2;
float ATTN_STATIC = 3;
// update types
float UPDATE_GENERAL = 0;
float UPDATE_STATIC = 1;
float UPDATE_BINARY = 2;
float UPDATE_TEMP = 3;
// entity effects
float EF_BRIGHTFIELD = 1;
float EF_MUZZLEFLASH = 2;
float EF_BRIGHTLIGHT = 4;
float EF_DIMLIGHT = 8;
// messages
float MSG_BROADCAST = 0; // unreliable to all
float MSG_ONE = 1; // reliable to one (msg_entity)
float MSG_ALL = 2; // reliable to all
float MSG_INIT = 3; // write to the init string
//================================================
//
// globals
//
float movedist;
float gameover; // set when a rule exits
string string_null; // null string, nothing should be held here
float empty_float;
entity newmis; // launch_spike sets this after spawning it
entity activator; // the entity that activated a trigger or brush
entity damage_attacker; // set by T_Damage
float framecount;
float skill;
float intermission_running;
float intermission_exittime;
//================================================
//
// world fields (FIXME: make globals)
//
.string wad;
.string map;
.float worldtype; // 0=medieval 1=metal 2=base
//================================================
.string killtarget;
//
// quakeed fields
//
.float light_lev; // not used by game, but parsed by light util
.float style;
//
// monster ai
//
.void() th_stand;
.void() th_walk;
.void() th_run;
.void() th_missile;
.void() th_melee;
.void(entity attacker, float damage) th_pain;
.void() th_die;
.entity oldenemy; // mad at this player before taking damage
.float speed;
.float lefty;
.float search_time;
.float attack_state;
float AS_STRAIGHT = 1;
float AS_SLIDING = 2;
float AS_MELEE = 3;
float AS_MISSILE = 4;
//
// player only fields
//
.float walkframe;
.float attack_finished;
.float pain_finished;
.float invincible_finished;
.float invisible_finished;
.float super_damage_finished;
.float radsuit_finished;
.float invincible_time, invincible_sound;
.float invisible_time, invisible_sound;
.float super_time, super_sound;
.float rad_time;
.float fly_sound;
.float axhitme;
.float show_hostile; // set to time+0.2 whenever a client fires a
// weapon or takes damage. Used to alert
// monsters that otherwise would let the player go
.float jump_flag; // player jump flag
.float swim_flag; // player swimming sound flag
.float air_finished; // when time > air_finished, start drowning
.float bubble_count; // keeps track of the number of bubbles
.string deathtype; // keeps track of how the player died
//
// object stuff
//
.string mdl;
.vector mangle; // angle at start
.vector oldorigin; // only used by secret door
.float t_length, t_width;
//
// doors, etc
//
.vector dest, dest1, dest2;
.float wait; // time from firing to restarting
.float delay; // time from activation to firing
.entity trigger_field; // door's trigger entity
.string noise4;
//
// monsters
//
.float pausetime;
.entity movetarget;
// x-men monsters
.float last_health_regen;
.float last_guided_search;
// x-men environmental stuff
.float last_blood_think;
//
// doors
//
.float aflag;
.float dmg; // damage done by door when hit
//
// misc
//
.float cnt; // misc flag
//
// subs
//
.void() think1;
.vector finaldest, finalangle;
//
// triggers
//
.float count; // for counting triggers
//
// plats / doors / buttons
//
.float lip;
.float state;
.vector pos1, pos2; // top and bottom positions
.float height;
//
// sounds
//
.float waitmin, waitmax;
.float distance;
.float volume;
//===========================================================================
//
// builtin functions
//
void(vector ang) makevectors = #1; // sets v_forward, etc globals
void(entity e, vector o) setorigin = #2;
void(entity e, string m) setmodel = #3; // set movetype and solid first
void(entity e, vector min, vector max) setsize = #4;
// #5 was removed
void() break = #6;
float() random = #7; // returns 0 - 1
void(entity e, float chan, string samp, float vol, float atten) sound = #8;
vector(vector v) normalize = #9;
void(string e) error = #10;
void(string e) objerror = #11;
float(vector v) vlen = #12;
float(vector v) vectoyaw = #13;
entity() spawn = #14;
void(entity e) remove = #15;
// sets trace_* globals
// nomonsters can be:
// An entity will also be ignored for testing if forent == test,
// forent->owner == test, or test->owner == forent
// a forent of world is ignored
void(vector v1, vector v2, float nomonsters, entity forent) traceline = #16;
entity() checkclient = #17; // returns a client to look for
entity(entity start, .string fld, string match) find = #18;
string(string s) precache_sound = #19;
string(string s) precache_model = #20;
void(entity client, string s)stuffcmd = #21;
entity(vector org, float rad) findradius = #22;
void(string s) bprint = #23;
void(entity client, string s) sprint = #24;
void(string s) dprint = #25;
string(float f) ftos = #26;
string(vector v) vtos = #27;
void() coredump = #28; // prints all edicts
void() traceon = #29; // turns statment trace on
void() traceoff = #30;
void(entity e) eprint = #31; // prints an entire edict
float(float yaw, float dist) walkmove = #32; // returns TRUE or FALSE
// #33 was removed
float(float yaw, float dist) droptofloor= #34; // TRUE if landed on floor
void(float style, string value) lightstyle = #35;
float(float v) rint = #36; // round to nearest int
float(float v) floor = #37; // largest integer <= v
float(float v) ceil = #38; // smallest integer >= v
// #39 was removed
float(entity e) checkbottom = #40; // true if self is on ground
float(vector v) pointcontents = #41; // returns a CONTENT_*
// #42 was removed
float(float f) fabs = #43;
vector(entity e, float speed) aim = #44; // returns the shooting vector
float(string s) cvar = #45; // return cvar.value
void(string s) localcmd = #46; // put string into local que
entity(entity e) nextent = #47; // for looping through all ents
void(vector o, vector d, float color, float count) particle = #48;// start a particle effect
void() ChangeYaw = #49; // turn towards self.ideal_yaw
// at self.yaw_speed
// #50 was removed
vector(vector v) vectoangles = #51;
//
// direct client message generation
//
void(float to, float f) WriteByte = #52;
void(float to, float f) WriteChar = #53;
void(float to, float f) WriteShort = #54;
void(float to, float f) WriteLong = #55;
void(float to, float f) WriteCoord = #56;
void(float to, float f) WriteAngle = #57;
void(float to, string s) WriteString = #58;
void(float to, entity s) WriteEntity = #59;
//
// broadcast client message generation
//
// void(float f) bWriteByte = #59;
// void(float f) bWriteChar = #60;
// void(float f) bWriteShort = #61;
// void(float f) bWriteLong = #62;
// void(float f) bWriteCoord = #63;
// void(float f) bWriteAngle = #64;
// void(string s) bWriteString = #65;
// void(entity e) bWriteEntity = #66;
void(float step) movetogoal = #67;
string(string s) precache_file = #68; // no effect except for -copy
void(entity e) makestatic = #69;
void(string s) changelevel = #70;
//#71 was removed
void(string var, string val) cvar_set = #72; // sets cvar.value
void(entity client, string s) do_centerprint = #73; // sprint, but in middle
void(vector pos, string samp, float vol, float atten) ambientsound = #74;
string(string s) precache_model2 = #75; // registered version only
string(string s) precache_sound2 = #76; // registered version only
string(string s) precache_file2 = #77; // registered version only
void(entity e) setspawnparms = #78; // set parm1... to the
// values at level start
// for coop respawn
//============================================================================
//
// subs.qc
//
void(vector tdest, float tspeed, void() func) SUB_CalcMove;
void(entity ent, vector tdest, float tspeed, void() func) SUB_CalcMoveEnt;
void(vector destangle, float tspeed, void() func) SUB_CalcAngleMove;
void() SUB_CalcMoveDone;
void() SUB_CalcAngleMoveDone;
void() SUB_Null;
void() SUB_UseTargets;
void() SUB_Remove;
//
// combat.qc
//
void(entity targ, entity inflictor, entity attacker, float damage) T_Damage;
float (entity e, float healamount, float ignore) T_Heal; // health function
float(entity targ, entity inflictor) CanDamage;

834
DOORS.c Normal file
View file

@ -0,0 +1,834 @@
float DOOR_START_OPEN = 1;
float DOOR_DONT_LINK = 4;
float DOOR_GOLD_KEY = 8;
float DOOR_SILVER_KEY = 16;
float DOOR_TOGGLE = 32;
/*
Doors are similar to buttons, but can spawn a fat trigger field around them
to open without a touch, and they link together to form simultanious
double/quad doors.
Door.owner is the master door. If there is only one door, it points to itself.
If multiple doors, all will point to a single one.
Door.enemy chains from the master door through all doors linked in the chain.
*/
/*
=============================================================================
THINK FUNCTIONS
=============================================================================
*/
void() door_go_down;
void() door_go_up;
void() door_blocked =
{
T_Damage (other, self, self, self.dmg);
// if a door has a negative wait, it would never come back if blocked,
// so let it just squash the object to death real fast
if (self.wait >= 0)
{
if (self.state == STATE_DOWN)
door_go_up ();
else
door_go_down ();
}
};
void() door_hit_top =
{
sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
self.state = STATE_TOP;
if (self.spawnflags & DOOR_TOGGLE)
return; // don't come down automatically
self.think = door_go_down;
self.nextthink = self.ltime + self.wait;
};
void() door_hit_bottom =
{
sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
self.state = STATE_BOTTOM;
};
void() door_go_down =
{
sound (self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
if (self.max_health)
{
self.takedamage = DAMAGE_YES;
self.health = self.max_health;
}
self.state = STATE_DOWN;
SUB_CalcMove (self.pos1, self.speed, door_hit_bottom);
};
void() door_go_up =
{
if (self.state == STATE_UP)
return; // allready going up
if (self.state == STATE_TOP)
{ // reset top wait time
self.nextthink = self.ltime + self.wait;
return;
}
sound (self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
self.state = STATE_UP;
SUB_CalcMove (self.pos2, self.speed, door_hit_top);
SUB_UseTargets();
};
/*
=============================================================================
ACTIVATION FUNCTIONS
=============================================================================
*/
void() door_fire =
{
local entity oself;
local entity starte;
if (self.owner != self)
objerror ("door_fire: self.owner != self");
// play use key sound
if (self.items)
sound (self, CHAN_VOICE, self.noise4, 1, ATTN_NORM);
self.message = string_null; // no more message
oself = self;
if (self.spawnflags & DOOR_TOGGLE)
{
if (self.state == STATE_UP || self.state == STATE_TOP)
{
starte = self;
do
{
door_go_down ();
self = self.enemy;
} while ( (self != starte) && (self != world) );
self = oself;
return;
}
}
// trigger all paired doors
starte = self;
do
{
door_go_up ();
self = self.enemy;
} while ( (self != starte) && (self != world) );
self = oself;
};
float() avatar_door =
{
local entity spot;
local float cyc;
cyc = 50;
spot = world;
while (cyc > 1)
{
spot = find (spot, classname, "door");
if (spot) {
if ((spot != self) && (spot.frags > 0))
cyc = 0;
}
else {
bprint("avatar_door: Unable to locate matching door\n");
return;
}
}
if ((self.state == 0) && (spot.state == 0))
{
local entity oself;
spot.message = "";
spot.owner.message = "";
spot.enemy.message = "";
oself = self;
self = spot.owner;
door_fire ();
self = oself;
}
};
void() elevator_door_think =
{
local entity lift, corner;
// door has been touched, keep checking to see if lift has arrived
corner = find(world, targetname, self.target);
};
void() door_use =
{
local entity oself;
if (self.frags > 0)
{
avatar_door();
if (self.state != 1)
return;
}
self.message = ""; // door message are for touch only
self.owner.message = "";
self.enemy.message = "";
oself = self;
self = self.owner;
door_fire ();
self = oself;
};
void() door_trigger_touch =
{
if (other.health <= 0)
return;
if (time < self.attack_finished)
return;
self.attack_finished = time + 1;
activator = other;
self = self.owner;
door_use ();
};
void() door_killed =
{
local entity oself;
oself = self;
self = self.owner;
self.health = self.max_health;
self.takedamage = DAMAGE_NO; // wil be reset upon return
door_use ();
self = oself;
};
/*
================
door_touch
Prints messages and opens key doors
================
*/
void() door_touch =
{
if (other.classname != "player")
return;
if (self.owner.attack_finished > time)
return;
self.owner.attack_finished = time + 2;
if (self.owner.message != "")
{
centerprint (other, self.owner.message);
sound (other, CHAN_VOICE, "misc/talk.wav", 1, ATTN_NORM);
}
// key door stuff
if (!self.items)
return;
// FIXME: blink key on player's status bar
if ( (self.items & other.items) != self.items )
{
if (self.owner.items == IT_KEY1)
{
if (world.worldtype == 2)
{
centerprint (other, "You need the silver keycard");
sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
}
else if (world.worldtype == 1)
{
centerprint (other, "You need the silver runekey");
sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
}
else if (world.worldtype == 0)
{
centerprint (other, "You need the silver key");
sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
}
}
else
{
if (world.worldtype == 2)
{
centerprint (other, "You need the gold keycard");
sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
}
else if (world.worldtype == 1)
{
centerprint (other, "You need the gold runekey");
sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
}
else if (world.worldtype == 0)
{
centerprint (other, "You need the gold key");
sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
}
}
return;
}
other.items = other.items - self.items;
self.touch = SUB_Null;
if (self.enemy)
self.enemy.touch = SUB_Null; // get paired door
door_use ();
};
/*
=============================================================================
SPAWNING FUNCTIONS
=============================================================================
*/
entity(vector fmins, vector fmaxs) spawn_field =
{
local entity trigger;
local vector t1, t2;
trigger = spawn();
trigger.movetype = MOVETYPE_NONE;
trigger.solid = SOLID_TRIGGER;
trigger.owner = self;
trigger.touch = door_trigger_touch;
t1 = fmins;
t2 = fmaxs;
setsize (trigger, t1 - '60 60 8', t2 + '60 60 8');
return (trigger);
};
float (entity e1, entity e2) EntitiesTouching =
{
if (e1.mins_x > e2.maxs_x)
return FALSE;
if (e1.mins_y > e2.maxs_y)
return FALSE;
if (e1.mins_z > e2.maxs_z)
return FALSE;
if (e1.maxs_x < e2.mins_x)
return FALSE;
if (e1.maxs_y < e2.mins_y)
return FALSE;
if (e1.maxs_z < e2.mins_z)
return FALSE;
return TRUE;
};
/*
=============
LinkDoors
=============
*/
void() LinkDoors =
{
local entity t, starte;
local vector cmins, cmaxs;
if (self.enemy)
return; // already linked by another door
if (self.spawnflags & 4)
{
self.owner = self.enemy = self;
return; // don't want to link this door
}
cmins = self.mins;
cmaxs = self.maxs;
starte = self;
t = self;
do
{
self.owner = starte; // master door
if (self.health)
starte.health = self.health;
if (self.targetname)
starte.targetname = self.targetname;
if (self.message != "")
starte.message = self.message;
t = find (t, classname, self.classname);
if (!t)
{
self.enemy = starte; // make the chain a loop
// shootable, fired, or key doors just needed the owner/enemy links,
// they don't spawn a field
self = self.owner;
if (self.health)
return;
if (self.targetname)
return;
if (self.items)
return;
self.owner.trigger_field = spawn_field(cmins, cmaxs);
return;
}
if (EntitiesTouching(self,t))
{
if (t.enemy)
objerror ("cross connected doors");
self.enemy = t;
self = t;
if (t.mins_x < cmins_x)
cmins_x = t.mins_x;
if (t.mins_y < cmins_y)
cmins_y = t.mins_y;
if (t.mins_z < cmins_z)
cmins_z = t.mins_z;
if (t.maxs_x > cmaxs_x)
cmaxs_x = t.maxs_x;
if (t.maxs_y > cmaxs_y)
cmaxs_y = t.maxs_y;
if (t.maxs_z > cmaxs_z)
cmaxs_z = t.maxs_z;
}
} while (1 );
};
/*QUAKED func_door (0 .5 .8) ? START_OPEN x DOOR_DONT_LINK GOLD_KEY SILVER_KEY TOGGLE
if two doors touch, they are assumed to be connected and operate as a unit.
TOGGLE causes the door to wait in both the start and end states for a trigger event.
START_OPEN causes the door to move to its destination when spawned, and operate in reverse. It is used to temporarily or permanently close off an area when triggered (not usefull for touch or takedamage doors).
Key doors are allways wait -1.
"message" is printed when the door is touched if it is a trigger door and it hasn't been fired yet
"angle" determines the opening direction
"targetname" if set, no touch field will be spawned and a remote button or trigger field activates the door.
"health" if set, door must be shot open
"speed" movement speed (100 default)
"wait" wait before returning (3 default, -1 = never return)
"lip" lip remaining at end of move (8 default)
"dmg" damage to inflict when blocked (2 default)
"sounds"
0) no sound
1) stone
2) base
3) stone chain
4) screechy metal
*/
void() func_door =
{
if (world.worldtype == 0)
{
precache_sound ("doors/medtry.wav");
precache_sound ("doors/meduse.wav");
self.noise3 = "doors/medtry.wav";
self.noise4 = "doors/meduse.wav";
}
else if (world.worldtype == 1)
{
precache_sound ("doors/runetry.wav");
precache_sound ("doors/runeuse.wav");
self.noise3 = "doors/runetry.wav";
self.noise4 = "doors/runeuse.wav";
}
else if (world.worldtype == 2)
{
precache_sound ("doors/basetry.wav");
precache_sound ("doors/baseuse.wav");
self.noise3 = "doors/basetry.wav";
self.noise4 = "doors/baseuse.wav";
}
else
{
dprint ("no worldtype set!\n");
}
if (self.sounds == 0)
{
precache_sound ("misc/null.wav");
precache_sound ("misc/null.wav");
self.noise1 = "misc/null.wav";
self.noise2 = "misc/null.wav";
}
if (self.sounds == 1)
{
precache_sound ("doors/drclos4.wav");
precache_sound ("doors/doormv1.wav");
self.noise1 = "doors/drclos4.wav";
self.noise2 = "doors/doormv1.wav";
}
if (self.sounds == 2)
{
precache_sound ("doors/hydro1.wav");
precache_sound ("doors/hydro2.wav");
self.noise2 = "doors/hydro1.wav";
self.noise1 = "doors/hydro2.wav";
}
if (self.sounds == 3)
{
precache_sound ("doors/stndr1.wav");
precache_sound ("doors/stndr2.wav");
self.noise2 = "doors/stndr1.wav";
self.noise1 = "doors/stndr2.wav";
}
if (self.sounds == 4)
{
precache_sound ("doors/ddoor1.wav");
precache_sound ("doors/ddoor2.wav");
self.noise1 = "doors/ddoor2.wav";
self.noise2 = "doors/ddoor1.wav";
}
if (self.sounds == 5) // X-Men: drill sound
{
precache_sound ("doors/ddoor1.wav");
precache_sound ("ambience/drill_x.wav");
self.noise1 = "doors/ddoor2.wav";
self.noise2 = "ambience/drill_x.wav";
}
SetMovedir ();
self.max_health = self.health;
self.solid = SOLID_BSP;
self.movetype = MOVETYPE_PUSH;
setorigin (self, self.origin);
setmodel (self, self.model);
self.classname = "door";
self.blocked = door_blocked;
self.use = door_use;
if (self.spawnflags & DOOR_SILVER_KEY)
self.items = IT_KEY1;
if (self.spawnflags & DOOR_GOLD_KEY)
self.items = IT_KEY2;
if (!self.speed)
self.speed = 100;
if (!self.wait)
self.wait = 3;
if (!self.lip)
self.lip = 8;
if (!self.dmg)
self.dmg = 2;
self.pos1 = self.origin;
self.pos2 = self.pos1 + self.movedir*(fabs(self.movedir*self.size) - self.lip);
// DOOR_START_OPEN is to allow an entity to be lighted in the closed position
// but spawn in the open position
if (self.spawnflags & DOOR_START_OPEN)
{
setorigin (self, self.pos2);
self.pos2 = self.pos1;
self.pos1 = self.origin;
}
self.state = STATE_BOTTOM;
if (self.health)
{
self.takedamage = DAMAGE_YES;
self.th_die = door_killed;
}
if (self.items)
self.wait = -1;
self.touch = door_touch;
// LinkDoors can't be done until all of the doors have been spawned, so
// the sizes can be detected properly.
self.think = LinkDoors;
self.nextthink = self.ltime + 0.1;
};
/*
=============================================================================
SECRET DOORS
=============================================================================
*/
void() fd_secret_move1;
void() fd_secret_move2;
void() fd_secret_move3;
void() fd_secret_move4;
void() fd_secret_move5;
void() fd_secret_move6;
void() fd_secret_done;
float SECRET_OPEN_ONCE = 1; // stays open
float SECRET_1ST_LEFT = 2; // 1st move is left of arrow
float SECRET_1ST_DOWN = 4; // 1st move is down from arrow
float SECRET_NO_SHOOT = 8; // only opened by trigger
float SECRET_YES_SHOOT = 16; // shootable even if targeted
void () fd_secret_use =
{
local float temp;
self.health = 10000;
// exit if still moving around...
if (self.origin != self.oldorigin)
return;
self.message = string_null; // no more message
SUB_UseTargets(); // fire all targets / killtargets
if (!(self.spawnflags & SECRET_NO_SHOOT))
{
self.th_pain = SUB_Null;
self.takedamage = DAMAGE_NO;
}
self.velocity = '0 0 0';
// Make a sound, wait a little...
sound(self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
self.nextthink = self.ltime + 0.1;
temp = 1 - (self.spawnflags & SECRET_1ST_LEFT); // 1 or -1
makevectors(self.mangle);
if (!self.t_width)
{
if (self.spawnflags & SECRET_1ST_DOWN)
self. t_width = fabs(v_up * self.size);
else
self. t_width = fabs(v_right * self.size);
}
if (!self.t_length)
self. t_length = fabs(v_forward * self.size);
if (self.spawnflags & SECRET_1ST_DOWN)
self.dest1 = self.origin - v_up * self.t_width;
else
self.dest1 = self.origin + v_right * (self.t_width * temp);
self.dest2 = self.dest1 + v_forward * self.t_length;
SUB_CalcMove(self.dest1, self.speed, fd_secret_move1);
sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
};
// Wait after first movement...
void () fd_secret_move1 =
{
self.nextthink = self.ltime + 1.0;
self.think = fd_secret_move2;
sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
};
// Start moving sideways w/sound...
void () fd_secret_move2 =
{
sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
SUB_CalcMove(self.dest2, self.speed, fd_secret_move3);
};
// Wait here until time to go back...
void () fd_secret_move3 =
{
sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
if (!(self.spawnflags & SECRET_OPEN_ONCE))
{
self.nextthink = self.ltime + self.wait;
self.think = fd_secret_move4;
}
};
// Move backward...
void () fd_secret_move4 =
{
sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
SUB_CalcMove(self.dest1, self.speed, fd_secret_move5);
};
// Wait 1 second...
void () fd_secret_move5 =
{
self.nextthink = self.ltime + 1.0;
self.think = fd_secret_move6;
sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
};
void () fd_secret_move6 =
{
sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
SUB_CalcMove(self.oldorigin, self.speed, fd_secret_done);
};
void () fd_secret_done =
{
if (!self.targetname || self.spawnflags&SECRET_YES_SHOOT)
{
self.health = 10000;
self.takedamage = DAMAGE_YES;
self.th_pain = fd_secret_use;
}
sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
};
void () secret_blocked =
{
if (time < self.attack_finished)
return;
self.attack_finished = time + 0.5;
T_Damage (other, self, self, self.dmg);
};
/*
================
secret_touch
Prints messages
================
*/
void() secret_touch =
{
if (other.classname != "player")
return;
if (self.attack_finished > time)
return;
self.attack_finished = time + 2;
if (self.message)
{
centerprint (other, self.message);
sound (other, CHAN_BODY, "misc/talk.wav", 1, ATTN_NORM);
}
};
/*QUAKED func_door_secret (0 .5 .8) ? open_once 1st_left 1st_down no_shoot always_shoot
Basic secret door. Slides back, then to the side. Angle determines direction.
wait = # of seconds before coming back
1st_left = 1st move is left of arrow
1st_down = 1st move is down from arrow
always_shoot = even if targeted, keep shootable
t_width = override WIDTH to move back (or height if going down)
t_length = override LENGTH to move sideways
"dmg" damage to inflict when blocked (2 default)
If a secret door has a targetname, it will only be opened by it's botton or trigger, not by damage.
"sounds"
1) medieval
2) metal
3) base
*/
void () func_door_secret =
{
if (self.sounds == 0)
self.sounds = 3;
if (self.sounds == 1)
{
precache_sound ("doors/latch2.wav");
precache_sound ("doors/winch2.wav");
precache_sound ("doors/drclos4.wav");
self.noise1 = "doors/latch2.wav";
self.noise2 = "doors/winch2.wav";
self.noise3 = "doors/drclos4.wav";
}
if (self.sounds == 2)
{
precache_sound ("doors/airdoor1.wav");
precache_sound ("doors/airdoor2.wav");
self.noise2 = "doors/airdoor1.wav";
self.noise1 = "doors/airdoor2.wav";
self.noise3 = "doors/airdoor2.wav";
}
if (self.sounds == 3)
{
precache_sound ("doors/basesec1.wav");
precache_sound ("doors/basesec2.wav");
self.noise2 = "doors/basesec1.wav";
self.noise1 = "doors/basesec2.wav";
self.noise3 = "doors/basesec2.wav";
}
if (!self.dmg)
self.dmg = 2;
// Magic formula...
self.mangle = self.angles;
self.angles = '0 0 0';
self.solid = SOLID_BSP;
self.movetype = MOVETYPE_PUSH;
self.classname = "door";
setmodel (self, self.model);
setorigin (self, self.origin);
self.touch = secret_touch;
self.blocked = secret_blocked;
self.speed = 50;
self.use = fd_secret_use;
if ( !self.targetname || self.spawnflags&SECRET_YES_SHOOT)
{
self.health = 10000;
self.takedamage = DAMAGE_YES;
self.th_pain = fd_secret_use;
self.th_die = fd_secret_use;
}
self.oldorigin = self.origin;
if (!self.wait)
self.wait = 5; // 5 seconds before closing
};

117
EXPLBRSH.c Normal file
View file

@ -0,0 +1,117 @@
/*
Begin Xmen - cl2
Exploding Brushes
*/
void () fe_boom =
{
local float num, r, mass;
local vector neworgs, vect;
local entity targ, oself;
vect = self.absmax - self.absmin;
mass = (vect_x / 10) * (vect_y / 10) * (vect_z / 10);
self.solid = SOLID_NOT;
neworgs = self.absmax - self.absmin;
self.origin_x = self.absmin_x + neworgs_x * random();
self.origin_y = self.absmin_y + neworgs_y * random();
self.origin_z = self.absmin_z + neworgs_z * random();
num = floor(mass / 100) + 5;
if (num > 12)
num = 12;
while (num >= 0) {
r = random ();
if (r < 0.2) {
ThrowGib ("progs/rubble1.mdl", random () * -50);
} else if (r < 0.4) {
ThrowGib ("progs/rubble2.mdl", random () * -50);
} else if (r < 0.6) {
ThrowGib ("progs/rubble3.mdl", random () * -50);
} else if (r < 0.8) {
ThrowGib ("progs/rubble4.mdl", random () * -50);
} else {
ThrowGib ("progs/rubble5.mdl", random () * -50);
}
num = num - 1;
}
T_RadiusDamage (self, self, 100, world);
sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
BecomeExplosion ();
SUB_UseTargets();
};
void () fe_touch =
{
local entity oself;
if ((other.classname != "guided_rocket") &&
(other.classname != "orb"))
return;
if (self.targetname != "")
return;
if (other.classname == "orb") {
oself = self;
self = other;
GrenadeExplode();
self = oself;
}
fe_boom ();
};
void () fe_use =
{
self.think = fe_boom;
self.nextthink = time + 0.1;
};
void () func_explode =
{
if (deathmatch) {
remove(self);
return;
}
if (!self.state)
self.state = 1; // FIXME
precache_model ("progs/rubble1.mdl");
precache_model ("progs/rubble2.mdl");
precache_model ("progs/rubble3.mdl");
precache_model ("progs/rubble4.mdl");
precache_model ("progs/rubble5.mdl");
self.movetype = MOVETYPE_PUSH;
self.solid = SOLID_BSP;
setmodel (self, self.model);
self.use = fe_use;
self.touch = fe_touch;
self.health = 0;
self.takedamage = DAMAGE_NO;
// set speed (skin) according to "mdl" field
if (self.mdl == "computer1")
self.speed = 0;
else if (self.mdl == "ewall")
self.speed = 1;
else if (self.mdl == "grass")
self.speed = 2;
else if (self.mdl == "bb016")
self.speed = 3;
else if (self.mdl == "steel")
self.speed = 4;
else if (self.mdl == "metal")
self.speed = 5;
else if (self.mdl == "redpan")
self.speed = 6;
else if (self.mdl == "conpanel")
self.speed = 7;
else if (self.mdl == "egyptwall")
self.speed = 8;
};

435
FIGHT.c Normal file
View file

@ -0,0 +1,435 @@
/*
A monster is in fight mode if it thinks it can effectively attack its
enemy.
When it decides it can't attack, it goes into hunt mode.
*/
float(float v) anglemod;
void() knight_atk;
void() knight_runattack;
float() DemonCheckAttack;
void(float side) Demon_Melee;
void(vector dest) ChooseTurn;
void() ai_face;
float enemy_vis, enemy_infront, enemy_range;
float enemy_yaw;
void() knight_attack =
{
local float len;
// decide if now is a good swing time
len = vlen(self.enemy.origin+self.enemy.view_ofs - (self.origin+self.view_ofs));
if (len<80)
knight_atk ();
else {
knight_runattack ();
}
};
//=============================================================================
/*
===========
CheckAttack
The player is in view, so decide to move or launch an attack
Returns FALSE if movement should continue
============
*/
float() CheckAttack =
{
local vector spot1, spot2;
local entity targ;
local float chance;
if (!(enemy_infront))
return FALSE;
targ = self.enemy;
// see if any entities are in the way of the shot
spot1 = self.origin + self.view_ofs;
spot2 = targ.origin + targ.view_ofs;
traceline (spot1, spot2, FALSE, self);
if (trace_ent != targ)
return FALSE; // don't have a clear shot
if (trace_inopen && trace_inwater)
return FALSE; // sight line crossed contents
if (enemy_range == RANGE_MELEE)
{ // melee attack
if (self.th_melee)
{
if (self.classname == "xmen_psylocke")
knight_attack ();
else
self.th_melee ();
return TRUE;
}
}
// missile attack
if (!self.th_missile)
return FALSE;
if (time < self.attack_finished)
return FALSE;
if (enemy_range == RANGE_FAR)
return FALSE;
if (enemy_range == RANGE_MELEE)
{
chance = 0.9;
self.attack_finished = 0;
}
else if (enemy_range == RANGE_NEAR)
{
if (self.th_melee)
chance = 0.2;
else
chance = 0.4;
}
else if (enemy_range == RANGE_MID)
{
if (self.th_melee)
chance = 0.05;
else
chance = 0.1;
}
else
chance = 0;
if (random () < chance)
{
self.th_missile ();
SUB_AttackFinished (2*random());
return TRUE;
}
return FALSE;
};
/*
=============
ai_face
Stay facing the enemy
=============
*/
void() ai_face =
{
local float diff;
self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin);
if (self.flags & FL_FLY) {
diff = angle_diff(self.angles_y, self.ideal_yaw);
if (diff < -10)
self.angles_z = self.angles_z - 2;
else if (diff > 10)
self.angles_z = self.angles_z + 2;
else {
if (fabs(self.angles_z) < 2)
self.angles_z = 0;
else if (self.angles_z > 0)
self.angles_z = self.angles_z - 2;
else
self.angles_z = self.angles_z + 2;
}
if (self.angles_z > 30)
self.angles_z = 30;
else if (self.angles_z < -30)
self.angles_z = -30;
}
ChangeYaw ();
};
/*
=============
ai_charge
The monster is in a melee attack, so get as close as possible to .enemy
=============
*/
float (entity targ) visible;
float(entity targ) infront;
float(entity targ) range;
void(float d) ai_charge =
{
ai_face ();
movetogoal (d); // done in C code...
if (self.classname == "xmen_wolverine")
self.nextthink = time + 0.05;
};
void() ai_charge_side =
{
local vector dtemp;
local float heading;
// aim to the left of the enemy for a flyby
self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin);
ChangeYaw ();
makevectors (self.angles);
dtemp = self.enemy.origin - 30*v_right;
heading = vectoyaw(dtemp - self.origin);
walkmove(heading, 20);
};
/*
=============
ai_melee
=============
*/
void() ai_melee =
{
local vector delta;
local float ldmg;
if (!self.enemy)
return; // removed before stroke
delta = self.enemy.origin - self.origin;
if (vlen(delta) > 60)
return;
ldmg = (random() + random() + random()) * 3;
T_Damage (self.enemy, self, self, ldmg);
};
void() ai_melee_side =
{
local vector delta;
local float ldmg;
if (!self.enemy)
return; // removed before stroke
ai_charge_side();
delta = self.enemy.origin - self.origin;
if (vlen(delta) > 60)
return;
if (!CanDamage (self.enemy, self))
return;
ldmg = (random() + random() + random()) * 3;
T_Damage (self.enemy, self, self, ldmg);
};
//=============================================================================
/*
===========
SoldierCheckAttack
The player is in view, so decide to move or launch an attack
Returns FALSE if movement should continue
============
*/
float() SoldierCheckAttack =
{
local vector spot1, spot2;
local entity targ;
local float chance;
targ = self.enemy;
// see if any entities are in the way of the shot
spot1 = self.origin + self.view_ofs;
spot2 = targ.origin + targ.view_ofs;
traceline (spot1, spot2, FALSE, self);
if (trace_inopen && trace_inwater)
return FALSE; // sight line crossed contents
if (trace_ent != targ)
return FALSE; // don't have a clear shot
// missile attack
if (time < self.attack_finished)
return FALSE;
if (enemy_range == RANGE_FAR)
return FALSE;
if (enemy_range == RANGE_MELEE)
chance = 0.9;
else if (enemy_range == RANGE_NEAR)
chance = 0.4;
else if (enemy_range == RANGE_MID)
chance = 0.05;
else
chance = 0;
if (random () < chance)
{
self.th_missile ();
SUB_AttackFinished (1 + random());
if (random() < 0.3)
self.lefty = !self.lefty;
return TRUE;
}
return FALSE;
};
//=============================================================================
/*
===========
ShamCheckAttack
The player is in view, so decide to move or launch an attack
Returns FALSE if movement should continue
============
*/
float() ShamCheckAttack =
{
local vector spot1, spot2;
local entity targ;
local float chance;
local float enemy_yaw;
if (enemy_range == RANGE_MELEE)
{
if (CanDamage (self.enemy, self))
{
self.attack_state = AS_MELEE;
return TRUE;
}
}
if (time < self.attack_finished)
return FALSE;
if (!enemy_vis)
return FALSE;
targ = self.enemy;
// see if any entities are in the way of the shot
spot1 = self.origin + self.view_ofs;
spot2 = targ.origin + targ.view_ofs;
if (vlen(spot1 - spot2) > 600)
return FALSE;
traceline (spot1, spot2, FALSE, self);
if (trace_inopen && trace_inwater)
return FALSE; // sight line crossed contents
if (trace_ent != targ)
{
return FALSE; // don't have a clear shot
}
// missile attack
if (enemy_range == RANGE_FAR)
return FALSE;
self.attack_state = AS_MISSILE;
SUB_AttackFinished (2 + 2*random());
return TRUE;
};
//============================================================================
/*
===========
OgreCheckAttack
The player is in view, so decide to move or launch an attack
Returns FALSE if movement should continue
============
*/
float() OgreCheckAttack =
{
local vector spot1, spot2;
local entity targ;
local float chance;
if (enemy_range == RANGE_MELEE)
{
if (CanDamage (self.enemy, self))
{
self.attack_state = AS_MELEE;
return TRUE;
}
}
if (time < self.attack_finished)
return FALSE;
if (!enemy_vis)
return FALSE;
targ = self.enemy;
// see if any entities are in the way of the shot
spot1 = self.origin + self.view_ofs;
spot2 = targ.origin + targ.view_ofs;
traceline (spot1, spot2, FALSE, self);
if (trace_inopen && trace_inwater)
return FALSE; // sight line crossed contents
if (trace_ent != targ)
{
return FALSE; // don't have a clear shot
}
// missile attack
if (time < self.attack_finished)
return FALSE;
if (enemy_range == RANGE_FAR)
return FALSE;
else if (enemy_range == RANGE_NEAR)
chance = 0.10;
else if (enemy_range == RANGE_MID)
chance = 0.05;
else
chance = 0;
self.attack_state = AS_MISSILE;
SUB_AttackFinished (1 + 2*random());
return TRUE;
};

2739
ITEMS.c Normal file

File diff suppressed because it is too large Load diff

792
Iceman.c Normal file
View file

@ -0,0 +1,792 @@
/*
==============================================================================
iceman
==============================================================================
*/
$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
$frame stand10 stand11 stand12 stand13
$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10
$frame walk11 walk12
$frame run1 run2 run3 run4 run5 run6
$frame pain1 pain2 pain3 pain4 pain5 pain6
$frame paina1 paina2 paina3 paina4 paina5 paina6 paina7 paina8 paina9 paina10
$frame paina11 paina12 paina13 paina14 paina15 paina16 paina17 paina18 paina19 paina20
$frame paina21 paina22 paina23 paina24 paina25 paina26 paina27 paina28 paina29
$frame death1 death2 death3 death4 death5 death6 death7 death8 death9 death10
$frame death11 death12 death13 death14 death15 death16
$frame rise1 rise2 rise3 rise4 rise5 rise6 rise7 rise8 rise9
$frame rise10 rise11 rise12 rise13 rise14 rise15 rise16 rise17 rise18 rise19
$frame melt1 melt2 melt3 melt4 melt5 melt6 melt7 melt8
$frame satta1 satta2 satta3 satta4 satta5 satta6 satta7 satta8
$frame satta9 satta10 satta11 satta12
$frame sattb1 sattb2 sattb3 sattb4 sattb5 sattb6 sattb7 sattb8
$frame sattb9 sattb10 sattb11 sattb12
$frame xatta1 xatta2 xatta3 xatta4 xatta5 xatta6 xatta7 xatta8
$frame xatta9 xatta10 xatta11 xatta12
void() iceman_Laser_Touch =
{
local vector org;
if (other == self.owner)
return; // don't explode on owner
if (pointcontents(self.origin) == CONTENT_SKY)
{
remove(self);
return;
}
org = self.origin - 8*normalize(self.velocity);
if (other.health)
{
SpawnBlood (org, self.velocity*0.2, 15);
T_Damage (other, self, self.owner, 10);
}
else
{
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_GUNSHOT);
WriteCoord (MSG_BROADCAST, org_x);
WriteCoord (MSG_BROADCAST, org_y);
WriteCoord (MSG_BROADCAST, org_z);
}
remove(self);
};
void(vector org, vector vec) Ice_LaunchShard =
{
local vector vec;
vec = normalize(vec);
newmis = spawn();
newmis.owner = self;
newmis.movetype = MOVETYPE_FLY;
newmis.solid = SOLID_BBOX;
newmis.effects = EF_DIMLIGHT;
setmodel (newmis, "progs/iceshard.mdl");
setsize (newmis, '0 0 0', '0 0 0');
setorigin (newmis, org);
newmis.velocity = vec * 600;
newmis.angles = vectoangles(newmis.velocity);
newmis.nextthink = time + 3;
newmis.think = SUB_Remove;
newmis.touch = iceman_Laser_Touch;
};
void() ice_atkb1;
void() ice_xatk1;
void() ShardTouch =
{
local vector t1, t2, vec;
vec = self.old_velocity;
if (other == self.owner)
return;
if (other == world)
{
if (random() < 0.5)
sound(self, CHAN_AUTO, "weapons/tink1.wav", 1, 3);
self.state = 0;
self.avelocity_x = random()*500;
self.avelocity_y = random()*500;
self.avelocity_z = random()*500;
// give seom random upwards velocity
self.velocity_z = random() * 500 - 100;
}
if (other.takedamage == DAMAGE_AIM)
{
spawn_touchblood (20);
T_Damage(other, self, self.owner, 3);
remove(self);
return;
}
self.last_touch = time;
if (self.velocity == '0 0 0')
remove(self);
};
void(vector org, vector dir) spawn_shard =
{
local entity missile, mpuff;
local vector vect;
missile = spawn ();
missile.owner = self;
missile.movetype = MOVETYPE_BOUNCE;
missile.state = 1;
missile.solid = SOLID_SLIDEBOX;
missile.classname = "shard";
// set missile speed
vect = normalize(dir);
missile.velocity = vect * 1000;
// missile.velocity_z = 0;
missile.angles = vectoangles(missile.velocity);
missile.old_velocity = missile.velocity;
missile.touch = ShardTouch;
// set missile duration
// missile.last_idle = time;
missile.last_touch = 0;
missile.oldorigin = missile.origin;
missile.nextthink = time + 2.8;
// missile.think = GrenadeExplode;
missile.think = SUB_Remove;
setmodel (missile, "progs/iceshard.mdl");
setsize (missile, '0 0 0', '0 0 0');
setorigin (missile, org);
self.old_velocity = self.velocity;
};
void(float offs) iceman_fire =
{
local vector org, vect, ang;
ang = self.angles;
ang_y = anglemod(ang_y + offs);
makevectors (ang);
vect = v_forward;
org = self.origin + '0 0 12';
spawn_shard(org, vect);
};
void() iceballTouch =
{
if (other == self.owner)
return;
if (((other.classname == "player") || (coop && (other.flags & FL_MONSTER))) && (other.parallize_time < (time - 4)))
{
if (!deathmatch && (other.flags & FL_CLIENT))
other.parallize_time = time + 2;
else
other.parallize_time = time + 3;
other.x_flags = other.x_flags | X_PARALLIZED;
other.parallized_velocity = '0 0 0';
if (other.flags & FL_CLIENT)
{
centerprint(other, "You have been iced!");
stuffcmd(other, "v_cshift 128 128 256 180\n");
}
else
{
other.think = other.th_stand;
other.enemy = world;
}
sound(other, CHAN_BODY, "generic/frozen1.wav", 1, ATTN_NORM);
if (deathmatch)
other.skin = 1;
remove(self);
return;
}
remove(self);
};
void(vector org, vector dir) spawn_iceball =
{
local entity missile, mpuff;
local vector vect;
missile = spawn ();
missile.owner = self;
missile.movetype = MOVETYPE_FLYMISSILE;
missile.solid = SOLID_BBOX;
missile.classname = "iceblast";
// set missile speed
vect = normalize(dir);
if (self.flags & FL_MONSTER)
missile.velocity = ProjectVelocity(1400, '0 0 0');
else
missile.velocity = vect * 1400;
missile.angles = vectoangles(missile.velocity);
missile.old_velocity = missile.velocity;
missile.touch = iceballTouch;
// set missile duration
// missile.last_idle = time;
missile.last_touch = 0;
missile.oldorigin = missile.origin;
missile.nextthink = time + 2;
// missile.think = GrenadeExplode;
missile.think = SUB_Remove;
missile.avelocity_z = 300;
setmodel (missile, "progs/iceblast.mdl");
setsize (missile, '0 0 0', '0 0 0');
setorigin (missile, org);
};
void () ice_fire_iceball =
{
local vector org,o2;
makevectors (self.angles);
org = self.origin + v_forward * 1 + '0 0 12';
o2 = self.enemy.origin + v_right * ((random() * 64) - 32);
spawn_iceball(org, o2 - self.origin);
};
//============================================================================
void() ice_stand1 =[ $stand1, ice_stand2 ] {ai_stand();};
void() ice_stand2 =[ $stand2, ice_stand3 ] {ai_stand();};
void() ice_stand3 =[ $stand3, ice_stand4 ] {ai_stand();};
void() ice_stand4 =[ $stand4, ice_stand5 ] {ai_stand();};
void() ice_stand5 =[ $stand5, ice_stand6 ] {ai_stand();};
void() ice_stand6 =[ $stand6, ice_stand7 ] {ai_stand();};
void() ice_stand7 =[ $stand7, ice_stand8 ] {ai_stand();};
void() ice_stand8 =[ $stand8, ice_stand9 ] {ai_stand();};
void() ice_stand9 =[ $stand9, ice_stand10 ] {ai_stand();};
void() ice_stand10 =[ $stand10, ice_stand11 ] {ai_stand();};
void() ice_stand11 =[ $stand11, ice_stand12 ] {ai_stand();};
void() ice_stand12 =[ $stand12, ice_stand13 ] {ai_stand();};
void() ice_stand13 =[ $stand13, ice_stand1 ] {ai_stand();};
void() ice_walk1 =[ $walk1 , ice_walk2 ] {ai_walk(7);};
void() ice_walk2 =[ $walk2 , ice_walk3 ] {ai_walk(4);};
void() ice_walk3 =[ $walk3 , ice_walk4 ] {ai_walk(4);};
void() ice_walk4 =[ $walk4 , ice_walk5 ] {ai_walk(4);};
void() ice_walk5 =[ $walk5 , ice_walk6 ] {ai_walk(4);};
void() ice_walk6 =[ $walk6 , ice_walk7 ] {ai_walk(5);};
void() ice_walk7 =[ $walk7 , ice_walk8 ] {ai_walk(5);};
void() ice_walk8 =[ $walk8 , ice_walk9 ] {ai_walk(4);};
void() ice_walk9 =[ $walk9 , ice_walk10 ] {ai_walk(7);};
void() ice_walk10 =[ $walk10, ice_walk11 ] {ai_walk(4);};
void() ice_walk11 =[ $walk11, ice_walk12 ] {ai_walk(0);};
void() ice_walk12 =[ $walk12, ice_walk1 ] {ai_walk(5);};
void() ice_run1 =[ $run1 , ice_run2 ] {
ai_run(14);};
void() ice_run2 =[ $run2 , ice_run3 ] {ai_run(16);};
void() ice_run3 =[ $run3 , ice_run4 ] {ai_run(16);};
void() ice_run4 =[ $run4 , ice_run5 ] {ai_run(16);};
void() ice_run5 =[ $run5 , ice_run6 ] {ai_run(16);};
void() ice_run6 =[ $run6 , ice_run1 ] {ai_run(16);};
void() ice_pain1 =[ $pain1, ice_pain2 ] {};
void() ice_pain2 =[ $pain2, ice_pain3 ] {};
void() ice_pain3 =[ $pain3, ice_pain4 ] {};
void() ice_pain4 =[ $pain4, ice_pain5 ] {};
void() ice_pain5 =[ $pain5, ice_pain6 ] {};
void() ice_pain6 =[ $pain6, ice_run1 ] {};
void() ice_melt1 =[ $melt1, ice_melt2 ] {};
void() ice_melt2 =[ $melt2, ice_melt3 ] {};
void() ice_melt3 =[ $melt3, ice_melt4 ] {};
void() ice_melt4 =[ $melt4, ice_melt5 ] {};
void() ice_melt5 =[ $melt5, ice_melt6 ] {};
void() ice_melt6 =[ $melt6, ice_melt7 ] {};
void() ice_melt7 =[ $melt7, ice_melt8 ] {};
void() ice_melt8 =[ $melt8, ice_melt8 ] {
setmodel(self, "progs/puddle.mdl");
self.skin = 0;
self.solid = SOLID_NOT;
self.deadflag = DEAD_DEAD;
self.think = SUB_Remove;
self.nextthink = time + 120 + random() * 30;
};
void() ice_paina1 =[ $paina1, ice_paina2 ] {};
void() ice_paina2 =[ $paina2, ice_paina3 ] {};
void() ice_paina3 =[ $paina3, ice_paina4 ] {};
void() ice_paina4 =[ $paina4, ice_paina5 ] {};
void() ice_paina5 =[ $paina5, ice_paina6 ] {};
void() ice_paina6 =[ $paina6, ice_paina7 ] {};
void() ice_paina7 =[ $paina7, ice_paina8 ] {};
void() ice_paina8 =[ $paina8, ice_paina9 ] {};
void() ice_paina9 =[ $paina9, ice_paina10 ] {};
void() ice_paina10 =[ $paina10, ice_paina11 ] {};
void() ice_paina11 =[ $paina11, ice_paina12 ] {};
void() ice_paina12 =[ $paina12, ice_paina13 ] {};
void() ice_paina13 =[ $paina12, ice_paina14 ] {};
void() ice_paina14 =[ $paina12, ice_paina15 ] {};
void() ice_paina15 =[ $paina13, ice_paina16 ] {};
void() ice_paina16 =[ $paina14, ice_paina17 ] {};
void() ice_paina17 =[ $paina15, ice_paina18 ] {};
void() ice_paina18 =[ $paina16, ice_paina19 ] {};
void() ice_paina19 =[ $paina16, ice_paina20 ] {};
void() ice_paina20 =[ $paina16, ice_paina21 ] {};
void() ice_paina21 =[ $paina17, ice_paina22 ] {};
void() ice_paina22 =[ $paina18, ice_paina23 ] {};
void() ice_paina23 =[ $paina19, ice_paina24 ] {};
void() ice_paina24 =[ $paina20, ice_paina25 ] {};
void() ice_paina25 =[ $paina21, ice_paina26 ] {};
void() ice_paina26 =[ $paina22, ice_paina27 ] {};
void() ice_paina27 =[ $paina23, ice_paina28 ] {};
void() ice_paina28 =[ $paina24, ice_paina29 ] {};
void() ice_paina29 =[ $paina25, ice_paina30 ] {};
void() ice_paina30 =[ $paina26, ice_paina31 ] {};
void() ice_paina31 =[ $paina27, ice_paina32 ] {};
void() ice_paina32 =[ $paina28, ice_paina33 ] {};
void() ice_paina33 =[ $paina29, ice_run1 ] {};
//============================================================================
void(entity attacker, float damage) ice_pain;
void() ice_atk1 =[ $satta1, ice_atk2 ]
{
ai_face();
self.start_attack_health = self.health;
if (self.count) ai_forward(24);
};
void() ice_atk2 =[ $satta2, ice_atk3 ]
{
ai_face();
iceman_fire(-15);
if (self.count) ai_forward(14);
};
void() ice_atk3 =[ $satta3, ice_atk4 ]
{
ai_face();
iceman_fire(-9);
if (self.count) ai_forward(8);
};
void() ice_atk4 =[ $satta4, ice_atk5 ]
{
ai_face();
iceman_fire(-3);
if (self.count) ai_forward(4);
};
void() ice_atk5 =[ $satta5, ice_atk6 ]
{
ai_face();
iceman_fire(3);
if (self.count) ai_forward(2);
self.count = 0;
};
void() ice_atk6 =[ $satta6, ice_atk7 ] {iceman_fire(9);};
void() ice_atk7 =[ $satta7, ice_atk8 ]
{
iceman_fire(15);
if (self.health < self.start_attack_health)
{
ice_pain(self.enemy, self.start_attack_health - self.health);
}
};
void() ice_atk8 =[ $satta8, ice_atk9 ] {};
void() ice_atk9 =[ $satta9, ice_atk10 ] {};
void() ice_atk10 =[ $satta10, ice_atk11 ] {};
void() ice_atk11 =[ $satta11, ice_atk12 ] {};
void() ice_atk12 =[ $satta12, ice_run1 ] {};
void() ice_xatk1 =[ $xatta1, ice_xatk2 ]
{
ai_face();
self.start_attack_health = self.health;
if (self.count) ai_forward(24);
};
void() ice_xatk2 =[ $xatta2, ice_xatk3 ]
{
ai_face();
if (self.count) ai_forward(14);
};
void() ice_xatk3 =[ $xatta3, ice_xatk4 ]
{
ai_face();
if (self.count) ai_forward(8);
};
void() ice_xatk4 =[ $xatta4, ice_xatk5 ]
{
ai_face();
if (self.count) ai_forward(4);
};
void() ice_xatk5 =[ $xatta5, ice_xatk6 ]
{
ai_face();
if (self.count) ai_forward(2);
self.count = 0;
};
void() ice_xatk6 =[ $xatta6, ice_xatk7 ] {ai_face();};
void() ice_xatk7 =[ $xatta7, ice_xatk8 ]
{ai_face();
if (self.health < self.start_attack_health) {
ice_pain(self.enemy, self.start_attack_health - self.health);
}
};
void() ice_xatk8 =[ $xatta8, ice_xatk9 ] {ai_face();};
void() ice_xatk9 =[ $xatta9, ice_xatk10 ] {ai_face();};
void() ice_xatk10 =[ $xatta10, ice_xatk11 ] {ai_face();};
void() ice_xatk11 =[ $xatta11, ice_xatk12 ] {ai_face();};
void() ice_xatk12 =[ $xatta12, ice_run1 ] {ai_face();
ice_fire_iceball();
};
void(entity attacker, float damage) ice_pain =
{
local float r;
if (self.enemy.weapon == IT_SUPER_NAILGUN)
return;
r = random ();
if (self.pain_finished > time)
return;
if (random()*40 > damage)
return; // didn't flinch
MalePainSound(2);
if ((random()*10 < 8) || ((damage > 50) && (random() < 0.5)))
{
self.pain_finished = time + 2;
ice_pain1 ();
}
else
{
self.pain_finished = time + 4;
ice_paina1 ();
}
};
void() ice_atkb1 =[ $sattb1, ice_atkb2 ]
{
ai_face();
self.start_attack_health = self.health;
if (self.count) ai_forward(32);
};
void() ice_atkb2 =[ $sattb2, ice_atkb3 ]
{
ai_face();
iceman_fire(15);
if (self.count) ai_forward(24);
};
void() ice_atkb3 =[ $sattb3, ice_atkb4 ]
{
ai_face();
iceman_fire(9);
if (self.count) ai_forward(16);
};
void() ice_atkb4 =[ $sattb4, ice_atkb5 ]
{
ai_face();
iceman_fire(3);
if (self.count) ai_forward(8);
};
void() ice_atkb5 =[ $sattb5, ice_atkb6 ]
{
ai_face();
iceman_fire(-3);
if (self.count) ai_forward(8);
self.count = 0;
};
void() ice_atkb6 =[ $sattb6, ice_atkb7 ] {iceman_fire(-9);};
void() ice_atkb7 =[ $sattb7, ice_atkb8 ] {
if (self.health < self.start_attack_health) {
ice_pain(self.enemy, self.start_attack_health - self.health);
iceman_fire(-15);
}
};
void() ice_atkb8 =[ $sattb8, ice_atkb9 ] {};
void() ice_atkb9 =[ $sattb9, ice_atkb10 ] {};
void() ice_atkb10 =[ $sattb10, ice_atkb11 ] {};
void() ice_atkb11 =[ $sattb11, ice_atkb12 ] {};
void() ice_atkb12 =[ $sattb12, ice_run1 ] {};
void() ice_attack =
{
local float rnd;
rnd = random();
if (rnd < 0.3)
ice_atk1();
else if (rnd < 0.6)
ice_atkb1();
else if (self.last_special < (time - 8)) {
self.last_special = time;
ice_xatk1();
}
else {
ice_atk1();
}
};
//============================================================================
void () iceman_melt_go =
{
self.deadflag = DEAD_DYING;
self.pain_finished = time + 99;
ice_melt1();
};
void (entity e) iceman_melt =
{
//e.health = 1;
e.think = iceman_melt_go;
e.nextthink = time + 0.1;
// up the kill count, since he is now officially DEAD
killed_monsters = killed_monsters + 1;
WriteByte (MSG_ALL, SVC_KILLEDMONSTER);
};
void () ice_getup =
{
self.takedamage = DAMAGE_AIM;
self.solid = SOLID_SLIDEBOX;
if (!walkmove(0,0))
{
self.think = ice_getup;
self.solid = SOLID_NOT;
self.nextthink = time + 0.5;
return;
}
self.health = self.start_health;
ice_run1();
};
void() ice_rise1 =[ $rise1, ice_rise2 ]
{
self.solid = SOLID_SLIDEBOX;
if (!walkmove(0,0))
{
self.think = ice_rise1;
self.solid = SOLID_NOT;
self.nextthink = time + 0.5;
return;
}
};
void() ice_rise2 =[ $rise2, ice_rise3 ] {};
void() ice_rise3 =[ $rise3, ice_rise4 ] {};
void() ice_rise4 =[ $rise4, ice_rise5 ] {};
void() ice_rise5 =[ $rise5, ice_rise6 ] {};
void() ice_rise6 =[ $rise6, ice_rise7 ] {};
void() ice_rise7 =[ $rise7, ice_rise8 ] {};
void() ice_rise8 =[ $rise8, ice_rise9 ] {};
void() ice_rise9 =[ $rise9, ice_rise10 ] {};
void() ice_rise10 =[ $rise10, ice_rise11 ] {};
void() ice_rise11 =[ $rise11, ice_rise12 ] {};
void() ice_rise12 =[ $rise12, ice_rise13 ] {};
void() ice_rise13 =[ $rise13, ice_rise14 ] {};
void() ice_rise14 =[ $rise14, ice_rise15 ] {};
void() ice_rise15 =[ $rise15, ice_rise16 ] {};
void() ice_rise16 =[ $rise16, ice_rise17 ] {};
void() ice_rise17 =[ $rise17, ice_rise18 ] {};
void() ice_rise18 =[ $rise18, ice_rise19 ] {};
void() ice_rise19 =[ $rise19, ice_getup ] {};
void() ice_die1 =[ $death1, ice_die2 ] {};
void() ice_die2 =[ $death2, ice_die3 ] {};
void() ice_die3 =[ $death3, ice_die4 ] {self.solid = SOLID_NOT;self.ammo_cells = 5;};
void() ice_die4 =[ $death4, ice_die5 ] {};
void() ice_die5 =[ $death5, ice_die6 ] {};
void() ice_die6 =[ $death6, ice_die7 ] {};
void() ice_die7 =[ $death7, ice_die8 ] {};
void() ice_die8 =[ $death8, ice_die9 ] {};
void() ice_die9 =[ $death9, ice_die10 ] {};
void() ice_die10 =[ $death10, ice_die11 ] {};
void() ice_die11 =[ $death11, ice_die12 ] {};
void() ice_die12 =[ $death12, ice_die13 ] {};
void() ice_die13 =[ $death13, ice_die14 ] {};
void() ice_die14 =[ $death14, ice_die15 ] {};
void() ice_die15 =[ $death15, ice_die16 ] {};
void() ice_die16 =[ $death16, ice_die16 ] {
if (!(self.spawnflags & SPAWNFLAG_CLONE)) {
self.solid = SOLID_NOT;
self.think = ice_rise1;
self.takedamage = DAMAGE_NO;
self.nextthink = time + 20 + random() * 20;
}
};
void() GibShardThink =
{
if (self.velocity_z == 0)
remove(self);
else
self.nextthink = time + 0.2;
};
void(entity ent, float num_gibs) IcemanShardGib =
{
local entity shard;
local float num;
local vector vect;
if (damage_inflictor.classname == "guided_rocket") {
vect = normalize(damage_inflictor.velocity);
}
else {
vect = '0 0 0';
}
num = num_gibs;
while (num > 0) {
shard = spawn();
shard.movetype = MOVETYPE_BOUNCE;
shard.velocity_x = random() * 150 - 75;
shard.velocity_y = random() * 150 - 75;
shard.velocity_z = 220 + random() * 150;
shard.velocity = shard.velocity + vect * 200;
shard.angles = shard.velocity;
shard.avelocity = '200 200 200';
setsize(shard, '0 0 0', '0 0 0');
setmodel(shard, "progs/iceshard.mdl");
setorigin(shard, ent.origin + shard.velocity * 0.1);
shard.frame = 1;
shard.think = GibShardThink;
shard.nextthink = time + 1;
num = num - 1;
}
};
void() ice_die =
{
// check for shard gib
if ((damage_inflictor.classname == "guided_rocket") ||
(damage_inflictor.classname == "orb") ||
(damage_inflictor.classname == "prox_missile") ||
(damage_inflictor.classname == "proximity_ball")) {
IcemanShardGib(self, 15);
remove(self);
return;
}
ice_die1 ();
};
/*QUAKED monster_iceman (1 0 0) (-16 -16 -24) (16 16 40) Ambush
*/
void() monster_zombie =
{
remove(self);
};
void() xmen_iceman =
{
if ((deathmatch) || (self.spawnflags & 1))
{
remove(self);
return;
}
precache_model2 ("progs/iceshard.mdl");
precache_model2 ("progs/puddle.mdl");
precache_model2 ("progs/iceblast.mdl");
precache_sound ("generic/frozen1.wav");
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
if ((self.map == "green") || (self.map == ""))
{
precache_model2("progs/ice1.mdl");
setmodel (self, "progs/ice1.mdl");
}
if (self.map == "blue")
{
precache_model2("progs/ice2.mdl");
setmodel (self, "progs/ice2.mdl");
}
if (self.map == "purple")
{
precache_model2("progs/ice3.mdl");
setmodel (self, "progs/ice3.mdl");
}
if (self.map == "brown")
{
precache_model2("progs/ice4.mdl");
setmodel (self, "progs/ice4.mdl");
}
if (self.map == "gold")
{
precache_model2("progs/ice5.mdl");
setmodel (self, "progs/ice5.mdl");
}
setsize (self, '-16 -16 -24', '16 16 40');
self.health = 80 + cvar("skill") * 10;
self.th_stand = ice_stand1;
self.th_walk = ice_walk1;
self.th_run = ice_run1;
self.th_pain = ice_pain;
self.th_die = ice_die;
self.th_missile = ice_attack;
self.count = 0;
walkmonster_start();
};

311
LITENING.c Normal file
View file

@ -0,0 +1,311 @@
/* Begin Xmen
Lightning revision 2
-cl2-
Revisions:
2: Added some safeguards to make lightning work right
Fixed error messages
Files involved:
litening.qc (this file)
How to implement in a map file:
Place a info_lightning somewhere. Give it a style.
Place other lightning_waypoints all with the same style as startpoint.
String 'em together via 'target' and 'targetname' and voila... lightning. I hope.
"style" : light style it affects (12-31)
"waitmin" : min. time between flashes (default = 3)
"waitmax" : max. time between flashes (default = 10)
"spawnflags" : if 1, bolt will randomly fork off at junctions (default = 0)
"distance" : how long the forks can be (default = 64)
Does looking at other people's code give you a headache, too? ;)
*/
void() lightning_trigger;
float(entity e1, entity e2, float dam) DoABolt =
{
// traceline(e1.origin, e2.origin, FALSE, world);
FillBetweenPoints(e1.origin, e2.origin, "progs/bolt3.mdl", '0 0 0', 0.2);
if (trace_fraction < 1) {
if (world.model == "maps/x1end.bsp") {
T_RadiusDamage(e2, self, dam, world);
}
else if (trace_ent.classname == "player")
T_Damage(trace_ent, self, self, dam);
return FALSE;
}
return TRUE;
/*
local entity bolt;
bolt = spawn();
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_LIGHTNING1);
WriteEntity (MSG_BROADCAST, bolt);
WriteCoord (MSG_BROADCAST, e1.origin_x);
WriteCoord (MSG_BROADCAST, e1.origin_y);
WriteCoord (MSG_BROADCAST, e1.origin_z);
WriteCoord (MSG_BROADCAST, e2.origin_x);
WriteCoord (MSG_BROADCAST, e2.origin_y);
WriteCoord (MSG_BROADCAST, e2.origin_z);
bolt.think = SUB_Remove;
bolt.nextthink = time + 0.2;
*/
};
// randomly create a fork
void(entity e) forkbolt =
{
local entity bolt;
local vector vec,org;
if (random() * 10 < 4) return;
bolt = spawn(); // spawn the bolt
vec = normalize(e.owner.origin - e.origin);
bolt.angles = vectoangles(vec);
makevectors(bolt.angles);
// do some complicated stuff to make sure the fork goes roughly the right
// direction, and doesnt look 'fake' (random in a controlled way?)
org = e.origin + v_forward*(random()*self.distance);
org = org + v_right*(random()*(self.distance*2)-self.distance);
org = org + v_up*(random()*(self.distance*2)-self.distance);
traceline(e.origin, org, TRUE, self);
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); // make some lightning
WriteByte (MSG_BROADCAST, TE_LIGHTNING2);
WriteEntity (MSG_BROADCAST, bolt);
WriteCoord (MSG_BROADCAST, e.origin_x);
WriteCoord (MSG_BROADCAST, e.origin_y);
WriteCoord (MSG_BROADCAST, e.origin_z);
WriteCoord (MSG_BROADCAST, trace_endpos_x);
WriteCoord (MSG_BROADCAST, trace_endpos_y);
WriteCoord (MSG_BROADCAST, trace_endpos_z);
bolt.think = SUB_Remove;
bolt.nextthink = time + 0.5;
};
// O.k. enough freakin' lightning, already.
void() lightning_finish =
{
if (self.style >= 12)
lightstyle(self.style, "a");
self.think = lightning_trigger;
if (self.targetname == "")
self.nextthink = time + self.waitmin + random() * (self.waitmax - self.waitmin);
};
float(entity parent, float lcount) randomRecursive =
{
local float dist, rnd, longbolt, newcount, dosecond;
local vector dir;
local entity newchild;
if (lcount > 4)
return lcount;
else
newcount = lcount + 1;
dosecond = TRUE;
if (newcount == 1) // don't fork on first bolt
dosecond = FALSE;
// create a left hand branch
rnd = random();
dist = 128 * floor(1 + rnd * 4);
dir = '0 0 -1';
dir_x = (random() * 1) - 0.5;
dir_y = (random() * 1) - 0.5;
dir = normalize(dir);
traceline(parent.origin, parent.origin + (dir * dist), FALSE, world);
// create the new endpoint entity
newchild = spawn();
newchild.classname = "lightning_bolt";
newchild.owner = parent;
newchild.origin = trace_endpos;
newchild.think = SUB_Remove;
newchild.nextthink = time + 0.1;
// draw the lightning bolt
DoABolt(parent, newchild, self.dmg);
if (trace_fraction == 1) { // no intersection, do another bolt from the new child
newcount = randomRecursive(newchild, newcount);
}
if (!dosecond)
return newcount;
longbolt = FALSE;
if (random() < 0.3)
longbolt = TRUE;
// do right hand branch
rnd = random();
dist = 128 * floor(1 + (3 * longbolt) + rnd * 4);
dir = '0 0 -1';
dir_x = (random() * 1) - 0.5;
dir_y = (random() * 1) - 0.5;
dir = normalize(dir);
traceline(parent.origin, parent.origin + (dir * dist), FALSE, world);
// create the new endpoint entity
newchild = spawn();
newchild.classname = "lightning_bolt";
newchild.owner = parent;
newchild.origin = trace_endpos;
newchild.think = SUB_Remove;
newchild.nextthink = time + 0.1;
// draw the lightning bolt
DoABolt(parent, newchild, self.dmg);
if ((trace_fraction == 1) && (longbolt)) { // no intersection, do another bolt from the new child
newcount = randomRecursive(newchild, newcount);
}
return newcount;
};
// Lets see some action, dammit!
void() lightning_trigger =
{
local entity lpos;
local float done;
// Sound should go here!
if (self.x_flags == 1)
sound (self, CHAN_AUTO, "ambience/elect.wav", 1, ATTN_NORM);
else
sound (self, CHAN_AUTO, "ambience/thunder1.wav", 0.7, ATTN_NORM);
//return;
if (!self.target) {
// randomize the lightning bolts
randomRecursive(self, 0);
}
else {
done = FALSE;
traceline(self.origin, self.owner.origin, FALSE, world);
DoABolt(self,self.owner, self.dmg);
// inefficient, but since find() can only match string fields... <sigh>
lpos = find(world, classname, "lightning_waypoint");
while ((lpos != world) && !(done))
{
if (lpos.style == self.style)
if (lpos.owner != world)
{
if (self.spawnflags & 1) forkbolt(lpos);
traceline(lpos.origin, lpos.owner.origin, FALSE, world);
if (!DoABolt(lpos, lpos.owner, self.dmg))
done = TRUE;
}
lpos = find(lpos, classname, "lightning_waypoint");
}
}
if (self.style >= 12)
lightstyle(self.style, "z");
self.think = lightning_finish;
self.nextthink = time + 0.3;
};
// Lightning endpoint spawn
void() lightning_ep_start =
{
local entity shnook;
if (self.target)
{
shnook = world;
do
{
shnook = find(shnook, targetname, self.target);
} while (shnook.classname != "lightning_waypoint");
self.owner = shnook;
}
else self.owner = world;
};
void() lightning_waypoint =
{
self.think = lightning_ep_start;
self.nextthink = time + 0.2;
};
// Lightning startpoint spawn
void() lightning_sp_start =
{
local entity shnook;
if (self.target) {
shnook = world;
do
{
shnook = find(shnook, targetname, self.target);
} while (shnook.classname != "lightning_waypoint");
// Safety measure in case map designer assigns lights target too...
}
self.owner = shnook;
self.think = self.use = lightning_trigger;
if (self.targetname == "")
self.nextthink = time + self.waitmin + random() * (self.waitmax - self.waitmin);
};
void() info_lightning =
{
if (deathmatch) {
remove(self);
return;
}
//if (!self.style)
// objerror("info_lightning has no style");
if (self.style && (self.style < 12))
objerror("info_lightning has invalid style");
// Ridah: target no longer required, but used if present
//if (!self.target)
// objerror("info_lightning has no target");
if (!self.waitmin) self.waitmin = 3;
if (!self.waitmax) self.waitmax = 10;
if (!self.distance) self.distance = 64;
if (!self.dmg) self.dmg = 50;
if (self.style >= 12)
lightstyle(self.style, "a");
if (self.x_flags == 1)
precache_sound ("ambience/elect.wav");
else
precache_sound ("ambience/thunder1.wav");
self.think = lightning_sp_start; // wait for all our buddies to spawn
self.nextthink = time + 0.2;
};
// End Xmen

80
MINES.c Normal file
View file

@ -0,0 +1,80 @@
/* Begin Xmen
Mines revision 1
-cl2-
Files involved:
mines.qc (this file)
client.qc (obituaries)
tripwire.qc (explosion function)
How to implement in a .map file:
Stick a 'mine' wherever you want a mine. Just like any other object or monster,
it should be placed just above the floor.
Some optional fields are "dmg", the maximum damage the mine inflicts,
and "distance", the distance the mine scans. For a normal mine, just omit them.
*/
// Just waitin' for someone to start with us... ;)
void() mine_scan =
{
local entity shnook;
shnook = findradius(self.origin, self.distance);
while(shnook)
{
if(shnook.health) // Should this only trip off for players?
{
self.think = BlowMeUp;
self.nextthink = time + 0.1;
return;
}
shnook = shnook.chain;
}
self.nextthink = time + 0.1;
};
// Mine start (mine has to start after world)
void() mine_start =
{
self.velocity = '0 0 0';
self.movetype = MOVETYPE_TOSS;
if (!droptofloor())
{
dprint ("Mine fell out of level at ");
dprint (vtos(self.origin));
dprint ("\n");
remove(self);
return;
}
self.health = 1;
self.th_die = BlowMeUp;
self.takedamage = DAMAGE_YES;
self.think = mine_scan;
self.nextthink = time + 0.1;
};
// Mine spawn
void() mine =
{
if (deathmatch) {
remove(self);
return;
}
if (!self.distance) self.distance = 64;
if (!self.dmg) self.dmg = 120;
precache_model("progs/mine.mdl");
setmodel(self, "progs/mine.mdl");
setsize(self, '-4 -4 0', '4 4 4');
self.think = mine_start;
self.nextthink = time + 0.2; // Put it in after world spawns (droptofloor)
};
// End Xmen

747
MISC.c Normal file
View file

@ -0,0 +1,747 @@
/*QUAKED info_null (0 0.5 0) (-4 -4 -4) (4 4 4)
Used as a positional target for spotlights, etc.
*/
void() info_null =
{
remove(self);
};
/*QUAKED info_notnull (0 0.5 0) (-4 -4 -4) (4 4 4)
Used as a positional target for lightning.
*/
void() info_notnull =
{
};
//============================================================================
float START_OFF = 1;
void() light_use =
{
if (self.spawnflags & START_OFF)
{
lightstyle(self.style, "m");
self.spawnflags = self.spawnflags - START_OFF;
}
else
{
lightstyle(self.style, "a");
self.spawnflags = self.spawnflags + START_OFF;
}
};
/*QUAKED light (0 1 0) (-8 -8 -8) (8 8 8) START_OFF
Non-displayed light.
Default light value is 300
Default style is 0
If targeted, it will toggle between on or off.
*/
void() light =
{
if (!self.targetname)
{ // inert light
remove(self);
return;
}
if (self.style >= 32)
{
self.use = light_use;
if (self.spawnflags & START_OFF)
lightstyle(self.style, "a");
else
lightstyle(self.style, "m");
}
};
/*QUAKED light_fluoro (0 1 0) (-8 -8 -8) (8 8 8) START_OFF
Non-displayed light.
Default light value is 300
Default style is 0
If targeted, it will toggle between on or off.
Makes steady fluorescent humming sound
*/
void() light_fluoro =
{
if (self.style >= 32)
{
self.use = light_use;
if (self.spawnflags & START_OFF)
lightstyle(self.style, "a");
else
lightstyle(self.style, "m");
}
precache_sound ("ambience/fl_hum1.wav");
ambientsound (self.origin, "ambience/fl_hum1.wav", 0.5, ATTN_STATIC);
};
/*QUAKED light_fluorospark (0 1 0) (-8 -8 -8) (8 8 8)
Non-displayed light.
Default light value is 300
Default style is 10
Makes sparking, broken fluorescent sound
*/
void() light_fluorospark =
{
if (!self.style)
self.style = 10;
precache_sound ("ambience/buzz1.wav");
ambientsound (self.origin, "ambience/buzz1.wav", 0.5, ATTN_STATIC);
};
/*QUAKED light_globe (0 1 0) (-8 -8 -8) (8 8 8)
Sphere globe light.
Default light value is 300
Default style is 0
*/
void() light_globe =
{
precache_model ("progs/s_light.spr");
setmodel (self, "progs/s_light.spr");
makestatic (self);
};
void() FireAmbient =
{
precache_sound ("ambience/fire1.wav");
// attenuate fast
ambientsound (self.origin, "ambience/fire1.wav", 0.2, 3);
};
/*QUAKED light_torch_small_walltorch (0 .5 0) (-10 -10 -20) (10 10 20)
Short wall torch
Default light value is 200
Default style is 0
*/
void() light_torch_small_walltorch =
{
precache_model ("progs/flame.mdl");
setmodel (self, "progs/flame.mdl");
FireAmbient ();
makestatic (self);
};
/*QUAKED light_flame_large_yellow (0 1 0) (-10 -10 -12) (12 12 18)
Large yellow flame ball
*/
void() light_flame_large_yellow =
{
precache_model ("progs/flame2.mdl");
setmodel (self, "progs/flame2.mdl");
self.frame = 1;
FireAmbient ();
makestatic (self);
};
/*QUAKED light_flame_small_yellow (0 1 0) (-8 -8 -8) (8 8 8) START_OFF
Small yellow flame ball
*/
void() light_flame_small_yellow =
{
precache_model ("progs/flame2.mdl");
setmodel (self, "progs/flame2.mdl");
FireAmbient ();
makestatic (self);
};
/*QUAKED light_flame_small_white (0 1 0) (-10 -10 -40) (10 10 40) START_OFF
Small white flame ball
*/
void() light_flame_small_white =
{
precache_model ("progs/flame2.mdl");
setmodel (self, "progs/flame2.mdl");
FireAmbient ();
makestatic (self);
};
//============================================================================
/*QUAKED misc_fireball (0 .5 .8) (-8 -8 -8) (8 8 8)
Lava Balls
*/
void() fire_fly;
void() fire_touch;
void() misc_fireball =
{
remove(self);
return;
/*
precache_model ("progs/lavaball.mdl");
self.classname = "fireball";
self.nextthink = time + (random() * 5);
self.think = fire_fly;
if (!self.speed)
self.speed == 1000;
*/
};
void() fire_fly =
{
local entity fireball;
fireball = spawn();
fireball.solid = SOLID_TRIGGER;
fireball.movetype = MOVETYPE_TOSS;
fireball.velocity = '0 0 1000';
fireball.velocity_x = (random() * 100) - 50;
fireball.velocity_y = (random() * 100) - 50;
fireball.velocity_z = self.speed + (random() * 200);
fireball.classname = "fireball";
setmodel (fireball, "progs/lavaball.mdl");
setsize (fireball, '0 0 0', '0 0 0');
setorigin (fireball, self.origin);
fireball.nextthink = time + 5;
fireball.think = SUB_Remove;
fireball.touch = fire_touch;
self.nextthink = time + (random() * 5) + 3;
self.think = fire_fly;
};
void() fire_touch =
{
T_Damage (other, self, self, 20);
remove(self);
};
//============================================================================
void() barrel_explode =
{
self.takedamage = DAMAGE_NO;
self.classname = "explo_box";
// did say self.owner
T_RadiusDamage (self, self, 160, world);
sound (self, CHAN_VOICE, "weapons/r_exp3.wav", 1, ATTN_NORM);
particle (self.origin, '0 0 0', 75, 255);
self.origin_z = self.origin_z + 32;
BecomeExplosion ();
};
/*QUAKED misc_explobox (0 .5 .8) (0 0 0) (32 32 64)
TESTING THING
*/
void() misc_explobox =
{
local float oldz;
self.solid = SOLID_BBOX;
self.movetype = MOVETYPE_NONE;
precache_model ("maps/b_explob.bsp");
setmodel (self, "maps/b_explob.bsp");
precache_sound ("weapons/r_exp3.wav");
self.health = 20;
self.th_die = barrel_explode;
self.takedamage = DAMAGE_AIM;
self.origin_z = self.origin_z + 2;
oldz = self.origin_z;
droptofloor();
if (oldz - self.origin_z > 250)
{
dprint ("item fell out of level at ");
dprint (vtos(self.origin));
dprint ("\n");
remove(self);
}
};
/*QUAKED misc_explobox2 (0 .5 .8) (0 0 0) (32 32 64)
Smaller exploding box, REGISTERED ONLY
*/
void() misc_explobox2 =
{
local float oldz;
self.solid = SOLID_BBOX;
self.movetype = MOVETYPE_NONE;
precache_model2 ("maps/b_exbox2.bsp");
setmodel (self, "maps/b_exbox2.bsp");
precache_sound ("weapons/r_exp3.wav");
self.health = 20;
self.th_die = barrel_explode;
self.takedamage = DAMAGE_AIM;
self.origin_z = self.origin_z + 2;
oldz = self.origin_z;
droptofloor();
if (oldz - self.origin_z > 250)
{
dprint ("item fell out of level at ");
dprint (vtos(self.origin));
dprint ("\n");
remove(self);
}
};
//============================================================================
float SPAWNFLAG_SUPERSPIKE = 1;
float SPAWNFLAG_LASER = 2;
/*QUAKED trap_spikeshooter (0 .5 .8) (-8 -8 -8) (8 8 8) superspike laser
When triggered, fires a spike in the direction set in QuakeEd.
Laser is only for REGISTERED.
*/
void() trap_spikeshooter =
{
remove(self);
};
/*QUAKED trap_shooter (0 .5 .8) (-8 -8 -8) (8 8 8) superspike laser
Continuously fires spikes.
"wait" time between spike (1.0 default)
"nextthink" delay before firing first spike, so multiple shooters can be stagered.
*/
void() trap_shooter =
{
remove(self);
};
//---------------------------------------------------------------
// X-Men: Flame-thrower trap
//---------------------------------------------------------------
void() flamethrower_think =
{
if (self.attack_finished < time) {
if (self.flags & FL_FLAMEON) {
// stop the flame, and set next think to start flame
self.flags = self.flags - (self.flags & FL_FLAMEON);
if (self.classname == "trap_flamethrower_constant") {
self.nextthink = time + self.pausetime;
// set next firing finish time
self.attack_finished = self.nextthink + self.delay;
}
else {
self.nextthink = -1;
}
// restart at starting angle
self.v_angle = self.angles;
return;
}
}
if (self.flags & FL_FLAMEON) {
self.v_angle_y = self.v_angle_y + (self.speed * (time - self.last_flame));
if (self.speed > 0) {
if ((self.v_angle_y - self.angles_y) > self.sway_range) {
self.speed = -1 * self.speed;
}
}
else {
if ((self.v_angle_y - self.angles_y) < (-1 * self.sway_range)) {
self.speed = -1 * self.speed;
}
}
}
else {
sound(self, CHAN_BODY, "weapons/f_start.wav", 1, ATTN_NORM);
}
W_FireFlameThrower();
self.flags = self.flags | FL_FLAMEON;
self.nextthink = time + 0.05;
};
/* Trap Flamethrower, fires constantly, with a break every
"delay" seconds (default 1), pausing for
"pausetime" seconds (default = 1) before firing again. Also use
"sway_range" to set left/right swaying range (default 0), and
"speed" = degrees per second at which the flamethrower rotates (default 120)*/
void() trap_flamethrower_constant =
{
// create flamethrower entities
self.flame_ent1 = spawn_flame_ent();
self.flame_ent2 = spawn_flame_ent();
self.flame_ent3 = spawn_flame_ent();
self.v_angle = self.angles;
if ((self.sway_range) && (self.speed == 0)) {
self.speed = 120;
}
if (self.pausetime == 0)
self.pausetime = 1;
if (self.delay == 0)
self.delay = 1;
self.weapon = IT_SUPER_NAILGUN; // so monsters get torched
self.nextthink = time + random() + self.wait;
self.think = flamethrower_think;
};
// ****************************************
void() trap_flamethrower_use =
{
// give 1 second of flames
self.attack_finished = time + 1;
if (self.nextthink == -1) // restart thinker
self.nextthink = time + 0.05;
};
// Triggerable verison of flamethrower
void() trap_flamethrower =
{
// create flamethrower entities
self.flame_ent1 = spawn_flame_ent();
self.flame_ent2 = spawn_flame_ent();
self.flame_ent3 = spawn_flame_ent();
self.v_angle = self.angles;
if ((self.sway_range) && (self.speed == 0)) {
self.speed = 120;
}
self.weapon = IT_SUPER_NAILGUN; // so monsters get torched
self.nextthink = -1;
self.think = flamethrower_think;
self.use = trap_flamethrower_use;
};
//---------------------------------------------------------------
/*
===============================================================================
===============================================================================
*/
void() make_bubbles;
void() bubble_remove;
void() bubble_bob;
/*QUAKED air_bubbles (0 .5 .8) (-8 -8 -8) (8 8 8)
testing air bubbles
*/
void() air_bubbles =
{
if (deathmatch)
{
remove (self);
return;
}
precache_model ("progs/s_bubble.spr");
self.nextthink = time + 1;
self.think = make_bubbles;
};
void() make_bubbles =
{
local entity bubble;
bubble = spawn();
setmodel (bubble, "progs/s_bubble.spr");
setorigin (bubble, self.origin);
bubble.movetype = MOVETYPE_NOCLIP;
bubble.solid = SOLID_NOT;
bubble.velocity = '0 0 15';
bubble.nextthink = time + 0.5;
bubble.think = bubble_bob;
bubble.touch = bubble_remove;
bubble.classname = "bubble";
bubble.frame = 0;
bubble.cnt = 0;
setsize (bubble, '-8 -8 -8', '8 8 8');
self.nextthink = time + random() + 0.5;
self.think = make_bubbles;
};
void() bubble_split =
{
local entity bubble;
bubble = spawn();
setmodel (bubble, "progs/s_bubble.spr");
setorigin (bubble, self.origin);
bubble.movetype = MOVETYPE_NOCLIP;
bubble.solid = SOLID_NOT;
bubble.velocity = self.velocity;
bubble.nextthink = time + 0.5;
bubble.think = bubble_bob;
bubble.touch = bubble_remove;
bubble.classname = "bubble";
bubble.frame = 1;
bubble.cnt = 10;
setsize (bubble, '-8 -8 -8', '8 8 8');
self.frame = 1;
self.cnt = 10;
if (self.waterlevel != 3)
remove (self);
};
void() bubble_remove =
{
if (other.classname == self.classname)
{
// dprint ("bump");
return;
}
remove(self);
};
void() bubble_bob =
{
local float rnd1, rnd2, rnd3;
local vector vtmp1, modi;
self.cnt = self.cnt + 1;
if (self.cnt == 4)
bubble_split();
if (self.cnt == 20)
remove(self);
rnd1 = self.velocity_x + (-10 + (random() * 20));
rnd2 = self.velocity_y + (-10 + (random() * 20));
rnd3 = self.velocity_z + 10 + random() * 10;
if (rnd1 > 10)
rnd1 = 5;
if (rnd1 < -10)
rnd1 = -5;
if (rnd2 > 10)
rnd2 = 5;
if (rnd2 < -10)
rnd2 = -5;
if (rnd3 < 10)
rnd3 = 15;
if (rnd3 > 30)
rnd3 = 25;
self.velocity_x = rnd1;
self.velocity_y = rnd2;
self.velocity_z = rnd3;
self.nextthink = time + 0.5;
self.think = bubble_bob;
};
/*~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>
~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~*/
/*QUAKED viewthing (0 .5 .8) (-8 -8 -8) (8 8 8)
Just for the debugging level. Don't use
*/
void() viewthing =
{
self.movetype = MOVETYPE_NONE;
self.solid = SOLID_NOT;
precache_model ("progs/player.mdl");
setmodel (self, "progs/player.mdl");
};
/*
==============================================================================
SIMPLE BMODELS
==============================================================================
*/
void() func_wall_use =
{ // change to alternate textures
self.frame = 1 - self.frame;
};
/*QUAKED func_wall (0 .5 .8) ?
This is just a solid wall if not inhibitted
*/
void() func_wall =
{
self.angles = '0 0 0';
self.movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything
self.solid = SOLID_BSP;
self.use = func_wall_use;
setmodel (self, self.model);
};
/*QUAKED func_illusionary (0 .5 .8) ?
A simple entity that looks solid but lets you walk through it.
*/
void() func_illusionary =
{
self.angles = '0 0 0';
self.movetype = MOVETYPE_NONE;
self.solid = SOLID_NOT;
setmodel (self, self.model);
makestatic ();
};
/*QUAKED func_episodegate (0 .5 .8) ? E1 E2 E3 E4
This bmodel will appear if the episode has allready been completed, so players can't reenter it.
*/
void() func_episodegate =
{
if (!(serverflags & self.spawnflags))
return; // can still enter episode
self.angles = '0 0 0';
self.movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything
self.solid = SOLID_BSP;
self.use = func_wall_use;
setmodel (self, self.model);
};
/*QUAKED func_bossgate (0 .5 .8) ?
This bmodel appears unless players have all of the episode sigils.
*/
void() func_bossgate =
{
if ( (serverflags & 15) == 15)
return; // all episodes completed
self.angles = '0 0 0';
self.movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything
self.solid = SOLID_BSP;
self.use = func_wall_use;
setmodel (self, self.model);
};
//============================================================================
/*QUAKED ambient_suck_wind (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
*/
void() ambient_suck_wind =
{
precache_sound ("ambience/suck1.wav");
ambientsound (self.origin, "ambience/suck1.wav", 1, ATTN_STATIC);
};
/*QUAKED ambient_drone (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
*/
void() ambient_drone =
{
precache_sound ("ambience/drone6.wav");
ambientsound (self.origin, "ambience/drone6.wav", 0.5, ATTN_STATIC);
};
/*QUAKED ambient_flouro_buzz (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
*/
void() ambient_flouro_buzz =
{
precache_sound ("ambience/buzz1.wav");
ambientsound (self.origin, "ambience/buzz1.wav", 1, ATTN_STATIC);
};
/*QUAKED ambient_drip (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
*/
void() ambient_drip =
{
precache_sound ("ambience/drip1.wav");
ambientsound (self.origin, "ambience/drip1.wav", 0.5, ATTN_STATIC);
};
/*QUAKED ambient_comp_hum (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
*/
void() ambient_comp_hum =
{
precache_sound ("ambience/comp1.wav");
ambientsound (self.origin, "ambience/comp1.wav", 1, ATTN_STATIC);
};
/*QUAKED ambient_thunder (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
*/
void() ambient_thunder =
{
precache_sound ("ambience/thunder1.wav");
ambientsound (self.origin, "ambience/thunder1.wav", 0.5, ATTN_STATIC);
};
/*QUAKED ambient_light_buzz (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
*/
void() ambient_light_buzz =
{
precache_sound ("ambience/fl_hum1.wav");
ambientsound (self.origin, "ambience/fl_hum1.wav", 0.5, ATTN_STATIC);
};
/*QUAKED ambient_swamp1 (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
*/
void() ambient_swamp1 =
{
precache_sound ("ambience/swamp1.wav");
ambientsound (self.origin, "ambience/swamp1.wav", 0.5, ATTN_STATIC);
};
/*QUAKED ambient_swamp2 (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
*/
void() ambient_swamp2 =
{
precache_sound ("ambience/swamp2.wav");
ambientsound (self.origin, "ambience/swamp2.wav", 0.5, ATTN_STATIC);
};
//============================================================================
void() noise_think =
{
self.nextthink = time + 0.5;
sound (self, 1, "enforcer/enfire.wav", 1, ATTN_NORM);
sound (self, 2, "enforcer/enfstop.wav", 1, ATTN_NORM);
sound (self, 3, "enforcer/sight1.wav", 1, ATTN_NORM);
sound (self, 4, "enforcer/sight2.wav", 1, ATTN_NORM);
sound (self, 5, "enforcer/sight3.wav", 1, ATTN_NORM);
sound (self, 6, "enforcer/sight4.wav", 1, ATTN_NORM);
sound (self, 7, "enforcer/pain1.wav", 1, ATTN_NORM);
};
/*QUAKED misc_noisemaker (1 0.5 0) (-10 -10 -10) (10 10 10)
For optimzation testing, starts a lot of sounds.
*/
void() misc_noisemaker =
{
precache_sound2 ("enforcer/enfire.wav");
precache_sound2 ("enforcer/enfstop.wav");
precache_sound2 ("enforcer/sight1.wav");
precache_sound2 ("enforcer/sight2.wav");
precache_sound2 ("enforcer/sight3.wav");
precache_sound2 ("enforcer/sight4.wav");
precache_sound2 ("enforcer/pain1.wav");
precache_sound2 ("enforcer/pain2.wav");
precache_sound2 ("enforcer/death1.wav");
precache_sound2 ("enforcer/idle1.wav");
self.nextthink = time + 0.1 + random();
self.think = noise_think;
};

585
MODELS.c Normal file
View file

@ -0,0 +1,585 @@
/*
===============================================================================
WORLD WEAPONS
===============================================================================
*/
$modelname g_shot
$cd id1/models/g_shot
$origin 0 0 -24
$flags 8 // client side rotate
$base base
$skin skin
$frame shot1
$modelname g_nail
$cd id1/models/g_nail
$flags 8 // client side rotate
$origin 0 0 -24
$base base
$skin skin
$frame shot1
$modelname g_nail2
$cd id1/models/g_nail2
$flags 8 // client side rotate
$origin 0 0 -24
$base base
$skin skin
$frame shot2
$modelname g_rock
$cd id1/models/g_rock
$flags 8 // client side rotate
$origin 0 0 -24
$base base
$skin skin
$frame shot1
$modelname g_rock2
$cd id1/models/g_rock2
$flags 8 // client side rotate
$origin 0 0 -24
$base base
$skin skin
$frame shot1
$modelname g_light
$cd id1/models/g_light
$flags 8 // client side rotate
$origin 0 0 -24
$base base
$skin skin
$frame shot1
/*
===============================================================================
VIEW WEAPONS
===============================================================================
*/
$modelname v_axe
$cd id1/models/v_axe
$origin 0 5 54
$base base
$skin skin
$frame frame1 frame2 frame3 frame4 frame5 frame6 frame7 frame8 frame9
$modelname v_shot
$cd id1/models/v_shot
$origin 0 0 54
$base base
$skin skin
$frame shot1 shot2 shot3 shot4 shot5 shot6 shot7
$modelname v_shot2
$cd id1/models/v_shot2
$origin 0 0 56
$base base
$skin skin
$frame shot1 shot2 shot3 shot4 shot5 shot6 shot7
$modelname v_rock2
$cd id1/models/v_rock2
$origin 0 0 54
$base base
$skin skin
$frame shot1 shot2 shot3 shot4 shot5 shot6 shot6
$modelname v_rock
$cd id1/models/v_rock
$origin 0 0 54
$base base
$skin skin
$frame shot1 shot2 shot3 shot4 shot5 shot6 shot7
$modelname v_nail2
$cd id1/models/v_nail2
$origin 0 0 54
$base base
$skin skin
$frame shot1 shot2 shot3 shot4 shot5 shot6 shot7 shot8 shot9
$modelname v_nail
$cd id1/models/v_nail
$origin 0 0 54
$base base
$skin skin
$frame shot1 shot2 shot3 shot4 shot5 shot6 shot7 shot8 shot9
$modelname v_light
$cd id1/models/v_light
$origin 0 0 54
$base base
$skin skin
$frame shot1 shot2 shot3 shot4 shot5
/*
===============================================================================
ITEMS
===============================================================================
*/
$modelname w_g_key
$cd id1/models/w_g_key
$flags 8 // client side rotate
$base base
$skin skin
$frame frame1
$modelname w_s_key
$cd id1/models/w_s_key
$flags 8 // client side rotate
$base base
$skin skin
$frame frame1
$modelname m_g_key
$cd id1/models/m_g_key
$flags 8 // client side rotate
$base base
$skin skin
$frame frame1
$modelname m_s_key
$cd id1/models/m_s_key
$flags 8 // client side rotate
$base base
$skin skin
$frame frame1
$modelname b_g_key
$cd id1/models/b_g_key
$flags 8 // client side rotate
$base base
$skin skin
$frame frame1
$modelname b_s_key
$cd id1/models/b_s_key
$flags 8 // client side rotate
$base base
$skin skin
$frame frame1
$modelname quaddama
$cd id1/models/quaddama
$flags 8 // client side rotate
$base base
$skin skin
$frame frame1
$modelname invisibl
$cd id1/models/invisibl
$flags 8 // client side rotate
$base base
$skin skin
$frame frame1
$modelname invulner
$flags 8 // client side rotate
$cd id1/models/invulner
$base base
$skin skin
$frame frame1
//modelname jetpack
//cd id1/models/jetpack
//flags 8 // client side rotate
//base base
//skin skin
//frame frame1
$modelname cube
$cd id1/models/cube
$flags 8 // client side rotate
$base base
$skin skin
$frame frame1
$modelname suit
$cd id1/models/suit
$flags 8 // client side rotate
$base base
$skin skin
$frame frame1
$modelname boots
$cd id1/models/boots
$flags 8 // client side rotate
$base base
$skin skin
$frame frame1
$modelname end1
$cd id1/models/end1
$flags 8 // client side rotate
$base base
$skin skin
$frame frame1
$modelname end2
$cd id1/models/end2
$flags 8 // client side rotate
$base base
$skin skin
$frame frame1
$modelname end3
$cd id1/models/end3
$flags 8 // client side rotate
$base base
$skin skin
$frame frame1
$modelname end4
$cd id1/models/end4
$flags 8 // client side rotate
$base base
$skin skin
$frame frame1
/*
===============================================================================
GIBS
===============================================================================
*/
$modelname gib1
$cd id1/models/gib1
$flags 4 // EF_GIB
$origin 0 0 0
$base base
$skin skin
$frame frame1
// torso
$modelname gib2
$cd id1/models/gib2
$flags 4 // EF_GIB
$origin 0 0 0
$base base
$skin skin
$frame frame1
$modelname gib3
$cd id1/models/gib3
$flags 4 // EF_GIB
$origin 0 0 0
$base base
$skin skin
$frame frame1
// heads
$modelname h_player
$cd id1/models/h_player
$flags 4 // EF_GIB
$origin 0 0 0
$base base
$skin skin
$frame frame1
$modelname h_dog
$cd id1/models/h_dog
$flags 4 // EF_GIB
$origin 0 0 0
$base base
$skin skin
$frame frame1
$modelname h_mega
$cd id1/models/h_mega
$flags 4 // EF_GIB
$origin 0 0 0
$base base
$skin skin
$frame frame1
$modelname h_guard
$cd id1/models/h_guard
$flags 4 // EF_GIB
$origin 0 0 0
$base base
$skin skin
$frame frame1
$modelname h_wizard
$cd id1/models/h_wizard
$flags 4 // EF_GIB
$origin 0 0 0
$base base
$skin skin
$frame frame1
$modelname h_knight
$cd id1/models/h_knight
$flags 4 // EF_GIB
$origin 0 0 0
$base base
$skin skin
$frame frame1
$modelname h_hellkn
$cd id1/models/h_hellkn
$flags 4 // EF_GIB
$origin 0 0 0
$base base
$skin skin
$frame frame1
$modelname h_zombie
$cd id1/models/h_zombie
$flags 4 // EF_GIB
$origin 0 0 0
$base base
$skin skin
$frame frame1
$modelname h_shams
$cd id1/models/h_shams
$flags 4 // EF_GIB
$origin 0 0 0
$base base
$skin skin
$frame frame1
$modelname h_shal
$cd id1/models/h_shal
$flags 4 // EF_GIB
$origin 0 0 0
$base base
$skin skin
$frame frame1
$modelname h_ogre
$cd id1/models/h_ogre
$flags 4 // EF_GIB
$origin 0 0 0
$base base
$skin skin
$frame frame1
$modelname h_demon
$cd id1/models/h_demon
$flags 4 // EF_GIB
$origin 0 0 0
$base base
$skin skin
$frame frame1
/*
===============================================================================
MISC
===============================================================================
*/
$modelname armor
$cd id1/models/armor
$flags 8 // client side rotate
$origin 0 0 -8
$base base
$skin skin
$skin skin2
$skin skin3
$frame armor
$modelname s_light // shambler lightning ready
$cd id1/models/s_light
$origin 0 0 24
$base base
$skin skin
$frame frame1 frame2 frame3
$modelname bolt3 // lightning towar bolts
$cd id1/models/bolt2
$origin 0 0 0
$base base
$scale 4
$skin skin
$frame light
$modelname bolt2
$cd id1/models/bolt2
$origin 0 0 0
$base base
$skin skin
$frame light
$modelname bolt
$cd id1/models/bolt
$origin 0 0 0
$base light
$skin light
$frame light
$modelname laser
$cd id1/models/laser
$base base
$skin skin
$scale 2
$frame frame1
$modelname flame // with torch
$cd id1/models/flame
$origin 0 0 12
$base base
$skin skin
$framegroupstart
$frame flame1 0.1
$frame flame2 0.1
$frame flame3 0.1
$frame flame4 0.1
$frame flame5 0.1
$frame flame6 0.1
$framegroupend
$modelname flame2 // standing flame, no torch
$cd id1/models/flame2
$origin 0 0 12
$base base
$skin skin
$framegroupstart
$frame flame1 0.1
$frame flame2 0.1
$frame flame3 0.1
$frame flame4 0.1
$frame flame5 0.1
$frame flame6 0.1
$framegroupend
$framegroupstart
$frame flameb1
$frame flameb2
$frame flameb3
$frame flameb4
$frame flameb5
$frame flameb6
$frame flameb7
$frame flameb8
$frame flameb9
$frame flameb10
$frame flameb11
$framegroupend
$modelname zom_gib
$cd id1/models/zom_gib
$flags 32 // EF_ZOMGIB
$base base
$skin skin
$frame frame1
$modelname eyes
$cd id1/models/eyes
$origin 0 0 -24
$base base
$skin skin
$frame frame1
$modelname spike
$cd id1/models/spike
$origin 0 0 0
$base spike
$skin skin
$frame spike
$modelname s_spike
$cd id1/models/s_spike
$origin 0 0 0
$base spike
$skin skin
$frame spike
$modelname v_spike
$cd id1/models/v_spike
$flags 128 // EF_TRACER3
$origin 0 0 0
$base base
$skin skin
$frame frame1
$modelname w_spike
$cd id1/models/w_spike
$flags 16 // EF_TRACER
$origin 0 0 0
$base base
$skin skin
$framegroupstart
$frame frame1 0.1
$frame frame2 0.1
$frame frame3 0.1
$frame frame4 0.1
$framegroupend
$modelname k_spike
$cd id1/models/k_spike
$flags 64 // EF_TRACER2
$origin 0 0 0
$base base
$skin skin
$frame frame1
$modelname backpack
$cd id1/models/backpack
$flags 8 // EF_ROTATE
$origin 0 0 0
$base base
$skin skin
$frame frame1
$modelname grenade
$cd id1/models/grenade2
$flags 2 // EF_GRENADE
$origin 0 0 0
$base base
$skin skin
$frame grenade
$modelname missile
$cd id1/models/missile
$flags 1 // EF_ROCKET
$origin 0 0 0
$base base
$skin skin
$frame missile
$modelname lavaball
$cd id1/models/lavaball
$flags 1 // EF_ROCKET
$origin 0 0 0
$base base
$skin skin
$frame frame1
$modelname teleport
$cd id1/models/teleport
$origin 0 0 24
$base base
$skin skin
$frame frame1

283
MONSTERS.c Normal file
View file

@ -0,0 +1,283 @@
/* ALL MONSTERS SHOULD BE 1 0 0 IN COLOR */
// name =[framenum, nexttime, nextthink] {code}
// expands to:
// name ()
// {
// self.frame=framenum;
// self.nextthink = time + nexttime;
// self.think = nextthink
// <code>
// };
/*
================
monster_use
Using a monster makes it angry at the current activator
================
*/
void() monster_use =
{
if (self.enemy)
return;
if (self.health <= 0)
return;
if (activator.items & IT_INVISIBILITY)
return;
if (activator.flags & FL_NOTARGET)
return;
if (activator.classname != "player")
return;
// delay reaction so if the monster is teleported, its sound is still
// heard
self.enemy = activator;
self.nextthink = time + 0.1;
self.think = FoundTarget;
};
/*
================
monster_death_use
When a mosnter dies, it fires all of its targets with the current
enemy as activator.
================
*/
void() monster_death_use =
{
local entity ent, otemp, stemp;
// fall to ground
if (self.flags & FL_FLY)
self.flags = self.flags - FL_FLY;
if (self.flags & FL_SWIM)
self.flags = self.flags - FL_SWIM;
if (!self.target)
return;
activator = self.enemy;
SUB_UseTargets ();
};
//============================================================================
void() walkmonster_start_go =
{
local string stemp;
local entity etemp;
self.origin_z = self.origin_z + 1; // raise off floor a bit
droptofloor();
if (!walkmove(0,0) && (self.classname != "apocalypse_small"))
{
bprint(self.classname);
bprint (" in wall at: ");
bprint (vtos(self.origin));
bprint ("\n");
}
// X-Men: increase strength of monsters depending on skill
if (self.health > 50) {
if ((self.health > 160) && (self.health < 500) && (self.classname != "xmen_wolverine"))
self.health = 160;
self.health = self.health + (cvar("skill") - 2) * 10;
if (cvar("skill") > 1)
self.health = self.health + cvar("skill") + 15;
}
// end
// X-Men: set starting health
self.start_health = self.health;
// end
self.takedamage = DAMAGE_AIM;
self.ideal_yaw = self.angles * '0 1 0';
if (!self.yaw_speed)
self.yaw_speed = 20;
self.view_ofs = '0 0 25';
self.use = monster_use;
self.flags = self.flags | FL_MONSTER;
if (self.target)
{
self.goalentity = self.movetarget = find(world, targetname, self.target);
self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin);
if (!self.movetarget)
{
dprint ("Monster can't find target at ");
dprint (vtos(self.origin));
dprint ("\n");
}
// this used to be an objerror
if (self.movetarget.classname == "path_corner")
self.th_walk ();
else
self.pausetime = 99999999;
self.th_stand ();
}
else
{
self.pausetime = 99999999;
self.th_stand ();
}
// spread think times so they don't all happen at same time
self.nextthink = self.nextthink + random()*0.5;
};
void() walkmonster_start =
{
// delay drop to floor to make sure all doors have been spawned
// spread think times so they don't all happen at same time
self.nextthink = self.nextthink + random()*0.5;
self.think = walkmonster_start_go;
if ((self.classname != "xmen_wolverine") && (!(self.spawnflags & SPAWNFLAG_CLONE)) && (self.classname != "xmen_apocalypse") && (self.classname != "apocalypse_small") && (self.classname != "xmen_sinister"))
total_monsters = total_monsters + 1;
};
void() flymonster_start_go =
{
// X-Men: increase strength of monsters depending on skill
if (self.health > 50) {
if ((self.health > 160) && (self.health < 500) && (self.classname != "xmen_wolverine"))
self.health = 160;
self.health = self.health + (cvar("skill") - 2) * 10;
if (cvar("skill") > 1)
self.health = self.health + cvar("skill") + 15;
}
// end
// X-Men: set starting health
self.start_health = self.health;
// end
self.takedamage = DAMAGE_AIM;
self.ideal_yaw = self.angles * '0 1 0';
if (!self.yaw_speed)
self.yaw_speed = 10;
self.view_ofs = '0 0 25';
self.use = monster_use;
self.flags = self.flags | FL_FLY;
self.flags = self.flags | FL_MONSTER;
if (!walkmove(0,0))
{
dprint ("flymonster in wall at: ");
dprint (vtos(self.origin));
dprint ("\n");
}
if (self.target)
{
self.goalentity = self.movetarget = find(world, targetname, self.target);
if (!self.movetarget)
{
dprint ("Monster can't find target at ");
dprint (vtos(self.origin));
dprint ("\n");
}
// this used to be an objerror
if (self.movetarget.classname == "path_corner")
self.th_walk ();
else
self.pausetime = 99999999;
self.th_stand ();
}
else
{
self.pausetime = 99999999;
self.th_stand ();
}
};
void() flymonster_start =
{
// spread think times so they don't all happen at same time
self.nextthink = self.nextthink + random()*0.5;
self.think = flymonster_start_go;
if ((self.classname != "xmen_wolverine") && (!(self.spawnflags & SPAWNFLAG_CLONE)))
total_monsters = total_monsters + 1;
};
void() swimmonster_start_go =
{
if (deathmatch)
{
remove(self);
return;
}
// X-Men: increase strength of monsters (this is a hack)
if (self.health > 50)
self.health = self.health + 40;
// end
// X-Men: set starting health
self.start_health = self.health;
// end
self.takedamage = DAMAGE_AIM;
self.ideal_yaw = self.angles * '0 1 0';
if (!self.yaw_speed)
self.yaw_speed = 10;
self.view_ofs = '0 0 10';
self.use = monster_use;
self.flags = self.flags | FL_SWIM;
self.flags = self.flags | FL_MONSTER;
if (self.target)
{
self.goalentity = self.movetarget = find(world, targetname, self.target);
if (!self.movetarget)
{
dprint ("Monster can't find target at ");
dprint (vtos(self.origin));
dprint ("\n");
}
// this used to be an objerror
self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin);
self.th_walk ();
}
else
{
self.pausetime = 99999999;
self.th_stand ();
}
// spread think times so they don't all happen at same time
self.nextthink = self.nextthink + random()*0.5;
};
void() swimmonster_start =
{
// spread think times so they don't all happen at same time
self.nextthink = self.nextthink + random()*0.5;
self.think = swimmonster_start_go;
if ((self.classname != "xmen_wolverine") && (!(self.spawnflags & SPAWNFLAG_CLONE)))
total_monsters = total_monsters + 1;
};

50
PARTICLE.c Normal file
View file

@ -0,0 +1,50 @@
/* Begin Xmen
Particle Throwers revision 2
-cl2-
Additions:
r2: Cleaned up the code
Files involved:
particle.qc (this file)
How to implement in a .map file:
Stick a 'misc_particles' wherever you want the particles to come from.
set "angles" to whatever VECTOR you want the particles to shoot at, and
"count" to how many particles to shoot. (for density)
Another neat thing I figured I'd add (why not?) was you can also specify
"wait" if you want there to be a wait in between 'particle spurts'. If no
wait is specified, it will be a continuous stream.
"style" is the color index # of the particles thrown.
If anyone has a need for a random "wait" period (maybe for electrical
sparks or something?) let me know and I can throw it in very easily.
Same goes for toggle-able particle throwers. Just say the werd.
Remember self.angles is actually a VECTOR, which means "180 0 0" shoots
particles at 180 units/sec to the right.
Vector axes are x,y,z, in that order. If the player's yaw is 90 degrees,
x is left/right, y is forward/back, z is up/down.
*/
// Throw some particles around
void() particle_throw =
{
particle(self.origin, self.angles, self.style, self.count);
self.nextthink = time + self.wait;
};
// particle init.. duh.
void() misc_particles =
{
if (!self.wait) self.wait = 0.1;
if (!self.style) self.style = 1;
if (!self.count) self.count = 50; // nice round default number.
self.think = particle_throw;
self.nextthink = time + self.wait;
};
// End Xmen

368
PLATS.c Normal file
View file

@ -0,0 +1,368 @@
void() plat_center_touch;
void() plat_outside_touch;
void() plat_trigger_use;
void() plat_go_up;
void() plat_go_down;
void() plat_crush;
float PLAT_LOW_TRIGGER = 1;
void() plat_spawn_inside_trigger =
{
local entity trigger;
local vector tmin, tmax;
//
// middle trigger
//
trigger = spawn();
trigger.touch = plat_center_touch;
trigger.movetype = MOVETYPE_NONE;
trigger.solid = SOLID_TRIGGER;
trigger.enemy = self;
tmin = self.mins + '25 25 0';
tmax = self.maxs - '25 25 -8';
tmin_z = tmax_z - (self.pos1_z - self.pos2_z + 8);
if (self.spawnflags & PLAT_LOW_TRIGGER)
tmax_z = tmin_z + 8;
if (self.size_x <= 50)
{
tmin_x = (self.mins_x + self.maxs_x) / 2;
tmax_x = tmin_x + 1;
}
if (self.size_y <= 50)
{
tmin_y = (self.mins_y + self.maxs_y) / 2;
tmax_y = tmin_y + 1;
}
setsize (trigger, tmin, tmax);
};
void() plat_hit_top =
{
sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
self.state = STATE_TOP;
self.think = plat_go_down;
self.nextthink = self.ltime + 3;
};
void() plat_hit_bottom =
{
sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
self.state = STATE_BOTTOM;
};
void() plat_go_down =
{
sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
self.state = STATE_DOWN;
SUB_CalcMove (self.pos2, self.speed, plat_hit_bottom);
};
void() plat_go_up =
{
sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
self.state = STATE_UP;
SUB_CalcMove (self.pos1, self.speed, plat_hit_top);
};
void() plat_center_touch =
{
if (other.classname != "player")
return;
if (other.health <= 0)
return;
self = self.enemy;
if (self.state == STATE_BOTTOM)
plat_go_up ();
else if (self.state == STATE_TOP)
self.nextthink = self.ltime + 1; // delay going down
};
void() plat_outside_touch =
{
if (other.classname != "player")
return;
if (other.health <= 0)
return;
//dprint ("plat_outside_touch\n");
self = self.enemy;
if (self.state == STATE_TOP)
plat_go_down ();
};
void() plat_trigger_use =
{
if (self.think)
return; // allready activated
plat_go_down();
};
void() plat_crush =
{
//dprint ("plat_crush\n");
T_Damage (other, self, self, 1);
if (self.state == STATE_UP)
plat_go_down ();
else if (self.state == STATE_DOWN)
plat_go_up ();
else
objerror ("plat_crush: bad self.state\n");
};
void() plat_use =
{
self.use = SUB_Null;
if (self.state != STATE_UP)
objerror ("plat_use: not in up state");
plat_go_down();
};
/*QUAKED func_plat (0 .5 .8) ? PLAT_LOW_TRIGGER
speed default 150
Plats are always drawn in the extended position, so they will light correctly.
If the plat is the target of another trigger or button, it will start out disabled in the extended position until it is trigger, when it will lower and become a normal plat.
If the "height" key is set, that will determine the amount the plat moves, instead of being implicitly determined by the model's height.
Set "sounds" to one of the following:
1) base fast
2) chain slow
*/
void() func_plat =
{
local entity t;
if (!self.t_length)
self.t_length = 80;
if (!self.t_width)
self.t_width = 10;
if (self.sounds == 0)
self.sounds = 2;
// FIX THIS TO LOAD A GENERIC PLAT SOUND
if (self.sounds == 1)
{
precache_sound ("plats/plat1.wav");
precache_sound ("plats/plat2.wav");
self.noise = "plats/plat1.wav";
self.noise1 = "plats/plat2.wav";
}
else //if (self.sounds == 2)
{
precache_sound ("plats/medplat1.wav");
precache_sound ("plats/medplat2.wav");
self.noise = "plats/medplat1.wav";
self.noise1 = "plats/medplat2.wav";
}
self.mangle = self.angles;
self.angles = '0 0 0';
self.classname = "plat";
self.solid = SOLID_BSP;
self.movetype = MOVETYPE_PUSH;
setorigin (self, self.origin);
setmodel (self, self.model);
setsize (self, self.mins , self.maxs);
self.blocked = plat_crush;
if (!self.speed)
self.speed = 150;
// pos1 is the top position, pos2 is the bottom
self.pos1 = self.origin;
self.pos2 = self.origin;
if (self.height)
self.pos2_z = self.origin_z - self.height;
else
self.pos2_z = self.origin_z - self.size_z + 8;
self.use = plat_trigger_use;
plat_spawn_inside_trigger (); // the "start moving" trigger
if (self.targetname)
{
self.state = STATE_UP;
self.use = plat_use;
}
else
{
setorigin (self, self.pos2);
self.state = STATE_BOTTOM;
}
};
//============================================================================
void() train_next;
void() func_train_find;
void() train_blocked =
{
if (time < self.attack_finished)
return;
self.attack_finished = time + 0.5;
T_Damage (other, self, self, self.dmg);
};
void() train_use =
{
if (self.think != func_train_find)
return; // already activated
train_next();
};
void() train_wait =
{
if (self.wait)
{
self.nextthink = self.ltime + self.wait;
sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
}
else
self.nextthink = self.ltime + 0.1;
if (self.wait == -1) {
self.think = func_train_find;
return;
}
self.think = train_next;
};
void() train_next =
{
local entity targ;
targ = find (world, targetname, self.target);
self.target = targ.target;
if (!self.target)
objerror ("train_next: no next target");
if (targ.wait)
self.wait = targ.wait;
else
self.wait = 0;
sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
SUB_CalcMove (targ.origin - self.mins, self.speed, train_wait);
};
void() func_train_find =
{
local entity targ;
targ = find (world, targetname, self.target);
self.target = targ.target;
setorigin (self, targ.origin - self.mins);
if (!self.targetname)
{ // not triggered, so start immediately
self.nextthink = self.ltime + 0.1;
self.think = train_next;
}
};
/*QUAKED func_train (0 .5 .8) ?
Trains are moving platforms that players can ride.
The targets origin specifies the min point of the train at each corner.
The train spawns at the first target it is pointing at.
If the train is the target of a button or trigger, it will not begin moving until activated.
speed default 100
dmg default 2
sounds
1) ratchet metal
*/
void() func_train =
{
if (!self.speed)
self.speed = 100;
if (!self.target)
objerror ("func_train without a target");
if (!self.dmg)
self.dmg = 2;
if (self.sounds == 0)
{
self.noise = ("misc/null.wav");
precache_sound ("misc/null.wav");
self.noise1 = ("misc/null.wav");
precache_sound ("misc/null.wav");
}
if (self.sounds == 1)
{
self.noise = ("plats/train2.wav");
precache_sound ("plats/train2.wav");
self.noise1 = ("plats/train1.wav");
precache_sound ("plats/train1.wav");
}
self.cnt = 1;
self.solid = SOLID_BSP;
self.movetype = MOVETYPE_PUSH;
self.blocked = train_blocked;
self.use = train_use;
self.classname = "train";
setmodel (self, self.model);
setsize (self, self.mins , self.maxs);
setorigin (self, self.origin);
// start trains on the second frame, to make sure their targets have had
// a chance to spawn
self.nextthink = self.ltime + 0.1;
self.think = func_train_find;
};
/*QUAKED misc_teleporttrain (0 .5 .8) (-8 -8 -8) (8 8 8)
This is used for the final bos
*/
void() misc_teleporttrain =
{
if (!self.speed)
self.speed = 100;
if (!self.target)
objerror ("func_train without a target");
self.cnt = 1;
self.solid = SOLID_NOT;
self.movetype = MOVETYPE_PUSH;
self.blocked = train_blocked;
self.use = train_use;
self.avelocity = '100 200 300';
self.noise = ("misc/null.wav");
precache_sound ("misc/null.wav");
self.noise1 = ("misc/null.wav");
precache_sound ("misc/null.wav");
precache_model2 ("progs/teleport.mdl");
setmodel (self, "progs/teleport.mdl");
setsize (self, self.mins , self.maxs);
setorigin (self, self.origin);
// start trains on the second frame, to make sure their targets have had
// a chance to spawn
self.nextthink = self.ltime + 0.1;
self.think = func_train_find;
};

1181
PLAYER.c Normal file

File diff suppressed because it is too large Load diff

63
Progs.src Normal file
View file

@ -0,0 +1,63 @@
../progs.dat
defs.c
x_vars.c
x_cam.c
x_misc.c
x_sound.c
geometry.c
subs.c
fight.c
ai.c
combat.c
items.c
weapons.c
x_spwpn.c
world.c
client.c
player.c
monsters.c
doors.c
buttons.c
tripwire.c // xmen (cl2): Laser Tripwire Code
particle.c // xmen (cl2): Particle Throwers
mines.c // xmen (cl2): Mines
litening.c // xmen (cl2): Lightning
triggers.c
x_trig.c // xmen (cl2): trigger_constant
plats.c
misc.c
explbrsh.c // xmen (cl2): Exploding brush code
x_selch.c // xmen : select character stuff
x_tech.c // xmen : tech dude
x_ambient.c // xmen : ambient sounds
skeleton.c
// X-Men characters (implemented)
wolvie.c
storm.c
cyclops.c
beast.c
psylocke.c
angel.c
gambit.c
bishop.c
rogue.c
cannon.c
cannon2.c
phoenix.c
iceman.c
// X-Men Bosses
apsmall.c
appy.c
sinister.c
// Id's untouched monsters
//boss.c
x_debug.c

26
SPRITES.c Normal file
View file

@ -0,0 +1,26 @@
// these are the only sprites still in the game...
$spritename s_explod
$type vp_parallel
$load id1/gfx/sprites/explod03.lbm
$frame 24 24 56 56
$frame 120 24 56 56
$frame 216 24 56 56
$frame 24 88 56 56
$frame 120 88 56 56
$frame 216 88 56 56
$spritename s_bubble
$type vp_parallel
$load id1/gfx/sprites/bubble.lbm
$frame 16 16 16 16
$frame 40 16 16 16
$spritename s_light
$type vp_parallel
$load id1/gfx/sprites/light.lbm
$frame 104 32 32 32

332
SUBS.c Normal file
View file

@ -0,0 +1,332 @@
void() SUB_Null = {};
void() SUB_Remove = {remove(self);};
/*
QuakeEd only writes a single float for angles (bad idea), so up and down are
just constant angles.
*/
vector() SetMovedir =
{
if (self.angles == '0 -1 0')
self.movedir = '0 0 1';
else if (self.angles == '0 -2 0')
self.movedir = '0 0 -1';
else
{
makevectors (self.angles);
self.movedir = v_forward;
}
self.angles = '0 0 0';
};
/*
================
InitTrigger
================
*/
void() InitTrigger =
{
// trigger angles are used for one-way touches. An angle of 0 is assumed
// to mean no restrictions, so use a yaw of 360 instead.
if (self.angles != '0 0 0')
SetMovedir ();
self.solid = SOLID_TRIGGER;
setmodel (self, self.model); // set size and link into world
self.movetype = MOVETYPE_NONE;
self.modelindex = 0;
self.model = "";
};
/*
=============
SUB_CalcMove
calculate self.velocity and self.nextthink to reach dest from
self.origin traveling at speed
===============
*/
void(entity ent, vector tdest, float tspeed, void() func) SUB_CalcMoveEnt =
{
local entity stemp;
stemp = self;
self = ent;
SUB_CalcMove (tdest, tspeed, func);
self = stemp;
};
void(vector tdest, float tspeed, void() func) SUB_CalcMove =
{
local vector vdestdelta;
local float len, traveltime;
if (!tspeed)
objerror("No speed is defined!");
self.think1 = func;
self.finaldest = tdest;
self.think = SUB_CalcMoveDone;
if (tdest == self.origin)
{
self.velocity = '0 0 0';
self.nextthink = self.ltime + 0.1;
return;
}
// set destdelta to the vector needed to move
vdestdelta = tdest - self.origin;
// calculate length of vector
len = vlen (vdestdelta);
// divide by speed to get time to reach dest
traveltime = len / tspeed;
if (traveltime < 0.1)
{
self.velocity = '0 0 0';
self.nextthink = self.ltime + 0.1;
return;
}
// set nextthink to trigger a think when dest is reached
self.nextthink = self.ltime + traveltime;
// scale the destdelta vector by the time spent traveling to get velocity
self.velocity = vdestdelta * (1/traveltime); // qcc won't take vec/float
};
/*
============
After moving, set origin to exact final destination
============
*/
void() SUB_CalcMoveDone =
{
setorigin(self, self.finaldest);
self.velocity = '0 0 0';
self.nextthink = -1;
if (self.think1)
self.think1();
};
/*
=============
SUB_CalcAngleMove
calculate self.avelocity and self.nextthink to reach destangle from
self.angles rotating
The calling function should make sure self.think is valid
===============
*/
void(entity ent, vector destangle, float tspeed, void() func) SUB_CalcAngleMoveEnt =
{
local entity stemp;
stemp = self;
self = ent;
SUB_CalcAngleMove (destangle, tspeed, func);
self = stemp;
};
void(vector destangle, float tspeed, void() func) SUB_CalcAngleMove =
{
local vector destdelta;
local float len, traveltime;
if (!tspeed)
objerror("No speed is defined!");
// set destdelta to the vector needed to move
destdelta = destangle - self.angles;
// calculate length of vector
len = vlen (destdelta);
// divide by speed to get time to reach dest
traveltime = len / tspeed;
// set nextthink to trigger a think when dest is reached
self.nextthink = self.ltime + traveltime;
// scale the destdelta vector by the time spent traveling to get velocity
self.avelocity = destdelta * (1 / traveltime);
self.think1 = func;
self.finalangle = destangle;
self.think = SUB_CalcAngleMoveDone;
};
/*
============
After rotating, set angle to exact final angle
============
*/
void() SUB_CalcAngleMoveDone =
{
self.angles = self.finalangle;
self.avelocity = '0 0 0';
self.nextthink = -1;
if (self.think1)
self.think1();
};
//=============================================================================
void() DelayThink =
{
activator = self.enemy;
SUB_UseTargets ();
remove(self);
};
/*
==============================
SUB_UseTargets
the global "activator" should be set to the entity that initiated the firing.
If self.delay is set, a DelayedUse entity will be created that will actually
do the SUB_UseTargets after that many seconds have passed.
Centerprints any self.message to the activator.
Removes all entities with a targetname that match self.killtarget,
and removes them, so some events can remove other triggers.
Search for (string)targetname in all entities that
match (string)self.target and call their .use function
==============================
*/
void() SUB_UseTargets =
{
local entity t, stemp, otemp, act;
//
// check for a delay
//
if (self.delay)
{
// create a temp object to fire at a later time
t = spawn();
t.classname = "DelayedUse";
t.nextthink = time + self.delay;
t.think = DelayThink;
t.enemy = activator;
t.message = self.message;
t.weapon_parts = self.weapon_parts;
t.killtarget = self.killtarget;
t.target = self.target;
return;
}
//
// print the message
//
if ((activator.classname == "player") && (self.message != "") &&
((self.weapon_parts == 0) ||
((self.weapon_parts == 1) && !(serverflags & 1)) ||
((self.weapon_parts == 2) && !(serverflags & 2)) ||
((self.weapon_parts == 3) && !(serverflags & 4)) ||
((self.weapon_parts == 4) && !(serverflags & 8)) ))
{
activator.last_centerprint = self.message;
centerprint (activator, self.message);
if (!self.noise)
sound (activator, CHAN_VOICE, "misc/talk.wav", 1, ATTN_NORM);
}
//
// kill the killtagets
//
if (self.killtarget)
{
t = world;
do
{
t = find (t, targetname, self.killtarget);
if (!t)
return;
remove (t);
} while ( 1 );
}
//
// fire targets
//
if (self.target)
{
act = activator;
t = world;
do
{
t = find (t, targetname, self.target);
if (!t)
{
return;
}
stemp = self;
otemp = other;
self = t;
other = stemp;
if (self.use != SUB_Null)
{
if (self.use) {
self.use ();
/*
bprint("firing: ");
bprint(t.targetname);
bprint("\n");
*/
}
}
self = stemp;
other = otemp;
activator = act;
} while ( 1 );
}
};
/*
in nightmare mode, all attack_finished times become 0
some monsters refire twice automatically
*/
void(float normal) SUB_AttackFinished =
{
self.cnt = 0; // refire count for nightmare
if (skill != 3)
self.attack_finished = time + normal;
};
float (entity targ) visible;
void (void() thinkst) SUB_CheckRefire =
{
if (skill != 3)
return;
if (self.cnt == 1)
return;
if (!visible (self.enemy))
return;
self.cnt = 1;
self.think = thinkst;
};

686
TRIGGERS.c Normal file
View file

@ -0,0 +1,686 @@
entity stemp, otemp, s, old;
void() trigger_reactivate =
{
self.solid = SOLID_TRIGGER;
};
//=============================================================================
float SPAWNFLAG_NOMESSAGE = 1;
float SPAWNFLAG_NOTOUCH = 1;
// the wait time has passed, so set back up for another activation
void() multi_wait =
{
if (self.max_health)
{
self.health = self.max_health;
self.takedamage = DAMAGE_YES;
self.solid = SOLID_BBOX;
}
};
// the trigger was just touched/killed/used
// self.enemy should be set to the activator so it can be held through a delay
// so wait for the delay time before firing
void() multi_trigger =
{
if (self.nextthink > time)
{
return; // allready been triggered
}
if (self.classname == "trigger_secret")
{
if (self.enemy.classname != "player")
return;
found_secrets = found_secrets + 1;
WriteByte (MSG_ALL, SVC_FOUNDSECRET);
}
if (self.noise)
sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
// don't trigger again until reset
self.takedamage = DAMAGE_NO;
activator = self.enemy;
SUB_UseTargets();
if (self.wait > 0)
{
self.think = multi_wait;
self.nextthink = time + self.wait;
}
else
{ // we can't just remove (self) here, because this is a touch function
// called wheil C code is looping through area links...
self.touch = SUB_Null;
self.nextthink = time + 0.1;
self.think = SUB_Remove;
}
};
void() multi_killed =
{
self.enemy = damage_attacker;
multi_trigger();
};
void() multi_use =
{
self.enemy = activator;
multi_trigger();
};
void() multi_touch =
{
if (other.classname != "player")
return;
// if the trigger has an angles field, check player's facing direction
if (self.movedir != '0 0 0')
{
makevectors (other.angles);
if (v_forward * self.movedir < 0)
return; // not facing the right way
}
// check for weapon part warning message
// if (other.classname == "player" && self.message != "" && (other.weapon_parts < self.weapon_parts))
// return;
self.enemy = other;
multi_trigger ();
};
/*QUAKED trigger_multiple (.5 .5 .5) ? notouch
Variable sized repeatable trigger. Must be targeted at one or more entities. If "health" is set, the trigger must be killed to activate each time.
If "delay" is set, the trigger waits some time after activating before firing.
"wait" : Seconds between triggerings. (.2 default)
If notouch is set, the trigger is only fired by other entities, not by touching.
NOTOUCH has been obsoleted by trigger_relay!
sounds
1) secret
2) beep beep
3) large switch
4)
set "message" to text string
*/
void() trigger_multiple =
{
if (deathmatch && self.weapon_parts) {
remove(self);
return;
}
if (self.sounds == 1)
{
precache_sound ("misc/secret.wav");
self.noise = "misc/secret.wav";
}
else if (self.sounds == 2)
{
precache_sound ("misc/talk.wav");
self.noise = "misc/talk.wav";
}
else if (self.sounds == 3)
{
precache_sound ("misc/trigger1.wav");
self.noise = "misc/trigger1.wav";
}
if (!self.wait)
self.wait = 0.2;
self.use = multi_use;
InitTrigger ();
if (self.health)
{
if (self.spawnflags & SPAWNFLAG_NOTOUCH)
objerror ("health and notouch don't make sense\n");
self.max_health = self.health;
self.th_die = multi_killed;
self.takedamage = DAMAGE_YES;
self.solid = SOLID_BBOX;
setorigin (self, self.origin); // make sure it links into the world
}
else
{
if ( !(self.spawnflags & SPAWNFLAG_NOTOUCH) )
{
self.touch = multi_touch;
}
}
};
/*QUAKED trigger_once (.5 .5 .5) ? notouch
Variable sized trigger. Triggers once, then removes itself. You must set the key "target" to the name of another object in the level that has a matching
"targetname". If "health" is set, the trigger must be killed to activate.
If notouch is set, the trigger is only fired by other entities, not by touching.
if "killtarget" is set, any objects that have a matching "target" will be removed when the trigger is fired.
if "angle" is set, the trigger will only fire when someone is facing the direction of the angle. Use "360" for an angle of 0.
sounds
1) secret
2) beep beep
3) large switch
4)
set "message" to text string
*/
void() trigger_once =
{
if ((deathmatch) && (self.message != "")) {
remove(self);
return;
}
self.wait = -1;
trigger_multiple();
};
//=============================================================================
/*QUAKED trigger_relay (.5 .5 .5) (-8 -8 -8) (8 8 8)
This fixed size trigger cannot be touched, it can only be fired by other events. It can contain killtargets, targets, delays, and messages.
*/
void() trigger_relay =
{
self.use = SUB_UseTargets;
};
//=============================================================================
/*QUAKED trigger_secret (.5 .5 .5) ?
secret counter trigger
sounds
1) secret
2) beep beep
3)
4)
set "message" to text string
*/
void() trigger_secret =
{
total_secrets = total_secrets + 1;
self.wait = -1;
if (!self.message)
self.message = "You found a secret area!";
if (!self.sounds)
self.sounds = 1;
if (self.sounds == 1)
{
precache_sound ("misc/secret.wav");
self.noise = "misc/secret.wav";
}
else if (self.sounds == 2)
{
precache_sound ("misc/talk.wav");
self.noise = "misc/talk.wav";
}
trigger_multiple ();
};
//=============================================================================
void() counter_use =
{
local string junk;
self.count = self.count - 1;
if (self.count < 0)
return;
if (self.count != 0)
{
if (activator.classname == "player"
&& (self.spawnflags & SPAWNFLAG_NOMESSAGE) == 0)
{
if (self.count >= 4)
centerprint (activator, "There are more to go...");
else if (self.count == 3)
centerprint (activator, "Only 3 more to go...");
else if (self.count == 2)
centerprint (activator, "Only 2 more to go...");
else
centerprint (activator, "Only 1 more to go...");
}
return;
}
if (activator.classname == "player"
&& (self.spawnflags & SPAWNFLAG_NOMESSAGE) == 0)
centerprint(activator, "Sequence completed!");
self.enemy = activator;
multi_trigger ();
};
/*QUAKED trigger_counter (.5 .5 .5) ? nomessage
Acts as an intermediary for an action that takes multiple inputs.
If nomessage is not set, t will print "1 more.. " etc when triggered and "sequence complete" when finished.
After the counter has been triggered "count" times (default 2), it will fire all of it's targets and remove itself.
*/
void() trigger_counter =
{
self.wait = -1;
if (!self.count)
self.count = 2;
self.use = counter_use;
};
/*
==============================================================================
TELEPORT TRIGGERS
==============================================================================
*/
float PLAYER_ONLY = 1;
float SILENT = 2;
void() play_teleport =
{
local float v;
local string tmpstr;
v = random() * 5;
if (v < 1)
tmpstr = "misc/r_tele1.wav";
else if (v < 2)
tmpstr = "misc/r_tele2.wav";
else if (v < 3)
tmpstr = "misc/r_tele3.wav";
else if (v < 4)
tmpstr = "misc/r_tele4.wav";
else
tmpstr = "misc/r_tele5.wav";
sound (self, CHAN_VOICE, tmpstr, 1, ATTN_NORM);
remove (self);
};
void(vector org) spawn_tfog =
{
s = spawn ();
s.origin = org;
s.nextthink = time + 0.2;
s.think = play_teleport;
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_TELEPORT);
WriteCoord (MSG_BROADCAST, org_x);
WriteCoord (MSG_BROADCAST, org_y);
WriteCoord (MSG_BROADCAST, org_z);
};
void() tdeath_touch =
{
if (other == self.owner)
return;
// frag anyone who teleports in on top of an invincible player
if (other.classname == "player")
{
if (other.invincible_finished > time)
self.classname = "teledeath2";
if (self.owner.classname != "player")
{ // other monsters explode themselves
T_Damage (self.owner, self, self, 50000);
return;
}
}
if (other.health)
{
T_Damage (other, self, self, 50000);
}
};
void(vector org, entity death_owner) spawn_tdeath =
{
local entity death;
death = spawn();
death.classname = "teledeath";
death.movetype = MOVETYPE_NONE;
death.solid = SOLID_TRIGGER;
death.angles = '0 0 0';
setsize (death, death_owner.mins - '1 1 1', death_owner.maxs + '1 1 1');
setorigin (death, org);
death.touch = tdeath_touch;
death.nextthink = time + 0.2;
death.think = SUB_Remove;
death.owner = death_owner;
force_retouch = 2; // make sure even still objects get hit
};
void() teleport_touch =
{
local entity t;
local vector org;
if (self.targetname)
{
if (self.nextthink < time)
{
return; // not fired yet
}
}
if (self.spawnflags & PLAYER_ONLY)
{
if (other.classname != "player")
return;
}
// only teleport living creatures
if (other.health <= 0 || other.solid != SOLID_SLIDEBOX)
return;
SUB_UseTargets ();
// put a tfog where the player was
spawn_tfog (other.origin);
t = find (world, targetname, self.target);
if (!t)
objerror ("couldn't find target");
// spawn a tfog flash in front of the destination
makevectors (t.mangle);
org = t.origin + 32 * v_forward;
spawn_tfog (org);
spawn_tdeath(t.origin, other);
// move the player and lock him down for a little while
if (!other.health)
{
other.origin = t.origin;
other.velocity = (v_forward * other.velocity_x) + (v_forward * other.velocity_y);
return;
}
setorigin (other, t.origin);
other.angles = t.mangle;
if (other.classname == "player")
{
other.fixangle = 1; // turn this way immediately
other.teleport_time = time + 0.7;
if (other.flags & FL_ONGROUND)
other.flags = other.flags - FL_ONGROUND;
other.velocity = v_forward * 300;
}
other.flags = other.flags - other.flags & FL_ONGROUND;
};
/*QUAKED info_teleport_destination (.5 .5 .5) (-8 -8 -8) (8 8 32)
This is the destination marker for a teleporter. It should have a "targetname" field with the same value as a teleporter's "target" field.
*/
void() info_teleport_destination =
{
// this does nothing, just serves as a target spot
self.mangle = self.angles;
self.angles = '0 0 0';
self.model = "";
self.origin = self.origin + '0 0 27';
if (!self.targetname)
objerror ("no targetname");
};
void() teleport_use =
{
self.nextthink = time + 0.2;
force_retouch = 2; // make sure even still objects get hit
self.think = SUB_Null;
};
/*QUAKED trigger_teleport (.5 .5 .5) ? PLAYER_ONLY SILENT
Any object touching this will be transported to the corresponding info_teleport_destination entity. You must set the "target" field, and create an object with a "targetname" field that matches.
If the trigger_teleport has a targetname, it will only teleport entities when it has been fired.
*/
void() trigger_teleport =
{
local vector o;
InitTrigger ();
self.touch = teleport_touch;
// find the destination
if (!self.target)
objerror ("no target");
self.use = teleport_use;
if (!(self.spawnflags & SILENT))
{
precache_sound ("ambience/hum1.wav");
o = (self.mins + self.maxs)*0.5;
ambientsound (o, "ambience/hum1.wav",0.5 , ATTN_STATIC);
}
};
/*
==============================================================================
trigger_setskill
==============================================================================
*/
void() trigger_skill_touch =
{
if (other.classname != "player")
return;
cvar_set ("skill", self.message);
};
/*QUAKED trigger_setskill (.5 .5 .5) ?
sets skill level to the value of "message".
Only used on start map.
*/
void() trigger_setskill =
{
InitTrigger ();
self.touch = trigger_skill_touch;
};
/*
==============================================================================
ONLY REGISTERED TRIGGERS
==============================================================================
*/
void() trigger_onlyregistered_touch =
{
if (other.classname != "player")
return;
if (self.attack_finished > time)
return;
self.attack_finished = time + 2;
if (cvar("registered"))
{
self.message = "";
SUB_UseTargets ();
remove (self);
}
else
{
if (self.message != "")
{
centerprint (other, self.message);
sound (other, CHAN_BODY, "misc/talk.wav", 1, ATTN_NORM);
}
}
};
/*QUAKED trigger_onlyregistered (.5 .5 .5) ?
Only fires if playing the registered version, otherwise prints the message
*/
void() trigger_onlyregistered =
{
precache_sound ("misc/talk.wav");
InitTrigger ();
self.touch = trigger_onlyregistered_touch;
};
//============================================================================
void() hurt_on =
{
self.solid = SOLID_TRIGGER;
self.nextthink = -1;
};
void() hurt_touch =
{
if ((self.flags & FL_MONSTER) && (other.flags & FL_MONSTER))
return; // don't hurt monsters
if (other.takedamage)
{
self.solid = SOLID_NOT;
T_Damage (other, self, self, self.dmg);
self.think = hurt_on;
self.nextthink = time + 1;
}
return;
};
/*QUAKED trigger_hurt (.5 .5 .5) ?
Any object touching this will be hurt
set dmg to damage amount
defalt dmg = 5
*/
void() trigger_hurt =
{
InitTrigger ();
self.touch = hurt_touch;
if (!self.dmg)
self.dmg = 5;
};
//============================================================================
float PUSH_ONCE = 1;
void() trigger_push_touch =
{
if (other.classname == "grenade")
other.velocity = self.speed * self.movedir * 10;
else if (other.health > 0)
{
other.velocity = self.speed * self.movedir * 10;
if (other.classname == "player")
{
if (other.fly_sound < time )
// Begin Xmen - cl2
if (!(self.spawnflags & 2)) // 2 = silent spawnflag
// End Xmen - cl2
{
other.fly_sound = time + 1.5;
sound (other, CHAN_AUTO, "ambience/windfly.wav", 1, ATTN_NORM);
}
}
}
if (self.spawnflags & PUSH_ONCE)
remove(self);
};
/*QUAKED trigger_push (.5 .5 .5) ? PUSH_ONCE
Pushes the player
*/
void() trigger_push =
{
InitTrigger ();
precache_sound ("ambience/windfly.wav");
self.touch = trigger_push_touch;
if (!self.speed)
self.speed = 1000;
};
//============================================================================
void() trigger_monsterjump_touch =
{
if ( other.flags & (FL_MONSTER | FL_FLY | FL_SWIM) != FL_MONSTER )
return;
// set XY even if not on ground, so the jump will clear lips
other.velocity_x = self.movedir_x * self.speed;
other.velocity_y = self.movedir_y * self.speed;
if ( !(other.flags & FL_ONGROUND) )
return;
other.flags = other.flags - FL_ONGROUND;
other.velocity_z = self.height;
};
/*QUAKED trigger_monsterjump (.5 .5 .5) ?
Walking monsters that touch this will jump in the direction of the trigger's angle
"speed" default to 200, the speed thrown forward
"height" default to 200, the speed thrown upwards
*/
void() trigger_monsterjump =
{
if (!self.speed)
self.speed = 200;
if (!self.height)
self.height = 200;
if (self.angles == '0 0 0')
self.angles = '0 360 0';
InitTrigger ();
self.touch = trigger_monsterjump_touch;
};

3169
WEAPONS.c Normal file

File diff suppressed because it is too large Load diff

650
WORLD.c Normal file
View file

@ -0,0 +1,650 @@
void() InitBodyQue;
void() main =
{
dprint ("main function\n");
// these are just commands the the prog compiler to copy these files
precache_file ("progs.dat");
precache_file ("gfx.wad");
precache_file ("quake.rc");
precache_file ("default.cfg");
precache_file ("end1.bin");
precache_file2 ("end2.bin");
precache_file ("demo1.dem");
precache_file ("demo2.dem");
precache_file ("demo3.dem");
//
// these are all of the lumps from the cached.ls files
//
precache_file ("gfx/palette.lmp");
precache_file ("gfx/colormap.lmp");
precache_file2 ("gfx/pop.lmp");
precache_file ("gfx/complete.lmp");
precache_file ("gfx/inter.lmp");
precache_file ("gfx/ranking.lmp");
precache_file ("gfx/vidmodes.lmp");
precache_file ("gfx/finale.lmp");
precache_file ("gfx/conback.lmp");
precache_file ("gfx/qplaque.lmp");
precache_file ("gfx/menudot1.lmp");
precache_file ("gfx/menudot2.lmp");
precache_file ("gfx/menudot3.lmp");
precache_file ("gfx/menudot4.lmp");
precache_file ("gfx/menudot5.lmp");
precache_file ("gfx/menudot6.lmp");
precache_file ("gfx/menuplyr.lmp");
precache_file ("gfx/bigbox.lmp");
precache_file ("gfx/dim_modm.lmp");
precache_file ("gfx/dim_drct.lmp");
precache_file ("gfx/dim_ipx.lmp");
precache_file ("gfx/dim_tcp.lmp");
precache_file ("gfx/dim_mult.lmp");
precache_file ("gfx/mainmenu.lmp");
precache_file ("gfx/box_tl.lmp");
precache_file ("gfx/box_tm.lmp");
precache_file ("gfx/box_tr.lmp");
precache_file ("gfx/box_ml.lmp");
precache_file ("gfx/box_mm.lmp");
precache_file ("gfx/box_mm2.lmp");
precache_file ("gfx/box_mr.lmp");
precache_file ("gfx/box_bl.lmp");
precache_file ("gfx/box_bm.lmp");
precache_file ("gfx/box_br.lmp");
precache_file ("gfx/sp_menu.lmp");
precache_file ("gfx/ttl_sgl.lmp");
precache_file ("gfx/ttl_main.lmp");
precache_file ("gfx/ttl_cstm.lmp");
precache_file ("gfx/mp_menu.lmp");
precache_file ("gfx/netmen1.lmp");
precache_file ("gfx/netmen2.lmp");
precache_file ("gfx/netmen3.lmp");
precache_file ("gfx/netmen4.lmp");
precache_file ("gfx/netmen5.lmp");
precache_file ("gfx/sell.lmp");
precache_file ("gfx/help0.lmp");
precache_file ("gfx/help1.lmp");
precache_file ("gfx/help2.lmp");
precache_file ("gfx/help3.lmp");
precache_file ("gfx/help4.lmp");
precache_file ("gfx/help5.lmp");
precache_file ("gfx/pause.lmp");
precache_file ("gfx/loading.lmp");
precache_file ("gfx/p_option.lmp");
precache_file ("gfx/p_load.lmp");
precache_file ("gfx/p_save.lmp");
precache_file ("gfx/p_multi.lmp");
// sounds loaded by C code
precache_sound ("misc/menu1.wav");
precache_sound ("misc/menu2.wav");
precache_sound ("misc/menu3.wav");
precache_sound ("ambience/water1.wav");
precache_sound ("ambience/wind2.wav");
// shareware
precache_file ("maps/start.bsp");
precache_file ("maps/e1m1.bsp");
precache_file ("maps/e1m2.bsp");
precache_file ("maps/e1m3.bsp");
precache_file ("maps/e1m4.bsp");
precache_file ("maps/e1m5.bsp");
precache_file ("maps/e1m6.bsp");
precache_file ("maps/e1m7.bsp");
precache_file ("maps/e1m8.bsp");
// registered
precache_file2 ("gfx/pop.lmp");
precache_file2 ("maps/e2m1.bsp");
precache_file2 ("maps/e2m2.bsp");
precache_file2 ("maps/e2m3.bsp");
precache_file2 ("maps/e2m4.bsp");
precache_file2 ("maps/e2m5.bsp");
precache_file2 ("maps/e2m6.bsp");
precache_file2 ("maps/e2m7.bsp");
precache_file2 ("maps/e3m1.bsp");
precache_file2 ("maps/e3m2.bsp");
precache_file2 ("maps/e3m3.bsp");
precache_file2 ("maps/e3m4.bsp");
precache_file2 ("maps/e3m5.bsp");
precache_file2 ("maps/e3m6.bsp");
precache_file2 ("maps/e3m7.bsp");
precache_file2 ("maps/e4m1.bsp");
precache_file2 ("maps/e4m2.bsp");
precache_file2 ("maps/e4m3.bsp");
precache_file2 ("maps/e4m4.bsp");
precache_file2 ("maps/e4m5.bsp");
precache_file2 ("maps/e4m6.bsp");
precache_file2 ("maps/e4m7.bsp");
precache_file2 ("maps/e4m8.bsp");
precache_file2 ("maps/end.bsp");
precache_file2 ("maps/dm1.bsp");
precache_file2 ("maps/dm2.bsp");
precache_file2 ("maps/dm3.bsp");
precache_file2 ("maps/dm4.bsp");
precache_file2 ("maps/dm5.bsp");
precache_file2 ("maps/dm6.bsp");
};
entity lastspawn;
//=======================
/*QUAKED worldspawn (0 0 0) ?
Only used for the world entity.
Set message to the level name.
Set sounds to the cd track to play.
World Types:
0: medieval
1: metal
2: base
*/
//=======================
void() worldspawn =
{
lastspawn = world;
InitBodyQue ();
num_clients = 0;
// custom map attributes
if (self.model == "maps/e1m8.bsp")
cvar_set ("sv_gravity", "100");
else
cvar_set ("sv_gravity", "800");
deathmatch = cvar("deathmatch");
executable = "dosQuake";
if (cvar("temp1") & 1)
executable = "glQuake";
// the area based ambient sounds MUST be the first precache_sounds
// player precaches
W_Precache (); // get weapon precaches
// sounds used from C physics code
precache_sound ("demon/dland2.wav"); // landing thud
precache_sound ("misc/h2ohit1.wav"); // landing splash
// setup precaches allways needed
precache_sound ("items/itembk2.wav"); // item respawn sound
precache_sound ("player/plyrjmp8.wav"); // player jump
precache_sound ("player/land1.wav"); // player landing
precache_sound ("player/land3.wav"); // player hurt landing
precache_sound ("player/land4.wav"); // player hurt landing
precache_sound ("player/drown1.wav"); // drowning pain
precache_sound ("player/drown2.wav"); // drowning pain
precache_sound ("player/gasp1.wav"); // gasping for air
precache_sound ("player/gasp2.wav"); // taking breath
precache_sound ("player/h2odeath.wav"); // drowning death
precache_sound ("player/h2ojump.wav");
precache_sound ("player/what_1.wav"); // parallize sound
precache_sound ("misc/talk.wav"); // talk
precache_sound ("player/teledth1.wav"); // telefrag
precache_sound ("misc/r_tele1.wav"); // teleport sounds
precache_sound ("misc/r_tele2.wav");
precache_sound ("misc/r_tele3.wav");
precache_sound ("misc/r_tele4.wav");
precache_sound ("misc/r_tele5.wav");
precache_sound ("weapons/lock4.wav"); // ammo pick up
precache_sound ("weapons/pkup.wav"); // weapon up
precache_sound ("items/armor1.wav"); // armor up
precache_sound ("weapons/lhit.wav"); //lightning
precache_sound ("weapons/lstart.wav"); //lightning start
precache_sound ("items/damage3.wav");
precache_sound ("items/protect.wav");
precache_sound ("cannon/takeoff.wav");
precache_sound ("doors/airdoor2.wav");
precache_sound ("items/inv1.wav");
precache_sound ("misc/power.wav"); //lightning for boss
// player gib sounds
precache_sound ("player/gib.wav"); // player gib sound
precache_sound ("player/udeath.wav"); // player gib sound
precache_sound ("player/tornoff2.wav"); // gib sound
// player pain sounds
precache_sound ("player/pain1.wav");
precache_sound ("player/pain2.wav");
precache_sound ("player/pain3.wav");
precache_sound ("player/pain4.wav");
// player death sounds
precache_sound ("player/death1.wav");
precache_sound ("player/death2.wav");
precache_sound ("player/death3.wav");
precache_sound ("player/death4.wav");
precache_sound ("player/death5.wav");
// ax sounds
precache_sound ("weapons/ax1.wav"); // ax swoosh
precache_sound ("player/axhit1.wav"); // ax hit meat
precache_sound ("player/axhit2.wav"); // ax hit world
precache_sound ("player/h2ojump.wav"); // player jumping into water
precache_sound ("player/slimbrn2.wav"); // player enter slime
precache_sound ("player/inh2o.wav"); // player enter water
precache_sound ("player/inlava.wav"); // player enter lava
precache_sound ("misc/outwater.wav"); // leaving water sound
precache_sound ("player/lburn1.wav"); // lava burn
precache_sound ("player/lburn2.wav"); // lava burn
precache_sound ("misc/water1.wav"); // swimming
precache_sound ("misc/water2.wav"); // swimming
// X-Men: id sounds used in weapons (soon to be replaced)
precache_sound ("enforcer/enfire.wav");
precache_sound ("enforcer/enfstop.wav");
// end
// X-Men sounds
precache_sound ("generic/punch1.wav");
precache_sound ("generic/punch2.wav");
precache_sound ("generic/punch3.wav");
precache_sound ("misc/snicker1.wav"); // GOD mode laugh
if (cvar("deathmatch") || cvar("coop")) {
precache_sound ("angel/flap1.wav");
precache_sound ("angel/flap2.wav");
precache_sound ("angel/flap3.wav");
precache_sound ("angel/flap4.wav");
precache_sound ("angel/flap5.wav");
precache_sound ("angel/flap6.wav");
precache_sound ("wizard/hit.wav"); // used by c code
precache_sound ("hknight/slash1.wav");
precache_sound ("doors/stndr1.wav");
precache_sound ("boss1/throw.wav");
precache_sound ("generic/swing1.wav");
precache_sound ("generic/frozen1.wav");
precache_sound ("zombie/z_hit.wav");
precache_sound ("cannon/flyloop.wav");
precache_sound ("cannon/takeoff.wav");
}
precache_sound ("weapons/guidfire.wav"); // guided missiles
precache_sound ("weapons/chnfire5.wav"); // chaingun
precache_sound ("weapons/shotfir6.wav");
precache_sound ("weapons/flame.wav");
precache_sound ("weapons/f_start.wav");
precache_sound ("weapons/flamball.wav");
precache_sound ("weapons/reload.wav");
precache_sound ("weapons/prox1.wav");
precache_sound ("weapons/prox2.wav");
precache_sound ("weapons/mega.wav");
precache_sound ("weapons/m_start.wav");
// skeleton
precache_sound ("zombie/idle_w2.wav");
precache_sound ("skeleton/crunch.wav");
// character sounds used during deathmatch
precache_sound ("storm/w_attack.wav");
precache_sound ("storm/l_attack.wav");
// deathmatch sounds
precache_sound ("demon/dhit2.wav");
// character/deathmatch sounds
precache_sound ("voice/male/pain1.wav");
precache_sound ("voice/male/pain2.wav");
precache_sound ("voice/male/pain3.wav");
precache_sound ("voice/male/pain4.wav");
precache_sound ("voice/male/pain5.wav");
precache_sound ("voice/male/pain6.wav");
precache_sound ("voice/male/pain7.wav");
precache_sound ("voice/male/diescrm1.wav");
precache_sound ("voice/male/diescrm2.wav");
precache_sound ("voice/male/diescrm3.wav");
precache_sound ("voice/male/diescrm4.wav");
precache_sound ("voice/male/diescrm5.wav");
precache_sound ("voice/male/diescrm6.wav");
precache_sound ("voice/female/scream1.wav");
precache_sound ("voice/female/scream2.wav");
precache_sound ("voice/female/scream3.wav");
precache_sound ("voice/female/scream4.wav");
precache_sound ("voice/female/scream5.wav");
precache_sound ("voice/female/no1.wav");
precache_sound ("voice/female/diescrm1.wav");
precache_sound ("voice/female/diescrm2.wav");
precache_sound ("voice/female/diescrm3.wav");
precache_sound ("voice/female/diescrm4.wav");
precache_sound ("voice/female/diescrm5.wav");
/*
precache_sound ("voice/female/hey.wav");
precache_sound ("voice/female/hey_you.wav");
precache_sound ("voice/female/stop.wav");
precache_sound ("voice/female/wait.wav");
precache_sound ("voice/male/growl.wav");
precache_sound ("voice/male/grrr.wav");
precache_sound ("voice/male/intruder.wav");
precache_sound ("voice/male/stop01.wav");
precache_sound ("voice/male/uh-a.wav");
precache_sound ("voice/male/what.wav");
precache_sound ("voice/male/what_the.wav");
precache_sound ("voice/male/youthere.wav");
*/
// temp only, used for proximity weapon
precache_sound ("items/damage2.wav");
// end
precache_model ("progs/player.mdl");
precache_model ("progs/cyborg.mdl");
precache_model ("progs/eyes.mdl");
precache_model ("progs/h_player.mdl");
// skeleton gibs
precache_model ("progs/gib01.mdl");
precache_model ("progs/gib02.mdl");
precache_model ("progs/gib03.mdl");
precache_model ("progs/s_bubble.spr"); // drowning bubbles
precache_model ("progs/s_explod.spr"); // sprite explosion
precache_model ("progs/spike.mdl");
// X-Men: deathmatch models
if (cvar("deathmatch") || cvar("coop")) {
// Characters
precache_model ("progs/dmskel.mdl");
precache_model ("progs/dmwolvy.mdl");
precache_model ("progs/dmstorm2.mdl");
precache_model ("progs/dmice.mdl");
precache_model ("progs/dmcyclop.mdl");
precache_model ("progs/dmpsy.mdl");
precache_model ("progs/dmangel.mdl");
precache_model ("progs/dmbeast.mdl");
precache_model ("progs/dmgambit.mdl");
precache_model ("progs/dmbishop.mdl");
precache_model ("progs/dmrogue.mdl");
precache_model ("progs/dmcannon.mdl");
precache_model ("progs/dmphoen.mdl");
// deathmatch special power weapons
precache_model ("progs/v_wol.mdl");
precache_model ("progs/v_sto.mdl");
precache_model ("progs/v_cyc.mdl");
precache_model ("progs/v_psy.mdl");
precache_model ("progs/v_ang.mdl");
precache_model ("progs/v_bea.mdl");
precache_model ("progs/v_gam.mdl");
precache_model ("progs/v_ice.mdl");
precache_model ("progs/v_bis.mdl");
precache_model ("progs/v_rog.mdl");
precache_model ("progs/v_can.mdl");
precache_model ("progs/v_pho.mdl");
// Other Models
precache_model ("progs/claser1.mdl");
precache_model ("progs/dart.mdl");
precache_model ("progs/pow.mdl");
precache_model ("progs/card.mdl");
precache_model ("progs/iceshard.mdl");
precache_model ("progs/iceblast.mdl");
precache_model ("progs/bisblast.mdl");
precache_model ("progs/beampart.mdl");
precache_model ("progs/psyblast.mdl");
}
// end
// X-Men: id models used in weapons
precache_model ("progs/laser.mdl");
// end
// X-Men view (weapon) models
precache_model ("progs/v_xfire1.mdl");
precache_model ("progs/v_xrock.mdl");
precache_model ("progs/v_xshot1.mdl");
precache_model ("progs/v_xchain.mdl");
precache_model ("progs/v_xorb.mdl");
precache_model ("progs/v_xflame.mdl");
precache_model ("progs/v_xshock.mdl");
if (!deathmatch && !coop) {
precache_model ("progs/v_xfist.mdl");
}
precache_model ("progs/v_xmega.mdl");
// end view models
precache_model ("progs/atom1.mdl");
precache_model ("progs/atom2.mdl");
precache_model ("progs/atom3.mdl");
precache_model ("progs/atomshot.mdl");
precache_model ("progs/bolt.mdl"); // for lightning gun
precache_model ("progs/bolt2.mdl"); // for lightning gun
precache_model ("progs/bolt3.mdl"); // for boss shock
precache_model ("progs/lavaball.mdl"); // for testing
precache_model ("progs/missile.mdl");
precache_model ("progs/backpack.mdl");
// X-Men models
precache_model ("progs/blood.mdl");
precache_model ("progs/missmall.mdl");
precache_model ("progs/fl_th1.mdl");
// precache_model ("progs/flame_sm.mdl");
precache_model ("progs/fl_th2.mdl");
// precache_model ("progs/fl_th3.mdl");
precache_model ("progs/fl_th5.mdl");
precache_model ("progs/fl_th6.mdl");
precache_model ("progs/flamball.mdl");
precache_model ("progs/skel.mdl");
precache_model ("progs/orb1.mdl");
precache_model ("progs/null.spr");
// END
//
// Setup light animation tables. 'a' is total darkness, 'z' is maxbright.
//
// 0 normal
lightstyle(0, "m");
// 1 FLICKER (first variety)
lightstyle(1, "mmnmmommommnonmmonqnmmo");
// 2 SLOW STRONG PULSE
lightstyle(2, "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba");
// 3 CANDLE (first variety)
lightstyle(3, "mmmmmaaaaammmmmaaaaaabcdefgabcdefg");
// 4 FAST STROBE
lightstyle(4, "mamamamamama");
// 5 GENTLE PULSE 1
lightstyle(5,"jklmnopqrstuvwxyzyxwvutsrqponmlkj");
// 6 FLICKER (second variety)
lightstyle(6, "nmonqnmomnmomomno");
// 7 CANDLE (second variety)
lightstyle(7, "mmmaaaabcdefgmmmmaaaammmaamm");
// 8 CANDLE (third variety)
lightstyle(8, "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa");
// 9 SLOW STROBE (fourth variety)
lightstyle(9, "aaaaaaaazzzzzzzz");
// 10 FLUORESCENT FLICKER
lightstyle(10, "mmamammmmammamamaaamammma");
// 11 SLOW PULSE NOT FADE TO BLACK
lightstyle(11, "abcdefghijklmnopqrrqponmlkjihgfedcba");
// styles 32-62 are assigned by the light program for switchable lights
// 63 testing
lightstyle(63, "a");
lightstyle(255, "a");
};
float last_explode;
void() StartFrame =
{
local entity laser, orb, old_laser, trav;
local vector vect;
local float vspeed, cont;
teamplay = cvar("teamplay");
skill = cvar("skill");
framecount = framecount + 1;
// check all lasers
laser = find(world, classname, "laser");
while (laser != world) {
if (laser.origin == laser.oldorigin) {
old_laser = laser;
laser = find(laser, classname, "laser");
remove(old_laser);
}
else {
if (laser.last_touch != 0) {
/*
vect = normalize(laser.old_velocity);
vspeed = vlen(laser.old_velocity);
traceline(laser.origin - (laser.old_velocity * 0.5), laser.origin + laser.old_velocity, TRUE, laser);
laser.velocity = (GetReflectionVect(trace_endpos, vect, trace_plane_normal) * vspeed);
*/
laser.old_velocity = laser.velocity;
vect = normalize(laser.old_velocity);
laser.angles = vectoangles(vect);
laser.last_touch = 0;
}
laser.velocity_z = laser.old_velocity_z + cvar("sv_gravity")*frametime;
laser.oldorigin = laser.origin;
laser = find(laser, classname, "laser");
}
}
// check orb for bounce
orb = world;
while ((orb = find(orb, classname, "orb")) != world) {
if ((orb.velocity_z > 0) && (orb.old_velocity_z <= 0)) {
orb.velocity_z = 300;
}
orb.old_velocity = orb.velocity;
}
// Ice shards too!
laser = find(world, classname, "shard");
while (laser != world)
{
if (laser.state)
{
laser.velocity_z = laser.velocity_z + cvar("sv_gravity")*frametime;
}
laser = find(laser, classname, "shard");
}
};
/*
==============================================================================
BODY QUE
==============================================================================
*/
entity bodyque_head;
void() bodyque =
{ // just here so spawn functions don't complain after the world
// creates bodyques
};
void() InitBodyQue =
{
local entity e;
bodyque_head = spawn();
bodyque_head.classname = "bodyque";
bodyque_head.owner = spawn();
bodyque_head.owner.classname = "bodyque";
bodyque_head.owner.owner = spawn();
bodyque_head.owner.owner.classname = "bodyque";
bodyque_head.owner.owner.owner = spawn();
bodyque_head.owner.owner.owner.classname = "bodyque";
bodyque_head.owner.owner.owner.owner = bodyque_head;
};
// make a body que entry for the given ent so the ent can be
// respawned elsewhere
void(entity ent) CopyToBodyQue =
{
bodyque_head.angles = ent.angles;
bodyque_head.model = ent.model;
bodyque_head.modelindex = ent.modelindex;
bodyque_head.frame = ent.frame;
bodyque_head.colormap = ent.colormap;
bodyque_head.movetype = ent.movetype;
bodyque_head.velocity = ent.velocity;
bodyque_head.flags = 0;
setorigin (bodyque_head, ent.origin);
setsize (bodyque_head, ent.mins, ent.maxs);
bodyque_head = bodyque_head.owner;
};

47
X_SELCH.c Normal file
View file

@ -0,0 +1,47 @@
void() clone_touch =
{
if (other.classname != "player")
return;
if (self.classname == "xmen_wclone") {
stuffcmd(other, "color 0 0\n");
}
else if (self.classname == "xmen_sclone") {
stuffcmd(other, "color 1 1\n");
}
stuffcmd(other, "connect\n");
};
void() clone_think =
{
self.frame = self.frame + 1;
if (self.frame > 12)
self.frame = 0;
self.nextthink = time + 0.1;
};
void() xmen_wclone =
{
self.touch = clone_touch;
setsize(self, '-8 -8 -8', '8 8 8');
self.solid = SOLID_TRIGGER;
precache_model("progs/wolvie2.mdl");
setmodel(self, "progs/wolvie2.mdl");
self.think = clone_think;
self.nextthink = time + 0.1;
};
void() xmen_sclone =
{
self.touch = clone_touch;
setsize(self, '-8 -8 -8', '8 8 8');
self.solid = SOLID_TRIGGER;
precache_model("progs/storm2.mdl");
setmodel(self, "progs/storm2.mdl");
self.think = clone_think;
self.nextthink = time + 0.1;
};

1135
X_SPWPN.c Normal file

File diff suppressed because it is too large Load diff

43
X_TRIG.c Normal file
View file

@ -0,0 +1,43 @@
/* Begin Xmen
triggers revision 1
-cl2-
Files involved:
x_trig.qc (this file)
*/
// trigger_constant
// triggers all is targets, waits for self.wait, repeats until triggered
// spawnflags:
// 1 : Starts off
void() tc_go =
{
activator = world;
SUB_UseTargets();
self.nextthink = time + self.wait;
};
void() tc_use =
{
self.state = 1 - self.state;
if (self.state)
{
self.think = tc_go;
self.nextthink = time + self.wait;
}
else self.nextthink = time + 9999999;
};
void() trigger_constant =
{
self.use = tc_use;
if (!self.wait) self.wait = 0.2;
if (self.spawnflags & 1) self.state = 0; else self.state = 1;
if (self.state)
{
self.think = tc_go;
self.nextthink = time + 0.2;
}
};

159
X_VARS.c Normal file
View file

@ -0,0 +1,159 @@
// General variables
.float last_special, last_special2;
.float x_flags;
.float start_health;
.float parallize_time;
.vector parallized_velocity;
.float guard_flag;
.float ammo_special;
.float weapon_parts;
.float char_type; // uses CT_* constants (see below)
.float tractor_dist; // how far enemy is from Phoenix player
.float last_clear; // used to clear screen of colors every few seconds
.float rapid_time;
.float last_wall_hit; // used for Phoenix Tractor beam smash into wall
.float last_prox_think;
.vector respawn_point;
.float prox_power; // builds up before releasing button with proximity weapon
.entity prox_ent;
.string last_centerprint;
.void() th_guard;
// this overrides the normal centerprint, so we can save each new centerprint
void(entity client, string s) centerprint;
float X_PARALLIZED = 1;
float X_CANNONFLYABORT = 2;
float X_TRACTOR_BEAM_HOLD = 4;
float X_SINISTER_FINAL = 8;
float X_ANGEL_DEFENSE = 16;
float X_STGUN = 32;
float X_FLYING = 64;
float X_RAPID_FIRE = 128;
float X_RAPID_WARNING = 512;
float X_MEGA_HIT = 1024;
float X_AMMO_ANIMATE = 2048;
float X_GODCHEAT = 4096;
float X_JUMP_PRESSED = 8192;
float CT_MALE_NORMAL = 1;
float CT_MALE_LARGE = 2;
float CT_FEMALE = 3;
// Globals
entity damage_inflictor;
float index_skeleton;
string executable; // use temp1 to set executable before entering game
// temp1: 0 = dos, 1 = glQuake, 2 = winQuake
float num_clients;
// debugging toggles
float show_damage; // used in SetDamageSkin(), gives % readout
// spawnflags
float SPAWNFLAG_CLONE = 8;
// deathmatch vars
.float special_weapon; // 0 or 1, toggles with subsequent IMPULSE 1 commands
.float character; // one of CHAR_*, may only be set upon joining the game
// if 0, then player can't move and must select a character
.float last_jump_z; // Z value of origin when jump was pressed (used by Angel hovering)
.float last_jump; // time of last jump press
float CHAR_WOLVERINE = 1;
float CHAR_STORM = 2;
float CHAR_CYCLOPS = 3;
float CHAR_PSYLOCKE = 4;
float CHAR_ANGEL = 5;
float CHAR_BEAST = 6;
float CHAR_GAMBIT = 7;
float CHAR_ICEMAN = 8;
float CHAR_BISHOP = 9;
float CHAR_ROGUE = 10;
float CHAR_CANNONBALL = 11;
float CHAR_PHOENIX = 12;
float STORM_VOFS_Z = 0;
float DM_SPECIAL_POWERS = 10; // set deathmatch = DM_SPECIAL_POWERS for no weapons
// weapon stuff
.float nextweapon;
.float change_weapon_status;
.float fadeout_endframe;
.float fadein_endframe;
.float last_fade;
.float weapon_flags;
.float remember_impulse; // stores a change weapon impulse while changing weapons
.float weapon_idleframe;
.float water_flame_flag;
.float consecutive_count, w_pausetime, last_pausetime; // used to pause flame gun after 3 shots
float W_RELOADING = 1;
float W_SHOTRELOAD = 2;
float DEATH_FLAG = 4;
float CW_DONE = 0;
float CW_FADEOUT = 1;
float CW_FADEIN = 2;
// Flame thrower vars
float FLAME_DIST = 112; // distance between each junction
float FLAME_ENT_SPEED = 650; // speed of movement towards ideal position
float SNDLEN_FLAME = 0.2;
.entity flame_ent1; // trail of 3 flamethrower junction entities
.entity flame_ent2;
.entity flame_ent3;
.float last_flame;
.float last_flame_sound;
// Laser gun vars
.float fire_reload_frames;
.float last_fire_laser;
.float spawn_time;
// Storm vars
float MAX_Z_OFS = 20;
.float last_wind;
.float z_ofs;
.float z_ofs_vel;
// Cyclops
.float start_attack_health;
.float last_touch;
.vector old_velocity; // also used for Player as Angel in deathmatch for floating downwards
// tech dude
.float start_frame, last_frame;
.float tech_state;
float TECH_IDLE = 0;
float TECH_WALKING = 1;
float TECH_HIDING = 2;
// Pheonix
.entity move_ent;
.float start_tractor_time;
.vector tractor_vel;
// Trap Flamethrower
.float sway_range;
// Apocalypse
.entity leg; // main legs entity, displays appy1.mdl
// Cannonball
.float last_rocket_hit;

579
angel.c Normal file
View file

@ -0,0 +1,579 @@
/*
==============================================================================
WIZARD
==============================================================================
*/
$frame hover1 hover2 hover3 hover4 hover5 hover6 hover7 hover8 hover9
$frame hover10 hover11 hover12 hover13
$frame slow1 slow2 slow3 slow4 slow5 slow6 slow7 slow8 slow9
$frame slow10 slow11 slow12 slow13
$frame fast1 fast2 fast3 fast4 fast5 fast6 fast7 fast8
$frame pain1 pain2 pain3 pain4 pain5 pain6
$frame guard1 guard2 guard3 guard4 guard5 guard6 guard7 guard8 guard9
$frame guard10 guard11 guard12
$frame death1 death2 death3 death4 death5 death6 death7 death8 death9 death10
$frame death11 death12 death13 death14 death15 death16 death17 death18 death19 death20
$frame deatha1 deatha2 deatha3 deatha4 deatha5 deatha6 deatha7 deatha8 deatha9 deatha10
$frame deatha11 deatha12 deatha13 deatha14 deatha15 deatha16 deatha17 deatha18 deatha19 deatha20
$frame attack1 attack2 attack3 attack4 attack5 attack6 attack7 attack8
$frame attack9 attack10 attack11 attack12 attack13
/*
==============================================================================
WIZARD
If the player moves behind cover before the missile is launched, launch it
at the last visible spot with no velocity leading, in hopes that the player
will duck back out and catch it.
==============================================================================
*/
/*
=============
LaunchMissile
Sets the given entities velocity and angles so that it will hit self.enemy
if self.enemy maintains it's current velocity
0.1 is moderately accurate, 0.0 is totally accurate
=============
*/
void(entity missile, float mspeed, float accuracy) LaunchMissile =
{
local vector vec, move;
local float fly;
makevectors (self.angles);
// set missile speed
vec = self.enemy.origin + self.enemy.mins + self.enemy.size * 0.7 - missile.origin;
// calc aproximate time for missile to reach vec
fly = vlen (vec) / mspeed;
// get the entities xy velocity
move = self.enemy.velocity;
move_z = 0;
// project the target forward in time
vec = vec + move * fly;
vec = normalize(vec);
vec = vec + accuracy*v_up*(random()- 0.5) + accuracy*v_right*(random()- 0.5);
missile.velocity = vec * mspeed;
missile.angles = '0 0 0';
missile.angles_y = vectoyaw(missile.velocity);
// set missile duration
missile.nextthink = time + 5;
missile.think = SUB_Remove;
};
void() wiz_run1;
void() wiz_side1;
/*
=================
WizardCheckAttack
=================
*/
float() WizardCheckAttack =
{
local vector spot1, spot2;
local entity targ;
local float chance;
if (time < self.attack_finished)
return FALSE;
if (!enemy_vis)
return FALSE;
if (enemy_range == RANGE_FAR)
{
if (self.attack_state != AS_STRAIGHT)
{
self.attack_state = AS_STRAIGHT;
wiz_run1 ();
}
return FALSE;
}
targ = self.enemy;
// see if any entities are in the way of the shot
spot1 = self.origin + self.view_ofs;
spot2 = targ.origin + targ.view_ofs;
traceline (spot1, spot2, FALSE, self);
if (trace_ent != targ)
{ // don't have a clear shot, so move to a side
if (self.attack_state != AS_STRAIGHT)
{
self.attack_state = AS_STRAIGHT;
wiz_run1 ();
}
return FALSE;
}
if (enemy_range == RANGE_MELEE)
chance = 0.9;
else if (enemy_range == RANGE_NEAR)
chance = 0.6;
else if (enemy_range == RANGE_MID)
chance = 0.2;
else
chance = 0;
if (random () < chance)
{
self.attack_state = AS_MISSILE;
return TRUE;
}
if ((enemy_range == RANGE_MID) && (vlen(self.origin - self.enemy.origin) > 256)) // keep at a distance
{
if (self.attack_state != AS_STRAIGHT)
{
self.attack_state = AS_STRAIGHT;
wiz_run1 ();
}
}
else
{
if (self.attack_state != AS_SLIDING)
{
self.attack_state = AS_SLIDING;
wiz_side1 ();
}
}
return FALSE;
};
/*
=================
WizardAttackFinished
=================
*/
float() WizardAttackFinished =
{
if (enemy_range >= RANGE_MID || !enemy_vis)
{
self.attack_state = AS_STRAIGHT;
self.think = wiz_run1;
}
else
{
self.attack_state = AS_SLIDING;
self.think = wiz_side1;
}
};
/*
==============================================================================
FAST ATTACKS
==============================================================================
*/
void() Wiz_FastFire =
{
local vector vec;
local vector dst;
if (self.owner.health > 0)
{
self.owner.effects = self.owner.effects | EF_MUZZLEFLASH;
makevectors (self.enemy.angles);
dst = self.enemy.origin - 13*self.movedir + (self.enemy.velocity * 0.3);
vec = normalize(dst - self.origin);
launch_spike (self.origin, vec);
newmis.velocity = vec*600;
newmis.owner = self.owner;
newmis.classname = "angel_dart";
setmodel (newmis, "progs/dart.mdl");
setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
}
remove (self);
};
void() Wiz_StartFast =
{
local entity missile;
self.v_angle = self.angles;
makevectors (self.angles);
missile = spawn ();
missile.owner = self;
missile.nextthink = time + 0.6;
setsize (missile, '0 0 0', '0 0 0');
setorigin (missile, self.origin + '0 0 30' + v_forward*14 + v_right*14);
missile.enemy = self.enemy;
missile.nextthink = time + 0.8;
missile.think = Wiz_FastFire;
missile.movedir = v_right;
missile = spawn ();
missile.owner = self;
missile.nextthink = time + 1;
setsize (missile, '0 0 0', '0 0 0');
setorigin (missile, self.origin + '0 0 30' + v_forward*14 + v_right* -14);
missile.enemy = self.enemy;
missile.nextthink = time + 0.3;
missile.think = Wiz_FastFire;
missile.movedir = VEC_ORIGIN - v_right;
};
void(float heading_ofs) AngelFeather =
{
local vector newangle, targ_vect;
local entity missile;
newangle = self.angles;
newangle_y = anglemod(newangle_y + heading_ofs);
targ_vect = normalize(self.enemy.origin - (self.origin + '0 0 30'));
targ_vect = vectoangles(targ_vect);
newangle_x = -1 * targ_vect_x;
newangle_x = newangle_x + (random() * 20) - 10;
makevectors(newangle);
launch_spike (self.origin + '0 0 30' + v_forward*14, v_forward);
newmis.classname = "angel_dart";
setmodel (newmis, "progs/dart.mdl");
setsize(newmis, '0 0 0', '0 0 0');
};
void() Wiz_idlesound =
{
local float wr;
return;
};
void() AngelPitch =
{
local vector vect;
if (self.enemy != world)
vect = normalize(self.enemy.origin - self.origin);
else
vect = '1 0 0';
vect = vectoangles(vect);
vect_x = -1 * vect_x;
if (vect_x < -25) vect_x = -25;
else if (vect_x > 40) vect_x = 40;
vect_x = anglemod(vect_x);
self.angles_x = anglemod(self.angles_x);
if (self.solid != SOLID_NOT)
self.angles_x = MoveToAngle(self.angles_x, vect_x, 45);
else
self.angles_x = MoveToAngle(self.angles_x, vect_x, 180);
if (self.angles_x > 180)
self.angles_x = self.angles_x - 360;
};
void() RandomFlapSound =
{
local float rnd;
rnd = random() * 6;
if (rnd < 1)
self.noise = "angel/flap1.wav";
else if (rnd < 2)
self.noise = "angel/flap2.wav";
else if (rnd < 3)
self.noise = "angel/flap3.wav";
else if (rnd < 4)
self.noise = "angel/flap4.wav";
else if (rnd < 5)
self.noise = "angel/flap5.wav";
else if (rnd < 6)
self.noise = "angel/flap6.wav";
sound(self, CHAN_BODY, self.noise, 1, 3);
};
void() wiz_stand1 =[ $hover1, wiz_stand2 ] {ai_stand();};
void() wiz_stand2 =[ $hover2, wiz_stand3 ] {ai_stand();};
void() wiz_stand3 =[ $hover3, wiz_stand4 ] {ai_stand();};
void() wiz_stand4 =[ $hover4, wiz_stand5 ] {ai_stand();};
void() wiz_stand5 =[ $hover5, wiz_stand6 ] {ai_stand(); RandomFlapSound();};
void() wiz_stand6 =[ $hover6, wiz_stand7 ] {ai_stand();};
void() wiz_stand7 =[ $hover7, wiz_stand8 ] {ai_stand();};
void() wiz_stand8 =[ $hover8, wiz_stand9 ] {ai_stand();};
void() wiz_stand9 =[ $hover9, wiz_stand10 ] {ai_stand();};
void() wiz_stand10 =[ $hover10, wiz_stand11 ] {ai_stand();};
void() wiz_stand11 =[ $hover11, wiz_stand12 ] {ai_stand();};
void() wiz_stand12 =[ $hover12, wiz_stand13 ] {ai_stand();};
void() wiz_stand13 =[ $hover13, wiz_stand1 ] {ai_stand();};
void() wiz_walk1 =[ $slow1, wiz_walk2 ] {ai_walk(10);};
void() wiz_walk2 =[ $slow2, wiz_walk3 ] {ai_walk(10);};
void() wiz_walk3 =[ $slow3, wiz_walk4 ] {ai_walk(10); RandomFlapSound();};
void() wiz_walk4 =[ $slow4, wiz_walk5 ] {ai_walk(10);};
void() wiz_walk5 =[ $slow5, wiz_walk6 ] {ai_walk(10);};
void() wiz_walk6 =[ $slow6, wiz_walk7 ] {ai_walk(10);};
void() wiz_walk7 =[ $slow7, wiz_walk8 ] {ai_walk(10);};
void() wiz_walk8 =[ $slow8, wiz_walk9 ] {ai_walk(10);};
void() wiz_walk9 =[ $slow9, wiz_walk10 ] {ai_walk(10);};
void() wiz_walk10 =[ $slow10, wiz_walk11 ] {ai_walk(10);};
void() wiz_walk11 =[ $slow11, wiz_walk12 ] {ai_walk(10);};
void() wiz_walk12 =[ $slow12, wiz_walk13 ] {ai_walk(10);};
void() wiz_walk13 =[ $slow13, wiz_walk1 ] {ai_walk(10);};
void() wiz_side1 =[ $slow1, wiz_side2 ] {ai_run(14);};
void() wiz_side2 =[ $slow2, wiz_side3 ] {ai_run(14);};
void() wiz_side3 =[ $slow3, wiz_side4 ] {ai_run(14); RandomFlapSound();};
void() wiz_side4 =[ $slow4, wiz_side5 ] {ai_run(14);};
void() wiz_side5 =[ $slow5, wiz_side6 ] {ai_run(14);};
void() wiz_side6 =[ $slow6, wiz_side7 ] {ai_run(14);};
void() wiz_side7 =[ $slow7, wiz_side8 ] {ai_run(14);};
void() wiz_side8 =[ $slow8, wiz_side9 ] {ai_run(14);};
void() wiz_side9 =[ $slow9, wiz_side10 ] {ai_run(14);};
void() wiz_side10 =[ $slow10, wiz_side11 ] {ai_run(14);};
void() wiz_side11 =[ $slow11, wiz_side12 ] {ai_run(14);};
void() wiz_side12 =[ $slow12, wiz_side13 ] {ai_run(14);};
void() wiz_side13 =[ $slow13, wiz_side1 ] {ai_run(14);};
void() wiz_run1 =[ $slow1, wiz_run2 ] {ai_run(20);};
void() wiz_run2 =[ $slow2, wiz_run3 ] {ai_run(20);};
void() wiz_run3 =[ $slow3, wiz_run4 ] {ai_run(20);};
void() wiz_run4 =[ $slow4, wiz_run5 ] {ai_run(20);};
void() wiz_run5 =[ $slow5, wiz_run6 ] {ai_run(20);};
void() wiz_run6 =[ $slow6, wiz_run7 ] {ai_run(20);};
void() wiz_run7 =[ $slow7, wiz_run8 ] {ai_run(20);};
void() wiz_run8 =[ $slow8, wiz_run9 ] {ai_run(20);};
void() wiz_run9 =[ $slow9, wiz_run10 ] {ai_run(20);};
void() wiz_run10 =[ $slow10, wiz_run11 ] {ai_run(20);};
void() wiz_run11 =[ $slow11, wiz_run12 ] {ai_run(20);};
void() wiz_run12 =[ $slow12, wiz_run13 ] {ai_run(20);};
void() wiz_run13 =[ $slow13, wiz_run1 ] {ai_run(20);};
float() AngelCheckGuard =
{
local entity trav;
trav = world;
while ((trav = find(trav, classname, "guided_rocket")) != world) {
// check that rocket is targetted for self
if (trav.enemy == self) { // uh oh
return TRUE;
}
}
// dangerous rocket not found
self.think = self.th_run;
self.flags = self.flags - (self.flags & FL_GODMODE);
return FALSE;
};
void() wiz_guard1 =[ $guard1, wiz_guard2 ] {self.nextthink = time + 0.05;};
void() wiz_guard2 =[ $guard2, wiz_guard3 ] {self.nextthink = time + 0.05;};
void() wiz_guard3 =[ $guard3, wiz_guard4 ] {self.nextthink = time + 0.05;};
void() wiz_guard4 =[ $guard4, wiz_guard5 ] {self.nextthink = time + 0.05;};
void() wiz_guard5 =[ $guard5, wiz_guard6 ] {self.nextthink = time + 0.05;};
void() wiz_guard6 =[ $guard6, wiz_guard7 ] {self.flags = self.flags | FL_GODMODE;};
void() wiz_guard7 =[ $guard7, wiz_guard8 ] {};
void() wiz_guard8 =[ $guard8, wiz_guard9 ] {};
void() wiz_guard9 =[ $guard9, wiz_guard10 ] {};
void() wiz_guard10 =[ $guard10, wiz_guard11 ] {};
void() wiz_guard11 =[ $guard11, wiz_guard12 ] {};
void() wiz_guard12 =[ $guard12, wiz_guard12 ] {AngelCheckGuard();};
void() wiz_attack1 =[ $attack1, wiz_attack2 ] {ai_face();};
void() wiz_attack2 =[ $attack2, wiz_attack3 ] {};
void() wiz_attack3 =[ $attack3, wiz_attack4 ] {ai_face(); RandomFlapSound();};
void() wiz_attack4 =[ $attack4, wiz_attack5 ] {};
void() wiz_attack5 =[ $attack5, wiz_attack6 ] {
//sound(self, CHAN_WEAPON, "hknight/slash1.wav", 1, ATTN_NORM);
ai_face();};
void() wiz_attack6 =[ $attack6, wiz_attack7 ] {AngelFeather(-25);AngelFeather(-20);};
void() wiz_attack7 =[ $attack7, wiz_attack8 ] {AngelFeather(-15);AngelFeather(-10);};
void() wiz_attack8 =[ $attack8, wiz_attack9 ] {AngelFeather(-5);AngelFeather(0);};
void() wiz_attack9 =[ $attack9, wiz_attack10 ] {AngelFeather(5);AngelFeather(10);};
void() wiz_attack10 =[ $attack10, wiz_attack11 ] {AngelFeather(15);AngelFeather(20);};
void() wiz_attack11 =[ $attack11, wiz_attack12 ] {ai_face();};
void() wiz_attack12 =[ $attack12, wiz_attack13 ] {ai_face();};
void() wiz_attack13 =[ $attack13, wiz_run1 ] {SUB_AttackFinished(2);WizardAttackFinished ();};
void() wiz_pain1 =[ $pain1, wiz_pain2 ] {};
void() wiz_pain2 =[ $pain2, wiz_pain3 ] {};
void() wiz_pain3 =[ $pain3, wiz_pain4 ] {};
void() wiz_pain4 =[ $pain4, wiz_pain5 ] {};
void() wiz_pain5 =[ $pain5, wiz_pain6 ] {};
void() wiz_pain6 =[ $pain6, wiz_run1 ] {};
void() wiz_death1 =[ $death1, wiz_death2 ] {
self.velocity_x = -200 + 400*random();
self.velocity_y = -200 + 400*random();
self.velocity_z = 100 + 100*random();
self.flags = self.flags - (self.flags & FL_ONGROUND);
self.enemy = world;
};
void() wiz_death2 =[ $death2, wiz_death3 ] {};
void() wiz_death3 =[ $death3, wiz_death4 ]{self.solid = SOLID_NOT;};
void() wiz_death4 =[ $death4, wiz_death5 ] {};
void() wiz_death5 =[ $death5, wiz_death6 ] {};
void() wiz_death6 =[ $death6, wiz_death7 ] {};
void() wiz_death7 =[ $death7, wiz_death8 ] {};
void() wiz_death8 =[ $death8, wiz_death9 ] {};
void() wiz_death9 =[ $death9, wiz_death10 ] {};
void() wiz_death10 =[ $death10, wiz_death11 ] {};
void() wiz_death11 =[ $death11, wiz_death12 ] {};
void() wiz_death12 =[ $death12, wiz_death13 ] {};
void() wiz_death13 =[ $death13, wiz_death14 ] {};
void() wiz_death14 =[ $death14, wiz_death15 ] {};
void() wiz_death15 =[ $death15, wiz_death16 ] {};
void() wiz_death16 =[ $death16, wiz_death17 ] {};
void() wiz_death17 =[ $death17, wiz_death18 ] {};
void() wiz_death18 =[ $death18, wiz_death19 ] {};
void() wiz_death19 =[ $death19, wiz_death20 ] {};
void() wiz_death20 =[ $death20, wiz_death20 ] {if (self.angles_x != 0) AngelPitch();};
void() wiz_deatha1 =[ $deatha1, wiz_deatha2 ] {
self.velocity_x = -200 + 400*random();
self.velocity_y = -200 + 400*random();
self.velocity_z = 100 + 100*random();
self.flags = self.flags - (self.flags & FL_ONGROUND);
self.enemy = world;
};
void() wiz_deatha2 =[ $deatha2, wiz_deatha3 ] {};
void() wiz_deatha3 =[ $deatha3, wiz_deatha4 ]{self.solid = SOLID_NOT;};
void() wiz_deatha4 =[ $deatha4, wiz_deatha5 ] {};
void() wiz_deatha5 =[ $deatha5, wiz_deatha6 ] {};
void() wiz_deatha6 =[ $deatha6, wiz_deatha7 ] {};
void() wiz_deatha7 =[ $deatha7, wiz_deatha8 ] {};
void() wiz_deatha8 =[ $deatha8, wiz_deatha9 ] {};
void() wiz_deatha9 =[ $deatha9, wiz_deatha10 ] {};
void() wiz_deatha10 =[ $deatha10, wiz_deatha11 ] {};
void() wiz_deatha11 =[ $deatha11, wiz_deatha12 ] {};
void() wiz_deatha12 =[ $deatha12, wiz_deatha13 ] {};
void() wiz_deatha13 =[ $deatha13, wiz_deatha14 ] {};
void() wiz_deatha14 =[ $deatha14, wiz_deatha15 ] {};
void() wiz_deatha15 =[ $deatha15, wiz_deatha16 ] {};
void() wiz_deatha16 =[ $deatha16, wiz_deatha17 ] {};
void() wiz_deatha17 =[ $deatha17, wiz_deatha18 ] {};
void() wiz_deatha18 =[ $deatha18, wiz_deatha19 ] {};
void() wiz_deatha19 =[ $deatha19, wiz_deatha20 ] {};
void() wiz_deatha20 =[ $deatha20, wiz_deatha20 ] {if (self.angles_x != 0) AngelPitch();};
void() wiz_die =
{
MaleDeathSound(2);
if (random() < 0.5)
wiz_death1 ();
else
wiz_deatha1 ();
};
void(entity attacker, float damage) Wiz_Pain =
{
if (self.pain_finished > time)
return;
MalePainSound(2);
if (random()*40 > damage)
return; // didn't flinch
self.pain_finished = time + 2;
wiz_pain1 ();
};
void() Wiz_Missile =
{
wiz_attack1();
};
/*QUAKED xmen_angel (1 0 0) (-16 -16 -24) (16 16 40) Ambush
*/
void() xmen_angel =
{
if (deathmatch)
{
remove(self);
return;
}
precache_model ("progs/angel1.mdl");
// precache_model ("progs/h_wizard.mdl");
precache_model ("progs/dart.mdl");
// XMen matched ID sounds
// precache_sound ("hknight/slash1.wav");
precache_sound ("angel/flap1.wav");
precache_sound ("angel/flap2.wav");
precache_sound ("angel/flap3.wav");
precache_sound ("angel/flap4.wav");
precache_sound ("angel/flap5.wav");
precache_sound ("angel/flap6.wav");
precache_sound ("wizard/hit.wav"); // used by c code
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
setmodel (self, "progs/angel1.mdl");
setsize (self, '-16 -16 -24', '16 16 40');
self.health = 110 + cvar("skill")*10;
self.yaw_speed = 9;
self.th_stand = wiz_stand1;
self.th_walk = wiz_walk1;
self.th_run = wiz_run1;
self.th_missile = Wiz_Missile;
self.th_pain = Wiz_Pain;
self.th_die = wiz_die;
self.th_guard = wiz_guard1;
flymonster_start ();
};
void() monster_wizard =
{
remove(self);
};

475
appy.c Normal file
View file

@ -0,0 +1,475 @@
/*************************************************************************
Apocalypse - Episode 1 Boss
**************************************************************************/
$frame stand101
$frame atta101 atta102 atta103 atta104 atta105 atta106 atta107
$frame atta108 atta109 atta110 atta111 atta112
$frame attb101 attb102 attb103 attb104 attb105 attb106 attb107
$frame attb108 attb109 attb110 attb111 attb112
$frame attc101 attc102 attc103 attc104 attc105 attc106 attc107
$frame attc108 attc109 attc110 attc111 attc112
$frame stomp101 stomp102 stomp103 stomp104 stomp105 stomp106 stomp107
$frame stomp108 stomp109 stomp110
$frame pain101 pain102 pain103 pain104 pain105 pain106 pain107 pain108 pain109 pain110
$frame pain111 pain112 pain113 pain114 pain115 pain116 pain117 pain118 pain119 pain120
$frame pain121 pain122 pain123 pain124 pain125 pain126 pain127 pain128 pain129 pain130
$frame pain131 pain132 pain133 pain134 pain135 pain136 pain137 pain138 pain139 pain140
$frame pain141 pain142 pain143 pain144 pain145 pain146 pain147 pain148 pain149 pain150
//====================================================================================
void() apoc_stand1 = [ $stomp101, apoc_stand1 ]
{
if (self.spawn_time < (time - 1)) {
ai_stand();
if (self.enemy != world) {
self.last_flame = time;
cvar_set("host_framerate", "0.02");
}
}
};
//====================================================================================
void() apoc_stomp =
{
local vector vect, vecta;
local float old_yaw, old_yaw_body;
if (vlen(self.enemy.origin - self.origin) < 32) { // in-between legs
// apoc_attb1();
return;
}
vect = normalize(self.enemy.origin - self.origin);
vecta = vectoangles(vect);
// rotate legs
self = self.leg;
old_yaw = self.angles_y;
self.ideal_yaw = self.owner.ideal_yaw;
ChangeYaw();
self = self.owner;
// move body according to the leg movement
self.angles_y = anglemod(self.angles_y + (self.leg.angles_y - old_yaw));
// set frame according to the direction of rotation
if (old_yaw < self.leg.angles_y)
self.frame = self.frame + 1;
else
self.frame = self.frame - 1;
if (self.frame > $stomp110 )
self.frame = $stomp101;
else if (self.frame < $stomp101 )
self.frame = $stomp110;
// rotate body
old_yaw_body = self.angles_y;
self.ideal_yaw = vecta_y;
self.angles_y = anglemod(self.angles_y + (self.leg.angles_y - old_yaw));
// ChangeYaw();
if (fabs(angle_diff(self.angles_y, self.leg.angles_y)) > 75) {
self.angles_y = old_yaw_body;
}
};
//====================================================================================
// this keeps apocalypse facing the player, unless the player goes out of the angle range
void() apoc_face =
{
local vector vect, vecta;
if (vlen(self.enemy.origin - self.origin) < 32) { // in-between legs
return;
}
vect = normalize(self.enemy.origin - self.origin);
vecta = vectoangles(vect);
self.ideal_yaw = vecta_y;
if (fabs(angle_diff(self.ideal_yaw, self.leg.angles_y)) < 75) {
ChangeYaw();
}
};
void() earth_quake_think =
{
local vector vec;
local float ratio;
if (self.last_flame < (time - 0.75)) {
remove(self);
return;
}
// shake view
vec = '12 0 0' * random() + '0 12 0' * random() + '0 0 22' * random() - '6 6 14';
ratio = (vlen(self.enemy.origin - self.origin) / 256);
if (ratio > 1)
ratio = 1;
vec = vec * ratio;
self.enemy.punchangle = vec * (0.75 - (time - self.last_flame));
};
void() apoc_thump =
{
local entity thinker;
makevectors(self.angles);
if (vlen(self.origin + (v_forward * 128) - self.enemy.origin) < 128)
T_Damage(self.enemy, self, self, 40);
sound(self, CHAN_BODY, "apoc/thump.wav", 1, ATTN_NONE);
thinker = spawn();
thinker.enemy = self.enemy;
thinker.last_flame = time;
thinker.think = earth_quake_think;
thinker.nextthink = time + 0.05;
self.nextthink = time + 0.05;
};
void() apoc_atta1 = [ $atta101, apoc_atta2 ] {apoc_face();};
void() apoc_atta2 = [ $atta102, apoc_atta3 ] {apoc_face();};
void() apoc_atta3 = [ $atta103, apoc_atta4 ] {apoc_face();};
void() apoc_atta4 = [ $atta104, apoc_atta5 ] {apoc_face();};
void() apoc_atta5 = [ $atta105, apoc_atta6 ] {apoc_face();};
void() apoc_atta6 = [ $atta106, apoc_atta7 ] {apoc_face(); apoc_thump();};
void() apoc_atta7 = [ $atta107, apoc_atta8 ] {apoc_face();};
void() apoc_atta8 = [ $atta108, apoc_atta9 ] {apoc_face();};
void() apoc_atta9 = [ $atta109, apoc_atta10 ] {apoc_face();};
void() apoc_atta10 = [ $atta110, apoc_atta11 ] {apoc_face();};
void() apoc_atta11 = [ $atta111, apoc_atta12 ] {apoc_face();};
void() apoc_atta12 = [ $atta112, apoc_melee ] {apoc_face();};
void() apoc_swipe =
{
local vector vect;
local float ang;
vect = normalize(self.enemy.origin - self.origin);
vect = vectoangles(vect);
ang = angle_diff(self.angles_y, vect_y);
if ((fabs(ang) < 90) && (vlen(self.enemy.origin - self.origin) < 300)) {
if (!(self.enemy.x_flags & X_PARALLIZED))
self.enemy.x_flags = self.enemy.x_flags | X_PARALLIZED;
makevectors(self.angles);
if (vlen(self.origin + (v_forward * 128) - self.enemy.origin) > 16)
self.enemy.parallized_velocity = normalize(self.origin + (v_forward * 128) - self.enemy.origin) * 200;
else
self.enemy.parallized_velocity = '0 0 0';
T_Damage(self.enemy, self, self, 2);
}
};
void() apoc_attb1 = [ $attb101, apoc_attb2 ] {apoc_face();};
void() apoc_attb2 = [ $attb102, apoc_attb3 ] {apoc_face();};
void() apoc_attb3 = [ $attb103, apoc_attb4 ] {apoc_face();};
void() apoc_attb4 = [ $attb104, apoc_attb5 ] {apoc_face(); sound(self, CHAN_ITEM, "apoc/swipe.wav", 1, ATTN_NONE);};
void() apoc_attb5 = [ $attb105, apoc_attb6 ] {apoc_face(); apoc_swipe();};
void() apoc_attb6 = [ $attb106, apoc_attb7 ] {apoc_face(); apoc_swipe();};
void() apoc_attb7 = [ $attb107, apoc_attb8 ] {apoc_face(); apoc_swipe();};
void() apoc_attb8 = [ $attb108, apoc_attb9 ] {apoc_face(); apoc_swipe();};
void() apoc_attb9 = [ $attb109, apoc_attb10 ] {apoc_face(); apoc_swipe();};
void() apoc_attb10 = [ $attb110, apoc_attb11 ] {apoc_face(); apoc_swipe();};
void() apoc_attb11 = [ $attb111, apoc_attb12 ] {apoc_face(); apoc_swipe();};
void() apoc_attb12 = [ $attb112, apoc_melee ]
{
apoc_face();
if (self.enemy.x_flags & X_PARALLIZED)
self.enemy.x_flags = self.enemy.x_flags - X_PARALLIZED;
};
void() apoc_spike =
{
if (vlen(self.origin - self.enemy.origin) < 96)
T_Damage(self.enemy, self, self, 10);
sound(self, CHAN_BODY, "apoc/spike.wav", 1, ATTN_NONE);
};
void() apoc_attc1 = [ $attc101, apoc_attc2 ] {apoc_face();};
void() apoc_attc2 = [ $attc102, apoc_attc3 ] {apoc_face();};
void() apoc_attc3 = [ $attc103, apoc_attc4 ] {apoc_face(); apoc_spike();};
void() apoc_attc4 = [ $attc104, apoc_attc5 ] {apoc_face();};
void() apoc_attc5 = [ $attc105, apoc_attc6 ] {apoc_face();};
void() apoc_attc6 = [ $attc106, apoc_attc7 ] {apoc_face(); apoc_spike();};
void() apoc_attc7 = [ $attc107, apoc_attc8 ] {apoc_face();};
void() apoc_attc8 = [ $attc108, apoc_attc9 ] {apoc_face();};
void() apoc_attc9 = [ $attc109, apoc_attc10 ] {apoc_face(); apoc_spike();};
void() apoc_attc10 = [ $attc110, apoc_attc11 ] {apoc_face();};
void() apoc_attc11 = [ $attc111, apoc_attc12 ] {apoc_face();};
void() apoc_attc12 = [ $attc112, apoc_melee ] {apoc_face();};
void() apoc_melee =
{
local vector vect, vecta;
if (self.last_flame > (time - 2.3)) {
// apoc_face();
if ((self.spawn_time != 99) && (self.last_flame > (time - 0.2))) { // found an enemy
sound(self, CHAN_VOICE, "apoc/astart.wav", 1, ATTN_NONE);
self.spawn_time = 99;
}
self.nextthink = time + 0.2;
return;
}
else if (self.spawn_time == 99) {
cvar_set("host_framerate", "0");
self.spawn_time = 0;
}
// first check if stomping (aligning legs with arms) is required
if (vlen(self.enemy.origin - self.origin) > 64) {
vect = normalize(self.enemy.origin - self.origin);
vecta = vectoangles(vect);
if (fabs(angle_diff(vecta_y, self.leg.angles_y)) > 30) {
// stomp!!
apoc_stomp();
self.nextthink = time + 0.05;
return;
}
}
if (vlen(self.enemy.origin - self.origin) < 96)
apoc_attc1();
else if (fabs(angle_diff(vecta_y, self.angles_y)) > 10)
apoc_attb1();
else
apoc_atta1();
};
//====================================================================================
void() apoc_pain101 = [ $pain101, apoc_die ]
{
local entity trav, last;
sound(self, CHAN_VOICE, "apoc/apocno.wav", 1, ATTN_NORM);
// prevent torso from taking damage
trav = find(world, classname, "apoc_torso");
if (trav != world) {
trav.solid = SOLID_NOT;
trav.takedamage = DAMAGE_NO;
}
// remove the bounding boxes for legs
remove(self.leg.leg.leg);
remove(self.leg.leg);
self.leg.leg = world;
self.x_flags = self.x_flags | X_MEGA_HIT;
self.enemy.currentammo = self.enemy.ammo_special = 0;
};
void() apoc_die =
{
local entity trav;
self.frame = self.frame + 1;
self.skin = 1 - self.skin;
self.leg.skin = 1 - self.leg.skin;
if (self.frame == $pain150 ) {
remove(self.leg);
trav = find(world, classname, "apoc_torso");
if (trav != world)
remove(trav);
// this is where the new smaller version of Apocalypse will kick in
ApocSmallSpawn();
self.think = SUB_Remove;
self.nextthink = time + 0.05;
}
self.nextthink = time + 0.1;
};
//====================================================================================
void() apoc_pain =
{
//bprint("apoc pain: ");
//bprint(ftos(self.health));
//bprint("\n");
// special weapon does 1000+ damage per strike
if (self.health > 99000)
self.health = 99999;
};
//====================================================================================
void() ApocLegsThink =
{
// sync frames with body
self.frame = self.owner.frame;
if (self.leg != world) {
// move leg bounding boxes
makevectors(self.angles);
setorigin(self.leg, self.origin + (v_right * 58));
setorigin(self.leg.leg, self.origin - (v_right * 58));
}
self.nextthink = time + 0.05;
};
void() SpawnApocLegs =
{
local entity ent;
ent = spawn();
ent.owner = self;
setmodel(ent, "progs/appy1.mdl");
traceline(self.origin, self.origin - '0 0 1024', TRUE, world);
setorigin(ent, trace_endpos + '0 0 24');
ent.angles = self.angles;
ent.yaw_speed = 5;
ent.think = ApocLegsThink;
ent.nextthink = time + 0.1;
self.leg = ent;
// now make the two solid leg boxes
// left
ent = spawn();
ent.owner = self.leg;
ent.classname = "apoc_leg";
ent.solid = SOLID_BBOX;
setsize(ent, VEC_HULL_MIN, VEC_HULL_MAX);
self.leg.leg = ent;
// right
ent = spawn();
ent.owner = self.leg;
ent.classname = "apoc_leg";
ent.solid = SOLID_BBOX;
setsize(ent, VEC_HULL_MIN, VEC_HULL_MAX);
self.leg.leg.leg = ent;
};
void() SpawnApocTorso =
{
local entity ent;
ent = spawn();
ent.classname = "apoc_torso";
ent.owner = self;
ent.solid = SOLID_BBOX;
ent.takedamage = DAMAGE_AIM;
ent.health = 99999;
setorigin(ent, self.origin + '0 0 330');
setsize(ent, '-138 -138 -300', '138 138 100');
};
//====================================================================================
void() xmen_apocalypse =
{
if (deathmatch) {
remove(self);
return;
}
precache_model("progs/appy1.mdl");
precache_model("progs/appy2.mdl");
precache_model("progs/apoc.mdl");
precache_model("progs/apblast.mdl");
precache_sound("apoc/thump.wav");
precache_sound("apoc/spike.wav");
precache_sound("apoc/swipe.wav");
precache_sound("apoc/astart.wav");
precache_sound("apoc/alaugh.wav");
precache_sound("apoc/apain2.wav");
precache_sound("apoc/apain4.wav");
precache_sound("apoc/apain5.wav");
precache_sound("apoc/apocno.wav");
precache_sound("apoc/miniapoc.wav");
precache_sound("apoc/aattack2.wav");
precache_sound("apoc/aattack3.wav");
precache_sound("apoc/aattack4.wav");
precache_sound("apoc/ahit.wav");
SpawnApocLegs();
SpawnApocTorso();
// self.solid = SOLID_BBOX;
setsize (self, '-128 -128 -24', '128 128 256');
setmodel(self, "progs/appy2.mdl");
self.health = 99999;
setorigin(self, self.leg.origin);
self.yaw_speed = 6;
self.takedamage = DAMAGE_AIM;
self.ideal_yaw = self.angles * '0 1 0';
self.view_ofs = '0 0 25';
self.spawn_time = time;
self.flags = self.flags | FL_MONSTER;
self.th_stand = apoc_stand1;
// self.th_walk = apoc_stand1;
self.th_run = apoc_melee;
self.th_pain = apoc_pain;
self.th_die = apoc_pain101;
self.th_melee = apoc_melee;
self.th_missile = apoc_melee;
self.pausetime = 99999999;
self.think = apoc_stand1;
self.nextthink = time + 0.1;
};

478
apsmall.c Normal file
View file

@ -0,0 +1,478 @@
$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9 stand10
$frame stand11 stand12 stand13
$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10
$frame walk11 walk12
$frame pain1 pain2 pain3 pain4 pain5 pain6 pain7 pain8 pain9 pain10
$frame pain11 pain12
$frame guard1 guard2 guard3 guard4 guard5 guard6 guard7 guard8
$frame guard9 guard10 guard11 guard12
$frame atta0 atta1 atta2 atta3 atta4 atta5 atta6 atta7 atta8
$frame atta9 atta10 atta11 atta12
$frame attb1 attb2 attb3 attb4 attb5 attb6 attb7 attb8
$frame attb9 attb10 attb11 attb12
$frame xatta1 xatta2 xatta3 xatta4 xatta5 xatta6 xatta7 xatta8
$frame xatta9 xatta10 xatta11 xatta12
$frame xattb1 xattb2 xattb3 xattb4 xattb5 xattb6 xattb7 xattb8
$frame xattb9 xattb10 xattb11 xattb12
$frame deatha1 deatha2 deatha3 deatha4 deatha5 deatha6 deatha7 deatha8 deatha9 deatha10
$frame deatha11 deatha12 deatha13 deatha14 deatha15 deatha16 deatha17 deatha18 deatha19 deatha20
$frame deatha21 deatha22 deatha23 deatha24 deatha25 deatha26 deatha27 deatha28 deatha29 deatha30
$frame pant1 pant2 pant3 pant4 pant5 pant6 pant7 pant8 pant9 pant10
//====================================================================================
void() apsmall_clone1 = [$stand1, apsmall_clone2 ] {};
void() apsmall_clone2 = [$stand2, apsmall_clone3 ] {};
void() apsmall_clone3 = [$stand3, apsmall_clone4 ] {};
void() apsmall_clone4 = [$stand4, apsmall_clone5 ] {};
void() apsmall_clone5 = [$stand5, apsmall_clone6 ] {};
void() apsmall_clone6 = [$stand6, apsmall_clone7 ] {};
void() apsmall_clone7 = [$stand7, apsmall_clone8 ] {};
void() apsmall_clone8 = [$stand8, apsmall_clone9 ] {};
void() apsmall_clone9 = [$stand9, apsmall_clone10 ] {};
void() apsmall_clone10 = [$stand10, apsmall_clone11 ] {};
void() apsmall_clone11 = [$stand11, apsmall_clone12 ] {};
void() apsmall_clone12 = [$stand12, apsmall_clone13 ] {};
void() apsmall_clone13 = [$stand13, apsmall_clone1 ] {};
//====================================================================================
void() apsmall_stand = [$walk1, apsmall_stand ] {};
void() apsmall_walk = [$walk1, apsmall_walk ]
{
self.walkframe = self.walkframe + 1;
if (self.walkframe >= 11)
self.walkframe = 0;
if (self.walkframe == 0) ai_run(9);
else if (self.walkframe == 1) ai_run(6);
else if (self.walkframe == 2) ai_run(7);
else if (self.walkframe == 3) ai_run(8);
else if (self.walkframe == 4) ai_run(8);
else if (self.walkframe == 5) ai_run(9);
else if (self.walkframe == 6) ai_run(14);
else if (self.walkframe == 7) ai_run(6);
else if (self.walkframe == 8) ai_run(5);
else if (self.walkframe == 9) ai_run(7);
else if (self.walkframe == 10) ai_run(7);
else if (self.walkframe == 11) ai_run(8);
// ai_face();
self.frame = self.frame + self.walkframe;
};
//====================================================================================
void() apsmall_pain = [$pain1, apsmall_pain ]
{
self.walkframe = self.walkframe + 1;
if (self.walkframe == 11) {
self.think = self.th_run;
}
self.frame = self.frame + self.walkframe;
};
void(entity attacker, float damage) ApocSmallPain =
{
if (self.spawnflags & SPAWNFLAG_CLONE) {
self.health = 99999;
return;
}
if (self.pain_finished > time)
return;
if (random() * 100 > damage)
return;
if (random() * 80 < damage)
sound(self, CHAN_BODY, "apoc/apain2.wav", 1, ATTN_NORM);
else if (random() < 0.5)
sound(self, CHAN_BODY, "apoc/apain4.wav", 1, ATTN_NORM);
else
sound(self, CHAN_BODY, "apoc/apain5.wav", 1, ATTN_NORM);
self.walkframe = -1;
self.pain_finished = time + 3;
apsmall_pain();
};
//====================================================================================
void() ApocCheckGuard =
{
local entity trav;
trav = world;
while ((trav = find(trav, classname, "guided_rocket")) != world) {
// check that rocket is targetted for self
if (trav.enemy == self) { // uh oh
return;
}
}
// dangerous rocket not found
self.flags = self.flags - (self.flags & FL_GODMODE);
self.walkframe = 8;
};
void() apsmall_guard = [$guard1, apsmall_guard ]
{
self.walkframe = self.walkframe + 1;
if (self.walkframe == 11)
self.think = self.th_run;
else if (self.walkframe == 3)
self.flags = self.flags | FL_GODMODE;
else if (self.walkframe == 8) {
self.walkframe = 7;
ApocCheckGuard();
}
self.frame = self.frame + self.walkframe;
};
void() ApocSmallGuardStart =
{
self.walkframe = -1;
apsmall_guard();
};
//====================================================================================
void() apsmall_atta = [$atta0, apsmall_atta ]
{
local vector vec1;
local float frame_diff;
self.walkframe = self.walkframe + 1;
if (self.walkframe == 12)
self.think = self.th_run;
self.frame = self.frame + self.walkframe;
frame_diff = fabs(self.frame - $atta7 );
if (frame_diff <= 3) {
makevectors(self.angles);
vec1 = normalize(self.enemy.origin - self.origin);
if (vlen(v_forward - vec1) < 0.2) {
if (vlen(self.enemy.origin - self.origin) < (128 - ((frame_diff / 3) * 64)))
T_Damage(self.enemy, self, self, 12);
}
}
self.nextthink = time + 0.05;
};
void() apsmall_attb = [$attb1, apsmall_attb ]
{
ai_face();
ai_forward(8);
self.walkframe = self.walkframe + 1;
if (self.walkframe == 11)
self.think = self.th_run;
self.frame = self.frame + self.walkframe;
if ((self.frame == $attb3 ) ||
(self.frame == $attb8 )) {
if (infront(self.enemy)) {
if (vlen(self.enemy.origin - self.origin) < 85) {
sound(self, CHAN_BODY, "apoc/ahit.wav", 1, ATTN_NORM);
T_Damage(self.enemy, self, self, 20);
makevectors(self.angles);
if (!(self.enemy.flags & FL_ONGROUND))
self.enemy.velocity = v_forward * 200 + '0 0 235';
else
self.enemy.velocity = '0 0 235';
self.enemy.punchangle_x = -10;
}
}
}
};
void() ApocSmallMelee =
{
self.walkframe = -1;
apsmall_attb();
};
//====================================================================================
void() ApocBallTouch =
{
if (other == self.owner)
return;
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_EXPLOSION);
WriteCoord (MSG_BROADCAST, self.origin_x);
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
if (other.takedamage == DAMAGE_AIM)
{
spawn_touchblood (10);
T_Damage(other, self, self.owner, 10);
if (other.classname == "player") {
other.velocity = other.velocity + (self.velocity * 0.2) + '0 0 180';
other.flags = other.flags - (other.flags & FL_ONGROUND);
}
}
remove(self);
};
void(vector org) spawn_apocball =
{
local entity missile, mpuff;
local vector vect;
missile = spawn ();
missile.owner = self;
missile.movetype = MOVETYPE_FLYMISSILE;
missile.solid = SOLID_BBOX;
missile.classname = "apocball";
missile.velocity = ProjectVelocity(1100, '0 0 0');
missile.angles = vectoangles(missile.velocity);
missile.old_velocity = missile.velocity;
missile.touch = ApocBallTouch;
missile.last_touch = 0;
missile.oldorigin = missile.origin;
missile.nextthink = time + 20;
missile.think = SUB_Remove;
setmodel (missile, "progs/apblast.mdl");
setsize (missile, '0 0 0', '0 0 0');
setorigin (missile, org);
};
void() apsmall_xatta = [$xatta1, apsmall_xatta ]
{
ai_face();
self.walkframe = self.walkframe + 1;
if (self.walkframe == 11)
self.think = self.th_run;
else if (self.walkframe == 4) {
makevectors(self.angles);
spawn_apocball(self.origin);
}
self.frame = self.frame + self.walkframe;
};
void() apsmall_xattb = [$xattb1, apsmall_xattb ]
{
ai_face();
self.walkframe = self.walkframe + 1;
if (self.walkframe == 11)
self.think = self.th_run;
else if (self.walkframe == 5) {
makevectors(self.angles);
spawn_apocball(self.origin + v_right * 3);
spawn_apocball(self.origin - v_right * 3);
}
self.frame = self.frame + self.walkframe;
};
void() ApocSmallMissile =
{
local float rnd;
if (self.spawn_time > (time - 4.5)) // don't attack for 4.5 seconds after shrinking
return;
if (self.last_special > (time - 3)) {
if (vlen(self.origin - self.enemy.origin) < 160) {
self.walkframe = -1;
apsmall_atta();
}
else {
self.walkframe = -1;
self.last_special2 = time;
apsmall_xatta();
}
}
else {
self.walkframe = -1;
self.last_special = time;
apsmall_xattb();
}
rnd = random() * 5;
if (rnd < 1)
sound(self, CHAN_VOICE, "apoc/aattack2.wav", 1, ATTN_NORM);
else if (rnd < 2)
sound(self, CHAN_VOICE, "apoc/aattack3.wav", 1, ATTN_NORM);
else if (rnd < 3)
sound(self, CHAN_VOICE, "apoc/aattack4.wav", 1, ATTN_NORM);
};
//====================================================================================
void() apoc_pant = [ $pant1, apoc_pant ]
{
self.walkframe = self.walkframe + 1;
if (self.walkframe > 9)
self.walkframe = 0;
self.frame = self.frame + self.walkframe;
};
void() apsmall_death = [$deatha1, apsmall_death ]
{
local entity trav;
local vector vec1;
if (self.walkframe < 30)
self.walkframe = self.walkframe + 1;
/*
else if (self.walkframe == 35) {
makevectors(self.angles);
vec1 = normalize(self.enemy.origin - self.origin);
if (vlen(self.enemy.origin - self.origin) < 90) {
if (vlen(v_forward - vec1) < 0.2) {
T_Damage(self.enemy, self, self, 25);
}
}
}
*/
else if ((self.walkframe == 30) && (self.enemy.health > 0)) { // show completed episode 1 sequence
killed_monsters = killed_monsters + 1;
WriteByte (MSG_ALL, SVC_KILLEDMONSTER); // FIXME: reliable broadcast
trav = find (world, classname, "player");
while (trav != world)
{
trav.view_ofs = '0 0 0';
trav.nextthink = time + 0.5;
trav.takedamage = DAMAGE_NO;
trav.solid = SOLID_NOT;
trav.movetype = MOVETYPE_NONE;
trav.weapon_parts = 0;
trav = find (trav, classname, "player");
}
WriteByte (MSG_ALL, SVC_INTERMISSION);
nextmap = "x2m1";
serverflags = serverflags - (serverflags & 15); // remove rune items from the consol
intermission_running = 1;
SUB_UseTargets ();
self.think = apoc_pant;
self.nextthink = time + 0.1;
}
self.frame = self.frame + self.walkframe;
};
void() ApocSmallDie =
{
self.walkframe = -1;
apsmall_death();
sound(self, CHAN_VOICE, "apoc/apain2.wav", 1, ATTN_NORM);
};
//====================================================================================
void(vector org) ApocSmallSpawn =
{
local entity apoc, oself;
apoc = spawn();
apoc.classname = "apocalypse_small";
setorigin(apoc, self.origin);
apoc.solid = SOLID_SLIDEBOX;
apoc.movetype = MOVETYPE_STEP;
apoc.takedamage = DAMAGE_AIM;
setmodel (apoc, "progs/apoc.mdl");
setsize (apoc, VEC_HULL2_MIN, VEC_HULL2_MAX);
apoc.health = 600;
apoc.yaw_speed = 20;
apoc.th_stand = apsmall_stand;
apoc.th_walk = apsmall_stand;
apoc.th_run = apsmall_walk;
apoc.th_pain = ApocSmallPain;
apoc.th_die = ApocSmallDie;
apoc.th_melee = ApocSmallMelee;
apoc.th_missile = ApocSmallMissile;
apoc.th_guard = ApocSmallGuardStart;
apoc.x_flags = apoc.x_flags | X_MEGA_HIT;
oself = self;
self = apoc;
walkmonster_start_go();
self = oself;
apoc.enemy = apoc.goalentity = self.enemy;
apoc.think = apoc.th_run;
apoc.nextthink = time + 0.1;
apoc.frame = $walk1;
apoc.spawn_time = time;
sound(self, CHAN_VOICE, "apoc/miniapoc.wav", 1, ATTN_NORM);
};
void() xmen_apocalypse_small =
{
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_NONE;
precache_model("progs/apoc.mdl");
setmodel (self, "progs/apoc.mdl");
setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX);
self.health = 99999;
self.th_stand = apsmall_clone1;
self.th_walk = apsmall_clone1;
self.th_run = apsmall_clone1;
self.th_pain = ApocSmallPain;
self.th_die = apsmall_clone1;
if (self.spawnflags & SPAWNFLAG_CLONE) {
self.flags = self.flags & FL_GODMODE;
droptofloor();
self.think = self.th_stand;
self.nextthink = time + 0.1;
}
};

621
beast.c Normal file
View file

@ -0,0 +1,621 @@
/*
==============================================================================
beast
==============================================================================
*/
$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
$frame stand10 stand11 stand12 stand13
$frame runa1 runa2 runa3 runa4 runa5 runa6 runa7 runa8 runa9 runa10
$frame runa11 runa12
$frame runb1 runb2 runb3 runb4 runb5 runb6 runb7 runb8 runb9 runb10
$frame runb11 runb12
$frame runc1 runc2 runc3 runc4 runc5 runc6 runc7 runc8 runc9 runc10
$frame runc11 runc12
$frame pain1 pain2 pain3 pain4 pain5 pain6
$frame death1 death2 death3 death4 death5 death6 death7 death8 death9 death10
$frame death11 death12
$frame deata1 deata2 deata3 deata4 deata5 deata6 deata7 deata8 deata9 deata10
$frame deata11 deata12
$frame atta1 atta2 atta3 atta4 atta5 atta6 atta7 atta8
$frame atta9 atta10 atta11 atta12
$frame attb1 attb2 attb3 attb4 attb5 attb6 attb7 attb8
$frame attb9 attb10 attb11 attb12
$frame xatta1 xatta2 xatta3 xatta4 xatta5 xatta6 xatta7 xatta8
$frame xatta9 xatta10 xatta11 xatta12 xatta13 xatta14 xatta15 xatta16 xatta17 xatta18
void() beast_atta1;
void() beast_atta8;
void() beast_runa1;
/*
================
beast_bite
================
*/
void() beast_bite =
{
local vector delta;
local float ldmg;
local entity plyr;
makevectors(self.v_angle);
if ((plyr = FindSightEnemy(self.origin, v_forward, 60, 40, "all", self)) == world)
return;
delta = plyr.origin - self.origin;
if (vlen(delta) > 60)
return;
ldmg = 9 + random() * 3;
T_Damage (plyr, self, self, ldmg);
if (self.frame >= $attb1 ) {
if (random() < 0.5)
sound(self, CHAN_WEAPON, "generic/punch2.wav", 1, ATTN_NORM);
else
sound(self, CHAN_WEAPON, "generic/punch3.wav", 1, ATTN_NORM);
}
else
sound(self, CHAN_WEAPON, "generic/punch1.wav", 1, ATTN_NORM);
};
/*
void() beast_JumpTouch =
{
local float ldmg;
if (self.health <= 0)
return;
if (other.takedamage)
{
if ( vlen(self.velocity) > 300 )
{
ldmg = 15 + 10*random();
T_Damage (other, self, self, ldmg);
}
}
if (!checkbottom(self))
{
if (self.flags & FL_ONGROUND)
{ // jump randomly to not get hung up
//bprint ("popjump\n");
self.touch = SUB_Null;
self.think = beast_atta1;
self.nextthink = time + 0.1;
// self.velocity_x = (random() - 0.5) * 600;
// self.velocity_y = (random() - 0.5) * 600;
// self.velocity_z = 200;
// self.flags = self.flags - FL_ONGROUND;
}
return; // not on ground yet
}
self.touch = SUB_Null;
self.think = beast_atta8;
self.nextthink = time + 0.05;
};
*/
void() beast_stand1 =[ $stand1, beast_stand2 ] {ai_stand();};
void() beast_stand2 =[ $stand2, beast_stand3 ] {ai_stand();};
void() beast_stand3 =[ $stand3, beast_stand4 ] {ai_stand();};
void() beast_stand4 =[ $stand4, beast_stand5 ] {ai_stand();};
void() beast_stand5 =[ $stand5, beast_stand6 ] {ai_stand();};
void() beast_stand6 =[ $stand6, beast_stand7 ] {ai_stand();};
void() beast_stand7 =[ $stand7, beast_stand8 ] {ai_stand();};
void() beast_stand8 =[ $stand8, beast_stand9 ] {ai_stand();};
void() beast_stand9 =[ $stand9, beast_stand10 ] {ai_stand();};
void() beast_stand10 =[ $stand10, beast_stand11 ] {ai_stand();};
void() beast_stand11 =[ $stand11, beast_stand12 ] {ai_stand();};
void() beast_stand12 =[ $stand12, beast_stand13 ] {ai_stand();};
void() beast_stand13 =[ $stand13, beast_stand1 ] {ai_stand();};
/*
void() beast_walk1 =[ $walk1 , beast_walk2 ] {
ai_walk(8);};
void() beast_walk2 =[ $walk2 , beast_walk3 ] {ai_walk(8);};
void() beast_walk3 =[ $walk3 , beast_walk4 ] {ai_walk(8);};
void() beast_walk4 =[ $walk4 , beast_walk5 ] {ai_walk(8);};
void() beast_walk5 =[ $walk5 , beast_walk6 ] {ai_walk(8);};
void() beast_walk6 =[ $walk6 , beast_walk7 ] {ai_walk(8);};
void() beast_walk7 =[ $walk7 , beast_walk8 ] {ai_walk(8);};
void() beast_walk8 =[ $walk8 , beast_walk1 ] {ai_walk(8);};
*/
void() beast_random_run;
void() beast_runa1 =[ $runa1 , beast_runa2 ] {
ai_run(32);};
void() beast_runa2 =[ $runa2 , beast_runa3 ] {ai_run(32);};
void() beast_runa3 =[ $runa3 , beast_runa4 ] {ai_run(32);};
void() beast_runa4 =[ $runa4 , beast_runa5 ] {ai_run(20);};
void() beast_runa5 =[ $runa5 , beast_runa6 ] {ai_run(32);};
void() beast_runa6 =[ $runa6 , beast_runa7 ] {ai_run(32);};
void() beast_runa7 =[ $runa7 , beast_runa8 ] {ai_run(26);};
void() beast_runa8 =[ $runa8 , beast_runa9 ] {ai_run(32);};
void() beast_runa9 =[ $runa9 , beast_runa10 ] {ai_run(32);};
void() beast_runa10 =[ $runa10 , beast_runa11 ] {ai_run(20);};
void() beast_runa11 =[ $runa11 , beast_runa12 ] {ai_run(32);};
void() beast_runa12 =[ $runa12 , beast_runa1 ]
{
ai_run(32);
beast_random_run();
};
void() beast_runb1 =[ $runb1 , beast_runb2 ] {
ai_run(32);};
void() beast_runb2 =[ $runb2 , beast_runb3 ] {ai_run(32);};
void() beast_runb3 =[ $runb3 , beast_runb4 ] {ai_run(32);};
void() beast_runb4 =[ $runb4 , beast_runb5 ] {ai_run(20);};
void() beast_runb5 =[ $runb5 , beast_runb6 ] {ai_run(32);};
void() beast_runb6 =[ $runb6 , beast_runb7 ] {ai_run(32);};
void() beast_runb7 =[ $runb7 , beast_runb8 ] {ai_run(26);};
void() beast_runb8 =[ $runb8 , beast_runb9 ] {ai_run(32);};
void() beast_runb9 =[ $runb9 , beast_runb10 ] {ai_run(32);};
void() beast_runb10 =[ $runb10 , beast_runb11 ] {ai_run(20);};
void() beast_runb11 =[ $runb11 , beast_runb12 ] {ai_run(32);};
void() beast_runb12 =[ $runb12 , beast_runb1 ]
{
ai_run(32);
beast_random_run();
};
void() beast_runc1 =[ $runc1 , beast_runc2 ] {
ai_run(32);};
void() beast_runc2 =[ $runc2 , beast_runc3 ] {ai_run(32);};
void() beast_runc3 =[ $runc3 , beast_runc4 ] {ai_run(32);};
void() beast_runc4 =[ $runc4 , beast_runc5 ] {ai_run(20);};
void() beast_runc5 =[ $runc5 , beast_runc6 ] {ai_run(32);};
void() beast_runc6 =[ $runc6 , beast_runc7 ] {ai_run(32);};
void() beast_runc7 =[ $runc7 , beast_runc8 ] {ai_run(26);};
void() beast_runc8 =[ $runc8 , beast_runc9 ] {ai_run(32);};
void() beast_runc9 =[ $runc9 , beast_runc10 ] {ai_run(32);};
void() beast_runc10 =[ $runc10 , beast_runc11 ] {ai_run(20);};
void() beast_runc11 =[ $runc11 , beast_runc12 ] {ai_run(32);};
void() beast_runc12 =[ $runc12 , beast_runc1 ]
{
ai_run(32);
beast_random_run();
};
void() beast_random_run =
{
local float rnd;
rnd = random() * 3;
if (rnd < 1)
self.think = beast_runa1;
else if (rnd < 2)
self.think = beast_runb1;
else
self.think = beast_runc1;
};
float() CheckbeastMelee;
void() beast_attb1 =[ $attb1, beast_attb2 ] {ai_charge(10);};
void() beast_attb2 =[ $attb2, beast_attb3 ] {ai_charge(10);};
void() beast_attb3 =[ $attb3, beast_attb4 ] {ai_charge(10);};
void() beast_attb4 =[ $attb4, beast_attb5 ] {
beast_bite();};
void() beast_attb5 =[ $attb5, beast_attb6 ] {ai_charge(10);};
void() beast_attb6 =[ $attb6, beast_attb7 ]
{
ai_charge(10);
// check if enemy is still in striking distance
if (!CheckbeastMelee())
beast_runa1();
};
void() beast_attb7 =[ $attb7, beast_attb8 ] {
beast_bite();};
void() beast_attb8 =[ $attb8, beast_attb9 ] {ai_charge(10);};
void() beast_attb9 =[ $attb9, beast_attb10 ] {ai_charge(10);};
void() beast_attb10 =[ $attb10, beast_attb11 ] {
beast_bite();};
void() beast_attb11 =[ $attb11, beast_attb12 ] {ai_charge(10);};
void() beast_attb12 =[ $attb12, beast_runa1 ] {ai_charge(10);};
void() beast_atta1 =[ $atta1, beast_atta2 ] {ai_charge(10);};
void() beast_atta2 =[ $atta2, beast_atta3 ] {ai_charge(10);};
void() beast_atta3 =[ $atta3, beast_atta4 ] {ai_charge(10);};
void() beast_atta4 =[ $atta4, beast_atta5 ] {ai_charge(10);};
void() beast_atta5 =[ $atta5, beast_atta6 ] {ai_charge(10);};
void() beast_atta6 =[ $atta6, beast_atta7 ] {ai_charge(10);};
void() beast_atta7 =[ $atta7, beast_atta8 ] {ai_charge(10);};
void() beast_atta8 =[ $atta8, beast_atta9 ] {ai_charge(10);};
void() beast_atta9 =[ $atta9, beast_atta10 ] {
beast_bite();
beast_bite();
ai_charge(10);};
void() beast_atta10 =[ $atta10, beast_atta11 ] {ai_charge(10);};
void() beast_atta11 =[ $atta11, beast_atta12 ] {ai_charge(10);};
void() beast_atta12 =[ $atta12, beast_runa1 ] {ai_charge(10);};
void() beast_melee =
{
if (random() < 0.5)
beast_atta1();
else
beast_attb1();
};
// special attack
void() BeastPowTouch =
{
local float damg;
if ((other == self.owner) || (other == world))
return;
damg = 25 + random()*10;
if (other.health)
{
T_Damage (other, self, self.owner, damg );
}
other.velocity = other.velocity + self.velocity + '0 0 200';
other.flags = other.flags - (other.flags & FL_ONGROUND);
setorigin(other, other.origin + '0 0 1');
sound (self.owner, CHAN_WEAPON, "weapons/r_exp3.wav", 0.2, ATTN_NORM);
self.origin = self.origin - 8*normalize(self.velocity);
/*
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_EXPLOSION);
WriteCoord (MSG_BROADCAST, self.origin_x);
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
*/
// BecomeExplosion ();
remove(self);
};
void() BeastPowThink =
{
local entity trav;
local vector vec;
local float dist, ratio;
if ((self.spawn_time < (time - 3)) || (self.origin == self.oldorigin)) {
sound (self.owner, CHAN_WEAPON, "weapons/r_exp3.wav", 0.2, ATTN_NORM);
remove(self);
return;
}
self.frame = self.frame + 1;
if (self.frame >= 8)
self.frame = 0;
vec = self.velocity;
traceline(self.origin + vec*frametime*2 + '0 0 32', self.origin + vec*frametime*2 - '0 0 48', TRUE, world);
if (trace_fraction == 1) {
sound (self.owner, CHAN_WEAPON, "weapons/r_exp3.wav", 0, ATTN_NORM);
remove(self);
return;
}
else {
self.velocity = normalize(trace_endpos + '0 0 24' - self.origin) * 750;
self.flags = self.flags - (self.flags & FL_ONGROUND);
traceline(self.origin + '0 0 32', self.origin - '0 0 48', TRUE, world);
setorigin(self, trace_endpos + '0 0 24');
}
// earth-shake
trav = findradius(self.origin, 512);
while (trav != world) {
if (trav.classname == "player") {
// shake view
vec = '12 0 0' * random() + '0 12 0' * random() + '0 0 22' * random() - '6 6 14';
ratio = 1 - (vlen(trav.origin - self.origin) / 512);
if (ratio > 1)
ratio = 1;
vec = vec * ratio;
trav.view_ofs = '0 0 22' + vec;
trav.punchangle = vec * 0.5;
if (trav.view_ofs == '0 0 0')
trav.view_ofs = '0 0 1';
}
trav = trav.chain;
}
self.oldorigin = self.origin;
self.nextthink = time + 0.05;
};
void() BeastSpecialAttack =
{
local entity trav;
local entity missile;
missile = spawn();
missile.classname = "beast_power";
missile.owner = self;
missile.solid = SOLID_TRIGGER;
missile.movetype = MOVETYPE_FLY;
setsize(missile, '0 0 0', '0 0 0');
setmodel(missile, "progs/pow.mdl");
missile.velocity = normalize(self.enemy.origin - self.origin + self.enemy.velocity * 0.5) * 750;
missile.velocity_z = 0;
missile.old_velocity = missile.velocity;
makevectors(self.angles);
setorigin(missile, self.origin + v_forward * 16);
missile.touch = BeastPowTouch;
missile.think = BeastPowThink;
missile.spawn_time = time;
missile.nextthink = time + 0.05;
/*
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_EXPLOSION);
WriteCoord (MSG_BROADCAST, missile.origin_x);
WriteCoord (MSG_BROADCAST, missile.origin_y);
WriteCoord (MSG_BROADCAST, missile.origin_z);
*/
sound (self, CHAN_BODY, "weapons/r_exp3.wav", 0.4, ATTN_NORM);
sound (self, CHAN_WEAPON, "doors/stndr1.wav", 1, ATTN_NORM);
// send players airbourne
trav = find(world, classname, "player");
while (trav != world) {
if ((trav.flags & FL_ONGROUND) && (vlen(trav.origin - self.origin) < 256))
trav.velocity_z = 225;
trav = find(trav, classname, "player");
}
};
void() beast_xatta1 =[ $xatta1, beast_xatta2 ] {self.last_special = time;};
void() beast_xatta2 =[ $xatta2, beast_xatta3 ] {};
void() beast_xatta3 =[ $xatta3, beast_xatta4 ] {};
void() beast_xatta4 =[ $xatta4, beast_xatta5 ] {};
void() beast_xatta5 =[ $xatta5, beast_xatta6 ] {};
void() beast_xatta6 =[ $xatta6, beast_xatta7 ] {};
void() beast_xatta7 =[ $xatta7, beast_xatta8 ] {};
void() beast_xatta8 =[ $xatta8, beast_xatta9 ] {};
void() beast_xatta9 =[ $xatta9, beast_xatta10 ] {};
void() beast_xatta10 =[ $xatta10, beast_xatta11 ] {};
void() beast_xatta11 =[ $xatta11, beast_xatta12 ] {BeastSpecialAttack();};
void() beast_xatta12 =[ $xatta12, beast_xatta13 ] {};
void() beast_xatta13 =[ $xatta13, beast_xatta14 ] {};
void() beast_xatta14 =[ $xatta14, beast_xatta15 ] {};
void() beast_xatta15 =[ $xatta15, beast_xatta16 ] {};
void() beast_xatta16 =[ $xatta16, beast_xatta17 ] {};
void() beast_xatta17 =[ $xatta17, beast_xatta18 ] {};
void() beast_xatta18 =[ $xatta18, beast_runa1 ] {};
void() beast_pain1 =[ $pain1 , beast_pain2 ] {};
void() beast_pain2 =[ $pain2 , beast_pain3 ] {};
void() beast_pain3 =[ $pain3 , beast_pain4 ] {};
void() beast_pain4 =[ $pain4 , beast_pain5 ] {};
void() beast_pain5 =[ $pain5 , beast_pain6 ] {};
void() beast_pain6 =[ $pain6 , beast_runa1 ] {};
void(entity attacker, float damage) beast_pain =
{
if (self.pain_finished > time)
return;
MalePainSound(1);
if (random()*100 > damage)
return;
self.pain_finished = time + 2;
beast_pain1 ();
};
void() beast_die1 =[ $death1, beast_die2 ] {};
void() beast_die2 =[ $death2, beast_die3 ] {};
void() beast_die3 =[ $death3, beast_die4 ] {};
void() beast_die4 =[ $death4, beast_die5 ] {};
void() beast_die5 =[ $death5, beast_die6 ] {};
void() beast_die6 =[ $death6, beast_die7 ] {};
void() beast_die7 =[ $death7, beast_die8 ] {};
void() beast_die8 =[ $death8, beast_die9 ] {};
void() beast_die9 =[ $death9, beast_die10 ] {};
void() beast_die10 =[ $death10, beast_die11 ] {};
void() beast_die11 =[ $death11, beast_die12 ] {};
void() beast_die12 =[ $death12, beast_die12 ] {};
void() beast_diea1 =[ $deata1, beast_diea2 ] {};
void() beast_diea2 =[ $deata2, beast_diea3 ] {};
void() beast_diea3 =[ $deata3, beast_diea4 ] {};
void() beast_diea4 =[ $deata4, beast_diea5 ] {};
void() beast_diea5 =[ $deata5, beast_diea6 ] {};
void() beast_diea6 =[ $deata6, beast_diea7 ] {};
void() beast_diea7 =[ $deata7, beast_diea8 ] {};
void() beast_diea8 =[ $deata8, beast_diea9 ] {};
void() beast_diea9 =[ $deata9, beast_diea10 ] {};
void() beast_diea10 =[ $deata10, beast_diea11 ] {};
void() beast_diea11 =[ $deata11, beast_diea12 ] {};
void() beast_diea12 =[ $deata12, beast_diea12 ] {};
void() beast_die =
{
// regular death
MaleDeathSound(1);
self.solid = SOLID_NOT;
if (random() > 0.5)
beast_die1 ();
else
beast_diea1 ();
};
//============================================================================
/*
==============
CheckbeastMelee
Returns TRUE if a melee attack would hit right now
==============
*/
float() CheckbeastMelee =
{
if ((enemy_range == RANGE_MELEE) && (vlen(self.origin - self.enemy.origin) < 96))
{ // FIXME: check canreach
self.attack_state = AS_MELEE;
return TRUE;
}
return FALSE;
};
/*
==============
CheckbeastJump
==============
*/
float() CheckbeastJump =
{
local vector dist, p1, p2;
local float d;
if (self.last_special > (time - 4))
return FALSE;
// check for head room
traceline(self.origin, self.origin + '0 0 64', TRUE, self);
if (trace_fraction < 1)
return FALSE;
// check if on same level as enemy
traceline(self.origin, self.origin - '0 0 64', TRUE, self);
p1 = trace_endpos;
traceline(self.enemy.origin, self.enemy.origin - '0 0 64', TRUE, self);
p2 = trace_endpos;
if (p1_z != p2_z)
return FALSE;
// now, check line of sight (between p1 and p2)
p1 = p1 + '0 0 1';
p2 = p2 + '0 0 1';
traceline(p1, p2, TRUE, world);
if (trace_fraction < 1)
return FALSE;
dist = self.enemy.origin - self.origin;
dist_z = 0;
d = vlen(dist);
if (d < 80)
return FALSE;
if (d > 256)
return FALSE;
return TRUE;
};
float() beastCheckAttack =
{
local vector vec;
// if close enough for slashing, go for it
if (CheckbeastMelee ())
{
self.attack_state = AS_MELEE;
return TRUE;
}
if (CheckbeastJump ())
{
self.attack_state = AS_MISSILE;
return TRUE;
}
return FALSE;
};
//===========================================================================
/*QUAKED monster_beast (1 0 0) (-32 -32 -24) (32 32 40) Ambush
*/
void() monster_dog =
{
remove(self);
};
void() xmen_beast =
{
if (deathmatch)
{
remove(self);
return;
}
precache_model ("progs/beast.mdl");
precache_model ("progs/pow.mdl");
// XMen matched ID sounds
// precache_sound ("zombie/z_hit.wav");
precache_sound ("zombie/z_miss.wav");
precache_sound ("doors/stndr1.wav");
precache_sound ("generic/punch1.wav");
precache_sound ("generic/punch2.wav");
precache_sound ("generic/punch3.wav");
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
setmodel (self, "progs/beast.mdl");
setsize (self, VEC_HULL_MIN, VEC_HULL_MAX);
self.health = 100 + cvar("skill")*10;
self.th_stand = beast_stand1;
self.th_walk = beast_stand1;
self.th_run = beast_runa1;
self.th_pain = beast_pain;
self.th_die = beast_die;
self.th_melee = beast_melee;
self.th_missile = beast_xatta1;
walkmonster_start();
};

323
bishop.c Normal file
View file

@ -0,0 +1,323 @@
/*
==============================================================================
Bishop
==============================================================================
Attack : Bishop enjoys using a BIG gun, He also has the ability to
absorb energy, allowing him to redirect it back towards his attacker.
Bishops main weapon is two cool futuristic laser type guns. If the
player uses an energy weapon against him, Bishop will not be effected,
but will store up energy for a special (magic) attack.
Bishop will do his special attack at random times. This will be a
huge energy burst from his hands.
Defence : The ability to Store energy attacks
Best weapon to use : Chaingun.
Worst weapon to use : Lazer will not be effectual
*/
$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
$frame stand10 stand11 stand12 stand13
$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10
$frame walk11 walk12
$frame run1 run2 run3 run4 run5 run6 run7 run8
$frame pain1 pain2 pain3 pain4 pain5 pain6 pain7 pain8 pain9
$frame paina1 paina2 paina3 paina4 paina5 paina6 paina7 paina8 paina9 paina10
$frame paina11 paina12 paina13 paina14 paina15 paina16 paina17 paina18 paina19 paina20
$frame paina21 paina22 paina23
$frame death1 death2 death3 death4 death5 death6 death7 death8 death9 death10
$frame death11 death12 death13 death14 death15 death16
$frame shoot1 shoot2 shoot3 shoot4 shoot5 shoot6 shoot7 shoot8
$frame xatta1 xatta2 xatta3 xatta4 xatta5 xatta6 xatta7 xatta8
$frame xatta9 xatta10 xatta11 xatta12
void(float r_ofs) bishop_fire;
void() bishop_specialfire;
void() bishop_stand1 =[ $stand1, bishop_stand2 ] {ai_stand();};
void() bishop_stand2 =[ $stand2, bishop_stand3 ] {ai_stand();};
void() bishop_stand3 =[ $stand3, bishop_stand4 ] {ai_stand();};
void() bishop_stand4 =[ $stand4, bishop_stand5 ] {ai_stand();};
void() bishop_stand5 =[ $stand5, bishop_stand6 ] {ai_stand();};
void() bishop_stand6 =[ $stand6, bishop_stand7 ] {ai_stand();};
void() bishop_stand7 =[ $stand7, bishop_stand8 ] {ai_stand();};
void() bishop_stand8 =[ $stand8, bishop_stand9 ] {ai_stand();};
void() bishop_stand9 =[ $stand9, bishop_stand10 ] {ai_stand();};
void() bishop_stand10 =[ $stand10, bishop_stand11 ] {ai_stand();};
void() bishop_stand11 =[ $stand11, bishop_stand12 ] {ai_stand();};
void() bishop_stand12 =[ $stand12, bishop_stand13 ] {ai_stand();};
void() bishop_stand13 =[ $stand13, bishop_stand1 ] {ai_stand();};
void() bishop_walk1 =[ $walk1, bishop_walk2 ] {
//if (random() < 0.2)
// sound (self, CHAN_VOICE, "soldier/idle.wav", 1, ATTN_IDLE);
ai_walk(6);};
void() bishop_walk2 =[ $walk2, bishop_walk3 ] {ai_walk(6);};
void() bishop_walk3 =[ $walk3, bishop_walk4 ] {ai_walk(6);};
void() bishop_walk4 =[ $walk4, bishop_walk5 ] {ai_walk(6);};
void() bishop_walk5 =[ $walk5, bishop_walk6 ] {ai_walk(7);};
void() bishop_walk6 =[ $walk6, bishop_walk7 ] {ai_walk(7);};
void() bishop_walk7 =[ $walk7, bishop_walk8 ] {ai_walk(8);};
void() bishop_walk8 =[ $walk8, bishop_walk9 ] {ai_walk(7);};
void() bishop_walk9 =[ $walk9, bishop_walk10 ] {ai_walk(5);};
void() bishop_walk10 =[ $walk10, bishop_walk11 ] {ai_walk(5);};
void() bishop_walk11 =[ $walk11, bishop_walk12 ] {ai_walk(6);};
void() bishop_walk12 =[ $walk12, bishop_walk1 ] {ai_walk(7);};
void() bishop_run1 =[ $run1, bishop_run2 ] {
//if (random() < 0.2)
// sound (self, CHAN_VOICE, "soldier/idle.wav", 1, ATTN_IDLE);
ai_run(14);};
void() bishop_run2 =[ $run2, bishop_run3 ] {ai_run(16);};
void() bishop_run3 =[ $run3, bishop_run4 ] {ai_run(12);};
void() bishop_run4 =[ $run4, bishop_run5 ] {ai_run(12);};
void() bishop_run5 =[ $run5, bishop_run6 ] {ai_run(10);};
void() bishop_run6 =[ $run6, bishop_run7 ] {ai_run(14);};
void() bishop_run7 =[ $run7, bishop_run8 ] {ai_run(12);};
void() bishop_run8 =[ $run8, bishop_run1 ] {ai_run(10);};
void() bishop_xatta1 =[ $xatta1, bishop_xatta2 ] {ai_face();};
void() bishop_xatta2 =[ $xatta2, bishop_xatta3 ] {ai_face();};
void() bishop_xatta3 =[ $xatta3, bishop_xatta4 ] {ai_face();};
void() bishop_xatta4 =[ $xatta4, bishop_xatta5 ] {ai_face();};
void() bishop_xatta5 =[ $xatta5, bishop_xatta6 ] {ai_face();};
void() bishop_xatta6 =[ $xatta6, bishop_xatta7 ] {bishop_specialfire();};
void() bishop_xatta7 =[ $xatta7, bishop_xatta8 ] {};
void() bishop_xatta8 =[ $xatta8, bishop_xatta9 ] {};
void() bishop_xatta9 =[ $xatta9, bishop_xatta10 ] {};
void() bishop_xatta10 =[ $xatta10, bishop_xatta11 ] {};
void() bishop_xatta11 =[ $xatta11, bishop_xatta12 ] {};
void() bishop_xatta12 =[ $xatta12, bishop_run1 ] {};
void() bishop_shoot1 =[ $shoot1, bishop_shoot2 ]
{
ai_face();
if ((self.last_special < (time - 5)) && (enemy_range >= RANGE_NEAR) && (enemy_range <= RANGE_MID) && (random() < 0.4)) {
self.last_special = time;
bishop_xatta1();
return;
}
};
void() bishop_shoot2 =[ $shoot2, bishop_shoot3 ] {ai_face();bishop_fire(6);};
void() bishop_shoot3 =[ $shoot3, bishop_shoot4 ] {ai_face();};
void() bishop_shoot4 =[ $shoot4, bishop_shoot5 ] {ai_face();};
void() bishop_shoot5 =[ $shoot5, bishop_shoot6 ] {ai_face();};
void() bishop_shoot6 =[ $shoot6, bishop_shoot7 ] {ai_face();bishop_fire(-6);};
void() bishop_shoot7 =[ $shoot7, bishop_shoot8 ] {ai_face();};
void() bishop_shoot8 =[ $shoot8, bishop_run1 ] {ai_face();SUB_CheckRefire (bishop_shoot1);};
void() bishop_pain1 =[ $pain1, bishop_pain2 ] {};
void() bishop_pain2 =[ $pain2, bishop_pain3 ] {};
void() bishop_pain3 =[ $pain3, bishop_pain4 ] {};
void() bishop_pain4 =[ $pain4, bishop_pain5 ] {};
void() bishop_pain5 =[ $pain5, bishop_pain6 ] {};
void() bishop_pain6 =[ $pain6, bishop_pain7 ] {};
void() bishop_pain7 =[ $pain7, bishop_pain8 ] {};
void() bishop_pain8 =[ $pain8, bishop_pain9 ] {};
void() bishop_pain9 =[ $pain9, bishop_run1 ] {};
void() bishop_paina1 =[ $paina1, bishop_paina2 ] {};
void() bishop_paina2 =[ $paina2, bishop_paina3 ] {};
void() bishop_paina3 =[ $paina3, bishop_paina4 ] {};
void() bishop_paina4 =[ $paina4, bishop_paina5 ] {};
void() bishop_paina5 =[ $paina5, bishop_paina6 ] {};
void() bishop_paina6 =[ $paina6, bishop_paina7 ] {};
void() bishop_paina7 =[ $paina7, bishop_paina8 ] {};
void() bishop_paina8 =[ $paina8, bishop_paina9 ] {};
void() bishop_paina9 =[ $paina9, bishop_paina10 ] {};
void() bishop_paina10 =[ $paina10, bishop_paina11 ] {};
void() bishop_paina11 =[ $paina11, bishop_paina12 ] {};
void() bishop_paina12 =[ $paina12, bishop_paina13 ] {};
void() bishop_paina13 =[ $paina13, bishop_paina14 ] {};
void() bishop_paina14 =[ $paina14, bishop_paina15 ] {};
void() bishop_paina15 =[ $paina15, bishop_paina16 ] {};
void() bishop_paina16 =[ $paina16, bishop_paina17 ] {};
void() bishop_paina17 =[ $paina17, bishop_paina18 ] {};
void() bishop_paina18 =[ $paina18, bishop_paina19 ] {};
void() bishop_paina19 =[ $paina19, bishop_paina20 ] {};
void() bishop_paina20 =[ $paina20, bishop_paina21 ] {};
void() bishop_paina21 =[ $paina21, bishop_paina22 ] {};
void() bishop_paina22 =[ $paina22, bishop_paina23 ] {};
void() bishop_paina23 =[ $paina23, bishop_run1 ] {};
void(entity attacker, float damage) bishop_pain =
{
local float r;
if (self.pain_finished > time)
return;
MalePainSound(1);
r = random();
if (r < 0.8)
{
self.pain_finished = time + 3;
bishop_pain1 ();
}
else
{
self.pain_finished = time + 6;
bishop_paina1 ();
}
};
void(float r_ofs) bishop_fire =
{
local vector vect;
local entity missile;
ai_face();
self.effects = self.effects | EF_MUZZLEFLASH;
makevectors(self.angles);
// allow for up/down aiming
vect = normalize(self.enemy.origin - self.origin);
v_forward_z = vect_z;
v_forward = normalize(v_forward);
sound (self, CHAN_WEAPON, "doors/airdoor2.wav", 1, ATTN_NORM);
launch_spike (self.origin + '0 0 8' + v_forward*14 + v_right * r_ofs, v_forward);
newmis.classname = "gambit_card";
setmodel (newmis, "progs/laser.mdl");
setsize(newmis, '0 0 0', '0 0 0');
};
void() BishopSpecialTouch =
{
if (other == self.owner)
return;
if (other.takedamage == DAMAGE_AIM)
{
spawn_touchblood (30);
T_Damage(other, self, self.owner, 20);
}
T_RadiusDamage(self, self.owner, 20, other);
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_EXPLOSION);
WriteCoord (MSG_BROADCAST, self.origin_x);
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
remove(self);
};
void() bishop_specialfire =
{
local vector vect;
local entity missile;
self.effects = self.effects | EF_MUZZLEFLASH;
sound (self, CHAN_WEAPON, "boss1/throw.wav", 1, ATTN_NORM);
vect = (self.enemy.origin - self.origin) + self.enemy.velocity * (vlen(self.enemy.origin - self.origin) / 750);
vect = normalize(vect);
launch_spike (self.origin + '0 0 8' + v_forward*14, vect);
newmis.velocity = newmis.velocity * 0.75;
newmis.classname = "bishop_special";
newmis.touch = BishopSpecialTouch;
newmis.avelocity_z = 300;
setmodel (newmis, "progs/bisblast.mdl");
setsize(newmis, '0 0 0', '0 0 0');
};
void() bishop_die1 =[ $death1, bishop_die2 ] {};
void() bishop_die2 =[ $death2, bishop_die3 ] {};
void() bishop_die3 =[ $death3, bishop_die4 ] {self.solid = SOLID_NOT;};
void() bishop_die4 =[ $death4, bishop_die5 ] {};
void() bishop_die5 =[ $death5, bishop_die6 ] {};
void() bishop_die6 =[ $death6, bishop_die7 ] {};
void() bishop_die7 =[ $death7, bishop_die8 ] {};
void() bishop_die8 =[ $death8, bishop_die9 ] {};
void() bishop_die9 =[ $death9, bishop_die10 ] {};
void() bishop_die10 =[ $death10, bishop_die11 ] {};
void() bishop_die11 =[ $death11, bishop_die12 ] {};
void() bishop_die12 =[ $death12, bishop_die13 ] {};
void() bishop_die13 =[ $death13, bishop_die14 ] {};
void() bishop_die14 =[ $death14, bishop_die15 ] {};
void() bishop_die15 =[ $death15, bishop_die16 ] {};
void() bishop_die16 =[ $death16, bishop_die16 ] {};
void() bishop_die =
{
// regular death
MaleDeathSound(1);
bishop_die1 ();
};
/*QUAKED monster_army (1 0 0) (-16 -16 -24) (16 16 40) Ambush
*/
void() monster_army =
{
remove(self);
};
void() xmen_bishop =
{
if (deathmatch)
{
remove(self);
return;
}
precache_model ("progs/bishop.mdl");
precache_model ("progs/laser.mdl");
precache_model ("progs/bisblast.mdl");
// Xmen Sounds: matched ID sounds
precache_sound ("boss1/throw.wav");
precache_sound2 ("doors/airdoor2.wav");
/*
// Old Soldier sounds
precache_sound ("soldier/death1.wav");
precache_sound ("soldier/idle.wav");
precache_sound ("soldier/pain1.wav");
precache_sound ("soldier/pain2.wav");
precache_sound ("soldier/sattck1.wav");
precache_sound ("soldier/sight1.wav");
*/
precache_sound ("player/udeath.wav"); // gib death
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
setmodel (self, "progs/bishop.mdl");
setsize (self, '-16 -16 -24', '16 16 40');
self.health = 180;
self.th_stand = bishop_stand1;
self.th_walk = bishop_walk1;
self.th_run = bishop_run1;
self.th_missile = bishop_shoot1;
self.th_pain = bishop_pain;
self.th_die = bishop_die;
walkmonster_start ();
};

308
cannon.c Normal file
View file

@ -0,0 +1,308 @@
/*==========================================================================
CANNONBALL
==========================================================================*/
$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
$frame stand10 stand11 stand12 stand13
$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10
$frame walk11 walk12
$frame run1 run2 run3 run4 run5 run6 run7 run8
$frame pain1 pain2 pain3 pain4 pain5 pain6
$frame paina1 paina2 paina3 paina4 paina5 paina6 paina7 paina8 paina9 paina10
$frame paina11 paina12 paina13 paina14 paina15 paina16 paina17 paina18 paina19 paina20
$frame paina21 paina22 paina23 paina24 paina25 paina26 paina27 paina28 paina29
$frame death1 death2 death3 death4 death5 death6 death7 death8 death9 death10
$frame death11 death12 death13 death14 death15 death16
$frame atta1 atta2 atta3 atta4 atta5 atta6 atta7 atta8 atta9
$frame xatta1 xatta2 xatta3 xatta4 xatta5
$frame xatta24 xatta25 xatta26 xatta27
void() cannon_stand1 = [ $stand1, cannon_stand2 ] {ai_stand();};
void() cannon_stand2 = [ $stand2, cannon_stand3 ] {ai_stand();};
void() cannon_stand3 = [ $stand3, cannon_stand4 ] {ai_stand();};
void() cannon_stand4 = [ $stand4, cannon_stand5 ] {ai_stand();};
void() cannon_stand5 = [ $stand5, cannon_stand6 ] {ai_stand();};
void() cannon_stand6 = [ $stand6, cannon_stand7 ] {ai_stand();};
void() cannon_stand7 = [ $stand7, cannon_stand8 ] {ai_stand();};
void() cannon_stand8 = [ $stand8, cannon_stand9 ] {ai_stand();};
void() cannon_stand9 = [ $stand9, cannon_stand10 ] {ai_stand();};
void() cannon_stand10 = [ $stand10, cannon_stand11 ] {ai_stand();};
void() cannon_stand11 = [ $stand11, cannon_stand12 ] {ai_stand();};
void() cannon_stand12 = [ $stand12, cannon_stand13 ] {ai_stand();};
void() cannon_stand13 = [ $stand13, cannon_stand1 ] {ai_stand();};
void() cannon_walk1 = [ $walk1, cannon_walk2 ] {ai_walk(6);};
void() cannon_walk2 = [ $walk2, cannon_walk3 ] {ai_walk(4);};
void() cannon_walk3 = [ $walk3, cannon_walk4 ] {ai_walk(4);};
void() cannon_walk4 = [ $walk4, cannon_walk5 ] {ai_walk(4);};
void() cannon_walk5 = [ $walk5, cannon_walk6 ] {ai_walk(6);};
void() cannon_walk6 = [ $walk6, cannon_walk7 ] {ai_walk(7);};
void() cannon_walk7 = [ $walk7, cannon_walk8 ] {ai_walk(7);};
void() cannon_walk8 = [ $walk8, cannon_walk9 ] {ai_walk(4);};
void() cannon_walk9 = [ $walk9, cannon_walk10 ] {ai_walk(4);};
void() cannon_walk10 = [ $walk10, cannon_walk11 ] {ai_walk(5);};
void() cannon_walk11 = [ $walk11, cannon_walk12 ] {ai_walk(6);};
void() cannon_walk12 = [ $walk12, cannon_walk1 ] {ai_walk(7);};
void() cannon_run1 = [ $run1, cannon_run2 ] {ai_run(16);};
void() cannon_run2 = [ $run2, cannon_run3 ] {ai_run(16);};
void() cannon_run3 = [ $run3, cannon_run4 ] {ai_run(16);};
void() cannon_run4 = [ $run4, cannon_run5 ] {ai_run(16);};
void() cannon_run5 = [ $run5, cannon_run6 ] {ai_run(16);};
void() cannon_run6 = [ $run6, cannon_run7 ] {ai_run(16);};
void() cannon_run7 = [ $run7, cannon_run8 ] {ai_run(16);};
void() cannon_run8 = [ $run8, cannon_run1 ] {ai_run(16);};
//============================================================================
void() cannon_pain1 = [ $pain1, cannon_pain2 ] {};
void() cannon_pain2 = [ $pain2, cannon_pain3 ] {};
void() cannon_pain3 = [ $pain3, cannon_pain4 ] {};
void() cannon_pain4 = [ $pain4, cannon_pain5 ] {};
void() cannon_pain5 = [ $pain5, cannon_pain6 ] {};
void() cannon_pain6 = [ $pain6, cannon_run1 ] {};
void() cannon_paina1 = [ $paina1, cannon_paina2 ] {};
void() cannon_paina2 = [ $paina2, cannon_paina3 ] {};
void() cannon_paina3 = [ $paina3, cannon_paina4 ] {};
void() cannon_paina4 = [ $paina4, cannon_paina5 ] {};
void() cannon_paina5 = [ $paina5, cannon_paina6 ] {};
void() cannon_paina6 = [ $paina6, cannon_paina7 ] {};
void() cannon_paina7 = [ $paina7, cannon_paina8 ] {};
void() cannon_paina8 = [ $paina8, cannon_paina9 ] {};
void() cannon_paina9 = [ $paina9, cannon_paina10 ] {};
void() cannon_paina10 = [ $paina10, cannon_paina11 ] {};
void() cannon_paina11 = [ $paina11, cannon_paina12 ] {};
void() cannon_paina12 = [ $paina12, cannon_paina13 ] {};
void() cannon_paina13 = [ $paina13, cannon_paina14 ] {sound(self, CHAN_BODY, "cannon/flyloop.wav", 1, ATTN_NORM);};
void() cannon_paina14 = [ $paina14, cannon_paina15 ] {};
void() cannon_paina15 = [ $paina15, cannon_paina16 ] {};
void() cannon_paina16 = [ $paina16, cannon_paina17 ] {};
void() cannon_paina17 = [ $paina17, cannon_paina18 ] {};
void() cannon_paina18 = [ $paina18, cannon_paina19 ] {};
void() cannon_paina19 = [ $paina19, cannon_paina20 ] {};
void() cannon_paina20 = [ $paina20, cannon_paina21 ] {};
void() cannon_paina21 = [ $paina21, cannon_paina22 ] {};
void() cannon_paina22 = [ $paina22, cannon_paina23 ] {};
void() cannon_paina23 = [ $paina23, cannon_paina24 ] {};
void() cannon_paina24 = [ $paina24, cannon_paina25 ] {};
void() cannon_paina25 = [ $paina25, cannon_paina26 ] {};
void() cannon_paina26 = [ $paina26, cannon_paina27 ] {};
void() cannon_paina27 = [ $paina27, cannon_paina28 ] {};
void() cannon_paina28 = [ $paina28, cannon_paina29 ] {};
void() cannon_paina29 = [ $paina29, cannon_run1 ] {};
void(entity attacker, float damage) CannonPain =
{
if (self.pain_finished > time)
return;
MalePainSound(2);
if (self.model != "progs/cannon1.mdl")
return;
if (self.health <= 0)
return;
if ((damage > 10) && (random() < 0.4)) {
self.pain_finished = time + 3;
cannon_paina1();
}
else {
self.pain_finished = time + 3;
cannon_pain1();
}
};
//============================================================================
void() cannon_death1 = [ $death1, cannon_death2 ] {};
void() cannon_death2 = [ $death2, cannon_death3 ] {};
void() cannon_death3 = [ $death3, cannon_death4 ] {self.solid = SOLID_NOT;};
void() cannon_death4 = [ $death4, cannon_death5 ] {};
void() cannon_death5 = [ $death5, cannon_death6 ] {};
void() cannon_death6 = [ $death6, cannon_death7 ] {};
void() cannon_death7 = [ $death7, cannon_death8 ] {};
void() cannon_death8 = [ $death8, cannon_death9 ] {};
void() cannon_death9 = [ $death9, cannon_death10 ] {};
void() cannon_death10 = [ $death10, cannon_death11 ] {};
void() cannon_death11 = [ $death11, cannon_death12 ] {};
void() cannon_death12 = [ $death12, cannon_death13 ] {};
void() cannon_death13 = [ $death13, cannon_death14 ] {};
void() cannon_death14 = [ $death14, cannon_death15 ] {};
void() cannon_death15 = [ $death15, cannon_death16 ] {};
void() cannon_death16 = [ $death16, cannon_death16 ] {if (self.angles_x != 0) AngelPitch();};
void() cannon_xatta24;
void() CannonDie =
{
if (self.model != "progs/cannon1.mdl") {
cannon_xatta24();
return;
}
MaleDeathSound(2);
cannon_death1();
};
//============================================================================
void() CannonPunch =
{
local vector vect;
if (!infront(self.enemy))
return;
if (vlen(self.enemy.origin - self.origin) > 64)
return;
T_Damage(self.enemy, self, self, 15);
self.enemy.punchangle_x = -15;
};
void() cannon_atta1 = [ $atta1, cannon_atta2 ] {ai_charge(4);};
void() cannon_atta2 = [ $atta2, cannon_atta3 ] {ai_charge(4);sound (self, CHAN_WEAPON, "generic/swing1.wav", 1, ATTN_NORM);};
void() cannon_atta3 = [ $atta3, cannon_atta4 ] {ai_charge(4);};
void() cannon_atta4 = [ $atta4, cannon_atta5 ] {ai_charge(4);CannonPunch();};
void() cannon_atta5 = [ $atta5, cannon_atta6 ] {};
void() cannon_atta6 = [ $atta6, cannon_atta7 ] {};
void() cannon_atta7 = [ $atta7, cannon_atta8 ] {};
void() cannon_atta8 = [ $atta8, cannon_atta9 ] {};
void() cannon_atta9 = [ $atta9, cannon_run1 ] {};
//============================================================================
void() xmen_cannonball;
void() cannon_xatta1 = [ $xatta1, cannon_xatta2 ] {sound(self, CHAN_ITEM, "cannon/takeoff.wav", 1, ATTN_NORM); self.flags = self.flags | FL_GODMODE;};
void() cannon_xatta2 = [ $xatta2, cannon_xatta3 ] {};
void() cannon_xatta3 = [ $xatta3, cannon_xatta4 ] {};
void() cannon_xatta4 = [ $xatta4, cannon_xatta5 ] {sound(self, CHAN_BODY, "cannon/flyloop.wav", 1, ATTN_NORM);};
void() cannon_xatta5 = [ $xatta5, cannon_xatta7 ] {self.flags = self.flags | FL_FLY; self.yaw_speed = 8;};
/* see cannon2.qc for flying attack frames */
void() cannon_xatta24 = [ $xatta24, cannon_xatta25 ]
{
setmodel(self, "progs/cannon1.mdl");
setsize (self, VEC_HULL_MIN, VEC_HULL_MAX);
setorigin(self, self.origin + '0 0 1');
self.flags = self.flags - FL_FLY;
self.flags = self.flags - (self.flags & FL_ONGROUND);
self.angles_x = 0;
self.angles_z = 0;
};
void() cannon_xatta25 = [ $xatta25, cannon_xatta26 ] {};
void() cannon_xatta26 = [ $xatta26, cannon_xatta27 ] {};
void() cannon_xatta27 = [ $xatta27, cannon_xatta27 ]
{
local entity new, oself;
if (self.origin == self.oldorigin) {
/*
new = spawn();
new.classname = "xmen_cannonball";
new.health = 99;
setorigin(new, self.origin);
new.angles = self.angles;
self.solid = SOLID_NOT;
oself = self;
self = new;
xmen_cannonball();
walkmonster_start_go();
self = oself;
new.last_special = self.last_special;
new.frame = self.frame;
new.health = self.health;
new.pausetime = 0;
new.enemy = new.goalentity = self.enemy;
remove(self);
self = new;
*/
setmodel (self, "progs/cannon1.mdl");
setsize (self, VEC_HULL_MIN, VEC_HULL_MAX);
self.flags = self.flags - (self.flags & FL_GODMODE);
self.th_run();
}
else {
self.oldorigin = self.origin;
}
};
//============================================================================
void() CannonCheckSpecial =
{
if (self.last_special < (time - 8))
cannon_xatta1();
};
void() xmen_cannonball =
{
if (deathmatch)
{
remove(self);
return;
}
if (self.health == 0) {
// Xmen Sounds: matched ID sounds
// precache_sound ("boss1/throw.wav");
precache_sound ("cannon/takeoff.wav");
precache_sound ("cannon/flyloop.wav");
precache_sound ("generic/swing1.wav");
precache_sound ("generic/punch2.wav");
precache_sound ("generic/crash1.wav");
precache_model ("progs/cannon1.mdl");
precache_model ("progs/cannon2.mdl");
}
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
setmodel (self, "progs/cannon1.mdl");
setsize (self, VEC_HULL_MIN, VEC_HULL_MAX);
self.health = 120 + cvar("skill")*10;
self.yaw_speed = 20;
self.th_stand = cannon_stand1;
self.th_walk = cannon_walk1;
self.th_run = cannon_run1;
self.th_die = CannonDie;
self.th_pain = CannonPain;
self.th_melee = cannon_atta1;
self.th_missile = CannonCheckSpecial;
self.think = walkmonster_start;
self.nextthink = time + 0.1 + random ()*0.1;
};

114
cannon2.c Normal file
View file

@ -0,0 +1,114 @@
// Cannonball's Special attack code
$frame xatta6 xatta7 xatta8 xatta9 xatta10 xatta11 xatta12 xatta13
$frame xatta14 xatta15 xatta16 xatta17 xatta18 xatta19 xatta20 xatta21
$frame xatta22 xatta23
$frame fly1 fly2 fly3
void() cannon_xatta16;
void() cannon_xatta18;
void() CannonFlyTouch =
{
self.velocity = '0 0 0';
if (other != self.enemy) { // abort attack
sound(self, CHAN_BODY, "generic/crash1.wav", 1, ATTN_NORM);
self.x_flags = self.x_flags | X_CANNONFLYABORT;
// cannon_xatta19();
return;
}
cannon_xatta16();
};
void() CannonFlyThink =
{
if (self.x_flags & X_CANNONFLYABORT) {
cannon_xatta18();
return;
}
ai_face();
if (!ai_forward(20)) {
if (self.oldorigin != '0 0 0')
setorigin(self, self.oldorigin);
other = world;
if (infront(self.enemy) && (vlen(self.enemy.origin - self.origin) < 80))
other = self.enemy;
CannonFlyTouch();
}
else {
self.oldorigin = self.origin;
}
if (self.last_flame_sound < (time - 0.75)) {
if (self.last_weapon_channel != CHAN_WEAPON) {
sound (self, CHAN_WEAPON, "cannon/flyloop.wav", 1, ATTN_NORM);
self.last_weapon_channel = CHAN_WEAPON;
} else {
sound (self, CHAN_BODY, "cannon/flyloop.wav", 1, ATTN_NORM);
self.last_weapon_channel = CHAN_BODY;
}
self.last_flame_sound = time;
}
ai_face();
self.nextthink = time + 0.05;
};
void() cannon_xatta7 = [ $xatta7, cannon_xatta8 ]
{
setmodel(self, "progs/cannon2.mdl");
self.flags = self.flags | FL_GODMODE;
ai_forward(3);
};
void() cannon_xatta8 = [ $xatta8, cannon_xatta9 ] {ai_forward(6); ai_face();};
void() cannon_xatta9 = [ $xatta9, cannon_xatta10 ] {ai_forward(9); ai_face();};
void() cannon_xatta10 = [ $xatta10, cannon_xatta11 ] {ai_forward(12); ai_face();};
void() cannon_xatta11 = [ $xatta11, cannon_xatta12 ] {ai_forward(15); ai_face();};
void() cannon_xatta12 = [ $xatta12, cannon_xatta13 ]
{
ai_forward(18);
self.oldorigin = '0 0 0';
self.x_flags = self.x_flags - (self.x_flags & X_CANNONFLYABORT);
};
void() cannon_xatta13 = [ $xatta13, cannon_xatta14 ] {CannonFlyThink();};
void() cannon_xatta14 = [ $xatta14, cannon_xatta15 ] {CannonFlyThink();};
void() cannon_xatta15 = [ $xatta15, cannon_xatta13 ] {CannonFlyThink();};
void() cannon_xatta16 = [ $xatta16, cannon_xatta17 ] {ai_forward(15); sound (self, CHAN_ITEM, "generic/swing1.wav", 1, ATTN_NORM);};
void() cannon_xatta17 = [ $xatta17, cannon_xatta18 ] {ai_forward(10);};
void() cannon_xatta18 = [ $xatta18, cannon_xatta19 ]
{
local vector vect;
if (self.x_flags & X_CANNONFLYABORT) {
self.x_flags = self.x_flags - X_CANNONFLYABORT;
return;
}
self.last_special = time;
// do some damage
T_Damage(self.enemy, self, self, 30);
sound (self, CHAN_WEAPON, "generic/punch2.wav", 1, ATTN_NORM);
vect = normalize(self.enemy.origin - self.origin);
self.enemy.velocity = vect * 300;
self.enemy.velocity_z = 300;
self.enemy.punchangle_x = -15;
};
void() cannon_xatta19 = [ $xatta19, cannon_xatta20 ] {self.angles_x = 0; self.angles_z = 0;};
void() cannon_xatta20 = [ $xatta20, cannon_xatta21 ] {};
void() cannon_xatta21 = [ $xatta21, cannon_xatta22 ] {};
void() cannon_xatta22 = [ $xatta22, cannon_xatta23 ] {};
void() cannon_xatta23 = [ $xatta23, cannon_xatta24 ] {};

419
cyclops.c Normal file
View file

@ -0,0 +1,419 @@
/*
==============================================================================
CYCLOPS
==============================================================================
*/
$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
$frame stand10 stand11 stand12 stand13
$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10 walk11 walk12
$frame run1 run2 run3 run4 run5 run6 run7 run8 run9 run10
$frame pain1 pain2 pain3 pain4 pain5 pain6
$frame paina1 paina2 paina3 paina4 paina5 paina6 paina7 paina8 paina9 paina10
$frame paina11 paina12 paina13 paina14 paina15 paina16 paina17 paina18 paina19 paina20
$frame paina21 paina22 paina23 paina24 paina25 paina26 paina27 paina28 paina29 paina30
$frame death1 death2 death3 death4 death5 death6 death7 death8 death9 death10
$frame death11 death12 death13 death14 death15 death16 death17 death18 death19 death20
$frame deata1 deata2 deata3 deata4 deata5 deata6 deata7 deata8 deata9 deata10
$frame deata11 deata12 deata13 deata14 deata15 deata16 deata17 deata18 deata19 deata20
$frame deata21 deata22 deata23 deata24 deata25 deata26 deata27 deata28 deata29 deata30
$frame deata31 deata32 deata33 deata34 deata35 deata36
$frame attack1 attack2 attack3 attack4 attack5 attack6 attack7 attack8
$frame attack9 attack10 attack11 attack12
/*
void() Cyclops_Laser_Touch =
{
local vector org;
if (other == self.owner)
return; // don't explode on owner
if (pointcontents(self.origin) == CONTENT_SKY)
{
remove(self);
return;
}
sound (self, CHAN_WEAPON, "enforcer/enfstop.wav", 1, ATTN_STATIC);
org = self.origin - 8*normalize(self.velocity);
if (other.health)
{
SpawnBlood (org, self.velocity*0.2, 15);
T_Damage (other, self, self.owner, 15);
}
else
{
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_GUNSHOT);
WriteCoord (MSG_BROADCAST, org_x);
WriteCoord (MSG_BROADCAST, org_y);
WriteCoord (MSG_BROADCAST, org_z);
}
remove(self);
};
void(vector org, vector vec) LaunchLaser =
{
local vector vec;
if (self.classname == "monster_enforcer")
sound (self, CHAN_WEAPON, "enforcer/enfire.wav", 1, ATTN_NORM);
vec = normalize(vec);
newmis = spawn();
newmis.owner = self;
newmis.movetype = MOVETYPE_FLY;
newmis.solid = SOLID_BBOX;
newmis.effects = EF_DIMLIGHT;
setmodel (newmis, "progs/claser1.mdl");
setsize (newmis, '0 0 0', '0 0 0');
setorigin (newmis, org);
newmis.velocity = vec * 600;
newmis.angles = vectoangles(newmis.velocity);
newmis.nextthink = time + 5;
newmis.think = SUB_Remove;
newmis.touch = Cyclops_Laser_Touch;
};
*/
void() LaserTouch =
{
if (other == self.owner)
return;
if (other.takedamage == DAMAGE_AIM)
{
spawn_touchblood (10);
T_Damage(other, self, self.owner, 10);
remove(self);
return;
}
self.last_touch = time;
sound (self, CHAN_WEAPON, "doors/airdoor2.wav", 1, ATTN_NORM);
if (self.velocity == '0 0 0')
remove(self);
};
void(vector org, vector dir) spawn_laser =
{
local entity missile, mpuff;
local vector vect;
missile = spawn ();
missile.owner = self;
missile.movetype = MOVETYPE_BOUNCE;
missile.solid = SOLID_BBOX;
missile.classname = "laser";
// set missile speed
vect = normalize(dir);
missile.velocity = ProjectVelocity(1000, '0 0 -16');
missile.angles = vectoangles(missile.velocity);
missile.old_velocity = missile.velocity;
missile.touch = LaserTouch;
// set missile duration
// missile.last_idle = time;
missile.last_touch = 0;
missile.oldorigin = missile.origin;
missile.nextthink = time + 2;
// missile.think = GrenadeExplode;
missile.think = SUB_Remove;
setmodel (missile, "progs/claser1.mdl");
setsize (missile, '0 0 0', '0 0 0');
setorigin (missile, org);
};
void() enforcer_fire =
{
local vector org;
self.effects = self.effects | EF_MUZZLEFLASH;
makevectors (self.angles);
sound (self, CHAN_VOICE, "items/inv1.wav", 1, ATTN_NORM);
org = self.origin + v_forward * 1 + '0 0 24';
spawn_laser(org, self.enemy.origin - self.origin);
};
//============================================================================
void() enf_stand1 =[ $stand1, enf_stand2 ] {ai_stand();};
void() enf_stand2 =[ $stand2, enf_stand3 ] {ai_stand();};
void() enf_stand3 =[ $stand3, enf_stand4 ] {ai_stand();};
void() enf_stand4 =[ $stand4, enf_stand5 ] {ai_stand();};
void() enf_stand5 =[ $stand5, enf_stand6 ] {ai_stand();};
void() enf_stand6 =[ $stand6, enf_stand7 ] {ai_stand();};
void() enf_stand7 =[ $stand7, enf_stand8 ] {ai_stand();};
void() enf_stand8 =[ $stand8, enf_stand9 ] {ai_stand();};
void() enf_stand9 =[ $stand9, enf_stand10 ] {ai_stand();};
void() enf_stand10 =[ $stand10, enf_stand11 ] {ai_stand();};
void() enf_stand11 =[ $stand11, enf_stand12 ] {ai_stand();};
void() enf_stand12 =[ $stand12, enf_stand13 ] {ai_stand();};
void() enf_stand13 =[ $stand13, enf_stand1 ] {ai_stand();};
void() enf_walk1 =[ $walk1 , enf_walk2 ] {
//if (random() < 0.2)
// sound (self, CHAN_VOICE, "enforcer/idle1.wav", 1, ATTN_IDLE);
ai_walk(6);};
void() enf_walk2 =[ $walk2 , enf_walk3 ] {ai_walk(8);};
void() enf_walk3 =[ $walk3 , enf_walk4 ] {ai_walk(7);};
void() enf_walk4 =[ $walk4 , enf_walk5 ] {ai_walk(7);};
void() enf_walk5 =[ $walk5 , enf_walk6 ] {ai_walk(7);};
void() enf_walk6 =[ $walk6 , enf_walk7 ] {ai_walk(6);};
void() enf_walk7 =[ $walk7 , enf_walk8 ] {ai_walk(4);};
void() enf_walk8 =[ $walk8 , enf_walk9 ] {ai_walk(7);};
void() enf_walk9 =[ $walk9 , enf_walk10 ] {ai_walk(7);};
void() enf_walk10 =[ $walk10, enf_walk11 ] {ai_walk(6);};
void() enf_walk11 =[ $walk11, enf_walk12 ] {ai_walk(6);};
void() enf_walk12 =[ $walk12, enf_walk1 ] {ai_walk(7);};
void() enf_run1 =[ $run1 , enf_run2 ] {
//if (random() < 0.2)
// sound (self, CHAN_VOICE, "enforcer/idle1.wav", 1, ATTN_IDLE);
ai_run(12);};
void() enf_run2 =[ $run2 , enf_run3 ] {ai_run(12);};
void() enf_run3 =[ $run3 , enf_run4 ] {ai_run(11);};
void() enf_run4 =[ $run4 , enf_run5 ] {ai_run(14);};
void() enf_run5 =[ $run5 , enf_run6 ] {ai_run(13);};
void() enf_run6 =[ $run6 , enf_run7 ] {ai_run(12);};
void() enf_run7 =[ $run7 , enf_run8 ] {ai_run(14);};
void() enf_run8 =[ $run8 , enf_run9 ] {ai_run(16);};
void() enf_run9 =[ $run9 , enf_run10 ] {ai_run(13);};
void() enf_run10 =[ $run10 , enf_run1 ] {ai_run(14);};
void() enf_pain1 =[ $pain1, enf_pain2 ] {};
void() enf_pain2 =[ $pain2, enf_pain3 ] {};
void() enf_pain3 =[ $pain3, enf_pain4 ] {};
void() enf_pain4 =[ $pain4, enf_pain5 ] {};
void() enf_pain5 =[ $pain5, enf_pain6 ] {};
void() enf_pain6 =[ $pain6, enf_run1 ] {};
void() enf_paina1 =[ $paina1, enf_paina2 ] {self.nextthink = time + 0.05;};
void() enf_paina2 =[ $paina2, enf_paina3 ] {self.nextthink = time + 0.05;};
void() enf_paina3 =[ $paina3, enf_paina4 ] {self.nextthink = time + 0.05;};
void() enf_paina4 =[ $paina4, enf_paina5 ] {self.nextthink = time + 0.05;};
void() enf_paina5 =[ $paina5, enf_paina6 ] {self.nextthink = time + 0.05;};
void() enf_paina6 =[ $paina6, enf_paina7 ] {self.nextthink = time + 0.05;};
void() enf_paina7 =[ $paina7, enf_paina8 ] {self.nextthink = time + 0.05;};
void() enf_paina8 =[ $paina8, enf_paina9 ] {self.nextthink = time + 0.05;};
void() enf_paina9 =[ $paina9, enf_paina10 ] {self.nextthink = time + 0.05;};
void() enf_paina10 =[ $paina10, enf_paina11 ] {self.nextthink = time + 0.05;};
void() enf_paina11 =[ $paina11, enf_paina12 ] {self.nextthink = time + 0.05;};
void() enf_paina12 =[ $paina12, enf_paina13 ] {self.nextthink = time + 0.05;};
void() enf_paina13 =[ $paina13, enf_paina14 ] {self.nextthink = time + 0.05;};
void() enf_paina14 =[ $paina14, enf_paina15 ] {self.nextthink = time + 0.05;};
void() enf_paina15 =[ $paina15, enf_paina16 ] {self.nextthink = time + 0.05;};
void() enf_paina16 =[ $paina16, enf_paina17 ] {self.nextthink = time + 0.05;};
void() enf_paina17 =[ $paina17, enf_paina18 ] {self.nextthink = time + 0.05;};
void() enf_paina18 =[ $paina18, enf_paina19 ] {self.nextthink = time + 0.05;};
void() enf_paina19 =[ $paina19, enf_paina20 ] {self.nextthink = time + 0.05;};
void() enf_paina20 =[ $paina20, enf_paina21 ] {self.nextthink = time + 0.05;};
void() enf_paina21 =[ $paina21, enf_paina22 ] {self.nextthink = time + 0.05;};
void() enf_paina22 =[ $paina22, enf_paina23 ] {self.nextthink = time + 0.05;};
void() enf_paina23 =[ $paina23, enf_paina24 ] {self.nextthink = time + 0.05;};
void() enf_paina24 =[ $paina24, enf_paina25 ] {self.nextthink = time + 0.05;};
void() enf_paina25 =[ $paina25, enf_paina26 ] {self.nextthink = time + 0.05;};
void() enf_paina26 =[ $paina26, enf_paina27 ] {self.nextthink = time + 0.05;};
void() enf_paina27 =[ $paina27, enf_paina28 ] {self.nextthink = time + 0.05;};
void() enf_paina28 =[ $paina28, enf_paina29 ] {self.nextthink = time + 0.05;};
void() enf_paina29 =[ $paina29, enf_paina30 ] {self.nextthink = time + 0.05;};
void() enf_paina30 =[ $paina30, enf_run1 ] {self.nextthink = time + 0.05;};
void(entity attacker, float damage) enf_pain;
void() enf_atk1 =[ $attack1, enf_atk2 ] {ai_face(); self.start_attack_health = self.health;};
void() enf_atk2 =[ $attack2, enf_atk3 ] {ai_face();};
void() enf_atk3 =[ $attack3, enf_atk4 ] {ai_face();};
void() enf_atk4 =[ $attack4, enf_atk5 ] {ai_face();};
void() enf_atk5 =[ $attack5, enf_atk6 ] {ai_face();};
void() enf_atk6 =[ $attack6, enf_atk7 ] {ai_face();};
void() enf_atk7 =[ $attack7, enf_atk8 ] {ai_face();
if (self.health < self.start_attack_health) {
enf_pain(self.enemy, self.start_attack_health - self.health);
}
};
void() enf_atk8 =[ $attack8, enf_atk9 ] {ai_face();};
void() enf_atk9 =[ $attack9, enf_atk10 ] {enforcer_fire();};
void() enf_atk10 =[ $attack10, enf_atk11 ] {ai_face();};
void() enf_atk11 =[ $attack11, enf_atk12 ] {ai_face();};
void() enf_atk12 =[ $attack12, enf_run1 ] {ai_face();
SUB_CheckRefire (enf_atk1);
};
void(entity attacker, float damage) enf_pain =
{
local float r;
/*
bprint("enforcer pain: ");
bprint(ftos(damage));
bprint("\n");
*/
r = random ();
if (self.pain_finished > time)
return;
if (random()*200 > damage)
return; // didn't flinch
if ((random()*10 < 8) || ((damage > 50) && (random() < 0.5)))
{
MalePainSound(2);
self.pain_finished = time + 1;
enf_paina1 ();
}
else
{
MalePainSound(2);
self.pain_finished = time + 4;
enf_paina1 ();
}
};
//============================================================================
void() enf_die1 =[ $death1, enf_die2 ] {};
void() enf_die2 =[ $death2, enf_die3 ] {};
void() enf_die3 =[ $death3, enf_die4 ] {self.solid = SOLID_NOT;self.ammo_cells = 5;};
void() enf_die4 =[ $death4, enf_die5 ] {};
void() enf_die5 =[ $death5, enf_die6 ] {};
void() enf_die6 =[ $death6, enf_die7 ] {};
void() enf_die7 =[ $death7, enf_die8 ] {};
void() enf_die8 =[ $death8, enf_die9 ] {};
void() enf_die9 =[ $death9, enf_die10 ] {};
void() enf_die10 =[ $death10, enf_die11 ] {};
void() enf_die11 =[ $death11, enf_die12 ] {};
void() enf_die12 =[ $death12, enf_die13 ] {};
void() enf_die13 =[ $death13, enf_die14 ] {};
void() enf_die14 =[ $death14, enf_die15 ] {};
void() enf_die15 =[ $death15, enf_die16 ] {};
void() enf_die16 =[ $death16, enf_die17 ] {};
void() enf_die17 =[ $death17, enf_die18 ] {};
void() enf_die18 =[ $death18, enf_die19 ] {};
void() enf_die19 =[ $death19, enf_die20 ] {};
void() enf_die20 =[ $death20, enf_die20 ] {};
void() enf_fdie1 =[ $deata1, enf_fdie2 ] {};
void() enf_fdie2 =[ $deata2, enf_fdie3 ] {};
void() enf_fdie3 =[ $deata3, enf_fdie4 ]
{self.solid = SOLID_NOT;self.ammo_cells = 5;};
void() enf_fdie4 =[ $deata4, enf_fdie5 ] {};
void() enf_fdie5 =[ $deata5, enf_fdie6 ] {};
void() enf_fdie6 =[ $deata6, enf_fdie7 ] {};
void() enf_fdie7 =[ $deata7, enf_fdie8 ] {};
void() enf_fdie8 =[ $deata8, enf_fdie9 ] {};
void() enf_fdie9 =[ $deata9, enf_fdie10 ] {};
void() enf_fdie10 =[ $deata10, enf_fdie11 ] {};
void() enf_fdie11 =[ $deata11, enf_fdie12 ] {};
void() enf_fdie12 =[ $deata12, enf_fdie13 ] {};
void() enf_fdie13 =[ $deata13, enf_fdie14 ] {};
void() enf_fdie14 =[ $deata14, enf_fdie15 ] {};
void() enf_fdie15 =[ $deata15, enf_fdie16 ] {};
void() enf_fdie16 =[ $deata16, enf_fdie17 ] {};
void() enf_fdie17 =[ $deata17, enf_fdie18 ] {};
void() enf_fdie18 =[ $deata18, enf_fdie19 ] {};
void() enf_fdie19 =[ $deata19, enf_fdie20 ] {};
void() enf_fdie20 =[ $deata20, enf_fdie21 ] {};
void() enf_fdie21 =[ $deata21, enf_fdie22 ] {};
void() enf_fdie22 =[ $deata22, enf_fdie23 ] {};
void() enf_fdie23 =[ $deata23, enf_fdie24 ] {};
void() enf_fdie24 =[ $deata24, enf_fdie25 ] {};
void() enf_fdie25 =[ $deata25, enf_fdie26 ] {};
void() enf_fdie26 =[ $deata26, enf_fdie27 ] {};
void() enf_fdie27 =[ $deata27, enf_fdie28 ] {};
void() enf_fdie28 =[ $deata28, enf_fdie29 ] {};
void() enf_fdie29 =[ $deata29, enf_fdie30 ] {};
void() enf_fdie30 =[ $deata30, enf_fdie31 ] {};
void() enf_fdie31 =[ $deata31, enf_fdie32 ] {};
void() enf_fdie32 =[ $deata32, enf_fdie33 ] {};
void() enf_fdie33 =[ $deata33, enf_fdie34 ] {};
void() enf_fdie34 =[ $deata34, enf_fdie35 ] {};
void() enf_fdie35 =[ $deata35, enf_fdie36 ] {};
void() enf_fdie36 =[ $deata36, enf_fdie36 ] {};
void() enf_die =
{
// regular death
MaleDeathSound(2);
if (random() >= 0.4)
enf_die1 ();
else
enf_fdie1 ();
};
/*QUAKED monster_enforcer (1 0 0) (-16 -16 -24) (16 16 40) Ambush
*/
void() monster_enforcer =
{
remove(self);
};
void() xmen_cyclops =
{
if (deathmatch)
{
remove(self);
return;
}
precache_model2 ("progs/cyclops.mdl");
precache_model2 ("progs/claser1.mdl");
// XMen matched ID sounds
precache_sound2 ("items/inv1.wav");
precache_sound2 ("doors/airdoor2.wav");
// Unmatched sounds
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
setmodel (self, "progs/cyclops.mdl");
setsize (self, '-16 -16 -24', '16 16 40');
self.health = 90 + cvar("skill")*10;
self.th_stand = enf_stand1;
self.th_walk = enf_walk1;
self.th_run = enf_run1;
self.th_pain = enf_pain;
self.th_die = enf_die;
self.th_missile = enf_atk1;
walkmonster_start();
};

456
gambit.c Normal file
View file

@ -0,0 +1,456 @@
/*
==============================================================================
Gambit
==============================================================================
*/
$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
$frame stand10 stand11 stand12 stand13
$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10
$frame walk11 walk12
$frame run1 run2 run3 run4 run5 run6 run7 run8
$frame pain1 pain2 pain3 pain4 pain5 pain6
$frame paina1 paina2 paina3 paina4 paina5 paina6 paina7 paina8 paina9 paina10
$frame paina11 paina12 paina13 paina14 paina15 paina16 paina17 paina18 paina19 paina20
$frame paina21 paina22 paina23 paina24 paina25 paina26
$frame death1 death2 death3 death4 death5 death6 death7 death8 death9 death10
$frame death11 death12 death13 death14 death15 death16 death17 death18
$frame jump1 jump2 jump3 jump4 jump5 jump6 jump7 jump8 jump9 jump10
$frame jump11 jump12 jump13 jump14
$frame satta1 satta2 satta3 satta4 satta5 satta6 satta7 satta8
$frame satta9 satta10 satta11 satta12
$frame xatta1 xatta2 xatta3 xatta4 xatta5 xatta6 xatta7 xatta8 xatta9 xatta10
$frame xatta11 xatta12 xatta13 xatta14
$frame xattb1 xattb2 xattb3 xattb4 xattb5 xattb6 xattb7 xattb8 xattb9 xattb10
$frame xattb11 xattb12
void() gambit_stand1 =[ $stand1, gambit_stand2 ] {ai_stand();};
void() gambit_stand2 =[ $stand2, gambit_stand3 ] {ai_stand();};
void() gambit_stand3 =[ $stand3, gambit_stand4 ] {ai_stand();};
void() gambit_stand4 =[ $stand4, gambit_stand5 ] {ai_stand();};
void() gambit_stand5 =[ $stand5, gambit_stand6 ] {ai_stand();};
void() gambit_stand6 =[ $stand6, gambit_stand7 ] {ai_stand();};
void() gambit_stand7 =[ $stand7, gambit_stand8 ] {ai_stand();};
void() gambit_stand8 =[ $stand8, gambit_stand9 ] {ai_stand();};
void() gambit_stand9 =[ $stand9, gambit_stand10 ] {ai_stand();};
void() gambit_stand10 =[ $stand10, gambit_stand11 ] {ai_stand();};
void() gambit_stand11 =[ $stand11, gambit_stand12 ] {ai_stand();};
void() gambit_stand12 =[ $stand12, gambit_stand13 ] {ai_stand();};
void() gambit_stand13 =[ $stand13, gambit_stand1 ] {ai_stand();};
//===========================================================================
void() gambit_walk1 =[ $walk1, gambit_walk2 ] {ai_walk(5);};
void() gambit_walk2 =[ $walk2, gambit_walk3 ] {ai_walk(5);};
void() gambit_walk3 =[ $walk3, gambit_walk4 ] {ai_walk(4);};
void() gambit_walk4 =[ $walk4, gambit_walk5 ] {ai_walk(4);};
void() gambit_walk5 =[ $walk5, gambit_walk6 ] {ai_walk(4);};
void() gambit_walk6 =[ $walk6, gambit_walk7 ] {ai_walk(5);};
void() gambit_walk7 =[ $walk7, gambit_walk8 ] {ai_walk(6);};
void() gambit_walk8 =[ $walk8, gambit_walk9 ] {ai_walk(6);};
void() gambit_walk9 =[ $walk9, gambit_walk10 ] {ai_walk(4);};
void() gambit_walk10 =[ $walk10, gambit_walk11 ] {ai_walk(4);};
void() gambit_walk11 =[ $walk11, gambit_walk12 ] {ai_walk(4);};
void() gambit_walk12 =[ $walk12, gambit_walk1 ] {ai_walk(4);};
//===========================================================================
void() gambit_run1 =[ $run1, gambit_run2 ] {ai_run (20);};
void() gambit_run2 =[ $run2, gambit_run3 ] {ai_run(25);};
void() gambit_run3 =[ $run3, gambit_run4 ] {ai_run(18);};
void() gambit_run4 =[ $run4, gambit_run5 ] {ai_run(16);};
void() gambit_run5 =[ $run5, gambit_run6 ] {ai_run(14);};
void() gambit_run6 =[ $run6, gambit_run7 ] {ai_run(25);};
void() gambit_run7 =[ $run7, gambit_run8 ] {ai_run(21);};
void() gambit_run8 =[ $run8, gambit_run1 ] {ai_run(13);};
void() gambit_jump1;
void() gambit_jump12;
void() GambitJumpTouch =
{
if (!checkbottom(self))
{
if (self.flags & FL_ONGROUND)
{ // jump randomly to not get hung up
self.touch = SUB_Null;
self.think = gambit_jump1;
self.nextthink = time + 0.1;
}
return; // not on ground yet
}
self.touch = SUB_Null;
self.think = gambit_jump12;
self.nextthink = time + 0.1;
};
void() gambit_jump1 =[ $jump1, gambit_jump2 ]
{
makevectors(self.angles);
self.velocity = v_forward * 300;
self.velocity_z = 200;
self.flags = self.flags - (self.flags & FL_ONGROUND);
setorigin(self, self.origin + '0 0 1');
self.touch = GambitJumpTouch;
self.nextthink = time + 0.05;
};
void() gambit_jump2 =[ $jump2, gambit_jump3 ] {self.nextthink = time + 0.05;};
void() gambit_jump3 =[ $jump3, gambit_jump4 ] {self.nextthink = time + 0.05;};
void() gambit_jump4 =[ $jump4, gambit_jump5 ] {self.nextthink = time + 0.05;};
void() gambit_jump5 =[ $jump5, gambit_jump6 ] {self.nextthink = time + 0.05;};
void() gambit_jump6 =[ $jump6, gambit_jump7 ] {self.nextthink = time + 0.05;};
void() gambit_jump7 =[ $jump7, gambit_jump8 ] {self.nextthink = time + 0.05;};
void() gambit_jump8 =[ $jump8, gambit_jump9 ] {self.nextthink = time + 0.05;};
void() gambit_jump9 =[ $jump9, gambit_jump10 ] {self.nextthink = time + 0.05;};
void() gambit_jump10 =[ $jump10, gambit_jump11 ] {self.nextthink = time + 0.05;};
void() gambit_jump11 =[ $jump11, gambit_jump11 ] {self.nextthink = time + 0.05;}; // stay on this frame until landing
void() gambit_jump12 =[ $jump12, gambit_jump13 ] {ai_forward(10);};
void() gambit_jump13 =[ $jump13, gambit_jump14 ] {ai_forward(6);};
void() gambit_jump14 =[ $jump14, gambit_run1 ] {};
//============================================================================
void() gambit_pain1 =[ $pain1, gambit_pain2 ] {};
void() gambit_pain2 =[ $pain2, gambit_pain3 ] {};
void() gambit_pain3 =[ $pain3, gambit_pain4 ] {};
void() gambit_pain4 =[ $pain4, gambit_pain5 ] {};
void() gambit_pain5 =[ $pain5, gambit_pain6 ] {};
void() gambit_pain6 =[ $pain6, gambit_run1 ] {};
void() gambit_paina1 =[ $paina1, gambit_paina2 ] {};
void() gambit_paina2 =[ $paina2, gambit_paina3 ] {};
void() gambit_paina3 =[ $paina3, gambit_paina4 ] {};
void() gambit_paina4 =[ $paina4, gambit_paina5 ] {};
void() gambit_paina5 =[ $paina5, gambit_paina6 ] {};
void() gambit_paina6 =[ $paina6, gambit_paina7 ] {};
void() gambit_paina7 =[ $paina7, gambit_paina8 ] {};
void() gambit_paina8 =[ $paina8, gambit_paina9 ] {};
void() gambit_paina9 =[ $paina9, gambit_paina10 ] {};
void() gambit_paina10 =[ $paina10, gambit_paina11 ] {};
void() gambit_paina11 =[ $paina11, gambit_paina12 ] {};
void() gambit_paina12 =[ $paina12, gambit_paina13 ] {};
void() gambit_paina13 =[ $paina13, gambit_paina14 ] {};
void() gambit_paina14 =[ $paina14, gambit_paina15 ] {};
void() gambit_paina15 =[ $paina15, gambit_paina16 ] {};
void() gambit_paina16 =[ $paina16, gambit_paina17 ] {};
void() gambit_paina17 =[ $paina17, gambit_paina18 ] {};
void() gambit_paina18 =[ $paina18, gambit_paina19 ] {};
void() gambit_paina19 =[ $paina19, gambit_paina20 ] {};
void() gambit_paina20 =[ $paina20, gambit_paina21 ] {};
void() gambit_paina21 =[ $paina21, gambit_paina22 ] {};
void() gambit_paina22 =[ $paina22, gambit_paina23 ] {};
void() gambit_paina23 =[ $paina23, gambit_paina24 ] {};
void() gambit_paina24 =[ $paina24, gambit_paina25 ] {};
void() gambit_paina25 =[ $paina25, gambit_paina26 ] {};
void() gambit_paina26 =[ $paina26, gambit_run1 ] {};
//============================================================================
void() gambit_die1 =[ $death1, gambit_die2 ] {};
void() gambit_die2 =[ $death2, gambit_die3 ] {};
void() gambit_die3 =[ $death3, gambit_die4 ] {self.solid = SOLID_NOT;};
void() gambit_die4 =[ $death4, gambit_die5 ] {};
void() gambit_die5 =[ $death5, gambit_die6 ] {};
void() gambit_die6 =[ $death6, gambit_die7 ] {};
void() gambit_die7 =[ $death7, gambit_die8 ] {};
void() gambit_die8 =[ $death8, gambit_die9 ] {};
void() gambit_die9 =[ $death9, gambit_die10 ] {};
void() gambit_die10 =[ $death10, gambit_die11 ] {};
void() gambit_die11 =[ $death11, gambit_die12 ] {};
void() gambit_die12 =[ $death12, gambit_die13 ] {};
void() gambit_die13 =[ $death13, gambit_die14 ] {};
void() gambit_die14 =[ $death14, gambit_die15 ] {};
void() gambit_die15 =[ $death15, gambit_die16 ] {};
void() gambit_die16 =[ $death16, gambit_die17 ] {};
void() gambit_die17 =[ $death17, gambit_die18 ] {};
void() gambit_die18 =[ $death18, gambit_die18 ] {};
void() gambit_die =
{
MaleDeathSound(2);
gambit_die1 ();
};
//============================================================================
void(entity attacker, float damage) gambit_pain =
{
if (self.pain_finished > time)
return;
MalePainSound(2);
if (time - self.pain_finished > 8)
{ // always go into pain frame if it has been a while
gambit_pain1 ();
self.pain_finished = time + 3;
return;
}
if (random() < 0.75) {
self.pain_finished = time + 3;
gambit_pain1 ();
}
else {
self.pain_finished = time + 5;
gambit_paina1 ();
}
};
//============================================================================
void() GambitStrike =
{
local vector vect;
local float damg;
if (vlen(self.enemy.origin - self.origin) > 64)
return;
if (!infront(self.enemy))
return;
// hurt enemy
damg = 15 + random() * 5;
T_Damage(self.enemy, self, self, damg);
};
void() gambit_satta1 =[ $satta1, gambit_satta2 ] {ai_charge(4);};
void() gambit_satta2 =[ $satta2, gambit_satta3 ] {ai_charge(8);};
void() gambit_satta3 =[ $satta3, gambit_satta4 ] {ai_charge(8);};
void() gambit_satta4 =[ $satta4, gambit_satta5 ] {ai_charge(8);};
void() gambit_satta5 =[ $satta5, gambit_satta6 ] {ai_charge(4);};
void() gambit_satta6 =[ $satta6, gambit_satta7 ] {};
void() gambit_satta7 =[ $satta7, gambit_satta8 ] {GambitStrike();};
void() gambit_satta8 =[ $satta8, gambit_satta9 ] {};
void() gambit_satta9 =[ $satta9, gambit_satta10 ] {ai_forward(4);};
void() gambit_satta10 =[ $satta10, gambit_satta11 ] {ai_forward(8);};
void() gambit_satta11 =[ $satta11, gambit_satta12 ] {ai_forward(8);};
void() gambit_satta12 =[ $satta12, gambit_run1 ] {ai_forward(4);};
void() gambit_melee =
{
sound (self, CHAN_WEAPON, "generic/swing1.wav", 1, ATTN_NORM);
gambit_satta1 ();
};
//============================================================================
void(float heading_ofs, float zofs) GambitCard =
{
local vector newangle, targ_vect, ofs;
local entity missile;
targ_vect = normalize(self.enemy.origin - self.origin);
newangle = vectoangles(targ_vect);
newangle_y = anglemod(newangle_y + heading_ofs);
newangle_x = -1 * newangle_x;
makevectors(newangle);
ofs = '0 0 0';
ofs_z = zofs;
launch_spike (self.origin + ofs + v_forward*14, v_forward);
newmis.classname = "gambit_card";
setmodel (newmis, "progs/card.mdl");
setsize(newmis, '0 0 0', '0 0 0');
};
void() gambit_xatta1 =[ $xatta1, gambit_xatta2 ] {ai_forward(4);};
void() gambit_xatta2 =[ $xatta2, gambit_xatta3 ] {ai_forward(8);};
void() gambit_xatta3 =[ $xatta3, gambit_xatta4 ] {ai_forward(8);};
void() gambit_xatta4 =[ $xatta4, gambit_xatta5 ] {ai_forward(8);ai_face();};
void() gambit_xatta5 =[ $xatta5, gambit_xatta6 ] {ai_forward(10);ai_face();};
void() gambit_xatta6 =[ $xatta6, gambit_xatta7 ] {ai_forward(10);ai_face();};
void() gambit_xatta7 =[ $xatta7, gambit_xatta8 ] {ai_forward(10);ai_face();};
void() gambit_xatta8 =[ $xatta8, gambit_xatta9 ] {ai_forward(8);ai_face();};
void() gambit_xatta9 =[ $xatta9, gambit_xatta10 ] {ai_forward(8);sound (self, CHAN_WEAPON, "boss1/throw.wav", 1, ATTN_NORM);GambitCard(-5, 16);};
void() gambit_xatta10 =[ $xatta10, gambit_xatta11 ] {ai_forward(8);GambitCard( 0, 16);};
void() gambit_xatta11 =[ $xatta11, gambit_xatta12 ] {ai_forward(8);GambitCard( 5, 16);};
void() gambit_xatta12 =[ $xatta12, gambit_xatta13 ] {ai_forward(6);};
void() gambit_xatta13 =[ $xatta13, gambit_xatta14 ] {ai_forward(4);};
void() gambit_xatta14 =[ $xatta14, gambit_run1 ] {ai_forward(2);};
void() gambit_xattb1 =[ $xattb1, gambit_xattb2 ] {ai_forward(-1);};
void() gambit_xattb2 =[ $xattb2, gambit_xattb3 ] {ai_forward(-1);sound (self, CHAN_WEAPON, "boss1/throw.wav", 1, ATTN_NORM);GambitCard(-6, 4);};
void() gambit_xattb3 =[ $xattb3, gambit_xattb4 ] {ai_forward(-3);GambitCard(-3, 4);};
void() gambit_xattb4 =[ $xattb4, gambit_xattb5 ] {ai_forward(-8);GambitCard( 0, 4);};
void() gambit_xattb5 =[ $xattb5, gambit_xattb6 ] {ai_forward(-10);GambitCard( 3, 4);};
void() gambit_xattb6 =[ $xattb6, gambit_xattb7 ] {ai_forward(-10);GambitCard( 6, 4);};
void() gambit_xattb7 =[ $xattb7, gambit_xattb8 ] {ai_forward(-10);};
void() gambit_xattb8 =[ $xattb8, gambit_xattb9 ] {ai_forward(-8);};
void() gambit_xattb9 =[ $xattb9, gambit_xattb10 ] {ai_forward(-8);};
void() gambit_xattb10 =[ $xattb10, gambit_xattb11 ] {ai_forward(-8);};
void() gambit_xattb11 =[ $xattb11, gambit_xattb12 ] {ai_forward(-4);};
void() gambit_xattb12 =[ $xattb12, gambit_run1 ] {};
void() gambit_special =
{
if (self.last_special > (time - 2))
return;
self.last_special = time;
// check head-room
traceline(self.origin, self.origin + '0 0 54', TRUE, self);
if (trace_fraction < 1)
gambit_xatta1();
else {
if (random() < 0.5)
gambit_xatta1();
else
gambit_xattb1();
}
};
//============================================================================
float() CheckGambitMelee =
{
local vector vect;
if ((enemy_range == RANGE_MELEE) && (vlen(self.origin - self.enemy.origin) < 96))
{ // FIXME: check canreach
self.attack_state = AS_MELEE;
return TRUE;
}
return FALSE;
};
/*
==============
CheckGambitSpecial
==============
*/
float() CheckGambitSpecial =
{
local vector dist, p1, p2, vect;
local float d;
if (self.last_special > (time - 4)) {
makevectors(self.angles);
if (random() < 0.1) { // jump if looking at player
vect = normalize(self.enemy.origin - self.origin);
if (vlen(v_forward - vect) < 0.5)
gambit_jump1();
}
return FALSE;
}
// now, check line of sight (between p1 and p2)
p1 = self.origin;
p2 = self.enemy.origin;
traceline(p1, p2, FALSE, self);
if ((trace_fraction < 1) && (trace_ent != self.enemy))
return FALSE;
dist = self.enemy.origin - self.origin;
dist_z = 0;
d = vlen(dist);
if (d < 100)
return FALSE;
if (d > 312)
return FALSE;
return TRUE;
};
float() GambitCheckAttack =
{
local vector vec;
// if close enough for slashing, go for it
if (CheckGambitMelee ())
{
self.attack_state = AS_MELEE;
return TRUE;
}
if (CheckGambitSpecial ())
{
self.attack_state = AS_MISSILE;
return TRUE;
}
return FALSE;
};
//============================================================================
/*QUAKED monster_hell_knight (1 0 0) (-16 -16 -24) (16 16 40) Ambush
*/
void() monster_hell_knight =
{
remove(self);
};
void() xmen_gambit =
{
if (deathmatch)
{
remove(self);
return;
}
precache_model2 ("progs/gambit1.mdl");
precache_model2 ("progs/card.mdl");
// Xmen Sounds: matched ID sounds
precache_sound ("boss1/throw.wav");
precache_sound ("generic/swing1.wav");
/*
// Unmatched HKnight sounds
precache_sound2 ("hknight/attack1.wav");
precache_sound2 ("hknight/death1.wav");
precache_sound2 ("hknight/pain1.wav");
precache_sound2 ("hknight/sight1.wav");
precache_sound ("hknight/hit.wav"); // used by C code, so don't sound2
precache_sound2 ("hknight/idle.wav");
precache_sound2 ("hknight/grunt.wav");
precache_sound ("knight/sword1.wav");
precache_sound ("knight/sword2.wav");
*/
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
setmodel (self, "progs/gambit1.mdl");
setsize (self, '-16 -16 -24', '16 16 40');
self.health = 120 + cvar("skill")*10;
self.th_stand = gambit_stand1;
self.th_walk = gambit_walk1;
self.th_run = gambit_run1;
self.th_melee = gambit_melee;
self.th_missile = gambit_special;
self.th_pain = gambit_pain;
self.th_die = gambit_die;
walkmonster_start ();
};

72
geometry.c Normal file
View file

@ -0,0 +1,72 @@
// Just a handy proc for finding the angle between two vectors
// v1 and v2 must be in range 0 - 360
// answer is heading (Y) angle going from v1 to v2
float(float a1, float a2) angle_diff =
{
if (a2 > a1) {
if ((a2 - a1) > 180) {
return (a1 - (a2 - 360));
}
else {
return (a1 - a2);
}
}
else {
if ((a1 - a2) > 180) {
return (a1 - (a2 + 360));
}
else {
return (a1 - a2);
}
}
};
// Calculates and returns the reflection vector of the intersection
// of the vector "dir" with a "wall_normal" at position "org"
vector(vector org, vector dir, vector wall_normal) GetReflectionVect =
{
local vector first_wallpoint, second_wallpoint, first_linepoint, second_linepoint;
local float wall_dist;
first_linepoint = org - dir*4;
traceline(first_linepoint, first_linepoint - wall_normal*8, TRUE, world);
first_wallpoint = trace_endpos;
second_wallpoint = org - (first_wallpoint - org);
second_linepoint = second_wallpoint + wall_normal * 4;
second_linepoint = normalize(second_linepoint - org);
return second_linepoint;
};
float(float s_angle, float e_angle, float rate) MoveToAngle =
{
local float result;
if ((s_angle > e_angle) &&
((s_angle - e_angle) > 180)) {
e_angle = e_angle + 360;
}
else if ((e_angle > s_angle) &&
((e_angle - s_angle) > 180)) {
s_angle = s_angle + 360;
}
if (s_angle > e_angle) {
result = s_angle - rate*frametime;
if (result < e_angle) result = e_angle;
}
else {
result = s_angle + rate*frametime;
if (result > e_angle) result = e_angle;
}
if (result >= 360) result = result - 360;
if (result < 0) result = result + 360;
return result;
};

502
phoenix.c Normal file
View file

@ -0,0 +1,502 @@
/*==========================================================================
phoenix
==========================================================================*/
$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
$frame stand10 stand11 stand12 stand13
$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10
$frame walk11 walk12
$frame run1 run2 run3 run4 run5 run6 run7 run8
$frame pain1 pain2 pain3 pain4 pain5 pain6
$frame paina1 paina2 paina3 paina4 paina5 paina6 paina7 paina8 paina9 paina10
$frame paina11 paina12 paina13 paina14 paina15 paina16 paina17 paina18 paina19 paina20
$frame paina21 paina22 paina23 paina24
$frame death1 death2 death3 death4 death5 death6 death7 death8 death9 death10
$frame death11 death12 death13 death14 death15 death16 death17 death18 death19 death20
$frame guard1 guard2 guard3 guard4 guard5 guard6 guard7 guard8 guard9
$frame guard10 guard11 guard12
$frame xatta1 xatta2 xatta3 xatta4 xatta5 xatta6 xatta7 xatta8 xatta9 xatta10
$frame xatta11 xatta12
$frame xattb1 xattb2 xattb3 xattb4 xattb5 xattb6 xattb7 xattb8 xattb9 xattb10
$frame xattb11 xattb12
$frame xattc1 xattc2 xattc3 xattc4 xattc5 xattc6 xattc7 xattc8 xattc9 xattc10
$frame xattc11 xattc12 xattc13 xattc14 xattc15 xattc16 xattc17
void() phoenix_stand1 = [ $stand1, phoenix_stand2 ] {ai_stand();};
void() phoenix_stand2 = [ $stand2, phoenix_stand3 ] {ai_stand();};
void() phoenix_stand3 = [ $stand3, phoenix_stand4 ] {ai_stand();};
void() phoenix_stand4 = [ $stand4, phoenix_stand5 ] {ai_stand();};
void() phoenix_stand5 = [ $stand5, phoenix_stand6 ] {ai_stand();};
void() phoenix_stand6 = [ $stand6, phoenix_stand7 ] {ai_stand();};
void() phoenix_stand7 = [ $stand7, phoenix_stand8 ] {ai_stand();};
void() phoenix_stand8 = [ $stand8, phoenix_stand9 ] {ai_stand();};
void() phoenix_stand9 = [ $stand9, phoenix_stand10 ] {ai_stand();};
void() phoenix_stand10 = [ $stand10, phoenix_stand11 ] {ai_stand();};
void() phoenix_stand11 = [ $stand11, phoenix_stand12 ] {ai_stand();};
void() phoenix_stand12 = [ $stand12, phoenix_stand13 ] {ai_stand();};
void() phoenix_stand13 = [ $stand13, phoenix_stand1 ] {ai_stand();};
void() phoenix_walk1 = [ $walk1, phoenix_walk2 ] {ai_walk(5);};
void() phoenix_walk2 = [ $walk2, phoenix_walk3 ] {ai_walk(4);};
void() phoenix_walk3 = [ $walk3, phoenix_walk4 ] {ai_walk(4);};
void() phoenix_walk4 = [ $walk4, phoenix_walk5 ] {ai_walk(5);};
void() phoenix_walk5 = [ $walk5, phoenix_walk6 ] {ai_walk(5);};
void() phoenix_walk6 = [ $walk6, phoenix_walk7 ] {ai_walk(6);};
void() phoenix_walk7 = [ $walk7, phoenix_walk8 ] {ai_walk(6);};
void() phoenix_walk8 = [ $walk8, phoenix_walk9 ] {ai_walk(4);};
void() phoenix_walk9 = [ $walk9, phoenix_walk10 ] {ai_walk(4);};
void() phoenix_walk10 = [ $walk10, phoenix_walk11 ] {ai_walk(5);};
void() phoenix_walk11 = [ $walk11, phoenix_walk12 ] {ai_walk(5);};
void() phoenix_walk12 = [ $walk12, phoenix_walk1 ] {ai_walk(6);};
void() phoenix_runwalk1;
void() phoenix_run1 = [ $run1, phoenix_run2 ]
{
if (vlen(self.enemy.origin - self.origin) < 196) {
phoenix_runwalk1();
return;
}
ai_run(19);
};
void() phoenix_run2 = [ $run2, phoenix_run3 ] {ai_run(19);};
void() phoenix_run3 = [ $run3, phoenix_run4 ] {ai_run(18);};
void() phoenix_run4 = [ $run4, phoenix_run5 ] {ai_run(18);};
void() phoenix_run5 = [ $run5, phoenix_run6 ] {ai_run(19);};
void() phoenix_run6 = [ $run6, phoenix_run7 ] {ai_run(19);};
void() phoenix_run7 = [ $run7, phoenix_run8 ] {ai_run(18);};
void() phoenix_run8 = [ $run8, phoenix_run1 ] {ai_run(18);};
void() phoenix_runwalk1 = [ $walk1, phoenix_runwalk2 ]
{
if (vlen(self.enemy.origin - self.origin) > 256) {
phoenix_run1();
return;
}
ai_run(4);
};
void() phoenix_runwalk2 = [ $walk2, phoenix_runwalk3 ] {ai_run(4);};
void() phoenix_runwalk3 = [ $walk3, phoenix_runwalk4 ] {ai_run(3);};
void() phoenix_runwalk4 = [ $walk4, phoenix_runwalk5 ] {ai_run(4);};
void() phoenix_runwalk5 = [ $walk5, phoenix_runwalk6 ] {ai_run(4);};
void() phoenix_runwalk6 = [ $walk6, phoenix_runwalk7 ] {ai_run(3);};
void() phoenix_runwalk7 = [ $walk7, phoenix_runwalk8 ] {ai_run(3);};
void() phoenix_runwalk8 = [ $walk8, phoenix_runwalk9 ] {ai_run(4);};
void() phoenix_runwalk9 = [ $walk9, phoenix_runwalk10 ] {ai_run(4);};
void() phoenix_runwalk10 = [ $walk10, phoenix_runwalk11 ] {ai_run(3);};
void() phoenix_runwalk11 = [ $walk11, phoenix_runwalk12 ] {ai_run(4);};
void() phoenix_runwalk12 = [ $walk12, phoenix_runwalk1 ] {ai_run(4);};
//============================================================================
void() phoenix_pain1 = [ $pain1, phoenix_pain2 ] {};
void() phoenix_pain2 = [ $pain2, phoenix_pain3 ] {};
void() phoenix_pain3 = [ $pain3, phoenix_pain4 ] {};
void() phoenix_pain4 = [ $pain4, phoenix_pain5 ] {};
void() phoenix_pain5 = [ $pain5, phoenix_pain6 ] {};
void() phoenix_pain6 = [ $pain6, phoenix_run1 ] {};
void() phoenix_paina1 = [ $paina1, phoenix_paina2 ] {};
void() phoenix_paina2 = [ $paina2, phoenix_paina3 ] {};
void() phoenix_paina3 = [ $paina3, phoenix_paina4 ] {};
void() phoenix_paina4 = [ $paina4, phoenix_paina5 ] {};
void() phoenix_paina5 = [ $paina5, phoenix_paina6 ] {};
void() phoenix_paina6 = [ $paina6, phoenix_paina7 ] {};
void() phoenix_paina7 = [ $paina7, phoenix_paina8 ] {};
void() phoenix_paina8 = [ $paina8, phoenix_paina9 ] {};
void() phoenix_paina9 = [ $paina9, phoenix_paina10 ] {};
void() phoenix_paina10 = [ $paina10, phoenix_paina11 ] {};
void() phoenix_paina11 = [ $paina11, phoenix_paina12 ] {};
void() phoenix_paina12 = [ $paina12, phoenix_paina13 ] {};
void() phoenix_paina13 = [ $paina13, phoenix_paina14 ] {};
void() phoenix_paina14 = [ $paina14, phoenix_paina15 ] {};
void() phoenix_paina15 = [ $paina15, phoenix_paina16 ] {};
void() phoenix_paina16 = [ $paina16, phoenix_paina17 ] {};
void() phoenix_paina17 = [ $paina17, phoenix_paina18 ] {};
void() phoenix_paina18 = [ $paina18, phoenix_paina19 ] {};
void() phoenix_paina19 = [ $paina19, phoenix_paina20 ] {};
void() phoenix_paina20 = [ $paina20, phoenix_paina21 ] {};
void() phoenix_paina21 = [ $paina21, phoenix_paina22 ] {};
void() phoenix_paina22 = [ $paina22, phoenix_paina23 ] {};
void() phoenix_paina23 = [ $paina23, phoenix_paina24 ] {};
void() phoenix_paina24 = [ $paina24, phoenix_run1 ] {};
void(entity attacker, float damage) PhoenixPain =
{
if (self.pain_finished > time)
return;
if (self.health <= 0)
return;
FemalePainSound();
if ((damage > 10) && (random() < 0.4)) {
sound(self, CHAN_AUTO, "items/protect3.wav", 1, ATTN_NORM);
self.pain_finished = time + 2;
phoenix_paina1();
}
else {
self.pain_finished = time + 5;
phoenix_pain1();
}
};
//============================================================================
void() phoenix_death1 = [ $death1, phoenix_death2 ] {};
void() phoenix_death2 = [ $death2, phoenix_death3 ] {};
void() phoenix_death3 = [ $death3, phoenix_death4 ] {self.solid = SOLID_NOT;};
void() phoenix_death4 = [ $death4, phoenix_death5 ] {};
void() phoenix_death5 = [ $death5, phoenix_death6 ] {};
void() phoenix_death6 = [ $death6, phoenix_death7 ] {};
void() phoenix_death7 = [ $death7, phoenix_death8 ] {};
void() phoenix_death8 = [ $death8, phoenix_death9 ] {};
void() phoenix_death9 = [ $death9, phoenix_death10 ] {};
void() phoenix_death10 = [ $death10, phoenix_death11 ] {};
void() phoenix_death11 = [ $death11, phoenix_death12 ] {};
void() phoenix_death12 = [ $death12, phoenix_death13 ] {};
void() phoenix_death13 = [ $death13, phoenix_death14 ] {};
void() phoenix_death14 = [ $death14, phoenix_death15 ] {};
void() phoenix_death15 = [ $death15, phoenix_death16 ] {};
void() phoenix_death16 = [ $death16, phoenix_death17 ] {};
void() phoenix_death17 = [ $death17, phoenix_death18 ] {};
void() phoenix_death18 = [ $death18, phoenix_death19 ] {};
void() phoenix_death19 = [ $death19, phoenix_death20 ] {};
void() phoenix_death20 = [ $death20, phoenix_death20 ] {if (self.angles_x != 0) AngelPitch();};
void() PhoenixDie =
{
FemaleDeathSound();
phoenix_death1();
};
//============================================================================
void() phoenix_guard1 = [ $guard1, phoenix_guard2 ] {self.nextthink = time + 0.05;};
void() phoenix_guard2 = [ $guard2, phoenix_guard3 ] {self.nextthink = time + 0.05;};
void() phoenix_guard3 = [ $guard3, phoenix_guard4 ] {self.nextthink = time + 0.05;};
void() phoenix_guard4 = [ $guard4, phoenix_guard5 ] {
sound(self, CHAN_BODY, "items/protect3.wav", 1, ATTN_NORM);
self.flags = self.flags | FL_GODMODE;};
void() phoenix_guard5 = [ $guard5, phoenix_guard6 ] {};
void() phoenix_guard6 = [ $guard6, phoenix_guard7 ] {};
void() phoenix_guard7 = [ $guard7, phoenix_guard8 ] {};
void() phoenix_guard8 = [ $guard8, phoenix_guard9 ] {};
void() phoenix_guard9 = [ $guard9, phoenix_guard10 ] {};
void() phoenix_guard10 = [ $guard10, phoenix_guard11 ] {};
void() phoenix_guard11 = [ $guard11, phoenix_guard12 ] {};
void() phoenix_guard12 = [ $guard12, phoenix_run1 ] {self.flags = self.flags - FL_GODMODE;};
//============================================================================
void() PhoenixFireHoming =
{
local entity missile, missile_enemy;
local vector dir;
missile = spawn ();
missile.classname = "phoenix_blast";
missile.attack_finished = time + 3;
missile.owner = self;
missile.movetype = MOVETYPE_FLYMISSILE;
missile.solid = SOLID_BBOX;
missile.enemy = self.enemy;
missile.think = GuidedRocketThink;
missile.last_guided_search = time;
missile.nextthink = time + 0.05;
// set missile speed
makevectors(self.angles);
missile.velocity = v_forward;
missile.velocity = missile.velocity * 800;
missile.angles = vectoangles(missile.velocity);
missile.touch = T_GuidedMissileTouch;
missile.avelocity_z = 300;
setmodel (missile, "progs/psyblast.mdl");
setsize (missile, '0 0 0', '0 0 0');
setorigin (missile, self.origin + dir*8 + '0 0 12');
};
void() phoenix_xatta1 = [ $xatta1, phoenix_xatta2 ] {ai_face();};
void() phoenix_xatta2 = [ $xatta2, phoenix_xatta3 ] {ai_face();};
void() phoenix_xatta3 = [ $xatta3, phoenix_xatta4 ] {ai_face();};
void() phoenix_xatta4 = [ $xatta4, phoenix_xatta5 ] {ai_face();};
void() phoenix_xatta5 = [ $xatta5, phoenix_xatta6 ] {PhoenixFireHoming();};
void() phoenix_xatta6 = [ $xatta6, phoenix_xatta7 ] {};
void() phoenix_xatta7 = [ $xatta7, phoenix_xatta8 ] {};
void() phoenix_xatta8 = [ $xatta8, phoenix_xatta9 ] {};
void() phoenix_xatta9 = [ $xatta9, phoenix_xatta10 ] {};
void() phoenix_xatta10 = [ $xatta10, phoenix_xatta11 ] {};
void() phoenix_xatta11 = [ $xatta11, phoenix_xatta12 ] {};
void() phoenix_xatta12 = [ $xatta12, phoenix_run1 ] {};
void() phoenix_xattb1 = [ $xattb1, phoenix_xattb2 ] {ai_face();};
void() phoenix_xattb2 = [ $xattb2, phoenix_xattb3 ] {ai_face();};
void() phoenix_xattb3 = [ $xattb3, phoenix_xattb4 ] {ai_face();};
void() phoenix_xattb4 = [ $xattb4, phoenix_xattb5 ] {ai_face();};
void() phoenix_xattb5 = [ $xattb5, phoenix_xattb6 ] {ai_face();};
void() phoenix_xattb6 = [ $xattb6, phoenix_xattb7 ] {ai_face();};
void() phoenix_xattb7 = [ $xattb7, phoenix_xattb8 ] {ai_face();};
void() phoenix_xattb8 = [ $xattb8, phoenix_xattb9 ]
{
// hurt enemy
T_Damage(self.enemy, self, self, 10);
self.enemy.punchangle_x = -8;
self.last_special2 = time;
};
void() phoenix_xattb9 = [ $xattb9, phoenix_xattb10 ] {};
void() phoenix_xattb10 = [ $xattb10, phoenix_xattb11 ] {};
void() phoenix_xattb11 = [ $xattb11, phoenix_xattb12 ] {};
void() phoenix_xattb12 = [ $xattb12, phoenix_run1 ] {};
void() TractorParticleThink =
{
local float dist, r;
local vector vect;
if (!(self.owner.enemy.x_flags & X_TRACTOR_BEAM_HOLD)) {
setmodel(self, "");
self.nextthink = -1;
return;
}
vect = self.owner.enemy.origin - self.owner.origin;
dist = vlen(vect);
vect = normalize(vect);
self.t_length = self.t_length + self.speed * (time - self.last_special);
if (self.t_length >= dist - 48)
self.t_length = 0;
if (self == self.owner.flame_ent2) // rotate in other direction
self.angles_z = anglemod(self.angles_z - self.speed * (time - self.last_special));
else
self.angles_z = anglemod(self.angles_z + self.speed * (time - self.last_special));
self.z_ofs = self.z_ofs + self.z_ofs_vel;
if ((self.z_ofs <= -30) || (self.z_ofs >= 30)) {
self.z_ofs = -1 * self.z_ofs;
}
makevectors(self.angles);
setorigin(self, self.owner.origin + vect * self.t_length + v_up * self.z_ofs);
// random colored particle
// r = random() * 3.9;
// r = floor(r);
particle(self.origin, vect * 10, 241, 10 + r*5);
self.last_special = time;
self.nextthink = time + 0.05;
};
void() PhoenixStartBeam =
{
// if player is already in a beam, abort attack
if (self.enemy.x_flags & X_TRACTOR_BEAM_HOLD) {
self.th_run();
return;
}
self.flags = self.flags | FL_GODMODE;
sound(self.enemy, CHAN_WEAPON, "items/damage3.wav", 1, ATTN_NORM);
self.last_special = time;
self.enemy.x_flags = self.enemy.x_flags | X_TRACTOR_BEAM_HOLD;
self.enemy.tractor_vel = '0 0 10';
setorigin(self.enemy, self.enemy.origin + '0 0 1');
self.enemy.flags = self.enemy.flags - (self.enemy.flags & FL_ONGROUND);
self.start_tractor_time = time;
self.enemy.start_tractor_time = time;
setmodel(self.flame_ent1, "progs/beampart.mdl");
setmodel(self.flame_ent2, "progs/beampart.mdl");
setmodel(self.flame_ent3, "progs/beampart.mdl");
setorigin(self.flame_ent1, self.origin);
setorigin(self.flame_ent2, self.origin);
setorigin(self.flame_ent3, self.origin);
self.flame_ent1.nextthink = time + 0.05;
self.flame_ent2.nextthink = time + 0.05;
self.flame_ent3.nextthink = time + 0.05;
// speed to travel
self.flame_ent1.speed = 800;
self.flame_ent2.speed = 400;
self.flame_ent3.speed = 200;
// distance from Phoenix
self.flame_ent1.t_length = 0;
self.flame_ent2.t_length = 0;
self.flame_ent3.t_length = 0;
// distance from center of tractor beam
self.flame_ent1.z_ofs = 10;
self.flame_ent2.z_ofs = 5;
self.flame_ent3.z_ofs = 0;
// 1 = travelling away from center, -1 = travelling towards center
self.flame_ent1.z_ofs_vel = -2;
self.flame_ent2.z_ofs_vel = 2.5;
self.flame_ent3.z_ofs_vel = 1;
};
void() phoenix_xattc9;
void() PhoenixBeamThink =
{
self.enemy.tractor_vel_z = self.enemy.tractor_vel_z + 50;
if (self.enemy.tractor_vel_z > 100)
self.enemy.tractor_vel_z = 100;
/*
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_LIGHTNING2);
WriteEntity (MSG_BROADCAST, self.enemy);
WriteCoord (MSG_BROADCAST, self.enemy.origin_x);
WriteCoord (MSG_BROADCAST, self.enemy.origin_y);
WriteCoord (MSG_BROADCAST, self.enemy.origin_z);
WriteCoord (MSG_BROADCAST, self.origin_x);
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
*/
traceline(self.origin, self.enemy.origin, TRUE, self);
if ((self.start_tractor_time < (time - 3)) || (trace_fraction < 1)) {
phoenix_xattc9();
}
};
void() PhoenixBeamEnd =
{
self.enemy.x_flags = self.enemy.x_flags - (self.enemy.x_flags & X_TRACTOR_BEAM_HOLD);
self.enemy.velocity = normalize(self.enemy.origin - self.origin) * 250 + '0 0 100';
// hurt enemy
T_Damage(self.enemy, self, self, 10);
self.enemy.punchangle_x = -8;
self.flags = self.flags - (self.flags & FL_GODMODE);
};
void() phoenix_xattc1 = [ $xattc1, phoenix_xattc2 ] {ai_face(); self.start_attack_health = self.health;};
void() phoenix_xattc2 = [ $xattc2, phoenix_xattc3 ] {ai_face(); self.nextthink = time + 0.2;};
void() phoenix_xattc3 = [ $xattc3, phoenix_xattc4 ] {ai_face(); self.nextthink = time + 0.2;};
void() phoenix_xattc4 = [ $xattc4, phoenix_xattc5 ]
{
ai_face();
if (self.start_attack_health == self.health)
PhoenixStartBeam();
else
self.th_run;
};
void() phoenix_xattc5 = [ $xattc5, phoenix_xattc6 ] {PhoenixBeamThink();};
void() phoenix_xattc6 = [ $xattc6, phoenix_xattc7 ] {PhoenixBeamThink();};
void() phoenix_xattc7 = [ $xattc7, phoenix_xattc8 ] {PhoenixBeamThink();};
void() phoenix_xattc8 = [ $xattc8, phoenix_xattc5 ] {PhoenixBeamThink();};
void() phoenix_xattc9 = [ $xattc9, phoenix_xattc10 ] {};
void() phoenix_xattc10 = [ $xattc10, phoenix_xattc11 ] {};
void() phoenix_xattc11 = [ $xattc11, phoenix_xattc12 ] {};
void() phoenix_xattc12 = [ $xattc12, phoenix_xattc13 ] {PhoenixBeamEnd();};
void() phoenix_xattc13 = [ $xattc13, phoenix_xattc14 ] {};
void() phoenix_xattc14 = [ $xattc14, phoenix_xattc15 ] {};
void() phoenix_xattc15 = [ $xattc15, phoenix_xattc16 ] {};
void() phoenix_xattc16 = [ $xattc16, phoenix_xattc17 ] {};
void() phoenix_xattc17 = [ $xattc17, phoenix_run1 ] {};
void() PhoenixMissile =
{
local float rnd;
rnd = random();
if ((rnd < 0.3) && (self.last_special2 < (time - 6)))
phoenix_xattb1();
else if ((vlen(self.origin - self.enemy.origin) > 128) && (rnd < 0.8) && (self.last_special < (time - 4)))
phoenix_xattc1();
else
phoenix_xatta1();
};
//============================================================================
void() monster_shalrath =
{
remove(self);
return;
};
void() xmen_phoenix =
{
if (deathmatch)
{
remove(self);
return;
}
precache_model ("progs/phoenix.mdl");
precache_model ("progs/psyblast.mdl");
// XMen matched ID sounds
precache_sound ("items/protect3.wav");
precache_sound ("items/damage3.wav");
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
setmodel (self, "progs/phoenix.mdl");
setsize (self, VEC_HULL_MIN, VEC_HULL_MAX);
self.health = 180 + cvar("skill")*10;
self.th_stand = phoenix_stand1;
self.th_walk = phoenix_walk1;
self.th_run = phoenix_run1;
self.th_pain = PhoenixPain;
self.th_die = PhoenixDie;
self.th_missile = PhoenixMissile;
self.th_guard = phoenix_guard1;
walkmonster_start();
precache_model("progs/beampart.mdl");
// create beam entities
self.flame_ent1 = spawn();
self.flame_ent2 = spawn();
self.flame_ent3 = spawn();
self.flame_ent1.think = TractorParticleThink;
self.flame_ent2.think = TractorParticleThink;
self.flame_ent3.think = TractorParticleThink;
self.flame_ent1.owner = self;
self.flame_ent2.owner = self;
self.flame_ent3.owner = self;
};

143
progdefs.h Normal file
View file

@ -0,0 +1,143 @@
/* file generated by qcc, do not modify */
typedef struct
{ int pad[28];
int self;
int other;
int world;
float time;
float frametime;
float force_retouch;
string_t mapname;
float deathmatch;
float coop;
float teamplay;
float serverflags;
float total_secrets;
float total_monsters;
float found_secrets;
float killed_monsters;
float parm1;
float parm2;
float parm3;
float parm4;
float parm5;
float parm6;
float parm7;
float parm8;
float parm9;
float parm10;
float parm11;
float parm12;
float parm13;
float parm14;
float parm15;
float parm16;
vec3_t v_forward;
vec3_t v_up;
vec3_t v_right;
float trace_allsolid;
float trace_startsolid;
float trace_fraction;
vec3_t trace_endpos;
vec3_t trace_plane_normal;
float trace_plane_dist;
int trace_ent;
float trace_inopen;
float trace_inwater;
int msg_entity;
func_t main;
func_t StartFrame;
func_t PlayerPreThink;
func_t PlayerPostThink;
func_t ClientKill;
func_t ClientConnect;
func_t PutClientInServer;
func_t ClientDisconnect;
func_t SetNewParms;
func_t SetChangeParms;
} globalvars_t;
typedef struct
{
float modelindex;
vec3_t absmin;
vec3_t absmax;
float ltime;
float movetype;
float solid;
vec3_t origin;
vec3_t oldorigin;
vec3_t velocity;
vec3_t angles;
vec3_t avelocity;
vec3_t punchangle;
string_t classname;
string_t model;
float frame;
float skin;
float effects;
vec3_t mins;
vec3_t maxs;
vec3_t size;
func_t touch;
func_t use;
func_t think;
func_t blocked;
float nextthink;
int groundentity;
float health;
float frags;
float weapon;
string_t weaponmodel;
float weaponframe;
float currentammo;
float ammo_shells;
float ammo_nails;
float ammo_rockets;
float ammo_cells;
float items;
float takedamage;
int chain;
float deadflag;
vec3_t view_ofs;
float button0;
float button1;
float button2;
float impulse;
float fixangle;
vec3_t v_angle;
float idealpitch;
string_t netname;
int enemy;
float flags;
float colormap;
float team;
float max_health;
float teleport_time;
float armortype;
float armorvalue;
float waterlevel;
float watertype;
float ideal_yaw;
float yaw_speed;
int aiment;
int goalentity;
float spawnflags;
string_t target;
string_t targetname;
float dmg_take;
float dmg_save;
int dmg_inflictor;
int owner;
vec3_t movedir;
string_t message;
float sounds;
string_t noise;
string_t noise1;
string_t noise2;
string_t noise3;
} entvars_t;
#define PROGHEADER_CRC 5927

388
psylocke.c Normal file
View file

@ -0,0 +1,388 @@
/*
==============================================================================
Psyloche
==============================================================================
*/
$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
$frame stand10 stand11 stand12 stand13
$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10 walk11 walk12
$frame run1 run2 run3 run4 run5 run6
$frame pain1 pain2 pain3 pain4 pain5 pain6
$frame paina1 paina2 paina3 paina4 paina5 paina6 paina7 paina8 paina9 paina10
$frame paina11 paina12 paina13 paina14 paina15 paina16 paina17 paina18 paina19 paina20
$frame paina21 paina22 paina23 paina24 paina25 paina26 paina27 paina28 paina29
$frame death1 death2 death3 death4 death5 death6 death7 death8 death9 death10
$frame death11 death12 death13 death14 death15 death16
$frame jatta1 jatta2 jatta3 jatta4 jatta5 jatta6 jatta7 jatta8
$frame jatta9 jatta10 jatta11 jatta12
$frame jattb1 jattb2 jattb3 jattb4 jattb5 jattb6 jattb7 jattb8
$frame jattb9 jattb10 jattb11 jattb12
$frame satta1 satta2 satta3 satta4 satta5 satta6 satta7 satta8
$frame satta9 satta10 satta11 satta12
$frame sattb1 sattb2 sattb3 sattb4 sattb5 sattb6 sattb7 sattb8
$frame sattb9 sattb10 sattb11 sattb12
$frame sattc1 sattc2 sattc3 sattc4 sattc5 sattc6 sattc7 sattc8
$frame sattc9 sattc10 sattc11 sattc12
$frame sattd1 sattd2 sattd3 sattd4 sattd5 sattd6 sattd7 sattd8
$frame sattd9 sattd10 sattd11 sattd12
$frame xatt1 xatt2 xatt3 xatt4 xatt5 xatt6 xatt7 xatt8
$frame xatt9 xatt10 xatt11 xatt12
void() knight_stand1 =[ $stand1, knight_stand2 ] {ai_stand();};
void() knight_stand2 =[ $stand2, knight_stand3 ] {ai_stand();};
void() knight_stand3 =[ $stand3, knight_stand4 ] {ai_stand();};
void() knight_stand4 =[ $stand4, knight_stand5 ] {ai_stand();};
void() knight_stand5 =[ $stand5, knight_stand6 ] {ai_stand();};
void() knight_stand6 =[ $stand6, knight_stand7 ] {ai_stand();};
void() knight_stand7 =[ $stand7, knight_stand8 ] {ai_stand();};
void() knight_stand8 =[ $stand8, knight_stand9 ] {ai_stand();};
void() knight_stand9 =[ $stand9, knight_stand10 ] {ai_stand();};
void() knight_stand10 =[ $stand10, knight_stand11 ] {ai_stand();};
void() knight_stand11 =[ $stand11, knight_stand12 ] {ai_stand();};
void() knight_stand12 =[ $stand12, knight_stand13 ] {ai_stand();};
void() knight_stand13 =[ $stand13, knight_stand1 ] {ai_stand();};
void() knight_walk1 =[ $walk1, knight_walk2 ] {ai_walk(7);};
void() knight_walk2 =[ $walk2, knight_walk3 ] {ai_walk(6);};
void() knight_walk3 =[ $walk3, knight_walk4 ] {ai_walk(5);};
void() knight_walk4 =[ $walk4, knight_walk5 ] {ai_walk(5);};
void() knight_walk5 =[ $walk5, knight_walk6 ] {ai_walk(5);};
void() knight_walk6 =[ $walk6, knight_walk7 ] {ai_walk(6);};
void() knight_walk7 =[ $walk7, knight_walk8 ] {ai_walk(8);};
void() knight_walk8 =[ $walk8, knight_walk9 ] {ai_walk(8);};
void() knight_walk9 =[ $walk9, knight_walk10 ] {ai_walk(6);};
void() knight_walk10 =[ $walk10, knight_walk11 ] {ai_walk(5);};
void() knight_walk11 =[ $walk11, knight_walk12 ] {ai_walk(4);};
void() knight_walk12 =[ $walk12, knight_walk1 ] {ai_walk(5);};
void() knight_run1 =[ $run1, knight_run2 ] {ai_run(24);};
void() knight_run2 =[ $run2, knight_run3 ] {ai_run(30);};
void() knight_run3 =[ $run3, knight_run4 ] {ai_run(20);};
void() knight_run4 =[ $run4, knight_run5 ] {ai_run(13);};
void() knight_run5 =[ $run5, knight_run6 ] {ai_run(22);};
void() knight_run6 =[ $run6, knight_run1 ] {ai_run(30);};
void() knight_runatk1 =[ $jatta1, knight_runatk2 ]
{
sound (self, CHAN_WEAPON, "voice/female/attack1.wav", 1, ATTN_NORM);
ai_charge(20);
};
void() knight_runatk2 =[ $jatta2, knight_runatk3 ] {ai_charge_side();};
void() knight_runatk3 =[ $jatta3, knight_runatk4 ] {ai_charge_side();};
void() knight_runatk4 =[ $jatta4, knight_runatk5 ] {ai_charge_side();};
void() knight_runatk5 =[ $jatta5, knight_runatk6 ] {ai_melee_side();};
void() knight_runatk6 =[ $jatta6, knight_runatk7 ] {ai_melee_side();};
void() knight_runatk7 =[ $jatta7, knight_runatk8 ] {ai_melee_side();};
void() knight_runatk8 =[ $jatta8, knight_runatk9 ] {ai_melee_side();};
void() knight_runatk9 =[ $jatta9, knight_runatk10 ] {ai_melee_side();};
void() knight_runatk10 =[ $jatta10, knight_runatk11 ] {ai_charge_side();};
void() knight_runatk11 =[ $jatta11, knight_runatk12 ] {ai_charge(10);};
void() knight_runatk12 =[ $jatta12, knight_run1 ] {ai_charge(10);};
void() knight_runatkb1 =[ $jattb1, knight_runatkb2 ]
{
if (random() > 0.5)
sound (self, CHAN_WEAPON, "knight/sword2.wav", 1, ATTN_NORM);
else
sound (self, CHAN_WEAPON, "knight/sword1.wav", 1, ATTN_NORM);
ai_charge(20);
};
void() knight_runatkb2 =[ $jattb2, knight_runatkb3 ] {ai_charge_side();};
void() knight_runatkb3 =[ $jattb3, knight_runatkb4 ] {ai_charge_side();};
void() knight_runatkb4 =[ $jattb4, knight_runatkb5 ] {ai_charge_side();};
void() knight_runatkb5 =[ $jattb5, knight_runatkb6 ] {ai_melee_side();};
void() knight_runatkb6 =[ $jattb6, knight_runatkb7 ] {ai_melee_side();};
void() knight_runatkb7 =[ $jattb7, knight_runatkb8 ] {ai_melee_side();};
void() knight_runatkb8 =[ $jattb8, knight_runatkb9 ] {ai_melee_side();};
void() knight_runatkb9 =[ $jattb9, knight_runatkb10 ] {ai_melee_side();};
void() knight_runatkb10 =[ $jattb10, knight_runatkb11 ] {ai_charge_side();};
void() knight_runatkb11 =[ $jattb11, knight_runatkb12 ] {ai_charge(10);};
void() knight_runatkb12 =[ $jattb12, knight_run1 ] {ai_charge(10);};
void() knight_runattack =
{
if (random() < 0.5)
knight_runatk1();
else
knight_runatkb1();
};
void() knight_atk1 =[ $satta1, knight_atk2 ]
{
sound (self, CHAN_WEAPON, "voice/female/attack1.wav", 1, ATTN_NORM);
ai_charge(0);};
void() knight_atk2 =[ $satta2, knight_atk3 ] {ai_charge(7);};
void() knight_atk3 =[ $satta3, knight_atk4 ] {ai_charge(4);};
void() knight_atk4 =[ $satta4, knight_atk5 ] {ai_charge(0);};
void() knight_atk5 =[ $satta5, knight_atk6 ] {ai_charge(3);};
void() knight_atk6 =[ $satta6, knight_atk7 ] {ai_charge(4); ai_melee();};
void() knight_atk7 =[ $satta7, knight_atk8 ] {ai_charge(1); ai_melee();};
void() knight_atk8 =[ $satta8, knight_atk9 ] {ai_charge(3); ai_melee();};
void() knight_atk9 =[ $satta9, knight_atk10] {ai_charge(1);};
void() knight_atk10=[ $satta10, knight_atk11 ] {ai_charge(5);};
void() knight_atk11=[ $satta11, knight_atk12 ] {ai_charge(5);};
void() knight_atk12=[ $satta12, knight_run1 ] {ai_charge(5);};
void() knight_atkb1 =[ $sattb1, knight_atkb2 ]
{
sound (self, CHAN_WEAPON, "knight/sword1.wav", 1, ATTN_NORM);
ai_charge(0);};
void() knight_atkb2 =[ $sattb2, knight_atkb3 ] {ai_charge(7);};
void() knight_atkb3 =[ $sattb3, knight_atkb4 ] {ai_charge(4);};
void() knight_atkb4 =[ $sattb4, knight_atkb5 ] {ai_charge(0);};
void() knight_atkb5 =[ $sattb5, knight_atkb6 ] {ai_charge(3);};
void() knight_atkb6 =[ $sattb6, knight_atkb7 ] {ai_charge(4); ai_melee();};
void() knight_atkb7 =[ $sattb7, knight_atkb8 ] {ai_charge(1); ai_melee();};
void() knight_atkb8 =[ $sattb8, knight_atkb9 ] {ai_charge(3); ai_melee();};
void() knight_atkb9 =[ $sattb9, knight_atkb10] {ai_charge(1);};
void() knight_atkb10=[ $sattb10, knight_atkb11 ] {ai_charge(5);};
void() knight_atkb11=[ $sattb11, knight_atkb12 ] {ai_charge(5);};
void() knight_atkb12=[ $sattb12, knight_run1 ] {ai_charge(5);};
void() knight_atkc1 =[ $sattc1, knight_atkc2 ]
{
sound (self, CHAN_WEAPON, "voice/female/attack1.wav", 1, ATTN_NORM);
ai_charge(0);};
void() knight_atkc2 =[ $sattc2, knight_atkc3 ] {ai_charge(7);};
void() knight_atkc3 =[ $sattc3, knight_atkc4 ] {ai_charge(4);};
void() knight_atkc4 =[ $sattc4, knight_atkc5 ] {ai_charge(0);};
void() knight_atkc5 =[ $sattc5, knight_atkc6 ] {ai_charge(3);};
void() knight_atkc6 =[ $sattc6, knight_atkc7 ] {ai_charge(4); ai_melee();};
void() knight_atkc7 =[ $sattc7, knight_atkc8 ] {ai_charge(1); ai_melee();};
void() knight_atkc8 =[ $sattc8, knight_atkc9 ] {ai_charge(3); ai_melee();};
void() knight_atkc9 =[ $sattc9, knight_atkc10] {ai_charge(1);};
void() knight_atkc10=[ $sattc10, knight_atkc11 ] {ai_charge(5);};
void() knight_atkc11=[ $sattc11, knight_atkc12 ] {ai_charge(5);};
void() knight_atkc12=[ $sattc12, knight_run1 ] {ai_charge(5);};
void() knight_atkd1 =[ $sattd1, knight_atkd2 ]
{
sound (self, CHAN_WEAPON, "knight/sword1.wav", 1, ATTN_NORM);
ai_charge(0);};
void() knight_atkd2 =[ $sattd2, knight_atkd3 ] {ai_charge(7);};
void() knight_atkd3 =[ $sattd3, knight_atkd4 ] {ai_charge(4);};
void() knight_atkd4 =[ $sattd4, knight_atkd5 ] {ai_charge(0);};
void() knight_atkd5 =[ $sattd5, knight_atkd6 ] {ai_charge(3);};
void() knight_atkd6 =[ $sattd6, knight_atkd7 ] {ai_charge(4); ai_melee();};
void() knight_atkd7 =[ $sattd7, knight_atkd8 ] {ai_charge(1); ai_melee();};
void() knight_atkd8 =[ $sattd8, knight_atkd9 ] {ai_charge(3); ai_melee();};
void() knight_atkd9 =[ $sattd9, knight_atkd10] {ai_charge(1);};
void() knight_atkd10=[ $sattd10, knight_atkd11 ] {ai_charge(5);};
void() knight_atkd11=[ $sattd11, knight_atkd12 ] {ai_charge(5);};
void() knight_atkd12=[ $sattd12, knight_run1 ] {ai_charge(5);};
// Psyloche's special parallise attack
void() knight_special =
{
makevectors(self.angles);
traceline(self.origin, self.origin + v_forward*48, FALSE, self);
if ((trace_ent == self.enemy) && (self.enemy.classname == "player")) {
// got 'em
sound(self, CHAN_WEAPON, "player/what_1.wav", 1, ATTN_NORM);
self.enemy.parallize_time = time + 2 + random();
self.enemy.x_flags = self.enemy.x_flags | X_PARALLIZED;
self.enemy.parallized_velocity = '0 0 0';
centerprint(self.enemy, "You have been paralyzed");
stuffcmd(self.enemy, "v_cshift 0 0 0 180\n");
}
};
void() knight_xatk1 =[ $xatt1, knight_xatk2 ]
{
sound (self, CHAN_WEAPON, "knight/sword1.wav", 1, ATTN_NORM);
ai_charge(0);
self.nextthink = time + 0.05;};
void() knight_xatk2 =[ $xatt2, knight_xatk3 ] {ai_charge(0);self.nextthink = time + 0.05;};
void() knight_xatk3 =[ $xatt3, knight_xatk4 ] {ai_charge(0);self.nextthink = time + 0.05;};
void() knight_xatk4 =[ $xatt4, knight_xatk5 ] {ai_charge(0);self.nextthink = time + 0.05;};
void() knight_xatk5 =[ $xatt5, knight_xatk6 ] {ai_charge(0);self.nextthink = time + 0.05;};
void() knight_xatk6 =[ $xatt6, knight_xatk7 ] {ai_charge(0);self.nextthink = time + 0.05;};
void() knight_xatk7 =[ $xatt7, knight_xatk8 ] {ai_charge(3);self.nextthink = time + 0.05;};
void() knight_xatk8 =[ $xatt8, knight_xatk9 ] {ai_charge(5);self.nextthink = time + 0.05;};
void() knight_xatk9 =[ $xatt9, knight_xatk10] {ai_charge(10); knight_special();};
void() knight_xatk10=[ $xatt10, knight_xatk11 ] {ai_charge(0);};
void() knight_xatk11=[ $xatt11, knight_xatk12 ] {ai_charge(0);};
void() knight_xatk12=[ $xatt12, knight_run1 ] {ai_charge(0);};
void() knight_atk =
{
local float rnd;
// check for special attack
if ((vlen(self.enemy.velocity) < 20) && (self.last_special < (time - 5)) && (self.enemy.classname == "player")) {
self.last_special = time;
knight_xatk1();
return;
}
rnd = random() * 4;
if (rnd < 1)
knight_atk1();
else if (rnd < 2)
knight_atkb1();
else if (rnd < 3)
knight_atkc1();
else
knight_atkd1();
};
float() PsylockeCheckAttack =
{
local float dist;
dist = vlen(self.enemy.origin - self.origin);
if (dist > 256)
return FALSE;
if (!infront(self.enemy))
return FALSE;
if (dist > 96) {
self.attack_state = AS_MISSILE;
}
else {
self.attack_state = AS_MELEE;
}
return TRUE;
};
//===========================================================================
void() knight_pain1 =[ $pain1, knight_pain2 ] {};
void() knight_pain2 =[ $pain2, knight_pain3 ] {};
void() knight_pain3 =[ $pain3, knight_pain4 ] {};
void() knight_pain4 =[ $pain4, knight_pain5 ] {};
void() knight_pain5 =[ $pain5, knight_pain6 ] {};
void() knight_pain6 =[ $pain6, knight_run1 ] {};
void() knight_paina =
{
self.frame = self.frame + 1;
if (self.frame > $paina29 )
knight_run1();
else {
self.think = knight_paina;
self.nextthink = time + 0.05;
}
};
void(entity attacker, float damage) knight_pain =
{
local float r;
if (self.pain_finished > time)
return;
r = random();
FemalePainSound();
if (r < 0.85)
{
knight_pain1 ();
self.pain_finished = time + 2;
}
else
{
self.frame = $paina1 - 1;
knight_paina ();
self.pain_finished = time + 5;
}
};
void() knight_die1 =[ $death1, knight_die2 ] {};
void() knight_die2 =[ $death2, knight_die3 ] {};
void() knight_die3 =[ $death3, knight_die4 ]
{self.solid = SOLID_NOT;};
void() knight_die4 =[ $death4, knight_die5 ] {};
void() knight_die5 =[ $death5, knight_die6 ] {};
void() knight_die6 =[ $death6, knight_die7 ] {};
void() knight_die7 =[ $death7, knight_die8 ] {};
void() knight_die8 =[ $death8, knight_die9 ] {};
void() knight_die9 =[ $death9, knight_die10] {};
void() knight_die10=[ $death10, knight_die11] {};
void() knight_die11=[ $death11, knight_die12] {};
void() knight_die12=[ $death12, knight_die13] {};
void() knight_die13=[ $death13, knight_die14] {};
void() knight_die14=[ $death14, knight_die15] {};
void() knight_die15=[ $death15, knight_die16] {};
void() knight_die16=[ $death16, knight_die16] {};
void() knight_die =
{
FemaleDeathSound();
knight_die1 ();
};
/*QUAKED monster_knight (1 0 0) (-16 -16 -24) (16 16 40) Ambush
*/
void() monster_knight =
{
remove(self);
};
void() xmen_psylocke =
{
if (deathmatch)
{
remove(self);
return;
}
precache_model ("progs/psy1.mdl");
// precache_model ("progs/h_knight.mdl");
precache_sound ("voice/female/attack1.wav");
// XMen Matched ID sounds
precache_sound ("knight/sword1.wav");
precache_sound ("knight/sword2.wav");
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
setmodel (self, "progs/psy1.mdl");
setsize (self, '-16 -16 -24', '16 16 40');
self.health = 150 + cvar("skill")*10;
self.th_stand = knight_stand1;
self.th_walk = knight_walk1;
self.th_run = knight_run1;
self.th_melee = knight_atk;
self.th_missile = knight_runattack;
self.th_pain = knight_pain;
self.th_die = knight_die;
walkmonster_start ();
};

275
rogue.c Normal file
View file

@ -0,0 +1,275 @@
/*
==============================================================================
Rogue
==============================================================================
*/
$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
$frame stand10 stand11 stand12 stand13
$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10
$frame walk11 walk12 walk13
$frame run1 run2 run3 run4 run5 run6 run7 run8 run9 run10 run11 run12
$frame pain1 pain2 pain3 pain4 pain5 pain6
$frame death1 death2 death3 death4 death5 death6 death7 death8 death9 death10
$frame death11 death12
$frame deata1 deata2 deata3 deata4 deata5 deata6 deata7 deata8 deata9 deata10
$frame deata11 deata12
$frame punch1 punch2 punch3 punch4 punch5 punch6 punch7 punch8
$frame punch9 punch10 punch11 punch12
$frame atta1 atta2 atta3 atta4 atta5 atta6 atta7 atta8
$frame atta9 atta10 atta11 atta12
//=====================================================================
void() rogue_stand1 = [ $stand1, rogue_stand2 ] {ai_stand();};
void() rogue_stand2 = [ $stand2, rogue_stand3 ] {ai_stand();};
void() rogue_stand3 = [ $stand3, rogue_stand4 ] {ai_stand();};
void() rogue_stand4 = [ $stand4, rogue_stand5 ] {ai_stand();};
void() rogue_stand5 = [ $stand5, rogue_stand6 ] {ai_stand();};
void() rogue_stand6 = [ $stand6, rogue_stand7 ] {ai_stand();};
void() rogue_stand7 = [ $stand7, rogue_stand8 ] {ai_stand();};
void() rogue_stand8 = [ $stand8, rogue_stand9 ] {ai_stand();};
void() rogue_stand9 = [ $stand9, rogue_stand10 ] {ai_stand();};
void() rogue_stand10 = [ $stand10, rogue_stand11 ] {ai_stand();};
void() rogue_stand11 = [ $stand11, rogue_stand12 ] {ai_stand();};
void() rogue_stand12 = [ $stand12, rogue_stand13 ] {ai_stand();};
void() rogue_stand13 = [ $stand13, rogue_stand1 ] {ai_stand();};
//=====================================================================
void() rogue_walk1 = [ $walk1, rogue_walk2 ] {ai_walk(10);};
void() rogue_walk2 = [ $walk2, rogue_walk3 ] {ai_walk(10);};
void() rogue_walk3 = [ $walk3, rogue_walk4 ] {ai_walk(10);};
void() rogue_walk4 = [ $walk4, rogue_walk5 ] {ai_walk(10);};
void() rogue_walk5 = [ $walk5, rogue_walk6 ] {ai_walk(10);};
void() rogue_walk6 = [ $walk6, rogue_walk7 ] {ai_walk(10);};
void() rogue_walk7 = [ $walk7, rogue_walk8 ] {ai_walk(10);};
void() rogue_walk8 = [ $walk8, rogue_walk9 ] {ai_walk(10);};
void() rogue_walk9 = [ $walk9, rogue_walk10 ] {ai_walk(10);};
void() rogue_walk10 = [ $walk10, rogue_walk11 ] {ai_walk(10);};
void() rogue_walk11 = [ $walk11, rogue_walk12 ] {ai_walk(10);};
void() rogue_walk12 = [ $walk12, rogue_walk13 ] {ai_walk(10);};
void() rogue_walk13 = [ $walk13, rogue_walk1 ] {ai_walk(10);};
//=====================================================================
void() rogue_run1 = [ $run1, rogue_run2 ] {ai_run(15);};
void() rogue_run2 = [ $run2, rogue_run3 ] {ai_run(15);};
void() rogue_run3 = [ $run3, rogue_run4 ] {ai_run(15);};
void() rogue_run4 = [ $run4, rogue_run5 ] {ai_run(15);};
void() rogue_run5 = [ $run5, rogue_run6 ] {ai_run(15);};
void() rogue_run6 = [ $run6, rogue_run7 ] {ai_run(15);};
void() rogue_run7 = [ $run7, rogue_run8 ] {ai_run(15);};
void() rogue_run8 = [ $run8, rogue_run9 ] {ai_run(15);};
void() rogue_run9 = [ $run9, rogue_run10 ] {ai_run(15);};
void() rogue_run10 = [ $run10, rogue_run11 ] {ai_run(15);};
void() rogue_run11 = [ $run11, rogue_run12 ] {ai_run(15);};
void() rogue_run12 = [ $run12, rogue_run1 ] {ai_run(15);};
//=====================================================================
void() rogue_pain1 = [ $pain1, rogue_pain2 ] {};
void() rogue_pain2 = [ $pain2, rogue_pain3 ] {};
void() rogue_pain3 = [ $pain3, rogue_pain4 ] {};
void() rogue_pain4 = [ $pain4, rogue_pain5 ] {};
void() rogue_pain5 = [ $pain5, rogue_pain6 ] {};
void() rogue_pain6 = [ $pain6, rogue_run1 ] {};
void() rogue_pain =
{
if (self.pain_finished > time)
return;
// play a sound here
FemalePainSound();
self.pain_finished = time + 2.5;
rogue_pain1();
};
//=====================================================================
void() rogue_death1 = [ $death1, rogue_death2 ] {};
void() rogue_death2 = [ $death2, rogue_death3 ] {};
void() rogue_death3 = [ $death3, rogue_death4 ] {self.solid = SOLID_NOT;};
void() rogue_death4 = [ $death4, rogue_death5 ] {};
void() rogue_death5 = [ $death5, rogue_death6 ] {};
void() rogue_death6 = [ $death6, rogue_death7 ] {};
void() rogue_death7 = [ $death7, rogue_death8 ] {};
void() rogue_death8 = [ $death8, rogue_death9 ] {};
void() rogue_death9 = [ $death9, rogue_death10 ] {};
void() rogue_death10 = [ $death10, rogue_death11 ] {};
void() rogue_death11 = [ $death11, rogue_death12 ] {};
void() rogue_death12 = [ $death12, rogue_death12 ] {if (self.angles_x != 0) AngelPitch();};
void() rogue_deata1 = [ $deata1, rogue_deata2 ] {};
void() rogue_deata2 = [ $deata2, rogue_deata3 ] {};
void() rogue_deata3 = [ $deata3, rogue_deata4 ] {self.solid = SOLID_NOT;};
void() rogue_deata4 = [ $deata4, rogue_deata5 ] {};
void() rogue_deata5 = [ $deata5, rogue_deata6 ] {};
void() rogue_deata6 = [ $deata6, rogue_deata7 ] {};
void() rogue_deata7 = [ $deata7, rogue_deata8 ] {};
void() rogue_deata8 = [ $deata8, rogue_deata9 ] {};
void() rogue_deata9 = [ $deata9, rogue_deata10 ] {};
void() rogue_deata10 = [ $deata10, rogue_deata11 ] {};
void() rogue_deata11 = [ $deata11, rogue_deata12 ] {};
void() rogue_deata12 = [ $deata12, rogue_deata12 ] {if (self.angles_x != 0) AngelPitch();};
void() rogue_die =
{
FemaleDeathSound();
self.velocity_x = -200 + 400*random();
self.velocity_y = -200 + 400*random();
self.velocity_z = 100 + 100*random();
self.flags = self.flags - (self.flags & FL_ONGROUND);
self.enemy = world;
if (random() < 0.5)
rogue_death1 ();
else
rogue_deata1 ();
};
//=====================================================================
void() rogue_punch4;
float(float move_dist) RogueCheckPunch =
{
ai_face();
if (!ai_forward(move_dist)) { // abort
self.think = self.th_run;
return FALSE;
}
self.nextthink = time + 0.05;
if (!infront(self.enemy)) { // abort attack
self.think = self.th_run;
return FALSE;
}
if (vlen(self.enemy.origin - self.origin) > 96)
return FALSE;
// striking distance!
return TRUE;
};
void() RoguePunchPosition =
{
local float distance1;
distance1 = vlen(self.enemy.origin - self.origin);
ai_back(5);
};
void() rogue_punch1 = [ $punch1, rogue_punch2 ] {RoguePunchPosition(); self.attack_finished = time + 4;};
void() rogue_punch2 = [ $punch2, rogue_punch3 ] {RoguePunchPosition();};
void() rogue_punch3 = [ $punch3, rogue_punch3 ] {if (RogueCheckPunch(35)) rogue_punch4();};
void() rogue_punch4 = [ $punch4, rogue_punch5 ] {ai_forward(15); ai_face();};
void() rogue_punch5 = [ $punch5, rogue_punch6 ] {ai_forward(12); ai_face();};
void() rogue_punch6 = [ $punch6, rogue_punch7 ] {ai_forward(8); ai_face();};
void() rogue_punch7 = [ $punch7, rogue_punch8 ]
{
local vector vect;
if (RogueCheckPunch(0)) {
// hit em
sound(self, CHAN_WEAPON, "generic/punch2.wav", 1, ATTN_NORM);
T_Damage(self.enemy, self, self, 25);
vect = normalize(self.enemy.origin - self.origin);
self.enemy.velocity = vect * 300;
self.enemy.velocity_z = 300;
self.enemy.punchangle_x = -15;
}
};
void() rogue_punch8 = [ $punch8, rogue_punch9 ] {};
void() rogue_punch9 = [ $punch9, rogue_punch10 ] {};
void() rogue_punch10 = [ $punch10, rogue_punch11 ] {};
void() rogue_punch11 = [ $punch11, rogue_punch12 ] {};
void() rogue_punch12 = [ $punch12, rogue_run1 ] {};
//=================================================================
void() rogue_atta1 = [ $atta1, rogue_atta2 ]
{
ai_face();
if (vlen(self.enemy.origin - self.origin) < 64)
ai_forward(-10);
};
void() rogue_atta2 = [ $atta2, rogue_atta3 ] {ai_face();};
void() rogue_atta3 = [ $atta3, rogue_atta4 ] {ai_face();};
void() rogue_atta4 = [ $atta4, rogue_atta5 ] {ai_face();};
void() rogue_atta5 = [ $atta5, rogue_atta6 ] {ai_face();};
void() rogue_atta6 = [ $atta6, rogue_atta7 ] {ai_face();};
void() rogue_atta7 = [ $atta7, rogue_atta8 ]
{
ai_face();
if (RogueCheckPunch(0)) {
sound(self, CHAN_WEAPON, "generic/punch2.wav", 1, ATTN_NORM);
self.enemy.punchangle_x = -7;
T_Damage(self.enemy, self, self, 10);
}
};
void() rogue_atta8 = [ $atta8, rogue_atta9 ] {ai_face();};
void() rogue_atta9 = [ $atta9, rogue_atta10 ] {ai_face();};
void() rogue_atta10 = [ $atta10, rogue_atta11 ] {ai_face();};
void() rogue_atta11 = [ $atta11, rogue_atta12 ] {ai_face();};
void() rogue_atta12 = [ $atta12, rogue_run1 ] {ai_face();};
//=================================================================
/*QUAKED monster_ogre (1 0 0) (-32 -32 -24) (32 32 48) Ambush
*/
void() monster_ogre =
{
remove(self);
};
void() xmen_rogue =
{
if (deathmatch)
{
remove(self);
return;
}
precache_model ("progs/rogue.mdl");
precache_sound ("generic/punch2.wav");
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
setmodel (self, "progs/rogue.mdl");
setsize (self, VEC_HULL_MIN, VEC_HULL_MAX);
self.health = 210 + cvar("skill")*10;
self.yaw_speed = 10;
self.th_stand = rogue_stand1;
self.th_walk = rogue_walk1;
self.th_run = rogue_run1;
self.th_die = rogue_die;
self.th_pain = rogue_pain;
self.th_melee = rogue_atta1;
self.th_missile = rogue_punch1;
self.think = flymonster_start;
self.nextthink = time + 0.1 + random ()*0.1;
};

645
sinister.c Normal file
View file

@ -0,0 +1,645 @@
/****************************************************************************
SINISTER (2nd Episode boss)
****************************************************************************/
$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9 stand10
$frame stand11 stand12 stand13
$frame laugh1 laugh2 laugh3 laugh4 laugh5 laugh6 laugh7 laugh8 laugh9 laugh10
$frame laugh11 laugh12
$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10
$frame walk11 walk12
$frame pain1 pain2 pain3 pain4 pain5 pain6 pain7 pain8 pain9
$frame guard1 guard2 guard3 guard4 guard5 guard6 guard7 guard8
$frame guard9 guard10 guard11 guard12
$frame xatta1 xatta2 xatta3 xatta4 xatta5 xatta6 xatta7 xatta8
$frame xatta9 xatta10 xatta11 xatta12
$frame xattb1 xattb2 xattb3 xattb4 xattb5 xattb6 xattb7 xattb8
$frame xattb9 xattb10 xattb11 xattb12
$frame diss1 diss2 diss3 diss4 diss5 diss6
$frame death1 death2 death3 death4 death5 death6 death7 death8 death9 death10
$frame death11 death12 death13 death14 death15 death16 death17 death18 death19 death20
$frame death21 death22 death23 death24 death25 death26 death27 death28 death29 death30
$frame death31 death32 death33 death34
//============================================================================
void() CheckPlayerSight =
{
local entity sin, current;
if (self.spawnflags & SPAWNFLAG_CLONE)
return;
if (self.enemy == world)
self.enemy = self.goalentity = find(world, classname, "player");
if (self.enemy.health <= 0) {
return;
}
if (self.enemy != world) {
traceline(self.origin + '0 0 40', self.enemy.origin + '0 0 40', TRUE, world);
if (trace_fraction == 1) {
self.th_run();
if (self.x_flags & X_SINISTER_FINAL) {
// remove all other sinisters still in the map
sin = find(world, classname, "xmen_sinister");
while (sin != world) {
current = sin;
if (sin != self)
remove(sin);
sin = find(current, classname, "xmen_sinister");
}
self.last_flame = time;
sound(self, CHAN_ITEM, "sinister/mrsin1.wav", 1, ATTN_NONE);
}
}
}
};
void() sin_laugh1;
void() sin_stand1 = [ $stand1, sin_stand2 ] {CheckPlayerSight();};
void() sin_stand2 = [ $stand2, sin_stand3 ] {CheckPlayerSight();};
void() sin_stand3 = [ $stand3, sin_stand4 ] {CheckPlayerSight();};
void() sin_stand4 = [ $stand4, sin_stand5 ] {CheckPlayerSight();};
void() sin_stand5 = [ $stand5, sin_stand6 ] {CheckPlayerSight();};
void() sin_stand6 = [ $stand6, sin_stand7 ] {CheckPlayerSight();};
void() sin_stand7 = [ $stand7, sin_stand8 ] {CheckPlayerSight();};
void() sin_stand8 = [ $stand8, sin_stand9 ] {CheckPlayerSight();};
void() sin_stand9 = [ $stand9, sin_stand10 ] {CheckPlayerSight();};
void() sin_stand10 = [ $stand10, sin_stand11 ] {CheckPlayerSight();};
void() sin_stand11 = [ $stand11, sin_stand12 ] {CheckPlayerSight();};
void() sin_stand12 = [ $stand12, sin_stand13 ] {CheckPlayerSight();};
void() sin_stand13 = [ $stand13, sin_stand1 ]
{
if (!(self.x_flags & X_SINISTER_FINAL)) {
self.count = self.count + 1;
if ((random() < 0.4) || (self.count == 3)) {
self.count = 0;
self.think = sin_laugh1;
}
}
};
void() sin_laugh1 = [ $laugh1, sin_laugh2 ]
{
local float rnd;
if ((self.count == 0) && (self.last_flame < (time - 4))) {
rnd = random() * 8;
if (rnd < 1)
sound(self, CHAN_VOICE, "sinister/laugh1.wav", 1, 2);
else if (rnd < 2)
sound(self, CHAN_VOICE, "sinister/laugh2.wav", 1, 2);
else if (rnd < 2)
sound(self, CHAN_VOICE, "sinister/cackle1.wav", 1, 2);
else if (rnd < 4)
sound(self, CHAN_VOICE, "sinister/cackle2.wav", 1, 2);
else if (rnd < 5)
sound(self, CHAN_VOICE, "sinister/cackle3.wav", 1, 2);
else if (rnd < 6)
sound(self, CHAN_VOICE, "sinister/threat1.wav", 1, 2);
else if (rnd < 7)
sound(self, CHAN_VOICE, "sinister/threat2.wav", 1, 2);
else
sound(self, CHAN_VOICE, "sinister/threat3.wav", 1, 2);
}
};
void() sin_laugh2 = [ $laugh2, sin_laugh3 ] {CheckPlayerSight();};
void() sin_laugh3 = [ $laugh3, sin_laugh4 ] {CheckPlayerSight();};
void() sin_laugh4 = [ $laugh4, sin_laugh5 ] {CheckPlayerSight();};
void() sin_laugh5 = [ $laugh5, sin_laugh6 ] {CheckPlayerSight();};
void() sin_laugh6 = [ $laugh6, sin_laugh7 ] {CheckPlayerSight();};
void() sin_laugh7 = [ $laugh7, sin_laugh8 ] {CheckPlayerSight();};
void() sin_laugh8 = [ $laugh8, sin_laugh9 ] {CheckPlayerSight();};
void() sin_laugh9 = [ $laugh9, sin_laugh10 ] {CheckPlayerSight();};
void() sin_laugh10 = [ $laugh10, sin_laugh11 ] {CheckPlayerSight();};
void() sin_laugh11 = [ $laugh11, sin_laugh12 ] {CheckPlayerSight();};
void() sin_laugh12 = [ $laugh12, sin_laugh1 ]
{
self.count = self.count + 1;
if (self.count >= 4) {
self.count = 0;
self.think = sin_stand1;
}
};
//============================================================================
void() SinisterMissile;
void() sin_sightlaugh1 = [ $laugh1, sin_sightlaugh2 ]
{
local float rnd;
if (self.count == 0) {
rnd = random() * 8;
if (rnd < 1)
sound(self, CHAN_VOICE, "sinister/laugh1.wav", 1, 2);
else if (rnd < 2)
sound(self, CHAN_VOICE, "sinister/laugh2.wav", 1, 2);
else if (rnd < 2)
sound(self, CHAN_VOICE, "sinister/cackle1.wav", 1, 2);
else if (rnd < 4)
sound(self, CHAN_VOICE, "sinister/cackle2.wav", 1, 2);
else if (rnd < 5)
sound(self, CHAN_VOICE, "sinister/cackle3.wav", 1, 2);
else if (rnd < 6)
sound(self, CHAN_VOICE, "sinister/threat1.wav", 1, 2);
else if (rnd < 7)
sound(self, CHAN_VOICE, "sinister/threat2.wav", 1, 2);
else
sound(self, CHAN_VOICE, "sinister/threat3.wav", 1, 2);
}
};
void() sin_sightlaugh2 = [ $laugh2, sin_sightlaugh3 ] {};
void() sin_sightlaugh3 = [ $laugh3, sin_sightlaugh4 ] {};
void() sin_sightlaugh4 = [ $laugh4, sin_sightlaugh5 ] {};
void() sin_sightlaugh5 = [ $laugh5, sin_sightlaugh6 ] {};
void() sin_sightlaugh6 = [ $laugh6, sin_sightlaugh7 ] {};
void() sin_sightlaugh7 = [ $laugh7, sin_sightlaugh8 ] {};
void() sin_sightlaugh8 = [ $laugh8, sin_sightlaugh9 ] {};
void() sin_sightlaugh9 = [ $laugh9, sin_sightlaugh10 ] {};
void() sin_sightlaugh10 = [ $laugh10, sin_sightlaugh11 ] {};
void() sin_sightlaugh11 = [ $laugh11, sin_sightlaugh12 ] {};
void() sin_sightlaugh12 = [ $laugh12, sin_sightlaugh1 ]
{
self.count = self.count + 1;
if (self.count >= 4) {
self.count = 0;
self.think = SinisterMissile;
}
};
void() sin_walk1 = [ $walk1, sin_walk2 ] {ai_run(3);};
void() sin_walk2 = [ $walk2, sin_walk3 ] {ai_run(2);};
void() sin_walk3 = [ $walk3, sin_walk4 ] {ai_run(3);};
void() sin_walk4 = [ $walk4, sin_walk5 ] {ai_run(5);};
void() sin_walk5 = [ $walk5, sin_walk6 ] {ai_run(6);};
void() sin_walk6 = [ $walk6, sin_walk7 ] {ai_run(6);};
void() sin_walk7 = [ $walk7, sin_walk8 ] {ai_run(5);};
void() sin_walk8 = [ $walk8, sin_walk9 ] {ai_run(3);};
void() sin_walk9 = [ $walk9, sin_walk10 ] {ai_run(3);};
void() sin_walk10 = [ $walk10, sin_walk11 ] {ai_run(4);};
void() sin_walk11 = [ $walk11, sin_walk12 ] {ai_run(5);};
void() sin_walk12 = [ $walk12, sin_walk1 ] {ai_run(6);};
//============================================================================
void() sin_pain1 = [ $pain1, sin_pain2 ] {};
void() sin_pain2 = [ $pain2, sin_pain3 ] {};
void() sin_pain3 = [ $pain3, sin_pain4 ] {};
void() sin_pain4 = [ $pain4, sin_pain5 ] {};
void() sin_pain5 = [ $pain5, sin_pain6 ] {};
void() sin_pain6 = [ $pain6, sin_pain7 ] {};
void() sin_pain7 = [ $pain7, sin_pain8 ] {};
void() sin_pain8 = [ $pain8, sin_pain9 ] {};
void() sin_pain9 = [ $pain9, sin_walk1 ] {};
void() sin_diss1;
void(entity attacker, float damage) SinisterPain =
{
local float best;
local entity stemp;
if (self.spawnflags & SPAWNFLAG_CLONE) {
self.health = 99999;
return;
}
if (self.x_flags & X_SINISTER_FINAL) {
//self.health =1;
//return;
if (attacker.weapon == IT_SPECIAL_WEAPON) {
if (self.health < 10000) { // special weapon has removed invulnerability
self.health = self.start_health = 500;
self.x_flags = self.x_flags | X_MEGA_HIT;
attacker.currentammo = attacker.ammo_special = 0;
self.th_run();
return;
}
if (self.pain_finished > time)
return;
self.pain_finished = time + 5;
// sin_pain1();
return;
}
if (!(self.x_flags & X_MEGA_HIT)) {
self.health = 99999;
return;
}
if (self.pain_finished > time)
return;
if ((random() * 20) > damage) // don't flinch
return;
self.pain_finished = time + 2;
sin_pain1();
return;
}
else { // move to next spot
sin_diss1();
}
self.health = 99999;
};
//============================================================================
void() sin_guard8;
void() sin_guard1 = [ $guard1, sin_guard2 ] {};
void() sin_guard2 = [ $guard2, sin_guard3 ] {};
void() sin_guard3 = [ $guard3, sin_guard4 ] {};
void() sin_guard4 = [ $guard4, sin_guard5 ] {};
void() sin_guard5 = [ $guard5, sin_guard6 ] {};
void() sin_guard6 = [ $guard6, sin_guard7 ] {self.flags = self.flags | FL_GODMODE;};
void() sin_guard7 = [ $guard7, sin_guard7 ]
{
local entity trav;
trav = world;
while ((trav = find(trav, classname, "guided_rocket")) != world) {
// check that rocket is targetted for self
if (trav.enemy == self) { // uh oh
return;
}
}
// dangerous rocket not found
self.flags = self.flags - (self.flags & FL_GODMODE);
self.think = sin_guard8;
};
void() sin_guard8 = [ $guard8, sin_guard9 ] {};
void() sin_guard9 = [ $guard9, sin_guard10 ] {};
void() sin_guard10 = [ $guard10, sin_guard11 ] {};
void() sin_guard11 = [ $guard11, sin_guard12 ] {};
void() sin_guard12 = [ $guard12, sin_walk1 ] {};
//============================================================================
void() SinisterMissile;
void() SinMissileTouch =
{
if (other == self.owner)
return;
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_EXPLOSION);
WriteCoord (MSG_BROADCAST, self.origin_x);
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
if (other.takedamage == DAMAGE_AIM)
{
spawn_touchblood (5);
T_Damage(other, self, self.owner, 5);
}
remove(self);
};
void(vector org) spawn_sinister_missile =
{
local entity missile, mpuff;
local vector vect;
missile = spawn ();
missile.owner = self;
missile.movetype = MOVETYPE_FLYMISSILE;
missile.solid = SOLID_BBOX;
missile.classname = "sin_missile";
missile.velocity = ProjectVelocity(750, '0 0 0');
missile.angles = vectoangles(missile.velocity);
missile.old_velocity = missile.velocity;
missile.touch = SinMissileTouch;
missile.last_touch = 0;
missile.oldorigin = missile.origin;
missile.nextthink = time + 10;
missile.think = SUB_Remove;
setmodel (missile, "progs/sinblast.mdl");
setsize (missile, '0 0 0', '0 0 0');
setorigin (missile, org);
};
void() sin_xatta1 = [ $xatta1, sin_xatta2 ] {ai_face();};
void() sin_xatta2 = [ $xatta2, sin_xatta3 ] {ai_face();};
void() sin_xatta3 = [ $xatta3, sin_xatta4 ] {ai_face();};
void() sin_xatta4 = [ $xatta4, sin_xatta5 ] {ai_face();};
void() sin_xatta5 = [ $xatta5, sin_xatta6 ]
{
ai_face();
makevectors(self.angles);
spawn_sinister_missile(self.origin + v_right * 4);
spawn_sinister_missile(self.origin + v_right * -4);
};
void() sin_xatta6 = [ $xatta6, sin_xatta7 ] {ai_face();};
void() sin_xatta7 = [ $xatta7, sin_xatta8 ] {ai_face();};
void() sin_xatta8 = [ $xatta8, sin_xatta9 ] {ai_face();};
void() sin_xatta9 = [ $xatta9, sin_xatta10 ] {ai_face();};
void() sin_xatta10 = [ $xatta10, sin_xatta11 ] {ai_face();};
void() sin_xatta11 = [ $xatta11, sin_xatta12 ] {ai_face();};
void() sin_xatta12 = [ $xatta12, sin_walk1 ]
{
if (!(self.x_flags & X_SINISTER_FINAL))
SinisterMissile();
};
void() sin_xattb1 = [ $xattb1, sin_xattb2 ] {ai_face();};
void() sin_xattb2 = [ $xattb2, sin_xattb3 ] {ai_face();};
void() sin_xattb3 = [ $xattb3, sin_xattb4 ]
{
ai_face();
makevectors(self.angles);
spawn_sinister_missile(self.origin + v_right * 4);
};
void() sin_xattb4 = [ $xattb4, sin_xattb5 ] {ai_face();};
void() sin_xattb5 = [ $xattb5, sin_xattb6 ] {ai_face();};
void() sin_xattb6 = [ $xattb6, sin_xattb7 ]
{
ai_face();
makevectors(self.angles);
spawn_sinister_missile(self.origin + v_right * -4);
};
void() sin_xattb7 = [ $xattb7, sin_xattb8 ] {ai_face();};
void() sin_xattb8 = [ $xattb8, sin_xattb9 ] {ai_face();};
void() sin_xattb9 = [ $xattb9, sin_xattb10 ]
{
ai_face();
makevectors(self.angles);
spawn_sinister_missile(self.origin + v_right * 4);
};
void() sin_xattb10 = [ $xattb10, sin_xattb11 ] {ai_face();};
void() sin_xattb11 = [ $xattb11, sin_xattb12 ] {ai_face();};
void() sin_xattb12 = [ $xattb12, sin_walk1 ]
{
if (!(self.x_flags & X_SINISTER_FINAL))
SinisterMissile();
};
void() SinisterMissile =
{
if ((self.x_flags & X_SINISTER_FINAL) && !(self.x_flags & X_MEGA_HIT) && (random() < 0.9)) {
self.count = 0;
sin_sightlaugh1();
return;
}
if (random() < 0.7)
sin_xatta1();
else
sin_xattb1();
};
//============================================================================
void() SinNextSpot =
{
local entity stemp, trav;
if (!(self.x_flags & X_SINISTER_FINAL)) {
self.state = self.state + 1;
self.enemy = world;
stemp = find(world, classname, "xmen_sinister_spot");
while (stemp != world) {
if (stemp.state == self.state) {
spawn_tfog(stemp.origin);
setorigin(self, stemp.origin);
droptofloor();
self.angles = stemp.angles;
self.velocity = '0 0 0';
self.th_stand();
return;
}
else
stemp = find(stemp, classname, "xmen_sinister_spot");
}
// no spot found, so disappear altogether
remove(self);
}
else { // random teleport
stemp = find(world, classname, "xmen_sinister_teleport");
while (stemp != world) {
if ((random() < 0.1) && (vlen(stemp.origin - self.origin) > 128)) {
self.oldorigin = self.origin;
setorigin(self, stemp.origin);
droptofloor();
if (!walkmove(0,0)) {
setorigin(self, self.oldorigin);
}
else {
spawn_tfog(stemp.origin);
self.angles = stemp.angles;
self.velocity = '0 0 0';
self.th_run();
trav = find(world, classname, "guided_rocket");
while (trav != world) {
if (trav.enemy == self)
trav.enemy = world;
trav = find(trav, classname, "guided_rocket");
}
return;
}
}
else {
stemp = find(stemp, classname, "xmen_sinister_teleport");
if (stemp == world) {
stemp = find(world, classname, "xmen_sinister_teleport");
}
}
}
}
};
void() sin_diss1 = [ $diss1, sin_diss2 ] {};
void() sin_diss2 = [ $diss2, sin_diss3 ] {};
void() sin_diss3 = [ $diss3, sin_diss4 ] {};
void() sin_diss4 = [ $diss4, sin_diss5 ] {};
void() sin_diss5 = [ $diss5, sin_diss6 ] {};
void() sin_diss6 = [ $diss6, SinNextSpot ] {spawn_tfog(self.origin);};
//============================================================================
void() sin_death1 = [ $death1, sin_death2 ] {};
void() sin_death2 = [ $death2, sin_death3 ] {};
void() sin_death3 = [ $death3, sin_death4 ] {};
void() sin_death4 = [ $death4, sin_death5 ] {};
void() sin_death5 = [ $death5, sin_death6 ] {};
void() sin_death6 = [ $death6, sin_death7 ] {};
void() sin_death7 = [ $death7, sin_death8 ] {};
void() sin_death8 = [ $death8, sin_death9 ] {};
void() sin_death9 = [ $death9, sin_death10 ] {};
void() sin_death10 = [ $death10, sin_death11 ] {};
void() sin_death11 = [ $death11, sin_death12 ] {};
void() sin_death12 = [ $death12, sin_death13 ] {};
void() sin_death13 = [ $death13, sin_death14 ] {};
void() sin_death14 = [ $death14, sin_death15 ] {};
void() sin_death15 = [ $death15, sin_death16 ] {};
void() sin_death16 = [ $death16, sin_death17 ] {};
void() sin_death17 = [ $death17, sin_death18 ] {};
void() sin_death18 = [ $death18, sin_death19 ] {};
void() sin_death19 = [ $death19, sin_death20 ] {};
void() sin_death20 = [ $death20, sin_death21 ] {};
void() sin_death21 = [ $death21, sin_death22 ] {};
void() sin_death22 = [ $death22, sin_death23 ] {};
void() sin_death23 = [ $death23, sin_death24 ] {};
void() sin_death24 = [ $death24, sin_death25 ] {};
void() sin_death25 = [ $death25, sin_death26 ] {};
void() sin_death26 = [ $death26, sin_death27 ] {};
void() sin_death27 = [ $death27, sin_death28 ] {};
void() sin_death28 = [ $death28, sin_death29 ] {};
void() sin_death29 = [ $death29, sin_death30 ] {};
void() sin_death30 = [ $death30, sin_death31 ] {sound(self, CHAN_VOICE, "sinister/cackle2.wav", 1, 0);};
void() sin_death31 = [ $death31, sin_death32 ] {};
void() sin_death32 = [ $death32, sin_death33 ] {};
void() sin_death33 = [ $death33, sin_death34 ] {spawn_tfog(self.origin);};
void() sin_death34 = [ $death34, sin_death34 ]
{
local entity trav;
killed_monsters = killed_monsters + 1;
WriteByte (MSG_ALL, SVC_KILLEDMONSTER); // FIXME: reliable broadcast
trav = find (world, classname, "player");
while (trav != world)
{
trav.view_ofs = '0 0 0';
trav.nextthink = time + 0.5;
trav.takedamage = DAMAGE_NO;
trav.solid = SOLID_NOT;
trav.movetype = MOVETYPE_NONE;
trav.modelindex = 0;
trav = find (trav, classname, "player");
}
WriteByte (MSG_ALL, SVC_INTERMISSION);
nextmap = "start";
intermission_running = 1;
SUB_UseTargets ();
remove (self);
};
//============================================================================
// Sinister teleport destination, use self.state to set sequence
void() xmen_sinister;
void() xmen_sinister_spot =
{
self.classname = "xmen_sinister";
xmen_sinister();
};
//============================================================================
void() xmen_sinister =
{
if (deathmatch)
{
remove(self);
return;
}
precache_model ("progs/sinister.mdl");
precache_model ("progs/sinblast.mdl");
precache_sound ("sinister/laugh1.wav");
precache_sound ("sinister/laugh2.wav");
precache_sound ("sinister/cackle1.wav");
precache_sound ("sinister/cackle2.wav");
precache_sound ("sinister/cackle3.wav");
precache_sound ("sinister/mrsin1.wav");
precache_sound ("sinister/threat1.wav");
precache_sound ("sinister/threat2.wav");
precache_sound ("sinister/threat3.wav");
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
setmodel (self, "progs/sinister.mdl");
setsize (self, VEC_HULL_MIN, VEC_HULL_MAX);
self.health = 99999;
self.th_stand = sin_stand1;
self.th_walk = sin_stand1;
self.th_run = sin_sightlaugh1;
self.th_pain = SinisterPain;
self.th_die = sin_death1;
self.th_missile = SinisterMissile;
if (!(self.spawnflags & SPAWNFLAG_CLONE))
walkmonster_start();
else {
self.flags = self.flags | FL_GODMODE;
self.think = self.th_stand;
self.nextthink = time + 0.1;
}
self.health = 99999;
};
void() xmen_sinister_final =
{
self.x_flags = self.x_flags | X_SINISTER_FINAL;
self.classname = "xmen_sinister";
xmen_sinister();
self.th_guard = sin_diss5;
self.th_run = sin_walk1;
};
void() xmen_sinister_teleport = {};

102
skeleton.c Normal file
View file

@ -0,0 +1,102 @@
/*
--------
Skeleton
--------
All monsters killed with a Flamethrower change to a skeleton to be "finished off"
*/
void () skeleton_animate =
{
self.frame = self.frame + 1;
if (self.frame > (self.start_frame + 12))
self.frame = self.start_frame;
self.skin = self.skin + 1;
if (self.skin > 3)
self.skin = 0;
if (random()*100 < 1)
sound (self, CHAN_AUTO, "zombie/idle_w2.wav", 1, ATTN_STATIC);
self.think = skeleton_animate;
self.nextthink = time + 0.1;
};
void() skeleton_die =
{
// play crunch sound, and spawn some bone parts
sound(self, CHAN_BODY, "skeleton/crunch.wav", 1, ATTN_NORM);
ThrowGib ("progs/gib01.mdl", self.health);
ThrowGib ("progs/gib02.mdl", self.health);
ThrowGib ("progs/gib02.mdl", self.health);
ThrowGib ("progs/gib02.mdl", self.health);
ThrowGib ("progs/gib02.mdl", self.health);
ThrowGib ("progs/gib03.mdl", self.health);
ThrowGib ("progs/gib03.mdl", self.health);
ThrowGib ("progs/gib03.mdl", self.health);
ThrowGib ("progs/gib03.mdl", self.health);
remove(self);
};
void(entity e) skeleton_morph =
{
local float rnd;
e.classname = "xmen_skeleton";
setmodel(e, "progs/skel.mdl");
// fall from the air
if (e.flags & FL_FLY) {
// e.velocity_z = 100;
// setmodel(e, "progs/skel.mdl");
setsize(e, VEC_HULL_MIN, VEC_HULL_MAX);
// setorigin(e, e.origin + '0 0 1');
e.flags = e.flags - (e.flags & FL_ONGROUND);
e.flags = e.flags - (e.flags & FL_FLY);
e.angles_x = 0;
e.angles_z = 0;
}
else {
setsize(e, VEC_HULL_MIN, VEC_HULL_MAX);
setorigin(e, e.origin - '0 0 1' * e.z_ofs);
}
e.flags = e.flags - (e.flags & FL_GODMODE);
e.x_flags = e.x_flags - (e.x_flags & X_ANGEL_DEFENSE);
rnd = random() * 3;
if (rnd < 1) {
e.start_frame = 0;
}
else if (rnd < 2) {
e.start_frame = 13;
}
else {
e.start_frame = 26;
}
e.frame = e.start_frame;
e.health = 1;
e.think = skeleton_animate;
e.nextthink = time + 0.1;
e.th_die = skeleton_die;
e.th_pain = skeleton_animate;
e.th_guard = skeleton_animate;
e.th_stand = skeleton_animate;
e.th_melee = skeleton_animate;
e.th_missile = skeleton_animate;
e.th_walk = skeleton_animate;
e.th_run = skeleton_animate;
e.th_guard = SUB_Null;
};

575
storm.c Normal file
View file

@ -0,0 +1,575 @@
/*
==============================================================================
Storm
==============================================================================
*/
$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
$frame stand10 stand11 stand12 stand13
$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10 walk11 walk12
$frame run1 run2 run3 run4 run5 run6
$frame wind1 wind2 wind3 wind4 wind5 wind6 wind7 wind8 wind9
$frame wind10 wind11 wind12 wind13 wind14 wind15 wind16
$frame attack1 attack2 attack3 attack4 attack5 attack6 attack7 attack8 attack9 attack10
$frame attack11 attack12 attack13 attack14 attack15 attack16 attack17 attack18 attack19 attack20
$frame paina1 paina2 paina3 paina4 paina5 paina6
$frame pain1 pain2 pain3 pain4 pain5 pain6 pain7 pain8 pain9 pain10
$frame pain11 pain12 pain13 pain14 pain15 pain16 pain17 pain18 pain19 pain20
$frame pain21 pain22 pain23 pain24 pain25 pain26 pain27 pain28 pain29 pain30
$frame pain31 pain32 pain33 pain34 pain35 pain36 pain37 pain38 pain39 pain40
$frame death1 death2 death3 death4 death5 death6 death7 death8 death9
$frame death10 death11 death12 death13 death14 death15 death16
$frame deata1 deata2 deata3 deata4 deata5 deata6 deata7 deata8 deata9
$frame deata10 deata11 deata12 deata13 deata14 deata15 deata16 deata17
/*
$frame hover1 hover2 hover3 hover4 hover5 hover6 hover7 hover8
$frame hover9 hover10 hover11 hover12 hover13 hover14 hover15
$frame fly1 fly2 fly3 fly4 fly5 fly6 fly7 fly8 fly9 fly10
$frame fly11 fly12 fly13 fly14
$frame magatt1 magatt2 magatt3 magatt4 magatt5 magatt6 magatt7
$frame magatt8 magatt9 magatt10 magatt11 magatt12 magatt13
$frame pain1 pain2 pain3 pain4
$frame death1 death2 death3 death4 death5 death6 death7 death8
*/
/*
==============================================================================
Storm
If the player moves behind cover before the missile is launched, launch it
at the last visible spot with no velocity leading, in hopes that the player
will duck back out and catch it.
==============================================================================
*/
void() storm_run1;
void() storm_wind1;
float(float drange) DangerousEntityInRange =
{
local entity trav;
local float strength, dist;
local vector vect, vect_angle;
trav = findradius(self.origin, drange);
while (trav != world) {
// check that the object is damage-able and is infront of self
vect = normalize(trav.origin - self.origin);
vect_angle = vectoangles(vect);
if ((trav != self) &&
(trav.movetype) &&
(fabs( angle_diff( vect_angle_y, self.angles_y)) < 60)) { // dangerous in range
return TRUE;
}
trav = trav.chain;
}
return FALSE;
};
/*
=================
StormCheckAttack
=================
*/
float() StormCheckAttack =
{
local vector spot1, spot2;
local entity targ, trav;
local float chance;
if (time < self.attack_finished)
return FALSE;
if (!enemy_vis)
return FALSE;
// look for a rocket in close vicinity
if ((self.last_wind < (time - 3)) && (DangerousEntityInRange(128))) {
self.attack_state = AS_SLIDING;
storm_wind1 ();
return FALSE;
}
if (enemy_range == RANGE_FAR)
{
if (self.attack_state != AS_STRAIGHT)
{
self.attack_state = AS_STRAIGHT;
storm_run1 ();
}
return FALSE;
}
targ = self.enemy;
// see if any entities are in the way of the shot
spot1 = self.origin + self.view_ofs;
spot2 = targ.origin + targ.view_ofs;
traceline (spot1, spot2, FALSE, self);
if (trace_ent != targ)
{ // don't have a clear shot, so move to a side
if (self.attack_state != AS_STRAIGHT)
{
self.attack_state = AS_STRAIGHT;
storm_run1 ();
}
return FALSE;
}
if ((self.last_wind < (time - 3)) && (vlen(self.enemy.origin - self.origin) < 196)) {
self.attack_state = AS_SLIDING;
storm_wind1 ();
return FALSE;
}
if (enemy_range == RANGE_MELEE)
chance = 0.4;
else if (enemy_range == RANGE_NEAR)
chance = 0.2;
else if (enemy_range == RANGE_MID)
chance = 0.1;
else
chance = 0;
if (random () < chance)
{
self.attack_state = AS_MISSILE;
return TRUE;
}
if (enemy_range == RANGE_MID)
{
if (self.attack_state != AS_STRAIGHT)
{
self.attack_state = AS_STRAIGHT;
storm_run1 ();
}
}
else
{
if (self.attack_state != AS_SLIDING)
{
self.attack_state = AS_SLIDING;
}
}
return FALSE;
};
/*
=================
StormAttackFinished
=================
*/
float() StormAttackFinished =
{
if (enemy_range >= RANGE_MID || !enemy_vis)
{
self.attack_state = AS_STRAIGHT;
self.think = storm_run1;
}
else if (self.last_wind < (time - 3))
{
self.attack_state = AS_SLIDING;
self.think = storm_wind1;
}
};
/*
==============================================================================
FAST ATTACKS
==============================================================================
*/
void() storm_idlesound =
{
local float wr;
return;
wr = random() * 5;
if (self.waitmin < time)
{
self.waitmin = time + 2;
if (wr > 4.5)
sound (self, CHAN_VOICE, "wizard/widle1.wav", 1, ATTN_IDLE);
if (wr < 1.5)
sound (self, CHAN_VOICE, "wizard/widle2.wav", 1, ATTN_IDLE);
}
return;
};
void() storm_stand1 =[ $stand1, storm_stand2 ] {ai_stand();};
void() storm_stand2 =[ $stand2, storm_stand3 ] {ai_stand();};
void() storm_stand3 =[ $stand3, storm_stand4 ] {ai_stand();};
void() storm_stand4 =[ $stand4, storm_stand5 ] {ai_stand();};
void() storm_stand5 =[ $stand5, storm_stand6 ] {ai_stand();};
void() storm_stand6 =[ $stand6, storm_stand7 ] {ai_stand();};
void() storm_stand7 =[ $stand7, storm_stand8 ] {ai_stand();};
void() storm_stand8 =[ $stand8, storm_stand9 ] {ai_stand();};
void() storm_stand9 =[ $stand9, storm_stand10 ] {ai_stand();};
void() storm_stand10 =[ $stand10, storm_stand11 ] {ai_stand();};
void() storm_stand11 =[ $stand11, storm_stand12 ] {ai_stand();};
void() storm_stand12 =[ $stand12, storm_stand13 ] {ai_stand();};
void() storm_stand13 =[ $stand13, storm_stand1 ] {ai_stand();};
void() storm_walk1 =[ $walk1, storm_walk2 ] {ai_walk(8);
storm_idlesound();};
void() storm_walk2 =[ $walk2, storm_walk3 ] {ai_walk(8);};
void() storm_walk3 =[ $walk3, storm_walk4 ] {ai_walk(8);};
void() storm_walk4 =[ $walk4, storm_walk5 ] {ai_walk(8);};
void() storm_walk5 =[ $walk5, storm_walk6 ] {ai_walk(8);};
void() storm_walk6 =[ $walk6, storm_walk7 ] {ai_walk(8);};
void() storm_walk7 =[ $walk7, storm_walk8 ] {ai_walk(8);};
void() storm_walk8 =[ $walk8, storm_walk9 ] {ai_walk(8);};
void() storm_walk9 =[ $walk9, storm_walk10 ] {ai_walk(8);};
void() storm_walk10 =[ $walk10, storm_walk11 ] {ai_walk(8);};
void() storm_walk11 =[ $walk11, storm_walk12 ] {ai_walk(8);};
void() storm_walk12 =[ $walk12, storm_walk1 ] {ai_walk(8);};
void() set_offset =
{
self.origin_z = self.origin_z - self.z_ofs;
self.z_ofs = self.z_ofs + (self.z_ofs_vel * random() * 2);
if (self.z_ofs >= (MAX_Z_OFS)) {
self.z_ofs_vel = -1 * self.z_ofs_vel;
self.z_ofs = MAX_Z_OFS;
}
else if (self.z_ofs <= 0) {
self.z_ofs_vel = -1 * self.z_ofs_vel;
self.z_ofs = 0;
}
else { // add some randomness
if (random() <= 0.1)
self.z_ofs_vel = -1 * self.z_ofs_vel;
}
self.origin_z = self.origin_z + self.z_ofs;
};
void() storm_run1 =[ $run1, storm_run2 ] {
set_offset();
ai_run(6);
storm_idlesound();};
void() storm_run2 =[ $run2, storm_run3 ] {ai_run(6);set_offset();};
void() storm_run3 =[ $run3, storm_run4 ] {ai_run(6);set_offset();};
void() storm_run4 =[ $run4, storm_run5 ] {ai_run(6);set_offset();};
void() storm_run5 =[ $run5, storm_run6 ] {ai_run(6);set_offset();};
void() storm_run6 =[ $run6, storm_run1 ] {ai_run(6);set_offset();};
void() storm_Wind =
{
local entity trav;
local float strength, dist;
local vector vect, vect_angle;
trav = findradius(self.origin, 256);
while (trav != world) {
// check that the object is damage-able and is infront of self
vect = normalize(trav.origin - self.origin);
vect_angle = vectoangles(vect);
if ((trav != self) &&
(trav.classname == "player") &&
(fabs( angle_diff( vect_angle_y, self.angles_y)) < 35)) { // give em some wind
strength = 200;
dist = vlen(trav.origin - self.origin);
if (dist > 128) { // reduce strength of blast
strength = ((dist - 128) / 128) * strength;
}
// blast now
trav.flags = trav.flags - (trav.flags & FL_ONGROUND);
trav.velocity = (trav.velocity * 0.5) + (vect * 600);
trav.velocity_z = 300;
trav.angles = trav.v_angle = self.angles;
trav.punchangle_x = -20;
trav.fixangle = TRUE;
}
trav = trav.chain;
}
self.last_wind = time;
};
void() storm_wind1 =[ $wind1, storm_wind2 ] {ai_face(); self.nextthink = time + 0.05;};
void() storm_wind2 =[ $wind2, storm_wind3 ] {ai_face(); self.nextthink = time + 0.05;};
void() storm_wind3 =[ $wind3, storm_wind4 ] {ai_face(); self.nextthink = time + 0.05;};
void() storm_wind4 =[ $wind4, storm_wind5 ] {ai_face(); self.nextthink = time + 0.05;};
void() storm_wind5 =[ $wind5, storm_wind6 ] {ai_face(); self.nextthink = time + 0.05;};
void() storm_wind6 =[ $wind6, storm_wind7 ] {ai_face(); self.nextthink = time + 0.05;};
void() storm_wind7 =[ $wind7, storm_wind8 ] {ai_face(); sound (self, CHAN_WEAPON, "storm/w_attack.wav", 1, ATTN_NORM); self.nextthink = time + 0.05;};
void() storm_wind8 =[ $wind8, storm_wind9 ] {ai_face(); self.nextthink = time + 0.05;};
void() storm_wind9 =[ $wind9, storm_wind10 ] {ai_face(); self.nextthink = time + 0.05;};
void() storm_wind10 =[ $wind10, storm_wind11 ] {ai_face(); storm_Wind(); self.nextthink = time + 0.05;};
void() storm_wind11 =[ $wind11, storm_wind12 ] {ai_face(); self.nextthink = time + 0.05;};
void() storm_wind12 =[ $wind12, storm_wind13 ] {ai_face(); self.nextthink = time + 0.05;};
void() storm_wind13 =[ $wind13, storm_wind14 ] {ai_face(); self.nextthink = time + 0.05;};
void() storm_wind14 =[ $wind14, storm_wind15 ] {ai_face(); self.nextthink = time + 0.05;};
void() storm_wind15 =[ $wind15, storm_wind16 ] {ai_face(); self.nextthink = time + 0.05;};
void() storm_wind16 =[ $wind16, storm_run1 ] {ai_face(); self.nextthink = time + 0.05;};
void() StormCastLightning =
{
local vector org, dir;
self.effects = self.effects | EF_MUZZLEFLASH;
ai_face ();
org = self.origin + '0 0 40';
dir = self.enemy.origin + '0 0 16' - org - (self.enemy.velocity * 0.5);
dir = normalize (dir);
traceline (org, self.origin + dir*1200, FALSE, self);
sound (self, CHAN_WEAPON, "storm/l_attack.wav", 1, ATTN_NORM);
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_LIGHTNING3);
WriteEntity (MSG_BROADCAST, self);
WriteCoord (MSG_BROADCAST, org_x);
WriteCoord (MSG_BROADCAST, org_y);
WriteCoord (MSG_BROADCAST, org_z - 20);
WriteCoord (MSG_BROADCAST, trace_endpos_x);
WriteCoord (MSG_BROADCAST, trace_endpos_y);
WriteCoord (MSG_BROADCAST, trace_endpos_z);
LightningDamage (org, trace_endpos + dir * 8, self, 20);
};
void() storm_fast1 =[ $attack1, storm_fast2 ] {ai_face();};
void() storm_fast2 =[ $attack2, storm_fast3 ] {ai_face();};
void() storm_fast3 =[ $attack3, storm_fast4 ] {ai_face();};
void() storm_fast4 =[ $attack4, storm_fast5 ] {ai_face();};
void() storm_fast5 =[ $attack5, storm_fast6 ] {ai_face();};
void() storm_fast6 =[ $attack6, storm_fast7 ] {ai_face();};
void() storm_fast7 =[ $attack7, storm_fast8 ] {ai_face();};
void() storm_fast8 =[ $attack8, storm_fast9 ] {ai_face();};
void() storm_fast9 =[ $attack9, storm_fast10 ] {ai_face();};
void() storm_fast10 =[ $attack10, storm_fast11 ] {ai_face();};
void() storm_fast11 =[ $attack11, storm_fast12 ] {ai_face(); StormCastLightning();};
void() storm_fast12 =[ $attack12, storm_fast13 ] {ai_face();};
void() storm_fast13 =[ $attack13, storm_fast14 ] {ai_face();};
void() storm_fast14 =[ $attack14, storm_fast15 ] {ai_face();};
void() storm_fast15 =[ $attack15, storm_fast16 ] {ai_face();};
void() storm_fast16 =[ $attack16, storm_fast17 ] {ai_face();};
void() storm_fast17 =[ $attack17, storm_fast18 ] {ai_face();};
void() storm_fast18 =[ $attack18, storm_fast19 ] {ai_face();};
void() storm_fast19 =[ $attack19, storm_fast20 ] {ai_face();};
void() storm_fast20 =[ $attack20, storm_run1 ] {ai_face();SUB_AttackFinished(2);StormAttackFinished ();};
void() storm_pain1 =[ $pain1, storm_pain2 ] {self.nextthink = time + 0.05;};
void() storm_pain2 =[ $pain2, storm_pain3 ] {self.nextthink = time + 0.05;};
void() storm_pain3 =[ $pain3, storm_pain4 ] {self.nextthink = time + 0.05;};
void() storm_pain4 =[ $pain4, storm_pain5 ] {self.nextthink = time + 0.05;};
void() storm_pain5 =[ $pain5, storm_pain6 ] {self.nextthink = time + 0.05;};
void() storm_pain6 =[ $pain6, storm_pain7 ] {self.nextthink = time + 0.05;};
void() storm_pain7 =[ $pain7, storm_pain8 ] {self.nextthink = time + 0.05;};
void() storm_pain8 =[ $pain8, storm_pain9 ] {self.nextthink = time + 0.05;};
void() storm_pain9 =[ $pain9, storm_pain10 ] {self.nextthink = time + 0.05;};
void() storm_pain10 =[ $pain10, storm_pain11 ] {self.nextthink = time + 0.05;};
void() storm_pain11 =[ $pain11, storm_pain12 ] {self.nextthink = time + 0.05;};
void() storm_pain12 =[ $pain12, storm_pain13 ] {self.nextthink = time + 0.05;};
void() storm_pain13 =[ $pain13, storm_pain14 ] {self.nextthink = time + 0.05;};
void() storm_pain14 =[ $pain14, storm_pain15 ] {self.nextthink = time + 0.05;};
void() storm_pain15 =[ $pain15, storm_pain16 ] {self.nextthink = time + 0.05;};
void() storm_pain16 =[ $pain16, storm_pain17 ] {self.nextthink = time + 0.05;};
void() storm_pain17 =[ $pain17, storm_pain18 ] {self.nextthink = time + 0.05;};
void() storm_pain18 =[ $pain18, storm_pain19 ] {self.nextthink = time + 0.05;};
void() storm_pain19 =[ $pain19, storm_pain20 ] {self.nextthink = time + 0.05;};
void() storm_pain20 =[ $pain20, storm_pain21 ] {self.nextthink = time + 0.05;};
void() storm_pain21 =[ $pain21, storm_pain22 ] {self.nextthink = time + 0.05;};
void() storm_pain22 =[ $pain22, storm_pain23 ] {self.nextthink = time + 0.05;};
void() storm_pain23 =[ $pain23, storm_pain24 ] {self.nextthink = time + 0.05;};
void() storm_pain24 =[ $pain24, storm_pain25 ] {self.nextthink = time + 0.05;};
void() storm_pain25 =[ $pain25, storm_pain26 ] {self.nextthink = time + 0.05;};
void() storm_pain26 =[ $pain26, storm_pain27 ] {self.nextthink = time + 0.05;};
void() storm_pain27 =[ $pain27, storm_pain28 ] {self.nextthink = time + 0.05;};
void() storm_pain28 =[ $pain28, storm_pain29 ] {self.nextthink = time + 0.05;};
void() storm_pain29 =[ $pain29, storm_pain30 ] {self.nextthink = time + 0.05;};
void() storm_pain30 =[ $pain30, storm_pain31 ] {self.in_pain = FALSE;self.nextthink = time + 0.05;};
void() storm_pain31 =[ $pain31, storm_pain32 ] {self.nextthink = time + 0.05;};
void() storm_pain32 =[ $pain32, storm_pain33 ] {self.nextthink = time + 0.05;};
void() storm_pain33 =[ $pain33, storm_pain34 ] {self.nextthink = time + 0.05;};
void() storm_pain34 =[ $pain34, storm_pain35 ] {self.nextthink = time + 0.05;};
void() storm_pain35 =[ $pain35, storm_pain36 ] {self.nextthink = time + 0.05;};
void() storm_pain36 =[ $pain36, storm_pain37 ] {self.nextthink = time + 0.05;};
void() storm_pain37 =[ $pain37, storm_pain38 ] {self.nextthink = time + 0.05;};
void() storm_pain38 =[ $pain38, storm_pain39 ] {self.nextthink = time + 0.05;};
void() storm_pain39 =[ $pain39, storm_pain40 ] {self.nextthink = time + 0.05;};
void() storm_pain40 =[ $pain40, storm_run1 ] {self.nextthink = time + 0.05;};
void() storm_painb1 =[ $paina1, storm_painb2 ] {};
void() storm_painb2 =[ $paina2, storm_painb3 ] {};
void() storm_painb3 =[ $paina3, storm_painb4 ] {};
void() storm_painb4 =[ $paina4, storm_painb5 ] {};
void() storm_painb5 =[ $paina5, storm_painb6 ] {};
void() storm_painb6 =[ $paina6, storm_run1 ] {};
void() storm_death1 =[ $death1, storm_death2 ] {
self.velocity_x = -200 + 400*random();
self.velocity_y = -200 + 400*random();
self.velocity_z = 100 + 100*random();
self.flags = self.flags - (self.flags & FL_ONGROUND);
self.angles_x = 0;
self.angles_z = 0;
};
void() storm_death2 =[ $death2, storm_death3 ] {};
void() storm_death3 =[ $death3, storm_death4 ]{self.solid = SOLID_NOT;};
void() storm_death4 =[ $death4, storm_death5 ] {};
void() storm_death5 =[ $death5, storm_death6 ] {};
void() storm_death6 =[ $death6, storm_death7 ] {};
void() storm_death7 =[ $death7, storm_death8 ] {};
void() storm_death8 =[ $death8, storm_death9 ] {};
void() storm_death9 =[ $death9, storm_death10 ] {};
void() storm_death10 =[ $death10, storm_death11 ] {};
void() storm_death11 =[ $death11, storm_death12 ] {};
void() storm_death12 =[ $death12, storm_death13 ] {};
void() storm_death13 =[ $death13, storm_death14 ] {};
void() storm_death14 =[ $death14, storm_death15 ] {};
void() storm_death15 =[ $death15, storm_death16 ] {};
void() storm_death16 =[ $death16, storm_death16 ] {};
void() storm_deata1 =[ $deata1, storm_deata2 ] {
self.velocity_x = -200 + 400*random();
self.velocity_y = -200 + 400*random();
self.velocity_z = 100 + 100*random();
self.flags = self.flags - (self.flags & FL_ONGROUND);
self.angles_x = 0;
self.angles_z = 0;
};
void() storm_deata2 =[ $deata2, storm_deata3 ] {};
void() storm_deata3 =[ $deata3, storm_deata4 ]{self.solid = SOLID_NOT;};
void() storm_deata4 =[ $deata4, storm_deata5 ] {};
void() storm_deata5 =[ $deata5, storm_deata6 ] {};
void() storm_deata6 =[ $deata6, storm_deata7 ] {};
void() storm_deata7 =[ $deata7, storm_deata8 ] {};
void() storm_deata8 =[ $deata8, storm_deata9 ] {};
void() storm_deata9 =[ $deata9, storm_deata10 ] {};
void() storm_deata10 =[ $deata10, storm_deata11 ] {};
void() storm_deata11 =[ $deata11, storm_deata12 ] {};
void() storm_deata12 =[ $deata12, storm_deata13 ] {};
void() storm_deata13 =[ $deata13, storm_deata14 ] {};
void() storm_deata14 =[ $deata14, storm_deata15 ] {};
void() storm_deata15 =[ $deata15, storm_deata16 ] {};
void() storm_deata16 =[ $deata16, storm_deata17 ] {};
void() storm_deata17 =[ $deata17, storm_deata17 ] {};
void() storm_die =
{
FemaleDeathSound();
if (!(self.deadflag == DEAD_DEAD)) {
if (random() < 0.5)
storm_death1 ();
else
storm_deata1 ();
}
self.deadflag = DEAD_DEAD;
};
void(entity attacker, float damage) storm_Pain =
{
if (self.in_pain) {
return;
}
self.in_pain = TRUE;
FemalePainSound();
if (random()*70 > damage)
return; // didn't flinch
if ((damage > 30) && (random() < 0.3))
storm_pain1 ();
else
storm_painb1 ();
};
void() storm_Missile =
{
storm_fast1();
};
/*QUAKED monster_shambler (1 0 0) (-16 -16 -24) (16 16 40) Ambush
*/
void() monster_shambler =
{
remove(self);
};
void() xmen_storm =
{
if (deathmatch)
{
remove(self);
return;
}
precache_model ("progs/storm2.mdl");
precache_sound ("wizard/hit.wav"); // used by c code
precache_sound ("storm/l_attack.wav");
precache_sound ("storm/w_attack.wav");
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
setmodel (self, "progs/storm2.mdl");
setsize (self, '-16 -16 -24', '16 16 64');
self.health = 150 + cvar("skill")*10;
self.th_stand = storm_stand1;
self.th_walk = storm_walk1;
self.th_run = storm_run1;
self.th_missile = storm_Missile;
self.th_pain = storm_Pain;
self.th_die = storm_die;
self.z_ofs = 0;
self.z_ofs_vel = 1;
// flymonster_start ();
walkmonster_start ();
};

145
tripwire.c Normal file
View file

@ -0,0 +1,145 @@
/* Begin Xmen
Laser Tripwire code revision 2
-cl2-
Additions:
r2:
Cleaned up the code
Changed BlowMeUp() to use self.dmg and to call BecomeExplosion()
Files involved:
tripwire.qc (this file)
client.qc (obituaries)
How to implement in a .map file:
There are two entities that make up a trip wire:
"tripwire_startpoint" and "tripwire_endpoint".
tripwire_startpoint should have a "target" field equal to it's respective
tripwire_endpoint's "targetname" field. (i.e. the endpoint is targeted by the startpoint)
Just stick the two entities near walls (within 64 units). Although it is not *essential*,
the two entities should have an unobstructed view of each other, otherwise the 'laser beam'
effect will not be too believable ;)
*/
void () BlowMeUp =
{
local entity oldself;
if (self.deadflag)
return;
self.deadflag = DEAD_DEAD;
T_RadiusDamage (self, self, self.dmg, self);
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_EXPLOSION);
WriteCoord (MSG_BROADCAST, self.origin_x);
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
BecomeExplosion();
};
// Tripwire scan - watch for some dummy to cross the line.
void () tripwire_scan =
{
traceline(self.origin, self.owner.origin, FALSE, self);
if (trace_fraction != 1)
{
self.owner.think = BlowMeUp;
self.owner.nextthink = time + 0.1;
self.think = BlowMeUp;
self.nextthink = time + 0.1;
return;
}
self.nextthink = time + 0.1;
};
// Tripwire init
void () tripwire_kickit =
{
local entity endpoint;
local vector vec,org;
local vector norm;
endpoint = find(world, targetname, self.target);
// Im using self.owner to knock out a find() in tripwire_scan...
self.owner = endpoint;
vec = normalize(endpoint.origin - self.origin);
traceline(self.origin, self.origin - vec * 64, TRUE, self);
norm = trace_plane_normal;
org = trace_endpos;
self.angles = vectoangles(norm);
makevectors(self.angles);
setorigin(self, org);
self.health = 1;
self.th_die = BlowMeUp;
self.takedamage = DAMAGE_YES;
self.solid = SOLID_BBOX;
setsize(self, '-8 -8 -8', '8 8 8');
traceline(endpoint.origin, endpoint.origin + vec * 64, TRUE, self);
norm = trace_plane_normal;
org = trace_endpos;
endpoint.angles = vectoangles(norm);
makevectors(endpoint.angles);
setorigin(endpoint, org);
endpoint.health = 1;
endpoint.th_die = BlowMeUp;
endpoint.takedamage = DAMAGE_YES;
endpoint.solid = SOLID_BBOX;
setsize(endpoint, '-8 -8 -8', '8 8 8');
self.nextthink = time + 0.1;
self.think = tripwire_scan;
};
// Tripwire endpoint spawn
void () tripwire_endpoint =
{
if (deathmatch) {
remove(self);
return;
}
if (!self.dmg) self.dmg = 120;
if (!self.targetname)
{
objerror("Tripwire_endpoint has no targetname.\n");
}
precache_model("progs/tripwire.mdl");
setmodel(self, "progs/tripwire.mdl");
};
// Tripwire startpoint spawn
void () tripwire_startpoint =
{
if (deathmatch) {
remove(self);
return;
}
if (!self.dmg) self.dmg = 120;
if (!self.target)
{
objerror("Tripwire_startpoint has no target.\n");
}
precache_model("progs/tripwire.mdl");
setmodel(self, "progs/tripwire.mdl");
self.skin = 1;
self.nextthink = time + 0.1;
self.think = tripwire_kickit; // Give tripwire_endpoint a chance to spawn
};
// End Xmen

51
wgun.c Normal file
View file

@ -0,0 +1,51 @@
$modelname wgun
$cd \games\quake\editors\util3d\meshes\wgun
$scale 2.884615
$origin 0 -6 -5
$base wgunbase
$skin wgunbase
$skin wgunbas2
$skin wgunbas3
$skin wgunbas4
$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
$frame stand10 stand11 stand12 stand13
$frame stgun1 stgun2 stgun3 stgun4 stgun5 stgun6 stgun7 stgun8 stgun9
$frame stgun10 stgun11 stgun12 stgun13
$frame run1 run2 run3 run4 run5 run6
$frame rungun1 rungun2 rungun3 rungun4 rungun5 rungun6
$frame pain1 pain2 pain3 pain4 pain5 pain6
$frame pgun1 pgun2 pgun3 pgun4 pgun5 pgun6
$frame deatha1 deatha2 deatha3 deatha4 deatha5 deatha6 deatha7 deatha8 deatha9
$frame deatha10 deatha11 deatha12
$frame dguna1 dguna2 dguna3 dguna4 dguna5 dguna6 dguna7 dguna8 dguna9
$frame dguna10 dguna11 dguna12
$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8 deathb9
$frame deathb10 deathb11 deathb12
$frame dgunb1 dgunb2 dgunb3 dgunb4 dgunb5 dgunb6 dgunb7 dgunb8 dgunb9
$frame dgunb10 dgunb11 dgunb12
$frame shot1 shot2 shot3 shot4 shot5 shot6 shot7 shot8 shot9
$frame shot10 shot11 shot12 shot13 shot14 shot15 shot16 shot17 shot18
$frame rock1 rock2 rock3 rock4 rock5 rock6 rock7 rock8 rock9
$frame rock10 rock11 rock12
$frame chain1 chain2 chain3 chain4 chain5 chain6
$frame bolt1 bolt2 bolt3 bolt4 bolt5 bolt6
$frame xatta1 xatta2 xatta3 xatta4 xatta5 xatta6 xatta7 xatta8 xatta9 xatta10
$frame xatta11 xatta12
$frame xattb1 xattb2 xattb3 xattb4 xattb5 xattb6 xattb7 xattb8
$frame xattb9 xattb10 xattb11 xattb12

736
wolvie.c Normal file
View file

@ -0,0 +1,736 @@
/*
==============================================================================
WOLVERINE
==============================================================================
*/
$cd id1/models/demon3
$scale 0.8
$origin 0 0 24
$base base
$skin base
.float in_pain;
$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
$frame stand10 stand11 stand12 stand13
$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8
$frame run1 run2 run3 run4 run5 run6
$frame leap1 leap2 leap3 leap4 leap5 leap6 leap7 leap8 leap9 leap10
$frame leap11 leap12
$frame pain1 pain2 pain3 pain4 pain5 pain6
$frame paina1 paina2 paina3 paina4 paina5 paina6 paina7 paina8 paina9 paina10
$frame paina11 paina12 paina13 paina14 paina15 paina16 paina17 paina18 paina19 paina20
$frame paina21 paina22 paina23 paina24 paina25 paina26 paina27 paina28 paina29 paina30
$frame paina31 paina32 paina33 paina34 paina35 paina36 paina37 paina38
$frame death1 death2 death3 death4 death5 death6 death7 death8 death9
$frame death10 death11 death12 death13 death14 death15 death16 death17
$frame rise1 rise2 rise3 rise4 rise5 rise6 rise7 rise8 rise9
$frame rise10 rise11 rise12 rise13 rise14 rise15 rise16 rise17 rise18 rise19 rise20
$frame rise21 rise22 rise23 rise24 rise25 rise26 rise27 rise28 rise29 rise30 rise31
$frame deata1 deata2 deata3 deata4 deata5 deata6 deata7 deata8 deata9 deata10
$frame deata11 deata12 deata13 deata14 deata15 deata16 deata17 deata18 deata19 deata20
$frame deata21 deata22 deata23 deata24 deata25 deata26 deata27 deata28 deata29 deata30
$frame deata31 deata32 deata33 deata34 deata35 deata36 deata37 deata38 deata39 deata40
$frame deata41 deata42 deata43 deata44 deata45 deata46 deata47 deata48 deata49
$frame risea1 risea2 risea3 risea4 risea5 risea6 risea7 risea8 risea9 risea10
$frame risea11 risea12 risea13 risea14 risea15 risea16 risea17 risea18 risea19 risea20
$frame risea21 risea22 risea23 risea24 risea25 risea26 risea27 risea28 risea29 risea30
$frame risea31 risea32 risea33 risea34 risea35 risea36 risea37 risea38 risea39 risea40
$frame risea41 risea42 risea43 risea44 risea45 risea46 risea47 risea48 risea49 risea50
$frame risea51 risea52
$frame attacka1 attacka2 attacka3 attacka4 attacka5 attacka6 attacka7 attacka8
$frame attacka9 attacka10 attacka11 attacka12 attacka13 attacka14 attacka15
//============================================================================
void() Demon_JumpTouch;
void() demon1_stand1 =[ $stand1, demon1_stand2 ] {
ai_stand();
sound(self, CHAN_AUTO, "wolvie/breath.wav", 1, 3);};
void() demon1_stand2 =[ $stand2, demon1_stand3 ] {ai_stand();};
void() demon1_stand3 =[ $stand3, demon1_stand4 ] {ai_stand();};
void() demon1_stand4 =[ $stand4, demon1_stand5 ] {ai_stand();};
void() demon1_stand5 =[ $stand5, demon1_stand6 ] {ai_stand();};
void() demon1_stand6 =[ $stand6, demon1_stand7 ] {ai_stand();};
void() demon1_stand7 =[ $stand7, demon1_stand8 ] {ai_stand();};
void() demon1_stand8 =[ $stand8, demon1_stand9 ] {ai_stand();};
void() demon1_stand9 =[ $stand9, demon1_stand10 ] {ai_stand();};
void() demon1_stand10 =[ $stand10, demon1_stand11 ] {ai_stand();};
void() demon1_stand11 =[ $stand11, demon1_stand12 ] {ai_stand();};
void() demon1_stand12 =[ $stand12, demon1_stand13 ] {ai_stand();};
void() demon1_stand13 =[ $stand13, demon1_stand1 ] {ai_stand();};
void() demon1_walk1 =[ $walk1, demon1_walk2 ] {ai_walk(3);};
void() demon1_walk2 =[ $walk2, demon1_walk3 ] {ai_walk(10);};
void() demon1_walk3 =[ $walk3, demon1_walk4 ] {ai_walk(9);};
void() demon1_walk4 =[ $walk4, demon1_walk5 ] {ai_walk(10);};
void() demon1_walk5 =[ $walk5, demon1_walk6 ] {ai_walk(3);};
void() demon1_walk6 =[ $walk6, demon1_walk7 ] {ai_walk(8);};
void() demon1_walk7 =[ $walk7, demon1_walk8 ] {ai_walk(7);};
void() demon1_walk8 =[ $walk8, demon1_walk1 ] {ai_walk(10);};
void() demon1_run1 =[ $run1, demon1_run2 ] {
ai_run(15);
/*sound(self, CHAN_AUTO, "wolvie/step.wav", 1, ATTN_NORM);*/};
void() demon1_run2 =[ $run2, demon1_run3 ] {ai_run(12);};
void() demon1_run3 =[ $run3, demon1_run4 ] {ai_run(28);};
void() demon1_run4 =[ $run4, demon1_run5 ] {ai_run(15);};
void() demon1_run5 =[ $run5, demon1_run6 ] {
ai_run(12);
/*sound(self, CHAN_AUTO, "wolvie/step.wav", 1, ATTN_NORM);*/};
void() demon1_run6 =[ $run6, demon1_run1 ] {ai_run(28);};
void() SetJumpAngle =
{
local vector vel;
vel = normalize(self.velocity);
self.angles = vectoangles(vel);
if (self.angles_x < 0)
self.angles_x = 0;
};
void() demon1_jump1 =[ $leap1, demon1_jump2 ] {ai_face();};
void() demon1_jump2 =[ $leap2, demon1_jump3 ] {ai_face();};
void() demon1_jump3 =[ $leap3, demon1_jump4 ] {ai_face();};
void() demon1_jump4 =[ $leap4, demon1_jump5 ]
{
ai_face();
self.touch = Demon_JumpTouch;
self.angles = vectoangles(self.enemy.origin - self.origin);
self.angles_x = 0;
makevectors (self.angles);
self.origin_z = self.origin_z + 1;
v_forward_z = -1 * v_forward_z;
self.velocity = v_forward * 700 + '0 0 150';
if (self.flags & FL_ONGROUND)
self.flags = self.flags - FL_ONGROUND;
};
void() demon1_jump5 =[ $leap5, demon1_jump6 ] {SetJumpAngle();};
void() demon1_jump6 =[ $leap6, demon1_jump7 ] {SetJumpAngle();};
void() demon1_jump7 =[ $leap7, demon1_jump8 ] {SetJumpAngle();};
void() demon1_jump8 =[ $leap8, demon1_jump9 ] {SetJumpAngle();};
void() demon1_jump9 =[ $leap9, demon1_jump10 ]
{
SetJumpAngle();
};
void() demon1_jump10 =[ $leap10, demon1_jump1 ] {
self.nextthink = time + 3;
// if three seconds pass, assume demon is stuck and jump again
};
void() demon1_jump11 =[ $leap11, demon1_jump12 ] {};
void() demon1_jump12 =[ $leap12, demon1_walk1 ] {self.angles_x = 0;};
float() CheckDemonMelee;
void() demon1_atta1 =[ $attacka1, demon1_atta2 ] {ai_charge(5);};
void() demon1_atta2 =[ $attacka2, demon1_atta3 ] {ai_charge(5);};
void() demon1_atta3 =[ $attacka3, demon1_atta4 ] {ai_charge(5);};
void() demon1_atta4 =[ $attacka4, demon1_atta5 ] {ai_charge(5);};
void() demon1_atta5 =[ $attacka5, demon1_atta6 ] {ai_charge(5); Demon_Melee(200);};
void() demon1_atta6 =[ $attacka6, demon1_atta7 ] {ai_charge(5);};
void() demon1_atta7 =[ $attacka7, demon1_atta8 ]
{
ai_charge(5);
if (vlen(self.enemy.origin - self.origin) > 100) { // abort attack
self.think = self.th_run;
}
};
void() demon1_atta8 =[ $attacka8, demon1_atta9 ] {ai_charge(5);};
void() demon1_atta9 =[ $attacka9, demon1_atta10] {ai_charge(5);};
void() demon1_atta10 =[ $attacka10, demon1_atta11] {ai_charge(5);};
void() demon1_atta11 =[ $attacka11, demon1_atta12]
{
local float rnd;
Demon_Melee(-200);
};
void() demon1_atta12 =[ $attacka12, demon1_atta13] {ai_charge(5);};
void() demon1_atta13 =[ $attacka13, demon1_atta14] {ai_charge(5);};
void() demon1_atta14 =[ $attacka14, demon1_atta15] {ai_charge(5);};
void() demon1_atta15 =[ $attacka15, demon1_run1] {
ai_charge(5);
if (CheckDemonMelee()) {
if (self.enemy.health > 0)
self.think = demon1_atta1;
else
self.think = self.th_walk;
}
};
void() demon1_pain1 =[ $pain1, demon1_pain2 ] {self.in_pain = TRUE;};
void() demon1_pain2 =[ $pain2, demon1_pain3 ] {};
void() demon1_pain3 =[ $pain3, demon1_pain4 ] {};
void() demon1_pain4 =[ $pain4, demon1_pain5 ] {};
void() demon1_pain5 =[ $pain5, demon1_pain6 ] {};
void() demon1_pain6 =[ $pain6, demon1_run1 ] {self.in_pain = FALSE;};
void() demon1_paina1 =[ $paina1, demon1_paina2 ] {self.in_pain = TRUE;};
void() demon1_paina2 =[ $paina2, demon1_paina3 ] {};
void() demon1_paina3 =[ $paina3, demon1_paina4 ] {};
void() demon1_paina4 =[ $paina4, demon1_paina5 ] {};
void() demon1_paina5 =[ $paina5, demon1_paina6 ] {};
void() demon1_paina6 =[ $paina6, demon1_paina7 ] {};
void() demon1_paina7 =[ $paina7, demon1_paina8 ] {};
void() demon1_paina8 =[ $paina8, demon1_paina9 ] {};
void() demon1_paina9 =[ $paina9, demon1_paina10 ] {};
void() demon1_paina10 =[ $paina10, demon1_paina11 ] {};
void() demon1_paina11 =[ $paina11, demon1_paina12 ] {};
void() demon1_paina12 =[ $paina12, demon1_paina13 ] {};
void() demon1_paina13 =[ $paina13, demon1_paina14 ] {};
void() demon1_paina14 =[ $paina14, demon1_paina15 ] {};
void() demon1_paina15 =[ $paina15, demon1_paina16 ] {};
void() demon1_paina16 =[ $paina16, demon1_paina17 ] {};
void() demon1_paina17 =[ $paina17, demon1_paina18 ] {};
void() demon1_paina18 =[ $paina18, demon1_paina19 ] {};
void() demon1_paina19 =[ $paina19, demon1_paina20 ] {};
void() demon1_paina20 =[ $paina20, demon1_paina21 ] {};
void() demon1_paina21 =[ $paina21, demon1_paina22 ] {};
void() demon1_paina22 =[ $paina22, demon1_paina23 ] {};
void() demon1_paina23 =[ $paina23, demon1_paina24 ] {};
void() demon1_paina24 =[ $paina24, demon1_paina25 ] {};
void() demon1_paina25 =[ $paina25, demon1_paina26 ] {};
void() demon1_paina26 =[ $paina26, demon1_paina27 ] {};
void() demon1_paina27 =[ $paina27, demon1_paina28 ] {};
void() demon1_paina28 =[ $paina28, demon1_paina29 ] {};
void() demon1_paina29 =[ $paina29, demon1_paina30 ] {};
void() demon1_paina30 =[ $paina30, demon1_paina31 ] {};
void() demon1_paina31 =[ $paina31, demon1_paina32 ] {};
void() demon1_paina32 =[ $paina32, demon1_paina33 ] {};
void() demon1_paina33 =[ $paina33, demon1_paina34 ] {};
void() demon1_paina34 =[ $paina34, demon1_paina35 ] {};
void() demon1_paina35 =[ $paina35, demon1_paina36 ] {};
void() demon1_paina36 =[ $paina36, demon1_paina37 ] {};
void() demon1_paina37 =[ $paina37, demon1_run1 ] {self.in_pain = FALSE;};
void(entity attacker, float damage) demon1_pain =
{
local vector vect;
local float rnd;
if (self.touch == Demon_JumpTouch)
return;
if (self.pain_finished > time)
return;
self.pain_finished = time + 1;
MalePainSound(2);
if (random()*200 > damage)
return; // didn't flinch
if (attacker.classname == "player") {
self.enemy = attacker;
}
if (self.in_pain)
return;
if (damage > 60)
demon1_paina1 ();
else
demon1_pain1 ();
};
void() demon1_die17;
void() demon1_rise1 =[ $rise1, demon1_rise2]
{
self.solid = SOLID_SLIDEBOX;
if (!walkmove(0,0)) {
self.think = demon1_rise1;
self.solid = SOLID_NOT;
self.nextthink = time + 1; // try again in 1 second
return;
}
self.skin = 0;
self.speed = self.speed - 0.35;
self.health = self.start_health * self.speed;
SetDamageSkin(self);
};
void() demon1_rise2 =[ $rise2, demon1_rise3] {};
void() demon1_rise3 =[ $rise3, demon1_rise4] {};
void() demon1_rise4 =[ $rise4, demon1_rise5] {};
void() demon1_rise5 =[ $rise5, demon1_rise6] {};
void() demon1_rise6 =[ $rise6, demon1_rise7] {};
void() demon1_rise7 =[ $rise7, demon1_rise8] {};
void() demon1_rise8 =[ $rise8, demon1_rise9] {};
void() demon1_rise9 =[ $rise9, demon1_rise10] {};
void() demon1_rise10 =[ $rise10, demon1_rise11] {};
void() demon1_rise11 =[ $rise11, demon1_rise12] {};
void() demon1_rise12 =[ $rise12, demon1_rise13] {};
void() demon1_rise13 =[ $rise13, demon1_rise14] {};
void() demon1_rise14 =[ $rise14, demon1_rise15] {};
void() demon1_rise15 =[ $rise15, demon1_rise16] {};
void() demon1_rise16 =[ $rise16, demon1_rise17] {};
void() demon1_rise17 =[ $rise17, demon1_rise18] {};
void() demon1_rise18 =[ $rise18, demon1_rise19] {};
void() demon1_rise19 =[ $rise19, demon1_rise20] {};
void() demon1_rise20 =[ $rise20, demon1_rise21] {};
void() demon1_rise21 =[ $rise21, demon1_rise22] {};
void() demon1_rise22 =[ $rise22, demon1_rise23] {};
void() demon1_rise23 =[ $rise23, demon1_rise24] {};
void() demon1_rise24 =[ $rise24, demon1_rise25] {};
void() demon1_rise25 =[ $rise25, demon1_rise26] {};
void() demon1_rise26 =[ $rise26, demon1_rise27] {};
void() demon1_rise27 =[ $rise27, demon1_rise28] {};
void() demon1_rise28 =[ $rise28, demon1_rise29] {};
void() demon1_rise29 =[ $rise29, demon1_rise30] {};
void() demon1_rise30 =[ $rise30, demon1_rise31] {};
void() demon1_rise31 =[ $rise31, demon1_run1]
{
// self.solid = SOLID_SLIDEBOX;
// self.movetype = MOVETYPE_STEP;
// self.enemy = world;
self.takedamage = DAMAGE_AIM;
};
void() demon1_die1 =[ $death1, demon1_die2 ] {};
void() demon1_die2 =[ $death2, demon1_die3 ] {};
void() demon1_die3 =[ $death3, demon1_die4 ] {};
void() demon1_die4 =[ $death4, demon1_die5 ] {};
void() demon1_die5 =[ $death5, demon1_die6 ] {};
void() demon1_die6 =[ $death6, demon1_die7 ] {self.solid = SOLID_NOT;};
void() demon1_die7 =[ $death7, demon1_die8 ] {};
void() demon1_die8 =[ $death8, demon1_die9 ] {};
void() demon1_die9 =[ $death9, demon1_die10 ] {};
void() demon1_die10 =[ $death10, demon1_die11 ] {};
void() demon1_die11 =[ $death11, demon1_die12 ] {};
void() demon1_die12 =[ $death12, demon1_die13 ] {};
void() demon1_die13 =[ $death13, demon1_die14 ] {};
void() demon1_die14 =[ $death14, demon1_die15 ] {};
void() demon1_die15 =[ $death15, demon1_die16 ] {};
void() demon1_die16 =[ $death16, demon1_die17 ] {};
void() demon1_die17 =[ $death17, demon1_die17 ]
{
if (self.speed < 0.4)
return;
self.in_pain = FALSE;
if (!(self.spawnflags & SPAWNFLAG_CLONE)) {
self.think = demon1_rise1;
self.nextthink = time + 20* random() + 20;
}
};
void() demon1_risea1;
void() demon1_diea1 =[ $deata1, demon1_diea2 ] {};
void() demon1_diea2 =[ $deata2, demon1_diea3 ] {};
void() demon1_diea3 =[ $deata3, demon1_diea4 ] {};
void() demon1_diea4 =[ $deata4, demon1_diea5 ] {};
void() demon1_diea5 =[ $deata5, demon1_diea6 ] {self.solid = SOLID_NOT;};
void() demon1_diea6 =[ $deata6, demon1_diea7 ] {};
void() demon1_diea7 =[ $deata7, demon1_diea8 ] {};
void() demon1_diea8 =[ $deata8, demon1_diea9 ] {};
void() demon1_diea9 =[ $deata9, demon1_diea10 ] {};
void() demon1_diea10 =[ $deata10, demon1_diea11 ] {};
void() demon1_diea11 =[ $deata11, demon1_diea12 ] {};
void() demon1_diea12 =[ $deata12, demon1_diea13 ] {};
void() demon1_diea13 =[ $deata13, demon1_diea14 ] {};
void() demon1_diea14 =[ $deata14, demon1_diea15 ] {};
void() demon1_diea15 =[ $deata15, demon1_diea16 ] {};
void() demon1_diea16 =[ $deata16, demon1_diea17 ] {};
void() demon1_diea17 =[ $deata17, demon1_diea18 ] {};
void() demon1_diea18 =[ $deata18, demon1_diea19 ] {};
void() demon1_diea19 =[ $deata19, demon1_diea20 ] {};
void() demon1_diea20 =[ $deata20, demon1_diea21 ] {};
void() demon1_diea21 =[ $deata21, demon1_diea22 ] {};
void() demon1_diea22 =[ $deata22, demon1_diea23 ] {};
void() demon1_diea23 =[ $deata23, demon1_diea24 ] {};
void() demon1_diea24 =[ $deata24, demon1_diea25 ] {};
void() demon1_diea25 =[ $deata25, demon1_diea26 ] {};
void() demon1_diea26 =[ $deata26, demon1_diea27 ] {};
void() demon1_diea27 =[ $deata27, demon1_diea28 ] {};
void() demon1_diea28 =[ $deata28, demon1_diea29 ] {};
void() demon1_diea29 =[ $deata29, demon1_diea30 ] {};
void() demon1_diea30 =[ $deata30, demon1_diea31 ] {};
void() demon1_diea31 =[ $deata31, demon1_diea32 ] {};
void() demon1_diea32 =[ $deata32, demon1_diea33 ] {};
void() demon1_diea33 =[ $deata33, demon1_diea34 ] {};
void() demon1_diea34 =[ $deata34, demon1_diea35 ] {};
void() demon1_diea35 =[ $deata35, demon1_diea36 ] {};
void() demon1_diea36 =[ $deata36, demon1_diea37 ] {};
void() demon1_diea37 =[ $deata37, demon1_diea38 ] {};
void() demon1_diea38 =[ $deata38, demon1_diea39 ] {};
void() demon1_diea39 =[ $deata39, demon1_diea40 ] {};
void() demon1_diea40 =[ $deata40, demon1_diea41 ] {};
void() demon1_diea41 =[ $deata41, demon1_diea42 ] {};
void() demon1_diea42 =[ $deata42, demon1_diea43 ] {};
void() demon1_diea43 =[ $deata43, demon1_diea44 ] {};
void() demon1_diea44 =[ $deata44, demon1_diea45 ] {};
void() demon1_diea45 =[ $deata45, demon1_diea46 ] {};
void() demon1_diea46 =[ $deata46, demon1_diea47 ] {};
void() demon1_diea47 =[ $deata47, demon1_diea48 ] {};
void() demon1_diea48 =[ $deata48, demon1_diea49 ] {};
void() demon1_diea49 =[ $deata49, demon1_diea49 ]
{
local float rise_delay;
if (self.speed < 0.4)
return;
self.in_pain = FALSE;
if (!(self.spawnflags & SPAWNFLAG_CLONE)) {
self.think = demon1_risea1;
rise_delay = (-0.5 * self.health) + 15;
if (rise_delay > 45) rise_delay = 45;
else if (rise_delay < 20) rise_delay = 20;
self.nextthink = time + rise_delay;
}
};
void() demon1_risea1 =[ $risea1, demon1_risea2 ]
{
self.solid = SOLID_SLIDEBOX;
if (!walkmove(0,0)) {
self.think = demon1_risea1;
self.solid = SOLID_NOT;
self.nextthink = time + 1; // try again in 1 second
return;
}
self.skin = 0;
self.speed = self.speed - 0.35;
self.health = self.start_health * self.speed;
SetDamageSkin(self);
};
void() demon1_risea2 =[ $risea2, demon1_risea3 ] {};
void() demon1_risea3 =[ $risea3, demon1_risea4 ] {};
void() demon1_risea4 =[ $risea4, demon1_risea5 ] {};
void() demon1_risea5 =[ $risea5, demon1_risea6 ] {};
void() demon1_risea6 =[ $risea6, demon1_risea7 ] {};
void() demon1_risea7 =[ $risea7, demon1_risea8 ] {};
void() demon1_risea8 =[ $risea8, demon1_risea9 ] {};
void() demon1_risea9 =[ $risea9, demon1_risea10 ] {};
void() demon1_risea10 =[ $risea10, demon1_risea11 ] {};
void() demon1_risea11 =[ $risea11, demon1_risea12 ] {};
void() demon1_risea12 =[ $risea12, demon1_risea13 ] {};
void() demon1_risea13 =[ $risea13, demon1_risea14 ] {};
void() demon1_risea14 =[ $risea14, demon1_risea15 ] {};
void() demon1_risea15 =[ $risea15, demon1_risea16 ] {};
void() demon1_risea16 =[ $risea16, demon1_risea17 ] {};
void() demon1_risea17 =[ $risea17, demon1_risea18 ] {};
void() demon1_risea18 =[ $risea18, demon1_risea19 ] {};
void() demon1_risea19 =[ $risea19, demon1_risea20 ] {};
void() demon1_risea20 =[ $risea20, demon1_risea21 ] {};
void() demon1_risea21 =[ $risea21, demon1_risea22 ] {};
void() demon1_risea22 =[ $risea22, demon1_risea23 ] {};
void() demon1_risea23 =[ $risea23, demon1_risea24 ] {};
void() demon1_risea24 =[ $risea24, demon1_risea25 ] {};
void() demon1_risea25 =[ $risea25, demon1_risea26 ] {};
void() demon1_risea26 =[ $risea26, demon1_risea27 ] {};
void() demon1_risea27 =[ $risea27, demon1_risea28 ] {};
void() demon1_risea28 =[ $risea28, demon1_risea29 ] {};
void() demon1_risea29 =[ $risea29, demon1_risea30 ] {};
void() demon1_risea30 =[ $risea30, demon1_risea31 ] {};
void() demon1_risea31 =[ $risea31, demon1_risea32 ] {};
void() demon1_risea32 =[ $risea32, demon1_risea33 ] {};
void() demon1_risea33 =[ $risea33, demon1_risea34 ] {};
void() demon1_risea34 =[ $risea34, demon1_risea35 ] {};
void() demon1_risea35 =[ $risea35, demon1_risea36 ] {};
void() demon1_risea36 =[ $risea36, demon1_risea37 ] {};
void() demon1_risea37 =[ $risea37, demon1_risea38 ] {};
void() demon1_risea38 =[ $risea38, demon1_risea39 ] {};
void() demon1_risea39 =[ $risea39, demon1_risea40 ] {};
void() demon1_risea40 =[ $risea40, demon1_risea41 ] {};
void() demon1_risea41 =[ $risea41, demon1_risea42 ] {};
void() demon1_risea42 =[ $risea42, demon1_risea43 ] {};
void() demon1_risea43 =[ $risea43, demon1_risea44 ] {};
void() demon1_risea44 =[ $risea44, demon1_risea45 ] {};
void() demon1_risea45 =[ $risea45, demon1_risea46 ] {};
void() demon1_risea46 =[ $risea46, demon1_risea47 ] {};
void() demon1_risea47 =[ $risea47, demon1_risea48 ] {};
void() demon1_risea48 =[ $risea48, demon1_risea49 ] {};
void() demon1_risea49 =[ $risea49, demon1_risea50 ] {};
void() demon1_risea50 =[ $risea50, demon1_risea51 ] {};
void() demon1_risea51 =[ $risea51, demon1_risea52 ] {};
void() demon1_risea52 =[ $risea52, demon1_run1 ]
{
self.takedamage = DAMAGE_AIM;
};
void() demon_die =
{
local float rnd;
self.angles_x = 0;
self.skin = 3;
MaleDeathSound(2);
// regular death
rnd = random();
if ((self.health < -20) && (rnd < 0.7))
demon1_diea1 ();
else if (rnd < 0.3)
demon1_diea1 ();
else
demon1_die1 ();
};
void() Demon_MeleeAttack =
{
demon1_atta1 ();
};
/*QUAKED monster_demon1 (1 0 0) (-32 -32 -24) (32 32 64) Ambush
*/
void() monster_demon1 =
{
remove(self);
};
void() xmen_wolverine =
{
if (deathmatch)
{
remove(self);
return;
}
precache_model ("progs/wolvie2.mdl");
// precache_model ("progs/h_demon.mdl");
// XMen Matched ID sounds
// precache_sound ("hknight/sight1.wav");
precache_sound ("demon/dhit2.wav");
// precache_sound ("demon/djump.wav");
// precache_sound ("demon/idle1.wav");
// Wolvie sounds
precache_sound ("wolvie/breath.wav");
// end
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
setmodel (self, "progs/wolvie2.mdl");
setsize (self, VEC_HULL_MIN, VEC_HULL_MAX);
self.health = 210 + cvar("skill")*10;
self.speed = 1; // used to reduce health for each regen.
self.in_pain = FALSE;
self.th_stand = demon1_stand1;
self.th_walk = demon1_walk1;
self.th_run = demon1_run1;
self.th_die = demon_die;
self.th_melee = Demon_MeleeAttack; // one of two attacks
self.th_missile = demon1_jump1; // jump attack
self.th_pain = demon1_pain;
walkmonster_start();
};
/*
==============================================================================
DEMON
==============================================================================
*/
/*
==============
CheckDemonMelee
Returns TRUE if a melee attack would hit right now
==============
*/
float() CheckDemonMelee =
{
// if (enemy_range == RANGE_MELEE)
// { // FIXME: check canreach
if (vlen(self.enemy.origin - self.origin) < 128) {
self.attack_state = AS_MELEE;
return TRUE;
}
// }
return FALSE;
};
/*
==============
CheckDemonJump
==============
*/
float() CheckDemonJump =
{
local vector dist;
local float d;
if (random() < 0.9)
return FALSE;
if (vlen(self.origin - self.enemy.origin) > 512)
return FALSE;
if (self.origin_z + self.mins_z > self.enemy.origin_z + self.enemy.mins_z
+ 0.75 * self.enemy.size_z)
return FALSE;
if (self.origin_z + self.maxs_z < self.enemy.origin_z + self.enemy.mins_z
+ 0.25 * self.enemy.size_z)
return FALSE;
traceline(self.origin, self.enemy.origin, TRUE, self);
if (trace_fraction < 1)
return FALSE;
/*
dist = self.enemy.origin - self.origin;
dist_z = 0;
d = vlen(dist);
if (d < 100)
return FALSE;
if (d > 200)
{
// if (random() < 0.9)
return FALSE;
}
*/
return TRUE;
};
float() DemonCheckAttack =
{
local vector vec;
local float rnd;
// if close enough for slashing, go for it
if ((CheckDemonMelee ()) && (self.health > 50))
{
self.attack_state = AS_MELEE;
return TRUE;
}
if (CheckDemonJump ())
{
self.attack_state = AS_MISSILE;
return TRUE;
}
return FALSE;
};
//===========================================================================
void(float side) Demon_Melee =
{
local float ldmg;
local vector delta;
ai_face ();
walkmove (self.ideal_yaw, 12); // allow a little closing
delta = self.enemy.origin - self.origin;
if (vlen(delta) > 64)
return;
if (!CanDamage (self.enemy, self))
return;
ldmg = 4 + random() * 2;
ldmg = rint(ldmg);
sound (self, CHAN_WEAPON, "demon/dhit2.wav", 1, ATTN_NORM);
T_Damage (self.enemy, self, self, ldmg);
makevectors (self.angles);
SpawnMeatSpray (self.origin + v_forward*16, side * v_right);
};
void() Demon_JumpTouch =
{
local float ldmg;
local vector dir;
if (self.health <= 0)
return;
// check for enemy getting hit
dir = normalize(self.velocity);
traceline(self.origin, self.origin + dir * 64, FALSE, self);
if ((trace_ent != world) && (trace_ent == self.enemy)) {
ldmg = (5 * cvar("skill")) + 10*random();
T_Damage (other, self, self, ldmg);
trace_ent.punchangle_x = -10;
}
// if (other.takedamage)
// {
// if ( vlen(self.velocity) > 400 )
// {
// ldmg = (5 * cvar("skill")) + 10*random();
// T_Damage (other, self, self, ldmg);
// }
// }
if (!checkbottom(self))
{
if (self.flags & FL_ONGROUND)
{ // jump randomly to not get hung up
//dprint ("popjump\n");
self.touch = SUB_Null;
self.think = demon1_jump1;
self.nextthink = time + 0.1;
// self.velocity_x = (random() - 0.5) * 600;
// self.velocity_y = (random() - 0.5) * 600;
// self.velocity_z = 200;
// self.flags = self.flags - FL_ONGROUND;
}
return; // not on ground yet
}
self.touch = SUB_Null;
self.think = demon1_jump11;
self.nextthink = time + 0.1;
};

53
x_ambient.c Normal file
View file

@ -0,0 +1,53 @@
void() ambient_water_leaky_pipe =
{
precache_sound ("ambience/water/leakpipe.wav");
ambientsound (self.origin, "ambience/water/leaky_pipe.wav", 1, ATTN_STATIC);
};
void() ambient_water_sewer =
{
precache_sound ("ambience/water/sewer.wav");
ambientsound (self.origin, "ambience/water/sewer.wav", 1, ATTN_STATIC);
};
void() ambient_water_flow_light =
{
precache_sound ("ambience/water/flowlght.wav");
ambientsound (self.origin, "ambience/water/flowlght.wav", 1, ATTN_STATIC);
};
void() ambient_water_stream_heavy =
{
precache_sound ("ambience/water/strmhvy.wav");
ambientsound (self.origin, "ambience/water/strmhvy.wav", 1, ATTN_STATIC);
};
void() ambient_water_stream_light =
{
precache_sound ("ambience/water/strmlght.wav");
ambientsound (self.origin, "ambience/water/strmlght.wav", 1, ATTN_STATIC);
};
void() ambient_water_tunnel_light =
{
precache_sound ("ambience/water/tnnl_lt.wav");
ambientsound (self.origin, "ambience/water/tnnl_lt.wav", 1, ATTN_STATIC);
};
void() ambient_airhose =
{
precache_sound ("ambience/airhose.wav");
ambientsound (self.origin, "ambience/airhose.wav", 1, ATTN_STATIC);
};
void() ambient_drill =
{
precache_sound ("ambience/drill_x.wav");
ambientsound (self.origin, "ambience/drill_x.wav", 1, ATTN_STATIC);
};
void() xmen_ambient =
{
precache_sound (self.noise);
ambientsound (self.origin, self.noise, 1, ATTN_STATIC);
};

103
x_cam.c Normal file
View file

@ -0,0 +1,103 @@
// X-Men chase-cam
float SVC_SETVIEWPORT = 5;
.entity chasecam;
vector CAM_OFFSET = '-36 0 6'; // forward, right, up
vector CAM_ORIGIN_OFFSET = '-8 0 8';
float CAM_TRACKSPEED = 0.5;
void(entity player) DisableCam =
{
if (player.chasecam == world)
return;
msg_entity = player; // target of message
WriteByte (MSG_ONE, SVC_SETVIEWPORT);
WriteEntity (MSG_ONE, player); // view port
stuffcmd(player, "cl_bobup 1\n");
stuffcmd(player, "r_drawviewmodel 1\n");
remove(player.chasecam);
player.chasecam = world;
};
void(entity player) InitCam =
{
local entity cam;
if (player.chasecam != world)
return;
cam = spawn();
player.chasecam = cam;
cam.owner=player;
cam.solid = SOLID_NOT;
cam.movetype = MOVETYPE_NONE;
cam.angles = cam.owner.angles;
setmodel (cam, "progs/eyes.mdl" );
setsize (cam, '0 0 0', '0 0 0');
setorigin( cam, cam.owner.origin );
cam.classname = "cam";
msg_entity = cam.owner; // target of message
WriteByte (MSG_ONE, SVC_SETVIEWPORT);
WriteEntity (MSG_ONE, cam); // view port
stuffcmd(player, "cl_bobup 0\n");
stuffcmd(player, "r_drawviewmodel 0\n");
};
void() CamThink =
{
local vector pos, vec, org, angle;
local float dist;
angle = self.owner.v_angle;
angle_x = 0;
makevectors(angle);
org = self.owner.origin + v_up * CAM_ORIGIN_OFFSET_z
+ v_forward * CAM_ORIGIN_OFFSET_x;
makevectors(self.owner.v_angle);
pos = org + v_forward * CAM_OFFSET_x
+ v_right * CAM_OFFSET_y
+ v_up * CAM_OFFSET_z;
if ((self.owner.character == CHAR_STORM) ||
(self.owner.character == CHAR_ANGEL))
{
pos = pos + v_up * 12;
}
vec = normalize(pos - org);
traceline(org, pos, TRUE, world);
dist = vlen(pos - self.origin);
if (trace_fraction == 1) { // check ceiling
traceline(org, pos + '0 0 32', TRUE, world);
if (trace_fraction < 1)
trace_endpos = trace_endpos - '0 0 32';
}
if (trace_fraction < 1) {
if (trace_ent == world) // move away from wall
setorigin(self, trace_endpos + trace_plane_normal * 8);
else
setorigin(self, trace_endpos - vec * 4);
}
else { // move towards ideal pos
if (vlen((pos - self.origin) * frametime * dist * CAM_TRACKSPEED) < dist)
setorigin(self, self.origin + ((pos - self.origin) * frametime * dist * CAM_TRACKSPEED));
else
setorigin(self, pos);
}
};

63
x_debug.c Normal file
View file

@ -0,0 +1,63 @@
void() xmen_monster_test =
{
if (cvar("coop") == 1)
{
self.classname = "xmen_wolverine";
xmen_wolverine();
}
else if (cvar("coop") == 2)
{
self.classname = "xmen_storm";
xmen_storm();
}
else if (cvar("coop") == 3)
{
self.classname = "xmen_cyclops";
xmen_cyclops();
}
else if (cvar("coop") == 4)
{
self.classname = "xmen_psylocke";
xmen_psylocke();
}
else if (cvar("coop") == 5)
{
self.classname = "xmen_angel";
xmen_angel();
}
else if (cvar("coop") == 6)
{
self.classname = "xmen_beast";
xmen_beast();
}
else if (cvar("coop") == 7)
{
self.classname = "xmen_gambit";
xmen_gambit();
}
else if (cvar("coop") == 8) {
self.map = "brown";
self.classname = "xmen_iceman";
xmen_iceman();
}
else if (cvar("coop") == 9)
{
self.classname = "xmen_bishop";
xmen_bishop();
}
else if (cvar("coop") == 10)
{
self.classname = "xmen_rogue";
xmen_rogue();
}
else if (cvar("coop") == 11)
{
self.classname = "xmen_cannonball";
xmen_cannonball();
}
else if (cvar("coop") == 12)
{
self.classname = "xmen_phoenix";
xmen_phoenix();
}
};

476
x_misc.c Normal file
View file

@ -0,0 +1,476 @@
string(float char) GetCharacterString =
{
if (char == CHAR_WOLVERINE)
return "Wolverine";
if (char == CHAR_STORM)
return "Storm";
if (char == CHAR_CYCLOPS)
return "Cyclops";
if (char == CHAR_PSYLOCKE)
return "Psylocke";
if (char == CHAR_ANGEL)
return "Angel";
if (char == CHAR_BEAST)
return "Beast";
if (char == CHAR_GAMBIT)
return "Gambit";
if (char == CHAR_ICEMAN)
return "Iceman";
if (char == CHAR_BISHOP)
return "Bishop";
if (char == CHAR_ROGUE)
return "Rogue";
if (char == CHAR_CANNONBALL)
return "Cannonball";
if (char == CHAR_PHOENIX)
return "Phoenix";
};
// This is an adaption of the Wizard missile prediction code
vector(float mspeed, vector target_offset) ProjectVelocity =
{
local vector vec, move;
local float fly;
makevectors (self.angles);
// set missile speed
vec = self.enemy.origin - self.origin + target_offset;
// calc aproximate time for missile to reach vec
fly = vlen (vec) / mspeed;
// get the entities xy velocity
move = self.enemy.velocity;
move_z = 0;
// project the target forward in time
vec = vec + move * (fly * 0.75);
vec = normalize(vec);
return (vec * mspeed);
};
//==========================================================================
void() xmen_post =
{
if (self.style == 1) {
precache_model ("progs/posta.spr");
setmodel(self, "progs/posta.spr");
}
else if (self.style == 2) {
precache_model ("progs/postb.spr");
setmodel(self, "progs/postb.spr");
}
else if (self.style == 3) {
precache_model ("progs/postc.spr");
setmodel(self, "progs/postc.spr");
}
else if (self.style == 4) {
precache_model ("progs/postd.spr");
setmodel(self, "progs/postd.spr");
}
};
//==========================================================================
// Special Weapon stuff
void() MagnetoThink =
{
local vector ang;
makevectors(self.owner.v_angle);
setorigin(self, self.owner.origin + v_forward * 70 + '0 0 22');
ang = self.owner.v_angle; //vectoangles(v_forward * 1);
if (executable == "glQuake") // fixes upside-down magneto sprite
ang_z = 180;
// ang_x = -1 * ang_x;
self.angles = ang;
if (random() < 0.5)
self.frame = rint(random() * 7);
self.nextthink = time + 0.01;
};
void() WeaponMessage =
{
local entity magneto;
if (/*(self.last_flame < (time - 24)) ||*/ ((self.last_flame < (time - 3)) && (self.owner.button2))) {
magneto = find(world, classname, "magneto_sprite");
if (magneto != world)
remove(magneto);
centerprint(self.owner, "");
remove(self);
return;
}
if (self.speed)
centerprint(self.owner, self.noise1);
else
centerprint(self.owner, self.noise);
self.nextthink = time + 0.1;
};
void(float newwpn) SetNewWeapon;
void() ImpulseCommands;
void() weapon_piece_touch =
{
local entity magneto, oself;
if (other.classname != "player")
return;
self.owner = other;
other.weapon_parts = other.weapon_parts + 1;
sound (other, CHAN_ITEM, "items/protect.wav", 1, ATTN_NORM);
stuffcmd (other, "bf\n");
self.solid = SOLID_NOT;
self.model = string_null;
self.classname = ""; // so rune doors won't find it
serverflags = serverflags | self.items;
if ((world.model == "maps/x1end.bsp") || (world.model == "maps/x2end.bsp")) // must be the final weapon component, so activate the Mega-Weapon!
{
// make sure they have all the components
if (serverflags & 15) {
other.items = other.items | IT_SPECIAL_WEAPON;
oself = self;
self = other;
self.ammo_special = 255;
// SetNewWeapon(IT_SPECIAL_WEAPON);
self.impulse = 13;
ImpulseCommands();
self.currentammo = self.ammo_special;
self = oself;
}
}
// centerprint(other, self.noise);
if (self.speed == other.weapon_parts)
self.speed = 0;
self.last_flame = time;
self.think = WeaponMessage;
self.nextthink = time + 0.1;
// spawn magneto sprite thinker
magneto = spawn();
magneto.classname = "magneto_sprite";
magneto.owner = other;
setmodel(magneto, "progs/magneto.spr");
magneto.think = MagnetoThink;
magneto.nextthink = time + 0.01;
};
void() StartItem;
void() xmen_weapon_part =
{
if (deathmatch) {
remove(self);
return;
}
if (world.model == "maps/x1m1.bsp") {
precache_model("progs/comp1_1.mdl");
setmodel(self, "progs/comp1_1.mdl");
self.items = 1;
self.noise = "Well done. You have found the\nfirst part of the only weapon\nable to defeat Apocalypse.\n\nYou will find other components\nthat have been seperated and\nhidden by Apocalypse. If you\nare unsuccessful the age of\nApocalypse will be unavoidable...\n\nGood luck.\n\n(press JUMP when ready)";
/*
Well done. You have found the
first part of the only weapon
able to defeat Apocalypse.\n
You will find other components
that have\nbeen seperated and
hidden by Apocalypse. If you
are unsuccessful the age of
Apocalypse will be unavoidable...\n
Good luck.\n\n(press JUMP when ready)
*/
}
else if (world.model == "maps/x1m2.bsp") {
precache_model("progs/comp1_2.mdl");
setmodel(self, "progs/comp1_2.mdl");
self.items = 2;
self.noise = "You have done well. your quest\nbecomes more important by the\nhour. Even as I speak Apocalypses\nclones are taking over every\nworld power. You are earth's\nonly hope for survival.\n\n(press JUMP when ready)";
/*
You have done well. your quest\n
becomes more important by the\n
hour. Even as I speak Apocalypses\n
clones are taking over every\n
world power. You are earth's\n
only hope for survival.\n\n(press JUMP when ready)
*/
}
else if (world.model == "maps/x1m3.bsp") {
precache_model("progs/comp1_3.mdl");
setmodel(self, "progs/comp1_3.mdl");
self.items = 4;
self.noise = "By destroying the cloning\ncomputer you have successfully\nstopped the production of this\nevil army of clones. You have\ngreatly threatened Apocalypses\nplans, but you must still rid\nthe world of the remaining\nclones and ensure that Apocalypse\ncan never attempt this again.\n\n(press JUMP when ready)";
/*
By destroying the cloning\n
computer you have successfully\n
stopped the production of this\n
evil army of clones. You have\n
greatly threatened Apocalypses\n
plans, but you must still rid\n
the world of the remaining\n
clones and ensure that Apocalypse\n
can never attempt this again.\n\n(press JUMP when ready)
*/
}
else if (world.model == "maps/x1m4.bsp") {
precache_model("progs/comp1_4.mdl");
setmodel(self, "progs/comp1_4.mdl");
self.items = 8;
self.speed = 4;
self.noise = "You are getting closer to\nApocalypses sanctuary. You now\nhave all the weapon components.\nAll you need now is enough power\nto activate it. Step carefully.\nApocalypse is bound to have many\ndefences surrounding his lair.\n\n(press JUMP when ready)";
/*
You are getting closer to\n
Apocalypses sanctuary. You now\n
have all the weapon components.\n
All you need now is enough power\n
to activate it. Step carefully.\n
Apocalypse is bound to have many\n
defences surrounding his lair.\n\n(press JUMP when ready)
*/
self.noise1 = "You are getting closer to\nApocalypse's sanctuary. You\nhave the final weapon component,\nbut you will need to get all the\nothers to defeat Apocalypse. Step\ncarefully. Apocalypse is bound to\nhave many defenses surrounding\nhis lair.\n\n(press JUMP when ready)";
/*
You are getting closer to\n
Apocalypse's sanctuary. You\n
have the final weapon component,\n
but you will need to get all the\n
others to defeat Apocalypse. Step\n
carefully. Apocalypse is bound to\n
have many defenses surrounding\n
his lair.\n
*/
}
else if (world.model == "maps/x1end.bsp") {
precache_model("progs/comp1_5.mdl");
setmodel(self, "progs/comp1_5.mdl");
self.speed = 5;
self.noise = "You have found a power pack\ncapable of activating the\nweapon for a short time. Use it\nwisely.\n\n(press JUMP when ready)";
self.noise1 = "You have found a power pack\ncapable of activating the\nweapon for a short time.\n\nUnfortunately you have not\ngot all the weapon components.\n\nYou will need to go back to\nget them before being able to\ndefeat Apocalypse.\n\n(press JUMP when ready)";
/*
You have found a power pack\n
capable of activating the\n
weapon for a short time.\n
Unfortunately you have not\n
got all the weapon components.\n
You will need to go back to\n
get them before being able to\n
defeat Apocalypse.
*/
}
else if (world.model == "maps/x2m1.bsp") {
precache_model("progs/comp2_1.mdl");
setmodel(self, "progs/comp2_1.mdl");
self.items = 1;
self.noise = "Now that you have defeated\nApocalypse you must find the\nother 3 components of the weapon\nthat must be used to defeat\nApocalypses sinister accomplice.\n\n(press JUMP when ready)";
/*
Now that you have defeated\n
Apocalypse you must find the\n
other 3 components of the weapon\n
that must be used to defeat\n
Apocalypses sinister accomplis.\n\n(press JUMP when ready)
*/
}
else if (world.model == "maps/x2m2.bsp") {
precache_model("progs/comp2_2.mdl");
setmodel(self, "progs/comp2_2.mdl");
self.items = 2;
self.speed = 2;
self.noise = "You are doing well. There are\nonly 2 more components to be\nfound. Keep an eye out for clues\nalong your journey.\n\n(press JUMP when ready)";
/*
You are doing well. There are\n
only 2 more components to be\n
found. Keep an eye out for clues\n
along your journey.\n\n(press JUMP when ready)
*/
self.noise1 = "You are doing well. You have\nmissed one of the weapon\ncomponents, you will need\nto have it before completing\nyour quest. Keep an eye out\nfor clues along the way.\n\n(press JUMP when ready)";
/*
You are doing well. You have\n
missed one of the weapon\n
components, you will need\n
to have it before completing\n
your quest. Keep an eye out\n
for clues along the way.
*/
}
else if (world.model == "maps/x2m3.bsp") {
precache_model("progs/comp2_3.mdl");
setmodel(self, "progs/comp2_3.mdl");
self.items = 4;
self.noise = "The weapon components were\nscattered farther than I had\nhoped. This is a minor set back.\nYou are getting closer to\nfinding Apocalypses evil\npartner.\n\n(press JUMP when ready)";
/*
The weapon components were\n
scattered farther than I had\n
hoped. This is a minor set back.\n
You are getting closer to\n
finding Apocalypses evil\n
partner.\n\n(press JUMP when ready)
*/
}
else if (world.model == "maps/x2m4.bsp") {
precache_model("progs/comp2_4.mdl");
setmodel(self, "progs/comp2_4.mdl");
self.items = 8;
self.speed = 4;
self.noise = "You are very close now I feel.\nNow that you have found the 4\nparts to the weapon, you must\nagain\nfind sufficient power to\nactivate it.\n\n(press JUMP when ready)";
/*
You are very close now I feel.\n
Now that you have found the 4\n
parts to the weapon, you must\n
again\nfind sufficient power to\n
activate it.\n\n(press JUMP when ready)";
*/
self.noise1 = "You are very close now, I feel,\nbut you have not got all 4\nparts to the weapon. Once you\nhave, you must again find\nsufficient power to activate it.\n\n(press JUMP when ready)";
/*
You are very close now, I feel,\n
but you have not got all 4\n
parts to the weapon. Once you\n
have, you must again find\n
sufficient power to activate it.
*/
}
else if (world.model == "maps/x2end.bsp") {
precache_model("progs/comp2_5.mdl");
setmodel(self, "progs/comp2_5.mdl");
self.speed = 5;
self.noise = "The weapon is now functional.\n\nUse it well.\n\n(press JUMP when ready)";
self.noise1 = "You have the power pack,\nbut not all of the weapon\ncomponents. You must find\nthese before defeating Mr\nSinister.\n\n(press JUMP when ready)";
/*
You have the power pack,\n
but not all of the weapon\n
components. You must find\n
these before defeating Mr\n
Sinister.
*/
}
else {
precache_model("progs/comp1_1.mdl");
setmodel(self, "progs/comp1_1.mdl");
self.noise = "Special Weapon: unknown level name";
}
precache_model("progs/magneto.spr");
self.touch = weapon_piece_touch;
setsize (self, '-8 -8 0', '8 8 32');
StartItem ();
};
//==========================================================================
void(entity ent) SetDamageSkin =
{
if (deathmatch)
return;
if (ent.classname == "player")
return;
if (ent.classname == "xmen_techdude")
return;
if (((ent.classname == "xmen_sinister") || (ent.classname == "apocalypse_small")) && !(ent.x_flags & X_MEGA_HIT))
return;
if (show_damage) {
bprint(ftos((ent.health * 100) / ent.start_health));
bprint("% damage\n");
}
// set damage skin
if ((ent.health / ent.start_health) < 0.33)
ent.skin = 2;
else if ((ent.health / ent.start_health) < 0.66)
ent.skin = 1;
else
ent.skin = 0;
};
//==========================================================================
void() item_furniture =
{
precache_model(self.model);
setmodel(self, self.model);
};
//==========================================================================
void() SUB_regen;
void() RapidTouch =
{
if (other.classname != "player")
return;
if (other.health <= 0)
return;
sprint(other, "You got the Rapid Fire!\n");
sound(other, CHAN_ITEM, "misc/rapid.wav", 1, ATTN_NORM);
other.rapid_time = time + 25;
other.x_flags = other.x_flags | X_RAPID_FIRE;
// other.items = other.items | IT_INVISIBILITY;
stuffcmd (other, "bf\n");
self.solid = SOLID_NOT;
self.mdl = self.model;
self.model = string_null;
if (deathmatch) {
self.nextthink = time + 40;
self.think = SUB_regen;
}
};
void() item_rapid_fire =
{
precache_model("progs/rapid.mdl");
precache_sound("misc/rapid.wav");
precache_sound("misc/rapidout.wav");
setmodel(self, "progs/rapid.mdl");
setsize (self, '-16 -16 -24', '16 16 32');
self.touch = RapidTouch;
StartItem();
};
void(entity client, string s) centerprint =
{
client.last_centerprint = s;
do_centerprint(client, s);
};

150
x_sound.c Normal file
View file

@ -0,0 +1,150 @@
// type = 1 for big characters like Beast and Bishop, 2 for normal/smaller characters
void(float type) MalePainSound =
{
local float rnd;
if (type == 1) {
rnd = random() * 5;
if (rnd < 1)
sound(self, CHAN_BODY, "voice/male/pain1.wav", 1, ATTN_NORM);
else if (rnd < 2)
sound(self, CHAN_BODY, "voice/male/pain2.wav", 1, ATTN_NORM);
else if (rnd < 3)
sound(self, CHAN_BODY, "voice/male/pain3.wav", 1, ATTN_NORM);
else if (rnd < 4)
sound(self, CHAN_BODY, "voice/male/pain4.wav", 1, ATTN_NORM);
else
sound(self, CHAN_BODY, "voice/male/pain5.wav", 1, ATTN_NORM);
}
else if (type == 2) {
rnd = random() * 2;
if (rnd < 1)
sound(self, CHAN_BODY, "voice/male/pain6.wav", 1, ATTN_NORM);
else
sound(self, CHAN_BODY, "voice/male/pain7.wav", 1, ATTN_NORM);
}
};
// type = 1 for big characters like Beast and Bishop, 2 for normal/smaller characters
void(float type) MaleDeathSound =
{
local float rnd;
if (type == 1) {
rnd = random() * 3;
if (rnd < 1)
sound(self, CHAN_BODY, "voice/male/diescrm1.wav", 1, ATTN_NORM);
else if (rnd < 2)
sound(self, CHAN_BODY, "voice/male/diescrm2.wav", 1, ATTN_NORM);
else if (rnd < 3)
sound(self, CHAN_BODY, "voice/male/diescrm3.wav", 1, ATTN_NORM);
}
else if (type == 2) {
rnd = random() * 3;
if (rnd < 1)
sound(self, CHAN_BODY, "voice/male/diescrm4.wav", 1, ATTN_NORM);
else if (rnd < 2)
sound(self, CHAN_BODY, "voice/male/diescrm5.wav", 1, ATTN_NORM);
else if (rnd < 3)
sound(self, CHAN_BODY, "voice/male/diescrm6.wav", 1, ATTN_NORM);
}
};
// type = 1 for big characters like Beast and Bishop, 2 for normal/smaller characters
void(float type) MaleSightSound =
{
local float rnd;
return; // disable all ICU sounds
if (type == 1) {
rnd = random() * 2;
if (rnd < 1)
sound(self, CHAN_BODY, "voice/male/growl.wav", 1, ATTN_NORM);
else if (rnd < 2)
sound(self, CHAN_BODY, "voice/male/grrr.wav", 1, ATTN_NORM);
}
else if (type == 2) {
rnd = random() * 6;
if (rnd < 1)
sound(self, CHAN_BODY, "voice/male/intruder.wav", 1, ATTN_NORM);
else if (rnd < 2)
sound(self, CHAN_BODY, "voice/male/stop01.wav", 1, ATTN_NORM);
else if (rnd < 3)
sound(self, CHAN_BODY, "voice/male/uh-a.wav", 1, ATTN_NORM);
else if (rnd < 4)
sound(self, CHAN_BODY, "voice/male/what.wav", 1, ATTN_NORM);
else if (rnd < 5)
sound(self, CHAN_BODY, "voice/male/what_the.wav", 1, ATTN_NORM);
else if (rnd < 6)
sound(self, CHAN_BODY, "voice/male/youthere.wav", 1, ATTN_NORM);
}
};
void() FemalePainSound =
{
local float rnd;
rnd = random() * 6;
if (rnd < 1)
sound(self, CHAN_BODY, "voice/female/scream1.wav", 1, ATTN_NORM);
else if (rnd < 2)
sound(self, CHAN_BODY, "voice/female/scream2.wav", 1, ATTN_NORM);
else if (rnd < 3)
sound(self, CHAN_BODY, "voice/female/scream3.wav", 1, ATTN_NORM);
else if (rnd < 4)
sound(self, CHAN_BODY, "voice/female/no1.wav", 1, ATTN_NORM);
else if (rnd < 5)
sound(self, CHAN_BODY, "voice/female/scream4.wav", 1, ATTN_NORM);
else if (rnd < 6)
sound(self, CHAN_BODY, "voice/female/scream5.wav", 1, ATTN_NORM);
};
void() FemaleDeathSound =
{
local float rnd;
rnd = random() * 3;
if (rnd < 1)
sound(self, CHAN_BODY, "voice/female/diescrm1.wav", 1, ATTN_NORM);
else if (rnd < 2)
sound(self, CHAN_BODY, "voice/female/diescrm2.wav", 1, ATTN_NORM);
else if (rnd < 3)
sound(self, CHAN_BODY, "voice/female/diescrm3.wav", 1, ATTN_NORM);
else if (rnd < 4)
sound(self, CHAN_BODY, "voice/female/diescrm4.wav", 1, ATTN_NORM);
else if (rnd < 5)
sound(self, CHAN_BODY, "voice/female/diescrm5.wav", 1, ATTN_NORM);
};
void() FemaleSightSound =
{
local float rnd;
return; // disable all ICU sounds
rnd = random() * 4;
if (rnd < 1)
sound(self, CHAN_BODY, "voice/female/hey.wav", 1, ATTN_NORM);
else if (rnd < 2)
sound(self, CHAN_BODY, "voice/female/hey_you.wav", 1, ATTN_NORM);
else if (rnd < 3)
sound(self, CHAN_BODY, "voice/female/stop.wav", 1, ATTN_NORM);
else if (rnd < 4)
sound(self, CHAN_BODY, "voice/female/wait.wav", 1, ATTN_NORM);
};

190
x_tech.c Normal file
View file

@ -0,0 +1,190 @@
$frame a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16
$frame b1 b2 b3 b4 b5 b6 b7 b8 b9 b10
$frame d1 d2 d3 d4 d5 d6 d7 d8 d9 d10
$frame d11 d12 d13 d14 d15 d16 d17 d18 d19 d20
$frame d21 d22 d23 d24 d25 d26 d27 d28 d29 d30
$frame d31 d32 d33 d34 d35 d36 d37 d38 d39 d40
$frame d41 d42 d43 d44 d45 d46
$frame death1 death2 death3 death4 death5 death6 death7 death8 death9 death10 death11 death12
$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10
$frame walk11 walk12
$frame walka1 walka2 walka3 walka4 walka5 walka6 walka7 walka8 walka9 walka10
$frame walka11 walka12
$frame duck1 duck2 duck3 duck4 duck5 duck6
$frame cower1 cower2
void() tech_die =
{
self.deadflag = DEAD_DEAD;
self.solid = SOLID_NOT;
self.takedamage = DAMAGE_NO;
if ((self.frame < $death1 ) || (self.frame > $death12 ))
self.frame = $death1;
else
self.frame = self.frame + 1;
if (self.frame == $death12 ) {
self.nextthink = -1;
return;
}
self.think = tech_die;
self.nextthink = time + 0.1;
};
void() tech_hide1 = [ $duck1, tech_hide2 ] {};
void() tech_hide2 = [ $duck2, tech_hide3 ] {};
void() tech_hide3 = [ $duck3, tech_hide4 ] {};
void() tech_hide4 = [ $duck4, tech_hide5 ] {};
void() tech_hide5 = [ $duck5, tech_hide6 ] {};
void() tech_hide6 = [ $duck6, tech_cower1 ] {};
void() tech_cower1 = [ $cower1, tech_cower2 ] {};
void() tech_cower2 = [ $cower2, tech_cower1 ] {};
void() tech_think =
{
local entity plyr, btn, oself;
local vector oldpos, vectmove, anglemove;
self.frame = self.frame + 1;
if (self.frame > self.last_frame) {
self.frame = self.start_frame;
if ((self.tech_state != TECH_WALKING) && (random() < 0.5)) // somewhat randomize the speed of animation
self.speed = 0.1;
else
self.speed = 0.05;
}
if (self.tech_state == TECH_WALKING) { // move towards target switch
oldpos = self.origin;
movetogoal(6);
vectmove = normalize(self.origin - oldpos);
anglemove = vectoangles(vectmove);
self.ideal_yaw = anglemove_y;
ChangeYaw();
if (vlen(self.origin - self.movetarget.origin) < 64) { // fire button, start hiding
//bprint("tech firing target\n");
oself = self;
activator = self;
self = self.movetarget.owner;
if (self.use)
self.use();
// else {
// objerror("Technician target doesn't have a use function\n");
// }
self = oself;
remove(self.movetarget);
self.tech_state = TECH_HIDING;
tech_hide1();
return;
}
}
else if ((self.tech_state == TECH_IDLE) && (self.target != "") && (self.frame == self.start_frame)) { // check for sighting intruder
plyr = world;
while ((plyr = find(plyr, classname, "player")) != world) {
// check if visible
traceline(self.origin + '0 0 16', plyr.origin + '0 0 16', TRUE, world);
if (trace_fraction == 1) { // player is visible
if ((btn = find(world, targetname, self.target)) == world) {
bprint("xmen_techdude: cannot find target\n");
}
else {
self.movetarget = spawn();
self.enemy = self.goalentity = self.movetarget;
self.movetarget.owner = btn;
self.movetarget.origin = btn.absmin + ((btn.absmax - btn.absmin) * 0.5);
}
self.speed = 0.05;
self.tech_state = TECH_WALKING;
// if (random() < 0.5) {
self.start_frame = self.frame = $walk1;
self.last_frame = $walk12;
// }
// else {
// self.start_frame = self.frame = $walka1;
// self.last_frame = $walka12;
// }
}
}
}
self.nextthink = time + self.speed;
};
void() tech_pain =
{
self.health = self.health; // should we play a sound here?
};
void() tech_drop =
{
droptofloor();
/*
if (!walkmove(0,0)) {
bprint("xmen_techdude fell out of level at ");
bprint(vtos(self.origin));
bprint("\n");
}
*/
self.think = tech_think;
self.nextthink = time + self.speed;
};
void() xmen_techdude =
{
local string str;
local float rnd;
if (deathmatch) {
remove(self);
return;
}
precache_model("progs/tech.mdl");
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
setmodel(self, "progs/tech.mdl");
setsize(self, VEC_HULL_MIN, VEC_HULL_MAX);
rnd = random() * 3;
if (rnd <= 1) {
self.start_frame = $a1;
self.last_frame = $a16;
}
else if (rnd <= 2) {
self.start_frame = $b1;
self.last_frame = $b10;
}
else {
self.start_frame = $d1;
self.last_frame = $d46;
}
self.tech_state = TECH_IDLE;
self.yaw_speed = 90;
self.takedamage = DAMAGE_AIM;
self.health = self.start_health = 25;
self.th_die = tech_die;
self.th_pain = tech_pain;
self.speed = 0.1; // speed of animation
self.think = tech_drop;
self.nextthink = time + 0.2;
};