This repository has been archived on 2024-10-22. You can view files and clone it, but cannot push or open issues or pull requests.
YimMenu/src/backend/commands/player/toxic/turn_into_beast.cpp
gir489 152642cf1b
Refactored Allow All Weapons In Vehicle to force all vehicles to use … (#1730)
* Refactored Allow All Weapons In Vehicle to force all vehicles to use all GROUPs.
* Refactored project to not depend on src/gta files that already exist in the GTA-V-Classes project.
* feat(cmake): bump GTAV-Classes
2023-07-16 18:24:40 +02:00

152 lines
5.7 KiB
C++

#include "backend/player_command.hpp"
#include "core/scr_globals.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "util/scripts.hpp"
namespace big
{
class turn_into_beast : player_command
{
using player_command::player_command;
virtual CommandAccessLevel get_access_level()
{
return CommandAccessLevel::AGGRESSIVE;
}
virtual void execute(player_ptr player, const std::vector<std::uint64_t>& _args, const std::shared_ptr<command_context> ctx)
{
auto id = player->id();
if (!NETWORK::NETWORK_IS_PLAYER_A_PARTICIPANT_ON_SCRIPT(id, "am_hunt_the_beast", -1))
{
if (!NETWORK::NETWORK_IS_PLAYER_A_PARTICIPANT_ON_SCRIPT(id, "am_launcher", -1))
{
g_notification_service->push_error("Turn to Beast", "Cannot start the Hunt the Beast event, player not a participant of am_launcher");
return;
}
g_notification_service->push("Turn to Beast", "Starting Hunt The Beast event. Please wait...");
scripts::start_launcher_script(47);
for (int i = 0; !NETWORK::NETWORK_IS_PLAYER_A_PARTICIPANT_ON_SCRIPT(id, "am_hunt_the_beast", -1); i++)
{
if (i >= 1000)
{
g_notification_service->push_error("Turn to Beast", "Failed to start the Hunt The Beast event");
return;
}
script::get_current()->yield(1ms);
}
}
if (!NETWORK::NETWORK_IS_PLAYER_CONNECTED(id))
return;
if (!scripts::force_host(RAGE_JOAAT("am_hunt_the_beast")))
{
g_notification_service->push_error("Turn to Beast", "Failed to take control of am_hunt_the_beast");
return;
}
auto thread = gta_util::find_script_thread(RAGE_JOAAT("am_hunt_the_beast"));
auto stack = thread->m_stack;
auto net_component = (CGameScriptHandlerNetComponent*)thread->m_net_component;
auto idx = scr_locals::am_hunt_the_beast::broadcast_idx;
if (!stack || !net_component || !player->is_valid())
return;
*script_local(stack, idx).as<int*>() = 1;
*script_local(stack, idx).at(1).as<int*>() = 2; // stage
*script_local(stack, idx).at(1).at(6).as<int*>() = net_component->get_participant_index(player->get_net_game_player()); // beast participant idx
*script_local(stack, idx).at(1).at(7).as<Player*>() = id; // beast player idx
*script_local(stack, idx).at(1).at(2).as<int*>() = INT_MAX; // stopwatch time
*script_local(stack, idx).at(1).at(2).at(1).as<bool*>() = true; // stopwatch initialized
*script_local(stack, idx).at(1).at(4).at(1).as<bool*>() = false; // destroy old stage 1 stopwatch
*script_local(stack, idx).at(1).at(9).as<int*>() = 2; // some distance check
*script_local(stack, idx).at(83).as<int*>() = 0; // transformed bitset
}
};
class turn_into_beast_all : command
{
using command::command;
virtual CommandAccessLevel get_access_level()
{
return CommandAccessLevel::AGGRESSIVE;
}
virtual void execute(const std::vector<std::uint64_t>& _args, const std::shared_ptr<command_context> ctx)
{
scripts::start_launcher_script(47);
for (int i = 0; !scripts::is_running(RAGE_JOAAT("am_launcher")); i++)
{
if (i >= 7000)
{
g_notification_service->push_error("Turn to Beast", "Failed to start the Hunt The Beast event");
return;
}
script::get_current()->yield(1ms);
}
script::get_current()->yield(500ms);
if (!scripts::force_host(RAGE_JOAAT("am_hunt_the_beast")))
{
g_notification_service->push_error("Turn to Beast", "Failed to take control of am_hunt_the_beast");
return;
}
script::get_current()->yield(3s);
auto thread = gta_util::find_script_thread(RAGE_JOAAT("am_hunt_the_beast"));
if (!thread)
return;
auto stack = thread->m_stack;
auto net_component = (CGameScriptHandlerNetComponent*)thread->m_net_component;
auto idx = scr_locals::am_hunt_the_beast::broadcast_idx;
if (!stack || !net_component)
return;
((CGameScriptHandlerNetComponent*)thread->m_net_component)->block_host_migration(true);
thread->m_context.m_state = rage::eThreadState::unk_3;
g.m_hunt_the_beast_thread = thread;
for (int i = 0; i < 15; i++)
{
*script_local(stack, idx).as<int*>() = 1;
*script_local(stack, idx).at(1).as<int*>() = 2; // stage
*script_local(stack, idx).at(1).at(6).as<int*>() = __rdtsc(); // participant idx
*script_local(stack, idx).at(1).at(7).as<Player*>() = __rdtsc(); // beast player idx
*script_local(stack, idx).at(1).at(2).as<int*>() = INT_MAX; // stopwatch time
*script_local(stack, idx).at(1).at(2).at(1).as<bool*>() = true; // stopwatch initialized
*script_local(stack, idx).at(1).at(4).at(1).as<bool*>() = false; // destroy old stage 1 stopwatch
*script_local(stack, idx).at(1).at(9).as<int*>() = 2; // some distance check
*script_local(stack, idx).at(83).as<int*>() = 0; // transformed bitset
script::get_current()->yield(350ms);
}
// unfortunately we must also turn ourselves into the beast to prevent the script from exiting due to a "missing player"
*script_local(stack, idx).at(1).at(6).as<int*>() = net_component->m_local_participant_index; // participant idx
*script_local(stack, idx).at(1).at(7).as<Player*>() = self::id; // beast player idx
*script_local(stack, idx).at(1).at(2).as<int*>() = INT_MAX; // stopwatch time
*script_local(stack, idx).at(83).as<int*>() = 0; // transformed bitset
thread->m_context.m_state = rage::eThreadState::running;
}
};
turn_into_beast g_turn_into_beast("beast", "TURN_INTO_BEAST", "TURN_INTO_BEAST_DESC", 0, false);
turn_into_beast_all g_turn_into_beast_all("beastall", "TURN_INTO_BEAST_ALL", "TURN_INTO_BEAST_ALL_DESC", 0);
}