diff --git a/game/g_cmds.c b/game/g_cmds.c index 35d85b4..6fe54cc 100644 --- a/game/g_cmds.c +++ b/game/g_cmds.c @@ -2506,7 +2506,7 @@ void ClientCommand (edict_t *ent) gi.dprintf("Not looking at an entity.\n"); return; } - if (!(viewing->svflags & SVF_MONSTER) || (viewing->svflags & SVF_DEADMONSTER)) + if ( !(viewing->svflags & SVF_MONSTER) || (viewing->svflags & SVF_DEADMONSTER) || (viewing->deadflag != DEAD_NO) ) { gi.dprintf("hint_test is only valid for live monsters and actors.\n"); return; diff --git a/game/g_func_decs.h b/game/g_func_decs.h index 89afc06..7489956 100644 --- a/game/g_func_decs.h +++ b/game/g_func_decs.h @@ -443,6 +443,7 @@ extern void gunner_duck_up ( edict_t * self ) ; extern void gunner_duck_hold ( edict_t * self ) ; extern void gunner_duck_down ( edict_t * self ) ; extern qboolean gunner_grenade_check ( edict_t * self ) ; +extern qboolean gunner_ctgrenade_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 ) ; diff --git a/game/g_func_list.h b/game/g_func_list.h index 1770ae6..cae2805 100644 --- a/game/g_func_list.h +++ b/game/g_func_list.h @@ -443,6 +443,7 @@ {"gunner_duck_hold", (byte *)gunner_duck_hold}, {"gunner_duck_down", (byte *)gunner_duck_down}, {"gunner_grenade_check", (byte *)gunner_grenade_check}, +{"gunner_ctgrenade_safety_check", (byte *)gunner_ctgrenade_safety_check}, {"gunner_die", (byte *)gunner_die}, {"gunner_dead", (byte *)gunner_dead}, {"gunner_pain", (byte *)gunner_pain}, diff --git a/game/g_local.h b/game/g_local.h index 00b037e..3ccff42 100644 --- a/game/g_local.h +++ b/game/g_local.h @@ -824,7 +824,7 @@ extern cvar_t *vid_ref; extern cvar_t *zoomrate; extern cvar_t *zoomsnap; -extern cvar_t *blaster_color; // Knightmare added +extern cvar_t *g_showlogic; // Knightmare added extern int max_modelindex; extern int max_soundindex; diff --git a/game/g_main.c b/game/g_main.c index cd8a8bd..81499bb 100644 --- a/game/g_main.c +++ b/game/g_main.c @@ -136,7 +136,7 @@ cvar_t *zoomsnap; cvar_t *sv_stopspeed; //PGM (this was a define in g_phys.c) cvar_t *sv_step_fraction; // Knightmare- this was a define in p_view.c -cvar_t *blaster_color; // Knightmare added +cvar_t *g_showlogic; // Knightmare added void SpawnEntities (char *mapname, char *entities, char *spawnpoint); void ClientThink (edict_t *ent, usercmd_t *cmd); diff --git a/game/g_monster.c b/game/g_monster.c index 50a9461..666fb4d 100644 --- a/game/g_monster.c +++ b/game/g_monster.c @@ -1461,7 +1461,7 @@ void HintTestNext (edict_t *self, edict_t *hint) self->ideal_yaw = vectoyaw(dir); self->goalentity = self->movetarget = next; self->monsterinfo.pausetime = 0; - self->monsterinfo.aiflags = AI_HINT_TEST; + self->monsterinfo.aiflags |= AI_HINT_TEST; // run for it self->monsterinfo.run (self); gi.dprintf("%s (%s): Reached hint_path %s,\nsearching for hint_path %s at %s. %s\n", @@ -1523,7 +1523,7 @@ int HintTestStart (edict_t *self) self->enemy = self->oldenemy = NULL; self->goalentity = self->movetarget = hint; self->monsterinfo.pausetime = 0; - self->monsterinfo.aiflags = AI_HINT_TEST; + self->monsterinfo.aiflags |= AI_HINT_TEST; // run for it self->monsterinfo.run (self); return 1; diff --git a/game/g_save.c b/game/g_save.c index 3df5cdb..9fc8d26 100644 --- a/game/g_save.c +++ b/game/g_save.c @@ -476,7 +476,7 @@ void InitGame (void) crossh = gi.cvar ("crossh", "1", 0); allow_download = gi.cvar("allow_download", "0", 0); - blaster_color = gi.cvar("blaster_color", "1", 0); // Knightmare added + g_showlogic = gi.cvar("g_showlogic", "0", 0); // Knightmare added // If this is an SP game and "readout" is not set, force allow_download off // so we don't get the annoying "Refusing to download path with .." messages diff --git a/game/m_gunner.c b/game/m_gunner.c index 9b205f4..3891f2f 100644 --- a/game/m_gunner.c +++ b/game/m_gunner.c @@ -384,6 +384,38 @@ void gunner_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damag self->monsterinfo.currentmove = &gunner_move_death; } +// Knightmare added +// This does a short-range trace at blast radius, to ensure we won't clip a wall. +#define GUNNER_CTGRENADE_DANGER_RANGE 128.0f +qboolean gunner_ctgrenade_safety_check (edict_t *self, vec3_t start, vec3_t target) +{ + trace_t tr; + vec3_t dir, dangerOffset, dangerTarget; + float dist; + + // get dist to target + VectorSubtract (target, start, dir); + dist = VectorLength (dir); + +// if ((g_showlogic) && (g_showlogic->value)) +// gi.dprintf ("Gunner: perfoming close-range contactgrenade safety check- "); + + // extrapolate point on path to target at danger range + VectorNormalize (dir); + VectorScale (dir, GUNNER_CTGRENADE_DANGER_RANGE, dangerOffset); + VectorAdd (start, dangerOffset, dangerTarget); + + tr = gi.trace(start, vec3_origin, vec3_origin, 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; @@ -392,7 +424,8 @@ qboolean gunner_grenade_check (edict_t *self) trace_t tr; vec3_t dir; vec3_t vhorz; - float horz,vertmax; + float horz, vertmax, dangerClose; + qboolean isContact = (self->spawnflags & SF_MONSTER_SPECIAL); if (!self->enemy) return false; @@ -411,8 +444,13 @@ qboolean gunner_grenade_check (edict_t *self) G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_GUNNER_GRENADE_1], forward, right, start); // see if we're too close + // Knightmare- use longer range for contact grenades + if (isContact) + dangerClose = 128.0f; + else + dangerClose = 100.0f; VectorSubtract (self->enemy->s.origin, self->s.origin, dir); - if (VectorLength(dir) < 100) + if (VectorLength(dir) < dangerClose) return false; // Lazarus: Max vertical distance - this is approximate and conservative @@ -431,13 +469,31 @@ qboolean gunner_grenade_check (edict_t *self) target[2] = self->enemy->absmax[2]; tr = gi.trace(start, vec3_origin, vec3_origin, target, self, MASK_SHOT); if (tr.ent == self->enemy || tr.fraction == 1) - return true; + { + VectorCopy (target, self->pos0); // save this aim location in case later safety check fails + // Knightmare- added close-range contact grenade safety checks + if (isContact) { + if ( gunner_ctgrenade_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]; tr = gi.trace(start, vec3_origin, vec3_origin, target, self, MASK_SHOT); if (tr.ent == self->enemy || tr.fraction == 1) - return true; + { + VectorCopy (target, self->pos0); // save this aim location in case later safety check fails + // Knightmare- added close-range contact grenade safety checks + if (isContact) { + if ( gunner_ctgrenade_safety_check(self, start, target) ) + return true; + } + else + return true; + } return false; } @@ -538,11 +594,15 @@ void GunnerFire (edict_t *self) void GunnerGrenade (edict_t *self) { - vec3_t start,target; - vec3_t forward, right, up; - vec3_t aim; - vec_t monster_speed; - int flash_number; + vec3_t start, target, leadTarget; + vec3_t forward, right, up; + vec3_t aim; + vec_t monster_speed; + int flash_number; + qboolean leadingTarget = false; + qboolean targetSafe = false; + qboolean leadSafe = false; + qboolean isContact = (self->spawnflags & SF_MONSTER_SPECIAL); if (!self->enemy || !self->enemy->inuse) return; @@ -573,7 +633,54 @@ void GunnerGrenade (edict_t *self) // aim at enemy's feet if he's at same elevation or lower. otherwise aim at origin VectorCopy (self->enemy->s.origin, target); - if (self->enemy->absmin[2] <= self->absmax[2]) target[2] = self->enemy->absmin[2]; + if (self->enemy->absmin[2] <= self->absmax[2]) + target[2] = self->enemy->absmin[2]; + + + // lead target... 20, 35, 50, 65 chance of leading + if ( random() < (0.2 + skill->value * 0.15) ) + { + float dist; + float time; + + VectorSubtract (target, start, aim); + dist = VectorLength (aim); + time = dist / GRENADE_VELOCITY; // Not correct, but better than nothin' + VectorMA (target, time, self->enemy->velocity, leadTarget); + if (!isContact) // delay copying for ctgrenade safety check + VectorCopy (leadTarget, target); + leadingTarget = true; + } + + if (isContact) + { + if ( gunner_ctgrenade_safety_check(self, start, target) ) { + VectorCopy (target, self->pos0); // save this target point + targetSafe = true; + } + if ( leadingTarget && gunner_ctgrenade_safety_check(self, start, leadTarget) ) { + VectorCopy (leadTarget, target); // copy lead point over target + leadSafe = true; + } + if ( !targetSafe && !leadSafe ) { + VectorCopy (self->pos0, target); // revert to prev target point + } + /* if ( (g_showlogic) && (g_showlogic->value) ) + { + if ( targetSafe && leadSafe ) + gi.dprintf ("GunnerGrenade: safe to fire at and lead target, saving target point.\n"); + else if ( targetSafe && leadingTarget && !leadSafe ) + gi.dprintf ("GunnerGrenade: safe to fire at but not lead target, saving target point.\n"); + else if ( targetSafe && !leadingTarget ) + gi.dprintf ("GunnerGrenade: safe to fire at target, saving target point.\n"); + else if ( !targetSafe && leadSafe ) + gi.dprintf ("GunnerGrenade: safe to lead target only, not saving target point.\n"); + else if ( !targetSafe && !leadSafe && leadingTarget ) + gi.dprintf ("GunnerGrenade: NOT safe to fire at or lead target, reverting to prev target point.\n"); + else if ( !targetSafe && !leadSafe && !leadingTarget ) + gi.dprintf ("GunnerGrenade: NOT safe to fire at target, reverting to prev target point.\n"); + } */ + } // Lazarus fog reduction of accuracy if (self->monsterinfo.visibility < FOG_CANSEEGOOD) @@ -595,18 +702,6 @@ void GunnerGrenade (edict_t *self) target[1] += crandom() * dist/8 * (2 - skill->value); } */ - // lead target... 20, 35, 50, 65 chance of leading - if ( random() < (0.2 + skill->value * 0.15) ) - { - float dist; - float time; - - VectorSubtract (target, start, aim); - dist = VectorLength (aim); - time = dist / GRENADE_VELOCITY; // Not correct, but better than nothin' - VectorMA (target, time, self->enemy->velocity, target); - } - AimGrenade (self, start, target, GRENADE_VELOCITY, aim); // Lazarus - take into account (sort of) feature of adding shooter's velocity to // grenade velocity @@ -623,7 +718,7 @@ void GunnerGrenade (edict_t *self) VectorNormalize (aim); } - monster_fire_grenade (self, start, aim, 50, GRENADE_VELOCITY, flash_number, (self->spawnflags & SF_MONSTER_SPECIAL)); + monster_fire_grenade (self, start, aim, 50, GRENADE_VELOCITY, flash_number, isContact); } mframe_t gunner_frames_attack_chain [] = diff --git a/missionpack/g_cmds.c b/missionpack/g_cmds.c index 4f6b094..6f32b45 100644 --- a/missionpack/g_cmds.c +++ b/missionpack/g_cmds.c @@ -2356,7 +2356,7 @@ void ClientCommand (edict_t *ent) gi.dprintf("Not looking at an entity.\n"); return; } - if (!(viewing->svflags & SVF_MONSTER) || (viewing->svflags & SVF_DEADMONSTER)) + if ( !(viewing->svflags & SVF_MONSTER) || (viewing->svflags & SVF_DEADMONSTER) || (viewing->deadflag != DEAD_NO) ) { gi.dprintf("hint_test is only valid for live monsters and actors.\n"); return; diff --git a/missionpack/g_func_decs.h b/missionpack/g_func_decs.h index 78e2bc3..686d0f0 100644 --- a/missionpack/g_func_decs.h +++ b/missionpack/g_func_decs.h @@ -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_ctgrenade_safety_check ( edict_t * self , vec3_t start , vec3_t target ) ; 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 ) ; diff --git a/missionpack/g_func_list.h b/missionpack/g_func_list.h index f54bb03..7324b76 100644 --- a/missionpack/g_func_list.h +++ b/missionpack/g_func_list.h @@ -1133,6 +1133,7 @@ {"gunner_opengun", (byte *)gunner_opengun}, {"gunner_duck_down", (byte *)gunner_duck_down}, {"gunner_grenade_check", (byte *)gunner_grenade_check}, +{"gunner_ctgrenade_safety_check", (byte *)gunner_ctgrenade_safety_check}, {"gunner_prox_safety_check", (byte *)gunner_prox_safety_check}, {"gunner_die", (byte *)gunner_die}, {"gunner_dead", (byte *)gunner_dead}, diff --git a/missionpack/g_local.h b/missionpack/g_local.h index 7b79bc9..3d0980d 100644 --- a/missionpack/g_local.h +++ b/missionpack/g_local.h @@ -2487,12 +2487,12 @@ struct edict_s char *common_name; - char *newtargetname; //used with target_change - char *followtarget; //used with func_door_swinging + char *newtargetname; // used with target_change + char *followtarget; // used with func_door_swinging char *destroytarget; char *viewmessage; - char *source; //used with target_bmodel_spawner - char *newteam; //used with target_bmodel_spawner + char *source; // used with target_bmodel_spawner + char *newteam; // used with target_bmodel_spawner char *musictrack; // Knightmare- for specifying OGG or CD track @@ -2500,7 +2500,7 @@ struct edict_s // the origin of this entity: char *move_to; - float distance; //target_playback stuff + float distance; // target_playback stuff float duration; float bob; int lip; @@ -2511,7 +2511,7 @@ struct edict_s vec3_t color; float alpha; - float holdtime; //target_fade stuff + float holdtime; // target_fade stuff float fadein; float fadeout; diff --git a/missionpack/g_monster.c b/missionpack/g_monster.c index 7edd0b6..7548a20 100644 --- a/missionpack/g_monster.c +++ b/missionpack/g_monster.c @@ -2787,7 +2787,7 @@ int HintTestStart (edict_t *self) self->enemy = self->oldenemy = NULL; self->goalentity = self->movetarget = hint; self->monsterinfo.pausetime = 0; - self->monsterinfo.aiflags2 = AI2_HINT_TEST; + self->monsterinfo.aiflags2 |= AI2_HINT_TEST; // run for it self->monsterinfo.run (self); return 1; diff --git a/missionpack/g_newweap.c b/missionpack/g_newweap.c index 8f1d3fc..bf192c9 100644 --- a/missionpack/g_newweap.c +++ b/missionpack/g_newweap.c @@ -204,8 +204,7 @@ edict_t *CheckForProxField (edict_t *ent) hit = touch[i]; if (!hit->inuse) continue; - if (hit->class_id == ENTITY_PROX_FIELD) - { + if (hit->class_id == ENTITY_PROX_FIELD) { return hit; } } diff --git a/missionpack/g_spawn.c b/missionpack/g_spawn.c index 77a3222..f05f909 100644 --- a/missionpack/g_spawn.c +++ b/missionpack/g_spawn.c @@ -885,8 +885,12 @@ void ED_CallSpawn (edict_t *ent) && !(ent->monsterinfo.monsterflags & MFL_DO_NOT_COUNT)) ent->classname = "monster_medic_commander"; // gunner - if ( !strcmp(ent->classname, "monster_gunner") && (random() < ((skill->value + 1.0f) * 0.15f)) ) - ent->classname = "monster_gunner_tactician"; + if ( !strcmp(ent->classname, "monster_gunner") ) { + if (random() < ((skill->value + 1.0f) * 0.15f)) + ent->classname = "monster_gunner_tactician"; + else + ent->spawnflags |= SF_MONSTER_SPECIAL; + } } // LM Escape monster replacement diff --git a/missionpack/m_gunner.c b/missionpack/m_gunner.c index e668e0c..6b8e522 100644 --- a/missionpack/m_gunner.c +++ b/missionpack/m_gunner.c @@ -467,6 +467,39 @@ qboolean gunner_prox_safety_check (edict_t *self, vec3_t start, vec3_t target) return true; } +// Knightmare added +// This does a short-range trace at blast radius, to ensure we won't clip a wall. +#define GUNNER_CTGRENADE_DANGER_RANGE 128.0f +qboolean gunner_ctgrenade_safety_check (edict_t *self, vec3_t start, vec3_t target) +{ + trace_t tr; + vec3_t dir, dangerOffset, dangerTarget; + float dist; + + // get dist to target + VectorSubtract (target, start, dir); + dist = VectorLength (dir); + +// if ((g_showlogic) && (g_showlogic->value)) +// gi.dprintf ("Gunner: perfoming close-range contactgrenade safety check- "); + + // extrapolate point on path to target at danger range + VectorNormalize (dir); + VectorScale (dir, GUNNER_CTGRENADE_DANGER_RANGE, dangerOffset); + VectorAdd (start, dangerOffset, dangerTarget); + + tr = gi.trace(start, vec3_origin, vec3_origin, 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; @@ -477,6 +510,7 @@ qboolean gunner_grenade_check (edict_t *self) vec3_t vhorz; float horz, vertmax, dangerClose; qboolean isProx = (self->moreflags & FL2_COMMANDER); + qboolean isContact = (self->spawnflags & SF_MONSTER_SPECIAL); // Knightmare- Tactician Gunner fires prox mines in a spread, // so we need a wider safety bounds check vec3_t checkMins, checkMaxs; @@ -510,8 +544,11 @@ qboolean gunner_grenade_check (edict_t *self) // see if we're too close // Knightmare- Tactician Gunner's prox mines stick around, so only use at longer range + // Also use longer range for contact grenades if (isProx) dangerClose = 320.0f; + else if (isContact) + dangerClose = 128.0f; else dangerClose = 100.0f; VectorSubtract (self->enemy->s.origin, self->s.origin, dir); @@ -534,10 +571,15 @@ qboolean gunner_grenade_check (edict_t *self) target[2] = self->enemy->absmax[2]; 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 + { + VectorCopy (target, self->aim_point); // save this aim location in case later safety check fails + // Knightmare- added close-range prox and contact grenade safety checks if (isProx) { - VectorCopy (target, self->aim_point); // save this aim location in case later safety check fails - if (gunner_prox_safety_check(self, start, target)) + if ( gunner_prox_safety_check(self, start, target) ) + return true; + } + else if (isContact) { + if ( gunner_ctgrenade_safety_check(self, start, target) ) return true; } else @@ -548,10 +590,15 @@ qboolean gunner_grenade_check (edict_t *self) target[2] = self->enemy->absmin[2]; 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 + { + VectorCopy (target, self->aim_point); // save this aim location in case later safety check fails + // Knightmare- added close-range prox and contact grenade safety checks if (isProx) { - VectorCopy (target, self->aim_point); // save this aim location in case later safety check fails - if (gunner_prox_safety_check(self, start, target)) + if ( gunner_prox_safety_check(self, start, target) ) + return true; + } + else if (isContact) { + if ( gunner_ctgrenade_safety_check(self, start, target) ) return true; } else @@ -694,6 +741,7 @@ void GunnerGrenade (edict_t *self) qboolean targetSafe = false; qboolean leadSafe = false; qboolean isProx = (self->moreflags & FL2_COMMANDER); + qboolean isContact = (self->spawnflags & SF_MONSTER_SPECIAL); //PGM if (!self->enemy || !self->enemy->inuse) @@ -766,12 +814,13 @@ void GunnerGrenade (edict_t *self) dist = VectorLength (aim); time = dist / GRENADE_VELOCITY; // Not correct, but better than nothin' VectorMA (target, time, self->enemy->velocity, leadTarget); - if (!isProx) // delay copying for prox safety check + if (!isProx && !isContact) // delay copying for prox/ctgrenade safety check VectorCopy (leadTarget, target); leadingTarget = true; } - if (isProx) // Knightmare- run another safety check before firing, so players can't trick us into self-damage + // Knightmare- run another safety check before firing, so players can't trick us into self-damage + if (isProx) { if ( gunner_prox_safety_check(self, start, target) ) { VectorCopy (target, self->aim_point); // save this target point @@ -784,22 +833,36 @@ void GunnerGrenade (edict_t *self) if ( !targetSafe && !leadSafe ) { VectorCopy (self->aim_point, target); // revert to prev target point } - /* if ((g_showlogic) && (g_showlogic->value)) - { - if ( targetSafe && leadSafe ) - gi.dprintf ("GunnerGrenade: safe to fire at and lead target, saving target point.\n"); - else if ( targetSafe && leadingTarget && !leadSafe ) - gi.dprintf ("GunnerGrenade: safe to fire at but not lead target, saving target point.\n"); - else if ( targetSafe && !leadingTarget ) - gi.dprintf ("GunnerGrenade: safe to fire at target, saving target point.\n"); - else if ( !targetSafe && leadSafe ) - gi.dprintf ("GunnerGrenade: safe to lead target only, not saving target point.\n"); - else if ( !targetSafe && !leadSafe && leadingTarget ) - gi.dprintf ("GunnerGrenade: NOT safe to fire at or lead target, reverting to prev target point.\n"); - else if ( !targetSafe && !leadSafe && !leadingTarget ) - gi.dprintf ("GunnerGrenade: NOT safe to fire at target, reverting to prev target point.\n"); - } */ } + else if (isContact) + { + if ( gunner_ctgrenade_safety_check(self, start, target) ) { + VectorCopy (target, self->aim_point); // save this target point + targetSafe = true; + } + if ( leadingTarget && gunner_ctgrenade_safety_check(self, start, leadTarget) ) { + VectorCopy (leadTarget, target); // copy lead point over target + leadSafe = true; + } + if ( !targetSafe && !leadSafe ) { + VectorCopy (self->aim_point, target); // revert to prev target point + } + } + /* if ( (isProx || isContact) && (g_showlogic) && (g_showlogic->value) ) + { + if ( targetSafe && leadSafe ) + gi.dprintf ("GunnerGrenade: safe to fire at and lead target, saving target point.\n"); + else if ( targetSafe && leadingTarget && !leadSafe ) + gi.dprintf ("GunnerGrenade: safe to fire at but not lead target, saving target point.\n"); + else if ( targetSafe && !leadingTarget ) + gi.dprintf ("GunnerGrenade: safe to fire at target, saving target point.\n"); + else if ( !targetSafe && leadSafe ) + gi.dprintf ("GunnerGrenade: safe to lead target only, not saving target point.\n"); + else if ( !targetSafe && !leadSafe && leadingTarget ) + gi.dprintf ("GunnerGrenade: NOT safe to fire at or lead target, reverting to prev target point.\n"); + else if ( !targetSafe && !leadSafe && !leadingTarget ) + gi.dprintf ("GunnerGrenade: NOT safe to fire at target, reverting to prev target point.\n"); + } */ // Knightmare- spread out Tactician Gunner's prox mines so they don't collide if (isProx) @@ -858,7 +921,7 @@ void GunnerGrenade (edict_t *self) 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, (self->spawnflags & SF_MONSTER_SPECIAL)); + monster_fire_grenade (self, start, aim, 50, GRENADE_VELOCITY, flash_number, isContact); } mframe_t gunner_frames_attack_chain [] =