Fix console cursor, add chat
This commit is contained in:
parent
e78eb74060
commit
90427d7324
88
src/component/chat.cpp
Normal file
88
src/component/chat.cpp
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
#include <stdinc.hpp>
|
||||||
|
#include "chat.hpp"
|
||||||
|
#include "scheduler.hpp"
|
||||||
|
|
||||||
|
#include "game/game.hpp"
|
||||||
|
#include "game/dvars.hpp"
|
||||||
|
|
||||||
|
#include <utils/string.hpp>
|
||||||
|
#include <utils/hook.hpp>
|
||||||
|
|
||||||
|
#define chat_font game::R_RegisterFont("fonts/fira_mono_regular.ttf", 25)
|
||||||
|
#define material_white game::Material_RegisterHandle("white")
|
||||||
|
|
||||||
|
namespace chat
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
struct message
|
||||||
|
{
|
||||||
|
std::string text;
|
||||||
|
std::chrono::steady_clock::time_point time;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::deque<message> history;
|
||||||
|
|
||||||
|
float color_white[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||||
|
|
||||||
|
float screen_max[2];
|
||||||
|
|
||||||
|
void check_resize()
|
||||||
|
{
|
||||||
|
screen_max[0] = game::ScrPlace_GetViewPlacement()->realViewportSize[0];
|
||||||
|
screen_max[1] = game::ScrPlace_GetViewPlacement()->realViewportSize[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
float relative(float value)
|
||||||
|
{
|
||||||
|
const auto ratio = screen_max[0] / 2560.f;
|
||||||
|
|
||||||
|
return value * ratio;
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_chat()
|
||||||
|
{
|
||||||
|
check_resize();
|
||||||
|
|
||||||
|
const auto now = std::chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
|
for (auto i = 0; i < std::min(15, (int)history.size()); i++)
|
||||||
|
{
|
||||||
|
if (now - history[i].time > 11s)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto diff = now - history[i].time;
|
||||||
|
|
||||||
|
float color[4] = { color_white[0], color_white[1], color_white[2], 1.f };
|
||||||
|
|
||||||
|
if (diff > 10.5s)
|
||||||
|
{
|
||||||
|
const auto milliseconds = (float)(11000 - std::chrono::duration_cast<std::chrono::milliseconds>(diff).count());
|
||||||
|
|
||||||
|
color[3] = (float)(milliseconds / 500.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
game::R_AddCmdDrawText(history[i].text.data(), 0x7FFFFFFF, chat_font, relative(15.f), relative(600.f + i * 25), 1.f, 1.f, 0.f, color, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print(const std::string& msg)
|
||||||
|
{
|
||||||
|
message m;
|
||||||
|
m.text = msg;
|
||||||
|
m.time = std::chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
|
history.push_front(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
void init()
|
||||||
|
{
|
||||||
|
scheduler::loop([]()
|
||||||
|
{
|
||||||
|
draw_chat();
|
||||||
|
}, scheduler::pipeline::renderer);
|
||||||
|
}
|
||||||
|
}
|
8
src/component/chat.hpp
Normal file
8
src/component/chat.hpp
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace chat
|
||||||
|
{
|
||||||
|
void print(const std::string& msg);
|
||||||
|
|
||||||
|
void init();
|
||||||
|
}
|
@ -146,6 +146,11 @@ namespace command
|
|||||||
{
|
{
|
||||||
utils::hook::jump(game::base_address + 0x5A74F0, dvar_command_stub, true);
|
utils::hook::jump(game::base_address + 0x5A74F0, dvar_command_stub, true);
|
||||||
|
|
||||||
|
add("say", [](const params& params)
|
||||||
|
{
|
||||||
|
chat::print(params.join(1));
|
||||||
|
});
|
||||||
|
|
||||||
add("listassetpool", [](const params& params)
|
add("listassetpool", [](const params& params)
|
||||||
{
|
{
|
||||||
if (params.size() < 2)
|
if (params.size() < 2)
|
||||||
|
@ -6,6 +6,10 @@
|
|||||||
#include "game/game.hpp"
|
#include "game/game.hpp"
|
||||||
#include "game/dvars.hpp"
|
#include "game/dvars.hpp"
|
||||||
|
|
||||||
|
#include "game/scripting/event.hpp"
|
||||||
|
#include "game/scripting/execution.hpp"
|
||||||
|
#include "game/scripting/lua/engine.hpp"
|
||||||
|
|
||||||
#include <utils/string.hpp>
|
#include <utils/string.hpp>
|
||||||
#include <utils/hook.hpp>
|
#include <utils/hook.hpp>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
@ -215,9 +219,9 @@ namespace game_console
|
|||||||
con.globals.left_x = con.globals.x;
|
con.globals.left_x = con.globals.x;
|
||||||
con.globals.auto_complete_choice[0] = 0;
|
con.globals.auto_complete_choice[0] = 0;
|
||||||
|
|
||||||
game::R_AddCmdDrawText(con.buffer, 0x7FFFFFFF, console_font, con.globals.x,
|
game::R_AddCmdDrawTextWithCursor(con.buffer, 0x7FFFFFFF, console_font, 18, con.globals.x,
|
||||||
con.globals.y + con.globals.font_height, 1.0f, 1.0f, 0.0f, color_white, 0/*,
|
con.globals.y + con.globals.font_height, 1.0f, 1.0f, 0, color_white, 0,
|
||||||
con.cursor, '|'*/);
|
con.cursor, '|');
|
||||||
|
|
||||||
// check if using a prefixed '/' or not
|
// check if using a prefixed '/' or not
|
||||||
const auto input = con.buffer[1] && (con.buffer[0] == '/' || con.buffer[0] == '\\')
|
const auto input = con.buffer[1] && (con.buffer[0] == '/' || con.buffer[0] == '\\')
|
||||||
@ -470,6 +474,18 @@ namespace game_console
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void execute(const char* cmd)
|
||||||
|
{
|
||||||
|
scripting::event e;
|
||||||
|
e.name = "console_command";
|
||||||
|
e.arguments.push_back(cmd);
|
||||||
|
e.entity = *game::levelEntityId;
|
||||||
|
|
||||||
|
scripting::lua::engine::notify(e);
|
||||||
|
|
||||||
|
game::Cbuf_AddText(0, utils::string::va("%s \n", cmd));
|
||||||
|
}
|
||||||
|
|
||||||
bool console_key_event(const int localClientNum, const int key, const int down)
|
bool console_key_event(const int localClientNum, const int key, const int down)
|
||||||
{
|
{
|
||||||
if (key == game::keyNum_t::K_F10)
|
if (key == game::keyNum_t::K_F10)
|
||||||
@ -573,7 +589,7 @@ namespace game_console
|
|||||||
|
|
||||||
if (key == game::keyNum_t::K_ENTER)
|
if (key == game::keyNum_t::K_ENTER)
|
||||||
{
|
{
|
||||||
game::Cbuf_AddText(0, utils::string::va("%s \n", fixed_input.data()));
|
execute(fixed_input.data());
|
||||||
|
|
||||||
if (history_index != -1)
|
if (history_index != -1)
|
||||||
{
|
{
|
||||||
|
@ -14,5 +14,7 @@ namespace game_console
|
|||||||
bool console_char_event(int local_client_num, int key);
|
bool console_char_event(int local_client_num, int key);
|
||||||
bool console_key_event(int local_client_num, int key, int down);
|
bool console_key_event(int local_client_num, int key, int down);
|
||||||
|
|
||||||
|
void execute(const char* cmd);
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
}
|
}
|
@ -17,7 +17,7 @@ DWORD WINAPI dwConsole(LPVOID)
|
|||||||
std::cout << "\n";
|
std::cout << "\n";
|
||||||
std::getline(std::cin, cmd);
|
std::getline(std::cin, cmd);
|
||||||
|
|
||||||
game::Cbuf_AddText(0, cmd.data());
|
game_console::execute(cmd.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -36,6 +36,7 @@ void init()
|
|||||||
scheduler::init();
|
scheduler::init();
|
||||||
game_console::init();
|
game_console::init();
|
||||||
scripting::init();
|
scripting::init();
|
||||||
|
chat::init();
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
|
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
|
||||||
|
@ -168,6 +168,11 @@ namespace scripting::lua
|
|||||||
{
|
{
|
||||||
command::execute(command, false);
|
command::execute(command, false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
game_type["say"] = [](const game&, const std::string& msg)
|
||||||
|
{
|
||||||
|
chat::print(msg);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,8 +44,8 @@ namespace game
|
|||||||
float* color, Material* material)> R_AddCmdDrawStretchPic{0x3C9710};
|
float* color, Material* material)> R_AddCmdDrawStretchPic{0x3C9710};
|
||||||
WEAK symbol<void(const char* text, int maxChars, Font_s* font, float x, float y, float xScale, float yScale,
|
WEAK symbol<void(const char* text, int maxChars, Font_s* font, float x, float y, float xScale, float yScale,
|
||||||
float rotation, float* color, int style)> R_AddCmdDrawText{0x76C660};
|
float rotation, float* color, int style)> R_AddCmdDrawText{0x76C660};
|
||||||
WEAK symbol<void(const char*, int, Font_s*, float, float, float, float, float, const float*, int, int, char)>
|
WEAK symbol<void(const char* text, int maxChars, Font_s* font, int fontSize, float x, float y, float xScale, float yScale, float rotation,
|
||||||
R_AddCmdDrawTextWithCursor{0x769D90};
|
const float* color, int style, int cursorPos, char cursor)> R_AddCmdDrawTextWithCursor{0x76CAF0};
|
||||||
WEAK symbol<Font_s*(const char* font, int size)> R_RegisterFont{0x746FE0};
|
WEAK symbol<Font_s*(const char* font, int size)> R_RegisterFont{0x746FE0};
|
||||||
WEAK symbol<int(const char* text, int maxChars, Font_s* font)> R_TextWidth{0x7472A0};
|
WEAK symbol<int(const char* text, int maxChars, Font_s* font)> R_TextWidth{0x7472A0};
|
||||||
|
|
||||||
|
@ -21,6 +21,15 @@
|
|||||||
#include <cstdarg>
|
#include <cstdarg>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <csetjmp>
|
#include <csetjmp>
|
||||||
|
#include <deque>
|
||||||
|
|
||||||
|
#ifdef max
|
||||||
|
#undef max
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef min
|
||||||
|
#undef min
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <MinHook.h>
|
#include <MinHook.h>
|
||||||
#include <gsl/gsl>
|
#include <gsl/gsl>
|
||||||
@ -42,3 +51,4 @@ using namespace std::literals;
|
|||||||
#include "component/scheduler.hpp"
|
#include "component/scheduler.hpp"
|
||||||
#include "component/input.hpp"
|
#include "component/input.hpp"
|
||||||
#include "component/game_console.hpp"
|
#include "component/game_console.hpp"
|
||||||
|
#include "component/chat.hpp"
|
||||||
|
Loading…
Reference in New Issue
Block a user