Compare commits

...

8 Commits

19 changed files with 264 additions and 30 deletions

View File

@ -0,0 +1,26 @@
entityDef info_player_start
{
editor_mins "-16 -16 -36"
editor_maxs "16 16 36"
editor_description "Singleplayer Spawn Point"
spawnclass NSSpawnPoint
}
entityDef info_player_deathmatch
{
editor_mins "-16 -16 -36"
editor_maxs "16 16 36"
editor_description "Deathmatch Spawn Point"
spawnclass NSSpawnPoint
}
entityDef info_player_coop
{
editor_mins "-16 -16 -36"
editor_maxs "16 16 36"
editor_description "Cooperative Spawn Point"
spawnclass NSSpawnPoint
}

View File

@ -27,3 +27,5 @@ enum
BOTINFO_TEAM_GOALCAPTURE, /* where to go when goal-item present */ BOTINFO_TEAM_GOALCAPTURE, /* where to go when goal-item present */
BOTINFO_END /* end destination */ BOTINFO_END /* end destination */
}; };
.float botinfo;

View File

@ -133,6 +133,8 @@ private:
bool m_bDrawLocalPlayer; bool m_bDrawLocalPlayer;
bool m_bDrawEntities; bool m_bDrawEntities;
bool _m_bWasAlive;
}; };
/** one NSView for each seat */ /** one NSView for each seat */

View File

@ -277,11 +277,28 @@ NSView::UpdateView(void)
pSeat->m_vecPredictedOrigin = cl.origin; pSeat->m_vecPredictedOrigin = cl.origin;
pSeat->m_flPredictedFlags = cl.flags; pSeat->m_flPredictedFlags = cl.flags;
pSeat->m_vecPredictedVelocity = cl.velocity; pSeat->m_vecPredictedVelocity = cl.velocity;
/* this player will respawn, so null visual damage cues */
if (Client_IsDead(cl)) {
if (_m_bWasAlive == true) {
pSeat->m_flDamageAlpha = 0.0f;
pSeat->m_vecDamagePos = g_vec_null;
pSeat->m_iDamageFlags = 0i;
pSeat->m_flShakeFreq = 0.0f;
pSeat->m_flShakeDuration = 0.0f;
pSeat->m_flShakeTime = 0.0f;
pSeat->m_flShakeAmp = 0.0f;
}
_m_bWasAlive = false;
} else {
_m_bWasAlive = true;
}
} }
/* put entities into the scene (and call their predraws */ /* put entities into the scene (and call their predraws */
if (m_bDrawEntities) if (m_bDrawEntities) {
addentities(MASK_ENGINE); addentities(MASK_ENGINE);
}
/* after predraws we can act upon their new positions */ /* after predraws we can act upon their new positions */
if (cl) { if (cl) {
@ -300,6 +317,7 @@ NSView::UpdateView(void)
cl.UpdateAliveCam(); cl.UpdateAliveCam();
StairSmooth(); StairSmooth();
View_DrawViewModel(); View_DrawViewModel();
_m_bWasAlive = true;
} }
} }
break; break;
@ -309,6 +327,29 @@ NSView::UpdateView(void)
spec = (NSClientSpectator)m_viewTarget; spec = (NSClientSpectator)m_viewTarget;
switch (spec.spec_mode) { switch (spec.spec_mode) {
case SPECMODE_DEATHCAM:
vector deathAngle;
vector vecEnd;
c = findfloat(world, ::entnum, spec.spec_ent);
vector vecStart = c.origin;
float progression = time - spec.m_flLastSpecTargetChange;
vecStart[2] += 16;
vecStart += (v_right * 4);
deathAngle[0] = bound(0, progression * 15.0f, 90.0f);
deathAngle[1] = c.angles[1] + (progression * 22.5f);
deathAngle[2] = 0.0f;
makevectors(deathAngle);
vecEnd = vecStart + (v_forward * -48) + [0,0,16] + (v_right * 4);
traceline(vecStart, vecEnd, FALSE, m_viewTarget);
SetCameraOrigin(trace_endpos + (v_forward * 5));
SetCameraAngle(deathAngle);
SetClientAngle(deathAngle);
break;
case SPECMODE_LOCKEDCHASE: case SPECMODE_LOCKEDCHASE:
view_angles = [0, spec.v_angle[1], 0]; view_angles = [0, spec.v_angle[1], 0];
case SPECMODE_THIRDPERSON: case SPECMODE_THIRDPERSON:

View File

@ -119,6 +119,8 @@ infodecal::Spawned(void)
void void
infodecal::Respawn(void) infodecal::Respawn(void)
{ {
InitPointTrigger();
/* this will be invisible by default */ /* this will be invisible by default */
if (!targetname) { if (!targetname) {
#if 0 #if 0

View File

@ -30,6 +30,7 @@ world. It'll enable mouth flapping and all sorts of other cool effects.
- "wait" : Delay before it can be triggered again? UNUSED RIGHT NOW. - "wait" : Delay before it can be triggered again? UNUSED RIGHT NOW.
- "listener" : The name of the entity we'll look at when speaking. Can be "player". - "listener" : The name of the entity we'll look at when speaking. Can be "player".
- "refire" : Additional time in seconds before the entity can be triggered again. - "refire" : Additional time in seconds before the entity can be triggered again.
- "duration" : Time after which the target stops talking.
# INPUTS # INPUTS
- "BeginSentence" : Starts the sentence. - "BeginSentence" : Starts the sentence.
@ -214,6 +215,7 @@ scripted_sentence::Input(entity entityActivator, string inputName, string dataFi
void void
scripted_sentence::AllowRefire(void) scripted_sentence::AllowRefire(void)
{ {
EntLog("%S can now be refired.", targetname);
m_iValue = 0; m_iValue = 0;
} }
@ -221,7 +223,17 @@ scripted_sentence::AllowRefire(void)
void void
scripted_sentence::SentenceEnded(void) scripted_sentence::SentenceEnded(void)
{ {
StopSound(CHAN_VOICE, true); NSTalkMonster targetMonster = __NULL__;
EntLog("%S finished speaking.", m_strSpeaker);
targetMonster = (NSTalkMonster)find(world, ::targetname, m_strSpeaker);
/* it might not exist anymore... */
if (targetMonster) {
targetMonster.StopSound(CHAN_VOICE, true);
}
UseOutput(this, m_strOnEndSentence); UseOutput(this, m_strOnEndSentence);
if (m_flRefire > 0.0f) { if (m_flRefire > 0.0f) {
@ -235,12 +247,13 @@ void
scripted_sentence::Trigger(entity act, triggermode_t unused) scripted_sentence::Trigger(entity act, triggermode_t unused)
{ {
entity spe; entity spe;
spe = find(world, ::targetname, m_strSpeaker);
if (m_iValue == 1) { if (m_iValue == 1) {
return; return;
} }
spe = find(world, ::targetname, m_strSpeaker);
if (!spe) { if (!spe) {
/* time to look for a classname instead */ /* time to look for a classname instead */
float closest = 9999999; float closest = 9999999;
@ -264,6 +277,10 @@ scripted_sentence::Trigger(entity act, triggermode_t unused)
EntLog("%s on %s", m_strSentence, m_strSpeaker); EntLog("%s on %s", m_strSentence, m_strSpeaker);
/* ensure this is set here, so when UseTargets() gets called
this entity will already be inaccessible. fixes ba_tram2. */
m_iValue = 1;
NSTalkMonster npc = (NSTalkMonster)spe; NSTalkMonster npc = (NSTalkMonster)spe;
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET); WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
WriteByte(MSG_MULTICAST, EV_SENTENCE); WriteByte(MSG_MULTICAST, EV_SENTENCE);
@ -271,14 +288,13 @@ scripted_sentence::Trigger(entity act, triggermode_t unused)
WriteInt(MSG_MULTICAST, m_iSentenceID); WriteInt(MSG_MULTICAST, m_iSentenceID);
msg_entity = npc; msg_entity = npc;
multicast(npc.origin, MULTICAST_PVS); multicast(npc.origin, MULTICAST_PVS);
npc.m_flNextSentence = time + m_flDuration + m_flRefire; npc.m_flNextSentence = time + m_flDuration;
UseTargets(act, TRIG_TOGGLE, m_flDelay); UseTargets(act, TRIG_TOGGLE, m_flDelay);
/* I/O */ /* I/O */
/* Uncertain: Are we triggering the output on behalf of someone maybe? */ /* Uncertain: Are we triggering the output on behalf of someone maybe? */
UseOutput(this, m_strOnBeginSentence); UseOutput(this, m_strOnBeginSentence);
ScheduleThink(SentenceEnded, m_flDuration); ScheduleThink(SentenceEnded, m_flDuration);
m_iValue = 1;
if (m_strListener) { if (m_strListener) {
if (m_strListener == "player") { if (m_strListener == "player") {

View File

@ -74,16 +74,15 @@ private:
bool m_bHDREnabled; bool m_bHDREnabled;
}; };
void void
worldspawn::worldspawn(void) worldspawn::worldspawn(void)
{ {
/* defaults */ /* defaults */
m_flHDRIrisMinValue = 1.0; m_flHDRIrisMinValue = 0.0;
m_flHDRIrisMaxValue = 2.0; m_flHDRIrisMaxValue = 1.25;
m_flHDRIrisMultiplier = 1.0; m_flHDRIrisMultiplier = 1.25;
m_flHDRIrisFadeUp = 0.1; m_flHDRIrisFadeUp = 0.1;
m_flHDRIrisFadeDown = 0.5; m_flHDRIrisFadeDown = 0.2;
m_bHDREnabled = false; m_bHDREnabled = false;
if (serverkeyfloat("*bspversion") == BSPVER_HL) { if (serverkeyfloat("*bspversion") == BSPVER_HL) {
@ -141,21 +140,11 @@ worldspawn::Spawned(void)
forceinfokey(world, "ambientsound", m_strAmbientSound); forceinfokey(world, "ambientsound", m_strAmbientSound);
forceinfokey(world, "bgm", m_strBGMTrack); forceinfokey(world, "bgm", m_strBGMTrack);
forceinfokey(world, "gametitle", ftos(m_bGameTitle)); forceinfokey(world, "gametitle", ftos(m_bGameTitle));
forceinfokey(world, "hdr_iris_minvalue", ftos(m_flHDRIrisMinValue));
if (m_bHDREnabled) { forceinfokey(world, "hdr_iris_maxvalue", ftos(m_flHDRIrisMaxValue));
forceinfokey(world, "hdr_iris_minvalue", ftos(m_flHDRIrisMinValue)); forceinfokey(world, "hdr_iris_multiplier", ftos(m_flHDRIrisMultiplier));
forceinfokey(world, "hdr_iris_maxvalue", ftos(m_flHDRIrisMaxValue)); forceinfokey(world, "hdr_iris_fade_up", ftos(m_flHDRIrisFadeUp));
forceinfokey(world, "hdr_iris_multiplier", ftos(m_flHDRIrisMultiplier)); forceinfokey(world, "hdr_iris_fade_down", ftos(m_flHDRIrisFadeDown));
forceinfokey(world, "hdr_iris_fade_up", ftos(m_flHDRIrisFadeUp));
forceinfokey(world, "hdr_iris_fade_down", ftos(m_flHDRIrisFadeDown));
} else {
forceinfokey(world, "hdr_iris_minvalue", "");
forceinfokey(world, "hdr_iris_maxvalue", "");
forceinfokey(world, "hdr_iris_multiplier", "");
forceinfokey(world, "hdr_iris_fade_up", "");
forceinfokey(world, "hdr_iris_fade_down", "");
}
forceinfokey(world, "hdr", ftos(m_bHDREnabled)); forceinfokey(world, "hdr", ftos(m_bHDREnabled));
} }

View File

@ -568,6 +568,10 @@ NSClientPlayer::ReceiveEntity(float new, float flChanged)
setsize(this, mins, maxs); setsize(this, mins, maxs);
setorigin(this, origin); setorigin(this, origin);
if (flChanged & PLAYER_SPECTATE) {
m_flLastSpecTargetChange = time;
}
} }
/* /*

View File

@ -26,6 +26,7 @@ typedef enumflags
typedef enum typedef enum
{ {
SPECMODE_DEATHCAM,
SPECMODE_LOCKEDCHASE, SPECMODE_LOCKEDCHASE,
SPECMODE_THIRDPERSON, SPECMODE_THIRDPERSON,
SPECMODE_FREE, SPECMODE_FREE,
@ -36,6 +37,7 @@ typedef enum
#ifdef CLIENT #ifdef CLIENT
string g_specmodes[] = { string g_specmodes[] = {
"Death Cam",
"Locked Chase Cam", "Locked Chase Cam",
"Free Chase Cam", "Free Chase Cam",
"Free Look", "Free Look",
@ -66,6 +68,8 @@ private:
PREDICTED_FLOAT(spec_ent) PREDICTED_FLOAT(spec_ent)
PREDICTED_FLOAT(spec_flags) PREDICTED_FLOAT(spec_flags)
NSClientSpectatorMode_t spec_mode; NSClientSpectatorMode_t spec_mode_net; NSClientSpectatorMode_t spec_mode; NSClientSpectatorMode_t spec_mode_net;
float m_flDeathCam;
float m_flLastSpecTargetChange;
vector spec_org; vector spec_org;
@ -110,6 +114,8 @@ public:
virtual void EvaluateEntity(void); virtual void EvaluateEntity(void);
virtual float SendEntity(entity,float); virtual float SendEntity(entity,float);
virtual void ServerInputFrame(void); virtual void ServerInputFrame(void);
nonvirtual void SpectatorDeathcam(NSRenderableEntity, NSEntity, float);
#endif #endif
}; };

View File

@ -212,6 +212,10 @@ NSClientSpectator::ReceiveEntity(float new, float flChanged)
READENTITY_BYTE(spec_flags, SPECFL_FLAGS) READENTITY_BYTE(spec_flags, SPECFL_FLAGS)
READENTITY_BYTE(movetype, SPECFL_TYPE) READENTITY_BYTE(movetype, SPECFL_TYPE)
READENTITY_BYTE(solid, SPECFL_TYPE) READENTITY_BYTE(solid, SPECFL_TYPE)
if (flChanged & SPECFL_TARGET) {
m_flLastSpecTargetChange = time;
}
}; };
float float
@ -225,9 +229,23 @@ NSClientSpectator::predraw(void)
void void
NSClientSpectator::InputNext(void) NSClientSpectator::InputNext(void)
{ {
if (spec_flags & SPECFLAG_BUTTON_RELEASED) if (m_flDeathCam > time)
return; return;
if (spec_flags & SPECFLAG_BUTTON_RELEASED) {
return;
}
if (spec_mode == SPECMODE_DEATHCAM && m_flDeathCam < time) {
spec_mode = SPECMODE_THIRDPERSON;
InputNext();
return;
} else if (spec_mode == SPECMODE_FREE) {
spec_mode = SPECMODE_THIRDPERSON;
} else if (spec_mode == SPECMODE_FREEOVERVIEW) {
spec_mode = SPECMODE_CHASEOVERVIEW;
}
spec_flags |= SPECFLAG_BUTTON_RELEASED; spec_flags |= SPECFLAG_BUTTON_RELEASED;
#if 0 #if 0
@ -288,9 +306,23 @@ NSClientSpectator::InputNext(void)
void void
NSClientSpectator::InputPrevious(void) NSClientSpectator::InputPrevious(void)
{ {
if (spec_flags & SPECFLAG_BUTTON_RELEASED) if (m_flDeathCam > time)
return; return;
if (spec_flags & SPECFLAG_BUTTON_RELEASED) {
return;
}
if (spec_mode == SPECMODE_DEATHCAM && m_flDeathCam < time) {
spec_mode = SPECMODE_THIRDPERSON;
InputNext();
return;
} else if (spec_mode == SPECMODE_FREE) {
spec_mode = SPECMODE_THIRDPERSON;
} else if (spec_mode == SPECMODE_FREEOVERVIEW) {
spec_mode = SPECMODE_CHASEOVERVIEW;
}
spec_flags |= SPECFLAG_BUTTON_RELEASED; spec_flags |= SPECFLAG_BUTTON_RELEASED;
#if 0 #if 0
@ -354,8 +386,15 @@ NSClientSpectator::InputPrevious(void)
void void
NSClientSpectator::InputMode(void) NSClientSpectator::InputMode(void)
{ {
if (spec_flags & SPECFLAG_BUTTON_RELEASED) if (spec_mode == SPECMODE_DEATHCAM && m_flDeathCam < time) {
spec_mode = SPECMODE_THIRDPERSON;
InputNext();
return; return;
}
if (spec_flags & SPECFLAG_BUTTON_RELEASED) {
return;
}
spec_flags |= SPECFLAG_BUTTON_RELEASED; spec_flags |= SPECFLAG_BUTTON_RELEASED;
@ -422,7 +461,8 @@ NSClientSpectator::PreFrame(void)
void void
NSClientSpectator::SpectatorTrackPlayer(void) NSClientSpectator::SpectatorTrackPlayer(void)
{ {
if (spec_mode == SPECMODE_THIRDPERSON if (spec_mode == SPECMODE_DEATHCAM
|| spec_mode == SPECMODE_THIRDPERSON
|| spec_mode == SPECMODE_FIRSTPERSON || spec_mode == SPECMODE_FIRSTPERSON
|| spec_mode == SPECMODE_CHASEOVERVIEW || spec_mode == SPECMODE_CHASEOVERVIEW
|| spec_mode == SPECMODE_LOCKEDCHASE ) { || spec_mode == SPECMODE_LOCKEDCHASE ) {
@ -466,6 +506,14 @@ NSClientSpectator::EvaluateEntity(void)
EVALUATE_FIELD(movetype, SPECFL_TYPE) EVALUATE_FIELD(movetype, SPECFL_TYPE)
EVALUATE_FIELD(solid, SPECFL_TYPE) EVALUATE_FIELD(solid, SPECFL_TYPE)
} }
void
NSClientSpectator::SpectatorDeathcam(NSRenderableEntity ourCorpse, NSEntity trackEntity, float waitTime)
{
spec_ent = num_for_edict(ourCorpse);
spec_mode = SPECMODE_DEATHCAM;
m_flDeathCam = time + waitTime;
}
#endif #endif
void void

View File

@ -596,6 +596,7 @@ private:
float m_flLeapDamage; float m_flLeapDamage;
bool m_bLeapAttacked; bool m_bLeapAttacked;
float m_flForceSequence;
nonvirtual void _LerpTurnToEnemy(void); nonvirtual void _LerpTurnToEnemy(void);
nonvirtual void _LerpTurnToPos(vector); nonvirtual void _LerpTurnToPos(vector);

View File

@ -1476,6 +1476,15 @@ NSMonster::Physics(void)
if (!IsAlive) if (!IsAlive)
return; return;
if (m_flForceSequence) {
if (m_iSequenceState != SEQUENCESTATE_IDLE) {
SetFrame(m_flForceSequence);
}
m_flAnimTime = time + 999.0f;
frame = m_flForceSequence;
m_iSequenceState = SEQUENCESTATE_IDLE;
}
/* unset the leap attack */ /* unset the leap attack */
if (m_bLeapAttacked == true && HasFlags(FL_ONGROUND) == true) { if (m_bLeapAttacked == true && HasFlags(FL_ONGROUND) == true) {
m_bLeapAttacked = false; m_bLeapAttacked = false;
@ -2037,6 +2046,9 @@ NSMonster::SpawnKey(string strKey, string strValue)
case "frame": case "frame":
_m_flFrame = ReadFloat(strValue); _m_flFrame = ReadFloat(strValue);
break; break;
case "sequence":
m_flForceSequence = ReadFloat(strValue);
break;
default: default:
super::SpawnKey(strKey, strValue); super::SpawnKey(strKey, strValue);
break; break;

View File

@ -33,6 +33,9 @@ public:
nonvirtual void InitPointTrigger(void); nonvirtual void InitPointTrigger(void);
#ifdef SERVER #ifdef SERVER
virtual void Save(float);
virtual void Restore(string, string);
private: private:
string m_strDebugTexture; string m_strDebugTexture;
#endif #endif

View File

@ -52,3 +52,25 @@ NSPointTrigger::DebugDraw(void)
R_EndPolygon(); R_EndPolygon();
#endif #endif
} }
#ifdef SERVER
void
NSPointTrigger::Save(float handle)
{
super::Save(handle);
SaveString(handle, "m_strDebugTexture", m_strDebugTexture);
}
void
NSPointTrigger::Restore(string strKey, string strValue)
{
switch (strKey) {
case "m_strDebugTexture":
m_strDebugTexture = ReadString(strValue);
break;
default:
super::Restore(strKey, strValue);
break;
}
}
#endif

26
src/shared/NSSpawnPoint.h Normal file
View File

@ -0,0 +1,26 @@
/*
* Copyright (c) 2024 Vera Visions LLC.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/** This entity class represents spawnpoints.
*/
class NSSpawnPoint:NSPointTrigger
{
public:
void NSSpawnPoint(void);
/* overrides */
virtual void Respawn(void);
};

View File

@ -0,0 +1,31 @@
/*
* Copyright (c) 2024 Vera Visions LLC.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
void
NSSpawnPoint::NSSpawnPoint(void)
{
}
void
NSSpawnPoint::Respawn(void)
{
InitPointTrigger();
setorigin_safe(this, GetSpawnOrigin());
SetSize(VEC_HULL_MIN, VEC_HULL_MAX);
SetSolid(SOLID_NOT);
SetMovetype(MOVETYPE_NONE);
botinfo = BOTINFO_SPAWNPOINT;
}

View File

@ -597,7 +597,7 @@ NSTalkMonster::FollowPlayer(void)
/* only update the timer when speed changed */ /* only update the timer when speed changed */
if (flNextSpeed != m_flFollowSpeed) { if (flNextSpeed != m_flFollowSpeed) {
m_flFollowSpeed = flNextSpeed; m_flFollowSpeed = flNextSpeed;
m_flFollowSpeedChanged = time + 5.0f; m_flFollowSpeedChanged = time + 1.0f;
} }
} }

View File

@ -78,6 +78,7 @@ string __fullspawndata;
#include "../gs-entbase/server/defs.h" #include "../gs-entbase/server/defs.h"
#endif #endif
#include "../botlib/botinfo.h"
#include "sentences.h" #include "sentences.h"
#include "NSIO.h" #include "NSIO.h"
@ -95,6 +96,7 @@ string __fullspawndata;
#include "NSMonster.h" #include "NSMonster.h"
#include "NSSquadMonster.h" #include "NSSquadMonster.h"
#include "NSTalkMonster.h" #include "NSTalkMonster.h"
#include "NSSpawnPoint.h"
#include "NSProjectile.h" #include "NSProjectile.h"
#include "NSItem.h" #include "NSItem.h"
#include "NSSpraylogo.h" #include "NSSpraylogo.h"

View File

@ -17,6 +17,7 @@ NSMonster.qc
NSSquadMonster.qc NSSquadMonster.qc
NSTalkMonster.qc NSTalkMonster.qc
NSProjectile.qc NSProjectile.qc
NSSpawnPoint.qc
NSItem.qc NSItem.qc
NSPortal.qc NSPortal.qc
NSDebris.qc NSDebris.qc