NSEntity: add SetOriginUnstick(), SetBotTag()
NSWeapon: basic inventory management functions
This commit is contained in:
parent
a852f887e2
commit
965d9e96d6
14 changed files with 274 additions and 31 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2022 Vera Visions LLC.
|
||||
* Copyright (c) 2016-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
|
||||
|
@ -18,11 +18,14 @@
|
|||
@brief Info tags for bots used to identify objects.
|
||||
@ingroup bot
|
||||
|
||||
Any entity can have these tags set onto using NSEntity::SetBotTag(), it will help
|
||||
the AI figure out a lot of game specific details.
|
||||
|
||||
@{
|
||||
*/
|
||||
|
||||
/* we need to keep this an enum so find() does its work faster */
|
||||
enum
|
||||
typedef enum
|
||||
{
|
||||
BOTINFO_NONE, /**< no info */
|
||||
BOTINFO_HEALTH, /**< health item */
|
||||
|
@ -32,8 +35,8 @@ enum
|
|||
BOTINFO_SPAWNPOINT, /**< place where to find new players */
|
||||
BOTINFO_TEAM_GOALITEM, /**< team-mode goal item (flag, intel) */
|
||||
BOTINFO_TEAM_GOALCAPTURE, /**< where to go when goal-item present */
|
||||
BOTINFO_END /**< end destination */
|
||||
};
|
||||
BOTINFO_END /**< end destination */
|
||||
} botInfo_t;
|
||||
|
||||
.float botinfo;
|
||||
|
||||
|
|
|
@ -397,14 +397,14 @@ Cmd_Parse(string sCMD)
|
|||
case "-gostand":
|
||||
pSeat->m_iInputJump = false;
|
||||
break;
|
||||
case "invnext":
|
||||
HUD_DrawWeaponSelect_Back();
|
||||
case "weapnext":
|
||||
NSWeapon_NextWeapon((NSClientPlayer)pSeat->m_ePlayer);
|
||||
break;
|
||||
case "invprev":
|
||||
HUD_DrawWeaponSelect_Forward();
|
||||
case "weapprev":
|
||||
NSWeapon_PrevWeapon((NSClientPlayer)pSeat->m_ePlayer);
|
||||
break;
|
||||
case "lastinv":
|
||||
HUD_DrawWeaponSelect_Last();
|
||||
case "weaplast":
|
||||
NSWeapon_LastWeapon((NSClientPlayer)pSeat->m_ePlayer);
|
||||
break;
|
||||
case "+showscores":
|
||||
pSeat->m_iScoresVisible = TRUE;
|
||||
|
@ -662,6 +662,8 @@ Cmd_Init(void)
|
|||
registercommand("-leanleft");
|
||||
registercommand("+leanright");
|
||||
registercommand("-leanright");
|
||||
registercommand("weapnext");
|
||||
registercommand("weapprev");
|
||||
|
||||
/* voting */
|
||||
registercommand("vote");
|
||||
|
@ -681,9 +683,6 @@ Cmd_Init(void)
|
|||
registercommand("slot8");
|
||||
registercommand("slot9");
|
||||
registercommand("slot10");
|
||||
registercommand("lastinv");
|
||||
registercommand("invnext");
|
||||
registercommand("invprev");
|
||||
|
||||
/* scoreboard */
|
||||
registercommand("+showscores");
|
||||
|
|
|
@ -216,23 +216,23 @@ trigger_teleport::Touch(entity eToucher)
|
|||
|
||||
if (eTarget) {
|
||||
vector endpos = eTarget.origin;
|
||||
float flSpeed = vlen(eToucher.velocity);
|
||||
float flSpeed = vlen(eActivator.velocity);
|
||||
makevectors(eTarget.angles);
|
||||
eToucher.velocity = (v_forward * flSpeed);
|
||||
eToucher.angles = eTarget.angles;
|
||||
eActivator.velocity = (v_forward * flSpeed);
|
||||
eActivator.angles = eTarget.angles;
|
||||
|
||||
if (eToucher.flags & FL_CLIENT) {
|
||||
Client_FixAngle(eToucher, eToucher.angles);
|
||||
if (eActivator.flags & FL_CLIENT) {
|
||||
Client_FixAngle(eActivator, eActivator.angles);
|
||||
|
||||
/* level designers place destinations where the feet
|
||||
are going to be, because monsters are mainly set up
|
||||
to be that way (0 0 0 being ground). players however
|
||||
have their it at the center of mass, so nudge it a little. */
|
||||
endpos[2] -= eToucher.mins[2];
|
||||
endpos[2] -= eActivator.mins[2];
|
||||
}
|
||||
|
||||
/* test if something is in the way. */
|
||||
tracebox(endpos, eToucher.mins, eToucher.maxs, endpos, MOVE_NORMAL, eToucher);
|
||||
tracebox(endpos, eActivator.mins, eActivator.maxs, endpos, MOVE_NORMAL, eActivator);
|
||||
|
||||
/* indeed something is in the way... */
|
||||
if (trace_ent && trace_startsolid == true) {
|
||||
|
@ -240,11 +240,11 @@ trigger_teleport::Touch(entity eToucher)
|
|||
if (trace_ent.takedamage != DAMAGE_NO) {
|
||||
NSSurfacePropEntity killThis = (NSSurfacePropEntity)trace_ent;
|
||||
killThis.SetHealth(-100);
|
||||
killThis.Death(this, eToucher, 1000, g_vec_null, 0i);
|
||||
killThis.Death(this, eActivator, 1000, g_vec_null, 0i);
|
||||
}
|
||||
}
|
||||
|
||||
setorigin_safe(eToucher, endpos);
|
||||
eActivator.SetOriginUnstick(endpos);
|
||||
|
||||
if (m_sndTeleport) {
|
||||
StartSoundDef(m_sndTeleport, CHAN_VOICE, true);
|
||||
|
@ -258,9 +258,9 @@ trigger_teleport::Touch(entity eToucher)
|
|||
StartSoundDef(m_sndTeleportExit, CHAN_VOICE, true);
|
||||
}
|
||||
|
||||
EntLog("Teleported %S to %v", eToucher.netname, endpos);
|
||||
EntLog("Teleported %S to %v", eActivator.netname, endpos);
|
||||
} else {
|
||||
EntWarning("Failed to teleport %S", eToucher.netname);
|
||||
EntWarning("Failed to teleport %S", eActivator.netname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -209,6 +209,8 @@ public:
|
|||
nonvirtual void SetAngularVelocity(vector);
|
||||
/** Sets the absolute 3D world position of the entity. */
|
||||
nonvirtual void SetOrigin(vector);
|
||||
/** Same as SetOrigin(), but will push the entity out the ground if needed. */
|
||||
nonvirtual void SetOriginUnstick(vector);
|
||||
/** Sets the bounding box size of the entity.
|
||||
This affects both collision and rendering bounds checking. */
|
||||
nonvirtual void SetSize(vector,vector);
|
||||
|
@ -419,6 +421,9 @@ public:
|
|||
|
||||
/** Will read from the named def to perform an attack. */
|
||||
virtual bool AttackByDef(string, bool);
|
||||
|
||||
/** Sets the @ref bot_info tag on this entity to the desired botInfo_t tag. */
|
||||
nonvirtual void SetBotTag(botInfo_t);
|
||||
};
|
||||
|
||||
/** Returns a new entity. Guaranteed to be something. Never __NULL__
|
||||
|
|
|
@ -638,6 +638,11 @@ NSEntity::SetOrigin(vector newOrigin) {
|
|||
setorigin(this, newOrigin);
|
||||
}
|
||||
|
||||
void
|
||||
NSEntity::SetOriginUnstick(vector newOrigin) {
|
||||
setorigin_safe(this, newOrigin);
|
||||
}
|
||||
|
||||
void
|
||||
NSEntity::SetModel(string newModel) {
|
||||
m_bIsBrush = substring(newModel, 0, 1) == "*" ? true : false;
|
||||
|
@ -1448,6 +1453,13 @@ NSEntity::AttackByDef(string defName, bool wasReleased)
|
|||
return (true);
|
||||
}
|
||||
|
||||
void
|
||||
NSEntity::SetBotTag(botInfo_t newTag)
|
||||
{
|
||||
#ifdef SERVER
|
||||
botinfo = newTag;
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
NSEntity::GetSharedID(void)
|
||||
|
|
|
@ -340,7 +340,7 @@ void
|
|||
NSItem::BecomePickup(void)
|
||||
{
|
||||
SetSolid(SOLID_TRIGGER);
|
||||
botinfo = BOTINFO_WEAPON;
|
||||
SetBotTag(BOTINFO_WEAPON);
|
||||
|
||||
if (m_bSpins)
|
||||
modelflags = MF_ROTATE;
|
||||
|
|
|
@ -1788,7 +1788,7 @@ NSMonster::Respawn(void)
|
|||
SetOrigin(GetSpawnVector("origin"));
|
||||
NSError("%S: %v, %v", classname, GetAngles(), GetOrigin());
|
||||
DropToFloor();
|
||||
setorigin_safe(this, origin);
|
||||
SetOriginUnstick(origin);
|
||||
}
|
||||
|
||||
super::Respawn();
|
||||
|
|
|
@ -557,7 +557,7 @@ NSNavAI::PlantCharge(string defName)
|
|||
#endif
|
||||
|
||||
/* push us outta the way! */
|
||||
setorigin_safe(this, GetOrigin());
|
||||
SetOriginUnstick(GetOrigin());
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
|
|
@ -34,9 +34,9 @@ NSSpawnPoint::Respawn(void)
|
|||
|
||||
super::Respawn();
|
||||
|
||||
setorigin_safe(this, GetSpawnVector("origin"));
|
||||
SetOriginUnstick(GetSpawnVector("origin"));
|
||||
SetSize(newMins, newMaxs);
|
||||
botinfo = BOTINFO_SPAWNPOINT;
|
||||
SetBotTag(BOTINFO_SPAWNPOINT);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -455,8 +455,8 @@ NSVehicle::PlayerLeave(NSClientPlayer pl)
|
|||
|
||||
owner = __NULL__;
|
||||
pl.vv_flags &= ~VFL_INVEHICLE;
|
||||
pl.velocity = g_vec_null;
|
||||
setorigin_safe(pl, pl.origin);
|
||||
pl.ClearVelocity();
|
||||
pl.SetOriginUnstick(pl.GetOrigin());
|
||||
|
||||
if (m_iVehicleFlags & VHF_FROZEN)
|
||||
pl.vv_flags &= ~VFL_FROZEN;
|
||||
|
|
|
@ -276,3 +276,4 @@ bool isWeaponClipOnly(string weaponDef);
|
|||
@return true/false whether or not the weapon creates a timed, fused detonating charge of sorts.
|
||||
@param weaponDef the name of the entityDef that defines the weapon.*/
|
||||
bool isWeaponDetonationTimed(string weaponDef);
|
||||
|
||||
|
|
|
@ -123,6 +123,8 @@ NSWeapon::Spawned(void)
|
|||
SetViewModel(m_strWeaponViewModel);
|
||||
SetWorldModel(model);
|
||||
SetPlayerModel(m_strWeaponPlayerModel);
|
||||
|
||||
printf("%S\n", classname);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1355,3 +1357,161 @@ isWeaponDetonationTimed(string weaponDef)
|
|||
bool isFused = (bool)stof(EntityDef_GetKeyValue(projectileDef, "detonate_on_fuse"));
|
||||
return (isFused);
|
||||
}
|
||||
|
||||
.NSWeapon m_nextWeapon;
|
||||
.NSWeapon m_prevWeapon;
|
||||
|
||||
NSWeapon
|
||||
NSWeapon_SortWeaponChain(NSClientPlayer targetPlayer)
|
||||
{
|
||||
NSWeapon itemChain = targetPlayer.m_itemList;
|
||||
int heighestSlot = -1i;
|
||||
int heighestPos = -1i;
|
||||
NSWeapon firstWeapon, lastWeapon;
|
||||
|
||||
firstWeapon = lastWeapon = __NULL__;
|
||||
|
||||
if (!targetPlayer.m_itemList) {
|
||||
return __NULL__;
|
||||
}
|
||||
|
||||
/* first we determine the range of our hud buckets. */
|
||||
while (itemChain) {
|
||||
if (itemChain.IsWeapon() == true) {
|
||||
int hudSlot = itemChain.GetDefInt("hudSlot");
|
||||
int hudPos = itemChain.GetDefInt("hudSlotPos");
|
||||
|
||||
if (hudSlot > heighestSlot) {
|
||||
heighestSlot = hudSlot;
|
||||
}
|
||||
if (hudPos > heighestPos) {
|
||||
heighestPos = hudPos;
|
||||
}
|
||||
}
|
||||
|
||||
itemChain = itemChain.chain;
|
||||
}
|
||||
|
||||
for (int hS = 0i; hS <= heighestSlot; hS++) {
|
||||
for (int hP = 0i; hP <= heighestPos; hP++) {
|
||||
itemChain = targetPlayer.m_itemList;
|
||||
|
||||
while (itemChain) {
|
||||
if (itemChain.IsWeapon() == true) {
|
||||
int hudSlot = itemChain.GetDefInt("hudSlot");
|
||||
int hudPos = itemChain.GetDefInt("hudSlotPos");
|
||||
|
||||
if (hudSlot == hS && hudPos == hP) {
|
||||
/* first weapon in the chain? */
|
||||
if (!lastWeapon) {
|
||||
firstWeapon = itemChain;
|
||||
lastWeapon = firstWeapon;
|
||||
} else {
|
||||
/* assign this weapon to the last weapon of our chain. */
|
||||
lastWeapon.m_nextWeapon = itemChain;
|
||||
itemChain.m_prevWeapon = lastWeapon;
|
||||
lastWeapon = itemChain;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
itemChain = itemChain.chain;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* test */
|
||||
NSWeapon weaponTest = firstWeapon;
|
||||
while (weaponTest) {
|
||||
weaponTest = weaponTest.m_nextWeapon;
|
||||
}
|
||||
|
||||
firstWeapon.m_prevWeapon = lastWeapon;
|
||||
|
||||
return (firstWeapon);
|
||||
}
|
||||
|
||||
#ifdef CLIENT
|
||||
bool
|
||||
NSWeapon_CanSwitch(NSClientPlayer pl)
|
||||
{
|
||||
if (!pl.m_activeWeapon)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
NSWeapon_SelectWeapon(NSWeapon nextWeapon)
|
||||
{
|
||||
if (!nextWeapon) {
|
||||
pSeat->m_iHUDWeaponSelected = 0i;
|
||||
return;
|
||||
}
|
||||
|
||||
pSeat->m_iHUDWeaponSelected = nextWeapon.GetSharedID();
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Select the next item in the list. */
|
||||
void
|
||||
NSWeapon_NextWeapon(NSNavAI pl)
|
||||
{
|
||||
#ifdef CLIENT
|
||||
NSWeapon firstWeapon;
|
||||
|
||||
if (NSWeapon_CanSwitch(pl) = false) {
|
||||
return;
|
||||
}
|
||||
|
||||
firstWeapon = NSWeapon_SortWeaponChain(pl);
|
||||
|
||||
if (pl.m_activeWeapon.m_nextWeapon) {
|
||||
NSWeapon_SelectWeapon(pl.m_activeWeapon.m_nextWeapon);
|
||||
} else {
|
||||
NSWeapon_SelectWeapon(firstWeapon);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Select the previous item in the list. */
|
||||
void
|
||||
NSWeapon_PrevWeapon(NSNavAI pl)
|
||||
{
|
||||
#ifdef CLIENT
|
||||
NSWeapon firstWeapon;
|
||||
|
||||
if (NSWeapon_CanSwitch(pl) = false) {
|
||||
return;
|
||||
}
|
||||
|
||||
firstWeapon = NSWeapon_SortWeaponChain(pl);
|
||||
|
||||
if (pl.m_activeWeapon.m_prevWeapon) {
|
||||
NSWeapon_SelectWeapon(pl.m_activeWeapon.m_prevWeapon);
|
||||
} else {
|
||||
NSWeapon_SelectWeapon(firstWeapon);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Select the previous item in the list. */
|
||||
void
|
||||
NSWeapon_LastWeapon(NSNavAI pl)
|
||||
{
|
||||
#ifdef CLIENT
|
||||
NSWeapon firstWeapon;
|
||||
|
||||
if (NSWeapon_CanSwitch(pl) = false) {
|
||||
return;
|
||||
}
|
||||
|
||||
firstWeapon = NSWeapon_SortWeaponChain(pl);
|
||||
|
||||
if (pl.m_activeWeapon.m_prevWeapon) {
|
||||
NSWeapon_SelectWeapon(pl.m_activeWeapon.m_prevWeapon);
|
||||
} else {
|
||||
NSWeapon_SelectWeapon(firstWeapon);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
4
src/shared/NSWeapon_NSNavAI.h
Normal file
4
src/shared/NSWeapon_NSNavAI.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
|
||||
void NSWeapon_NextWeapon(NSNavAI);
|
||||
void NSWeapon_PrevWeapon(NSNavAI);
|
||||
void NSWeapon_LastWeapon(NSNavAI);
|
|
@ -105,6 +105,7 @@ string __fullspawndata;
|
|||
#include "NSItem.h"
|
||||
#include "NSWeapon.h"
|
||||
#include "NSNavAI.h"
|
||||
#include "NSWeapon_NSNavAI.h"
|
||||
#include "NSMonster.h"
|
||||
#include "NSSquadMonster.h"
|
||||
#include "NSTalkMonster.h"
|
||||
|
@ -269,6 +270,64 @@ pseudorandom()
|
|||
return bound(0.01, (seed) / 100.0f, 0.99f);
|
||||
}
|
||||
|
||||
#if 0
|
||||
__wrap void
|
||||
WriteByte(float to, float val)
|
||||
{
|
||||
breakpoint();
|
||||
prior(to, val);
|
||||
}
|
||||
|
||||
__wrap void
|
||||
WriteChar(float to, float val)
|
||||
{
|
||||
breakpoint();
|
||||
prior(to, val);
|
||||
}
|
||||
|
||||
__wrap void
|
||||
WriteShort(float to, float val)
|
||||
{
|
||||
breakpoint();
|
||||
prior(to, val);
|
||||
}
|
||||
|
||||
__wrap void
|
||||
WriteLong(float to, float val)
|
||||
{
|
||||
breakpoint();
|
||||
prior(to, val);
|
||||
}
|
||||
|
||||
__wrap void
|
||||
WriteCoord(float to, float val)
|
||||
{
|
||||
breakpoint();
|
||||
prior(to, val);
|
||||
}
|
||||
|
||||
__wrap void
|
||||
WriteAngle(float to, float val)
|
||||
{
|
||||
breakpoint();
|
||||
prior(to, val);
|
||||
}
|
||||
|
||||
__wrap void
|
||||
WriteString(float to, string val)
|
||||
{
|
||||
breakpoint();
|
||||
prior(to, val);
|
||||
}
|
||||
|
||||
__wrap void
|
||||
WriteEntity(float to, entity val)
|
||||
{
|
||||
breakpoint();
|
||||
prior(to, val);
|
||||
}
|
||||
#endif
|
||||
|
||||
__wrap void
|
||||
setmodel(entity ent, string mname)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue