diff --git a/base/src/shared/input.qc b/base/src/shared/input.qc index 2dace1a0..0bb24389 100644 --- a/base/src/shared/input.qc +++ b/base/src/shared/input.qc @@ -26,9 +26,9 @@ Game_Input(player pl) } if (input_buttons & INPUT_BUTTON5) - Player_UseDown(); + pl.InputUse_Down(); else - Player_UseUp(); + pl.InputUse_Up(); if (pl.impulse == 100) Flashlight_Toggle(); diff --git a/src/gs-entbase/server/func_button.qc b/src/gs-entbase/server/func_button.qc index ce3ef70a..b6952e9d 100644 --- a/src/gs-entbase/server/func_button.qc +++ b/src/gs-entbase/server/func_button.qc @@ -111,7 +111,7 @@ class func_button:NSSurfacePropEntity virtual void(entity) Blocked; virtual void(entity, int) Trigger; virtual void(void) DeathTrigger; - virtual void(void) Use; + virtual void(void) PlayerUse; virtual void(void) SetMovementDirection; virtual void(vector, void(void)) MoveToDestination; @@ -337,8 +337,11 @@ func_button::Touch(entity eToucher) } void -func_button::Use(void) +func_button::PlayerUse(void) { + if (HasSpawnFlags(SF_BTT_TOUCH_ONLY)) { + return; + } Trigger(eActivator, TRIG_TOGGLE); } @@ -425,12 +428,6 @@ func_button::Respawn(void) m_flSpeed = 100; } - if (HasSpawnFlags(SF_BTT_TOUCH_ONLY)) { - PlayerUse = __NULL__; - } else { - PlayerUse = Use; - } - m_vecPos1 = GetSpawnOrigin(); if (HasSpawnFlags(SF_BTT_NOMOVE)) { diff --git a/src/gs-entbase/server/func_door.qc b/src/gs-entbase/server/func_door.qc index 11b9c0ea..7f74a16c 100644 --- a/src/gs-entbase/server/func_door.qc +++ b/src/gs-entbase/server/func_door.qc @@ -113,7 +113,7 @@ class func_door:NSRenderableEntity virtual void(entity, int) Trigger; virtual void(entity) Blocked; virtual void(entity) Touch; - virtual void(void) Use; + virtual void(void) PlayerUse; virtual void(float) Save; virtual void(string, string) Restore; virtual void(string, string) SpawnKey; @@ -141,8 +141,11 @@ func_door::PortalClose(void) } void -func_door::Use(void) +func_door::PlayerUse(void) { + if (!HasSpawnFlags(SF_MOV_USE)) + return; + eActivator.flags &= ~FL_USE_RELEASED; Trigger(eActivator, TRIG_TOGGLE); } @@ -398,6 +401,7 @@ func_door::Respawn(void) SetMovetype(MOVETYPE_PUSH); SetModel(GetSpawnModel()); SetOrigin(GetSpawnOrigin()); + flags |= FL_FINDABLE_NONSOLID; think = __NULL__; nextthink = 0.0f; @@ -415,12 +419,6 @@ func_door::Respawn(void) m_iDamage = 2; } - if (HasSpawnFlags(SF_MOV_USE)) { - PlayerUse = Use; - } else { - PlayerUse = __NULL__; - } - m_iValue = 0; m_iState = DOORSTATE_LOWERED; m_vecPos1 = GetSpawnOrigin(); diff --git a/src/gs-entbase/server/func_rot_button.qc b/src/gs-entbase/server/func_rot_button.qc index 602e89c9..b361f44b 100644 --- a/src/gs-entbase/server/func_rot_button.qc +++ b/src/gs-entbase/server/func_rot_button.qc @@ -218,6 +218,7 @@ func_rot_button::Respawn(void) SetOrigin(GetSpawnOrigin()); SetAngles(GetSpawnAngles()); PlayerUse = OnPlayerUse; + flags |= FL_FINDABLE_NONSOLID; m_iState = ROTBTNSTATE_OPENED; think = __NULL__; diff --git a/src/shared/player.h b/src/shared/player.h index f329709c..f08b40f6 100644 --- a/src/shared/player.h +++ b/src/shared/player.h @@ -113,5 +113,8 @@ base_player:spectator virtual void(void) Death; virtual void(void) MakePlayer; virtual void(void) MakeTempSpectator; + + virtual void(void) InputUse_Down; + virtual void(void) InputUse_Up; #endif }; diff --git a/src/shared/player.qc b/src/shared/player.qc index 41c999e6..ebebc1ab 100644 --- a/src/shared/player.qc +++ b/src/shared/player.qc @@ -789,6 +789,110 @@ base_player::SendEntity(entity ePEnt, float fChanged) return (1); } + +/* +==================== +_base_player_useworkaround + +A wrapper to cleanly reset 'self' as to not mess up the QC VM +==================== +*/ +void +_base_player_useworkaround(entity eTarget) +{ + eActivator = self; + entity eOldSelf = self; + self = eTarget; + self.PlayerUse(); + self = eOldSelf; +} + +/* +==================== +_base_player_useworkaround + +A wrapper to cleanly reset 'self' as to not mess up the QC VM +==================== +*/ +void +_base_player_unuseworkaround(entity eTarget) +{ + eActivator = self; + entity eOldSelf = self; + self = eTarget; + if (self.PlayerUseUnpressed) + self.PlayerUseUnpressed(); + self = eOldSelf; +} + +/* +================= +base_player:: InputUse_Down + +Called when we hold down the +use button for the first time +================= +*/ +void +base_player::InputUse_Down(void) +{ + if (health <= 0) { + return; + } else if (!(flags & FL_USE_RELEASED)) { + return; + } + + vector vecSource; + entity eRad; + + makevectors(v_angle); + vecSource = origin + view_ofs; + traceline(vecSource, vecSource + (v_forward * 64), MOVE_EVERYTHING, this); + + /* find anything in a 8 unit radius, including certain non-solids (func_door, func_rot_button etc. */ + eRad = findradius(trace_endpos, 8); + bool found_use = false; + + /* loop through our chain and just pick the first valid one */ + while (eRad) { + if (eRad.PlayerUse) { + found_use = true; + break; + } + eRad = eRad.chain; + } + + /* TODO: maybe eRad will return something in the future that'll suppress a successfull use? */ + if (eRad && found_use == true) { + flags &= ~FL_USE_RELEASED; + _base_player_useworkaround(eRad); + last_used = eRad; + + /* Some entities want to support Use spamming */ + if (!(flags & FL_USE_RELEASED)) { + sound(this, CHAN_ITEM, "common/wpn_select.wav", 0.25, ATTN_IDLE); + } + } else { + sound(this, CHAN_ITEM, "common/wpn_denyselect.wav", 0.25, ATTN_IDLE); + flags &= ~FL_USE_RELEASED; + } +} + +/* +================= +base_player:: InputUse_Down + +Called when we let go of the +use button +================= +*/ +void +base_player::InputUse_Up(void) +{ + if (!(flags & FL_USE_RELEASED)) { + _base_player_unuseworkaround(last_used); + last_used = world; + flags |= FL_USE_RELEASED; + } +} #endif void