- Fix a few possible crashes.

- Fix xenmaker sprites never being removed if their framerate is 0.
- Fix xenmaker sprites never showing if their scale is 0.
- Add trigger_setcvar.
- New "health" keyvalue for monsters/monstermaker for custom health.
This commit is contained in:
Giegue
2024-01-10 16:05:40 -03:00
parent 75596ad87e
commit 9f77e10934
39 changed files with 225 additions and 65 deletions

View File

@@ -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

View File

@@ -46,6 +46,7 @@ OBJ = \
rgrunt.o \
ripent.o \
scientist.o \
setcvar.o \
shock.o \
shockroach.o \
skill.o \

View File

@@ -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;

View File

@@ -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

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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();
}
}

View File

@@ -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;

View File

@@ -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;
}
}
}

View File

@@ -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;

View File

@@ -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));

View File

@@ -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;

View File

@@ -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;

View File

@@ -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 )

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -173,6 +173,7 @@
<ClCompile Include="rgrunt.cpp" />
<ClCompile Include="ripent.cpp" />
<ClCompile Include="scientist.cpp" />
<ClCompile Include="setcvar.cpp" />
<ClCompile Include="shock.cpp" />
<ClCompile Include="shockroach.cpp" />
<ClCompile Include="skill.cpp" />

View File

@@ -189,6 +189,9 @@
<ClCompile Include="xenmaker.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="setcvar.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="activity.h">

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

68
src/dlls/setcvar.cpp Normal file
View 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);
}
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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) );

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;