Merge pull request #9 from NeonKnightOA/pvsfixes

Adding struct checks to files. This solves countless of issues and bugs.
This commit is contained in:
Yamagi 2020-02-04 09:27:34 +01:00 committed by GitHub
commit c49cb3982d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
56 changed files with 7058 additions and 1430 deletions

View file

@ -72,6 +72,11 @@ This replaces the QC functions: ai_forward, ai_back, ai_pain, and ai_painforward
*/
void ai_move (edict_t *self, float dist)
{
if (!self)
{
return;
}
M_walkmove (self, self->s.angles[YAW], dist);
}
@ -88,6 +93,11 @@ void ai_stand (edict_t *self, float dist)
{
vec3_t v;
if (!self)
{
return;
}
if (dist)
M_walkmove (self, self->s.angles[YAW], dist);
@ -143,6 +153,11 @@ The monster is walking it's beat
*/
void ai_walk (edict_t *self, float dist)
{
if (!self)
{
return;
}
M_MoveToGoal (self, dist);
// check for noticing a player
@ -176,6 +191,11 @@ void ai_charge (edict_t *self, float dist)
{
vec3_t v;
if (!self)
{
return;
}
if(self->monsterinfo.aiflags & AI_ONESHOTTARGET)
{
VectorSubtract (self->monsterinfo.shottarget, self->s.origin, v);
@ -207,6 +227,11 @@ Distance is for slight position adjustments needed by the animations
*/
void ai_turn (edict_t *self, float dist)
{
if (!self)
{
return;
}
if (dist)
M_walkmove (self, self->s.angles[YAW], dist);
@ -259,6 +284,11 @@ int range (edict_t *self, edict_t *other)
vec3_t v;
float len;
if (!self || !other)
{
return 0;
}
VectorSubtract (self->s.origin, other->s.origin, v);
len = VectorLength (v);
if (len < MELEE_DISTANCE)
@ -283,6 +313,11 @@ qboolean visible (edict_t *self, edict_t *other)
vec3_t spot2;
trace_t trace;
if (!self || !other)
{
return false;
}
if (self->monsterinfo.flashTime > 0)
return false;
@ -310,12 +345,17 @@ qboolean infront (edict_t *self, edict_t *other)
vec3_t vec;
float dot;
vec3_t forward;
if (!self || !other)
{
return false;
}
AngleVectors (self->s.angles, forward, NULL, NULL);
VectorSubtract (other->s.origin, self->s.origin, vec);
VectorNormalize (vec);
dot = DotProduct (vec, forward);
if (dot > 0.3)
return true;
return false;
@ -334,12 +374,17 @@ qboolean inweaponLineOfSight (edict_t *self, edict_t *other)
vec3_t vec;
float dot;
vec3_t forward;
if (!self || !other)
{
return false;
}
AngleVectors (self->s.angles, forward, NULL, NULL);
VectorSubtract (other->s.origin, self->s.origin, vec);
VectorNormalize (vec);
dot = DotProduct (vec, forward);
if (dot > 0.8)
return true;
return false;
@ -352,6 +397,11 @@ void HuntTarget (edict_t *self)
{
vec3_t vec;
if (!self)
{
return;
}
self->goalentity = self->enemy;
if (self->monsterinfo.aiflags & AI_STAND_GROUND)
self->monsterinfo.stand (self);
@ -368,6 +418,11 @@ void FoundTarget (edict_t *self)
{
vec3_t v;
if (!self|| !self->enemy || !self->enemy->inuse)
{
return;
}
// let other monsters see this monster for a while
if (self->enemy->client)
{
@ -436,6 +491,11 @@ qboolean FindTarget (edict_t *self)
qboolean heardit;
int r;
if (!self)
{
return false;
}
if (self->monsterinfo.aiflags & AI_GOOD_GUY)
{
if (self->goalentity && self->goalentity->inuse && self->goalentity->classname)
@ -619,6 +679,11 @@ qboolean FacingIdeal(edict_t *self)
{
float delta;
if (!self)
{
return false;
}
delta = anglemod(self->s.angles[YAW] - self->ideal_yaw);
if (delta > 45 && delta < 315)
return false;
@ -634,6 +699,11 @@ qboolean M_CheckAttack (edict_t *self)
float chance;
trace_t tr;
if (!self || !self->enemy || !self->enemy->inuse)
{
return false;
}
if (self->enemy->health > 0)
{
// see if any entities are in the way of the shot
@ -726,6 +796,11 @@ Turn and close until within an angle to launch a melee attack
*/
void ai_run_melee(edict_t *self)
{
if (!self)
{
return;
}
self->ideal_yaw = enemy_yaw;
M_ChangeYaw (self);
@ -746,6 +821,11 @@ Turn in place until within an angle to launch a missile attack
*/
void ai_run_missile(edict_t *self)
{
if (!self)
{
return;
}
self->ideal_yaw = enemy_yaw;
M_ChangeYaw (self);
@ -767,7 +847,12 @@ Strafe sideways, but stay at aproximately the same range
void ai_run_slide(edict_t *self, float distance)
{
float ofs;
if (!self)
{
return;
}
self->ideal_yaw = enemy_yaw;
M_ChangeYaw (self);
@ -793,6 +878,11 @@ void ai_fly_strafe(edict_t *self, float dist)
{
vec3_t forward, right, vel;
if (!self)
{
return;
}
// face the enemy
self->ideal_yaw = enemy_yaw;
M_ChangeYaw (self);
@ -822,6 +912,13 @@ qboolean ai_checkattack (edict_t *self, float dist)
vec3_t temp;
qboolean hesDeadJim;
if (!self)
{
enemy_vis = false;
return false;
}
// this causes monsters to run blindly to the combat point w/o firing
if (self->goalentity)
{
@ -965,6 +1062,11 @@ void ai_run (edict_t *self, float dist)
float left, center, right;
vec3_t left_target, right_target;
if (!self)
{
return;
}
if (self->monsterinfo.flashTime > 0)
{
M_MoveAwayFromFlare(self, dist);

View file

@ -6,6 +6,11 @@ ClientTeam (edict_t *ent, char* value)
{
char *p;
if (!ent)
{
return value;
}
value[0] = 0;
if (!ent->client)
@ -30,6 +35,11 @@ qboolean OnSameTeam (edict_t *ent1, edict_t *ent2)
char ent1Team [512];
char ent2Team [512];
if (!ent1 || !ent2)
{
return false;
}
if (!((int)(dmflags->value) & (DF_MODELTEAMS | DF_SKINTEAMS)))
return false;
@ -49,6 +59,11 @@ void SelectNextItem (edict_t *ent, int itflags)
int i, index;
gitem_t *it;
if (!ent)
{
return;
}
cl = ent->client;
// scan for the next valid one
@ -78,6 +93,11 @@ void SelectPrevItem (edict_t *ent, int itflags)
int i, index;
gitem_t *it;
if (!ent)
{
return;
}
cl = ent->client;
// scan for the next valid one
@ -105,6 +125,11 @@ void ValidateSelectedItem (edict_t *ent)
{
gclient_t *cl;
if (!ent)
{
return;
}
cl = ent->client;
if (cl->pers.inventory[cl->pers.selected_item])
@ -134,6 +159,11 @@ void Cmd_Give_f (edict_t *ent)
int numargs;
char tryname[256];
if (!ent)
{
return;
}
if (deathmatch->value && !sv_cheats->value)
{
gi.cprintf (ent, PRINT_HIGH, "You must run the server with '+set cheats 1' to enable this command.\n");
@ -314,6 +344,11 @@ void Cmd_God_f (edict_t *ent)
{
char *msg;
if (!ent)
{
return;
}
if ((deathmatch->value || coop->value) && !sv_cheats->value)
{
gi.cprintf (ent, PRINT_HIGH, "You must run the server with '+set cheats 1' to enable this command.\n");
@ -343,6 +378,11 @@ void Cmd_Notarget_f (edict_t *ent)
{
char *msg;
if (!ent)
{
return;
}
if ((deathmatch->value || coop->value) && !sv_cheats->value)
{
gi.cprintf (ent, PRINT_HIGH, "You must run the server with '+set cheats 1' to enable this command.\n");
@ -370,6 +410,11 @@ void Cmd_Noclip_f (edict_t *ent)
{
char *msg;
if (!ent)
{
return;
}
if ((deathmatch->value || coop->value) && !sv_cheats->value)
{
gi.cprintf (ent, PRINT_HIGH, "You must run the server with '+set cheats 1' to enable this command.\n");
@ -414,6 +459,12 @@ qboolean tryUse(edict_t *ent, char *s)
{
int index = 0;
gitem_t *it = FindItem(s);
if (!ent)
{
return false;
}
if (!it)
{
gi.cprintf (ent, PRINT_HIGH, "unknown item: %s\n", s);
@ -438,6 +489,11 @@ void findNext(edict_t *ent, struct altsel_s *ptr, int offset)
{
int start = offset;
if (!ent)
{
return;
}
while (1)
{
if (tryUse(ent, ptr->weapon[offset]))
@ -459,7 +515,12 @@ void altSelect(edict_t *ent, int num)
int i = 0;
struct altsel_s *ptr = NULL;
gitem_t *it = NULL;
if (!ent)
{
return;
}
// within range?
if (num < 1 || num > 10)
{
@ -504,6 +565,11 @@ void Cmd_Use_f (edict_t *ent)
gitem_t *it;
char *s;
if (!ent)
{
return;
}
// are we using a multiselect item?
if (Q_stricmp(gi.argv(1), "weapon") == 0)
{
@ -551,6 +617,11 @@ void Cmd_Drop_f (edict_t *ent)
gitem_t *it;
char *s;
if (!ent)
{
return;
}
s = gi.args();
it = FindItem (s);
if (!it)
@ -584,6 +655,11 @@ void Cmd_Inven_f (edict_t *ent)
int i;
gclient_t *cl;
if (!ent)
{
return;
}
cl = ent->client;
cl->showscores = false;
@ -621,6 +697,11 @@ void Cmd_InvUse_f (edict_t *ent)
{
gitem_t *it;
if (!ent)
{
return;
}
ValidateSelectedItem (ent);
if (ent->client->pers.selected_item == -1)
@ -650,6 +731,11 @@ void Cmd_WeapPrev_f (edict_t *ent)
gitem_t *it;
int selected_weapon;
if (!ent)
{
return;
}
cl = ent->client;
if (!cl->pers.weapon)
@ -688,6 +774,11 @@ void Cmd_WeapNext_f (edict_t *ent)
gitem_t *it;
int selected_weapon;
if (!ent)
{
return;
}
cl = ent->client;
if (!cl->pers.weapon)
@ -725,6 +816,11 @@ void Cmd_WeapLast_f (edict_t *ent)
int index;
gitem_t *it;
if (!ent)
{
return;
}
cl = ent->client;
if (!cl->pers.weapon || !cl->pers.lastweapon)
@ -750,6 +846,11 @@ void Cmd_InvDrop_f (edict_t *ent)
{
gitem_t *it;
if (!ent)
{
return;
}
ValidateSelectedItem (ent);
if (ent->client->pers.selected_item == -1)
@ -774,6 +875,11 @@ Cmd_Kill_f
*/
void Cmd_Kill_f (edict_t *ent)
{
if (!ent)
{
return;
}
if((level.time - ent->client->respawn_time) < 5)
return;
ent->flags &= ~FL_GODMODE;
@ -793,6 +899,11 @@ Cmd_PutAway_f
*/
void Cmd_PutAway_f (edict_t *ent)
{
if (!ent)
{
return;
}
ent->client->showscores = false;
ent->client->showhelp = false;
ent->client->showinventory = false;
@ -832,6 +943,11 @@ void Cmd_Players_f (edict_t *ent)
char large[1280];
int index[256];
if (!ent)
{
return;
}
count = 0;
for (i = 0 ; i < maxclients->value ; i++)
if (game.clients[i].pers.connected)
@ -871,6 +987,11 @@ void Cmd_Wave_f (edict_t *ent)
{
int i;
if (!ent)
{
return;
}
i = atoi (gi.argv(1));
// can't wave when ducked
@ -925,6 +1046,11 @@ void Cmd_Say_f (edict_t *ent, qboolean team, qboolean arg0)
char *p;
char text[2048];
if (!ent)
{
return;
}
if (gi.argc () < 2 && !arg0)
return;
@ -988,6 +1114,11 @@ void ClientCommand (edict_t *ent)
{
char *cmd;
if (!ent)
{
return;
}
if (!ent->client)
return; // not fully in game yet

View file

@ -15,6 +15,11 @@ qboolean CanDamage (edict_t *targ, edict_t *inflictor)
vec3_t dest;
trace_t trace;
if (!targ || !inflictor)
{
return false;
}
// bmodels need special checking because their origin is 0,0,0
if (targ->movetype == MOVETYPE_PUSH)
{
@ -72,6 +77,11 @@ Killed
*/
void Killed (edict_t *targ, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
{
if (!targ || !inflictor || !attacker)
{
return;
}
if (targ->health < -999)
targ->health = -999;
@ -159,6 +169,11 @@ int CheckPowerArmor (edict_t *ent, vec3_t point, vec3_t normal, int damage, int
int power;
int power_used;
if (!ent)
{
return 0;
}
if (!damage)
return 0;
@ -264,6 +279,11 @@ int CheckArmor (edict_t *ent, vec3_t point, vec3_t normal, int damage, int te_sp
int index;
gitem_t *armor;
if (!ent)
{
return 0;
}
if (!damage)
return 0;
@ -305,6 +325,11 @@ int CheckArmor (edict_t *ent, vec3_t point, vec3_t normal, int damage, int te_sp
void M_ReactToDamage (edict_t *targ, edict_t *attacker)
{
if (!targ || !attacker)
{
return;
}
if (!(attacker->client) && !(attacker->svflags & SVF_MONSTER) &&
(strcmp (attacker->classname, "monster_autocannon") != 0))
return;
@ -385,6 +410,11 @@ void T_Damage (edict_t *targ, edict_t *inflictor, edict_t *attacker, vec3_t dir,
int psave;
int te_sparks;
if (!targ || !inflictor || !attacker)
{
return;
}
if (!targ->takedamage)
return;
@ -582,6 +612,12 @@ void T_RadiusDamage (edict_t *inflictor, edict_t *attacker, float damage, edict_
vec3_t v;
vec3_t dir;
if (!inflictor || !attacker || !ignore)
{
return;
}
while ((ent = findradius(ent, inflictor->s.origin, radius)) != NULL)
{
if (ent == ignore)
@ -619,6 +655,12 @@ void T_RadiusDamagePosition (vec3_t origin, edict_t *inflictor, edict_t *attacke
vec3_t v;
vec3_t dir;
if (!inflictor || !ignore)
{
return;
}
while ((ent = findradius(ent, origin, radius)) != NULL)
{
if (ent == ignore)

View file

@ -64,6 +64,12 @@
void Move_Done (edict_t *ent)
{
if (!ent)
{
return;
}
VectorClear (ent->velocity);
VectorClear(ent->avelocity);
ent->moveinfo.endfunc (ent);
@ -71,6 +77,11 @@ void Move_Done (edict_t *ent)
void Move_Final (edict_t *ent)
{
if (!ent)
{
return;
}
if (ent->moveinfo.remaining_distance == 0)
{
Move_Done (ent);
@ -87,6 +98,11 @@ void Move_Begin (edict_t *ent)
{
float frames;
if (!ent)
{
return;
}
if ((ent->moveinfo.speed * FRAMETIME) >= ent->moveinfo.remaining_distance)
{
Move_Final (ent);
@ -107,6 +123,11 @@ void Think_SmoothAccelMove (edict_t *ent);
void Move_Calc (edict_t *ent, vec3_t dest, void(*func)(edict_t*), int smoothSpeedChange)
{
if (!ent)
{
return;
}
VectorClear (ent->velocity);
VectorSubtract (dest, ent->s.origin, ent->moveinfo.dir);
ent->moveinfo.remaining_distance = VectorNormalize (ent->moveinfo.dir);
@ -177,6 +198,11 @@ void Move_Calc (edict_t *ent, vec3_t dest, void(*func)(edict_t*), int smoothSpee
void AngleMove_Done (edict_t *ent)
{
if (!ent)
{
return;
}
VectorClear (ent->avelocity);
ent->moveinfo.endfunc (ent);
}
@ -185,6 +211,11 @@ void AngleMove_Final (edict_t *ent)
{
vec3_t move;
if (!ent)
{
return;
}
if (ent->moveinfo.state == STATE_UP)
VectorSubtract (ent->moveinfo.end_angles, ent->s.angles, move);
else
@ -209,6 +240,11 @@ void AngleMove_Begin (edict_t *ent)
float traveltime;
float frames;
if (!ent)
{
return;
}
// set destdelta to the vector needed to move
if (ent->moveinfo.state == STATE_UP)
VectorSubtract (ent->moveinfo.end_angles, ent->s.angles, destdelta);
@ -239,6 +275,12 @@ void AngleMove_Begin (edict_t *ent)
void AngleMove_Calc (edict_t *ent, void(*func)(edict_t*))
{
if (!ent)
{
return;
}
VectorClear (ent->avelocity);
ent->moveinfo.endfunc = func;
if (level.current_entity == ((ent->flags & FL_TEAMSLAVE) ? ent->teammaster : ent))
@ -268,6 +310,11 @@ void plat_CalcAcceleratedMove(moveinfo_t *moveinfo)
float accel_dist;
float decel_dist;
if (!moveinfo)
{
return;
}
moveinfo->move_speed = moveinfo->speed;
if (moveinfo->remaining_distance < moveinfo->accel)
@ -293,6 +340,11 @@ void plat_CalcAcceleratedMove(moveinfo_t *moveinfo)
void plat_Accelerate (moveinfo_t *moveinfo)
{
if (!moveinfo)
{
return;
}
// are we decelerating?
if (moveinfo->remaining_distance <= moveinfo->decel_distance)
{
@ -364,6 +416,11 @@ void plat_Accelerate (moveinfo_t *moveinfo)
void Think_AccelMove (edict_t *ent)
{
if (!ent)
{
return;
}
ent->moveinfo.remaining_distance -= ent->moveinfo.current_speed;
if (ent->moveinfo.current_speed == 0) // starting or blocked
@ -397,6 +454,11 @@ change the speed for the next frame
void Think_SmoothAccelMove (edict_t *ent)
{
if (!ent)
{
return;
}
if (ent->moveinfo.remaining_distance >= ent->moveinfo.current_speed)
{
ent->moveinfo.remaining_distance -= ent->moveinfo.current_speed;
@ -432,6 +494,11 @@ void plat_go_down (edict_t *ent);
void plat_hit_top (edict_t *ent)
{
if (!ent)
{
return;
}
if (!(ent->flags & FL_TEAMSLAVE))
{
if (ent->moveinfo.sound_end)
@ -446,6 +513,11 @@ void plat_hit_top (edict_t *ent)
void plat_hit_bottom (edict_t *ent)
{
if (!ent)
{
return;
}
if (!(ent->flags & FL_TEAMSLAVE))
{
if (ent->moveinfo.sound_end)
@ -457,6 +529,11 @@ void plat_hit_bottom (edict_t *ent)
void plat_go_down (edict_t *ent)
{
if (!ent)
{
return;
}
if (!(ent->flags & FL_TEAMSLAVE))
{
if (ent->moveinfo.sound_start)
@ -469,6 +546,11 @@ void plat_go_down (edict_t *ent)
void plat_go_up (edict_t *ent)
{
if (!ent)
{
return;
}
if (!(ent->flags & FL_TEAMSLAVE))
{
if (ent->moveinfo.sound_start)
@ -481,6 +563,11 @@ void plat_go_up (edict_t *ent)
void plat_blocked (edict_t *self, edict_t *other)
{
if (!self || !other)
{
return;
}
if (!(other->svflags & SVF_MONSTER) && (!other->client) )
{
// give it a chance to go away on it's own terms (like gibs)
@ -508,16 +595,26 @@ void plat_blocked (edict_t *self, edict_t *other)
}
void Use_Plat (edict_t *ent, edict_t *other, edict_t *activator)
{
void Use_Plat (edict_t *ent, edict_t *other /* unused */, edict_t *activator /* unused */)
{
if (!ent)
{
return;
}
if (ent->think)
return; // already down
plat_go_down (ent);
}
void Touch_Plat_Center (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
void Touch_Plat_Center (edict_t *ent, edict_t *other, cplane_t *plane /* unused */, csurface_t *surf /* unused */)
{
if (!ent || !other)
{
return;
}
if (!other->client)
return;
@ -544,6 +641,11 @@ void plat_spawn_inside_trigger (edict_t *ent)
edict_t *trigger;
vec3_t tmin, tmax;
if (!ent)
{
return;
}
//
// middle trigger
//
@ -603,6 +705,11 @@ Set "sounds" to one of the following:
*/
void SP_func_plat (edict_t *ent)
{
if (!ent)
{
return;
}
VectorClear (ent->s.angles);
ent->solid = SOLID_BSP;
ent->movetype = MOVETYPE_PUSH;
@ -687,17 +794,32 @@ STOP mean it will stop moving instead of pushing entities
void rotating_blocked (edict_t *self, edict_t *other)
{
if (!self || !other)
{
return;
}
T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, 1, 0, MOD_CRUSH);
}
void rotating_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
{
if (!self || !other)
{
return;
}
if (self->moveinfo.state != STATE_STOPPED)
T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, 1, 0, MOD_CRUSH);
}
void rotating_think(edict_t *self)
{
if (!self)
{
return;
}
self->nextthink = level.time + FRAMETIME;
if (self->moveinfo.state == STATE_DECEL)
{
@ -730,8 +852,13 @@ void rotating_think(edict_t *self)
VectorScale(self->movedir, self->moveinfo.current_speed, self->avelocity);
}
void rotating_use (edict_t *self, edict_t *other, edict_t *activator)
void rotating_use (edict_t *self, edict_t *other /* unused */, edict_t *activator /* unused */)
{
if (!self)
{
return;
}
// if we're at full speed or we're accelerating
if (self->moveinfo.state == STATE_TOPSPEED || self->moveinfo.state == STATE_ACCEL)
{
@ -773,6 +900,11 @@ void rotating_use (edict_t *self, edict_t *other, edict_t *activator)
void SP_func_rotating (edict_t *ent)
{
if (!ent)
{
return;
}
ent->solid = SOLID_BSP;
if (ent->spawnflags & 32)
ent->movetype = MOVETYPE_STOP;
@ -843,6 +975,11 @@ When a button is touched, it moves some distance in the direction of it's angle,
void button_done (edict_t *self)
{
if (!self)
{
return;
}
self->moveinfo.state = STATE_BOTTOM;
self->s.effects &= ~EF_ANIM23;
self->s.effects |= EF_ANIM01;
@ -850,6 +987,11 @@ void button_done (edict_t *self)
void button_return (edict_t *self)
{
if (!self)
{
return;
}
self->moveinfo.state = STATE_DOWN;
Move_Calc (self, self->moveinfo.start_origin, button_done, false);
@ -862,6 +1004,11 @@ void button_return (edict_t *self)
void button_wait (edict_t *self)
{
if (!self)
{
return;
}
self->moveinfo.state = STATE_TOP;
self->s.effects &= ~EF_ANIM01;
self->s.effects |= EF_ANIM23;
@ -877,6 +1024,11 @@ void button_wait (edict_t *self)
void button_fire (edict_t *self)
{
if (!self)
{
return;
}
if (self->moveinfo.state == STATE_UP || self->moveinfo.state == STATE_TOP)
return;
@ -888,12 +1040,22 @@ void button_fire (edict_t *self)
void button_use (edict_t *self, edict_t *other, edict_t *activator)
{
if (!self || !activator)
{
return;
}
self->activator = activator;
button_fire (self);
}
void button_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
{
if (!self || !other)
{
return;
}
if (!other->client)
return;
@ -906,6 +1068,11 @@ void button_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *s
void button_killed (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
{
if (!self)
{
return;
}
self->activator = attacker;
self->health = self->max_health;
self->takedamage = DAMAGE_NO;
@ -917,6 +1084,11 @@ void SP_func_button (edict_t *ent)
vec3_t abs_movedir;
float dist;
if (!ent)
{
return;
}
G_SetMovedir (ent->s.angles, ent->movedir);
ent->movetype = MOVETYPE_STOP;
ent->solid = SOLID_BSP;
@ -1005,6 +1177,11 @@ void door_use_areaportals (edict_t *self, qboolean open)
{
edict_t *t = NULL;
if (!self)
{
return;
}
if (!self->target)
return;
@ -1021,6 +1198,11 @@ void door_go_down (edict_t *self);
void door_hit_top (edict_t *self)
{
if (!self)
{
return;
}
if (!(self->flags & FL_TEAMSLAVE))
{
if (self->moveinfo.sound_end)
@ -1039,6 +1221,11 @@ void door_hit_top (edict_t *self)
void door_hit_bottom (edict_t *self)
{
if (!self)
{
return;
}
if (!(self->flags & FL_TEAMSLAVE))
{
if (self->moveinfo.sound_end)
@ -1051,6 +1238,11 @@ void door_hit_bottom (edict_t *self)
void door_go_down (edict_t *self)
{
if (!self)
{
return;
}
if (!(self->flags & FL_TEAMSLAVE))
{
if (self->moveinfo.sound_start)
@ -1072,6 +1264,11 @@ void door_go_down (edict_t *self)
void door_go_up (edict_t *self, edict_t *activator)
{
if (!self || !activator)
{
return;
}
if (self->moveinfo.state == STATE_UP)
return; // already going up
@ -1102,6 +1299,11 @@ void door_openclose (edict_t *self, edict_t *other, edict_t *activator)
{
edict_t *ent;
if (!self || !activator)
{
return;
}
if (self->flags & FL_TEAMSLAVE)
return;
@ -1138,6 +1340,12 @@ void door_use (edict_t *self, edict_t *other, edict_t *activator)
{
// toggle active?
edict_t *ent;
if (!self || !other || !activator)
{
return;
}
if (self->active & DOOR_ACTIVE_TOGGLE)
{
for (ent = self ; ent ; ent = ent->teamchain)
@ -1160,6 +1368,11 @@ void door_use (edict_t *self, edict_t *other, edict_t *activator)
void Touch_DoorTrigger (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
{
if (!self || !other)
{
return;
}
if (other->health <= 0)
return;
@ -1190,6 +1403,11 @@ void Think_CalcMoveSpeed (edict_t *self)
float ratio;
float dist;
if (!self)
{
return;
}
if (self->flags & FL_TEAMSLAVE)
return; // only the team master does this
@ -1226,6 +1444,11 @@ void Think_SpawnDoorTrigger (edict_t *ent)
edict_t *other;
vec3_t mins, maxs;
if (!ent)
{
return;
}
if (ent->flags & FL_TEAMSLAVE)
return; // only the team leader spawns a trigger
@ -1264,6 +1487,11 @@ void door_blocked (edict_t *self, edict_t *other)
{
edict_t *ent;
if (!self || !other)
{
return;
}
if (!(other->svflags & SVF_MONSTER) && (!other->client) )
{
// give it a chance to go away on it's own terms (like gibs)
@ -1310,6 +1538,11 @@ void door_killed (edict_t *self, edict_t *inflictor, edict_t *attacker, int dama
{
edict_t *ent;
if (!self || !attacker)
{
return;
}
for (ent = self->teammaster ; ent ; ent = ent->teamchain)
{
ent->health = ent->max_health;
@ -1320,6 +1553,11 @@ void door_killed (edict_t *self, edict_t *inflictor, edict_t *attacker, int dama
void door_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
{
if (!self || !other)
{
return;
}
if (!other->client)
return;
@ -1338,6 +1576,11 @@ void SP_func_door (edict_t *ent)
{
vec3_t abs_movedir;
if (!ent)
{
return;
}
if (ent->sounds != 1)
{
ent->moveinfo.sound_start = gi.soundindex ("doors/dr1_strt.wav");
@ -1463,6 +1706,11 @@ REVERSE will cause the door to rotate in the opposite direction.
void SP_func_door_rotating (edict_t *ent)
{
if (!ent)
{
return;
}
VectorClear (ent->s.angles);
// set the axis of rotation
@ -1580,6 +1828,11 @@ void SP_func_water (edict_t *self)
{
vec3_t abs_movedir;
if (!self)
{
return;
}
G_SetMovedir (self->s.angles, self->movedir);
self->movetype = MOVETYPE_PUSH;
self->solid = SOLID_BSP;
@ -1665,6 +1918,11 @@ void train_next (edict_t *self);
void train_blocked (edict_t *self, edict_t *other)
{
if (!self || !other)
{
return;
}
if (!(other->svflags & SVF_MONSTER) && (!other->client) )
{
// give it a chance to go away on it's own terms (like gibs)
@ -1694,6 +1952,11 @@ void train_blocked (edict_t *self, edict_t *other)
void train_wait (edict_t *self)
{
if (!self)
{
return;
}
if (self->target_ent->pathtarget)
{
char *savetarget;
@ -1745,6 +2008,11 @@ void train_next (edict_t *self)
vec3_t dest;
qboolean first;
if (!self)
{
return;
}
first = true;
again:
if (!self->target)
@ -1825,6 +2093,11 @@ void train_resume (edict_t *self)
edict_t *ent;
vec3_t dest;
if (!self)
{
return;
}
ent = self->target_ent;
VectorSubtract (ent->s.origin, self->mins, dest);
@ -1839,6 +2112,11 @@ void func_train_find (edict_t *self)
{
edict_t *ent;
if (!self)
{
return;
}
if (!self->target)
{
gi.dprintf ("train_find: no target\n");
@ -1869,6 +2147,11 @@ void func_train_find (edict_t *self)
void train_use (edict_t *self, edict_t *other, edict_t *activator)
{
if (!self || !activator)
{
return;
}
self->activator = activator;
if (self->spawnflags & TRAIN_START_ON)
@ -1890,6 +2173,11 @@ void train_use (edict_t *self, edict_t *other, edict_t *activator)
void SP_func_train (edict_t *self)
{
if (!self)
{
return;
}
self->movetype = MOVETYPE_PUSH;
VectorClear (self->s.angles);
@ -1950,6 +2238,11 @@ void trigger_elevator_use (edict_t *self, edict_t *other, edict_t *activator)
{
edict_t *target;
if (!self || !other)
{
return;
}
if (self->movetarget->nextthink)
{
// gi.dprintf("elevator busy\n");
@ -1975,6 +2268,11 @@ void trigger_elevator_use (edict_t *self, edict_t *other, edict_t *activator)
void trigger_elevator_init (edict_t *self)
{
if (!self)
{
return;
}
if (!self->target)
{
gi.dprintf("trigger_elevator has no target\n");
@ -1999,6 +2297,11 @@ void trigger_elevator_init (edict_t *self)
void SP_trigger_elevator (edict_t *self)
{
if (!self)
{
return;
}
self->think = trigger_elevator_init;
self->nextthink = level.time + FRAMETIME;
}
@ -2022,6 +2325,11 @@ void parseTargets(edict_t *self)
{
int numTargets = 0;
if (!self)
{
return;
}
self->numTargets = 0;
if (self->target)
{
@ -2059,6 +2367,11 @@ void parseTargets(edict_t *self)
void func_timer_think (edict_t *self)
{
if (!self)
{
return;
}
if (self->numTargets <= 0)
return;
@ -2071,6 +2384,11 @@ void func_timer_think (edict_t *self)
void func_timer_use (edict_t *self, edict_t *other, edict_t *activator)
{
if (!self || !activator)
{
return;
}
self->activator = activator;
// if on, turn it off
@ -2089,6 +2407,11 @@ void func_timer_use (edict_t *self, edict_t *other, edict_t *activator)
void SP_func_timer (edict_t *self)
{
if (!self)
{
return;
}
if (!self->wait)
self->wait = 1.0;
@ -2121,6 +2444,11 @@ speed default 100
void func_conveyor_use (edict_t *self, edict_t *other, edict_t *activator)
{
if (!self)
{
return;
}
if (self->spawnflags & 1)
{
self->speed = 0;
@ -2138,6 +2466,11 @@ void func_conveyor_use (edict_t *self, edict_t *other, edict_t *activator)
void SP_func_conveyor (edict_t *self)
{
if (!self)
{
return;
}
if (!self->speed)
self->speed = 100;
@ -2182,6 +2515,11 @@ void door_secret_done (edict_t *self);
void door_secret_use (edict_t *self, edict_t *other, edict_t *activator)
{
if (!self)
{
return;
}
// make sure we're not already moving
if (!VectorCompare(self->s.origin, vec3_origin))
return;
@ -2192,17 +2530,32 @@ void door_secret_use (edict_t *self, edict_t *other, edict_t *activator)
void door_secret_move1 (edict_t *self)
{
if (!self)
{
return;
}
self->nextthink = level.time + 1.0;
self->think = door_secret_move2;
}
void door_secret_move2 (edict_t *self)
{
if (!self)
{
return;
}
Move_Calc (self, self->pos2, door_secret_move3, false);
}
void door_secret_move3 (edict_t *self)
{
if (!self)
{
return;
}
if (self->wait == -1)
return;
self->nextthink = level.time + self->wait;
@ -2211,22 +2564,42 @@ void door_secret_move3 (edict_t *self)
void door_secret_move4 (edict_t *self)
{
if (!self)
{
return;
}
Move_Calc (self, self->pos1, door_secret_move5, false);
}
void door_secret_move5 (edict_t *self)
{
if (!self)
{
return;
}
self->nextthink = level.time + 1.0;
self->think = door_secret_move6;
}
void door_secret_move6 (edict_t *self)
{
if (!self)
{
return;
}
Move_Calc (self, vec3_origin, door_secret_done, false);
}
void door_secret_done (edict_t *self)
{
if (!self)
{
return;
}
if (!(self->targetname) || (self->spawnflags & SECRET_ALWAYS_SHOOT))
{
self->health = 0;
@ -2237,6 +2610,11 @@ void door_secret_done (edict_t *self)
void door_secret_blocked (edict_t *self, edict_t *other)
{
if (!self)
{
return;
}
if (!(other->svflags & SVF_MONSTER) && (!other->client) )
{
// give it a chance to go away on it's own terms (like gibs)
@ -2264,6 +2642,11 @@ void door_secret_blocked (edict_t *self, edict_t *other)
void door_secret_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
{
if (!self || !attacker)
{
return;
}
self->takedamage = DAMAGE_NO;
door_secret_use (self, attacker, attacker);
}
@ -2275,6 +2658,11 @@ void SP_func_door_secret (edict_t *ent)
float width;
float length;
if (!ent)
{
return;
}
ent->moveinfo.sound_start = gi.soundindex ("doors/dr1_strt.wav");
ent->moveinfo.sound_middle = gi.soundindex ("doors/dr1_mid.wav");
ent->moveinfo.sound_end = gi.soundindex ("doors/dr1_end.wav");
@ -2341,6 +2729,11 @@ Kills everything inside when fired, irrespective of protection.
*/
void use_killbox (edict_t *self, edict_t *other, edict_t *activator)
{
if (!self)
{
return;
}
KillBox (self);
/* Hack to make sure that really everything is killed */
@ -2355,6 +2748,11 @@ void use_killbox (edict_t *self, edict_t *other, edict_t *activator)
void SP_func_killbox (edict_t *ent)
{
if (!ent)
{
return;
}
gi.setmodel (ent, ent->model);
ent->use = use_killbox;
ent->svflags = SVF_NOCLIENT;

View file

@ -127,6 +127,11 @@ void precacheAllItems()
void DoRespawn (edict_t *ent)
{
if (!ent)
{
return;
}
if (ent->team)
{
edict_t *master;
@ -154,6 +159,11 @@ void DoRespawn (edict_t *ent)
void SetRespawn (edict_t *ent, float delay)
{
if (!ent)
{
return;
}
ent->flags |= FL_RESPAWN;
ent->svflags |= SVF_NOCLIENT;
ent->solid = SOLID_NOT;
@ -169,6 +179,11 @@ qboolean Pickup_Powerup (edict_t *ent, edict_t *other)
{
int quantity;
if (!ent || !other)
{
return false;
}
quantity = other->client->pers.inventory[ITEM_INDEX(ent->item)];
if ((skill->value == SKILL_MEDIUM && quantity >= 2) || (skill->value >= SKILL_HARD && quantity >= 1))
return false;
@ -205,6 +220,11 @@ void Drop_General (edict_t *ent, gitem_t *item)
qboolean Pickup_Adrenaline (edict_t *ent, edict_t *other)
{
if (!ent || !other)
{
return false;
}
if (!deathmatch->value)
other->max_health += 1;
@ -219,6 +239,11 @@ qboolean Pickup_Adrenaline (edict_t *ent, edict_t *other)
qboolean Pickup_AncientHead (edict_t *ent, edict_t *other)
{
if (!ent || !other)
{
return false;
}
other->max_health += 2;
if (!(ent->spawnflags & DROPPED_ITEM) && (deathmatch->value))
@ -232,6 +257,11 @@ qboolean Pickup_Bandolier (edict_t *ent, edict_t *other)
gitem_t *item;
int index;
if (!ent || !other)
{
return false;
}
if (other->client->pers.max_bullets < 250)
other->client->pers.max_bullets = 250;
if (other->client->pers.max_shells < 150)
@ -270,6 +300,11 @@ qboolean Pickup_Pack (edict_t *ent, edict_t *other)
gitem_t *item;
int index;
if (!ent || !other)
{
return false;
}
if (other->client->pers.max_bullets < 300)
other->client->pers.max_bullets = 300;
if (other->client->pers.max_shells < 200)
@ -393,6 +428,11 @@ void Use_Quad (edict_t *ent, gitem_t *item)
{
int timeout;
if (!ent || !item)
{
return;
}
ent->client->pers.inventory[ITEM_INDEX(item)]--;
ValidateSelectedItem (ent);
@ -418,6 +458,11 @@ void Use_Quad (edict_t *ent, gitem_t *item)
void Use_Breather (edict_t *ent, gitem_t *item)
{
if (!ent || !item)
{
return;
}
ent->client->pers.inventory[ITEM_INDEX(item)]--;
ValidateSelectedItem (ent);
@ -431,6 +476,11 @@ void Use_Breather (edict_t *ent, gitem_t *item)
void Use_Envirosuit (edict_t *ent, gitem_t *item)
{
if (!ent || !item)
{
return;
}
ent->client->pers.inventory[ITEM_INDEX(item)]--;
ValidateSelectedItem (ent);
@ -444,6 +494,11 @@ void Use_Envirosuit (edict_t *ent, gitem_t *item)
void Use_Invulnerability (edict_t *ent, gitem_t *item)
{
if (!ent || !item)
{
return;
}
ent->client->pers.inventory[ITEM_INDEX(item)]--;
ValidateSelectedItem (ent);
@ -459,6 +514,11 @@ void Use_Invulnerability (edict_t *ent, gitem_t *item)
void Use_Silencer (edict_t *ent, gitem_t *item)
{
if (!ent || !item)
{
return;
}
ent->client->pers.inventory[ITEM_INDEX(item)]--;
ValidateSelectedItem (ent);
ent->client->silencer_shots += 30;
@ -468,6 +528,11 @@ void Use_Silencer (edict_t *ent, gitem_t *item)
qboolean Pickup_Key (edict_t *ent, edict_t *other)
{
if (!ent || !other)
{
return false;
}
if (coop->value)
{
if (strcmp(ent->classname, "key_power_cube") == 0)
@ -496,6 +561,11 @@ qboolean Add_Ammo (edict_t *ent, gitem_t *item, int count)
int index;
int max;
if (!ent || !item)
{
return false;
}
if (!ent->client)
return false;
@ -543,6 +613,11 @@ qboolean Pickup_Ammo (edict_t *ent, edict_t *other)
int count;
qboolean weapon;
if (!ent || !other)
{
return false;
}
weapon = (ent->item->flags & IT_WEAPON);
if ( (weapon) && ( (int)dmflags->value & DF_INFINITE_AMMO ) )
count = 1000;
@ -589,6 +664,11 @@ void Drop_Ammo (edict_t *ent, gitem_t *item)
edict_t *dropped;
int index;
if (!ent || !item)
{
return;
}
index = ITEM_INDEX(item);
dropped = Drop_Item (ent, item);
if (ent->client->pers.inventory[index] >= item->quantity)
@ -601,6 +681,11 @@ void Drop_Ammo (edict_t *ent, gitem_t *item)
qboolean Pickup_A2k (edict_t *ent, edict_t *other)
{
if (!ent || !other)
{
return false;
}
// do we already have an a2k?
if (other->client->pers.inventory[ITEM_INDEX(ent->item)] == 1)
{
@ -623,6 +708,11 @@ qboolean Pickup_A2k (edict_t *ent, edict_t *other)
void MegaHealth_think (edict_t *self)
{
if (!self)
{
return;
}
if (self->owner->health > self->owner->max_health)
{
self->nextthink = level.time + 1;
@ -638,6 +728,11 @@ void MegaHealth_think (edict_t *self)
qboolean Pickup_Health (edict_t *ent, edict_t *other)
{
if (!ent || !other)
{
return false;
}
if (!(ent->style & HEALTH_IGNORE_MAX))
if (other->health >= other->max_health)
return false;
@ -681,6 +776,11 @@ qboolean Pickup_Health (edict_t *ent, edict_t *other)
int ArmorIndex (edict_t *ent)
{
if (!ent)
{
return 0;
}
if (!ent->client)
return 0;
@ -705,6 +805,11 @@ qboolean Pickup_Armor (edict_t *ent, edict_t *other)
float salvage;
int salvagecount;
if (!ent || !other)
{
return false;
}
// get info on new armor
newinfo = (gitem_armor_t *)ent->item->info;
@ -779,6 +884,11 @@ qboolean Pickup_Armor (edict_t *ent, edict_t *other)
int PowerArmorType (edict_t *ent)
{
if (!ent)
{
return 0;
}
if (!ent->client)
return POWER_ARMOR_NONE;
@ -798,6 +908,11 @@ void Use_PowerArmor (edict_t *ent, gitem_t *item)
{
int index;
if (!ent || !item)
{
return;
}
if (ent->flags & FL_POWER_ARMOR)
{
ent->flags &= ~FL_POWER_ARMOR;
@ -820,6 +935,11 @@ qboolean Pickup_PowerArmor (edict_t *ent, edict_t *other)
{
int quantity;
if (!ent || !other)
{
return false;
}
quantity = other->client->pers.inventory[ITEM_INDEX(ent->item)];
other->client->pers.inventory[ITEM_INDEX(ent->item)]++;
@ -838,6 +958,11 @@ qboolean Pickup_PowerArmor (edict_t *ent, edict_t *other)
void Drop_PowerArmor (edict_t *ent, gitem_t *item)
{
if (!ent || !item)
{
return;
}
if ((ent->flags & FL_POWER_ARMOR) && (ent->client->pers.inventory[ITEM_INDEX(item)] == 1))
Use_PowerArmor (ent, item);
Drop_General (ent, item);
@ -847,17 +972,22 @@ void Drop_PowerArmor (edict_t *ent, gitem_t *item)
qboolean Pickup_PlasmaShield(edict_t *ent, edict_t *other)
{
if(other->client->pers.inventory[ITEM_INDEX(ent->item)])
{
return false;
}
if (!ent || !other)
{
return false;
}
if(other->client->pers.inventory[ITEM_INDEX(ent->item)])
{
return false;
}
other->client->pers.inventory[ITEM_INDEX(ent->item)] = 1;
if (deathmatch->value)
{
if (!(ent->spawnflags & DROPPED_ITEM) )
SetRespawn (ent, ent->item->quantity);
SetRespawn (ent, ent->item->quantity);
}
return true;
@ -866,6 +996,11 @@ qboolean Pickup_PlasmaShield(edict_t *ent, edict_t *other)
qboolean Pickup_Visor(edict_t *ent, edict_t *other)
{
if (!ent || !other)
{
return false;
}
// do we already have a visor?
if (other->client->pers.inventory[ITEM_INDEX(ent->item)] == 1 &&
other->client->pers.visorFrames == 300)
@ -891,6 +1026,11 @@ qboolean Pickup_Visor(edict_t *ent, edict_t *other)
void Drop_Visor(edict_t *ent, gitem_t *item)
{
if (!ent || !item)
{
return;
}
edict_t *visor = Drop_Item (ent, item);
ent->client->pers.inventory[ITEM_INDEX(item)] = 0;
ValidateSelectedItem (ent);
@ -909,6 +1049,11 @@ void Touch_Item (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf
{
qboolean taken;
if (!ent || !other)
{
return;
}
if (!other->client)
return;
if (other->health < 1)
@ -957,6 +1102,11 @@ void Touch_Item (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf
void drop_temp_touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
{
if (!ent || !other)
{
return;
}
if (other == ent->owner)
return;
@ -965,6 +1115,11 @@ void drop_temp_touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t
void drop_make_touchable (edict_t *ent)
{
if (!ent)
{
return;
}
ent->touch = Touch_Item;
if (deathmatch->value)
{
@ -979,6 +1134,11 @@ edict_t *Drop_Item (edict_t *ent, gitem_t *item)
vec3_t forward, right;
vec3_t offset;
if (!ent || !item)
{
return NULL;
}
dropped = G_Spawn();
dropped->classname = item->classname;
@ -1024,6 +1184,11 @@ edict_t *Drop_Item (edict_t *ent, gitem_t *item)
void Use_Item (edict_t *ent, edict_t *other, edict_t *activator)
{
if (!ent)
{
return;
}
ent->svflags &= ~SVF_NOCLIENT;
ent->use = NULL;
@ -1054,6 +1219,11 @@ void droptofloor (edict_t *ent)
vec3_t dest;
float *v;
if (!ent)
{
return;
}
v = tv(-15,-15,-15);
VectorCopy (v, ent->mins);
v = tv(15,15,15);
@ -1193,6 +1363,11 @@ be on an entity that hasn't spawned yet.
*/
void SpawnItem (edict_t *ent, gitem_t *item)
{
if (!ent || !item)
{
return;
}
PrecacheItem (item);
if (ent->spawnflags)
@ -2590,6 +2765,11 @@ security pass for the security level
*/
void SP_item_health (edict_t *self)
{
if (!self)
{
return;
}
if ( deathmatch->value && ((int)dmflags->value & DF_NO_HEALTH) )
{
G_FreeEdict (self);
@ -2606,6 +2786,11 @@ void SP_item_health (edict_t *self)
*/
void SP_item_health_small (edict_t *self)
{
if (!self)
{
return;
}
if ( deathmatch->value && ((int)dmflags->value & DF_NO_HEALTH) )
{
G_FreeEdict (self);
@ -2623,6 +2808,11 @@ void SP_item_health_small (edict_t *self)
*/
void SP_item_health_large (edict_t *self)
{
if (!self)
{
return;
}
if ( deathmatch->value && ((int)dmflags->value & DF_NO_HEALTH) )
{
G_FreeEdict (self);
@ -2639,6 +2829,11 @@ void SP_item_health_large (edict_t *self)
*/
void SP_item_health_mega (edict_t *self)
{
if (!self)
{
return;
}
if ( deathmatch->value && ((int)dmflags->value & DF_NO_HEALTH) )
{
G_FreeEdict (self);

View file

@ -13,6 +13,11 @@ Used to group brushes together just for editor convenience.
void Use_Areaportal (edict_t *ent, edict_t *other, edict_t *activator)
{
if (!ent)
{
return;
}
ent->count ^= 1; // toggle state
// gi.dprintf ("portalstate: %i = %i\n", ent->style, ent->count);
gi.SetAreaPortalState (ent->style, ent->count);
@ -26,6 +31,11 @@ Usually enclosed in the middle of a door.
*/
void SP_func_areaportal (edict_t *ent)
{
if (!ent)
{
return;
}
ent->use = Use_Areaportal;
ent->count = 0; // always start closed;
}
@ -52,6 +62,11 @@ void VelocityForDamage (int damage, vec3_t v)
void ClipGibVelocity (edict_t *ent)
{
if (!ent)
{
return;
}
if (ent->velocity[0] < -300)
ent->velocity[0] = -300;
else if (ent->velocity[0] > 300)
@ -74,6 +89,11 @@ gibs
*/
void gib_think (edict_t *self)
{
if (!self)
{
return;
}
self->s.frame++;
self->nextthink = level.time + FRAMETIME;
@ -88,6 +108,11 @@ void gib_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf
{
vec3_t normal_angles, right;
if (!self)
{
return;
}
if (!self->groundentity)
return;
@ -112,6 +137,11 @@ void gib_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf
void gib_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
{
if (!self)
{
return;
}
G_FreeEdict (self);
}
@ -123,6 +153,11 @@ void ThrowGib (edict_t *self, char *gibname, int damage, int type)
vec3_t size;
float vscale;
if (!self)
{
return;
}
if (!self || !gibname)
{
return;
@ -186,6 +221,11 @@ void ThrowHead (edict_t *self, char *gibname, int damage, int type)
vec3_t vd;
float vscale;
if (!self)
{
return;
}
self->s.skinnum = 0;
self->s.frame = 0;
VectorClear (self->mins);
@ -232,6 +272,11 @@ void ThrowClientHead (edict_t *self, int damage)
vec3_t vd;
char *gibname;
if (!self)
{
return;
}
if (rand()&1)
{
gibname = "models/objects/gibs/head2/tris.md2";
@ -276,6 +321,11 @@ debris
*/
void debris_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
{
if (!self)
{
return;
}
G_FreeEdict (self);
}
@ -284,6 +334,11 @@ void ThrowDebris (edict_t *self, char *modelname, float speed, vec3_t origin)
edict_t *chunk;
vec3_t v;
if (!self)
{
return;
}
if (!self || !modelname)
{
return;
@ -327,6 +382,11 @@ void ThrowDebris (edict_t *self, char *modelname, float speed, vec3_t origin)
void BecomeExplosion1 (edict_t *self)
{
if (!self)
{
return;
}
gi.WriteByte (svc_temp_entity);
gi.WriteByte (TE_EXPLOSION1);
gi.WritePosition (self->s.origin);
@ -338,6 +398,11 @@ void BecomeExplosion1 (edict_t *self)
void BecomeExplosion2 (edict_t *self)
{
if (!self)
{
return;
}
gi.WriteByte (svc_temp_entity);
gi.WriteByte (TE_EXPLOSION2);
gi.WritePosition (self->s.origin);
@ -358,6 +423,11 @@ void path_corner_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface
vec3_t v;
edict_t *next;
if (!self || !other)
{
return;
}
if (other->movetarget != self)
return;
@ -417,6 +487,11 @@ void path_corner_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface
void SP_path_corner (edict_t *self)
{
if (!self)
{
return;
}
if (!self->targetname)
{
gi.dprintf ("path_corner with no targetname at %s\n", vtos(self->s.origin));
@ -442,6 +517,11 @@ void point_combat_touch (edict_t *self, edict_t *other, cplane_t *plane, csurfac
{
edict_t *activator;
if (!self || !other)
{
return;
}
if (other->movetarget != self)
return;
@ -492,6 +572,11 @@ void point_combat_touch (edict_t *self, edict_t *other, cplane_t *plane, csurfac
void SP_point_combat (edict_t *self)
{
if (!self)
{
return;
}
if (deathmatch->value)
{
G_FreeEdict (self);
@ -511,12 +596,22 @@ Just for the debugging level. Don't use
*/
void TH_viewthing(edict_t *ent)
{
if (!ent)
{
return;
}
ent->s.frame = (ent->s.frame + 1) % 7;
ent->nextthink = level.time + FRAMETIME;
}
void SP_viewthing(edict_t *ent)
{
if (!ent)
{
return;
}
gi.dprintf ("viewthing spawned\n");
ent->movetype = MOVETYPE_NONE;
@ -537,6 +632,11 @@ Used as a positional target for spotlights, etc.
*/
void SP_info_null (edict_t *self)
{
if (!self)
{
return;
}
G_FreeEdict (self);
}
@ -546,6 +646,11 @@ Used as a positional target for lightning.
*/
void SP_info_notnull (edict_t *self)
{
if (!self)
{
return;
}
VectorCopy (self->s.origin, self->absmin);
VectorCopy (self->s.origin, self->absmax);
}
@ -563,6 +668,11 @@ Default _cone value is 10 (used to set size of light for spotlights)
void light_use (edict_t *self, edict_t *other, edict_t *activator)
{
if (!self)
{
return;
}
if (self->spawnflags & START_OFF)
{
gi.configstring (CS_LIGHTS+self->style, "m");
@ -577,6 +687,11 @@ void light_use (edict_t *self, edict_t *other, edict_t *activator)
void SP_light (edict_t *self)
{
if (!self)
{
return;
}
// no targeted lights in deathmatch, because they cause global messages
if (!self->targetname || deathmatch->value)
{
@ -611,6 +726,11 @@ START_ON only valid for TRIGGER_SPAWN walls
void func_wall_use (edict_t *self, edict_t *other, edict_t *activator)
{
if (!self)
{
return;
}
if (self->solid == SOLID_NOT)
{
self->solid = SOLID_BSP;
@ -630,6 +750,11 @@ void func_wall_use (edict_t *self, edict_t *other, edict_t *activator)
void SP_func_wall (edict_t *self)
{
if (!self)
{
return;
}
self->movetype = MOVETYPE_PUSH;
gi.setmodel (self, self->model);
@ -682,6 +807,11 @@ This is solid bmodel that will fall if it's support it removed.
void func_object_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
{
if (!self || !other)
{
return;
}
// only squash thing we fall on top of
if (!plane)
return;
@ -694,12 +824,22 @@ void func_object_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface
void func_object_release (edict_t *self)
{
if (!self)
{
return;
}
self->movetype = MOVETYPE_TOSS;
self->touch = func_object_touch;
}
void func_object_use (edict_t *self, edict_t *other, edict_t *activator)
{
if (!self)
{
return;
}
self->solid = SOLID_BSP;
self->svflags &= ~SVF_NOCLIENT;
self->use = NULL;
@ -709,6 +849,11 @@ void func_object_use (edict_t *self, edict_t *other, edict_t *activator)
void SP_func_object (edict_t *self)
{
if (!self)
{
return;
}
gi.setmodel (self, self->model);
self->mins[0] += 1;
@ -768,6 +913,11 @@ void func_explosive_explode (edict_t *self, edict_t *inflictor, edict_t *attacke
int count;
int mass;
if (!self || !inflictor || !attacker)
{
return;
}
// bmodel origins are (0 0 0), we need to adjust that here
VectorScale (self->size, 0.5, size);
VectorAdd (self->absmin, size, origin);
@ -826,11 +976,21 @@ void func_explosive_explode (edict_t *self, edict_t *inflictor, edict_t *attacke
void func_explosive_use(edict_t *self, edict_t *other, edict_t *activator)
{
if (!self || !other)
{
return;
}
func_explosive_explode (self, self, other, self->health, vec3_origin);
}
void func_explosive_spawn (edict_t *self, edict_t *other, edict_t *activator)
{
if (!self)
{
return;
}
self->solid = SOLID_BSP;
self->svflags &= ~SVF_NOCLIENT;
self->use = NULL;
@ -840,6 +1000,11 @@ void func_explosive_spawn (edict_t *self, edict_t *other, edict_t *activator)
void SP_func_explosive (edict_t *self)
{
if (!self)
{
return;
}
if (deathmatch->value)
{ // auto-remove for deathmatch
G_FreeEdict (self);
@ -888,14 +1053,19 @@ Large exploding box. You can override its mass (100),
health (80), and dmg (150).
*/
qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink);
void barrel_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
void barrel_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
{
float ratio;
vec3_t v;
vec3_t move;
float yaw, dist;
if (!self || !other)
{
return;
}
if (other->groundentity == self || !other->client)
return;
@ -919,6 +1089,11 @@ void barrel_explode (edict_t *self)
float spd;
vec3_t save;
if (!self)
{
return;
}
T_RadiusDamage (self, self->activator, self->dmg, NULL, self->dmg+40, MOD_BARREL);
VectorCopy (self->s.origin, save);
@ -994,6 +1169,11 @@ void barrel_explode (edict_t *self)
void barrel_delay (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
{
if (!self)
{
return;
}
self->takedamage = DAMAGE_NO;
self->nextthink = level.time + 2 * FRAMETIME;
self->think = barrel_explode;
@ -1002,6 +1182,11 @@ void barrel_delay (edict_t *self, edict_t *inflictor, edict_t *attacker, int dam
void SP_misc_explobox (edict_t *self)
{
if (!self)
{
return;
}
if (deathmatch->value)
{ // auto-remove for deathmatch
G_FreeEdict (self);
@ -1049,6 +1234,11 @@ void SP_misc_explobox (edict_t *self)
void misc_blackhole_use (edict_t *ent, edict_t *other, edict_t *activator)
{
if (!ent)
{
return;
}
/*
gi.WriteByte (svc_temp_entity);
gi.WriteByte (TE_BOSSTPORT);
@ -1060,6 +1250,11 @@ void misc_blackhole_use (edict_t *ent, edict_t *other, edict_t *activator)
void misc_blackhole_think (edict_t *self)
{
if (!self)
{
return;
}
if (++self->s.frame < 19)
self->nextthink = level.time + FRAMETIME;
else
@ -1071,6 +1266,11 @@ void misc_blackhole_think (edict_t *self)
void SP_misc_blackhole (edict_t *ent)
{
if (!ent)
{
return;
}
ent->movetype = MOVETYPE_NONE;
ent->solid = SOLID_NOT;
VectorSet (ent->mins, -64, -64, 0);
@ -1088,6 +1288,11 @@ void SP_misc_blackhole (edict_t *ent)
void misc_eastertank_think (edict_t *self)
{
if (!self)
{
return;
}
if (++self->s.frame < 293)
self->nextthink = level.time + FRAMETIME;
else
@ -1099,6 +1304,11 @@ void misc_eastertank_think (edict_t *self)
void SP_misc_eastertank (edict_t *ent)
{
if (!ent)
{
return;
}
ent->movetype = MOVETYPE_NONE;
ent->solid = SOLID_BBOX;
VectorSet (ent->mins, -32, -32, -16);
@ -1116,6 +1326,11 @@ void SP_misc_eastertank (edict_t *ent)
void misc_easterchick_think (edict_t *self)
{
if (!self)
{
return;
}
if (++self->s.frame < 247)
self->nextthink = level.time + FRAMETIME;
else
@ -1127,6 +1342,11 @@ void misc_easterchick_think (edict_t *self)
void SP_misc_easterchick (edict_t *ent)
{
if (!ent)
{
return;
}
ent->movetype = MOVETYPE_NONE;
ent->solid = SOLID_BBOX;
VectorSet (ent->mins, -32, -32, 0);
@ -1144,6 +1364,11 @@ void SP_misc_easterchick (edict_t *ent)
void misc_easterchick2_think (edict_t *self)
{
if (!self)
{
return;
}
if (++self->s.frame < 287)
self->nextthink = level.time + FRAMETIME;
else
@ -1155,6 +1380,11 @@ void misc_easterchick2_think (edict_t *self)
void SP_misc_easterchick2 (edict_t *ent)
{
if (!ent)
{
return;
}
ent->movetype = MOVETYPE_NONE;
ent->solid = SOLID_BBOX;
VectorSet (ent->mins, -32, -32, 0);
@ -1174,6 +1404,11 @@ There should be a item_commander_head that has this as it's target.
void commander_body_think (edict_t *self)
{
if (!self)
{
return;
}
if (++self->s.frame < 24)
self->nextthink = level.time + FRAMETIME;
else
@ -1185,6 +1420,11 @@ void commander_body_think (edict_t *self)
void commander_body_use (edict_t *self, edict_t *other, edict_t *activator)
{
if (!self)
{
return;
}
self->think = commander_body_think;
self->nextthink = level.time + FRAMETIME;
gi.sound (self, CHAN_BODY, gi.soundindex ("tank/pain.wav"), 1, ATTN_NORM, 0);
@ -1192,12 +1432,22 @@ void commander_body_use (edict_t *self, edict_t *other, edict_t *activator)
void commander_body_drop (edict_t *self)
{
if (!self)
{
return;
}
self->movetype = MOVETYPE_TOSS;
self->s.origin[2] += 2;
}
void SP_monster_commander_body (edict_t *self)
{
if (!self)
{
return;
}
self->movetype = MOVETYPE_NONE;
self->solid = SOLID_BBOX;
self->model = "models/monsters/commandr/tris.md2";
@ -1224,12 +1474,22 @@ The banner is 128 tall.
*/
void misc_banner_think (edict_t *ent)
{
if (!ent)
{
return;
}
ent->s.frame = (ent->s.frame + 1) % 16;
ent->nextthink = level.time + FRAMETIME;
}
void SP_misc_banner (edict_t *ent)
{
if (!ent)
{
return;
}
ent->movetype = MOVETYPE_NONE;
ent->solid = SOLID_NOT;
ent->s.modelindex = gi.modelindex ("models/objects/banner/tris.md2");
@ -1247,6 +1507,11 @@ void misc_deadsoldier_die (edict_t *self, edict_t *inflictor, edict_t *attacker,
{
int n;
if (!self)
{
return;
}
if (self->health > -80)
return;
@ -1258,6 +1523,11 @@ void misc_deadsoldier_die (edict_t *self, edict_t *inflictor, edict_t *attacker,
void SP_misc_deadsoldier (edict_t *ent)
{
if (!ent)
{
return;
}
if (deathmatch->value)
{ // auto-remove for deathmatch
G_FreeEdict (ent);
@ -1306,6 +1576,11 @@ extern void func_train_find (edict_t *self);
void misc_viper_use (edict_t *self, edict_t *other, edict_t *activator)
{
if (!self || !other || !activator)
{
return;
}
self->svflags &= ~SVF_NOCLIENT;
self->use = train_use;
train_use (self, other, activator);
@ -1313,6 +1588,11 @@ void misc_viper_use (edict_t *self, edict_t *other, edict_t *activator)
void SP_misc_viper (edict_t *ent)
{
if (!ent)
{
return;
}
if (!ent->target)
{
gi.dprintf ("misc_viper without a target at %s\n", vtos(ent->absmin));
@ -1385,6 +1665,11 @@ This is a large stationary viper as seen in Paul's intro
*/
void SP_misc_bigviper (edict_t *ent)
{
if (!ent)
{
return;
}
ent->movetype = MOVETYPE_NONE;
ent->solid = SOLID_BBOX;
VectorSet (ent->mins, -176, -120, -24);
@ -1399,6 +1684,11 @@ void SP_misc_bigviper (edict_t *ent)
*/
void misc_viper_bomb_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
{
if (!self)
{
return;
}
G_UseTargets (self, self->activator);
self->s.origin[2] = self->absmin[2] + 1;
@ -1411,6 +1701,11 @@ void misc_viper_bomb_prethink (edict_t *self)
vec3_t v;
float diff;
if (!self)
{
return;
}
self->groundentity = NULL;
diff = self->timestamp - level.time;
@ -1429,6 +1724,11 @@ void misc_viper_bomb_use (edict_t *self, edict_t *other, edict_t *activator)
{
edict_t *viper;
if (!self || !activator)
{
return;
}
self->solid = SOLID_BBOX;
self->svflags &= ~SVF_NOCLIENT;
self->s.effects |= EF_ROCKET;
@ -1447,6 +1747,11 @@ void misc_viper_bomb_use (edict_t *self, edict_t *other, edict_t *activator)
void SP_misc_viper_bomb (edict_t *self)
{
if (!self)
{
return;
}
self->movetype = MOVETYPE_NONE;
self->solid = SOLID_NOT;
VectorSet (self->mins, -8, -8, -8);
@ -1477,6 +1782,11 @@ extern void func_train_find (edict_t *self);
void misc_strogg_ship_use (edict_t *self, edict_t *other, edict_t *activator)
{
if (!self || !other || !activator)
{
return;
}
self->svflags &= ~SVF_NOCLIENT;
self->use = train_use;
train_use (self, other, activator);
@ -1484,6 +1794,11 @@ void misc_strogg_ship_use (edict_t *self, edict_t *other, edict_t *activator)
void SP_misc_strogg_ship (edict_t *ent)
{
if (!ent)
{
return;
}
if (!ent->target)
{
gi.dprintf ("%s without a target at %s\n", ent->classname, vtos(ent->absmin));
@ -1514,6 +1829,11 @@ void SP_misc_strogg_ship (edict_t *ent)
*/
void misc_satellite_dish_think (edict_t *self)
{
if (!self)
{
return;
}
self->s.frame++;
if (self->s.frame < 38)
self->nextthink = level.time + FRAMETIME;
@ -1521,6 +1841,11 @@ void misc_satellite_dish_think (edict_t *self)
void misc_satellite_dish_use (edict_t *self, edict_t *other, edict_t *activator)
{
if (!self)
{
return;
}
self->s.frame = 0;
self->think = misc_satellite_dish_think;
self->nextthink = level.time + FRAMETIME;
@ -1528,6 +1853,11 @@ void misc_satellite_dish_use (edict_t *self, edict_t *other, edict_t *activator)
void SP_misc_satellite_dish (edict_t *ent)
{
if (!ent)
{
return;
}
ent->movetype = MOVETYPE_NONE;
ent->solid = SOLID_BBOX;
VectorSet (ent->mins, -64, -64, 0);
@ -1542,6 +1872,11 @@ void SP_misc_satellite_dish (edict_t *ent)
*/
void SP_light_mine1 (edict_t *ent)
{
if (!ent)
{
return;
}
ent->movetype = MOVETYPE_NONE;
ent->solid = SOLID_BBOX;
ent->s.modelindex = gi.modelindex ("models/objects/minelite/light1/tris.md2");
@ -1553,6 +1888,11 @@ void SP_light_mine1 (edict_t *ent)
*/
void SP_light_mine2 (edict_t *ent)
{
if (!ent)
{
return;
}
ent->movetype = MOVETYPE_NONE;
ent->solid = SOLID_BBOX;
ent->s.modelindex = gi.modelindex ("models/objects/minelite/light2/tris.md2");
@ -1565,6 +1905,11 @@ Intended for use with the target_spawner
*/
void SP_misc_gib_arm (edict_t *ent)
{
if (!ent)
{
return;
}
gi.setmodel (ent, "models/objects/gibs/arm/tris.md2");
ent->solid = SOLID_NOT;
ent->s.effects |= EF_GIB;
@ -1586,6 +1931,11 @@ Intended for use with the target_spawner
*/
void SP_misc_gib_leg (edict_t *ent)
{
if (!ent)
{
return;
}
gi.setmodel (ent, "models/objects/gibs/leg/tris.md2");
ent->solid = SOLID_NOT;
ent->s.effects |= EF_GIB;
@ -1607,6 +1957,11 @@ Intended for use with the target_spawner
*/
void SP_misc_gib_head (edict_t *ent)
{
if (!ent)
{
return;
}
gi.setmodel (ent, "models/objects/gibs/head/tris.md2");
ent->solid = SOLID_NOT;
ent->s.effects |= EF_GIB;
@ -1632,6 +1987,11 @@ used with target_string (must be on same "team")
void SP_target_character (edict_t *self)
{
if (!self)
{
return;
}
self->movetype = MOVETYPE_PUSH;
gi.setmodel (self, self->model);
self->solid = SOLID_BSP;
@ -1650,6 +2010,11 @@ void target_string_use (edict_t *self, edict_t *other, edict_t *activator)
int n, l;
char c;
if (!self)
{
return;
}
l = strlen(self->message);
for (e = self->teammaster; e; e = e->teamchain)
{
@ -1676,6 +2041,11 @@ void target_string_use (edict_t *self, edict_t *other, edict_t *activator)
void SP_target_string (edict_t *self)
{
if (!self)
{
return;
}
if (!self->message)
self->message = "";
self->use = target_string_use;
@ -1702,6 +2072,11 @@ If START_OFF, this entity must be used before it starts
void func_clock_reset (edict_t *self)
{
if (!self)
{
return;
}
self->activator = NULL;
if (self->spawnflags & 1)
{
@ -1717,6 +2092,11 @@ void func_clock_reset (edict_t *self)
void func_clock_format_countdown (edict_t *self)
{
if (!self)
{
return;
}
if (self->style == 0)
{
Com_sprintf (self->message, CLOCK_MESSAGE_SIZE, "%2i", self->health);
@ -1744,6 +2124,11 @@ void func_clock_format_countdown (edict_t *self)
void func_clock_think (edict_t *self)
{
if (!self)
{
return;
}
if (!self->enemy)
{
self->enemy = G_Find (NULL, FOFS(targetname), self->target);
@ -1809,6 +2194,11 @@ void func_clock_think (edict_t *self)
void func_clock_use (edict_t *self, edict_t *other, edict_t *activator)
{
if (!self || !activator)
{
return;
}
if (!(self->spawnflags & 8))
self->use = NULL;
if (self->activator)
@ -1819,6 +2209,11 @@ void func_clock_use (edict_t *self, edict_t *other, edict_t *activator)
void SP_func_clock (edict_t *self)
{
if (!self)
{
return;
}
if (!self->target)
{
gi.dprintf("%s with no target at %s\n", self->classname, vtos(self->s.origin));
@ -1855,6 +2250,11 @@ void teleporter_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_
edict_t *dest;
int i;
if (!self || !other)
{
return;
}
if (!other->client)
return;
dest = G_Find (NULL, FOFS(targetname), self->target);
@ -1903,6 +2303,11 @@ void SP_misc_teleporter (edict_t *ent)
{
edict_t *trig;
if (!ent)
{
return;
}
if (!ent->target)
{
gi.dprintf ("teleporter without a target.\n");
@ -1937,6 +2342,11 @@ Point teleporters at these.
*/
void SP_misc_teleporter_dest (edict_t *ent)
{
if (!ent)
{
return;
}
gi.setmodel (ent, "models/objects/dmspot/tris.md2");
ent->s.skinnum = 0;
ent->solid = SOLID_BBOX;

View file

@ -10,6 +10,11 @@
// the damages too, but I'm not sure that's such a good idea.
void monster_fire_bullet (edict_t *self, vec3_t start, vec3_t dir, int damage, int kick, int hspread, int vspread, int flashtype)
{
if (!self)
{
return;
}
ANIM_AIM(self, dir);
fire_bullet (self, start, dir, damage, kick, hspread, vspread, MOD_UNKNOWN);
@ -21,6 +26,11 @@ void monster_fire_bullet (edict_t *self, vec3_t start, vec3_t dir, int damage, i
void monster_fire_shotgun (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick, int hspread, int vspread, int count, int flashtype)
{
if (!self)
{
return;
}
ANIM_AIM(self, aimdir);
fire_shotgun (self, start, aimdir, damage, kick, hspread, vspread, count, MOD_UNKNOWN);
@ -32,7 +42,12 @@ void monster_fire_shotgun (edict_t *self, vec3_t start, vec3_t aimdir, int damag
void monster_fire_blaster (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, int flashtype, int effect)
{
if(EMPNukeCheck(self, start))
if (!self)
{
return;
}
if (EMPNukeCheck(self, start))
{
gi.sound (self, CHAN_AUTO, gi.soundindex("items/empnuke/emp_missfire.wav"), 1, ATTN_NORM, 0);
return;
@ -45,10 +60,15 @@ void monster_fire_blaster (edict_t *self, vec3_t start, vec3_t dir, int damage,
gi.WriteShort (self - g_edicts);
gi.WriteByte (flashtype);
gi.multicast (start, MULTICAST_PVS);
}
}
void monster_fire_grenade (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, int flashtype)
{
if (!self)
{
return;
}
ANIM_AIM(self, aimdir);
fire_grenade (self, start, aimdir, damage, speed, 2.5, damage+40);
@ -60,7 +80,12 @@ void monster_fire_grenade (edict_t *self, vec3_t start, vec3_t aimdir, int damag
void monster_fire_rocket (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, int flashtype)
{
if(EMPNukeCheck(self, start))
if (!self)
{
return;
}
if (EMPNukeCheck(self, start))
{
gi.sound (self, CHAN_AUTO, gi.soundindex("items/empnuke/emp_missfire.wav"), 1, ATTN_NORM, 0);
return;
@ -77,7 +102,12 @@ void monster_fire_rocket (edict_t *self, vec3_t start, vec3_t dir, int damage, i
void monster_fire_railgun (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick, int flashtype)
{
if(EMPNukeCheck(self, start))
if (!self)
{
return;
}
if (EMPNukeCheck(self, start))
{
gi.sound (self, CHAN_AUTO, gi.soundindex("items/empnuke/emp_missfire.wav"), 1, ATTN_NORM, 0);
return;
@ -94,7 +124,12 @@ void monster_fire_railgun (edict_t *self, vec3_t start, vec3_t aimdir, int damag
void monster_fire_bfg (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, int kick, float damage_radius, int flashtype)
{
if(EMPNukeCheck(self, start))
if (!self)
{
return;
}
if (EMPNukeCheck(self, start))
{
gi.sound (self, CHAN_AUTO, gi.soundindex("items/empnuke/emp_missfire.wav"), 1, ATTN_NORM, 0);
return;
@ -117,14 +152,25 @@ void monster_fire_bfg (edict_t *self, vec3_t start, vec3_t aimdir, int damage, i
void M_FliesOff (edict_t *self)
{
if (!self)
{
return;
}
self->s.effects &= ~EF_FLIES;
self->s.sound = 0;
}
void M_FliesOn (edict_t *self)
{
if (!self)
{
return;
}
if (self->waterlevel)
return;
self->s.effects |= EF_FLIES;
self->s.sound = gi.soundindex ("infantry/inflies1.wav");
self->think = M_FliesOff;
@ -133,6 +179,11 @@ void M_FliesOn (edict_t *self)
void M_FlyCheck (edict_t *self)
{
if (!self)
{
return;
}
if (self->waterlevel)
return;
@ -145,6 +196,11 @@ void M_FlyCheck (edict_t *self)
void AttackFinished (edict_t *self, float time)
{
if (!self)
{
return;
}
self->monsterinfo.attack_finished = level.time + time;
}
@ -154,6 +210,11 @@ void M_CheckGround (edict_t *ent)
vec3_t point;
trace_t trace;
if (!ent)
{
return;
}
if (ent->flags & (FL_SWIM|FL_FLY))
return;
@ -192,6 +253,11 @@ void M_CatagorizePosition (edict_t *ent)
vec3_t point;
int cont;
if (!ent)
{
return;
}
//
// get waterlevel
//
@ -226,6 +292,11 @@ void M_WorldEffects (edict_t *ent)
{
int dmg;
if (!ent)
{
return;
}
if (ent->health > 0)
{
if (!(ent->flags & FL_SWIM))
@ -265,7 +336,7 @@ void M_WorldEffects (edict_t *ent)
}
}
}
if (ent->waterlevel == 0)
{
if (ent->flags & FL_INWATER)
@ -319,10 +390,15 @@ void M_droptofloor (edict_t *ent)
vec3_t end;
trace_t trace;
if (!ent)
{
return;
}
ent->s.origin[2] += 1;
VectorCopy (ent->s.origin, end);
end[2] -= 256;
trace = gi.trace (ent->s.origin, ent->mins, ent->maxs, end, ent, MASK_MONSTERSOLID);
if (trace.fraction == 1 || trace.allsolid)
@ -338,6 +414,11 @@ void M_droptofloor (edict_t *ent)
void M_SetEffects (edict_t *ent)
{
if (!ent)
{
return;
}
ent->s.effects &= ~(EF_COLOR_SHELL|EF_POWERSCREEN);
ent->s.renderfx &= ~(RF_SHELL_RED|RF_SHELL_GREEN|RF_SHELL_BLUE);
@ -367,6 +448,11 @@ void M_SetEffects (edict_t *ent)
qboolean FindTarget (edict_t *self);
void M_MoveFrame (edict_t *self)
{
if (!self)
{
return;
}
mmove_t *move;
int index;
@ -427,6 +513,11 @@ void M_MoveFrame (edict_t *self)
void monster_think (edict_t *self)
{
if (!self)
{
return;
}
M_MoveFrame (self);
if (self->linkcount != self->monsterinfo.linkcount)
{
@ -452,6 +543,11 @@ Using a monster makes it angry at the current activator
*/
void monster_use (edict_t *self, edict_t *other, edict_t *activator)
{
if (!self || !activator)
{
return;
}
if (self->enemy)
return;
if (self->health <= 0)
@ -472,6 +568,11 @@ void monster_start_go (edict_t *self);
void monster_triggered_spawn (edict_t *self)
{
if (!self)
{
return;
}
self->s.origin[2] += 1;
MonsterKillBox (self);
@ -500,6 +601,11 @@ void monster_triggered_spawn (edict_t *self)
void monster_triggered_spawn_use (edict_t *self, edict_t *other, edict_t *activator)
{
if (!self || !activator)
{
return;
}
// we have a one frame delay here so we don't telefrag the guy who activated us
self->think = monster_triggered_spawn;
self->nextthink = level.time + FRAMETIME;
@ -510,6 +616,11 @@ void monster_triggered_spawn_use (edict_t *self, edict_t *other, edict_t *activa
void monster_triggered_start (edict_t *self)
{
if (!self)
{
return;
}
self->solid = SOLID_NOT;
self->movetype = MOVETYPE_NONE;
self->svflags |= SVF_NOCLIENT;
@ -528,6 +639,11 @@ enemy as activator.
*/
void monster_death_use (edict_t *self)
{
if (!self)
{
return;
}
self->flags &= ~(FL_FLY|FL_SWIM);
self->monsterinfo.aiflags &= AI_GOOD_GUY;
@ -551,6 +667,11 @@ void monster_death_use (edict_t *self)
qboolean monster_start (edict_t *self)
{
if (!self)
{
return false;
}
if (deathmatch->value)
{
G_FreeEdict (self);
@ -606,6 +727,11 @@ void monster_start_go (edict_t *self)
{
vec3_t v;
if (!self)
{
return;
}
if (self->health <= 0)
return;
@ -692,6 +818,11 @@ void monster_start_go (edict_t *self)
void walkmonster_start_go (edict_t *self)
{
if (!self)
{
return;
}
if (!(self->spawnflags & 2) && level.time < 1)
{
M_droptofloor (self);
@ -700,7 +831,7 @@ void walkmonster_start_go (edict_t *self)
if (!M_walkmove (self, 0, 0))
gi.dprintf ("%s in solid at %s\n", self->classname, vtos(self->s.origin));
}
if (!self->yaw_speed)
self->yaw_speed = 20;
self->viewheight = 25;
@ -713,6 +844,11 @@ void walkmonster_start_go (edict_t *self)
void walkmonster_start (edict_t *self)
{
if (!self)
{
return;
}
self->think = walkmonster_start_go;
monster_start (self);
}
@ -720,6 +856,11 @@ void walkmonster_start (edict_t *self)
void flymonster_start_go (edict_t *self)
{
if (!self)
{
return;
}
if (!M_walkmove (self, 0, 0))
gi.dprintf ("%s in solid at %s\n", self->classname, vtos(self->s.origin));
@ -736,6 +877,11 @@ void flymonster_start_go (edict_t *self)
void flymonster_start (edict_t *self)
{
if (!self)
{
return;
}
self->flags |= FL_FLY;
self->think = flymonster_start_go;
monster_start (self);
@ -744,6 +890,11 @@ void flymonster_start (edict_t *self)
void swimmonster_start_go (edict_t *self)
{
if (!self)
{
return;
}
if (!self->yaw_speed)
self->yaw_speed = 10;
self->viewheight = 10;
@ -756,6 +907,11 @@ void swimmonster_start_go (edict_t *self)
void swimmonster_start (edict_t *self)
{
if (!self)
{
return;
}
self->flags |= FL_SWIM;
self->think = swimmonster_start_go;
monster_start (self);

View file

@ -32,15 +32,20 @@ edict_t *SV_TestEntityPosition (edict_t *ent)
trace_t trace;
int mask;
if (!ent)
{
return NULL;
}
if (ent->clipmask)
mask = ent->clipmask;
else
mask = MASK_SOLID;
trace = gi.trace (ent->s.origin, ent->mins, ent->maxs, ent->s.origin, ent, mask);
if (trace.startsolid)
return g_edicts;
return NULL;
}
@ -54,6 +59,11 @@ void SV_CheckVelocity (edict_t *ent)
{
int i;
if (!ent)
{
return;
}
//
// bound velocity
//
@ -77,12 +87,17 @@ qboolean SV_RunThink (edict_t *ent)
{
float thinktime;
if (!ent)
{
return false;
}
thinktime = ent->nextthink;
if (thinktime <= 0)
return true;
if (thinktime > level.time+0.001)
return true;
ent->nextthink = 0;
if (!ent->think)
gi.error ("NULL ent->think");
@ -101,13 +116,18 @@ Two entities have touched, so run their touch functions
void SV_Impact (edict_t *e1, trace_t *trace)
{
edict_t *e2;
// cplane_t backplane;
// cplane_t backplane;
if (!e1 || !trace)
{
return;
}
e2 = trace->ent;
if (e1->touch && e1->solid != SOLID_NOT)
e1->touch (e1, e2, &trace->plane, trace->surface);
if (e2->touch && e2->solid != SOLID_NOT)
e2->touch (e2, e1, NULL, NULL);
}
@ -128,13 +148,13 @@ int ClipVelocity (vec3_t in, vec3_t normal, vec3_t out, float overbounce)
float backoff;
float change;
int i, blocked;
blocked = 0;
if (normal[2] > 0)
blocked |= 1; // floor
if (!normal[2])
blocked |= 2; // step
backoff = DotProduct (in, normal) * overbounce;
for (i=0 ; i<3 ; i++)
@ -175,14 +195,19 @@ int SV_FlyMove (edict_t *ent, float time, int mask)
vec3_t end;
float time_left;
int blocked;
if (!ent)
{
return 0;
}
numbumps = 4;
blocked = 0;
VectorCopy (ent->velocity, original_velocity);
VectorCopy (ent->velocity, primal_velocity);
numplanes = 0;
time_left = time;
ent->groundentity = NULL;
@ -207,7 +232,7 @@ int SV_FlyMove (edict_t *ent, float time, int mask)
}
if (trace.fraction == 1)
break; // moved the entire distance
break; // moved the entire distance
hit = trace.ent;
@ -232,9 +257,9 @@ int SV_FlyMove (edict_t *ent, float time, int mask)
if (!ent->inuse)
break; // removed by the impact function
time_left -= time_left * trace.fraction;
// cliped to another plane
if (numplanes >= MAX_CLIP_PLANES)
{ // this shouldn't really happen
@ -260,7 +285,7 @@ int SV_FlyMove (edict_t *ent, float time, int mask)
if (j == numplanes)
break;
}
if (i != numplanes)
{ // go along this plane
VectorCopy (new_velocity, ent->velocity);
@ -300,6 +325,11 @@ SV_AddGravity
*/
void SV_AddGravity (edict_t *ent)
{
if (!ent)
{
return;
}
ent->velocity[2] -= ent->gravity * sv_gravity->value * FRAMETIME;
}
@ -320,6 +350,11 @@ RealBoundingBox(edict_t *ent, vec3_t mins, vec3_t maxs)
vec3_t p[8];
int i, j, k, j2, k4;
if (!ent)
{
return;
}
for (k = 0; k < 2; k++)
{
k4 = k * 4;
@ -387,12 +422,12 @@ RealBoundingBox(edict_t *ent, vec3_t mins, vec3_t maxs)
{
mins[0] = p[i][0];
}
if (mins[1] > p[i][1])
{
mins[1] = p[i][1];
}
if (mins[2] > p[i][2])
{
mins[2] = p[i][2];
@ -403,11 +438,11 @@ RealBoundingBox(edict_t *ent, vec3_t mins, vec3_t maxs)
maxs[0] = p[i][0];
}
if (maxs[1] < p[i][1])
if (maxs[1] < p[i][1])
{
maxs[1] = p[i][1];
}
if (maxs[2] < p[i][2])
{
maxs[2] = p[i][2];
@ -447,7 +482,7 @@ retry:
mask = MASK_SOLID;
trace = gi.trace (start, ent->mins, ent->maxs, end, ent, mask);
VectorCopy (trace.endpos, ent->s.origin);
gi.linkentity (ent);
@ -469,7 +504,7 @@ retry:
G_TouchTriggers (ent);
return trace;
}
}
typedef struct
@ -502,6 +537,11 @@ qboolean SV_Push (edict_t *pusher, vec3_t move, vec3_t amove)
vec3_t org, org2, move2, forward, right, up;
vec3_t realmins, realmaxs;
if (!pusher)
{
return false;
}
// clamp the move to 1/8 units, so the position will
// be accurate for client side prediction
for (i=0 ; i<3 ; i++)
@ -540,7 +580,7 @@ qboolean SV_Push (edict_t *pusher, vec3_t move, vec3_t amove)
gi.linkentity (pusher);
/* Create a real bounding box for
rotating brush models. */
rotating brush models. */
RealBoundingBox(pusher,realmins,realmaxs);
// see if any solid entities are inside the final position
@ -550,9 +590,9 @@ qboolean SV_Push (edict_t *pusher, vec3_t move, vec3_t amove)
if (!check->inuse)
continue;
if (check->movetype == MOVETYPE_PUSH
|| check->movetype == MOVETYPE_STOP
|| check->movetype == MOVETYPE_NONE
|| check->movetype == MOVETYPE_NOCLIP)
|| check->movetype == MOVETYPE_STOP
|| check->movetype == MOVETYPE_NONE
|| check->movetype == MOVETYPE_NOCLIP)
continue;
if (!check->area.prev)
@ -623,7 +663,7 @@ qboolean SV_Push (edict_t *pusher, vec3_t move, vec3_t amove)
continue;
}
}
// save off the obstacle so we can call the block function
obstacle = check;
@ -663,6 +703,11 @@ void SV_Physics_Pusher (edict_t *ent)
vec3_t move, amove;
edict_t *part, *mv;
if (!ent)
{
return;
}
// if not a team captain, so movement will be handled elsewhere
if ( ent->flags & FL_TEAMSLAVE)
return;
@ -675,7 +720,7 @@ void SV_Physics_Pusher (edict_t *ent)
{
if (part->velocity[0] || part->velocity[1] || part->velocity[2] ||
part->avelocity[0] || part->avelocity[1] || part->avelocity[2]
)
)
{ // object is moving
VectorScale (part->velocity, FRAMETIME, move);
VectorScale (part->avelocity, FRAMETIME, amove);
@ -724,6 +769,11 @@ Non moving objects can only think
*/
void SV_Physics_None (edict_t *ent)
{
if (!ent)
{
return;
}
// regular thinking
SV_RunThink (ent);
}
@ -737,10 +787,15 @@ A moving object that doesn't obey physics
*/
void SV_Physics_Noclip (edict_t *ent)
{
if (!ent)
{
return;
}
// regular thinking
if (!SV_RunThink (ent))
return;
VectorMA (ent->s.angles, FRAMETIME, ent->avelocity, ent->s.angles);
VectorMA (ent->s.origin, FRAMETIME, ent->velocity, ent->s.origin);
@ -773,6 +828,11 @@ void SV_Physics_Toss (edict_t *ent)
vec3_t old_origin;
float speed = 0;
if (!ent)
{
return;
}
// regular thinking
SV_RunThink (ent);
@ -798,8 +858,8 @@ void SV_Physics_Toss (edict_t *ent)
// add gravity
if (ent->movetype != MOVETYPE_FLY
&& ent->movetype != MOVETYPE_FLYMISSILE
&& ent->movetype != MOVETYPE_BOUNCEFLY)
&& ent->movetype != MOVETYPE_FLYMISSILE
&& ent->movetype != MOVETYPE_BOUNCEFLY)
SV_AddGravity (ent);
// move angles
@ -834,11 +894,9 @@ void SV_Physics_Toss (edict_t *ent)
VectorNormalize (ent->velocity);
VectorScale (ent->velocity, speed, ent->velocity);
}
else
// stop if on ground
if (trace.plane.normal[2] > 0.7)
{
// stop if on ground
else if (trace.plane.normal[2] > 0.7)
{
if (ent->velocity[2] < 60 || ent->movetype != MOVETYPE_BOUNCE)
{
ent->groundentity = trace.ent;
@ -848,7 +906,7 @@ void SV_Physics_Toss (edict_t *ent)
}
}
}
// check for water transition
wasinwater = (ent->watertype & MASK_WATER);
ent->watertype = gi.pointcontents (ent->s.origin);
@ -903,6 +961,11 @@ void SV_AddRotationalFriction (edict_t *ent)
int n;
float adjustment;
if (!ent)
{
return;
}
VectorMA (ent->s.angles, FRAMETIME, ent->avelocity, ent->s.angles);
adjustment = FRAMETIME * sv_stopspeed * sv_friction;
for (n = 0; n < 3; n++)
@ -911,13 +974,13 @@ void SV_AddRotationalFriction (edict_t *ent)
{
ent->avelocity[n] -= adjustment;
if (ent->avelocity[n] < 0)
ent->avelocity[n] = 0;
ent->avelocity[n] = 0;
}
else
{
ent->avelocity[n] += adjustment;
if (ent->avelocity[n] > 0)
ent->avelocity[n] = 0;
ent->avelocity[n] = 0;
}
}
}
@ -932,6 +995,11 @@ void SV_Physics_Step (edict_t *ent)
edict_t *groundentity;
int mask;
if (!ent)
{
return;
}
// airborn monsters should always check for ground
if (!ent->groundentity)
M_CheckGround (ent);
@ -944,7 +1012,7 @@ void SV_Physics_Step (edict_t *ent)
wasonground = true;
else
wasonground = false;
if (ent->avelocity[0] || ent->avelocity[1] || ent->avelocity[2])
SV_AddRotationalFriction (ent);
@ -1037,7 +1105,12 @@ void SV_Physics_FallFloat (edict_t *ent)
float gravVal = ent->gravity * sv_gravity->value * FRAMETIME;
qboolean wasonground = false;
qboolean hitsound = false;
if (!ent)
{
return;
}
// check velocity
SV_CheckVelocity (ent);
@ -1055,7 +1128,7 @@ void SV_Physics_FallFloat (edict_t *ent)
VectorCopy(ent->mins, min);
VectorCopy(ent->maxs, max);
VectorCopy(ent->s.origin, end);
end[2] -= 0.25; // down 4
@ -1105,7 +1178,7 @@ void SV_Physics_FallFloat (edict_t *ent)
{
vec3_t midpoint;
int watertype;
VectorAdd(ent->s.origin, ent->mins, midpoint);
VectorMA(midpoint, i, ent->maxs, midpoint);
watertype = gi.pointcontents (midpoint);
@ -1133,7 +1206,7 @@ void SV_Physics_FallFloat (edict_t *ent)
qboolean wasinwater = false;
vec3_t old_origin;
VectorCopy (ent->s.origin, old_origin);
SV_FlyMove (ent, FRAMETIME, MASK_SHOT);
gi.linkentity (ent);
@ -1158,7 +1231,6 @@ void SV_Physics_FallFloat (edict_t *ent)
gi.positioned_sound (old_origin, g_edicts, CHAN_AUTO, gi.soundindex("misc/h2ohit1.wav"), 1, 1, 0);
else if (wasinwater && !isinwater)
gi.positioned_sound (ent->s.origin, g_edicts, CHAN_AUTO, gi.soundindex("misc/h2ohit1.wav"), 1, 1, 0);
}
// relink
@ -1172,6 +1244,11 @@ void adjustRiders(edict_t *ent)
{
int i = 0;
if (!ent)
{
return;
}
// make sure the offsets are constant
for (i = 0; i < 2; i++)
{
@ -1182,6 +1259,11 @@ void adjustRiders(edict_t *ent)
void SV_Physics_Ride (edict_t *ent)
{
if (!ent)
{
return;
}
// base ourself on the step
SV_Physics_Step(ent);
@ -1197,39 +1279,44 @@ G_RunEntity
*/
void G_RunEntity (edict_t *ent)
{
if (!ent)
{
return;
}
if (ent->prethink)
ent->prethink (ent);
switch ( (int)ent->movetype)
{
case MOVETYPE_PUSH:
case MOVETYPE_STOP:
SV_Physics_Pusher (ent);
break;
case MOVETYPE_NONE:
SV_Physics_None (ent);
break;
case MOVETYPE_NOCLIP:
SV_Physics_Noclip (ent);
break;
case MOVETYPE_STEP:
SV_Physics_Step (ent);
break;
case MOVETYPE_TOSS:
case MOVETYPE_BOUNCE:
case MOVETYPE_FLY:
case MOVETYPE_BOUNCEFLY:
case MOVETYPE_FLYMISSILE:
SV_Physics_Toss (ent);
break;
case MOVETYPE_FALLFLOAT:
SV_Physics_FallFloat(ent);
break;
case MOVETYPE_RIDE:
SV_Physics_Ride(ent);
break;
default:
gi.error ("SV_Physics: bad movetype %i", (int)ent->movetype);
case MOVETYPE_PUSH:
case MOVETYPE_STOP:
SV_Physics_Pusher (ent);
break;
case MOVETYPE_NONE:
SV_Physics_None (ent);
break;
case MOVETYPE_NOCLIP:
SV_Physics_Noclip (ent);
break;
case MOVETYPE_STEP:
SV_Physics_Step (ent);
break;
case MOVETYPE_TOSS:
case MOVETYPE_BOUNCE:
case MOVETYPE_FLY:
case MOVETYPE_BOUNCEFLY:
case MOVETYPE_FLYMISSILE:
SV_Physics_Toss (ent);
break;
case MOVETYPE_FALLFLOAT:
SV_Physics_FallFloat(ent);
break;
case MOVETYPE_RIDE:
SV_Physics_Ride(ent);
break;
default:
gi.error ("SV_Physics: bad movetype %i", (int)ent->movetype);
}
}

View file

@ -311,6 +311,11 @@ void ED_CallSpawn (edict_t *ent)
return;
}
if (!ent)
{
return;
}
if (!ent->classname)
{
gi.dprintf ("ED_CallSpawn: NULL classname\n");
@ -456,7 +461,7 @@ char *ED_ParseEdict (char *data, edict_t *ent)
char keyname[256];
const char *com_token;
if (!ent || !data)
if (!ent)
{
return NULL;
}
@ -850,6 +855,11 @@ Only used for the world.
*/
void SP_worldspawn (edict_t *ent)
{
if (!ent)
{
return;
}
ent->movetype = MOVETYPE_PUSH;
ent->solid = SOLID_BSP;
ent->inuse = true; // since the world doesn't use G_Spawn()

View file

@ -6,6 +6,11 @@ Fire an origin based temp entity event to the clients.
*/
void Use_Target_Tent (edict_t *ent, edict_t *other, edict_t *activator)
{
if (!ent)
{
return;
}
gi.WriteByte (svc_temp_entity);
gi.WriteByte (ent->style);
gi.WritePosition (ent->s.origin);
@ -14,6 +19,11 @@ void Use_Target_Tent (edict_t *ent, edict_t *other, edict_t *activator)
void SP_target_temp_entity (edict_t *ent)
{
if (!ent)
{
return;
}
ent->use = Use_Target_Tent;
}
@ -40,6 +50,11 @@ void Use_Target_Speaker (edict_t *ent, edict_t *other, edict_t *activator)
{
int chan;
if (!ent)
{
return;
}
if (ent->spawnflags & 3)
{ // looping sound toggles
if (ent->s.sound)
@ -63,6 +78,11 @@ void SP_target_speaker (edict_t *ent)
{
char buffer[MAX_QPATH];
if (!ent)
{
return;
}
if(!st.noise)
{
gi.dprintf("target_speaker with no noise set at %s\n", vtos(ent->s.origin));
@ -98,6 +118,11 @@ void SP_target_speaker (edict_t *ent)
void Use_Target_Help (edict_t *ent, edict_t *other, edict_t *activator)
{
if (!ent)
{
return;
}
if (ent->spawnflags & 1)
strncpy (game.helpmessage1, ent->message, sizeof(game.helpmessage2)-1);
else
@ -111,6 +136,11 @@ When fired, the "message" key becomes the current personal computer string, and
*/
void SP_target_help(edict_t *ent)
{
if (!ent)
{
return;
}
if (deathmatch->value)
{ // auto-remove for deathmatch
G_FreeEdict (ent);
@ -134,6 +164,11 @@ These are single use targets.
*/
void use_target_secret (edict_t *ent, edict_t *other, edict_t *activator)
{
if (!ent || !activator)
{
return;
}
gi.sound (ent, CHAN_VOICE, ent->noise_index, 1, ATTN_NORM, 0);
level.found_secrets++;
@ -144,6 +179,11 @@ void use_target_secret (edict_t *ent, edict_t *other, edict_t *activator)
void SP_target_secret (edict_t *ent)
{
if (!ent)
{
return;
}
if (deathmatch->value)
{ // auto-remove for deathmatch
G_FreeEdict (ent);
@ -169,6 +209,11 @@ These are single use targets.
*/
void use_target_goal (edict_t *ent, edict_t *other, edict_t *activator)
{
if (!ent || !activator)
{
return;
}
gi.sound (ent, CHAN_VOICE, ent->noise_index, 1, ATTN_NORM, 0);
level.found_goals++;
@ -182,6 +227,11 @@ void use_target_goal (edict_t *ent, edict_t *other, edict_t *activator)
void SP_target_goal (edict_t *ent)
{
if (!ent)
{
return;
}
if (deathmatch->value)
{ // auto-remove for deathmatch
G_FreeEdict (ent);
@ -209,6 +259,11 @@ Spawns an explosion temporary entity when used.
void target_explosion_explode_think(edict_t *self)
{
if (!self)
{
return;
}
if(self->s.frame >= 5)
{
self->svflags |= SVF_NOCLIENT;
@ -226,6 +281,11 @@ void target_explosion_explode (edict_t *self)
{
float save;
if (!self)
{
return;
}
if (self->spawnflags & EMP_STYLE)
{
// play the sound
@ -260,6 +320,11 @@ void target_explosion_explode (edict_t *self)
void use_target_explosion (edict_t *self, edict_t *other, edict_t *activator)
{
if (!self || !activator)
{
return;
}
self->activator = activator;
if (!self->delay)
@ -274,6 +339,11 @@ void use_target_explosion (edict_t *self, edict_t *other, edict_t *activator)
void SP_target_explosion (edict_t *ent)
{
if (!ent)
{
return;
}
// setup stuff
ent->use = use_target_explosion;
ent->svflags = SVF_NOCLIENT;
@ -287,6 +357,11 @@ Changes level to "map" when fired
*/
void use_target_changelevel (edict_t *self, edict_t *other, edict_t *activator)
{
if (!self || !other || !activator)
{
return;
}
if (level.intermissiontime)
return; // already activated
@ -319,6 +394,11 @@ void use_target_changelevel (edict_t *self, edict_t *other, edict_t *activator)
void SP_target_changelevel (edict_t *ent)
{
if (!ent)
{
return;
}
if (!ent->map)
{
gi.dprintf("target_changelevel with no map at %s\n", vtos(ent->s.origin));
@ -327,8 +407,8 @@ void SP_target_changelevel (edict_t *ent)
}
// ugly hack because *SOMEBODY* screwed up their map
if((Q_stricmp(level.mapname, "fact1") == 0) && (Q_stricmp(ent->map, "fact3") == 0))
ent->map = "fact3$secret1";
if((Q_stricmp(level.mapname, "fact1") == 0) && (Q_stricmp(ent->map, "fact3") == 0))
ent->map = "fact3$secret1";
ent->use = use_target_changelevel;
ent->svflags = SVF_NOCLIENT;
@ -355,6 +435,11 @@ Set "sounds" to one of the following:
void use_target_splash (edict_t *self, edict_t *other, edict_t *activator)
{
if (!self || !activator)
{
return;
}
gi.WriteByte (svc_temp_entity);
gi.WriteByte (TE_SPLASH);
gi.WriteByte (self->count);
@ -369,6 +454,11 @@ void use_target_splash (edict_t *self, edict_t *other, edict_t *activator)
void SP_target_splash (edict_t *self)
{
if (!self)
{
return;
}
self->use = use_target_splash;
G_SetMovedir (self->s.angles, self->movedir);
@ -397,6 +487,11 @@ void ED_CallSpawn (edict_t *ent);
void use_target_spawner (edict_t *self, edict_t *other, edict_t *activator)
{
if (!self)
{
return;
}
edict_t *ent;
ent = G_Spawn();
@ -414,6 +509,11 @@ void use_target_spawner (edict_t *self, edict_t *other, edict_t *activator)
void SP_target_spawner (edict_t *self)
{
if (!self)
{
return;
}
self->use = use_target_spawner;
self->svflags = SVF_NOCLIENT;
if (self->speed)
@ -436,6 +536,11 @@ void use_target_blaster (edict_t *self, edict_t *other, edict_t *activator)
{
int effect;
if (!self)
{
return;
}
if(EMPNukeCheck(self, self->s.origin))
{
gi.sound (self, CHAN_AUTO, gi.soundindex("items/empnuke/emp_missfire.wav"), 1, ATTN_NORM, 0);
@ -455,6 +560,11 @@ void use_target_blaster (edict_t *self, edict_t *other, edict_t *activator)
void SP_target_blaster (edict_t *self)
{
if (!self)
{
return;
}
self->use = use_target_blaster;
G_SetMovedir (self->s.angles, self->movedir);
self->noise_index = gi.soundindex ("weapons/laser2.wav");
@ -475,12 +585,22 @@ Once this trigger is touched/used, any trigger_crosslevel_target with the same t
*/
void trigger_crosslevel_trigger_use (edict_t *self, edict_t *other, edict_t *activator)
{
if (!self)
{
return;
}
game.serverflags |= self->spawnflags;
G_FreeEdict (self);
}
void SP_target_crosslevel_trigger (edict_t *self)
{
if (!self)
{
return;
}
self->svflags = SVF_NOCLIENT;
self->use = trigger_crosslevel_trigger_use;
}
@ -493,6 +613,11 @@ killtarget also work.
*/
void target_crosslevel_target_think (edict_t *self)
{
if (!self)
{
return;
}
if (self->spawnflags == (game.serverflags & SFL_CROSS_TRIGGER_MASK & self->spawnflags))
{
G_UseTargets (self, self);
@ -502,7 +627,12 @@ void target_crosslevel_target_think (edict_t *self)
void SP_target_crosslevel_target (edict_t *self)
{
if (! self->delay)
if (!self)
{
return;
}
if (!self->delay)
self->delay = 1;
self->svflags = SVF_NOCLIENT;
@ -527,6 +657,11 @@ void target_laser_think (edict_t *self)
vec3_t last_movedir;
int count;
if (!self)
{
return;
}
if (self->spawnflags & 0x80000000)
count = 8;
else
@ -584,6 +719,11 @@ void target_laser_think (edict_t *self)
void target_laser_on (edict_t *self)
{
if (!self)
{
return;
}
if (!self->activator)
self->activator = self;
self->spawnflags |= 0x80000001;
@ -593,6 +733,11 @@ void target_laser_on (edict_t *self)
void target_laser_off (edict_t *self)
{
if (!self)
{
return;
}
self->spawnflags &= ~1;
self->svflags |= SVF_NOCLIENT;
self->nextthink = 0;
@ -600,6 +745,11 @@ void target_laser_off (edict_t *self)
void target_laser_use (edict_t *self, edict_t *other, edict_t *activator)
{
if (!self || !activator)
{
return;
}
self->activator = activator;
if (self->spawnflags & 1)
target_laser_off (self);
@ -611,6 +761,11 @@ void target_laser_start (edict_t *self)
{
edict_t *ent;
if (!self)
{
return;
}
self->movetype = MOVETYPE_NONE;
self->solid = SOLID_NOT;
self->s.renderfx |= RF_BEAM|RF_TRANSLUCENT;
@ -666,6 +821,11 @@ void target_laser_start (edict_t *self)
void SP_target_laser (edict_t *self)
{
if (!self)
{
return;
}
// let everything else get spawned before we start firing
self->think = target_laser_start;
self->nextthink = level.time + 1;
@ -682,6 +842,11 @@ void target_lightramp_think (edict_t *self)
{
char style[2];
if (!self)
{
return;
}
style[0] = 'a' + self->movedir[0] + (level.time - self->timestamp) / FRAMETIME * self->movedir[2];
style[1] = 0;
gi.configstring (CS_LIGHTS+self->enemy->style, style);
@ -703,6 +868,11 @@ void target_lightramp_think (edict_t *self)
void target_lightramp_use (edict_t *self, edict_t *other, edict_t *activator)
{
if (!self)
{
return;
}
if (!self->enemy)
{
edict_t *e;
@ -739,6 +909,11 @@ void target_lightramp_use (edict_t *self, edict_t *other, edict_t *activator)
void SP_target_lightramp (edict_t *self)
{
if (!self)
{
return;
}
if (!self->message || strlen(self->message) != 2 || self->message[0] < 'a' || self->message[0] > 'z' || self->message[1] < 'a' || self->message[1] > 'z' || self->message[0] == self->message[1])
{
gi.dprintf("target_lightramp has bad ramp (%s) at %s\n", self->message, vtos(self->s.origin));
@ -782,6 +957,11 @@ void target_earthquake_think (edict_t *self)
int i;
edict_t *e;
if (!self)
{
return;
}
if (self->last_move_time < level.time)
{
gi.positioned_sound (self->s.origin, self, CHAN_AUTO, self->noise_index, 1.0, ATTN_NONE, 0);
@ -809,6 +989,11 @@ void target_earthquake_think (edict_t *self)
void target_earthquake_use (edict_t *self, edict_t *other, edict_t *activator)
{
if (!self || !activator)
{
return;
}
self->timestamp = level.time + self->count;
self->nextthink = level.time + FRAMETIME;
self->activator = activator;
@ -817,6 +1002,11 @@ void target_earthquake_use (edict_t *self, edict_t *other, edict_t *activator)
void SP_target_earthquake (edict_t *self)
{
if (!self)
{
return;
}
if (!self->targetname)
gi.dprintf("untargeted %s at %s\n", self->classname, vtos(self->s.origin));

View file

@ -3,6 +3,11 @@
void InitTrigger (edict_t *self)
{
if (!self)
{
return;
}
if (!VectorCompare (self->s.angles, vec3_origin))
G_SetMovedir (self->s.angles, self->movedir);
@ -16,6 +21,11 @@ void InitTrigger (edict_t *self)
// the wait time has passed, so set back up for another activation
void multi_wait (edict_t *ent)
{
if (!ent)
{
return;
}
ent->nextthink = 0;
}
@ -25,6 +35,11 @@ void multi_wait (edict_t *ent)
// so wait for the delay time before firing
void multi_trigger (edict_t *ent)
{
if (!ent)
{
return;
}
if (ent->nextthink)
return; // already been triggered
@ -36,7 +51,8 @@ void multi_trigger (edict_t *ent)
ent->nextthink = level.time + ent->wait;
}
else
{ // we can't just remove (self) here, because this is a touch function
{
// we can't just remove (self) here, because this is a touch function
// called while looping through area links...
ent->touch = NULL;
ent->nextthink = level.time + FRAMETIME;
@ -46,24 +62,34 @@ void multi_trigger (edict_t *ent)
void Use_Multi (edict_t *ent, edict_t *other, edict_t *activator)
{
if (!ent || !activator)
{
return;
}
ent->activator = activator;
multi_trigger (ent);
}
void Touch_Multi (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
{
if (!self || !other)
{
return;
}
if(other->client)
{
if (self->spawnflags & 2)
return;
return;
}
else if (other->svflags & SVF_MONSTER)
{
if (!(self->spawnflags & 1))
return;
return;
}
else
return;
return;
if (!VectorCompare(self->movedir, vec3_origin))
{
@ -91,6 +117,11 @@ set "message" to text string
*/
void trigger_enable (edict_t *self, edict_t *other, edict_t *activator)
{
if (!self)
{
return;
}
self->solid = SOLID_TRIGGER;
self->use = Use_Multi;
gi.linkentity (self);
@ -98,13 +129,18 @@ void trigger_enable (edict_t *self, edict_t *other, edict_t *activator)
void SP_trigger_multiple (edict_t *ent)
{
if (!ent)
{
return;
}
if (ent->sounds == 1)
ent->noise_index = gi.soundindex ("misc/secret.wav");
else if (ent->sounds == 2)
ent->noise_index = gi.soundindex ("misc/talk.wav");
else if (ent->sounds == 3)
ent->noise_index = gi.soundindex ("misc/trigger1.wav");
if (!ent->wait)
ent->wait = 0.2;
ent->touch = Touch_Multi;
@ -148,6 +184,11 @@ sounds
void SP_trigger_once(edict_t *ent)
{
if (!ent)
{
return;
}
// make old maps work because I messed up on flag assignments here
// triggered was on bit 1 when it should have been on bit 4
if (ent->spawnflags & 1)
@ -169,11 +210,21 @@ This fixed size trigger cannot be touched, it can only be fired by other events.
*/
void trigger_relay_use (edict_t *self, edict_t *other, edict_t *activator)
{
if (!self || !activator)
{
return;
}
G_UseTargets (self, activator);
}
void SP_trigger_relay (edict_t *self)
{
if (!self)
{
return;
}
self->use = trigger_relay_use;
}
@ -194,6 +245,11 @@ void trigger_key_use (edict_t *self, edict_t *other, edict_t *activator)
{
int index;
if (!self || !activator)
{
return;
}
if (!self->item)
return;
if (!activator->client)
@ -262,6 +318,11 @@ void trigger_key_use (edict_t *self, edict_t *other, edict_t *activator)
void SP_trigger_key (edict_t *self)
{
if (!self)
{
return;
}
if (!st.item)
{
gi.dprintf("no key item for trigger_key at %s\n", vtos(self->s.origin));
@ -306,9 +367,14 @@ After the counter has been triggered "count" times (default 2), it will fire all
void trigger_counter_use(edict_t *self, edict_t *other, edict_t *activator)
{
if (!self || !activator)
{
return;
}
if (self->count == 0)
return;
self->count--;
if (self->count)
@ -320,7 +386,7 @@ void trigger_counter_use(edict_t *self, edict_t *other, edict_t *activator)
}
return;
}
if (! (self->spawnflags & 1))
{
gi.centerprintf(activator, "Sequence completed!");
@ -332,6 +398,11 @@ void trigger_counter_use(edict_t *self, edict_t *other, edict_t *activator)
void SP_trigger_counter (edict_t *self)
{
if (!self)
{
return;
}
self->wait = -1;
if (!self->count)
self->count = 2;
@ -353,6 +424,11 @@ This trigger will always fire. It is activated by the world.
*/
void SP_trigger_always (edict_t *ent)
{
if (!ent)
{
return;
}
// we must have some delay to make sure our use targets are present
if (ent->delay < 0.2)
ent->delay = 0.2;
@ -376,6 +452,11 @@ static int windsound; // fixup or zaero or may not work with mirror level's...
void trigger_push_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
{
if (!self || !other)
{
return;
}
if (self->spawnflags & START_OFF)
{
if (self->message && self->touch_debounce_time < level.time)
@ -412,6 +493,11 @@ void trigger_push_touch (edict_t *self, edict_t *other, cplane_t *plane, csurfac
void trigger_push_use(edict_t *self, edict_t *other, edict_t *activator)
{
if (!self)
{
return;
}
if (self->spawnflags & START_OFF)
self->spawnflags &= ~START_OFF;
else
@ -424,6 +510,11 @@ Pushes the player
*/
void SP_trigger_push (edict_t *self)
{
if (!self)
{
return;
}
InitTrigger (self);
windsound = gi.soundindex ("misc/windfly.wav");
self->touch = trigger_push_touch;
@ -432,7 +523,7 @@ void SP_trigger_push (edict_t *self)
if (self->targetname)
self->use = trigger_push_use;
gi.linkentity (self);
}
@ -459,6 +550,11 @@ NO_PROTECTION *nothing* stops the damage
*/
void hurt_use (edict_t *self, edict_t *other, edict_t *activator)
{
if (!self)
{
return;
}
if (self->solid == SOLID_NOT)
self->solid = SOLID_TRIGGER;
else
@ -474,6 +570,11 @@ void hurt_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *sur
{
int dflags;
if (!self || !other)
{
return;
}
if (!other->takedamage)
return;
@ -500,6 +601,11 @@ void hurt_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *sur
void SP_trigger_hurt (edict_t *self)
{
if (!self)
{
return;
}
InitTrigger (self);
self->noise_index = gi.soundindex ("world/electro.wav");
@ -536,11 +642,21 @@ gravity for the level.
void trigger_gravity_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
{
if (!self || !other)
{
return;
}
other->gravity = self->gravity;
}
void SP_trigger_gravity (edict_t *self)
{
if (!self)
{
return;
}
if (st.gravity == 0)
{
gi.dprintf("trigger_gravity without gravity set at %s\n", vtos(self->s.origin));
@ -570,6 +686,11 @@ Walking monsters that touch this will jump in the direction of the trigger's ang
void trigger_monsterjump_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
{
if (!self || !other)
{
return;
}
if (other->flags & (FL_FLY | FL_SWIM) )
return;
if (other->svflags & SVF_DEADMONSTER)
@ -580,16 +701,21 @@ void trigger_monsterjump_touch (edict_t *self, edict_t *other, cplane_t *plane,
// set XY even if not on ground, so the jump will clear lips
other->velocity[0] = self->movedir[0] * self->speed;
other->velocity[1] = self->movedir[1] * self->speed;
if (!other->groundentity)
return;
other->groundentity = NULL;
other->velocity[2] = self->movedir[2];
}
void SP_trigger_monsterjump (edict_t *self)
{
if (!self)
{
return;
}
if (!self->speed)
self->speed = 200;
if (!st.height)

View file

@ -30,6 +30,11 @@ void turret_blocked(edict_t *self, edict_t *other)
{
edict_t *attacker;
if (!self || !other)
{
return;
}
if (other->takedamage)
{
if (self->teammaster->owner)
@ -63,6 +68,11 @@ void turret_breach_fire (edict_t *self)
int damage;
int speed;
if (!self)
{
return;
}
AngleVectors (self->s.angles, f, r, u);
VectorMA (self->s.origin, self->move_origin[0], f, start);
VectorMA (start, self->move_origin[1], r, start);
@ -86,6 +96,11 @@ void turret_breach_think (edict_t *self)
vec3_t current_angles;
vec3_t delta;
if (!self)
{
return;
}
VectorCopy (self->s.angles, current_angles);
AnglesNormalize(current_angles);
@ -187,6 +202,11 @@ void turret_breach_think (edict_t *self)
void turret_breach_finish_init (edict_t *self)
{
if (!self)
{
return;
}
// get and save info for muzzle location
if (!self->target)
{
@ -206,6 +226,11 @@ void turret_breach_finish_init (edict_t *self)
void SP_turret_breach (edict_t *self)
{
if (!self)
{
return;
}
self->solid = SOLID_BSP;
self->movetype = MOVETYPE_PUSH;
gi.setmodel (self, self->model);
@ -245,6 +270,11 @@ MUST be teamed with a turret_breach.
void SP_turret_base (edict_t *self)
{
if (!self)
{
return;
}
self->solid = SOLID_BSP;
self->movetype = MOVETYPE_PUSH;
gi.setmodel (self, self->model);
@ -266,12 +296,17 @@ void turret_driver_die (edict_t *self, edict_t *inflictor, edict_t *attacker, in
{
edict_t *ent;
if (!self || !inflictor || !attacker)
{
return;
}
// level the gun
self->target_ent->move_angles[0] = 0;
// remove the driver from the end of them team chain
for (ent = self->target_ent->teammaster; ent->teamchain != self; ent = ent->teamchain)
;
;
ent->teamchain = NULL;
self->teammaster = NULL;
self->flags &= ~FL_TEAMSLAVE;
@ -290,6 +325,11 @@ void turret_driver_think (edict_t *self)
vec3_t dir;
float reaction_time;
if (!self)
{
return;
}
self->nextthink = level.time + FRAMETIME;
if (self->enemy && (!self->enemy->inuse || self->enemy->health <= 0))
@ -343,6 +383,11 @@ void turret_driver_link (edict_t *self)
vec3_t vec;
edict_t *ent;
if (!self)
{
return;
}
self->think = turret_driver_think;
self->nextthink = level.time + FRAMETIME;
@ -373,6 +418,11 @@ void turret_driver_link (edict_t *self)
void SP_turret_driver (edict_t *self)
{
if (!self)
{
return;
}
if (deathmatch->value)
{
G_FreeEdict (self);
@ -412,7 +462,7 @@ void SP_turret_driver (edict_t *self)
{
self->item = FindItemByClassname (st.item);
if (!self->item)
gi.dprintf("%s at %s has bad item: %s\n", self->classname, vtos(self->s.origin), st.item);
gi.dprintf("%s at %s has bad item: %s\n", self->classname, vtos(self->s.origin), st.item);
}
self->think = turret_driver_link;

View file

@ -27,6 +27,11 @@ edict_t *G_Find (edict_t *from, int fieldofs, char *match)
{
char *s;
if (!from)
{
return NULL;
}
if (!from)
from = g_edicts;
else
@ -61,6 +66,11 @@ edict_t *findradius (edict_t *from, vec3_t org, float rad)
vec3_t eorg;
int j;
if (!from)
{
return NULL;
}
if (!from)
from = g_edicts;
else
@ -131,6 +141,11 @@ edict_t *G_PickTarget (char *targetname)
void Think_Delay (edict_t *ent)
{
if (!ent)
{
return;
}
G_UseTargets (ent, ent->activator);
G_FreeEdict (ent);
}
@ -155,12 +170,17 @@ void G_UseTargets (edict_t *ent, edict_t *activator)
{
edict_t *t;
if (!ent || !activator)
{
return;
}
//
// check for a delay
//
if (ent->delay)
{
// create a temp object to fire at a later time
// create a temp object to fire at a later time
t = G_Spawn();
t->classname = "DelayedUse";
t->nextthink = level.time + ent->delay;
@ -173,8 +193,8 @@ void G_UseTargets (edict_t *ent, edict_t *activator)
t->killtarget = ent->killtarget;
return;
}
//
// print the message
//
@ -224,7 +244,7 @@ void G_UseTargets (edict_t *ent, edict_t *activator)
else
{
if (t->use)
t->use (t, ent, activator);
t->use (t, ent, activator);
}
if (!ent->inuse)
{
@ -314,7 +334,7 @@ void G_SetMovedir (vec3_t angles, vec3_t movedir)
float vectoyaw (vec3_t vec)
{
float yaw;
if (/*vec[YAW] == 0 &&*/ vec[PITCH] == 0)
{
yaw = 0;
@ -338,7 +358,7 @@ void vectoangles (vec3_t value1, vec3_t angles)
{
float forward;
float yaw, pitch;
if (value1[1] == 0 && value1[0] == 0)
{
yaw = 0;
@ -372,7 +392,7 @@ void vectoangles (vec3_t value1, vec3_t angles)
char *G_CopyString (char *in)
{
char *out;
out = gi.TagMalloc (strlen(in)+1, TAG_LEVEL);
strcpy (out, in);
return out;
@ -381,6 +401,11 @@ char *G_CopyString (char *in)
void G_InitEdict (edict_t *e)
{
if (!e)
{
return;
}
e->inuse = true;
e->classname = "noclass";
e->gravity = 1.0;
@ -414,10 +439,10 @@ edict_t *G_Spawn (void)
return e;
}
}
if (i == game.maxentities)
gi.error ("ED_Alloc: no free edicts");
globals.num_edicts++;
G_InitEdict (e);
return e;
@ -432,6 +457,11 @@ Marks the edict as free
*/
void G_FreeEdict (edict_t *ed)
{
if (!ed)
{
return;
}
gi.unlinkentity (ed); // unlink from world
if ((ed - g_edicts) <= (maxclients->value + BODY_QUEUE_SIZE))
@ -458,6 +488,11 @@ void G_TouchTriggers (edict_t *ent)
int i, num;
edict_t *touch[MAX_EDICTS], *hit;
if (!ent)
{
return;
}
// dead things don't activate triggers!
if ((ent->client || (ent->svflags & SVF_MONSTER)) && (ent->health <= 0))
return;
@ -491,6 +526,11 @@ void G_TouchSolids (edict_t *ent)
int i, num;
edict_t *touch[MAX_EDICTS], *hit;
if (!ent)
{
return;
}
num = gi.BoxEdicts (ent->absmin, ent->absmax, touch
, MAX_EDICTS, AREA_SOLID);
@ -528,6 +568,11 @@ qboolean KillBox (edict_t *ent)
{
trace_t tr;
if (!ent)
{
return false;
}
while (1)
{
tr = gi.trace (ent->s.origin, ent->mins, ent->maxs, ent->s.origin, NULL, MASK_PLAYERSOLID);
@ -557,17 +602,22 @@ qboolean MonsterKillBox (edict_t *ent)
{
trace_t tr;
if (!ent)
{
return false;
}
while (1)
{
tr = gi.trace (ent->s.origin, ent->mins, ent->maxs, ent->s.origin, NULL, MASK_PLAYERSOLID);
if (!tr.ent)
break;
if(!((ent->svflags & SVF_MONSTER) && tr.ent->client && tr.ent->health))
{
// nail it
T_Damage (tr.ent, ent, ent, vec3_origin, ent->s.origin, vec3_origin, 100000, 0, DAMAGE_NO_PROTECTION, MOD_TELEFRAG);
}
if(!((ent->svflags & SVF_MONSTER) && tr.ent->client && tr.ent->health))
{
// nail it
T_Damage (tr.ent, ent, ent, vec3_origin, ent->s.origin, vec3_origin, 100000, 0, DAMAGE_NO_PROTECTION, MOD_TELEFRAG);
}
// if we didn't kill it, fail
if (tr.ent->solid)
@ -589,27 +639,32 @@ qboolean MonsterPlayerKillBox (edict_t *ent)
{
trace_t tr;
if (!ent)
{
return false;
}
while (1)
{
tr = gi.trace (ent->s.origin, ent->mins, ent->maxs, ent->s.origin, ent, MASK_PLAYERSOLID);
if (!tr.ent)
break;
if((ent->svflags & SVF_MONSTER) && tr.ent->client && tr.ent->health)
{
// nail myself
T_Damage (ent, ent, ent, vec3_origin, ent->s.origin, vec3_origin, 100000, 0, DAMAGE_NO_PROTECTION, MOD_TELEFRAG);
return true;
}
else
{
// nail it
T_Damage (tr.ent, ent, ent, vec3_origin, ent->s.origin, vec3_origin, 100000, 0, DAMAGE_NO_PROTECTION, MOD_TELEFRAG);
}
if((ent->svflags & SVF_MONSTER) && tr.ent->client && tr.ent->health)
{
// nail myself
T_Damage (ent, ent, ent, vec3_origin, ent->s.origin, vec3_origin, 100000, 0, DAMAGE_NO_PROTECTION, MOD_TELEFRAG);
return true;
}
else
{
// nail it
T_Damage (tr.ent, ent, ent, vec3_origin, ent->s.origin, vec3_origin, 100000, 0, DAMAGE_NO_PROTECTION, MOD_TELEFRAG);
}
// if we didn't kill it, fail
if (tr.ent->solid)
return false;
return false;
}
return true; // all clear

View file

@ -17,6 +17,11 @@ void check_dodge (edict_t *self, vec3_t start, vec3_t dir, int speed)
trace_t tr;
float eta;
if (!self)
{
return;
}
// easy mode only ducks one quarter the time
if (skill->value == SKILL_EASY)
{
@ -81,6 +86,11 @@ qboolean fire_hit (edict_t *self, vec3_t aim, int damage, int kick)
float range;
vec3_t dir;
if (!self)
{
return false;
}
//see if enemy is in range
VectorSubtract (self->enemy->s.origin, self->s.origin, dir);
range = VectorLength(dir);
@ -155,6 +165,11 @@ void fire_lead (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick
qboolean water = false;
int content_mask = MASK_SHOT | MASK_WATER;
if (!self)
{
return;
}
tr = gi.trace (self->s.origin, NULL, NULL, start, self, MASK_SHOT);
if (!(tr.fraction < 1.0))
{
@ -288,6 +303,11 @@ pistols, rifles, etc....
*/
void fire_bullet (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick, int hspread, int vspread, int mod)
{
if (!self)
{
return;
}
fire_lead (self, start, aimdir, damage, kick, TE_GUNSHOT, hspread, vspread, mod);
}
@ -303,6 +323,11 @@ void fire_shotgun (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int k
{
int i;
if (!self)
{
return;
}
for (i = 0; i < count; i++)
fire_lead (self, start, aimdir, damage, kick, TE_SHOTGUN, hspread, vspread, mod);
}
@ -319,6 +344,11 @@ void blaster_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *
{
int mod;
if (!self || !other)
{
return;
}
if (other == self->owner)
return;
@ -359,6 +389,11 @@ void fire_blaster (edict_t *self, vec3_t start, vec3_t dir, int damage, int spee
edict_t *bolt;
trace_t tr;
if (!self)
{
return;
}
VectorNormalize (dir);
bolt = G_Spawn();
@ -404,6 +439,11 @@ void Grenade_Explode (edict_t *ent)
vec3_t origin;
int mod;
if (!ent)
{
return;
}
if (ent->owner->client)
PlayerNoise(ent->owner, ent->s.origin, PNOISE_IMPACT);
@ -458,6 +498,11 @@ void Grenade_Explode (edict_t *ent)
void Grenade_Touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
{
if (!ent || !other)
{
return;
}
if (other == ent->owner)
return;
@ -493,6 +538,11 @@ void fire_grenade (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int s
vec3_t dir;
vec3_t forward, right, up;
if (!self)
{
return;
}
vectoangles (aimdir, dir);
AngleVectors (dir, forward, right, up);
@ -526,6 +576,11 @@ void fire_grenade2 (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int
vec3_t dir;
vec3_t forward, right, up;
if (!self)
{
return;
}
vectoangles (aimdir, dir);
AngleVectors (dir, forward, right, up);
@ -575,6 +630,11 @@ void rocket_touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *su
vec3_t origin;
int n;
if (!ent || !other)
{
return;
}
if (other == ent->owner)
return;
@ -625,6 +685,11 @@ void fire_rocket (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed
{
edict_t *rocket;
if (!self)
{
return;
}
rocket = G_Spawn();
VectorCopy (start, rocket->s.origin);
VectorCopy (dir, rocket->movedir);
@ -668,6 +733,11 @@ void fire_rail (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick
int mask;
qboolean water;
if (!self)
{
return;
}
VectorMA (start, 8192, aimdir, end);
VectorCopy (start, from);
ignore = self;
@ -728,6 +798,11 @@ void bfg_explode (edict_t *self)
vec3_t v;
float dist;
if (!self)
{
return;
}
if (self->s.frame == 0)
{
// the BFG effect
@ -769,6 +844,11 @@ void bfg_explode (edict_t *self)
void bfg_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
{
if (!self || !other)
{
return;
}
if (other == self->owner)
return;
@ -817,6 +897,11 @@ void bfg_think (edict_t *self)
int dmg;
trace_t tr;
if (!self)
{
return;
}
if (deathmatch->value)
dmg = 5;
else
@ -888,6 +973,11 @@ void fire_bfg (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, f
{
edict_t *bfg;
if (!self)
{
return;
}
bfg = G_Spawn();
VectorCopy (start, bfg->s.origin);
VectorCopy (dir, bfg->movedir);

View file

@ -67,6 +67,11 @@ mmove_t actor_move_stand = {FRAME_stand101, FRAME_stand140, actor_frames_stand,
void actor_stand (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &actor_move_stand;
// randomize on startup
@ -93,6 +98,11 @@ mmove_t actor_move_walk = {FRAME_walk01, FRAME_walk08, actor_frames_walk, NULL};
void actor_walk (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &actor_move_walk;
}
@ -116,6 +126,11 @@ mmove_t actor_move_run = {FRAME_run02, FRAME_run07, actor_frames_run, NULL};
void actor_run (edict_t *self)
{
if (!self)
{
return;
}
if ((level.time < self->pain_debounce_time) && (!self->enemy))
{
if (self->movetarget)
@ -212,6 +227,11 @@ void actor_pain (edict_t *self, edict_t *other, float kick, int damage)
{
int n;
if (!self || !other)
{
return;
}
if (self->health < (self->max_health / 2))
self->s.skinnum = 1;
@ -251,6 +271,11 @@ void actorMachineGun (edict_t *self)
vec3_t start, target;
vec3_t forward, right;
if (!self)
{
return;
}
AngleVectors (self->s.angles, forward, right, NULL);
G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_ACTOR_MACHINEGUN_1], forward, right, start);
if (self->enemy)
@ -278,6 +303,11 @@ void actorMachineGun (edict_t *self)
void actor_dead (edict_t *self)
{
if (!self)
{
return;
}
VectorSet (self->mins, -16, -16, -24);
VectorSet (self->maxs, 16, 16, -8);
self->movetype = MOVETYPE_TOSS;
@ -320,6 +350,11 @@ void actor_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage
{
int n;
if (!self)
{
return;
}
// check for gib
if (self->health <= -80)
{
@ -349,6 +384,11 @@ void actor_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage
void actor_fire (edict_t *self)
{
if (!self)
{
return;
}
actorMachineGun (self);
if (level.time >= self->monsterinfo.pausetime)
@ -370,6 +410,11 @@ void actor_attack(edict_t *self)
{
int n;
if (!self)
{
return;
}
self->monsterinfo.currentmove = &actor_move_attack;
n = (rand() & 15) + 3 + 7;
self->monsterinfo.pausetime = level.time + n * FRAMETIME;
@ -380,6 +425,11 @@ void actor_use (edict_t *self, edict_t *other, edict_t *activator)
{
vec3_t v;
if (!self)
{
return;
}
self->goalentity = self->movetarget = G_PickTarget(self->target);
if ((!self->movetarget) || (strcmp(self->movetarget->classname, "target_actor") != 0))
{
@ -402,6 +452,11 @@ void actor_use (edict_t *self, edict_t *other, edict_t *activator)
void SP_misc_actor (edict_t *self)
{
if (!self)
{
return;
}
if (deathmatch->value)
{
G_FreeEdict (self);
@ -475,9 +530,14 @@ void target_actor_touch (edict_t *self, edict_t *other, cplane_t *plane, csurfac
{
vec3_t v;
if (!self || !other)
{
return;
}
if (other->movetarget != self)
return;
if (other->enemy)
return;
@ -501,7 +561,7 @@ void target_actor_touch (edict_t *self, edict_t *other, cplane_t *plane, csurfac
{
other->velocity[0] = self->movedir[0] * self->speed;
other->velocity[1] = self->movedir[1] * self->speed;
if (other->groundentity)
{
other->groundentity = NULL;
@ -562,6 +622,11 @@ void target_actor_touch (edict_t *self, edict_t *other, cplane_t *plane, csurfac
void SP_target_actor (edict_t *self)
{
if (!self)
{
return;
}
if (!self->targetname)
gi.dprintf ("%s with no targetname at %s\n", self->classname, vtos(self->s.origin));

View file

@ -19,11 +19,21 @@ static int sound_search;
void berserk_sight (edict_t *self, edict_t *other)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
}
void berserk_search (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_search, 1, ATTN_NORM, 0);
}
@ -41,6 +51,11 @@ mmove_t berserk_move_stand = {FRAME_stand1, FRAME_stand5, berserk_frames_stand,
void berserk_stand (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &berserk_move_stand;
}
@ -71,6 +86,11 @@ mmove_t berserk_move_stand_fidget = {FRAME_standb1, FRAME_standb20, berserk_fram
void berserk_fidget (edict_t *self)
{
if (!self)
{
return;
}
if (self->monsterinfo.aiflags & AI_STAND_GROUND)
return;
if (random() > 0.15)
@ -100,6 +120,11 @@ mmove_t berserk_move_walk = {FRAME_walkc1, FRAME_walkc11, berserk_frames_walk, N
void berserk_walk (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &berserk_move_walk;
}
@ -116,6 +141,11 @@ mmove_t berserk_move_run1 = {FRAME_run1, FRAME_run6, berserk_frames_run1, NULL};
void berserk_run (edict_t *self)
{
if (!self)
{
return;
}
if (self->monsterinfo.aiflags & AI_STAND_GROUND)
self->monsterinfo.currentmove = &berserk_move_stand;
else
@ -125,6 +155,11 @@ void berserk_run (edict_t *self)
void berserk_attack_spike (edict_t *self)
{
if (!self)
{
return;
}
static vec3_t aim = {MELEE_DISTANCE, 0, -24};
fire_hit (self, aim, (15 + (rand() % 6)), 400); // Faster attack -- upwards and backwards
}
@ -132,6 +167,11 @@ void berserk_attack_spike (edict_t *self)
void berserk_swing (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_WEAPON, sound_punch, 1, ATTN_NORM, 0);
}
@ -153,12 +193,17 @@ void berserk_attack_club (edict_t *self)
{
vec3_t aim;
if (!self)
{
return;
}
VectorSet (aim, MELEE_DISTANCE, self->mins[0], -4);
fire_hit (self, aim, (5 + (rand() % 6)), 400); // Slower attack
}
mframe_t berserk_frames_attack_club [] =
{
{
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
@ -197,12 +242,17 @@ mframe_t berserk_frames_attack_strike [] =
{ai_move, 9.7, NULL},
{ai_move, 13.6, NULL}
};
mmove_t berserk_move_attack_strike = {FRAME_att_c21, FRAME_att_c34, berserk_frames_attack_strike, berserk_run};
void berserk_melee (edict_t *self)
{
if (!self)
{
return;
}
if ((rand() % 2) == 0)
self->monsterinfo.currentmove = &berserk_move_attack_spike;
else
@ -246,6 +296,11 @@ mmove_t berserk_move_pain2 = {FRAME_painb1, FRAME_painb20, berserk_frames_pain2,
void berserk_pain (edict_t *self, edict_t *other, float kick, int damage)
{
if (!self)
{
return;
}
if (self->health < (self->max_health / 2))
self->s.skinnum = 1;
@ -267,6 +322,11 @@ void berserk_pain (edict_t *self, edict_t *other, float kick, int damage)
void berserk_dead (edict_t *self)
{
if (!self)
{
return;
}
VectorSet (self->mins, -16, -16, -24);
VectorSet (self->maxs, 16, 16, -8);
self->movetype = MOVETYPE_TOSS;
@ -314,6 +374,11 @@ void berserk_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int dama
{
int n;
if (!self)
{
return;
}
if (self->health <= self->gib_health)
{
gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0);
@ -344,6 +409,11 @@ void berserk_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int dama
*/
void SP_monster_berserk (edict_t *self)
{
if (!self)
{
return;
}
if (deathmatch->value)
{
G_FreeEdict (self);

View file

@ -45,18 +45,33 @@ void zboss_attack (edict_t *self);
void zboss_walksound (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_BODY, sound_walk, 1, ATTN_NORM, 0);
}
void zboss_sight (edict_t *self, edict_t *other)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
}
void possibleBossTaunt(edict_t *self)
{
if (!self)
{
return;
}
float r = random();
if(random() < 0.10)
@ -155,6 +170,11 @@ mmove_t zboss_stand2 = {FRAME_stand2start, FRAME_stand2end, zboss_frames_stand2,
void zboss_standidle (edict_t *self)
{
if (!self)
{
return;
}
if (random() < 0.8)
{
gi.sound (self, CHAN_VOICE, sound_idle1, 1, ATTN_NORM, 0);
@ -187,6 +207,11 @@ mmove_t zboss_move_postwalk = {FRAME_postWalkStart, FRAME_postWalkEnd, zboss_fra
void zboss_postWalkRun (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &zboss_move_postwalk;
}
@ -229,11 +254,21 @@ mmove_t zboss_move_walk = {FRAME_walkStart, FRAME_walkEnd, zboss_frames_walk, zb
void zboss_walk (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &zboss_move_prewalk;
}
void zboss_walk2(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &zboss_move_walk;
}
@ -276,6 +311,11 @@ mmove_t zboss_move_run = {FRAME_walkStart, FRAME_walkEnd, zboss_frames_run, NULL
void zboss_run (edict_t *self)
{
if (!self)
{
return;
}
if (self->monsterinfo.aiflags & AI_STAND_GROUND)
zboss_stand(self);
else
@ -284,6 +324,11 @@ void zboss_run (edict_t *self)
void zboss_run2 (edict_t *self)
{
if (!self)
{
return;
}
if (self->monsterinfo.aiflags & AI_STAND_GROUND)
zboss_stand(self);
else
@ -295,6 +340,11 @@ void zboss_run2 (edict_t *self)
//
void zboss_stand (edict_t *self)
{
if (!self)
{
return;
}
if(self->monsterinfo.currentmove == &zboss_move_prewalk ||
self->monsterinfo.currentmove == &zboss_move_walk ||
self->monsterinfo.currentmove == &zboss_move_prerun ||
@ -367,6 +417,11 @@ void zboss_pain (edict_t *self, edict_t *other, float kick, int damage)
float r;
float hbreak = (self->max_health / 3.0);
if (!self)
{
return;
}
// set the skin
if (self->health < hbreak)
{
@ -469,6 +524,11 @@ void zboss_pain (edict_t *self, edict_t *other, float kick, int damage)
void zboss_swing (edict_t *self)
{
if (!self)
{
return;
}
static vec3_t aim = {MELEE_DISTANCE, 0, -24};
fire_hit (self, aim, (15 + (rand() % 6)), 800);
}
@ -489,6 +549,11 @@ mmove_t zboss_move_attack2c = {FRAME_attack2cStart, FRAME_attack2cEnd, zboss_fra
void zboss_melee2 (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &zboss_move_attack2c;
gi.sound (self, CHAN_WEAPON, sound_swing, 1, ATTN_NORM, 0);
}
@ -510,6 +575,11 @@ mmove_t zboss_move_premelee = {FRAME_preHookStart, FRAME_preHookEnd, zboss_frame
void zboss_melee (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_BODY, sound_raisegun, 1, ATTN_NORM, 0);
self->monsterinfo.currentmove = &zboss_move_premelee;
}
@ -536,6 +606,11 @@ mmove_t zboss_move_attack1b = {FRAME_attack1bStart, FRAME_attack1bEnd, zboss_fra
void zboss_reloadRockets(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.aiflags &= ~AI_ONESHOTTARGET;
self->monsterinfo.currentmove = &zboss_move_attack1b;
}
@ -559,6 +634,11 @@ void FireFlare(edict_t *self)
vec3_t dir;
vec3_t vec;
if (!self)
{
return;
}
int offset = (self->s.frame - 71) / 3;
AngleVectors (self->s.angles, forward, right, NULL);
@ -595,6 +675,11 @@ void FireRocket(edict_t *self)
vec3_t dir;
vec3_t vec;
if (!self)
{
return;
}
int offset = (self->s.frame - 71) / 3;
AngleVectors (self->s.angles, forward, right, NULL);
@ -661,6 +746,11 @@ void zboss_reelInGraaple2(edict_t *self)
vec3_t hookoffset = {-5, -24, 34};
vec3_t forward, right;
if (!self)
{
return;
}
AngleVectors (self->s.angles, forward, right, NULL);
G_ProjectSource(self->s.origin, hookoffset, forward, right, vec);
VectorSubtract (vec, self->laser->s.origin, dir);
@ -704,6 +794,11 @@ void HookDragThink (edict_t *self)
vec3_t hookoffset = {-5, -24, 34};
vec3_t forward, right;
if (!self)
{
return;
}
if(self->enemy && self->enemy->health > 0)
{
VectorCopy (self->enemy->s.origin, self->s.origin);
@ -769,6 +864,11 @@ void HookThink(edict_t *self)
vec3_t hookoffset = {-3, -24, 34};
vec3_t forward, right;
if (!self)
{
return;
}
if(self->powerarmor_time < level.time)
{
self->powerarmor_time = level.time + 15;
@ -802,6 +902,11 @@ void FireHook(edict_t *self)
edict_t *hook;
float speed;
if (!self)
{
return;
}
AngleVectors (self->s.angles, forward, right, NULL);
G_ProjectSource (self->s.origin, hookoffset, forward, right, start);
@ -843,6 +948,11 @@ void FireHook(edict_t *self)
void zboss_reelInGraaple(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &zboss_move_attack2b;
}
@ -872,11 +982,21 @@ mmove_t zboss_move_posthook = {FRAME_postHookStart, FRAME_postHookEnd, zboss_fra
void zboss_posthook(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &zboss_move_posthook;
}
void zboss_chooseHookRocket(edict_t *self)
{
if (!self)
{
return;
}
if(random() < 0.2 && !(self->monsterinfo.aiflags & AI_ONESHOTTARGET))
{
self->monsterinfo.currentmove = &zboss_move_attack2a;
@ -904,24 +1024,34 @@ mmove_t zboss_move_prehook = {FRAME_preHookStart, FRAME_preHookEnd, zboss_frames
// Plasma Cannon
void PlasmaballBlastAnim(edict_t *ent)
void PlasmaballBlastAnim(edict_t *ent)
{
ent->s.frame++;
ent->s.skinnum++;
ent->s.frame++;
ent->s.skinnum++;
if(ent->s.frame > 1)
{
if (!ent)
{
return;
}
if(ent->s.frame > 1)
{
G_FreeEdict(ent);
return;
}
else
{
ent->nextthink = level.time + FRAMETIME;
}
}
else
{
ent->nextthink = level.time + FRAMETIME;
}
}
void Plasmaball_Explode (edict_t *ent)
{
if (!ent)
{
return;
}
//FIXME: if we are onground then raise our Z just a bit since we are a point?
if (ent->enemy)
{
@ -956,6 +1086,11 @@ void Plasmaball_Explode (edict_t *ent)
void Plasmaball_Touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
{
if (!ent || !other)
{
return;
}
if (other == ent->owner)
return;
@ -975,6 +1110,11 @@ void fire_plasmaCannon (edict_t *self, vec3_t start, vec3_t aimdir, int damage,
vec3_t dir;
vec3_t forward, right, up;
if (!self)
{
return;
}
vectoangles (aimdir, dir);
AngleVectors (dir, forward, right, up);
@ -1024,6 +1164,11 @@ void FireCannon(edict_t *self)
vec3_t vec;
float distance;
if (!self)
{
return;
}
int offset = (self->s.frame - 119) / 2;
AngleVectors (self->s.angles, forward, right, NULL);
@ -1097,6 +1242,11 @@ mmove_t zboss_move_attack3 = {FRAME_attack3Start, FRAME_attack3End, zboss_frames
void zboss_fireCannons(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &zboss_move_attack3;
self->seq = 0;
@ -1123,6 +1273,11 @@ mmove_t zboss_move_postcannon = {FRAME_postCannonStart, FRAME_postCannonEnd, zbo
void zboss_postcannon(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &zboss_move_postcannon;
}
@ -1153,6 +1308,11 @@ mmove_t zboss_move_c2h = {FRAME_attackC2HStart, FRAME_attackC2HEnd, zboss_frames
void zboss_chooseNextAttack(edict_t *self)
{
if (!self)
{
return;
}
if (self->enemy == NULL)
return;
@ -1203,6 +1363,11 @@ void zboss_chooseNextAttack(edict_t *self)
void zboss_attack (edict_t *self)
{
if (!self)
{
return;
}
if (self->enemy == NULL)
return;
@ -1226,6 +1391,11 @@ Death Stuff Starts
void zboss_dead (edict_t *self)
{
if (!self)
{
return;
}
VectorSet (self->mins, -32, -74, -30);
VectorSet (self->maxs, 32, 40, 12);
self->movetype = MOVETYPE_TOSS;
@ -1265,6 +1435,11 @@ void FireDeadRocket1(edict_t *self)
vec3_t start;
vec3_t rocketoffset = {-26, -26, 25};
if (!self)
{
return;
}
AngleVectors (self->s.angles, forward, right, NULL);
G_ProjectSource (self->s.origin, rocketoffset, forward, right, start);
@ -1283,6 +1458,11 @@ void FireDeadRocket2(edict_t *self)
vec3_t start;
vec3_t rocketoffset = {-16, -21, 20};
if (!self)
{
return;
}
AngleVectors (self->s.angles, forward, right, NULL);
G_ProjectSource (self->s.origin, rocketoffset, forward, right, start);
@ -1302,6 +1482,11 @@ void FireDeadRocket3(edict_t *self)
vec3_t start;
vec3_t rocketoffset = {-17, -20, 30};
if (!self)
{
return;
}
AngleVectors (self->s.angles, forward, right, up);
G_ProjectSource (self->s.origin, rocketoffset, forward, right, start);
@ -1316,10 +1501,15 @@ void FireDeadRocket3(edict_t *self)
void FireDeadRocket4(edict_t *self)
{
vec3_t forward, right, up;
vec3_t start;
vec3_t rocketoffset = {-8, -16, 17};
if (!self)
{
return;
}
AngleVectors (self->s.angles, forward, right, up);
G_ProjectSource (self->s.origin, rocketoffset, forward, right, start);
@ -1338,6 +1528,11 @@ void FireDeadRocket5(edict_t *self)
vec3_t start;
vec3_t rocketoffset = {-10, -16, 30};
if (!self)
{
return;
}
AngleVectors (self->s.angles, forward, right, up);
G_ProjectSource (self->s.origin, rocketoffset, forward, right, start);
@ -1357,6 +1552,11 @@ void FireDeadRocket6(edict_t *self)
vec3_t start;
vec3_t rocketoffset = {0, -18, 25};
if (!self)
{
return;
}
AngleVectors (self->s.angles, forward, right, up);
G_ProjectSource (self->s.origin, rocketoffset, forward, right, start);
@ -1377,6 +1577,11 @@ void FireDeadRocket7(edict_t *self)
vec3_t start;
vec3_t rocketoffset = {17, -27, 30};
if (!self)
{
return;
}
AngleVectors (self->s.angles, forward, right, up);
G_ProjectSource (self->s.origin, rocketoffset, forward, right, start);
@ -1397,6 +1602,11 @@ void FireDeadCannon1(edict_t *self)
vec3_t start;
vec3_t cannonoffset = {9, -46, 33};
if (!self)
{
return;
}
AngleVectors (self->s.angles, forward, right, NULL);
G_ProjectSource (self->s.origin, cannonoffset, forward, right, start);
@ -1415,6 +1625,11 @@ void FireDeadCannon2(edict_t *self)
vec3_t start;
vec3_t cannonoffset = {3, -31, 37};
if (!self)
{
return;
}
AngleVectors (self->s.angles, forward, right, NULL);
G_ProjectSource (self->s.origin, cannonoffset, forward, right, start);
@ -1433,6 +1648,11 @@ void FireDeadCannon3(edict_t *self)
vec3_t start;
vec3_t cannonoffset = {-21, -19, 24};
if (!self)
{
return;
}
AngleVectors (self->s.angles, forward, right, NULL);
G_ProjectSource (self->s.origin, cannonoffset, forward, right, start);
@ -1447,6 +1667,11 @@ void FireDeadCannon3(edict_t *self)
void DeadHookTouch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
{
if (!ent || !other)
{
return;
}
if (other == ent->owner)
return;
@ -1467,6 +1692,11 @@ void FireDeadGrapple(edict_t *self)
edict_t *hook;
float speed;
if (!self)
{
return;
}
if(self->s.modelindex3 == 0) // hook already out...
return;
@ -1560,6 +1790,11 @@ void zboss_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage
{
int n;
if (!self)
{
return;
}
if(self->laser)
{
G_FreeEdict(self->laser);
@ -1589,15 +1824,15 @@ void zboss_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage
// todo
if (random() < 0.5)
{
{
gi.sound (self, CHAN_VOICE, sound_die1, 1, ATTN_NORM, 0);
self->monsterinfo.currentmove = &zboss_move_death1;
}
else
{
self->monsterinfo.currentmove = &zboss_move_death1;
}
else
{
gi.sound (self, CHAN_VOICE, sound_die2, 1, ATTN_NORM, 0);
self->monsterinfo.currentmove = &zboss_move_death2;
}
self->monsterinfo.currentmove = &zboss_move_death2;
}
}
@ -1636,6 +1871,11 @@ void SP_monster_zboss_precache(void)
*/
void SP_monster_zboss (edict_t *self)
{
if (!self)
{
return;
}
if (deathmatch->value)
{
G_FreeEdict (self);
@ -1703,6 +1943,11 @@ void SP_monster_zboss (edict_t *self)
void trigger_zboss (edict_t *self, edict_t *other, edict_t *activator)
{
if (!self)
{
return;
}
edict_t *boss = NULL;
while ((boss = G_Find (boss, FOFS(targetname), self->target)) != NULL)
@ -1718,6 +1963,11 @@ void trigger_zboss (edict_t *self, edict_t *other, edict_t *activator)
void SP_target_zboss_target(edict_t *self)
{
if (!self)
{
return;
}
if(!self->target)
{
gi.dprintf("target_zboss_target does not have a target");

View file

@ -21,6 +21,11 @@ static int sound_search1;
void boss2_search (edict_t *self)
{
if (!self)
{
return;
}
if (random() < 0.5)
gi.sound (self, CHAN_VOICE, sound_search1, 1, ATTN_NONE, 0);
}
@ -40,6 +45,11 @@ void Boss2Rocket (edict_t *self)
vec3_t dir;
vec3_t vec;
if (!self)
{
return;
}
AngleVectors (self->s.angles, forward, right, NULL);
G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_BOSS2_ROCKET_1], forward, right, start);
@ -76,6 +86,11 @@ void boss2_firebullet_right (edict_t *self)
vec3_t forward, right, target;
vec3_t start;
if (!self)
{
return;
}
AngleVectors (self->s.angles, forward, right, NULL);
G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_BOSS2_MACHINEGUN_R1], forward, right, start);
@ -97,7 +112,12 @@ void boss2_firebullet_left (edict_t *self)
{
vec3_t forward, right, target;
vec3_t start;
if (!self)
{
return;
}
AngleVectors (self->s.angles, forward, right, NULL);
G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_BOSS2_MACHINEGUN_L1], forward, right, start);
@ -118,9 +138,14 @@ void boss2_firebullet_left (edict_t *self)
void Boss2MachineGun (edict_t *self)
{
boss2_firebullet_left(self);
if (!self)
{
return;
}
boss2_firebullet_left(self);
boss2_firebullet_right(self);
}
}
mframe_t boss2_frames_stand [] =
@ -385,11 +410,21 @@ mmove_t boss2_move_death = {FRAME_death2, FRAME_death50, boss2_frames_death, bos
void boss2_stand (edict_t *self)
{
self->monsterinfo.currentmove = &boss2_move_stand;
if (!self)
{
return;
}
self->monsterinfo.currentmove = &boss2_move_stand;
}
void boss2_run (edict_t *self)
{
if (!self)
{
return;
}
if (self->monsterinfo.aiflags & AI_STAND_GROUND)
self->monsterinfo.currentmove = &boss2_move_stand;
else
@ -398,6 +433,11 @@ void boss2_run (edict_t *self)
void boss2_walk (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &boss2_move_walk;
}
@ -406,9 +446,14 @@ void boss2_attack (edict_t *self)
vec3_t vec;
float range;
if (!self)
{
return;
}
VectorSubtract (self->enemy->s.origin, self->s.origin, vec);
range = VectorLength (vec);
if (range <= 125)
{
self->monsterinfo.currentmove = &boss2_move_attack_pre_mg;
@ -424,11 +469,21 @@ void boss2_attack (edict_t *self)
void boss2_attack_mg (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &boss2_move_attack_mg;
}
void boss2_reattack_mg (edict_t *self)
{
if (!self)
{
return;
}
if ( infront(self, self->enemy) )
if (random() <= 0.7)
self->monsterinfo.currentmove = &boss2_move_attack_mg;
@ -441,6 +496,11 @@ void boss2_reattack_mg (edict_t *self)
void boss2_pain (edict_t *self, edict_t *other, float kick, int damage)
{
if (!self)
{
return;
}
if (self->health < (self->max_health / 2))
self->s.skinnum = 1;
@ -468,6 +528,11 @@ void boss2_pain (edict_t *self, edict_t *other, float kick, int damage)
void boss2_dead (edict_t *self)
{
if (!self)
{
return;
}
VectorSet (self->mins, -56, -56, 0);
VectorSet (self->maxs, 56, 56, 80);
self->movetype = MOVETYPE_TOSS;
@ -478,6 +543,11 @@ void boss2_dead (edict_t *self)
void boss2_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_death, 1, ATTN_NONE, 0);
self->deadflag = DEAD_DEAD;
self->takedamage = DAMAGE_NO;
@ -495,6 +565,11 @@ qboolean Boss2_CheckAttack (edict_t *self)
int enemy_range;
float enemy_yaw;
if (!self)
{
return false;
}
if (self->enemy->health > 0)
{
// see if any entities are in the way of the shot
@ -583,6 +658,11 @@ qboolean Boss2_CheckAttack (edict_t *self)
*/
void SP_monster_boss2 (edict_t *self)
{
if (!self)
{
return;
}
if (deathmatch->value)
{
G_FreeEdict (self);

View file

@ -11,6 +11,11 @@ boss3
void Use_Boss3 (edict_t *ent, edict_t *other, edict_t *activator)
{
if (!ent)
{
return;
}
gi.WriteByte (svc_temp_entity);
gi.WriteByte (TE_BOSSTPORT);
gi.WritePosition (ent->s.origin);
@ -20,6 +25,11 @@ void Use_Boss3 (edict_t *ent, edict_t *other, edict_t *activator)
void Think_Boss3Stand (edict_t *ent)
{
if (!ent)
{
return;
}
if (ent->s.frame == FRAME_stand260)
ent->s.frame = FRAME_stand201;
else
@ -33,6 +43,11 @@ Just stands and cycles in one place until targeted, then teleports away.
*/
void SP_monster_boss3_stand (edict_t *self)
{
if (!self)
{
return;
}
if (deathmatch->value)
{
G_FreeEdict (self);

View file

@ -35,6 +35,11 @@ void jorg_search (edict_t *self)
{
float r;
if (!self)
{
return;
}
r = random();
if (r <= 0.3)
@ -119,28 +124,53 @@ mmove_t jorg_move_stand = {FRAME_stand01, FRAME_stand51, jorg_frames_stand, NULL
void jorg_idle (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_NORM,0);
}
void jorg_death_hit (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_BODY, sound_death_hit, 1, ATTN_NORM,0);
}
void jorg_step_left (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_BODY, sound_step_left, 1, ATTN_NORM,0);
}
void jorg_step_right (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_BODY, sound_step_right, 1, ATTN_NORM,0);
}
void jorg_stand (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &jorg_move_stand;
}
@ -209,11 +239,21 @@ mmove_t jorg_move_end_walk = {FRAME_walk20, FRAME_walk25, jorg_frames_end_walk,
void jorg_walk (edict_t *self)
{
self->monsterinfo.currentmove = &jorg_move_walk;
if (!self)
{
return;
}
self->monsterinfo.currentmove = &jorg_move_walk;
}
void jorg_run (edict_t *self)
{
if (!self)
{
return;
}
if (self->monsterinfo.aiflags & AI_STAND_GROUND)
self->monsterinfo.currentmove = &jorg_move_stand;
else
@ -374,6 +414,11 @@ mmove_t jorg_move_end_attack1 = {FRAME_attak115, FRAME_attak118, jorg_frames_end
void jorg_reattack1(edict_t *self)
{
if (!self)
{
return;
}
if (visible(self, self->enemy))
if (random() < 0.9)
self->monsterinfo.currentmove = &jorg_move_attack1;
@ -391,11 +436,20 @@ void jorg_reattack1(edict_t *self)
void jorg_attack1(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &jorg_move_attack1;
}
void jorg_pain (edict_t *self, edict_t *other, float kick, int damage)
{
if (!self)
{
return;
}
if (self->health < (self->max_health / 2))
self->s.skinnum = 1;
@ -460,6 +514,11 @@ void jorgBFG (edict_t *self)
vec3_t dir;
vec3_t vec;
if (!self)
{
return;
}
AngleVectors (self->s.angles, forward, right, NULL);
G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_JORG_BFG_1], forward, right, start);
@ -476,6 +535,11 @@ void jorg_firebullet_right (edict_t *self)
vec3_t forward, right, target;
vec3_t start;
if (!self)
{
return;
}
AngleVectors (self->s.angles, forward, right, NULL);
G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_JORG_MACHINEGUN_R1], forward, right, start);
@ -498,6 +562,11 @@ void jorg_firebullet_left (edict_t *self)
vec3_t forward, right, target;
vec3_t start;
if (!self)
{
return;
}
AngleVectors (self->s.angles, forward, right, NULL);
G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_JORG_MACHINEGUN_L1], forward, right, start);
@ -517,6 +586,11 @@ void jorg_firebullet_left (edict_t *self)
void jorg_firebullet (edict_t *self)
{
if (!self)
{
return;
}
jorg_firebullet_left(self);
jorg_firebullet_right(self);
}
@ -525,7 +599,12 @@ void jorg_attack(edict_t *self)
{
vec3_t vec;
float range;
if (!self)
{
return;
}
VectorSubtract (self->enemy->s.origin, self->s.origin, vec);
range = VectorLength (vec);
@ -549,6 +628,11 @@ void jorg_dead (edict_t *self)
void jorg_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_death, 1, ATTN_NORM, 0);
self->deadflag = DEAD_DEAD;
self->takedamage = DAMAGE_NO;
@ -567,6 +651,11 @@ qboolean Jorg_CheckAttack (edict_t *self)
int enemy_range;
float enemy_yaw;
if (!self)
{
return false;
}
if (self->enemy->health > 0)
{
// see if any entities are in the way of the shot
@ -656,6 +745,11 @@ void MakronPrecache (void);
*/
void SP_monster_jorg (edict_t *self)
{
if (!self)
{
return;
}
if (deathmatch->value)
{
G_FreeEdict (self);

View file

@ -38,6 +38,11 @@ void makron_taunt (edict_t *self)
{
float r;
if (!self)
{
return;
}
r=random();
if (r <= 0.3)
gi.sound (self, CHAN_AUTO, sound_taunt1, 1, ATTN_NONE, 0);
@ -118,6 +123,11 @@ mmove_t makron_move_stand = {FRAME_stand201, FRAME_stand260, makron_frames_stand
void makron_stand (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &makron_move_stand;
}
@ -138,31 +148,61 @@ mmove_t makron_move_run = {FRAME_walk204, FRAME_walk213, makron_frames_run, NULL
void makron_hit (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_AUTO, sound_hit, 1, ATTN_NONE,0);
}
void makron_popup (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_BODY, sound_popup, 1, ATTN_NONE,0);
}
void makron_step_left (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_BODY, sound_step_left, 1, ATTN_NORM,0);
}
void makron_step_right (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_BODY, sound_step_right, 1, ATTN_NORM,0);
}
void makron_brainsplorch (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_brainsplorch, 1, ATTN_NORM,0);
}
void makron_prerailgun (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_WEAPON, sound_prerailgun, 1, ATTN_NORM,0);
}
@ -184,11 +224,21 @@ mmove_t makron_move_walk = {FRAME_walk204, FRAME_walk213, makron_frames_run, NUL
void makron_walk (edict_t *self)
{
self->monsterinfo.currentmove = &makron_move_walk;
if (!self)
{
return;
}
self->monsterinfo.currentmove = &makron_move_walk;
}
void makron_run (edict_t *self)
{
if (!self)
{
return;
}
if (self->monsterinfo.aiflags & AI_STAND_GROUND)
self->monsterinfo.currentmove = &makron_move_stand;
else
@ -395,6 +445,11 @@ void makronBFG (edict_t *self)
vec3_t dir;
vec3_t vec;
if (!self)
{
return;
}
AngleVectors (self->s.angles, forward, right, NULL);
G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_MAKRON_BFG], forward, right, start);
@ -480,6 +535,11 @@ mmove_t makron_move_attack5 = {FRAME_attak501, FRAME_attak516, makron_frames_att
void MakronSaveloc (edict_t *self)
{
if (!self)
{
return;
}
VectorCopy (self->enemy->s.origin, self->pos1); //save for aiming the shot
self->pos1[2] += self->enemy->viewheight;
}
@ -491,6 +551,11 @@ void MakronRailgun (edict_t *self)
vec3_t dir;
vec3_t forward, right;
if (!self)
{
return;
}
AngleVectors (self->s.angles, forward, right, NULL);
G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_MAKRON_RAILGUN_1], forward, right, start);
@ -510,6 +575,11 @@ void MakronHyperblaster (edict_t *self)
vec3_t forward, right;
int flash_number;
if (!self)
{
return;
}
flash_number = MZ2_MAKRON_BLASTER_1 + (self->s.frame - FRAME_attak405);
AngleVectors (self->s.angles, forward, right, NULL);
@ -541,6 +611,11 @@ void MakronHyperblaster (edict_t *self)
void makron_pain (edict_t *self, edict_t *other, float kick, int damage)
{
if (!self)
{
return;
}
if (self->health < (self->max_health / 2))
self->s.skinnum = 1;
@ -589,6 +664,11 @@ void makron_pain (edict_t *self, edict_t *other, float kick, int damage)
void makron_sight(edict_t *self, edict_t *other)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &makron_move_sight;
}
@ -598,6 +678,11 @@ void makron_attack(edict_t *self)
float range;
float r;
if (!self)
{
return;
}
r = random();
VectorSubtract (self->enemy->s.origin, self->s.origin, vec);
@ -620,10 +705,15 @@ Makron Torso. This needs to be spawned in
void makron_torso_think (edict_t *self)
{
if (!self)
{
return;
}
if (++self->s.frame < 365)
self->nextthink = level.time + FRAMETIME;
else
{
{
self->s.frame = 346;
self->nextthink = level.time + FRAMETIME;
}
@ -631,6 +721,11 @@ void makron_torso_think (edict_t *self)
void makron_torso (edict_t *ent)
{
if (!ent)
{
return;
}
ent->movetype = MOVETYPE_NONE;
ent->solid = SOLID_NOT;
VectorSet (ent->mins, -8, -8, 0);
@ -650,6 +745,11 @@ void makron_torso (edict_t *ent)
void makron_dead (edict_t *self)
{
if (!self)
{
return;
}
VectorSet (self->mins, -60, -60, 0);
VectorSet (self->maxs, 60, 60, 72);
self->movetype = MOVETYPE_TOSS;
@ -665,6 +765,11 @@ void makron_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damag
int n;
if (!self)
{
return;
}
self->s.sound = 0;
// check for gib
if (self->health <= self->gib_health)
@ -707,6 +812,11 @@ qboolean Makron_CheckAttack (edict_t *self)
int enemy_range;
float enemy_yaw;
if (!self)
{
return false;
}
if (self->enemy->health > 0)
{
// see if any entities are in the way of the shot
@ -818,6 +928,11 @@ void MakronPrecache (void)
*/
void SP_monster_makron (edict_t *self)
{
if (!self)
{
return;
}
if (deathmatch->value)
{
G_FreeEdict (self);
@ -867,6 +982,11 @@ void MakronSpawn (edict_t *self)
vec3_t vec;
edict_t *player;
if (!self)
{
return;
}
SP_monster_makron (self);
// jump at player
@ -893,6 +1013,11 @@ void MakronToss (edict_t *self)
{
edict_t *ent;
if (!self)
{
return;
}
ent = G_Spawn ();
ent->nextthink = level.time + 0.8;
ent->think = MakronSpawn;

View file

@ -28,11 +28,21 @@ static int sound_melee3;
void brain_sight (edict_t *self, edict_t *other)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
}
void brain_search (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_search, 1, ATTN_NORM, 0);
}
@ -84,6 +94,11 @@ mmove_t brain_move_stand = {FRAME_stand01, FRAME_stand30, brain_frames_stand, NU
void brain_stand (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &brain_move_stand;
}
@ -131,6 +146,11 @@ mmove_t brain_move_idle = {FRAME_stand31, FRAME_stand60, brain_frames_idle, brai
void brain_idle (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_AUTO, sound_idle3, 1, ATTN_IDLE, 0);
self->monsterinfo.currentmove = &brain_move_idle;
}
@ -158,7 +178,12 @@ mmove_t brain_move_walk1 = {FRAME_walk101, FRAME_walk111, brain_frames_walk1, NU
void brain_walk (edict_t *self)
{
self->monsterinfo.currentmove = &brain_move_walk1;
if (!self)
{
return;
}
self->monsterinfo.currentmove = &brain_move_walk1;
}
@ -234,6 +259,11 @@ mmove_t brain_move_pain1 = {FRAME_pain101, FRAME_pain121, brain_frames_pain1, br
void brain_duck_down (edict_t *self)
{
if (!self)
{
return;
}
if (self->monsterinfo.aiflags & AI_DUCKED)
return;
self->monsterinfo.aiflags |= AI_DUCKED;
@ -244,6 +274,11 @@ void brain_duck_down (edict_t *self)
void brain_duck_hold (edict_t *self)
{
if (!self)
{
return;
}
if (level.time >= self->monsterinfo.pausetime)
self->monsterinfo.aiflags &= ~AI_HOLD_FRAME;
else
@ -252,6 +287,11 @@ void brain_duck_hold (edict_t *self)
void brain_duck_up (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.aiflags &= ~AI_DUCKED;
self->maxs[2] += 32;
self->takedamage = DAMAGE_AIM;
@ -273,6 +313,11 @@ mmove_t brain_move_duck = {FRAME_duck01, FRAME_duck08, brain_frames_duck, brain_
void brain_dodge (edict_t *self, edict_t *attacker, float eta)
{
if (!self || !attacker)
{
return;
}
if (random() > 0.25)
return;
@ -324,6 +369,11 @@ mmove_t brain_move_death1 = {FRAME_death101, FRAME_death118, brain_frames_death1
void brain_swing_right (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_BODY, sound_melee1, 1, ATTN_NORM, 0);
}
@ -331,6 +381,11 @@ void brain_hit_right (edict_t *self)
{
vec3_t aim;
if (!self)
{
return;
}
VectorSet (aim, MELEE_DISTANCE, self->maxs[0], 8);
if (fire_hit (self, aim, (15 + (rand() %5)), 40))
gi.sound (self, CHAN_WEAPON, sound_melee3, 1, ATTN_NORM, 0);
@ -338,6 +393,11 @@ void brain_hit_right (edict_t *self)
void brain_swing_left (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_BODY, sound_melee2, 1, ATTN_NORM, 0);
}
@ -345,6 +405,11 @@ void brain_hit_left (edict_t *self)
{
vec3_t aim;
if (!self)
{
return;
}
VectorSet (aim, MELEE_DISTANCE, self->mins[0], 8);
if (fire_hit (self, aim, (15 + (rand() %5)), 40))
gi.sound (self, CHAN_WEAPON, sound_melee3, 1, ATTN_NORM, 0);
@ -375,6 +440,11 @@ mmove_t brain_move_attack1 = {FRAME_attak101, FRAME_attak118, brain_frames_attac
void brain_chest_open (edict_t *self)
{
if (!self)
{
return;
}
self->spawnflags &= ~65536;
self->monsterinfo.power_armor_type = POWER_ARMOR_NONE;
gi.sound (self, CHAN_BODY, sound_chest_open, 1, ATTN_NORM, 0);
@ -384,6 +454,11 @@ void brain_tentacle_attack (edict_t *self)
{
vec3_t aim;
if (!self)
{
return;
}
VectorSet (aim, MELEE_DISTANCE, 0, 8);
if (fire_hit (self, aim, (10 + (rand() %5)), -600) && skill->value > SKILL_EASY)
self->spawnflags |= 65536;
@ -392,6 +467,11 @@ void brain_tentacle_attack (edict_t *self)
void brain_chest_closed (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.power_armor_type = POWER_ARMOR_SCREEN;
if (self->spawnflags & 65536)
{
@ -424,6 +504,11 @@ mmove_t brain_move_attack2 = {FRAME_attak201, FRAME_attak217, brain_frames_attac
void brain_melee(edict_t *self)
{
if (!self)
{
return;
}
if (random() <= 0.5)
self->monsterinfo.currentmove = &brain_move_attack1;
else
@ -453,6 +538,11 @@ mmove_t brain_move_run = {FRAME_walk101, FRAME_walk111, brain_frames_run, NULL};
void brain_run (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.power_armor_type = POWER_ARMOR_SCREEN;
if (self->monsterinfo.aiflags & AI_STAND_GROUND)
self->monsterinfo.currentmove = &brain_move_stand;
@ -465,6 +555,11 @@ void brain_pain (edict_t *self, edict_t *other, float kick, int damage)
{
float r;
if (!self)
{
return;
}
if (self->health < (self->max_health / 2))
self->s.skinnum = 1;
@ -495,6 +590,11 @@ void brain_pain (edict_t *self, edict_t *other, float kick, int damage)
void brain_dead (edict_t *self)
{
if (!self)
{
return;
}
VectorSet (self->mins, -16, -16, -24);
VectorSet (self->maxs, 16, 16, -8);
self->movetype = MOVETYPE_TOSS;
@ -509,6 +609,11 @@ void brain_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage
{
int n;
if (!self)
{
return;
}
self->s.effects = 0;
self->monsterinfo.power_armor_type = POWER_ARMOR_NONE;
@ -542,6 +647,11 @@ void brain_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage
*/
void SP_monster_brain (edict_t *self)
{
if (!self)
{
return;
}
if (deathmatch->value)
{
G_FreeEdict (self);

View file

@ -36,6 +36,11 @@ static int sound_search;
void ChickMoan (edict_t *self)
{
if (!self)
{
return;
}
if (random() < 0.5)
gi.sound (self, CHAN_VOICE, sound_idle1, 1, ATTN_IDLE, 0);
else
@ -79,6 +84,11 @@ mmove_t chick_move_fidget = {FRAME_stand201, FRAME_stand230, chick_frames_fidget
void chick_fidget (edict_t *self)
{
if (!self)
{
return;
}
if (self->monsterinfo.aiflags & AI_STAND_GROUND)
return;
if (random() <= 0.3)
@ -123,6 +133,11 @@ mmove_t chick_move_stand = {FRAME_stand101, FRAME_stand130, chick_frames_stand,
void chick_stand (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &chick_move_stand;
}
@ -176,11 +191,21 @@ mmove_t chick_move_walk = {FRAME_walk11, FRAME_walk20, chick_frames_walk, NULL};
void chick_walk (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &chick_move_walk;
}
void chick_run (edict_t *self)
{
if (!self)
{
return;
}
if (self->monsterinfo.aiflags & AI_STAND_GROUND)
{
self->monsterinfo.currentmove = &chick_move_stand;
@ -248,6 +273,11 @@ void chick_pain (edict_t *self, edict_t *other, float kick, int damage)
{
float r;
if (!self)
{
return;
}
if (self->health < (self->max_health / 2))
self->s.skinnum = 1;
@ -277,6 +307,11 @@ void chick_pain (edict_t *self, edict_t *other, float kick, int damage)
void chick_dead (edict_t *self)
{
if (!self)
{
return;
}
VectorSet (self->mins, -16, -16, 0);
VectorSet (self->maxs, 16, 16, 16);
self->movetype = MOVETYPE_TOSS;
@ -335,6 +370,11 @@ void chick_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage
{
int n;
if (!self)
{
return;
}
// check for gib
if (self->health <= self->gib_health)
{
@ -371,6 +411,11 @@ void chick_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage
void chick_duck_down (edict_t *self)
{
if (!self)
{
return;
}
if (self->monsterinfo.aiflags & AI_DUCKED)
return;
self->monsterinfo.aiflags |= AI_DUCKED;
@ -382,6 +427,11 @@ void chick_duck_down (edict_t *self)
void chick_duck_hold (edict_t *self)
{
if (!self)
{
return;
}
if (level.time >= self->monsterinfo.pausetime)
self->monsterinfo.aiflags &= ~AI_HOLD_FRAME;
else
@ -390,6 +440,11 @@ void chick_duck_hold (edict_t *self)
void chick_duck_up (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.aiflags &= ~AI_DUCKED;
self->maxs[2] += 32;
self->takedamage = DAMAGE_AIM;
@ -410,6 +465,11 @@ mmove_t chick_move_duck = {FRAME_duck01, FRAME_duck07, chick_frames_duck, chick_
void chick_dodge (edict_t *self, edict_t *attacker, float eta)
{
if (!self || !attacker)
{
return;
}
if (random() > 0.25)
return;
@ -423,6 +483,11 @@ void ChickSlash (edict_t *self)
{
vec3_t aim;
if (!self)
{
return;
}
VectorSet (aim, MELEE_DISTANCE, self->mins[0], 10);
gi.sound (self, CHAN_WEAPON, sound_melee_swing, 1, ATTN_NORM, 0);
fire_hit (self, aim, (10 + (rand() %6)), 100);
@ -436,6 +501,11 @@ void ChickRocket (edict_t *self)
vec3_t dir;
vec3_t vec;
if (!self)
{
return;
}
AngleVectors (self->s.angles, forward, right, NULL);
G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_CHICK_ROCKET_1], forward, right, start);
@ -449,11 +519,21 @@ void ChickRocket (edict_t *self)
void Chick_PreAttack1 (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_missile_prelaunch, 1, ATTN_NORM, 0);
}
void ChickReload (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_missile_reload, 1, ATTN_NORM, 0);
}
@ -509,6 +589,11 @@ mmove_t chick_move_end_attack1 = {FRAME_attak128, FRAME_attak132, chick_frames_e
void chick_rerocket(edict_t *self)
{
if (!self)
{
return;
}
if (self->enemy->health > 0)
{
if (range (self, self->enemy) > RANGE_MELEE)
@ -524,6 +609,11 @@ void chick_rerocket(edict_t *self)
void chick_attack1(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &chick_move_attack1;
}
@ -553,6 +643,11 @@ mmove_t chick_move_end_slash = {FRAME_attak213, FRAME_attak216, chick_frames_end
void chick_reslash(edict_t *self)
{
if (!self)
{
return;
}
if (self->enemy->health > 0)
{
if (range (self, self->enemy) == RANGE_MELEE)
@ -574,6 +669,11 @@ void chick_reslash(edict_t *self)
void chick_slash(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &chick_move_slash;
}
@ -590,17 +690,32 @@ mmove_t chick_move_start_slash = {FRAME_attak201, FRAME_attak203, chick_frames_s
void chick_melee(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &chick_move_start_slash;
}
void chick_attack(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &chick_move_start_attack1;
}
void chick_sight(edict_t *self, edict_t *other)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
}
@ -608,6 +723,11 @@ void chick_sight(edict_t *self, edict_t *other)
*/
void SP_monster_chick (edict_t *self)
{
if (!self)
{
return;
}
if (deathmatch->value)
{
G_FreeEdict (self);

View file

@ -31,7 +31,12 @@ mmove_t flipper_move_stand = {FRAME_flphor01, FRAME_flphor01, flipper_frames_sta
void flipper_stand (edict_t *self)
{
self->monsterinfo.currentmove = &flipper_move_stand;
if (!self)
{
return;
}
self->monsterinfo.currentmove = &flipper_move_stand;
}
#define FLIPPER_RUN_SPEED 24
@ -69,6 +74,11 @@ mmove_t flipper_move_run_loop = {FRAME_flpver06, FRAME_flpver29, flipper_frames_
void flipper_run_loop (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &flipper_move_run_loop;
}
@ -85,6 +95,11 @@ mmove_t flipper_move_run_start = {FRAME_flpver01, FRAME_flpver06, flipper_frames
void flipper_run (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &flipper_move_run_start;
}
@ -120,6 +135,11 @@ mmove_t flipper_move_walk = {FRAME_flphor01, FRAME_flphor24, flipper_frames_walk
void flipper_walk (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &flipper_move_walk;
}
@ -135,6 +155,11 @@ mmove_t flipper_move_start_run = {FRAME_flphor01, FRAME_flphor05, flipper_frames
void flipper_start_run (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &flipper_move_start_run;
}
@ -162,12 +187,22 @@ void flipper_bite (edict_t *self)
{
vec3_t aim;
if (!self)
{
return;
}
VectorSet (aim, MELEE_DISTANCE, 0, 0);
fire_hit (self, aim, 5, 0);
}
void flipper_preattack (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_WEAPON, sound_chomp, 1, ATTN_NORM, 0);
}
@ -198,6 +233,11 @@ mmove_t flipper_move_attack = {FRAME_flpbit01, FRAME_flpbit20, flipper_frames_at
void flipper_melee(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &flipper_move_attack;
}
@ -205,6 +245,11 @@ void flipper_pain (edict_t *self, edict_t *other, float kick, int damage)
{
int n;
if (!self)
{
return;
}
if (self->health < (self->max_health / 2))
self->s.skinnum = 1;
@ -231,6 +276,11 @@ void flipper_pain (edict_t *self, edict_t *other, float kick, int damage)
void flipper_dead (edict_t *self)
{
if (!self)
{
return;
}
VectorSet (self->mins, -16, -16, -24);
VectorSet (self->maxs, 16, 16, -8);
self->movetype = MOVETYPE_TOSS;
@ -307,6 +357,11 @@ mmove_t flipper_move_death = {FRAME_flpdth01, FRAME_flpdth56, flipper_frames_dea
void flipper_sight (edict_t *self, edict_t *other)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
}
@ -314,6 +369,11 @@ void flipper_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int dama
{
int n;
if (!self)
{
return;
}
// check for gib
if (self->health <= self->gib_health)
{
@ -341,6 +401,11 @@ void flipper_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int dama
*/
void SP_monster_flipper (edict_t *self)
{
if (!self)
{
return;
}
if (deathmatch->value)
{
G_FreeEdict (self);

View file

@ -21,11 +21,21 @@ static int sound_sight;
void floater_sight (edict_t *self, edict_t *other)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
}
void floater_idle (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0);
}
@ -45,6 +55,11 @@ void floater_fire_blaster (edict_t *self)
vec3_t dir;
int effect;
if (!self)
{
return;
}
if ((self->s.frame == FRAME_attak104) || (self->s.frame == FRAME_attak107))
effect = EF_HYPERBLASTER;
else
@ -176,7 +191,12 @@ mmove_t floater_move_stand2 = {FRAME_stand201, FRAME_stand252, floater_frames_st
void floater_stand (edict_t *self)
{
if (random() <= 0.5)
if (!self)
{
return;
}
if (random() <= 0.5)
self->monsterinfo.currentmove = &floater_move_stand1;
else
self->monsterinfo.currentmove = &floater_move_stand2;
@ -481,6 +501,11 @@ mmove_t floater_move_run = {FRAME_stand101, FRAME_stand152, floater_frames_run,
void floater_run (edict_t *self)
{
if (!self)
{
return;
}
if (self->monsterinfo.aiflags & AI_STAND_GROUND)
self->monsterinfo.currentmove = &floater_move_stand1;
else
@ -489,12 +514,23 @@ void floater_run (edict_t *self)
void floater_walk (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &floater_move_walk;
}
void floater_wham (edict_t *self)
{
static vec3_t aim = {MELEE_DISTANCE, 0, 0};
if (!self)
{
return;
}
gi.sound (self, CHAN_WEAPON, sound_attack3, 1, ATTN_NORM, 0);
fire_hit (self, aim, 5 + rand() % 6, -50);
}
@ -506,6 +542,11 @@ void floater_zap (edict_t *self)
vec3_t dir;
vec3_t offset;
if (!self)
{
return;
}
VectorSubtract (self->enemy->s.origin, self->s.origin, dir);
AngleVectors (self->s.angles, forward, right, NULL);
@ -529,13 +570,23 @@ void floater_zap (edict_t *self)
void floater_attack(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &floater_move_attack1;
}
void floater_melee(edict_t *self)
{
if (random() < 0.5)
if (!self)
{
return;
}
if (random() < 0.5)
self->monsterinfo.currentmove = &floater_move_attack3;
else
self->monsterinfo.currentmove = &floater_move_attack2;
@ -546,6 +597,11 @@ void floater_pain (edict_t *self, edict_t *other, float kick, int damage)
{
int n;
if (!self)
{
return;
}
if (self->health < (self->max_health / 2))
self->s.skinnum = 1;
@ -571,6 +627,11 @@ void floater_pain (edict_t *self, edict_t *other, float kick, int damage)
void floater_dead (edict_t *self)
{
if (!self)
{
return;
}
VectorSet (self->mins, -16, -16, -24);
VectorSet (self->maxs, 16, 16, -8);
self->movetype = MOVETYPE_TOSS;
@ -581,6 +642,11 @@ void floater_dead (edict_t *self)
void floater_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_death1, 1, ATTN_NORM, 0);
BecomeExplosion1(self);
}
@ -589,6 +655,11 @@ void floater_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int dama
*/
void SP_monster_floater (edict_t *self)
{
if (!self)
{
return;
}
if (deathmatch->value)
{
G_FreeEdict (self);

View file

@ -32,16 +32,31 @@ void flyer_nextmove (edict_t *self);
void flyer_sight (edict_t *self, edict_t *other)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
}
void flyer_idle (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0);
}
void flyer_pop_blades (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_sproing, 1, ATTN_NORM, 0);
}
@ -199,6 +214,11 @@ mmove_t flyer_move_run = {FRAME_stand01, FRAME_stand45, flyer_frames_run, NULL};
void flyer_run (edict_t *self)
{
if (!self)
{
return;
}
if (self->monsterinfo.aiflags & AI_STAND_GROUND)
self->monsterinfo.currentmove = &flyer_move_stand;
else
@ -207,12 +227,22 @@ void flyer_run (edict_t *self)
void flyer_walk (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &flyer_move_walk;
}
void flyer_stand (edict_t *self)
{
self->monsterinfo.currentmove = &flyer_move_stand;
if (!self)
{
return;
}
self->monsterinfo.currentmove = &flyer_move_stand;
}
mframe_t flyer_frames_start [] =
@ -240,12 +270,22 @@ mmove_t flyer_move_stop = {FRAME_stop01, FRAME_stop07, flyer_frames_stop, NULL};
void flyer_stop (edict_t *self)
{
self->monsterinfo.currentmove = &flyer_move_stop;
if (!self)
{
return;
}
self->monsterinfo.currentmove = &flyer_move_stop;
}
void flyer_start (edict_t *self)
{
self->monsterinfo.currentmove = &flyer_move_start;
if (!self)
{
return;
}
self->monsterinfo.currentmove = &flyer_move_start;
}
@ -353,6 +393,11 @@ void flyer_fire (edict_t *self, int flash_number)
vec3_t dir;
int effect;
if (!self)
{
return;
}
if ((self->s.frame == FRAME_attak204) || (self->s.frame == FRAME_attak207) || (self->s.frame == FRAME_attak210))
effect = EF_HYPERBLASTER;
else
@ -369,11 +414,21 @@ void flyer_fire (edict_t *self, int flash_number)
void flyer_fireleft (edict_t *self)
{
if (!self)
{
return;
}
flyer_fire (self, MZ2_FLYER_BLASTER_1);
}
void flyer_fireright (edict_t *self)
{
if (!self)
{
return;
}
flyer_fire (self, MZ2_FLYER_BLASTER_2);
}
@ -405,6 +460,11 @@ void flyer_slash_left (edict_t *self)
{
vec3_t aim;
if (!self)
{
return;
}
VectorSet (aim, MELEE_DISTANCE, self->mins[0], 0);
fire_hit (self, aim, 5, 0);
gi.sound (self, CHAN_WEAPON, sound_slash, 1, ATTN_NORM, 0);
@ -414,6 +474,11 @@ void flyer_slash_right (edict_t *self)
{
vec3_t aim;
if (!self)
{
return;
}
VectorSet (aim, MELEE_DISTANCE, self->maxs[0], 0);
fire_hit (self, aim, 5, 0);
gi.sound (self, CHAN_WEAPON, sound_slash, 1, ATTN_NORM, 0);
@ -459,6 +524,11 @@ mmove_t flyer_move_loop_melee = {FRAME_attak107, FRAME_attak118, flyer_frames_lo
void flyer_loop_melee (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &flyer_move_loop_melee;
}
@ -466,17 +536,32 @@ void flyer_loop_melee (edict_t *self)
void flyer_attack (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &flyer_move_attack2;
}
void flyer_setstart (edict_t *self)
{
if (!self)
{
return;
}
nextmove = ACTION_run;
self->monsterinfo.currentmove = &flyer_move_start;
}
void flyer_nextmove (edict_t *self)
{
if (!self)
{
return;
}
if (nextmove == ACTION_attack1)
self->monsterinfo.currentmove = &flyer_move_start_melee;
else if (nextmove == ACTION_attack2)
@ -487,11 +572,21 @@ void flyer_nextmove (edict_t *self)
void flyer_melee (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &flyer_move_start_melee;
}
void flyer_check_melee(edict_t *self)
{
if (!self)
{
return;
}
if (range (self, self->enemy) == RANGE_MELEE)
if (random() <= 0.8)
self->monsterinfo.currentmove = &flyer_move_loop_melee;
@ -505,6 +600,11 @@ void flyer_pain (edict_t *self, edict_t *other, float kick, int damage)
{
int n;
if (!self)
{
return;
}
if (self->health < (self->max_health / 2))
self->s.skinnum = 1;
@ -536,6 +636,11 @@ void flyer_pain (edict_t *self, edict_t *other, float kick, int damage)
void flyer_die(edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_die, 1, ATTN_NORM, 0);
BecomeExplosion1(self);
}
@ -545,6 +650,11 @@ void flyer_die(edict_t *self, edict_t *inflictor, edict_t *attacker, int damage,
*/
void SP_monster_flyer (edict_t *self)
{
if (!self)
{
return;
}
if (deathmatch->value)
{
G_FreeEdict (self);

View file

@ -24,21 +24,41 @@ static int sound_sight;
void gladiator_idle (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0);
}
void gladiator_sight (edict_t *self, edict_t *other)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
}
void gladiator_search (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_search, 1, ATTN_NORM, 0);
}
void gladiator_cleaver_swing (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_WEAPON, sound_cleaver_swing, 1, ATTN_NORM, 0);
}
@ -56,6 +76,11 @@ mmove_t gladiator_move_stand = {FRAME_stand1, FRAME_stand7, gladiator_frames_sta
void gladiator_stand (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &gladiator_move_stand;
}
@ -83,6 +108,11 @@ mmove_t gladiator_move_walk = {FRAME_walk1, FRAME_walk16, gladiator_frames_walk,
void gladiator_walk (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &gladiator_move_walk;
}
@ -100,6 +130,11 @@ mmove_t gladiator_move_run = {FRAME_run1, FRAME_run6, gladiator_frames_run, NULL
void gladiator_run (edict_t *self)
{
if (!self)
{
return;
}
if (self->monsterinfo.aiflags & AI_STAND_GROUND)
self->monsterinfo.currentmove = &gladiator_move_stand;
else
@ -111,6 +146,11 @@ void GaldiatorMelee (edict_t *self)
{
vec3_t aim;
if (!self)
{
return;
}
VectorSet (aim, MELEE_DISTANCE, self->mins[0], -4);
if (fire_hit (self, aim, (20 + (rand() %5)), 300))
gi.sound (self, CHAN_AUTO, sound_cleaver_hit, 1, ATTN_NORM, 0);
@ -142,6 +182,11 @@ mmove_t gladiator_move_attack_melee = {FRAME_melee1, FRAME_melee17, gladiator_fr
void gladiator_melee(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &gladiator_move_attack_melee;
}
@ -152,6 +197,11 @@ void GladiatorGun (edict_t *self)
vec3_t dir;
vec3_t forward, right;
if (!self)
{
return;
}
AngleVectors (self->s.angles, forward, right, NULL);
G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_GLADIATOR_RAILGUN_1], forward, right, start);
@ -181,6 +231,11 @@ void gladiator_attack(edict_t *self)
float range;
vec3_t v;
if (!self)
{
return;
}
// a small safe zone
VectorSubtract (self->s.origin, self->enemy->s.origin, v);
range = VectorLength(v);
@ -220,6 +275,10 @@ mmove_t gladiator_move_pain_air = {FRAME_painup1, FRAME_painup7, gladiator_frame
void gladiator_pain (edict_t *self, edict_t *other, float kick, int damage)
{
if (!self)
{
return;
}
if (self->health < (self->max_health / 2))
self->s.skinnum = 1;
@ -251,6 +310,11 @@ void gladiator_pain (edict_t *self, edict_t *other, float kick, int damage)
void gladiator_dead (edict_t *self)
{
if (!self)
{
return;
}
VectorSet (self->mins, -16, -16, -24);
VectorSet (self->maxs, 16, 16, -8);
self->movetype = MOVETYPE_TOSS;
@ -290,6 +354,11 @@ void gladiator_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int da
{
int n;
if (!self)
{
return;
}
// check for gib
if (self->health <= self->gib_health)
{
@ -319,6 +388,11 @@ void gladiator_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int da
*/
void SP_monster_gladiator (edict_t *self)
{
if (!self)
{
return;
}
if (deathmatch->value)
{
G_FreeEdict (self);

View file

@ -21,16 +21,31 @@ static int sound_sight;
void gunner_idlesound (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0);
}
void gunner_sight (edict_t *self, edict_t *other)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
}
void gunner_search (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_search, 1, ATTN_NORM, 0);
}
@ -104,6 +119,11 @@ mmove_t gunner_move_fidget = {FRAME_stand31, FRAME_stand70, gunner_frames_fidget
void gunner_fidget (edict_t *self)
{
if (!self)
{
return;
}
if (self->monsterinfo.aiflags & AI_STAND_GROUND)
return;
if (random() <= 0.05)
@ -149,7 +169,12 @@ mmove_t gunner_move_stand = {FRAME_stand01, FRAME_stand30, gunner_frames_stand,
void gunner_stand (edict_t *self)
{
self->monsterinfo.currentmove = &gunner_move_stand;
if (!self)
{
return;
}
self->monsterinfo.currentmove = &gunner_move_stand;
}
@ -173,6 +198,11 @@ mmove_t gunner_move_walk = {FRAME_walk07, FRAME_walk19, gunner_frames_walk, NULL
void gunner_walk (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &gunner_move_walk;
}
@ -192,6 +222,11 @@ mmove_t gunner_move_run = {FRAME_run01, FRAME_run08, gunner_frames_run, NULL};
void gunner_run (edict_t *self)
{
if (!self)
{
return;
}
if (self->monsterinfo.aiflags & AI_STAND_GROUND)
self->monsterinfo.currentmove = &gunner_move_stand;
else
@ -212,6 +247,11 @@ mmove_t gunner_move_runandshoot = {FRAME_runs01, FRAME_runs06, gunner_frames_run
void gunner_runandshoot (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &gunner_move_runandshoot;
}
@ -263,6 +303,11 @@ mmove_t gunner_move_pain1 = {FRAME_pain101, FRAME_pain118, gunner_frames_pain1,
void gunner_pain (edict_t *self, edict_t *other, float kick, int damage)
{
if (!self)
{
return;
}
if (self->health < (self->max_health / 2))
self->s.skinnum = 1;
@ -289,6 +334,11 @@ void gunner_pain (edict_t *self, edict_t *other, float kick, int damage)
void gunner_dead (edict_t *self)
{
if (!self)
{
return;
}
VectorSet (self->mins, -16, -16, -24);
VectorSet (self->maxs, 16, 16, -8);
self->movetype = MOVETYPE_TOSS;
@ -317,6 +367,11 @@ void gunner_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damag
{
int n;
if (!self)
{
return;
}
// check for gib
if (self->health <= self->gib_health)
{
@ -343,6 +398,11 @@ void gunner_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damag
void gunner_duck_down (edict_t *self)
{
if (!self)
{
return;
}
if (self->monsterinfo.aiflags & AI_DUCKED)
return;
self->monsterinfo.aiflags |= AI_DUCKED;
@ -360,6 +420,11 @@ void gunner_duck_down (edict_t *self)
void gunner_duck_hold (edict_t *self)
{
if (!self)
{
return;
}
if (level.time >= self->monsterinfo.pausetime)
self->monsterinfo.aiflags &= ~AI_HOLD_FRAME;
else
@ -368,6 +433,11 @@ void gunner_duck_hold (edict_t *self)
void gunner_duck_up (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.aiflags &= ~AI_DUCKED;
self->maxs[2] += 32;
self->takedamage = DAMAGE_AIM;
@ -389,6 +459,11 @@ mmove_t gunner_move_duck = {FRAME_duck01, FRAME_duck08, gunner_frames_duck, gunn
void gunner_dodge (edict_t *self, edict_t *attacker, float eta)
{
if (!self || !attacker)
{
return;
}
if (random() > 0.25)
return;
@ -401,6 +476,11 @@ void gunner_dodge (edict_t *self, edict_t *attacker, float eta)
void gunner_opengun (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_open, 1, ATTN_IDLE, 0);
}
@ -412,6 +492,11 @@ void GunnerFire (edict_t *self)
vec3_t aim;
int flash_number;
if (!self)
{
return;
}
flash_number = MZ2_GUNNER_MACHINEGUN_1 + (self->s.frame - FRAME_attak216);
AngleVectors (self->s.angles, forward, right, NULL);
@ -434,6 +519,11 @@ void GunnerGrenade (edict_t *self)
vec3_t aim;
int flash_number;
if (!self)
{
return;
}
if (self->s.frame == FRAME_attak105)
flash_number = MZ2_GUNNER_GRENADE_1;
else if (self->s.frame == FRAME_attak108)
@ -517,6 +607,11 @@ mmove_t gunner_move_attack_grenade = {FRAME_attak101, FRAME_attak121, gunner_fra
void gunner_attack(edict_t *self)
{
if (!self)
{
return;
}
if (range (self, self->enemy) == RANGE_MELEE)
{
self->monsterinfo.currentmove = &gunner_move_attack_chain;
@ -532,11 +627,21 @@ void gunner_attack(edict_t *self)
void gunner_fire_chain(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &gunner_move_fire_chain;
}
void gunner_refire_chain(edict_t *self)
{
if (!self)
{
return;
}
if (self->enemy->health > 0)
if ( visible (self, self->enemy) )
if (random() <= 0.5)
@ -551,6 +656,11 @@ void gunner_refire_chain(edict_t *self)
*/
void SP_monster_gunner (edict_t *self)
{
if (!self)
{
return;
}
if (deathmatch->value)
{
G_FreeEdict (self);

View file

@ -24,6 +24,11 @@ static int sound_attack;
void handler_sight (edict_t *self, edict_t *other)
{
if (!self || !other)
{
return;
}
hound_sight(self, other);
infantry_sight(self, other);
}
@ -200,15 +205,20 @@ mmove_t handler_stand5 = {FRAME_stand5start, FRAME_stand5end, handler_frames_sta
*/
void handler_standWhatNext (edict_t *self)
{
if (!self)
{
return;
}
float r = random();
if(r < 0.90)
{
self->monsterinfo.currentmove = &handler_stand3;
self->monsterinfo.currentmove = &handler_stand3;
}
else
{
self->monsterinfo.currentmove = &handler_stand5;
self->monsterinfo.currentmove = &handler_stand5;
}
}
@ -217,30 +227,40 @@ void handler_standSitWhatNext (edict_t *self)
{
float r = random();
if (!self)
{
return;
}
if(r < 0.70)
{
self->monsterinfo.currentmove = &handler_stand1;
self->monsterinfo.currentmove = &handler_stand1;
}
else if(r < 0.85)
{
self->monsterinfo.currentmove = &handler_stand2;
self->monsterinfo.currentmove = &handler_stand2;
}
else
{
self->monsterinfo.currentmove = &handler_stand4;
self->monsterinfo.currentmove = &handler_stand4;
}
}
void handler_stand (edict_t *self)
{
if(self->monsterinfo.currentmove != &handler_stand1 &&
self->monsterinfo.currentmove != &handler_stand2 &&
self->monsterinfo.currentmove != &handler_stand3 &&
self->monsterinfo.currentmove != &handler_stand4 &&
self->monsterinfo.currentmove != &handler_stand5)
if (!self)
{
self->monsterinfo.currentmove = &handler_stand3;
return;
}
if(self->monsterinfo.currentmove != &handler_stand1 &&
self->monsterinfo.currentmove != &handler_stand2 &&
self->monsterinfo.currentmove != &handler_stand3 &&
self->monsterinfo.currentmove != &handler_stand4 &&
self->monsterinfo.currentmove != &handler_stand5)
{
self->monsterinfo.currentmove = &handler_stand3;
}
}
@ -260,6 +280,11 @@ void handler_pain (edict_t *self, edict_t *other, float kick, int damage)
void handler_createHound(edict_t *self)
{
if (!self)
{
return;
}
self->s.modelindex2 = 0;
hound_createHound(self, (self->health / 175.0));
}
@ -267,6 +292,11 @@ void handler_createHound(edict_t *self)
void CheckIdleLoop(edict_t *self)
{
if (!self)
{
return;
}
if(!self->powerarmor_time && self->spawnflags & 8)
{
self->powerarmor_time = level.time + (FRAMETIME * random() * 3);
@ -280,6 +310,11 @@ void CheckIdleLoop(edict_t *self)
void CheckForEnemy(edict_t *self)
{
if (!self)
{
return;
}
if(self->enemy && (self->enemy->client || (self->enemy->svflags & SVF_MONSTER)))
{
self->powerarmor_time = 0;
@ -298,6 +333,11 @@ void CheckForEnemy(edict_t *self)
void StartCount(edict_t *self)
{
if (!self)
{
return;
}
self->powerarmor_time = level.time + 3;
}
@ -329,6 +369,11 @@ mmove_t handler_move_attack1 = {FRAME_attack1Start, FRAME_attack1End, handler_fr
void handler_attack (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_attack, 1, ATTN_NORM, 0);
self->monsterinfo.currentmove = &handler_move_attack1;
@ -344,6 +389,11 @@ Death Stuff Starts
void handler_dead (edict_t *self)
{
if (!self)
{
return;
}
VectorSet (self->mins, -16, -16, -24);
VectorSet (self->maxs, 16, 16, -8);
self->movetype = MOVETYPE_TOSS;
@ -355,6 +405,11 @@ void handler_dead (edict_t *self)
void handler_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
{
if (!self)
{
return;
}
self->health = 1; // can't die while together...
}
@ -380,28 +435,33 @@ void SP_monster_handler_precache(void)
*/
void SP_monster_handler (edict_t *self)
{
if (!self)
{
return;
}
if (deathmatch->value)
{
G_FreeEdict (self);
return;
}
SP_monster_handler_precache();
SP_monster_handler_precache();
self->s.modelindex = gi.modelindex ("models/monsters/guard/handler/tris.md2");
self->s.modelindex2 = gi.modelindex ("models/monsters/guard/hound/tris.md2");
/*
Handler
X = -36 to 3
Y = -3 to 27
Z = -24 to 28
/*
Handler
X = -36 to 3
Y = -3 to 27
Z = -24 to 28
Hound
X = -12 to 11
Y = -30 to 30
Z = -24 to 8
*/
Hound
X = -12 to 11
Y = -30 to 30
Z = -24 to 8
*/
VectorSet (self->mins, -32, -32, -24);
VectorSet (self->maxs, 32, 32, 32);

View file

@ -28,11 +28,21 @@ void hound_walk (edict_t *self);
void hound_launch (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_WEAPON, sound_launch, 1, ATTN_NORM, 0);
}
void hound_sight (edict_t *self, edict_t *other)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_WEAPON, sound_sight, 1, ATTN_NORM, 0);
}
@ -100,14 +110,19 @@ mmove_t hound_stand2 = {FRAME_stand2start, FRAME_stand2end, hound_frames_stand2,
void hound_stand (edict_t *self)
{
if (!self)
{
return;
}
if (random() < 0.8)
{
self->monsterinfo.currentmove = &hound_stand1;
}
else
{
self->monsterinfo.currentmove = &hound_stand2;
}
{
self->monsterinfo.currentmove = &hound_stand1;
}
else
{
self->monsterinfo.currentmove = &hound_stand2;
}
}
//
@ -130,8 +145,13 @@ mmove_t hound_move_run = {FRAME_runStart, FRAME_runEnd, hound_frames_run, NULL};
void hound_run (edict_t *self)
{
if (!self)
{
return;
}
if (self->monsterinfo.aiflags & AI_STAND_GROUND)
hound_stand(self);
hound_stand(self);
else
self->monsterinfo.currentmove = &hound_move_run;
}
@ -157,6 +177,11 @@ mmove_t hound_move_walk = {FRAME_walkStart, FRAME_walkEnd, hound_frames_walk, ho
void hound_walk (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &hound_move_walk;
}
@ -191,6 +216,11 @@ mmove_t hound_move_pain2 = {FRAME_pain2Start, FRAME_pain2End, hound_frames_pain2
void hound_pain (edict_t *self, edict_t *other, float kick, int damage)
{
if (!self)
{
return;
}
if (self->health < (self->max_health / 2))
self->s.skinnum = 1;
@ -222,6 +252,11 @@ void hound_bite (edict_t *self)
{
vec3_t aim;
if (!self)
{
return;
}
VectorSet (aim, MELEE_DISTANCE, self->mins[0], 8);
if (fire_hit (self, aim, (30 + (rand() %5)), 100))
gi.sound (self, CHAN_WEAPON, sound_bite, 1, ATTN_NORM, 0);
@ -233,6 +268,11 @@ void hound_bite2 (edict_t *self)
{
vec3_t aim;
if (!self)
{
return;
}
VectorSet (aim, MELEE_DISTANCE, self->mins[0], 8);
fire_hit (self, aim, (30 + (rand() %5)), 100);
}
@ -270,14 +310,19 @@ mmove_t hound_move_attack2 = {FRAME_attack2Start, FRAME_attack2End, hound_frames
void hound_attack (edict_t *self)
{
if (!self)
{
return;
}
if (random() < 0.6)
{
self->monsterinfo.currentmove = &hound_move_attack1;
}
else
{
self->monsterinfo.currentmove = &hound_move_attack2;
}
{
self->monsterinfo.currentmove = &hound_move_attack1;
}
else
{
self->monsterinfo.currentmove = &hound_move_attack2;
}
}
//
@ -285,6 +330,11 @@ void hound_attack (edict_t *self)
//
void hound_jump_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
{
if (!self || !other)
{
return;
}
if (self->health <= 0)
{
self->touch = NULL;
@ -324,6 +374,11 @@ void hound_jump_takeoff (edict_t *self)
{
vec3_t forward;
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_jump, 1, ATTN_NORM, 0);
AngleVectors (self->s.angles, forward, NULL, NULL);
self->s.origin[2] += 1;
@ -337,6 +392,11 @@ void hound_jump_takeoff (edict_t *self)
void hound_check_landing (edict_t *self)
{
if (!self)
{
return;
}
if (self->groundentity)
{
gi.sound (self, CHAN_WEAPON, sound_impact, 1, ATTN_NORM, 0);
@ -353,9 +413,14 @@ void hound_check_landing (edict_t *self)
void hound_check_landing2 (edict_t *self)
{
if (!self)
{
return;
}
self->owner = NULL;
if (self->groundentity)
if (self->groundentity)
{
gi.sound (self, CHAN_WEAPON, sound_impact, 1, ATTN_NORM, 0);
self->monsterinfo.attack_finished = 0;
@ -400,6 +465,11 @@ mmove_t hound_move_jump = {FRAME_leapStart, FRAME_leapEnd, hound_frames_jump, ho
void hound_jump (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &hound_move_jump;
}
@ -411,6 +481,10 @@ attack check routines
qboolean hound_check_melee (edict_t *self)
{
if(!self) {
return false;
}
if (range (self, self->enemy) == RANGE_MELEE)
return true;
return false;
@ -422,6 +496,10 @@ qboolean hound_check_jump (edict_t *self)
vec3_t v;
float distance;
if(!self) {
return false;
}
if (self->absmin[2] > (self->enemy->absmin[2] + 0.75 * self->enemy->size[2]))
return false;
@ -447,6 +525,10 @@ qboolean hound_check_jump (edict_t *self)
qboolean hound_checkattack (edict_t *self)
{
if(!self) {
return false;
}
if (!self->enemy || self->enemy->health <= 0)
return false;
@ -474,6 +556,11 @@ Death Stuff Starts
void hound_dead (edict_t *self)
{
if (!self)
{
return;
}
VectorSet (self->mins, -16, -16, -24);
VectorSet (self->maxs, 16, 16, -8);
self->movetype = MOVETYPE_TOSS;
@ -503,6 +590,11 @@ void hound_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage
{
int n;
if (!self)
{
return;
}
// check for gib
if (self->health <= self->gib_health)
{
@ -551,13 +643,18 @@ void SP_monster_hound_precache(void)
*/
void SP_monster_hound (edict_t *self)
{
if (!self)
{
return;
}
if (deathmatch->value)
{
G_FreeEdict (self);
return;
}
SP_monster_hound_precache();
SP_monster_hound_precache();
self->s.modelindex = gi.modelindex ("models/monsters/guard/hound/tris.md2");
VectorSet (self->mins, -16, -16, -24);
@ -575,16 +672,16 @@ void SP_monster_hound (edict_t *self)
if (self->spawnflags & 0x8)
{
self->monsterinfo.aiflags = AI_SCHOOLING;
}
self->monsterinfo.aiflags = AI_SCHOOLING;
}
self->monsterinfo.zSchoolSightRadius = 500;
self->monsterinfo.zSchoolMaxSpeed = 4;
self->monsterinfo.zSchoolMinSpeed = 3;
self->monsterinfo.zSpeedStandMax = 1;
self->monsterinfo.zSpeedWalkMax = 3;
self->monsterinfo.zSchoolDecayRate = 0.95;
self->monsterinfo.zSchoolMinimumDistance = 100;
self->monsterinfo.zSchoolSightRadius = 500;
self->monsterinfo.zSchoolMaxSpeed = 4;
self->monsterinfo.zSchoolMinSpeed = 3;
self->monsterinfo.zSpeedStandMax = 1;
self->monsterinfo.zSpeedWalkMax = 3;
self->monsterinfo.zSchoolDecayRate = 0.95;
self->monsterinfo.zSchoolMinimumDistance = 100;
self->monsterinfo.stand = hound_stand;
self->monsterinfo.walk = hound_walk;
@ -609,9 +706,14 @@ qboolean monster_start (edict_t *self);
void hound_createHound(edict_t *self, float healthPercent)
{
edict_t *hound;
if (!self)
{
return;
}
hound = G_Spawn();
hound->s.modelindex = gi.modelindex ("models/monsters/guard/hound/tris.md2");
VectorSet (hound->mins, -16, -16, -24);
VectorSet (hound->maxs, 16, 16, 24);

View file

@ -23,11 +23,21 @@ static int sound_search2;
void hover_sight (edict_t *self, edict_t *other)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
}
void hover_search (edict_t *self)
{
if (!self)
{
return;
}
if (random() < 0.5)
gi.sound (self, CHAN_VOICE, sound_search1, 1, ATTN_NORM, 0);
else
@ -401,6 +411,11 @@ mmove_t hover_move_end_attack = {FRAME_attak107, FRAME_attak108, hover_frames_en
void hover_reattack (edict_t *self)
{
if (!self)
{
return;
}
if (self->enemy->health > 0 )
if (visible (self, self->enemy) )
if (random() <= 0.6)
@ -420,6 +435,11 @@ void hover_fire_blaster (edict_t *self)
vec3_t dir;
int effect;
if (!self)
{
return;
}
if (self->s.frame == FRAME_attak104)
effect = EF_HYPERBLASTER;
else
@ -438,11 +458,21 @@ void hover_fire_blaster (edict_t *self)
void hover_stand (edict_t *self)
{
self->monsterinfo.currentmove = &hover_move_stand;
if (!self)
{
return;
}
self->monsterinfo.currentmove = &hover_move_stand;
}
void hover_run (edict_t *self)
{
if (!self)
{
return;
}
if (self->monsterinfo.aiflags & AI_STAND_GROUND)
self->monsterinfo.currentmove = &hover_move_stand;
else
@ -451,22 +481,42 @@ void hover_run (edict_t *self)
void hover_walk (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &hover_move_walk;
}
void hover_start_attack (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &hover_move_start_attack;
}
void hover_attack(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &hover_move_attack1;
}
void hover_pain (edict_t *self, edict_t *other, float kick, int damage)
{
if (!self)
{
return;
}
if (self->health < (self->max_health / 2))
self->s.skinnum = 1;
@ -500,6 +550,11 @@ void hover_pain (edict_t *self, edict_t *other, float kick, int damage)
void hover_deadthink (edict_t *self)
{
if (!self)
{
return;
}
if (!self->groundentity && level.time < self->timestamp)
{
self->nextthink = level.time + FRAMETIME;
@ -510,6 +565,11 @@ void hover_deadthink (edict_t *self)
void hover_dead (edict_t *self)
{
if (!self)
{
return;
}
VectorSet (self->mins, -16, -16, -24);
VectorSet (self->maxs, 16, 16, -8);
self->movetype = MOVETYPE_TOSS;
@ -523,6 +583,11 @@ void hover_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage
{
int n;
if (!self)
{
return;
}
// check for gib
if (self->health <= self->gib_health)
{
@ -558,6 +623,12 @@ void hover_dodge (edict_t *self, edict_t *attacker, float eta)
vec3_t forward, right;
vec3_t dir;
int count = 0;
if (!self)
{
return;
}
if (self->monsterinfo.currentmove == &hover_move_attack1)
if (random() < 0.75) // if we're attacking, stop attacking and dodge 1/4 the time
return;
@ -611,6 +682,11 @@ void SP_monster_hover_precache(void)
*/
void SP_monster_hover (edict_t *self)
{
if (!self)
{
return;
}
if (deathmatch->value)
{
G_FreeEdict (self);

View file

@ -55,6 +55,11 @@ mmove_t infantry_move_stand = {FRAME_stand50, FRAME_stand71, infantry_frames_sta
void infantry_stand (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &infantry_move_stand;
}
@ -115,6 +120,11 @@ mmove_t infantry_move_fidget = {FRAME_stand01, FRAME_stand49, infantry_frames_fi
void infantry_fidget (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &infantry_move_fidget;
gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0);
}
@ -138,6 +148,11 @@ mmove_t infantry_move_walk = {FRAME_walk03, FRAME_walk14, infantry_frames_walk,
void infantry_walk (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &infantry_move_walk;
}
@ -156,6 +171,11 @@ mmove_t infantry_move_run = {FRAME_run01, FRAME_run08, infantry_frames_run, NULL
void infantry_run (edict_t *self)
{
if (!self)
{
return;
}
if (self->monsterinfo.aiflags & AI_STAND_GROUND)
self->monsterinfo.currentmove = &infantry_move_stand;
else
@ -197,6 +217,11 @@ void infantry_pain (edict_t *self, edict_t *other, float kick, int damage)
{
int n;
if (!self)
{
return;
}
if (self->health < (self->max_health / 2))
self->s.skinnum = 1;
@ -245,6 +270,11 @@ void InfantryMachineGun (edict_t *self)
vec3_t vec;
int flash_number;
if (!self)
{
return;
}
if (self->s.frame == FRAME_attak111)
{
flash_number = MZ2_INFANTRY_MACHINEGUN_1;
@ -285,11 +315,21 @@ void InfantryMachineGun (edict_t *self)
void infantry_sight (edict_t *self, edict_t *other)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_BODY, sound_sight, 1, ATTN_NORM, 0);
}
void infantry_dead (edict_t *self)
{
if (!self)
{
return;
}
VectorSet (self->mins, -16, -16, -24);
VectorSet (self->maxs, 16, 16, -8);
self->movetype = MOVETYPE_TOSS;
@ -374,6 +414,11 @@ void infantry_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int dam
{
int n;
if (!self)
{
return;
}
// check for gib
if (self->health <= self->gib_health)
{
@ -416,6 +461,11 @@ void infantry_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int dam
void infantry_duck_down (edict_t *self)
{
if (!self)
{
return;
}
if (self->monsterinfo.aiflags & AI_DUCKED)
return;
self->monsterinfo.aiflags |= AI_DUCKED;
@ -427,6 +477,11 @@ void infantry_duck_down (edict_t *self)
void infantry_duck_hold (edict_t *self)
{
if (!self)
{
return;
}
if (level.time >= self->monsterinfo.pausetime)
self->monsterinfo.aiflags &= ~AI_HOLD_FRAME;
else
@ -435,6 +490,11 @@ void infantry_duck_hold (edict_t *self)
void infantry_duck_up (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.aiflags &= ~AI_DUCKED;
self->maxs[2] += 32;
self->takedamage = DAMAGE_AIM;
@ -453,6 +513,11 @@ mmove_t infantry_move_duck = {FRAME_duck01, FRAME_duck05, infantry_frames_duck,
void infantry_dodge (edict_t *self, edict_t *attacker, float eta)
{
if (!self || !attacker)
{
return;
}
if (random() > 0.25)
return;
@ -467,6 +532,11 @@ void infantry_cock_gun (edict_t *self)
{
int n;
if (!self)
{
return;
}
gi.sound (self, CHAN_WEAPON, sound_weapon_cock, 1, ATTN_NORM, 0);
n = (rand() & 15) + 3 + 7;
self->monsterinfo.pausetime = level.time + n * FRAMETIME;
@ -474,6 +544,11 @@ void infantry_cock_gun (edict_t *self)
void infantry_fire (edict_t *self)
{
if (!self)
{
return;
}
InfantryMachineGun (self);
if (level.time >= self->monsterinfo.pausetime)
@ -505,6 +580,11 @@ mmove_t infantry_move_attack1 = {FRAME_attak101, FRAME_attak115, infantry_frames
void infantry_swing (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_WEAPON, sound_punch_swing, 1, ATTN_NORM, 0);
}
@ -512,6 +592,11 @@ void infantry_smack (edict_t *self)
{
vec3_t aim;
if (!self)
{
return;
}
VectorSet (aim, MELEE_DISTANCE, 0, 0);
if (fire_hit (self, aim, (5 + (rand() % 5)), 50))
gi.sound (self, CHAN_WEAPON, sound_punch_hit, 1, ATTN_NORM, 0);
@ -532,6 +617,11 @@ mmove_t infantry_move_attack2 = {FRAME_attak201, FRAME_attak208, infantry_frames
void infantry_attack(edict_t *self)
{
if (!self)
{
return;
}
if (range (self, self->enemy) == RANGE_MELEE)
self->monsterinfo.currentmove = &infantry_move_attack2;
else
@ -543,6 +633,11 @@ void infantry_attack(edict_t *self)
*/
void SP_monster_infantry (edict_t *self)
{
if (!self)
{
return;
}
if (deathmatch->value)
{
G_FreeEdict (self);
@ -597,6 +692,11 @@ void SP_monster_infantry (edict_t *self)
void handler_ConvertToInfantry(edict_t *self)
{
if (!self)
{
return;
}
self->s.modelindex = gi.modelindex("models/monsters/infantry/tris.md2");
VectorSet (self->mins, -16, -16, -24);
VectorSet (self->maxs, 16, 16, 32);

View file

@ -17,21 +17,41 @@ static int sound_scream[8];
void insane_fist (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_fist, 1, ATTN_IDLE, 0);
}
void insane_shake (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_shake, 1, ATTN_IDLE, 0);
}
void insane_moan (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_moan, 1, ATTN_IDLE, 0);
}
void insane_scream (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_scream[rand()%8], 1, ATTN_IDLE, 0);
}
@ -414,7 +434,12 @@ mmove_t insane_move_struggle_cross = {FRAME_cross16, FRAME_cross30, insane_frame
void insane_cross (edict_t *self)
{
if (random() < 0.8)
if (!self)
{
return;
}
if (random() < 0.8)
self->monsterinfo.currentmove = &insane_move_cross;
else
self->monsterinfo.currentmove = &insane_move_struggle_cross;
@ -422,6 +447,11 @@ void insane_cross (edict_t *self)
void insane_walk (edict_t *self)
{
if (!self)
{
return;
}
if ( self->spawnflags & 16 ) // Hold Ground?
if (self->s.frame == FRAME_cr_pain10)
{
@ -439,6 +469,11 @@ void insane_walk (edict_t *self)
void insane_run (edict_t *self)
{
if (!self)
{
return;
}
if ( self->spawnflags & 16 ) // Hold Ground?
if (self->s.frame == FRAME_cr_pain10)
{
@ -459,6 +494,11 @@ void insane_pain (edict_t *self, edict_t *other, float kick, int damage)
{
int l,r;
if (!self)
{
return;
}
if (level.time < self->pain_debounce_time)
return;
@ -496,11 +536,21 @@ void insane_pain (edict_t *self, edict_t *other, float kick, int damage)
void insane_onground (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &insane_move_down;
}
void insane_checkdown (edict_t *self)
{
if (!self)
{
return;
}
if (self->spawnflags & 32) // Always stand
return;
if (random() < 0.3)
@ -514,6 +564,11 @@ void insane_checkdown (edict_t *self)
void insane_checkup (edict_t *self)
{
if (!self)
{
return;
}
// If Hold_Ground and Crawl are set
if ( (self->spawnflags & 4) && (self->spawnflags & 16) )
return;
@ -524,6 +579,11 @@ void insane_checkup (edict_t *self)
void insane_stand (edict_t *self)
{
if (!self)
{
return;
}
if (self->spawnflags & 8) // If crucified
{
self->monsterinfo.currentmove = &insane_move_cross;
@ -541,6 +601,11 @@ void insane_stand (edict_t *self)
void insane_dead (edict_t *self)
{
if (!self)
{
return;
}
if (self->spawnflags & 8)
{
self->flags |= FL_FLY;
@ -561,6 +626,11 @@ void insane_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damag
{
int n;
if (!self)
{
return;
}
if (self->health <= self->gib_health)
{
gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/udeath.wav"), 1, ATTN_IDLE, 0);
@ -599,6 +669,11 @@ void insane_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damag
*/
void SP_misc_insane (edict_t *self)
{
if (!self)
{
return;
}
if (deathmatch->value)
{
G_FreeEdict (self);

View file

@ -29,6 +29,11 @@ edict_t *medic_FindDeadMonster (edict_t *self)
edict_t *ent = NULL;
edict_t *best = NULL;
if (!self)
{
return NULL;
}
while ((ent = findradius(ent, self->s.origin, 1024)) != NULL)
{
if (ent == self)
@ -62,6 +67,11 @@ void medic_idle (edict_t *self)
{
edict_t *ent;
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_idle1, 1, ATTN_IDLE, 0);
ent = medic_FindDeadMonster(self);
@ -78,6 +88,11 @@ void medic_search (edict_t *self)
{
edict_t *ent;
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_search, 1, ATTN_IDLE, 0);
if (!self->oldenemy)
@ -96,6 +111,11 @@ void medic_search (edict_t *self)
void medic_sight (edict_t *self, edict_t *other)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
}
@ -198,6 +218,11 @@ mmove_t medic_move_stand = {FRAME_wait1, FRAME_wait90, medic_frames_stand, NULL}
void medic_stand (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &medic_move_stand;
}
@ -221,6 +246,11 @@ mmove_t medic_move_walk = {FRAME_walk1, FRAME_walk12, medic_frames_walk, NULL};
void medic_walk (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &medic_move_walk;
}
@ -239,6 +269,11 @@ mmove_t medic_move_run = {FRAME_run1, FRAME_run6, medic_frames_run, NULL};
void medic_run (edict_t *self)
{
if (!self)
{
return;
}
if (!(self->monsterinfo.aiflags & AI_MEDIC))
{
edict_t *ent;
@ -297,6 +332,11 @@ mmove_t medic_move_pain2 = {FRAME_painb1, FRAME_painb15, medic_frames_pain2, med
void medic_pain (edict_t *self, edict_t *other, float kick, int damage)
{
if (!self)
{
return;
}
if (self->health < (self->max_health / 2))
self->s.skinnum = 1;
@ -328,6 +368,11 @@ void medic_fire_blaster (edict_t *self)
vec3_t dir;
int effect;
if (!self)
{
return;
}
if ((self->s.frame == FRAME_attack9) || (self->s.frame == FRAME_attack12))
effect = EF_BLASTER;
else if ((self->s.frame == FRAME_attack19) || (self->s.frame == FRAME_attack22) || (self->s.frame == FRAME_attack25) || (self->s.frame == FRAME_attack28))
@ -348,6 +393,11 @@ void medic_fire_blaster (edict_t *self)
void medic_dead (edict_t *self)
{
if (!self)
{
return;
}
VectorSet (self->mins, -16, -16, -24);
VectorSet (self->maxs, 16, 16, -8);
self->movetype = MOVETYPE_TOSS;
@ -395,6 +445,11 @@ void medic_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage
{
int n;
if (!self)
{
return;
}
// if we had a pending patient, free him up for another medic
if ((self->enemy) && (self->enemy->owner == self))
self->enemy->owner = NULL;
@ -426,6 +481,11 @@ void medic_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage
void medic_duck_down (edict_t *self)
{
if (!self)
{
return;
}
if (self->monsterinfo.aiflags & AI_DUCKED)
return;
self->monsterinfo.aiflags |= AI_DUCKED;
@ -437,6 +497,11 @@ void medic_duck_down (edict_t *self)
void medic_duck_hold (edict_t *self)
{
if (!self)
{
return;
}
if (level.time >= self->monsterinfo.pausetime)
self->monsterinfo.aiflags &= ~AI_HOLD_FRAME;
else
@ -445,6 +510,11 @@ void medic_duck_hold (edict_t *self)
void medic_duck_up (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.aiflags &= ~AI_DUCKED;
self->maxs[2] += 32;
self->takedamage = DAMAGE_AIM;
@ -474,6 +544,11 @@ mmove_t medic_move_duck = {FRAME_duck1, FRAME_duck16, medic_frames_duck, medic_r
void medic_dodge (edict_t *self, edict_t *attacker, float eta)
{
if (!self || !attacker)
{
return;
}
if (random() > 0.25)
return;
@ -507,6 +582,11 @@ mmove_t medic_move_attackHyperBlaster = {FRAME_attack15, FRAME_attack30, medic_f
void medic_continue (edict_t *self)
{
if (!self)
{
return;
}
if (visible (self, self->enemy) )
if (random() <= 0.95)
self->monsterinfo.currentmove = &medic_move_attackHyperBlaster;
@ -535,6 +615,11 @@ mmove_t medic_move_attackBlaster = {FRAME_attack1, FRAME_attack14, medic_frames_
void medic_hook_launch (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_WEAPON, sound_hook_launch, 1, ATTN_NORM, 0);
}
@ -561,6 +646,11 @@ void medic_cable_attack (edict_t *self)
vec3_t dir, angles;
float distance;
if (!self)
{
return;
}
if (!self->enemy->inuse)
return;
@ -636,6 +726,11 @@ void medic_cable_attack (edict_t *self)
void medic_hook_retract (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_WEAPON, sound_hook_retract, 1, ATTN_NORM, 0);
self->enemy->monsterinfo.aiflags &= ~AI_RESURRECTING;
}
@ -676,6 +771,11 @@ mmove_t medic_move_attackCable = {FRAME_attack33, FRAME_attack60, medic_frames_a
void medic_attack(edict_t *self)
{
if (!self)
{
return;
}
if (self->monsterinfo.aiflags & AI_MEDIC)
self->monsterinfo.currentmove = &medic_move_attackCable;
else
@ -684,6 +784,11 @@ void medic_attack(edict_t *self)
qboolean medic_checkattack (edict_t *self)
{
if (!self)
{
return false;
}
if (self->monsterinfo.aiflags & AI_MEDIC)
{
medic_attack(self);
@ -698,6 +803,11 @@ qboolean medic_checkattack (edict_t *self)
*/
void SP_monster_medic (edict_t *self)
{
if (!self)
{
return;
}
if (deathmatch->value)
{
G_FreeEdict (self);

View file

@ -21,7 +21,12 @@ qboolean M_CheckBottom (edict_t *ent)
trace_t trace;
int x, y;
float mid, bottom;
if (!ent)
{
return false;
}
VectorAdd (ent->s.origin, ent->mins, mins);
VectorAdd (ent->s.origin, ent->maxs, maxs);
@ -100,6 +105,11 @@ qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink)
vec3_t test;
int contents;
if (!ent)
{
return false;
}
// try the move
VectorCopy (ent->s.origin, oldorg);
VectorAdd (ent->s.origin, move, neworg);
@ -310,7 +320,12 @@ void M_ChangeYaw (edict_t *ent)
float current;
float move;
float speed;
if (!ent)
{
return;
}
current = anglemod(ent->s.angles[YAW]);
ideal = ent->ideal_yaw;
@ -357,10 +372,15 @@ qboolean SV_StepDirection (edict_t *ent, float yaw, float dist)
{
vec3_t move, oldorigin;
float delta;
if (!ent)
{
return false;
}
ent->ideal_yaw = yaw;
M_ChangeYaw (ent);
yaw = yaw*M_PI*2 / 360;
move[0] = cos(yaw)*dist;
move[1] = sin(yaw)*dist;
@ -391,6 +411,11 @@ SV_FixCheckBottom
*/
void SV_FixCheckBottom (edict_t *ent)
{
if (!ent)
{
return;
}
ent->flags |= FL_PARTIALGROUND;
}
@ -409,6 +434,11 @@ void SV_NewChaseDir (edict_t *actor, edict_t *enemy, float dist)
float d[3];
float tdir, olddir, turnaround;
if (!actor || !enemy)
{
return;
}
//FIXME: how did we get here with no enemy
if (!enemy)
return;
@ -498,7 +528,12 @@ SV_CloseEnough
qboolean SV_CloseEnough (edict_t *ent, edict_t *goal, float dist)
{
int i;
if (!ent || !goal)
{
return false;
}
for (i=0 ; i<3 ; i++)
{
if (goal->absmin[i] > ent->absmax[i] + dist)
@ -518,7 +553,12 @@ M_MoveToGoal
void M_MoveToGoal (edict_t *ent, float dist)
{
edict_t *goal;
if (!ent)
{
return;
}
goal = ent->goalentity;
if (!ent->groundentity && !(ent->flags & (FL_FLY|FL_SWIM)))
@ -545,7 +585,12 @@ M_walkmove
qboolean M_walkmove (edict_t *ent, float yaw, float dist)
{
vec3_t move;
if (!ent)
{
return false;
}
if (!ent->groundentity && !(ent->flags & (FL_FLY|FL_SWIM)))
return false;
@ -571,6 +616,11 @@ qboolean M_MoveAwayFromFlare(edict_t *self, float dist)
vec3_t delta;
vec3_t forward;
if (!self)
{
return false;
}
// find the closest flare
while(1)
{

View file

@ -30,6 +30,11 @@ static int sound_thud;
void mutant_step (edict_t *self)
{
if (!self)
{
return;
}
int n;
n = (rand() + 1) % 3;
if (n == 0)
@ -42,16 +47,31 @@ void mutant_step (edict_t *self)
void mutant_sight (edict_t *self, edict_t *other)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
}
void mutant_search (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_search, 1, ATTN_NORM, 0);
}
void mutant_swing (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_swing, 1, ATTN_NORM, 0);
}
@ -123,6 +143,11 @@ mmove_t mutant_move_stand = {FRAME_stand101, FRAME_stand151, mutant_frames_stand
void mutant_stand (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &mutant_move_stand;
}
@ -133,6 +158,11 @@ void mutant_stand (edict_t *self)
void mutant_idle_loop (edict_t *self)
{
if (!self)
{
return;
}
if (random() < 0.75)
self->monsterinfo.nextframe = FRAME_stand155;
}
@ -157,6 +187,11 @@ mmove_t mutant_move_idle = {FRAME_stand152, FRAME_stand164, mutant_frames_idle,
void mutant_idle (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &mutant_move_idle;
gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0);
}
@ -187,6 +222,11 @@ mmove_t mutant_move_walk = {FRAME_walk05, FRAME_walk16, mutant_frames_walk, NULL
void mutant_walk_loop (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &mutant_move_walk;
}
@ -201,6 +241,11 @@ mmove_t mutant_move_start_walk = {FRAME_walk01, FRAME_walk04, mutant_frames_star
void mutant_walk (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &mutant_move_start_walk;
}
@ -222,6 +267,11 @@ mmove_t mutant_move_run = {FRAME_run03, FRAME_run08, mutant_frames_run, NULL};
void mutant_run (edict_t *self)
{
if (!self)
{
return;
}
if (self->monsterinfo.aiflags & AI_STAND_GROUND)
self->monsterinfo.currentmove = &mutant_move_stand;
else
@ -235,6 +285,11 @@ void mutant_run (edict_t *self)
void mutant_hit_left (edict_t *self)
{
if (!self)
{
return;
}
vec3_t aim;
VectorSet (aim, MELEE_DISTANCE, self->mins[0], 8);
@ -246,6 +301,11 @@ void mutant_hit_left (edict_t *self)
void mutant_hit_right (edict_t *self)
{
if (!self)
{
return;
}
vec3_t aim;
VectorSet (aim, MELEE_DISTANCE, self->maxs[0], 8);
@ -257,6 +317,11 @@ void mutant_hit_right (edict_t *self)
void mutant_check_refire (edict_t *self)
{
if (!self)
{
return;
}
if (!self->enemy || !self->enemy->inuse || self->enemy->health <= 0)
return;
@ -278,6 +343,11 @@ mmove_t mutant_move_attack = {FRAME_attack09, FRAME_attack15, mutant_frames_atta
void mutant_melee (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &mutant_move_attack;
}
@ -288,6 +358,11 @@ void mutant_melee (edict_t *self)
void mutant_jump_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
{
if (!self || !other)
{
return;
}
if (self->health <= 0)
{
self->touch = NULL;
@ -327,6 +402,11 @@ void mutant_jump_takeoff (edict_t *self)
{
vec3_t forward;
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
AngleVectors (self->s.angles, forward, NULL, NULL);
self->s.origin[2] += 1;
@ -340,6 +420,11 @@ void mutant_jump_takeoff (edict_t *self)
void mutant_check_landing (edict_t *self)
{
if (!self)
{
return;
}
if (self->groundentity)
{
gi.sound (self, CHAN_WEAPON, sound_thud, 1, ATTN_NORM, 0);
@ -369,6 +454,11 @@ mmove_t mutant_move_jump = {FRAME_attack01, FRAME_attack08, mutant_frames_jump,
void mutant_jump (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &mutant_move_jump;
}
@ -379,6 +469,11 @@ void mutant_jump (edict_t *self)
qboolean mutant_check_melee (edict_t *self)
{
if (!self)
{
return false;
}
if (range (self, self->enemy) == RANGE_MELEE)
return true;
return false;
@ -389,6 +484,11 @@ qboolean mutant_check_jump (edict_t *self)
vec3_t v;
float distance;
if (!self)
{
return false;
}
if (self->absmin[2] > (self->enemy->absmin[2] + 0.75 * self->enemy->size[2]))
return false;
@ -413,6 +513,11 @@ qboolean mutant_check_jump (edict_t *self)
qboolean mutant_checkattack (edict_t *self)
{
if (!self)
{
return false;
}
if (!self->enemy || self->enemy->health <= 0)
return false;
@ -514,6 +619,11 @@ void mutant_pain (edict_t *self, edict_t *other, float kick, int damage)
void mutant_dead (edict_t *self)
{
if (!self)
{
return;
}
VectorSet (self->mins, -16, -16, -24);
VectorSet (self->maxs, 16, 16, -8);
self->movetype = MOVETYPE_TOSS;
@ -556,6 +666,11 @@ void mutant_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damag
{
int n;
if (!self)
{
return;
}
if (self->health <= self->gib_health)
{
gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0);
@ -591,6 +706,11 @@ void mutant_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damag
*/
void SP_monster_mutant (edict_t *self)
{
if (!self)
{
return;
}
if (deathmatch->value)
{
G_FreeEdict (self);

View file

@ -35,31 +35,61 @@ void parasite_refidget (edict_t *self);
void parasite_launch (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_WEAPON, sound_launch, 1, ATTN_NORM, 0);
}
void parasite_reel_in (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_WEAPON, sound_reelin, 1, ATTN_NORM, 0);
}
void parasite_sight (edict_t *self, edict_t *other)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_WEAPON, sound_sight, 1, ATTN_NORM, 0);
}
void parasite_tap (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_WEAPON, sound_tap, 1, ATTN_IDLE, 0);
}
void parasite_scratch (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_WEAPON, sound_scratch, 1, ATTN_IDLE, 0);
}
void parasite_search (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_WEAPON, sound_search, 1, ATTN_IDLE, 0);
}
@ -99,16 +129,31 @@ mmove_t parasite_move_end_fidget = {FRAME_stand28, FRAME_stand35, parasite_frame
void parasite_end_fidget (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &parasite_move_end_fidget;
}
void parasite_do_fidget (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &parasite_move_fidget;
}
void parasite_refidget (edict_t *self)
{
{
if (!self)
{
return;
}
if (random() <= 0.8)
self->monsterinfo.currentmove = &parasite_move_fidget;
else
@ -116,7 +161,12 @@ void parasite_refidget (edict_t *self)
}
void parasite_idle (edict_t *self)
{
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &parasite_move_start_fidget;
}
@ -145,6 +195,11 @@ mmove_t parasite_move_stand = {FRAME_stand01, FRAME_stand17, parasite_frames_sta
void parasite_stand (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &parasite_move_stand;
}
@ -180,7 +235,12 @@ mframe_t parasite_frames_stop_run [] =
mmove_t parasite_move_stop_run = {FRAME_run10, FRAME_run15, parasite_frames_stop_run, NULL};
void parasite_start_run (edict_t *self)
{
{
if (!self)
{
return;
}
if (self->monsterinfo.aiflags & AI_STAND_GROUND)
self->monsterinfo.currentmove = &parasite_move_stand;
else
@ -189,6 +249,11 @@ void parasite_start_run (edict_t *self)
void parasite_run (edict_t *self)
{
if (!self)
{
return;
}
if (self->monsterinfo.aiflags & AI_STAND_GROUND)
self->monsterinfo.currentmove = &parasite_move_stand;
else
@ -227,12 +292,22 @@ mframe_t parasite_frames_stop_walk [] =
mmove_t parasite_move_stop_walk = {FRAME_run10, FRAME_run15, parasite_frames_stop_walk, NULL};
void parasite_start_walk (edict_t *self)
{
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &parasite_move_start_walk;
}
void parasite_walk (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &parasite_move_walk;
}
@ -255,6 +330,11 @@ mmove_t parasite_move_pain1 = {FRAME_pain101, FRAME_pain111, parasite_frames_pai
void parasite_pain (edict_t *self, edict_t *other, float kick, int damage)
{
if (!self)
{
return;
}
if (self->health < (self->max_health / 2))
self->s.skinnum = 1;
@ -300,6 +380,11 @@ void parasite_drain_attack (edict_t *self)
trace_t tr;
int damage;
if (!self)
{
return;
}
AngleVectors (self->s.angles, f, r, NULL);
VectorSet (offset, 24, 0, 6);
G_ProjectSource (self->s.origin, offset, f, r, start);
@ -413,7 +498,12 @@ Break Stuff Ends
void parasite_attack (edict_t *self)
{
self->monsterinfo.currentmove = &parasite_move_drain;
if (!self)
{
return;
}
self->monsterinfo.currentmove = &parasite_move_drain;
}
@ -426,6 +516,11 @@ Death Stuff Starts
void parasite_dead (edict_t *self)
{
if (!self)
{
return;
}
VectorSet (self->mins, -16, -16, -24);
VectorSet (self->maxs, 16, 16, -8);
self->movetype = MOVETYPE_TOSS;
@ -450,6 +545,11 @@ void parasite_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int dam
{
int n;
if (!self)
{
return;
}
// check for gib
if (self->health <= self->gib_health)
{
@ -483,6 +583,11 @@ End Death Stuff
*/
void SP_monster_parasite (edict_t *self)
{
if (!self)
{
return;
}
if (deathmatch->value)
{
G_FreeEdict (self);

View file

@ -27,67 +27,132 @@ static int sound_att3;
void sentien_sound_footstep(edict_t *self)
{
gi.sound(self, CHAN_BODY, sound_walk, 1, ATTN_NORM, 0);
if (!self)
{
return;
}
gi.sound(self, CHAN_BODY, sound_walk, 1, ATTN_NORM, 0);
}
void sentien_sound_idle1(edict_t *self)
{
gi.sound(self, CHAN_BODY, sound_idle1, 1, ATTN_NORM, 0);
if (!self)
{
return;
}
gi.sound(self, CHAN_BODY, sound_idle1, 1, ATTN_NORM, 0);
}
void sentien_sound_idle2(edict_t *self)
{
gi.sound(self, CHAN_BODY, sound_idle2, 1, ATTN_NORM, 0);
if (!self)
{
return;
}
gi.sound(self, CHAN_BODY, sound_idle2, 1, ATTN_NORM, 0);
}
void sentien_sound_idle3(edict_t *self)
{
gi.sound(self, CHAN_BODY, sound_idle3, 1, ATTN_NORM, 0);
if (!self)
{
return;
}
gi.sound(self, CHAN_BODY, sound_idle3, 1, ATTN_NORM, 0);
}
void sentian_sound_att1(edict_t *self)
{
gi.sound(self, CHAN_BODY, sound_att1, 1, ATTN_NORM, 0);
if (!self)
{
return;
}
gi.sound(self, CHAN_BODY, sound_att1, 1, ATTN_NORM, 0);
}
void sentian_sound_att2(edict_t *self)
{
gi.sound(self, CHAN_BODY, sound_att2, 1, ATTN_NORM, 0);
if (!self)
{
return;
}
gi.sound(self, CHAN_BODY, sound_att2, 1, ATTN_NORM, 0);
}
void sentian_sound_att3(edict_t *self)
{
gi.sound(self, CHAN_BODY, sound_att3, 1, ATTN_NORM, 0);
if (!self)
{
return;
}
gi.sound(self, CHAN_BODY, sound_att3, 1, ATTN_NORM, 0);
}
void sentian_sound_fend(edict_t *self)
{
gi.sound(self, CHAN_BODY, sound_fend, 1, ATTN_NORM, 0);
if (!self)
{
return;
}
gi.sound(self, CHAN_BODY, sound_fend, 1, ATTN_NORM, 0);
}
void sentian_sound_pain1(edict_t *self)
{
gi.sound(self, CHAN_BODY, sound_pain1, 1, ATTN_NORM, 0);
if (!self)
{
return;
}
gi.sound(self, CHAN_BODY, sound_pain1, 1, ATTN_NORM, 0);
}
void sentian_sound_pain2(edict_t *self)
{
gi.sound(self, CHAN_BODY, sound_pain2, 1, ATTN_NORM, 0);
if (!self)
{
return;
}
gi.sound(self, CHAN_BODY, sound_pain2, 1, ATTN_NORM, 0);
}
void sentian_sound_pain3(edict_t *self)
{
gi.sound(self, CHAN_BODY, sound_pain3, 1, ATTN_NORM, 0);
if (!self)
{
return;
}
gi.sound(self, CHAN_BODY, sound_pain3, 1, ATTN_NORM, 0);
}
void sentian_sound_die1(edict_t *self)
{
gi.sound(self, CHAN_BODY, sound_die1, 1, ATTN_NORM, 0);
if (!self)
{
return;
}
gi.sound(self, CHAN_BODY, sound_die1, 1, ATTN_NORM, 0);
}
void sentian_sound_die2(edict_t *self)
{
gi.sound(self, CHAN_BODY, sound_die2, 1, ATTN_NORM, 0);
if (!self)
{
return;
}
gi.sound(self, CHAN_BODY, sound_die2, 1, ATTN_NORM, 0);
}
@ -202,42 +267,57 @@ mmove_t sentien_move_stand3 = {FRAME_stand3start, FRAME_stand3end,
void sentien_stand(edict_t *self)
{
target_laser_off(self->laser);
if (!self)
{
return;
}
self->monsterinfo.currentmove = &sentien_move_stand1;
target_laser_off(self->laser);
self->monsterinfo.currentmove = &sentien_move_stand1;
}
void sentien_stand_whatnow(edict_t *self)
{
float r;
r = random();
float r;
r = random();
if(r < self->random)
{
self->monsterinfo.currentmove = &sentien_move_stand1;
self->random -= 0.05;
}
else
{
r = random();
if(r < 0.5)
self->monsterinfo.currentmove = &sentien_move_stand2;
else
self->monsterinfo.currentmove = &sentien_move_stand3;
if (!self)
{
return;
}
self->random = 1;
}
if(r < self->random)
{
self->monsterinfo.currentmove = &sentien_move_stand1;
self->random -= 0.05;
}
else
{
r = random();
if(r < 0.5)
self->monsterinfo.currentmove = &sentien_move_stand2;
else
self->monsterinfo.currentmove = &sentien_move_stand3;
self->random = 1;
}
}
void sentien_stand_earwax(edict_t *self)
{
if(random() > 0.80)
{
//more ear wax damn it, try again
self->monsterinfo.currentmove = &sentien_move_stand3;
}
else
sentien_stand_whatnow(self);
if (!self)
{
return;
}
if(random() > 0.80)
{
//more ear wax damn it, try again
self->monsterinfo.currentmove = &sentien_move_stand3;
}
else
sentien_stand_whatnow(self);
}
/*=========================================================================
@ -301,21 +381,26 @@ mmove_t sentien_move_walk_end = {FRAME_walkEndStart, FRAME_walkEndEnd,
void sentien_walk(edict_t *self)
{
target_laser_off(self->laser);
if (!self)
{
return;
}
if(self->monsterinfo.currentmove == &sentien_move_walk)
return;
target_laser_off(self->laser);
if (self->monsterinfo.currentmove == &sentien_move_stand1 ||
self->monsterinfo.currentmove == &sentien_move_stand2 ||
self->monsterinfo.currentmove == &sentien_move_stand3)
{
self->monsterinfo.currentmove = &sentien_move_walk_start;
}
else
{
self->monsterinfo.currentmove = &sentien_move_walk;
}
if(self->monsterinfo.currentmove == &sentien_move_walk)
return;
if (self->monsterinfo.currentmove == &sentien_move_stand1 ||
self->monsterinfo.currentmove == &sentien_move_stand2 ||
self->monsterinfo.currentmove == &sentien_move_stand3)
{
self->monsterinfo.currentmove = &sentien_move_walk_start;
}
else
{
self->monsterinfo.currentmove = &sentien_move_walk;
}
}
@ -380,7 +465,12 @@ mmove_t sentien_move_run_end = {FRAME_walkEndStart, FRAME_walkEndEnd,
void sentien_run(edict_t *self)
{
target_laser_off(self->laser);
if (!self)
{
return;
}
target_laser_off(self->laser);
if (self->monsterinfo.aiflags & AI_STAND_GROUND)
{
@ -388,18 +478,18 @@ void sentien_run(edict_t *self)
return;
}
if (self->monsterinfo.currentmove == &sentien_move_run)
return;
if (self->monsterinfo.currentmove == &sentien_move_run)
return;
if (self->monsterinfo.currentmove == &sentien_move_walk ||
self->monsterinfo.currentmove == &sentien_move_run_start)
{
self->monsterinfo.currentmove = &sentien_move_run;
}
else
{
self->monsterinfo.currentmove = &sentien_move_run_start;
}
if (self->monsterinfo.currentmove == &sentien_move_walk ||
self->monsterinfo.currentmove == &sentien_move_run_start)
{
self->monsterinfo.currentmove = &sentien_move_run;
}
else
{
self->monsterinfo.currentmove = &sentien_move_run_start;
}
}
/*=========================================================================
@ -448,43 +538,58 @@ mmove_t sentien_move_post_blast_attack = { FRAME_blastPostStart, FRAME_blast
void sentien_blast_attack(edict_t *self)
{
target_laser_off(self->laser);
if (!self)
{
return;
}
self->monsterinfo.currentmove = &sentien_move_blast_attack;
target_laser_off(self->laser);
// is a player right infront?
if (visible(self, self->enemy) &&
infront(self, self->enemy))
{
self->monsterinfo.currentmove = &sentien_move_blast_attack;
}
else
self->monsterinfo.currentmove = &sentien_move_post_blast_attack;
self->monsterinfo.currentmove = &sentien_move_blast_attack;
// is a player right infront?
if (visible(self, self->enemy) &&
infront(self, self->enemy))
{
self->monsterinfo.currentmove = &sentien_move_blast_attack;
}
else
self->monsterinfo.currentmove = &sentien_move_post_blast_attack;
}
void sentien_post_blast_attack(edict_t *self)
{
float refire = 0.25;
float refire = 0.25;
if (visible(self, self->enemy) &&
infront(self, self->enemy))
{
if(skill->value == SKILL_MEDIUM)
refire = 0.40;
else if(skill->value == SKILL_HARD)
refire = 0.60;
else if(skill->value >= SKILL_HARDPLUS)
refire = 0.75;
if (!self)
{
return;
}
if (random() > refire)
self->monsterinfo.currentmove = &sentien_move_post_blast_attack;
}
else
self->monsterinfo.currentmove = &sentien_move_post_blast_attack;
if (visible(self, self->enemy) &&
infront(self, self->enemy))
{
if(skill->value == SKILL_MEDIUM)
refire = 0.40;
else if(skill->value == SKILL_HARD)
refire = 0.60;
else if(skill->value >= SKILL_HARDPLUS)
refire = 0.75;
if (random() > refire)
self->monsterinfo.currentmove = &sentien_move_post_blast_attack;
}
else
self->monsterinfo.currentmove = &sentien_move_post_blast_attack;
}
void sentien_fire_bullet (edict_t *self, vec3_t start, vec3_t dir, int damage)
{
if (!self)
{
return;
}
if(EMPNukeCheck(self, self->s.origin))
{
gi.sound (self, CHAN_AUTO, gi.soundindex("items/empnuke/emp_missfire.wav"), 1, ATTN_NORM, 0);
@ -493,8 +598,8 @@ void sentien_fire_bullet (edict_t *self, vec3_t start, vec3_t dir, int damage)
ANIM_AIM(self, dir);
fire_bullet (self, start, dir, 2, 4,
DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD,
MOD_UNKNOWN);
DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD,
MOD_UNKNOWN);
sentian_sound_att1(self);
}
@ -519,12 +624,17 @@ void sentien_do_blast(edict_t *self)
vec3_t end;
int idx;
if (!self)
{
return;
}
idx = self->s.frame - FRAME_blastStart + 1;
AngleVectors (self->s.angles, forward, right, NULL);
G_ProjectSource (self->s.origin, sentien_flash_offset[0],
forward, right, start);
forward, right, start);
VectorCopy (self->enemy->s.origin, end);
end[2] += self->enemy->viewheight;
@ -534,7 +644,7 @@ void sentien_do_blast(edict_t *self)
//aiming too far sideways and correct if we are.
G_ProjectSource (self->s.origin, sentien_flash_offset[idx],
forward, right, start);
forward, right, start);
if(EMPNukeCheck(self, start))
{
@ -597,23 +707,28 @@ mmove_t sentien_move_post_laser_attack = { FRAME_laserPostStart, FRAME_laser
void sentien_laser_attack(edict_t *self)
{
// is a player right infront?
if (visible(self, self->enemy) &&
infront(self, self->enemy))
{
self->monsterinfo.currentmove = &sentien_move_laser_attack;
}
else
{
self->monsterinfo.currentmove = &sentien_move_post_laser_attack;
target_laser_off(self->laser);
}
if (!self)
{
return;
}
// is a player right infront?
if (visible(self, self->enemy) &&
infront(self, self->enemy))
{
self->monsterinfo.currentmove = &sentien_move_laser_attack;
}
else
{
self->monsterinfo.currentmove = &sentien_move_post_laser_attack;
target_laser_off(self->laser);
}
}
void sentien_post_laser_attack(edict_t *self)
{
self->monsterinfo.currentmove = &sentien_move_post_laser_attack;
target_laser_off(self->laser);
self->monsterinfo.currentmove = &sentien_move_post_laser_attack;
target_laser_off(self->laser);
}
void blaster_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf);
@ -658,7 +773,7 @@ void sentien_do_laser(edict_t *self)
AngleVectors(self->s.angles, forward, right, up);
G_ProjectSource(self->s.origin, sentien_laser_offset[idx],
forward, right, start);
forward, right, start);
VectorCopy(start, self->laser->s.origin);
if(self->s.frame == FRAME_laserStart)
@ -686,15 +801,19 @@ void sentien_do_laser(edict_t *self)
void sentien_attack(edict_t *self)
{
vec3_t vec;
float range;
float r;
target_laser_off(self->laser);
if (!self)
{
return;
}
//sentien_run(self); // to test walking
//return;
target_laser_off(self->laser);
//sentien_run(self); // to test walking
//return;
VectorSubtract (self->enemy->s.origin, self->s.origin, vec);
range = VectorLength (vec);
@ -726,6 +845,11 @@ void sentien_attack(edict_t *self)
void sentien_fend_ready (edict_t *self)
{
if (!self)
{
return;
}
if (self->monsterinfo.aiflags & AI_REDUCEDDAMAGE)
return;
self->monsterinfo.pausetime = level.time + 1;
@ -733,6 +857,11 @@ void sentien_fend_ready (edict_t *self)
void sentien_fend_hold (edict_t *self)
{
if (!self)
{
return;
}
if (level.time >= self->monsterinfo.pausetime)
{
self->monsterinfo.aiflags &= ~AI_HOLD_FRAME;
@ -767,6 +896,11 @@ mmove_t sentien_move_fend = {FRAME_dodgeStart, FRAME_dodgeEnd, sentien_frames_fe
void sentien_fend (edict_t *self, edict_t *attacker, float eta)
{
if (!self || !attacker)
{
return;
}
// don't flinch if attacking
if(self->monsterinfo.currentmove == &sentien_move_laser_attack ||
self->monsterinfo.currentmove == &sentien_move_blast_attack)
@ -852,6 +986,11 @@ void sentien_pain (edict_t *self, edict_t *other, float kick, int damage)
{
float r;
if (!self)
{
return;
}
if((self->health < (self->max_health / 2)))
self->s.skinnum |= 1;
@ -859,19 +998,16 @@ void sentien_pain (edict_t *self, edict_t *other, float kick, int damage)
if (damage <= 10)
return;
r = random();
r = random();
if(r < 0.33)
{
sentian_sound_pain1(self);
}
else if(r < 0.66)
{
sentian_sound_pain2(self);
}
else
{
}
if(r < 0.33)
{
sentian_sound_pain1(self);
}
else if(r < 0.66)
{
sentian_sound_pain2(self);
}
if (level.time < self->pain_debounce_time)
return;
@ -885,8 +1021,8 @@ void sentien_pain (edict_t *self, edict_t *other, float kick, int damage)
{
// don't flinch if attacking
if(self->monsterinfo.currentmove == &sentien_move_laser_attack ||
self->monsterinfo.currentmove == &sentien_move_blast_attack)
return;
self->monsterinfo.currentmove == &sentien_move_blast_attack)
return;
}
if (skill->value == SKILL_HARDPLUS)
return; // no pain anims in nightmare
@ -993,34 +1129,44 @@ vec3_t sentien_death_offset [] =
void sentien_dead(edict_t *self)
{
vec3_t start, end, point;
vec3_t forward, right;
vec3_t start, end, point;
vec3_t forward, right;
AngleVectors (self->s.angles, forward, right, NULL);
G_ProjectSource (self->s.origin, sentien_death_offset[0],
forward, right, point);
VectorSubtract (point, self->s.origin, start);
if (!self)
{
return;
}
G_ProjectSource (self->s.origin, sentien_death_offset[1],
forward, right, point);
VectorSubtract (point, self->s.origin, end);
AngleVectors (self->s.angles, forward, right, NULL);
G_ProjectSource (self->s.origin, sentien_death_offset[0],
forward, right, point);
VectorSubtract (point, self->s.origin, start);
VectorSet (self->mins, MIN(start[0], end[0]), MIN(start[1], end[1]), -16);
VectorSet (self->maxs, MAX(start[0], end[0]), MAX(start[1], end[1]), 0);
G_ProjectSource (self->s.origin, sentien_death_offset[1],
forward, right, point);
VectorSubtract (point, self->s.origin, end);
self->movetype = MOVETYPE_TOSS;
self->svflags |= SVF_DEADMONSTER;
self->nextthink = 0;
gi.linkentity(self);
VectorSet (self->mins, MIN(start[0], end[0]), MIN(start[1], end[1]), -16);
VectorSet (self->maxs, MAX(start[0], end[0]), MAX(start[1], end[1]), 0);
self->movetype = MOVETYPE_TOSS;
self->svflags |= SVF_DEADMONSTER;
self->nextthink = 0;
gi.linkentity(self);
}
void sentien_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
{
int n;
int n;
target_laser_off(self->laser);
if (!self)
{
return;
}
//gib code to go here
target_laser_off(self->laser);
//gib code to go here
if (self->health <= self->gib_health)
{
gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0);
@ -1034,17 +1180,17 @@ void sentien_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int dama
return;
}
if (self->deadflag == DEAD_DEAD)
return;
if (self->deadflag == DEAD_DEAD)
return;
self->deadflag = DEAD_DEAD;
self->takedamage = DAMAGE_YES;
self->s.skinnum |= 1;
self->deadflag = DEAD_DEAD;
self->takedamage = DAMAGE_YES;
self->s.skinnum |= 1;
if (random() < 0.80)
self->monsterinfo.currentmove = &sentien_move_death1;
else
self->monsterinfo.currentmove = &sentien_move_death2;
if (random() < 0.80)
self->monsterinfo.currentmove = &sentien_move_death1;
else
self->monsterinfo.currentmove = &sentien_move_death2;
}
@ -1053,53 +1199,62 @@ void sentien_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int dama
=========================================================================*/
void create_sentien_laser(edict_t *self)
{
vec3_t start;
vec3_t forward, right;
vec3_t start;
vec3_t forward, right;
self->laser = G_Spawn();
self->laser->movetype = MOVETYPE_NONE;
self->laser->solid = SOLID_BBOX;//SOLID_NOT;
self->laser->s.renderfx = RF_BEAM|RF_TRANSLUCENT;
self->laser->s.modelindex = 2;
self->laser->classname = "laser_yaya";
self->laser->s.frame = 2;
self->laser->owner = self;
self->laser->s.skinnum = 0xd0d1d2d3;
self->laser->dmg = 8;
self->laser->think = target_laser_think;
if (!self)
{
return;
}
AngleVectors(self->s.angles, forward, right, NULL);
G_ProjectSource(self->s.origin, sentien_laser_offset[0],
forward, right, start);
self->laser = G_Spawn();
self->laser->movetype = MOVETYPE_NONE;
self->laser->solid = SOLID_BBOX;//SOLID_NOT;
self->laser->s.renderfx = RF_BEAM|RF_TRANSLUCENT;
self->laser->s.modelindex = 2;
self->laser->classname = "laser_yaya";
self->laser->s.frame = 2;
self->laser->owner = self;
self->laser->s.skinnum = 0xd0d1d2d3;
self->laser->dmg = 8;
self->laser->think = target_laser_think;
VectorCopy(start, self->laser->s.origin);
VectorCopy(self->s.angles, self->laser->s.angles);
AngleVectors(self->s.angles, forward, right, NULL);
G_ProjectSource(self->s.origin, sentien_laser_offset[0],
forward, right, start);
G_SetMovedir(self->laser->s.angles, self->laser->movedir);
VectorCopy(start, self->laser->s.origin);
VectorCopy(self->s.angles, self->laser->s.angles);
gi.linkentity (self->laser);
target_laser_off(self->laser);
G_SetMovedir(self->laser->s.angles, self->laser->movedir);
gi.linkentity (self->laser);
target_laser_off(self->laser);
}
void SP_monster_sentien_precache(void)
{
sound_idle1 = gi.soundindex("monsters/sentien/sen_idle1.wav");
sound_idle2 = gi.soundindex("monsters/sentien/sen_idle2.wav");
sound_walk = gi.soundindex("monsters/sentien/sen_walk.wav");
sound_fend = gi.soundindex("monsters/sentien/sen_fend.wav");
sound_pain1 = gi.soundindex("monsters/sentien/sen_pain1.wav");
sound_pain2 = gi.soundindex("monsters/sentien/sen_pain2.wav");
sound_die1 = gi.soundindex("monsters/sentien/sen_die1.wav");
sound_die2 = gi.soundindex("monsters/sentien/sen_die2.wav");
sound_att1 = gi.soundindex("monsters/sentien/sen_att1.wav");
sound_att2 = gi.soundindex("monsters/sentien/sen_att2.wav");
sound_idle1 = gi.soundindex("monsters/sentien/sen_idle1.wav");
sound_idle2 = gi.soundindex("monsters/sentien/sen_idle2.wav");
sound_walk = gi.soundindex("monsters/sentien/sen_walk.wav");
sound_fend = gi.soundindex("monsters/sentien/sen_fend.wav");
sound_pain1 = gi.soundindex("monsters/sentien/sen_pain1.wav");
sound_pain2 = gi.soundindex("monsters/sentien/sen_pain2.wav");
sound_die1 = gi.soundindex("monsters/sentien/sen_die1.wav");
sound_die2 = gi.soundindex("monsters/sentien/sen_die2.wav");
sound_att1 = gi.soundindex("monsters/sentien/sen_att1.wav");
sound_att2 = gi.soundindex("monsters/sentien/sen_att2.wav");
}
void SP_monster_sentien(edict_t *self)
{
{
if (!self)
{
return;
}
SP_monster_sentien_precache();
self->mass = 500;

View file

@ -24,12 +24,22 @@ static int sound_cock;
void soldier_idle (edict_t *self)
{
if (!self)
{
return;
}
if (random() > 0.8)
gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0);
}
void soldier_cock (edict_t *self)
{
if (!self)
{
return;
}
if (self->s.frame == FRAME_stand322)
gi.sound (self, CHAN_WEAPON, sound_cock, 1, ATTN_IDLE, 0);
else
@ -128,6 +138,11 @@ mmove_t soldier_move_stand3 = {FRAME_stand301, FRAME_stand339, soldier_frames_st
void soldier_stand (edict_t *self)
{
if (!self)
{
return;
}
if ((self->monsterinfo.currentmove == &soldier_move_stand3) || (random() < 0.8))
self->monsterinfo.currentmove = &soldier_move_stand1;
else
@ -141,6 +156,11 @@ void soldier_stand (edict_t *self)
void soldier_walk1_random (edict_t *self)
{
if (!self)
{
return;
}
if (random() > 0.1)
self->monsterinfo.nextframe = FRAME_walk101;
}
@ -200,6 +220,11 @@ mmove_t soldier_move_walk2 = {FRAME_walk209, FRAME_walk218, soldier_frames_walk2
void soldier_walk (edict_t *self)
{
if (!self)
{
return;
}
if (random() < 0.5)
self->monsterinfo.currentmove = &soldier_move_walk1;
else
@ -233,6 +258,11 @@ mmove_t soldier_move_run = {FRAME_run03, FRAME_run08, soldier_frames_run, NULL};
void soldier_run (edict_t *self)
{
if (!self)
{
return;
}
if (self->monsterinfo.aiflags & AI_STAND_GROUND)
{
self->monsterinfo.currentmove = &soldier_move_stand1;
@ -329,6 +359,11 @@ void soldier_pain (edict_t *self, edict_t *other, float kick, int damage)
float r;
int n;
if (!self)
{
return;
}
if (self->health < (self->max_health / 2))
self->s.skinnum |= 1;
@ -387,6 +422,11 @@ void soldier_fire (edict_t *self, int flash_number)
float r, u;
int flash_index;
if (!self)
{
return;
}
if (self->s.skinnum < 2)
flash_index = blaster_flash[flash_number];
else if (self->s.skinnum < 4)
@ -445,11 +485,21 @@ void soldier_fire (edict_t *self, int flash_number)
void soldier_fire1 (edict_t *self)
{
if (!self)
{
return;
}
soldier_fire (self, 0);
}
void soldier_attack1_refire1 (edict_t *self)
{
if (!self)
{
return;
}
if (self->s.skinnum > 1)
return;
@ -464,6 +514,11 @@ void soldier_attack1_refire1 (edict_t *self)
void soldier_attack1_refire2 (edict_t *self)
{
if (!self)
{
return;
}
if (self->s.skinnum < 2)
return;
@ -495,11 +550,21 @@ mmove_t soldier_move_attack1 = {FRAME_attak101, FRAME_attak112, soldier_frames_a
void soldier_fire2 (edict_t *self)
{
if (!self)
{
return;
}
soldier_fire (self, 1);
}
void soldier_attack2_refire1 (edict_t *self)
{
if (!self)
{
return;
}
if (self->s.skinnum > 1)
return;
@ -514,6 +579,11 @@ void soldier_attack2_refire1 (edict_t *self)
void soldier_attack2_refire2 (edict_t *self)
{
if (!self)
{
return;
}
if (self->s.skinnum < 2)
return;
@ -551,6 +621,11 @@ mmove_t soldier_move_attack2 = {FRAME_attak201, FRAME_attak218, soldier_frames_a
void soldier_duck_down (edict_t *self)
{
if (!self)
{
return;
}
if (self->monsterinfo.aiflags & AI_DUCKED)
return;
self->monsterinfo.aiflags |= AI_DUCKED;
@ -562,6 +637,11 @@ void soldier_duck_down (edict_t *self)
void soldier_duck_up (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.aiflags &= ~AI_DUCKED;
self->maxs[2] += 32;
self->takedamage = DAMAGE_AIM;
@ -570,12 +650,22 @@ void soldier_duck_up (edict_t *self)
void soldier_fire3 (edict_t *self)
{
if (!self)
{
return;
}
soldier_duck_down (self);
soldier_fire (self, 2);
}
void soldier_attack3_refire (edict_t *self)
{
if (!self)
{
return;
}
if ((level.time + 0.4) < self->monsterinfo.pausetime)
self->monsterinfo.nextframe = FRAME_attak303;
}
@ -598,6 +688,11 @@ mmove_t soldier_move_attack3 = {FRAME_attak301, FRAME_attak309, soldier_frames_a
void soldier_fire4 (edict_t *self)
{
if (!self)
{
return;
}
soldier_fire (self, 3);
}
@ -616,11 +711,21 @@ mmove_t soldier_move_attack4 = {FRAME_attak401, FRAME_attak406, soldier_frames_a
void soldier_fire8 (edict_t *self)
{
if (!self)
{
return;
}
soldier_fire (self, 7);
}
void soldier_attack6_refire (edict_t *self)
{
if (!self)
{
return;
}
if (self->enemy->health <= 0)
return;
@ -652,6 +757,11 @@ mmove_t soldier_move_attack6 = {FRAME_runs01, FRAME_runs14, soldier_frames_attac
void soldier_attack(edict_t *self)
{
if (!self)
{
return;
}
if (self->s.skinnum < 4)
{
if (random() < 0.5)
@ -672,6 +782,11 @@ void soldier_attack(edict_t *self)
void soldier_sight(edict_t *self, edict_t *other)
{
if (!self)
{
return;
}
if (random() < 0.5)
gi.sound (self, CHAN_VOICE, sound_sight1, 1, ATTN_NORM, 0);
else
@ -690,6 +805,11 @@ void soldier_sight(edict_t *self, edict_t *other)
void soldier_duck_hold (edict_t *self)
{
if (!self)
{
return;
}
if (level.time >= self->monsterinfo.pausetime)
self->monsterinfo.aiflags &= ~AI_HOLD_FRAME;
else
@ -710,6 +830,11 @@ void soldier_dodge (edict_t *self, edict_t *attacker, float eta)
{
float r;
if (!self || !attacker)
{
return;
}
r = random();
if (r > 0.25)
return;
@ -754,16 +879,31 @@ void soldier_dodge (edict_t *self, edict_t *attacker, float eta)
void soldier_fire6 (edict_t *self)
{
if (!self)
{
return;
}
soldier_fire (self, 5);
}
void soldier_fire7 (edict_t *self)
{
if (!self)
{
return;
}
soldier_fire (self, 6);
}
void soldier_dead (edict_t *self)
{
if (!self)
{
return;
}
VectorSet (self->mins, -16, -16, -24);
VectorSet (self->maxs, 16, 16, -8);
self->movetype = MOVETYPE_TOSS;
@ -1026,6 +1166,11 @@ void soldier_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int dama
{
int n;
if (!self)
{
return;
}
// check for gib
if (self->health <= self->gib_health)
{
@ -1080,6 +1225,10 @@ void soldier_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int dama
void SP_monster_soldier_x (edict_t *self)
{
if (!self)
{
return;
}
self->s.modelindex = gi.modelindex ("models/monsters/soldier/tris.md2");
self->monsterinfo.scale = MODEL_SCALE;
@ -1118,6 +1267,11 @@ void SP_monster_soldier_x (edict_t *self)
*/
void SP_monster_soldier_light (edict_t *self)
{
if (!self)
{
return;
}
if (deathmatch->value)
{
G_FreeEdict (self);
@ -1141,6 +1295,11 @@ void SP_monster_soldier_light (edict_t *self)
*/
void SP_monster_soldier (edict_t *self)
{
if (!self)
{
return;
}
if (deathmatch->value)
{
G_FreeEdict (self);
@ -1162,6 +1321,11 @@ void SP_monster_soldier (edict_t *self)
*/
void SP_monster_soldier_ss (edict_t *self)
{
if (!self)
{
return;
}
if (deathmatch->value)
{
G_FreeEdict (self);

View file

@ -24,11 +24,21 @@ void BossExplode (edict_t *self);
void TreadSound (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, tread_sound, 1, ATTN_NORM, 0);
}
void supertank_search (edict_t *self)
{
if (!self)
{
return;
}
if (random() < 0.5)
gi.sound (self, CHAN_VOICE, sound_search1, 1, ATTN_NORM, 0);
else
@ -110,9 +120,14 @@ mframe_t supertank_frames_stand []=
{ai_stand, 0, NULL}
};
mmove_t supertank_move_stand = {FRAME_stand_1, FRAME_stand_60, supertank_frames_stand, NULL};
void supertank_stand (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &supertank_move_stand;
}
@ -170,16 +185,31 @@ mmove_t supertank_move_forward = {FRAME_forwrd_1, FRAME_forwrd_18, supertank_fra
void supertank_forward (edict_t *self)
{
self->monsterinfo.currentmove = &supertank_move_forward;
if (!self)
{
return;
}
self->monsterinfo.currentmove = &supertank_move_forward;
}
void supertank_walk (edict_t *self)
{
self->monsterinfo.currentmove = &supertank_move_forward;
if (!self)
{
return;
}
self->monsterinfo.currentmove = &supertank_move_forward;
}
void supertank_run (edict_t *self)
{
if (!self)
{
return;
}
if (self->monsterinfo.aiflags & AI_STAND_GROUND)
self->monsterinfo.currentmove = &supertank_move_stand;
else
@ -421,6 +451,11 @@ mmove_t supertank_move_end_attack1 = {FRAME_attak1_7, FRAME_attak1_20, supertank
void supertank_reattack1(edict_t *self)
{
if (!self)
{
return;
}
if (visible(self, self->enemy))
if (random() < 0.9)
self->monsterinfo.currentmove = &supertank_move_attack1;
@ -432,6 +467,10 @@ void supertank_reattack1(edict_t *self)
void supertank_pain (edict_t *self, edict_t *other, float kick, int damage)
{
if (!self)
{
return;
}
if (self->health < (self->max_health / 2))
self->s.skinnum = 1;
@ -480,6 +519,11 @@ void supertankRocket (edict_t *self)
vec3_t vec;
int flash_number;
if (!self)
{
return;
}
if (self->s.frame == FRAME_attak2_8)
flash_number = MZ2_SUPERTANK_ROCKET_1;
else if (self->s.frame == FRAME_attak2_11)
@ -506,6 +550,11 @@ void supertankMachineGun (edict_t *self)
vec3_t forward, right;
int flash_number;
if (!self)
{
return;
}
flash_number = MZ2_SUPERTANK_MACHINEGUN_1 + (self->s.frame - FRAME_attak1_1);
//FIXME!!!
@ -540,6 +589,11 @@ void supertank_attack(edict_t *self)
vec3_t vec;
float range;
if (!self)
{
return;
}
VectorSubtract (self->enemy->s.origin, self->s.origin, vec);
range = VectorLength (vec);
@ -563,6 +617,11 @@ void supertank_attack(edict_t *self)
void supertank_dead (edict_t *self)
{
if (!self)
{
return;
}
VectorSet (self->mins, -60, -60, 0);
VectorSet (self->maxs, 60, 60, 72);
self->movetype = MOVETYPE_TOSS;
@ -577,6 +636,11 @@ void BossExplode (edict_t *self)
vec3_t org;
int n;
if (!self)
{
return;
}
self->think = BossExplode;
VectorCopy (self->s.origin, org);
org[2] += 24 + (rand()&15);
@ -637,6 +701,11 @@ void BossExplode (edict_t *self)
void supertank_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_death, 1, ATTN_NORM, 0);
self->deadflag = DEAD_DEAD;
self->takedamage = DAMAGE_NO;
@ -652,6 +721,11 @@ void supertank_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int da
*/
void SP_monster_supertank (edict_t *self)
{
if (!self)
{
return;
}
if (deathmatch->value)
{
G_FreeEdict (self);

View file

@ -29,27 +29,52 @@ static int sound_strike;
void tank_sight (edict_t *self, edict_t *other)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
}
void tank_footstep (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_BODY, sound_step, 1, ATTN_NORM, 0);
}
void tank_thud (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_BODY, sound_thud, 1, ATTN_NORM, 0);
}
void tank_windup (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_WEAPON, sound_windup, 1, ATTN_NORM, 0);
}
void tank_idle (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0);
}
@ -95,6 +120,11 @@ mmove_t tank_move_stand = {FRAME_stand01, FRAME_stand30, tank_frames_stand, NULL
void tank_stand (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &tank_move_stand;
}
@ -147,7 +177,12 @@ mmove_t tank_move_stop_walk = {FRAME_walk21, FRAME_walk25, tank_frames_stop_walk
void tank_walk (edict_t *self)
{
self->monsterinfo.currentmove = &tank_move_walk;
if (!self)
{
return;
}
self->monsterinfo.currentmove = &tank_move_walk;
}
@ -199,6 +234,11 @@ mmove_t tank_move_stop_run = {FRAME_walk21, FRAME_walk25, tank_frames_stop_run,
void tank_run (edict_t *self)
{
if (!self)
{
return;
}
if (self->enemy && self->enemy->client)
self->monsterinfo.aiflags |= AI_BRUTAL;
else
@ -268,14 +308,19 @@ mmove_t tank_move_pain3 = {FRAME_pain301, FRAME_pain316, tank_frames_pain3, tank
void tank_pain (edict_t *self, edict_t *other, float kick, int damage)
{
if (!self)
{
return;
}
if (self->health < (self->max_health / 2))
self->s.skinnum |= 1;
self->s.skinnum |= 1;
if (damage <= 10)
return;
if (level.time < self->pain_debounce_time)
return;
return;
if (damage <= 30)
if (random() > 0.2)
@ -317,6 +362,11 @@ void TankBlaster (edict_t *self)
vec3_t dir;
int flash_number;
if (!self)
{
return;
}
if (self->s.frame == FRAME_attak110)
flash_number = MZ2_TANK_BLASTER_1;
else if (self->s.frame == FRAME_attak113)
@ -336,8 +386,13 @@ void TankBlaster (edict_t *self)
void TankStrike (edict_t *self)
{
if (!self)
{
return;
}
gi.sound (self, CHAN_WEAPON, sound_strike, 1, ATTN_NORM, 0);
}
}
void TankRocket (edict_t *self)
{
@ -347,6 +402,11 @@ void TankRocket (edict_t *self)
vec3_t vec;
int flash_number;
if (!self)
{
return;
}
if (self->s.frame == FRAME_attak324)
flash_number = MZ2_TANK_ROCKET_1;
else if (self->s.frame == FRAME_attak327)
@ -373,6 +433,11 @@ void TankMachineGun (edict_t *self)
vec3_t forward, right;
int flash_number;
if (!self)
{
return;
}
flash_number = MZ2_TANK_MACHINEGUN_1 + (self->s.frame - FRAME_attak406);
AngleVectors (self->s.angles, forward, right, NULL);
@ -453,6 +518,11 @@ mmove_t tank_move_attack_post_blast = {FRAME_attak117, FRAME_attak122, tank_fram
void tank_reattack_blaster (edict_t *self)
{
if (!self)
{
return;
}
if (skill->value >= SKILL_HARD)
if (visible (self, self->enemy))
if (self->enemy->health > 0)
@ -467,6 +537,11 @@ void tank_reattack_blaster (edict_t *self)
void tank_poststrike (edict_t *self)
{
if (!self)
{
return;
}
self->enemy = NULL;
tank_run (self);
}
@ -622,6 +697,11 @@ mmove_t tank_move_attack_chain = {FRAME_attak401, FRAME_attak429, tank_frames_at
void tank_refire_rocket (edict_t *self)
{
if (!self)
{
return;
}
// Only on hard or nightmare
if ( skill->value >= SKILL_HARD )
if (self->enemy->health > 0)
@ -636,6 +716,11 @@ void tank_refire_rocket (edict_t *self)
void tank_doattack_rocket (edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &tank_move_attack_fire_rocket;
}
@ -645,6 +730,11 @@ void tank_attack(edict_t *self)
float range;
float r;
if (!self)
{
return;
}
if (self->enemy->health < 0)
{
self->monsterinfo.currentmove = &tank_move_attack_strike;
@ -692,6 +782,11 @@ void tank_attack(edict_t *self)
void tank_dead (edict_t *self)
{
if (!self)
{
return;
}
VectorSet (self->mins, -16, -16, -16);
VectorSet (self->maxs, 16, 16, -0);
self->movetype = MOVETYPE_TOSS;
@ -741,6 +836,11 @@ void tank_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage,
{
int n;
if (!self)
{
return;
}
// check for gib
if (self->health <= self->gib_health)
{
@ -778,6 +878,11 @@ void tank_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage,
*/
void SP_monster_tank (edict_t *self)
{
if (!self)
{
return;
}
if (deathmatch->value)
{
G_FreeEdict (self);

View file

@ -23,6 +23,11 @@ void SP_FixCoopSpots (edict_t *self)
edict_t *spot;
vec3_t d;
if (!self)
{
return;
}
spot = NULL;
while(1)
@ -59,6 +64,11 @@ The normal starting point for a level.
*/
void SP_info_player_start(edict_t *self)
{
if (!self)
{
return;
}
if (!coop->value)
return;
if(Q_stricmp(level.mapname, "security") == 0)
@ -74,6 +84,11 @@ potential spawning position for deathmatch games
*/
void SP_info_player_deathmatch(edict_t *self)
{
if (!self)
{
return;
}
if (!deathmatch->value)
{
G_FreeEdict (self);
@ -88,6 +103,11 @@ potential spawning position for coop games
void SP_info_player_coop(edict_t *self)
{
if (!self)
{
return;
}
if (!coop->value)
{
G_FreeEdict (self);
@ -130,6 +150,11 @@ void SP_info_player_intermission(void)
void stopCamera(edict_t *ent);
void player_pain (edict_t *self, edict_t *other, float kick, int damage)
{
if (!self)
{
return;
}
// player pain is handled at the end of the frame in P_DamageFeedback
// if we're in a camera, get out
if (self->client->zCameraTrack)
@ -143,6 +168,11 @@ qboolean IsFemale (edict_t *ent)
{
char *info;
if (!ent)
{
return false;
}
if (!ent->client)
return false;
@ -192,6 +222,11 @@ void ClientObituary (edict_t *self, edict_t *inflictor, edict_t *attacker)
char *message2;
qboolean ff;
if (!self || !attacker)
{
return;
}
if (coop->value && attacker->client)
meansOfDeath |= MOD_FRIENDLY_FIRE;
@ -436,6 +471,11 @@ void TossClientWeapon (edict_t *self)
qboolean quad;
float spread;
if (!self)
{
return;
}
if (!deathmatch->value)
return;
@ -486,6 +526,11 @@ void LookAtKiller (edict_t *self, edict_t *inflictor, edict_t *attacker)
{
vec3_t dir;
if (!self || !inflictor || !attacker)
{
return;
}
if (attacker && attacker != world && attacker != self)
{
VectorSubtract (attacker->s.origin, self->s.origin, dir);
@ -515,7 +560,11 @@ void player_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damag
{
int n;
if (!self || !inflictor || !attacker)
{
return;
}
// if we're in a camera, get out
if (self->client->zCameraTrack)
{
@ -621,6 +670,11 @@ void InitClientPersistant (gclient_t *client)
{
gitem_t *item;
if (!client)
{
return;
}
memset (&client->pers, 0, sizeof(client->pers));
item = FindItem("Push");
@ -662,6 +716,11 @@ void InitClientPersistant (gclient_t *client)
void InitClientResp (gclient_t *client)
{
if (!client)
{
return;
}
memset (&client->resp, 0, sizeof(client->resp));
client->resp.enterframe = level.framenum;
client->resp.coop_respawn = client->pers;
@ -697,6 +756,11 @@ void SaveClientData (void)
void FetchClientEntData (edict_t *ent)
{
if (!ent)
{
return;
}
ent->health = ent->client->pers.health;
ent->max_health = ent->client->pers.max_health;
if (ent->client->pers.powerArmorActive)
@ -730,6 +794,11 @@ float PlayersRangeFromSpot (edict_t *spot)
int n;
float playerdistance;
if (!spot)
{
return 0.0;
}
bestplayerdistance = 9999999;
@ -1015,6 +1084,11 @@ void body_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage,
{
int n;
if (!self)
{
return;
}
if (self->health < -40)
{
gi.sound (self, CHAN_BODY, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0);
@ -1030,6 +1104,11 @@ void CopyToBodyQue (edict_t *ent)
{
edict_t *body;
if (!ent)
{
return;
}
// grab a body que and cycle to the next one
body = &g_edicts[(int)maxclients->value + level.body_que + 1];
level.body_que = (level.body_que + 1) % BODY_QUEUE_SIZE;
@ -1062,6 +1141,11 @@ void CopyToBodyQue (edict_t *ent)
void respawn (edict_t *self)
{
if (!self)
{
return;
}
if (deathmatch->value || coop->value)
{
// spectator's don't leave bodies
@ -1108,6 +1192,11 @@ void PutClientInServer (edict_t *ent)
client_persistant_t saved;
client_respawn_t resp;
if (!ent)
{
return;
}
// find a spawn point
// do it before setting health back up, so farthest
// ranging doesn't count this client
@ -1261,6 +1350,11 @@ deathmatch mode, so clear everything out before starting them.
*/
void ClientBeginDeathmatch (edict_t *ent)
{
if (!ent)
{
return;
}
G_InitEdict (ent);
InitClientResp (ent->client);
@ -1293,6 +1387,11 @@ void ClientBegin (edict_t *ent)
{
int i;
if (!ent)
{
return;
}
ent->client = game.clients + (ent - g_edicts - 1);
if (deathmatch->value)
@ -1360,6 +1459,11 @@ void ClientUserinfoChanged (edict_t *ent, char *userinfo)
char *s;
int playernum;
if (!ent)
{
return;
}
// check for malformed or illegal info strings
if (!Info_Validate(userinfo))
{
@ -1429,6 +1533,11 @@ qboolean ClientConnect (edict_t *ent, char *userinfo)
{
char *value;
if (!ent)
{
return false;
}
// check to see if they are on the banned IP list
value = Info_ValueForKey (userinfo, "ip");
@ -1472,6 +1581,11 @@ void ClientDisconnect (edict_t *ent)
{
int playernum;
if (!ent)
{
return;
}
if (!ent->client)
return;
@ -1521,6 +1635,11 @@ void PrintPmove (pmove_t *pm)
{
unsigned c1, c2;
if (!pm)
{
return;
}
c1 = CheckBlock (&pm->s, sizeof(pm->s));
c2 = CheckBlock (&pm->cmd, sizeof(pm->cmd));
Com_Printf ("sv %3i:%i %i\n", pm->cmd.impulse, c1, c2);
@ -1541,6 +1660,11 @@ void ClientThink (edict_t *ent, usercmd_t *ucmd)
int i, j;
pmove_t pm;
if (!ent || !ucmd)
{
return;
}
level.current_entity = ent;
client = ent->client;
@ -1695,6 +1819,11 @@ void ClientBeginServerFrame (edict_t *ent)
gclient_t *client;
int buttonMask;
if (!ent)
{
return;
}
if (level.intermissiontime)
return;

View file

@ -12,6 +12,11 @@ INTERMISSION
void MoveClientToIntermission (edict_t *ent)
{
if (!ent)
{
return;
}
if (deathmatch->value || coop->value)
ent->client->showscores = true;
VectorCopy (level.intermission_origin, ent->s.origin);
@ -56,6 +61,11 @@ void BeginIntermission (edict_t *targ)
int i, n;
edict_t *ent, *client;
if (!targ)
{
return;
}
if (level.intermissiontime)
return; // already activated
@ -90,7 +100,7 @@ void BeginIntermission (edict_t *targ)
for (n = 0; n < MAX_ITEMS; n++)
{
if (itemlist[n].flags & IT_KEY)
client->client->pers.inventory[n] = 0;
client->client->pers.inventory[n] = 0;
}
}
}
@ -160,6 +170,11 @@ void DeathmatchScoreboardMessage (edict_t *ent, edict_t *killer)
edict_t *cl_ent;
char *tag;
if (!ent || !killer)
{
return;
}
// sort the clients by score
total = 0;
for (i=0 ; i<game.maxclients ; i++)
@ -245,6 +260,11 @@ Note that it isn't that hard to overflow the 1400 byte message limit!
*/
void DeathmatchScoreboard (edict_t *ent)
{
if (!ent)
{
return;
}
DeathmatchScoreboardMessage (ent, ent->enemy);
gi.unicast (ent, true);
}
@ -259,6 +279,11 @@ Display the scoreboard
*/
void Cmd_Score_f (edict_t *ent)
{
if (!ent)
{
return;
}
ent->client->showinventory = false;
ent->client->showhelp = false;
@ -288,6 +313,11 @@ void HelpComputer (edict_t *ent)
char string[1024];
char *sk;
if (!ent)
{
return;
}
if (skill->value == SKILL_EASY)
sk = "easy";
else if (skill->value == SKILL_MEDIUM)
@ -329,6 +359,11 @@ Display the current help message
*/
void Cmd_Help_f (edict_t *ent)
{
if (!ent)
{
return;
}
// this is for backwards compatability
if (deathmatch->value)
{
@ -364,7 +399,12 @@ void G_SetStats (edict_t *ent)
int index, cells;
int power_armor_type;
cells = 0;
if (!ent)
{
return;
}
cells = 0;
//
// health

View file

@ -78,6 +78,11 @@ edict_t *PlayerTrail_PickFirst (edict_t *self)
int marker;
int n;
if (!self)
{
return NULL;
}
if (!trail_active)
return NULL;
@ -107,6 +112,11 @@ edict_t *PlayerTrail_PickNext (edict_t *self)
int marker;
int n;
if (!self)
{
return NULL;
}
if (!trail_active)
return NULL;

View file

@ -25,20 +25,20 @@ float SV_CalcRoll (vec3_t angles, vec3_t velocity)
float sign;
float side;
float value;
side = DotProduct (velocity, right);
sign = side < 0 ? -1 : 1;
side = fabs(side);
value = sv_rollangle->value;
if (side < sv_rollspeed->value)
side = side * value / sv_rollspeed->value;
else
side = value;
return side*sign;
}
@ -60,6 +60,11 @@ void P_DamageFeedback (edict_t *player)
static vec3_t acolor = {1.0, 1.0, 1.0};
static vec3_t bcolor = {1.0, 0.0, 0.0};
if (!player)
{
return;
}
client = player->client;
// flash the backgrounds behind the status numbers
@ -90,18 +95,18 @@ void P_DamageFeedback (edict_t *player)
i = (i+1)%3;
switch (i)
{
case 0:
player->s.frame = FRAME_pain101-1;
client->anim_end = FRAME_pain104;
break;
case 1:
player->s.frame = FRAME_pain201-1;
client->anim_end = FRAME_pain204;
break;
case 2:
player->s.frame = FRAME_pain301-1;
client->anim_end = FRAME_pain304;
break;
case 0:
player->s.frame = FRAME_pain101-1;
client->anim_end = FRAME_pain104;
break;
case 1:
player->s.frame = FRAME_pain201-1;
client->anim_end = FRAME_pain204;
break;
case 2:
player->s.frame = FRAME_pain301-1;
client->anim_end = FRAME_pain304;
break;
}
}
}
@ -162,10 +167,10 @@ void P_DamageFeedback (edict_t *player)
VectorSubtract (client->damage_from, player->s.origin, v);
VectorNormalize (v);
side = DotProduct (v, right);
client->v_dmg_roll = kick*side*0.3;
side = -DotProduct (v, forward);
client->v_dmg_pitch = kick*side*0.3;
@ -208,6 +213,10 @@ void SV_CalcViewOffset (edict_t *ent)
float delta;
vec3_t v;
if (!ent)
{
return;
}
//===================================
@ -252,7 +261,7 @@ void SV_CalcViewOffset (edict_t *ent)
delta = DotProduct (ent->velocity, forward);
angles[PITCH] += delta*run_pitch->value;
delta = DotProduct (ent->velocity, right);
angles[ROLL] += delta*run_roll->value;
@ -374,6 +383,11 @@ void SV_CalcGunOffset (edict_t *ent)
int i;
float delta;
if (!ent)
{
return;
}
// if we're using the sniper rifle, let's not do this
if (ent->client->pers.weapon &&
Q_stricmp(ent->client->pers.weapon->classname, "weapon_sniperrifle") != 0)
@ -458,8 +472,13 @@ void SV_CalcBlend (edict_t *ent)
vec3_t vieworg;
int remaining;
if (!ent)
{
return;
}
ent->client->ps.blend[0] = ent->client->ps.blend[1] =
ent->client->ps.blend[2] = ent->client->ps.blend[3] = 0;
ent->client->ps.blend[2] = ent->client->ps.blend[3] = 0;
// add for contents
VectorAdd (ent->s.origin, ent->client->ps.viewoffset, vieworg);
@ -484,7 +503,7 @@ void SV_CalcBlend (edict_t *ent)
gi.sound(ent, CHAN_ITEM, gi.soundindex("items/damage2.wav"), 1, ATTN_NORM, 0);
if (remaining > 30 || (remaining & 4) )
SV_AddBlend (0, 0, 1, 0.08, ent->client->ps.blend);
}
}
else if (ent->client->invincible_framenum > level.framenum)
{
remaining = ent->client->invincible_framenum - level.framenum;
@ -513,7 +532,7 @@ void SV_CalcBlend (edict_t *ent)
// add for damage
if (ent->client->damage_alpha > 0)
SV_AddBlend (ent->client->damage_blend[0],ent->client->damage_blend[1]
,ent->client->damage_blend[2], ent->client->damage_alpha, ent->client->ps.blend);
,ent->client->damage_blend[2], ent->client->damage_alpha, ent->client->ps.blend);
if (ent->client->bonus_alpha > 0)
SV_AddBlend (0.85, 0.7, 0.3, ent->client->bonus_alpha, ent->client->ps.blend);
@ -556,6 +575,11 @@ void P_FallingDamage (edict_t *ent)
int damage;
vec3_t dir;
if (!ent)
{
return;
}
if (ent->s.modelindex != 255)
return; // not in the player model
@ -799,6 +823,11 @@ void G_SetClientEffects (edict_t *ent)
int pa_type;
int remaining;
if (!ent)
{
return;
}
ent->s.effects = 0;
ent->s.renderfx = 0;
@ -840,14 +869,14 @@ void G_SetClientEffects (edict_t *ent)
ent->s.renderfx |= (RF_SHELL_RED|RF_SHELL_GREEN|RF_SHELL_BLUE);
}
if(ent->client->zCameraLocalEntity)
{
VectorCopy (ent->s.origin, ent->client->zCameraLocalEntity->s.origin);
VectorCopy (ent->s.angles, ent->client->zCameraLocalEntity->s.angles);
VectorCopy (ent->s.old_origin, ent->client->zCameraLocalEntity->s.old_origin);
if(ent->client->zCameraLocalEntity)
{
VectorCopy (ent->s.origin, ent->client->zCameraLocalEntity->s.origin);
VectorCopy (ent->s.angles, ent->client->zCameraLocalEntity->s.angles);
VectorCopy (ent->s.old_origin, ent->client->zCameraLocalEntity->s.old_origin);
ent->client->zCameraLocalEntity->s.effects = ent->s.effects;
}
ent->client->zCameraLocalEntity->s.effects = ent->s.effects;
}
}
@ -861,6 +890,11 @@ void G_SetClientEvent (edict_t *ent)
if (ent->s.event)
return;
if (!ent)
{
return;
}
if ( ent->groundentity && xyspeed > 225)
{
if ( (int)(current_client->bobtime+bobmove) != bobcycle )
@ -877,6 +911,11 @@ void G_SetClientSound (edict_t *ent)
{
char *weap;
if (!ent)
{
return;
}
if (ent->client->resp.game_helpchanged != game.helpchanged)
{
ent->client->resp.game_helpchanged = game.helpchanged;
@ -890,7 +929,6 @@ void G_SetClientSound (edict_t *ent)
gi.sound (ent, CHAN_VOICE, gi.soundindex ("misc/pc_up.wav"), 1, ATTN_STATIC, 0);
}
if (ent->client->pers.weapon)
weap = ent->client->pers.weapon->classname;
else
@ -920,6 +958,11 @@ void G_SetClientFrame (edict_t *ent)
gclient_t *client;
qboolean duck, run;
if (!ent)
{
return;
}
if (ent->s.modelindex != 255)
return; // not in the player model
@ -960,7 +1003,7 @@ void G_SetClientFrame (edict_t *ent)
return;
}
newanim:
newanim:
// return to either a running or standing frame
client->anim_priority = ANIM_BASIC;
client->anim_duck = duck;
@ -970,7 +1013,7 @@ newanim:
{
client->anim_priority = ANIM_JUMP;
if (ent->s.frame != FRAME_jump2)
ent->s.frame = FRAME_jump1;
ent->s.frame = FRAME_jump1;
client->anim_end = FRAME_jump2;
}
else if (run && client->zCameraTrack == NULL)
@ -1019,6 +1062,11 @@ void ClientEndServerFrame (edict_t *ent)
float bobtime;
int i;
if (!ent)
{
return;
}
current_player = ent;
current_client = ent->client;
@ -1093,7 +1141,7 @@ void ClientEndServerFrame (edict_t *ent)
else
bobmove = 0.0625;
}
bobtime = (current_client->bobtime += bobmove);
if (current_client->ps.pmove.pm_flags & PMF_DUCKED)

View file

@ -9,6 +9,11 @@ byte is_silenced;
void playQuadSound(edict_t *ent)
{
if (!ent)
{
return;
}
if (ent->client->quad_framenum > level.framenum)
gi.sound(ent, CHAN_ITEM, gi.soundindex("items/damage3.wav"), 1, ATTN_NORM, 0);
}
@ -20,6 +25,11 @@ void P_ProjectSource (gclient_t *client, vec3_t point, vec3_t distance, vec3_t f
{
vec3_t _distance;
if (!client)
{
return;
}
VectorCopy (distance, _distance);
if (client->pers.hand == LEFT_HANDED)
_distance[1] *= -1;
@ -45,6 +55,11 @@ void PlayerNoise(edict_t *who, vec3_t where, int type)
{
edict_t *noise;
if (!who)
{
return;
}
if (type == PNOISE_WEAPON)
{
if (who->client->silencer_shots)
@ -106,6 +121,11 @@ qboolean Pickup_Weapon (edict_t *ent, edict_t *other)
int index;
gitem_t *ammo;
if (!ent || !other)
{
return false;
}
index = ITEM_INDEX(ent->item);
if ( ( ((int)(dmflags->value) & DF_WEAPONS_STAY) || coop->value)
@ -161,6 +181,11 @@ current
*/
void ChangeWeapon (edict_t *ent)
{
if (!ent)
{
return;
}
if (ent->client->grenade_time)
{
ent->client->grenade_time = level.time;
@ -211,6 +236,11 @@ NoAmmoWeaponChange
*/
void NoAmmoWeaponChange (edict_t *ent)
{
if (!ent)
{
return;
}
if ( ent->client->pers.inventory[ITEM_INDEX(FindItem("slugs"))]
&& ent->client->pers.inventory[ITEM_INDEX(FindItem("railgun"))] )
{
@ -259,6 +289,11 @@ Called by ClientBeginServerFrame and ClientThink
*/
void Think_Weapon (edict_t *ent)
{
if (!ent)
{
return;
}
// if just died, put the weapon away
if (ent->health < 1)
{
@ -282,9 +317,14 @@ void Think_Weapon (edict_t *ent)
void stuffcmd(edict_t *e, char *s)
{
gi.WriteByte (11);
gi.WriteString (s);
gi.unicast (e, true);
if (!e)
{
return;
}
gi.WriteByte (11);
gi.WriteString (s);
gi.unicast (e, true);
}
@ -300,6 +340,11 @@ void Use_Weapon (edict_t *ent, gitem_t *item)
int ammo_index;
gitem_t *ammo_item;
if (!ent || !item)
{
return;
}
// see if we're already using it
if (item == ent->client->pers.weapon)
{
@ -343,6 +388,11 @@ void Drop_Weapon (edict_t *ent, gitem_t *item)
{
int index;
if (!ent || !item)
{
return;
}
if ((int)(dmflags->value) & DF_WEAPONS_STAY)
return;
@ -374,6 +424,11 @@ void Weapon_Generic (edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST,
{
int n;
if (!ent)
{
return;
}
if (ent->client->weaponstate == WEAPON_DROPPING)
{
if (ent->client->ps.gunframe == FRAME_DEACTIVATE_LAST)
@ -507,6 +562,11 @@ void weapon_grenade_fire (edict_t *ent, qboolean held)
int speed;
float radius;
if (!ent)
{
return;
}
radius = damage+40;
if (is_quad)
damage *= 4;
@ -530,6 +590,11 @@ void weapon_grenade_fire (edict_t *ent, qboolean held)
void Weapon_Grenade (edict_t *ent)
{
if (!ent)
{
return;
}
if ((ent->client->newweapon) && (ent->client->weaponstate == WEAPON_READY))
{
ChangeWeapon (ent);
@ -650,6 +715,11 @@ void weapon_grenadelauncher_fire (edict_t *ent)
int damage;
float radius;
if (!ent)
{
return;
}
if(GetItemByIndex(ent->client->ammo_index)->tag == AMMO_GRENADES)
{
damage = 120;
@ -693,6 +763,11 @@ void Weapon_GrenadeLauncher (edict_t *ent)
static int pause_frames[] = {34, 51, 59, 0};
static int fire_frames[] = {6, 0};
if (!ent)
{
return;
}
Weapon_Generic (ent, 5, 16, 59, 64, pause_frames, fire_frames, weapon_grenadelauncher_fire);
}
@ -711,6 +786,11 @@ void Weapon_RocketLauncher_Fire (edict_t *ent)
float damage_radius;
int radius_damage;
if (!ent)
{
return;
}
damage = 100 + (int)(random() * 20.0);
radius_damage = 120;
damage_radius = 120;
@ -759,6 +839,11 @@ void Weapon_RocketLauncher (edict_t *ent)
static int pause_frames[] = {25, 33, 42, 50, 0};
static int fire_frames[] = {5, 0};
if (!ent)
{
return;
}
Weapon_Generic (ent, 4, 12, 50, 54, pause_frames, fire_frames, Weapon_RocketLauncher_Fire);
}
@ -778,6 +863,11 @@ int Blaster_Fire (edict_t *ent, vec3_t g_offset, int damage, qboolean hyper, int
vec3_t offset;
int ret = 1;
if (!ent)
{
return 0;
}
if (is_quad)
damage *= 4;
AngleVectors (ent->client->v_angle, forward, right, NULL);
@ -820,6 +910,11 @@ void Weapon_Blaster_Fire (edict_t *ent)
{
int damage;
if (!ent)
{
return;
}
if (deathmatch->value)
damage = 15;
else
@ -833,6 +928,11 @@ void Weapon_Blaster (edict_t *ent)
static int pause_frames[] = {19, 32, 0};
static int fire_frames[] = {5, 0};
if (!ent)
{
return;
}
Weapon_Generic (ent, 4, 8, 52, 55, pause_frames, fire_frames, Weapon_Blaster_Fire);
}
@ -844,6 +944,11 @@ void Weapon_HyperBlaster_Fire (edict_t *ent)
int effect;
int damage;
if (!ent)
{
return;
}
ent->client->weapon_sound = gi.soundindex("weapons/hyprbl1a.wav");
if (!(ent->client->buttons & BUTTON_ATTACK))
@ -902,6 +1007,11 @@ void Weapon_HyperBlaster (edict_t *ent)
static int pause_frames[] = {0};
static int fire_frames[] = {6, 7, 8, 9, 10, 11, 0};
if (!ent)
{
return;
}
Weapon_Generic (ent, 5, 20, 49, 53, pause_frames, fire_frames, Weapon_HyperBlaster_Fire);
}
@ -923,6 +1033,11 @@ void Machinegun_Fire (edict_t *ent)
int kick = 2;
vec3_t offset;
if (!ent)
{
return;
}
if (!(ent->client->buttons & BUTTON_ATTACK))
{
ent->client->machinegun_shots = 0;
@ -995,6 +1110,11 @@ void Weapon_Machinegun (edict_t *ent)
static int pause_frames[] = {23, 45, 0};
static int fire_frames[] = {4, 5, 0};
if (!ent)
{
return;
}
Weapon_Generic (ent, 3, 5, 45, 49, pause_frames, fire_frames, Machinegun_Fire);
}
@ -1009,6 +1129,11 @@ void Chaingun_Fire (edict_t *ent)
int damage;
int kick = 2;
if (!ent)
{
return;
}
if (deathmatch->value)
damage = 6;
else
@ -1120,6 +1245,11 @@ void Weapon_Chaingun (edict_t *ent)
static int pause_frames[] = {38, 43, 51, 61, 0};
static int fire_frames[] = {5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 0};
if (!ent)
{
return;
}
Weapon_Generic (ent, 4, 31, 61, 64, pause_frames, fire_frames, Chaingun_Fire);
}
@ -1140,6 +1270,11 @@ void weapon_shotgun_fire (edict_t *ent)
int damage = 4;
int kick = 8;
if (!ent)
{
return;
}
if (ent->client->ps.gunframe == 9)
{
ent->client->ps.gunframe++;
@ -1186,6 +1321,11 @@ void Weapon_Shotgun (edict_t *ent)
static int pause_frames[] = {22, 28, 34, 0};
static int fire_frames[] = {8, 9, 0};
if (!ent)
{
return;
}
Weapon_Generic (ent, 7, 18, 36, 39, pause_frames, fire_frames, weapon_shotgun_fire);
}
@ -1199,6 +1339,11 @@ void weapon_supershotgun_fire (edict_t *ent)
int damage = 6;
int kick = 12;
if (!ent)
{
return;
}
AngleVectors (ent->client->v_angle, forward, right, NULL);
VectorScale (forward, -2, ent->client->kick_origin);
@ -1243,6 +1388,11 @@ void Weapon_SuperShotgun (edict_t *ent)
static int pause_frames[] = {29, 42, 57, 0};
static int fire_frames[] = {7, 0};
if (!ent)
{
return;
}
Weapon_Generic (ent, 6, 17, 57, 61, pause_frames, fire_frames, weapon_supershotgun_fire);
}
@ -1264,6 +1414,11 @@ void weapon_railgun_fire (edict_t *ent)
int damage;
int kick;
if (!ent)
{
return;
}
if (deathmatch->value)
{ // normal damage is too extreme in dm
damage = 100;
@ -1320,6 +1475,11 @@ void Weapon_Railgun (edict_t *ent)
static int pause_frames[] = {56, 0};
static int fire_frames[] = {4, 0};
if (!ent)
{
return;
}
Weapon_Generic (ent, 3, 18, 56, 61, pause_frames, fire_frames, weapon_railgun_fire);
}
@ -1339,6 +1499,11 @@ void weapon_bfg_fire (edict_t *ent)
int damage;
float damage_radius = 1000;
if (!ent)
{
return;
}
AngleVectors (ent->client->v_angle, forward, right, NULL);
VectorScale (forward, -2, ent->client->kick_origin);
@ -1416,6 +1581,11 @@ void Weapon_BFG (edict_t *ent)
static int pause_frames[] = {39, 45, 50, 55, 0};
static int fire_frames[] = {9, 17, 0};
if (!ent)
{
return;
}
Weapon_Generic (ent, 8, 32, 55, 58, pause_frames, fire_frames, weapon_bfg_fire);
}

View file

@ -199,6 +199,11 @@ void monster_autocannon_fire(edict_t *self)
{
vec3_t forward, right, start;
if (!self)
{
return;
}
// fire straight ahead
AngleVectors (self->s.angles, forward, right, NULL);
if (self->onFloor)
@ -275,6 +280,11 @@ qboolean canShoot(edict_t *self, edict_t *e)
vec3_t delta;
vec3_t dangles;
if (!self || !e)
{
return false;
}
VectorSubtract(e->s.origin, self->s.origin, delta);
vectoangles(delta, dangles);
dangles[PITCH] = mod180(dangles[PITCH]);
@ -304,12 +314,17 @@ qboolean autocannonInfront (edict_t *self, edict_t *other)
float dot;
float min = -30.0;
float max = 30.0;
if (!self || !other)
{
return false;
}
// what's the yaw distance between the 2?
VectorSubtract (other->s.origin, self->s.origin, vec);
vectoangles(vec, angle);
dot = angle[YAW] - self->s.angles[YAW];
if (angleBetween(&dot, &min, &max))
return true;
return false;
@ -319,6 +334,11 @@ void monster_autocannon_findenemy(edict_t *self)
{
edict_t *e = NULL;
if (!self)
{
return;
}
// can we still use our enemy?
if (self->enemy)
{
@ -407,6 +427,12 @@ void monster_autocannon_turn(edict_t *self)
{
vec3_t old_angles;
VectorCopy(self->s.angles, old_angles);
if (!self)
{
return;
}
if (!self->enemy)
{
if (self->monsterinfo.linkcount > 0)
@ -518,6 +544,11 @@ void monster_autocannon_think(edict_t *self)
int lefty = 0;
edict_t *old_enemy;
if (!self)
{
return;
}
self->nextthink = level.time + FRAMETIME;
// get an enemy
@ -599,6 +630,11 @@ void monster_autocannon_explode (edict_t *ent)
{
vec3_t origin;
if (!ent)
{
return;
}
T_RadiusDamage(ent, ent, AC_EXPLODE_DMG, ent->enemy, AC_EXPLODE_RADIUS, MOD_TRIPBOMB);
VectorMA (ent->s.origin, -0.02, ent->velocity, origin);
@ -631,6 +667,11 @@ void monster_autocannon_explode (edict_t *ent)
void monster_autocannon_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
{
if (!self)
{
return;
}
// explode
self->takedamage = DAMAGE_NO;
self->think = monster_autocannon_explode;
@ -639,6 +680,11 @@ void monster_autocannon_die (edict_t *self, edict_t *inflictor, edict_t *attacke
void monster_autocannon_pain (edict_t *self, edict_t *other, float kick, int damage)
{
if (!self || !other)
{
return;
}
// keep the enemy
if (other->client || other->svflags & SVF_MONSTER)
self->enemy = other;
@ -646,6 +692,11 @@ void monster_autocannon_pain (edict_t *self, edict_t *other, float kick, int dam
void monster_autocannon_activate(edict_t *self)
{
if (!self)
{
return;
}
self->active = AC_S_ACTIVATING;
self->nextthink = level.time + FRAMETIME;
@ -677,6 +728,11 @@ void monster_autocannon_activate(edict_t *self)
void monster_autocannon_deactivate(edict_t *self)
{
if (!self)
{
return;
}
self->active = AC_S_DEACTIVATING;
self->nextthink = level.time + FRAMETIME;
@ -723,6 +779,11 @@ void monster_autocannon_deactivate(edict_t *self)
void monster_autocannon_act(edict_t *self)
{
if (!self)
{
return;
}
if (self->active == AC_S_IDLE)
{
if (acActStart[self->style] != -1)
@ -759,6 +820,11 @@ void monster_autocannon_act(edict_t *self)
void monster_autocannon_use(edict_t *self, edict_t *other, edict_t *activator)
{
if (!self)
{
return;
}
// on/off or berserk toggle?
if (self->spawnflags & AC_SF_BERSERK_TOGGLE)
{
@ -773,6 +839,11 @@ void monster_autocannon_use(edict_t *self, edict_t *other, edict_t *activator)
void monster_autocannon_usestub(edict_t *self)
{
if (!self)
{
return;
}
// stub
monster_autocannon_act(self);
}
@ -782,6 +853,11 @@ void SP_monster_autocannon(edict_t *self)
edict_t *base, *turret;
vec3_t offset;
if (!self)
{
return;
}
if (deathmatch->value)
{
G_FreeEdict(self);
@ -898,6 +974,11 @@ void SP_monster_autocannon(edict_t *self)
void SP_monster_autocannon_floor(edict_t *self)
{
if (!self)
{
return;
}
if (self->style == 1)
{
gi.error("monster_autocannon_floor does not permit bullet style");

View file

@ -1,15 +1,12 @@
#include "../header/local.h"
#define Z_RADUISLISTSIZE 2000
void ai_run_melee(edict_t *self);
qboolean FindTarget (edict_t *self);
qboolean SV_StepDirection (edict_t *ent, float yaw, float dist);
void SV_NewChaseDir (edict_t *actor, vec3_t eOrigin, float dist);
/*
=============
zSchoolAllVisiable
@ -20,37 +17,40 @@ Creates a list of all entities in the raduis of Z_RADUISLISTSIZE
void zCreateRaduisList(edict_t *self)
{
edict_t *head, *list;
vec3_t vec;
vec3_t vec;
if (!self)
{
return;
}
if(self->zRaduisList)
{
// already created for this think, don't bother doing it again...
return;
}
{
// already created for this think, don't bother doing it again...
return;
}
head = NULL;
list = self;
head = NULL;
list = self;
while(1)
{
while(1)
{
head = findradius(head, self->s.origin, Z_RADUISLISTSIZE);
if(head == NULL)
break;
if(head != self)
{
list->zRaduisList = head;
VectorSubtract(self->s.origin, head->s.origin, vec);
head->zDistance = VectorLength(vec);
list = head;
}
}
if(head != self)
{
list->zRaduisList = head;
VectorSubtract(self->s.origin, head->s.origin, vec);
head->zDistance = VectorLength(vec);
list = head;
}
}
list->zRaduisList = NULL;
list->zRaduisList = NULL;
};
/*
=============
zSchoolAllVisiable
@ -60,35 +60,37 @@ Create list of monsters of the same schooling type that are ahead of you.
*/
int zSchoolAllVisiable(edict_t *self)
{
int max;
edict_t *head, *list;
int max;
edict_t *head, *list;
max = 0;
if (!self)
{
return 0;
}
zCreateRaduisList(self);
max = 0;
zCreateRaduisList(self);
head = self->zRaduisList;
list = self;
list = self;
while (head)
{
if(strcmp(head->classname, self->classname) == 0 && (self->monsterinfo.aiflags & AI_SCHOOLING) && (head->health > 0) &&
(head->zDistance <= self->monsterinfo.zSchoolSightRadius) && (visible(self, head)) && (infront(self, head)))
if(strcmp(head->classname, self->classname) == 0 && (self->monsterinfo.aiflags & AI_SCHOOLING) && (head->health > 0) &&
(head->zDistance <= self->monsterinfo.zSchoolSightRadius) && (visible(self, head)) && (infront(self, head)))
{
list->zSchoolChain = head;
list = head;
max++;
list->zSchoolChain = head;
list = head;
max++;
}
head = head->zRaduisList;
}
list->zSchoolChain = NULL;
list->zSchoolChain = NULL;
return max;
return max;
}
/*
=============
zFindRoamYaw
@ -100,58 +102,61 @@ int zFindRoamYaw(edict_t *self, float distcheck)
{
vec3_t forward, end, angles;
trace_t tr;
float current = anglemod(self->s.angles[YAW]);
if(current <= self->ideal_yaw - 1 || current > self->ideal_yaw + 1)
{
if(fabs(current - self->ideal_yaw) <= 359.0)
{
return 0;
}
}
float current = anglemod(self->s.angles[YAW]);
if (!self)
{
return 0;
}
if(current <= self->ideal_yaw - 1 || current > self->ideal_yaw + 1)
{
if(fabs(current - self->ideal_yaw) <= 359.0)
{
return 0;
}
}
AngleVectors (self->s.angles, forward, NULL, NULL);
VectorMA (self->s.origin, distcheck, forward, end);
VectorMA (self->s.origin, distcheck, forward, end);
tr = gi.trace (self->s.origin, self->mins, self->maxs, end, self, MASK_SOLID);
if (tr.fraction < 1.0)
{
if(random() > 0.75)
{
self->ideal_yaw = vectoyaw(forward);
self->ideal_yaw = self->ideal_yaw + 180;
}
else
{
float dir = random() > 0.5 ? -45 : 45;
float maxtrys = 100;
VectorCopy(self->s.angles, angles);
{
if(random() > 0.75)
{
self->ideal_yaw = vectoyaw(forward);
self->ideal_yaw = self->ideal_yaw + 180;
}
else
{
float dir = random() > 0.5 ? -45 : 45;
float maxtrys = 100;
while(tr.fraction < 1.0 && maxtrys)
{
// blocked, change ideal yaw...
self->ideal_yaw = vectoyaw(forward);
self->ideal_yaw = self->ideal_yaw + (random() * dir);
VectorCopy(self->s.angles, angles);
angles[YAW] = anglemod (self->ideal_yaw);
AngleVectors (angles, forward, NULL, NULL);
VectorMA (self->s.origin, distcheck, forward, end);
while(tr.fraction < 1.0 && maxtrys)
{
// blocked, change ideal yaw...
self->ideal_yaw = vectoyaw(forward);
self->ideal_yaw = self->ideal_yaw + (random() * dir);
tr = gi.trace (self->s.origin, self->mins, self->maxs, end, self, MASK_SOLID);
maxtrys--;
}
}
angles[YAW] = anglemod (self->ideal_yaw);
AngleVectors (angles, forward, NULL, NULL);
VectorMA (self->s.origin, distcheck, forward, end);
return 1;
}
return 0;
tr = gi.trace (self->s.origin, self->mins, self->maxs, end, self, MASK_SOLID);
maxtrys--;
}
}
return 1;
}
return 0;
};
/*
=============
zSchoolMonsters
@ -161,148 +166,151 @@ Roaming schooling ai.
*/
int zSchoolMonsters(edict_t *self, float dist, int runStyle, float *currentSpeed)
{
int maxInsight;
int newRunStyle;
int maxInsight;
int newRunStyle;
maxInsight = zSchoolAllVisiable(self);
if (!self)
{
return 0;
}
// If you're not out in front
if(maxInsight > 0)
{
float totalSpeed;
float totalBearing;
float distanceToNearest, distanceToLeader, dist;
edict_t *nearestEntity = 0, *list;
vec3_t vec;
maxInsight = zSchoolAllVisiable(self);
totalSpeed = 0;
totalBearing = 0;
distanceToNearest = 10000;
distanceToLeader = 0;
list = self->zSchoolChain;
// If you're not out in front
if(maxInsight > 0)
{
float totalSpeed;
float totalBearing;
float distanceToNearest, distanceToLeader, dist;
edict_t *nearestEntity = 0, *list;
vec3_t vec;
while(list)
{
// Gather data on those you see
totalSpeed += list->speed;
totalBearing += anglemod(list->s.angles[YAW]);
totalSpeed = 0;
totalBearing = 0;
distanceToNearest = 10000;
distanceToLeader = 0;
list = self->zSchoolChain;
VectorSubtract(self->s.origin, list->s.origin, vec);
dist = VectorLength(vec);
while(list)
{
// Gather data on those you see
totalSpeed += list->speed;
totalBearing += anglemod(list->s.angles[YAW]);
if(dist < distanceToNearest)
{
distanceToNearest = dist;
nearestEntity = list;
}
VectorSubtract(self->s.origin, list->s.origin, vec);
dist = VectorLength(vec);
if(dist > distanceToLeader)
{
distanceToLeader = dist;
}
if(dist < distanceToNearest)
{
distanceToNearest = dist;
nearestEntity = list;
}
list = list->zSchoolChain;
if(dist > distanceToLeader)
{
distanceToLeader = dist;
}
list = list->zSchoolChain;
}
// Rule 1) Match average speed of those in the list
self->speed = (totalSpeed / maxInsight) * 1.5;
self->speed = (totalSpeed / maxInsight) * 1.5;
// Rule 2) Move towards the perceived center of gravity of the herd
self->ideal_yaw = totalBearing / maxInsight;
// check if hitting something
if(!zFindRoamYaw(self, 10))
{
// Rule 3) Maintain a minimum distance from those around you
if(distanceToNearest <= self->monsterinfo.zSchoolMinimumDistance)
{
self->ideal_yaw = nearestEntity->s.angles[YAW];
self->speed = nearestEntity->speed;
}
}
// check if hitting something
if(!zFindRoamYaw(self, 10))
{
// Rule 3) Maintain a minimum distance from those around you
if(distanceToNearest <= self->monsterinfo.zSchoolMinimumDistance)
{
self->ideal_yaw = nearestEntity->s.angles[YAW];
self->speed = nearestEntity->speed;
}
}
}
else
{
//You are in front, so slow down a bit
edict_t *head;
}
else
{
//You are in front, so slow down a bit
edict_t *head;
self->speed = (self->speed * self->monsterinfo.zSchoolDecayRate);
self->speed = (self->speed * self->monsterinfo.zSchoolDecayRate);
// check direction
zFindRoamYaw(self, 100);
// check direction
zFindRoamYaw(self, 100);
// change directions of the monsters following you...
zCreateRaduisList(self);
head = self->zRaduisList;
// change directions of the monsters following you...
zCreateRaduisList(self);
head = self->zRaduisList;
while (head)
{
if(strcmp(head->classname, self->classname) == 0 && (head->health > 0) &&
(head->zDistance <= self->monsterinfo.zSchoolSightRadius) && (visible(self, head)))
{
head->ideal_yaw = self->ideal_yaw + (-20 + (random() * 40));
}
head = head->zRaduisList;
}
}
while (head)
{
if(strcmp(head->classname, self->classname) == 0 && (head->health > 0) &&
(head->zDistance <= self->monsterinfo.zSchoolSightRadius) && (visible(self, head)))
if(self->speed > self->monsterinfo.zSchoolMaxSpeed)
{
self->speed = self->monsterinfo.zSchoolMaxSpeed;
}
{
head->ideal_yaw = self->ideal_yaw + (-20 + (random() * 40));
}
head = head->zRaduisList;
}
}
if(self->speed < self->monsterinfo.zSchoolMinSpeed)
{
if(self->speed > self->monsterinfo.zSchoolMaxSpeed)
{
self->speed = self->monsterinfo.zSchoolMaxSpeed;
}
if(self->speed < self->monsterinfo.zSchoolMinSpeed)
{
self->speed = self->monsterinfo.zSchoolMinSpeed;
}
}
if(self->speed <= self->monsterinfo.zSpeedStandMax)
{
newRunStyle = 0;
if(self->speed <= self->monsterinfo.zSpeedStandMax)
{
newRunStyle = 0;
if(newRunStyle != runStyle)
{
*currentSpeed = 1;
}
else
{
*currentSpeed = (self->speed - self->monsterinfo.zSchoolMinSpeed) + 1;
}
}
else if(self->speed <= self->monsterinfo.zSpeedWalkMax)
{
newRunStyle = 1;
if(newRunStyle != runStyle)
{
*currentSpeed = 1;
}
else
{
*currentSpeed = (self->speed - self->monsterinfo.zSchoolMinSpeed) + 1;
}
}
else if(self->speed <= self->monsterinfo.zSpeedWalkMax)
{
newRunStyle = 1;
if(newRunStyle != runStyle)
{
*currentSpeed = 1;
}
else
{
*currentSpeed = (self->speed - self->monsterinfo.zSpeedStandMax) + 1;
}
}
else
{
newRunStyle = 2;
if(newRunStyle != runStyle)
{
*currentSpeed = 1;
}
else
{
*currentSpeed = (self->speed - self->monsterinfo.zSpeedStandMax) + 1;
}
}
else
{
newRunStyle = 2;
if(newRunStyle != runStyle)
{
*currentSpeed = 1;
}
else
{
*currentSpeed = (self->speed - self->monsterinfo.zSpeedWalkMax) + 1;
}
}
if(newRunStyle != runStyle)
{
*currentSpeed = 1;
}
else
{
*currentSpeed = (self->speed - self->monsterinfo.zSpeedWalkMax) + 1;
}
}
return newRunStyle;
return newRunStyle;
}
/*
=============
ai_schoolStand
@ -313,43 +321,47 @@ Distance is for slight position adjustments needed by the animations
*/
void ai_schoolStand (edict_t *self, float dist)
{
float speed;
float speed;
if(!(self->monsterinfo.aiflags & AI_SCHOOLING))
{
ai_stand(self, dist);
return;
}
if (!self)
{
return;
}
// init school var's for this frame
self->zRaduisList = NULL;
if(!(self->monsterinfo.aiflags & AI_SCHOOLING))
{
ai_stand(self, dist);
return;
}
if(self->enemy || FindTarget(self))
{
ai_stand(self, dist);
return;
}
else
{
// run schooling routines
switch(zSchoolMonsters(self, dist, 0, &speed))
{
case 1:
self->monsterinfo.walk (self);
break;
// init school var's for this frame
self->zRaduisList = NULL;
case 2:
self->monsterinfo.run (self);
break;
}
}
if(self->enemy || FindTarget(self))
{
ai_stand(self, dist);
return;
}
else
{
// run schooling routines
switch(zSchoolMonsters(self, dist, 0, &speed))
{
case 1:
self->monsterinfo.walk (self);
break;
// do the normal stand stuff
if (dist)
M_walkmove (self, self->ideal_yaw, dist);
case 2:
self->monsterinfo.run (self);
break;
}
}
// do the normal stand stuff
if (dist)
M_walkmove (self, self->ideal_yaw, dist);
}
/*
=============
ai_schoolRun
@ -359,42 +371,46 @@ The monster has an enemy it is trying to kill
*/
void ai_schoolRun (edict_t *self, float dist)
{
float speed;
float speed;
if(!(self->monsterinfo.aiflags & AI_SCHOOLING))
{
ai_run(self, dist);
return;
}
if (!self)
{
return;
}
// init school var's for this frame
self->zRaduisList = NULL;
if(!(self->monsterinfo.aiflags & AI_SCHOOLING))
{
ai_run(self, dist);
return;
}
if(self->enemy || FindTarget(self))
{
ai_run(self, dist);
return;
}
else
{
// run schooling routines
switch(zSchoolMonsters(self, dist, 2, &speed))
{
case 0:
self->monsterinfo.stand (self);
break;
// init school var's for this frame
self->zRaduisList = NULL;
case 1:
self->monsterinfo.walk (self);
break;
}
}
if(self->enemy || FindTarget(self))
{
ai_run(self, dist);
return;
}
else
{
// run schooling routines
switch(zSchoolMonsters(self, dist, 2, &speed))
{
case 0:
self->monsterinfo.stand (self);
break;
// do the normal run stuff
SV_StepDirection (self, self->ideal_yaw, dist);
case 1:
self->monsterinfo.walk (self);
break;
}
}
// do the normal run stuff
SV_StepDirection (self, self->ideal_yaw, dist);
}
/*
=============
ai_schoolWalk
@ -404,41 +420,45 @@ The monster is walking it's beat
*/
void ai_schoolWalk (edict_t *self, float dist)
{
float speed;
float speed;
if(!(self->monsterinfo.aiflags & AI_SCHOOLING))
{
ai_walk(self, dist);
return;
}
if (!self)
{
return;
}
// init school var's for this frame
self->zRaduisList = NULL;
if(!(self->monsterinfo.aiflags & AI_SCHOOLING))
{
ai_walk(self, dist);
return;
}
if(self->enemy || FindTarget(self))
{
ai_walk(self, dist);
return;
}
else
{
// run schooling routines
switch(zSchoolMonsters(self, dist, 1, &speed))
{
case 0:
self->monsterinfo.stand (self);
break;
// init school var's for this frame
self->zRaduisList = NULL;
case 2:
self->monsterinfo.run (self);
break;
}
}
if(self->enemy || FindTarget(self))
{
ai_walk(self, dist);
return;
}
else
{
// run schooling routines
switch(zSchoolMonsters(self, dist, 1, &speed))
{
case 0:
self->monsterinfo.stand (self);
break;
// do the normal walk stuff
SV_StepDirection (self, self->ideal_yaw, dist);
case 2:
self->monsterinfo.run (self);
break;
}
}
// do the normal walk stuff
SV_StepDirection (self, self->ideal_yaw, dist);
}
/*
=============
@ -450,6 +470,10 @@ Use this call with a distnace of 0 to replace ai_face
*/
void ai_schoolCharge (edict_t *self, float dist)
{
ai_charge(self, dist);
}
if (!self)
{
return;
}
ai_charge(self, dist);
}

File diff suppressed because it is too large Load diff

View file

@ -6,7 +6,6 @@
void zCam_SetLocalCopy(struct edict_s *player, char *s);
void zCam_TrackEntity(struct edict_s *player, struct edict_s *track, qboolean playerVisiable, qboolean playerOffset)
{
if(player->client == NULL)
@ -51,7 +50,6 @@ void zCam_TrackEntity(struct edict_s *player, struct edict_s *track, qboolean pl
}
}
void zCam_Stop(struct edict_s *player)
{
if(player->client == NULL)
@ -78,7 +76,6 @@ void zCam_Stop(struct edict_s *player)
}
}
char *getSkinModel(char *s, char *buffer)
{
char *cp;

View file

@ -7,7 +7,6 @@
Monster frame move lists.
**************************************************************************/
/*=========================================================================
Hound.
=========================================================================*/
@ -30,7 +29,6 @@ mmove_t *frame_moves_hound[] = {
&hound_move_death,
NULL};
/*=========================================================================
Sentien.
=========================================================================*/

View file

@ -1,6 +1,5 @@
#include "../header/local.h"
extern qboolean is_quad;
extern byte is_silenced;
@ -24,7 +23,6 @@ void zCam_Stop(struct edict_s *player);
void fire_empnuke(edict_t *ent, vec3_t center, int radius);
/*
misc_securitycamera
@ -32,6 +30,11 @@ void fire_empnuke(edict_t *ent, vec3_t center, int radius);
*/
void use_securitycamera (edict_t *self, edict_t *other, edict_t *activator)
{
if (!self)
{
return;
}
self->active = !self->active;
}
@ -39,6 +42,11 @@ void use_securitycamera (edict_t *self, edict_t *other, edict_t *activator)
#define CAMERA_FRAME_LAST 59
void securitycamera_think(edict_t *self)
{
if (!self)
{
return;
}
if (self->active)
{
self->s.frame++;
@ -62,6 +70,11 @@ void securitycamera_think(edict_t *self)
void camera_pain(edict_t *self, edict_t *other, float kick, int damage)
{
if (!self)
{
return;
}
self->timeout = level.time + FRAMETIME * 2;
}
@ -69,6 +82,11 @@ void SP_misc_securitycamera(edict_t *self)
{
vec3_t offset, forward, up;
if (!self)
{
return;
}
// no message? error
if (!self->message)
{
@ -129,6 +147,12 @@ char *camera_statusbar =
void updateVisorHud(edict_t *ent)
{
static char buf[1024];
if (!ent)
{
return;
}
gi.WriteByte (svc_layout);
sprintf(buf, camera_statusbar, ent->client->zCameraTrack->message);
gi.WriteString(buf);
@ -136,11 +160,21 @@ void updateVisorHud(edict_t *ent)
void startVisorStatic(edict_t *ent)
{
if (!ent)
{
return;
}
ent->client->zCameraStaticFramenum = level.time + FRAMETIME * 2;
}
void startVisor(edict_t *ent, edict_t *e)
{
if (!ent || !e)
{
return;
}
// don't do anything if we're already at the destination camera
if (e == ent->client->zCameraTrack)
return;
@ -166,6 +200,11 @@ void startVisor(edict_t *ent, edict_t *e)
void stopCamera(edict_t *self)
{
if (!self)
{
return;
}
zCam_Stop(self);
self->client->showscores = false;
gi.sound(self, CHAN_AUTO, gi.soundindex("items/visor/deact.wav"), 1, ATTN_NORM, 0);
@ -174,7 +213,12 @@ void stopCamera(edict_t *self)
edict_t *findNextCamera(edict_t *old)
{
edict_t *e = NULL;
if (!old)
{
return NULL;
}
// first of all, are there *any* cameras?
e = G_Find(NULL, FOFS(classname), "misc_securitycamera");
if (e == NULL)
@ -201,6 +245,11 @@ edict_t *findNextCamera(edict_t *old)
void Use_Visor (edict_t *ent, gitem_t *item)
{
if (!ent || !item)
{
return;
}
if (ent->client->zCameraTrack == NULL)
{
edict_t *e = findNextCamera(NULL);
@ -228,38 +277,44 @@ void Use_Visor (edict_t *ent, gitem_t *item)
}
}
/*
=================
EMP Nuke
=================
*/
void weapon_EMPNuke_fire (edict_t *ent)
{
fire_empnuke(ent, ent->s.origin, 1024);
if (!ent)
{
return;
}
fire_empnuke(ent, ent->s.origin, 1024);
ent->client->pers.inventory[ent->client->ammo_index]--;
if(ent->client->pers.inventory[ent->client->ammo_index])
{
ent->client->weaponstate = WEAPON_ACTIVATING;
ent->client->ps.gunframe = 0;
}
else
{
NoAmmoWeaponChange (ent);
ChangeWeapon(ent);
}
if(ent->client->pers.inventory[ent->client->ammo_index])
{
ent->client->weaponstate = WEAPON_ACTIVATING;
ent->client->ps.gunframe = 0;
}
else
{
NoAmmoWeaponChange (ent);
ChangeWeapon(ent);
}
}
void Weapon_EMPNuke (edict_t *ent)
{
static int pause_frames[] = {25, 34, 43, 0};
static int fire_frames[] = {16, 0};
if (!ent)
{
return;
}
if (deathmatch->value)
{
if (ent->client->ps.gunframe == 0)
@ -279,39 +334,51 @@ void Weapon_EMPNuke (edict_t *ent)
Weapon_Generic (ent, 9, 16, 43, 47, pause_frames, fire_frames, weapon_EMPNuke_fire);
}
void empnukeFinish(edict_t *ent)
void empnukeFinish(edict_t *ent)
{
G_FreeEdict(ent);
if (!ent)
{
return;
}
G_FreeEdict(ent);
}
void empBlastAnim(edict_t *ent)
void empBlastAnim(edict_t *ent)
{
ent->s.frame++;
ent->s.skinnum++;
if (!ent)
{
return;
}
if(ent->s.frame > 5)
{
ent->svflags |= SVF_NOCLIENT;
ent->s.modelindex = 0;
ent->s.frame = 0;
ent->s.skinnum = 0;
ent->s.frame++;
ent->s.skinnum++;
ent->think = empnukeFinish;
ent->nextthink = level.time + 30;
}
else
{
ent->nextthink = level.time + FRAMETIME;
}
if(ent->s.frame > 5)
{
ent->svflags |= SVF_NOCLIENT;
ent->s.modelindex = 0;
ent->s.frame = 0;
ent->s.skinnum = 0;
ent->think = empnukeFinish;
ent->nextthink = level.time + 30;
}
else
{
ent->nextthink = level.time + FRAMETIME;
}
}
void fire_empnuke(edict_t *ent, vec3_t center, int radius)
void fire_empnuke(edict_t *ent, vec3_t center, int radius)
{
edict_t *empnuke;
if (!ent)
{
return;
}
gi.sound(ent, CHAN_VOICE, gi.soundindex("items/empnuke/emp_trg.wav"), 1, ATTN_NORM, 0);
empnuke = G_Spawn();
@ -328,73 +395,89 @@ void fire_empnuke(edict_t *ent, vec3_t center, int radius)
gi.linkentity (empnuke);
}
qboolean EMPNukeCheck(edict_t *ent, vec3_t pos)
qboolean EMPNukeCheck(edict_t *ent, vec3_t pos)
{
edict_t *check = NULL;
if (!ent)
{
return false;
}
while ((check = G_Find (check, FOFS(classname), "EMPNukeCenter")) != NULL)
{
vec3_t v;
vec3_t v;
if(check->owner != ent)
{
VectorSubtract (check->s.origin, pos, v);
if(VectorLength(v) <= check->dmg)
{
return true;
return true;
}
}
}
}
return false;
return false;
}
/*
=================
Plasma Shield
=================
*/
void PlasmaShield_die (edict_t *self)
{
if (!self)
{
return;
}
if (deathmatch->value)
{
gi.sound(self, CHAN_VOICE, gi.soundindex("items/plasmashield/psdie.wav"), 1, ATTN_NORM, 0);
gi.sound(self, CHAN_VOICE, gi.soundindex("items/plasmashield/psdie.wav"), 1, ATTN_NORM, 0);
}
G_FreeEdict(self);
G_FreeEdict(self);
}
void PlasmaShield_killed (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
{
PlasmaShield_die(self);
}
if (!self)
{
return;
}
PlasmaShield_die(self);
}
void Use_PlasmaShield (edict_t *ent, gitem_t *item)
{
int ammoIdx = ITEM_INDEX(item);
int ammoIdx = ITEM_INDEX(item);
edict_t *PlasmaShield;
vec3_t forward, right, up, frontbottomleft, backtopright;
vec3_t forward, right, up, frontbottomleft, backtopright;
if(!ent->client->pers.inventory[ammoIdx])
{
return;
}
if (!ent || !item)
{
return;
}
if(EMPNukeCheck(ent, ent->s.origin))
{
if(!ent->client->pers.inventory[ammoIdx])
{
return;
}
if(EMPNukeCheck(ent, ent->s.origin))
{
gi.sound (ent, CHAN_AUTO, gi.soundindex("items/empnuke/emp_missfire.wav"), 1, ATTN_NORM, 0);
return;
}
return;
}
if (! ( (int)dmflags->value & DF_INFINITE_AMMO ) )
ent->client->pers.inventory[ammoIdx]--;
if (deathmatch->value)
{
gi.sound(ent, CHAN_VOICE, gi.soundindex("items/plasmashield/psfire.wav"), 1, ATTN_NORM, 0);
gi.sound(ent, CHAN_VOICE, gi.soundindex("items/plasmashield/psfire.wav"), 1, ATTN_NORM, 0);
}
PlasmaShield = G_Spawn();
@ -402,33 +485,33 @@ void Use_PlasmaShield (edict_t *ent, gitem_t *item)
PlasmaShield->movetype = MOVETYPE_PUSH;
PlasmaShield->solid = SOLID_BBOX;
PlasmaShield->s.modelindex = gi.modelindex("sprites/plasmashield.sp2");
PlasmaShield->s.effects |= EF_POWERSCREEN;
PlasmaShield->s.sound = gi.soundindex ("items/plasmashield/psactive.wav");
PlasmaShield->s.effects |= EF_POWERSCREEN;
PlasmaShield->s.sound = gi.soundindex ("items/plasmashield/psactive.wav");
AngleVectors (ent->client->v_angle, forward, right, up);
vectoangles (forward, PlasmaShield->s.angles);
VectorMA (ent->s.origin, 50, forward, PlasmaShield->s.origin);
VectorScale(forward, 10, frontbottomleft);
VectorMA(frontbottomleft, -30, right, frontbottomleft);
VectorMA(frontbottomleft, -30, up, frontbottomleft);
VectorScale(forward, 10, frontbottomleft);
VectorMA(frontbottomleft, -30, right, frontbottomleft);
VectorMA(frontbottomleft, -30, up, frontbottomleft);
VectorScale(forward, 5, backtopright);
VectorMA(backtopright, 30, right, backtopright);
VectorMA(backtopright, 50, up, backtopright);
VectorScale(forward, 5, backtopright);
VectorMA(backtopright, 30, right, backtopright);
VectorMA(backtopright, 50, up, backtopright);
ClearBounds (PlasmaShield->mins, PlasmaShield->maxs);
ClearBounds (PlasmaShield->mins, PlasmaShield->maxs);
AddPointToBounds (frontbottomleft, PlasmaShield->mins, PlasmaShield->maxs);
AddPointToBounds (backtopright, PlasmaShield->mins, PlasmaShield->maxs);
AddPointToBounds (frontbottomleft, PlasmaShield->mins, PlasmaShield->maxs);
AddPointToBounds (backtopright, PlasmaShield->mins, PlasmaShield->maxs);
PlasmaShield->health = PlasmaShield->max_health = 4000;
PlasmaShield->health = PlasmaShield->max_health = 4000;
PlasmaShield->die = PlasmaShield_killed;
PlasmaShield->takedamage = DAMAGE_YES;
PlasmaShield->think = PlasmaShield_die;
PlasmaShield->nextthink = level.time + 10;
PlasmaShield->think = PlasmaShield_die;
PlasmaShield->nextthink = level.time + 10;
gi.linkentity (PlasmaShield);
}
@ -440,9 +523,14 @@ void barrel_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *s
void setupCrate(edict_t *self)
{
if (!self)
{
return;
}
self->solid = SOLID_BBOX;
self->movetype = MOVETYPE_FALLFLOAT;
if (!self->mass)
self->mass = 400;
@ -455,6 +543,11 @@ void setupCrate(edict_t *self)
void SP_misc_crate(edict_t *self)
{
if (!self)
{
return;
}
// setup specific to this size
self->s.modelindex = gi.modelindex("models/objects/crate/crate64.md2");
VectorSet (self->mins, -32, -32, 0);
@ -466,6 +559,11 @@ void SP_misc_crate(edict_t *self)
void SP_misc_crate_medium(edict_t *self)
{
if (!self)
{
return;
}
// setup specific to this size
self->s.modelindex = gi.modelindex("models/objects/crate/crate48.md2");
VectorSet (self->mins, -24, -24, 0);
@ -477,6 +575,11 @@ void SP_misc_crate_medium(edict_t *self)
void SP_misc_crate_small(edict_t *self)
{
if (!self)
{
return;
}
// setup specific to this size
self->s.modelindex = gi.modelindex("models/objects/crate/crate32.md2");
VectorSet (self->mins, -16, -16, 0);
@ -490,6 +593,12 @@ qboolean thruBarrier(edict_t *targ, edict_t *inflictor)
{
trace_t tr;
edict_t *e = inflictor;
if (!targ || !inflictor)
{
return false;
}
while(e)
{
tr = gi.trace(e->s.origin, NULL, NULL, targ->s.origin, e, MASK_SHOT);
@ -512,6 +621,11 @@ qboolean thruBarrier(edict_t *targ, edict_t *inflictor)
void barrier_think(edict_t *self)
{
if (!self)
{
return;
}
if (self->timeout > level.time)
{
self->svflags &= ~SVF_NOCLIENT;
@ -526,6 +640,11 @@ void barrier_think(edict_t *self)
void barrier_pain(edict_t *self, edict_t *other, float kick, int damage)
{
if (!self)
{
return;
}
self->timeout = level.time + FRAMETIME * 2;
if (self->damage_debounce_time < level.time)
{
@ -533,8 +652,14 @@ void barrier_pain(edict_t *self, edict_t *other, float kick, int damage)
self->damage_debounce_time = level.time + FRAMETIME * 2;
}
}
void barrier_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
{
if (!self || !other)
{
return;
}
if (other == world)
return;
@ -549,6 +674,11 @@ void barrier_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *
void SP_func_barrier(edict_t *self)
{
if (!self)
{
return;
}
self->solid = SOLID_BBOX;
self->movetype = MOVETYPE_NONE;
self->s.modelindex = gi.modelindex("models/objects/wall/tris.md2");
@ -567,6 +697,11 @@ void SP_func_barrier(edict_t *self)
void SP_misc_seat(edict_t *self)
{
if (!self)
{
return;
}
self->s.modelindex = gi.modelindex("models/objects/seat/tris.md2");
VectorSet(self->mins, -16, -16, 0);
VectorSet(self->maxs, 16, 16, 40);

View file

@ -12,7 +12,6 @@ void Weapon_Generic (edict_t *ent,
void (*fire)(edict_t *ent));
void P_ProjectSource (gclient_t *client, vec3_t point, vec3_t distance, vec3_t forward, vec3_t right, vec3_t result);
static char testItem_className[256];
static char testItem_gModel[256];
static char testItem_icon[256];
@ -21,87 +20,93 @@ static char testItem_aminationFramesStr[4096];
static int testItem_aminationFrames[100];
static vec3_t testItem_Size[2];
gitem_t *testItem;
edict_t *testItemDroped = NULL;
int animUpto;
qboolean testitemOriginMove = false;
float animSpeed = 1.0;
float lineSize = 100.0f;
void Weapon_LineDraw_Fire (edict_t *ent);
void Weapon_LineDraw_Think (edict_t *ent)
{
Weapon_LineDraw_Fire (ent->owner);
if (!ent)
{
return;
}
Weapon_LineDraw_Fire (ent->owner);
ent->owner->client->ps.gunframe--;
}
void Weapon_LineDraw_Fire (edict_t *ent)
{
edict_t *beam;
edict_t *beam;
vec3_t start;
vec3_t forward, right;
vec3_t offset;
if (!ent)
{
return;
}
AngleVectors (ent->client->v_angle, forward, right, NULL);
VectorSet(offset, 0, 7, ent->viewheight - 8);
P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start);
if(!ent->client->lineDraw)
{
beam = ent->client->lineDraw = G_Spawn();
if(!ent->client->lineDraw)
{
beam = ent->client->lineDraw = G_Spawn();
beam->classname = "DrawLine";
beam->classname = "DrawLine";
beam->flags |= FL_DONTSETOLDORIGIN;
beam->flags |= FL_DONTSETOLDORIGIN;
beam->owner = ent;
beam->owner = ent;
beam->movetype = MOVETYPE_NONE;
beam->solid = SOLID_NOT;
beam->s.renderfx |= RF_BEAM|RF_TRANSLUCENT;
beam->s.modelindex = 1; // must be non-zero
beam->movetype = MOVETYPE_NONE;
beam->solid = SOLID_NOT;
beam->s.renderfx |= RF_BEAM|RF_TRANSLUCENT;
beam->s.modelindex = 1; // must be non-zero
VectorSet (beam->mins, -8, -8, -8);
VectorSet (beam->maxs, 8, 8, 8);
VectorSet (beam->mins, -8, -8, -8);
VectorSet (beam->maxs, 8, 8, 8);
beam->s.frame = 2;
beam->s.skinnum = 0xf3f3f1f1;
beam->s.frame = 2;
beam->s.skinnum = 0xf3f3f1f1;
beam->think = Weapon_LineDraw_Think;
beam->nextthink = level.time + (FRAMETIME * 2);
}
else
{
beam = ent->client->lineDraw;
}
beam->think = Weapon_LineDraw_Think;
beam->nextthink = level.time + (FRAMETIME * 2);
}
else
{
beam = ent->client->lineDraw;
}
VectorCopy (start, beam->s.origin);
VectorCopy (start, beam->s.origin);
VectorMA (start, lineSize, forward, beam->s.old_origin);
gi.linkentity (beam);
gi.linkentity (beam);
ent->client->ps.gunframe++;
}
void Weapon_LineDraw (edict_t *ent)
{
if (!ent)
{
return;
}
static int pause_frames[] = {19, 32, 0};
static int fire_frames[] = {5, 0};
Weapon_Generic (ent, 4, 8, 52, 55, pause_frames, fire_frames, Weapon_LineDraw_Fire);
}
static char testWeap_className[256];
static char testWeap_gModel[256];
static char testWeap_vModel[256];
@ -117,10 +122,8 @@ static int testWeap_FRAME_DEACTIVATE_LAST;
static int testWeap_pause_frames[20];
static int testWeap_fire_frames[20];
gitem_t *testWeapon;
void convertToNumbers(char *frames, int *arrayFrames)
{
int num = 0;
@ -157,9 +160,6 @@ void convertToNumbers(char *frames, int *arrayFrames)
arrayFrames[num] = 0;
}
void convertToVector(char *vecStr, vec3_t *size)
{
int num = 0;
@ -199,8 +199,6 @@ void convertToVector(char *vecStr, vec3_t *size)
}
}
void InitTestWeapon(void)
{
FILE *wCfgFile;
@ -294,121 +292,135 @@ void InitTestWeapon(void)
testWeapon->pickup_name = testWeap_name;
}
void Weapon_Test_Fire (edict_t *ent)
{
if (!ent)
{
return;
}
gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/blastf1a.wav"), 1, ATTN_NORM, 0);
ent->client->ps.gunframe++;
}
void Weapon_Test (edict_t *ent)
{
Weapon_Generic (ent, testWeap_FRAME_ACTIVATE_LAST,
testWeap_FRAME_FIRE_LAST, testWeap_FRAME_IDLE_LAST,
testWeap_FRAME_DEACTIVATE_LAST,
testWeap_pause_frames, testWeap_fire_frames, Weapon_Test_Fire);
}
if (!ent)
{
return;
}
Weapon_Generic (ent, testWeap_FRAME_ACTIVATE_LAST,
testWeap_FRAME_FIRE_LAST, testWeap_FRAME_IDLE_LAST,
testWeap_FRAME_DEACTIVATE_LAST,
testWeap_pause_frames, testWeap_fire_frames, Weapon_Test_Fire);
}
void testitem_think (edict_t *ent)
{
if(testItem_aminationFrames[animUpto])
{
ent->s.frame++;
if(ent->s.frame >= testItem_aminationFrames[animUpto])
{
if(animUpto)
{
ent->s.frame = testItem_aminationFrames[animUpto - 1];
}
else
{
ent->s.frame = 0;
}
}
}
if (!ent)
{
return;
}
if(testItem_aminationFrames[animUpto])
{
ent->s.frame++;
if(ent->s.frame >= testItem_aminationFrames[animUpto])
{
if(animUpto)
{
ent->s.frame = testItem_aminationFrames[animUpto - 1];
}
else
{
ent->s.frame = 0;
}
}
}
ent->nextthink = level.time + (FRAMETIME * animSpeed);
}
void Cmd_TestItem (edict_t *ent)
{
char *cmd;
char *cmd;
cmd = gi.argv(1);
if (!ent)
{
return;
}
cmd = gi.argv(1);
if (Q_stricmp (cmd, "animnext") == 0)
{
if(testItem_aminationFrames[animUpto] && testItem_aminationFrames[animUpto + 1])
{
animUpto++;
{
if(testItem_aminationFrames[animUpto] && testItem_aminationFrames[animUpto + 1])
{
animUpto++;
gi.cprintf (ent, PRINT_HIGH, "Animation %d set\n", animUpto);
}
}
gi.cprintf (ent, PRINT_HIGH, "Animation %d set\n", animUpto);
}
}
else if (Q_stricmp (cmd, "animprev") == 0)
{
if(animUpto && testItem_aminationFrames[animUpto - 1])
{
animUpto--;
{
if(animUpto && testItem_aminationFrames[animUpto - 1])
{
animUpto--;
gi.cprintf (ent, PRINT_HIGH, "Animation %d set\n", animUpto);
}
}
gi.cprintf (ent, PRINT_HIGH, "Animation %d set\n", animUpto);
}
}
else if (Q_stricmp (cmd, "animspeed") == 0)
{
float as = atof(gi.argv(2));
{
float as = atof(gi.argv(2));
if(as < 1.0)
{
gi.cprintf (ent, PRINT_HIGH, "AnimSpeed must be greater than or equal to 1\n");
return;
}
if(as < 1.0)
{
gi.cprintf (ent, PRINT_HIGH, "AnimSpeed must be greater than or equal to 1\n");
return;
}
animSpeed = as;
}
animSpeed = as;
}
else if (Q_stricmp (cmd, "movestart") == 0)
{
if(testItemDroped)
{
testitemOriginMove = true;
gi.cprintf (ent, PRINT_HIGH, "testitem move start\n");
}
}
{
if(testItemDroped)
{
testitemOriginMove = true;
gi.cprintf (ent, PRINT_HIGH, "testitem move start\n");
}
}
else if (Q_stricmp (cmd, "moveend") == 0)
{
if(testItemDroped)
{
testitemOriginMove = false;
gi.cprintf (ent, PRINT_HIGH, "testitem move end\n");
}
}
{
if(testItemDroped)
{
testitemOriginMove = false;
gi.cprintf (ent, PRINT_HIGH, "testitem move end\n");
}
}
else if (Q_stricmp (cmd, "rotatestart") == 0)
{
if(testItemDroped)
{
testItemDroped->s.effects = EF_ROTATE;
gi.cprintf (ent, PRINT_HIGH, "Rotate On\n");
}
}
{
if(testItemDroped)
{
testItemDroped->s.effects = EF_ROTATE;
gi.cprintf (ent, PRINT_HIGH, "Rotate On\n");
}
}
else if (Q_stricmp (cmd, "rotateend") == 0)
{
if(testItemDroped)
{
testItemDroped->s.effects = 0;
gi.cprintf (ent, PRINT_HIGH, "Rotate Off\n");
}
}
else
{
gi.cprintf (ent, PRINT_HIGH, "Bad testitem command\n");
}
{
if(testItemDroped)
{
testItemDroped->s.effects = 0;
gi.cprintf (ent, PRINT_HIGH, "Rotate Off\n");
}
}
else
{
gi.cprintf (ent, PRINT_HIGH, "Bad testitem command\n");
}
}
void InitTestItem(void)
{
FILE *wCfgFile;
@ -493,11 +505,13 @@ void InitTestItem(void)
testItem->pickup_name = testItem_name;
}
qboolean Pickup_TestItem (edict_t *ent, edict_t *other)
{
if (!ent)
{
return false;
}
other->client->pers.inventory[ITEM_INDEX(ent->item)]++;
return true;
@ -510,19 +524,24 @@ void Drop_TestItem (edict_t *ent, gitem_t *item)
vec3_t forward, right;
vec3_t offset;
testitemOriginMove = false;
if (!ent || !item)
{
return;
}
testItemDroped = G_Spawn();
testitemOriginMove = false;
testItemDroped = G_Spawn();
testItemDroped->classname = item->classname;
testItemDroped->item = item;
testItemDroped->spawnflags = DROPPED_ITEM;
testItemDroped->s.effects = item->world_model_flags;
testItemDroped->s.renderfx = RF_GLOW;
VectorCopy(testItem_Size[0], testItemDroped->mins);
VectorCopy(testItem_Size[1], testItemDroped->maxs);
VectorCopy(testItem_Size[0], testItemDroped->mins);
VectorCopy(testItem_Size[1], testItemDroped->maxs);
gi.setmodel (testItemDroped, testItemDroped->item->world_model);
testItemDroped->s.skinnum = 0;
testItemDroped->s.skinnum = 0;
testItemDroped->solid = SOLID_TRIGGER;
testItemDroped->movetype = MOVETYPE_TOSS;
testItemDroped->touch = drop_temp_touch;
@ -536,7 +555,7 @@ void Drop_TestItem (edict_t *ent, gitem_t *item)
VectorSet(offset, 24, 0, -16);
G_ProjectSource (ent->s.origin, offset, forward, right, testItemDroped->s.origin);
trace = gi.trace (ent->s.origin, testItemDroped->mins, testItemDroped->maxs,
testItemDroped->s.origin, ent, CONTENTS_SOLID);
testItemDroped->s.origin, ent, CONTENTS_SOLID);
VectorCopy (trace.endpos, testItemDroped->s.origin);
}
else

View file

@ -39,6 +39,11 @@ qboolean SpawnZ(gitem_t *item, edict_t *spot)
int ang = 0;
int startAng = 0;
if (!item || !spot)
{
return false;
}
ent = G_Spawn();
ent->classname = item->classname;

View file

@ -10,6 +10,11 @@ Echo any sounds that are played within "dmg_radius" radius.
void SP_sound_echo (edict_t *self)
{
if (!self)
{
return;
}
G_FreeEdict(self);
}
@ -19,6 +24,11 @@ void SP_sound_echo (edict_t *self)
void SP_load_mirrorlevel (edict_t *self)
{
if (!self)
{
return;
}
G_FreeEdict(self);
}
@ -95,7 +105,6 @@ void printSoundNum()
}
#endif
/********************************************
trigger_laser
*/
@ -110,6 +119,7 @@ Laser-type trigger
#define TRIGGER_MULTIPLE 1
void trigger_laser_on (edict_t *self);
void trigger_laser_think (edict_t *self)
{
vec3_t start;
@ -117,6 +127,11 @@ void trigger_laser_think (edict_t *self)
trace_t tr;
int count = 8;
if (!self)
{
return;
}
self->nextthink = level.time + FRAMETIME;
VectorCopy (self->s.origin, start);
@ -165,6 +180,11 @@ void trigger_laser_think (edict_t *self)
void trigger_laser_on (edict_t *self)
{
if (!self)
{
return;
}
self->svflags &= ~SVF_NOCLIENT;
self->think = trigger_laser_think;
trigger_laser_think(self);
@ -172,6 +192,11 @@ void trigger_laser_on (edict_t *self)
void SP_trigger_laser(edict_t *self)
{
if (!self)
{
return;
}
// if no target
if (!self->target)
{
@ -202,31 +227,45 @@ void SP_trigger_laser(edict_t *self)
/*QUAKED misc_commdish (0 .5 .8) (-16 -16 0) (16 16 40)
*/
void Anim_CommDish(edict_t *self)
{
if (!self)
{
return;
}
self->s.frame++;
if(self->s.frame >= 98)
{
self->s.frame = 98;
}
else
{
self->nextthink = level.time + FRAMETIME;
}
if(self->s.frame >= 98)
{
self->s.frame = 98;
}
else
{
self->nextthink = level.time + FRAMETIME;
}
}
void Use_CommDish (edict_t *ent, edict_t *other, edict_t *activator)
{
ent->nextthink = level.time + FRAMETIME;
if (!ent)
{
return;
}
ent->nextthink = level.time + FRAMETIME;
ent->think = Anim_CommDish;
ent->use = NULL;
ent->use = NULL;
gi.sound (ent, CHAN_AUTO, gi.soundindex ("misc/commdish.wav"), 1, ATTN_NORM, 0);
}
void SP_misc_commdish (edict_t *self)
{
if (!self)
{
return;
}
if (deathmatch->value)
{ // auto-remove for deathmatch
G_FreeEdict (self);

View file

@ -19,7 +19,6 @@ void check_dodge (edict_t *self, vec3_t start, vec3_t dir, int speed);
void Grenade_Explode(edict_t *ent);
void P_ProjectSource (gclient_t *client, vec3_t point, vec3_t distance, vec3_t forward, vec3_t right, vec3_t result);
void fire_sconnan (edict_t *self);
void fire_sconnanEffects (edict_t *self);
@ -48,6 +47,12 @@ void angleToward(edict_t *self, vec3_t point, float speed)
float vel = 0.0;
vec3_t delta;
vec3_t destAngles;
if (!self)
{
return;
}
VectorSubtract(point, self->s.origin, delta);
vectoangles(delta, destAngles);
self->ideal_yaw = destAngles[YAW];
@ -84,6 +89,11 @@ void angleToward(edict_t *self, vec3_t point, float speed)
void shrapnel_touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
{
if (!ent || !other)
{
return;
}
// do damage if we can
if (!other->takedamage)
return;
@ -101,6 +111,11 @@ void TripBomb_Explode (edict_t *ent)
vec3_t origin;
int i = 0;
if (!ent)
{
return;
}
T_RadiusDamage(ent, ent->owner ? ent->owner : ent, ent->dmg, ent->enemy, ent->dmg_radius, MOD_TRIPBOMB);
VectorMA (ent->s.origin, -0.02, ent->velocity, origin);
@ -157,6 +172,11 @@ void tripbomb_laser_think (edict_t *self)
trace_t tr;
int count = 8;
if (!self)
{
return;
}
self->nextthink = level.time + FRAMETIME;
if (level.time > self->timeout)
@ -213,6 +233,11 @@ void tripbomb_laser_think (edict_t *self)
void tripbomb_laser_on (edict_t *self)
{
if (!self)
{
return;
}
self->svflags &= ~SVF_NOCLIENT;
self->think = tripbomb_laser_think;
@ -223,6 +248,11 @@ void tripbomb_laser_on (edict_t *self)
void create_tripbomb_laser(edict_t *bomb)
{
if (!bomb)
{
return;
}
// create the laser
edict_t *laser = G_Spawn();
bomb->chain = laser;
@ -249,6 +279,11 @@ void create_tripbomb_laser(edict_t *bomb)
void use_tripbomb(edict_t *self, edict_t *other, edict_t *activator)
{
if (!self)
{
return;
}
if (self->chain)
{
// we already have a laser, remove it
@ -262,6 +297,11 @@ void use_tripbomb(edict_t *self, edict_t *other, edict_t *activator)
void turnOffGlow(edict_t *self)
{
if (!self)
{
return;
}
self->s.effects &= ~EF_COLOR_SHELL;
self->s.renderfx &= ~RF_SHELL_GREEN;
self->think = NULL;
@ -270,6 +310,11 @@ void turnOffGlow(edict_t *self)
void tripbomb_pain(edict_t *self, edict_t *other, float kick, int damage)
{
if (!self)
{
return;
}
// turn on the glow
self->damage_debounce_time = level.time + 0.2;
@ -285,6 +330,11 @@ void tripbomb_pain(edict_t *self, edict_t *other, float kick, int damage)
void tripbomb_think(edict_t *self)
{
if (!self)
{
return;
}
if (self->chain == NULL)
{
// check whether we need to create the laser
@ -311,6 +361,11 @@ void tripbomb_think(edict_t *self)
void setupBomb(edict_t *bomb, char *classname, float damage, float damage_radius)
{
if (!bomb)
{
return;
}
bomb->classname = classname;
VectorSet(bomb->mins, -8, -8, -8);
VectorSet(bomb->maxs, 8, 8, 8);
@ -364,6 +419,11 @@ qboolean fire_lasertripbomb(edict_t *self, vec3_t start, vec3_t dir, float timer
vec3_t _dir;
edict_t *bomb = NULL;
if (!self)
{
return false;
}
VectorScale(dir, 64, _dir);
VectorAdd(start, _dir, endPos);
@ -403,6 +463,11 @@ qboolean fire_lasertripbomb(edict_t *self, vec3_t start, vec3_t dir, float timer
void weapon_lasertripbomb_fire (edict_t *ent)
{
if (!ent)
{
return;
}
if (ent->client->ps.gunframe == 10)
{
vec3_t offset;
@ -461,7 +526,12 @@ void Weapon_LaserTripBomb(edict_t *ent)
const int idleLast = 43;
const int fireFirst = 7;
const int activateLast = 6;
if (!ent)
{
return;
}
if (ent->client->weaponstate == WEAPON_DROPPING)
{
if (ent->client->ps.gunframe == deactivateLast)
@ -572,6 +642,11 @@ void Weapon_LaserTripBomb(edict_t *ent)
void SP_misc_lasertripbomb(edict_t *bomb)
{
if (!bomb)
{
return;
}
// precache
gi.soundindex("weapons/ired/las_set.wav");
gi.soundindex("weapons/ired/las_arm.wav");
@ -612,10 +687,13 @@ Sonic Cannon
======================================================================
*/
void weapon_sc_fire (edict_t *ent)
{
if (!ent)
{
return;
}
if (!(ent->client->buttons & BUTTON_ATTACK))
{
ent->client->ps.gunframe++;
@ -728,6 +806,11 @@ void Weapon_SonicCannon (edict_t *ent)
static int pause_frames[] = {32, 42, 52, 0};
static int fire_frames[] = {12, 13, 14, 15, 16, 17, 0};
if (!ent)
{
return;
}
if (ent->client->ps.gunframe == 0)
{
if (deathmatch->value)
@ -772,7 +855,12 @@ void fire_sconnanEffects (edict_t *self)
vec3_t forward, right;
vec3_t offset, v;
trace_t tr;
if (!self)
{
return;
}
AngleVectors (self->client->v_angle, forward, right, NULL);
VectorScale (forward, -3, self->client->kick_origin);
@ -793,7 +881,12 @@ void fire_sconnanEffects (edict_t *self)
void scexplode_think(edict_t *self)
{
gi.WriteByte (svc_temp_entity);
if (!self)
{
return;
}
gi.WriteByte (svc_temp_entity);
gi.WriteByte (TE_ROCKET_EXPLOSION);
gi.WritePosition (self->s.origin);
gi.multicast (self->s.origin, MULTICAST_PHS);
@ -807,12 +900,17 @@ void fire_sconnan (edict_t *self)
vec3_t forward, right, up;
vec3_t offset;
trace_t tr;
float damage;
float radius;
float damage;
float radius;
damage = self->dmg_radius / SC_MAXCELLS;
radius = damage * SC_MAXRADIUS;
damage = SC_BASEDAMAGE + (damage * SC_DAMGERANGE);
if (!self)
{
return;
}
damage = self->dmg_radius / SC_MAXCELLS;
radius = damage * SC_MAXRADIUS;
damage = SC_BASEDAMAGE + (damage * SC_DAMGERANGE);
AngleVectors (self->client->v_angle, forward, right, up);
@ -824,43 +922,43 @@ void fire_sconnan (edict_t *self)
VectorMA (start, 8192, forward, end);
tr = gi.trace (start, NULL, NULL, end, self, MASK_SHOT|CONTENTS_SLIME|CONTENTS_LAVA);
tr = gi.trace (start, NULL, NULL, end, self, MASK_SHOT|CONTENTS_SLIME|CONTENTS_LAVA);
if ((tr.ent != self) && (tr.ent->takedamage))
{
if ((tr.ent != self) && (tr.ent->takedamage))
{
T_Damage (tr.ent, self, self, forward, tr.endpos, tr.plane.normal, damage, 0, 0, MOD_SONICCANNON);
}
}
T_RadiusDamagePosition (tr.endpos, self, self, damage, tr.ent, radius, MOD_SONICCANNON);
T_RadiusDamagePosition (tr.endpos, self, self, damage, tr.ent, radius, MOD_SONICCANNON);
VectorMA (tr.endpos, -5, forward, end);
gi.WriteByte (svc_temp_entity);
gi.WriteByte (svc_temp_entity);
gi.WriteByte (TE_ROCKET_EXPLOSION);
gi.WritePosition (end);
gi.multicast (self->s.origin, MULTICAST_PHS);
damage -= 100;
radius = 0.1;
damage -= 100;
radius = 0.1;
while(damage > 0)
{
edict_t *explode;
while(damage > 0)
{
edict_t *explode;
VectorMA (end, (50 * crandom()) - 5, forward, explodepos);
VectorMA (explodepos, (50 * crandom()) - 5, right, explodepos);
VectorMA (explodepos, (50 * crandom()) - 5, up, explodepos);
VectorMA (end, (50 * crandom()) - 5, forward, explodepos);
VectorMA (explodepos, (50 * crandom()) - 5, right, explodepos);
VectorMA (explodepos, (50 * crandom()) - 5, up, explodepos);
explode = G_Spawn();
VectorCopy (explodepos, explode->s.origin);
explode = G_Spawn();
VectorCopy (explodepos, explode->s.origin);
explode->classname = "sconnanExplode";
explode->nextthink = level.time + radius;
explode->think = scexplode_think;
explode->classname = "sconnanExplode";
explode->nextthink = level.time + radius;
explode->think = scexplode_think;
radius += 0.1;
damage -= 100;
}
radius += 0.1;
damage -= 100;
}
// play quad damage sound
playQuadSound(self);
@ -875,16 +973,20 @@ void FoundTarget (edict_t *self);
void flare_flash(edict_t *ent)
{
edict_t *target = NULL;
float dist;
float ratio;
float dot;
vec3_t delta;
vec3_t forward;
if (!ent)
{
return;
}
// flash
while (1)
{
float dist;
float ratio;
float dot;
vec3_t delta;
vec3_t forward;
// get the next entity near us
target = findradius(target, ent->s.origin, FLASH_RANGE);
if (target == NULL)
@ -938,6 +1040,11 @@ void flare_flash(edict_t *ent)
void flare_think(edict_t *self)
{
if (!self)
{
return;
}
// on our last leg?
if (level.time > self->timeout)
{
@ -970,6 +1077,11 @@ void fire_flare (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed,
vec3_t adir;
vec3_t up;
if (!self)
{
return;
}
vectoangles (dir, adir);
AngleVectors (adir, NULL, NULL, up);
@ -1006,6 +1118,11 @@ void Weapon_FlareLauncher_Fire (edict_t *ent)
vec3_t offset, start;
vec3_t forward, right;
if (!ent)
{
return;
}
AngleVectors (ent->client->v_angle, forward, right, NULL);
VectorSet(offset, 8, 8, ent->viewheight-8);
@ -1034,6 +1151,11 @@ void Weapon_FlareGun (edict_t *ent)
static int pause_frames[] = {15, 25, 35, 0};
static int fire_frames[] = {8, 0};
if (!ent)
{
return;
}
Weapon_Generic (ent, 5, 14, 44, 48, pause_frames, fire_frames, Weapon_FlareLauncher_Fire);
}
@ -1047,6 +1169,12 @@ void fire_sniper_bullet (edict_t *self, vec3_t start, vec3_t aimdir, int damage,
vec3_t s;
edict_t *ignore = self;
int i = 0;
if (!self)
{
return;
}
VectorMA (start, 8192, aimdir, end);
VectorCopy(start, s);
for(i=0;i<256;++i) // DG: prevent infinite loop (adapted from q2dos)
@ -1094,6 +1222,11 @@ void weapon_sniperrifle_fire (edict_t *ent)
int damage;
int kick;
if (!ent)
{
return;
}
if (deathmatch->value)
{ // normal damage is too extreme in dm
damage = 150;
@ -1153,7 +1286,12 @@ void Weapon_SniperRifle(edict_t *ent)
const static int deactivateEnd = 41;
const static int spFov = 15;
const static int dmFov = 30;
if (!ent)
{
return;
}
if (ent->client->weaponstate == WEAPON_DROPPING)
{
ent->client->sniperFramenum = 0;
@ -1281,6 +1419,11 @@ void Weapon_SniperRifle(edict_t *ent)
void weapon_a2k_exp_think(edict_t *self)
{
if (!self)
{
return;
}
self->s.frame++;
self->s.skinnum++;
@ -1299,6 +1442,11 @@ void Z_RadiusDamageVisible(edict_t *inflictor, edict_t *attacker, float damage,
vec3_t v;
vec3_t dir;
if (!inflictor || !attacker || !ignore)
{
return;
}
while ((ent = findradius(ent, inflictor->s.origin, radius)) != NULL)
{
if (ent == ignore)
@ -1325,10 +1473,14 @@ void Z_RadiusDamageVisible(edict_t *inflictor, edict_t *attacker, float damage,
}
}
#define A2K_FRAMENUM 50
void weapon_a2k_fire (edict_t *ent)
{
if (!ent)
{
return;
}
if (ent->client->ps.gunframe == 14)
{
ent->client->a2kFramenum = level.framenum + A2K_FRAMENUM;
@ -1384,19 +1536,24 @@ void weapon_a2k_fire (edict_t *ent)
}
}
/*
00-09 Active
10-19 Boom (14 actual fire frame)
20-29 Idle1
30-39 Idle2
40-49 Idle3
50-55 Away
*/
void Weapon_A2k (edict_t *ent)
{
/*
00-09 Active
10-19 Boom (14 actual fire frame)
20-29 Idle1
30-39 Idle2
40-49 Idle3
50-55 Away
*/
static int pause_frames[] = {20, 30, 40, 0};
static int fire_frames[] = {14, 19, 0};
if (!ent)
{
return;
}
Weapon_Generic (ent, 9, 19, 49, 55, pause_frames, fire_frames, weapon_a2k_fire);
}
@ -1414,6 +1571,10 @@ qboolean push_hit (edict_t *self, vec3_t start, vec3_t aim, int damage, int kick
vec3_t end;
vec3_t v;
if (!self) {
return false;
}
//see if enemy is in range
VectorMA(start, 64, aim, end);
tr = gi.trace(start, NULL, NULL, end, self, MASK_SHOT);
@ -1457,6 +1618,11 @@ qboolean push_hit (edict_t *self, vec3_t start, vec3_t aim, int damage, int kick
void Action_Push (edict_t *ent)
{
if (!ent)
{
return;
}
if (ent->client->ps.gunframe == 0)
{
ent->client->ps.gunframe++;