Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f035b865e5 | ||
|
|
9f77e10934 | ||
|
|
75596ad87e | ||
|
|
f57c7760f7 | ||
|
|
8ed6c4eb2b | ||
|
|
c1660a0e48 |
@@ -63,7 +63,9 @@ I'm aware that the plugin is far from perfect, and there are a few things that n
|
|||||||
|
|
||||||
- Rarely, Stukabats will become unable to fly towards their target, standing in air doing seemingly nothing.
|
- Rarely, Stukabats will become unable to fly towards their target, standing in air doing seemingly nothing.
|
||||||
|
|
||||||
- Monsters are very prone to gibbing when hurt during death animations.
|
- Monsters are very prone to gibbing.
|
||||||
|
|
||||||
|
- Houndeyes and Hornets (Alien Grunts) do not get along. The server will crash if a houndeye damages a hornet.
|
||||||
|
|
||||||
There are probably more issues that aren't listed here, I'll attempt to fix them as I find them. Of course, any bug report is welcome. If reporting a bug, try to explain step by step how the bug ocurred. The easier it is to replicate a bug, the easier it is to locate it and fix it.
|
There are probably more issues that aren't listed here, I'll attempt to fix them as I find them. Of course, any bug report is welcome. If reporting a bug, try to explain step by step how the bug ocurred. The easier it is to replicate a bug, the easier it is to locate it and fix it.
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ sk_apache_health 250
|
|||||||
// Barney
|
// Barney
|
||||||
sk_barney_health 35
|
sk_barney_health 35
|
||||||
|
|
||||||
// Big Momma
|
// Big Momma (HP = 150 * health_factor)
|
||||||
sk_bigmomma_health_factor 1.5
|
sk_bigmomma_health_factor 1.5
|
||||||
sk_bigmomma_dmg_slash 60
|
sk_bigmomma_dmg_slash 60
|
||||||
sk_bigmomma_dmg_blast 120
|
sk_bigmomma_dmg_blast 120
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ OBJ = \
|
|||||||
rgrunt.o \
|
rgrunt.o \
|
||||||
ripent.o \
|
ripent.o \
|
||||||
scientist.o \
|
scientist.o \
|
||||||
|
setcvar.o \
|
||||||
shock.o \
|
shock.o \
|
||||||
shockroach.o \
|
shockroach.o \
|
||||||
skill.o \
|
skill.o \
|
||||||
@@ -60,6 +61,7 @@ OBJ = \
|
|||||||
util.o \
|
util.o \
|
||||||
voltigore.o \
|
voltigore.o \
|
||||||
weapons.o \
|
weapons.o \
|
||||||
|
xenmaker.o \
|
||||||
zombie.o
|
zombie.o
|
||||||
|
|
||||||
monster_mm_i386.so: ${OBJ}
|
monster_mm_i386.so: ${OBJ}
|
||||||
|
|||||||
@@ -543,7 +543,7 @@ void CMAGrunt :: Spawn()
|
|||||||
pev->movetype = MOVETYPE_STEP;
|
pev->movetype = MOVETYPE_STEP;
|
||||||
m_bloodColor = !m_bloodColor ? BLOOD_COLOR_YELLOW : m_bloodColor;
|
m_bloodColor = !m_bloodColor ? BLOOD_COLOR_YELLOW : m_bloodColor;
|
||||||
pev->effects = 0;
|
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_flFieldOfView = 0.2;// indicates the width of this monster's forward view cone ( as a dotproduct result )
|
||||||
m_MonsterState = MONSTERSTATE_NONE;
|
m_MonsterState = MONSTERSTATE_NONE;
|
||||||
m_afCapability = 0;
|
m_afCapability = 0;
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ void CMApache :: Spawn( void )
|
|||||||
|
|
||||||
pev->flags |= FL_MONSTER;
|
pev->flags |= FL_MONSTER;
|
||||||
pev->takedamage = DAMAGE_AIM;
|
pev->takedamage = DAMAGE_AIM;
|
||||||
pev->health = gSkillData.apacheHealth;
|
if (!pev->health) { pev->health = gSkillData.apacheHealth; }
|
||||||
|
|
||||||
m_flFieldOfView = -0.707; // 270 degrees
|
m_flFieldOfView = -0.707; // 270 degrees
|
||||||
|
|
||||||
|
|||||||
@@ -351,7 +351,7 @@ void CMBarney :: Spawn()
|
|||||||
pev->solid = SOLID_SLIDEBOX;
|
pev->solid = SOLID_SLIDEBOX;
|
||||||
pev->movetype = MOVETYPE_STEP;
|
pev->movetype = MOVETYPE_STEP;
|
||||||
m_bloodColor = !m_bloodColor ? BLOOD_COLOR_RED : m_bloodColor;
|
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.
|
pev->view_ofs = Vector ( 0, 0, 50 );// position of the eyes relative to monster's origin.
|
||||||
m_flFieldOfView = VIEW_FIELD_FULL;
|
m_flFieldOfView = VIEW_FIELD_FULL;
|
||||||
m_MonsterState = MONSTERSTATE_NONE;
|
m_MonsterState = MONSTERSTATE_NONE;
|
||||||
|
|||||||
@@ -610,7 +610,7 @@ void CMBigMomma :: Spawn()
|
|||||||
pev->solid = SOLID_SLIDEBOX;
|
pev->solid = SOLID_SLIDEBOX;
|
||||||
pev->movetype = MOVETYPE_STEP;
|
pev->movetype = MOVETYPE_STEP;
|
||||||
m_bloodColor = !m_bloodColor ? BLOOD_COLOR_YELLOW : m_bloodColor;
|
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.
|
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_flFieldOfView = 0.3;// indicates the width of this monster's forward view cone ( as a dotproduct result )
|
||||||
m_MonsterState = MONSTERSTATE_NONE;
|
m_MonsterState = MONSTERSTATE_NONE;
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ public:
|
|||||||
void EXPORT Animate( void );
|
void EXPORT Animate( void );
|
||||||
|
|
||||||
int m_maxFrame;
|
int m_maxFrame;
|
||||||
|
EHANDLE m_hOwner;
|
||||||
};
|
};
|
||||||
|
|
||||||
void CSquidSpit:: Spawn( void )
|
void CSquidSpit:: Spawn( void )
|
||||||
@@ -110,6 +111,7 @@ void CSquidSpit::Shoot( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity
|
|||||||
UTIL_SetOrigin( pSpit->pev, vecStart );
|
UTIL_SetOrigin( pSpit->pev, vecStart );
|
||||||
pSpit->pev->velocity = vecVelocity;
|
pSpit->pev->velocity = vecVelocity;
|
||||||
pSpit->pev->owner = ENT(pevOwner);
|
pSpit->pev->owner = ENT(pevOwner);
|
||||||
|
pSpit->m_hOwner = ENT(pevOwner);
|
||||||
|
|
||||||
pSpit->SetThink ( &CSquidSpit::Animate );
|
pSpit->SetThink ( &CSquidSpit::Animate );
|
||||||
pSpit->pev->nextthink = gpGlobals->time + 0.1;
|
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 )
|
void CSquidSpit :: SpitTouch ( edict_t *pOther )
|
||||||
{
|
{
|
||||||
|
if (m_hOwner == NULL)
|
||||||
|
pev->owner = NULL;
|
||||||
|
|
||||||
TraceResult tr;
|
TraceResult tr;
|
||||||
int iPitch;
|
int iPitch;
|
||||||
|
|
||||||
@@ -617,7 +622,7 @@ void CMBullsquid :: Spawn()
|
|||||||
pev->movetype = MOVETYPE_STEP;
|
pev->movetype = MOVETYPE_STEP;
|
||||||
m_bloodColor = !m_bloodColor ? BLOOD_COLOR_YELLOW : m_bloodColor;
|
m_bloodColor = !m_bloodColor ? BLOOD_COLOR_YELLOW : m_bloodColor;
|
||||||
pev->effects = 0;
|
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_flFieldOfView = 0.2;// indicates the width of this monster's forward view cone ( as a dotproduct result )
|
||||||
m_MonsterState = MONSTERSTATE_NONE;
|
m_MonsterState = MONSTERSTATE_NONE;
|
||||||
|
|
||||||
|
|||||||
@@ -48,4 +48,57 @@ public:
|
|||||||
BOOL m_fPlaying; // music is active
|
BOOL m_fPlaying; // music is active
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//=========================================================
|
||||||
|
// XenMaker - spawns a monster with a teleportation effect.
|
||||||
|
//=========================================================
|
||||||
|
class CMXenMaker : public CMBaseMonster
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void Spawn(void);
|
||||||
|
void Precache(void);
|
||||||
|
void KeyValue(KeyValueData* pkvd);
|
||||||
|
void EXPORT CyclicUse(edict_t *pActivator, edict_t *pCaller, USE_TYPE useType, float value);
|
||||||
|
void EXPORT RetryThink(void);
|
||||||
|
void StartEffect(void);
|
||||||
|
void EXPORT MiddleEffect(void);
|
||||||
|
void EXPORT EndEffect(void);
|
||||||
|
|
||||||
|
int m_iMonsterIndex;// index of the monster that will be created.
|
||||||
|
|
||||||
|
float m_flBeamRadius; // Maximum beam strike radius.
|
||||||
|
int m_iBeamAlpha;
|
||||||
|
int m_iBeamCount; // Number of single beam instances.
|
||||||
|
Vector m_vBeamColor;
|
||||||
|
|
||||||
|
float m_flLightRadius;
|
||||||
|
Vector m_vLightColor;
|
||||||
|
|
||||||
|
float m_flStartSpriteFramerate;
|
||||||
|
float m_flStartSpriteScale;
|
||||||
|
int m_iStartSpriteAlpha;
|
||||||
|
Vector m_vStartSpriteColor;
|
||||||
|
|
||||||
|
float m_flEndSpriteFramerate;
|
||||||
|
float m_flEndSpriteScale;
|
||||||
|
int m_iEndSpriteAlpha;
|
||||||
|
Vector m_vEndSpriteColor;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void SpawnBeam(void);
|
||||||
|
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
|
#endif // BASEEXTRA_H
|
||||||
|
|||||||
@@ -632,6 +632,7 @@ public:
|
|||||||
void IdleSound( void );
|
void IdleSound( void );
|
||||||
|
|
||||||
void Killed( entvars_t *pevAttacker, int iGib );
|
void Killed( entvars_t *pevAttacker, int iGib );
|
||||||
|
void UpdateOnRemove();
|
||||||
|
|
||||||
void StartTask ( Task_t *pTask );
|
void StartTask ( Task_t *pTask );
|
||||||
Schedule_t *GetSchedule( void );
|
Schedule_t *GetSchedule( void );
|
||||||
|
|||||||
@@ -974,10 +974,15 @@ int CMBaseMonster :: DeadTakeDamage( entvars_t *pevInflictor, entvars_t *pevAtta
|
|||||||
vecDir = Vector( 0, 0, 0 );
|
vecDir = Vector( 0, 0, 0 );
|
||||||
if (!FNullEnt( pevInflictor ))
|
if (!FNullEnt( pevInflictor ))
|
||||||
{
|
{
|
||||||
CMBaseMonster *pMonster = GetClassPtr((CMBaseMonster *)VARS(pevInflictor));
|
if (pevInflictor->euser4 != NULL)
|
||||||
if (pMonster)
|
|
||||||
{
|
{
|
||||||
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();
|
vecDir = g_vecAttackDir = vecDir.Normalize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -309,7 +309,7 @@ void CMController :: Spawn()
|
|||||||
pev->movetype = MOVETYPE_FLY;
|
pev->movetype = MOVETYPE_FLY;
|
||||||
pev->flags |= FL_FLY;
|
pev->flags |= FL_FLY;
|
||||||
m_bloodColor = !m_bloodColor ? BLOOD_COLOR_YELLOW : m_bloodColor;
|
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.
|
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_flFieldOfView = VIEW_FIELD_FULL;// indicates the width of this monster's forward view cone ( as a dotproduct result )
|
||||||
m_MonsterState = MONSTERSTATE_NONE;
|
m_MonsterState = MONSTERSTATE_NONE;
|
||||||
|
|||||||
@@ -166,6 +166,8 @@ monster_type_t monster_types[]=
|
|||||||
"info_node_air", FALSE,
|
"info_node_air", FALSE,
|
||||||
"monstermaker", FALSE, // Extra entities
|
"monstermaker", FALSE, // Extra entities
|
||||||
"ambient_music", FALSE,
|
"ambient_music", FALSE,
|
||||||
|
"env_xenmaker", FALSE,
|
||||||
|
"trigger_setcvar", FALSE,
|
||||||
"squadmaker", FALSE, // Aliases
|
"squadmaker", FALSE, // Aliases
|
||||||
"", FALSE
|
"", FALSE
|
||||||
};
|
};
|
||||||
@@ -711,6 +713,9 @@ edict_t* spawn_monster(int monster_type, Vector origin, Vector angles, int spawn
|
|||||||
// Extra entities
|
// Extra entities
|
||||||
case 32: monsters[monster_index].pMonster = CreateClassPtr((CMMonsterMaker *)NULL); break;
|
case 32: monsters[monster_index].pMonster = CreateClassPtr((CMMonsterMaker *)NULL); break;
|
||||||
case 33: monsters[monster_index].pMonster = CreateClassPtr((CMAmbientMusic *)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;
|
||||||
|
default: LOG_MESSAGE(PLID, "ERROR: Invalid monster type! (%i)", monster_type); return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (monsters[monster_index].pMonster == NULL)
|
if (monsters[monster_index].pMonster == NULL)
|
||||||
@@ -1239,6 +1244,28 @@ void SpawnViewerCommand(void)
|
|||||||
LOG_MESSAGE(PLID, "spawns a node viewer at the player's location");
|
LOG_MESSAGE(PLID, "spawns a node viewer at the player's location");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DebugGetEntities(void)
|
||||||
|
{
|
||||||
|
LOG_MESSAGE(PLID, "count: %i ents of max %i\n", monster_ents_used, MAX_MONSTER_ENTS);
|
||||||
|
for (int index = 0; index < MAX_MONSTER_ENTS; index++)
|
||||||
|
{
|
||||||
|
if (monsters[index].monster_index)
|
||||||
|
{
|
||||||
|
LOG_MESSAGE(PLID, "SLOT #%i:", index);
|
||||||
|
edict_t *pent = (*g_engfuncs.pfnPEntityOfEntIndex)(monsters[index].monster_index);
|
||||||
|
|
||||||
|
if (pent)
|
||||||
|
{
|
||||||
|
LOG_MESSAGE(PLID, "Class is \"%s\"\n", STRING(pent->v.classname));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG_MESSAGE(PLID, "NULL entity\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void mmGameDLLInit( void )
|
void mmGameDLLInit( void )
|
||||||
{
|
{
|
||||||
// one time initialization stuff here...
|
// one time initialization stuff here...
|
||||||
@@ -1435,11 +1462,14 @@ void mmServerActivate( edict_t *pEdictList, int edictCount, int clientMax )
|
|||||||
// Extra entities
|
// Extra entities
|
||||||
CMMonsterMaker monstermaker; // 32
|
CMMonsterMaker monstermaker; // 32
|
||||||
CMAmbientMusic ambientmusic;
|
CMAmbientMusic ambientmusic;
|
||||||
|
CMXenMaker xenmaker;
|
||||||
|
CMSetCVar setcvar;
|
||||||
|
|
||||||
g_psv_gravity = CVAR_GET_POINTER( "sv_gravity" );
|
g_psv_gravity = CVAR_GET_POINTER( "sv_gravity" );
|
||||||
|
|
||||||
(g_engfuncs.pfnAddServerCommand)("monster", MonsterCommand);
|
(g_engfuncs.pfnAddServerCommand)("monster", MonsterCommand);
|
||||||
(g_engfuncs.pfnAddServerCommand)("node_viewer", SpawnViewerCommand);
|
(g_engfuncs.pfnAddServerCommand)("node_viewer", SpawnViewerCommand);
|
||||||
|
(g_engfuncs.pfnAddServerCommand)("get_edicts", DebugGetEntities);
|
||||||
(g_engfuncs.pfnAddServerCommand)("_use", mmDispatchUse);
|
(g_engfuncs.pfnAddServerCommand)("_use", mmDispatchUse);
|
||||||
|
|
||||||
for (index = 0; monster_types[index].name[0]; index++)
|
for (index = 0; monster_types[index].name[0]; index++)
|
||||||
@@ -1485,6 +1515,8 @@ void mmServerActivate( edict_t *pEdictList, int edictCount, int clientMax )
|
|||||||
case 29: stukabat.Precache(); break;
|
case 29: stukabat.Precache(); break;
|
||||||
case 32: monstermaker.Precache(); break;
|
case 32: monstermaker.Precache(); break;
|
||||||
//case 33: ambientmusic.Precache(); break;
|
//case 33: ambientmusic.Precache(); break;
|
||||||
|
case 34: xenmaker.Precache(); break;
|
||||||
|
//case 35: setcvar.Precache(); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -332,14 +332,18 @@ void CMSprite::SpriteInit( const char *pSpriteName, const Vector &origin )
|
|||||||
CMSprite *CMSprite::SpriteCreate( const char *pSpriteName, const Vector &origin, BOOL animate )
|
CMSprite *CMSprite::SpriteCreate( const char *pSpriteName, const Vector &origin, BOOL animate )
|
||||||
{
|
{
|
||||||
CMSprite *pSprite = CreateClassPtr( (CMSprite *)NULL );
|
CMSprite *pSprite = CreateClassPtr( (CMSprite *)NULL );
|
||||||
pSprite->SpriteInit( pSpriteName, origin );
|
if (pSprite)
|
||||||
pSprite->pev->classname = MAKE_STRING("env_sprite");
|
{
|
||||||
pSprite->pev->solid = SOLID_NOT;
|
pSprite->SpriteInit(pSpriteName, origin);
|
||||||
pSprite->pev->movetype = MOVETYPE_NOCLIP;
|
pSprite->pev->classname = MAKE_STRING("env_sprite");
|
||||||
if ( animate )
|
pSprite->pev->solid = SOLID_NOT;
|
||||||
pSprite->TurnOn();
|
pSprite->pev->movetype = MOVETYPE_NOCLIP;
|
||||||
|
if (animate)
|
||||||
|
pSprite->TurnOn();
|
||||||
|
|
||||||
return pSprite;
|
return pSprite;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -79,10 +79,13 @@ public:
|
|||||||
|
|
||||||
inline void AnimateAndDie( float framerate )
|
inline void AnimateAndDie( float framerate )
|
||||||
{
|
{
|
||||||
|
pev->effects = 0;
|
||||||
SetThink(&CMSprite::AnimateUntilDead);
|
SetThink(&CMSprite::AnimateUntilDead);
|
||||||
pev->framerate = framerate;
|
pev->framerate = framerate;
|
||||||
pev->dmgtime = gpGlobals->time + (m_maxFrame / framerate);
|
pev->dmgtime = gpGlobals->time + (m_maxFrame / framerate);
|
||||||
pev->nextthink = gpGlobals->time;
|
pev->nextthink = gpGlobals->time;
|
||||||
|
m_lastTime = gpGlobals->time;
|
||||||
|
pev->frame = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EXPORT AnimateUntilDead( void );
|
void EXPORT AnimateUntilDead( void );
|
||||||
|
|||||||
@@ -97,6 +97,7 @@ void CSmoker::Spawn( void )
|
|||||||
UTIL_SetSize(pev, g_vecZero, g_vecZero );
|
UTIL_SetSize(pev, g_vecZero, g_vecZero );
|
||||||
pev->effects |= EF_NODRAW;
|
pev->effects |= EF_NODRAW;
|
||||||
pev->angles = g_vecZero;
|
pev->angles = g_vecZero;
|
||||||
|
pev->classname = MAKE_STRING("env_smoker");
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSmoker::Think( void )
|
void CSmoker::Think( void )
|
||||||
|
|||||||
@@ -684,7 +684,7 @@ void CMGargantua :: Spawn()
|
|||||||
pev->solid = SOLID_SLIDEBOX;
|
pev->solid = SOLID_SLIDEBOX;
|
||||||
pev->movetype = MOVETYPE_STEP;
|
pev->movetype = MOVETYPE_STEP;
|
||||||
m_bloodColor = !m_bloodColor ? BLOOD_COLOR_YELLOW : m_bloodColor;
|
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
|
//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_flFieldOfView = -0.2;// width of forward view cone ( as a dotproduct result )
|
||||||
m_MonsterState = MONSTERSTATE_NONE;
|
m_MonsterState = MONSTERSTATE_NONE;
|
||||||
@@ -1329,7 +1329,7 @@ void CMBabyGargantua::Spawn()
|
|||||||
pev->solid = SOLID_SLIDEBOX;
|
pev->solid = SOLID_SLIDEBOX;
|
||||||
pev->movetype = MOVETYPE_STEP;
|
pev->movetype = MOVETYPE_STEP;
|
||||||
m_bloodColor = !m_bloodColor ? BLOOD_COLOR_YELLOW : m_bloodColor;
|
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
|
//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_flFieldOfView = -0.2;// width of forward view cone ( as a dotproduct result )
|
||||||
m_MonsterState = MONSTERSTATE_NONE;
|
m_MonsterState = MONSTERSTATE_NONE;
|
||||||
|
|||||||
@@ -56,6 +56,12 @@ bool AddGlobalSound(const char *from, const char *to)
|
|||||||
{
|
{
|
||||||
if (numSounds < MAX_REPLACEMENTS)
|
if (numSounds < MAX_REPLACEMENTS)
|
||||||
{
|
{
|
||||||
|
if (from[0] == '!')
|
||||||
|
{
|
||||||
|
// sentence sounds cannot be replaced, skip.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// allocate for the first time
|
// allocate for the first time
|
||||||
if (!numSounds)
|
if (!numSounds)
|
||||||
GSR = (REPLACER*)calloc(MAX_REPLACEMENTS, sizeof(*GSR));
|
GSR = (REPLACER*)calloc(MAX_REPLACEMENTS, sizeof(*GSR));
|
||||||
|
|||||||
@@ -615,7 +615,7 @@ void CMGonome::Spawn()
|
|||||||
pev->movetype = MOVETYPE_STEP;
|
pev->movetype = MOVETYPE_STEP;
|
||||||
m_bloodColor = !m_bloodColor ? BLOOD_COLOR_YELLOW : m_bloodColor;
|
m_bloodColor = !m_bloodColor ? BLOOD_COLOR_YELLOW : m_bloodColor;
|
||||||
pev->effects = 0;
|
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_flFieldOfView = 0.2;// indicates the width of this monster's forward view cone ( as a dotproduct result )
|
||||||
m_MonsterState = MONSTERSTATE_NONE;
|
m_MonsterState = MONSTERSTATE_NONE;
|
||||||
|
|
||||||
|
|||||||
@@ -222,7 +222,7 @@ void CMHAssassin :: Spawn()
|
|||||||
pev->movetype = MOVETYPE_STEP;
|
pev->movetype = MOVETYPE_STEP;
|
||||||
m_bloodColor = !m_bloodColor ? BLOOD_COLOR_RED : m_bloodColor;
|
m_bloodColor = !m_bloodColor ? BLOOD_COLOR_RED : m_bloodColor;
|
||||||
pev->effects = 0;
|
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_flFieldOfView = VIEW_FIELD_WIDE; // indicates the width of this monster's forward view cone ( as a dotproduct result )
|
||||||
m_MonsterState = MONSTERSTATE_NONE;
|
m_MonsterState = MONSTERSTATE_NONE;
|
||||||
m_afCapability = bits_CAP_MELEE_ATTACK1 | bits_CAP_DOORS_GROUP;
|
m_afCapability = bits_CAP_MELEE_ATTACK1 | bits_CAP_DOORS_GROUP;
|
||||||
|
|||||||
@@ -254,7 +254,7 @@ void CMHeadCrab :: Spawn()
|
|||||||
pev->movetype = MOVETYPE_STEP;
|
pev->movetype = MOVETYPE_STEP;
|
||||||
m_bloodColor = !m_bloodColor ? BLOOD_COLOR_YELLOW : m_bloodColor;
|
m_bloodColor = !m_bloodColor ? BLOOD_COLOR_YELLOW : m_bloodColor;
|
||||||
pev->effects = 0;
|
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->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?
|
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_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;
|
pev->renderamt = 192;
|
||||||
UTIL_SetSize(pev, Vector(-12, -12, 0), Vector(12, 12, 24));
|
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 )
|
void CMBabyCrab :: Precache( void )
|
||||||
|
|||||||
@@ -837,7 +837,7 @@ void CMHGrunt :: Spawn()
|
|||||||
pev->movetype = MOVETYPE_STEP;
|
pev->movetype = MOVETYPE_STEP;
|
||||||
m_bloodColor = !m_bloodColor ? BLOOD_COLOR_RED : m_bloodColor;
|
m_bloodColor = !m_bloodColor ? BLOOD_COLOR_RED : m_bloodColor;
|
||||||
pev->effects = 0;
|
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_flFieldOfView = VIEW_FIELD_FULL; // indicates the width of this monster's forward view cone ( as a dotproduct result )
|
||||||
m_MonsterState = MONSTERSTATE_NONE;
|
m_MonsterState = MONSTERSTATE_NONE;
|
||||||
m_flNextGrenadeCheck = gpGlobals->time + 1;
|
m_flNextGrenadeCheck = gpGlobals->time + 1;
|
||||||
|
|||||||
@@ -131,7 +131,10 @@ int CMHornet::Classify ( void )
|
|||||||
if (UTIL_IsValidEntity(pev->owner))
|
if (UTIL_IsValidEntity(pev->owner))
|
||||||
{
|
{
|
||||||
CMBaseMonster *pOwner = GetClassPtr((CMBaseMonster *)VARS(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;
|
return CLASS_ALIEN_BIOWEAPON;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -274,7 +274,7 @@ void CMHoundeye :: Spawn()
|
|||||||
pev->movetype = MOVETYPE_STEP;
|
pev->movetype = MOVETYPE_STEP;
|
||||||
m_bloodColor = !m_bloodColor ? BLOOD_COLOR_YELLOW : m_bloodColor;
|
m_bloodColor = !m_bloodColor ? BLOOD_COLOR_YELLOW : m_bloodColor;
|
||||||
pev->effects = 0;
|
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?
|
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_flFieldOfView = 0.5;// indicates the width of this monster's forward view cone ( as a dotproduct result )
|
||||||
m_MonsterState = MONSTERSTATE_NONE;
|
m_MonsterState = MONSTERSTATE_NONE;
|
||||||
|
|||||||
@@ -201,7 +201,7 @@ void CMHWGrunt::Spawn()
|
|||||||
pev->movetype = MOVETYPE_STEP;
|
pev->movetype = MOVETYPE_STEP;
|
||||||
m_bloodColor = !m_bloodColor ? BLOOD_COLOR_RED : m_bloodColor;
|
m_bloodColor = !m_bloodColor ? BLOOD_COLOR_RED : m_bloodColor;
|
||||||
pev->effects = 0;
|
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_flFieldOfView = 0.2;// indicates the width of this monster's forward view cone ( as a dotproduct result )
|
||||||
m_MonsterState = MONSTERSTATE_NONE;
|
m_MonsterState = MONSTERSTATE_NONE;
|
||||||
//m_flNextGrenadeCheck = gpGlobals->time + 1;
|
//m_flNextGrenadeCheck = gpGlobals->time + 1;
|
||||||
|
|||||||
@@ -168,6 +168,12 @@ void CMISlave::Killed( entvars_t *pevAttacker, int iGib )
|
|||||||
CMBaseMonster::Killed( pevAttacker, iGib );
|
CMBaseMonster::Killed( pevAttacker, iGib );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CMISlave::UpdateOnRemove()
|
||||||
|
{
|
||||||
|
CMBaseMonster::UpdateOnRemove();
|
||||||
|
ClearBeams();
|
||||||
|
}
|
||||||
|
|
||||||
//=========================================================
|
//=========================================================
|
||||||
// SetYawSpeed - allows each sequence to have a different
|
// SetYawSpeed - allows each sequence to have a different
|
||||||
// turn rate associated with it.
|
// turn rate associated with it.
|
||||||
@@ -423,7 +429,7 @@ void CMISlave :: Spawn()
|
|||||||
pev->movetype = MOVETYPE_STEP;
|
pev->movetype = MOVETYPE_STEP;
|
||||||
m_bloodColor = !m_bloodColor ? BLOOD_COLOR_YELLOW : m_bloodColor;
|
m_bloodColor = !m_bloodColor ? BLOOD_COLOR_YELLOW : m_bloodColor;
|
||||||
pev->effects = 0;
|
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.
|
pev->view_ofs = Vector ( 0, 0, 64 );// position of the eyes relative to monster's origin.
|
||||||
m_flFieldOfView = 0.5;
|
m_flFieldOfView = 0.5;
|
||||||
m_MonsterState = MONSTERSTATE_NONE;
|
m_MonsterState = MONSTERSTATE_NONE;
|
||||||
|
|||||||
@@ -231,7 +231,7 @@ void CMMassn::Spawn()
|
|||||||
pev->movetype = MOVETYPE_STEP;
|
pev->movetype = MOVETYPE_STEP;
|
||||||
m_bloodColor = !m_bloodColor ? BLOOD_COLOR_RED : m_bloodColor;
|
m_bloodColor = !m_bloodColor ? BLOOD_COLOR_RED : m_bloodColor;
|
||||||
pev->effects = 0;
|
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_flFieldOfView = 0.2;// indicates the width of this monster's forward view cone ( as a dotproduct result )
|
||||||
m_MonsterState = MONSTERSTATE_NONE;
|
m_MonsterState = MONSTERSTATE_NONE;
|
||||||
m_flNextGrenadeCheck = gpGlobals->time + 1;
|
m_flNextGrenadeCheck = gpGlobals->time + 1;
|
||||||
|
|||||||
@@ -133,7 +133,6 @@ void process_monster_sound(edict_t *pMonster, char *fileName)
|
|||||||
|
|
||||||
// SC soundlist path starts from sound/MAPNAME
|
// SC soundlist path starts from sound/MAPNAME
|
||||||
sprintf(srPath, "%s/sound/%s/%s", game_dir, STRING(gpGlobals->mapname), fileName);
|
sprintf(srPath, "%s/sound/%s/%s", game_dir, STRING(gpGlobals->mapname), fileName);
|
||||||
|
|
||||||
if (access(srPath, 0) == 0)
|
if (access(srPath, 0) == 0)
|
||||||
{
|
{
|
||||||
if ((fp = fopen(srPath, "r")) != NULL)
|
if ((fp = fopen(srPath, "r")) != NULL)
|
||||||
@@ -225,6 +224,36 @@ void scan_monster_cfg(FILE *fp)
|
|||||||
monster = TRUE;
|
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
|
||||||
|
if (monster_spawn_count == MAX_MONSTERS)
|
||||||
|
{
|
||||||
|
// error.exe
|
||||||
|
LOG_MESSAGE(PLID, "ERROR: can't add monstermaker, 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, "info_node") == 0)
|
else if (strcmp(monster_types[mIndex].name, "info_node") == 0)
|
||||||
{
|
{
|
||||||
// Normal node
|
// Normal node
|
||||||
@@ -391,8 +420,8 @@ void scan_monster_cfg(FILE *fp)
|
|||||||
{
|
{
|
||||||
if (monster)
|
if (monster)
|
||||||
{
|
{
|
||||||
// this keyvalue is only valid for monstermaker entity
|
// this keyvalue is only valid for monstermaker entities
|
||||||
if (strcmp(data[kvd_index-1].value, "monstermaker") == 0 || strcmp(data[kvd_index-1].value, "squadmaker") == 0)
|
if (strcmp(data[kvd_index - 1].value, "monstermaker") == 0 || strcmp(data[kvd_index - 1].value, "squadmaker") == 0 || strcmp(data[kvd_index - 1].value, "env_xenmaker") == 0)
|
||||||
{
|
{
|
||||||
// process the entity precache here
|
// process the entity precache here
|
||||||
int mIndex;
|
int mIndex;
|
||||||
@@ -420,11 +449,11 @@ void scan_monster_cfg(FILE *fp)
|
|||||||
{
|
{
|
||||||
// precache the sound here
|
// precache the sound here
|
||||||
PRECACHE_GENERIC(data[i].value);
|
PRECACHE_GENERIC(data[i].value);
|
||||||
|
|
||||||
// the entity will need the keyvalue
|
|
||||||
strcpy(monster_spawnpoint[monster_spawn_count].keyvalue[i].key, data[i].key);
|
|
||||||
strcpy(monster_spawnpoint[monster_spawn_count].keyvalue[i].value, data[i].value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// common pev-field, an entity might need it
|
||||||
|
strcpy(monster_spawnpoint[monster_spawn_count].keyvalue[i].key, data[i].key);
|
||||||
|
strcpy(monster_spawnpoint[monster_spawn_count].keyvalue[i].value, data[i].value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -771,7 +800,7 @@ void scan_monster_bsp(void)
|
|||||||
if (monster)
|
if (monster)
|
||||||
{
|
{
|
||||||
// this keyvalue is only valid for monstermaker entity
|
// this keyvalue is only valid for monstermaker entity
|
||||||
if (strcmp(data[classname_kvdI].value, "monstermaker") == 0 || strcmp(data[classname_kvdI].value, "squadmaker") == 0)
|
if (strcmp(data[classname_kvdI].value, "monstermaker") == 0 || strcmp(data[classname_kvdI].value, "squadmaker") == 0 || strcmp(data[classname_kvdI].value, "env_xenmaker") == 0)
|
||||||
{
|
{
|
||||||
// process the entity precache here
|
// process the entity precache here
|
||||||
for (mIndex = 0; monster_types[mIndex].name[0]; mIndex++)
|
for (mIndex = 0; monster_types[mIndex].name[0]; mIndex++)
|
||||||
@@ -798,11 +827,11 @@ void scan_monster_bsp(void)
|
|||||||
{
|
{
|
||||||
// precache the sound here
|
// precache the sound here
|
||||||
PRECACHE_GENERIC(data[i].value);
|
PRECACHE_GENERIC(data[i].value);
|
||||||
|
|
||||||
// the entity will need the keyvalue
|
|
||||||
strcpy(monster_spawnpoint[monster_spawn_count].keyvalue[i].key, data[i].key);
|
|
||||||
strcpy(monster_spawnpoint[monster_spawn_count].keyvalue[i].value, data[i].value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// common pev-field, an entity might need it
|
||||||
|
strcpy(monster_spawnpoint[monster_spawn_count].keyvalue[i].key, data[i].key);
|
||||||
|
strcpy(monster_spawnpoint[monster_spawn_count].keyvalue[i].value, data[i].value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -127,6 +127,7 @@
|
|||||||
<DataExecutionPrevention>
|
<DataExecutionPrevention>
|
||||||
</DataExecutionPrevention>
|
</DataExecutionPrevention>
|
||||||
<ImportLibrary>.\Release/monster_mm.lib</ImportLibrary>
|
<ImportLibrary>.\Release/monster_mm.lib</ImportLibrary>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -172,6 +173,7 @@
|
|||||||
<ClCompile Include="rgrunt.cpp" />
|
<ClCompile Include="rgrunt.cpp" />
|
||||||
<ClCompile Include="ripent.cpp" />
|
<ClCompile Include="ripent.cpp" />
|
||||||
<ClCompile Include="scientist.cpp" />
|
<ClCompile Include="scientist.cpp" />
|
||||||
|
<ClCompile Include="setcvar.cpp" />
|
||||||
<ClCompile Include="shock.cpp" />
|
<ClCompile Include="shock.cpp" />
|
||||||
<ClCompile Include="shockroach.cpp" />
|
<ClCompile Include="shockroach.cpp" />
|
||||||
<ClCompile Include="skill.cpp" />
|
<ClCompile Include="skill.cpp" />
|
||||||
@@ -186,6 +188,7 @@
|
|||||||
<ClCompile Include="util.cpp" />
|
<ClCompile Include="util.cpp" />
|
||||||
<ClCompile Include="voltigore.cpp" />
|
<ClCompile Include="voltigore.cpp" />
|
||||||
<ClCompile Include="weapons.cpp" />
|
<ClCompile Include="weapons.cpp" />
|
||||||
|
<ClCompile Include="xenmaker.cpp" />
|
||||||
<ClCompile Include="zombie.cpp" />
|
<ClCompile Include="zombie.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -186,6 +186,12 @@
|
|||||||
<ClCompile Include="globalreplace.cpp">
|
<ClCompile Include="globalreplace.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="xenmaker.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="setcvar.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="activity.h">
|
<ClInclude Include="activity.h">
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ typedef struct
|
|||||||
CMBaseMonster *pMonster;
|
CMBaseMonster *pMonster;
|
||||||
} monster_t;
|
} monster_t;
|
||||||
|
|
||||||
#define MAX_MONSTER_ENTS 400
|
#define MAX_MONSTER_ENTS 768
|
||||||
|
|
||||||
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 200
|
#define MAX_MONSTERS 384
|
||||||
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
|
||||||
|
|||||||
@@ -25,9 +25,10 @@
|
|||||||
#include "monsters.h"
|
#include "monsters.h"
|
||||||
|
|
||||||
// Monstermaker spawnflags
|
// Monstermaker spawnflags
|
||||||
#define SF_MONSTERMAKER_START_ON 1 // start active ( if has targetname )
|
#define SF_MONSTERMAKER_START_ON 1 // start active ( if has targetname )
|
||||||
#define SF_MONSTERMAKER_CYCLIC 4 // drop one monster every time fired.
|
#define SF_MONSTERMAKER_CYCLIC 4 // drop one monster every time fired.
|
||||||
#define SF_MONSTERMAKER_MONSTERCLIP 8 // Children are blocked by monsterclip
|
#define SF_MONSTERMAKER_MONSTERCLIP 8 // Children are blocked by monsterclip
|
||||||
|
#define SF_MONSTERMAKER_PRISONER 16 // children won't attack or be attacked
|
||||||
|
|
||||||
extern monster_type_t monster_types[];
|
extern monster_type_t monster_types[];
|
||||||
extern edict_t* spawn_monster(int monster_type, Vector origin, Vector angles, int spawnflags, pKVD *keyvalue);
|
extern edict_t* spawn_monster(int monster_type, Vector origin, Vector angles, int spawnflags, pKVD *keyvalue);
|
||||||
@@ -171,7 +172,7 @@ void CMMonsterMaker::MakeMonster( void )
|
|||||||
}
|
}
|
||||||
|
|
||||||
edict_t *pent;
|
edict_t *pent;
|
||||||
pKVD keyvalue[MAX_KEYVALUES]; // sometimes, i don't know what am i doing. -Giegue
|
pKVD keyvalue[MAX_KEYVALUES];
|
||||||
int createSF = SF_MONSTER_FALL_TO_GROUND;
|
int createSF = SF_MONSTER_FALL_TO_GROUND;
|
||||||
|
|
||||||
if ( m_iMaxLiveChildren > 0 && m_cLiveChildren >= m_iMaxLiveChildren )
|
if ( m_iMaxLiveChildren > 0 && m_cLiveChildren >= m_iMaxLiveChildren )
|
||||||
@@ -205,6 +206,10 @@ void CMMonsterMaker::MakeMonster( void )
|
|||||||
if ( pev->spawnflags & SF_MONSTERMAKER_MONSTERCLIP )
|
if ( pev->spawnflags & SF_MONSTERMAKER_MONSTERCLIP )
|
||||||
createSF |= SF_MONSTER_HITMONSTERCLIP;
|
createSF |= SF_MONSTER_HITMONSTERCLIP;
|
||||||
|
|
||||||
|
// Should children be prisoner entities?
|
||||||
|
if (pev->spawnflags & SF_MONSTERMAKER_PRISONER)
|
||||||
|
createSF |= SF_MONSTER_PRISONER;
|
||||||
|
|
||||||
/* KEYVALUES */
|
/* KEYVALUES */
|
||||||
// Monster is to have a custom model?
|
// Monster is to have a custom model?
|
||||||
if ( !FStringNull( m_iszCustomModel ) )
|
if ( !FStringNull( m_iszCustomModel ) )
|
||||||
@@ -247,6 +252,12 @@ void CMMonsterMaker::MakeMonster( void )
|
|||||||
strcpy(keyvalue[6].key, "classify");
|
strcpy(keyvalue[6].key, "classify");
|
||||||
sprintf(keyvalue[6].value, "%i", m_iClassifyOverride);
|
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
|
// Attempt to spawn monster
|
||||||
pent = spawn_monster(m_iMonsterIndex, pev->origin, pev->angles, createSF, keyvalue);
|
pent = spawn_monster(m_iMonsterIndex, pev->origin, pev->angles, createSF, keyvalue);
|
||||||
@@ -278,13 +289,13 @@ void CMMonsterMaker::MakeMonster( void )
|
|||||||
pent->v.rendercolor = pev->rendercolor;
|
pent->v.rendercolor = pev->rendercolor;
|
||||||
|
|
||||||
// Soundlist isn't "exactly" a keyvalue so pass it here
|
// Soundlist isn't "exactly" a keyvalue so pass it here
|
||||||
if ( m_srSoundList != NULL )
|
if (m_srSoundList != NULL)
|
||||||
{
|
{
|
||||||
// it needs to be allocated first
|
// it needs to be allocated first
|
||||||
CMBaseMonster *pChild = GetClassPtr((CMBaseMonster *)VARS(pent));
|
CMBaseMonster *pChild = GetClassPtr((CMBaseMonster *)VARS(pent));
|
||||||
pChild->m_srSoundList = (REPLACER::REPLACER*)calloc(MAX_REPLACEMENTS, sizeof(*pChild->m_srSoundList));
|
pChild->m_srSoundList = (REPLACER::REPLACER*)calloc(MAX_REPLACEMENTS, sizeof(*pChild->m_srSoundList));
|
||||||
|
|
||||||
memcpy(pChild->m_srSoundList, m_srSoundList, sizeof(REPLACER::REPLACER));
|
memcpy(pChild->m_srSoundList, m_srSoundList, m_isrSounds * sizeof(*pChild->m_srSoundList));
|
||||||
pChild->m_isrSounds = m_isrSounds;
|
pChild->m_isrSounds = m_isrSounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ void CMOtis::Spawn()
|
|||||||
pev->solid = SOLID_SLIDEBOX;
|
pev->solid = SOLID_SLIDEBOX;
|
||||||
pev->movetype = MOVETYPE_STEP;
|
pev->movetype = MOVETYPE_STEP;
|
||||||
m_bloodColor = !m_bloodColor ? BLOOD_COLOR_RED : m_bloodColor;
|
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.
|
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_flFieldOfView = VIEW_FIELD_WIDE; // NOTE: we need a wide field of view so npc will notice player and say hello
|
||||||
m_MonsterState = MONSTERSTATE_NONE;
|
m_MonsterState = MONSTERSTATE_NONE;
|
||||||
|
|||||||
@@ -578,7 +578,7 @@ void CMPitdrone::Spawn()
|
|||||||
pev->movetype = MOVETYPE_STEP;
|
pev->movetype = MOVETYPE_STEP;
|
||||||
m_bloodColor = !m_bloodColor ? BLOOD_COLOR_YELLOW : m_bloodColor;
|
m_bloodColor = !m_bloodColor ? BLOOD_COLOR_YELLOW : m_bloodColor;
|
||||||
pev->effects = 0;
|
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_flFieldOfView = 0.2;// indicates the width of this monster's forward view cone ( as a dotproduct result )
|
||||||
m_MonsterState = MONSTERSTATE_NONE;
|
m_MonsterState = MONSTERSTATE_NONE;
|
||||||
|
|
||||||
|
|||||||
@@ -324,7 +324,7 @@ void CMRGrunt::Spawn()
|
|||||||
pev->movetype = MOVETYPE_STEP;
|
pev->movetype = MOVETYPE_STEP;
|
||||||
m_bloodColor = DONT_BLEED;
|
m_bloodColor = DONT_BLEED;
|
||||||
pev->effects = 0;
|
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
|
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_flFieldOfView = 0.2;// indicates the width of this monster's forward view cone ( as a dotproduct result )
|
||||||
m_MonsterState = MONSTERSTATE_NONE;
|
m_MonsterState = MONSTERSTATE_NONE;
|
||||||
|
|||||||
@@ -602,7 +602,7 @@ void CMScientist :: Spawn( void )
|
|||||||
pev->solid = SOLID_SLIDEBOX;
|
pev->solid = SOLID_SLIDEBOX;
|
||||||
pev->movetype = MOVETYPE_STEP;
|
pev->movetype = MOVETYPE_STEP;
|
||||||
m_bloodColor = !m_bloodColor ? BLOOD_COLOR_RED : m_bloodColor;
|
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.
|
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_flFieldOfView = VIEW_FIELD_WIDE; // NOTE: we need a wide field of view so scientists will notice player and say hello
|
||||||
m_MonsterState = MONSTERSTATE_NONE;
|
m_MonsterState = MONSTERSTATE_NONE;
|
||||||
|
|||||||
68
src/dlls/setcvar.cpp
Normal file
68
src/dlls/setcvar.cpp
Normal file
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -107,7 +107,7 @@ void CMSporeGrenade::Explode(TraceResult *pTrace)
|
|||||||
|
|
||||||
pev->owner = NULL; // can't traceline attack owner if this is set
|
pev->owner = NULL; // can't traceline attack owner if this is set
|
||||||
|
|
||||||
RadiusDamage(pev, pevOwner, pev->dmg, CLASS_NONE, DMG_BLAST);
|
RadiusDamage(pev, pevOwner, pev->dmg, CLASS_NONE, DMG_BLAST | DMG_POISON);
|
||||||
|
|
||||||
// Place a decal on the surface that was hit.
|
// Place a decal on the surface that was hit.
|
||||||
UTIL_DecalTrace(pTrace, DECAL_SPIT1 + RANDOM_LONG(0, 1));
|
UTIL_DecalTrace(pTrace, DECAL_SPIT1 + RANDOM_LONG(0, 1));
|
||||||
|
|||||||
@@ -369,7 +369,7 @@ void CMStrooper::Spawn()
|
|||||||
pev->movetype = MOVETYPE_STEP;
|
pev->movetype = MOVETYPE_STEP;
|
||||||
m_bloodColor = !m_bloodColor ? BLOOD_COLOR_YELLOW : m_bloodColor;
|
m_bloodColor = !m_bloodColor ? BLOOD_COLOR_YELLOW : m_bloodColor;
|
||||||
pev->effects = 0;
|
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_flFieldOfView = 0.2;// indicates the width of this monster's forward view cone ( as a dotproduct result )
|
||||||
m_MonsterState = MONSTERSTATE_NONE;
|
m_MonsterState = MONSTERSTATE_NONE;
|
||||||
m_flNextGrenadeCheck = gpGlobals->time + 1;
|
m_flNextGrenadeCheck = gpGlobals->time + 1;
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ void CMStukabat :: Spawn()
|
|||||||
pev->movetype = MOVETYPE_FLY;
|
pev->movetype = MOVETYPE_FLY;
|
||||||
pev->flags |= FL_FLY;
|
pev->flags |= FL_FLY;
|
||||||
m_bloodColor = !m_bloodColor ? BLOOD_COLOR_YELLOW : m_bloodColor;
|
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.
|
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_flFieldOfView = 0.5;// indicates the width of this monster's forward view cone ( as a dotproduct result )
|
||||||
m_MonsterState = MONSTERSTATE_NONE;
|
m_MonsterState = MONSTERSTATE_NONE;
|
||||||
|
|||||||
@@ -226,7 +226,7 @@ void CMBaseDelay :: SUB_UseTargets( edict_t *pActivator, USE_TYPE useType, float
|
|||||||
pentKillTarget = FIND_ENTITY_BY_TARGETNAME( NULL, STRING(m_iszKillTarget) );
|
pentKillTarget = FIND_ENTITY_BY_TARGETNAME( NULL, STRING(m_iszKillTarget) );
|
||||||
while ( !FNullEnt(pentKillTarget) )
|
while ( !FNullEnt(pentKillTarget) )
|
||||||
{
|
{
|
||||||
UTIL_Remove( CMBaseEntity::Instance(pentKillTarget)->edict() );
|
UTIL_Remove( pentKillTarget );
|
||||||
|
|
||||||
ALERT( at_aiconsole, "killing %s\n", STRING( pentKillTarget->v.classname ) );
|
ALERT( at_aiconsole, "killing %s\n", STRING( pentKillTarget->v.classname ) );
|
||||||
pentKillTarget = FIND_ENTITY_BY_TARGETNAME( pentKillTarget, STRING(m_iszKillTarget) );
|
pentKillTarget = FIND_ENTITY_BY_TARGETNAME( pentKillTarget, STRING(m_iszKillTarget) );
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ void CMTurret::Spawn()
|
|||||||
{
|
{
|
||||||
Precache( );
|
Precache( );
|
||||||
SET_MODEL(ENT(pev), (!FStringNull( pev->model ) ? STRING( pev->model ) : "models/turret.mdl"));
|
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_HackedGunPos = Vector( 0, 0, 12.75 );
|
||||||
m_flMaxSpin = TURRET_MAXSPIN;
|
m_flMaxSpin = TURRET_MAXSPIN;
|
||||||
pev->view_ofs.z = 12.75;
|
pev->view_ofs.z = 12.75;
|
||||||
@@ -165,7 +165,7 @@ void CMMiniTurret::Spawn()
|
|||||||
{
|
{
|
||||||
Precache( );
|
Precache( );
|
||||||
SET_MODEL(ENT(pev), (!FStringNull( pev->model ) ? STRING( pev->model ) : "models/miniturret.mdl"));
|
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_HackedGunPos = Vector( 0, 0, 12.75 );
|
||||||
m_flMaxSpin = 0;
|
m_flMaxSpin = 0;
|
||||||
pev->view_ofs.z = 12.75;
|
pev->view_ofs.z = 12.75;
|
||||||
@@ -1019,7 +1019,7 @@ void CMSentry::Spawn()
|
|||||||
{
|
{
|
||||||
Precache( );
|
Precache( );
|
||||||
SET_MODEL(ENT(pev), (!FStringNull( pev->model ) ? STRING( pev->model ) : "models/sentry.mdl"));
|
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 );
|
m_HackedGunPos = Vector( 0, 0, 48 );
|
||||||
pev->view_ofs.z = 48;
|
pev->view_ofs.z = 48;
|
||||||
m_flMaxWait = 1E6;
|
m_flMaxWait = 1E6;
|
||||||
|
|||||||
@@ -1564,9 +1564,9 @@ void UTIL_Remove( edict_t *pEntity )
|
|||||||
if ( !pEntity )
|
if ( !pEntity )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//jlb pEntity->UpdateOnRemove();
|
//pEntity->UpdateOnRemove();
|
||||||
pEntity->v.flags |= FL_KILLME;
|
|
||||||
pEntity->v.targetname = 0;
|
pEntity->v.targetname = 0;
|
||||||
|
pEntity->v.flags |= FL_KILLME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -644,7 +644,7 @@ void CMVoltigore::Spawn()
|
|||||||
pev->movetype = MOVETYPE_STEP;
|
pev->movetype = MOVETYPE_STEP;
|
||||||
m_bloodColor = !m_bloodColor ? BLOOD_COLOR_YELLOW : m_bloodColor;
|
m_bloodColor = !m_bloodColor ? BLOOD_COLOR_YELLOW : m_bloodColor;
|
||||||
pev->effects = 0;
|
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_flFieldOfView = 0.2;// indicates the width of this monster's forward view cone ( as a dotproduct result )
|
||||||
m_MonsterState = MONSTERSTATE_NONE;
|
m_MonsterState = MONSTERSTATE_NONE;
|
||||||
|
|
||||||
@@ -1152,7 +1152,7 @@ void CMBabyVoltigore::Spawn()
|
|||||||
pev->movetype = MOVETYPE_STEP;
|
pev->movetype = MOVETYPE_STEP;
|
||||||
m_bloodColor = !m_bloodColor ? BLOOD_COLOR_YELLOW : m_bloodColor;
|
m_bloodColor = !m_bloodColor ? BLOOD_COLOR_YELLOW : m_bloodColor;
|
||||||
pev->effects = 0;
|
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_flFieldOfView = 0.2;// indicates the width of this monster's forward view cone ( as a dotproduct result )
|
||||||
m_MonsterState = MONSTERSTATE_NONE;
|
m_MonsterState = MONSTERSTATE_NONE;
|
||||||
|
|
||||||
|
|||||||
377
src/dlls/xenmaker.cpp
Normal file
377
src/dlls/xenmaker.cpp
Normal file
@@ -0,0 +1,377 @@
|
|||||||
|
//=========================================================
|
||||||
|
// Xen Maker - Sven Co-op's env_xenmaker.
|
||||||
|
// Spawns a monster with visual/auditive teleportation effects.
|
||||||
|
//=========================================================
|
||||||
|
|
||||||
|
#include "extdll.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "cmbase.h"
|
||||||
|
#include "cmbasemonster.h"
|
||||||
|
#include "cmbaseextra.h"
|
||||||
|
#include "monsters.h"
|
||||||
|
|
||||||
|
// Xenmaker spawnflags
|
||||||
|
#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);
|
||||||
|
|
||||||
|
|
||||||
|
// ========================================================
|
||||||
|
void CMXenMaker::KeyValue(KeyValueData *pkvd)
|
||||||
|
{
|
||||||
|
if (FStrEq(pkvd->szKeyName, "monstertype"))
|
||||||
|
{
|
||||||
|
// Process monster_index
|
||||||
|
int mIndex;
|
||||||
|
for (mIndex = 0; monster_types[mIndex].name[0]; mIndex++)
|
||||||
|
{
|
||||||
|
if (strcmp(pkvd->szValue, monster_types[mIndex].name) == 0)
|
||||||
|
{
|
||||||
|
m_iMonsterIndex = mIndex;
|
||||||
|
break; // grab the first entry we find
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (monster_types[mIndex].name[0] == 0)
|
||||||
|
{
|
||||||
|
ALERT(at_console, "[MONSTER] XenMaker - %s is not a valid monster type!\n", pkvd->szValue);
|
||||||
|
m_iMonsterIndex = -1;
|
||||||
|
}
|
||||||
|
pkvd->fHandled = TRUE;
|
||||||
|
}
|
||||||
|
else if (FStrEq(pkvd->szKeyName, "m_flBeamRadius"))
|
||||||
|
{
|
||||||
|
m_flBeamRadius = atof(pkvd->szValue);
|
||||||
|
pkvd->fHandled = TRUE;
|
||||||
|
}
|
||||||
|
else if (FStrEq(pkvd->szKeyName, "m_iBeamAlpha"))
|
||||||
|
{
|
||||||
|
m_iBeamAlpha = atoi(pkvd->szValue);
|
||||||
|
pkvd->fHandled = TRUE;
|
||||||
|
}
|
||||||
|
else if (FStrEq(pkvd->szKeyName, "m_iBeamCount"))
|
||||||
|
{
|
||||||
|
m_iBeamCount = atoi(pkvd->szValue);
|
||||||
|
pkvd->fHandled = TRUE;
|
||||||
|
}
|
||||||
|
else if (FStrEq(pkvd->szKeyName, "m_vBeamColor"))
|
||||||
|
{
|
||||||
|
UTIL_StringToVector(m_vBeamColor, pkvd->szValue);
|
||||||
|
pkvd->fHandled = TRUE;
|
||||||
|
}
|
||||||
|
else if (FStrEq(pkvd->szKeyName, "m_flLightRadius"))
|
||||||
|
{
|
||||||
|
m_flLightRadius = atof(pkvd->szValue);
|
||||||
|
pkvd->fHandled = TRUE;
|
||||||
|
}
|
||||||
|
else if (FStrEq(pkvd->szKeyName, "m_vLightColor"))
|
||||||
|
{
|
||||||
|
UTIL_StringToVector(m_vLightColor, pkvd->szValue);
|
||||||
|
pkvd->fHandled = TRUE;
|
||||||
|
}
|
||||||
|
else if (FStrEq(pkvd->szKeyName, "m_flStartSpriteFramerate"))
|
||||||
|
{
|
||||||
|
m_flStartSpriteFramerate = atof(pkvd->szValue);
|
||||||
|
pkvd->fHandled = TRUE;
|
||||||
|
}
|
||||||
|
else if (FStrEq(pkvd->szKeyName, "m_flStartSpriteScale"))
|
||||||
|
{
|
||||||
|
m_flStartSpriteScale = atof(pkvd->szValue);
|
||||||
|
pkvd->fHandled = TRUE;
|
||||||
|
}
|
||||||
|
else if (FStrEq(pkvd->szKeyName, "m_iStartSpriteAlpha"))
|
||||||
|
{
|
||||||
|
m_iStartSpriteAlpha = atoi(pkvd->szValue);
|
||||||
|
pkvd->fHandled = TRUE;
|
||||||
|
}
|
||||||
|
else if (FStrEq(pkvd->szKeyName, "m_vStartSpriteColor"))
|
||||||
|
{
|
||||||
|
UTIL_StringToVector(m_vStartSpriteColor, pkvd->szValue);
|
||||||
|
pkvd->fHandled = TRUE;
|
||||||
|
}
|
||||||
|
else if (FStrEq(pkvd->szKeyName, "m_flEndSpriteFramerate"))
|
||||||
|
{
|
||||||
|
m_flEndSpriteFramerate = atof(pkvd->szValue);
|
||||||
|
pkvd->fHandled = TRUE;
|
||||||
|
}
|
||||||
|
else if (FStrEq(pkvd->szKeyName, "m_flEndSpriteScale"))
|
||||||
|
{
|
||||||
|
m_flEndSpriteScale = atof(pkvd->szValue);
|
||||||
|
pkvd->fHandled = TRUE;
|
||||||
|
}
|
||||||
|
else if (FStrEq(pkvd->szKeyName, "m_iEndSpriteAlpha"))
|
||||||
|
{
|
||||||
|
m_iEndSpriteAlpha = atoi(pkvd->szValue);
|
||||||
|
pkvd->fHandled = TRUE;
|
||||||
|
}
|
||||||
|
else if (FStrEq(pkvd->szKeyName, "m_vEndSpriteColor"))
|
||||||
|
{
|
||||||
|
UTIL_StringToVector(m_vEndSpriteColor, pkvd->szValue);
|
||||||
|
pkvd->fHandled = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
CMBaseMonster::KeyValue(pkvd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CMXenMaker::Spawn()
|
||||||
|
{
|
||||||
|
// likely omitted keyvalue, but it could truly be an alien grunt spawn
|
||||||
|
if (m_iMonsterIndex == 0)
|
||||||
|
{
|
||||||
|
if (!monster_types[0].need_to_precache)
|
||||||
|
{
|
||||||
|
// monstertype was not defined, it may be intentional if nothing is to spawn here
|
||||||
|
if (!FBitSet(pev->spawnflags, SF_XENMAKER_NO_SPAWN))
|
||||||
|
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();
|
||||||
|
|
||||||
|
SetUse(&CMXenMaker::CyclicUse); // drop one monster each time we fire
|
||||||
|
SetThink(&CMXenMaker::SUB_DoNothing);
|
||||||
|
|
||||||
|
pev->classname = MAKE_STRING("env_xenmaker");
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMXenMaker::Precache(void)
|
||||||
|
{
|
||||||
|
m_iBeamIndex = PRECACHE_MODELINDEX("sprites/lgtning.spr");
|
||||||
|
PRECACHE_MODEL("sprites/fexplo1.spr");
|
||||||
|
PRECACHE_MODEL("sprites/xflare1.spr");
|
||||||
|
|
||||||
|
PRECACHE_SOUND("debris/beamstart7.wav");
|
||||||
|
PRECACHE_SOUND("debris/beamstart2.wav");
|
||||||
|
|
||||||
|
CMBaseMonster::Precache();
|
||||||
|
// choosen monster is auto-precached
|
||||||
|
}
|
||||||
|
|
||||||
|
//=========================================================
|
||||||
|
// StartEffect - spawns the monster and starts the effects
|
||||||
|
//=========================================================
|
||||||
|
void CMXenMaker::StartEffect(void)
|
||||||
|
{
|
||||||
|
if (!FBitSet(pev->spawnflags, SF_XENMAKER_NO_SPAWN))
|
||||||
|
{
|
||||||
|
// monstermaker incorrectly setup
|
||||||
|
if (m_iMonsterIndex == -1)
|
||||||
|
{
|
||||||
|
ALERT(at_console, "[MONSTER] NULL Ent in XenMaker!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
edict_t *pent;
|
||||||
|
|
||||||
|
Vector mins = pev->origin - Vector(34, 34, 34);
|
||||||
|
Vector maxs = pev->origin + Vector(34, 34, 34);
|
||||||
|
|
||||||
|
edict_t *pList[2];
|
||||||
|
int count = UTIL_EntitiesInBox(pList, 2, mins, maxs, FL_CLIENT | FL_MONSTER);
|
||||||
|
if (!count)
|
||||||
|
{
|
||||||
|
// Attempt to spawn monster
|
||||||
|
pent = spawn_monster(m_iMonsterIndex, pev->origin, pev->angles, 0, NULL);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
else if (!FBitSet(pev->spawnflags, SF_XENMAKER_TRY_ONCE))
|
||||||
|
{
|
||||||
|
// wait until spawnpoint is clear
|
||||||
|
pev->nextthink = gpGlobals->time + 1;
|
||||||
|
SetUse(NULL);
|
||||||
|
SetThink(&CMXenMaker::RetryThink);
|
||||||
|
return; // don't do effects
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// no effects here, either
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// BEAM EFFECT
|
||||||
|
if (!FBitSet(pev->spawnflags, SF_XENMAKER_NO_BEAMS))
|
||||||
|
{
|
||||||
|
for (int beam = 0; beam < m_iBeamCount; beam++)
|
||||||
|
{
|
||||||
|
SpawnBeam();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// LIGHT EFFECT
|
||||||
|
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
|
||||||
|
if (!FBitSet(pev->spawnflags, SF_XENMAKER_NO_SPRITE))
|
||||||
|
{
|
||||||
|
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
|
||||||
|
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);
|
||||||
|
SetThink(&CMXenMaker::MiddleEffect);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=========================================================
|
||||||
|
// MiddleEffect - second set of effects
|
||||||
|
//=========================================================
|
||||||
|
void CMXenMaker::MiddleEffect(void)
|
||||||
|
{
|
||||||
|
// SPRITE EFFECT
|
||||||
|
if (!FBitSet(pev->spawnflags, SF_XENMAKER_NO_SPRITE))
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
SetThink(&CMXenMaker::EndEffect);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=========================================================
|
||||||
|
// EndEffect - final set of effects
|
||||||
|
//=========================================================
|
||||||
|
void CMXenMaker::EndEffect(void)
|
||||||
|
{
|
||||||
|
// SOUND EFFECT
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=========================================================
|
||||||
|
// CyclicUse - drops one monster from the xen maker
|
||||||
|
// each time we call this.
|
||||||
|
//=========================================================
|
||||||
|
void CMXenMaker::CyclicUse(edict_t *pActivator, edict_t *pCaller, USE_TYPE useType, float value)
|
||||||
|
{
|
||||||
|
StartEffect();
|
||||||
|
}
|
||||||
|
|
||||||
|
//=========================================================
|
||||||
|
// RetryThink - try spawning again if spawn was obstructed
|
||||||
|
//=========================================================
|
||||||
|
void CMXenMaker::RetryThink(void)
|
||||||
|
{
|
||||||
|
SetUse(&CMXenMaker::CyclicUse);
|
||||||
|
SetThink(&CMXenMaker::SUB_DoNothing);
|
||||||
|
|
||||||
|
StartEffect();
|
||||||
|
}
|
||||||
|
|
||||||
|
//=========================================================
|
||||||
|
// SpawnBeam - calculates beam end position and creates it.
|
||||||
|
// starting position is the origin of the xenmaker itself.
|
||||||
|
//=========================================================
|
||||||
|
void CMXenMaker::SpawnBeam(void)
|
||||||
|
{
|
||||||
|
// CLightning::RandomArea
|
||||||
|
for (int iLoops = 0; iLoops < 10; iLoops++)
|
||||||
|
{
|
||||||
|
Vector vecSrc = pev->origin;
|
||||||
|
|
||||||
|
Vector vecDir1 = Vector(RANDOM_FLOAT(-1.0, 1.0), RANDOM_FLOAT(-1.0, 1.0), RANDOM_FLOAT(-1.0, 1.0));
|
||||||
|
vecDir1 = vecDir1.Normalize();
|
||||||
|
TraceResult tr1;
|
||||||
|
UTIL_TraceLine(vecSrc, vecSrc + vecDir1 * m_flBeamRadius, ignore_monsters, ENT(pev), &tr1);
|
||||||
|
|
||||||
|
if (tr1.flFraction == 1.0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Vector vecDir2;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
vecDir2 = Vector(RANDOM_FLOAT(-1.0, 1.0), RANDOM_FLOAT(-1.0, 1.0), RANDOM_FLOAT(-1.0, 1.0));
|
||||||
|
} while (DotProduct(vecDir1, vecDir2) > 0);
|
||||||
|
vecDir2 = vecDir2.Normalize();
|
||||||
|
TraceResult tr2;
|
||||||
|
UTIL_TraceLine(vecSrc, vecSrc + vecDir2 * m_flBeamRadius, ignore_monsters, ENT(pev), &tr2);
|
||||||
|
|
||||||
|
if (tr2.flFraction == 1.0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ((tr1.vecEndPos - tr2.vecEndPos).Length() < m_flBeamRadius * 0.1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
UTIL_TraceLine(tr1.vecEndPos, tr2.vecEndPos, ignore_monsters, ENT(pev), &tr2);
|
||||||
|
|
||||||
|
if (tr2.flFraction != 1.0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// CLightning::Zap
|
||||||
|
MESSAGE_BEGIN(MSG_BROADCAST, SVC_TEMPENTITY);
|
||||||
|
WRITE_BYTE(TE_BEAMPOINTS);
|
||||||
|
WRITE_COORD(tr1.vecEndPos.x);
|
||||||
|
WRITE_COORD(tr1.vecEndPos.y);
|
||||||
|
WRITE_COORD(tr1.vecEndPos.z);
|
||||||
|
WRITE_COORD(tr2.vecEndPos.x);
|
||||||
|
WRITE_COORD(tr2.vecEndPos.y);
|
||||||
|
WRITE_COORD(tr2.vecEndPos.z);
|
||||||
|
WRITE_SHORT(m_iBeamIndex);
|
||||||
|
WRITE_BYTE(0); // starting frame
|
||||||
|
WRITE_BYTE(10); // framerate
|
||||||
|
WRITE_BYTE(10); // life
|
||||||
|
WRITE_BYTE(16); // width
|
||||||
|
WRITE_BYTE(64); // noise
|
||||||
|
WRITE_BYTE((int)m_vBeamColor.x);
|
||||||
|
WRITE_BYTE((int)m_vBeamColor.y);
|
||||||
|
WRITE_BYTE((int)m_vBeamColor.z);
|
||||||
|
WRITE_BYTE(m_iBeamAlpha);
|
||||||
|
WRITE_BYTE(15); // speed
|
||||||
|
MESSAGE_END();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -242,7 +242,7 @@ void CMZombie :: Spawn()
|
|||||||
pev->solid = SOLID_SLIDEBOX;
|
pev->solid = SOLID_SLIDEBOX;
|
||||||
pev->movetype = MOVETYPE_STEP;
|
pev->movetype = MOVETYPE_STEP;
|
||||||
m_bloodColor = !m_bloodColor ? BLOOD_COLOR_YELLOW : m_bloodColor;
|
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.
|
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_flFieldOfView = 0.5;// indicates the width of this monster's forward view cone ( as a dotproduct result )
|
||||||
m_MonsterState = MONSTERSTATE_NONE;
|
m_MonsterState = MONSTERSTATE_NONE;
|
||||||
|
|||||||
Reference in New Issue
Block a user