Fix apache/turrets not triggering their targets on death.

Fix apache not giving score upon kill.
Fix monster trigger target crashing the server.
Add "squadmaker" alias entity.
Added plenty of keyvalues to monstermaker, similar to SC's squadmaker.
This commit is contained in:
Giegue
2023-04-26 01:44:36 -03:00
parent e1e2a48f89
commit 5da691b5fe
8 changed files with 91 additions and 16 deletions

View File

@@ -157,6 +157,11 @@ void CMApache :: Killed( entvars_t *pevAttacker, int iGib )
pev->health = 0;
pev->takedamage = DAMAGE_NO;
pev->deadflag = DEAD_DYING;
FCheckAITrigger(); // trigger death condition
if ( UTIL_IsPlayer( ENT( pevAttacker ) ) ) // If a player killed this monster, add score
pevAttacker->frags += 1.0;
if (pev->spawnflags & SF_NOWRECKAGE)
{
m_flNextRocket = gpGlobals->time + 4.0;

View File

@@ -222,7 +222,7 @@ public:
pent = ENT(0);
if ( pent->v.euser4 == NULL )
return (CMBaseEntity *)NULL;
CMBaseEntity *pEnt = GetClassPtr((CMBaseEntity *)VARS(pent));
CMBaseEntity *pEnt = GetClassPtr((CMBaseEntity *)VARS(pent));
return pEnt;
}

View File

@@ -163,6 +163,7 @@ monster_type_t monster_types[]=
"info_node_air", FALSE,
"monstermaker", FALSE, // Extra entities
"ambient_music", FALSE,
"squadmaker", FALSE, // Aliases
"", FALSE
};
@@ -1370,7 +1371,7 @@ void mmDispatchUse( void )
if ( FNullEnt( caller ) ) caller = NULL;
if ( FNullEnt( activator ) ) activator = NULL;
monsters[index].pMonster->Use( caller, activator, useType, flValue );
monsters[index].pMonster->Use( activator, caller, useType, flValue );
return;
}
}

View File

@@ -116,7 +116,7 @@ void scan_monster_cfg(FILE *fp)
monster = TRUE;
}
}
else if (strcmp(monster_types[mIndex].name, "monstermaker") == 0)
else if (strcmp(monster_types[mIndex].name, "monstermaker") == 0 || strcmp(monster_types[mIndex].name, "squadmaker") == 0)
{
// A monster spawner, add it to the list
if (monster_spawn_count == MAX_MONSTERS)
@@ -127,8 +127,8 @@ void scan_monster_cfg(FILE *fp)
}
else
{
monster_spawnpoint[monster_spawn_count].monster = mIndex;
monster_types[mIndex].need_to_precache = TRUE;
monster_spawnpoint[monster_spawn_count].monster = 32; // monstermaker index is fixed at 32
monster_types[32].need_to_precache = TRUE;
monster = TRUE;
}
}
@@ -266,7 +266,7 @@ void scan_monster_cfg(FILE *fp)
if (monster)
{
// only applicable for normal monsters
if (strcmp(data[kvd_index-1].value, "monstermaker") != 0)
if (strcmp(data[kvd_index-1].value, "monstermaker") != 0 && strcmp(data[kvd_index-1].value, "squadmaker") != 0)
{
// precache the custom model here
PRECACHE_MODEL( data[i].value );
@@ -282,7 +282,7 @@ void scan_monster_cfg(FILE *fp)
if (monster)
{
// only applicable for monstermaker entity
if (strcmp(data[kvd_index-1].value, "monstermaker") == 0)
if (strcmp(data[kvd_index-1].value, "monstermaker") == 0 || strcmp(data[kvd_index-1].value, "squadmaker") == 0)
{
// precache the custom model
PRECACHE_MODEL( data[i].value );
@@ -298,7 +298,7 @@ void scan_monster_cfg(FILE *fp)
if (monster)
{
// this keyvalue is only valid for monstermaker entity
if (strcmp(data[kvd_index-1].value, "monstermaker") == 0)
if (strcmp(data[kvd_index-1].value, "monstermaker") == 0 || strcmp(data[kvd_index-1].value, "squadmaker") == 0)
{
// process the entity precache here
int mIndex;
@@ -529,6 +529,10 @@ void scan_monster_bsp(void)
}
else
{
// Aliases
if (strcmp(monster_types[mIndex].name, "squadmaker") == 0)
mIndex = 32; // monstermaker
monster_spawnpoint[monster_spawn_count].monster = mIndex;
monster_types[mIndex].need_to_precache = true;
monster = true;
@@ -619,7 +623,7 @@ void scan_monster_bsp(void)
if (monster)
{
// only applicable for normal monsters
if (strcmp(data[classname_kvdI].value, "monstermaker") != 0)
if (strcmp(data[classname_kvdI].value, "monstermaker") != 0 && strcmp(data[classname_kvdI].value, "squadmaker") != 0)
{
// precache the custom model here
PRECACHE_MODEL( data[i].value );
@@ -635,7 +639,7 @@ void scan_monster_bsp(void)
if (monster)
{
// only applicable for monstermaker entity
if (strcmp(data[classname_kvdI].value, "monstermaker") == 0)
if (strcmp(data[classname_kvdI].value, "monstermaker") == 0 || strcmp(data[classname_kvdI].value, "squadmaker") == 0)
{
// precache the custom model
PRECACHE_MODEL( data[i].value );
@@ -651,7 +655,7 @@ void scan_monster_bsp(void)
if (monster)
{
// this keyvalue is only valid for monstermaker entity
if (strcmp(data[classname_kvdI].value, "monstermaker") == 0)
if (strcmp(data[classname_kvdI].value, "monstermaker") == 0 || strcmp(data[classname_kvdI].value, "squadmaker") == 0)
{
// process the entity precache here
for (mIndex = 0; monster_types[mIndex].name[0]; mIndex++)

View File

@@ -70,6 +70,19 @@ void CMMonsterMaker :: KeyValue( KeyValueData *pkvd )
m_iMonsterBlood = atoi(pkvd->szValue);
pkvd->fHandled = TRUE;
}
// These are to keep consistency with Sven Co-op's squadmaker entity.
// CMBaseMonster::KeyValue will process TriggerCondition/TriggerTarget
// keyvalues in the same way.
else if ( FStrEq(pkvd->szKeyName, "trigger_condition") )
{
m_iTriggerCondition = atoi(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if ( FStrEq(pkvd->szKeyName, "trigger_target") )
{
m_iszTriggerTarget = ALLOC_STRING(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else
CMBaseMonster::KeyValue( pkvd );
}
@@ -163,6 +176,7 @@ void CMMonsterMaker::MakeMonster( void )
if ( pev->spawnflags & SF_MONSTERMAKER_MONSTERCLIP )
createSF |= SF_MONSTER_HITMONSTERCLIP;
/* KEYVALUES */
// Monster is to have a custom model?
if ( !FStringNull( m_iszCustomModel ) )
{
@@ -175,7 +189,34 @@ void CMMonsterMaker::MakeMonster( void )
{
// setup blood keyvalue
strcpy(keyvalue[1].key, "bloodcolor");
sprintf(keyvalue[1].value, "%i", m_iMonsterBlood );
sprintf(keyvalue[1].value, "%i", m_iMonsterBlood);
}
// Trigger conditions set?
if ( !FStringNull( m_iszTriggerTarget ) )
{
// setup trigger keyvalues
strcpy(keyvalue[2].key, "TriggerCondition");
sprintf(keyvalue[2].value, "%i", m_iTriggerCondition);
strcpy(keyvalue[3].key, "TriggerTarget");
strcpy(keyvalue[3].value, STRING( m_iszTriggerTarget ));
}
// Weapons (For hgrunt/massn/rgrunt/etc...)
if ( pev->weapons )
{
strcpy(keyvalue[4].key, "weapons");
sprintf(keyvalue[4].value, "%i", pev->weapons);
}
// Monster's Name
if ( !FStringNull( m_szMonsterName ) )
{
strcpy(keyvalue[5].key, "displayname");
strcpy(keyvalue[5].value, STRING( m_szMonsterName ));
}
// Classify override
if ( m_iClassifyOverride )
{
strcpy(keyvalue[6].key, "classify");
sprintf(keyvalue[6].value, "%i", m_iClassifyOverride);
}
// Attempt to spawn monster
@@ -201,6 +242,12 @@ void CMMonsterMaker::MakeMonster( void )
pent->v.targetname = pev->netname;
}
// Pass parent's rendering effects to child
pent->v.rendermode = pev->rendermode;
pent->v.renderfx = pev->renderfx;
pent->v.renderamt = pev->renderamt;
pent->v.rendercolor = pev->rendercolor;
m_cLiveChildren++;// count this monster
m_cNumMonsters--;

View File

@@ -145,12 +145,25 @@ void FireTargets( const char *targetName, edict_t *pActivator, edict_t *pCaller,
if (FNullEnt(pentTarget))
break;
// MonsterMod entity
CMBaseEntity *pTarget = CMBaseEntity::Instance( pentTarget );
if ( pTarget && !(pTarget->pev->flags & FL_KILLME) ) // Don't use dying ents
if ( pTarget && !(pTarget->pev->flags & FL_KILLME) )
{
ALERT( at_aiconsole, "Found: %s, firing (%s)\n", STRING(pTarget->pev->classname), targetName );
pTarget->Use( pActivator, pCaller, useType, value );
}
// Valid entity but not recognized by monstermod, must be a normal entity
else if (!(pentTarget->v.flags & FL_KILLME))
{
if (CVAR_GET_FLOAT("_glb_use")) // avoid "unknown command" spam
{
ALERT( at_aiconsole, "Found: %s, firing (%s)\n", STRING(pentTarget->v.classname), targetName );
char extCmd[64];
sprintf( extCmd, "_trigger %i %i %i %i %f\n", ENTINDEX( pentTarget ), ENTINDEX( ENT( pActivator ) ), ENTINDEX( ENT( pCaller ) ), useType, value );
SERVER_COMMAND( extCmd );
}
}
}
}

View File

@@ -801,6 +801,7 @@ void CMBaseTurret :: TurretDeath( void )
if (pev->deadflag != DEAD_DEAD)
{
pev->deadflag = DEAD_DEAD;
FCheckAITrigger(); // trigger death condition
float flRndSound = RANDOM_FLOAT ( 0 , 1 );
@@ -1105,6 +1106,7 @@ void CMSentry::SentryDeath( void )
if (pev->deadflag != DEAD_DEAD)
{
pev->deadflag = DEAD_DEAD;
FCheckAITrigger(); // trigger death condition
float flRndSound = RANDOM_FLOAT ( 0 , 1 );

View File

@@ -2142,7 +2142,10 @@ bool UTIL_IsBSPModel( edict_t *pent )
void UTIL_TakeDamageExternal( edict_t *pEdict, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType )
{
// Tell AMXX to call TakeDamage for us if it can.
char extCmd[64];
sprintf( extCmd, "monster_hurt_entity %i %i %i %f %i\n", ENTINDEX( pEdict ), ENTINDEX( ENT( pevInflictor ) ), ENTINDEX( ENT( pevAttacker ) ), flDamage, bitsDamageType );
SERVER_COMMAND( extCmd );
if (CVAR_GET_FLOAT("_glb_takedamage"))
{
char extCmd[64];
sprintf( extCmd, "_takedamage %i %i %i %f %i\n", ENTINDEX( pEdict ), ENTINDEX( ENT( pevInflictor ) ), ENTINDEX( ENT( pevAttacker ) ), flDamage, bitsDamageType );
SERVER_COMMAND( extCmd );
}
}