Add camera scripting
This commit is contained in:
parent
4b507a73ee
commit
c086ddeb3f
@ -3,11 +3,15 @@
|
||||
|
||||
#include "game/game.hpp"
|
||||
#include "game/dvars.hpp"
|
||||
#include "game/ui_scripting/execution.hpp"
|
||||
|
||||
#include "command.hpp"
|
||||
#include "console.hpp"
|
||||
#include "camera.hpp"
|
||||
#include "gui/gui.hpp"
|
||||
|
||||
#include <utils/hook.hpp>
|
||||
#include <utils/concurrency.hpp>
|
||||
|
||||
namespace camera
|
||||
{
|
||||
@ -18,6 +22,9 @@ namespace camera
|
||||
game::dvar_t* cl_free_move_scale = nullptr;
|
||||
game::dvar_t** cg_paused = nullptr;
|
||||
|
||||
using cb_type = std::optional<std::function<void()>>;
|
||||
utils::concurrency::container<cb_type> callback;
|
||||
|
||||
float angle_normalize(const float angle)
|
||||
{
|
||||
const auto value = ((angle * 0.0027777778f) - std::floorf(angle * 0.0027777778f)) * 360.f;
|
||||
@ -40,6 +47,12 @@ namespace camera
|
||||
|
||||
float camera_origin[3]{};
|
||||
|
||||
auto using_camera_override = false;
|
||||
auto using_camera_angles_override = false;
|
||||
|
||||
float camera_origin_override[3]{};
|
||||
float camera_angles_override[3]{};
|
||||
|
||||
void paused_free_move()
|
||||
{
|
||||
if ((*cg_paused)->current.integer != 2)
|
||||
@ -57,10 +70,27 @@ namespace camera
|
||||
return;
|
||||
}
|
||||
|
||||
callback.access([](cb_type& cb)
|
||||
{
|
||||
if (cb.has_value())
|
||||
{
|
||||
auto& fn = cb.value();
|
||||
fn();
|
||||
}
|
||||
});
|
||||
|
||||
if (using_camera_angles_override)
|
||||
{
|
||||
game::cgs->refdefViewAngles[0] = camera_angles_override[0];
|
||||
game::cgs->refdefViewAngles[1] = camera_angles_override[1];
|
||||
game::cgs->refdefViewAngles[2] = camera_angles_override[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
game::cgs->refdefViewAngles[0] = angle_normalize((cmd.angles[0] * 0.000021457672f) + ps->delta_angles[0]);
|
||||
game::cgs->refdefViewAngles[1] = angle_normalize((cmd.angles[1] * 0.000021457672f) + ps->delta_angles[1]);
|
||||
game::cgs->refdefViewAngles[2] = angle_normalize((cmd.angles[2] * 0.000021457672f) + ps->delta_angles[2]);
|
||||
game::cgs->refdefViewAngles[2] = 0;
|
||||
}
|
||||
|
||||
const auto game_time = game::CG_GetGameTime(local_client_num);
|
||||
|
||||
@ -118,9 +148,18 @@ namespace camera
|
||||
ps->origin[2] -= scale * 10.f;
|
||||
}
|
||||
|
||||
if (using_camera_override)
|
||||
{
|
||||
game::refdef->org[0] = camera_origin_override[0];
|
||||
game::refdef->org[1] = camera_origin_override[1];
|
||||
game::refdef->org[2] = camera_origin_override[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
game::refdef->org[0] = ps->origin[0];
|
||||
game::refdef->org[1] = ps->origin[1];
|
||||
game::refdef->org[2] = ps->origin[2] + ps->viewHeightCurrent;
|
||||
}
|
||||
|
||||
camera_origin[0] = game::refdef->org[0];
|
||||
camera_origin[1] = game::refdef->org[1];
|
||||
@ -147,12 +186,95 @@ namespace camera
|
||||
}
|
||||
}
|
||||
|
||||
void enable_free_move()
|
||||
{
|
||||
(*cg_paused)->current.integer = 2;
|
||||
}
|
||||
|
||||
void disable_free_move()
|
||||
{
|
||||
(*cg_paused)->current.integer = 0;
|
||||
}
|
||||
|
||||
bool is_free_move_enabled()
|
||||
{
|
||||
return *cg_paused && (*cg_paused)->current.integer == 2;
|
||||
}
|
||||
|
||||
void set_camera_position(const float x, const float y, const float z)
|
||||
{
|
||||
camera_origin_override[0] = x;
|
||||
camera_origin_override[1] = y;
|
||||
camera_origin_override[2] = z;
|
||||
}
|
||||
|
||||
void set_camera_angles(const float x, const float y, const float z)
|
||||
{
|
||||
camera_angles_override[0] = x;
|
||||
camera_angles_override[1] = y;
|
||||
camera_angles_override[2] = z;
|
||||
}
|
||||
|
||||
void set_using_origin_override(bool value)
|
||||
{
|
||||
using_camera_override = value;
|
||||
}
|
||||
|
||||
void set_using_angles_override(bool value)
|
||||
{
|
||||
using_camera_angles_override = value;
|
||||
}
|
||||
|
||||
ui_scripting::table get_camera_position()
|
||||
{
|
||||
ui_scripting::table res;
|
||||
res["x"] = camera_origin[0];
|
||||
res["y"] = camera_origin[1];
|
||||
res["z"] = camera_origin[2];
|
||||
return res;
|
||||
}
|
||||
|
||||
void set_callback(const ui_scripting::script_value& callback_)
|
||||
{
|
||||
callback.access([=](cb_type& cb)
|
||||
{
|
||||
cb = [=]()
|
||||
{
|
||||
try
|
||||
{
|
||||
const auto state = *game::hks::lua_state;
|
||||
const ui_scripting::table globals = state->globals.v.table;
|
||||
const auto pcall = globals["pcall"];
|
||||
const auto results = pcall(callback_);
|
||||
|
||||
if (!results[0].as<bool>())
|
||||
{
|
||||
const auto error = results[1].as<std::string>();
|
||||
console::error("Error executing camera callback: %s\n", error.data());
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
console::error("Error executing camera callback: %s\n", e.what());
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
void clear_lua()
|
||||
{
|
||||
callback.access([=](cb_type& cb)
|
||||
{
|
||||
cb.reset();
|
||||
});
|
||||
}
|
||||
|
||||
class component final : public component_interface
|
||||
{
|
||||
public:
|
||||
void post_unpack() override
|
||||
{
|
||||
cl_free_move_scale = dvars::register_float("cl_freemoveScale", 1.f, 0.01f, 100.f,
|
||||
cl_free_move_scale = dvars::register_float("cl_freemoveScale", 1.f, 0.0001f, 100.f,
|
||||
game::DVAR_FLAG_SAVED, "Scale how fast you move in cl_freemove mode");
|
||||
|
||||
cg_paused = reinterpret_cast<game::dvar_t**>(0x141E39FC0);
|
||||
|
22
src/client/component/camera.hpp
Normal file
22
src/client/component/camera.hpp
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include "game/ui_scripting/execution.hpp"
|
||||
|
||||
namespace camera
|
||||
{
|
||||
void enable_free_move();
|
||||
void disable_free_move();
|
||||
bool is_free_move_enabled();
|
||||
|
||||
void set_camera_position(const float x, const float y, const float z);
|
||||
void set_camera_angles(const float x, const float y, const float z);
|
||||
|
||||
void set_using_origin_override(bool value);
|
||||
void set_using_angles_override(bool value);
|
||||
|
||||
ui_scripting::table get_camera_position();
|
||||
|
||||
void set_callback(const ui_scripting::script_value& callback);
|
||||
|
||||
void clear_lua();
|
||||
}
|
@ -18,6 +18,7 @@
|
||||
#include "config.hpp"
|
||||
#include "motd.hpp"
|
||||
#include "achievements.hpp"
|
||||
#include "camera.hpp"
|
||||
|
||||
#include "game/ui_scripting/execution.hpp"
|
||||
#include "game/scripting/execution.hpp"
|
||||
@ -708,6 +709,20 @@ namespace ui_scripting
|
||||
|
||||
return table;
|
||||
};
|
||||
|
||||
table camera_table;
|
||||
lua["camera"] = camera_table;
|
||||
|
||||
camera::clear_lua();
|
||||
camera_table["enablefreemove"] = camera::enable_free_move;
|
||||
camera_table["disablefreemove"] = camera::disable_free_move;
|
||||
camera_table["isfreemoveenabled"] = camera::is_free_move_enabled;
|
||||
camera_table["setposition"] = camera::set_camera_position;
|
||||
camera_table["setangles"] = camera::set_camera_angles;
|
||||
camera_table["getposition"] = camera::get_camera_position;
|
||||
camera_table["setusingoriginoverride"] = camera::set_using_origin_override;
|
||||
camera_table["setusinganglesoverride"] = camera::set_using_angles_override;
|
||||
camera_table["setcallback"] = camera::set_callback;
|
||||
}
|
||||
|
||||
void start()
|
||||
@ -788,6 +803,7 @@ namespace ui_scripting
|
||||
|
||||
void hks_shutdown_stub()
|
||||
{
|
||||
camera::clear_lua();
|
||||
converted_functions.clear();
|
||||
globals = {};
|
||||
hks_shutdown_hook.invoke<void>();
|
||||
|
@ -69,7 +69,8 @@ namespace game
|
||||
{
|
||||
char __pad0[26];
|
||||
vec3_t origin;
|
||||
char __pad1[100];
|
||||
vec3_t angles;
|
||||
char __pad1[88];
|
||||
EntityState s;
|
||||
char __pad2[50];
|
||||
Bounds box;
|
||||
|
Loading…
Reference in New Issue
Block a user