diff --git a/missionpack/g_ai.c b/missionpack/g_ai.c index 1e8c34f..62e3527 100644 --- a/missionpack/g_ai.c +++ b/missionpack/g_ai.c @@ -966,7 +966,8 @@ qboolean FindTarget (edict_t *self) { vec3_t temp; - if (self->spawnflags & SF_MONSTER_SIGHT) + // Skid - No spawnflag check for noise for Q1 monsters - they seem excessively stupid that way + if ( (self->spawnflags & SF_MONSTER_SIGHT) || (self->flags & FL_Q1_MONSTER) ) { if (!visible (self, client)) return false; @@ -987,9 +988,11 @@ qboolean FindTarget (edict_t *self) // check area portals - if they are different and not connected then we can't hear it if (!(client->flags & FL_REFLECT)) // Lazarus reflections { - if (client->areanum != self->areanum) - if ((!gi.AreasConnected(self->areanum, client->areanum)) ) + if (client->areanum != self->areanum) { + // Skid - Q1 monsters dont hear too far + if ( (!gi.AreasConnected(self->areanum, client->areanum)) || (self->flags & (FL_Q1_MONSTER)) ) return false; + } } self->ideal_yaw = vectoyaw(temp); diff --git a/missionpack/g_combat.c b/missionpack/g_combat.c index 350d292..f080e7d 100644 --- a/missionpack/g_combat.c +++ b/missionpack/g_combat.c @@ -455,13 +455,13 @@ void CallMyFriends (edict_t *targ, edict_t *attacker) } } } - if( targ->client && (attacker->svflags & SVF_MONSTER) ) + if ( targ->client && (attacker->svflags & SVF_MONSTER) ) { // target is player; attacker is monster... alert "good guys", if any // trace_t tr; edict_t *teammate = NULL; teammate = G_Find(NULL,FOFS(dmgteam),"player"); - while(teammate) + while (teammate) { if((teammate->health > 0) && !(teammate->monsterinfo.aiflags & AI_CHASE_THING) && (teammate != attacker)) { @@ -484,7 +484,7 @@ void CallMyFriends (edict_t *targ, edict_t *attacker) } } // If player attacks a GOODGUY, turn GOODGUY stuff off - //Knightmare- gekks and stalkers use different spawnflag + // Knightmare- gekks and stalkers use different spawnflag if ( attacker->client && (targ->svflags & SVF_MONSTER) && UseSpecialGoodGuyFlag(targ) && (targ->spawnflags & 16) ) { @@ -885,6 +885,11 @@ void T_Damage (edict_t *in_targ, edict_t *inflictor, edict_t *in_attacker, vec3_ if (!targ->takedamage) return; + // no drowning damage for zombies! + if ( (mod == MOD_WATER) && + (!Q_stricmp(targ->classname, "q1_monster_zombie") || !Q_stricmp(targ->classname, "monster_q1_zombie")) ) + return; + sphere_notified = false; // PGM // Lazarus: If monster/actor is currently being forced to use @@ -907,7 +912,7 @@ void T_Damage (edict_t *in_targ, edict_t *inflictor, edict_t *in_attacker, vec3_ { if (targ->target_ent && targ->target_ent->client && targ->target_ent->client->spycam) { - if(attacker->enemy == targ) + if (attacker->enemy == targ) { attacker->enemy = targ->target_ent; attacker->goalentity = NULL; @@ -916,7 +921,7 @@ void T_Damage (edict_t *in_targ, edict_t *inflictor, edict_t *in_attacker, vec3_ targ = targ->target_ent; camera_off(targ); if (attacker->svflags & SVF_MONSTER) - { //Knightmare- gekks and stalkers use different spawnflag + { // Knightmare- gekks and stalkers use different spawnflag if ( (UseRegularGoodGuyFlag(attacker) && (attacker->spawnflags & SF_MONSTER_GOODGUY)) || (UseSpecialGoodGuyFlag(attacker) && (attacker->spawnflags & 16)) ) { @@ -926,13 +931,13 @@ void T_Damage (edict_t *in_targ, edict_t *inflictor, edict_t *in_attacker, vec3_ attacker->monsterinfo.aiflags &= ~AI_FOLLOW_LEADER; attacker->monsterinfo.attack_finished = 0; attacker->monsterinfo.pausetime = level.time + 100000000; - if(attacker->monsterinfo.stand) + if (attacker->monsterinfo.stand) attacker->monsterinfo.stand(attacker); } } else { - if(attacker->enemy == targ) + if (attacker->enemy == targ) FoundTarget(attacker); } } @@ -947,10 +952,10 @@ void T_Damage (edict_t *in_targ, edict_t *inflictor, edict_t *in_attacker, vec3_ { edict_t *monster; monster = targ->child; - if(monster) + if (monster) { monster->health = targ->health; - if(targ->target_ent) + if (targ->target_ent) { targ->target_ent->spawnflags &= ~4; targ->target_ent->move_angles[0] = 0; @@ -988,12 +993,12 @@ void T_Damage (edict_t *in_targ, edict_t *inflictor, edict_t *in_attacker, vec3_ // allow the deathmatch game to change values if (deathmatch->value && gamerules && gamerules->value) { - if(DMGame.ChangeDamage) + if (DMGame.ChangeDamage) damage = DMGame.ChangeDamage(targ, attacker, damage, mod); - if(DMGame.ChangeKnockback) + if (DMGame.ChangeKnockback) knockback = DMGame.ChangeKnockback(targ, attacker, knockback, mod); - if(!damage) + if (!damage) return; } //ROGUE @@ -1023,16 +1028,25 @@ void T_Damage (edict_t *in_targ, edict_t *inflictor, edict_t *in_attacker, vec3_ VectorNormalize(dir); -// bonus damage for suprising a monster - if (!(dflags & DAMAGE_RADIUS) && (targ->svflags & SVF_MONSTER) && (attacker->client) && (!targ->enemy) && (targ->health > 0)) + // bonus damage for suprising a monster + if ( !(dflags & DAMAGE_RADIUS) && (targ->svflags & SVF_MONSTER) && (attacker->client) && (!targ->enemy) && (targ->health > 0) ) damage *= 2; - if ((targ->flags & FL_NO_KNOCKBACK) || (mod == MOD_ETF_SPLASH) || (mod == MOD_ETF_RIFLE)) + // Shamblers take half damage from explosives + if ( (targ->svflags & SVF_MONSTER) && + ( (Q_stricmp(targ->classname,"q1_monster_shambler") == 0) || (Q_stricmp(targ->classname,"monster_q1_shambler") == 0) ) && + ( (Q_stricmp(inflictor->classname, "grenade") == 0) || (Q_stricmp(inflictor->classname, "prox") == 0) || + (Q_stricmp(inflictor->classname, "plasma") == 0) || + (Q_stricmp(inflictor->classname, "rocket") == 0) || (Q_stricmp(inflictor->classname, "homing rocket") == 0) ) ) + damage = (int)((float)damage * 0.5f); + + // Skid - q1 monsters don't go flying + if ( (targ->flags & (FL_NO_KNOCKBACK|FL_Q1_MONSTER)) || (mod == MOD_ETF_SPLASH) || (mod == MOD_ETF_RIFLE)) knockback = 0; // figure momentum add if (!(dflags & DAMAGE_NO_KNOCKBACK) - //Knightmare- no knockback from negative damage lasers and triggers + // Knightmare- no knockback from negative damage lasers and triggers && ( (damage > 0) || ((mod != MOD_TRIGGER_HURT) && (mod != MOD_TARGET_LASER)) )) { if ((knockback) && (targ->movetype != MOVETYPE_NONE) && (targ->movetype != MOVETYPE_BOUNCE) && (targ->movetype != MOVETYPE_PUSH) && (targ->movetype != MOVETYPE_STOP)) @@ -1165,9 +1179,9 @@ void T_Damage (edict_t *in_targ, edict_t *inflictor, edict_t *in_attacker, vec3_ //PGM } - if(targ->client) + if (targ->client) { - if(in_targ != targ) + if (in_targ != targ) { // Then player has taken the place of whatever was originally // damaged, as in switching from func_monitor usage. Limit @@ -1186,11 +1200,11 @@ void T_Damage (edict_t *in_targ, edict_t *inflictor, edict_t *in_attacker, vec3_ { // Lazarus: For func_explosive target, check spawnflags and, if needed, // damage type - if(targ->classname && !Q_stricmp(targ->classname,"func_explosive")) + if (targ->classname && !Q_stricmp(targ->classname,"func_explosive")) { qboolean good_damage = true; - if(targ->spawnflags & 16) // explosion only + if (targ->spawnflags & 16) // explosion only { good_damage = false; if(mod == MOD_GRENADE) good_damage = true; @@ -1215,21 +1229,22 @@ void T_Damage (edict_t *in_targ, edict_t *inflictor, edict_t *in_attacker, vec3_ if(mod == MOD_SHOCK_SPLASH) good_damage = true; if(mod == MOD_ETF_SPLASH) good_damage = true; } - if(!good_damage) return; + if (!good_damage) return; } targ->health = targ->health - take; } //PGM - spheres need to know who to shoot at - if(client && client->owned_sphere) + if (client && client->owned_sphere) { sphere_notified = true; - if(client->owned_sphere->pain) + if (client->owned_sphere->pain) client->owned_sphere->pain (client->owned_sphere, attacker, 0, 0); } //PGM - - if (targ->health <= 0) + // Knocked down Q1 zombies can't be killed + // if (targ->health <= 0) + if ( (targ->health <= 0) && !( (!Q_stricmp(targ->classname, "q1_monster_zombie") || !Q_stricmp(targ->classname, "monster_q1_zombie")) && targ->count) ) { if ((targ->svflags & SVF_MONSTER) || (client)) targ->flags |= FL_NO_KNOCKBACK; diff --git a/missionpack/g_func.c b/missionpack/g_func.c index 71129d0..7e25d93 100644 --- a/missionpack/g_func.c +++ b/missionpack/g_func.c @@ -837,9 +837,16 @@ void plat_blocked (edict_t *self, edict_t *other) return; } + // Remove dead Q1 monsters, as they can't be gibbed + if ( (other->svflags & SVF_DEADMONSTER) && (other->flags & FL_Q1_MONSTER) ) + { + G_FreeEdict(other); + return; + } + //PGM // gib dead things - if(other->health < 1) + if (other->health < 1) { T_Damage(other, self, self, vec3_origin, other->s.origin, vec3_origin, 100, 1, 0, MOD_CRUSH); } @@ -1298,6 +1305,13 @@ void plat2_blocked (edict_t *self, edict_t *other) return; } + // Remove dead Q1 monsters, as they can't be gibbed + if ( (other->svflags & SVF_DEADMONSTER) && (other->flags & FL_Q1_MONSTER) ) + { + G_FreeEdict(other); + return; + } + // gib dead things if(other->health < 1) { @@ -1568,6 +1582,13 @@ void rotating_decel (edict_t *self) void rotating_blocked (edict_t *self, edict_t *other) { + // Remove dead Q1 monsters, as they can't be gibbed + if ( (other->svflags & SVF_DEADMONSTER) && (other->flags & FL_Q1_MONSTER) ) + { + G_FreeEdict(other); + return; + } + T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, 1, 0, MOD_CRUSH); } @@ -2461,6 +2482,13 @@ void door_blocked (edict_t *self, edict_t *other) return; } + // Remove dead Q1 monsters, as they can't be gibbed + if ( (other->svflags & SVF_DEADMONSTER) && (other->flags & FL_Q1_MONSTER) ) + { + G_FreeEdict(other); + return; + } + T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, 1, 0, MOD_CRUSH); if (self->spawnflags & DOOR_CRUSHER) @@ -2903,6 +2931,13 @@ void smart_water_blocked (edict_t *self, edict_t *other) return; } + // Remove dead Q1 monsters, as they can't be gibbed + if ( (other->svflags & SVF_DEADMONSTER) && (other->flags & FL_Q1_MONSTER) ) + { + G_FreeEdict(other); + return; + } + T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, 100, 1, 0, MOD_LAVA); } @@ -3691,6 +3726,13 @@ void train_blocked (edict_t *self, edict_t *other) } VectorClear (self->avelocity); //don't turn children when blocked + // Remove dead Q1 monsters, as they can't be gibbed + if ( (other->svflags & SVF_DEADMONSTER) && (other->flags & FL_Q1_MONSTER) ) + { + G_FreeEdict(other); + return; + } + if (level.time < self->touch_debounce_time) return; @@ -4991,6 +5033,13 @@ void door_secret_blocked (edict_t *self, edict_t *other) return; } + // Remove dead Q1 monsters, as they can't be gibbed + if ( (other->svflags & SVF_DEADMONSTER) && (other->flags & FL_Q1_MONSTER) ) + { + G_FreeEdict(other); + return; + } + if (level.time < self->touch_debounce_time) return; self->touch_debounce_time = level.time + 0.5; @@ -5983,7 +6032,7 @@ void SP_func_bobbingwater(edict_t *self) // void pivot_blocked (edict_t *self, edict_t *other) { - VectorCopy(vec3_origin,self->avelocity); + VectorCopy(vec3_origin ,self->avelocity); gi.linkentity(self); } diff --git a/missionpack/g_func_decs.h b/missionpack/g_func_decs.h index 4cac7ac..e58384d 100644 --- a/missionpack/g_func_decs.h +++ b/missionpack/g_func_decs.h @@ -540,6 +540,222 @@ extern void soldier_cock ( edict_t * self ) ; extern void soldier_idle ( edict_t * self ) ; extern void soldier_stop_charge ( edict_t * self ) ; extern void soldier_start_charge ( edict_t * self ) ; +extern void SP_monster_q1_zombie ( edict_t * self ) ; +extern void q1zombie_die ( edict_t * self , edict_t * inflictor , edict_t * attacker , int damage , vec3_t point ) ; +extern void q1zombie_sight ( edict_t * self , edict_t * other ) ; +extern void q1zombie_fallagain ( edict_t * self ) ; +extern void q1zombie_pain ( edict_t * self , edict_t * other , float kick , int damage ) ; +extern void q1zombie_down ( edict_t * self ) ; +extern void q1zombie_attack ( edict_t * self ) ; +extern void q1zombie_firegib3 ( edict_t * self ) ; +extern void q1zombie_firegib2 ( edict_t * self ) ; +extern void q1zombie_firegib1 ( edict_t * self ) ; +extern void q1zombie_firegib ( edict_t * self , vec3_t offset ) ; +extern void q1zombie_run ( edict_t * self ) ; +extern void q1zombie_walk ( edict_t * self ) ; +extern void q1zombie_crucify ( edict_t * self ) ; +extern void q1zombie_stand ( edict_t * self ) ; +extern void q1zombie_fall ( edict_t * self ) ; +extern void q1zombie_pain2 ( edict_t * self ) ; +extern void q1zombie_pain1 ( edict_t * self ) ; +extern void q1zombie_idle2 ( edict_t * self ) ; +extern void q1zombie_idle ( edict_t * self ) ; +extern void q1zombie_idle3 ( edict_t * self ) ; +extern void q1zombie_Cidle ( edict_t * self ) ; +extern void SP_monster_q1_tarbaby ( edict_t * self ) ; +extern void tarbaby_die ( edict_t * self , edict_t * inflictor , edict_t * attacker , int damage , vec3_t point ) ; +extern void tarbaby_dead ( edict_t * self ) ; +extern void tarbaby_pain ( edict_t * self , edict_t * other , float kick , int damage ) ; +extern void tarbaby_jump ( edict_t * self ) ; +extern void tarbaby_takeoff ( edict_t * self ) ; +extern void tarbaby_check_landing ( edict_t * self ) ; +extern void tarbaby_jump_touch ( edict_t * self , edict_t * other , cplane_t * plane , csurface_t * surf ) ; +extern void tarbaby_fly ( edict_t * self ) ; +extern void tarbaby_run ( edict_t * self ) ; +extern void tarbaby_walk ( edict_t * self ) ; +extern void tarbaby_stand ( edict_t * self ) ; +extern void tarbaby_sight ( edict_t * self , edict_t * other ) ; +extern void SP_monster_q1_shambler ( edict_t * self ) ; +extern void shambler_melee ( edict_t * self ) ; +extern void shambler_attack ( edict_t * self ) ; +extern void shambler_skill3 ( edict_t * self ) ; +extern void shambler_magic_attack ( edict_t * self ) ; +extern void shambler_sparks ( edict_t * self ) ; +extern void shambler_smash ( edict_t * self ) ; +extern void shambler_swing_right ( edict_t * self ) ; +extern void shambler_swing_left ( edict_t * self ) ; +extern void shambler_die ( edict_t * self , edict_t * inflictor , edict_t * attacker , int damage , vec3_t point ) ; +extern void shambler_nogib ( edict_t * self ) ; +extern void shambler_dead ( edict_t * self ) ; +extern void shambler_pain ( edict_t * self , edict_t * other , float kick , int damage ) ; +extern void shambler_run ( edict_t * self ) ; +extern void shambler_walk ( edict_t * self ) ; +extern void shambler_stand ( edict_t * self ) ; +extern void shambler_attack_sound ( edict_t * self ) ; +extern void shambler_melee_sound2 ( edict_t * self ) ; +extern void shambler_melee_sound ( edict_t * self ) ; +extern void shambler_idle_sound ( edict_t * self ) ; +extern void shambler_sight ( edict_t * self , edict_t * other ) ; +extern void SP_monster_q1_shalrath ( edict_t * self ) ; +extern void q1shalrath_die ( edict_t * self , edict_t * inflictor , edict_t * attacker , int damage , vec3_t point ) ; +extern void q1shalrath_nogib ( edict_t * self ) ; +extern void q1shalrath_dead ( edict_t * self ) ; +extern void q1shalrath_sight ( edict_t * self , edict_t * other ) ; +extern void q1shalrath_attack ( edict_t * self ) ; +extern void q1shalrath_attack_snd ( edict_t * self ) ; +extern void q1shalrath_fire ( edict_t * self ) ; +extern void q1shalrath_pain ( edict_t * self , edict_t * other , float kick , int damage ) ; +extern void q1shalrath_run ( edict_t * self ) ; +extern void q1shalrath_walk ( edict_t * self ) ; +extern void q1shalrath_stand ( edict_t * self ) ; +extern void q1shalrath_idle ( edict_t * self ) ; +extern void SP_monster_q1_scrag ( edict_t * self ) ; +extern void scrag_attack ( edict_t * self ) ; +extern void scrag_fire2 ( edict_t * self ) ; +extern void scrag_fire ( edict_t * self ) ; +extern void scrag_die ( edict_t * self , edict_t * inflictor , edict_t * attacker , int damage , vec3_t point ) ; +extern void scrag_nogib ( edict_t * self ) ; +extern void scrag_dead ( edict_t * self ) ; +extern void scrag_pain ( edict_t * self , edict_t * other , float kick , int damage ) ; +extern void scrag_run ( edict_t * self ) ; +extern void scrag_walk ( edict_t * self ) ; +extern void scrag_stand ( edict_t * self ) ; +extern void scrag_idle ( edict_t * self ) ; +extern void scrag_attack_sound ( edict_t * self ) ; +extern void scrag_sight ( edict_t * self , edict_t * other ) ; +extern void SP_monster_q1_rotfish ( edict_t * self ) ; +extern void q1rotfish_die ( edict_t * self , edict_t * inflictor , edict_t * attacker , int damage , vec3_t point ) ; +extern void q1rotfish_sight ( edict_t * self , edict_t * other ) ; +extern void q1rotfish_dead ( edict_t * self ) ; +extern void q1rotfish_pain ( edict_t * self , edict_t * other , float kick , int damage ) ; +extern void q1rotfish_melee ( edict_t * self ) ; +extern void q1rotfish_bite ( edict_t * self ) ; +extern void q1rotfish_walk ( edict_t * self ) ; +extern void q1rotfish_run ( edict_t * self ) ; +extern void q1rotfish_stand ( edict_t * self ) ; +extern void q1rotfish_idle ( edict_t * self ) ; +extern void SP_monster_q1_ogre ( edict_t * self ) ; +extern void ogre_attack ( edict_t * self ) ; +extern void ogre_sawswingsound ( edict_t * self ) ; +extern void ogre_check_refire ( edict_t * self ) ; +extern void ogre_smash ( edict_t * self ) ; +extern void ogre_swing_right ( edict_t * self ) ; +extern void ogre_swing_left ( edict_t * self ) ; +extern void ogre_grenade_fire ( edict_t * self ) ; +extern void ogre_die ( edict_t * self , edict_t * inflictor , edict_t * attacker , int damage , vec3_t point ) ; +extern void ogre_dead ( edict_t * self ) ; +extern void ogre_droprockets ( edict_t * self ) ; +extern void ogre_pain ( edict_t * self , edict_t * other , float kick , int damage ) ; +extern void ogre_run ( edict_t * self ) ; +extern void ogre_walk ( edict_t * self ) ; +extern void ogre_stand ( edict_t * self ) ; +extern void ogre_drag_sound ( edict_t * self ) ; +extern void ogre_sight ( edict_t * self , edict_t * other ) ; +extern void ogre_idle_sound2 ( edict_t * self ) ; +extern void ogre_idle_sound1 ( edict_t * self ) ; +extern void SP_monster_q1_knight ( edict_t * self ) ; +extern void knight_die ( edict_t * self , edict_t * inflictor , edict_t * attacker , int damage , vec3_t point ) ; +extern void knight_nogib ( edict_t * self ) ; +extern void knight_dead ( edict_t * self ) ; +extern void knight_pain ( edict_t * self , edict_t * other , float kick , int damage ) ; +extern void knight_melee ( edict_t * self ) ; +extern void knight_hit_left ( edict_t * self ) ; +extern void knight_attack_run ( edict_t * self ) ; +extern void knight_attack ( edict_t * self ) ; +extern void knight_run ( edict_t * self ) ; +extern void knight_check_dist ( edict_t * self ) ; +extern void knight_walk ( edict_t * self ) ; +extern void knight_stand ( edict_t * self ) ; +extern void knight_standing ( edict_t * self ) ; +extern void knight_kneel ( edict_t * self ) ; +extern void knight_sword_sound ( edict_t * self ) ; +extern void knight_idle_sound ( edict_t * self ) ; +extern void knight_sight ( edict_t * self , edict_t * other ) ; +extern void knight_sight_sound ( edict_t * self ) ; +extern void SP_monster_q1_hknight ( edict_t * self ) ; +extern void hknight_magic ( edict_t * self ) ; +extern void hknight_fire_flame ( edict_t * self ) ; +extern void hknight_check_charge ( edict_t * self ) ; +extern void hknight_die ( edict_t * self , edict_t * inflictor , edict_t * attacker , int damage , vec3_t point ) ; +extern void hknight_nogib ( edict_t * self ) ; +extern void hknight_dead ( edict_t * self ) ; +extern void hknight_pain ( edict_t * self , edict_t * other , float kick , int damage ) ; +extern void hknight_melee ( edict_t * self ) ; +extern void hknight_sword_swing ( edict_t * self ) ; +extern void hknight_melee_damage ( edict_t * self ) ; +extern void hknight_run ( edict_t * self ) ; +extern void hknight_check_dist ( edict_t * self ) ; +extern void hknight_walk ( edict_t * self ) ; +extern void hknight_stand ( edict_t * self ) ; +extern void hknight_sword_sound ( edict_t * self ) ; +extern void hknight_idle_sound ( edict_t * self ) ; +extern void hknight_sight ( edict_t * self , edict_t * other ) ; +extern void hknight_sight_sound ( edict_t * self ) ; +extern void SP_monster_q1_grunt ( edict_t * self ) ; +extern void q1grunt_die ( edict_t * self , edict_t * inflictor , edict_t * attacker , int damage , vec3_t point ) ; +extern void q1grunt_dead ( edict_t * self ) ; +extern void q1grunt_dropshells ( edict_t * self ) ; +extern void q1grunt_sight ( edict_t * self , edict_t * other ) ; +extern void q1grunt_attack ( edict_t * self ) ; +extern void q1grunt_attack_refire ( edict_t * self ) ; +extern void q1grunt_fire ( edict_t * self ) ; +extern void q1grunt_pain ( edict_t * self , edict_t * other , float kick , int damage ) ; +extern void q1grunt_run ( edict_t * self ) ; +extern void q1grunt_walk ( edict_t * self ) ; +extern void q1grunt_stand ( edict_t * self ) ; +extern void q1grunt_idle ( edict_t * self ) ; +extern void SP_monster_q1_fiend ( edict_t * self ) ; +extern void fiend_die ( edict_t * self , edict_t * inflictor , edict_t * attacker , int damage , vec3_t point ) ; +extern void fiend_nogib ( edict_t * self ) ; +extern void fiend_dead ( edict_t * self ) ; +extern void fiend_pain ( edict_t * self , edict_t * other , float kick , int damage ) ; +extern qboolean fiend_checkattack ( edict_t * self ) ; +extern void fiend_jump ( edict_t * self ) ; +extern void fiend_check_landing ( edict_t * self ) ; +extern void fiend_jump_takeoff ( edict_t * self ) ; +extern void fiend_jump_touch ( edict_t * self , edict_t * other , cplane_t * plane , csurface_t * surf ) ; +extern void fiend_melee ( edict_t * self ) ; +extern void fiend_check_refire ( edict_t * self ) ; +extern void fiend_hit_right ( edict_t * self ) ; +extern void fiend_hit_left ( edict_t * self ) ; +extern void fiend_run ( edict_t * self ) ; +extern void fiend_walk ( edict_t * self ) ; +extern void fiend_stand ( edict_t * self ) ; +extern void fiend_idle_sound2 ( edict_t * self ) ; +extern void fiend_idle_sound ( edict_t * self ) ; +extern void fiend_sight ( edict_t * self , edict_t * other ) ; +extern void SP_monster_q1_enforcer ( edict_t * self ) ; +extern void q1enforcer_attack ( edict_t * self ) ; +extern void q1enforcer_secondfire ( edict_t * self ) ; +extern void q1enforcer_fire ( edict_t * self ) ; +extern void q1enforcer_die ( edict_t * self , edict_t * inflictor , edict_t * attacker , int damage , vec3_t point ) ; +extern void q1enforcer_throw_backpack ( edict_t * self ) ; +extern void q1enforcer_dead ( edict_t * self ) ; +extern void q1enforcer_pain ( edict_t * self , edict_t * other , float kick , int damage ) ; +extern void q1enforcer_run ( edict_t * self ) ; +extern void q1enforcer_walk ( edict_t * self ) ; +extern void q1enforcer_stand ( edict_t * self ) ; +extern void q1enforcer_search ( edict_t * self ) ; +extern void q1enforcer_sight ( edict_t * self , edict_t * other ) ; +extern void q1enforcer_idlesound ( edict_t * self ) ; +extern void SP_monster_q1_dog ( edict_t * self ) ; +extern void q1dog_die ( edict_t * self , edict_t * inflictor , edict_t * attacker , int damage , vec3_t point ) ; +extern void q1dog_nogib ( edict_t * self ) ; +extern void q1dog_dead ( edict_t * self ) ; +extern qboolean q1dog_checkattack ( edict_t * self ) ; +extern void q1dog_leap ( edict_t * self ) ; +extern void q1dog_checklanding ( edict_t * self ) ; +extern void q1dog_takeoff ( edict_t * self ) ; +extern void q1dog_jump_touch ( edict_t * self , edict_t * other , cplane_t * plane , csurface_t * surf ) ; +extern void q1dog_melee ( edict_t * self ) ; +extern void q1dog_checkrefire ( edict_t * self ) ; +extern void q1dog_bite ( edict_t * self ) ; +extern void q1dog_pain ( edict_t * self , edict_t * other , float kick , int damage ) ; +extern void q1dog_run ( edict_t * self ) ; +extern void q1dog_walk ( edict_t * self ) ; +extern void q1dog_stand ( edict_t * self ) ; +extern void q1dog_sight ( edict_t * self , edict_t * other ) ; +extern void q1dog_idle ( edict_t * self ) ; extern void SP_monster_parasite ( edict_t * self ) ; extern void parasite_die ( edict_t * self , edict_t * inflictor , edict_t * attacker , int damage , vec3_t point ) ; extern void parasite_dead ( edict_t * self ) ; @@ -1153,6 +1369,31 @@ extern void actor_walk_back ( edict_t * self ) ; extern void actor_walk ( edict_t * self ) ; extern void actor_stand ( edict_t * self ) ; extern void InitLithiumVars ( void ) ; +extern void q1_fire_gib ( edict_t * self , vec3_t start , vec3_t aimdir , int damage , int speed ) ; +extern void q1_zombiegib_touch ( edict_t * ent , edict_t * other , cplane_t * plane , csurface_t * surf ) ; +extern void q1_fire_acidspit ( edict_t * self , vec3_t start , vec3_t dir , int damage , int speed ) ; +extern void q1_acidbolt_touch ( edict_t * ent , edict_t * other , cplane_t * plane , csurface_t * surf ) ; +extern void q1_fire_lavaball ( edict_t * self , vec3_t start , vec3_t dir , int damage , int speed , float damage_radius , int radius_damage ) ; +extern void q1_lavaball_touch ( edict_t * ent , edict_t * other , cplane_t * plane , csurface_t * surf ) ; +extern void q1_fire_firepod ( edict_t * self , vec3_t dir ) ; +extern void q1_firepod_home ( edict_t * self ) ; +extern void q1_firepod_touch ( edict_t * self , edict_t * other , cplane_t * plane , csurface_t * surf ) ; +extern void q1_fire_lightning ( edict_t * self , vec3_t start , vec3_t dir , int damage ) ; +extern void q1_fire_rocket ( edict_t * self , vec3_t start , vec3_t dir , int damage , int speed , float damage_radius , int radius_damage ) ; +extern void q1rocket_trail ( edict_t * self , vec3_t start , vec3_t dir ) ; +extern void q1rocketTrail_touch ( edict_t * ent , edict_t * other , cplane_t * plane , csurface_t * surf ) ; +extern void q1_rocket_touch ( edict_t * ent , edict_t * other , cplane_t * plane , csurface_t * surf ) ; +extern void q1_fire_grenade ( edict_t * self , vec3_t start , vec3_t aimdir , int damage , int speed , float timer , float damage_radius ) ; +extern void q1_grenade_touch ( edict_t * ent , edict_t * other , cplane_t * plane , csurface_t * surf ) ; +extern void q1_grenade_explode ( edict_t * ent ) ; +extern void q1_explode ( edict_t * self ) ; +extern void q1_fire_flame ( edict_t * self , vec3_t start , vec3_t dir , float leftrightoff ) ; +extern void q1_flame_touch ( edict_t * self , edict_t * other , cplane_t * plane , csurface_t * surf ) ; +extern void q1_flame_splash ( int type , int count , int color , vec3_t start , vec3_t movdir , vec3_t origin ) ; +extern void q1_fire_laser ( edict_t * self , vec3_t start , vec3_t dir , int damage , int speed ) ; +extern void q1_laser_touch ( edict_t * self , edict_t * other , cplane_t * plane , csurface_t * surf ) ; +extern void q1_fire_nail ( edict_t * self , vec3_t start , vec3_t dir , int damage , int speed , qboolean sng ) ; +extern void q1_nail_touch ( edict_t * self , edict_t * other , cplane_t * plane , csurface_t * surf ) ; extern void Trap_Explode ( edict_t * ent ) ; extern void Cmd_KillTrap_f ( edict_t * ent ) ; extern void Trap_Die ( edict_t * self , edict_t * inflictor , edict_t * attacker , int damage , vec3_t point ) ; @@ -1230,6 +1471,9 @@ extern void vehicle_disengage ( edict_t * vehicle ) ; extern void vehicle_touch ( edict_t * self , edict_t * other , cplane_t * plane , csurface_t * surf ) ; extern void vehicle_blocked ( edict_t * self , edict_t * other ) ; extern void func_vehicle_explode ( edict_t * self , edict_t * inflictor , edict_t * attacker , int damage , vec3_t point ) ; +extern void Q1TeleportSounds2 ( edict_t * ent1 , edict_t * ent2 ) ; +extern void Q1TeleportSounds ( edict_t * ent ) ; +extern float PointDist ( vec3_t x , vec3_t y ) ; extern qboolean UseRegularGoodGuyFlag ( edict_t * monster ) ; extern qboolean UseSpecialGoodGuyFlag ( edict_t * monster ) ; extern qboolean CheckCoop_MapHacks ( edict_t * ent ) ; @@ -1818,6 +2062,28 @@ extern void monster_fire_bullet ( edict_t * self , vec3_t start , vec3_t dir , i extern qboolean M_SetDeath ( edict_t * self , mmove_t * * deathmoves ) ; extern void FadeDieSink ( edict_t * ent ) ; extern void FadeSink ( edict_t * ent ) ; +extern void SP_misc_q1_fireball ( edict_t * self ) ; +extern void q1_fireball_fly ( edict_t * self ) ; +extern void q1_fireball_touch ( edict_t * self , edict_t * other , cplane_t * plane , csurface_t * surf ) ; +extern void SP_misc_q1_explobox ( edict_t * self ) ; +extern void q1_explobox_delay ( edict_t * self , edict_t * inflictor , edict_t * attacker , int damage , vec3_t point ) ; +extern void q1_barrel_explode ( edict_t * self ) ; +extern void SP_target_q1_trap ( edict_t * self ) ; +extern void q1_use_target_trapshooter ( edict_t * self , edict_t * other , edict_t * activator ) ; +extern void SP_misc_q1_torch ( edict_t * ent ) ; +extern void q1_torch_think ( edict_t * self ) ; +extern void SP_misc_q1_large_flame ( edict_t * ent ) ; +extern void q1_large_flame_think ( edict_t * self ) ; +extern void SP_misc_q1_small_flame ( edict_t * ent ) ; +extern void q1_small_flame_think ( edict_t * self ) ; +extern void SP_misc_q1_globe ( edict_t * self ) ; +extern void SP_misc_q1_air_bubbles ( edict_t * self ) ; +extern void make_bubbles ( edict_t * self ) ; +extern void bubble_bob ( edict_t * bubble ) ; +extern void bubble_split ( edict_t * bubble ) ; +extern void bubble_touch ( edict_t * ent , edict_t * other , cplane_t * plane , csurface_t * surf ) ; +extern void SP_misc_q1_zombie_crucified ( edict_t * self ) ; +extern void misc_zombie_crucified_think ( edict_t * self ) ; extern int PatchDeadSoldier ( void ) ; extern void SP_target_fountain ( edict_t * ent ) ; extern void target_fountain_delayed_use ( edict_t * self ) ; diff --git a/missionpack/g_func_list.h b/missionpack/g_func_list.h index 4a47524..a922b89 100644 --- a/missionpack/g_func_list.h +++ b/missionpack/g_func_list.h @@ -540,6 +540,222 @@ {"soldier_idle", (byte *)soldier_idle}, {"soldier_stop_charge", (byte *)soldier_stop_charge}, {"soldier_start_charge", (byte *)soldier_start_charge}, +{"SP_monster_q1_zombie", (byte *)SP_monster_q1_zombie}, +{"q1zombie_die", (byte *)q1zombie_die}, +{"q1zombie_sight", (byte *)q1zombie_sight}, +{"q1zombie_fallagain", (byte *)q1zombie_fallagain}, +{"q1zombie_pain", (byte *)q1zombie_pain}, +{"q1zombie_down", (byte *)q1zombie_down}, +{"q1zombie_attack", (byte *)q1zombie_attack}, +{"q1zombie_firegib3", (byte *)q1zombie_firegib3}, +{"q1zombie_firegib2", (byte *)q1zombie_firegib2}, +{"q1zombie_firegib1", (byte *)q1zombie_firegib1}, +{"q1zombie_firegib", (byte *)q1zombie_firegib}, +{"q1zombie_run", (byte *)q1zombie_run}, +{"q1zombie_walk", (byte *)q1zombie_walk}, +{"q1zombie_crucify", (byte *)q1zombie_crucify}, +{"q1zombie_stand", (byte *)q1zombie_stand}, +{"q1zombie_fall", (byte *)q1zombie_fall}, +{"q1zombie_pain2", (byte *)q1zombie_pain2}, +{"q1zombie_pain1", (byte *)q1zombie_pain1}, +{"q1zombie_idle2", (byte *)q1zombie_idle2}, +{"q1zombie_idle", (byte *)q1zombie_idle}, +{"q1zombie_idle3", (byte *)q1zombie_idle3}, +{"q1zombie_Cidle", (byte *)q1zombie_Cidle}, +{"SP_monster_q1_tarbaby", (byte *)SP_monster_q1_tarbaby}, +{"tarbaby_die", (byte *)tarbaby_die}, +{"tarbaby_dead", (byte *)tarbaby_dead}, +{"tarbaby_pain", (byte *)tarbaby_pain}, +{"tarbaby_jump", (byte *)tarbaby_jump}, +{"tarbaby_takeoff", (byte *)tarbaby_takeoff}, +{"tarbaby_check_landing", (byte *)tarbaby_check_landing}, +{"tarbaby_jump_touch", (byte *)tarbaby_jump_touch}, +{"tarbaby_fly", (byte *)tarbaby_fly}, +{"tarbaby_run", (byte *)tarbaby_run}, +{"tarbaby_walk", (byte *)tarbaby_walk}, +{"tarbaby_stand", (byte *)tarbaby_stand}, +{"tarbaby_sight", (byte *)tarbaby_sight}, +{"SP_monster_q1_shambler", (byte *)SP_monster_q1_shambler}, +{"shambler_melee", (byte *)shambler_melee}, +{"shambler_attack", (byte *)shambler_attack}, +{"shambler_skill3", (byte *)shambler_skill3}, +{"shambler_magic_attack", (byte *)shambler_magic_attack}, +{"shambler_sparks", (byte *)shambler_sparks}, +{"shambler_smash", (byte *)shambler_smash}, +{"shambler_swing_right", (byte *)shambler_swing_right}, +{"shambler_swing_left", (byte *)shambler_swing_left}, +{"shambler_die", (byte *)shambler_die}, +{"shambler_nogib", (byte *)shambler_nogib}, +{"shambler_dead", (byte *)shambler_dead}, +{"shambler_pain", (byte *)shambler_pain}, +{"shambler_run", (byte *)shambler_run}, +{"shambler_walk", (byte *)shambler_walk}, +{"shambler_stand", (byte *)shambler_stand}, +{"shambler_attack_sound", (byte *)shambler_attack_sound}, +{"shambler_melee_sound2", (byte *)shambler_melee_sound2}, +{"shambler_melee_sound", (byte *)shambler_melee_sound}, +{"shambler_idle_sound", (byte *)shambler_idle_sound}, +{"shambler_sight", (byte *)shambler_sight}, +{"SP_monster_q1_shalrath", (byte *)SP_monster_q1_shalrath}, +{"q1shalrath_die", (byte *)q1shalrath_die}, +{"q1shalrath_nogib", (byte *)q1shalrath_nogib}, +{"q1shalrath_dead", (byte *)q1shalrath_dead}, +{"q1shalrath_sight", (byte *)q1shalrath_sight}, +{"q1shalrath_attack", (byte *)q1shalrath_attack}, +{"q1shalrath_attack_snd", (byte *)q1shalrath_attack_snd}, +{"q1shalrath_fire", (byte *)q1shalrath_fire}, +{"q1shalrath_pain", (byte *)q1shalrath_pain}, +{"q1shalrath_run", (byte *)q1shalrath_run}, +{"q1shalrath_walk", (byte *)q1shalrath_walk}, +{"q1shalrath_stand", (byte *)q1shalrath_stand}, +{"q1shalrath_idle", (byte *)q1shalrath_idle}, +{"SP_monster_q1_scrag", (byte *)SP_monster_q1_scrag}, +{"scrag_attack", (byte *)scrag_attack}, +{"scrag_fire2", (byte *)scrag_fire2}, +{"scrag_fire", (byte *)scrag_fire}, +{"scrag_die", (byte *)scrag_die}, +{"scrag_nogib", (byte *)scrag_nogib}, +{"scrag_dead", (byte *)scrag_dead}, +{"scrag_pain", (byte *)scrag_pain}, +{"scrag_run", (byte *)scrag_run}, +{"scrag_walk", (byte *)scrag_walk}, +{"scrag_stand", (byte *)scrag_stand}, +{"scrag_idle", (byte *)scrag_idle}, +{"scrag_attack_sound", (byte *)scrag_attack_sound}, +{"scrag_sight", (byte *)scrag_sight}, +{"SP_monster_q1_rotfish", (byte *)SP_monster_q1_rotfish}, +{"q1rotfish_die", (byte *)q1rotfish_die}, +{"q1rotfish_sight", (byte *)q1rotfish_sight}, +{"q1rotfish_dead", (byte *)q1rotfish_dead}, +{"q1rotfish_pain", (byte *)q1rotfish_pain}, +{"q1rotfish_melee", (byte *)q1rotfish_melee}, +{"q1rotfish_bite", (byte *)q1rotfish_bite}, +{"q1rotfish_walk", (byte *)q1rotfish_walk}, +{"q1rotfish_run", (byte *)q1rotfish_run}, +{"q1rotfish_stand", (byte *)q1rotfish_stand}, +{"q1rotfish_idle", (byte *)q1rotfish_idle}, +{"SP_monster_q1_ogre", (byte *)SP_monster_q1_ogre}, +{"ogre_attack", (byte *)ogre_attack}, +{"ogre_sawswingsound", (byte *)ogre_sawswingsound}, +{"ogre_check_refire", (byte *)ogre_check_refire}, +{"ogre_smash", (byte *)ogre_smash}, +{"ogre_swing_right", (byte *)ogre_swing_right}, +{"ogre_swing_left", (byte *)ogre_swing_left}, +{"ogre_grenade_fire", (byte *)ogre_grenade_fire}, +{"ogre_die", (byte *)ogre_die}, +{"ogre_dead", (byte *)ogre_dead}, +{"ogre_droprockets", (byte *)ogre_droprockets}, +{"ogre_pain", (byte *)ogre_pain}, +{"ogre_run", (byte *)ogre_run}, +{"ogre_walk", (byte *)ogre_walk}, +{"ogre_stand", (byte *)ogre_stand}, +{"ogre_drag_sound", (byte *)ogre_drag_sound}, +{"ogre_sight", (byte *)ogre_sight}, +{"ogre_idle_sound2", (byte *)ogre_idle_sound2}, +{"ogre_idle_sound1", (byte *)ogre_idle_sound1}, +{"SP_monster_q1_knight", (byte *)SP_monster_q1_knight}, +{"knight_die", (byte *)knight_die}, +{"knight_nogib", (byte *)knight_nogib}, +{"knight_dead", (byte *)knight_dead}, +{"knight_pain", (byte *)knight_pain}, +{"knight_melee", (byte *)knight_melee}, +{"knight_hit_left", (byte *)knight_hit_left}, +{"knight_attack_run", (byte *)knight_attack_run}, +{"knight_attack", (byte *)knight_attack}, +{"knight_run", (byte *)knight_run}, +{"knight_check_dist", (byte *)knight_check_dist}, +{"knight_walk", (byte *)knight_walk}, +{"knight_stand", (byte *)knight_stand}, +{"knight_standing", (byte *)knight_standing}, +{"knight_kneel", (byte *)knight_kneel}, +{"knight_sword_sound", (byte *)knight_sword_sound}, +{"knight_idle_sound", (byte *)knight_idle_sound}, +{"knight_sight", (byte *)knight_sight}, +{"knight_sight_sound", (byte *)knight_sight_sound}, +{"SP_monster_q1_hknight", (byte *)SP_monster_q1_hknight}, +{"hknight_magic", (byte *)hknight_magic}, +{"hknight_fire_flame", (byte *)hknight_fire_flame}, +{"hknight_check_charge", (byte *)hknight_check_charge}, +{"hknight_die", (byte *)hknight_die}, +{"hknight_nogib", (byte *)hknight_nogib}, +{"hknight_dead", (byte *)hknight_dead}, +{"hknight_pain", (byte *)hknight_pain}, +{"hknight_melee", (byte *)hknight_melee}, +{"hknight_sword_swing", (byte *)hknight_sword_swing}, +{"hknight_melee_damage", (byte *)hknight_melee_damage}, +{"hknight_run", (byte *)hknight_run}, +{"hknight_check_dist", (byte *)hknight_check_dist}, +{"hknight_walk", (byte *)hknight_walk}, +{"hknight_stand", (byte *)hknight_stand}, +{"hknight_sword_sound", (byte *)hknight_sword_sound}, +{"hknight_idle_sound", (byte *)hknight_idle_sound}, +{"hknight_sight", (byte *)hknight_sight}, +{"hknight_sight_sound", (byte *)hknight_sight_sound}, +{"SP_monster_q1_grunt", (byte *)SP_monster_q1_grunt}, +{"q1grunt_die", (byte *)q1grunt_die}, +{"q1grunt_dead", (byte *)q1grunt_dead}, +{"q1grunt_dropshells", (byte *)q1grunt_dropshells}, +{"q1grunt_sight", (byte *)q1grunt_sight}, +{"q1grunt_attack", (byte *)q1grunt_attack}, +{"q1grunt_attack_refire", (byte *)q1grunt_attack_refire}, +{"q1grunt_fire", (byte *)q1grunt_fire}, +{"q1grunt_pain", (byte *)q1grunt_pain}, +{"q1grunt_run", (byte *)q1grunt_run}, +{"q1grunt_walk", (byte *)q1grunt_walk}, +{"q1grunt_stand", (byte *)q1grunt_stand}, +{"q1grunt_idle", (byte *)q1grunt_idle}, +{"SP_monster_q1_fiend", (byte *)SP_monster_q1_fiend}, +{"fiend_die", (byte *)fiend_die}, +{"fiend_nogib", (byte *)fiend_nogib}, +{"fiend_dead", (byte *)fiend_dead}, +{"fiend_pain", (byte *)fiend_pain}, +{"fiend_checkattack", (byte *)fiend_checkattack}, +{"fiend_jump", (byte *)fiend_jump}, +{"fiend_check_landing", (byte *)fiend_check_landing}, +{"fiend_jump_takeoff", (byte *)fiend_jump_takeoff}, +{"fiend_jump_touch", (byte *)fiend_jump_touch}, +{"fiend_melee", (byte *)fiend_melee}, +{"fiend_check_refire", (byte *)fiend_check_refire}, +{"fiend_hit_right", (byte *)fiend_hit_right}, +{"fiend_hit_left", (byte *)fiend_hit_left}, +{"fiend_run", (byte *)fiend_run}, +{"fiend_walk", (byte *)fiend_walk}, +{"fiend_stand", (byte *)fiend_stand}, +{"fiend_idle_sound2", (byte *)fiend_idle_sound2}, +{"fiend_idle_sound", (byte *)fiend_idle_sound}, +{"fiend_sight", (byte *)fiend_sight}, +{"SP_monster_q1_enforcer", (byte *)SP_monster_q1_enforcer}, +{"q1enforcer_attack", (byte *)q1enforcer_attack}, +{"q1enforcer_secondfire", (byte *)q1enforcer_secondfire}, +{"q1enforcer_fire", (byte *)q1enforcer_fire}, +{"q1enforcer_die", (byte *)q1enforcer_die}, +{"q1enforcer_throw_backpack", (byte *)q1enforcer_throw_backpack}, +{"q1enforcer_dead", (byte *)q1enforcer_dead}, +{"q1enforcer_pain", (byte *)q1enforcer_pain}, +{"q1enforcer_run", (byte *)q1enforcer_run}, +{"q1enforcer_walk", (byte *)q1enforcer_walk}, +{"q1enforcer_stand", (byte *)q1enforcer_stand}, +{"q1enforcer_search", (byte *)q1enforcer_search}, +{"q1enforcer_sight", (byte *)q1enforcer_sight}, +{"q1enforcer_idlesound", (byte *)q1enforcer_idlesound}, +{"SP_monster_q1_dog", (byte *)SP_monster_q1_dog}, +{"q1dog_die", (byte *)q1dog_die}, +{"q1dog_nogib", (byte *)q1dog_nogib}, +{"q1dog_dead", (byte *)q1dog_dead}, +{"q1dog_checkattack", (byte *)q1dog_checkattack}, +{"q1dog_leap", (byte *)q1dog_leap}, +{"q1dog_checklanding", (byte *)q1dog_checklanding}, +{"q1dog_takeoff", (byte *)q1dog_takeoff}, +{"q1dog_jump_touch", (byte *)q1dog_jump_touch}, +{"q1dog_melee", (byte *)q1dog_melee}, +{"q1dog_checkrefire", (byte *)q1dog_checkrefire}, +{"q1dog_bite", (byte *)q1dog_bite}, +{"q1dog_pain", (byte *)q1dog_pain}, +{"q1dog_run", (byte *)q1dog_run}, +{"q1dog_walk", (byte *)q1dog_walk}, +{"q1dog_stand", (byte *)q1dog_stand}, +{"q1dog_sight", (byte *)q1dog_sight}, +{"q1dog_idle", (byte *)q1dog_idle}, {"SP_monster_parasite", (byte *)SP_monster_parasite}, {"parasite_die", (byte *)parasite_die}, {"parasite_dead", (byte *)parasite_dead}, @@ -1153,6 +1369,31 @@ {"actor_walk", (byte *)actor_walk}, {"actor_stand", (byte *)actor_stand}, {"InitLithiumVars", (byte *)InitLithiumVars}, +{"q1_fire_gib", (byte *)q1_fire_gib}, +{"q1_zombiegib_touch", (byte *)q1_zombiegib_touch}, +{"q1_fire_acidspit", (byte *)q1_fire_acidspit}, +{"q1_acidbolt_touch", (byte *)q1_acidbolt_touch}, +{"q1_fire_lavaball", (byte *)q1_fire_lavaball}, +{"q1_lavaball_touch", (byte *)q1_lavaball_touch}, +{"q1_fire_firepod", (byte *)q1_fire_firepod}, +{"q1_firepod_home", (byte *)q1_firepod_home}, +{"q1_firepod_touch", (byte *)q1_firepod_touch}, +{"q1_fire_lightning", (byte *)q1_fire_lightning}, +{"q1_fire_rocket", (byte *)q1_fire_rocket}, +{"q1rocket_trail", (byte *)q1rocket_trail}, +{"q1rocketTrail_touch", (byte *)q1rocketTrail_touch}, +{"q1_rocket_touch", (byte *)q1_rocket_touch}, +{"q1_fire_grenade", (byte *)q1_fire_grenade}, +{"q1_grenade_touch", (byte *)q1_grenade_touch}, +{"q1_grenade_explode", (byte *)q1_grenade_explode}, +{"q1_explode", (byte *)q1_explode}, +{"q1_fire_flame", (byte *)q1_fire_flame}, +{"q1_flame_touch", (byte *)q1_flame_touch}, +{"q1_flame_splash", (byte *)q1_flame_splash}, +{"q1_fire_laser", (byte *)q1_fire_laser}, +{"q1_laser_touch", (byte *)q1_laser_touch}, +{"q1_fire_nail", (byte *)q1_fire_nail}, +{"q1_nail_touch", (byte *)q1_nail_touch}, {"Trap_Explode", (byte *)Trap_Explode}, {"Cmd_KillTrap_f", (byte *)Cmd_KillTrap_f}, {"Trap_Die", (byte *)Trap_Die}, @@ -1230,6 +1471,9 @@ {"vehicle_touch", (byte *)vehicle_touch}, {"vehicle_blocked", (byte *)vehicle_blocked}, {"func_vehicle_explode", (byte *)func_vehicle_explode}, +{"Q1TeleportSounds2", (byte *)Q1TeleportSounds2}, +{"Q1TeleportSounds", (byte *)Q1TeleportSounds}, +{"PointDist", (byte *)PointDist}, {"UseRegularGoodGuyFlag", (byte *)UseRegularGoodGuyFlag}, {"UseSpecialGoodGuyFlag", (byte *)UseSpecialGoodGuyFlag}, {"CheckCoop_MapHacks", (byte *)CheckCoop_MapHacks}, @@ -1818,6 +2062,28 @@ {"M_SetDeath", (byte *)M_SetDeath}, {"FadeDieSink", (byte *)FadeDieSink}, {"FadeSink", (byte *)FadeSink}, +{"SP_misc_q1_fireball", (byte *)SP_misc_q1_fireball}, +{"q1_fireball_fly", (byte *)q1_fireball_fly}, +{"q1_fireball_touch", (byte *)q1_fireball_touch}, +{"SP_misc_q1_explobox", (byte *)SP_misc_q1_explobox}, +{"q1_explobox_delay", (byte *)q1_explobox_delay}, +{"q1_barrel_explode", (byte *)q1_barrel_explode}, +{"SP_target_q1_trap", (byte *)SP_target_q1_trap}, +{"q1_use_target_trapshooter", (byte *)q1_use_target_trapshooter}, +{"SP_misc_q1_torch", (byte *)SP_misc_q1_torch}, +{"q1_torch_think", (byte *)q1_torch_think}, +{"SP_misc_q1_large_flame", (byte *)SP_misc_q1_large_flame}, +{"q1_large_flame_think", (byte *)q1_large_flame_think}, +{"SP_misc_q1_small_flame", (byte *)SP_misc_q1_small_flame}, +{"q1_small_flame_think", (byte *)q1_small_flame_think}, +{"SP_misc_q1_globe", (byte *)SP_misc_q1_globe}, +{"SP_misc_q1_air_bubbles", (byte *)SP_misc_q1_air_bubbles}, +{"make_bubbles", (byte *)make_bubbles}, +{"bubble_bob", (byte *)bubble_bob}, +{"bubble_split", (byte *)bubble_split}, +{"bubble_touch", (byte *)bubble_touch}, +{"SP_misc_q1_zombie_crucified", (byte *)SP_misc_q1_zombie_crucified}, +{"misc_zombie_crucified_think", (byte *)misc_zombie_crucified_think}, {"PatchDeadSoldier", (byte *)PatchDeadSoldier}, {"SP_target_fountain", (byte *)SP_target_fountain}, {"target_fountain_delayed_use", (byte *)target_fountain_delayed_use}, diff --git a/missionpack/g_items.c b/missionpack/g_items.c index 712c325..c1f4607 100644 --- a/missionpack/g_items.c +++ b/missionpack/g_items.c @@ -67,6 +67,15 @@ int tesla_index; int trap_index; int shocksphere_index; +// added for convenience with triger_key sound hack +int key_q1_med_silver_index; +int key_q1_med_gold_index; +int key_q1_rune_silver_index; +int key_q1_rune_gold_index; +int key_q1_base_silver_index; +int key_q1_base_gold_index; + + #define HEALTH_IGNORE_MAX 1 #define HEALTH_TIMED 2 #define HEALTH_FOODCUBE 4 @@ -2118,7 +2127,7 @@ gitem_t itemlist[] = // ARMOR // -//1 +// 1 /*QUAKED item_armor_body (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -2142,7 +2151,7 @@ gitem_t itemlist[] = "" //precache }, -//2 +// 2 /*QUAKED item_armor_combat (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -2166,7 +2175,7 @@ gitem_t itemlist[] = "" //precache }, -//3 +// 3 /*QUAKED item_armor_jacket (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -2190,7 +2199,7 @@ gitem_t itemlist[] = "" //precache }, -//4 +// 4 /*QUAKED item_armor_shard (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -2219,7 +2228,7 @@ gitem_t itemlist[] = }, //Knightmare- armor shard that lies flat on the ground -//5 +// 5 /*QUAKED item_armor_shard_flat (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -2247,7 +2256,7 @@ gitem_t itemlist[] = "" //precache }, -//6 +// 6 /*QUAKED item_power_screen (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -2271,7 +2280,7 @@ gitem_t itemlist[] = "misc/power2.wav misc/power1.wav" //precache }, -//7 +// 7 /*QUAKED item_power_shield (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -2298,7 +2307,7 @@ gitem_t itemlist[] = // // WEAPONS // -//8 +// 8 /* weapon_blaster (.3 .3 1) (-16 -16 -16) (16 16 16) */ { @@ -2326,7 +2335,7 @@ gitem_t itemlist[] = #endif }, -//9 +// 9 /*QUAKED weapon_shotgun (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -2350,7 +2359,7 @@ gitem_t itemlist[] = "weapons/shotgf1b.wav weapons/shotgr1b.wav" //precache }, -//10 +// 10 /*QUAKED weapon_supershotgun (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -2374,7 +2383,7 @@ gitem_t itemlist[] = "weapons/sshotf1b.wav" //precache }, -//11 +// 11 /*QUAKED weapon_machinegun (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -2398,7 +2407,7 @@ gitem_t itemlist[] = "weapons/machgf1b.wav weapons/machgf2b.wav weapons/machgf3b.wav weapons/machgf4b.wav weapons/machgf5b.wav" //precache }, -//12 +// 12 /*QUAKED weapon_chaingun (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -2422,7 +2431,7 @@ gitem_t itemlist[] = "weapons/chngnu1a.wav weapons/chngnl1a.wav weapons/machgf3b.wav` weapons/chngnd1a.wav" //precache }, -//13 +// 13 // ROGUE /*QUAKED weapon_etf_rifle (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ @@ -2448,7 +2457,7 @@ gitem_t itemlist[] = }, // rogue -//14 +// 14 /*QUAKED ammo_grenades (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -2472,7 +2481,7 @@ gitem_t itemlist[] = "weapons/hgrent1a.wav weapons/hgrena1b.wav weapons/hgrenc1b.wav weapons/hgrenb1a.wav weapons/hgrenb2a.wav" //precache }, -//15 +// 15 /*QUAKED weapon_grenadelauncher (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -2496,7 +2505,7 @@ gitem_t itemlist[] = "models/objects/grenade/tris.md2 weapons/grenlf1a.wav weapons/grenlr1b.wav weapons/grenlb1b.wav" //precache }, -//16 +// 16 // ROGUE /*QUAKED weapon_proxlauncher (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ @@ -2522,7 +2531,7 @@ gitem_t itemlist[] = }, // rogue -//17 +// 17 /*QUAKED weapon_rocketlauncher (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -2546,7 +2555,7 @@ gitem_t itemlist[] = "models/objects/rocket/tris.md2 weapons/rockfly.wav weapons/rocklf1a.wav weapons/rocklr1b.wav models/objects/debris2/tris.md2" //precache }, -//18 +// 18 /*QUAKED weapon_hyperblaster (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -2574,7 +2583,7 @@ gitem_t itemlist[] = #endif }, -//19 +// 19 // ROGUE /*QUAKED weapon_plasmabeam (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ @@ -2600,7 +2609,7 @@ gitem_t itemlist[] = }, //rogue -//20 +// 20 /*QUAKED weapon_boomer (.3 .3 1) (-16 -16 -16) (16 16 16) */ @@ -2629,7 +2638,7 @@ gitem_t itemlist[] = #endif }, -//21 +// 21 /*QUAKED weapon_railgun (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -2653,7 +2662,7 @@ gitem_t itemlist[] = "weapons/rg_hum.wav weapons/railgf1a.wav" //precache }, -//22 +// 22 /*QUAKED weapon_phalanx (.3 .3 1) (-16 -16 -16) (16 16 16) */ @@ -2682,7 +2691,7 @@ gitem_t itemlist[] = #endif }, -//23 +// 23 /*QUAKED weapon_bfg (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -2713,7 +2722,7 @@ gitem_t itemlist[] = // ========================= // ROGUE WEAPONS -//24 +// 24 /*QUAKED weapon_disintegrator (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -2737,7 +2746,7 @@ gitem_t itemlist[] = "models/items/spawngro/tris.md2 models/proj/disintegrator/tris.md2 weapons/disrupt.wav weapons/disint2.wav weapons/disrupthit.wav", // precaches }, -//25 +// 25 /*QUAKED weapon_chainfist (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -2763,7 +2772,7 @@ gitem_t itemlist[] = // ROGUE WEAPONS // ========================= -//26 +// 26 /*QUAKED weapon_shockwave (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -2787,7 +2796,7 @@ gitem_t itemlist[] = "weapons/shockactive.wav weapons/shock_hum.wav weapons/shockfire.wav weapons/shockaway.wav weapons/shockhit.wav weapons/shockexp.wav models/objects/shocksphere/tris.md2 models/objects/shockfield/tris.md2 sprites/s_trap.sp2" }, -//27 +// 27 /*QUAKED weapon_hml (.3 .3 1) (-16 -16 -16) (16 16 16) */ { @@ -2811,7 +2820,7 @@ gitem_t itemlist[] = "models/objects/rocket/tris.md2 weapons/rockfly.wav weapons/rocklf1a.wav weapons/rocklr1b.wav models/objects/debris2/tris.md2" }, -//28 +// 28 // Lazarus: No weapon - we HAVE to have a weapon { "weapon_null", @@ -2837,7 +2846,7 @@ gitem_t itemlist[] = // AMMO ITEMS // -//29 +// 29 /*QUAKED ammo_shells (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -2861,7 +2870,7 @@ gitem_t itemlist[] = "" //precache }, -//30 +// 30 /*QUAKED ammo_bullets (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -2885,7 +2894,7 @@ gitem_t itemlist[] = "" //precache }, -//31 +// 31 /*QUAKED ammo_cells (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -2909,7 +2918,7 @@ gitem_t itemlist[] = "" //precache }, -//32 +// 32 /*QUAKED ammo_rockets (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -2933,7 +2942,7 @@ gitem_t itemlist[] = "" //precache }, -//33 +// 33 /*QUAKED ammo_homing_missiles (.3 .3 1) (-16 -16 -16) (16 16 16) */ { @@ -2957,7 +2966,7 @@ gitem_t itemlist[] = "" //precache }, -//34 +// 34 /*QUAKED ammo_slugs (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -2981,7 +2990,7 @@ gitem_t itemlist[] = "" //precache }, -//35 +// 35 /*QUAKED ammo_magslug (.3 .3 1) (-16 -16 -16) (16 16 16) */ { @@ -3008,7 +3017,7 @@ gitem_t itemlist[] = // ======================================= // ROGUE AMMO -//36 +// 36 /*QUAKED ammo_flechettes (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -3031,7 +3040,7 @@ gitem_t itemlist[] = AMMO_FLECHETTES }, -//37 +// 37 /*QUAKED ammo_disruptor (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -3054,7 +3063,7 @@ gitem_t itemlist[] = AMMO_DISRUPTOR, // tag }, -//38 +// 38 /*QUAKED ammo_prox (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -3078,7 +3087,7 @@ gitem_t itemlist[] = "models/weapons/g_prox/tris.md2 weapons/proxwarn.wav" // precaches }, -//39 +// 39 /*QUAKED ammo_shocksphere (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -3102,7 +3111,7 @@ gitem_t itemlist[] = "" // precache }, -//40 +// 40 /*QUAKED ammo_tesla (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -3127,7 +3136,7 @@ gitem_t itemlist[] = "models/weapons/v_tesla2/tris.md2 weapons/teslaopen.wav weapons/hgrenb1a.wav weapons/hgrenb2a.wav models/weapons/g_tesla/tris.md2" // precache }, -//41 +// 41 /*QUAKED ammo_trap (.3 .3 1) (-16 -16 -16) (16 16 16) */ { @@ -3151,7 +3160,7 @@ gitem_t itemlist[] = "weapons/trapcock.wav weapons/traploop.wav weapons/trapsuck.wav weapons/trapdown.wav" //precache }, -//42 +// 42 /*QUAKED ammo_nuke (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -3175,7 +3184,7 @@ gitem_t itemlist[] = "weapons/nukewarn2.wav world/rumble.wav" }, -//43 +// 43 /*QUAKED ammo_nbomb (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -3203,7 +3212,7 @@ gitem_t itemlist[] = "weapons/nukewarn2.wav world/rumble.wav" }, -//44 +// 44 /*QUAKED ammo_fuel (.3 .3 1) (-16 -16 -16) (16 16 16) model="models/items/ammo/fuel/medium/" */ @@ -3234,7 +3243,7 @@ model="models/items/ammo/fuel/medium/" // // POWERUP ITEMS // -//45 +// 45 /*QUAKED item_quad (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -3258,7 +3267,7 @@ model="models/items/ammo/fuel/medium/" "items/damage.wav items/damage2.wav items/damage3.wav" //precache }, -//46 +// 46 /*QUAKED item_double (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -3282,7 +3291,7 @@ model="models/items/ammo/fuel/medium/" "misc/ddamage1.wav misc/ddamage2.wav misc/ddamage3.wav" //precache }, -//47 +// 47 /*QUAKED item_quadfire (.3 .3 1) (-16 -16 -16) (16 16 16) */ { @@ -3306,7 +3315,7 @@ model="models/items/ammo/fuel/medium/" "items/quadfire1.wav items/quadfire2.wav items/quadfire3.wav" //precache }, -//48 +// 48 /*QUAKED item_invulnerability (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -3330,7 +3339,7 @@ model="models/items/ammo/fuel/medium/" /* precache */ "items/protect.wav items/protect2.wav items/protect4.wav" //precache }, -//49 +// 49 /*QUAKED item_silencer (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -3354,7 +3363,7 @@ model="models/items/ammo/fuel/medium/" "" //precache }, -//50 +// 50 /*QUAKED item_breather (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -3378,7 +3387,7 @@ model="models/items/ammo/fuel/medium/" "player/u_breath1.wav player/u_breath2.wav items/airout.wav" //precache }, -//51 +// 51 /*QUAKED item_enviro (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -3402,7 +3411,7 @@ model="models/items/ammo/fuel/medium/" "player/u_breath1.wav player/u_breath2.wav items/airout.wav" //precache }, -//52 +// 52 /*QUAKED item_ir_goggles (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN gives +1 to maximum health */ @@ -3427,7 +3436,7 @@ gives +1 to maximum health "misc/ir_start.wav" //precache }, -//53 +// 53 /*QUAKED item_ancient_head (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN Special item that gives +2 to maximum health */ @@ -3454,7 +3463,7 @@ Special item that gives +2 to maximum health // New item (sorta) for Citadel pack by Andrea Rosa #ifdef CITADELMOD_FEATURES -//54 +// 54 /*QUAKED item_steroid_pack (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN Special item that gives +2 to maximum health */ @@ -3480,7 +3489,7 @@ Special item that gives +2 to maximum health }, #endif -//54 +// 54 /*QUAKED item_adrenaline (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN gives +1 to maximum health */ @@ -3505,7 +3514,7 @@ gives +1 to maximum health "" //precache }, -//55 +// 55 /*QUAKED item_bandolier (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -3529,7 +3538,7 @@ gives +1 to maximum health "" //precache }, -//56 +// 56 /*QUAKED item_pack (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -3554,7 +3563,7 @@ gives +1 to maximum health }, #ifdef JETPACK_MOD -//57 +// 57 /*QUAKED item_jetpack (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN model="models/items/jet/" */ @@ -3608,7 +3617,7 @@ model="models/items/jet/" "" //precache },*/ -//58 +// 58 /*QUAKED item_flashlight (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -3632,7 +3641,7 @@ model="models/items/jet/" "" //precache }, -//59 +// 59 /*QUAKED item_compass (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -3656,7 +3665,7 @@ model="models/items/jet/" "" //precache }, -//60 +// 60 /*QUAKED item_sphere_vengeance (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -3680,7 +3689,7 @@ model="models/items/jet/" "spheres/v_idle.wav" //precache }, -//61 +// 61 /*QUAKED item_sphere_hunter (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -3704,7 +3713,7 @@ model="models/items/jet/" "spheres/h_idle.wav spheres/h_active.wav spheres/h_lurk.wav" //precache }, -//62 +// 62 /*QUAKED item_sphere_defender (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -3728,7 +3737,7 @@ model="models/items/jet/" "models/proj/laser2/tris.md2 models/items/shell/tris.md2 spheres/d_idle.wav" // precache }, -//63 +// 63 /*QUAKED item_doppleganger (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -3752,7 +3761,7 @@ model="models/items/jet/" "models/objects/dopplebase/tris.md2 models/items/spawngro2/tris.md2 models/items/hunter/tris.md2 models/items/vengnce/tris.md2", // precaches }, -//64 +// 64 /*QUAKED item_freeze (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -3776,7 +3785,7 @@ model="models/items/jet/" "items/stasis_start.wav items/stasis.wav items/stasis_stop.wav" }, -//65 +// 65 { "dm_tag_token", // classname // NULL, // classname @@ -3806,7 +3815,7 @@ model="models/items/jet/" // // KEYS // -//66 +// 66 /*QUAKED key_data_cd (0 .5 .8) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN key for computer centers */ @@ -3831,7 +3840,7 @@ key for computer centers "" //precache }, -//67 +// 67 /*QUAKED key_dstarchart (0 .5 .8) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN starchart in Makron's tomb */ @@ -3856,7 +3865,7 @@ starchart in Makron's tomb "" //precache }, -//68 +// 68 /*QUAKED key_power_cube (0 .5 .8) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN NO_TOUCH warehouse circuits */ @@ -3883,7 +3892,7 @@ warehouse circuits // New item (sorta) for Citadel pack by Andrea Rosa #ifdef CITADELMOD_FEATURES -//69 +// 69 /*QUAKED key_mystery (0 .5 .8) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN key for Citadel Pack 3.0 */ @@ -3909,7 +3918,7 @@ key for Citadel Pack 3.0 }, #endif -//69 +// 69 /*QUAKED key_pyramid (0 .5 .8) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN key for the entrance of jail3 */ @@ -3934,7 +3943,7 @@ key for the entrance of jail3 "" //precache }, -//70 +// 70 /*QUAKED key_data_spinner (0 .5 .8) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN key for the city computer */ @@ -3959,7 +3968,7 @@ key for the city computer "" //precache }, -//71 +// 71 /*QUAKED key_pass (0 .5 .8) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN security pass for the security level */ @@ -3984,7 +3993,7 @@ security pass for the security level "" //precache }, -//72 +// 72 /*QUAKED key_blue_key (0 .5 .8) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN normal door key - blue */ @@ -4009,7 +4018,7 @@ normal door key - blue "" //precache }, -//73 +// 73 /*QUAKED key_red_key (0 .5 .8) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN normal door key - red */ @@ -4034,9 +4043,9 @@ normal door key - red "" //precache }, -//74 +// 74 // RAFAEL -/*QUAKED key_green_key (0 .5 .8) (-16 -16 -16) (16 16 16) +/*QUAKED key_green_key (0 .5 .8) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN normal door key - green */ { @@ -4060,7 +4069,7 @@ normal door key - green "" //precache }, -//75 +// 75 /*QUAKED key_commander_head (0 .5 .8) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN tank commander's head */ @@ -4085,7 +4094,7 @@ tank commander's head "" //precache }, -//76 +// 76 /*QUAKED key_airstrike_target (0 .5 .8) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN marker for airstrike */ @@ -4112,7 +4121,7 @@ marker for airstrike // ====================================== // PGM -//77 +// 77 /*QUAKED key_nuke_container (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -4136,7 +4145,7 @@ marker for airstrike "" // precache }, -//78 +// 78 /*QUAKED key_nuke (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN */ { @@ -4162,6 +4171,162 @@ marker for airstrike // PGM // ====================================== +// 79 +/*QUAKED key_q1_gold (0 .5 .8) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN +medevial door key - gold +model="models/items/q1keys/gold/tris.md2" +*/ + { + "key_q1_gold", + Pickup_Key, + NULL, + Drop_General, + NULL, + "q1items/medkey.wav", + "models/items/q1keys/gold/tris.md2", 0, EF_ROTATE, + NULL, + "q1hud/items/SbKeyG", + "Gold Key", + 2, + 0, + NULL, + IT_STAY_COOP|IT_KEY|IT_Q1, + 0, + NULL, + 0, +/* precache */ "" + }, + +// 80 +/*QUAKED key_q1_silver (0 .5 .8) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN +medevial door key - silver +model="models/items/q1keys/silver/tris.md2" +*/ + { + "key_q1_silver", + Pickup_Key, + NULL, + Drop_General, + NULL, + "q1items/medkey.wav", + "models/items/q1keys/silver/tris.md2", 0, EF_ROTATE, + NULL, + "q1hud/items/SbKeyS", + "Silver Key", + 2, + 0, + NULL, + IT_STAY_COOP|IT_KEY|IT_Q1, + 0, + NULL, + 0, +/* precache */ "" + }, + +// 81 +/*QUAKED runekey_q1_gold (0 .5 .8) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN +runic door key - gold +model="models/items/q1keys/gold/rune/tris.md2" +*/ + { + "runekey_q1_gold", + Pickup_Key, + NULL, + Drop_General, + NULL, + "q1items/runekey.wav", + "models/items/q1keys/gold/rune/tris.md2", 0, EF_ROTATE, + NULL, + "q1hud/items/SbKeyG", + "Gold Rune Key", + 2, + 0, + NULL, + IT_STAY_COOP|IT_KEY|IT_Q1, + 0, + NULL, + 0, +/* precache */ "" + }, + +// 82 +/*QUAKED runekey_q1_silver (0 .5 .8) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN +runic door key - silver +model="models/items/q1keys/silver/rune/tris.md2" +*/ + { + "runekey_q1_silver", + Pickup_Key, + NULL, + Drop_General, + NULL, + "q1items/runekey.wav", + "models/items/q1keys/silver/rune/tris.md2", 0, EF_ROTATE, + NULL, + "q1hud/items/SbKeyS", + "Silver Rune Key", + 2, + 0, + NULL, + IT_STAY_COOP|IT_KEY|IT_Q1, + 0, + NULL, + 0, +/* precache */ "" + }, + +// 83 +/*QUAKED basekey_q1_gold (0 .5 .8) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN +base door key - gold +model="models/items/q1keys/gold/base/tris.md2" +*/ + { + "basekey_q1_gold", + Pickup_Key, + NULL, + Drop_General, + NULL, + "q1items/basekey.wav", + "models/items/q1keys/gold/base/tris.md2", 0, EF_ROTATE, + NULL, + "q1hud/items/SbKeyG", + "Gold Keycard", + 2, + 0, + NULL, + IT_STAY_COOP|IT_KEY|IT_Q1, + 0, + NULL, + 0, +/* precache */ "" + }, + +// 84 +/*QUAKED basekey_q1_silver (0 .5 .8) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN +base door key - silver +model="models/items/q1keys/silver/base/tris.md2" +*/ + { + "basekey_q1_silver", + Pickup_Key, + NULL, + Drop_General, + NULL, + "q1items/basekey.wav", + "models/items/q1keys/silver/base/tris.md2", 0, EF_ROTATE, + NULL, + "q1hud/items/SbKeyS", + "Silver Keycard", + 2, + 0, + NULL, + IT_STAY_COOP|IT_KEY|IT_Q1, + 0, + NULL, + 0, +/* precache */ "" + }, + /* Insert new key items here @@ -4175,7 +4340,7 @@ marker for airstrike full (pickup) name */ -//79 +// 85 { NULL, Pickup_Health, @@ -4335,6 +4500,14 @@ void SetItemNames (void) tesla_index = ITEM_INDEX(FindItem("Tesla")); trap_index = ITEM_INDEX(FindItem("Trap")); shocksphere_index = ITEM_INDEX(FindItem("Shocksphere")); + + // added for convenience with triger_key sound hack + key_q1_med_silver_index = ITEM_INDEX(FindItem("Silver Key")); + key_q1_med_gold_index = ITEM_INDEX(FindItem("Gold Key")); + key_q1_rune_silver_index = ITEM_INDEX(FindItem("Silver Rune Key")); + key_q1_rune_gold_index = ITEM_INDEX(FindItem("Gold Rune Key")); + key_q1_base_silver_index = ITEM_INDEX(FindItem("Silver Keycard")); + key_q1_base_gold_index = ITEM_INDEX(FindItem("Gold Keycard")); } #ifdef JETPACK_MOD diff --git a/missionpack/g_local.h b/missionpack/g_local.h index 41ca8ff..f63d131 100644 --- a/missionpack/g_local.h +++ b/missionpack/g_local.h @@ -80,18 +80,18 @@ #define FL_NO_KNOCKBACK 0x00000800 #define FL_POWER_SHIELD 0x00001000 // power armor (if any) is active #define FL_POWER_SCREEN 0x00002000 -//ROGUE +// ROGUE #define FL_MECHANICAL 0x00004000 // entity is mechanical, use sparks not blood #define FL_SAM_RAIMI 0x00008000 // entity is in sam raimi cam mode #define FL_DISGUISED 0x00010000 // entity is in disguise, monsters will not recognize. #define FL_NUKED 0x00020000 // player has been vaporized by a nuke, drop no gibs -//ROGUE -//Mappack - this flag says the player is in a turret and controlling it +// ROGUE +// Mappack - this flag says the player is in a turret and controlling it #define FL_TURRET_OWNER 0x00040000 -//Knightmare- this says that an entity is set to move with another +// Knightmare- this says that an entity is set to move with another #define FL_MOVESLAVE 0x00080000 -//Knightmare- flags for trains +// Knightmare- flags for trains #define FL_TRACKTRAIN 0x00100000 #define FL_ROTTRAIN 0x00200000 #define FL_REVERSIBLE 0x00400000 @@ -100,6 +100,8 @@ #define FL_ROBOT 0x02000000 // Player-controlled robot or monster. Relax yaw constraints #define FL_REFLECT 0x04000000 // Reflection entity +#define FL_Q1_MONSTER 0x08000000 + #define FL_RESPAWN 0x80000000 // used for item respawning #define FRAMETIME 0.1 @@ -316,6 +318,8 @@ typedef struct #define IT_KEY 0x00000010 #define IT_POWERUP 0x00000020 +#define IT_Q1 0x00000080 // added for Q1 keys + // ROGUE #define IT_MELEE 0x00000040 #define IT_NOT_GIVEABLE 0x00000080 // item can not be given @@ -738,6 +742,14 @@ extern int tesla_index; extern int trap_index; extern int shocksphere_index; +// added for convenience with triger_key sound hack +extern int key_q1_med_silver_index; +extern int key_q1_med_gold_index; +extern int key_q1_rune_silver_index; +extern int key_q1_rune_gold_index; +extern int key_q1_base_silver_index; +extern int key_q1_base_gold_index; + // mxd added extern int gibsthisframe; extern int lastgibframe; @@ -820,6 +832,26 @@ extern int lastgibframe; #define MOD_MISSILE 67 #define MOD_MISSILE_SPLASH 68 +//=============================== +// Extra MODs +// Quake1 -Skid +//=============================== +#define MOD_Q1_AXE 69 +#define MOD_Q1_SG 70 +#define MOD_Q1_SSG 71 +#define MOD_Q1_NG 72 +#define MOD_Q1_SNG 73 +#define MOD_Q1_GL 74 +#define MOD_Q1_RL 75 +#define MOD_Q1_LG 76 +#define MOD_Q1_GL_SPLASH 77 +#define MOD_Q1_RL_SPLASH 78 +#define MOD_Q1_LG_SPLASH 79 +#define MOD_Q1_LASER 80 +#define MOD_Q1_FLAMEBOLT 81 +#define MOD_Q1_FIREPOD 82 + + extern int meansOfDeath; @@ -1075,9 +1107,12 @@ float *tv (float x, float y, float z); char *vtos (vec3_t v); float vectoyaw (vec3_t vec); -float vectopitch (vec3_t vec); //Knightmare +float vectopitch (vec3_t vec); // Knightmare added void vectoangles (vec3_t vec, vec3_t angles); + +float PointDist (vec3_t x, vec3_t y); + void stuffcmd(edict_t *ent, char *s); qboolean point_infront (edict_t *self, vec3_t point); @@ -1097,7 +1132,6 @@ qboolean CheckCoop_MapHacks (edict_t *ent); // FS: Coop: Check if we have to mod qboolean UseSpecialGoodGuyFlag (edict_t *monster); //Knightmare added qboolean UseRegularGoodGuyFlag (edict_t *monster); //Knightmare added - //ROGUE void G_ProjectSource2 (vec3_t point, vec3_t distance, vec3_t forward, vec3_t right, vec3_t up, vec3_t result); float vectoyaw2 (vec3_t vec); @@ -1105,6 +1139,13 @@ void vectoangles2 (vec3_t vec, vec3_t angles); edict_t *findradius2 (edict_t *from, vec3_t org, float rad); //ROGUE +// +// g_utils_q1.c +// +float PointDist (vec3_t x, vec3_t y); +void Q1TeleportSounds (edict_t *ent); +void Q1TeleportSounds2 (edict_t *ent1, edict_t *ent2); + // // g_combat.c // @@ -1301,10 +1342,10 @@ qboolean infront (edict_t *self, edict_t *other); qboolean visible (edict_t *self, edict_t *other); qboolean FacingIdeal(edict_t *self); qboolean ai_chicken (edict_t *ent, edict_t *badguy); + // // g_weapon.c // - #define BLASTER_ORANGE 1 #define BLASTER_GREEN 2 #define BLASTER_BLUE 3 @@ -1334,6 +1375,22 @@ void Trap_Explode (edict_t *ent); qboolean AimGrenade (edict_t *launcher, vec3_t start, vec3_t target, vec_t speed, vec3_t aim); void Grenade_Evade (edict_t *monster); +// +// g_weapon_q1.c +// +void q1_fire_nail (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, qboolean sng); +void q1_fire_laser (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed); +void q1_fire_flame (edict_t *self, vec3_t start, vec3_t dir, float leftrightoff); +void q1_explode (edict_t *self); +void q1_fire_grenade (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, float timer, float damage_radius); +void q1_fire_rocket (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, float damage_radius, int radius_damage); +void q1_fire_lightning (edict_t *self, vec3_t start, vec3_t dir, int damage); +void q1_fire_firepod (edict_t *self, vec3_t dir); +void q1_fire_lavaball (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, float damage_radius, int radius_damage); +void q1_fire_acidspit (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed); +void q1_fire_gib (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed); + + // // m_actor.c // diff --git a/missionpack/g_mappack.c b/missionpack/g_mappack.c index 9ac7123..4dfba1e 100644 --- a/missionpack/g_mappack.c +++ b/missionpack/g_mappack.c @@ -62,7 +62,7 @@ void bigflame_think (edict_t *self) self->nextthink = level.time + FRAMETIME; } -void SP_light_flame (edict_t *self) //New function by Beel. (small flame) +void SP_light_flame (edict_t *self) // New function by Beel. (small flame) { self->movetype = MOVETYPE_NONE; self->solid = SOLID_NOT; @@ -72,7 +72,7 @@ void SP_light_flame (edict_t *self) //New function by Beel. (small flame) self->s.frame = 0; self->s.renderfx |= RF_IR_VISIBLE | RF_FULLBRIGHT; // PGM self->s.effects |= EF_PLASMA; - //Knightmare- only one size for this model + // Knightmare- only one size for this model //ed - spawnflag of 2 gives a big flame // if (self->spawnflags & 2) // self->think = bigflame_think; diff --git a/missionpack/g_misc.c b/missionpack/g_misc.c index dd486d9..03515fa 100644 --- a/missionpack/g_misc.c +++ b/missionpack/g_misc.c @@ -397,6 +397,11 @@ void ThrowHead (edict_t *self, char *gibname, int damage, int type) VectorSet (self->mins, -4, -4, -4); VectorSet (self->maxs, 4, 4, 4); } + else if (self->flags & FL_Q1_MONSTER) // Q1 monster heads have bigger bbox + { + VectorSet (self->mins, -16, -16, 0); + VectorSet (self->maxs, 16, 16, 32); + } else { VectorSet (self->mins, -4, -4, 0); @@ -445,8 +450,16 @@ void ThrowHead (edict_t *self, char *gibname, int damage, int type) self->avelocity[YAW] = crandom()*600; - self->think = gib_fade; //Knightmare- gib fade, was G_FreeEdict - self->nextthink = level.time + 10 + random()*10; + if (self->flags & FL_Q1_MONSTER) // Q1 monster heads don't disappear + { + self->think = NULL; + self->nextthink = 0; + } + else + { + self->think = gib_fade; // Knightmare- gib fade, was G_FreeEdict + self->nextthink = level.time + 10 + random()*10; + } //PGM self->s.renderfx |= RF_IR_VISIBLE; diff --git a/missionpack/g_misc_q1.c b/missionpack/g_misc_q1.c new file mode 100644 index 0000000..28eb143 --- /dev/null +++ b/missionpack/g_misc_q1.c @@ -0,0 +1,593 @@ +// g_misc_q1.c + +#include "g_local.h" + +//====================================================================== +// CRUCIFIED ZOMBIE +//====================================================================== + +void misc_zombie_crucified_think (edict_t *self) +{ + float r1; + + if (++self->s.frame < 198) // was FRAME_death4_22 + self->nextthink = level.time + FRAMETIME; + else + { + self->s.frame = 192; + self->nextthink = level.time + FRAMETIME; + } + r1 = random(); + if (r1 <= .017) + { + gi.sound (self, CHAN_VOICE, gi.soundindex ("q1zombie/idle_w2.wav"), 1, ATTN_IDLE, 0); + } +} + +/*QUAKED misc_q1_zombie_crucified (1 .5 0) (-16 -16 -24) (16 16 32) +model="models/monsters/q1zombie/" +frame="192" +*/ +void SP_misc_q1_zombie_crucified (edict_t *self) +{ + self->movetype = MOVETYPE_NONE; + self->solid = SOLID_NOT; + VectorSet (self->mins, -16, -16, -24); + VectorSet (self->maxs, 16, 16, 32); + self->s.modelindex = gi.modelindex ("models/monsters/q1zombie/tris.md2"); + self->s.frame = 192; + + self->common_name = "Crucified Zombie"; + + gi.linkentity (self); + + self->think = misc_zombie_crucified_think; + self->nextthink = level.time + FRAMETIME; +} + +//====================================================================== +// AIR BUBBLES +//====================================================================== + +void bubble_bob (edict_t *bubble); +void bubble_touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) +{ + if (!strcmp (other->classname, ent->classname)) + { + // gi.dprintf ("bump\n"); + return; + } + G_FreeEdict (ent); +} + +void bubble_split (edict_t *bubble) +{ + edict_t *newbubble; + float r1 = random(); + float r2 = random(); + int i, j; + + newbubble = G_Spawn(); + newbubble->classname = "bubble"; + newbubble->s.modelindex = gi.modelindex ("sprites/s_bubble.sp2"); + VectorCopy (bubble->s.origin, newbubble->s.origin); + + if (r1 > 0.5) i = 1; + else i = 0; + + if (r2 > 0.5) j = 1; + else j = -1; + + newbubble->s.origin[i] += (6 * j); + + newbubble->movetype = MOVETYPE_FLYMISSILE; + newbubble->solid = SOLID_TRIGGER; + VectorCopy (bubble->velocity, newbubble->velocity); + newbubble->nextthink = level.time + 0.5; + newbubble->think = bubble_bob; + newbubble->touch = bubble_touch; + newbubble->s.frame = 1; + newbubble->count = 10; + VectorSet (newbubble->mins, -2, -2, -2); + VectorSet (newbubble->maxs, 2, 2, 2); + gi.linkentity (newbubble); + + bubble->s.frame = 1; + bubble->count = 10; + if (bubble->waterlevel != 3) + G_FreeEdict (bubble); +} + +void bubble_bob (edict_t *bubble) +{ + float rnd1, rnd2, rnd3; +// vec3_t vtmp1, modi; + + bubble->count++; + if (bubble->count == 4) + bubble_split (bubble); + if (bubble->count == 20) + G_FreeEdict (bubble); + + rnd1 = bubble->velocity[0] + (-10 + (random() * 20)); + rnd2 = bubble->velocity[1] + (-10 + (random() * 20)); + rnd3 = bubble->velocity[2] + 10 + random() * 10; + + if (rnd1 > 10) + rnd1 = 5; + if (rnd1 < -10) + rnd1 = -5; + + if (rnd2 > 10) + rnd2 = 5; + if (rnd2 < -10) + rnd2 = -5; + + if (rnd3 < 10) + rnd3 = 15; + if (rnd3 > 30) + rnd3 = 25; + + bubble->velocity[0] = rnd1; + bubble->velocity[1] = rnd2; + bubble->velocity[2] = rnd3; + + bubble->nextthink = level.time + 0.5; + bubble->think = bubble_bob; +} + +void make_bubbles (edict_t *self) +{ + + edict_t *bubble; + + bubble = G_Spawn(); + bubble->classname = "bubble"; + bubble->s.modelindex = gi.modelindex ("sprites/s_bubble.sp2"); + VectorCopy (self->s.origin, bubble->s.origin); + bubble->movetype = MOVETYPE_FLYMISSILE; + bubble->solid = SOLID_TRIGGER; + VectorSet (bubble->mins, -2, -2, -2); + VectorSet (bubble->maxs, 2, 2, 2); + VectorSet (bubble->velocity, 0, 0, 15); + bubble->nextthink = level.time + 0.5; + bubble->think = bubble_bob; + bubble->touch = bubble_touch; + bubble->s.frame = 0; + bubble->count = 0; + + bubble->common_name = "Bubble"; + + gi.linkentity (bubble); + + self->nextthink = level.time + random() + 0.5; + self->think = make_bubbles; +} + +/*QUAKED misc_q1_air_bubbles (1 0 0) (-8 -8 -8) (8 8 8) +This entity gives off sprite air bubbles, put it at the bottom of the water where the air should start bubbling up. +*/ +void SP_misc_q1_air_bubbles (edict_t *self) +{ + if (deathmatch->value) + { + G_FreeEdict (self); + return; + } + gi.modelindex ("sprites/s_bubble.sp2"); + self->nextthink = level.time + 1; + self->think = make_bubbles; + gi.linkentity (self); +} + + +//====================================================================== +// GLOBE +//====================================================================== + +/*QUAKED misc_q1_globe (0 1 0) (-4 -4 -4) (4 4 4) +This is a sprite, is not solid +*/ +void SP_misc_q1_globe(edict_t *self) +{ + self->movetype = MOVETYPE_NONE; + self->solid = SOLID_NOT; + self->s.modelindex = gi.modelindex ("sprites/s_light.sp2"); + self->s.frame = 0; + self->s.sound = 0; + + self->common_name = "Globe Light"; + + gi.linkentity (self); +} + +//====================================================================== +// SMALL FLAME +//====================================================================== + +void q1_small_flame_think (edict_t *self) +{ + if(self->s.frame >= 5) + self->s.frame = 0; + else + self->s.frame++; + self->nextthink = level.time + FRAMETIME; +} + +/*QUAKED misc_q1_small_flame (0 1 0) (-4 -4 -4) (4 4 4) +not solid +model="models/objects/q1flame/" +*/ +void SP_misc_q1_small_flame (edict_t *ent) +{ + ent->movetype = MOVETYPE_NONE; + ent->solid = SOLID_NOT; + ent->s.modelindex = gi.modelindex ("models/objects/q1flame/tris.md2"); + ent->s.frame = 0; + ent->s.sound = gi.soundindex("q1world/fire1.wav"); + ent->s.renderfx = RF_FULLBRIGHT | RF_NOSHADOW; + ent->nextthink = level.time + FRAMETIME; + ent->think = q1_small_flame_think; + + ent->common_name = "Small Flame"; + + gi.linkentity (ent); +} + +//====================================================================== +// LARGE FLAME +//====================================================================== + +void q1_large_flame_think (edict_t *self) +{ + if (self->s.frame >= 16) + self->s.frame = 6; + else + self->s.frame++; + self->nextthink = level.time + FRAMETIME; +} + +/*QUAKED misc_q1_large_flame (0 1 0) (-4 -4 -4) (4 4 4) +not solid +model="models/objects/q1flame/" +frame="6" +*/ +void SP_misc_q1_large_flame (edict_t *ent) +{ + ent->movetype = MOVETYPE_NONE; + ent->solid = SOLID_NOT; + ent->s.modelindex = gi.modelindex ("models/objects/q1flame/tris.md2"); + ent->s.frame = 6; + ent->s.sound = gi.soundindex("q1world/fire1.wav"); + ent->nextthink = level.time + FRAMETIME; + ent->think = q1_large_flame_think; + ent->s.renderfx = RF_FULLBRIGHT | RF_NOSHADOW; + + ent->common_name = "Large Flame"; + + gi.linkentity (ent); +} + +//====================================================================== +// TORCH +//====================================================================== + +void q1_torch_think (edict_t *self) +{ + if(self->s.frame >= 5) + self->s.frame = 0; + else + self->s.frame++; + self->nextthink = level.time + FRAMETIME; +} + +/*QUAKED misc_q1_torch (0 1 0) (-4 -4 -4) (4 4 4) +model="models/objects/q1torch/" +not solid +*/ +void SP_misc_q1_torch (edict_t *ent) +{ + ent->movetype = MOVETYPE_NONE; + ent->solid = SOLID_NOT; + ent->s.modelindex = gi.modelindex ("models/objects/q1torch/tris.md2"); + ent->s.frame = 0; + ent->s.sound = gi.soundindex("q1world/fire1.wav"); + ent->s.renderfx = RF_FULLBRIGHT | RF_NOSHADOW; + ent->nextthink = level.time + FRAMETIME; + ent->think = q1_torch_think; + + ent->common_name = "Torch"; + + gi.linkentity (ent); +} + +/* +============== +target_q1_trap + +spawnflag 1 = superspike +spawnflag 2 = laser +defualt speed 500, 600 for laser +damage 9 for spike, 15 for superspike, 15 for laser +============== +*/ + +void q1_use_target_trapshooter (edict_t *self, edict_t *other, edict_t *activator) +{ + qboolean super = (self->spawnflags & 1); + + gi.sound (self, CHAN_AUTO, self->noise_index, 1, ATTN_NORM, 0); + if (self->spawnflags & 2) { + q1_fire_laser (self, self->s.origin, self->movedir, self->dmg, self->speed); + } + else { + q1_fire_nail (self, self->s.origin, self->movedir, self->dmg, self->speed, super); +#ifndef KMQUAKE2_ENGINE_MOD + gi.sound (self, CHAN_AUTO, gi.soundindex("q1weap/nails/s_end.wav"), 1.0, ATTN_NORM, 0); +#endif + } +} + +/*QUAKED target_q1_trap (1 0 0) (-8 -8 -8) (8 8 8) superspike laser +Fires a spike in the set direction when triggered. +default speed 500, 600 for laser +damage 9 for spike, 15 for superspike, 15 for laser +*/ +void SP_target_q1_trap (edict_t *self) +{ + self->use = q1_use_target_trapshooter; + G_SetMovedir (self->s.angles, self->movedir); + if (self->spawnflags & 2) { + self->noise_index = gi.soundindex ("q1enforcer/enfire.wav"); + gi.soundindex("q1enforcer/enfstop.wav"); + if (!self->speed) + self->speed = 600; + } + else { +#ifdef KMQUAKE2_ENGINE_MOD + self->noise_index = gi.soundindex ("q1weap/nails/spike2.wav"); +#else + self->noise_index = gi.soundindex ("q1weap/nails/spike.wav"); + gi.soundindex("q1weap/nails/s_end.wav"); +#endif + if (!self->speed) + self->speed = 500; + } + + if (self->spawnflags & 1 || self->spawnflags & 2) { + if (!self->dmg) + self->dmg = 15; + } + else { + if (!self->dmg) + self->dmg = 9; + } + self->svflags = SVF_NOCLIENT; +} + + +//====================================================================== +// Q1 EXPLOBOX +//====================================================================== + +void q1_barrel_explode (edict_t *self) +{ + self->nextthink = level.time + FRAMETIME; + self->s.frame++; + if (self->s.frame == 5) + G_FreeEdict(self); +} + +/*static*/ void q1_explobox_delay (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) +{ + self->takedamage = DAMAGE_NO; + self->nextthink = level.time + 2 * FRAMETIME; + self->activator = attacker; + + T_RadiusDamage (self, self->activator, self->dmg, NULL, self->dmg+30, MOD_BARREL); + + if (!deathmatch->value) + { + vec3_t org; + float spd; + vec3_t save; + + VectorCopy (self->s.origin, save); + VectorMA (self->absmin, 0.5, self->size, self->s.origin); + + // a few big chunks + spd = 1.5 * (float)self->dmg / 200.0; + org[0] = self->s.origin[0] + crandom() * self->size[0]; + org[1] = self->s.origin[1] + crandom() * self->size[1]; + org[2] = self->s.origin[2] + crandom() * self->size[2]; + ThrowDebris (self, "models/objects/debris1/tris.md2", spd, org, 0, 0); + org[0] = self->s.origin[0] + crandom() * self->size[0]; + org[1] = self->s.origin[1] + crandom() * self->size[1]; + org[2] = self->s.origin[2] + crandom() * self->size[2]; + ThrowDebris (self, "models/objects/debris1/tris.md2", spd, org, 0, 0); + + // bottom corners + spd = 1.75 * (float)self->dmg / 200.0; + VectorCopy (self->absmin, org); + ThrowDebris (self, "models/objects/debris3/tris.md2", spd, org, 0, 0); + VectorCopy (self->absmin, org); + org[0] += self->size[0]; + ThrowDebris (self, "models/objects/debris3/tris.md2", spd, org, 0, 0); + VectorCopy (self->absmin, org); + org[1] += self->size[1]; + ThrowDebris (self, "models/objects/debris3/tris.md2", spd, org, 0, 0); + VectorCopy (self->absmin, org); + org[0] += self->size[0]; + org[1] += self->size[1]; + ThrowDebris (self, "models/objects/debris3/tris.md2", spd, org, 0, 0); + + // a bunch of little chunks + spd = 2 * self->dmg / 200; + org[0] = self->s.origin[0] + crandom() * self->size[0]; + org[1] = self->s.origin[1] + crandom() * self->size[1]; + org[2] = self->s.origin[2] + crandom() * self->size[2]; + ThrowDebris (self, "models/objects/debris2/tris.md2", spd, org, 0, 0); + org[0] = self->s.origin[0] + crandom() * self->size[0]; + org[1] = self->s.origin[1] + crandom() * self->size[1]; + org[2] = self->s.origin[2] + crandom() * self->size[2]; + ThrowDebris (self, "models/objects/debris2/tris.md2", spd, org, 0, 0); + org[0] = self->s.origin[0] + crandom() * self->size[0]; + org[1] = self->s.origin[1] + crandom() * self->size[1]; + org[2] = self->s.origin[2] + crandom() * self->size[2]; + ThrowDebris (self, "models/objects/debris2/tris.md2", spd, org, 0, 0); + org[0] = self->s.origin[0] + crandom() * self->size[0]; + org[1] = self->s.origin[1] + crandom() * self->size[1]; + org[2] = self->s.origin[2] + crandom() * self->size[2]; + ThrowDebris (self, "models/objects/debris2/tris.md2", spd, org, 0, 0); + org[0] = self->s.origin[0] + crandom() * self->size[0]; + org[1] = self->s.origin[1] + crandom() * self->size[1]; + org[2] = self->s.origin[2] + crandom() * self->size[2]; + ThrowDebris (self, "models/objects/debris2/tris.md2", spd, org, 0, 0); + org[0] = self->s.origin[0] + crandom() * self->size[0]; + org[1] = self->s.origin[1] + crandom() * self->size[1]; + org[2] = self->s.origin[2] + crandom() * self->size[2]; + ThrowDebris (self, "models/objects/debris2/tris.md2", spd, org, 0, 0); + org[0] = self->s.origin[0] + crandom() * self->size[0]; + org[1] = self->s.origin[1] + crandom() * self->size[1]; + org[2] = self->s.origin[2] + crandom() * self->size[2]; + ThrowDebris (self, "models/objects/debris2/tris.md2", spd, org, 0, 0); + org[0] = self->s.origin[0] + crandom() * self->size[0]; + org[1] = self->s.origin[1] + crandom() * self->size[1]; + org[2] = self->s.origin[2] + crandom() * self->size[2]; + ThrowDebris (self, "models/objects/debris2/tris.md2", spd, org, 0, 0); + + VectorCopy (save, self->s.origin); + } + + gi.sound (self, CHAN_AUTO, gi.soundindex ("q1weap/rocket/r_exp3.wav"), 1.0, ATTN_NORM, 0); + gi.WriteByte (svc_temp_entity); + gi.WriteByte (TE_ROCKET_EXPLOSION); + gi.WritePosition (self->s.origin); + gi.multicast (self->s.origin, MULTICAST_PVS); + + // explosion sprite + gi.unlinkentity (self); + self->solid = SOLID_NOT; + self->touch = NULL; + VectorClear (self->velocity); + self->s.modelindex = gi.modelindex ("sprites/s_explod.sp2"); + self->s.frame = 0; + self->s.sound = 0; + self->s.effects &= ~EF_ANIM_ALLFAST; + self->think = q1_barrel_explode; + self->nextthink = level.time + FRAMETIME; + gi.linkentity (self); +} + +/*QUAKED misc_q1_explobox (0 .5 .8) (-16 -16 -16) (16 16 48) small +If small is checked, it is only 40, not 64 units tall. +health defaults to 20 +dmg defaults to 160 +mass defaults to 400 +model="models/objects/q1explo/big/" +*/ +void SP_misc_q1_explobox (edict_t *self) +{ + self->solid = SOLID_BBOX; + //self->solid = SOLID_NOT; + self->movetype = MOVETYPE_NONE; + self->svflags &= ~SVF_NOCLIENT; + + if (self->spawnflags & 1) + { + self->model = "models/objects/q1explo/small/tris.md2"; + VectorSet (self->mins, -16, -16, -16); + VectorSet (self->maxs, 16, 16, 24); + } + else + { + self->model = "models/objects/q1explo/big/tris.md2"; + VectorSet (self->mins, -16, -16, -16); + VectorSet (self->maxs, 16, 16, 48); + } + + self->s.modelindex = gi.modelindex (self->model); + + if (!self->mass) + self->mass = 400; + if (!self->health) + self->health = 20; + if (!self->dmg) + self->dmg = 160; + + self->die = q1_explobox_delay; + self->takedamage = DAMAGE_YES; + self->monsterinfo.aiflags = AI_NOSTEP; + self->touch = NULL; + self->think = M_droptofloor; + self->nextthink = level.time + 2 * FRAMETIME; + + self->common_name = "Exploding Box"; + + gi.linkentity (self); +} + +//====================================================================== +// FIREBALL +//====================================================================== + +void q1_fireball_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) +{ + T_Damage (other, self, self->owner, self->velocity, self->s.origin, plane->normal, self->dmg, 0, 0, 0); + G_FreeEdict (self); +} + +void q1_fireball_fly (edict_t *self) +{ + edict_t *lavaball; + +// gi.dprintf ("Launching Fireball\n"); + + lavaball = G_Spawn(); + lavaball->speed = 200; + VectorCopy (self->s.origin, lavaball->s.origin); + VectorCopy (self->movedir, lavaball->movedir); + vectoangles (self->movedir, lavaball->s.angles); + VectorSet(lavaball->velocity,((random() * 100) - 50), + ((random() * 100) - 50), + (self->speed + (random() * 150))); + + lavaball->movetype = MOVETYPE_FLYMISSILE; + lavaball->clipmask = MASK_SHOT; + lavaball->solid = SOLID_BBOX; + lavaball->s.effects |= EF_ROCKET; //EF_FLAG1 + lavaball->s.renderfx |= RF_GLOW; + VectorClear (lavaball->mins); + VectorClear (lavaball->maxs); + VectorSet (lavaball->mins, -8, -8, -8); + VectorSet (lavaball->maxs, 8, 8, 8); + lavaball->s.modelindex = gi.modelindex ("models/monsters/q1chthon/lavaball/tris.md2"); + lavaball->owner = self; + lavaball->touch = q1_fireball_touch; + lavaball->nextthink = level.time + 7; + lavaball->think = G_FreeEdict; + lavaball->dmg = 20; + lavaball->classname = "lavaball"; + + lavaball->common_name = "Lavaball"; + + gi.linkentity (lavaball); + + self->nextthink = level.time + (4 + (random() * 3.0)); + self->think = q1_fireball_fly; +} + +/*QUAKED misc_q1_fireball (.5 .5 .5) (-8 -8 -8) (8 8 8) +model="models/monsters/q1chthon/lavaball/" +*/ +void SP_misc_q1_fireball (edict_t *self) +{ + gi.modelindex ("models/monsters/q1chthon/lavaball/tris.md2"); + self->nextthink = level.time + (4 + (random() * 3.0)); + self->think = q1_fireball_fly; + self->classname = "fireball"; + + self->common_name = "Lavaball spawner"; + + gi.linkentity(self); +} diff --git a/missionpack/g_mmove_decs.h b/missionpack/g_mmove_decs.h index e26ace6..c54ccf8 100644 --- a/missionpack/g_mmove_decs.h +++ b/missionpack/g_mmove_decs.h @@ -163,6 +163,120 @@ extern mmove_t soldier_move_walk2 ; extern mmove_t soldier_move_walk1 ; extern mmove_t soldier_move_stand3 ; extern mmove_t soldier_move_stand1 ; +extern mmove_t q1zombie_move_pain4 ; +extern mmove_t q1zombie_move_pain3 ; +extern mmove_t q1zombie_move_pain2 ; +extern mmove_t q1zombie_move_pain1 ; +extern mmove_t q1zombie_move_attack3 ; +extern mmove_t q1zombie_move_attack2 ; +extern mmove_t q1zombie_move_attack1 ; +extern mmove_t q1zombie_move_run ; +extern mmove_t q1zombie_move_walk ; +extern mmove_t q1zombie_crucified ; +extern mmove_t q1zombie_move_stand ; +extern mmove_t q1zombie_move_pain5 ; +extern mmove_t tarbaby_move_explode ; +extern mmove_t tarbaby_move_jump ; +extern mmove_t tarbaby_move_fly ; +extern mmove_t tarbaby_move_run ; +extern mmove_t tarbaby_move_walk ; +extern mmove_t tarbaby_move_stand ; +extern mmove_t shambler_move_magic_attack ; +extern mmove_t shambler_move_smash_attack ; +extern mmove_t shambler_move_swingR_attack ; +extern mmove_t shambler_move_swingL_attack ; +extern mmove_t shambler_move_death ; +extern mmove_t shambler_move_pain ; +extern mmove_t shambler_move_run ; +extern mmove_t shambler_move_walk ; +extern mmove_t shambler_move_stand ; +extern mmove_t q1shalrath_move_death ; +extern mmove_t q1shalrath_move_attack ; +extern mmove_t q1shalrath_move_pain1 ; +extern mmove_t q1shalrath_move_run ; +extern mmove_t q1shalrath_move_walk ; +extern mmove_t q1shalrath_move_stand ; +extern mmove_t scrag_move_attack ; +extern mmove_t scrag_move_die ; +extern mmove_t scrag_move_pain ; +extern mmove_t scrag_move_run ; +extern mmove_t scrag_move_walk ; +extern mmove_t scrag_move_stand ; +extern mmove_t q1rotfish_move_death ; +extern mmove_t q1rotfish_move_attack ; +extern mmove_t q1rotfish_move_pain1 ; +extern mmove_t q1rotfish_move_walk_loop ; +extern mmove_t q1rotfish_move_run_loop ; +extern mmove_t q1rotfish_move_stand ; +extern mmove_t ogre_move_attack_grenade ; +extern mmove_t ogre_move_smash_attack ; +extern mmove_t ogre_move_swing_attack ; +extern mmove_t ogre_move_death2 ; +extern mmove_t ogre_move_death1 ; +extern mmove_t ogre_move_pain5 ; +extern mmove_t ogre_move_pain4 ; +extern mmove_t ogre_move_pain3 ; +extern mmove_t ogre_move_pain2 ; +extern mmove_t ogre_move_pain1 ; +extern mmove_t ogre_move_run ; +extern mmove_t ogre_move_walk ; +extern mmove_t ogre_move_stand ; +extern mmove_t knight_move_death2 ; +extern mmove_t knight_move_death1 ; +extern mmove_t knight_move_pain2 ; +extern mmove_t knight_move_pain1 ; +extern mmove_t knight_move_attack ; +extern mmove_t knight_move_attack_run ; +extern mmove_t knight_move_run ; +extern mmove_t knight_move_walk ; +extern mmove_t knight_move_stand ; +extern mmove_t knight_move_standing ; +extern mmove_t knight_move_kneel ; +extern mmove_t hknight_magic_attack ; +extern mmove_t knight_charge1_attack ; +extern mmove_t hknight_move_death2 ; +extern mmove_t hknight_move_death1 ; +extern mmove_t hknight_move_pain1 ; +extern mmove_t hknight_slice_attack ; +extern mmove_t hknight_watk_attack ; +extern mmove_t hknight_smash_attack ; +extern mmove_t hknight_move_run ; +extern mmove_t hknight_move_walk ; +extern mmove_t hknight_move_stand ; +extern mmove_t q1grunt_move_death2 ; +extern mmove_t q1grunt_move_death1 ; +extern mmove_t q1grunt_move_attack ; +extern mmove_t q1grunt_move_pain3 ; +extern mmove_t q1grunt_move_pain2 ; +extern mmove_t q1grunt_move_pain1 ; +extern mmove_t q1grunt_move_run ; +extern mmove_t q1grunt_move_walk ; +extern mmove_t q1grunt_move_stand ; +extern mmove_t fiend_move_death ; +extern mmove_t fiend_move_pain ; +extern mmove_t fiend_move_jump ; +extern mmove_t fiend_move_attack ; +extern mmove_t fiend_move_run ; +extern mmove_t fiend_move_walk ; +extern mmove_t fiend_move_stand ; +extern mmove_t q1enforcer_move_start_fire ; +extern mmove_t q1enforcer_move_death2 ; +extern mmove_t q1enforcer_move_death1 ; +extern mmove_t q1enforcer_move_pain1 ; +extern mmove_t q1enforcer_move_pain2 ; +extern mmove_t q1enforcer_move_pain3 ; +extern mmove_t q1enforcer_move_run ; +extern mmove_t q1enforcer_move_walk ; +extern mmove_t q1enforcer_move_stand ; +extern mmove_t q1dog_move_death2 ; +extern mmove_t q1dog_move_death1 ; +extern mmove_t q1dog_move_leap ; +extern mmove_t q1dog_move_attack ; +extern mmove_t q1dog_move_pain2 ; +extern mmove_t q1dog_move_pain1 ; +extern mmove_t q1dog_move_run ; +extern mmove_t q1dog_move_walk ; +extern mmove_t q1dog_move_stand ; extern mmove_t parasite_move_death ; extern mmove_t parasite_move_jump_down ; extern mmove_t parasite_move_jump_up ; diff --git a/missionpack/g_mmove_list.h b/missionpack/g_mmove_list.h index 28c8aed..65de6e7 100644 --- a/missionpack/g_mmove_list.h +++ b/missionpack/g_mmove_list.h @@ -163,6 +163,120 @@ {"soldier_move_walk1", &soldier_move_walk1}, {"soldier_move_stand3", &soldier_move_stand3}, {"soldier_move_stand1", &soldier_move_stand1}, +{"q1zombie_move_pain4", &q1zombie_move_pain4}, +{"q1zombie_move_pain3", &q1zombie_move_pain3}, +{"q1zombie_move_pain2", &q1zombie_move_pain2}, +{"q1zombie_move_pain1", &q1zombie_move_pain1}, +{"q1zombie_move_attack3", &q1zombie_move_attack3}, +{"q1zombie_move_attack2", &q1zombie_move_attack2}, +{"q1zombie_move_attack1", &q1zombie_move_attack1}, +{"q1zombie_move_run", &q1zombie_move_run}, +{"q1zombie_move_walk", &q1zombie_move_walk}, +{"q1zombie_crucified", &q1zombie_crucified}, +{"q1zombie_move_stand", &q1zombie_move_stand}, +{"q1zombie_move_pain5", &q1zombie_move_pain5}, +{"tarbaby_move_explode", &tarbaby_move_explode}, +{"tarbaby_move_jump", &tarbaby_move_jump}, +{"tarbaby_move_fly", &tarbaby_move_fly}, +{"tarbaby_move_run", &tarbaby_move_run}, +{"tarbaby_move_walk", &tarbaby_move_walk}, +{"tarbaby_move_stand", &tarbaby_move_stand}, +{"shambler_move_magic_attack", &shambler_move_magic_attack}, +{"shambler_move_smash_attack", &shambler_move_smash_attack}, +{"shambler_move_swingR_attack", &shambler_move_swingR_attack}, +{"shambler_move_swingL_attack", &shambler_move_swingL_attack}, +{"shambler_move_death", &shambler_move_death}, +{"shambler_move_pain", &shambler_move_pain}, +{"shambler_move_run", &shambler_move_run}, +{"shambler_move_walk", &shambler_move_walk}, +{"shambler_move_stand", &shambler_move_stand}, +{"q1shalrath_move_death", &q1shalrath_move_death}, +{"q1shalrath_move_attack", &q1shalrath_move_attack}, +{"q1shalrath_move_pain1", &q1shalrath_move_pain1}, +{"q1shalrath_move_run", &q1shalrath_move_run}, +{"q1shalrath_move_walk", &q1shalrath_move_walk}, +{"q1shalrath_move_stand", &q1shalrath_move_stand}, +{"scrag_move_attack", &scrag_move_attack}, +{"scrag_move_die", &scrag_move_die}, +{"scrag_move_pain", &scrag_move_pain}, +{"scrag_move_run", &scrag_move_run}, +{"scrag_move_walk", &scrag_move_walk}, +{"scrag_move_stand", &scrag_move_stand}, +{"q1rotfish_move_death", &q1rotfish_move_death}, +{"q1rotfish_move_attack", &q1rotfish_move_attack}, +{"q1rotfish_move_pain1", &q1rotfish_move_pain1}, +{"q1rotfish_move_walk_loop", &q1rotfish_move_walk_loop}, +{"q1rotfish_move_run_loop", &q1rotfish_move_run_loop}, +{"q1rotfish_move_stand", &q1rotfish_move_stand}, +{"ogre_move_attack_grenade", &ogre_move_attack_grenade}, +{"ogre_move_smash_attack", &ogre_move_smash_attack}, +{"ogre_move_swing_attack", &ogre_move_swing_attack}, +{"ogre_move_death2", &ogre_move_death2}, +{"ogre_move_death1", &ogre_move_death1}, +{"ogre_move_pain5", &ogre_move_pain5}, +{"ogre_move_pain4", &ogre_move_pain4}, +{"ogre_move_pain3", &ogre_move_pain3}, +{"ogre_move_pain2", &ogre_move_pain2}, +{"ogre_move_pain1", &ogre_move_pain1}, +{"ogre_move_run", &ogre_move_run}, +{"ogre_move_walk", &ogre_move_walk}, +{"ogre_move_stand", &ogre_move_stand}, +{"knight_move_death2", &knight_move_death2}, +{"knight_move_death1", &knight_move_death1}, +{"knight_move_pain2", &knight_move_pain2}, +{"knight_move_pain1", &knight_move_pain1}, +{"knight_move_attack", &knight_move_attack}, +{"knight_move_attack_run", &knight_move_attack_run}, +{"knight_move_run", &knight_move_run}, +{"knight_move_walk", &knight_move_walk}, +{"knight_move_stand", &knight_move_stand}, +{"knight_move_standing", &knight_move_standing}, +{"knight_move_kneel", &knight_move_kneel}, +{"hknight_magic_attack", &hknight_magic_attack}, +{"knight_charge1_attack", &knight_charge1_attack}, +{"hknight_move_death2", &hknight_move_death2}, +{"hknight_move_death1", &hknight_move_death1}, +{"hknight_move_pain1", &hknight_move_pain1}, +{"hknight_slice_attack", &hknight_slice_attack}, +{"hknight_watk_attack", &hknight_watk_attack}, +{"hknight_smash_attack", &hknight_smash_attack}, +{"hknight_move_run", &hknight_move_run}, +{"hknight_move_walk", &hknight_move_walk}, +{"hknight_move_stand", &hknight_move_stand}, +{"q1grunt_move_death2", &q1grunt_move_death2}, +{"q1grunt_move_death1", &q1grunt_move_death1}, +{"q1grunt_move_attack", &q1grunt_move_attack}, +{"q1grunt_move_pain3", &q1grunt_move_pain3}, +{"q1grunt_move_pain2", &q1grunt_move_pain2}, +{"q1grunt_move_pain1", &q1grunt_move_pain1}, +{"q1grunt_move_run", &q1grunt_move_run}, +{"q1grunt_move_walk", &q1grunt_move_walk}, +{"q1grunt_move_stand", &q1grunt_move_stand}, +{"fiend_move_death", &fiend_move_death}, +{"fiend_move_pain", &fiend_move_pain}, +{"fiend_move_jump", &fiend_move_jump}, +{"fiend_move_attack", &fiend_move_attack}, +{"fiend_move_run", &fiend_move_run}, +{"fiend_move_walk", &fiend_move_walk}, +{"fiend_move_stand", &fiend_move_stand}, +{"q1enforcer_move_start_fire", &q1enforcer_move_start_fire}, +{"q1enforcer_move_death2", &q1enforcer_move_death2}, +{"q1enforcer_move_death1", &q1enforcer_move_death1}, +{"q1enforcer_move_pain1", &q1enforcer_move_pain1}, +{"q1enforcer_move_pain2", &q1enforcer_move_pain2}, +{"q1enforcer_move_pain3", &q1enforcer_move_pain3}, +{"q1enforcer_move_run", &q1enforcer_move_run}, +{"q1enforcer_move_walk", &q1enforcer_move_walk}, +{"q1enforcer_move_stand", &q1enforcer_move_stand}, +{"q1dog_move_death2", &q1dog_move_death2}, +{"q1dog_move_death1", &q1dog_move_death1}, +{"q1dog_move_leap", &q1dog_move_leap}, +{"q1dog_move_attack", &q1dog_move_attack}, +{"q1dog_move_pain2", &q1dog_move_pain2}, +{"q1dog_move_pain1", &q1dog_move_pain1}, +{"q1dog_move_run", &q1dog_move_run}, +{"q1dog_move_walk", &q1dog_move_walk}, +{"q1dog_move_stand", &q1dog_move_stand}, {"parasite_move_death", ¶site_move_death}, {"parasite_move_jump_down", ¶site_move_jump_down}, {"parasite_move_jump_up", ¶site_move_jump_up}, diff --git a/missionpack/g_monster.c b/missionpack/g_monster.c index cd995f8..bd9bac6 100644 --- a/missionpack/g_monster.c +++ b/missionpack/g_monster.c @@ -814,7 +814,7 @@ void M_MoveFrame (edict_t *self) // Lazarus: For live monsters weaker than gladiator who aren't already running from // something, evade live grenades on the ground. - if((self->health > 0) && (self->max_health < 400) && !(self->monsterinfo.aiflags & AI_CHASE_THING) && self->monsterinfo.run) + if ((self->health > 0) && (self->max_health < 400) && !(self->monsterinfo.aiflags & AI_CHASE_THING) && self->monsterinfo.run) Grenade_Evade (self); move = self->monsterinfo.currentmove; @@ -948,6 +948,12 @@ void monster_triggered_spawn (edict_t *self) self->movetype = MOVETYPE_STEP; self->svflags &= ~SVF_NOCLIENT; self->air_finished = level.time + 12; + // Knightmare- teleport effect for Q1 monsters + if (self->flags & FL_Q1_MONSTER) { + self->s.event = EV_PLAYER_TELEPORT; + Q1TeleportSounds(self); + } + // end Knightmare gi.linkentity (self); monster_start_go (self); @@ -1097,7 +1103,7 @@ qboolean monster_start (edict_t *self) self->air_finished = level.time + 12; self->use = monster_use; // Lazarus - don't reset max_health unnecessarily - if(!self->max_health) + if (!self->max_health) self->max_health = self->health; /* if (self->health < (self->max_health / 2)) self->s.skinnum |= 1; @@ -1110,28 +1116,28 @@ qboolean monster_start (edict_t *self) self->deadflag = DEAD_NO; self->svflags &= ~SVF_DEADMONSTER; - if(self->monsterinfo.flies > 1.0) + if (self->monsterinfo.flies > 1.0) { self->s.effects |= EF_FLIES; self->s.sound = gi.soundindex ("infantry/inflies1.wav"); } // Lazarus - if(self->health <= 0) + if (self->health <= 0) { self->svflags |= SVF_DEADMONSTER; self->movetype = MOVETYPE_TOSS; self->takedamage = DAMAGE_YES; self->monsterinfo.pausetime = 100000000; self->monsterinfo.aiflags &= ~AI_RESPAWN_FINDPLAYER; - if(self->max_health > 0) + if (self->max_health > 0) { // This must be a dead monster who changed levels // via trigger_transition self->nextthink = 0; self->deadflag = DEAD_DEAD; } - if(self->s.effects & EF_FLIES && self->monsterinfo.flies <= 1.0) + if (self->s.effects & EF_FLIES && self->monsterinfo.flies <= 1.0) { self->think = M_FliesOff; self->nextthink = level.time + 1 + random()*60; @@ -1438,19 +1444,19 @@ void InitiallyDead (edict_t *self) { int damage; - if(self->max_health > 0) + if (self->max_health > 0) return; // gi.dprintf("InitiallyDead on %s at %s\n",self->classname,vtos(self->s.origin)); // initially dead bad guys shouldn't count against totals - if((self->max_health <= 0) && !(self->monsterinfo.aiflags & AI_GOOD_GUY)) + if ((self->max_health <= 0) && !(self->monsterinfo.aiflags & AI_GOOD_GUY)) { level.total_monsters--; if(self->deadflag != DEAD_DEAD) level.killed_monsters--; } - if(self->deadflag != DEAD_DEAD) + if (self->deadflag != DEAD_DEAD) { damage = 1 - self->health; self->health = 1; @@ -1520,61 +1526,61 @@ int PatchMonsterModel (char *modelname) numskins = 8; // special cases - if(!strcmp(modelname,"models/monsters/tank/tris.md2")) + if (!strcmp(modelname,"models/monsters/tank/tris.md2")) { is_tank = true; numskins = 16; } - else if(!strcmp(modelname,"models/monsters/soldier/tris.md2")) + else if (!strcmp(modelname,"models/monsters/soldier/tris.md2")) { is_soldier = true; numskins = 24; } // Knightmare added #ifdef CITADELMOD_FEATURES - else if(!strcmp(modelname,"models/monsters/brain/tris.md2")) + else if (!strcmp(modelname,"models/monsters/brain/tris.md2")) { is_brain = true; numskins = 16; } #endif - else if(!strcmp(modelname,"models/monsters/gekk/tris.md2")) + else if (!strcmp(modelname,"models/monsters/gekk/tris.md2")) { is_gekk = true; numskins = 12; } - else if(!strcmp(modelname,"models/monsters/fixbot/tris.md2")) + else if (!strcmp(modelname,"models/monsters/fixbot/tris.md2")) { is_fixbot = true; numskins = 4; } - else if(!strcmp(modelname,"models/monsters/bitch/tris.md2") + else if (!strcmp(modelname,"models/monsters/bitch/tris.md2") || !strcmp(modelname,"models/monsters/bitch2/tris.md2")) { is_chick = true; numskins = 16; } - else if(!strcmp(modelname,"models/monsters/soldierh/tris.md2")) + else if (!strcmp(modelname,"models/monsters/soldierh/tris.md2")) { is_soldierh = true; numskins = 24; } - else if(!strcmp(modelname,"models/monsters/carrier/tris.md2")) + else if (!strcmp(modelname,"models/monsters/carrier/tris.md2")) { is_carrier = true; numskins = 8; } - else if(!strcmp(modelname,"models/monsters/hover/tris.md2")) + else if (!strcmp(modelname,"models/monsters/hover/tris.md2")) { is_hover = true; numskins = 16; } - else if(!strcmp(modelname,"models/monsters/medic/tris.md2")) + else if (!strcmp(modelname,"models/monsters/medic/tris.md2")) { is_medic = true; numskins = 16; } - else if(!strcmp(modelname,"models/monsters/turret/tris.md2")) + else if (!strcmp(modelname,"models/monsters/turret/tris.md2")) { is_turret = true; numskins = 12; diff --git a/missionpack/g_newweap.c b/missionpack/g_newweap.c index 003cb8a..dd672af 100644 --- a/missionpack/g_newweap.c +++ b/missionpack/g_newweap.c @@ -2034,7 +2034,7 @@ void tesla_think_active (edict_t *self) vec3_t dir, start; trace_t tr; - if(level.time > self->air_finished) + if (level.time > self->air_finished) { tesla_remove(self); return; @@ -2044,28 +2044,28 @@ void tesla_think_active (edict_t *self) start[2] += 12; // was 16 num = gi.BoxEdicts(self->teamchain->absmin, self->teamchain->absmax, touch, MAX_EDICTS, AREA_SOLID); - for(i=0;iinuse)) break; hit=touch[i]; - if(!hit->inuse) + if (!hit->inuse) continue; - if(hit == self) + if (hit == self) continue; - if(hit->health < 1) + if (hit->health < 1) continue; // don't hit clients in single-player or coop - if(hit->client) + if (hit->client) if (coop->value || !deathmatch->value) continue; - if(!(hit->svflags & (SVF_MONSTER | SVF_DAMAGEABLE)) && !hit->client) + if (!(hit->svflags & (SVF_MONSTER | SVF_DAMAGEABLE)) && !hit->client) continue; tr = gi.trace(start, vec3_origin, vec3_origin, hit->s.origin, self, MASK_SHOT); - if(tr.fraction==1 || tr.ent==hit)// || tr.ent->client || (tr.ent->svflags & (SVF_MONSTER | SVF_DAMAGEABLE))) + if (tr.fraction == 1 || tr.ent == hit)// || tr.ent->client || (tr.ent->svflags & (SVF_MONSTER | SVF_DAMAGEABLE))) { VectorSubtract(hit->s.origin, start, dir); @@ -2079,7 +2079,7 @@ void tesla_think_active (edict_t *self) } // PGM - don't do knockback to walking monsters - if((hit->svflags & SVF_MONSTER) && !(hit->flags & (FL_FLY|FL_SWIM))) + if ((hit->svflags & SVF_MONSTER) && !(hit->flags & (FL_FLY|FL_SWIM))) T_Damage (hit, self, self->teammaster, dir, tr.endpos, tr.plane.normal, self->dmg, 0, 0, MOD_TESLA); else @@ -2100,7 +2100,7 @@ void tesla_think_active (edict_t *self) } } - if(self->inuse) + if (self->inuse) { self->think = tesla_think_active; self->nextthink = level.time + FRAMETIME; diff --git a/missionpack/g_phys.c b/missionpack/g_phys.c index d6eecbd..72a8567 100644 --- a/missionpack/g_phys.c +++ b/missionpack/g_phys.c @@ -2129,9 +2129,17 @@ void SV_Physics_Step (edict_t *ent) return; if (ent->groundentity) + { if (!wasonground) - if (hitsound) - gi.sound (ent, 0, gi.soundindex("world/land.wav"), 1, 1, 0); + { + if (hitsound) { + if (ent->flags & FL_Q1_MONSTER) + gi.sound (ent, 0, gi.soundindex("q1fiend/dland2.wav"), 1, ATTN_NORM, 0); + else + gi.sound (ent, 0, gi.soundindex("world/land.wav"), 1, 1, 0); + } + } + } // Move func_pushable riders if (ent->movetype == MOVETYPE_PUSHABLE) diff --git a/missionpack/g_save.c b/missionpack/g_save.c index 81aa70a..2e4a448 100644 --- a/missionpack/g_save.c +++ b/missionpack/g_save.c @@ -18,21 +18,21 @@ field_t fields[] = { {"spawnflags", FOFS(spawnflags), F_INT}, {"speed", FOFS(speed), F_FLOAT}, - //Knightmare- movetype backup + // Knightmare- movetype backup {"oldmovetype", FOFS(oldmovetype), F_INT}, {"relative_velocity", FOFS(relative_velocity), F_VECTOR}, //relative velocity {"relative_avelocity", FOFS(relative_avelocity), F_VECTOR}, //relative angular velocity {"oldvelocity", FOFS(oldvelocity), F_VECTOR}, //relative angular velocity - //Knightmare- rotating train stuff + // Knightmare- rotating train stuff {"movewith_set", FOFS(movewith_set), F_INT}, {"bounce_me", FOFS(bounce_me), F_INT}, {"in_mud", FOFS(in_mud), F_INT}, - {"width", FOFS(width), F_FLOAT}, //Knightmare- these are needed to update func_door_secret's positions + {"width", FOFS(width), F_FLOAT}, // Knightmare- these are needed to update func_door_secret's positions {"length", FOFS(length), F_FLOAT}, {"side", FOFS(side), F_FLOAT}, - {"move_origin", FOFS(move_origin), F_VECTOR}, //relative angular velocity + {"move_origin", FOFS(move_origin), F_VECTOR}, // relative angular velocity {"org_angles", FOFS(org_angles), F_VECTOR}, {"deploy_angles", FOFS(deploy_angles), F_VECTOR}, {"aim_point", FOFS(aim_point), F_VECTOR}, @@ -41,7 +41,7 @@ field_t fields[] = { {"ideal_yaw", FOFS(ideal_yaw), F_FLOAT}, {"ideal_roll", FOFS(ideal_roll), F_FLOAT}, - //Knightmare- misc ent stuff + // Knightmare- misc ent stuff {"common_name", FOFS(common_name), F_LSTRING}, {"newteam", FOFS(newteam), F_LSTRING}, {"musictrack", FOFS(musictrack), F_LSTRING}, @@ -53,7 +53,7 @@ field_t fields[] = { {"shift", FOFS(shift), F_FLOAT}, {"last_attacked_framenum", FOFS(last_attacked_framenum), F_INT}, - //Knightmare + // Knightmare {"accel", FOFS(accel), F_FLOAT}, {"decel", FOFS(decel), F_FLOAT}, diff --git a/missionpack/g_spawn.c b/missionpack/g_spawn.c index 5eb9c89..937ecd6 100644 --- a/missionpack/g_spawn.c +++ b/missionpack/g_spawn.c @@ -299,6 +299,33 @@ void SP_misc_crashviper_origin (edict_t *ent); void SP_misc_strogg_ship_origin (edict_t *ent); void SP_misc_transport_origin (edict_t *ent); +// Knightmare- Q1 monsters/entities +void SP_monster_q1_chthon (edict_t *self); +void SP_monster_q1_dog (edict_t *self); +void SP_monster_q1_enforcer (edict_t *self); +void SP_monster_q1_fiend (edict_t *self); +void SP_monster_q1_grunt (edict_t *self); +void SP_monster_q1_hknight (edict_t *self); +void SP_monster_q1_knight (edict_t *self); +void SP_monster_q1_ogre (edict_t *self); +void SP_monster_q1_rotfish (edict_t *self); +void SP_monster_q1_scrag (edict_t *self); +void SP_monster_q1_shalrath (edict_t *self); +void SP_monster_q1_shambler (edict_t *self); +void SP_monster_q1_tarbaby (edict_t *self); +void SP_monster_q1_zombie (edict_t *self); + +void SP_misc_q1_zombie_crucified (edict_t *self); +void SP_misc_q1_air_bubbles (edict_t *self); +void SP_misc_q1_large_flame(edict_t *self); +void SP_misc_q1_small_flame (edict_t *self); +void SP_misc_q1_torch(edict_t *self); +void SP_target_q1_trap(edict_t *self); +void SP_misc_q1_explobox(edict_t *self); +void SP_misc_q1_fireball(edict_t *self); +void SP_misc_q1_globe(edict_t *self); +// end Knightmare + // transition entities void SP_bolt (edict_t *self); void SP_bolt2 (edict_t *self); @@ -447,7 +474,7 @@ spawn_t spawns[] = { //Knightmare- experiment gekks {"misc_gekk_writhe", SP_misc_gekk_writhe}, - //Knightmare- Coconut Monkey 3 Flame entities + // Knightmare- Coconut Monkey 3 Flame entities {"light_flame1", SP_light_flame1}, {"light_flame1s", SP_light_flame1s}, {"light_flame2", SP_light_flame2}, @@ -626,6 +653,51 @@ spawn_t spawns[] = { {"misc_strogg_ship_origin", SP_misc_strogg_ship_origin}, {"misc_transport_origin", SP_misc_transport_origin}, +// Knightmare- Q1 monsters/entities + // Generations spawn names +// {"q1_monster_chton", SP_monster_q1_chthon}, + {"q1_monster_dog", SP_monster_q1_dog}, + {"q1_monster_enforcer", SP_monster_q1_enforcer}, + {"q1_monster_fiend", SP_monster_q1_fiend}, + {"q1_monster_soldier", SP_monster_q1_grunt}, + {"q1_monster_hknight", SP_monster_q1_hknight}, + {"q1_monster_knight", SP_monster_q1_knight}, + {"q1_monster_ogre", SP_monster_q1_ogre}, + {"q1_monster_fish", SP_monster_q1_rotfish}, + {"q1_monster_scrag", SP_monster_q1_scrag}, + {"q1_monster_shambler", SP_monster_q1_shambler}, + {"q1_monster_shalrath", SP_monster_q1_shalrath}, + {"q1_monster_tarbaby", SP_monster_q1_tarbaby}, + {"q1_monster_zombie", SP_monster_q1_zombie}, + + // Q2Infighter spawn names +// {"monster_q1_chthon", SP_monster_q1_chthon}, + {"monster_q1_dog", SP_monster_q1_dog}, + {"monster_q1_enforcer", SP_monster_q1_enforcer}, + {"monster_q1_demon", SP_monster_q1_fiend}, + {"monster_q1_army", SP_monster_q1_grunt}, + {"monster_q1_hknight", SP_monster_q1_hknight}, + {"monster_q1_knight", SP_monster_q1_knight}, + {"monster_q1_ogre", SP_monster_q1_ogre}, + {"monster_q1_fish", SP_monster_q1_rotfish}, + {"monster_q1_wizard", SP_monster_q1_scrag}, + {"monster_q1_shambler", SP_monster_q1_shambler}, + {"monster_q1_shalrath", SP_monster_q1_shalrath}, + {"monster_q1_tarbaby", SP_monster_q1_tarbaby}, + {"monster_q1_zombie", SP_monster_q1_zombie}, + + // misc Q1 entities + {"misc_q1_zombie_crucified", SP_misc_q1_zombie_crucified}, + {"misc_q1_air_bubbles", SP_misc_q1_air_bubbles}, + {"misc_q1_large_flame", SP_misc_q1_large_flame}, + {"misc_q1_small_flame", SP_misc_q1_small_flame}, + {"misc_q1_torch", SP_misc_q1_torch}, + {"target_q1_trap", SP_target_q1_trap}, + {"misc_q1_light_globe", SP_misc_q1_globe}, + {"misc_q1_explobox", SP_misc_q1_explobox}, + {"misc_q1_fireball",SP_misc_q1_fireball}, +// end Knightmare + // transition entities {"bolt", SP_bolt}, {"bolt2", SP_bolt2}, @@ -703,9 +775,9 @@ void ED_CallSpawn (edict_t *ent) && IsXatrixMap() && !strcmp(ent->classname, "monster_brain")) ent->classname = "monster_brain_beta"; - //Knightmare- mission pack monster replacement + // Knightmare- mission pack monster replacement if (mp_monster_replace->value) - { //gladiator + { // gladiator if (!strcmp(ent->classname, "monster_gladiator")) { ent->classname = "monster_gladb"; @@ -716,10 +788,10 @@ void ED_CallSpawn (edict_t *ent) st.item = NULL; } } - //brain + // brain if (!strcmp(ent->classname, "monster_brain")) ent->classname = "monster_brain_beta"; - //soldiers + // soldiers if (!strcmp(ent->classname, "monster_soldier_light")) { ent->classname = "monster_soldier_ripper"; @@ -750,16 +822,16 @@ void ED_CallSpawn (edict_t *ent) st.item = NULL; } } - //icarus + // icarus if (!strcmp(ent->classname, "monster_hover")) ent->classname = "monster_daedalus"; - //supertank + // supertank if (!strcmp(ent->classname, "monster_supertank")) ent->classname = "monster_boss5"; - //chick + // chick if (!strcmp(ent->classname, "monster_chick")) ent->classname = "monster_chick_heat"; - //medic + // medic if (!strcmp(ent->classname, "monster_medic") //don't spawn another medic commander from medic commander && !(ent->monsterinfo.monsterflags & MFL_DO_NOT_COUNT)) diff --git a/missionpack/g_trigger.c b/missionpack/g_trigger.c index 23f953d..633e3e8 100644 --- a/missionpack/g_trigger.c +++ b/missionpack/g_trigger.c @@ -352,19 +352,45 @@ void trigger_key_use (edict_t *self, edict_t *other, edict_t *activator) if (level.time < self->touch_debounce_time) return; self->touch_debounce_time = level.time + 5.0; - if(!(self->spawnflags & 4)) + if (!(self->spawnflags & 4)) { if (self->key_message && strlen(self->key_message)) gi.centerprintf (activator, self->key_message); else gi.centerprintf (activator, "You need the %s", self->item->pickup_name); + // Skid added + if (self->item->flags & IT_Q1) + { + if (index == key_q1_med_gold_index || index == key_q1_med_silver_index) + gi.sound (activator, CHAN_AUTO, gi.soundindex ("q1world/doors/medtry.wav"), 1, ATTN_NORM, 0); + else if (index == key_q1_base_gold_index || index == key_q1_base_silver_index) + gi.sound (activator, CHAN_AUTO, gi.soundindex ("q1world/doors/basetry.wav"), 1, ATTN_NORM, 0); + else + gi.sound (activator, CHAN_AUTO, gi.soundindex ("q1world/doors/runetry.wav"), 1, ATTN_NORM, 0); + } + else + // end Skid gi.sound (activator, CHAN_AUTO, gi.soundindex ("misc/keytry.wav"), 1, ATTN_NORM, 0); } return; } - if(!(self->spawnflags & 4)) + if (!(self->spawnflags & 4)) + { + // Skid added + if (self->item->flags & IT_Q1) + { + if (index == key_q1_med_gold_index || index == key_q1_med_silver_index) + gi.sound (activator, CHAN_AUTO, gi.soundindex ("q1world/doors/meduse.wav"), 1, ATTN_NORM, 0); + else if (index == key_q1_base_gold_index || index == key_q1_base_silver_index) + gi.sound (activator, CHAN_AUTO, gi.soundindex ("q1world/doors/baseuse.wav"), 1, ATTN_NORM, 0); + else + gi.sound (activator, CHAN_AUTO, gi.soundindex ("q1world/doors/runeuse.wav"), 1, ATTN_NORM, 0); + } + else + // end Skid gi.sound (activator, CHAN_AUTO, gi.soundindex ("misc/keyuse.wav"), 1, ATTN_NORM, 0); + } if (coop->value) { int player; diff --git a/missionpack/g_utils_q1.c b/missionpack/g_utils_q1.c new file mode 100644 index 0000000..ca7bdf3 --- /dev/null +++ b/missionpack/g_utils_q1.c @@ -0,0 +1,60 @@ +// g_utils_q1.c + +#include "g_local.h" + +float PointDist (vec3_t x, vec3_t y) +{ + vec3_t len; + float dist; + + VectorSubtract (x, y, len); + dist = VectorLength(len); + return dist; +} + +void Q1TeleportSounds (edict_t *ent) +{ + float sound = random(); + + if (sound < 0.2) + gi.sound (ent, CHAN_NO_PHS_ADD+CHAN_VOICE, gi.soundindex("q1world/teleport/r_tele1.wav"), 1, ATTN_NORM, 0); + else if (sound < 0.4) + gi.sound (ent, CHAN_NO_PHS_ADD+CHAN_VOICE, gi.soundindex("q1world/teleport/r_tele2.wav"), 1, ATTN_NORM, 0); + else if (sound < 0.6) + gi.sound (ent, CHAN_NO_PHS_ADD+CHAN_VOICE, gi.soundindex("q1world/teleport/r_tele3.wav"), 1, ATTN_NORM, 0); + else if (sound < 0.8) + gi.sound (ent, CHAN_NO_PHS_ADD+CHAN_VOICE, gi.soundindex("q1world/teleport/r_tele4.wav"), 1, ATTN_NORM, 0); + else + gi.sound (ent, CHAN_NO_PHS_ADD+CHAN_VOICE, gi.soundindex("q1world/teleport/r_tele5.wav"), 1, ATTN_NORM, 0); +} + +void Q1TeleportSounds2 (edict_t *ent1, edict_t *ent2) +{ + float sound = random(); + + if(sound < 0.2) + { + gi.sound (ent1, CHAN_NO_PHS_ADD+CHAN_VOICE, gi.soundindex("q1world/teleport/r_tele1.wav"), 1, ATTN_NORM, 0); + gi.sound (ent2, CHAN_NO_PHS_ADD+CHAN_VOICE, gi.soundindex("q1world/teleport/r_tele1.wav"), 1, ATTN_NORM, 0); + } + else if (sound < 0.4) + { + gi.sound (ent1, CHAN_NO_PHS_ADD+CHAN_VOICE, gi.soundindex("q1world/teleport/r_tele2.wav"), 1, ATTN_NORM, 0); + gi.sound (ent2, CHAN_NO_PHS_ADD+CHAN_VOICE, gi.soundindex("q1world/teleport/r_tele2.wav"), 1, ATTN_NORM, 0); + } + else if (sound < 0.6) + { + gi.sound (ent1, CHAN_NO_PHS_ADD+CHAN_VOICE, gi.soundindex("q1world/teleport/r_tele3.wav"), 1, ATTN_NORM, 0); + gi.sound (ent2, CHAN_NO_PHS_ADD+CHAN_VOICE, gi.soundindex("q1world/teleport/r_tele3.wav"), 1, ATTN_NORM, 0); + } + else if (sound < 0.8) + { + gi.sound (ent1, CHAN_NO_PHS_ADD+CHAN_VOICE, gi.soundindex("q1world/teleport/r_tele4.wav"), 1, ATTN_NORM, 0); + gi.sound (ent2, CHAN_NO_PHS_ADD+CHAN_VOICE, gi.soundindex("q1world/teleport/r_tele4.wav"), 1, ATTN_NORM, 0); + } + else + { + gi.sound (ent1, CHAN_NO_PHS_ADD+CHAN_VOICE, gi.soundindex("q1world/teleport/r_tele5.wav"), 1, ATTN_NORM, 0); + gi.sound (ent2, CHAN_NO_PHS_ADD+CHAN_VOICE, gi.soundindex("q1world/teleport/r_tele5.wav"), 1, ATTN_NORM, 0); + } +} diff --git a/missionpack/g_weapon.c b/missionpack/g_weapon.c index b2be037..9b7a4f6 100644 --- a/missionpack/g_weapon.c +++ b/missionpack/g_weapon.c @@ -477,7 +477,7 @@ void fire_blueblaster (edict_t *self, vec3_t start, vec3_t dir, int damage, int // entities. void bolt_delayed_start (edict_t *bolt) { - if(g_edicts[1].linkcount) + if (g_edicts[1].linkcount) { VectorScale(bolt->movedir,bolt->moveinfo.speed,bolt->velocity); bolt->nextthink = level.time + 2; @@ -490,9 +490,9 @@ void bolt_delayed_start (edict_t *bolt) void SP_bolt (edict_t *bolt) { - if (bolt->count == 2) //green bolt + if (bolt->count == 2) // green bolt bolt->s.modelindex = gi.modelindex ("models/objects/laser2/tris.md2"); - else if (bolt->count == 3) //blue bolt + else if (bolt->count == 3) // blue bolt bolt->s.modelindex = gi.modelindex ("models/objects/blaser/tris.md2"); else //orange bolt bolt->s.modelindex = gi.modelindex ("models/objects/laser/tris.md2"); diff --git a/missionpack/g_weapon_q1.c b/missionpack/g_weapon_q1.c new file mode 100644 index 0000000..a8819c3 --- /dev/null +++ b/missionpack/g_weapon_q1.c @@ -0,0 +1,1014 @@ +// g_weapon_q1.c + +#include "g_local.h" + + +void check_dodge (edict_t *self, vec3_t start, vec3_t dir, int speed); + + +/* +================= +q1_fire_nail + +Fires a Nail, Used by Q1 NG and SNG +================= +*/ +void q1_nail_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) +{ + int mod; + + if (other == self->owner) + return; + + if (surf && (surf->flags & SURF_SKY)) + { + G_FreeEdict (self); + return; + } + + if (self->owner->client) + PlayerNoise(self->owner, self->s.origin, PNOISE_IMPACT); + + if (other->takedamage) + { + if (self->spawnflags & 1) + mod = MOD_Q1_SNG; + else + mod = MOD_Q1_NG; + T_Damage (other, self, self->owner, self->velocity, self->s.origin, plane->normal, self->dmg, 0, DAMAGE_BULLET, mod); + } + else + { + gi.WriteByte (svc_temp_entity); + gi.WriteByte (TE_SHOTGUN); + gi.WritePosition (self->s.origin); + if (!plane) + gi.WriteDir (vec3_origin); + else + gi.WriteDir (plane->normal); + gi.multicast (self->s.origin, MULTICAST_PVS); + + //not if online, too laggy + if(!deathmatch->value) + { + float sound= random(); + if (sound < 0.3) + { + if (sound < 0.1) + gi.sound (self, CHAN_WEAPON, gi.soundindex ("q1weap/nails/ric3.wav"), 1, ATTN_STATIC, 0); + else if (sound < 0.2) + gi.sound (self, CHAN_WEAPON, gi.soundindex ("q1weap/nails/ric2.wav"), 1, ATTN_STATIC, 0); + else + gi.sound (self, CHAN_WEAPON, gi.soundindex ("q1weap/nails/ric1.wav"), 1, ATTN_STATIC, 0); + } + else if (sound < 0.5) + gi.sound (self, CHAN_WEAPON, gi.soundindex ("q1weap/nails/tink1.wav"), 1, ATTN_STATIC, 0); + } + + } + G_FreeEdict (self); +} + + +void q1_fire_nail (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, qboolean sng) +{ + edict_t *nail; + trace_t tr; + + VectorNormalize (dir); + + nail = G_Spawn(); + VectorCopy (start, nail->s.origin); + VectorCopy (start, nail->s.old_origin); + vectoangles (dir, nail->s.angles); + VectorScale (dir, speed, nail->velocity); + nail->movetype = MOVETYPE_FLYMISSILE; + nail->clipmask = MASK_SHOT; + nail->solid = SOLID_BBOX; + nail->svflags = SVF_DEADMONSTER; + nail->s.renderfx = RF_FULLBRIGHT; + VectorClear (nail->mins); + VectorClear (nail->maxs); + nail->s.modelindex = gi.modelindex ("models/objects/q1nail/tris.md2"); + nail->owner = self; + nail->touch = q1_nail_touch; + nail->nextthink = level.time + 8000/speed; + nail->think = G_FreeEdict; + nail->dmg = damage; + nail->classname = "nail"; + if (sng) + nail->spawnflags = 1; + + nail->common_name = "Nail"; + + gi.linkentity (nail); + + if (self->client) + check_dodge (self, nail->s.origin, dir, speed); + + tr = gi.trace (self->s.origin, NULL, NULL, nail->s.origin, nail, MASK_SHOT); + if (tr.fraction < 1.0) + { + VectorMA (nail->s.origin, -10, dir, nail->s.origin); + nail->touch (nail, tr.ent, NULL, NULL); + } +} + + +/* +================= +q1_fire_laser + +Fires a laser bolt, used by Q1 enforcer and laser trap. +================= +*/ +void q1_laser_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) +{ + if (other == self->owner) + return; + + if (surf && (surf->flags & SURF_SKY)) + { + G_FreeEdict (self); + return; + } + + if (self->owner->client) + PlayerNoise(self->owner, self->s.origin, PNOISE_IMPACT); + + if (other->takedamage) { + T_Damage (other, self, self->owner, self->velocity, self->s.origin, plane->normal, self->dmg, 0, DAMAGE_ENERGY, MOD_Q1_LASER); + } + else + { +#if 1 // From Decino's Q2Infighter mod + gi.WriteByte (svc_temp_entity); + gi.WriteByte (TE_WELDING_SPARKS); + gi.WriteByte (15); + gi.WritePosition (self->s.origin); + gi.WriteDir ((!plane) ? vec3_origin : plane->normal); + gi.WriteByte (226); + gi.multicast (self->s.origin, MULTICAST_PVS); +#else + gi.WriteByte (svc_temp_entity); + gi.WriteByte (TE_SHOTGUN); + gi.WritePosition (self->s.origin); + if (!plane) + gi.WriteDir (vec3_origin); + else + gi.WriteDir (plane->normal); + gi.multicast (self->s.origin, MULTICAST_PVS); +#endif + + // not if online, too laggy + if (!deathmatch->value) + { + gi.sound (self, CHAN_WEAPON, gi.soundindex ("q1enforcer/enfstop.wav"), 1, ATTN_STATIC, 0); + } + } + G_FreeEdict (self); +} + +void q1_fire_laser (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed) +{ + edict_t *laser; + trace_t tr; + + VectorNormalize (dir); + + laser = G_Spawn(); + VectorCopy (start, laser->s.origin); + VectorCopy (start, laser->s.old_origin); + vectoangles (dir, laser->s.angles); + VectorScale (dir, speed, laser->velocity); + laser->movetype = MOVETYPE_FLYMISSILE; + laser->clipmask = MASK_SHOT; + laser->solid = SOLID_BBOX; + laser->svflags = SVF_DEADMONSTER; + laser->s.renderfx = RF_FULLBRIGHT; + VectorClear (laser->mins); + VectorClear (laser->maxs); + laser->s.modelindex = gi.modelindex ("models/monsters/q1enforcer/laser/tris.md2"); + laser->owner = self; + laser->touch = q1_laser_touch; + laser->nextthink = level.time + 8000/speed; + laser->think = G_FreeEdict; + laser->dmg = damage; + laser->classname = "laser"; + + laser->common_name = "Laser"; + + gi.linkentity (laser); + + if (self->client) + check_dodge (self, laser->s.origin, dir, speed); + + tr = gi.trace (self->s.origin, NULL, NULL, laser->s.origin, laser, MASK_SHOT); + if (tr.fraction < 1.0) + { + VectorMA (laser->s.origin, -10, dir, laser->s.origin); + laser->touch (laser, tr.ent, NULL, NULL); + } +} + + +/* +================= +q1_fire_flame + +Fires a flame bolt. Used by the Hell Knight. +================= +*/ + +void q1_flame_splash (int type, int count, int color, vec3_t start, vec3_t movdir, vec3_t origin) +{ + gi.WriteByte (svc_temp_entity); + gi.WriteByte (type); + gi.WriteByte (count); + gi.WritePosition (start); + gi.WriteDir (movdir); + gi.WriteByte (color); + gi.multicast (origin, MULTICAST_PVS); +} + +void q1_flame_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) +{ + if (other == self->owner) + return; + + if (surf && (surf->flags & SURF_SKY)) + { + G_FreeEdict (self); + return; + } + + if (self->owner->client) + PlayerNoise(self->owner, self->s.origin, PNOISE_IMPACT); + + if (other->takedamage) + { + T_Damage (other, self, self->owner, self->velocity, self->s.origin, plane->normal, self->dmg, 1, DAMAGE_ENERGY, MOD_Q1_FLAMEBOLT); + } + else + { +#if 1 // From Decino's Q2Infighter mod + gi.WriteByte (svc_temp_entity); + gi.WriteByte (TE_WELDING_SPARKS); + gi.WriteByte (15); + gi.WritePosition (self->s.origin); + gi.WriteDir ((!plane) ? vec3_origin : plane->normal); + // gi.WriteByte (66); + gi.WriteByte (228); + gi.multicast (self->s.origin, MULTICAST_PVS); +#else + q1_flame_splash (TE_TUNNEL_SPARKS, 16, 71, self->s.origin, plane->normal, self->s.origin); +#endif + } + + gi.sound (self, CHAN_WEAPON, gi.soundindex("q1hknight/hit.wav"), 1, ATTN_NORM, 0); + + G_FreeEdict (self); +} + +void q1_fire_flame (edict_t *self, vec3_t start, vec3_t dir, float leftrightoff) +{ + edict_t *bolt; + trace_t tr; + int damage, speed; +// vec3_t up; + + damage = 9; + speed = 300; + + VectorNormalize (dir); + + bolt = G_Spawn(); + bolt->svflags |= SVF_DEADMONSTER; + // yes, I know it looks weird that projectiles are deadmonsters + // what this means is that when prediction is used against the object + // (blaster/hyperblaster shots), the player won't be solid clipped against + // the object. Right now trying to run into a firing hyperblaster + // is very jerky since you are predicted 'against' the shots. + + VectorCopy (start, bolt->s.origin); + VectorCopy (start, bolt->s.old_origin); + vectoangles (dir, bolt->s.angles); + VectorScale (dir, speed, bolt->velocity); + bolt->movetype = MOVETYPE_FLYMISSILE; + bolt->clipmask = MASK_SHOT; + bolt->solid = SOLID_BBOX; + bolt->s.effects |= EF_IONRIPPER; + VectorClear (bolt->mins); + VectorClear (bolt->maxs); + bolt->s.modelindex = gi.modelindex ("models/monsters/q1hknight/k_spike/tris.md2"); + bolt->owner = self; + bolt->touch = q1_flame_touch; + bolt->nextthink = level.time + 2; + bolt->think = G_FreeEdict; + bolt->dmg = damage; + bolt->classname = "bolt"; + + bolt->common_name = "Hell Knight Flame"; + + gi.linkentity (bolt); + + tr = gi.trace (self->s.origin, NULL, NULL, bolt->s.origin, bolt, MASK_SHOT); + if (tr.fraction < 1.0) + { + VectorMA (bolt->s.origin, -10, dir, bolt->s.origin); + bolt->touch (bolt, tr.ent, NULL, NULL); + } +} + + +/* +================= +q1_fire_grenade + +Fires a grenade. Used by the Ogre. +================= +*/ +void q1_explode (edict_t *self) +{ + if (self->s.frame == 5) + { + G_FreeEdict (self); + return; + } + self->nextthink = level.time + FRAMETIME; + self->s.frame++; +} + +void q1_grenade_explode (edict_t *ent) +{ + vec3_t origin; + + if (ent->owner->client) + PlayerNoise(ent->owner, ent->s.origin, PNOISE_IMPACT); + + // FIXME: if we are onground then raise our Z just a bit since we are a point? + if (ent->enemy) + { + float points; + vec3_t v; + vec3_t dir; + + VectorAdd (ent->enemy->mins, ent->enemy->maxs, v); + VectorMA (ent->enemy->s.origin, 0.5, v, v); + VectorSubtract (ent->s.origin, v, v); + points = ent->dmg - 0.5 * VectorLength (v); + VectorSubtract (ent->enemy->s.origin, ent->s.origin, dir); + T_Damage (ent->enemy, ent, ent->owner, dir, ent->s.origin, vec3_origin, (int)points, (int)points, DAMAGE_RADIUS, MOD_Q1_GL); + } + + T_RadiusDamage(ent, ent->owner, ent->dmg, ent->enemy, ent->dmg_radius, MOD_Q1_GL_SPLASH); + + VectorMA (ent->s.origin, -0.02, ent->velocity, origin); + gi.sound (ent, CHAN_AUTO, gi.soundindex ("q1weap/rocket/r_exp3.wav"), 1.0, ATTN_NORM, 0); + + gi.WriteByte (svc_temp_entity); + gi.WriteByte (TE_ROCKET_EXPLOSION); + gi.WritePosition (origin); + gi.multicast (ent->s.origin, MULTICAST_PVS); + + // explosion sprite + gi.unlinkentity (ent); + ent->solid = SOLID_NOT; + ent->touch = NULL; + VectorCopy( origin, ent->s.origin); + VectorCopy( origin, ent->s.old_origin); + VectorClear (ent->velocity); + ent->s.modelindex = gi.modelindex ("sprites/s_explod.sp2"); + ent->s.frame = 0; + ent->s.sound = 0; + ent->s.effects &= ~EF_ANIM_ALLFAST; + ent->think = q1_explode; + ent->nextthink = level.time + FRAMETIME; + gi.linkentity (ent); +} + + +void q1_grenade_touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) +{ + if (other == ent->owner) + return; + + if (surf && (surf->flags & SURF_SKY)) + { + G_FreeEdict (ent); + return; + } + + if (!other->takedamage || + (other->solid == SOLID_BSP)) + { + gi.sound (ent, CHAN_RELIABLE|CHAN_WEAPON, gi.soundindex ("q1weap/grenades/bounce.wav"), 1, ATTN_NORM, 0); + return; + } + + ent->enemy = other; + q1_grenade_explode (ent); +} + + +void q1_fire_grenade (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, float timer, float damage_radius) +{ + edict_t *grenade; + vec3_t dir; + vec3_t forward, right, up; + + vectoangles (aimdir, dir); + AngleVectors (dir, forward, right, up); + grenade = G_Spawn(); + VectorCopy (start, grenade->s.origin); + VectorScale (aimdir, speed, grenade->velocity); + VectorMA (grenade->velocity, 200 + (random() - 0.5) * 20.0, up, grenade->velocity); + VectorMA (grenade->velocity, (random() - 0.5) * 20.0, right, grenade->velocity); + VectorSet (grenade->avelocity, 300, 300, 300); + grenade->movetype = MOVETYPE_BOUNCE; + grenade->clipmask = MASK_SHOT; + grenade->solid = SOLID_BBOX; + grenade->s.effects |= EF_GRENADE; + VectorClear (grenade->mins); + VectorClear (grenade->maxs); + grenade->s.modelindex = gi.modelindex ("models/objects/grenade/tris.md2"); + grenade->owner = self; + grenade->touch = q1_grenade_touch; + grenade->nextthink = level.time + timer; + grenade->think = q1_grenade_explode; + grenade->dmg = damage; + grenade->dmg_radius = damage_radius; + grenade->classname = "grenade"; + + grenade->common_name = "Quake Grenade"; + + gi.linkentity (grenade); +} + + +/* +================= +q1_fire_rocket + +Fires a q1 rocket. Used by ? +================= +*/ +void q1_rocket_touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) +{ + vec3_t origin; + + if (other == ent->owner) + return; + + if (surf && (surf->flags & SURF_SKY)) + { + G_FreeEdict (ent); + return; + } + + if (ent->owner->client) + PlayerNoise(ent->owner, ent->s.origin, PNOISE_IMPACT); + + // calculate position for the explosion entity + VectorMA (ent->s.origin, -0.02, ent->velocity, origin); + + if (other->takedamage) + { + T_Damage (other, ent, ent->owner, ent->velocity, ent->s.origin, plane->normal, ent->dmg, 0, 0, MOD_Q1_RL); + } + T_RadiusDamage(ent, ent->owner, ent->radius_dmg, other, ent->dmg_radius, MOD_Q1_RL_SPLASH); + gi.sound (ent,CHAN_AUTO , gi.soundindex ("q1weap/rocket/r_exp3.wav"), 1.0, ATTN_NORM, 0); + + gi.WriteByte (svc_temp_entity); + gi.WriteByte (TE_ROCKET_EXPLOSION); + gi.WritePosition (origin); + gi.multicast (ent->s.origin, MULTICAST_PVS); + +// if (ent->target_ent) +// G_FreeEdict(ent->target_ent); + + // explosion sprite + gi.unlinkentity (ent); + ent->solid = SOLID_NOT; + ent->touch = NULL; + VectorCopy( origin, ent->s.origin); + VectorCopy( origin, ent->s.old_origin); + VectorClear (ent->velocity); + ent->s.modelindex = gi.modelindex ("sprites/s_explod.sp2"); + ent->s.frame = 0; + ent->s.sound = 0; + ent->s.effects &= ~EF_ANIM_ALLFAST; + ent->think = q1_explode; + ent->nextthink = level.time + FRAMETIME; + gi.linkentity (ent); +} + + +void q1rocketTrail_touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) +{ + G_FreeEdict (ent); +} + +// Rocket Trails +// needed to give the yellow part of the Rocket trail + +void q1rocket_trail (edict_t *self, vec3_t start, vec3_t dir) +{ + edict_t *bolt; + VectorNormalize (dir); + + bolt = G_Spawn(); + VectorCopy (start, bolt->s.origin); + VectorCopy (start, bolt->s.old_origin); + vectoangles (dir, bolt->s.angles); + VectorScale (dir, 950, bolt->velocity); + bolt->movetype = MOVETYPE_FLYMISSILE; + bolt->clipmask = MASK_SHOT; + bolt->solid = SOLID_BBOX; + bolt->s.effects = EF_BLASTER; + bolt->svflags |= SVF_DEADMONSTER; + VectorClear (bolt->mins); + VectorClear (bolt->maxs); + bolt->s.modelindex = gi.modelindex ("models/objects/laser/tris.md2"); + bolt->owner = self; + bolt->touch = q1rocketTrail_touch; + bolt->nextthink = level.time + 8000/950; + bolt->think = G_FreeEdict; + bolt->classname = "bolt"; + gi.linkentity (bolt); + +} + + +void q1_fire_rocket (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, float damage_radius, int radius_damage) +{ + edict_t *rocket; + + rocket = G_Spawn(); + VectorCopy (start, rocket->s.origin); + VectorCopy (dir, rocket->movedir); + vectoangles (dir, rocket->s.angles); + VectorScale (dir, speed, rocket->velocity); + rocket->movetype = MOVETYPE_FLYMISSILE; + rocket->clipmask = MASK_SHOT; + rocket->solid = SOLID_BBOX; + rocket->s.effects |= EF_GRENADE; + VectorClear (rocket->mins); + VectorClear (rocket->maxs); + rocket->s.modelindex = gi.modelindex ("models/objects/rocket/tris.md2"); + rocket->owner = self; + rocket->touch = q1_rocket_touch; + rocket->nextthink = level.time + 8000/speed; + rocket->think = G_FreeEdict; + rocket->dmg = damage; + rocket->radius_dmg = radius_damage; + rocket->dmg_radius = damage_radius; + rocket->s.sound = gi.soundindex ("weapons/rockfly.wav"); + rocket->classname = "rocket"; + + q1rocket_trail (rocket, start, dir); + + rocket->common_name = "Quake Rocket"; + + gi.linkentity (rocket); +} + + +/* +================= +q1_fire_lightning + +Fires a lighting bolt. Used by ? +================= +*/ +void q1_fire_lightning (edict_t *self, vec3_t start, vec3_t dir, int damage) +{ + vec3_t end; + trace_t tr; + + + VectorNormalize(dir); + VectorMA(start,600,dir,end); + + // Initial Trace - damage if close enough + tr = gi.trace (self->s.origin, NULL, NULL, start, self, MASK_SHOT); + if (tr.fraction < 1.0) + { + if(tr.ent && (tr.ent !=self) && (tr.ent->takedamage)) + T_Damage (tr.ent, self, self, dir, tr.endpos, tr.plane.normal, damage, 0, DAMAGE_ENERGY, MOD_Q1_LG); + return; + } + else + { + // trace 2 + tr = gi.trace (start, NULL, NULL, end, self, MASK_SHOT); + + if(self->client->chasetoggle) + { + gi.WriteByte (svc_temp_entity); + gi.WriteByte (TE_MEDIC_CABLE_ATTACK); +// gi.WriteByte (TE_HEATBEAM); + gi.WriteShort (self->client->oldplayer - g_edicts); + gi.WritePosition (start); + gi.WritePosition (tr.endpos); + gi.multicast (self->client->oldplayer->s.origin, MULTICAST_PVS); +// gi.multicast (self->client->oldplayer->s.origin, MULTICAST_ALL); + } + else + { + gi.WriteByte (svc_temp_entity); + gi.WriteByte (TE_MEDIC_CABLE_ATTACK); +// gi.WriteByte (TE_HEATBEAM); + gi.WriteShort (self - g_edicts); + gi.WritePosition (start); + gi.WritePosition (tr.endpos); + gi.multicast (self->s.origin, MULTICAST_PVS); +// gi.multicast (self->s.origin, MULTICAST_ALL); + } + + if ((tr.ent != self) && (tr.ent->takedamage)) + T_Damage (tr.ent, self, self, dir, tr.endpos, tr.plane.normal, damage, 0, DAMAGE_ENERGY, MOD_Q1_LG); + } +} + + +/* +================= +q1_fire_firepod + +Fires a homing fire pod. Used by the Vore (shalrath). +================= +*/ +void q1_firepod_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) +{ +// int mod; + vec3_t origin; + + if (other == self->owner) + return; + + if ( (Q_stricmp(other->classname, "q1_monster_zombie") == 0) || (Q_stricmp(other->classname, "monster_q1_zombie") == 0) ) + T_Damage (other, self, self->owner, vec3_origin, other->s.origin, vec3_origin, 200, 0, 0, 0); + T_RadiusDamage (self, self->owner, 40, NULL, 40, MOD_Q1_FIREPOD); + + gi.sound (self,CHAN_AUTO , gi.soundindex ("q1weap/rocket/r_exp3.wav"), 1.0, ATTN_NORM, 0); + + VectorMA (self->s.origin, -0.02, self->velocity, origin); + +// gi.WriteByte (svc_temp_entity); +// gi.WriteByte (TE_Q1_EXPLOSION); + // FX Paril +// gi.WriteByte (TE_ROCKET_EXPLOSION); +// gi.WritePosition (origin); +// gi.multicast (self->s.origin, MULTICAST_PVS); + + gi.unlinkentity (self); + self->solid = SOLID_NOT; + self->touch = NULL; + VectorCopy (origin, self->s.origin); + VectorCopy (origin, self->s.old_origin); + VectorClear (self->velocity); + self->s.modelindex = gi.modelindex ("sprites/s_explod.sp2"); + self->s.frame = 0; + self->s.sound = 0; + self->s.effects &= ~EF_ANIM_ALLFAST; + self->think = q1_explode; + self->nextthink = level.time + FRAMETIME; + gi.linkentity (self); + +// q1_explo_particles (self, origin); +// if (Q_stricmp(self->classname, "freed")) +// G_FreeEdict (self); +} + + +void q1_firepod_home (edict_t *self) +{ + vec3_t dir, vtemp; + VectorClear (self->velocity); + VectorCopy (self->enemy->s.origin, vtemp); + VectorSet (dir, 0, 0, 10); + VectorAdd (vtemp, dir, vtemp); + VectorClear (dir); + if (self->enemy->health < 1) + { + G_FreeEdict(self); + return; + } + if (self->enemy->client && (self->enemy->client->ps.pmove.pm_flags & PMF_DUCKED)) + vtemp[2] -= 10; + VectorSubtract (vtemp, self->s.origin, dir); + VectorNormalize (dir); + if (skill->value >= 2) + VectorMA (self->velocity, 350, dir, self->velocity); + else + VectorMA (self->velocity, 250, dir, self->velocity); + self->nextthink = level.time + 0.2; +} + + +void q1_fire_firepod (edict_t *self, vec3_t dir) +{ + edict_t *pod; + trace_t tr; + vec3_t start, temp; + + VectorCopy (self->s.origin, start); + VectorSet (temp, 0, 0, 10); + VectorAdd (start, temp, start); + + VectorNormalize (dir); + + pod = G_Spawn(); + pod->svflags |= SVF_DEADMONSTER; + // yes, I know it looks weird that projectiles are deadmonsters + // what this means is that when prediction is used against the object + // (blaster/hyperblaster shots), the player won't be solid clipped against + // the object. Right now trying to run into a firing hyperblaster + // is very jerky since you are predicted 'against' the shots. + + VectorCopy (start, pod->s.origin); + VectorCopy (start, pod->s.old_origin); + vectoangles (dir, pod->s.angles); + VectorScale (dir, 400, pod->velocity); + pod->movetype = MOVETYPE_FLYMISSILE; + pod->clipmask = MASK_SHOT; + pod->solid = SOLID_BBOX; + VectorSet (pod->avelocity, 300, 300, 300); +#ifdef KMQUAKE2_ENGINE_MOD + pod->s.effects |= EF_FLAG1|EF_BLUEHYPERBLASTER; +#else + pod->s.effects |= EF_FLAG1|EF_FLAG2; +#endif + VectorClear (pod->mins); + VectorClear (pod->maxs); + pod->s.modelindex = gi.modelindex ("models/monsters/q1shalrath/v_spike/tris.md2"); +// pod->s.sound = gi.soundindex ("misc/lasfly.wav"); + pod->touch = q1_firepod_touch; + pod->nextthink = level.time +.1; + pod->think = q1_firepod_home; + pod->classname = "firepod"; + pod->enemy = self->enemy; + pod->owner = self; + + pod->common_name = "Firepod"; + + gi.linkentity (pod); + +// if (self->client) +// check_dodge (self, pod->s.origin, dir, speed); + + tr = gi.trace (self->s.origin, NULL, NULL, pod->s.origin, pod, MASK_SHOT); + if (tr.fraction < 1.0) + { + VectorMA (pod->s.origin, -10, dir, pod->s.origin); + pod->touch (pod, tr.ent, NULL, NULL); + } +} + +/* +================= +q1_fire_firepod + +Fires a lavaball. Used by Chthon. +================= +*/ +/*static*/ void q1_lavaball_touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) +{ + vec3_t origin; + + if (other == ent->owner) + return; + + if (surf && (surf->flags & SURF_SKY)) + { + G_FreeEdict (ent); + return; + } + + // calculate position for the explosion entity + VectorMA (ent->s.origin, -0.02, ent->velocity, origin); + + if (other->takedamage) + { + T_Damage (other, ent, ent->owner, ent->velocity, ent->s.origin, plane->normal, ent->dmg,(ent->dmg*2), 0, MOD_Q1_RL); + } + + T_RadiusDamage(ent, ent->owner, ent->radius_dmg, other, ent->dmg_radius, MOD_Q1_RL_SPLASH); + gi.sound (ent, CHAN_WEAPON, gi.soundindex ("q1weap/rocket/r_exp3.wav"), 1.0, ATTN_NORM, 0); + +// + gi.WriteByte (svc_temp_entity); + gi.WriteByte (TE_ROCKET_EXPLOSION); + gi.WritePosition (origin); + gi.multicast (ent->s.origin, MULTICAST_PVS); +// + // explosion sprite + gi.unlinkentity(ent); + ent->solid = SOLID_NOT; + ent->touch = NULL; + VectorCopy(ent->s.origin, origin); + VectorCopy(ent->s.origin, ent->s.old_origin); + VectorClear (ent->velocity); + ent->s.modelindex = gi.modelindex ("sprites/s_explod.sp2"); + ent->s.frame = 0; + ent->s.sound = 0; + ent->s.effects &= ~EF_ANIM_ALLFAST; + ent->think = q1_explode; + ent->nextthink = level.time + FRAMETIME; + ent->enemy = other; + gi.linkentity (ent); +} + + +void q1_fire_lavaball (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, float damage_radius, int radius_damage) +{ + edict_t *lavaball; + + lavaball = G_Spawn(); + VectorCopy (start, lavaball->s.origin); + VectorCopy (dir, lavaball->movedir); + vectoangles (dir, lavaball->s.angles); + VectorScale (dir, speed, lavaball->velocity); + lavaball->movetype = MOVETYPE_FLYMISSILE; + lavaball->clipmask = MASK_SHOT; + lavaball->solid = SOLID_BBOX; + lavaball->s.effects |= EF_ROCKET; //EF_FLAG1 + lavaball->s.renderfx |= RF_GLOW; + + VectorClear (lavaball->mins); + VectorClear (lavaball->maxs); + lavaball->s.modelindex = gi.modelindex ("models/monsters/q1chthon/lavaball/tris.md2"); + lavaball->owner = self; + lavaball->touch = q1_lavaball_touch; + lavaball->nextthink = level.time + 8000/speed; + lavaball->think = G_FreeEdict; + lavaball->dmg = damage; + lavaball->radius_dmg = radius_damage; + lavaball->dmg_radius = damage_radius; + lavaball->s.sound = gi.soundindex ("weapons/rockfly.wav"); + lavaball->classname = "chthon_lavaball"; + + lavaball->common_name = "Chthon Lavaball"; + + gi.linkentity (lavaball); +} + +/* +================= +q1_acidbolt_touch + +Fires a bolt of acid spit. Used by the Scrag. +================= +*/ +/*static*/ void q1_acidbolt_touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) +{ + if (other == ent->owner) + return; + + if (surf && (surf->flags & SURF_SKY)) + { + G_FreeEdict (ent); + return; + } + + if (other->takedamage) + { + // FIX MOD + T_Damage (other, ent, ent->owner, ent->velocity, ent->s.origin, plane->normal, ent->dmg, 0, 0, MOD_Q1_RL); + } + else + { + gi.WriteByte (svc_temp_entity); + gi.WriteByte (TE_WELDING_SPARKS); + gi.WriteByte (15); + gi.WritePosition (ent->s.origin); + gi.WriteDir ((!plane) ? vec3_origin : plane->normal); + // gi.WriteByte (209); + gi.WriteByte (222); + gi.multicast (ent->s.origin, MULTICAST_PVS); + + gi.sound (ent, CHAN_VOICE, gi.soundindex ("q1scrag/hit.wav"), 1, ATTN_NORM, 0); + } + + G_FreeEdict (ent); +} + +/* +void G_Spawn_Trails(int type, vec3_t start, vec3_t endpos, vec3_t origin ) { +gi.WriteByte(svc_temp_entity); +gi.WriteByte(type); +gi.WritePosition(start); +gi.WritePosition(endpos); +gi.multicast(origin, MULTICAST_PVS); +} +*/ + +void q1_fire_acidspit (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed) +{ + edict_t *acidbolt; + + acidbolt = G_Spawn(); + VectorCopy (start, acidbolt->s.origin); + VectorCopy (dir, acidbolt->movedir); + vectoangles (dir, acidbolt->s.angles); + VectorScale (dir, speed, acidbolt->velocity); + acidbolt->movetype = MOVETYPE_FLYMISSILE; + acidbolt->clipmask = MASK_SHOT; + acidbolt->solid = SOLID_BBOX; + acidbolt->s.effects |= EF_GREENGIB; //EF_HYPERBLASTER EF_BFG EF_GREENTRAIL + acidbolt->s.renderfx |= RF_TRANSLUCENT;//FULLBRIGHT; + + VectorClear (acidbolt->mins); + VectorClear (acidbolt->maxs); + acidbolt->s.modelindex = gi.modelindex ("models/monsters/q1scrag/bolt/tris.md2"); + acidbolt->owner = self; + acidbolt->touch = q1_acidbolt_touch; + acidbolt->nextthink = level.time + 8000/speed; + acidbolt->think = G_FreeEdict; + acidbolt->dmg = damage; + //acidbolt->s.sound = gi.soundindex ("weapons/rockfly.wav"); + acidbolt->classname = "acidbolt"; + + acidbolt->common_name = "Acid Bolt"; + + gi.linkentity (acidbolt); +} + +/* +================= +q1_fire_gib + +Fires a gib projectile. Used by the Zombie. +================= +*/ +/*static*/ void q1_zombiegib_touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) +{ + if (other == ent->owner) + return; + + if (surf && (surf->flags & SURF_SKY)) + { + G_FreeEdict (ent); + return; + } + + if (other->takedamage) + { + // FIX MOD + T_Damage (other, ent, ent->owner, ent->velocity, ent->s.origin, plane->normal, ent->dmg, 0, 0, MOD_Q1_RL); + gi.sound (ent, CHAN_RELIABLE|CHAN_WEAPON, gi.soundindex ("q1zombie/z_hit.wav"), 1.0, ATTN_NORM, 0); + } + else + { + gi.sound (ent, CHAN_RELIABLE|CHAN_WEAPON, gi.soundindex ("q1zombie/z_miss.wav"), 1.0, ATTN_NORM, 0); + gi.WriteByte (svc_temp_entity); + gi.WriteByte (TE_BLOOD); + gi.WritePosition (ent->s.origin); + gi.WriteDir (plane->normal); + gi.multicast (ent->s.origin, MULTICAST_PVS); + } + +// no more touches + ent->touch = NULL; + + ent->nextthink = level.time + 3; + ent->think = G_FreeEdict; + //G_FreeEdict (ent); +} + + +void q1_fire_gib (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed) +{ + edict_t *gib; + vec3_t dir; + vec3_t up; //forward, right, + + vectoangles (aimdir, dir); + AngleVectors (dir, NULL, NULL, up); + + gib = G_Spawn(); + VectorCopy (start, gib->s.origin); + VectorScale (aimdir, speed, gib->velocity); + VectorMA (gib->velocity, 200, up, gib->velocity); + //VectorMA (gib->velocity, 20, right, gib->velocity); + + VectorSet (gib->avelocity, 3000, 1000, 2000); + gib->movetype = MOVETYPE_BOUNCE; + gib->clipmask = MASK_SHOT; + gib->solid = SOLID_BBOX; + gib->s.effects |= EF_GIB; + VectorClear (gib->mins); + VectorClear (gib->maxs); + gib->s.modelindex = gi.modelindex ("models/monsters/q1zombie/gib/tris.md2"); + gib->owner = self; + gib->touch = q1_zombiegib_touch; + gib->nextthink = level.time + 2.5; + gib->think = G_FreeEdict; + gib->dmg = damage; + gib->classname = "gib"; + + gib->common_name = "Gib Projectile"; + + gi.linkentity (gib); +} diff --git a/missionpack/m_berserk.c b/missionpack/m_berserk.c index a7b5cf4..0acd2e2 100644 --- a/missionpack/m_berserk.c +++ b/missionpack/m_berserk.c @@ -577,7 +577,7 @@ void SP_monster_berserk (edict_t *self) self->blood_type = 3; //sparks and blood // Lazarus - if(self->powerarmor) + if (self->powerarmor) { if (self->powerarmortype == 1) self->monsterinfo.power_armor_type = POWER_ARMOR_SCREEN; @@ -585,8 +585,10 @@ void SP_monster_berserk (edict_t *self) self->monsterinfo.power_armor_type = POWER_ARMOR_SHIELD; self->monsterinfo.power_armor_power = self->powerarmor; } - if(!self->monsterinfo.flies) + + if (!self->monsterinfo.flies) self->monsterinfo.flies = 0.20; + self->common_name = "Berserker"; gi.linkentity (self); diff --git a/missionpack/m_dog.c b/missionpack/m_dog.c index 2fa2f69..c58335f 100644 --- a/missionpack/m_dog.c +++ b/missionpack/m_dog.c @@ -136,7 +136,7 @@ void dog_pain (edict_t *self, edict_t *other, float kick, int damage) self->s.skinnum |= 1; if (level.time < self->pain_debounce_time) - return; + return; self->pain_debounce_time = level.time + 1; @@ -147,7 +147,7 @@ void dog_pain (edict_t *self, edict_t *other, float kick, int damage) gi.sound (self, CHAN_VOICE, sound_pain, 1, ATTN_NORM, 0); //WAS ATTN_IDLE - if(random() < 0.5) + if (random() < 0.5) self->monsterinfo.currentmove = &dog_move_pain1; else self->monsterinfo.currentmove = &dog_move_pain2; @@ -459,7 +459,7 @@ void SP_monster_dog (edict_t *self) // Lazarus: special purpose skins if ( self->style ) { - PatchMonsterModel("models/monsters/dog/tris.md2"); + PatchMonsterModel("models/monsters/dog/dog.md2"); self->s.skinnum = self->style * 2; } @@ -492,7 +492,7 @@ void SP_monster_dog (edict_t *self) self->monsterinfo.flies = 0.60; // Lazarus - if(self->powerarmor) + if (self->powerarmor) { if (self->powerarmortype == 1) self->monsterinfo.power_armor_type = POWER_ARMOR_SCREEN; @@ -509,4 +509,3 @@ void SP_monster_dog (edict_t *self) self->monsterinfo.scale = MODEL_SCALE; walkmonster_start (self); } - diff --git a/missionpack/m_flipper.c b/missionpack/m_flipper.c index db0477c..22997dd 100644 --- a/missionpack/m_flipper.c +++ b/missionpack/m_flipper.c @@ -415,11 +415,11 @@ void SP_monster_flipper (edict_t *self) self->monsterinfo.sight = flipper_sight; self->monsterinfo.search = flipper_search; //Knightmare added - if(!self->monsterinfo.flies) + if (!self->monsterinfo.flies) self->monsterinfo.flies = 0.90; // Lazarus - if(self->powerarmor) + if (self->powerarmor) { if (self->powerarmortype == 1) self->monsterinfo.power_armor_type = POWER_ARMOR_SCREEN; diff --git a/missionpack/m_gunner.c b/missionpack/m_gunner.c index f8a7470..8d12f2a 100644 --- a/missionpack/m_gunner.c +++ b/missionpack/m_gunner.c @@ -1109,11 +1109,11 @@ void SP_monster_gunner (edict_t *self) VectorSet (self->mins, -16, -16, -24); VectorSet (self->maxs, 16, 16, 32); - if(!self->health) + if (!self->health) self->health = 175; - if(!self->gib_health) + if (!self->gib_health) self->gib_health = -150; - if(!self->mass) + if (!self->mass) self->mass = 200; self->pain = gunner_pain; @@ -1139,7 +1139,7 @@ void SP_monster_gunner (edict_t *self) self->blood_type = 3; //sparks and blood // Lazarus - if(self->powerarmor) + if (self->powerarmor) { if (self->powerarmortype == 1) self->monsterinfo.power_armor_type = POWER_ARMOR_SCREEN; @@ -1147,8 +1147,9 @@ void SP_monster_gunner (edict_t *self) self->monsterinfo.power_armor_type = POWER_ARMOR_SHIELD; self->monsterinfo.power_armor_power = self->powerarmor; } - if(!self->monsterinfo.flies) + if (!self->monsterinfo.flies) self->monsterinfo.flies = 0.30; + self->common_name = "Gunner"; gi.linkentity (self); diff --git a/missionpack/m_infantry.c b/missionpack/m_infantry.c index 7326cd7..b5058a1 100644 --- a/missionpack/m_infantry.c +++ b/missionpack/m_infantry.c @@ -865,7 +865,7 @@ void SP_monster_infantry (edict_t *self) self->monsterinfo.power_armor_power = self->powerarmor; } - if(!self->monsterinfo.flies) + if (!self->monsterinfo.flies) self->monsterinfo.flies = 0.40; self->common_name = "Enforcer"; diff --git a/missionpack/m_q1dog.c b/missionpack/m_q1dog.c new file mode 100644 index 0000000..b2b7aa0 --- /dev/null +++ b/missionpack/m_q1dog.c @@ -0,0 +1,502 @@ +/* +============================================================================== + +QUAKE DOG + +============================================================================== +*/ + +#include "g_local.h" +#include "m_q1dog.h" + + +static int sound_pain; +static int sound_death; +static int sound_attack; +static int sound_sight; +static int sound_idle; + + +void q1dog_idle (edict_t *self) +{ + if(random() < 0.2) + gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0); +} + +void q1dog_sight (edict_t *self, edict_t *other) +{ + gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0); +} + +//STAND + +mframe_t q1dog_frames_stand [] = +{ + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL +}; +mmove_t q1dog_move_stand = {FRAME_stand1, FRAME_stand9, q1dog_frames_stand, NULL}; + +void q1dog_stand (edict_t *self) +{ + self->monsterinfo.currentmove = &q1dog_move_stand; +} + +// WALK + +mframe_t q1dog_frames_walk [] = +{ + ai_walk, 7, q1dog_idle, + ai_walk, 7, NULL, + ai_walk, 7, NULL, + ai_walk, 7, NULL, + ai_walk, 7, NULL, + ai_walk, 7, NULL, + ai_walk, 7, NULL, + ai_walk, 7, NULL +}; +mmove_t q1dog_move_walk = {FRAME_walk1, FRAME_walk8, q1dog_frames_walk, NULL}; + +void q1dog_walk (edict_t *self) +{ + self->monsterinfo.currentmove = &q1dog_move_walk; +} + +// RUN + +mframe_t q1dog_frames_run [] = +{ + ai_run, 12, q1dog_idle, + ai_run, 20, NULL, + ai_run, 20, NULL, + ai_run, 16, NULL, + ai_run, 22, NULL, + ai_run, 20, NULL, + ai_run, 12, NULL, + ai_run, 20, NULL, + ai_run, 20, NULL, + ai_run, 16, NULL, + ai_run, 22, NULL, + ai_run, 20, NULL +}; +mmove_t q1dog_move_run = {FRAME_run1, FRAME_run12, q1dog_frames_run, NULL}; + +void q1dog_run (edict_t *self) +{ + if (self->monsterinfo.aiflags & AI_STAND_GROUND) + self->monsterinfo.currentmove = &q1dog_move_walk; + else + self->monsterinfo.currentmove = &q1dog_move_run; +} + +// PAIN + +mframe_t q1dog_frames_pain1 [] = +{ + 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 q1dog_move_pain1 = {FRAME_pain1, FRAME_pain6, q1dog_frames_pain1, q1dog_run}; + +mframe_t q1dog_frames_pain2 [] = +{ + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, -4, NULL, + ai_move, -12,NULL, + ai_move, -12,NULL, + ai_move, -2, NULL, + ai_move, 0, NULL, + ai_move, -4, NULL, + ai_move, 0, NULL, + ai_move, -10, 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 q1dog_move_pain2 = {FRAME_painb1, FRAME_painb16, q1dog_frames_pain2, q1dog_run}; + +void q1dog_pain (edict_t *self, edict_t *other, float kick, int damage) +{ + if (level.time < self->pain_debounce_time) + return; + + self->pain_debounce_time = level.time + 1; + + if (skill->value == 3) + return; + + if (self->health > 0) + gi.sound (self, CHAN_VOICE, sound_pain, 1, ATTN_NORM, 0); //WAS ATTN_IDLE + + + if(random() < 0.5) + self->monsterinfo.currentmove = &q1dog_move_pain1; + else + self->monsterinfo.currentmove = &q1dog_move_pain2; +} + +// MELEE + +void q1dog_bite (edict_t *self) +{ + vec3_t aim; + + VectorSet (aim, MELEE_DISTANCE, self->maxs[0], 8); + if (fire_hit (self, aim, (random() + random() + random())*8, 100)) + gi.sound (self, CHAN_WEAPON, sound_attack, 1, ATTN_NORM, 0); +} + + +void q1dog_checkrefire (edict_t *self) +{ + if (!self->enemy || !self->enemy->inuse || self->enemy->health <= 0) + return; + + if ( ((skill->value == 2) && (random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE) ) + self->monsterinfo.nextframe = FRAME_attack1; +} + + +mframe_t q1dog_frames_attack []= +{ + ai_charge, 10, NULL, + ai_charge, 10, NULL, + ai_charge, 10, NULL, + ai_charge, 10, q1dog_bite, + ai_charge, 10, NULL, + ai_charge, 10, NULL, + ai_charge, 10, NULL, + ai_charge, 10, q1dog_checkrefire +}; +mmove_t q1dog_move_attack = {FRAME_attack1, FRAME_attack8, q1dog_frames_attack, q1dog_run}; + +void q1dog_melee (edict_t *self) +{ + self->monsterinfo.currentmove = &q1dog_move_attack; +} + + +// LEAP + +void q1dog_jump_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) +{ + if (self->health <= 0) + { + self->touch = NULL; + return; + } + + if (other->takedamage) + { + if (VectorLength(self->velocity) > 300) + { + vec3_t point, normal; + int damage; + + VectorCopy (self->velocity, normal); + VectorNormalize(normal); + VectorMA (self->s.origin, self->maxs[0], normal, point); + damage = 10 + 10 * random(); + T_Damage (other, self, self, self->velocity, point, normal, damage, damage, 0, MOD_UNKNOWN); + } + } + + if (!M_CheckBottom (self)) + { + if (self->groundentity) + { + self->monsterinfo.nextframe = FRAME_attack1; + self->touch = NULL; + } + return; + } + + self->touch = NULL; +} + + +void q1dog_takeoff (edict_t *self) +{ + vec3_t forward; + + gi.sound (self, CHAN_VOICE, sound_attack, 1, ATTN_NORM, 0); + AngleVectors (self->s.angles, forward, NULL, NULL); + self->s.origin[2] += 1; + VectorScale (forward, 350, self->velocity); + self->velocity[2] = 220; + self->groundentity = NULL; + self->monsterinfo.attack_finished = level.time + 2; + self->touch = q1dog_jump_touch; +} + +void q1dog_checklanding (edict_t *self) +{ + if (self->groundentity) + { + self->monsterinfo.attack_finished = 0; + return; + } + + if (level.time > self->monsterinfo.attack_finished) + self->monsterinfo.nextframe = FRAME_attack1; +} + + +mframe_t q1dog_frames_leap [] = +{ + ai_charge, 0, NULL, + ai_charge, 0, q1dog_takeoff, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, q1dog_checklanding +}; +mmove_t q1dog_move_leap = {FRAME_leap1, FRAME_leap9, q1dog_frames_leap, q1dog_run}; + +void q1dog_leap (edict_t *self) +{ + self->monsterinfo.currentmove = &q1dog_move_leap; +} + +// +// CHECKATTACK +// + +static qboolean q1dog_check_melee (edict_t *self) +{ + if (range (self, self->enemy) == RANGE_MELEE) + return true; + return false; +} + +static qboolean q1dog_check_jump (edict_t *self) +{ + vec3_t v; + float distance; + + if (self->absmin[2] > (self->enemy->absmin[2] + 0.75 * self->enemy->size[2])) + return false; + + if (self->absmax[2] < (self->enemy->absmin[2] + 0.25 * self->enemy->size[2])) + return false; + + v[0] = self->s.origin[0] - self->enemy->s.origin[0]; + v[1] = self->s.origin[1] - self->enemy->s.origin[1]; + v[2] = 0; + distance = VectorLength(v); + + if (distance < 80) + return false; + if (distance > 80) + { + vec3_t offset,end,dir; + vec3_t forward,right; + int cont; + VectorSet(offset, 80, 0, -2); + AngleVectors (self->s.angles, forward, right, NULL); + G_ProjectSource (self->s.origin, offset, forward, right, dir); + VectorMA (self->s.origin, 100 , dir, end); + cont = gi.pointcontents (end); + if (!(cont & MASK_SOLID)) + { + // gi.dprintf("DOG TARGET LANDING IS NOT SOLID\n"); + return false; + } + + if (random() < 0.7) + return false; + } + return true; +} + +qboolean q1dog_checkattack (edict_t *self) +{ + if (!self->enemy || self->enemy->health <= 0) + return false; + + if (q1dog_check_melee(self)) + { + self->monsterinfo.attack_state = AS_MELEE; + return true; + } + + if (q1dog_check_jump(self)) + { + self->monsterinfo.attack_state = AS_MISSILE; + return true; + } + return false; +} + + +// DEAD + +void q1dog_dead (edict_t *self) +{ + VectorSet (self->mins, -16, -16, -24); + VectorSet (self->maxs, 16, 16, -8); + self->movetype = MOVETYPE_TOSS; + self->svflags |= SVF_DEADMONSTER; + gi.linkentity (self); +} + +void q1dog_nogib (edict_t *self) +{ + self->gib_health = -10000; +} + +mframe_t q1dog_frames_death1 [] = +{ + ai_move, 0, NULL, + ai_move, 0, q1dog_nogib, + 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 q1dog_move_death1 = {FRAME_death1, FRAME_death9, q1dog_frames_death1, q1dog_dead}; + +mframe_t q1dog_frames_death2 [] = +{ + ai_move, 0, NULL, + ai_move, 0, q1dog_nogib, + 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 q1dog_move_death2 = {FRAME_deathb1, FRAME_deathb9, q1dog_frames_death2, q1dog_dead}; + +void q1dog_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) +{ + int n; + + if (self->health <= self->gib_health && !(self->spawnflags & SF_MONSTER_NOGIB)) + { + gi.sound (self, CHAN_VOICE|CHAN_RELIABLE, gi.soundindex ("q1monstr/udeath.wav"), 1, ATTN_NORM, 0); + + ThrowGib (self, "models/objects/q1gibs/q1gib1/tris.md2", damage, GIB_ORGANIC); + for (n= 0; n < 2; n++) + ThrowGib (self, "models/objects/q1gibs/q1gib3/tris.md2", damage, GIB_ORGANIC); + ThrowHead (self, "models/monsters/q1dog/head/tris.md2", damage, GIB_ORGANIC); + + self->deadflag = DEAD_DEAD; + return; + } + + if (self->deadflag == DEAD_DEAD) + return; + + gi.sound (self, CHAN_VOICE, sound_death, 1, ATTN_NORM, 0); + self->deadflag = DEAD_DEAD; + self->takedamage = DAMAGE_YES; + + if(random() < 0.5) + self->monsterinfo.currentmove = &q1dog_move_death1; + else + self->monsterinfo.currentmove = &q1dog_move_death2; +} + + +// +// SPAWN +// + +/*QUAKED monster_q1_dog (1 .5 0) (-32 -32 -24) (32 32 32) Ambush Trigger_Spawn Sight +model="models/monsters/q1dog/tris.md2" +*/ +void SP_monster_q1_dog (edict_t *self) +{ + if (deathmatch->value) + { + G_FreeEdict (self); + return; + } + sound_pain = gi.soundindex ("q1dog/dpain1.wav"); + sound_death = gi.soundindex ("q1dog/ddeath.wav"); + sound_attack = gi.soundindex ("q1dog/dattack1.wav"); + sound_sight = gi.soundindex ("q1dog/dsight.wav"); + sound_idle = gi.soundindex ("q1dog/idle.wav"); + + self->movetype = MOVETYPE_STEP; + self->solid = SOLID_BBOX; + + // Lazarus: special purpose skins + if ( self->style ) + { + PatchMonsterModel("models/monsters/q1dog/tris.md2"); + self->s.skinnum = self->style * 2; + } + + self->s.modelindex = gi.modelindex ("models/monsters/q1dog/tris.md2"); + VectorSet (self->mins, -32, -32, -24); + VectorSet (self->maxs, 32, 32, 32); + + if (!self->health) + self->health = 30; + if (!self->gib_health) + self->gib_health = -35; + if (!self->mass) + self->mass = 80; + + self->pain = q1dog_pain; + self->die = q1dog_die; + + self->flags |= FL_Q1_MONSTER; + + self->monsterinfo.stand = q1dog_stand; + self->monsterinfo.walk = q1dog_walk; + self->monsterinfo.run = q1dog_run; + self->monsterinfo.dodge = NULL; + self->monsterinfo.attack = q1dog_leap; + self->monsterinfo.melee = q1dog_melee; + self->monsterinfo.sight = q1dog_sight; + self->monsterinfo.search = q1dog_stand; + self->monsterinfo.idle = q1dog_stand; + self->monsterinfo.checkattack = q1dog_checkattack; + + if (!self->monsterinfo.flies) + self->monsterinfo.flies = 0.60; + + // Lazarus + if (self->powerarmor) + { + if (self->powerarmortype == 1) + self->monsterinfo.power_armor_type = POWER_ARMOR_SCREEN; + else + self->monsterinfo.power_armor_type = POWER_ARMOR_SHIELD; + self->monsterinfo.power_armor_power = self->powerarmor; + } + self->common_name = "Rottweiler"; + + gi.linkentity (self); + + self->monsterinfo.currentmove = &q1dog_move_stand; + + self->monsterinfo.scale = MODEL_SCALE; + walkmonster_start (self); +} diff --git a/missionpack/m_q1dog.h b/missionpack/m_q1dog.h new file mode 100644 index 0000000..09efa85 --- /dev/null +++ b/missionpack/m_q1dog.h @@ -0,0 +1,91 @@ +// Generated by ModelEd +// DOG + +#define FRAME_attack1 0 +#define FRAME_attack2 1 +#define FRAME_attack3 2 +#define FRAME_attack4 3 +#define FRAME_attack5 4 +#define FRAME_attack6 5 +#define FRAME_attack7 6 +#define FRAME_attack8 7 +#define FRAME_death1 8 +#define FRAME_death2 9 +#define FRAME_death3 10 +#define FRAME_death4 11 +#define FRAME_death5 12 +#define FRAME_death6 13 +#define FRAME_death7 14 +#define FRAME_death8 15 +#define FRAME_death9 16 +#define FRAME_deathb1 17 +#define FRAME_deathb2 18 +#define FRAME_deathb3 19 +#define FRAME_deathb4 20 +#define FRAME_deathb5 21 +#define FRAME_deathb6 22 +#define FRAME_deathb7 23 +#define FRAME_deathb8 24 +#define FRAME_deathb9 25 +#define FRAME_pain1 26 +#define FRAME_pain2 27 +#define FRAME_pain3 28 +#define FRAME_pain4 29 +#define FRAME_pain5 30 +#define FRAME_pain6 31 +#define FRAME_painb1 32 +#define FRAME_painb2 33 +#define FRAME_painb3 34 +#define FRAME_painb4 35 +#define FRAME_painb5 36 +#define FRAME_painb6 37 +#define FRAME_painb7 38 +#define FRAME_painb8 39 +#define FRAME_painb9 40 +#define FRAME_painb10 41 +#define FRAME_painb11 42 +#define FRAME_painb12 43 +#define FRAME_painb13 44 +#define FRAME_painb14 45 +#define FRAME_painb15 46 +#define FRAME_painb16 47 +#define FRAME_run1 48 +#define FRAME_run2 49 +#define FRAME_run3 50 +#define FRAME_run4 51 +#define FRAME_run5 52 +#define FRAME_run6 53 +#define FRAME_run7 54 +#define FRAME_run8 55 +#define FRAME_run9 56 +#define FRAME_run10 57 +#define FRAME_run11 58 +#define FRAME_run12 59 +#define FRAME_leap1 60 +#define FRAME_leap2 61 +#define FRAME_leap3 62 +#define FRAME_leap4 63 +#define FRAME_leap5 64 +#define FRAME_leap6 65 +#define FRAME_leap7 66 +#define FRAME_leap8 67 +#define FRAME_leap9 68 +#define FRAME_stand1 69 +#define FRAME_stand2 70 +#define FRAME_stand3 71 +#define FRAME_stand4 72 +#define FRAME_stand5 73 +#define FRAME_stand6 74 +#define FRAME_stand7 75 +#define FRAME_stand8 76 +#define FRAME_stand9 77 +#define FRAME_walk1 78 +#define FRAME_walk2 79 +#define FRAME_walk3 80 +#define FRAME_walk4 81 +#define FRAME_walk5 82 +#define FRAME_walk6 83 +#define FRAME_walk7 84 +#define FRAME_walk8 85 + +#define MODEL_SCALE 1.000000 diff --git a/missionpack/m_q1enforcer.c b/missionpack/m_q1enforcer.c new file mode 100644 index 0000000..4b0db62 --- /dev/null +++ b/missionpack/m_q1enforcer.c @@ -0,0 +1,413 @@ +/* +============================================================================== + +QUAKE ENFORCER + +============================================================================== +*/ + +#include "g_local.h" +#include "m_q1enforcer.h" + +static int sound_pain1; +static int sound_pain2; +static int sound_death; +static int sound_idle; +static int sound_sight1; +static int sound_sight2; +static int sound_sight3; +static int sound_sight4; +static int sound_fire; + + +void q1enforcer_fire (edict_t *self); +void q1enforcer_stand (edict_t *self); + +/*int q1enforcer_rndidle () +{ + char str[256]; + + Com_sprintf (str, sizeof(str), "q1enforcer/sight%i.wav", rand()%3+1); + + return gi.soundindex(str); +}*/ + +void q1enforcer_idlesound (edict_t *self) +{ + gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0); +} + +void q1enforcer_sight (edict_t *self, edict_t *other) +{ + float r = random(); + + if (r < 0.25) + gi.sound (self, CHAN_VOICE, sound_sight1, 1, ATTN_NORM, 0); + else if (r < 0.5) + gi.sound (self, CHAN_VOICE, sound_sight2, 1, ATTN_NORM, 0); + else if (r < 0.75) + gi.sound (self, CHAN_VOICE, sound_sight3, 1, ATTN_NORM, 0); + else + gi.sound (self, CHAN_VOICE, sound_sight4, 1, ATTN_NORM, 0); +} + +void q1enforcer_search (edict_t *self) +{ + gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0); +// gi.sound (self, CHAN_VOICE, q1enforcer_rndidle(), 1, ATTN_IDLE, 0); +} + +mframe_t q1enforcer_frames_stand [] = +{ + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL +}; +mmove_t q1enforcer_move_stand = {FRAME_stand1, FRAME_stand7, q1enforcer_frames_stand, NULL}; + +void q1enforcer_stand (edict_t *self) +{ + self->monsterinfo.currentmove = &q1enforcer_move_stand; +} + +mframe_t q1enforcer_frames_walk [] = +{ + ai_walk, 3, NULL, + ai_walk, 4, NULL, + ai_walk, 4, NULL, + ai_walk, 5, NULL, + ai_walk, 4, NULL, + ai_walk, 3, NULL, + ai_walk, 2, NULL, + ai_walk, 0, NULL, + ai_walk, 0, NULL, + ai_walk, 2, NULL, + ai_walk, 3, NULL, + ai_walk, 4, NULL, + ai_walk, 5, NULL, + ai_walk, 5, NULL, + ai_walk, 4, NULL, + ai_walk, 3, NULL +}; +mmove_t q1enforcer_move_walk = {FRAME_walk1, FRAME_walk16, q1enforcer_frames_walk, NULL}; + +void q1enforcer_walk (edict_t *self) +{ + self->monsterinfo.currentmove = &q1enforcer_move_walk; +} + +mframe_t q1enforcer_frames_run [] = +{ + ai_run, 22, NULL, + ai_run, 8, NULL, + ai_run, 7, NULL, + ai_run, 8, NULL, + ai_run, 13, NULL, + ai_run, 12, NULL, + ai_run, 11, NULL, + ai_run, 7, NULL +}; + +mmove_t q1enforcer_move_run = {FRAME_run1, FRAME_run8, q1enforcer_frames_run, NULL}; + +void q1enforcer_run (edict_t *self) +{ + if (self->monsterinfo.aiflags & AI_STAND_GROUND) + self->monsterinfo.currentmove = &q1enforcer_move_stand; + else + self->monsterinfo.currentmove = &q1enforcer_move_run; +} + +mframe_t q1enforcer_frames_pain3 [] = +{ + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL +}; +mmove_t q1enforcer_move_pain3 = {FRAME_paina1, FRAME_paina4, q1enforcer_frames_pain3, q1enforcer_run}; + +mframe_t q1enforcer_frames_pain2 [] = +{ + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL +}; +mmove_t q1enforcer_move_pain2 = {FRAME_painb1, FRAME_painb5, q1enforcer_frames_pain2, q1enforcer_run}; + +mframe_t q1enforcer_frames_pain1 [] = +{ + 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 q1enforcer_move_pain1 = {FRAME_painc1, FRAME_painc8, q1enforcer_frames_pain1, q1enforcer_run}; + +void q1enforcer_pain (edict_t *self, edict_t *other, float kick, int damage) +{ + if (self->health < (self->max_health / 2)) + self->s.skinnum = 1; + + if (level.time < self->pain_debounce_time) + return; + + self->pain_debounce_time = level.time + 3; + + if (rand()&1) + gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0); + else + gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0); + + if (skill->value == 3) + return; // no pain anims in nightmare + + if (damage <= 10) + self->monsterinfo.currentmove = &q1enforcer_move_pain3; + else if (damage <= 25) + self->monsterinfo.currentmove = &q1enforcer_move_pain2; + else + self->monsterinfo.currentmove = &q1enforcer_move_pain1; +} + +void q1enforcer_dead (edict_t *self) +{ + VectorSet (self->mins, -16, -16, -24); + VectorSet (self->maxs, 16, 16, -8); + self->movetype = MOVETYPE_TOSS; + self->svflags |= SVF_DEADMONSTER; + self->nextthink = 0; + gi.linkentity (self); +} + +void q1enforcer_throw_backpack (edict_t *self) +{ +/* edict_t *backpack; + + backpack = Drop_Item(self, FindItemByClassname("item_q1_backpack")); + backpack->item = FindItemByClassname("ammo_cells"); + backpack->count = 5; + backpack->touch = Touch_Item; + backpack->nextthink = level.time + 1800; + backpack->think = G_FreeEdict; +*/ + self->gib_health = -10000; +} + +mframe_t q1enforcer_frames_death1 [] = +{ + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, q1enforcer_throw_backpack, + 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 q1enforcer_move_death1 = {FRAME_death1, FRAME_death14, q1enforcer_frames_death1, q1enforcer_dead}; + +mframe_t q1enforcer_frames_death2 [] = +{ + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, q1enforcer_throw_backpack, + 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 q1enforcer_move_death2 = {FRAME_fdeath1, FRAME_fdeath11, q1enforcer_frames_death2, q1enforcer_dead}; + + +void q1enforcer_whichway (edict_t *self); + +void q1enforcer_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) +{ + int n; + +// check for gib + if (self->health <= self->gib_health && !(self->spawnflags & SF_MONSTER_NOGIB)) + { + gi.sound (self, CHAN_VOICE|CHAN_RELIABLE, gi.soundindex ("q1monstr/udeath.wav"), 1, ATTN_NORM, 0); + + for (n= 0; n < 2; n++) + ThrowGib (self, "models/objects/q1gibs/q1gib1/tris.md2", damage, GIB_ORGANIC); + ThrowGib (self, "models/objects/q1gibs/q1gib2/tris.md2", damage, GIB_ORGANIC); + ThrowHead (self, "models/monsters/q1enforcer/head/tris.md2", damage, GIB_ORGANIC); + self->deadflag = DEAD_DEAD; + return; + } + + if (self->deadflag == DEAD_DEAD) + return; + +// regular death + gi.sound (self, CHAN_VOICE, sound_death, 1, ATTN_NORM, 0); + self->deadflag = DEAD_DEAD; + self->takedamage = DAMAGE_YES; + + if (random() < 0.5) + self->monsterinfo.currentmove = &q1enforcer_move_death1; + else + self->monsterinfo.currentmove = &q1enforcer_move_death2; +} + +void q1enforcer_fire (edict_t *self) +{ + vec3_t forward, right; + vec3_t start, target, aim; + + AngleVectors (self->s.angles, forward, right, NULL); + G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_SOLDIER_BLASTER_1], forward, right, start); + + // project enemy back a bit and target there + VectorCopy (self->enemy->s.origin, target); + VectorMA (target, -0.2, self->enemy->velocity, target); + target[2] += self->enemy->viewheight; + + VectorSubtract (target, start, aim); + VectorNormalize (aim); + + gi.sound (self, CHAN_WEAPON|CHAN_RELIABLE, sound_fire, 1, ATTN_NORM, 0); + q1_fire_laser (self, start, aim, 15, 600); +} + +void q1enforcer_secondfire (edict_t *self) +{ + if (!self->radius_dmg) + { + self->monsterinfo.nextframe = 36; + self->radius_dmg = 1; + } + else + self->radius_dmg = 0; +} + +mframe_t q1enforcer_frames_start_chain [] = +{ + ai_charge, 0, NULL, + ai_charge, 1, NULL, + ai_charge, 1, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, q1enforcer_fire, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, q1enforcer_secondfire, + ai_charge, 0, NULL +}; +mmove_t q1enforcer_move_start_fire = {FRAME_attack1, FRAME_attack10, q1enforcer_frames_start_chain, q1enforcer_run}; + +void q1enforcer_attack (edict_t *self) +{ + self->monsterinfo.currentmove = &q1enforcer_move_start_fire; +} + + +// +// SPAWN +// + +/*QUAKED SP_monster_q1_enforcer (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight +model="models/monsters/q1enforcer/tris.md2" +*/ +void SP_monster_q1_enforcer (edict_t *self) +{ + if (deathmatch->value) + { + G_FreeEdict (self); + return; + } + + sound_pain1 = gi.soundindex ("q1enforcer/pain1.wav"); + sound_pain2 = gi.soundindex ("q1enforcer/pain2.wav"); + sound_death = gi.soundindex ("q1enforcer/death1.wav"); + sound_idle = gi.soundindex ("q1enforcer/idle1.wav"); + sound_sight1 = gi.soundindex ("q1enforcer/sight1.wav"); + sound_sight2 = gi.soundindex ("q1enforcer/sight2.wav"); + sound_sight3 = gi.soundindex ("q1enforcer/sight3.wav"); + sound_sight4 = gi.soundindex ("q1enforcer/sight4.wav"); + sound_fire = gi.soundindex ("q1enforcer/enfire.wav"); + + self->movetype = MOVETYPE_STEP; + self->solid = SOLID_BBOX; + + // Lazarus: special purpose skins + if ( self->style ) + { + PatchMonsterModel("models/monsters/q1enforcer/tris.md2"); + self->s.skinnum = self->style * 2; + } + + self->s.modelindex = gi.modelindex ("models/monsters/q1enforcer/tris.md2"); + VectorSet (self->mins, -16, -16, -24); + VectorSet (self->maxs, 16, 16, 40); + + if (!self->health) + self->health = 80; + if (!self->gib_health) + self->gib_health = -35; + if (!self->mass) + self->mass = 175; + + self->flags |= FL_Q1_MONSTER; + + self->pain = q1enforcer_pain; + self->die = q1enforcer_die; + + + self->monsterinfo.stand = q1enforcer_stand; + self->monsterinfo.walk = q1enforcer_walk; + self->monsterinfo.run = q1enforcer_run; + self->monsterinfo.dodge = NULL; + self->monsterinfo.attack = q1enforcer_attack; + self->monsterinfo.melee = NULL; + self->monsterinfo.sight = q1enforcer_sight; + self->monsterinfo.search = q1enforcer_search; + + if (!self->monsterinfo.flies) + self->monsterinfo.flies = 0.10; + + // Lazarus + if (self->powerarmor) + { + if (self->powerarmortype == 1) + self->monsterinfo.power_armor_type = POWER_ARMOR_SCREEN; + else + self->monsterinfo.power_armor_type = POWER_ARMOR_SHIELD; + self->monsterinfo.power_armor_power = self->powerarmor; + } + self->common_name = "Enforcer"; + + gi.linkentity (self); + + gi.linkentity (self); + + self->monsterinfo.currentmove = &q1enforcer_move_stand; + self->monsterinfo.scale = 1.000000; + + self->radius_dmg = 0; + + walkmonster_start (self); +} diff --git a/missionpack/m_q1enforcer.h b/missionpack/m_q1enforcer.h new file mode 100644 index 0000000..de21cf7 Binary files /dev/null and b/missionpack/m_q1enforcer.h differ diff --git a/missionpack/m_q1fiend.c b/missionpack/m_q1fiend.c new file mode 100644 index 0000000..0ac4b21 --- /dev/null +++ b/missionpack/m_q1fiend.c @@ -0,0 +1,520 @@ +/* +============================================================================== + +QUAKE FIEND + +============================================================================== +*/ + +#include "g_local.h" +#include "m_q1fiend.h" + + +static int sound_hit; +static int sound_jump; +static int sound_death; +static int sound_idle; +static int sound_pain; +static int sound_sight; +static int sound_land; + + + +// +// SOUNDS +// + + +void fiend_sight (edict_t *self, edict_t *other) +{ + gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0); //was ATTN_IDLE +} + +void fiend_idle_sound (edict_t *self) +{ + if (random() < 0.2) + gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_STATIC, 0); +} + +void fiend_idle_sound2 (edict_t *self) +{ + if (random() < 0.2) + gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_NORM, 0); //was ATTN_STATIC +} + + +// +// STAND +// + +//void fiend_stand (edict_t *self); + +mframe_t fiend_frames_stand [] = +{ + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, fiend_idle_sound, + + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL + +}; +mmove_t fiend_move_stand = {FRAME_stand1, FRAME_stand13, fiend_frames_stand, NULL}; //stand + +void fiend_stand (edict_t *self) +{ + self->monsterinfo.currentmove = &fiend_move_stand; +} + + +// +// WALK +// + +//void fiend_walk (edict_t *self); + +mframe_t fiend_frames_walk [] = +{ + ai_walk, 8, fiend_idle_sound2, + ai_walk, 6, NULL, + ai_walk, 6, NULL, + ai_walk, 7, NULL, + ai_walk, 4, NULL, + ai_walk, 6, NULL, + ai_walk, 10, NULL, + ai_walk, 10, NULL +}; +mmove_t fiend_move_walk = {FRAME_walk1, FRAME_walk8, fiend_frames_walk, NULL}; //walk + +void fiend_walk (edict_t *self) +{ + self->monsterinfo.currentmove = &fiend_move_walk; +} + + +// +// RUN +// + +mframe_t fiend_frames_run [] = +{ + ai_run, 20, fiend_idle_sound2, + ai_run, 15, NULL, + ai_run, 36, NULL, + ai_run, 20, NULL, + ai_run, 15, NULL, + ai_run, 36, NULL +}; +mmove_t fiend_move_run = {FRAME_run1, FRAME_run6, fiend_frames_run, NULL}; + +void fiend_run (edict_t *self) +{ + if (self->monsterinfo.aiflags & AI_STAND_GROUND) + self->monsterinfo.currentmove = &fiend_move_stand; + else + self->monsterinfo.currentmove = &fiend_move_run; +} + + + +// +// MELEE +// + +/*static*/ void fiend_hit_left (edict_t *self) +{ + vec3_t aim; + + VectorSet (aim, MELEE_DISTANCE, self->mins[0], 8); + if (fire_hit (self, aim, (10 + (rand() %5)), 100)) + gi.sound (self, CHAN_WEAPON, sound_hit, 1, ATTN_NORM, 0); +} + +/*static*/ void fiend_hit_right (edict_t *self) +{ + vec3_t aim; + + VectorSet (aim, MELEE_DISTANCE, self->maxs[0], 8); + if (fire_hit (self, aim, (10 + (rand() %5)), 100)) + gi.sound (self, CHAN_WEAPON, sound_hit, 1, ATTN_NORM, 0); +} + + +/*static*/ void fiend_check_refire (edict_t *self) +{ + if (!self->enemy || !self->enemy->inuse || self->enemy->health <= 0) + return; + + if ( ((skill->value == 3) && (random() < 0.5)) || (range(self, self->enemy) == RANGE_MELEE) ) + self->monsterinfo.nextframe = FRAME_attacka1; +} + +mframe_t fiend_frames_attack [] = +{ + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, fiend_hit_left, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, fiend_hit_right, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, fiend_check_refire +}; +mmove_t fiend_move_attack = {FRAME_attacka1, FRAME_attacka15, fiend_frames_attack, fiend_run}; + + +void fiend_melee (edict_t *self) +{ + self->monsterinfo.currentmove = &fiend_move_attack; +} + + +// +// ATTACK +// + +void fiend_jump_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) +{ + if (self->health <= 0) + { + self->touch = NULL; + return; + } + + if (other->takedamage) + { + if (VectorLength(self->velocity) > 400) + { + vec3_t point; + vec3_t normal; + int damage; + + VectorCopy (self->velocity, normal); + VectorNormalize(normal); + VectorMA (self->s.origin, self->maxs[0], normal, point); + damage = 40 + 10 * random(); + T_Damage (other, self, self, self->velocity, point, normal, damage, damage, 0, MOD_UNKNOWN); + } + } + + if (!M_CheckBottom (self)) + { + if (self->groundentity) + { + self->monsterinfo.nextframe = FRAME_attacka1; + self->touch = NULL; + } + return; + } + + self->touch = NULL; +} + +void fiend_jump_takeoff (edict_t *self) +{ + vec3_t forward; + + gi.sound (self, CHAN_VOICE, sound_jump, 1, ATTN_NORM, 0); + AngleVectors (self->s.angles, forward, NULL, NULL); + self->s.origin[2] += 1; + VectorScale (forward, 600, self->velocity); + self->velocity[2] = 250; + self->groundentity = NULL; + self->monsterinfo.aiflags |= AI_DUCKED; + self->monsterinfo.attack_finished = level.time + 3; + self->touch = fiend_jump_touch; +} + +void fiend_check_landing (edict_t *self) +{ + if (self->groundentity) + { + self->monsterinfo.attack_finished = 0; + self->monsterinfo.aiflags &= ~AI_DUCKED; + return; + } + + if (level.time > self->monsterinfo.attack_finished) + self->monsterinfo.nextframe = FRAME_attacka1; + else + self->monsterinfo.nextframe = FRAME_attacka8; +} + +mframe_t fiend_frames_jump [] = +{ + ai_charge, 5, NULL, + ai_charge, 5, NULL, + ai_charge, 5, fiend_jump_takeoff, + ai_charge, 10, NULL, + ai_charge, 10, NULL, + ai_charge, 15, NULL, + ai_charge, 15, NULL, + ai_charge, 10, NULL, + ai_charge, 10, NULL, + ai_charge, 5, NULL, + ai_charge, 5, fiend_check_landing, + ai_charge, 5, NULL +}; +mmove_t fiend_move_jump = {FRAME_leap1, FRAME_leap12, fiend_frames_jump, fiend_run}; + +void fiend_jump (edict_t *self) +{ + self->monsterinfo.currentmove = &fiend_move_jump; +} + + +// +// CHECKATTACK +// + +static qboolean fiend_check_melee (edict_t *self) +{ + if (range (self, self->enemy) == RANGE_MELEE) + return true; + return false; +} + +static qboolean fiend_check_jump (edict_t *self) +{ + vec3_t v; + float distance; + + if (self->absmin[2] > (self->enemy->absmin[2] + 0.75 * self->enemy->size[2])) + return false; + + if (self->absmax[2] < (self->enemy->absmin[2] + 0.25 * self->enemy->size[2])) + return false; + + v[0] = self->s.origin[0] - self->enemy->s.origin[0]; + v[1] = self->s.origin[1] - self->enemy->s.origin[1]; + v[2] = 0; + distance = VectorLength(v); + + if (distance < 100) + return false; + if (distance > 100) + { + if (random() < 0.8) + return false; + } + + return true; +} + +qboolean fiend_checkattack (edict_t *self) +{ + if (!self->enemy || self->enemy->health <= 0) + return false; + + if (fiend_check_melee(self)) + { + self->monsterinfo.attack_state = AS_MELEE; + return true; + } + + if (fiend_check_jump(self)) + { + self->monsterinfo.attack_state = AS_MISSILE; + // FIXME play a jump sound here + return true; + } + return false; +} + + +// +// PAIN +// + +mframe_t fiend_frames_pain [] = +{ + ai_move, 4, NULL, + ai_move, -3, NULL, + ai_move, -8, NULL, + ai_move, -3, NULL, + ai_move, 2, NULL, + ai_move, 5, NULL +}; +mmove_t fiend_move_pain = {FRAME_pain1, FRAME_pain6, fiend_frames_pain, fiend_run}; + + +void fiend_pain (edict_t *self, edict_t *other, float kick, int damage) +{ + if (level.time < self->pain_debounce_time) + return; + + self->pain_debounce_time = level.time + 1.5; + + if (random()*200 > damage) + return; + + if (self->health > 0) + gi.sound (self, CHAN_VOICE, sound_pain, 1, ATTN_NORM, 0); + + if (skill->value == 3) + return; // no pain anims in nightmare + + self->monsterinfo.currentmove = &fiend_move_pain; + +} + + +// +// DEATH +// + +void fiend_dead (edict_t *self) +{ + VectorSet (self->mins, -16, -16, -24); + VectorSet (self->maxs, 16, 16, -8); + self->movetype = MOVETYPE_TOSS; + self->svflags |= SVF_DEADMONSTER; + gi.linkentity (self); +} + +void fiend_nogib (edict_t *self) +{ + self->gib_health = -10000; +} + +mframe_t fiend_frames_death [] = +{ + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, fiend_nogib, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL +}; +mmove_t fiend_move_death = {FRAME_death1, FRAME_death9, fiend_frames_death, fiend_dead}; + + +void fiend_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) +{ + int n; + + if (self->health <= self->gib_health && !(self->spawnflags & SF_MONSTER_NOGIB)) + { + gi.sound (self, CHAN_VOICE|CHAN_RELIABLE, gi.soundindex ("q1monstr/udeath.wav"), 1, ATTN_NORM, 0); + + for (n= 0; n < 2; n++) + ThrowGib (self, "models/objects/q1gibs/q1gib1/tris.md2", damage, GIB_ORGANIC); + for (n= 0; n < 2; n++) + ThrowGib (self, "models/objects/q1gibs/q1gib3/tris.md2", damage, GIB_ORGANIC); + ThrowHead (self, "models/monsters/q1fiend/head/tris.md2", damage, GIB_ORGANIC); + + self->deadflag = DEAD_DEAD; + return; + } + + if (self->deadflag == DEAD_DEAD) + return; + + gi.sound (self, CHAN_VOICE, sound_death, 1, ATTN_NORM, 0); + self->deadflag = DEAD_DEAD; + self->takedamage = DAMAGE_YES; + //self->s.skinnum = 1; + + self->monsterinfo.currentmove = &fiend_move_death; +} + + +// +// SPAWN +// + +/*QUAKED monster_q1_fiend (1 .5 0) (-32 -32 -24) (32 32 48) Ambush Trigger_Spawn Sight +model="models/monsters/q1fiend/tris.md2" +*/ +void SP_monster_q1_fiend (edict_t *self) +{ + if (deathmatch->value) + { + G_FreeEdict (self); + return; + } + + sound_hit = gi.soundindex ("q1fiend/dhit2.wav"); + sound_jump = gi.soundindex ("q1fiend/djump.wav"); + sound_death = gi.soundindex ("q1fiend/ddeath.wav"); + sound_idle = gi.soundindex ("q1fiend/idle1.wav"); + sound_pain = gi.soundindex ("q1fiend/dpain1.wav"); + sound_sight = gi.soundindex ("q1fiend/sight2.wav"); + sound_land = gi.soundindex ("q1fiend/dland2.wav"); + + self->movetype = MOVETYPE_STEP; + self->solid = SOLID_BBOX; + + // Lazarus: special purpose skins + if ( self->style ) + { + PatchMonsterModel("models/monsters/q1fiend/tris.md2"); + self->s.skinnum = self->style * 2; + } + + self->s.modelindex = gi.modelindex ("models/monsters/q1fiend/tris.md2"); + VectorSet (self->mins, -32, -32, -24); + VectorSet (self->maxs, 32, 32, 48); + + if (!self->health) + self->health = 300; + if (!self->gib_health) + self->gib_health = -80; + if (!self->mass) + self->mass = 300; + + self->pain = fiend_pain; + self->die = fiend_die; + + self->flags |= FL_Q1_MONSTER; + + self->monsterinfo.stand = fiend_stand; + self->monsterinfo.walk = fiend_walk; + self->monsterinfo.run = fiend_run; + self->monsterinfo.dodge = NULL; + self->monsterinfo.attack = fiend_jump; + self->monsterinfo.melee = fiend_melee; + self->monsterinfo.sight = fiend_sight; + self->monsterinfo.search = fiend_stand; + self->monsterinfo.idle = fiend_stand; + self->monsterinfo.checkattack = fiend_checkattack; + + if (!self->monsterinfo.flies) + self->monsterinfo.flies = 0.70; + + // Lazarus + if (self->powerarmor) + { + if (self->powerarmortype == 1) + self->monsterinfo.power_armor_type = POWER_ARMOR_SCREEN; + else + self->monsterinfo.power_armor_type = POWER_ARMOR_SHIELD; + self->monsterinfo.power_armor_power = self->powerarmor; + } + self->common_name = "Fiend"; + + gi.linkentity (self); + + self->monsterinfo.currentmove = &fiend_move_stand; + + self->monsterinfo.scale = MODEL_SCALE; + walkmonster_start (self); +} diff --git a/missionpack/m_q1fiend.h b/missionpack/m_q1fiend.h new file mode 100644 index 0000000..e3c42a7 --- /dev/null +++ b/missionpack/m_q1fiend.h @@ -0,0 +1,74 @@ +// Generated by ModelEd +// FIEND + +#define FRAME_stand1 0 +#define FRAME_stand2 1 +#define FRAME_stand3 2 +#define FRAME_stand4 3 +#define FRAME_stand5 4 +#define FRAME_stand6 5 +#define FRAME_stand7 6 +#define FRAME_stand8 7 +#define FRAME_stand9 8 +#define FRAME_stand10 9 +#define FRAME_stand11 10 +#define FRAME_stand12 11 +#define FRAME_stand13 12 +#define FRAME_walk1 13 +#define FRAME_walk2 14 +#define FRAME_walk3 15 +#define FRAME_walk4 16 +#define FRAME_walk5 17 +#define FRAME_walk6 18 +#define FRAME_walk7 19 +#define FRAME_walk8 20 +#define FRAME_run1 21 +#define FRAME_run2 22 +#define FRAME_run3 23 +#define FRAME_run4 24 +#define FRAME_run5 25 +#define FRAME_run6 26 +#define FRAME_leap1 27 +#define FRAME_leap2 28 +#define FRAME_leap3 29 +#define FRAME_leap4 30 +#define FRAME_leap5 31 +#define FRAME_leap6 32 +#define FRAME_leap7 33 +#define FRAME_leap8 34 +#define FRAME_leap9 35 +#define FRAME_leap10 36 +#define FRAME_leap11 37 +#define FRAME_leap12 38 +#define FRAME_pain1 39 +#define FRAME_pain2 40 +#define FRAME_pain3 41 +#define FRAME_pain4 42 +#define FRAME_pain5 43 +#define FRAME_pain6 44 +#define FRAME_death1 45 +#define FRAME_death2 46 +#define FRAME_death3 47 +#define FRAME_death4 48 +#define FRAME_death5 49 +#define FRAME_death6 50 +#define FRAME_death7 51 +#define FRAME_death8 52 +#define FRAME_death9 53 +#define FRAME_attacka1 54 +#define FRAME_attacka2 55 +#define FRAME_attacka3 56 +#define FRAME_attacka4 57 +#define FRAME_attacka5 58 +#define FRAME_attacka6 59 +#define FRAME_attacka7 60 +#define FRAME_attacka8 61 +#define FRAME_attacka9 62 +#define FRAME_attacka10 63 +#define FRAME_attacka11 64 +#define FRAME_attacka12 65 +#define FRAME_attacka13 66 +#define FRAME_attacka14 67 +#define FRAME_attacka15 68 + +#define MODEL_SCALE 1.000000 \ No newline at end of file diff --git a/missionpack/m_q1grunt.c b/missionpack/m_q1grunt.c new file mode 100644 index 0000000..6be592e --- /dev/null +++ b/missionpack/m_q1grunt.c @@ -0,0 +1,468 @@ +/* +============================================================================== + +Q1 SOLDIER + +============================================================================== +*/ + +#include "g_local.h" +#include "m_q1grunt.h" + +static int sound_idle; +static int sound_sight; +static int sound_pain1; +static int sound_pain2; +static int sound_death; +static int sound_attack; + + +void q1grunt_idle (edict_t *self) +{ + if(!self->enemy) + if (random() > 0.8) + { + gi.sound (self, CHAN_VOICE, sound_idle, 0.8, ATTN_STATIC, 0); + } +} + + + +// STAND + +void q1grunt_stand (edict_t *self); + +mframe_t q1grunt_frames_stand [] = +{ + ai_stand, 0, q1grunt_idle, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL +}; +mmove_t q1grunt_move_stand = {FRAME_stand1, FRAME_stand8, q1grunt_frames_stand, q1grunt_stand}; + +void q1grunt_stand (edict_t *self) +{ + self->monsterinfo.currentmove = &q1grunt_move_stand; +} + + +// +// WALK +// + +mframe_t q1grunt_frames_walk [] = +{ + ai_walk, 1, q1grunt_idle, + ai_walk, 1, NULL, + ai_walk, 1, NULL, + ai_walk, 1, NULL, + ai_walk, 2, NULL, + ai_walk, 3, NULL, + ai_walk, 4, NULL, + ai_walk, 4, NULL, + ai_walk, 2, NULL, + ai_walk, 2, NULL, + ai_walk, 2, NULL, + ai_walk, 1, NULL, + ai_walk, 0, NULL, + ai_walk, 1, NULL, + ai_walk, 1, NULL, + ai_walk, 1, NULL, + ai_walk, 3, NULL, + ai_walk, 3, NULL, + ai_walk, 3, NULL, + ai_walk, 3, NULL, + ai_walk, 2, NULL, + ai_walk, 1, NULL, + ai_walk, 1, NULL, + ai_walk, 1, NULL +}; +mmove_t q1grunt_move_walk = {FRAME_prowl_1, FRAME_prowl_24, q1grunt_frames_walk, NULL}; + +void q1grunt_walk (edict_t *self) +{ + self->monsterinfo.currentmove = &q1grunt_move_walk; +} + + +// +// RUN +// + +void q1grunt_run (edict_t *self); + +mframe_t q1grunt_frames_run [] = +{ + ai_run, 11, NULL, //q1grunt_idle, + ai_run, 15, NULL, + ai_run, 10, NULL, + ai_run, 10, NULL, + ai_run, 8, NULL, + ai_run, 15, NULL, + ai_run, 10, NULL, + ai_run, 15, NULL +}; +mmove_t q1grunt_move_run = {FRAME_run1, FRAME_run8, q1grunt_frames_run, q1grunt_run}; + +void q1grunt_run (edict_t *self) +{ + if (self->monsterinfo.aiflags & AI_STAND_GROUND) + { + self->monsterinfo.currentmove = &q1grunt_move_stand; + return; + } + else + self->monsterinfo.currentmove = &q1grunt_move_run; +} + +// +// PAIN +// + +mframe_t q1grunt_frames_pain1 [] = +{ + ai_move, -2, NULL, + ai_move, 3, NULL, + ai_move, 1, NULL, + ai_move, 1, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL +}; +mmove_t q1grunt_move_pain1 = {FRAME_pain1, FRAME_pain6, q1grunt_frames_pain1, q1grunt_run}; + +mframe_t q1grunt_frames_pain2 [] = +{ + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 13, NULL, + ai_move, 9, 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, -2, NULL, + ai_move, 0, NULL +}; +mmove_t q1grunt_move_pain2 = {FRAME_painb1, FRAME_painb14, q1grunt_frames_pain2, q1grunt_run}; + +mframe_t q1grunt_frames_pain3 [] = +{ + ai_move, 0, NULL, + ai_move, -1, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 1, NULL, + ai_move, 1, NULL, + ai_move, 0, NULL, + ai_move, -1, NULL, + ai_move, 4, NULL, + ai_move, 3, NULL, + ai_move, 6, NULL, + ai_move, 8, NULL, + ai_move, 0, NULL +}; +mmove_t q1grunt_move_pain3 = {FRAME_painc1, FRAME_painc13, q1grunt_frames_pain3, q1grunt_run}; + + +void q1grunt_pain (edict_t *self, edict_t *other, float kick, int damage) +{ + float r; + + if (level.time < self->pain_debounce_time) + return; + + if(self->health <= 0) + return; + + r = random(); + + if (r < 0.2) + { + self->monsterinfo.currentmove = &q1grunt_move_pain1; + gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0); + self->pain_debounce_time = level.time + 0.6; + } + else if (r < 0.6) + { + self->monsterinfo.currentmove = &q1grunt_move_pain2; + gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0); + self->pain_debounce_time = level.time + 1.1; + } + else + { + self->monsterinfo.currentmove = &q1grunt_move_pain3; + gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0); + self->pain_debounce_time = level.time + 1.1; + } +} + + +// +// ATTACK +// + +void q1grunt_fire (edict_t *self) +{ + vec3_t start; + vec3_t forward, right, up; + vec3_t aim; + vec3_t dir; + vec3_t end; + float r, u; + + if(!self->enemy) + return; + + AngleVectors (self->s.angles, forward, right, NULL); + G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_SOLDIER_SHOTGUN_1], forward, right, start); + + VectorCopy (self->enemy->s.origin, end); + end[2] += self->enemy->viewheight; + VectorSubtract (end, start, aim); + vectoangles (aim, dir); + AngleVectors (dir, forward, right, up); + + r = crandom()*1000; + u = crandom()*500; + VectorMA (start, 8192, forward, end); + VectorMA (end, r, right, end); + VectorMA (end, u, up, end); + + VectorSubtract (end, start, aim); + VectorNormalize (aim); + + gi.sound (self, CHAN_WEAPON|CHAN_RELIABLE, sound_attack, 1, ATTN_NORM, 0); + monster_fire_shotgun (self, start, aim, 2, 1, DEFAULT_SHOTGUN_HSPREAD, DEFAULT_SHOTGUN_VSPREAD, DEFAULT_SHOTGUN_COUNT, MZ2_SOLDIER_SHOTGUN_1); +} + + +void q1grunt_attack_refire (edict_t *self) +{ + if (!self->enemy || self->enemy->health <= 0) + return; + + if ( ((skill->value == 3) && (random() < 0.2)) || (range(self, self->enemy) == RANGE_MELEE) ) + self->monsterinfo.nextframe = FRAME_shoot1; + else + self->monsterinfo.nextframe = FRAME_shoot8; +} + + +mframe_t q1grunt_frames_attack [] = +{ + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, q1grunt_fire, + ai_charge, 0, NULL, + ai_charge, 0, q1grunt_attack_refire, + ai_charge, 0, NULL, + ai_charge, 0, NULL +}; +mmove_t q1grunt_move_attack = {FRAME_shoot1, FRAME_shoot9, q1grunt_frames_attack, q1grunt_run}; + +void q1grunt_attack(edict_t *self) +{ + self->monsterinfo.currentmove = &q1grunt_move_attack; +} + + +// +// SIGHT +// + +void q1grunt_sight(edict_t *self, edict_t *other) +{ + gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0); + + if ((skill->value > 0) && (range(self, self->enemy) < RANGE_FAR) + && !(self->monsterinfo.aiflags & AI_SOUND_TARGET)) + { + self->monsterinfo.currentmove = &q1grunt_move_attack; + } +} + + +// +// DEATH +// +void q1grunt_dropshells (edict_t *self) +{ +/* edict_t *backpack; + + if (self->health <= self->gib_health) + return; + + backpack = Drop_Item(self, FindItemByClassname("item_q1_backpack")); + backpack->item = FindItemByClassname("ammo_shells"); + backpack->count = 5; + backpack->touch = Touch_Item; + backpack->nextthink = level.time + 1800; + backpack->think = G_FreeEdict; +*/ + self->gib_health = -10000; +} + +void q1grunt_dead (edict_t *self) +{ + VectorSet (self->mins, -16, -16, -24); + VectorSet (self->maxs, 16, 16, -8); + self->movetype = MOVETYPE_TOSS; + self->svflags |= SVF_DEADMONSTER; + self->nextthink = 0; + gi.linkentity (self); +} + +mframe_t q1grunt_frames_death1 [] = +{ + ai_move, 0, NULL, + ai_move, -10, NULL, + ai_move, -10, q1grunt_dropshells, + ai_move, -10, NULL, + ai_move, -5, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL +}; +mmove_t q1grunt_move_death1 = {FRAME_death1, FRAME_death10, q1grunt_frames_death1, q1grunt_dead}; + +mframe_t q1grunt_frames_death2 [] = +{ + ai_move, 0, NULL, + ai_move, -5, NULL, + ai_move, -4, q1grunt_dropshells, + ai_move, -13, NULL, + ai_move, -3, NULL, + ai_move, -4, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL +}; +mmove_t q1grunt_move_death2 = {FRAME_deathc1, FRAME_deathc11, q1grunt_frames_death2, q1grunt_dead}; + +void q1grunt_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) +{ + int n; +// check for gib + if (self->health <= self->gib_health && !(self->spawnflags & SF_MONSTER_NOGIB)) + { + gi.sound (self, CHAN_VOICE|CHAN_RELIABLE, gi.soundindex ("q1monstr/udeath.wav"), 1, ATTN_NORM, 0); + + // if dead body, don't drop pack when gibbed + // if (self->deadflag != DEAD_DEAD) + // q1grunt_dropshells(self); + + for (n= 0; n < 2; n++) + ThrowGib (self, "models/objects/q1gibs/q1gib1/tris.md2", damage, GIB_ORGANIC); + ThrowGib (self, "models/objects/q1gibs/q1gib2/tris.md2", damage, GIB_ORGANIC); + ThrowHead (self, "models/monsters/q1grunt/head/tris.md2", damage, GIB_ORGANIC); + self->deadflag = DEAD_DEAD; + return; + } + + if (self->deadflag == DEAD_DEAD) + return; + +// regular death + self->deadflag = DEAD_DEAD; + self->takedamage = DAMAGE_YES; + + gi.sound (self, CHAN_VOICE, sound_death, 1, ATTN_NORM, 0); + + if (random() < 0.5) + self->monsterinfo.currentmove = &q1grunt_move_death1; + else + self->monsterinfo.currentmove = &q1grunt_move_death2; +} + + +// +// SPAWN +// + +/*QUAKED monster_q1_grunt (1 .5 0) (-16 -16 -24) (16 16 40) Ambush Trigger_Spawn Sight +model="models/monsters/q1grunt/tris.md2" +*/ +void SP_monster_q1_grunt (edict_t *self) +{ + if (deathmatch->value) + { + G_FreeEdict (self); + return; + } + + sound_idle = gi.soundindex ("q1grunt/idle.wav"); + sound_sight = gi.soundindex ("q1grunt/sight1.wav"); + sound_pain1 = gi.soundindex ("q1grunt/pain1.wav"); + sound_pain2 = gi.soundindex ("q1grunt/pain2.wav"); + sound_death = gi.soundindex ("q1grunt/death1.wav"); + sound_attack = gi.soundindex ("q1grunt/sattck1.wav"); + + self->movetype = MOVETYPE_STEP; + self->solid = SOLID_BBOX; + + // Lazarus: special purpose skins + if ( self->style ) + { + PatchMonsterModel("models/monsters/q1grunt/tris.md2"); + self->s.skinnum = self->style * 2; + } + + self->s.modelindex = gi.modelindex ("models/monsters/q1grunt/tris.md2"); + VectorSet (self->mins, -16, -16, -24); + VectorSet (self->maxs, 16, 16, 40); + + if (!self->health) + self->health = 35; + if (!self->gib_health) + self->gib_health = -35; + if (!self->mass) + self->mass = 100; + + self->pain = q1grunt_pain; + self->die = q1grunt_die; + + self->flags |= FL_Q1_MONSTER; + + self->monsterinfo.stand = q1grunt_stand; + self->monsterinfo.walk = q1grunt_walk; + self->monsterinfo.run = q1grunt_run; + self->monsterinfo.attack = q1grunt_attack; + self->monsterinfo.melee = NULL; + self->monsterinfo.sight = q1grunt_sight; + + if (!self->monsterinfo.flies) + self->monsterinfo.flies = 0.40; + + // Lazarus + if (self->powerarmor) + { + if (self->powerarmortype == 1) + self->monsterinfo.power_armor_type = POWER_ARMOR_SCREEN; + else + self->monsterinfo.power_armor_type = POWER_ARMOR_SHIELD; + self->monsterinfo.power_armor_power = self->powerarmor; + } + self->common_name = "Grunt"; + + gi.linkentity (self); + + self->monsterinfo.currentmove = &q1grunt_move_stand; + self->monsterinfo.scale = MODEL_SCALE; + + walkmonster_start (self); +} \ No newline at end of file diff --git a/missionpack/m_q1grunt.h b/missionpack/m_q1grunt.h new file mode 100644 index 0000000..0e37e75 --- /dev/null +++ b/missionpack/m_q1grunt.h @@ -0,0 +1,119 @@ +// Generated by ModelEd +// GRUNT / ARMY + +#define FRAME_stand1 0 +#define FRAME_stand2 1 +#define FRAME_stand3 2 +#define FRAME_stand4 3 +#define FRAME_stand5 4 +#define FRAME_stand6 5 +#define FRAME_stand7 6 +#define FRAME_stand8 7 +#define FRAME_death1 8 +#define FRAME_death2 9 +#define FRAME_death3 10 +#define FRAME_death4 11 +#define FRAME_death5 12 +#define FRAME_death6 13 +#define FRAME_death7 14 +#define FRAME_death8 15 +#define FRAME_death9 16 +#define FRAME_death10 17 +#define FRAME_deathc1 18 +#define FRAME_deathc2 19 +#define FRAME_deathc3 20 +#define FRAME_deathc4 21 +#define FRAME_deathc5 22 +#define FRAME_deathc6 23 +#define FRAME_deathc7 24 +#define FRAME_deathc8 25 +#define FRAME_deathc9 26 +#define FRAME_deathc10 27 +#define FRAME_deathc11 28 +#define FRAME_load1 29 +#define FRAME_load2 30 +#define FRAME_load3 31 +#define FRAME_load4 32 +#define FRAME_load5 33 +#define FRAME_load6 34 +#define FRAME_load7 35 +#define FRAME_load8 36 +#define FRAME_load9 37 +#define FRAME_load10 38 +#define FRAME_load11 39 +#define FRAME_pain1 40 +#define FRAME_pain2 41 +#define FRAME_pain3 42 +#define FRAME_pain4 43 +#define FRAME_pain5 44 +#define FRAME_pain6 45 +#define FRAME_painb1 46 +#define FRAME_painb2 47 +#define FRAME_painb3 48 +#define FRAME_painb4 49 +#define FRAME_painb5 50 +#define FRAME_painb6 51 +#define FRAME_painb7 52 +#define FRAME_painb8 53 +#define FRAME_painb9 54 +#define FRAME_painb10 55 +#define FRAME_painb11 56 +#define FRAME_painb12 57 +#define FRAME_painb13 58 +#define FRAME_painb14 59 +#define FRAME_painc1 60 +#define FRAME_painc2 61 +#define FRAME_painc3 62 +#define FRAME_painc4 63 +#define FRAME_painc5 64 +#define FRAME_painc6 65 +#define FRAME_painc7 66 +#define FRAME_painc8 67 +#define FRAME_painc9 68 +#define FRAME_painc10 69 +#define FRAME_painc11 70 +#define FRAME_painc12 71 +#define FRAME_painc13 72 +#define FRAME_run1 73 +#define FRAME_run2 74 +#define FRAME_run3 75 +#define FRAME_run4 76 +#define FRAME_run5 77 +#define FRAME_run6 78 +#define FRAME_run7 79 +#define FRAME_run8 80 +#define FRAME_shoot1 81 +#define FRAME_shoot2 82 +#define FRAME_shoot3 83 +#define FRAME_shoot4 84 +#define FRAME_shoot5 85 +#define FRAME_shoot6 86 +#define FRAME_shoot7 87 +#define FRAME_shoot8 88 +#define FRAME_shoot9 89 +#define FRAME_prowl_1 90 +#define FRAME_prowl_2 91 +#define FRAME_prowl_3 92 +#define FRAME_prowl_4 93 +#define FRAME_prowl_5 94 +#define FRAME_prowl_6 95 +#define FRAME_prowl_7 96 +#define FRAME_prowl_8 97 +#define FRAME_prowl_9 98 +#define FRAME_prowl_10 99 +#define FRAME_prowl_11 100 +#define FRAME_prowl_12 101 +#define FRAME_prowl_13 102 +#define FRAME_prowl_14 103 +#define FRAME_prowl_15 104 +#define FRAME_prowl_16 105 +#define FRAME_prowl_17 106 +#define FRAME_prowl_18 107 +#define FRAME_prowl_19 108 +#define FRAME_prowl_20 109 +#define FRAME_prowl_21 110 +#define FRAME_prowl_22 111 +#define FRAME_prowl_23 112 +#define FRAME_prowl_24 113 + +#define MODEL_SCALE 1.000000 \ No newline at end of file diff --git a/missionpack/m_q1hknight.c b/missionpack/m_q1hknight.c new file mode 100644 index 0000000..9248872 --- /dev/null +++ b/missionpack/m_q1hknight.c @@ -0,0 +1,560 @@ +/* +============================================================================== + +QUAKE HELL KNIGHT + +============================================================================== +*/ + +#include "g_local.h" +#include "m_q1hknight.h" + + +static int sound_sword1; +static int sound_sword2; +static int sound_death; +static int sound_idle; +static int sound_pain; +static int sound_sight; + +#define SWORDSOUND(self) gi.sound (self, CHAN_WEAPON, sound_sword1, 1, ATTN_NORM, 0.1f); + +void hknight_stand (edict_t *self); +void hknight_walk (edict_t *self); +void hknight_check_dist (edict_t *self); +void hknight_melee (edict_t *self); + +// +// SOUNDS +// +void hknight_sight_sound (edict_t *self) +{ + gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0); +} + +void hknight_sight (edict_t *self, edict_t *other) +{ + hknight_sight_sound(self); + + hknight_check_dist(self); +} + +void hknight_idle_sound (edict_t *self) +{ + if (random() < 0.1) + gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0); +} + +void hknight_sword_sound (edict_t *self) +{ + //if(self->style) + // return; + + if (random() < 0.5) + gi.sound (self, CHAN_VOICE, sound_sword1, 1, ATTN_IDLE, 0); + //self->style = 1; +} + + +// +// STAND +// + +mframe_t hknight_frames_stand [] = +{ + ai_stand, 0, hknight_idle_sound, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL + +}; +mmove_t hknight_move_stand = {FRAME_stand1, FRAME_stand9, hknight_frames_stand, hknight_stand}; + +void hknight_stand (edict_t *self) +{ + self->monsterinfo.currentmove = &hknight_move_stand; +} + + +// +// WALK +// + +mframe_t hknight_frames_walk [] = +{ + ai_walk, 5, NULL, + ai_walk, 5, NULL, + ai_walk, 4, NULL, + ai_walk, 4, NULL, + ai_walk, 2, NULL, + ai_walk, 2, NULL, + ai_walk, 3, NULL, + ai_walk, 3, NULL, + ai_walk, 4, NULL, + ai_walk, 3, NULL, + ai_walk, 4, NULL, + ai_walk, 6, NULL, + ai_walk, 2, NULL, + ai_walk, 2, NULL, + ai_walk, 4, NULL, + ai_walk, 3, NULL, + ai_walk, 3, NULL, + ai_walk, 3, NULL, + ai_walk, 3, NULL, + ai_walk, 2, NULL +}; +mmove_t hknight_move_walk = {FRAME_walk1, FRAME_walk20, hknight_frames_walk, hknight_walk}; + +void hknight_walk (edict_t *self) +{ + self->monsterinfo.currentmove = &hknight_move_walk; +} + + +// +// RUN +// +// can be improved + +void hknight_check_dist (edict_t *self) +{ + if (!self->enemy || !self->enemy->inuse || self->enemy->health <= 0) + return; + + if (range(self, self->enemy) == RANGE_MELEE) + hknight_melee(self); + //else if (random() < 0.5) + // hknight_runatk(self); +} + + +mframe_t hknight_frames_run [] = +{ + ai_run, 16, NULL, + ai_run, 20, NULL, + ai_run, 13, NULL, + ai_run, 7, NULL, + ai_run, 16, NULL, + ai_run, 20, NULL, + ai_run, 14, NULL, + ai_run, 6, hknight_check_dist +}; +mmove_t hknight_move_run = {FRAME_run1, FRAME_run8, hknight_frames_run, NULL}; + + +void hknight_run (edict_t *self) +{ + if (self->monsterinfo.aiflags & AI_STAND_GROUND) + self->monsterinfo.currentmove = &hknight_move_stand; + else + self->monsterinfo.currentmove = &hknight_move_run; +} + +/*mframe_t hknight_frames_attack_run [] = +{ + ai_charge, 20, NULL, + ai_charge, 20, hknight_sword_sound, + ai_charge, 13, NULL, + ai_charge, 7, NULL, + ai_charge, 16, NULL, + ai_charge, 20, hknight_attack, + ai_charge, 14, NULL, + ai_charge, 14, NULL, + ai_charge, 14, NULL, + ai_charge, 14, NULL, + ai_charge, 6, hknight_check_dist +}; +mmove_t hknight_move_attack_run = {FRAME_runattack1, FRAME_runattack11, hknight_frames_attack_run, hknight_run}; + +void hknight_attack_run (edict_t *self) +{ + self->monsterinfo.currentmove = &hknight_move_attack_run; +}*/ + +void hknight_melee_damage (edict_t *self) +{ + float ldmg; + + if (!self->enemy) + return; // removed before stroke + + if (PointDist(self->enemy->s.origin, self->s.origin) > 60) + return; + + ldmg = (random() + random() + random()) * 3; + T_Damage (self->enemy, self, self, vec3_origin, self->enemy->s.origin, vec3_origin, ldmg, 0, 0, MOD_UNKNOWN); +} + +mframe_t hknight_frames_smash [] = +{ + ai_charge, 1, NULL, + ai_charge, 13, NULL, + ai_charge, 9, NULL, + ai_charge, 11, NULL, + ai_charge, 10, hknight_melee_damage, + ai_charge, 7, hknight_melee_damage, + ai_charge, 12, hknight_melee_damage, + ai_charge, 2, hknight_melee_damage, + ai_charge, 3, hknight_melee_damage, + ai_charge, 0, NULL, + ai_charge, 0, NULL +}; +mmove_t hknight_smash_attack = {FRAME_smash1, FRAME_smash11, hknight_frames_smash, hknight_run}; + +void hknight_sword_swing (edict_t *self) +{ + SWORDSOUND(self); +} + +mframe_t hknight_frames_watk [] = +{ + ai_charge, 2, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 1, NULL, + ai_charge, 4, NULL, + ai_charge, 5, NULL, + ai_charge, 3, hknight_melee_damage, + ai_charge, 2, hknight_melee_damage, + ai_charge, 2, hknight_melee_damage, + ai_charge, 0, hknight_sword_swing, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 1, NULL, + ai_charge, 1, hknight_melee_damage, + ai_charge, 3, hknight_melee_damage, + ai_charge, 4, hknight_melee_damage, + ai_charge, 6, NULL, + ai_charge, 7, NULL, + ai_charge, 3, NULL +}; +mmove_t hknight_watk_attack = {FRAME_w_attack1, FRAME_w_attack22, hknight_frames_watk, hknight_run}; + +mframe_t hknight_frames_srice [] = +{ + ai_charge, 9, NULL, + ai_charge, 6, NULL, + ai_charge, 13, NULL, + ai_charge, 4, NULL, + ai_charge, 7, hknight_melee_damage, + ai_charge, 15, hknight_melee_damage, + ai_charge, 8, hknight_melee_damage, + ai_charge, 2, hknight_melee_damage, + ai_charge, 0, hknight_melee_damage, + ai_charge, 3, NULL +}; +mmove_t hknight_slice_attack = {FRAME_slice1, FRAME_slice10, hknight_frames_srice, hknight_run}; + +void hknight_melee (edict_t *self) +{ +// int hknight_type = (self->s.frame >= 121 ? (self->s.frame >= 133 ? 3 : 2) : 1) - 1; + + SWORDSOUND(self); + + if (self->dmg == 0) + { + self->monsterinfo.currentmove = &hknight_slice_attack; + self->dmg++; + } + else if (self->dmg == 1) + { + self->monsterinfo.currentmove = &hknight_smash_attack; + self->dmg++; + } + else if (self->dmg == 2) + { + self->monsterinfo.currentmove = &hknight_watk_attack; + self->dmg = 0; + } +} + + +// +// PAIN +// + +mframe_t hknight_frames_pain1 [] = +{ + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL +}; +mmove_t hknight_move_pain1 = {FRAME_pain1, FRAME_pain5, hknight_frames_pain1, hknight_run}; + +void hknight_pain (edict_t *self, edict_t *other, float kick, int damage) +{ + + if (level.time < self->pain_debounce_time) + return; + + if (skill->value == 3) + return; // no pain anims in nightmare + + gi.sound (self, CHAN_VOICE, sound_pain, 1, ATTN_NORM, 0); + self->pain_debounce_time = level.time + 1.1; + + self->monsterinfo.currentmove = &hknight_move_pain1; +} + + +// +// DEATH +// + +void hknight_dead (edict_t *self) +{ + VectorSet (self->mins, -16, -16, -24); + VectorSet (self->maxs, 16, 16, -8); + self->movetype = MOVETYPE_TOSS; + self->svflags |= SVF_DEADMONSTER; + gi.linkentity (self); +} + +void hknight_nogib (edict_t *self) +{ + self->gib_health = -10000; +} + +mframe_t hknight_frames_death1 [] = +{ + ai_move, 10, NULL, + ai_move, 8, NULL, + ai_move, 7, hknight_nogib, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 10, NULL, + ai_move, 11, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL +}; +mmove_t hknight_move_death1 = {FRAME_death1, FRAME_death12, hknight_frames_death1, hknight_dead}; + + +mframe_t hknight_frames_death2 [] = +{ + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, hknight_nogib, + 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 hknight_move_death2 = {FRAME_deathb1, FRAME_deathb9, hknight_frames_death2, hknight_dead}; + +void hknight_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) +{ + int n; + + if (self->health <= self->gib_health && !(self->spawnflags & SF_MONSTER_NOGIB)) + { + gi.sound (self, CHAN_VOICE|CHAN_RELIABLE, gi.soundindex ("q1monstr/udeath.wav"), 1, ATTN_NORM, 0); + + for (n= 0; n < 2; n++) + ThrowGib (self, "models/objects/q1gibs/q1gib3/tris.md2", damage, GIB_ORGANIC); + ThrowGib (self, "models/objects/q1gibs/q1gib1/tris.md2", damage, GIB_ORGANIC); + ThrowHead(self, "models/monsters/q1hknight/head/tris.md2", damage, GIB_ORGANIC); + + self->deadflag = DEAD_DEAD; + return; + } + + if (self->deadflag == DEAD_DEAD) + return; + + gi.sound (self, CHAN_VOICE, sound_death, 1, ATTN_NORM, 0); + self->deadflag = DEAD_DEAD; + self->takedamage = DAMAGE_YES; + + if(random() < 0.5) + self->monsterinfo.currentmove = &hknight_move_death1; + else + self->monsterinfo.currentmove = &hknight_move_death2; +} + +#define enemy_vis visible(self, self->enemy) + +mframe_t knight_charge1_frames [] = +{ + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL +}; +mmove_t knight_charge1_attack = {FRAME_char_a1, FRAME_char_a16, knight_charge1_frames, hknight_run}; + +void hknight_check_charge (edict_t *self) +{ + if (!enemy_vis) + return; + if (fabs(self->s.origin[2] - self->enemy->s.origin[2]) > 20) + return; + if (PointDist(self->s.origin, self->enemy->s.origin) < 80) + return; + + // Charge + self->monsterinfo.currentmove = &knight_charge1_attack; +} + +void hknight_fire_flame (edict_t *self) +{ + int lawl[] = {-2, -1, 0, 1, 2, 3}; + int rem = 165; + int arraynum = rem-self->s.frame; + float offang_y = 0; + vec3_t vec, forward, right, start; + vec3_t offang, v_forward, temp; + + AngleVectors (self->s.angles, forward, right, NULL); + VectorSet (temp, 0, 0, 14); + G_ProjectSource (self->s.origin, temp, forward, right, start); + + VectorSet (temp, 0, lawl[arraynum], 0); + VectorSubtract (self->s.angles, temp, vec); +// gi.dprintf("%i, %i\n", lawl[arraynum], arraynum); + AngleVectors (vec, forward, NULL, NULL); + + VectorSubtract (self->enemy->s.origin, self->s.origin, offang); + vectoangles (offang, offang); + offang_y = self->s.angles[1] + -lawl[arraynum] * 6; + offang[1] = offang_y; + + AngleVectors (offang, v_forward, NULL, NULL); + + //vec = VectorNormalizeFastf( + + gi.sound (self, CHAN_WEAPON, gi.soundindex ("q1hknight/attack1.wav"), 1, ATTN_NORM, 0); + + q1_fire_flame (self, start, v_forward, 0); +} + +mframe_t hknight_frames_magic [] = +{ + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, hknight_fire_flame, + ai_charge, 0, hknight_fire_flame, + ai_charge, 0, hknight_fire_flame, + ai_charge, 0, hknight_fire_flame, + ai_charge, 0, hknight_fire_flame, + ai_charge, 0, hknight_fire_flame +}; +mmove_t hknight_magic_attack = { FRAME_magicc1, FRAME_magicc11, hknight_frames_magic, hknight_run}; + +void hknight_magic (edict_t *self) +{ + self->monsterinfo.currentmove = &hknight_magic_attack; +} + + +// +// SPAWN +// + +/*QUAKED SP_monster_q1_hknight (1 .5 0) (-16 -16 -24) (16 16 40) Ambush Trigger_Spawn Sight +model="models/monsters/q1hknight/tris.md2" +*/ +void SP_monster_q1_hknight (edict_t *self) +{ + if (deathmatch->value) + { + G_FreeEdict (self); + return; + } + + sound_death = gi.soundindex ("q1hknight/death1.wav"); + sound_pain = gi.soundindex ("q1hknight/pain1.wav"); + sound_idle = gi.soundindex ("q1hknight/idle.wav"); + sound_sight = gi.soundindex ("q1hknight/sight1.wav"); + sound_sword1 = gi.soundindex ("q1hknight/slash1.wav"); + sound_sword2 = gi.soundindex ("q1hknight/slash1.wav"); + + self->movetype = MOVETYPE_STEP; + self->solid = SOLID_BBOX; + + // Lazarus: special purpose skins + if ( self->style ) + { + PatchMonsterModel("models/monsters/q1hknight/tris.md2"); + self->s.skinnum = self->style * 2; + } + + self->s.modelindex = gi.modelindex ("models/monsters/q1hknight/tris.md2"); + VectorSet (self->mins, -16, -16, -24); + VectorSet (self->maxs, 16, 16, 40); + + if (!self->health) + self->health = 250; + if (!self->gib_health) + self->gib_health = -40; + if (!self->mass) + self->mass = 175; + + self->pain = hknight_pain; + self->die = hknight_die; + + self->flags |= FL_Q1_MONSTER; + + self->monsterinfo.stand = hknight_stand; + self->monsterinfo.walk = hknight_walk; + self->monsterinfo.run = hknight_run; + self->monsterinfo.dodge = NULL; + self->monsterinfo.attack = hknight_magic; + self->monsterinfo.melee = hknight_melee; + self->monsterinfo.sight = hknight_sight; + self->monsterinfo.search = hknight_stand; + self->monsterinfo.idle = hknight_stand; + + self->dmg = rand()%2; + + if (!self->monsterinfo.flies) + self->monsterinfo.flies = 0.30; + + // Lazarus + if (self->powerarmor) + { + if (self->powerarmortype == 1) + self->monsterinfo.power_armor_type = POWER_ARMOR_SCREEN; + else + self->monsterinfo.power_armor_type = POWER_ARMOR_SHIELD; + self->monsterinfo.power_armor_power = self->powerarmor; + } + self->common_name = "Hell Knight"; + + gi.linkentity (self); + + self->monsterinfo.currentmove = &hknight_move_stand; + + self->monsterinfo.scale = MODEL_SCALE; + walkmonster_start (self); +} diff --git a/missionpack/m_q1hknight.h b/missionpack/m_q1hknight.h new file mode 100644 index 0000000..35721ae Binary files /dev/null and b/missionpack/m_q1hknight.h differ diff --git a/missionpack/m_q1knight.c b/missionpack/m_q1knight.c new file mode 100644 index 0000000..2dc253d --- /dev/null +++ b/missionpack/m_q1knight.c @@ -0,0 +1,474 @@ +/* +============================================================================== + +QUAKE KNIGHT + +============================================================================== +*/ + +#include "g_local.h" +#include "m_q1knight.h" + + +static int sound_sword1; +static int sound_sword2; +static int sound_death; +static int sound_pain; +static int sound_idle; +static int sound_sight; + + +void knight_stand (edict_t *self); +void knight_walk (edict_t *self); +void knight_check_dist (edict_t *self); + + +// +// SOUNDS +// + + +void knight_sight_sound (edict_t *self) +{ + gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0); // WAS ATTN_IDLE + self->style ++; +} + + +void knight_sight (edict_t *self, edict_t *other) +{ + if(self->style <= 1) + knight_sight_sound(self); + knight_check_dist(self); +} + +void knight_idle_sound (edict_t *self) +{ + if(random() < 0.1) + gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0); // WAS ATTN_STATIC +} + +void knight_sword_sound (edict_t *self) +{ + //if(self->style) + // return; + + if(random() < 0.5) + gi.sound (self, CHAN_VOICE, sound_sword1, 1, ATTN_NORM, 0); // WAS ATTN_IDLE + else + gi.sound (self, CHAN_VOICE, sound_sword2, 1, ATTN_NORM, 0); // WAS ATTN_IDLE + //self->style = 1; +} + +mframe_t knight_frames_kneel[] = +{ + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL +}; +mmove_t knight_move_kneel = {FRAME_kneel1, FRAME_kneel5, knight_frames_kneel, knight_stand}; + +void knight_kneel (edict_t *self) +{ + if(random() < 0.1) + self->monsterinfo.currentmove = &knight_move_kneel; +} + + +mframe_t knight_frames_standing[] = +{ + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL +}; +mmove_t knight_move_standing = {FRAME_standing2, FRAME_standing5, knight_frames_standing, knight_walk}; + +void knight_standing (edict_t *self) +{ + if(random() < 0.2) + self->monsterinfo.currentmove = &knight_move_standing; +} + + +// +// STAND +// + +mframe_t knight_frames_stand [] = +{ + ai_stand, 0, knight_idle_sound, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, knight_kneel, + ai_stand, 0, NULL, + ai_stand, 0, NULL + +}; +mmove_t knight_move_stand = {FRAME_stand1, FRAME_stand9, knight_frames_stand, knight_stand}; + +void knight_stand (edict_t *self) +{ + self->monsterinfo.currentmove = &knight_move_stand; +} + + +// +// WALK +// + +mframe_t knight_frames_walk [] = +{ + ai_walk, 3, knight_idle_sound, + ai_walk, 2, NULL, + ai_walk, 3, NULL, + ai_walk, 4, NULL, + ai_walk, 3, NULL, + ai_walk, 3, NULL, + ai_walk, 3, NULL, + ai_walk, 4, NULL, + ai_walk, 3, knight_standing, + ai_walk, 3, NULL, + ai_walk, 2, NULL, + ai_walk, 3, NULL, + ai_walk, 4, NULL, + ai_walk, 3, NULL +}; +mmove_t knight_move_walk = {FRAME_walk1, FRAME_walk14, knight_frames_walk, knight_walk}; + +void knight_walk (edict_t *self) +{ + self->monsterinfo.currentmove = &knight_move_walk; +} + + +// +// RUN +// +// can be improved + +void knight_check_dist (edict_t *self) +{ + if (!self->enemy || !self->enemy->inuse || self->enemy->health <= 0) + return; + + if (range(self, self->enemy) == RANGE_MELEE) + { + self->monsterinfo.nextframe = FRAME_attackb1; + } + else + { + if(random() > 0.6) + self->monsterinfo.nextframe = FRAME_runattack1; + else + self->monsterinfo.nextframe = FRAME_runb1; + } +} + + +mframe_t knight_frames_run [] = +{ + ai_run, 16, NULL, + ai_run, 20, NULL, + ai_run, 13, NULL, + ai_run, 7, NULL, + ai_run, 16, NULL, + ai_run, 20, NULL, + ai_run, 14, NULL, + ai_run, 6, knight_check_dist +}; +mmove_t knight_move_run = {FRAME_runb1, FRAME_runb8, knight_frames_run, NULL}; + + +void knight_run (edict_t *self) +{ + if (self->monsterinfo.aiflags & AI_STAND_GROUND) + self->monsterinfo.currentmove = &knight_move_stand; + else + self->monsterinfo.currentmove = &knight_move_run; +} + + +void knight_attack (edict_t *self) +{ + vec3_t aim; + + VectorSet (aim, MELEE_DISTANCE, self->mins[0], 2); + if (fire_hit (self, aim, (10 + (rand() %5)), 100)) + gi.sound (self, CHAN_WEAPON, sound_sword1, 1, ATTN_NORM, 0); +} + + + +mframe_t knight_frames_attack_run [] = +{ + ai_charge, 20, NULL, + ai_charge, 20, knight_sword_sound, + ai_charge, 13, NULL, + ai_charge, 7, NULL, + ai_charge, 16, NULL, + ai_charge, 20, knight_attack, + ai_charge, 14, NULL, + ai_charge, 14, NULL, + ai_charge, 14, NULL, + ai_charge, 14, NULL, + ai_charge, 6, knight_check_dist +}; +mmove_t knight_move_attack_run = {FRAME_runattack1, FRAME_runattack11, knight_frames_attack_run, knight_run}; + +void knight_attack_run (edict_t *self) +{ + self->monsterinfo.currentmove = &knight_move_attack_run; +} + + +void knight_hit_left (edict_t *self) +{ + vec3_t aim; + + VectorSet (aim, MELEE_DISTANCE, self->mins[0], 4); + if (fire_hit (self, aim, (10 + (rand() %5)), 100)) + gi.sound (self, CHAN_WEAPON, sound_sword1, 1, ATTN_NORM, 0); +} + +mframe_t knight_frames_attack [] = +{ + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, knight_hit_left, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, knight_check_dist +}; +mmove_t knight_move_attack = {FRAME_attackb1, FRAME_attackb10, knight_frames_attack, knight_run}; + + +void knight_melee (edict_t *self) +{ + self->monsterinfo.currentmove = &knight_move_attack; +} + + +// +// PAIN +// + +mframe_t knight_frames_pain1 [] = +{ + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL +}; +mmove_t knight_move_pain1 = {FRAME_pain1, FRAME_pain3, knight_frames_pain1, knight_run}; + +mframe_t knight_frames_pain2 [] = +{ + 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 knight_move_pain2 = {FRAME_painb1, FRAME_painb11, knight_frames_pain2, knight_run}; + +void knight_pain (edict_t *self, edict_t *other, float kick, int damage) +{ + + if (level.time < self->pain_debounce_time) + return; + + if (skill->value == 3) + return; // no pain anims in nightmare + + if (self->health > 0) + gi.sound (self, CHAN_VOICE, sound_pain, 1, ATTN_NORM, 0); + + + self->pain_debounce_time = level.time + 1.1; + + if(random() <0.85) + self->monsterinfo.currentmove = &knight_move_pain1; + else + self->monsterinfo.currentmove = &knight_move_pain2; + +} + + +// +// DEATH +// + +void knight_dead (edict_t *self) +{ + VectorSet (self->mins, -16, -16, -24); + VectorSet (self->maxs, 16, 16, -8); + self->movetype = MOVETYPE_TOSS; + self->svflags |= SVF_DEADMONSTER; + gi.linkentity (self); +} + +void knight_nogib (edict_t *self) +{ + self->gib_health = -10000; +} + +mframe_t knight_frames_death1 [] = +{ + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, knight_nogib, + 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 knight_move_death1 = {FRAME_death1, FRAME_death10, knight_frames_death1, knight_dead}; + + +mframe_t knight_frames_death2 [] = +{ + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, knight_nogib, + 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 knight_move_death2 = {FRAME_deathb1, FRAME_deathb11, knight_frames_death2, knight_dead}; + + + +void knight_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) +{ + int n; + + if (self->health <= self->gib_health && !(self->spawnflags & SF_MONSTER_NOGIB)) + { + gi.sound (self, CHAN_VOICE|CHAN_RELIABLE, gi.soundindex ("q1monstr/udeath.wav"), 1, ATTN_NORM, 0); + + for (n= 0; n < 2; n++) + ThrowGib (self, "models/objects/q1gibs/q1gib3/tris.md2", damage, GIB_ORGANIC); + ThrowGib (self, "models/objects/q1gibs/q1gib1/tris.md2", damage, GIB_ORGANIC); + ThrowHead(self, "models/monsters/q1knight/head/tris.md2", damage, GIB_ORGANIC); + + self->deadflag = DEAD_DEAD; + return; + } + + if (self->deadflag == DEAD_DEAD) + return; + + gi.sound (self, CHAN_VOICE, sound_death, 1, ATTN_NORM, 0); + self->deadflag = DEAD_DEAD; + self->takedamage = DAMAGE_YES; + + if(random() < 0.5) + self->monsterinfo.currentmove = &knight_move_death1; + else + self->monsterinfo.currentmove = &knight_move_death2; +} + + +// +// SPAWN +// + +/*QUAKED monster_q1_knight (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight +model="models/monsters/q1knight/tris.md2" +*/ +void SP_monster_q1_knight (edict_t *self) +{ + if (deathmatch->value) + { + G_FreeEdict (self); + return; + } + + sound_sword1 = gi.soundindex ("q1knight/sword1.wav"); + sound_sword2 = gi.soundindex ("q1knight/sword2.wav"); + sound_death = gi.soundindex ("q1knight/kdeath.wav"); + sound_pain = gi.soundindex ("q1knight/khurt.wav"); + sound_idle = gi.soundindex ("q1knight/idle.wav"); + sound_sight = gi.soundindex ("q1knight/ksight.wav"); + + self->movetype = MOVETYPE_STEP; + self->solid = SOLID_BBOX; + + // Lazarus: special purpose skins + if ( self->style ) + { + PatchMonsterModel("models/monsters/q1knight/tris.md2"); + self->s.skinnum = self->style * 2; + } + + self->s.modelindex = gi.modelindex ("models/monsters/q1knight/tris.md2"); + VectorSet (self->mins, -16, -16, -24); + VectorSet (self->maxs, 16, 16, 32); + + if (!self->health) + self->health = 75; + if (!self->gib_health) + self->gib_health = -40; + if (!self->mass) + self->mass = 125; + + self->pain = knight_pain; + self->die = knight_die; + + self->flags |= FL_Q1_MONSTER; + + self->monsterinfo.stand = knight_stand; + self->monsterinfo.walk = knight_walk; + self->monsterinfo.run = knight_run; + self->monsterinfo.dodge = NULL; + self->monsterinfo.attack = knight_attack_run; + self->monsterinfo.melee = knight_melee; + self->monsterinfo.sight = knight_sight; + self->monsterinfo.search = knight_stand; + self->monsterinfo.idle = knight_stand; + + if (!self->monsterinfo.flies) + self->monsterinfo.flies = 0.30; + + // Lazarus + if (self->powerarmor) + { + if (self->powerarmortype == 1) + self->monsterinfo.power_armor_type = POWER_ARMOR_SCREEN; + else + self->monsterinfo.power_armor_type = POWER_ARMOR_SHIELD; + self->monsterinfo.power_armor_power = self->powerarmor; + } + self->common_name = "Knight"; + + gi.linkentity (self); + + self->monsterinfo.currentmove = &knight_move_stand; + + self->monsterinfo.scale = MODEL_SCALE; + walkmonster_start (self); +} diff --git a/missionpack/m_q1knight.h b/missionpack/m_q1knight.h new file mode 100644 index 0000000..a398503 --- /dev/null +++ b/missionpack/m_q1knight.h @@ -0,0 +1,101 @@ +// Generated by ModelEd +// KNIGHT + +#define FRAME_stand1 0 +#define FRAME_stand2 1 +#define FRAME_stand3 2 +#define FRAME_stand4 3 +#define FRAME_stand5 4 +#define FRAME_stand6 5 +#define FRAME_stand7 6 +#define FRAME_stand8 7 +#define FRAME_stand9 8 +#define FRAME_runb1 9 +#define FRAME_runb2 10 +#define FRAME_runb3 11 +#define FRAME_runb4 12 +#define FRAME_runb5 13 +#define FRAME_runb6 14 +#define FRAME_runb7 15 +#define FRAME_runb8 16 +#define FRAME_runattack1 17 +#define FRAME_runattack2 18 +#define FRAME_runattack3 19 +#define FRAME_runattack4 20 +#define FRAME_runattack5 21 +#define FRAME_runattack6 22 +#define FRAME_runattack7 23 +#define FRAME_runattack8 24 +#define FRAME_runattack9 25 +#define FRAME_runattack10 26 +#define FRAME_runattack11 27 +#define FRAME_pain1 28 +#define FRAME_pain2 29 +#define FRAME_pain3 30 +#define FRAME_painb1 31 +#define FRAME_painb2 32 +#define FRAME_painb3 33 +#define FRAME_painb4 34 +#define FRAME_painb5 35 +#define FRAME_painb6 36 +#define FRAME_painb7 37 +#define FRAME_painb8 38 +#define FRAME_painb9 39 +#define FRAME_painb10 40 +#define FRAME_painb11 41 +#define FRAME_attackb1 42 +#define FRAME_attackb2 43 +#define FRAME_attackb3 44 +#define FRAME_attackb4 45 +#define FRAME_attackb5 46 +#define FRAME_attackb6 47 +#define FRAME_attackb7 48 +#define FRAME_attackb8 49 +#define FRAME_attackb9 50 +#define FRAME_attackb10 51 +#define FRAME_walk1 52 +#define FRAME_walk2 53 +#define FRAME_walk3 54 +#define FRAME_walk4 55 +#define FRAME_walk5 56 +#define FRAME_walk6 57 +#define FRAME_walk7 58 +#define FRAME_walk8 59 +#define FRAME_walk9 60 +#define FRAME_walk10 61 +#define FRAME_walk11 62 +#define FRAME_walk12 63 +#define FRAME_walk13 64 +#define FRAME_walk14 65 +#define FRAME_kneel1 66 +#define FRAME_kneel2 67 +#define FRAME_kneel3 68 +#define FRAME_kneel4 69 +#define FRAME_kneel5 70 +#define FRAME_standing2 71 +#define FRAME_standing3 72 +#define FRAME_standing4 73 +#define FRAME_standing5 74 +#define FRAME_death1 75 +#define FRAME_death2 76 +#define FRAME_death3 77 +#define FRAME_death4 78 +#define FRAME_death5 79 +#define FRAME_death6 80 +#define FRAME_death7 81 +#define FRAME_death8 82 +#define FRAME_death9 83 +#define FRAME_death10 84 +#define FRAME_deathb1 85 +#define FRAME_deathb2 86 +#define FRAME_deathb3 87 +#define FRAME_deathb4 88 +#define FRAME_deathb5 89 +#define FRAME_deathb6 90 +#define FRAME_deathb7 91 +#define FRAME_deathb8 92 +#define FRAME_deathb9 93 +#define FRAME_deathb10 94 +#define FRAME_deathb11 95 + +#define MODEL_SCALE 1.000000 \ No newline at end of file diff --git a/missionpack/m_q1ogre.c b/missionpack/m_q1ogre.c new file mode 100644 index 0000000..fafbfae --- /dev/null +++ b/missionpack/m_q1ogre.c @@ -0,0 +1,586 @@ +/* +============================================================================== + +QUAKE OGRE + +============================================================================== +*/ + +#include "g_local.h" +#include "m_q1ogre.h" + +static int sound_pain; +static int sound_death; +static int sound_idle; +static int sound_idle2; +static int sound_wake; +static int sound_saw; +static int sound_drag; + + +void ogre_check_refire (edict_t *self); +void ogre_attack(edict_t *self); + +void ogre_idle_sound1 (edict_t *self) +{ + if (random() < 0.2) + gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0); +} + +void ogre_idle_sound2 (edict_t *self) +{ + if (random() < 0.2) + gi.sound (self, CHAN_VOICE, sound_idle2, 1, ATTN_IDLE, 0); +} + +void ogre_sight (edict_t *self, edict_t *other) +{ + gi.sound (self, CHAN_VOICE, sound_wake, 1, ATTN_NORM, 0); + ogre_attack(self); +} + +void ogre_drag_sound (edict_t *self) +{ + //if(anglemod(self->s.angles[YAW]) != self->ideal_yaw) + if (random() < 0.2) + gi.sound (self, CHAN_VOICE, sound_drag, 1, ATTN_IDLE, 0); +} + + +void ogre_stand (edict_t *self); + +mframe_t ogre_frames_stand [] = +{ + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, ogre_idle_sound1, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, +}; + +mmove_t ogre_move_stand = {FRAME_stand1, FRAME_stand9, ogre_frames_stand, ogre_stand}; + +void ogre_stand (edict_t *self) +{ + self->monsterinfo.currentmove = &ogre_move_stand; +} + + +mframe_t ogre_frames_walk [] = +{ + ai_walk, 3, NULL, + ai_walk, 2, NULL, + ai_walk, 2, ogre_idle_sound1, + ai_walk, 2, NULL, + ai_walk, 2, NULL, + ai_walk, 6, ogre_drag_sound, + ai_walk, 3, NULL, + ai_walk, 2, NULL, + ai_walk, 3, NULL, + ai_walk, 1, NULL, + ai_walk, 2, NULL, + ai_walk, 3, NULL, + ai_walk, 3, NULL, + ai_walk, 3, NULL, + ai_walk, 3, NULL, + ai_walk, 4, NULL +}; +mmove_t ogre_move_walk = {FRAME_walk1, FRAME_walk16, ogre_frames_walk, NULL}; + +void ogre_walk (edict_t *self) +{ + self->monsterinfo.currentmove = &ogre_move_walk; +} + + +mframe_t ogre_frames_run [] = +{ + ai_run, 9, NULL, + ai_run, 12,NULL, + ai_run, 8, NULL, + ai_run, 22,NULL, + ai_run, 16,NULL, + ai_run, 4, NULL, + ai_run, 13,ogre_attack, + ai_run, 24,NULL +}; + +mmove_t ogre_move_run = {FRAME_run1, FRAME_run8, ogre_frames_run, NULL}; + + +void ogre_run (edict_t *self) +{ + if (self->monsterinfo.aiflags & AI_STAND_GROUND) + self->monsterinfo.currentmove = &ogre_move_stand; + else + self->monsterinfo.currentmove = &ogre_move_run; +} + + + +mframe_t ogre_frames_pain1 [] = +{ + ai_move, -3, NULL, + ai_move, 1, NULL, + ai_move, 1, NULL, + ai_move, 0, NULL, + ai_move, 1, NULL +}; +mmove_t ogre_move_pain1 = {FRAME_pain1, FRAME_pain5, ogre_frames_pain1, ogre_run}; + +mframe_t ogre_frames_pain2 [] = +{ + ai_move, -1,NULL, + ai_move, 0, NULL, + ai_move, 1, NULL +}; +mmove_t ogre_move_pain2 = {FRAME_painb1, FRAME_painb3, ogre_frames_pain2, ogre_run}; + + +mframe_t ogre_frames_pain3 [] = +{ + ai_move, -3, NULL, + ai_move, 1, NULL, + ai_move, 1, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 1, NULL +}; +mmove_t ogre_move_pain3 = {FRAME_painc1, FRAME_painc6, ogre_frames_pain3, ogre_run}; + + +mframe_t ogre_frames_pain4 [] = +{ + ai_move, -3, 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, 1, NULL, + ai_move, 1, NULL, + ai_move, 0, NULL +}; +mmove_t ogre_move_pain4 = {FRAME_paind1, FRAME_paind16, ogre_frames_pain4, ogre_run}; + +mframe_t ogre_frames_pain5 [] = +{ + ai_move, -3, 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, 1, NULL, + ai_move, 1, NULL, + ai_move, 0, NULL, +}; +mmove_t ogre_move_pain5 = {FRAME_paine1, FRAME_paine15, ogre_frames_pain5, ogre_run}; + + +void ogre_pain (edict_t *self, edict_t *other, float kick, int damage) +{ + float r; + + + if (level.time < self->pain_debounce_time) + return; + + r=random(); + + if (self->health > 0) + gi.sound (self, CHAN_VOICE, sound_pain, 1, ATTN_NORM, 0); + + if (r < 0.25) + { + self->monsterinfo.currentmove = &ogre_move_pain1; + self->pain_debounce_time = level.time + 1; + + } + else if (r < 0.5) + { + self->monsterinfo.currentmove = &ogre_move_pain2; + self->pain_debounce_time = level.time + 1; + + } + else if (r < 0.75) + { + self->monsterinfo.currentmove = &ogre_move_pain3; + self->pain_debounce_time = level.time + 1; + + } + else if (r < 0.88) + { + self->monsterinfo.currentmove = &ogre_move_pain4; + self->pain_debounce_time = level.time + 2; + + } + else + { + self->monsterinfo.currentmove = &ogre_move_pain5; + self->pain_debounce_time = level.time + 2; + + } +} + +void ogre_droprockets (edict_t *self) +{ +/* edict_t *backpack; + + if (self->health <= self->gib_health) + return; + + backpack = Drop_Item(self, FindItemByClassname("item_q1_backpack")); +// backpack->item = FindItemByClassname("ammo_grenades"); + backpack->item = FindItemByClassname("ammo_rockets"); + backpack->count = 2; + backpack->touch = Touch_Item; + backpack->nextthink = level.time + 1800; + backpack->think = G_FreeEdict; +*/ + self->gib_health = -10000; +} + +void ogre_dead (edict_t *self) +{ + VectorSet (self->mins, -16, -16, -24); + VectorSet (self->maxs, 16, 16, -8); + self->movetype = MOVETYPE_TOSS; + self->svflags |= SVF_DEADMONSTER; + self->nextthink = 0; + gi.linkentity (self); +} + +mframe_t ogre_frames_death1 [] = +{ + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, ogre_droprockets, + ai_move, -7, NULL, + ai_move, -3, NULL, + ai_move, -5, NULL, + ai_move, 8, NULL, + ai_move, 6, 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 ogre_move_death1 = {FRAME_death1, FRAME_death14, ogre_frames_death1, ogre_dead}; + +mframe_t ogre_frames_death2 [] = +{ + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, ogre_droprockets, + ai_move, -7, NULL, + ai_move, -3, NULL, + ai_move, -5, NULL, + ai_move, 8, NULL, + ai_move, 6, 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 ogre_move_death2 = {FRAME_bdeath1, FRAME_bdeath10, ogre_frames_death2, ogre_dead}; + + +void ogre_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) +{ + int n; + +// check for gib + if (self->health <= self->gib_health && !(self->spawnflags & SF_MONSTER_NOGIB)) + { + gi.sound (self, CHAN_VOICE|CHAN_RELIABLE, gi.soundindex ("q1monstr/udeath.wav"), 1, ATTN_NORM, 0); + + // if dead body, don't drop pack when gibbed + // if (self->deadflag != DEAD_DEAD) + // ogre_droprockets(self); + + for (n= 0; n < 2; n++) + ThrowGib (self, "models/objects/q1gibs/q1gib1/tris.md2", damage, GIB_ORGANIC); + for (n= 0; n < 4; n++) + ThrowGib (self, "models/objects/q1gibs/q1gib3/tris.md2", damage, GIB_ORGANIC); + ThrowHead (self, "models/monsters/q1ogre/head/tris.md2", damage, GIB_ORGANIC); + self->deadflag = DEAD_DEAD; + return; + } + + if (self->deadflag == DEAD_DEAD) + return; + +// regular death + gi.sound (self, CHAN_VOICE, sound_death, 1, ATTN_NORM, 0); + self->deadflag = DEAD_DEAD; + self->takedamage = DAMAGE_YES; + + if(random() < 0.5) + self->monsterinfo.currentmove = &ogre_move_death1; + else + self->monsterinfo.currentmove = &ogre_move_death2; +} + + +void ogre_grenade_fire(edict_t *self) +{ + + vec3_t start; + vec3_t forward, right; + vec3_t target; + vec3_t aim; + + AngleVectors (self->s.angles, forward, right, NULL); + G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_GUNNER_GRENADE_1], forward, right, start); + + // project enemy back a bit and target there + VectorCopy (self->enemy->s.origin, target); + + //if(range(self,self->enemy) > RANGE_MID) + VectorMA (target, -0.1, self->enemy->velocity, target); + + if(range(self,self->enemy) > RANGE_MID) + target[2] += self->enemy->viewheight; + else + target[2] += self->enemy->viewheight*0.8; + + VectorSubtract (target, start, aim); + VectorNormalize (aim); + + gi.WriteByte (svc_muzzleflash); + gi.WriteShort (self-g_edicts); + gi.WriteByte (MZ_MACHINEGUN | 128); + gi.multicast (self->s.origin, MULTICAST_PVS); + + gi.sound (self, CHAN_WEAPON|CHAN_RELIABLE, gi.soundindex("q1weap/grenades/grenade.wav"), 1.0, ATTN_NORM, 0); + q1_fire_grenade (self, start,aim,40 , 600, 2.5, 80); +} + + +////////////// +// Skid - add Gib fall off + +void ogre_swing_left (edict_t *self) +{ + vec3_t aim; + + VectorSet (aim, MELEE_DISTANCE, self->mins[0], 8); + fire_hit (self, aim, ((random() + random() + random()) * 4), 100); +} + +void ogre_swing_right (edict_t *self) +{ + vec3_t aim; + + VectorSet (aim, MELEE_DISTANCE, self->maxs[0], 8); + fire_hit (self, aim, ((random() + random() + random()) * 4), 100); +} + +void ogre_smash (edict_t *self) +{ + vec3_t aim; + + VectorSet (aim, MELEE_DISTANCE, self->mins[0], 8); + if (fire_hit (self, aim, (25 + (rand() %5)), 100)) + gi.sound (self, CHAN_WEAPON, sound_saw, 1, ATTN_NORM, 0); +} + + +void ogre_check_refire (edict_t *self) +{ + if (!self->enemy || !self->enemy->inuse || self->enemy->health <= 0) + return; + + if (skill->value == 3|| (range(self, self->enemy) == RANGE_MELEE)) + { + if(random() > 0.5) + self->monsterinfo.nextframe = FRAME_swing1; + else + self->monsterinfo.nextframe = FRAME_smash1; + } + else + ogre_attack(self); +} + + +/*static*/ void ogre_sawswingsound(edict_t *self) +{ + gi.sound (self, CHAN_WEAPON, sound_saw, 1, ATTN_NORM, 0); +} + +mframe_t ogre_frames_swing [] = +{ + + ai_charge, 0, NULL, + ai_charge, 0, ogre_sawswingsound, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, ogre_swing_right, + ai_charge, 0, NULL, + ai_charge, 0, ogre_sawswingsound, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, ogre_swing_left, + ai_charge, 0, NULL, + ai_charge, 0, ogre_check_refire +}; +mmove_t ogre_move_swing_attack = {FRAME_swing1, FRAME_swing14, ogre_frames_swing, ogre_run}; + + +mframe_t ogre_frames_smash [] = +{ + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, ogre_smash, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, ogre_check_refire +}; +mmove_t ogre_move_smash_attack = {FRAME_smash1, FRAME_smash14, ogre_frames_smash, ogre_run}; + +mframe_t ogre_frames_attack_grenade [] = +{ + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, ogre_grenade_fire, + ai_charge, 0, NULL, + ai_charge, 0, NULL //ogre_attack +}; +mmove_t ogre_move_attack_grenade = {FRAME_shoot1, FRAME_shoot6, ogre_frames_attack_grenade, ogre_run}; + + +void ogre_attack(edict_t *self) +{ + int r; + + if(!self->enemy) + return; + + r = range(self,self->enemy); + + if (r == RANGE_MELEE) + { + self->monsterinfo.currentmove = &ogre_move_swing_attack; + } + else if(visible(self,self->enemy) && infront(self,self->enemy) + && (r < RANGE_FAR) && !(self->monsterinfo.aiflags & AI_SOUND_TARGET)) + { + self->monsterinfo.currentmove = &ogre_move_attack_grenade; + } + else + self->monsterinfo.currentmove = &ogre_move_run; +} + + +// +// SPAWN +// + +/*QUAKED monster_q1_ogre (1 .5 0) (-20 -20 -24) (20 20 32) Ambush Trigger_Spawn Sight +model="models/monsters/q1ogre/tris.md2" +*/ +void SP_monster_q1_ogre (edict_t *self) +{ + if (deathmatch->value) + { + G_FreeEdict (self); + return; + } + + sound_pain = gi.soundindex ("q1ogre/ogpain1.wav"); + sound_death= gi.soundindex ("q1ogre/ogdth.wav"); + sound_idle = gi.soundindex ("q1ogre/ogidle.wav"); + sound_idle2= gi.soundindex ("q1ogre/ogidle2.wav"); + sound_wake = gi.soundindex ("q1ogre/ogwake.wav"); + sound_saw = gi.soundindex ("q1ogre/ogsawatk.wav"); + sound_drag = gi.soundindex ("q1ogre/ogdrag.wav"); + + self->movetype = MOVETYPE_STEP; + self->solid = SOLID_BBOX; + + // Lazarus: special purpose skins + if ( self->style ) + { + PatchMonsterModel("models/monsters/q1ogre/tris.md2"); + self->s.skinnum = self->style * 2; + } + + self->s.modelindex = gi.modelindex ("models/monsters/q1ogre/tris.md2"); + VectorSet (self->mins, -20, -20, -24); //16 16 + VectorSet (self->maxs, 20, 20, 32); //16 16 + + if (!self->health) + self->health = 200; + if (!self->gib_health) + self->gib_health = -80; + if (!self->mass) + self->mass = 400; + + self->pain = ogre_pain; + self->die = ogre_die; + + self->flags |= FL_Q1_MONSTER; + + self->monsterinfo.stand = ogre_stand; + self->monsterinfo.walk = ogre_walk; + self->monsterinfo.run = ogre_run; + self->monsterinfo.dodge = NULL; + self->monsterinfo.attack = ogre_attack; + self->monsterinfo.melee = ogre_check_refire; + self->monsterinfo.sight = ogre_sight; + self->monsterinfo.search = ogre_stand; + + if (!self->monsterinfo.flies) + self->monsterinfo.flies = 0.75; + + // Lazarus + if (self->powerarmor) + { + if (self->powerarmortype == 1) + self->monsterinfo.power_armor_type = POWER_ARMOR_SCREEN; + else + self->monsterinfo.power_armor_type = POWER_ARMOR_SHIELD; + self->monsterinfo.power_armor_power = self->powerarmor; + } + self->common_name = "Ogre"; + + gi.linkentity (self); + + self->monsterinfo.currentmove = &ogre_move_stand; + self->monsterinfo.scale = MODEL_SCALE; + + walkmonster_start (self); +} diff --git a/missionpack/m_q1ogre.h b/missionpack/m_q1ogre.h new file mode 100644 index 0000000..359c74f --- /dev/null +++ b/missionpack/m_q1ogre.h @@ -0,0 +1,152 @@ +// Generated by ModelEd +// OGRE + +#define FRAME_stand1 0 +#define FRAME_stand2 1 +#define FRAME_stand3 2 +#define FRAME_stand4 3 +#define FRAME_stand5 4 +#define FRAME_stand6 5 +#define FRAME_stand7 6 +#define FRAME_stand8 7 +#define FRAME_stand9 8 +#define FRAME_walk1 9 +#define FRAME_walk2 10 +#define FRAME_walk3 11 +#define FRAME_walk4 12 +#define FRAME_walk5 13 +#define FRAME_walk6 14 +#define FRAME_walk7 15 +#define FRAME_walk8 16 +#define FRAME_walk9 17 +#define FRAME_walk10 18 +#define FRAME_walk11 19 +#define FRAME_walk12 20 +#define FRAME_walk13 21 +#define FRAME_walk14 22 +#define FRAME_walk15 23 +#define FRAME_walk16 24 +#define FRAME_run1 25 +#define FRAME_run2 26 +#define FRAME_run3 27 +#define FRAME_run4 28 +#define FRAME_run5 29 +#define FRAME_run6 30 +#define FRAME_run7 31 +#define FRAME_run8 32 +#define FRAME_swing1 33 +#define FRAME_swing2 34 +#define FRAME_swing3 35 +#define FRAME_swing4 36 +#define FRAME_swing5 37 +#define FRAME_swing6 38 +#define FRAME_swing7 39 +#define FRAME_swing8 40 +#define FRAME_swing9 41 +#define FRAME_swing10 42 +#define FRAME_swing11 43 +#define FRAME_swing12 44 +#define FRAME_swing13 45 +#define FRAME_swing14 46 +#define FRAME_smash1 47 +#define FRAME_smash2 48 +#define FRAME_smash3 49 +#define FRAME_smash4 50 +#define FRAME_smash5 51 +#define FRAME_smash6 52 +#define FRAME_smash7 53 +#define FRAME_smash8 54 +#define FRAME_smash9 55 +#define FRAME_smash10 56 +#define FRAME_smash11 57 +#define FRAME_smash12 58 +#define FRAME_smash13 59 +#define FRAME_smash14 60 +#define FRAME_shoot1 61 +#define FRAME_shoot2 62 +#define FRAME_shoot3 63 +#define FRAME_shoot4 64 +#define FRAME_shoot5 65 +#define FRAME_shoot6 66 +#define FRAME_pain1 67 +#define FRAME_pain2 68 +#define FRAME_pain3 69 +#define FRAME_pain4 70 +#define FRAME_pain5 71 +#define FRAME_painb1 72 +#define FRAME_painb2 73 +#define FRAME_painb3 74 +#define FRAME_painc1 75 +#define FRAME_painc2 76 +#define FRAME_painc3 77 +#define FRAME_painc4 78 +#define FRAME_painc5 79 +#define FRAME_painc6 80 +#define FRAME_paind1 81 +#define FRAME_paind2 82 +#define FRAME_paind3 83 +#define FRAME_paind4 84 +#define FRAME_paind5 85 +#define FRAME_paind6 86 +#define FRAME_paind7 87 +#define FRAME_paind8 88 +#define FRAME_paind9 89 +#define FRAME_paind10 90 +#define FRAME_paind11 91 +#define FRAME_paind12 92 +#define FRAME_paind13 93 +#define FRAME_paind14 94 +#define FRAME_paind15 95 +#define FRAME_paind16 96 +#define FRAME_paine1 97 +#define FRAME_paine2 98 +#define FRAME_paine3 99 +#define FRAME_paine4 100 +#define FRAME_paine5 101 +#define FRAME_paine6 102 +#define FRAME_paine7 103 +#define FRAME_paine8 104 +#define FRAME_paine9 105 +#define FRAME_paine10 106 +#define FRAME_paine11 107 +#define FRAME_paine12 108 +#define FRAME_paine13 109 +#define FRAME_paine14 110 +#define FRAME_paine15 111 +#define FRAME_death1 112 +#define FRAME_death2 113 +#define FRAME_death3 114 +#define FRAME_death4 115 +#define FRAME_death5 116 +#define FRAME_death6 117 +#define FRAME_death7 118 +#define FRAME_death8 119 +#define FRAME_death9 120 +#define FRAME_death10 121 +#define FRAME_death11 122 +#define FRAME_death12 123 +#define FRAME_death13 124 +#define FRAME_death14 125 +#define FRAME_bdeath1 126 +#define FRAME_bdeath2 127 +#define FRAME_bdeath3 128 +#define FRAME_bdeath4 129 +#define FRAME_bdeath5 130 +#define FRAME_bdeath6 131 +#define FRAME_bdeath7 132 +#define FRAME_bdeath8 133 +#define FRAME_bdeath9 134 +#define FRAME_bdeath10 135 +#define FRAME_pull1 136 +#define FRAME_pull2 137 +#define FRAME_pull3 138 +#define FRAME_pull4 139 +#define FRAME_pull5 140 +#define FRAME_pull6 141 +#define FRAME_pull7 142 +#define FRAME_pull8 143 +#define FRAME_pull9 144 +#define FRAME_pull10 145 +#define FRAME_pull11 146 + +#define MODEL_SCALE 1.000000 \ No newline at end of file diff --git a/missionpack/m_q1rotfish.c b/missionpack/m_q1rotfish.c new file mode 100644 index 0000000..d00c513 --- /dev/null +++ b/missionpack/m_q1rotfish.c @@ -0,0 +1,299 @@ +/* +============================================================================== + +QUAKE ROTFISH + +============================================================================== +*/ + +#include "g_local.h" +#include "m_q1rotfish.h" + +#define Q1_FISH_RUN_SPEED 12 +#define Q1_FISH_WALK_SPEED 8 +#define Q1_FISH_MELEE_DISTANCE 60 + +static int sound_chomp; +static int sound_death; +static int sound_idle; + +void q1rotfish_idle (edict_t *self) +{ + if (random() < 0.5) + gi.sound (self, CHAN_AUTO, sound_idle, 1, ATTN_IDLE, 0); +} + +void q1rotfish_stand (edict_t *self); + +mframe_t q1rotfish_frames_stand [] = +{ + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL +}; +mmove_t q1rotfish_move_stand = {FRAME_swim1, FRAME_swim18, q1rotfish_frames_stand, NULL}; + +void q1rotfish_stand (edict_t *self) +{ + self->monsterinfo.currentmove = &q1rotfish_move_stand; +} + +mframe_t q1rotfish_frrun_loop [] = +{ + ai_run, Q1_FISH_RUN_SPEED, NULL, + ai_run, Q1_FISH_RUN_SPEED, NULL, + ai_run, Q1_FISH_RUN_SPEED, NULL, + ai_run, Q1_FISH_RUN_SPEED, NULL, + ai_run, Q1_FISH_RUN_SPEED, NULL, + ai_run, Q1_FISH_RUN_SPEED, NULL, + ai_run, Q1_FISH_RUN_SPEED, NULL, + ai_run, Q1_FISH_RUN_SPEED, NULL, + ai_run, Q1_FISH_RUN_SPEED, NULL, + ai_run, Q1_FISH_RUN_SPEED, NULL, + ai_run, Q1_FISH_RUN_SPEED, NULL, + ai_run, Q1_FISH_RUN_SPEED, NULL, + ai_run, Q1_FISH_RUN_SPEED, NULL, + ai_run, Q1_FISH_RUN_SPEED, NULL, + ai_run, Q1_FISH_RUN_SPEED, NULL, + ai_run, Q1_FISH_RUN_SPEED, NULL, + ai_run, Q1_FISH_RUN_SPEED, NULL, + ai_run, Q1_FISH_RUN_SPEED, NULL +}; +mmove_t q1rotfish_move_run_loop = {FRAME_swim1, FRAME_swim18, q1rotfish_frrun_loop, NULL}; + +void q1rotfish_run (edict_t *self) +{ + self->monsterinfo.currentmove = &q1rotfish_move_run_loop; +} + +/* Standard Swimming */ +mframe_t q1rotfish_walk_loop [] = +{ + ai_walk, Q1_FISH_WALK_SPEED, NULL, + ai_walk, Q1_FISH_WALK_SPEED, NULL, + ai_walk, Q1_FISH_WALK_SPEED, NULL, + ai_walk, Q1_FISH_WALK_SPEED, NULL, + ai_walk, Q1_FISH_WALK_SPEED, NULL, + ai_walk, Q1_FISH_WALK_SPEED, NULL, + ai_walk, Q1_FISH_WALK_SPEED, NULL, + ai_walk, Q1_FISH_WALK_SPEED, NULL, + ai_walk, Q1_FISH_WALK_SPEED, NULL, + ai_walk, Q1_FISH_WALK_SPEED, NULL, + ai_walk, Q1_FISH_WALK_SPEED, NULL, + ai_walk, Q1_FISH_WALK_SPEED, NULL, + ai_walk, Q1_FISH_WALK_SPEED, NULL, + ai_walk, Q1_FISH_WALK_SPEED, NULL, + ai_walk, Q1_FISH_WALK_SPEED, NULL, + ai_walk, Q1_FISH_WALK_SPEED, NULL, + ai_walk, Q1_FISH_WALK_SPEED, NULL, + ai_walk, Q1_FISH_WALK_SPEED, NULL +}; +mmove_t q1rotfish_move_walk_loop = {FRAME_swim1, FRAME_swim18, q1rotfish_walk_loop, NULL}; + +void q1rotfish_walk (edict_t *self) +{ + self->monsterinfo.currentmove = &q1rotfish_move_walk_loop; +} + +mframe_t q1rotfish_frames_pain1 [] = +{ + 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 q1rotfish_move_pain1 = {FRAME_pain1, FRAME_pain9, q1rotfish_frames_pain1, q1rotfish_run}; + +void q1rotfish_bite (edict_t *self) +{ + vec3_t aim; + + if (!self->enemy) + return; + + VectorSet (aim, Q1_FISH_MELEE_DISTANCE, 0, 0); + + gi.sound (self, CHAN_WEAPON, sound_chomp, 1, ATTN_NORM, 0); + fire_hit (self, aim, (random() + random()) * 3, 0); +} + +mframe_t q1rotfish_frames_attack [] = +{ + ai_charge, 10, NULL, + ai_charge, 10, NULL, + ai_charge, 0, q1rotfish_bite, + ai_charge, 10, NULL, + ai_charge, 10, NULL, + ai_charge, 10, NULL, + ai_charge, 10, NULL, + ai_charge, 10, NULL, + ai_charge, 0, q1rotfish_bite, + ai_charge, 10, NULL, + ai_charge, 10, NULL, + ai_charge, 10, NULL, + ai_charge, 10, NULL, + ai_charge, 10, NULL, + ai_charge, 0, q1rotfish_bite, + ai_charge, 10, NULL, + ai_charge, 10, NULL, + ai_charge, 10, NULL, +}; +mmove_t q1rotfish_move_attack = {FRAME_attack1, FRAME_attack18, q1rotfish_frames_attack, q1rotfish_run}; + +void q1rotfish_melee(edict_t *self) +{ + self->monsterinfo.currentmove = &q1rotfish_move_attack; +} + +void q1rotfish_pain (edict_t *self, edict_t *other, float kick, int damage) +{ + self->monsterinfo.currentmove = &q1rotfish_move_pain1; +} + +void q1rotfish_dead (edict_t *self) +{ + VectorSet (self->mins, -16, -16, -24); + VectorSet (self->maxs, 16, 16, -8); + self->gib_health = -10000; + self->movetype = MOVETYPE_TOSS; + self->svflags |= SVF_DEADMONSTER; + gi.linkentity (self); +} + +mframe_t q1rotfish_frames_death [] = +{ + 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, 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 q1rotfish_move_death = {FRAME_death1, FRAME_death21, q1rotfish_frames_death, q1rotfish_dead}; + +void q1rotfish_sight (edict_t *self, edict_t *other) +{ +} + +void q1rotfish_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) +{ + if (self->deadflag == DEAD_DEAD) + return; + +// regular death + gi.sound (self, CHAN_VOICE, sound_death, 1, ATTN_NORM, 0); + self->deadflag = DEAD_DEAD; + self->takedamage = DAMAGE_YES; + self->movetype = MOVETYPE_TOSS; + + self->monsterinfo.currentmove = &q1rotfish_move_death; +} + + +// +// SPAWN +// + +/*QUAKED monster_q1_rotfish (1 .5 0) (-16 -16 -24) (16 16 24) Ambush Trigger_Spawn Sight +model="models/monsters/q1rotfish/tris.md2" +*/ +void SP_monster_q1_rotfish (edict_t *self) +{ + if (deathmatch->value) + { + G_FreeEdict (self); + return; + } + + sound_death = gi.soundindex ("q1rotfish/death.wav"); + sound_chomp = gi.soundindex ("q1rotfish/bite.wav"); + sound_idle = gi.soundindex ("q1rotfish/idle.wav"); + + self->movetype = MOVETYPE_STEP; + self->solid = SOLID_BBOX; + + // Lazarus: special purpose skins + if ( self->style ) + { + PatchMonsterModel("models/monsters/q1rotfish/tris.md2"); + self->s.skinnum = self->style * 2; + } + + self->s.modelindex = gi.modelindex ("models/monsters/q1rotfish/tris.md2"); + VectorSet (self->mins, -16, -16, -24); + VectorSet (self->maxs, 16, 16, 24); + + if (!self->health) + self->health = 25; +// if (!self->gib_health) + self->gib_health = 0; + if (!self->mass) + self->mass = 100; + + self->pain = q1rotfish_pain; + self->die = q1rotfish_die; + + self->flags |= FL_Q1_MONSTER; + + self->monsterinfo.stand = q1rotfish_stand; + self->monsterinfo.walk = q1rotfish_walk; + self->monsterinfo.run = q1rotfish_run; + self->monsterinfo.melee = q1rotfish_melee; + self->monsterinfo.sight = q1rotfish_sight; + + if (!self->monsterinfo.flies) + self->monsterinfo.flies = 0.95; + + // Lazarus + if (self->powerarmor) + { + if (self->powerarmortype == 1) + self->monsterinfo.power_armor_type = POWER_ARMOR_SCREEN; + else + self->monsterinfo.power_armor_type = POWER_ARMOR_SHIELD; + self->monsterinfo.power_armor_power = self->powerarmor; + } + self->common_name = "Rotfish"; + + gi.linkentity (self); + + self->monsterinfo.currentmove = &q1rotfish_move_stand; + self->monsterinfo.scale = 1.000000; + + swimmonster_start (self); +} diff --git a/missionpack/m_q1rotfish.h b/missionpack/m_q1rotfish.h new file mode 100644 index 0000000..757ea77 Binary files /dev/null and b/missionpack/m_q1rotfish.h differ diff --git a/missionpack/m_q1scrag.c b/missionpack/m_q1scrag.c new file mode 100644 index 0000000..42a4304 --- /dev/null +++ b/missionpack/m_q1scrag.c @@ -0,0 +1,409 @@ +/* +============================================================================== + +QUAKE SCRAG + +============================================================================== +*/ + +#include "g_local.h" +#include "m_q1scrag.h" + +qboolean visible (edict_t *self, edict_t *other); +void q1_fire_acidspit (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed); +qboolean monster_start (edict_t *self); + +static int sound_sight; +static int sound_idle1; +static int sound_idle2; +static int sound_attack; +static int sound_die; +static int sound_pain; +static int sound_hit; + + +void scrag_sight (edict_t *self, edict_t *other) +{ + gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0); +} + +void scrag_attack_sound(edict_t *self) +{ + gi.sound (self, CHAN_VOICE, sound_attack, 1, ATTN_NORM, 0); //WAS ATTN_IDLE +} + +void scrag_idle (edict_t *self) +{ + float wr; + + wr = random() * 5; + if (level.time > self->wait) + { + self->wait = level.time + 2; + if (wr > 4.5) + gi.sound (self, CHAN_VOICE, sound_idle1, 1, ATTN_IDLE, 0); + if (wr < 1.5) + gi.sound (self, CHAN_VOICE, sound_idle2, 1, ATTN_IDLE, 0); + } +} + + +mframe_t scrag_frames_stand [] = +{ + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, scrag_idle +}; +mmove_t scrag_move_stand = {FRAME_hover1, FRAME_hover15, scrag_frames_stand, NULL}; + +void scrag_stand (edict_t *self) +{ + self->monsterinfo.currentmove = &scrag_move_stand; +} + + +mframe_t scrag_frames_walk [] = +{ + ai_walk, 6, scrag_idle, + ai_walk, 6, NULL, + ai_walk, 6, NULL, + ai_walk, 6, NULL, + ai_walk, 6, NULL, + ai_walk, 6, NULL, + ai_walk, 6, NULL, + ai_walk, 6, NULL, + ai_walk, 6, NULL, + ai_walk, 6, NULL, + ai_walk, 6, NULL, + ai_walk, 6, NULL, + ai_walk, 6, NULL, + ai_walk, 6, NULL, + ai_walk, 6, NULL +}; +mmove_t scrag_move_walk = {FRAME_hover1, FRAME_hover15, scrag_frames_walk, NULL}; + +void scrag_walk (edict_t *self) +{ + self->monsterinfo.currentmove = &scrag_move_walk; +} + + +void scrag_run (edict_t *self); + +mframe_t scrag_frames_run [] = +{ + ai_run, 12, scrag_idle, + ai_run, 12, NULL, + ai_run, 12, NULL, + ai_run, 12, NULL, + ai_run, 12, NULL, + ai_run, 12, NULL, + ai_run, 12, NULL, + ai_run, 12, NULL, + ai_run, 12, NULL, + ai_run, 12, NULL, + ai_run, 12, NULL, + ai_run, 12, NULL, + ai_run, 12, NULL, + ai_run, 12, NULL +}; +mmove_t scrag_move_run = {FRAME_fly1, FRAME_fly14, scrag_frames_run, scrag_run}; + + +void scrag_run (edict_t *self) +{ + if (self->monsterinfo.aiflags & AI_STAND_GROUND) + self->monsterinfo.currentmove = &scrag_move_stand; + else + self->monsterinfo.currentmove = &scrag_move_run; +} + + + + + + +mframe_t scrag_frames_pain [] = +{ + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL +}; +mmove_t scrag_move_pain = {FRAME_pain1, FRAME_pain4, scrag_frames_pain, scrag_run}; + + +void scrag_pain (edict_t *self, edict_t *other, float kick, int damage) +{ + if (level.time < self->pain_debounce_time) + return; + + self->pain_debounce_time = level.time + 2; + if (skill->value == 3) + return; // no pain anims in nightmare + + if(self->health > 0) + gi.sound (self, CHAN_VOICE, sound_pain, 1, ATTN_NORM, 0); + self->monsterinfo.currentmove = &scrag_move_pain; +} + +void scrag_dead(edict_t * self) +{ + VectorSet (self->mins, -16, -16, -24); + VectorSet (self->maxs, 16, 16, -8); + self->movetype = MOVETYPE_TOSS; + self->svflags |= SVF_DEADMONSTER; + self->nextthink = 0; + gi.linkentity (self); + + M_FlyCheck (self); +} + +void scrag_nogib (edict_t *self) +{ + self->gib_health = -10000; +} + +mframe_t scrag_frames_die [] = +{ + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, scrag_nogib, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL +}; +mmove_t scrag_move_die = {FRAME_death1, FRAME_death8, scrag_frames_die, scrag_dead}; + + +void scrag_die(edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) +{ + int n; +// check for gib + + if (self->health <= self->gib_health && !(self->spawnflags & SF_MONSTER_NOGIB)) + { + gi.sound (self, CHAN_VOICE|CHAN_RELIABLE, gi.soundindex ("q1monstr/udeath.wav"), 1, ATTN_NORM, 0); + + for (n= 0; n < 3; n++) + ThrowGib (self, "models/objects/q1gibs/q1gib2/tris.md2", damage, GIB_ORGANIC); + ThrowHead (self, "models/monsters/q1scrag/head/tris.md2", damage, GIB_ORGANIC); + self->deadflag = DEAD_DEAD; + return; + } + + if (self->deadflag == DEAD_DEAD) + return; + +// regular death + self->deadflag = DEAD_DEAD; + self->takedamage = DAMAGE_YES; + + gi.sound (self, CHAN_VOICE, sound_die, 1, ATTN_NORM, 0); + self->monsterinfo.currentmove = &scrag_move_die; +} + + +void scrag_fire (edict_t *self) +{ + vec3_t forward, right, start; + vec3_t end, dir; + + if(!self->enemy) + return; + +// gi.sound (self, CHAN_VOICE, sound_attack, 1, ATTN_NORM, 0); + +//fire 1 + AngleVectors (self->s.angles, forward, right, NULL); + G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_FLYER_BLASTER_1], forward, right, start); + + start[2] += 48; //was 32 + + VectorCopy (self->enemy->s.origin, end); + end[2] += self->enemy->viewheight; + VectorSubtract (end, start, dir); + VectorNormalize (dir); + +/* gi.WriteByte (svc_muzzleflash2); + gi.WriteShort (self - g_edicts); + gi.WriteByte (MZ2_FLYER_BLASTER_1); + gi.multicast (start, MULTICAST_PVS); +*/ + q1_fire_acidspit(self,start, dir, 9, 500); + +// fire 2 +/* AngleVectors (self->s.angles, forward, right, NULL); + G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_FLYER_BLASTER_2], forward, right, start); + + start[2]+=32; + + VectorCopy (self->enemy->s.origin, end); + end[2] += self->enemy->viewheight; + VectorSubtract (end, start, dir); + + VectorNormalize (dir); + +/* gi.WriteByte (svc_muzzleflash2); + gi.WriteShort (self - g_edicts); + gi.WriteByte (MZ2_FLYER_BLASTER_2); + gi.multicast (start, MULTICAST_PVS); +*/ +// q1_fire_acidspit(self,start, dir, 9, 500); +} + +void scrag_fire2 (edict_t *self) +{ + vec3_t forward, right, start; + vec3_t end, dir; + + if(!self->enemy) + return; + +// gi.sound (self, CHAN_VOICE, sound_attack, 1, ATTN_NORM, 0); + +// fire 2 + AngleVectors (self->s.angles, forward, right, NULL); + G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_FLYER_BLASTER_2], forward, right, start); +// + start[2] += 64; //was 32 + + VectorCopy (self->enemy->s.origin, end); + end[2] += self->enemy->viewheight; + VectorSubtract (end, start, dir); + + VectorNormalize (dir); + +/* gi.WriteByte (svc_muzzleflash2); + gi.WriteShort (self - g_edicts); + gi.WriteByte (MZ2_FLYER_BLASTER_2); + gi.multicast (start, MULTICAST_PVS); +*/ + q1_fire_acidspit(self,start, dir, 9, 500); +} + + +mframe_t scrag_frames_attack [] = +{ + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, scrag_attack_sound, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, -1,scrag_fire, + ai_charge, -2,NULL, + ai_charge, -3,NULL, + ai_charge, -2,NULL, //scrag_fire + ai_charge, -1,NULL, + ai_charge, 0, scrag_fire2, //scrag_fire + ai_charge, 0, NULL, + ai_charge, 0, NULL +}; + +mmove_t scrag_move_attack = {FRAME_magatt1, FRAME_magatt13, scrag_frames_attack, scrag_run}; + +void scrag_attack (edict_t *self) +{ + self->monsterinfo.currentmove = &scrag_move_attack; +} + + +// +// SPAWN +// + +/*QUAKED monster_q1_scrag (1 .5 0) (-16 -16 -24) (16 16 40) Ambush Trigger_Spawn Sight +model="models/monsters/q1scrag/tris.md2" +*/ +void SP_monster_q1_scrag (edict_t *self) +{ + if (deathmatch->value) + { + G_FreeEdict (self); + return; + } + + sound_sight = gi.soundindex ("q1scrag/wsight.wav"); + sound_idle1 = gi.soundindex ("q1scrag/widle1.wav"); + sound_idle2 = gi.soundindex ("q1scrag/widle2.wav"); + sound_attack = gi.soundindex ("q1scrag/wattack.wav"); + sound_die = gi.soundindex ("q1scrag/wdeath.wav"); + sound_pain = gi.soundindex ("q1scrag/wpain.wav"); + sound_hit = gi.soundindex ("q1scrag/hit.wav"); + + self->movetype = MOVETYPE_STEP; + self->solid = SOLID_BBOX; + + // Lazarus: special purpose skins + if ( self->style ) + { + PatchMonsterModel("models/monsters/q1scrag/tris.md2"); + self->s.skinnum = self->style * 2; + } + + self->s.modelindex = gi.modelindex ("models/monsters/q1scrag/tris.md2"); + VectorSet (self->mins, -16, -16, -24); + VectorSet (self->maxs, 16, 16, 40); + + if (!self->health) + self->health = 80; + if (!self->gib_health) + self->gib_health = -40; + if (!self->mass) + self->mass = 50; + + self->pain = scrag_pain; + self->die = scrag_die; + + self->flags |= FL_Q1_MONSTER; + + self->monsterinfo.stand = scrag_stand; + self->monsterinfo.walk = scrag_walk; + self->monsterinfo.run = scrag_run; + self->monsterinfo.attack = scrag_attack; + self->monsterinfo.melee = NULL; + self->monsterinfo.sight = scrag_sight; + self->monsterinfo.idle = scrag_walk; + + if (!self->monsterinfo.flies) + self->monsterinfo.flies = 0.50; + + // Lazarus + if (self->powerarmor) + { + if (self->powerarmortype == 1) + self->monsterinfo.power_armor_type = POWER_ARMOR_SCREEN; + else + self->monsterinfo.power_armor_type = POWER_ARMOR_SHIELD; + self->monsterinfo.power_armor_power = self->powerarmor; + } + self->common_name = "Scrag"; + + gi.linkentity (self); + + self->monsterinfo.currentmove = &scrag_move_stand; + self->monsterinfo.scale = MODEL_SCALE; + + + self->flags |= FL_FLY; + if (!self->yaw_speed) + self->yaw_speed = 10; + self->viewheight = 10; + +// monster_start (self); + flymonster_start (self); +} diff --git a/missionpack/m_q1scrag.h b/missionpack/m_q1scrag.h new file mode 100644 index 0000000..21ba571 --- /dev/null +++ b/missionpack/m_q1scrag.h @@ -0,0 +1,59 @@ +// Generated by ModelEd +// SCRAG + +#define FRAME_hover1 0 +#define FRAME_hover2 1 +#define FRAME_hover3 2 +#define FRAME_hover4 3 +#define FRAME_hover5 4 +#define FRAME_hover6 5 +#define FRAME_hover7 6 +#define FRAME_hover8 7 +#define FRAME_hover9 8 +#define FRAME_hover10 9 +#define FRAME_hover11 10 +#define FRAME_hover12 11 +#define FRAME_hover13 12 +#define FRAME_hover14 13 +#define FRAME_hover15 14 +#define FRAME_fly1 15 +#define FRAME_fly2 16 +#define FRAME_fly3 17 +#define FRAME_fly4 18 +#define FRAME_fly5 19 +#define FRAME_fly6 20 +#define FRAME_fly7 21 +#define FRAME_fly8 22 +#define FRAME_fly9 23 +#define FRAME_fly10 24 +#define FRAME_fly11 25 +#define FRAME_fly12 26 +#define FRAME_fly13 27 +#define FRAME_fly14 28 +#define FRAME_magatt1 29 +#define FRAME_magatt2 30 +#define FRAME_magatt3 31 +#define FRAME_magatt4 32 +#define FRAME_magatt5 33 +#define FRAME_magatt6 34 +#define FRAME_magatt7 35 +#define FRAME_magatt8 36 +#define FRAME_magatt9 37 +#define FRAME_magatt10 38 +#define FRAME_magatt11 39 +#define FRAME_magatt12 40 +#define FRAME_magatt13 41 +#define FRAME_pain1 42 +#define FRAME_pain2 43 +#define FRAME_pain3 44 +#define FRAME_pain4 45 +#define FRAME_death1 46 +#define FRAME_death2 47 +#define FRAME_death3 48 +#define FRAME_death4 49 +#define FRAME_death5 50 +#define FRAME_death6 51 +#define FRAME_death7 52 +#define FRAME_death8 53 + +#define MODEL_SCALE 1.000000 \ No newline at end of file diff --git a/missionpack/m_q1shalrath.c b/missionpack/m_q1shalrath.c new file mode 100644 index 0000000..f358c4d --- /dev/null +++ b/missionpack/m_q1shalrath.c @@ -0,0 +1,340 @@ +/* +============================================================================== + +QUAKE SHALRATH + +============================================================================== +*/ + +#include "g_local.h" +#include "m_q1shalrath.h" + +static int sound_death; +static int sound_sight; +static int sound_pain1; +static int sound_attack; +static int sound_idle; + + +// STAND +void q1shalrath_idle (edict_t *self) +{ + if (random() < 0.2) + gi.sound (self, CHAN_BODY, sound_idle, 1, ATTN_IDLE, 0); +} + +void q1shalrath_stand (edict_t *self); + +mframe_t q1shalrath_frames_stand [] = +{ + ai_stand, 0, NULL +}; +mmove_t q1shalrath_move_stand = {FRAME_walk1, FRAME_walk1, q1shalrath_frames_stand, q1shalrath_stand}; + +void q1shalrath_stand (edict_t *self) +{ + self->monsterinfo.currentmove = &q1shalrath_move_stand; +} + + +// +// WALK +// + +mframe_t q1shalrath_frames_walk [] = +{ + ai_walk, 6, q1shalrath_idle, + ai_walk, 4, NULL, + ai_walk, 0, NULL, + ai_walk, 0, NULL, + ai_walk, 0, NULL, + ai_walk, 0, NULL, + ai_walk, 5, NULL, + ai_walk, 6, NULL, + ai_walk, 5, NULL, + ai_walk, 0, NULL, + ai_walk, 4, NULL, + ai_walk, 5, NULL +}; +mmove_t q1shalrath_move_walk = {FRAME_walk1, FRAME_walk12, q1shalrath_frames_walk, NULL}; + +void q1shalrath_walk (edict_t *self) +{ + self->monsterinfo.currentmove = &q1shalrath_move_walk; +} + + +// +// RUN +// + +void q1shalrath_run (edict_t *self); + +mframe_t q1shalrath_frames_run [] = +{ + ai_run, 6, q1shalrath_idle, + ai_run, 4, NULL, + ai_run, 0, NULL, + ai_run, 0, NULL, + ai_run, 0, NULL, + ai_run, 0, NULL, + ai_run, 5, NULL, + ai_run, 6, NULL, + ai_run, 5, NULL, + ai_run, 0, NULL, + ai_run, 4, NULL, + ai_run, 5, NULL +}; +mmove_t q1shalrath_move_run = {FRAME_walk1, FRAME_walk12, q1shalrath_frames_run, q1shalrath_run}; + +void q1shalrath_run (edict_t *self) +{ + if (self->monsterinfo.aiflags & AI_STAND_GROUND) + { + self->monsterinfo.currentmove = &q1shalrath_move_stand; + return; + } + else + self->monsterinfo.currentmove = &q1shalrath_move_run; +} + +// +// PAIN +// + +mframe_t q1shalrath_frames_pain1 [] = +{ + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL +}; +mmove_t q1shalrath_move_pain1 = {FRAME_pain1, FRAME_pain5, q1shalrath_frames_pain1, q1shalrath_run}; + +void q1shalrath_pain (edict_t *self, edict_t *other, float kick, int damage) +{ + float r; + + if (level.time < self->pain_debounce_time) + return; + + r = random(); + + self->monsterinfo.currentmove = &q1shalrath_move_pain1; + gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0); + self->pain_debounce_time = level.time + 3; +} + + +// +// ATTACK +// + +void q1shalrath_fire (edict_t *self) +{ + vec3_t start; + vec3_t forward, right, up; + vec3_t aim; + vec3_t dir; + vec3_t end; + float r, u; + + if(!self->enemy) + return; + + AngleVectors (self->s.angles, forward, right, NULL); + G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_SOLDIER_SHOTGUN_1], forward, right, start); + + VectorCopy (self->enemy->s.origin, end); + end[2] += self->enemy->viewheight; + VectorSubtract (end, start, aim); + vectoangles (aim, dir); + AngleVectors (dir, forward, right, up); + + r = crandom()*1000; + u = crandom()*500; + VectorMA (start, 8192, forward, end); + VectorMA (end, r, right, end); + VectorMA (end, u, up, end); + + VectorSubtract (end, start, aim); + VectorNormalize (aim); + + gi.sound (self, CHAN_WEAPON|CHAN_RELIABLE, gi.soundindex("shalrath/attack2.wav"), 1, ATTN_NORM, 0); + q1_fire_firepod (self, aim); +} + +void q1shalrath_attack_snd (edict_t *self) +{ + gi.sound (self, CHAN_AUTO, sound_attack, 1, ATTN_NORM, 0); +} + +mframe_t q1shalrath_frames_attack [] = +{ + ai_charge, 0, q1shalrath_attack_snd, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, q1shalrath_fire, + ai_charge, 0, NULL +}; +mmove_t q1shalrath_move_attack = {FRAME_attack1, FRAME_attack11, q1shalrath_frames_attack, q1shalrath_run}; + +void q1shalrath_attack(edict_t *self) +{ + self->monsterinfo.currentmove = &q1shalrath_move_attack; +} + + +// +// SIGHT +// + +void q1shalrath_sight(edict_t *self, edict_t *other) +{ + gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0); +} + + +// +// DEATH +// + +void q1shalrath_dead (edict_t *self) +{ + VectorSet (self->mins, -16, -16, -24); + VectorSet (self->maxs, 16, 16, -8); + self->movetype = MOVETYPE_TOSS; + self->svflags |= SVF_DEADMONSTER; + self->nextthink = 0; + self->takedamage = DAMAGE_NO; + self->solid = SOLID_NOT; + gi.linkentity (self); +} + +void q1shalrath_nogib (edict_t *self) +{ + self->gib_health = -10000; +} + +mframe_t q1shalrath_frames_death1 [] = +{ + ai_move, 0, NULL, + ai_move, 0, q1shalrath_nogib, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL +}; +mmove_t q1shalrath_move_death = {FRAME_death1, FRAME_death7, q1shalrath_frames_death1, q1shalrath_dead}; + +void q1shalrath_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) +{ + int n; +// check for gib + if (self->health <= self->gib_health && !(self->spawnflags & SF_MONSTER_NOGIB)) + { + gi.sound (self, CHAN_VOICE|CHAN_RELIABLE, gi.soundindex ("q1monstr/udeath.wav"), 1, ATTN_NORM, 0); + + for (n = 0; n < 2; n++) + ThrowGib (self, "models/objects/q1gibs/q1gib1/tris.md2", damage, GIB_ORGANIC); + ThrowGib (self, "models/objects/q1gibs/q1gib2/tris.md2", damage, GIB_ORGANIC); + ThrowHead (self, "models/monsters/q1shalrath/head/tris.md2", damage, GIB_ORGANIC); + self->deadflag = DEAD_DEAD; + return; + } + + if (self->deadflag == DEAD_DEAD) + return; + +// regular death + self->deadflag = DEAD_DEAD; + self->takedamage = DAMAGE_YES; + + gi.sound (self, CHAN_VOICE, sound_death, 1, ATTN_NORM, 0); + self->monsterinfo.currentmove = &q1shalrath_move_death; +} + + +// +// SPAWN +// + +/*QUAKED monster_q1_shalrath (1 .5 0) (-16 -16 -24) (16 16 40) Ambush Trigger_Spawn Sight +model="models/monsters/q1shalrath/tris.md2" +*/ +void SP_monster_q1_shalrath (edict_t *self) +{ + if (deathmatch->value) + { + G_FreeEdict (self); + return; + } + + sound_sight = gi.soundindex ("q1shalrath/sight.wav"); + sound_pain1 = gi.soundindex ("q1shalrath/pain.wav"); + sound_death = gi.soundindex ("q1shalrath/death.wav"); + sound_attack = gi.soundindex ("q1shalrath/attack.wav"); + sound_idle = gi.soundindex ("q1shalrath/idle.wav"); + + self->movetype = MOVETYPE_STEP; + self->solid = SOLID_BBOX; + + // Lazarus: special purpose skins + if ( self->style ) + { + PatchMonsterModel("models/monsters/q1shalrath/tris.md2"); + self->s.skinnum = self->style * 2; + } + + self->s.modelindex = gi.modelindex ("models/monsters/q1shalrath/tris.md2"); + VectorSet (self->mins, -32, -32, -24); + VectorSet (self->maxs, 32, 32, 48); + + if (!self->health) + self->health = 400; + if (!self->gib_health) + self->gib_health = -90; + if (!self->mass) + self->mass = 125; + + self->pain = q1shalrath_pain; + self->die = q1shalrath_die; + + self->flags |= FL_Q1_MONSTER; + + self->monsterinfo.stand = q1shalrath_stand; + self->monsterinfo.walk = q1shalrath_walk; + self->monsterinfo.run = q1shalrath_run; + self->monsterinfo.attack = q1shalrath_attack; + self->monsterinfo.melee = NULL; + self->monsterinfo.sight = q1shalrath_sight; + + if (!self->monsterinfo.flies) + self->monsterinfo.flies = 0.40; + + // Lazarus + if (self->powerarmor) + { + if (self->powerarmortype == 1) + self->monsterinfo.power_armor_type = POWER_ARMOR_SCREEN; + else + self->monsterinfo.power_armor_type = POWER_ARMOR_SHIELD; + self->monsterinfo.power_armor_power = self->powerarmor; + } + self->common_name = "Vore"; + + gi.linkentity (self); + + self->monsterinfo.currentmove = &q1shalrath_move_stand; + self->monsterinfo.scale = 1.000000; + + walkmonster_start (self); +} \ No newline at end of file diff --git a/missionpack/m_q1shalrath.h b/missionpack/m_q1shalrath.h new file mode 100644 index 0000000..07f9c59 Binary files /dev/null and b/missionpack/m_q1shalrath.h differ diff --git a/missionpack/m_q1shambler.c b/missionpack/m_q1shambler.c new file mode 100644 index 0000000..5bfc252 --- /dev/null +++ b/missionpack/m_q1shambler.c @@ -0,0 +1,585 @@ +/* +============================================================================== + +QUAKE SHAMBLER + +============================================================================== +*/ + +#include "g_local.h" +#include "m_q1shambler.h" + + +static int sound_melee1; +static int sound_melee2; +static int sound_melee3; +static int sound_attack; +static int sound_boom; // ? +static int sound_pain; +static int sound_death; +static int sound_idle; +static int sound_sight; + +void shambler_attack(edict_t *self); + +void shambler_sight (edict_t *self, edict_t *other) +{ + gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0); + shambler_attack(self); +} + +/*static*/ void shambler_idle_sound (edict_t *self) +{ + if(!self->enemy && random() > 0.8) + gi.sound (self, CHAN_VOICE, sound_idle, 0.8, ATTN_IDLE, 0); +} + +/*static*/ void shambler_melee_sound (edict_t *self) +{ + gi.sound (self, CHAN_VOICE, sound_melee1, 1, ATTN_NORM, 0); +} + +/*static*/ void shambler_melee_sound2 (edict_t *self) +{ + gi.sound (self, CHAN_VOICE, sound_melee2, 1, ATTN_NORM, 0); +} + +/*static*/ void shambler_attack_sound (edict_t *self) +{ + gi.sound (self, CHAN_VOICE, sound_attack, 1, ATTN_NORM, 0); +} + +// STAND + +void shambler_stand (edict_t *self); + +mframe_t shambler_frames_stand [] = +{ + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL +}; + +mmove_t shambler_move_stand = {FRAME_stand1, FRAME_stand17, shambler_frames_stand, shambler_stand}; + +void shambler_stand (edict_t *self) +{ + self->monsterinfo.currentmove = &shambler_move_stand; +} + +// WALK + +void shambler_walk (edict_t *self); + +mframe_t shambler_frames_walk [] = +{ + ai_walk, 10, shambler_idle_sound, + ai_walk, 9, NULL, + ai_walk, 9, NULL, + ai_walk, 5, NULL, + ai_walk, 6, NULL, + ai_walk, 12, NULL, + ai_walk, 8, NULL, + ai_walk, 3, NULL, + ai_walk, 13, NULL, + ai_walk, 9, NULL, + ai_walk, 7, NULL, + ai_walk, 7, NULL +}; +mmove_t shambler_move_walk = {FRAME_walk1, FRAME_walk12, shambler_frames_walk, shambler_walk}; + +void shambler_walk (edict_t *self) +{ + self->monsterinfo.currentmove = &shambler_move_walk; +} + +//RUN + +void shambler_run (edict_t *self); + +mframe_t shambler_frames_run [] = +{ + ai_run, 20, shambler_idle_sound, + ai_run, 24, NULL, + ai_run, 20, NULL, + ai_run, 20, NULL, + ai_run, 24, NULL, + ai_run, 20, shambler_attack +}; + +mmove_t shambler_move_run = {FRAME_run1, FRAME_run6, shambler_frames_run, shambler_run}; + +void shambler_run (edict_t *self) +{ + if (self->monsterinfo.aiflags & AI_STAND_GROUND) + self->monsterinfo.currentmove = &shambler_move_stand; + else + self->monsterinfo.currentmove = &shambler_move_run; +} + + + +mframe_t shambler_frames_pain [] = +{ + 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 shambler_move_pain = {FRAME_pain1, FRAME_pain6, shambler_frames_pain, shambler_run}; + + +void shambler_pain (edict_t *self, edict_t *other, float kick, int damage) +{ + if (level.time < self->pain_debounce_time) + return; + + if (self->health <= 0) + return; + + if (skill->value == 3) + return; // no pain anims in nightmare + + if (self->health > 0) + gi.sound (self, CHAN_VOICE, sound_pain, 1, ATTN_NORM, 0); + + if(random() * 400 > damage) + return; + + self->monsterinfo.currentmove = &shambler_move_pain; + self->pain_debounce_time = level.time + 2; +} + + + +void shambler_dead (edict_t *self) +{ + VectorSet (self->mins, -16, -16, -24); + VectorSet (self->maxs, 16, 16, -8); + self->movetype = MOVETYPE_TOSS; + self->svflags |= SVF_DEADMONSTER; + self->nextthink = 0; + gi.linkentity (self); +} + +void shambler_nogib (edict_t *self) +{ + self->gib_health = -10000; +} + +mframe_t shambler_frames_death [] = +{ + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, shambler_nogib, + 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 shambler_move_death = {FRAME_death1, FRAME_death11, shambler_frames_death, shambler_dead}; + + +void shambler_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) +{ + + // check for gib + if (self->health <= self->gib_health && !(self->spawnflags & SF_MONSTER_NOGIB)) + { + gi.sound (self, CHAN_VOICE|CHAN_RELIABLE, gi.soundindex ("q1monstr/udeath.wav"), 1, ATTN_NORM, 0); + ThrowGib (self, "models/objects/q1gibs/q1gib1/tris.md2", damage, GIB_ORGANIC); + ThrowGib (self, "models/objects/q1gibs/q1gib3/tris.md2", damage, GIB_ORGANIC); + ThrowGib (self, "models/objects/q1gibs/q1gib2/tris.md2", damage, GIB_ORGANIC); + ThrowHead (self, "models/monsters/q1shambler/head/tris.md2", damage, GIB_ORGANIC); + self->deadflag = DEAD_DEAD; + return; + } + + if (self->deadflag == DEAD_DEAD) + return; + + // regular death + gi.sound (self, CHAN_VOICE, sound_death, 1, ATTN_NORM, 0); + self->deadflag = DEAD_DEAD; + self->takedamage = DAMAGE_YES; + + self->monsterinfo.currentmove = &shambler_move_death; +} + + + +// ATTACK + + +void shambler_swing_left (edict_t *self) +{ + vec3_t aim; + + if (!self->enemy) + return; + + VectorSet (aim, MELEE_DISTANCE*1.2, self->mins[0], 8); + if (fire_hit (self, aim, ((random() + random() + random()) * 20), 100)) + gi.sound (self, CHAN_VOICE, sound_melee3, 1, ATTN_NORM, 0); //WAS ATTN_IDLE +} + + +mframe_t shambler_frames_swingL [] = +{ + ai_charge, 5, shambler_melee_sound2, + ai_charge, 3, NULL, + ai_charge, 7, NULL, + ai_charge, 3, NULL, + ai_charge, 7, NULL, + ai_charge, 9, NULL, + ai_charge, 5, shambler_swing_left, + ai_charge, 4, NULL, + ai_charge, 8, shambler_attack +}; +mmove_t shambler_move_swingL_attack = {FRAME_swingl1, FRAME_swingl9, shambler_frames_swingL, shambler_run}; + +void shambler_swing_right (edict_t *self) +{ + vec3_t aim; + + if(!self->enemy) + return; + + VectorSet (aim, MELEE_DISTANCE*1.2, self->maxs[0], 8); + if (fire_hit (self, aim, ((random() + random() + random()) * 20), 100)) + gi.sound (self, CHAN_VOICE, sound_melee3, 1, ATTN_NORM, 0); //WAS ATTN_IDLE +} + +mframe_t shambler_frames_swingR [] = +{ + ai_charge, 1, shambler_melee_sound, + ai_charge, 8, NULL, + ai_charge, 14,NULL, + ai_charge, 7, NULL, + ai_charge, 3, NULL, + ai_charge, 6, NULL, + ai_charge, 6, shambler_swing_right, + ai_charge, 3, NULL, + ai_charge, 10,shambler_attack +}; +mmove_t shambler_move_swingR_attack = {FRAME_swingr1, FRAME_swingr9, shambler_frames_swingR, shambler_run}; + + +void shambler_smash (edict_t *self) +{ + vec3_t aim; + + if(!self->enemy) + return; + + VectorSet (aim, MELEE_DISTANCE*1.2, self->maxs[0], self->maxs[2]); + if (fire_hit (self, aim, ((random() + random() + random()) * 40), 100)) + gi.sound (self, CHAN_WEAPON, sound_melee3, 1, ATTN_NORM, 0); +} + +mframe_t shambler_frames_smash [] = +{ + ai_charge, 2, shambler_melee_sound, + ai_charge, 6, NULL, + ai_charge, 6, NULL, + ai_charge, 5, NULL, + ai_charge, 4, NULL, + ai_charge, 1, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, shambler_smash, + ai_charge, 5, NULL, + ai_charge, 4, shambler_attack +}; +mmove_t shambler_move_smash_attack = {FRAME_smash1, FRAME_smash12, shambler_frames_smash, shambler_run}; + + +static qboolean shambler_magic_attack_ok (vec3_t start, vec3_t end) +{ + vec3_t dir, angles; + + // check for max distance + VectorSubtract (start, end, dir); + if (VectorLength(dir) > 600) + return false; + + // check for min/max pitch + vectoangles (dir, angles); + if (angles[0] < -180) + angles[0] += 360; + if (fabs(angles[0]) > 30) + return false; + + return true; +} + +// Added from Decino's Q2Infighter code +void shambler_sparks (edict_t *self) +{ + vec3_t spark_pt; + + VectorCopy (self->s.origin, spark_pt); + spark_pt[2] += 80.0f; + + gi.WriteByte (svc_temp_entity); + gi.WriteByte (TE_WELDING_SPARKS); + gi.WriteByte (15); + gi.WritePosition (spark_pt); + gi.WriteDir (vec3_origin); + gi.WriteByte (15); + gi.multicast (spark_pt, MULTICAST_PVS); +} + + +void shambler_magic_attack (edict_t *self) +{ + vec3_t offset, start, f, r, end, dir; + trace_t tr; + int damage = 10; + + if (!self->enemy) + return; + + // Skip last lighting frame if not on nightmare skill + if ( (self->s.frame == 74) && (skill->value < 3) ) + return; + + AngleVectors (self->s.angles, f, r, NULL); + VectorSet (offset, 28, 0, 40); + G_ProjectSource (self->s.origin, offset, f, r, start); + + VectorCopy (self->enemy->s.origin, end); + if (!shambler_magic_attack_ok(start, end)) + { + end[2] = self->enemy->s.origin[2] + self->enemy->maxs[2] - 8; + if (!shambler_magic_attack_ok(start, end)) + { + end[2] = self->enemy->s.origin[2] + self->enemy->mins[2] + 8; + if (!shambler_magic_attack_ok(start, end)) + { + shambler_run(self); + return; + } + } + } + VectorCopy (self->enemy->s.origin, end); + + tr = gi.trace (start, NULL, NULL, end, self, (MASK_SHOT|CONTENTS_WATER|CONTENTS_SLIME|CONTENTS_LAVA)); + if (tr.ent != self->enemy) + return; + + if (self->s.frame == FRAME_magic6) + gi.sound (self, CHAN_WEAPON, sound_boom, 1, ATTN_NORM, 0); + +#if 1 // From Decino's Q2Infighter mod + gi.WriteByte (svc_temp_entity); + gi.WriteByte (TE_LIGHTNING); + gi.WriteShort (tr.ent - g_edicts); + gi.WriteShort (self - g_edicts); + gi.WritePosition (end); + gi.WritePosition (start); + gi.multicast (self->s.origin, MULTICAST_PVS); +#else + 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); +#endif + + VectorSubtract (start, end, dir); + T_Damage (self->enemy, self, self, dir, self->enemy->s.origin, vec3_origin, damage, 0, 0, 0); +} + + +void shambler_skill3 (edict_t *self) +{ + if (skill->value == 3) + shambler_attack(self); +} + + +mframe_t shambler_frames_magic_attack[] = +{ + ai_charge, 0, shambler_attack_sound, + ai_charge, 0, shambler_sparks, // NULL, + ai_charge, 0, shambler_sparks, // NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, shambler_magic_attack, + ai_charge, 0, shambler_magic_attack, + ai_charge, 0, shambler_magic_attack, + ai_charge, 0, shambler_magic_attack, + ai_charge, 0, shambler_magic_attack, + ai_charge, 0, shambler_skill3, + ai_charge, 0, shambler_attack +}; +mmove_t shambler_move_magic_attack = {FRAME_magic1, FRAME_magic12, shambler_frames_magic_attack, shambler_run}; + + +void shambler_attack (edict_t *self) +{ + float len; + vec3_t v; + + //int i; + //i = range (self, self->enemy); + + if (level.intermissiontime && !Q_stricmp(level.mapname, "bbelief9")) // don't attack intermission cam + return; + + if (!self->enemy || !self->enemy->inuse || self->enemy->health <= 0) + return; + + VectorSubtract (self->s.origin, self->enemy->s.origin, v); + len = VectorLength (v); + + if (len < 128) + { + if (self->health > 500 && random() > 0.6) + self->monsterinfo.currentmove = &shambler_move_smash_attack; + else + { + if (random() > 0.5) + self->monsterinfo.currentmove = &shambler_move_swingL_attack; + else + self->monsterinfo.currentmove = &shambler_move_swingR_attack; + } + } + else if((len > 196 && len < 1024) && infront(self,self->enemy)) + { + self->monsterinfo.currentmove = &shambler_move_magic_attack; + } + else + { + self->monsterinfo.currentmove = &shambler_move_run; + } +} + +void shambler_melee(edict_t *self) +{ + if (!self->enemy || !self->enemy->inuse || self->enemy->health <= 0) + { + // if(random() > 0.5) + // self->monsterinfo.currentmove = &shambler_move_walk; + return; + } + + if (range (self, self->enemy) == RANGE_MELEE) + { + if (self->health > 500 && random() > 0.6) + self->monsterinfo.currentmove = &shambler_move_smash_attack; + else + { + if(random() > 0.5) + self->monsterinfo.currentmove = &shambler_move_swingL_attack; + else + self->monsterinfo.currentmove = &shambler_move_swingR_attack; + } + } +} + + +// +// SPAWN +// + +/*QUAKED monster_q1_shambler (1 .5 0) (-32 -32 -24) (32 32 64) Ambush Trigger_Spawn Sight +model="models/monsters/q1shambler/tris.md2" +*/ +void SP_monster_q1_shambler (edict_t *self) +{ + if (deathmatch->value) + { + G_FreeEdict (self); + return; + } + + sound_melee1 = gi.soundindex ("q1shambler/melee1.wav"); + sound_melee2 = gi.soundindex ("q1shambler/melee1.wav"); + sound_melee3 = gi.soundindex ("q1shambler/smack.wav"); + sound_attack = gi.soundindex ("q1shambler/sattck1.wav"); + sound_boom = gi.soundindex ("q1shambler/sboom.wav"); + sound_pain = gi.soundindex ("q1shambler/shurt2.wav"); + sound_death = gi.soundindex ("q1shambler/sdeath.wav"); + sound_idle = gi.soundindex ("q1shambler/sidle.wav"); + sound_sight = gi.soundindex ("q1shambler/ssight.wav"); + + self->movetype = MOVETYPE_STEP; + self->solid = SOLID_BBOX; + + // Lazarus: special purpose skins + if ( self->style ) + { + PatchMonsterModel("models/monsters/q1shambler/tris.md2"); + self->s.skinnum = self->style * 2; + } + + self->s.modelindex = gi.modelindex ("models/monsters/q1shambler/tris.md2"); + VectorSet (self->mins, -32, -32, -24); + VectorSet (self->maxs, 32, 32, 64); + + if (!self->health) + self->health = 600; + if (!self->gib_health) + self->gib_health = -60; + if (!self->mass) + self->mass = 600; + + self->pain = shambler_pain; + self->die = shambler_die; + + self->flags |= FL_Q1_MONSTER; + + self->monsterinfo.stand = shambler_stand; + self->monsterinfo.walk = shambler_walk; + self->monsterinfo.run = shambler_run; + self->monsterinfo.dodge = NULL; + self->monsterinfo.attack = shambler_attack; + self->monsterinfo.melee = shambler_melee; + self->monsterinfo.sight = shambler_sight; + self->monsterinfo.search = shambler_stand; + + if (!self->monsterinfo.flies) + self->monsterinfo.flies = 0.50; + + // Lazarus + if (self->powerarmor) + { + if (self->powerarmortype == 1) + self->monsterinfo.power_armor_type = POWER_ARMOR_SCREEN; + else + self->monsterinfo.power_armor_type = POWER_ARMOR_SHIELD; + self->monsterinfo.power_armor_power = self->powerarmor; + } + self->common_name = "Shambler"; + + gi.linkentity (self); + + self->monsterinfo.currentmove = &shambler_move_stand; + self->monsterinfo.scale = MODEL_SCALE; + + walkmonster_start (self); +} diff --git a/missionpack/m_q1shambler.h b/missionpack/m_q1shambler.h new file mode 100644 index 0000000..7d9839c --- /dev/null +++ b/missionpack/m_q1shambler.h @@ -0,0 +1,99 @@ +// Generated by ModelEd +// SHAMBLER + +#define FRAME_stand1 0 +#define FRAME_stand2 1 +#define FRAME_stand3 2 +#define FRAME_stand4 3 +#define FRAME_stand5 4 +#define FRAME_stand6 5 +#define FRAME_stand7 6 +#define FRAME_stand8 7 +#define FRAME_stand9 8 +#define FRAME_stand10 9 +#define FRAME_stand11 10 +#define FRAME_stand12 11 +#define FRAME_stand13 12 +#define FRAME_stand14 13 +#define FRAME_stand15 14 +#define FRAME_stand16 15 +#define FRAME_stand17 16 +#define FRAME_walk1 17 +#define FRAME_walk2 18 +#define FRAME_walk3 19 +#define FRAME_walk4 20 +#define FRAME_walk5 21 +#define FRAME_walk6 22 +#define FRAME_walk7 23 +#define FRAME_walk8 24 +#define FRAME_walk9 25 +#define FRAME_walk10 26 +#define FRAME_walk11 27 +#define FRAME_walk12 28 +#define FRAME_run1 29 +#define FRAME_run2 30 +#define FRAME_run3 31 +#define FRAME_run4 32 +#define FRAME_run5 33 +#define FRAME_run6 34 +#define FRAME_smash1 35 +#define FRAME_smash2 36 +#define FRAME_smash3 37 +#define FRAME_smash4 38 +#define FRAME_smash5 39 +#define FRAME_smash6 40 +#define FRAME_smash7 41 +#define FRAME_smash8 42 +#define FRAME_smash9 43 +#define FRAME_smash10 44 +#define FRAME_smash11 45 +#define FRAME_smash12 46 +#define FRAME_swingr1 47 +#define FRAME_swingr2 48 +#define FRAME_swingr3 49 +#define FRAME_swingr4 50 +#define FRAME_swingr5 51 +#define FRAME_swingr6 52 +#define FRAME_swingr7 53 +#define FRAME_swingr8 54 +#define FRAME_swingr9 55 +#define FRAME_swingl1 56 +#define FRAME_swingl2 57 +#define FRAME_swingl3 58 +#define FRAME_swingl4 59 +#define FRAME_swingl5 60 +#define FRAME_swingl6 61 +#define FRAME_swingl7 62 +#define FRAME_swingl8 63 +#define FRAME_swingl9 64 +#define FRAME_magic1 65 +#define FRAME_magic2 66 +#define FRAME_magic3 67 +#define FRAME_magic4 68 +#define FRAME_magic5 69 +#define FRAME_magic6 70 +#define FRAME_magic7 71 +#define FRAME_magic8 72 +#define FRAME_magic9 73 +#define FRAME_magic10 74 +#define FRAME_magic11 75 +#define FRAME_magic12 76 +#define FRAME_pain1 77 +#define FRAME_pain2 78 +#define FRAME_pain3 79 +#define FRAME_pain4 80 +#define FRAME_pain5 81 +#define FRAME_pain6 82 +#define FRAME_death1 83 +#define FRAME_death2 84 +#define FRAME_death3 85 +#define FRAME_death4 86 +#define FRAME_death5 87 +#define FRAME_death6 88 +#define FRAME_death7 89 +#define FRAME_death8 90 +#define FRAME_death9 91 +#define FRAME_death10 92 +#define FRAME_death11 93 + +#define MODEL_SCALE 1.000000 diff --git a/missionpack/m_q1tarbaby.c b/missionpack/m_q1tarbaby.c new file mode 100644 index 0000000..5ab8dbb --- /dev/null +++ b/missionpack/m_q1tarbaby.c @@ -0,0 +1,375 @@ +/* +============================================================================== + +QUAKE TARBABY (BLOB) + +============================================================================== +*/ + +#include "g_local.h" +#include "m_q1tarbaby.h" + +static int sound_death; +static int sound_hit; +static int sound_land; +static int sound_sight; + + +void tarbaby_stand (edict_t *self); +void tarbaby_jump_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf); +void tarbaby_check_landing (edict_t *self); +void tarbaby_fly (edict_t *self); +void tarbaby_takeoff (edict_t *self); + + +void tarbaby_sight (edict_t *self, edict_t *other) +{ + gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0); +} + + +mframe_t tarbaby_frames_stand [] = +{ + ai_stand, 0, NULL +}; +mmove_t tarbaby_move_stand = {FRAME_walk1, FRAME_walk1, tarbaby_frames_stand, tarbaby_stand}; + +void tarbaby_stand (edict_t *self) +{ + self->monsterinfo.currentmove = &tarbaby_move_stand; +} + + +mframe_t tarbaby_frames_walk [] = +{ + ai_walk, 0, NULL, + ai_walk, 0, NULL, + ai_walk, 0, NULL, + ai_walk, 0, NULL, + ai_walk, 0, NULL, + ai_walk, 0, NULL, + ai_walk, 0, NULL, + ai_walk, 0, NULL, + ai_walk, 0, NULL, + ai_walk, 0, NULL, + ai_walk, 2, NULL, + ai_walk, 2, NULL, + ai_walk, 2, NULL, + ai_walk, 2, NULL, + ai_walk, 2, NULL, + ai_walk, 2, NULL, + ai_walk, 2, NULL, + ai_walk, 2, NULL, + ai_walk, 2, NULL, + ai_walk, 2, NULL, + ai_walk, 2, NULL, + ai_walk, 2, NULL, + ai_walk, 2, NULL, + ai_walk, 2, NULL, + ai_walk, 2, NULL +}; +mmove_t tarbaby_move_walk = {FRAME_walk1, FRAME_walk25, tarbaby_frames_walk, NULL}; + +void tarbaby_walk (edict_t *self) +{ + self->monsterinfo.currentmove = &tarbaby_move_walk; +} + + +mframe_t tarbaby_frames_run [] = +{ + ai_run, 0, NULL, + ai_run, 0, NULL, + ai_run, 0, NULL, + ai_run, 0, NULL, + ai_run, 0, NULL, + ai_run, 0, NULL, + ai_run, 0, NULL, + ai_run, 0, NULL, + ai_run, 0, NULL, + ai_run, 0, NULL, + ai_run, 2, NULL, + ai_run, 2, NULL, + ai_run, 2, NULL, + ai_run, 2, NULL, + ai_run, 2, NULL, + ai_run, 2, NULL, + ai_run, 2, NULL, + ai_run, 2, NULL, + ai_run, 2, NULL, + ai_run, 2, NULL, + ai_run, 2, NULL, + ai_run, 2, NULL, + ai_run, 2, NULL, + ai_run, 2, NULL, + ai_run, 2, NULL +}; +mmove_t tarbaby_move_run = {FRAME_run1, FRAME_run25, tarbaby_frames_run, NULL}; + +void tarbaby_run (edict_t *self) +{ + self->monsterinfo.currentmove = &tarbaby_move_run; +} + + +mframe_t tarbaby_frames_fly [] = +{ + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, tarbaby_check_landing +}; +mmove_t tarbaby_move_fly = {FRAME_fly1, FRAME_fly4, tarbaby_frames_fly, tarbaby_fly}; + +void tarbaby_fly (edict_t *self) +{ + self->monsterinfo.currentmove = &tarbaby_move_fly; +} + +mframe_t tarbaby_frames_jump [] = +{ + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, tarbaby_takeoff, + ai_charge, 0, NULL +}; +mmove_t tarbaby_move_jump = {FRAME_jump1, FRAME_jump6, tarbaby_frames_jump, tarbaby_fly}; + +void tarbaby_jump_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) +{ + if (self->health <= 0) { + self->touch = NULL; + return; + } + + if (other->takedamage && strcmp(other->classname, self->classname)) + { + if (VectorLength(self->velocity) > 400) + { + vec3_t point, normal; + int damage; + + damage = 10 + 10 * random(); + VectorCopy (self->velocity, normal); + VectorNormalize (normal); + VectorMA (self->s.origin, self->maxs[0], normal, point); + T_Damage (other, self, self, self->velocity, point, normal, damage, damage, 0, MOD_UNKNOWN); + gi.sound (self, CHAN_VOICE, sound_hit, 1, ATTN_NORM, 0); + } + } + else + gi.sound (self, CHAN_VOICE, sound_land, 1, ATTN_NORM, 0); + + if ( !M_CheckBottom (self) ) + { + if (self->groundentity) { + self->touch = NULL; + self->monsterinfo.currentmove = &tarbaby_move_run; + self->movetype = MOVETYPE_STEP; + self->monsterinfo.attack_finished = 0; + self->monsterinfo.aiflags &= ~AI_DUCKED; + } + return; // not landed yet + } + self->touch = NULL; + self->monsterinfo.currentmove = &tarbaby_move_jump; +} + +void tarbaby_check_landing (edict_t *self) +{ + vec3_t temp; + + VectorCopy (self->velocity, temp); + temp[2] = 0.0f; + + if (self->groundentity) + { + self->touch = NULL; + self->monsterinfo.currentmove = &tarbaby_move_run; + self->movetype = MOVETYPE_STEP; + self->monsterinfo.attack_finished = 0; + self->monsterinfo.aiflags &= ~AI_DUCKED; + return; + } + else if (VectorLength(temp) == 0) // random jump to un-stick + { + self->velocity[0] = (random() -0.5) * 600; + self->velocity[1] = (random() -0.5) * 600; + self->velocity[2] = 200; + self->groundentity = NULL; + return; + } + + self->count++; + if ( self->count == 4 ) // continue flying + { + self->monsterinfo.currentmove = &tarbaby_move_jump; + self->monsterinfo.nextframe = FRAME_jump5; + tarbaby_takeoff (self); + } +} + +void tarbaby_takeoff (edict_t *self) +{ + vec3_t forward, /*temp,*/ add; + + self->movetype = MOVETYPE_BOUNCE; + self->s.origin[2] += 1; + AngleVectors (self->s.angles, forward, NULL, NULL); + VectorScale (forward, 600, self->velocity); + VectorSet (add, 0, 0, 200); + VectorAdd (self->velocity, add, self->velocity); + self->monsterinfo.attack_finished = level.time + 3; + self->touch = tarbaby_jump_touch; + self->groundentity = NULL; + self->count = 0; +} + +void tarbaby_jump (edict_t *self) +{ + if (!self->enemy) + return; + + self->monsterinfo.currentmove = &tarbaby_move_jump; +} + + +void tarbaby_pain (edict_t *self, edict_t *other, float kick, int damage) +{ + // The tarbaby has no pain frames, so nothing goes here. +} + + +void tarbaby_dead (edict_t *self) +{ + edict_t *explode; + vec3_t temp; + + T_RadiusDamage (self, self, 120, NULL, 120, MOD_UNKNOWN); + + gi.sound (self, CHAN_VOICE, sound_death, 1, ATTN_NORM, 0); + + VectorCopy (self->velocity, temp); + VectorNormalize (temp); + VectorScale (temp, -8, temp); + VectorAdd (self->s.origin, temp, temp); + + explode = G_Spawn (); + VectorCopy (temp, explode->s.origin); + VectorCopy (temp, explode->s.old_origin); + explode->solid = SOLID_NOT; + explode->movetype = MOVETYPE_NONE; + explode->touch = NULL; + VectorClear (explode->velocity); + explode->s.modelindex = gi.modelindex ("sprites/s_explod.sp2"); + explode->s.frame = 0; + explode->s.sound = 0; + explode->s.effects &= ~EF_ANIM_ALLFAST; + explode->think = q1_explode; + explode->nextthink = level.time + FRAMETIME; + gi.linkentity (explode); + + gi.unlinkentity (self); + self->solid = SOLID_NOT; + self->movetype = MOVETYPE_NONE; + self->touch = NULL; + self->svflags |= SVF_NOCLIENT; + self->think = G_FreeEdict; + self->nextthink = level.time + 1; + gi.linkentity (self); +} + +mframe_t tarbaby_frames_explode [] = +{ + ai_move, 0, NULL +}; +mmove_t tarbaby_move_explode = {FRAME_exp, FRAME_exp, tarbaby_frames_explode, tarbaby_dead}; + +void tarbaby_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) +{ + if (self->deadflag == DEAD_DEAD) + return; + + self->deadflag = DEAD_DEAD; + self->takedamage = DAMAGE_YES; + self->gib_health = -10000; + + self->monsterinfo.currentmove = &tarbaby_move_explode; +} + + +// +// SPAWN +// + +/*QUAKED monster_q1_tarbaby (1 .5 0) (-16 -16 -24) (16 16 24) Ambush Trigger_Spawn Sight +model="models/monsters/q1tarbaby/tris.md2" +*/ +void SP_monster_q1_tarbaby (edict_t *self) +{ + if (deathmatch->value) + { + G_FreeEdict (self); + return; + } + + sound_death = gi.soundindex ("q1tarbaby/death1.wav"); + sound_hit = gi.soundindex ("q1tarbaby/hit1.wav"); + sound_land = gi.soundindex ("q1tarbaby/land1.wav"); + sound_sight = gi.soundindex ("q1tarbaby/sight1.wav"); + + self->movetype = MOVETYPE_STEP; + self->solid = SOLID_BBOX; + + // Lazarus: special purpose skins + if ( self->style ) + { + PatchMonsterModel("models/monsters/q1tarbaby/tris.md2"); + self->s.skinnum = self->style * 2; + } + + self->s.modelindex = gi.modelindex ("models/monsters/q1tarbaby/tris.md2"); + VectorSet (self->mins, -16, -16, -24); + VectorSet (self->maxs, 16, 16, 24); + + if (!self->health) + self->health = 80; +// if (!self->gib_health) + self->gib_health = 0; + if (!self->mass) + self->mass = 100; + + self->pain = tarbaby_pain; + self->die = tarbaby_die; + + self->flags |= FL_Q1_MONSTER; + + self->monsterinfo.stand = tarbaby_stand; + self->monsterinfo.walk = tarbaby_walk; + self->monsterinfo.run = tarbaby_run; + self->monsterinfo.dodge = NULL; + self->monsterinfo.attack = tarbaby_jump; + self->monsterinfo.melee = tarbaby_jump; + self->monsterinfo.sight = tarbaby_sight; + self->monsterinfo.search = NULL; + + // Lazarus + if (self->powerarmor) + { + if (self->powerarmortype == 1) + self->monsterinfo.power_armor_type = POWER_ARMOR_SCREEN; + else + self->monsterinfo.power_armor_type = POWER_ARMOR_SHIELD; + self->monsterinfo.power_armor_power = self->powerarmor; + } + self->common_name = "Spawn"; + + gi.linkentity (self); + + self->monsterinfo.currentmove = &tarbaby_move_stand; + self->monsterinfo.scale = MODEL_SCALE; + + walkmonster_start (self); +} diff --git a/missionpack/m_q1tarbaby.h b/missionpack/m_q1tarbaby.h new file mode 100644 index 0000000..018e36c Binary files /dev/null and b/missionpack/m_q1tarbaby.h differ diff --git a/missionpack/m_q1zombie.c b/missionpack/m_q1zombie.c new file mode 100644 index 0000000..731689c --- /dev/null +++ b/missionpack/m_q1zombie.c @@ -0,0 +1,710 @@ + +/* +============================================================================== + +QUAKE ZOMBIE + +============================================================================== +*/ + + +#include "g_local.h" +#include "m_q1zombie.h" + + +static int sound_idleC; +static int sound_idle; +static int sound_idle2; +static int sound_pain; +static int sound_pain2; +static int sound_fall; +static int sound_gib; +static int sound_shot; + +void q1_fire_gib (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed); +void q1zombie_down (edict_t *self); +void q1zombie_fallagain (edict_t *self); +void q1zombie_pain2 (edict_t *self); +void q1zombie_idle3 (edict_t *self); +void q1zombie_run (edict_t *self); + +void q1zombie_Cidle (edict_t *self) +{ + if (random() < 0.1) + gi.sound (self, CHAN_VOICE, sound_idleC, 1, ATTN_IDLE, 0); //was ATTN_STATIC +} + +mframe_t q1zombie_frames_pain5 [] = +{ + ai_move, 0, q1zombie_pain2, //1 + ai_move, -8, NULL, + ai_move, -5, NULL, + ai_move, -3,NULL, + ai_move, -1,NULL, //5 + ai_move, -2,NULL, + ai_move, -1, NULL, + ai_move, -1, NULL, + ai_move, -2, NULL, + ai_move, 0, q1zombie_down, //10 + ai_move, 0, NULL, + ai_move, 0, q1zombie_idle3, //12 + ai_move, 0, q1zombie_fallagain, //13 + 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, //19- was q1zombie_takedamage + ai_move, 0, NULL, //20 + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 5, NULL, + ai_move, 3, NULL, //25 + ai_move, 1, NULL, + ai_move, -1, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL //30 +}; +mmove_t q1zombie_move_pain5 = {FRAME_paine1, FRAME_paine30, q1zombie_frames_pain5, q1zombie_run}; + +void q1zombie_idle3 (edict_t *self) +{ + trace_t tr; + +// self->health = 60; + self->health = self->max_health; + self->solid = SOLID_BBOX; + self->count = 0; + gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0); //was ATTN_STATIC + // Check if player is standing on top + tr = gi.trace (self->s.origin, self->mins, self->maxs, self->s.origin, self, CONTENTS_PLAYERCLIP|CONTENTS_MONSTER); + if (tr.ent && tr.ent->solid != SOLID_BSP) + { + self->solid = SOLID_NOT; + self->count = 1; + // self->monsterinfo.currentmove = NULL; + // self->nextthink = level.time + FRAMETIME; + // self->think = q1zombie_ + self->s.frame = FRAME_paine11; + // self->monsterinfo.currentmove = &q1zombie_move_pain5; + self->nextthink += 5; + self->pain_debounce_time = level.time + 3; + } +} + +void q1zombie_idle (edict_t *self) +{ + if (random() > 0.8) + gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0); //was ATTN_STATIC + + if(self->solid == SOLID_NOT) + self->solid = SOLID_BBOX; +} + +void q1zombie_idle2 (edict_t *self) +{ + if (random() > 0.2) + gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0); //was ATTN_STATIC + else + gi.sound (self, CHAN_VOICE, sound_idle2, 1, ATTN_IDLE, 0); //was ATTN_STATIC +} + +void q1zombie_pain1(edict_t *self) +{ + gi.sound (self, CHAN_VOICE, sound_pain, 1, ATTN_NORM, 0); //was ATTN_IDLE +// self->health = 60; + self->health = self->max_health; +} + +void q1zombie_pain2(edict_t *self) +{ + gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0); //was ATTN_IDLE +// self->health = 60; + self->health = self->max_health; +} + +void q1zombie_fall(edict_t *self) +{ + gi.sound (self, CHAN_VOICE, sound_fall, 1, ATTN_NORM, 0); //was ATTN_IDLE +// self->health = 60; + self->health = self->max_health; +} + + +// STAND + +void q1zombie_stand (edict_t *self); + +mframe_t q1zombie_frames_stand [] = +{ + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL +}; +mmove_t q1zombie_move_stand = {FRAME_stand1, FRAME_stand15, q1zombie_frames_stand, q1zombie_stand}; + +void q1zombie_stand (edict_t *self) +{ + self->solid = SOLID_BBOX; + self->count = 0; + self->monsterinfo.currentmove = &q1zombie_move_stand; +} + + +//Crucified +void q1zombie_crucify (edict_t *self); + +mframe_t q1zombie_frames_cruc [] = +{ + ai_stand, 0, NULL, + ai_stand, 0, q1zombie_Cidle, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, + ai_stand, 0, NULL, +}; +mmove_t q1zombie_crucified = {FRAME_cruc_1, FRAME_cruc_6, q1zombie_frames_cruc, q1zombie_crucify}; + +void q1zombie_crucify (edict_t *self) +{ + self->monsterinfo.currentmove = &q1zombie_crucified; +} + +// +// WALK +// + +mframe_t q1zombie_frames_walk [] = +{ + ai_walk, 0, NULL, + ai_walk, 2, NULL, + ai_walk, 3, NULL, + ai_walk, 2, NULL, + ai_walk, 1, NULL, + ai_walk, 0, NULL, + ai_walk, 0, NULL, + ai_walk, 0, NULL, + ai_walk, 0, NULL, + ai_walk, 0, NULL, + ai_walk, 2, NULL, + ai_walk, 2, NULL, + ai_walk, 1, NULL, + ai_walk, 0, NULL, + ai_walk, 0, NULL, + ai_walk, 0, NULL, + ai_walk, 0, NULL, + ai_walk, 0, NULL, + ai_walk, 0, q1zombie_idle +}; +mmove_t q1zombie_move_walk = {FRAME_walk1, FRAME_walk19, q1zombie_frames_walk, NULL}; + +void q1zombie_walk (edict_t *self) +{ + self->solid = SOLID_BBOX; + self->count = 0; + self->monsterinfo.currentmove = &q1zombie_move_walk; +} + + +// +// RUN +// + +mframe_t q1zombie_frames_run [] = +{ + ai_run, 1, NULL, + ai_run, 1, NULL, + ai_run, 0, NULL, + ai_run, 1, NULL, + ai_run, 2, NULL, + ai_run, 3, NULL, + ai_run, 4, NULL, + ai_run, 4, NULL, + ai_run, 2, NULL, + ai_run, 0, NULL, + ai_run, 0, NULL, + ai_run, 0, NULL, + ai_run, 2, NULL, + ai_run, 4, NULL, + ai_run, 6, NULL, + ai_run, 7, NULL, + ai_run, 3, NULL, + ai_run, 8, q1zombie_idle2 +}; +mmove_t q1zombie_move_run = {FRAME_run1, FRAME_run18, q1zombie_frames_run, q1zombie_run}; + +void q1zombie_run (edict_t *self) +{ + self->solid = SOLID_BBOX; + self->count = 0; + + if (self->monsterinfo.aiflags & AI_STAND_GROUND) + { + self->monsterinfo.currentmove = &q1zombie_move_stand; + return; + } + else + self->monsterinfo.currentmove = &q1zombie_move_run; +} + + +// +// ATTACK +// +void q1zombie_firegib (edict_t *self, vec3_t offset) +{ + vec3_t start; + vec3_t forward, right; + vec3_t target; + vec3_t aim; + + AngleVectors (self->s.angles, forward, right, NULL); + G_ProjectSource (self->s.origin, offset, forward, right, start); + + // project enemy back a bit and target there + VectorCopy (self->enemy->s.origin, target); + + switch(range (self,self->enemy)) + { + case RANGE_MELEE: + target[2] += self->enemy->viewheight; + break; + case RANGE_NEAR: + VectorMA (target, -0.04, self->enemy->velocity, target); + target[2] += (self->enemy->viewheight * 0.9); + break; + case RANGE_MID: + VectorMA (target, -0.08, self->enemy->velocity, target); + target[2] += (self->enemy->viewheight * 0.8); + break; + default: + VectorMA (target,-0.1, self->enemy->velocity, target); + target[2] += (rand() & self->enemy->viewheight); + break; + } + + VectorSubtract (target, start, aim); + VectorNormalize (aim); + + gi.sound (self, CHAN_WEAPON|CHAN_RELIABLE, sound_shot, 1.0, ATTN_NORM, 0); + q1_fire_gib (self, start, aim, 10, 600); + +} + +void q1zombie_firegib1(edict_t *self) +{ + vec3_t offset; + offset[0]=-8; + offset[1]=-18; + offset[2]=30; + + q1zombie_firegib(self,offset); +} + +void q1zombie_firegib2(edict_t *self) +{ + vec3_t offset; + offset[0]=-8; + offset[1]=-18; + offset[2]=30; + q1zombie_firegib(self,offset); +} + +void q1zombie_firegib3(edict_t *self) +{ + vec3_t offset; + offset[0]=-8; + offset[1]=22; + offset[2]=30; + q1zombie_firegib(self,offset); +} + +mframe_t q1zombie_frames_attack1[] = +{ + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, q1zombie_firegib1 +}; +mmove_t q1zombie_move_attack1 = {FRAME_atta1, FRAME_atta13, q1zombie_frames_attack1, q1zombie_run}; + +mframe_t q1zombie_frames_attack2[] = +{ + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, q1zombie_firegib2 +}; +mmove_t q1zombie_move_attack2 = {FRAME_attb1, FRAME_attb14, q1zombie_frames_attack2, q1zombie_run}; + + +mframe_t q1zombie_frames_attack3[] = +{ + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, q1zombie_firegib3 +}; +mmove_t q1zombie_move_attack3 = {FRAME_attc1, FRAME_attc12, q1zombie_frames_attack3, q1zombie_run}; + + +void q1zombie_attack(edict_t *self) +{ + float r = random(); + + if (self->style) + return; + + self->solid = SOLID_BBOX; + self->count = 0; + + if (r < 0.3) + self->monsterinfo.currentmove = &q1zombie_move_attack1; + else if (r < 0.6) + self->monsterinfo.currentmove = &q1zombie_move_attack2; + else + self->monsterinfo.currentmove = &q1zombie_move_attack3; +} + + +// +// PAIN +// + +mframe_t q1zombie_frames_pain1 [] = +{ + ai_move, 0, q1zombie_pain1, + ai_move, 3, NULL, + ai_move, 1, NULL, + ai_move, -1,NULL, + ai_move, -3,NULL, + ai_move, -1,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 q1zombie_move_pain1 = {FRAME_paina1, FRAME_paina12, q1zombie_frames_pain1, q1zombie_run}; + +mframe_t q1zombie_frames_pain2 [] = +{ + ai_move, 0, q1zombie_pain2, + ai_move, -2, NULL, + ai_move, -8, NULL, + ai_move, -6,NULL, + ai_move, -2,NULL, + ai_move, 0,NULL, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, q1zombie_fall, + 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, NULL, + ai_move, 0, NULL, + ai_move, 1, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL +}; +mmove_t q1zombie_move_pain2 = {FRAME_painb1, FRAME_painb28, q1zombie_frames_pain2, q1zombie_run}; + +mframe_t q1zombie_frames_pain3 [] = +{ + ai_move, 0, q1zombie_pain2, + ai_move, 0, NULL, + ai_move, -3,NULL, + ai_move, -1,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, 1, NULL, + ai_move, 1, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL +}; +mmove_t q1zombie_move_pain3 = {FRAME_painc1, FRAME_painc18, q1zombie_frames_pain3, q1zombie_run}; + +mframe_t q1zombie_frames_pain4 [] = +{ + ai_move, 0, q1zombie_pain1, + 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, -1, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL +}; +mmove_t q1zombie_move_pain4 = {FRAME_paind1, FRAME_paind13, q1zombie_frames_pain4, q1zombie_run}; + +// fall and stand up functions + +void q1zombie_down( edict_t *self) +{ + self->solid = SOLID_NOT; + q1zombie_fall(self); + self->nextthink += 5; +} + +void q1zombie_pain (edict_t *self, edict_t *other, float kick, int damage) +{ + float r; + +// self->health = 60; + self->health = self->max_health; + if (self->wait > level.time) + { + self->dmg += damage; + if (self->dmg > 30) + { + self->monsterinfo.currentmove = &q1zombie_move_pain5; + self->pain_debounce_time = level.time + 3; + self->dmg = 0; + self->wait = 0; + // self->solid = SOLID_NOT; + self->count = 1; + return; + } + } + else + { + self->wait = level.time + 1; + self->dmg = damage; + } + + if (damage < 15) + return; + + if (damage >= 25) + { + self->monsterinfo.currentmove = &q1zombie_move_pain5; + self->pain_debounce_time = level.time + 3; + // self->solid = SOLID_NOT; + self->count = 1; + return; + } + + if (self->pain_debounce_time > level.time) + return; + + r = random(); + + if (r < 0.25) + { + self->monsterinfo.currentmove = &q1zombie_move_pain1; + gi.sound (self, CHAN_VOICE, sound_pain, 1, ATTN_NORM, 0); + self->pain_debounce_time = level.time + 1.0; + } + else if (r < 0.5) + { + self->monsterinfo.currentmove = &q1zombie_move_pain2; + gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0); + self->pain_debounce_time = level.time + 1.5; + } + else if (r < 0.75) + { + self->monsterinfo.currentmove = &q1zombie_move_pain3; + gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0); + self->pain_debounce_time = level.time + 1.1; + } + else + { + self->monsterinfo.currentmove = &q1zombie_move_pain4; + self->pain_debounce_time = level.time + 1.0; + } +} + +void q1zombie_fallagain ( edict_t *self) +{ + if (self->pain_debounce_time > level.time) + { + self->monsterinfo.currentmove = &q1zombie_move_pain5; + } +} + +// +// SIGHT +// + +void q1zombie_sight(edict_t *self, edict_t *other) +{ + gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_NORM, 0); + + if (!self->style && (skill->value > 0) && (range(self, self->enemy) >= RANGE_MID)) + q1zombie_attack(self); +} + + +// +// DEATH +// + +void q1zombie_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) +{ +// gi.sound (self, CHAN_VOICE, sound_gib, 1, ATTN_NORM, 0); + gi.sound (self, CHAN_VOICE, gi.soundindex ("q1zombie/z_gib.wav"), 1, ATTN_NORM, 0); + ThrowGib (self, "models/objects/q1gibs/q1gib1/tris.md2", damage, GIB_ORGANIC); + ThrowGib (self, "models/objects/q1gibs/q1gib2/tris.md2", damage, GIB_ORGANIC); + ThrowGib (self, "models/objects/q1gibs/q1gib3/tris.md2", damage, GIB_ORGANIC); + ThrowHead (self, "models/monsters/q1zombie/head/tris.md2", damage*2, GIB_ORGANIC); + self->deadflag = DEAD_DEAD; + self->takedamage = DAMAGE_NO; + return; +} + + +// +// SPAWN +// + +/*QUAKED monster_q1_zombie (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight +model="models/monsters/q1zombie/tris.md2" +"sounds" 1 makes the zombie crucified +*/ + +void SP_misc_q1_zombie_crucified (edict_t *self); +void SP_monster_q1_zombie (edict_t *self) +{ + if (self->sounds) // change to different entity because crucified code here is broken + { + self->classname = "misc_q1_zombie_crucified"; + SP_misc_q1_zombie_crucified (self); + return; + } + + if (deathmatch->value) + { + G_FreeEdict (self); + return; + } + + sound_idleC = gi.soundindex ("q1zombie/idle_w2.wav"); + sound_idle = gi.soundindex ("q1zombie/z_idle.wav"); + sound_idle2 = gi.soundindex ("q1zombie/z_idle1.wav"); + sound_pain = gi.soundindex ("q1zombie/z_pain.wav"); + sound_pain2 = gi.soundindex ("q1zombie/z_pain1.wav"); + sound_fall = gi.soundindex ("q1zombie/z_fall.wav"); + sound_gib = gi.soundindex ("q1zombie/z_gib.wav"); + sound_shot = gi.soundindex ("q1zombie/z_shot1.wav"); + + self->movetype = MOVETYPE_STEP; + self->solid = SOLID_BBOX; + + // Lazarus: special purpose skins + if ( self->style ) + { + PatchMonsterModel("models/monsters/q1zombie/tris.md2"); + self->s.skinnum = self->style * 2; + } + + self->s.modelindex = gi.modelindex ("models/monsters/q1zombie/tris.md2"); + VectorSet (self->mins, -16, -16, -24); + VectorSet (self->maxs, 16, 16, 32); + + if (!self->health) + self->health = 60; +// if (!self->gib_health) + self->gib_health = 0; + if (!self->mass) + self->mass = 100; + self->count = 0; + self->max_health = self->health; // save custom health + + self->pain = q1zombie_pain; + self->die = q1zombie_die; + + self->flags |= FL_Q1_MONSTER; + + self->monsterinfo.stand = q1zombie_stand; + self->monsterinfo.walk = q1zombie_walk; + self->monsterinfo.run = q1zombie_run; + self->monsterinfo.attack = q1zombie_attack; + self->monsterinfo.melee = NULL; + self->monsterinfo.sight = q1zombie_sight; + + if (!self->monsterinfo.flies) + self->monsterinfo.flies = 0.90; + + // Lazarus + if (self->powerarmor) + { + if (self->powerarmortype == 1) + self->monsterinfo.power_armor_type = POWER_ARMOR_SCREEN; + else + self->monsterinfo.power_armor_type = POWER_ARMOR_SHIELD; + self->monsterinfo.power_armor_power = self->powerarmor; + } + self->common_name = "Zombie"; + + gi.linkentity (self); + + self->monsterinfo.currentmove = &q1zombie_move_stand; + walkmonster_start (self); + self->monsterinfo.scale = MODEL_SCALE; +} diff --git a/missionpack/m_q1zombie.h b/missionpack/m_q1zombie.h new file mode 100644 index 0000000..e962d74 --- /dev/null +++ b/missionpack/m_q1zombie.h @@ -0,0 +1,203 @@ +// Generated by ModelEd +// ZOMBIE + +#define FRAME_stand1 0 +#define FRAME_stand2 1 +#define FRAME_stand3 2 +#define FRAME_stand4 3 +#define FRAME_stand5 4 +#define FRAME_stand6 5 +#define FRAME_stand7 6 +#define FRAME_stand8 7 +#define FRAME_stand9 8 +#define FRAME_stand10 9 +#define FRAME_stand11 10 +#define FRAME_stand12 11 +#define FRAME_stand13 12 +#define FRAME_stand14 13 +#define FRAME_stand15 14 +#define FRAME_walk1 15 +#define FRAME_walk2 16 +#define FRAME_walk3 17 +#define FRAME_walk4 18 +#define FRAME_walk5 19 +#define FRAME_walk6 20 +#define FRAME_walk7 21 +#define FRAME_walk8 22 +#define FRAME_walk9 23 +#define FRAME_walk10 24 +#define FRAME_walk11 25 +#define FRAME_walk12 26 +#define FRAME_walk13 27 +#define FRAME_walk14 28 +#define FRAME_walk15 29 +#define FRAME_walk16 30 +#define FRAME_walk17 31 +#define FRAME_walk18 32 +#define FRAME_walk19 33 +#define FRAME_run1 34 +#define FRAME_run2 35 +#define FRAME_run3 36 +#define FRAME_run4 37 +#define FRAME_run5 38 +#define FRAME_run6 39 +#define FRAME_run7 40 +#define FRAME_run8 41 +#define FRAME_run9 42 +#define FRAME_run10 43 +#define FRAME_run11 44 +#define FRAME_run12 45 +#define FRAME_run13 46 +#define FRAME_run14 47 +#define FRAME_run15 48 +#define FRAME_run16 49 +#define FRAME_run17 50 +#define FRAME_run18 51 +#define FRAME_atta1 52 +#define FRAME_atta2 53 +#define FRAME_atta3 54 +#define FRAME_atta4 55 +#define FRAME_atta5 56 +#define FRAME_atta6 57 +#define FRAME_atta7 58 +#define FRAME_atta8 59 +#define FRAME_atta9 60 +#define FRAME_atta10 61 +#define FRAME_atta11 62 +#define FRAME_atta12 63 +#define FRAME_atta13 64 +#define FRAME_attb1 65 +#define FRAME_attb2 66 +#define FRAME_attb3 67 +#define FRAME_attb4 68 +#define FRAME_attb5 69 +#define FRAME_attb6 70 +#define FRAME_attb7 71 +#define FRAME_attb8 72 +#define FRAME_attb9 73 +#define FRAME_attb10 74 +#define FRAME_attb11 75 +#define FRAME_attb12 76 +#define FRAME_attb13 77 +#define FRAME_attb14 78 +#define FRAME_attc1 79 +#define FRAME_attc2 80 +#define FRAME_attc3 81 +#define FRAME_attc4 82 +#define FRAME_attc5 83 +#define FRAME_attc6 84 +#define FRAME_attc7 85 +#define FRAME_attc8 86 +#define FRAME_attc9 87 +#define FRAME_attc10 88 +#define FRAME_attc11 89 +#define FRAME_attc12 90 +#define FRAME_paina1 91 +#define FRAME_paina2 92 +#define FRAME_paina3 93 +#define FRAME_paina4 94 +#define FRAME_paina5 95 +#define FRAME_paina6 96 +#define FRAME_paina7 97 +#define FRAME_paina8 98 +#define FRAME_paina9 99 +#define FRAME_paina10 100 +#define FRAME_paina11 101 +#define FRAME_paina12 102 +#define FRAME_painb1 103 +#define FRAME_painb2 104 +#define FRAME_painb3 105 +#define FRAME_painb4 106 +#define FRAME_painb5 107 +#define FRAME_painb6 108 +#define FRAME_painb7 109 +#define FRAME_painb8 110 +#define FRAME_painb9 111 +#define FRAME_painb10 112 +#define FRAME_painb11 113 +#define FRAME_painb12 114 +#define FRAME_painb13 115 +#define FRAME_painb14 116 +#define FRAME_painb15 117 +#define FRAME_painb16 118 +#define FRAME_painb17 119 +#define FRAME_painb18 120 +#define FRAME_painb19 121 +#define FRAME_painb20 122 +#define FRAME_painb21 123 +#define FRAME_painb22 124 +#define FRAME_painb23 125 +#define FRAME_painb24 126 +#define FRAME_painb25 127 +#define FRAME_painb26 128 +#define FRAME_painb27 129 +#define FRAME_painb28 130 +#define FRAME_painc1 131 +#define FRAME_painc2 132 +#define FRAME_painc3 133 +#define FRAME_painc4 134 +#define FRAME_painc5 135 +#define FRAME_painc6 136 +#define FRAME_painc7 137 +#define FRAME_painc8 138 +#define FRAME_painc9 139 +#define FRAME_painc10 140 +#define FRAME_painc11 141 +#define FRAME_painc12 142 +#define FRAME_painc13 143 +#define FRAME_painc14 144 +#define FRAME_painc15 145 +#define FRAME_painc16 146 +#define FRAME_painc17 147 +#define FRAME_painc18 148 +#define FRAME_paind1 149 +#define FRAME_paind2 150 +#define FRAME_paind3 151 +#define FRAME_paind4 152 +#define FRAME_paind5 153 +#define FRAME_paind6 154 +#define FRAME_paind7 155 +#define FRAME_paind8 156 +#define FRAME_paind9 157 +#define FRAME_paind10 158 +#define FRAME_paind11 159 +#define FRAME_paind12 160 +#define FRAME_paind13 161 +#define FRAME_paine1 162 +#define FRAME_paine2 163 +#define FRAME_paine3 164 +#define FRAME_paine4 165 +#define FRAME_paine5 166 +#define FRAME_paine6 167 +#define FRAME_paine7 168 +#define FRAME_paine8 169 +#define FRAME_paine9 170 +#define FRAME_paine10 171 +#define FRAME_paine11 172 +#define FRAME_paine12 173 +#define FRAME_paine13 174 +#define FRAME_paine14 175 +#define FRAME_paine15 176 +#define FRAME_paine16 177 +#define FRAME_paine17 178 +#define FRAME_paine18 179 +#define FRAME_paine19 180 +#define FRAME_paine20 181 +#define FRAME_paine21 182 +#define FRAME_paine22 183 +#define FRAME_paine23 184 +#define FRAME_paine24 185 +#define FRAME_paine25 186 +#define FRAME_paine26 187 +#define FRAME_paine27 188 +#define FRAME_paine28 189 +#define FRAME_paine29 190 +#define FRAME_paine30 191 +#define FRAME_cruc_1 192 +#define FRAME_cruc_2 193 +#define FRAME_cruc_3 194 +#define FRAME_cruc_4 195 +#define FRAME_cruc_5 196 +#define FRAME_cruc_6 197 + +#define MODEL_SCALE 1.000000 \ No newline at end of file diff --git a/missionpack/m_soldier.c b/missionpack/m_soldier.c index 0d433ad..772a275 100644 --- a/missionpack/m_soldier.c +++ b/missionpack/m_soldier.c @@ -3049,7 +3049,7 @@ void SP_monster_soldier_x (edict_t *self) //===== // Lazarus - if(self->powerarmor) + if (self->powerarmor) { if (self->powerarmortype == 1) self->monsterinfo.power_armor_type = POWER_ARMOR_SCREEN; @@ -3057,13 +3057,13 @@ void SP_monster_soldier_x (edict_t *self) self->monsterinfo.power_armor_type = POWER_ARMOR_SHIELD; self->monsterinfo.power_armor_power = self->powerarmor; } - if(!self->monsterinfo.flies) + if (!self->monsterinfo.flies) self->monsterinfo.flies = 0.40; gi.linkentity (self); self->monsterinfo.stand (self); - if(self->health < 0) + if (self->health < 0) { mmove_t *deathmoves[] = {&soldier_move_death1, &soldier_move_death2, @@ -3219,14 +3219,14 @@ void SP_monster_soldier_h (edict_t *self) self->monsterinfo.power_armor_type = POWER_ARMOR_SHIELD; self->monsterinfo.power_armor_power = self->powerarmor; } - if(!self->monsterinfo.flies) + if (!self->monsterinfo.flies) self->monsterinfo.flies = 0.40; gi.linkentity (self); // self->monsterinfo.stand (self); self->monsterinfo.currentmove = &soldierh_move_stand3; - if(self->health < 0) + if (self->health < 0) { mmove_t *deathmoves[] = {&soldierh_move_death1, &soldierh_move_death2, diff --git a/missionpack/missionpack.dsp b/missionpack/missionpack.dsp index 8638f12..4744f60 100644 --- a/missionpack/missionpack.dsp +++ b/missionpack/missionpack.dsp @@ -169,6 +169,10 @@ SOURCE=.\g_misc.c # End Source File # Begin Source File +SOURCE=.\g_misc_q1.c +# End Source File +# Begin Source File + SOURCE=.\g_monster.c # End Source File # Begin Source File @@ -261,6 +265,10 @@ SOURCE=.\g_utils.c # End Source File # Begin Source File +SOURCE=.\g_utils_q1.c +# End Source File +# Begin Source File + SOURCE=.\g_vehicle.c # End Source File # Begin Source File @@ -269,6 +277,10 @@ SOURCE=.\g_weapon.c # End Source File # Begin Source File +SOURCE=.\g_weapon_q1.c +# End Source File +# Begin Source File + SOURCE=.\grenade.c # End Source File # Begin Source File @@ -393,6 +405,58 @@ SOURCE=.\m_parasite.c # End Source File # Begin Source File +SOURCE=.\m_q1dog.c +# End Source File +# Begin Source File + +SOURCE=.\m_q1enforcer.c +# End Source File +# Begin Source File + +SOURCE=.\m_q1fiend.c +# End Source File +# Begin Source File + +SOURCE=.\m_q1grunt.c +# End Source File +# Begin Source File + +SOURCE=.\m_q1hknight.c +# End Source File +# Begin Source File + +SOURCE=.\m_q1knight.c +# End Source File +# Begin Source File + +SOURCE=.\m_q1ogre.c +# End Source File +# Begin Source File + +SOURCE=.\m_q1rotfish.c +# End Source File +# Begin Source File + +SOURCE=.\m_q1scrag.c +# End Source File +# Begin Source File + +SOURCE=.\m_q1shalrath.c +# End Source File +# Begin Source File + +SOURCE=.\m_q1shambler.c +# End Source File +# Begin Source File + +SOURCE=.\m_q1tarbaby.c +# End Source File +# Begin Source File + +SOURCE=.\m_q1zombie.c +# End Source File +# Begin Source File + SOURCE=.\m_soldier.c # End Source File # Begin Source File @@ -585,6 +649,58 @@ SOURCE=.\m_player.h # End Source File # Begin Source File +SOURCE=.\m_q1dog.h +# End Source File +# Begin Source File + +SOURCE=.\m_q1enforcer.h +# End Source File +# Begin Source File + +SOURCE=.\m_q1fiend.h +# End Source File +# Begin Source File + +SOURCE=.\m_q1grunt.h +# End Source File +# Begin Source File + +SOURCE=.\m_q1hknight.h +# End Source File +# Begin Source File + +SOURCE=.\m_q1knight.h +# End Source File +# Begin Source File + +SOURCE=.\m_q1ogre.h +# End Source File +# Begin Source File + +SOURCE=.\m_q1rotfish.h +# End Source File +# Begin Source File + +SOURCE=.\m_q1scrag.h +# End Source File +# Begin Source File + +SOURCE=.\m_q1shalrath.h +# End Source File +# Begin Source File + +SOURCE=.\m_q1shambler.h +# End Source File +# Begin Source File + +SOURCE=.\m_q1tarbaby.h +# End Source File +# Begin Source File + +SOURCE=.\m_q1zombie.h +# End Source File +# Begin Source File + SOURCE=.\m_rider.h # End Source File # Begin Source File diff --git a/missionpack/missionpack_2008.vcproj b/missionpack/missionpack_2008.vcproj index ee80399..01377f8 100644 --- a/missionpack/missionpack_2008.vcproj +++ b/missionpack/missionpack_2008.vcproj @@ -490,6 +490,10 @@ RelativePath="g_misc.c" > + + @@ -582,6 +586,10 @@ RelativePath="g_utils.c" > + + @@ -590,6 +598,10 @@ RelativePath="g_weapon.c" > + + @@ -714,6 +726,58 @@ RelativePath="m_parasite.c" > + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -907,6 +971,58 @@ RelativePath="m_player.h" > + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/missionpack/p_client.c b/missionpack/p_client.c index 63aa827..5ed64ee 100644 --- a/missionpack/p_client.c +++ b/missionpack/p_client.c @@ -918,6 +918,48 @@ void ClientObituary (edict_t *self, edict_t *inflictor, edict_t *attacker) // Rottweiler else if (!strcmp(attacker->classname, "monster_dog")) message = "was mauled by a"; + // Quake 1 Monsters + // Fiend + else if ( !Q_stricmp(attacker->classname, "q1_monster_fiend") || !Q_stricmp(attacker->classname, "monster_q1_demon") ) + message ="was eviscerated by a"; + // Quake Grunt + else if ( !Q_stricmp(attacker->classname, "q1_monster_soldier") || !Q_stricmp(attacker->classname, "monster_q1_army") ) + message = "was shot by a"; + // Quake Enforcer + else if ( !Q_stricmp(attacker->classname, "q1_monster_enforcer") || !Q_stricmp(attacker->classname, "monster_q1_enforcer") ) + message = "was blasted by an"; + // Ogre + else if ( !Q_stricmp(attacker->classname, "q1_monster_ogre") || !Q_stricmp(attacker->classname, "monster_q1_ogre") ) + message = "was destroyed by an"; + // Knight + else if ( !Q_stricmp(attacker->classname, "q1_monster_knight") || !Q_stricmp(attacker->classname, "monster_q1_knight") ) + message = "was slashed by a"; + // Scrag + else if ( !Q_stricmp(attacker->classname, "q1_monster_scrag") || !Q_stricmp(attacker->classname, "monster_q1_wizard") ) + message = "was scragged by a"; + // Zombie + else if ( !Q_stricmp(attacker->classname, "q1_monster_zombie") || !Q_stricmp(attacker->classname, "monster_q1_zombie") ) { + message = "joins the"; + message2 = "s"; + } + // Shambler + else if ( !Q_stricmp(attacker->classname, "q1_monster_shambler") || !Q_stricmp(attacker->classname, "monster_q1_shambler") ) + message = "was smashed by a"; + // Rottweiler + else if ( !Q_stricmp(attacker->classname, "q1_monster_dog") || !Q_stricmp(attacker->classname, "monster_q1_dog") ) + message = "was mauled by a"; + // Rotfish + else if ( !Q_stricmp(attacker->classname, "q1_monster_fish") || !Q_stricmp(attacker->classname, "monster_q1_fish") ) + message = "was fed to the"; + // Hell Knight + else if ( !Q_stricmp(attacker->classname, "q1_monster_hknight") || !Q_stricmp(attacker->classname, "monster_q1_hknight") ) + message = "was slain by at"; + // Vore + else if ( !Q_stricmp(attacker->classname, "q1_monster_shalrath") || !Q_stricmp(attacker->classname, "monster_q1_shalrath") ) + message = "was exploded by a"; + // Spawn + else if ( !Q_stricmp(attacker->classname, "q1_monster_tarbaby") || !Q_stricmp(attacker->classname, "monster_q1_tarbaby") ) + message = "was slimed by a"; } if (message) { diff --git a/missionpack/p_view.c b/missionpack/p_view.c index daf0df1..ecfca00 100644 --- a/missionpack/p_view.c +++ b/missionpack/p_view.c @@ -712,7 +712,7 @@ void P_SlamDamage (edict_t *ent) vec3_t dir; vec3_t deltav; - if (ent->s.modelindex != (MAX_MODELS-1)) //was 255 + if (ent->s.modelindex != (MAX_MODELS-1)) // was 255 return; // not in the player model if (ent->movetype == MOVETYPE_NOCLIP) @@ -731,11 +731,11 @@ void P_SlamDamage (edict_t *ent) ent->s.event = EV_FALLFAR; else ent->s.event = EV_FALL;*/ - //play correct PPM sounds while in third person mode + // play correct PPM sounds while in third person mode if (delta >= 65*(player_max_speed->value/300)) // Knightmare changed - gi.sound(ent,CHAN_VOICE,gi.soundindex("*fall1.wav"),1.0,ATTN_NORM,0); + gi.sound(ent, CHAN_VOICE, gi.soundindex("*fall1.wav"), 1.0, ATTN_NORM, 0); else - gi.sound(ent,CHAN_VOICE,gi.soundindex("*fall2.wav"),1.0,ATTN_NORM,0); + gi.sound(ent, CHAN_VOICE, gi.soundindex("*fall2.wav"), 1.0, ATTN_NORM, 0); } ent->pain_debounce_time = level.time; // no normal pain sound damage = (delta-40*(player_max_speed->value/300))/2; // Knightmare changed @@ -764,7 +764,7 @@ void P_FallingDamage (edict_t *ent) if (ent->s.modelindex != (MAX_MODELS-1)) //was 255 return; // not in the player model - //Knightmare- no falling if player is controlling a turret + // Knightmare- no falling if player is controlling a turret if (ent->flags & FL_TURRET_OWNER) return; @@ -799,11 +799,11 @@ void P_FallingDamage (edict_t *ent) // Lazarus: Changed here to NOT play footstep sounds if ent isn't on the ground. // So player will no longer play footstep sounds when descending a ladder. - if (delta < 7) //Knightmare- was 15, changed to 7 + if (delta < 7) // Knightmare- was 15, changed to 7 { if (!(ent->watertype & CONTENTS_MUD) && !ent->vehicle && !ent->turret && (ent->groundentity || PlayerOnFloor(ent)) ) #ifndef FMOD_FOOTSTEPS - ent->s.event = EV_FOOTSTEP; //Knightmare- move Lazarus footsteps client-side + ent->s.event = EV_FOOTSTEP; // Knightmare- move Lazarus footsteps client-side #else FootStep(ent); #endif @@ -823,11 +823,11 @@ void P_FallingDamage (edict_t *ent) ent->s.event = EV_FALLFAR; else ent->s.event = EV_FALL;*/ - //play correct PPM sounds while in third person mode + // play correct PPM sounds while in third person mode if (delta >= 55) - gi.sound(ent,CHAN_VOICE,gi.soundindex("*fall1.wav"),1.0,ATTN_NORM,0); + gi.sound(ent, CHAN_VOICE, gi.soundindex("*fall1.wav"), 1.0, ATTN_NORM, 0); else - gi.sound(ent,CHAN_VOICE,gi.soundindex("*fall2.wav"),1.0,ATTN_NORM,0); + gi.sound(ent, CHAN_VOICE, gi.soundindex("*fall2.wav"), 1.0, ATTN_NORM,0); if (world->effects & FX_WORLDSPAWN_ALERTSOUNDS) PlayerNoise(ent,ent->s.origin,PNOISE_SELF);