diff --git a/regamedll/CMakeLists.txt b/regamedll/CMakeLists.txt index 735d54fc8..6bb79e849 100644 --- a/regamedll/CMakeLists.txt +++ b/regamedll/CMakeLists.txt @@ -229,6 +229,7 @@ set(GAMEDLL_SRCS "dlls/API/CSPlayerWeapon.cpp" "dlls/addons/item_airbox.cpp" "dlls/addons/point_command.cpp" + "dlls/addons/trigger_bomb_reset.cpp" "dlls/addons/trigger_random.cpp" "dlls/addons/trigger_setorigin.cpp" "dlls/wpn_shared/wpn_ak47.cpp" diff --git a/regamedll/dlls/addons/trigger_bomb_reset.cpp b/regamedll/dlls/addons/trigger_bomb_reset.cpp new file mode 100644 index 000000000..3765cbdb8 --- /dev/null +++ b/regamedll/dlls/addons/trigger_bomb_reset.cpp @@ -0,0 +1,39 @@ +/* +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at +* your option) any later version. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +*/ + +#include "precompiled.h" + +LINK_ENTITY_TO_CLASS(trigger_bomb_reset, CTriggerBombReset, CCSTriggerBombReset) + +void CTriggerBombReset::Spawn() +{ + InitTrigger(); + SetTouch(&CTriggerBombReset::Touch); + SetUse(&CTriggerBombReset::ToggleUse); +} + +void CTriggerBombReset::Touch(CBaseEntity *pOther) +{ + CWeaponBox *pWeaponBox = dynamic_cast(pOther); + + if (pWeaponBox && pWeaponBox->m_bIsBomb) + { + // If the bomb touches this trigger, tell it to reset to its last known valid position. + pWeaponBox->ResetToLastValidPlayerHeldC4Position(); + } +} diff --git a/regamedll/dlls/addons/trigger_bomb_reset.h b/regamedll/dlls/addons/trigger_bomb_reset.h new file mode 100644 index 000000000..60e21bfcf --- /dev/null +++ b/regamedll/dlls/addons/trigger_bomb_reset.h @@ -0,0 +1,28 @@ +/* +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at +* your option) any later version. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +*/ + +#pragma once + +#include "triggers.h" + +class CTriggerBombReset: public CBaseTrigger +{ +public: + virtual void Spawn(); + virtual void Touch(CBaseEntity *pOther); +}; diff --git a/regamedll/dlls/player.cpp b/regamedll/dlls/player.cpp index e2e185a62..e896e0b6a 100644 --- a/regamedll/dlls/player.cpp +++ b/regamedll/dlls/player.cpp @@ -8218,6 +8218,7 @@ CBaseEntity *EXT_FUNC CBasePlayer::__API_HOOK(DropPlayerItem)(const char *pszIte pWeaponBox->m_bIsBomb = true; pWeaponBox->SetThink(&CWeaponBox::BombThink); pWeaponBox->pev->nextthink = gpGlobals->time + 1.0f; + pWeaponBox->SetLastValidHeldC4Position(((CC4 *)pWeapon)->GetLastValidHeldPosition()); if (TheCSBots()) { diff --git a/regamedll/dlls/weapons.cpp b/regamedll/dlls/weapons.cpp index 3baa8a44e..3604c26de 100644 --- a/regamedll/dlls/weapons.cpp +++ b/regamedll/dlls/weapons.cpp @@ -2269,6 +2269,24 @@ void CWeaponBox::SetObjectCollisionBox() pev->absmax = pev->origin + Vector(16, 16, 16); } +void CWeaponBox::ResetToLastValidPlayerHeldC4Position() +{ + if (pev->origin == m_vecLastValidPlayerHeldC4Position) + { + return; + } + + Vector const vecResetPos = m_vecLastValidPlayerHeldC4Position + Vector(0.0f, 0.0f, 8.0f); + Vector const angResetAng = Vector(0.0f, RANDOM_FLOAT(0.0f, 360.0f), 0.0f); + + // Teleport + pev->velocity = Vector(0.0f, 0.0f, 0.0f); + pev->movetype = MOVETYPE_NONE; + pev->flags |= FL_ONGROUND; + pev->angles = angResetAng; + UTIL_SetOrigin(pev, vecResetPos); +} + char *CArmoury::m_ItemModels[] = { "models/w_mp5.mdl", "models/w_tmp.mdl", diff --git a/regamedll/dlls/weapons.h b/regamedll/dlls/weapons.h index 431284fb9..8e4e2651e 100644 --- a/regamedll/dlls/weapons.h +++ b/regamedll/dlls/weapons.h @@ -486,6 +486,9 @@ class CWeaponBox: public CBaseEntity void SetModel_OrigFunc(const char *pszModelName); #endif + void SetLastValidHeldC4Position(const Vector &vecPositon) { m_vecLastValidPlayerHeldC4Position = vecPositon; } + void ResetToLastValidPlayerHeldC4Position(); + public: static TYPEDESCRIPTION m_SaveData[]; @@ -494,6 +497,9 @@ class CWeaponBox: public CBaseEntity int m_rgAmmo[MAX_AMMO_SLOTS]; int m_cAmmoTypes; bool m_bIsBomb; + +private: + Vector m_vecLastValidPlayerHeldC4Position; }; @@ -846,6 +852,7 @@ class CAWP: public CBasePlayerWeapon const float C4_MAX_SPEED = 250.0f; const float C4_ARMING_ON_TIME = 3.0f; +constexpr float WEAPON_C4_UPDATE_LAST_VALID_PLAYER_HELD_POSITION_INTERVAL = 0.2f; enum c4_e { @@ -865,6 +872,7 @@ class CC4: public CBasePlayerWeapon virtual int GetItemInfo(ItemInfo *p); virtual BOOL Deploy(); virtual void Holster(int skiplocal); + virtual void AttachToPlayer(CBasePlayer *pPlayer); virtual float GetMaxSpeed(); virtual int iItemSlot() { return C4_SLOT; } virtual void PrimaryAttack(); @@ -878,6 +886,9 @@ class CC4: public CBasePlayerWeapon #endif } + void EXPORT TrackPlayerHeldPosition(); + Vector GetLastValidHeldPosition() const { return m_vecLastValidPlayerHeldPosition; } + public: bool m_bStartedArming; bool m_bBombPlacedAnimation; @@ -885,6 +896,7 @@ class CC4: public CBasePlayerWeapon private: bool m_bHasShield; + Vector m_vecLastValidPlayerHeldPosition; }; diff --git a/regamedll/dlls/wpn_shared/wpn_c4.cpp b/regamedll/dlls/wpn_shared/wpn_c4.cpp index f5c52b01a..d35a7ab01 100644 --- a/regamedll/dlls/wpn_shared/wpn_c4.cpp +++ b/regamedll/dlls/wpn_shared/wpn_c4.cpp @@ -382,3 +382,33 @@ float CC4::GetMaxSpeed() return C4_MAX_SPEED; } + +void CC4::AttachToPlayer(CBasePlayer *pPlayer) +{ + CBasePlayerWeapon::AttachToPlayer(pPlayer); + +#ifdef REGAMEDLL_ADD + SetThink(&CC4::TrackPlayerHeldPosition); + pev->nextthink = gpGlobals->time + WEAPON_C4_UPDATE_LAST_VALID_PLAYER_HELD_POSITION_INTERVAL; + + if (pPlayer->IsPlayer() && pPlayer->IsAlive()) + { + entvars_t *pevPlayer = pPlayer->pev; + m_vecLastValidPlayerHeldPosition = pevPlayer->origin + pevPlayer->mins; + } +#endif +} + +void CC4::TrackPlayerHeldPosition() +{ + pev->nextthink = gpGlobals->time + WEAPON_C4_UPDATE_LAST_VALID_PLAYER_HELD_POSITION_INTERVAL; + + // If the bomb is held by an alive player standing on the ground, then we can use this + // position as the last known valid position to respawn the bomb if it gets reset. + + if (m_pPlayer && m_pPlayer->IsPlayer() && m_pPlayer->IsAlive() && (m_pPlayer->pev->flags & FL_ONGROUND)) + { + entvars_t *pevPlayer = m_pPlayer->pev; + m_vecLastValidPlayerHeldPosition = pevPlayer->origin + pevPlayer->mins; + } +} diff --git a/regamedll/extra/Toolkit/GameDefinitionFile/regamedll-cs.fgd b/regamedll/extra/Toolkit/GameDefinitionFile/regamedll-cs.fgd index 0e6838732..f9bf99a52 100644 --- a/regamedll/extra/Toolkit/GameDefinitionFile/regamedll-cs.fgd +++ b/regamedll/extra/Toolkit/GameDefinitionFile/regamedll-cs.fgd @@ -2272,6 +2272,10 @@ ] ] +@SolidClass base(Trigger) = trigger_bomb_reset : "Trigger bomb reset" +[ +] + // Function entities @SolidClass = func_bomb_target : "Bomb target zone" [ diff --git a/regamedll/msvc/ReGameDLL.vcxproj b/regamedll/msvc/ReGameDLL.vcxproj index c31abc6e9..a9c9d6743 100644 --- a/regamedll/msvc/ReGameDLL.vcxproj +++ b/regamedll/msvc/ReGameDLL.vcxproj @@ -1,4 +1,4 @@ - + @@ -25,6 +25,7 @@ + @@ -620,6 +621,7 @@ + diff --git a/regamedll/msvc/ReGameDLL.vcxproj.filters b/regamedll/msvc/ReGameDLL.vcxproj.filters index 84536f321..34d6ead93 100644 --- a/regamedll/msvc/ReGameDLL.vcxproj.filters +++ b/regamedll/msvc/ReGameDLL.vcxproj.filters @@ -1,4 +1,4 @@ - + @@ -552,6 +552,9 @@ dlls\addons + + dlls\addons + public @@ -1046,14 +1049,17 @@ public\regamedll\API + + public + dlls\addons dlls\addons - - public + + dlls\addons \ No newline at end of file diff --git a/regamedll/public/regamedll/API/CSInterfaces.h b/regamedll/public/regamedll/API/CSInterfaces.h index 98e9ea145..41d16ecec 100644 --- a/regamedll/public/regamedll/API/CSInterfaces.h +++ b/regamedll/public/regamedll/API/CSInterfaces.h @@ -213,6 +213,7 @@ class CCSChangeLevel: public CCSTrigger {}; class CCSLadder: public CCSTrigger {}; class CCSTriggerPush: public CCSTrigger {}; class CCSTriggerTeleport: public CCSTrigger {}; +class CCSTriggerBombReset: public CCSTrigger {}; class CCSBuyZone: public CCSTrigger {}; class CCSBombTarget: public CCSTrigger {}; class CCSHostageRescue: public CCSTrigger {}; diff --git a/regamedll/regamedll/dlls.h b/regamedll/regamedll/dlls.h index 2bef63d6d..51f4a2e4d 100644 --- a/regamedll/regamedll/dlls.h +++ b/regamedll/regamedll/dlls.h @@ -134,6 +134,7 @@ using FloatRef = float; #include "addons/trigger_setorigin.h" #include "addons/trigger_random.h" #include "addons/point_command.h" +#include "addons/trigger_bomb_reset.h" // Tutor #include "tutor.h"