diff --git a/cfg/monster_skill.cfg b/cfg/monster_skill.cfg index 88ebb8b..f8e2d46 100755 --- a/cfg/monster_skill.cfg +++ b/cfg/monster_skill.cfg @@ -16,7 +16,7 @@ sk_apache_health 250 // Barney sk_barney_health 35 -// Big Momma +// Big Momma (HP = 150 * health_factor) sk_bigmomma_health_factor 1.5 sk_bigmomma_dmg_slash 60 sk_bigmomma_dmg_blast 120 diff --git a/src/dlls/Makefile b/src/dlls/Makefile index 1a1e854..0789924 100644 --- a/src/dlls/Makefile +++ b/src/dlls/Makefile @@ -46,6 +46,7 @@ OBJ = \ rgrunt.o \ ripent.o \ scientist.o \ + setcvar.o \ shock.o \ shockroach.o \ skill.o \ diff --git a/src/dlls/agrunt.cpp b/src/dlls/agrunt.cpp index 73d34f8..fb42487 100644 --- a/src/dlls/agrunt.cpp +++ b/src/dlls/agrunt.cpp @@ -543,7 +543,7 @@ void CMAGrunt :: Spawn() pev->movetype = MOVETYPE_STEP; m_bloodColor = !m_bloodColor ? BLOOD_COLOR_YELLOW : m_bloodColor; pev->effects = 0; - pev->health = gSkillData.agruntHealth; + if (!pev->health) { pev->health = gSkillData.agruntHealth; } m_flFieldOfView = 0.2;// indicates the width of this monster's forward view cone ( as a dotproduct result ) m_MonsterState = MONSTERSTATE_NONE; m_afCapability = 0; diff --git a/src/dlls/apache.cpp b/src/dlls/apache.cpp index 940c65a..c91af2a 100644 --- a/src/dlls/apache.cpp +++ b/src/dlls/apache.cpp @@ -41,7 +41,7 @@ void CMApache :: Spawn( void ) pev->flags |= FL_MONSTER; pev->takedamage = DAMAGE_AIM; - pev->health = gSkillData.apacheHealth; + if (!pev->health) { pev->health = gSkillData.apacheHealth; } m_flFieldOfView = -0.707; // 270 degrees diff --git a/src/dlls/barney.cpp b/src/dlls/barney.cpp index b9c56a5..d6b863f 100644 --- a/src/dlls/barney.cpp +++ b/src/dlls/barney.cpp @@ -351,7 +351,7 @@ void CMBarney :: Spawn() pev->solid = SOLID_SLIDEBOX; pev->movetype = MOVETYPE_STEP; m_bloodColor = !m_bloodColor ? BLOOD_COLOR_RED : m_bloodColor; - pev->health = gSkillData.barneyHealth; + if (!pev->health) { pev->health = gSkillData.barneyHealth; } pev->view_ofs = Vector ( 0, 0, 50 );// position of the eyes relative to monster's origin. m_flFieldOfView = VIEW_FIELD_FULL; m_MonsterState = MONSTERSTATE_NONE; diff --git a/src/dlls/bigmomma.cpp b/src/dlls/bigmomma.cpp index 3911456..046c6b8 100644 --- a/src/dlls/bigmomma.cpp +++ b/src/dlls/bigmomma.cpp @@ -610,7 +610,7 @@ void CMBigMomma :: Spawn() pev->solid = SOLID_SLIDEBOX; pev->movetype = MOVETYPE_STEP; m_bloodColor = !m_bloodColor ? BLOOD_COLOR_YELLOW : m_bloodColor; - pev->health = 150 * gSkillData.bigmommaHealthFactor; + if (!pev->health) { pev->health = 150 * gSkillData.bigmommaHealthFactor; } pev->view_ofs = Vector ( 0, 0, 128 );// position of the eyes relative to monster's origin. m_flFieldOfView = 0.3;// indicates the width of this monster's forward view cone ( as a dotproduct result ) m_MonsterState = MONSTERSTATE_NONE; diff --git a/src/dlls/bullsquid.cpp b/src/dlls/bullsquid.cpp index 625fbb3..24bd9b5 100644 --- a/src/dlls/bullsquid.cpp +++ b/src/dlls/bullsquid.cpp @@ -65,6 +65,7 @@ public: void EXPORT Animate( void ); int m_maxFrame; + EHANDLE m_hOwner; }; void CSquidSpit:: Spawn( void ) @@ -110,6 +111,7 @@ void CSquidSpit::Shoot( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity UTIL_SetOrigin( pSpit->pev, vecStart ); pSpit->pev->velocity = vecVelocity; pSpit->pev->owner = ENT(pevOwner); + pSpit->m_hOwner = ENT(pevOwner); pSpit->SetThink ( &CSquidSpit::Animate ); pSpit->pev->nextthink = gpGlobals->time + 0.1; @@ -118,6 +120,9 @@ void CSquidSpit::Shoot( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity void CSquidSpit :: SpitTouch ( edict_t *pOther ) { + if (m_hOwner == NULL) + pev->owner = NULL; + TraceResult tr; int iPitch; @@ -617,7 +622,7 @@ void CMBullsquid :: Spawn() pev->movetype = MOVETYPE_STEP; m_bloodColor = !m_bloodColor ? BLOOD_COLOR_YELLOW : m_bloodColor; pev->effects = 0; - pev->health = gSkillData.bullsquidHealth; + if (!pev->health) { pev->health = gSkillData.bullsquidHealth; } m_flFieldOfView = 0.2;// indicates the width of this monster's forward view cone ( as a dotproduct result ) m_MonsterState = MONSTERSTATE_NONE; diff --git a/src/dlls/cmbaseextra.h b/src/dlls/cmbaseextra.h index 103ad4d..43aa24f 100644 --- a/src/dlls/cmbaseextra.h +++ b/src/dlls/cmbaseextra.h @@ -88,4 +88,17 @@ private: int m_iBeamIndex; }; +//========================================================= +// Set CVar - Adjust a map CVar when triggered. +//========================================================= +class CMSetCVar : public CMBaseMonster +{ +public: + void Spawn(void); + void KeyValue(KeyValueData* pkvd); + void EXPORT ActUse(edict_t *pActivator, edict_t *pCaller, USE_TYPE useType, float value); + + string_t m_iszCVarToChange; +}; + #endif // BASEEXTRA_H diff --git a/src/dlls/combat.cpp b/src/dlls/combat.cpp index b38ebd7..cd6812f 100644 --- a/src/dlls/combat.cpp +++ b/src/dlls/combat.cpp @@ -974,10 +974,15 @@ int CMBaseMonster :: DeadTakeDamage( entvars_t *pevInflictor, entvars_t *pevAtta vecDir = Vector( 0, 0, 0 ); if (!FNullEnt( pevInflictor )) { - CMBaseMonster *pMonster = GetClassPtr((CMBaseMonster *)VARS(pevInflictor)); - if (pMonster) + if (pevInflictor->euser4 != NULL) { - vecDir = ( pMonster->Center() - Vector ( 0, 0, 10 ) - Center() ).Normalize(); + CMBaseMonster *pMonster = GetClassPtr((CMBaseMonster *)VARS(pevInflictor)); + vecDir = (pMonster->Center() - Vector(0, 0, 10) - Center()).Normalize(); + vecDir = g_vecAttackDir = vecDir.Normalize(); + } + else + { + vecDir = (UTIL_Center(ENT(pevInflictor)) - Vector(0, 0, 10) - Center()).Normalize(); vecDir = g_vecAttackDir = vecDir.Normalize(); } } diff --git a/src/dlls/controller.cpp b/src/dlls/controller.cpp index c8e9180..8d30dff 100644 --- a/src/dlls/controller.cpp +++ b/src/dlls/controller.cpp @@ -309,7 +309,7 @@ void CMController :: Spawn() pev->movetype = MOVETYPE_FLY; pev->flags |= FL_FLY; m_bloodColor = !m_bloodColor ? BLOOD_COLOR_YELLOW : m_bloodColor; - pev->health = gSkillData.controllerHealth; + if (!pev->health) { pev->health = gSkillData.controllerHealth; } pev->view_ofs = Vector( 0, 0, -2 );// position of the eyes relative to monster's origin. m_flFieldOfView = VIEW_FIELD_FULL;// indicates the width of this monster's forward view cone ( as a dotproduct result ) m_MonsterState = MONSTERSTATE_NONE; diff --git a/src/dlls/dllapi.cpp b/src/dlls/dllapi.cpp index 88f3ce5..96de25e 100644 --- a/src/dlls/dllapi.cpp +++ b/src/dlls/dllapi.cpp @@ -167,6 +167,7 @@ monster_type_t monster_types[]= "monstermaker", FALSE, // Extra entities "ambient_music", FALSE, "env_xenmaker", FALSE, + "trigger_setcvar", FALSE, "squadmaker", FALSE, // Aliases "", FALSE }; @@ -713,6 +714,7 @@ edict_t* spawn_monster(int monster_type, Vector origin, Vector angles, int spawn case 32: monsters[monster_index].pMonster = CreateClassPtr((CMMonsterMaker *)NULL); break; case 33: monsters[monster_index].pMonster = CreateClassPtr((CMAmbientMusic *)NULL); break; case 34: monsters[monster_index].pMonster = CreateClassPtr((CMXenMaker *)NULL); break; + case 35: monsters[monster_index].pMonster = CreateClassPtr((CMSetCVar *)NULL); break; } if (monsters[monster_index].pMonster == NULL) @@ -1438,6 +1440,7 @@ void mmServerActivate( edict_t *pEdictList, int edictCount, int clientMax ) CMMonsterMaker monstermaker; // 32 CMAmbientMusic ambientmusic; CMXenMaker xenmaker; + CMSetCVar setcvar; g_psv_gravity = CVAR_GET_POINTER( "sv_gravity" ); @@ -1489,6 +1492,7 @@ void mmServerActivate( edict_t *pEdictList, int edictCount, int clientMax ) case 32: monstermaker.Precache(); break; //case 33: ambientmusic.Precache(); break; case 34: xenmaker.Precache(); break; + //case 35: setcvar.Precache(); break; } } } diff --git a/src/dlls/gargantua.cpp b/src/dlls/gargantua.cpp index 776cbd1..7ad009a 100644 --- a/src/dlls/gargantua.cpp +++ b/src/dlls/gargantua.cpp @@ -684,7 +684,7 @@ void CMGargantua :: Spawn() pev->solid = SOLID_SLIDEBOX; pev->movetype = MOVETYPE_STEP; m_bloodColor = !m_bloodColor ? BLOOD_COLOR_YELLOW : m_bloodColor; - pev->health = gSkillData.gargantuaHealth; + if (!pev->health) { pev->health = gSkillData.gargantuaHealth; } //pev->view_ofs = Vector ( 0, 0, 96 );// taken from mdl file m_flFieldOfView = -0.2;// width of forward view cone ( as a dotproduct result ) m_MonsterState = MONSTERSTATE_NONE; @@ -1329,7 +1329,7 @@ void CMBabyGargantua::Spawn() pev->solid = SOLID_SLIDEBOX; pev->movetype = MOVETYPE_STEP; m_bloodColor = !m_bloodColor ? BLOOD_COLOR_YELLOW : m_bloodColor; - pev->health = gSkillData.babygargHealth; + if (!pev->health) { pev->health = gSkillData.babygargHealth; } //pev->view_ofs = Vector ( 0, 0, 96 );// taken from mdl file m_flFieldOfView = -0.2;// width of forward view cone ( as a dotproduct result ) m_MonsterState = MONSTERSTATE_NONE; diff --git a/src/dlls/globalreplace.cpp b/src/dlls/globalreplace.cpp index 71a0bde..d8e87e2 100644 --- a/src/dlls/globalreplace.cpp +++ b/src/dlls/globalreplace.cpp @@ -56,6 +56,12 @@ bool AddGlobalSound(const char *from, const char *to) { if (numSounds < MAX_REPLACEMENTS) { + if (from[0] == '!') + { + // sentence sounds cannot be replaced, skip. + return false; + } + // allocate for the first time if (!numSounds) GSR = (REPLACER*)calloc(MAX_REPLACEMENTS, sizeof(*GSR)); diff --git a/src/dlls/gonome.cpp b/src/dlls/gonome.cpp index f165e9d..30de5c7 100644 --- a/src/dlls/gonome.cpp +++ b/src/dlls/gonome.cpp @@ -615,7 +615,7 @@ void CMGonome::Spawn() pev->movetype = MOVETYPE_STEP; m_bloodColor = !m_bloodColor ? BLOOD_COLOR_YELLOW : m_bloodColor; pev->effects = 0; - pev->health = gSkillData.gonomeHealth; + if (!pev->health) { pev->health = gSkillData.gonomeHealth; } m_flFieldOfView = 0.2;// indicates the width of this monster's forward view cone ( as a dotproduct result ) m_MonsterState = MONSTERSTATE_NONE; diff --git a/src/dlls/hassassin.cpp b/src/dlls/hassassin.cpp index 5564354..eab528b 100644 --- a/src/dlls/hassassin.cpp +++ b/src/dlls/hassassin.cpp @@ -222,7 +222,7 @@ void CMHAssassin :: Spawn() pev->movetype = MOVETYPE_STEP; m_bloodColor = !m_bloodColor ? BLOOD_COLOR_RED : m_bloodColor; pev->effects = 0; - pev->health = gSkillData.hassassinHealth; + if (!pev->health) { pev->health = gSkillData.hassassinHealth; } m_flFieldOfView = VIEW_FIELD_WIDE; // indicates the width of this monster's forward view cone ( as a dotproduct result ) m_MonsterState = MONSTERSTATE_NONE; m_afCapability = bits_CAP_MELEE_ATTACK1 | bits_CAP_DOORS_GROUP; diff --git a/src/dlls/headcrab.cpp b/src/dlls/headcrab.cpp index df5b607..fd37254 100644 --- a/src/dlls/headcrab.cpp +++ b/src/dlls/headcrab.cpp @@ -254,7 +254,7 @@ void CMHeadCrab :: Spawn() pev->movetype = MOVETYPE_STEP; m_bloodColor = !m_bloodColor ? BLOOD_COLOR_YELLOW : m_bloodColor; pev->effects = 0; - pev->health = gSkillData.headcrabHealth; + if (!pev->health) { pev->health = gSkillData.headcrabHealth; } pev->view_ofs = Vector ( 0, 0, 20 );// position of the eyes relative to monster's origin. pev->yaw_speed = 5;//!!! should we put this in the monster's changeanim function since turn rates may vary with state/anim? m_flFieldOfView = 0.5;// indicates the width of this monster's forward view cone ( as a dotproduct result ) @@ -466,7 +466,7 @@ void CMBabyCrab :: Spawn( void ) pev->renderamt = 192; UTIL_SetSize(pev, Vector(-12, -12, 0), Vector(12, 12, 24)); - pev->health = gSkillData.headcrabHealth * 0.25; // less health than full grown + if (!pev->health) { pev->health = gSkillData.headcrabHealth * 0.25; } // less health than full grown } void CMBabyCrab :: Precache( void ) diff --git a/src/dlls/hgrunt.cpp b/src/dlls/hgrunt.cpp index 8c534e1..ab0a325 100644 --- a/src/dlls/hgrunt.cpp +++ b/src/dlls/hgrunt.cpp @@ -837,7 +837,7 @@ void CMHGrunt :: Spawn() pev->movetype = MOVETYPE_STEP; m_bloodColor = !m_bloodColor ? BLOOD_COLOR_RED : m_bloodColor; pev->effects = 0; - pev->health = gSkillData.hgruntHealth; + if (!pev->health) { pev->health = gSkillData.hgruntHealth; } m_flFieldOfView = VIEW_FIELD_FULL; // indicates the width of this monster's forward view cone ( as a dotproduct result ) m_MonsterState = MONSTERSTATE_NONE; m_flNextGrenadeCheck = gpGlobals->time + 1; diff --git a/src/dlls/hornet.cpp b/src/dlls/hornet.cpp index d841745..1292db3 100644 --- a/src/dlls/hornet.cpp +++ b/src/dlls/hornet.cpp @@ -131,7 +131,10 @@ int CMHornet::Classify ( void ) if (UTIL_IsValidEntity(pev->owner)) { CMBaseMonster *pOwner = GetClassPtr((CMBaseMonster *)VARS(pev->owner)); - return pOwner->Classify(); + if (pOwner) + return pOwner->Classify(); + else + return pev->owner->v.iuser4; } return CLASS_ALIEN_BIOWEAPON; } diff --git a/src/dlls/houndeye.cpp b/src/dlls/houndeye.cpp index e52c5c3..374125b 100644 --- a/src/dlls/houndeye.cpp +++ b/src/dlls/houndeye.cpp @@ -274,7 +274,7 @@ void CMHoundeye :: Spawn() pev->movetype = MOVETYPE_STEP; m_bloodColor = !m_bloodColor ? BLOOD_COLOR_YELLOW : m_bloodColor; pev->effects = 0; - pev->health = gSkillData.houndeyeHealth; + if (!pev->health) { pev->health = gSkillData.houndeyeHealth; } pev->yaw_speed = 5;//!!! should we put this in the monster's changeanim function since turn rates may vary with state/anim? m_flFieldOfView = 0.5;// indicates the width of this monster's forward view cone ( as a dotproduct result ) m_MonsterState = MONSTERSTATE_NONE; diff --git a/src/dlls/hwgrunt.cpp b/src/dlls/hwgrunt.cpp index c67455b..b8b8dc3 100644 --- a/src/dlls/hwgrunt.cpp +++ b/src/dlls/hwgrunt.cpp @@ -201,7 +201,7 @@ void CMHWGrunt::Spawn() pev->movetype = MOVETYPE_STEP; m_bloodColor = !m_bloodColor ? BLOOD_COLOR_RED : m_bloodColor; pev->effects = 0; - pev->health = gSkillData.hwgruntHealth; + if (!pev->health) { pev->health = gSkillData.hwgruntHealth; } m_flFieldOfView = 0.2;// indicates the width of this monster's forward view cone ( as a dotproduct result ) m_MonsterState = MONSTERSTATE_NONE; //m_flNextGrenadeCheck = gpGlobals->time + 1; diff --git a/src/dlls/islave.cpp b/src/dlls/islave.cpp index c943161..518afca 100644 --- a/src/dlls/islave.cpp +++ b/src/dlls/islave.cpp @@ -423,7 +423,7 @@ void CMISlave :: Spawn() pev->movetype = MOVETYPE_STEP; m_bloodColor = !m_bloodColor ? BLOOD_COLOR_YELLOW : m_bloodColor; pev->effects = 0; - pev->health = gSkillData.slaveHealth; + if (!pev->health) { pev->health = gSkillData.slaveHealth; } pev->view_ofs = Vector ( 0, 0, 64 );// position of the eyes relative to monster's origin. m_flFieldOfView = 0.5; m_MonsterState = MONSTERSTATE_NONE; diff --git a/src/dlls/massn.cpp b/src/dlls/massn.cpp index e0ced67..5d28e40 100644 --- a/src/dlls/massn.cpp +++ b/src/dlls/massn.cpp @@ -231,7 +231,7 @@ void CMMassn::Spawn() pev->movetype = MOVETYPE_STEP; m_bloodColor = !m_bloodColor ? BLOOD_COLOR_RED : m_bloodColor; pev->effects = 0; - pev->health = gSkillData.massnHealth; + if (!pev->health) { pev->health = gSkillData.massnHealth; } m_flFieldOfView = 0.2;// indicates the width of this monster's forward view cone ( as a dotproduct result ) m_MonsterState = MONSTERSTATE_NONE; m_flNextGrenadeCheck = gpGlobals->time + 1; diff --git a/src/dlls/monster_config.cpp b/src/dlls/monster_config.cpp index cc23d5e..c0dbacd 100644 --- a/src/dlls/monster_config.cpp +++ b/src/dlls/monster_config.cpp @@ -225,6 +225,20 @@ void scan_monster_cfg(FILE *fp) monster = TRUE; } } + else if (strcmp(monster_types[mIndex].name, "trigger_setcvar") == 0) + { + if (monster_spawn_count == MAX_MONSTERS) + { + LOG_MESSAGE(PLID, "ERROR: can't add ambient_music, reached MAX_MONSTERS!"); + badent = TRUE; + } + else + { + monster_spawnpoint[monster_spawn_count].monster = mIndex; + monster_types[mIndex].need_to_precache = TRUE; + monster = TRUE; + } + } else if (strcmp(monster_types[mIndex].name, "env_xenmaker") == 0) { // A monster spawner, add it to the list diff --git a/src/dlls/monster_mm.vcxproj b/src/dlls/monster_mm.vcxproj index 18deb35..a7bc5ff 100644 --- a/src/dlls/monster_mm.vcxproj +++ b/src/dlls/monster_mm.vcxproj @@ -173,6 +173,7 @@ + diff --git a/src/dlls/monster_mm.vcxproj.filters b/src/dlls/monster_mm.vcxproj.filters index c4a95b0..3c7df94 100644 --- a/src/dlls/monster_mm.vcxproj.filters +++ b/src/dlls/monster_mm.vcxproj.filters @@ -189,6 +189,9 @@ Source Files + + Source Files + diff --git a/src/dlls/monstermaker.cpp b/src/dlls/monstermaker.cpp index ed51585..4573582 100644 --- a/src/dlls/monstermaker.cpp +++ b/src/dlls/monstermaker.cpp @@ -247,6 +247,12 @@ void CMMonsterMaker::MakeMonster( void ) strcpy(keyvalue[6].key, "classify"); sprintf(keyvalue[6].value, "%i", m_iClassifyOverride); } + // Custom health + if (pev->health) + { + strcpy(keyvalue[7].key, "health"); + sprintf(keyvalue[7].value, "%f", pev->health); + } // Attempt to spawn monster pent = spawn_monster(m_iMonsterIndex, pev->origin, pev->angles, createSF, keyvalue); diff --git a/src/dlls/otis.cpp b/src/dlls/otis.cpp index 989038e..222ca5c 100644 --- a/src/dlls/otis.cpp +++ b/src/dlls/otis.cpp @@ -143,7 +143,7 @@ void CMOtis::Spawn() pev->solid = SOLID_SLIDEBOX; pev->movetype = MOVETYPE_STEP; m_bloodColor = !m_bloodColor ? BLOOD_COLOR_RED : m_bloodColor; - pev->health = gSkillData.otisHealth; + if (!pev->health) { pev->health = gSkillData.otisHealth; } pev->view_ofs = Vector(0, 0, 50);// position of the eyes relative to monster's origin. m_flFieldOfView = VIEW_FIELD_WIDE; // NOTE: we need a wide field of view so npc will notice player and say hello m_MonsterState = MONSTERSTATE_NONE; diff --git a/src/dlls/pitdrone.cpp b/src/dlls/pitdrone.cpp index 7c20a85..b0fc971 100644 --- a/src/dlls/pitdrone.cpp +++ b/src/dlls/pitdrone.cpp @@ -578,7 +578,7 @@ void CMPitdrone::Spawn() pev->movetype = MOVETYPE_STEP; m_bloodColor = !m_bloodColor ? BLOOD_COLOR_YELLOW : m_bloodColor; pev->effects = 0; - pev->health = gSkillData.pitdroneHealth; + if (!pev->health) { pev->health = gSkillData.pitdroneHealth; } m_flFieldOfView = 0.2;// indicates the width of this monster's forward view cone ( as a dotproduct result ) m_MonsterState = MONSTERSTATE_NONE; diff --git a/src/dlls/rgrunt.cpp b/src/dlls/rgrunt.cpp index 5d305f1..29d5ef8 100644 --- a/src/dlls/rgrunt.cpp +++ b/src/dlls/rgrunt.cpp @@ -324,7 +324,7 @@ void CMRGrunt::Spawn() pev->movetype = MOVETYPE_STEP; m_bloodColor = DONT_BLEED; pev->effects = 0; - pev->health = gSkillData.rgruntHealth; + if (!pev->health) { pev->health = gSkillData.rgruntHealth; } pev->max_health = pev->health; // to determine when sparks should be emitted m_flFieldOfView = 0.2;// indicates the width of this monster's forward view cone ( as a dotproduct result ) m_MonsterState = MONSTERSTATE_NONE; diff --git a/src/dlls/scientist.cpp b/src/dlls/scientist.cpp index f6ccdec..e13f2f4 100644 --- a/src/dlls/scientist.cpp +++ b/src/dlls/scientist.cpp @@ -602,7 +602,7 @@ void CMScientist :: Spawn( void ) pev->solid = SOLID_SLIDEBOX; pev->movetype = MOVETYPE_STEP; m_bloodColor = !m_bloodColor ? BLOOD_COLOR_RED : m_bloodColor; - pev->health = gSkillData.scientistHealth; + if (!pev->health) { pev->health = gSkillData.scientistHealth; } pev->view_ofs = Vector ( 0, 0, 50 );// position of the eyes relative to monster's origin. m_flFieldOfView = VIEW_FIELD_WIDE; // NOTE: we need a wide field of view so scientists will notice player and say hello m_MonsterState = MONSTERSTATE_NONE; diff --git a/src/dlls/setcvar.cpp b/src/dlls/setcvar.cpp new file mode 100644 index 0000000..4eb0ee2 --- /dev/null +++ b/src/dlls/setcvar.cpp @@ -0,0 +1,68 @@ +//========================================================= +// Set CVar - trigger_setcvar from Sven Co-op. +// Change a map CVar when triggered. +//========================================================= +#include "extdll.h" +#include "util.h" +#include "cmbase.h" +#include "cmbasemonster.h" +#include "cmbaseextra.h" + +#define MAX_CVARS 10 + +// list of CVars that can be modified by this entity +char *cvar_list[MAX_CVARS] +{ + "mp_falldamage", + "mp_flashlight", + "mp_fraglimit", + "mp_timelimit", + "mp_weaponstay", + "sv_accelerate", + "sv_airaccelerate" + "sv_friction", + "sv_gravity", + "sv_maxspeed" +}; // quite lame compared to SC, but many CVars don't exist in vanilla HL + +void CMSetCVar::KeyValue(KeyValueData *pkvd) +{ + if (FStrEq(pkvd->szKeyName, "m_iszCVarToChange")) + { + for (int index = 0; index < MAX_CVARS; index++) + { + if (strcmp(pkvd->szValue, cvar_list[index]) == 0) + { + m_iszCVarToChange = ALLOC_STRING(pkvd->szValue); + break; + } + } + if (FStringNull(m_iszCVarToChange)) + { + ALERT(at_console, "trigger_setcvar - can't change CVar \"%s\". not supported!\n", pkvd->szValue); + } + pkvd->fHandled = TRUE; + } + else + CMBaseMonster::KeyValue(pkvd); +} +void CMSetCVar::Spawn() +{ + pev->solid = SOLID_NOT; + SetUse(&CMSetCVar::ActUse); + pev->classname = MAKE_STRING("trigger_setcvar"); +} + +void CMSetCVar::ActUse(edict_t *pActivator, edict_t *pCaller, USE_TYPE useType, float value) +{ + // nothing to change + if (FStringNull(m_iszCVarToChange)) + return; + + CVAR_SET_FLOAT(STRING(m_iszCVarToChange), atof(STRING(pev->message))); + + if (!FStringNull(pev->netname)) + { + FireTargets(STRING(pev->netname), pActivator, this->edict(), USE_TOGGLE, 0.0f); + } +} diff --git a/src/dlls/strooper.cpp b/src/dlls/strooper.cpp index 25d6a18..490066f 100644 --- a/src/dlls/strooper.cpp +++ b/src/dlls/strooper.cpp @@ -369,7 +369,7 @@ void CMStrooper::Spawn() pev->movetype = MOVETYPE_STEP; m_bloodColor = !m_bloodColor ? BLOOD_COLOR_YELLOW : m_bloodColor; pev->effects = 0; - pev->health = gSkillData.strooperHealth; + if (!pev->health) { pev->health = gSkillData.strooperHealth; } m_flFieldOfView = 0.2;// indicates the width of this monster's forward view cone ( as a dotproduct result ) m_MonsterState = MONSTERSTATE_NONE; m_flNextGrenadeCheck = gpGlobals->time + 1; diff --git a/src/dlls/stukabat.cpp b/src/dlls/stukabat.cpp index 479ce34..adbb05e 100644 --- a/src/dlls/stukabat.cpp +++ b/src/dlls/stukabat.cpp @@ -106,7 +106,7 @@ void CMStukabat :: Spawn() pev->movetype = MOVETYPE_FLY; pev->flags |= FL_FLY; m_bloodColor = !m_bloodColor ? BLOOD_COLOR_YELLOW : m_bloodColor; - pev->health = gSkillData.stukabatHealth; + if (!pev->health) { pev->health = gSkillData.stukabatHealth; } pev->view_ofs = Vector ( 0, 0, 22 );// position of the eyes relative to monster's origin. m_flFieldOfView = 0.5;// indicates the width of this monster's forward view cone ( as a dotproduct result ) m_MonsterState = MONSTERSTATE_NONE; diff --git a/src/dlls/subs.cpp b/src/dlls/subs.cpp index 3e7bd26..cd78589 100644 --- a/src/dlls/subs.cpp +++ b/src/dlls/subs.cpp @@ -226,7 +226,7 @@ void CMBaseDelay :: SUB_UseTargets( edict_t *pActivator, USE_TYPE useType, float pentKillTarget = FIND_ENTITY_BY_TARGETNAME( NULL, STRING(m_iszKillTarget) ); while ( !FNullEnt(pentKillTarget) ) { - UTIL_Remove( CMBaseEntity::Instance(pentKillTarget)->edict() ); + UTIL_Remove( pentKillTarget ); ALERT( at_aiconsole, "killing %s\n", STRING( pentKillTarget->v.classname ) ); pentKillTarget = FIND_ENTITY_BY_TARGETNAME( pentKillTarget, STRING(m_iszKillTarget) ); diff --git a/src/dlls/turret.cpp b/src/dlls/turret.cpp index 2ca16e0..38d4de1 100644 --- a/src/dlls/turret.cpp +++ b/src/dlls/turret.cpp @@ -125,7 +125,7 @@ void CMTurret::Spawn() { Precache( ); SET_MODEL(ENT(pev), (!FStringNull( pev->model ) ? STRING( pev->model ) : "models/turret.mdl")); - pev->health = gSkillData.turretHealth; + if (!pev->health) { pev->health = gSkillData.turretHealth; } m_HackedGunPos = Vector( 0, 0, 12.75 ); m_flMaxSpin = TURRET_MAXSPIN; pev->view_ofs.z = 12.75; @@ -165,7 +165,7 @@ void CMMiniTurret::Spawn() { Precache( ); SET_MODEL(ENT(pev), (!FStringNull( pev->model ) ? STRING( pev->model ) : "models/miniturret.mdl")); - pev->health = gSkillData.miniturretHealth; + if (!pev->health) { pev->health = gSkillData.miniturretHealth; } m_HackedGunPos = Vector( 0, 0, 12.75 ); m_flMaxSpin = 0; pev->view_ofs.z = 12.75; @@ -1019,7 +1019,7 @@ void CMSentry::Spawn() { Precache( ); SET_MODEL(ENT(pev), (!FStringNull( pev->model ) ? STRING( pev->model ) : "models/sentry.mdl")); - pev->health = gSkillData.sentryHealth; + if (!pev->health) { pev->health = gSkillData.sentryHealth; } m_HackedGunPos = Vector( 0, 0, 48 ); pev->view_ofs.z = 48; m_flMaxWait = 1E6; diff --git a/src/dlls/util.cpp b/src/dlls/util.cpp index 1d774fb..bd65f3a 100644 --- a/src/dlls/util.cpp +++ b/src/dlls/util.cpp @@ -1564,9 +1564,9 @@ void UTIL_Remove( edict_t *pEntity ) if ( !pEntity ) return; -//jlb pEntity->UpdateOnRemove(); - pEntity->v.flags |= FL_KILLME; + //pEntity->UpdateOnRemove(); pEntity->v.targetname = 0; + pEntity->v.flags |= FL_KILLME; } diff --git a/src/dlls/voltigore.cpp b/src/dlls/voltigore.cpp index 6bf81ab..e8e5b5f 100644 --- a/src/dlls/voltigore.cpp +++ b/src/dlls/voltigore.cpp @@ -644,7 +644,7 @@ void CMVoltigore::Spawn() pev->movetype = MOVETYPE_STEP; m_bloodColor = !m_bloodColor ? BLOOD_COLOR_YELLOW : m_bloodColor; pev->effects = 0; - pev->health = gSkillData.voltigoreHealth; + if (!pev->health) { pev->health = gSkillData.voltigoreHealth; } m_flFieldOfView = 0.2;// indicates the width of this monster's forward view cone ( as a dotproduct result ) m_MonsterState = MONSTERSTATE_NONE; @@ -1152,7 +1152,7 @@ void CMBabyVoltigore::Spawn() pev->movetype = MOVETYPE_STEP; m_bloodColor = !m_bloodColor ? BLOOD_COLOR_YELLOW : m_bloodColor; pev->effects = 0; - pev->health = gSkillData.babyVoltigoreHealth; + if (!pev->health) { pev->health = gSkillData.babyVoltigoreHealth; } m_flFieldOfView = 0.2;// indicates the width of this monster's forward view cone ( as a dotproduct result ) m_MonsterState = MONSTERSTATE_NONE; diff --git a/src/dlls/xenmaker.cpp b/src/dlls/xenmaker.cpp index 4351eb4..46a80e5 100644 --- a/src/dlls/xenmaker.cpp +++ b/src/dlls/xenmaker.cpp @@ -14,6 +14,11 @@ #define SF_XENMAKER_TRY_ONCE 1 // only one attempt to spawn each time it is fired #define SF_XENMAKER_NO_SPAWN 2 // don't spawn anything, only do effects +#define SF_XENMAKER_NO_LIGHT 4 // don't do light effect +#define SF_XENMAKER_NO_BEAMS 8 // don't do beam effects +#define SF_XENMAKER_NO_SPRITE 16 // don't do sprite effects +#define SF_XENMAKER_NO_SOUND 32 // don't do sound effect + extern monster_type_t monster_types[]; extern edict_t* spawn_monster(int monster_type, Vector origin, Vector angles, int spawnflags, pKVD *keyvalue); @@ -35,7 +40,7 @@ void CMXenMaker::KeyValue(KeyValueData *pkvd) } if (monster_types[mIndex].name[0] == 0) { - ALERT(at_logged, "[MONSTER] XenMaker - %s is not a valid monster type!\n", pkvd->szValue); + ALERT(at_console, "[MONSTER] XenMaker - %s is not a valid monster type!\n", pkvd->szValue); m_iMonsterIndex = -1; } pkvd->fHandled = TRUE; @@ -124,11 +129,17 @@ void CMXenMaker::Spawn() { // monstertype was not defined, it may be intentional if nothing is to spawn here if (!FBitSet(pev->spawnflags, SF_XENMAKER_NO_SPAWN)) - ALERT(at_logged, "[MONSTER] Spawned a env_xenmaker entity without a monstertype! targetname: \"%s\"\n", STRING(pev->targetname)); + ALERT(at_console, "[MONSTER] Spawned a env_xenmaker entity without a monstertype! targetname: \"%s\"\n", STRING(pev->targetname)); m_iMonsterIndex = -1; } } + // fix uninitialized keyvalues (default per Sven Co-op's FGD) + if (!m_flStartSpriteScale) m_flStartSpriteScale = 1.0; + if (!m_flEndSpriteScale) m_flEndSpriteScale = 1.0; + if (!m_flStartSpriteFramerate) m_flStartSpriteFramerate = 12; + if (!m_flEndSpriteFramerate) m_flEndSpriteFramerate = 12; + pev->solid = SOLID_NOT; Precache(); @@ -180,6 +191,7 @@ void CMXenMaker::StartEffect(void) if (pent == NULL) { ALERT(at_console, "[MONSTER] XenMaker - failed to spawn monster! targetname: \"%s\"\n", STRING(pev->targetname)); + return; } else pent->v.spawnflags |= SF_MONSTER_FADECORPSE; @@ -192,39 +204,54 @@ void CMXenMaker::StartEffect(void) SetThink(&CMXenMaker::RetryThink); return; // don't do effects } + else + { + // no effects here, either + return; + } } // BEAM EFFECT - for (int beam = 0; beam < m_iBeamCount; beam++) + if (!FBitSet(pev->spawnflags, SF_XENMAKER_NO_BEAMS)) { - SpawnBeam(); + for (int beam = 0; beam < m_iBeamCount; beam++) + { + SpawnBeam(); + } } // LIGHT EFFECT - MESSAGE_BEGIN(MSG_BROADCAST, SVC_TEMPENTITY); - WRITE_BYTE(TE_DLIGHT); - WRITE_COORD(pev->origin.x); - WRITE_COORD(pev->origin.y); - WRITE_COORD(pev->origin.z); - WRITE_BYTE((int)(m_flLightRadius / 10)); - WRITE_BYTE((int)m_vLightColor.x); - WRITE_BYTE((int)m_vLightColor.y); - WRITE_BYTE((int)m_vLightColor.z); - WRITE_BYTE(10); // life - WRITE_BYTE(0); // decay rate - MESSAGE_END(); + if (!FBitSet(pev->spawnflags, SF_XENMAKER_NO_LIGHT)) + { + MESSAGE_BEGIN(MSG_BROADCAST, SVC_TEMPENTITY); + WRITE_BYTE(TE_DLIGHT); + WRITE_COORD(pev->origin.x); + WRITE_COORD(pev->origin.y); + WRITE_COORD(pev->origin.z); + WRITE_BYTE((int)(m_flLightRadius / 10)); + WRITE_BYTE((int)m_vLightColor.x); + WRITE_BYTE((int)m_vLightColor.y); + WRITE_BYTE((int)m_vLightColor.z); + WRITE_BYTE(10); // life + WRITE_BYTE(0); // decay rate + MESSAGE_END(); + } // SPRITE EFFECT - CMSprite *pSprite = CMSprite::SpriteCreate("sprites/fexplo1.spr", pev->origin, FALSE); - if (pSprite) + if (!FBitSet(pev->spawnflags, SF_XENMAKER_NO_SPRITE)) { - pSprite->SetScale(m_flStartSpriteScale); - pSprite->SetTransparency(kRenderGlow, (int)m_vStartSpriteColor.x, (int)m_vStartSpriteColor.y, (int)m_vStartSpriteColor.z, m_iStartSpriteAlpha, kRenderFxNoDissipation); - pSprite->AnimateAndDie(m_flStartSpriteFramerate); + CMSprite *pSprite = CMSprite::SpriteCreate("sprites/fexplo1.spr", pev->origin, FALSE); + if (pSprite) + { + pSprite->SetScale(m_flStartSpriteScale); + pSprite->SetTransparency(kRenderGlow, (int)m_vStartSpriteColor.x, (int)m_vStartSpriteColor.y, (int)m_vStartSpriteColor.z, m_iStartSpriteAlpha, kRenderFxNoDissipation); + pSprite->AnimateAndDie(m_flStartSpriteFramerate); + } } // SOUND EFFECT - EMIT_SOUND_DYN(ENT(pev), CHAN_AUTO, "debris/beamstart7.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM); + if (!FBitSet(pev->spawnflags, SF_XENMAKER_NO_SOUND)) + EMIT_SOUND_DYN(ENT(pev), CHAN_AUTO, "debris/beamstart7.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM); pev->nextthink = gpGlobals->time + 0.5; SetUse(NULL); @@ -237,12 +264,15 @@ void CMXenMaker::StartEffect(void) void CMXenMaker::MiddleEffect(void) { // SPRITE EFFECT - CMSprite *pSprite = CMSprite::SpriteCreate("sprites/xflare1.spr", pev->origin, FALSE); - if (pSprite) + if (!FBitSet(pev->spawnflags, SF_XENMAKER_NO_SPRITE)) { - pSprite->SetScale(m_flEndSpriteScale); - pSprite->SetTransparency(kRenderGlow, (int)m_vEndSpriteColor.x, (int)m_vEndSpriteColor.y, (int)m_vEndSpriteColor.z, m_iEndSpriteAlpha, kRenderFxNoDissipation); - pSprite->AnimateAndDie(m_flEndSpriteFramerate); + CMSprite *pSprite = CMSprite::SpriteCreate("sprites/xflare1.spr", pev->origin, FALSE); + if (pSprite) + { + pSprite->SetScale(m_flEndSpriteScale); + pSprite->SetTransparency(kRenderGlow, (int)m_vEndSpriteColor.x, (int)m_vEndSpriteColor.y, (int)m_vEndSpriteColor.z, m_iEndSpriteAlpha, kRenderFxNoDissipation); + pSprite->AnimateAndDie(m_flEndSpriteFramerate); + } } pev->nextthink = gpGlobals->time + 0.5; @@ -255,7 +285,8 @@ void CMXenMaker::MiddleEffect(void) void CMXenMaker::EndEffect(void) { // SOUND EFFECT - EMIT_SOUND_DYN(ENT(pev), CHAN_AUTO, "debris/beamstart2.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM); + if (!FBitSet(pev->spawnflags, SF_XENMAKER_NO_SOUND)) + EMIT_SOUND_DYN(ENT(pev), CHAN_AUTO, "debris/beamstart2.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM); SetUse(&CMXenMaker::CyclicUse); SetThink(&CMXenMaker::SUB_DoNothing); diff --git a/src/dlls/zombie.cpp b/src/dlls/zombie.cpp index 6cd2c42..8909a9c 100644 --- a/src/dlls/zombie.cpp +++ b/src/dlls/zombie.cpp @@ -242,7 +242,7 @@ void CMZombie :: Spawn() pev->solid = SOLID_SLIDEBOX; pev->movetype = MOVETYPE_STEP; m_bloodColor = !m_bloodColor ? BLOOD_COLOR_YELLOW : m_bloodColor; - pev->health = gSkillData.zombieHealth; + if (!pev->health) { pev->health = gSkillData.zombieHealth; } pev->view_ofs = VEC_VIEW;// position of the eyes relative to monster's origin. m_flFieldOfView = 0.5;// indicates the width of this monster's forward view cone ( as a dotproduct result ) m_MonsterState = MONSTERSTATE_NONE;