mirror of
https://github.com/EQEmu/Server.git
synced 2026-04-05 15:22:37 +00:00
- License was intended to be GPLv3 per earlier commit of GPLv3 LICENSE FILE - This is confirmed by the inclusion of libraries that are incompatible with GPLv2 - This is also confirmed by KLS and the agreement of KLS's predecessors - Added GPLv3 license headers to the compilable source files - Removed Folly licensing in strings.h since the string functions do not match the Folly functions and are standard functions - this must have been left over from previous implementations - Removed individual contributor license headers since the project has been under the "developer" mantle for many years - Removed comments on files that were previously automatically generated since they've been manually modified multiple times and there are no automatic scripts referencing them (removed in 2023)
741 lines
20 KiB
C++
741 lines
20 KiB
C++
/* EQEmu: EQEmulator
|
|
|
|
Copyright (C) 2001-2026 EQEmu Development Team
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
#include "door_manipulation.h"
|
|
|
|
#include "common/misc_functions.h"
|
|
#include "common/strings.h"
|
|
#include "zone/doors.h"
|
|
|
|
#define MAX_CLIENT_MESSAGE_LENGTH 2000
|
|
|
|
void DoorManipulation::CommandHandler(Client *c, const Seperator *sep)
|
|
{
|
|
// this should never happen
|
|
if (!c) {
|
|
return;
|
|
}
|
|
|
|
// args
|
|
std::string arg1(sep->arg[1]);
|
|
std::string arg2(sep->arg[2]);
|
|
std::string arg3(sep->arg[3]);
|
|
|
|
// table check
|
|
std::string table_name = "tool_game_objects";
|
|
std::string url = "https://raw.githubusercontent.com/EQEmu/database-tool-sqls/main/tool_game_objects.sql";
|
|
if (!database.DoesTableExist(table_name)) {
|
|
c->Message(
|
|
Chat::White,
|
|
fmt::format(
|
|
"Table [{}] does not exist. Downloading from [{}] and installing locally",
|
|
table_name,
|
|
url
|
|
).c_str()
|
|
);
|
|
database.SourceDatabaseTableFromUrl(
|
|
table_name,
|
|
url
|
|
);
|
|
}
|
|
|
|
if (arg1 == "drawbox") {
|
|
Doors *door = entity_list.GetDoorsByID(c->GetDoorToolEntityId());
|
|
|
|
if (door) {
|
|
uint16 door_size = 15;
|
|
float door_depth = 5.0f;
|
|
|
|
if (sep->IsNumber(2) && atof(sep->arg[2]) > 0) {
|
|
door_size = atof(sep->arg[2]);
|
|
}
|
|
|
|
if (sep->IsNumber(3) && atof(sep->arg[3]) > 0) {
|
|
door_depth = atof(sep->arg[3]);
|
|
}
|
|
|
|
|
|
door->IsDoorBetween(c->GetPosition(), (c->GetTarget() ? c->GetTarget()->GetPosition() : c->GetPosition()), door_size, door_depth, true);
|
|
}
|
|
}
|
|
|
|
// edit menu
|
|
if (arg1 == "edit") {
|
|
Doors *door = entity_list.GetDoorsByID(c->GetDoorToolEntityId());
|
|
if (door) {
|
|
|
|
const std::string move_x_action = "move_x";
|
|
const std::string move_y_action = "move_y";
|
|
const std::string move_z_action = "move_z";
|
|
const std::string move_h_action = "move_h";
|
|
const std::string set_size_action = "set_size";
|
|
|
|
// we're passing a move action here
|
|
if (!arg3.empty() && (Strings::IsFloat(arg3) || Strings::IsNumber(arg3))) {
|
|
float x_move = 0.0f;
|
|
float y_move = 0.0f;
|
|
float z_move = 0.0f;
|
|
float h_move = 0.0f;
|
|
float set_size = 0.0f;
|
|
|
|
if (arg2 == move_x_action) {
|
|
x_move = Strings::ToFloat(arg3);
|
|
}
|
|
|
|
if (arg2 == move_y_action) {
|
|
y_move = Strings::ToFloat(arg3);
|
|
}
|
|
|
|
if (arg2 == move_z_action) {
|
|
z_move = Strings::ToFloat(arg3);
|
|
}
|
|
|
|
if (arg2 == move_h_action) {
|
|
h_move = Strings::ToFloat(arg3);
|
|
}
|
|
|
|
if (arg2 == set_size_action) {
|
|
set_size = Strings::ToFloat(arg3);
|
|
}
|
|
|
|
door->SetLocation(
|
|
door->GetX() + x_move,
|
|
door->GetY() + y_move,
|
|
door->GetZ() + z_move
|
|
);
|
|
|
|
glm::vec4 door_position = door->GetPosition();
|
|
door_position.w = door_position.w + h_move;
|
|
door->SetPosition(door_position);
|
|
door->SetSize(door->GetSize() + set_size);
|
|
|
|
// spawn and move helpers
|
|
uint16 helper_mob_x_negative = 0;
|
|
uint16 helper_mob_x_positive = 0;
|
|
uint16 helper_mob_y_positive = 0;
|
|
uint16 helper_mob_y_negative = 0;
|
|
|
|
for (auto &n: entity_list.GetNPCList()) {
|
|
NPC *npc = n.second;
|
|
std::string npc_name = npc->GetName();
|
|
if (npc_name.find("-X") != std::string::npos) {
|
|
helper_mob_x_negative = npc->GetID();
|
|
}
|
|
if (npc_name.find("-Y") != std::string::npos) {
|
|
helper_mob_y_negative = npc->GetID();
|
|
}
|
|
if (npc_name.find("+X") != std::string::npos) {
|
|
helper_mob_x_positive = npc->GetID();
|
|
}
|
|
if (npc_name.find("+Y") != std::string::npos) {
|
|
helper_mob_y_positive = npc->GetID();
|
|
}
|
|
}
|
|
|
|
// -X
|
|
door_position = door->GetPosition();
|
|
if (helper_mob_x_negative == 0) {
|
|
door_position.x = door_position.x - 15;
|
|
helper_mob_x_negative = NPC::SpawnNodeNPC("-X", "", door_position)->GetID();
|
|
}
|
|
else {
|
|
auto n = entity_list.GetNPCByID(helper_mob_x_negative);
|
|
n->GMMove(door->GetX() - 15, door->GetY(), door->GetZ(), n->GetHeading());
|
|
}
|
|
|
|
// +X
|
|
door_position = door->GetPosition();
|
|
if (helper_mob_x_positive == 0) {
|
|
door_position.x = door_position.x + 15;
|
|
helper_mob_x_positive = NPC::SpawnNodeNPC("+X", "", door_position)->GetID();
|
|
}
|
|
else {
|
|
auto n = entity_list.GetNPCByID(helper_mob_x_positive);
|
|
n->GMMove(door->GetX() + 15, door->GetY(), door->GetZ(), n->GetHeading());
|
|
}
|
|
|
|
// -Y
|
|
door_position = door->GetPosition();
|
|
if (helper_mob_y_negative == 0) {
|
|
door_position.y = door_position.y - 15;
|
|
helper_mob_y_negative = NPC::SpawnNodeNPC("-Y", "", door_position)->GetID();
|
|
}
|
|
else {
|
|
auto n = entity_list.GetNPCByID(helper_mob_y_negative);
|
|
n->GMMove(door->GetX(), door->GetY() - 15, door->GetZ(), n->GetHeading());
|
|
}
|
|
|
|
// +Y
|
|
door_position = door->GetPosition();
|
|
if (helper_mob_y_positive == 0) {
|
|
door_position.y = door_position.y + 15;
|
|
helper_mob_y_positive = NPC::SpawnNodeNPC("+Y", "", door_position)->GetID();
|
|
}
|
|
else {
|
|
auto n = entity_list.GetNPCByID(helper_mob_y_positive);
|
|
n->GMMove(door->GetX(), door->GetY() + 15, door->GetZ(), n->GetHeading());
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
c->Message(
|
|
Chat::White,
|
|
fmt::format(
|
|
"Door Selected ID [{}] Name [{}] OpenType [{}] Invertstate [{} | {}/{}] ",
|
|
c->GetDoorToolEntityId(),
|
|
door->GetDoorName(),
|
|
door->GetOpenType(),
|
|
door->GetInvertState(),
|
|
Saylink::Silent("#door setinvertstate 0", "0"),
|
|
Saylink::Silent("#door setinvertstate 1", "1")
|
|
).c_str()
|
|
);
|
|
|
|
|
|
std::vector<std::string> move_options = {
|
|
move_x_action,
|
|
move_y_action,
|
|
move_z_action,
|
|
move_h_action,
|
|
set_size_action
|
|
};
|
|
std::vector<std::string> move_x_options_positive;
|
|
std::vector<std::string> move_x_options_negative;
|
|
std::vector<std::string> move_y_options_positive;
|
|
std::vector<std::string> move_y_options_negative;
|
|
std::vector<std::string> move_z_options_positive;
|
|
std::vector<std::string> move_z_options_negative;
|
|
std::vector<std::string> move_h_options_positive;
|
|
std::vector<std::string> move_h_options_negative;
|
|
std::vector<std::string> set_size_options_positive;
|
|
std::vector<std::string> set_size_options_negative;
|
|
|
|
std::vector<std::string> xyz_values = {
|
|
"0.1", "1", "5", "10", "25", "50", "100"
|
|
};
|
|
|
|
// build positive options x/y/z
|
|
for (const auto &v: xyz_values) {
|
|
for (const auto &o: move_options) {
|
|
if (o == move_x_action) {
|
|
move_x_options_positive.emplace_back(
|
|
Saylink::Silent(fmt::format("#door edit {} {}", o, v), v)
|
|
);
|
|
}
|
|
else if (o == move_y_action) {
|
|
move_y_options_positive.emplace_back(
|
|
Saylink::Silent(fmt::format("#door edit {} {}", o, v), v)
|
|
);
|
|
}
|
|
else if (o == move_z_action) {
|
|
move_z_options_positive.emplace_back(
|
|
Saylink::Silent(fmt::format("#door edit {} {}", o, v), v)
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
// loop through vector in reverse order
|
|
// build negative options x/y/z
|
|
for (auto v = xyz_values.rbegin(); v != xyz_values.rend(); ++v) {
|
|
for (const auto &o: move_options) {
|
|
if (o == move_x_action) {
|
|
move_x_options_negative.emplace_back(
|
|
Saylink::Silent(fmt::format("#door edit {} -{}", o, *v), *v)
|
|
);
|
|
}
|
|
else if (o == move_y_action) {
|
|
move_y_options_negative.emplace_back(
|
|
Saylink::Silent(fmt::format("#door edit {} -{}", o, *v), *v)
|
|
);
|
|
}
|
|
else if (o == move_z_action) {
|
|
move_z_options_negative.emplace_back(
|
|
Saylink::Silent(fmt::format("#door edit {} -{}", o, *v), *v)
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
std::vector<std::string> heading_values = {
|
|
"1", "5", "32.5", "63.75", "130",
|
|
};
|
|
|
|
// build positive options h
|
|
for (const auto &v: heading_values) {
|
|
move_h_options_positive.emplace_back(
|
|
Saylink::Silent(fmt::format("#door edit {} {}", move_h_action, v), v)
|
|
);
|
|
}
|
|
|
|
// loop through vector in reverse order
|
|
// build negative options h
|
|
for (auto v = heading_values.rbegin(); v != heading_values.rend(); ++v) {
|
|
move_h_options_negative.emplace_back(
|
|
Saylink::Silent(fmt::format("#door edit {} -{}", move_h_action, *v), *v)
|
|
);
|
|
}
|
|
|
|
std::vector<std::string> size_values = {
|
|
"1", "5", "10", "25", "50", "100", "1000"
|
|
};
|
|
|
|
// build positive options size
|
|
for (const auto &v: size_values) {
|
|
set_size_options_positive.emplace_back(
|
|
Saylink::Silent(fmt::format("#door edit {} {}", set_size_action, v), v)
|
|
);
|
|
}
|
|
|
|
// loop through vector in reverse order
|
|
// build negative options size
|
|
for (auto v = size_values.rbegin(); v != size_values.rend(); ++v) {
|
|
set_size_options_negative.emplace_back(
|
|
Saylink::Silent(fmt::format("#door edit {} -{}", set_size_action, *v), *v)
|
|
);
|
|
}
|
|
|
|
c->Message(
|
|
Chat::White,
|
|
fmt::format(
|
|
"Name [{}] [{}] [{}] [{}]",
|
|
door->GetDoorName(),
|
|
Saylink::Silent("#door save", "Save"),
|
|
Saylink::Silent("#door changemodelqueue", "Change Model"),
|
|
Saylink::Silent("#door setinclineinc", "Incline")
|
|
).c_str()
|
|
);
|
|
c->Message(
|
|
Chat::White,
|
|
fmt::format(
|
|
"[{}] - [X] + [{}]",
|
|
Strings::Implode(" | ", move_x_options_negative),
|
|
Strings::Implode(" | ", move_x_options_positive)
|
|
).c_str()
|
|
);
|
|
c->Message(
|
|
Chat::White,
|
|
fmt::format(
|
|
"[{}] - [Y] + [{}]",
|
|
Strings::Implode(" | ", move_y_options_negative),
|
|
Strings::Implode(" | ", move_y_options_positive)
|
|
).c_str()
|
|
);
|
|
c->Message(
|
|
Chat::White,
|
|
fmt::format(
|
|
"[{}] - [Z] + [{}]",
|
|
Strings::Implode(" | ", move_z_options_negative),
|
|
Strings::Implode(" | ", move_z_options_positive)
|
|
).c_str()
|
|
);
|
|
c->Message(
|
|
Chat::White,
|
|
fmt::format(
|
|
"[{}] - [H] + [{}]",
|
|
Strings::Implode(" | ", move_h_options_negative),
|
|
Strings::Implode(" | ", move_h_options_positive)
|
|
).c_str()
|
|
);
|
|
c->Message(
|
|
Chat::White,
|
|
fmt::format(
|
|
"[{}] - [Size] + [{}]",
|
|
Strings::Implode(" | ", set_size_options_negative),
|
|
Strings::Implode(" | ", set_size_options_positive)
|
|
).c_str()
|
|
);
|
|
|
|
return;
|
|
}
|
|
|
|
c->Message(Chat::Red, "Door selection invalid...");
|
|
}
|
|
|
|
// create
|
|
if (arg1 == "create") {
|
|
std::string model = Strings::ToUpper(arg2);
|
|
uint16 entity_id = entity_list.CreateDoor(
|
|
model.c_str(),
|
|
c->GetPosition(),
|
|
58,
|
|
100
|
|
);
|
|
|
|
c->Message(
|
|
Chat::White,
|
|
fmt::format("Creating door entity_id [{}] with model [{}]", entity_id, model).c_str());
|
|
c->SetDoorToolEntityId(entity_id);
|
|
}
|
|
|
|
// set model
|
|
if (arg1 == "model") {
|
|
Doors *door = entity_list.GetDoorsByID(c->GetDoorToolEntityId());
|
|
std::string model = Strings::ToUpper(arg2);
|
|
if (door) {
|
|
door->SetDoorName(model.c_str());
|
|
}
|
|
}
|
|
|
|
// change model queue
|
|
if (arg1 == "changemodelqueue") {
|
|
c->Message(
|
|
Chat::White,
|
|
fmt::format(
|
|
"#door model <modelname> | Changes door model for selected door or select from [{}] or [{}]",
|
|
Saylink::Silent("#door showmodelszone", "local zone"),
|
|
Saylink::Silent("#door showmodelsglobal", "global")
|
|
).c_str()
|
|
);
|
|
}
|
|
|
|
// open type
|
|
if (arg1 == "opentype" && !arg2.empty() && Strings::IsNumber(arg2)) {
|
|
Doors *door = entity_list.GetDoorsByID(c->GetDoorToolEntityId());
|
|
if (door) {
|
|
door->SetOpenType(Strings::ToInt(arg2));
|
|
}
|
|
}
|
|
|
|
// incline
|
|
if (arg1 == "setincline" && !arg2.empty() && Strings::IsNumber(arg2)) {
|
|
Doors *door = entity_list.GetDoorsByID(c->GetDoorToolEntityId());
|
|
if (door) {
|
|
door->SetIncline(Strings::ToInt(arg2));
|
|
}
|
|
}
|
|
|
|
// invertstate
|
|
if (arg1 == "setinvertstate" && !arg2.empty() && Strings::IsNumber(arg2)) {
|
|
Doors *door = entity_list.GetDoorsByID(c->GetDoorToolEntityId());
|
|
if (door) {
|
|
door->SetInvertState(Strings::ToInt(arg2));
|
|
}
|
|
}
|
|
|
|
// save
|
|
if (arg1 == "save") {
|
|
Doors *door = entity_list.GetDoorsByID(c->GetDoorToolEntityId());
|
|
if (door) {
|
|
door->CreateDatabaseEntry();
|
|
c->Message(Chat::White, "Door saved");
|
|
}
|
|
}
|
|
|
|
// incline incremental
|
|
if (arg1 == "setinclineinc" && !arg2.empty() && Strings::IsNumber(arg2)) {
|
|
Doors *door = entity_list.GetDoorsByID(c->GetDoorToolEntityId());
|
|
if (door) {
|
|
door->SetIncline(door->GetIncline() + Strings::ToInt(arg2));
|
|
}
|
|
}
|
|
|
|
if (arg1 == "setinclineinc") {
|
|
std::map<float, std::string> incline_values = {
|
|
{.01, "Upright"},
|
|
{63.75, "45 Degrees",},
|
|
{130, "90 Degrees"},
|
|
{192.5, "135 Degrees"},
|
|
{255, "180 Degrees"},
|
|
{321.25, "225 Degrees"},
|
|
{385, "270 Degrees"},
|
|
{448.75, "315 Degrees"},
|
|
{512.5, "360 Degrees"}
|
|
};
|
|
|
|
std::vector<std::string> incline_normal_options;
|
|
std::vector<std::string> incline_positive_options;
|
|
std::vector<std::string> incline_negative_options;
|
|
for (auto incline_value: incline_values) {
|
|
incline_normal_options.emplace_back(
|
|
Saylink::Silent(
|
|
fmt::format(
|
|
"#door setincline {}",
|
|
incline_value.first
|
|
),
|
|
incline_value.second
|
|
)
|
|
);
|
|
}
|
|
|
|
for (int incline_index = 0; incline_index <= 100; incline_index += 10) {
|
|
int incline_value = (incline_index == 0 ? 1 : incline_index);
|
|
incline_positive_options.emplace_back(
|
|
Saylink::Silent(
|
|
fmt::format(
|
|
"#door setinclineinc {}",
|
|
incline_value
|
|
),
|
|
itoa(std::abs(incline_value))
|
|
)
|
|
);
|
|
}
|
|
|
|
for (int incline_index = -100; incline_index <= 1; incline_index += 10) {
|
|
int incline_value = (incline_index == 0 ? -1 : incline_index);
|
|
incline_negative_options.emplace_back(
|
|
Saylink::Silent(
|
|
fmt::format(
|
|
"#door setinclineinc {}",
|
|
incline_value
|
|
),
|
|
itoa(std::abs(incline_value))
|
|
)
|
|
);
|
|
}
|
|
|
|
c->Message(
|
|
Chat::White,
|
|
fmt::format(
|
|
"[Incline] [{}]",
|
|
Strings::Implode(" | ", incline_normal_options)
|
|
).c_str()
|
|
);
|
|
|
|
c->Message(
|
|
Chat::White,
|
|
fmt::format(
|
|
"[Incline Increments] [{}] - | + [{}]",
|
|
Strings::Implode(" | ", incline_negative_options),
|
|
Strings::Implode(" | ", incline_positive_options)
|
|
).c_str()
|
|
);
|
|
}
|
|
|
|
// show models in zone
|
|
if (arg1 == "showmodelsglobal") {
|
|
auto game_objects = ToolGameObjectsRepository::GetWhere(
|
|
database,
|
|
"object_name LIKE '%IT%' AND zoneid = 0 AND object_name NOT LIKE '%OBJ%' GROUP by file_from"
|
|
);
|
|
|
|
if (game_objects.empty()) {
|
|
c->Message(Chat::White, "There are no models to display...");
|
|
}
|
|
|
|
c->Message(Chat::White, "------------------------------------------------");
|
|
c->Message(Chat::White, "# Models (Global)");
|
|
c->Message(Chat::White, "------------------------------------------------");
|
|
|
|
DisplayModelsFromFileResults(c, game_objects);
|
|
}
|
|
|
|
// show models in zone
|
|
if (arg1 == "showmodelszone") {
|
|
auto game_objects = ToolGameObjectsRepository::GetWhere(
|
|
database,
|
|
fmt::format("zoneid = {}", zone->GetZoneID())
|
|
);
|
|
|
|
if (game_objects.empty()) {
|
|
c->Message(Chat::White, "There are no models for this zone...");
|
|
}
|
|
|
|
c->Message(Chat::White, "------------------------------------------------");
|
|
c->Message(Chat::White, "# Models from zone");
|
|
c->Message(Chat::White, "------------------------------------------------");
|
|
|
|
DisplayObjectResultToClient(c, game_objects);
|
|
}
|
|
|
|
// show models from file name
|
|
if (arg1 == "showmodelsfromfile" && !arg2.empty()) {
|
|
const std::string &file_name = arg2;
|
|
auto game_objects = ToolGameObjectsRepository::GetWhere(
|
|
database,
|
|
fmt::format("file_from = '{}'", file_name)
|
|
);
|
|
|
|
if (game_objects.empty()) {
|
|
c->Message(Chat::White, "There are no models for this zone...");
|
|
}
|
|
|
|
c->Message(Chat::White, "------------------------------------------------");
|
|
c->Message(Chat::White, fmt::format("# Models from file name [{}]", file_name).c_str());
|
|
c->Message(Chat::White, "------------------------------------------------");
|
|
|
|
DisplayObjectResultToClient(c, game_objects);
|
|
}
|
|
|
|
// help menu
|
|
if (arg1.empty()) {
|
|
DoorManipulation::CommandHeader(c);
|
|
c->Message(
|
|
Chat::White,
|
|
"#door create <modelname> | Creates a door from a model. (Example IT78 creates a campfire)"
|
|
);
|
|
c->Message(Chat::White, "#door setinvertstate [0|1] | Sets selected door invert state");
|
|
c->Message(Chat::White, "#door setincline <incline> | Sets selected door incline");
|
|
c->Message(Chat::White, "#door opentype <opentype> | Sets selected door opentype");
|
|
c->Message(
|
|
Chat::White,
|
|
fmt::format(
|
|
"{} <door_size> <door_depth> | Draws a box for the door, default size = 15, depth = 5 if none defined",
|
|
Saylink::Silent("#door drawbox")
|
|
).c_str()
|
|
);
|
|
c->Message(
|
|
Chat::White,
|
|
fmt::format(
|
|
"#door model <modelname> | Changes door model for selected door or select from [{}] or [{}]",
|
|
Saylink::Silent("#door showmodelszone", "local zone"),
|
|
Saylink::Silent("#door showmodelsglobal", "global")
|
|
).c_str()
|
|
);
|
|
c->Message(
|
|
Chat::White,
|
|
"#door showmodelsfromfile <file.eqg|file.s3d> | Shows models from s3d or eqg file. Example tssequip.eqg or wallet01.eqg"
|
|
);
|
|
|
|
c->Message(
|
|
Chat::White,
|
|
fmt::format(
|
|
"{} | Shows available models in the current zone that you are in",
|
|
Saylink::Silent("#door showmodelszone")
|
|
).c_str()
|
|
);
|
|
|
|
c->Message(
|
|
Chat::White,
|
|
fmt::format(
|
|
"{} | Shows available models globally by first listing all global model files",
|
|
Saylink::Silent("#door showmodelsglobal")
|
|
).c_str()
|
|
);
|
|
|
|
c->Message(Chat::White, "#door save | Creates database entry for selected door");
|
|
c->Message(
|
|
Chat::White,
|
|
fmt::format(
|
|
"{} - Brings up editing interface for selected door",
|
|
Saylink::Silent("#door edit")
|
|
).c_str()
|
|
);
|
|
c->Message(
|
|
Chat::White,
|
|
fmt::format(
|
|
"{} - lists doors in zone",
|
|
Saylink::Silent("#list doors")
|
|
).c_str()
|
|
);
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
void DoorManipulation::CommandHeader(Client *c)
|
|
{
|
|
c->Message(Chat::White, "------------------------------------------------");
|
|
c->Message(Chat::White, "# Door Commands");
|
|
c->Message(Chat::White, "------------------------------------------------");
|
|
}
|
|
|
|
void DoorManipulation::DisplayObjectResultToClient(
|
|
Client *c,
|
|
std::vector<ToolGameObjectsRepository::ToolGameObjects> game_objects
|
|
)
|
|
{
|
|
std::vector<std::string> say_links;
|
|
|
|
for (auto &g: game_objects) {
|
|
say_links.emplace_back(
|
|
fmt::format(
|
|
"[{}] ",
|
|
Saylink::Silent(
|
|
fmt::format("#door model {}", g.object_name),
|
|
g.object_name
|
|
)
|
|
)
|
|
);
|
|
}
|
|
|
|
int character_length = 0;
|
|
std::vector<std::string> buffered_links;
|
|
|
|
for (auto &links: say_links) {
|
|
buffered_links.emplace_back(links);
|
|
character_length += links.length();
|
|
|
|
// empty buffer
|
|
if (character_length > MAX_CLIENT_MESSAGE_LENGTH) {
|
|
std::string message_buffer;
|
|
|
|
for (auto &buffered_link: buffered_links) {
|
|
message_buffer += buffered_link;
|
|
}
|
|
|
|
c->Message(Chat::White, message_buffer.c_str());
|
|
|
|
// reset
|
|
character_length = 0;
|
|
buffered_links = {};
|
|
}
|
|
}
|
|
|
|
if (!buffered_links.empty()) {
|
|
c->Message(Chat::White, Strings::Implode(" ", buffered_links).c_str());
|
|
}
|
|
}
|
|
|
|
void DoorManipulation::DisplayModelsFromFileResults(
|
|
Client *c,
|
|
std::vector<ToolGameObjectsRepository::ToolGameObjects> game_objects
|
|
)
|
|
{
|
|
std::vector<std::string> say_links;
|
|
|
|
for (auto &g: game_objects) {
|
|
say_links.emplace_back(
|
|
fmt::format(
|
|
"[{}] ",
|
|
Saylink::Silent(
|
|
fmt::format("#door showmodelsfromfile {}", g.file_from),
|
|
g.file_from
|
|
)
|
|
)
|
|
);
|
|
}
|
|
|
|
int character_length = 0;
|
|
std::vector<std::string> buffered_links;
|
|
|
|
for (auto &links: say_links) {
|
|
buffered_links.emplace_back(links);
|
|
character_length += links.length();
|
|
|
|
// empty buffer
|
|
if (character_length > MAX_CLIENT_MESSAGE_LENGTH) {
|
|
std::string message_buffer;
|
|
|
|
for (auto &buffered_link: buffered_links) {
|
|
message_buffer += buffered_link;
|
|
}
|
|
|
|
c->Message(Chat::White, message_buffer.c_str());
|
|
|
|
// reset
|
|
character_length = 0;
|
|
buffered_links = {};
|
|
}
|
|
}
|
|
|
|
if (!buffered_links.empty()) {
|
|
c->Message(Chat::White, Strings::Implode(" ", buffered_links).c_str());
|
|
}
|
|
}
|