Refactor of Player Wanted Level (#3070)

This commit is contained in:
R.K 2024-05-08 01:24:00 -07:00 committed by GitHub
parent 499fc6b906
commit 1b82c94d4d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 124 additions and 93 deletions

View File

@ -54,7 +54,7 @@ namespace big
while (g_running)
{
looped::self_police();
looped::self_wanted();
looped::self_hud();
looped::self_dance_mode();
looped::self_persist_outfit();

View File

@ -1,22 +0,0 @@
#include "backend/command.hpp"
#include "natives.hpp"
namespace big
{
class clear_wanted : command
{
using command::command;
virtual void execute(const command_arguments&, const std::shared_ptr<command_context> ctx) override
{
if(g_local_player && g_local_player !=nullptr && !g.self.force_wanted_level)
{
g_local_player->m_player_info->m_wanted_level = 0;
g.self.wanted_level = 0;
g_local_player->m_player_info->m_is_wanted = false;
}
}
};
clear_wanted g_clear_wanted("clearwantedlvl", "CLEAR_WANTED_LEVEL", "CLEAR_WANTED_LEVEL_DESC_SELF", 0);
}

View File

@ -25,7 +25,7 @@ namespace big
static void player_spectate();
static void player_remote_control_vehicle();
static void self_police();
static void self_wanted();
static void self_hud();
static void self_dance_mode();
static void self_persist_outfit();

View File

@ -1,33 +0,0 @@
#include "backend/looped/looped.hpp"
#include "pointers.hpp"
#include "util/police.hpp"
namespace big
{
void looped::self_police()
{
if (g_local_player == nullptr || g_local_player->m_player_info == nullptr) [[unlikely]]
return;
static bool bLast = false;
bool b = g.self.never_wanted;
if (b)
{
g_local_player->m_player_info->m_wanted_level = 0;
police::m_max_wanted_level->apply();
police::m_max_wanted_level_2->apply();
bLast = b;
}
else if (b != bLast)
{
police::m_max_wanted_level->restore();
police::m_max_wanted_level_2->restore();
bLast = b;
}
if (g.self.force_wanted_level && !b)
g_local_player->m_player_info->m_wanted_level = g.self.wanted_level;
}
}

View File

@ -0,0 +1,93 @@
#include "backend/command.hpp"
#include "backend/looped_command.hpp"
#include "backend/looped/looped.hpp"
#include "pointers.hpp"
namespace big
{
bool user_updated_wanted_level = false;
class clear_wanted : command
{
using command::command;
virtual void execute(const command_arguments&, const std::shared_ptr<command_context> ctx) override
{
// If we're never wanted... don't bother since there is no wanted level to clear anyway (this button won't even be shown if never_wanted is enabled)
if (g.self.never_wanted)
return;
// Clear current wanted level
g_local_player->m_player_info->m_wanted_level = 0;
g_local_player->m_player_info->m_is_wanted = false;
// Keep the lock if it's on, but reset the wanted level
g.self.wanted_level = 0;
}
};
clear_wanted g_clear_wanted("clearwanted", "CLEAR_WANTED_LEVEL", "CLEAR_WANTED_LEVEL_DESC_SELF", 0);
class never_wanted : looped_command
{
using looped_command::looped_command;
virtual void on_tick() override
{
// Clear current wanted level
g_local_player->m_player_info->m_wanted_level = 0;
g_local_player->m_player_info->m_is_wanted = false;
// Since we're hiding the force wanted checkbox and wanted slider, we don't need to do anything else
}
virtual void on_disable() override
{
// If we turn off never wanted, be sure to disable force wanted to restore to a "default" setting
g.self.force_wanted_level = false;
}
};
never_wanted g_never_wanted("neverwanted", "NEVER_WANTED", "NEVER_WANTED", g.self.never_wanted);
void looped::self_wanted()
{
// Don't do anything if we're supposed to be never wanted (this slider won't be shown if never_wanted is enabled)
if (g.self.never_wanted)
return;
if (g_local_player && g_local_player->m_player_info)
{
// We only want the wanted level to update when the player changed it via the ImGui slider
if (user_updated_wanted_level)
{
g_local_player->m_player_info->m_wanted_level = g.self.wanted_level;
if (g.self.wanted_level == 0)
g_local_player->m_player_info->m_is_wanted = false;
else
g_local_player->m_player_info->m_is_wanted = true;
// I don't know if ImGui resets this every tick, let's assume it doesn't
user_updated_wanted_level = false;
return;
}
// Otherwise, if we're locking the wanted level, then just keep it consistently at what the player set
if (g.self.force_wanted_level)
{
g_local_player->m_player_info->m_wanted_level = g.self.wanted_level;
if (g.self.wanted_level == 0)
g_local_player->m_player_info->m_is_wanted = false;
else
g_local_player->m_player_info->m_is_wanted = true;
}
if (!user_updated_wanted_level && !g.self.force_wanted_level)
{
// If the player hasn't updated the wanted level and we're not locking, then YimMenu should update its own slider value to reflect the actual in-game wanted level since it may have changed
g.self.wanted_level = g_local_player->m_player_info->m_wanted_level;
}
}
}
}

View File

@ -5,7 +5,6 @@
#include "memory/byte_patch.hpp"
#include "pointers.hpp"
#include "util/explosion_anti_cheat_bypass.hpp"
#include "util/police.hpp"
#include "util/vehicle.hpp"
#include "util/world_model.hpp"
@ -16,12 +15,6 @@ namespace big
{
static void init()
{
// Restore max wanted level after menu unload
police::m_max_wanted_level =
memory::byte_patch::make(g_pointers->m_gta.m_max_wanted_level.add(5).rip().as<uint32_t*>(), 0).get();
police::m_max_wanted_level_2 =
memory::byte_patch::make(g_pointers->m_gta.m_max_wanted_level.add(14).rip().as<uint32_t*>(), 0).get();
// Patch World Model Spawn Bypass
std::array<uint8_t, 24> world_spawn_patch;
std::fill(world_spawn_patch.begin(), world_spawn_patch.end(), 0x90);

View File

@ -311,12 +311,12 @@ namespace big
} ipls{};
bool clean_player = false;
bool never_wanted = false;
bool force_wanted_level = false;
bool passive = false;
bool free_cam = false;
bool invisibility = false;
bool local_visibility = true;
bool never_wanted = false;
bool no_ragdoll = false;
bool noclip = false;
float noclip_aim_speed_multiplier = 0.25f;
@ -387,7 +387,8 @@ namespace big
NLOHMANN_DEFINE_TYPE_INTRUSIVE(super_hero_fly, gradual, explosions, auto_land, charge, ptfx, fly_speed, initial_launch)
} super_hero_fly{};
NLOHMANN_DEFINE_TYPE_INTRUSIVE(self, ipls, ptfx_effects, clean_player, force_wanted_level, passive, free_cam, invisibility, local_visibility, never_wanted, no_ragdoll, noclip, noclip_aim_speed_multiplier, noclip_speed_multiplier, off_radar, super_run, no_collision, unlimited_oxygen, no_water_collision, wanted_level, god_mode, part_water, proof_bullet, proof_fire, proof_collision, proof_melee, proof_explosion, proof_steam, proof_water, proof_mask, mobile_radio, fast_respawn, auto_tp, super_jump, beast_jump, healthregen, healthregenrate, hud, superman, custom_weapon_stop, prompt_ambient_animations, persist_outfit, persist_outfits_mis, interaction_menu_freedom, super_hero_fly)
NLOHMANN_DEFINE_TYPE_INTRUSIVE(self, ipls, ptfx_effects, clean_player, never_wanted, force_wanted_level, passive, free_cam, invisibility, local_visibility, no_ragdoll, noclip, noclip_aim_speed_multiplier, noclip_speed_multiplier, off_radar, super_run, no_collision, unlimited_oxygen, no_water_collision, wanted_level, god_mode, part_water, proof_bullet, proof_fire, proof_collision, proof_melee, proof_explosion, proof_steam, proof_water, proof_mask, mobile_radio, fast_respawn, auto_tp, super_jump, beast_jump, healthregen, healthregenrate, hud, superman, custom_weapon_stop, prompt_ambient_animations, persist_outfit, persist_outfits_mis, interaction_menu_freedom, super_hero_fly)
} self{};
struct session

View File

@ -1,10 +0,0 @@
#pragma once
namespace big
{
struct police
{
inline static memory::byte_patch* m_max_wanted_level;
inline static memory::byte_patch* m_max_wanted_level_2;
};
}

View File

@ -10,6 +10,8 @@
namespace big
{
extern bool user_updated_wanted_level;
void view::self()
{
components::command_button<"suicide">();
@ -204,24 +206,31 @@ namespace big
}
});
ImGui::EndGroup();
ImGui::SeparatorText("WANTED_LEVEL"_T.data());
ImGui::Checkbox("NEVER_WANTED"_T.data(), &g.self.never_wanted);
components::options_modal("POLICE"_T.data(), [] {
ImGui::Checkbox("NEVER_WANTED"_T.data(), &g.self.never_wanted);
components::command_button<"clearwantedlvl">();
if (ImGui::IsItemHovered())
ImGui::SetTooltip("NEVER_WANTED_DESC"_T.data());
// Only show all the other stuff like clear wanted, force wanted, and the slider if we don't have never_wanted enabled, since never_wanted overrides all of that
if (!g.self.never_wanted)
{
ImGui::Checkbox("FORCE_WANTED_LVL"_T.data(), &g.self.force_wanted_level);
if (ImGui::IsItemHovered())
ImGui::SetTooltip("FORCE_WANTED_LVL_INFO"_T.data());
ImGui::Text("WANTED_LVL"_T.data());
if (ImGui::SliderInt("###wanted_level", &g.self.wanted_level, 0, 5) && !g.self.force_wanted_level && g_local_player != nullptr)
{
g_local_player->m_player_info->m_wanted_level = g.self.wanted_level;
}
}
});
ImGui::SameLine();
components::command_button<"clearwanted">();
ImGui::EndGroup();
// Most ImGui widgets return true when they've been changed, so this is useful to prevent us from overwriting the wanted level's natural decay/progression if we're not keeping it locked
ImGui::SetNextItemWidth(200);
user_updated_wanted_level = ImGui::SliderInt("###wanted_level", &g.self.wanted_level, 0, 5);
if (ImGui::IsItemHovered())
ImGui::SetTooltip("WANTED_LEVEL_SLIDER_DESC"_T.data());
ImGui::SameLine();
ImGui::Checkbox("FORCE_WANTED_LEVEL"_T.data(), &g.self.force_wanted_level);
if (ImGui::IsItemHovered())
ImGui::SetTooltip("FORCE_WANTED_LEVEL_DESC"_T.data());
}
ImGui::SeparatorText("PROOFS"_T.data());