#include "FreeCam.h" #include "helpers.h" #include FreeCamModule::FreeCamModule() : BaseModule("FreeCam", "Free Camera", ModuleCategory::Visual) {} void FreeCamModule::RegisterTab() { keys_.toggle = VK_OEM_3; } const char* FreeCamModule::KeyName(int vk) { static thread_local char name[64]; if (vk <= 0) { return "NONE"; } UINT scan = MapVirtualKeyA(static_cast(vk), MAPVK_VK_TO_VSC); LONG lp = static_cast(scan << 16); if (GetKeyNameTextA(lp, name, static_cast(sizeof(name))) > 0) { return name; } return "NONE"; } void FreeCamModule::Render() { if (!ImGui::CollapsingHeader(Tr("Free Camera"), ImGuiTreeNodeFlags_DefaultOpen)) { return; } bool enabled = Enabled(); if (ImGui::Checkbox(Tr("ON / OFF"), &enabled)) { SetEnabled(enabled); if (!enabled) { active_cam_ptr_ = nullptr; override_cam_ptr_ = nullptr; cam_override_active_ = false; } } if (!Enabled()) { return; } ImGui::DragFloat(Tr("Move Speed"), &move_speed_, 0.1f, 0.1f, 500.0f, "%.3f"); ImGui::DragFloat(Tr("Look Sensitivity"), &look_sensitivity_, 0.1f, 0.1f, 500.0f, "%.3f"); ImGui::DragFloat(Tr("Roll Speed"), &roll_speed_, 0.1f, 0.1f, 100.0f, "%.3f"); ImGui::DragFloat(Tr("FOV Speed"), &fov_speed_, 0.1f, 0.1f, 100.0f, "%.3f"); ImGui::DragFloat(Tr("FOV"), &fov_value_, 0.1f, 1.0f, 179.0f, "%.1f"); char row[96]; std::snprintf(row, sizeof(row), "Forward Key: %s", KeyName(keys_.forward)); ImGui::TextUnformatted(row); std::snprintf(row, sizeof(row), "Backward Key: %s", KeyName(keys_.backward)); ImGui::TextUnformatted(row); std::snprintf(row, sizeof(row), "Left Key: %s", KeyName(keys_.left)); ImGui::TextUnformatted(row); std::snprintf(row, sizeof(row), "Right Key: %s", KeyName(keys_.right)); ImGui::TextUnformatted(row); std::snprintf(row, sizeof(row), "Up Key: %s", KeyName(keys_.up)); ImGui::TextUnformatted(row); std::snprintf(row, sizeof(row), "Down Key: %s", KeyName(keys_.down)); ImGui::TextUnformatted(row); std::snprintf(row, sizeof(row), "IncFOV Key: %s", KeyName(keys_.inc_fov)); ImGui::TextUnformatted(row); std::snprintf(row, sizeof(row), "DecFOV Key: %s", KeyName(keys_.dec_fov)); ImGui::TextUnformatted(row); std::snprintf(row, sizeof(row), "LeftRoll Key: %s", KeyName(keys_.left_roll)); ImGui::TextUnformatted(row); std::snprintf(row, sizeof(row), "RightRoll Key: %s", KeyName(keys_.right_roll)); ImGui::TextUnformatted(row); std::snprintf(row, sizeof(row), "ResetRoll Key: %s", KeyName(keys_.reset_roll)); ImGui::TextUnformatted(row); } void FreeCamModule::Update() { if (!Enabled()) { return; } using FnCameraMain = void* (*)(void*); using FnGetTransform = void* (*)(void*); using FnGetPosition = Vec3* (*)(void*); using FnSetPosition = void (*)(void*, Vec3*); auto camera_main = GetIl2cppFn(IL2CPP::Camera_get_main); auto get_transform = GetIl2cppFn(IL2CPP::GameObject_get_transform); auto get_position = GetIl2cppFn(IL2CPP::Transform_get_position); auto set_position = GetIl2cppFn(IL2CPP::Transform_set_position); if (!camera_main || !get_transform || !get_position || !set_position) { return; } void* camera = camera_main(nullptr); if (!camera) { return; } void* transform = get_transform(camera); if (!transform) { return; } Vec3 pos = {}; Vec3* pos_ptr = get_position(transform); if (!pos_ptr) { return; } pos = *pos_ptr; const float dt = ImGui::GetIO().DeltaTime; const float speed = move_speed_ * dt; if (GetAsyncKeyState(keys_.forward) & 0x8000) pos.z += speed; if (GetAsyncKeyState(keys_.backward) & 0x8000) pos.z -= speed; if (GetAsyncKeyState(keys_.left) & 0x8000) pos.x -= speed; if (GetAsyncKeyState(keys_.right) & 0x8000) pos.x += speed; if (GetAsyncKeyState(keys_.up) & 0x8000) pos.y += speed; if (GetAsyncKeyState(keys_.down) & 0x8000) pos.y -= speed; set_position(transform, &pos); active_cam_ptr_ = camera; cam_override_active_ = true; } void FreeCamModule::OnHotkey() { if (IsKeyPressedOnce(keys_.toggle)) { SetEnabled(!Enabled()); } }