diff --git a/src/component/game_console.cpp b/src/component/game_console.cpp index f6dc5d75..07a76775 100644 --- a/src/component/game_console.cpp +++ b/src/component/game_console.cpp @@ -234,7 +234,7 @@ namespace game_console con.globals.left_x = con.screen_min[0] + 6.0f; draw_input_box(1, dvars::con_inputBoxColor->current.vector); - draw_input_text_and_over("h1-mod >", color_h2); + draw_input_text_and_over("h2-mod >", color_h2); con.globals.left_x = con.globals.x; con.globals.auto_complete_choice[0] = 0; @@ -385,7 +385,7 @@ namespace game_console const auto width = (con.screen_max[0] - con.screen_min[0]) - 12.0f; const auto height = ((con.screen_max[1] - con.screen_min[1]) - 32.0f) - 12.0f; - game::R_AddCmdDrawText("h1-mod", 0x7FFFFFFF, console_font, x, + game::R_AddCmdDrawText("h2-mod", 0x7FFFFFFF, console_font, x, ((height - 16.0f) + y) + console_font->pixelHeight, 1.0f, 1.0f, 0.0f, color_h2, 0); draw_output_scrollbar(x, y, width, height); diff --git a/src/game/scripting/lua/context.cpp b/src/game/scripting/lua/context.cpp index cd9b1005..453f3595 100644 --- a/src/game/scripting/lua/context.cpp +++ b/src/game/scripting/lua/context.cpp @@ -417,6 +417,7 @@ namespace scripting::lua void context::notify(const event& e) { + this->scheduler_.dispatch(e); this->event_handler_.dispatch(e); } diff --git a/src/game/scripting/lua/context.hpp b/src/game/scripting/lua/context.hpp index 336d7ff6..dbf52472 100644 --- a/src/game/scripting/lua/context.hpp +++ b/src/game/scripting/lua/context.hpp @@ -2,6 +2,9 @@ #include "../event.hpp" +#pragma warning(push) +#pragma warning(disable: 4702) + #define SOL_ALL_SAFETIES_ON 1 #define SOL_PRINT_ERRORS 0 #include diff --git a/src/game/scripting/lua/event_handler.cpp b/src/game/scripting/lua/event_handler.cpp index 2b02a509..c70afc41 100644 --- a/src/game/scripting/lua/event_handler.cpp +++ b/src/game/scripting/lua/event_handler.cpp @@ -3,6 +3,8 @@ #include "error.hpp" #include "value_conversion.hpp" +#include "event_handler.hpp" + namespace scripting::lua { event_handler::event_handler(sol::state& state) @@ -14,26 +16,22 @@ namespace scripting::lua { this->remove(handle); }; + + event_listener_handle_type["endon"] = [this](const event_listener_handle& handle, const entity& entity, const std::string& event) + { + this->add_endon_condition(handle, entity, event); + }; } void event_handler::dispatch(const event& event) { - std::vector arguments; + bool has_built_arguments = false; + event_arguments arguments{}; - for (const auto& argument : event.arguments) - { - arguments.emplace_back(convert(this->state_, argument)); - } - - this->dispatch_to_specific_listeners(event, arguments); - } - - void event_handler::dispatch_to_specific_listeners(const event& event, - const event_arguments& arguments) - { callbacks_.access([&](task_list& tasks) { this->merge_callbacks(); + this->handle_endon_conditions(event); for (auto i = tasks.begin(); i != tasks.end();) { @@ -74,6 +72,27 @@ namespace scripting::lua return {id}; } + void event_handler::add_endon_condition(const event_listener_handle& handle, const entity& entity, + const std::string& event) + { + auto merger = [&](task_list& tasks) + { + for (auto& task : tasks) + { + if (task.id == handle.id) + { + task.endon_conditions.emplace_back(entity, event); + } + } + }; + + callbacks_.access([&](task_list& tasks) + { + merger(tasks); + new_callbacks_.access(merger); + }); + } + void event_handler::clear() { callbacks_.access([&](task_list& tasks) @@ -116,4 +135,36 @@ namespace scripting::lua }); }); } + + void event_handler::handle_endon_conditions(const event& event) + { + auto deleter = [&](task_list& tasks) + { + for (auto& task : tasks) + { + for (auto& condition : task.endon_conditions) + { + if (condition.first == event.entity && condition.second == event.name) + { + task.is_deleted = true; + break; + } + } + } + }; + + callbacks_.access(deleter); + } + + event_arguments event_handler::build_arguments(const event& event) const + { + event_arguments arguments; + + for (const auto& argument : event.arguments) + { + arguments.emplace_back(convert(this->state_, argument)); + } + + return arguments; + } } diff --git a/src/game/scripting/lua/event_handler.hpp b/src/game/scripting/lua/event_handler.hpp index ca554286..981392e7 100644 --- a/src/game/scripting/lua/event_handler.hpp +++ b/src/game/scripting/lua/event_handler.hpp @@ -1,4 +1,5 @@ #pragma once +#include namespace scripting::lua { @@ -19,6 +20,7 @@ namespace scripting::lua event_callback callback = {}; bool is_volatile = false; bool is_deleted = false; + std::vector> endon_conditions{}; }; class event_handler final @@ -46,9 +48,12 @@ namespace scripting::lua utils::concurrency::container new_callbacks_; utils::concurrency::container callbacks_; - void dispatch_to_specific_listeners(const event& event, const event_arguments& arguments); - void remove(const event_listener_handle& handle); void merge_callbacks(); + void handle_endon_conditions(const event& event); + + void add_endon_condition(const event_listener_handle& handle, const entity& entity, const std::string& event); + + event_arguments build_arguments(const event& event) const; }; } diff --git a/src/game/scripting/lua/scheduler.cpp b/src/game/scripting/lua/scheduler.cpp index 781e5cab..2aaaac5b 100644 --- a/src/game/scripting/lua/scheduler.cpp +++ b/src/game/scripting/lua/scheduler.cpp @@ -12,6 +12,35 @@ namespace scripting::lua { this->remove(handle); }; + + task_handle_type["endon"] = [this](const task_handle& handle, const entity& entity, const std::string& event) + { + this->add_endon_condition(handle, entity, event); + }; + } + + void scheduler::dispatch(const event& event) + { + auto deleter = [&](task_list& tasks) + { + for (auto& task : tasks) + { + for (auto& condition : task.endon_conditions) + { + if (condition.first == event.entity && condition.second == event.name) + { + task.is_deleted = true; + break; + } + } + } + }; + + callbacks_.access([&](task_list& tasks) + { + deleter(tasks); + new_callbacks_.access(deleter); + }); } void scheduler::run_frame() @@ -89,6 +118,26 @@ namespace scripting::lua return {id}; } + void scheduler::add_endon_condition(const task_handle& handle, const entity& entity, const std::string& event) + { + auto merger = [&](task_list& tasks) + { + for (auto& task : tasks) + { + if (task.id == handle.id) + { + task.endon_conditions.emplace_back(entity, event); + } + } + }; + + callbacks_.access([&](task_list& tasks) + { + merger(tasks); + new_callbacks_.access(merger); + }); + } + void scheduler::remove(const task_handle& handle) { auto mask_as_deleted = [&](task_list& tasks) diff --git a/src/game/scripting/lua/scheduler.hpp b/src/game/scripting/lua/scheduler.hpp index a939d65f..c2eb2df9 100644 --- a/src/game/scripting/lua/scheduler.hpp +++ b/src/game/scripting/lua/scheduler.hpp @@ -19,6 +19,7 @@ namespace scripting::lua std::chrono::milliseconds delay{}; bool is_volatile = false; bool is_deleted = false; + std::vector> endon_conditions{}; }; class scheduler final @@ -32,6 +33,7 @@ namespace scripting::lua scheduler(const scheduler&) = delete; scheduler& operator=(const scheduler&) = delete; + void dispatch(const event& event); void run_frame(); void clear(); @@ -44,6 +46,8 @@ namespace scripting::lua utils::concurrency::container callbacks_; std::atomic_int64_t current_task_id_ = 0; + void add_endon_condition(const task_handle& handle, const entity& entity, const std::string& event); + void remove(const task_handle& handle); void merge_callbacks(); }; diff --git a/src/game/symbols.hpp b/src/game/symbols.hpp index 2346e01b..6ef5b81c 100644 --- a/src/game/symbols.hpp +++ b/src/game/symbols.hpp @@ -12,6 +12,7 @@ namespace game WEAK symbol Cbuf_AddText{0x59A050}; WEAK symbol CG_GameMessage{0x37F450}; + WEAK symbol CG_GameMessageBold{0x37F1B0}; WEAK symbol Cmd_AddCommandInternal{0x59A5F0}; WEAK symbol Cmd_ExecuteSingleCommand{0x59ABA0};