NSEntity: new methods to simplify a lot of common tasks added. ScheduleThink(void(), float) and WithinBounds(entity) will surely be helpful.

Went over gs-entbase/server and made sure to use the new Think handlers to safely deal with MOVETYPE_PUSH
and handle any fun edge cases where time may be 0.0f.
func_breakable has also been fixed, since the changed Show/Hide behaviour prevented
them from getting destroyed fully.
This commit is contained in:
Marco Cawthorne 2022-08-26 15:39:00 -07:00
parent acaa918403
commit 7a252ad213
Signed by: eukara
GPG Key ID: CE2032F0A2882A22
41 changed files with 380 additions and 343 deletions

View File

@ -144,13 +144,12 @@ env_beverage::Trigger(entity act, int unused)
return;
}
entity eCan = spawn();
setorigin(eCan, origin);
eCan.angles = angles;
eCan.owner = this;
eCan.think = item_sodacan;
eCan.nextthink = time;
eCan.skin = m_sodaSkin;
NSEntity eCan = spawn(NSEntity);
eCan.SetOrigin(GetOrigin());
eCan.SetAngles(GetAngles());
eCan.SetOwner(this);
eCan.ScheduleThink(item_sodacan, 0.0f);
eCan.SetSkin((float)m_sodaSkin);
m_iUses--;
m_bReady = false;

View File

@ -69,7 +69,7 @@ env_laser:NSPointTrigger
virtual void(string,string) Restore;
virtual void(string, string) SpawnKey;
virtual void(void) Respawn;
virtual void(void) think;
virtual void(void) LaserThink;
virtual void(entity, int) Trigger;
virtual void(void) EvaluateEntity;
virtual float(entity, float) SendEntity;
@ -154,26 +154,26 @@ env_laser::Respawn(void)
{
if (HasSpawnFlags(ENVLAZ_STARTON)) {
m_iState = 1;
nextthink = time + 0.1;
ScheduleThink(LaserThink, 0.0f);
}
}
void
env_laser::think(void)
env_laser::LaserThink(void)
{
entity t;
if (!m_iState) {
return;
} else {
nextthink = time + 0.1;
ScheduleThink(LaserThink, 0.1f);
}
t = find(world, ::targetname, m_strLaserDest);
angles = t.origin;
SetAngles(t.origin);
if (!t) {
print(sprintf("^1env_laser::^3think^7: %s has no valid target. Aborting\n", targetname));
print(sprintf("^1env_laser::^3LaserThink^7: %s has no valid target. Aborting\n", targetname));
return;
}
@ -199,9 +199,9 @@ env_laser::Trigger(entity act, int state)
}
if (m_iState) {
nextthink = time;
ScheduleThink(LaserThink, 0.0f);
} else {
nextthink = 0.25;
ReleaseThink();
}
}

View File

@ -178,33 +178,35 @@ env_shooter::Respawn(void)
}
m_iGibsLeft = m_iGibs;
think = __NULL__;
ReleaseThink();
}
void
env_shooter::ShootGib(void)
{
static void Gib_Remove(void) { remove(self); }
vector vecSpinVel = [0.0f, 0.0f, 0.0f];
vector vecThrowVel = [0.0f, 0.0f, 0.0f];
entity eGib = spawn();
eGib.movetype = MOVETYPE_BOUNCE;
setmodel(eGib, m_strShootModel);
setorigin(eGib, origin);
NSRenderableEntity eGib = spawn(NSRenderableEntity);
eGib.SetMovetype(MOVETYPE_BOUNCE);
eGib.SetModel(m_strShootModel);
eGib.SetOrigin(GetOrigin());
eGib.SetAngles(GetAngles());
makevectors(angles);
eGib.velocity = v_forward * m_flVelocity + [0,0,64 + (random()*64)];
eGib.avelocity[0] = random(-1,1) * 32;
eGib.avelocity[1] = random(-1,1) * 32;
eGib.avelocity[2] = random(-1,1) * 32;
eGib.think = Gib_Remove;
eGib.nextthink = time + m_flGibLife;
eGib.angles = angles;
makevectors(GetAngles());
vecThrowVel = v_forward * m_flVelocity;
vecThrowVel += [0.0f, 0.0f, 64.0f + (random() * 64.0f)];
vecSpinVel[0] = random(-1,1) * 32;
vecSpinVel[1] = random(-1,1) * 32;
vecSpinVel[2] = random(-1,1) * 32;
eGib.SetVelocity(vecThrowVel);
eGib.SetAngularVelocity(vecSpinVel);
eGib.ScheduleThink(Destroy, m_flGibLife);
m_iGibsLeft--;
if (m_iGibsLeft) {
nextthink = time + m_flVariance;
ScheduleThink(ShootGib, m_flVariance);
}
}
@ -213,18 +215,16 @@ env_shooter::Trigger(entity act, int state)
{
switch (state) {
case TRIG_OFF:
think = __NULL__;
nextthink = 0.0f;
ReleaseThink();
break;
case TRIG_ON:
if (spawnflags & EVSHOOTER_REPEATABLE)
m_iGibsLeft = m_iGibs;
think = ShootGib;
nextthink = time + m_flVariance;
ScheduleThink(ShootGib, m_flVariance);
break;
default:
if (think == __NULL__)
if (IsThinking() == false)
Trigger(act, TRIG_ON);
else
Trigger(act, TRIG_OFF);

View File

@ -131,15 +131,13 @@ env_spark::Trigger(entity act, int state)
switch (state) {
case TRIG_OFF:
think = __NULL__;
nextthink = 0;
ReleaseThink();
break;
case TRIG_ON:
think = TimedSpark;
nextthink = time + (random() * m_flMaxDelay);
ScheduleThink(CreateSpark, (random() * m_flMaxDelay));
break;
default:
if (think != __NULL__) {
if (IsThinking() == true) {
Trigger(act, TRIG_OFF);
} else {
Trigger(act, TRIG_ON);
@ -158,5 +156,5 @@ void
env_spark::TimedSpark(void)
{
CreateSpark();
nextthink = time + (random() * m_flMaxDelay);
ScheduleThink(CreateSpark, (random() * m_flMaxDelay));
}

View File

@ -62,6 +62,7 @@ func_areaportal::Respawn(void)
SetModel(GetSpawnModel());
SetOrigin(GetSpawnOrigin());
Hide();
SetSolid(SOLID_NOT);
if (!m_iStartOpen)
PortalClose();

View File

@ -251,30 +251,30 @@ func_breakable::Respawn(void)
SetModel(GetSpawnModel());
SetOrigin(GetSpawnOrigin());
ClearAngles();
think = __NULL__;
ReleaseThink();
m_bCanTouch = true;
if (HasSpawnFlags(SF_TRIGGER)) {
takedamage = DAMAGE_NO;
SetTakedamage(DAMAGE_NO);
} else {
takedamage = DAMAGE_YES;
SetTakedamage(DAMAGE_YES);
}
/* initially set the health to that of the ent-data */
float sh = GetSpawnHealth();
float spawnhealth = GetSpawnHealth();
if (HasPropData() == TRUE && sh == 0) {
if (HasPropData() == TRUE && spawnhealth <= 0) {
/* assign propdata health */
health = GetPropData(PROPINFO_HEALTH);
SetHealth(GetPropData(PROPINFO_HEALTH));
m_flExplodeMag = GetPropData(PROPINFO_EXPLOSIVE_DMG);
m_flExplodeRad = GetPropData(PROPINFO_EXPLOSIVE_RADIUS);
} else {
health = sh;
SetHealth(spawnhealth);
}
/* unassigned health isn't valid */
if (!health)
health = 15;
if (GetHealth() <= 0)
SetHealth(15);
}
void
@ -297,6 +297,8 @@ func_breakable::Explode(void)
Damage_Radius(rp, this, m_flExplodeMag, m_flExplodeRad, TRUE, 0);
UseTargets(this, TRIG_TOGGLE, 0.0f); /* delay... ignored. */
Hide();
SetSolid(SOLID_NOT);
SetTakedamage(DAMAGE_NO);
}
void
@ -340,11 +342,12 @@ func_breakable::Death(void)
* The only way around this is to set a hard-coded limit of loops per
* frame and that would break functionality. */
if (m_flExplodeMag) {
think = Explode;
nextthink = time + random(0.0,0.5);
ScheduleThink(Explode, random(0.0f, 0.5f));
} else {
FX_BreakModel(vlen(size) / 10, absmin, absmax, [0,0,0], GetSurfaceData(SURFDATA_MATERIAL));
Hide();
SetSolid(SOLID_NOT);
SetTakedamage(DAMAGE_NO);
UseTargets(eActivator, TRIG_TOGGLE, 0.0f);
}
}
@ -352,7 +355,7 @@ func_breakable::Death(void)
void
func_breakable::Trigger(entity act, int state)
{
if (health > 0)
if (GetHealth() > 0)
Death();
}
@ -392,12 +395,11 @@ func_breakable::Touch(entity eToucher)
if (HasSpawnFlags(SF_PRESSURE) && (eToucher.absmin[2] >= maxs[2] - 2)) {
m_bCanTouch = false;
think = TriggerWrap;
if (m_flDelay == 0) {
if (m_flDelay <= 0) {
m_flDelay = 0.1f;
}
nextthink = time + m_flDelay;
ScheduleThink(TriggerWrap, m_flDelay);
}
}

View File

@ -313,9 +313,9 @@ func_button::Respawn(void)
SetOrigin(GetSpawnOrigin());
SetModel(GetSpawnModel());
velocity = [0,0,0];
nextthink = -1;
health = GetSpawnHealth();
ClearVelocity();
ReleaseThink();
SetHealth(GetSpawnHealth());
if (health > 0) {
takedamage = DAMAGE_YES;
@ -342,20 +342,19 @@ void
func_button::Arrived(void)
{
SetOrigin(m_vecDest);
velocity = [0,0,0];
nextthink = 0;
ClearVelocity();
ReleaseThink();
m_bCanTouch = true;
UseOutput(this, m_strOnIn);
m_iState = STATE_RAISED;
if (HasSpawnFlags(SF_BTT_TOGGLE)) {
if (HasSpawnFlags(SF_BTT_TOGGLE) == true) {
return;
}
if (m_flWait != -1) {
think = MoveBack;
nextthink = (ltime + m_flWait);
ScheduleThink(MoveBack, m_flWait);
}
}
@ -364,12 +363,11 @@ func_button::Returned(void)
{
UseOutput(this, m_strOnOut);
SetOrigin(m_vecDest);
velocity = [0,0,0];
nextthink = 0;
m_bCanTouch = true;
m_iState = STATE_LOWERED;
ClearVelocity();
ReleaseThink();
SetFrame(FRAME_OFF);
m_bCanTouch = true;
m_iState = STATE_LOWERED;
}
void
@ -396,13 +394,8 @@ func_button::MoveAway(void)
if (m_iState == STATE_UP) {
return;
}
m_bCanTouch = false;
if (m_iState == STATE_RAISED) {
nextthink = (ltime + m_flWait);
return;
}
m_bCanTouch = false;
m_iState = STATE_UP;
if (m_vecPos2 != m_vecPos1) {
@ -448,7 +441,7 @@ func_button::Trigger(entity act, int state)
if (message)
env_message_single(act, message);
health = GetSpawnHealth();
SetHealth(GetSpawnHealth());
}
void
@ -460,7 +453,7 @@ func_button::DeathTrigger(void)
void
func_button::Touch(entity eToucher)
{
if (!HasSpawnFlags(SF_BTT_TOUCH_ONLY)) {
if (HasSpawnFlags(SF_BTT_TOUCH_ONLY) == false) {
return;
}
@ -517,11 +510,10 @@ func_button::MoveToDestination(vector vecDest, void(void) func)
}
m_vecDest = vecDest;
think = func;
if (vecDest == origin) {
velocity = [0,0,0];
nextthink = (ltime + 0.1);
ClearVelocity();
ScheduleThink(func, 0.0f);
return;
}
@ -530,11 +522,11 @@ func_button::MoveToDestination(vector vecDest, void(void) func)
fTravelTime = (flTravel / m_flSpeed);
if (fTravelTime < 0.1) {
velocity = [0,0,0];
nextthink = ltime + 0.1;
ClearVelocity();
ScheduleThink(func, 0.0f);
return;
}
nextthink = (ltime + fTravelTime);
velocity = (vecDifference * (1 / fTravelTime));
ScheduleThink(func, fTravelTime);
SetVelocity(vecDifference * (1 / fTravelTime));
}

View File

@ -375,10 +375,8 @@ func_door::Respawn(void)
SetMovetype(MOVETYPE_PUSH);
SetModel(GetSpawnModel());
SetOrigin(GetSpawnOrigin());
flags |= FL_FINDABLE_NONSOLID;
think = __NULL__;
nextthink = 0.0f;
AddFlags(FL_FINDABLE_NONSOLID);
ReleaseThink();
/* FIXME: Is this correct? */
if (m_flWait == -1) {
@ -472,8 +470,8 @@ void
func_door::Arrived(void)
{
SetOrigin(m_vecDest);
velocity = [0,0,0];
nextthink = 0.0f;
ClearVelocity();
ReleaseThink();
m_iState = DOORSTATE_RAISED;
@ -489,16 +487,15 @@ func_door::Arrived(void)
if ((m_flWait < 0.0f) || HasSpawnFlags(SF_MOV_TOGGLE) == true)
return;
think = MoveBack;
nextthink = (ltime + m_flWait);
ScheduleThink(MoveBack, m_flWait);
}
void
func_door::Returned(void)
{
SetOrigin(m_vecDest);
velocity = [0,0,0];
nextthink = 0.0f;
ClearVelocity();
ReleaseThink();
if (targetClose)
for (entity f = world; (f = find(f, ::targetname, targetClose));) {
@ -554,13 +551,6 @@ func_door::MoveAway(void)
if (m_strSndMove)
Sound_Play(this, CHAN_WEAPON, m_strSndMove);
if (!HasSpawnFlags(SF_MOV_TOGGLE)) {
if (m_iState == DOORSTATE_RAISED) {
nextthink = (ltime + m_flWait);
return;
}
}
m_iValue = 1;
m_iState = DOORSTATE_UP;
MoveToDestination(m_vecPos2, Arrived);
@ -568,13 +558,13 @@ func_door::MoveAway(void)
}
void
func_door::Trigger(entity act, int state)
func_door::Trigger(entity act, int triggerstate)
{
if (GetMaster() == 0)
return;
if (m_flNextTrigger > time) {
if (!HasSpawnFlags(SF_MOV_TOGGLE)) {
if (HasSpawnFlags(SF_MOV_TOGGLE) == false) {
return;
}
}
@ -585,9 +575,9 @@ func_door::Trigger(entity act, int state)
UseTargets(act, TRIG_TOGGLE, m_flDelay);
}
if (state == TRIG_OFF) {
if (triggerstate == TRIG_OFF) {
MoveBack();
} else if (state == TRIG_ON) {
} else if (triggerstate == TRIG_ON) {
MoveAway();
} else {
if ((m_iState == DOORSTATE_UP) || (m_iState == DOORSTATE_RAISED)){
@ -604,7 +594,7 @@ func_door::Touch(entity eToucher)
if (m_iCanTouch == false)
return;
if (HasSpawnFlags(SF_MOV_USE))
if (HasSpawnFlags(SF_MOV_USE) == true)
return;
if (m_iLocked || !GetMaster()) {
@ -615,7 +605,7 @@ func_door::Touch(entity eToucher)
return;
}
if (HasSpawnFlags(SF_MOV_TOGGLE)) {
if (HasSpawnFlags(SF_MOV_TOGGLE) == true) {
return;
}
@ -669,11 +659,10 @@ func_door::MoveToDestination(vector vecDest, void(void) func)
}
m_vecDest = vecDest;
think = func;
if (vecDest == origin) {
velocity = [0,0,0];
nextthink = (ltime + 0.1f);
ScheduleThink(func, 0.1f);
ClearVelocity();
return;
}
@ -682,13 +671,13 @@ func_door::MoveToDestination(vector vecDest, void(void) func)
fTravelTime = (flTravel / m_flSpeed);
if (fTravelTime < 0.1) {
velocity = [0,0,0];
nextthink = ltime + 0.1f;
ScheduleThink(func, 0.1f);
ClearVelocity();
return;
}
nextthink = (ltime + fTravelTime);
velocity = (vecDifference * (1.0f / fTravelTime));
ScheduleThink(func, fTravelTime);
SetVelocity(vecDifference * (1.0f / fTravelTime));
}
void

View File

@ -259,8 +259,8 @@ func_door_rotating::Respawn(void)
ClearAngles();
#ifdef GS_PHYSICS
takedamage = DAMAGE_YES;
health = 100;
SetTakedamage(DAMAGE_YES);
SetHealth(100);
Death = func_door_rotating::Unhinge;
#endif
@ -268,9 +268,8 @@ func_door_rotating::Respawn(void)
SetMovetype(MOVETYPE_PUSH);
SetModel(GetSpawnModel());
SetOrigin(GetSpawnOrigin());
think = __NULL__;
nextthink = 0.0f;
avelocity = [0,0,0];
ClearVelocity();
ReleaseThink();
if (spawnflags & SF_ROT_USE)
m_iCanTouch = false;
@ -397,8 +396,8 @@ func_door_rotating::PortalClose(void)
void
func_door_rotating::Unhinge(void)
{
takedamage = DAMAGE_NO;
think = __NULL__;
SetTakedamage(DAMAGE_NO);
ReleaseThink();
m_iCanTouch = false;
SetSolid(SOLID_PHYSICS_BOX);
SetMovetype(MOVETYPE_PHYSICS);
@ -411,7 +410,7 @@ func_door_rotating::Arrived(void)
{
SetAngles(m_vecDest);
SetAngularVelocity([0,0,0]);
nextthink = 0.0f;
ReleaseThink();
m_iState = STATE_RAISED;
@ -424,8 +423,7 @@ func_door_rotating::Arrived(void)
if ((m_flWait < 0.0f) || HasSpawnFlags(SF_ROT_TOGGLE) == true)
return;
think = Back;
nextthink = (ltime + m_flWait);
ScheduleThink(Back, m_flWait);
}
void
@ -433,7 +431,7 @@ func_door_rotating::Returned(void)
{
SetAngles(m_vecDest);
SetAngularVelocity([0,0,0]);
nextthink = 0.0f;
ReleaseThink();
if (m_strSndStop) {
Sound_Play(this, CHAN_VOICE, m_strSndStop);
@ -458,7 +456,6 @@ void
func_door_rotating::Back(void)
{
if (!HasSpawnFlags(SF_DOOR_SILENT)) {
if (m_strSndClose) {
Sound_Play(this, CHAN_VOICE, m_strSndClose);
} else {
@ -486,11 +483,6 @@ func_door_rotating::Away(void)
sound(this, CHAN_VOICE, "common/null.wav", 1.0f, ATTN_NORM);
}
}
if (m_iState == STATE_RAISED) {
nextthink = (ltime + m_flWait);
return;
}
m_iState = STATE_UP;
@ -566,8 +558,9 @@ func_door_rotating::Touch(entity eToucher)
return;
}
if ((m_iState == STATE_UP) || (m_iState == STATE_DOWN))
if ((m_iState == STATE_UP) || (m_iState == STATE_DOWN)) {
return;
}
if (eToucher.movetype == MOVETYPE_WALK) {
Trigger(eToucher, TRIG_TOGGLE);
@ -610,7 +603,7 @@ func_door_rotating::RotToDest(vector vDestAngle, void(void) func)
if (!m_flSpeed) {
NSLog("^1func_door_rotating::^3RotToDest^7: No speed defined for %s!", targetname);
func_door_rotating::Respawn();
Respawn();
return;
}
@ -620,12 +613,10 @@ func_door_rotating::RotToDest(vector vDestAngle, void(void) func)
/* Avoid NAN hack */
if (flTravelTime <= 0.0f) {
func();
nextthink = 0.0f;
ScheduleThink(func, 0.0f);
} else {
avelocity = (vecAngleDifference * (1 / flTravelTime));
m_vecDest = vDestAngle;
think = func;
nextthink = (ltime + flTravelTime);
ScheduleThink(func, flTravelTime);
}
}

View File

@ -128,11 +128,10 @@ func_guntarget::Respawn(void)
SetMovetype(MOVETYPE_PUSH);
SetModel(GetSpawnModel());
SetOrigin(GetSpawnOrigin());
health = GetSpawnHealth();
SetHealth(GetSpawnHealth());
if (HasSpawnFlags(SF_GUNTARGET_ON)) {
think = ThinkWrap;
nextthink = ltime + 0.25f;
if (HasSpawnFlags(SF_GUNTARGET_ON) == true) {
ScheduleThink(ThinkWrap, 0.25f);
}
}
@ -156,14 +155,13 @@ func_guntarget::Move(void)
vel_to_pos = (node.origin - vecWorldPos);
flTravelTime = (vlen(vel_to_pos) / m_flSpeed);
if (!flTravelTime) {
if (flTravelTime <= 0.0f) {
NextPath();
return;
}
velocity = (vel_to_pos * (1 / flTravelTime));
think = NextPath;
nextthink = (ltime + flTravelTime);
SetVelocity(vel_to_pos * (1 / flTravelTime));
ScheduleThink(NextPath, flTravelTime);
}
void
@ -181,7 +179,7 @@ func_guntarget::NextPath(void)
}
target = node.target;
velocity = [0,0,0];
ClearVelocity();
if (target) {
Move();
@ -211,7 +209,7 @@ func_guntarget::Death(void)
void
func_guntarget::Start(void)
{
takedamage = DAMAGE_YES;
SetTakedamage(DAMAGE_YES);
NextPath();
m_iValue = 0;
}
@ -219,10 +217,9 @@ func_guntarget::Start(void)
void
func_guntarget::Stop(void)
{
takedamage = DAMAGE_NO;
velocity = [0,0,0];
nextthink = 0;
think = __NULL__;
SetTakedamage(DAMAGE_NO);
ClearVelocity();
ReleaseThink();
m_iValue = 1;
}

View File

@ -191,8 +191,7 @@ func_healthcharger::OnPlayerUse(void)
/* Reset 30 seconds after first being used successfully */
//if (health == max_health) {
think = ResetHealth;
nextthink = time + 60.0f;
ScheduleThink(ResetHealth, 60.0f);
//}
health -= 1;

View File

@ -77,6 +77,8 @@ void
func_physbox::Death(void)
{
Hide();
SetSolid(SOLID_NOT);
SetTakedamage(DAMAGE_NO);
}
void

View File

@ -120,21 +120,20 @@ func_plat::Respawn(void)
ClearAngles();
m_iState = PLATSTATE_RAISED;
think = __NULL__;
nextthink = 0.0f;
ReleaseThink();
}
void
func_plat::ArrivedUp(void)
{
velocity = [0,0,0];
ClearVelocity();
m_iState = PLATSTATE_RAISED;
}
void
func_plat::ArrivedDown(void)
{
velocity = [0,0,0];
ClearVelocity();
m_iState = PLATSTATE_LOWERED;
}
@ -148,16 +147,16 @@ func_plat::Move(vector vecDest, void() vFunc)
vecDifference = (vecDest - origin);
flTravel = vlen(vecDifference);
fTravelTime = (flTravel / m_flSpeed);
think = vFunc;
SetThink(vFunc);
if (fTravelTime < 0.1) {
velocity = [0,0,0];
nextthink = ltime + 0.1f;
ClearVelocity();
SetNextThink(0.1f);
return;
}
velocity = (vecDifference * (1.0f / fTravelTime));
nextthink = (ltime + fTravelTime);
SetVelocity(vecDifference * (1.0f / fTravelTime));
SetNextThink(fTravelTime);
}
void

View File

@ -152,14 +152,13 @@ func_platrot::Respawn(void)
SetAngles(GetSpawnAngles());
m_iState = PLATSTATE_RAISED;
think = __NULL__;
nextthink = 0.0f;
ReleaseThink();
}
void
func_platrot::ArrivedUp(void)
{
avelocity = velocity = [0,0,0];
ClearVelocity();
m_iState = PLATSTATE_RAISED;
sound(this, CHAN_VOICE, "common/null.wav", 1.0f, ATTN_NORM);
@ -171,7 +170,7 @@ func_platrot::ArrivedUp(void)
void
func_platrot::ArrivedDown(void)
{
avelocity = velocity = [0,0,0];
ClearVelocity();
m_iState = PLATSTATE_LOWERED;
sound(this, CHAN_VOICE, "common/null.wav", 1.0f, ATTN_NORM);
@ -191,17 +190,18 @@ func_platrot::Move(vector vecDest, vector vecADest, void() vFunc)
vecADifference = vecADest - angles;
flTravel = vlen(vecDifference);
fTravelTime = (flTravel / m_flSpeed);
think = vFunc;
SetThink(vFunc);
if (fTravelTime < 0.1) {
velocity = [0,0,0];
nextthink = ltime + 0.1f;
ClearVelocity();
SetNextThink(0.1f);
return;
}
avelocity = (vecADifference * (1.0f / fTravelTime));
velocity = (vecDifference * (1.0f / fTravelTime));
nextthink = (ltime + fTravelTime);
SetAngularVelocity(vecADifference * (1.0f / fTravelTime));
SetVelocity(vecDifference * (1.0f / fTravelTime));
SetNextThink(ltime + fTravelTime);
if (m_strNoise1)
sound(this, CHAN_VOICE, m_strNoise1, 1.0f, ATTN_NORM);

View File

@ -201,8 +201,7 @@ func_recharge::OnPlayerUse(void)
/* Reset 30 seconds after first being used successfully */
//if (health == max_health) {
think = ResetHealth;
nextthink = time + 30.0f;
ScheduleThink(ResetHealth, 30.0f);
//}
health -= 1;

View File

@ -61,11 +61,10 @@ enum
};
class
func_rot_button:NSRenderableEntity
func_rot_button:NSSurfacePropEntity
{
vector m_vecMoveAngle;
int m_iState;
int m_iHealth;
float m_flSpeed;
float m_flDistance;
@ -94,7 +93,6 @@ func_rot_button::func_rot_button(void)
{
m_vecMoveAngle = [0.0f, 0.0f, 0.0f];
m_iState = 0i;
m_iHealth = 0i;
m_flSpeed = 0.0f;
m_flDistance = 0.0f;
m_flReturnTime = 0.0f;
@ -106,7 +104,6 @@ func_rot_button::Save(float handle)
super::Save(handle);
SaveVector(handle, "m_vecMoveAngle", m_vecMoveAngle);
SaveInt(handle, "m_iState", m_iState);
SaveInt(handle, "m_iHealth", m_iHealth);
SaveFloat(handle, "m_flSpeed", m_flSpeed);
SaveFloat(handle, "m_flDistance", m_flDistance);
SaveFloat(handle, "m_flReturnTime", m_flReturnTime);
@ -122,9 +119,6 @@ func_rot_button::Restore(string strKey, string strValue)
case "m_iState":
m_iState = ReadInt(strValue);
break;
case "m_iHealth":
m_iHealth = ReadInt(strValue);
break;
case "m_flSpeed":
m_flSpeed = ReadFloat(strValue);
break;
@ -152,9 +146,6 @@ func_rot_button::SpawnKey(string strKey, string strValue)
case "wait":
m_flReturnTime = stof(strValue);
break;
case "health":
m_iHealth = stoi(strValue);
break;
default:
super::SpawnKey(strKey, strValue);
}
@ -173,16 +164,15 @@ func_rot_button::Respawn(void)
SetModel(GetSpawnModel());
SetOrigin(GetSpawnOrigin());
SetAngles(GetSpawnAngles());
AddFlags(FL_FINDABLE_NONSOLID);
PlayerUse = OnPlayerUse;
flags |= FL_FINDABLE_NONSOLID;
m_iState = ROTBTNSTATE_OPENED;
think = __NULL__;
nextthink = 0.0f;
ReleaseThink();
if (m_iHealth > 0) {
takedamage = DAMAGE_YES;
health = m_iHealth;
if (GetSpawnHealth() > 0) {
SetTakedamage(DAMAGE_YES);
SetHealth(GetSpawnHealth());
}
vector vecMoveDir;
@ -210,20 +200,22 @@ func_rot_button::TriggerTargets(void)
void
func_rot_button::ArrivedClosed(void)
{
avelocity = [0,0,0];
ClearVelocity();
ReleaseThink();
m_iState = ROTBTNSTATE_CLOSED;
TriggerTargets();
if (m_flReturnTime > 0.0f) {
think = TurnToggle;
nextthink = ltime + m_flReturnTime;
ScheduleThink(TurnToggle, m_flReturnTime);
}
}
void
func_rot_button::ArrivedOpened(void)
{
avelocity = [0,0,0];
ClearVelocity();
ReleaseThink();
m_iState = ROTBTNSTATE_OPENED;
}
@ -236,10 +228,9 @@ func_rot_button::Rotate(vector vecDest, void(void) vFunc)
vecAngleDifference = (vecDest - angles);
flTravelLength = vlen(vecAngleDifference);
flTravelTime = (flTravelLength / m_flSpeed);
avelocity = (vecAngleDifference * (1 / flTravelTime));
think = vFunc;
nextthink = (ltime + flTravelTime);
SetAngularVelocity(vecAngleDifference * (1 / flTravelTime));
ScheduleThink(vFunc, flTravelTime);
}
void
@ -274,6 +265,6 @@ func_rot_button::TurnToggle(void)
void
func_rot_button::Death(void)
{
takedamage = DAMAGE_NO;
SetTakedamage(DAMAGE_NO);
TurnToggle();
}

View File

@ -162,9 +162,8 @@ func_rotating::Respawn(void)
ClearAngles();
if (HasSpawnFlags(FR_STARTON)) {
avelocity = m_vecMoveDir * m_flSpeed;
think = Rotate;
nextthink = ltime + 1.5f;
SetAngularVelocity(m_vecMoveDir * m_flSpeed);
ScheduleThink(Rotate, 1.5f);
}
}
@ -173,9 +172,8 @@ void
func_rotating::Trigger(entity act, int state)
{
if (vlen(avelocity) > 0) {
avelocity = [0,0,0];
think = __NULL__;
nextthink = 0.0f;
ClearVelocity();
ReleaseThink();
} else {
float flSpeed;
@ -185,19 +183,18 @@ func_rotating::Trigger(entity act, int state)
flSpeed = m_flSpeed;
}
avelocity = m_vecMoveDir * flSpeed;
SetAngularVelocity(m_vecMoveDir * flSpeed);
m_flDir = 1 - m_flDir;
/* HACK HACK HACK! This is terrible */
think = Rotate;
nextthink = ltime + 99999.0f;
/* HACK HACK HACK! This is terrible, but the only way PUSH movetypes rotate */
ScheduleThink(Rotate, 99999.0f);
}
}
void
func_rotating::Rotate(void)
{
nextthink = ltime + 10.0f;
SetNextThink(10.0f);
}
void
@ -210,13 +207,8 @@ func_rotating::Blocked(entity eBlocker)
if (other.takedamage == DAMAGE_YES) {
/* this is to work around a Q1 BSP bug. don't attempt to damage our
* target unless we're absolutely sure he's within the bounds of the entity */
if not (other.absmin[0] >= absmin[0] && other.absmax[0] <= absmax[0])
return;
if not (other.absmin[1] >= absmin[1] && other.absmax[1] <= absmax[1])
return;
if not (other.absmin[2] >= absmin[2] && other.absmax[2] <= absmax[2])
return;
Damage_Apply(other, this, m_flDamage, 0, DMG_CRUSH);
if (WithinBounds(other))
Damage_Apply(other, this, m_flDamage, 0, DMG_CRUSH);
}
}

View File

@ -188,9 +188,8 @@ func_tracktrain::Respawn(void)
/* let's wait 1/4 a second to give the path_corner entities a chance to
* spawn in case they're after us in the ent lump */
target = m_oldstrTarget;
think = AfterSpawn;
nextthink = ltime + 0.25f;
ScheduleThink(AfterSpawn, 0.25f);
SetTriggerTarget(m_oldstrTarget);
}
void
@ -250,14 +249,13 @@ func_tracktrain::PathMove(void)
if (!flTravelTime) {
print("^1func_tracktrain::^3PathMove^7: Distance short, going next\n");
think = PathNext;
nextthink = ltime;
ScheduleThink(PathNext, 0.0f);
return;
}
SoundMove();
velocity = (vecVelocity * (1 / flTravelTime));
SetVelocity(vecVelocity * (1 / flTravelTime));
vector vecAngleDest;
vector vecDiff;
@ -284,15 +282,14 @@ func_tracktrain::PathMove(void)
//print(sprintf("vecAngleDiff: %v\n", vecAngleDiff));
if (vecAngleDiff[1] == 0)
angles = vecAngleDest;
SetAngles(vecAngleDest);
else
avelocity = (vecAngleDiff * (1 / flTravelTime));
SetAngularVelocity(vecAngleDiff * (1 / flTravelTime));
if (!eNode)
avelocity = [0,0,0];
SetAngularVelocity([0,0,0]);
think = PathNext;
nextthink = (ltime + flTravelTime);
ScheduleThink(PathNext, flTravelTime);
}
void
@ -302,7 +299,7 @@ func_tracktrain::PathDone(void)
eNode = (path_corner)find(world, ::targetname, target);
/* stop */
avelocity = [0,0,0];
ClearVelocity();
if (!eNode) {
return;
@ -334,7 +331,7 @@ func_tracktrain::PathNext(void)
m_flWait = eNode.m_flWait;
target = eNode.target;
velocity = [0,0,0];
ClearVelocity();
/* warp */
if (eNode.HasSpawnFlags(PC_TELEPORT)) {
@ -347,13 +344,7 @@ func_tracktrain::PathNext(void)
return;
}
/* move after delay, or instantly when none is given */
/*if (m_flWait > 0) {
think = PathMove;
nextthink = ltime + m_flWait;
} else */ {
PathMove();
}
PathMove();
}
/* TODO: Handle state? */

View File

@ -172,9 +172,8 @@ func_train::Respawn(void)
/* let's wait 1/4 a second to give the path_corner entities a chance to
* spawn in case they're after us in the ent lump */
target = m_oldstrTarget;
think = AfterSpawn;
nextthink = ltime + 0.25f;
SetTriggerTarget(m_oldstrTarget);
ScheduleThink(AfterSpawn, 0.25f);
}
void
@ -228,22 +227,20 @@ func_train::PathMove(void)
}
vecWorldPos = WorldSpaceCenter();
vecVelocity = (eNode.origin - vecWorldPos);
flTravelTime = (vlen(vecVelocity) / m_flSpeed);
if (!flTravelTime) {
print("^1func_train::^3PathMove^7: Distance short, going next\n");
think = PathNext;
nextthink = ltime;
ClearVelocity();
ScheduleThink(PathNext, 0.0f);
return;
}
SoundMove();
velocity = (vecVelocity * (1 / flTravelTime));
think = PathNext;
nextthink = (ltime + flTravelTime);
SetVelocity(vecVelocity * (1 / flTravelTime));
ScheduleThink(PathNext, flTravelTime);
}
void
@ -281,8 +278,8 @@ func_train::PathNext(void)
m_flSpeed = eNode.m_flSpeed;
m_flWait = eNode.m_flWait;
target = eNode.target;
velocity = [0,0,0];
SetTriggerTarget(eNode.target);
ClearVelocity();
/* warp */
if (eNode.HasSpawnFlags(PC_TELEPORT)) {
@ -297,8 +294,7 @@ func_train::PathNext(void)
/* move after delay, or instantly when none is given */
if (m_flWait > 0) {
think = PathMove;
nextthink = ltime + m_flWait;
ScheduleThink(PathMove, m_flWait);
} else {
PathMove();
}
@ -316,7 +312,8 @@ func_train::AfterSpawn(void)
{
PathNext();
if (!targetname) {
/* if we're unable to be triggered by anything, begin moving */
if (HasTargetname() == false) {
PathMove();
}
}

View File

@ -497,14 +497,14 @@ func_vehicle::Respawn(void)
SetModel(GetSpawnModel());
SetOrigin(GetSpawnOrigin());
SetAngles(GetSpawnAngles());
think = Realign;
nextthink = time + 0.1f;
ScheduleThink(Realign, 0.0f);
m_wlFL.velocity =
m_wlFR.velocity =
m_wlBL.velocity =
m_wlBR.velocity =
velocity = [0,0,0];
m_wlBR.velocity = [0.0f, 0.0f, 0.0f];
ClearVelocity();
PlayerUse = OnPlayerUse;
if (m_eDriver)
@ -613,7 +613,7 @@ func_vehicle::customphysics(void)
new_origin += m_wlBL.origin;
new_origin += m_wlBR.origin;
new_origin *= 0.25f;
setorigin(this, new_origin);
SetOrigin(new_origin);
PlayerAlign();
/* support for think/nextthink */

View File

@ -69,7 +69,6 @@ info_null::WarnDeveloper(void)
void
info_null::Respawn(void)
{
nextthink = time + 0.1f;
think = WarnDeveloper;
ScheduleThink(WarnDeveloper, 0.0f);
}
#endif

View File

@ -78,8 +78,7 @@ item_food::Spawned(void)
}
SetSize([0,0,0], [0,0,0]);
think = Setup;
nextthink = time + 1.0f;
ScheduleThink(Setup, 1.0f);
}
void

View File

@ -136,11 +136,9 @@ logic_auto::Restore(string strKey, string strValue)
void
logic_auto::RestoreComplete(void)
{
think = Processing;
nextthink = time + 0.2f;
ScheduleThink(Processing, 0.2f);
}
void
logic_auto::SpawnKey(string strKey, string strValue)
{
@ -196,8 +194,7 @@ logic_auto::Spawned(void)
void
logic_auto::Respawn(void)
{
think = Processing;
nextthink = time + 0.2f;
ScheduleThink(Processing, 0.2f);
}
void
@ -232,7 +229,7 @@ logic_auto::Processing(void)
UseOutput(this, m_strOnBackgroundMap);
if (HasSpawnFlags(1)) {
NSLog("^2logic_auto::^3think^7: %s triggerer removed self", target);
NSLog("^2logic_auto::^3Processing ^7: %s triggerer removed self", target);
remove(this);
}
}

View File

@ -67,6 +67,7 @@ momentary_door::Respawn(void)
RestoreAngles();
SetMovementDirection();
ClearAngles();
ClearVelocity();
SetMovetype(MOVETYPE_PUSH);
SetSolid(SOLID_BSP);
@ -87,7 +88,8 @@ momentary_door::GetProgress(void)
void
momentary_door::MovementDone(void)
{
m_vecDest = velocity = [0,0,0];
m_vecDest = [0,0,0];
ClearVelocity();
}
void
@ -122,9 +124,8 @@ momentary_door::MovementStateChanged(void)
return;
}
think = MovementDone;
nextthink = (ltime + flTravelTime);
velocity = (vecDifference * (1.0f / flTravelTime));
ScheduleThink(MovementDone, flTravelTime);
SetVelocity(vecDifference * (1.0f / flTravelTime));
}
void

View File

@ -183,13 +183,12 @@ momentary_rot_button::MovementStateChanged(void)
/* Avoid NAN hack */
if (flTravelTime <= 0.0f) {
angles = m_vecDest;
SetAngles(m_vecDest);
MovementDone();
nextthink = 0.0f;
ReleaseThink();
} else {
avelocity = (vecAngleDifference * (1 / flTravelTime));
think = MovementDone;
nextthink = (ltime + flTravelTime);
SetAngularVelocity(vecAngleDifference * (1 / flTravelTime));
ScheduleThink(MovementDone, flTravelTime);
}
}

View File

@ -158,16 +158,14 @@ monstermaker::Respawn(void)
void
monstermaker::TurnOff(void)
{
think = __NULL__;
nextthink = 0;
ReleaseThink();
m_iValue = 0;
}
void
monstermaker::TurnOn(void)
{
think = Spawner;
nextthink = time + m_flDelay;
ScheduleThink(Spawner, m_flDelay);
m_iValue = 1;
}
@ -210,14 +208,14 @@ monstermaker::Spawner(void)
/* too many alive at a time */
if ((m_iMaxChildren > 0 && c >= m_iMaxChildren) || (m_flDelay <= 0 && c >= 1)) {
nextthink = time + m_flDelay;
ScheduleThink(Spawner, m_flDelay);
return;
}
tracebox(origin, [-16,-16,-16], [16,16,16], origin, FALSE, this);
if (trace_startsolid == TRUE) {
nextthink = time + m_flDelay;
ScheduleThink(Spawner, m_flDelay);
return;
}
@ -249,7 +247,7 @@ monstermaker::Spawner(void)
/* shut off for good when we've spawned all we ever wanted */
if ((m_iTotalMonsters > 0) && m_iMonsterSpawned >= m_iTotalMonsters) {
think = __NULL__;
ReleaseThink();
return;
}
@ -257,7 +255,7 @@ monstermaker::Spawner(void)
if (HasSpawnFlags(MMF_NONTOGGLE)) {
TurnOff();
} else {
nextthink = time + m_flDelay;
ScheduleThink(Spawner, m_flDelay);
}
}

View File

@ -262,7 +262,7 @@ multi_manager::Spawned(void)
if ((!HasSpawnFlags(MM_MULTITHREADED) && targetname == argv(i)))
continue;
m_eTriggers[b].target = argv(i);
m_eTriggers[b].SetTriggerTarget(argv(i));
m_eTriggers[b].m_oldstrTarget = argv(i);
m_eTriggers[b].m_flUntilTriggered = stof(argv(i+1));
b++;
@ -303,7 +303,7 @@ multi_manager::Trigger(entity act, int state)
/* If not multi-threaded, we have to watch out 'til all triggers are done. */
if (!HasSpawnFlags(MM_MULTITHREADED)) {
for (int i = 0; i < 16; i++) {
if (m_eTriggers[i].nextthink > time) {
if (m_eTriggers[i].IsThinking() == true) {
return;
}
}
@ -311,12 +311,11 @@ multi_manager::Trigger(entity act, int state)
/* time to trigger our sub triggers */
for (int i = 0; i < 16; i++) {
if (!m_eTriggers[i].target)
if (m_eTriggers[i].HasTriggerTarget() == false)
continue;
m_eTriggers[i].think = mm_enttrigger;
m_eTriggers[i].ScheduleThink(mm_enttrigger, m_eTriggers[i].m_flUntilTriggered);
m_eTriggers[i].m_iValue = FALSE;
m_eTriggers[i].nextthink = time + m_eTriggers[i].m_flUntilTriggered;
m_eTriggers[i].m_eActivator = act;
}
}

View File

@ -123,19 +123,16 @@ player_loadsaved::Trigger(entity act, int unused)
{
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
WriteByte(MSG_MULTICAST, EV_FADE);
WriteFloat(MSG_MULTICAST, m_vecRenderColor[0]);
WriteFloat(MSG_MULTICAST, m_vecRenderColor[1]);
WriteFloat(MSG_MULTICAST, m_vecRenderColor[2]);
WriteFloat(MSG_MULTICAST, m_flRenderAmt);
WriteFloat(MSG_MULTICAST, m_flFadeDuration);
WriteFloat(MSG_MULTICAST, m_flFadeHold);
WriteByte(MSG_MULTICAST, 0);
msg_entity = world;
multicast([0,0,0], MULTICAST_ALL);
env_message_single(act, m_strMessage);
think = ReloadSave;
nextthink = time + m_flLoadTime;
env_message_single(act, m_strMessage);
ScheduleThink(ReloadSave, m_flLoadTime);
}

View File

@ -124,24 +124,25 @@ prop_door_rotating::Turn(vector vecDest, void(void) vFunc)
vecAngleDifference = (vecDest - angles);
flTravelLength = vlen(vecAngleDifference);
flTravelTime = (flTravelLength / m_flSpeed);
avelocity = (vecAngleDifference * (1 / flTravelTime));
think = vFunc;
nextthink = (ltime + flTravelTime);
SetAngularVelocity(vecAngleDifference * (1 / flTravelTime));
ScheduleThink(vFunc, flTravelTime);
}
void
prop_door_rotating::Closed(void)
{
avelocity = [0,0,0];
angles = m_vecDest1;
ClearVelocity();
ReleaseThink();
SetAngles(m_vecDest1);
PlayerUse = Interact;
}
void
prop_door_rotating::Opened(void)
{
avelocity = [0,0,0];
angles = m_vecDest2;
ClearVelocity();
ReleaseThink();
SetAngles(m_vecDest2);
PlayerUse = Interact;
}
@ -156,15 +157,14 @@ prop_door_rotating::Interact(void)
}
m_iValue = 1 - m_iValue;
frame = 1;
frame1time = 0.0f;
SetFrame(1);
SetSendFlags(BASEFL_CHANGED_FRAME);
if (m_iValue)
think = TurnAway;
ScheduleThink(TurnAway, 0.25f);
else
think = TurnBack;
ScheduleThink(TurnBack, 0.25f);
nextthink = ltime + 0.25f;
PlayerUse = __NULL__;
}

View File

@ -165,15 +165,14 @@ random_speaker::Enable(void)
m_iValue = 1;
/* at least wait this amount */
r = time + m_flMinPos;
r = m_flMinPos;
/* then take the specified percentage of 'wait', by random and add it */
r += (m_flMinPos * (m_flRandPercent / 100)) * random();
think = PlaySample;
nextthink = r;
ScheduleThink(PlaySample, r);
print("^2random_speaker::^3Disable^7: " \
NSLog("^2random_speaker::^3Disable^7: " \
"%s playing %s in %d\n", \
targetname, m_strSample, r);
}
@ -181,11 +180,10 @@ random_speaker::Enable(void)
void
random_speaker::Disable(void)
{
dprint("^2random_speaker::^3Disable^7: " \
NSLog("^2random_speaker::^3Disable^7: " \
"Disabled %s playing %s\n", \
targetname, m_strSample);
m_iValue = 0;
think = __NULL__;
nextthink = 0;
ReleaseThink();
}

View File

@ -210,8 +210,7 @@ scripted_sequence::Respawn(void)
}
if (m_strIdleAnim) {
think = InitIdle;
nextthink = time + 0.1f;
ScheduleThink(InitIdle, 0.0f);
}
}
@ -287,7 +286,7 @@ scripted_sequence::RunOnEntity(entity targ)
/* all the non-moving targets will do this at least */
if (m_strActionAnim) {
duration = frameduration(f.modelindex, f.m_flSequenceEnd);
f.nextthink = time + duration;
f.SetNextThink(duration);
NSLog(
"\tAnimation: %s Duration: %f seconds (modelindex %d, frame %d)",
m_strActionAnim,
@ -296,7 +295,7 @@ scripted_sequence::RunOnEntity(entity targ)
f.m_flSequenceEnd
);
} else {
f.nextthink = time;
f.SetNextThink(0.0f);
NSLog(
"\t^1WARNING: %s skipping animation on script type %i",
f.targetname,
@ -307,11 +306,11 @@ scripted_sequence::RunOnEntity(entity targ)
f.m_iSequenceState = SEQUENCESTATE_ENDING;
if (HasSpawnFlags(SSFL_NOSCRIPTMOVE))
f.think = NSMonster::FreeState;
f.SetThink(NSMonster::FreeState);
else
f.think = NSMonster::FreeStateMoved;
f.SetThink(NSMonster::FreeStateMoved);
NSLog("\tEnding: %f", f.nextthink);
NSLog("\tEnding: %f", f.GetNextThinkTime());
/* make sure we're forgetting about enemies and attack states in sequence */
f.m_eEnemy = __NULL__;

View File

@ -79,7 +79,7 @@ speaker:NSTalkMonster
virtual void(void) Respawn;
virtual void(entity, int) Trigger;
virtual void(void) Annouce;
virtual void(void) Announce;
};
void
@ -143,14 +143,12 @@ speaker::Respawn(void)
SetRenderMode(RM_COLOR);
SetRenderAmt(0);
think = Annouce;
if (!HasSpawnFlags(SPEAKFL_SILENT))
nextthink = time + 10.0f;
if (HasSpawnFlags(SPEAKFL_SILENT) == false)
ScheduleThink(Announce, 10.0f);
}
void
speaker::Annouce(void)
speaker::Announce(void)
{
string seq = Sentences_GetSamples(m_strSentence);
@ -165,11 +163,12 @@ speaker::Annouce(void)
msg_entity = this;
multicast(origin, MULTICAST_PVS);
nextthink = time + random(30,60);
/* ...onto the next announcement */
ScheduleThink(Announce, random(30.0f, 60.0f));
}
void
speaker::Trigger(entity eAct, int foo)
{
nextthink = time;
ScheduleThink(Announce, 0.0f);
}

View File

@ -56,7 +56,6 @@ trigger_auto::trigger_auto(void)
{
/* default is always toggle */
m_iTriggerState = TRIG_TOGGLE;
m_strGlobalState = __NULL__;
m_flDelay = 0.0f;
}
@ -86,8 +85,7 @@ trigger_auto::Restore(string strKey, string strValue)
void
trigger_auto::RestoreComplete(void)
{
think = Processing;
nextthink = time + 0.2f;
ScheduleThink(Processing, 0.25f);
}
void
@ -110,8 +108,8 @@ trigger_auto::Respawn(void)
{
InitPointTrigger();
think = Processing;
nextthink = time + 0.2f;
/* deliberately add a bit more time in case we're first in the ent-lump */
ScheduleThink(Processing, 0.25f);
}
void
@ -125,7 +123,7 @@ trigger_auto::Processing(void)
print(sprintf("%S %i %f\n", target, m_iTriggerState, m_flDelay));
if (HasSpawnFlags(1)) {
NSLog("^2trigger_auto::^3think^7: %s triggerer removed self", target);
NSLog("^2trigger_auto::^3Processing^7: %s triggerer removed self", target);
remove(this);
}
}

View File

@ -101,8 +101,6 @@ trigger_autosave::Touch(entity eToucher)
eToucher.netname);
localcmd("save autosave\n");
Hide();
SetSolid(SOLID_NOT);
UseTargets(eToucher, TRIG_TOGGLE, m_flDelay);

View File

@ -50,6 +50,8 @@ enumflags
void
ChangeTarget_Activate(void)
{
NSTimer foo = __NULL__;
static void Finalize(void) {
string ctarg = cvar_string("_bsp_changetarget");
if (ctarg) {
@ -64,10 +66,7 @@ ChangeTarget_Activate(void)
readcmd("set _bsp_changedelay \"\"\n");
}
entity foo = spawn();
float cdel = cvar("_bsp_changedelay");
foo.think = Finalize;
foo.nextthink = time + 0.1f + cdel;
foo.TemporaryTimer(self, Finalize, cvar("_bsp_changedelay"), false);
}
class

View File

@ -169,15 +169,14 @@ trigger_multiple::Touch(entity eToucher)
}
/* if the target key isn't used, assume we're using the new I/O system */
if (!target)
if (HasTriggerTarget() == false)
UseOutput(eToucher, m_strOnStartTouch);
else
UseTargets(eToucher, TRIG_TOGGLE, m_flDelay);
/* This is effectively a trigger_once...*/
if (m_flWait != -1) {
think = Respawn;
nextthink = time + m_flWait;
ScheduleThink(Respawn, m_flWait);
}
SetSolid(SOLID_NOT);

View File

@ -150,7 +150,7 @@ trigger_push::Touch(entity eToucher)
if (eToucher.velocity[2] > 0) {
eToucher.flags &= ~FL_ONGROUND;
}
Hide();
SetSolid(SOLID_NOT);
} else {
eToucher.basevelocity += vecPush;
}

View File

@ -136,6 +136,9 @@ class NSEntity:NSTrigger
virtual void(vector, vector) SetSize;
virtual void(float) AddFlags;
virtual void(float) RemoveFlags;
virtual void(void()) SetThink;
virtual void(float) SetNextThink;
virtual void(void(void), float) ScheduleThink;
/* gets */
nonvirtual vector(void) GetSpawnOrigin;
@ -163,6 +166,10 @@ class NSEntity:NSTrigger
nonvirtual vector(void) GetAbsoluteMins;
nonvirtual vector(void) GetAbsoluteMaxs;
nonvirtual float(void) GetFlags;
nonvirtual float(void) GetNextThinkTime;
nonvirtual bool(void) IsThinking;
nonvirtual void(void) ReleaseThink;
nonvirtual void(void) ClearVelocity;
virtual void(void) Show;
virtual void(void) Hide;
@ -186,6 +193,7 @@ class NSEntity:NSTrigger
nonvirtual bool(void) IsOnGround;
nonvirtual entity(void) GetGroundEntity;
nonvirtual bool(void) CreatedByMap;
nonvirtual bool(entity) WithinBounds;
virtual void(entity) Blocked;
virtual void(entity) StartTouch;

View File

@ -677,6 +677,42 @@ NSEntity::RemoveFlags(float fl)
flags &= ~fl;
}
void
NSEntity::SetThink(void(void) func)
{
think = func;
}
/* FIXME: Why do we need to declare this?! */
#ifdef CSQC
noref .float ltime;
#endif
void
NSEntity::SetNextThink(float fl)
{
float flTime;
/* thinks work differently for pushmovables */
flTime = (movetype == MOVETYPE_PUSH) ? ltime : time;
/* HACK: to make sure things happen post-spawn */
if (flTime <= 0.0f)
flTime = 0.1f;
if (fl >= 0)
nextthink = flTime + fl;
else
NSLog("%s sets bogus nextthink value %f\n", classname, fl);
}
void
NSEntity::ScheduleThink(void(void) func, float fl)
{
SetThink(func);
SetNextThink(fl);
}
vector
NSEntity::GetSpawnOrigin(void)
{
@ -821,6 +857,34 @@ NSEntity::GetFlags(void)
return flags;
}
float
NSEntity::GetNextThinkTime(void)
{
return nextthink;
}
bool
NSEntity::IsThinking(void)
{
if (movetype == MOVETYPE_PUSH)
return (nextthink > ltime) ? true : false;
else
return (nextthink > time) ? true : false;
}
void
NSEntity::ReleaseThink(void)
{
think = __NULL__;
nextthink = 0.0f;
}
void
NSEntity::ClearVelocity(void)
{
velocity = avelocity = [0.0f, 0.0f, 0.0f];
}
#ifdef SERVER
void
NSEntity::Respawn(void)
@ -1058,3 +1122,16 @@ NSEntity::MakeStatic(void)
{
makestatic(this);
}
bool
NSEntity::WithinBounds(entity check)
{
if not (check.absmin[0] >= absmin[0] && check.absmax[0] <= absmax[0])
return false;
if not (check.absmin[1] >= absmin[1] && check.absmax[1] <= absmax[1])
return false;
if not (check.absmin[2] >= absmin[2] && check.absmax[2] <= absmax[2])
return false;
return true;
}

View File

@ -50,11 +50,15 @@ class NSTrigger:NSIO
float m_flDelay;
virtual void(entity, int) Trigger;
virtual void(entity, int, float) UseTargets;
virtual void(string) SetTriggerTarget;
/* master feature */
nonvirtual int(void) GetValue;
nonvirtual int(void) GetMaster;
nonvirtual globalstate_t(string) GetGlobalValue;
nonvirtual string(void) GetTriggerTarget;
nonvirtual bool(void) HasTriggerTarget;
nonvirtual bool(void) HasTargetname;
/* overrides */
virtual void(float) Save;

View File

@ -87,6 +87,12 @@ NSTrigger::UseTargets(entity act, int state, float fDelay)
}
}
void
NSTrigger::SetTriggerTarget(string name)
{
target = name;
}
int
NSTrigger::GetValue(void)
{
@ -135,6 +141,30 @@ NSTrigger::GetMaster(void)
return t.GetValue();
}
string
NSTrigger::GetTriggerTarget(void)
{
return target;
}
bool
NSTrigger::HasTriggerTarget(void)
{
if not (target)
return false;
return true;
}
bool
NSTrigger::HasTargetname(void)
{
if not (targetname)
return false;
return true;
}
void
NSTrigger::Save(float handle)
{