diff --git a/dChatFilter/dChatFilter.cpp b/dChatFilter/dChatFilter.cpp index ea38f8cd..92da9556 100644 --- a/dChatFilter/dChatFilter.cpp +++ b/dChatFilter/dChatFilter.cpp @@ -12,6 +12,7 @@ #include "dConfig.h" #include "Database.h" #include "Game.h" +#include "eGameMasterLevel.h" using namespace dChatFilterDCF; @@ -108,8 +109,8 @@ void dChatFilter::ExportWordlistToDCF(const std::string& filepath, bool whiteLis } } -std::vector> dChatFilter::IsSentenceOkay(const std::string& message, int gmLevel, bool whiteList) { - if (gmLevel > GAME_MASTER_LEVEL_FORUM_MODERATOR) return { }; //If anything but a forum mod, return true. +std::vector> dChatFilter::IsSentenceOkay(const std::string& message, eGameMasterLevel gmLevel, bool whiteList) { + if (gmLevel > eGameMasterLevel::FORUM_MODERATOR) return { }; //If anything but a forum mod, return true. if (message.empty()) return { }; if (!whiteList && m_DeniedWords.empty()) return { { 0, message.length() } }; diff --git a/dChatFilter/dChatFilter.h b/dChatFilter/dChatFilter.h index 7e7dd859..d00525ce 100644 --- a/dChatFilter/dChatFilter.h +++ b/dChatFilter/dChatFilter.h @@ -4,6 +4,7 @@ #include "dCommonVars.h" +enum class eGameMasterLevel : uint8_t; namespace dChatFilterDCF { static const uint32_t header = ('D' + ('C' << 8) + ('F' << 16) + ('B' << 24)); static const uint32_t formatVersion = 2; @@ -23,7 +24,7 @@ public: void ReadWordlistPlaintext(const std::string& filepath, bool whiteList); bool ReadWordlistDCF(const std::string& filepath, bool whiteList); void ExportWordlistToDCF(const std::string& filepath, bool whiteList); - std::vector> IsSentenceOkay(const std::string& message, int gmLevel, bool whiteList = true); + std::vector> IsSentenceOkay(const std::string& message, eGameMasterLevel gmLevel, bool whiteList = true); private: bool m_DontGenerateDCF; diff --git a/dCommon/GeneralUtils.cpp b/dCommon/GeneralUtils.cpp index 54ef5661..df641a1b 100644 --- a/dCommon/GeneralUtils.cpp +++ b/dCommon/GeneralUtils.cpp @@ -319,3 +319,7 @@ std::vector GeneralUtils::GetSqlFileNamesFromFolder(const std::stri return sortedFiles; } + +bool GeneralUtils::TryParse(const std::string& x, const std::string& y, const std::string& z, NiPoint3& dst) { + return TryParse(x.c_str(), dst.x) && TryParse(y.c_str(), dst.y) && TryParse(z.c_str(), dst.z); +} diff --git a/dCommon/GeneralUtils.h b/dCommon/GeneralUtils.h index a2a52b45..25aac783 100644 --- a/dCommon/GeneralUtils.h +++ b/dCommon/GeneralUtils.h @@ -10,6 +10,7 @@ #include #include #include +#include "NiPoint3.h" #include "Game.h" #include "dLogger.h" @@ -208,6 +209,8 @@ namespace GeneralUtils { return TryParse(value.c_str(), dst); } + bool TryParse(const std::string& x, const std::string& y, const std::string& z, NiPoint3& dst); + template std::u16string to_u16string(T value) { return GeneralUtils::ASCIIToUTF16(std::to_string(value)); diff --git a/dCommon/NiPoint3.cpp b/dCommon/NiPoint3.cpp index a539c4df..b2ffa0d1 100644 --- a/dCommon/NiPoint3.cpp +++ b/dCommon/NiPoint3.cpp @@ -128,6 +128,12 @@ NiPoint3 NiPoint3::operator+(const NiPoint3& point) const { return NiPoint3(this->x + point.x, this->y + point.y, this->z + point.z); } +//! Operator for addition of vectors +NiPoint3 NiPoint3::operator+=(const NiPoint3& point) const { + return NiPoint3(this->x + point.x, this->y + point.y, this->z + point.z); +} + + //! Operator for subtraction of vectors NiPoint3 NiPoint3::operator-(const NiPoint3& point) const { return NiPoint3(this->x - point.x, this->y - point.y, this->z - point.z); diff --git a/dCommon/NiPoint3.h b/dCommon/NiPoint3.h index 6c0b9d3d..f76b9269 100644 --- a/dCommon/NiPoint3.h +++ b/dCommon/NiPoint3.h @@ -135,6 +135,9 @@ public: //! Operator for addition of vectors NiPoint3 operator+(const NiPoint3& point) const; + //! Operator for addition of vectors + NiPoint3 operator+=(const NiPoint3& point) const; + //! Operator for subtraction of vectors NiPoint3 operator-(const NiPoint3& point) const; diff --git a/dCommon/dEnums/dCommonVars.h b/dCommon/dEnums/dCommonVars.h index 2b7f63dc..16cae3c9 100644 --- a/dCommon/dEnums/dCommonVars.h +++ b/dCommon/dEnums/dCommonVars.h @@ -175,21 +175,6 @@ union suchar { char svalue; }; -//=========== DLU ENUMS ============ - -enum eGameMasterLevel : int32_t { - GAME_MASTER_LEVEL_CIVILIAN = 0, // Normal player. - GAME_MASTER_LEVEL_FORUM_MODERATOR = 1, // No permissions on live servers. - GAME_MASTER_LEVEL_JUNIOR_MODERATOR = 2, // Can kick/mute and pull chat logs. - GAME_MASTER_LEVEL_MODERATOR = 3, // Can return lost items. - GAME_MASTER_LEVEL_SENIOR_MODERATOR = 4, // Can ban. - GAME_MASTER_LEVEL_LEAD_MODERATOR = 5, // Can approve properties. - GAME_MASTER_LEVEL_JUNIOR_DEVELOPER = 6, // Junior developer & future content team. Civilan on live. - GAME_MASTER_LEVEL_INACTIVE_DEVELOPER = 7, // Inactive developer, limited permissions. - GAME_MASTER_LEVEL_DEVELOPER = 8, // Active developer, full permissions on live. - GAME_MASTER_LEVEL_OPERATOR = 9 // Can shutdown server for restarts & updates. -}; - //=========== LU ENUMS ============ //! An enum for object ID bits diff --git a/dCommon/dEnums/dMessageIdentifiers.h b/dCommon/dEnums/dMessageIdentifiers.h index e11f9e7f..7c810a2d 100644 --- a/dCommon/dEnums/dMessageIdentifiers.h +++ b/dCommon/dEnums/dMessageIdentifiers.h @@ -445,6 +445,7 @@ enum GAME_MSG : unsigned short { GAME_MSG_BBB_SAVE_RESPONSE = 1006, GAME_MSG_NOTIFY_CLIENT_OBJECT = 1042, GAME_MSG_DISPLAY_ZONE_SUMMARY = 1043, + GAME_MSG_ZONE_SUMMARY_DISMISSED = 1044, GAME_MSG_ACTIVITY_STATE_CHANGE_REQUEST = 1053, GAME_MSG_MODIFY_PLAYER_ZONE_STATISTIC = 1046, GAME_MSG_START_BUILDING_WITH_ITEM = 1057, @@ -484,6 +485,7 @@ enum GAME_MSG : unsigned short { GAME_MSG_LOCK_NODE_ROTATION = 1260, GAME_MSG_VEHICLE_SET_WHEEL_LOCK_STATE = 1273, GAME_MSG_NOTIFY_VEHICLE_OF_RACING_OBJECT = 1276, + GAME_MSG_SET_NAME_BILLBOARD_STATE = 1284, GAME_MSG_PLAYER_REACHED_RESPAWN_CHECKPOINT = 1296, GAME_MSG_HANDLE_UGC_EQUIP_POST_DELETE_BASED_ON_EDIT_MODE = 1300, GAME_MSG_HANDLE_UGC_EQUIP_PRE_CREATE_BASED_ON_EDIT_MODE = 1301, @@ -494,6 +496,7 @@ enum GAME_MSG : unsigned short { GAME_MSG_MATCH_UPDATE = 1310, GAME_MSG_MODULE_ASSEMBLY_DB_DATA_FOR_CLIENT = 1131, GAME_MSG_MODULE_ASSEMBLY_QUERY_DATA = 1132, + GAME_MSG_SHOW_BILLBOARD_INTERACT_ICON = 1337, GAME_MSG_CHANGE_IDLE_FLAGS = 1338, GAME_MSG_VEHICLE_ADD_PASSIVE_BOOST_ACTION = 1340, GAME_MSG_VEHICLE_REMOVE_PASSIVE_BOOST_ACTION = 1341, diff --git a/dCommon/dEnums/eEndBehavior.h b/dCommon/dEnums/eEndBehavior.h new file mode 100644 index 00000000..77afaab4 --- /dev/null +++ b/dCommon/dEnums/eEndBehavior.h @@ -0,0 +1,11 @@ +#ifndef __EENDBEHAVIOR__H__ +#define __EENDBEHAVIOR__H__ + +#include + +enum class eEndBehavior : uint32_t { + RETURN, + WAIT +}; + +#endif //!__EENDBEHAVIOR__H__ diff --git a/dCommon/dEnums/eGameMasterLevel.h b/dCommon/dEnums/eGameMasterLevel.h new file mode 100644 index 00000000..a63c1caf --- /dev/null +++ b/dCommon/dEnums/eGameMasterLevel.h @@ -0,0 +1,20 @@ +#ifndef __EGAMEMASTERLEVEL__H__ +#define __EGAMEMASTERLEVEL__H__ + +#include + +enum class eGameMasterLevel : uint8_t { + CIVILIAN = 0, // Normal player. + FORUM_MODERATOR = 1, // No permissions on live servers. + JUNIOR_MODERATOR = 2, // Can kick/mute and pull chat logs. + MODERATOR = 3, // Can return lost items. + SENIOR_MODERATOR = 4, // Can ban. + LEAD_MODERATOR = 5, // Can approve properties. + JUNIOR_DEVELOPER = 6, // Junior developer & future content team. Civilan on live. + INACTIVE_DEVELOPER = 7, // Inactive developer, limited permissions. + DEVELOPER = 8, // Active developer, full permissions on live. + OPERATOR = 9 // Can shutdown server for restarts & updates. +}; + + +#endif //!__EGAMEMASTERLEVEL__H__ diff --git a/dCommon/dEnums/ePhysicsEffectType.h b/dCommon/dEnums/ePhysicsEffectType.h new file mode 100644 index 00000000..1aa68b34 --- /dev/null +++ b/dCommon/dEnums/ePhysicsEffectType.h @@ -0,0 +1,15 @@ +#ifndef __EPHYSICSEFFECTTYPE__H__ +#define __EPHYSICSEFFECTTYPE__H__ + + +#include + +enum class ePhysicsEffectType : uint32_t { + PUSH, + ATTRACT, + REPULSE, + GRAVITY_SCALE, + FRICTION +}; + +#endif //!__EPHYSICSEFFECTTYPE__H__ diff --git a/dCommon/dEnums/eTriggerEventType.h b/dCommon/dEnums/eTriggerEventType.h index 1705ce22..a2daa256 100644 --- a/dCommon/dEnums/eTriggerEventType.h +++ b/dCommon/dEnums/eTriggerEventType.h @@ -35,7 +35,7 @@ public: {"OnTimerDone", eTriggerEventType::TIMER_DONE}, {"OnRebuildComplete", eTriggerEventType::REBUILD_COMPLETE}, {"OnActivated", eTriggerEventType::ACTIVATED}, - {"OnDeactivated", eTriggerEventType::DEACTIVATED}, + {"OnDectivated", eTriggerEventType::DEACTIVATED}, // Dectivated vs Deactivated {"OnArrived", eTriggerEventType::ARRIVED}, {"OnArrivedAtEndOfPath", eTriggerEventType::ARRIVED_AT_END_OF_PATH}, {"OnZoneSummaryDismissed", eTriggerEventType::ZONE_SUMMARY_DISMISSED}, diff --git a/dGame/Character.cpp b/dGame/Character.cpp index 572a3e9e..b8d08854 100644 --- a/dGame/Character.cpp +++ b/dGame/Character.cpp @@ -18,6 +18,7 @@ #include "InventoryComponent.h" #include "eMissionTaskType.h" #include "eMissionState.h" +#include "eGameMasterLevel.h" Character::Character(uint32_t id, User* parentUser) { //First load the name, etc: @@ -204,7 +205,9 @@ void Character::DoQuickXMLDataParse() { tinyxml2::XMLElement* character = m_Doc->FirstChildElement("obj")->FirstChildElement("char"); if (character) { character->QueryAttribute("cc", &m_Coins); - character->QueryAttribute("gm", &m_GMLevel); + int32_t gm_level = 0; + character->QueryAttribute("gm", &gm_level); + m_GMLevel = static_cast(gm_level); uint64_t lzidConcat = 0; if (character->FindAttribute("lzid")) { @@ -304,7 +307,7 @@ void Character::SaveXMLToDatabase() { tinyxml2::XMLElement* character = m_Doc->FirstChildElement("obj")->FirstChildElement("char"); if (character) { - character->SetAttribute("gm", m_GMLevel); + character->SetAttribute("gm", static_cast(m_GMLevel)); character->SetAttribute("cc", m_Coins); auto zoneInfo = dZoneManager::Instance()->GetZone()->GetZoneID(); @@ -545,7 +548,7 @@ void Character::OnZoneLoad() { const auto maxGMLevel = m_ParentUser->GetMaxGMLevel(); // This does not apply to the GMs - if (maxGMLevel > GAME_MASTER_LEVEL_CIVILIAN) { + if (maxGMLevel > eGameMasterLevel::CIVILIAN) { return; } @@ -621,3 +624,21 @@ void Character::SendMuteNotice() const { ChatPackets::SendSystemMessage(GetEntity()->GetSystemAddress(), u"You are muted until " + timeStr); } + +void Character::SetBillboardVisible(bool visible) { + if (m_BillboardVisible == visible) return; + m_BillboardVisible = visible; + + GameMessages::SendSetNamebillboardState(UNASSIGNED_SYSTEM_ADDRESS, m_OurEntity->GetObjectID()); + + if (!visible) return; + + // The GameMessage we send for turning the nameplate off just deletes the BillboardSubcomponent from the parent component. + // Because that same message does not allow for custom parameters, we need to create the BillboardSubcomponent a different way + // This workaround involves sending an unrelated GameMessage that does not apply to player entites, + // but forces the client to create the necessary SubComponent that controls the billboard. + GameMessages::SendShowBillboardInteractIcon(UNASSIGNED_SYSTEM_ADDRESS, m_OurEntity->GetObjectID()); + + // Now turn off the billboard for the owner. + GameMessages::SendSetNamebillboardState(m_OurEntity->GetSystemAddress(), m_OurEntity->GetObjectID()); +} diff --git a/dGame/Character.h b/dGame/Character.h index abded1b3..2f0abba5 100644 --- a/dGame/Character.h +++ b/dGame/Character.h @@ -15,6 +15,7 @@ class User; struct Packet; class Entity; enum class ePermissionMap : uint64_t; +enum class eGameMasterLevel : uint8_t; /** * Meta information about a character, like their name and style @@ -308,13 +309,13 @@ public: * Gets the GM level of the character * @return the GM level */ - int32_t GetGMLevel() const { return m_GMLevel; } + eGameMasterLevel GetGMLevel() const { return m_GMLevel; } /** * Sets the GM level of the character * @param value the GM level to set */ - void SetGMLevel(uint8_t value) { m_GMLevel = value; } + void SetGMLevel(eGameMasterLevel value) { m_GMLevel = value; } /** * Gets the current amount of coins of the character @@ -451,6 +452,10 @@ public: */ void SetIsFlying(bool isFlying) { m_IsFlying = isFlying; } + bool GetBillboardVisible() { return m_BillboardVisible; } + + void SetBillboardVisible(bool visible); + private: /** * The ID of this character. First 32 bits of the ObjectID. @@ -477,7 +482,7 @@ private: * * @see eGameMasterLevel */ - int32_t m_GMLevel; + eGameMasterLevel m_GMLevel; /** * Bitmap of permission attributes this character has. @@ -652,6 +657,11 @@ private: */ bool m_IsFlying = false; + /** + * True if billboard (referred to as nameplate for end users) is visible, false otherwise + */ + bool m_BillboardVisible = true; + /** * Queries the character XML and updates all the fields of this object * NOTE: quick as there's no DB lookups diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index 290f4f7e..4b0e1506 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -70,6 +70,7 @@ #include "RailActivatorComponent.h" #include "LUPExhibitComponent.h" #include "TriggerComponent.h" +#include "eGameMasterLevel.h" #include "eReplicaComponentType.h" // Table includes @@ -89,7 +90,7 @@ Entity::Entity(const LWOOBJID& objectID, EntityInfo info, Entity* parentEntity) m_TemplateID = info.lot; m_ParentEntity = parentEntity; m_Character = nullptr; - m_GMLevel = 0; + m_GMLevel = eGameMasterLevel::CIVILIAN; m_CollectibleID = 0; m_NetworkID = 0; m_Groups = {}; @@ -763,7 +764,7 @@ void Entity::Initialize() { no_ghosting: - TriggerEvent(eTriggerEventType::CREATE); + TriggerEvent(eTriggerEventType::CREATE, this); if (m_Character) { auto* controllablePhysicsComponent = GetComponent(); @@ -858,7 +859,7 @@ void Entity::SetProximityRadius(dpEntity* entity, std::string name) { proxMon->SetProximityRadius(entity, name); } -void Entity::SetGMLevel(uint8_t value) { +void Entity::SetGMLevel(eGameMasterLevel value) { m_GMLevel = value; if (GetParentUser()) { Character* character = GetParentUser()->GetLastUsedChar(); @@ -970,7 +971,7 @@ void Entity::WriteBaseReplicaData(RakNet::BitStream* outBitStream, eReplicaPacke outBitStream->Write0(); //ObjectWorldState - if (m_GMLevel != 0) { + if (m_GMLevel != eGameMasterLevel::CIVILIAN) { outBitStream->Write1(); outBitStream->Write(m_GMLevel); } else outBitStream->Write0(); //No GM Level @@ -1390,7 +1391,7 @@ void Entity::OnEmoteReceived(const int32_t emote, Entity* target) { } void Entity::OnUse(Entity* originator) { - TriggerEvent(eTriggerEventType::INTERACT); + TriggerEvent(eTriggerEventType::INTERACT, originator); for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { script->OnUse(this, originator); @@ -1412,6 +1413,7 @@ void Entity::OnHitOrHealResult(Entity* attacker, int32_t damage) { } void Entity::OnHit(Entity* attacker) { + TriggerEvent(eTriggerEventType::HIT, attacker); for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { script->OnHit(this, attacker); } diff --git a/dGame/Entity.h b/dGame/Entity.h index ae16fb82..f8abff31 100644 --- a/dGame/Entity.h +++ b/dGame/Entity.h @@ -31,6 +31,7 @@ class Item; class Character; class EntityCallbackTimer; enum class eTriggerEventType; +enum class eGameMasterLevel : uint8_t; enum class eReplicaComponentType : uint32_t; namespace CppScripts { @@ -60,7 +61,7 @@ public: Character* GetCharacter() const { return m_Character; } - uint8_t GetGMLevel() const { return m_GMLevel; } + eGameMasterLevel GetGMLevel() const { return m_GMLevel; } uint8_t GetCollectibleID() const { return uint8_t(m_CollectibleID); } @@ -108,7 +109,7 @@ public: void SetCharacter(Character* value) { m_Character = value; } - void SetGMLevel(uint8_t value); + void SetGMLevel(eGameMasterLevel value); void SetOwnerOverride(LWOOBJID value); @@ -308,7 +309,7 @@ protected: Entity* m_ParentEntity; //For spawners and the like std::vector m_ChildEntities; - uint8_t m_GMLevel; + eGameMasterLevel m_GMLevel; uint16_t m_CollectibleID; std::vector m_Groups; uint16_t m_NetworkID; diff --git a/dGame/EntityManager.cpp b/dGame/EntityManager.cpp index e79ada25..d547cdb1 100644 --- a/dGame/EntityManager.cpp +++ b/dGame/EntityManager.cpp @@ -20,6 +20,7 @@ #include "MessageIdentifiers.h" #include "dConfig.h" #include "eTriggerEventType.h" +#include "eGameMasterLevel.h" #include "eReplicaComponentType.h" EntityManager* EntityManager::m_Address = nullptr; @@ -162,6 +163,8 @@ void EntityManager::DestroyEntity(Entity* entity) { return; } + entity->TriggerEvent(eTriggerEventType::DESTROY, entity); + const auto id = entity->GetObjectID(); if (std::count(m_EntitiesToDelete.begin(), m_EntitiesToDelete.end(), id)) { @@ -370,7 +373,7 @@ void EntityManager::ConstructEntity(Entity* entity, const SystemAddress& sysAddr // PacketUtils::SavePacket("[24]_"+std::to_string(entity->GetObjectID()) + "_" + std::to_string(m_SerializationCounter) + ".bin", (char*)stream.GetData(), stream.GetNumberOfBytesUsed()); if (entity->IsPlayer()) { - if (entity->GetGMLevel() > GAME_MASTER_LEVEL_CIVILIAN) { + if (entity->GetGMLevel() > eGameMasterLevel::CIVILIAN) { GameMessages::SendToggleGMInvis(entity->GetObjectID(), true, sysAddr); } } @@ -587,7 +590,7 @@ void EntityManager::ScheduleForKill(Entity* entity) { SwitchComponent* switchComp = entity->GetComponent(); if (switchComp) { - entity->TriggerEvent(eTriggerEventType::DEACTIVATED); + entity->TriggerEvent(eTriggerEventType::DEACTIVATED, entity); } const auto objectId = entity->GetObjectID(); diff --git a/dGame/User.cpp b/dGame/User.cpp index dc607cd0..55bbcc09 100644 --- a/dGame/User.cpp +++ b/dGame/User.cpp @@ -6,13 +6,14 @@ #include "Game.h" #include "dZoneManager.h" #include "eServerDisconnectIdentifiers.h" +#include "eGameMasterLevel.h" User::User(const SystemAddress& sysAddr, const std::string& username, const std::string& sessionKey) { m_AccountID = 0; m_Username = ""; m_SessionKey = ""; - m_MaxGMLevel = 0; //The max GM level this account can assign to it's characters + m_MaxGMLevel = eGameMasterLevel::CIVILIAN; //The max GM level this account can assign to it's characters m_LastCharID = 0; m_SessionKey = sessionKey; @@ -33,7 +34,7 @@ User::User(const SystemAddress& sysAddr, const std::string& username, const std: sql::ResultSet* res = stmt->executeQuery(); while (res->next()) { m_AccountID = res->getUInt(1); - m_MaxGMLevel = res->getInt(2); + m_MaxGMLevel = static_cast(res->getInt(2)); m_MuteExpire = 0; //res->getUInt64(3); } diff --git a/dGame/User.h b/dGame/User.h index 59416c4c..3201538e 100644 --- a/dGame/User.h +++ b/dGame/User.h @@ -9,6 +9,7 @@ #include class Character; +enum class eGameMasterLevel : uint8_t; struct BehaviorParams { uint32_t behavior; @@ -29,7 +30,7 @@ public: std::string& GetSessionKey() { return m_SessionKey; } SystemAddress& GetSystemAddress() { return m_SystemAddress; } - uint32_t GetMaxGMLevel() { return m_MaxGMLevel; } + eGameMasterLevel GetMaxGMLevel() { return m_MaxGMLevel; } uint32_t GetLastCharID() { return m_LastCharID; } void SetLastCharID(uint32_t newCharID) { m_LastCharID = newCharID; } @@ -61,7 +62,7 @@ private: std::string m_SessionKey; SystemAddress m_SystemAddress; - uint32_t m_MaxGMLevel; //The max GM level this account can assign to it's characters + eGameMasterLevel m_MaxGMLevel; //The max GM level this account can assign to it's characters uint32_t m_LastCharID; std::vector m_Characters; LWOOBJID m_LoggedInCharID; diff --git a/dGame/UserManager.cpp b/dGame/UserManager.cpp index 93469daa..4f0c456d 100644 --- a/dGame/UserManager.cpp +++ b/dGame/UserManager.cpp @@ -23,6 +23,7 @@ #include "AssetManager.h" #include "CDClientDatabase.h" #include "dMessageIdentifiers.h" +#include "eGameMasterLevel.h" UserManager* UserManager::m_Address = nullptr; @@ -330,7 +331,7 @@ void UserManager::CreateCharacter(const SystemAddress& sysAddr, Packet* packet) //Check to see if our name was pre-approved: bool nameOk = IsNamePreapproved(name); - if (!nameOk && u->GetMaxGMLevel() > 1) nameOk = true; + if (!nameOk && u->GetMaxGMLevel() > eGameMasterLevel::FORUM_MODERATOR) nameOk = true; if (name != "") { sql::PreparedStatement* stmt = Database::CreatePreppedStmt("INSERT INTO `charinfo`(`id`, `account_id`, `name`, `pending_name`, `needs_rename`, `last_login`) VALUES (?,?,?,?,?,?)"); diff --git a/dGame/dComponents/BouncerComponent.cpp b/dGame/dComponents/BouncerComponent.cpp index 1f32d6e5..f6a53261 100644 --- a/dGame/dComponents/BouncerComponent.cpp +++ b/dGame/dComponents/BouncerComponent.cpp @@ -7,6 +7,7 @@ #include "dLogger.h" #include "GameMessages.h" #include +#include "eTriggerEventType.h" BouncerComponent::BouncerComponent(Entity* parent) : Component(parent) { m_PetEnabled = false; @@ -46,8 +47,10 @@ void BouncerComponent::SetPetBouncerEnabled(bool value) { EntityManager::Instance()->SerializeEntity(m_Parent); if (value) { + m_Parent->TriggerEvent(eTriggerEventType::PET_ON_SWITCH, m_Parent); GameMessages::SendPlayFXEffect(m_Parent->GetObjectID(), 1513, u"create", "PetOnSwitch", LWOOBJID_EMPTY, 1, 1, true); } else { + m_Parent->TriggerEvent(eTriggerEventType::PET_OFF_SWITCH, m_Parent); GameMessages::SendStopFXEffect(m_Parent, true, "PetOnSwitch"); } diff --git a/dGame/dComponents/CharacterComponent.cpp b/dGame/dComponents/CharacterComponent.cpp index 98540bd0..6394cc32 100644 --- a/dGame/dComponents/CharacterComponent.cpp +++ b/dGame/dComponents/CharacterComponent.cpp @@ -14,6 +14,7 @@ #include "GameMessages.h" #include "Item.h" #include "AMFFormat.h" +#include "eGameMasterLevel.h" CharacterComponent::CharacterComponent(Entity* parent, Character* character) : Component(parent) { m_Character = character; @@ -165,9 +166,9 @@ void CharacterComponent::SetPvpEnabled(const bool value) { m_PvpEnabled = value; } -void CharacterComponent::SetGMLevel(int gmlevel) { +void CharacterComponent::SetGMLevel(eGameMasterLevel gmlevel) { m_DirtyGMInfo = true; - if (gmlevel > 0) m_IsGM = true; + if (gmlevel > eGameMasterLevel::CIVILIAN) m_IsGM = true; else m_IsGM = false; m_GMLevel = gmlevel; } @@ -239,7 +240,7 @@ void CharacterComponent::LoadFromXml(tinyxml2::XMLDocument* doc) { // End custom attributes // - if (m_GMLevel > 0) { + if (m_GMLevel > eGameMasterLevel::CIVILIAN) { m_IsGM = true; m_DirtyGMInfo = true; m_EditorLevel = m_GMLevel; diff --git a/dGame/dComponents/CharacterComponent.h b/dGame/dComponents/CharacterComponent.h index 613f2322..0e047494 100644 --- a/dGame/dComponents/CharacterComponent.h +++ b/dGame/dComponents/CharacterComponent.h @@ -178,7 +178,7 @@ public: * Sets the GM level of the character, should be called in the entity. Here it's set for serialization * @param gmlevel the gm level to set */ - void SetGMLevel(int gmlevel); + void SetGMLevel(eGameMasterLevel gmlevel); /** * Initializes the player statistics from the string stored in the XML @@ -333,7 +333,7 @@ private: /** * The current GM level of this character (anything > 0 counts as a GM) */ - unsigned char m_GMLevel; + eGameMasterLevel m_GMLevel; /** * Whether the character has HF enabled @@ -343,7 +343,7 @@ private: /** * The level of the character in HF */ - unsigned char m_EditorLevel; + eGameMasterLevel m_EditorLevel; /** * Whether the currently active activity has been changed diff --git a/dGame/dComponents/PetComponent.cpp b/dGame/dComponents/PetComponent.cpp index f5b7a1a7..db4d5693 100644 --- a/dGame/dComponents/PetComponent.cpp +++ b/dGame/dComponents/PetComponent.cpp @@ -23,6 +23,7 @@ #include "EntityInfo.h" #include "eMissionTaskType.h" #include "RenderComponent.h" +#include "eGameMasterLevel.h" std::unordered_map PetComponent::buildCache{}; std::unordered_map PetComponent::currentActivities{}; @@ -988,7 +989,7 @@ void PetComponent::Command(NiPoint3 position, LWOOBJID source, int32_t commandTy // TODO: Go to player } - if (owner->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (owner->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { ChatPackets::SendSystemMessage(owner->GetSystemAddress(), u"Commmand Type: " + (GeneralUtils::to_u16string(commandType)) + u" - Type Id: " + (GeneralUtils::to_u16string(typeId))); } } @@ -1080,7 +1081,7 @@ void PetComponent::SetPetNameForModeration(const std::string& petName) { int approved = 1; //default, in mod //Make sure that the name isn't already auto-approved: - if (Game::chatFilter->IsSentenceOkay(petName, 0).empty()) { + if (Game::chatFilter->IsSentenceOkay(petName, eGameMasterLevel::CIVILIAN).empty()) { approved = 2; //approved } diff --git a/dGame/dComponents/PhantomPhysicsComponent.cpp b/dGame/dComponents/PhantomPhysicsComponent.cpp index 75cef4fb..ce205826 100644 --- a/dGame/dComponents/PhantomPhysicsComponent.cpp +++ b/dGame/dComponents/PhantomPhysicsComponent.cpp @@ -14,6 +14,7 @@ #include "EntityManager.h" #include "ControllablePhysicsComponent.h" #include "GameMessages.h" +#include "ePhysicsEffectType.h" #include "CDClientManager.h" #include "CDComponentsRegistryTable.h" @@ -36,7 +37,7 @@ PhantomPhysicsComponent::PhantomPhysicsComponent(Entity* parent) : Component(par m_PositionInfoDirty = false; m_IsPhysicsEffectActive = false; - m_EffectType = 0; + m_EffectType = ePhysicsEffectType::PUSH; m_DirectionalMultiplier = 0.0f; m_MinMax = false; @@ -405,7 +406,7 @@ void PhantomPhysicsComponent::SetDirectionalMultiplier(float mul) { m_EffectInfoDirty = true; } -void PhantomPhysicsComponent::SetEffectType(uint32_t type) { +void PhantomPhysicsComponent::SetEffectType(ePhysicsEffectType type) { m_EffectType = type; m_EffectInfoDirty = true; } diff --git a/dGame/dComponents/PhantomPhysicsComponent.h b/dGame/dComponents/PhantomPhysicsComponent.h index 0b27db05..cc0d1844 100644 --- a/dGame/dComponents/PhantomPhysicsComponent.h +++ b/dGame/dComponents/PhantomPhysicsComponent.h @@ -17,6 +17,7 @@ class LDFBaseData; class Entity; class dpEntity; +enum class ePhysicsEffectType : uint32_t ; /** * Allows the creation of phantom physics for an entity: a physics object that is generally invisible but can be @@ -103,13 +104,13 @@ public: * Returns the effect that's currently active, defaults to 0 * @return the effect that's currently active */ - uint32_t GetEffectType() const { return m_EffectType; } + ePhysicsEffectType GetEffectType() const { return m_EffectType; } /** * Sets the effect that's currently active * @param type the effect to set */ - void SetEffectType(uint32_t type); + void SetEffectType(ePhysicsEffectType type); /** * Returns the Physics entity for the component @@ -168,7 +169,7 @@ private: /** * The physics effect that's currently active, defaults to 0 */ - uint32_t m_EffectType; + ePhysicsEffectType m_EffectType; /** * A scaling multiplier to add to the directional vector diff --git a/dGame/dComponents/PropertyEntranceComponent.cpp b/dGame/dComponents/PropertyEntranceComponent.cpp index fa838ed7..c251dc96 100644 --- a/dGame/dComponents/PropertyEntranceComponent.cpp +++ b/dGame/dComponents/PropertyEntranceComponent.cpp @@ -12,6 +12,7 @@ #include "UserManager.h" #include "dLogger.h" #include "AMFFormat.h" +#include "eGameMasterLevel.h" PropertyEntranceComponent::PropertyEntranceComponent(uint32_t componentID, Entity* parent) : Component(parent) { this->propertyQueries = {}; @@ -271,7 +272,7 @@ void PropertyEntranceComponent::OnPropertyEntranceSync(Entity* entity, bool incl bool isModeratorApproved = propertyEntry->getBoolean(10); - if (!isModeratorApproved && entity->GetGMLevel() >= GAME_MASTER_LEVEL_LEAD_MODERATOR) { + if (!isModeratorApproved && entity->GetGMLevel() >= eGameMasterLevel::LEAD_MODERATOR) { propertyName = "[AWAITING APPROVAL]"; propertyDescription = "[AWAITING APPROVAL]"; isModeratorApproved = true; diff --git a/dGame/dComponents/RebuildComponent.cpp b/dGame/dComponents/RebuildComponent.cpp index f0b39346..6f2e9eab 100644 --- a/dGame/dComponents/RebuildComponent.cpp +++ b/dGame/dComponents/RebuildComponent.cpp @@ -8,6 +8,7 @@ #include "CharacterComponent.h" #include "MissionComponent.h" #include "eMissionTaskType.h" +#include "eTriggerEventType.h" #include "dServer.h" #include "PacketUtils.h" @@ -496,6 +497,8 @@ void RebuildComponent::CompleteRebuild(Entity* user) { for (const auto& callback : m_RebuildCompleteCallbacks) callback(user); + m_Parent->TriggerEvent(eTriggerEventType::REBUILD_COMPLETE, user); + auto* movingPlatform = m_Parent->GetComponent(); if (movingPlatform != nullptr) { movingPlatform->OnCompleteRebuild(); diff --git a/dGame/dComponents/ScriptedActivityComponent.cpp b/dGame/dComponents/ScriptedActivityComponent.cpp index d6700ab2..4f1e15d8 100644 --- a/dGame/dComponents/ScriptedActivityComponent.cpp +++ b/dGame/dComponents/ScriptedActivityComponent.cpp @@ -305,7 +305,7 @@ bool ScriptedActivityComponent::HasLobby() const { bool ScriptedActivityComponent::IsValidActivity(Entity* player) { // Makes it so that scripted activities with an unimplemented map cannot be joined - /*if (player->GetGMLevel() < GAME_MASTER_LEVEL_DEVELOPER && (m_ActivityInfo.instanceMapID == 1302 || m_ActivityInfo.instanceMapID == 1301)) { + /*if (player->GetGMLevel() < eGameMasterLevel::DEVELOPER && (m_ActivityInfo.instanceMapID == 1302 || m_ActivityInfo.instanceMapID == 1301)) { if (m_Parent->GetLOT() == 4860) { auto* missionComponent = player->GetComponent(); missionComponent->CompleteMission(229); diff --git a/dGame/dComponents/SwitchComponent.cpp b/dGame/dComponents/SwitchComponent.cpp index d2c1dd50..131a7d52 100644 --- a/dGame/dComponents/SwitchComponent.cpp +++ b/dGame/dComponents/SwitchComponent.cpp @@ -44,7 +44,7 @@ void SwitchComponent::EntityEnter(Entity* entity) { } m_Active = true; if (!m_Parent) return; - m_Parent->TriggerEvent(eTriggerEventType::ACTIVATED); + m_Parent->TriggerEvent(eTriggerEventType::ACTIVATED, entity); const auto grpName = m_Parent->GetVarAsString(u"grp_name"); @@ -80,7 +80,7 @@ void SwitchComponent::Update(float deltaTime) { if (m_Timer <= 0.0f) { m_Active = false; if (!m_Parent) return; - m_Parent->TriggerEvent(eTriggerEventType::DEACTIVATED); + m_Parent->TriggerEvent(eTriggerEventType::DEACTIVATED, m_Parent); const auto grpName = m_Parent->GetVarAsString(u"grp_name"); diff --git a/dGame/dComponents/TriggerComponent.cpp b/dGame/dComponents/TriggerComponent.cpp index d98b2eea..0f241116 100644 --- a/dGame/dComponents/TriggerComponent.cpp +++ b/dGame/dComponents/TriggerComponent.cpp @@ -1,10 +1,19 @@ #include "TriggerComponent.h" #include "dZoneManager.h" -#include "LUTriggers.h" +#include "TeamManager.h" #include "eTriggerCommandType.h" +#include "eMissionTaskType.h" +#include "ePhysicsEffectType.h" + +#include "CharacterComponent.h" +#include "ControllablePhysicsComponent.h" #include "MissionComponent.h" #include "PhantomPhysicsComponent.h" -#include "CDMissionTasksTable.h" +#include "Player.h" +#include "RebuildComponent.h" +#include "SkillComponent.h" +#include "eEndBehavior.h" + TriggerComponent::TriggerComponent(Entity* parent, const std::string triggerInfo): Component(parent) { m_Parent = parent; @@ -51,19 +60,37 @@ void TriggerComponent::HandleTriggerCommand(LUTriggers::Command* command, Entity case eTriggerCommandType::FIRE_EVENT: HandleFireEvent(targetEntity, command->args); break; - case eTriggerCommandType::DESTROY_OBJ: break; - case eTriggerCommandType::TOGGLE_TRIGGER: break; - case eTriggerCommandType::RESET_REBUILD: break; + case eTriggerCommandType::DESTROY_OBJ: + HandleDestroyObject(targetEntity, command->args); + break; + case eTriggerCommandType::TOGGLE_TRIGGER: + HandleToggleTrigger(targetEntity, command->args); + break; + case eTriggerCommandType::RESET_REBUILD: + HandleResetRebuild(targetEntity, command->args); + break; case eTriggerCommandType::SET_PATH: break; case eTriggerCommandType::SET_PICK_TYPE: break; - case eTriggerCommandType::MOVE_OBJECT: break; - case eTriggerCommandType::ROTATE_OBJECT: break; - case eTriggerCommandType::PUSH_OBJECT: break; - case eTriggerCommandType::REPEL_OBJECT: break; + case eTriggerCommandType::MOVE_OBJECT: + HandleMoveObject(targetEntity, argArray); + break; + case eTriggerCommandType::ROTATE_OBJECT: + HandleRotateObject(targetEntity, argArray); + break; + case eTriggerCommandType::PUSH_OBJECT: + HandlePushObject(targetEntity, argArray); + break; + case eTriggerCommandType::REPEL_OBJECT: + HandleRepelObject(targetEntity, command->args); + break; case eTriggerCommandType::SET_TIMER: break; case eTriggerCommandType::CANCEL_TIMER: break; - case eTriggerCommandType::PLAY_CINEMATIC: break; - case eTriggerCommandType::TOGGLE_BBB: break; + case eTriggerCommandType::PLAY_CINEMATIC: + HandlePlayCinematic(targetEntity, argArray); + break; + case eTriggerCommandType::TOGGLE_BBB: + HandleToggleBBB(targetEntity, command->args); + break; case eTriggerCommandType::UPDATE_MISSION: HandleUpdateMission(targetEntity, argArray); break; @@ -75,8 +102,43 @@ void TriggerComponent::HandleTriggerCommand(LUTriggers::Command* command, Entity case eTriggerCommandType::STOP_PATHING: break; case eTriggerCommandType::START_PATHING: break; case eTriggerCommandType::LOCK_OR_UNLOCK_CONTROLS: break; - case eTriggerCommandType::PLAY_EFFECT: break; - case eTriggerCommandType::STOP_EFFECT: break; + case eTriggerCommandType::PLAY_EFFECT: + HandlePlayEffect(targetEntity, argArray); + break; + case eTriggerCommandType::STOP_EFFECT: + GameMessages::SendStopFXEffect(targetEntity, true, command->args); + break; + case eTriggerCommandType::CAST_SKILL: + HandleCastSkill(targetEntity, command->args); + break; + case eTriggerCommandType::DISPLAY_ZONE_SUMMARY: + GameMessages::SendDisplayZoneSummary(targetEntity->GetObjectID(), targetEntity->GetSystemAddress(), false, command->args == "1", m_Parent->GetObjectID()); + break; + case eTriggerCommandType::SET_PHYSICS_VOLUME_EFFECT: + HandleSetPhysicsVolumeEffect(targetEntity, argArray); + break; + case eTriggerCommandType::SET_PHYSICS_VOLUME_STATUS: + HandleSetPhysicsVolumeStatus(targetEntity, command->args); + break; + case eTriggerCommandType::SET_MODEL_TO_BUILD: break; + case eTriggerCommandType::SPAWN_MODEL_BRICKS: break; + case eTriggerCommandType::ACTIVATE_SPAWNER_NETWORK: + HandleActivateSpawnerNetwork(command->args); + break; + case eTriggerCommandType::DEACTIVATE_SPAWNER_NETWORK: + HandleDeactivateSpawnerNetwork(command->args); + break; + case eTriggerCommandType::RESET_SPAWNER_NETWORK: + HandleResetSpawnerNetwork(command->args); + break; + case eTriggerCommandType::DESTROY_SPAWNER_NETWORK_OBJECTS: + HandleDestroySpawnerNetworkObjects(command->args); + break; + case eTriggerCommandType::GO_TO_WAYPOINT: break; + case eTriggerCommandType::ACTIVATE_PHYSICS: + HandleActivatePhysics(targetEntity, command->args); + break; + // DEPRECATED BLOCK START case eTriggerCommandType::ACTIVATE_MUSIC_CUE: break; case eTriggerCommandType::DEACTIVATE_MUSIC_CUE: break; case eTriggerCommandType::FLASH_MUSIC_CUE: break; @@ -87,20 +149,7 @@ void TriggerComponent::HandleTriggerCommand(LUTriggers::Command* command, Entity case eTriggerCommandType::STOP_3D_AMBIENT_SOUND: break; case eTriggerCommandType::ACTIVATE_MIXER_PROGRAM: break; case eTriggerCommandType::DEACTIVATE_MIXER_PROGRAM: break; - case eTriggerCommandType::CAST_SKILL: break; - case eTriggerCommandType::DISPLAY_ZONE_SUMMARY: break; - case eTriggerCommandType::SET_PHYSICS_VOLUME_EFFECT: - HandleSetPhysicsVolume(targetEntity, argArray, command->target); - break; - case eTriggerCommandType::SET_PHYSICS_VOLUME_STATUS: break; - case eTriggerCommandType::SET_MODEL_TO_BUILD: break; - case eTriggerCommandType::SPAWN_MODEL_BRICKS: break; - case eTriggerCommandType::ACTIVATE_SPAWNER_NETWORK: break; - case eTriggerCommandType::DEACTIVATE_SPAWNER_NETWORK: break; - case eTriggerCommandType::RESET_SPAWNER_NETWORK: break; - case eTriggerCommandType::DESTROY_SPAWNER_NETWORK_OBJECTS: break; - case eTriggerCommandType::GO_TO_WAYPOINT: break; - case eTriggerCommandType::ACTIVATE_PHYSICS: break; + // DEPRECATED BLOCK END default: Game::logger->LogDebug("TriggerComponent", "Event %i was not handled!", command->id); break; @@ -113,70 +162,262 @@ std::vector TriggerComponent::GatherTargets(LUTriggers::Command* comman if (command->target == "self") entities.push_back(m_Parent); else if (command->target == "zone") { /*TODO*/ } - else if (command->target == "target") { /*TODO*/ } - else if (command->target == "targetTeam") { /*TODO*/ } - else if (command->target == "objGroup") entities = EntityManager::Instance()->GetEntitiesInGroup(command->targetName); - else if (command->target == "allPlayers") { /*TODO*/ } - else if (command->target == "allNPCs") { /*TODO*/ } - - if (optionalTarget) entities.push_back(optionalTarget); + else if (command->target == "target" && optionalTarget) entities.push_back(optionalTarget); + else if (command->target == "targetTeam" && optionalTarget) { + auto* team = TeamManager::Instance()->GetTeam(optionalTarget->GetObjectID()); + for (const auto memberId : team->members) { + auto* member = EntityManager::Instance()->GetEntity(memberId); + if (member) entities.push_back(member); + } + } else if (command->target == "objGroup") entities = EntityManager::Instance()->GetEntitiesInGroup(command->targetName); + else if (command->target == "allPlayers") { + for (auto* player : Player::GetAllPlayers()) { + entities.push_back(player); + } + } else if (command->target == "allNPCs") { /*UNUSED*/ } return entities; } -void TriggerComponent::HandleSetPhysicsVolume(Entity* targetEntity, std::vector argArray, std::string target) { - PhantomPhysicsComponent* phanPhys = m_Parent->GetComponent(); - if (!phanPhys) return; - - phanPhys->SetPhysicsEffectActive(true); - uint32_t effectType = 0; - std::transform(argArray.at(0).begin(), argArray.at(0).end(), argArray.at(0).begin(), ::tolower); //Transform to lowercase - if (argArray.at(0) == "push") effectType = 0; - else if (argArray.at(0) == "attract") effectType = 1; - else if (argArray.at(0) == "repulse") effectType = 2; - else if (argArray.at(0) == "gravity") effectType = 3; - else if (argArray.at(0) == "friction") effectType = 4; - - phanPhys->SetEffectType(effectType); - phanPhys->SetDirectionalMultiplier(std::stof(argArray.at(1))); - if (argArray.size() > 4) { - NiPoint3 direction = NiPoint3::ZERO; - GeneralUtils::TryParse(argArray.at(2), direction.x); - GeneralUtils::TryParse(argArray.at(3), direction.y); - GeneralUtils::TryParse(argArray.at(4), direction.z); - phanPhys->SetDirection(direction); - } - if (argArray.size() > 5) { - uint32_t min; - GeneralUtils::TryParse(argArray.at(6), min); - phanPhys->SetMin(min); - - uint32_t max; - GeneralUtils::TryParse(argArray.at(7), max); - phanPhys->SetMax(max); - } - - // TODO: why is this contruct and not serialize? - if (target == "self") EntityManager::Instance()->ConstructEntity(m_Parent); -} - -void TriggerComponent::HandleUpdateMission(Entity* targetEntity, std::vector argArray) { - CDMissionTasksTable* missionTasksTable = CDClientManager::Instance().GetTable(); - std::vector missionTasks = missionTasksTable->Query([=](CDMissionTasks entry) { - return (entry.targetGroup == argArray.at(4)); - }); - - for (const CDMissionTasks& task : missionTasks) { - MissionComponent* missionComponent = targetEntity->GetComponent(); - if (!missionComponent) continue; - - missionComponent->ForceProgress(task.id, task.uid, std::stoi(argArray.at(2))); - } -} - void TriggerComponent::HandleFireEvent(Entity* targetEntity, std::string args) { for (CppScripts::Script* script : CppScripts::GetEntityScripts(targetEntity)) { script->OnFireEventServerSide(targetEntity, m_Parent, args, 0, 0, 0); } } +void TriggerComponent::HandleDestroyObject(Entity* targetEntity, std::string args){ + uint32_t killType; + GeneralUtils::TryParse(args, killType); + targetEntity->Smash(m_Parent->GetObjectID(), static_cast(killType)); +} + +void TriggerComponent::HandleToggleTrigger(Entity* targetEntity, std::string args){ + auto* triggerComponent = targetEntity->GetComponent(); + if (!triggerComponent) { + Game::logger->Log("TriggerComponent::HandleToggleTrigger", "Trigger component not found!"); + return; + } + triggerComponent->SetTriggerEnabled(args == "1"); +} + +void TriggerComponent::HandleResetRebuild(Entity* targetEntity, std::string args){ + auto* rebuildComponent = targetEntity->GetComponent(); + if (!rebuildComponent) { + Game::logger->Log("TriggerComponent::HandleResetRebuild", "Rebuild component not found!"); + return; + } + rebuildComponent->ResetRebuild(args == "1"); +} + +void TriggerComponent::HandleMoveObject(Entity* targetEntity, std::vector argArray){ + if (argArray.size() <= 2) return; + + auto position = targetEntity->GetPosition(); + NiPoint3 offset = NiPoint3::ZERO; + GeneralUtils::TryParse(argArray.at(0), argArray.at(1), argArray.at(2), offset); + + position += offset; + targetEntity->SetPosition(position); +} + +void TriggerComponent::HandleRotateObject(Entity* targetEntity, std::vector argArray){ + if (argArray.size() <= 2) return; + + NiPoint3 vector = NiPoint3::ZERO; + GeneralUtils::TryParse(argArray.at(0), argArray.at(1), argArray.at(2), vector); + + NiQuaternion rotation = NiQuaternion::FromEulerAngles(vector); + targetEntity->SetRotation(rotation); +} + +void TriggerComponent::HandlePushObject(Entity* targetEntity, std::vector argArray){ + auto* phantomPhysicsComponent = m_Parent->GetComponent(); + if (!phantomPhysicsComponent) { + Game::logger->Log("TriggerComponent::HandlePushObject", "Phantom Physics component not found!"); + return; + } + phantomPhysicsComponent->SetPhysicsEffectActive(true); + phantomPhysicsComponent->SetEffectType(ePhysicsEffectType::PUSH); + phantomPhysicsComponent->SetDirectionalMultiplier(1); + NiPoint3 direction = NiPoint3::ZERO; + GeneralUtils::TryParse(argArray.at(0), argArray.at(1), argArray.at(2), direction); + phantomPhysicsComponent->SetDirection(direction); + + EntityManager::Instance()->SerializeEntity(m_Parent); +} + + +void TriggerComponent::HandleRepelObject(Entity* targetEntity, std::string args){ + auto* phantomPhysicsComponent = m_Parent->GetComponent(); + if (!phantomPhysicsComponent) { + Game::logger->Log("TriggerComponent::HandleRepelObject", "Phantom Physics component not found!"); + return; + } + float forceMultiplier; + GeneralUtils::TryParse(args, forceMultiplier); + phantomPhysicsComponent->SetPhysicsEffectActive(true); + phantomPhysicsComponent->SetEffectType(ePhysicsEffectType::REPULSE); + phantomPhysicsComponent->SetDirectionalMultiplier(forceMultiplier); + + auto triggerPos = m_Parent->GetPosition(); + auto targetPos = targetEntity->GetPosition(); + + // normalize the vectors to get the direction + auto delta = targetPos - triggerPos; + auto length = delta.Length(); + NiPoint3 direction = delta / length; + phantomPhysicsComponent->SetDirection(direction); + + EntityManager::Instance()->SerializeEntity(m_Parent); +} + +void TriggerComponent::HandlePlayCinematic(Entity* targetEntity, std::vector argArray) { + float leadIn = -1.0; + auto wait = eEndBehavior::RETURN; + bool unlock = true; + bool leaveLocked = false; + bool hidePlayer = false; + + if (argArray.size() >= 2) { + GeneralUtils::TryParse(argArray.at(1), leadIn); + if (argArray.size() >= 3 && argArray.at(2) == "wait") { + wait = eEndBehavior::WAIT; + if (argArray.size() >= 4 && argArray.at(3) == "unlock") { + unlock = false; + if (argArray.size() >= 5 && argArray.at(4) == "leavelocked") { + leaveLocked = true; + if (argArray.size() >= 6 && argArray.at(5) == "hideplayer") { + hidePlayer = true; + } + } + } + } + } + + GameMessages::SendPlayCinematic(targetEntity->GetObjectID(), GeneralUtils::UTF8ToUTF16(argArray.at(0)), targetEntity->GetSystemAddress(), true, true, false, false, wait, hidePlayer, leadIn, leaveLocked, unlock); +} + +void TriggerComponent::HandleToggleBBB(Entity* targetEntity, std::string args) { + auto* character = targetEntity->GetCharacter(); + if (!character) { + Game::logger->Log("TriggerComponent::HandleToggleBBB", "Character was not found!"); + return; + } + bool buildMode = !(character->GetBuildMode()); + if (args == "enter") buildMode = true; + else if (args == "exit") buildMode = false; + character->SetBuildMode(buildMode); +} + +void TriggerComponent::HandleUpdateMission(Entity* targetEntity, std::vector argArray) { + // there are only explore tasks used + // If others need to be implemented for modding + // then we need a good way to convert this from a string to that enum + if (argArray.at(0) != "exploretask") return; + MissionComponent* missionComponent = targetEntity->GetComponent(); + if (!missionComponent){ + Game::logger->Log("TriggerComponent::HandleUpdateMission", "Mission component not found!"); + return; + } + missionComponent->Progress(eMissionTaskType::EXPLORE, 0, 0, argArray.at(4)); +} + +void TriggerComponent::HandlePlayEffect(Entity* targetEntity, std::vector argArray) { + if (argArray.size() < 3) return; + int32_t effectID = 0; + if (!GeneralUtils::TryParse(argArray.at(1), effectID)) return; + std::u16string effectType = GeneralUtils::UTF8ToUTF16(argArray.at(2)); + float priority = 1; + if (argArray.size() == 4) GeneralUtils::TryParse(argArray.at(3), priority); + GameMessages::SendPlayFXEffect(targetEntity, effectID, effectType, argArray.at(0), LWOOBJID_EMPTY, priority); +} + +void TriggerComponent::HandleCastSkill(Entity* targetEntity, std::string args){ + auto* skillComponent = targetEntity->GetComponent(); + if (!skillComponent) { + Game::logger->Log("TriggerComponent::HandleCastSkill", "Skill component not found!"); + return; + } + uint32_t skillId; + GeneralUtils::TryParse(args, skillId); + skillComponent->CastSkill(skillId, targetEntity->GetObjectID()); +} + +void TriggerComponent::HandleSetPhysicsVolumeEffect(Entity* targetEntity, std::vector argArray) { + auto* phantomPhysicsComponent = targetEntity->GetComponent(); + if (!phantomPhysicsComponent) { + Game::logger->Log("TriggerComponent::HandleSetPhysicsVolumeEffect", "Phantom Physics component not found!"); + return; + } + phantomPhysicsComponent->SetPhysicsEffectActive(true); + ePhysicsEffectType effectType = ePhysicsEffectType::PUSH; + std::transform(argArray.at(0).begin(), argArray.at(0).end(), argArray.at(0).begin(), ::tolower); //Transform to lowercase + if (argArray.at(0) == "push") effectType = ePhysicsEffectType::PUSH; + else if (argArray.at(0) == "attract") effectType = ePhysicsEffectType::ATTRACT; + else if (argArray.at(0) == "repulse") effectType = ePhysicsEffectType::REPULSE; + else if (argArray.at(0) == "gravity") effectType = ePhysicsEffectType::GRAVITY_SCALE; + else if (argArray.at(0) == "friction") effectType = ePhysicsEffectType::FRICTION; + + phantomPhysicsComponent->SetEffectType(effectType); + phantomPhysicsComponent->SetDirectionalMultiplier(std::stof(argArray.at(1))); + if (argArray.size() > 4) { + NiPoint3 direction = NiPoint3::ZERO; + GeneralUtils::TryParse(argArray.at(2), argArray.at(3), argArray.at(4), direction); + phantomPhysicsComponent->SetDirection(direction); + } + if (argArray.size() > 5) { + uint32_t min; + GeneralUtils::TryParse(argArray.at(6), min); + phantomPhysicsComponent->SetMin(min); + + uint32_t max; + GeneralUtils::TryParse(argArray.at(7), max); + phantomPhysicsComponent->SetMax(max); + } + + EntityManager::Instance()->SerializeEntity(targetEntity); +} + +void TriggerComponent::HandleSetPhysicsVolumeStatus(Entity* targetEntity, std::string args) { + auto* phantomPhysicsComponent = targetEntity->GetComponent(); + if (!phantomPhysicsComponent) { + Game::logger->Log("TriggerComponent::HandleSetPhysicsVolumeEffect", "Phantom Physics component not found!"); + return; + } + phantomPhysicsComponent->SetPhysicsEffectActive(args == "On"); + EntityManager::Instance()->SerializeEntity(targetEntity); +} + +void TriggerComponent::HandleActivateSpawnerNetwork(std::string args){ + for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(args)) { + if (spawner) spawner->Activate(); + } +} + +void TriggerComponent::HandleDeactivateSpawnerNetwork(std::string args){ + for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(args)) { + if (spawner) spawner->Deactivate(); + } +} + +void TriggerComponent::HandleResetSpawnerNetwork(std::string args){ + for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(args)) { + if (spawner) spawner->Reset(); + } +} + +void TriggerComponent::HandleDestroySpawnerNetworkObjects(std::string args){ + for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(args)) { + if (spawner) spawner->DestroyAllEntities(); + } +} + +void TriggerComponent::HandleActivatePhysics(Entity* targetEntity, std::string args) { + if (args == "true") { + // TODO add physics entity if there isn't one + } else if (args == "false"){ + // TODO remove Phsyics entity if there is one + } else { + Game::logger->LogDebug("TriggerComponent", "Invalid argument for ActivatePhysics Trigger: %s", args.c_str()); + } +} diff --git a/dGame/dComponents/TriggerComponent.h b/dGame/dComponents/TriggerComponent.h index 492b0449..317da00e 100644 --- a/dGame/dComponents/TriggerComponent.h +++ b/dGame/dComponents/TriggerComponent.h @@ -2,13 +2,9 @@ #define __TRIGGERCOMPONENT__H__ #include "Component.h" +#include "LUTriggers.h" #include "eReplicaComponentType.h" -namespace LUTriggers { - struct Trigger; - struct Command; -}; - class TriggerComponent : public Component { public: static const eReplicaComponentType ComponentType = eReplicaComponentType::TRIGGER; @@ -17,18 +13,35 @@ public: void TriggerEvent(eTriggerEventType event, Entity* optionalTarget = nullptr); LUTriggers::Trigger* GetTrigger() const { return m_Trigger; } + void SetTriggerEnabled(bool enabled){ m_Trigger->enabled = enabled; }; + private: void HandleTriggerCommand(LUTriggers::Command* command, Entity* optionalTarget); - std::vector ParseArgs(std::string args); std::vector GatherTargets(LUTriggers::Command* command, Entity* optionalTarget); // Trigger Event Handlers - void HandleSetPhysicsVolume(Entity* targetEntity, std::vector argArray, std::string target); - void HandleUpdateMission(Entity* targetEntity, std::vector argArray); void HandleFireEvent(Entity* targetEntity, std::string args); - void HandleCastSkill(Entity* targetEntity, uint32_t skillID); + void HandleDestroyObject(Entity* targetEntity, std::string args); + void HandleToggleTrigger(Entity* targetEntity, std::string args); + void HandleResetRebuild(Entity* targetEntity, std::string args); + void HandleMoveObject(Entity* targetEntity, std::vector argArray); + void HandleRotateObject(Entity* targetEntity, std::vector argArray); + void HandlePushObject(Entity* targetEntity, std::vector argArray); + void HandleRepelObject(Entity* targetEntity, std::string args); + void HandlePlayCinematic(Entity* targetEntity, std::vector argArray); + void HandleToggleBBB(Entity* targetEntity, std::string args); + void HandleUpdateMission(Entity* targetEntity, std::vector argArray); + void HandlePlayEffect(Entity* targetEntity, std::vector argArray); + void HandleCastSkill(Entity* targetEntity, std::string args); + void HandleSetPhysicsVolumeEffect(Entity* targetEntity, std::vector argArray); + void HandleSetPhysicsVolumeStatus(Entity* targetEntity, std::string args); + void HandleActivateSpawnerNetwork(std::string args); + void HandleDeactivateSpawnerNetwork(std::string args); + void HandleResetSpawnerNetwork(std::string args); + void HandleDestroySpawnerNetworkObjects(std::string args); + void HandleActivatePhysics(Entity* targetEntity, std::string args); LUTriggers::Trigger* m_Trigger; }; diff --git a/dGame/dGameMessages/GameMessageHandler.cpp b/dGame/dGameMessages/GameMessageHandler.cpp index 5c05c28d..c0893a09 100644 --- a/dGame/dGameMessages/GameMessageHandler.cpp +++ b/dGame/dGameMessages/GameMessageHandler.cpp @@ -673,6 +673,9 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System case GAME_MSG_ACTIVATE_BUBBLE_BUFF: GameMessages::HandleActivateBubbleBuff(inStream, entity); break; + case GAME_MSG_ZONE_SUMMARY_DISMISSED: + GameMessages::HandleZoneSummaryDismissed(inStream, entity); + break; default: // Game::logger->Log("GameMessageHandler", "Unknown game message ID: %i", messageID); break; diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 062fece7..b7af9188 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -35,6 +35,7 @@ #include "eMissionTaskType.h" #include "eMissionState.h" #include "RenderComponent.h" +#include "eTriggerEventType.h" #include #include @@ -410,7 +411,7 @@ void GameMessages::SendServerDoneLoadingAllObjects(Entity* entity, const SystemA SEND_PACKET; } -void GameMessages::SendChatModeUpdate(const LWOOBJID& objectID, uint8_t level) { +void GameMessages::SendChatModeUpdate(const LWOOBJID& objectID, eGameMasterLevel level) { CBITSTREAM; CMSGHEADER; bitStream.Write(objectID); @@ -419,7 +420,7 @@ void GameMessages::SendChatModeUpdate(const LWOOBJID& objectID, uint8_t level) { SEND_PACKET_BROADCAST; } -void GameMessages::SendGMLevelBroadcast(const LWOOBJID& objectID, uint8_t level) { +void GameMessages::SendGMLevelBroadcast(const LWOOBJID& objectID, eGameMasterLevel level) { CBITSTREAM; CMSGHEADER; bitStream.Write(objectID); @@ -2814,7 +2815,7 @@ void GameMessages::HandleSetConsumableItem(RakNet::BitStream* inStream, Entity* void GameMessages::SendPlayCinematic(LWOOBJID objectId, std::u16string pathName, const SystemAddress& sysAddr, bool allowGhostUpdates, bool bCloseMultiInteract, bool bSendServerNotify, bool bUseControlledObjectForAudioListener, - int endBehavior, bool hidePlayerDuringCine, float leadIn, bool leavePlayerLockedWhenFinished, + eEndBehavior endBehavior, bool hidePlayerDuringCine, float leadIn, bool leavePlayerLockedWhenFinished, bool lockPlayer, bool result, bool skipIfSamePath, float startTimeAdvance) { CBITSTREAM; CMSGHEADER; @@ -2827,8 +2828,8 @@ void GameMessages::SendPlayCinematic(LWOOBJID objectId, std::u16string pathName, bitStream.Write(bSendServerNotify); bitStream.Write(bUseControlledObjectForAudioListener); - bitStream.Write(endBehavior != 0); - if (endBehavior != 0) bitStream.Write(endBehavior); + bitStream.Write(endBehavior != eEndBehavior::RETURN); + if (endBehavior != eEndBehavior::RETURN) bitStream.Write(endBehavior); bitStream.Write(hidePlayerDuringCine); @@ -6155,3 +6156,39 @@ void GameMessages::SendDeactivateBubbleBuffFromServer(LWOOBJID objectId, const S if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST; SEND_PACKET; } + +void GameMessages::HandleZoneSummaryDismissed(RakNet::BitStream* inStream, Entity* entity) { + LWOOBJID player_id; + inStream->Read(player_id); + auto target = EntityManager::Instance()->GetEntity(player_id); + entity->TriggerEvent(eTriggerEventType::ZONE_SUMMARY_DISMISSED, target); +}; + +void GameMessages::SendSetNamebillboardState(const SystemAddress& sysAddr, LWOOBJID objectId) { + CBITSTREAM; + CMSGHEADER; + + bitStream.Write(objectId); + bitStream.Write(GAME_MSG::GAME_MSG_SET_NAME_BILLBOARD_STATE); + + // Technically these bits would be written, however the client does not + // contain a deserialize method to actually deserialize, so we are leaving it out. + // As such this GM only turns the billboard off. + + // bitStream.Write(overrideDefault); + // bitStream.Write(state); + + if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST + else SEND_PACKET +} + +void GameMessages::SendShowBillboardInteractIcon(const SystemAddress& sysAddr, LWOOBJID objectId) { + CBITSTREAM; + CMSGHEADER; + + bitStream.Write(objectId); + bitStream.Write(GAME_MSG::GAME_MSG_SHOW_BILLBOARD_INTERACT_ICON); + + if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST + else SEND_PACKET +} diff --git a/dGame/dGameMessages/GameMessages.h b/dGame/dGameMessages/GameMessages.h index 5d199995..68f4542f 100644 --- a/dGame/dGameMessages/GameMessages.h +++ b/dGame/dGameMessages/GameMessages.h @@ -7,6 +7,7 @@ #include #include "eMovementPlatformState.h" #include "NiPoint3.h" +#include "eEndBehavior.h" class AMFValue; class Entity; @@ -21,6 +22,7 @@ enum class eAnimationFlags : uint32_t; enum class eUnequippableActiveType; enum eInventoryType : uint32_t; +enum class eGameMasterLevel : uint8_t; namespace GameMessages { class PropertyDataMessage; @@ -61,8 +63,8 @@ namespace GameMessages { void SendRestoreToPostLoadStats(Entity* entity, const SystemAddress& sysAddr); void SendServerDoneLoadingAllObjects(Entity* entity, const SystemAddress& sysAddr); - void SendGMLevelBroadcast(const LWOOBJID& objectID, uint8_t level); - void SendChatModeUpdate(const LWOOBJID& objectID, uint8_t level); + void SendGMLevelBroadcast(const LWOOBJID& objectID, eGameMasterLevel level); + void SendChatModeUpdate(const LWOOBJID& objectID, eGameMasterLevel level); void SendAddItemToInventoryClientSync(Entity* entity, const SystemAddress& sysAddr, Item* item, const LWOOBJID& objectID, bool showFlyingLoot, int itemCount, LWOOBJID subKey = LWOOBJID_EMPTY, eLootSourceType lootSourceType = eLootSourceType::LOOT_SOURCE_NONE); void SendNotifyClientFlagChange(const LWOOBJID& objectID, int iFlagID, bool bFlag, const SystemAddress& sysAddr); @@ -265,7 +267,7 @@ namespace GameMessages { void SendPlayCinematic(LWOOBJID objectId, std::u16string pathName, const SystemAddress& sysAddr, bool allowGhostUpdates = true, bool bCloseMultiInteract = true, bool bSendServerNotify = false, bool bUseControlledObjectForAudioListener = false, - int endBehavior = 0, bool hidePlayerDuringCine = false, float leadIn = -1, bool leavePlayerLockedWhenFinished = false, + eEndBehavior endBehavior = eEndBehavior::RETURN, bool hidePlayerDuringCine = false, float leadIn = -1, bool leavePlayerLockedWhenFinished = false, bool lockPlayer = true, bool result = false, bool skipIfSamePath = false, float startTimeAdvance = 0); void SendEndCinematic(LWOOBJID objectID, std::u16string pathName, const SystemAddress& sysAddr = UNASSIGNED_SYSTEM_ADDRESS, @@ -574,6 +576,8 @@ namespace GameMessages { void HandleToggleGhostReferenceOverride(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr); void HandleSetGhostReferencePosition(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr); + void SendSetNamebillboardState(const SystemAddress& sysAddr, LWOOBJID objectId); + void SendShowBillboardInteractIcon(const SystemAddress& sysAddr, LWOOBJID objectId); void HandleBuyFromVendor(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr); void HandleSellToVendor(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr); void HandleBuybackFromVendor(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr); @@ -621,7 +625,7 @@ namespace GameMessages { void HandleReportBug(RakNet::BitStream* inStream, Entity* entity); void SendRemoveBuff(Entity* entity, bool fromUnEquip, bool removeImmunity, uint32_t buffId); - + // bubble void HandleDeactivateBubbleBuff(RakNet::BitStream* inStream, Entity* entity); @@ -630,6 +634,8 @@ namespace GameMessages { void SendActivateBubbleBuffFromServer(LWOOBJID objectId, const SystemAddress& sysAddr); void SendDeactivateBubbleBuffFromServer(LWOOBJID objectId, const SystemAddress& sysAddr); + + void HandleZoneSummaryDismissed(RakNet::BitStream* inStream, Entity* entity); }; #endif // GAMEMESSAGES_H diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index d426ac12..e4edaa4a 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -75,6 +75,7 @@ #include "eMissionState.h" #include "TriggerComponent.h" #include "eServerDisconnectIdentifiers.h" +#include "eGameMasterLevel.h" #include "eReplicaComponentType.h" #include "RenderComponent.h" @@ -122,19 +123,20 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit //Game::logger->Log("SlashCommandHandler", "Received chat command \"%s\"", GeneralUtils::UTF16ToWTF8(command).c_str()); User* user = UserManager::Instance()->GetUser(sysAddr); - if ((chatCommand == "setgmlevel" || chatCommand == "makegm" || chatCommand == "gmlevel") && user->GetMaxGMLevel() > GAME_MASTER_LEVEL_CIVILIAN) { + if ((chatCommand == "setgmlevel" || chatCommand == "makegm" || chatCommand == "gmlevel") && user->GetMaxGMLevel() > eGameMasterLevel::CIVILIAN) { if (args.size() != 1) return; - uint32_t level; + uint32_t level_intermed = 0; - if (!GeneralUtils::TryParse(args[0], level)) { + if (!GeneralUtils::TryParse(args[0], level_intermed)) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid gm level."); return; } + eGameMasterLevel level = static_cast(level_intermed); #ifndef DEVELOPER_SERVER - if (user->GetMaxGMLevel() == GAME_MASTER_LEVEL_JUNIOR_DEVELOPER) { - level = GAME_MASTER_LEVEL_CIVILIAN; + if (user->GetMaxGMLevel() == eGameMasterLevel::JUNIOR_DEVELOPER) { + level = eGameMasterLevel::CIVILIAN; } #endif @@ -147,9 +149,9 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if (success) { - if (entity->GetGMLevel() > GAME_MASTER_LEVEL_CIVILIAN && level == GAME_MASTER_LEVEL_CIVILIAN) { + if (entity->GetGMLevel() > eGameMasterLevel::CIVILIAN && level == eGameMasterLevel::CIVILIAN) { GameMessages::SendToggleGMInvis(entity->GetObjectID(), false, UNASSIGNED_SYSTEM_ADDRESS); - } else if (entity->GetGMLevel() == GAME_MASTER_LEVEL_CIVILIAN && level > GAME_MASTER_LEVEL_CIVILIAN) { + } else if (entity->GetGMLevel() == eGameMasterLevel::CIVILIAN && level > eGameMasterLevel::CIVILIAN) { GameMessages::SendToggleGMInvis(entity->GetObjectID(), true, UNASSIGNED_SYSTEM_ADDRESS); } @@ -161,10 +163,10 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } #ifndef DEVELOPER_SERVER - if ((entity->GetGMLevel() > user->GetMaxGMLevel()) || (entity->GetGMLevel() > GAME_MASTER_LEVEL_CIVILIAN && user->GetMaxGMLevel() == GAME_MASTER_LEVEL_JUNIOR_DEVELOPER)) { - WorldPackets::SendGMLevelChange(sysAddr, true, user->GetMaxGMLevel(), entity->GetGMLevel(), GAME_MASTER_LEVEL_CIVILIAN); - GameMessages::SendChatModeUpdate(entity->GetObjectID(), GAME_MASTER_LEVEL_CIVILIAN); - entity->SetGMLevel(GAME_MASTER_LEVEL_CIVILIAN); + if ((entity->GetGMLevel() > user->GetMaxGMLevel()) || (entity->GetGMLevel() > eGameMasterLevel::CIVILIAN && user->GetMaxGMLevel() == eGameMasterLevel::JUNIOR_DEVELOPER)) { + WorldPackets::SendGMLevelChange(sysAddr, true, user->GetMaxGMLevel(), entity->GetGMLevel(), eGameMasterLevel::CIVILIAN); + GameMessages::SendChatModeUpdate(entity->GetObjectID(), eGameMasterLevel::CIVILIAN); + entity->SetGMLevel(eGameMasterLevel::CIVILIAN); GameMessages::SendToggleGMInvis(entity->GetObjectID(), false, UNASSIGNED_SYSTEM_ADDRESS); @@ -172,6 +174,19 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } #endif + if (chatCommand == "togglenameplate" && (Game::config->GetValue("allownameplateoff") == "1" || entity->GetGMLevel() > eGameMasterLevel::DEVELOPER)) { + auto* character = entity->GetCharacter(); + + if (character && character->GetBillboardVisible()) { + character->SetBillboardVisible(false); + ChatPackets::SendSystemMessage(sysAddr, u"Your nameplate has been turned off and is not visible to players currently in this zone."); + } else { + character->SetBillboardVisible(true); + ChatPackets::SendSystemMessage(sysAddr, u"Your nameplate is now on and visible to all players."); + } + return; + } + //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //HANDLE ALL NON GM SLASH COMMANDS RIGHT HERE! //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! @@ -337,7 +352,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit }); } - if (user->GetMaxGMLevel() == 0 || entity->GetGMLevel() >= 0) { + if (user->GetMaxGMLevel() == eGameMasterLevel::CIVILIAN || entity->GetGMLevel() >= eGameMasterLevel::CIVILIAN) { if (chatCommand == "die") { entity->Smash(entity->GetObjectID()); } @@ -363,7 +378,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit ChatPackets::SendSystemMessage(sysAddr, u"Map: " + (GeneralUtils::to_u16string(zoneId.GetMapID())) + u"\nClone: " + (GeneralUtils::to_u16string(zoneId.GetCloneID())) + u"\nInstance: " + (GeneralUtils::to_u16string(zoneId.GetInstanceID()))); } - if (entity->GetGMLevel() == 0) return; + if (entity->GetGMLevel() == eGameMasterLevel::CIVILIAN) return; } // Log command to database @@ -373,7 +388,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit stmt->execute(); delete stmt; - if (chatCommand == "setminifig" && args.size() == 2 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_FORUM_MODERATOR) { // could break characters so only allow if GM > 0 + if (chatCommand == "setminifig" && args.size() == 2 && entity->GetGMLevel() >= eGameMasterLevel::FORUM_MODERATOR) { // could break characters so only allow if GM > 0 int32_t minifigItemId; if (!GeneralUtils::TryParse(args[1], minifigItemId)) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid Minifig Item Id ID."); @@ -417,7 +432,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit GameMessages::SendToggleGMInvis(entity->GetObjectID(), false, UNASSIGNED_SYSTEM_ADDRESS); // need to retoggle because it gets reenabled on creation of new character } - if ((chatCommand == "playanimation" || chatCommand == "playanim") && args.size() == 1 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if ((chatCommand == "playanimation" || chatCommand == "playanim") && args.size() == 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { std::u16string anim = GeneralUtils::ASCIIToUTF16(args[0], args[0].size()); RenderComponent::PlayAnimation(entity, anim); auto* possessorComponent = entity->GetComponent(); @@ -427,7 +442,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } } - if (chatCommand == "list-spawns" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "list-spawns" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { for (const auto& pair : EntityManager::Instance()->GetSpawnPointEntities()) { ChatPackets::SendSystemMessage(sysAddr, GeneralUtils::ASCIIToUTF16(pair.first)); } @@ -437,7 +452,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "unlock-emote" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "unlock-emote" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { int32_t emoteID; if (!GeneralUtils::TryParse(args[0], emoteID)) { @@ -448,11 +463,11 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit entity->GetCharacter()->UnlockEmote(emoteID); } - if (chatCommand == "force-save" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "force-save" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { entity->GetCharacter()->SaveXMLToDatabase(); } - if (chatCommand == "kill" && args.size() == 1 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "kill" && args.size() == 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { ChatPackets::SendSystemMessage(sysAddr, u"Brutally murdering that player, if online on this server."); auto* user = UserManager::Instance()->GetUser(args[0]); @@ -467,7 +482,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "speedboost" && args.size() == 1 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "speedboost" && args.size() == 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { float boost; if (!GeneralUtils::TryParse(args[0], boost)) { @@ -498,7 +513,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit EntityManager::Instance()->SerializeEntity(entity); } - if (chatCommand == "freecam" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "freecam" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { const auto state = !entity->GetVar(u"freecam"); entity->SetVar(u"freecam", state); @@ -508,7 +523,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "setcontrolscheme" && args.size() == 1 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "setcontrolscheme" && args.size() == 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { uint32_t scheme; if (!GeneralUtils::TryParse(args[0], scheme)) { @@ -522,7 +537,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "approveproperty" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_LEAD_MODERATOR) { + if (chatCommand == "approveproperty" && entity->GetGMLevel() >= eGameMasterLevel::LEAD_MODERATOR) { if (PropertyManagementComponent::Instance() != nullptr) { PropertyManagementComponent::Instance()->UpdateApprovedStatus(true); @@ -531,7 +546,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "setuistate" && args.size() == 1 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "setuistate" && args.size() == 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { AMFStringValue* value = new AMFStringValue(); value->SetStringValue(args[0]); @@ -544,7 +559,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "toggle" && args.size() == 1 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "toggle" && args.size() == 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { AMFTrueValue* value = new AMFTrueValue(); AMFArrayValue amfArgs; @@ -556,7 +571,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if ((chatCommand == "setinventorysize" || chatCommand == "setinvsize") && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 1) { + if ((chatCommand == "setinventorysize" || chatCommand == "setinvsize") && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 1) { uint32_t size; if (!GeneralUtils::TryParse(args.at(0), size)) { @@ -597,7 +612,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "runmacro" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "runmacro" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { if (args.size() != 1) return; // Only process if input does not contain separator charaters @@ -627,7 +642,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "addmission" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "addmission" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { if (args.size() == 0) return; uint32_t missionID; @@ -642,7 +657,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "completemission" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "completemission" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { if (args.size() == 0) return; uint32_t missionID; @@ -657,7 +672,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "setflag" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() == 1) { + if (chatCommand == "setflag" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() == 1) { uint32_t flagId; if (!GeneralUtils::TryParse(args[0], flagId)) { @@ -668,7 +683,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit entity->GetCharacter()->SetPlayerFlag(flagId, true); } - if (chatCommand == "setflag" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() == 2) { + if (chatCommand == "setflag" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() == 2) { uint32_t flagId; std::string onOffFlag = args[0]; if (!GeneralUtils::TryParse(args[1], flagId)) { @@ -681,7 +696,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } entity->GetCharacter()->SetPlayerFlag(flagId, onOffFlag == "on"); } - if (chatCommand == "clearflag" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() == 1) { + if (chatCommand == "clearflag" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() == 1) { uint32_t flagId; if (!GeneralUtils::TryParse(args[0], flagId)) { @@ -692,7 +707,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit entity->GetCharacter()->SetPlayerFlag(flagId, false); } - if (chatCommand == "resetmission" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "resetmission" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { if (args.size() == 0) return; uint32_t missionID; @@ -719,7 +734,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "playeffect" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 3) { + if (chatCommand == "playeffect" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 3) { int32_t effectID = 0; if (!GeneralUtils::TryParse(args[0], effectID)) { @@ -730,11 +745,11 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit GameMessages::SendPlayFXEffect(entity->GetObjectID(), effectID, GeneralUtils::ASCIIToUTF16(args[1]), args[2]); } - if (chatCommand == "stopeffect" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 1) { + if (chatCommand == "stopeffect" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 1) { GameMessages::SendStopFXEffect(entity, true, args[0]); } - if (chatCommand == "setanntitle" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "setanntitle" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { if (args.size() < 0) return; std::stringstream ss; @@ -745,7 +760,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "setannmsg" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "setannmsg" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { if (args.size() < 0) return; std::stringstream ss; @@ -756,7 +771,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "announce" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "announce" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { if (entity->GetCharacter()->GetAnnouncementTitle().size() == 0 || entity->GetCharacter()->GetAnnouncementMessage().size() == 0) { ChatPackets::SendSystemMessage(sysAddr, u"Use /setanntitle & /setannmsg <msg> first!"); return; @@ -766,7 +781,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "shutdownuniverse" && entity->GetGMLevel() == GAME_MASTER_LEVEL_OPERATOR) { + if (chatCommand == "shutdownuniverse" && entity->GetGMLevel() == eGameMasterLevel::OPERATOR) { //Tell the master server that we're going to be shutting down whole "universe": CBITSTREAM; PacketUtils::WriteHeader(bitStream, MASTER, MSG_MASTER_SHUTDOWN_UNIVERSE); @@ -778,7 +793,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "getnavmeshheight" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "getnavmeshheight" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { auto control = static_cast<ControllablePhysicsComponent*>(entity->GetComponent(eReplicaComponentType::CONTROLLABLE_PHYSICS)); if (!control) return; @@ -787,7 +802,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit ChatPackets::SendSystemMessage(sysAddr, msg); } - if (chatCommand == "gmadditem" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "gmadditem" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { if (args.size() == 1) { uint32_t itemLOT; @@ -822,7 +837,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } } - if (chatCommand == "mailitem" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_MODERATOR && args.size() >= 2) { + if (chatCommand == "mailitem" && entity->GetGMLevel() >= eGameMasterLevel::MODERATOR && args.size() >= 2) { const auto& playerName = args[0]; sql::PreparedStatement* stmt = Database::CreatePreppedStmt("SELECT id from charinfo WHERE name=? LIMIT 1;"); @@ -871,7 +886,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "setname" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "setname" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { std::string name = ""; for (const auto& arg : args) { @@ -881,7 +896,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit GameMessages::SendSetName(entity->GetObjectID(), GeneralUtils::UTF8ToUTF16(name), UNASSIGNED_SYSTEM_ADDRESS); } - if (chatCommand == "title" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "title" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { std::string name = entity->GetCharacter()->GetName() + " - "; for (const auto& arg : args) { @@ -891,7 +906,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit GameMessages::SendSetName(entity->GetObjectID(), GeneralUtils::UTF8ToUTF16(name), UNASSIGNED_SYSTEM_ADDRESS); } - if ((chatCommand == "teleport" || chatCommand == "tele") && entity->GetGMLevel() >= GAME_MASTER_LEVEL_JUNIOR_MODERATOR) { + if ((chatCommand == "teleport" || chatCommand == "tele") && entity->GetGMLevel() >= eGameMasterLevel::JUNIOR_MODERATOR) { NiPoint3 pos{}; if (args.size() == 3) { @@ -957,7 +972,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } } - if (chatCommand == "tpall" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "tpall" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { const auto pos = entity->GetPosition(); const auto characters = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::CHARACTER); @@ -969,7 +984,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "dismount" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "dismount" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { auto* possessorComponent = entity->GetComponent<PossessorComponent>(); if (possessorComponent) { auto possessableId = possessorComponent->GetPossessable(); @@ -980,7 +995,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } } - if (chatCommand == "fly" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_JUNIOR_DEVELOPER) { + if (chatCommand == "fly" && entity->GetGMLevel() >= eGameMasterLevel::JUNIOR_DEVELOPER) { auto* character = entity->GetCharacter(); if (character) { @@ -1016,7 +1031,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit //------- GM COMMANDS TO ACTUALLY MODERATE -------- - if (chatCommand == "mute" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_JUNIOR_DEVELOPER) { + if (chatCommand == "mute" && entity->GetGMLevel() >= eGameMasterLevel::JUNIOR_DEVELOPER) { if (args.size() >= 1) { auto* player = Player::GetPlayer(args[0]); @@ -1111,7 +1126,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } } - if (chatCommand == "kick" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_JUNIOR_MODERATOR) { + if (chatCommand == "kick" && entity->GetGMLevel() >= eGameMasterLevel::JUNIOR_MODERATOR) { if (args.size() == 1) { auto* player = Player::GetPlayer(args[0]); @@ -1129,7 +1144,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } } - if (chatCommand == "ban" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_SENIOR_MODERATOR) { + if (chatCommand == "ban" && entity->GetGMLevel() >= eGameMasterLevel::SENIOR_MODERATOR) { if (args.size() == 1) { auto* player = Player::GetPlayer(args[0]); @@ -1178,7 +1193,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit //------------------------------------------------- - if (chatCommand == "buffme" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "buffme" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { auto dest = static_cast<DestroyableComponent*>(entity->GetComponent(eReplicaComponentType::DESTROYABLE)); if (dest) { dest->SetHealth(999); @@ -1191,7 +1206,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit EntityManager::Instance()->SerializeEntity(entity); } - if (chatCommand == "startcelebration" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() == 1) { + if (chatCommand == "startcelebration" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() == 1) { int32_t celebration; if (!GeneralUtils::TryParse(args[0], celebration)) { @@ -1202,7 +1217,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit GameMessages::SendStartCelebrationEffect(entity, entity->GetSystemAddress(), celebration); } - if (chatCommand == "buffmed" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "buffmed" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { auto dest = static_cast<DestroyableComponent*>(entity->GetComponent(eReplicaComponentType::DESTROYABLE)); if (dest) { dest->SetHealth(9); @@ -1215,7 +1230,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit EntityManager::Instance()->SerializeEntity(entity); } - if (chatCommand == "refillstats" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "refillstats" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { auto dest = static_cast<DestroyableComponent*>(entity->GetComponent(eReplicaComponentType::DESTROYABLE)); if (dest) { @@ -1227,7 +1242,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit EntityManager::Instance()->SerializeEntity(entity); } - if (chatCommand == "lookup" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 1) { + if (chatCommand == "lookup" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 1) { auto query = CDClientDatabase::CreatePreppedStmt( "SELECT `id`, `name` FROM `Objects` WHERE `displayName` LIKE ?1 OR `name` LIKE ?1 OR `description` LIKE ?1 LIMIT 50"); // Concatenate all of the arguments into a single query so a multi word query can be used properly. @@ -1249,7 +1264,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } } - if (chatCommand == "spawn" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 1) { + if (chatCommand == "spawn" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 1) { ControllablePhysicsComponent* comp = static_cast<ControllablePhysicsComponent*>(entity->GetComponent(eReplicaComponentType::CONTROLLABLE_PHYSICS)); if (!comp) return; @@ -1290,7 +1305,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit EntityManager::Instance()->ConstructEntity(newEntity); } - if (chatCommand == "spawngroup" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 3) { + if (chatCommand == "spawngroup" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 3) { auto controllablePhysicsComponent = entity->GetComponent<ControllablePhysicsComponent>(); if (!controllablePhysicsComponent) return; @@ -1341,7 +1356,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } } - if ((chatCommand == "giveuscore") && args.size() >= 1 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if ((chatCommand == "giveuscore") && args.size() >= 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { int32_t uscore; if (!GeneralUtils::TryParse(args[0], uscore)) { @@ -1363,7 +1378,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit GameMessages::SendModifyLEGOScore(entity, entity->GetSystemAddress(), uscore, lootType); } - if ((chatCommand == "setlevel") && args.size() >= 1 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if ((chatCommand == "setlevel") && args.size() >= 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { // We may be trying to set a specific players level to a level. If so override the entity with the requested players. std::string requestedPlayerToSetLevelOf = ""; if (args.size() > 1) { @@ -1431,7 +1446,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "pos" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "pos" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { const auto position = entity->GetPosition(); ChatPackets::SendSystemMessage(sysAddr, u"<" + (GeneralUtils::to_u16string(position.x)) + u", " + (GeneralUtils::to_u16string(position.y)) + u", " + (GeneralUtils::to_u16string(position.z)) + u">"); @@ -1439,7 +1454,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit std::cout << position.x << ", " << position.y << ", " << position.z << std::endl; } - if (chatCommand == "rot" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "rot" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { const auto rotation = entity->GetRotation(); ChatPackets::SendSystemMessage(sysAddr, u"<" + (GeneralUtils::to_u16string(rotation.w)) + u", " + (GeneralUtils::to_u16string(rotation.x)) + u", " + (GeneralUtils::to_u16string(rotation.y)) + u", " + (GeneralUtils::to_u16string(rotation.z)) + u">"); @@ -1447,22 +1462,22 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit std::cout << rotation.w << ", " << rotation.x << ", " << rotation.y << ", " << rotation.z << std::endl; } - if (chatCommand == "locrow" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "locrow" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { const auto position = entity->GetPosition(); const auto rotation = entity->GetRotation(); std::cout << "<location x=\"" << position.x << "\" y=\"" << position.y << "\" z=\"" << position.z << "\" rw=\"" << rotation.w << "\" rx=\"" << rotation.x << "\" ry=\"" << rotation.y << "\" rz=\"" << rotation.z << "\" />" << std::endl; } - if (chatCommand == "playlvlfx" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "playlvlfx" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { GameMessages::SendPlayFXEffect(entity, 7074, u"create", "7074", LWOOBJID_EMPTY, 1.0f, 1.0f, true); } - if (chatCommand == "playrebuildfx" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "playrebuildfx" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { GameMessages::SendPlayFXEffect(entity, 230, u"rebuild", "230", LWOOBJID_EMPTY, 1.0f, 1.0f, true); } - if ((chatCommand == "freemoney" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) && args.size() == 1) { + if ((chatCommand == "freemoney" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) && args.size() == 1) { int32_t money; if (!GeneralUtils::TryParse(args[0], money)) { @@ -1474,7 +1489,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit ch->SetCoins(ch->GetCoins() + money, eLootSourceType::LOOT_SOURCE_MODERATION); } - if ((chatCommand == "setcurrency") && args.size() == 1 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if ((chatCommand == "setcurrency") && args.size() == 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { int32_t money; if (!GeneralUtils::TryParse(args[0], money)) { @@ -1487,13 +1502,13 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } // Allow for this on even while not a GM, as it sometimes toggles incorrrectly. - if (chatCommand == "gminvis" && entity->GetParentUser()->GetMaxGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "gminvis" && entity->GetParentUser()->GetMaxGMLevel() >= eGameMasterLevel::DEVELOPER) { GameMessages::SendToggleGMInvis(entity->GetObjectID(), true, UNASSIGNED_SYSTEM_ADDRESS); return; } - if (chatCommand == "gmimmune" && args.size() >= 1 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "gmimmune" && args.size() >= 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { auto* destroyableComponent = entity->GetComponent<DestroyableComponent>(); int32_t state = false; @@ -1510,7 +1525,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "buff" && args.size() >= 2 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "buff" && args.size() >= 2 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { auto* buffComponent = entity->GetComponent<BuffComponent>(); int32_t id = 0; @@ -1533,7 +1548,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if ((chatCommand == "testmap" && args.size() >= 1) && entity->GetGMLevel() >= GAME_MASTER_LEVEL_FORUM_MODERATOR) { + if ((chatCommand == "testmap" && args.size() >= 1) && entity->GetGMLevel() >= eGameMasterLevel::FORUM_MODERATOR) { ChatPackets::SendSystemMessage(sysAddr, u"Requesting map change..."); uint32_t reqZone; LWOCLONEID cloneId = 0; @@ -1592,7 +1607,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } } - if (chatCommand == "createprivate" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 3) { + if (chatCommand == "createprivate" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 3) { uint32_t zone; if (!GeneralUtils::TryParse(args[0], zone)) { @@ -1616,13 +1631,13 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if ((chatCommand == "debugui") && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if ((chatCommand == "debugui") && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { ChatPackets::SendSystemMessage(sysAddr, u"Opening UIDebugger..."); AMFArrayValue args; GameMessages::SendUIMessageServerToSingleClient(entity, sysAddr, "ToggleUIDebugger;", nullptr); } - if ((chatCommand == "boost") && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if ((chatCommand == "boost") && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { auto* possessorComponent = entity->GetComponent<PossessorComponent>(); if (possessorComponent == nullptr) { @@ -1654,7 +1669,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } - if ((chatCommand == "unboost") && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if ((chatCommand == "unboost") && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { auto* possessorComponent = entity->GetComponent<PossessorComponent>(); if (possessorComponent == nullptr) return; @@ -1664,7 +1679,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit GameMessages::SendVehicleRemovePassiveBoostAction(vehicle->GetObjectID(), UNASSIGNED_SYSTEM_ADDRESS); } - if (chatCommand == "activatespawner" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 1) { + if (chatCommand == "activatespawner" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 1) { auto spawners = dZoneManager::Instance()->GetSpawnersByName(args[0]); for (auto* spawner : spawners) { @@ -1678,7 +1693,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } } - if (chatCommand == "spawnphysicsverts" && entity->GetGMLevel() >= 6) { + if (chatCommand == "spawnphysicsverts" && entity->GetGMLevel() >= eGameMasterLevel::JUNIOR_DEVELOPER) { //Go tell physics to spawn all the vertices: auto entities = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::PHANTOM_PHYSICS); for (auto en : entities) { @@ -1688,7 +1703,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } } - if (chatCommand == "reportproxphys" && entity->GetGMLevel() >= 6) { + if (chatCommand == "reportproxphys" && entity->GetGMLevel() >= eGameMasterLevel::JUNIOR_DEVELOPER) { auto entities = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::PROXIMITY_MONITOR); for (auto en : entities) { auto phys = static_cast<ProximityMonitorComponent*>(en->GetComponent(eReplicaComponentType::PROXIMITY_MONITOR)); @@ -1704,7 +1719,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } } - if (chatCommand == "triggerspawner" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 1) { + if (chatCommand == "triggerspawner" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 1) { auto spawners = dZoneManager::Instance()->GetSpawnersByName(args[0]); for (auto* spawner : spawners) { @@ -1718,7 +1733,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } } - if (chatCommand == "reforge" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 2) { + if (chatCommand == "reforge" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 2) { LOT baseItem; LOT reforgedItem; @@ -1735,7 +1750,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit inventoryComponent->AddItem(baseItem, 1, eLootSourceType::LOOT_SOURCE_MODERATION, eInventoryType::INVALID, data); } - if (chatCommand == "crash" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_OPERATOR) { + if (chatCommand == "crash" && entity->GetGMLevel() >= eGameMasterLevel::OPERATOR) { ChatPackets::SendSystemMessage(sysAddr, u"Crashing..."); int* badPtr = nullptr; @@ -1744,7 +1759,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "metrics" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "metrics" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { for (const auto variable : Metrics::GetAllMetrics()) { auto* metric = Metrics::GetMetric(variable); @@ -1781,7 +1796,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if (chatCommand == "reloadconfig" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "reloadconfig" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { Game::config->ReloadConfig(); VanityUtilities::SpawnVanity(); dpWorld::Instance().Reload(); @@ -1797,7 +1812,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit ChatPackets::SendSystemMessage(sysAddr, u"Successfully reloaded config for world!"); } - if (chatCommand == "rollloot" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_OPERATOR && args.size() >= 3) { + if (chatCommand == "rollloot" && entity->GetGMLevel() >= eGameMasterLevel::OPERATOR && args.size() >= 3) { uint32_t lootMatrixIndex = 0; uint32_t targetLot = 0; uint32_t loops = 1; @@ -1834,7 +1849,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit ChatPackets::SendSystemMessage(sysAddr, message); } - if (chatCommand == "deleteinven" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 1) { + if (chatCommand == "deleteinven" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 1) { eInventoryType inventoryType = eInventoryType::INVALID; if (!GeneralUtils::TryParse(args[0], inventoryType)) { // In this case, we treat the input as a string and try to find it in the reflection list @@ -1861,7 +1876,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit ChatPackets::SendSystemMessage(sysAddr, u"Deleted inventory " + GeneralUtils::UTF8ToUTF16(args[0])); } - if (chatCommand == "inspect" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 1) { + if (chatCommand == "inspect" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 1) { Entity* closest = nullptr; eReplicaComponentType component; @@ -2004,7 +2019,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit auto* phantomPhysicsComponent = closest->GetComponent<PhantomPhysicsComponent>(); if (phantomPhysicsComponent != nullptr) { - ChatPackets::SendSystemMessage(sysAddr, u"Type: " + (GeneralUtils::to_u16string(phantomPhysicsComponent->GetEffectType()))); + ChatPackets::SendSystemMessage(sysAddr, u"Type: " + (GeneralUtils::to_u16string(static_cast<uint32_t>(phantomPhysicsComponent->GetEffectType())))); const auto dir = phantomPhysicsComponent->GetDirection(); ChatPackets::SendSystemMessage(sysAddr, u"Direction: <" + (GeneralUtils::to_u16string(dir.x)) + u", " + (GeneralUtils::to_u16string(dir.y)) + u", " + (GeneralUtils::to_u16string(dir.z)) + u">"); ChatPackets::SendSystemMessage(sysAddr, u"Multiplier: " + (GeneralUtils::to_u16string(phantomPhysicsComponent->GetDirectionalMultiplier()))); diff --git a/dNet/ClientPackets.cpp b/dNet/ClientPackets.cpp index 100efac5..a1c08938 100644 --- a/dNet/ClientPackets.cpp +++ b/dNet/ClientPackets.cpp @@ -32,6 +32,7 @@ #include "CharacterComponent.h" #include "Database.h" #include "dMessageIdentifiers.h" +#include "eGameMasterLevel.h" #include "eReplicaComponentType.h" void ClientPackets::HandleChatMessage(const SystemAddress& sysAddr, Packet* packet) { @@ -66,7 +67,7 @@ void ClientPackets::HandleChatMessage(const SystemAddress& sysAddr, Packet* pack } std::string playerName = user->GetLastUsedChar()->GetName(); - bool isMythran = user->GetLastUsedChar()->GetGMLevel() > 0; + bool isMythran = user->GetLastUsedChar()->GetGMLevel() > eGameMasterLevel::CIVILIAN; if (!user->GetLastChatMessageApproved() && !isMythran) return; diff --git a/dNet/WorldPackets.cpp b/dNet/WorldPackets.cpp index f6a8f558..febb6bc1 100644 --- a/dNet/WorldPackets.cpp +++ b/dNet/WorldPackets.cpp @@ -15,6 +15,7 @@ #include "CharacterComponent.h" #include "ZCompression.h" + void WorldPackets::SendLoadStaticZone(const SystemAddress& sysAddr, float x, float y, float z, uint32_t checksum) { RakNet::BitStream bitStream; PacketUtils::WriteHeader(bitStream, CLIENT, MSG_CLIENT_LOAD_STATIC_ZONE); @@ -127,7 +128,7 @@ void WorldPackets::SendServerState(const SystemAddress& sysAddr) { SEND_PACKET; } -void WorldPackets::SendCreateCharacter(const SystemAddress& sysAddr, Entity* entity, const std::string& xmlData, const std::u16string& username, int32_t gm) { +void WorldPackets::SendCreateCharacter(const SystemAddress& sysAddr, Entity* entity, const std::string& xmlData, const std::u16string& username, eGameMasterLevel gm) { RakNet::BitStream bitStream; PacketUtils::WriteHeader(bitStream, CLIENT, MSG_CLIENT_CREATE_CHARACTER); @@ -144,8 +145,8 @@ void WorldPackets::SendCreateCharacter(const SystemAddress& sysAddr, Entity* ent LDFData<LOT>* lot = new LDFData<LOT>(u"template", 1); LDFData<std::string>* xmlConfigData = new LDFData<std::string>(u"xmlData", xmlData); LDFData<std::u16string>* name = new LDFData<std::u16string>(u"name", username); - LDFData<int32_t>* gmlevel = new LDFData<int32_t>(u"gmlevel", gm); - LDFData<int32_t>* chatmode = new LDFData<int32_t>(u"chatmode", gm); + LDFData<int32_t>* gmlevel = new LDFData<int32_t>(u"gmlevel", static_cast<int32_t>(gm)); + LDFData<int32_t>* chatmode = new LDFData<int32_t>(u"chatmode", static_cast<int32_t>(gm)); LDFData<int64_t>* reputation = new LDFData<int64_t>(u"reputation", character->GetReputation()); objid->WriteToPacket(&data); @@ -220,14 +221,14 @@ void WorldPackets::SendChatModerationResponse(const SystemAddress& sysAddr, bool SEND_PACKET; } -void WorldPackets::SendGMLevelChange(const SystemAddress& sysAddr, bool success, uint8_t highestLevel, uint8_t prevLevel, uint8_t newLevel) { +void WorldPackets::SendGMLevelChange(const SystemAddress& sysAddr, bool success, eGameMasterLevel highestLevel, eGameMasterLevel prevLevel, eGameMasterLevel newLevel) { CBITSTREAM; PacketUtils::WriteHeader(bitStream, CLIENT, MSG_CLIENT_MAKE_GM_RESPONSE); bitStream.Write<uint8_t>(success); - bitStream.Write<uint16_t>(highestLevel); - bitStream.Write<uint16_t>(prevLevel); - bitStream.Write<uint16_t>(newLevel); + bitStream.Write(static_cast<uint16_t>(highestLevel)); + bitStream.Write(static_cast<uint16_t>(prevLevel)); + bitStream.Write(static_cast<uint16_t>(newLevel)); SEND_PACKET; } diff --git a/dNet/WorldPackets.h b/dNet/WorldPackets.h index d9951941..ec20ac22 100644 --- a/dNet/WorldPackets.h +++ b/dNet/WorldPackets.h @@ -8,6 +8,7 @@ class User; struct SystemAddress; +enum class eGameMasterLevel : uint8_t; namespace WorldPackets { void SendLoadStaticZone(const SystemAddress& sysAddr, float x, float y, float z, uint32_t checksum); @@ -17,9 +18,9 @@ namespace WorldPackets { void SendCharacterDeleteResponse(const SystemAddress& sysAddr, bool response); void SendTransferToWorld(const SystemAddress& sysAddr, const std::string& serverIP, uint32_t serverPort, bool mythranShift); void SendServerState(const SystemAddress& sysAddr); - void SendCreateCharacter(const SystemAddress& sysAddr, Entity* entity, const std::string& xmlData, const std::u16string& username, int32_t gm); + void SendCreateCharacter(const SystemAddress& sysAddr, Entity* entity, const std::string& xmlData, const std::u16string& username, eGameMasterLevel gm); void SendChatModerationResponse(const SystemAddress& sysAddr, bool requestAccepted, uint32_t requestID, const std::string& receiver, std::vector<std::pair<uint8_t, uint8_t>> unacceptedItems); - void SendGMLevelChange(const SystemAddress& sysAddr, bool success, uint8_t highestLevel, uint8_t prevLevel, uint8_t newLevel); + void SendGMLevelChange(const SystemAddress& sysAddr, bool success, eGameMasterLevel highestLevel, eGameMasterLevel prevLevel, eGameMasterLevel newLevel); } #endif // WORLDPACKETS_H diff --git a/dScripts/02_server/Map/AG/AgLaserSensorServer.cpp b/dScripts/02_server/Map/AG/AgLaserSensorServer.cpp index c09000be..703625d2 100644 --- a/dScripts/02_server/Map/AG/AgLaserSensorServer.cpp +++ b/dScripts/02_server/Map/AG/AgLaserSensorServer.cpp @@ -5,13 +5,14 @@ #include "EntityManager.h" #include "AgMonumentLaserServer.h" #include "EntityManager.h" +#include "ePhysicsEffectType.h" #include "eReplicaComponentType.h" void AgLaserSensorServer::OnStartup(Entity* self) { PhantomPhysicsComponent* physComp = static_cast<PhantomPhysicsComponent*>(self->GetComponent(eReplicaComponentType::PHANTOM_PHYSICS)); physComp->SetPhysicsEffectActive(true); - physComp->SetEffectType(2); // repulse (prolly should make definitions of these are in Entity.cpp) + physComp->SetEffectType(ePhysicsEffectType::REPULSE); physComp->SetDirectionalMultiplier(static_cast<float>(m_RepelForce)); physComp->SetDirection(NiPoint3::UNIT_Y); diff --git a/dScripts/02_server/Map/GF/MastTeleport.cpp b/dScripts/02_server/Map/GF/MastTeleport.cpp index fd2fe96d..24d623de 100644 --- a/dScripts/02_server/Map/GF/MastTeleport.cpp +++ b/dScripts/02_server/Map/GF/MastTeleport.cpp @@ -2,6 +2,7 @@ #include "EntityManager.h" #include "GameMessages.h" #include "Preconditions.h" +#include "eEndBehavior.h" #include "DestroyableComponent.h" #ifdef _WIN32 @@ -53,7 +54,7 @@ void MastTeleport::OnTimerDone(Entity* self, std::string timerName) { if (!cinematic.empty()) { GameMessages::SendPlayCinematic(playerId, GeneralUtils::ASCIIToUTF16(cinematic), player->GetSystemAddress(), - true, true, false, false, 0, false, leanIn + true, true, false, false, eEndBehavior::RETURN, false, leanIn ); } diff --git a/dScripts/02_server/Map/General/ForceVolumeServer.cpp b/dScripts/02_server/Map/General/ForceVolumeServer.cpp index fbaad6ee..ed9024c1 100644 --- a/dScripts/02_server/Map/General/ForceVolumeServer.cpp +++ b/dScripts/02_server/Map/General/ForceVolumeServer.cpp @@ -1,6 +1,7 @@ #include "ForceVolumeServer.h" #include "PhantomPhysicsComponent.h" #include "EntityManager.h" +#include "ePhysicsEffectType.h" void ForceVolumeServer::OnStartup(Entity* self) { auto* phantomPhysicsComponent = self->GetComponent<PhantomPhysicsComponent>(); @@ -12,7 +13,7 @@ void ForceVolumeServer::OnStartup(Entity* self) { const auto forceY = self->GetVar<float>(u"ForceY"); const auto forceZ = self->GetVar<float>(u"ForceZ"); - phantomPhysicsComponent->SetEffectType(0); // PUSH + phantomPhysicsComponent->SetEffectType(ePhysicsEffectType::PUSH); phantomPhysicsComponent->SetDirectionalMultiplier(forceAmount); phantomPhysicsComponent->SetDirection({ forceX, forceY, forceZ }); phantomPhysicsComponent->SetPhysicsEffectActive(true); diff --git a/dScripts/02_server/Map/NT/NtAssemblyTubeServer.cpp b/dScripts/02_server/Map/NT/NtAssemblyTubeServer.cpp index 26da3aca..d5f33336 100644 --- a/dScripts/02_server/Map/NT/NtAssemblyTubeServer.cpp +++ b/dScripts/02_server/Map/NT/NtAssemblyTubeServer.cpp @@ -5,6 +5,7 @@ #include "eMissionTaskType.h" #include "eMissionState.h" #include "RenderComponent.h" +#include "eEndBehavior.h" void NtAssemblyTubeServer::OnStartup(Entity* self) { self->SetProximityRadius(5, "teleport"); @@ -46,7 +47,7 @@ void NtAssemblyTubeServer::RunAssemblyTube(Entity* self, Entity* player) { if (!teleCinematic.empty()) { const auto teleCinematicUname = teleCinematic; GameMessages::SendPlayCinematic(player->GetObjectID(), teleCinematicUname, player->GetSystemAddress(), - true, true, true, false, 0, false, -1, false, true + true, true, true, false, eEndBehavior::RETURN, false, -1, false, true ); } diff --git a/dScripts/02_server/Map/NT/NtSentinelWalkwayServer.cpp b/dScripts/02_server/Map/NT/NtSentinelWalkwayServer.cpp index 66bfe46f..257bf6da 100644 --- a/dScripts/02_server/Map/NT/NtSentinelWalkwayServer.cpp +++ b/dScripts/02_server/Map/NT/NtSentinelWalkwayServer.cpp @@ -3,6 +3,7 @@ #include "EntityManager.h" #include "MissionComponent.h" #include "eMissionTaskType.h" +#include "ePhysicsEffectType.h" void NtSentinelWalkwayServer::OnStartup(Entity* self) { auto* phantomPhysicsComponent = self->GetComponent<PhantomPhysicsComponent>(); @@ -19,7 +20,7 @@ void NtSentinelWalkwayServer::OnStartup(Entity* self) { const auto forward = self->GetRotation().GetRightVector() * -1; - phantomPhysicsComponent->SetEffectType(0); // PUSH + phantomPhysicsComponent->SetEffectType(ePhysicsEffectType::PUSH); phantomPhysicsComponent->SetDirectionalMultiplier(force); phantomPhysicsComponent->SetDirection(forward); phantomPhysicsComponent->SetPhysicsEffectActive(true); diff --git a/dScripts/02_server/Map/NT/NtVentureCannonServer.cpp b/dScripts/02_server/Map/NT/NtVentureCannonServer.cpp index c1f07bbd..1e7b9b3f 100644 --- a/dScripts/02_server/Map/NT/NtVentureCannonServer.cpp +++ b/dScripts/02_server/Map/NT/NtVentureCannonServer.cpp @@ -4,6 +4,7 @@ #include "Entity.h" #include "GeneralUtils.h" #include "RenderComponent.h" +#include "eEndBehavior.h" void NtVentureCannonServer::OnUse(Entity* self, Entity* user) { auto* player = user; @@ -76,7 +77,7 @@ void NtVentureCannonServer::EnterCannonEnded(Entity* self, Entity* player) { const auto exitCinematicUname = exitCinematic; GameMessages::SendPlayCinematic(player->GetObjectID(), exitCinematicUname, player->GetSystemAddress(), - true, true, true, false, 0, false, 0, false, false + true, true, true, false, eEndBehavior::RETURN, false, 0, false, false ); self->AddCallbackTimer(1.5f, [this, self, playerID]() { diff --git a/dScripts/BasePropertyServer.cpp b/dScripts/BasePropertyServer.cpp index 7552eeca..a9f35e25 100644 --- a/dScripts/BasePropertyServer.cpp +++ b/dScripts/BasePropertyServer.cpp @@ -303,18 +303,8 @@ void BasePropertyServer::ResetSpawner(const std::string& spawnerName) { void BasePropertyServer::DestroySpawner(const std::string& spawnerName) { for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(spawnerName)) { - for (auto* node : spawner->m_Info.nodes) { - for (const auto& element : node->entities) { - auto* entity = EntityManager::Instance()->GetEntity(element); - if (entity == nullptr) - continue; - - entity->Kill(); - } - - node->entities.clear(); - } - + if (!spawner) return; + spawner->DestroyAllEntities(); spawner->Deactivate(); } } diff --git a/dScripts/ai/FV/ActParadoxPipeFix.cpp b/dScripts/ai/FV/ActParadoxPipeFix.cpp index 1dddde64..517474a9 100644 --- a/dScripts/ai/FV/ActParadoxPipeFix.cpp +++ b/dScripts/ai/FV/ActParadoxPipeFix.cpp @@ -3,6 +3,7 @@ #include "RebuildComponent.h" #include "GameMessages.h" #include "MissionComponent.h" +#include "eEndBehavior.h" void ActParadoxPipeFix::OnRebuildComplete(Entity* self, Entity* target) { const auto myGroup = "AllPipes"; @@ -42,7 +43,7 @@ void ActParadoxPipeFix::OnRebuildComplete(Entity* self, Entity* target) { missionComponent->ForceProgressTaskType(769, 1, 1, false); } - GameMessages::SendPlayCinematic(player->GetObjectID(), u"ParadoxPipeFinish", player->GetSystemAddress(), true, true, false, false, 0, false, 2.0f); + GameMessages::SendPlayCinematic(player->GetObjectID(), u"ParadoxPipeFinish", player->GetSystemAddress(), true, true, false, false, eEndBehavior::RETURN, false, 2.0f); } object->SetVar(u"PlayerID", LWOOBJID_EMPTY); diff --git a/dZoneManager/Spawner.cpp b/dZoneManager/Spawner.cpp index 57b4e988..28f77fea 100644 --- a/dZoneManager/Spawner.cpp +++ b/dZoneManager/Spawner.cpp @@ -134,24 +134,23 @@ void Spawner::AddEntitySpawnedCallback(std::function<void(Entity*)> callback) { void Spawner::Reset() { m_Start = true; - - for (auto* node : m_Info.nodes) { - for (const auto& spawned : node->entities) { - auto* entity = EntityManager::Instance()->GetEntity(spawned); - - if (entity == nullptr) continue; - - entity->Kill(); - } - - node->entities.clear(); - } - + DestroyAllEntities(); m_Entities.clear(); m_AmountSpawned = 0; m_NeedsUpdate = true; } +void Spawner::DestroyAllEntities(){ + for (auto* node : m_Info.nodes) { + for (const auto& element : node->entities) { + auto* entity = EntityManager::Instance()->GetEntity(element); + if (entity == nullptr) continue; + entity->Kill(); + } + node->entities.clear(); + } +} + void Spawner::SoftReset() { m_Start = true; m_AmountSpawned = 0; diff --git a/dZoneManager/Spawner.h b/dZoneManager/Spawner.h index a42c8a65..1f610b71 100644 --- a/dZoneManager/Spawner.h +++ b/dZoneManager/Spawner.h @@ -61,6 +61,7 @@ public: void AddEntitySpawnedCallback(std::function<void(Entity*)> callback); void SetSpawnLot(LOT lot); void Reset(); + void DestroyAllEntities(); void SoftReset(); void SetRespawnTime(float time); void SetNumToMaintain(int32_t value); diff --git a/dZoneManager/dZoneManager.cpp b/dZoneManager/dZoneManager.cpp index 52008b5d..ac3a7008 100644 --- a/dZoneManager/dZoneManager.cpp +++ b/dZoneManager/dZoneManager.cpp @@ -182,17 +182,7 @@ void dZoneManager::RemoveSpawner(const LWOOBJID id) { Game::logger->Log("dZoneManager", "Failed to find spawner entity (%llu)", id); } - for (auto* node : spawner->m_Info.nodes) { - for (const auto& element : node->entities) { - auto* nodeEntity = EntityManager::Instance()->GetEntity(element); - - if (nodeEntity == nullptr) continue; - - nodeEntity->Kill(); - } - - node->entities.clear(); - } + spawner->DestroyAllEntities(); spawner->Deactivate(); diff --git a/docs/Commands.md b/docs/Commands.md index a9cd3e7c..c997c3c4 100644 --- a/docs/Commands.md +++ b/docs/Commands.md @@ -48,6 +48,7 @@ These commands are primarily for development and testing. The usage of many of t |Command|Usage|Description|Admin Level Requirement| |--- |--- |--- |--- | +|togglenameplate|`/togglenameplate`|Turns the nameplate above your head that is visible to other players off and on.|8 or if `allow_nameplate_off` is set to exactly `1` in the settings| |fix-stats|`/fix-stats`|Resets skills, buffs, and destroyables.|| |join|`/join <password>`|Joins a private zone with given password.|| |leave-zone|`/leave-zone`|If you are in an instanced zone, transfers you to the closest main world. For example, if you are in an instance of Avant Gardens Survival or the Spider Queen Battle, you are sent to Avant Gardens. If you are in the Battle of Nimbus Station, you are sent to Nimbus Station.|| @@ -127,13 +128,13 @@ There are 9 Game master levels |Level|Variable Name|Description| |--- |--- |--- | -|0|GAME_MASTER_LEVEL_CIVILIAN|Normal player| -|1|GAME_MASTER_LEVEL_FORUM_MODERATOR|Forum moderator. No permissions on live servers.| -|2|GAME_MASTER_LEVEL_JUNIOR_MODERATOR|Can kick/mute and pull chat logs| -|3|GAME_MASTER_LEVEL_MODERATOR|Can return lost items| -|4|GAME_MASTER_LEVEL_SENIOR_MODERATOR|Can ban| -|5|GAME_MASTER_LEVEL_LEAD_MODERATOR|Can approve properties| -|6|GAME_MASTER_LEVEL_JUNIOR_DEVELOPER|Junior developer & future content team. Civilan on live.| -|7|GAME_MASTER_LEVEL_INACTIVE_DEVELOPER|Inactive developer, limited permissions.| -|8|GAME_MASTER_LEVEL_DEVELOPER|Active developer, full permissions on live.| -|9|GAME_MASTER_LEVEL_OPERATOR|Can shutdown server for restarts & updates.| +|0|CIVILIAN|Normal player| +|1|FORUM_MODERATOR|Forum moderator. No permissions on live servers.| +|2|JUNIOR_MODERATOR|Can kick/mute and pull chat logs| +|3|MODERATOR|Can return lost items| +|4|SENIOR_MODERATOR|Can ban| +|5|LEAD_MODERATOR|Can approve properties| +|6|JUNIOR_DEVELOPER|Junior developer & future content team. Civilan on live.| +|7|INACTIVE_DEVELOPER|Inactive developer, limited permissions.| +|8|DEVELOPER|Active developer, full permissions on live.| +|9|OPERATOR|Can shutdown server for restarts & updates.| diff --git a/resources/worldconfig.ini b/resources/worldconfig.ini index 64b4fb40..b05614b4 100644 --- a/resources/worldconfig.ini +++ b/resources/worldconfig.ini @@ -58,3 +58,6 @@ hardcore_uscore_enemies_multiplier=2 # Percentage of u-score to lose on player death hardcore_lose_uscore_on_death_percent=10 + +# Allow civilian players the ability to turn the nameplate above their head off. Must be exactly 1 to be enabled for civilians. +allow_nameplate_off=0