More tweaks to Tactician Gunner prox aiming.

Added close range safety check/trace to Tactician Gunner prox aiming.
Added check for nightmare mode for Beta-Class Gladiator and dog.
This commit is contained in:
Knightmare66 2021-07-31 21:47:21 -04:00
parent 8401c475f6
commit cedf3628ac
25 changed files with 188 additions and 131 deletions

View file

@ -1315,7 +1315,7 @@ void T_Damage (edict_t *in_targ, edict_t *inflictor, edict_t *in_attacker, vec3_
//PGM
if ((targ->svflags & SVF_MONSTER)
//Knightmare- no damage reaction from negative damage lasers and triggers
// Knightmare- no damage reaction from negative damage lasers and triggers
&& ( (damage > 0) || ((mod != MOD_TRIGGER_HURT) && (mod != MOD_TARGET_LASER)) ))
{
M_ReactToDamage (targ, attacker, inflictor);
@ -1331,7 +1331,7 @@ void T_Damage (edict_t *in_targ, edict_t *inflictor, edict_t *in_attacker, vec3_
}
}
else if ((client)
//Knightmare- no damage reaction from negative damage lasers and triggers
// Knightmare- no damage reaction from negative damage lasers and triggers
&& ( (damage > 0) || ((mod != MOD_TRIGGER_HURT) && (mod != MOD_TARGET_LASER)) ))
{
if (!(targ->flags & FL_GODMODE) && (take)) {
@ -1340,7 +1340,7 @@ void T_Damage (edict_t *in_targ, edict_t *inflictor, edict_t *in_attacker, vec3_
}
}
else if ((take)
//Knightmare- no damage reaction from negative damage lasers and triggers
// Knightmare- no damage reaction from negative damage lasers and triggers
&& ( (damage > 0) || ((mod != MOD_TRIGGER_HURT) && (mod != MOD_TARGET_LASER)) ))
{
if (targ->pain)

View file

@ -1133,6 +1133,7 @@ extern void GunnerFire ( edict_t * self ) ;
extern void gunner_opengun ( edict_t * self ) ;
extern void gunner_duck_down ( edict_t * self ) ;
extern qboolean gunner_grenade_check ( edict_t * self ) ;
extern qboolean gunner_prox_safety_check ( edict_t * self , vec3_t start , vec3_t target ) ;
extern void gunner_die ( edict_t * self , edict_t * inflictor , edict_t * attacker , int damage , vec3_t point ) ;
extern void gunner_dead ( edict_t * self ) ;
extern void gunner_pain ( edict_t * self , edict_t * other , float kick , int damage ) ;

View file

@ -1133,6 +1133,7 @@
{"gunner_opengun", (byte *)gunner_opengun},
{"gunner_duck_down", (byte *)gunner_duck_down},
{"gunner_grenade_check", (byte *)gunner_grenade_check},
{"gunner_prox_safety_check", (byte *)gunner_prox_safety_check},
{"gunner_die", (byte *)gunner_die},
{"gunner_dead", (byte *)gunner_dead},
{"gunner_pain", (byte *)gunner_pain},

View file

@ -1740,8 +1740,6 @@ void kick_attack (edict_t *ent);
// g_newweap.c
//
//extern float nuke_framenum;
extern vec3_t proxMins;
extern vec3_t proxMaxs;
void fire_flechette (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, float damage_radius, int radius_damage);
//void fire_prox (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed);
void fire_prox (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int damage_multiplier, int speed, int health, float timer, float damage_radius);

View file

@ -151,10 +151,6 @@ void SP_flechette (edict_t *flechette)
#define PROX_HEALTH 20
#define PROX_DAMAGE 90
// Knightmare- these are used for aiming traces to avoid collision
vec3_t proxMins = {-8, -8, -8};
vec3_t proxMaxs = {8, 8, 8};
void Prox_Explode (edict_t *ent);
//===============
//===============
@ -734,7 +730,12 @@ void fire_prox (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int dama
prox = G_Spawn();
VectorCopy (start, prox->s.origin);
VectorScale (aimdir, speed, prox->velocity);
// Lazarus - keep same vertical boost for players, but monsters do a better job
// of calculating aim direction, so throw that out
if (self->client)
VectorMA (prox->velocity, 200 + crandom() * 10.0, up, prox->velocity);
else
VectorMA (prox->velocity, crandom() * 10.0, up, prox->velocity);
VectorMA (prox->velocity, crandom() * 10.0, right, prox->velocity);
// Knightmare- add player's base velocity to prox
if (add_velocity_throw->value && self->client)

View file

@ -942,6 +942,9 @@ qboolean AimGrenade (edict_t *self, vec3_t start, vec3_t target, vec_t speed, ve
float last_error, v_error;
int i;
vec3_t last_aim;
// Knightmare- wider bounds to avoid prox collision
vec3_t proxMins = {-8, -8, -8};
vec3_t proxMaxs = {8, 8, 8};
VectorCopy (target, aim_point);
VectorSubtract (aim_point, self->s.origin, from_origin);

View file

@ -452,10 +452,10 @@ void q1_fire_grenade (edict_t *self, vec3_t start, vec3_t aimdir, int damage, in
VectorScale (aimdir, speed, grenade->velocity);
// Lazarus - keep same vertical boost for players, but monsters do a better job
// of calculating aim direction, so throw that out
if (self->client)
// if (self->client)
VectorMA (grenade->velocity, 200 + (random() - 0.5) * 20.0, up, grenade->velocity);
else
VectorMA (grenade->velocity, (random() - 0.5) * 20.0, up, grenade->velocity);
// else
// VectorMA (grenade->velocity, (random() - 0.5) * 20.0, up, grenade->velocity);
VectorMA (grenade->velocity, (random() - 0.5) * 20.0, right, grenade->velocity);
VectorSet (grenade->avelocity, 300, 300, 300);

View file

@ -140,12 +140,11 @@ void dog_pain (edict_t *self, edict_t *other, float kick, int damage)
self->pain_debounce_time = level.time + 1;
if (skill->value == 3)
return;
if (self->health > 0)
gi.sound (self, CHAN_VOICE, sound_pain, 1, ATTN_NORM, 0); //WAS ATTN_IDLE
if (skill->value == 3)
return; // no pain anims in nightmare
if (random() < 0.5)
self->monsterinfo.currentmove = &dog_move_pain1;

View file

@ -258,6 +258,9 @@ void gladb_pain (edict_t *self, edict_t *other, float kick, int damage)
else
gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
if (skill->value == 3)
return; // no pain anims in nightmare
if (self->velocity[2] > 100)
self->monsterinfo.currentmove = &gladb_move_pain_air;
else

View file

@ -229,7 +229,6 @@ 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->health < (self->max_health / 2))
self->s.skinnum |= 1;
@ -254,7 +253,6 @@ void gladiator_pain (edict_t *self, edict_t *other, float kick, int damage)
self->monsterinfo.currentmove = &gladiator_move_pain_air;
else
self->monsterinfo.currentmove = &gladiator_move_pain;
}

View file

@ -38,8 +38,11 @@ static int tactician_sound_sight;
// (for the gunner, not for players) since the gunner now shoots
// smarter, and adjusted things so that the initial velocity out
// of the barrel is the same.
#define GRENADE_VELOCITY 632.4555320337
#define GRENADE_VELOCITY_SQUARED 400000
#define GRENADE_VELOCITY 632.4555320337f
#define GRENADE_VELOCITY_SQUARED 400000.0f
// Knightmare- placement spread for Tactician Gunner prox mines
#define GUNNER_PROX_SPREAD 40.0f
#define HALF_GUNNER_PROX_SPREAD (GUNNER_PROX_SPREAD * 0.5f)
void gunner_idlesound (edict_t *self)
{
@ -296,6 +299,8 @@ 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)
{
int smallDamage, bigDamage;
if (self->health < (self->max_health / 2))
self->s.skinnum |= 1;
@ -303,8 +308,8 @@ void gunner_pain (edict_t *self, edict_t *other, float kick, int damage)
if (!self->groundentity)
{
// if ((g_showlogic) && (g_showlogic->value))
// gi.dprintf ("gunner: pain avoided due to no ground\n");
// if ((g_showlogic) && (g_showlogic->value))
// gi.dprintf ("gunner: pain avoided due to no ground\n");
return;
}
@ -329,9 +334,20 @@ void gunner_pain (edict_t *self, edict_t *other, float kick, int damage)
if (skill->value == 3)
return; // no pain anims in nightmare
if (damage <= 10)
if (self->moreflags & FL2_COMMANDER) {
smallDamage = 20;
bigDamage = 50;
}
else {
smallDamage = 10;
bigDamage = 25;
}
// if (damage <= 10)
if (damage <= smallDamage)
self->monsterinfo.currentmove = &gunner_move_pain3;
else if (damage <= 25)
// else if (damage <= 25)
else if (damage <= bigDamage)
self->monsterinfo.currentmove = &gunner_move_pain2;
else
self->monsterinfo.currentmove = &gunner_move_pain1;
@ -340,7 +356,7 @@ void gunner_pain (edict_t *self, edict_t *other, float kick, int damage)
// PMM - clear duck flag
if (self->monsterinfo.aiflags & AI_DUCKED)
monster_duck_up(self);
monster_duck_up (self);
}
void gunner_dead (edict_t *self)
@ -412,6 +428,44 @@ void gunner_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damag
self->monsterinfo.currentmove = &gunner_move_death;
}
// Knightmare added
// This calcs horizontal spread of prox mines based on distance.
// Then it does a short-range trace at blast radius, to ensure we won't clip a wall.
qboolean gunner_prox_safety_check (edict_t *self, vec3_t start, vec3_t target)
{
trace_t tr;
vec3_t closeCheckMins, closeCheckMaxs, dir, dangerOffset, dangerTarget;
float dist, dangerSpread, dangerRange = 256.0f;
// get dist to target
VectorSubtract (target, start, dir);
dist = VectorLength (dir);
// get spread at damger range
dangerSpread = (HALF_GUNNER_PROX_SPREAD / dist) * dangerRange;
dangerSpread += 8.0f; // add bounds of prox mine + 2
VectorSet (closeCheckMins, -dangerSpread, -dangerSpread, -12.0f);
VectorSet (closeCheckMaxs, dangerSpread, dangerSpread, 12.0f);
// if ((g_showlogic) && (g_showlogic->value))
// gi.dprintf ("Tactician Gunner: perfoming close-range safety check with radius of %5.2f- ", dangerSpread);
// extrapolate point on path to target at danger range
VectorNormalize (dir);
VectorScale (dir, dangerRange, dangerOffset);
VectorAdd (start, dangerOffset, dangerTarget);
tr = gi.trace(start, closeCheckMins, closeCheckMaxs, dangerTarget, self, MASK_SHOT);
if (tr.fraction < 1.0) {
// if (g_showlogic && g_showlogic->value)
// gi.dprintf ("failed!\n");
return false;
}
// if (g_showlogic && g_showlogic->value)
// gi.dprintf ("succeeded!\n");
return true;
}
qboolean gunner_grenade_check (edict_t *self)
{
vec3_t start;
@ -422,6 +476,11 @@ qboolean gunner_grenade_check (edict_t *self)
vec3_t vhorz;
float horz, vertmax, dangerClose;
qboolean isProx = (self->moreflags & FL2_COMMANDER);
// Knightmare- Tactician Gunner fires prox mines in a spread,
// so we need a wider safety bounds check
vec3_t checkMins, checkMaxs;
vec3_t proxMins = {-8, -8, -8};
vec3_t proxMaxs = {8, 8, 8};
if (!self->enemy)
return false;
@ -433,6 +492,16 @@ qboolean gunner_grenade_check (edict_t *self)
// Lazarus: We can do better than that... see below
// Knightmare- use appropriate trace mins/maxs based on projectile
if (isProx) {
VectorCopy (proxMins, checkMins);
VectorCopy (proxMaxs, checkMaxs);
}
else {
VectorCopy (vec3_origin, checkMins);
VectorCopy (vec3_origin, checkMaxs);
}
// check to see that we can trace to the player before we start
// tossing grenades around.
AngleVectors (self->s.angles, forward, right, NULL);
@ -462,21 +531,29 @@ qboolean gunner_grenade_check (edict_t *self)
// would almost always hit the platform the target was standing on
VectorCopy (self->enemy->s.origin, target);
target[2] = self->enemy->absmax[2];
if (isProx)
tr = gi.trace(start, proxMins, proxMaxs, target, self, MASK_SHOT);
else
tr = gi.trace(start, vec3_origin, vec3_origin, target, self, MASK_SHOT);
tr = gi.trace(start, checkMins, checkMaxs, target, self, MASK_SHOT);
if (tr.ent == self->enemy || tr.fraction == 1)
{ // Knightmare- added close-range prox safety check
if (isProx) {
if (gunner_prox_safety_check(self, start, target))
return true;
}
else
return true;
}
// Repeat for feet... in case we're looking down at a target standing under,
// for example, a short doorway
target[2] = self->enemy->absmin[2];
if (isProx)
tr = gi.trace(start, proxMins, proxMaxs, target, self, MASK_SHOT);
else
tr = gi.trace(start, vec3_origin, vec3_origin, target, self, MASK_SHOT);
tr = gi.trace(start, checkMins, checkMaxs, target, self, MASK_SHOT);
if (tr.ent == self->enemy || tr.fraction == 1)
{ // Knightmare- added close-range prox safety check
if (isProx) {
if (gunner_prox_safety_check(self, start, target))
return true;
}
else
return true;
}
return false;
}
@ -493,7 +570,8 @@ void gunner_duck_down (edict_t *self)
self->monsterinfo.aiflags |= AI_DUCKED;
if (skill->value >= 2)
{
if (random() > 0.5)
// Lazarus: Added check for goodness of grenade firing
if (random() > 0.5 && gunner_grenade_check(self))
GunnerGrenade (self);
}
@ -675,17 +753,8 @@ void GunnerGrenade (edict_t *self)
// Knightmare- spread out Tactician Gunner's prox mines so they don't collide
if (self->moreflags & FL2_COMMANDER)
{
if ( blindfire )
{
target[0] += crandom() * 192;
target[1] += crandom() * 192;
target[2] += crandom() * 192;
}
else
{
target[0] += crandom() * 32;
target[1] += crandom() * 32;
}
target[0] += crandom() * GUNNER_PROX_SPREAD;
target[1] += crandom() * GUNNER_PROX_SPREAD;
}
// Lazarus fog reduction of accuracy
@ -745,7 +814,7 @@ void GunnerGrenade (edict_t *self)
if (self->moreflags & FL2_COMMANDER)
{
float prox_timer = (blindfire) ? 60.0f : 30.0f;
monster_fire_prox (self, start, aim, 90, 1, 600, 20, prox_timer, 192, flash_number);
monster_fire_prox (self, start, aim, 90, 1, GRENADE_VELOCITY, 20, prox_timer, 192, flash_number);
}
else
monster_fire_grenade (self, start, aim, 50, GRENADE_VELOCITY, flash_number, false);
@ -879,7 +948,7 @@ void gunner_attack (edict_t *self)
{
// if the check passes, go for the attack
self->monsterinfo.currentmove = &gunner_move_attack_grenade;
self->monsterinfo.attack_finished = level.time + 2*random();
self->monsterinfo.attack_finished = level.time + 2 * random();
}
// pmm - should this be active?
// else
@ -1294,7 +1363,7 @@ void SP_monster_gunner (edict_t *self)
if (!self->health)
self->health = 400;
if (!self->gib_health)
self->gib_health = -150;
self->gib_health = -250;
if (!self->mass)
self->mass = 300;

View file

@ -767,13 +767,15 @@ void medic_pain (edict_t *self, edict_t *other, float kick, int damage)
}
else if (random() < 0.5)
{
self->monsterinfo.currentmove = &medic_move_pain1;
gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
self->monsterinfo.currentmove = &medic_move_pain1;
}
else
{
self->monsterinfo.currentmove = &medic_move_pain2;
gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
self->monsterinfo.currentmove = &medic_move_pain2;
}
// PMM - clear duck flag
if (self->monsterinfo.aiflags & AI_DUCKED)

View file

@ -20,7 +20,7 @@ static int sound_idle;
void q1dog_idle (edict_t *self)
{
if(random() < 0.2)
if (random() < 0.2)
gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0);
}
@ -138,14 +138,10 @@ void q1dog_pain (edict_t *self, edict_t *other, float kick, int damage)
self->pain_debounce_time = level.time + 1;
if (skill->value == 3)
return;
if (self->health > 0)
gi.sound (self, CHAN_VOICE, sound_pain, 1, ATTN_NORM, 0); //WAS ATTN_IDLE
if(random() < 0.5)
if (random() < 0.5)
self->monsterinfo.currentmove = &q1dog_move_pain1;
else
self->monsterinfo.currentmove = &q1dog_move_pain2;
@ -418,7 +414,7 @@ void q1dog_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage
self->deadflag = DEAD_DEAD;
self->takedamage = DAMAGE_YES;
if(random() < 0.5)
if (random() < 0.5)
self->monsterinfo.currentmove = &q1dog_move_death1;
else
self->monsterinfo.currentmove = &q1dog_move_death2;

View file

@ -170,9 +170,6 @@ void q1enforcer_pain (edict_t *self, edict_t *other, float kick, int damage)
else
gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
if (skill->value == 3)
return; // no pain anims in nightmare
if (damage <= 10)
self->monsterinfo.currentmove = &q1enforcer_move_pain3;
else if (damage <= 25)

View file

@ -367,11 +367,7 @@ void fiend_pain (edict_t *self, edict_t *other, float kick, int damage)
if (self->health > 0)
gi.sound (self, CHAN_VOICE, sound_pain, 1, ATTN_NORM, 0);
if (skill->value == 3)
return; // no pain anims in nightmare
self->monsterinfo.currentmove = &fiend_move_pain;
}

View file

@ -20,7 +20,7 @@ static int sound_attack;
void q1grunt_idle (edict_t *self)
{
if(!self->enemy)
if (!self->enemy)
if (random() > 0.8)
{
gi.sound (self, CHAN_VOICE, sound_idle, 0.8, ATTN_STATIC, 0);
@ -181,28 +181,28 @@ void q1grunt_pain (edict_t *self, edict_t *other, float kick, int damage)
if (level.time < self->pain_debounce_time)
return;
if(self->health <= 0)
if (self->health <= 0)
return;
r = random();
if (r < 0.2)
{
self->monsterinfo.currentmove = &q1grunt_move_pain1;
gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
self->pain_debounce_time = level.time + 0.6;
gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
self->monsterinfo.currentmove = &q1grunt_move_pain1;
}
else if (r < 0.6)
{
self->monsterinfo.currentmove = &q1grunt_move_pain2;
gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
self->pain_debounce_time = level.time + 1.1;
gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
self->monsterinfo.currentmove = &q1grunt_move_pain2;
}
else
{
self->monsterinfo.currentmove = &q1grunt_move_pain3;
gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
self->pain_debounce_time = level.time + 1.1;
gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
self->monsterinfo.currentmove = &q1grunt_move_pain3;
}
}
@ -220,7 +220,7 @@ void q1grunt_fire (edict_t *self)
vec3_t end;
float r, u;
if(!self->enemy)
if (!self->enemy)
return;
AngleVectors (self->s.angles, forward, right, NULL);

View file

@ -295,15 +295,12 @@ mmove_t hknight_move_pain1 = {FRAME_pain1, FRAME_pain5, hknight_frames_pain1, hk
void hknight_pain (edict_t *self, edict_t *other, float kick, int damage)
{
if (level.time < self->pain_debounce_time)
return;
if (skill->value == 3)
return; // no pain anims in nightmare
self->pain_debounce_time = level.time + 1.1;
gi.sound (self, CHAN_VOICE, sound_pain, 1, ATTN_NORM, 0);
self->pain_debounce_time = level.time + 1.1;
self->monsterinfo.currentmove = &hknight_move_pain1;
}

View file

@ -290,20 +290,15 @@ mmove_t knight_move_pain2 = {FRAME_painb1, FRAME_painb11, knight_frames_pain2, k
void knight_pain (edict_t *self, edict_t *other, float kick, int damage)
{
if (level.time < self->pain_debounce_time)
return;
if (skill->value == 3)
return; // no pain anims in nightmare
self->pain_debounce_time = level.time + 1.1;
if (self->health > 0)
gi.sound (self, CHAN_VOICE, sound_pain, 1, ATTN_NORM, 0);
self->pain_debounce_time = level.time + 1.1;
if (random() <0.85)
if (random() < 0.85)
self->monsterinfo.currentmove = &knight_move_pain1;
else
self->monsterinfo.currentmove = &knight_move_pain2;

View file

@ -211,33 +211,28 @@ void ogre_pain (edict_t *self, edict_t *other, float kick, int damage)
if (r < 0.25)
{
self->monsterinfo.currentmove = &ogre_move_pain1;
self->pain_debounce_time = level.time + 1;
self->monsterinfo.currentmove = &ogre_move_pain1;
}
else if (r < 0.5)
{
self->monsterinfo.currentmove = &ogre_move_pain2;
self->pain_debounce_time = level.time + 1;
self->monsterinfo.currentmove = &ogre_move_pain2;
}
else if (r < 0.75)
{
self->monsterinfo.currentmove = &ogre_move_pain3;
self->pain_debounce_time = level.time + 1;
self->monsterinfo.currentmove = &ogre_move_pain3;
}
else if (r < 0.88)
{
self->monsterinfo.currentmove = &ogre_move_pain4;
self->pain_debounce_time = level.time + 2;
self->monsterinfo.currentmove = &ogre_move_pain4;
}
else
{
self->monsterinfo.currentmove = &ogre_move_pain5;
self->pain_debounce_time = level.time + 2;
self->monsterinfo.currentmove = &ogre_move_pain5;
}
}
@ -351,7 +346,7 @@ void ogre_grenade_fire (edict_t *self)
vec3_t start, target;
vec3_t forward, right, aim;
vec_t monster_speed;
// vec_t monster_speed;
AngleVectors (self->s.angles, forward, right, NULL);
G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_GUNNER_GRENADE_1], forward, right, start);
@ -367,9 +362,7 @@ void ogre_grenade_fire (edict_t *self)
else
target[2] += self->enemy->viewheight*0.8;
// VectorSubtract (target, start, aim);
// VectorNormalize (aim);
#if 0
if (self->enemy)
{
float range;
@ -417,6 +410,10 @@ void ogre_grenade_fire (edict_t *self)
VectorMA (aim, delta, v1, aim);
VectorNormalize (aim);
}
#else
VectorSubtract (target, start, aim);
VectorNormalize (aim);
#endif
gi.WriteByte (svc_muzzleflash);
gi.WriteShort (self-g_edicts);
@ -424,8 +421,8 @@ void ogre_grenade_fire (edict_t *self)
gi.multicast (self->s.origin, MULTICAST_PVS);
gi.sound (self, CHAN_WEAPON|CHAN_RELIABLE, sound_shoot, 1.0, ATTN_NORM, 0);
// q1_fire_grenade (self, start, aim, 40, 600, 2.5, 80);
q1_fire_grenade (self, start, aim, 40, GRENADE_VELOCITY, 2.5, 80);
q1_fire_grenade (self, start, aim, 40, 600, 2.5, 80);
// q1_fire_grenade (self, start, aim, 40, GRENADE_VELOCITY, 2.5, 80);
}

View file

@ -134,6 +134,7 @@ void q1rotfish_bite (edict_t *self)
VectorSet (aim, Q1_FISH_MELEE_DISTANCE, 0, 0);
gi.sound (self, CHAN_WEAPON, sound_chomp, 1, ATTN_NORM, 0);
fire_hit (self, aim, (random() + random()) * 3, 0);
}
@ -167,6 +168,11 @@ void q1rotfish_melee(edict_t *self)
void q1rotfish_pain (edict_t *self, edict_t *other, float kick, int damage)
{
if (level.time < self->pain_debounce_time)
return;
self->pain_debounce_time = level.time + 1.1;
self->monsterinfo.currentmove = &q1rotfish_move_pain1;
}

View file

@ -152,11 +152,10 @@ void scrag_pain (edict_t *self, edict_t *other, float kick, int damage)
return;
self->pain_debounce_time = level.time + 2;
if (skill->value == 3)
return; // no pain anims in nightmare
if (self->health > 0)
gi.sound (self, CHAN_VOICE, sound_pain, 1, ATTN_NORM, 0);
self->monsterinfo.currentmove = &scrag_move_pain;
}

View file

@ -116,16 +116,18 @@ mmove_t q1shalrath_move_pain1 = {FRAME_pain1, FRAME_pain5, q1shalrath_frames_pai
void q1shalrath_pain (edict_t *self, edict_t *other, float kick, int damage)
{
float r;
// float r;
if (level.time < self->pain_debounce_time)
return;
r = random();
// r = random();
self->pain_debounce_time = level.time + 3;
gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
self->monsterinfo.currentmove = &q1shalrath_move_pain1;
gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
self->pain_debounce_time = level.time + 3;
}

View file

@ -31,7 +31,7 @@ void shambler_sight (edict_t *self, edict_t *other)
/*static*/ void shambler_idle_sound (edict_t *self)
{
if(!self->enemy && random() > 0.8)
if (!self->enemy && random() > 0.8)
gi.sound (self, CHAN_VOICE, sound_idle, 0.8, ATTN_IDLE, 0);
}
@ -154,13 +154,10 @@ void shambler_pain (edict_t *self, edict_t *other, float kick, int damage)
if (self->health <= 0)
return;
if (skill->value == 3)
return; // no pain anims in nightmare
if (self->health > 0)
gi.sound (self, CHAN_VOICE, sound_pain, 1, ATTN_NORM, 0);
if(random() * 400 > damage)
if (random() * 400 > damage)
return;
self->monsterinfo.currentmove = &shambler_move_pain;
@ -266,7 +263,7 @@ void shambler_swing_right (edict_t *self)
{
vec3_t aim;
if(!self->enemy)
if (!self->enemy)
return;
VectorSet (aim, MELEE_DISTANCE*1.2, self->maxs[0], 8);
@ -293,7 +290,7 @@ void shambler_smash (edict_t *self)
{
vec3_t aim;
if(!self->enemy)
if (!self->enemy)
return;
VectorSet (aim, MELEE_DISTANCE*1.2, self->maxs[0], self->maxs[2]);
@ -472,7 +469,7 @@ void shambler_attack (edict_t *self)
self->monsterinfo.currentmove = &shambler_move_swingR_attack;
}
}
else if((len > 196 && len < 1024) && infront(self,self->enemy))
else if ((len > 196 && len < 1024) && infront(self,self->enemy))
{
self->monsterinfo.currentmove = &shambler_move_magic_attack;
}
@ -486,7 +483,7 @@ void shambler_melee(edict_t *self)
{
if (!self->enemy || !self->enemy->inuse || self->enemy->health <= 0)
{
// if(random() > 0.5)
// if (random() > 0.5)
// self->monsterinfo.currentmove = &shambler_move_walk;
return;
}
@ -497,7 +494,7 @@ void shambler_melee(edict_t *self)
self->monsterinfo.currentmove = &shambler_move_smash_attack;
else
{
if(random() > 0.5)
if (random() > 0.5)
self->monsterinfo.currentmove = &shambler_move_swingL_attack;
else
self->monsterinfo.currentmove = &shambler_move_swingR_attack;

View file

@ -557,26 +557,26 @@ void q1zombie_pain (edict_t *self, edict_t *other, float kick, int damage)
if (r < 0.25)
{
self->monsterinfo.currentmove = &q1zombie_move_pain1;
gi.sound (self, CHAN_VOICE, sound_pain, 1, ATTN_NORM, 0);
self->pain_debounce_time = level.time + 1.0;
gi.sound (self, CHAN_VOICE, sound_pain, 1, ATTN_NORM, 0);
self->monsterinfo.currentmove = &q1zombie_move_pain1;
}
else if (r < 0.5)
{
self->monsterinfo.currentmove = &q1zombie_move_pain2;
gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
self->pain_debounce_time = level.time + 1.5;
gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
self->monsterinfo.currentmove = &q1zombie_move_pain2;
}
else if (r < 0.75)
{
self->monsterinfo.currentmove = &q1zombie_move_pain3;
gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
self->pain_debounce_time = level.time + 1.1;
gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
self->monsterinfo.currentmove = &q1zombie_move_pain3;
}
else
{
self->monsterinfo.currentmove = &q1zombie_move_pain4;
self->pain_debounce_time = level.time + 1.0;
self->monsterinfo.currentmove = &q1zombie_move_pain4;
}
}