mirror of
https://github.com/YimMenu/YimMenuV2.git
synced 2026-10-10 11:53:14 +08:00
feat(hotkeys): implement hotkeys and more
This commit is contained in:
@@ -88,43 +88,52 @@ namespace YimMenu
|
|||||||
MarkStateDirty();
|
MarkStateDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HotkeySystem::Update()
|
void HotkeySystem::RunScriptImpl()
|
||||||
{
|
{
|
||||||
for (auto& [hash, link] : m_CommandHotkeys)
|
while (g_Running)
|
||||||
{
|
{
|
||||||
if (link.m_Chain.empty() || link.m_BeingModified)
|
for (auto& [hash, link] : m_CommandHotkeys)
|
||||||
continue;
|
|
||||||
|
|
||||||
bool all_keys_pressed = true;
|
|
||||||
|
|
||||||
for (auto modifier : link.m_Chain)
|
|
||||||
{
|
{
|
||||||
if (!(GetAsyncKeyState(modifier) & 0x8000))
|
if (link.m_Chain.empty() || link.m_BeingModified)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
bool all_keys_pressed = true;
|
||||||
|
|
||||||
|
for (auto modifier : link.m_Chain)
|
||||||
{
|
{
|
||||||
all_keys_pressed = false;
|
if (!(GetAsyncKeyState(modifier) & 0x8000))
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (all_keys_pressed && std::chrono::system_clock::now() - m_LastHotkeyTriggerTime > 100ms)
|
|
||||||
{
|
|
||||||
auto command = Commands::GetCommand(hash);
|
|
||||||
if (command)
|
|
||||||
{
|
|
||||||
// TODO: this is the only way I can prevent chat from blocking the main loop while keeping everything else fast
|
|
||||||
if (hash != "chathelper"_J)
|
|
||||||
command->Call();
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
FiberPool::Push([command] {
|
all_keys_pressed = false;
|
||||||
command->Call();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_LastHotkeyTriggerTime = std::chrono::system_clock::now();
|
|
||||||
|
if (all_keys_pressed && std::chrono::system_clock::now() - m_LastHotkeyTriggerTime > 100ms)
|
||||||
|
{
|
||||||
|
auto command = Commands::GetCommand(hash);
|
||||||
|
if (command)
|
||||||
|
{
|
||||||
|
// TODO: this is the only way I can prevent chat from blocking the main loop while keeping everything else fast
|
||||||
|
if (hash != "chathelper"_J)
|
||||||
|
command->Call();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FiberPool::Push([command] {
|
||||||
|
command->Call();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_LastHotkeyTriggerTime = std::chrono::system_clock::now();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
ScriptMgr::Yield();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HotkeySystem::RunScript()
|
||||||
|
{
|
||||||
|
g_HotkeySystem.RunScriptImpl();
|
||||||
|
}
|
||||||
|
|
||||||
void HotkeySystem::SaveStateImpl(nlohmann::json& state)
|
void HotkeySystem::SaveStateImpl(nlohmann::json& state)
|
||||||
{
|
{
|
||||||
for (auto& hotkey : m_CommandHotkeys)
|
for (auto& hotkey : m_CommandHotkeys)
|
||||||
|
|||||||
@@ -26,7 +26,8 @@ namespace YimMenu
|
|||||||
std::string GetHotkeyLabel(int hotkey_modifiers);
|
std::string GetHotkeyLabel(int hotkey_modifiers);
|
||||||
void CreateHotkey(std::vector<int>& Hotkey);
|
void CreateHotkey(std::vector<int>& Hotkey);
|
||||||
|
|
||||||
void Update();
|
void RunScriptImpl();
|
||||||
|
static void RunScript();
|
||||||
|
|
||||||
virtual void SaveStateImpl(nlohmann::json& state) override;
|
virtual void SaveStateImpl(nlohmann::json& state) override;
|
||||||
virtual void LoadStateImpl(nlohmann::json& state) override;
|
virtual void LoadStateImpl(nlohmann::json& state) override;
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace YimMenu
|
|||||||
|
|
||||||
const char* LogSink::GetLevelStr(const eLogLevel level)
|
const char* LogSink::GetLevelStr(const eLogLevel level)
|
||||||
{
|
{
|
||||||
constexpr std::array<const char*, 4> levelStrings = {{{"DEBUG"}, {"INFO"}, {"WARN"}, {"ERROR"}}};
|
constexpr std::array<const char*, 4> levelStrings = {"DEBUG", "INFO", "WARN", "ERROR"};
|
||||||
|
|
||||||
return levelStrings[level];
|
return levelStrings[level];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,10 +31,12 @@ namespace YimMenu
|
|||||||
|
|
||||||
ImGui::DestroyContext();
|
ImGui::DestroyContext();
|
||||||
|
|
||||||
|
#if 0
|
||||||
// manually destroy the allocators we created for the rest of the frame contexts
|
// manually destroy the allocators we created for the rest of the frame contexts
|
||||||
for (size_t i = 1; i < m_SwapChainDesc.BufferCount; ++i)
|
for (size_t i = 1; i < m_SwapChainDesc.BufferCount; ++i)
|
||||||
if (m_FrameContext[i].CommandAllocator)
|
if (m_FrameContext[i].CommandAllocator)
|
||||||
m_FrameContext[i].CommandAllocator->Release();
|
m_FrameContext[i].CommandAllocator->Release();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Renderer::InitDX12()
|
bool Renderer::InitDX12()
|
||||||
|
|||||||
@@ -0,0 +1,113 @@
|
|||||||
|
#include "SavedLocations.hpp"
|
||||||
|
|
||||||
|
#include "core/filemgr/FileMgr.hpp"
|
||||||
|
#include "core/frontend/Notifications.hpp"
|
||||||
|
|
||||||
|
namespace YimMenu
|
||||||
|
{
|
||||||
|
std::filesystem::path SavedLocations::GetSavedLocationsFilePath()
|
||||||
|
{
|
||||||
|
return FileMgr::GetProjectFile("./saved_locations.json").Path();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<SavedLocation> SavedLocations::SavedLocationsFilteredListImpl(std::string filter)
|
||||||
|
{
|
||||||
|
std::vector<SavedLocation> filterList{};
|
||||||
|
|
||||||
|
static auto toLower = [=](std::string text) -> std::string {
|
||||||
|
std::transform(text.begin(), text.end(), text.begin(), ::tolower);
|
||||||
|
return text;
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto& location : m_AllSavedLocations | std::views::values | std::views::join)
|
||||||
|
if (toLower(location.name).find(toLower(filter)) != std::string::npos)
|
||||||
|
filterList.push_back(location);
|
||||||
|
|
||||||
|
return filterList;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SavedLocations::FetchSavedLocationsImpl()
|
||||||
|
{
|
||||||
|
m_AllSavedLocations.clear();
|
||||||
|
|
||||||
|
auto path = GetSavedLocationsFilePath();
|
||||||
|
std::ifstream file(path, std::ios::binary);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!file.is_open())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
nlohmann::json j;
|
||||||
|
file >> j;
|
||||||
|
m_AllSavedLocations = j.get<std::map<std::string, std::vector<SavedLocation>>>();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (const std::exception& e)
|
||||||
|
{
|
||||||
|
LOG(WARNING) << "Failed fetching saved locations: " << e.what() << '\n';
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SavedLocations::SaveNewLocationImpl(const std::string& category, SavedLocation t)
|
||||||
|
{
|
||||||
|
const auto& pair = m_AllSavedLocations.insert({category, {t}});
|
||||||
|
if (!pair.second)
|
||||||
|
{
|
||||||
|
pair.first->second.push_back(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto path = GetSavedLocationsFilePath();
|
||||||
|
|
||||||
|
std::ofstream fileOut(path, std::ofstream::trunc | std::ofstream::binary);
|
||||||
|
if (!fileOut.is_open())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
nlohmann::json j = m_AllSavedLocations;
|
||||||
|
fileOut << j.dump(4);
|
||||||
|
fileOut.close();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SavedLocations::DeleteSavedLocationImpl(const std::string& category, const std::string& locationName)
|
||||||
|
{
|
||||||
|
auto path = GetSavedLocationsFilePath();
|
||||||
|
|
||||||
|
const auto& it = m_AllSavedLocations.find(category);
|
||||||
|
if (it == m_AllSavedLocations.end())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
std::erase_if(it->second, [locationName](SavedLocation t) {
|
||||||
|
return t.name == locationName;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!it->second.size())
|
||||||
|
{
|
||||||
|
m_AllSavedLocations.erase(category);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ofstream fileOut(path, std::ofstream::trunc | std::ofstream::binary);
|
||||||
|
if (!fileOut.is_open())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
nlohmann::json j = m_AllSavedLocations;
|
||||||
|
fileOut << j.dump(4);
|
||||||
|
fileOut.close();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
SavedLocation* SavedLocations::GetSavedLocationByNameImpl(std::string name)
|
||||||
|
{
|
||||||
|
for (auto& loc : SavedLocationsFilteredList())
|
||||||
|
if (loc.name == name)
|
||||||
|
return &loc;
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace YimMenu
|
||||||
|
{
|
||||||
|
struct SavedLocation
|
||||||
|
{
|
||||||
|
std::string name;
|
||||||
|
float x, y, z;
|
||||||
|
float yaw = 0.0f, pitch = 0.0f, roll = 0.0f;
|
||||||
|
};
|
||||||
|
|
||||||
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(SavedLocation, name, x, y, z, yaw, pitch, roll);
|
||||||
|
|
||||||
|
class SavedLocations
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::filesystem::path GetSavedLocationsFilePath();
|
||||||
|
std::map<std::string, std::vector<SavedLocation>> m_AllSavedLocations;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool FetchSavedLocationsImpl();
|
||||||
|
bool SaveNewLocationImpl(const std::string& category, SavedLocation t);
|
||||||
|
bool DeleteSavedLocationImpl(const std::string& category, const std::string& location_name);
|
||||||
|
SavedLocation* GetSavedLocationByNameImpl(std::string);
|
||||||
|
std::vector<SavedLocation> SavedLocationsFilteredListImpl(std::string filter = "");
|
||||||
|
|
||||||
|
static SavedLocations& GetInstance()
|
||||||
|
{
|
||||||
|
static SavedLocations instance{};
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
static std::map<std::string, std::vector<SavedLocation>>& GetAllSavedLocations()
|
||||||
|
{
|
||||||
|
return GetInstance().m_AllSavedLocations;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool FetchSavedLocations()
|
||||||
|
{
|
||||||
|
return GetInstance().FetchSavedLocationsImpl();
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool SaveNewLocation(const std::string& category, SavedLocation t)
|
||||||
|
{
|
||||||
|
return GetInstance().SaveNewLocationImpl(category, t);
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool DeleteSavedLocation(const std::string& category, const std::string& location_name)
|
||||||
|
{
|
||||||
|
return GetInstance().DeleteSavedLocationImpl(category, location_name);
|
||||||
|
};
|
||||||
|
|
||||||
|
static SavedLocation* GetSavedLocationByName(std::string location_name)
|
||||||
|
{
|
||||||
|
return GetInstance().GetSavedLocationByNameImpl(location_name);
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::vector<SavedLocation> SavedLocationsFilteredList(std::string filter = "")
|
||||||
|
{
|
||||||
|
return GetInstance().SavedLocationsFilteredListImpl(filter);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
#include "core/commands/LoopedCommand.hpp"
|
||||||
|
#include "game/backend/Self.hpp"
|
||||||
|
#include "game/gta/Scripts.hpp"
|
||||||
|
#include "types/script/globals/GlobalPlayerBD.hpp"
|
||||||
|
|
||||||
|
namespace YimMenu::Features
|
||||||
|
{
|
||||||
|
class OffTheRadar : public LoopedCommand
|
||||||
|
{
|
||||||
|
using LoopedCommand::LoopedCommand;
|
||||||
|
|
||||||
|
virtual void OnTick() override
|
||||||
|
{
|
||||||
|
if (auto gpbd = GlobalPlayerBD::Get(); gpbd && Scripts::SafeToModifyFreemodeBroadcastGlobals())
|
||||||
|
gpbd->Entries[Self::GetPlayer().GetId()].OffRadarActive = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void OnDisable() override
|
||||||
|
{
|
||||||
|
if (auto gpbd = GlobalPlayerBD::Get(); gpbd && Scripts::SafeToModifyFreemodeBroadcastGlobals())
|
||||||
|
gpbd->Entries[Self::GetPlayer().GetId()].OffRadarActive = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static OffTheRadar _OffTheRadar{"otr", "Off The Radar", "Hides you from other players on the radar"};
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
#include "core/commands/Command.hpp"
|
||||||
|
#include "core/backend/ScriptMgr.hpp"
|
||||||
|
#include "game/backend/Self.hpp"
|
||||||
|
#include "game/gta/Natives.hpp"
|
||||||
|
#include "core/frontend/Notifications.hpp"
|
||||||
|
|
||||||
|
namespace YimMenu::Features
|
||||||
|
{
|
||||||
|
void ResolveZCoordinate(Vector3& vec)
|
||||||
|
{
|
||||||
|
constexpr float max_ground_check = 1000.f;
|
||||||
|
constexpr int max_attempts = 20;
|
||||||
|
float ground_z = vec.z;
|
||||||
|
int current_attempts = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
STREAMING::REQUEST_COLLISION_AT_COORD(vec.x, vec.y, vec.z);
|
||||||
|
|
||||||
|
float water_height;
|
||||||
|
if (WATER::GET_WATER_HEIGHT(vec.x, vec.y, vec.z, &water_height))
|
||||||
|
{
|
||||||
|
vec.z = water_height;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MISC::GET_GROUND_Z_FOR_3D_COORD(vec.x, vec.y, max_ground_check, &ground_z, false, false))
|
||||||
|
{
|
||||||
|
vec.z = ground_z + 1.0f;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current_attempts % 3 == 0)
|
||||||
|
{
|
||||||
|
ground_z += 25.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
++current_attempts;
|
||||||
|
ScriptMgr::Yield();
|
||||||
|
} while (current_attempts < max_attempts);
|
||||||
|
|
||||||
|
vec.z = PATHFIND::GET_APPROX_HEIGHT_FOR_POINT(vec.x, vec.y); // fallback value
|
||||||
|
}
|
||||||
|
|
||||||
|
class TpToWaypoint : public Command
|
||||||
|
{
|
||||||
|
using Command::Command;
|
||||||
|
|
||||||
|
virtual void OnCall() override
|
||||||
|
{
|
||||||
|
if (!HUD::IS_WAYPOINT_ACTIVE())
|
||||||
|
Notifications::Show("Teleport", "No waypoint set", NotificationType::Warning);
|
||||||
|
|
||||||
|
auto coords = HUD::GET_BLIP_COORDS(HUD::GET_CLOSEST_BLIP_INFO_ID(HUD::GET_WAYPOINT_BLIP_ENUM_ID()));
|
||||||
|
ResolveZCoordinate(coords);
|
||||||
|
Self::GetPed().TeleportTo(coords);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static TpToWaypoint _TpToWaypoint{"tptowaypoint", "Teleport to Waypoint", "Teleports you to the waypoint"};
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
#include "core/commands/LoopedCommand.hpp"
|
||||||
|
#include "game/backend/Self.hpp"
|
||||||
|
|
||||||
|
namespace YimMenu::Features
|
||||||
|
{
|
||||||
|
class KeepFixed : public LoopedCommand
|
||||||
|
{
|
||||||
|
using LoopedCommand::LoopedCommand;
|
||||||
|
|
||||||
|
virtual void OnTick() override
|
||||||
|
{
|
||||||
|
auto veh = Self::GetVehicle();
|
||||||
|
if (veh)
|
||||||
|
veh.Fix();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static KeepFixed _KeepFixed{"keepfixed", "Keep Vehicle Fixed", "Keeps your vehicle clean and fixed"};
|
||||||
|
}
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
#include "core/commands/LoopedCommand.hpp"
|
||||||
|
#include "game/backend/Self.hpp"
|
||||||
|
#include "game/gta/Natives.hpp"
|
||||||
|
|
||||||
|
namespace YimMenu::Features
|
||||||
|
{
|
||||||
|
class Speedometer : public LoopedCommand
|
||||||
|
{
|
||||||
|
using LoopedCommand::LoopedCommand;
|
||||||
|
int m_ScaleformHandle{};
|
||||||
|
|
||||||
|
bool EnsureScaleformLoaded()
|
||||||
|
{
|
||||||
|
if (m_ScaleformHandle && GRAPHICS::HAS_SCALEFORM_MOVIE_LOADED(m_ScaleformHandle))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!m_ScaleformHandle)
|
||||||
|
m_ScaleformHandle = GRAPHICS::REQUEST_SCALEFORM_MOVIE("DRAG_RACE");
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetVehicleSpeed(Vehicle veh)
|
||||||
|
{
|
||||||
|
auto speed = veh.GetSpeed();
|
||||||
|
|
||||||
|
if (MISC::SHOULD_USE_METRIC_MEASUREMENTS())
|
||||||
|
return speed * 3.6f;
|
||||||
|
else
|
||||||
|
return speed * 2.23694f;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void OnTick() override
|
||||||
|
{
|
||||||
|
auto veh = Self::GetVehicle();
|
||||||
|
|
||||||
|
if (!veh || !EnsureScaleformLoaded() || STREAMING::IS_PLAYER_SWITCH_IN_PROGRESS())
|
||||||
|
return;
|
||||||
|
|
||||||
|
GRAPHICS::BEGIN_SCALEFORM_MOVIE_METHOD(m_ScaleformHandle, "SET_GEAR");
|
||||||
|
GRAPHICS::SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(veh.GetGear());
|
||||||
|
GRAPHICS::END_SCALEFORM_MOVIE_METHOD();
|
||||||
|
GRAPHICS::BEGIN_SCALEFORM_MOVIE_METHOD(m_ScaleformHandle, "SET_SPEED");
|
||||||
|
GRAPHICS::SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(GetVehicleSpeed(veh));
|
||||||
|
GRAPHICS::END_SCALEFORM_MOVIE_METHOD();
|
||||||
|
GRAPHICS::BEGIN_SCALEFORM_MOVIE_METHOD(m_ScaleformHandle, "SET_SPEED_UNITS");
|
||||||
|
GRAPHICS::BEGIN_TEXT_COMMAND_SCALEFORM_STRING("STRING");
|
||||||
|
HUD::ADD_TEXT_COMPONENT_SUBSTRING_PLAYER_NAME(MISC::SHOULD_USE_METRIC_MEASUREMENTS() ? "KPH" : "MPH");
|
||||||
|
GRAPHICS::END_TEXT_COMMAND_SCALEFORM_STRING();
|
||||||
|
GRAPHICS::BEGIN_SCALEFORM_MOVIE_METHOD(m_ScaleformHandle, "SET_METER_VALUE");
|
||||||
|
GRAPHICS::SCALEFORM_MOVIE_METHOD_ADD_PARAM_FLOAT(veh.GetSpeed() * 2000);
|
||||||
|
GRAPHICS::END_SCALEFORM_MOVIE_METHOD();
|
||||||
|
GRAPHICS::BEGIN_SCALEFORM_MOVIE_METHOD(m_ScaleformHandle, "SET_OUTER_GOAL");
|
||||||
|
GRAPHICS::SCALEFORM_MOVIE_METHOD_ADD_PARAM_FLOAT(-1.0f);
|
||||||
|
GRAPHICS::SCALEFORM_MOVIE_METHOD_ADD_PARAM_FLOAT(-1.0f);
|
||||||
|
GRAPHICS::END_SCALEFORM_MOVIE_METHOD();
|
||||||
|
GRAPHICS::BEGIN_SCALEFORM_MOVIE_METHOD(m_ScaleformHandle, "SET_INNER_GOAL");
|
||||||
|
GRAPHICS::SCALEFORM_MOVIE_METHOD_ADD_PARAM_FLOAT(-1.0f);
|
||||||
|
GRAPHICS::SCALEFORM_MOVIE_METHOD_ADD_PARAM_FLOAT(-1.0f);
|
||||||
|
GRAPHICS::END_SCALEFORM_MOVIE_METHOD();
|
||||||
|
GRAPHICS::BEGIN_SCALEFORM_MOVIE_METHOD(m_ScaleformHandle, "SET_SCREEN_POSITION");
|
||||||
|
GRAPHICS::SCALEFORM_MOVIE_METHOD_ADD_PARAM_FLOAT(1.0f);
|
||||||
|
GRAPHICS::SCALEFORM_MOVIE_METHOD_ADD_PARAM_FLOAT(0.85f);
|
||||||
|
GRAPHICS::END_SCALEFORM_MOVIE_METHOD();
|
||||||
|
GRAPHICS::BEGIN_SCALEFORM_MOVIE_METHOD(m_ScaleformHandle, "SET_IS_DRIFT_RACE");
|
||||||
|
GRAPHICS::SCALEFORM_MOVIE_METHOD_ADD_PARAM_BOOL(false);
|
||||||
|
GRAPHICS::END_SCALEFORM_MOVIE_METHOD();
|
||||||
|
GRAPHICS::DRAW_SCALEFORM_MOVIE_FULLSCREEN(m_ScaleformHandle, 255, 255, 255, 255, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void OnDisable() override
|
||||||
|
{
|
||||||
|
GRAPHICS::SET_SCALEFORM_MOVIE_AS_NO_LONGER_NEEDED(&m_ScaleformHandle);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static Speedometer _Speedometer{"speedometer", "Speedometer", "Shows a speedometer whenever you are in a vehicle"};
|
||||||
|
}
|
||||||
@@ -8,8 +8,10 @@
|
|||||||
#include "game/frontend/fonts/Fonts.hpp"
|
#include "game/frontend/fonts/Fonts.hpp"
|
||||||
#include "game/pointers/Pointers.hpp"
|
#include "game/pointers/Pointers.hpp"
|
||||||
#include "submenus/Self.hpp"
|
#include "submenus/Self.hpp"
|
||||||
|
#include "submenus/Teleport.hpp"
|
||||||
#include "submenus/Network.hpp"
|
#include "submenus/Network.hpp"
|
||||||
#include "submenus/Players.hpp"
|
#include "submenus/Players.hpp"
|
||||||
|
#include "submenus/Settings.hpp"
|
||||||
|
|
||||||
namespace YimMenu
|
namespace YimMenu
|
||||||
{
|
{
|
||||||
@@ -17,8 +19,10 @@ namespace YimMenu
|
|||||||
{
|
{
|
||||||
// Arguably the only place this file should be edited at for more menus
|
// Arguably the only place this file should be edited at for more menus
|
||||||
UIManager::AddSubmenu(std::make_shared<Submenus::Self>());
|
UIManager::AddSubmenu(std::make_shared<Submenus::Self>());
|
||||||
|
UIManager::AddSubmenu(std::make_shared<Submenus::Teleport>());
|
||||||
UIManager::AddSubmenu(std::make_shared<Submenus::Network>());
|
UIManager::AddSubmenu(std::make_shared<Submenus::Network>());
|
||||||
UIManager::AddSubmenu(std::make_shared<Submenus::Players>());
|
UIManager::AddSubmenu(std::make_shared<Submenus::Players>());
|
||||||
|
UIManager::AddSubmenu(std::make_shared<Submenus::Settings>());
|
||||||
|
|
||||||
Renderer::AddRendererCallBack(
|
Renderer::AddRendererCallBack(
|
||||||
[&] {
|
[&] {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "core/commands/BoolCommand.hpp"
|
#include "core/commands/BoolCommand.hpp"
|
||||||
#include "game/pointers/Pointers.hpp"
|
#include "game/pointers/Pointers.hpp"
|
||||||
#include "game/gta/invoker/Invoker.hpp"
|
#include "game/gta/invoker/Invoker.hpp"
|
||||||
|
#include "game/gta/Natives.hpp"
|
||||||
|
|
||||||
namespace YimMenu::Features
|
namespace YimMenu::Features
|
||||||
{
|
{
|
||||||
@@ -14,7 +15,6 @@ namespace YimMenu
|
|||||||
{
|
{
|
||||||
void Overlay::Draw()
|
void Overlay::Draw()
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
if (!Features::_OverlayEnabled.GetState() || !NativeInvoker::AreHandlersCached())
|
if (!Features::_OverlayEnabled.GetState() || !NativeInvoker::AreHandlersCached())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -31,6 +31,5 @@ namespace YimMenu
|
|||||||
ImGui::PopFont();
|
ImGui::PopFont();
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,8 +2,9 @@
|
|||||||
#include "core/commands/Command.hpp"
|
#include "core/commands/Command.hpp"
|
||||||
#include "core/commands/Commands.hpp"
|
#include "core/commands/Commands.hpp"
|
||||||
#include "core/commands/Vector3Command.hpp"
|
#include "core/commands/Vector3Command.hpp"
|
||||||
//#include "game/backend/SavedLocations.hpp"
|
#include "game/backend/SavedLocations.hpp"
|
||||||
//#include "game/backend/Self.hpp"
|
#include "game/backend/Self.hpp"
|
||||||
|
#include "game/pointers/Pointers.hpp"
|
||||||
|
|
||||||
namespace YimMenu
|
namespace YimMenu
|
||||||
{
|
{
|
||||||
@@ -26,7 +27,7 @@ namespace YimMenu
|
|||||||
ImGui::SetNextItemWidth(180);
|
ImGui::SetNextItemWidth(180);
|
||||||
if (ImGui::InputFloat3("##coord_inp", &value.x, "%.1f"))
|
if (ImGui::InputFloat3("##coord_inp", &value.x, "%.1f"))
|
||||||
m_Command->SetState(value);
|
m_Command->SetState(value);
|
||||||
#if 0
|
|
||||||
if (Self::GetPed())
|
if (Self::GetPed())
|
||||||
{
|
{
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
@@ -90,7 +91,7 @@ namespace YimMenu
|
|||||||
if (ImGui::IsItemHovered() && l.name.length() > 27)
|
if (ImGui::IsItemHovered() && l.name.length() > 27)
|
||||||
{
|
{
|
||||||
ImGui::BeginTooltip();
|
ImGui::BeginTooltip();
|
||||||
ImGui::Text(l.name.data());
|
ImGui::Text("%s", l.name.data());
|
||||||
ImGui::EndTooltip();
|
ImGui::EndTooltip();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -108,7 +109,6 @@ namespace YimMenu
|
|||||||
|
|
||||||
ImGui::EndPopup();
|
ImGui::EndPopup();
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
auto& label = m_LabelOverride.has_value() ? m_LabelOverride.value() : m_Command->GetLabel();
|
auto& label = m_LabelOverride.has_value() ? m_LabelOverride.value() : m_Command->GetLabel();
|
||||||
if (!label.empty())
|
if (!label.empty())
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ namespace YimMenu::Submenus
|
|||||||
if (player.GetPed() && player.GetPed().IsInvincible())
|
if (player.GetPed() && player.GetPed().IsInvincible())
|
||||||
tags.push_back({"GOD", ImGui::Colors::Crimson});
|
tags.push_back({"GOD", ImGui::Colors::Crimson});
|
||||||
|
|
||||||
if (player.GetPed() && !player.GetPed().IsVisible())
|
if (player.GetPed() && !player.GetPed().IsVisible() && false) // doesn't really seem to work on GTA
|
||||||
tags.push_back({"INVIS", ImGui::Colors::MediumPurple});
|
tags.push_back({"INVIS", ImGui::Colors::MediumPurple});
|
||||||
|
|
||||||
return tags;
|
return tags;
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ namespace YimMenu::Submenus
|
|||||||
|
|
||||||
globalsGroup->AddItem(std::make_shared<BoolCommandItem>("godmode"_J));
|
globalsGroup->AddItem(std::make_shared<BoolCommandItem>("godmode"_J));
|
||||||
globalsGroup->AddItem(std::make_shared<BoolCommandItem>("invis"_J));
|
globalsGroup->AddItem(std::make_shared<BoolCommandItem>("invis"_J));
|
||||||
|
globalsGroup->AddItem(std::make_shared<BoolCommandItem>("otr"_J));
|
||||||
|
|
||||||
toolsGroup->AddItem(std::make_shared<CommandItem>("suicide"_J));
|
toolsGroup->AddItem(std::make_shared<CommandItem>("suicide"_J));
|
||||||
|
|
||||||
@@ -50,12 +51,16 @@ namespace YimMenu::Submenus
|
|||||||
|
|
||||||
auto vehicle = std::make_shared<Category>("Vehicle");
|
auto vehicle = std::make_shared<Category>("Vehicle");
|
||||||
auto vehicleGlobalsGroup = std::make_shared<Group>("Globals");
|
auto vehicleGlobalsGroup = std::make_shared<Group>("Globals");
|
||||||
|
auto vehicleMiscGroup = std::make_shared<Group>("Misc");
|
||||||
|
|
||||||
vehicleGlobalsGroup->AddItem(std::make_shared<BoolCommandItem>("vehiclegodmode"_J));
|
vehicleGlobalsGroup->AddItem(std::make_shared<BoolCommandItem>("vehiclegodmode"_J, "Godmode"));
|
||||||
|
vehicleGlobalsGroup->AddItem(std::make_shared<BoolCommandItem>("keepfixed"_J, "Keep Fixed"));
|
||||||
vehicleGlobalsGroup->AddItem(std::make_shared<CommandItem>("repairvehicle"_J));
|
vehicleGlobalsGroup->AddItem(std::make_shared<CommandItem>("repairvehicle"_J));
|
||||||
|
|
||||||
|
|
||||||
|
vehicleMiscGroup->AddItem(std::make_shared<BoolCommandItem>("speedometer"_J));
|
||||||
|
|
||||||
vehicle->AddItem(vehicleGlobalsGroup);
|
vehicle->AddItem(vehicleGlobalsGroup);
|
||||||
|
vehicle->AddItem(vehicleMiscGroup);
|
||||||
AddCategory(std::move(vehicle));
|
AddCategory(std::move(vehicle));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
#include "Settings.hpp"
|
||||||
|
|
||||||
|
#include "core/commands/Commands.hpp"
|
||||||
|
#include "core/commands/HotkeySystem.hpp"
|
||||||
|
#include "core/commands/LoopedCommand.hpp"
|
||||||
|
#include "game/backend/Self.hpp"
|
||||||
|
#include "game/frontend/items/Items.hpp"
|
||||||
|
|
||||||
|
namespace YimMenu::Submenus
|
||||||
|
{
|
||||||
|
// TODO: refactor this
|
||||||
|
static void Hotkeys()
|
||||||
|
{
|
||||||
|
ImGui::BulletText("Hold the command name clicked to change its hotkey");
|
||||||
|
ImGui::BulletText("Press any registered key to remove");
|
||||||
|
|
||||||
|
ImGui::Spacing();
|
||||||
|
ImGui::Separator();
|
||||||
|
ImGui::Spacing();
|
||||||
|
|
||||||
|
for (auto& [Hash, Command] : Commands::GetCommands())
|
||||||
|
{
|
||||||
|
ImGui::PushID(Hash);
|
||||||
|
|
||||||
|
if (g_HotkeySystem.m_CommandHotkeys.find(Hash) != g_HotkeySystem.m_CommandHotkeys.end())
|
||||||
|
HotkeySetter(Hash).Draw();
|
||||||
|
|
||||||
|
ImGui::Spacing();
|
||||||
|
|
||||||
|
ImGui::PopID();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Settings::Settings() :
|
||||||
|
Submenu::Submenu("Settings")
|
||||||
|
{
|
||||||
|
auto hotkeys = std::make_shared<Category>("Hotkeys");
|
||||||
|
auto gui = std::make_shared<Category>("GUI");
|
||||||
|
auto overlay = std::make_shared<Group>("Overlay");
|
||||||
|
|
||||||
|
hotkeys->AddItem(std::make_shared<ImGuiItem>(Hotkeys));
|
||||||
|
|
||||||
|
overlay->AddItem(std::make_shared<BoolCommandItem>("overlay"_J));
|
||||||
|
overlay->AddItem(std::make_shared<ConditionalItem>("overlay"_J, std::make_shared<BoolCommandItem>("overlayfps"_J)));
|
||||||
|
|
||||||
|
gui->AddItem(overlay);
|
||||||
|
|
||||||
|
AddCategory(std::move(hotkeys));
|
||||||
|
AddCategory(std::move(gui));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "core/frontend/manager/UIManager.hpp"
|
||||||
|
|
||||||
|
namespace YimMenu::Submenus
|
||||||
|
{
|
||||||
|
class Settings : public Submenu
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Settings();
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,192 @@
|
|||||||
|
#include "Teleport.hpp"
|
||||||
|
|
||||||
|
#include "core/frontend/Notifications.hpp"
|
||||||
|
#include "core/backend/FiberPool.hpp"
|
||||||
|
#include "game/backend/SavedLocations.hpp"
|
||||||
|
#include "game/backend/Self.hpp"
|
||||||
|
#include "game/frontend/items/Items.hpp"
|
||||||
|
|
||||||
|
namespace YimMenu::Submenus
|
||||||
|
{
|
||||||
|
static float GetDistanceFromLocation(const SavedLocation& t)
|
||||||
|
{
|
||||||
|
return rage::fvector3(t.x, t.y, t.z).GetDistance(Self::GetPed().GetPosition());
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderCustomTeleport()
|
||||||
|
{
|
||||||
|
ImGui::BeginGroup();
|
||||||
|
static std::string newLocationName{};
|
||||||
|
static std::string category = "Default";
|
||||||
|
static SavedLocation locationToDelete;
|
||||||
|
|
||||||
|
if (!std::string(locationToDelete.name).empty())
|
||||||
|
ImGui::OpenPopup("##deletelocation");
|
||||||
|
|
||||||
|
if (ImGui::BeginPopupModal("##deletelocation", nullptr, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove))
|
||||||
|
{
|
||||||
|
ImGui::Text("Are you sure you want to delete %s?", locationToDelete.name.data());
|
||||||
|
|
||||||
|
ImGui::Spacing();
|
||||||
|
|
||||||
|
if (ImGui::Button("Yes"))
|
||||||
|
{
|
||||||
|
SavedLocations::DeleteSavedLocation(category, locationToDelete.name);
|
||||||
|
locationToDelete.name = "";
|
||||||
|
ImGui::CloseCurrentPopup();
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button("No"))
|
||||||
|
{
|
||||||
|
locationToDelete.name = "";
|
||||||
|
ImGui::CloseCurrentPopup();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::PushItemWidth(300);
|
||||||
|
InputTextWithHint("Category", "Category", &category).Draw();
|
||||||
|
|
||||||
|
ImGui::PushItemWidth(200);
|
||||||
|
InputTextWithHint("Location name", "New location", &newLocationName).Draw();
|
||||||
|
ImGui::PopItemWidth();
|
||||||
|
|
||||||
|
if (ImGui::Button("Save current location")) // Button widget still crashes
|
||||||
|
{
|
||||||
|
FiberPool::Push([=] {
|
||||||
|
if (newLocationName.empty())
|
||||||
|
{
|
||||||
|
Notifications::Show("Custom Teleport", "Please enter a valid name", NotificationType::Warning);
|
||||||
|
}
|
||||||
|
else if (SavedLocations::GetSavedLocationByName(newLocationName))
|
||||||
|
{
|
||||||
|
Notifications::Show("Custom Teleport", std::format("Location with name {} already exists", newLocationName));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SavedLocation teleportLocation;
|
||||||
|
Entity teleportEntity = Self::GetPed();
|
||||||
|
if (auto vehicle = Self::GetVehicle())
|
||||||
|
teleportEntity = vehicle;
|
||||||
|
|
||||||
|
auto coords = teleportEntity.GetPosition();
|
||||||
|
teleportLocation.name = newLocationName;
|
||||||
|
teleportLocation.x = coords.x;
|
||||||
|
teleportLocation.y = coords.y;
|
||||||
|
teleportLocation.z = coords.z;
|
||||||
|
teleportLocation.yaw = teleportEntity.GetHeading();
|
||||||
|
teleportLocation.pitch = 0.0f; // why do we need pitch and roll anyway?
|
||||||
|
teleportLocation.roll = 0.0f;
|
||||||
|
SavedLocations::SaveNewLocation(category, teleportLocation);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
|
ImGui::Text("Double click to teleport\nShift click to delete");
|
||||||
|
|
||||||
|
ImGui::Spacing();
|
||||||
|
|
||||||
|
static std::string filter{};
|
||||||
|
InputTextWithHint("##filter", "Search", &filter).Draw();
|
||||||
|
|
||||||
|
ImGui::BeginGroup();
|
||||||
|
ImGui::Text("Categories");
|
||||||
|
if (ImGui::BeginListBox("##categories", {200, -1}))
|
||||||
|
{
|
||||||
|
for (auto& l : SavedLocations::GetAllSavedLocations() | std::ranges::views::keys)
|
||||||
|
{
|
||||||
|
if (ImGui::Selectable(l.data(), l == category))
|
||||||
|
{
|
||||||
|
category = l;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (category.empty())
|
||||||
|
{
|
||||||
|
category = l;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndListBox();
|
||||||
|
}
|
||||||
|
ImGui::EndGroup();
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::BeginGroup();
|
||||||
|
ImGui::Text("Locations");
|
||||||
|
if (ImGui::BeginListBox("##saved_locs", {200, -1})) // Need automatic dimensions instead of hard coded
|
||||||
|
{
|
||||||
|
if (SavedLocations::GetAllSavedLocations().find(category) != SavedLocations::GetAllSavedLocations().end())
|
||||||
|
{
|
||||||
|
std::vector<SavedLocation> current_list{};
|
||||||
|
|
||||||
|
if (!filter.empty())
|
||||||
|
current_list = SavedLocations::SavedLocationsFilteredList(filter);
|
||||||
|
else
|
||||||
|
current_list = SavedLocations::GetAllSavedLocations().at(category);
|
||||||
|
|
||||||
|
for (const auto& l : current_list)
|
||||||
|
{
|
||||||
|
if (ImGui::Selectable(l.name.data(), false, ImGuiSelectableFlags_AllowDoubleClick))
|
||||||
|
{
|
||||||
|
if (GetAsyncKeyState(VK_SHIFT) & 0x8000)
|
||||||
|
{
|
||||||
|
locationToDelete = l;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ImGui::IsMouseDoubleClicked(0))
|
||||||
|
{
|
||||||
|
FiberPool::Push([l] {
|
||||||
|
rage::fvector3 l_ = {l.x, l.y, l.z};
|
||||||
|
Self::GetPed().TeleportTo(l_);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::IsItemHovered())
|
||||||
|
{
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
if (l.name.length() > 27)
|
||||||
|
ImGui::Text("%s", l.name.data());
|
||||||
|
ImGui::Text("Distance: %f", GetDistanceFromLocation(l));
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::EndListBox();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::EndGroup();
|
||||||
|
|
||||||
|
ImGui::EndGroup();
|
||||||
|
}
|
||||||
|
|
||||||
|
Teleport::Teleport() :
|
||||||
|
Submenu::Submenu("Teleport")
|
||||||
|
{
|
||||||
|
auto main = std::make_shared<Category>("Main");
|
||||||
|
auto miscGroup = std::make_shared<Group>("Misc");
|
||||||
|
|
||||||
|
// miscGroup->AddItem(std::make_shared<BoolCommandItem>("autotp"_J));
|
||||||
|
miscGroup->AddItem(std::make_shared<CommandItem>("tptowaypoint"_J));
|
||||||
|
// miscGroup->AddItem(std::make_shared<CommandItem>("tptomount"_J));
|
||||||
|
// miscGroup->AddItem(std::make_shared<CommandItem>("tptotraintrack"_J));
|
||||||
|
// miscGroup->AddItem(std::make_shared<CommandItem>("tptomoonshineshack"_J));
|
||||||
|
// miscGroup->AddItem(std::make_shared<CommandItem>("tptonazar"_J));
|
||||||
|
|
||||||
|
main->AddItem(miscGroup);
|
||||||
|
|
||||||
|
auto customteleport = std::make_shared<Category>("Saved");
|
||||||
|
customteleport->AddItem(std::make_shared<ImGuiItem>([] {
|
||||||
|
RenderCustomTeleport();
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
AddCategory(std::move(main));
|
||||||
|
AddCategory(std::move(customteleport));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "core/frontend/manager/UIManager.hpp"
|
||||||
|
|
||||||
|
namespace YimMenu::Submenus
|
||||||
|
{
|
||||||
|
class Teleport : public Submenu
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Teleport();
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -155,6 +155,25 @@ namespace YimMenu
|
|||||||
ENTITY::SET_ENTITY_VELOCITY(GetHandle(), vel.x, vel.y, vel.z);
|
ENTITY::SET_ENTITY_VELOCITY(GetHandle(), vel.x, vel.y, vel.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float Entity::GetHeading()
|
||||||
|
{
|
||||||
|
ENTITY_ASSERT_VALID();
|
||||||
|
return ENTITY::GET_ENTITY_HEADING(GetHandle());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entity::SetHeading(float heading)
|
||||||
|
{
|
||||||
|
ENTITY_ASSERT_VALID();
|
||||||
|
ENTITY_ASSERT_CONTROL();
|
||||||
|
ENTITY::SET_ENTITY_HEADING(GetHandle(), heading);
|
||||||
|
}
|
||||||
|
|
||||||
|
float Entity::GetSpeed()
|
||||||
|
{
|
||||||
|
ENTITY_ASSERT_VALID();
|
||||||
|
return ENTITY::GET_ENTITY_SPEED(GetHandle());
|
||||||
|
}
|
||||||
|
|
||||||
void Entity::SetCollision(bool enabled)
|
void Entity::SetCollision(bool enabled)
|
||||||
{
|
{
|
||||||
ENTITY_ASSERT_VALID();
|
ENTITY_ASSERT_VALID();
|
||||||
|
|||||||
@@ -101,6 +101,9 @@ namespace YimMenu
|
|||||||
void SetRotation(rage::fvector3 rotation, int order = 2);
|
void SetRotation(rage::fvector3 rotation, int order = 2);
|
||||||
rage::fvector3 GetVelocity();
|
rage::fvector3 GetVelocity();
|
||||||
void SetVelocity(rage::fvector3 velocity);
|
void SetVelocity(rage::fvector3 velocity);
|
||||||
|
float GetHeading();
|
||||||
|
void SetHeading(float heading);
|
||||||
|
float GetSpeed();
|
||||||
|
|
||||||
// physical
|
// physical
|
||||||
void SetCollision(bool enabled);
|
void SetCollision(bool enabled);
|
||||||
|
|||||||
+14
-1
@@ -51,7 +51,9 @@ namespace YimMenu
|
|||||||
Vehicle Ped::GetVehicle()
|
Vehicle Ped::GetVehicle()
|
||||||
{
|
{
|
||||||
ENTITY_ASSERT_VALID();
|
ENTITY_ASSERT_VALID();
|
||||||
return Vehicle(PED::GET_VEHICLE_PED_IS_IN(GetHandle(), true));
|
if (!PED::IS_PED_IN_ANY_VEHICLE(GetHandle(), false))
|
||||||
|
return nullptr;
|
||||||
|
return Vehicle(PED::GET_VEHICLE_PED_IS_USING(GetHandle()));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Ped::GetRagdoll()
|
bool Ped::GetRagdoll()
|
||||||
@@ -139,4 +141,15 @@ namespace YimMenu
|
|||||||
|
|
||||||
WEAPON::SET_PED_INFINITE_AMMO_CLIP(GetHandle(), infinite); // is this networked?
|
WEAPON::SET_PED_INFINITE_AMMO_CLIP(GetHandle(), infinite); // is this networked?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Ped::TeleportTo(const rage::fvector3& pos)
|
||||||
|
{
|
||||||
|
ENTITY_ASSERT_VALID();
|
||||||
|
ENTITY_ASSERT_CONTROL();
|
||||||
|
|
||||||
|
if (auto veh = GetVehicle())
|
||||||
|
veh.SetPosition(pos);
|
||||||
|
else
|
||||||
|
SetPosition(pos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -40,5 +40,8 @@ namespace YimMenu
|
|||||||
// weapons
|
// weapons
|
||||||
void SetInfiniteAmmo(bool infinite);
|
void SetInfiniteAmmo(bool infinite);
|
||||||
void SetInfiniteClip(bool infinite);
|
void SetInfiniteClip(bool infinite);
|
||||||
|
|
||||||
|
// teleport
|
||||||
|
void TeleportTo(const rage::fvector3& pos); // similar to SetPosition, but handles vehicles correctly
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -5,6 +5,8 @@
|
|||||||
#include "types/script/GtaThread.hpp"
|
#include "types/script/GtaThread.hpp"
|
||||||
#include "types/script/CGameScriptHandler.hpp"
|
#include "types/script/CGameScriptHandler.hpp"
|
||||||
#include "types/script/CGameScriptId.hpp"
|
#include "types/script/CGameScriptId.hpp"
|
||||||
|
#include "types/script/globals/GlobalPlayerBD.hpp"
|
||||||
|
#include "game/backend/Self.hpp"
|
||||||
|
|
||||||
namespace YimMenu::Scripts
|
namespace YimMenu::Scripts
|
||||||
{
|
{
|
||||||
@@ -59,4 +61,20 @@ namespace YimMenu::Scripts
|
|||||||
thread->m_ScriptHandler->GetId()->m_Hash = *hash_4;
|
thread->m_ScriptHandler->GetId()->m_Hash = *hash_4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SafeToModifyFreemodeBroadcastGlobals()
|
||||||
|
{
|
||||||
|
if (!*Pointers.IsSessionStarted)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!FindScriptThread("freemode"_J))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (auto gpbd = GlobalPlayerBD::Get())
|
||||||
|
{
|
||||||
|
return gpbd->Entries[Self::GetPlayer().GetId()].FreemodeState == eFreemodeState::RUNNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -12,4 +12,5 @@ namespace YimMenu::Scripts
|
|||||||
extern rage::scrThread* FindScriptThread(joaat_t hash);
|
extern rage::scrThread* FindScriptThread(joaat_t hash);
|
||||||
extern void RunAsScript(rage::scrThread* thread, std::function<void()> callback);
|
extern void RunAsScript(rage::scrThread* thread, std::function<void()> callback);
|
||||||
extern void RunWithSpoofedThreadName(std::uint32_t name, std::function<void()> callback); // consider using RunAsScript if possible
|
extern void RunWithSpoofedThreadName(std::uint32_t name, std::function<void()> callback); // consider using RunAsScript if possible
|
||||||
|
extern bool SafeToModifyFreemodeBroadcastGlobals(); // TODO: find a better method for this that works for all scripts
|
||||||
}
|
}
|
||||||
@@ -57,4 +57,25 @@ namespace YimMenu
|
|||||||
VEHICLE::SET_VEHICLE_DIRT_LEVEL(GetHandle(), 0);
|
VEHICLE::SET_VEHICLE_DIRT_LEVEL(GetHandle(), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Vehicle::GetGear()
|
||||||
|
{
|
||||||
|
ENTITY_ASSERT_VALID();
|
||||||
|
|
||||||
|
return VEHICLE::_GET_VEHICLE_CURRENT_DRIVE_GEAR(GetHandle());
|
||||||
|
}
|
||||||
|
|
||||||
|
float Vehicle::GetRevRatio()
|
||||||
|
{
|
||||||
|
ENTITY_ASSERT_VALID();
|
||||||
|
|
||||||
|
return VEHICLE::_GET_VEHICLE_CURRENT_REV_RATIO(GetHandle());
|
||||||
|
}
|
||||||
|
|
||||||
|
float Vehicle::GetMaxSpeed()
|
||||||
|
{
|
||||||
|
ENTITY_ASSERT_VALID();
|
||||||
|
|
||||||
|
return VEHICLE::GET_VEHICLE_ESTIMATED_MAX_SPEED(GetHandle());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -11,5 +11,12 @@ namespace YimMenu
|
|||||||
static Vehicle Create(std::uint32_t model, rage::fvector3 coords, float heading = 0.0f);
|
static Vehicle Create(std::uint32_t model, rage::fvector3 coords, float heading = 0.0f);
|
||||||
|
|
||||||
void Fix();
|
void Fix();
|
||||||
|
|
||||||
|
// gears
|
||||||
|
int GetGear();
|
||||||
|
float GetRevRatio(); // doesn't work
|
||||||
|
|
||||||
|
// speed
|
||||||
|
float GetMaxSpeed();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -43,6 +43,7 @@ namespace YimMenu
|
|||||||
|
|
||||||
ScriptMgr::AddScript(std::make_unique<Script>(&Self::RunScript));
|
ScriptMgr::AddScript(std::make_unique<Script>(&Self::RunScript));
|
||||||
FiberPool::Init(5);
|
FiberPool::Init(5);
|
||||||
|
ScriptMgr::AddScript(std::make_unique<Script>(&HotkeySystem::RunScript));
|
||||||
ScriptMgr::AddScript(std::make_unique<Script>(&Commands::RunScript));
|
ScriptMgr::AddScript(std::make_unique<Script>(&Commands::RunScript));
|
||||||
|
|
||||||
Notifications::Show("YimMenuV2", "Loaded succesfully", NotificationType::Success);
|
Notifications::Show("YimMenuV2", "Loaded succesfully", NotificationType::Success);
|
||||||
|
|||||||
Reference in New Issue
Block a user