mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-12-12 19:18:28 +00:00
feat: proper gminvs with ghosting (#1920)
* feat: proper gminvis ghosting * address feedback --------- Co-authored-by: David Markowitz <39972741+EmosewaMC@users.noreply.github.com>
This commit is contained in:
@@ -504,7 +504,7 @@ void Entity::Initialize() {
|
|||||||
auto& systemAddress = m_Character->GetParentUser() ? m_Character->GetParentUser()->GetSystemAddress() : UNASSIGNED_SYSTEM_ADDRESS;
|
auto& systemAddress = m_Character->GetParentUser() ? m_Character->GetParentUser()->GetSystemAddress() : UNASSIGNED_SYSTEM_ADDRESS;
|
||||||
AddComponent<CharacterComponent>(characterID, m_Character, systemAddress)->LoadFromXml(m_Character->GetXMLDoc());
|
AddComponent<CharacterComponent>(characterID, m_Character, systemAddress)->LoadFromXml(m_Character->GetXMLDoc());
|
||||||
|
|
||||||
AddComponent<GhostComponent>(characterID);
|
AddComponent<GhostComponent>(characterID)->LoadFromXml(m_Character->GetXMLDoc());
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto inventoryID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::INVENTORY);
|
const auto inventoryID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::INVENTORY);
|
||||||
|
|||||||
@@ -361,16 +361,24 @@ void EntityManager::ConstructEntity(Entity* entity, const SystemAddress& sysAddr
|
|||||||
LOG("Attempted to construct null entity");
|
LOG("Attempted to construct null entity");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// Don't construct GM invisible entities unless it's for the GM themselves
|
||||||
|
// GMs can see other GMs if they are the same or lower level
|
||||||
|
GameMessages::GetGMInvis getGMInvisMsg;
|
||||||
|
getGMInvisMsg.Send(entity->GetObjectID());
|
||||||
|
if (getGMInvisMsg.bGMInvis && sysAddr != entity->GetSystemAddress()) {
|
||||||
|
auto* toUser = UserManager::Instance()->GetUser(sysAddr);
|
||||||
|
if (!toUser) return;
|
||||||
|
auto* constructedUser = UserManager::Instance()->GetUser(entity->GetSystemAddress());
|
||||||
|
if (!constructedUser) return;
|
||||||
|
if (toUser->GetMaxGMLevel() < constructedUser->GetMaxGMLevel()) return;
|
||||||
|
}
|
||||||
|
|
||||||
if (entity->GetNetworkId() == 0) {
|
if (entity->GetNetworkId() == 0) {
|
||||||
uint16_t networkId;
|
uint16_t networkId;
|
||||||
|
|
||||||
if (!m_LostNetworkIds.empty()) {
|
if (!m_LostNetworkIds.empty()) {
|
||||||
networkId = m_LostNetworkIds.top();
|
networkId = m_LostNetworkIds.top();
|
||||||
m_LostNetworkIds.pop();
|
m_LostNetworkIds.pop();
|
||||||
} else {
|
} else networkId = ++m_NetworkIdCounter;
|
||||||
networkId = ++m_NetworkIdCounter;
|
|
||||||
}
|
|
||||||
|
|
||||||
entity->SetNetworkId(networkId);
|
entity->SetNetworkId(networkId);
|
||||||
}
|
}
|
||||||
@@ -379,10 +387,8 @@ void EntityManager::ConstructEntity(Entity* entity, const SystemAddress& sysAddr
|
|||||||
if (std::find(m_EntitiesToGhost.begin(), m_EntitiesToGhost.end(), entity) == m_EntitiesToGhost.end()) {
|
if (std::find(m_EntitiesToGhost.begin(), m_EntitiesToGhost.end(), entity) == m_EntitiesToGhost.end()) {
|
||||||
m_EntitiesToGhost.push_back(entity);
|
m_EntitiesToGhost.push_back(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) {
|
if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) {
|
||||||
CheckGhosting(entity);
|
CheckGhosting(entity);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -413,11 +419,6 @@ void EntityManager::ConstructEntity(Entity* entity, const SystemAddress& sysAddr
|
|||||||
Game::server->Send(stream, sysAddr, false);
|
Game::server->Send(stream, sysAddr, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entity->IsPlayer()) {
|
|
||||||
if (entity->GetGMLevel() > eGameMasterLevel::CIVILIAN) {
|
|
||||||
GameMessages::SendToggleGMInvis(entity->GetObjectID(), true, sysAddr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityManager::ConstructAllEntities(const SystemAddress& sysAddr) {
|
void EntityManager::ConstructAllEntities(const SystemAddress& sysAddr) {
|
||||||
@@ -488,11 +489,7 @@ void EntityManager::QueueGhostUpdate(LWOOBJID playerID) {
|
|||||||
void EntityManager::UpdateGhosting() {
|
void EntityManager::UpdateGhosting() {
|
||||||
for (const auto playerID : m_PlayersToUpdateGhosting) {
|
for (const auto playerID : m_PlayersToUpdateGhosting) {
|
||||||
auto* player = PlayerManager::GetPlayer(playerID);
|
auto* player = PlayerManager::GetPlayer(playerID);
|
||||||
|
if (!player) continue;
|
||||||
if (player == nullptr) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateGhosting(player);
|
UpdateGhosting(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -519,6 +516,7 @@ void EntityManager::UpdateGhosting(Entity* player) {
|
|||||||
|
|
||||||
const auto distance = NiPoint3::DistanceSquared(referencePoint, entityPoint);
|
const auto distance = NiPoint3::DistanceSquared(referencePoint, entityPoint);
|
||||||
|
|
||||||
|
|
||||||
auto ghostingDistanceMax = m_GhostDistanceMaxSquared;
|
auto ghostingDistanceMax = m_GhostDistanceMaxSquared;
|
||||||
auto ghostingDistanceMin = m_GhostDistanceMinSqaured;
|
auto ghostingDistanceMin = m_GhostDistanceMinSqaured;
|
||||||
|
|
||||||
@@ -555,35 +553,25 @@ void EntityManager::UpdateGhosting(Entity* player) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EntityManager::CheckGhosting(Entity* entity) {
|
void EntityManager::CheckGhosting(Entity* entity) {
|
||||||
if (entity == nullptr) {
|
if (!entity) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto& referencePoint = entity->GetPosition();
|
const auto& referencePoint = entity->GetPosition();
|
||||||
|
|
||||||
for (auto* player : PlayerManager::GetAllPlayers()) {
|
for (auto* player : PlayerManager::GetAllPlayers()) {
|
||||||
auto* ghostComponent = player->GetComponent<GhostComponent>();
|
auto* ghostComponent = player->GetComponent<GhostComponent>();
|
||||||
if (!ghostComponent) continue;
|
if (!ghostComponent) continue;
|
||||||
|
|
||||||
const auto& entityPoint = ghostComponent->GetGhostReferencePoint();
|
const auto& entityPoint = ghostComponent->GetGhostReferencePoint();
|
||||||
|
|
||||||
const auto id = entity->GetObjectID();
|
const auto id = entity->GetObjectID();
|
||||||
|
|
||||||
const auto observed = ghostComponent->IsObserved(id);
|
const auto observed = ghostComponent->IsObserved(id);
|
||||||
|
|
||||||
const auto distance = NiPoint3::DistanceSquared(referencePoint, entityPoint);
|
const auto distance = NiPoint3::DistanceSquared(referencePoint, entityPoint);
|
||||||
|
|
||||||
if (observed && distance > m_GhostDistanceMaxSquared) {
|
if (observed && distance > m_GhostDistanceMaxSquared) {
|
||||||
ghostComponent->GhostEntity(id);
|
ghostComponent->GhostEntity(id);
|
||||||
|
|
||||||
DestructEntity(entity, player->GetSystemAddress());
|
DestructEntity(entity, player->GetSystemAddress());
|
||||||
|
|
||||||
entity->SetObservers(entity->GetObservers() - 1);
|
entity->SetObservers(entity->GetObservers() - 1);
|
||||||
} else if (!observed && m_GhostDistanceMinSqaured > distance) {
|
} else if (!observed && m_GhostDistanceMinSqaured > distance) {
|
||||||
ghostComponent->ObserveEntity(id);
|
ghostComponent->ObserveEntity(id);
|
||||||
|
|
||||||
ConstructEntity(entity, player->GetSystemAddress());
|
ConstructEntity(entity, player->GetSystemAddress());
|
||||||
|
|
||||||
entity->SetObservers(entity->GetObservers() + 1);
|
entity->SetObservers(entity->GetObservers() + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,9 @@
|
|||||||
#include "GhostComponent.h"
|
#include "GhostComponent.h"
|
||||||
|
#include "PlayerManager.h"
|
||||||
|
#include "Character.h"
|
||||||
|
#include "ControllablePhysicsComponent.h"
|
||||||
|
#include "UserManager.h"
|
||||||
|
#include "User.h"
|
||||||
|
|
||||||
#include "Amf3.h"
|
#include "Amf3.h"
|
||||||
#include "GameMessages.h"
|
#include "GameMessages.h"
|
||||||
@@ -8,6 +13,8 @@ GhostComponent::GhostComponent(Entity* parent, const int32_t componentID) : Comp
|
|||||||
m_GhostOverridePoint = NiPoint3Constant::ZERO;
|
m_GhostOverridePoint = NiPoint3Constant::ZERO;
|
||||||
m_GhostOverride = false;
|
m_GhostOverride = false;
|
||||||
|
|
||||||
|
RegisterMsg<GameMessages::ToggleGMInvis>(this, &GhostComponent::OnToggleGMInvis);
|
||||||
|
RegisterMsg<GameMessages::GetGMInvis>(this, &GhostComponent::OnGetGMInvis);
|
||||||
RegisterMsg<GameMessages::GetObjectReportInfo>(this, &GhostComponent::MsgGetObjectReportInfo);
|
RegisterMsg<GameMessages::GetObjectReportInfo>(this, &GhostComponent::MsgGetObjectReportInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -22,6 +29,25 @@ GhostComponent::~GhostComponent() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GhostComponent::LoadFromXml(const tinyxml2::XMLDocument& doc) {
|
||||||
|
auto* objElement = doc.FirstChildElement("obj");
|
||||||
|
if (!objElement) return;
|
||||||
|
auto* ghstElement = objElement->FirstChildElement("ghst");
|
||||||
|
if (!ghstElement) return;
|
||||||
|
m_IsGMInvisible = ghstElement->BoolAttribute("i");
|
||||||
|
}
|
||||||
|
|
||||||
|
void GhostComponent::UpdateXml(tinyxml2::XMLDocument& doc) {
|
||||||
|
auto* objElement = doc.FirstChildElement("obj");
|
||||||
|
if (!objElement) return;
|
||||||
|
auto* ghstElement = objElement->FirstChildElement("ghst");
|
||||||
|
if (ghstElement) objElement->DeleteChild(ghstElement);
|
||||||
|
// Only save if GM invisible
|
||||||
|
if (!m_IsGMInvisible) return;
|
||||||
|
ghstElement = objElement->InsertNewChildElement("ghst");
|
||||||
|
if (ghstElement) ghstElement->SetAttribute("i", m_IsGMInvisible);
|
||||||
|
}
|
||||||
|
|
||||||
void GhostComponent::SetGhostReferencePoint(const NiPoint3& value) {
|
void GhostComponent::SetGhostReferencePoint(const NiPoint3& value) {
|
||||||
m_GhostReferencePoint = value;
|
m_GhostReferencePoint = value;
|
||||||
}
|
}
|
||||||
@@ -61,6 +87,40 @@ void GhostComponent::GhostEntity(LWOOBJID id) {
|
|||||||
m_ObservedEntities.erase(id);
|
m_ObservedEntities.erase(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GhostComponent::OnToggleGMInvis(GameMessages::GameMsg& msg) {
|
||||||
|
auto& gmInvisMsg = static_cast<GameMessages::ToggleGMInvis&>(msg);
|
||||||
|
gmInvisMsg.bStateOut = !m_IsGMInvisible;
|
||||||
|
m_IsGMInvisible = !m_IsGMInvisible;
|
||||||
|
LOG_DEBUG("GM Invisibility toggled to: %s", m_IsGMInvisible ? "true" : "false");
|
||||||
|
gmInvisMsg.Send(UNASSIGNED_SYSTEM_ADDRESS);
|
||||||
|
auto* thisUser = UserManager::Instance()->GetUser(m_Parent->GetSystemAddress());
|
||||||
|
for (const auto& player : PlayerManager::GetAllPlayers()) {
|
||||||
|
if (!player || player->GetObjectID() == m_Parent->GetObjectID()) continue;
|
||||||
|
auto* toUser = UserManager::Instance()->GetUser(player->GetSystemAddress());
|
||||||
|
if (m_IsGMInvisible) {
|
||||||
|
if (toUser->GetMaxGMLevel() < thisUser->GetMaxGMLevel()) {
|
||||||
|
Game::entityManager->DestructEntity(m_Parent, player->GetSystemAddress());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (toUser->GetMaxGMLevel() >= thisUser->GetMaxGMLevel()) {
|
||||||
|
Game::entityManager->ConstructEntity(m_Parent, player->GetSystemAddress());
|
||||||
|
auto* controllableComp = m_Parent->GetComponent<ControllablePhysicsComponent>();
|
||||||
|
controllableComp->SetDirtyPosition(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Game::entityManager->SerializeEntity(m_Parent);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GhostComponent::OnGetGMInvis(GameMessages::GameMsg& msg) {
|
||||||
|
LOG_DEBUG("GM Invisibility requested: %s", m_IsGMInvisible ? "true" : "false");
|
||||||
|
auto& gmInvisMsg = static_cast<GameMessages::GetGMInvis&>(msg);
|
||||||
|
gmInvisMsg.bGMInvis = m_IsGMInvisible;
|
||||||
|
return gmInvisMsg.bGMInvis;
|
||||||
|
}
|
||||||
|
|
||||||
bool GhostComponent::MsgGetObjectReportInfo(GameMessages::GameMsg& msg) {
|
bool GhostComponent::MsgGetObjectReportInfo(GameMessages::GameMsg& msg) {
|
||||||
auto& reportMsg = static_cast<GameMessages::GetObjectReportInfo&>(msg);
|
auto& reportMsg = static_cast<GameMessages::GetObjectReportInfo&>(msg);
|
||||||
auto& cmptType = reportMsg.info->PushDebug("Ghost");
|
auto& cmptType = reportMsg.info->PushDebug("Ghost");
|
||||||
|
|||||||
@@ -7,11 +7,17 @@
|
|||||||
|
|
||||||
class NiPoint3;
|
class NiPoint3;
|
||||||
|
|
||||||
|
namespace tinyxml2 {
|
||||||
|
class XMLDocument;
|
||||||
|
}
|
||||||
|
|
||||||
class GhostComponent final : public Component {
|
class GhostComponent final : public Component {
|
||||||
public:
|
public:
|
||||||
static inline const eReplicaComponentType ComponentType = eReplicaComponentType::GHOST;
|
static inline const eReplicaComponentType ComponentType = eReplicaComponentType::GHOST;
|
||||||
GhostComponent(Entity* parent, const int32_t componentID);
|
GhostComponent(Entity* parent, const int32_t componentID);
|
||||||
~GhostComponent() override;
|
~GhostComponent() override;
|
||||||
|
void LoadFromXml(const tinyxml2::XMLDocument& doc) override;
|
||||||
|
void UpdateXml(tinyxml2::XMLDocument& doc) override;
|
||||||
|
|
||||||
void SetGhostOverride(bool value) { m_GhostOverride = value; };
|
void SetGhostOverride(bool value) { m_GhostOverride = value; };
|
||||||
|
|
||||||
@@ -39,9 +45,14 @@ public:
|
|||||||
|
|
||||||
void GhostEntity(const LWOOBJID id);
|
void GhostEntity(const LWOOBJID id);
|
||||||
|
|
||||||
|
bool OnToggleGMInvis(GameMessages::GameMsg& msg);
|
||||||
|
|
||||||
|
bool OnGetGMInvis(GameMessages::GameMsg& msg);
|
||||||
|
|
||||||
bool MsgGetObjectReportInfo(GameMessages::GameMsg& msg);
|
bool MsgGetObjectReportInfo(GameMessages::GameMsg& msg);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
NiPoint3 m_GhostReferencePoint;
|
NiPoint3 m_GhostReferencePoint;
|
||||||
|
|
||||||
NiPoint3 m_GhostOverridePoint;
|
NiPoint3 m_GhostOverridePoint;
|
||||||
@@ -51,6 +62,9 @@ private:
|
|||||||
std::unordered_set<LWOOBJID> m_LimboConstructions;
|
std::unordered_set<LWOOBJID> m_LimboConstructions;
|
||||||
|
|
||||||
bool m_GhostOverride;
|
bool m_GhostOverride;
|
||||||
|
|
||||||
|
bool m_IsGMInvisible;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //!__GHOSTCOMPONENT__H__
|
#endif //!__GHOSTCOMPONENT__H__
|
||||||
|
|||||||
@@ -1847,18 +1847,6 @@ void GameMessages::SendNotifyClientFailedPrecondition(LWOOBJID objectId, const S
|
|||||||
SEND_PACKET;
|
SEND_PACKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameMessages::SendToggleGMInvis(LWOOBJID objectId, bool enabled, const SystemAddress& sysAddr) {
|
|
||||||
CBITSTREAM;
|
|
||||||
CMSGHEADER;
|
|
||||||
|
|
||||||
bitStream.Write(objectId);
|
|
||||||
bitStream.Write(MessageType::Game::TOGGLE_GM_INVIS);
|
|
||||||
bitStream.Write(enabled); // does not matter?
|
|
||||||
|
|
||||||
if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST;
|
|
||||||
SEND_PACKET;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GameMessages::SendSetName(LWOOBJID objectID, std::u16string name, const SystemAddress& sysAddr) {
|
void GameMessages::SendSetName(LWOOBJID objectID, std::u16string name, const SystemAddress& sysAddr) {
|
||||||
CBITSTREAM;
|
CBITSTREAM;
|
||||||
CMSGHEADER;
|
CMSGHEADER;
|
||||||
@@ -6449,4 +6437,8 @@ namespace GameMessages {
|
|||||||
stream.Write(lootID);
|
stream.Write(lootID);
|
||||||
stream.Write(lootOwnerID);
|
stream.Write(lootOwnerID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ToggleGMInvis::Serialize(RakNet::BitStream& stream) const {
|
||||||
|
stream.Write(bStateOut);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -243,8 +243,6 @@ namespace GameMessages {
|
|||||||
bool cancelOnLogout = false, bool cancelOnRemoveBuff = true, bool cancelOnUi = false,
|
bool cancelOnLogout = false, bool cancelOnRemoveBuff = true, bool cancelOnUi = false,
|
||||||
bool cancelOnUnequip = false, bool cancelOnZone = false, bool addedByTeammate = false, bool applyOnTeammates = false, const SystemAddress& sysAddr = UNASSIGNED_SYSTEM_ADDRESS);
|
bool cancelOnUnequip = false, bool cancelOnZone = false, bool addedByTeammate = false, bool applyOnTeammates = false, const SystemAddress& sysAddr = UNASSIGNED_SYSTEM_ADDRESS);
|
||||||
|
|
||||||
void SendToggleGMInvis(LWOOBJID objectId, bool enabled, const SystemAddress& sysAddr);
|
|
||||||
|
|
||||||
void SendSetName(LWOOBJID objectID, std::u16string name, const SystemAddress& sysAddr);
|
void SendSetName(LWOOBJID objectID, std::u16string name, const SystemAddress& sysAddr);
|
||||||
|
|
||||||
// Property messages
|
// Property messages
|
||||||
@@ -938,6 +936,20 @@ namespace GameMessages {
|
|||||||
LWOOBJID lootOwnerID{};
|
LWOOBJID lootOwnerID{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ToggleGMInvis : public GameMsg {
|
||||||
|
ToggleGMInvis() : GameMsg(MessageType::Game::TOGGLE_GM_INVIS) {}
|
||||||
|
|
||||||
|
void Serialize(RakNet::BitStream& stream) const override;
|
||||||
|
bool bStateOut{ false };
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GetGMInvis : public GameMsg {
|
||||||
|
GetGMInvis() : GameMsg(MessageType::Game::GET_GM_INVIS) {}
|
||||||
|
|
||||||
|
bool bGMInvis{ false };
|
||||||
|
};
|
||||||
|
|
||||||
struct ChildRemoved : public GameMsg {
|
struct ChildRemoved : public GameMsg {
|
||||||
ChildRemoved() : GameMsg(MessageType::Game::CHILD_REMOVED) {}
|
ChildRemoved() : GameMsg(MessageType::Game::CHILD_REMOVED) {}
|
||||||
|
|
||||||
|
|||||||
@@ -893,10 +893,10 @@ void SlashCommandHandler::Startup() {
|
|||||||
|
|
||||||
Command GmInvisCommand{
|
Command GmInvisCommand{
|
||||||
.help = "Toggles invisibility for the character",
|
.help = "Toggles invisibility for the character",
|
||||||
.info = "Toggles invisibility for the character, though it's currently a bit buggy. Requires nonzero GM Level for the character, but the account must have a GM level of 8",
|
.info = "Toggles invisibility for the character, making them invisible to other players and lower GM levels",
|
||||||
.aliases = { "gminvis" },
|
.aliases = { "gminvis" },
|
||||||
.handle = GMGreaterThanZeroCommands::GmInvis,
|
.handle = GMGreaterThanZeroCommands::GmInvis,
|
||||||
.requiredLevel = eGameMasterLevel::DEVELOPER
|
.requiredLevel = eGameMasterLevel::FORUM_MODERATOR
|
||||||
};
|
};
|
||||||
RegisterCommand(GmInvisCommand);
|
RegisterCommand(GmInvisCommand);
|
||||||
|
|
||||||
|
|||||||
@@ -89,7 +89,8 @@ namespace DEVGMCommands {
|
|||||||
GameMessages::SendChatModeUpdate(entity->GetObjectID(), eGameMasterLevel::CIVILIAN);
|
GameMessages::SendChatModeUpdate(entity->GetObjectID(), eGameMasterLevel::CIVILIAN);
|
||||||
entity->SetGMLevel(eGameMasterLevel::CIVILIAN);
|
entity->SetGMLevel(eGameMasterLevel::CIVILIAN);
|
||||||
|
|
||||||
GameMessages::SendToggleGMInvis(entity->GetObjectID(), false, UNASSIGNED_SYSTEM_ADDRESS);
|
GameMessages::ToggleGMInvis msg;
|
||||||
|
msg.Send(entity->GetObjectID());
|
||||||
|
|
||||||
GameMessages::SendSlashCommandFeedbackText(entity, u"Your game master level has been changed, you may not be able to use all commands.");
|
GameMessages::SendSlashCommandFeedbackText(entity, u"Your game master level has been changed, you may not be able to use all commands.");
|
||||||
}
|
}
|
||||||
@@ -183,7 +184,6 @@ namespace DEVGMCommands {
|
|||||||
Game::entityManager->ConstructEntity(entity);
|
Game::entityManager->ConstructEntity(entity);
|
||||||
ChatPackets::SendSystemMessage(sysAddr, GeneralUtils::ASCIIToUTF16(lowerName) + u" set to " + (GeneralUtils::to_u16string(minifigItemId)));
|
ChatPackets::SendSystemMessage(sysAddr, GeneralUtils::ASCIIToUTF16(lowerName) + u" set to " + (GeneralUtils::to_u16string(minifigItemId)));
|
||||||
|
|
||||||
GameMessages::SendToggleGMInvis(entity->GetObjectID(), false, UNASSIGNED_SYSTEM_ADDRESS); // need to retoggle because it gets reenabled on creation of new character
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayAnimation(Entity* entity, const SystemAddress& sysAddr, const std::string args) {
|
void PlayAnimation(Entity* entity, const SystemAddress& sysAddr, const std::string args) {
|
||||||
|
|||||||
@@ -275,7 +275,8 @@ namespace GMGreaterThanZeroCommands {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GmInvis(Entity* entity, const SystemAddress& sysAddr, const std::string args) {
|
void GmInvis(Entity* entity, const SystemAddress& sysAddr, const std::string args) {
|
||||||
GameMessages::SendToggleGMInvis(entity->GetObjectID(), true, UNASSIGNED_SYSTEM_ADDRESS);
|
GameMessages::ToggleGMInvis msg;
|
||||||
|
msg.Send(entity->GetObjectID());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetName(Entity* entity, const SystemAddress& sysAddr, const std::string args) {
|
void SetName(Entity* entity, const SystemAddress& sysAddr, const std::string args) {
|
||||||
|
|||||||
Reference in New Issue
Block a user