Compare commits

...

4 Commits

Author SHA1 Message Date
Marco Cawthorne 40aee258ce
NSClientSpectator: new mode: overview which is work in progress.
Various misc fixes to code routines that negatively affect splitscreen.
We also set frametime/clframetime to 0.0 after the first player view has been drawn as to not run
predraw math more than once per frame. This should not cause any issues but if you are experiencing issues let us know.
2024-01-08 14:58:45 -08:00
Marco Cawthorne 2891bc061e
func_breakable: precache particleeffectnum before first use 2024-01-04 14:34:37 -08:00
Marco Cawthorne 2034eb1d45
ambient_generic: better logging. 2024-01-04 14:33:25 -08:00
Marco Cawthorne 0c7fc9abc6
NSRadar: add method InitEmpty() 2024-01-02 15:41:25 -08:00
29 changed files with 273 additions and 130 deletions

View File

@ -33,8 +33,10 @@ public:
nonvirtual NSRadar InitFromHLTVScript(string);
/** Init as Overview from Source Engine HLTV script file. */
nonvirtual NSRadar InitFromSourceHLTVScript(string);
/** Init an empty (wireframe) overview */
/** Init a wireframe overview. */
nonvirtual NSRadar InitWireframe(void);
/** Init an empty overview. */
nonvirtual NSRadar InitEmpty(void);
nonvirtual void RenderOverviewPlane(void);
nonvirtual void RenderWireframePlane(void);

View File

@ -137,7 +137,7 @@ NSRadar::RenderView(void)
{
if (m_strMaterial != __NULL__) {
RenderOverviewPlane();
} else {
} else if (m_strMaterial == "wireframe") {
RenderWireframePlane();
}
@ -150,7 +150,7 @@ NSRadar::RenderView(void)
}
NSRadar
NSRadar::InitWireframe(void)
NSRadar::InitEmpty(void)
{
NSRadar newRadar = spawn(NSRadar);
newRadar.m_bDrawEntities = false;
@ -159,6 +159,16 @@ NSRadar::InitWireframe(void)
return newRadar;
}
NSRadar
NSRadar::InitWireframe(void)
{
NSRadar newRadar = spawn(NSRadar);
newRadar.m_bDrawEntities = false;
newRadar.CalculateVertices();
newRadar.m_strMaterial = "wireframe";
return newRadar;
}
NSRadar
NSRadar::InitForCurrentMap(void)
{

View File

@ -132,6 +132,7 @@ private:
bool m_bSetClientAngle;
bool m_bDrawLocalPlayer;
bool m_bDrawEntities;
};
/** one NSView for each seat */

View File

@ -26,6 +26,7 @@ NSView::NSView(void)
m_flFieldOfView = 90.0f;
m_client = __NULL__;
m_flSensitivity = 1.0f;
m_bDrawEntities = true;
}
void
@ -49,7 +50,7 @@ NSView::SetupView(void)
if (m_bDrawLocalPlayer)
setproperty(VF_VIEWENTITY, 0);
else
setproperty(VF_VIEWENTITY, player_localentnum);
setproperty(VF_VIEWENTITY, m_viewTarget.entnum);
/* handle camera override */
if (pSeat->m_flCameraTime > time || pSeat->m_flCameraTime == -1) {
@ -260,28 +261,30 @@ void View_DrawViewModel();
void
NSView::UpdateView(void)
{
player pl = (player)m_viewTarget;
NSClientPlayer pl = (NSClientPlayer)m_viewTarget;
NSClient cl = (NSClient)m_viewTarget;
NSClientSpectator spec = (NSClientSpectator)m_viewTarget;
entity c;
if (!cl)
return;
clearscene();
/* run preframe code on our viewtarget */
cl.PreFrame();
/* is a client attached to this view? */
if (cl) {
/* run preframe code on our viewtarget */
cl.PreFrame();
/* update our player seat info with predicted info */
pSeat->m_vecPredictedOrigin = cl.origin;
pSeat->m_flPredictedFlags = cl.flags;
pSeat->m_vecPredictedVelocity = cl.velocity;
/* update our player seat info with predicted info */
pSeat->m_vecPredictedOrigin = cl.origin;
pSeat->m_flPredictedFlags = cl.flags;
pSeat->m_vecPredictedVelocity = cl.velocity;
}
/* put entities into the scene (and call their predraws */
addentities(MASK_ENGINE);
if (m_bDrawEntities)
addentities(MASK_ENGINE);
/* after predraws we can act upon their new positions */
if (cl) {
switch (GetViewMode()) {
case VIEWMODE_FPS:
if (Client_InIntermission()) {
@ -306,6 +309,8 @@ NSView::UpdateView(void)
spec = (NSClientSpectator)m_viewTarget;
switch (spec.spec_mode) {
case SPECMODE_LOCKEDCHASE:
view_angles = [0, spec.v_angle[1], 0];
case SPECMODE_THIRDPERSON:
makevectors(view_angles);
vector vecStart = spec.GetEyePos();
@ -322,7 +327,7 @@ NSView::UpdateView(void)
c = findfloat(world, ::entnum, spec.spec_ent);
if (c.classname == "player") {
player bp = (player)c;
NSClientPlayer bp = (NSClientPlayer)c;
removeentity(c);
SetCameraOrigin(bp.GetEyePos());
SetCameraAngle(bp.v_angle);
@ -334,7 +339,7 @@ NSView::UpdateView(void)
/* we found them */
if (c && c != spec) {
player ps = (player)c;
NSClientPlayer ps = (NSClientPlayer)c;
if (ps.health <= 0)
pl.UpdateDeathcam();
else
@ -343,6 +348,27 @@ NSView::UpdateView(void)
}
}
break;
case SPECMODE_CHASEOVERVIEW:
c = findfloat(world, ::entnum, spec.spec_ent);
if (c.classname == "player") {
SetCameraOrigin(c.origin);
}
drawfill(m_vecPosition, m_vecSize, [0,0,0], 1.0f, DRAWFLAG_NORMAL);
g_overview.SetViewPosition(m_vecPosition);
g_overview.SetViewSize(m_vecSize);
g_overview.SetRadarPitch(view_angles[0]);
g_overview.UpdateView();
return;
case SPECMODE_FREEOVERVIEW:
SetCameraOrigin(pSeat->m_vecPredictedOrigin);
drawfill(m_vecPosition, m_vecSize, [0,0,0], 1.0f, DRAWFLAG_NORMAL);
g_overview.SetViewPosition(m_vecPosition);
g_overview.SetViewSize(m_vecSize);
g_overview.SetRadarPitch(view_angles[0]);
g_overview.UpdateView();
return;
break;
default:
SetCameraOrigin(cl.GetEyePos());
SetCameraAngle(view_angles);
@ -354,13 +380,19 @@ NSView::UpdateView(void)
View_PreDraw();
}
/* prepare our scene properties */
SetupView();
/* properties are locked in place, run logic that depends on final values */
addentities(MASK_GLOWS);
if (m_bDrawEntities)
addentities(MASK_GLOWS);
SkyCamera_Setup(origin);
XR_UpdateView(m_viewTarget);
if (cl)
XR_UpdateView(m_viewTarget);
/* render our frame */
RenderView();
@ -375,12 +407,14 @@ NSView::UpdateView(void)
}
/* the blinding stuff */
Fade_Update(m_vecPosition[0], m_vecPosition[1], m_vecSize[0], m_vecSize[1]);
if (cl) {
Fade_Update(m_vecPosition[0], m_vecPosition[1], m_vecSize[0], m_vecSize[1]);
View_PostDraw();
View_PostDraw();
/* move this into NSClient methods */
cl.PostFrame();
/* move this into NSClient methods */
cl.PostFrame();
}
if (autocvar(r_showView, 0) == false)
return;

View File

@ -339,10 +339,14 @@ Cmd_Parse(string sCMD)
pSeat->m_iInputDuck = 1 - pSeat->m_iInputDuck;
else
pSeat->m_iInputDuck = TRUE;
pSeat->m_bSpecInput = true;
break;
case "-duck":
if (autocvar_pm_crouchToggle == false)
pSeat->m_iInputDuck = FALSE;
pSeat->m_bSpecInput = false;
break;
case "invnext":
HUD_DrawWeaponSelect_Back();

View File

@ -22,6 +22,7 @@
#include "cmd.h"
#include "util.h"
#include "NSView.h"
#include "NSRadar.h"
#include "crosshair.h"
var bool g_net_debug = false;
@ -372,6 +373,11 @@ struct
bool m_bMoveForward;
bool m_bInterfaceFocused;
bool m_bSpecInput;
} g_seats[4], *pSeat;
var vector g_vecMousePos;
var vector g_hudmins;
var vector g_hudres;
var NSRadar g_overview;

View File

@ -264,7 +264,7 @@ EFX_Interpolate(int id)
}
void
EFX_UpdateListener(void)
EFX_UpdateListener(NSView playerView)
{
static int old_dsp;
@ -301,8 +301,8 @@ EFX_UpdateListener(void)
EFX_SetEnvironment(scape.m_iRoomType);
}
makevectors(getproperty(VF_CL_VIEWANGLES));
SetListener(getproperty(VF_ORIGIN), v_forward, v_right, v_up, 12);
makevectors(playerView.GetCameraAngle());
SetListener(playerView.GetCameraOrigin(), v_forward, v_right, v_up, 12);
if (old_dsp == g_iEFX) {
return;

View File

@ -71,7 +71,7 @@ Entity_EntityUpdate(float type, float new)
NSENTITY_READENTITY(prop_vehicle_driveable, new)
break;
case ENT_PLAYER:
player pl = (player)self;
NSClientPlayer pl = (NSClientPlayer)self;
/* splitscreen */
CSQC_UpdateSeat();

View File

@ -81,6 +81,8 @@ CSQC_Init(float apilevel, string enginename, float engineversion)
WorldSpawn_Init();
g_overview = NSRadar::InitForCurrentMap();
Sound_Precache("Player.DenyWeaponSelection");
Sound_Precache("Player.WeaponSelected");
Sound_Precache("Player.WeaponSelectionMoveSlot");
@ -308,13 +310,14 @@ CSQC_UpdateView(float w, float h, float focus)
/* 2D calls happen here, after rendering is done */
CSQC_Update2D(w, h, focus);
EFX_UpdateListener(g_view);
DSP_UpdateSoundscape(g_view);
clframetime = 0.0f;
frametime = 0.0f;
}
}
/* this sucks and doesn't take seats into account */
EFX_UpdateListener();
DSP_UpdateSoundscape();
/* draw AL debug info (no regard for seating */
if (autocvar_s_al_debug)
EFX_DebugInfo();

View File

@ -1,6 +1,7 @@
#includelist
NSInteractiveSurface.qc
NSView.qc
NSRadar.qc
fog.qc
font.qc
sky.qc

View File

@ -39,7 +39,7 @@ Event_Callback(float mtime, __inout float btime)
return;
/* weapon changed */
player pl = (player)(pSeat->m_ePlayer);
NSClientPlayer pl = (NSClientPlayer)(pSeat->m_ePlayer);
if (pSeat->m_iEventWeapon != pl.activeweapon)
return;

View File

@ -14,6 +14,8 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
var string autocvar_g_playerClass = "player";
/*
=================
Predict_EntityUpdate
@ -24,15 +26,15 @@ Propagate our pmove state to whatever the current frame before its stomped on
=================
*/
void
Predict_EntityUpdate(player pl, float new)
Predict_EntityUpdate(NSClientPlayer pl, float new)
{
/* people expect a static camera when paused */
if (Util_IsPaused())
return;
/* this is a new client entity, let's set it up right */
if (new || self.classname != "player") {
spawnfunc_player();
if (new || pl.classname != "player") {
Util_ChangeClass(pl, "player");
pl.classname = "player";
/* is this **us** ? */

View File

@ -325,4 +325,4 @@ GameMessage_Parse(void)
if (strSound)
sound(self, CHAN_ITEM, strSound, flVolume, iAttenuation);
}
}

View File

@ -111,6 +111,13 @@ View_DrawViewmodel_Single(int weapon, float weapontime)
}
static void
View_HandleAnimEvent(float flTimeStamp, int iCode, string strData)
{
NSRenderableEntity viewModel = (NSRenderableEntity)self;
viewModel.HandleAnimEvent(flTimeStamp, iCode, strData);
}
/*
====================
View_DrawViewModel
@ -125,18 +132,18 @@ View_DrawViewModel(void)
NSRenderableEntity m_eViewModel = (NSRenderableEntity)pSeat->m_eViewModel;
NSRenderableEntity m_eViewModelL = (NSRenderableEntity)pSeat->m_eViewModelL;
player pl = __NULL__;
NSClientPlayer pl = __NULL__;
NSClient cl = (NSClient)pSeat->m_ePlayer;
/* it's either us or us spectating */
if (Client_IsSpectator(cl)) {
NSClientSpectator spec = (NSClientSpectator)pSeat->m_ePlayer;
pl = (player)findfloat(world, ::entnum, spec.spec_ent);
pl = (NSClientPlayer)findfloat(world, ::entnum, spec.spec_ent);
if (spec.spec_mode != SPECMODE_FIRSTPERSON)
return;
} else {
pl = (player)pSeat->m_ePlayer;
pl = (NSClientPlayer)pSeat->m_ePlayer;
}
if (!pl)
@ -215,7 +222,7 @@ View_DrawViewModel(void)
entity oldSelf = self;
self = m_eViewModel;
processmodelevents(m_eViewModel.modelindex, m_eViewModel.frame, fBaseTime,
m_eViewModel.frame1time, NSRenderableEntity::HandleAnimEvent);
m_eViewModel.frame1time, View_HandleAnimEvent);
self = oldSelf;
makevectors(view_angles);
@ -255,11 +262,17 @@ View_DrawViewModel(void)
if (Client_IsSpectator(cl) || XR_Available(pl) == false) {
m_eViewModelL.origin = g_view.GetCameraOrigin();
m_eViewModel.origin = g_view.GetCameraOrigin();
//m_eViewModel.angles = g_view.GetCameraAngle();
//m_eViewModelL.angles = g_view.GetCameraAngle();
if (Client_IsSpectator(cl)) {
m_eViewModel.angles = g_view.GetCameraAngle();
m_eViewModelL.angles = g_view.GetCameraAngle();
/* HACK: fool Viewmodel_CalcBob(); */
pSeat->m_vecPredictedVelocity = pl.velocity;
}
/* we only calculate bob on the right model, to avoid double speed bobbing */
Viewmodel_CalcBob();
makevectors(g_view.GetCameraAngle());
Viewmodel_ApplyBob(m_eViewModel);
Viewmodel_ApplyBob(m_eViewModelL);
} else {

View File

@ -98,7 +98,7 @@ DSP_ResetSoundscape(void)
}
void
DSP_UpdateSoundscape(void)
DSP_UpdateSoundscape(NSView playerView)
{
vector vecPlayer;

View File

@ -142,6 +142,7 @@ private:
float m_flExplodeRad;
string m_strBreakSpawn;
bool m_bCanTouch;
int _m_iExplosionParticle;
/*entity m_pressAttacker;
int m_pressType;
@ -156,6 +157,7 @@ func_breakable::func_breakable(void)
m_flExplodeRad = 0.0f;
m_strBreakSpawn = __NULL__;
m_bCanTouch = false;
_m_iExplosionParticle = 0i;
/* func_breakable defaults to glass */
if (classname == "func_breakable") {
@ -236,7 +238,7 @@ func_breakable::Spawned(void)
/* needs to be called before super function */
SetSurfaceData(funcbreakable_surftable[material]);
SetPropData(funcbreakable_surftable[material]);
_m_iExplosionParticle = particleeffectnum("fx_explosion.main");
super::Spawned();
}
@ -299,7 +301,7 @@ func_breakable::Explode(void)
string breakModel = GetPropData(PROPINFO_BREAKMODEL);
BreakModel_Spawn(absmin, absmax, [0,0,0], m_flExplodeMag, vlen(size) / 10, breakModel);
pointparticles(particleeffectnum("fx_explosion.main"), rp, [0,0,0], 1);
pointparticles(_m_iExplosionParticle, rp, [0,0,0], 1);
Damage_Radius(rp, this, m_flExplodeMag, m_flExplodeRad, TRUE, 0);
UseTargets(this, TRIG_TOGGLE, 0.0f); /* delay... ignored. */
SetTakedamage(DAMAGE_NO);

View File

@ -273,8 +273,7 @@ ambient_generic::Respawn(void)
void
ambient_generic::UseNormal(entity act, triggermode_t state)
{
NSLog("Sound once: %S Volume: %f; Radius: %d; Pitch: %d", \
m_strActivePath, m_flVolume, m_flRadius, m_flPitch);
SndLog( "^2%s::^3UseNormal^7: %S Volume: %f; Radius: %d; Pitch: %f", classname, m_strActivePath, m_flVolume, m_flRadius, m_flPitch);
if (substring(m_strActivePath, 0, 1) == "!") {
string seq = Sentences_GetSamples(m_strActivePath);
@ -301,13 +300,11 @@ void
ambient_generic::UseLoop(entity act, triggermode_t state)
{
if (m_bToggle == true) {
NSLog("^2ambient_generic::^3UseLoop^7: %s stops `%s`",
target, m_strActivePath);
SndLog( "^2%s::^3UseLoop^7: %s stops %S", classname, target, m_strActivePath);
m_strActivePath = "common/null.wav";
} else {
m_strActivePath = m_strSpawnPath;
NSLog("^2ambient_generic::^3UseLoop^7: %s plays `%s`",
target, m_strActivePath);
SndLog( "^2%s::^3UseLoop^7: %s plays %S", classname, target, m_strActivePath);
}
m_bToggle = !m_bToggle;
@ -424,7 +421,7 @@ ambient_generic::ReceiveEntity(float isnew, float flChanged)
if (flChanged & AMBIENT_ENABLED)
m_bLoops = readbyte();
SndLog("Sound received: %S Volume: %f; Radius: %d; Pitch: %d, Org: %v", m_strActivePath, m_flVolume, m_flRadius, m_flPitch, origin);
SndLog( "^2%s::^3ReceiveEntity^7: received: %S Volume: %f; Radius: %d; Pitch: %d, Org: %v", classname, m_strActivePath, m_flVolume, m_flRadius, m_flPitch, origin);
if (m_bLoops == true) {
if (flChanged & AMBIENT_MODERN) {

View File

@ -91,7 +91,7 @@ public:
/** Checks if an entity can be attacked from a given position. */
virtual bool DamageCheckTrace(entity,vector);
/** Overridable: shim to handle application of indirect radius damage. */
virtual void DamageRadius(vector,entity,float,float,int,int);
virtual void DamageRadius(vector,entity,float,float,bool,int);
/* end of a game */
/** Called when intermission starts. */

View File

@ -221,6 +221,14 @@ NSGameRules::IntermissionCycle(void)
WriteCoord(MSG_MULTICAST, cam.origin[0]);
WriteCoord(MSG_MULTICAST, cam.origin[1]);
WriteCoord(MSG_MULTICAST, cam.origin[2]);
} else {
WriteByte(MSG_MULTICAST, 1);
WriteFloat(MSG_MULTICAST, cam.angles[0]);
WriteFloat(MSG_MULTICAST, cam.angles[1]);
WriteFloat(MSG_MULTICAST, cam.angles[2]);
WriteCoord(MSG_MULTICAST, cam.origin[0]);
WriteCoord(MSG_MULTICAST, cam.origin[1]);
WriteCoord(MSG_MULTICAST, cam.origin[2]);
}
for (entity pl = world; (pl = find(pl, ::classname, "player"));) {
@ -455,7 +463,7 @@ NSGameRules::DamageCheckTrace(entity t, vector vecHitPos)
}
void
NSGameRules::DamageRadius(vector org, entity attacker, float dmg, float r, int check, int w)
NSGameRules::DamageRadius(vector org, entity attacker, float dmg, float r, bool checkCollision, int w)
{
float new_dmg;
float dist;
@ -473,7 +481,7 @@ NSGameRules::DamageRadius(vector org, entity attacker, float dmg, float r, int c
continue;
/* can we physically hit this thing? */
if (check == TRUE)
if (checkCollision == true)
if (DamageCheckTrace(e, org) == FALSE)
continue;

View File

@ -269,8 +269,13 @@ SV_RunClientCommand(void)
/* TODO */
}
cl.SharedInputFrame();
cl.ServerInputFrame();
/* FIXME: before a splitscreen player disconnects, it often sends
one last SV_RunClientCommand which causes an error if we don't
check these two methods here */
if (cl.SharedInputFrame)
cl.SharedInputFrame();
if (cl.ServerInputFrame)
cl.ServerInputFrame();
if (self.gotData == false) {
BreakModel_SendClientData(self);
@ -313,8 +318,9 @@ SV_ParseClientCommand(string cmd)
case "spectate":
if (self.classname != "player")
break;
ClientKill();
spawnfunc_NSClientSpectator();
player pl = (player)self;
pl.MakeSpectator();
break;
case "play":
if (self.classname != "spectator")

View File

@ -88,8 +88,10 @@ public:
/** When called, will turn the client into a proper player. */
virtual void MakePlayer(void);
/** When called, will turn the client into a spectator. */
/** When called, will turn the client into a spectator until the next round. */
virtual void MakeTempSpectator(void);
/** When called, will turn the client into a general spectator. */
virtual void MakeSpectator(void);
/** Called when we press the button bound to +use. */
virtual void InputUse_Down(void);

View File

@ -898,6 +898,15 @@ NSClientPlayer::MakePlayer(void)
forceinfokey(this, "*dead", "0");
}
void
NSClientPlayer::MakeSpectator(void)
{
ClientKill();
MakeTempSpectator();
team = 0;
forceinfokey(this, "*team", ftos(team));
}
/*
=================
NSClientPlayer::EvaluateEntity
@ -910,6 +919,8 @@ at the top of player::EvaluateEntity
void
NSClientPlayer::EvaluateEntity(void)
{
pvsflags = (flags & FL_FAKESPEC) ? 0 : PVSF_IGNOREPVS;
EVALUATE_FIELD(modelindex, PLAYER_MODELINDEX)
EVALUATE_FIELD(colormap, PLAYER_MODELINDEX)

View File

@ -26,12 +26,25 @@ typedef enumflags
typedef enum
{
SPECMODE_FREE,
SPECMODE_LOCKEDCHASE,
SPECMODE_THIRDPERSON,
SPECMODE_FREE,
SPECMODE_FIRSTPERSON,
SPECMODE_OVERVIEW
SPECMODE_FREEOVERVIEW,
SPECMODE_CHASEOVERVIEW
} NSClientSpectatorMode_t;
#ifdef CLIENT
string g_specmodes[] = {
"Locked Chase Cam",
"Free Chase Cam",
"Free Look",
"First Person",
"Free Overview",
"Chase Overview"
};
#endif
enumflags
{
SPECFLAG_BUTTON_RELEASED,

View File

@ -18,6 +18,7 @@ void
NSClientSpectator::NSClientSpectator(void)
{
flags |= FL_CLIENT;
spec_mode = SPECMODE_FREE;
}
#ifdef SERVER
@ -90,7 +91,11 @@ NSClientSpectator::SharedInputFrame(void)
{
SetSize(g_vec_null, g_vec_null);
if (spec_mode == SPECMODE_FREE) {
if (spec_mode == SPECMODE_FREE || spec_mode == SPECMODE_FREEOVERVIEW) {
if (spec_mode == SPECMODE_FREEOVERVIEW) {
input_angles[0] = 0.0f;
}
SetSolid(SOLID_NOT);
SetMovetype(MOVETYPE_NOCLIP);
} else {
@ -134,6 +139,8 @@ NSClientSpectator::SendEntity(entity ePVSent, float flChanged)
void
NSClientSpectator::ServerInputFrame(void)
{
movetype = MOVETYPE_NOCLIP;
if (spec_mode == SPECMODE_FREE) {
runstandardplayerphysics(this);
} else {
@ -163,7 +170,7 @@ NSClientSpectator::ClientInputFrame(void)
void
NSClientSpectator::ReceiveEntity(float new, float flChanged)
{
if (spec_mode == SPECMODE_FREE)
if (spec_mode == SPECMODE_FREE || spec_mode == SPECMODE_FREEOVERVIEW)
if (new == FALSE) {
/* Go through all the physics code between the last received frame
* and the newest frame and keep the changes this time around instead
@ -274,8 +281,8 @@ NSClientSpectator::InputNext(void)
WarpToTarget();
if (spec_mode == SPECMODE_FREE)
spec_mode = SPECMODE_THIRDPERSON;
if (spec_mode == SPECMODE_CHASEOVERVIEW)
spec_mode = SPECMODE_CHASEOVERVIEW;
}
void
@ -340,8 +347,8 @@ NSClientSpectator::InputPrevious(void)
WarpToTarget();
if (spec_mode == SPECMODE_FREE)
spec_mode = SPECMODE_THIRDPERSON;
if (spec_mode == SPECMODE_LOCKEDCHASE)
spec_mode = SPECMODE_CHASEOVERVIEW;
}
void
@ -359,13 +366,16 @@ NSClientSpectator::InputMode(void)
f = (NSClient)edict_num(spec_ent);
#endif
if (f == this || f.classname != "player")
spec_mode = SPECMODE_FREE;
else {
if (f == this || f.classname != "player") {
if (spec_mode != SPECMODE_FREE)
spec_mode = SPECMODE_FREE;
else
spec_mode = SPECMODE_FREEOVERVIEW;
} else {
spec_mode++;
if (spec_mode > SPECMODE_FIRSTPERSON)
spec_mode = SPECMODE_FREE;
if (spec_mode > SPECMODE_CHASEOVERVIEW)
spec_mode = SPECMODE_LOCKEDCHASE;
}
}
@ -412,7 +422,10 @@ NSClientSpectator::PreFrame(void)
void
NSClientSpectator::SpectatorTrackPlayer(void)
{
if (spec_mode == SPECMODE_THIRDPERSON || spec_mode == SPECMODE_FIRSTPERSON ) {
if (spec_mode == SPECMODE_THIRDPERSON
|| spec_mode == SPECMODE_FIRSTPERSON
|| spec_mode == SPECMODE_CHASEOVERVIEW
|| spec_mode == SPECMODE_LOCKEDCHASE ) {
NSClient b;
#ifdef CLIENT

View File

@ -2022,7 +2022,7 @@ NSMonster::SpawnKey(string strKey, string strValue)
_m_flFrame = ReadFloat(strValue);
break;
default:
NSSurfacePropEntity::SpawnKey(strKey, strValue);
super::SpawnKey(strKey, strValue);
break;
}
}

View File

@ -712,10 +712,13 @@ NSProjectile::_ThrustThink(void)
/* homing mode */
if (m_bThrustHoming) {
vector ownerPos;
vector endPos;
NSSurfacePropEntity projectileOwner = (NSSurfacePropEntity)GetOwner();
vector ownerPos = projectileOwner.GetEyePos();
makevectors(projectileOwner.v_angle);
traceline(ownerPos, ownerPos + v_forward * 8096, FALSE, projectileOwner);
ownerPos = projectileOwner.GetEyePos();
makevectors(projectileOwner.GetViewAngle());
endPos = ownerPos + (v_forward * 4096.0f);
traceline(ownerPos, endPos, MOVE_NORMAL, projectileOwner);
SetAngles(vectoangles(trace_endpos - GetOrigin()));
}

View File

@ -1,48 +1,48 @@
/*
* Copyright (c) 2016-2022 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.
*/
/*
* Copyright (c) 2016-2022 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.
*/
/** All available damage types. */
typedef enumflags
{
DMG_GENERIC, /**< Non specific. */
DMG_CRUSH, /**< Being crushed by something heavy. */
DMG_BULLET, /**< Shot by a gun. */
DMG_SLASH, /**< Cutting, from swords or knives. */
DMG_FREEZE, /**< Ice/freezing temperature damage. */
DMG_BURN, /**< Short flame, or on-fire type damage. */
DMG_VEHICLE, /**< Vehicle ramming into you at speed. */
DMG_FALL, /**< Fall damage */
DMG_EXPLODE, /**< Firery explosion damage. */
DMG_BLUNT, /**< Blunt damage, like from a pipe or a bat. */
DMG_ELECTRO, /**< Electric shock damage. */
DMG_SOUND, /**< Noise so irritating it creates damage. */
DMG_ENERGYBEAM, /**< Energy beam damage. */
DMG_GIB_NEVER, /**< This damage type doesn't cause gibbing. */
DMG_GIB_ALWAYS, /**< This damage type will always gib. */
DMG_DROWN, /**< Drown damage, gets restored over time. */
DMG_PARALYZE, /**< Paralyzation damage. */
DMG_NERVEGAS, /**< Toxins to the nerve, special effect? */
DMG_POISON, /**< Poisonous damage. Similar to nervegas? */
DMG_RADIATION, /**< Radiation damage. Geiger counter go brrr */
DMG_DROWNRECOVER, /**< Health increase from drown recovery. */
DMG_CHEMICAL, /**< Chemical damage. */
DMG_SLOWBURN, /**< Slow burning, just like burning but different rate. */
DMG_SLOWFREEZE, /**< Slow freeze, just freezing but different rate. */
DMG_SKIP_ARMOR, /**< This damage will skip armor checks entirely. */
DMG_SKIP_RAGDOLL /**< This damage will not affect ragdolls. */
} damageType_t;
#define DMG_ACID DMG_CHEMICAL
typedef enum
{
DMG_GENERIC = 1, /**< Non specific. */
DMG_CRUSH = 2, /**< Being crushed by something heavy. */
DMG_BULLET = 4, /**< Shot by a gun. */
DMG_SLASH = 8, /**< Cutting, from swords or knives. */
DMG_FREEZE = 16, /**< Ice/freezing temperature damage. */
DMG_BURN = 32, /**< Short flame, or on-fire type damage. */
DMG_VEHICLE = 64, /**< Vehicle ramming into you at speed. */
DMG_FALL = 128, /**< Fall damage */
DMG_EXPLODE = 256, /**< Firery explosion damage. */
DMG_BLUNT = 512, /**< Blunt damage, like from a pipe or a bat. */
DMG_ELECTRO = 1024, /**< Electric shock damage. */
DMG_SOUND = 2048, /**< Noise so irritating it creates damage. */
DMG_ENERGYBEAM = 4096, /**< Energy beam damage. */
DMG_GIB_NEVER = 8192, /**< This damage type doesn't cause gibbing. */
DMG_GIB_ALWAYS = 16384, /**< This damage type will always gib. */
DMG_DROWN = 32768, /**< Drown damage, gets restored over time. */
DMG_PARALYZE = 65536, /**< Paralyzation damage. */
DMG_NERVEGAS = 131072, /**< Toxins to the nerve, special effect? */
DMG_POISON = 262144, /**< Poisonous damage. Similar to nervegas? */
DMG_RADIATION = 524288, /**< Radiation damage. Geiger counter go brrr */
DMG_DROWNRECOVER = 1048576, /**< Health increase from drown recovery. */
DMG_CHEMICAL = 2097152, /**< Chemical damage. */
DMG_SLOWBURN = 4194304, /**< Slow burning, just like burning but different rate. */
DMG_SLOWFREEZE = 8388608, /**< Slow freeze, just freezing but different rate. */
DMG_SKIP_ARMOR = 16777216, /**< This damage will skip armor checks entirely. */
DMG_SKIP_RAGDOLL = 33554432 /**< This damage will not affect ragdolls. */
} damageType_t;
#define DMG_ACID DMG_CHEMICAL

View File

@ -1,4 +1,18 @@
/* Copyright (c) 2022, Vera Visions, L.L.C. All rights reserved. */
/*
* Copyright (c) 2022-2023 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.
*/
/*
Decal Property List Specs

View File

@ -328,7 +328,7 @@ Sound_PrecacheFile(string fileName)
g_hashsounds = hash_createtab(2, HASH_ADD);
}
print(sprintf("Precaching SOURCE ENGINE file %S\n", fileName));
SndLog("Precaching SOURCE ENGINE file %S", fileName);
while ((lineStream = fgets(scriptFile))) {
/* when we found it, quit */
@ -396,9 +396,7 @@ Sound_Precache(string shader)
index = g_sounds_count;
SndLog("Precaching SoundDef ");
SndLog(shader);
SndLog("\n");
SndLog("Precaching SoundDef %S", shader);
/* create the hash-table if it doesn't exist */
if (!g_hashsounds) {