From 8d5c395bb4a76b2a23a331f2ba60dddd3ef4e0c1 Mon Sep 17 00:00:00 2001 From: Arthur <121949966+ShinyWasabi@users.noreply.github.com> Date: Sun, 6 Apr 2025 15:05:59 +0300 Subject: [PATCH] feat(self): Various Features (#103) * feat(self): Various Features * code review changes --- src/game/features/self/ClearDamage.cpp | 17 ++++ src/game/features/self/FillInventory.cpp | 30 ++++++ src/game/features/self/Heal.cpp | 20 ++++ src/game/features/self/UnlimitedOxygen.cpp | 22 +++++ src/game/frontend/submenus/Self.cpp | 4 + src/game/gta/Ped.cpp | 27 +++++ src/game/gta/Ped.hpp | 8 ++ src/game/gta/Player.cpp | 5 + src/game/gta/Player.hpp | 2 +- src/game/gta/Stats.cpp | 110 +++++++++++++++++++++ src/game/gta/Stats.hpp | 28 ++++++ 11 files changed, 272 insertions(+), 1 deletion(-) create mode 100644 src/game/features/self/ClearDamage.cpp create mode 100644 src/game/features/self/FillInventory.cpp create mode 100644 src/game/features/self/Heal.cpp create mode 100644 src/game/features/self/UnlimitedOxygen.cpp create mode 100644 src/game/gta/Stats.cpp create mode 100644 src/game/gta/Stats.hpp diff --git a/src/game/features/self/ClearDamage.cpp b/src/game/features/self/ClearDamage.cpp new file mode 100644 index 0000000..abfc331 --- /dev/null +++ b/src/game/features/self/ClearDamage.cpp @@ -0,0 +1,17 @@ +#include "core/commands/Command.hpp" +#include "game/backend/Self.hpp" + +namespace YimMenu::Features +{ + class ClearDamage : Command + { + using Command::Command; + + virtual void OnCall() override + { + Self::GetPed().ClearDamage(); + } + }; + + static ClearDamage _ClearDamage{"cleardamage", "Clear Damage", "Clears all the dirt and blood on you."}; +} \ No newline at end of file diff --git a/src/game/features/self/FillInventory.cpp b/src/game/features/self/FillInventory.cpp new file mode 100644 index 0000000..97a9619 --- /dev/null +++ b/src/game/features/self/FillInventory.cpp @@ -0,0 +1,30 @@ +#include "core/commands/Command.hpp" +#include "game/gta/Stats.hpp" + +namespace YimMenu::Features +{ + class FillInventory : public Command + { + using Command::Command; + + virtual void OnCall() override + { + Stats::SetInt("MPX_NO_BOUGHT_YUM_SNACKS", 30); + Stats::SetInt("MPX_NO_BOUGHT_HEALTH_SNACKS", 15); + Stats::SetInt("MPX_NO_BOUGHT_EPIC_SNACKS", 5); + Stats::SetInt("MPX_NUMBER_OF_CHAMP_BOUGHT", 5); + Stats::SetInt("MPX_NUMBER_OF_ORANGE_BOUGHT", 10); + Stats::SetInt("MPX_NUMBER_OF_BOURGE_BOUGHT", 10); + Stats::SetInt("MPX_NUMBER_OF_SPRUNK_BOUGHT", 10); + Stats::SetInt("MPX_MP_CHAR_ARMOUR_1_COUNT", 10); + Stats::SetInt("MPX_MP_CHAR_ARMOUR_2_COUNT", 10); + Stats::SetInt("MPX_MP_CHAR_ARMOUR_3_COUNT", 10); + Stats::SetInt("MPX_MP_CHAR_ARMOUR_4_COUNT", 10); + Stats::SetInt("MPX_MP_CHAR_ARMOUR_5_COUNT", 10); + Stats::SetInt("MPX_CIGARETTES_BOUGHT", 20); + Stats::SetInt("MPX_BREATHING_APPAR_BOUGHT", 20); + } + }; + + static FillInventory _FillInventory{"fillinventory", "Fill Inventory", "Fills all of your snacks and armours."}; +} \ No newline at end of file diff --git a/src/game/features/self/Heal.cpp b/src/game/features/self/Heal.cpp new file mode 100644 index 0000000..1f5e609 --- /dev/null +++ b/src/game/features/self/Heal.cpp @@ -0,0 +1,20 @@ +#include "core/commands/Command.hpp" +#include "game/backend/Self.hpp" + +namespace YimMenu::Features +{ + class Heal : Command + { + using Command::Command; + + virtual void OnCall() override + { + int maxHealth = Self::GetPed().GetMaxHealth(); + int maxArmour = Self::GetPlayer().GetMaxArmour(); + Self::GetPed().SetHealth(maxHealth); + Self::GetPed().SetArmour(maxArmour); + } + }; + + static Heal _Heal{"heal", "Heal", "Restores your health and armour."}; +} \ No newline at end of file diff --git a/src/game/features/self/UnlimitedOxygen.cpp b/src/game/features/self/UnlimitedOxygen.cpp new file mode 100644 index 0000000..a7a42b2 --- /dev/null +++ b/src/game/features/self/UnlimitedOxygen.cpp @@ -0,0 +1,22 @@ +#include "core/commands/LoopedCommand.hpp" +#include "game/backend/Self.hpp" + +namespace YimMenu::Features +{ + class UnlimitedOxygen : LoopedCommand + { + using LoopedCommand::LoopedCommand; + + virtual void OnTick() override + { + Self::GetPed().SetMaxTimeUnderwater(INT_MAX); + } + + virtual void OnDisable() override + { + Self::GetPed().SetMaxTimeUnderwater(-1.0f); // default value + } + }; + + static UnlimitedOxygen _UnlimitedOxygen{"unlimitedoxygen", "Unlimited Oxygen", "Allows you to stay underwater without losing oxygen."}; +} \ No newline at end of file diff --git a/src/game/frontend/submenus/Self.cpp b/src/game/frontend/submenus/Self.cpp index 1399142..8bb8f89 100644 --- a/src/game/frontend/submenus/Self.cpp +++ b/src/game/frontend/submenus/Self.cpp @@ -25,6 +25,7 @@ namespace YimMenu::Submenus globalsGroup->AddItem(std::make_shared("otr"_J)); globalsGroup->AddItem(std::make_shared("noragdoll"_J)); globalsGroup->AddItem(std::make_shared("noidlekick"_J)); + globalsGroup->AddItem(std::make_shared("unlimitedoxygen"_J)); auto clearWanted = std::make_shared("", 1); clearWanted->AddItem(std::make_shared("neverwanted"_J, std::make_shared("clearwanted"_J), true)); @@ -38,6 +39,9 @@ namespace YimMenu::Submenus toolsGroup->AddItem(std::make_shared("skipcutscene"_J)); toolsGroup->AddItem(std::make_shared("suicide"_J)); + toolsGroup->AddItem(std::make_shared("heal"_J)); + toolsGroup->AddItem(std::make_shared("cleardamage"_J)); + toolsGroup->AddItem(std::make_shared("fillinventory"_J)); movementGroup->AddItem(std::make_shared("superrun"_J)); movementGroup->AddItem(std::make_shared("superjump"_J)); diff --git a/src/game/gta/Ped.cpp b/src/game/gta/Ped.cpp index 28e5596..eca5fa3 100644 --- a/src/game/gta/Ped.cpp +++ b/src/game/gta/Ped.cpp @@ -208,4 +208,31 @@ namespace YimMenu return WEAPON::HAS_PED_GOT_WEAPON(GetHandle(), hash, false); } + + int Ped::GetArmour() + { + ENTITY_ASSERT_VALID(); + return PED::GET_PED_ARMOUR(GetHandle()); + } + + void Ped::SetArmour(int amount) + { + ENTITY_ASSERT_VALID(); + PED::SET_PED_ARMOUR(GetHandle(), amount); + } + + void Ped::ClearDamage() + { + ENTITY_ASSERT_VALID(); + PED::CLEAR_PED_BLOOD_DAMAGE(GetHandle()); + PED::CLEAR_PED_WETNESS(GetHandle()); + PED::CLEAR_PED_ENV_DIRT(GetHandle()); + PED::RESET_PED_VISIBLE_DAMAGE(GetHandle()); + } + + void Ped::SetMaxTimeUnderwater(int time) + { + ENTITY_ASSERT_VALID(); + PED::SET_PED_MAX_TIME_UNDERWATER(GetHandle(), time); + } } \ No newline at end of file diff --git a/src/game/gta/Ped.hpp b/src/game/gta/Ped.hpp index 9dfc7ab..a4b3fd9 100644 --- a/src/game/gta/Ped.hpp +++ b/src/game/gta/Ped.hpp @@ -51,5 +51,13 @@ namespace YimMenu // teleport void TeleportTo(const rage::fvector3& pos); // similar to SetPosition, but handles vehicles correctly + + // armour + int GetArmour(); + void SetArmour(int amount); + + // misc + void ClearDamage(); + void SetMaxTimeUnderwater(int time); }; } \ No newline at end of file diff --git a/src/game/gta/Player.cpp b/src/game/gta/Player.cpp index ab54fca..2991f9b 100644 --- a/src/game/gta/Player.cpp +++ b/src/game/gta/Player.cpp @@ -337,6 +337,11 @@ namespace YimMenu }); } + int Player::GetMaxArmour() + { + return PLAYER::GET_PLAYER_MAX_ARMOUR(GetId()); // Not checking IsValid to let GetId return 0 in SP + } + bool Player::operator==(Player other) { return m_Handle == other.m_Handle; diff --git a/src/game/gta/Player.hpp b/src/game/gta/Player.hpp index f1d0f4c..7427f28 100644 --- a/src/game/gta/Player.hpp +++ b/src/game/gta/Player.hpp @@ -79,7 +79,7 @@ namespace YimMenu /// The position to teleport to void TeleportTo(const rage::fvector3& coords); - + int GetMaxArmour(); bool operator==(Player other); diff --git a/src/game/gta/Stats.cpp b/src/game/gta/Stats.cpp new file mode 100644 index 0000000..f37490f --- /dev/null +++ b/src/game/gta/Stats.cpp @@ -0,0 +1,110 @@ +#include "Stats.hpp" +#include "game/gta/Natives.hpp" + +namespace +{ + void ConvertMPX(std::string& statName) + { + std::transform(statName.begin(), statName.end(), statName.begin(), ::tolower); + if (statName.substr(0, 3) == "mpx") + statName[2] = YimMenu::Stats::GetCharIndex() + '0'; + } +} + +namespace YimMenu::Stats +{ + int GetCharIndex() + { + int index{}; + STATS::STAT_GET_INT("MPPLY_LAST_MP_CHAR"_J, &index, -1); + return index; + } + + void SetInt(std::string statName, int value) + { + ConvertMPX(statName); + STATS::STAT_SET_INT(Joaat(statName), value, TRUE); + } + + void SetBool(std::string statName, bool value) + { + ConvertMPX(statName); + STATS::STAT_SET_BOOL(Joaat(statName), value, TRUE); + } + + void SetFloat(std::string statName, float value) + { + ConvertMPX(statName); + STATS::STAT_SET_FLOAT(Joaat(statName), value, TRUE); + } + + void SetDate(std::string statName, Date* value) + { + ConvertMPX(statName); + STATS::STAT_SET_DATE(Joaat(statName), value, sizeof(Date) / 8, TRUE); + } + + void SetString(std::string statName, const char* value) + { + ConvertMPX(statName); + STATS::STAT_SET_STRING(Joaat(statName), value, TRUE); + } + + int GetInt(std::string statName) + { + int value{}; + ConvertMPX(statName); + STATS::STAT_GET_INT(Joaat(statName), &value, -1); + return value; + } + + bool GetBool(std::string statName) + { + BOOL value{}; + ConvertMPX(statName); + STATS::STAT_GET_BOOL(Joaat(statName), &value, -1); + return value; + } + + float GetFloat(std::string statName) + { + float value{}; + ConvertMPX(statName); + STATS::STAT_GET_FLOAT(Joaat(statName), &value, -1); + return value; + } + + Date GetDate(std::string statName) + { + Date value{}; + ConvertMPX(statName); + STATS::STAT_GET_DATE(Joaat(statName), &value, sizeof(Date) / 8, -1); + return value; + } + + const char* GetString(std::string statName) + { + ConvertMPX(statName); + return STATS::STAT_GET_STRING(Joaat(statName), -1); // The native is null-safe + } + + void SetPackedBool(int index, bool value) + { + STATS::SET_PACKED_STAT_BOOL_CODE(index, value, -1); + } + + void SetPackedInt(int index, int value) + { + STATS::SET_PACKED_STAT_INT_CODE(index, value, -1); + } + + bool GetPackedBool(int index) + { + return STATS::GET_PACKED_STAT_BOOL_CODE(index, -1); + } + + int GetPackedInt(int index) + { + return STATS::GET_PACKED_STAT_INT_CODE(index, -1); + } +} \ No newline at end of file diff --git a/src/game/gta/Stats.hpp b/src/game/gta/Stats.hpp new file mode 100644 index 0000000..8e5035b --- /dev/null +++ b/src/game/gta/Stats.hpp @@ -0,0 +1,28 @@ +#pragma once +#include "core/util/Joaat.hpp" + +namespace YimMenu::Stats +{ + struct Date + { + alignas(8) int Year, Month, Day, Hour, Minute, Second, Millisecond; + }; + + extern int GetCharIndex(); + + extern void SetInt(std::string statName, int value); + extern void SetBool(std::string statName, bool value); + extern void SetFloat(std::string statName, float value); + extern void SetDate(std::string statName, Date* value); + extern void SetString(std::string statName, const char* value); + extern int GetInt(std::string statName); + extern bool GetBool(std::string statName); + extern float GetFloat(std::string statName); + extern Date GetDate(std::string statName); + extern const char* GetString(std::string statName); + + extern void SetPackedBool(int index, bool value); + extern void SetPackedInt(int index, int value); + extern bool GetPackedBool(int index); + extern int GetPackedInt(int index); +} \ No newline at end of file