diff --git a/missionpack/g_ai.c b/missionpack/g_ai.c index 06cbea3..47a9be8 100644 --- a/missionpack/g_ai.c +++ b/missionpack/g_ai.c @@ -2146,16 +2146,16 @@ qboolean ai_chicken (edict_t *self, edict_t *badguy) return true; } - VectorCopy(self->mins,mins); + VectorCopy (self->mins, mins); mins[2] += 18; if (mins[2] > 0) mins[2] = 0; - VectorCopy(self->maxs,maxs); + VectorCopy(self->maxs, maxs); // Find a vector that will hide the actor from his enemy - VectorCopy(badguy->s.origin,atk); + VectorCopy (badguy->s.origin, atk); atk[2] += badguy->viewheight; VectorClear(best_dir); - AngleVectors(self->s.angles,forward,NULL,NULL); + AngleVectors (self->s.angles, forward, NULL, NULL); dir[2] = 0; for (travel=512; travel>63 && best_dist == 0; travel /= 2) { diff --git a/missionpack/g_func_decs.h b/missionpack/g_func_decs.h index 9a5ed1f..44cf495 100644 --- a/missionpack/g_func_decs.h +++ b/missionpack/g_func_decs.h @@ -534,6 +534,22 @@ extern float target_angle ( edict_t * self ) ; extern void widow_sight ( edict_t * self , edict_t * other ) ; extern void widow_search ( edict_t * self ) ; extern void showme ( edict_t * self ) ; +extern void SP_monster_vulture ( edict_t * self ) ; +extern void vulture_die ( edict_t * self , edict_t * inflictor , edict_t * attacker , int damage , vec3_t point ) ; +extern void vulture_dead ( edict_t * self ) ; +extern void vulture_pain ( edict_t * self , edict_t * other , float kick , int damage ) ; +extern void vulture_melee ( edict_t * self ) ; +extern void vulture_peck ( edict_t * self ) ; +extern void vulture_run ( edict_t * self ) ; +extern void vulture_landed ( edict_t * self ) ; +extern void vulture_airborne ( edict_t * self ) ; +extern void vulture_walk ( edict_t * self ) ; +extern void vulture_perch ( edict_t * self ) ; +extern void vulture_flap ( edict_t * self ) ; +extern void vulture_idle ( edict_t * self ) ; +extern void vulture_soar_idle ( edict_t * self ) ; +extern void vulture_perch_idle ( edict_t * self ) ; +extern void vulture_sight ( edict_t * self , edict_t * other ) ; extern void SP_monster_turret ( edict_t * self ) ; extern qboolean turret_checkattack ( edict_t * self ) ; extern void turret_activate ( edict_t * self , edict_t * other , edict_t * activator ) ; @@ -864,6 +880,32 @@ 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_freddie ( edict_t * self ) ; +extern void freddie_die ( edict_t * self , edict_t * inflictor , edict_t * attacker , int damage , vec3_t point ) ; +extern void freddie_nogib ( edict_t * self ) ; +extern void freddie_dead ( edict_t * self ) ; +extern void freddie_melee ( edict_t * self ) ; +extern void freddie_melee_repeat ( edict_t * self ) ; +extern void freddie_blade_left ( edict_t * self ) ; +extern void freddie_blade_right ( edict_t * self ) ; +extern void freddie_blade ( edict_t * self , float side ) ; +extern void freddie_saw_sound ( edict_t * self ) ; +extern void freddie_attack ( edict_t * self ) ; +extern void freddie_attack_spindown ( edict_t * self ) ; +extern void freddie_do_sfire ( edict_t * self ) ; +extern void freddie_stand_fire ( edict_t * self ) ; +extern void freddie_fireweapon ( edict_t * self , vec3_t offset ) ; +extern void freddie_attack_prefire ( edict_t * self ) ; +extern void freddie_attack_spinupsound ( edict_t * self ) ; +extern void freddie_pain ( edict_t * self , edict_t * other , float kick , int damage ) ; +extern void freddie_run_frame ( edict_t * self ) ; +extern void freddie_rfire ( edict_t * self ) ; +extern void freddie_run ( edict_t * self ) ; +extern void freddie_walk ( edict_t * self ) ; +extern void freddie_stand ( edict_t * self ) ; +extern void freddie_sound_footstep ( edict_t * self ) ; +extern void freddie_sight ( edict_t * self , edict_t * other ) ; +extern void freddie_idle_sound ( 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 ) ; @@ -1532,29 +1574,38 @@ 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_gib_precache ( 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_acidspit_precache ( void ) ; 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_precache ( void ) ; 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_firepod_precache ( void ) ; 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_rocket_precahce ( void ) ; 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_grenade_precache ( void ) ; 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_flame_precache ( void ) ; 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_laser_precache ( void ) ; 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_nail_precache ( void ) ; 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 SP_goop ( edict_t * goop ) ; @@ -1613,6 +1664,7 @@ extern void fire_missile ( edict_t * self , vec3_t start , vec3_t dir , int dama extern void missile_die ( edict_t * self , edict_t * inflictor , edict_t * attacker , int damage , vec3_t point ) ; extern void missile_explode ( edict_t * ent ) ; extern void missile_touch ( edict_t * ent , edict_t * other , cplane_t * plane , csurface_t * surf ) ; +extern qboolean AimGrenade ( edict_t * self , vec3_t start , vec3_t target , vec_t speed , vec3_t aim ) ; extern void SP_handgrenade ( edict_t * grenade ) ; extern void handgrenade_delayed_start ( edict_t * grenade ) ; extern void SP_grenade ( edict_t * grenade ) ; @@ -1807,7 +1859,7 @@ extern void thing_grenade_boom ( edict_t * self ) ; extern void thing_think_pause ( edict_t * self ) ; extern void thing_think ( edict_t * self ) ; extern void thing_restore_leader ( edict_t * self ) ; -extern edict_t * SpawnThing ( ) ; +extern edict_t * SpawnThing ( void ) ; extern void SP_target_earthquake ( edict_t * self ) ; extern void target_earthquake_use ( edict_t * self , edict_t * other , edict_t * activator ) ; extern void target_earthquake_think ( edict_t * self ) ; @@ -2421,6 +2473,7 @@ extern void BecomeExplosion1 ( edict_t * self ) ; extern void SP_debris ( edict_t * debris ) ; extern void debris_delayed_start ( edict_t * debris ) ; extern void ThrowDebris ( edict_t * self , char * modelname , float speed , vec3_t origin , int skin , int effects ) ; +extern void ThrowDebrisFrame ( edict_t * self , char * modelname , float speed , vec3_t origin , int frame , int skin , int effects ) ; extern void debris_die ( edict_t * self , edict_t * inflictor , edict_t * attacker , int damage , vec3_t point ) ; extern void ThrowClientHead ( edict_t * self , int damage ) ; extern void SP_gibhead ( edict_t * gib ) ; @@ -2428,6 +2481,7 @@ extern void ThrowHead ( edict_t * self , char * gibname , int damage , int type extern void SP_gib ( edict_t * gib ) ; extern void gib_delayed_start ( edict_t * gib ) ; extern void ThrowGib ( edict_t * self , char * gibname , int damage , int type ) ; +extern void ThrowGibFrame ( edict_t * self , char * gibname , int frame , int damage , int type ) ; extern void gib_die ( edict_t * self , edict_t * inflictor , edict_t * attacker , int damage , vec3_t point ) ; extern void gib_touch ( edict_t * self , edict_t * other , cplane_t * plane , csurface_t * surf ) ; extern void gib_think ( edict_t * self ) ; @@ -2827,7 +2881,6 @@ extern void ai_walk ( edict_t * self , float dist ) ; extern void ai_stand ( edict_t * self , float dist ) ; extern void ai_move ( edict_t * self , float dist ) ; extern void AI_SetSightClient ( void ) ; -extern qboolean AimGrenade ( edict_t * self , vec3_t start , vec3_t target , vec_t speed , vec3_t aim ) ; extern void SP_dm_tag_token ( edict_t * self ) ; extern void Tag_PostInitSetup ( void ) ; extern void Tag_GameInit ( void ) ; diff --git a/missionpack/g_func_list.h b/missionpack/g_func_list.h index 02236a8..d9bda7c 100644 --- a/missionpack/g_func_list.h +++ b/missionpack/g_func_list.h @@ -534,6 +534,22 @@ {"widow_sight", (byte *)widow_sight}, {"widow_search", (byte *)widow_search}, {"showme", (byte *)showme}, +{"SP_monster_vulture", (byte *)SP_monster_vulture}, +{"vulture_die", (byte *)vulture_die}, +{"vulture_dead", (byte *)vulture_dead}, +{"vulture_pain", (byte *)vulture_pain}, +{"vulture_melee", (byte *)vulture_melee}, +{"vulture_peck", (byte *)vulture_peck}, +{"vulture_run", (byte *)vulture_run}, +{"vulture_landed", (byte *)vulture_landed}, +{"vulture_airborne", (byte *)vulture_airborne}, +{"vulture_walk", (byte *)vulture_walk}, +{"vulture_perch", (byte *)vulture_perch}, +{"vulture_flap", (byte *)vulture_flap}, +{"vulture_idle", (byte *)vulture_idle}, +{"vulture_soar_idle", (byte *)vulture_soar_idle}, +{"vulture_perch_idle", (byte *)vulture_perch_idle}, +{"vulture_sight", (byte *)vulture_sight}, {"SP_monster_turret", (byte *)SP_monster_turret}, {"turret_checkattack", (byte *)turret_checkattack}, {"turret_activate", (byte *)turret_activate}, @@ -864,6 +880,32 @@ {"q1grunt_walk", (byte *)q1grunt_walk}, {"q1grunt_stand", (byte *)q1grunt_stand}, {"q1grunt_idle", (byte *)q1grunt_idle}, +{"SP_monster_q1_freddie", (byte *)SP_monster_q1_freddie}, +{"freddie_die", (byte *)freddie_die}, +{"freddie_nogib", (byte *)freddie_nogib}, +{"freddie_dead", (byte *)freddie_dead}, +{"freddie_melee", (byte *)freddie_melee}, +{"freddie_melee_repeat", (byte *)freddie_melee_repeat}, +{"freddie_blade_left", (byte *)freddie_blade_left}, +{"freddie_blade_right", (byte *)freddie_blade_right}, +{"freddie_blade", (byte *)freddie_blade}, +{"freddie_saw_sound", (byte *)freddie_saw_sound}, +{"freddie_attack", (byte *)freddie_attack}, +{"freddie_attack_spindown", (byte *)freddie_attack_spindown}, +{"freddie_do_sfire", (byte *)freddie_do_sfire}, +{"freddie_stand_fire", (byte *)freddie_stand_fire}, +{"freddie_fireweapon", (byte *)freddie_fireweapon}, +{"freddie_attack_prefire", (byte *)freddie_attack_prefire}, +{"freddie_attack_spinupsound", (byte *)freddie_attack_spinupsound}, +{"freddie_pain", (byte *)freddie_pain}, +{"freddie_run_frame", (byte *)freddie_run_frame}, +{"freddie_rfire", (byte *)freddie_rfire}, +{"freddie_run", (byte *)freddie_run}, +{"freddie_walk", (byte *)freddie_walk}, +{"freddie_stand", (byte *)freddie_stand}, +{"freddie_sound_footstep", (byte *)freddie_sound_footstep}, +{"freddie_sight", (byte *)freddie_sight}, +{"freddie_idle_sound", (byte *)freddie_idle_sound}, {"SP_monster_q1_fiend", (byte *)SP_monster_q1_fiend}, {"fiend_die", (byte *)fiend_die}, {"fiend_nogib", (byte *)fiend_nogib}, @@ -1532,29 +1574,38 @@ {"actor_walk", (byte *)actor_walk}, {"actor_stand", (byte *)actor_stand}, {"InitLithiumVars", (byte *)InitLithiumVars}, +{"q1_gib_precache", (byte *)q1_gib_precache}, {"q1_fire_gib", (byte *)q1_fire_gib}, {"q1_zombiegib_touch", (byte *)q1_zombiegib_touch}, +{"q1_acidspit_precache", (byte *)q1_acidspit_precache}, {"q1_fire_acidspit", (byte *)q1_fire_acidspit}, {"q1_acidbolt_touch", (byte *)q1_acidbolt_touch}, +{"q1_fire_lavaball_precache", (byte *)q1_fire_lavaball_precache}, {"q1_fire_lavaball", (byte *)q1_fire_lavaball}, {"q1_lavaball_touch", (byte *)q1_lavaball_touch}, +{"q1_firepod_precache", (byte *)q1_firepod_precache}, {"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_rocket_precahce", (byte *)q1_rocket_precahce}, {"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_grenade_precache", (byte *)q1_grenade_precache}, {"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_flame_precache", (byte *)q1_flame_precache}, {"q1_fire_flame", (byte *)q1_fire_flame}, {"q1_flame_touch", (byte *)q1_flame_touch}, {"q1_flame_splash", (byte *)q1_flame_splash}, +{"q1_laser_precache", (byte *)q1_laser_precache}, {"q1_fire_laser", (byte *)q1_fire_laser}, {"q1_laser_touch", (byte *)q1_laser_touch}, +{"q1_nail_precache", (byte *)q1_nail_precache}, {"q1_fire_nail", (byte *)q1_fire_nail}, {"q1_nail_touch", (byte *)q1_nail_touch}, {"SP_goop", (byte *)SP_goop}, @@ -1613,6 +1664,7 @@ {"missile_die", (byte *)missile_die}, {"missile_explode", (byte *)missile_explode}, {"missile_touch", (byte *)missile_touch}, +{"AimGrenade", (byte *)AimGrenade}, {"SP_handgrenade", (byte *)SP_handgrenade}, {"handgrenade_delayed_start", (byte *)handgrenade_delayed_start}, {"SP_grenade", (byte *)SP_grenade}, @@ -2421,6 +2473,7 @@ {"SP_debris", (byte *)SP_debris}, {"debris_delayed_start", (byte *)debris_delayed_start}, {"ThrowDebris", (byte *)ThrowDebris}, +{"ThrowDebrisFrame", (byte *)ThrowDebrisFrame}, {"debris_die", (byte *)debris_die}, {"ThrowClientHead", (byte *)ThrowClientHead}, {"SP_gibhead", (byte *)SP_gibhead}, @@ -2428,6 +2481,7 @@ {"SP_gib", (byte *)SP_gib}, {"gib_delayed_start", (byte *)gib_delayed_start}, {"ThrowGib", (byte *)ThrowGib}, +{"ThrowGibFrame", (byte *)ThrowGibFrame}, {"gib_die", (byte *)gib_die}, {"gib_touch", (byte *)gib_touch}, {"gib_think", (byte *)gib_think}, @@ -2827,7 +2881,6 @@ {"ai_stand", (byte *)ai_stand}, {"ai_move", (byte *)ai_move}, {"AI_SetSightClient", (byte *)AI_SetSightClient}, -{"AimGrenade", (byte *)AimGrenade}, {"SP_dm_tag_token", (byte *)SP_dm_tag_token}, {"Tag_PostInitSetup", (byte *)Tag_PostInitSetup}, {"Tag_GameInit", (byte *)Tag_GameInit}, diff --git a/missionpack/g_local.h b/missionpack/g_local.h index 3d9a04f..9a8830e 100644 --- a/missionpack/g_local.h +++ b/missionpack/g_local.h @@ -212,6 +212,7 @@ typedef enum //gib types #define GIB_ORGANIC 0 #define GIB_METALLIC 1 +#define GIB_FEATHER 2 // Knightmare- added for vulture // monster ai flags #define AI_STAND_GROUND 0x00000001 @@ -346,6 +347,7 @@ MOVETYPE_PENDULUM, // same as MOVETYPE_PUSH, but used only for pendulums to gra MOVETYPE_CONVEYOR, // conveyor MOVETYPE_SHOCKBOUNCE, // Knightmare- added for shockwave +MOVETYPE_FEATHER, // Knightmare- added for vulture, specifies slow falling // Zaero MOVETYPE_FREEZE, // player freeze, used for Zaero Camera MOVETYPE_FALLFLOAT, // falls down slopes and floats in water @@ -1409,7 +1411,9 @@ void gib_fade (edict_t *self); void ThrowHead (edict_t *self, char *gibname, int damage, int type); void ThrowClientHead (edict_t *self, int damage); void ThrowGib (edict_t *self, char *gibname, int damage, int type); +void ThrowGibFrame (edict_t *self, char *gibname, int frame, int damage, int type); void ThrowDebris (edict_t *self, char *modelname, float speed, vec3_t origin, int skin, int effects); +void ThrowDebrisFrame (edict_t *self, char *modelname, float speed, vec3_t origin, int frame, int skin, int effects); void BecomeExplosion1(edict_t *self); void BecomeExplosion2(edict_t *self); void BecomeExplosion3(edict_t *self); @@ -1498,17 +1502,25 @@ 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_nail_precache (void); void q1_fire_laser (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed); +void q1_laser_precache (void); void q1_fire_flame (edict_t *self, vec3_t start, vec3_t dir, float leftrightoff); +void q1_flame_precache (void); 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_grenade_precache (void); 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_rocket_precahce (void); 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_firepod_precache (void); 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_lavaball_precache (void); void q1_fire_acidspit (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed); +void q1_acidspit_precache (void); void q1_fire_gib (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed); - +void q1_gib_precache (void); // // m_actor.c @@ -2237,17 +2249,17 @@ new structure for the backup client data while its in the camera. typedef struct { - vec3_t oldorigin; //clients world origin - vec3_t moveorigin; //for client prediction, don't think this is needed as its only an sp modification - vec3_t viewangles; //which way the client is facing + vec3_t oldorigin; // clients world origin + vec3_t moveorigin; // for client prediction, don't think this is needed as its only an sp modification + vec3_t viewangles; // which way the client is facing - int pm_type; //player movetype I believe. (noclip, fly, etc) - int gunindex; //gun model + int pm_type; // player movetype I believe. (noclip, fly, etc) + int gunindex; // gun model - vec3_t blend; //screen blend value (for bleeding, etc) - int rdflags; //render flags for the clent + vec3_t blend; // screen blend value (for bleeding, etc) + int rdflags; // render flags for the clent - //how long left before something happens/runs out + // how long left before something happens/runs out int quad_framenum; int invincible_framenum; int breather_framenum; @@ -2255,15 +2267,15 @@ typedef struct int grenade_blew_up; int grenade_time; - int viewheight; //viewheight from the origin + int viewheight; // viewheight from the origin - //various model files the player can be displayed as. + // various model files the player can be displayed as. int modelindex; int modelindex2; int modelindex3; - unsigned int effects; //what effect are we (needs to be unsigned because theres a few + unsigned int effects; // what effect are we (needs to be unsigned because theres a few int sound; - solid_t solid; //current solid state, 90% certain its SOLID_PLAYER ;) + solid_t solid; // current solid state, 90% certain its SOLID_PLAYER ;) } backup_t; diff --git a/missionpack/g_mappack.c b/missionpack/g_mappack.c index 6076967..848a700 100644 --- a/missionpack/g_mappack.c +++ b/missionpack/g_mappack.c @@ -298,7 +298,7 @@ void modelspawn_think (edict_t *self) void model_spawn_use (edict_t *self, edict_t *other, edict_t *activator) { - if (self->delay) //we started off + if (self->delay) // we started off { self->svflags &= ~SVF_NOCLIENT; self->delay = 0; @@ -312,7 +312,7 @@ void model_spawn_use (edict_t *self, edict_t *other, edict_t *activator) self->s.attenuation = self->attenuation; #endif } - else //we started active + else // we started active { self->svflags |= SVF_NOCLIENT; self->delay = 1; diff --git a/missionpack/g_misc.c b/missionpack/g_misc.c index 6c213ae..028bab0 100644 --- a/missionpack/g_misc.c +++ b/missionpack/g_misc.c @@ -200,7 +200,7 @@ void gib_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, G_FreeEdict (self); } -void ThrowGib (edict_t *self, char *gibname, int damage, int type) +void ThrowGibFrame (edict_t *self, char *gibname, int frame, int damage, int type) { edict_t *gib; vec3_t vd; @@ -248,8 +248,9 @@ void ThrowGib (edict_t *self, char *gibname, int damage, int type) gib->s.origin[1] = origin[1] + crandom() * size[1]; gib->s.origin[2] = origin[2] + crandom() * size[2]; - //gi.setmodel (gib, gibname); +// gi.setmodel (gib, gibname); gib->s.modelindex = gi.modelindex (gibname); + gib->s.frame = frame; // Knightmare added gib->clipmask = MASK_SHOT; VectorSet (gib->mins, -4, -4, -4); VectorSet (gib->maxs, 4, 4, 4); @@ -288,14 +289,20 @@ void ThrowGib (edict_t *self, char *gibname, int damage, int type) gib->movetype = MOVETYPE_BOUNCE; // was MOVETYPE_TOSS gib->touch = gib_touch; if (self->blood_type == 1) - vscale = 3.0; + vscale = 3.0f; else - vscale = 1.0; + vscale = 1.0f; + } + else if (type == GIB_FEATHER) // Knightmare- added for vulture + { + gib->movetype = MOVETYPE_FEATHER; + gib->touch = gib_touch; + vscale = 2.0f; } else { gib->movetype = MOVETYPE_BOUNCE; - vscale = 1.0; + vscale = 1.0f; } VelocityForDamage (damage, vd); @@ -316,6 +323,11 @@ void ThrowGib (edict_t *self, char *gibname, int damage, int type) gi.linkentity (gib); } +void ThrowGib (edict_t *self, char *gibname, int damage, int type) +{ + ThrowGibFrame (self, gibname, 0, damage, type); +} + // NOTE: SP_gib is ONLY intended to be used for gibs that change maps // via trigger_transition. It should NOT be used for map entities. @@ -434,7 +446,7 @@ void ThrowHead (edict_t *self, char *gibname, int damage, int type) if (type == GIB_ORGANIC) { - self->movetype = MOVETYPE_BOUNCE; //was MOVETYPE_TOSS + self->movetype = MOVETYPE_BOUNCE; // was MOVETYPE_TOSS self->touch = gib_touch; if (self->blood_type == 1) vscale = 3.0; @@ -555,7 +567,7 @@ void debris_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damag G_FreeEdict (self); } -void ThrowDebris (edict_t *self, char *modelname, float speed, vec3_t origin, int skin, int effects) +void ThrowDebrisFrame (edict_t *self, char *modelname, float speed, vec3_t origin, int frame, int skin, int effects) { edict_t *chunk; vec3_t v; @@ -599,7 +611,8 @@ void ThrowDebris (edict_t *self, char *modelname, float speed, vec3_t origin, in chunk->avelocity[2] = random()*600; chunk->think = gib_fade; // Knightmare- gib fade, was G_FreeEdict chunk->nextthink = level.time + 8 + random()*10; - chunk->s.frame = 0; +// chunk->s.frame = 0; + chunk->s.frame = frame; // Knightmare added chunk->flags = 0; chunk->classname = "debris"; chunk->svflags |= SVF_GIB; // Knightmare- gib flag @@ -615,6 +628,11 @@ void ThrowDebris (edict_t *self, char *modelname, float speed, vec3_t origin, in gi.linkentity (chunk); } +void ThrowDebris (edict_t *self, char *modelname, float speed, vec3_t origin, int skin, int effects) +{ + ThrowDebrisFrame (self, modelname, speed, origin, 0, skin, effects); +} + // NOTE: SP_debris is ONLY intended to be used for debris chunks that change maps // via trigger_transition. It should NOT be used for map entities. @@ -4975,7 +4993,7 @@ void spawn_precipitation(edict_t *self, vec3_t org, vec3_t dir, float speed) drop->s.modelindex = gi.modelindex ("models/objects/drop/tris.md2"); drop->classname = "rain drop"; } - if (self->gravity > 0. || self->attenuation > 0 ) + if (self->gravity > 0.0f || self->attenuation > 0 ) drop->movetype = MOVETYPE_DEBRIS; else drop->movetype = MOVETYPE_RAIN; @@ -4983,19 +5001,19 @@ void spawn_precipitation(edict_t *self, vec3_t org, vec3_t dir, float speed) drop->touch = drop_touch; if (self->style == STYLE_WEATHER_USER) drop->clipmask = MASK_MONSTERSOLID; - else if ((self->fadeout > 0) && (self->gravity == 0.)) + else if ((self->fadeout > 0) && (self->gravity == 0.0f)) drop->clipmask = MASK_SOLID | CONTENTS_WATER; else drop->clipmask = MASK_MONSTERSOLID | CONTENTS_WATER; drop->solid = SOLID_BBOX; drop->svflags = SVF_DEADMONSTER; - VectorSet(drop->mins,-1,-1,-1); + VectorSet(drop->mins, -1, -1, -1); VectorSet(drop->maxs, 1, 1, 1); if (self->spawnflags & SF_WEATHER_GRAVITY_BOUNCE) drop->gravity = self->gravity; else - drop->gravity = 0.; + drop->gravity = 0.0f; drop->attenuation = self->attenuation; drop->mass = self->mass; drop->spawnflags = self->spawnflags; @@ -5182,12 +5200,12 @@ void SP_target_precipitation (edict_t *ent) if (st.gravity) ent->gravity = atof(st.gravity); else - ent->gravity = 0.; + ent->gravity = 0.0f; } else { - ent->gravity = 0.; - ent->attenuation = 0.; + ent->gravity = 0.0f; + ent->attenuation = 0.0f; } // If not rain or "user", turn off splash. Yeah I know goofy mapper @@ -5397,7 +5415,7 @@ void SP_target_fountain (edict_t *ent) if (st.gravity) ent->gravity = atof(st.gravity); else - ent->gravity = 0.; + ent->gravity = 0.0f; ent->use = target_fountain_use; diff --git a/missionpack/g_misc_q1.c b/missionpack/g_misc_q1.c index df345db..a4beb22 100644 --- a/missionpack/g_misc_q1.c +++ b/missionpack/g_misc_q1.c @@ -216,7 +216,7 @@ void SP_misc_q1_globe(edict_t *self) void q1_small_flame_think (edict_t *self) { - if(self->s.frame >= 5) + if (self->s.frame >= 5) self->s.frame = 0; else self->s.frame++; @@ -285,7 +285,7 @@ void SP_misc_q1_large_flame (edict_t *ent) void q1_torch_think (edict_t *self) { - if(self->s.frame >= 5) + if (self->s.frame >= 5) self->s.frame = 0; else self->s.frame++; @@ -354,7 +354,7 @@ void SP_target_q1_trap (edict_t *self) if (self->spawnflags & 2) { self->noise_index = gi.soundindex ("q1enforcer/enfire.wav"); - gi.soundindex("q1enforcer/enfstop.wav"); + q1_laser_precache (); if (!self->speed) self->speed = 600; } @@ -365,11 +365,12 @@ void SP_target_q1_trap (edict_t *self) self->noise_index = gi.soundindex ("q1weapons/spike.wav"); gi.soundindex("q1weapons/s_end.wav"); #endif + q1_nail_precache (); if (!self->speed) self->speed = 500; } - if (self->spawnflags & 1 || self->spawnflags & 2) { + if ( (self->spawnflags & 1) || (self->spawnflags & 2) ) { if (!self->dmg) self->dmg = 15; } diff --git a/missionpack/g_mmove_decs.h b/missionpack/g_mmove_decs.h index aea00c7..076fb4e 100644 --- a/missionpack/g_mmove_decs.h +++ b/missionpack/g_mmove_decs.h @@ -92,6 +92,17 @@ extern mmove_t widow_move_attack_blaster ; extern mmove_t widow_move_attack_post_blaster_l ; extern mmove_t widow_move_attack_post_blaster_r ; extern mmove_t widow_move_attack_post_blaster ; +extern mmove_t vulture_move_soardeath ; +extern mmove_t vulture_move_death ; +extern mmove_t vulture_move_soarpain ; +extern mmove_t vulture_move_pain ; +extern mmove_t vulture_move_melee ; +extern mmove_t vulture_move_land ; +extern mmove_t vulture_move_takeoff ; +extern mmove_t vulture_move_fly ; +extern mmove_t vulture_move_soar ; +extern mmove_t vulture_move_walk ; +extern mmove_t vulture_move_perch ; extern mmove_t turret_move_run ; extern mmove_t turret_move_seek ; extern mmove_t turret_move_ready_gun ; @@ -283,6 +294,19 @@ 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 freddie_move_death ; +extern mmove_t freddie_move_fswinge ; +extern mmove_t freddie_move_bswing ; +extern mmove_t freddie_move_fswing ; +extern mmove_t freddie_move_sfire_stop ; +extern mmove_t freddie_move_sfire ; +extern mmove_t freddie_move_sfire_start ; +extern mmove_t freddie_move_pain2 ; +extern mmove_t freddie_move_pain1 ; +extern mmove_t freddie_move_rfire ; +extern mmove_t freddie_move_run ; +extern mmove_t freddie_move_walk ; +extern mmove_t freddie_move_stand ; extern mmove_t fiend_move_death ; extern mmove_t fiend_move_pain ; extern mmove_t fiend_move_jump ; diff --git a/missionpack/g_mmove_list.h b/missionpack/g_mmove_list.h index 9ce6f6c..fd0201d 100644 --- a/missionpack/g_mmove_list.h +++ b/missionpack/g_mmove_list.h @@ -92,6 +92,17 @@ {"widow_move_attack_post_blaster_l", &widow_move_attack_post_blaster_l}, {"widow_move_attack_post_blaster_r", &widow_move_attack_post_blaster_r}, {"widow_move_attack_post_blaster", &widow_move_attack_post_blaster}, +{"vulture_move_soardeath", &vulture_move_soardeath}, +{"vulture_move_death", &vulture_move_death}, +{"vulture_move_soarpain", &vulture_move_soarpain}, +{"vulture_move_pain", &vulture_move_pain}, +{"vulture_move_melee", &vulture_move_melee}, +{"vulture_move_land", &vulture_move_land}, +{"vulture_move_takeoff", &vulture_move_takeoff}, +{"vulture_move_fly", &vulture_move_fly}, +{"vulture_move_soar", &vulture_move_soar}, +{"vulture_move_walk", &vulture_move_walk}, +{"vulture_move_perch", &vulture_move_perch}, {"turret_move_run", &turret_move_run}, {"turret_move_seek", &turret_move_seek}, {"turret_move_ready_gun", &turret_move_ready_gun}, @@ -283,6 +294,19 @@ {"q1grunt_move_run", &q1grunt_move_run}, {"q1grunt_move_walk", &q1grunt_move_walk}, {"q1grunt_move_stand", &q1grunt_move_stand}, +{"freddie_move_death", &freddie_move_death}, +{"freddie_move_fswinge", &freddie_move_fswinge}, +{"freddie_move_bswing", &freddie_move_bswing}, +{"freddie_move_fswing", &freddie_move_fswing}, +{"freddie_move_sfire_stop", &freddie_move_sfire_stop}, +{"freddie_move_sfire", &freddie_move_sfire}, +{"freddie_move_sfire_start", &freddie_move_sfire_start}, +{"freddie_move_pain2", &freddie_move_pain2}, +{"freddie_move_pain1", &freddie_move_pain1}, +{"freddie_move_rfire", &freddie_move_rfire}, +{"freddie_move_run", &freddie_move_run}, +{"freddie_move_walk", &freddie_move_walk}, +{"freddie_move_stand", &freddie_move_stand}, {"fiend_move_death", &fiend_move_death}, {"fiend_move_pain", &fiend_move_pain}, {"fiend_move_jump", &fiend_move_jump}, diff --git a/missionpack/g_monster.c b/missionpack/g_monster.c index 4541cc2..69baa91 100644 --- a/missionpack/g_monster.c +++ b/missionpack/g_monster.c @@ -319,7 +319,7 @@ void dabeam_hit (edict_t *self) VectorCopy (self->s.origin, start); VectorMA (start, 2048, self->movedir, end); - while(1) + while (1) { //Knightmare- double trace here, needed to make sure clipping works- must be compiler weirdness tr = gi.trace (start, NULL, NULL, end, ignore, (CONTENTS_SOLID|CONTENTS_MONSTER|CONTENTS_DEADMONSTER)); tr = gi.trace (start, NULL, NULL, end, ignore, (CONTENTS_SOLID|CONTENTS_MONSTER|CONTENTS_DEADMONSTER)); @@ -1323,7 +1323,7 @@ void monster_start_go (edict_t *self) // Lazarus: move_origin for func_monitor if (!VectorLength(self->move_origin)) - VectorSet(self->move_origin,0,0,self->viewheight); + VectorSet(self->move_origin, 0, 0, self->viewheight); // check for target to combat_point and change to combattarget if (self->target) @@ -1426,6 +1426,9 @@ void walkmonster_start_go (edict_t *self) // PMM - stalkers are too short for this if (!(strcmp(self->classname, "monster_stalker"))) self->viewheight = 15; + // Knightmare- vultures also too short + else if (!(strcmp(self->classname, "monster_vulture"))) + self->viewheight = 8; else self->viewheight = 25; @@ -1449,7 +1452,11 @@ void flymonster_start_go (edict_t *self) if (!self->yaw_speed) self->yaw_speed = 10; - self->viewheight = 25; + // Knightmare- vultures too short for this + if (!(strcmp(self->classname, "monster_vulture"))) + self->viewheight = 8; + else + self->viewheight = 25; monster_start_go (self); @@ -1636,6 +1643,7 @@ int PatchMonsterModel (char *modelname) qboolean is_hover = false; qboolean is_medic = false; qboolean is_turret = false; + qboolean is_vulture = false; qboolean is_zboss_mech = false; qboolean is_zboss_pilot = false; @@ -1660,71 +1668,76 @@ 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 = 32; // was 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") - || !strcmp(modelname,"models/monsters/bitch2/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; } - else if (!strcmp(modelname,"models/monsters/bossz/mech/tris.md2")) + else if (!strcmp(modelname, "models/monsters/vulture/tris.md2")) + { + is_vulture = true; + numskins = 4; + } + else if (!strcmp(modelname, "models/monsters/bossz/mech/tris.md2")) { is_zboss_mech = true; numskins = 12; } - else if (!strcmp(modelname,"models/monsters/bossz/pilot/tris.md2")) + else if (!strcmp(modelname, "models/monsters/bossz/pilot/tris.md2")) { is_zboss_pilot = true; numskins = 12; @@ -2119,6 +2132,20 @@ int PatchMonsterModel (char *modelname) Com_strcat (skins[j], sizeof(skins[j]), "custom3_3.pcx"); break; } } + else if (is_vulture) + { + switch (j) + { + case 0: + Com_strcat (skins[j], sizeof(skins[j]), "vulture.pcx"); break; + case 1: + Com_strcat (skins[j], sizeof(skins[j]), "custom1.pcx"); break; + case 2: + Com_strcat (skins[j], sizeof(skins[j]), "custom2.pcx"); break; + case 3: + Com_strcat (skins[j], sizeof(skins[j]), "custom3.pcx"); break; + } + } else if (is_zboss_mech || is_zboss_pilot) { switch (j) diff --git a/missionpack/g_phys.c b/missionpack/g_phys.c index 91d64b3..5d2968e 100644 --- a/missionpack/g_phys.c +++ b/missionpack/g_phys.c @@ -718,10 +718,24 @@ void SV_AddGravity (edict_t *ent) ent->velocity); } else if (level.time > ent->gravity_debounce_time) - ent->velocity[2] -= ent->gravity * sv_gravity->value * FRAMETIME; + { + // Knightmare- MOVETYPE_FEATHER specifies slow falling + if ( (ent->movetype == MOVETYPE_FEATHER) && (ent->velocity[2] < 0.0f) ) { + ent->velocity[2] -= ent->gravity * sv_gravity->value * FRAMETIME * 0.001f; + } + else + ent->velocity[2] -= ent->gravity * sv_gravity->value * FRAMETIME; + } #else if (level.time > ent->gravity_debounce_time) - ent->velocity[2] -= ent->gravity * sv_gravity->value * FRAMETIME; + { + // Knightmare- MOVETYPE_FEATHER specifies slow falling + if ( (ent->movetype == MOVETYPE_FEATHER) && (ent->velocity[2] < 0.0f) ) { + ent->velocity[2] -= ent->gravity * sv_gravity->value * FRAMETIME * 0.001f; + } + else + ent->velocity[2] -= ent->gravity * sv_gravity->value * FRAMETIME; + } #endif } @@ -744,6 +758,7 @@ called for MOVETYPE_TOSS MOVETYPE_FLY MOVETYPE_FLYMISSILE MOVETYPE_RAIN + MOVETYPE_FEATHER ================================================= */ trace_t SV_PushEntity (edict_t *ent, vec3_t push) @@ -2798,7 +2813,7 @@ void SV_Physics_FallFloat (edict_t *ent) SV_CheckVelocity (ent); wasonground = (ent->groundentity == NULL); - if (ent->velocity[2] < sv_gravity->value*-0.1) + if (ent->velocity[2] < (sv_gravity->value * -0.1f)) hitsound = true; if (!ent->waterlevel) @@ -2835,8 +2850,7 @@ void SV_Physics_FallFloat (edict_t *ent) ent->groundentity = NULL; } } - else - //if (ent->waterlevel) + else // if (ent->waterlevel) { // where's the midpoint? above or below the water? const double WATER_MASS = 500.0; @@ -3001,6 +3015,7 @@ void G_RunEntity (edict_t *ent) // RAFAEL case MOVETYPE_WALLBOUNCE: case MOVETYPE_RAIN: + case MOVETYPE_FEATHER: // Knightmare added SV_Physics_Toss (ent); break; case MOVETYPE_NEWTOSS: diff --git a/missionpack/g_spawn.c b/missionpack/g_spawn.c index 31e4927..b81df37 100644 --- a/missionpack/g_spawn.c +++ b/missionpack/g_spawn.c @@ -198,6 +198,8 @@ void SP_misc_seat(edict_t *self); // Knightmare- the dog from Coconut Monkey 3 void SP_monster_dog (edict_t *self); +// Knightmare- the vulture from Coconut Monkey 2 +void SP_monster_vulture (edict_t *self); void SP_rotating_light (edict_t *self); void SP_object_repair (edict_t *self); @@ -332,6 +334,7 @@ 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_monster_q1_freddie (edict_t *self); void SP_misc_q1_zombie_crucified (edict_t *self); void SP_misc_q1_air_bubbles (edict_t *self); @@ -585,6 +588,8 @@ spawn_t spawns[] = { // Knightmare- the dog from Coconut Monkey 3 {"monster_dog", SP_monster_dog}, + // Knightmare- the vulture from Coconut Monkey 2 + {"monster_vulture", SP_monster_vulture}, {"misc_nuke", SP_misc_nuke}, @@ -706,6 +711,7 @@ spawn_t spawns[] = { {"q1_monster_shalrath", SP_monster_q1_shalrath}, {"q1_monster_tarbaby", SP_monster_q1_tarbaby}, {"q1_monster_zombie", SP_monster_q1_zombie}, + {"q1_monster_freddie", SP_monster_q1_freddie}, // Q2Infighter spawn names // {"monster_q1_chthon", SP_monster_q1_chthon}, @@ -722,6 +728,7 @@ spawn_t spawns[] = { {"monster_q1_shalrath", SP_monster_q1_shalrath}, {"monster_q1_tarbaby", SP_monster_q1_tarbaby}, {"monster_q1_zombie", SP_monster_q1_zombie}, + {"monster_q1_freddie", SP_monster_q1_freddie}, // misc Q1 entities {"misc_q1_zombie_crucified", SP_misc_q1_zombie_crucified}, diff --git a/missionpack/g_thing.c b/missionpack/g_thing.c index c1a6546..05039de 100644 --- a/missionpack/g_thing.c +++ b/missionpack/g_thing.c @@ -3,7 +3,7 @@ qboolean has_valid_enemy (edict_t *self); void HuntTarget (edict_t *self); -edict_t *SpawnThing() +edict_t *SpawnThing (void) { edict_t *thing; thing = G_Spawn(); @@ -16,14 +16,14 @@ void thing_restore_leader (edict_t *self) { edict_t *monster; monster = self->target_ent; - if(!monster || !monster->inuse) + if (!monster || !monster->inuse) { G_FreeEdict(self); return; } - if(monster->monsterinfo.old_leader && monster->monsterinfo.old_leader->inuse) + if (monster->monsterinfo.old_leader && monster->monsterinfo.old_leader->inuse) { - if(VectorCompare(monster->monsterinfo.old_leader->s.origin,self->move_origin)) + if (VectorCompare(monster->monsterinfo.old_leader->s.origin,self->move_origin)) { self->nextthink = level.time + 0.5; return; @@ -48,18 +48,18 @@ void thing_think (edict_t *self) edict_t *monster; monster = self->target_ent; - if(level.time <= self->touch_debounce_time) + if (level.time <= self->touch_debounce_time) { - if(monster && monster->inuse) + if (monster && monster->inuse) { - if(monster->movetarget == self) + if (monster->movetarget == self) { - if(monster->health > 0) + if (monster->health > 0) { VectorSubtract(monster->s.origin,self->s.origin,vec); vec[2] = 0; dist = VectorLength(vec); - if(dist >= monster->size[0]) + if (dist >= monster->size[0]) { self->nextthink = level.time + FRAMETIME; return; @@ -68,19 +68,19 @@ void thing_think (edict_t *self) } } } - if(!monster || !monster->inuse || (monster->health <= 0)) + if (!monster || !monster->inuse || (monster->health <= 0)) { G_FreeEdict(self); return; } - if(monster->goalentity == self) + if (monster->goalentity == self) monster->goalentity = NULL; - if(monster->movetarget == self) + if (monster->movetarget == self) monster->movetarget = NULL; - if(monster->monsterinfo.aiflags & AI_FOLLOW_LEADER) + if (monster->monsterinfo.aiflags & AI_FOLLOW_LEADER) { monster->monsterinfo.leader = NULL; - if(monster->monsterinfo.old_leader && monster->monsterinfo.old_leader->inuse) + if (monster->monsterinfo.old_leader && monster->monsterinfo.old_leader->inuse) { monster->monsterinfo.pausetime = level.time + 2; monster->monsterinfo.stand(monster); @@ -95,7 +95,7 @@ void thing_think (edict_t *self) monster->monsterinfo.aiflags &= ~AI_FOLLOW_LEADER; } } - if(monster->monsterinfo.aiflags & AI_CHICKEN) + if (monster->monsterinfo.aiflags & AI_CHICKEN) { monster->monsterinfo.stand(monster); monster->monsterinfo.aiflags |= AI_STAND_GROUND; @@ -124,26 +124,26 @@ void thing_think (edict_t *self) monster->monsterinfo.stand (monster); // crashes here } -void thing_think_pause(edict_t *self) +void thing_think_pause (edict_t *self) { edict_t *monster; - if(level.time > self->touch_debounce_time) + if (level.time > self->touch_debounce_time) { thing_think(self); return; } monster = self->target_ent; - if(!monster || !monster->inuse) + if (!monster || !monster->inuse) { G_FreeEdict(self); return; } - if(has_valid_enemy(monster)) + if (has_valid_enemy(monster)) { vec3_t dir; vec3_t angles; - if(visible(monster->enemy,monster)) + if (visible(monster->enemy,monster)) { self->touch_debounce_time = 0; thing_think(self); @@ -164,25 +164,25 @@ void thing_grenade_boom (edict_t *self) monster = self->target_ent; G_FreeEdict(self); - if(!monster || !monster->inuse || (monster->health <= 0)) + if (!monster || !monster->inuse || (monster->health <= 0)) return; monster->monsterinfo.aiflags &= ~(AI_CHASE_THING | AI_EVADE_GRENADE | AI_STAND_GROUND); monster->monsterinfo.pausetime = 0; - if(monster->enemy) + if (monster->enemy) monster->monsterinfo.run(monster); } void thing_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { - if(self->target_ent != other) + if (self->target_ent != other) return; - if(other->health <= 0) + if (other->health <= 0) { G_FreeEdict(self); return; } self->touch = NULL; - if( self->target_ent->monsterinfo.aiflags & AI_SEEK_COVER ) + if ( self->target_ent->monsterinfo.aiflags & AI_SEEK_COVER ) { edict_t *monster; // For monster/actor seeking cover after firing, @@ -195,29 +195,29 @@ void thing_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *su self->think(self); return; } - if( self->target_ent->monsterinfo.aiflags & AI_EVADE_GRENADE ) + if ( self->target_ent->monsterinfo.aiflags & AI_EVADE_GRENADE ) { edict_t *grenade = other->next_grenade; - if(other->goalentity == self) + if (other->goalentity == self) other->goalentity = NULL; - if(other->movetarget == self) + if (other->movetarget == self) other->movetarget = NULL; other->vehicle = NULL; - if(grenade) + if (grenade) { // make sure this is still a grenade - if(grenade->inuse) + if (grenade->inuse) { - if(Q_stricmp(grenade->classname,"grenade") && Q_stricmp(grenade->classname,"hgrenade")) + if (Q_stricmp(grenade->classname,"grenade") && Q_stricmp(grenade->classname,"hgrenade")) other->next_grenade = grenade = NULL; } else other->next_grenade = grenade = NULL; } - if(grenade) + if (grenade) { - if(self->touch_debounce_time > level.time) + if (self->touch_debounce_time > level.time) { other->monsterinfo.pausetime = self->touch_debounce_time + 0.1; other->monsterinfo.aiflags |= AI_STAND_GROUND; @@ -240,7 +240,7 @@ void thing_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *su other->enemy = NULL; other->monsterinfo.stand (other); } - if(other->monsterinfo.pausetime > 0) + if (other->monsterinfo.pausetime > 0) { self->think = thing_grenade_boom; self->nextthink = other->monsterinfo.pausetime; @@ -281,7 +281,7 @@ void SP_thing (edict_t *self) self->svflags |= SVF_MONSTER; self->health = 1000; self->takedamage = DAMAGE_NO; - if(developer->value) { + if (developer->value) { gi.setmodel (self, "models/items/c_head/tris.md2"); self->s.effects |= EF_BLASTER; } diff --git a/missionpack/g_utils.c b/missionpack/g_utils.c index 77a57c0..943242e 100644 --- a/missionpack/g_utils.c +++ b/missionpack/g_utils.c @@ -1601,6 +1601,7 @@ qboolean UseSpecialGoodGuyFlag (edict_t *monster) if ( !strcmp(monster->classname, "monster_gekk") || !strcmp(monster->classname, "monster_stalker") + || !strcmp(monster->classname, "monster_vulture") || !strcmp(monster->classname, "monster_handler") ) return true; @@ -1625,6 +1626,7 @@ qboolean UseRegularGoodGuyFlag (edict_t *monster) if ( strcmp(monster->classname, "monster_gekk") && strcmp(monster->classname, "monster_stalker") + && strcmp(monster->classname, "monster_vulture") && strcmp(monster->classname, "monster_turret") && strcmp(monster->classname, "monster_fixbot") && strcmp(monster->classname, "monster_handler") diff --git a/missionpack/g_weapon.c b/missionpack/g_weapon.c index f528b8b..524fd56 100644 --- a/missionpack/g_weapon.c +++ b/missionpack/g_weapon.c @@ -903,6 +903,175 @@ void SP_handgrenade (edict_t *grenade) } +//========================================================================================== +// +// AimGrenade finds the correct aim vector to get a grenade from start to target at initial +// velocity = speed. Returns false if grenade can't make it to target. +// +//========================================================================================== +qboolean AimGrenade (edict_t *self, vec3_t start, vec3_t target, vec_t speed, vec3_t aim) +{ + vec3_t angles, forward, right, up; + vec3_t from_origin, from_muzzle; + vec3_t aim_point; + vec_t xo, yo; + vec_t x; + float cosa, t, vx, y; + float drop; + float last_error, v_error; + int i; + vec3_t last_aim; + + VectorCopy(target,aim_point); + VectorSubtract(aim_point,self->s.origin,from_origin); + VectorSubtract(aim_point, start, from_muzzle); + + if(self->svflags & SVF_MONSTER) + { + VectorCopy(from_muzzle,aim); + VectorNormalize(aim); + yo = from_muzzle[2]; + xo = sqrt(from_muzzle[0]*from_muzzle[0] + from_muzzle[1]*from_muzzle[1]); + } + else + { + VectorCopy(from_origin,aim); + VectorNormalize(aim); + yo = from_origin[2]; + xo = sqrt(from_origin[0]*from_origin[0] + from_origin[1]*from_origin[1]); + } + + // If resulting aim vector is looking straight up or straight down, we're + // done. Actually now that I write this down and think about it... should + // probably check straight up to make sure grenade will actually reach the + // target. + if( (aim[2] == 1.0) || (aim[2] == -1.0)) + return true; + + // horizontal distance to target from muzzle + x = sqrt( from_muzzle[0]*from_muzzle[0] + from_muzzle[1]*from_muzzle[1]); + cosa = sqrt(aim[0]*aim[0] + aim[1]*aim[1]); + // constant horizontal velocity (since grenades don't have drag) + vx = speed * cosa; + // time to reach target x + t = x/vx; + // if flight time is less than one frame, no way grenade will drop much, + // shoot the sucker now. + if(t < FRAMETIME) + return true; + // in that time, grenade will drop this much: + drop = 0.5*sv_gravity->value*t*t; + y = speed*aim[2]*t - drop; + v_error = target[2] - start[2] - y; + + // if we're fairly close and we'll hit target at current angle, + // no need for all this, just shoot it + if( (x < 128) && (fabs(v_error) < 16) ) + return true; + + last_error = 100000.; + VectorCopy(aim,last_aim); + + // Unfortunately there is no closed-form solution for this problem, + // so we creep up on an answer and balk if it takes more than + // 10 iterations to converge to the tolerance we'll accept. + for(i=0; i<10 && fabs(v_error) > 4 && fabs(v_error) < fabs(last_error); i++) + { + last_error = v_error; + aim[2] = cosa * (yo + drop)/xo; + VectorNormalize(aim); + if(!(self->svflags & SVF_MONSTER)) + { + vectoangles(aim,angles); + AngleVectors(angles, forward, right, up); + G_ProjectSource2(self->s.origin,self->move_origin,forward,right,up,start); + VectorSubtract(aim_point,start,from_muzzle); + x = sqrt(from_muzzle[0]*from_muzzle[0] + from_muzzle[1]*from_muzzle[1]); + } + cosa = sqrt(aim[0]*aim[0] + aim[1]*aim[1]); + vx = speed * cosa; + t = x/vx; + drop = 0.5*sv_gravity->value*t*t; + y = speed*aim[2]*t - drop; + v_error = target[2] - start[2] - y; + if(fabs(v_error) < fabs(last_error)) + VectorCopy(aim,last_aim); + } + + if(i >= 10 || v_error > 64) + return false; + if(fabs(v_error) > fabs(last_error)) + { + VectorCopy(last_aim,aim); + if(!(self->svflags & SVF_MONSTER)) + { + vectoangles(aim,angles); + AngleVectors(angles, forward, right, up); + G_ProjectSource2(self->s.origin,self->move_origin,forward,right,up,start); + VectorSubtract(aim_point,start,from_muzzle); + } + } + + // Sanity check... if launcher is at the same elevation or a bit above the + // target entity, check to make sure he won't bounce grenades off the + // top of a doorway or other obstruction. If he WOULD do that, then figure out + // the max elevation angle that will get the grenade through the door, and + // hope we get a good bounce. + if( (start[2] - target[2] < 160) && + (start[2] - target[2] > -16) ) + { + trace_t tr; + vec3_t dist; + + tr = gi.trace(start,vec3_origin,vec3_origin,aim_point,self,MASK_SOLID); + if( (tr.fraction < 1.0) && (!self->enemy || (tr.ent != self->enemy) )) { + // OK... the aim vector hit a solid, but would the grenade actually hit? + int contents; + cosa = sqrt(aim[0]*aim[0] + aim[1]*aim[1]); + vx = speed * cosa; + VectorSubtract(tr.endpos,start,dist); + dist[2] = 0; + x = VectorLength(dist); + t = x/vx; + drop = 0.5*sv_gravity->value*t*(t+FRAMETIME); + tr.endpos[2] -= drop; + // move just a bit in the aim direction + tr.endpos[0] += aim[0]; + tr.endpos[1] += aim[1]; + contents = gi.pointcontents(tr.endpos); + while((contents & MASK_SOLID) && (aim_point[2] > target[2])) { + aim_point[2] -= 8.0; + VectorSubtract(aim_point,self->s.origin,from_origin); + VectorCopy(from_origin,aim); + VectorNormalize(aim); + if(!(self->svflags & SVF_MONSTER)) + { + vectoangles(aim,angles); + AngleVectors(angles, forward, right, up); + G_ProjectSource2(self->s.origin,self->move_origin,forward,right,up,start); + VectorSubtract(aim_point,start,from_muzzle); + } + tr = gi.trace(start,vec3_origin,vec3_origin,aim_point,self,MASK_SOLID); + if(tr.fraction < 1.0) { + cosa = sqrt(aim[0]*aim[0] + aim[1]*aim[1]); + vx = speed * cosa; + VectorSubtract(tr.endpos,start,dist); + dist[2] = 0; + x = VectorLength(dist); + t = x/vx; + drop = 0.5*sv_gravity->value*t*(t+FRAMETIME); + tr.endpos[2] -= drop; + tr.endpos[0] += aim[0]; + tr.endpos[1] += aim[1]; + contents = gi.pointcontents(tr.endpos); + } + } + } + } + return true; +} + + /* ================= fire_missile diff --git a/missionpack/g_weapon_q1.c b/missionpack/g_weapon_q1.c index 2ad12a7..448ef53 100644 --- a/missionpack/g_weapon_q1.c +++ b/missionpack/g_weapon_q1.c @@ -48,10 +48,10 @@ void q1_nail_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t * gi.WriteDir (plane->normal); gi.multicast (self->s.origin, MULTICAST_PVS); - //not if online, too laggy - if(!deathmatch->value) + // not if online, too laggy + if (!deathmatch->value) { - float sound= random(); + float sound = random(); if (sound < 0.3) { if (sound < 0.1) @@ -116,6 +116,16 @@ void q1_fire_nail (edict_t *self, vec3_t start, vec3_t dir, int damage, int spee } +void q1_nail_precache (void) +{ + gi.modelindex ("models/objects/q1nail/tris.md2"); + gi.soundindex ("q1weapons/tink1.wav"); + gi.soundindex ("q1weapons/ric1.wav"); + gi.soundindex ("q1weapons/ric2.wav"); + gi.soundindex ("q1weapons/ric3.wav"); +} + + /* ================= q1_fire_laser @@ -213,6 +223,12 @@ void q1_fire_laser (edict_t *self, vec3_t start, vec3_t dir, int damage, int spe } } +void q1_laser_precache (void) +{ + gi.modelindex ("models/monsters/q1enforcer/laser/tris.md2"); + gi.soundindex ("q1enforcer/enfstop.wav"); +} + /* ================= @@ -272,6 +288,7 @@ void q1_flame_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t G_FreeEdict (self); } + void q1_fire_flame (edict_t *self, vec3_t start, vec3_t dir, float leftrightoff) { edict_t *bolt; @@ -324,6 +341,13 @@ void q1_fire_flame (edict_t *self, vec3_t start, vec3_t dir, float leftrightoff) } +void q1_flame_precache (void) +{ + gi.modelindex ("models/monsters/q1hknight/k_spike/tris.md2"); + gi.soundindex("q1hknight/hit.wav"); +} + + /* ================= q1_fire_grenade @@ -449,6 +473,14 @@ void q1_fire_grenade (edict_t *self, vec3_t start, vec3_t aimdir, int damage, in gi.linkentity (grenade); } +void q1_grenade_precache (void) +{ + gi.modelindex ("models/objects/grenade/tris.md2"); + gi.modelindex ("sprites/s_explod.sp2"); + gi.soundindex ("q1weapons/bounce.wav"); + gi.soundindex ("q1weapons/r_exp3.wav"); +} + /* ================= @@ -481,7 +513,7 @@ void q1_rocket_touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t 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 ("q1weapons/r_exp3.wav"), 1.0, ATTN_NORM, 0); + gi.sound (ent, CHAN_AUTO, gi.soundindex ("q1weapons/r_exp3.wav"), 1.0, ATTN_NORM, 0); gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_ROCKET_EXPLOSION); @@ -579,6 +611,15 @@ void q1_fire_rocket (edict_t *self, vec3_t start, vec3_t dir, int damage, int sp } +void q1_rocket_precahce (void) +{ + gi.modelindex ("models/objects/rocket/tris.md2"); + gi.modelindex ("sprites/s_explod.sp2"); + gi.soundindex ("weapons/rockfly.wav"); + gi.soundindex ("q1weapons/r_exp3.wav"); +} + + /* ================= q1_fire_lightning @@ -599,7 +640,7 @@ void q1_fire_lightning (edict_t *self, vec3_t start, vec3_t dir, int damage) 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)) + 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; } @@ -656,7 +697,7 @@ void q1_firepod_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_ 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 ("q1weapons/r_exp3.wav"), 1.0, ATTN_NORM, 0); + gi.sound (self, CHAN_AUTO, gi.soundindex ("q1weapons/r_exp3.wav"), 1.0, ATTN_NORM, 0); VectorMA (self->s.origin, -0.02, self->velocity, origin); @@ -673,7 +714,7 @@ void q1_firepod_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_ 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.modelindex = gi.modelindex ("sprites/s_explod.sp2"); self->s.frame = 0; self->s.sound = 0; self->s.effects &= ~EF_ANIM_ALLFAST; @@ -770,7 +811,16 @@ void q1_fire_firepod (edict_t *self, vec3_t dir) VectorMA (pod->s.origin, -10, dir, pod->s.origin); pod->touch (pod, tr.ent, NULL, NULL); } -} +} + + +void q1_firepod_precache (void) +{ + gi.modelindex ("models/monsters/q1shalrath/v_spike/tris.md2"); + gi.modelindex ("sprites/s_explod.sp2"); + gi.soundindex ("q1weapons/r_exp3.wav"); +} + /* ================= @@ -861,6 +911,15 @@ void q1_fire_lavaball (edict_t *self, vec3_t start, vec3_t dir, int damage, int gi.linkentity (lavaball); } + +void q1_fire_lavaball_precache (void) +{ + gi.modelindex ("models/monsters/q1chthon/lavaball/tris.md2"); + gi.modelindex ("sprites/s_explod.sp2"); + gi.soundindex ("q1weapons/r_exp3.wav"); +} + + /* ================= q1_acidbolt_touch @@ -943,6 +1002,14 @@ void q1_fire_acidspit (edict_t *self, vec3_t start, vec3_t dir, int damage, int gi.linkentity (acidbolt); } + +void q1_acidspit_precache (void) +{ + gi.modelindex ("models/monsters/q1scrag/w_spike/tris.md2"); + gi.soundindex ("q1scrag/hit.wav"); +} + + /* ================= q1_fire_gib @@ -1022,3 +1089,11 @@ void q1_fire_gib (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int sp gi.linkentity (gib); } + + +void q1_gib_precache (void) +{ + gi.modelindex ("models/monsters/q1zombie/gib/tris.md2"); + gi.soundindex ("q1zombie/z_hit.wav"); + gi.soundindex ("q1zombie/z_miss.wav"); +} diff --git a/missionpack/grenade.c b/missionpack/grenade.c deleted file mode 100644 index 2e18e71..0000000 --- a/missionpack/grenade.c +++ /dev/null @@ -1,169 +0,0 @@ -#include "g_local.h" - -//========================================================================================== -// -// AimGrenade finds the correct aim vector to get a grenade from start to target at initial -// velocity = speed. Returns false if grenade can't make it to target. -// -//========================================================================================== -qboolean AimGrenade (edict_t *self, vec3_t start, vec3_t target, vec_t speed, vec3_t aim) -{ - vec3_t angles, forward, right, up; - vec3_t from_origin, from_muzzle; - vec3_t aim_point; - vec_t xo, yo; - vec_t x; - float cosa, t, vx, y; - float drop; - float last_error, v_error; - int i; - vec3_t last_aim; - - VectorCopy(target,aim_point); - VectorSubtract(aim_point,self->s.origin,from_origin); - VectorSubtract(aim_point, start, from_muzzle); - - if(self->svflags & SVF_MONSTER) - { - VectorCopy(from_muzzle,aim); - VectorNormalize(aim); - yo = from_muzzle[2]; - xo = sqrt(from_muzzle[0]*from_muzzle[0] + from_muzzle[1]*from_muzzle[1]); - } - else - { - VectorCopy(from_origin,aim); - VectorNormalize(aim); - yo = from_origin[2]; - xo = sqrt(from_origin[0]*from_origin[0] + from_origin[1]*from_origin[1]); - } - - // If resulting aim vector is looking straight up or straight down, we're - // done. Actually now that I write this down and think about it... should - // probably check straight up to make sure grenade will actually reach the - // target. - if( (aim[2] == 1.0) || (aim[2] == -1.0)) - return true; - - // horizontal distance to target from muzzle - x = sqrt( from_muzzle[0]*from_muzzle[0] + from_muzzle[1]*from_muzzle[1]); - cosa = sqrt(aim[0]*aim[0] + aim[1]*aim[1]); - // constant horizontal velocity (since grenades don't have drag) - vx = speed * cosa; - // time to reach target x - t = x/vx; - // if flight time is less than one frame, no way grenade will drop much, - // shoot the sucker now. - if(t < FRAMETIME) - return true; - // in that time, grenade will drop this much: - drop = 0.5*sv_gravity->value*t*t; - y = speed*aim[2]*t - drop; - v_error = target[2] - start[2] - y; - - // if we're fairly close and we'll hit target at current angle, - // no need for all this, just shoot it - if( (x < 128) && (fabs(v_error) < 16) ) - return true; - - last_error = 100000.; - VectorCopy(aim,last_aim); - - // Unfortunately there is no closed-form solution for this problem, - // so we creep up on an answer and balk if it takes more than - // 10 iterations to converge to the tolerance we'll accept. - for(i=0; i<10 && fabs(v_error) > 4 && fabs(v_error) < fabs(last_error); i++) - { - last_error = v_error; - aim[2] = cosa * (yo + drop)/xo; - VectorNormalize(aim); - if(!(self->svflags & SVF_MONSTER)) - { - vectoangles(aim,angles); - AngleVectors(angles, forward, right, up); - G_ProjectSource2(self->s.origin,self->move_origin,forward,right,up,start); - VectorSubtract(aim_point,start,from_muzzle); - x = sqrt(from_muzzle[0]*from_muzzle[0] + from_muzzle[1]*from_muzzle[1]); - } - cosa = sqrt(aim[0]*aim[0] + aim[1]*aim[1]); - vx = speed * cosa; - t = x/vx; - drop = 0.5*sv_gravity->value*t*t; - y = speed*aim[2]*t - drop; - v_error = target[2] - start[2] - y; - if(fabs(v_error) < fabs(last_error)) - VectorCopy(aim,last_aim); - } - - if(i >= 10 || v_error > 64) - return false; - if(fabs(v_error) > fabs(last_error)) - { - VectorCopy(last_aim,aim); - if(!(self->svflags & SVF_MONSTER)) - { - vectoangles(aim,angles); - AngleVectors(angles, forward, right, up); - G_ProjectSource2(self->s.origin,self->move_origin,forward,right,up,start); - VectorSubtract(aim_point,start,from_muzzle); - } - } - - // Sanity check... if launcher is at the same elevation or a bit above the - // target entity, check to make sure he won't bounce grenades off the - // top of a doorway or other obstruction. If he WOULD do that, then figure out - // the max elevation angle that will get the grenade through the door, and - // hope we get a good bounce. - if( (start[2] - target[2] < 160) && - (start[2] - target[2] > -16) ) - { - trace_t tr; - vec3_t dist; - - tr = gi.trace(start,vec3_origin,vec3_origin,aim_point,self,MASK_SOLID); - if( (tr.fraction < 1.0) && (!self->enemy || (tr.ent != self->enemy) )) { - // OK... the aim vector hit a solid, but would the grenade actually hit? - int contents; - cosa = sqrt(aim[0]*aim[0] + aim[1]*aim[1]); - vx = speed * cosa; - VectorSubtract(tr.endpos,start,dist); - dist[2] = 0; - x = VectorLength(dist); - t = x/vx; - drop = 0.5*sv_gravity->value*t*(t+FRAMETIME); - tr.endpos[2] -= drop; - // move just a bit in the aim direction - tr.endpos[0] += aim[0]; - tr.endpos[1] += aim[1]; - contents = gi.pointcontents(tr.endpos); - while((contents & MASK_SOLID) && (aim_point[2] > target[2])) { - aim_point[2] -= 8.0; - VectorSubtract(aim_point,self->s.origin,from_origin); - VectorCopy(from_origin,aim); - VectorNormalize(aim); - if(!(self->svflags & SVF_MONSTER)) - { - vectoangles(aim,angles); - AngleVectors(angles, forward, right, up); - G_ProjectSource2(self->s.origin,self->move_origin,forward,right,up,start); - VectorSubtract(aim_point,start,from_muzzle); - } - tr = gi.trace(start,vec3_origin,vec3_origin,aim_point,self,MASK_SOLID); - if(tr.fraction < 1.0) { - cosa = sqrt(aim[0]*aim[0] + aim[1]*aim[1]); - vx = speed * cosa; - VectorSubtract(tr.endpos,start,dist); - dist[2] = 0; - x = VectorLength(dist); - t = x/vx; - drop = 0.5*sv_gravity->value*t*(t+FRAMETIME); - tr.endpos[2] -= drop; - tr.endpos[0] += aim[0]; - tr.endpos[1] += aim[1]; - contents = gi.pointcontents(tr.endpos); - } - } - } - } - return true; -} diff --git a/missionpack/laz_misc.h b/missionpack/laz_misc.h index bd84369..8d68434 100644 --- a/missionpack/laz_misc.h +++ b/missionpack/laz_misc.h @@ -419,5 +419,6 @@ ENTITY_MISC_Q1_TORCH, ENTITY_TARGET_Q1_TRAPSHOOTER, ENTITY_MISC_Q1_EXPLOBOX, ENTITY_Q1_FIREBALL, -ENTITY_MISC_Q1_FIREBALL_SPAWNER +ENTITY_MISC_Q1_FIREBALL_SPAWNER, +ENTITY_MONSTER_Q1_FREDDIE } entity_id; diff --git a/missionpack/m_flipper.c b/missionpack/m_flipper.c index 7480123..d3e2953 100644 --- a/missionpack/m_flipper.c +++ b/missionpack/m_flipper.c @@ -256,7 +256,7 @@ void flipper_dead (edict_t *self) M_FlyCheck (self); // Lazarus monster fade - if(world->effects & FX_WORLDSPAWN_CORPSEFADE) + if (world->effects & FX_WORLDSPAWN_CORPSEFADE) { self->think=FadeDieSink; self->nextthink=level.time+corpse_fadetime->value; @@ -398,11 +398,11 @@ void SP_monster_flipper (edict_t *self) VectorSet (self->mins, -16, -16, -8); VectorSet (self->maxs, 16, 16, 24); - if(!self->health) + if (!self->health) self->health = 50; - if(!self->gib_health) + if (!self->gib_health) self->gib_health = -40; //was -30 - if(!self->mass) + if (!self->mass) self->mass = 100; self->pain = flipper_pain; diff --git a/missionpack/m_flyer.c b/missionpack/m_flyer.c index 3a40dc5..73f4250 100644 --- a/missionpack/m_flyer.c +++ b/missionpack/m_flyer.c @@ -348,12 +348,12 @@ mmove_t flyer_move_stop = {FRAME_stop01, FRAME_stop07, flyer_frames_stop, NULL}; void flyer_stop (edict_t *self) { - self->monsterinfo.currentmove = &flyer_move_stop; + self->monsterinfo.currentmove = &flyer_move_stop; } void flyer_start (edict_t *self) { - self->monsterinfo.currentmove = &flyer_move_start; + self->monsterinfo.currentmove = &flyer_move_start; } @@ -846,7 +846,7 @@ void SP_monster_flyer (edict_t *self) self->monsterinfo.blocked = flyer_blocked; if (!self->blood_type) - self->blood_type = 3; //sparks and blood + self->blood_type = 3; // sparks and blood // Lazarus if (self->powerarmor) diff --git a/missionpack/m_gladiator.c b/missionpack/m_gladiator.c index d20d80f..022a387 100644 --- a/missionpack/m_gladiator.c +++ b/missionpack/m_gladiator.c @@ -140,7 +140,7 @@ mframe_t gladiator_frames_attack_melee [] = }; mmove_t gladiator_move_attack_melee = {FRAME_melee1, FRAME_melee17, gladiator_frames_attack_melee, gladiator_run}; -void gladiator_melee(edict_t *self) +void gladiator_melee (edict_t *self) { self->monsterinfo.currentmove = &gladiator_move_attack_melee; } diff --git a/missionpack/m_gunner.c b/missionpack/m_gunner.c index 5a7c7b3..01526a0 100644 --- a/missionpack/m_gunner.c +++ b/missionpack/m_gunner.c @@ -28,7 +28,7 @@ static int sound_sight; void gunner_idlesound (edict_t *self) { - if(!(self->spawnflags & SF_MONSTER_AMBUSH)) + if (!(self->spawnflags & SF_MONSTER_AMBUSH)) gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0); } @@ -321,7 +321,7 @@ void gunner_dead (edict_t *self) M_FlyCheck (self); // Lazarus monster fade - if(world->effects & FX_WORLDSPAWN_CORPSEFADE) + if (world->effects & FX_WORLDSPAWN_CORPSEFADE) { self->think=FadeDieSink; self->nextthink=level.time+corpse_fadetime->value; @@ -354,9 +354,9 @@ void gunner_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damag if (self->health <= self->gib_health && !(self->spawnflags & SF_MONSTER_NOGIB)) { gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0); - for (n= 0; n < 2; n++) + for (n = 0; n < 2; n++) ThrowGib (self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC); - for (n= 0; n < 4; n++) + for (n = 0; n < 4; n++) ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC); ThrowGib (self, "models/objects/gibs/chest/tris.md2", damage, GIB_ORGANIC); ThrowHead (self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC); @@ -384,12 +384,12 @@ qboolean gunner_grenade_check(edict_t *self) vec3_t vhorz; float horz,vertmax; - if(!self->enemy) + if (!self->enemy) return false; // if the player is above my head, use machinegun. -// if(self->absmax[2] <= self->enemy->absmin[2]) +// if (self->absmax[2] <= self->enemy->absmin[2]) // return false; // Lazarus: We can do better than that... see below @@ -411,7 +411,7 @@ qboolean gunner_grenade_check(edict_t *self) horz = VectorLength(vhorz); vertmax = (GRENADE_VELOCITY_SQUARED)/(2*sv_gravity->value) - 0.5*sv_gravity->value*horz*horz/GRENADE_VELOCITY_SQUARED; - if(dir[2] > vertmax) + if (dir[2] > vertmax) return false; // Lazarus: Make sure there's a more-or-less clear flight path to target @@ -420,13 +420,13 @@ qboolean gunner_grenade_check(edict_t *self) VectorCopy(self->enemy->s.origin,target); target[2] = self->enemy->absmax[2]; tr = gi.trace(start, vec3_origin, vec3_origin, target, self, MASK_SHOT); - if(tr.ent == self->enemy || tr.fraction == 1) + if (tr.ent == self->enemy || tr.fraction == 1) return true; // Repeat for feet... in case we're looking down at a target standing under, // for example, a short doorway target[2] = self->enemy->absmin[2]; tr = gi.trace(start, vec3_origin, vec3_origin, target, self, MASK_SHOT); - if(tr.ent == self->enemy || tr.fraction == 1) + if (tr.ent == self->enemy || tr.fraction == 1) return true; return false; @@ -484,7 +484,7 @@ void GunnerFire (edict_t *self) vec3_t aim; int flash_number; - if(!self->enemy || !self->enemy->inuse) //PGM + if (!self->enemy || !self->enemy->inuse) //PGM return; //PGM flash_number = MZ2_GUNNER_MACHINEGUN_1 + (self->s.frame - FRAME_attak216); @@ -498,7 +498,7 @@ void GunnerFire (edict_t *self) target[2] += self->enemy->viewheight; // Lazarus fog reduction of accuracy - if(self->monsterinfo.visibility < FOG_CANSEEGOOD) + if (self->monsterinfo.visibility < FOG_CANSEEGOOD) { target[0] += crandom() * 640 * (FOG_CANSEEGOOD - self->monsterinfo.visibility); target[1] += crandom() * 640 * (FOG_CANSEEGOOD - self->monsterinfo.visibility); @@ -523,7 +523,7 @@ void GunnerGrenade (edict_t *self) vec3_t target; qboolean blindfire; - if(!self->enemy || !self->enemy->inuse) //PGM + if (!self->enemy || !self->enemy->inuse) //PGM return; //PGM // pmm @@ -572,7 +572,7 @@ void GunnerGrenade (edict_t *self) G_ProjectSource (self->s.origin, monster_flash_offset[flash_number], forward, right, start); //PGM - if(self->enemy) + if (self->enemy) { float dist; @@ -582,10 +582,10 @@ void GunnerGrenade (edict_t *self) // aim at enemy's feet if he's at same elevation or lower. otherwise aim at origin VectorCopy(self->enemy->s.origin,target); - if(self->enemy->absmin[2] <= self->absmax[2]) target[2] = self->enemy->absmin[2]; + if (self->enemy->absmin[2] <= self->absmax[2]) target[2] = self->enemy->absmin[2]; // Lazarus fog reduction of accuracy - if(self->monsterinfo.visibility < FOG_CANSEEGOOD) + if (self->monsterinfo.visibility < FOG_CANSEEGOOD) { target[0] += crandom() * 640 * (FOG_CANSEEGOOD - self->monsterinfo.visibility); target[1] += crandom() * 640 * (FOG_CANSEEGOOD - self->monsterinfo.visibility); @@ -593,7 +593,7 @@ void GunnerGrenade (edict_t *self) } // lead target... 20, 35, 50, 65 chance of leading - if( random() < (0.2 + skill->value * 0.15) ) + if ( random() < (0.2 + skill->value * 0.15) ) { float dist; float time; @@ -605,14 +605,14 @@ void GunnerGrenade (edict_t *self) } // aim up if they're on the same level as me and far away. - if((dist > 512) && (aim[2] < 64) && (aim[2] > -64)) + if ((dist > 512) && (aim[2] < 64) && (aim[2] > -64)) aim[2] += (dist - 512); /* VectorNormalize (aim); pitch = aim[2]; - if(pitch > 0.4) + if (pitch > 0.4) pitch = 0.4; - else if(pitch < -0.5) + else if (pitch < -0.5) pitch = -0.5;*/ } //PGM @@ -621,7 +621,7 @@ void GunnerGrenade (edict_t *self) // Lazarus - take into account (sort of) feature of adding shooter's velocity to // grenade velocity monster_speed = VectorLength(self->velocity); - if(monster_speed > 0) + if (monster_speed > 0) { vec3_t v1; vec_t delta; @@ -930,11 +930,11 @@ void gunner_jump2_now (edict_t *self) void gunner_jump_wait_land (edict_t *self) { - if(self->groundentity == NULL) + if (self->groundentity == NULL) { self->monsterinfo.nextframe = self->s.frame; - if(monster_jump_finished (self)) + if (monster_jump_finished (self)) self->monsterinfo.nextframe = self->s.frame + 1; } else @@ -973,12 +973,12 @@ mmove_t gunner_move_jump2 = { FRAME_jump01, FRAME_jump10, gunner_frames_jump2, g void gunner_jump (edict_t *self) { - if(!self->enemy) + if (!self->enemy) return; monster_done_dodge (self); - if(self->enemy->s.origin[2] > self->s.origin[2]) + if (self->enemy->s.origin[2] > self->s.origin[2]) self->monsterinfo.currentmove = &gunner_move_jump2; else self->monsterinfo.currentmove = &gunner_move_jump; @@ -988,13 +988,13 @@ void gunner_jump (edict_t *self) //PGM qboolean gunner_blocked (edict_t *self, float dist) { - if(blocked_checkshot (self, 0.25 + (0.05 * skill->value) )) + if (blocked_checkshot (self, 0.25 + (0.05 * skill->value) )) return true; - if(blocked_checkplat (self, dist)) + if (blocked_checkplat (self, dist)) return true; - if(blocked_checkjump (self, dist, 192, 40)) + if (blocked_checkjump (self, dist, 192, 40)) { gunner_jump(self); return true; diff --git a/missionpack/m_mutant.c b/missionpack/m_mutant.c index 4095b9a..987174b 100644 --- a/missionpack/m_mutant.c +++ b/missionpack/m_mutant.c @@ -157,7 +157,7 @@ mmove_t mutant_move_idle = {FRAME_stand152, FRAME_stand164, mutant_frames_idle, void mutant_idle (edict_t *self) { self->monsterinfo.currentmove = &mutant_move_idle; - if(!(self->spawnflags & SF_MONSTER_AMBUSH)) + if (!(self->spawnflags & SF_MONSTER_AMBUSH)) gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0); } @@ -528,7 +528,7 @@ void mutant_dead (edict_t *self) M_FlyCheck (self); // Lazarus monster fade - if(world->effects & FX_WORLDSPAWN_CORPSEFADE) + if (world->effects & FX_WORLDSPAWN_CORPSEFADE) { self->think=FadeDieSink; self->nextthink=level.time+corpse_fadetime->value; @@ -619,7 +619,7 @@ void mutant_jump_up (edict_t *self) void mutant_jump_wait_land (edict_t *self) { - if(self->groundentity == NULL) + if (self->groundentity == NULL) self->monsterinfo.nextframe = self->s.frame; else self->monsterinfo.nextframe = self->s.frame + 1; @@ -647,10 +647,10 @@ mmove_t mutant_move_jump_down = { FRAME_jump01, FRAME_jump05, mutant_frames_jump void mutant_jump_updown (edict_t *self) { - if(!self->enemy) + if (!self->enemy) return; - if(self->enemy->s.origin[2] > self->s.origin[2]) + if (self->enemy->s.origin[2] > self->s.origin[2]) self->monsterinfo.currentmove = &mutant_move_jump_up; else self->monsterinfo.currentmove = &mutant_move_jump_down; @@ -663,13 +663,13 @@ Blocked */ qboolean mutant_blocked (edict_t *self, float dist) { - if(blocked_checkjump (self, dist, 256, 68)) + if (blocked_checkjump (self, dist, 256, 68)) { mutant_jump_updown (self); return true; } - if(blocked_checkplat (self, dist)) + if (blocked_checkplat (self, dist)) return true; return false; //Knightmare- this is to prevent warnings @@ -719,11 +719,11 @@ void SP_monster_mutant (edict_t *self) VectorSet (self->mins, -32, -32, -24); VectorSet (self->maxs, 32, 32, 48); - if(!self->health) + if (!self->health) self->health = 300; - if(!self->gib_health) + if (!self->gib_health) self->gib_health = -120; - if(!self->mass) + if (!self->mass) self->mass = 300; self->pain = mutant_pain; @@ -741,11 +741,11 @@ void SP_monster_mutant (edict_t *self) self->monsterinfo.checkattack = mutant_checkattack; self->monsterinfo.blocked = mutant_blocked; // PGM - if(!self->monsterinfo.flies) + if (!self->monsterinfo.flies) self->monsterinfo.flies = 0.80; // Lazarus - if(self->powerarmor) + if (self->powerarmor) { if (self->powerarmortype == 1) self->monsterinfo.power_armor_type = POWER_ARMOR_SCREEN; diff --git a/missionpack/m_q1dog.c b/missionpack/m_q1dog.c index ed4bea1..b6ee388 100644 --- a/missionpack/m_q1dog.c +++ b/missionpack/m_q1dog.c @@ -12,6 +12,7 @@ QUAKE DOG static int sound_pain; static int sound_death; +static int sound_gib; static int sound_attack; static int sound_sight; static int sound_idle; @@ -397,7 +398,7 @@ void q1dog_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage if (self->health <= self->gib_health && !(self->spawnflags & SF_MONSTER_NOGIB)) { - gi.sound (self, CHAN_VOICE|CHAN_RELIABLE, gi.soundindex ("q1player/udeath.wav"), 1, ATTN_NORM, 0); + gi.sound (self, CHAN_VOICE|CHAN_RELIABLE, sound_gib, 1, ATTN_NORM, 0); ThrowGib (self, "models/objects/q1gibs/q1gib1/tris.md2", damage, GIB_ORGANIC); for (n= 0; n < 2; n++) @@ -438,10 +439,16 @@ void SP_monster_q1_dog (edict_t *self) } sound_pain = gi.soundindex ("q1dog/dpain1.wav"); sound_death = gi.soundindex ("q1dog/ddeath.wav"); + sound_gib = gi.soundindex ("q1player/udeath.wav"); sound_attack = gi.soundindex ("q1dog/dattack1.wav"); sound_sight = gi.soundindex ("q1dog/dsight.wav"); sound_idle = gi.soundindex ("q1dog/idle.wav"); - + + // precache gibs + gi.modelindex ("models/monsters/q1dog/head/tris.md2"); + gi.modelindex ("models/objects/q1gibs/q1gib1/tris.md2"); + gi.modelindex ("models/objects/q1gibs/q1gib3/tris.md2"); + self->movetype = MOVETYPE_STEP; self->solid = SOLID_BBOX; diff --git a/missionpack/m_q1enforcer.c b/missionpack/m_q1enforcer.c index 44b8b68..c162033 100644 --- a/missionpack/m_q1enforcer.c +++ b/missionpack/m_q1enforcer.c @@ -12,6 +12,7 @@ QUAKE ENFORCER static int sound_pain1; static int sound_pain2; static int sound_death; +static int sound_gib; static int sound_idle; static int sound_sight1; static int sound_sight2; @@ -253,7 +254,7 @@ void q1enforcer_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int d // check for gib if (self->health <= self->gib_health && !(self->spawnflags & SF_MONSTER_NOGIB)) { - gi.sound (self, CHAN_VOICE|CHAN_RELIABLE, gi.soundindex ("q1player/udeath.wav"), 1, ATTN_NORM, 0); + gi.sound (self, CHAN_VOICE|CHAN_RELIABLE, sound_gib, 1, ATTN_NORM, 0); for (n= 0; n < 2; n++) ThrowGib (self, "models/objects/q1gibs/q1gib1/tris.md2", damage, GIB_ORGANIC); @@ -347,6 +348,7 @@ void SP_monster_q1_enforcer (edict_t *self) sound_pain1 = gi.soundindex ("q1enforcer/pain1.wav"); sound_pain2 = gi.soundindex ("q1enforcer/pain2.wav"); sound_death = gi.soundindex ("q1enforcer/death1.wav"); + sound_gib = gi.soundindex ("q1player/udeath.wav"); sound_idle = gi.soundindex ("q1enforcer/idle1.wav"); sound_sight1 = gi.soundindex ("q1enforcer/sight1.wav"); sound_sight2 = gi.soundindex ("q1enforcer/sight2.wav"); @@ -357,6 +359,12 @@ void SP_monster_q1_enforcer (edict_t *self) // precache backpack gi.modelindex ("models/items/q1backpack/tris.md2"); // gi.soundindex ("q1weapons/lock4.wav"); + // precache gibs + gi.modelindex ("models/monsters/q1enforcer/head/tris.md2"); + gi.modelindex ("models/objects/q1gibs/q1gib1/tris.md2"); + gi.modelindex ("models/objects/q1gibs/q1gib3/tris.md2"); + // precache laser + q1_laser_precache (); self->movetype = MOVETYPE_STEP; self->solid = SOLID_BBOX; diff --git a/missionpack/m_q1fiend.c b/missionpack/m_q1fiend.c index 006ba52..776a0ca 100644 --- a/missionpack/m_q1fiend.c +++ b/missionpack/m_q1fiend.c @@ -13,6 +13,7 @@ QUAKE FIEND static int sound_hit; static int sound_jump; static int sound_death; +static int sound_gib; static int sound_idle; static int sound_pain; static int sound_sight; @@ -413,7 +414,7 @@ void fiend_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage if (self->health <= self->gib_health && !(self->spawnflags & SF_MONSTER_NOGIB)) { - gi.sound (self, CHAN_VOICE|CHAN_RELIABLE, gi.soundindex ("q1player/udeath.wav"), 1, ATTN_NORM, 0); + gi.sound (self, CHAN_VOICE|CHAN_RELIABLE, sound_gib, 1, ATTN_NORM, 0); for (n= 0; n < 2; n++) ThrowGib (self, "models/objects/q1gibs/q1gib1/tris.md2", damage, GIB_ORGANIC); @@ -452,13 +453,19 @@ void SP_monster_q1_fiend (edict_t *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"); + sound_hit = gi.soundindex ("q1fiend/dhit2.wav"); + sound_jump = gi.soundindex ("q1fiend/djump.wav"); + sound_death = gi.soundindex ("q1fiend/ddeath.wav"); + sound_gib = gi.soundindex ("q1player/udeath.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"); + + // precache gibs + gi.modelindex ("models/monsters/q1fiend/head/tris.md2"); + gi.modelindex ("models/objects/q1gibs/q1gib1/tris.md2"); + gi.modelindex ("models/objects/q1gibs/q1gib3/tris.md2"); self->movetype = MOVETYPE_STEP; self->solid = SOLID_BBOX; diff --git a/missionpack/m_q1freddie.c b/missionpack/m_q1freddie.c new file mode 100644 index 0000000..08f069a --- /dev/null +++ b/missionpack/m_q1freddie.c @@ -0,0 +1,890 @@ +/*============================================================================== + +Quake AD FREDDIE (Edie from Quoth - Kell/Necros/Preach) +Reimplemented by Knightmare and MikeM + +============================================================================== +*/ + +#include "g_local.h" +#include "m_q1freddie.h" + +static int sound_pain1; +static int sound_pain2; +static int sound_death; +static int sound_death2; +static int sound_idle; +static int sound_sight; +static int sound_saw; +static int sound_melee; +static int sound_atk_spinup; +static int sound_atk_nail; +static int sound_atk_laser; +static int sound_step1; +static int sound_step2; +static int sound_step3; + +#define SF_FREDDIE_LASER 32 +#define FREDDIE_MELEE_DISTANCE 64 + +void freddie_fireweapon (edict_t *self, vec3_t offset); +void freddie_attack(edict_t *self); +void freddie_check_refire (edict_t *self); + +void freddie_idle_sound (edict_t *self) +{ + if (random() < 0.2) + gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0); +} + +void freddie_sight (edict_t *self, edict_t *other) +{ + gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0); + freddie_attack (self); +} + +void freddie_sound_footstep (edict_t *self) +{ + static int stepNum = 0; + + switch (stepNum) + { + case 0: + default: + gi.sound (self, CHAN_BODY, sound_step1, 1, ATTN_NORM, 0); + break; + case 1: + gi.sound (self, CHAN_BODY, sound_step2, 1, ATTN_NORM, 0); + break; + case 2: + gi.sound (self, CHAN_BODY, sound_step1, 1, ATTN_NORM, 0); + break; + case 3: + gi.sound (self, CHAN_BODY, sound_step2, 1, ATTN_NORM, 0); + break; + case 4: + gi.sound (self, CHAN_BODY, sound_step3, 1, ATTN_NORM, 0); + break; + } + stepNum++; + if (stepNum > 4) + stepNum = 0; +} + +// +// stand +// + +void freddie_stand (edict_t *self); + +mframe_t freddie_frames_stand [] = +{ + ai_stand, 0, freddie_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, +}; +mmove_t freddie_move_stand = {FRAME_stand1, FRAME_stand8, freddie_frames_stand, freddie_stand}; + +void freddie_stand (edict_t *self) +{ + self->monsterinfo.currentmove = &freddie_move_stand; +} + +// +// walk +// + +void freddie_walk (edict_t *self); + +mframe_t freddie_frames_walk [] = +{ + ai_walk, 20, freddie_idle_sound, + ai_walk, 16, freddie_sound_footstep, + ai_walk, 1, NULL, + ai_walk, 2, NULL, + ai_walk, 4, NULL, + ai_walk, 8, NULL, + ai_walk, 4, NULL, + ai_walk, 16, NULL, + ai_walk, 20, NULL, + ai_walk, 16, freddie_sound_footstep, + ai_walk, 1, NULL, + ai_walk, 2, NULL, + ai_walk, 4, NULL, + ai_walk, 8, NULL, + ai_walk, 4, NULL, + ai_walk, 16, NULL, +}; +mmove_t freddie_move_walk = {FRAME_run1, FRAME_run6, freddie_frames_walk, NULL}; + +void freddie_walk (edict_t *self) +{ + self->monsterinfo.currentmove = &freddie_move_walk; +} + +// +// run +// + +void freddie_run (edict_t *self); +void freddie_run_frame (edict_t *self); + +mframe_t freddie_frames_run [] = +{ + ai_run, 24, freddie_run_frame, // freddie_idle_sound, + ai_run, 19, freddie_run_frame, // freddie_sound_footstep, + ai_run, 1, freddie_run_frame, + ai_run, 2, freddie_run_frame, + ai_run, 5, freddie_run_frame, + ai_run, 10, freddie_run_frame, + ai_run, 5, freddie_run_frame, + ai_run, 5, freddie_run_frame, + ai_run, 24, freddie_run_frame, + ai_run, 19, freddie_run_frame, + ai_run, 1, freddie_run_frame, // freddie_sound_footstep, + ai_run, 2, freddie_run_frame, + ai_run, 5, freddie_run_frame, + ai_run, 10, freddie_run_frame, + ai_run, 5, freddie_run_frame, + ai_run, 5, freddie_run_frame, +}; +mmove_t freddie_move_run = {FRAME_run1, FRAME_run16, freddie_frames_run, NULL}; + +void freddie_run (edict_t *self) +{ + if (self->monsterinfo.aiflags & AI_STAND_GROUND) + self->monsterinfo.currentmove = &freddie_move_stand; + else + self->monsterinfo.currentmove = &freddie_move_run; +} + +// +// run + firing +// + +mframe_t freddie_frames_rfire [] = +{ + ai_run, 24, freddie_run_frame, // freddie_idle_sound, + ai_run, 19, freddie_run_frame, // freddie_sound_footstep, + ai_run, 1, freddie_run_frame, + ai_run, 2, freddie_run_frame, + ai_run, 5, freddie_run_frame, + ai_run, 10, freddie_run_frame, + ai_run, 5, freddie_run_frame, + ai_run, 5, freddie_run_frame, + ai_run, 24, freddie_run_frame, + ai_run, 19, freddie_run_frame, + ai_run, 1, freddie_run_frame, // freddie_sound_footstep, + ai_run, 2, freddie_run_frame, + ai_run, 5, freddie_run_frame, + ai_run, 10, freddie_run_frame, + ai_run, 5, freddie_run_frame, + ai_run, 5, freddie_run_frame, +}; +mmove_t freddie_move_rfire = {FRAME_rfire1, FRAME_rfire16, freddie_frames_rfire, NULL}; + +void freddie_rfire (edict_t *self) +{ + if (self->monsterinfo.aiflags & AI_STAND_GROUND) + self->monsterinfo.currentmove = &freddie_move_stand; + else + self->monsterinfo.currentmove = &freddie_move_rfire; +} + +void freddie_run_frame (edict_t *self) +{ + int startFrame = 0; + + if ( !self || (self->health <= 0) ) + return; + + // If enemy is dead or missing no firing +// if ( !self->enemy || (self->enemy->health <= 0) ) +// self-> + + if (self->monsterinfo.currentmove == &freddie_move_run) + startFrame = FRAME_run1; + else if (self->monsterinfo.currentmove == &freddie_move_rfire) + startFrame = FRAME_rfire1; + + switch (self->s.frame - startFrame) + { + case 0: + VectorSet (self->muzzle, 50, -20, 32); freddie_idle_sound (self); + break; + case 1: + VectorSet (self->muzzle, 43, -18, 33); freddie_sound_footstep (self); + break; + case 2: + VectorSet (self->muzzle, 53, -20, 27); + break; + case 3: + VectorSet (self->muzzle, 47, -19, 31); + break; + case 4: + VectorSet (self->muzzle, 54, -17, 29); + break; + case 5: + VectorSet (self->muzzle, 47, -17, 35); + break; + case 6: + VectorSet (self->muzzle, 53, -15, 32); + break; + case 7: + VectorSet (self->muzzle, 47, -15, 36); + break; + case 8: + VectorSet (self->muzzle, 50, -13, 32); + break; + case 9: + VectorSet (self->muzzle, 46, -15, 33); + break; + case 10: + VectorSet (self->muzzle, 51, -14, 33); freddie_sound_footstep (self); + break; + case 11: + VectorSet (self->muzzle, 47, -14, 32); + break; + case 12: + VectorSet (self->muzzle, 52, -14, 33); + break; + case 13: + VectorSet (self->muzzle, 47, -14, 36); + break; + case 14: + VectorSet (self->muzzle, 49, -14, 35); + break; + case 15: + VectorSet (self->muzzle, 45, -15, 34); + break; + default: + VectorSet (self->muzzle, 0, 0, 0); + break; + } + + // Run + Fire time? +/* if (self->fog_model > 0) + { + self->fog_index++; + if (self->fog_index > 2) + self->fog_model = 0; + else + freddie_fireweapon (self, self->muzzle); + }*/ +} + + +// +// pain +// + +void freddie_pain (edict_t *self, edict_t *other, float kick, int damage); + +mframe_t freddie_frames_pain1 [] = +{ + ai_move, 0, NULL, + ai_move, 10, NULL, + ai_move, 9, 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, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL +}; +mmove_t freddie_move_pain1 = {FRAME_pain1, FRAME_pain12, freddie_frames_pain1, freddie_run}; + +mframe_t freddie_frames_pain2 [] = +{ + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL +}; +mmove_t freddie_move_pain2 = {FRAME_painb1, FRAME_painb5, freddie_frames_pain2, freddie_run}; + + +void freddie_pain (edict_t *self, edict_t *other, float kick, int damage) +{ + float r; + + if (level.time < self->pain_debounce_time) + return; + + r = random(); + + if (r < 0.5f) + gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0); + else + gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0); + + self->pain_debounce_time = level.time + 3 + random() * 2; + + if (skill->value == 3) { + self->pain_debounce_time = level.time + 3 + random() * 2; + return; // no pain anims in nightmare + } + + if (damage <= 50) { + self->monsterinfo.currentmove = &freddie_move_pain2; + self->pain_debounce_time = level.time + 2 + random() * 2; + } + else { + self->monsterinfo.currentmove = &freddie_move_pain1; + self->pain_debounce_time = level.time + 3 + random() * 2; + } +} + +// +// fire (standing) +// + +void freddie_attack (edict_t *self); +void freddie_do_sfire (edict_t *self); +void freddie_attack_spindown (edict_t *self); + +void freddie_attack_spinupsound (edict_t *self) +{ + gi.sound (self, CHAN_BODY, sound_atk_spinup, 1.0, ATTN_NORM, 0); +} + +void freddie_attack_prefire (edict_t *self) +{ + self->fog_index = 0; + self->fogclip = 4 + (int)skill->value * 2; +} + +void freddie_fireweapon (edict_t *self, vec3_t offset) +{ + vec3_t start, forward, right, dir, vec; // attack_track + float speed, scale; + + if ( !self || (self->health <= 0) ) + return; + if ( !self->enemy || (self->enemy->health < 1) ) // If no enemy or enemy dead then stop attack + return; + + // Nail and laser use the same firing speed + speed = 500 + (int)skill->value * 150; + // Rotate offset vector + AngleVectors (self->s.angles, forward, right, NULL); + G_ProjectSource (self->s.origin, offset, forward, right, start); + +/* if ( (self->fog_model != 0) && ((int)skill->value > 1) ) // The mini burst mode (run+fire) can do tracking + { + if (self->fog_index == 1) + Freddie_Tracking (self->enemy->s.origin, offset, self->enemy, speed, attack_track); + else + Freddie_Tracking (attack_track, offset, self->enemy, speed, attack_track); + VectorSubtract (attack_track, start, dir); + VectorNormalize (dir); + } + else*/ // Standard mode spray bullets at player + { + scale = crandom() * (20 + (random() * 50)); + VectorScale (right, scale, vec); + VectorAdd (self->enemy->s.origin, vec, dir); + VectorSubtract (dir, start, dir); + VectorNormalize (dir); + } + + if (self->spawnflags & SF_FREDDIE_LASER) { + gi.sound (self, CHAN_WEAPON|CHAN_RELIABLE, sound_atk_laser, 1.0, ATTN_NORM, 0); + q1_fire_laser (self, start, dir, 15, speed); + } + else { + gi.sound (self, CHAN_WEAPON|CHAN_RELIABLE, sound_atk_nail, 1.0, ATTN_NORM, 0); + q1_fire_nail (self, start, dir, 9, speed, true); + } +} + +void freddie_stand_fire (edict_t *self) +{ + vec3_t offset; + qboolean quitNext = false; + + // Easy = 7 shots, Normal = 11 shots, Hard/NM = 15 shots + switch (self->s.frame) + { + case FRAME_sfire9: + VectorSet (offset, 45, -10, 20); + break; + case FRAME_sfire10: + VectorSet (offset, 45, -10, 20); + break; + case FRAME_sfire11: + VectorSet (offset, 45, -10, 22); + break; + case FRAME_sfire12: + VectorSet (offset, 45, -10, 22); + break; + case FRAME_sfire13: + VectorSet (offset, 45, -12, 23); + break; + case FRAME_sfire14: + VectorSet (offset, 42, -12, 25); + break; + case FRAME_sfire15: + VectorSet (offset, 42, -14, 23); + if ((int)skill->value == 0) + quitNext = true; + break; + case FRAME_sfire16: + VectorSet (offset, 38, -14, 27); + break; + case FRAME_sfire17: + VectorSet (offset, 38, -17, 26); + break; + case FRAME_sfire18: + VectorSet (offset, 36, -17, 28); + break; + case FRAME_sfire19: + VectorSet (offset, 36, -17, 26); + if ((int)skill->value == 1) + quitNext = true; + break; + case FRAME_sfire20: + VectorSet (offset, 30, -17, 28); + break; + case FRAME_sfire21: + VectorSet (offset, 30, -18, 25); + break; + case FRAME_sfire22: + VectorSet (offset, 25, -18, 27); + break; + case FRAME_sfire23: + VectorSet (offset, 25, -18, 27); + break; + default: + VectorSet (offset, 0, 0, 0); + break; + } + + if ( !self->enemy || (self->enemy->health < 1) ) // If no enemy or enemy dead then stop attack + self->fog_index = self->fogclip + 1; + else if ( visible(self, self->enemy) ) // Check if enemy is visible to weapon + self->fog_index++; + else // Reset counter and keep firing + self->fog_index = 0; + + if (self->fog_index > self->fogclip) + freddie_attack_spindown (self); + else + freddie_fireweapon (self, offset); + + if (quitNext) // this is our last firing frame based on skill level + self->fog_index = self->fogclip + 1; +} + +mframe_t freddie_frames_sfire_start [] = +{ + ai_charge, 0, freddie_attack_spinupsound, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, freddie_sound_footstep, + ai_charge, 0, NULL, + ai_charge, 0, NULL, + ai_charge, 0, freddie_attack_prefire +}; +mmove_t freddie_move_sfire_start = {FRAME_sfire1, FRAME_sfire8, freddie_frames_sfire_start, freddie_do_sfire}; + +mframe_t freddie_frames_sfire [] = +{ + ai_charge, 0, freddie_stand_fire, + ai_charge, 0, freddie_stand_fire, + ai_charge, 0, freddie_stand_fire, + ai_charge, 0, freddie_stand_fire, + ai_charge, 0, freddie_stand_fire, + ai_charge, 0, freddie_stand_fire, + ai_charge, 0, freddie_stand_fire, + ai_charge, 0, freddie_stand_fire, + ai_charge, 0, freddie_stand_fire, + ai_charge, 0, freddie_stand_fire, + ai_charge, 0, freddie_stand_fire, + ai_charge, 0, freddie_stand_fire, + ai_charge, 0, freddie_stand_fire, + ai_charge, 0, freddie_stand_fire, + ai_charge, 0, freddie_stand_fire +}; +mmove_t freddie_move_sfire = {FRAME_sfire9, FRAME_sfire23, freddie_frames_sfire, freddie_attack_spindown}; + +mframe_t freddie_frames_sfire_stop [] = +{ + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL +}; +mmove_t freddie_move_sfire_stop = {FRAME_sfire24, FRAME_sfire27, freddie_frames_sfire_stop, freddie_run}; + +void freddie_do_sfire (edict_t *self) +{ + self->monsterinfo.currentmove = &freddie_move_sfire; +} + +void freddie_attack_spindown (edict_t *self) +{ + self->monsterinfo.currentmove = &freddie_move_sfire_stop; +} + +void freddie_attack (edict_t *self) +{ + self->monsterinfo.currentmove = &freddie_move_sfire_start; +} + +// +// melee +// + +void freddie_melee (edict_t *self); +void freddie_melee_repeat (edict_t *self); + +void freddie_saw_sound (edict_t *self) +{ + gi.sound (self, CHAN_VOICE, sound_saw, 1, ATTN_NORM, 0); +} + +void freddie_blade (edict_t *self, float side) +{ + float damage; + vec3_t aim; + + if (!self->enemy) + return; + if (self->enemy->health <= 0) + return; + + // 1-45 (3x15) damage + damage = (random() + random() + random()) * 15; + damage = max (1, damage); + + VectorSet (aim, FREDDIE_MELEE_DISTANCE, self->mins[0], 8); + if ( fire_hit (self, aim, damage, 100) ) + gi.sound (self, CHAN_VOICE, sound_melee, 1, ATTN_NORM, 0); +} + +void freddie_blade_right (edict_t *self) +{ + freddie_blade (self, -200); +} + +void freddie_blade_left (edict_t *self) +{ + freddie_blade (self, 200); +} + +mframe_t freddie_frames_fswing [] = +{ + ai_charge, 8, freddie_saw_sound, + ai_charge, 16, freddie_sound_footstep, + ai_charge, 10, NULL, + ai_charge, 4, freddie_sound_footstep, + ai_charge, 2, NULL, + ai_charge, 1, NULL, + ai_charge, 1, NULL, + ai_charge, 2, freddie_blade_right, + ai_charge, 2, NULL, + ai_charge, 2, NULL, + ai_charge, 0, NULL, +}; +mmove_t freddie_move_fswing = {FRAME_fswing1, FRAME_fswing11, freddie_frames_fswing, freddie_melee_repeat}; + +mframe_t freddie_frames_bswing [] = +{ + ai_charge, 20, freddie_saw_sound, + ai_charge, 12, NULL, + ai_charge, 4, NULL, + ai_charge, 2, freddie_sound_footstep, + ai_charge, 6, freddie_blade_left, + ai_charge, 4, NULL, + ai_charge, 4, NULL, + ai_charge, 8, NULL, + ai_charge, 8, freddie_sound_footstep, + ai_charge, 8, NULL, + ai_charge, 8, NULL, + ai_charge, 12, NULL, + ai_charge, 10, NULL, + ai_charge, 10, NULL, +}; +mmove_t freddie_move_bswing = {FRAME_bswing1, FRAME_bswing14, freddie_frames_bswing, freddie_run}; + +mframe_t freddie_frames_fswinge [] = +{ + 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, freddie_sound_footstep, +}; +mmove_t freddie_move_fswinge = {FRAME_fswinge1, FRAME_fswinge10, freddie_frames_fswinge, freddie_run}; + +void freddie_melee_repeat (edict_t *self) +{ + int r; + + if (!self->enemy) + return; + if (self->enemy->health <= 0) + return; + + // Check if within range to do a second (backward) swing attack + r = range(self, self->enemy); + if (r == RANGE_MELEE) + { + self->monsterinfo.currentmove = &freddie_move_bswing; + } + else + self->monsterinfo.currentmove = &freddie_move_fswinge; +} + +void freddie_melee (edict_t *self) +{ + int r; + + if (!self->enemy) + return; + if (self->enemy->health <= 0) + return; + + r = range(self, self->enemy); + if (r == RANGE_MELEE) + { + self->monsterinfo.currentmove = &freddie_move_fswing; + } + else if (visible(self, self->enemy) && infront(self,self->enemy) + && (r < RANGE_FAR) && !(self->monsterinfo.aiflags & AI_SOUND_TARGET)) + { + self->monsterinfo.currentmove = &freddie_move_sfire_start; + } + else + self->monsterinfo.currentmove = &freddie_move_run; +} + +// +// death +// + +void freddie_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 freddie_nogib (edict_t *self) +{ + self->gib_health = -10000; +} + +mframe_t freddie_frames_death [] = +{ + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, freddie_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, + 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, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL +}; +mmove_t freddie_move_death = {FRAME_death1, FRAME_death35, freddie_frames_death, freddie_dead}; + +void freddie_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) +{ + int n, type, bloodTypeBak; + +// check for gib + if ( (self->health <= self->gib_health) && !(self->spawnflags & SF_MONSTER_NOGIB) ) + { + gi.sound (self, CHAN_VOICE|CHAN_RELIABLE, sound_death2, 1, ATTN_NORM, 0); + + // T_RadiusDamage (self, self, 40, NULL, 40, MOD_EXPLOSIVE); // this would cause a crash because inflictor entity is freed + + gi.WriteByte (svc_temp_entity); + if (self->waterlevel) + type = TE_ROCKET_EXPLOSION_WATER; + else + type = TE_EXPLOSION1_BIG; + gi.WriteByte (type); + gi.WritePosition (self->s.origin); + gi.multicast (self->s.origin, MULTICAST_PVS); + + for (n = 0; n < 6; n++) + ThrowGib (self, "models/objects/q1gibs/q1gib1/tris.md2", damage, GIB_ORGANIC); + for (n = 0; n < 6; n++) + ThrowGib (self, "models/objects/q1gibs/q1gib3/tris.md2", damage, GIB_ORGANIC); + + // change blood type to mechanical to throw mech gibs + bloodTypeBak = self->blood_type; + self->blood_type = 2; + for (n = 0; n < 3; n++) + ThrowGibFrame (self, "models/monsters/q1freddie/gib_junk/tris.md2", (int)(random()*3), damage, GIB_METALLIC); + for (n = 0; n < 4; n++) + ThrowGib (self, "models/monsters/q1freddie/gib_metal1/tris.md2", damage, GIB_METALLIC); + for (n = 0; n < 4; n++) + ThrowGib (self, "models/monsters/q1freddie/gib_metal3/tris.md2", damage, GIB_METALLIC); + self->blood_type = bloodTypeBak; + + 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; + + self->monsterinfo.currentmove = &freddie_move_death; +} + + +/*QUAKED monster_q1_freddie (1 0 0) (-32 -32 -24) (32 32 64) Ambush Trigger_Spawn Sight +model="models/monsters/q1freddie/tris.md2" +*/ +void SP_monster_q1_freddie (edict_t *self) +{ + if (deathmatch->value) + { + G_FreeEdict (self); + return; + } + + sound_pain1 = gi.soundindex ("q1freddie/pain.wav"); + sound_pain2 = gi.soundindex ("q1freddie/painshrt.wav"); + sound_death = gi.soundindex ("q1freddie/death.wav"); + sound_death2 = gi.soundindex ("q1freddie/explode_major.wav"); + sound_idle = gi.soundindex ("q1freddie/idle1.wav"); + sound_sight = gi.soundindex ("q1freddie/sight.wav"); + sound_saw = gi.soundindex ("q1freddie/sawstart.wav"); + sound_melee = gi.soundindex ("q1freddie/mangle.wav"); + sound_atk_spinup = gi.soundindex ("q1freddie/stfire.wav"); + sound_atk_nail = gi.soundindex ("q1weapons/rocket1i.wav"); + sound_atk_laser = gi.soundindex ("q1enforcer/enfire.wav"); + sound_step1 = gi.soundindex ("q1freddie/step.wav"); + sound_step2 = gi.soundindex ("q1freddie/step2.wav"); + sound_step3 = gi.soundindex ("q1freddie/step3.wav"); + + // precache gibs + gi.modelindex ("models/monsters/q1ogre/head/tris.md2"); + gi.modelindex ("models/objects/q1gibs/q1gib1/tris.md2"); + gi.modelindex ("models/objects/q1gibs/q1gib3/tris.md2"); + gi.modelindex ("models/monsters/q1freddie/gib_junk/tris.md2"); + gi.modelindex ("models/monsters/q1freddie/gib_metal1/tris.md2"); + gi.modelindex ("models/monsters/q1freddie/gib_metal3/tris.md2"); + // precache nail/laser + if (self->spawnflags & SF_FREDDIE_LASER) + q1_laser_precache (); + else + q1_nail_precache (); + + self->movetype = MOVETYPE_STEP; + self->solid = SOLID_BBOX; + + // Lazarus: special purpose skins + if ( self->style ) + { + PatchMonsterModel("models/monsters/q1freddie/tris.md2"); + self->s.skinnum = self->style * 2; + } + + self->s.modelindex = gi.modelindex ("models/monsters/q1freddie/tris.md2"); + VectorSet (self->mins, -24, -24, -24); + VectorSet (self->maxs, 24, 24, 64); + + if (!self->health) + self->health = 500; + if (!self->gib_health) + self->gib_health = -80; + if (!self->mass) + self->mass = 500; + + self->pain = freddie_pain; + self->die = freddie_die; + + self->flags |= FL_Q1_MONSTER; + + self->monsterinfo.stand = freddie_stand; + self->monsterinfo.walk = freddie_walk; + self->monsterinfo.run = freddie_run; + self->monsterinfo.walk = freddie_walk; + self->monsterinfo.dodge = NULL; + self->monsterinfo.attack = freddie_attack; + self->monsterinfo.melee = freddie_melee; + self->monsterinfo.sight = freddie_sight; + self->monsterinfo.search = freddie_stand; + + VectorSet (self->muzzle, 0.0f, 0.0f, 0.0f); // attack_offset from original Quake C + self->fog_model = 0; // attack_timer from original Quake C + + if (!self->monsterinfo.flies) + self->monsterinfo.flies = 0.25; + + // 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 = "Freddie"; + self->class_id = ENTITY_MONSTER_Q1_FREDDIE; + + gi.linkentity (self); + + self->monsterinfo.currentmove = &freddie_move_stand; + self->monsterinfo.scale = MODEL_SCALE; + + walkmonster_start (self); +} diff --git a/missionpack/m_q1freddie.h b/missionpack/m_q1freddie.h new file mode 100644 index 0000000..53b4ba4 --- /dev/null +++ b/missionpack/m_q1freddie.h @@ -0,0 +1,161 @@ +// FREDDIE + +#define FRAME_run1 0 +#define FRAME_run2 1 +#define FRAME_run3 2 +#define FRAME_run4 3 +#define FRAME_run5 4 +#define FRAME_run6 5 +#define FRAME_run7 6 +#define FRAME_run8 7 +#define FRAME_run9 8 +#define FRAME_run10 9 +#define FRAME_run11 10 +#define FRAME_run12 11 +#define FRAME_run13 12 +#define FRAME_run14 13 +#define FRAME_run15 14 +#define FRAME_run16 15 +#define FRAME_rfire1 16 +#define FRAME_rfire2 17 +#define FRAME_rfire3 18 +#define FRAME_rfire4 19 +#define FRAME_rfire5 20 +#define FRAME_rfire6 21 +#define FRAME_rfire7 22 +#define FRAME_rfire8 23 +#define FRAME_rfire9 24 +#define FRAME_rfire10 25 +#define FRAME_rfire11 26 +#define FRAME_rfire12 27 +#define FRAME_rfire13 28 +#define FRAME_rfire14 29 +#define FRAME_rfire15 30 +#define FRAME_rfire16 31 +#define FRAME_sfire1 32 +#define FRAME_sfire2 33 +#define FRAME_sfire3 34 +#define FRAME_sfire4 35 +#define FRAME_sfire5 36 +#define FRAME_sfire6 37 +#define FRAME_sfire7 38 +#define FRAME_sfire8 39 +#define FRAME_sfire9 40 +#define FRAME_sfire10 41 +#define FRAME_sfire11 42 +#define FRAME_sfire12 43 +#define FRAME_sfire13 44 +#define FRAME_sfire14 45 +#define FRAME_sfire15 46 +#define FRAME_sfire16 47 +#define FRAME_sfire17 48 +#define FRAME_sfire18 49 +#define FRAME_sfire19 50 +#define FRAME_sfire20 51 +#define FRAME_sfire21 52 +#define FRAME_sfire22 53 +#define FRAME_sfire23 54 +#define FRAME_sfire24 55 +#define FRAME_sfire25 56 +#define FRAME_sfire26 57 +#define FRAME_sfire27 58 +#define FRAME_sfire28 59 +#define FRAME_pain1 60 +#define FRAME_pain2 61 +#define FRAME_pain3 62 +#define FRAME_pain4 63 +#define FRAME_pain5 64 +#define FRAME_pain6 65 +#define FRAME_pain7 66 +#define FRAME_pain8 67 +#define FRAME_pain9 68 +#define FRAME_pain10 69 +#define FRAME_pain11 70 +#define FRAME_pain12 71 +#define FRAME_painb1 72 +#define FRAME_painb2 73 +#define FRAME_painb3 74 +#define FRAME_painb4 75 +#define FRAME_painb5 76 +#define FRAME_fswing1 77 +#define FRAME_fswing2 78 +#define FRAME_fswing3 79 +#define FRAME_fswing4 80 +#define FRAME_fswing5 81 +#define FRAME_fswing6 82 +#define FRAME_fswing7 83 +#define FRAME_fswing8 84 +#define FRAME_fswing9 85 +#define FRAME_fswing10 86 +#define FRAME_fswing11 87 +#define FRAME_fswinge1 88 +#define FRAME_fswinge2 89 +#define FRAME_fswinge3 90 +#define FRAME_fswinge4 91 +#define FRAME_fswinge5 92 +#define FRAME_fswinge6 93 +#define FRAME_fswinge7 94 +#define FRAME_fswinge8 95 +#define FRAME_fswinge9 96 +#define FRAME_fswinge10 97 +#define FRAME_bswing1 98 +#define FRAME_bswing2 99 +#define FRAME_bswing3 100 +#define FRAME_bswing4 101 +#define FRAME_bswing5 102 +#define FRAME_bswing6 103 +#define FRAME_bswing7 104 +#define FRAME_bswing8 105 +#define FRAME_bswing9 106 +#define FRAME_bswing10 107 +#define FRAME_bswing11 108 +#define FRAME_bswing12 109 +#define FRAME_bswing13 110 +#define FRAME_bswing14 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_death15 126 +#define FRAME_death16 127 +#define FRAME_death17 128 +#define FRAME_death18 129 +#define FRAME_death19 130 +#define FRAME_death20 131 +#define FRAME_death21 132 +#define FRAME_death22 133 +#define FRAME_death23 134 +#define FRAME_death24 135 +#define FRAME_death25 136 +#define FRAME_death26 137 +#define FRAME_death27 138 +#define FRAME_death28 139 +#define FRAME_death29 140 +#define FRAME_death30 141 +#define FRAME_death31 142 +#define FRAME_death32 143 +#define FRAME_death33 144 +#define FRAME_death34 145 +#define FRAME_death35 146 +#define FRAME_base1 147 +#define FRAME_base2 148 +#define FRAME_stand1 149 +#define FRAME_stand2 150 +#define FRAME_stand3 151 +#define FRAME_stand4 152 +#define FRAME_stand5 153 +#define FRAME_stand6 153 +#define FRAME_stand7 155 +#define FRAME_stand8 156 + +#define MODEL_SCALE 1.000000 \ No newline at end of file diff --git a/missionpack/m_q1grunt.c b/missionpack/m_q1grunt.c index e4a0db4..0ef82f5 100644 --- a/missionpack/m_q1grunt.c +++ b/missionpack/m_q1grunt.c @@ -14,6 +14,7 @@ static int sound_sight; static int sound_pain1; static int sound_pain2; static int sound_death; +static int sound_gib; static int sound_attack; @@ -361,7 +362,7 @@ void q1grunt_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int dama // check for gib if (self->health <= self->gib_health && !(self->spawnflags & SF_MONSTER_NOGIB)) { - gi.sound (self, CHAN_VOICE|CHAN_RELIABLE, gi.soundindex ("q1player/udeath.wav"), 1, ATTN_NORM, 0); + gi.sound (self, CHAN_VOICE|CHAN_RELIABLE, sound_gib, 1, ATTN_NORM, 0); // if dead body, don't drop pack when gibbed // if (self->deadflag != DEAD_DEAD) @@ -411,11 +412,16 @@ void SP_monster_q1_grunt (edict_t *self) sound_pain1 = gi.soundindex ("q1grunt/pain1.wav"); sound_pain2 = gi.soundindex ("q1grunt/pain2.wav"); sound_death = gi.soundindex ("q1grunt/death1.wav"); + sound_gib = gi.soundindex ("q1player/udeath.wav"); sound_attack = gi.soundindex ("q1grunt/sattck1.wav"); // precache backpack gi.modelindex ("models/items/q1backpack/tris.md2"); // gi.soundindex ("q1weapons/lock4.wav"); + // precache gibs + gi.modelindex ("models/monsters/q1grunt/head/tris.md2"); + gi.modelindex ("models/objects/q1gibs/q1gib1/tris.md2"); + gi.modelindex ("models/objects/q1gibs/q1gib2/tris.md2"); self->movetype = MOVETYPE_STEP; self->solid = SOLID_BBOX; diff --git a/missionpack/m_q1hknight.c b/missionpack/m_q1hknight.c index bc0f4fe..4f2dbaa 100644 --- a/missionpack/m_q1hknight.c +++ b/missionpack/m_q1hknight.c @@ -12,7 +12,9 @@ QUAKE HELL KNIGHT static int sound_sword1; static int sound_sword2; +static int sound_flame; static int sound_death; +static int sound_gib; static int sound_idle; static int sound_pain; static int sound_sight; @@ -363,7 +365,7 @@ void hknight_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int dama if (self->health <= self->gib_health && !(self->spawnflags & SF_MONSTER_NOGIB)) { - gi.sound (self, CHAN_VOICE|CHAN_RELIABLE, gi.soundindex ("q1player/udeath.wav"), 1, ATTN_NORM, 0); + gi.sound (self, CHAN_VOICE|CHAN_RELIABLE, sound_gib, 1, ATTN_NORM, 0); for (n= 0; n < 2; n++) ThrowGib (self, "models/objects/q1gibs/q1gib3/tris.md2", damage, GIB_ORGANIC); @@ -450,7 +452,7 @@ void hknight_fire_flame (edict_t *self) //vec = VectorNormalizeFastf( - gi.sound (self, CHAN_WEAPON, gi.soundindex ("q1hknight/attack1.wav"), 1, ATTN_NORM, 0); + gi.sound (self, CHAN_WEAPON, sound_flame, 1, ATTN_NORM, 0); q1_fire_flame (self, start, v_forward, 0); } @@ -492,12 +494,21 @@ void SP_monster_q1_hknight (edict_t *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"); + sound_death = gi.soundindex ("q1hknight/death1.wav"); + sound_gib = gi.soundindex ("q1player/udeath.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"); + sound_flame = gi.soundindex ("q1hknight/attack1.wav"); + + // precache gibs + gi.modelindex ("models/monsters/q1hknight/head/tris.md2"); + gi.modelindex ("models/objects/q1gibs/q1gib1/tris.md2"); + gi.modelindex ("models/objects/q1gibs/q1gib3/tris.md2"); + // precache flame + q1_flame_precache (); self->movetype = MOVETYPE_STEP; self->solid = SOLID_BBOX; diff --git a/missionpack/m_q1knight.c b/missionpack/m_q1knight.c index 148f4e9..1961422 100644 --- a/missionpack/m_q1knight.c +++ b/missionpack/m_q1knight.c @@ -13,6 +13,7 @@ QUAKE KNIGHT static int sound_sword1; static int sound_sword2; static int sound_death; +static int sound_gib; static int sound_pain; static int sound_idle; static int sound_sight; @@ -368,7 +369,7 @@ void knight_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damag if (self->health <= self->gib_health && !(self->spawnflags & SF_MONSTER_NOGIB)) { - gi.sound (self, CHAN_VOICE|CHAN_RELIABLE, gi.soundindex ("q1player/udeath.wav"), 1, ATTN_NORM, 0); + gi.sound (self, CHAN_VOICE|CHAN_RELIABLE, sound_gib, 1, ATTN_NORM, 0); for (n= 0; n < 2; n++) ThrowGib (self, "models/objects/q1gibs/q1gib3/tris.md2", damage, GIB_ORGANIC); @@ -408,12 +409,18 @@ void SP_monster_q1_knight (edict_t *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"); + sound_sword1 = gi.soundindex ("q1knight/sword1.wav"); + sound_sword2 = gi.soundindex ("q1knight/sword2.wav"); + sound_death = gi.soundindex ("q1knight/kdeath.wav"); + sound_gib = gi.soundindex ("q1player/udeath.wav"); + sound_pain = gi.soundindex ("q1knight/khurt.wav"); + sound_idle = gi.soundindex ("q1knight/idle.wav"); + sound_sight = gi.soundindex ("q1knight/ksight.wav"); + + // precache gibs + gi.modelindex ("models/monsters/q1knight/head/tris.md2"); + gi.modelindex ("models/objects/q1gibs/q1gib1/tris.md2"); + gi.modelindex ("models/objects/q1gibs/q1gib3/tris.md2"); self->movetype = MOVETYPE_STEP; self->solid = SOLID_BBOX; diff --git a/missionpack/m_q1ogre.c b/missionpack/m_q1ogre.c index c8d91d1..7c8f401 100644 --- a/missionpack/m_q1ogre.c +++ b/missionpack/m_q1ogre.c @@ -11,15 +11,17 @@ QUAKE OGRE static int sound_pain; static int sound_death; +static int sound_gib; static int sound_idle; static int sound_idle2; static int sound_wake; +static int sound_shoot; static int sound_saw; static int sound_drag; void ogre_check_refire (edict_t *self); -void ogre_attack(edict_t *self); +void ogre_attack (edict_t *self); void ogre_idle_sound1 (edict_t *self) { @@ -36,12 +38,12 @@ void ogre_idle_sound2 (edict_t *self) void ogre_sight (edict_t *self, edict_t *other) { gi.sound (self, CHAN_VOICE, sound_wake, 1, ATTN_NORM, 0); - ogre_attack(self); + ogre_attack (self); } void ogre_drag_sound (edict_t *self) { - //if(anglemod(self->s.angles[YAW]) != self->ideal_yaw) + //if (anglemod(self->s.angles[YAW]) != self->ideal_yaw) if (random() < 0.2) gi.sound (self, CHAN_VOICE, sound_drag, 1, ATTN_IDLE, 0); } @@ -100,15 +102,14 @@ void ogre_walk (edict_t *self) mframe_t ogre_frames_run [] = { ai_run, 9, NULL, - ai_run, 12,NULL, + ai_run, 12, NULL, ai_run, 8, NULL, - ai_run, 22,NULL, - ai_run, 16,NULL, + ai_run, 22, NULL, + ai_run, 16, NULL, ai_run, 4, NULL, - ai_run, 13,ogre_attack, - ai_run, 24,NULL + ai_run, 13, ogre_attack, + ai_run, 24, NULL }; - mmove_t ogre_move_run = {FRAME_run1, FRAME_run8, ogre_frames_run, NULL}; @@ -199,11 +200,10 @@ 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(); + r = random(); if (self->health > 0) gi.sound (self, CHAN_VOICE, sound_pain, 1, ATTN_NORM, 0); @@ -313,17 +313,17 @@ void ogre_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, int n; // check for gib - if (self->health <= self->gib_health && !(self->spawnflags & SF_MONSTER_NOGIB)) + if ( (self->health <= self->gib_health) && !(self->spawnflags & SF_MONSTER_NOGIB) ) { - gi.sound (self, CHAN_VOICE|CHAN_RELIABLE, gi.soundindex ("q1player/udeath.wav"), 1, ATTN_NORM, 0); + gi.sound (self, CHAN_VOICE|CHAN_RELIABLE, sound_gib, 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++) + for (n = 0; n < 2; n++) ThrowGib (self, "models/objects/q1gibs/q1gib1/tris.md2", damage, GIB_ORGANIC); - for (n= 0; n < 4; n++) + 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; @@ -338,14 +338,14 @@ void ogre_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, self->deadflag = DEAD_DEAD; self->takedamage = DAMAGE_YES; - if(random() < 0.5) + if (random() < 0.5) self->monsterinfo.currentmove = &ogre_move_death1; else self->monsterinfo.currentmove = &ogre_move_death2; } -void ogre_grenade_fire(edict_t *self) +void ogre_grenade_fire (edict_t *self) { vec3_t start; @@ -359,10 +359,10 @@ void ogre_grenade_fire(edict_t *self) // project enemy back a bit and target there VectorCopy (self->enemy->s.origin, target); - //if(range(self,self->enemy) > RANGE_MID) + //if (range(self,self->enemy) > RANGE_MID) VectorMA (target, -0.1, self->enemy->velocity, target); - if(range(self,self->enemy) > RANGE_MID) + if (range(self,self->enemy) > RANGE_MID) target[2] += self->enemy->viewheight; else target[2] += self->enemy->viewheight*0.8; @@ -375,7 +375,7 @@ void ogre_grenade_fire(edict_t *self) gi.WriteByte (MZ_MACHINEGUN | 128); gi.multicast (self->s.origin, MULTICAST_PVS); - gi.sound (self, CHAN_WEAPON|CHAN_RELIABLE, gi.soundindex("q1weapons/grenade.wav"), 1.0, ATTN_NORM, 0); + gi.sound (self, CHAN_WEAPON|CHAN_RELIABLE, sound_shoot, 1.0, ATTN_NORM, 0); q1_fire_grenade (self, start,aim,40 , 600, 2.5, 80); } @@ -414,9 +414,9 @@ 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 ( (skill->value == 3) || (range(self, self->enemy) == RANGE_MELEE)) { - if(random() > 0.5) + if (random() > 0.5) self->monsterinfo.nextframe = FRAME_swing1; else self->monsterinfo.nextframe = FRAME_smash1; @@ -426,7 +426,7 @@ void ogre_check_refire (edict_t *self) } -/*static*/ void ogre_sawswingsound(edict_t *self) +/*static*/ void ogre_sawswingsound (edict_t *self) { gi.sound (self, CHAN_WEAPON, sound_saw, 1, ATTN_NORM, 0); } @@ -478,25 +478,25 @@ mframe_t ogre_frames_attack_grenade [] = ai_charge, 0, NULL, ai_charge, 0, ogre_grenade_fire, ai_charge, 0, NULL, - ai_charge, 0, NULL //ogre_attack + 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) +void ogre_attack (edict_t *self) { int r; - if(!self->enemy) + if (!self->enemy) return; - r = range(self,self->enemy); + 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) + 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; @@ -510,7 +510,7 @@ void ogre_attack(edict_t *self) // SPAWN // -/*QUAKED monster_q1_ogre (1 .5 0) (-20 -20 -24) (20 20 32) Ambush Trigger_Spawn Sight +/*QUAKED monster_q1_ogre (1 .5 0) (-20 -20 -24) (20 20 32) Ambush Trigger_Spawn Sight GoodGuy NoGib model="models/monsters/q1ogre/tris.md2" */ void SP_monster_q1_ogre (edict_t *self) @@ -523,15 +523,23 @@ void SP_monster_q1_ogre (edict_t *self) sound_pain = gi.soundindex ("q1ogre/ogpain1.wav"); sound_death = gi.soundindex ("q1ogre/ogdth.wav"); + sound_gib = gi.soundindex ("q1player/udeath.wav"); sound_idle = gi.soundindex ("q1ogre/ogidle.wav"); sound_idle2 = gi.soundindex ("q1ogre/ogidle2.wav"); sound_wake = gi.soundindex ("q1ogre/ogwake.wav"); + sound_shoot = gi.soundindex ("q1weapons/grenade.wav"); sound_saw = gi.soundindex ("q1ogre/ogsawatk.wav"); sound_drag = gi.soundindex ("q1ogre/ogdrag.wav"); // precache backpack gi.modelindex ("models/items/q1backpack/tris.md2"); // gi.soundindex ("q1weapons/lock4.wav"); + // precache gibs + gi.modelindex ("models/monsters/q1ogre/head/tris.md2"); + gi.modelindex ("models/objects/q1gibs/q1gib1/tris.md2"); + gi.modelindex ("models/objects/q1gibs/q1gib3/tris.md2"); + // precache grenade + q1_grenade_precache (); self->movetype = MOVETYPE_STEP; self->solid = SOLID_BBOX; diff --git a/missionpack/m_q1scrag.c b/missionpack/m_q1scrag.c index 01cd06e..9b02f31 100644 --- a/missionpack/m_q1scrag.c +++ b/missionpack/m_q1scrag.c @@ -18,6 +18,7 @@ static int sound_idle1; static int sound_idle2; static int sound_attack; static int sound_die; +static int sound_gib; static int sound_pain; static int sound_hit; @@ -197,9 +198,9 @@ void scrag_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage if (self->health <= self->gib_health && !(self->spawnflags & SF_MONSTER_NOGIB)) { - gi.sound (self, CHAN_VOICE|CHAN_RELIABLE, gi.soundindex ("q1player/udeath.wav"), 1, ATTN_NORM, 0); + gi.sound (self, CHAN_VOICE|CHAN_RELIABLE, sound_gib, 1, ATTN_NORM, 0); - for (n= 0; n < 3; n++) + 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; @@ -337,14 +338,21 @@ void SP_monster_q1_scrag (edict_t *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"); - + 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_gib = gi.soundindex ("q1player/udeath.wav"); + sound_pain = gi.soundindex ("q1scrag/wpain.wav"); + sound_hit = gi.soundindex ("q1scrag/hit.wav"); + + // precache gibs + gi.modelindex ("models/monsters/q1scrag/head/tris.md2"); + gi.modelindex ("models/objects/q1gibs/q1gib2/tris.md2"); + // precache acidspit + q1_acidspit_precache (); + self->movetype = MOVETYPE_STEP; self->solid = SOLID_BBOX; diff --git a/missionpack/m_q1shalrath.c b/missionpack/m_q1shalrath.c index 504f747..f613588 100644 --- a/missionpack/m_q1shalrath.c +++ b/missionpack/m_q1shalrath.c @@ -10,9 +10,11 @@ QUAKE SHALRATH #include "m_q1shalrath.h" static int sound_death; +static int sound_gib; static int sound_sight; static int sound_pain1; static int sound_attack; +static int sound_attack2; static int sound_idle; @@ -161,7 +163,7 @@ void q1shalrath_fire (edict_t *self) VectorSubtract (end, start, aim); VectorNormalize (aim); - gi.sound (self, CHAN_WEAPON|CHAN_RELIABLE, gi.soundindex("shalrath/attack2.wav"), 1, ATTN_NORM, 0); + gi.sound (self, CHAN_WEAPON|CHAN_RELIABLE, sound_attack2, 1, ATTN_NORM, 0); q1_fire_firepod (self, aim); } @@ -238,14 +240,17 @@ mmove_t q1shalrath_move_death = {FRAME_death1, FRAME_death7, q1shalrath_frames_d 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 ("q1player/udeath.wav"), 1, ATTN_NORM, 0); + gi.sound (self, CHAN_VOICE|CHAN_RELIABLE, sound_gib, 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); + for (n = 0; n < 2; n++) + ThrowGib (self, "models/objects/q1gibs/q1gib3/tris.md2", damage, GIB_ORGANIC); ThrowHead (self, "models/monsters/q1shalrath/head/tris.md2", damage, GIB_ORGANIC); self->deadflag = DEAD_DEAD; return; @@ -280,10 +285,20 @@ void SP_monster_q1_shalrath (edict_t *self) sound_sight = gi.soundindex ("q1shalrath/sight.wav"); sound_pain1 = gi.soundindex ("q1shalrath/pain.wav"); + sound_gib = gi.soundindex ("q1player/udeath.wav"); sound_death = gi.soundindex ("q1shalrath/death.wav"); sound_attack = gi.soundindex ("q1shalrath/attack.wav"); + sound_attack2 = gi.soundindex ("shalrath/attack2.wav"); sound_idle = gi.soundindex ("q1shalrath/idle.wav"); + // precache gibs + gi.modelindex ("models/monsters/q1shalrath/head/tris.md2"); + gi.modelindex ("models/objects/q1gibs/q1gib1/tris.md2"); + gi.modelindex ("models/objects/q1gibs/q1gib2/tris.md2"); + gi.modelindex ("models/objects/q1gibs/q1gib3/tris.md2"); + // precache firepod + q1_firepod_precache (); + self->movetype = MOVETYPE_STEP; self->solid = SOLID_BBOX; diff --git a/missionpack/m_q1shambler.c b/missionpack/m_q1shambler.c index 54c3e73..8a6c104 100644 --- a/missionpack/m_q1shambler.c +++ b/missionpack/m_q1shambler.c @@ -17,6 +17,7 @@ static int sound_attack; static int sound_boom; // ? static int sound_pain; static int sound_death; +static int sound_gib; static int sound_idle; static int sound_sight; @@ -202,13 +203,16 @@ mmove_t shambler_move_death = {FRAME_death1, FRAME_death11, shambler_frames_deat void shambler_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 ("q1player/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); + gi.sound (self, CHAN_VOICE|CHAN_RELIABLE, sound_gib, 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 < 4; n++) + 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; @@ -517,15 +521,22 @@ void SP_monster_q1_shambler (edict_t *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"); + 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_gib = gi.soundindex ("q1player/udeath.wav"); + sound_idle = gi.soundindex ("q1shambler/sidle.wav"); + sound_sight = gi.soundindex ("q1shambler/ssight.wav"); + + // precache gibs + gi.modelindex ("models/monsters/q1shambler/head/tris.md2"); + gi.modelindex ("models/objects/q1gibs/q1gib1/tris.md2"); + gi.modelindex ("models/objects/q1gibs/q1gib2/tris.md2"); + gi.modelindex ("models/objects/q1gibs/q1gib3/tris.md2"); self->movetype = MOVETYPE_STEP; self->solid = SOLID_BBOX; diff --git a/missionpack/m_q1zombie.c b/missionpack/m_q1zombie.c index 2ec9db4..c447b09 100644 --- a/missionpack/m_q1zombie.c +++ b/missionpack/m_q1zombie.c @@ -607,11 +607,14 @@ void q1zombie_sight(edict_t *self, edict_t *other) 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); + int n; + + gi.sound (self, CHAN_VOICE, sound_gib, 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); - ThrowGib (self, "models/objects/q1gibs/q1gib3/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/q1zombie/head/tris.md2", damage*2, GIB_ORGANIC); self->deadflag = DEAD_DEAD; self->takedamage = DAMAGE_NO; @@ -653,6 +656,14 @@ void SP_monster_q1_zombie (edict_t *self) sound_gib = gi.soundindex ("q1zombie/z_gib.wav"); sound_shot = gi.soundindex ("q1zombie/z_shot1.wav"); + // precache gibs + gi.modelindex ("models/monsters/q1zombie/head/tris.md2"); + gi.modelindex ("models/objects/q1gibs/q1gib1/tris.md2"); + gi.modelindex ("models/objects/q1gibs/q1gib2/tris.md2"); + gi.modelindex ("models/objects/q1gibs/q1gib3/tris.md2"); + // precache projectile gib + q1_gib_precache (); + self->movetype = MOVETYPE_STEP; self->solid = SOLID_BBOX; diff --git a/missionpack/m_supertank.c b/missionpack/m_supertank.c index 0f03938..4067cc0 100644 --- a/missionpack/m_supertank.c +++ b/missionpack/m_supertank.c @@ -654,7 +654,7 @@ void BossExplode (edict_t *self) case 9: self->s.sound = 0; - //Knightmare- big explosion + // Knightmare- big explosion gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_EXPLOSION1_BIG); gi.WritePosition (org); diff --git a/missionpack/m_tank.c b/missionpack/m_tank.c index b75c87f..897701a 100644 --- a/missionpack/m_tank.c +++ b/missionpack/m_tank.c @@ -145,7 +145,7 @@ mmove_t tank_move_stop_walk = {FRAME_walk21, FRAME_walk25, tank_frames_stop_walk void tank_walk (edict_t *self) { - self->monsterinfo.currentmove = &tank_move_walk; + self->monsterinfo.currentmove = &tank_move_walk; } diff --git a/missionpack/m_vulture.c b/missionpack/m_vulture.c new file mode 100644 index 0000000..c11b0e8 --- /dev/null +++ b/missionpack/m_vulture.c @@ -0,0 +1,702 @@ +/* +============================================================================== + +flyer + +============================================================================== +*/ + +#include "g_local.h" +#include "m_vulture.h" + +#define SF_VULTURE_IN_AIR 8 + +qboolean visible (edict_t *self, edict_t *other); + +static int nextmove; // Used for start/stop frames + +//static int sound_sight; +static int sound_perch_idle1; +static int sound_perch_idle2; +static int sound_perch_idle3; +static int sound_soar_idle1; +static int sound_soar_idle2; +static int sound_soar_idle3; +static int sound_flap1; +static int sound_flap2; +static int sound_flap3; +static int sound_peck1; +static int sound_peck2; +static int sound_peck3; +static int sound_pain1; +static int sound_pain2; +static int sound_death; + +void vulture_run (edict_t *self); + +void vulture_sight (edict_t *self, edict_t *other) +{ +// gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0); +} + +void vulture_perch_idle (edict_t *self) +{ + float r; + + if (random() < 0.3f) + { + r = random(); + if (r < 0.33f) + gi.sound (self, CHAN_VOICE, sound_perch_idle1, 1, ATTN_IDLE, 0); + else if (r < 0.67f) + gi.sound (self, CHAN_VOICE, sound_perch_idle2, 1, ATTN_IDLE, 0); + else + gi.sound (self, CHAN_VOICE, sound_perch_idle3, 1, ATTN_IDLE, 0); + } +} + +void vulture_soar_idle (edict_t *self) +{ + float r; + + if (random() < 0.3f) + { + r = random(); + if (r < 0.33f) + gi.sound (self, CHAN_VOICE, sound_soar_idle1, 1, ATTN_IDLE, 0); + else if (r < 0.67f) + gi.sound (self, CHAN_VOICE, sound_soar_idle2, 1, ATTN_IDLE, 0); + else + gi.sound (self, CHAN_VOICE, sound_soar_idle3, 1, ATTN_IDLE, 0); + } +} + +void vulture_idle (edict_t *self) +{ + if (self->flags & FL_FLY) + vulture_soar_idle (self); + else + vulture_perch_idle (self); +} + + +void vulture_flap (edict_t *self) +{ + float r; + + if (random() < 0.67f) + { + r = random(); + if (r < 0.33f) + gi.sound (self, CHAN_VOICE, sound_flap1, 1, ATTN_IDLE, 0); + else if (r < 0.67f) + gi.sound (self, CHAN_VOICE, sound_flap2, 1, ATTN_IDLE, 0); + else + gi.sound (self, CHAN_VOICE, sound_flap3, 1, ATTN_IDLE, 0); + } +} + +// +// perch +// + +mframe_t vulture_frames_perch [] = +{ + 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, + 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 vulture_move_perch = {FRAME_perch1, FRAME_perch30, vulture_frames_perch, NULL}; + +void vulture_perch (edict_t *self) +{ + self->monsterinfo.currentmove = &vulture_move_perch; +} + +// +// walk +// + +mframe_t vulture_frames_walk [] = +{ + ai_walk, 1, NULL, + ai_walk, 1, NULL, + ai_walk, 1, NULL, + ai_walk, 1, NULL, + ai_walk, 1, NULL, + ai_walk, 1, NULL, + ai_walk, 1, NULL, + ai_walk, 1, NULL, + ai_walk, 1, NULL, + ai_walk, 1, NULL +}; +mmove_t vulture_move_walk = {FRAME_walk1, FRAME_walk10, vulture_frames_walk, NULL}; + +// +// soar +// + +mframe_t vulture_frames_soar [] = +{ + ai_walk, 5, NULL, + ai_walk, 5, NULL, + ai_walk, 5, NULL, + ai_walk, 5, NULL, + ai_walk, 5, NULL, + ai_walk, 5, NULL, + ai_walk, 5, NULL, + ai_walk, 5, NULL, + ai_walk, 5, NULL, + ai_walk, 5, NULL, + + ai_walk, 5, NULL, + ai_walk, 5, NULL, + ai_walk, 5, NULL, + ai_walk, 5, NULL, + ai_walk, 5, NULL, + ai_walk, 5, NULL, + ai_walk, 5, NULL, + ai_walk, 5, NULL, + ai_walk, 5, NULL, + ai_walk, 5, NULL, + + ai_walk, 5, NULL, + ai_walk, 5, NULL, + ai_walk, 5, NULL, + ai_walk, 5, NULL, + ai_walk, 5, NULL, + ai_walk, 5, NULL, + ai_walk, 5, NULL, + ai_walk, 5, NULL, + ai_walk, 5, NULL, + ai_walk, 5, NULL, + + ai_walk, 5, NULL, + ai_walk, 5, NULL, + ai_walk, 5, NULL, + ai_walk, 5, NULL, + ai_walk, 5, NULL, + ai_walk, 5, NULL, + ai_walk, 5, NULL, + ai_walk, 5, NULL, + ai_walk, 5, NULL, + ai_walk, 5, NULL, + ai_walk, 5, NULL, + ai_walk, 5, NULL +}; +mmove_t vulture_move_soar = {FRAME_soar1, FRAME_soar42, vulture_frames_soar, NULL}; +/* +void vulture_soar (edict_t *self) +{ + self->monsterinfo.currentmove = &vulture_move_soar; +} +*/ + +#if 0 +// +// bank right +// + +mframe_t vulture_frames_bankright [] = +{ + ai_move, 10, NULL, + ai_move, 10, NULL, + ai_move, 10, NULL, + ai_move, 10, NULL, + ai_move, 10, NULL, + ai_move, 10, NULL, + ai_move, 10, NULL, + ai_move, 10, NULL, + ai_move, 10, NULL, + ai_move, 10, NULL +}; +//mmove_t vulture_move_bankright = {FRAME_bankR1, FRAME_bankR10, vulture_frames_bankright, NULL}; + +void vulture_bankright (edict_t *self) +{ + self->monsterinfo.currentmove = &vulture_move_bankright; +} + +// +// bank left +// + +mframe_t vulture_frames_bankleft [] = +{ + ai_move, 10, NULL, + ai_move, 10, NULL, + ai_move, 10, NULL, + ai_move, 10, NULL, + ai_move, 10, NULL, + ai_move, 10, NULL, + ai_move, 10, NULL, + ai_move, 10, NULL, + ai_move, 10, NULL, + ai_move, 10, NULL +}; +//mmove_t vulture_move_bankleft = {FRAME_bankL1, FRAME_bankL10, vulture_frames_bankleft, NULL}; + +void vulture_bankleft (edict_t *self) +{ + self->monsterinfo.currentmove = &vulture_move_bankleft; +} +#endif + +void vulture_walk (edict_t *self) +{ + if (self->flags & FL_FLY) { + self->monsterinfo.currentmove = &vulture_move_soar; + } + else { + self->monsterinfo.currentmove = &vulture_move_walk; + } +} + +// +// fly +// + +mframe_t vulture_frames_fly [] = +{ + ai_run, 15, NULL, + ai_run, 15, vulture_flap, + ai_run, 15, NULL, + ai_run, 15, NULL, + ai_run, 15, NULL +}; +mmove_t vulture_move_fly = {FRAME_fly1, FRAME_fly5, vulture_frames_fly, NULL}; +/* +void vulture_fly (edict_t *self) +{ + self->monsterinfo.currentmove = &vulture_move_fly; +} +*/ + +// +// takeoff +// + +void vulture_airborne (edict_t *self) +{ + self->flags |= FL_FLY; + +// if (self->flags & FL_FLY) +// gi.dprintf ("successfully converted monster_vulture to flying\n"); +} + +mframe_t vulture_frames_takeoff [] = +{ + ai_move, 5, NULL, + ai_move, 5, NULL, + ai_move, 5, NULL, + ai_move, 5, NULL, + ai_move, 5, NULL, + ai_move, 5, vulture_airborne +}; +mmove_t vulture_move_takeoff = {FRAME_takeoff1, FRAME_takeoff6, vulture_frames_takeoff, vulture_run}; +/* +void vulture_takeoff (edict_t *self) +{ + self->monsterinfo.currentmove = &vulture_move_takeoff; +} +*/ + +// +// land +// + +void vulture_landed (edict_t *self) +{ + self->flags &= ~FL_FLY; + +// if ( !(self->flags & FL_FLY) ) +// gi.dprintf ("successfully converted monster_vulture to ground\n"); +} + +mframe_t vulture_frames_land [] = +{ + ai_move, 5, NULL, + ai_move, 5, NULL, + ai_move, 5, NULL, + ai_move, 5, NULL, + ai_move, 5, NULL, + ai_move, 5, NULL, + ai_move, 5, NULL, + ai_move, 5, NULL, + ai_move, 5, NULL, + ai_move, 5, NULL, + ai_move, 5, NULL, + ai_move, 5, NULL, + ai_move, 5, vulture_landed +}; +mmove_t vulture_move_land = {FRAME_land1, FRAME_land13, vulture_frames_land, vulture_walk}; +/* +void vulture_land (edict_t *self) +{ + self->monsterinfo.currentmove = &vulture_move_land; +} +*/ + +void vulture_run (edict_t *self) +{ + if (self->monsterinfo.aiflags & AI_STAND_GROUND) + { + if (self->flags & FL_FLY) { + self->monsterinfo.currentmove = &vulture_move_soar; + } + else { + self->monsterinfo.currentmove = &vulture_move_perch; + } + } + else + { + if (self->flags & FL_FLY) { + self->monsterinfo.currentmove = &vulture_move_fly; + } + else { + // takeoff if we're on ground + self->monsterinfo.currentmove = &vulture_move_takeoff; + } + } +} + +// +// melee +// + +void vulture_peck (edict_t *self) +{ + vec3_t aim; + float r; + + VectorSet (aim, MELEE_DISTANCE, self->mins[0], 0); + if ( fire_hit (self, aim, (int)(10 + (random() * 5)), 0) ) + { + r = random(); + if (r < 0.33f) + gi.sound (self, CHAN_WEAPON, sound_peck1, 1, ATTN_NORM, 0); + else if (r < 0.67f) + gi.sound (self, CHAN_WEAPON, sound_peck2, 1, ATTN_NORM, 0); + else + gi.sound (self, CHAN_WEAPON, sound_peck3, 1, ATTN_NORM, 0); + } +} + +mframe_t vulture_frames_melee [] = +{ + ai_charge, 0, NULL, + ai_charge, 0, vulture_peck, + ai_charge, 0, NULL, + ai_charge, 0, NULL +}; +mmove_t vulture_move_melee = {FRAME_melee1, FRAME_melee4, vulture_frames_melee, vulture_run}; + +void vulture_melee (edict_t *self) +{ + if (level.time < self->touch_debounce_time) + return; + + self->touch_debounce_time = level.time + 0.5f; + + self->monsterinfo.currentmove = &vulture_move_melee; +} + +/* +void vulture_attack (edict_t *self) +{ + int r; + + if (!self->enemy) + return; + + r = range(self, self->enemy); + + if (r == RANGE_MELEE) + { + self->monsterinfo.currentmove = &vulture_move_melee; + } +} +*/ + +// +// pain +// + +mframe_t vulture_frames_pain [] = +{ + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL +}; +mmove_t vulture_move_pain = {FRAME_pain1, FRAME_pain4, vulture_frames_pain, vulture_run}; + +// +// soar pain +// + +mframe_t vulture_frames_soarpain [] = +{ + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL +}; +mmove_t vulture_move_soarpain = {FRAME_soarpain1, FRAME_soarpain4, vulture_frames_soarpain, vulture_run}; + +void vulture_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 + 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 (self->flags & FL_FLY) + self->monsterinfo.currentmove = &vulture_move_soarpain; + else + self->monsterinfo.currentmove = &vulture_move_pain; +} + +// +// death +// + +void vulture_dead (edict_t *self) +{ + VectorSet (self->mins, -8, -8, -8); + VectorSet (self->maxs, 8, 8, 8); + self->movetype = MOVETYPE_TOSS; + self->svflags |= SVF_DEADMONSTER; + self->nextthink = 0; + gi.linkentity (self); + M_FlyCheck (self); + + // Lazarus monster fade + if (world->effects & FX_WORLDSPAWN_CORPSEFADE) + { + self->think = FadeDieSink; + self->nextthink = level.time + corpse_fadetime->value; + } +} + +mframe_t vulture_frames_death [] = +{ + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL, + ai_move, 0, NULL +}; +mmove_t vulture_move_death = {FRAME_die1, FRAME_die4, vulture_frames_death, vulture_dead}; + +// +// soar death +// + +mframe_t vulture_frames_soardeath [] = +{ + 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, + 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 vulture_move_soardeath = {FRAME_soardie1, FRAME_soardie30, vulture_frames_soardeath, vulture_dead}; + +void vulture_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 & 32) ) + { + gi.sound (self, CHAN_VOICE|CHAN_RELIABLE, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0); + + for (n = 0; n < 4; n++) + ThrowGib (self, "models/monsters/vulture/feather1.md2", damage, GIB_FEATHER); + for (n = 0; n < 4; n++) + ThrowGib (self, "models/monsters/vulture/feather2.md2", damage, GIB_FEATHER); + ThrowGib (self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC); + ThrowHead (self, "models/objects/gibs/bone2/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 (self->flags & FL_FLY) + self->monsterinfo.currentmove = &vulture_move_soardeath; + else + self->monsterinfo.currentmove = &vulture_move_death;; +} + + +/*QUAKED monster_vulture (1 .5 0) (-8 -8 -8) (8 8 8) Ambush Trigger_Spawn Sight InAir GoodGuy NoGib +*/ +void SP_monster_vulture (edict_t *self) +{ + if (deathmatch->value) + { + G_FreeEdict (self); + return; + } + +// sound_sight = gi.soundindex ("vulture/sight1.wav"); + sound_perch_idle1 = gi.soundindex ("vulture/perch_idle1.wav"); + sound_perch_idle2 = gi.soundindex ("vulture/perch_idle2.wav"); + sound_perch_idle3 = gi.soundindex ("vulture/perch_idle3.wav"); + sound_soar_idle1 = gi.soundindex ("vulture/soar_idle1.wav"); + sound_soar_idle2 = gi.soundindex ("vulture/soar_idle2.wav"); + sound_soar_idle3 = gi.soundindex ("vulture/soar_idle3.wav"); + sound_flap1 = gi.soundindex ("vulture/flap1.wav"); + sound_flap2 = gi.soundindex ("vulture/flap2.wav"); + sound_flap3 = gi.soundindex ("vulture/flap3.wav"); + sound_peck1 = gi.soundindex ("vulture/peck1.wav"); + sound_peck2 = gi.soundindex ("vulture/peck2.wav"); + sound_peck3 = gi.soundindex ("vulture/peck3.wav"); + sound_pain1 = gi.soundindex ("vulture/pain1.wav"); + sound_pain2 = gi.soundindex ("vulture/pain2.wav"); + sound_death = gi.soundindex ("vulture/death1.wav"); + + // precache feather gibs + gi.modelindex ("models/monsters/vulture/feather1.md2"); + gi.modelindex ("models/monsters/vulture/feather2.md2"); + + // Lazarus: special purpose skins + if ( self->style ) + { + PatchMonsterModel("models/monsters/vulture/tris.md2"); + self->s.skinnum = self->style; + } + + self->s.modelindex = gi.modelindex ("models/monsters/vulture/tris.md2"); + VectorSet (self->mins, -8, -8, -8); + VectorSet (self->maxs, 8, 8, 10); + self->movetype = MOVETYPE_STEP; + self->solid = SOLID_BBOX; + + // if spawned as landed, bump origin so we don't start in a brush +/* if ( !(self->spawnflags & SF_VULTURE_IN_AIR) ) { + self->s.origin[2] += 8; + } */ + + if (!self->health) + self->health = 50; + if (!self->gib_health) + self->gib_health = -20; + if (!self->mass) + self->mass = 50; + + self->pain = vulture_pain; + self->die = vulture_die; + + self->monsterinfo.stand = vulture_perch; + self->monsterinfo.walk = vulture_walk; + self->monsterinfo.run = vulture_run; + self->monsterinfo.dodge = NULL; + self->monsterinfo.attack = NULL; + self->monsterinfo.melee = vulture_melee; + self->monsterinfo.sight = vulture_sight; + self->monsterinfo.idle = vulture_idle; + self->monsterinfo.search = NULL; + self->monsterinfo.blocked = NULL; + + if (!self->monsterinfo.flies) + self->monsterinfo.flies = 0.05; + + // 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 = "Vulture"; + self->class_id = ENTITY_MONSTER_VULTURE; + self->spawnflags |= SF_MONSTER_KNOWS_MIRRORS; + + gi.linkentity (self); + +// self->monsterinfo.currentmove = &vulture_move_perch; + self->monsterinfo.scale = MODEL_SCALE; + + if (self->spawnflags & SF_VULTURE_IN_AIR) { + self->monsterinfo.currentmove = &vulture_move_soar; + flymonster_start (self); + } + else { + self->monsterinfo.currentmove = &vulture_move_perch; + walkmonster_start (self); + } +} diff --git a/missionpack/missionpack.dsp b/missionpack/missionpack.dsp index 757dd22..2c6e361 100644 --- a/missionpack/missionpack.dsp +++ b/missionpack/missionpack.dsp @@ -281,10 +281,6 @@ SOURCE=.\g_weapon_q1.c # End Source File # Begin Source File -SOURCE=.\grenade.c -# End Source File -# Begin Source File - SOURCE=.\km_cvar.c # End Source File # Begin Source File @@ -477,6 +473,10 @@ SOURCE=.\m_turret.c # End Source File # Begin Source File +SOURCE=.\m_vulture.c +# End Source File +# Begin Source File + SOURCE=.\m_widow.c # End Source File # Begin Source File @@ -757,6 +757,10 @@ SOURCE=.\m_turret.h # End Source File # Begin Source File +SOURCE=.\m_vulture.h +# End Source File +# Begin Source File + SOURCE=.\m_zombie.h # End Source File # Begin Source File diff --git a/missionpack/missionpack_2008.vcproj b/missionpack/missionpack_2008.vcproj index 7231d9d..da44f32 100644 --- a/missionpack/missionpack_2008.vcproj +++ b/missionpack/missionpack_2008.vcproj @@ -4,6 +4,7 @@ Version="9.00" Name="missionpack" ProjectGUID="{B2C5294F-5F08-4598-B02C-272370AE8F38}" + RootNamespace="missionpack" TargetFrameworkVersion="0" > <Platforms> @@ -602,10 +603,6 @@ RelativePath=".\g_weapon_q1.c" > </File> - <File - RelativePath="grenade.c" - > - </File> <File RelativePath="km_cvar.c" > @@ -738,6 +735,10 @@ RelativePath=".\m_q1fiend.c" > </File> + <File + RelativePath=".\m_q1freddie.c" + > + </File> <File RelativePath=".\m_q1grunt.c" > @@ -798,6 +799,10 @@ RelativePath="m_turret.c" > </File> + <File + RelativePath=".\m_vulture.c" + > + </File> <File RelativePath="m_widow.c" > @@ -1015,6 +1020,10 @@ RelativePath=".\m_q1fiend.h" > </File> + <File + RelativePath=".\m_q1freddie.h" + > + </File> <File RelativePath=".\m_q1grunt.h" > @@ -1080,7 +1089,7 @@ > </File> <File - RelativePath="m_zombie.h" + RelativePath=".\m_vulture.h" > </File> <File diff --git a/missionpack/p_client.c b/missionpack/p_client.c index 5d5a102..17c7f35 100644 --- a/missionpack/p_client.c +++ b/missionpack/p_client.c @@ -1044,6 +1044,9 @@ void ClientObituary (edict_t *self, edict_t *inflictor, edict_t *attacker) // Rottweiler else if (!strcmp(attacker->classname, "monster_dog")) message = "was mauled by a"; + // Vulture + else if (!strcmp(attacker->classname, "monster_vulture")) + message = "was pecked to death by a"; // Quake 1 Monsters // Fiend else if ( !Q_stricmp(attacker->classname, "q1_monster_fiend") || !Q_stricmp(attacker->classname, "monster_q1_demon") ) @@ -1086,6 +1089,10 @@ void ClientObituary (edict_t *self, edict_t *inflictor, edict_t *attacker) // Spawn else if ( !Q_stricmp(attacker->classname, "q1_monster_tarbaby") || !Q_stricmp(attacker->classname, "monster_q1_tarbaby") ) message = "was slimed by a"; + // Freddie + else if ( !Q_stricmp(attacker->classname, "q1_monster_freddie") || !Q_stricmp(attacker->classname, "monster_q1_freddie") ) + message = "was exterminated by"; + } if (message) { diff --git a/missionpack/p_weapon.c b/missionpack/p_weapon.c index b0e88b5..c5c1caa 100644 --- a/missionpack/p_weapon.c +++ b/missionpack/p_weapon.c @@ -3636,7 +3636,7 @@ void weapon_plasma_rifle_fire (edict_t *ent, qboolean altfire) } // if outa ammo, don't fire - if (ent->client->pers.inventory[ent->client->ammo_index] < 1) + if (ent->client->pers.inventory[ent->client->ammo_index] < PLASMA_CELLS_PER_SHOT) // was < 1 { ent->client->ps.gunframe++;