diff --git a/src/monster/widow/widow.c b/src/monster/widow/widow.c index 66fccb7..739d5da 100644 --- a/src/monster/widow/widow.c +++ b/src/monster/widow/widow.c @@ -1,42 +1,34 @@ -/* -============================================================================== - -black widow - -============================================================================== -*/ - -// self->timestamp used to prevent rapid fire of railgun -// self->plat2flags used for fire count (flashes) -// self->monsterinfo.pausetime used for timing of blaster shots - +/* ======================================================================= + * + * Black Window (stage 1). + * + * ======================================================================= + */ + #include "../../header/local.h" #include "widow.h" -#define NUM_STALKERS_SPAWNED 6 // max # of stalkers she can spawn +#define NUM_STALKERS_SPAWNED 6 /* max # of stalkers she can spawn */ -#define RAIL_TIME 3 -#define BLASTER_TIME 2 -#define BLASTER2_DAMAGE 10 -#define WIDOW_RAIL_DAMAGE 50 +#define RAIL_TIME 3 +#define BLASTER_TIME 2 +#define BLASTER2_DAMAGE 10 +#define WIDOW_RAIL_DAMAGE 50 +#define VARIANCE 15.0 -#define DRAWBBOX NULL -#define SHOWME NULL // showme +void BossExplode(edict_t *self); +qboolean infront(edict_t *self, edict_t *other); -void BossExplode (edict_t *self); - -qboolean infront (edict_t *self, edict_t *other); - -static int sound_pain1; -static int sound_pain2; -static int sound_pain3; -static int sound_search1; -static int sound_rail; +static int sound_pain1; +static int sound_pain2; +static int sound_pain3; +static int sound_search1; +static int sound_rail; static unsigned long shotsfired; static vec3_t spawnpoints[] = { - {30, 100, 16}, + {30, 100, 16}, {30, -100, 16} }; @@ -46,78 +38,107 @@ static vec3_t beameffects[] = { }; static float sweep_angles[] = { -// 32.0, 26.0, 20.0, 11.5, 3.0, -8.0, -13.0, -27.0, -41.0 32.0, 26.0, 20.0, 10.0, 0.0, -6.5, -13.0, -27.0, -41.0 }; vec3_t stalker_mins = {-28, -28, -18}; vec3_t stalker_maxs = {28, 28, 18}; - -unsigned int widow_damage_multiplier; - -void widow_run (edict_t *self); -void widow_stand (edict_t *self); -void widow_dead (edict_t *self); -void widow_attack (edict_t *self); -void widow_attack_blaster (edict_t *self); -void widow_reattack_blaster (edict_t *self); -void widow_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point); - -void widow_start_spawn (edict_t *self); -void widow_done_spawn (edict_t *self); -void widow_spawn_check (edict_t *self); -void widow_prep_spawn (edict_t *self); -void widow_attack_rail (edict_t *self); - -void widow_start_run_5 (edict_t *self); -void widow_start_run_10 (edict_t *self); -void widow_start_run_12 (edict_t *self); - -void WidowCalcSlots (edict_t *self); - -void drawbbox (edict_t *self); - -void showme (edict_t *self) -{ - gi.dprintf ("frame %d\n", self->s.frame); -} - -void widow_search (edict_t *self) -{ -} - -void widow_sight (edict_t *self, edict_t *other) -{ - self->monsterinfo.pausetime = 0; -} - + mmove_t widow_move_attack_post_blaster; mmove_t widow_move_attack_post_blaster_r; mmove_t widow_move_attack_post_blaster_l; mmove_t widow_move_attack_blaster; +mmove_t widow_move_attack_rail; +mmove_t widow_move_attack_rail_l; +mmove_t widow_move_attack_rail_r; + +unsigned int widow_damage_multiplier; -float target_angle (edict_t *self) +void widow_run(edict_t *self); +void widow_stand(edict_t *self); +void widow_dead(edict_t *self); +void widow_attack(edict_t *self); +void widow_attack_blaster(edict_t *self); +void widow_reattack_blaster(edict_t *self); +void widow_die(edict_t *self, edict_t *inflictor, edict_t *attacker, + int damage, vec3_t point); + +void widow_start_spawn(edict_t *self); +void widow_done_spawn(edict_t *self); +void widow_spawn_check(edict_t *self); +void widow_prep_spawn(edict_t *self); +void widow_attack_rail(edict_t *self); + +void widow_start_run_5(edict_t *self); +void widow_start_run_10(edict_t *self); +void widow_start_run_12(edict_t *self); + +void WidowCalcSlots(edict_t *self); + +void drawbbox(edict_t *self); + +void +showme(edict_t *self) +{ + if (!self) + { + return; + } + + gi.dprintf("frame %d\n", self->s.frame); +} + +void +widow_search(edict_t *self) +{ +} + +void +widow_sight(edict_t *self, edict_t *other /* unused */) +{ + if (!self) + { + return; + } + + self->monsterinfo.pausetime = 0; +} + +float +target_angle(edict_t *self) { vec3_t target; float enemy_yaw; - - VectorSubtract (self->s.origin, self->enemy->s.origin, target); + + if (!self) + { + return 0.0; + } + + VectorSubtract(self->s.origin, self->enemy->s.origin, target); enemy_yaw = self->s.angles[YAW] - vectoyaw2(target); - if (enemy_yaw < 0) - enemy_yaw += 360.0; - // this gets me 0 degrees = forward + if (enemy_yaw < 0) + { + enemy_yaw += 360.0; + } + enemy_yaw -= 180.0; - // positive is to right, negative to left return enemy_yaw; } -int WidowTorso (edict_t *self) +int +WidowTorso(edict_t *self) { float enemy_yaw; - - enemy_yaw = target_angle (self); + + if (!self) + { + return 0; + } + + enemy_yaw = target_angle(self); if (enemy_yaw >= 105) { @@ -134,79 +155,129 @@ int WidowTorso (edict_t *self) } if (enemy_yaw >= 95) + { return FRAME_fired03; + } else if (enemy_yaw >= 85) + { return FRAME_fired04; + } else if (enemy_yaw >= 75) + { return FRAME_fired05; + } else if (enemy_yaw >= 65) + { return FRAME_fired06; + } else if (enemy_yaw >= 55) + { return FRAME_fired07; + } else if (enemy_yaw >= 45) + { return FRAME_fired08; + } else if (enemy_yaw >= 35) + { return FRAME_fired09; + } else if (enemy_yaw >= 25) + { return FRAME_fired10; + } else if (enemy_yaw >= 15) + { return FRAME_fired11; + } else if (enemy_yaw >= 5) + { return FRAME_fired12; + } else if (enemy_yaw >= -5) + { return FRAME_fired13; + } else if (enemy_yaw >= -15) + { return FRAME_fired14; + } else if (enemy_yaw >= -25) + { return FRAME_fired15; + } else if (enemy_yaw >= -35) + { return FRAME_fired16; + } else if (enemy_yaw >= -45) + { return FRAME_fired17; + } else if (enemy_yaw >= -55) + { return FRAME_fired18; + } else if (enemy_yaw >= -65) + { return FRAME_fired19; + } else if (enemy_yaw >= -75) + { return FRAME_fired20; + } return 1; } -#define VARIANCE 15.0 - -void WidowBlaster (edict_t *self) +void +WidowBlaster(edict_t *self) { - vec3_t forward, right, target, vec, targ_angles; - vec3_t start; - int flashnum; - int effect; - - if (!self->enemy) + vec3_t forward, right, target, vec, targ_angles; + vec3_t start; + int flashnum; + int effect; + + if (!self) + { return; + } + + if (!self->enemy) + { + return; + } shotsfired++; - if (!(shotsfired % 4)) - effect = EF_BLASTER; - else - effect = 0; - AngleVectors (self->s.angles, forward, right, NULL); + 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 + /* 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); + 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]; + 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); + 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)) { @@ -216,131 +287,172 @@ void WidowBlaster (edict_t *self) self->monsterinfo.aiflags |= AI_MANUAL_STEERING; - self->monsterinfo.nextframe = WidowTorso (self); + 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); + 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); + 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); + aim_angle = 100 - (10 * (flashnum - MZ2_WIDOW_BLASTER_100)); - // 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* + /* 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); + AngleVectors(angles, forward, NULL, NULL); } else if (error < -VARIANCE) { angles[YAW] = (self->s.angles[YAW] - aim_angle) - VARIANCE; - AngleVectors (angles, forward, NULL, NULL); + AngleVectors(angles, forward, NULL, NULL); } - monster_fire_blaster2 (self, start, forward, BLASTER2_DAMAGE*widow_damage_multiplier, 1000, flashnum, effect); + 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); + 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); + monster_fire_blaster2(self, start, target, BLASTER2_DAMAGE * widow_damage_multiplier, + 1000, flashnum, effect); } -} +} -void WidowSpawn (edict_t *self) +void +WidowSpawn(edict_t *self) { - vec3_t f, r, u, offset, startpoint, spawnpoint; - edict_t *ent, *designated_enemy; - int i; - - AngleVectors (self->s.angles, f, r, u); - - for (i=0; i < 2; i++) + vec3_t f, r, u, offset, startpoint, spawnpoint; + edict_t *ent, *designated_enemy; + int i; + + if (!self) { - VectorCopy (spawnpoints[i], offset); + return; + } + + AngleVectors(self->s.angles, f, r, u); - G_ProjectSource2 (self->s.origin, offset, f, r, u, startpoint); + for (i = 0; i < 2; i++) + { + VectorCopy(spawnpoints[i], offset); - if (FindSpawnPoint (startpoint, stalker_mins, stalker_maxs, spawnpoint, 64)) + G_ProjectSource2(self->s.origin, offset, f, r, u, startpoint); + + if (FindSpawnPoint(startpoint, stalker_mins, stalker_maxs, spawnpoint, + 64)) { - ent = CreateGroundMonster (spawnpoint, self->s.angles, stalker_mins, stalker_maxs, "monster_stalker", 256); + ent = CreateGroundMonster(spawnpoint, self->s.angles, stalker_mins, stalker_maxs, + "monster_stalker", 256); if (!ent) + { continue; - + } + self->monsterinfo.monster_used++; ent->monsterinfo.commander = self; ent->nextthink = level.time; - ent->think (ent); - - ent->monsterinfo.aiflags |= AI_SPAWNED_WIDOW|AI_DO_NOT_COUNT|AI_IGNORE_SHOTS; + ent->think(ent); + + ent->monsterinfo.aiflags |= AI_SPAWNED_WIDOW | AI_DO_NOT_COUNT | AI_IGNORE_SHOTS; designated_enemy = self->enemy; if ((designated_enemy->inuse) && (designated_enemy->health > 0)) { ent->enemy = designated_enemy; - FoundTarget (ent); + FoundTarget(ent); ent->monsterinfo.attack(ent); } } } } -void widow_spawn_check (edict_t *self) -{ +void +widow_spawn_check(edict_t *self) +{ + if (!self) + { + return; + } + WidowBlaster(self); - WidowSpawn (self); + WidowSpawn(self); } -void widow_ready_spawn (edict_t *self) +void +widow_ready_spawn(edict_t *self) { - vec3_t f, r, u, offset, startpoint, spawnpoint; - int i; - - WidowBlaster(self); - AngleVectors (self->s.angles, f, r, u); - - for (i=0; i < 2; i++) + vec3_t f, r, u, offset, startpoint, spawnpoint; + int i; + + if (!self) { - VectorCopy (spawnpoints[i], offset); - G_ProjectSource2 (self->s.origin, offset, f, r, u, startpoint); - if (FindSpawnPoint (startpoint, stalker_mins, stalker_maxs, spawnpoint, 64)) + return; + } + + WidowBlaster(self); + AngleVectors(self->s.angles, f, r, u); + + for (i = 0; i < 2; i++) + { + VectorCopy(spawnpoints[i], offset); + G_ProjectSource2(self->s.origin, offset, f, r, u, startpoint); + + if (FindSpawnPoint(startpoint, stalker_mins, stalker_maxs, spawnpoint, + 64)) { - SpawnGrow_Spawn (spawnpoint, 1); + SpawnGrow_Spawn(spawnpoint, 1); } } } -void widow_step (edict_t *self) +void +widow_step(edict_t *self) { - gi.sound (self, CHAN_BODY, gi.soundindex("widow/bwstep3.wav"), 1, ATTN_NORM, 0); + gi.sound(self, CHAN_BODY, gi.soundindex("widow/bwstep3.wav"), 1, ATTN_NORM, 0); } -mframe_t widow_frames_stand [] = -{ +mframe_t widow_frames_stand[] = { {ai_stand, 0, NULL}, {ai_stand, 0, NULL}, {ai_stand, 0, NULL}, @@ -353,164 +465,232 @@ mframe_t widow_frames_stand [] = {ai_stand, 0, NULL}, {ai_stand, 0, NULL} }; -mmove_t widow_move_stand = {FRAME_idle01, FRAME_idle11, widow_frames_stand, NULL}; -mframe_t widow_frames_walk [] = -{ - // auto generated numbers - {ai_walk, 2.79, widow_step}, - {ai_walk, 2.77, NULL}, - {ai_walk, 3.53, NULL}, - {ai_walk, 3.97, NULL}, - {ai_walk, 4.13, NULL}, //5 - {ai_walk, 4.09, NULL}, - {ai_walk, 3.84, NULL}, - {ai_walk, 3.62, widow_step}, - {ai_walk, 3.29, NULL}, - {ai_walk, 6.08, NULL}, //10 - {ai_walk, 6.94, NULL}, - {ai_walk, 5.73, NULL}, - {ai_walk, 2.85, NULL} +mmove_t widow_move_stand = { + FRAME_idle01, + FRAME_idle11, + widow_frames_stand, + NULL }; -mmove_t widow_move_walk = {FRAME_walk01, FRAME_walk13, widow_frames_walk, NULL}; - -mframe_t widow_frames_run [] = -{ - {ai_run, 2.79, widow_step}, - {ai_run, 2.77, NULL}, - {ai_run, 3.53, NULL}, - {ai_run, 3.97, NULL}, - {ai_run, 4.13, NULL}, //5 - {ai_run, 4.09, NULL}, - {ai_run, 3.84, NULL}, - {ai_run, 3.62, widow_step}, - {ai_run, 3.29, NULL}, - {ai_run, 6.08, NULL}, //10 - {ai_run, 6.94, NULL}, - {ai_run, 5.73, NULL}, - {ai_run, 2.85, NULL} +mframe_t widow_frames_walk[] = { + /* auto generated numbers */ + {ai_walk, 2.79, widow_step}, + {ai_walk, 2.77, NULL}, + {ai_walk, 3.53, NULL}, + {ai_walk, 3.97, NULL}, + {ai_walk, 4.13, NULL}, /* 5 */ + {ai_walk, 4.09, NULL}, + {ai_walk, 3.84, NULL}, + {ai_walk, 3.62, widow_step}, + {ai_walk, 3.29, NULL}, + {ai_walk, 6.08, NULL}, /* 10 */ + {ai_walk, 6.94, NULL}, + {ai_walk, 5.73, NULL}, + {ai_walk, 2.85, NULL} }; -mmove_t widow_move_run = {FRAME_walk01, FRAME_walk13, widow_frames_run, NULL}; -void widow_stepshoot (edict_t *self) -{ - gi.sound (self, CHAN_BODY, gi.soundindex("widow/bwstep2.wav"), 1, ATTN_NORM,0); - WidowBlaster (self); +mmove_t widow_move_walk = { + FRAME_walk01, + FRAME_walk13, + widow_frames_walk, + NULL +}; + +mframe_t widow_frames_run[] = { + {ai_run, 2.79, widow_step}, + {ai_run, 2.77, NULL}, + {ai_run, 3.53, NULL}, + {ai_run, 3.97, NULL}, + {ai_run, 4.13, NULL}, /* 5 */ + {ai_run, 4.09, NULL}, + {ai_run, 3.84, NULL}, + {ai_run, 3.62, widow_step}, + {ai_run, 3.29, NULL}, + {ai_run, 6.08, NULL}, /* 10 */ + {ai_run, 6.94, NULL}, + {ai_run, 5.73, NULL}, + {ai_run, 2.85, NULL} +}; + +mmove_t widow_move_run = { + FRAME_walk01, + FRAME_walk13, + widow_frames_run, + NULL +}; + +void +widow_stepshoot(edict_t *self) +{ + if (!self) + { + return; + } + + gi.sound(self, CHAN_BODY, gi.soundindex("widow/bwstep2.wav"), 1, ATTN_NORM, 0); + WidowBlaster(self); } -mframe_t widow_frames_run_attack [] = -{ - {ai_charge, 13, widow_stepshoot}, - {ai_charge, 11.72, WidowBlaster}, - {ai_charge, 18.04, WidowBlaster}, - {ai_charge, 14.58, WidowBlaster}, - {ai_charge, 13, widow_stepshoot}, //5 - {ai_charge, 12.12, WidowBlaster}, - {ai_charge, 19.63, WidowBlaster}, - {ai_charge, 11.37, WidowBlaster} +mframe_t widow_frames_run_attack[] = { + {ai_charge, 13, widow_stepshoot}, + {ai_charge, 11.72, WidowBlaster}, + {ai_charge, 18.04, WidowBlaster}, + {ai_charge, 14.58, WidowBlaster}, + {ai_charge, 13, widow_stepshoot}, /* 5 */ + {ai_charge, 12.12, WidowBlaster}, + {ai_charge, 19.63, WidowBlaster}, + {ai_charge, 11.37, WidowBlaster} }; -mmove_t widow_move_run_attack = {FRAME_run01, FRAME_run08, widow_frames_run_attack, widow_run}; +mmove_t widow_move_run_attack = { + FRAME_run01, + FRAME_run08, + widow_frames_run_attack, + widow_run +}; -// -// These three allow specific entry into the run sequence -// +/* These three allow specific entry into the run sequence */ -void widow_start_run_5 (edict_t *self) -{ +void +widow_start_run_5(edict_t *self) +{ + if (!self) + { + return; + } + self->monsterinfo.currentmove = &widow_move_run; self->monsterinfo.nextframe = FRAME_walk05; } -void widow_start_run_10 (edict_t *self) -{ +void +widow_start_run_10(edict_t *self) +{ + if (!self) + { + return; + } + self->monsterinfo.currentmove = &widow_move_run; self->monsterinfo.nextframe = FRAME_walk10; } -void widow_start_run_12 (edict_t *self) -{ +void +widow_start_run_12(edict_t *self) +{ + if (!self) + { + return; + } + self->monsterinfo.currentmove = &widow_move_run; self->monsterinfo.nextframe = FRAME_walk12; } - -mframe_t widow_frames_attack_pre_blaster [] = -{ - {ai_charge, 0, NULL}, - {ai_charge, 0, NULL}, - {ai_charge, 0, widow_attack_blaster} +mframe_t widow_frames_attack_pre_blaster[] = { + {ai_charge, 0, NULL}, + {ai_charge, 0, NULL}, + {ai_charge, 0, widow_attack_blaster} }; -mmove_t widow_move_attack_pre_blaster = {FRAME_fired01, FRAME_fired02a, widow_frames_attack_pre_blaster, NULL}; -// Loop this -mframe_t widow_frames_attack_blaster [] = -{ - {ai_charge, 0, widow_reattack_blaster}, // str{aight ahead - {ai_charge, 0, widow_reattack_blaster}, // 100 degrees right - {ai_charge, 0, widow_reattack_blaster}, - {ai_charge, 0, widow_reattack_blaster}, - {ai_charge, 0, widow_reattack_blaster}, - {ai_charge, 0, widow_reattack_blaster}, - {ai_charge, 0, widow_reattack_blaster}, // 50 degrees right - {ai_charge, 0, widow_reattack_blaster}, - {ai_charge, 0, widow_reattack_blaster}, - {ai_charge, 0, widow_reattack_blaster}, - {ai_charge, 0, widow_reattack_blaster}, - {ai_charge, 0, widow_reattack_blaster}, // str{aight - {ai_charge, 0, widow_reattack_blaster}, - {ai_charge, 0, widow_reattack_blaster}, - {ai_charge, 0, widow_reattack_blaster}, - {ai_charge, 0, widow_reattack_blaster}, - {ai_charge, 0, widow_reattack_blaster}, // 50 degrees left - {ai_charge, 0, widow_reattack_blaster}, - {ai_charge, 0, widow_reattack_blaster} // 70 degrees left +mmove_t widow_move_attack_pre_blaster = { + FRAME_fired01, + FRAME_fired02a, + widow_frames_attack_pre_blaster, + NULL }; -mmove_t widow_move_attack_blaster = {FRAME_fired02a, FRAME_fired20, widow_frames_attack_blaster, NULL}; -mframe_t widow_frames_attack_post_blaster [] = -{ - {ai_charge, 0, NULL}, - {ai_charge, 0, NULL} +mframe_t widow_frames_attack_blaster[] = { + {ai_charge, 0, widow_reattack_blaster}, /* straight ahead */ + {ai_charge, 0, widow_reattack_blaster}, /* 100 degrees right */ + {ai_charge, 0, widow_reattack_blaster}, + {ai_charge, 0, widow_reattack_blaster}, + {ai_charge, 0, widow_reattack_blaster}, + {ai_charge, 0, widow_reattack_blaster}, + {ai_charge, 0, widow_reattack_blaster}, /* 50 degrees right */ + {ai_charge, 0, widow_reattack_blaster}, + {ai_charge, 0, widow_reattack_blaster}, + {ai_charge, 0, widow_reattack_blaster}, + {ai_charge, 0, widow_reattack_blaster}, + {ai_charge, 0, widow_reattack_blaster}, /* straight */ + {ai_charge, 0, widow_reattack_blaster}, + {ai_charge, 0, widow_reattack_blaster}, + {ai_charge, 0, widow_reattack_blaster}, + {ai_charge, 0, widow_reattack_blaster}, + {ai_charge, 0, widow_reattack_blaster}, /* 50 degrees left */ + {ai_charge, 0, widow_reattack_blaster}, + {ai_charge, 0, widow_reattack_blaster} /* 70 degrees left */ }; -mmove_t widow_move_attack_post_blaster = {FRAME_fired21, FRAME_fired22, widow_frames_attack_post_blaster, widow_run}; -mframe_t widow_frames_attack_post_blaster_r [] = -{ - {ai_charge, -2, NULL}, - {ai_charge, -10, NULL}, - {ai_charge, -2, NULL}, - {ai_charge, 0, NULL}, - {ai_charge, 0, widow_start_run_12} +mmove_t widow_move_attack_blaster = { + FRAME_fired02a, + FRAME_fired20, + widow_frames_attack_blaster, + NULL }; -mmove_t widow_move_attack_post_blaster_r = {FRAME_transa01, FRAME_transa05, widow_frames_attack_post_blaster_r, NULL}; -mframe_t widow_frames_attack_post_blaster_l [] = -{ - {ai_charge, 0, NULL}, - {ai_charge, 14, NULL}, - {ai_charge, -2, NULL}, - {ai_charge, 10, NULL}, - {ai_charge, 10, widow_start_run_12} +mframe_t widow_frames_attack_post_blaster[] = { + {ai_charge, 0, NULL}, + {ai_charge, 0, NULL} }; -mmove_t widow_move_attack_post_blaster_l = {FRAME_transb01, FRAME_transb05, widow_frames_attack_post_blaster_l, NULL}; -mmove_t widow_move_attack_rail; -mmove_t widow_move_attack_rail_l; -mmove_t widow_move_attack_rail_r; +mmove_t widow_move_attack_post_blaster = { + FRAME_fired21, + FRAME_fired22, + widow_frames_attack_post_blaster, + widow_run +}; -void WidowRail (edict_t *self) +mframe_t widow_frames_attack_post_blaster_r[] = { + {ai_charge, -2, NULL}, + {ai_charge, -10, NULL}, + {ai_charge, -2, NULL}, + {ai_charge, 0, NULL}, + {ai_charge, 0, widow_start_run_12} +}; + +mmove_t widow_move_attack_post_blaster_r = { + FRAME_transa01, + FRAME_transa05, + widow_frames_attack_post_blaster_r, + NULL +}; + +mframe_t widow_frames_attack_post_blaster_l[] = { + {ai_charge, 0, NULL}, + {ai_charge, 14, NULL}, + {ai_charge, -2, NULL}, + {ai_charge, 10, NULL}, + {ai_charge, 10, widow_start_run_12} +}; + +mmove_t widow_move_attack_post_blaster_l = { + FRAME_transb01, + FRAME_transb05, + widow_frames_attack_post_blaster_l, + NULL +}; + +void +WidowRail(edict_t *self) { - vec3_t start; - vec3_t dir; - vec3_t forward, right; - int flash = 0; - - AngleVectors (self->s.angles, forward, right, NULL); + vec3_t start; + vec3_t dir; + vec3_t forward, right; + int flash = 0; + + if (!self) + { + return; + } + + AngleVectors(self->s.angles, forward, right, NULL); if (self->monsterinfo.currentmove == &widow_move_attack_rail) + { flash = MZ2_WIDOW_RAIL; + } else if (self->monsterinfo.currentmove == &widow_move_attack_rail_l) { flash = MZ2_WIDOW_RAIL_LEFT; @@ -520,43 +700,67 @@ void WidowRail (edict_t *self) flash = MZ2_WIDOW_RAIL_RIGHT; } - G_ProjectSource (self->s.origin, monster_flash_offset[flash], forward, right, start); + G_ProjectSource(self->s.origin, monster_flash_offset[flash], forward, + right, start); - // calc direction to where we targeted - VectorSubtract (self->pos1, start, dir); - VectorNormalize (dir); + /* calc direction to where we targeted */ + VectorSubtract(self->pos1, start, dir); + VectorNormalize(dir); - monster_fire_railgun (self, start, dir, WIDOW_RAIL_DAMAGE*widow_damage_multiplier, 100, flash); + monster_fire_railgun(self, start, dir, WIDOW_RAIL_DAMAGE * widow_damage_multiplier, + 100, flash); self->timestamp = level.time + RAIL_TIME; } -void WidowSaveLoc (edict_t *self) -{ - VectorCopy (self->enemy->s.origin, self->pos1); //save for aiming the shot +void +WidowSaveLoc(edict_t *self) +{ + if (!self) + { + return; + } + + VectorCopy(self->enemy->s.origin, self->pos1); /* save for aiming the shot */ self->pos1[2] += self->enemy->viewheight; -}; +} -void widow_start_rail (edict_t *self) -{ +void +widow_start_rail(edict_t *self) +{ + if (!self) + { + return; + } + self->monsterinfo.aiflags |= AI_MANUAL_STEERING; } -void widow_rail_done (edict_t *self) -{ +void +widow_rail_done(edict_t *self) +{ + if (!self) + { + return; + } + self->monsterinfo.aiflags &= ~AI_MANUAL_STEERING; } -mframe_t widow_frames_attack_pre_rail [] = -{ - {ai_charge, 0, widow_start_rail}, - {ai_charge, 0, NULL}, - {ai_charge, 0, NULL}, - {ai_charge, 0, widow_attack_rail} +mframe_t widow_frames_attack_pre_rail[] = { + {ai_charge, 0, widow_start_rail}, + {ai_charge, 0, NULL}, + {ai_charge, 0, NULL}, + {ai_charge, 0, widow_attack_rail} }; -mmove_t widow_move_attack_pre_rail = {FRAME_transc01, FRAME_transc04, widow_frames_attack_pre_rail, NULL}; -mframe_t widow_frames_attack_rail [] = -{ +mmove_t widow_move_attack_pre_rail = { + FRAME_transc01, + FRAME_transc04, + widow_frames_attack_pre_rail, + NULL +}; + +mframe_t widow_frames_attack_rail[] = { {ai_charge, 0, NULL}, {ai_charge, 0, NULL}, {ai_charge, 0, WidowSaveLoc}, @@ -567,10 +771,15 @@ mframe_t widow_frames_attack_rail [] = {ai_charge, 0, NULL}, {ai_charge, 0, widow_rail_done} }; -mmove_t widow_move_attack_rail = {FRAME_firea01, FRAME_firea09, widow_frames_attack_rail, widow_run}; -mframe_t widow_frames_attack_rail_r [] = -{ +mmove_t widow_move_attack_rail = { + FRAME_firea01, + FRAME_firea09, + widow_frames_attack_rail, + widow_run +}; + +mframe_t widow_frames_attack_rail_r[] = { {ai_charge, 0, NULL}, {ai_charge, 0, NULL}, {ai_charge, 0, WidowSaveLoc}, @@ -581,10 +790,14 @@ mframe_t widow_frames_attack_rail_r [] = {ai_charge, 0, NULL}, {ai_charge, 0, widow_rail_done} }; -mmove_t widow_move_attack_rail_r = {FRAME_fireb01, FRAME_fireb09, widow_frames_attack_rail_r, widow_run}; +mmove_t widow_move_attack_rail_r = { + FRAME_fireb01, + FRAME_fireb09, + widow_frames_attack_rail_r, + widow_run +}; -mframe_t widow_frames_attack_rail_l [] = -{ +mframe_t widow_frames_attack_rail_l[] = { {ai_charge, 0, NULL}, {ai_charge, 0, NULL}, {ai_charge, 0, WidowSaveLoc}, @@ -595,222 +808,327 @@ mframe_t widow_frames_attack_rail_l [] = {ai_charge, 0, NULL}, {ai_charge, 0, widow_rail_done} }; -mmove_t widow_move_attack_rail_l = {FRAME_firec01, FRAME_firec09, widow_frames_attack_rail_l, widow_run}; -void widow_attack_rail (edict_t *self) +mmove_t widow_move_attack_rail_l = { + FRAME_firec01, + FRAME_firec09, + widow_frames_attack_rail_l, + widow_run +}; + +void +widow_attack_rail(edict_t *self) { - float enemy_angle; - - enemy_angle = target_angle (self); + float enemy_angle; + + if (!self) + { + return; + } + + enemy_angle = target_angle(self); if (enemy_angle < -15) + { self->monsterinfo.currentmove = &widow_move_attack_rail_l; + } else if (enemy_angle > 15) + { self->monsterinfo.currentmove = &widow_move_attack_rail_r; + } else + { self->monsterinfo.currentmove = &widow_move_attack_rail; + } } -void widow_start_spawn (edict_t *self) -{ +void +widow_start_spawn(edict_t *self) +{ + if (!self) + { + return; + } + self->monsterinfo.aiflags |= AI_MANUAL_STEERING; } -void widow_done_spawn (edict_t *self) -{ +void +widow_done_spawn(edict_t *self) +{ + if (!self) + { + return; + } + self->monsterinfo.aiflags &= ~AI_MANUAL_STEERING; } -mframe_t widow_frames_spawn [] = -{ - {ai_charge, 0, NULL}, //1 - {ai_charge, 0, NULL}, - {ai_charge, 0, NULL}, - {ai_charge, 0, widow_start_spawn}, - {ai_charge, 0, NULL}, //5 - {ai_charge, 0, WidowBlaster}, //6 - {ai_charge, 0, widow_ready_spawn}, //7 - {ai_charge, 0, WidowBlaster}, - {ai_charge, 0, WidowBlaster}, //9 - {ai_charge, 0, widow_spawn_check}, - {ai_charge, 0, WidowBlaster}, //11 - {ai_charge, 0, WidowBlaster}, - {ai_charge, 0, WidowBlaster}, //13 - {ai_charge, 0, NULL}, - {ai_charge, 0, NULL}, - {ai_charge, 0, NULL}, - {ai_charge, 0, NULL}, - {ai_charge, 0, widow_done_spawn} +mframe_t widow_frames_spawn[] = { + {ai_charge, 0, NULL}, /* 1 */ + {ai_charge, 0, NULL}, + {ai_charge, 0, NULL}, + {ai_charge, 0, widow_start_spawn}, + {ai_charge, 0, NULL}, /* 5 */ + {ai_charge, 0, WidowBlaster}, /* 6 */ + {ai_charge, 0, widow_ready_spawn}, /* 7 */ + {ai_charge, 0, WidowBlaster}, + {ai_charge, 0, WidowBlaster}, /* 9 */ + {ai_charge, 0, widow_spawn_check}, + {ai_charge, 0, WidowBlaster}, /* 11 */ + {ai_charge, 0, WidowBlaster}, + {ai_charge, 0, WidowBlaster}, /* 13 */ + {ai_charge, 0, NULL}, + {ai_charge, 0, NULL}, + {ai_charge, 0, NULL}, + {ai_charge, 0, NULL}, + {ai_charge, 0, widow_done_spawn} }; -mmove_t widow_move_spawn = {FRAME_spawn01, FRAME_spawn18, widow_frames_spawn, widow_run}; -mframe_t widow_frames_pain_heavy [] = -{ - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL} +mmove_t widow_move_spawn = { + FRAME_spawn01, + FRAME_spawn18, + widow_frames_spawn, + widow_run }; -mmove_t widow_move_pain_heavy = {FRAME_pain01, FRAME_pain13, widow_frames_pain_heavy, widow_run}; -mframe_t widow_frames_pain_light [] = -{ - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL} -}; -mmove_t widow_move_pain_light = {FRAME_pain201, FRAME_pain203, widow_frames_pain_light, widow_run}; - -void spawn_out_start (edict_t *self) -{ - vec3_t startpoint,f,r,u; - self->wait = level.time + 2.0; - - AngleVectors (self->s.angles, f, r, u); - - G_ProjectSource2 (self->s.origin, beameffects[0], f, r, u, startpoint); - gi.WriteByte (svc_temp_entity); - gi.WriteByte (TE_WIDOWBEAMOUT); - gi.WriteShort (20001); - gi.WritePosition (startpoint); - gi.multicast (startpoint, MULTICAST_ALL); - - G_ProjectSource2 (self->s.origin, beameffects[1], f, r, u, startpoint); - gi.WriteByte (svc_temp_entity); - gi.WriteByte (TE_WIDOWBEAMOUT); - gi.WriteShort (20002); - gi.WritePosition (startpoint); - gi.multicast (startpoint, MULTICAST_ALL); - - gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/bwidowbeamout.wav"), 1, ATTN_NORM, 0); -} - -void spawn_out_do (edict_t *self) -{ - vec3_t startpoint,f,r,u; - - AngleVectors (self->s.angles, f, r, u); - G_ProjectSource2 (self->s.origin, beameffects[0], f, r, u, startpoint); - gi.WriteByte (svc_temp_entity); - gi.WriteByte (TE_WIDOWSPLASH); - gi.WritePosition (startpoint); - gi.multicast (startpoint, MULTICAST_ALL); - - G_ProjectSource2 (self->s.origin, beameffects[1], f, r, u, startpoint); - gi.WriteByte (svc_temp_entity); - gi.WriteByte (TE_WIDOWSPLASH); - gi.WritePosition (startpoint); - gi.multicast (startpoint, MULTICAST_ALL); - - VectorCopy (self->s.origin, startpoint); - startpoint[2] += 36; - gi.WriteByte (svc_temp_entity); - gi.WriteByte (TE_BOSSTPORT); - gi.WritePosition (startpoint); - gi.multicast (startpoint, MULTICAST_PVS); - - Widowlegs_Spawn (self->s.origin, self->s.angles); - - G_FreeEdict (self); -} - -mframe_t widow_frames_death [] = -{ - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, //5 - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, spawn_out_start}, //10 - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, //15 - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, //20 - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, //25 - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, //30 - {ai_move, 0, spawn_out_do} -}; -mmove_t widow_move_death = {FRAME_death01, FRAME_death31, widow_frames_death, NULL}; - -void widow_attack_kick (edict_t *self) -{ - vec3_t aim; - - VectorSet (aim, 100, 0, 4); - if (self->enemy->groundentity) - fire_hit (self, aim, (50 + (rand() % 6)), 500); - else // not as much kick if they're in the air .. makes it harder to land on her head - fire_hit (self, aim, (50 + (rand() % 6)), 250); - -} - -mframe_t widow_frames_attack_kick [] = -{ +mframe_t widow_frames_pain_heavy[] = { + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, {ai_move, 0, NULL}, {ai_move, 0, NULL}, {ai_move, 0, NULL}, - {ai_move, 0, widow_attack_kick}, - {ai_move, 0, NULL}, // 5 {ai_move, 0, NULL}, {ai_move, 0, NULL}, {ai_move, 0, NULL} }; -mmove_t widow_move_attack_kick = {FRAME_kick01, FRAME_kick08, widow_frames_attack_kick, widow_run}; +mmove_t widow_move_pain_heavy = { + FRAME_pain01, + FRAME_pain13, + widow_frames_pain_heavy, + widow_run +}; -void widow_stand (edict_t *self) +mframe_t widow_frames_pain_light[] = { + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL} +}; + +mmove_t widow_move_pain_light = { + FRAME_pain201, + FRAME_pain203, + widow_frames_pain_light, + widow_run +}; + +void +spawn_out_start(edict_t *self) { - gi.sound (self, CHAN_WEAPON, gi.soundindex ("widow/laugh.wav"), 1, ATTN_NORM, 0); + vec3_t startpoint, f, r, u; + + if (!self) + { + return; + } + + self->wait = level.time + 2.0; + + AngleVectors(self->s.angles, f, r, u); + + G_ProjectSource2(self->s.origin, beameffects[0], f, r, u, startpoint); + gi.WriteByte(svc_temp_entity); + gi.WriteByte(TE_WIDOWBEAMOUT); + gi.WriteShort(20001); + gi.WritePosition(startpoint); + gi.multicast(startpoint, MULTICAST_ALL); + + G_ProjectSource2(self->s.origin, beameffects[1], f, r, u, startpoint); + gi.WriteByte(svc_temp_entity); + gi.WriteByte(TE_WIDOWBEAMOUT); + gi.WriteShort(20002); + gi.WritePosition(startpoint); + gi.multicast(startpoint, MULTICAST_ALL); + + gi.sound(self, CHAN_VOICE, gi.soundindex("misc/bwidowbeamout.wav"), 1, ATTN_NORM, 0); +} + +void +spawn_out_do(edict_t *self) +{ + vec3_t startpoint, f, r, u; + + if (!self) + { + return; + } + + AngleVectors(self->s.angles, f, r, u); + G_ProjectSource2(self->s.origin, beameffects[0], f, r, u, startpoint); + gi.WriteByte(svc_temp_entity); + gi.WriteByte(TE_WIDOWSPLASH); + gi.WritePosition(startpoint); + gi.multicast(startpoint, MULTICAST_ALL); + + G_ProjectSource2(self->s.origin, beameffects[1], f, r, u, startpoint); + gi.WriteByte(svc_temp_entity); + gi.WriteByte(TE_WIDOWSPLASH); + gi.WritePosition(startpoint); + gi.multicast(startpoint, MULTICAST_ALL); + + VectorCopy(self->s.origin, startpoint); + startpoint[2] += 36; + gi.WriteByte(svc_temp_entity); + gi.WriteByte(TE_BOSSTPORT); + gi.WritePosition(startpoint); + gi.multicast(startpoint, MULTICAST_PVS); + + Widowlegs_Spawn(self->s.origin, self->s.angles); + + G_FreeEdict(self); +} + +mframe_t widow_frames_death[] = { + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, /* 5 */ + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, spawn_out_start}, /* 10 */ + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, /* 15 */ + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, /* 20 */ + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, /* 25 */ + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, /* 30 */ + {ai_move, 0, spawn_out_do} +}; + +mmove_t widow_move_death = { + FRAME_death01, + FRAME_death31, + widow_frames_death, + NULL +}; + +void +widow_attack_kick(edict_t *self) +{ + vec3_t aim; + + if (!self) + { + return; + } + + VectorSet(aim, 100, 0, 4); + + if (self->enemy->groundentity) + { + fire_hit(self, aim, (50 + (rand() % 6)), 500); + } + else /* not as much kick if they're in the air .. makes it harder to land on her head */ + { + fire_hit(self, aim, (50 + (rand() % 6)), 250); + } +} + +mframe_t widow_frames_attack_kick[] = { + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, widow_attack_kick}, + {ai_move, 0, NULL}, /* 5 */ + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL} +}; + +mmove_t widow_move_attack_kick = { + FRAME_kick01, + FRAME_kick08, + widow_frames_attack_kick, + widow_run +}; + +void +widow_stand(edict_t *self) +{ + if (!self) + { + return; + } + + gi.sound(self, CHAN_WEAPON, gi.soundindex("widow/laugh.wav"), 1, ATTN_NORM, 0); self->monsterinfo.currentmove = &widow_move_stand; } -void widow_run (edict_t *self) -{ +void +widow_run(edict_t *self) +{ + if (!self) + { + return; + } + self->monsterinfo.aiflags &= ~AI_HOLD_FRAME; if (self->monsterinfo.aiflags & AI_STAND_GROUND) + { self->monsterinfo.currentmove = &widow_move_stand; + } else + { self->monsterinfo.currentmove = &widow_move_run; + } } -void widow_walk (edict_t *self) -{ +void +widow_walk(edict_t *self) +{ + if (!self) + { + return; + } + self->monsterinfo.currentmove = &widow_move_walk; } -void widow_attack (edict_t *self) +void +widow_attack(edict_t *self) { - float luck; + float luck; qboolean rail_frames = false, blaster_frames = false, blocked = false, anger = false; - + + if (!self) + { + return; + } + self->movetarget = NULL; if (self->monsterinfo.aiflags & AI_BLOCKED) @@ -818,7 +1136,7 @@ void widow_attack (edict_t *self) blocked = true; self->monsterinfo.aiflags &= ~AI_BLOCKED; } - + if (self->monsterinfo.aiflags & AI_TARGET_ANGER) { anger = true; @@ -826,43 +1144,54 @@ void widow_attack (edict_t *self) } if ((!self->enemy) || (!self->enemy->inuse)) + { return; + } if (self->bad_area) { if ((random() < 0.1) || (level.time < self->timestamp)) + { self->monsterinfo.currentmove = &widow_move_attack_pre_blaster; + } else { - gi.sound (self, CHAN_WEAPON, sound_rail, 1, ATTN_NORM, 0); + gi.sound(self, CHAN_WEAPON, sound_rail, 1, ATTN_NORM, 0); self->monsterinfo.currentmove = &widow_move_attack_pre_rail; } + return; } - if ((self->s.frame == FRAME_walk13) || ((self->s.frame >= FRAME_walk01) && (self->s.frame <= FRAME_walk03))) + if ((self->s.frame == FRAME_walk13) || + ((self->s.frame >= FRAME_walk01) && (self->s.frame <= FRAME_walk03))) + { rail_frames = true; + } if ((self->s.frame >= FRAME_walk09) && (self->s.frame <= FRAME_walk12)) + { blaster_frames = true; + } WidowCalcSlots(self); - // if we can't see the target, spawn stuff regardless of frame + /* if we can't see the target, spawn stuff regardless of frame */ if ((self->monsterinfo.attack_state == AS_BLIND) && (SELF_SLOTS_LEFT >= 2)) { self->monsterinfo.currentmove = &widow_move_spawn; return; } - // accept bias towards spawning regardless of frame + /* accept bias towards spawning regardless of frame */ if (blocked && (SELF_SLOTS_LEFT >= 2)) { self->monsterinfo.currentmove = &widow_move_spawn; return; } - if ((realrange(self, self->enemy) > 300) && (!anger) && (random() < 0.5) && (!blocked)) + if ((realrange(self, self->enemy) > 300) && (!anger) && (random() < 0.5) && + (!blocked)) { self->monsterinfo.currentmove = &widow_move_run_attack; return; @@ -886,117 +1215,172 @@ void widow_attack (edict_t *self) { if (!(level.time < self->timestamp)) { - gi.sound (self, CHAN_WEAPON, sound_rail, 1, ATTN_NORM, 0); + gi.sound(self, CHAN_WEAPON, sound_rail, 1, ATTN_NORM, 0); self->monsterinfo.currentmove = &widow_move_attack_pre_rail; } } if ((rail_frames) || (blaster_frames)) + { return; + } luck = random(); + if (SELF_SLOTS_LEFT >= 2) { if ((luck <= 0.40) && (self->monsterinfo.pausetime + BLASTER_TIME <= level.time)) + { self->monsterinfo.currentmove = &widow_move_attack_pre_blaster; + } else if ((luck <= 0.7) && !(level.time < self->timestamp)) { - gi.sound (self, CHAN_WEAPON, sound_rail, 1, ATTN_NORM, 0); + gi.sound(self, CHAN_WEAPON, sound_rail, 1, ATTN_NORM, 0); self->monsterinfo.currentmove = &widow_move_attack_pre_rail; } else + { self->monsterinfo.currentmove = &widow_move_spawn; + } } else { if (level.time < self->timestamp) + { self->monsterinfo.currentmove = &widow_move_attack_pre_blaster; + } else if ((luck <= 0.50) || (level.time + BLASTER_TIME >= self->monsterinfo.pausetime)) { - gi.sound (self, CHAN_WEAPON, sound_rail, 1, ATTN_NORM, 0); + gi.sound(self, CHAN_WEAPON, sound_rail, 1, ATTN_NORM, 0); self->monsterinfo.currentmove = &widow_move_attack_pre_rail; } - else // holdout to blaster + else /* holdout to blaster */ + { self->monsterinfo.currentmove = &widow_move_attack_pre_blaster; + } } } -void widow_attack_blaster (edict_t *self) -{ - self->monsterinfo.pausetime = level.time + 1.0 + (2.0*random()); +void +widow_attack_blaster(edict_t *self) +{ + if (!self) + { + return; + } + + self->monsterinfo.pausetime = level.time + 1.0 + (2.0 * random()); self->monsterinfo.currentmove = &widow_move_attack_blaster; - self->monsterinfo.nextframe = WidowTorso (self); + self->monsterinfo.nextframe = WidowTorso(self); } -void widow_reattack_blaster (edict_t *self) -{ +void +widow_reattack_blaster(edict_t *self) +{ + if (!self) + { + return; + } + WidowBlaster(self); if ((self->monsterinfo.currentmove == &widow_move_attack_post_blaster_l) || (self->monsterinfo.currentmove == &widow_move_attack_post_blaster_r)) + { return; + } - // if we're not done with the attack, don't leave the sequence + /* if we're not done with the attack, don't leave the sequence */ if (self->monsterinfo.pausetime >= level.time) + { return; + } self->monsterinfo.aiflags &= ~AI_MANUAL_STEERING; - self->monsterinfo.currentmove = &widow_move_attack_post_blaster; } -void widow_pain (edict_t *self, edict_t *other, float kick, int damage) -{ +void +widow_pain(edict_t *self, edict_t *other /* unused */, float kick, int damage) +{ + if (!self) + { + return; + } + if (self->health < (self->max_health / 2)) + { self->s.skinnum = 1; + } if (skill->value == 3) - return; // no pain anims in nightmare + { + return; /* no pain anims in nightmare */ + } if (level.time < self->pain_debounce_time) + { return; + } if (self->monsterinfo.pausetime == 100000000) + { self->monsterinfo.pausetime = 0; + } self->pain_debounce_time = level.time + 5; if (damage < 15) { - gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NONE, 0); + gi.sound(self, CHAN_VOICE, sound_pain1, 1, ATTN_NONE, 0); } else if (damage < 75) { - if ((skill->value < 3) && (random() < (0.6 - (0.2*((float)skill->value))))) + if ((skill->value < 3) && (random() < (0.6 - (0.2 * ((float)skill->value))))) { self->monsterinfo.currentmove = &widow_move_pain_light; self->monsterinfo.aiflags &= ~AI_MANUAL_STEERING; } - gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NONE, 0); + + gi.sound(self, CHAN_VOICE, sound_pain2, 1, ATTN_NONE, 0); } - else + else { - if ((skill->value < 3) && (random() < (0.75 - (0.1*((float)skill->value))))) + if ((skill->value < 3) && (random() < (0.75 - (0.1 * ((float)skill->value))))) { self->monsterinfo.currentmove = &widow_move_pain_heavy; self->monsterinfo.aiflags &= ~AI_MANUAL_STEERING; } - gi.sound (self, CHAN_VOICE, sound_pain3, 1, ATTN_NONE, 0); + + gi.sound(self, CHAN_VOICE, sound_pain3, 1, ATTN_NONE, 0); } } -void widow_dead (edict_t *self) -{ - VectorSet (self->mins, -56, -56, 0); - VectorSet (self->maxs, 56, 56, 80); +void +widow_dead(edict_t *self) +{ + if (!self) + { + return; + } + + VectorSet(self->mins, -56, -56, 0); + VectorSet(self->maxs, 56, 56, 80); self->movetype = MOVETYPE_TOSS; self->svflags |= SVF_DEADMONSTER; self->nextthink = 0; - gi.linkentity (self); + gi.linkentity(self); } -void widow_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) -{ +void +widow_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /* unused */, + int damage /* unused */, vec3_t point /* unused */) +{ + if (!self) + { + return; + } + self->deadflag = DEAD_DEAD; self->takedamage = DAMAGE_NO; self->count = 0; @@ -1006,99 +1390,163 @@ void widow_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage self->monsterinfo.currentmove = &widow_move_death; } -void widow_melee (edict_t *self) -{ +void +widow_melee(edict_t *self) +{ + if (!self) + { + return; + } + self->monsterinfo.currentmove = &widow_move_attack_kick; } -void WidowGoinQuad (edict_t *self, float framenum) -{ +void +WidowGoinQuad(edict_t *self, float framenum) +{ + if (!self) + { + return; + } + self->monsterinfo.quad_framenum = framenum; widow_damage_multiplier = 4; } -void WidowDouble (edict_t *self, float framenum) -{ +void +WidowDouble(edict_t *self, float framenum) +{ + if (!self) + { + return; + } + self->monsterinfo.double_framenum = framenum; widow_damage_multiplier = 2; } -void WidowPent (edict_t *self, float framenum) -{ +void +WidowPent(edict_t *self, float framenum) +{ + if (!self) + { + return; + } + self->monsterinfo.invincible_framenum = framenum; } -void WidowPowerArmor (edict_t *self) -{ +void +WidowPowerArmor(edict_t *self) +{ + if (!self) + { + return; + } + self->monsterinfo.power_armor_type = POWER_ARMOR_SHIELD; - // I don't like this, but it works + + /* I don't like this, but it works */ if (self->monsterinfo.power_armor_power <= 0) + { self->monsterinfo.power_armor_power += 250 * skill->value; + } } -void WidowRespondPowerup (edict_t *self, edict_t *other) -{ +void +WidowRespondPowerup(edict_t *self, edict_t *other) +{ + if (!self || !other) + { + return; + } + if (other->s.effects & EF_QUAD) { if (skill->value == 1) - WidowDouble (self, other->client->quad_framenum); + { + WidowDouble(self, other->client->quad_framenum); + } else if (skill->value == 2) - WidowGoinQuad (self, other->client->quad_framenum); + { + WidowGoinQuad(self, other->client->quad_framenum); + } else if (skill->value == 3) { - WidowGoinQuad (self, other->client->quad_framenum); - WidowPowerArmor (self); + WidowGoinQuad(self, other->client->quad_framenum); + WidowPowerArmor(self); } } else if (other->s.effects & EF_DOUBLE) { if (skill->value == 2) - WidowDouble (self, other->client->double_framenum); + { + WidowDouble(self, other->client->double_framenum); + } else if (skill->value == 3) { - WidowDouble (self, other->client->double_framenum); - WidowPowerArmor (self); + WidowDouble(self, other->client->double_framenum); + WidowPowerArmor(self); } } else + { widow_damage_multiplier = 1; + } if (other->s.effects & EF_PENT) { if (skill->value == 1) - WidowPowerArmor (self); + { + WidowPowerArmor(self); + } else if (skill->value == 2) - WidowPent (self, other->client->invincible_framenum); + { + WidowPent(self, other->client->invincible_framenum); + } else if (skill->value == 3) { - WidowPent (self, other->client->invincible_framenum); - WidowPowerArmor (self); + WidowPent(self, other->client->invincible_framenum); + WidowPowerArmor(self); } } } -void WidowPowerups (edict_t *self) +void +WidowPowerups(edict_t *self) { int player; edict_t *ent; - + + if (!self) + { + return; + } + if (!(coop && coop->value)) { - WidowRespondPowerup (self, self->enemy); + WidowRespondPowerup(self, self->enemy); } else { - // in coop, check for pents, then quads, then doubles + /* in coop, check for pents, then quads, then doubles */ for (player = 1; player <= game.maxclients; player++) { ent = &g_edicts[player]; + if (!ent->inuse) + { continue; + } + if (!ent->client) + { continue; + } + if (ent->s.effects & EF_PENT) { - WidowRespondPowerup (self, ent); + WidowRespondPowerup(self, ent); return; } } @@ -1106,13 +1554,20 @@ void WidowPowerups (edict_t *self) for (player = 1; player <= game.maxclients; player++) { ent = &g_edicts[player]; + if (!ent->inuse) + { continue; + } + if (!ent->client) + { continue; + } + if (ent->s.effects & EF_QUAD) { - WidowRespondPowerup (self, ent); + WidowRespondPowerup(self, ent); return; } } @@ -1120,38 +1575,52 @@ void WidowPowerups (edict_t *self) for (player = 1; player <= game.maxclients; player++) { ent = &g_edicts[player]; + if (!ent->inuse) + { continue; + } + if (!ent->client) + { continue; + } + if (ent->s.effects & EF_DOUBLE) { - WidowRespondPowerup (self, ent); + WidowRespondPowerup(self, ent); return; } } } } -qboolean Widow_CheckAttack (edict_t *self) +qboolean +Widow_CheckAttack(edict_t *self) { - vec3_t spot1, spot2; - vec3_t temp; - float chance = 0; - trace_t tr; - int enemy_range; - float enemy_yaw; - float real_enemy_range; - - if (!self->enemy) + vec3_t spot1, spot2; + vec3_t temp; + float chance = 0; + trace_t tr; + int enemy_range; + float enemy_yaw; + float real_enemy_range; + + if (!self) + { return false; + } + + if (!self->enemy) + { + return false; + } WidowPowerups(self); if (self->monsterinfo.currentmove == &widow_move_run) { - // if we're in run, make sure we're in a good frame for attacking before doing anything else - // frames 1,2,3,9,10,11,13 good to fire + /* if we're in run, make sure we're in a good frame for attacking before doing anything else */ switch (self->s.frame) { case FRAME_walk04: @@ -1160,17 +1629,18 @@ qboolean Widow_CheckAttack (edict_t *self) case FRAME_walk07: case FRAME_walk08: case FRAME_walk12: - { - return false; - } + { + return false; + } default: break; } } - // give a LARGE bias to spawning things when we have room - // use AI_BLOCKED as a signal to attack to spawn - if ((random() < 0.8) && (SELF_SLOTS_LEFT >= 2) && (realrange(self, self->enemy) > 150)) + /* give a LARGE bias to spawning things when we have room + use AI_BLOCKED as a signal to attack to spawn */ + if ((random() < 0.8) && (SELF_SLOTS_LEFT >= 2) && + (realrange(self, self->enemy) > 150)) { self->monsterinfo.aiflags |= AI_BLOCKED; self->monsterinfo.attack_state = AS_MISSILE; @@ -1179,53 +1649,67 @@ qboolean Widow_CheckAttack (edict_t *self) if (self->enemy->health > 0) { - // see if any entities are in the way of the shot - VectorCopy (self->s.origin, spot1); + /* see if any entities are in the way of the shot */ + VectorCopy(self->s.origin, spot1); spot1[2] += self->viewheight; - VectorCopy (self->enemy->s.origin, spot2); + VectorCopy(self->enemy->s.origin, spot2); spot2[2] += self->enemy->viewheight; - tr = gi.trace (spot1, NULL, NULL, spot2, self, CONTENTS_SOLID|CONTENTS_MONSTER|CONTENTS_SLIME|CONTENTS_LAVA); + tr = gi.trace(spot1, NULL, NULL, spot2, self, + CONTENTS_SOLID | CONTENTS_MONSTER | CONTENTS_SLIME | + CONTENTS_LAVA); - // do we have a clear shot? + /* do we have a clear shot? */ if (tr.ent != self->enemy) - { - // go ahead and spawn stuff if we're mad a a client - if (self->enemy->client && SELF_SLOTS_LEFT >= 2) + { + /* go ahead and spawn stuff if we're mad a a client */ + if (self->enemy->client && (SELF_SLOTS_LEFT >= 2)) { self->monsterinfo.attack_state = AS_BLIND; return true; } - - // PGM - we want them to go ahead and shoot at info_notnulls if they can. - if(self->enemy->solid != SOLID_NOT || tr.fraction < 1.0) //PGM + + /* PGM - we want them to go ahead and shoot at info_notnulls if they can. */ + if ((self->enemy->solid != SOLID_NOT) || (tr.fraction < 1.0)) + { return false; + } } } - + enemy_range = range(self, self->enemy); - VectorSubtract (self->enemy->s.origin, self->s.origin, temp); + VectorSubtract(self->enemy->s.origin, self->s.origin, temp); enemy_yaw = vectoyaw2(temp); self->ideal_yaw = enemy_yaw; - real_enemy_range = realrange (self, self->enemy); + real_enemy_range = realrange(self, self->enemy); - if (real_enemy_range <= (MELEE_DISTANCE+20)) + if (real_enemy_range <= (MELEE_DISTANCE + 20)) { - // don't always melee in easy mode - if (skill->value == 0 && (rand()&3) ) + /* don't always melee in easy mode */ + if ((skill->value == 0) && (rand() & 3)) + { return false; + } + if (self->monsterinfo.melee) + { self->monsterinfo.attack_state = AS_MELEE; + } else + { self->monsterinfo.attack_state = AS_MISSILE; + } + return true; } if (level.time < self->monsterinfo.attack_finished) + { return false; - + } + if (self->monsterinfo.aiflags & AI_STAND_GROUND) { chance = 0.4; @@ -1247,8 +1731,8 @@ qboolean Widow_CheckAttack (edict_t *self) chance = 0.5; } - // PGM - go ahead and shoot every time if it's a info_notnull - if ((random () < chance) || (self->enemy->solid == SOLID_NOT)) + /* go ahead and shoot every time if it's a info_notnull */ + if ((random() < chance) || (self->enemy->solid == SOLID_NOT)) { self->monsterinfo.attack_state = AS_MISSILE; return true; @@ -1257,31 +1741,46 @@ qboolean Widow_CheckAttack (edict_t *self) return false; } -qboolean widow_blocked (edict_t *self, float dist) -{ - // if we get blocked while we're in our run/attack mode, turn on a meaningless (in this context)AI flag, - // and call attack to get a new attack sequence. make sure to turn it off when we're done. - // - // I'm using AI_TARGET_ANGER for this purpose - +qboolean +widow_blocked(edict_t *self, float dist) +{ + if (!self) + { + return false; + } + if (self->monsterinfo.currentmove == &widow_move_run_attack) { self->monsterinfo.aiflags |= AI_TARGET_ANGER; + if (self->monsterinfo.checkattack(self)) + { self->monsterinfo.attack(self); + } else + { self->monsterinfo.run(self); + } + return true; } - if(blocked_checkshot (self, 0.25 + (0.05 * skill->value) )) + if (blocked_checkshot(self, 0.25 + (0.05 * skill->value))) + { return true; + } return false; } -void WidowCalcSlots (edict_t *self) -{ +void +WidowCalcSlots(edict_t *self) +{ + if (!self) + { + return; + } + switch ((int)skill->value) { case 0: @@ -1298,73 +1797,86 @@ void WidowCalcSlots (edict_t *self) self->monsterinfo.monster_slots = 3; break; } + if (coop->value) { - self->monsterinfo.monster_slots = min (6, self->monsterinfo.monster_slots + ((skill->value)*(CountPlayers()-1))); + self->monsterinfo.monster_slots = min(6, self->monsterinfo.monster_slots + ((skill->value) * (CountPlayers() - 1))); } } -void WidowPrecache () +void +WidowPrecache() { - // cache in all of the stalker stuff, widow stuff, spawngro stuff, gibs - gi.soundindex ("stalker/pain.wav"); - gi.soundindex ("stalker/death.wav"); - gi.soundindex ("stalker/sight.wav"); - gi.soundindex ("stalker/melee1.wav"); - gi.soundindex ("stalker/melee2.wav"); - gi.soundindex ("stalker/idle.wav"); + /* cache in all of the stalker stuff, widow stuff, spawngro stuff, gibs */ + gi.soundindex("stalker/pain.wav"); + gi.soundindex("stalker/death.wav"); + gi.soundindex("stalker/sight.wav"); + gi.soundindex("stalker/melee1.wav"); + gi.soundindex("stalker/melee2.wav"); + gi.soundindex("stalker/idle.wav"); - gi.soundindex ("tank/tnkatck3.wav"); - gi.modelindex ("models/proj/laser2/tris.md2"); + gi.soundindex("tank/tnkatck3.wav"); + gi.modelindex("models/proj/laser2/tris.md2"); - gi.modelindex ("models/monsters/stalker/tris.md2"); - gi.modelindex ("models/items/spawngro2/tris.md2"); - gi.modelindex ("models/objects/gibs/sm_metal/tris.md2"); - gi.modelindex ("models/objects/gibs/gear/tris.md2"); - gi.modelindex ("models/monsters/blackwidow/gib1/tris.md2"); - gi.modelindex ("models/monsters/blackwidow/gib2/tris.md2"); - gi.modelindex ("models/monsters/blackwidow/gib3/tris.md2"); - gi.modelindex ("models/monsters/blackwidow/gib4/tris.md2"); - gi.modelindex ("models/monsters/blackwidow2/gib1/tris.md2"); - gi.modelindex ("models/monsters/blackwidow2/gib2/tris.md2"); - gi.modelindex ("models/monsters/blackwidow2/gib3/tris.md2"); - gi.modelindex ("models/monsters/blackwidow2/gib4/tris.md2"); - gi.modelindex ("models/monsters/legs/tris.md2"); - gi.soundindex ("misc/bwidowbeamout.wav"); + gi.modelindex("models/monsters/stalker/tris.md2"); + gi.modelindex("models/items/spawngro2/tris.md2"); + gi.modelindex("models/objects/gibs/sm_metal/tris.md2"); + gi.modelindex("models/objects/gibs/gear/tris.md2"); + gi.modelindex("models/monsters/blackwidow/gib1/tris.md2"); + gi.modelindex("models/monsters/blackwidow/gib2/tris.md2"); + gi.modelindex("models/monsters/blackwidow/gib3/tris.md2"); + gi.modelindex("models/monsters/blackwidow/gib4/tris.md2"); + gi.modelindex("models/monsters/blackwidow2/gib1/tris.md2"); + gi.modelindex("models/monsters/blackwidow2/gib2/tris.md2"); + gi.modelindex("models/monsters/blackwidow2/gib3/tris.md2"); + gi.modelindex("models/monsters/blackwidow2/gib4/tris.md2"); + gi.modelindex("models/monsters/legs/tris.md2"); + gi.soundindex("misc/bwidowbeamout.wav"); - gi.soundindex ("misc/bigtele.wav"); - gi.soundindex ("widow/bwstep3.wav"); - gi.soundindex ("widow/bwstep2.wav"); + gi.soundindex("misc/bigtele.wav"); + gi.soundindex("widow/bwstep3.wav"); + gi.soundindex("widow/bwstep2.wav"); } - -/*QUAKED monster_widow (1 .5 0) (-40 -40 0) (40 40 144) Ambush Trigger_Spawn Sight -*/ -void SP_monster_widow (edict_t *self) -{ +/* + * QUAKED monster_widow (1 .5 0) (-40 -40 0) (40 40 144) Ambush Trigger_Spawn Sight + */ +void +SP_monster_widow(edict_t *self) +{ + if (!self) + { + return; + } + if (deathmatch->value) { - G_FreeEdict (self); + G_FreeEdict(self); return; } - sound_pain1 = gi.soundindex ("widow/bw1pain1.wav"); - sound_pain2 = gi.soundindex ("widow/bw1pain2.wav"); - sound_pain3 = gi.soundindex ("widow/bw1pain3.wav"); - sound_search1 = gi.soundindex ("bosshovr/bhvunqv1.wav"); - sound_rail = gi.soundindex ("gladiator/railgun.wav"); + sound_pain1 = gi.soundindex("widow/bw1pain1.wav"); + sound_pain2 = gi.soundindex("widow/bw1pain2.wav"); + sound_pain3 = gi.soundindex("widow/bw1pain3.wav"); + sound_search1 = gi.soundindex("bosshovr/bhvunqv1.wav"); + sound_rail = gi.soundindex("gladiator/railgun.wav"); self->movetype = MOVETYPE_STEP; self->solid = SOLID_BBOX; - self->s.modelindex = gi.modelindex ("models/monsters/blackwidow/tris.md2"); - VectorSet (self->mins, -40, -40, 0); - VectorSet (self->maxs, 40, 40, 144); + self->s.modelindex = gi.modelindex("models/monsters/blackwidow/tris.md2"); + VectorSet(self->mins, -40, -40, 0); + VectorSet(self->maxs, 40, 40, 144); + + self->health = 2000 + 1000 * (skill->value); - self->health = 2000 + 1000*(skill->value); if (coop->value) - self->health += 500*(skill->value); + { + self->health += 500 * (skill->value); + } + self->gib_health = -5000; self->mass = 1500; + if (skill->value == 3) { self->monsterinfo.power_armor_type = POWER_ARMOR_SHIELD; @@ -1372,7 +1884,7 @@ void SP_monster_widow (edict_t *self) } self->yaw_speed = 30; - + self->flags |= FL_IMMUNE_LASER; self->monsterinfo.aiflags |= AI_IGNORE_SHOTS; @@ -1387,18 +1899,17 @@ void SP_monster_widow (edict_t *self) self->monsterinfo.search = widow_search; self->monsterinfo.checkattack = Widow_CheckAttack; self->monsterinfo.sight = widow_sight; - + self->monsterinfo.blocked = widow_blocked; - gi.linkentity (self); + gi.linkentity(self); - self->monsterinfo.currentmove = &widow_move_stand; + self->monsterinfo.currentmove = &widow_move_stand; self->monsterinfo.scale = MODEL_SCALE; WidowPrecache(); WidowCalcSlots(self); widow_damage_multiplier = 1; - walkmonster_start (self); + walkmonster_start(self); } - diff --git a/src/monster/widow/widow.h b/src/monster/widow/widow.h index a8ec5ce..529efb0 100644 --- a/src/monster/widow/widow.h +++ b/src/monster/widow/widow.h @@ -1,7 +1,10 @@ -// G:\quake2\xpack\models/monsters/blackwidow - -// This file generated by qdata - Do NOT Modify - +/* ======================================================================= + * + * Black Widow (stage 1) animations. + * + * ======================================================================= + */ + #define FRAME_idle01 0 #define FRAME_idle02 1 #define FRAME_idle03 2 @@ -171,5 +174,4 @@ #define FRAME_kick06 166 #define FRAME_kick07 167 #define FRAME_kick08 168 - -#define MODEL_SCALE 2.000000 +#define MODEL_SCALE 2.000000 diff --git a/src/monster/widow/widow2.c b/src/monster/widow/widow2.c index a66b032..f6848cf 100644 --- a/src/monster/widow/widow2.c +++ b/src/monster/widow/widow2.c @@ -1,30 +1,25 @@ -/* -============================================================================== - -black widow, part 2 - -============================================================================== -*/ - -// timestamp used to prevent rapid fire of melee attack - +/* ======================================================================= + * + * Black Window (stage 2). + * + * ======================================================================= + */ + #include "../../header/local.h" #include "widow2.h" -#define NUM_STALKERS_SPAWNED 6 // max # of stalkers she can spawn +#define NUM_STALKERS_SPAWNED 6 /* max # of stalkers she can spawn */ +#define DISRUPT_TIME 3 -#define DISRUPT_TIME 3 +static int sound_pain1; +static int sound_pain2; +static int sound_pain3; +static int sound_death; +static int sound_search1; +static int sound_tentacles_retract; -static int sound_pain1; -static int sound_pain2; -static int sound_pain3; -static int sound_death; -static int sound_search1; -static int sound_tentacles_retract; - -// sqrt(64*64*2) + sqrt(28*28*2) => 130.1 static vec3_t spawnpoints[] = { - {30, 135, 0}, + {30, 135, 0}, {30, -135, 0} }; @@ -32,46 +27,54 @@ static float sweep_angles[] = { -40.0, -32.0, -24.0, -16.0, -8.0, 0.0, 8.0, 16.0, 24.0, 32.0, 40.0 }; -extern vec3_t stalker_mins, stalker_maxs; +extern vec3_t stalker_mins, stalker_maxs; -qboolean infront (edict_t *self, edict_t *other); -void WidowCalcSlots (edict_t *self); -void WidowPowerups (edict_t *self); +qboolean infront(edict_t *self, edict_t *other); +void WidowCalcSlots(edict_t *self); +void WidowPowerups(edict_t *self); -void widow2_run (edict_t *self); -void widow2_stand (edict_t *self); -void widow2_dead (edict_t *self); -void widow2_attack (edict_t *self); -void widow2_attack_beam (edict_t *self); -void widow2_reattack_beam (edict_t *self); -void widow2_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point); -void widow_start_spawn (edict_t *self); -void widow_done_spawn (edict_t *self); -void widow2_spawn_check (edict_t *self); -void widow2_prep_spawn (edict_t *self); +void widow2_run(edict_t *self); +void widow2_stand(edict_t *self); +void widow2_dead(edict_t *self); +void widow2_attack(edict_t *self); +void widow2_attack_beam(edict_t *self); +void widow2_reattack_beam(edict_t *self); +void widow2_die(edict_t *self, edict_t *inflictor, edict_t *attacker, + int damage, vec3_t point); +void widow_start_spawn(edict_t *self); +void widow_done_spawn(edict_t *self); +void widow2_spawn_check(edict_t *self); +void widow2_prep_spawn(edict_t *self); void Widow2SaveBeamTarget(edict_t *self); +void widow2_start_searching(edict_t *self); +void widow2_keep_searching(edict_t *self); +void widow2_finaldeath(edict_t *self); + +void WidowExplode(edict_t *self); +void gib_die(edict_t *self, edict_t *inflictor, edict_t *attacker, + int damage, vec3_t point); +void gib_touch(edict_t *self, edict_t *other, cplane_t *plane, + csurface_t *surf); +void ThrowWidowGibReal(edict_t *self, char *gibname, int damage, int type, + vec3_t startpos, qboolean large, int hitsound, qboolean fade); +void ThrowWidowGibSized(edict_t *self, char *gibname, int damage, int type, + vec3_t startpos, int hitsound, qboolean fade); +void ThrowWidowGibLoc(edict_t *self, char *gibname, int damage, int type, + vec3_t startpos, qboolean fade); +void WidowExplosion1(edict_t *self); +void WidowExplosion2(edict_t *self); +void WidowExplosion3(edict_t *self); +void WidowExplosion4(edict_t *self); +void WidowExplosion5(edict_t *self); +void WidowExplosion6(edict_t *self); +void WidowExplosion7(edict_t *self); +void WidowExplosionLeg(edict_t *self); +void ThrowArm1(edict_t *self); +void ThrowArm2(edict_t *self); +void ClipGibVelocity(edict_t *ent); +void showme(edict_t *self); -// death stuff -void WidowExplode (edict_t *self); -void gib_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point); -void gib_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf); -void ThrowWidowGibReal (edict_t *self, char *gibname, int damage, int type, vec3_t startpos, qboolean large, int hitsound, qboolean fade); -void ThrowWidowGibSized (edict_t *self, char *gibname, int damage, int type, vec3_t startpos, int hitsound, qboolean fade); -void ThrowWidowGibLoc (edict_t *self, char *gibname, int damage, int type, vec3_t startpos, qboolean fade); -void WidowExplosion1 (edict_t *self); -void WidowExplosion2 (edict_t *self); -void WidowExplosion3 (edict_t *self); -void WidowExplosion4 (edict_t *self); -void WidowExplosion5 (edict_t *self); -void WidowExplosion6 (edict_t *self); -void WidowExplosion7 (edict_t *self); -void WidowExplosionLeg (edict_t *self); -void ThrowArm1 (edict_t *self); -void ThrowArm2 (edict_t *self); -void ClipGibVelocity (edict_t *ent); -// end of death stuff - -// these offsets used by the tongue +/* these offsets used by the tongue */ static vec3_t offsets[] = { {17.48, 0.10, 68.92}, {17.47, 0.29, 68.91}, @@ -83,101 +86,133 @@ static vec3_t offsets[] = { {17.37, 1.21, 68.72}, }; -void showme (edict_t *self); - -void pauseme (edict_t *self) -{ +void +pauseme(edict_t *self) +{ + if (!self) + { + return; + } + self->monsterinfo.aiflags |= AI_HOLD_FRAME; } -void widow2_search (edict_t *self) -{ +void +widow2_search(edict_t *self) +{ + if (!self) + { + return; + } + if (random() < 0.5) - gi.sound (self, CHAN_VOICE, sound_search1, 1, ATTN_NONE, 0); + { + gi.sound(self, CHAN_VOICE, sound_search1, 1, ATTN_NONE, 0); + } } -void Widow2Beam (edict_t *self) +void +Widow2Beam(edict_t *self) { - vec3_t forward, right, target; - vec3_t start, targ_angles, vec; - int flashnum; - - if ((!self->enemy) || (!self->enemy->inuse)) + vec3_t forward, right, target; + vec3_t start, targ_angles, vec; + int flashnum; + + if (!self) + { return; + } + + if ((!self->enemy) || (!self->enemy->inuse)) + { + return; + } + + AngleVectors(self->s.angles, forward, right, NULL); - AngleVectors (self->s.angles, forward, right, NULL); - if ((self->s.frame >= FRAME_fireb05) && (self->s.frame <= FRAME_fireb09)) { - // regular beam attack + /* regular beam attack */ Widow2SaveBeamTarget(self); flashnum = MZ2_WIDOW2_BEAMER_1 + self->s.frame - FRAME_fireb05; - G_ProjectSource (self->s.origin, monster_flash_offset[flashnum], forward, right, start); - VectorCopy (self->pos2, target); - target[2] += self->enemy->viewheight-10; - VectorSubtract (target, start, forward); - VectorNormalize (forward); - monster_fire_heat (self, start, forward, vec3_origin, 10, 50, flashnum); + G_ProjectSource(self->s.origin, monster_flash_offset[flashnum], forward, + right, start); + VectorCopy(self->pos2, target); + target[2] += self->enemy->viewheight - 10; + VectorSubtract(target, start, forward); + VectorNormalize(forward); + monster_fire_heat(self, start, forward, vec3_origin, 10, 50, flashnum); } else if ((self->s.frame >= FRAME_spawn04) && (self->s.frame <= FRAME_spawn14)) { - // sweep + /* sweep */ flashnum = MZ2_WIDOW2_BEAM_SWEEP_1 + self->s.frame - FRAME_spawn04; - 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); + 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_WIDOW2_BEAM_SWEEP_1]; + vec[YAW] -= sweep_angles[flashnum - MZ2_WIDOW2_BEAM_SWEEP_1]; - AngleVectors (vec, forward, NULL, NULL); - monster_fire_heat (self, start, forward, vec3_origin, 10, 50, flashnum); + AngleVectors(vec, forward, NULL, NULL); + monster_fire_heat(self, start, forward, vec3_origin, 10, 50, flashnum); } else { Widow2SaveBeamTarget(self); - G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_WIDOW2_BEAMER_1], forward, right, start); + G_ProjectSource(self->s.origin, monster_flash_offset[MZ2_WIDOW2_BEAMER_1], + forward, right, start); - VectorCopy (self->pos2, target); - target[2] += self->enemy->viewheight-10; - - VectorSubtract (target, start, forward); - VectorNormalize (forward); + VectorCopy(self->pos2, target); + target[2] += self->enemy->viewheight - 10; - monster_fire_heat (self, start, forward, vec3_origin, 10, 50, 0); - } + VectorSubtract(target, start, forward); + VectorNormalize(forward); + + monster_fire_heat(self, start, forward, vec3_origin, 10, 50, 0); + } } -void Widow2Spawn (edict_t *self) +void +Widow2Spawn(edict_t *self) { - vec3_t f, r, u, offset, startpoint, spawnpoint; - edict_t *ent, *designated_enemy; - int i; - - AngleVectors (self->s.angles, f, r, u); - - for (i=0; i < 2; i++) + vec3_t f, r, u, offset, startpoint, spawnpoint; + edict_t *ent, *designated_enemy; + int i; + + if (!self) { - VectorCopy (spawnpoints[i], offset); + return; + } + + AngleVectors(self->s.angles, f, r, u); - G_ProjectSource2 (self->s.origin, offset, f, r, u, startpoint); + for (i = 0; i < 2; i++) + { + VectorCopy(spawnpoints[i], offset); - if (FindSpawnPoint (startpoint, stalker_mins, stalker_maxs, spawnpoint, 64)) + G_ProjectSource2(self->s.origin, offset, f, r, u, startpoint); + + if (FindSpawnPoint(startpoint, stalker_mins, stalker_maxs, spawnpoint, 64)) { - ent = CreateGroundMonster (spawnpoint, self->s.angles, stalker_mins, stalker_maxs, "monster_stalker", 256); + ent = CreateGroundMonster(spawnpoint, self->s.angles, stalker_mins, + stalker_maxs, "monster_stalker", 256); if (!ent) + { continue; + } self->monsterinfo.monster_used++; ent->monsterinfo.commander = self; ent->nextthink = level.time; - ent->think (ent); - - ent->monsterinfo.aiflags |= AI_SPAWNED_WIDOW|AI_DO_NOT_COUNT|AI_IGNORE_SHOTS; + ent->think(ent); + + ent->monsterinfo.aiflags |= AI_SPAWNED_WIDOW | AI_DO_NOT_COUNT | AI_IGNORE_SHOTS; if (!(coop && coop->value)) { @@ -186,12 +221,14 @@ void Widow2Spawn (edict_t *self) else { designated_enemy = PickCoopTarget(ent); + if (designated_enemy) { - // try to avoid using my enemy + /* try to avoid using my enemy */ if (designated_enemy == self->enemy) { designated_enemy = PickCoopTarget(ent); + if (designated_enemy) { } @@ -210,153 +247,215 @@ void Widow2Spawn (edict_t *self) if ((designated_enemy->inuse) && (designated_enemy->health > 0)) { ent->enemy = designated_enemy; - FoundTarget (ent); + FoundTarget(ent); ent->monsterinfo.attack(ent); } } } } -void widow2_spawn_check (edict_t *self) -{ +void +widow2_spawn_check(edict_t *self) +{ + if (!self) + { + return; + } + Widow2Beam(self); - Widow2Spawn (self); + Widow2Spawn(self); } -void widow2_ready_spawn (edict_t *self) +void +widow2_ready_spawn(edict_t *self) { - vec3_t f, r, u, offset, startpoint, spawnpoint; - int i; - - Widow2Beam(self); - AngleVectors (self->s.angles, f, r, u); - - for (i=0; i < 2; i++) + vec3_t f, r, u, offset, startpoint, spawnpoint; + int i; + + if (!self) { - VectorCopy (spawnpoints[i], offset); - G_ProjectSource2 (self->s.origin, offset, f, r, u, startpoint); - if (FindSpawnPoint (startpoint, stalker_mins, stalker_maxs, spawnpoint, 64)) + return; + } + + Widow2Beam(self); + AngleVectors(self->s.angles, f, r, u); + + for (i = 0; i < 2; i++) + { + VectorCopy(spawnpoints[i], offset); + G_ProjectSource2(self->s.origin, offset, f, r, u, startpoint); + + if (FindSpawnPoint(startpoint, stalker_mins, stalker_maxs, spawnpoint, 64)) { - SpawnGrow_Spawn (spawnpoint, 1); + SpawnGrow_Spawn(spawnpoint, 1); } } } -mframe_t widow2_frames_stand [] = -{ +mframe_t widow2_frames_stand[] = { {ai_stand, 0, NULL} }; -mmove_t widow2_move_stand = {FRAME_blackwidow3, FRAME_blackwidow3, widow2_frames_stand, NULL}; -mframe_t widow2_frames_walk [] = -{ - {ai_walk, 9.01, NULL}, - {ai_walk, 7.55, NULL}, - {ai_walk, 7.01, NULL}, - {ai_walk, 6.66, NULL}, - {ai_walk, 6.20, NULL}, - {ai_walk, 5.78, NULL}, - {ai_walk, 7.25, NULL}, - {ai_walk, 8.37, NULL}, - {ai_walk, 10.41, NULL} +mmove_t widow2_move_stand = { + FRAME_blackwidow3, + FRAME_blackwidow3, + widow2_frames_stand, + NULL }; -mmove_t widow2_move_walk = {FRAME_walk01, FRAME_walk09, widow2_frames_walk, NULL}; - -mframe_t widow2_frames_run [] = -{ - {ai_run, 9.01, NULL}, - {ai_run, 7.55, NULL}, - {ai_run, 7.01, NULL}, - {ai_run, 6.66, NULL}, - {ai_run, 6.20, NULL}, - {ai_run, 5.78, NULL}, - {ai_run, 7.25, NULL}, - {ai_run, 8.37, NULL}, - {ai_run, 10.41, NULL} +mframe_t widow2_frames_walk[] = { + {ai_walk, 9.01, NULL}, + {ai_walk, 7.55, NULL}, + {ai_walk, 7.01, NULL}, + {ai_walk, 6.66, NULL}, + {ai_walk, 6.20, NULL}, + {ai_walk, 5.78, NULL}, + {ai_walk, 7.25, NULL}, + {ai_walk, 8.37, NULL}, + {ai_walk, 10.41, NULL} }; -mmove_t widow2_move_run = {FRAME_walk01, FRAME_walk09, widow2_frames_run, NULL}; -mframe_t widow2_frames_attack_pre_beam [] = -{ - {ai_charge, 4, NULL}, - {ai_charge, 4, NULL}, - {ai_charge, 4, NULL}, - {ai_charge, 4, widow2_attack_beam} +mmove_t widow2_move_walk = { + FRAME_walk01, + FRAME_walk09, + widow2_frames_walk, + NULL }; -mmove_t widow2_move_attack_pre_beam = {FRAME_fireb01, FRAME_fireb04, widow2_frames_attack_pre_beam, NULL}; - -// Loop this -mframe_t widow2_frames_attack_beam [] = -{ - {ai_charge, 0, Widow2Beam}, - {ai_charge, 0, Widow2Beam}, - {ai_charge, 0, Widow2Beam}, - {ai_charge, 0, Widow2Beam}, - {ai_charge, 0, widow2_reattack_beam} +mframe_t widow2_frames_run[] = { + {ai_run, 9.01, NULL}, + {ai_run, 7.55, NULL}, + {ai_run, 7.01, NULL}, + {ai_run, 6.66, NULL}, + {ai_run, 6.20, NULL}, + {ai_run, 5.78, NULL}, + {ai_run, 7.25, NULL}, + {ai_run, 8.37, NULL}, + {ai_run, 10.41, NULL} }; -mmove_t widow2_move_attack_beam = {FRAME_fireb05, FRAME_fireb09, widow2_frames_attack_beam, NULL}; -mframe_t widow2_frames_attack_post_beam [] = -{ - {ai_charge, 4, NULL}, - {ai_charge, 4, NULL}, - {ai_charge, 4, NULL} +mmove_t widow2_move_run = { + FRAME_walk01, + FRAME_walk09, + widow2_frames_run, + NULL }; -mmove_t widow2_move_attack_post_beam = {FRAME_fireb06, FRAME_fireb07, widow2_frames_attack_post_beam, widow2_run}; +mframe_t widow2_frames_attack_pre_beam[] = { + {ai_charge, 4, NULL}, + {ai_charge, 4, NULL}, + {ai_charge, 4, NULL}, + {ai_charge, 4, widow2_attack_beam} +}; -void WidowDisrupt (edict_t *self) +mmove_t widow2_move_attack_pre_beam = { + FRAME_fireb01, + FRAME_fireb04, + widow2_frames_attack_pre_beam, + NULL +}; + +/* Loop this */ +mframe_t widow2_frames_attack_beam[] = { + {ai_charge, 0, Widow2Beam}, + {ai_charge, 0, Widow2Beam}, + {ai_charge, 0, Widow2Beam}, + {ai_charge, 0, Widow2Beam}, + {ai_charge, 0, widow2_reattack_beam} +}; + +mmove_t widow2_move_attack_beam = { + FRAME_fireb05, + FRAME_fireb09, + widow2_frames_attack_beam, + NULL +}; + +mframe_t widow2_frames_attack_post_beam[] = { + {ai_charge, 4, NULL}, + {ai_charge, 4, NULL}, + {ai_charge, 4, NULL} +}; + +mmove_t widow2_move_attack_post_beam = { + FRAME_fireb06, + FRAME_fireb07, + widow2_frames_attack_post_beam, + widow2_run +}; + +void +WidowDisrupt(edict_t *self) { - vec3_t start; - vec3_t dir; - vec3_t forward, right; - float len; + 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); - 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); + VectorSubtract(self->pos1, self->enemy->s.origin, dir); + len = VectorLength(dir); if (len < 30) { - VectorSubtract (self->pos1, start, dir); - VectorNormalize (dir); + 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); + PredictAim(self->enemy, start, 1200, true, 0, dir, NULL); monster_fire_tracker(self, start, dir, 20, 1200, NULL, MZ2_WIDOW_DISRUPTOR); } } -void Widow2SaveDisruptLoc (edict_t *self) -{ +void +Widow2SaveDisruptLoc(edict_t *self) +{ + if (!self) + { + return; + } + if (self->enemy && self->enemy->inuse) { - VectorCopy (self->enemy->s.origin, self->pos1); //save for aiming the shot + VectorCopy(self->enemy->s.origin, self->pos1); /* save for aiming the shot */ self->pos1[2] += self->enemy->viewheight; } else - VectorCopy (vec3_origin, self->pos1); -}; - -void widow2_disrupt_reattack (edict_t *self) -{ - float luck; - - luck = random(); - - if (luck < (0.25 + ((float)(skill->value))*0.15)) - self->monsterinfo.nextframe = FRAME_firea01; + { + VectorCopy(vec3_origin, self->pos1); + } } -mframe_t widow2_frames_attack_disrupt [] = +void +widow2_disrupt_reattack(edict_t *self) { + float luck; + + if (!self) + { + return; + } + + luck = random(); + + if (luck < (0.25 + ((float)(skill->value)) * 0.15)) + { + self->monsterinfo.nextframe = FRAME_firea01; + } +} + +mframe_t widow2_frames_attack_disrupt[] = { {ai_charge, 2, NULL}, {ai_charge, 2, NULL}, {ai_charge, 2, Widow2SaveDisruptLoc}, @@ -365,128 +464,190 @@ mframe_t widow2_frames_attack_disrupt [] = {ai_charge, 2, NULL}, {ai_charge, 2, widow2_disrupt_reattack} }; -mmove_t widow2_move_attack_disrupt = {FRAME_firea01, FRAME_firea07, widow2_frames_attack_disrupt, widow2_run}; -void Widow2SaveBeamTarget (edict_t *self) -{ +mmove_t widow2_move_attack_disrupt = { + FRAME_firea01, + FRAME_firea07, + widow2_frames_attack_disrupt, + widow2_run +}; + +void +Widow2SaveBeamTarget(edict_t *self) +{ + if (!self) + { + return; + } + if (self->enemy && self->enemy->inuse) { - VectorCopy (self->pos1, self->pos2); - VectorCopy (self->enemy->s.origin, self->pos1); //save for aiming the shot + VectorCopy(self->pos1, self->pos2); + VectorCopy(self->enemy->s.origin, self->pos1); /* save for aiming the shot */ } else { - VectorCopy (vec3_origin, self->pos1); - VectorCopy (vec3_origin, self->pos2); + VectorCopy(vec3_origin, self->pos1); + VectorCopy(vec3_origin, self->pos2); } } -void Widow2BeamTargetRemove (edict_t *self) -{ - VectorCopy (vec3_origin, self->pos1); - VectorCopy (vec3_origin, self->pos2); +void +Widow2BeamTargetRemove(edict_t *self) +{ + if (!self) + { + return; + } + + VectorCopy(vec3_origin, self->pos1); + VectorCopy(vec3_origin, self->pos2); } -void Widow2StartSweep (edict_t *self) -{ - Widow2SaveBeamTarget (self); +void +Widow2StartSweep(edict_t *self) +{ + if (!self) + { + return; + } + + Widow2SaveBeamTarget(self); } -mframe_t widow2_frames_spawn [] = -{ - {ai_charge, 0, NULL}, - {ai_charge, 0, NULL}, - {ai_charge, 0, widow_start_spawn}, - {ai_charge, 0, Widow2Beam}, - {ai_charge, 0, Widow2Beam}, //5 - {ai_charge, 0, Widow2Beam}, - {ai_charge, 0, Widow2Beam}, - {ai_charge, 0, Widow2Beam}, - {ai_charge, 0, Widow2Beam}, - {ai_charge, 0, widow2_ready_spawn}, //10 - {ai_charge, 0, Widow2Beam}, - {ai_charge, 0, Widow2Beam}, - {ai_charge, 0, Widow2Beam}, - {ai_charge, 0, widow2_spawn_check}, - {ai_charge, 0, NULL}, //15 - {ai_charge, 0, NULL}, - {ai_charge, 0, NULL}, - {ai_charge, 0, widow2_reattack_beam} +mframe_t widow2_frames_spawn[] = { + {ai_charge, 0, NULL}, + {ai_charge, 0, NULL}, + {ai_charge, 0, widow_start_spawn}, + {ai_charge, 0, Widow2Beam}, + {ai_charge, 0, Widow2Beam}, /* 5 */ + {ai_charge, 0, Widow2Beam}, + {ai_charge, 0, Widow2Beam}, + {ai_charge, 0, Widow2Beam}, + {ai_charge, 0, Widow2Beam}, + {ai_charge, 0, widow2_ready_spawn}, /* 10 */ + {ai_charge, 0, Widow2Beam}, + {ai_charge, 0, Widow2Beam}, + {ai_charge, 0, Widow2Beam}, + {ai_charge, 0, widow2_spawn_check}, + {ai_charge, 0, NULL}, /* 15 */ + {ai_charge, 0, NULL}, + {ai_charge, 0, NULL}, + {ai_charge, 0, widow2_reattack_beam} }; -mmove_t widow2_move_spawn = {FRAME_spawn01, FRAME_spawn18, widow2_frames_spawn, NULL}; -qboolean widow2_tongue_attack_ok (vec3_t start, vec3_t end, float range) +mmove_t widow2_move_spawn = { + FRAME_spawn01, + FRAME_spawn18, + widow2_frames_spawn, + NULL +}; + +qboolean +widow2_tongue_attack_ok(vec3_t start, vec3_t end, float range) { - vec3_t dir, angles; + vec3_t dir, angles; + + /* check for max distance */ + VectorSubtract(start, end, dir); - // check for max distance - VectorSubtract (start, end, dir); if (VectorLength(dir) > range) + { return false; + } + + /* check for min/max pitch */ + vectoangles(dir, angles); - // check for min/max pitch - vectoangles (dir, angles); if (angles[0] < -180) + { angles[0] += 360; + } + if (fabs(angles[0]) > 30) + { return false; + } return true; } -void Widow2Tongue (edict_t *self) +void +Widow2Tongue(edict_t *self) { - vec3_t f, r, u; - vec3_t start, end, dir; - trace_t tr; + vec3_t f, r, u; + vec3_t start, end, dir; + trace_t tr; + + if (!self) + { + return; + } + + AngleVectors(self->s.angles, f, r, u); + G_ProjectSource2(self->s.origin, offsets[self->s.frame - FRAME_tongs01], f, r, u, start); + VectorCopy(self->enemy->s.origin, end); - AngleVectors (self->s.angles, f, r, u); - G_ProjectSource2 (self->s.origin, offsets[self->s.frame - FRAME_tongs01], f, r, u, start); - VectorCopy (self->enemy->s.origin, end); if (!widow2_tongue_attack_ok(start, end, 256)) { end[2] = self->enemy->s.origin[2] + self->enemy->maxs[2] - 8; + if (!widow2_tongue_attack_ok(start, end, 256)) { end[2] = self->enemy->s.origin[2] + self->enemy->mins[2] + 8; + if (!widow2_tongue_attack_ok(start, end, 256)) + { return; + } } } - VectorCopy (self->enemy->s.origin, end); - tr = gi.trace (start, NULL, NULL, end, self, MASK_SHOT); + VectorCopy(self->enemy->s.origin, end); + + tr = gi.trace(start, NULL, NULL, end, self, MASK_SHOT); + if (tr.ent != self->enemy) - return; - - gi.sound (self, CHAN_WEAPON, sound_tentacles_retract, 1, ATTN_NORM, 0); - - gi.WriteByte (svc_temp_entity); - gi.WriteByte (TE_PARASITE_ATTACK); - gi.WriteShort (self - g_edicts); - gi.WritePosition (start); - gi.WritePosition (end); - gi.multicast (self->s.origin, MULTICAST_PVS); - - VectorSubtract (start, end, dir); - T_Damage (self->enemy, self, self, dir, self->enemy->s.origin, vec3_origin, 2, 0, DAMAGE_NO_KNOCKBACK, MOD_UNKNOWN); -} - -void Widow2TonguePull (edict_t *self) -{ - vec3_t vec; - vec3_t f, r, u; - vec3_t start, end; - - if ((!self->enemy) || (!self->enemy->inuse)) { - self->monsterinfo.run (self); return; } - AngleVectors (self->s.angles, f, r, u); - G_ProjectSource2 (self->s.origin, offsets[self->s.frame - FRAME_tongs01], f, r, u, start); - VectorCopy (self->enemy->s.origin, end); + gi.sound(self, CHAN_WEAPON, sound_tentacles_retract, 1, ATTN_NORM, 0); + + gi.WriteByte(svc_temp_entity); + gi.WriteByte(TE_PARASITE_ATTACK); + gi.WriteShort(self - g_edicts); + gi.WritePosition(start); + gi.WritePosition(end); + gi.multicast(self->s.origin, MULTICAST_PVS); + + VectorSubtract(start, end, dir); + T_Damage(self->enemy, self, self, dir, self->enemy->s.origin, + vec3_origin, 2, 0, DAMAGE_NO_KNOCKBACK, MOD_UNKNOWN); +} + +void +Widow2TonguePull(edict_t *self) +{ + vec3_t vec; + vec3_t f, r, u; + vec3_t start, end; + + if (!self) + { + return; + } + + if ((!self->enemy) || (!self->enemy->inuse)) + { + self->monsterinfo.run(self); + return; + } + + AngleVectors(self->s.angles, f, r, u); + G_ProjectSource2(self->s.origin, offsets[self->s.frame - FRAME_tongs01], + f, r, u, start); + VectorCopy(self->enemy->s.origin, end); if (!widow2_tongue_attack_ok(start, end, 256)) { @@ -498,178 +659,231 @@ void Widow2TonguePull (edict_t *self) self->enemy->s.origin[2] += 1; self->enemy->groundentity = NULL; } - - VectorSubtract (self->s.origin, self->enemy->s.origin, vec); + + VectorSubtract(self->s.origin, self->enemy->s.origin, vec); + if (self->enemy->client) { - VectorNormalize (vec); - VectorMA (self->enemy->velocity, 1000, vec, self->enemy->velocity); + VectorNormalize(vec); + VectorMA(self->enemy->velocity, 1000, vec, self->enemy->velocity); } else { - self->enemy->ideal_yaw = vectoyaw(vec); - M_ChangeYaw (self->enemy); - VectorScale (f, 1000, self->enemy->velocity); + self->enemy->ideal_yaw = vectoyaw(vec); + M_ChangeYaw(self->enemy); + VectorScale(f, 1000, self->enemy->velocity); } } -void Widow2Crunch (edict_t *self) +void +Widow2Crunch(edict_t *self) { - vec3_t aim; - + vec3_t aim; + + if (!self) + { + return; + } + if ((!self->enemy) || (!self->enemy->inuse)) { - self->monsterinfo.run (self); + self->monsterinfo.run(self); return; } - Widow2TonguePull (self); + Widow2TonguePull(self); + + /* 70 + 32 */ + VectorSet(aim, 150, 0, 4); - // 70 + 32 - VectorSet (aim, 150, 0, 4); if (self->s.frame != FRAME_tongs07) - fire_hit (self, aim, 20 + (rand() % 6), 0); + { + fire_hit(self, aim, 20 + (rand() % 6), 0); + } else { if (self->enemy->groundentity) - fire_hit (self, aim, (20 + (rand() % 6)), 500); - else // not as much kick if they're in the air .. makes it harder to land on her head - fire_hit (self, aim, (20 + (rand() % 6)), 250); + { + fire_hit(self, aim, (20 + (rand() % 6)), 500); + } + else /* not as much kick if they're in the air .. makes it harder to land on her head */ + { + fire_hit(self, aim, (20 + (rand() % 6)), 250); + } } } -void Widow2Toss (edict_t *self) -{ +void +Widow2Toss(edict_t *self) +{ + if (!self) + { + return; + } + self->timestamp = level.time + 3; return; } -mframe_t widow2_frames_tongs [] = -{ - {ai_charge, 0, Widow2Tongue}, - {ai_charge, 0, Widow2Tongue}, - {ai_charge, 0, Widow2Tongue}, - {ai_charge, 0, Widow2TonguePull}, - {ai_charge, 0, Widow2TonguePull}, //5 - {ai_charge, 0, Widow2TonguePull}, - {ai_charge, 0, Widow2Crunch}, - {ai_charge, 0, Widow2Toss} +mframe_t widow2_frames_tongs[] = { + {ai_charge, 0, Widow2Tongue}, + {ai_charge, 0, Widow2Tongue}, + {ai_charge, 0, Widow2Tongue}, + {ai_charge, 0, Widow2TonguePull}, + {ai_charge, 0, Widow2TonguePull}, /* 5 */ + {ai_charge, 0, Widow2TonguePull}, + {ai_charge, 0, Widow2Crunch}, + {ai_charge, 0, Widow2Toss} }; -mmove_t widow2_move_tongs = {FRAME_tongs01, FRAME_tongs08, widow2_frames_tongs, widow2_run}; -mframe_t widow2_frames_pain [] = -{ - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL} +mmove_t widow2_move_tongs = { + FRAME_tongs01, + FRAME_tongs08, + widow2_frames_tongs, + widow2_run }; -mmove_t widow2_move_pain = {FRAME_pain01, FRAME_pain05, widow2_frames_pain, widow2_run}; -mframe_t widow2_frames_death [] = -{ - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, WidowExplosion1}, // 3 boom - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, // 5 - - {ai_move, 0, WidowExplosion2}, // 6 boom - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, // 10 - - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, // 12 - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, // 15 - - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, WidowExplosion3}, // 18 - {ai_move, 0, NULL}, // 19 - {ai_move, 0, NULL}, // 20 - - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, WidowExplosion4}, // 25 - - {ai_move, 0, NULL}, // 26 - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, WidowExplosion5}, - {ai_move, 0, WidowExplosionLeg}, // 30 - - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, WidowExplosion6}, - {ai_move, 0, NULL}, // 35 - - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, WidowExplosion7}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, // 40 - - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, WidowExplode} // 44 +mframe_t widow2_frames_pain[] = { + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL} }; -mmove_t widow2_move_death = {FRAME_death01, FRAME_death44, widow2_frames_death, NULL}; -void widow2_start_searching (edict_t *self); -void widow2_keep_searching (edict_t *self); -void widow2_finaldeath (edict_t *self); - -mframe_t widow2_frames_dead [] = -{ - {ai_move, 0, widow2_start_searching}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, widow2_keep_searching} +mmove_t widow2_move_pain = { + FRAME_pain01, + FRAME_pain05, + widow2_frames_pain, + widow2_run }; -mmove_t widow2_move_dead = {FRAME_dthsrh01, FRAME_dthsrh15, widow2_frames_dead, NULL}; -mframe_t widow2_frames_really_dead [] = -{ - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, - {ai_move, 0, NULL}, +mframe_t widow2_frames_death[] = { + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, WidowExplosion1}, /* 3 boom */ + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, /* 5 */ - {ai_move, 0, NULL}, - {ai_move, 0, widow2_finaldeath} + {ai_move, 0, WidowExplosion2}, /* 6 boom */ + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, /* 10 */ + + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, /* 12 */ + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, /* 15 */ + + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, WidowExplosion3}, /* 18 */ + {ai_move, 0, NULL}, /* 19 */ + {ai_move, 0, NULL}, /* 20 */ + + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, WidowExplosion4}, /* 25 */ + + {ai_move, 0, NULL}, /* 26 */ + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, WidowExplosion5}, + {ai_move, 0, WidowExplosionLeg}, /* 30 */ + + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, WidowExplosion6}, + {ai_move, 0, NULL}, /* 35 */ + + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, WidowExplosion7}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, /* 40 */ + + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, WidowExplode} /* 44 */ }; -mmove_t widow2_move_really_dead = {FRAME_dthsrh16, FRAME_dthsrh22, widow2_frames_really_dead, NULL}; -void widow2_start_searching (edict_t *self) -{ +mmove_t widow2_move_death = { + FRAME_death01, + FRAME_death44, + widow2_frames_death, + NULL +}; + +mframe_t widow2_frames_dead[] = { + {ai_move, 0, widow2_start_searching}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, widow2_keep_searching} +}; + +mmove_t widow2_move_dead = { + FRAME_dthsrh01, + FRAME_dthsrh15, + widow2_frames_dead, + NULL +}; + +mframe_t widow2_frames_really_dead[] = { + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + {ai_move, 0, NULL}, + + {ai_move, 0, NULL}, + {ai_move, 0, widow2_finaldeath} +}; + +mmove_t widow2_move_really_dead = { + FRAME_dthsrh16, + FRAME_dthsrh22, + widow2_frames_really_dead, + NULL +}; + +void +widow2_start_searching(edict_t *self) +{ + if (!self) + { + return; + } + self->count = 0; } -void widow2_keep_searching (edict_t *self) -{ +void +widow2_keep_searching(edict_t *self) +{ + if (!self) + { + return; + } + if (self->count <= 2) { self->monsterinfo.currentmove = &widow2_move_dead; @@ -681,47 +895,86 @@ void widow2_keep_searching (edict_t *self) self->monsterinfo.currentmove = &widow2_move_really_dead; } -void widow2_finaldeath (edict_t *self) -{ - VectorSet (self->mins, -70, -70, 0); - VectorSet (self->maxs, 70, 70, 80); +void +widow2_finaldeath(edict_t *self) +{ + if (!self) + { + return; + } + + VectorSet(self->mins, -70, -70, 0); + VectorSet(self->maxs, 70, 70, 80); self->movetype = MOVETYPE_TOSS; self->takedamage = DAMAGE_YES; self->nextthink = 0; - gi.linkentity (self); + gi.linkentity(self); } -void widow2_stand (edict_t *self) -{ +void +widow2_stand(edict_t *self) +{ + if (!self) + { + return; + } + self->monsterinfo.currentmove = &widow2_move_stand; } -void widow2_run (edict_t *self) -{ - +void +widow2_run(edict_t *self) +{ + if (!self) + { + return; + } + self->monsterinfo.aiflags &= ~AI_HOLD_FRAME; if (self->monsterinfo.aiflags & AI_STAND_GROUND) + { self->monsterinfo.currentmove = &widow2_move_stand; + } else + { self->monsterinfo.currentmove = &widow2_move_run; + } } -void widow2_walk (edict_t *self) -{ +void +widow2_walk(edict_t *self) +{ + if (!self) + { + return; + } + self->monsterinfo.currentmove = &widow2_move_walk; } -void widow2_melee (edict_t *self) -{ +void +widow2_melee(edict_t *self) +{ + if (!self) + { + return; + } + self->monsterinfo.currentmove = &widow2_move_tongs; } -void widow2_attack (edict_t *self) +void +widow2_attack(edict_t *self) { - float range, luck; + float range, luck; qboolean blocked = false; - + + if (!self) + { + return; + } + if (self->monsterinfo.aiflags & AI_BLOCKED) { blocked = true; @@ -729,55 +982,67 @@ void widow2_attack (edict_t *self) } if (!self->enemy) + { return; + } if (self->bad_area) { if ((random() < 0.75) || (level.time < self->monsterinfo.attack_finished)) + { self->monsterinfo.currentmove = &widow2_move_attack_pre_beam; + } else { self->monsterinfo.currentmove = &widow2_move_attack_disrupt; } + return; } WidowCalcSlots(self); - // if we can't see the target, spawn stuff + /* if we can't see the target, spawn stuff */ if ((self->monsterinfo.attack_state == AS_BLIND) && (SELF_SLOTS_LEFT >= 2)) { self->monsterinfo.currentmove = &widow2_move_spawn; return; } - // accept bias towards spawning - if (blocked && (SELF_SLOTS_LEFT >= 2)) + /* accept bias towards spawning */ + if (blocked && (SELF_SLOTS_LEFT >= 2)) { self->monsterinfo.currentmove = &widow2_move_spawn; return; } - range = realrange (self, self->enemy); + range = realrange(self, self->enemy); if (range < 600) { luck = random(); + if (SELF_SLOTS_LEFT >= 2) { if (luck <= 0.40) + { self->monsterinfo.currentmove = &widow2_move_attack_pre_beam; + } else if ((luck <= 0.7) && !(level.time < self->monsterinfo.attack_finished)) { self->monsterinfo.currentmove = &widow2_move_attack_disrupt; } else + { self->monsterinfo.currentmove = &widow2_move_spawn; + } } else { if ((luck <= 0.50) || (level.time < self->monsterinfo.attack_finished)) + { self->monsterinfo.currentmove = &widow2_move_attack_pre_beam; + } else { self->monsterinfo.currentmove = &widow2_move_attack_disrupt; @@ -787,12 +1052,17 @@ void widow2_attack (edict_t *self) else { luck = random(); + if (SELF_SLOTS_LEFT >= 2) { if (luck < 0.3) + { self->monsterinfo.currentmove = &widow2_move_attack_pre_beam; + } else if ((luck < 0.65) || (level.time < self->monsterinfo.attack_finished)) + { self->monsterinfo.currentmove = &widow2_move_spawn; + } else { self->monsterinfo.currentmove = &widow2_move_attack_disrupt; @@ -801,7 +1071,9 @@ void widow2_attack (edict_t *self) else { if ((luck < 0.45) || (level.time < self->monsterinfo.attack_finished)) + { self->monsterinfo.currentmove = &widow2_move_attack_pre_beam; + } else { self->monsterinfo.currentmove = &widow2_move_attack_disrupt; @@ -810,59 +1082,97 @@ void widow2_attack (edict_t *self) } } -void widow2_attack_beam (edict_t *self) -{ +void +widow2_attack_beam(edict_t *self) +{ + if (!self) + { + return; + } + self->monsterinfo.currentmove = &widow2_move_attack_beam; } -void widow2_reattack_beam (edict_t *self) -{ +void +widow2_reattack_beam(edict_t *self) +{ + if (!self) + { + return; + } + self->monsterinfo.aiflags &= ~AI_MANUAL_STEERING; - if ( infront(self, self->enemy) ) + if (infront(self, self->enemy)) + { if (random() <= 0.5) + { if ((random() < 0.7) || (SELF_SLOTS_LEFT < 2)) + { self->monsterinfo.currentmove = &widow2_move_attack_beam; + } else + { self->monsterinfo.currentmove = &widow2_move_spawn; + } + } else + { self->monsterinfo.currentmove = &widow2_move_attack_post_beam; + } + } else + { self->monsterinfo.currentmove = &widow2_move_attack_post_beam; + } } - - -void widow2_pain (edict_t *self, edict_t *other, float kick, int damage) -{ +void +widow2_pain(edict_t *self, edict_t *other /* unused */, float kick, int damage) +{ + if (!self) + { + return; + } + if (self->health < (self->max_health / 2)) + { self->s.skinnum = 1; + } if (skill->value == 3) - return; // no pain anims in nightmare + { + return; /* no pain anims in nightmare */ + } if (level.time < self->pain_debounce_time) + { return; + } self->pain_debounce_time = level.time + 5; if (damage < 15) { - gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NONE, 0); + gi.sound(self, CHAN_VOICE, sound_pain1, 1, ATTN_NONE, 0); } else if (damage < 75) { - gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NONE, 0); - if ((skill->value < 3) && (random() < (0.6 - (0.2*((float)skill->value))))) + gi.sound(self, CHAN_VOICE, sound_pain2, 1, ATTN_NONE, 0); + + if ((skill->value < 3) && + (random() < (0.6 - (0.2 * ((float)skill->value))))) { self->monsterinfo.aiflags &= ~AI_MANUAL_STEERING; self->monsterinfo.currentmove = &widow2_move_pain; } } - else + else { - gi.sound (self, CHAN_VOICE, sound_pain3, 1, ATTN_NONE, 0); - if ((skill->value < 3) && (random() < (0.75 - (0.1*((float)skill->value))))) + gi.sound(self, CHAN_VOICE, sound_pain3, 1, ATTN_NONE, 0); + + if ((skill->value < 3) && + (random() < (0.75 - (0.1 * ((float)skill->value))))) { self->monsterinfo.aiflags &= ~AI_MANUAL_STEERING; self->monsterinfo.currentmove = &widow2_move_pain; @@ -870,95 +1180,137 @@ void widow2_pain (edict_t *self, edict_t *other, float kick, int damage) } } -void widow2_dead (edict_t *self) +void +widow2_dead(edict_t *self) { } -void KillChildren (edict_t *self) +void +KillChildren(edict_t *self) { edict_t *ent; - int field; - + int field; + + if (!self) + { + return; + } + ent = NULL; field = FOFS(classname); + while (1) { - ent = G_Find (ent, field, "monster_stalker"); - if(!ent) + ent = G_Find(ent, field, "monster_stalker"); + + if (!ent) + { return; - - // FIXME - may need to stagger + } + if ((ent->inuse) && (ent->health > 0)) - T_Damage (ent, self, self, vec3_origin, self->enemy->s.origin, vec3_origin, (ent->health + 1), 0, DAMAGE_NO_KNOCKBACK, MOD_UNKNOWN); + { + T_Damage(ent, self, self, vec3_origin, self->enemy->s.origin, vec3_origin, + (ent->health + 1), 0, DAMAGE_NO_KNOCKBACK, MOD_UNKNOWN); + } } } -void widow2_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) +void +widow2_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /* unused */, + int damage, vec3_t point /* unused */) { int n; - int clipped; - - // check for gib + int clipped; + + if (!self) + { + return; + } + + /* check for gib */ if (self->health <= self->gib_health) { - clipped = min (damage, 100); + clipped = min(damage, 100); - gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0); - for (n= 0; n < 2; n++) - ThrowWidowGibLoc (self, "models/objects/gibs/bone/tris.md2", clipped, GIB_ORGANIC, NULL, false); - for (n= 0; n < 3; n++) - ThrowWidowGibLoc (self, "models/objects/gibs/sm_meat/tris.md2", clipped, GIB_ORGANIC, NULL, false); - for (n= 0; n < 3; n++) + gi.sound(self, CHAN_VOICE, gi.soundindex("misc/udeath.wav"), 1, ATTN_NORM, 0); + + for (n = 0; n < 2; n++) { - ThrowWidowGibSized (self, "models/monsters/blackwidow2/gib1/tris.md2", clipped, GIB_METALLIC, NULL, - 0, false); - ThrowWidowGibSized (self, "models/monsters/blackwidow2/gib2/tris.md2", clipped, GIB_METALLIC, NULL, - gi.soundindex ("misc/fhit3.wav"), false); + ThrowWidowGibLoc(self, "models/objects/gibs/bone/tris.md2", clipped, GIB_ORGANIC, + NULL, false); } - for (n= 0; n < 2; n++) + + for (n = 0; n < 3; n++) { - ThrowWidowGibSized (self, "models/monsters/blackwidow2/gib3/tris.md2", clipped, GIB_METALLIC, NULL, - 0, false); - ThrowWidowGibSized (self, "models/monsters/blackwidow/gib3/tris.md2", clipped, GIB_METALLIC, NULL, - 0, false); + ThrowWidowGibLoc(self, "models/objects/gibs/sm_meat/tris.md2", clipped, GIB_ORGANIC, + NULL, false); } - ThrowGib (self, "models/objects/gibs/chest/tris.md2", clipped, GIB_ORGANIC); - ThrowHead (self, "models/objects/gibs/head2/tris.md2", clipped, GIB_ORGANIC); + + for (n = 0; n < 3; n++) + { + ThrowWidowGibSized(self, "models/monsters/blackwidow2/gib1/tris.md2", clipped, + GIB_METALLIC, NULL, 0, false); + ThrowWidowGibSized(self, "models/monsters/blackwidow2/gib2/tris.md2", clipped, + GIB_METALLIC, NULL, gi.soundindex("misc/fhit3.wav"), false); + } + + for (n = 0; n < 2; n++) + { + ThrowWidowGibSized(self, "models/monsters/blackwidow2/gib3/tris.md2", clipped, + GIB_METALLIC, NULL, 0, false); + ThrowWidowGibSized(self, "models/monsters/blackwidow/gib3/tris.md2", clipped, + GIB_METALLIC, NULL, 0, false); + } + + ThrowGib(self, "models/objects/gibs/chest/tris.md2", clipped, GIB_ORGANIC); + ThrowHead(self, "models/objects/gibs/head2/tris.md2", clipped, GIB_ORGANIC); self->deadflag = DEAD_DEAD; return; } if (self->deadflag == DEAD_DEAD) + { return; + } - gi.sound (self, CHAN_VOICE, sound_death, 1, ATTN_NONE, 0); + gi.sound(self, CHAN_VOICE, sound_death, 1, ATTN_NONE, 0); self->deadflag = DEAD_DEAD; self->takedamage = DAMAGE_NO; self->count = 0; - KillChildren (self); + KillChildren(self); self->monsterinfo.quad_framenum = 0; self->monsterinfo.double_framenum = 0; self->monsterinfo.invincible_framenum = 0; self->monsterinfo.currentmove = &widow2_move_death; } -qboolean Widow2_CheckAttack (edict_t *self) +qboolean +Widow2_CheckAttack(edict_t *self) { - vec3_t spot1, spot2; - vec3_t temp; - float chance = 0; - trace_t tr; - int enemy_range; - float enemy_yaw; - float real_enemy_range; - vec3_t f, r, u; - - if (!self->enemy) + vec3_t spot1, spot2; + vec3_t temp; + float chance = 0; + trace_t tr; + int enemy_range; + float enemy_yaw; + float real_enemy_range; + vec3_t f, r, u; + + if (!self) + { return false; + } + + if (!self->enemy) + { + return false; + } WidowPowerups(self); - if ((random() < 0.8) && (SELF_SLOTS_LEFT >= 2) && (realrange(self, self->enemy) > 150)) + if ((random() < 0.8) && (SELF_SLOTS_LEFT >= 2) && + (realrange(self, self->enemy) > 150)) { self->monsterinfo.aiflags |= AI_BLOCKED; self->monsterinfo.attack_state = AS_MISSILE; @@ -967,65 +1319,77 @@ qboolean Widow2_CheckAttack (edict_t *self) if (self->enemy->health > 0) { - // see if any entities are in the way of the shot - VectorCopy (self->s.origin, spot1); + /* see if any entities are in the way of the shot */ + VectorCopy(self->s.origin, spot1); spot1[2] += self->viewheight; - VectorCopy (self->enemy->s.origin, spot2); + VectorCopy(self->enemy->s.origin, spot2); spot2[2] += self->enemy->viewheight; - tr = gi.trace (spot1, NULL, NULL, spot2, self, CONTENTS_SOLID|CONTENTS_MONSTER|CONTENTS_SLIME|CONTENTS_LAVA); + tr = gi.trace(spot1, NULL, NULL, spot2, self, + CONTENTS_SOLID | CONTENTS_MONSTER | CONTENTS_SLIME | + CONTENTS_LAVA); - // do we have a clear shot? + /* do we have a clear shot? */ if (tr.ent != self->enemy) - { - // go ahead and spawn stuff if we're mad a a client - if (self->enemy->client && SELF_SLOTS_LEFT >= 2) + { + /* go ahead and spawn stuff if we're mad a a client */ + if (self->enemy->client && (SELF_SLOTS_LEFT >= 2)) { self->monsterinfo.attack_state = AS_BLIND; return true; } - - // PGM - we want them to go ahead and shoot at info_notnulls if they can. - if(self->enemy->solid != SOLID_NOT || tr.fraction < 1.0) //PGM + + if ((self->enemy->solid != SOLID_NOT) || (tr.fraction < 1.0)) + { return false; + } } } - + enemy_range = range(self, self->enemy); - VectorSubtract (self->enemy->s.origin, self->s.origin, temp); + VectorSubtract(self->enemy->s.origin, self->s.origin, temp); enemy_yaw = vectoyaw2(temp); self->ideal_yaw = enemy_yaw; - // melee attack + /* melee attack */ if (self->timestamp < level.time) { - real_enemy_range = realrange (self, self->enemy); + real_enemy_range = realrange(self, self->enemy); + if (real_enemy_range < 300) { - AngleVectors (self->s.angles, f, r, u); - G_ProjectSource2 (self->s.origin, offsets[0], f, r, u, spot1); - VectorCopy (self->enemy->s.origin, spot2); + AngleVectors(self->s.angles, f, r, u); + G_ProjectSource2(self->s.origin, offsets[0], f, r, u, spot1); + VectorCopy(self->enemy->s.origin, spot2); + if (widow2_tongue_attack_ok(spot1, spot2, 256)) { - // melee attack ok - - // be nice in easy mode - if (skill->value == 0 && (rand()&3) ) + /* be nice in easy mode */ + if ((skill->value == 0) && (rand() & 3)) + { return false; + } if (self->monsterinfo.melee) + { self->monsterinfo.attack_state = AS_MELEE; + } else + { self->monsterinfo.attack_state = AS_MISSILE; + } + return true; } } } - + if (level.time < self->monsterinfo.attack_finished) + { return false; - + } + if (self->monsterinfo.aiflags & AI_STAND_GROUND) { chance = 0.4; @@ -1043,8 +1407,7 @@ qboolean Widow2_CheckAttack (edict_t *self) chance = 0.5; } - // PGM - go ahead and shoot every time if it's a info_notnull - if ((random () < chance) || (self->enemy->solid == SOLID_NOT)) + if ((random() < chance) || (self->enemy->solid == SOLID_NOT)) { self->monsterinfo.attack_state = AS_MISSILE; return true; @@ -1053,63 +1416,75 @@ qboolean Widow2_CheckAttack (edict_t *self) return false; } -void Widow2Precache () +void +Widow2Precache() { - // cache in all of the stalker stuff, widow stuff, spawngro stuff, gibs - gi.soundindex ("parasite/parpain1.wav"); - gi.soundindex ("parasite/parpain2.wav"); - gi.soundindex ("parasite/pardeth1.wav"); - gi.soundindex ("parasite/paratck1.wav"); - gi.soundindex ("parasite/parsght1.wav"); - gi.soundindex ("infantry/melee2.wav"); - gi.soundindex ("misc/fhit3.wav"); + /* cache in all of the stalker stuff, widow stuff, spawngro stuff, gibs */ + gi.soundindex("parasite/parpain1.wav"); + gi.soundindex("parasite/parpain2.wav"); + gi.soundindex("parasite/pardeth1.wav"); + gi.soundindex("parasite/paratck1.wav"); + gi.soundindex("parasite/parsght1.wav"); + gi.soundindex("infantry/melee2.wav"); + gi.soundindex("misc/fhit3.wav"); - gi.soundindex ("tank/tnkatck3.wav"); - gi.soundindex ("weapons/disrupt.wav"); - gi.soundindex ("weapons/disint2.wav"); + gi.soundindex("tank/tnkatck3.wav"); + gi.soundindex("weapons/disrupt.wav"); + gi.soundindex("weapons/disint2.wav"); - gi.modelindex ("models/monsters/stalker/tris.md2"); - gi.modelindex ("models/items/spawngro2/tris.md2"); - gi.modelindex ("models/objects/gibs/sm_metal/tris.md2"); - gi.modelindex ("models/proj/laser2/tris.md2"); - gi.modelindex ("models/proj/disintegrator/tris.md2"); + gi.modelindex("models/monsters/stalker/tris.md2"); + gi.modelindex("models/items/spawngro2/tris.md2"); + gi.modelindex("models/objects/gibs/sm_metal/tris.md2"); + gi.modelindex("models/proj/laser2/tris.md2"); + gi.modelindex("models/proj/disintegrator/tris.md2"); - gi.modelindex ("models/monsters/blackwidow/gib1/tris.md2"); - gi.modelindex ("models/monsters/blackwidow/gib2/tris.md2"); - gi.modelindex ("models/monsters/blackwidow/gib3/tris.md2"); - gi.modelindex ("models/monsters/blackwidow/gib4/tris.md2"); - gi.modelindex ("models/monsters/blackwidow2/gib1/tris.md2"); - gi.modelindex ("models/monsters/blackwidow2/gib2/tris.md2"); - gi.modelindex ("models/monsters/blackwidow2/gib3/tris.md2"); - gi.modelindex ("models/monsters/blackwidow2/gib4/tris.md2"); + gi.modelindex("models/monsters/blackwidow/gib1/tris.md2"); + gi.modelindex("models/monsters/blackwidow/gib2/tris.md2"); + gi.modelindex("models/monsters/blackwidow/gib3/tris.md2"); + gi.modelindex("models/monsters/blackwidow/gib4/tris.md2"); + gi.modelindex("models/monsters/blackwidow2/gib1/tris.md2"); + gi.modelindex("models/monsters/blackwidow2/gib2/tris.md2"); + gi.modelindex("models/monsters/blackwidow2/gib3/tris.md2"); + gi.modelindex("models/monsters/blackwidow2/gib4/tris.md2"); } -/*QUAKED monster_widow2 (1 .5 0) (-70 -70 0) (70 70 144) Ambush Trigger_Spawn Sight -*/ -void SP_monster_widow2 (edict_t *self) -{ +/* + * QUAKED monster_widow2 (1 .5 0) (-70 -70 0) (70 70 144) Ambush Trigger_Spawn Sight + */ +void +SP_monster_widow2(edict_t *self) +{ + if (!self) + { + return; + } + if (deathmatch->value) { - G_FreeEdict (self); + G_FreeEdict(self); return; } - sound_pain1 = gi.soundindex ("widow/bw2pain1.wav"); - sound_pain2 = gi.soundindex ("widow/bw2pain2.wav"); - sound_pain3 = gi.soundindex ("widow/bw2pain3.wav"); - sound_death = gi.soundindex ("widow/death.wav"); - sound_search1 = gi.soundindex ("bosshovr/bhvunqv1.wav"); - sound_tentacles_retract = gi.soundindex ("brain/brnatck3.wav"); + sound_pain1 = gi.soundindex("widow/bw2pain1.wav"); + sound_pain2 = gi.soundindex("widow/bw2pain2.wav"); + sound_pain3 = gi.soundindex("widow/bw2pain3.wav"); + sound_death = gi.soundindex("widow/death.wav"); + sound_search1 = gi.soundindex("bosshovr/bhvunqv1.wav"); + sound_tentacles_retract = gi.soundindex("brain/brnatck3.wav"); self->movetype = MOVETYPE_STEP; self->solid = SOLID_BBOX; - self->s.modelindex = gi.modelindex ("models/monsters/blackwidow2/tris.md2"); - VectorSet (self->mins, -70, -70, 0); - VectorSet (self->maxs, 70, 70, 144); + self->s.modelindex = gi.modelindex("models/monsters/blackwidow2/tris.md2"); + VectorSet(self->mins, -70, -70, 0); + VectorSet(self->maxs, 70, 70, 144); + + self->health = 2000 + 800 + 1000 * (skill->value); - self->health = 2000 + 800 + 1000*(skill->value); if (coop->value) - self->health += 500*(skill->value); + { + self->health += 500 * (skill->value); + } + self->gib_health = -900; self->mass = 2500; @@ -1120,7 +1495,7 @@ void SP_monster_widow2 (edict_t *self) } self->yaw_speed = 30; - + self->flags |= FL_IMMUNE_LASER; self->monsterinfo.aiflags |= AI_IGNORE_SHOTS; @@ -1134,74 +1509,106 @@ void SP_monster_widow2 (edict_t *self) self->monsterinfo.attack = widow2_attack; self->monsterinfo.search = widow2_search; self->monsterinfo.checkattack = Widow2_CheckAttack; - gi.linkentity (self); + gi.linkentity(self); - self->monsterinfo.currentmove = &widow2_move_stand; + self->monsterinfo.currentmove = &widow2_move_stand; self->monsterinfo.scale = MODEL_SCALE; Widow2Precache(); WidowCalcSlots(self); - walkmonster_start (self); + walkmonster_start(self); } -// -// Death sequence stuff -// - -void WidowVelocityForDamage (int damage, vec3_t v) +void +WidowVelocityForDamage(int damage, vec3_t v) { v[0] = damage * crandom(); v[1] = damage * crandom(); v[2] = damage * crandom() + 200.0; } -void widow_gib_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) -{ - +void +widow_gib_touch(edict_t *self, edict_t *other /* unused */, cplane_t *plane /* unused */, + csurface_t *surf /* unused */) +{ + if (!self) + { + return; + } + self->solid = SOLID_NOT; self->touch = NULL; self->s.angles[PITCH] = 0; self->s.angles[ROLL] = 0; - VectorClear (self->avelocity); + VectorClear(self->avelocity); if (self->plat2flags) - gi.sound (self, CHAN_VOICE, self->plat2flags, 1, ATTN_NORM, 0); + { + gi.sound(self, CHAN_VOICE, self->plat2flags, 1, ATTN_NORM, 0); + } } -void ThrowWidowGib (edict_t *self, char *gibname, int damage, int type) -{ - ThrowWidowGibReal (self, gibname, damage, type, NULL, false, 0, true); +void +ThrowWidowGib(edict_t *self, char *gibname, int damage, int type) +{ + if (!self || !gibname) + { + return; + } + + ThrowWidowGibReal(self, gibname, damage, type, NULL, false, 0, true); } -void ThrowWidowGibLoc (edict_t *self, char *gibname, int damage, int type, vec3_t startpos, qboolean fade) -{ - ThrowWidowGibReal (self, gibname, damage, type, startpos, false, 0, fade); +void +ThrowWidowGibLoc(edict_t *self, char *gibname, int damage, + int type, vec3_t startpos, qboolean fade) +{ + if (!self || !gibname) + { + return; + } + + ThrowWidowGibReal(self, gibname, damage, type, startpos, false, 0, fade); } -void ThrowWidowGibSized (edict_t *self, char *gibname, int damage, int type, vec3_t startpos, int hitsound, qboolean fade) -{ - ThrowWidowGibReal (self, gibname, damage, type, startpos, true, hitsound, fade); +void +ThrowWidowGibSized(edict_t *self, char *gibname, int damage, int type, + vec3_t startpos, int hitsound, qboolean fade) +{ + if (!self || !gibname) + { + return; + } + + ThrowWidowGibReal(self, gibname, damage, type, startpos, + true, hitsound, fade); } -void ThrowWidowGibReal (edict_t *self, char *gibname, int damage, int type, vec3_t startpos, qboolean sized, int hitsound, qboolean fade) +void +ThrowWidowGibReal(edict_t *self, char *gibname, int damage, int type, + vec3_t startpos, qboolean sized, int hitsound, qboolean fade) { edict_t *gib; - vec3_t vd; - vec3_t origin; - vec3_t size; - float vscale; + vec3_t vd; + vec3_t origin; + vec3_t size; + float vscale; - if (!gibname) + if (!self || !gibname) + { return; + } gib = G_Spawn(); if (startpos) - VectorCopy (startpos, gib->s.origin); + { + VectorCopy(startpos, gib->s.origin); + } else { - VectorScale (self->size, 0.5, size); - VectorAdd (self->absmin, size, origin); + VectorScale(self->size, 0.5, size); + VectorAdd(self->absmin, size, origin); gib->s.origin[0] = origin[0] + crandom() * size[0]; gib->s.origin[1] = origin[1] + crandom() * size[1]; gib->s.origin[2] = origin[2] + crandom() * size[2]; @@ -1217,20 +1624,30 @@ void ThrowWidowGibReal (edict_t *self, char *gibname, int damage, int type, vec3 if (fade) { gib->think = G_FreeEdict; - // sized gibs last longer + + /* sized gibs last longer */ if (sized) - gib->nextthink = level.time + 20 + random()*15; + { + gib->nextthink = level.time + 20 + random() * 15; + } else - gib->nextthink = level.time + 5 + random()*10; + { + gib->nextthink = level.time + 5 + random() * 10; + } } else { gib->think = G_FreeEdict; - // sized gibs last longer + + /* sized gibs last longer */ if (sized) - gib->nextthink = level.time + 60 + random()*15; + { + gib->nextthink = level.time + 60 + random() * 15; + } else - gib->nextthink = level.time + 25 + random()*10; + { + gib->nextthink = level.time + 25 + random() * 10; + } } if (type == GIB_ORGANIC) @@ -1245,430 +1662,647 @@ void ThrowWidowGibReal (edict_t *self, char *gibname, int damage, int type, vec3 vscale = 1.0; } - WidowVelocityForDamage (damage, vd); - VectorMA (self->velocity, vscale, vd, gib->velocity); - ClipGibVelocity (gib); + WidowVelocityForDamage(damage, vd); + VectorMA(self->velocity, vscale, vd, gib->velocity); + ClipGibVelocity(gib); - gi.setmodel (gib, gibname); + gi.setmodel(gib, gibname); if (sized) { gib->plat2flags = hitsound; gib->solid = SOLID_BBOX; - gib->avelocity[0] = random()*400; - gib->avelocity[1] = random()*400; - gib->avelocity[2] = random()*200; + gib->avelocity[0] = random() * 400; + gib->avelocity[1] = random() * 400; + gib->avelocity[2] = random() * 200; + if (gib->velocity[2] < 0) + { gib->velocity[2] *= -1; + } + gib->velocity[0] *= 2; gib->velocity[1] *= 2; - ClipGibVelocity (gib); - gib->velocity[2] = max((350 + (random()*100.0)), gib->velocity[2]); + ClipGibVelocity(gib); + gib->velocity[2] = max((350 + (random() * 100.0)), gib->velocity[2]); gib->gravity = 0.25; gib->touch = widow_gib_touch; gib->owner = self; - if (gib->s.modelindex == gi.modelindex ("models/monsters/blackwidow2/gib2/tris.md2")) + + if (gib->s.modelindex == gi.modelindex("models/monsters/blackwidow2/gib2/tris.md2")) { - VectorSet (gib->mins, -10, -10, 0); - VectorSet (gib->maxs, 10, 10, 10); + VectorSet(gib->mins, -10, -10, 0); + VectorSet(gib->maxs, 10, 10, 10); } else { - VectorSet (gib->mins, -5, -5, 0); - VectorSet (gib->maxs, 5, 5, 5); + VectorSet(gib->mins, -5, -5, 0); + VectorSet(gib->maxs, 5, 5, 5); } } else { gib->velocity[0] *= 2; gib->velocity[1] *= 2; - gib->avelocity[0] = random()*600; - gib->avelocity[1] = random()*600; - gib->avelocity[2] = random()*600; + gib->avelocity[0] = random() * 600; + gib->avelocity[1] = random() * 600; + gib->avelocity[2] = random() * 600; } - gi.linkentity (gib); + gi.linkentity(gib); } -void BloodFountain (edict_t *self, int number, vec3_t startpos, int damage) +void +BloodFountain(edict_t *self, int number, vec3_t startpos, int damage) { int n; - vec3_t vd; - vec3_t origin, size, velocity; - + vec3_t vd; + vec3_t origin, size, velocity; + + if (!self) + { + return; + } + return; - for (n= 0; n < number; n++) + for (n = 0; n < number; n++) { if (startpos) - VectorCopy (startpos, origin); + { + VectorCopy(startpos, origin); + } else { - VectorScale (self->size, 0.5, size); - VectorAdd (self->absmin, size, origin); + VectorScale(self->size, 0.5, size); + VectorAdd(self->absmin, size, origin); origin[0] = origin[0] + crandom() * size[0]; origin[1] = origin[1] + crandom() * size[1]; origin[2] = origin[2] + crandom() * size[2]; } - WidowVelocityForDamage (damage, vd); - VectorMA (self->velocity, 1.0, vd, velocity); + WidowVelocityForDamage(damage, vd); + VectorMA(self->velocity, 1.0, vd, velocity); velocity[0] *= 2; velocity[1] *= 2; } } -void ThrowSmallStuff (edict_t *self, vec3_t point) +void +ThrowSmallStuff(edict_t *self, vec3_t point) { int n; + + if (!self) + { + return; + } + + for (n = 0; n < 2; n++) + { + ThrowWidowGibLoc(self, "models/objects/gibs/sm_meat/tris.md2", + 300, GIB_ORGANIC, point, false); + } - for (n= 0; n < 2; n++) - ThrowWidowGibLoc (self, "models/objects/gibs/sm_meat/tris.md2", 300, GIB_ORGANIC, point, false); - ThrowWidowGibLoc (self, "models/objects/gibs/sm_metal/tris.md2", 300, GIB_METALLIC, point, false); - ThrowWidowGibLoc (self, "models/objects/gibs/sm_metal/tris.md2", 100, GIB_METALLIC, point, false); - + ThrowWidowGibLoc(self, "models/objects/gibs/sm_metal/tris.md2", + 300, GIB_METALLIC, point, false); + ThrowWidowGibLoc(self, "models/objects/gibs/sm_metal/tris.md2", + 100, GIB_METALLIC, point, false); } -void ThrowMoreStuff (edict_t *self, vec3_t point) +void +ThrowMoreStuff(edict_t *self, vec3_t point) { int n; - + + if (!self) + { + return; + } + if (coop && coop->value) { - ThrowSmallStuff (self, point); + ThrowSmallStuff(self, point); return; } - for (n= 0; n < 1; n++) - ThrowWidowGibLoc (self, "models/objects/gibs/sm_meat/tris.md2", 300, GIB_ORGANIC, point, false); - for (n= 0; n < 2; n++) - ThrowWidowGibLoc (self, "models/objects/gibs/sm_metal/tris.md2", 300, GIB_METALLIC, point, false); - for (n= 0; n < 3; n++) - ThrowWidowGibLoc (self, "models/objects/gibs/sm_metal/tris.md2", 100, GIB_METALLIC, point, false); + for (n = 0; n < 1; n++) + { + ThrowWidowGibLoc(self, "models/objects/gibs/sm_meat/tris.md2", + 300, GIB_ORGANIC, point, false); + } + for (n = 0; n < 2; n++) + { + ThrowWidowGibLoc(self, "models/objects/gibs/sm_metal/tris.md2", + 300, GIB_METALLIC, point, false); + } + + for (n = 0; n < 3; n++) + { + ThrowWidowGibLoc(self, "models/objects/gibs/sm_metal/tris.md2", + 100, GIB_METALLIC, point, false); + } } -void WidowExplode (edict_t *self) +void +WidowExplode(edict_t *self) { - vec3_t org; - int n; - + vec3_t org; + int n; + + if (!self) + { + return; + } + self->think = WidowExplode; - VectorCopy (self->s.origin, org); - org[2] += 24 + (rand()&15); + VectorCopy(self->s.origin, org); + org[2] += 24 + (rand() & 15); + if (self->count < 8) - org[2] += 24 + (rand()&31); + { + org[2] += 24 + (rand() & 31); + } + switch (self->count) { - case 0: - org[0] -= 24; - org[1] -= 24; - break; - case 1: - org[0] += 24; - org[1] += 24; - ThrowSmallStuff(self, org); - break; - case 2: - org[0] += 24; - org[1] -= 24; - break; - case 3: - org[0] -= 24; - org[1] += 24; - ThrowMoreStuff(self, org); - break; - case 4: - org[0] -= 48; - org[1] -= 48; - break; - case 5: - org[0] += 48; - org[1] += 48; - ThrowArm1 (self); - break; - case 6: - org[0] -= 48; - org[1] += 48; - ThrowArm2 (self); - break; - case 7: - org[0] += 48; - org[1] -= 48; - ThrowSmallStuff(self, org); - break; - case 8: - org[0] += 18; - org[1] += 18; - org[2] = self->s.origin[2] + 48; - ThrowMoreStuff(self, org); - break; - case 9: - org[0] -= 18; - org[1] += 18; - org[2] = self->s.origin[2] + 48; - break; - case 10: - org[0] += 18; - org[1] -= 18; - org[2] = self->s.origin[2] + 48; - break; - case 11: - org[0] -= 18; - org[1] -= 18; - org[2] = self->s.origin[2] + 48; - break; - case 12: - self->s.sound = 0; - for (n= 0; n < 1; n++) - ThrowWidowGib (self, "models/objects/gibs/sm_meat/tris.md2", 400, GIB_ORGANIC); - for (n= 0; n < 2; n++) - ThrowWidowGib (self, "models/objects/gibs/sm_metal/tris.md2", 100, GIB_METALLIC); - for (n= 0; n < 2; n++) - ThrowWidowGib (self, "models/objects/gibs/sm_metal/tris.md2", 400, GIB_METALLIC); - self->deadflag = DEAD_DEAD; - self->think = monster_think; - self->nextthink = level.time + 0.1; - self->monsterinfo.currentmove = &widow2_move_dead; - return; + case 0: + org[0] -= 24; + org[1] -= 24; + break; + case 1: + org[0] += 24; + org[1] += 24; + ThrowSmallStuff(self, org); + break; + case 2: + org[0] += 24; + org[1] -= 24; + break; + case 3: + org[0] -= 24; + org[1] += 24; + ThrowMoreStuff(self, org); + break; + case 4: + org[0] -= 48; + org[1] -= 48; + break; + case 5: + org[0] += 48; + org[1] += 48; + ThrowArm1(self); + break; + case 6: + org[0] -= 48; + org[1] += 48; + ThrowArm2(self); + break; + case 7: + org[0] += 48; + org[1] -= 48; + ThrowSmallStuff(self, org); + break; + case 8: + org[0] += 18; + org[1] += 18; + org[2] = self->s.origin[2] + 48; + ThrowMoreStuff(self, org); + break; + case 9: + org[0] -= 18; + org[1] += 18; + org[2] = self->s.origin[2] + 48; + break; + case 10: + org[0] += 18; + org[1] -= 18; + org[2] = self->s.origin[2] + 48; + break; + case 11: + org[0] -= 18; + org[1] -= 18; + org[2] = self->s.origin[2] + 48; + break; + case 12: + self->s.sound = 0; + + for (n = 0; n < 1; n++) + { + ThrowWidowGib(self, "models/objects/gibs/sm_meat/tris.md2", + 400, GIB_ORGANIC); + } + + for (n = 0; n < 2; n++) + { + ThrowWidowGib(self, "models/objects/gibs/sm_metal/tris.md2", + 100, GIB_METALLIC); + } + + for (n = 0; n < 2; n++) + { + ThrowWidowGib(self, "models/objects/gibs/sm_metal/tris.md2", + 400, GIB_METALLIC); + } + + self->deadflag = DEAD_DEAD; + self->think = monster_think; + self->nextthink = level.time + 0.1; + self->monsterinfo.currentmove = &widow2_move_dead; + return; } self->count++; - if (self->count >=9 && self->count <=12) + + if ((self->count >= 9) && (self->count <= 12)) { - gi.WriteByte (svc_temp_entity); - gi.WriteByte (TE_EXPLOSION1_BIG); - gi.WritePosition (org); - gi.multicast (self->s.origin, MULTICAST_ALL); - } + gi.WriteByte(svc_temp_entity); + gi.WriteByte(TE_EXPLOSION1_BIG); + gi.WritePosition(org); + gi.multicast(self->s.origin, MULTICAST_ALL); + } else { - gi.WriteByte (svc_temp_entity); - if (self->count %2) - gi.WriteByte (TE_EXPLOSION1); + gi.WriteByte(svc_temp_entity); + + if (self->count % 2) + { + gi.WriteByte(TE_EXPLOSION1); + } else - gi.WriteByte (TE_EXPLOSION1_NP); - gi.WritePosition (org); - gi.multicast (self->s.origin, MULTICAST_ALL); + { + gi.WriteByte(TE_EXPLOSION1_NP); + } + + gi.WritePosition(org); + gi.multicast(self->s.origin, MULTICAST_ALL); } self->nextthink = level.time + 0.1; } -void WidowExplosion1 (edict_t *self) +void +WidowExplosion1(edict_t *self) { - int n; - vec3_t f,r,u, startpoint; - vec3_t offset = {23.74, -37.67, 76.96}; + int n; + vec3_t f, r, u, startpoint; + vec3_t offset = {23.74, -37.67, 76.96}; + + if (!self) + { + return; + } + + AngleVectors(self->s.angles, f, r, u); + G_ProjectSource2(self->s.origin, offset, f, r, u, startpoint); - AngleVectors (self->s.angles, f, r, u); - G_ProjectSource2 (self->s.origin, offset, f, r, u, startpoint); + gi.WriteByte(svc_temp_entity); + gi.WriteByte(TE_EXPLOSION1); + gi.WritePosition(startpoint); + gi.multicast(self->s.origin, MULTICAST_ALL); - gi.WriteByte (svc_temp_entity); - gi.WriteByte (TE_EXPLOSION1); - gi.WritePosition (startpoint); - gi.multicast (self->s.origin, MULTICAST_ALL); - - for (n= 0; n < 1; n++) - ThrowWidowGibLoc (self, "models/objects/gibs/sm_meat/tris.md2", 300, GIB_ORGANIC, startpoint, false); - for (n= 0; n < 1; n++) - ThrowWidowGibLoc (self, "models/objects/gibs/sm_metal/tris.md2", 100, GIB_METALLIC, startpoint, false); - for (n= 0; n < 2; n++) - ThrowWidowGibLoc (self, "models/objects/gibs/sm_metal/tris.md2", 300, GIB_METALLIC, startpoint, false); + for (n = 0; n < 1; n++) + { + ThrowWidowGibLoc(self, "models/objects/gibs/sm_meat/tris.md2", + 300, GIB_ORGANIC, startpoint, false); + } + + for (n = 0; n < 1; n++) + { + ThrowWidowGibLoc(self, "models/objects/gibs/sm_metal/tris.md2", + 100, GIB_METALLIC, startpoint, false); + } + + for (n = 0; n < 2; n++) + { + ThrowWidowGibLoc(self, "models/objects/gibs/sm_metal/tris.md2", + 300, GIB_METALLIC, startpoint, false); + } } -void WidowExplosion2 (edict_t *self) +void +WidowExplosion2(edict_t *self) { - int n; - vec3_t f,r,u, startpoint; - vec3_t offset = {-20.49, 36.92, 73.52}; + int n; + vec3_t f, r, u, startpoint; + vec3_t offset = {-20.49, 36.92, 73.52}; + + if (!self) + { + return; + } + + AngleVectors(self->s.angles, f, r, u); + G_ProjectSource2(self->s.origin, offset, f, r, u, startpoint); - AngleVectors (self->s.angles, f, r, u); - G_ProjectSource2 (self->s.origin, offset, f, r, u, startpoint); + gi.WriteByte(svc_temp_entity); + gi.WriteByte(TE_EXPLOSION1); + gi.WritePosition(startpoint); + gi.multicast(self->s.origin, MULTICAST_ALL); - gi.WriteByte (svc_temp_entity); - gi.WriteByte (TE_EXPLOSION1); - gi.WritePosition (startpoint); - gi.multicast (self->s.origin, MULTICAST_ALL); - - for (n= 0; n < 1; n++) - ThrowWidowGibLoc (self, "models/objects/gibs/sm_meat/tris.md2", 300, GIB_ORGANIC, startpoint, false); - for (n= 0; n < 1; n++) - ThrowWidowGibLoc (self, "models/objects/gibs/sm_metal/tris.md2", 100, GIB_METALLIC, startpoint, false); - for (n= 0; n < 2; n++) - ThrowWidowGibLoc (self, "models/objects/gibs/sm_metal/tris.md2", 300, GIB_METALLIC, startpoint, false); + for (n = 0; n < 1; n++) + { + ThrowWidowGibLoc(self, "models/objects/gibs/sm_meat/tris.md2", + 300, GIB_ORGANIC, startpoint, false); + } + + for (n = 0; n < 1; n++) + { + ThrowWidowGibLoc(self, "models/objects/gibs/sm_metal/tris.md2", + 100, GIB_METALLIC, startpoint, false); + } + + for (n = 0; n < 2; n++) + { + ThrowWidowGibLoc(self, "models/objects/gibs/sm_metal/tris.md2", + 300, GIB_METALLIC, startpoint, false); + } } -void WidowExplosion3 (edict_t *self) +void +WidowExplosion3(edict_t *self) { - int n; - vec3_t f,r,u, startpoint; - vec3_t offset = {2.11, 0.05, 92.20}; + int n; + vec3_t f, r, u, startpoint; + vec3_t offset = {2.11, 0.05, 92.20}; + + if (!self) + { + return; + } + + AngleVectors(self->s.angles, f, r, u); + G_ProjectSource2(self->s.origin, offset, f, r, u, startpoint); - AngleVectors (self->s.angles, f, r, u); - G_ProjectSource2 (self->s.origin, offset, f, r, u, startpoint); + gi.WriteByte(svc_temp_entity); + gi.WriteByte(TE_EXPLOSION1); + gi.WritePosition(startpoint); + gi.multicast(self->s.origin, MULTICAST_ALL); - gi.WriteByte (svc_temp_entity); - gi.WriteByte (TE_EXPLOSION1); - gi.WritePosition (startpoint); - gi.multicast (self->s.origin, MULTICAST_ALL); - - for (n= 0; n < 1; n++) - ThrowWidowGibLoc (self, "models/objects/gibs/sm_meat/tris.md2", 300, GIB_ORGANIC, startpoint, false); - for (n= 0; n < 1; n++) - ThrowWidowGibLoc (self, "models/objects/gibs/sm_metal/tris.md2", 100, GIB_METALLIC, startpoint, false); - for (n= 0; n < 2; n++) - ThrowWidowGibLoc (self, "models/objects/gibs/sm_metal/tris.md2", 300, GIB_METALLIC, startpoint, false); + for (n = 0; n < 1; n++) + { + ThrowWidowGibLoc(self, "models/objects/gibs/sm_meat/tris.md2", + 300, GIB_ORGANIC, startpoint, false); + } + + for (n = 0; n < 1; n++) + { + ThrowWidowGibLoc(self, "models/objects/gibs/sm_metal/tris.md2", + 100, GIB_METALLIC, startpoint, false); + } + + for (n = 0; n < 2; n++) + { + ThrowWidowGibLoc(self, "models/objects/gibs/sm_metal/tris.md2", + 300, GIB_METALLIC, startpoint, false); + } } -void WidowExplosion4 (edict_t *self) +void +WidowExplosion4(edict_t *self) { - int n; - vec3_t f,r,u, startpoint; - vec3_t offset = {-28.04, -35.57, -77.56}; + int n; + vec3_t f, r, u, startpoint; + vec3_t offset = {-28.04, -35.57, -77.56}; + + if (!self) + { + return; + } + + AngleVectors(self->s.angles, f, r, u); + G_ProjectSource2(self->s.origin, offset, f, r, u, startpoint); - AngleVectors (self->s.angles, f, r, u); - G_ProjectSource2 (self->s.origin, offset, f, r, u, startpoint); + gi.WriteByte(svc_temp_entity); + gi.WriteByte(TE_EXPLOSION1); + gi.WritePosition(startpoint); + gi.multicast(self->s.origin, MULTICAST_ALL); - gi.WriteByte (svc_temp_entity); - gi.WriteByte (TE_EXPLOSION1); - gi.WritePosition (startpoint); - gi.multicast (self->s.origin, MULTICAST_ALL); - - for (n= 0; n < 1; n++) - ThrowWidowGibLoc (self, "models/objects/gibs/sm_meat/tris.md2", 300, GIB_ORGANIC, startpoint, false); - for (n= 0; n < 1; n++) - ThrowWidowGibLoc (self, "models/objects/gibs/sm_metal/tris.md2", 100, GIB_METALLIC, startpoint, false); - for (n= 0; n < 2; n++) - ThrowWidowGibLoc (self, "models/objects/gibs/sm_metal/tris.md2", 300, GIB_METALLIC, startpoint, false); + for (n = 0; n < 1; n++) + { + ThrowWidowGibLoc(self, "models/objects/gibs/sm_meat/tris.md2", + 300, GIB_ORGANIC, startpoint, false); + } + + for (n = 0; n < 1; n++) + { + ThrowWidowGibLoc(self, "models/objects/gibs/sm_metal/tris.md2", + 100, GIB_METALLIC, startpoint, false); + } + + for (n = 0; n < 2; n++) + { + ThrowWidowGibLoc(self, "models/objects/gibs/sm_metal/tris.md2", + 300, GIB_METALLIC, startpoint, false); + } } -void WidowExplosion5 (edict_t *self) +void +WidowExplosion5(edict_t *self) { - int n; - vec3_t f,r,u, startpoint; - vec3_t offset = {-20.11, -1.11, 40.76}; + int n; + vec3_t f, r, u, startpoint; + vec3_t offset = {-20.11, -1.11, 40.76}; + + if (!self) + { + return; + } + + AngleVectors(self->s.angles, f, r, u); + G_ProjectSource2(self->s.origin, offset, f, r, u, startpoint); - AngleVectors (self->s.angles, f, r, u); - G_ProjectSource2 (self->s.origin, offset, f, r, u, startpoint); + gi.WriteByte(svc_temp_entity); + gi.WriteByte(TE_EXPLOSION1); + gi.WritePosition(startpoint); + gi.multicast(self->s.origin, MULTICAST_ALL); - gi.WriteByte (svc_temp_entity); - gi.WriteByte (TE_EXPLOSION1); - gi.WritePosition (startpoint); - gi.multicast (self->s.origin, MULTICAST_ALL); - - for (n= 0; n < 1; n++) - ThrowWidowGibLoc (self, "models/objects/gibs/sm_meat/tris.md2", 300, GIB_ORGANIC, startpoint, false); - for (n= 0; n < 1; n++) - ThrowWidowGibLoc (self, "models/objects/gibs/sm_metal/tris.md2", 100, GIB_METALLIC, startpoint, false); - for (n= 0; n < 2; n++) - ThrowWidowGibLoc (self, "models/objects/gibs/sm_metal/tris.md2", 300, GIB_METALLIC, startpoint, false); + for (n = 0; n < 1; n++) + { + ThrowWidowGibLoc(self, "models/objects/gibs/sm_meat/tris.md2", + 300, GIB_ORGANIC, startpoint, false); + } + + for (n = 0; n < 1; n++) + { + ThrowWidowGibLoc(self, "models/objects/gibs/sm_metal/tris.md2", + 100, GIB_METALLIC, startpoint, false); + } + + for (n = 0; n < 2; n++) + { + ThrowWidowGibLoc(self, "models/objects/gibs/sm_metal/tris.md2", + 300, GIB_METALLIC, startpoint, false); + } } -void WidowExplosion6 (edict_t *self) +void +WidowExplosion6(edict_t *self) { - int n; - vec3_t f,r,u, startpoint; - vec3_t offset = {-20.11, -1.11, 40.76}; + int n; + vec3_t f, r, u, startpoint; + vec3_t offset = {-20.11, -1.11, 40.76}; + + if (!self) + { + return; + } + + AngleVectors(self->s.angles, f, r, u); + G_ProjectSource2(self->s.origin, offset, f, r, u, startpoint); - AngleVectors (self->s.angles, f, r, u); - G_ProjectSource2 (self->s.origin, offset, f, r, u, startpoint); + gi.WriteByte(svc_temp_entity); + gi.WriteByte(TE_EXPLOSION1); + gi.WritePosition(startpoint); + gi.multicast(self->s.origin, MULTICAST_ALL); - gi.WriteByte (svc_temp_entity); - gi.WriteByte (TE_EXPLOSION1); - gi.WritePosition (startpoint); - gi.multicast (self->s.origin, MULTICAST_ALL); - - for (n= 0; n < 1; n++) - ThrowWidowGibLoc (self, "models/objects/gibs/sm_meat/tris.md2", 300, GIB_ORGANIC, startpoint, false); - for (n= 0; n < 1; n++) - ThrowWidowGibLoc (self, "models/objects/gibs/sm_metal/tris.md2", 100, GIB_METALLIC, startpoint, false); - for (n= 0; n < 2; n++) - ThrowWidowGibLoc (self, "models/objects/gibs/sm_metal/tris.md2", 300, GIB_METALLIC, startpoint, false); + for (n = 0; n < 1; n++) + { + ThrowWidowGibLoc(self, "models/objects/gibs/sm_meat/tris.md2", + 300, GIB_ORGANIC, startpoint, false); + } + + for (n = 0; n < 1; n++) + { + ThrowWidowGibLoc(self, "models/objects/gibs/sm_metal/tris.md2", + 100, GIB_METALLIC, startpoint, false); + } + + for (n = 0; n < 2; n++) + { + ThrowWidowGibLoc(self, "models/objects/gibs/sm_metal/tris.md2", + 300, GIB_METALLIC, startpoint, false); + } } -void WidowExplosion7 (edict_t *self) +void +WidowExplosion7(edict_t *self) { - int n; - vec3_t f,r,u, startpoint; - vec3_t offset = {-20.11, -1.11, 40.76}; + int n; + vec3_t f, r, u, startpoint; + vec3_t offset = {-20.11, -1.11, 40.76}; + + if (!self) + { + return; + } + + AngleVectors(self->s.angles, f, r, u); + G_ProjectSource2(self->s.origin, offset, f, r, u, startpoint); - AngleVectors (self->s.angles, f, r, u); - G_ProjectSource2 (self->s.origin, offset, f, r, u, startpoint); + gi.WriteByte(svc_temp_entity); + gi.WriteByte(TE_EXPLOSION1); + gi.WritePosition(startpoint); + gi.multicast(self->s.origin, MULTICAST_ALL); - gi.WriteByte (svc_temp_entity); - gi.WriteByte (TE_EXPLOSION1); - gi.WritePosition (startpoint); - gi.multicast (self->s.origin, MULTICAST_ALL); - - for (n= 0; n < 1; n++) - ThrowWidowGibLoc (self, "models/objects/gibs/sm_meat/tris.md2", 300, GIB_ORGANIC, startpoint, false); - for (n= 0; n < 1; n++) - ThrowWidowGibLoc (self, "models/objects/gibs/sm_metal/tris.md2", 100, GIB_METALLIC, startpoint, false); - for (n= 0; n < 2; n++) - ThrowWidowGibLoc (self, "models/objects/gibs/sm_metal/tris.md2", 300, GIB_METALLIC, startpoint, false); + for (n = 0; n < 1; n++) + { + ThrowWidowGibLoc(self, "models/objects/gibs/sm_meat/tris.md2", + 300, GIB_ORGANIC, startpoint, false); + } + + for (n = 0; n < 1; n++) + { + ThrowWidowGibLoc(self, "models/objects/gibs/sm_metal/tris.md2", + 100, GIB_METALLIC, startpoint, false); + } + + for (n = 0; n < 2; n++) + { + ThrowWidowGibLoc(self, "models/objects/gibs/sm_metal/tris.md2", + 300, GIB_METALLIC, startpoint, false); + } } -void WidowExplosionLeg (edict_t *self) +void +WidowExplosionLeg(edict_t *self) { - vec3_t f,r,u, startpoint; - vec3_t offset1 = {-31.89, -47.86, 67.02}; - vec3_t offset2 = {-44.9, -82.14, 54.72}; + vec3_t f, r, u, startpoint; + vec3_t offset1 = {-31.89, -47.86, 67.02}; + vec3_t offset2 = {-44.9, -82.14, 54.72}; + + if (!self) + { + return; + } + + AngleVectors(self->s.angles, f, r, u); + G_ProjectSource2(self->s.origin, offset1, f, r, u, startpoint); - AngleVectors (self->s.angles, f, r, u); - G_ProjectSource2 (self->s.origin, offset1, f, r, u, startpoint); + gi.WriteByte(svc_temp_entity); + gi.WriteByte(TE_EXPLOSION1_BIG); + gi.WritePosition(startpoint); + gi.multicast(self->s.origin, MULTICAST_ALL); - gi.WriteByte (svc_temp_entity); - gi.WriteByte (TE_EXPLOSION1_BIG); - gi.WritePosition (startpoint); - gi.multicast (self->s.origin, MULTICAST_ALL); + ThrowWidowGibSized(self, "models/monsters/blackwidow2/gib2/tris.md2", + 200, GIB_METALLIC, startpoint, gi.soundindex("misc/fhit3.wav"), + false); + ThrowWidowGibLoc(self, "models/objects/gibs/sm_meat/tris.md2", + 300, GIB_ORGANIC, startpoint, false); + ThrowWidowGibLoc(self, "models/objects/gibs/sm_metal/tris.md2", + 100, GIB_METALLIC, startpoint, false); - ThrowWidowGibSized (self, "models/monsters/blackwidow2/gib2/tris.md2", 200, GIB_METALLIC, startpoint, - gi.soundindex ("misc/fhit3.wav"), false); - ThrowWidowGibLoc (self, "models/objects/gibs/sm_meat/tris.md2", 300, GIB_ORGANIC, startpoint, false); - ThrowWidowGibLoc (self, "models/objects/gibs/sm_metal/tris.md2", 100, GIB_METALLIC, startpoint, false); + G_ProjectSource2(self->s.origin, offset2, f, r, u, startpoint); - G_ProjectSource2 (self->s.origin, offset2, f, r, u, startpoint); + gi.WriteByte(svc_temp_entity); + gi.WriteByte(TE_EXPLOSION1); + gi.WritePosition(startpoint); + gi.multicast(self->s.origin, MULTICAST_ALL); - gi.WriteByte (svc_temp_entity); - gi.WriteByte (TE_EXPLOSION1); - gi.WritePosition (startpoint); - gi.multicast (self->s.origin, MULTICAST_ALL); - - ThrowWidowGibSized (self, "models/monsters/blackwidow2/gib1/tris.md2", 300, GIB_METALLIC, startpoint, - gi.soundindex ("misc/fhit3.wav"), false); - ThrowWidowGibLoc (self, "models/objects/gibs/sm_meat/tris.md2", 300, GIB_ORGANIC, startpoint, false); - ThrowWidowGibLoc (self, "models/objects/gibs/sm_metal/tris.md2", 100, GIB_METALLIC, startpoint, false); + ThrowWidowGibSized(self, "models/monsters/blackwidow2/gib1/tris.md2", + 300, GIB_METALLIC, startpoint, gi.soundindex("misc/fhit3.wav"), + false); + ThrowWidowGibLoc(self, "models/objects/gibs/sm_meat/tris.md2", + 300, GIB_ORGANIC, startpoint, false); + ThrowWidowGibLoc(self, "models/objects/gibs/sm_metal/tris.md2", + 100, GIB_METALLIC, startpoint, false); } -void ThrowArm1 (edict_t *self) +void +ThrowArm1(edict_t *self) { - int n; - vec3_t f,r,u, startpoint; - vec3_t offset1 = {65.76, 17.52, 7.56}; + int n; + vec3_t f, r, u, startpoint; + vec3_t offset1 = {65.76, 17.52, 7.56}; + + if (!self) + { + return; + } + + AngleVectors(self->s.angles, f, r, u); + G_ProjectSource2(self->s.origin, offset1, f, r, u, startpoint); - AngleVectors (self->s.angles, f, r, u); - G_ProjectSource2 (self->s.origin, offset1, f, r, u, startpoint); + gi.WriteByte(svc_temp_entity); + gi.WriteByte(TE_EXPLOSION1_BIG); + gi.WritePosition(startpoint); + gi.multicast(self->s.origin, MULTICAST_ALL); - gi.WriteByte (svc_temp_entity); - gi.WriteByte (TE_EXPLOSION1_BIG); - gi.WritePosition (startpoint); - gi.multicast (self->s.origin, MULTICAST_ALL); - - for (n= 0; n < 2; n++) - ThrowWidowGibLoc (self, "models/objects/gibs/sm_metal/tris.md2", 100, GIB_METALLIC, startpoint, false); + for (n = 0; n < 2; n++) + { + ThrowWidowGibLoc(self, "models/objects/gibs/sm_metal/tris.md2", + 100, GIB_METALLIC, startpoint, false); + } } -void ThrowArm2 (edict_t *self) +void +ThrowArm2(edict_t *self) { - vec3_t f,r,u, startpoint; - vec3_t offset1 = {65.76, 17.52, 7.56}; + vec3_t f, r, u, startpoint; + vec3_t offset1 = {65.76, 17.52, 7.56}; + + if (!self) + { + return; + } + + AngleVectors(self->s.angles, f, r, u); + G_ProjectSource2(self->s.origin, offset1, f, r, u, startpoint); - AngleVectors (self->s.angles, f, r, u); - G_ProjectSource2 (self->s.origin, offset1, f, r, u, startpoint); - - ThrowWidowGibSized (self, "models/monsters/blackwidow2/gib4/tris.md2", 200, GIB_METALLIC, startpoint, - gi.soundindex ("misc/fhit3.wav"), false); - ThrowWidowGibLoc (self, "models/objects/gibs/sm_meat/tris.md2", 300, GIB_ORGANIC, startpoint, false); + ThrowWidowGibSized(self, "models/monsters/blackwidow2/gib4/tris.md2", + 200, GIB_METALLIC, startpoint, gi.soundindex("misc/fhit3.wav"), + false); + ThrowWidowGibLoc(self, "models/objects/gibs/sm_meat/tris.md2", + 300, GIB_ORGANIC, startpoint, false); } - diff --git a/src/monster/widow/widow2.h b/src/monster/widow/widow2.h index 035c91e..1073235 100644 --- a/src/monster/widow/widow2.h +++ b/src/monster/widow/widow2.h @@ -1,7 +1,10 @@ -// G:\quake2\xpack\models/monsters/blackwidow2 - -// This file generated by qdata - Do NOT Modify - +/* ======================================================================= + * + * Black Widow (stage 2) animations. + * + * ======================================================================= + */ + #define FRAME_blackwidow3 0 #define FRAME_walk01 1 #define FRAME_walk02 2 @@ -128,5 +131,4 @@ #define FRAME_dthsrh20 123 #define FRAME_dthsrh21 124 #define FRAME_dthsrh22 125 - -#define MODEL_SCALE 2.000000 +#define MODEL_SCALE 2.000000