From 5da691b5fe1b711d03764e4aee526bdfbd9d4327 Mon Sep 17 00:00:00 2001 From: Giegue Date: Wed, 26 Apr 2023 01:44:36 -0300 Subject: [PATCH] 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. --- src/dlls/apache.cpp | 5 ++++ src/dlls/cmbase.h | 2 +- src/dlls/dllapi.cpp | 3 ++- src/dlls/monster_config.cpp | 22 ++++++++++------- src/dlls/monstermaker.cpp | 49 ++++++++++++++++++++++++++++++++++++- src/dlls/subs.cpp | 15 +++++++++++- src/dlls/turret.cpp | 2 ++ src/dlls/util.cpp | 9 ++++--- 8 files changed, 91 insertions(+), 16 deletions(-) diff --git a/src/dlls/apache.cpp b/src/dlls/apache.cpp index ec3b748..33d7490 100644 --- a/src/dlls/apache.cpp +++ b/src/dlls/apache.cpp @@ -156,6 +156,11 @@ void CMApache :: Killed( entvars_t *pevAttacker, int iGib ) pev->nextthink = gpGlobals->time + 0.1; 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) { diff --git a/src/dlls/cmbase.h b/src/dlls/cmbase.h index b0d16eb..f9af751 100644 --- a/src/dlls/cmbase.h +++ b/src/dlls/cmbase.h @@ -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; } diff --git a/src/dlls/dllapi.cpp b/src/dlls/dllapi.cpp index 78eb2e4..90c0f8f 100644 --- a/src/dlls/dllapi.cpp +++ b/src/dlls/dllapi.cpp @@ -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; } } diff --git a/src/dlls/monster_config.cpp b/src/dlls/monster_config.cpp index dc6ed9a..b2dc6c1 100644 --- a/src/dlls/monster_config.cpp +++ b/src/dlls/monster_config.cpp @@ -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++) diff --git a/src/dlls/monstermaker.cpp b/src/dlls/monstermaker.cpp index f61957b..408ff0b 100644 --- a/src/dlls/monstermaker.cpp +++ b/src/dlls/monstermaker.cpp @@ -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--; diff --git a/src/dlls/subs.cpp b/src/dlls/subs.cpp index f9fac79..3e7bd26 100644 --- a/src/dlls/subs.cpp +++ b/src/dlls/subs.cpp @@ -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 ); + } + } } } diff --git a/src/dlls/turret.cpp b/src/dlls/turret.cpp index b2239e0..5f41199 100644 --- a/src/dlls/turret.cpp +++ b/src/dlls/turret.cpp @@ -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 ); diff --git a/src/dlls/util.cpp b/src/dlls/util.cpp index 1f7f536..1d774fb 100644 --- a/src/dlls/util.cpp +++ b/src/dlls/util.cpp @@ -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 ); + } }