Big overhaul of momentary_door, momentary_rot_button... now onto the last

entity until Hazard Course is fully functional from beginning to end.
This commit is contained in:
Marco Cawthorne 2022-01-04 21:54:42 -08:00
parent 08e112e128
commit 9d4d7afdcd
Signed by: eukara
GPG key ID: C196CD8BA993248A
9 changed files with 238 additions and 92 deletions

View file

@ -27,6 +27,19 @@ UseWorkaround(entity eTarget)
self = eTarget;
self.PlayerUse();
self = eOldSelf;
print("pressed\n");
}
void
UnUseWorkaround(entity eTarget)
{
eActivator = self;
entity eOldSelf = self;
self = eTarget;
if (self.PlayerUseUnpressed)
self.PlayerUseUnpressed();
self = eOldSelf;
print("unpressed\n");
}
/*
@ -38,6 +51,7 @@ void
Player_UseDown(void)
{
vector vecSrc;
player pl = (player)self;
if (self.health <= 0) {
return;
@ -58,6 +72,7 @@ Player_UseDown(void)
self.flags &= ~FL_USE_RELEASED;
UseWorkaround(trace_ent);
pl.last_used = trace_ent;
/* Some entities want to support Use spamming */
if (!(self.flags & FL_USE_RELEASED)) {
@ -76,7 +91,10 @@ Player_UseUp
*/
void
Player_UseUp(void) {
player pl = (player)self;
if (!(self.flags & FL_USE_RELEASED)) {
UnUseWorkaround(pl.last_used);
pl.last_used = world;
self.flags |= FL_USE_RELEASED;
}
}

View file

@ -144,8 +144,8 @@ func_mortar_field::FireControlled(void)
vecPos[2] = absmin[2] + (0.5f * (absmax[2] - absmin[2]));
/* now offset the position to the rot_buttons */
vecPos[0] += mins[0] + (mX.m_flProgress * size[0]);
vecPos[1] += mins[1] + (mY.m_flProgress * size[1]);
vecPos[0] += mins[0] + (mX.GetProgress() * size[0]);
vecPos[1] += mins[1] + (mY.GetProgress() * size[1]);
for (int i = 0; i < m_iCount; i++);
Fire(vecPos);
@ -186,7 +186,7 @@ func_mortar_field::SpawnKey(string strKey, string strValue)
case "m_iszYController":
m_strYController = strValue;
break;
case "m_flControl":
case "m_fControl":
m_iType = stoi(strValue);
break;
case "m_flCount":

View file

@ -28,54 +28,63 @@ class momentary_door:CBaseMomentary
{
void(void) momentary_door;
virtual void(void) customphysics;
virtual void(void) Respawn;
virtual void(void) SetMovementDirection;
virtual void(string, string) SpawnKey;
virtual void(void) MovementDone;
virtual void(void) MovementStateChanged;
virtual float(void) GetProgress;
};
void
momentary_door::customphysics(void)
float
momentary_door::GetProgress(void)
{
entity e = find(world, ::targetname, target);
CBaseMomentary bl = (CBaseMomentary)e;
return (vlen(origin) / vlen(m_vecPos2));
}
if (m_eUser != world) {
base_player pl = (base_player)m_eUser;
/* we need to check if the user has changed every frame. */
if (!m_eUser.button5) {
/* clear user */
m_eUser = world;
if (e) {
bl.m_eUser = world;
}
} else {
if (e) {
bl.m_eUser = m_eUser;
}
void
momentary_door::MovementDone(void)
{
m_vecDest = velocity = [0,0,0];
}
m_flProgress += frametime;
if (m_flProgress >= 1.0f)
m_flProgress = 1.0f;
}
} else {
m_flProgress = Math_Lerp(m_flProgress, 0.0f, frametime * 0.5);
void
momentary_door::MovementStateChanged(void)
{
vector vecDifference;
float flTravelLength;
float flTravelTime;
float flSpeed;
switch (m_iMoveState) {
case MOMENTARY_IDLE:
MovementDone();
return;
break;
case MOMENTARY_ROTATING:
m_vecDest = m_vecPos2;
flSpeed = m_flSpeed;
break;
case MOMENTARY_RETURNING:
m_vecDest = m_vecPos1;
flSpeed = m_flReturnspeed;
break;
}
origin[0] = Math_Lerp(m_vecPos1[0], m_vecPos2[0], m_flProgress);
origin[1] = Math_Lerp(m_vecPos1[1], m_vecPos2[1], m_flProgress);
origin[2] = Math_Lerp(m_vecPos1[2], m_vecPos2[2], m_flProgress);
setorigin(this, origin);
vecDifference = (m_vecDest - origin);
flTravelLength = vlen(vecDifference);
flTravelTime = (flTravelLength / m_flSpeed);
/* support for think/nextthink */
if (think && nextthink > 0.0f) {
if (nextthink < time) {
nextthink = 0.0f;
think();
}
if (flTravelTime < 0.1) {
MovementDone();
return;
}
think = MovementDone;
nextthink = (ltime + flTravelTime);
velocity = (vecDifference * (1.0f / flTravelTime));
}
void
@ -94,15 +103,15 @@ momentary_door::SetMovementDirection(void)
void
momentary_door::Respawn(void)
{
RestoreAngles();
SetMovementDirection();
ClearAngles();
SetMovetype(MOVETYPE_PUSH);
SetSolid(SOLID_BSP);
SetModel(GetSpawnModel());
SetOrigin(GetSpawnOrigin());
RestoreAngles();
SetMovementDirection();
ClearAngles();
m_vecPos1 = GetSpawnOrigin();
m_vecPos2 = (m_vecPos1 + m_vecMoveDir * (fabs(m_vecMoveDir * size) - m_flDistance));
}

View file

@ -49,64 +49,130 @@ enumflags
class momentary_rot_button:CBaseMomentary
{
int m_iTurnDir;
void(void) momentary_rot_button;
virtual void(void) OnPlayerUse;
virtual void(void) customphysics;
virtual void(void) Respawn;
virtual void(void) SetMovementDirection;
virtual void(string, string) SpawnKey;
virtual void(void) MovementDone;
virtual void(void) MovementStateChanged;
virtual float(void) GetProgress;
};
float
momentary_rot_button::GetProgress(void)
{
return (vlen(angles) / vlen(m_vecPos2));
}
void
momentary_rot_button::MovementDone(void)
{
m_vecDest = avelocity = [0,0,0];
}
void
momentary_rot_button::MovementStateChanged(void)
{
vector vecAngleDifference;
float flTravelLength;
float flTravelTime;
float flSpeed;
switch (m_iMoveState) {
case MOMENTARY_IDLE:
MovementDone();
return;
break;
case MOMENTARY_ROTATING:
m_vecDest = m_vecPos2;
flSpeed = m_flSpeed;
break;
case MOMENTARY_RETURNING:
m_vecDest = m_vecPos1;
flSpeed = m_flReturnspeed;
break;
}
vecAngleDifference = (m_vecDest - angles);
flTravelLength = vlen(vecAngleDifference);
flTravelTime = (flTravelLength / flSpeed);
/* Avoid NAN hack */
if (flTravelTime <= 0.0f) {
angles = m_vecDest;
MovementDone();
nextthink = 0.0f;
} else {
avelocity = (vecAngleDifference * (1 / flTravelTime));
think = MovementDone;
nextthink = (ltime + flTravelTime);
}
}
void
momentary_rot_button::OnPlayerUse(void)
{
if (spawnflags & MRBFL_NOTUSE)
return;
int iEndState;
m_eUser = eActivator;
/* if we're not already rotating (or can only turn 1 way) */
if (m_iTurnDir == 0 || (spawnflags & MRBFL_AUTORETURN))
iEndState = (MOMENTARY_ROTATING); /* always turning one way on auto-return */
else
iEndState = (MOMENTARY_RETURNING);
/* apply the end state */
SetMoveState(iEndState);
m_iTurnDir = 1 - m_iTurnDir;
for (entity e = world; (e = find(e, ::targetname, target));) {
CBaseMomentary b = (CBaseMomentary)e;
b.SetMoveState(iEndState);
}
for (entity e = world; (e = find(e, ::targetname, targetname));) {
CBaseMomentary b = (CBaseMomentary)e;
/* door hack: any entity with the same name as ours will follow our states */
if (b.spawnflags & MRBFL_DOORHACK)
b.SetMoveState(iEndState);
}
}
void
momentary_rot_button::customphysics(void)
momentary_rot_button::OnPlayerUnUse(void)
{
entity e = find(world, ::targetname, target);
CBaseMomentary bl = (CBaseMomentary)e;
int iEndState;
if (m_eUser != world) {
base_player pl = (base_player)m_eUser;
/* we need to check if the user has changed every frame. */
if (!m_eUser.button5) {
/* clear user */
m_eUser = world;
m_eUser = world;
if (e) {
bl.m_eUser = world;
}
} else {
if (e) {
bl.m_eUser = m_eUser;
}
/* instead of stopping, auto-return. */
if (spawnflags & MRBFL_AUTORETURN)
iEndState = (MOMENTARY_RETURNING);
else
iEndState = (MOMENTARY_IDLE);
m_flProgress += frametime;
if (m_flProgress >= 1.0f)
m_flProgress = 1.0f;
}
} else {
m_flProgress = Math_Lerp(m_flProgress, 0.0f, frametime * 0.5);
/* apply the end state */
SetMoveState(iEndState);
for (entity e = world; (e = find(e, ::targetname, target));) {
CBaseMomentary b = (CBaseMomentary)e;
b.SetMoveState(iEndState);
}
angles[0] = Math_Lerp(m_vecPos1[0], m_vecPos2[0], m_flProgress);
angles[1] = Math_Lerp(m_vecPos1[1], m_vecPos2[1], m_flProgress);
angles[2] = Math_Lerp(m_vecPos1[2], m_vecPos2[2], m_flProgress);
/* support for think/nextthink */
if (think && nextthink > 0.0f) {
if (nextthink < time) {
nextthink = 0.0f;
think();
}
for (entity e = world; (e = find(e, ::targetname, targetname));) {
CBaseMomentary b = (CBaseMomentary)e;
/* door hack: any entity with the same name as ours will follow our states */
if (b.spawnflags & MRBFL_DOORHACK)
b.SetMoveState(iEndState);
}
}
@ -125,19 +191,31 @@ momentary_rot_button::SetMovementDirection(void)
void
momentary_rot_button::Respawn(void)
{
SetMovetype(MOVETYPE_PUSH);
SetSolid(SOLID_BSP);
SetModel(GetSpawnModel());
SetOrigin(GetSpawnOrigin());
RestoreAngles();
SetMovementDirection();
ClearAngles();
PlayerUse = OnPlayerUse;
if (m_flSpeed == -1)
m_flSpeed = 100;
if (m_flReturnspeed == -1)
m_flReturnspeed = m_flSpeed;
SetSolid(SOLID_BSP);
SetMovetype(MOVETYPE_PUSH);
SetModel(GetSpawnModel());
SetOrigin(GetSpawnOrigin());
/* purely visual, can't use this */
if (!(spawnflags & MRBFL_NOTUSE)) {
PlayerUse = OnPlayerUse;
PlayerUseUnpressed = OnPlayerUnUse;
}
m_vecPos1 = [0,0,0];
m_vecPos2 = GetSpawnAngles() + m_vecMoveDir * m_flDistance;
m_vecPos2 = m_vecMoveDir * m_flDistance;
SetSkin(0);
SetMoveState(MOMENTARY_IDLE);
}
void
@ -161,5 +239,6 @@ momentary_rot_button::SpawnKey(string strKey, string strValue)
void
momentary_rot_button::momentary_rot_button(void)
{
m_flReturnspeed = m_flSpeed = -1;
super::CBaseMomentary();
}

View file

@ -14,16 +14,25 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
typedef enum
{
MOMENTARY_IDLE,
MOMENTARY_ROTATING,
MOMENTARY_RETURNING
};
class CBaseMomentary:NSRenderableEntity
{
entity m_eUser;
vector m_vecMoveDir;
vector m_vecPos1;
vector m_vecPos2;
vector m_vecDest;
int m_iMoveState;
/* map keys */
float m_flDistance;
float m_flProgress;
float m_flSpeed;
float m_flReturnspeed;
@ -32,8 +41,34 @@ class CBaseMomentary:NSRenderableEntity
/* overrides */
virtual void(float) Save;
virtual void(string, string) Restore;
virtual void(int) SetMoveState;
virtual void(void) MovementStateChanged;
virtual float(void) GetProgress;
};
float
CBaseMomentary::GetProgress(void)
{
return 0.0f;
}
void
CBaseMomentary::MovementStateChanged(void)
{
/* this is handled by the respective sub entity */
}
void
CBaseMomentary::SetMoveState(int status)
{
if (m_iMoveState == status)
return;
m_iMoveState = status;
MovementStateChanged();
}
void
CBaseMomentary::Save(float handle)
{
@ -42,7 +77,6 @@ CBaseMomentary::Save(float handle)
SaveVector(handle, "pos1", m_vecPos1);
SaveVector(handle, "pos2", m_vecPos2);
SaveFloat(handle, "distance", m_flDistance);
SaveFloat(handle, "progress", m_flProgress);
SaveFloat(handle, "speed", m_flSpeed);
SaveFloat(handle, "returnspeed", m_flReturnspeed);
@ -66,10 +100,7 @@ CBaseMomentary::Restore(string strKey, string strValue)
m_vecPos2 = ReadVector(strValue);
break;
case "distance":
m_flProgress = ReadFloat(strValue);
break;
case "progress":
m_flProgress = ReadFloat(strValue);
m_flDistance = ReadFloat(strValue);
break;
case "speed":
m_flSpeed = ReadFloat(strValue);

View file

@ -39,7 +39,7 @@ trigger_endsection::Trigger(entity act, int state)
if (GetMaster() == FALSE)
return;
localcmd("echo disconnect\n");
localcmd("disconnect\n");
}
void

View file

@ -55,6 +55,7 @@ entity eActivator;
/* Generic entity fields */
.void(void) PlayerUse;
.void(void) PlayerUseUnpressed;
.int iBleeds;
.entity eUser;
.float material;

View file

@ -105,6 +105,8 @@ base_player
float underwater_dmg;
float pain_time;
entity last_used;
virtual void(float) Save;
virtual void(string,string) Restore;
virtual void(void) Respawn;

View file

@ -393,6 +393,9 @@ Sound_Play(entity target, int chan, string shader)
int flag;
int sample;
if (shader == "")
return;
flag = 0;
sample = (int)hash_get(g_hashsounds, shader, -1);
@ -502,6 +505,9 @@ Sound_PlayAt(vector pos, string shader)
int flag;
int sample;
if (shader == "")
return;
flag = 0;
sample = (int)hash_get(g_hashsounds, shader, -1);