void CCarrier::PredictiveRocket () { vec3f start, dir; anglef angles = Entity->State.GetAngles().ToVectors (); //1 G_ProjectSource (Entity->State.GetOrigin(), MonsterFlashOffsets[MZ2_CARRIER_ROCKET_1], angles, start); PredictAim (*Entity->Enemy, start, CARRIER_ROCKET_SPEED, false, -0.3f, &dir, NULL); MonsterFireRocket (start, dir, 50, CARRIER_ROCKET_SPEED, MZ2_CARRIER_ROCKET_1); //2 G_ProjectSource (Entity->State.GetOrigin(), MonsterFlashOffsets[MZ2_CARRIER_ROCKET_2], angles, start); PredictAim (*Entity->Enemy, start, CARRIER_ROCKET_SPEED, false, -0.15f, &dir, NULL); MonsterFireRocket (start, dir, 50, CARRIER_ROCKET_SPEED, MZ2_CARRIER_ROCKET_2); //3 G_ProjectSource (Entity->State.GetOrigin(), MonsterFlashOffsets[MZ2_CARRIER_ROCKET_3], angles, start); PredictAim (*Entity->Enemy, start, CARRIER_ROCKET_SPEED, false, 0, &dir, NULL); MonsterFireRocket (start, dir, 50, CARRIER_ROCKET_SPEED, MZ2_CARRIER_ROCKET_3); //4 G_ProjectSource (Entity->State.GetOrigin(), MonsterFlashOffsets[MZ2_CARRIER_ROCKET_4], angles, start); PredictAim (*Entity->Enemy, start, CARRIER_ROCKET_SPEED, false, 0.15f, &dir, NULL); MonsterFireRocket (start, dir, 50, CARRIER_ROCKET_SPEED, MZ2_CARRIER_ROCKET_4); }
void WidowDisrupt(edict_t *self) { vec3_t start; vec3_t dir; vec3_t forward, right; float len; if (!self) { return; } AngleVectors(self->s.angles, forward, right, NULL); G_ProjectSource(self->s.origin, monster_flash_offset[MZ2_WIDOW_DISRUPTOR], forward, right, start); VectorSubtract(self->pos1, self->enemy->s.origin, dir); len = VectorLength(dir); if (len < 30) { VectorSubtract(self->pos1, start, dir); VectorNormalize(dir); monster_fire_tracker(self, start, dir, 20, 500, self->enemy, MZ2_WIDOW_DISRUPTOR); } else { PredictAim(self->enemy, start, 1200, true, 0, dir, NULL); monster_fire_tracker(self, start, dir, 20, 1200, NULL, MZ2_WIDOW_DISRUPTOR); } }
void WidowDisrupt (edict_t *self) { vec3_t start; vec3_t dir; vec3_t forward, right; float len; AngleVectors (self->s.angles, forward, right, NULL); G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_WIDOW_DISRUPTOR], forward, right, start); VectorSubtract (self->pos1, self->enemy->s.origin, dir); len = VectorLength (dir); if (len < 30) { // if ((g_showlogic) && (g_showlogic->value)) // gi.dprintf ("target locked - dist %2.2f\n", len); // calc direction to where we targeted VectorSubtract (self->pos1, start, dir); VectorNormalize (dir); monster_fire_tracker(self, start, dir, 20, 500, self->enemy, MZ2_WIDOW_DISRUPTOR); } else { // if ((g_showlogic) && (g_showlogic->value)) // gi.dprintf ("target missed - dist %2.2f\n", len); PredictAim (self->enemy, start, 1200, true, 0, dir, NULL); // VectorSubtract (self->enemy->s.origin, start, dir); // VectorNormalize (dir); monster_fire_tracker(self, start, dir, 20, 1200, NULL, MZ2_WIDOW_DISRUPTOR); } }
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 WidowBlaster (edict_t *self) { vec3_t forward, right, target, vec, targ_angles; vec3_t start; int flashnum; int effect; if (!self->enemy) return; shotsfired++; if (!(shotsfired % 4)) effect = EF_BLASTER; else effect = 0; AngleVectors (self->s.angles, forward, right, NULL); if ((self->s.frame >= FRAME_spawn05) && (self->s.frame <= FRAME_spawn13)) { // sweep flashnum = MZ2_WIDOW_BLASTER_SWEEP1 + self->s.frame - FRAME_spawn05; G_ProjectSource (self->s.origin, monster_flash_offset[flashnum], forward, right, start); VectorSubtract (self->enemy->s.origin, start, target); vectoangles2 (target, targ_angles); VectorCopy (self->s.angles, vec); vec[PITCH] += targ_angles[PITCH]; vec[YAW] -= sweep_angles[flashnum-MZ2_WIDOW_BLASTER_SWEEP1]; AngleVectors (vec, forward, NULL, NULL); monster_fire_blaster2 (self, start, forward, BLASTER2_DAMAGE*widow_damage_multiplier, 1000, flashnum, effect); } else if ((self->s.frame >= FRAME_fired02a) && (self->s.frame <= FRAME_fired20)) { vec3_t angles; float aim_angle, target_angle; float error; self->monsterinfo.aiflags |= AI_MANUAL_STEERING; self->monsterinfo.nextframe = WidowTorso (self); if (!self->monsterinfo.nextframe) self->monsterinfo.nextframe = self->s.frame; if (self->s.frame == FRAME_fired02a) flashnum = MZ2_WIDOW_BLASTER_0; else flashnum = MZ2_WIDOW_BLASTER_100 + self->s.frame - FRAME_fired03; G_ProjectSource (self->s.origin, monster_flash_offset[flashnum], forward, right, start); PredictAim (self->enemy, start, 1000, true, ((random()*0.1)-0.05), forward, NULL); // clamp it to within 10 degrees of the aiming angle (where she's facing) vectoangles2 (forward, angles); // give me 100 -> -70 aim_angle = 100 - (10*(flashnum-MZ2_WIDOW_BLASTER_100)); if (aim_angle <= 0) aim_angle += 360; target_angle = self->s.angles[YAW] - angles[YAW]; if (target_angle <= 0) target_angle += 360; error = aim_angle - target_angle; // positive error is to entity's left, aka positive direction in engine // unfortunately, I decided that for the aim_angle, positive was right. *sigh* if (error > VARIANCE) { angles[YAW] = (self->s.angles[YAW] - aim_angle) + VARIANCE; AngleVectors (angles, forward, NULL, NULL); } else if (error < -VARIANCE) { angles[YAW] = (self->s.angles[YAW] - aim_angle) - VARIANCE; AngleVectors (angles, forward, NULL, NULL); } monster_fire_blaster2 (self, start, forward, BLASTER2_DAMAGE*widow_damage_multiplier, 1000, flashnum, effect); } else if ((self->s.frame >= FRAME_run01) && (self->s.frame <= FRAME_run08)) { flashnum = MZ2_WIDOW_RUN_1 + self->s.frame - FRAME_run01; G_ProjectSource (self->s.origin, monster_flash_offset[flashnum], forward, right, start); VectorSubtract (self->enemy->s.origin, start, target); target[2] += self->enemy->viewheight; monster_fire_blaster2 (self, start, target, BLASTER2_DAMAGE*widow_damage_multiplier, 1000, flashnum, effect); } }
void WidowBlaster (edict_t *self) { vec3_t forward, right, target, vec, targ_angles; vec3_t start, end; int flashnum; int effect; if (!self->enemy) return; shotsfired++; if (!(shotsfired % 4)) effect = EF_BLASTER; else effect = 0; AngleVectors (self->s.angles, forward, right, NULL); if ((self->s.frame >= FRAME_spawn05) && (self->s.frame <= FRAME_spawn13)) { // sweep flashnum = MZ2_WIDOW_BLASTER_SWEEP1 + self->s.frame - FRAME_spawn05; G_ProjectSource (self->s.origin, monster_flash_offset[flashnum], forward, right, start); VectorCopy(self->enemy->s.origin, end); // 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, target); vectoangles2 (target, targ_angles); VectorCopy (self->s.angles, vec); vec[PITCH] += targ_angles[PITCH]; vec[YAW] -= sweep_angles[flashnum-MZ2_WIDOW_BLASTER_SWEEP1]; AngleVectors (vec, forward, NULL, NULL); // monster_fire_blaster (self, start, forward, BLASTER2_DAMAGE*widow_damage_multiplier, 1000, flashnum, (effect!=0)?(effect|EF_TRACKER):0, BLASTER_GREEN); monster_fire_blaster2 (self, start, forward, BLASTER2_DAMAGE*widow_damage_multiplier, 1000, flashnum, effect); /* if (self->s.frame == FRAME_spawn13) { VectorMA (start, 1024, forward, debugend); gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_DEBUGTRAIL); gi.WritePosition (start); gi.WritePosition (debugend); gi.multicast (start, MULTICAST_ALL); drawbbox (self); self->monsterinfo.aiflags |= AI_HOLD_FRAME|AI_MANUAL_STEERING; } */ } else if ((self->s.frame >= FRAME_fired02a) && (self->s.frame <= FRAME_fired20)) { vec3_t angles; float aim_angle, target_angle; float error; self->monsterinfo.aiflags |= AI_MANUAL_STEERING; self->monsterinfo.nextframe = WidowTorso (self); if (!self->monsterinfo.nextframe) self->monsterinfo.nextframe = self->s.frame; // if ((g_showlogic) && (g_showlogic->value)) // gi.dprintf ("%d\n", self->monsterinfo.nextframe); if (self->s.frame == FRAME_fired02a) flashnum = MZ2_WIDOW_BLASTER_0; else flashnum = MZ2_WIDOW_BLASTER_100 + self->s.frame - FRAME_fired03; G_ProjectSource (self->s.origin, monster_flash_offset[flashnum], forward, right, start); PredictAim (self->enemy, start, 1000, true, ((random()*0.1)-0.05), forward, NULL); // clamp it to within 10 degrees of the aiming angle (where she's facing) vectoangles2 (forward, angles); // give me 100 -> -70 aim_angle = 100 - (10*(flashnum-MZ2_WIDOW_BLASTER_100)); if (aim_angle <= 0) aim_angle += 360; target_angle = self->s.angles[YAW] - angles[YAW]; if (target_angle <= 0) target_angle += 360; error = aim_angle - target_angle; // positive error is to entity's left, aka positive direction in engine // unfortunately, I decided that for the aim_angle, positive was right. *sigh* if (error > VARIANCE) { // if ((g_showlogic) && (g_showlogic->value)) // gi.dprintf ("angle %2.2f (really %2.2f) (%2.2f off of %2.2f) corrected to", target_angle, angles[YAW], error, aim_angle); angles[YAW] = (self->s.angles[YAW] - aim_angle) + VARIANCE; // if ((g_showlogic) && (g_showlogic->value)) // { // if (angles[YAW] <= 0) // angles[YAW] += 360; // gi.dprintf (" %2.2f\n", angles[YAW]); // } AngleVectors (angles, forward, NULL, NULL); } else if (error < -VARIANCE) { // if ((g_showlogic) && (g_showlogic->value)) // gi.dprintf ("angle %2.2f (really %2.2f) (%2.2f off of %2.2f) corrected to", target_angle, angles[YAW], error, aim_angle); angles[YAW] = (self->s.angles[YAW] - aim_angle) - VARIANCE; // if ((g_showlogic) && (g_showlogic->value)) // { // if (angles[YAW] <= 0) // angles[YAW] += 360; // gi.dprintf (" %2.2f\n", angles[YAW]); // } AngleVectors (angles, forward, NULL, NULL); } // gi.dprintf ("%2.2f - %2.2f - %2.2f - %2.2f\n", aim_angle, self->s.angles[YAW] - angles[YAW], target_angle, error); // gi.dprintf ("%2.2f - %2.2f - %2.2f\n", angles[YAW], aim_angle, self->s.angles[YAW]); /* if (self->s.frame == FRAME_fired20) { VectorMA (start, 512, forward, debugend); gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_DEBUGTRAIL); gi.WritePosition (start); gi.WritePosition (forward); gi.multicast (start, MULTICAST_ALL); drawbbox (self); self->monsterinfo.aiflags |= AI_HOLD_FRAME; self->monsterinfo.nextframe = FRAME_fired20; self->monsterinfo.aiflags |= AI_MANUAL_STEERING; } */ /* if (!(self->plat2flags % 3)) effect = EF_HYPERBLASTER; else effect = 0; self->plat2flags ++; */ // monster_fire_blaster (self, start, forward, BLASTER2_DAMAGE*widow_damage_multiplier, 1000, flashnum, (effect!=0)?(effect|EF_TRACKER):0, BLASTER_GREEN); monster_fire_blaster2 (self, start, forward, BLASTER2_DAMAGE*widow_damage_multiplier, 1000, flashnum, effect); } else if ((self->s.frame >= FRAME_run01) && (self->s.frame <= FRAME_run08)) { flashnum = MZ2_WIDOW_RUN_1 + self->s.frame - FRAME_run01; G_ProjectSource (self->s.origin, monster_flash_offset[flashnum], forward, right, start); VectorCopy(self->enemy->s.origin, end); // 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, target); target[2] += self->enemy->viewheight; // monster_fire_blaster (self, start, target, BLASTER2_DAMAGE*widow_damage_multiplier, 1000, flashnum, (effect!=0)?(effect|EF_TRACKER):0, BLASTER_GREEN); monster_fire_blaster2 (self, start, target, BLASTER2_DAMAGE*widow_damage_multiplier, 1000, flashnum, effect); } // else // { // if ((g_showlogic) && (g_showlogic->value)) // gi.dprintf ("widow: firing on non-fire frame!\n"); // } }