2022-12-22 21:23:32 +00:00
|
|
|
#include "backend/player_command.hpp"
|
2023-03-01 21:27:15 +00:00
|
|
|
#include "core/scr_globals.hpp"
|
2022-12-22 21:23:32 +00:00
|
|
|
#include "natives.hpp"
|
|
|
|
#include "pointers.hpp"
|
|
|
|
#include "util/scripts.hpp"
|
|
|
|
|
|
|
|
namespace big
|
|
|
|
{
|
|
|
|
class turn_into_beast : player_command
|
|
|
|
{
|
|
|
|
using player_command::player_command;
|
|
|
|
|
2023-08-01 11:10:14 +02:00
|
|
|
virtual CommandAccessLevel get_access_level() override
|
2022-12-22 21:23:32 +00:00
|
|
|
{
|
|
|
|
return CommandAccessLevel::AGGRESSIVE;
|
|
|
|
}
|
|
|
|
|
2023-08-01 11:10:14 +02:00
|
|
|
virtual void execute(player_ptr player, const command_arguments& _args, const std::shared_ptr<command_context> ctx) override
|
2022-12-22 21:23:32 +00:00
|
|
|
{
|
|
|
|
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))
|
|
|
|
{
|
2024-03-23 00:04:49 +01:00
|
|
|
g_notification_service.push_error("TURN_INTO_BEAST"_T.data(), "BACKEND_TURN_INTO_BEAST_CANNOT_START_AM_LAUNCHER"_T.data());
|
2022-12-22 21:23:32 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2024-03-23 00:04:49 +01:00
|
|
|
g_notification_service.push("TURN_INTO_BEAST"_T.data(), "BACKEND_TURN_INTO_BEAST_STARTING"_T.data());
|
2022-12-22 21:23:32 +00:00
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
2024-03-23 00:04:49 +01:00
|
|
|
g_notification_service.push_error("TURN_INTO_BEAST"_T.data(), "BACKEND_TURN_INTO_BEAST_FAILED"_T.data());
|
2022-12-22 21:23:32 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
script::get_current()->yield(1ms);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!NETWORK::NETWORK_IS_PLAYER_CONNECTED(id))
|
|
|
|
return;
|
|
|
|
|
2024-03-12 09:42:11 +01:00
|
|
|
if (!scripts::force_host("am_hunt_the_beast"_J))
|
2022-12-22 21:23:32 +00:00
|
|
|
{
|
2024-03-23 00:04:49 +01:00
|
|
|
g_notification_service.push_error("TURN_INTO_BEAST"_T.data(), "BACKEND_TURN_INTO_BEAST_FAILED_CONTROL"_T.data());
|
2022-12-22 21:23:32 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2024-03-12 09:42:11 +01:00
|
|
|
auto thread = gta_util::find_script_thread("am_hunt_the_beast"_J);
|
2023-03-01 21:27:15 +00:00
|
|
|
auto stack = thread->m_stack;
|
2023-07-16 12:24:40 -04:00
|
|
|
auto net_component = (CGameScriptHandlerNetComponent*)thread->m_net_component;
|
2023-03-01 21:27:15 +00:00
|
|
|
auto idx = scr_locals::am_hunt_the_beast::broadcast_idx;
|
2022-12-22 21:23:32 +00:00
|
|
|
|
|
|
|
if (!stack || !net_component || !player->is_valid())
|
|
|
|
return;
|
|
|
|
|
2023-03-01 21:27:15 +00:00
|
|
|
*script_local(stack, idx).as<int*>() = 1;
|
2023-06-06 07:40:40 +00:00
|
|
|
*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
|
2022-12-22 21:23:32 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class turn_into_beast_all : command
|
|
|
|
{
|
|
|
|
using command::command;
|
|
|
|
|
|
|
|
virtual CommandAccessLevel get_access_level()
|
|
|
|
{
|
|
|
|
return CommandAccessLevel::AGGRESSIVE;
|
|
|
|
}
|
|
|
|
|
2023-07-26 22:22:40 +02:00
|
|
|
virtual void execute(const command_arguments& _args, const std::shared_ptr<command_context> ctx)
|
2022-12-22 21:23:32 +00:00
|
|
|
{
|
|
|
|
scripts::start_launcher_script(47);
|
|
|
|
|
2024-03-12 09:42:11 +01:00
|
|
|
for (int i = 0; !scripts::is_running("am_launcher"_J); i++)
|
2022-12-22 21:23:32 +00:00
|
|
|
{
|
|
|
|
if (i >= 7000)
|
|
|
|
{
|
2024-03-23 00:04:49 +01:00
|
|
|
g_notification_service.push_error("TURN_INTO_BEAST"_T.data(), "BACKEND_TURN_INTO_BEAST_FAILED"_T.data());
|
2022-12-22 21:23:32 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
script::get_current()->yield(1ms);
|
|
|
|
}
|
|
|
|
|
|
|
|
script::get_current()->yield(500ms);
|
|
|
|
|
2024-03-12 09:42:11 +01:00
|
|
|
if (!scripts::force_host("am_hunt_the_beast"_J))
|
2022-12-22 21:23:32 +00:00
|
|
|
{
|
2024-03-23 00:04:49 +01:00
|
|
|
g_notification_service.push_error("TURN_INTO_BEAST"_T.data(), "BACKEND_TURN_INTO_BEAST_FAILED_CONTROL"_T.data());
|
2022-12-22 21:23:32 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
script::get_current()->yield(3s);
|
|
|
|
|
2024-03-12 09:42:11 +01:00
|
|
|
auto thread = gta_util::find_script_thread("am_hunt_the_beast"_J);
|
2022-12-22 21:23:32 +00:00
|
|
|
|
|
|
|
if (!thread)
|
|
|
|
return;
|
|
|
|
|
2023-03-01 21:27:15 +00:00
|
|
|
auto stack = thread->m_stack;
|
2023-07-16 12:24:40 -04:00
|
|
|
auto net_component = (CGameScriptHandlerNetComponent*)thread->m_net_component;
|
2023-03-01 21:27:15 +00:00
|
|
|
auto idx = scr_locals::am_hunt_the_beast::broadcast_idx;
|
2022-12-22 21:23:32 +00:00
|
|
|
|
|
|
|
if (!stack || !net_component)
|
|
|
|
return;
|
|
|
|
|
2023-07-16 12:24:40 -04:00
|
|
|
((CGameScriptHandlerNetComponent*)thread->m_net_component)->block_host_migration(true);
|
2022-12-22 21:23:32 +00:00
|
|
|
thread->m_context.m_state = rage::eThreadState::unk_3;
|
|
|
|
g.m_hunt_the_beast_thread = thread;
|
|
|
|
|
|
|
|
for (int i = 0; i < 15; i++)
|
|
|
|
{
|
2023-03-01 21:27:15 +00:00
|
|
|
*script_local(stack, idx).as<int*>() = 1;
|
2023-06-06 07:40:40 +00:00
|
|
|
*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
|
2022-12-22 21:23:32 +00:00
|
|
|
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"
|
|
|
|
|
2023-06-06 07:40:40 +00:00
|
|
|
*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
|
2022-12-22 21:23:32 +00:00
|
|
|
|
|
|
|
thread->m_context.m_state = rage::eThreadState::running;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2023-06-06 07:40:40 +00:00
|
|
|
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);
|
2024-03-12 09:42:11 +01:00
|
|
|
}
|