void soldier_fire(edict_t * self, int flash_number) { vec3_t start; vec3_t forward, right, up; vec3_t aim; vec3_t dir; vec3_t end; float r , u; int flash_index; if (self->s.skinnum < 2) flash_index = blaster_flash[flash_number]; else if (self->s.skinnum < 4) flash_index = shotgun_flash[flash_number]; else flash_index = machinegun_flash[flash_number]; AngleVectors(self->s.angles, forward, right, NULL); G_ProjectSource(self->s.origin, monster_flash_offset[flash_index], forward, right, start); if (flash_number == 5 || flash_number == 6) { VectorCopy(forward, aim); } else { VectorCopy(self->enemy->s.origin, end); end[2] += self->enemy->viewheight; VectorSubtract(end, start, aim); vectoangles(aim, dir); AngleVectors(dir, forward, right, up); r = crandom() * 1000; u = crandom() * 500; VectorMA(start, 8192, forward, end); VectorMA(end, r, right, end); VectorMA(end, u, up, end); VectorSubtract(end, start, aim); VectorNormalize(aim); } if (self->s.skinnum <= 1) { monster_fire_blaster(self, start, aim, 5, 600, flash_index, EF_BLASTER); } else if (self->s.skinnum <= 3) { monster_fire_shotgun(self, start, aim, 2, 1, DEFAULT_SHOTGUN_HSPREAD, DEFAULT_SHOTGUN_VSPREAD, DEFAULT_SHOTGUN_COUNT, flash_index); } else { if (!(self->monsterinfo.aiflags & AI_HOLD_FRAME)) self->monsterinfo.pausetime = level.time + (3 + rand() % 8) * FRAMETIME; monster_fire_bullet(self, start, aim, 2, 4, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, flash_index); if (level.time >= self->monsterinfo.pausetime) self->monsterinfo.aiflags &= ~AI_HOLD_FRAME; else self->monsterinfo.aiflags |= AI_HOLD_FRAME; } }
void soldier_fireshotgun (edict_t *self) { int damage; vec3_t forward, start; if (!G_EntExists(self->enemy)) return; damage = 5 + self->monsterinfo.level; MonsterAim(self, 0.8, 0, false, MZ2_SOLDIER_SHOTGUN_8, forward, start); monster_fire_shotgun(self, start, forward, damage, damage, 375, 375, 10, MZ2_SOLDIER_SHOTGUN_8); }
void soldier_fire (edict_t *self, int flash_number) { vec3_t start; vec3_t forward, right, up; vec3_t aim; vec3_t dir; vec3_t end; float r, u; int flash_index; if ((self->s.skinnum % 6) < 2) flash_index = blaster_flash[flash_number]; else if ((self->s.skinnum % 6) < 4) flash_index = shotgun_flash[flash_number]; else flash_index = machinegun_flash[flash_number]; AngleVectors (self->s.angles, forward, right, NULL); G_ProjectSource (self->s.origin, monster_flash_offset[flash_index], forward, right, start); if (flash_number == 5 || flash_number == 6) { VectorCopy (forward, aim); } else { VectorCopy (self->enemy->s.origin, end); end[2] += self->enemy->viewheight; // Lazarus fog reduction of accuracy if(self->monsterinfo.visibility < FOG_CANSEEGOOD) { end[0] += crandom() * 640 * (FOG_CANSEEGOOD - self->monsterinfo.visibility); end[1] += crandom() * 640 * (FOG_CANSEEGOOD - self->monsterinfo.visibility); end[2] += crandom() * 320 * (FOG_CANSEEGOOD - self->monsterinfo.visibility); } VectorSubtract (end, start, aim); // Lazarus: Accuracy is skill level dependent if(skill->value < 3) { vectoangles (aim, dir); AngleVectors (dir, forward, right, up); r = crandom()*(1000 - 333*skill->value); u = crandom()*(500 - 167*skill->value); VectorMA (start, 8192, forward, end); VectorMA (end, r, right, end); VectorMA (end, u, up, end); VectorSubtract (end, start, aim); } VectorNormalize (aim); } if ((self->s.skinnum % 6) <= 1) { // Lazarus: make bolt speed skill level dependent monster_fire_blaster (self, start, aim, 5, 600 + 100*skill->value, flash_index, EF_BLASTER, BLASTER_ORANGE); } else if ((self->s.skinnum % 6) <= 3) { monster_fire_shotgun (self, start, aim, 2, 1, DEFAULT_SHOTGUN_HSPREAD, DEFAULT_SHOTGUN_VSPREAD, DEFAULT_SHOTGUN_COUNT, flash_index); } else { if (!(self->monsterinfo.aiflags & AI_HOLD_FRAME)) self->monsterinfo.pausetime = level.time + (3 + rand() % 8) * FRAMETIME; monster_fire_bullet (self, start, aim, 2, 4, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, flash_index); if (level.time >= self->monsterinfo.pausetime) self->monsterinfo.aiflags &= ~AI_HOLD_FRAME; else self->monsterinfo.aiflags |= AI_HOLD_FRAME; } }
//void soldier_fire (edict_t *self, int flash_number) PMM void soldier_fire (edict_t *self, int in_flash_number) { vec3_t start; vec3_t forward, right, up; vec3_t aim; vec3_t dir; vec3_t end; float r, u; int flash_index; int flash_number; #ifdef RUN_SHOOT vec3_t aim_norm; float angle; #endif #ifdef CHECK_TARGET trace_t tr; vec3_t aim_good; #endif if ((!self->enemy) || (!self->enemy->inuse)) { self->monsterinfo.aiflags &= ~AI_HOLD_FRAME; return; } if (in_flash_number < 0) { flash_number = -1 * in_flash_number; } else flash_number = in_flash_number; if (self->s.skinnum < 2) flash_index = blaster_flash[flash_number]; else if (self->s.skinnum < 4) flash_index = shotgun_flash[flash_number]; else flash_index = machinegun_flash[flash_number]; AngleVectors (self->s.angles, forward, right, NULL); G_ProjectSource (self->s.origin, monster_flash_offset[flash_index], forward, right, start); if (flash_number == 5 || flash_number == 6) // he's dead { VectorCopy (forward, aim); } else { VectorCopy (self->enemy->s.origin, end); end[2] += self->enemy->viewheight; VectorSubtract (end, start, aim); #ifdef CHECK_TARGET VectorCopy (end, aim_good); #endif #ifdef RUN_SHOOT //PMM if (in_flash_number < 0) { VectorCopy (aim, aim_norm); VectorNormalize (aim_norm); angle = DotProduct (aim_norm, forward); //gi.dprintf ("Dot Product: %f", DotProduct (aim_norm, forward)); if (angle < 0.9) // ~25 degree angle { // if(g_showlogic && g_showlogic->value) // gi.dprintf (" not firing due to bad dotprod %f\n", angle); return; } // else // { // if(g_showlogic && g_showlogic->value) // gi.dprintf (" firing: dotprod = %f\n", angle); // } } //-PMM #endif vectoangles (aim, dir); AngleVectors (dir, forward, right, up); if (skill->value < 2) { r = crandom()*1000; u = crandom()*500; } else { r = crandom()*500; u = crandom()*250; } VectorMA (start, 8192, forward, end); VectorMA (end, r, right, end); VectorMA (end, u, up, end); VectorSubtract (end, start, aim); VectorNormalize (aim); } #ifdef CHECK_TARGET if (!(flash_number == 5 || flash_number == 6)) // he's dead { tr = gi.trace (start, NULL, NULL, aim_good, self, MASK_SHOT); if ((tr.ent != self->enemy) && (tr.ent != world)) { // if(g_showlogic && g_showlogic->value) // gi.dprintf ("infantry shot aborted due to bad target\n"); return; } } #endif if (self->s.skinnum <= 1) { monster_fire_blaster (self, start, aim, 5, 600, flash_index, EF_BLASTER); } else if (self->s.skinnum <= 3) { monster_fire_shotgun (self, start, aim, 2, 1, DEFAULT_SHOTGUN_HSPREAD, DEFAULT_SHOTGUN_VSPREAD, DEFAULT_SHOTGUN_COUNT, flash_index); } else { // PMM - changed to wait from pausetime to not interfere with dodge code if (!(self->monsterinfo.aiflags & AI_HOLD_FRAME)) self->wait = level.time + (3 + rand() % 8) * FRAMETIME; monster_fire_bullet (self, start, aim, 2, 4, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, flash_index); if (level.time >= self->wait) self->monsterinfo.aiflags &= ~AI_HOLD_FRAME; else self->monsterinfo.aiflags |= AI_HOLD_FRAME; } }
void soldier_fire (edict_t *self, int flash_number) { vec3_t start; vec3_t forward, right, up; vec3_t aim; vec3_t dir; vec3_t end; float r, u; int flash_index; if (!self->enemy) return; if (self->s.skinnum < 2) flash_index = blaster_flash[flash_number]; else if (self->s.skinnum < 4) flash_index = shotgun_flash[flash_number]; else flash_index = machinegun_flash[flash_number]; AngleVectors (self->s.angles, forward, right, NULL); G_ProjectSource (self->s.origin, monster_flash_offset[flash_index], forward, right, start); if (flash_number == 5 || flash_number == 6) { VectorCopy (forward, aim); } else { VectorMA(self->enemy->s.origin, 0.3, self->enemy->velocity, end); end[2] += self->enemy->viewheight; VectorSubtract (end, start, aim); vectoangles (aim, dir); AngleVectors (dir, forward, right, up); if (self->s.skinnum <= 1) { r = crandom()*(500 - 6 * self->monsterinfo.skill); u = crandom()*(250 - 3 * self->monsterinfo.skill); } else { r = crandom()*(800 - 16 * self->monsterinfo.skill); u = crandom()*(400 - 8 * self->monsterinfo.skill); } VectorMA (start, 8192, forward, end); VectorMA (end, r, right, end); VectorMA (end, u, up, end); VectorSubtract (end, start, aim); VectorNormalize (aim); } if (self->s.skinnum <= 1) { if (self->radius_dmg) monster_fire_blaster (self, start, aim, (int) ceil(8.0 + 5.0 * self->monsterinfo.skill), 1500 + 50 * self->monsterinfo.skill, flash_index, 0); else monster_fire_blaster (self, start, aim, (int) ceil(4.0 + 2.5 * self->monsterinfo.skill), 900 + 30 * self->monsterinfo.skill, flash_index, 0); if (self->s.frame == 41) { if (level.time >= self->monsterinfo.pausetime) { if (visible(self, self->enemy) && (self->enemy->health > 0) && (random() <= 0.9)) { self->monsterinfo.pausetime = level.time + (4 + rand() % 4) * FRAMETIME; self->monsterinfo.aiflags |= AI_HOLD_FRAME; } else { self->monsterinfo.aiflags &= ~AI_HOLD_FRAME; } } else { self->monsterinfo.aiflags |= AI_HOLD_FRAME; } } } else if (self->s.skinnum <= 3) { if (self->radius_dmg) monster_fire_shotgun (self, start, aim, (int) ceil(2.0 + 0.6 * self->monsterinfo.skill), 1, DEFAULT_SHOTGUN_HSPREAD, DEFAULT_SHOTGUN_VSPREAD, DEFAULT_SHOTGUN_COUNT, flash_index); else monster_fire_shotgun (self, start, aim, (int) ceil(1.0 + 0.3 * self->monsterinfo.skill), 1, DEFAULT_SHOTGUN_HSPREAD, DEFAULT_SHOTGUN_VSPREAD, DEFAULT_SHOTGUN_COUNT, flash_index); } else { vec3_t target; if ((!(self->monsterinfo.aiflags & AI_HOLD_FRAME)) && (self->health > 0)) self->monsterinfo.pausetime = level.time + (3 + rand() % 8) * FRAMETIME; // project enemy back a bit and target there VectorCopy (self->enemy->s.origin, target); VectorMA (target, (-0.5 + 0.015 * self->monsterinfo.skill), self->enemy->velocity, target); target[2] += self->enemy->viewheight; VectorSubtract (target, start, aim); VectorNormalize (aim); if (self->radius_dmg) monster_fire_bullet (self, start, aim, (int) ceil(4.2 + 2.2 * self->monsterinfo.skill), 4, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, flash_index); else monster_fire_bullet (self, start, aim, (int) ceil(2.1 + 1.1 * self->monsterinfo.skill), 4, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, flash_index); if (level.time >= self->monsterinfo.pausetime) self->monsterinfo.aiflags &= ~AI_HOLD_FRAME; else { self->s.frame--; // self->monsterinfo.aiflags |= AI_HOLD_FRAME; } } }