A long overdue update...

- Fixed Alien Grunt's hornets being silent.
- Fixed many, many, many, many ... many GSR crashes.
- Fixed voltigore's beams not being cleared upon gibbing/removal.
- Prepare for T4 release.
This commit is contained in:
Giegue
2023-09-12 13:51:25 -03:00
parent 12f8eea011
commit 272482c5e7
14 changed files with 74 additions and 50 deletions

View File

@@ -87,6 +87,13 @@ const char *CMAGrunt::pAttackSounds[] =
"agrunt/ag_attack3.wav", "agrunt/ag_attack3.wav",
}; };
const char *CMAGrunt::pFireSounds[] =
{
"agrunt/ag_fire1.wav",
"agrunt/ag_fire2.wav",
"agrunt/ag_fire3.wav",
};
const char *CMAGrunt::pDieSounds[] = const char *CMAGrunt::pDieSounds[] =
{ {
"agrunt/ag_die1.wav", "agrunt/ag_die1.wav",
@@ -413,6 +420,8 @@ void CMAGrunt :: HandleAnimEvent( MonsterEvent_t *pEvent )
UTIL_MakeVectors ( pHornet->pev->angles ); UTIL_MakeVectors ( pHornet->pev->angles );
pHornet->pev->velocity = gpGlobals->v_forward * 300; pHornet->pev->velocity = gpGlobals->v_forward * 300;
EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, pFireSounds[RANDOM_LONG(0, ARRAYSIZE(pFireSounds) - 1)], 1.0, ATTN_NORM, 0, 100);
CMBaseMonster *pHornetMonster = pHornet->MyMonsterPointer(); CMBaseMonster *pHornetMonster = pHornet->MyMonsterPointer();
if ( pHornetMonster ) if ( pHornetMonster )

View File

@@ -734,6 +734,7 @@ public:
static const char *pAttackHitSounds[]; static const char *pAttackHitSounds[];
static const char *pAttackMissSounds[]; static const char *pAttackMissSounds[];
static const char *pAttackSounds[]; static const char *pAttackSounds[];
static const char *pFireSounds[];
static const char *pDieSounds[]; static const char *pDieSounds[];
static const char *pPainSounds[]; static const char *pPainSounds[];
static const char *pIdleSounds[]; static const char *pIdleSounds[];
@@ -1381,6 +1382,8 @@ public:
void EXPORT SpikeTouch(edict_t *pOther); void EXPORT SpikeTouch(edict_t *pOther);
void EXPORT StartTrail(); void EXPORT StartTrail();
static edict_t *Shoot(entvars_t *pevOwner, Vector vecStart, Vector vecVelocity, Vector vecAngles); static edict_t *Shoot(entvars_t *pevOwner, Vector vecStart, Vector vecVelocity, Vector vecAngles);
EHANDLE m_hOwner;
}; };
//========================================================= //=========================================================
@@ -1557,6 +1560,7 @@ public:
Schedule_t *GetScheduleOfType(int Type); Schedule_t *GetScheduleOfType(int Type);
virtual int TakeDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType); virtual int TakeDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType);
virtual void Killed(entvars_t *pevAttacker, int iGib); virtual void Killed(entvars_t *pevAttacker, int iGib);
void UpdateOnRemove();
CUSTOM_SCHEDULES CUSTOM_SCHEDULES

View File

@@ -211,11 +211,6 @@ int GetMonsterIndex(void)
void FreeMonsterIndex(int index) void FreeMonsterIndex(int index)
{ {
/*
if (monsters[index].pMonster->m_srSoundList != NULL)
free(monsters[index].pMonster->m_srSoundList);
monsters[index].pMonster->m_srSoundList = NULL;
*/
delete monsters[index].pMonster; delete monsters[index].pMonster;
monsters[index].monster_index = 0; monsters[index].monster_index = 0;
@@ -261,11 +256,6 @@ void monster_unload(void)
{ {
monsters[index].monster_pent->v.flags |= FL_KILLME; monsters[index].monster_pent->v.flags |= FL_KILLME;
/*
if (monsters[index].pMonster->m_srSoundList != NULL)
free(monsters[index].pMonster->m_srSoundList);
monsters[index].pMonster->m_srSoundList = NULL;
*/
delete monsters[index].pMonster; delete monsters[index].pMonster;
monsters[index].monster_index = 0; monsters[index].monster_index = 0;
@@ -1268,14 +1258,7 @@ int mmDispatchSpawn( edict_t *pent )
for (index = 0; index < MAX_MONSTER_ENTS; index++) for (index = 0; index < MAX_MONSTER_ENTS; index++)
{ {
if (monsters[index].pMonster != NULL) if (monsters[index].pMonster != NULL)
{
// free the soundlists first!
/*if (monsters[index].pMonster->m_srSoundList != NULL)
free(monsters[index].pMonster->m_srSoundList);
monsters[index].pMonster->m_srSoundList = NULL;
*/
delete monsters[index].pMonster; delete monsters[index].pMonster;
}
} }
// free any allocated keyvalue memory // free any allocated keyvalue memory

View File

@@ -48,6 +48,10 @@ void CMGrenade::Explode( Vector vecSrc, Vector vecAim )
// UNDONE: temporary scorching for PreAlpha - find a less sleazy permenant solution. // UNDONE: temporary scorching for PreAlpha - find a less sleazy permenant solution.
void CMGrenade::Explode( TraceResult *pTrace, int bitsDamageType ) void CMGrenade::Explode( TraceResult *pTrace, int bitsDamageType )
{ {
// CRITICAL - always ensure owner of grenade is valid
if (m_hOwner == NULL)
pev->owner = NULL;
float flRndSound;// sound randomizer float flRndSound;// sound randomizer
pev->model = iStringNull;//invisible pev->model = iStringNull;//invisible
@@ -309,6 +313,10 @@ void CMGrenade::SlideTouch( edict_t *pOther )
void CMGrenade :: BounceSound( void ) void CMGrenade :: BounceSound( void )
{ {
// CRITICAL - always ensure owner of grenade is valid
if (m_hOwner == NULL)
pev->owner = NULL;
switch ( RANDOM_LONG( 0, 2 ) ) switch ( RANDOM_LONG( 0, 2 ) )
{ {
case 0: EMIT_SOUND(ENT(pev), CHAN_VOICE, "weapons/grenade_hit1.wav", 0.25, ATTN_NORM); break; case 0: EMIT_SOUND(ENT(pev), CHAN_VOICE, "weapons/grenade_hit1.wav", 0.25, ATTN_NORM); break;
@@ -369,7 +377,8 @@ CMGrenade *CMGrenade::ShootContact( entvars_t *pevOwner, Vector vecStart, Vector
pGrenade->pev->velocity = vecVelocity; pGrenade->pev->velocity = vecVelocity;
pGrenade->pev->angles = UTIL_VecToAngles (pGrenade->pev->velocity); pGrenade->pev->angles = UTIL_VecToAngles (pGrenade->pev->velocity);
pGrenade->pev->owner = ENT(pevOwner); pGrenade->pev->owner = ENT(pevOwner);
pGrenade->m_hOwner = ENT(pevOwner);
// make monsters afaid of it while in the air // make monsters afaid of it while in the air
pGrenade->SetThink( &CMGrenade::DangerSoundThink ); pGrenade->SetThink( &CMGrenade::DangerSoundThink );
pGrenade->pev->nextthink = gpGlobals->time; pGrenade->pev->nextthink = gpGlobals->time;
@@ -398,7 +407,8 @@ CMGrenade * CMGrenade:: ShootTimed( entvars_t *pevOwner, Vector vecStart, Vector
pGrenade->pev->velocity = vecVelocity; pGrenade->pev->velocity = vecVelocity;
pGrenade->pev->angles = UTIL_VecToAngles(pGrenade->pev->velocity); pGrenade->pev->angles = UTIL_VecToAngles(pGrenade->pev->velocity);
pGrenade->pev->owner = ENT(pevOwner); pGrenade->pev->owner = ENT(pevOwner);
pGrenade->m_hOwner = ENT(pevOwner);
pGrenade->SetTouch( &CMGrenade::BounceTouch ); // Bounce if touched pGrenade->SetTouch( &CMGrenade::BounceTouch ); // Bounce if touched
// Take one second off of the desired detonation time and set the think to PreDetonate. PreDetonate // Take one second off of the desired detonation time and set the think to PreDetonate. PreDetonate
@@ -451,7 +461,8 @@ CMGrenade * CMGrenade :: ShootSatchelCharge( entvars_t *pevOwner, Vector vecStar
pGrenade->pev->velocity = vecVelocity; pGrenade->pev->velocity = vecVelocity;
pGrenade->pev->angles = g_vecZero; pGrenade->pev->angles = g_vecZero;
pGrenade->pev->owner = ENT(pevOwner); pGrenade->pev->owner = ENT(pevOwner);
pGrenade->m_hOwner = ENT(pevOwner);
// Detonate in "time" seconds // Detonate in "time" seconds
pGrenade->SetThink( &CMGrenade::SUB_DoNothing ); pGrenade->SetThink( &CMGrenade::SUB_DoNothing );
pGrenade->SetUse( &CMGrenade::DetonateUse ); pGrenade->SetUse( &CMGrenade::DetonateUse );

View File

@@ -123,19 +123,19 @@ const char* FindSoundReplacement( edict_t *pMonster, const char *from )
if (UTIL_IsValidEntity(pMonster)) if (UTIL_IsValidEntity(pMonster))
{ {
CMBaseMonster *castMonster = NULL; CMBaseMonster *castMonster = NULL;
// Check if this is really a monster or not // Check if this is really a monster or not
if (pMonster->v.flags & FL_MONSTER) if (pMonster->v.flags & FL_MONSTER)
castMonster = GetClassPtr((CMBaseMonster *)VARS(pMonster)); castMonster = GetClassPtr((CMBaseMonster *)VARS(pMonster));
else else
{ {
// This is probably a monster-owned projectile of sorts // This is probably a monster-owned projectile of sorts
if (!FNullEnt(pMonster->v.owner)) if (UTIL_IsValidEntity(pMonster->v.owner))
castMonster = GetClassPtr((CMBaseMonster *)VARS(pMonster->v.owner)); castMonster = GetClassPtr((CMBaseMonster *)VARS(pMonster->v.owner));
} }
// If still no valid BaseMonster pointer, full stop, use GSR. // If still no valid BaseMonster pointer, full stop, use GSR.
if (castMonster && castMonster->m_isrSounds) if (castMonster != NULL && castMonster->m_srSoundList != NULL && castMonster->m_isrSounds > 0)
{ {
for (int sound = 0; sound < castMonster->m_isrSounds; sound++) for (int sound = 0; sound < castMonster->m_isrSounds; sound++)
{ {
@@ -145,7 +145,6 @@ const char* FindSoundReplacement( edict_t *pMonster, const char *from )
return castMonster->m_srSoundList[sound].destination; return castMonster->m_srSoundList[sound].destination;
} }
} }
// If nothing is found stick to GSR if available // If nothing is found stick to GSR if available
} }
} }

View File

@@ -126,23 +126,14 @@ int CMHornet::IRelationship ( CMBaseEntity *pTarget )
//========================================================= //=========================================================
int CMHornet::Classify ( void ) int CMHornet::Classify ( void )
{ {
/*
if ( pev->owner && pev->owner->v.flags & FL_CLIENT)
{
return CLASS_PLAYER_BIOWEAPON;
}
return CLASS_ALIEN_BIOWEAPON;
*/
// Ensure classify is consistent with the owner, in the event // Ensure classify is consistent with the owner, in the event
// it's classification was overriden. // it's classification was overriden.
if ( pev->owner == NULL ) if (UTIL_IsValidEntity(pev->owner))
return CLASS_ALIEN_BIOWEAPON; {
CMBaseMonster *pOwner = GetClassPtr((CMBaseMonster *)VARS(pev->owner));
// Ain't this going to make the hornets code "slow"? return pOwner->Classify();
CMBaseMonster *pOwner = GetClassPtr((CMBaseMonster *)VARS(pev->owner)); }
return pOwner->Classify(); return CLASS_ALIEN_BIOWEAPON;
} }
//========================================================= //=========================================================

View File

@@ -56,8 +56,8 @@ static META_FUNCTIONS gMetaFunctionTable =
plugin_info_t Plugin_info = { plugin_info_t Plugin_info = {
META_INTERFACE_VERSION, // interface version META_INTERFACE_VERSION, // interface version
"MonsterMod", // name "MonsterMod", // name
"3.0", // version "4.0", // version
"24/02/2023", // date in DD/MM/YYYY format "14/07/2023", // date in DD/MM/YYYY format
"botman, Rick90, Giegue", // original authors + recreation by... "botman, Rick90, Giegue", // original authors + recreation by...
"https://github.com/JulianR0/monstermod-redo", // url "https://github.com/JulianR0/monstermod-redo", // url
"MONSTER", // logtag "MONSTER", // logtag

View File

@@ -74,8 +74,12 @@ void scan_monster_sound(FILE *fp, edict_t *pMonster )
while (get_input(fp, input)) while (get_input(fp, input))
{ {
char *source = strtok(input, " "); // might slip through
char *destination = strtok(NULL, " "); if (strlen(input) == 0)
continue;
char *source = strtok(input, " \t");
char *destination = strtok(NULL, " \t");
// Remove all quotes // Remove all quotes
char parse[128] = {0}; char parse[128] = {0};
@@ -894,8 +898,8 @@ void scan_monster_replace(FILE *fp, bool toGSR )
if (strlen(input) == 0) if (strlen(input) == 0)
continue; continue;
char *source = strtok(input, " "); char *source = strtok(input, " \t");
char *destination = strtok(NULL, " "); char *destination = strtok(NULL, " \t");
// Remove all quotes // Remove all quotes
char parse[128] = {0}; char parse[128] = {0};

View File

@@ -30,7 +30,7 @@ typedef struct
CMBaseMonster *pMonster; CMBaseMonster *pMonster;
} monster_t; } monster_t;
#define MAX_MONSTER_ENTS 400 // increased from 200 so it can hold non-monster entities #define MAX_MONSTER_ENTS 400
extern monster_t monsters[MAX_MONSTER_ENTS]; extern monster_t monsters[MAX_MONSTER_ENTS];
@@ -43,7 +43,7 @@ typedef struct {
bool need_to_respawn; bool need_to_respawn;
} monster_spawnpoint_t; } monster_spawnpoint_t;
#define MAX_MONSTERS 100 #define MAX_MONSTERS 200
extern monster_spawnpoint_t monster_spawnpoint[MAX_MONSTERS]; extern monster_spawnpoint_t monster_spawnpoint[MAX_MONSTERS];
// this is here to store if a node we want to spawn is an ordinary one, or a flying one // this is here to store if a node we want to spawn is an ordinary one, or a flying one

View File

@@ -172,7 +172,7 @@ void CMBaseMonster :: Look ( int iDistance )
{ {
/* MonsterMod monster looking at another MonsterMod monster */ /* MonsterMod monster looking at another MonsterMod monster */
CMBaseMonster *pMonster = GetClassPtr((CMBaseMonster *)VARS(pSightEnt)); CMBaseMonster *pMonster = GetClassPtr((CMBaseMonster *)VARS(pSightEnt));
// the looker will want to consider this entity // the looker will want to consider this entity
// don't check anything else about an entity that can't be seen, or an entity that you don't care about. // don't check anything else about an entity that can't be seen, or an entity that you don't care about.
if ( IRelationship( pMonster ) != R_NO && UTIL_FInViewCone( pSightEnt, ENT(pev), m_flFieldOfView ) && !FBitSet( pSightEnt->v.flags, FL_NOTARGET ) && UTIL_FVisible( pSightEnt, ENT(pev) ) ) if ( IRelationship( pMonster ) != R_NO && UTIL_FInViewCone( pSightEnt, ENT(pev), m_flFieldOfView ) && !FBitSet( pSightEnt->v.flags, FL_NOTARGET ) && UTIL_FVisible( pSightEnt, ENT(pev) ) )

View File

@@ -60,6 +60,9 @@ void CPitdroneSpike::Spawn(void)
void CPitdroneSpike::SpikeTouch(edict_t *pOther) void CPitdroneSpike::SpikeTouch(edict_t *pOther)
{ {
if (m_hOwner == NULL)
pev->owner = NULL;
int iPitch; int iPitch;
// splat sound // splat sound
@@ -89,7 +92,9 @@ void CPitdroneSpike::SpikeTouch(edict_t *pOther)
else else
{ {
entvars_t *pevOwner = VARS(pev->owner); entvars_t *pevOwner = VARS(pev->owner);
if (pevOwner == NULL)
pevOwner = pev;
if ( UTIL_IsPlayer( pOther ) ) if ( UTIL_IsPlayer( pOther ) )
UTIL_TakeDamage( pOther, pev, pevOwner, gSkillData.pitdroneDmgSpit, DMG_GENERIC | DMG_NEVERGIB ); UTIL_TakeDamage( pOther, pev, pevOwner, gSkillData.pitdroneDmgSpit, DMG_GENERIC | DMG_NEVERGIB );
else if ( pOther->v.euser4 != NULL ) else if ( pOther->v.euser4 != NULL )
@@ -141,6 +146,7 @@ edict_t *CPitdroneSpike::Shoot(entvars_t *pevOwner, Vector vecStart, Vector vecV
pSpit->pev->velocity = vecVelocity; pSpit->pev->velocity = vecVelocity;
pSpit->pev->angles = vecAngles; pSpit->pev->angles = vecAngles;
pSpit->pev->owner = ENT( pevOwner ); pSpit->pev->owner = ENT( pevOwner );
pSpit->m_hOwner = ENT( pevOwner );
pSpit->SetThink(&CPitdroneSpike::StartTrail); pSpit->SetThink(&CPitdroneSpike::StartTrail);
pSpit->pev->nextthink = gpGlobals->time + 0.1; pSpit->pev->nextthink = gpGlobals->time + 0.1;

View File

@@ -40,6 +40,9 @@ void CMSporeGrenade::Precache()
void CMSporeGrenade::Explode(TraceResult *pTrace) void CMSporeGrenade::Explode(TraceResult *pTrace)
{ {
if (m_hOwner == NULL)
pev->owner = NULL;
pev->solid = SOLID_NOT;// intangible pev->solid = SOLID_NOT;// intangible
pev->takedamage = DAMAGE_NO; pev->takedamage = DAMAGE_NO;
@@ -125,6 +128,9 @@ void CMSporeGrenade::Detonate()
void CMSporeGrenade::BounceSound() void CMSporeGrenade::BounceSound()
{ {
if (m_hOwner == NULL)
pev->owner = NULL;
EMIT_SOUND(ENT(pev), CHAN_VOICE, "weapons/splauncher_bounce.wav", 0.25, ATTN_NORM); EMIT_SOUND(ENT(pev), CHAN_VOICE, "weapons/splauncher_bounce.wav", 0.25, ATTN_NORM);
} }
@@ -252,6 +258,7 @@ CMSporeGrenade* CMSporeGrenade::ShootTimed(entvars_t *pevOwner, Vector vecStart,
pGrenade->pev->velocity = vecVelocity; pGrenade->pev->velocity = vecVelocity;
pGrenade->pev->angles = UTIL_VecToAngles(pGrenade->pev->velocity); pGrenade->pev->angles = UTIL_VecToAngles(pGrenade->pev->velocity);
pGrenade->pev->owner = ENT(pevOwner); pGrenade->pev->owner = ENT(pevOwner);
pGrenade->m_hOwner = ENT(pevOwner);
pGrenade->SetTouch(&CMSporeGrenade::BounceTouch); // Bounce if touched pGrenade->SetTouch(&CMSporeGrenade::BounceTouch); // Bounce if touched
@@ -286,6 +293,7 @@ CMSporeGrenade *CMSporeGrenade::ShootContact(entvars_t *pevOwner, Vector vecStar
pGrenade->pev->velocity = vecVelocity; pGrenade->pev->velocity = vecVelocity;
pGrenade->pev->angles = UTIL_VecToAngles(pGrenade->pev->velocity); pGrenade->pev->angles = UTIL_VecToAngles(pGrenade->pev->velocity);
pGrenade->pev->owner = ENT(pevOwner); pGrenade->pev->owner = ENT(pevOwner);
pGrenade->m_hOwner = ENT(pevOwner);
// make monsters afraid of it while in the air // make monsters afraid of it while in the air
pGrenade->SetThink(&CMSporeGrenade::DangerSoundThink); pGrenade->SetThink(&CMSporeGrenade::DangerSoundThink);

View File

@@ -449,6 +449,13 @@ void CMVoltigore::GibMonster()
pev->nextthink = gpGlobals->time; pev->nextthink = gpGlobals->time;
} }
void CMVoltigore::UpdateOnRemove()
{
CMBaseMonster::UpdateOnRemove();
DestroyBeams();
DestroyGlow();
}
//========================================================= //=========================================================
// CheckMeleeAttack1 - voltigore is a big guy, so has a longer // CheckMeleeAttack1 - voltigore is a big guy, so has a longer
// melee range than most monsters. This is the tailwhip attack // melee range than most monsters. This is the tailwhip attack

View File

@@ -47,6 +47,7 @@ public:
virtual void Killed( entvars_t *pevAttacker, int iGib ); virtual void Killed( entvars_t *pevAttacker, int iGib );
BOOL m_fRegisteredSound;// whether or not this grenade has issued its DANGER sound to the world sound list yet. BOOL m_fRegisteredSound;// whether or not this grenade has issued its DANGER sound to the world sound list yet.
EHANDLE m_hOwner;
}; };
// Contact/Timed spore grenade // Contact/Timed spore grenade
@@ -75,6 +76,7 @@ public:
void UpdateOnRemove(); void UpdateOnRemove();
CMSprite* m_pSporeGlow; CMSprite* m_pSporeGlow;
EHANDLE m_hOwner;
}; };
// constant items // constant items