Add camera scripting

This commit is contained in:
fed 2023-08-14 19:09:51 +02:00
parent 4b507a73ee
commit c086ddeb3f
4 changed files with 170 additions and 9 deletions

View File

@ -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);

View 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();
}

View File

@ -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>();

View File

@ -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;