mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-12-21 12:10:17 +00:00
Initial changes.
* Recorder to recall player actions. * Server precondtions to manage entity visiblity.
This commit is contained in:
113
dGame/dUtilities/ServerPreconditions.cpp
Normal file
113
dGame/dUtilities/ServerPreconditions.cpp
Normal file
@@ -0,0 +1,113 @@
|
||||
#include "ServerPreconditions.hpp"
|
||||
|
||||
#include "tinyxml2.h"
|
||||
|
||||
using namespace ServerPreconditions;
|
||||
|
||||
std::unordered_map<LOT, std::vector<std::pair<bool, PreconditionExpression>>> ServerPreconditions::m_Preconditions;
|
||||
|
||||
std::unordered_map<LWOOBJID, LWOOBJID> ServerPreconditions::m_SoloActors;
|
||||
|
||||
std::unordered_map<LWOOBJID, std::unordered_set<LWOOBJID>> ServerPreconditions::m_ExcludeForPlayer;
|
||||
|
||||
void ServerPreconditions::LoadPreconditions(std::string file) {
|
||||
tinyxml2::XMLDocument doc;
|
||||
doc.LoadFile(file.c_str());
|
||||
|
||||
tinyxml2::XMLElement* root = doc.FirstChildElement("Preconditions");
|
||||
if (!root) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (tinyxml2::XMLElement* element = root->FirstChildElement("Entity"); element; element = element->NextSiblingElement("Entity")) {
|
||||
LOT lot = element->UnsignedAttribute("lot");
|
||||
std::vector<std::pair<bool, PreconditionExpression>> preconditions;
|
||||
|
||||
for (tinyxml2::XMLElement* precondition = element->FirstChildElement("Precondition"); precondition; precondition = precondition->NextSiblingElement("Precondition")) {
|
||||
const auto condition = Preconditions::CreateExpression(precondition->GetText());
|
||||
|
||||
int64_t inverted;
|
||||
|
||||
if (precondition->QueryInt64Attribute("not", &inverted) == tinyxml2::XML_SUCCESS) {
|
||||
preconditions.push_back(std::make_pair(inverted > 0, condition));
|
||||
}
|
||||
else {
|
||||
preconditions.push_back(std::make_pair(false, condition));
|
||||
}
|
||||
}
|
||||
|
||||
m_Preconditions[lot] = preconditions;
|
||||
}
|
||||
}
|
||||
|
||||
bool ServerPreconditions::CheckPreconditions(Entity* target, Entity* entity) {
|
||||
if (IsExcludedFor(entity->GetObjectID(), target->GetObjectID())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsSoloActor(target->GetObjectID())) {
|
||||
return IsActingFor(target->GetObjectID(), entity->GetObjectID());
|
||||
}
|
||||
|
||||
if (m_Preconditions.find(target->GetLOT()) == m_Preconditions.end()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (const auto& [inverse, precondition] : m_Preconditions[target->GetLOT()]) {
|
||||
if (precondition.Check(entity) == inverse) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ServerPreconditions::IsSoloActor(LWOOBJID actor) {
|
||||
return m_SoloActors.find(actor) != m_SoloActors.end();
|
||||
}
|
||||
|
||||
bool ServerPreconditions::IsActingFor(LWOOBJID actor, LWOOBJID target) {
|
||||
return m_SoloActors.find(actor) != m_SoloActors.end() && m_SoloActors[actor] == target;
|
||||
}
|
||||
|
||||
void ServerPreconditions::AddSoloActor(LWOOBJID actor, LWOOBJID target) {
|
||||
m_SoloActors[actor] = target;
|
||||
}
|
||||
|
||||
void ServerPreconditions::RemoveSoloActor(LWOOBJID actor) {
|
||||
m_SoloActors.erase(actor);
|
||||
}
|
||||
|
||||
void ServerPreconditions::AddExcludeFor(LWOOBJID player, LWOOBJID target) {
|
||||
const auto& it = m_ExcludeForPlayer.find(player);
|
||||
|
||||
if (it == m_ExcludeForPlayer.end()) {
|
||||
m_ExcludeForPlayer[player] = std::unordered_set<LWOOBJID>();
|
||||
}
|
||||
|
||||
m_ExcludeForPlayer[player].insert(target);
|
||||
}
|
||||
|
||||
void ServerPreconditions::RemoveExcludeFor(LWOOBJID player, LWOOBJID target) {
|
||||
const auto& it = m_ExcludeForPlayer.find(player);
|
||||
|
||||
if (it == m_ExcludeForPlayer.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_ExcludeForPlayer[player].erase(target);
|
||||
|
||||
if (m_ExcludeForPlayer[player].empty()) {
|
||||
m_ExcludeForPlayer.erase(player);
|
||||
}
|
||||
}
|
||||
|
||||
bool ServerPreconditions::IsExcludedFor(LWOOBJID player, LWOOBJID target) {
|
||||
const auto& it = m_ExcludeForPlayer.find(player);
|
||||
|
||||
if (it == m_ExcludeForPlayer.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return it->second.find(target) != it->second.end();
|
||||
}
|
||||
Reference in New Issue
Block a user