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_END /* end destination */
};
.float botinfo;

View File

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

View File

@ -277,11 +277,28 @@ NSView::UpdateView(void)
pSeat->m_vecPredictedOrigin = cl.origin;
pSeat->m_flPredictedFlags = cl.flags;
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 */
if (m_bDrawEntities)
if (m_bDrawEntities) {
addentities(MASK_ENGINE);
}
/* after predraws we can act upon their new positions */
if (cl) {
@ -300,6 +317,7 @@ NSView::UpdateView(void)
cl.UpdateAliveCam();
StairSmooth();
View_DrawViewModel();
_m_bWasAlive = true;
}
}
break;
@ -309,6 +327,29 @@ NSView::UpdateView(void)
spec = (NSClientSpectator)m_viewTarget;
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:
view_angles = [0, spec.v_angle[1], 0];
case SPECMODE_THIRDPERSON:

View File

@ -119,6 +119,8 @@ infodecal::Spawned(void)
void
infodecal::Respawn(void)
{
InitPointTrigger();
/* this will be invisible by default */
if (!targetname) {
#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.
- "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.
- "duration" : Time after which the target stops talking.
# INPUTS
- "BeginSentence" : Starts the sentence.
@ -214,6 +215,7 @@ scripted_sentence::Input(entity entityActivator, string inputName, string dataFi
void
scripted_sentence::AllowRefire(void)
{
EntLog("%S can now be refired.", targetname);
m_iValue = 0;
}
@ -221,7 +223,17 @@ scripted_sentence::AllowRefire(void)
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);
if (m_flRefire > 0.0f) {
@ -235,12 +247,13 @@ void
scripted_sentence::Trigger(entity act, triggermode_t unused)
{
entity spe;
spe = find(world, ::targetname, m_strSpeaker);
if (m_iValue == 1) {
return;
}
spe = find(world, ::targetname, m_strSpeaker);
if (!spe) {
/* time to look for a classname instead */
float closest = 9999999;
@ -264,6 +277,10 @@ scripted_sentence::Trigger(entity act, triggermode_t unused)
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;
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
WriteByte(MSG_MULTICAST, EV_SENTENCE);
@ -271,14 +288,13 @@ scripted_sentence::Trigger(entity act, triggermode_t unused)
WriteInt(MSG_MULTICAST, m_iSentenceID);
msg_entity = npc;
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);
/* I/O */
/* Uncertain: Are we triggering the output on behalf of someone maybe? */
UseOutput(this, m_strOnBeginSentence);
ScheduleThink(SentenceEnded, m_flDuration);
m_iValue = 1;
if (m_strListener) {
if (m_strListener == "player") {

View File

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

View File

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

View File

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

View File

@ -212,6 +212,10 @@ NSClientSpectator::ReceiveEntity(float new, float flChanged)
READENTITY_BYTE(spec_flags, SPECFL_FLAGS)
READENTITY_BYTE(movetype, SPECFL_TYPE)
READENTITY_BYTE(solid, SPECFL_TYPE)
if (flChanged & SPECFL_TARGET) {
m_flLastSpecTargetChange = time;
}
};
float
@ -225,9 +229,23 @@ NSClientSpectator::predraw(void)
void
NSClientSpectator::InputNext(void)
{
if (spec_flags & SPECFLAG_BUTTON_RELEASED)
if (m_flDeathCam > time)
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;
#if 0
@ -288,9 +306,23 @@ NSClientSpectator::InputNext(void)
void
NSClientSpectator::InputPrevious(void)
{
if (spec_flags & SPECFLAG_BUTTON_RELEASED)
if (m_flDeathCam > time)
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;
#if 0
@ -354,8 +386,15 @@ NSClientSpectator::InputPrevious(void)
void
NSClientSpectator::InputMode(void)
{
if (spec_flags & SPECFLAG_BUTTON_RELEASED)
if (spec_mode == SPECMODE_DEATHCAM && m_flDeathCam < time) {
spec_mode = SPECMODE_THIRDPERSON;
InputNext();
return;
}
if (spec_flags & SPECFLAG_BUTTON_RELEASED) {
return;
}
spec_flags |= SPECFLAG_BUTTON_RELEASED;
@ -422,7 +461,8 @@ NSClientSpectator::PreFrame(void)
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_CHASEOVERVIEW
|| spec_mode == SPECMODE_LOCKEDCHASE ) {
@ -466,6 +506,14 @@ NSClientSpectator::EvaluateEntity(void)
EVALUATE_FIELD(movetype, 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
void

View File

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

View File

@ -1476,6 +1476,15 @@ NSMonster::Physics(void)
if (!IsAlive)
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 */
if (m_bLeapAttacked == true && HasFlags(FL_ONGROUND) == true) {
m_bLeapAttacked = false;
@ -2037,6 +2046,9 @@ NSMonster::SpawnKey(string strKey, string strValue)
case "frame":
_m_flFrame = ReadFloat(strValue);
break;
case "sequence":
m_flForceSequence = ReadFloat(strValue);
break;
default:
super::SpawnKey(strKey, strValue);
break;

View File

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

View File

@ -52,3 +52,25 @@ NSPointTrigger::DebugDraw(void)
R_EndPolygon();
#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 */
if (flNextSpeed != m_flFollowSpeed) {
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"
#endif
#include "../botlib/botinfo.h"
#include "sentences.h"
#include "NSIO.h"
@ -95,6 +96,7 @@ string __fullspawndata;
#include "NSMonster.h"
#include "NSSquadMonster.h"
#include "NSTalkMonster.h"
#include "NSSpawnPoint.h"
#include "NSProjectile.h"
#include "NSItem.h"
#include "NSSpraylogo.h"

View File

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