Added monster_gunner_commander to missionpack DLL.

Added monster_fire_flechette() and monster_fire_prox() functions to g_monster.c in missionpack DLL.
Refactored prox weapon code in missionpack DLL.
Added grenade evasion for monster-fired prox mines.
Added FL2_COMMANDER moreflag for medic commander and deadalus in missionpack DLL.
Added precache of hand grenade model to grenade ammo in g_items.c in default Lazarus DLL and missionpack DLL.
This commit is contained in:
Knightmare66 2021-04-23 05:08:26 -04:00
parent 0a54aa8423
commit 4b6e68fcd2
20 changed files with 502 additions and 293 deletions

View file

@ -1986,7 +1986,7 @@ always owned, never in the world
WEAP_GRENADES, WEAP_GRENADES,
NULL, NULL,
AMMO_GRENADES, AMMO_GRENADES,
/* precache */ "weapons/hgrent1a.wav weapons/hgrena1b.wav weapons/hgrenc1b.wav weapons/hgrenb1a.wav weapons/hgrenb2a.wav " /* precache */ "models/objects/grenade2/tris.md2 weapons/hgrent1a.wav weapons/hgrena1b.wav weapons/hgrenc1b.wav weapons/hgrenb1a.wav weapons/hgrenb2a.wav "
}, },
/*QUAKED weapon_grenadelauncher (.3 .3 1) (-16 -16 -16) (16 16 16) /*QUAKED weapon_grenadelauncher (.3 .3 1) (-16 -16 -16) (16 16 16)

View file

@ -1076,9 +1076,9 @@ void T_Damage (edict_t *in_targ, edict_t *inflictor, edict_t *in_attacker, vec3_
// Shamblers take half damage from explosives // Shamblers take half damage from explosives
if ( (targ->svflags & SVF_MONSTER) && if ( (targ->svflags & SVF_MONSTER) &&
( (Q_stricmp(targ->classname,"q1_monster_shambler") == 0) || (Q_stricmp(targ->classname,"monster_q1_shambler") == 0) ) && ( (Q_stricmp(targ->classname,"q1_monster_shambler") == 0) || (Q_stricmp(targ->classname,"monster_q1_shambler") == 0) ) &&
( (Q_stricmp(inflictor->classname, "grenade") == 0) || (Q_stricmp(inflictor->classname, "prox") == 0) || ( (Q_stricmp(inflictor->classname, "grenade") == 0) || (Q_stricmp(inflictor->classname, "hgrenade") == 0)
(Q_stricmp(inflictor->classname, "plasma") == 0) || || (Q_stricmp(inflictor->classname, "prox") == 0) || (Q_stricmp(inflictor->classname, "plasma") == 0)
(Q_stricmp(inflictor->classname, "rocket") == 0) || (Q_stricmp(inflictor->classname, "homing rocket") == 0) ) ) || (Q_stricmp(inflictor->classname, "rocket") == 0) || (Q_stricmp(inflictor->classname, "homing rocket") == 0) ) )
damage = (int)((float)damage * 0.5f); damage = (int)((float)damage * 0.5f);
// Skid - q1 monsters don't go flying // Skid - q1 monsters don't go flying

View file

@ -2149,7 +2149,7 @@ extern void fire_player_melee ( edict_t * self , vec3_t start , vec3_t aim , int
extern void SP_prox ( edict_t * prox ) ; extern void SP_prox ( edict_t * prox ) ;
extern void prox_delayed_start ( edict_t * prox ) ; extern void prox_delayed_start ( edict_t * prox ) ;
extern void Cmd_DetProx_f ( edict_t * ent ) ; extern void Cmd_DetProx_f ( edict_t * ent ) ;
extern void fire_prox ( edict_t * self , vec3_t start , vec3_t aimdir , int damage_multiplier , int speed ) ; extern void fire_prox ( edict_t * self , vec3_t start , vec3_t aimdir , int damage , int damage_multiplier , int speed , int health , float timer , float damage_radius ) ;
extern void prox_land ( edict_t * ent , edict_t * other , cplane_t * plane , csurface_t * surf ) ; extern void prox_land ( edict_t * ent , edict_t * other , cplane_t * plane , csurface_t * surf ) ;
extern void prox_open ( edict_t * ent ) ; extern void prox_open ( edict_t * ent ) ;
extern void prox_seek ( edict_t * ent ) ; extern void prox_seek ( edict_t * ent ) ;
@ -2272,6 +2272,8 @@ extern void M_FlyCheck ( edict_t * self ) ;
extern void M_FliesOn ( edict_t * self ) ; extern void M_FliesOn ( edict_t * self ) ;
extern void M_FliesOff ( edict_t * self ) ; extern void M_FliesOff ( edict_t * self ) ;
extern void monster_fire_plasma_rifle ( edict_t * self , vec3_t start , vec3_t dir , int damage , int speed , int flashtype , qboolean spread ) ; extern void monster_fire_plasma_rifle ( edict_t * self , vec3_t start , vec3_t dir , int damage , int speed , int flashtype , qboolean spread ) ;
extern void monster_fire_prox ( edict_t * self , vec3_t start , vec3_t aimdir , int damage , int damage_multiplier , int speed , int health , float timer , float damage_radius , int flashtype ) ;
extern void monster_fire_flechette ( edict_t * self , vec3_t start , vec3_t dir , int damage , int speed , float damage_radius , int radius_damage , int flashtype ) ;
extern void monster_fire_heat ( edict_t * self , vec3_t start , vec3_t dir , vec3_t offset , int damage , int kick , int flashtype ) ; extern void monster_fire_heat ( edict_t * self , vec3_t start , vec3_t dir , vec3_t offset , int damage , int kick , int flashtype ) ;
extern void monster_fire_tracker ( edict_t * self , vec3_t start , vec3_t dir , int damage , int speed , edict_t * enemy , int flashtype ) ; extern void monster_fire_tracker ( edict_t * self , vec3_t start , vec3_t dir , int damage , int speed , edict_t * enemy , int flashtype ) ;
extern void monster_fire_blaster2 ( edict_t * self , vec3_t start , vec3_t dir , int damage , int speed , int flashtype , int effect ) ; extern void monster_fire_blaster2 ( edict_t * self , vec3_t start , vec3_t dir , int damage , int speed , int flashtype , int effect ) ;

View file

@ -2272,6 +2272,8 @@
{"M_FliesOn", (byte *)M_FliesOn}, {"M_FliesOn", (byte *)M_FliesOn},
{"M_FliesOff", (byte *)M_FliesOff}, {"M_FliesOff", (byte *)M_FliesOff},
{"monster_fire_plasma_rifle", (byte *)monster_fire_plasma_rifle}, {"monster_fire_plasma_rifle", (byte *)monster_fire_plasma_rifle},
{"monster_fire_prox", (byte *)monster_fire_prox},
{"monster_fire_flechette", (byte *)monster_fire_flechette},
{"monster_fire_heat", (byte *)monster_fire_heat}, {"monster_fire_heat", (byte *)monster_fire_heat},
{"monster_fire_tracker", (byte *)monster_fire_tracker}, {"monster_fire_tracker", (byte *)monster_fire_tracker},
{"monster_fire_blaster2", (byte *)monster_fire_blaster2}, {"monster_fire_blaster2", (byte *)monster_fire_blaster2},

View file

@ -2825,7 +2825,7 @@ gitem_t itemlist[] =
WEAP_GRENADES, WEAP_GRENADES,
NULL, NULL,
AMMO_GRENADES, AMMO_GRENADES,
"weapons/hgrent1a.wav weapons/hgrena1b.wav weapons/hgrenc1b.wav weapons/hgrenb1a.wav weapons/hgrenb2a.wav" // precache "models/objects/grenade2/tris.md2 weapons/hgrent1a.wav weapons/hgrena1b.wav weapons/hgrenc1b.wav weapons/hgrenb1a.wav weapons/hgrenb2a.wav" // precache
}, },
// 16 // 16

View file

@ -135,6 +135,7 @@
#define FL2_TURRET_DOUBLE_ALT 0x00000002 // this turret alternates firing its barrels (style is set) #define FL2_TURRET_DOUBLE_ALT 0x00000002 // this turret alternates firing its barrels (style is set)
#define FL2_TURRET_DOUBLE_ALT_FIRING 0x00000004 // secondary barrel in use for alternate firing #define FL2_TURRET_DOUBLE_ALT_FIRING 0x00000004 // secondary barrel in use for alternate firing
#define FL2_CRUCIFIED 0x00000008 // insane is crucified #define FL2_CRUCIFIED 0x00000008 // insane is crucified
#define FL2_COMMANDER 0x00000008 // Gunner Commander internal flag
#define FL2_WEAPON_ALT 0x00000010 // plasma guard has spread mode #define FL2_WEAPON_ALT 0x00000010 // plasma guard has spread mode
#define FL2_DO_NOT_REFLECT 0x00000020 // do not reflect this entity #define FL2_DO_NOT_REFLECT 0x00000020 // do not reflect this entity
@ -1380,7 +1381,11 @@ void monster_fire_tracker (edict_t *self, vec3_t start, vec3_t dir, int damage,
void monster_fire_heat (edict_t *self, vec3_t start, vec3_t dir, vec3_t offset, int damage, int kick, int flashtype); void monster_fire_heat (edict_t *self, vec3_t start, vec3_t dir, vec3_t offset, int damage, int kick, int flashtype);
// ROGUE // ROGUE
void monster_fire_plasma_rifle (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, int flashtype, qboolean spread); // SKWiD MOD // Knightmare added
void monster_fire_flechette (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, float damage_radius, int radius_damage, int flashtype);
void monster_fire_prox (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int damage_multiplier, int speed, int health, float timer, float damage_radius, int flashtype);
// SKWiD MOD
void monster_fire_plasma_rifle (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, int flashtype, qboolean spread);
void M_droptofloor (edict_t *ent); void M_droptofloor (edict_t *ent);
void monster_think (edict_t *self); void monster_think (edict_t *self);
@ -1501,6 +1506,8 @@ void Trap_Explode (edict_t *ent);
// Lazarus // Lazarus
qboolean AimGrenade (edict_t *launcher, vec3_t start, vec3_t target, vec_t speed, vec3_t aim); qboolean AimGrenade (edict_t *launcher, vec3_t start, vec3_t target, vec_t speed, vec3_t aim);
void Grenade_Evade (edict_t *monster); void Grenade_Evade (edict_t *monster);
void Grenade_Add_To_Chain (edict_t *grenade);
void Grenade_Remove_From_Chain (edict_t *grenade);
// //
// g_weapon_q1.c // g_weapon_q1.c
@ -1732,7 +1739,8 @@ void kick_attack (edict_t *ent);
// //
//extern float nuke_framenum; //extern float nuke_framenum;
void fire_flechette (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, float damage_radius, int radius_damage); void fire_flechette (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, float damage_radius, int radius_damage);
void fire_prox (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed); //void fire_prox (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed);
void fire_prox (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int damage_multiplier, int speed, int health, float timer, float damage_radius);
void fire_nuke (edict_t *self, vec3_t start, vec3_t aimdir, int speed); void fire_nuke (edict_t *self, vec3_t start, vec3_t aimdir, int speed);
void fire_nbomb (edict_t *self, vec3_t start, vec3_t aimdir, int speed); void fire_nbomb (edict_t *self, vec3_t start, vec3_t aimdir, int speed);
void fire_flame (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed); void fire_flame (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed);

View file

@ -486,6 +486,28 @@ void monster_fire_heat (edict_t *self, vec3_t start, vec3_t dir, vec3_t offset,
} }
// ROGUE // ROGUE
// Knightmare added
void monster_fire_flechette (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, float damage_radius, int radius_damage, int flashtype)
{
fire_flechette (self, start, dir, damage, speed, damage_radius, radius_damage);
gi.WriteByte (svc_muzzleflash2);
gi.WriteShort (self - g_edicts);
gi.WriteByte (flashtype);
gi.multicast (start, MULTICAST_PVS);
}
void monster_fire_prox (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int damage_multiplier, int speed, int health, float timer, float damage_radius, int flashtype)
{
fire_prox (self, start, aimdir, damage, damage_multiplier, speed, health, timer, damage_radius);
gi.WriteByte (svc_muzzleflash2);
gi.WriteShort (self - g_edicts);
gi.WriteByte (flashtype);
gi.multicast (start, MULTICAST_PVS);
}
// end Knightmare
// SKWiD MOD // SKWiD MOD
void monster_fire_plasma_rifle (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, int flashtype, qboolean spread) void monster_fire_plasma_rifle (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, int flashtype, qboolean spread)
{ {
@ -939,9 +961,9 @@ void M_MoveFrame (edict_t *self)
mmove_t *move; mmove_t *move;
int index; int index;
// Lazarus: For live monsters weaker than gladiator who aren't already running from // Lazarus: For live monsters weaker than the tank who aren't already running from
// something, evade live grenades on the ground. // something, evade live grenades on the ground.
if ((self->health > 0) && (self->max_health < 400) && !(self->monsterinfo.aiflags & AI_CHASE_THING) && self->monsterinfo.run) if ((self->health > 0) && (self->max_health < 750) && !(self->monsterinfo.aiflags & AI_CHASE_THING) && self->monsterinfo.run) // was self->max_health < 400
Grenade_Evade (self); Grenade_Evade (self);
move = self->monsterinfo.currentmove; move = self->monsterinfo.currentmove;
@ -1659,6 +1681,7 @@ int PatchMonsterModel (char *modelname)
qboolean is_gekk = false; qboolean is_gekk = false;
qboolean is_fixbot = false; qboolean is_fixbot = false;
qboolean is_chick = false; qboolean is_chick = false;
qboolean is_gunner = false;
qboolean is_soldierh = false; qboolean is_soldierh = false;
qboolean is_carrier = false; qboolean is_carrier = false;
qboolean is_hover = false; qboolean is_hover = false;
@ -1724,6 +1747,11 @@ int PatchMonsterModel (char *modelname)
is_chick = true; is_chick = true;
numskins = 16; numskins = 16;
} }
else if (!strcmp(modelname, "models/monsters/gunner/tris.md2"))
{
is_gunner = true;
numskins = 16;
}
else if (!strcmp(modelname, "models/monsters/soldierh/tris.md2")) else if (!strcmp(modelname, "models/monsters/soldierh/tris.md2"))
{ {
is_soldierh = true; is_soldierh = true;
@ -2021,6 +2049,44 @@ int PatchMonsterModel (char *modelname)
Com_strcat (skins[j], sizeof(skins[j]), "custombeta_p3.pcx"); break; Com_strcat (skins[j], sizeof(skins[j]), "custombeta_p3.pcx"); break;
} }
} }
else if (is_gunner)
{
switch (j)
{
case 0:
Com_strcat (skins[j], sizeof(skins[j]), "skin.pcx"); break;
case 1:
Com_strcat (skins[j], sizeof(skins[j]), "pain.pcx"); break;
case 2:
Com_strcpy (skins[j], sizeof(skins[j]), "comm_skin.pcx"); break;
case 3:
Com_strcpy (skins[j], sizeof(skins[j]), "comm_pain.pcx"); break;
case 4:
Com_strcat (skins[j], sizeof(skins[j]), "custom1.pcx"); break;
case 5:
Com_strcat (skins[j], sizeof(skins[j]), "custompain1.pcx"); break;
case 6:
Com_strcat (skins[j], sizeof(skins[j]), "custombeta1.pcx"); break;
case 7:
Com_strcat (skins[j], sizeof(skins[j]), "custombeta_p1.pcx"); break;
case 8:
Com_strcat (skins[j], sizeof(skins[j]), "custom2.pcx"); break;
case 9:
Com_strcat (skins[j], sizeof(skins[j]), "custompain2.pcx"); break;
case 10:
Com_strcat (skins[j], sizeof(skins[j]), "custombeta2.pcx"); break;
case 11:
Com_strcat (skins[j], sizeof(skins[j]), "custombeta_p2.pcx"); break;
case 12:
Com_strcat (skins[j], sizeof(skins[j]), "custom3.pcx"); break;
case 13:
Com_strcat (skins[j], sizeof(skins[j]), "custompain3.pcx"); break;
case 14:
Com_strcat (skins[j], sizeof(skins[j]), "custombeta3.pcx"); break;
case 15:
Com_strcat (skins[j], sizeof(skins[j]), "custombeta_p3.pcx"); break;
}
}
else if (is_soldierh) else if (is_soldierh)
{ {
switch (j) switch (j)

View file

@ -1409,6 +1409,7 @@ qboolean MarkTeslaArea(edict_t *self, edict_t *tesla)
return true; return true;
} }
// predictive calculator // predictive calculator
// target is who you want to shoot // target is who you want to shoot
// start is where the shot comes from // start is where the shot comes from

View file

@ -279,6 +279,8 @@ void Prox_Explode (edict_t *ent)
edict_t *owner; edict_t *owner;
int type; int type;
Grenade_Remove_From_Chain (ent);
// free the trigger field // free the trigger field
// PMM - changed teammaster to "mover" .. owner of the field is the prox // PMM - changed teammaster to "mover" .. owner of the field is the prox
@ -293,16 +295,19 @@ void Prox_Explode (edict_t *ent)
} }
// play quad sound if appopriate // play quad sound if appopriate
if (ent->dmg > sk_prox_damage->value) // if (ent->dmg > sk_prox_damage->value)
if (ent->count > 1) // Knightmare- use stored multiplier
{ {
if (ent->dmg < (4 * sk_prox_damage->value)) //double sound // if (ent->dmg < (4 * sk_prox_damage->value)) // double sound
if (ent->count < 4) // double sound
gi.sound(ent, CHAN_ITEM, gi.soundindex("misc/ddamage3.wav"), 1, ATTN_NORM, 0); gi.sound(ent, CHAN_ITEM, gi.soundindex("misc/ddamage3.wav"), 1, ATTN_NORM, 0);
else // quad sound else // quad sound
gi.sound(ent, CHAN_ITEM, gi.soundindex("items/damage3.wav"), 1, ATTN_NORM, 0); gi.sound(ent, CHAN_ITEM, gi.soundindex("items/damage3.wav"), 1, ATTN_NORM, 0);
} }
ent->takedamage = DAMAGE_NO; ent->takedamage = DAMAGE_NO;
T_RadiusDamage(ent, owner, ent->dmg, ent, sk_prox_radius->value, MOD_PROX); // T_RadiusDamage(ent, owner, ent->dmg, ent, sk_prox_radius->value, MOD_PROX);
T_RadiusDamage(ent, owner, ent->dmg, ent, ent->dmg_radius, MOD_PROX);
VectorMA (ent->s.origin, -0.02, ent->velocity, origin); VectorMA (ent->s.origin, -0.02, ent->velocity, origin);
if (ent->groundentity) if (ent->groundentity)
@ -350,7 +355,6 @@ void Prox_Field_Touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t
if ( !(other->svflags & SVF_MONSTER) && !other->client ) if ( !(other->svflags & SVF_MONSTER) && !other->client )
return; return;
// trigger the prox mine if it's still there, and still mine. // trigger the prox mine if it's still there, and still mine.
prox = ent->owner; prox = ent->owner;
@ -418,7 +422,8 @@ void prox_open (edict_t *ent)
// ent->owner = NULL; // ent->owner = NULL;
if (ent->teamchain) if (ent->teamchain)
ent->teamchain->touch = Prox_Field_Touch; ent->teamchain->touch = Prox_Field_Touch;
while ((search = findradius(search, ent->s.origin, sk_prox_radius->value + 10)) != NULL) // while ((search = findradius(search, ent->s.origin, sk_prox_radius->value + 10)) != NULL)
while ((search = findradius(search, ent->s.origin, ent->dmg_radius + 10)) != NULL)
{ {
if (!search->classname) // tag token and other weird shit if (!search->classname) // tag token and other weird shit
continue; continue;
@ -452,27 +457,28 @@ void prox_open (edict_t *ent)
} }
if (strong_mines && (strong_mines->value)) if (strong_mines && (strong_mines->value))
ent->wait = level.time + sk_prox_life->value; ent->wait = level.time + ent->delay; // sk_prox_life->value // Knightmare- use stored timer
else else
{ {
switch (ent->dmg / (int)sk_prox_damage->value) // switch (ent->dmg / (int)sk_prox_damage->value)
switch (ent->count) // Knightmare- use stored multiplier
{ {
case 1: case 1:
ent->wait = level.time + sk_prox_life->value; ent->wait = level.time + ent->delay; // sk_prox_life->value // Knightmare- use stored timer
break; break;
case 2: case 2:
ent->wait = level.time + sk_prox_life->value / 2; ent->wait = level.time + ent->delay / 2; // sk_prox_life->value // Knightmare- use stored timer
break; break;
case 4: case 4:
ent->wait = level.time + sk_prox_life->value / 4; ent->wait = level.time + ent->delay / 4; // sk_prox_life->value // Knightmare- use stored timer
break; break;
case 8: case 8:
ent->wait = level.time + sk_prox_life->value / 8; ent->wait = level.time + ent->delay / 8; // sk_prox_life->value // Knightmare- use stored timer
break; break;
default: default:
// if ((g_showlogic) && (g_showlogic->value)) // if ((g_showlogic) && (g_showlogic->value))
// gi.dprintf ("prox with unknown multiplier %d!\n", ent->dmg/PROX_DAMAGE); // gi.dprintf ("prox with unknown multiplier %d!\n", ent->count);
ent->wait = level.time + sk_prox_life->value; ent->wait = level.time + ent->delay; // sk_prox_life->value // Knightmare- use stored timer
break; break;
} }
} }
@ -515,6 +521,7 @@ void prox_land (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
if (surf && (surf->flags & SURF_SKY)) if (surf && (surf->flags & SURF_SKY))
{ {
Grenade_Remove_From_Chain (ent);
G_FreeEdict(ent); G_FreeEdict(ent);
return; return;
} }
@ -655,7 +662,8 @@ void prox_land (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
ent->movetype = movetype; // either bounce or none, depending on whether we stuck to something ent->movetype = movetype; // either bounce or none, depending on whether we stuck to something
ent->die = prox_die; ent->die = prox_die;
ent->teamchain = field; ent->teamchain = field;
ent->health = sk_prox_health->value; // ent->health = sk_prox_health->value;
ent->health = ent->max_health; // Knightmare- health is stored in max_health
ent->nextthink = level.time + 0.05; ent->nextthink = level.time + 0.05;
ent->think = prox_open; ent->think = prox_open;
ent->touch = NULL; ent->touch = NULL;
@ -672,7 +680,7 @@ void prox_land (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
//=============== //===============
//=============== //===============
void fire_prox (edict_t *self, vec3_t start, vec3_t aimdir, int damage_multiplier, int speed) void fire_prox (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int damage_multiplier, int speed, int health, float timer, float damage_radius)
{ {
edict_t *prox; edict_t *prox;
vec3_t dir; vec3_t dir;
@ -709,34 +717,22 @@ void fire_prox (edict_t *self, vec3_t start, vec3_t aimdir, int damage_multiplie
prox->owner = self; prox->owner = self;
prox->teammaster = self; prox->teammaster = self;
prox->touch = prox_land; prox->touch = prox_land;
// prox->nextthink = level.time + sk_prox_life->value; prox->nextthink = level.time + timer;
prox->think = Prox_Explode; prox->think = Prox_Explode;
prox->dmg = sk_prox_damage->value*damage_multiplier; // prox->dmg = sk_prox_damage->value * damage_multiplier;
prox->dmg = damage * damage_multiplier; // Knightmare- use damage param
prox->count = damage_multiplier; // Knightmare- store damage_multiplier param
prox->dmg_radius = damage_radius; // Knightmare- use damage_radius param
prox->max_health = health; // Knightmare- use health param
prox->delay = timer; // Knightmare- store timer param
prox->classname = "prox"; prox->classname = "prox";
prox->class_id = ENTITY_MINE_PROX; prox->class_id = ENTITY_MINE_PROX;
prox->svflags |= SVF_DAMAGEABLE; prox->svflags |= SVF_DAMAGEABLE;
prox->flags |= FL_MECHANICAL; prox->flags |= FL_MECHANICAL;
switch (damage_multiplier) // Knightmare- mark monster-fired prox mines for avoidance
{ if (self->svflags & SVF_MONSTER)
case 1: Grenade_Add_To_Chain (prox);
prox->nextthink = level.time + sk_prox_life->value;
break;
case 2:
prox->nextthink = level.time + sk_prox_life->value;
break;
case 4:
prox->nextthink = level.time + sk_prox_life->value;
break;
case 8:
prox->nextthink = level.time + sk_prox_life->value;
break;
default:
// if ((g_showlogic) && (g_showlogic->value))
// gi.dprintf ("prox with unknown multiplier %d!\n", damage_multiplier);
prox->nextthink = level.time + sk_prox_life->value;
break;
}
gi.linkentity (prox); gi.linkentity (prox);
} }
@ -764,7 +760,7 @@ void prox_delayed_start (edict_t *prox)
{ {
VectorScale(prox->movedir,prox->moveinfo.speed,prox->velocity); VectorScale(prox->movedir,prox->moveinfo.speed,prox->velocity);
prox->movetype = MOVETYPE_BOUNCE; prox->movetype = MOVETYPE_BOUNCE;
prox->nextthink = level.time + sk_prox_life->value; prox->nextthink = level.time + prox->delay; // sk_prox_life->value // Knightmare- use stored timer
prox->think = Prox_Explode; prox->think = Prox_Explode;
gi.linkentity(prox); gi.linkentity(prox);
} }
@ -794,7 +790,7 @@ void SP_prox (edict_t *prox)
else else
{ {
prox->movetype = MOVETYPE_BOUNCE; prox->movetype = MOVETYPE_BOUNCE;
prox->nextthink = level.time + sk_prox_life->value; prox->nextthink = level.time + prox->delay; // sk_prox_life->value // Knightmare- use stored timer
prox->think = Prox_Explode; prox->think = Prox_Explode;
} }
gi.linkentity (prox); gi.linkentity (prox);

View file

@ -586,6 +586,9 @@ spawn_t spawns[] = {
{"misc_seat", SP_misc_seat}, {"misc_seat", SP_misc_seat},
// end Zaero // end Zaero
// Knightmare- added Gunner Commander
{"monster_gunner_commander", SP_monster_gunner},
// Knightmare- the dog from Coconut Monkey 3 // Knightmare- the dog from Coconut Monkey 3
{"monster_dog", SP_monster_dog}, {"monster_dog", SP_monster_dog},
// Knightmare- the vulture from Coconut Monkey 2 // Knightmare- the vulture from Coconut Monkey 2
@ -881,6 +884,9 @@ void ED_CallSpawn (edict_t *ent)
// don't spawn another medic commander from medic commander // don't spawn another medic commander from medic commander
&& !(ent->monsterinfo.monsterflags & MFL_DO_NOT_COUNT)) && !(ent->monsterinfo.monsterflags & MFL_DO_NOT_COUNT))
ent->classname = "monster_medic_commander"; ent->classname = "monster_medic_commander";
// gunner
if ( !strcmp(ent->classname, "monster_gunner") && (random() < ((skill->value + 1.0f) * 0.15f)) )
ent->classname = "monster_gunner_commander";
} }
// LM Escape monster replacement // LM Escape monster replacement

View file

@ -212,7 +212,8 @@ void thing_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *su
// make sure this is still a 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")
&& Q_stricmp(grenade->classname, "prox")) // Knightmare- added prox
other->next_grenade = grenade = NULL; other->next_grenade = grenade = NULL;
} }
else else

View file

@ -588,7 +588,7 @@ void Grenade_Evade (edict_t *monster)
} }
} }
/*static*/ void Grenade_Add_To_Chain (edict_t *grenade) void Grenade_Add_To_Chain (edict_t *grenade)
{ {
edict_t *ancestor; edict_t *ancestor;
@ -599,7 +599,7 @@ void Grenade_Evade (edict_t *monster)
grenade->prev_grenade = ancestor; grenade->prev_grenade = ancestor;
} }
/*static*/ void Grenade_Remove_From_Chain (edict_t *grenade) void Grenade_Remove_From_Chain (edict_t *grenade)
{ {
if (grenade->prev_grenade) if (grenade->prev_grenade)
{ {
@ -617,6 +617,8 @@ void Grenade_Explode (edict_t *ent)
int mod; int mod;
int type; // Knightmare added int type; // Knightmare added
Grenade_Remove_From_Chain (ent);
if (ent->owner->client) if (ent->owner->client)
PlayerNoise(ent->owner, ent->s.origin, PNOISE_IMPACT); PlayerNoise(ent->owner, ent->s.origin, PNOISE_IMPACT);
@ -674,13 +676,14 @@ void Grenade_Explode (edict_t *ent)
G_FreeEdict (ent); G_FreeEdict (ent);
} }
/*static*/ void Grenade_Touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) void Grenade_Touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
{ {
if (other == ent->owner) if (other == ent->owner)
return; return;
if (surf && (surf->flags & SURF_SKY)) if (surf && (surf->flags & SURF_SKY))
{ {
Grenade_Remove_From_Chain (ent);
G_FreeEdict (ent); G_FreeEdict (ent);
return; return;
} }
@ -705,7 +708,7 @@ void Grenade_Explode (edict_t *ent)
Grenade_Explode (ent); Grenade_Explode (ent);
} }
/*static*/ void ContactGrenade_Touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) void ContactGrenade_Touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
{ {
if (other == ent->owner) if (other == ent->owner)
return; return;
@ -764,6 +767,8 @@ void fire_grenade (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int s
grenade->classname = "grenade"; grenade->classname = "grenade";
grenade->class_id = ENTITY_GRENADE; grenade->class_id = ENTITY_GRENADE;
Grenade_Add_To_Chain (grenade);
gi.linkentity (grenade); gi.linkentity (grenade);
} }
@ -815,6 +820,7 @@ void fire_grenade2 (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int
else else
{ {
gi.sound (self, CHAN_WEAPON, gi.soundindex ("weapons/hgrent1a.wav"), 1, ATTN_NORM, 0); gi.sound (self, CHAN_WEAPON, gi.soundindex ("weapons/hgrent1a.wav"), 1, ATTN_NORM, 0);
Grenade_Add_To_Chain (grenade);
gi.linkentity (grenade); gi.linkentity (grenade);
} }
} }
@ -1000,6 +1006,7 @@ qboolean AimGrenade (edict_t *self, vec3_t start, vec3_t target, vec_t speed, ve
if (i >= 10 || v_error > 64) if (i >= 10 || v_error > 64)
return false; return false;
if (fabs(v_error) > fabs(last_error)) if (fabs(v_error) > fabs(last_error))
{ {
VectorCopy(last_aim,aim); VectorCopy(last_aim,aim);
@ -1024,7 +1031,8 @@ qboolean AimGrenade (edict_t *self, vec3_t start, vec3_t target, vec_t speed, ve
vec3_t dist; vec3_t dist;
tr = gi.trace(start, vec3_origin, vec3_origin, aim_point, self, MASK_SOLID); tr = gi.trace(start, vec3_origin, vec3_origin, aim_point, self, MASK_SOLID);
if( (tr.fraction < 1.0) && (!self->enemy || (tr.ent != self->enemy) )) { if ( (tr.fraction < 1.0) && (!self->enemy || (tr.ent != self->enemy) ))
{
// OK... the aim vector hit a solid, but would the grenade actually hit? // OK... the aim vector hit a solid, but would the grenade actually hit?
int contents; int contents;
cosa = sqrt(aim[0] * aim[0] + aim[1] * aim[1]); cosa = sqrt(aim[0] * aim[0] + aim[1] * aim[1]);
@ -1039,7 +1047,8 @@ qboolean AimGrenade (edict_t *self, vec3_t start, vec3_t target, vec_t speed, ve
tr.endpos[0] += aim[0]; tr.endpos[0] += aim[0];
tr.endpos[1] += aim[1]; tr.endpos[1] += aim[1];
contents = gi.pointcontents(tr.endpos); contents = gi.pointcontents(tr.endpos);
while((contents & MASK_SOLID) && (aim_point[2] > target[2])) { while ((contents & MASK_SOLID) && (aim_point[2] > target[2]))
{
aim_point[2] -= 8.0; aim_point[2] -= 8.0;
VectorSubtract (aim_point, self->s.origin, from_origin); VectorSubtract (aim_point, self->s.origin, from_origin);
VectorCopy (from_origin, aim); VectorCopy (from_origin, aim);
@ -1052,7 +1061,8 @@ qboolean AimGrenade (edict_t *self, vec3_t start, vec3_t target, vec_t speed, ve
VectorSubtract (aim_point, start, from_muzzle); VectorSubtract (aim_point, start, from_muzzle);
} }
tr = gi.trace(start, vec3_origin, vec3_origin, aim_point, self,MASK_SOLID); tr = gi.trace(start, vec3_origin, vec3_origin, aim_point, self,MASK_SOLID);
if(tr.fraction < 1.0) { if (tr.fraction < 1.0)
{
cosa = sqrt(aim[0] * aim[0] + aim[1] * aim[1]); cosa = sqrt(aim[0] * aim[0] + aim[1] * aim[1]);
vx = speed * cosa; vx = speed * cosa;
VectorSubtract (tr.endpos, start, dist); VectorSubtract (tr.endpos, start, dist);

View file

@ -420,5 +420,7 @@ ENTITY_TARGET_Q1_TRAPSHOOTER,
ENTITY_MISC_Q1_EXPLOBOX, ENTITY_MISC_Q1_EXPLOBOX,
ENTITY_Q1_FIREBALL, ENTITY_Q1_FIREBALL,
ENTITY_MISC_Q1_FIREBALL_SPAWNER, ENTITY_MISC_Q1_FIREBALL_SPAWNER,
ENTITY_MONSTER_Q1_FREDDIE ENTITY_MONSTER_Q1_FREDDIE,
// New stuff
ENTITY_MONSTER_GUNNER_COMMANDER
} entity_id; } entity_id;

View file

@ -487,6 +487,11 @@ void GunnerFire (edict_t *self)
if (!self->enemy || !self->enemy->inuse) //PGM if (!self->enemy || !self->enemy->inuse) //PGM
return; //PGM return; //PGM
#ifdef KMQUAKE2_ENGINE_MOD // Knightmare- unique muzzle flash for gunner commander's flechettes
if (self->moreflags & FL2_COMMANDER)
flash_number = MZ2_GUNNER_ETF_RIFLE_1 + (self->s.frame - FRAME_attak216);
else
#endif // KMQUAKE2_ENGINE_MOD
flash_number = MZ2_GUNNER_MACHINEGUN_1 + (self->s.frame - FRAME_attak216); flash_number = MZ2_GUNNER_MACHINEGUN_1 + (self->s.frame - FRAME_attak216);
AngleVectors (self->s.angles, forward, right, NULL); AngleVectors (self->s.angles, forward, right, NULL);
@ -494,7 +499,10 @@ void GunnerFire (edict_t *self)
// project enemy back a bit and target there // project enemy back a bit and target there
VectorCopy (self->enemy->s.origin, target); VectorCopy (self->enemy->s.origin, target);
if ( !(self->moreflags & FL2_COMMANDER) )
{ // Commander fires projectiles, so no backward projection
VectorMA (target, -0.2, self->enemy->velocity, target); VectorMA (target, -0.2, self->enemy->velocity, target);
}
target[2] += self->enemy->viewheight; target[2] += self->enemy->viewheight;
// Lazarus fog reduction of accuracy // Lazarus fog reduction of accuracy
@ -507,6 +515,11 @@ void GunnerFire (edict_t *self)
VectorSubtract (target, start, aim); VectorSubtract (target, start, aim);
VectorNormalize (aim); VectorNormalize (aim);
// Knightmare- gunner commander fires flechettes
if (self->moreflags & FL2_COMMANDER)
monster_fire_flechette (self, start, aim, 5, 850, 75, 10, flash_number);
else
monster_fire_bullet (self, start, aim, 3, 4, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, flash_number); monster_fire_bullet (self, start, aim, 3, 4, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, flash_number);
} }
@ -521,10 +534,11 @@ void GunnerGrenade (edict_t *self)
// float pitch; // float pitch;
// PMM // PMM
vec3_t target; vec3_t target;
qboolean blindfire; qboolean blindfire = false;
if (!self->enemy || !self->enemy->inuse) //PGM //PGM
return; //PGM if (!self->enemy || !self->enemy->inuse)
return;
// pmm // pmm
if (self->monsterinfo.aiflags & AI_MANUAL_STEERING) if (self->monsterinfo.aiflags & AI_MANUAL_STEERING)
@ -580,9 +594,26 @@ void GunnerGrenade (edict_t *self)
VectorSubtract(target, self->s.origin, aim); VectorSubtract(target, self->s.origin, aim);
dist = VectorLength(aim); dist = VectorLength(aim);
// aim at enemy's feet if he's at same elevation or lower. otherwise aim at origin // aim at enemy's feet if he's at same elevation or lower, otherwise aim at origin
VectorCopy (self->enemy->s.origin, target); 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];
// Knightmare- spread out Commander's prox mines so they don't collide
if (self->moreflags & FL2_COMMANDER)
{
if ( blindfire )
{
target[0] += crandom() * 192;
target[1] += crandom() * 192;
target[2] += crandom() * 192;
}
else
{
target[0] += crandom() * 32;
target[1] += crandom() * 32;
}
}
// Lazarus fog reduction of accuracy // Lazarus fog reduction of accuracy
if ( self->monsterinfo.visibility < FOG_CANSEEGOOD ) if ( self->monsterinfo.visibility < FOG_CANSEEGOOD )
@ -637,6 +668,13 @@ void GunnerGrenade (edict_t *self)
// VectorMA (forward, spread, right, aim); // VectorMA (forward, spread, right, aim);
// VectorMA (aim, pitch, up, aim); // VectorMA (aim, pitch, up, aim);
// Knightmare- Gunner Commander fires prox mines
if (self->moreflags & FL2_COMMANDER)
{
float prox_timer = (blindfire) ? 60.0f : 2.5f;
monster_fire_prox (self, start, aim, 65, 1, 600, 20, prox_timer, 192, flash_number);
}
else
monster_fire_grenade (self, start, aim, 50, 600, flash_number); monster_fire_grenade (self, start, aim, 50, 600, flash_number);
} }
@ -1069,6 +1107,8 @@ void gunner_sidestep (edict_t *self)
/*QUAKED monster_gunner (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight GoodGuy NoGib /*QUAKED monster_gunner (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight GoodGuy NoGib
*/ */
/*QUAKED monster_gunner_commander (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight GoodGuy NoGib
*/
void SP_monster_gunner (edict_t *self) void SP_monster_gunner (edict_t *self)
{ {
if (deathmatch->value) if (deathmatch->value)
@ -1085,17 +1125,22 @@ void SP_monster_gunner (edict_t *self)
sound_search = gi.soundindex ("gunner/gunsrch1.wav"); sound_search = gi.soundindex ("gunner/gunsrch1.wav");
sound_sight = gi.soundindex ("gunner/sight1.wav"); sound_sight = gi.soundindex ("gunner/sight1.wav");
gi.soundindex ("gunner/gunatck2.wav"); // gi.soundindex ("gunner/gunatck2.wav"); // not used by Gunner Commander
gi.soundindex ("gunner/gunatck3.wav"); gi.soundindex ("gunner/gunatck3.wav");
self->movetype = MOVETYPE_STEP; self->movetype = MOVETYPE_STEP;
self->solid = SOLID_BBOX; self->solid = SOLID_BBOX;
// Lazarus: special purpose skins // Lazarus: special purpose skins
if (strcmp(self->classname, "monster_gunner_commander") == 0)
{
self->s.skinnum = 2;
self->moreflags |= FL2_COMMANDER;
}
if ( self->style ) if ( self->style )
{ {
PatchMonsterModel("models/monsters/gunner/tris.md2"); PatchMonsterModel("models/monsters/gunner/tris.md2");
self->s.skinnum = self->style * 2; self->s.skinnum += self->style * 4;
} }
self->s.modelindex = gi.modelindex ("models/monsters/gunner/tris.md2"); self->s.modelindex = gi.modelindex ("models/monsters/gunner/tris.md2");
@ -1109,6 +1154,30 @@ void SP_monster_gunner (edict_t *self)
VectorSet (self->mins, -16, -16, -24); VectorSet (self->mins, -16, -16, -24);
VectorSet (self->maxs, 16, 16, 32); VectorSet (self->maxs, 16, 16, 32);
if (strcmp(self->classname, "monster_gunner_commander") == 0)
{ // precache
gi.modelindex ("models/weapons/g_prox/tris.md2");
gi.modelindex ("models/proj/flechette/tris.md2");
gi.soundindex ("weapons/nail1.wav");
if (!self->health)
self->health = 400;
if (!self->gib_health)
self->gib_health = -150;
if (!self->mass)
self->mass = 300;
self->monsterinfo.power_armor_type = POWER_ARMOR_SHIELD;
self->monsterinfo.power_armor_power = 200;
self->common_name = "Gunner Commander";
self->class_id = ENTITY_MONSTER_GUNNER_COMMANDER;
}
else
{ // precache
gi.modelindex ("models/objects/grenade/tris.md2");
gi.soundindex ("gunner/gunatck2.wav");
if (!self->health) if (!self->health)
self->health = 175; self->health = 175;
if (!self->gib_health) if (!self->gib_health)
@ -1116,6 +1185,10 @@ void SP_monster_gunner (edict_t *self)
if (!self->mass) if (!self->mass)
self->mass = 200; self->mass = 200;
self->common_name = "Gunner";
self->class_id = ENTITY_MONSTER_GUNNER;
}
self->pain = gunner_pain; self->pain = gunner_pain;
self->die = gunner_die; self->die = gunner_die;
@ -1147,11 +1220,11 @@ void SP_monster_gunner (edict_t *self)
self->monsterinfo.power_armor_type = POWER_ARMOR_SHIELD; self->monsterinfo.power_armor_type = POWER_ARMOR_SHIELD;
self->monsterinfo.power_armor_power = self->powerarmor; self->monsterinfo.power_armor_power = self->powerarmor;
} }
if (!self->monsterinfo.flies)
self->monsterinfo.flies = 0.30;
self->common_name = "Gunner"; if ( !self->monsterinfo.flies && strcmp(self->classname, "monster_gunner_commander") == 0 )
self->class_id = ENTITY_MONSTER_GUNNER; self->monsterinfo.flies = 0.20;
else if (!self->monsterinfo.flies)
self->monsterinfo.flies = 0.30;
gi.linkentity (self); gi.linkentity (self);

View file

@ -33,7 +33,8 @@ static int daed_sound_search2;
void hover_sight (edict_t *self, edict_t *other) void hover_sight (edict_t *self, edict_t *other)
{ {
// PMM - daedalus sounds // PMM - daedalus sounds
if (strcmp(self->classname, "monster_daedalus")) // if (strcmp(self->classname, "monster_daedalus"))
if ( !(self->moreflags & FL2_COMMANDER) )
gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0); gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
else else
gi.sound (self, CHAN_VOICE, daed_sound_sight, 1, ATTN_NORM, 0); gi.sound (self, CHAN_VOICE, daed_sound_sight, 1, ATTN_NORM, 0);
@ -42,7 +43,8 @@ void hover_sight (edict_t *self, edict_t *other)
void hover_search (edict_t *self) void hover_search (edict_t *self)
{ {
// PMM - daedalus sounds // PMM - daedalus sounds
if (strcmp(self->classname, "monster_daedalus")) // if (strcmp(self->classname, "monster_daedalus"))
if ( !(self->moreflags & FL2_COMMANDER) )
{ {
if (random() < 0.5) if (random() < 0.5)
gi.sound (self, CHAN_VOICE, sound_search1, 1, ATTN_NORM, 0); gi.sound (self, CHAN_VOICE, sound_search1, 1, ATTN_NORM, 0);
@ -510,7 +512,8 @@ void hover_fire_blaster (edict_t *self)
VectorSubtract (end, start, dir); VectorSubtract (end, start, dir);
//PGM - daedalus fires blaster2 //PGM - daedalus fires blaster2
if (strcmp(self->classname, "monster_daedalus") == 0) // if (strcmp(self->classname, "monster_daedalus") == 0)
if (self->moreflags & FL2_COMMANDER)
// monster_fire_blaster (self, start, dir, self->dmg, 1000, MZ2_DAEDALUS_BLASTER, EF_BLASTER|EF_TRACKER, BLASTER_GREEN); // monster_fire_blaster (self, start, dir, self->dmg, 1000, MZ2_DAEDALUS_BLASTER, EF_BLASTER|EF_TRACKER, BLASTER_GREEN);
monster_fire_blaster2 (self, start, dir, self->dmg, 1000, MZ2_DAEDALUS_BLASTER, EF_BLASTER); monster_fire_blaster2 (self, start, dir, self->dmg, 1000, MZ2_DAEDALUS_BLASTER, EF_BLASTER);
// fixme - different muzzle flash // fixme - different muzzle flash
@ -558,7 +561,8 @@ void hover_attack(edict_t *self)
else else
chance = 1.0 - (0.5/(float)(skill->value)); chance = 1.0 - (0.5/(float)(skill->value));
if (strcmp(self->classname, "monster_daedalus") == 0) // if (strcmp(self->classname, "monster_daedalus") == 0)
if (self->moreflags & FL2_COMMANDER)
chance += 0.1; chance += 0.1;
if (random() > chance) if (random() > chance)
@ -600,7 +604,8 @@ void hover_pain (edict_t *self, edict_t *other, float kick, int damage)
if (random() < 0.5) if (random() < 0.5)
{ {
// PMM - daedalus sounds // PMM - daedalus sounds
if (strcmp(self->classname, "monster_daedalus")) // if (strcmp(self->classname, "monster_daedalus"))
if ( !(self->moreflags & FL2_COMMANDER) )
gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0); gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
else else
gi.sound (self, CHAN_VOICE, daed_sound_pain1, 1, ATTN_NORM, 0); gi.sound (self, CHAN_VOICE, daed_sound_pain1, 1, ATTN_NORM, 0);
@ -609,7 +614,8 @@ void hover_pain (edict_t *self, edict_t *other, float kick, int damage)
else else
{ {
// PMM - daedalus sounds // PMM - daedalus sounds
if (strcmp(self->classname, "monster_daedalus")) // if (strcmp(self->classname, "monster_daedalus"))
if ( !(self->moreflags & FL2_COMMANDER) )
gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0); gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
else else
gi.sound (self, CHAN_VOICE, daed_sound_pain2, 1, ATTN_NORM, 0); gi.sound (self, CHAN_VOICE, daed_sound_pain2, 1, ATTN_NORM, 0);
@ -623,7 +629,8 @@ void hover_pain (edict_t *self, edict_t *other, float kick, int damage)
if (random() < (0.45 - (0.1 * skill->value))) if (random() < (0.45 - (0.1 * skill->value)))
{ {
// PMM - daedalus sounds // PMM - daedalus sounds
if (strcmp(self->classname, "monster_daedalus")) // if (strcmp(self->classname, "monster_daedalus"))
if ( !(self->moreflags & FL2_COMMANDER) )
gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0); gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
else else
gi.sound (self, CHAN_VOICE, daed_sound_pain1, 1, ATTN_NORM, 0); gi.sound (self, CHAN_VOICE, daed_sound_pain1, 1, ATTN_NORM, 0);
@ -632,7 +639,8 @@ void hover_pain (edict_t *self, edict_t *other, float kick, int damage)
else else
{ {
// PMM - daedalus sounds // PMM - daedalus sounds
if (strcmp(self->classname, "monster_daedalus")) // if (strcmp(self->classname, "monster_daedalus"))
if ( !(self->moreflags & FL2_COMMANDER) )
gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0); gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
else else
gi.sound (self, CHAN_VOICE, daed_sound_pain2, 1, ATTN_NORM, 0); gi.sound (self, CHAN_VOICE, daed_sound_pain2, 1, ATTN_NORM, 0);
@ -714,7 +722,8 @@ void hover_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage
// regular death // regular death
// PMM - daedalus sounds // PMM - daedalus sounds
if (strcmp(self->classname, "monster_daedalus")) // if (strcmp(self->classname, "monster_daedalus"))
if ( !(self->moreflags & FL2_COMMANDER) )
{ {
if (random() < 0.5) if (random() < 0.5)
gi.sound (self, CHAN_VOICE, sound_death1, 1, ATTN_NORM, 0); gi.sound (self, CHAN_VOICE, sound_death1, 1, ATTN_NORM, 0);
@ -763,7 +772,10 @@ void SP_monster_hover (edict_t *self)
// Lazarus: special purpose skins // Lazarus: special purpose skins
if (strcmp(self->classname, "monster_daedalus") == 0) if (strcmp(self->classname, "monster_daedalus") == 0)
{
self->s.skinnum = 2; self->s.skinnum = 2;
self->moreflags |= FL2_COMMANDER;
}
if ( self->style ) if ( self->style )
{ {
PatchMonsterModel("models/monsters/hover/tris.md2"); PatchMonsterModel("models/monsters/hover/tris.md2");
@ -806,6 +818,7 @@ void SP_monster_hover (edict_t *self)
//PGM //PGM
if (strcmp(self->classname, "monster_daedalus") == 0) if (strcmp(self->classname, "monster_daedalus") == 0)
{ {
// self->s.skinnum = 2;
if (!self->health) if (!self->health)
self->health = 450; self->health = 450;
if (!self->mass) if (!self->mass)
@ -813,8 +826,10 @@ void SP_monster_hover (edict_t *self)
self->yaw_speed = 25; self->yaw_speed = 25;
if (!self->dmg) if (!self->dmg)
self->dmg = 2; self->dmg = 2;
self->monsterinfo.power_armor_type = POWER_ARMOR_SCREEN; self->monsterinfo.power_armor_type = POWER_ARMOR_SCREEN;
self->monsterinfo.power_armor_power = 100; self->monsterinfo.power_armor_power = 100;
// PMM - daedalus sounds // PMM - daedalus sounds
self->s.sound = gi.soundindex ("daedalus/daedidle1.wav"); self->s.sound = gi.soundindex ("daedalus/daedidle1.wav");
daed_sound_pain1 = gi.soundindex ("daedalus/daedpain1.wav"); daed_sound_pain1 = gi.soundindex ("daedalus/daedpain1.wav");
@ -828,7 +843,7 @@ void SP_monster_hover (edict_t *self)
// Knightmare- precache blaster bolt // Knightmare- precache blaster bolt
gi.modelindex ("models/proj/laser2/tris.md2"); gi.modelindex ("models/proj/laser2/tris.md2");
// pmm // pmm
self->common_name = "Daedalus"; // Knightmare self->common_name = "Daedalus"; // Knightmare added
self->class_id = ENTITY_MONSTER_DAEDALUS; self->class_id = ENTITY_MONSTER_DAEDALUS;
} }
else else
@ -849,7 +864,7 @@ void SP_monster_hover (edict_t *self)
gi.soundindex ("hover/hovatck1.wav"); gi.soundindex ("hover/hovatck1.wav");
self->s.sound = gi.soundindex ("hover/hovidle1.wav"); self->s.sound = gi.soundindex ("hover/hovidle1.wav");
self->common_name = "Icarus"; // Knightmare self->common_name = "Icarus"; // Knightmare added
self->class_id = ENTITY_MONSTER_HOVER; self->class_id = ENTITY_MONSTER_HOVER;
} }
//PGM //PGM
@ -870,9 +885,4 @@ void SP_monster_hover (edict_t *self)
self->monsterinfo.scale = MODEL_SCALE; self->monsterinfo.scale = MODEL_SCALE;
flymonster_start (self); flymonster_start (self);
//PGM
// if (strcmp(self->classname, "monster_daedalus") == 0)
// self->s.skinnum = 2;
//PGM
} }

View file

@ -404,7 +404,8 @@ void medic_idle (edict_t *self)
if (!(self->spawnflags & SF_MONSTER_AMBUSH)) if (!(self->spawnflags & SF_MONSTER_AMBUSH))
{ {
// PMM - commander sounds // PMM - commander sounds
if (strcmp(self->classname, "monster_medic_commander")) // if (strcmp(self->classname, "monster_medic_commander"))
if ( !(self->moreflags & FL2_COMMANDER) )
gi.sound (self, CHAN_VOICE, sound_idle1, 1, ATTN_IDLE, 0); gi.sound (self, CHAN_VOICE, sound_idle1, 1, ATTN_IDLE, 0);
else else
gi.sound (self, CHAN_VOICE, commander_sound_idle1, 1, ATTN_IDLE, 0); gi.sound (self, CHAN_VOICE, commander_sound_idle1, 1, ATTN_IDLE, 0);
@ -490,7 +491,8 @@ void medic_search (edict_t *self)
edict_t *ent; edict_t *ent;
// PMM - commander sounds // PMM - commander sounds
if (strcmp(self->classname, "monster_medic_commander")) // if (strcmp(self->classname, "monster_medic_commander"))
if ( !(self->moreflags & FL2_COMMANDER) )
gi.sound (self, CHAN_VOICE, sound_search, 1, ATTN_IDLE, 0); gi.sound (self, CHAN_VOICE, sound_search, 1, ATTN_IDLE, 0);
else else
gi.sound (self, CHAN_VOICE, commander_sound_search, 1, ATTN_IDLE, 0); gi.sound (self, CHAN_VOICE, commander_sound_search, 1, ATTN_IDLE, 0);
@ -512,7 +514,8 @@ void medic_search (edict_t *self)
void medic_sight (edict_t *self, edict_t *other) void medic_sight (edict_t *self, edict_t *other)
{ {
// PMM - commander sounds // PMM - commander sounds
if (strcmp(self->classname, "monster_medic_commander")) // if (strcmp(self->classname, "monster_medic_commander"))
if ( !(self->moreflags & FL2_COMMANDER) )
gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0); gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
else else
gi.sound (self, CHAN_VOICE, commander_sound_sight, 1, ATTN_NORM, 0); gi.sound (self, CHAN_VOICE, commander_sound_sight, 1, ATTN_NORM, 0);
@ -743,7 +746,8 @@ void medic_pain (edict_t *self, edict_t *other, float kick, int damage)
if (self->monsterinfo.aiflags & AI_MEDIC) if (self->monsterinfo.aiflags & AI_MEDIC)
return; return;
if (strcmp(self->classname, "monster_medic_commander") == 0) // if (strcmp(self->classname, "monster_medic_commander") == 0)
if (self->moreflags & FL2_COMMANDER)
{ {
if (damage < 35) if (damage < 35)
{ {
@ -815,7 +819,8 @@ void medic_fire_blaster (edict_t *self)
damage = 3; damage = 3;
// medic commander shoots blaster2 // medic commander shoots blaster2
if (strcmp(self->classname, "monster_medic_commander") == 0) // if (strcmp(self->classname, "monster_medic_commander") == 0)
if (self->moreflags & FL2_COMMANDER)
// monster_fire_blaster (self, start, dir, damage, 1000, MZ2_MEDIC_BLASTER_2, (effect!=0)?(effect|EF_TRACKER):0, BLASTER_GREEN); // monster_fire_blaster (self, start, dir, damage, 1000, MZ2_MEDIC_BLASTER_2, (effect!=0)?(effect|EF_TRACKER):0, BLASTER_GREEN);
monster_fire_blaster2 (self, start, dir, damage, 1000, MZ2_MEDIC_BLASTER_2, effect); monster_fire_blaster2 (self, start, dir, damage, 1000, MZ2_MEDIC_BLASTER_2, effect);
else else
@ -905,7 +910,8 @@ void medic_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage
// regular death // regular death
// PMM // PMM
if (strcmp(self->classname, "monster_medic_commander")) // if (strcmp(self->classname, "monster_medic_commander"))
if ( !(self->moreflags & FL2_COMMANDER) )
gi.sound (self, CHAN_VOICE, sound_die, 1, ATTN_NORM, 0); gi.sound (self, CHAN_VOICE, sound_die, 1, ATTN_NORM, 0);
else else
gi.sound (self, CHAN_VOICE, commander_sound_die, 1, ATTN_NORM, 0); gi.sound (self, CHAN_VOICE, commander_sound_die, 1, ATTN_NORM, 0);
@ -992,7 +998,8 @@ mmove_t medic_move_attackBlaster = {FRAME_attack1, FRAME_attack14, medic_frames_
void medic_hook_launch (edict_t *self) void medic_hook_launch (edict_t *self)
{ {
// PMM - commander sounds // PMM - commander sounds
if (strcmp(self->classname, "monster_medic_commander")) // if (strcmp(self->classname, "monster_medic_commander"))
if ( !(self->moreflags & FL2_COMMANDER) )
gi.sound (self, CHAN_WEAPON, sound_hook_launch, 1, ATTN_NORM, 0); gi.sound (self, CHAN_WEAPON, sound_hook_launch, 1, ATTN_NORM, 0);
else else
gi.sound (self, CHAN_WEAPON, commander_sound_hook_launch, 1, ATTN_NORM, 0); gi.sound (self, CHAN_WEAPON, commander_sound_hook_launch, 1, ATTN_NORM, 0);
@ -1122,7 +1129,8 @@ void medic_cable_attack (edict_t *self)
if (self->s.frame == FRAME_attack43) if (self->s.frame == FRAME_attack43)
{ {
// PMM - commander sounds // PMM - commander sounds
if (strcmp(self->classname, "monster_medic_commander")) // if (strcmp(self->classname, "monster_medic_commander"))
if ( !(self->moreflags & FL2_COMMANDER) )
gi.sound (self->enemy, CHAN_AUTO, sound_hook_hit, 1, ATTN_NORM, 0); gi.sound (self->enemy, CHAN_AUTO, sound_hook_hit, 1, ATTN_NORM, 0);
else else
gi.sound (self->enemy, CHAN_AUTO, commander_sound_hook_hit, 1, ATTN_NORM, 0); gi.sound (self->enemy, CHAN_AUTO, commander_sound_hook_hit, 1, ATTN_NORM, 0);
@ -1265,7 +1273,8 @@ void medic_cable_attack (edict_t *self)
{ {
if (self->s.frame == FRAME_attack44) if (self->s.frame == FRAME_attack44)
// PMM - medic commander sounds // PMM - medic commander sounds
if (strcmp(self->classname, "monster_medic_commander")) // if (strcmp(self->classname, "monster_medic_commander"))
if ( !(self->moreflags & FL2_COMMANDER) )
gi.sound (self, CHAN_WEAPON, sound_hook_heal, 1, ATTN_NORM, 0); gi.sound (self, CHAN_WEAPON, sound_hook_heal, 1, ATTN_NORM, 0);
else else
gi.sound (self, CHAN_WEAPON, commander_sound_hook_heal, 1, ATTN_NORM, 0); gi.sound (self, CHAN_WEAPON, commander_sound_hook_heal, 1, ATTN_NORM, 0);
@ -1291,7 +1300,8 @@ void medic_cable_attack (edict_t *self)
void medic_hook_retract (edict_t *self) void medic_hook_retract (edict_t *self)
{ {
if (strcmp(self->classname, "monster_medic_commander")) // if (strcmp(self->classname, "monster_medic_commander"))
if ( !(self->moreflags & FL2_COMMANDER) )
gi.sound (self, CHAN_WEAPON, sound_hook_retract, 1, ATTN_NORM, 0); gi.sound (self, CHAN_WEAPON, sound_hook_retract, 1, ATTN_NORM, 0);
else else
gi.sound (self, CHAN_WEAPON, sound_hook_retract, 1, ATTN_NORM, 0); gi.sound (self, CHAN_WEAPON, sound_hook_retract, 1, ATTN_NORM, 0);
@ -1667,14 +1677,14 @@ void medic_finish_spawn (edict_t *self)
designated_enemy = PickCoopTarget(ent); designated_enemy = PickCoopTarget(ent);
if (designated_enemy) if (designated_enemy)
{ {
// if ((g_showlogic) && (g_showlogic->value)) /* if ((g_showlogic) && (g_showlogic->value))
// { {
// gi.dprintf ("PickCoopTarget returned a %s - ", designated_enemy->classname); gi.dprintf ("PickCoopTarget returned a %s - ", designated_enemy->classname);
// if (designated_enemy->client) if (designated_enemy->client)
// gi.dprintf ("with name %s\n", designated_enemy->client->pers.netname); gi.dprintf ("with name %s\n", designated_enemy->client->pers.netname);
// else else
// gi.dprintf ("NOT A CLIENT\n"); gi.dprintf ("NOT A CLIENT\n");
// } } */
} }
else else
{ {
@ -1762,7 +1772,8 @@ void medic_attack(edict_t *self)
r = random(); r = random();
if (self->monsterinfo.aiflags & AI_MEDIC) if (self->monsterinfo.aiflags & AI_MEDIC)
{ {
if ((strcmp(self->classname, "monster_medic_commander") == 0) && (r > 0.8) && (self->monsterinfo.monster_slots > 2)) // if ((strcmp(self->classname, "monster_medic_commander") == 0) && (r > 0.8) && (self->monsterinfo.monster_slots > 2))
if ((self->moreflags & FL2_COMMANDER) && (r > 0.8) && (self->monsterinfo.monster_slots > 2))
self->monsterinfo.currentmove = &medic_move_callReinforcements; self->monsterinfo.currentmove = &medic_move_callReinforcements;
else else
self->monsterinfo.currentmove = &medic_move_attackCable; self->monsterinfo.currentmove = &medic_move_attackCable;
@ -1774,7 +1785,8 @@ void medic_attack(edict_t *self)
self->monsterinfo.currentmove = &medic_move_callReinforcements; self->monsterinfo.currentmove = &medic_move_callReinforcements;
return; return;
} }
if ((strcmp(self->classname, "monster_medic_commander") == 0) && (r > 0.2) && (enemy_range != RANGE_MELEE) && (self->monsterinfo.monster_slots > 2)) // if ((strcmp(self->classname, "monster_medic_commander") == 0) && (r > 0.2) && (enemy_range != RANGE_MELEE) && (self->monsterinfo.monster_slots > 2))
if ((self->moreflags & FL2_COMMANDER) && (r > 0.2) && (enemy_range != RANGE_MELEE) && (self->monsterinfo.monster_slots > 2))
self->monsterinfo.currentmove = &medic_move_callReinforcements; self->monsterinfo.currentmove = &medic_move_callReinforcements;
else else
self->monsterinfo.currentmove = &medic_move_attackBlaster; self->monsterinfo.currentmove = &medic_move_attackBlaster;
@ -2050,7 +2062,10 @@ void SP_monster_medic (edict_t *self)
// Lazarus: special purpose skins // Lazarus: special purpose skins
if (strcmp(self->classname, "monster_medic_commander") == 0) if (strcmp(self->classname, "monster_medic_commander") == 0)
{
self->s.skinnum = 2; self->s.skinnum = 2;
self->moreflags |= FL2_COMMANDER;
}
if ( self->style ) if ( self->style )
{ {
PatchMonsterModel("models/monsters/medic/tris.md2"); PatchMonsterModel("models/monsters/medic/tris.md2");
@ -2121,6 +2136,7 @@ void SP_monster_medic (edict_t *self)
self->monsterinfo.power_armor_type = POWER_ARMOR_SHIELD; self->monsterinfo.power_armor_type = POWER_ARMOR_SHIELD;
self->monsterinfo.power_armor_power = self->powerarmor; self->monsterinfo.power_armor_power = self->powerarmor;
} }
if ( !self->monsterinfo.flies && strcmp(self->classname, "monster_medic_commander") == 0 ) if ( !self->monsterinfo.flies && strcmp(self->classname, "monster_medic_commander") == 0 )
self->monsterinfo.flies = 0.10; self->monsterinfo.flies = 0.10;
else if (!self->monsterinfo.flies) else if (!self->monsterinfo.flies)

View file

@ -1028,7 +1028,10 @@ void SP_monster_tank (edict_t *self)
// Lazarus: special purpose skins // Lazarus: special purpose skins
if (strcmp(self->classname, "monster_tank_commander") == 0) if (strcmp(self->classname, "monster_tank_commander") == 0)
{
self->s.skinnum = 2; self->s.skinnum = 2;
self->moreflags |= FL2_COMMANDER;
}
if ( self->style ) if ( self->style )
{ {
PatchMonsterModel("models/monsters/tank/tris.md2"); PatchMonsterModel("models/monsters/tank/tris.md2");
@ -1058,7 +1061,8 @@ void SP_monster_tank (edict_t *self)
gi.soundindex ("tank/tnkatk2e.wav"); gi.soundindex ("tank/tnkatk2e.wav");
gi.soundindex ("tank/tnkatck3.wav"); gi.soundindex ("tank/tnkatck3.wav");
if (strcmp(self->classname, "monster_tank_commander") == 0) // if (strcmp(self->classname, "monster_tank_commander") == 0)
if (self->moreflags & FL2_COMMANDER)
{ {
if (!self->health) if (!self->health)
self->health = 1000; self->health = 1000;

View file

@ -695,7 +695,8 @@ void ClientObituary (edict_t *self, edict_t *inflictor, edict_t *attacker)
message = "was pumped full of lead by an"; message = "was pumped full of lead by an";
} }
// Gunner // Gunner
else if (!strcmp(attacker->classname, "monster_gunner")) else if (!strcmp(attacker->classname, "monster_gunner")
|| !strcmp(attacker->classname, "monster_gunner_commander") )
{ {
if (mod == MOD_GRENADE) { if (mod == MOD_GRENADE) {
message = "was popped by a"; message = "was popped by a";
@ -705,6 +706,17 @@ void ClientObituary (edict_t *self, edict_t *inflictor, edict_t *attacker)
message = "was shredded by a"; message = "was shredded by a";
message2 = "'s shrapnel"; message2 = "'s shrapnel";
} }
else if (mod == MOD_PROX) {
message = "got too close to a";
message2 = "'s proximity mine";
}
else if (mod == MOD_ETF_RIFLE) {
message = "was perforated by a";
}
else if (mod == MOD_ETF_SPLASH) {
message = "was torn up by a";
message2 = "'s explosive flechettes";
}
else else
message = "was machinegunned by a"; message = "was machinegunned by a";
} }

View file

@ -999,7 +999,7 @@ void weapon_grenade_fire (edict_t *ent, qboolean held)
fire_tesla (ent, start, forward, damage_multiplier, speed); fire_tesla (ent, start, forward, damage_multiplier, speed);
break; break;
default: default:
fire_prox (ent, start, forward, damage_multiplier, speed); fire_prox (ent, start, forward, (int)sk_prox_damage->value, damage_multiplier, speed, (int)sk_prox_health->value, sk_prox_life->value, sk_prox_radius->value);
break; break;
} }
// PGM // PGM
@ -1373,10 +1373,10 @@ void weapon_grenadelauncher_fire (edict_t *ent, qboolean altfire)
switch (ent->client->pers.weapon->tag) switch (ent->client->pers.weapon->tag)
{ {
case AMMO_PROX: case AMMO_PROX:
fire_prox (ent, start, forward, multiplier, sk_prox_speed->value); //was damage_multiplier fire_prox (ent, start, forward, damage, multiplier, (int)sk_prox_speed->value, (int)sk_prox_health->value, sk_prox_life->value, sk_prox_radius->value);
break; break;
default: default:
fire_grenade (ent, start, forward, damage, sk_grenade_speed->value, 2.5, radius, altfire); fire_grenade (ent, start, forward, damage, (int)sk_grenade_speed->value, 2.5, radius, altfire);
break; break;
} }
// PGM // PGM