TmpMenu/src/util/toxic.hpp

347 lines
11 KiB
C++
Raw Normal View History

2022-12-06 16:12:02 +00:00
#pragma once
#include "pointers.hpp"
#include "core/scr_globals.hpp"
#include "core/enums.hpp"
#include "gta/net_object_mgr.hpp"
#include "gta/pickup_rewards.hpp"
2022-12-06 16:12:02 +00:00
#include "util/session.hpp"
#include "util/scripts.hpp"
#include "services/gta_data/gta_data_service.hpp"
#include "util/system.hpp"
namespace big::toxic
{
inline void blame_explode_coord(player_ptr to_blame, Vector3 pos, eExplosionTag explosion_type, float damage, bool is_audible, bool is_invisible, float camera_shake)
{
g_pointers->m_blame_explode->apply();
FIRE::ADD_OWNED_EXPLOSION(
PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(to_blame->id()),
pos.x, pos.y, pos.z,
(int)explosion_type,
damage,
is_audible,
is_invisible,
camera_shake
);
g_pointers->m_blame_explode->restore();
}
inline void blame_explode_player(player_ptr to_blame, player_ptr target, eExplosionTag explosion_type, float damage, bool is_audible, bool is_invisible, float camera_shake)
{
Vector3 coords = ENTITY::GET_ENTITY_COORDS(PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(target->id()), true);
blame_explode_coord(to_blame, coords, explosion_type, damage, is_audible, is_invisible, camera_shake);
}
inline void ceo_kick(player_ptr target)
{
auto leader = *scr_globals::gpbd_fm_3.at(target->id(), scr_globals::size::gpbd_fm_3).at(10).as<int*>();
if (leader == -1)
g_notification_service->push_warning("CEO Kick", "Player is not in a CEO/MC");
else if (leader == target->id())
{
g_notification_service->push_error("CEO Kick", "Cannot kick leader of CEO/MC anymore");
}
else
{
// use a more private method to remove associate
const size_t arg_count = 3;
int64_t args[arg_count] = {
(int64_t)eRemoteEvent::MarkPlayerAsBeast,
(int64_t)self::id,
leader
};
g_pointers->m_trigger_script_event(1, args, arg_count, 1 << target->id());
}
}
2022-12-06 16:12:02 +00:00
inline void send_player_to_island(player_ptr target)
{
const size_t arg_count = 2;
int64_t args[arg_count] = {
(int64_t)eRemoteEvent::SendToCayoPerico,
(int64_t)self::id,
};
g_pointers->m_trigger_script_event(1, args, arg_count, 1 << target->id());
}
inline void send_player_to_apartment(player_ptr target, int index)
{
const size_t arg_count = 9;
int64_t args[arg_count] = {
(int64_t)eRemoteEvent::Teleport,
self::id,
(int64_t)target->id(),
(int64_t)(int)-1, 1, (int64_t)index, 1, 1, 1
};
g_pointers->m_trigger_script_event(1, args, arg_count, 1 << target->id());
}
inline void send_player_to_warehouse(player_ptr target, int index)
{
const size_t arg_count = 6;
int64_t args[arg_count] = {
(int64_t)eRemoteEvent::TeleportToWarehouse,
self::id,
(int64_t)target->id(),
1,
index
};
g_pointers->m_trigger_script_event(1, args, arg_count, 1 << target->id());
}
inline void send_player_to_interior(player_ptr player, int interior)
{
float max = 1e+38f;
auto coords = ENTITY::GET_ENTITY_COORDS(PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(player->id()), FALSE);
const size_t arg_count = 15;
int64_t args[arg_count] =
{
(int64_t)eRemoteEvent::InteriorControl,
(int64_t)self::id,
(int64_t)(int)interior,
(int64_t)self::id,
(int64_t)false,
(int64_t)true, // true means enter sender interior
(int64_t)*(uint32_t*)&coords.x,
(int64_t)*(uint32_t*)&coords.y,
(int64_t)*(uint32_t*)&coords.z,
0,
0,
1,
(int64_t)*(uint32_t*)&max,
(int64_t)true,
-1
};
g_pointers->m_trigger_script_event(1, args, arg_count, 1 << player->id());
}
inline void kick_player_from_vehicle(player_ptr target)
{
auto vehicle = target->get_current_vehicle();
if (!vehicle || !vehicle->m_net_object)
{
// vehicle hasn't synced yet, use TSE
const size_t arg_count = 9;
int64_t args[arg_count] = {
(int64_t)eRemoteEvent::VehicleKick,
self::id, 0, 0, 0, 0, 0, 0, 0
};
g_pointers->m_trigger_script_event(1, args, arg_count, 1 << target->id());
}
else
{
// use a private method to kick player from vehicle
(*g_pointers->m_network_object_mgr)->ChangeOwner(vehicle->m_net_object, g_player_service->get_self()->get_net_game_player(), 0);
}
}
inline void ragdoll_player(player_ptr target)
{
if (auto ped = target->get_ped())
if (auto net_object = ped->m_net_object)
g_pointers->m_request_ragdoll(net_object->m_object_id);
}
inline void start_activity(player_ptr target, eActivityType type)
{
const size_t arg_count = 4;
int64_t args[arg_count] =
{
(int64_t)eRemoteEvent::StartActivity,
(int64_t)self::id,
(int64_t)type,
(int64_t)true
};
g_pointers->m_trigger_script_event(1, args, arg_count, 1 << target->id());
}
inline void kick_player_from_interior(player_ptr target)
{
const size_t arg_count = 8;
int64_t args[arg_count]{
(int64_t)eRemoteEvent::KickFromInterior,
(int64_t)self::id,
*scr_globals::globalplayer_bd.at(target->id(), scr_globals::size::globalplayer_bd).at(321).at(6).as<int64_t*>(),
*scr_globals::globalplayer_bd.at(target->id(), scr_globals::size::globalplayer_bd).at(321).at(7).as<int64_t*>(),
2022-12-06 16:12:02 +00:00
};
g_pointers->m_trigger_script_event(1, args, arg_count, 1 << target->id());
}
inline void set_wanted_level(player_ptr target, int wanted_level)
{
int id = target->id();
if (PLAYER::GET_PLAYER_WANTED_LEVEL(id) > wanted_level)
{
// clear existing wanted
globals::clear_wanted_player(id);
for (int i = 0; PLAYER::GET_PLAYER_WANTED_LEVEL(id) > wanted_level && i < 3600; i++)
script::get_current()->yield(1ms);
}
if (wanted_level > 0)
{
*scr_globals::globalplayer_bd.at(self::id, scr_globals::size::globalplayer_bd).at(214).as<Player*>() = id;
*scr_globals::globalplayer_bd.at(self::id, scr_globals::size::globalplayer_bd).at(215).as<int*>() = wanted_level;
2022-12-06 16:12:02 +00:00
for (int i = 0; PLAYER::GET_PLAYER_WANTED_LEVEL(id) < wanted_level && i < 3600; i++)
script::get_current()->yield(1ms);
*scr_globals::globalplayer_bd.at(self::id, scr_globals::size::globalplayer_bd).at(214).as<Player*>() = -1; // reset to prevent wanted from being constantly set
*scr_globals::globalplayer_bd.at(self::id, scr_globals::size::globalplayer_bd).at(215).as<int*>() = -1;
2022-12-06 16:12:02 +00:00
}
}
inline void turn_player_into_beast(player_ptr target)
{
auto id = target->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 = thread->m_net_component;
auto idx = scr_locals::am_hunt_the_beast::broadcast_idx;
if (!stack || !net_component || !target->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(target->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
}
inline void turn_everyone_into_beast()
{
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 = thread->m_net_component;
auto idx = scr_locals::am_hunt_the_beast::broadcast_idx;
if (!stack || !net_component)
return;
thread->m_net_component->block_host_migration(true);
thread->m_context.m_state = rage::eThreadState::unk_3;
g.m_hunt_the_beast_thread = thread;
2022-12-06 16:12:02 +00:00
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;
}
// the blamed player cannot be the target itself
inline void kill_player(player_ptr player, player_ptr to_blame)
{
if (!player->get_ped() || !to_blame->get_ped())
return;
g_pointers->m_send_network_damage((CEntity*)to_blame->get_ped(), (CEntity*)player->get_ped(), player->get_ped()->m_navigation->get_position(),
0, true, RAGE_JOAAT("weapon_explosion"), 10000.0f, 2, 0, (1 << 4), 0, 0, 0, false, false, true, true, nullptr);
}
inline void give_all_weapons(player_ptr target)
{
for (auto& weapon : g_gta_data_service->weapons())
WEAPON::GIVE_WEAPON_TO_PED(PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(target->id()), weapon.second.m_hash, 9999, FALSE, FALSE);
}
inline void remove_all_weapons(player_ptr target)
{
WEAPON::REMOVE_ALL_PED_WEAPONS(PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(target->id()), FALSE);
}
}