Compare commits
5 commits
b4fbab80c5
...
66745985d4
Author | SHA1 | Date | |
---|---|---|---|
66745985d4 | |||
40dc1267fa | |||
3e8cf479c9 | |||
d0838eab60 | |||
1bb1fe705d |
24 changed files with 632 additions and 457 deletions
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
#define CSQC
|
#define CSQC
|
||||||
#define CLIENT
|
#define CLIENT
|
||||||
#define NEW_INVENTORY
|
|
||||||
|
|
||||||
#includelist
|
#includelist
|
||||||
/* first the engine, then nuclide headers for client/shared */
|
/* first the engine, then nuclide headers for client/shared */
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "gamerules.h"
|
#include "gamerules.h"
|
||||||
|
#include "items.h"
|
||||||
|
|
||||||
// stubs for spawning
|
// stubs for spawning
|
||||||
void info_player_deathmatch(void)
|
void info_player_deathmatch(void)
|
||||||
|
|
32
base/src/server/items.h
Normal file
32
base/src/server/items.h
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* PICKUP ITEMS */
|
||||||
|
class item_pickup:NSRenderableEntity
|
||||||
|
{
|
||||||
|
int m_bFloating;
|
||||||
|
int m_iClip;
|
||||||
|
int m_iWasDropped;
|
||||||
|
int id;
|
||||||
|
void item_pickup(void);
|
||||||
|
|
||||||
|
virtual void Spawned(void);
|
||||||
|
virtual void Touch(entity);
|
||||||
|
virtual void SetItem(int i);
|
||||||
|
virtual void Respawn(void);
|
||||||
|
virtual void SetFloating(int);
|
||||||
|
virtual void PickupRespawn(void);
|
||||||
|
};
|
92
base/src/server/items.qc
Normal file
92
base/src/server/items.qc
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void item_pickup::Touch(entity eToucher)
|
||||||
|
{
|
||||||
|
if (eToucher.classname != "player") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* don't remove if AddItem fails */
|
||||||
|
if (Weapons_AddItem((player)eToucher, id, m_iClip) == FALSE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Logging_Pickup(eToucher, this, __NULL__);
|
||||||
|
Sound_Play(other, CHAN_ITEM, "weapon.pickup");
|
||||||
|
|
||||||
|
UseTargets(eToucher, TRIG_TOGGLE, m_flDelay);
|
||||||
|
|
||||||
|
if (real_owner || m_iWasDropped == 1 || cvar("sv_playerslots") == 1) {
|
||||||
|
Destroy();
|
||||||
|
} else {
|
||||||
|
Disappear();
|
||||||
|
ScheduleThink(PickupRespawn, 30.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void item_pickup::SetItem(int i)
|
||||||
|
{
|
||||||
|
id = i;
|
||||||
|
m_oldModel = Weapons_GetWorldmodel(id);
|
||||||
|
SetModel(GetSpawnModel());
|
||||||
|
SetSize([-16,-16,0], [16,16,16]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void item_pickup::SetFloating(int i)
|
||||||
|
{
|
||||||
|
m_bFloating = rint(bound(0, m_bFloating, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
item_pickup::PickupRespawn(void)
|
||||||
|
{
|
||||||
|
Respawn();
|
||||||
|
Sound_Play(this, CHAN_ITEM, "item.respawn");
|
||||||
|
}
|
||||||
|
|
||||||
|
void item_pickup::Respawn(void)
|
||||||
|
{
|
||||||
|
SetSolid(SOLID_TRIGGER);
|
||||||
|
SetOrigin(GetSpawnOrigin());
|
||||||
|
botinfo = BOTINFO_WEAPON;
|
||||||
|
|
||||||
|
/* At some points, the item id might not yet be set */
|
||||||
|
if (GetSpawnModel()) {
|
||||||
|
SetModel(GetSpawnModel());
|
||||||
|
}
|
||||||
|
|
||||||
|
SetSize([-16,-16,0], [16,16,16]);
|
||||||
|
ReleaseThink();
|
||||||
|
|
||||||
|
if (!m_bFloating) {
|
||||||
|
DropToFloor();
|
||||||
|
SetMovetype(MOVETYPE_TOSS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
item_pickup::Spawned(void)
|
||||||
|
{
|
||||||
|
super::Spawned();
|
||||||
|
|
||||||
|
Sound_Precache("item.respawn");
|
||||||
|
Sound_Precache("weapon.pickup");
|
||||||
|
}
|
||||||
|
|
||||||
|
void item_pickup::item_pickup(void)
|
||||||
|
{
|
||||||
|
}
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
#define QWSSQC
|
#define QWSSQC
|
||||||
#define SERVER
|
#define SERVER
|
||||||
#define NEW_INVENTORY
|
|
||||||
|
|
||||||
#includelist
|
#includelist
|
||||||
/* engine, then nuclide headers & functions */
|
/* engine, then nuclide headers & functions */
|
||||||
|
@ -27,6 +26,7 @@ gamerules.qc
|
||||||
gamerules_singleplayer.qc
|
gamerules_singleplayer.qc
|
||||||
gamerules_multiplayer.qc
|
gamerules_multiplayer.qc
|
||||||
modelevent.qc
|
modelevent.qc
|
||||||
|
items.qc
|
||||||
|
|
||||||
/* global server/shared code */
|
/* global server/shared code */
|
||||||
../../../src/server/include.src
|
../../../src/server/include.src
|
||||||
|
|
40
base/src/shared/flags.h
Normal file
40
base/src/shared/flags.h
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* game flags */
|
||||||
|
#define GF_SEMI_TOGGLED (int)(1<<0)
|
||||||
|
#define GF_FLASHLIGHT (int)(1<<1)
|
||||||
|
#define GF_UNUSED3 (int)(1<<2)
|
||||||
|
#define GF_UNUSED4 (int)(1<<3)
|
||||||
|
#define GF_UNUSED5 (int)(1<<4)
|
||||||
|
#define GF_UNUSED6 (int)(1<<5)
|
||||||
|
#define GF_UNUSED7 (int)(1<<6)
|
||||||
|
#define GF_UNUSED8 (int)(1<<7)
|
||||||
|
#define GF_UNUSED9 (int)(1<<8)
|
||||||
|
#define GF_UNUSED10 (int)(1<<9)
|
||||||
|
#define GF_UNUSED11 (int)(1<<10)
|
||||||
|
#define GF_UNUSED12 (int)(1<<11)
|
||||||
|
#define GF_UNUSED13 (int)(1<<12)
|
||||||
|
#define GF_UNUSED14 (int)(1<<14)
|
||||||
|
#define GF_UNUSED15 (int)(1<<16)
|
||||||
|
#define GF_UNUSED16 (int)(1<<13)
|
||||||
|
#define GF_UNUSED17 (int)(1<<17)
|
||||||
|
#define GF_UNUSED18 (int)(1<<18)
|
||||||
|
#define GF_UNUSED19 (int)(1<<19)
|
||||||
|
#define GF_UNUSED20 (int)(1<<20)
|
||||||
|
#define GF_UNUSED21 (int)(1<<21)
|
||||||
|
#define GF_UNUSED22 (int)(1<<22)
|
||||||
|
#define GF_UNUSED23 (int)(1<<23)
|
|
@ -1,5 +1,8 @@
|
||||||
#includelist
|
#includelist
|
||||||
player.qc
|
player.qc
|
||||||
|
weapon_common.h
|
||||||
|
weapons.h
|
||||||
|
flags.h
|
||||||
fx_explosion.qc
|
fx_explosion.qc
|
||||||
fx_spark.qc
|
fx_spark.qc
|
||||||
fx_blood.qc
|
fx_blood.qc
|
||||||
|
@ -8,4 +11,6 @@ fx_corpse.qc
|
||||||
fx_gibhuman.qc
|
fx_gibhuman.qc
|
||||||
fx_impact.qc
|
fx_impact.qc
|
||||||
TestWeapon.qc
|
TestWeapon.qc
|
||||||
|
weapons.qc
|
||||||
|
weapon_common.qc
|
||||||
#endlist
|
#endlist
|
||||||
|
|
20
base/src/shared/weapons.h
Normal file
20
base/src/shared/weapons.h
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
WEAPON_NONE
|
||||||
|
};
|
20
base/src/shared/weapons.qc
Normal file
20
base/src/shared/weapons.qc
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
weapon_t w_null = {};
|
||||||
|
weapon_t g_weapons[] = {
|
||||||
|
w_null
|
||||||
|
};
|
|
@ -124,7 +124,7 @@ NSTraceAttack::_ApplyDamage(void)
|
||||||
|
|
||||||
/* the location _could_ be more accurate... */
|
/* the location _could_ be more accurate... */
|
||||||
if (m_eMultiTarget.CanBleed() == true) {
|
if (m_eMultiTarget.CanBleed() == true) {
|
||||||
FX_Blood(trace_endpos, [0.5,0,0]);
|
FX_Blood(trace_endpos, m_eMultiTarget.GetBloodColor());
|
||||||
}
|
}
|
||||||
|
|
||||||
trace_surface_id = m_iMultiBody;
|
trace_surface_id = m_iMultiBody;
|
||||||
|
|
|
@ -322,7 +322,7 @@ public:
|
||||||
/** Returns if the entity is visible from a given position and a field of view of 90 degrees. */
|
/** Returns if the entity is visible from a given position and a field of view of 90 degrees. */
|
||||||
nonvirtual bool VisibleVec(vector);
|
nonvirtual bool VisibleVec(vector);
|
||||||
/** Returns a normalized value of how far away the target is from the entity's view direction. 1 means dead-center. 0 means it's behind.*/
|
/** Returns a normalized value of how far away the target is from the entity's view direction. 1 means dead-center. 0 means it's behind.*/
|
||||||
nonvirtual bool DistanceFromYaw(entity);
|
nonvirtual bool DistanceFromYaw(vector);
|
||||||
/** Returns if the entity has any spawnflags set. */
|
/** Returns if the entity has any spawnflags set. */
|
||||||
nonvirtual bool HasSpawnFlags(float);
|
nonvirtual bool HasSpawnFlags(float);
|
||||||
/** Returns if the entity is aligned to the ground. */
|
/** Returns if the entity is aligned to the ground. */
|
||||||
|
|
|
@ -99,7 +99,7 @@ bool NSEntity::VisibleVec( vector org ) {
|
||||||
|
|
||||||
bool NSEntity::Visible( entity ent ) {
|
bool NSEntity::Visible( entity ent ) {
|
||||||
/* is it in our field of view? */
|
/* is it in our field of view? */
|
||||||
if ( DistanceFromYaw(ent) > 0.3f ) {
|
if ( DistanceFromYaw(ent.origin) > 0.3f ) {
|
||||||
traceline( origin, ent.origin, MOVE_NORMAL, this );
|
traceline( origin, ent.origin, MOVE_NORMAL, this );
|
||||||
if ( trace_fraction == 1.0f || trace_ent == ent ) {
|
if ( trace_fraction == 1.0f || trace_ent == ent ) {
|
||||||
print( sprintf( "%s can see %s\n", classname, ent.classname ) );
|
print( sprintf( "%s can see %s\n", classname, ent.classname ) );
|
||||||
|
@ -110,12 +110,12 @@ bool NSEntity::Visible( entity ent ) {
|
||||||
return ( false );
|
return ( false );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NSEntity::DistanceFromYaw( entity ent ) {
|
bool NSEntity::DistanceFromYaw( vector targetPos ) {
|
||||||
vector flDelta;
|
vector flDelta;
|
||||||
float flFoV;
|
float flFoV;
|
||||||
|
|
||||||
makevectors( angles );
|
makevectors( angles );
|
||||||
flDelta = normalize( ent.origin - origin );
|
flDelta = normalize( targetPos - origin );
|
||||||
return flDelta * v_forward;
|
return flDelta * v_forward;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -331,12 +331,16 @@ public:
|
||||||
nonvirtual bool InSequence(void);
|
nonvirtual bool InSequence(void);
|
||||||
|
|
||||||
/* animation cycles */
|
/* animation cycles */
|
||||||
/** Overridable: Called when we need to play a fresh idle framegroup. */
|
/** DEPRECATED, Overridable: Called when we need to play a fresh idle framegroup. */
|
||||||
virtual int AnimIdle(void);
|
virtual int AnimIdle(void);
|
||||||
/** Overridable: Called when we need to play a fresh walking framegroup. */
|
/** DEPRECATED, Overridable: Called when we need to play a fresh walking framegroup. */
|
||||||
virtual int AnimWalk(void);
|
virtual int AnimWalk(void);
|
||||||
/** Overridable: Called when we need to play a fresh running framegroup. */
|
/** DEPRECATED, Overridable: Called when we need to play a fresh running framegroup. */
|
||||||
virtual int AnimRun(void);
|
virtual int AnimRun(void);
|
||||||
|
/** Overridable: Returns which framegroup to play for a given ACT. */
|
||||||
|
virtual float FramegroupForAct(float);
|
||||||
|
/** Call to play an ACT on the given NSMonster. */
|
||||||
|
nonvirtual void ActPlay(float);
|
||||||
/** Call to play a single animation onto it, which cannot be interrupted by movement. */
|
/** Call to play a single animation onto it, which cannot be interrupted by movement. */
|
||||||
virtual void AnimPlay(float);
|
virtual void AnimPlay(float);
|
||||||
/** Internal use only. Run every frame to update animation parameters. */
|
/** Internal use only. Run every frame to update animation parameters. */
|
||||||
|
@ -417,8 +421,11 @@ private:
|
||||||
|
|
||||||
/* caching variables, don't save these */
|
/* caching variables, don't save these */
|
||||||
float m_actIdle;
|
float m_actIdle;
|
||||||
|
bool m_bTurning;
|
||||||
|
|
||||||
nonvirtual void _LerpTurnToEnemy(void);
|
nonvirtual void _LerpTurnToEnemy(void);
|
||||||
|
nonvirtual void _LerpTurnToPos(vector);
|
||||||
|
nonvirtual void _LerpTurnToYaw(vector);
|
||||||
virtual void _Alerted(void);
|
virtual void _Alerted(void);
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
|
@ -188,19 +188,33 @@ NSMonster::Restore(string strKey, string strValue)
|
||||||
int
|
int
|
||||||
NSMonster::AnimIdle(void)
|
NSMonster::AnimIdle(void)
|
||||||
{
|
{
|
||||||
return frameforaction(modelindex, ACT_IDLE);
|
return FramegroupForAct(ACT_IDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
NSMonster::AnimWalk(void)
|
NSMonster::AnimWalk(void)
|
||||||
{
|
{
|
||||||
return frameforaction(modelindex, ACT_WALK);
|
return FramegroupForAct(ACT_WALK);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
NSMonster::AnimRun(void)
|
NSMonster::AnimRun(void)
|
||||||
{
|
{
|
||||||
return frameforaction(modelindex, ACT_RUN);
|
float runAnim = FramegroupForAct(ACT_RUN);
|
||||||
|
return (runAnim == -1) ? AnimWalk() : runAnim;
|
||||||
|
}
|
||||||
|
|
||||||
|
float
|
||||||
|
NSMonster::FramegroupForAct(float actName)
|
||||||
|
{
|
||||||
|
float frameGroup = frameforaction(modelindex, actName);
|
||||||
|
return frameGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NSMonster::ActPlay(float actName)
|
||||||
|
{
|
||||||
|
AnimPlay(FramegroupForAct(actName));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -425,21 +439,21 @@ var float autocvar_ai_stepSize = 128;
|
||||||
float
|
float
|
||||||
NSMonster::GetWalkSpeed(void)
|
NSMonster::GetWalkSpeed(void)
|
||||||
{
|
{
|
||||||
float speed = autocvar_ai_stepSize / frameduration(modelindex, AnimWalk());
|
float speed = autocvar_ai_stepSize / frameduration(modelindex, FramegroupForAct(ACT_WALK));
|
||||||
return speed;
|
return speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
float
|
float
|
||||||
NSMonster::GetChaseSpeed(void)
|
NSMonster::GetChaseSpeed(void)
|
||||||
{
|
{
|
||||||
float speed = autocvar_ai_stepSize / frameduration(modelindex, AnimRun());
|
float speed = autocvar_ai_stepSize / frameduration(modelindex, FramegroupForAct(ACT_RUN));
|
||||||
return speed;
|
return speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
float
|
float
|
||||||
NSMonster::GetRunSpeed(void)
|
NSMonster::GetRunSpeed(void)
|
||||||
{
|
{
|
||||||
float speed = autocvar_ai_stepSize / frameduration(modelindex, AnimRun());
|
float speed = autocvar_ai_stepSize / frameduration(modelindex, FramegroupForAct(ACT_RUN));
|
||||||
return speed;
|
return speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -453,20 +467,27 @@ NSMonster::GetYawSpeed(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
NSMonster::_LerpTurnToEnemy(void)
|
NSMonster::_LerpTurnToYaw(vector turnYaw)
|
||||||
{
|
{
|
||||||
/* only continue if we're in one of the three states. */
|
|
||||||
if (GetState() != MONSTER_AIMING)
|
|
||||||
if (GetState() != MONSTER_CHASING)
|
|
||||||
if (GetState() != MONSTER_FOLLOWING)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!m_eEnemy)
|
|
||||||
return;
|
|
||||||
|
|
||||||
float turnSpeed = GetYawSpeed();
|
float turnSpeed = GetYawSpeed();
|
||||||
vector vecWishAngle = vectoangles(m_eEnemy.origin - origin);
|
vector vecWishAngle = turnYaw;
|
||||||
float yawDiff = anglesub(vecWishAngle[1], v_angle[1]);
|
float yawDiff = anglesub(turnYaw[1], v_angle[1]);
|
||||||
|
|
||||||
|
if (fabs(yawDiff) > 90) {
|
||||||
|
velocity = g_vec_null;
|
||||||
|
input_movevalues = g_vec_null;
|
||||||
|
|
||||||
|
if (m_bTurning == false)
|
||||||
|
if (yawDiff < 0) {
|
||||||
|
SetFrame(FramegroupForAct(ACT_TURN_RIGHT));
|
||||||
|
} else {
|
||||||
|
SetFrame(FramegroupForAct(ACT_TURN_LEFT));
|
||||||
|
}
|
||||||
|
|
||||||
|
m_bTurning = true;
|
||||||
|
} else {
|
||||||
|
m_bTurning = false;
|
||||||
|
}
|
||||||
|
|
||||||
/* min/max out the diff */
|
/* min/max out the diff */
|
||||||
if (yawDiff > 0) {
|
if (yawDiff > 0) {
|
||||||
|
@ -487,6 +508,29 @@ NSMonster::_LerpTurnToEnemy(void)
|
||||||
angles[1] = input_angles[1] = v_angle[1] = vecWishAngle[1];
|
angles[1] = input_angles[1] = v_angle[1] = vecWishAngle[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NSMonster::_LerpTurnToPos(vector turnPos)
|
||||||
|
{
|
||||||
|
vector vecWishAngle = vectoangles(turnPos - origin);
|
||||||
|
_LerpTurnToYaw(vecWishAngle);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
NSMonster::_LerpTurnToEnemy(void)
|
||||||
|
{
|
||||||
|
if (!m_eEnemy)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* only continue if we're in one of the three states. */
|
||||||
|
if (GetState() != MONSTER_AIMING)
|
||||||
|
if (GetState() != MONSTER_CHASING)
|
||||||
|
if (GetState() != MONSTER_FOLLOWING)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_LerpTurnToPos(m_eEnemy.origin);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
NSMonster::AttackThink(void)
|
NSMonster::AttackThink(void)
|
||||||
{
|
{
|
||||||
|
@ -662,29 +706,7 @@ NSMonster::WalkRoute(void)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* yaw interpolation */
|
/* yaw interpolation */
|
||||||
{
|
_LerpTurnToYaw(input_angles);
|
||||||
float turnSpeed = GetYawSpeed();
|
|
||||||
vector vecWishAngle = input_angles;
|
|
||||||
float yawDiff = anglesub(vecWishAngle[1], v_angle[1]);
|
|
||||||
|
|
||||||
/* min/max out the diff */
|
|
||||||
if (yawDiff > 0) {
|
|
||||||
v_angle[1] += turnSpeed * frametime;
|
|
||||||
|
|
||||||
if (v_angle[1] > vecWishAngle[1])
|
|
||||||
v_angle[1] = vecWishAngle[1];
|
|
||||||
} else if (yawDiff < 0) {
|
|
||||||
v_angle[1] -= turnSpeed * frametime;
|
|
||||||
|
|
||||||
if (v_angle[1] < vecWishAngle[1])
|
|
||||||
v_angle[1] = vecWishAngle[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* fix angles */
|
|
||||||
makevectors(v_angle);
|
|
||||||
vecWishAngle = vectoangles( v_forward );
|
|
||||||
angles[1] = input_angles[1] = v_angle[1] = vecWishAngle[1];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -699,6 +721,9 @@ NSMonster::AnimationUpdate(void)
|
||||||
if (GetState() == MONSTER_AIMING)
|
if (GetState() == MONSTER_AIMING)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (m_bTurning)
|
||||||
|
return;
|
||||||
|
|
||||||
float spvel = vlen(velocity);
|
float spvel = vlen(velocity);
|
||||||
float midspeed = GetWalkSpeed() + ((GetRunSpeed() - GetWalkSpeed()) * 0.5f);
|
float midspeed = GetWalkSpeed() + ((GetRunSpeed() - GetWalkSpeed()) * 0.5f);
|
||||||
|
|
||||||
|
@ -813,6 +838,7 @@ NSMonster::Physics(void)
|
||||||
input_buttons = 0;
|
input_buttons = 0;
|
||||||
input_timelength = frametime;
|
input_timelength = frametime;
|
||||||
input_angles = angles;
|
input_angles = angles;
|
||||||
|
m_bTurning = false;
|
||||||
|
|
||||||
/* when stuck in a sequence, forget enemies, combat stance */
|
/* when stuck in a sequence, forget enemies, combat stance */
|
||||||
if (GetSequenceState() != SEQUENCESTATE_NONE) {
|
if (GetSequenceState() != SEQUENCESTATE_NONE) {
|
||||||
|
|
60
src/shared/NSSquadMonster.h
Normal file
60
src/shared/NSSquadMonster.h
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define NSSQUADMONSTER_MAXMEMBERS 5
|
||||||
|
|
||||||
|
/** NSSquadMonster based NPCs are able to communicate strategies together. */
|
||||||
|
class
|
||||||
|
NSSquadMonster:NSMonster
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void NSSquadMonster(void);
|
||||||
|
|
||||||
|
#ifdef SERVER
|
||||||
|
/** Overridable: Called when this NPC became squad leader. */
|
||||||
|
virtual void HasBecomeSquadLeader(void);
|
||||||
|
/** Overridable: Called when this NPC joined a squad. */
|
||||||
|
virtual void HasJoinedSquad(void);
|
||||||
|
|
||||||
|
/** Returns true/false if they're in a squad. */
|
||||||
|
nonvirtual bool InSquad(void);
|
||||||
|
/** Returns whether or not they're the squad leader. */
|
||||||
|
nonvirtual bool IsSquadLeader(void);
|
||||||
|
/** Returns the leader of their squad. Invalid if none. */
|
||||||
|
nonvirtual NSSquadMonster GetSquadLeader(void);
|
||||||
|
|
||||||
|
/** Will find and attach to a Squad in the specified radius. */
|
||||||
|
nonvirtual void FindSquadNearMe(float);
|
||||||
|
|
||||||
|
/** Will add the specified NPC to this entity's current squad. */
|
||||||
|
nonvirtual void AddToSquad(NSSquadMonster);
|
||||||
|
/** Will remove the specified NPC from this entity's current squad. Can be called on self. */
|
||||||
|
nonvirtual void RemoveFromSquad(NSSquadMonster);
|
||||||
|
/** Returns the nearest available member of its squad. */
|
||||||
|
nonvirtual NSSquadMonster GetNearestSquadMember(void);
|
||||||
|
/** Returns the farthest available member of its squad. */
|
||||||
|
nonvirtual NSSquadMonster GetFarthestSquadMember(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SERVER
|
||||||
|
private:
|
||||||
|
bool m_inSquad;
|
||||||
|
NSSquadMonster m_eSquadLeader;
|
||||||
|
|
||||||
|
/* stored only in the squad leader's memory */
|
||||||
|
NSSquadMonster m_eSquadMembers[NSSQUADMONSTER_MAXMEMBERS];
|
||||||
|
#endif
|
||||||
|
};
|
216
src/shared/NSSquadMonster.qc
Normal file
216
src/shared/NSSquadMonster.qc
Normal file
|
@ -0,0 +1,216 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
NSSquadMonster::NSSquadMonster(void)
|
||||||
|
{
|
||||||
|
#ifdef SERVER
|
||||||
|
m_inSquad = false;
|
||||||
|
m_eSquadLeader = __NULL__;
|
||||||
|
|
||||||
|
for (int i = 0; i < NSSQUADMONSTER_MAXMEMBERS; i++) {
|
||||||
|
m_eSquadMembers[i] = __NULL__;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef SERVER
|
||||||
|
void
|
||||||
|
NSSquadMonster::HasBecomeSquadLeader(void)
|
||||||
|
{
|
||||||
|
/* implemented by sub-class */
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NSSquadMonster::HasJoinedSquad(void)
|
||||||
|
{
|
||||||
|
/* implemented by sub-class */
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
NSSquadMonster::InSquad(void)
|
||||||
|
{
|
||||||
|
return m_inSquad;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
NSSquadMonster::IsSquadLeader(void)
|
||||||
|
{
|
||||||
|
if (m_eSquadLeader == this)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSSquadMonster
|
||||||
|
NSSquadMonster::GetSquadLeader(void)
|
||||||
|
{
|
||||||
|
return m_eSquadLeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NSSquadMonster::FindSquadNearMe(float searchRadius)
|
||||||
|
{
|
||||||
|
entity searchResult = findradius(GetOrigin(), searchRadius);
|
||||||
|
|
||||||
|
while (searchResult) {
|
||||||
|
/* found someone just like us */
|
||||||
|
if (searchResult != this)
|
||||||
|
if (searchResult.classname == classname) {
|
||||||
|
NSSquadMonster squadMember = (NSSquadMonster)searchResult;
|
||||||
|
|
||||||
|
/* we found someone, they may not be in a squad (that's ok!)
|
||||||
|
as they will then create one. */
|
||||||
|
squadMember.AddToSquad(this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* advance the chain. */
|
||||||
|
searchResult = searchResult.chain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NSSquadMonster::AddToSquad(NSSquadMonster addMember)
|
||||||
|
{
|
||||||
|
NSSquadMonster startMember = __NULL__;
|
||||||
|
|
||||||
|
if (!addMember)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* no start? this monster just became a squad leader */
|
||||||
|
if (InSquad() == false) {
|
||||||
|
m_eSquadLeader = this;
|
||||||
|
startMember = this;
|
||||||
|
m_inSquad = true;
|
||||||
|
print(sprintf("%s (%d) became squad leader\n", classname, num_for_edict(this)));
|
||||||
|
HasBecomeSquadLeader();
|
||||||
|
}
|
||||||
|
|
||||||
|
startMember = GetSquadLeader();
|
||||||
|
|
||||||
|
/* fit the member into the nearest slot */
|
||||||
|
for (int i = 0; i < NSSQUADMONSTER_MAXMEMBERS; i++) {
|
||||||
|
if (startMember.m_eSquadMembers[i] == __NULL__) {
|
||||||
|
startMember.m_eSquadMembers[i] = addMember;
|
||||||
|
addMember.m_eSquadLeader = startMember;
|
||||||
|
addMember.m_inSquad = true;
|
||||||
|
addMember.HasJoinedSquad();
|
||||||
|
print(sprintf("%s (%d) added to squad, member %i\n", classname, num_for_edict(this), i));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NSSquadMonster::RemoveFromSquad(NSSquadMonster toRemove)
|
||||||
|
{
|
||||||
|
NSSquadMonster startMember = __NULL__;
|
||||||
|
|
||||||
|
/* don't bother if not in squad. */
|
||||||
|
if (InSquad() == false)
|
||||||
|
return;
|
||||||
|
if (!toRemove)
|
||||||
|
return;
|
||||||
|
|
||||||
|
startMember = GetSquadLeader();
|
||||||
|
|
||||||
|
/* fit the member into the nearest slot */
|
||||||
|
for (int i = 0; i < NSSQUADMONSTER_MAXMEMBERS; i++) {
|
||||||
|
if (startMember.m_eSquadMembers[i] == toRemove) {
|
||||||
|
startMember.m_eSquadMembers[i] = __NULL__;
|
||||||
|
toRemove.m_eSquadLeader = __NULL__;
|
||||||
|
toRemove.m_inSquad = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NSSquadMonster
|
||||||
|
NSSquadMonster::GetNearestSquadMember(void)
|
||||||
|
{
|
||||||
|
NSSquadMonster member = __NULL__;
|
||||||
|
NSSquadMonster nearestMember = __NULL__;
|
||||||
|
float dist = 0.0f;
|
||||||
|
float nearestDist = 99999.0f;
|
||||||
|
NSSquadMonster startMember;
|
||||||
|
|
||||||
|
if (InSquad() == false)
|
||||||
|
return __NULL__;
|
||||||
|
|
||||||
|
/* only leaders have the member list */
|
||||||
|
startMember = GetSquadLeader();
|
||||||
|
|
||||||
|
/* iterate through members... */
|
||||||
|
for (int i = 0; i < NSSQUADMONSTER_MAXMEMBERS; i++) {
|
||||||
|
member = startMember.m_eSquadMembers[i];
|
||||||
|
|
||||||
|
/* don't recognize self, ever */
|
||||||
|
if (member == __NULL__ || member == this)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* check the distance from us to a valid member */
|
||||||
|
member = startMember.m_eSquadMembers[i];
|
||||||
|
dist = vlen(member.GetOrigin() - GetOrigin());
|
||||||
|
|
||||||
|
/* found one */
|
||||||
|
if (dist < nearestDist) {
|
||||||
|
nearestDist = dist;
|
||||||
|
nearestMember = member;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nearestMember;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSSquadMonster
|
||||||
|
NSSquadMonster::GetFarthestSquadMember(void)
|
||||||
|
{
|
||||||
|
NSSquadMonster member = __NULL__;
|
||||||
|
NSSquadMonster farthestMember = __NULL__;
|
||||||
|
float dist = 0.0f;
|
||||||
|
float farthestDist = 0.0f;
|
||||||
|
NSSquadMonster startMember;
|
||||||
|
|
||||||
|
if (InSquad() == false)
|
||||||
|
return __NULL__;
|
||||||
|
|
||||||
|
/* only leaders have the member list */
|
||||||
|
startMember = GetSquadLeader();
|
||||||
|
|
||||||
|
/* iterate through members... */
|
||||||
|
for (int i = 0; i < NSSQUADMONSTER_MAXMEMBERS; i++) {
|
||||||
|
member = startMember.m_eSquadMembers[i];
|
||||||
|
|
||||||
|
/* don't recognize self, ever */
|
||||||
|
if (member == __NULL__ || member == this)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* check the distance from us to a valid member */
|
||||||
|
member = startMember.m_eSquadMembers[i];
|
||||||
|
dist = vlen(member.GetOrigin() - GetOrigin());
|
||||||
|
|
||||||
|
/* found one */
|
||||||
|
if (dist > farthestDist) {
|
||||||
|
farthestDist = dist;
|
||||||
|
farthestMember = member;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return farthestMember;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -47,37 +47,6 @@ typedef enumflags
|
||||||
It can take damage and can handle variously different types of impact. */
|
It can take damage and can handle variously different types of impact. */
|
||||||
class NSSurfacePropEntity:NSRenderableEntity
|
class NSSurfacePropEntity:NSRenderableEntity
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
float m_flBurnNext;
|
|
||||||
|
|
||||||
PREDICTED_FLOAT(armor)
|
|
||||||
PREDICTED_FLOAT_N(health)
|
|
||||||
|
|
||||||
#ifdef SERVER
|
|
||||||
/* fire/burning */
|
|
||||||
entity m_eBurner;
|
|
||||||
int m_iBurnWeapon;
|
|
||||||
float m_flBurnTime;
|
|
||||||
float m_flBurnDmgTime; /* for whenever they touch a hot flame */
|
|
||||||
|
|
||||||
/* I/O */
|
|
||||||
string m_strOnBreak;
|
|
||||||
|
|
||||||
/* life, death */
|
|
||||||
float m_oldHealth;
|
|
||||||
|
|
||||||
/* Surface/PropKit */
|
|
||||||
int m_iMaterial;
|
|
||||||
string m_strSurfData;
|
|
||||||
int m_iPropData;
|
|
||||||
string m_strPropData;
|
|
||||||
|
|
||||||
float m_flDeathTime;
|
|
||||||
|
|
||||||
nonvirtual void _SurfaceDataFinish(void);
|
|
||||||
nonvirtual void _PropDataFinish(void);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void NSSurfacePropEntity(void);
|
void NSSurfacePropEntity(void);
|
||||||
|
|
||||||
|
@ -154,6 +123,11 @@ public:
|
||||||
nonvirtual void SetPropData(string);
|
nonvirtual void SetPropData(string);
|
||||||
/** Returns how many seconds have passed since we died. Will return -1 if not applicable. */
|
/** Returns how many seconds have passed since we died. Will return -1 if not applicable. */
|
||||||
nonvirtual float TimeSinceDeath(void);
|
nonvirtual float TimeSinceDeath(void);
|
||||||
|
|
||||||
|
/** Sets the colour of the blood of this entity. */
|
||||||
|
nonvirtual void SetBloodColor(vector);
|
||||||
|
/** Returns the blood color of this entity. */
|
||||||
|
nonvirtual vector GetBloodColor(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CLIENT
|
#ifdef CLIENT
|
||||||
|
@ -164,8 +138,41 @@ public:
|
||||||
/* misc 'being' methods */
|
/* misc 'being' methods */
|
||||||
/** Returns the absolute world position of where the eyes are located. */
|
/** Returns the absolute world position of where the eyes are located. */
|
||||||
nonvirtual vector GetEyePos(void);
|
nonvirtual vector GetEyePos(void);
|
||||||
/** Sets the relative position of the eyes */
|
/** Sets the relative position of the eyes. */
|
||||||
nonvirtual void SetEyePos(vector);
|
nonvirtual void SetEyePos(vector);
|
||||||
|
|
||||||
|
private:
|
||||||
|
float m_flBurnNext;
|
||||||
|
|
||||||
|
PREDICTED_FLOAT(armor)
|
||||||
|
PREDICTED_FLOAT_N(health)
|
||||||
|
|
||||||
|
#ifdef SERVER
|
||||||
|
/* fire/burning */
|
||||||
|
entity m_eBurner;
|
||||||
|
int m_iBurnWeapon;
|
||||||
|
float m_flBurnTime;
|
||||||
|
float m_flBurnDmgTime; /* for whenever they touch a hot flame */
|
||||||
|
|
||||||
|
/* I/O */
|
||||||
|
string m_strOnBreak;
|
||||||
|
|
||||||
|
/* life, death */
|
||||||
|
float m_oldHealth;
|
||||||
|
vector m_vecBloodColor;
|
||||||
|
|
||||||
|
/* Surface/PropKit */
|
||||||
|
int m_iMaterial;
|
||||||
|
string m_strSurfData;
|
||||||
|
int m_iPropData;
|
||||||
|
string m_strPropData;
|
||||||
|
|
||||||
|
float m_flDeathTime;
|
||||||
|
|
||||||
|
nonvirtual void _SurfaceDataFinish(void);
|
||||||
|
nonvirtual void _PropDataFinish(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CLIENT
|
#ifdef CLIENT
|
||||||
|
|
|
@ -30,6 +30,7 @@ NSSurfacePropEntity::NSSurfacePropEntity(void)
|
||||||
m_oldHealth = 0;
|
m_oldHealth = 0;
|
||||||
m_strSurfData = __NULL__;
|
m_strSurfData = __NULL__;
|
||||||
m_strPropData = __NULL__;
|
m_strPropData = __NULL__;
|
||||||
|
m_vecBloodColor = [0.5, 0, 0];
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,6 +64,17 @@ NSSurfacePropEntity::Spawned(void)
|
||||||
|
|
||||||
/* networking */
|
/* networking */
|
||||||
#ifdef SERVER
|
#ifdef SERVER
|
||||||
|
void
|
||||||
|
NSSurfacePropEntity::SetBloodColor(vector newColor)
|
||||||
|
{
|
||||||
|
m_vecBloodColor = newColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector
|
||||||
|
NSSurfacePropEntity::GetBloodColor(void)
|
||||||
|
{
|
||||||
|
return m_vecBloodColor;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
NSSurfacePropEntity::IsAlive(void)
|
NSSurfacePropEntity::IsAlive(void)
|
||||||
|
|
|
@ -34,7 +34,7 @@ information and can speak more complicated dialogue.
|
||||||
|
|
||||||
They also can communicate with other NSTalkMonster based entities.
|
They also can communicate with other NSTalkMonster based entities.
|
||||||
*/
|
*/
|
||||||
class NSTalkMonster:NSMonster
|
class NSTalkMonster:NSSquadMonster
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void NSTalkMonster(void);
|
void NSTalkMonster(void);
|
||||||
|
|
|
@ -493,6 +493,7 @@ NSTalkMonster::FollowPlayer(void)
|
||||||
input_angles[0] = 0;
|
input_angles[0] = 0;
|
||||||
input_angles[1] = Math_FixDelta(input_angles[1]);
|
input_angles[1] = Math_FixDelta(input_angles[1]);
|
||||||
input_angles[2] = 0;
|
input_angles[2] = 0;
|
||||||
|
_LerpTurnToYaw(input_angles[1]);
|
||||||
|
|
||||||
/* for best results, we want to ignore the Z plane
|
/* for best results, we want to ignore the Z plane
|
||||||
this avoids the problem of a follower spinning
|
this avoids the problem of a follower spinning
|
||||||
|
@ -521,6 +522,7 @@ NSTalkMonster::FollowPlayer(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (DistanceFromYaw(vecParent) > 0.9f)
|
||||||
input_movevalues[0] = m_flFollowSpeed;
|
input_movevalues[0] = m_flFollowSpeed;
|
||||||
|
|
||||||
other = world;
|
other = world;
|
||||||
|
@ -532,6 +534,7 @@ NSTalkMonster::FollowPlayer(void)
|
||||||
input_angles[0] = 0;
|
input_angles[0] = 0;
|
||||||
input_angles[1] = Math_FixDelta(input_angles[1]);
|
input_angles[1] = Math_FixDelta(input_angles[1]);
|
||||||
input_angles[2] = 0;
|
input_angles[2] = 0;
|
||||||
|
_LerpTurnToYaw(input_angles[1]);
|
||||||
} else {
|
} else {
|
||||||
m_vecLastUserPos = m_eFollowingChain.origin;
|
m_vecLastUserPos = m_eFollowingChain.origin;
|
||||||
}
|
}
|
||||||
|
@ -617,7 +620,7 @@ NSTalkMonster::RunAI(void)
|
||||||
void
|
void
|
||||||
NSTalkMonster::Respawn(void)
|
NSTalkMonster::Respawn(void)
|
||||||
{
|
{
|
||||||
NSMonster::Respawn();
|
super::Respawn();
|
||||||
m_eFollowing = world;
|
m_eFollowing = world;
|
||||||
m_eFollowingChain = world;
|
m_eFollowingChain = world;
|
||||||
}
|
}
|
||||||
|
@ -658,7 +661,7 @@ NSTalkMonster::SpawnKey(string strKey, string strValue)
|
||||||
m_talkFollow = strcat("!", strValue);
|
m_talkFollow = strcat("!", strValue);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
NSMonster::SpawnKey(strKey, strValue);
|
super::SpawnKey(strKey, strValue);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,119 +0,0 @@
|
||||||
#ifndef MAX_WEAPONS
|
|
||||||
#define MAX_WEAPONS 32
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** This class represents inventory items and weapons that you can directly interact with.
|
|
||||||
|
|
||||||
Trouble that's standing in the way of this taking off:
|
|
||||||
|
|
||||||
Level changes currently only support client entities from setting up
|
|
||||||
changelevel parameters. There is parm_string that we *could* use to
|
|
||||||
store weapon entity information in, but this will grow massively.
|
|
||||||
|
|
||||||
For the time being, we need to use the legacy system if we want to support
|
|
||||||
singleplayer.
|
|
||||||
*/
|
|
||||||
class
|
|
||||||
NSWeapon:NSRenderableEntity
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
entity m_owner;
|
|
||||||
|
|
||||||
string m_strName; /* Full character name */
|
|
||||||
int m_iSlot;
|
|
||||||
int m_iSlotPos;
|
|
||||||
bool m_bAllowDropping;
|
|
||||||
int m_iWeight;
|
|
||||||
|
|
||||||
/* generic info */
|
|
||||||
int m_iClip1;
|
|
||||||
int m_iClip2;
|
|
||||||
float m_flPrimaryNext;
|
|
||||||
float m_flSecondaryNext;
|
|
||||||
float m_flLastFired;
|
|
||||||
|
|
||||||
public:
|
|
||||||
void NSWeapon(void);
|
|
||||||
|
|
||||||
/* inspired by GMOD API https://wiki.facepunch.com/gmod/Weapon */
|
|
||||||
/** Returns the model used to attach to players that wield this weapon */
|
|
||||||
virtual string GetPlayerModel(void);
|
|
||||||
/** Returns the model used to display in-world representations of this weapon. */
|
|
||||||
virtual string GetWorldModel(void);
|
|
||||||
/** Returns the name used in printed text for this weapon */
|
|
||||||
virtual string GetPrintName(void);
|
|
||||||
/** Returns if this weapon is allowed to be dropped. */
|
|
||||||
virtual bool AllowDropping(void);
|
|
||||||
/** Returns the framegroup used for the top-half of a player when aiming this weapon. */
|
|
||||||
virtual int GetPlayerAnim(void);
|
|
||||||
/** Returns a formatted obituary message.
|
|
||||||
Should contain two %s parameters, the first is the attacker and the second is the target. */
|
|
||||||
virtual string GetObituaryMessage(void);
|
|
||||||
/** Returns the weapon type. Check weapontype_t for details. */
|
|
||||||
virtual int GetType(void);
|
|
||||||
|
|
||||||
/** Returns primary attack clip */
|
|
||||||
virtual int GetClip1(void);
|
|
||||||
/** Returns secondary attack clip */
|
|
||||||
virtual int GetClip2(void);
|
|
||||||
/** Returns primary max clip size */
|
|
||||||
virtual int GetMaxClip1(void);
|
|
||||||
/** Returns secondary max clip size */
|
|
||||||
virtual int GetMaxClip2(void);
|
|
||||||
/** Returns the next time the primary mode can fire */
|
|
||||||
virtual float GetNextPrimaryFire(void);
|
|
||||||
/** Returns the next time the secondary mode can fire */
|
|
||||||
virtual float GetNextSecondaryFire(void);
|
|
||||||
/** Returns the slot/HUD category the weapon belongs in. */
|
|
||||||
virtual int GetSlot(void);
|
|
||||||
/** Returns the position the weapon belongs in of the slot specified in GetSlot() */
|
|
||||||
virtual int GetSlotPos(void);
|
|
||||||
/** Returns the 'weight', used for deciding what the next best weapon to switch to is. */
|
|
||||||
virtual int GetWeight(void);
|
|
||||||
/** Returns absolute time at which the weapon was last fired */
|
|
||||||
virtual float LastFireTime(void);
|
|
||||||
/** Sets the primary ammo clip count */
|
|
||||||
virtual void SetClip1(int);
|
|
||||||
/** Sets the secondary ammo clip count */
|
|
||||||
virtual void SetClip2(int);
|
|
||||||
/** Returns whether the weapon allows to being switched from when a better weighted weapon is picked up */
|
|
||||||
virtual bool AllowsAutoSwitchFrom(void);
|
|
||||||
/** Returns whether the weapon allows to being switched to when a better weighted weapon is picked up */
|
|
||||||
virtual bool AllowsAutoSwitchTo(void);
|
|
||||||
/** Returns if the weapon is empty, with no reserve ammonition */
|
|
||||||
virtual bool IsEmpty(void);
|
|
||||||
/** Returns if the weapon has ammo left in it. */
|
|
||||||
virtual bool HasAmmo(void);
|
|
||||||
|
|
||||||
/* calls */
|
|
||||||
/** Called to reload resources utilized by this weapon. */
|
|
||||||
virtual void Precache(void);
|
|
||||||
/** Called when the weapon was switched to from another. */
|
|
||||||
virtual void Draw(void);
|
|
||||||
/** Called right before switching to a new weapon. */
|
|
||||||
virtual void Holster(void);
|
|
||||||
/** Called whenever the command +attack is called by a client. */
|
|
||||||
virtual void Primary(void);
|
|
||||||
/** Called whenever the command +attack2 is called by a client. */
|
|
||||||
virtual void Secondary(void);
|
|
||||||
/** Called whenever the command +reload is called by a client. */
|
|
||||||
virtual void Reload(void);
|
|
||||||
/** Called whenever the no weapon command is called by a client. */
|
|
||||||
virtual void Release(void);
|
|
||||||
|
|
||||||
#ifdef CLIENT
|
|
||||||
/** Called before 3D world rendering is performed. */
|
|
||||||
virtual void ClientPredraw(void);
|
|
||||||
/** Called after 3D world rendering is performed. */
|
|
||||||
virtual void ClientPostdraw(void);
|
|
||||||
|
|
||||||
virtual void ReceiveEntity(float, float);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef SERVER
|
|
||||||
virtual float SendEntity(entity, float);
|
|
||||||
|
|
||||||
virtual void Touch(entity);
|
|
||||||
virtual void Respawn(void);
|
|
||||||
#endif
|
|
||||||
};
|
|
|
@ -1,246 +0,0 @@
|
||||||
void
|
|
||||||
NSWeapon::NSWeapon(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* calls */
|
|
||||||
void
|
|
||||||
NSWeapon::Precache(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
NSWeapon::Draw(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
NSWeapon::Holster(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
NSWeapon::Primary(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
NSWeapon::Secondary(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
NSWeapon::Reload(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
NSWeapon::Release(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CLIENT
|
|
||||||
void
|
|
||||||
NSWeapon::ClientPredraw(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
NSWeapon::ClientPostdraw(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
NSWeapon::ReceiveEntity(float new, float flChanged)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef SERVER
|
|
||||||
float
|
|
||||||
NSWeapon::SendEntity(entity ePEnt, float flChanged)
|
|
||||||
{
|
|
||||||
/* if we have a model, assume we're a pickup */
|
|
||||||
if (modelindex) {
|
|
||||||
return super::SendEntity(ePEnt, flChanged);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* don't network to anyone but the owner */
|
|
||||||
if (ePEnt != owner) {
|
|
||||||
return (false);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
WriteByte(MSG_ENTITY, ENT_WEAPON);
|
|
||||||
WriteFloat(MSG_ENTITY, flChanged);
|
|
||||||
WriteInt(MSG_ENTITY, m_iSlot);
|
|
||||||
WriteInt(MSG_ENTITY, m_iSlotPos);
|
|
||||||
WriteByte(MSG_ENTITY, m_bAllowDropping);
|
|
||||||
WriteInt(MSG_ENTITY, m_iWeight);
|
|
||||||
WriteInt(MSG_ENTITY, m_iClip1);
|
|
||||||
WriteInt(MSG_ENTITY, m_iClip2);
|
|
||||||
WriteFloat(MSG_ENTITY, m_flPrimaryNext);
|
|
||||||
WriteFloat(MSG_ENTITY, m_flSecondaryNext);
|
|
||||||
WriteFloat(MSG_ENTITY, m_flLastFired);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return (true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
NSWeapon::Touch(entity eToucher)
|
|
||||||
{
|
|
||||||
Hide();
|
|
||||||
SetSolid(SOLID_NOT);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
NSWeapon::Respawn(void)
|
|
||||||
{
|
|
||||||
/* the weapons gets placed in-world */
|
|
||||||
SetModel(GetWorldModel());
|
|
||||||
SetSolid(SOLID_TRIGGER);
|
|
||||||
SetOrigin(GetSpawnOrigin());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* get */
|
|
||||||
string
|
|
||||||
NSWeapon::GetPlayerModel(void)
|
|
||||||
{
|
|
||||||
return "models/error.vvm";
|
|
||||||
}
|
|
||||||
|
|
||||||
string
|
|
||||||
NSWeapon::GetWorldModel(void)
|
|
||||||
{
|
|
||||||
return "models/error.vvm";
|
|
||||||
}
|
|
||||||
|
|
||||||
string
|
|
||||||
NSWeapon::GetPrintName(void)
|
|
||||||
{
|
|
||||||
return m_strName;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
NSWeapon::GetSlot(void)
|
|
||||||
{
|
|
||||||
return m_iSlot;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
NSWeapon::GetSlotPos(void)
|
|
||||||
{
|
|
||||||
return m_iSlotPos;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
NSWeapon::AllowDropping(void)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
NSWeapon::GetWeight(void)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
NSWeapon::GetPlayerAnim(void)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
NSWeapon::IsEmpty(void)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
string
|
|
||||||
NSWeapon::GetObituaryMessage(void)
|
|
||||||
{
|
|
||||||
return "%s killed %s with Unknown";
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
NSWeapon::GetType(void)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
NSWeapon::GetClip1(void)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
NSWeapon::GetClip2(void)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
NSWeapon::GetMaxClip1(void)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
NSWeapon::GetMaxClip2(void)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
float
|
|
||||||
NSWeapon::GetNextPrimaryFire(void)
|
|
||||||
{
|
|
||||||
return m_flPrimaryNext;
|
|
||||||
}
|
|
||||||
|
|
||||||
float
|
|
||||||
NSWeapon::GetNextSecondaryFire(void)
|
|
||||||
{
|
|
||||||
return m_flSecondaryNext;
|
|
||||||
}
|
|
||||||
|
|
||||||
float
|
|
||||||
NSWeapon::LastFireTime(void)
|
|
||||||
{
|
|
||||||
return m_flLastFired;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
NSWeapon::SetClip1(int new_clip)
|
|
||||||
{
|
|
||||||
m_iClip1 = new_clip;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
NSWeapon::SetClip2(int new_clip)
|
|
||||||
{
|
|
||||||
m_iClip1 = new_clip;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
NSWeapon::AllowsAutoSwitchFrom(void)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
NSWeapon::AllowsAutoSwitchTo(void)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
NSWeapon::HasAmmo(void)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
|
@ -62,6 +62,7 @@ string __fullspawndata;
|
||||||
#include "NSPointTrigger.h"
|
#include "NSPointTrigger.h"
|
||||||
#include "NSNavAI.h"
|
#include "NSNavAI.h"
|
||||||
#include "NSMonster.h"
|
#include "NSMonster.h"
|
||||||
|
#include "NSSquadMonster.h"
|
||||||
#include "NSTalkMonster.h"
|
#include "NSTalkMonster.h"
|
||||||
#include "NSProjectile.h"
|
#include "NSProjectile.h"
|
||||||
#include "NSItem.h"
|
#include "NSItem.h"
|
||||||
|
@ -71,7 +72,6 @@ string __fullspawndata;
|
||||||
#include "../xr/defs.h"
|
#include "../xr/defs.h"
|
||||||
#include "NSClient.h"
|
#include "NSClient.h"
|
||||||
#include "NSClientSpectator.h"
|
#include "NSClientSpectator.h"
|
||||||
#include "NSWeapon.h"
|
|
||||||
#include "NSClientPlayer.h"
|
#include "NSClientPlayer.h"
|
||||||
|
|
||||||
#include "NSVehicle.h"
|
#include "NSVehicle.h"
|
||||||
|
|
|
@ -10,10 +10,10 @@ NSMoverEntity.qc
|
||||||
NSPhysicsEntity.qc
|
NSPhysicsEntity.qc
|
||||||
NSBrushTrigger.qc
|
NSBrushTrigger.qc
|
||||||
NSPointTrigger.qc
|
NSPointTrigger.qc
|
||||||
NSWeapon.qc
|
|
||||||
NSVehicle.qc
|
NSVehicle.qc
|
||||||
NSNavAI.qc
|
NSNavAI.qc
|
||||||
NSMonster.qc
|
NSMonster.qc
|
||||||
|
NSSquadMonster.qc
|
||||||
NSTalkMonster.qc
|
NSTalkMonster.qc
|
||||||
NSProjectile.qc
|
NSProjectile.qc
|
||||||
NSItem.qc
|
NSItem.qc
|
||||||
|
|
Loading…
Reference in a new issue