mirror of
https://github.com/yquake2/zaero.git
synced 2024-11-24 21:01:43 +00:00
Merge pull request #9 from NeonKnightOA/pvsfixes
Adding struct checks to files. This solves countless of issues and bugs.
This commit is contained in:
commit
c49cb3982d
56 changed files with 7058 additions and 1430 deletions
112
src/g_ai.c
112
src/g_ai.c
|
@ -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);
|
||||
|
|
133
src/g_cmds.c
133
src/g_cmds.c
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
406
src/g_func.c
406
src/g_func.c
|
@ -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;
|
||||
|
|
205
src/g_items.c
205
src/g_items.c
|
@ -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);
|
||||
|
|
412
src/g_misc.c
412
src/g_misc.c
|
@ -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;
|
||||
|
|
172
src/g_monster.c
172
src/g_monster.c
|
@ -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);
|
||||
|
|
229
src/g_phys.c
229
src/g_phys.c
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
196
src/g_target.c
196
src/g_target.c
|
@ -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));
|
||||
|
||||
|
|
146
src/g_trigger.c
146
src/g_trigger.c
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
107
src/g_utils.c
107
src/g_utils.c
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 = ¶site_move_end_fidget;
|
||||
}
|
||||
|
||||
void parasite_do_fidget (edict_t *self)
|
||||
{
|
||||
if (!self)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
self->monsterinfo.currentmove = ¶site_move_fidget;
|
||||
}
|
||||
|
||||
void parasite_refidget (edict_t *self)
|
||||
{
|
||||
{
|
||||
if (!self)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (random() <= 0.8)
|
||||
self->monsterinfo.currentmove = ¶site_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 = ¶site_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 = ¶site_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 = ¶site_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 = ¶site_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 = ¶site_move_start_walk;
|
||||
}
|
||||
|
||||
void parasite_walk (edict_t *self)
|
||||
{
|
||||
if (!self)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
self->monsterinfo.currentmove = ¶site_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 = ¶site_move_drain;
|
||||
if (!self)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
self->monsterinfo.currentmove = ¶site_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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
584
src/zaero/ai.c
584
src/zaero/ai.c
|
@ -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);
|
||||
}
|
||||
|
|
868
src/zaero/anim.c
868
src/zaero/anim.c
File diff suppressed because it is too large
Load diff
|
@ -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;
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
Monster frame move lists.
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
/*=========================================================================
|
||||
Hound.
|
||||
=========================================================================*/
|
||||
|
@ -30,7 +29,6 @@ mmove_t *frame_moves_hound[] = {
|
|||
&hound_move_death,
|
||||
NULL};
|
||||
|
||||
|
||||
/*=========================================================================
|
||||
Sentien.
|
||||
=========================================================================*/
|
||||
|
|
293
src/zaero/item.c
293
src/zaero/item.c
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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++;
|
||||
|
|
Loading…
Reference in a new issue