Orbital Drone Feature (#1148)
* Orbital Drone Feature * Fixed PR review comments * chore: cleanup code * UI & globals saving * Fixed typo * Fixed noclip conflict & Applied review suggestions & Added another changeable variable --------- Co-authored-by: Yimura <24669514+Yimura@users.noreply.github.com>
This commit is contained in:
parent
67b18ca5eb
commit
92400a956a
@ -5,8 +5,10 @@
|
|||||||
#include "script.hpp"
|
#include "script.hpp"
|
||||||
#include "script_patches.hpp"
|
#include "script_patches.hpp"
|
||||||
#include "services/context_menu/context_menu_service.hpp"
|
#include "services/context_menu/context_menu_service.hpp"
|
||||||
|
#include "services/orbital_drone/orbital_drone.hpp"
|
||||||
#include "thread_pool.hpp"
|
#include "thread_pool.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace big
|
namespace big
|
||||||
{
|
{
|
||||||
void backend::loop()
|
void backend::loop()
|
||||||
@ -186,4 +188,22 @@ namespace big
|
|||||||
script::get_current()->yield();
|
script::get_current()->yield();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void backend::orbital_drone()
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (g.world.orbital_drone.enabled && PAD::IS_CONTROL_JUST_PRESSED(2, (int)ControllerInputs::INPUT_VEH_LOOK_BEHIND))
|
||||||
|
{
|
||||||
|
if (!g_orbital_drone_service.initialized())
|
||||||
|
g_orbital_drone_service.init();
|
||||||
|
else
|
||||||
|
g_orbital_drone_service.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
g_orbital_drone_service.tick();
|
||||||
|
|
||||||
|
script::get_current()->yield();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,5 +18,6 @@ namespace big
|
|||||||
static void vehiclefly_loop();
|
static void vehiclefly_loop();
|
||||||
static void disable_control_action_loop();
|
static void disable_control_action_loop();
|
||||||
static void world_loop();
|
static void world_loop();
|
||||||
|
static void orbital_drone();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "gta/enums.hpp"
|
#include "gta/enums.hpp"
|
||||||
#include "natives.hpp"
|
#include "natives.hpp"
|
||||||
#include "util/entity.hpp"
|
#include "util/entity.hpp"
|
||||||
|
#include "services/orbital_drone/orbital_drone.hpp"
|
||||||
|
|
||||||
namespace big
|
namespace big
|
||||||
{
|
{
|
||||||
@ -20,6 +21,10 @@ namespace big
|
|||||||
|
|
||||||
virtual void on_tick() override
|
virtual void on_tick() override
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if (g_orbital_drone_service.initialized())
|
||||||
|
return;
|
||||||
|
|
||||||
for (const auto& control : controls)
|
for (const auto& control : controls)
|
||||||
PAD::DISABLE_CONTROL_ACTION(0, static_cast<int>(control), true);
|
PAD::DISABLE_CONTROL_ACTION(0, static_cast<int>(control), true);
|
||||||
|
|
||||||
|
@ -68,8 +68,10 @@ namespace big
|
|||||||
{
|
{
|
||||||
bool enabled = false;
|
bool enabled = false;
|
||||||
} cmd_executor{};
|
} cmd_executor{};
|
||||||
|
|
||||||
rage::scrThread* m_modshop_thread = nullptr;
|
rage::scrThread* m_modshop_thread = nullptr;
|
||||||
bool in_script_vm = false;
|
bool in_script_vm = false;
|
||||||
|
|
||||||
struct debug
|
struct debug
|
||||||
{
|
{
|
||||||
struct logs
|
struct logs
|
||||||
@ -428,6 +430,15 @@ namespace big
|
|||||||
|
|
||||||
struct world
|
struct world
|
||||||
{
|
{
|
||||||
|
struct orbital_drone
|
||||||
|
{
|
||||||
|
bool enabled = false;
|
||||||
|
bool detect_player = false;
|
||||||
|
float nav_ovverride_fast = 3.f;
|
||||||
|
float nav_ovverride_slow = 0.25f;
|
||||||
|
NLOHMANN_DEFINE_TYPE_INTRUSIVE(orbital_drone, detect_player, nav_ovverride_fast, nav_ovverride_slow);
|
||||||
|
} orbital_drone{};
|
||||||
|
|
||||||
struct train
|
struct train
|
||||||
{
|
{
|
||||||
bool derail_train = false;
|
bool derail_train = false;
|
||||||
@ -494,7 +505,7 @@ namespace big
|
|||||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE(model_swapper, models)
|
NLOHMANN_DEFINE_TYPE_INTRUSIVE(model_swapper, models)
|
||||||
} model_swapper{};
|
} model_swapper{};
|
||||||
|
|
||||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE(world, water, spawn_ped, custom_time, blackhole, model_swapper, nearby)
|
NLOHMANN_DEFINE_TYPE_INTRUSIVE(world, water, spawn_ped, custom_time, blackhole, model_swapper, nearby, orbital_drone)
|
||||||
} world{};
|
} world{};
|
||||||
|
|
||||||
struct spoofing
|
struct spoofing
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "script_mgr.hpp"
|
#include "script_mgr.hpp"
|
||||||
#include "services/api/api_service.hpp"
|
#include "services/api/api_service.hpp"
|
||||||
#include "services/context_menu/context_menu_service.hpp"
|
#include "services/context_menu/context_menu_service.hpp"
|
||||||
|
#include "services/orbital_drone/orbital_drone.hpp"
|
||||||
#include "services/custom_text/custom_text_service.hpp"
|
#include "services/custom_text/custom_text_service.hpp"
|
||||||
#include "services/globals/globals_service.hpp"
|
#include "services/globals/globals_service.hpp"
|
||||||
#include "services/gta_data/gta_data_service.hpp"
|
#include "services/gta_data/gta_data_service.hpp"
|
||||||
@ -113,7 +114,9 @@ BOOL APIENTRY DllMain(HMODULE hmod, DWORD reason, PVOID)
|
|||||||
g_script_mgr.add_script(std::make_unique<script>(&backend::turnsignal_loop, "Turn Signals"));
|
g_script_mgr.add_script(std::make_unique<script>(&backend::turnsignal_loop, "Turn Signals"));
|
||||||
g_script_mgr.add_script(std::make_unique<script>(&backend::disable_control_action_loop, "Disable Controls"));
|
g_script_mgr.add_script(std::make_unique<script>(&backend::disable_control_action_loop, "Disable Controls"));
|
||||||
g_script_mgr.add_script(std::make_unique<script>(&backend::world_loop, "World"));
|
g_script_mgr.add_script(std::make_unique<script>(&backend::world_loop, "World"));
|
||||||
|
g_script_mgr.add_script(std::make_unique<script>(&backend::orbital_drone, "Orbital Drone"));
|
||||||
g_script_mgr.add_script(std::make_unique<script>(&context_menu_service::context_menu, "Context Menu"));
|
g_script_mgr.add_script(std::make_unique<script>(&context_menu_service::context_menu, "Context Menu"));
|
||||||
|
|
||||||
LOG(INFO) << "Scripts registered.";
|
LOG(INFO) << "Scripts registered.";
|
||||||
|
|
||||||
g_hooking->enable();
|
g_hooking->enable();
|
||||||
|
@ -203,6 +203,11 @@ namespace big
|
|||||||
m_blame_explode = memory::byte_patch::make(ptr.as<std::uint16_t*>(), 0xE990).get();
|
m_blame_explode = memory::byte_patch::make(ptr.as<std::uint16_t*>(), 0xE990).get();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//Patch blocked explosions
|
||||||
|
main_batch.add("EP", "E8 ? ? ? ? 48 8D 4C 24 20 E8 ? ? ? ? 4C 8D 9C 24 80 01 00 00", [this](memory::handle ptr) {
|
||||||
|
m_explosion_patch = memory::byte_patch::make(ptr.sub(12).as<uint16_t*>(), 0x9090).get();
|
||||||
|
});
|
||||||
|
|
||||||
// CNetworkObjectMgr
|
// CNetworkObjectMgr
|
||||||
main_batch.add("CNOM", "48 8B 0D ? ? ? ? 45 33 C0 E8 ? ? ? ? 33 FF 4C 8B F0", [this](memory::handle ptr) {
|
main_batch.add("CNOM", "48 8B 0D ? ? ? ? 45 33 C0 E8 ? ? ? ? 33 FF 4C 8B F0", [this](memory::handle ptr) {
|
||||||
m_network_object_mgr = ptr.add(3).rip().as<CNetworkObjectMgr**>();
|
m_network_object_mgr = ptr.add(3).rip().as<CNetworkObjectMgr**>();
|
||||||
|
@ -67,6 +67,7 @@ namespace big
|
|||||||
memory::byte_patch* m_max_wanted_level_2;
|
memory::byte_patch* m_max_wanted_level_2;
|
||||||
|
|
||||||
memory::byte_patch* m_blame_explode;
|
memory::byte_patch* m_blame_explode;
|
||||||
|
memory::byte_patch* m_explosion_patch;
|
||||||
PVOID m_world_model_spawn_bypass;
|
PVOID m_world_model_spawn_bypass;
|
||||||
PVOID m_native_return;
|
PVOID m_native_return;
|
||||||
PVOID m_get_label_text;
|
PVOID m_get_label_text;
|
||||||
|
@ -33,6 +33,7 @@ namespace big
|
|||||||
BLACKHOLE,
|
BLACKHOLE,
|
||||||
MODEL_SWAPPER,
|
MODEL_SWAPPER,
|
||||||
NEARBY,
|
NEARBY,
|
||||||
|
ORBITAL_DRONE,
|
||||||
|
|
||||||
NETWORK,
|
NETWORK,
|
||||||
SESSION,
|
SESSION,
|
||||||
@ -121,6 +122,7 @@ namespace big
|
|||||||
{tabs::BLACKHOLE, {"GUI_TAB_BLACKHOLE", view::blackhole}},
|
{tabs::BLACKHOLE, {"GUI_TAB_BLACKHOLE", view::blackhole}},
|
||||||
{tabs::MODEL_SWAPPER, {"GUI_TAB_MODEL_SWAPPER", view::model_swapper}},
|
{tabs::MODEL_SWAPPER, {"GUI_TAB_MODEL_SWAPPER", view::model_swapper}},
|
||||||
{tabs::NEARBY, {"GUI_TAB_NEARBY", view::nearby}},
|
{tabs::NEARBY, {"GUI_TAB_NEARBY", view::nearby}},
|
||||||
|
{tabs::ORBITAL_DRONE, {"Orbital Drone", view::orbital_drone}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
423
src/services/orbital_drone/orbital_drone.cpp
Normal file
423
src/services/orbital_drone/orbital_drone.cpp
Normal file
@ -0,0 +1,423 @@
|
|||||||
|
#include "orbital_drone.hpp"
|
||||||
|
|
||||||
|
#include "backend/bool_command.hpp"
|
||||||
|
#include "core/globals.hpp"
|
||||||
|
#include "gui.hpp"
|
||||||
|
#include "natives.hpp"
|
||||||
|
#include "pointers.hpp"
|
||||||
|
#include "script/globals/GlobalPlayerBD.hpp"
|
||||||
|
#include "services/players/player_service.hpp"
|
||||||
|
#include "util/entity.hpp"
|
||||||
|
#include "util/toxic.hpp"
|
||||||
|
#include "vehicle/CVehicle.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
namespace big
|
||||||
|
{
|
||||||
|
bool_command g_orbital_drone("orbitaldrone", "Toggle orbital drone", "Enables/Disables the orbital drone.",
|
||||||
|
g.world.orbital_drone.enabled);
|
||||||
|
|
||||||
|
static bool nav_override;
|
||||||
|
static float nav_multiplier = 1.f;
|
||||||
|
|
||||||
|
void orbital_drone::init()
|
||||||
|
{
|
||||||
|
if (m_initialized)
|
||||||
|
{
|
||||||
|
destroy();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*g_pointers->m_is_session_started && gta_util::get_network_player_mgr()->m_local_net_player
|
||||||
|
&& gta_util::get_network_player_mgr()->m_local_net_player->m_player_info->m_ped)
|
||||||
|
{
|
||||||
|
scr_globals::globalplayer_bd.as<GlobalPlayerBD*>()->Entries[self::id].OrbitalBitset.Set(eOrbitalBitset::kOrbitalCannonActive);
|
||||||
|
const auto player_pos =
|
||||||
|
*gta_util::get_network_player_mgr()->m_local_net_player->m_player_info->m_ped->m_navigation->get_position();
|
||||||
|
|
||||||
|
m_start_pos = {player_pos.x, player_pos.y, player_pos.z};
|
||||||
|
|
||||||
|
m_cam = CAM::CREATE_CAM("DEFAULT_SCRIPTED_CAMERA", 0);
|
||||||
|
CAM::SET_CAM_COORD(m_cam, player_pos.x, player_pos.y, player_pos.z + 100.f);
|
||||||
|
CAM::SET_CAM_ROT(m_cam, -90.f, 0, 0, 2);
|
||||||
|
CAM::SET_CAM_FOV(m_cam, 100.f);
|
||||||
|
CAM::SET_CAM_ACTIVE(m_cam, true);
|
||||||
|
CAM::RENDER_SCRIPT_CAMS(true, true, 1000, true, false, 0);
|
||||||
|
|
||||||
|
m_scaleform = GRAPHICS::REQUEST_SCALEFORM_MOVIE("ORBITAL_CANNON_CAM");
|
||||||
|
|
||||||
|
for (size_t i = 0; i < 10 && !GRAPHICS::HAS_SCALEFORM_MOVIE_LOADED(m_scaleform); i++)
|
||||||
|
{
|
||||||
|
script::get_current()->yield();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GRAPHICS::HAS_SCALEFORM_MOVIE_LOADED(m_scaleform))
|
||||||
|
{
|
||||||
|
GRAPHICS::BEGIN_SCALEFORM_MOVIE_METHOD(m_scaleform, "showSurveillance");
|
||||||
|
GRAPHICS::SCALEFORM_MOVIE_METHOD_ADD_PARAM_FLOAT(0.f);
|
||||||
|
GRAPHICS::END_SCALEFORM_MOVIE_METHOD();
|
||||||
|
}
|
||||||
|
|
||||||
|
HUD::SET_BIGMAP_ACTIVE(true, false);
|
||||||
|
HUD::LOCK_MINIMAP_ANGLE(0);
|
||||||
|
|
||||||
|
m_initialized = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void orbital_drone::destroy()
|
||||||
|
{
|
||||||
|
m_initialized = false;
|
||||||
|
|
||||||
|
Entity self = PLAYER::PLAYER_PED_ID();
|
||||||
|
if (PED::IS_PED_IN_ANY_VEHICLE(self, true))
|
||||||
|
self = PED::GET_VEHICLE_PED_IS_IN(self, false);
|
||||||
|
|
||||||
|
ENTITY::FREEZE_ENTITY_POSITION(self, 0);
|
||||||
|
|
||||||
|
ENTITY::SET_ENTITY_VISIBLE(self, true, 0);
|
||||||
|
|
||||||
|
CAM::RENDER_SCRIPT_CAMS(false, true, 1000, true, false, 0);
|
||||||
|
|
||||||
|
Vector3 tp_pos = m_start_pos;
|
||||||
|
|
||||||
|
if (m_should_tp)
|
||||||
|
{
|
||||||
|
tp_pos = m_ground_pos;
|
||||||
|
|
||||||
|
if (m_ground_pos.z < PATHFIND::GET_APPROX_FLOOR_FOR_POINT(m_ground_pos.x, m_ground_pos.z))
|
||||||
|
m_ground_pos.z = PATHFIND::GET_APPROX_FLOOR_FOR_POINT(m_ground_pos.x, m_ground_pos.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_should_tp)
|
||||||
|
ENTITY::SET_ENTITY_COORDS(self, tp_pos.x, tp_pos.y, tp_pos.z, 0, 0, 0, 0);
|
||||||
|
else
|
||||||
|
ENTITY::SET_ENTITY_COORDS(self, tp_pos.x, tp_pos.y, tp_pos.z, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
CAM::SET_CAM_ACTIVE(m_cam, false);
|
||||||
|
CAM::DESTROY_CAM(m_cam, 1);
|
||||||
|
|
||||||
|
HUD::UNLOCK_MINIMAP_ANGLE();
|
||||||
|
|
||||||
|
m_lock_ent = -1;
|
||||||
|
m_lock = false;
|
||||||
|
|
||||||
|
scr_globals::globalplayer_bd.as<GlobalPlayerBD*>()->Entries[PLAYER::PLAYER_ID()].OrbitalBitset.Clear(eOrbitalBitset::kOrbitalCannonActive);
|
||||||
|
m_should_tp = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void orbital_drone::cam_nav()
|
||||||
|
{
|
||||||
|
if (!m_initialized || !CAM::DOES_CAM_EXIST(m_cam))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Vector3 campos = CAM::GET_CAM_COORD(m_cam);
|
||||||
|
Vector3 finalpos = CAM::GET_CAM_COORD(m_cam);
|
||||||
|
|
||||||
|
MISC::GET_GROUND_Z_FOR_3D_COORD(finalpos.x, finalpos.y, finalpos.z, &finalpos.z, false, false);
|
||||||
|
|
||||||
|
m_ground_pos = {campos.x, campos.y, finalpos.z};
|
||||||
|
|
||||||
|
float minz = finalpos.z + 10;
|
||||||
|
float maxz = 1500.f;
|
||||||
|
|
||||||
|
if (campos.z < minz)
|
||||||
|
CAM::SET_CAM_COORD(m_cam, campos.x, campos.y, minz);
|
||||||
|
if (campos.z > maxz)
|
||||||
|
CAM::SET_CAM_COORD(m_cam, campos.x, campos.y, maxz);
|
||||||
|
|
||||||
|
HUD::SET_FAKE_PAUSEMAP_PLAYER_POSITION_THIS_FRAME(campos.x, campos.y);
|
||||||
|
|
||||||
|
Vector3 movepos;
|
||||||
|
bool moved = false;
|
||||||
|
|
||||||
|
float leftstick_xaxis = PAD::GET_CONTROL_NORMAL(2, (int)ControllerInputs::INPUT_SCRIPT_LEFT_AXIS_X);
|
||||||
|
float leftstick_yaxis = -PAD::GET_CONTROL_NORMAL(2, (int)ControllerInputs::INPUT_SCRIPT_LEFT_AXIS_Y);
|
||||||
|
float rightstick_yaxis = PAD::GET_CONTROL_NORMAL(2, (int)ControllerInputs::INPUT_SCRIPT_RIGHT_AXIS_Y);
|
||||||
|
|
||||||
|
//LEFT
|
||||||
|
if (PAD::IS_CONTROL_PRESSED(2, (int)ControllerInputs::INPUT_MOVE_LEFT_ONLY) || PAD::IS_DISABLED_CONTROL_JUST_PRESSED(2, (int)ControllerInputs::INPUT_MOVE_LEFT_ONLY))
|
||||||
|
{
|
||||||
|
if (leftstick_xaxis == 0)
|
||||||
|
movepos = {campos.x - ((campos.z / 50) * nav_multiplier), campos.y, campos.z};
|
||||||
|
else
|
||||||
|
movepos = {campos.x + ((leftstick_xaxis * 5) * nav_multiplier), campos.y, campos.z};
|
||||||
|
moved = true;
|
||||||
|
m_lock = false;
|
||||||
|
}
|
||||||
|
//RIGHT
|
||||||
|
if (PAD::IS_CONTROL_PRESSED(2, (int)ControllerInputs::INPUT_MOVE_RIGHT) || PAD::IS_CONTROL_PRESSED(2, (int)ControllerInputs::INPUT_MOVE_RIGHT))
|
||||||
|
{
|
||||||
|
if (leftstick_xaxis == 0)
|
||||||
|
movepos = moved ? Vector3(movepos.x + ((movepos.z / 50) * nav_multiplier), movepos.y, movepos.z) :
|
||||||
|
Vector3(campos.x + ((campos.z / 50) * nav_multiplier), campos.y, campos.z);
|
||||||
|
else
|
||||||
|
movepos = moved ? Vector3(movepos.x + ((leftstick_xaxis * 5) * nav_multiplier), movepos.y, movepos.z) :
|
||||||
|
Vector3(campos.x + ((leftstick_xaxis * 5) * nav_multiplier), campos.y, campos.z);
|
||||||
|
moved = true;
|
||||||
|
m_lock = false;
|
||||||
|
}
|
||||||
|
//UP
|
||||||
|
if (PAD::IS_CONTROL_PRESSED(2, (int)ControllerInputs::INPUT_MOVE_UP_ONLY) || PAD::IS_CONTROL_PRESSED(2, (int)ControllerInputs::INPUT_MOVE_UP_ONLY))
|
||||||
|
{
|
||||||
|
if (leftstick_yaxis == 0)
|
||||||
|
movepos = moved ? Vector3(movepos.x, movepos.y + ((movepos.z / 50) * nav_multiplier), movepos.z) :
|
||||||
|
Vector3(campos.x, campos.y + ((campos.z / 50) * nav_multiplier), campos.z);
|
||||||
|
else
|
||||||
|
movepos = moved ? Vector3(movepos.x, movepos.y + ((leftstick_yaxis * 5) * nav_multiplier), movepos.z) :
|
||||||
|
Vector3(campos.x, campos.y + ((leftstick_yaxis * 5) * nav_multiplier), campos.z);
|
||||||
|
moved = true;
|
||||||
|
m_lock = false;
|
||||||
|
}
|
||||||
|
//DOWN
|
||||||
|
if (PAD::IS_CONTROL_PRESSED(2, (int)ControllerInputs::INPUT_MOVE_DOWN) || PAD::IS_CONTROL_PRESSED(2, (int)ControllerInputs::INPUT_MOVE_DOWN))
|
||||||
|
{
|
||||||
|
if (leftstick_yaxis == 0)
|
||||||
|
movepos = moved ? Vector3(movepos.x, movepos.y + ((movepos.z / 50) * nav_multiplier), movepos.z) :
|
||||||
|
Vector3(campos.x, campos.y - ((campos.z / 50) * nav_multiplier), campos.z);
|
||||||
|
else
|
||||||
|
movepos = moved ? Vector3(movepos.x, movepos.y + ((leftstick_yaxis * 5) * nav_multiplier), movepos.z) :
|
||||||
|
Vector3(campos.x, campos.y + ((leftstick_yaxis * 5) * nav_multiplier), campos.z);
|
||||||
|
moved = true;
|
||||||
|
m_lock = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//ZOOM IN
|
||||||
|
if (PAD::IS_CONTROL_PRESSED(2, (int)ControllerInputs::INPUT_VEH_SLOWMO_UP_ONLY)
|
||||||
|
|| PAD::IS_CONTROL_PRESSED(2, (int)ControllerInputs::INPUT_VEH_SLOWMO_UP_ONLY) && !g_gui->is_open())
|
||||||
|
{
|
||||||
|
if (campos.z > minz)
|
||||||
|
{
|
||||||
|
movepos = moved ? Vector3(movepos.x, movepos.y, movepos.z - movepos.z / 20) :
|
||||||
|
Vector3(campos.x, campos.y, campos.z - campos.z / 20);
|
||||||
|
moved = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//ZOOM OUT
|
||||||
|
if (PAD::IS_CONTROL_PRESSED(2, (int)ControllerInputs::INPUT_VEH_SLOWMO_DOWN_ONLY)
|
||||||
|
|| PAD::IS_CONTROL_PRESSED(2, (int)ControllerInputs::INPUT_VEH_SLOWMO_DOWN_ONLY) && !g_gui->is_open())
|
||||||
|
{
|
||||||
|
if (campos.z < maxz)
|
||||||
|
{
|
||||||
|
movepos = moved ? Vector3(movepos.x, movepos.y, movepos.z + movepos.z / 20) :
|
||||||
|
Vector3(campos.x, campos.y, campos.z + campos.z / 20);
|
||||||
|
moved = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//ZOOM IN CONTROLLER
|
||||||
|
if (rightstick_yaxis && !g_gui->is_open())
|
||||||
|
{
|
||||||
|
movepos = moved ? Vector3(movepos.x, movepos.y, movepos.z + (rightstick_yaxis * 5)) :
|
||||||
|
Vector3(campos.x, campos.y, campos.z + (rightstick_yaxis * 5));
|
||||||
|
moved = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_lock && ENTITY::DOES_ENTITY_EXIST(m_lock_ent) && m_lock_ent != -1)
|
||||||
|
{
|
||||||
|
Vector3 targetpos = ENTITY::GET_ENTITY_COORDS(m_lock_ent, 0);
|
||||||
|
if (moved)
|
||||||
|
CAM::SET_CAM_COORD(m_cam, targetpos.x, targetpos.y, movepos.z);
|
||||||
|
else
|
||||||
|
CAM::SET_CAM_COORD(m_cam, targetpos.x, targetpos.y, campos.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (moved)
|
||||||
|
{
|
||||||
|
CAM::SET_CAM_COORD(m_cam, movepos.x, movepos.y, movepos.z);
|
||||||
|
|
||||||
|
moved = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void orbital_drone::tick()
|
||||||
|
{
|
||||||
|
if (!m_initialized)
|
||||||
|
return;
|
||||||
|
|
||||||
|
PAD::ALLOW_ALTERNATIVE_SCRIPT_CONTROLS_LAYOUT(2);
|
||||||
|
PAD::DISABLE_CONTROL_ACTION(0, (int)ControllerInputs::INPUT_ATTACK, true);
|
||||||
|
PAD::DISABLE_CONTROL_ACTION(0, (int)ControllerInputs::INPUT_ATTACK2, true);
|
||||||
|
PAD::DISABLE_CONTROL_ACTION(0, (int)ControllerInputs::INPUT_MELEE_ATTACK_ALTERNATE, true);
|
||||||
|
PAD::DISABLE_CONTROL_ACTION(0, (int)ControllerInputs::INPUT_MELEE_ATTACK_HEAVY, true);
|
||||||
|
PAD::DISABLE_CONTROL_ACTION(0, (int)ControllerInputs::INPUT_MELEE_ATTACK_LIGHT, true);
|
||||||
|
PAD::DISABLE_CONTROL_ACTION(0, (int)ControllerInputs::INPUT_MELEE_ATTACK1, true);
|
||||||
|
PAD::DISABLE_CONTROL_ACTION(0, (int)ControllerInputs::INPUT_MELEE_ATTACK2, true);
|
||||||
|
PAD::DISABLE_CONTROL_ACTION(0, (int)ControllerInputs::INPUT_MELEE_BLOCK, true);
|
||||||
|
PAD::DISABLE_CONTROL_ACTION(2, (int)ControllerInputs::INPUT_FRONTEND_PAUSE_ALTERNATE, true);
|
||||||
|
PAD::DISABLE_CONTROL_ACTION(2, (int)ControllerInputs::INPUT_SELECT_NEXT_WEAPON, true);
|
||||||
|
PAD::DISABLE_CONTROL_ACTION(2, (int)ControllerInputs::INPUT_SELECT_PREV_WEAPON, true);
|
||||||
|
PAD::DISABLE_CONTROL_ACTION(2, (int)ControllerInputs::INPUT_WEAPON_WHEEL_NEXT, true);
|
||||||
|
PAD::DISABLE_CONTROL_ACTION(2, (int)ControllerInputs::INPUT_WEAPON_WHEEL_PREV, true);
|
||||||
|
PAD::DISABLE_CONTROL_ACTION(2, (int)ControllerInputs::INPUT_VEH_SELECT_NEXT_WEAPON, true);
|
||||||
|
PAD::DISABLE_CONTROL_ACTION(2, (int)ControllerInputs::INPUT_VEH_SELECT_PREV_WEAPON, true);
|
||||||
|
PAD::DISABLE_CONTROL_ACTION(2, (int)ControllerInputs::INPUT_VEH_NEXT_RADIO, true);
|
||||||
|
PAD::DISABLE_CONTROL_ACTION(2, (int)ControllerInputs::INPUT_VEH_PREV_RADIO, true);
|
||||||
|
PAD::DISABLE_CONTROL_ACTION(2, (int)ControllerInputs::INPUT_DUCK, true);
|
||||||
|
PAD::DISABLE_CONTROL_ACTION(2, (int)ControllerInputs::INPUT_VEH_SPECIAL, true);
|
||||||
|
HUD::DISPLAY_AMMO_THIS_FRAME(false);
|
||||||
|
HUD::HUD_FORCE_WEAPON_WHEEL(false);
|
||||||
|
HUD::HIDE_HUD_COMPONENT_THIS_FRAME(19);
|
||||||
|
HUD::HIDE_HUD_COMPONENT_THIS_FRAME(2);
|
||||||
|
HUD::HIDE_HUD_COMPONENT_THIS_FRAME(1);
|
||||||
|
HUD::HIDE_HUD_COMPONENT_THIS_FRAME(3);
|
||||||
|
HUD::HIDE_HUD_COMPONENT_THIS_FRAME(4);
|
||||||
|
|
||||||
|
Vector3 cam_pos = CAM::GET_CAM_COORD(m_cam);
|
||||||
|
Vector3 cam_rot = CAM::GET_CAM_ROT(m_cam, 0);
|
||||||
|
|
||||||
|
Entity self = self::ped;
|
||||||
|
if (PED::IS_PED_IN_ANY_VEHICLE(self, true) && VEHICLE::GET_PED_IN_VEHICLE_SEAT(self::veh, -1, false) == self)
|
||||||
|
self = self::veh;
|
||||||
|
|
||||||
|
ENTITY::SET_ENTITY_COORDS(self, cam_pos.x, cam_pos.y, cam_pos.z + 15, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
ENTITY::FREEZE_ENTITY_POSITION(self, 1);
|
||||||
|
ENTITY::SET_ENTITY_VISIBLE(self, false, 0);
|
||||||
|
|
||||||
|
cam_nav();
|
||||||
|
|
||||||
|
GRAPHICS::DRAW_SCALEFORM_MOVIE_FULLSCREEN(m_scaleform, 255, 255, 255, 0, 1);
|
||||||
|
|
||||||
|
if (PAD::IS_CONTROL_JUST_PRESSED(2, (int)ControllerInputs::INPUT_FRONTEND_RDOWN) || PAD::IS_DISABLED_CONTROL_JUST_PRESSED(2, (int)ControllerInputs::INPUT_FRONTEND_RDOWN))
|
||||||
|
{
|
||||||
|
m_should_tp = true;
|
||||||
|
destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PAD::IS_CONTROL_JUST_PRESSED(2, (int)ControllerInputs::INPUT_JUMP)
|
||||||
|
|| PAD::IS_DISABLED_CONTROL_JUST_PRESSED(2, (int)ControllerInputs::INPUT_JUMP && !g_gui->is_open()))
|
||||||
|
{
|
||||||
|
m_lock_ent = entity::get_entity_closest_to_middle_of_screen();
|
||||||
|
m_lock = true;
|
||||||
|
|
||||||
|
if (g.world.orbital_drone.detect_player)
|
||||||
|
detect_player(m_lock_ent);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PAD::IS_CONTROL_JUST_PRESSED(2, (int)ControllerInputs::INPUT_ATTACK) || PAD::IS_DISABLED_CONTROL_JUST_PRESSED(2, (int)ControllerInputs::INPUT_ATTACK))
|
||||||
|
{
|
||||||
|
orbital_cannon_explosion();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PAD::IS_CONTROL_JUST_PRESSED(2, (int)ControllerInputs::INPUT_ARREST)
|
||||||
|
|| PAD::IS_DISABLED_CONTROL_JUST_PRESSED(2, (int)ControllerInputs::INPUT_ARREST) && !g_gui->is_open())
|
||||||
|
{
|
||||||
|
//For Future Features
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PAD::IS_CONTROL_PRESSED(2, (int)ControllerInputs::INPUT_PARACHUTE_BRAKE_RIGHT) || PAD::IS_DISABLED_CONTROL_JUST_PRESSED(2, (int)ControllerInputs::INPUT_PARACHUTE_BRAKE_RIGHT))
|
||||||
|
{
|
||||||
|
nav_override = true;
|
||||||
|
nav_multiplier = g.world.orbital_drone.nav_ovverride_fast;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PAD::IS_CONTROL_PRESSED(2, (int)ControllerInputs::INPUT_PARACHUTE_BRAKE_LEFT) || PAD::IS_DISABLED_CONTROL_PRESSED(2, (int)ControllerInputs::INPUT_PARACHUTE_BRAKE_LEFT))
|
||||||
|
{
|
||||||
|
nav_override = true;
|
||||||
|
nav_multiplier = g.world.orbital_drone.nav_ovverride_slow;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nav_override)
|
||||||
|
nav_multiplier = 1.f;
|
||||||
|
else
|
||||||
|
nav_override = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void orbital_drone::detect_player(Entity ent)
|
||||||
|
{
|
||||||
|
if (!ENTITY::DOES_ENTITY_EXIST(ent))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (ENTITY::IS_ENTITY_A_VEHICLE(ent))
|
||||||
|
{
|
||||||
|
const auto vehicle = reinterpret_cast<CVehicle*>(g_pointers->m_handle_to_ptr(ent));
|
||||||
|
if (vehicle)
|
||||||
|
{
|
||||||
|
for (const auto& player : g_player_service->players() | std::ranges::views::values)
|
||||||
|
{
|
||||||
|
if (player && vehicle->m_driver)
|
||||||
|
{
|
||||||
|
if (player->get_ped() == vehicle->m_driver)
|
||||||
|
{
|
||||||
|
g_player_service->set_selected(player);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto ped : vehicle->m_passengers)
|
||||||
|
{
|
||||||
|
if (ped && player->get_ped() == ped)
|
||||||
|
{
|
||||||
|
g_player_service->set_selected(player);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PED::IS_PED_A_PLAYER(ent))
|
||||||
|
{
|
||||||
|
for (auto ped : g_player_service->players() | std::ranges::views::values)
|
||||||
|
{
|
||||||
|
if (ped && g_pointers->m_ptr_to_handle(ped->get_ped()) == ent)
|
||||||
|
{
|
||||||
|
g_player_service->set_selected(ped);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void orbital_drone::orbital_cannon_explosion()
|
||||||
|
{
|
||||||
|
if (g_gui->is_open())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Vector3 campos = CAM::GET_CAM_COORD(m_cam);
|
||||||
|
Vector3 entpos = ENTITY::GET_ENTITY_COORDS(entity::get_entity_closest_to_middle_of_screen(), 0);
|
||||||
|
|
||||||
|
if (ENTITY::DOES_ENTITY_EXIST(g_pointers->m_ptr_to_handle(g_player_service->get_selected()->get_ped())))
|
||||||
|
{
|
||||||
|
toxic::blame_explode_coord(g_player_service->get_selected(), m_ground_pos, eExplosionTag::EXP_TAG_ORBITAL_CANNON, 1.f, TRUE, TRUE, 1.f);
|
||||||
|
|
||||||
|
if (MISC::GET_DISTANCE_BETWEEN_COORDS(campos.x, campos.y, campos.z, entpos.x, entpos.y, entpos.z, false) < 10)
|
||||||
|
toxic::blame_explode_coord(g_player_service->get_selected(), entpos, eExplosionTag::EXP_TAG_ORBITAL_CANNON, 1.f, TRUE, TRUE, 1.f);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
toxic::blame_explode_coord(g_player_service->get_self(), m_ground_pos, eExplosionTag::EXP_TAG_ORBITAL_CANNON, 1.f, TRUE, TRUE, 1.f);
|
||||||
|
if (MISC::GET_DISTANCE_BETWEEN_COORDS(campos.x, campos.y, campos.z, entpos.x, entpos.y, entpos.z, false) < 10)
|
||||||
|
toxic::blame_explode_coord(g_player_service->get_self(), entpos, eExplosionTag::EXP_TAG_ORBITAL_CANNON, 1.f, TRUE, TRUE, 1.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!STREAMING::HAS_NAMED_PTFX_ASSET_LOADED("scr_xm_orbital"))
|
||||||
|
{
|
||||||
|
STREAMING::REQUEST_NAMED_PTFX_ASSET("scr_xm_orbital");
|
||||||
|
|
||||||
|
for (int i = 0; i < 10 && !STREAMING::HAS_NAMED_PTFX_ASSET_LOADED("scr_xm_orbital"); i++)
|
||||||
|
{
|
||||||
|
script::get_current()->yield();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (STREAMING::HAS_NAMED_PTFX_ASSET_LOADED("scr_xm_orbital"))
|
||||||
|
{
|
||||||
|
GRAPHICS::USE_PARTICLE_FX_ASSET("scr_xm_orbital");
|
||||||
|
GRAPHICS::START_NETWORKED_PARTICLE_FX_NON_LOOPED_AT_COORD("scr_xm_orbital_blast",
|
||||||
|
m_ground_pos.x,
|
||||||
|
m_ground_pos.y,
|
||||||
|
m_ground_pos.z,
|
||||||
|
0.f,
|
||||||
|
0.f,
|
||||||
|
0.f,
|
||||||
|
1.f,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
37
src/services/orbital_drone/orbital_drone.hpp
Normal file
37
src/services/orbital_drone/orbital_drone.hpp
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace big
|
||||||
|
{
|
||||||
|
class orbital_drone
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
Cam m_cam;
|
||||||
|
bool m_lock;
|
||||||
|
Entity m_lock_ent;
|
||||||
|
|
||||||
|
Vector3 m_ground_pos;
|
||||||
|
Vector3 m_start_pos;
|
||||||
|
|
||||||
|
int m_scaleform;
|
||||||
|
|
||||||
|
bool m_should_tp;
|
||||||
|
bool m_initialized;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void init();
|
||||||
|
void destroy();
|
||||||
|
void tick();
|
||||||
|
|
||||||
|
bool initialized()
|
||||||
|
{ return m_initialized; };
|
||||||
|
|
||||||
|
private:
|
||||||
|
void cam_nav();
|
||||||
|
void detect_player(Entity ent);
|
||||||
|
void orbital_cannon_explosion();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
inline orbital_drone g_orbital_drone_service;
|
||||||
|
|
||||||
|
}
|
@ -185,4 +185,71 @@ namespace big::entity
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline double distance_to_middle_of_screen(const rage::fvector2& screen_pos)
|
||||||
|
{
|
||||||
|
double cumulative_distance{};
|
||||||
|
|
||||||
|
if (screen_pos.x > 0.5)
|
||||||
|
cumulative_distance += screen_pos.x - 0.5;
|
||||||
|
else
|
||||||
|
cumulative_distance += 0.5 - screen_pos.x;
|
||||||
|
|
||||||
|
if (screen_pos.y > 0.5)
|
||||||
|
cumulative_distance += screen_pos.y - 0.5;
|
||||||
|
else
|
||||||
|
cumulative_distance += 0.5 - screen_pos.y;
|
||||||
|
|
||||||
|
return cumulative_distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Entity get_entity_closest_to_middle_of_screen()
|
||||||
|
{
|
||||||
|
|
||||||
|
Entity closest_entity{};
|
||||||
|
float distance = 1;
|
||||||
|
|
||||||
|
//if (!vehicleInterface || !pedInterface)
|
||||||
|
// return 0;
|
||||||
|
|
||||||
|
auto replayInterface = *g_pointers->m_replay_interface;
|
||||||
|
auto vehicleInterface = replayInterface->m_vehicle_interface;
|
||||||
|
auto pedInterface = replayInterface->m_ped_interface;
|
||||||
|
|
||||||
|
for (auto veh : vehicleInterface->m_vehicle_list->m_vehicles)
|
||||||
|
{
|
||||||
|
if (veh.m_entity_ptr)
|
||||||
|
{
|
||||||
|
Vehicle handle = g_pointers->m_ptr_to_handle(veh.m_entity_ptr);
|
||||||
|
Vector3 pos = ENTITY::GET_ENTITY_COORDS(handle, 1);
|
||||||
|
rage::fvector2 screenpos;
|
||||||
|
HUD::GET_HUD_SCREEN_POSITION_FROM_WORLD_POSITION(pos.x, pos.y, pos.z, &screenpos.x, &screenpos.y);
|
||||||
|
|
||||||
|
if (distance_to_middle_of_screen(screenpos) < distance && ENTITY::HAS_ENTITY_CLEAR_LOS_TO_ENTITY(PLAYER::PLAYER_PED_ID(), handle, 17))
|
||||||
|
{
|
||||||
|
closest_entity = handle;
|
||||||
|
distance = distance_to_middle_of_screen(screenpos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto ped : pedInterface->m_ped_list->m_peds)
|
||||||
|
{
|
||||||
|
if (ped.m_entity_ptr)
|
||||||
|
{
|
||||||
|
Vehicle handle = g_pointers->m_ptr_to_handle(ped.m_entity_ptr);
|
||||||
|
Vector3 pos = ENTITY::GET_ENTITY_COORDS(handle, 1);
|
||||||
|
rage::fvector2 screenpos;
|
||||||
|
HUD::GET_HUD_SCREEN_POSITION_FROM_WORLD_POSITION(pos.x, pos.y, pos.z, &screenpos.x, &screenpos.y);
|
||||||
|
|
||||||
|
if (distance_to_middle_of_screen(screenpos) < distance && ENTITY::HAS_ENTITY_CLEAR_LOS_TO_ENTITY(PLAYER::PLAYER_PED_ID(), handle, 17) && handle != PLAYER::PLAYER_PED_ID())
|
||||||
|
{
|
||||||
|
closest_entity = handle;
|
||||||
|
distance = distance_to_middle_of_screen(screenpos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return closest_entity;
|
||||||
|
}
|
||||||
}
|
}
|
@ -20,8 +20,10 @@ 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)
|
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();
|
g_pointers->m_blame_explode->apply();
|
||||||
|
g_pointers->m_explosion_patch->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);
|
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();
|
g_pointers->m_blame_explode->restore();
|
||||||
|
g_pointers->m_explosion_patch->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)
|
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)
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "util/entity.hpp"
|
#include "util/entity.hpp"
|
||||||
#include "util/local_player.hpp"
|
#include "util/local_player.hpp"
|
||||||
#include "util/scripts.hpp"
|
#include "util/scripts.hpp"
|
||||||
|
#include "services/orbital_drone/orbital_drone.hpp"
|
||||||
#include "views/view.hpp"
|
#include "views/view.hpp"
|
||||||
|
|
||||||
namespace big
|
namespace big
|
||||||
|
@ -30,6 +30,7 @@ namespace big
|
|||||||
static void mobile();
|
static void mobile();
|
||||||
static void navigation();
|
static void navigation();
|
||||||
static void notifications();
|
static void notifications();
|
||||||
|
static void orbital_drone();
|
||||||
static void overlay();
|
static void overlay();
|
||||||
static void root();
|
static void root();
|
||||||
static void self();
|
static void self();
|
||||||
|
34
src/views/world/view_orbital_drone.cpp
Normal file
34
src/views/world/view_orbital_drone.cpp
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#include "views/view.hpp"
|
||||||
|
|
||||||
|
namespace big
|
||||||
|
{
|
||||||
|
void view::orbital_drone()
|
||||||
|
{
|
||||||
|
components::command_checkbox<"orbitaldrone">();
|
||||||
|
|
||||||
|
if (g.world.orbital_drone.enabled)
|
||||||
|
{
|
||||||
|
ImGui::Separator();
|
||||||
|
ImGui::BeginGroup();
|
||||||
|
ImGui::Text("press 'Look behind' (C/R3 by default) to activate\npress WASD buttons or Left thumbstick to navigate\nUse scroll wheel/Mouse or Right thumbstick to zoom\npress E/Q or L1/R1 to modify speed\npress 'Jump' (Space/X/Square by default) to lock on an entity\npress 'Fire' (Mouse button 1/Right trigger by default) to Obliterate\npress Enter or A/X by default to teleport to target");
|
||||||
|
ImGui::EndGroup();
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
|
ImGui::BeginGroup();
|
||||||
|
ImGui::Checkbox("Detect player on lock", &g.world.orbital_drone.detect_player);
|
||||||
|
if (ImGui::IsItemHovered())
|
||||||
|
{
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
ImGui::Text("if enabled, changes the selected player to the one it detects upon locking on an entity");
|
||||||
|
ImGui::Text("All explosions will be blamed on the selected player, defaulting to the local player");
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
|
ImGui::Text("Adjust fast modifier");
|
||||||
|
ImGui::SliderFloat("##fastspeed", &g.world.orbital_drone.nav_ovverride_fast, 1.f, 10.f);
|
||||||
|
ImGui::Text("Adjust slow modifier");
|
||||||
|
ImGui::SliderFloat("##slowspeed", &g.world.orbital_drone.nav_ovverride_slow, 0.f, 1.f);
|
||||||
|
ImGui::EndGroup();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user