Add env_xenmaker entity.
This commit is contained in:
@@ -60,6 +60,7 @@ OBJ = \
|
||||
util.o \
|
||||
voltigore.o \
|
||||
weapons.o \
|
||||
xenmaker.o \
|
||||
zombie.o
|
||||
|
||||
monster_mm_i386.so: ${OBJ}
|
||||
|
||||
@@ -48,4 +48,46 @@ public:
|
||||
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_flGround; // z coord of the ground under me, used to make sure no monsters are under the spawner
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
#endif // BASEEXTRA_H
|
||||
|
||||
@@ -166,6 +166,7 @@ monster_type_t monster_types[]=
|
||||
"info_node_air", FALSE,
|
||||
"monstermaker", FALSE, // Extra entities
|
||||
"ambient_music", FALSE,
|
||||
"env_xenmaker", FALSE,
|
||||
"squadmaker", FALSE, // Aliases
|
||||
"", FALSE
|
||||
};
|
||||
@@ -711,6 +712,7 @@ edict_t* spawn_monster(int monster_type, Vector origin, Vector angles, int spawn
|
||||
// Extra entities
|
||||
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;
|
||||
}
|
||||
|
||||
if (monsters[monster_index].pMonster == NULL)
|
||||
@@ -1435,7 +1437,8 @@ void mmServerActivate( edict_t *pEdictList, int edictCount, int clientMax )
|
||||
// Extra entities
|
||||
CMMonsterMaker monstermaker; // 32
|
||||
CMAmbientMusic ambientmusic;
|
||||
|
||||
CMXenMaker xenmaker;
|
||||
|
||||
g_psv_gravity = CVAR_GET_POINTER( "sv_gravity" );
|
||||
|
||||
(g_engfuncs.pfnAddServerCommand)("monster", MonsterCommand);
|
||||
@@ -1485,6 +1488,7 @@ void mmServerActivate( edict_t *pEdictList, int edictCount, int clientMax )
|
||||
case 29: stukabat.Precache(); break;
|
||||
case 32: monstermaker.Precache(); break;
|
||||
//case 33: ambientmusic.Precache(); break;
|
||||
case 34: xenmaker.Precache(); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,6 +225,22 @@ void scan_monster_cfg(FILE *fp)
|
||||
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)
|
||||
{
|
||||
// Normal node
|
||||
@@ -391,8 +407,8 @@ void scan_monster_cfg(FILE *fp)
|
||||
{
|
||||
if (monster)
|
||||
{
|
||||
// this keyvalue is only valid for monstermaker entity
|
||||
if (strcmp(data[kvd_index-1].value, "monstermaker") == 0 || strcmp(data[kvd_index-1].value, "squadmaker") == 0)
|
||||
// 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 || strcmp(data[kvd_index - 1].value, "env_xenmaker") == 0)
|
||||
{
|
||||
// process the entity precache here
|
||||
int mIndex;
|
||||
@@ -771,7 +787,7 @@ void scan_monster_bsp(void)
|
||||
if (monster)
|
||||
{
|
||||
// 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
|
||||
for (mIndex = 0; monster_types[mIndex].name[0]; mIndex++)
|
||||
|
||||
@@ -127,6 +127,7 @@
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
<ImportLibrary>.\Release/monster_mm.lib</ImportLibrary>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
@@ -186,6 +187,7 @@
|
||||
<ClCompile Include="util.cpp" />
|
||||
<ClCompile Include="voltigore.cpp" />
|
||||
<ClCompile Include="weapons.cpp" />
|
||||
<ClCompile Include="xenmaker.cpp" />
|
||||
<ClCompile Include="zombie.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@@ -224,4 +226,4 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -186,6 +186,9 @@
|
||||
<ClCompile Include="globalreplace.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="xenmaker.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="activity.h">
|
||||
@@ -282,4 +285,4 @@
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
356
src/dlls/xenmaker.cpp
Normal file
356
src/dlls/xenmaker.cpp
Normal file
@@ -0,0 +1,356 @@
|
||||
//=========================================================
|
||||
// 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
|
||||
|
||||
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_logged, "[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_logged, "[MONSTER] Spawned a env_xenmaker entity without a monstertype! targetname: \"%s\"\n", STRING(pev->targetname));
|
||||
m_iMonsterIndex = -1;
|
||||
}
|
||||
}
|
||||
|
||||
pev->solid = SOLID_NOT;
|
||||
|
||||
Precache();
|
||||
|
||||
SetUse(&CMXenMaker::CyclicUse); // drop one monster each time we fire
|
||||
SetThink(&CMXenMaker::SUB_DoNothing);
|
||||
|
||||
m_flGround = 0;
|
||||
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 (!m_flGround)
|
||||
{
|
||||
// setup altitude
|
||||
TraceResult tr;
|
||||
|
||||
UTIL_TraceLine(pev->origin, pev->origin - Vector(0, 0, 2048), ignore_monsters, ENT(pev), &tr);
|
||||
m_flGround = tr.vecEndPos.z;
|
||||
}
|
||||
|
||||
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, 0);
|
||||
Vector maxs = pev->origin + Vector(34, 34, 0);
|
||||
maxs.z = pev->origin.z;
|
||||
mins.z = m_flGround;
|
||||
|
||||
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, SF_MONSTER_FALL_TO_GROUND, NULL);
|
||||
if (pent == NULL)
|
||||
{
|
||||
ALERT(at_console, "[MONSTER] XenMaker - failed to spawn monster! targetname: \"%s\"\n", STRING(pev->targetname));
|
||||
}
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
// BEAM EFFECT
|
||||
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();
|
||||
|
||||
// SPRITE EFFECT
|
||||
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);
|
||||
|
||||
pev->nextthink = gpGlobals->time + 0.5;
|
||||
SetUse(NULL);
|
||||
SetThink(&CMXenMaker::MiddleEffect);
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// MiddleEffect - second set of effects
|
||||
//=========================================================
|
||||
void CMXenMaker::MiddleEffect(void)
|
||||
{
|
||||
// SPRITE EFFECT
|
||||
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
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user