Some fixes + set entity field window
This commit is contained in:
parent
5c31d10e1f
commit
6e7e1c57ec
@ -72,15 +72,8 @@ namespace gui
|
||||
{
|
||||
if (ImGui::BeginMenu("Windows"))
|
||||
{
|
||||
if (ImGui::MenuItem("Asset list"))
|
||||
{
|
||||
toggle_menu("asset_list");
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem("Entity list"))
|
||||
{
|
||||
toggle_menu("entity_list");
|
||||
}
|
||||
ImGui::Checkbox("Asset list", &enabled_menus["asset_list"]);
|
||||
ImGui::Checkbox("Entity list", &enabled_menus["entity_list"]);
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
@ -19,6 +19,8 @@ namespace entity_list
|
||||
{
|
||||
namespace
|
||||
{
|
||||
game::dvar_t* sv_running = nullptr;
|
||||
|
||||
enum entity_type
|
||||
{
|
||||
type_any,
|
||||
@ -70,6 +72,7 @@ namespace entity_list
|
||||
std::chrono::milliseconds interval{};
|
||||
std::chrono::high_resolution_clock::time_point last_call{};
|
||||
std::vector<entity_info_t> entity_info{};
|
||||
std::vector<std::function<void()>> tasks;
|
||||
std::unordered_map<std::string, bool> selected_fields =
|
||||
{
|
||||
{"code_classname", false},
|
||||
@ -277,6 +280,19 @@ namespace entity_list
|
||||
};
|
||||
|
||||
utils::concurrency::container<data_t> data_;
|
||||
unsigned int selected_entity{};
|
||||
bool set_field_window{};
|
||||
int selected_type = game::SCRIPT_INTEGER;
|
||||
|
||||
bool is_sv_running()
|
||||
{
|
||||
if (!sv_running)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return sv_running->current.enabled;
|
||||
}
|
||||
|
||||
bool verify_entity(unsigned int id)
|
||||
{
|
||||
@ -368,6 +384,13 @@ namespace entity_list
|
||||
{
|
||||
data_.access([](data_t& data)
|
||||
{
|
||||
for (const auto& task : data.tasks)
|
||||
{
|
||||
task();
|
||||
}
|
||||
|
||||
data.tasks = {};
|
||||
|
||||
const auto now = std::chrono::high_resolution_clock::now();
|
||||
if (!data.force_update && (!data.auto_update || (now - data.last_call < data.interval)))
|
||||
{
|
||||
@ -455,9 +478,9 @@ namespace entity_list
|
||||
});
|
||||
}
|
||||
|
||||
void teleport_to(unsigned int id)
|
||||
void teleport_to(data_t& data, unsigned int id)
|
||||
{
|
||||
scheduler::once([id]()
|
||||
data.tasks.push_back([id]()
|
||||
{
|
||||
if (!verify_entity(id))
|
||||
{
|
||||
@ -473,12 +496,12 @@ namespace entity_list
|
||||
|
||||
const auto player = value.as<scripting::entity>();
|
||||
player.call("setorigin", {dest.get("origin")});
|
||||
}, scheduler::pipeline::server);
|
||||
});
|
||||
}
|
||||
|
||||
void teleport_to_reverse(unsigned int id)
|
||||
void teleport_to_reverse(data_t& data, unsigned int id)
|
||||
{
|
||||
scheduler::once([id]()
|
||||
data.tasks.push_back([id]()
|
||||
{
|
||||
if (!verify_entity(id))
|
||||
{
|
||||
@ -494,12 +517,12 @@ namespace entity_list
|
||||
|
||||
const auto player = value.as<scripting::entity>();
|
||||
dest.set("origin", player.get("origin"));
|
||||
}, scheduler::pipeline::server);
|
||||
});
|
||||
}
|
||||
|
||||
void delete_entity(unsigned int id)
|
||||
void delete_entity(data_t& data, unsigned int id)
|
||||
{
|
||||
scheduler::once([id]()
|
||||
data.tasks.push_back([id]()
|
||||
{
|
||||
if (!verify_entity(id))
|
||||
{
|
||||
@ -508,18 +531,129 @@ namespace entity_list
|
||||
|
||||
const auto target = scripting::entity{id};
|
||||
target.call("delete");
|
||||
}, scheduler::pipeline::server);
|
||||
});
|
||||
}
|
||||
|
||||
void on_frame()
|
||||
void set_entity_field(data_t& data, unsigned int id,
|
||||
const std::string& name, const std::string& string_value, int type)
|
||||
{
|
||||
if (!gui::enabled_menus["entity_list"])
|
||||
data.tasks.push_back([id, name, type, string_value, &data]()
|
||||
{
|
||||
if (!verify_entity(id))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
data_.access([](data_t& data)
|
||||
scripting::script_value value{};
|
||||
|
||||
if (type == game::SCRIPT_INTEGER)
|
||||
{
|
||||
value = atoi(string_value.data());
|
||||
}
|
||||
|
||||
if (type == game::SCRIPT_FLOAT)
|
||||
{
|
||||
value = atof(string_value.data());
|
||||
}
|
||||
|
||||
if (type == game::SCRIPT_STRING)
|
||||
{
|
||||
value = string_value;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
scripting::set_entity_field(id, name, value);
|
||||
data.force_update = true;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void set_entity_field_vector(data_t& data, unsigned int id,
|
||||
const std::string& name, const scripting::vector& value)
|
||||
{
|
||||
data.tasks.push_back([id, name, value, &data]()
|
||||
{
|
||||
if (!verify_entity(id))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
scripting::set_entity_field(id, name, value);
|
||||
data.force_update = true;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void show_set_field_window(data_t& data)
|
||||
{
|
||||
static char name[0x100]{};
|
||||
static char value[0x100]{};
|
||||
|
||||
static char x[0x100]{};
|
||||
static char y[0x100]{};
|
||||
static char z[0x100]{};
|
||||
|
||||
ImGui::SetNextWindowSizeConstraints(ImVec2(300, 300), ImVec2(300, 300));
|
||||
ImGui::Begin("Set entity field", &set_field_window);
|
||||
ImGui::SetWindowSize(ImVec2(300, 300));
|
||||
ImGui::Text(utils::string::va("Entity id %i", selected_entity));
|
||||
|
||||
if (ImGui::TreeNode("Type"))
|
||||
{
|
||||
ImGui::RadioButton("integer", &selected_type, game::SCRIPT_INTEGER);
|
||||
ImGui::RadioButton("float", &selected_type, game::SCRIPT_FLOAT);
|
||||
ImGui::RadioButton("vector", &selected_type, game::SCRIPT_VECTOR);
|
||||
ImGui::RadioButton("string", &selected_type, game::SCRIPT_STRING);
|
||||
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
ImGui::InputText("name", name, IM_ARRAYSIZE(name));
|
||||
if (selected_type == game::SCRIPT_VECTOR)
|
||||
{
|
||||
ImGui::InputText("x", x, IM_ARRAYSIZE(x));
|
||||
ImGui::InputText("y", y, IM_ARRAYSIZE(y));
|
||||
ImGui::InputText("z", z, IM_ARRAYSIZE(z));
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui::InputText("value", value, IM_ARRAYSIZE(value));
|
||||
}
|
||||
|
||||
if (ImGui::Button("set", ImVec2(300, 0)))
|
||||
{
|
||||
if (selected_type == game::SCRIPT_VECTOR)
|
||||
{
|
||||
const scripting::vector vector
|
||||
{
|
||||
static_cast<float>(atof(x)),
|
||||
static_cast<float>(atof(y)),
|
||||
static_cast<float>(atof(z))
|
||||
};
|
||||
|
||||
set_entity_field_vector(data, selected_entity, name, vector);
|
||||
}
|
||||
else
|
||||
{
|
||||
set_entity_field(data, selected_entity, name, value, selected_type);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void show_entity_list_window(data_t& data)
|
||||
{
|
||||
ImGui::SetNextWindowSizeConstraints(ImVec2(500, 500), ImVec2(1000, 1000));
|
||||
ImGui::Begin("Entity list", &gui::enabled_menus["entity_list"]);
|
||||
|
||||
if (ImGui::Button("Update list"))
|
||||
@ -619,21 +753,27 @@ namespace entity_list
|
||||
{
|
||||
ImGui::Text("Commands");
|
||||
|
||||
if (ImGui::Button("Set field"))
|
||||
{
|
||||
set_field_window = true;
|
||||
selected_entity = info.id;
|
||||
}
|
||||
|
||||
if (ImGui::Button("Teleport to"))
|
||||
{
|
||||
teleport_to(info.id);
|
||||
teleport_to(data, info.id);
|
||||
data.force_update = true;
|
||||
}
|
||||
|
||||
if (ImGui::Button("Teleport to you"))
|
||||
{
|
||||
teleport_to_reverse(info.id);
|
||||
teleport_to_reverse(data, info.id);
|
||||
data.force_update = true;
|
||||
}
|
||||
|
||||
if (info.num != 0 && ImGui::Button("Delete"))
|
||||
{
|
||||
delete_entity(info.id);
|
||||
delete_entity(data, info.id);
|
||||
data.force_update = true;
|
||||
}
|
||||
|
||||
@ -679,6 +819,29 @@ namespace entity_list
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void on_frame()
|
||||
{
|
||||
if (!gui::enabled_menus["entity_list"])
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
data_.access([](data_t& data)
|
||||
{
|
||||
if (!is_sv_running())
|
||||
{
|
||||
selected_entity = 0;
|
||||
data.entity_info = {};
|
||||
data.tasks = {};
|
||||
}
|
||||
|
||||
show_entity_list_window(data);
|
||||
if (selected_entity && set_field_window)
|
||||
{
|
||||
show_set_field_window(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -688,6 +851,11 @@ namespace entity_list
|
||||
public:
|
||||
void post_unpack() override
|
||||
{
|
||||
scheduler::on_game_initialized([]()
|
||||
{
|
||||
sv_running = game::Dvar_FindVar("sv_running");
|
||||
});
|
||||
|
||||
gui::on_frame(on_frame);
|
||||
scheduler::loop(update_entity_list, scheduler::pipeline::server, 0ms);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user