func_tracktrain: unbreak.
more cleanups.
This commit is contained in:
parent
6867396b09
commit
19b47e393c
81 changed files with 1419 additions and 822 deletions
|
@ -283,18 +283,6 @@ Event_Parse(float type)
|
|||
case EV_ENTITYEVENT:
|
||||
EV_EntityEvent();
|
||||
break;
|
||||
case EV_BLOOD:
|
||||
vector vBloodPos = g_vec_null;
|
||||
vector vBloodColor = g_vec_null;
|
||||
|
||||
vBloodPos[0] = readcoord();
|
||||
vBloodPos[1] = readcoord();
|
||||
vBloodPos[2] = readcoord();
|
||||
|
||||
vBloodColor[0] = readbyte() / 255;
|
||||
vBloodColor[1] = readbyte() / 255;
|
||||
vBloodColor[2] = readbyte() / 255;
|
||||
break;
|
||||
case EV_CHAT:
|
||||
float fSender = readbyte();
|
||||
float fTeam = readbyte();
|
||||
|
|
|
@ -27,7 +27,6 @@ enum
|
|||
EV_ANGLE,
|
||||
EV_IMPACT,
|
||||
EV_GIBHUMAN,
|
||||
EV_BLOOD,
|
||||
EV_EXPLOSION,
|
||||
EV_SPARK,
|
||||
EV_SHAKE,
|
||||
|
|
|
@ -35,6 +35,7 @@ class func_dustcloud:ncEntity
|
|||
{
|
||||
public:
|
||||
void func_dustcloud(void);
|
||||
virtual void Precache(void);
|
||||
virtual void Spawned(void);
|
||||
virtual float predraw(void);
|
||||
virtual void SpawnKey(string,string);
|
||||
|
@ -156,12 +157,17 @@ func_dustcloud::predraw(void)
|
|||
return (PREDRAW_NEXT);
|
||||
}
|
||||
|
||||
void
|
||||
func_dustcloud::Precache(void)
|
||||
{
|
||||
precache.Model(model);
|
||||
}
|
||||
|
||||
void
|
||||
func_dustcloud::Spawned(void)
|
||||
{
|
||||
super::Spawned();
|
||||
|
||||
precache_model(model);
|
||||
setmodel(this, model);
|
||||
setorigin(this, origin);
|
||||
movetype = MOVETYPE_NONE;
|
||||
|
|
|
@ -33,6 +33,7 @@ class func_dustmotes:ncEntity
|
|||
public:
|
||||
void func_dustmotes(void);
|
||||
|
||||
virtual void Precache(void);
|
||||
virtual void Spawned(void);
|
||||
virtual float predraw(void);
|
||||
virtual void SpawnKey(string,string);
|
||||
|
@ -44,6 +45,13 @@ private:
|
|||
float m_flNexTime;
|
||||
};
|
||||
|
||||
void
|
||||
func_dustmotes::func_dustmotes(void)
|
||||
{
|
||||
solid = SOLID_NOT;
|
||||
isCSQC = true;
|
||||
}
|
||||
|
||||
bool
|
||||
func_dustmotes::CanSpawn(bool clientSide)
|
||||
{
|
||||
|
@ -55,11 +63,13 @@ func_dustmotes::predraw(void)
|
|||
{
|
||||
vector vecPlayer = g_view.GetCameraOrigin();
|
||||
|
||||
if (checkpvs(vecPlayer, this) == FALSE)
|
||||
if (checkpvs(vecPlayer, this) == FALSE) {
|
||||
return (PREDRAW_NEXT);
|
||||
}
|
||||
|
||||
if (m_flNexTime > cltime)
|
||||
if (m_flNexTime > cltime) {
|
||||
return (PREDRAW_NEXT);
|
||||
}
|
||||
|
||||
for (int i = 0; i < m_iCount; i++) {
|
||||
vector vecPos;
|
||||
|
@ -75,12 +85,17 @@ func_dustmotes::predraw(void)
|
|||
return (PREDRAW_NEXT);
|
||||
}
|
||||
|
||||
void
|
||||
func_dustmotes::Precache(void)
|
||||
{
|
||||
precache.Model(model);
|
||||
}
|
||||
|
||||
void
|
||||
func_dustmotes::Spawned(void)
|
||||
{
|
||||
super::Spawned();
|
||||
|
||||
precache_model(model);
|
||||
setmodel(this, model);
|
||||
setorigin(this, origin);
|
||||
movetype = MOVETYPE_NONE;
|
||||
|
@ -100,10 +115,3 @@ func_dustmotes::SpawnKey(string strField, string strKey)
|
|||
super::SpawnKey(strField, strKey);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
func_dustmotes::func_dustmotes(void)
|
||||
{
|
||||
solid = SOLID_NOT;
|
||||
isCSQC = true;
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ class func_smokevolume:ncEntity
|
|||
public:
|
||||
void func_smokevolume(void);
|
||||
|
||||
virtual void Precache(void);
|
||||
virtual void Spawned(void);
|
||||
virtual float predraw(void);
|
||||
virtual void SpawnKey(string, string);
|
||||
|
@ -180,12 +181,17 @@ func_smokevolume::predraw(void)
|
|||
return (PREDRAW_NEXT);
|
||||
}
|
||||
|
||||
void
|
||||
func_smokevolume::Precache(void)
|
||||
{
|
||||
precache.Model(model);
|
||||
}
|
||||
|
||||
void
|
||||
func_smokevolume::Spawned(void)
|
||||
{
|
||||
super::Spawned();
|
||||
|
||||
precache_model(model);
|
||||
setmodel(this, model);
|
||||
setorigin(this, origin);
|
||||
movetype = MOVETYPE_NONE;
|
||||
|
|
|
@ -69,7 +69,8 @@ public:
|
|||
virtual void Save(float);
|
||||
virtual void Restore(string,string);
|
||||
virtual void SpawnKey(string,string);
|
||||
virtual void Spawned(void);
|
||||
virtual void Precache(void);
|
||||
virtual void Respawn(void);
|
||||
virtual void Trigger(entity, triggermode_t);
|
||||
|
||||
private:
|
||||
|
@ -129,13 +130,15 @@ env_beverage::SpawnKey(string strKey, string strValue)
|
|||
}
|
||||
|
||||
void
|
||||
env_beverage::Spawned(void)
|
||||
env_beverage::Precache(void)
|
||||
{
|
||||
super::Spawned();
|
||||
|
||||
precache_model("models/can.mdl");
|
||||
precache_sound("weapons/g_bounce3.wav");
|
||||
precache.Model("models/can.mdl");
|
||||
precache.Sound("weapons/g_bounce3.wav");
|
||||
}
|
||||
|
||||
void
|
||||
env_beverage::Respawn(void)
|
||||
{
|
||||
m_bReady = true;
|
||||
|
||||
if (m_sodaSkin == SKIN_RANDOM) {
|
||||
|
|
|
@ -51,7 +51,7 @@ env_shooter:ncRenderableEntity
|
|||
public:
|
||||
void env_shooter(void);
|
||||
|
||||
virtual void Spawned(void);
|
||||
virtual void Precache(void);
|
||||
virtual void Save(float);
|
||||
virtual void Restore(string,string);
|
||||
virtual void SpawnKey(string,string);
|
||||
|
@ -93,41 +93,39 @@ env_shooter::env_shooter(void)
|
|||
}
|
||||
|
||||
void
|
||||
env_shooter::Spawned(void)
|
||||
env_shooter::Precache(void)
|
||||
{
|
||||
super::Spawned();
|
||||
if (STRING_SET(m_strShootModel)) {
|
||||
precache.Model(m_strShootModel);
|
||||
|
||||
if (m_strShootModel) {
|
||||
precache_model(m_strShootModel);
|
||||
/* figure out if we're a sprite... */
|
||||
if (Util_ExtensionFromString(m_strShootModel) == "spr") {
|
||||
m_bCanScale = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* There isn't a much more portable to do this, maybe this can be abstracted
|
||||
through separate soundDef entries but I don't know if that'll be less annoying. */
|
||||
switch (m_flShootSounds) {
|
||||
case 0: /* glass */
|
||||
Sound_Precache("func_breakable.impact_glass");
|
||||
Sound_Precache("sfx_impact.glass");
|
||||
break;
|
||||
case 1: /* wood */
|
||||
Sound_Precache("func_breakable.impact_wood");
|
||||
Sound_Precache("sfx_impact.wood");
|
||||
break;
|
||||
case 2: /* metal */
|
||||
Sound_Precache("func_breakable.impact_metal");
|
||||
Sound_Precache("sfx_impact.metal");
|
||||
break;
|
||||
case 3: /* flesh */
|
||||
Sound_Precache("func_breakable.impact_flesh");
|
||||
Sound_Precache("sfx_impact.flesh");
|
||||
break;
|
||||
case 4: /* concrete */
|
||||
Sound_Precache("func_breakable.impact_concrete");
|
||||
Sound_Precache("sfx_impact.concrete");
|
||||
break;
|
||||
case -1: /* none */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* figure out if we're a sprite... */
|
||||
if (Util_ExtensionFromString(m_strShootModel) == "spr") {
|
||||
m_bCanScale = true;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -212,7 +210,7 @@ env_shooter::SpawnKey(string strKey, string strValue)
|
|||
m_flGibLife = ReadFloat(strValue);
|
||||
break;
|
||||
case "shootmodel":
|
||||
m_strShootModel = strValue;
|
||||
m_strShootModel = ReadString(strValue);
|
||||
break;
|
||||
case "shootsounds":
|
||||
m_flShootSounds = ReadFloat(strValue);
|
||||
|
|
|
@ -44,7 +44,7 @@ public:
|
|||
/* overrides */
|
||||
virtual void Save(float);
|
||||
virtual void Restore(string,string);
|
||||
virtual void Spawned(void);
|
||||
virtual void Precache(void);
|
||||
virtual void SpawnKey(string,string);
|
||||
virtual void customphysics(void);
|
||||
virtual void Respawn(void);
|
||||
|
@ -130,13 +130,11 @@ func_healthcharger::SpawnKey(string strKey, string strValue)
|
|||
}
|
||||
|
||||
void
|
||||
func_healthcharger::Spawned(void)
|
||||
func_healthcharger::Precache(void)
|
||||
{
|
||||
super::Spawned();
|
||||
|
||||
precache_sound(m_strSndFirst);
|
||||
precache_sound(m_strSndCharging);
|
||||
precache_sound(m_strSndDone);
|
||||
precache.Sound(m_strSndFirst);
|
||||
precache.Sound(m_strSndCharging);
|
||||
precache.Sound(m_strSndDone);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -46,7 +46,7 @@ public:
|
|||
virtual void Save(float);
|
||||
virtual void Restore(string,string);
|
||||
virtual void SpawnKey(string,string);
|
||||
virtual void Spawned(void);
|
||||
virtual void Precache(void);
|
||||
virtual void Respawn(void);
|
||||
virtual void customphysics(void);
|
||||
|
||||
|
@ -132,13 +132,11 @@ func_recharge::SpawnKey(string strKey, string strValue)
|
|||
}
|
||||
|
||||
void
|
||||
func_recharge::Spawned(void)
|
||||
func_recharge::Precache(void)
|
||||
{
|
||||
super::Spawned();
|
||||
|
||||
precache_sound(m_strSndFirst);
|
||||
precache_sound(m_strSndCharging);
|
||||
precache_sound(m_strSndDone);
|
||||
precache.Sound(m_strSndFirst);
|
||||
precache.Sound(m_strSndCharging);
|
||||
precache.Sound(m_strSndDone);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -76,7 +76,7 @@ func_tank:ncVehicle
|
|||
public:
|
||||
void func_tank(void);
|
||||
|
||||
virtual void Spawned(void);
|
||||
virtual void Precache(void);
|
||||
virtual void Save(float);
|
||||
virtual void Restore(string,string);
|
||||
virtual void customphysics(void);
|
||||
|
@ -209,55 +209,55 @@ func_tank::SpawnKey(string strKey, string strValue)
|
|||
{
|
||||
switch (strKey) {
|
||||
case "yawrate":
|
||||
m_flYawRate = stof(strValue);
|
||||
m_flYawRate = ReadFloat(strValue);
|
||||
break;
|
||||
case "yawrange":
|
||||
m_flYawRange = stof(strValue);
|
||||
m_flYawRange = ReadFloat(strValue);
|
||||
break;
|
||||
case "pitchrate":
|
||||
m_flPitchRate = stof(strValue);
|
||||
m_flPitchRate = ReadFloat(strValue);
|
||||
break;
|
||||
case "pitchrange":
|
||||
m_flPitchRange = stof(strValue);
|
||||
m_flPitchRange = ReadFloat(strValue);
|
||||
break;
|
||||
case "barrel":
|
||||
m_vecTipPos[0] = stof(strValue);
|
||||
m_vecTipPos[0] = ReadFloat(strValue);
|
||||
break;
|
||||
case "barrely":
|
||||
m_vecTipPos[1] = stof(strValue);
|
||||
m_vecTipPos[1] = ReadFloat(strValue);
|
||||
break;
|
||||
case "barrelz":
|
||||
m_vecTipPos[2] = stof(strValue);
|
||||
m_vecTipPos[2] = ReadFloat(strValue);
|
||||
break;
|
||||
case "firerate":
|
||||
m_flFireRate = 1.0f / stof(strValue);
|
||||
m_flFireRate = 1.0f / ReadFloat(strValue);
|
||||
break;
|
||||
case "bullet_damage":
|
||||
m_iDamage = stoi(strValue);
|
||||
m_iDamage = ReadInt(strValue);
|
||||
break;
|
||||
case "firespread":
|
||||
m_vecSpread = [0.25, 0.25, 0] * stof(strValue);
|
||||
m_vecSpread = [0.1, 0.1, 0] * ReadFloat(strValue);
|
||||
break;
|
||||
case "persistance":
|
||||
m_flPersistance = stof(strValue);
|
||||
m_flPersistance = ReadFloat(strValue);
|
||||
break;
|
||||
case "minRange":
|
||||
m_flMinRange = stof(strValue);
|
||||
m_flMinRange = ReadFloat(strValue);
|
||||
break;
|
||||
case "maxRange":
|
||||
m_flMaxRange = stof(strValue);
|
||||
m_flMaxRange = ReadFloat(strValue);
|
||||
break;
|
||||
case "spritesmoke":
|
||||
m_strSpriteSmoke = strValue;
|
||||
m_strSpriteSmoke = ReadString(strValue);
|
||||
break;
|
||||
case "spriteflash":
|
||||
m_strSpriteFlash = strValue;
|
||||
m_strSpriteFlash = ReadString(strValue);
|
||||
break;
|
||||
case "spritescale":
|
||||
m_flSpriteScale = stof(strValue);
|
||||
m_flSpriteScale = ReadFloat(strValue);
|
||||
break;
|
||||
case "rotatesound":
|
||||
m_strSndRotate = strValue;
|
||||
m_strSndRotate = ReadString(strValue);
|
||||
break;
|
||||
default:
|
||||
super::SpawnKey(strKey, strValue);
|
||||
|
@ -265,14 +265,10 @@ func_tank::SpawnKey(string strKey, string strValue)
|
|||
}
|
||||
|
||||
void
|
||||
func_tank::Spawned(void)
|
||||
func_tank::Precache(void)
|
||||
{
|
||||
super::Spawned();
|
||||
|
||||
if (m_strSpriteFlash)
|
||||
precache_model(m_strSpriteFlash);
|
||||
if (m_strSpriteSmoke)
|
||||
precache_model(m_strSpriteSmoke);
|
||||
precache.Model(m_strSpriteFlash);
|
||||
precache.Model(m_strSpriteSmoke);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -283,8 +279,9 @@ func_tank::Respawn(void)
|
|||
SetMovetype(MOVETYPE_PUSH);
|
||||
SetSolid(SOLID_BSP);
|
||||
|
||||
if (m_eDriver)
|
||||
if (m_eDriver) {
|
||||
PlayerLeave((ncPlayer)m_eDriver);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -294,8 +291,9 @@ func_tank::SpriteSmoke(vector org)
|
|||
remove(self);
|
||||
}
|
||||
|
||||
if (!m_strSpriteSmoke)
|
||||
if (!STRING_SET(m_strSpriteSmoke)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ncRenderableEntity smoke = spawn(ncRenderableEntity);
|
||||
smoke.SetModel(m_strSpriteSmoke);
|
||||
|
@ -315,8 +313,9 @@ func_tank::SpriteFlash(vector org)
|
|||
remove(self);
|
||||
}
|
||||
|
||||
if (!m_strSpriteFlash)
|
||||
if (!STRING_SET(m_strSpriteFlash)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ncRenderableEntity flash = spawn(ncRenderableEntity);
|
||||
flash.SetModel(m_strSpriteFlash);
|
||||
|
@ -332,18 +331,19 @@ func_tank::SpriteFlash(vector org)
|
|||
void
|
||||
func_tank::customphysics(void)
|
||||
{
|
||||
if (m_eDriver && m_eDriver.health <= 0)
|
||||
if (m_eDriver && m_eDriver.health <= 0) {
|
||||
PlayerLeave((ncPlayer)m_eDriver);
|
||||
}
|
||||
|
||||
if (m_eDriver) {
|
||||
vector endorg;
|
||||
makevectors(m_eDriver.v_angle);
|
||||
endorg = v_forward * 4086;
|
||||
angles = vectoangles(endorg - origin);
|
||||
endorg = anglesToForward(m_eDriver.v_angle) * 4096.0f;
|
||||
angles = vectorToAngles(endorg - origin);
|
||||
PlayerUpdateFlags();
|
||||
|
||||
if (vlen(m_eDriver.origin - origin) > 128)
|
||||
if (distance(m_eDriver.origin, origin) > 128) {
|
||||
PlayerLeave((ncPlayer)m_eDriver);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -550,19 +550,14 @@ func_tracktrain::Respawn(void)
|
|||
{
|
||||
super::Respawn();
|
||||
|
||||
if (modelindex == 0) {
|
||||
Destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
/* legacy compat */
|
||||
SetSolid(HasSpawnFlags(TRAIN_NONSOLID) ? SOLID_NOT : SOLID_BSP);
|
||||
SetMovetype(MOVETYPE_PUSH);
|
||||
|
||||
m_flCurrentSpeed = m_flStartSpeed;
|
||||
|
||||
ScheduleThink(_AfterSpawn, 0.0f);
|
||||
SetTriggerTarget(GetSpawnString("target"));
|
||||
/* this needs to be a bit later than anything else. */
|
||||
ScheduleThink(_AfterSpawn, 0.1f);
|
||||
PlayerUse = OnPlayerUse;
|
||||
|
||||
if (m_flTrainLength == 0.0f)
|
||||
|
@ -970,6 +965,8 @@ func_tracktrain::_AfterSpawn(void)
|
|||
path_track targetNode;
|
||||
path_track nodeAhead;
|
||||
|
||||
SetTriggerTarget(GetSpawnString("target"));
|
||||
|
||||
/* get the first target */
|
||||
targetNode = (path_track)GetTrackNodeForward();
|
||||
|
||||
|
|
|
@ -47,12 +47,27 @@ gibshooter:env_shooter
|
|||
{
|
||||
public:
|
||||
void gibshooter(void);
|
||||
|
||||
virtual void Spawned(void);
|
||||
virtual void Precache(void);
|
||||
};
|
||||
|
||||
void
|
||||
gibshooter::gibshooter(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
gibshooter::Spawned(void)
|
||||
{
|
||||
m_strShootModel = "models/hgibs.mdl";
|
||||
m_flShootSounds = 3;
|
||||
precache_model(m_strShootModel);
|
||||
|
||||
super::Spawned();
|
||||
}
|
||||
|
||||
void
|
||||
gibshooter::Precache(void)
|
||||
{
|
||||
precache.Model(m_strShootModel);
|
||||
}
|
||||
|
|
|
@ -49,13 +49,6 @@ typedef enum
|
|||
HINT_WORLD_ALIEN_BLOOD = 1003,
|
||||
} hinttype_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
IGNORE_NO,
|
||||
IGNORE_YES,
|
||||
IGNORE_DEFAULT
|
||||
} ignorefacing_t;
|
||||
|
||||
/* TODO: Make this match ncMonster more */
|
||||
typedef enum
|
||||
{
|
||||
|
@ -142,7 +135,7 @@ However, that was never completed.
|
|||
@ingroup pointentity
|
||||
*/
|
||||
class
|
||||
info_hint:ncPointTrigger
|
||||
info_hint:ncHint
|
||||
{
|
||||
public:
|
||||
void info_hint(void);
|
||||
|
|
|
@ -55,7 +55,7 @@ public:
|
|||
/* overrides */
|
||||
virtual void Save(float);
|
||||
virtual void Restore(string,string);
|
||||
virtual void Spawned(void);
|
||||
virtual void Precache(void);
|
||||
virtual void SpawnKey(string,string);
|
||||
virtual void customphysics(void);
|
||||
virtual void Respawn(void);
|
||||
|
@ -155,13 +155,11 @@ item_healthcharger::SpawnKey(string strKey, string strValue)
|
|||
}
|
||||
|
||||
void
|
||||
item_healthcharger::Spawned(void)
|
||||
item_healthcharger::Precache(void)
|
||||
{
|
||||
super::Spawned();
|
||||
|
||||
precache_sound(m_strSndFirst);
|
||||
precache_sound(m_strSndCharging);
|
||||
precache_sound(m_strSndDone);
|
||||
precache.Sound(m_strSndFirst);
|
||||
precache.Sound(m_strSndCharging);
|
||||
precache.Sound(m_strSndDone);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ public:
|
|||
/* overrides */
|
||||
virtual void Save(float);
|
||||
virtual void Restore(string,string);
|
||||
virtual void Spawned(void);
|
||||
virtual void Precache(void);
|
||||
virtual void SpawnKey(string,string);
|
||||
virtual void customphysics(void);
|
||||
virtual void Respawn(void);
|
||||
|
@ -155,13 +155,11 @@ item_recharge::SpawnKey(string strKey, string strValue)
|
|||
}
|
||||
|
||||
void
|
||||
item_recharge::Spawned(void)
|
||||
item_recharge::Precache(void)
|
||||
{
|
||||
super::Spawned();
|
||||
|
||||
precache_sound(m_strSndFirst);
|
||||
precache_sound(m_strSndCharging);
|
||||
precache_sound(m_strSndDone);
|
||||
precache.Sound(m_strSndFirst);
|
||||
precache.Sound(m_strSndCharging);
|
||||
precache.Sound(m_strSndDone);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -95,7 +95,7 @@ path_corner::Spawned(void)
|
|||
{
|
||||
super::Spawned();
|
||||
|
||||
if (m_strOnPass)
|
||||
if (STRING_SET(m_strOnPass))
|
||||
m_strOnPass = CreateOutput(m_strOnPass);
|
||||
}
|
||||
|
||||
|
|
|
@ -131,6 +131,7 @@ path_track::SpawnKey(string keyName, string setValue)
|
|||
void
|
||||
path_track::Respawn(void)
|
||||
{
|
||||
super::Respawn();
|
||||
m_bTrackEnabled = HasSpawnFlags(PATHTRACK_DISABLED) ? false : true;
|
||||
}
|
||||
|
||||
|
|
|
@ -126,9 +126,10 @@ trigger_auto::Respawn(void)
|
|||
void
|
||||
trigger_auto::Processing(void)
|
||||
{
|
||||
if (m_strGlobalState) {
|
||||
if (GetGlobalValue(m_strGlobalState) == 0)
|
||||
if (STRING_SET(m_strGlobalState)) {
|
||||
if (GetGlobalValue(m_strGlobalState) == 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
UseTargets(this, m_iTriggerState, m_flDelay);
|
||||
|
|
|
@ -76,6 +76,7 @@ public:
|
|||
virtual void Restore(string,string);
|
||||
virtual void SpawnKey(string,string);
|
||||
virtual void Spawned(void);
|
||||
virtual void Precache(void);
|
||||
virtual void Respawn(void);
|
||||
virtual void EvaluateEntity(void);
|
||||
virtual float SendEntity(entity,float);
|
||||
|
@ -225,7 +226,12 @@ ambient_generic::Spawned(void)
|
|||
spawnflags |= MSF_MULTIPLAYER;
|
||||
|
||||
super::Spawned();
|
||||
precache_sound(m_strSpawnPath);
|
||||
}
|
||||
|
||||
void
|
||||
ambient_generic::Precache(void)
|
||||
{
|
||||
precache.Sound(m_strSpawnPath);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -68,7 +68,7 @@ public:
|
|||
/* overrides */
|
||||
virtual void SpawnKey(string,string);
|
||||
virtual void Respawn(void);
|
||||
virtual void Spawned(void);
|
||||
virtual void Precache(void);
|
||||
|
||||
#ifdef SERVER
|
||||
virtual void Save(float);
|
||||
|
@ -298,14 +298,18 @@ env_bubbles::ReceiveEntity(float is_new, float flChanged)
|
|||
angles[2] = readcoord();
|
||||
}
|
||||
|
||||
if (flChanged & BUBBLES_DENSITY)
|
||||
if (flChanged & BUBBLES_DENSITY) {
|
||||
m_iDensity = readbyte();
|
||||
if (flChanged & BUBBLES_FREQUENCY)
|
||||
}
|
||||
if (flChanged & BUBBLES_FREQUENCY) {
|
||||
m_flFrequency = readfloat();
|
||||
if (flChanged & BUBBLES_CURRENT)
|
||||
}
|
||||
if (flChanged & BUBBLES_CURRENT) {
|
||||
m_flCurrent = readfloat();
|
||||
if (flChanged & BUBBLES_ENABLED)
|
||||
}
|
||||
if (flChanged & BUBBLES_ENABLED) {
|
||||
m_bEnabled = readbyte();
|
||||
}
|
||||
|
||||
think = EmitBubbles;
|
||||
nextthink = time + m_flFrequency;
|
||||
|
@ -340,16 +344,15 @@ env_bubbles::Respawn(void)
|
|||
m_flFrequency = m_flSpawnFrequency;
|
||||
m_flCurrent = m_flSpawnCurrent;
|
||||
|
||||
if (spawnflags & BUBFL_STARTOFF)
|
||||
if (spawnflags & BUBFL_STARTOFF) {
|
||||
m_bEnabled = false;
|
||||
else
|
||||
} else {
|
||||
m_bEnabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
env_bubbles::Spawned(void)
|
||||
env_bubbles::Precache(void)
|
||||
{
|
||||
super::Spawned();
|
||||
|
||||
precache_model("sprites/bubble.spr");
|
||||
precache.Model("sprites/bubble.spr");
|
||||
}
|
||||
|
|
|
@ -83,7 +83,6 @@ func_lod::Spawned(void)
|
|||
{
|
||||
super::Spawned();
|
||||
|
||||
precache_model(model);
|
||||
setmodel(this, model);
|
||||
setorigin(this, origin);
|
||||
movetype = MOVETYPE_NONE;
|
||||
|
@ -155,4 +154,4 @@ func_lod::SendEntity(entity a, float b)
|
|||
{
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -109,6 +109,11 @@ private:
|
|||
float m_flFireTime;
|
||||
};
|
||||
|
||||
void
|
||||
func_tankmortar::func_tankmortar(void)
|
||||
{
|
||||
m_iVehicleFlags |= VHF_FROZEN | VHF_NOATTACK;
|
||||
}
|
||||
|
||||
#ifdef CLIENT
|
||||
void
|
||||
|
@ -450,16 +455,7 @@ func_tankmortar::Spawned(void)
|
|||
super::Spawned();
|
||||
|
||||
#ifdef SERVER
|
||||
if (m_strSpriteFlash)
|
||||
precache_model(m_strSpriteFlash);
|
||||
if (m_strSpriteSmoke)
|
||||
precache_model(m_strSpriteSmoke);
|
||||
precache.Model(m_strSpriteFlash);
|
||||
precache.Model(m_strSpriteSmoke);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
func_tankmortar::func_tankmortar(void)
|
||||
{
|
||||
m_iVehicleFlags |= VHF_FROZEN | VHF_NOATTACK;
|
||||
|
||||
}
|
||||
|
|
|
@ -55,10 +55,10 @@ This entity was introduced in Quake (1996).
|
|||
*/
|
||||
|
||||
#ifdef SERVER
|
||||
class NSWorldspawn:ncEntity
|
||||
class ncWorldSpawn:ncEntity
|
||||
{
|
||||
public:
|
||||
void NSWorldspawn(void);
|
||||
void ncWorldSpawn(void);
|
||||
|
||||
virtual void Spawned(void);
|
||||
virtual void Save(float);
|
||||
|
@ -83,7 +83,7 @@ private:
|
|||
};
|
||||
|
||||
void
|
||||
NSWorldspawn::NSWorldspawn(void)
|
||||
ncWorldSpawn::ncWorldSpawn(void)
|
||||
{
|
||||
/* defaults */
|
||||
m_flHDRIrisMinValue = 0.0;
|
||||
|
@ -128,14 +128,14 @@ NSWorldspawn::NSWorldspawn(void)
|
|||
lightstyle(64, "m");
|
||||
lightstyle(65, "z");
|
||||
|
||||
precache_model("models/error.vvm");
|
||||
precache.Model("models/error.vvm");
|
||||
|
||||
//if (autocvar_sv_levelexec)
|
||||
// readcmd(sprintf("exec maps/%s.cfg\n", mapname));
|
||||
}
|
||||
|
||||
void
|
||||
NSWorldspawn::Spawned(void)
|
||||
ncWorldSpawn::Spawned(void)
|
||||
{
|
||||
super::Spawned();
|
||||
|
||||
|
@ -171,7 +171,7 @@ NSWorldspawn::Spawned(void)
|
|||
}
|
||||
|
||||
void
|
||||
NSWorldspawn::SpawnKey(string strKey, string strValue)
|
||||
ncWorldSpawn::SpawnKey(string strKey, string strValue)
|
||||
{
|
||||
switch (strKey) {
|
||||
case "skyname":
|
||||
|
@ -228,7 +228,7 @@ NSWorldspawn::SpawnKey(string strKey, string strValue)
|
|||
}
|
||||
|
||||
void
|
||||
NSWorldspawn::Save(float handle)
|
||||
ncWorldSpawn::Save(float handle)
|
||||
{
|
||||
super::Save(handle);
|
||||
|
||||
|
@ -248,7 +248,7 @@ NSWorldspawn::Save(float handle)
|
|||
}
|
||||
|
||||
void
|
||||
NSWorldspawn::Restore(string strKey, string strValue)
|
||||
ncWorldSpawn::Restore(string strKey, string strValue)
|
||||
{
|
||||
switch (strKey) {
|
||||
case "m_strSkyName":
|
||||
|
@ -299,7 +299,7 @@ NSWorldspawn::Restore(string strKey, string strValue)
|
|||
void
|
||||
worldspawn(void)
|
||||
{
|
||||
NSWorldspawn ourWorld = spawn(NSWorldspawn);
|
||||
ncWorldSpawn ourWorld = spawn(ncWorldSpawn);
|
||||
ourWorld.pvsflags = PVSF_IGNOREPVS;
|
||||
|
||||
/* fill the delegate with spawndata */
|
||||
|
|
65
src/nav/Hint.h
Normal file
65
src/nav/Hint.h
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2025 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.
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
IGNORE_NO,
|
||||
IGNORE_YES,
|
||||
IGNORE_DEFAULT
|
||||
} ignorefacing_t;
|
||||
|
||||
/*! \brief Nav Hint */
|
||||
/*!QUAKED ncNavHint (0 0 0) (-8 -8 -8) (8 8 8)
|
||||
# OVERVIEW
|
||||
Helper entity for the Nav routines. Defines where to go for
|
||||
sensible defense/offensive or other hints.
|
||||
|
||||
# KEYS
|
||||
- "targetname" : Name
|
||||
- "hintType" : Hint type, this controls this hints' purpose. Be short and descriptive.
|
||||
- "hintActivity" : Associated animation activity. Once an NPC goes to this node they'll play it
|
||||
- "nodeFOV" : Field of view of the node. You'll probably want to set a sensible angle too.
|
||||
- "StartHintDisabled" : Whether or not to 'hide' the hint on start, requiring activation to work.
|
||||
- "Group" : Hint group definition. Some NPCs are set up to only look for their specific group.
|
||||
- "IgnoreFacing" : Whether or not we need to ignore the angle and field of view setting, see notes.
|
||||
- "mindsetFilter" : Comma-separated list of mindsets required to use this hint, see notes.
|
||||
|
||||
The 'IgnoreFacing' field can be one of 3 values:
|
||||
|
||||
- NO = 0
|
||||
- YES = 1
|
||||
- AUTO = 2
|
||||
*/
|
||||
class
|
||||
ncHint:ncPointTrigger
|
||||
{
|
||||
public:
|
||||
void ncHint(void);
|
||||
|
||||
/* overrides */
|
||||
virtual void Save(float);
|
||||
virtual void Restore(string,string);
|
||||
virtual void SpawnKey(string,string);
|
||||
virtual void Spawned(void);
|
||||
|
||||
private:
|
||||
string m_hintType;
|
||||
string m_strHintActivity;
|
||||
float m_flNodeFOV;
|
||||
string m_strHintGroup;
|
||||
ignorefacing_t m_ignoreFacing;
|
||||
string m_mindsetFilter;
|
||||
};
|
102
src/nav/Hint.qc
Normal file
102
src/nav/Hint.qc
Normal file
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2025 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
|
||||
ncHint::ncHint(void)
|
||||
{
|
||||
m_hintType = __NULL__;
|
||||
m_strHintActivity = __NULL__;
|
||||
m_flNodeFOV = 360;
|
||||
m_strHintGroup = __NULL__;
|
||||
m_ignoreFacing = IGNORE_DEFAULT;
|
||||
m_mindsetFilter = __NULL__;
|
||||
};
|
||||
|
||||
void
|
||||
ncHint::Save(float handle)
|
||||
{
|
||||
super::Save(handle);
|
||||
SaveString(handle, "m_hintType", m_hintType);
|
||||
SaveString(handle, "m_strHintActivity", m_strHintActivity);
|
||||
SaveFloat(handle, "m_flNodeFOV", m_flNodeFOV);
|
||||
SaveString(handle, "m_strHintGroup", m_strHintGroup);
|
||||
SaveFloat(handle, "m_ignoreFacing", m_ignoreFacing);
|
||||
SaveString(handle, "m_mindsetFilter", m_mindsetFilter);
|
||||
}
|
||||
|
||||
void
|
||||
ncHint::Restore(string strKey, string strValue)
|
||||
{
|
||||
switch (strKey) {
|
||||
case "m_hintType":
|
||||
m_hintType = ReadString(strValue);
|
||||
break;
|
||||
case "m_strHintActivity":
|
||||
m_strHintActivity = ReadString(strValue);
|
||||
break;
|
||||
case "m_flNodeFOV":
|
||||
m_flNodeFOV = ReadFloat(strValue);
|
||||
break;
|
||||
case "m_strHintGroup":
|
||||
m_strHintGroup = ReadString(strValue);
|
||||
break;
|
||||
case "m_ignoreFacing":
|
||||
m_ignoreFacing = ReadFloat(strValue);
|
||||
break;
|
||||
case "m_mindsetFilter":
|
||||
m_mindsetFilter = ReadString(strValue);
|
||||
break;
|
||||
default:
|
||||
super::Restore(strKey, strValue);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ncHint::SpawnKey(string strKey, string strValue)
|
||||
{
|
||||
switch (strKey) {
|
||||
case "hinttype":
|
||||
m_hintType = ReadString(strValue);
|
||||
break;
|
||||
case "hintactivity":
|
||||
m_strHintActivity = ReadString(strValue);
|
||||
break;
|
||||
case "nodeFOV":
|
||||
m_flNodeFOV = ReadFloat(strValue);
|
||||
break;
|
||||
case "StartDisabled":
|
||||
m_bStartDisabled = ReadFloat(strValue) == 1 ? true : false;
|
||||
break;
|
||||
case "Group":
|
||||
m_strHintGroup = ReadString(strValue);
|
||||
break;
|
||||
case "IgnoreFacing":
|
||||
m_ignoreFacing = ReadFloat(strValue);
|
||||
break;
|
||||
case "MinimumState":
|
||||
m_mindsetFilter = ReadString(strValue);
|
||||
break;
|
||||
default:
|
||||
super::SpawnKey(strKey, strValue);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ncHint::Spawned(void)
|
||||
{
|
||||
super::Spawned();
|
||||
SetEditorIcon("help");
|
||||
}
|
79
src/nav/NavInfo.h
Normal file
79
src/nav/NavInfo.h
Normal file
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright (c) 2025 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.
|
||||
*/
|
||||
|
||||
class
|
||||
ncNavInfo
|
||||
{
|
||||
public:
|
||||
nonvirtual vector PositionOfClosestNode(vector);
|
||||
|
||||
/** Returns the position of a spot that'll provide cover from the specified enemy.
|
||||
|
||||
@param targetEnemy The enemy to hide from.
|
||||
@return Absolute position of a valid cover spot. */
|
||||
nonvirtual vector FindCoverFromEnemy(ncActor targetEnemy);
|
||||
|
||||
/** Returns the position of a spot that'll be behind where you're currently standing
|
||||
|
||||
@param targetPosition The position to back away from.
|
||||
@param eulerDirection The direction we're looking in, in euler-angles.
|
||||
@return Absolute position of a valid cover spot. */
|
||||
nonvirtual vector FindBackFromPosition(vector targetPosition, vector eulerDirection);
|
||||
|
||||
|
||||
/** Returns the position of a spot that'll provide cover from the specified enemy, closest to a specified node.
|
||||
|
||||
@param targetEnemy The enemy to hide from.
|
||||
@param nodePosition The position we should get closest to.
|
||||
@return Absolute position of a valid cover spot. */
|
||||
nonvirtual vector FindCoverFromEnemyNearNode(ncActor targetEnemy, vector nodePosition);
|
||||
|
||||
|
||||
/** Returns the position of a spot that'll provide cover from the specified enemy, furthest from a specified node.
|
||||
|
||||
@param targetEnemy The enemy to hide from.
|
||||
@param nodePosition The position we should get as far away from as possible from.
|
||||
@return Absolute position of a valid cover spot. */
|
||||
nonvirtual vector FindCoverFromEnemyFarNode(ncActor targetEnemy, vector nodePosition);
|
||||
|
||||
|
||||
/** Returns the position of a spot that'll provide cover from the specified enemy.
|
||||
|
||||
@param traceEntity The entity which will be testing for collisions.
|
||||
@param targetOrigin The spot to hide from.
|
||||
@return Absolute position of a valid cover spot. */
|
||||
nonvirtual vector FindCoverFromPosition(entity traceEntity, vector targetOrigin);
|
||||
|
||||
|
||||
/** Returns the position of a spot that is accessible within a specified position.
|
||||
|
||||
@param traceEntity The entity which will be testing for collisions.
|
||||
@param targetOrigin The spot to be near.
|
||||
@param minRadius The mininum distance / search radius from the targetOrigin.
|
||||
@param maxRadius The maximum Radius in which we'll look for a free spot.
|
||||
@return Absolute position of a valid cover spot. */
|
||||
nonvirtual vector FindEmptySpotNearPosition(entity traceEntity, vector position, float minRadius, float maxRadius);
|
||||
|
||||
|
||||
/** Returns the position of a spot that is far away within a specified position.
|
||||
|
||||
@param traceEntity The entity which will be testing for collisions.
|
||||
@param targetOrigin The spot to be near.
|
||||
@param minRadius The mininum distance / search radius from the targetOrigin.
|
||||
@param maxRadius The maximum Radius in which we'll look for a free spot.
|
||||
@return Absolute position of a valid cover spot. */
|
||||
nonvirtual vector FindEmptySpotAwayFromPosition(entity traceEntity, vector position, float minRadius, float maxRadius);
|
||||
};
|
246
src/nav/NavInfo.qc
Normal file
246
src/nav/NavInfo.qc
Normal file
|
@ -0,0 +1,246 @@
|
|||
/*
|
||||
* Copyright (c) 2025 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.
|
||||
*/
|
||||
|
||||
/* Helper functions for tasks/nav */
|
||||
vector
|
||||
ncNavInfo::PositionOfClosestNode(vector pointOrigin)
|
||||
{
|
||||
float bestDistance = COST_INFINITE;
|
||||
int bestNodeID = -1;
|
||||
|
||||
for (int i = 0; i < g_iNodes; i++) {
|
||||
vector nodePosition = g_pNodes[i].m_vecOrigin;
|
||||
float nodeDistance = distanceSquared(nodePosition, pointOrigin);
|
||||
|
||||
if (nodeDistance < bestDistance) {
|
||||
bestDistance = nodeDistance;
|
||||
bestNodeID = i;
|
||||
}
|
||||
}
|
||||
|
||||
return (g_pNodes[bestNodeID].m_vecOrigin);
|
||||
}
|
||||
|
||||
vector
|
||||
ncNavInfo::FindCoverFromEnemy(ncActor targetEnemy)
|
||||
{
|
||||
float bestDistance = COST_INFINITE;
|
||||
int bestNodeID = -1i;
|
||||
|
||||
for (int i = 0; i < g_iNodes; i++) {
|
||||
vector nodePosition = g_pNodes[i].m_vecOrigin;
|
||||
float nodeRadius = g_pNodes[i].m_flRadius;
|
||||
float nodeDistance = distanceSquared(nodePosition, targetEnemy.origin);
|
||||
traceline(targetEnemy.origin, nodePosition, MOVE_NORMAL, targetEnemy);
|
||||
|
||||
if (trace_fraction < 1.0 && nodeDistance < bestDistance) {
|
||||
bestDistance = nodeDistance;
|
||||
bestNodeID = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (bestNodeID != -1i) {
|
||||
return g_vec_null;
|
||||
}
|
||||
|
||||
return (g_pNodes[bestNodeID].m_vecOrigin);
|
||||
}
|
||||
|
||||
vector
|
||||
ncNavInfo::FindBackFromPosition(vector targetPosition, vector eulerDirection)
|
||||
{
|
||||
float bestDistance = COST_INFINITE;
|
||||
int bestNodeID = -1;
|
||||
vector forwardDir = anglesToForward(eulerDirection);
|
||||
|
||||
for (int i = 0; i < g_iNodes; i++) {
|
||||
vector nodePosition = g_pNodes[i].m_vecOrigin;
|
||||
float nodeRadius = g_pNodes[i].m_flRadius;
|
||||
float nodeDistance = distanceSquared(nodePosition, targetPosition);
|
||||
traceline(targetPosition, nodePosition, MOVE_NORMAL, world);
|
||||
|
||||
if (trace_fraction < 1.0 && nodeDistance < bestDistance) {
|
||||
bestDistance = nodeDistance;
|
||||
bestNodeID = i;
|
||||
}
|
||||
}
|
||||
|
||||
return (g_pNodes[bestNodeID].m_vecOrigin);
|
||||
}
|
||||
|
||||
vector
|
||||
ncNavInfo::FindCoverFromEnemyNearNode(ncActor targetEnemy, vector targetNode)
|
||||
{
|
||||
float bestDistance = COST_INFINITE;
|
||||
int bestNodeID = -1;
|
||||
|
||||
for (int i = 0; i < g_iNodes; i++) {
|
||||
vector nodePosition = g_pNodes[i].m_vecOrigin;
|
||||
float nodeDistance = distanceSquared(nodePosition, targetNode);
|
||||
|
||||
traceline(targetEnemy.origin, nodePosition, MOVE_NORMAL, targetEnemy);
|
||||
|
||||
if (trace_fraction < 1.0 && nodeDistance < bestDistance) {
|
||||
bestDistance = nodeDistance;
|
||||
bestNodeID = i;
|
||||
}
|
||||
}
|
||||
|
||||
return (g_pNodes[bestNodeID].m_vecOrigin);
|
||||
}
|
||||
|
||||
vector
|
||||
ncNavInfo::FindCoverFromEnemyFarNode(ncActor targetEnemy, vector targetNode)
|
||||
{
|
||||
float bestDistance = 0;
|
||||
int bestNodeID = -1;
|
||||
|
||||
for (int i = 0; i < g_iNodes; i++) {
|
||||
vector nodePosition = g_pNodes[i].m_vecOrigin;
|
||||
float nodeDistance = distanceSquared(nodePosition, targetNode);
|
||||
|
||||
traceline(targetEnemy.origin, nodePosition, MOVE_NORMAL, targetEnemy);
|
||||
|
||||
if (trace_fraction < 1.0 && nodeDistance > bestDistance) {
|
||||
bestDistance = nodeDistance;
|
||||
bestNodeID = i;
|
||||
}
|
||||
}
|
||||
|
||||
return (g_pNodes[bestNodeID].m_vecOrigin);
|
||||
}
|
||||
|
||||
vector
|
||||
ncNavInfo::FindCoverFromPosition(entity traceEntity, vector targetOrigin)
|
||||
{
|
||||
float bestDistance = COST_INFINITE;
|
||||
int bestNodeID = -1i;
|
||||
|
||||
#if 0
|
||||
if (g_iNodes <= 0i) {
|
||||
return ncNavInfo::FindEmptySpotNearPosition(world, targetOrigin, 512.0, 4096.0f);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < g_iNodes; i++) {
|
||||
vector nodePosition = g_pNodes[i].m_vecOrigin;
|
||||
float nodeDistance = distanceSquared(nodePosition, traceEntity.origin);
|
||||
|
||||
traceline(nodePosition, targetOrigin, MOVE_NORMAL, traceEntity);
|
||||
|
||||
if ((trace_ent == world || trace_fraction < 1.0) && nodeDistance < bestDistance) {
|
||||
bestDistance = nodeDistance;
|
||||
bestNodeID = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (bestNodeID) {
|
||||
return (g_vec_null);
|
||||
}
|
||||
|
||||
NSError("%v", (g_pNodes[bestNodeID].m_vecOrigin));
|
||||
return (g_pNodes[bestNodeID].m_vecOrigin);
|
||||
}
|
||||
|
||||
vector
|
||||
ncNavInfo::FindEmptySpotNearPosition(entity traceEntity, vector position, float minRadius, float maxRadius)
|
||||
{
|
||||
float bestYaw = 0.0f;
|
||||
float bestDist = 0.0f;
|
||||
vector testAngle = g_vec_null;
|
||||
vector testPos = g_vec_null;
|
||||
|
||||
for (float yawTest = 0.0f; yawTest < 360.0f; yawTest += 10.0f) {
|
||||
vector testPos;
|
||||
float distSquared;
|
||||
vector testAngle = traceEntity.angles = [0, yawTest, 0];
|
||||
testAngle[0] = testAngle[2] = 0.0f;
|
||||
makevectors(testAngle);
|
||||
testPos = position + (v_forward * 2048.0f);
|
||||
tracebox(position, traceEntity.mins, traceEntity.maxs, testPos, MOVE_NORMAL, traceEntity);
|
||||
distSquared = distance(position, trace_endpos);
|
||||
|
||||
if (distSquared > bestDist) {
|
||||
bestYaw = yawTest;
|
||||
bestDist = distSquared;
|
||||
}
|
||||
}
|
||||
|
||||
/* cancel early */
|
||||
if (bestDist <= minRadius) {
|
||||
return (g_vec_null);
|
||||
}
|
||||
|
||||
for (float dist = minRadius; dist < maxRadius; dist += ((maxRadius - minRadius) / 16.0f)) {
|
||||
vector testAngle = [0, bestYaw, 0];
|
||||
testAngle[0] = testAngle[2] = 0.0f;
|
||||
makevectors(testAngle);
|
||||
vector testPos = position + (v_forward * dist);
|
||||
tracebox(testPos, traceEntity.mins, traceEntity.maxs, testPos, MOVE_NORMAL, traceEntity);
|
||||
|
||||
if (!trace_startsolid) {
|
||||
return (testPos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return (g_vec_null);
|
||||
}
|
||||
|
||||
vector
|
||||
ncNavInfo::FindEmptySpotAwayFromPosition(entity traceEntity, vector position, float minRadius, float maxRadius)
|
||||
{
|
||||
float bestYaw = 0.0f;
|
||||
float bestDist = 0.0f;
|
||||
vector testAngle = g_vec_null;
|
||||
vector testPos = g_vec_null;
|
||||
|
||||
for (float yawTest = 0.0f; yawTest < 360.0f; yawTest += 10.0f) {
|
||||
vector testPos;
|
||||
float distSquared;
|
||||
vector testAngle = traceEntity.angles = [0, yawTest, 0];
|
||||
testAngle[0] = testAngle[2] = 0.0f;
|
||||
makevectors(testAngle);
|
||||
testPos = position + (v_forward * 2048.0f);
|
||||
tracebox(position, traceEntity.mins, traceEntity.maxs, testPos, MOVE_NORMAL, traceEntity);
|
||||
distSquared = distance(position, trace_endpos);
|
||||
|
||||
if (distSquared > bestDist) {
|
||||
bestYaw = yawTest;
|
||||
bestDist = distSquared;
|
||||
}
|
||||
}
|
||||
|
||||
/* cancel early */
|
||||
if (bestDist <= minRadius) {
|
||||
return (g_vec_null);
|
||||
}
|
||||
|
||||
for (float dist = maxRadius; dist > minRadius; dist -= ((maxRadius - minRadius) / 16.0f)) {
|
||||
vector testAngle = [0, bestYaw, 0];
|
||||
testAngle[0] = testAngle[2] = 0.0f;
|
||||
makevectors(testAngle);
|
||||
vector testPos = position + (v_forward * dist);
|
||||
tracebox(testPos, traceEntity.mins, traceEntity.maxs, testPos, MOVE_NORMAL, traceEntity);
|
||||
|
||||
if (!trace_startsolid) {
|
||||
return (testPos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return (g_vec_null);
|
||||
}
|
56
src/nav/NodeEditor.h
Normal file
56
src/nav/NodeEditor.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Vera Visions LLC.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/** @ingroup nav
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
class
|
||||
ncNodeEditor
|
||||
{
|
||||
/** Links node wp towards w2. */
|
||||
nonvirtual void LinkNodes(node_t *, node_t *);
|
||||
/** Unlinks node wp from going towards w2. */
|
||||
nonvirtual void UnlinkNodes(node_t *, node_t *);
|
||||
/** Returns the id of the closest node in a node graph. */
|
||||
nonvirtual int FindClosestNode(vector);
|
||||
/** Saves the specified nodegraph to disk with the specified filename. */
|
||||
nonvirtual bool SaveFile(string);
|
||||
/** Loads the nodegraph from the specified filename off disk. */
|
||||
nonvirtual bool ReadFile(string, bool);
|
||||
/** Flushes the nodegraph being passed. */
|
||||
nonvirtual void Flush(void);
|
||||
|
||||
nonvirtual void Cmd(void);
|
||||
nonvirtual void DrawDebugInfo(void);
|
||||
|
||||
private:
|
||||
nonvirtual void AutoLink(int wpidx);
|
||||
nonvirtual void CreateNode(entity ePlayer, int iAutoLink);
|
||||
nonvirtual void DeleteNode(int iID);
|
||||
nonvirtual void SetRadius(int iID, float flRadValue);
|
||||
nonvirtual void LinkFlag(int linkFlag);
|
||||
nonvirtual void Unlink(void);
|
||||
nonvirtual void UnlinkTwo(void);
|
||||
nonvirtual void HelperSpawns(void);
|
||||
nonvirtual void GoToPoint(entity pl);
|
||||
nonvirtual void ConnectOne(void);
|
||||
nonvirtual void ConnectTwo(void);
|
||||
nonvirtual void LoadCurrentMapNavMesh(void);
|
||||
};
|
||||
|
||||
/** @} */ // end of nav
|
|
@ -19,7 +19,7 @@ var int g_way1 = -1;
|
|||
var int g_way2 = -1;
|
||||
|
||||
void
|
||||
NodeEdit_LinkNodes(node_t *wp, node_t *w2)
|
||||
ncNodeEditor::LinkNodes(node_t *wp, node_t *w2)
|
||||
{
|
||||
int w2n = w2 - g_pNodes;
|
||||
|
||||
|
@ -39,7 +39,7 @@ NodeEdit_LinkNodes(node_t *wp, node_t *w2)
|
|||
}
|
||||
|
||||
void
|
||||
NodeEdit_UnlinkNodes(node_t *wp, node_t *w2)
|
||||
ncNodeEditor::UnlinkNodes(node_t *wp, node_t *w2)
|
||||
{
|
||||
int w2n = w2 - g_pNodes;
|
||||
int nilled = 0;
|
||||
|
@ -76,8 +76,8 @@ NodeEdit_UnlinkNodes(node_t *wp, node_t *w2)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
NodeEdit_AutoLink(int wpidx)
|
||||
void
|
||||
ncNodeEditor::AutoLink(int wpidx)
|
||||
{
|
||||
for (int i = 0i; i < g_iNodes; i++) {
|
||||
//don't link to ourself...
|
||||
|
@ -99,13 +99,13 @@ NodeEdit_AutoLink(int wpidx)
|
|||
continue;
|
||||
}
|
||||
|
||||
NodeEdit_LinkNodes(&g_pNodes[wpidx], &g_pNodes[i]);
|
||||
NodeEdit_LinkNodes(&g_pNodes[i], &g_pNodes[wpidx]);
|
||||
ncNodeEditor::LinkNodes(&g_pNodes[wpidx], &g_pNodes[i]);
|
||||
ncNodeEditor::LinkNodes(&g_pNodes[i], &g_pNodes[wpidx]);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
NodeEdit_FindClosestNode(vector vecOrigin)
|
||||
ncNodeEditor::FindClosestNode(vector vecOrigin)
|
||||
{
|
||||
|
||||
/* -1 for no nodes anywhere... */
|
||||
|
@ -133,10 +133,10 @@ NodeEdit_FindClosestNode(vector vecOrigin)
|
|||
return r;
|
||||
}
|
||||
|
||||
static void
|
||||
NodeEdit_CreateNode(entity ePlayer, int iAutoLink)
|
||||
void
|
||||
ncNodeEditor::CreateNode(entity ePlayer, int iAutoLink)
|
||||
{
|
||||
int iNearest = NodeEdit_FindClosestNode(self.origin);
|
||||
int iNearest = ncNodeEditor::FindClosestNode(self.origin);
|
||||
int iID = g_iNodes++;
|
||||
g_pNodes = (node_t *)memreallocOld(g_pNodes, sizeof(node_t), iID, g_iNodes);
|
||||
node_t *n = g_pNodes + iID;
|
||||
|
@ -146,32 +146,32 @@ NodeEdit_CreateNode(entity ePlayer, int iAutoLink)
|
|||
n->m_flRadius = autocvar_nav_radius;
|
||||
|
||||
if (iAutoLink == 1) {
|
||||
NodeEdit_AutoLink(iID);
|
||||
ncNodeEditor::AutoLink(iID);
|
||||
} else {
|
||||
if (iID != 0) {
|
||||
if (iAutoLink == 0) {
|
||||
NodeEdit_LinkNodes(n, &g_pNodes[iID-1]);
|
||||
NodeEdit_LinkNodes(&g_pNodes[iID-1], n);
|
||||
ncNodeEditor::LinkNodes(n, &g_pNodes[iID-1]);
|
||||
ncNodeEditor::LinkNodes(&g_pNodes[iID-1], n);
|
||||
} else if (iAutoLink == -1) {
|
||||
NodeEdit_LinkNodes(&g_pNodes[iID-1], n);
|
||||
ncNodeEditor::LinkNodes(&g_pNodes[iID-1], n);
|
||||
} else if (iAutoLink == -2) {
|
||||
NodeEdit_LinkNodes(n, &g_pNodes[iID-1]);
|
||||
ncNodeEditor::LinkNodes(n, &g_pNodes[iID-1]);
|
||||
} else if (iAutoLink == -4) {
|
||||
if (iNearest == -1i)
|
||||
return;
|
||||
|
||||
NodeEdit_LinkNodes(n, &g_pNodes[iNearest]);
|
||||
NodeEdit_LinkNodes(&g_pNodes[iNearest], n);
|
||||
ncNodeEditor::LinkNodes(n, &g_pNodes[iNearest]);
|
||||
ncNodeEditor::LinkNodes(&g_pNodes[iNearest], n);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
NodeEdit_DeleteNode(int iID)
|
||||
void
|
||||
ncNodeEditor::DeleteNode(int iID)
|
||||
{
|
||||
if (iID < 0i || iID >= g_iNodes) {
|
||||
print("NodeEdit_DeleteNode: invalid waypoint\n");
|
||||
print("ncNodeEditor::DeleteNode: invalid waypoint\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -196,21 +196,21 @@ NodeEdit_DeleteNode(int iID)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
NodeEdit_SetRadius(int iID, float flRadValue)
|
||||
void
|
||||
ncNodeEditor::SetRadius(int iID, float flRadValue)
|
||||
{
|
||||
if (iID < 0i || iID >= g_iNodes) {
|
||||
print("NodeEdit_SetRadius: invalid waypoint\n");
|
||||
print("ncNodeEditor::SetRadius: invalid waypoint\n");
|
||||
return;
|
||||
}
|
||||
g_pNodes[iID].m_flRadius = flRadValue;
|
||||
}
|
||||
|
||||
static void
|
||||
NodeEdit_LinkFlag(int linkFlag)
|
||||
void
|
||||
ncNodeEditor::LinkFlag(int linkFlag)
|
||||
{
|
||||
if (g_waylink_status == 0) {
|
||||
g_way1 = NodeEdit_FindClosestNode(self.origin);
|
||||
g_way1 = ncNodeEditor::FindClosestNode(self.origin);
|
||||
|
||||
if (g_way1 == -1i)
|
||||
return;
|
||||
|
@ -218,7 +218,7 @@ NodeEdit_LinkFlag(int linkFlag)
|
|||
g_waylink_status = 1;
|
||||
env_message_single(self, "^2Selected first waypoint!\n");
|
||||
} else if (g_waylink_status == 1) {
|
||||
g_way2 = NodeEdit_FindClosestNode(self.origin);
|
||||
g_way2 = ncNodeEditor::FindClosestNode(self.origin);
|
||||
|
||||
if (g_way2 == -1i)
|
||||
return;
|
||||
|
@ -226,7 +226,7 @@ NodeEdit_LinkFlag(int linkFlag)
|
|||
g_waylink_status = 0;
|
||||
|
||||
if (g_way1 != g_way2) {
|
||||
NodeEdit_LinkNodes(&g_pNodes[g_way1], &g_pNodes[g_way2]);
|
||||
ncNodeEditor::LinkNodes(&g_pNodes[g_way1], &g_pNodes[g_way2]);
|
||||
for (int b = 0i; b < g_pNodes[g_way1].m_numNeighbours; b++) {
|
||||
if (g_pNodes[g_way1].m_pNeighbour[b].m_iNode == g_way2) {
|
||||
g_pNodes[g_way1].m_pNeighbour[b].m_iFlags |= linkFlag;
|
||||
|
@ -240,11 +240,11 @@ NodeEdit_LinkFlag(int linkFlag)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
NodeEdit_Unlink(void)
|
||||
void
|
||||
ncNodeEditor::Unlink(void)
|
||||
{
|
||||
if (g_waylink_status == 0) {
|
||||
g_way1 = NodeEdit_FindClosestNode(self.origin);
|
||||
g_way1 = ncNodeEditor::FindClosestNode(self.origin);
|
||||
|
||||
if (g_way1 == -1i)
|
||||
return;
|
||||
|
@ -252,7 +252,7 @@ NodeEdit_Unlink(void)
|
|||
g_waylink_status = 1;
|
||||
env_message_single(self, "^2Selected first waypoint!\n");
|
||||
} else if (g_waylink_status == 1) {
|
||||
g_way2 = NodeEdit_FindClosestNode(self.origin);
|
||||
g_way2 = ncNodeEditor::FindClosestNode(self.origin);
|
||||
|
||||
if (g_way2 == -1i)
|
||||
return;
|
||||
|
@ -260,7 +260,7 @@ NodeEdit_Unlink(void)
|
|||
g_waylink_status = 0;
|
||||
|
||||
if (g_way1 != g_way2) {
|
||||
NodeEdit_UnlinkNodes(&g_pNodes[g_way1], &g_pNodes[g_way2]);
|
||||
ncNodeEditor::UnlinkNodes(&g_pNodes[g_way1], &g_pNodes[g_way2]);
|
||||
} else {
|
||||
env_message_single(self, "^1Failed to link, the two points are the same!\n");
|
||||
}
|
||||
|
@ -268,11 +268,11 @@ NodeEdit_Unlink(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
NodeEdit_UnlinkTwo(void)
|
||||
void
|
||||
ncNodeEditor::UnlinkTwo(void)
|
||||
{
|
||||
if (g_waylink_status == 0) {
|
||||
g_way1 = NodeEdit_FindClosestNode(self.origin);
|
||||
g_way1 = ncNodeEditor::FindClosestNode(self.origin);
|
||||
|
||||
if (g_way1 == -1i)
|
||||
return;
|
||||
|
@ -280,7 +280,7 @@ NodeEdit_UnlinkTwo(void)
|
|||
g_waylink_status = 1;
|
||||
env_message_single(self, "^2Selected first waypoint!\n");
|
||||
} else if (g_waylink_status == 1) {
|
||||
g_way2 = NodeEdit_FindClosestNode(self.origin);
|
||||
g_way2 = ncNodeEditor::FindClosestNode(self.origin);
|
||||
|
||||
if (g_way2 == -1i)
|
||||
return;
|
||||
|
@ -288,8 +288,8 @@ NodeEdit_UnlinkTwo(void)
|
|||
g_waylink_status = 0;
|
||||
|
||||
if (g_way1 != g_way2) {
|
||||
NodeEdit_UnlinkNodes(&g_pNodes[g_way1], &g_pNodes[g_way2]);
|
||||
NodeEdit_UnlinkNodes(&g_pNodes[g_way2], &g_pNodes[g_way1]);
|
||||
ncNodeEditor::UnlinkNodes(&g_pNodes[g_way1], &g_pNodes[g_way2]);
|
||||
ncNodeEditor::UnlinkNodes(&g_pNodes[g_way2], &g_pNodes[g_way1]);
|
||||
} else {
|
||||
env_message_single(self, "^1Failed to link, the two points are the same!\n");
|
||||
}
|
||||
|
@ -297,16 +297,16 @@ NodeEdit_UnlinkTwo(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
NodeEdit_HelperSpawns()
|
||||
void
|
||||
ncNodeEditor::HelperSpawns()
|
||||
{
|
||||
for (entity a = world; (a = find(a, ::classname, "info_player_deathmatch"));) {
|
||||
NodeEdit_CreateNode(a, TRUE);
|
||||
ncNodeEditor::CreateNode(a, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
NodeEdit_GoToPoint(entity pl)
|
||||
void
|
||||
ncNodeEditor::GoToPoint(entity pl)
|
||||
{
|
||||
vector vecSrc;
|
||||
makevectors(pl.v_angle);
|
||||
|
@ -314,7 +314,7 @@ NodeEdit_GoToPoint(entity pl)
|
|||
traceline(vecSrc, vecSrc + (v_forward * 4096), FALSE, pl);
|
||||
print(sprintf("Telling all bots to go to %v\n", trace_endpos));
|
||||
|
||||
for (entity a = world; (a = find(a, classname, "player"));) {
|
||||
for (entity a = world; (a = find(a, ::classname, "player"));) {
|
||||
if (clienttype(a) != CLIENTTYPE_REAL) {
|
||||
ncBot targ;
|
||||
targ = (ncBot)a;
|
||||
|
@ -326,7 +326,7 @@ NodeEdit_GoToPoint(entity pl)
|
|||
}
|
||||
|
||||
bool
|
||||
NodeEdit_SaveFile(string filename)
|
||||
ncNodeEditor::SaveFile(string filename)
|
||||
{
|
||||
filestream file;
|
||||
|
||||
|
@ -357,7 +357,7 @@ NodeEdit_SaveFile(string filename)
|
|||
}
|
||||
|
||||
void
|
||||
NodeEdit_Flush(void)
|
||||
ncNodeEditor::Flush(void)
|
||||
{
|
||||
for (int i = 0i; i < g_iNodes; i++) {
|
||||
memfree(g_pNodes[i].m_pNeighbour);
|
||||
|
@ -368,14 +368,14 @@ NodeEdit_Flush(void)
|
|||
}
|
||||
|
||||
bool
|
||||
NodeEdit_ReadFile(string strFile, bool flush)
|
||||
ncNodeEditor::ReadFile(string strFile, bool flush)
|
||||
{
|
||||
int startId = 0i;
|
||||
int offSet = 0i;
|
||||
|
||||
filestream file = fopen(strFile, FILE_READ);
|
||||
if (file < 0) {
|
||||
print("NodeEdit_ReadFile: unable to open ", strFile, "\n");
|
||||
print("ncNodeEditor::ReadFile: unable to open ", strFile, "\n");
|
||||
return (false);
|
||||
}
|
||||
|
||||
|
@ -383,7 +383,7 @@ NodeEdit_ReadFile(string strFile, bool flush)
|
|||
tokenize(fgets(file));
|
||||
|
||||
if (flush) {
|
||||
NodeEdit_Flush();
|
||||
ncNodeEditor::Flush();
|
||||
g_iNodes = (int)stoi(argv(0));
|
||||
g_pNodes = memalloc(sizeof(*g_pNodes) * g_iNodes);
|
||||
} else {
|
||||
|
@ -415,11 +415,11 @@ NodeEdit_ReadFile(string strFile, bool flush)
|
|||
return (true);
|
||||
}
|
||||
|
||||
static void
|
||||
NodeEdit_ConnectOne(void)
|
||||
void
|
||||
ncNodeEditor::ConnectOne(void)
|
||||
{
|
||||
if (g_waylink_status == 0) {
|
||||
g_way1 = NodeEdit_FindClosestNode(self.origin);
|
||||
g_way1 = ncNodeEditor::FindClosestNode(self.origin);
|
||||
|
||||
if (g_way1 == -1i)
|
||||
return;
|
||||
|
@ -427,7 +427,7 @@ NodeEdit_ConnectOne(void)
|
|||
g_waylink_status = 1;
|
||||
env_message_single(self, "^21/2 nodes selected... \n");
|
||||
} else if (g_waylink_status == 1) {
|
||||
g_way2 = NodeEdit_FindClosestNode(self.origin);
|
||||
g_way2 = ncNodeEditor::FindClosestNode(self.origin);
|
||||
|
||||
if (g_way2 == -1i)
|
||||
return;
|
||||
|
@ -435,37 +435,7 @@ NodeEdit_ConnectOne(void)
|
|||
g_waylink_status = 0;
|
||||
|
||||
if (g_way1 != g_way2) {
|
||||
NodeEdit_LinkNodes(&g_pNodes[g_way1], &g_pNodes[g_way2]);
|
||||
env_message_single(self, "^22/2 nodes selected, done!\n");
|
||||
} else {
|
||||
env_message_single(self, "^1Failed to link, the two points are the same!\n");
|
||||
}
|
||||
g_way1 = g_way2 = -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
NodeEdit_ConnectTwo(void)
|
||||
{
|
||||
if (g_waylink_status == 0) {
|
||||
g_way1 = NodeEdit_FindClosestNode(self.origin);
|
||||
|
||||
if (g_way1 == -1i)
|
||||
return;
|
||||
|
||||
g_waylink_status = 1;
|
||||
env_message_single(self, "^21/2 nodes selected... \n");
|
||||
} else if (g_waylink_status == 1) {
|
||||
g_way2 = NodeEdit_FindClosestNode(self.origin);
|
||||
|
||||
if (g_way2 == -1i)
|
||||
return;
|
||||
|
||||
g_waylink_status = 0;
|
||||
|
||||
if (g_way1 != g_way2) {
|
||||
NodeEdit_LinkNodes(&g_pNodes[g_way1], &g_pNodes[g_way2]);
|
||||
NodeEdit_LinkNodes(&g_pNodes[g_way2], &g_pNodes[g_way1]);
|
||||
ncNodeEditor::LinkNodes(&g_pNodes[g_way1], &g_pNodes[g_way2]);
|
||||
env_message_single(self, "^22/2 nodes selected, done!\n");
|
||||
} else {
|
||||
env_message_single(self, "^1Failed to link, the two points are the same!\n");
|
||||
|
@ -475,13 +445,43 @@ NodeEdit_ConnectTwo(void)
|
|||
}
|
||||
|
||||
void
|
||||
NodeEdit_DrawDebugInfo(void)
|
||||
ncNodeEditor::ConnectTwo(void)
|
||||
{
|
||||
if (g_waylink_status == 0) {
|
||||
g_way1 = ncNodeEditor::FindClosestNode(self.origin);
|
||||
|
||||
if (g_way1 == -1i)
|
||||
return;
|
||||
|
||||
g_waylink_status = 1;
|
||||
env_message_single(self, "^21/2 nodes selected... \n");
|
||||
} else if (g_waylink_status == 1) {
|
||||
g_way2 = ncNodeEditor::FindClosestNode(self.origin);
|
||||
|
||||
if (g_way2 == -1i)
|
||||
return;
|
||||
|
||||
g_waylink_status = 0;
|
||||
|
||||
if (g_way1 != g_way2) {
|
||||
ncNodeEditor::LinkNodes(&g_pNodes[g_way1], &g_pNodes[g_way2]);
|
||||
ncNodeEditor::LinkNodes(&g_pNodes[g_way2], &g_pNodes[g_way1]);
|
||||
env_message_single(self, "^22/2 nodes selected, done!\n");
|
||||
} else {
|
||||
env_message_single(self, "^1Failed to link, the two points are the same!\n");
|
||||
}
|
||||
g_way1 = g_way2 = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ncNodeEditor::DrawDebugInfo(void)
|
||||
{
|
||||
if (!g_iNodes) {
|
||||
return;
|
||||
}
|
||||
|
||||
int iNearest = NodeEdit_FindClosestNode(self.origin);
|
||||
int iNearest = ncNodeEditor::FindClosestNode(self.origin);
|
||||
makevectors([-90, 0, 0]);
|
||||
|
||||
for (int i = 0i; i < g_iNodes; i++) {
|
||||
|
@ -604,14 +604,14 @@ NodeEdit_DrawDebugInfo(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
NodeEdit_LoadCurrentMapNavMesh(void)
|
||||
void
|
||||
ncNodeEditor::LoadCurrentMapNavMesh(void)
|
||||
{
|
||||
NodeEdit_ReadFile(sprintf("%s.way", mapname), true);
|
||||
ncNodeEditor::ReadFile(sprintf("%s.way", mapname), true);
|
||||
}
|
||||
|
||||
void
|
||||
NodeEdit_Cmd(void)
|
||||
ncNodeEditor::Cmd(void)
|
||||
{
|
||||
if (!self) {
|
||||
return;
|
||||
|
@ -619,46 +619,46 @@ NodeEdit_Cmd(void)
|
|||
|
||||
switch (argv(1)) {
|
||||
case "goto":
|
||||
NodeEdit_GoToPoint(self);
|
||||
ncNodeEditor::GoToPoint(self);
|
||||
break;
|
||||
case "autolink":
|
||||
NodeEdit_AutoLink(NodeEdit_FindClosestNode(self.origin));
|
||||
ncNodeEditor::AutoLink(ncNodeEditor::FindClosestNode(self.origin));
|
||||
break;
|
||||
case "connect1":
|
||||
NodeEdit_ConnectOne();
|
||||
ncNodeEditor::ConnectOne();
|
||||
break;
|
||||
case "connect2":
|
||||
NodeEdit_ConnectTwo();
|
||||
ncNodeEditor::ConnectTwo();
|
||||
break;
|
||||
case "add":
|
||||
NodeEdit_CreateNode(self, 1);
|
||||
ncNodeEditor::CreateNode(self, 1);
|
||||
break;
|
||||
case "addchain":
|
||||
NodeEdit_CreateNode(self, 0);
|
||||
ncNodeEditor::CreateNode(self, 0);
|
||||
break;
|
||||
case "addsingle":
|
||||
NodeEdit_CreateNode(self, -3);
|
||||
ncNodeEditor::CreateNode(self, -3);
|
||||
break;
|
||||
case "addltn":
|
||||
NodeEdit_CreateNode(self, -1);
|
||||
ncNodeEditor::CreateNode(self, -1);
|
||||
break;
|
||||
case "addntl":
|
||||
NodeEdit_CreateNode(self, -2);
|
||||
ncNodeEditor::CreateNode(self, -2);
|
||||
break;
|
||||
case "addnear":
|
||||
NodeEdit_CreateNode(self, -4);
|
||||
ncNodeEditor::CreateNode(self, -4);
|
||||
break;
|
||||
case "addspawns":
|
||||
NodeEdit_HelperSpawns();
|
||||
ncNodeEditor::HelperSpawns();
|
||||
break;
|
||||
case "delete":
|
||||
NodeEdit_DeleteNode(NodeEdit_FindClosestNode(self.origin));
|
||||
ncNodeEditor::DeleteNode(ncNodeEditor::FindClosestNode(self.origin));
|
||||
break;
|
||||
case "purge":
|
||||
Nodes_Flush();
|
||||
break;
|
||||
case "radius":
|
||||
NodeEdit_SetRadius(NodeEdit_FindClosestNode(self.origin), stof(argv(2)));
|
||||
ncNodeEditor::SetRadius(ncNodeEditor::FindClosestNode(self.origin), stof(argv(2)));
|
||||
break;
|
||||
case "radiushack":
|
||||
for (int i = 0i; i < g_iNodes; i++) {
|
||||
|
@ -685,17 +685,17 @@ NodeEdit_Cmd(void)
|
|||
}
|
||||
break;
|
||||
case "flag":
|
||||
NodeEdit_LinkFlag(stoi(argv(2)));
|
||||
ncNodeEditor::LinkFlag(stoi(argv(2)));
|
||||
break;
|
||||
case "unlink1":
|
||||
NodeEdit_Unlink();
|
||||
ncNodeEditor::Unlink();
|
||||
break;
|
||||
case "unlink2":
|
||||
NodeEdit_UnlinkTwo();
|
||||
ncNodeEditor::UnlinkTwo();
|
||||
break;
|
||||
case "move":
|
||||
vector p;
|
||||
int n = NodeEdit_FindClosestNode(self.origin);
|
||||
int n = ncNodeEditor::FindClosestNode(self.origin);
|
||||
if (n >= 0) {
|
||||
p[0] = stof(argv(2));
|
||||
p[1] = stof(argv(3));
|
||||
|
@ -704,19 +704,19 @@ NodeEdit_Cmd(void)
|
|||
}
|
||||
break;
|
||||
case "movetopos":
|
||||
int nearest = NodeEdit_FindClosestNode(self.origin);
|
||||
int nearest = ncNodeEditor::FindClosestNode(self.origin);
|
||||
if (nearest >= 0) {
|
||||
g_pNodes[nearest].m_vecOrigin = self.origin;
|
||||
}
|
||||
break;
|
||||
case "save":
|
||||
NodeEdit_SaveFile(argv(2));
|
||||
ncNodeEditor::SaveFile(argv(2));
|
||||
break;
|
||||
case "load":
|
||||
NodeEdit_ReadFile(argv(2), true);
|
||||
ncNodeEditor::ReadFile(argv(2), true);
|
||||
break;
|
||||
case "merge":
|
||||
NodeEdit_ReadFile(argv(2), false);
|
||||
ncNodeEditor::ReadFile(argv(2), false);
|
||||
break;
|
||||
case "loadpb":
|
||||
Way_ReadPBFile(argv(2), true);
|
||||
|
@ -743,7 +743,7 @@ void
|
|||
SV_AddDebugPolygons(void)
|
||||
{
|
||||
if (autocvar_nav_visualize) {
|
||||
NodeEdit_DrawDebugInfo();
|
||||
ncNodeEditor::DrawDebugInfo();
|
||||
}
|
||||
|
||||
if (autocvar_r_renderEntityInfo) {
|
||||
|
@ -759,7 +759,7 @@ SV_AddDebugPolygons(void)
|
|||
return;
|
||||
|
||||
if (!g_iNodes) {
|
||||
NodeEdit_LoadCurrentMapNavMesh();
|
||||
ncNodeEditor::LoadCurrentMapNavMesh();
|
||||
}
|
||||
|
||||
#if 1
|
|
@ -17,6 +17,7 @@
|
|||
#include "linkflags.h"
|
||||
#include "nodes.h"
|
||||
#include "route.h"
|
||||
#include "node_edit.h"
|
||||
#include "NodeEditor.h"
|
||||
#include "way_convert.h"
|
||||
#include "NavInfo.h"
|
||||
#include "Hint.h"
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#includelist
|
||||
Hint.qc
|
||||
nodes.qc
|
||||
route.qc
|
||||
node_edit.qc
|
||||
NodeEditor.qc
|
||||
way_convert.qc
|
||||
NavInfo.qc
|
||||
#endlist
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Vera Visions LLC.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/** @ingroup nav
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** Links node wp towards w2. */
|
||||
void NodeEdit_LinkNodes(node_t *, node_t *);
|
||||
/** Unlinks node wp from going towards w2. */
|
||||
void NodeEdit_UnlinkNodes(node_t *, node_t *);
|
||||
/** Returns the id of the closest node in a node graph. */
|
||||
int NodeEdit_FindClosestNode(vector);
|
||||
/** Saves the specified nodegraph to disk with the specified filename. */
|
||||
bool NodeEdit_SaveFile(string);
|
||||
/** Loads the nodegraph from the specified filename off disk. */
|
||||
bool NodeEdit_ReadFile(string, bool);
|
||||
/** Flushes the nodegraph being passed. */
|
||||
void NodeEdit_Flush(void);
|
||||
|
||||
void NodeEdit_Cmd(void);
|
||||
void NodeEdit_DrawDebugInfo(void);
|
||||
|
||||
/** @} */ // end of nav
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 Vera Visions LLC.
|
||||
* Copyright (c) 2016-2025 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
|
||||
|
|
|
@ -137,7 +137,7 @@ Nodes_BuildFromEnts(void)
|
|||
|
||||
if (g_iNodes) {
|
||||
NSLog("saving nodes nodes for %s", mapname);
|
||||
NodeEdit_SaveFile(sprintf("%s.way", mapname));
|
||||
ncNodeEditor::SaveFile(sprintf("%s.way", mapname));
|
||||
} else {
|
||||
NSLog("no node data found for %s", mapname);
|
||||
}
|
||||
|
@ -172,7 +172,7 @@ Nodes_Init(void)
|
|||
|
||||
/* skip if present. TODO: check if they're out of date? */
|
||||
if (fileExists(sprintf("data/%s.way", mapname))) {
|
||||
NodeEdit_ReadFile(sprintf("data/%s.way", mapname), true);
|
||||
ncNodeEditor::ReadFile(sprintf("data/%s.way", mapname), true);
|
||||
} else {
|
||||
Nodes_BuildFromEnts();
|
||||
}
|
||||
|
@ -185,5 +185,5 @@ Nodes_Init(void)
|
|||
void
|
||||
Nodes_Flush(void)
|
||||
{
|
||||
NodeEdit_Flush();
|
||||
ncNodeEditor::Flush();
|
||||
}
|
||||
|
|
|
@ -497,8 +497,8 @@ Way_ReadJumbotFile(string strFile, bool flush)
|
|||
g_pNodes[i].m_flRadius = 32.0f;
|
||||
|
||||
if (i > startId) {
|
||||
NodeEdit_LinkNodes(&g_pNodes[i], &g_pNodes[i-1]);
|
||||
NodeEdit_LinkNodes(&g_pNodes[i-1], &g_pNodes[i]);
|
||||
ncNodeEditor::LinkNodes(&g_pNodes[i], &g_pNodes[i-1]);
|
||||
ncNodeEditor::LinkNodes(&g_pNodes[i-1], &g_pNodes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -52,13 +52,6 @@ typedef struct
|
|||
@param spawnPos the position at which it should spawn.
|
||||
@return The created entity. */
|
||||
entity Create(string className, vector spawnPos);
|
||||
/** Precaches a given entity class.
|
||||
Ensuring models, sounds and other assets referenced
|
||||
within are loaded ahead of time.
|
||||
|
||||
@param className to precache
|
||||
@return Success. */
|
||||
bool Precache(string className);
|
||||
/** Transitions an entity from one class to another.
|
||||
|
||||
@param targetEntity is the target entity.
|
||||
|
@ -214,7 +207,6 @@ _server_main(void)
|
|||
|
||||
ents.Create = linkToServerProgs("spawnClass");
|
||||
ents.ChangeToClass = linkToServerProgs("changeClass");
|
||||
ents.Precache = linkToServerProgs("EntityDef_Precache");
|
||||
ents.Input = linkToServerProgs("sendInput");
|
||||
ents.isAI = linkToServerProgs("isAI");
|
||||
ents.isAlive = linkToServerProgs("isAlive");
|
||||
|
|
|
@ -274,7 +274,7 @@ Cmd_ParseServerCommand(void)
|
|||
break;
|
||||
#ifdef BOT_INCLUDED
|
||||
case "way":
|
||||
NodeEdit_Cmd();
|
||||
ncNodeEditor::Cmd();
|
||||
break;
|
||||
#endif
|
||||
case "listEntityDef":
|
||||
|
|
|
@ -26,7 +26,7 @@ MapC_Init(void)
|
|||
|
||||
/* No mapname.dat, exit out */
|
||||
if (fileExists(mapProgs) == false) {
|
||||
NSWarning("No MapC for level %s loaded. (%s)", cvar_string("mapname"), mapProgs);
|
||||
NSLog("No MapC for level %s loaded. (%s)", cvar_string("mapname"), mapProgs);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -281,8 +281,10 @@ ncActor::Spawned(void)
|
|||
|
||||
if (defKey != "") {
|
||||
int defValue = GetDefInt(defKey);
|
||||
EntLog("Giving %S some %i units of %S", classname, defValue, defKey);
|
||||
GiveAmmo(i, defValue);
|
||||
if (defValue > 0i) {
|
||||
EntLog("Giving %S some %i units of %S", classname, defValue, defKey);
|
||||
GiveAmmo(i, defValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ void
|
|||
ncEntity::Precache(void)
|
||||
{
|
||||
if (STRING_SET(model)) {
|
||||
precache_model(model);
|
||||
precache.Model(model);
|
||||
}
|
||||
|
||||
#ifdef SERVER
|
||||
|
@ -1213,6 +1213,7 @@ ncEntity::SpawnKey(string strKey, string strValue)
|
|||
bool tempCheck = false;
|
||||
/* we do re-read a lot of the builtin fields in case we want to set
|
||||
defaults. just in case anybody is wondering. */
|
||||
|
||||
switch (strKey) {
|
||||
case "spawnflags":
|
||||
spawnflags = ReadFloat(strValue);
|
||||
|
|
|
@ -882,6 +882,9 @@ ncIO::SpawnKey(string strKey, string strValue)
|
|||
case "maxs":
|
||||
maxs = ReadVector(strValue);
|
||||
break;
|
||||
case "target":
|
||||
target = strValue;
|
||||
break;
|
||||
case "targetname":
|
||||
targetname = strValue;
|
||||
break;
|
||||
|
@ -1005,8 +1008,8 @@ ncIO::SetNextThink(float fl)
|
|||
float flTime = GetTime() + fl;
|
||||
|
||||
/* HACK: to make sure things happen post-spawn */
|
||||
if (flTime == 0.0f) {
|
||||
flTime = 0.001f;
|
||||
if (flTime < 0.1f) {
|
||||
flTime = 0.1f;
|
||||
}
|
||||
|
||||
if (flTime >= 0) {
|
||||
|
|
|
@ -33,10 +33,4 @@ public:
|
|||
|
||||
/** Sets up a point entity trigger with no size. */
|
||||
nonvirtual void InitPointTrigger(void);
|
||||
|
||||
#ifdef SERVER
|
||||
virtual void SpawnKey(string, string);
|
||||
virtual void Save(float);
|
||||
virtual void Restore(string, string);
|
||||
#endif
|
||||
};
|
||||
|
|
|
@ -63,32 +63,3 @@ ncPointTrigger::DebugDraw(void)
|
|||
R_EndPolygon();
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef SERVER
|
||||
|
||||
void
|
||||
ncPointTrigger::SpawnKey(string strKey, string strValue)
|
||||
{
|
||||
switch (strKey) {
|
||||
default:
|
||||
super::SpawnKey(strKey, strValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ncPointTrigger::Save(float handle)
|
||||
{
|
||||
super::Save(handle);
|
||||
}
|
||||
|
||||
void
|
||||
ncPointTrigger::Restore(string strKey, string strValue)
|
||||
{
|
||||
switch (strKey) {
|
||||
default:
|
||||
super::Restore(strKey, strValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -49,7 +49,7 @@ ncPortal::ncPortal(void)
|
|||
}
|
||||
|
||||
/* default fallback */
|
||||
precache_model("models/b_portal.bsp");
|
||||
precache.Model("models/b_portal.bsp");
|
||||
SetPortalModel("models/b_portal.bsp");
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -476,6 +476,7 @@ ncSurfacePropEntity::SpawnKey(string keyName, string setValue)
|
|||
else
|
||||
DisableBleeding();
|
||||
|
||||
break;
|
||||
case "health":
|
||||
max_health = health = ReadFloat(setValue);
|
||||
m_oldHealth = health;
|
||||
|
@ -501,7 +502,6 @@ ncSurfacePropEntity::SpawnKey(string keyName, string setValue)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ncSurfacePropEntity::Pain(entity inflictor, entity attacker, int damage, vector dir, vector absImpactPos, int hitBody)
|
||||
{
|
||||
|
|
|
@ -251,8 +251,8 @@ ncWeapon::Spawned(void)
|
|||
}
|
||||
|
||||
m_bInvCarry = true;
|
||||
precache_model(m_strWeaponViewModel);
|
||||
precache_model(m_strWeaponPlayerModel);
|
||||
precache.Model(m_strWeaponViewModel);
|
||||
precache.Model(m_strWeaponPlayerModel);
|
||||
|
||||
SetViewModel(m_strWeaponViewModel);
|
||||
SetWorldModel(model);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2024 Vera Visions LLC.
|
||||
* Copyright (c) 2016-2025 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
|
||||
|
@ -367,8 +367,40 @@ entityDefAPI_t entityDef;
|
|||
|
||||
typedef struct
|
||||
{
|
||||
float Model(string);
|
||||
float Sound(string);
|
||||
/** Precaches a given model file and additional helper files.
|
||||
|
||||
`precache.Model("models/weapons/v_pistol.vvm");`
|
||||
|
||||
@param pathToModel to precache
|
||||
@return modelindex value. */
|
||||
float Model(string pathToModel);
|
||||
|
||||
/** Precaches a given sound def or sample.
|
||||
|
||||
`precache.Sound("Foo.Bar");`
|
||||
`precache.Sound("foo/bar.wav");`
|
||||
|
||||
@param soundDef to precache
|
||||
@return sound def id. */
|
||||
float Sound(string soundDef);
|
||||
|
||||
/** Precaches a given particle effect.
|
||||
|
||||
The following loads `r_part impactSpark` from `particles/weapon_laser.cfg`.
|
||||
|
||||
`precache.Particle("weapon_laser.impactSpark");
|
||||
|
||||
@param particleEffect to precache
|
||||
@return particle effect num. */
|
||||
float Particle(string particleEffect);
|
||||
|
||||
/** Precaches a given entity class.
|
||||
Ensuring models, sounds and other assets referenced
|
||||
within are loaded ahead of time.
|
||||
|
||||
@param className to precache
|
||||
@return Success. */
|
||||
bool Entity(string className);
|
||||
} precacheAPI_t;
|
||||
precacheAPI_t precache;
|
||||
|
||||
|
@ -553,6 +585,8 @@ _shared_main(void)
|
|||
|
||||
precache.Model = linkToSharedProgs("SHPF_precache_Model");
|
||||
precache.Sound = linkToSharedProgs("SHPF_precache_Sound");
|
||||
precache.Particle = linkToSharedProgs("SHPF_precache_Particle");
|
||||
precache.Entity = linkToSharedProgs("EntityDef_Precache");
|
||||
|
||||
soundKit.Play = linkToSharedProgs("SHPF_sounds_Play");
|
||||
|
||||
|
|
|
@ -892,6 +892,17 @@ void
|
|||
sendInput(entity target, string inputName, string dataString, entity activator)
|
||||
{
|
||||
ncEntity targetEntity = (ncEntity)target;
|
||||
|
||||
if (!target) {
|
||||
NSError("target entity is nil");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!STRING_SET(inputName)) {
|
||||
NSError("No input specified.");
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef SERVER
|
||||
targetEntity.Input(activator, inputName, dataString);
|
||||
#endif
|
||||
|
@ -901,6 +912,10 @@ sendInput(entity target, string inputName, string dataString, entity activator)
|
|||
bool
|
||||
isAI(entity entityToCheck)
|
||||
{
|
||||
if (!entityToCheck) {
|
||||
return (false);
|
||||
}
|
||||
|
||||
if (entityToCheck.flags & FL_MONSTER) {
|
||||
return (true);
|
||||
}
|
||||
|
@ -911,6 +926,10 @@ isAI(entity entityToCheck)
|
|||
bool
|
||||
isAlive(entity entityToCheck)
|
||||
{
|
||||
if (!entityToCheck) {
|
||||
return (false);
|
||||
}
|
||||
|
||||
#ifdef SERVER
|
||||
if (entityToCheck.takedamage != DAMAGE_NO) {
|
||||
ncSurfacePropEntity livingEnt = (ncSurfacePropEntity)entityToCheck;
|
||||
|
@ -924,6 +943,10 @@ isAlive(entity entityToCheck)
|
|||
bool
|
||||
isGodMode(entity entityToCheck)
|
||||
{
|
||||
if (!entityToCheck) {
|
||||
return (false);
|
||||
}
|
||||
|
||||
if (entityToCheck.flags & FL_GODMODE) {
|
||||
return (true);
|
||||
}
|
||||
|
@ -934,6 +957,10 @@ isGodMode(entity entityToCheck)
|
|||
bool
|
||||
isClient(entity entityToCheck)
|
||||
{
|
||||
if (!entityToCheck) {
|
||||
return (false);
|
||||
}
|
||||
|
||||
return (entityToCheck.flags & FL_CLIENT) ? (true) : (false);
|
||||
}
|
||||
|
||||
|
@ -961,18 +988,30 @@ isSentient(entity entityToCheck)
|
|||
bool
|
||||
isBot(entity entityToCheck)
|
||||
{
|
||||
return userinfo.GetBool(self, "*bot");
|
||||
if (!entityToCheck) {
|
||||
return (false);
|
||||
}
|
||||
|
||||
return userinfo.GetBool(entityToCheck, "*bot");
|
||||
}
|
||||
|
||||
bool
|
||||
isWeapon(entity entityToCheck)
|
||||
{
|
||||
if (!entityToCheck) {
|
||||
return (false);
|
||||
}
|
||||
|
||||
return (entityToCheck._isWeapon) ? (true) : (false);
|
||||
}
|
||||
|
||||
bool
|
||||
isItem(entity entityToCheck)
|
||||
{
|
||||
if (!entityToCheck) {
|
||||
return (false);
|
||||
}
|
||||
|
||||
return (entityToCheck._isItem) ? (true) : (false);
|
||||
}
|
||||
|
||||
|
@ -1011,15 +1050,33 @@ SHPF_entityDef_GetVector(string declName, string keyName)
|
|||
int
|
||||
SHPF_precache_Model(string modelPath)
|
||||
{
|
||||
if (!STRING_SET(modelPath)) {
|
||||
return (0i);
|
||||
}
|
||||
|
||||
precache_model(modelPath);
|
||||
PropData_ForModel(modelPath);
|
||||
return (int)getmodelindex(modelPath, false);
|
||||
}
|
||||
|
||||
int
|
||||
SHPF_precache_Sound(string modelPath)
|
||||
SHPF_precache_Sound(string soundDecl)
|
||||
{
|
||||
return (int)Sound_Precache(modelPath);
|
||||
if (!STRING_SET(soundDecl)) {
|
||||
return (-1i);
|
||||
}
|
||||
|
||||
return (int)Sound_Precache(soundDecl);
|
||||
}
|
||||
|
||||
int
|
||||
SHPF_precache_Particle(string particleName)
|
||||
{
|
||||
if (!STRING_SET(particleName)) {
|
||||
return (0i);
|
||||
}
|
||||
|
||||
return (int)particleeffectnum(particleName);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -439,23 +439,41 @@ EntityDef_PrepareEntity(entity target, int id)
|
|||
static void
|
||||
EntityDef_Precaches(int index)
|
||||
{
|
||||
if (time > 2.0f) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < tokenize_console(g_entDefTable[index].spawnData); i+= 2) {
|
||||
string strKey = argv(i);
|
||||
string strValue = argv(i+1);
|
||||
|
||||
if (substring(strKey, 0, 4) == "snd_") {
|
||||
Sound_Precache(strValue);
|
||||
precache.Sound(strValue);
|
||||
} else if (substring(strKey, 0, 6) == "smoke_") {
|
||||
particleeffectnum(strValue);
|
||||
} else if (strKey == "model_detonate") {
|
||||
particleeffectnum(strValue);
|
||||
} else if (substring(strKey, 0, 4) == "def_") {
|
||||
} else if (strKey == "model") {
|
||||
precache.Model(strValue);
|
||||
} else if (substring(strKey, 0, 6) == "model_") {
|
||||
precache.Model(strValue);
|
||||
} else if (substring(strKey, 0, 4) == "def_" || (strKey == "item")) {
|
||||
int defID = EntityDef_IDFromName(strValue);
|
||||
|
||||
/* only precache valid def, and avoid recursion */
|
||||
if (defID != -1 && defID != index) {
|
||||
EntityDef_Precaches(defID);
|
||||
}
|
||||
} else if (strKey == "weapon") {
|
||||
for (int w = 0; w < tokenizebyseparator(strValue, ","); w++) {
|
||||
string weaponName = argv(w);
|
||||
int defID = EntityDef_IDFromName(weaponName);
|
||||
|
||||
/* only precache valid def, and avoid recursion */
|
||||
if (defID != -1 && defID != index) {
|
||||
EntityDef_Precaches(defID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -506,11 +524,7 @@ EntityDef_NewClassname(string className)
|
|||
|
||||
for (int i = 0i; i < g_entDefCount; i++) {
|
||||
if (className == g_entDefTable[i].entClass) {
|
||||
if (time < 5.0) {
|
||||
EntityDef_Precaches(i);
|
||||
}
|
||||
|
||||
NSLog("Spawning eDef %S", className);
|
||||
EntityDef_Precache(className);
|
||||
return EntityDef_PrepareEntity(self, i);
|
||||
}
|
||||
}
|
||||
|
@ -529,11 +543,7 @@ EntityDef_SpawnClassname(string className)
|
|||
|
||||
for (int i = 0i; i < g_entDefCount; i++) {
|
||||
if (className == g_entDefTable[i].entClass) {
|
||||
if (time < 5.0) {
|
||||
EntityDef_Precaches(i);
|
||||
}
|
||||
|
||||
NSLog("Spawning eDef %S", className);
|
||||
EntityDef_Precache(className);
|
||||
return EntityDef_PrepareEntity(self, i);
|
||||
}
|
||||
}
|
||||
|
@ -549,11 +559,7 @@ EntityDef_SwitchClass(ncEntity target, string className)
|
|||
|
||||
for (int i = 0i; i < g_entDefCount; i++) {
|
||||
if (className == g_entDefTable[i].entClass) {
|
||||
if (time < 5.0) {
|
||||
EntityDef_Precaches(i);
|
||||
}
|
||||
|
||||
NSLog("Spawning eDef %S", className);
|
||||
EntityDef_Precache(className);
|
||||
returnEntity = EntityDef_PrepareEntity(target, i);
|
||||
return (returnEntity);
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ PropData_PrecacheGib(string modelPath)
|
|||
}
|
||||
|
||||
tokenizebyseparator(modelPath, "#");
|
||||
precache_model(argv(0));
|
||||
precache.Model(argv(0));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -401,14 +401,17 @@ PropData_ForModel(string modelname)
|
|||
string line;
|
||||
int index;
|
||||
|
||||
if (!g_propdata_count)
|
||||
if (!g_propdata_count) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!modelname)
|
||||
if (!modelname) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (substring(modelname, 0, 1) == "*")
|
||||
if (substring(modelname, 0, 1) == "*") {
|
||||
return -1;
|
||||
}
|
||||
|
||||
index = g_propdata_count;
|
||||
modelname = strtolower(modelname);
|
||||
|
@ -460,12 +463,13 @@ PropData_ForModel(string modelname)
|
|||
/* not found. try again? */
|
||||
if (fh < 0) {
|
||||
/* try the Source Engine version */
|
||||
fh = fopen(Util_ChangeExtension(modelname, "phy"), FILE_READ);
|
||||
string binaryFile = Util_ChangeExtension(modelname, "phy");
|
||||
fh = fopen(binaryFile, FILE_READ);
|
||||
|
||||
if (fh < 0) {
|
||||
g_propdata_count--;
|
||||
NSLog("No PropData for model %S", modelname);
|
||||
return -1;
|
||||
return -1i;
|
||||
}
|
||||
|
||||
int fileSize;
|
||||
|
@ -478,7 +482,7 @@ PropData_ForModel(string modelname)
|
|||
filePos = fread(fh, (void*)&fileSize, 4i); /* header size, sanity check */
|
||||
|
||||
if (fileSize != 16i) {
|
||||
NSError("Only .phy files from Source are supported.");
|
||||
NSError("%s: not in Source Engine format", binaryFile);
|
||||
fclose(fh);
|
||||
return -1;
|
||||
}
|
||||
|
@ -494,7 +498,7 @@ PropData_ForModel(string modelname)
|
|||
|
||||
/* HACK: We won't support ragdolls, for now. */
|
||||
if (numSolids > 1) {
|
||||
NSError("Only non-ragdoll models are currently supported.");
|
||||
NSError("%s: ragdoll models not supported", binaryFile);
|
||||
fclose(fh);
|
||||
return -1;
|
||||
}
|
||||
|
@ -608,19 +612,23 @@ PropData_Load(string type)
|
|||
{
|
||||
int index;
|
||||
|
||||
if (!type)
|
||||
return -1;
|
||||
if (g_propdata_count <= 0i) {
|
||||
return -1i;
|
||||
}
|
||||
|
||||
if (substring(type, 0, 1) == "*")
|
||||
return -1;
|
||||
if (!type) {
|
||||
return -1i;
|
||||
}
|
||||
|
||||
if (substring(type, 0, 1) == "*") {
|
||||
return -1i;
|
||||
}
|
||||
|
||||
type = strtolower(type);
|
||||
|
||||
index = (int)hash_get(g_hashpropdata, type, -1);
|
||||
|
||||
if (index < 0) {
|
||||
NSLog("PropData type %S is not defined.", type);
|
||||
return -1;
|
||||
if (index < 0i) {
|
||||
return -1i;
|
||||
} else {
|
||||
return index;
|
||||
}
|
||||
|
@ -883,7 +891,7 @@ PropData_Init(void)
|
|||
mname = argv(0);
|
||||
}
|
||||
|
||||
precache_model(mname);
|
||||
precache.Model(mname);
|
||||
|
||||
/* gotta tokenize our inputs again */
|
||||
x = tokenize(g_breakmodel[i].data);
|
||||
|
@ -1025,8 +1033,7 @@ BreakModel_SpawnID(vector smins, vector smaxs, vector dir, float speed, int coun
|
|||
|
||||
if (usePhysics == false) {
|
||||
gib.SetSize([-8,-8,-8],[8,8,8]);
|
||||
makevectors(dir);
|
||||
gib.velocity = (v_forward * speed) * 0.75;
|
||||
gib.velocity = (dir * speed) * 0.75;
|
||||
gib.velocity[0] += (random() - 0.5) * (speed * 0.25);
|
||||
gib.velocity[1] += (random() - 0.5) * (speed * 0.25);
|
||||
gib.velocity[2] += (random() - 0.5) * (speed * 0.25);
|
||||
|
@ -1083,9 +1090,9 @@ BreakModel_Receive(void)
|
|||
smaxs[1] = readcoord();
|
||||
smaxs[2] = readcoord();
|
||||
|
||||
dir[0] = readcoord();
|
||||
dir[1] = readcoord();
|
||||
dir[2] = readcoord();
|
||||
dir[0] = readfloat();
|
||||
dir[1] = readfloat();
|
||||
dir[2] = readfloat();
|
||||
|
||||
speed = readfloat();
|
||||
count = readbyte();
|
||||
|
@ -1158,9 +1165,9 @@ BreakModel_Spawn(vector smins, vector smaxs, vector dir, float speed, int count,
|
|||
WriteCoord(MSG_MULTICAST, smaxs[0]);
|
||||
WriteCoord(MSG_MULTICAST, smaxs[1]);
|
||||
WriteCoord(MSG_MULTICAST, smaxs[2]);
|
||||
WriteCoord(MSG_MULTICAST, dir[0]);
|
||||
WriteCoord(MSG_MULTICAST, dir[1]);
|
||||
WriteCoord(MSG_MULTICAST, dir[2]);
|
||||
WriteFloat(MSG_MULTICAST, dir[0]);
|
||||
WriteFloat(MSG_MULTICAST, dir[1]);
|
||||
WriteFloat(MSG_MULTICAST, dir[2]);
|
||||
WriteFloat(MSG_MULTICAST, speed);
|
||||
WriteByte(MSG_MULTICAST, count);
|
||||
multicast(pvsPosition, MULTICAST_PVS);
|
||||
|
|
|
@ -238,10 +238,10 @@ Sound_ParseField(int i, int a, string keyName, string valueCS)
|
|||
g_sounds[i].flags |= SNDFL_STEP;
|
||||
break;
|
||||
case "distshader":
|
||||
g_sounds[i].distshader = setValue;
|
||||
g_sounds[i].distshader = valueCS;
|
||||
break;
|
||||
case "pointparticle":
|
||||
g_sounds[i].pointparticle = particleeffectnum(setValue);
|
||||
g_sounds[i].pointparticle = particleeffectnum(valueCS);
|
||||
break;
|
||||
case "alerts":
|
||||
dprint("\tSound set to alert enemy AI\n");
|
||||
|
@ -422,8 +422,14 @@ Sound_Precache(string shader)
|
|||
string line;
|
||||
int index;
|
||||
|
||||
if (!shader)
|
||||
return -1;
|
||||
if (!STRING_SET(shader)) {
|
||||
return -1i;
|
||||
}
|
||||
|
||||
if (fileExists(strcat("sound/", shader)) == true) {
|
||||
precache_sound(shader);
|
||||
return -1i;
|
||||
}
|
||||
|
||||
index = g_sounds_count;
|
||||
|
||||
|
|
91
src/vgui/Widget.h
Normal file
91
src/vgui/Widget.h
Normal file
|
@ -0,0 +1,91 @@
|
|||
/** @brief The base VGUI widget class.
|
||||
|
||||
Every VGUI widget is based off of this. */
|
||||
class vguiWidget
|
||||
{
|
||||
public:
|
||||
void vguiWidget(void);
|
||||
|
||||
/** Adds a widget into this one. */
|
||||
virtual void Add(vguiWidget);
|
||||
/** Add a flag to the widget. */
|
||||
nonvirtual void FlagAdd(int);
|
||||
/** Remove a flag from the widget. */
|
||||
nonvirtual void FlagRemove(int);
|
||||
/** Check if the vguiWidget has a flag attached. */
|
||||
nonvirtual bool HasFlag(int);
|
||||
|
||||
/** Set the position within its context. */
|
||||
nonvirtual void SetPos(vector);
|
||||
/** Return the position of the widget within its context. */
|
||||
nonvirtual vector GetPos(void);
|
||||
/** Returns the X coordinate of the widget position within its context. */
|
||||
nonvirtual int GetPosWidth(void);
|
||||
/** Returns the Y coordinate of the widget position within its context. */
|
||||
nonvirtual int GetPosHeight(void);
|
||||
|
||||
/** Set the size of the widget to a new one. */
|
||||
nonvirtual void SetSize(vector);
|
||||
/** Returns the size of the widget, in pixels. */
|
||||
nonvirtual vector GetSize(void);
|
||||
|
||||
/** Returns the width of the widget, in pixels. */
|
||||
nonvirtual int GetWidth(void);
|
||||
/** Returns the height of the widget, in pixels. */
|
||||
nonvirtual int GetHeight(void);
|
||||
|
||||
/** Sets the minimum size of the widget. */
|
||||
nonvirtual void SetMinSize(vector);
|
||||
/** Returns the minimum size of the widget. */
|
||||
nonvirtual vector GetMinSize(void);
|
||||
|
||||
/** Sets the maximum size of the widget. */
|
||||
nonvirtual void SetMaxSize(vector);
|
||||
/** Returns the maximum size of the widget. */
|
||||
nonvirtual vector GetMaxSize(void);
|
||||
|
||||
/** Returns true/false depending on if the widget is visible. */
|
||||
nonvirtual bool Visible(void);
|
||||
/** Show the widget. */
|
||||
nonvirtual void Show(void);
|
||||
/** Hide the widget. */
|
||||
nonvirtual void Hide(void);
|
||||
|
||||
/** Sets the vguiTheme to use on this widget (and any children it may have) */
|
||||
nonvirtual void SetTheme(vguiTheme);
|
||||
/** Returns the VGUI that will be used on this widget. */
|
||||
nonvirtual vguiTheme GetTheme(void);
|
||||
|
||||
/** Called when the position of the widget was changed in any capacity. */
|
||||
virtual void PositionChanged(vector, vector);
|
||||
/** Called when the size of the widget has changed in any capacity. */
|
||||
virtual void SizeChanged(vector, vector);
|
||||
|
||||
virtual void NowVisible(void);
|
||||
virtual void NowHidden(void);
|
||||
|
||||
/** Called in order to draw the widget. */
|
||||
virtual void Draw(void);
|
||||
/** Called whenever the physical properties of the display change. */
|
||||
virtual void Reposition(void);
|
||||
/** Called whenever an input event gets directed to the widget. */
|
||||
virtual bool Input(float, float, float, float);
|
||||
/** Called when the widget has fully initialized.
|
||||
When you override this, you may call `super::Spawned();` to ensure
|
||||
the parent classes get to finish initializing also. */
|
||||
virtual void Spawned(void);
|
||||
|
||||
private:
|
||||
/* why are these 3D vectors? because drawpic() etc. take it. ..you never know what that may be used for some day! */
|
||||
vector m_vecOrigin;
|
||||
vector m_vecSize;
|
||||
vector m_vecMinSize;
|
||||
vector m_vecMaxSize;
|
||||
|
||||
vguiWidget m_next;
|
||||
vguiWidget m_parent;
|
||||
vguiWidget m_children;
|
||||
int m_iFlags;
|
||||
bool m_bVisible;
|
||||
vguiTheme m_theme;
|
||||
};
|
277
src/vgui/Widget.qc
Normal file
277
src/vgui/Widget.qc
Normal file
|
@ -0,0 +1,277 @@
|
|||
void
|
||||
vguiWidget::vguiWidget(void)
|
||||
{
|
||||
m_vecOrigin = [0.0f, 0.0f];
|
||||
m_vecSize = [0.0f, 0.0f];
|
||||
m_vecMinSize = [0.0f, 0.0f];
|
||||
m_vecMaxSize = [9999.0f, 9999.0f];
|
||||
m_next = __NULL__;
|
||||
m_parent = __NULL__;
|
||||
m_iFlags = 0i;
|
||||
m_bVisible = true;
|
||||
isVGUI = true;
|
||||
|
||||
Spawned();
|
||||
}
|
||||
|
||||
void
|
||||
vguiWidget::SetTheme(vguiTheme theme)
|
||||
{
|
||||
m_theme = theme;
|
||||
}
|
||||
|
||||
vguiTheme
|
||||
vguiWidget::GetTheme(void)
|
||||
{
|
||||
/* if no theme set, but we have a parent... inherit the parents' theme recursively */
|
||||
if (!m_theme && m_parent) {
|
||||
return m_parent.GetTheme();
|
||||
}
|
||||
|
||||
/* we have nothing, use the default one. */
|
||||
if (!m_theme) {
|
||||
m_theme = spawn(vguiTheme);
|
||||
}
|
||||
|
||||
return (m_theme);
|
||||
}
|
||||
|
||||
bool
|
||||
vguiWidget::Visible(void)
|
||||
{
|
||||
return (m_bVisible);
|
||||
}
|
||||
|
||||
void
|
||||
vguiWidget::Hide(void)
|
||||
{
|
||||
m_bVisible = false;
|
||||
NowHidden();
|
||||
}
|
||||
|
||||
void
|
||||
vguiWidget::NowHidden(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
vguiWidget::NowVisible(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
vguiWidget::Show(void)
|
||||
{
|
||||
m_bVisible = true;
|
||||
NowVisible();
|
||||
}
|
||||
|
||||
void
|
||||
vguiWidget::PositionChanged(vector vecOld, vector vecNew)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
vguiWidget::SizeChanged(vector vecOld, vector vecNew)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
vguiWidget::SetPos(vector vecNewPos)
|
||||
{
|
||||
vector vecOld = m_vecOrigin;
|
||||
m_vecOrigin[0] = bound(0, vecNewPos[0], 9999.0);
|
||||
m_vecOrigin[1] = bound(0, vecNewPos[1], 9999.0);
|
||||
PositionChanged(vecOld, m_vecOrigin);
|
||||
}
|
||||
|
||||
vector
|
||||
vguiWidget::GetPos(void)
|
||||
{
|
||||
return (m_vecOrigin);
|
||||
}
|
||||
|
||||
int
|
||||
vguiWidget::GetPosWidth(void)
|
||||
{
|
||||
return (m_vecOrigin[0]);
|
||||
}
|
||||
|
||||
int
|
||||
vguiWidget::GetPosHeight(void)
|
||||
{
|
||||
return (m_vecOrigin[1]);
|
||||
}
|
||||
|
||||
void
|
||||
vguiWidget::SetSize(vector vecNewSize)
|
||||
{
|
||||
vector vecOld = m_vecSize;
|
||||
m_vecSize[0] = bound(m_vecMinSize[0], vecNewSize[0], m_vecMaxSize[0]);
|
||||
m_vecSize[1] = bound(m_vecMinSize[1], vecNewSize[1], m_vecMaxSize[1]);
|
||||
SizeChanged(vecOld, m_vecSize);
|
||||
}
|
||||
|
||||
vector
|
||||
vguiWidget::GetSize(void)
|
||||
{
|
||||
return (m_vecSize);
|
||||
}
|
||||
|
||||
int
|
||||
vguiWidget::GetWidth(void)
|
||||
{
|
||||
return (m_vecSize[0]);
|
||||
}
|
||||
|
||||
int
|
||||
vguiWidget::GetHeight(void)
|
||||
{
|
||||
return (m_vecSize[1]);
|
||||
}
|
||||
|
||||
void
|
||||
vguiWidget::SetMinSize (vector vecNewSize)
|
||||
{
|
||||
m_vecMinSize = vecNewSize;
|
||||
}
|
||||
|
||||
vector
|
||||
vguiWidget::GetMinSize(void)
|
||||
{
|
||||
return (m_vecMinSize);
|
||||
}
|
||||
|
||||
void
|
||||
vguiWidget::SetMaxSize (vector vecNewSize)
|
||||
{
|
||||
m_vecMaxSize = vecNewSize;
|
||||
}
|
||||
|
||||
vector
|
||||
vguiWidget::GetMaxSize(void)
|
||||
{
|
||||
return (m_vecMaxSize);
|
||||
}
|
||||
|
||||
void
|
||||
vguiWidget::FlagAdd(int iFlag)
|
||||
{
|
||||
m_iFlags |= iFlag;
|
||||
}
|
||||
|
||||
void
|
||||
vguiWidget::FlagRemove(int iFlag)
|
||||
{
|
||||
m_iFlags -= (m_iFlags & iFlag);
|
||||
}
|
||||
|
||||
bool
|
||||
vguiWidget::HasFlag(int flag)
|
||||
{
|
||||
return (m_iFlags & flag) ? (true) : (false);
|
||||
}
|
||||
|
||||
void
|
||||
vguiWidget::Reposition(void)
|
||||
{
|
||||
vguiWidget wNext = this;
|
||||
|
||||
do {
|
||||
wNext = wNext.m_next;
|
||||
|
||||
if (wNext) {
|
||||
wNext.Reposition();
|
||||
}
|
||||
} while (wNext);
|
||||
}
|
||||
|
||||
void
|
||||
vguiWidget::Add(vguiWidget wNew)
|
||||
{
|
||||
vguiWidget wNext = this;
|
||||
vguiWidget wParent;
|
||||
|
||||
do {
|
||||
wParent = wNext;
|
||||
wNext = wNext.m_next;
|
||||
} while (wNext);
|
||||
|
||||
wParent.m_next = wNew;
|
||||
wNew.m_parent = this;
|
||||
}
|
||||
|
||||
void
|
||||
vguiWidget::Draw(void)
|
||||
{
|
||||
vguiWidget wNext = this;
|
||||
g_vguiWidgetCount = 0;
|
||||
|
||||
do {
|
||||
wNext = wNext.m_next;
|
||||
if (wNext && wNext.Visible() && wNext.m_parent.Visible()) {
|
||||
g_vguiWidgetCount++;
|
||||
wNext.Draw();
|
||||
}
|
||||
} while (wNext);
|
||||
}
|
||||
|
||||
bool
|
||||
vguiWidget::Input(float flEVType, float flKey, float flChar, float flDevID)
|
||||
{
|
||||
vguiWidget wNext = this;
|
||||
vguiWidget wLast = __NULL__;
|
||||
vguiWidget wLastBefore = __NULL__;
|
||||
|
||||
/* figure out the last window in the chain... */
|
||||
do {
|
||||
wLastBefore = wNext;
|
||||
wNext = wNext.m_next;
|
||||
|
||||
if (wNext) {
|
||||
wLast = wNext;
|
||||
}
|
||||
} while (wNext);
|
||||
|
||||
//print(sprintf("Last widget: %S\n", wLast.classname));
|
||||
|
||||
/* we've found a window, let's test inputs backwards. */
|
||||
while (wLast.classname) {
|
||||
bool test = false;
|
||||
|
||||
if (wLast.Visible())
|
||||
test = wLast.Input(flEVType, flKey, flChar, flDevID);
|
||||
|
||||
//print(sprintf("Testing input for... widget: %S %d\n", wLast.classname, test));
|
||||
|
||||
/* input successful */
|
||||
if (test == true) {
|
||||
return (true);
|
||||
}
|
||||
|
||||
/* select the former input */
|
||||
for (vguiWidget a = this; a != __NULL__; a = a.m_next) {
|
||||
/* we've reached the end, take one from before */
|
||||
if (a == wLast) {
|
||||
wLast = wLastBefore;
|
||||
break;
|
||||
}
|
||||
wLastBefore = a;
|
||||
}
|
||||
|
||||
/* the end of the world. */
|
||||
if (wLast == this)
|
||||
return (false);
|
||||
}
|
||||
|
||||
return (false);
|
||||
}
|
||||
|
||||
void
|
||||
vguiWidget::Spawned(void)
|
||||
{
|
||||
}
|
|
@ -1,28 +1,29 @@
|
|||
#includelist
|
||||
../vgui/ui_color.qc
|
||||
../vgui/ui_theme.qc
|
||||
../vgui/Color.qc
|
||||
../vgui/Theme.qc
|
||||
../vgui/ui.qc
|
||||
../vgui/ui_control.qc
|
||||
../vgui/ui_button.qc
|
||||
../vgui/ui_commandbutton.qc
|
||||
../vgui/ui_menubutton.qc
|
||||
../vgui/ui_radio.qc
|
||||
../vgui/ui_checkbox.qc
|
||||
../vgui/ui_view.qc
|
||||
../vgui/ui_window.qc
|
||||
../vgui/ui_frame.qc
|
||||
../vgui/ui_label.qc
|
||||
../vgui/ui_menutitle.qc
|
||||
../vgui/ui_pic.qc
|
||||
../vgui/ui_rect.qc
|
||||
../vgui/ui_3dview.qc
|
||||
../vgui/ui_scrollbar.qc
|
||||
../vgui/ui_list.qc
|
||||
../vgui/ui_listbox.qc
|
||||
../vgui/ui_textbox.qc
|
||||
../vgui/ui_tabviewitem.qc
|
||||
../vgui/ui_tabview.qc
|
||||
../vgui/ui_progressbar.qc
|
||||
../vgui/ui_loadingpanel.qc
|
||||
../vgui/ui_textview.qc
|
||||
../vgui/Widget.qc
|
||||
../vgui/Control.qc
|
||||
../vgui/Button.qc
|
||||
../vgui/CommandButton.qc
|
||||
../vgui/MenuButton.qc
|
||||
../vgui/Radio.qc
|
||||
../vgui/CheckBox.qc
|
||||
../vgui/View.qc
|
||||
../vgui/Window.qc
|
||||
../vgui/Frame.qc
|
||||
../vgui/Label.qc
|
||||
../vgui/MenuTitle.qc
|
||||
../vgui/Pic.qc
|
||||
../vgui/Rect.qc
|
||||
../vgui/3DView.qc
|
||||
../vgui/ScrollBar.qc
|
||||
../vgui/List.qc
|
||||
../vgui/ListBox.qc
|
||||
../vgui/TextBox.qc
|
||||
../vgui/TabViewItem.qc
|
||||
../vgui/TabView.qc
|
||||
../vgui/ProgressBar.qc
|
||||
../vgui/LoadingPanel.qc
|
||||
../vgui/TextView.qc
|
||||
#endlist
|
||||
|
|
372
src/vgui/ui.qc
372
src/vgui/ui.qc
|
@ -16,6 +16,8 @@
|
|||
|
||||
#warning vguiWidget needs methods to deal with .res/.gui type files.
|
||||
|
||||
#include "Widget.h"
|
||||
|
||||
.string classname;
|
||||
.bool isVGUI;
|
||||
|
||||
|
@ -119,376 +121,6 @@ Util_MouseAbove(vector vecMousePos, vector vecPos, vector vecSize)
|
|||
return (false);
|
||||
}
|
||||
|
||||
/** @brief The base VGUI widget class.
|
||||
|
||||
Every VGUI widget is based off of this. */
|
||||
class vguiWidget
|
||||
{
|
||||
public:
|
||||
void vguiWidget(void);
|
||||
|
||||
/** Adds a widget into this one. */
|
||||
virtual void Add(vguiWidget);
|
||||
/** Add a flag to the widget. */
|
||||
nonvirtual void FlagAdd(int);
|
||||
/** Remove a flag from the widget. */
|
||||
nonvirtual void FlagRemove(int);
|
||||
/** Check if the vguiWidget has a flag attached. */
|
||||
nonvirtual bool HasFlag(int);
|
||||
|
||||
/** Set the position within its context. */
|
||||
nonvirtual void SetPos(vector);
|
||||
/** Return the position of the widget within its context. */
|
||||
nonvirtual vector GetPos(void);
|
||||
/** Returns the X coordinate of the widget position within its context. */
|
||||
nonvirtual int GetPosWidth(void);
|
||||
/** Returns the Y coordinate of the widget position within its context. */
|
||||
nonvirtual int GetPosHeight(void);
|
||||
|
||||
/** Set the size of the widget to a new one. */
|
||||
nonvirtual void SetSize(vector);
|
||||
/** Returns the size of the widget, in pixels. */
|
||||
nonvirtual vector GetSize(void);
|
||||
|
||||
/** Returns the width of the widget, in pixels. */
|
||||
nonvirtual int GetWidth(void);
|
||||
/** Returns the height of the widget, in pixels. */
|
||||
nonvirtual int GetHeight(void);
|
||||
|
||||
/** Sets the minimum size of the widget. */
|
||||
nonvirtual void SetMinSize(vector);
|
||||
/** Returns the minimum size of the widget. */
|
||||
nonvirtual vector GetMinSize(void);
|
||||
|
||||
/** Sets the maximum size of the widget. */
|
||||
nonvirtual void SetMaxSize(vector);
|
||||
/** Returns the maximum size of the widget. */
|
||||
nonvirtual vector GetMaxSize(void);
|
||||
|
||||
/** Returns true/false depending on if the widget is visible. */
|
||||
nonvirtual bool Visible(void);
|
||||
/** Show the widget. */
|
||||
nonvirtual void Show(void);
|
||||
/** Hide the widget. */
|
||||
nonvirtual void Hide(void);
|
||||
|
||||
/** Sets the vguiTheme to use on this widget (and any children it may have) */
|
||||
nonvirtual void SetTheme(vguiTheme);
|
||||
/** Returns the VGUI that will be used on this widget. */
|
||||
nonvirtual vguiTheme GetTheme(void);
|
||||
|
||||
/** Called when the position of the widget was changed in any capacity. */
|
||||
virtual void PositionChanged(vector, vector);
|
||||
/** Called when the size of the widget has changed in any capacity. */
|
||||
virtual void SizeChanged(vector, vector);
|
||||
|
||||
virtual void NowVisible(void);
|
||||
virtual void NowHidden(void);
|
||||
|
||||
/** Called in order to draw the widget. */
|
||||
virtual void Draw(void);
|
||||
/** Called whenever the physical properties of the display change. */
|
||||
virtual void Reposition(void);
|
||||
/** Called whenever an input event gets directed to the widget. */
|
||||
virtual bool Input(float, float, float, float);
|
||||
/** Called when the widget has fully initialized.
|
||||
When you override this, you may call `super::Spawned();` to ensure
|
||||
the parent classes get to finish initializing also. */
|
||||
virtual void Spawned(void);
|
||||
|
||||
private:
|
||||
/* why are these 3D vectors? because drawpic() etc. take it. ..you never know what that may be used for some day! */
|
||||
vector m_vecOrigin;
|
||||
vector m_vecSize;
|
||||
vector m_vecMinSize;
|
||||
vector m_vecMaxSize;
|
||||
|
||||
vguiWidget m_next;
|
||||
vguiWidget m_parent;
|
||||
vguiWidget m_children;
|
||||
int m_iFlags;
|
||||
bool m_bVisible;
|
||||
vguiTheme m_theme;
|
||||
};
|
||||
|
||||
void
|
||||
vguiWidget::vguiWidget(void)
|
||||
{
|
||||
m_vecOrigin = [0.0f, 0.0f];
|
||||
m_vecSize = [0.0f, 0.0f];
|
||||
m_vecMinSize = [0.0f, 0.0f];
|
||||
m_vecMaxSize = [9999.0f, 9999.0f];
|
||||
m_next = __NULL__;
|
||||
m_parent = __NULL__;
|
||||
m_iFlags = 0i;
|
||||
m_bVisible = true;
|
||||
isVGUI = true;
|
||||
|
||||
Spawned();
|
||||
}
|
||||
|
||||
void
|
||||
vguiWidget::SetTheme(vguiTheme theme)
|
||||
{
|
||||
m_theme = theme;
|
||||
}
|
||||
|
||||
vguiTheme
|
||||
vguiWidget::GetTheme(void)
|
||||
{
|
||||
/* if no theme set, but we have a parent... inherit the parents' theme recursively */
|
||||
if (!m_theme && m_parent) {
|
||||
return m_parent.GetTheme();
|
||||
}
|
||||
|
||||
/* we have nothing, use the default one. */
|
||||
if (!m_theme) {
|
||||
m_theme = spawn(vguiTheme);
|
||||
}
|
||||
|
||||
return (m_theme);
|
||||
}
|
||||
|
||||
bool
|
||||
vguiWidget::Visible(void)
|
||||
{
|
||||
return (m_bVisible);
|
||||
}
|
||||
|
||||
void
|
||||
vguiWidget::Hide(void)
|
||||
{
|
||||
m_bVisible = false;
|
||||
NowHidden();
|
||||
}
|
||||
|
||||
void
|
||||
vguiWidget::NowHidden(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
vguiWidget::NowVisible(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
vguiWidget::Show(void)
|
||||
{
|
||||
m_bVisible = true;
|
||||
NowVisible();
|
||||
}
|
||||
|
||||
void
|
||||
vguiWidget::PositionChanged(vector vecOld, vector vecNew)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
vguiWidget::SizeChanged(vector vecOld, vector vecNew)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
vguiWidget::SetPos(vector vecNewPos)
|
||||
{
|
||||
vector vecOld = m_vecOrigin;
|
||||
m_vecOrigin[0] = bound(0, vecNewPos[0], 9999.0);
|
||||
m_vecOrigin[1] = bound(0, vecNewPos[1], 9999.0);
|
||||
PositionChanged(vecOld, m_vecOrigin);
|
||||
}
|
||||
|
||||
vector
|
||||
vguiWidget::GetPos(void)
|
||||
{
|
||||
return (m_vecOrigin);
|
||||
}
|
||||
|
||||
int
|
||||
vguiWidget::GetPosWidth(void)
|
||||
{
|
||||
return (m_vecOrigin[0]);
|
||||
}
|
||||
|
||||
int
|
||||
vguiWidget::GetPosHeight(void)
|
||||
{
|
||||
return (m_vecOrigin[1]);
|
||||
}
|
||||
|
||||
void
|
||||
vguiWidget::SetSize(vector vecNewSize)
|
||||
{
|
||||
vector vecOld = m_vecSize;
|
||||
m_vecSize[0] = bound(m_vecMinSize[0], vecNewSize[0], m_vecMaxSize[0]);
|
||||
m_vecSize[1] = bound(m_vecMinSize[1], vecNewSize[1], m_vecMaxSize[1]);
|
||||
SizeChanged(vecOld, m_vecSize);
|
||||
}
|
||||
|
||||
vector
|
||||
vguiWidget::GetSize(void)
|
||||
{
|
||||
return (m_vecSize);
|
||||
}
|
||||
|
||||
int
|
||||
vguiWidget::GetWidth(void)
|
||||
{
|
||||
return (m_vecSize[0]);
|
||||
}
|
||||
|
||||
int
|
||||
vguiWidget::GetHeight(void)
|
||||
{
|
||||
return (m_vecSize[1]);
|
||||
}
|
||||
|
||||
void
|
||||
vguiWidget::SetMinSize (vector vecNewSize)
|
||||
{
|
||||
m_vecMinSize = vecNewSize;
|
||||
}
|
||||
|
||||
vector
|
||||
vguiWidget::GetMinSize(void)
|
||||
{
|
||||
return (m_vecMinSize);
|
||||
}
|
||||
|
||||
void
|
||||
vguiWidget::SetMaxSize (vector vecNewSize)
|
||||
{
|
||||
m_vecMaxSize = vecNewSize;
|
||||
}
|
||||
|
||||
vector
|
||||
vguiWidget::GetMaxSize(void)
|
||||
{
|
||||
return (m_vecMaxSize);
|
||||
}
|
||||
|
||||
void
|
||||
vguiWidget::FlagAdd(int iFlag)
|
||||
{
|
||||
m_iFlags |= iFlag;
|
||||
}
|
||||
|
||||
void
|
||||
vguiWidget::FlagRemove(int iFlag)
|
||||
{
|
||||
m_iFlags -= (m_iFlags & iFlag);
|
||||
}
|
||||
|
||||
bool
|
||||
vguiWidget::HasFlag(int flag)
|
||||
{
|
||||
return (m_iFlags & flag) ? (true) : (false);
|
||||
}
|
||||
|
||||
void
|
||||
vguiWidget::Reposition(void)
|
||||
{
|
||||
vguiWidget wNext = this;
|
||||
|
||||
do {
|
||||
wNext = wNext.m_next;
|
||||
|
||||
if (wNext) {
|
||||
wNext.Reposition();
|
||||
}
|
||||
} while (wNext);
|
||||
}
|
||||
|
||||
void
|
||||
vguiWidget::Add(vguiWidget wNew)
|
||||
{
|
||||
vguiWidget wNext = this;
|
||||
vguiWidget wParent;
|
||||
|
||||
do {
|
||||
wParent = wNext;
|
||||
wNext = wNext.m_next;
|
||||
} while (wNext);
|
||||
|
||||
wParent.m_next = wNew;
|
||||
wNew.m_parent = this;
|
||||
}
|
||||
|
||||
void
|
||||
vguiWidget::Draw(void)
|
||||
{
|
||||
vguiWidget wNext = this;
|
||||
g_vguiWidgetCount = 0;
|
||||
|
||||
do {
|
||||
wNext = wNext.m_next;
|
||||
if (wNext && wNext.Visible() && wNext.m_parent.Visible()) {
|
||||
g_vguiWidgetCount++;
|
||||
wNext.Draw();
|
||||
}
|
||||
} while (wNext);
|
||||
}
|
||||
|
||||
bool
|
||||
vguiWidget::Input(float flEVType, float flKey, float flChar, float flDevID)
|
||||
{
|
||||
vguiWidget wNext = this;
|
||||
vguiWidget wLast = __NULL__;
|
||||
vguiWidget wLastBefore = __NULL__;
|
||||
|
||||
/* figure out the last window in the chain... */
|
||||
do {
|
||||
wLastBefore = wNext;
|
||||
wNext = wNext.m_next;
|
||||
|
||||
if (wNext) {
|
||||
wLast = wNext;
|
||||
}
|
||||
} while (wNext);
|
||||
|
||||
//print(sprintf("Last widget: %S\n", wLast.classname));
|
||||
|
||||
/* we've found a window, let's test inputs backwards. */
|
||||
while (wLast.classname) {
|
||||
bool test = false;
|
||||
|
||||
if (wLast.Visible())
|
||||
test = wLast.Input(flEVType, flKey, flChar, flDevID);
|
||||
|
||||
//print(sprintf("Testing input for... widget: %S %d\n", wLast.classname, test));
|
||||
|
||||
/* input successful */
|
||||
if (test == true) {
|
||||
return (true);
|
||||
}
|
||||
|
||||
/* select the former input */
|
||||
for (vguiWidget a = this; a != __NULL__; a = a.m_next) {
|
||||
/* we've reached the end, take one from before */
|
||||
if (a == wLast) {
|
||||
wLast = wLastBefore;
|
||||
break;
|
||||
}
|
||||
wLastBefore = a;
|
||||
}
|
||||
|
||||
/* the end of the world. */
|
||||
if (wLast == this)
|
||||
return (false);
|
||||
}
|
||||
|
||||
return (false);
|
||||
}
|
||||
|
||||
void
|
||||
vguiWidget::Spawned(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
UISystem_Init(void)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue