From f1a909b4642d4e75d01d6915360366c640b8fb66 Mon Sep 17 00:00:00 2001 From: maybegreat48 <96936658+maybegreat48@users.noreply.github.com> Date: Sun, 16 Mar 2025 23:13:32 -0400 Subject: [PATCH] feat: add more features --- src/core/util/Joaat.hpp | 31 +++--- src/game/backend/Players.cpp | 1 - src/game/features/players/toxic/Explode.cpp | 2 +- src/game/features/self/GiveAllWeapons.cpp | 19 ++++ src/game/features/self/NoRagdoll.cpp | 28 +++++ src/game/features/self/RapidFire.cpp | 89 +++++++++++++++ src/game/features/self/Wanted.cpp | 63 +++++++++++ src/game/features/vehicle/HornBoost.cpp | 45 ++++++++ src/game/features/vehicle/Speedometer.cpp | 1 + src/game/frontend/items/ConditionalItem.cpp | 7 +- src/game/frontend/items/Items.hpp | 3 +- src/game/frontend/submenus/Self.cpp | 16 +++ src/game/gta/Ped.cpp | 22 ++++ src/game/gta/Ped.hpp | 5 + src/game/gta/Player.cpp | 10 ++ src/game/gta/Player.hpp | 5 + src/game/gta/data/Weapons.hpp | 115 ++++++++++++++++++++ 17 files changed, 441 insertions(+), 21 deletions(-) create mode 100644 src/game/features/self/GiveAllWeapons.cpp create mode 100644 src/game/features/self/NoRagdoll.cpp create mode 100644 src/game/features/self/RapidFire.cpp create mode 100644 src/game/features/self/Wanted.cpp create mode 100644 src/game/features/vehicle/HornBoost.cpp create mode 100644 src/game/gta/data/Weapons.hpp diff --git a/src/core/util/Joaat.hpp b/src/core/util/Joaat.hpp index 1f6470e..f531353 100644 --- a/src/core/util/Joaat.hpp +++ b/src/core/util/Joaat.hpp @@ -26,21 +26,22 @@ namespace YimMenu return hash; } - inline consteval joaat_t operator""_J(const char* s, std::size_t n) +}; + +inline consteval YimMenu::joaat_t operator""_J(const char* s, std::size_t n) +{ + YimMenu::joaat_t result = 0; + + for (std::size_t i = 0; i < n; i++) { - joaat_t result = 0; - - for (std::size_t i = 0; i < n; i++) - { - result += ToLower(s[i]); - result += (result << 10); - result ^= (result >> 6); - } - - result += (result << 3); - result ^= (result >> 11); - result += (result << 15); - - return result; + result += YimMenu::ToLower(s[i]); + result += (result << 10); + result ^= (result >> 6); } + + result += (result << 3); + result ^= (result >> 11); + result += (result << 15); + + return result; } \ No newline at end of file diff --git a/src/game/backend/Players.cpp b/src/game/backend/Players.cpp index 48142cb..d9f3eef 100644 --- a/src/game/backend/Players.cpp +++ b/src/game/backend/Players.cpp @@ -3,7 +3,6 @@ #include "types/network/CNetGamePlayer.hpp" #include "types/network/rlGamerInfo.hpp" - namespace YimMenu { Players::Players() diff --git a/src/game/features/players/toxic/Explode.cpp b/src/game/features/players/toxic/Explode.cpp index 802f1cc..3ea88fd 100644 --- a/src/game/features/players/toxic/Explode.cpp +++ b/src/game/features/players/toxic/Explode.cpp @@ -10,7 +10,7 @@ namespace YimMenu::Features virtual void OnCall(Player player) override { if (auto ped = player.GetPed()) - ped.Explode(ExplosionType::ORBITAL_CANNON, 900.f); + ped.Explode(ExplosionType::BLIMP, 900.f); } }; diff --git a/src/game/features/self/GiveAllWeapons.cpp b/src/game/features/self/GiveAllWeapons.cpp new file mode 100644 index 0000000..807efcf --- /dev/null +++ b/src/game/features/self/GiveAllWeapons.cpp @@ -0,0 +1,19 @@ +#include "core/commands/Command.hpp" +#include "game/backend/Self.hpp" +#include "game/gta/data/Weapons.hpp" + +namespace YimMenu::Features +{ + class GiveAllWeapons : public Command + { + using Command::Command; + + virtual void OnCall() override + { + for (auto weapon : Data::Weapons) + Self::GetPed().GiveWeapon(weapon); + } + }; + + static GiveAllWeapons _GiveAllWeapons{"giveallweapons", "Give All Weapons", "Gives you all weapons"}; +} \ No newline at end of file diff --git a/src/game/features/self/NoRagdoll.cpp b/src/game/features/self/NoRagdoll.cpp new file mode 100644 index 0000000..e1811bc --- /dev/null +++ b/src/game/features/self/NoRagdoll.cpp @@ -0,0 +1,28 @@ +#include "core/commands/LoopedCommand.hpp" +#include "game/backend/Self.hpp" + +namespace YimMenu::Features +{ + class NoRagdoll : public LoopedCommand + { + using LoopedCommand::LoopedCommand; + + virtual void OnTick() override + { + if (!Self::GetPed()) + return; + + Self::GetPed().SetRagdoll(false); + } + + virtual void OnDisable() override + { + if (!Self::GetPed()) + return; + + Self::GetPed().SetRagdoll(true); + } + }; + + static NoRagdoll _NoRagdoll{"noragdoll", "No Ragdoll", "Prevents your ped from ragdolling"}; +} \ No newline at end of file diff --git a/src/game/features/self/RapidFire.cpp b/src/game/features/self/RapidFire.cpp new file mode 100644 index 0000000..363c691 --- /dev/null +++ b/src/game/features/self/RapidFire.cpp @@ -0,0 +1,89 @@ +#include "core/commands/LoopedCommand.hpp" +#include "core/util/Math.hpp" +#include "game/backend/Self.hpp" +#include "game/gta/Natives.hpp" +#include "game/frontend/GUI.hpp" +#include "types/pad/ControllerInputs.hpp" + +namespace YimMenu::Features +{ + class RapidFire : public LoopedCommand + { + using LoopedCommand::LoopedCommand; + + const std::size_t m_TickRate = 5u; + std::size_t m_CurrentTick = 0; + + bool CanShoot() + { + bool result = (m_CurrentTick == 0); + m_CurrentTick = (m_CurrentTick + 1) % m_TickRate; + return result; + } + + virtual void OnTick() override + { + if (!HUD::IS_PAUSE_MENU_ACTIVE() && !GUI::IsOpen() && Self::GetPed() && !Self::GetPed().IsDead()) + { + if (PAD::IS_DISABLED_CONTROL_PRESSED(0, (int)ControllerInputs::INPUT_ATTACK) && CanShoot()) + { + const auto weapon_entity = WEAPON::GET_CURRENT_PED_WEAPON_ENTITY_INDEX(Self::GetPed().GetHandle(), 0); + if (!weapon_entity) + return; + + Vector3 dim_min; + Vector3 dim_max; + MISC::GET_MODEL_DIMENSIONS(ENTITY::GET_ENTITY_MODEL(weapon_entity), &dim_min, &dim_max); + + const auto dimensions = (dim_max - dim_min) * 0.5f; + const auto weapon_position = + ENTITY::GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(weapon_entity, dimensions.x, 0, dimensions.z * 0.3f); + + auto camera_direction = Math::RotationToDirection(CAM::GET_GAMEPLAY_CAM_ROT(0)); + auto camera_position = CAM::GET_GAMEPLAY_CAM_COORD() + camera_direction; + + Vector3 end = camera_position + camera_direction * 2000.0; + + const auto raycast_handle = + SHAPETEST::START_EXPENSIVE_SYNCHRONOUS_SHAPE_TEST_LOS_PROBE(camera_position.x, + camera_position.y, + camera_position.z, + end.x, + end.y, + end.z, + -1, + 0, + 7); + BOOL did_raycast_hit{FALSE}; + Vector3 raycast_hit_position{}; + Vector3 raycast_surface_normal_hit_position{}; + int raycast_hit_entity{}; + SHAPETEST::GET_SHAPE_TEST_RESULT(raycast_handle, &did_raycast_hit, &raycast_hit_position, &raycast_surface_normal_hit_position, &raycast_hit_entity); + if (did_raycast_hit) + { + end = raycast_hit_position; + } + + Hash weapon_hash = Self::GetPed().GetCurrentWeapon(); + + MISC::SHOOT_SINGLE_BULLET_BETWEEN_COORDS( + weapon_position.x, + weapon_position.y, + weapon_position.z, + end.x, + end.y, + end.z, + WEAPON::GET_WEAPON_DAMAGE(weapon_hash, 0), + true, + weapon_hash, + Self::GetPed().GetHandle(), + true, + false, + -1.0); + } + } + } + }; + + static RapidFire _RapidFire{"rapidfire", "Rapid Fire", "Increases the fire rate of your weapons substantially"}; +} \ No newline at end of file diff --git a/src/game/features/self/Wanted.cpp b/src/game/features/self/Wanted.cpp new file mode 100644 index 0000000..9fc6c3d --- /dev/null +++ b/src/game/features/self/Wanted.cpp @@ -0,0 +1,63 @@ +#include "core/commands/Command.hpp" +#include "core/commands/LoopedCommand.hpp" +#include "core/commands/IntCommand.hpp" +#include "game/backend/Self.hpp" +#include "game/gta/Natives.hpp" + +namespace YimMenu::Features +{ + static IntCommand _WantedSlider{"wantedslider", "Wanted Slider", "Wanted level to set/freeze", 0, 5, 0}; + + class ClearWanted : public Command + { + using Command::Command; + + virtual void OnCall() override + { + Self::GetPlayer().SetWantedLevel(0); + } + }; + + class SetWanted : public Command + { + using Command::Command; + + virtual void OnCall() override + { + Self::GetPlayer().SetWantedLevel(_WantedSlider.GetState()); + } + }; + + class NeverWanted : public LoopedCommand + { + using LoopedCommand::LoopedCommand; + + virtual void OnTick() override + { + Self::GetPlayer().SetWantedLevel(0); + PLAYER::SET_MAX_WANTED_LEVEL(0); + } + + virtual void OnDisable() override + { + PLAYER::SET_MAX_WANTED_LEVEL(6); + } + }; + + class FreezeWanted : public LoopedCommand + { + using LoopedCommand::LoopedCommand; + + virtual void OnTick() override + { + if (Self::GetPlayer().GetWantedLevel() != _WantedSlider.GetState()) + Self::GetPlayer().SetWantedLevel(_WantedSlider.GetState()); + PLAYER::SET_MAX_WANTED_LEVEL(_WantedSlider.GetState()); + } + }; + + static ClearWanted _ClearWanted{"clearwanted", "Clear Wanted", "Clears your wanted level"}; + static SetWanted _SetWanted{"setwanted", "Set Wanted", "Sets your wanted level to the desired level"}; + static NeverWanted _NeverWanted{"neverwanted", "Never Wanted", "Never gain a wanted level"}; + static FreezeWanted _FreezeWanted{"freezewanted", "Freeze Wanted", "Freeze your wanted level to the desired level"}; +} \ No newline at end of file diff --git a/src/game/features/vehicle/HornBoost.cpp b/src/game/features/vehicle/HornBoost.cpp new file mode 100644 index 0000000..09be4d0 --- /dev/null +++ b/src/game/features/vehicle/HornBoost.cpp @@ -0,0 +1,45 @@ +#include "core/commands/LoopedCommand.hpp" +#include "game/backend/Self.hpp" +#include "game/gta/Natives.hpp" +#include "types/pad/ControllerInputs.hpp" + +namespace YimMenu::Features +{ + class HornBoost : public LoopedCommand + { + using LoopedCommand::LoopedCommand; + + static constexpr float horn_boost_speed_default = 10.f; + static constexpr float horn_boost_speed_max = 200.f; + static constexpr float horn_boost_speed_increment = 0.3f; + + float m_HornBoostSpeed = horn_boost_speed_default; + + virtual void OnTick() override + { + auto veh = Self::GetVehicle(); + + if (!veh) + { + m_HornBoostSpeed = horn_boost_speed_default; + return; + } + + if (PAD::IS_CONTROL_JUST_PRESSED(0, (int)ControllerInputs::INPUT_VEH_HORN)) + m_HornBoostSpeed = veh.GetSpeed(); + + if (PAD::IS_CONTROL_PRESSED(0, (int)ControllerInputs::INPUT_VEH_HORN)) + { + if (m_HornBoostSpeed < horn_boost_speed_max) + m_HornBoostSpeed += horn_boost_speed_increment; + + const auto velocity = ENTITY::GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(veh.GetHandle(), 0.f, m_HornBoostSpeed, 0.f) - veh.GetPosition(); + veh.SetVelocity(Vector3(velocity)); + } + else if (PAD::IS_CONTROL_JUST_RELEASED(0, (int)ControllerInputs::INPUT_VEH_HORN)) + m_HornBoostSpeed = horn_boost_speed_default; + } + }; + + static HornBoost _HornBoost{"hornboost", "Horn Boost", "Makes the vehicle boost when you hold the horn"}; +} \ No newline at end of file diff --git a/src/game/features/vehicle/Speedometer.cpp b/src/game/features/vehicle/Speedometer.cpp index 79ae7f0..779502c 100644 --- a/src/game/features/vehicle/Speedometer.cpp +++ b/src/game/features/vehicle/Speedometer.cpp @@ -72,6 +72,7 @@ namespace YimMenu::Features virtual void OnDisable() override { GRAPHICS::SET_SCALEFORM_MOVIE_AS_NO_LONGER_NEEDED(&m_ScaleformHandle); + m_ScaleformHandle = 0; } }; diff --git a/src/game/frontend/items/ConditionalItem.cpp b/src/game/frontend/items/ConditionalItem.cpp index 93fb9a1..71157bd 100644 --- a/src/game/frontend/items/ConditionalItem.cpp +++ b/src/game/frontend/items/ConditionalItem.cpp @@ -6,9 +6,10 @@ namespace YimMenu { - ConditionalItem::ConditionalItem(joaat_t bool_cmd_id, std::shared_ptr to_draw) : + ConditionalItem::ConditionalItem(joaat_t bool_cmd_id, std::shared_ptr to_draw, bool negate) : m_Condition(Commands::GetCommand(bool_cmd_id)), - m_Item(to_draw) + m_Item(to_draw), + m_Negate(negate) { } @@ -19,7 +20,7 @@ namespace YimMenu return; } - if (m_Condition->GetState()) + if (m_Condition->GetState() ^ m_Negate) m_Item->Draw(); } } \ No newline at end of file diff --git a/src/game/frontend/items/Items.hpp b/src/game/frontend/items/Items.hpp index 385a6d9..d1c7e30 100644 --- a/src/game/frontend/items/Items.hpp +++ b/src/game/frontend/items/Items.hpp @@ -112,12 +112,13 @@ namespace YimMenu class ConditionalItem : public UIItem { public: - explicit ConditionalItem(joaat_t bool_cmd_id, std::shared_ptr to_draw); + explicit ConditionalItem(joaat_t bool_cmd_id, std::shared_ptr to_draw, bool negate = false); void Draw() override; private: BoolCommand* m_Condition; std::shared_ptr m_Item; + bool m_Negate; }; class ImGuiItem : public UIItem diff --git a/src/game/frontend/submenus/Self.cpp b/src/game/frontend/submenus/Self.cpp index 241b7fb..b77157a 100644 --- a/src/game/frontend/submenus/Self.cpp +++ b/src/game/frontend/submenus/Self.cpp @@ -22,11 +22,23 @@ namespace YimMenu::Submenus auto main = std::make_shared("Main"); auto globalsGroup = std::make_shared("Globals"); auto movementGroup = std::make_shared("Movement"); + auto wantedGroup = std::make_shared("Wanted"); auto toolsGroup = std::make_shared("Tools"); globalsGroup->AddItem(std::make_shared("godmode"_J)); globalsGroup->AddItem(std::make_shared("invis"_J)); globalsGroup->AddItem(std::make_shared("otr"_J)); + globalsGroup->AddItem(std::make_shared("noragdoll"_J)); + + auto clearWanted = std::make_shared("", 1); + clearWanted->AddItem(std::make_shared("neverwanted"_J, std::make_shared("clearwanted"_J), true)); + clearWanted->AddItem(std::make_shared("neverwanted"_J)); + auto setWanted = std::make_shared("", 1); + setWanted->AddItem(std::make_shared("wantedslider"_J, "Level")); + setWanted->AddItem(std::make_shared("freezewanted"_J, std::make_shared("setwanted"_J), true)); + setWanted->AddItem(std::make_shared("freezewanted"_J)); + wantedGroup->AddItem(std::make_shared("freezewanted"_J, clearWanted, true)); + wantedGroup->AddItem(std::make_shared("neverwanted"_J, setWanted, true)); toolsGroup->AddItem(std::make_shared("suicide"_J)); @@ -38,6 +50,7 @@ namespace YimMenu::Submenus movementGroup->AddItem(std::make_shared("freecam"_J, std::make_shared("freecamspeed"_J))); main->AddItem(globalsGroup); + main->AddItem(wantedGroup); main->AddItem(toolsGroup); main->AddItem(movementGroup); AddCategory(std::move(main)); @@ -47,6 +60,8 @@ namespace YimMenu::Submenus weaponsGlobalsGroup->AddItem(std::make_shared("infiniteammo"_J)); weaponsGlobalsGroup->AddItem(std::make_shared("infiniteclip"_J)); + weaponsGlobalsGroup->AddItem(std::make_shared("rapidfire"_J)); + weaponsGlobalsGroup->AddItem(std::make_shared("giveallweapons"_J)); weapons->AddItem(weaponsGlobalsGroup); AddCategory(std::move(weapons)); @@ -57,6 +72,7 @@ namespace YimMenu::Submenus vehicleGlobalsGroup->AddItem(std::make_shared("vehiclegodmode"_J, "Godmode")); vehicleGlobalsGroup->AddItem(std::make_shared("keepfixed"_J, "Keep Fixed")); + vehicleGlobalsGroup->AddItem(std::make_shared("hornboost"_J)); vehicleGlobalsGroup->AddItem(std::make_shared("repairvehicle"_J)); vehicleMiscGroup->AddItem(std::make_shared("speedometer"_J)); diff --git a/src/game/gta/Ped.cpp b/src/game/gta/Ped.cpp index a2e9954..87a0ea7 100644 --- a/src/game/gta/Ped.cpp +++ b/src/game/gta/Ped.cpp @@ -152,4 +152,26 @@ namespace YimMenu else SetPosition(pos); } + + void Ped::GiveWeapon(std::uint32_t hash, bool equip) + { + ENTITY_ASSERT_VALID(); + + WEAPON::GIVE_WEAPON_TO_PED(GetHandle(), hash, 9999, false, equip); + } + + void Ped::RemoveWeapon(std::uint32_t hash) + { + ENTITY_ASSERT_VALID(); + + WEAPON::REMOVE_WEAPON_FROM_PED(GetHandle(), hash); + } + + std::uint32_t Ped::GetCurrentWeapon() + { + ENTITY_ASSERT_VALID(); + std::uint32_t weapon; + WEAPON::GET_CURRENT_PED_WEAPON(GetHandle(), &weapon, 0); + return weapon; + } } \ No newline at end of file diff --git a/src/game/gta/Ped.hpp b/src/game/gta/Ped.hpp index 21bc837..bb5df6f 100644 --- a/src/game/gta/Ped.hpp +++ b/src/game/gta/Ped.hpp @@ -43,5 +43,10 @@ namespace YimMenu // teleport void TeleportTo(const rage::fvector3& pos); // similar to SetPosition, but handles vehicles correctly + + // weapons + void GiveWeapon(std::uint32_t hash, bool equip = false); + void RemoveWeapon(std::uint32_t hash); + std::uint32_t GetCurrentWeapon(); }; } \ No newline at end of file diff --git a/src/game/gta/Player.cpp b/src/game/gta/Player.cpp index d0dbffb..8a72346 100644 --- a/src/game/gta/Player.cpp +++ b/src/game/gta/Player.cpp @@ -177,6 +177,16 @@ namespace YimMenu return 0; } + int Player::GetWantedLevel() + { + return PLAYER::GET_PLAYER_WANTED_LEVEL(GetId()); + } + + void Player::SetWantedLevel(int level) + { + PLAYER::SET_PLAYER_WANTED_LEVEL_NOW(GetId(), level); + } + void Player::SetVisibleLocally(bool visible) { if (!IsValid()) diff --git a/src/game/gta/Player.hpp b/src/game/gta/Player.hpp index 5bb0fc4..ab4d3b5 100644 --- a/src/game/gta/Player.hpp +++ b/src/game/gta/Player.hpp @@ -52,10 +52,15 @@ namespace YimMenu float GetAverageLatency(); float GetAveragePacketLoss(); + // stats int GetRank(); int GetRP(); int GetMoney(); + // wanted + int GetWantedLevel(); + void SetWantedLevel(int level); // only works for local player for now + #if 0 // backend/data store (should be refactored?) PlayerData& GetData(); diff --git a/src/game/gta/data/Weapons.hpp b/src/game/gta/data/Weapons.hpp new file mode 100644 index 0000000..c4d493b --- /dev/null +++ b/src/game/gta/data/Weapons.hpp @@ -0,0 +1,115 @@ +#pragma once +#include "core/util/Joaat.hpp" + +namespace Data +{ + static inline constexpr auto Weapons = std::to_array({ + "weapon_dagger"_J, + "weapon_bat"_J, + "weapon_bottle"_J, + "weapon_crowbar"_J, + "weapon_unarmed"_J, + "weapon_flashlight"_J, + "weapon_golfclub"_J, + "weapon_hammer"_J, + "weapon_hatchet"_J, + "weapon_knuckle"_J, + "weapon_knife"_J, + "weapon_machete"_J, + "weapon_switchblade"_J, + "weapon_nightstick"_J, + "weapon_wrench"_J, + "weapon_battleaxe"_J, + "weapon_poolcue"_J, + "weapon_stone_hatchet"_J, + "weapon_pistol"_J, + "weapon_pistol_mk2"_J, + "weapon_combatpistol"_J, + "weapon_appistol"_J, + "weapon_stungun"_J, + "weapon_pistol50"_J, + "weapon_snspistol"_J, + "weapon_snspistol_mk2"_J, + "weapon_heavypistol"_J, + "weapon_vintagepistol"_J, + "weapon_flaregun"_J, + "weapon_marksmanpistol"_J, + "weapon_revolver"_J, + "weapon_revolver_mk2"_J, + "weapon_doubleaction"_J, + "weapon_raypistol"_J, + "weapon_ceramicpistol"_J, + "weapon_navyrevolver"_J, + "weapon_microsmg"_J, + "weapon_smg"_J, + "weapon_smg_mk2"_J, + "weapon_assaultsmg"_J, + "weapon_combatpdw"_J, + "weapon_machinepistol"_J, + "weapon_minismg"_J, + "weapon_raycarbine"_J, + "weapon_pumpshotgun"_J, + "weapon_pumpshotgun_mk2"_J, + "weapon_sawnoffshotgun"_J, + "weapon_assaultshotgun"_J, + "weapon_bullpupshotgun"_J, + "weapon_musket"_J, + "weapon_heavyshotgun"_J, + "weapon_dbshotgun"_J, + "weapon_autoshotgun"_J, + "weapon_assaultrifle"_J, + "weapon_assaultrifle_mk2"_J, + "weapon_carbinerifle"_J, + "weapon_carbinerifle_mk2"_J, + "weapon_advancedrifle"_J, + "weapon_specialcarbine"_J, + "weapon_specialcarbine_mk2"_J, + "weapon_bullpuprifle"_J, + "weapon_bullpuprifle_mk2"_J, + "weapon_compactrifle"_J, + "weapon_mg"_J, + "weapon_combatmg"_J, + "weapon_combatmg_mk2"_J, + "weapon_gusenberg"_J, + "weapon_sniperrifle"_J, + "weapon_heavysniper"_J, + "weapon_heavysniper_mk2"_J, + "weapon_marksmanrifle"_J, + "weapon_marksmanrifle_mk2"_J, + "weapon_rpg"_J, + "weapon_grenadelauncher"_J, + "weapon_grenadelauncher_smoke"_J, + "weapon_minigun"_J, + "weapon_firework"_J, + "weapon_railgun"_J, + "weapon_hominglauncher"_J, + "weapon_compactlauncher"_J, + "weapon_rayminigun"_J, + "weapon_grenade"_J, + "weapon_bzgas"_J, + "weapon_smokegrenade"_J, + "weapon_flare"_J, + "weapon_molotov"_J, + "weapon_stickybomb"_J, + "weapon_proxmine"_J, + "weapon_snowball"_J, + "weapon_pipebomb"_J, + "weapon_ball"_J, + "weapon_petrolcan"_J, + "weapon_fireextinguisher"_J, + "weapon_hazardcan"_J, + "weapon_militaryrifle"_J, + "weapon_combatshotgun"_J, + "weapon_gadgetpistol"_J, + "WEAPON_SNOWLAUNCHER"_J, + "WEAPON_BATTLERIFLE"_J, + "WEAPON_TECPISTOL"_J, + "WEAPON_CANDYCANE"_J, + "WEAPON_PISTOLXM3"_J, + "WEAPON_RAILGUNXM3"_J, + "WEAPON_PRECISIONRIFLE"_J, + "WEAPON_TACTICALRIFLE"_J, + "WEAPON_EMPLAUNCHER"_J, + "WEAPON_HEAVYRIFLE"_J, + }); +} \ No newline at end of file