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;