void Boss2Rocket (edict_t *self) { vec3_t forward, right; vec3_t start; vec3_t dir; vec3_t vec; int rocketSpeed; if((self->spawnflags & SF_MONSTER_SPECIAL)) rocketSpeed = 400; // Lazarus: Homing rockets are tougher if slow else rocketSpeed = 500 + (100 * skill->value); AngleVectors (self->s.angles, forward, right, NULL); VectorCopy (self->enemy->s.origin, vec); vec[2] += self->enemy->viewheight; // Lazarus fog reduction of accuracy if(self->monsterinfo.visibility < FOG_CANSEEGOOD) { vec[0] += crandom() * 640 * (FOG_CANSEEGOOD - self->monsterinfo.visibility); vec[1] += crandom() * 640 * (FOG_CANSEEGOOD - self->monsterinfo.visibility); vec[2] += crandom() * 320 * (FOG_CANSEEGOOD - self->monsterinfo.visibility); } //1 G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_BOSS2_ROCKET_1], forward, right, start); VectorSubtract (vec, start, dir); VectorNormalize (dir); monster_fire_rocket (self, start, dir, 50, rocketSpeed, MZ2_BOSS2_ROCKET_1, (self->spawnflags & SF_MONSTER_SPECIAL ? self->enemy : NULL) ); //2 G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_BOSS2_ROCKET_2], forward, right, start); VectorSubtract (vec, start, dir); VectorNormalize (dir); monster_fire_rocket (self, start, dir, 50, rocketSpeed, MZ2_BOSS2_ROCKET_2, (self->spawnflags & SF_MONSTER_SPECIAL ? self->enemy : NULL) ); //3 G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_BOSS2_ROCKET_3], forward, right, start); VectorSubtract (vec, start, dir); VectorNormalize (dir); monster_fire_rocket (self, start, dir, 50, rocketSpeed, MZ2_BOSS2_ROCKET_3, (self->spawnflags & SF_MONSTER_SPECIAL ? self->enemy : NULL) ); //4 G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_BOSS2_ROCKET_4], forward, right, start); VectorSubtract (vec, start, dir); VectorNormalize (dir); monster_fire_rocket (self, start, dir, 50, rocketSpeed, MZ2_BOSS2_ROCKET_4, (self->spawnflags & SF_MONSTER_SPECIAL ? self->enemy : NULL) ); }
void Boss2Rocket(edict_t * self) { vec3_t forward, right; vec3_t start; vec3_t dir; vec3_t vec; AngleVectors(self->s.angles, forward, right, NULL); //1 G_ProjectSource(self->s.origin, monster_flash_offset[MZ2_BOSS2_ROCKET_1], forward, right, start); VectorCopy(self->enemy->s.origin, vec); vec[2] += self->enemy->viewheight; VectorSubtract(vec, start, dir); VectorNormalize(dir); monster_fire_rocket(self, start, dir, 50, 500, MZ2_BOSS2_ROCKET_1); //2 G_ProjectSource(self->s.origin, monster_flash_offset[MZ2_BOSS2_ROCKET_2], forward, right, start); VectorCopy(self->enemy->s.origin, vec); vec[2] += self->enemy->viewheight; VectorSubtract(vec, start, dir); VectorNormalize(dir); monster_fire_rocket(self, start, dir, 50, 500, MZ2_BOSS2_ROCKET_2); //3 G_ProjectSource(self->s.origin, monster_flash_offset[MZ2_BOSS2_ROCKET_3], forward, right, start); VectorCopy(self->enemy->s.origin, vec); vec[2] += self->enemy->viewheight; VectorSubtract(vec, start, dir); VectorNormalize(dir); monster_fire_rocket(self, start, dir, 50, 500, MZ2_BOSS2_ROCKET_3); //4 G_ProjectSource(self->s.origin, monster_flash_offset[MZ2_BOSS2_ROCKET_4], forward, right, start); VectorCopy(self->enemy->s.origin, vec); vec[2] += self->enemy->viewheight; VectorSubtract(vec, start, dir); VectorNormalize(dir); monster_fire_rocket(self, start, dir, 50, 500, MZ2_BOSS2_ROCKET_4); }
void myChickRocket (edict_t *self) { int damage, speed; vec3_t forward, start; if (self->monsterinfo.bonus_flags & BF_UNIQUE_FIRE) { myChickFireball(self); return; } if (!G_EntExists(self->enemy)) return; damage = 50 + 15*self->monsterinfo.level; if ( self->activator && self->activator->client ) { speed = 450 + 30*self->monsterinfo.level; } else { speed = 450; } MonsterAim(self, 1, speed, true, MZ2_CHICK_ROCKET_1, forward, start); monster_fire_rocket (self, start, forward, damage, speed, MZ2_CHICK_ROCKET_1); }
void TankRocket (edict_t *self) { vec3_t forward, right; vec3_t start; vec3_t dir; vec3_t vec; int flash_number; if (self->s.frame == FRAME_attak324) flash_number = MZ2_TANK_ROCKET_1; else if (self->s.frame == FRAME_attak327) flash_number = MZ2_TANK_ROCKET_2; else // (self->s.frame == FRAME_attak330) flash_number = MZ2_TANK_ROCKET_3; AngleVectors (self->s.angles, forward, right, NULL); G_ProjectSource (self->s.origin, monster_flash_offset[flash_number], forward, right, start); VectorCopy (self->enemy->s.origin, vec); vec[2] += self->enemy->viewheight; VectorSubtract (vec, start, dir); VectorNormalize (dir); monster_fire_rocket (self, start, dir, 50, 550, flash_number); }
void ChickRocket (edict_t *self) { vec3_t forward, right; vec3_t start; vec3_t dir; vec3_t vec; int damage; if (!self->enemy) return; AngleVectors (self->s.angles, forward, right, NULL); G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_CHICK_ROCKET_1], forward, right, start); VectorMA(self->enemy->s.origin, 0.4, self->enemy->velocity, vec); // VectorCopy (self->enemy->s.origin, vec); vec[2] += self->enemy->viewheight; VectorSubtract (vec, start, dir); VectorNormalize (dir); if (self->radius_dmg) damage = (80 + 14 * self->monsterinfo.skill); else damage = (40 + 7 * self->monsterinfo.skill); monster_fire_rocket (self, start, dir, damage, 650 + 10 * self->monsterinfo.skill, MZ2_CHICK_ROCKET_1); }
void supertankRocket ( edict_t *self ) { vec3_t forward, right; vec3_t start; vec3_t dir; vec3_t vec; q_int32_t 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 ) { flash_number = MZ2_SUPERTANK_ROCKET_2; } else { flash_number = MZ2_SUPERTANK_ROCKET_3; } AngleVectors ( self->s.angles, forward, right, NULL ); G_ProjectSource ( self->s.origin, monster_flash_offset[flash_number], forward, right, start ); VectorCopy ( self->enemy->s.origin, vec ); vec[2] += self->enemy->viewheight; VectorSubtract ( vec, start, dir ); VectorNormalize ( dir ); monster_fire_rocket ( self, start, dir, 50, 500, flash_number ); }
void CarrierPredictiveRocket(edict_t *self) { vec3_t forward, right; vec3_t start; vec3_t dir; if (!self) { return; } AngleVectors(self->s.angles, forward, right, NULL); /* 1 */ G_ProjectSource(self->s.origin, monster_flash_offset[MZ2_CARRIER_ROCKET_1], forward, right, start); PredictAim(self->enemy, start, CARRIER_ROCKET_SPEED, false, -0.3, dir, NULL); monster_fire_rocket(self, start, dir, 50, CARRIER_ROCKET_SPEED, MZ2_CARRIER_ROCKET_1); /* 2 */ G_ProjectSource(self->s.origin, monster_flash_offset[MZ2_CARRIER_ROCKET_2], forward, right, start); PredictAim(self->enemy, start, CARRIER_ROCKET_SPEED, false, -0.15, dir, NULL); monster_fire_rocket(self, start, dir, 50, CARRIER_ROCKET_SPEED, MZ2_CARRIER_ROCKET_2); /* 3 */ G_ProjectSource(self->s.origin, monster_flash_offset[MZ2_CARRIER_ROCKET_3], forward, right, start); PredictAim(self->enemy, start, CARRIER_ROCKET_SPEED, false, 0, dir, NULL); monster_fire_rocket(self, start, dir, 50, CARRIER_ROCKET_SPEED, MZ2_CARRIER_ROCKET_3); /* 4 */ G_ProjectSource(self->s.origin, monster_flash_offset[MZ2_CARRIER_ROCKET_4], forward, right, start); PredictAim(self->enemy, start, CARRIER_ROCKET_SPEED, false, 0.15, dir, NULL); monster_fire_rocket(self, start, dir, 50, CARRIER_ROCKET_SPEED, MZ2_CARRIER_ROCKET_4); }
void soldier_firerocket (edict_t *self) { int damage, speed; vec3_t forward, start; if (!G_EntExists(self->enemy)) return; damage = 50 + 10*self->monsterinfo.level; speed = 650 + 30*self->monsterinfo.level; MonsterAim(self, 0.8, speed, true, MZ2_SOLDIER_BLASTER_8, forward, start); monster_fire_rocket (self, start, forward, damage, speed, MZ2_SOLDIER_BLASTER_8); }
void supertankRocket (edict_t *self) { vec3_t forward, right; vec3_t start; vec3_t dir; vec3_t vec; int flash_number; int rocketSpeed; if((self->spawnflags & SF_MONSTER_SPECIAL)) rocketSpeed = 400; // DWH: Homing rockets are tougher if slow else rocketSpeed = 500 + (100 * skill->value); if (self->s.frame == FRAME_attak2_8) flash_number = MZ2_SUPERTANK_ROCKET_1; else if (self->s.frame == FRAME_attak2_11) flash_number = MZ2_SUPERTANK_ROCKET_2; else // (self->s.frame == FRAME_attak2_14) flash_number = MZ2_SUPERTANK_ROCKET_3; AngleVectors (self->s.angles, forward, right, NULL); G_ProjectSource (self->s.origin, monster_flash_offset[flash_number], forward, right, start); VectorCopy (self->enemy->s.origin, vec); vec[2] += self->enemy->viewheight; // Lazarus fog reduction of accuracy if(self->monsterinfo.visibility < FOG_CANSEEGOOD) { vec[0] += crandom() * 640 * (FOG_CANSEEGOOD - self->monsterinfo.visibility); vec[1] += crandom() * 640 * (FOG_CANSEEGOOD - self->monsterinfo.visibility); vec[2] += crandom() * 320 * (FOG_CANSEEGOOD - self->monsterinfo.visibility); } VectorSubtract (vec, start, dir); VectorNormalize (dir); monster_fire_rocket (self, start, dir, 50, rocketSpeed, flash_number, (self->spawnflags & SF_MONSTER_SPECIAL ? self->enemy : NULL) ); }
void ChickRocket (edict_t *self) { vec3_t forward, right; vec3_t start; vec3_t dir; vec3_t vec; qboolean tone = true; AngleVectors (self->s.angles, forward, right, NULL); G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_CHICK_ROCKET_1], forward, right, start); VectorCopy (self->enemy->s.origin, vec); vec[2] += self->enemy->viewheight; VectorSubtract (vec, start, dir); VectorNormalize (dir); if (self->s.skinnum > 1) monster_fire_heat (self, start, dir, 50, 500, MZ2_CHICK_ROCKET_1); else monster_fire_rocket (self, start, dir, 50, 500, MZ2_CHICK_ROCKET_1); }
void decoy_rocket (edict_t *self) { int damage, speed; vec3_t forward, start; speed = 650 + 30*self->activator->myskills.level; if (speed > 950) speed = 950; //if (random() <= 0.1) // damage = 50 + 10*self->activator->myskills.level; //else damage = 1; MonsterAim(self, damage, speed, true, 0, forward, start); monster_fire_rocket (self, start, forward, damage, speed, 0); gi.WriteByte (svc_muzzleflash); gi.WriteShort (self-g_edicts); gi.WriteByte (MZ_ROCKET); gi.multicast (self->s.origin, MULTICAST_PVS); }
void myTankRocket (edict_t *self) { int flash_number, damage, speed; vec3_t forward, start; // sanity check if (!self->enemy || !self->enemy->inuse) return; if (self->s.frame == FRAME_attak324) flash_number = MZ2_TANK_ROCKET_1; else if (self->s.frame == FRAME_attak327) flash_number = MZ2_TANK_ROCKET_2; else flash_number = MZ2_TANK_ROCKET_3; damage = 50 + 10*self->monsterinfo.level; speed = 650 + 30*self->monsterinfo.level; MonsterAim(self, 0.5, speed, true, flash_number, forward, start); monster_fire_rocket (self, start, forward, damage, speed, flash_number); }
void ChickRocket(edict_t *self) { if (!self) { return; } vec3_t forward, right; vec3_t start; vec3_t dir; vec3_t vec; AngleVectors(self->s.angles, forward, right, NULL); G_ProjectSource(self->s.origin, monster_flash_offset[MZ2_CHICK_ROCKET_1], forward, right, start); VectorCopy(self->enemy->s.origin, vec); vec[2] += self->enemy->viewheight; VectorSubtract(vec, start, dir); VectorNormalize(dir); monster_fire_rocket(self, start, dir, 50, 500, MZ2_CHICK_ROCKET_1); }
void Boss2PredictiveRocket (edict_t *self) { vec3_t forward, right; vec3_t start; vec3_t dir; vec3_t vec; float time, dist; gi.dprintf("predictive fire\n"); AngleVectors (self->s.angles, forward, right, NULL); //1 G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_BOSS2_ROCKET_1], forward, right, start); VectorSubtract(self->enemy->s.origin, start, dir); // dir[2] += self->enemy->viewheight; dist = VectorLength(dir); time = dist / BOSS2_ROCKET_SPEED; VectorMA(self->enemy->s.origin, time-0.3, self->enemy->velocity, vec); // VectorCopy (self->enemy->s.origin, vec); // vec[2] += self->enemy->viewheight; VectorSubtract (vec, start, dir); VectorNormalize (dir); monster_fire_rocket (self, start, dir, 50, BOSS2_ROCKET_SPEED, MZ2_BOSS2_ROCKET_1); //2 G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_BOSS2_ROCKET_2], forward, right, start); VectorSubtract(self->enemy->s.origin, start, dir); // dir[2] += self->enemy->viewheight; dist = VectorLength(dir); time = dist / BOSS2_ROCKET_SPEED; VectorMA(self->enemy->s.origin, time-0.15, self->enemy->velocity, vec); // VectorCopy (self->enemy->s.origin, vec); // vec[2] += self->enemy->viewheight; VectorSubtract (vec, start, dir); VectorNormalize (dir); monster_fire_rocket (self, start, dir, 50, BOSS2_ROCKET_SPEED, MZ2_BOSS2_ROCKET_2); //3 G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_BOSS2_ROCKET_3], forward, right, start); VectorSubtract(self->enemy->s.origin, start, dir); // dir[2] += self->enemy->viewheight; dist = VectorLength(dir); time = dist / BOSS2_ROCKET_SPEED; VectorMA(self->enemy->s.origin, time, self->enemy->velocity, vec); // VectorCopy (self->enemy->s.origin, vec); // vec[2] += self->enemy->viewheight; VectorSubtract (vec, start, dir); VectorNormalize (dir); monster_fire_rocket (self, start, dir, 50, BOSS2_ROCKET_SPEED, MZ2_BOSS2_ROCKET_3); //4 G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_BOSS2_ROCKET_4], forward, right, start); VectorSubtract(self->enemy->s.origin, start, dir); // dir[2] += self->enemy->viewheight; dist = VectorLength(dir); time = dist / BOSS2_ROCKET_SPEED; VectorMA(self->enemy->s.origin, time+0.15, self->enemy->velocity, vec); // VectorCopy (self->enemy->s.origin, vec); // vec[2] += self->enemy->viewheight; VectorSubtract (vec, start, dir); VectorNormalize (dir); monster_fire_rocket (self, start, dir, 50, BOSS2_ROCKET_SPEED, MZ2_BOSS2_ROCKET_4); }
void CarrierRocket(edict_t *self) { vec3_t forward, right; vec3_t start; vec3_t dir; vec3_t vec; if (!self) { return; } if (self->enemy) { if (self->enemy->client && (random() < 0.5)) { CarrierPredictiveRocket(self); return; } } else { return; } AngleVectors(self->s.angles, forward, right, NULL); /* 1 */ G_ProjectSource(self->s.origin, monster_flash_offset[MZ2_CARRIER_ROCKET_1], forward, right, start); VectorCopy(self->enemy->s.origin, vec); vec[2] -= 15; VectorSubtract(vec, start, dir); VectorNormalize(dir); VectorMA(dir, 0.4, right, dir); VectorNormalize(dir); monster_fire_rocket(self, start, dir, 50, 500, MZ2_CARRIER_ROCKET_1); /* 2 */ G_ProjectSource(self->s.origin, monster_flash_offset[MZ2_CARRIER_ROCKET_2], forward, right, start); VectorCopy(self->enemy->s.origin, vec); VectorSubtract(vec, start, dir); VectorNormalize(dir); VectorMA(dir, 0.025, right, dir); VectorNormalize(dir); monster_fire_rocket(self, start, dir, 50, 500, MZ2_CARRIER_ROCKET_2); /* 3 */ G_ProjectSource(self->s.origin, monster_flash_offset[MZ2_CARRIER_ROCKET_3], forward, right, start); VectorCopy(self->enemy->s.origin, vec); VectorSubtract(vec, start, dir); VectorNormalize(dir); VectorMA(dir, -0.025, right, dir); VectorNormalize(dir); monster_fire_rocket(self, start, dir, 50, 500, MZ2_CARRIER_ROCKET_3); /* 4 */ G_ProjectSource(self->s.origin, monster_flash_offset[MZ2_CARRIER_ROCKET_4], forward, right, start); VectorCopy(self->enemy->s.origin, vec); vec[2] -= 15; VectorSubtract(vec, start, dir); VectorNormalize(dir); VectorMA(dir, -0.4, right, dir); VectorNormalize(dir); monster_fire_rocket(self, start, dir, 50, 500, MZ2_CARRIER_ROCKET_4); }
void ChickRocket (edict_t *self) { // DWH: Added skill level-dependent rocket speed, leading target, suicide prevention, // target elevation dependent target location, and homing rockets trace_t trace; vec3_t forward, right; vec3_t start; vec3_t dir; vec3_t vec; int rocketSpeed; AngleVectors (self->s.angles, forward, right, NULL); G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_CHICK_ROCKET_1], forward, right, start); if((self->spawnflags & SF_MONSTER_SPECIAL)) rocketSpeed = 400; // DWH: Homing rockets are tougher if slow else rocketSpeed = 500 + (100 * skill->value); if(visible(self,self->enemy)) { if(random() < 0.66 || (start[2] < self->enemy->absmin[2])) { VectorCopy (self->enemy->s.origin, vec); vec[2] += self->enemy->viewheight; VectorSubtract (vec, start, dir); } else { VectorCopy (self->enemy->s.origin, vec); vec[2] = self->enemy->absmin[2]; VectorSubtract (vec, start, dir); } // Lazarus fog reduction of accuracy if(self->monsterinfo.visibility < FOG_CANSEEGOOD) { vec[0] += crandom() * 640 * (FOG_CANSEEGOOD - self->monsterinfo.visibility); vec[1] += crandom() * 640 * (FOG_CANSEEGOOD - self->monsterinfo.visibility); vec[2] += crandom() * 320 * (FOG_CANSEEGOOD - self->monsterinfo.visibility); } // lead target, but not if using homers // 20, 35, 50, 65 chance of leading // DWH: Switched this around from Rogue code... it led target more often // for Easy, which seemed backwards if( (random() < (0.2 + skill->value * 0.15) ) && !(self->spawnflags & SF_MONSTER_SPECIAL)) { float dist; float time; dist = VectorLength (dir); time = dist/rocketSpeed; VectorMA(vec, time, self->enemy->velocity, vec); VectorSubtract(vec, start, dir); } } else { // Fire at feet of last known position VectorCopy(self->monsterinfo.last_sighting,vec); vec[2] += self->enemy->mins[2]; VectorSubtract(vec,start,dir); } VectorNormalize(dir); // paranoia, make sure we're not shooting a target right next to us trace = gi.trace(start, vec3_origin, vec3_origin, vec, self, MASK_SHOT); if(trace.ent == self->enemy || trace.ent == world) { VectorSubtract(trace.endpos,start,vec); if(VectorLength(vec) > MELEE_DISTANCE) { if(trace.fraction > 0.5 || (trace.ent && trace.ent->client)) monster_fire_rocket (self, start, dir, 50, rocketSpeed, MZ2_CHICK_ROCKET_1, (self->spawnflags & SF_MONSTER_SPECIAL ? self->enemy : NULL) ); } } }
void TankRocket (edict_t *self) { vec3_t forward, right; vec3_t start; vec3_t dir; vec3_t vec; int flash_number; trace_t trace; // PGM int rocketSpeed; // PGM // pmm - blindfire support vec3_t target; qboolean blindfire = false; if(!self->enemy || !self->enemy->inuse) //PGM return; //PGM // pmm - blindfire check if (self->monsterinfo.aiflags & AI_MANUAL_STEERING) blindfire = true; else blindfire = false; if (self->s.frame == FRAME_attak324) flash_number = MZ2_TANK_ROCKET_1; else if (self->s.frame == FRAME_attak327) flash_number = MZ2_TANK_ROCKET_2; else // (self->s.frame == FRAME_attak330) flash_number = MZ2_TANK_ROCKET_3; AngleVectors (self->s.angles, forward, right, NULL); G_ProjectSource (self->s.origin, monster_flash_offset[flash_number], forward, right, start); rocketSpeed = 500 + (100 * skill->value); // PGM rock & roll.... :) // PMM if (blindfire) VectorCopy (self->monsterinfo.blind_fire_target, target); else VectorCopy (self->enemy->s.origin, target); // pmm // VectorCopy (self->enemy->s.origin, vec); // vec[2] += self->enemy->viewheight; // VectorSubtract (vec, start, dir); //PGM // PMM - blindfire shooting if (blindfire) { VectorCopy (target, vec); VectorSubtract (vec, start, dir); } // pmm // don't shoot at feet if they're above me. else if(random() < 0.66 || (start[2] < self->enemy->absmin[2])) { // gi.dprintf("normal shot\n"); VectorCopy (self->enemy->s.origin, vec); vec[2] += self->enemy->viewheight; VectorSubtract (vec, start, dir); } else { // gi.dprintf("shooting at feet!\n"); VectorCopy (self->enemy->s.origin, vec); vec[2] = self->enemy->absmin[2]; VectorSubtract (vec, start, dir); } //PGM //====== //PMM - lead target (not when blindfiring) // 20, 35, 50, 65 chance of leading if((!blindfire) && ((random() < (0.2 + ((3 - skill->value) * 0.15))))) { float dist; float time; // gi.dprintf ("leading target\n"); dist = VectorLength (dir); time = dist/rocketSpeed; VectorMA(vec, time, self->enemy->velocity, vec); VectorSubtract(vec, start, dir); } //PMM - lead target //====== VectorNormalize (dir); // gi.WriteByte (svc_temp_entity); // gi.WriteByte (TE_DEBUGTRAIL); // gi.WritePosition (start); // gi.WritePosition (vec); // gi.multicast (start, MULTICAST_ALL); // pmm blindfire doesn't check target (done in checkattack) // paranoia, make sure we're not shooting a target right next to us trace = gi.trace(start, vec3_origin, vec3_origin, vec, self, MASK_SHOT); if (blindfire) { // blindfire has different fail criteria for the trace if (!(trace.startsolid || trace.allsolid || (trace.fraction < 0.5))) monster_fire_rocket (self, start, dir, 50, rocketSpeed, flash_number); else { // try shifting the target to the left a little (to help counter large offset) VectorCopy (target, vec); VectorMA (vec, -20, right, vec); VectorSubtract(vec, start, dir); VectorNormalize (dir); trace = gi.trace(start, vec3_origin, vec3_origin, vec, self, MASK_SHOT); if (!(trace.startsolid || trace.allsolid || (trace.fraction < 0.5))) monster_fire_rocket (self, start, dir, 50, rocketSpeed, flash_number); else { // ok, that failed. try to the right VectorCopy (target, vec); VectorMA (vec, 20, right, vec); VectorSubtract(vec, start, dir); VectorNormalize (dir); trace = gi.trace(start, vec3_origin, vec3_origin, vec, self, MASK_SHOT); if (!(trace.startsolid || trace.allsolid || (trace.fraction < 0.5))) monster_fire_rocket (self, start, dir, 50, rocketSpeed, flash_number); else if ((g_showlogic) && (g_showlogic->value)) // ok, I give up gi.dprintf ("tank avoiding blindfire shot\n"); } } } else { trace = gi.trace(start, vec3_origin, vec3_origin, vec, self, MASK_SHOT); if(trace.ent == self->enemy || trace.ent == world) { if(trace.fraction > 0.5 || (trace.ent && trace.ent->client)) monster_fire_rocket (self, start, dir, 50, rocketSpeed, MZ2_CHICK_ROCKET_1); // else // gi.dprintf("didn't make it halfway to target...aborting\n"); } } }
void TankRocket (edict_t *self) { trace_t trace; vec3_t forward, right; vec3_t start; vec3_t dir; vec3_t vec; int flash_number; // Lazarus: Added skill level-dependent rocket speed similar to Rogue pack int rocketSpeed; // check if enemy went away if (!self->enemy || !self->enemy->inuse) return; if (self->s.frame == FRAME_attak324) flash_number = MZ2_TANK_ROCKET_1; else if (self->s.frame == FRAME_attak327) flash_number = MZ2_TANK_ROCKET_2; else // (self->s.frame == FRAME_attak330) flash_number = MZ2_TANK_ROCKET_3; AngleVectors (self->s.angles, forward, right, NULL); G_ProjectSource (self->s.origin, monster_flash_offset[flash_number], forward, right, start); if((self->spawnflags & SF_MONSTER_SPECIAL)) rocketSpeed = 400; // Lazarus: Homing rockets are tougher if slow else rocketSpeed = 500 + (100 * skill->value); /* VectorCopy (self->enemy->s.origin, vec); vec[2] += self->enemy->viewheight; VectorSubtract (vec, start, dir); VectorNormalize (dir); */ // Lazarus: Added homers VectorCopy (self->enemy->s.origin, vec); if(random() < 0.66 || (start[2] < self->enemy->absmin[2])) { // gi.dprintf("normal shot\n"); vec[2] += self->enemy->viewheight; } else { // gi.dprintf("shooting at feet!\n"); vec[2] = self->enemy->absmin[2]; } // Lazarus fog reduction of accuracy if(self->monsterinfo.visibility < FOG_CANSEEGOOD) { vec[0] += crandom() * 640 * (FOG_CANSEEGOOD - self->monsterinfo.visibility); vec[1] += crandom() * 640 * (FOG_CANSEEGOOD - self->monsterinfo.visibility); vec[2] += crandom() * 320 * (FOG_CANSEEGOOD - self->monsterinfo.visibility); } VectorSubtract (vec, start, dir); // lead target, but not if using homers // 20, 35, 50, 65 chance of leading // Lazarus: Switched this around from Rogue code... it led target more often // for Easy, which seemed backwards if( (random() < (0.2 + skill->value * 0.15) ) && !(self->spawnflags & SF_MONSTER_SPECIAL)) { float dist; float time; dist = VectorLength (dir); time = dist/rocketSpeed; VectorMA(vec, time, self->enemy->velocity, vec); VectorSubtract(vec, start, dir); } VectorNormalize(dir); // paranoia, make sure we're not shooting a target right next to us trace = gi.trace(start, vec3_origin, vec3_origin, vec, self, MASK_SHOT); if(trace.ent == self->enemy || trace.ent == world) { if(trace.fraction > 0.5 || (trace.ent && trace.ent->client)) monster_fire_rocket (self, start, dir, 50, rocketSpeed, flash_number, (self->spawnflags & SF_MONSTER_SPECIAL ? self->enemy : NULL) ); } }
void Boss2Rocket (edict_t *self) { vec3_t forward, right; vec3_t start; vec3_t dir; vec3_t vec; if(self->enemy) { if(self->enemy->client && random() < 0.9) { Boss2PredictiveRocket(self); return; } } AngleVectors (self->s.angles, forward, right, NULL); //1 G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_BOSS2_ROCKET_1], forward, right, start); VectorCopy (self->enemy->s.origin, vec); // vec[2] += self->enemy->viewheight; vec[2] -= 15; VectorSubtract (vec, start, dir); VectorNormalize (dir); VectorMA (dir, 0.4, right, dir); VectorNormalize (dir); monster_fire_rocket (self, start, dir, 50, 500, MZ2_BOSS2_ROCKET_1); //2 G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_BOSS2_ROCKET_2], forward, right, start); VectorCopy (self->enemy->s.origin, vec); // vec[2] += self->enemy->viewheight; VectorSubtract (vec, start, dir); VectorNormalize (dir); VectorMA (dir, 0.025, right, dir); VectorNormalize (dir); monster_fire_rocket (self, start, dir, 50, 500, MZ2_BOSS2_ROCKET_2); //3 G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_BOSS2_ROCKET_3], forward, right, start); VectorCopy (self->enemy->s.origin, vec); // vec[2] += self->enemy->viewheight; VectorSubtract (vec, start, dir); VectorNormalize (dir); VectorMA (dir, -0.025, right, dir); VectorNormalize (dir); monster_fire_rocket (self, start, dir, 50, 500, MZ2_BOSS2_ROCKET_3); //4 G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_BOSS2_ROCKET_4], forward, right, start); VectorCopy (self->enemy->s.origin, vec); // vec[2] += self->enemy->viewheight; vec[2] -= 15; VectorSubtract (vec, start, dir); VectorNormalize (dir); VectorMA (dir, -0.4, right, dir); VectorNormalize (dir); monster_fire_rocket (self, start, dir, 50, 500, MZ2_BOSS2_ROCKET_4); //5 // G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_BOSS2_ROCKET_4], forward, right, start); // VectorCopy (self->enemy->s.origin, vec); // vec[2] += self->enemy->viewheight; // VectorSubtract (vec, start, dir); // VectorNormalize (dir); // monster_fire_rocket (self, start, dir, 50, 500, MZ2_BOSS2_ROCKET_2); }