diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index ab3917c1..8a81def7 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -36,22 +36,16 @@ jobs: testPreset: "ci-${{matrix.os}}" - name: artifacts uses: actions/upload-artifact@v3 - if: ${{ github.ref == 'ref/head/main' }} with: name: build-${{matrix.os}} path: | - build - !build/tests - !build/Testing - !build/CMakeFiles - !build/DartConfiguration.tcl - !build/CTestTestfile.cmake - !build/CMakeCache.txt - !build/build.ninja - !build/_deps - !build/cmake_install.cmake - !build/*.a - !build/*.lib - !build/*.dir - !build/*.vcxproj - !build/*.vcxproj.filters + build/*Server* + build/*.ini + build/*.so + build/*.dll + build/vanity/ + build/navmeshes/ + build/migrations/ + build/*.dcf + !build/*.pdb + !build/d*/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 41d4219f..8f8981ee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -97,15 +97,56 @@ make_directory(${CMAKE_BINARY_DIR}/logs) # Copy resource files on first build set(RESOURCE_FILES "sharedconfig.ini" "authconfig.ini" "chatconfig.ini" "worldconfig.ini" "masterconfig.ini" "blacklist.dcf") -foreach(resource_file ${RESOURCE_FILES}) - if (NOT EXISTS ${PROJECT_BINARY_DIR}/${resource_file}) +message(STATUS "Checking resource file integrity") +foreach (resource_file ${RESOURCE_FILES}) + set(file_size 0) + if (EXISTS ${PROJECT_BINARY_DIR}/${resource_file}) + file(SIZE ${PROJECT_BINARY_DIR}/${resource_file} file_size) + endif() + if (${file_size} EQUAL 0) configure_file( ${CMAKE_SOURCE_DIR}/resources/${resource_file} ${PROJECT_BINARY_DIR}/${resource_file} COPYONLY ) - message("Moved ${resource_file} to project binary directory") + message(STATUS "Moved " ${resource_file} " to project binary directory") + elseif (resource_file MATCHES ".ini") + message(STATUS "Checking " ${resource_file} " for missing config options") + file(READ ${PROJECT_BINARY_DIR}/${resource_file} current_file_contents) + string(REPLACE "\\\n" "" current_file_contents ${current_file_contents}) + string(REPLACE "\n" ";" current_file_contents ${current_file_contents}) + set(parsed_current_file_contents "") + # Remove comment lines so they do not interfere with the variable parsing + foreach (line ${current_file_contents}) + string(FIND ${line} "#" is_comment) + if (NOT ${is_comment} EQUAL 0) + string(APPEND parsed_current_file_contents ${line}) + endif() + endforeach() + file(READ ${CMAKE_SOURCE_DIR}/resources/${resource_file} depot_file_contents) + string(REPLACE "\\\n" "" depot_file_contents ${depot_file_contents}) + string(REPLACE "\n" ";" depot_file_contents ${depot_file_contents}) + set(line_to_add "") + foreach (line ${depot_file_contents}) + string(FIND ${line} "#" is_comment) + if (NOT ${is_comment} EQUAL 0) + string(REPLACE "=" ";" line_split ${line}) + list(GET line_split 0 variable_name) + if (NOT ${parsed_current_file_contents} MATCHES ${variable_name}) + message(STATUS "Adding missing config option " ${variable_name} " to " ${resource_file}) + set(line_to_add ${line_to_add} ${line}) + foreach (line_to_append ${line_to_add}) + file(APPEND ${PROJECT_BINARY_DIR}/${resource_file} "\n" ${line_to_append}) + endforeach() + file(APPEND ${PROJECT_BINARY_DIR}/${resource_file} "\n") + endif() + set(line_to_add "") + else() + set(line_to_add ${line_to_add} ${line}) + endif() + endforeach() endif() endforeach() +message(STATUS "Resource file integrity check complete") # Copy navmesh data on first build and extract it if (NOT EXISTS ${PROJECT_BINARY_DIR}/navmeshes/) diff --git a/CMakeVariables.txt b/CMakeVariables.txt index d3c8b36f..02173ba7 100644 --- a/CMakeVariables.txt +++ b/CMakeVariables.txt @@ -1,6 +1,6 @@ PROJECT_VERSION_MAJOR=1 -PROJECT_VERSION_MINOR=0 -PROJECT_VERSION_PATCH=4 +PROJECT_VERSION_MINOR=1 +PROJECT_VERSION_PATCH=0 # LICENSE LICENSE=AGPL-3.0 # The network version. diff --git a/README.md b/README.md index f51b5e2a..b7e2a101 100644 --- a/README.md +++ b/README.md @@ -338,7 +338,7 @@ This is a Work in Progress, but below are some quick links to documentaion for s ## Former Contributors * TheMachine * Matthew -* [Raine](https://github.com/Rainebannister) +* [Raine](https://github.com/uwainium) * Bricknave ## Special Thanks diff --git a/dAuthServer/AuthServer.cpp b/dAuthServer/AuthServer.cpp index ddec32db..38910823 100644 --- a/dAuthServer/AuthServer.cpp +++ b/dAuthServer/AuthServer.cpp @@ -29,6 +29,7 @@ namespace Game { dServer* server = nullptr; dConfig* config = nullptr; bool shouldShutdown = false; + std::mt19937 randomEngine; } dLogger* SetupLogger(); @@ -83,6 +84,8 @@ int main(int argc, char** argv) { delete res; delete stmt; + Game::randomEngine = std::mt19937(time(0)); + //It's safe to pass 'localhost' here, as the IP is only used as the external IP. uint32_t maxClients = 50; uint32_t ourPort = 1001; //LU client is hardcoded to use this for auth port, so I'm making it the default. @@ -171,6 +174,8 @@ dLogger* SetupLogger() { } void HandlePacket(Packet* packet) { + if (packet->length < 4) return; + if (packet->data[0] == ID_USER_PACKET_ENUM) { if (static_cast(packet->data[1]) == eConnectionType::SERVER) { if (static_cast(packet->data[3]) == eServerMessageType::VERSION_CONFIRM) { diff --git a/dChatServer/ChatPacketHandler.cpp b/dChatServer/ChatPacketHandler.cpp index 9b5ca761..878cc71c 100644 --- a/dChatServer/ChatPacketHandler.cpp +++ b/dChatServer/ChatPacketHandler.cpp @@ -22,10 +22,9 @@ extern PlayerContainer playerContainer; void ChatPacketHandler::HandleFriendlistRequest(Packet* packet) { //Get from the packet which player we want to do something with: - CINSTREAM; + CINSTREAM_SKIP_HEADER; LWOOBJID playerID = 0; inStream.Read(playerID); - inStream.Read(playerID); auto player = playerContainer.GetPlayerData(playerID); if (!player) return; @@ -99,10 +98,9 @@ void ChatPacketHandler::HandleFriendRequest(Packet* packet) { auto maxNumberOfBestFriendsAsString = Game::config->GetValue("max_number_of_best_friends"); // If this config option doesn't exist, default to 5 which is what live used. auto maxNumberOfBestFriends = maxNumberOfBestFriendsAsString != "" ? std::stoi(maxNumberOfBestFriendsAsString) : 5U; - CINSTREAM; + CINSTREAM_SKIP_HEADER; LWOOBJID requestorPlayerID; inStream.Read(requestorPlayerID); - inStream.Read(requestorPlayerID); uint32_t spacing{}; inStream.Read(spacing); std::string playerName = ""; @@ -247,10 +245,9 @@ void ChatPacketHandler::HandleFriendRequest(Packet* packet) { } void ChatPacketHandler::HandleFriendResponse(Packet* packet) { - CINSTREAM; + CINSTREAM_SKIP_HEADER; LWOOBJID playerID; inStream.Read(playerID); - inStream.Read(playerID); eAddFriendResponseCode clientResponseCode = static_cast(packet->data[0x14]); std::string friendName = PacketUtils::ReadString(0x15, packet, true); @@ -323,10 +320,9 @@ void ChatPacketHandler::HandleFriendResponse(Packet* packet) { } void ChatPacketHandler::HandleRemoveFriend(Packet* packet) { - CINSTREAM; + CINSTREAM_SKIP_HEADER; LWOOBJID playerID; inStream.Read(playerID); - inStream.Read(playerID); std::string friendName = PacketUtils::ReadString(0x14, packet, true); //we'll have to query the db here to find the user, since you can delete them while they're offline. @@ -381,10 +377,9 @@ void ChatPacketHandler::HandleRemoveFriend(Packet* packet) { } void ChatPacketHandler::HandleChatMessage(Packet* packet) { - CINSTREAM; + CINSTREAM_SKIP_HEADER; LWOOBJID playerID = LWOOBJID_EMPTY; inStream.Read(playerID); - inStream.Read(playerID); auto* sender = playerContainer.GetPlayerData(playerID); @@ -501,10 +496,9 @@ void ChatPacketHandler::HandlePrivateChatMessage(Packet* packet) { } void ChatPacketHandler::HandleTeamInvite(Packet* packet) { - CINSTREAM; + CINSTREAM_SKIP_HEADER; LWOOBJID playerID; inStream.Read(playerID); - inStream.Read(playerID); std::string invitedPlayer = PacketUtils::ReadString(0x14, packet, true); auto* player = playerContainer.GetPlayerData(playerID); @@ -542,10 +536,9 @@ void ChatPacketHandler::HandleTeamInvite(Packet* packet) { } void ChatPacketHandler::HandleTeamInviteResponse(Packet* packet) { - CINSTREAM; + CINSTREAM_SKIP_HEADER; LWOOBJID playerID = LWOOBJID_EMPTY; inStream.Read(playerID); - inStream.Read(playerID); uint32_t size = 0; inStream.Read(size); char declined = 0; @@ -576,10 +569,9 @@ void ChatPacketHandler::HandleTeamInviteResponse(Packet* packet) { } void ChatPacketHandler::HandleTeamLeave(Packet* packet) { - CINSTREAM; + CINSTREAM_SKIP_HEADER; LWOOBJID playerID = LWOOBJID_EMPTY; inStream.Read(playerID); - inStream.Read(playerID); uint32_t size = 0; inStream.Read(size); @@ -593,10 +585,9 @@ void ChatPacketHandler::HandleTeamLeave(Packet* packet) { } void ChatPacketHandler::HandleTeamKick(Packet* packet) { - CINSTREAM; + CINSTREAM_SKIP_HEADER; LWOOBJID playerID = LWOOBJID_EMPTY; inStream.Read(playerID); - inStream.Read(playerID); std::string kickedPlayer = PacketUtils::ReadString(0x14, packet, true); @@ -624,10 +615,9 @@ void ChatPacketHandler::HandleTeamKick(Packet* packet) { } void ChatPacketHandler::HandleTeamPromote(Packet* packet) { - CINSTREAM; + CINSTREAM_SKIP_HEADER; LWOOBJID playerID = LWOOBJID_EMPTY; inStream.Read(playerID); - inStream.Read(playerID); std::string promotedPlayer = PacketUtils::ReadString(0x14, packet, true); @@ -647,10 +637,9 @@ void ChatPacketHandler::HandleTeamPromote(Packet* packet) { } void ChatPacketHandler::HandleTeamLootOption(Packet* packet) { - CINSTREAM; + CINSTREAM_SKIP_HEADER; LWOOBJID playerID = LWOOBJID_EMPTY; inStream.Read(playerID); - inStream.Read(playerID); uint32_t size = 0; inStream.Read(size); @@ -671,10 +660,9 @@ void ChatPacketHandler::HandleTeamLootOption(Packet* packet) { } void ChatPacketHandler::HandleTeamStatusRequest(Packet* packet) { - CINSTREAM; + CINSTREAM_SKIP_HEADER; LWOOBJID playerID = LWOOBJID_EMPTY; inStream.Read(playerID); - inStream.Read(playerID); auto* team = playerContainer.GetTeam(playerID); auto* data = playerContainer.GetPlayerData(playerID); diff --git a/dChatServer/ChatServer.cpp b/dChatServer/ChatServer.cpp index 3e3ddfd3..b9fb8556 100644 --- a/dChatServer/ChatServer.cpp +++ b/dChatServer/ChatServer.cpp @@ -203,6 +203,8 @@ void HandlePacket(Packet* packet) { Game::logger->Log("ChatServer", "A server is connecting, awaiting user list."); } + if (packet->length < 4) return; // Nothing left to process. Need 4 bytes to continue. + if (static_cast(packet->data[1]) == eConnectionType::CHAT_INTERNAL) { switch (static_cast(packet->data[3])) { case eChatInternalMessageType::PLAYER_ADDED_NOTIFICATION: diff --git a/dChatServer/PlayerContainer.cpp b/dChatServer/PlayerContainer.cpp index dcc9ebb9..689ffd77 100644 --- a/dChatServer/PlayerContainer.cpp +++ b/dChatServer/PlayerContainer.cpp @@ -19,9 +19,8 @@ PlayerContainer::~PlayerContainer() { } void PlayerContainer::InsertPlayer(Packet* packet) { - CINSTREAM; + CINSTREAM_SKIP_HEADER; PlayerData* data = new PlayerData(); - inStream.SetReadOffset(inStream.GetReadOffset() + 64); inStream.Read(data->playerID); uint32_t len; @@ -52,9 +51,8 @@ void PlayerContainer::InsertPlayer(Packet* packet) { } void PlayerContainer::RemovePlayer(Packet* packet) { - CINSTREAM; + CINSTREAM_SKIP_HEADER; LWOOBJID playerID; - inStream.Read(playerID); //skip header inStream.Read(playerID); //Before they get kicked, we need to also send a message to their friends saying that they disconnected. @@ -97,9 +95,8 @@ void PlayerContainer::RemovePlayer(Packet* packet) { } void PlayerContainer::MuteUpdate(Packet* packet) { - CINSTREAM; + CINSTREAM_SKIP_HEADER; LWOOBJID playerID; - inStream.Read(playerID); //skip header inStream.Read(playerID); time_t expire = 0; inStream.Read(expire); @@ -118,9 +115,8 @@ void PlayerContainer::MuteUpdate(Packet* packet) { } void PlayerContainer::CreateTeamServer(Packet* packet) { - CINSTREAM; + CINSTREAM_SKIP_HEADER; LWOOBJID playerID; - inStream.Read(playerID); //skip header inStream.Read(playerID); size_t membersSize = 0; inStream.Read(membersSize); diff --git a/dCommon/AMFDeserialize.cpp b/dCommon/AMFDeserialize.cpp index df4a7cb6..648d1ed1 100644 --- a/dCommon/AMFDeserialize.cpp +++ b/dCommon/AMFDeserialize.cpp @@ -1,77 +1,79 @@ #include "AMFDeserialize.h" -#include "AMFFormat.h" +#include + +#include "Amf3.h" /** * AMF3 Reference document https://rtmp.veriskope.com/pdf/amf3-file-format-spec.pdf * AMF3 Deserializer written by EmosewaMC */ -AMFValue* AMFDeserialize::Read(RakNet::BitStream* inStream) { +AMFBaseValue* AMFDeserialize::Read(RakNet::BitStream* inStream) { if (!inStream) return nullptr; - AMFValue* returnValue = nullptr; + AMFBaseValue* returnValue = nullptr; // Read in the value type from the bitStream - int8_t marker; + eAmf marker; inStream->Read(marker); // Based on the typing, create the value associated with that and return the base value class switch (marker) { - case AMFValueType::AMFUndefined: { - returnValue = new AMFUndefinedValue(); + case eAmf::Undefined: { + returnValue = new AMFBaseValue(); break; } - case AMFValueType::AMFNull: { + case eAmf::Null: { returnValue = new AMFNullValue(); break; } - case AMFValueType::AMFFalse: { - returnValue = new AMFFalseValue(); + case eAmf::False: { + returnValue = new AMFBoolValue(false); break; } - case AMFValueType::AMFTrue: { - returnValue = new AMFTrueValue(); + case eAmf::True: { + returnValue = new AMFBoolValue(true); break; } - case AMFValueType::AMFInteger: { + case eAmf::Integer: { returnValue = ReadAmfInteger(inStream); break; } - case AMFValueType::AMFDouble: { + case eAmf::Double: { returnValue = ReadAmfDouble(inStream); break; } - case AMFValueType::AMFString: { + case eAmf::String: { returnValue = ReadAmfString(inStream); break; } - case AMFValueType::AMFArray: { + case eAmf::Array: { returnValue = ReadAmfArray(inStream); break; } - // TODO We do not need these values, but if someone wants to implement them - // then please do so and add the corresponding unit tests. - case AMFValueType::AMFXMLDoc: - case AMFValueType::AMFDate: - case AMFValueType::AMFObject: - case AMFValueType::AMFXML: - case AMFValueType::AMFByteArray: - case AMFValueType::AMFVectorInt: - case AMFValueType::AMFVectorUInt: - case AMFValueType::AMFVectorDouble: - case AMFValueType::AMFVectorObject: - case AMFValueType::AMFDictionary: { - throw static_cast(marker); + // These values are unimplemented in the live client and will remain unimplemented + // unless someone modifies the client to allow serializing of these values. + case eAmf::XMLDoc: + case eAmf::Date: + case eAmf::Object: + case eAmf::XML: + case eAmf::ByteArray: + case eAmf::VectorInt: + case eAmf::VectorUInt: + case eAmf::VectorDouble: + case eAmf::VectorObject: + case eAmf::Dictionary: { + throw marker; break; } default: - throw static_cast(marker); + throw std::invalid_argument("Invalid AMF3 marker" + std::to_string(static_cast(marker))); break; } return returnValue; @@ -99,7 +101,7 @@ uint32_t AMFDeserialize::ReadU29(RakNet::BitStream* inStream) { return actualNumber; } -std::string AMFDeserialize::ReadString(RakNet::BitStream* inStream) { +const std::string AMFDeserialize::ReadString(RakNet::BitStream* inStream) { auto length = ReadU29(inStream); // Check if this is a reference bool isReference = length % 2 == 1; @@ -113,48 +115,39 @@ std::string AMFDeserialize::ReadString(RakNet::BitStream* inStream) { return value; } else { // Length is a reference to a previous index - use that as the read in value - return accessedElements[length]; + return accessedElements.at(length); } } -AMFValue* AMFDeserialize::ReadAmfDouble(RakNet::BitStream* inStream) { - auto doubleValue = new AMFDoubleValue(); +AMFBaseValue* AMFDeserialize::ReadAmfDouble(RakNet::BitStream* inStream) { double value; inStream->Read(value); - doubleValue->SetDoubleValue(value); - return doubleValue; + return new AMFDoubleValue(value); } -AMFValue* AMFDeserialize::ReadAmfArray(RakNet::BitStream* inStream) { +AMFBaseValue* AMFDeserialize::ReadAmfArray(RakNet::BitStream* inStream) { auto arrayValue = new AMFArrayValue(); // Read size of dense array auto sizeOfDenseArray = (ReadU29(inStream) >> 1); - - // Then read Key'd portion + // Then read associative portion while (true) { auto key = ReadString(inStream); - // No more values when we encounter an empty string + // No more associative values when we encounter an empty string key if (key.size() == 0) break; - arrayValue->InsertValue(key, Read(inStream)); + arrayValue->Insert(key, Read(inStream)); } - // Finally read dense portion for (uint32_t i = 0; i < sizeOfDenseArray; i++) { - arrayValue->PushBackValue(Read(inStream)); + arrayValue->Insert(i, Read(inStream)); } - return arrayValue; } -AMFValue* AMFDeserialize::ReadAmfString(RakNet::BitStream* inStream) { - auto stringValue = new AMFStringValue(); - stringValue->SetStringValue(ReadString(inStream)); - return stringValue; +AMFBaseValue* AMFDeserialize::ReadAmfString(RakNet::BitStream* inStream) { + return new AMFStringValue(ReadString(inStream)); } -AMFValue* AMFDeserialize::ReadAmfInteger(RakNet::BitStream* inStream) { - auto integerValue = new AMFIntegerValue(); - integerValue->SetIntegerValue(ReadU29(inStream)); - return integerValue; +AMFBaseValue* AMFDeserialize::ReadAmfInteger(RakNet::BitStream* inStream) { + return new AMFIntValue(ReadU29(inStream)); } diff --git a/dCommon/AMFDeserialize.h b/dCommon/AMFDeserialize.h index a49cdcd2..5e2729eb 100644 --- a/dCommon/AMFDeserialize.h +++ b/dCommon/AMFDeserialize.h @@ -5,7 +5,8 @@ #include #include -class AMFValue; +class AMFBaseValue; + class AMFDeserialize { public: /** @@ -14,7 +15,7 @@ public: * @param inStream inStream to read value from. * @return Returns an AMFValue with all the information from the bitStream in it. */ - AMFValue* Read(RakNet::BitStream* inStream); + AMFBaseValue* Read(RakNet::BitStream* inStream); private: /** * @brief Private method to read a U29 integer from a bitstream @@ -30,7 +31,7 @@ private: * @param inStream bitStream to read data from * @return The read string */ - std::string ReadString(RakNet::BitStream* inStream); + const std::string ReadString(RakNet::BitStream* inStream); /** * @brief Read an AMFDouble value from a bitStream @@ -38,7 +39,7 @@ private: * @param inStream bitStream to read data from * @return Double value represented as an AMFValue */ - AMFValue* ReadAmfDouble(RakNet::BitStream* inStream); + AMFBaseValue* ReadAmfDouble(RakNet::BitStream* inStream); /** * @brief Read an AMFArray from a bitStream @@ -46,7 +47,7 @@ private: * @param inStream bitStream to read data from * @return Array value represented as an AMFValue */ - AMFValue* ReadAmfArray(RakNet::BitStream* inStream); + AMFBaseValue* ReadAmfArray(RakNet::BitStream* inStream); /** * @brief Read an AMFString from a bitStream @@ -54,7 +55,7 @@ private: * @param inStream bitStream to read data from * @return String value represented as an AMFValue */ - AMFValue* ReadAmfString(RakNet::BitStream* inStream); + AMFBaseValue* ReadAmfString(RakNet::BitStream* inStream); /** * @brief Read an AMFInteger from a bitStream @@ -62,7 +63,7 @@ private: * @param inStream bitStream to read data from * @return Integer value represented as an AMFValue */ - AMFValue* ReadAmfInteger(RakNet::BitStream* inStream); + AMFBaseValue* ReadAmfInteger(RakNet::BitStream* inStream); /** * List of strings read so far saved to be read by reference. diff --git a/dCommon/AMFFormat.cpp b/dCommon/AMFFormat.cpp deleted file mode 100644 index 4407b29c..00000000 --- a/dCommon/AMFFormat.cpp +++ /dev/null @@ -1,156 +0,0 @@ -#include "AMFFormat.h" - -// AMFInteger -void AMFIntegerValue::SetIntegerValue(uint32_t value) { - this->value = value; -} - -uint32_t AMFIntegerValue::GetIntegerValue() { - return this->value; -} - -// AMFDouble -void AMFDoubleValue::SetDoubleValue(double value) { - this->value = value; -} - -double AMFDoubleValue::GetDoubleValue() { - return this->value; -} - -// AMFString -void AMFStringValue::SetStringValue(const std::string& value) { - this->value = value; -} - -std::string AMFStringValue::GetStringValue() { - return this->value; -} - -// AMFXMLDoc -void AMFXMLDocValue::SetXMLDocValue(const std::string& value) { - this->xmlData = value; -} - -std::string AMFXMLDocValue::GetXMLDocValue() { - return this->xmlData; -} - -// AMFDate -void AMFDateValue::SetDateValue(uint64_t value) { - this->millisecondTimestamp = value; -} - -uint64_t AMFDateValue::GetDateValue() { - return this->millisecondTimestamp; -} - -// AMFArray Insert Value -void AMFArrayValue::InsertValue(const std::string& key, AMFValue* value) { - this->associative.insert(std::make_pair(key, value)); -} - -// AMFArray Remove Value -void AMFArrayValue::RemoveValue(const std::string& key) { - _AMFArrayMap_::iterator it = this->associative.find(key); - if (it != this->associative.end()) { - this->associative.erase(it); - } -} - -// AMFArray Get Associative Iterator Begin -_AMFArrayMap_::iterator AMFArrayValue::GetAssociativeIteratorValueBegin() { - return this->associative.begin(); -} - -// AMFArray Get Associative Iterator End -_AMFArrayMap_::iterator AMFArrayValue::GetAssociativeIteratorValueEnd() { - return this->associative.end(); -} - -// AMFArray Push Back Value -void AMFArrayValue::PushBackValue(AMFValue* value) { - this->dense.push_back(value); -} - -// AMFArray Pop Back Value -void AMFArrayValue::PopBackValue() { - this->dense.pop_back(); -} - -// AMFArray Get Dense List Size -uint32_t AMFArrayValue::GetDenseValueSize() { - return (uint32_t)this->dense.size(); -} - -// AMFArray Get Dense Iterator Begin -_AMFArrayList_::iterator AMFArrayValue::GetDenseIteratorBegin() { - return this->dense.begin(); -} - -// AMFArray Get Dense Iterator End -_AMFArrayList_::iterator AMFArrayValue::GetDenseIteratorEnd() { - return this->dense.end(); -} - -AMFArrayValue::~AMFArrayValue() { - for (auto valueToDelete : GetDenseArray()) { - if (valueToDelete) delete valueToDelete; - } - for (auto valueToDelete : GetAssociativeMap()) { - if (valueToDelete.second) delete valueToDelete.second; - } -} - -// AMFObject Constructor -AMFObjectValue::AMFObjectValue(std::vector> traits) { - this->traits.reserve(traits.size()); - std::vector>::iterator it = traits.begin(); - while (it != traits.end()) { - this->traits.insert(std::make_pair(it->first, std::make_pair(it->second, new AMFNullValue()))); - it++; - } -} - -// AMFObject Set Value -void AMFObjectValue::SetTraitValue(const std::string& trait, AMFValue* value) { - if (value) { - _AMFObjectTraits_::iterator it = this->traits.find(trait); - if (it != this->traits.end()) { - if (it->second.first == value->GetValueType()) { - it->second.second = value; - } - } - } -} - -// AMFObject Get Value -AMFValue* AMFObjectValue::GetTraitValue(const std::string& trait) { - _AMFObjectTraits_::iterator it = this->traits.find(trait); - if (it != this->traits.end()) { - return it->second.second; - } - - return nullptr; -} - -// AMFObject Get Trait Iterator Begin -_AMFObjectTraits_::iterator AMFObjectValue::GetTraitsIteratorBegin() { - return this->traits.begin(); -} - -// AMFObject Get Trait Iterator End -_AMFObjectTraits_::iterator AMFObjectValue::GetTraitsIteratorEnd() { - return this->traits.end(); -} - -// AMFObject Get Trait Size -uint32_t AMFObjectValue::GetTraitArrayCount() { - return (uint32_t)this->traits.size(); -} - -AMFObjectValue::~AMFObjectValue() { - for (auto valueToDelete = GetTraitsIteratorBegin(); valueToDelete != GetTraitsIteratorEnd(); valueToDelete++) { - if (valueToDelete->second.second) delete valueToDelete->second.second; - } -} diff --git a/dCommon/AMFFormat.h b/dCommon/AMFFormat.h deleted file mode 100644 index 6e479ef6..00000000 --- a/dCommon/AMFFormat.h +++ /dev/null @@ -1,413 +0,0 @@ -#pragma once - -// Custom Classes -#include "dCommonVars.h" - -// C++ -#include -#include - -/*! - \file AMFFormat.hpp - \brief A class for managing AMF values - */ - -class AMFValue; // Forward declaration - -// Definitions -#define _AMFArrayMap_ std::unordered_map -#define _AMFArrayList_ std::vector - -#define _AMFObjectTraits_ std::unordered_map> -#define _AMFObjectDynamicTraits_ std::unordered_map - -//! An enum for each AMF value type -enum AMFValueType : unsigned char { - AMFUndefined = 0x00, //!< An undefined AMF Value - AMFNull = 0x01, //!< A null AMF value - AMFFalse = 0x02, //!< A false AMF value - AMFTrue = 0x03, //!< A true AMF value - AMFInteger = 0x04, //!< An integer AMF value - AMFDouble = 0x05, //!< A double AMF value - AMFString = 0x06, //!< A string AMF value - AMFXMLDoc = 0x07, //!< An XML Doc AMF value - AMFDate = 0x08, //!< A date AMF value - AMFArray = 0x09, //!< An array AMF value - AMFObject = 0x0A, //!< An object AMF value - AMFXML = 0x0B, //!< An XML AMF value - AMFByteArray = 0x0C, //!< A byte array AMF value - AMFVectorInt = 0x0D, //!< An integer vector AMF value - AMFVectorUInt = 0x0E, //!< An unsigned integer AMF value - AMFVectorDouble = 0x0F, //!< A double vector AMF value - AMFVectorObject = 0x10, //!< An object vector AMF value - AMFDictionary = 0x11 //!< A dictionary AMF value -}; - -//! An enum for the object value types -enum AMFObjectValueType : unsigned char { - AMFObjectAnonymous = 0x01, - AMFObjectTyped = 0x02, - AMFObjectDynamic = 0x03, - AMFObjectExternalizable = 0x04 -}; - -//! The base AMF value class -class AMFValue { -public: - //! Returns the AMF value type - /*! - \return The AMF value type - */ - virtual AMFValueType GetValueType() = 0; - virtual ~AMFValue() {}; -}; - -//! A typedef for a pointer to an AMF value -typedef AMFValue* NDGFxValue; - - -// The various AMF value types - -//! The undefined value AMF type -class AMFUndefinedValue : public AMFValue { -private: - //! Returns the AMF value type - /*! - \return The AMF value type - */ - AMFValueType GetValueType() { return ValueType; } -public: - static const AMFValueType ValueType = AMFUndefined; -}; - -//! The null value AMF type -class AMFNullValue : public AMFValue { -private: - //! Returns the AMF value type - /*! - \return The AMF value type - */ - AMFValueType GetValueType() { return ValueType; } -public: - static const AMFValueType ValueType = AMFNull; -}; - -//! The false value AMF type -class AMFFalseValue : public AMFValue { -private: - //! Returns the AMF value type - /*! - \return The AMF value type - */ - AMFValueType GetValueType() { return ValueType; } -public: - static const AMFValueType ValueType = AMFFalse; -}; - -//! The true value AMF type -class AMFTrueValue : public AMFValue { -private: - //! Returns the AMF value type - /*! - \return The AMF value type - */ - AMFValueType GetValueType() { return ValueType; } -public: - static const AMFValueType ValueType = AMFTrue; -}; - -//! The integer value AMF type -class AMFIntegerValue : public AMFValue { -private: - uint32_t value; //!< The value of the AMF type - - //! Returns the AMF value type - /*! - \return The AMF value type - */ - AMFValueType GetValueType() { return ValueType; } - -public: - static const AMFValueType ValueType = AMFInteger; - //! Sets the integer value - /*! - \param value The value to set - */ - void SetIntegerValue(uint32_t value); - - //! Gets the integer value - /*! - \return The integer value - */ - uint32_t GetIntegerValue(); -}; - -//! The double value AMF type -class AMFDoubleValue : public AMFValue { -private: - double value; //!< The value of the AMF type - - //! Returns the AMF value type - /*! - \return The AMF value type - */ - AMFValueType GetValueType() { return ValueType; } - -public: - static const AMFValueType ValueType = AMFDouble; - //! Sets the double value - /*! - \param value The value to set to - */ - void SetDoubleValue(double value); - - //! Gets the double value - /*! - \return The double value - */ - double GetDoubleValue(); -}; - -//! The string value AMF type -class AMFStringValue : public AMFValue { -private: - std::string value; //!< The value of the AMF type - - //! Returns the AMF value type - /*! - \return The AMF value type - */ - AMFValueType GetValueType() { return ValueType; } - -public: - static const AMFValueType ValueType = AMFString; - //! Sets the string value - /*! - \param value The string value to set to - */ - void SetStringValue(const std::string& value); - - //! Gets the string value - /*! - \return The string value - */ - std::string GetStringValue(); -}; - -//! The XML doc value AMF type -class AMFXMLDocValue : public AMFValue { -private: - std::string xmlData; //!< The value of the AMF type - - //! Returns the AMF value type - /*! - \return The AMF value type - */ - AMFValueType GetValueType() { return ValueType; } - -public: - static const AMFValueType ValueType = AMFXMLDoc; - //! Sets the XML Doc value - /*! - \param value The value to set to - */ - void SetXMLDocValue(const std::string& value); - - //! Gets the XML Doc value - /*! - \return The XML Doc value - */ - std::string GetXMLDocValue(); -}; - -//! The date value AMF type -class AMFDateValue : public AMFValue { -private: - uint64_t millisecondTimestamp; //!< The time in milliseconds since the ephoch - - //! Returns the AMF value type - /*! - \return The AMF value type - */ - AMFValueType GetValueType() { return ValueType; } - -public: - static const AMFValueType ValueType = AMFDate; - //! Sets the date time - /*! - \param value The value to set to - */ - void SetDateValue(uint64_t value); - - //! Gets the date value - /*! - \return The date value in milliseconds since the epoch - */ - uint64_t GetDateValue(); -}; - -//! The array value AMF type -// This object will manage it's own memory map and list. Do not delete its values. -class AMFArrayValue : public AMFValue { -private: - _AMFArrayMap_ associative; //!< The array map (associative part) - _AMFArrayList_ dense; //!< The array list (dense part) - - //! Returns the AMF value type - /*! - \return The AMF value type - */ - AMFValueType GetValueType() override { return ValueType; } - -public: - static const AMFValueType ValueType = AMFArray; - - ~AMFArrayValue() override; - //! Inserts an item into the array map for a specific key - /*! - \param key The key to set - \param value The value to add - */ - void InsertValue(const std::string& key, AMFValue* value); - - //! Removes an item for a specific key - /*! - \param key The key to remove - */ - void RemoveValue(const std::string& key); - - //! Finds an AMF value - /*! - \return The AMF value if found, nullptr otherwise - */ - template - T* FindValue(const std::string& key) const { - _AMFArrayMap_::const_iterator it = this->associative.find(key); - if (it != this->associative.end() && T::ValueType == it->second->GetValueType()) { - return dynamic_cast(it->second); - } - - return nullptr; - }; - - //! Returns where the associative iterator begins - /*! - \return Where the array map iterator begins - */ - _AMFArrayMap_::iterator GetAssociativeIteratorValueBegin(); - - //! Returns where the associative iterator ends - /*! - \return Where the array map iterator ends - */ - _AMFArrayMap_::iterator GetAssociativeIteratorValueEnd(); - - //! Pushes back a value into the array list - /*! - \param value The value to push back - */ - void PushBackValue(AMFValue* value); - - //! Pops back the last value in the array list - void PopBackValue(); - - //! Gets the count of the dense list - /*! - \return The dense list size - */ - uint32_t GetDenseValueSize(); - - //! Gets a specific value from the list for the specified index - /*! - \param index The index to get - */ - template - T* GetValueAt(uint32_t index) { - if (index >= this->dense.size()) return nullptr; - AMFValue* foundValue = this->dense.at(index); - return T::ValueType == foundValue->GetValueType() ? dynamic_cast(foundValue) : nullptr; - }; - - //! Returns where the dense iterator begins - /*! - \return Where the iterator begins - */ - _AMFArrayList_::iterator GetDenseIteratorBegin(); - - //! Returns where the dense iterator ends - /*! - \return Where the iterator ends - */ - _AMFArrayList_::iterator GetDenseIteratorEnd(); - - //! Returns the associative map - /*! - \return The associative map - */ - _AMFArrayMap_ GetAssociativeMap() { return this->associative; }; - - //! Returns the dense array - /*! - \return The dense array - */ - _AMFArrayList_ GetDenseArray() { return this->dense; }; -}; - -//! The anonymous object value AMF type -class AMFObjectValue : public AMFValue { -private: - _AMFObjectTraits_ traits; //!< The object traits - - //! Returns the AMF value type - /*! - \return The AMF value type - */ - AMFValueType GetValueType() override { return ValueType; } - ~AMFObjectValue() override; - -public: - static const AMFValueType ValueType = AMFObject; - //! Constructor - /*! - \param traits The traits to set - */ - AMFObjectValue(std::vector> traits); - - //! Gets the object value type - /*! - \return The object value type - */ - virtual AMFObjectValueType GetObjectValueType() { return AMFObjectAnonymous; } - - //! Sets the value of a trait - /*! - \param trait The trait to set the value for - \param value The AMF value to set - */ - void SetTraitValue(const std::string& trait, AMFValue* value); - - //! Gets a trait value - /*! - \param trait The trait to get the value for - \return The trait value - */ - AMFValue* GetTraitValue(const std::string& trait); - - //! Gets the beginning of the object traits iterator - /*! - \return The AMF trait array iterator begin - */ - _AMFObjectTraits_::iterator GetTraitsIteratorBegin(); - - //! Gets the end of the object traits iterator - /*! - \return The AMF trait array iterator begin - */ - _AMFObjectTraits_::iterator GetTraitsIteratorEnd(); - - //! Gets the amount of traits - /*! - \return The amount of traits - */ - uint32_t GetTraitArrayCount(); -}; diff --git a/dCommon/AMFFormat_BitStream.cpp b/dCommon/AMFFormat_BitStream.cpp deleted file mode 100644 index dcb9197d..00000000 --- a/dCommon/AMFFormat_BitStream.cpp +++ /dev/null @@ -1,259 +0,0 @@ -#include "AMFFormat_BitStream.h" - -// Writes an AMFValue pointer to a RakNet::BitStream -template<> -void RakNet::BitStream::Write(AMFValue* value) { - if (value != nullptr) { - AMFValueType type = value->GetValueType(); - - switch (type) { - case AMFUndefined: { - AMFUndefinedValue* v = (AMFUndefinedValue*)value; - this->Write(*v); - break; - } - - case AMFNull: { - AMFNullValue* v = (AMFNullValue*)value; - this->Write(*v); - break; - } - - case AMFFalse: { - AMFFalseValue* v = (AMFFalseValue*)value; - this->Write(*v); - break; - } - - case AMFTrue: { - AMFTrueValue* v = (AMFTrueValue*)value; - this->Write(*v); - break; - } - - case AMFInteger: { - AMFIntegerValue* v = (AMFIntegerValue*)value; - this->Write(*v); - break; - } - - case AMFDouble: { - AMFDoubleValue* v = (AMFDoubleValue*)value; - this->Write(*v); - break; - } - - case AMFString: { - AMFStringValue* v = (AMFStringValue*)value; - this->Write(*v); - break; - } - - case AMFXMLDoc: { - AMFXMLDocValue* v = (AMFXMLDocValue*)value; - this->Write(*v); - break; - } - - case AMFDate: { - AMFDateValue* v = (AMFDateValue*)value; - this->Write(*v); - break; - } - - case AMFArray: { - this->Write((AMFArrayValue*)value); - break; - } - case AMFObject: - case AMFXML: - case AMFByteArray: - case AMFVectorInt: - case AMFVectorUInt: - case AMFVectorDouble: - case AMFVectorObject: - case AMFDictionary: - break; - } - } -} - -/** - * A private function to write an value to a RakNet::BitStream - * RakNet writes in the correct byte order - do not reverse this. - */ -void WriteUInt29(RakNet::BitStream* bs, uint32_t v) { - unsigned char b4 = (unsigned char)v; - if (v < 0x00200000) { - b4 = b4 & 0x7F; - if (v > 0x7F) { - unsigned char b3; - v = v >> 7; - b3 = ((unsigned char)(v)) | 0x80; - if (v > 0x7F) { - unsigned char b2; - v = v >> 7; - b2 = ((unsigned char)(v)) | 0x80; - bs->Write(b2); - } - - bs->Write(b3); - } - } else { - unsigned char b1; - unsigned char b2; - unsigned char b3; - - v = v >> 8; - b3 = ((unsigned char)(v)) | 0x80; - v = v >> 7; - b2 = ((unsigned char)(v)) | 0x80; - v = v >> 7; - b1 = ((unsigned char)(v)) | 0x80; - - bs->Write(b1); - bs->Write(b2); - bs->Write(b3); - } - - bs->Write(b4); -} - -/** - * Writes a flag number to a RakNet::BitStream - * RakNet writes in the correct byte order - do not reverse this. - */ -void WriteFlagNumber(RakNet::BitStream* bs, uint32_t v) { - v = (v << 1) | 0x01; - WriteUInt29(bs, v); -} - -/** - * Writes an AMFString to a RakNet::BitStream - * - * RakNet writes in the correct byte order - do not reverse this. - */ -void WriteAMFString(RakNet::BitStream* bs, const std::string& str) { - WriteFlagNumber(bs, (uint32_t)str.size()); - bs->Write(str.c_str(), (uint32_t)str.size()); -} - -/** - * Writes an U16 to a bitstream - * - * RakNet writes in the correct byte order - do not reverse this. - */ -void WriteAMFU16(RakNet::BitStream* bs, uint16_t value) { - bs->Write(value); -} - -/** - * Writes an U32 to a bitstream - * - * RakNet writes in the correct byte order - do not reverse this. - */ -void WriteAMFU32(RakNet::BitStream* bs, uint32_t value) { - bs->Write(value); -} - -/** - * Writes an U64 to a bitstream - * - * RakNet writes in the correct byte order - do not reverse this. - */ -void WriteAMFU64(RakNet::BitStream* bs, uint64_t value) { - bs->Write(value); -} - - -// Writes an AMFUndefinedValue to BitStream -template<> -void RakNet::BitStream::Write(AMFUndefinedValue value) { - this->Write(AMFUndefined); -} - -// Writes an AMFNullValue to BitStream -template<> -void RakNet::BitStream::Write(AMFNullValue value) { - this->Write(AMFNull); -} - -// Writes an AMFFalseValue to BitStream -template<> -void RakNet::BitStream::Write(AMFFalseValue value) { - this->Write(AMFFalse); -} - -// Writes an AMFTrueValue to BitStream -template<> -void RakNet::BitStream::Write(AMFTrueValue value) { - this->Write(AMFTrue); -} - -// Writes an AMFIntegerValue to BitStream -template<> -void RakNet::BitStream::Write(AMFIntegerValue value) { - this->Write(AMFInteger); - WriteUInt29(this, value.GetIntegerValue()); -} - -// Writes an AMFDoubleValue to BitStream -template<> -void RakNet::BitStream::Write(AMFDoubleValue value) { - this->Write(AMFDouble); - double d = value.GetDoubleValue(); - WriteAMFU64(this, *((unsigned long long*) & d)); -} - -// Writes an AMFStringValue to BitStream -template<> -void RakNet::BitStream::Write(AMFStringValue value) { - this->Write(AMFString); - std::string v = value.GetStringValue(); - WriteAMFString(this, v); -} - -// Writes an AMFXMLDocValue to BitStream -template<> -void RakNet::BitStream::Write(AMFXMLDocValue value) { - this->Write(AMFXMLDoc); - std::string v = value.GetXMLDocValue(); - WriteAMFString(this, v); -} - -// Writes an AMFDateValue to BitStream -template<> -void RakNet::BitStream::Write(AMFDateValue value) { - this->Write(AMFDate); - uint64_t date = value.GetDateValue(); - WriteAMFU64(this, date); -} - -// Writes an AMFArrayValue to BitStream -template<> -void RakNet::BitStream::Write(AMFArrayValue* value) { - this->Write(AMFArray); - uint32_t denseSize = value->GetDenseValueSize(); - WriteFlagNumber(this, denseSize); - - _AMFArrayMap_::iterator it = value->GetAssociativeIteratorValueBegin(); - _AMFArrayMap_::iterator end = value->GetAssociativeIteratorValueEnd(); - - while (it != end) { - WriteAMFString(this, it->first); - this->Write(it->second); - it++; - } - - this->Write(AMFNull); - - if (denseSize > 0) { - _AMFArrayList_::iterator it2 = value->GetDenseIteratorBegin(); - _AMFArrayList_::iterator end2 = value->GetDenseIteratorEnd(); - - while (it2 != end2) { - this->Write(*it2); - it2++; - } - } -} diff --git a/dCommon/AMFFormat_BitStream.h b/dCommon/AMFFormat_BitStream.h deleted file mode 100644 index caa49337..00000000 --- a/dCommon/AMFFormat_BitStream.h +++ /dev/null @@ -1,92 +0,0 @@ -#pragma once - -// Custom Classes -#include "AMFFormat.h" - -// RakNet -#include - -/*! - \file AMFFormat_BitStream.h - \brief A class that implements native writing of AMF values to RakNet::BitStream - */ - - // We are using the RakNet namespace -namespace RakNet { - //! Writes an AMFValue pointer to a RakNet::BitStream - /*! - \param value The value to write - */ - template <> - void RakNet::BitStream::Write(AMFValue* value); - - //! Writes an AMFUndefinedValue to a RakNet::BitStream - /*! - \param value The value to write - */ - template <> - void RakNet::BitStream::Write(AMFUndefinedValue value); - - //! Writes an AMFNullValue to a RakNet::BitStream - /*! - \param value The value to write - */ - template <> - void RakNet::BitStream::Write(AMFNullValue value); - - //! Writes an AMFFalseValue to a RakNet::BitStream - /*! - \param value The value to write - */ - template <> - void RakNet::BitStream::Write(AMFFalseValue value); - - //! Writes an AMFTrueValue to a RakNet::BitStream - /*! - \param value The value to write - */ - template <> - void RakNet::BitStream::Write(AMFTrueValue value); - - //! Writes an AMFIntegerValue to a RakNet::BitStream - /*! - \param value The value to write - */ - template <> - void RakNet::BitStream::Write(AMFIntegerValue value); - - //! Writes an AMFDoubleValue to a RakNet::BitStream - /*! - \param value The value to write - */ - template <> - void RakNet::BitStream::Write(AMFDoubleValue value); - - //! Writes an AMFStringValue to a RakNet::BitStream - /*! - \param value The value to write - */ - template <> - void RakNet::BitStream::Write(AMFStringValue value); - - //! Writes an AMFXMLDocValue to a RakNet::BitStream - /*! - \param value The value to write - */ - template <> - void RakNet::BitStream::Write(AMFXMLDocValue value); - - //! Writes an AMFDateValue to a RakNet::BitStream - /*! - \param value The value to write - */ - template <> - void RakNet::BitStream::Write(AMFDateValue value); - - //! Writes an AMFArrayValue to a RakNet::BitStream - /*! - \param value The value to write - */ - template <> - void RakNet::BitStream::Write(AMFArrayValue* value); -} // namespace RakNet diff --git a/dCommon/Amf3.h b/dCommon/Amf3.h new file mode 100644 index 00000000..4c649524 --- /dev/null +++ b/dCommon/Amf3.h @@ -0,0 +1,367 @@ +#ifndef __AMF3__H__ +#define __AMF3__H__ + +#include "dCommonVars.h" +#include "dLogger.h" +#include "Game.h" + +#include +#include + +enum class eAmf : uint8_t { + Undefined = 0x00, // An undefined AMF Value + Null = 0x01, // A null AMF value + False = 0x02, // A false AMF value + True = 0x03, // A true AMF value + Integer = 0x04, // An integer AMF value + Double = 0x05, // A double AMF value + String = 0x06, // A string AMF value + XMLDoc = 0x07, // Unused in the live client and cannot be serialized without modification. An XML Doc AMF value + Date = 0x08, // Unused in the live client and cannot be serialized without modification. A date AMF value + Array = 0x09, // An array AMF value + Object = 0x0A, // Unused in the live client and cannot be serialized without modification. An object AMF value + XML = 0x0B, // Unused in the live client and cannot be serialized without modification. An XML AMF value + ByteArray = 0x0C, // Unused in the live client and cannot be serialized without modification. A byte array AMF value + VectorInt = 0x0D, // Unused in the live client and cannot be serialized without modification. An integer vector AMF value + VectorUInt = 0x0E, // Unused in the live client and cannot be serialized without modification. An unsigned integer AMF value + VectorDouble = 0x0F, // Unused in the live client and cannot be serialized without modification. A double vector AMF value + VectorObject = 0x10, // Unused in the live client and cannot be serialized without modification. An object vector AMF value + Dictionary = 0x11 // Unused in the live client and cannot be serialized without modification. A dictionary AMF value +}; + +class AMFBaseValue { +public: + virtual eAmf GetValueType() { return eAmf::Undefined; }; + AMFBaseValue() {}; + virtual ~AMFBaseValue() {}; +}; + +template +class AMFValue : public AMFBaseValue { +public: + AMFValue() {}; + AMFValue(ValueType value) { SetValue(value); }; + virtual ~AMFValue() override {}; + + eAmf GetValueType() override { return eAmf::Undefined; }; + + const ValueType& GetValue() { return data; }; + void SetValue(ValueType value) { data = value; }; +protected: + ValueType data; +}; + +// As a string this is much easier to write and read from a BitStream. +template<> +class AMFValue : public AMFBaseValue { +public: + AMFValue() {}; + AMFValue(const char* value) { SetValue(std::string(value)); }; + virtual ~AMFValue() override {}; + + eAmf GetValueType() override { return eAmf::String; }; + + const std::string& GetValue() { return data; }; + void SetValue(std::string value) { data = value; }; +protected: + std::string data; +}; + +typedef AMFValue AMFNullValue; +typedef AMFValue AMFBoolValue; +typedef AMFValue AMFIntValue; +typedef AMFValue AMFStringValue; +typedef AMFValue AMFDoubleValue; + +template<> inline eAmf AMFValue::GetValueType() { return eAmf::Null; }; +template<> inline eAmf AMFValue::GetValueType() { return this->data ? eAmf::True : eAmf::False; }; +template<> inline eAmf AMFValue::GetValueType() { return eAmf::Integer; }; +template<> inline eAmf AMFValue::GetValueType() { return eAmf::Integer; }; +template<> inline eAmf AMFValue::GetValueType() { return eAmf::String; }; +template<> inline eAmf AMFValue::GetValueType() { return eAmf::Double; }; + +/** + * The AMFArrayValue object holds 2 types of lists: + * An associative list where a key maps to a value + * A Dense list where elements are stored back to back + * + * Objects that are Registered are owned by this object + * and are not to be deleted by a caller. + */ +class AMFArrayValue : public AMFBaseValue { + + typedef std::unordered_map AMFAssociative; + typedef std::vector AMFDense; + +public: + eAmf GetValueType() override { return eAmf::Array; }; + + ~AMFArrayValue() override { + for (auto valueToDelete : GetDense()) { + if (valueToDelete) { + delete valueToDelete; + valueToDelete = nullptr; + } + } + for (auto valueToDelete : GetAssociative()) { + if (valueToDelete.second) { + delete valueToDelete.second; + valueToDelete.second = nullptr; + } + } + }; + + /** + * Returns the Associative portion of the object + */ + inline AMFAssociative& GetAssociative() { return this->associative; }; + + /** + * Returns the dense portion of the object + */ + inline AMFDense& GetDense() { return this->dense; }; + + /** + * Inserts an AMFValue into the associative portion with the given key. + * If a duplicate is attempted to be inserted, it is ignored and the + * first value with that key is kept in the map. + * + * These objects are not to be deleted by the caller as they are owned by + * the AMFArray object which manages its own memory. + * + * @param key The key to associate with the value + * @param value The value to insert + * + * @return The inserted element if the type matched, + * or nullptr if a key existed and was not the same type + */ + template + std::pair*, bool> Insert(const std::string& key, ValueType value) { + auto element = associative.find(key); + AMFValue* val = nullptr; + bool found = true; + if (element == associative.end()) { + val = new AMFValue(value); + associative.insert(std::make_pair(key, val)); + } else { + val = dynamic_cast*>(element->second); + found = false; + } + return std::make_pair(val, found); + }; + + // Associates an array with a string key + std::pair Insert(const std::string& key) { + auto element = associative.find(key); + AMFArrayValue* val = nullptr; + bool found = true; + if (element == associative.end()) { + val = new AMFArrayValue(); + associative.insert(std::make_pair(key, val)); + } else { + val = dynamic_cast(element->second); + found = false; + } + return std::make_pair(val, found); + }; + + // Associates an array with an integer key + std::pair Insert(const uint32_t& index) { + AMFArrayValue* val = nullptr; + bool inserted = false; + if (index >= dense.size()) { + dense.resize(index + 1); + val = new AMFArrayValue(); + dense.at(index) = val; + inserted = true; + } + return std::make_pair(dynamic_cast(dense.at(index)), inserted); + }; + + /** + * @brief Inserts an AMFValue into the AMFArray key'd by index. + * Attempting to insert the same key to the same value twice overwrites + * the previous value with the new one. + * + * @param index The index to associate with the value + * @param value The value to insert + * @return The inserted element, or nullptr if the type did not match + * what was at the index. + */ + template + std::pair*, bool> Insert(const uint32_t& index, ValueType value) { + AMFValue* val = nullptr; + bool inserted = false; + if (index >= this->dense.size()) { + this->dense.resize(index + 1); + val = new AMFValue(value); + this->dense.at(index) = val; + inserted = true; + } + return std::make_pair(dynamic_cast*>(this->dense.at(index)), inserted); + }; + + /** + * Inserts an AMFValue into the associative portion with the given key. + * If a duplicate is attempted to be inserted, it replaces the original + * + * The inserted element is now owned by this object and is not to be deleted + * + * @param key The key to associate with the value + * @param value The value to insert + */ + void Insert(const std::string& key, AMFBaseValue* value) { + auto element = associative.find(key); + if (element != associative.end() && element->second) { + delete element->second; + element->second = value; + } else { + associative.insert(std::make_pair(key, value)); + } + }; + + /** + * Inserts an AMFValue into the associative portion with the given index. + * If a duplicate is attempted to be inserted, it replaces the original + * + * The inserted element is now owned by this object and is not to be deleted + * + * @param key The key to associate with the value + * @param value The value to insert + */ + void Insert(const uint32_t index, AMFBaseValue* value) { + if (index < dense.size()) { + AMFDense::iterator itr = dense.begin() + index; + if (*itr) delete dense.at(index); + } else { + dense.resize(index + 1); + } + dense.at(index) = value; + }; + + /** + * Pushes an AMFValue into the back of the dense portion. + * + * These objects are not to be deleted by the caller as they are owned by + * the AMFArray object which manages its own memory. + * + * @param value The value to insert + * + * @return The inserted pointer, or nullptr should the key already be in use. + */ + template + inline AMFValue* Push(ValueType value) { + return Insert(this->dense.size(), value).first; + }; + + /** + * Removes the key from the associative portion + * + * The pointer removed is now no longer managed by this container + * + * @param key The key to remove from the associative portion + */ + void Remove(const std::string& key, bool deleteValue = true) { + AMFAssociative::iterator it = this->associative.find(key); + if (it != this->associative.end()) { + if (deleteValue) delete it->second; + this->associative.erase(it); + } + } + + /** + * Pops the last element in the dense portion, deleting it in the process. + */ + void Remove(const uint32_t index) { + if (!this->dense.empty() && index < this->dense.size()) { + auto itr = this->dense.begin() + index; + if (*itr) delete (*itr); + this->dense.erase(itr); + } + } + + void Pop() { + if (!this->dense.empty()) Remove(this->dense.size() - 1); + } + + AMFArrayValue* GetArray(const std::string& key) { + AMFAssociative::const_iterator it = this->associative.find(key); + if (it != this->associative.end()) { + return dynamic_cast(it->second); + } + return nullptr; + }; + + AMFArrayValue* GetArray(const uint32_t index) { + return index >= this->dense.size() ? nullptr : dynamic_cast(this->dense.at(index)); + }; + + inline AMFArrayValue* InsertArray(const std::string& key) { + return static_cast(Insert(key).first); + }; + + inline AMFArrayValue* InsertArray(const uint32_t index) { + return static_cast(Insert(index).first); + }; + + inline AMFArrayValue* PushArray() { + return static_cast(Insert(this->dense.size()).first); + }; + + /** + * Gets an AMFValue by the key from the associative portion and converts it + * to the AmfValue template type. If the key did not exist, it is inserted. + * + * @tparam The target object type + * @param key The key to lookup + * + * @return The AMFValue + */ + template + AMFValue* Get(const std::string& key) const { + AMFAssociative::const_iterator it = this->associative.find(key); + return it != this->associative.end() ? + dynamic_cast*>(it->second) : + nullptr; + }; + + // Get from the array but dont cast it + AMFBaseValue* Get(const std::string& key) const { + AMFAssociative::const_iterator it = this->associative.find(key); + return it != this->associative.end() ? it->second : nullptr; + }; + + /** + * @brief Get an AMFValue object at a position in the dense portion. + * Gets an AMFValue by the index from the dense portion and converts it + * to the AmfValue template type. If the index did not exist, it is inserted. + * + * @tparam The target object type + * @param index The index to get + * @return The casted object, or nullptr. + */ + template + AMFValue* Get(uint32_t index) const { + return index < this->dense.size() ? + dynamic_cast*>(this->dense.at(index)) : + nullptr; + }; + + // Get from the dense but dont cast it + AMFBaseValue* Get(const uint32_t index) const { + return index < this->dense.size() ? this->dense.at(index) : nullptr; + }; +private: + /** + * The associative portion. These values are key'd with strings to an AMFValue. + */ + AMFAssociative associative; + + /** + * The dense portion. These AMFValue's are stored one after + * another with the most recent addition being at the back. + */ + AMFDense dense; +}; + +#endif //!__AMF3__H__ diff --git a/dCommon/AmfSerialize.cpp b/dCommon/AmfSerialize.cpp new file mode 100644 index 00000000..79ba5e2d --- /dev/null +++ b/dCommon/AmfSerialize.cpp @@ -0,0 +1,184 @@ +#include "AmfSerialize.h" + +#include "Game.h" +#include "dLogger.h" + +// Writes an AMFValue pointer to a RakNet::BitStream +template<> +void RakNet::BitStream::Write(AMFBaseValue& value) { + eAmf type = value.GetValueType(); + this->Write(type); + switch (type) { + case eAmf::Integer: { + this->Write(*static_cast(&value)); + break; + } + + case eAmf::Double: { + this->Write(*static_cast(&value)); + break; + } + + case eAmf::String: { + this->Write(*static_cast(&value)); + break; + } + + case eAmf::Array: { + this->Write(*static_cast(&value)); + break; + } + default: { + Game::logger->Log("AmfSerialize", "Encountered unwritable AMFType %i!", type); + } + case eAmf::Undefined: + case eAmf::Null: + case eAmf::False: + case eAmf::True: + case eAmf::Date: + case eAmf::Object: + case eAmf::XML: + case eAmf::XMLDoc: + case eAmf::ByteArray: + case eAmf::VectorInt: + case eAmf::VectorUInt: + case eAmf::VectorDouble: + case eAmf::VectorObject: + case eAmf::Dictionary: + break; + } +} + +/** + * A private function to write an value to a RakNet::BitStream + * RakNet writes in the correct byte order - do not reverse this. + */ +void WriteUInt29(RakNet::BitStream* bs, uint32_t v) { + unsigned char b4 = (unsigned char)v; + if (v < 0x00200000) { + b4 = b4 & 0x7F; + if (v > 0x7F) { + unsigned char b3; + v = v >> 7; + b3 = ((unsigned char)(v)) | 0x80; + if (v > 0x7F) { + unsigned char b2; + v = v >> 7; + b2 = ((unsigned char)(v)) | 0x80; + bs->Write(b2); + } + + bs->Write(b3); + } + } else { + unsigned char b1; + unsigned char b2; + unsigned char b3; + + v = v >> 8; + b3 = ((unsigned char)(v)) | 0x80; + v = v >> 7; + b2 = ((unsigned char)(v)) | 0x80; + v = v >> 7; + b1 = ((unsigned char)(v)) | 0x80; + + bs->Write(b1); + bs->Write(b2); + bs->Write(b3); + } + + bs->Write(b4); +} + +/** + * Writes a flag number to a RakNet::BitStream + * RakNet writes in the correct byte order - do not reverse this. + */ +void WriteFlagNumber(RakNet::BitStream* bs, uint32_t v) { + v = (v << 1) | 0x01; + WriteUInt29(bs, v); +} + +/** + * Writes an AMFString to a RakNet::BitStream + * + * RakNet writes in the correct byte order - do not reverse this. + */ +void WriteAMFString(RakNet::BitStream* bs, const std::string& str) { + WriteFlagNumber(bs, (uint32_t)str.size()); + bs->Write(str.c_str(), (uint32_t)str.size()); +} + +/** + * Writes an U16 to a bitstream + * + * RakNet writes in the correct byte order - do not reverse this. + */ +void WriteAMFU16(RakNet::BitStream* bs, uint16_t value) { + bs->Write(value); +} + +/** + * Writes an U32 to a bitstream + * + * RakNet writes in the correct byte order - do not reverse this. + */ +void WriteAMFU32(RakNet::BitStream* bs, uint32_t value) { + bs->Write(value); +} + +/** + * Writes an U64 to a bitstream + * + * RakNet writes in the correct byte order - do not reverse this. + */ +void WriteAMFU64(RakNet::BitStream* bs, uint64_t value) { + bs->Write(value); +} + +// Writes an AMFIntegerValue to BitStream +template<> +void RakNet::BitStream::Write(AMFIntValue& value) { + WriteUInt29(this, value.GetValue()); +} + +// Writes an AMFDoubleValue to BitStream +template<> +void RakNet::BitStream::Write(AMFDoubleValue& value) { + double d = value.GetValue(); + WriteAMFU64(this, *reinterpret_cast(&d)); +} + +// Writes an AMFStringValue to BitStream +template<> +void RakNet::BitStream::Write(AMFStringValue& value) { + WriteAMFString(this, value.GetValue()); +} + +// Writes an AMFArrayValue to BitStream +template<> +void RakNet::BitStream::Write(AMFArrayValue& value) { + uint32_t denseSize = value.GetDense().size(); + WriteFlagNumber(this, denseSize); + + auto it = value.GetAssociative().begin(); + auto end = value.GetAssociative().end(); + + while (it != end) { + WriteAMFString(this, it->first); + this->Write(*it->second); + it++; + } + + this->Write(eAmf::Null); + + if (denseSize > 0) { + auto it2 = value.GetDense().begin(); + auto end2 = value.GetDense().end(); + + while (it2 != end2) { + this->Write(**it2); + it2++; + } + } +} diff --git a/dCommon/AmfSerialize.h b/dCommon/AmfSerialize.h new file mode 100644 index 00000000..9a6f56f2 --- /dev/null +++ b/dCommon/AmfSerialize.h @@ -0,0 +1,50 @@ +#pragma once + +// Custom Classes +#include "Amf3.h" + +// RakNet +#include + +/*! + \file AmfSerialize.h + \brief A class that implements native writing of AMF values to RakNet::BitStream + */ + + // We are using the RakNet namespace +namespace RakNet { + //! Writes an AMFValue pointer to a RakNet::BitStream + /*! + \param value The value to write + */ + template <> + void RakNet::BitStream::Write(AMFBaseValue& value); + + //! Writes an AMFIntegerValue to a RakNet::BitStream + /*! + \param value The value to write + */ + template <> + void RakNet::BitStream::Write(AMFIntValue& value); + + //! Writes an AMFDoubleValue to a RakNet::BitStream + /*! + \param value The value to write + */ + template <> + void RakNet::BitStream::Write(AMFDoubleValue& value); + + //! Writes an AMFStringValue to a RakNet::BitStream + /*! + \param value The value to write + */ + template <> + void RakNet::BitStream::Write(AMFStringValue& value); + + //! Writes an AMFArrayValue to a RakNet::BitStream + /*! + \param value The value to write + */ + template <> + void RakNet::BitStream::Write(AMFArrayValue& value); +} // namespace RakNet diff --git a/dCommon/CMakeLists.txt b/dCommon/CMakeLists.txt index 549acfb2..2517c048 100644 --- a/dCommon/CMakeLists.txt +++ b/dCommon/CMakeLists.txt @@ -1,6 +1,6 @@ -set(DCOMMON_SOURCES "AMFFormat.cpp" +set(DCOMMON_SOURCES "AMFDeserialize.cpp" - "AMFFormat_BitStream.cpp" + "AmfSerialize.cpp" "BinaryIO.cpp" "dConfig.cpp" "Diagnostics.cpp" diff --git a/dCommon/DluAssert.h b/dCommon/DluAssert.h new file mode 100644 index 00000000..c54dd54e --- /dev/null +++ b/dCommon/DluAssert.h @@ -0,0 +1,12 @@ +#ifndef __DLUASSERT__H__ +#define __DLUASSERT__H__ + +#include + +#ifdef _DEBUG +# define DluAssert(expression) assert(expression) +#else +# define DluAssert(expression) +#endif + +#endif //!__DLUASSERT__H__ diff --git a/dCommon/Game.h b/dCommon/Game.h index 66f3f6b7..09ac6f6e 100644 --- a/dCommon/Game.h +++ b/dCommon/Game.h @@ -10,6 +10,8 @@ class dConfig; class RakPeerInterface; class AssetManager; struct SystemAddress; +class EntityManager; +class dZoneManager; namespace Game { extern dLogger* logger; @@ -22,4 +24,6 @@ namespace Game { extern AssetManager* assetManager; extern SystemAddress chatSysAddr; extern bool shouldShutdown; + extern EntityManager* entityManager; + extern dZoneManager* zoneManager; } diff --git a/dCommon/GeneralUtils.h b/dCommon/GeneralUtils.h index 0a8a0a16..e9e20ba0 100644 --- a/dCommon/GeneralUtils.h +++ b/dCommon/GeneralUtils.h @@ -111,29 +111,6 @@ namespace GeneralUtils { */ bool CheckBit(int64_t value, uint32_t index); - // MARK: Random Number Generation - - //! Generates a random number - /*! - \param min The minimum the generate from - \param max The maximum to generate to - */ - template - inline T GenerateRandomNumber(std::size_t min, std::size_t max) { - // Make sure it is a numeric type - static_assert(std::is_arithmetic::value, "Not an arithmetic type"); - - if constexpr (std::is_integral_v) { // constexpr only necessary on first statement - std::uniform_int_distribution distribution(min, max); - return distribution(Game::randomEngine); - } else if (std::is_floating_point_v) { - std::uniform_real_distribution distribution(min, max); - return distribution(Game::randomEngine); - } - - return T(); - } - bool ReplaceInString(std::string& str, const std::string& from, const std::string& to); std::u16string ReadWString(RakNet::BitStream* inStream); @@ -223,4 +200,42 @@ namespace GeneralUtils { std::hash h; s ^= h(v) + 0x9e3779b9 + (s << 6) + (s >> 2); } + + // MARK: Random Number Generation + + //! Generates a random number + /*! + \param min The minimum the generate from + \param max The maximum to generate to + */ + template + inline T GenerateRandomNumber(std::size_t min, std::size_t max) { + // Make sure it is a numeric type + static_assert(std::is_arithmetic::value, "Not an arithmetic type"); + + if constexpr (std::is_integral_v) { // constexpr only necessary on first statement + std::uniform_int_distribution distribution(min, max); + return distribution(Game::randomEngine); + } else if (std::is_floating_point_v) { + std::uniform_real_distribution distribution(min, max); + return distribution(Game::randomEngine); + } + + return T(); + } + +// on Windows we need to undef these or else they conflict with our numeric limits calls +// DEVELOPERS DEVELOPERS DEVELOPERS DEVELOPERS DEVELOPERS DEVELOPERS DEVELOPERS DEVELOPERS +#ifdef _WIN32 +#undef min +#undef max +#endif + + template + inline T GenerateRandomNumber() { + // Make sure it is a numeric type + static_assert(std::is_arithmetic::value, "Not an arithmetic type"); + + return GenerateRandomNumber(std::numeric_limits::min(), std::numeric_limits::max()); + } } diff --git a/dCommon/dEnums/dCommonVars.h b/dCommon/dEnums/dCommonVars.h index e11866f1..f67145da 100644 --- a/dCommon/dEnums/dCommonVars.h +++ b/dCommon/dEnums/dCommonVars.h @@ -28,8 +28,10 @@ constexpr uint32_t lowFrameDelta = FRAMES_TO_MS(lowFramerate); //========== MACROS =========== +#define HEADER_SIZE 8 #define CBITSTREAM RakNet::BitStream bitStream; #define CINSTREAM RakNet::BitStream inStream(packet->data, packet->length, false); +#define CINSTREAM_SKIP_HEADER CINSTREAM if (inStream.GetNumberOfUnreadBits() >= BYTES_TO_BITS(HEADER_SIZE)) inStream.IgnoreBytes(HEADER_SIZE); else inStream.IgnoreBits(inStream.GetNumberOfUnreadBits()); #define CMSGHEADER PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::GAME_MSG); #define SEND_PACKET Game::server->Send(&bitStream, sysAddr, false); #define SEND_PACKET_BROADCAST Game::server->Send(&bitStream, UNASSIGNED_SYSTEM_ADDRESS, true); diff --git a/dCommon/dEnums/eGameMessageType.h b/dCommon/dEnums/eGameMessageType.h index 247ee5e2..051a5ae8 100644 --- a/dCommon/dEnums/eGameMessageType.h +++ b/dCommon/dEnums/eGameMessageType.h @@ -273,7 +273,7 @@ enum class eGameMessageType : uint16_t { TEAM_SET_LEADER = 1557, TEAM_INVITE_CONFIRM = 1558, TEAM_GET_STATUS_RESPONSE = 1559, - TEAM_ADD_PLAYER = 1526, + TEAM_ADD_PLAYER = 1562, TEAM_REMOVE_PLAYER = 1563, START_CELEBRATION_EFFECT = 1618, ADD_BUFF = 1647, diff --git a/dCommon/dEnums/eReplicaComponentType.h b/dCommon/dEnums/eReplicaComponentType.h index 3eee16f3..2d24c19e 100644 --- a/dCommon/dEnums/eReplicaComponentType.h +++ b/dCommon/dEnums/eReplicaComponentType.h @@ -107,7 +107,7 @@ enum class eReplicaComponentType : uint32_t { DONATION_VENDOR, COMBAT_MEDIATOR, COMMENDATION_VENDOR, - UNKNOWN_103, + GATE_RUSH_CONTROL, RAIL_ACTIVATOR, ROLLER, PLAYER_FORCED_MOVEMENT, @@ -119,7 +119,7 @@ enum class eReplicaComponentType : uint32_t { UNKNOWN_112, PROPERTY_PLAQUE, BUILD_BORDER, - UNKOWN_115, + UNKNOWN_115, CULLING_PLANE, DESTROYABLE = 1000 // Actually 7 }; diff --git a/dDatabase/CDClientDatabase.h b/dDatabase/CDClientDatabase.h index 96f67d64..59f69b7d 100644 --- a/dDatabase/CDClientDatabase.h +++ b/dDatabase/CDClientDatabase.h @@ -16,9 +16,6 @@ // Enable this to cache all entries in each table for fast access, comes with more memory cost //#define CDCLIENT_CACHE_ALL - // Enable this to skip some unused columns in some tables -#define UNUSED(v) - /*! \file CDClientDatabase.hpp \brief An interface between the CDClient.sqlite file and the server diff --git a/dDatabase/CDClientManager.cpp b/dDatabase/CDClientManager.cpp index eeea686f..9df6ff31 100644 --- a/dDatabase/CDClientManager.cpp +++ b/dDatabase/CDClientManager.cpp @@ -40,7 +40,7 @@ CDClientManager::CDClientManager() { CDActivityRewardsTable::Instance(); - UNUSED(CDAnimationsTable::Instance()); + CDAnimationsTable::Instance(); CDBehaviorParameterTable::Instance(); CDBehaviorTemplateTable::Instance(); CDComponentsRegistryTable::Instance(); diff --git a/dDatabase/CDClientManager.h b/dDatabase/CDClientManager.h index 1754fe99..74069ff4 100644 --- a/dDatabase/CDClientManager.h +++ b/dDatabase/CDClientManager.h @@ -4,6 +4,8 @@ #include "Singleton.h" +#define UNUSED_TABLE(v) + /** * Initialize the CDClient tables so they are all loaded into memory. */ diff --git a/dDatabase/Tables/CDAnimationsTable.cpp b/dDatabase/Tables/CDAnimationsTable.cpp index e1227f39..76ce0e5a 100644 --- a/dDatabase/Tables/CDAnimationsTable.cpp +++ b/dDatabase/Tables/CDAnimationsTable.cpp @@ -1,56 +1,83 @@ #include "CDAnimationsTable.h" +#include "GeneralUtils.h" +#include "Game.h" -CDAnimationsTable::CDAnimationsTable(void) { +bool CDAnimationsTable::CacheData(CppSQLite3Statement& queryToCache) { + auto tableData = queryToCache.execQuery(); + // If we received a bad lookup, cache it anyways so we do not run the query again. + if (tableData.eof()) return false; - // First, get the size of the table - unsigned int size = 0; - auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM Animations"); - while (!tableSize.eof()) { - size = tableSize.getIntField(0, 0); + do { + std::string animation_type = tableData.getStringField("animation_type", ""); + DluAssert(!animation_type.empty()); + AnimationGroupID animationGroupID = tableData.getIntField("animationGroupID", -1); + DluAssert(animationGroupID != -1); - tableSize.nextRow(); - } - - tableSize.finalize(); - - // Reserve the size - this->entries.reserve(size); - - // Now get the data - auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM Animations"); - while (!tableData.eof()) { - CDAnimations entry; - entry.animationGroupID = tableData.getIntField("animationGroupID", -1); - entry.animation_type = tableData.getStringField("animation_type", ""); + CDAnimation entry; entry.animation_name = tableData.getStringField("animation_name", ""); - entry.chance_to_play = tableData.getFloatField("chance_to_play", -1.0f); - entry.min_loops = tableData.getIntField("min_loops", -1); - entry.max_loops = tableData.getIntField("max_loops", -1); - entry.animation_length = tableData.getFloatField("animation_length", -1.0f); - entry.hideEquip = tableData.getIntField("hideEquip", -1) == 1 ? true : false; - entry.ignoreUpperBody = tableData.getIntField("ignoreUpperBody", -1) == 1 ? true : false; - entry.restartable = tableData.getIntField("restartable", -1) == 1 ? true : false; - entry.face_animation_name = tableData.getStringField("face_animation_name", ""); - entry.priority = tableData.getFloatField("priority", -1.0f); - entry.blendTime = tableData.getFloatField("blendTime", -1.0f); + entry.chance_to_play = tableData.getFloatField("chance_to_play", 1.0f); + UNUSED_COLUMN(entry.min_loops = tableData.getIntField("min_loops", 0);) + UNUSED_COLUMN(entry.max_loops = tableData.getIntField("max_loops", 0);) + entry.animation_length = tableData.getFloatField("animation_length", 0.0f); + UNUSED_COLUMN(entry.hideEquip = tableData.getIntField("hideEquip", 0) == 1;) + UNUSED_COLUMN(entry.ignoreUpperBody = tableData.getIntField("ignoreUpperBody", 0) == 1;) + UNUSED_COLUMN(entry.restartable = tableData.getIntField("restartable", 0) == 1;) + UNUSED_COLUMN(entry.face_animation_name = tableData.getStringField("face_animation_name", "");) + UNUSED_COLUMN(entry.priority = tableData.getFloatField("priority", 0.0f);) + UNUSED_COLUMN(entry.blendTime = tableData.getFloatField("blendTime", 0.0f);) - this->entries.push_back(entry); + this->animations[CDAnimationKey(animation_type, animationGroupID)].push_back(entry); tableData.nextRow(); - } + } while (!tableData.eof()); tableData.finalize(); + + return true; } -std::vector CDAnimationsTable::Query(std::function predicate) { - - std::vector data = cpplinq::from(this->entries) - >> cpplinq::where(predicate) - >> cpplinq::to_vector(); - - return data; +void CDAnimationsTable::CacheAnimations(const CDAnimationKey animationKey) { + auto query = CDClientDatabase::CreatePreppedStmt("SELECT * FROM Animations WHERE animationGroupID = ? and animation_type = ?"); + query.bind(1, static_cast(animationKey.second)); + query.bind(2, animationKey.first.c_str()); + // If we received a bad lookup, cache it anyways so we do not run the query again. + if (!CacheData(query)) { + this->animations[animationKey]; + } } -std::vector CDAnimationsTable::GetEntries(void) const { - return this->entries; +void CDAnimationsTable::CacheAnimationGroup(AnimationGroupID animationGroupID) { + auto animationEntryCached = this->animations.find(CDAnimationKey("", animationGroupID)); + if (animationEntryCached != this->animations.end()) { + return; + } + + auto query = CDClientDatabase::CreatePreppedStmt("SELECT * FROM Animations WHERE animationGroupID = ?"); + query.bind(1, static_cast(animationGroupID)); + + // Cache the query so we don't run the query again. + CacheData(query); + this->animations[CDAnimationKey("", animationGroupID)]; } +CDAnimationLookupResult CDAnimationsTable::GetAnimation(const AnimationID& animationType, const std::string& previousAnimationName, const AnimationGroupID animationGroupID) { + CDAnimationKey animationKey(animationType, animationGroupID); + auto animationEntryCached = this->animations.find(animationKey); + if (animationEntryCached == this->animations.end()) { + this->CacheAnimations(animationKey); + } + + auto animationEntry = this->animations.find(animationKey); + // If we have only one animation, return it regardless of the chance to play. + if (animationEntry->second.size() == 1) { + return CDAnimationLookupResult(animationEntry->second.front()); + } + auto randomAnimation = GeneralUtils::GenerateRandomNumber(0, 1); + + for (auto& animationEntry : animationEntry->second) { + randomAnimation -= animationEntry.chance_to_play; + // This is how the client gets the random animation. + if (animationEntry.animation_name != previousAnimationName && randomAnimation <= 0.0f) return CDAnimationLookupResult(animationEntry); + } + + return CDAnimationLookupResult(); +} diff --git a/dDatabase/Tables/CDAnimationsTable.h b/dDatabase/Tables/CDAnimationsTable.h index 43400abf..65f54d98 100644 --- a/dDatabase/Tables/CDAnimationsTable.h +++ b/dDatabase/Tables/CDAnimationsTable.h @@ -1,33 +1,66 @@ #pragma once -// Custom Classes #include "CDTable.h" +#include -struct CDAnimations { - unsigned int animationGroupID; //!< The animation group ID - std::string animation_type; //!< The animation type +struct CDAnimation { + // unsigned int animationGroupID; + // std::string animation_type; + // The above two are a pair to represent a primary key in the map. std::string animation_name; //!< The animation name float chance_to_play; //!< The chance to play the animation - unsigned int min_loops; //!< The minimum number of loops - unsigned int max_loops; //!< The maximum number of loops + UNUSED_COLUMN(unsigned int min_loops;) //!< The minimum number of loops + UNUSED_COLUMN(unsigned int max_loops;) //!< The maximum number of loops float animation_length; //!< The animation length - bool hideEquip; //!< Whether or not to hide the equip - bool ignoreUpperBody; //!< Whether or not to ignore the upper body - bool restartable; //!< Whether or not the animation is restartable - std::string face_animation_name; //!< The face animation name - float priority; //!< The priority - float blendTime; //!< The blend time + UNUSED_COLUMN(bool hideEquip;) //!< Whether or not to hide the equip + UNUSED_COLUMN(bool ignoreUpperBody;) //!< Whether or not to ignore the upper body + UNUSED_COLUMN(bool restartable;) //!< Whether or not the animation is restartable + UNUSED_COLUMN(std::string face_animation_name;) //!< The face animation name + UNUSED_COLUMN(float priority;) //!< The priority + UNUSED_COLUMN(float blendTime;) //!< The blend time }; +typedef LookupResult CDAnimationLookupResult; class CDAnimationsTable : public CDTable { -private: - std::vector entries; - + typedef int32_t AnimationGroupID; + typedef std::string AnimationID; + typedef std::pair CDAnimationKey; public: - CDAnimationsTable(); - // Queries the table with a custom "where" clause - std::vector Query(std::function predicate); + /** + * Given an animationType and the previousAnimationName played, return the next animationType to play. + * If there are more than 1 animationTypes that can be played, one is selected at random but also does not allow + * the previousAnimationName to be played twice. + * + * @param animationType The animationID to lookup + * @param previousAnimationName The previously played animation + * @param animationGroupID The animationGroupID to lookup + * @return CDAnimationLookupResult + */ + [[nodiscard]] CDAnimationLookupResult GetAnimation(const AnimationID& animationType, const std::string& previousAnimationName, const AnimationGroupID animationGroupID); - std::vector GetEntries(void) const; + /** + * Cache a full AnimationGroup by its ID. + */ + void CacheAnimationGroup(AnimationGroupID animationGroupID); +private: + + /** + * Cache all animations given a premade key + */ + void CacheAnimations(const CDAnimationKey animationKey); + + /** + * Run the query responsible for caching the data. + * @param queryToCache + * @return true + * @return false + */ + bool CacheData(CppSQLite3Statement& queryToCache); + + /** + * Each animation is key'd by its animationName and its animationGroupID. Each + * animation has a possible list of animations. This is because there can be animations have a percent chance to play so one is selected at random. + */ + std::map> animations; }; diff --git a/dDatabase/Tables/CDTable.h b/dDatabase/Tables/CDTable.h index fca16eb8..e4c11fb9 100644 --- a/dDatabase/Tables/CDTable.h +++ b/dDatabase/Tables/CDTable.h @@ -2,6 +2,7 @@ #include "CDClientDatabase.h" #include "Singleton.h" +#include "DluAssert.h" #include #include @@ -15,6 +16,12 @@ #endif #include "cpplinq.hpp" +// Used for legacy +#define UNUSED(x) + +// Enable this to skip some unused columns in some tables +#define UNUSED_COLUMN(v) + #pragma warning (disable : 4244) //Disable double to float conversion warnings #pragma warning (disable : 4715) //Disable "not all control paths return a value" @@ -23,3 +30,15 @@ class CDTable : public Singleton { protected: virtual ~CDTable() = default; }; + +template +class LookupResult { + typedef std::pair DataType; +public: + LookupResult() { m_data.first = T(); m_data.second = false; }; + LookupResult(T& data) { m_data.first = data; m_data.second = true; }; + inline const T& Data() { return m_data.first; }; + inline const bool& FoundData() { return m_data.second; }; +private: + DataType m_data; +}; diff --git a/dGame/Character.cpp b/dGame/Character.cpp index e565ed4f..c5602bf2 100644 --- a/dGame/Character.cpp +++ b/dGame/Character.cpp @@ -241,7 +241,7 @@ void Character::DoQuickXMLDataParse() { //To try and fix the AG landing into: if (m_ZoneID == 1000 && Game::server->GetZoneID() == 1100) { //sneakily insert our position: - auto pos = dZoneManager::Instance()->GetZone()->GetSpawnPos(); + auto pos = Game::zoneManager->GetZone()->GetSpawnPos(); character->SetAttribute("lzx", pos.x); character->SetAttribute("lzy", pos.y); character->SetAttribute("lzz", pos.z); @@ -290,13 +290,13 @@ void Character::DoQuickXMLDataParse() { void Character::UnlockEmote(int emoteID) { m_UnlockedEmotes.push_back(emoteID); - GameMessages::SendSetEmoteLockState(EntityManager::Instance()->GetEntity(m_ObjectID), false, emoteID); + GameMessages::SendSetEmoteLockState(Game::entityManager->GetEntity(m_ObjectID), false, emoteID); } void Character::SetBuildMode(bool buildMode) { m_BuildMode = buildMode; - auto* controller = dZoneManager::Instance()->GetZoneControlObject(); + auto* controller = Game::zoneManager->GetZoneControlObject(); controller->OnFireEventServerSide(m_OurEntity, buildMode ? "OnBuildModeEnter" : "OnBuildModeLeave"); } @@ -312,7 +312,7 @@ void Character::SaveXMLToDatabase() { character->SetAttribute("gm", static_cast(m_GMLevel)); character->SetAttribute("cc", m_Coins); - auto zoneInfo = dZoneManager::Instance()->GetZone()->GetZoneID(); + auto zoneInfo = Game::zoneManager->GetZone()->GetZoneID(); // lzid garbage, binary concat of zoneID, zoneInstance and zoneClone if (zoneInfo.GetMapID() != 0 && zoneInfo.GetCloneID() == 0) { uint64_t lzidConcat = zoneInfo.GetCloneID(); @@ -373,7 +373,7 @@ void Character::SaveXMLToDatabase() { //Call upon the entity to update our xmlDoc: if (!m_OurEntity) { - Game::logger->Log("Character", "We didn't have an entity set while saving! CHARACTER WILL NOT BE SAVED!"); + Game::logger->Log("Character", "%i:%s didn't have an entity set while saving! CHARACTER WILL NOT BE SAVED!", this->GetID(), this->GetName().c_str()); return; } @@ -384,7 +384,7 @@ void Character::SaveXMLToDatabase() { //For metrics, log the time it took to save: auto end = std::chrono::system_clock::now(); std::chrono::duration elapsed = end - start; - Game::logger->Log("Character", "Saved character to Database in: %fs", elapsed.count()); + Game::logger->Log("Character", "%i:%s Saved character to Database in: %fs", this->GetID(), this->GetName().c_str(), elapsed.count()); } void Character::SetIsNewLogin() { @@ -396,7 +396,7 @@ void Character::SetIsNewLogin() { while (currentChild) { if (currentChild->Attribute("si")) { flags->DeleteChild(currentChild); - Game::logger->Log("Character", "Removed isLoggedIn flag from character %i, saving character to database", GetID()); + Game::logger->Log("Character", "Removed isLoggedIn flag from character %i:%s, saving character to database", GetID(), GetName().c_str()); WriteToDatabase(); } currentChild = currentChild->NextSiblingElement(); @@ -418,13 +418,13 @@ void Character::WriteToDatabase() { delete printer; } -void Character::SetPlayerFlag(const int32_t flagId, const bool value) { +void Character::SetPlayerFlag(const uint32_t flagId, const bool value) { // If the flag is already set, we don't have to recalculate it if (GetPlayerFlag(flagId) == value) return; if (value) { // Update the mission component: - auto* player = EntityManager::Instance()->GetEntity(m_ObjectID); + auto* player = Game::entityManager->GetEntity(m_ObjectID); if (player != nullptr) { auto* missionComponent = player->GetComponent(); @@ -465,7 +465,7 @@ void Character::SetPlayerFlag(const int32_t flagId, const bool value) { GameMessages::SendNotifyClientFlagChange(m_ObjectID, flagId, value, m_ParentUser->GetSystemAddress()); } -bool Character::GetPlayerFlag(const int32_t flagId) const { +bool Character::GetPlayerFlag(const uint32_t flagId) const { // Calculate the index first const auto flagIndex = uint32_t(std::floor(flagId / 64)); @@ -602,7 +602,7 @@ void Character::SetCoins(int64_t newCoins, eLootSourceType lootSource) { m_Coins = newCoins; - GameMessages::SendSetCurrency(EntityManager::Instance()->GetEntity(m_ObjectID), m_Coins, 0, 0, 0, 0, true, lootSource); + GameMessages::SendSetCurrency(Game::entityManager->GetEntity(m_ObjectID), m_Coins, 0, 0, 0, 0, true, lootSource); } bool Character::HasBeenToWorld(LWOMAPID mapID) const { diff --git a/dGame/Character.h b/dGame/Character.h index 3759f206..79ce0c0c 100644 --- a/dGame/Character.h +++ b/dGame/Character.h @@ -415,14 +415,14 @@ public: * @param flagId the ID of the flag to set * @param value the value to set for the flag */ - void SetPlayerFlag(int32_t flagId, bool value); + void SetPlayerFlag(uint32_t flagId, bool value); /** * Gets the value for a certain character flag * @param flagId the ID of the flag to get a value for * @return the value of the flag given the ID (the default is false, obviously) */ - bool GetPlayerFlag(int32_t flagId) const; + bool GetPlayerFlag(uint32_t flagId) const; /** * Notifies the character that they're now muted diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index b9fc79fb..998541ad 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -263,17 +263,17 @@ void Entity::Initialize() { NiQuaternion rot; const auto& targetSceneName = m_Character->GetTargetScene(); - auto* targetScene = EntityManager::Instance()->GetSpawnPointEntity(targetSceneName); + auto* targetScene = Game::entityManager->GetSpawnPointEntity(targetSceneName); if (m_Character->HasBeenToWorld(mapID) && targetSceneName.empty()) { pos = m_Character->GetRespawnPoint(mapID); - rot = dZoneManager::Instance()->GetZone()->GetSpawnRot(); + rot = Game::zoneManager->GetZone()->GetSpawnRot(); } else if (targetScene != nullptr) { pos = targetScene->GetPosition(); rot = targetScene->GetRotation(); } else { - pos = dZoneManager::Instance()->GetZone()->GetSpawnPos(); - rot = dZoneManager::Instance()->GetZone()->GetSpawnRot(); + pos = Game::zoneManager->GetZone()->GetSpawnPos(); + rot = Game::zoneManager->GetZone()->GetSpawnRot(); } controllablePhysics->SetPosition(pos); @@ -386,8 +386,8 @@ void Entity::Initialize() { comp->SetMaxCoins(currencyValues[0].maxvalue); } - // extraInfo overrides - comp->SetIsSmashable(GetVarAs(u"is_smashable") != 0); + // extraInfo overrides. Client ORs the database smashable and the luz smashable. + comp->SetIsSmashable(comp->GetIsSmashable() | (GetVarAs(u"is_smashable") != 0)); } } else { comp->SetHealth(1); @@ -505,7 +505,7 @@ void Entity::Initialize() { // ZoneControl script if (m_TemplateID == 2365) { CDZoneTableTable* zoneTable = CDClientManager::Instance().GetTable(); - const auto zoneID = dZoneManager::Instance()->GetZoneID(); + const auto zoneID = Game::zoneManager->GetZoneID(); const CDZoneTable* zoneData = zoneTable->Query(zoneID.GetMapID()); if (zoneData != nullptr) { @@ -595,8 +595,9 @@ void Entity::Initialize() { m_Components.insert(std::make_pair(eReplicaComponentType::BOUNCER, comp)); } - if ((compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::RENDER) > 0 && m_TemplateID != 2365) || m_Character) { - RenderComponent* render = new RenderComponent(this); + int32_t renderComponentId = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::RENDER); + if ((renderComponentId > 0 && m_TemplateID != 2365) || m_Character) { + RenderComponent* render = new RenderComponent(this, renderComponentId); m_Components.insert(std::make_pair(eReplicaComponentType::RENDER, render)); } @@ -690,7 +691,7 @@ void Entity::Initialize() { } std::string pathName = GetVarAsString(u"attached_path"); - const Path* path = dZoneManager::Instance()->GetZone()->GetPath(pathName); + const Path* path = Game::zoneManager->GetZone()->GetPath(pathName); //Check to see if we have an attached path and add the appropiate component to handle it: if (path){ @@ -707,6 +708,13 @@ void Entity::Initialize() { // TODO: create movementAIcomp and set path } }*/ + } else { + // else we still need to setup moving platform if it has a moving platform comp but no path + int32_t movingPlatformComponentId = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::MOVING_PLATFORM, -1); + if (movingPlatformComponentId >= 0) { + MovingPlatformComponent* plat = new MovingPlatformComponent(this, pathName); + m_Components.insert(std::make_pair(eReplicaComponentType::MOVING_PLATFORM, plat)); + } } int proximityMonitorID = compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PROXIMITY_MONITOR); @@ -727,7 +735,7 @@ void Entity::Initialize() { } }); - if (!m_Character && EntityManager::Instance()->GetGhostingEnabled()) { + if (!m_Character && Game::entityManager->GetGhostingEnabled()) { // Don't ghost what is likely large scene elements if (HasComponent(eReplicaComponentType::SIMPLE_PHYSICS) && HasComponent(eReplicaComponentType::RENDER) && (m_Components.size() == 2 || (HasComponent(eReplicaComponentType::TRIGGER) && m_Components.size() == 3))) { goto no_ghosting; @@ -1276,12 +1284,12 @@ void Entity::Update(const float deltaTime) { } if (m_ShouldDestroyAfterUpdate) { - EntityManager::Instance()->DestroyEntity(this->GetObjectID()); + Game::entityManager->DestroyEntity(this->GetObjectID()); } } void Entity::OnCollisionProximity(LWOOBJID otherEntity, const std::string& proxName, const std::string& status) { - Entity* other = EntityManager::Instance()->GetEntity(otherEntity); + Entity* other = Game::entityManager->GetEntity(otherEntity); if (!other) return; for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { @@ -1295,7 +1303,7 @@ void Entity::OnCollisionProximity(LWOOBJID otherEntity, const std::string& proxN } void Entity::OnCollisionPhantom(const LWOOBJID otherEntity) { - auto* other = EntityManager::Instance()->GetEntity(otherEntity); + auto* other = Game::entityManager->GetEntity(otherEntity); if (!other) return; for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { @@ -1342,7 +1350,7 @@ void Entity::OnCollisionPhantom(const LWOOBJID otherEntity) { } void Entity::OnCollisionLeavePhantom(const LWOOBJID otherEntity) { - auto* other = EntityManager::Instance()->GetEntity(otherEntity); + auto* other = Game::entityManager->GetEntity(otherEntity); if (!other) return; for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { @@ -1485,18 +1493,24 @@ void Entity::OnChoiceBoxResponse(Entity* sender, int32_t button, const std::u16s } } +void Entity::RequestActivityExit(Entity* sender, LWOOBJID player, bool canceled) { + for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) { + script->OnRequestActivityExit(sender, player, canceled); + } +} + void Entity::Smash(const LWOOBJID source, const eKillType killType, const std::u16string& deathType) { if (!m_PlayerIsReadyForUpdates) return; auto* destroyableComponent = GetComponent(); if (destroyableComponent == nullptr) { - Kill(EntityManager::Instance()->GetEntity(source)); + Kill(Game::entityManager->GetEntity(source)); return; } auto* possessorComponent = GetComponent(); if (possessorComponent) { if (possessorComponent->GetPossessable() != LWOOBJID_EMPTY) { - auto* mount = EntityManager::Instance()->GetEntity(possessorComponent->GetPossessable()); + auto* mount = Game::entityManager->GetEntity(possessorComponent->GetPossessable()); if (mount) possessorComponent->Dismount(mount, true); } } @@ -1524,20 +1538,20 @@ void Entity::Kill(Entity* murderer) { } if (!IsPlayer()) { - EntityManager::Instance()->DestroyEntity(this); + Game::entityManager->DestroyEntity(this); } const auto& grpNameQBShowBricks = GetVar(u"grpNameQBShowBricks"); if (!grpNameQBShowBricks.empty()) { - auto spawners = dZoneManager::Instance()->GetSpawnersByName(grpNameQBShowBricks); + auto spawners = Game::zoneManager->GetSpawnersByName(grpNameQBShowBricks); Spawner* spawner = nullptr; if (!spawners.empty()) { spawner = spawners[0]; } else { - spawners = dZoneManager::Instance()->GetSpawnersInGroup(grpNameQBShowBricks); + spawners = Game::zoneManager->GetSpawnersInGroup(grpNameQBShowBricks); if (!spawners.empty()) { spawner = spawners[0]; @@ -1705,7 +1719,7 @@ void Entity::CancelCallbackTimers() { void Entity::ScheduleKillAfterUpdate(Entity* murderer) { //if (m_Info.spawner) m_Info.spawner->ScheduleKill(this); - EntityManager::Instance()->ScheduleForKill(this); + Game::entityManager->ScheduleForKill(this); if (murderer) m_ScheduleKiller = murderer; } @@ -1749,7 +1763,7 @@ void Entity::TriggerEvent(eTriggerEventType event, Entity* optionalTarget) { Entity* Entity::GetOwner() const { if (m_OwnerOverride != LWOOBJID_EMPTY) { - auto* other = EntityManager::Instance()->GetEntity(m_OwnerOverride); + auto* other = Game::entityManager->GetEntity(m_OwnerOverride); if (other != nullptr) { return other->GetOwner(); @@ -1813,8 +1827,6 @@ bool Entity::IsSleeping() const { const NiPoint3& Entity::GetPosition() const { - if (!this) return NiPoint3::ZERO; - auto* controllable = GetComponent(); if (controllable != nullptr) { @@ -1895,7 +1907,7 @@ void Entity::SetPosition(NiPoint3 position) { vehicel->SetPosition(position); } - EntityManager::Instance()->SerializeEntity(this); + Game::entityManager->SerializeEntity(this); } void Entity::SetRotation(NiQuaternion rotation) { @@ -1923,7 +1935,7 @@ void Entity::SetRotation(NiQuaternion rotation) { vehicel->SetRotation(rotation); } - EntityManager::Instance()->SerializeEntity(this); + Game::entityManager->SerializeEntity(this); } bool Entity::GetBoolean(const std::u16string& name) const { @@ -1975,7 +1987,7 @@ std::vector& Entity::GetTargetsInPhantom() { for (auto i = 0u; i < m_TargetsInPhantom.size(); ++i) { const auto id = m_TargetsInPhantom.at(i); - auto* entity = EntityManager::Instance()->GetEntity(id); + auto* entity = Game::entityManager->GetEntity(id); if (entity == nullptr) { continue; diff --git a/dGame/Entity.h b/dGame/Entity.h index b980b179..90f2a34f 100644 --- a/dGame/Entity.h +++ b/dGame/Entity.h @@ -207,6 +207,7 @@ public: void OnMessageBoxResponse(Entity* sender, int32_t button, const std::u16string& identifier, const std::u16string& userData); void OnChoiceBoxResponse(Entity* sender, int32_t button, const std::u16string& buttonIdentifier, const std::u16string& identifier); + void RequestActivityExit(Entity* sender, LWOOBJID player, bool canceled); void Smash(const LWOOBJID source = LWOOBJID_EMPTY, const eKillType killType = eKillType::VIOLENT, const std::u16string& deathType = u""); void Kill(Entity* murderer = nullptr); diff --git a/dGame/EntityManager.cpp b/dGame/EntityManager.cpp index 1a77d365..28b5f526 100644 --- a/dGame/EntityManager.cpp +++ b/dGame/EntityManager.cpp @@ -25,8 +25,6 @@ #include "eReplicaComponentType.h" #include "eReplicaPacketType.h" -EntityManager* EntityManager::m_Address = nullptr; - // Configure which zones have ghosting disabled, mostly small worlds. std::vector EntityManager::m_GhostingExcludedZones = { // Small zones @@ -62,7 +60,7 @@ void EntityManager::Initialize() { m_GhostingEnabled = std::find( m_GhostingExcludedZones.begin(), m_GhostingExcludedZones.end(), - dZoneManager::Instance()->GetZoneID().GetMapID() + Game::zoneManager->GetZoneID().GetMapID() ) == m_GhostingExcludedZones.end(); // grab hardcore mode settings and load them with sane defaults @@ -77,10 +75,7 @@ void EntityManager::Initialize() { // If cloneID is not zero, then hardcore mode is disabled // aka minigames and props - if (dZoneManager::Instance()->GetZoneID().GetCloneID() != 0) m_HardcoreMode = false; -} - -EntityManager::~EntityManager() { + if (Game::zoneManager->GetZoneID().GetCloneID() != 0) m_HardcoreMode = false; } Entity* EntityManager::CreateEntity(EntityInfo info, User* user, Entity* parentEntity, const bool controller, const LWOOBJID explicitId) { @@ -161,9 +156,7 @@ void EntityManager::DestroyEntity(const LWOOBJID& objectID) { } void EntityManager::DestroyEntity(Entity* entity) { - if (entity == nullptr) { - return; - } + if (!entity) return; entity->TriggerEvent(eTriggerEventType::DESTROY, entity); @@ -182,15 +175,11 @@ void EntityManager::DestroyEntity(Entity* entity) { ScheduleForDeletion(id); } -void EntityManager::UpdateEntities(const float deltaTime) { - for (const auto& e : m_Entities) { - e.second->Update(deltaTime); - } - +void EntityManager::SerializeEntities() { for (auto entry = m_EntitiesToSerialize.begin(); entry != m_EntitiesToSerialize.end(); entry++) { auto* entity = GetEntity(*entry); - if (entity == nullptr) continue; + if (!entity) continue; m_SerializationCounter++; @@ -212,11 +201,16 @@ void EntityManager::UpdateEntities(const float deltaTime) { } } m_EntitiesToSerialize.clear(); +} +void EntityManager::KillEntities() { for (auto entry = m_EntitiesToKill.begin(); entry != m_EntitiesToKill.end(); entry++) { auto* entity = GetEntity(*entry); - if (!entity) continue; + if (!entity) { + Game::logger->Log("EntityManager", "Attempting to kill null entity %llu", *entry); + continue; + } if (entity->GetScheduledKiller()) { entity->Smash(entity->GetScheduledKiller()->GetObjectID(), eKillType::SILENT); @@ -225,32 +219,41 @@ void EntityManager::UpdateEntities(const float deltaTime) { } } m_EntitiesToKill.clear(); +} +void EntityManager::DeleteEntities() { for (auto entry = m_EntitiesToDelete.begin(); entry != m_EntitiesToDelete.end(); entry++) { - - // Get all this info first before we delete the player. auto entityToDelete = GetEntity(*entry); - auto networkIdToErase = entityToDelete->GetNetworkId(); - const auto& ghostingToDelete = std::find(m_EntitiesToGhost.begin(), m_EntitiesToGhost.end(), entityToDelete); - if (entityToDelete) { - // If we are a player run through the player destructor. - if (entityToDelete->IsPlayer()) { - delete dynamic_cast(entityToDelete); - } else { - delete entityToDelete; - } + // Get all this info first before we delete the player. + auto networkIdToErase = entityToDelete->GetNetworkId(); + const auto& ghostingToDelete = std::find(m_EntitiesToGhost.begin(), m_EntitiesToGhost.end(), entityToDelete); + + delete entityToDelete; + entityToDelete = nullptr; + if (networkIdToErase != 0) m_LostNetworkIds.push(networkIdToErase); + + if (ghostingToDelete != m_EntitiesToGhost.end()) m_EntitiesToGhost.erase(ghostingToDelete); + } else { + Game::logger->Log("EntityManager", "Attempted to delete non-existent entity %llu", *entry); } - - if (ghostingToDelete != m_EntitiesToGhost.end()) m_EntitiesToGhost.erase(ghostingToDelete); - m_Entities.erase(*entry); } m_EntitiesToDelete.clear(); } +void EntityManager::UpdateEntities(const float deltaTime) { + for (const auto& e : m_Entities) { + e.second->Update(deltaTime); + } + + SerializeEntities(); + KillEntities(); + DeleteEntities(); +} + Entity* EntityManager::GetEntity(const LWOOBJID& objectId) const { const auto& index = m_Entities.find(objectId); @@ -316,6 +319,11 @@ const std::unordered_map& EntityManager::GetSpawnPointEnt } void EntityManager::ConstructEntity(Entity* entity, const SystemAddress& sysAddr, const bool skipChecks) { + if (!entity) { + Game::logger->Log("EntityManager", "Attempted to construct null entity"); + return; + } + if (entity->GetNetworkId() == 0) { uint16_t networkId; @@ -395,9 +403,7 @@ void EntityManager::ConstructAllEntities(const SystemAddress& sysAddr) { } void EntityManager::DestructEntity(Entity* entity, const SystemAddress& sysAddr) { - if (entity->GetNetworkId() == 0) { - return; - } + if (!entity || entity->GetNetworkId() == 0) return; RakNet::BitStream stream; @@ -414,9 +420,7 @@ void EntityManager::DestructEntity(Entity* entity, const SystemAddress& sysAddr) } void EntityManager::SerializeEntity(Entity* entity) { - if (entity->GetNetworkId() == 0) { - return; - } + if (!entity || entity->GetNetworkId() == 0) return; if (std::find(m_EntitiesToSerialize.begin(), m_EntitiesToSerialize.end(), entity->GetObjectID()) == m_EntitiesToSerialize.end()) { m_EntitiesToSerialize.push_back(entity->GetObjectID()); diff --git a/dGame/EntityManager.h b/dGame/EntityManager.h index 0314cc09..9bea0618 100644 --- a/dGame/EntityManager.h +++ b/dGame/EntityManager.h @@ -1,12 +1,13 @@ #ifndef ENTITYMANAGER_H #define ENTITYMANAGER_H -#include "dCommonVars.h" #include #include #include #include +#include "dCommonVars.h" + class Entity; class EntityInfo; class Player; @@ -17,19 +18,8 @@ struct SystemAddress; class EntityManager { public: - static EntityManager* Instance() { - if (!m_Address) { - m_Address = new EntityManager(); - m_Address->Initialize(); - } - - return m_Address; - } - void Initialize(); - ~EntityManager(); - void UpdateEntities(float deltaTime); Entity* CreateEntity(EntityInfo info, User* user = nullptr, Entity* parentEntity = nullptr, bool controller = false, LWOOBJID explicitId = LWOOBJID_EMPTY); void DestroyEntity(const LWOOBJID& objectID); @@ -85,7 +75,10 @@ public: const uint32_t GetHardcoreUscoreEnemiesMultiplier() { return m_HardcoreUscoreEnemiesMultiplier; }; private: - static EntityManager* m_Address; //For singleton method + void SerializeEntities(); + void KillEntities(); + void DeleteEntities(); + static std::vector m_GhostingExcludedZones; static std::vector m_GhostingExcludedLOTs; diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index d85a95d4..a4c6ec1a 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -1,5 +1,8 @@ #include "LeaderboardManager.h" + +#include #include + #include "Database.h" #include "EntityManager.h" #include "Character.h" @@ -10,461 +13,400 @@ #include "CDClientManager.h" #include "GeneralUtils.h" #include "Entity.h" +#include "LDFFormat.h" +#include "DluAssert.h" #include "CDActivitiesTable.h" +#include "Metrics.hpp" -Leaderboard::Leaderboard(uint32_t gameID, uint32_t infoType, bool weekly, std::vector entries, - LWOOBJID relatedPlayer, LeaderboardType leaderboardType) { - this->relatedPlayer = relatedPlayer; +namespace LeaderboardManager { + std::map leaderboardCache; +} + +Leaderboard::Leaderboard(const GameID gameID, const Leaderboard::InfoType infoType, const bool weekly, LWOOBJID relatedPlayer, const Leaderboard::Type leaderboardType) { this->gameID = gameID; this->weekly = weekly; this->infoType = infoType; - this->entries = std::move(entries); this->leaderboardType = leaderboardType; + this->relatedPlayer = relatedPlayer; } -std::u16string Leaderboard::ToString() const { - std::string leaderboard; +Leaderboard::~Leaderboard() { + Clear(); +} - leaderboard += "ADO.Result=7:1\n"; - leaderboard += "Result.Count=1:1\n"; - leaderboard += "Result[0].Index=0:RowNumber\n"; - leaderboard += "Result[0].RowCount=1:" + std::to_string(entries.size()) + "\n"; +void Leaderboard::Clear() { + for (auto& entry : entries) for (auto ldfData : entry) delete ldfData; +} - auto index = 0; - for (const auto& entry : entries) { - leaderboard += "Result[0].Row[" + std::to_string(index) + "].LastPlayed=8:" + std::to_string(entry.lastPlayed) + "\n"; - leaderboard += "Result[0].Row[" + std::to_string(index) + "].CharacterID=8:" + std::to_string(entry.playerID) + "\n"; - leaderboard += "Result[0].Row[" + std::to_string(index) + "].NumPlayed=1:1\n"; - leaderboard += "Result[0].Row[" + std::to_string(index) + "].RowNumber=8:" + std::to_string(entry.placement) + "\n"; - leaderboard += "Result[0].Row[" + std::to_string(index) + "].Time=1:" + std::to_string(entry.time) + "\n"; +inline void WriteLeaderboardRow(std::ostringstream& leaderboard, const uint32_t& index, LDFBaseData* data) { + leaderboard << "\nResult[0].Row[" << index << "]." << data->GetString(); +} - // Only these minigames have a points system - if (leaderboardType == Survival || leaderboardType == ShootingGallery) { - leaderboard += "Result[0].Row[" + std::to_string(index) + "].Points=1:" + std::to_string(entry.score) + "\n"; - } else if (leaderboardType == SurvivalNS) { - leaderboard += "Result[0].Row[" + std::to_string(index) + "].Wave=1:" + std::to_string(entry.score) + "\n"; +void Leaderboard::Serialize(RakNet::BitStream* bitStream) const { + bitStream->Write(gameID); + bitStream->Write(infoType); + + std::ostringstream leaderboard; + + leaderboard << "ADO.Result=7:1"; // Unused in 1.10.64, but is in captures + leaderboard << "\nResult.Count=1:1"; // number of results, always 1 + if (!this->entries.empty()) leaderboard << "\nResult[0].Index=0:RowNumber"; // "Primary key". Live doesn't include this if there are no entries. + leaderboard << "\nResult[0].RowCount=1:" << entries.size(); + + int32_t rowNumber = 0; + for (auto& entry : entries) { + for (auto* data : entry) { + WriteLeaderboardRow(leaderboard, rowNumber, data); } - - leaderboard += "Result[0].Row[" + std::to_string(index) + "].name=0:" + entry.playerName + "\n"; - index++; + rowNumber++; } - return GeneralUtils::UTF8ToUTF16(leaderboard); + // Serialize the thing to a BitStream + uint32_t leaderboardSize = leaderboard.tellp(); + bitStream->Write(leaderboardSize); + // Doing this all in 1 call so there is no possbility of a dangling pointer. + bitStream->WriteAlignedBytes(reinterpret_cast(GeneralUtils::ASCIIToUTF16(leaderboard.str()).c_str()), leaderboardSize * sizeof(char16_t)); + if (leaderboardSize > 0) bitStream->Write(0); + bitStream->Write0(); + bitStream->Write0(); } -std::vector Leaderboard::GetEntries() { - return entries; +void Leaderboard::QueryToLdf(std::unique_ptr& rows) { + Clear(); + if (rows->rowsCount() == 0) return; + + this->entries.reserve(rows->rowsCount()); + while (rows->next()) { + constexpr int32_t MAX_NUM_DATA_PER_ROW = 9; + this->entries.push_back(std::vector()); + auto& entry = this->entries.back(); + entry.reserve(MAX_NUM_DATA_PER_ROW); + entry.push_back(new LDFData(u"CharacterID", rows->getInt("character_id"))); + entry.push_back(new LDFData(u"LastPlayed", rows->getUInt64("lastPlayed"))); + entry.push_back(new LDFData(u"NumPlayed", rows->getInt("timesPlayed"))); + entry.push_back(new LDFData(u"name", GeneralUtils::ASCIIToUTF16(rows->getString("name").c_str()))); + entry.push_back(new LDFData(u"RowNumber", rows->getInt("ranking"))); + switch (leaderboardType) { + case Type::ShootingGallery: + entry.push_back(new LDFData(u"Score", rows->getInt("primaryScore"))); + // Score:1 + entry.push_back(new LDFData(u"Streak", rows->getInt("secondaryScore"))); + // Streak:1 + entry.push_back(new LDFData(u"HitPercentage", (rows->getInt("tertiaryScore") / 100.0f))); + // HitPercentage:3 between 0 and 1 + break; + case Type::Racing: + entry.push_back(new LDFData(u"BestTime", rows->getDouble("primaryScore"))); + // BestLapTime:3 + entry.push_back(new LDFData(u"BestLapTime", rows->getDouble("secondaryScore"))); + // BestTime:3 + entry.push_back(new LDFData(u"License", 1)); + // License:1 - 1 if player has completed mission 637 and 0 otherwise + entry.push_back(new LDFData(u"NumWins", rows->getInt("numWins"))); + // NumWins:1 + break; + case Type::UnusedLeaderboard4: + entry.push_back(new LDFData(u"Points", rows->getInt("primaryScore"))); + // Points:1 + break; + case Type::MonumentRace: + entry.push_back(new LDFData(u"Time", rows->getInt("primaryScore"))); + // Time:1(?) + break; + case Type::FootRace: + entry.push_back(new LDFData(u"Time", rows->getInt("primaryScore"))); + // Time:1 + break; + case Type::Survival: + entry.push_back(new LDFData(u"Points", rows->getInt("primaryScore"))); + // Points:1 + entry.push_back(new LDFData(u"Time", rows->getInt("secondaryScore"))); + // Time:1 + break; + case Type::SurvivalNS: + entry.push_back(new LDFData(u"Wave", rows->getInt("primaryScore"))); + // Wave:1 + entry.push_back(new LDFData(u"Time", rows->getInt("secondaryScore"))); + // Time:1 + break; + case Type::Donations: + entry.push_back(new LDFData(u"Points", rows->getInt("primaryScore"))); + // Score:1 + break; + case Type::None: + // This type is included here simply to resolve a compiler warning on mac about unused enum types + break; + default: + break; + } + } } -uint32_t Leaderboard::GetGameID() const { - return gameID; +const std::string_view Leaderboard::GetOrdering(Leaderboard::Type leaderboardType) { + // Use a switch case and return desc for all 3 columns if higher is better and asc if lower is better + switch (leaderboardType) { + case Type::Racing: + case Type::MonumentRace: + return "primaryScore ASC, secondaryScore ASC, tertiaryScore ASC"; + case Type::Survival: + return Game::config->GetValue("classic_survival_scoring") == "1" ? + "secondaryScore DESC, primaryScore DESC, tertiaryScore DESC" : + "primaryScore DESC, secondaryScore DESC, tertiaryScore DESC"; + case Type::SurvivalNS: + return "primaryScore DESC, secondaryScore ASC, tertiaryScore DESC"; + case Type::ShootingGallery: + case Type::FootRace: + case Type::UnusedLeaderboard4: + case Type::Donations: + case Type::None: + default: + return "primaryScore DESC, secondaryScore DESC, tertiaryScore DESC"; + } } -uint32_t Leaderboard::GetInfoType() const { - return infoType; +void Leaderboard::SetupLeaderboard(bool weekly, uint32_t resultStart, uint32_t resultEnd) { + resultStart++; + resultEnd++; + // We need everything except 1 column so i'm selecting * from leaderboard + const std::string queryBase = + R"QUERY( + WITH leaderboardsRanked AS ( + SELECT leaderboard.*, charinfo.name, + RANK() OVER + ( + ORDER BY %s, UNIX_TIMESTAMP(last_played) ASC, id DESC + ) AS ranking + FROM leaderboard JOIN charinfo on charinfo.id = leaderboard.character_id + WHERE game_id = ? %s + ), + myStanding AS ( + SELECT + ranking as myRank + FROM leaderboardsRanked + WHERE id = ? + ), + lowestRanking AS ( + SELECT MAX(ranking) AS lowestRank + FROM leaderboardsRanked + ) + SELECT leaderboardsRanked.*, character_id, UNIX_TIMESTAMP(last_played) as lastPlayed, leaderboardsRanked.name, leaderboardsRanked.ranking FROM leaderboardsRanked, myStanding, lowestRanking + WHERE leaderboardsRanked.ranking + BETWEEN + LEAST(GREATEST(CAST(myRank AS SIGNED) - 5, %i), lowestRanking.lowestRank - 9) + AND + LEAST(GREATEST(myRank + 5, %i), lowestRanking.lowestRank) + ORDER BY ranking ASC; + )QUERY"; + + std::string friendsFilter = + R"QUERY( + AND ( + character_id IN ( + SELECT fr.requested_player FROM ( + SELECT CASE + WHEN player_id = ? THEN friend_id + WHEN friend_id = ? THEN player_id + END AS requested_player + FROM friends + ) AS fr + JOIN charinfo AS ci + ON ci.id = fr.requested_player + WHERE fr.requested_player IS NOT NULL + ) + OR character_id = ? + ) + )QUERY"; + + std::string weeklyFilter = " AND UNIX_TIMESTAMP(last_played) BETWEEN UNIX_TIMESTAMP(date_sub(now(),INTERVAL 1 WEEK)) AND UNIX_TIMESTAMP(now()) "; + + std::string filter; + // Setup our filter based on the query type + if (this->infoType == InfoType::Friends) filter += friendsFilter; + if (this->weekly) filter += weeklyFilter; + const auto orderBase = GetOrdering(this->leaderboardType); + + // For top query, we want to just rank all scores, but for all others we need the scores around a specific player + std::string baseLookup; + if (this->infoType == InfoType::Top) { + baseLookup = "SELECT id, last_played FROM leaderboard WHERE game_id = ? " + (this->weekly ? weeklyFilter : std::string("")) + " ORDER BY "; + baseLookup += orderBase.data(); + } else { + baseLookup = "SELECT id, last_played FROM leaderboard WHERE game_id = ? " + (this->weekly ? weeklyFilter : std::string("")) + " AND character_id = "; + baseLookup += std::to_string(static_cast(this->relatedPlayer)); + } + baseLookup += " LIMIT 1"; + Game::logger->LogDebug("LeaderboardManager", "query is %s", baseLookup.c_str()); + std::unique_ptr baseQuery(Database::CreatePreppedStmt(baseLookup)); + baseQuery->setInt(1, this->gameID); + std::unique_ptr baseResult(baseQuery->executeQuery()); + + if (!baseResult->next()) return; // In this case, there are no entries in the leaderboard for this game. + + uint32_t relatedPlayerLeaderboardId = baseResult->getInt("id"); + + // Create and execute the actual save here. Using a heap allocated buffer to avoid stack overflow + constexpr uint16_t STRING_LENGTH = 4096; + std::unique_ptr lookupBuffer = std::make_unique(STRING_LENGTH); + int32_t res = snprintf(lookupBuffer.get(), STRING_LENGTH, queryBase.c_str(), orderBase.data(), filter.c_str(), resultStart, resultEnd); + DluAssert(res != -1); + std::unique_ptr query(Database::CreatePreppedStmt(lookupBuffer.get())); + Game::logger->LogDebug("LeaderboardManager", "Query is %s vars are %i %i %i", lookupBuffer.get(), this->gameID, this->relatedPlayer, relatedPlayerLeaderboardId); + query->setInt(1, this->gameID); + if (this->infoType == InfoType::Friends) { + query->setInt(2, this->relatedPlayer); + query->setInt(3, this->relatedPlayer); + query->setInt(4, this->relatedPlayer); + query->setInt(5, relatedPlayerLeaderboardId); + } else { + query->setInt(2, relatedPlayerLeaderboardId); + } + std::unique_ptr result(query->executeQuery()); + QueryToLdf(result); } -void Leaderboard::Send(LWOOBJID targetID) const { - auto* player = EntityManager::Instance()->GetEntity(relatedPlayer); +void Leaderboard::Send(const LWOOBJID targetID) const { + auto* player = Game::entityManager->GetEntity(relatedPlayer); if (player != nullptr) { GameMessages::SendActivitySummaryLeaderboardData(targetID, this, player->GetSystemAddress()); } } -void LeaderboardManager::SaveScore(LWOOBJID playerID, uint32_t gameID, uint32_t score, uint32_t time) { - const auto* player = EntityManager::Instance()->GetEntity(playerID); - if (player == nullptr) - return; +std::string FormatInsert(const Leaderboard::Type& type, const Score& score, const bool useUpdate) { + std::string insertStatement; + if (useUpdate) { + insertStatement = + R"QUERY( + UPDATE leaderboard + SET primaryScore = %f, secondaryScore = %f, tertiaryScore = %f, + timesPlayed = timesPlayed + 1 WHERE character_id = ? AND game_id = ?; + )QUERY"; + } else { + insertStatement = + R"QUERY( + INSERT leaderboard SET + primaryScore = %f, secondaryScore = %f, tertiaryScore = %f, + character_id = ?, game_id = ?; + )QUERY"; + } - auto* character = player->GetCharacter(); - if (character == nullptr) - return; + constexpr uint16_t STRING_LENGTH = 400; + // Then fill in our score + char finishedQuery[STRING_LENGTH]; + int32_t res = snprintf(finishedQuery, STRING_LENGTH, insertStatement.c_str(), score.GetPrimaryScore(), score.GetSecondaryScore(), score.GetTertiaryScore()); + DluAssert(res != -1); + return finishedQuery; +} - auto* select = Database::CreatePreppedStmt("SELECT time, score FROM leaderboard WHERE character_id = ? AND game_id = ?;"); +void LeaderboardManager::SaveScore(const LWOOBJID& playerID, const GameID activityId, const float primaryScore, const float secondaryScore, const float tertiaryScore) { + const Leaderboard::Type leaderboardType = GetLeaderboardType(activityId); + auto* lookup = "SELECT * FROM leaderboard WHERE character_id = ? AND game_id = ?;"; - select->setUInt64(1, character->GetID()); - select->setInt(2, gameID); - - auto any = false; - auto* result = select->executeQuery(); - auto leaderboardType = GetLeaderboardType(gameID); - - // Check if the new score is a high score - while (result->next()) { - any = true; - - const auto storedTime = result->getInt(1); - const auto storedScore = result->getInt(2); - auto highscore = true; - bool classicSurvivalScoring = Game::config->GetValue("classic_survival_scoring") == "1"; + std::unique_ptr query(Database::CreatePreppedStmt(lookup)); + query->setInt(1, playerID); + query->setInt(2, activityId); + std::unique_ptr myScoreResult(query->executeQuery()); + std::string saveQuery("UPDATE leaderboard SET timesPlayed = timesPlayed + 1 WHERE character_id = ? AND game_id = ?;"); + Score newScore(primaryScore, secondaryScore, tertiaryScore); + if (myScoreResult->next()) { + Score oldScore; + bool lowerScoreBetter = false; switch (leaderboardType) { - case ShootingGallery: - if (score <= storedScore) - highscore = false; + // Higher score better + case Leaderboard::Type::ShootingGallery: { + oldScore.SetPrimaryScore(myScoreResult->getInt("primaryScore")); + oldScore.SetSecondaryScore(myScoreResult->getInt("secondaryScore")); + oldScore.SetTertiaryScore(myScoreResult->getInt("tertiaryScore")); break; - case Racing: - if (time >= storedTime) - highscore = false; - break; - case MonumentRace: - if (time >= storedTime) - highscore = false; - break; - case FootRace: - if (time <= storedTime) - highscore = false; - break; - case Survival: - if (classicSurvivalScoring) { - if (time <= storedTime) { // Based on time (LU live) - highscore = false; - } - } else { - if (score <= storedScore) // Based on score (DLU) - highscore = false; - } - break; - case SurvivalNS: - if (!(score > storedScore || (time < storedTime && score >= storedScore))) - highscore = false; - break; - default: - highscore = false; } + case Leaderboard::Type::FootRace: { + oldScore.SetPrimaryScore(myScoreResult->getInt("primaryScore")); + break; + } + case Leaderboard::Type::Survival: { + oldScore.SetPrimaryScore(myScoreResult->getInt("primaryScore")); + oldScore.SetSecondaryScore(myScoreResult->getInt("secondaryScore")); + break; + } + case Leaderboard::Type::SurvivalNS: { + oldScore.SetPrimaryScore(myScoreResult->getInt("primaryScore")); + oldScore.SetSecondaryScore(myScoreResult->getInt("secondaryScore")); + break; + } + case Leaderboard::Type::UnusedLeaderboard4: + case Leaderboard::Type::Donations: { + oldScore.SetPrimaryScore(myScoreResult->getInt("primaryScore")); + break; + } + case Leaderboard::Type::Racing: { + oldScore.SetPrimaryScore(myScoreResult->getInt("primaryScore")); + oldScore.SetSecondaryScore(myScoreResult->getInt("secondaryScore")); - if (!highscore) { - delete select; - delete result; + // For wins we dont care about the score, just the time, so zero out the tertiary. + // Wins are updated later. + oldScore.SetTertiaryScore(0); + newScore.SetTertiaryScore(0); + lowerScoreBetter = true; + break; + } + case Leaderboard::Type::MonumentRace: { + oldScore.SetPrimaryScore(myScoreResult->getInt("primaryScore")); + lowerScoreBetter = true; + // Do score checking here + break; + } + case Leaderboard::Type::None: + default: + Game::logger->Log("LeaderboardManager", "Unknown leaderboard type %i for game %i. Cannot save score!", leaderboardType, activityId); return; } - } - - delete select; - delete result; - - if (any) { - auto* statement = Database::CreatePreppedStmt("UPDATE leaderboard SET time = ?, score = ?, last_played=SYSDATE() WHERE character_id = ? AND game_id = ?;"); - statement->setInt(1, time); - statement->setInt(2, score); - statement->setUInt64(3, character->GetID()); - statement->setInt(4, gameID); - statement->execute(); - - delete statement; + bool newHighScore = lowerScoreBetter ? newScore < oldScore : newScore > oldScore; + // Nimbus station has a weird leaderboard where we need a custom scoring system + if (leaderboardType == Leaderboard::Type::SurvivalNS) { + newHighScore = newScore.GetPrimaryScore() > oldScore.GetPrimaryScore() || + (newScore.GetPrimaryScore() == oldScore.GetPrimaryScore() && newScore.GetSecondaryScore() < oldScore.GetSecondaryScore()); + } else if (leaderboardType == Leaderboard::Type::Survival && Game::config->GetValue("classic_survival_scoring") == "1") { + Score oldScoreFlipped(oldScore.GetSecondaryScore(), oldScore.GetPrimaryScore()); + Score newScoreFlipped(newScore.GetSecondaryScore(), newScore.GetPrimaryScore()); + newHighScore = newScoreFlipped > oldScoreFlipped; + } + if (newHighScore) { + saveQuery = FormatInsert(leaderboardType, newScore, true); + } } else { - // Note: last_played will be set to SYSDATE() by default when inserting into leaderboard - auto* statement = Database::CreatePreppedStmt("INSERT INTO leaderboard (character_id, game_id, time, score) VALUES (?, ?, ?, ?);"); - statement->setUInt64(1, character->GetID()); - statement->setInt(2, gameID); - statement->setInt(3, time); - statement->setInt(4, score); - statement->execute(); - - delete statement; + saveQuery = FormatInsert(leaderboardType, newScore, false); + } + Game::logger->Log("LeaderboardManager", "save query %s %i %i", saveQuery.c_str(), playerID, activityId); + std::unique_ptr saveStatement(Database::CreatePreppedStmt(saveQuery)); + saveStatement->setInt(1, playerID); + saveStatement->setInt(2, activityId); + saveStatement->execute(); + + // track wins separately + if (leaderboardType == Leaderboard::Type::Racing && tertiaryScore != 0.0f) { + std::unique_ptr winUpdate(Database::CreatePreppedStmt("UPDATE leaderboard SET numWins = numWins + 1 WHERE character_id = ? AND game_id = ?;")); + winUpdate->setInt(1, playerID); + winUpdate->setInt(2, activityId); + winUpdate->execute(); } } -Leaderboard* LeaderboardManager::GetLeaderboard(uint32_t gameID, InfoType infoType, bool weekly, LWOOBJID playerID) { - auto leaderboardType = GetLeaderboardType(gameID); - - std::string query; - bool classicSurvivalScoring = Game::config->GetValue("classic_survival_scoring") == "1"; - switch (infoType) { - case InfoType::Standings: - switch (leaderboardType) { - case ShootingGallery: - query = standingsScoreQuery; // Shooting gallery is based on the highest score. - break; - case FootRace: - query = standingsTimeQuery; // The higher your time, the better for FootRace. - break; - case Survival: - query = classicSurvivalScoring ? standingsTimeQuery : standingsScoreQuery; - break; - case SurvivalNS: - query = standingsScoreQueryAsc; // BoNS is scored by highest wave (score) first, then time. - break; - default: - query = standingsTimeQueryAsc; // MonumentRace and Racing are based on the shortest time. - } - break; - case InfoType::Friends: - switch (leaderboardType) { - case ShootingGallery: - query = friendsScoreQuery; // Shooting gallery is based on the highest score. - break; - case FootRace: - query = friendsTimeQuery; // The higher your time, the better for FootRace. - break; - case Survival: - query = classicSurvivalScoring ? friendsTimeQuery : friendsScoreQuery; - break; - case SurvivalNS: - query = friendsScoreQueryAsc; // BoNS is scored by highest wave (score) first, then time. - break; - default: - query = friendsTimeQueryAsc; // MonumentRace and Racing are based on the shortest time. - } - break; - - default: - switch (leaderboardType) { - case ShootingGallery: - query = topPlayersScoreQuery; // Shooting gallery is based on the highest score. - break; - case FootRace: - query = topPlayersTimeQuery; // The higher your time, the better for FootRace. - break; - case Survival: - query = classicSurvivalScoring ? topPlayersTimeQuery : topPlayersScoreQuery; - break; - case SurvivalNS: - query = topPlayersScoreQueryAsc; // BoNS is scored by highest wave (score) first, then time. - break; - default: - query = topPlayersTimeQueryAsc; // MonumentRace and Racing are based on the shortest time. - } - } - - auto* statement = Database::CreatePreppedStmt(query); - statement->setUInt(1, gameID); - - // Only the standings and friends leaderboards require the character ID to be set - if (infoType == Standings || infoType == Friends) { - auto characterID = 0; - - const auto* player = EntityManager::Instance()->GetEntity(playerID); - if (player != nullptr) { - auto* character = player->GetCharacter(); - if (character != nullptr) - characterID = character->GetID(); - } - - statement->setUInt64(2, characterID); - } - - auto* res = statement->executeQuery(); - - std::vector entries{}; - - uint32_t index = 0; - while (res->next()) { - LeaderboardEntry entry; - entry.playerID = res->getUInt64(4); - entry.playerName = res->getString(5); - entry.time = res->getUInt(1); - entry.score = res->getUInt(2); - entry.placement = res->getUInt(3); - entry.lastPlayed = res->getUInt(6); - - entries.push_back(entry); - index++; - } - - delete res; - delete statement; - - return new Leaderboard(gameID, infoType, weekly, entries, playerID, leaderboardType); +void LeaderboardManager::SendLeaderboard(const GameID gameID, const Leaderboard::InfoType infoType, const bool weekly, const LWOOBJID playerID, const LWOOBJID targetID, const uint32_t resultStart, const uint32_t resultEnd) { + Leaderboard leaderboard(gameID, infoType, weekly, playerID, GetLeaderboardType(gameID)); + leaderboard.SetupLeaderboard(weekly, resultStart, resultEnd); + leaderboard.Send(targetID); } -void LeaderboardManager::SendLeaderboard(uint32_t gameID, InfoType infoType, bool weekly, LWOOBJID targetID, - LWOOBJID playerID) { - const auto* leaderboard = LeaderboardManager::GetLeaderboard(gameID, infoType, weekly, playerID); - leaderboard->Send(targetID); - delete leaderboard; -} +Leaderboard::Type LeaderboardManager::GetLeaderboardType(const GameID gameID) { + auto lookup = leaderboardCache.find(gameID); + if (lookup != leaderboardCache.end()) return lookup->second; -LeaderboardType LeaderboardManager::GetLeaderboardType(uint32_t gameID) { auto* activitiesTable = CDClientManager::Instance().GetTable(); - std::vector activities = activitiesTable->Query([=](const CDActivities& entry) { - return (entry.ActivityID == gameID); + std::vector activities = activitiesTable->Query([gameID](const CDActivities& entry) { + return entry.ActivityID == gameID; }); - - for (const auto& activity : activities) { - return static_cast(activity.leaderboardType); - } - - return LeaderboardType::None; + auto type = !activities.empty() ? static_cast(activities.at(0).leaderboardType) : Leaderboard::Type::None; + leaderboardCache.insert_or_assign(gameID, type); + return type; } - -const std::string LeaderboardManager::topPlayersScoreQuery = -"WITH leaderboard_vales AS ( " -" SELECT l.time, l.score, UNIX_TIMESTAMP(l.last_played) last_played, c.name, c.id, " -"RANK() OVER ( ORDER BY l.score DESC, l.time DESC, last_played ) leaderboard_rank " -" FROM leaderboard l " -"INNER JOIN charinfo c ON l.character_id = c.id " -"WHERE l.game_id = ? " -"ORDER BY leaderboard_rank) " -"SELECT time, score, leaderboard_rank, id, name, last_played " -"FROM leaderboard_vales LIMIT 11;"; - -const std::string LeaderboardManager::friendsScoreQuery = -"WITH leaderboard_vales AS ( " -" SELECT l.time, l.score, UNIX_TIMESTAMP(l.last_played) last_played, c.name, c.id, f.friend_id, f.player_id, " -" RANK() OVER ( ORDER BY l.score DESC, l.time DESC, last_played ) leaderboard_rank " -" FROM leaderboard l " -" INNER JOIN charinfo c ON l.character_id = c.id " -" INNER JOIN friends f ON f.player_id = c.id " -" WHERE l.game_id = ? " -" ORDER BY leaderboard_rank), " -" personal_values AS ( " -" SELECT id as related_player_id, " -" GREATEST(CAST(leaderboard_rank AS SIGNED) - 5, 1) AS min_rank, " -" GREATEST(leaderboard_rank + 5, 11) AS max_rank " -" FROM leaderboard_vales WHERE leaderboard_vales.id = ? LIMIT 1) " -"SELECT time, score, leaderboard_rank, id, name, last_played " -"FROM leaderboard_vales, personal_values " -"WHERE leaderboard_rank BETWEEN min_rank AND max_rank AND (player_id = related_player_id OR friend_id = related_player_id);"; - -const std::string LeaderboardManager::standingsScoreQuery = -"WITH leaderboard_vales AS ( " -" SELECT l.time, l.score, UNIX_TIMESTAMP(l.last_played) last_played, c.name, c.id, " -" RANK() OVER ( ORDER BY l.score DESC, l.time DESC, last_played ) leaderboard_rank " -" FROM leaderboard l " -" INNER JOIN charinfo c ON l.character_id = c.id " -" WHERE l.game_id = ? " -" ORDER BY leaderboard_rank), " -"personal_values AS ( " -" SELECT GREATEST(CAST(leaderboard_rank AS SIGNED) - 5, 1) AS min_rank, " -" GREATEST(leaderboard_rank + 5, 11) AS max_rank " -" FROM leaderboard_vales WHERE id = ? LIMIT 1) " -"SELECT time, score, leaderboard_rank, id, name, last_played " -"FROM leaderboard_vales, personal_values " -"WHERE leaderboard_rank BETWEEN min_rank AND max_rank;"; - -const std::string LeaderboardManager::topPlayersScoreQueryAsc = -"WITH leaderboard_vales AS ( " -" SELECT l.time, l.score, UNIX_TIMESTAMP(l.last_played) last_played, c.name, c.id, " -"RANK() OVER ( ORDER BY l.score DESC, l.time ASC, last_played ) leaderboard_rank " -" FROM leaderboard l " -"INNER JOIN charinfo c ON l.character_id = c.id " -"WHERE l.game_id = ? " -"ORDER BY leaderboard_rank) " -"SELECT time, score, leaderboard_rank, id, name, last_played " -"FROM leaderboard_vales LIMIT 11;"; - -const std::string LeaderboardManager::friendsScoreQueryAsc = -"WITH leaderboard_vales AS ( " -" SELECT l.time, l.score, UNIX_TIMESTAMP(l.last_played) last_played, c.name, c.id, f.friend_id, f.player_id, " -" RANK() OVER ( ORDER BY l.score DESC, l.time ASC, last_played ) leaderboard_rank " -" FROM leaderboard l " -" INNER JOIN charinfo c ON l.character_id = c.id " -" INNER JOIN friends f ON f.player_id = c.id " -" WHERE l.game_id = ? " -" ORDER BY leaderboard_rank), " -" personal_values AS ( " -" SELECT id as related_player_id, " -" GREATEST(CAST(leaderboard_rank AS SIGNED) - 5, 1) AS min_rank, " -" GREATEST(leaderboard_rank + 5, 11) AS max_rank " -" FROM leaderboard_vales WHERE leaderboard_vales.id = ? LIMIT 1) " -"SELECT time, score, leaderboard_rank, id, name, last_played " -"FROM leaderboard_vales, personal_values " -"WHERE leaderboard_rank BETWEEN min_rank AND max_rank AND (player_id = related_player_id OR friend_id = related_player_id);"; - -const std::string LeaderboardManager::standingsScoreQueryAsc = -"WITH leaderboard_vales AS ( " -" SELECT l.time, l.score, UNIX_TIMESTAMP(l.last_played) last_played, c.name, c.id, " -" RANK() OVER ( ORDER BY l.score DESC, l.time ASC, last_played ) leaderboard_rank " -" FROM leaderboard l " -" INNER JOIN charinfo c ON l.character_id = c.id " -" WHERE l.game_id = ? " -" ORDER BY leaderboard_rank), " -"personal_values AS ( " -" SELECT GREATEST(CAST(leaderboard_rank AS SIGNED) - 5, 1) AS min_rank, " -" GREATEST(leaderboard_rank + 5, 11) AS max_rank " -" FROM leaderboard_vales WHERE id = ? LIMIT 1) " -"SELECT time, score, leaderboard_rank, id, name, last_played " -"FROM leaderboard_vales, personal_values " -"WHERE leaderboard_rank BETWEEN min_rank AND max_rank;"; - -const std::string LeaderboardManager::topPlayersTimeQuery = -"WITH leaderboard_vales AS ( " -" SELECT l.time, l.score, UNIX_TIMESTAMP(l.last_played) last_played, c.name, c.id, " -"RANK() OVER ( ORDER BY l.time DESC, l.score DESC, last_played ) leaderboard_rank " -" FROM leaderboard l " -"INNER JOIN charinfo c ON l.character_id = c.id " -"WHERE l.game_id = ? " -"ORDER BY leaderboard_rank) " -"SELECT time, score, leaderboard_rank, id, name, last_played " -"FROM leaderboard_vales LIMIT 11;"; - -const std::string LeaderboardManager::friendsTimeQuery = -"WITH leaderboard_vales AS ( " -" SELECT l.time, l.score, UNIX_TIMESTAMP(l.last_played) last_played, c.name, c.id, f.friend_id, f.player_id, " -" RANK() OVER ( ORDER BY l.time DESC, l.score DESC, last_played ) leaderboard_rank " -" FROM leaderboard l " -" INNER JOIN charinfo c ON l.character_id = c.id " -" INNER JOIN friends f ON f.player_id = c.id " -" WHERE l.game_id = ? " -" ORDER BY leaderboard_rank), " -" personal_values AS ( " -" SELECT id as related_player_id, " -" GREATEST(CAST(leaderboard_rank AS SIGNED) - 5, 1) AS min_rank, " -" GREATEST(leaderboard_rank + 5, 11) AS max_rank " -" FROM leaderboard_vales WHERE leaderboard_vales.id = ? LIMIT 1) " -"SELECT time, score, leaderboard_rank, id, name, last_played " -"FROM leaderboard_vales, personal_values " -"WHERE leaderboard_rank BETWEEN min_rank AND max_rank AND (player_id = related_player_id OR friend_id = related_player_id);"; - -const std::string LeaderboardManager::standingsTimeQuery = -"WITH leaderboard_vales AS ( " -" SELECT l.time, l.score, UNIX_TIMESTAMP(l.last_played) last_played, c.name, c.id, " -" RANK() OVER ( ORDER BY l.time DESC, l.score DESC, last_played ) leaderboard_rank " -" FROM leaderboard l " -" INNER JOIN charinfo c ON l.character_id = c.id " -" WHERE l.game_id = ? " -" ORDER BY leaderboard_rank), " -"personal_values AS ( " -" SELECT GREATEST(CAST(leaderboard_rank AS SIGNED) - 5, 1) AS min_rank, " -" GREATEST(leaderboard_rank + 5, 11) AS max_rank " -" FROM leaderboard_vales WHERE id = ? LIMIT 1) " -"SELECT time, score, leaderboard_rank, id, name, last_played " -"FROM leaderboard_vales, personal_values " -"WHERE leaderboard_rank BETWEEN min_rank AND max_rank;"; - -const std::string LeaderboardManager::topPlayersTimeQueryAsc = -"WITH leaderboard_vales AS ( " -" SELECT l.time, l.score, UNIX_TIMESTAMP(l.last_played) last_played, c.name, c.id, " -"RANK() OVER ( ORDER BY l.time ASC, l.score DESC, last_played ) leaderboard_rank " -" FROM leaderboard l " -"INNER JOIN charinfo c ON l.character_id = c.id " -"WHERE l.game_id = ? " -"ORDER BY leaderboard_rank) " -"SELECT time, score, leaderboard_rank, id, name, last_played " -"FROM leaderboard_vales LIMIT 11;"; - -const std::string LeaderboardManager::friendsTimeQueryAsc = -"WITH leaderboard_vales AS ( " -" SELECT l.time, l.score, UNIX_TIMESTAMP(l.last_played) last_played, c.name, c.id, f.friend_id, f.player_id, " -" RANK() OVER ( ORDER BY l.time ASC, l.score DESC, last_played ) leaderboard_rank " -" FROM leaderboard l " -" INNER JOIN charinfo c ON l.character_id = c.id " -" INNER JOIN friends f ON f.player_id = c.id " -" WHERE l.game_id = ? " -" ORDER BY leaderboard_rank), " -" personal_values AS ( " -" SELECT id as related_player_id, " -" GREATEST(CAST(leaderboard_rank AS SIGNED) - 5, 1) AS min_rank, " -" GREATEST(leaderboard_rank + 5, 11) AS max_rank " -" FROM leaderboard_vales WHERE leaderboard_vales.id = ? LIMIT 1) " -"SELECT time, score, leaderboard_rank, id, name, last_played " -"FROM leaderboard_vales, personal_values " -"WHERE leaderboard_rank BETWEEN min_rank AND max_rank AND (player_id = related_player_id OR friend_id = related_player_id);"; - -const std::string LeaderboardManager::standingsTimeQueryAsc = -"WITH leaderboard_vales AS ( " -" SELECT l.time, l.score, UNIX_TIMESTAMP(l.last_played) last_played, c.name, c.id, " -" RANK() OVER ( ORDER BY l.time ASC, l.score DESC, last_played ) leaderboard_rank " -" FROM leaderboard l " -" INNER JOIN charinfo c ON l.character_id = c.id " -" WHERE l.game_id = ? " -" ORDER BY leaderboard_rank), " -"personal_values AS ( " -" SELECT GREATEST(CAST(leaderboard_rank AS SIGNED) - 5, 1) AS min_rank, " -" GREATEST(leaderboard_rank + 5, 11) AS max_rank " -" FROM leaderboard_vales WHERE id = ? LIMIT 1) " -"SELECT time, score, leaderboard_rank, id, name, last_played " -"FROM leaderboard_vales, personal_values " -"WHERE leaderboard_rank BETWEEN min_rank AND max_rank;"; diff --git a/dGame/LeaderboardManager.h b/dGame/LeaderboardManager.h index cabdf2d6..e2ce3f97 100644 --- a/dGame/LeaderboardManager.h +++ b/dGame/LeaderboardManager.h @@ -1,80 +1,134 @@ -#pragma once +#ifndef __LEADERBOARDMANAGER__H__ +#define __LEADERBOARDMANAGER__H__ + +#include +#include +#include #include -#include + +#include "Singleton.h" #include "dCommonVars.h" +#include "LDFFormat.h" -struct LeaderboardEntry { - uint64_t playerID; - std::string playerName; - uint32_t time; - uint32_t score; - uint32_t placement; - time_t lastPlayed; +namespace sql { + class ResultSet; }; -enum InfoType : uint32_t { - Top, // Top 11 all time players - Standings, // Ranking of the current player - Friends // Ranking between friends +namespace RakNet { + class BitStream; }; -enum LeaderboardType : uint32_t { - ShootingGallery, - Racing, - MonumentRace, - FootRace, - Survival = 5, - SurvivalNS = 6, - None = UINT_MAX +class Score { +public: + Score() { + primaryScore = 0; + secondaryScore = 0; + tertiaryScore = 0; + } + Score(const float primaryScore, const float secondaryScore = 0, const float tertiaryScore = 0) { + this->primaryScore = primaryScore; + this->secondaryScore = secondaryScore; + this->tertiaryScore = tertiaryScore; + } + bool operator<(const Score& rhs) const { + return primaryScore < rhs.primaryScore || (primaryScore == rhs.primaryScore && secondaryScore < rhs.secondaryScore) || (primaryScore == rhs.primaryScore && secondaryScore == rhs.secondaryScore && tertiaryScore < rhs.tertiaryScore); + } + bool operator>(const Score& rhs) const { + return primaryScore > rhs.primaryScore || (primaryScore == rhs.primaryScore && secondaryScore > rhs.secondaryScore) || (primaryScore == rhs.primaryScore && secondaryScore == rhs.secondaryScore && tertiaryScore > rhs.tertiaryScore); + } + void SetPrimaryScore(const float score) { primaryScore = score; } + float GetPrimaryScore() const { return primaryScore; } + + void SetSecondaryScore(const float score) { secondaryScore = score; } + float GetSecondaryScore() const { return secondaryScore; } + + void SetTertiaryScore(const float score) { tertiaryScore = score; } + float GetTertiaryScore() const { return tertiaryScore; } +private: + float primaryScore; + float secondaryScore; + float tertiaryScore; }; +using GameID = uint32_t; + class Leaderboard { public: - Leaderboard(uint32_t gameID, uint32_t infoType, bool weekly, std::vector entries, - LWOOBJID relatedPlayer = LWOOBJID_EMPTY, LeaderboardType = None); - std::vector GetEntries(); - [[nodiscard]] std::u16string ToString() const; - [[nodiscard]] uint32_t GetGameID() const; - [[nodiscard]] uint32_t GetInfoType() const; - void Send(LWOOBJID targetID) const; + + // Enums for leaderboards + enum InfoType : uint32_t { + Top, // Top 11 all time players + MyStanding, // Ranking of the current player + Friends // Ranking between friends + }; + + enum Type : uint32_t { + ShootingGallery, + Racing, + MonumentRace, + FootRace, + UnusedLeaderboard4, // There is no 4 defined anywhere in the cdclient, but it takes a Score. + Survival, + SurvivalNS, + Donations, + None + }; + Leaderboard() = delete; + Leaderboard(const GameID gameID, const Leaderboard::InfoType infoType, const bool weekly, LWOOBJID relatedPlayer, const Leaderboard::Type = None); + + ~Leaderboard(); + + /** + * @brief Resets the leaderboard state and frees its allocated memory + * + */ + void Clear(); + + /** + * Serialize the Leaderboard to a BitStream + * + * Expensive! Leaderboards are very string intensive so be wary of performatnce calling this method. + */ + void Serialize(RakNet::BitStream* bitStream) const; + + /** + * Builds the leaderboard from the database based on the associated gameID + * + * @param resultStart The index to start the leaderboard at. Zero indexed. + * @param resultEnd The index to end the leaderboard at. Zero indexed. + */ + void SetupLeaderboard(bool weekly, uint32_t resultStart = 0, uint32_t resultEnd = 10); + + /** + * Sends the leaderboard to the client specified by targetID. + */ + void Send(const LWOOBJID targetID) const; + + // Helper function to get the columns, ordering and insert format for a leaderboard + static const std::string_view GetOrdering(Type leaderboardType); private: - std::vector entries{}; + // Takes the resulting query from a leaderboard lookup and converts it to the LDF we need + // to send it to a client. + void QueryToLdf(std::unique_ptr& rows); + + using LeaderboardEntry = std::vector; + using LeaderboardEntries = std::vector; + + LeaderboardEntries entries; LWOOBJID relatedPlayer; - uint32_t gameID; - uint32_t infoType; - LeaderboardType leaderboardType; + GameID gameID; + InfoType infoType; + Leaderboard::Type leaderboardType; bool weekly; }; -class LeaderboardManager { -public: - static LeaderboardManager* Instance() { - if (address == nullptr) - address = new LeaderboardManager; - return address; - } - static void SendLeaderboard(uint32_t gameID, InfoType infoType, bool weekly, LWOOBJID targetID, - LWOOBJID playerID = LWOOBJID_EMPTY); - static Leaderboard* GetLeaderboard(uint32_t gameID, InfoType infoType, bool weekly, LWOOBJID playerID = LWOOBJID_EMPTY); - static void SaveScore(LWOOBJID playerID, uint32_t gameID, uint32_t score, uint32_t time); - static LeaderboardType GetLeaderboardType(uint32_t gameID); -private: - static LeaderboardManager* address; +namespace LeaderboardManager { + void SendLeaderboard(const GameID gameID, const Leaderboard::InfoType infoType, const bool weekly, const LWOOBJID playerID, const LWOOBJID targetID, const uint32_t resultStart = 0, const uint32_t resultEnd = 10); - // Modified 12/12/2021: Existing queries were renamed to be more descriptive. - static const std::string topPlayersScoreQuery; - static const std::string friendsScoreQuery; - static const std::string standingsScoreQuery; - static const std::string topPlayersScoreQueryAsc; - static const std::string friendsScoreQueryAsc; - static const std::string standingsScoreQueryAsc; + void SaveScore(const LWOOBJID& playerID, const GameID activityId, const float primaryScore, const float secondaryScore = 0, const float tertiaryScore = 0); - // Added 12/12/2021: Queries dictated by time are needed for certain minigames. - static const std::string topPlayersTimeQuery; - static const std::string friendsTimeQuery; - static const std::string standingsTimeQuery; - static const std::string topPlayersTimeQueryAsc; - static const std::string friendsTimeQueryAsc; - static const std::string standingsTimeQueryAsc; + Leaderboard::Type GetLeaderboardType(const GameID gameID); + extern std::map leaderboardCache; }; +#endif //!__LEADERBOARDMANAGER__H__ diff --git a/dGame/Player.cpp b/dGame/Player.cpp index 2e194e6a..48b983aa 100644 --- a/dGame/Player.cpp +++ b/dGame/Player.cpp @@ -62,7 +62,7 @@ void Player::SetSystemAddress(const SystemAddress& value) { void Player::SetRespawnPos(const NiPoint3 position) { m_respawnPos = position; - m_Character->SetRespawnPoint(dZoneManager::Instance()->GetZone()->GetWorldID(), position); + m_Character->SetRespawnPoint(Game::zoneManager->GetZone()->GetWorldID(), position); } void Player::SetRespawnRot(const NiQuaternion rotation) { @@ -85,7 +85,7 @@ void Player::SendToZone(LWOMAPID zoneId, LWOCLONEID cloneId) { const auto objid = GetObjectID(); ZoneInstanceManager::Instance()->RequestZoneTransfer(Game::server, zoneId, cloneId, false, [objid](bool mythranShift, uint32_t zoneID, uint32_t zoneInstance, uint32_t zoneClone, std::string serverIP, uint16_t serverPort) { - auto* entity = EntityManager::Instance()->GetEntity(objid); + auto* entity = Game::entityManager->GetEntity(objid); if (entity == nullptr) { return; @@ -108,7 +108,7 @@ void Player::SendToZone(LWOMAPID zoneId, LWOCLONEID cloneId) { WorldPackets::SendTransferToWorld(sysAddr, serverIP, serverPort, mythranShift); - EntityManager::Instance()->DestructEntity(entity); + Game::entityManager->DestructEntity(entity); return; }); } @@ -135,13 +135,13 @@ void Player::RemoveLimboConstruction(LWOOBJID objectId) { void Player::ConstructLimboEntities() { for (const auto objectId : m_LimboConstructions) { - auto* entity = EntityManager::Instance()->GetEntity(objectId); + auto* entity = Game::entityManager->GetEntity(objectId); if (entity == nullptr) { continue; } - EntityManager::Instance()->ConstructEntity(entity, m_SystemAddress); + Game::entityManager->ConstructEntity(entity, m_SystemAddress); } m_LimboConstructions.clear(); @@ -224,7 +224,7 @@ Player* Player::GetPlayer(const SystemAddress& sysAddr) { } Player* Player::GetPlayer(const std::string& name) { - const auto characters = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::CHARACTER); + const auto characters = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::CHARACTER); for (auto* character : characters) { if (!character->IsPlayer()) continue; @@ -269,7 +269,7 @@ Player::~Player() { continue; } - auto* entity = EntityManager::Instance()->GetGhostCandidate(id); + auto* entity = Game::entityManager->GetGhostCandidate(id); if (entity != nullptr) { entity->SetObservers(entity->GetObservers() - 1); @@ -285,12 +285,12 @@ Player::~Player() { } if (IsPlayer()) { - Entity* zoneControl = EntityManager::Instance()->GetZoneControlEntity(); + Entity* zoneControl = Game::entityManager->GetZoneControlEntity(); for (CppScripts::Script* script : CppScripts::GetEntityScripts(zoneControl)) { script->OnPlayerExit(zoneControl, this); } - std::vector scriptedActs = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::SCRIPTED_ACTIVITY); + std::vector scriptedActs = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SCRIPTED_ACTIVITY); for (Entity* scriptEntity : scriptedActs) { if (scriptEntity->GetObjectID() != zoneControl->GetObjectID()) { // Don't want to trigger twice on instance worlds for (CppScripts::Script* script : CppScripts::GetEntityScripts(scriptEntity)) { diff --git a/dGame/TradingManager.cpp b/dGame/TradingManager.cpp index 281c003d..09d452b3 100644 --- a/dGame/TradingManager.cpp +++ b/dGame/TradingManager.cpp @@ -40,11 +40,11 @@ LWOOBJID Trade::GetParticipantB() const { } Entity* Trade::GetParticipantAEntity() const { - return EntityManager::Instance()->GetEntity(m_ParticipantA); + return Game::entityManager->GetEntity(m_ParticipantA); } Entity* Trade::GetParticipantBEntity() const { - return EntityManager::Instance()->GetEntity(m_ParticipantB); + return Game::entityManager->GetEntity(m_ParticipantB); } void Trade::SetCoins(LWOOBJID participant, uint64_t coins) { diff --git a/dGame/UserManager.cpp b/dGame/UserManager.cpp index 0161395c..9e409019 100644 --- a/dGame/UserManager.cpp +++ b/dGame/UserManager.cpp @@ -220,7 +220,7 @@ void UserManager::RequestCharacterList(const SystemAddress& sysAddr) { skillComponent->Reset(); } - EntityManager::Instance()->DestroyEntity(chars[i]->GetEntity()); + Game::entityManager->DestroyEntity(chars[i]->GetEntity()); chars[i]->SaveXMLToDatabase(); diff --git a/dGame/dBehaviors/AirMovementBehavior.cpp b/dGame/dBehaviors/AirMovementBehavior.cpp index dbfde465..a6d749d3 100644 --- a/dGame/dBehaviors/AirMovementBehavior.cpp +++ b/dGame/dBehaviors/AirMovementBehavior.cpp @@ -39,7 +39,7 @@ void AirMovementBehavior::Sync(BehaviorContext* context, RakNet::BitStream* bitS auto* behavior = CreateBehavior(behaviorId); - if (EntityManager::Instance()->GetEntity(target) != nullptr) { + if (Game::entityManager->GetEntity(target) != nullptr) { branch.target = target; } diff --git a/dGame/dBehaviors/ApplyBuffBehavior.cpp b/dGame/dBehaviors/ApplyBuffBehavior.cpp index 35b0f269..c94762aa 100644 --- a/dGame/dBehaviors/ApplyBuffBehavior.cpp +++ b/dGame/dBehaviors/ApplyBuffBehavior.cpp @@ -6,7 +6,7 @@ void ApplyBuffBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - auto* entity = EntityManager::Instance()->GetEntity(branch.target == LWOOBJID_EMPTY ? context->originator : branch.target); + auto* entity = Game::entityManager->GetEntity(branch.target == LWOOBJID_EMPTY ? context->originator : branch.target); if (entity == nullptr) return; @@ -19,7 +19,7 @@ void ApplyBuffBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitS } void ApplyBuffBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext branch) { - auto* entity = EntityManager::Instance()->GetEntity(branch.target); + auto* entity = Game::entityManager->GetEntity(branch.target); if (entity == nullptr) return; diff --git a/dGame/dBehaviors/AreaOfEffectBehavior.cpp b/dGame/dBehaviors/AreaOfEffectBehavior.cpp index dedede2a..e43d542d 100644 --- a/dGame/dBehaviors/AreaOfEffectBehavior.cpp +++ b/dGame/dBehaviors/AreaOfEffectBehavior.cpp @@ -47,7 +47,7 @@ void AreaOfEffectBehavior::Handle(BehaviorContext* context, RakNet::BitStream* b } void AreaOfEffectBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - auto* self = EntityManager::Instance()->GetEntity(context->caster); + auto* self = Game::entityManager->GetEntity(context->caster); if (self == nullptr) { Game::logger->Log("AreaOfEffectBehavior", "Invalid self for (%llu)!", context->originator); @@ -58,7 +58,7 @@ void AreaOfEffectBehavior::Calculate(BehaviorContext* context, RakNet::BitStream std::vector targets; - auto* presetTarget = EntityManager::Instance()->GetEntity(branch.target); + auto* presetTarget = Game::entityManager->GetEntity(branch.target); if (presetTarget != nullptr) { if (this->m_radius * this->m_radius >= Vector3::DistanceSquared(reference, presetTarget->GetPosition())) { @@ -75,7 +75,7 @@ void AreaOfEffectBehavior::Calculate(BehaviorContext* context, RakNet::BitStream // Gets all of the valid targets, passing in if should target enemies and friends for (auto validTarget : context->GetValidTargets(m_ignoreFaction, includeFaction, m_TargetSelf == 1, m_targetEnemy == 1, m_targetFriend == 1)) { - auto* entity = EntityManager::Instance()->GetEntity(validTarget); + auto* entity = Game::entityManager->GetEntity(validTarget); if (entity == nullptr) { Game::logger->Log("AreaOfEffectBehavior", "Invalid target (%llu) for (%llu)!", validTarget, context->originator); diff --git a/dGame/dBehaviors/BasicAttackBehavior.cpp b/dGame/dBehaviors/BasicAttackBehavior.cpp index f8693795..0a21383b 100644 --- a/dGame/dBehaviors/BasicAttackBehavior.cpp +++ b/dGame/dBehaviors/BasicAttackBehavior.cpp @@ -9,7 +9,7 @@ void BasicAttackBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { if (context->unmanaged) { - auto* entity = EntityManager::Instance()->GetEntity(branch.target); + auto* entity = Game::entityManager->GetEntity(branch.target); auto* destroyableComponent = entity->GetComponent(); if (destroyableComponent != nullptr) { @@ -38,7 +38,7 @@ void BasicAttackBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bi } void BasicAttackBehavior::DoHandleBehavior(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - auto* targetEntity = EntityManager::Instance()->GetEntity(branch.target); + auto* targetEntity = Game::entityManager->GetEntity(branch.target); if (!targetEntity) { Game::logger->Log("BasicAttackBehavior", "Target targetEntity %llu not found.", branch.target); return; @@ -61,7 +61,7 @@ void BasicAttackBehavior::DoHandleBehavior(BehaviorContext* context, RakNet::Bit if (isBlocked) { destroyableComponent->SetAttacksToBlock(std::min(destroyableComponent->GetAttacksToBlock() - 1, 0U)); - EntityManager::Instance()->SerializeEntity(targetEntity); + Game::entityManager->SerializeEntity(targetEntity); this->m_OnFailBlocked->Handle(context, bitStream, branch); return; } @@ -155,7 +155,7 @@ void BasicAttackBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* } void BasicAttackBehavior::DoBehaviorCalculation(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - auto* targetEntity = EntityManager::Instance()->GetEntity(branch.target); + auto* targetEntity = Game::entityManager->GetEntity(branch.target); if (!targetEntity) { Game::logger->Log("BasicAttackBehavior", "Target entity %llu is null!", branch.target); return; @@ -173,7 +173,7 @@ void BasicAttackBehavior::DoBehaviorCalculation(BehaviorContext* context, RakNet if (isBlocking) { destroyableComponent->SetAttacksToBlock(destroyableComponent->GetAttacksToBlock() - 1); - EntityManager::Instance()->SerializeEntity(targetEntity); + Game::entityManager->SerializeEntity(targetEntity); this->m_OnFailBlocked->Calculate(context, bitStream, branch); return; } diff --git a/dGame/dBehaviors/Behavior.cpp b/dGame/dBehaviors/Behavior.cpp index 2a269ddc..6fe84a9f 100644 --- a/dGame/dBehaviors/Behavior.cpp +++ b/dGame/dBehaviors/Behavior.cpp @@ -61,6 +61,7 @@ #include "SpeedBehavior.h" #include "DamageReductionBehavior.h" #include "JetPackBehavior.h" +#include "FallSpeedBehavior.h" #include "ChangeIdleFlagsBehavior.h" #include "DarkInspirationBehavior.h" @@ -164,7 +165,9 @@ Behavior* Behavior::CreateBehavior(const uint32_t behaviorId) { case BehaviorTemplates::BEHAVIOR_CAR_BOOST: behavior = new CarBoostBehavior(behaviorId); break; - case BehaviorTemplates::BEHAVIOR_FALL_SPEED: break; + case BehaviorTemplates::BEHAVIOR_FALL_SPEED: + behavior = new FallSpeedBehavior(behaviorId); + break; case BehaviorTemplates::BEHAVIOR_SHIELD: break; case BehaviorTemplates::BEHAVIOR_REPAIR_ARMOR: behavior = new RepairBehavior(behaviorId); @@ -311,7 +314,7 @@ BehaviorTemplates Behavior::GetBehaviorTemplate(const uint32_t behaviorId) { // For use with enemies, to display the correct damage animations on the players void Behavior::PlayFx(std::u16string type, const LWOOBJID target, const LWOOBJID secondary) { - auto* targetEntity = EntityManager::Instance()->GetEntity(target); + auto* targetEntity = Game::entityManager->GetEntity(target); if (targetEntity == nullptr) { return; diff --git a/dGame/dBehaviors/BehaviorContext.cpp b/dGame/dBehaviors/BehaviorContext.cpp index c7db4208..43ba8457 100644 --- a/dGame/dBehaviors/BehaviorContext.cpp +++ b/dGame/dBehaviors/BehaviorContext.cpp @@ -27,7 +27,7 @@ BehaviorEndEntry::BehaviorEndEntry() { } uint32_t BehaviorContext::GetUniqueSkillId() const { - auto* entity = EntityManager::Instance()->GetEntity(this->originator); + auto* entity = Game::entityManager->GetEntity(this->originator); if (entity == nullptr) { Game::logger->Log("BehaviorContext", "Invalid entity for (%llu)!", this->originator); @@ -94,11 +94,11 @@ void BehaviorContext::ScheduleUpdate(const LWOOBJID id) { void BehaviorContext::ExecuteUpdates() { for (const auto& id : this->scheduledUpdates) { - auto* entity = EntityManager::Instance()->GetEntity(id); + auto* entity = Game::entityManager->GetEntity(id); if (entity == nullptr) continue; - EntityManager::Instance()->SerializeEntity(entity); + Game::entityManager->SerializeEntity(entity); } this->scheduledUpdates.clear(); @@ -308,7 +308,7 @@ void BehaviorContext::Reset() { } std::vector BehaviorContext::GetValidTargets(int32_t ignoreFaction, int32_t includeFaction, bool targetSelf, bool targetEnemy, bool targetFriend) const { - auto* entity = EntityManager::Instance()->GetEntity(this->caster); + auto* entity = Game::entityManager->GetEntity(this->caster); std::vector targets; @@ -320,7 +320,7 @@ std::vector BehaviorContext::GetValidTargets(int32_t ignoreFaction, in if (!ignoreFaction && !includeFaction) { for (auto entry : entity->GetTargetsInPhantom()) { - auto* instance = EntityManager::Instance()->GetEntity(entry); + auto* instance = Game::entityManager->GetEntity(entry); if (instance == nullptr) { continue; @@ -336,7 +336,7 @@ std::vector BehaviorContext::GetValidTargets(int32_t ignoreFaction, in return targets; } - auto entities = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::CONTROLLABLE_PHYSICS); + auto entities = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::CONTROLLABLE_PHYSICS); for (auto* candidate : entities) { const auto id = candidate->GetObjectID(); diff --git a/dGame/dBehaviors/BlockBehavior.cpp b/dGame/dBehaviors/BlockBehavior.cpp index cdbb3d80..19db0267 100644 --- a/dGame/dBehaviors/BlockBehavior.cpp +++ b/dGame/dBehaviors/BlockBehavior.cpp @@ -10,7 +10,7 @@ void BlockBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { const auto target = context->originator; - auto* entity = EntityManager::Instance()->GetEntity(target); + auto* entity = Game::entityManager->GetEntity(target); if (entity == nullptr) { Game::logger->Log("DamageAbsorptionBehavior", "Failed to find target (%llu)!", branch.target); @@ -40,7 +40,7 @@ void BlockBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitSt void BlockBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext branch) { const auto target = context->originator; - auto* entity = EntityManager::Instance()->GetEntity(target); + auto* entity = Game::entityManager->GetEntity(target); if (entity == nullptr) { Game::logger->Log("DamageAbsorptionBehavior", "Failed to find target (%llu)!", branch.target); diff --git a/dGame/dBehaviors/BuffBehavior.cpp b/dGame/dBehaviors/BuffBehavior.cpp index a39fd165..2c06dbd4 100644 --- a/dGame/dBehaviors/BuffBehavior.cpp +++ b/dGame/dBehaviors/BuffBehavior.cpp @@ -10,7 +10,7 @@ void BuffBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { const auto target = branch.target != LWOOBJID_EMPTY ? branch.target : context->originator; - auto* entity = EntityManager::Instance()->GetEntity(target); + auto* entity = Game::entityManager->GetEntity(target); if (entity == nullptr) { Game::logger->Log("BuffBehavior", "Invalid target (%llu)!", target); @@ -30,7 +30,7 @@ void BuffBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream component->SetMaxArmor(component->GetMaxArmor() + this->m_armor); component->SetMaxImagination(component->GetMaxImagination() + this->m_imagination); - EntityManager::Instance()->SerializeEntity(entity); + Game::entityManager->SerializeEntity(entity); if (!context->unmanaged) { if (branch.duration > 0) { @@ -44,7 +44,7 @@ void BuffBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream void BuffBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext branch) { const auto target = branch.target != LWOOBJID_EMPTY ? branch.target : context->originator; - auto* entity = EntityManager::Instance()->GetEntity(target); + auto* entity = Game::entityManager->GetEntity(target); if (entity == nullptr) { Game::logger->Log("BuffBehavior", "Invalid target (%llu)!", target); @@ -64,7 +64,7 @@ void BuffBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext branch component->SetMaxArmor(component->GetMaxArmor() - this->m_armor); component->SetMaxImagination(component->GetMaxImagination() - this->m_imagination); - EntityManager::Instance()->SerializeEntity(entity); + Game::entityManager->SerializeEntity(entity); } void BuffBehavior::Timer(BehaviorContext* context, const BehaviorBranchContext branch, LWOOBJID second) { diff --git a/dGame/dBehaviors/CMakeLists.txt b/dGame/dBehaviors/CMakeLists.txt index 7b331fe0..8a9368b9 100644 --- a/dGame/dBehaviors/CMakeLists.txt +++ b/dGame/dBehaviors/CMakeLists.txt @@ -22,6 +22,7 @@ set(DGAME_DBEHAVIORS_SOURCES "AirMovementBehavior.cpp" "DurationBehavior.cpp" "EmptyBehavior.cpp" "EndBehavior.cpp" + "FallSpeedBehavior.cpp" "ForceMovementBehavior.cpp" "HealBehavior.cpp" "ImaginationBehavior.cpp" diff --git a/dGame/dBehaviors/CarBoostBehavior.cpp b/dGame/dBehaviors/CarBoostBehavior.cpp index 1ab0af95..e2929863 100644 --- a/dGame/dBehaviors/CarBoostBehavior.cpp +++ b/dGame/dBehaviors/CarBoostBehavior.cpp @@ -11,7 +11,7 @@ void CarBoostBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { GameMessages::SendVehicleAddPassiveBoostAction(branch.target, UNASSIGNED_SYSTEM_ADDRESS); - auto* entity = EntityManager::Instance()->GetEntity(context->originator); + auto* entity = Game::entityManager->GetEntity(context->originator); if (entity == nullptr) { return; @@ -22,7 +22,7 @@ void CarBoostBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitSt auto* possessableComponent = entity->GetComponent(); if (possessableComponent != nullptr) { - auto* possessor = EntityManager::Instance()->GetEntity(possessableComponent->GetPossessor()); + auto* possessor = Game::entityManager->GetEntity(possessableComponent->GetPossessor()); if (possessor != nullptr) { auto* characterComponent = possessor->GetComponent(); diff --git a/dGame/dBehaviors/ChangeOrientationBehavior.cpp b/dGame/dBehaviors/ChangeOrientationBehavior.cpp index 36a2e6a8..445c76df 100644 --- a/dGame/dBehaviors/ChangeOrientationBehavior.cpp +++ b/dGame/dBehaviors/ChangeOrientationBehavior.cpp @@ -5,14 +5,14 @@ void ChangeOrientationBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { Entity* sourceEntity; - if (this->m_orientCaster) sourceEntity = EntityManager::Instance()->GetEntity(context->originator); - else sourceEntity = EntityManager::Instance()->GetEntity(branch.target); + if (this->m_orientCaster) sourceEntity = Game::entityManager->GetEntity(context->originator); + else sourceEntity = Game::entityManager->GetEntity(branch.target); if (!sourceEntity) return; if (this->m_toTarget) { Entity* destinationEntity; - if (this->m_orientCaster) destinationEntity = EntityManager::Instance()->GetEntity(branch.target); - else destinationEntity = EntityManager::Instance()->GetEntity(context->originator); + if (this->m_orientCaster) destinationEntity = Game::entityManager->GetEntity(branch.target); + else destinationEntity = Game::entityManager->GetEntity(context->originator); if (!destinationEntity) return; sourceEntity->SetRotation( @@ -23,7 +23,7 @@ void ChangeOrientationBehavior::Calculate(BehaviorContext* context, RakNet::BitS if (this->m_relative) baseAngle += sourceEntity->GetRotation().GetForwardVector(); sourceEntity->SetRotation(NiQuaternion::FromEulerAngles(baseAngle)); } else return; - EntityManager::Instance()->SerializeEntity(sourceEntity); + Game::entityManager->SerializeEntity(sourceEntity); return; } diff --git a/dGame/dBehaviors/DamageAbsorptionBehavior.cpp b/dGame/dBehaviors/DamageAbsorptionBehavior.cpp index 48dbf705..f9936767 100644 --- a/dGame/dBehaviors/DamageAbsorptionBehavior.cpp +++ b/dGame/dBehaviors/DamageAbsorptionBehavior.cpp @@ -8,7 +8,7 @@ #include "DestroyableComponent.h" void DamageAbsorptionBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) { - auto* target = EntityManager::Instance()->GetEntity(branch.target); + auto* target = Game::entityManager->GetEntity(branch.target); if (target == nullptr) { Game::logger->Log("DamageAbsorptionBehavior", "Failed to find target (%llu)!", branch.target); @@ -34,7 +34,7 @@ void DamageAbsorptionBehavior::Calculate(BehaviorContext* context, RakNet::BitSt } void DamageAbsorptionBehavior::Timer(BehaviorContext* context, BehaviorBranchContext branch, const LWOOBJID second) { - auto* target = EntityManager::Instance()->GetEntity(second); + auto* target = Game::entityManager->GetEntity(second); if (target == nullptr) { Game::logger->Log("DamageAbsorptionBehavior", "Failed to find target (%llu)!", second); diff --git a/dGame/dBehaviors/DamageReductionBehavior.cpp b/dGame/dBehaviors/DamageReductionBehavior.cpp index 2b18b7c2..7645ec7b 100644 --- a/dGame/dBehaviors/DamageReductionBehavior.cpp +++ b/dGame/dBehaviors/DamageReductionBehavior.cpp @@ -8,7 +8,7 @@ #include "DestroyableComponent.h" void DamageReductionBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) { - auto* target = EntityManager::Instance()->GetEntity(branch.target); + auto* target = Game::entityManager->GetEntity(branch.target); if (target == nullptr) { Game::logger->Log("DamageReductionBehavior", "Failed to find target (%llu)!", branch.target); @@ -32,7 +32,7 @@ void DamageReductionBehavior::Calculate(BehaviorContext* context, RakNet::BitStr } void DamageReductionBehavior::Timer(BehaviorContext* context, BehaviorBranchContext branch, const LWOOBJID second) { - auto* target = EntityManager::Instance()->GetEntity(second); + auto* target = Game::entityManager->GetEntity(second); if (target == nullptr) { Game::logger->Log("DamageReductionBehavior", "Failed to find target (%llu)!", second); diff --git a/dGame/dBehaviors/DarkInspirationBehavior.cpp b/dGame/dBehaviors/DarkInspirationBehavior.cpp index ea80cbba..4e9890e3 100644 --- a/dGame/dBehaviors/DarkInspirationBehavior.cpp +++ b/dGame/dBehaviors/DarkInspirationBehavior.cpp @@ -7,7 +7,7 @@ #include "BehaviorContext.h" void DarkInspirationBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) { - auto* target = EntityManager::Instance()->GetEntity(branch.target); + auto* target = Game::entityManager->GetEntity(branch.target); if (target == nullptr) { Game::logger->LogDebug("DarkInspirationBehavior", "Failed to find target (%llu)!", branch.target); @@ -26,7 +26,7 @@ void DarkInspirationBehavior::Handle(BehaviorContext* context, RakNet::BitStream } void DarkInspirationBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - auto* target = EntityManager::Instance()->GetEntity(branch.target); + auto* target = Game::entityManager->GetEntity(branch.target); if (target == nullptr) { Game::logger->LogDebug("DarkInspirationBehavior", "Failed to find target (%llu)!", branch.target); diff --git a/dGame/dBehaviors/FallSpeedBehavior.cpp b/dGame/dBehaviors/FallSpeedBehavior.cpp new file mode 100644 index 00000000..dfbdec2a --- /dev/null +++ b/dGame/dBehaviors/FallSpeedBehavior.cpp @@ -0,0 +1,50 @@ +#include "FallSpeedBehavior.h" + +#include "ControllablePhysicsComponent.h" +#include "BehaviorContext.h" +#include "BehaviorBranchContext.h" + + +void FallSpeedBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { + // make sure required parameter has non-default value + if (m_PercentSlowed == 0.0f) return; + auto* target = Game::entityManager->GetEntity(branch.target); + if (!target) return; + + auto* controllablePhysicsComponent = target->GetComponent(); + if (!controllablePhysicsComponent) return; + controllablePhysicsComponent->SetGravityScale(m_PercentSlowed); + Game::entityManager->SerializeEntity(target); + + if (branch.duration > 0.0f) { + context->RegisterTimerBehavior(this, branch); + } else if (branch.start > 0) { + context->RegisterEndBehavior(this, branch); + } +} + +void FallSpeedBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { + Handle(context, bitStream, branch); +} + +void FallSpeedBehavior::Timer(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) { + End(context, branch, second); +} + +void FallSpeedBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext branch) { + End(context, branch, LWOOBJID_EMPTY); +} + +void FallSpeedBehavior::End(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) { + auto* target = Game::entityManager->GetEntity(branch.target); + if (!target) return; + + auto* controllablePhysicsComponent = target->GetComponent(); + if (!controllablePhysicsComponent) return; + controllablePhysicsComponent->SetGravityScale(1); + Game::entityManager->SerializeEntity(target); +} + +void FallSpeedBehavior::Load(){ + m_PercentSlowed = GetFloat("percent_slowed"); +} diff --git a/dGame/dBehaviors/FallSpeedBehavior.h b/dGame/dBehaviors/FallSpeedBehavior.h new file mode 100644 index 00000000..01f0143f --- /dev/null +++ b/dGame/dBehaviors/FallSpeedBehavior.h @@ -0,0 +1,18 @@ +#pragma once +#include "Behavior.h" + +class FallSpeedBehavior final : public Behavior +{ +public: + explicit FallSpeedBehavior(const uint32_t behaviorId) : Behavior(behaviorId) {} + + void Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override; + void Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override; + void Timer(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) override; + void End(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) override; + void UnCast(BehaviorContext* context, BehaviorBranchContext branch) override; + void Load() override; + +private: + float m_PercentSlowed; +}; diff --git a/dGame/dBehaviors/ForceMovementBehavior.cpp b/dGame/dBehaviors/ForceMovementBehavior.cpp index 52359cf7..97208236 100644 --- a/dGame/dBehaviors/ForceMovementBehavior.cpp +++ b/dGame/dBehaviors/ForceMovementBehavior.cpp @@ -42,7 +42,7 @@ void ForceMovementBehavior::Calculate(BehaviorContext* context, RakNet::BitStrea return; } - auto* casterEntity = EntityManager::Instance()->GetEntity(context->caster); + auto* casterEntity = Game::entityManager->GetEntity(context->caster); if (casterEntity != nullptr) { auto* controllablePhysicsComponent = casterEntity->GetComponent(); if (controllablePhysicsComponent != nullptr) { @@ -51,7 +51,7 @@ void ForceMovementBehavior::Calculate(BehaviorContext* context, RakNet::BitStrea controllablePhysicsComponent->SetVelocity(controllablePhysicsComponent->GetRotation().GetForwardVector() * 25); } - EntityManager::Instance()->SerializeEntity(casterEntity); + Game::entityManager->SerializeEntity(casterEntity); } } @@ -72,7 +72,7 @@ void ForceMovementBehavior::Load() { } void ForceMovementBehavior::SyncCalculation(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - auto* casterEntity = EntityManager::Instance()->GetEntity(context->caster); + auto* casterEntity = Game::entityManager->GetEntity(context->caster); if (casterEntity != nullptr) { auto* controllablePhysicsComponent = casterEntity->GetComponent(); if (controllablePhysicsComponent != nullptr) { @@ -80,7 +80,7 @@ void ForceMovementBehavior::SyncCalculation(BehaviorContext* context, RakNet::Bi controllablePhysicsComponent->SetPosition(controllablePhysicsComponent->GetPosition() + controllablePhysicsComponent->GetVelocity() * m_Duration); controllablePhysicsComponent->SetVelocity({}); - EntityManager::Instance()->SerializeEntity(casterEntity); + Game::entityManager->SerializeEntity(casterEntity); } } diff --git a/dGame/dBehaviors/HealBehavior.cpp b/dGame/dBehaviors/HealBehavior.cpp index 66fe2c79..dae009d4 100644 --- a/dGame/dBehaviors/HealBehavior.cpp +++ b/dGame/dBehaviors/HealBehavior.cpp @@ -8,7 +8,7 @@ void HealBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bit_stream, const BehaviorBranchContext branch) { - auto* entity = EntityManager::Instance()->GetEntity(branch.target); + auto* entity = Game::entityManager->GetEntity(branch.target); if (entity == nullptr) { Game::logger->Log("HealBehavior", "Failed to find entity for (%llu)!", branch.target); diff --git a/dGame/dBehaviors/ImaginationBehavior.cpp b/dGame/dBehaviors/ImaginationBehavior.cpp index 59b192b0..50f7e046 100644 --- a/dGame/dBehaviors/ImaginationBehavior.cpp +++ b/dGame/dBehaviors/ImaginationBehavior.cpp @@ -7,7 +7,7 @@ void ImaginationBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bit_stream, const BehaviorBranchContext branch) { - auto* entity = EntityManager::Instance()->GetEntity(branch.target); + auto* entity = Game::entityManager->GetEntity(branch.target); if (entity == nullptr) { return; diff --git a/dGame/dBehaviors/ImmunityBehavior.cpp b/dGame/dBehaviors/ImmunityBehavior.cpp index a5dd4c85..ba4a8b77 100644 --- a/dGame/dBehaviors/ImmunityBehavior.cpp +++ b/dGame/dBehaviors/ImmunityBehavior.cpp @@ -10,7 +10,7 @@ #include "eStateChangeType.h" void ImmunityBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) { - auto* target = EntityManager::Instance()->GetEntity(branch.target); + auto* target = Game::entityManager->GetEntity(branch.target); if (!target) { Game::logger->Log("DamageAbsorptionBehavior", "Failed to find target (%llu)!", branch.target); @@ -56,7 +56,7 @@ void ImmunityBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bi } void ImmunityBehavior::Timer(BehaviorContext* context, BehaviorBranchContext branch, const LWOOBJID second) { - auto* target = EntityManager::Instance()->GetEntity(second); + auto* target = Game::entityManager->GetEntity(second); if (!target) { Game::logger->Log("DamageAbsorptionBehavior", "Failed to find target (%llu)!", second); diff --git a/dGame/dBehaviors/InterruptBehavior.cpp b/dGame/dBehaviors/InterruptBehavior.cpp index 9035c092..ffe3bb8b 100644 --- a/dGame/dBehaviors/InterruptBehavior.cpp +++ b/dGame/dBehaviors/InterruptBehavior.cpp @@ -42,7 +42,7 @@ void InterruptBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitS if (branch.target == context->originator) return; - auto* target = EntityManager::Instance()->GetEntity(branch.target); + auto* target = Game::entityManager->GetEntity(branch.target); if (target == nullptr) return; @@ -67,7 +67,7 @@ void InterruptBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* b if (branch.target == context->originator) return; - auto* target = EntityManager::Instance()->GetEntity(branch.target); + auto* target = Game::entityManager->GetEntity(branch.target); if (target == nullptr) return; diff --git a/dGame/dBehaviors/JetPackBehavior.cpp b/dGame/dBehaviors/JetPackBehavior.cpp index e7d76560..134dd0fb 100644 --- a/dGame/dBehaviors/JetPackBehavior.cpp +++ b/dGame/dBehaviors/JetPackBehavior.cpp @@ -6,7 +6,7 @@ #include "Character.h" void JetPackBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bit_stream, const BehaviorBranchContext branch) { - auto* entity = EntityManager::Instance()->GetEntity(branch.target); + auto* entity = Game::entityManager->GetEntity(branch.target); GameMessages::SendSetJetPackMode(entity, true, this->m_BypassChecks, this->m_EnableHover, this->m_effectId, this->m_Airspeed, this->m_MaxAirspeed, this->m_VerticalVelocity, this->m_WarningEffectID); @@ -20,7 +20,7 @@ void JetPackBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bit_st } void JetPackBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext branch) { - auto* entity = EntityManager::Instance()->GetEntity(branch.target); + auto* entity = Game::entityManager->GetEntity(branch.target); GameMessages::SendSetJetPackMode(entity, false); diff --git a/dGame/dBehaviors/KnockbackBehavior.cpp b/dGame/dBehaviors/KnockbackBehavior.cpp index 1b878ed0..d67ebbc8 100644 --- a/dGame/dBehaviors/KnockbackBehavior.cpp +++ b/dGame/dBehaviors/KnockbackBehavior.cpp @@ -21,7 +21,7 @@ void KnockbackBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitS void KnockbackBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { bool blocked = false; - auto* target = EntityManager::Instance()->GetEntity(branch.target); + auto* target = Game::entityManager->GetEntity(branch.target); if (target != nullptr) { auto* destroyableComponent = target->GetComponent(); diff --git a/dGame/dBehaviors/LootBuffBehavior.cpp b/dGame/dBehaviors/LootBuffBehavior.cpp index 6e5634fc..c7a6b36a 100644 --- a/dGame/dBehaviors/LootBuffBehavior.cpp +++ b/dGame/dBehaviors/LootBuffBehavior.cpp @@ -1,14 +1,14 @@ #include "LootBuffBehavior.h" void LootBuffBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - auto target = EntityManager::Instance()->GetEntity(context->caster); + auto target = Game::entityManager->GetEntity(context->caster); if (!target) return; auto controllablePhysicsComponent = target->GetComponent(); if (!controllablePhysicsComponent) return; controllablePhysicsComponent->AddPickupRadiusScale(m_Scale); - EntityManager::Instance()->SerializeEntity(target); + Game::entityManager->SerializeEntity(target); if (branch.duration > 0) context->RegisterTimerBehavior(this, branch); @@ -19,14 +19,14 @@ void LootBuffBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bi } void LootBuffBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext branch) { - auto target = EntityManager::Instance()->GetEntity(context->caster); + auto target = Game::entityManager->GetEntity(context->caster); if (!target) return; auto controllablePhysicsComponent = target->GetComponent(); if (!controllablePhysicsComponent) return; controllablePhysicsComponent->RemovePickupRadiusScale(m_Scale); - EntityManager::Instance()->SerializeEntity(target); + Game::entityManager->SerializeEntity(target); } void LootBuffBehavior::Timer(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) { diff --git a/dGame/dBehaviors/OverTimeBehavior.cpp b/dGame/dBehaviors/OverTimeBehavior.cpp index 5afbbd26..49077f0f 100644 --- a/dGame/dBehaviors/OverTimeBehavior.cpp +++ b/dGame/dBehaviors/OverTimeBehavior.cpp @@ -14,13 +14,13 @@ void OverTimeBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { const auto originator = context->originator; - auto* entity = EntityManager::Instance()->GetEntity(originator); + auto* entity = Game::entityManager->GetEntity(originator); if (entity == nullptr) return; for (size_t i = 0; i < m_NumIntervals; i++) { entity->AddCallbackTimer((i + 1) * m_Delay, [originator, branch, this]() { - auto* entity = EntityManager::Instance()->GetEntity(originator); + auto* entity = Game::entityManager->GetEntity(originator); if (entity == nullptr) return; diff --git a/dGame/dBehaviors/ProjectileAttackBehavior.cpp b/dGame/dBehaviors/ProjectileAttackBehavior.cpp index f65421cb..eb435d7c 100644 --- a/dGame/dBehaviors/ProjectileAttackBehavior.cpp +++ b/dGame/dBehaviors/ProjectileAttackBehavior.cpp @@ -16,7 +16,7 @@ void ProjectileAttackBehavior::Handle(BehaviorContext* context, RakNet::BitStrea return; }; - auto* entity = EntityManager::Instance()->GetEntity(context->originator); + auto* entity = Game::entityManager->GetEntity(context->originator); if (entity == nullptr) { Game::logger->Log("ProjectileAttackBehavior", "Failed to find originator (%llu)!", context->originator); @@ -40,7 +40,7 @@ void ProjectileAttackBehavior::Handle(BehaviorContext* context, RakNet::BitStrea }; } - auto* targetEntity = EntityManager::Instance()->GetEntity(target); + auto* targetEntity = Game::entityManager->GetEntity(target); for (auto i = 0u; i < this->m_projectileCount; ++i) { LWOOBJID projectileId{}; @@ -61,7 +61,7 @@ void ProjectileAttackBehavior::Handle(BehaviorContext* context, RakNet::BitStrea void ProjectileAttackBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { bitStream->Write(branch.target); - auto* entity = EntityManager::Instance()->GetEntity(context->originator); + auto* entity = Game::entityManager->GetEntity(context->originator); if (entity == nullptr) { Game::logger->Log("ProjectileAttackBehavior", "Failed to find originator (%llu)!", context->originator); @@ -78,7 +78,7 @@ void ProjectileAttackBehavior::Calculate(BehaviorContext* context, RakNet::BitSt } - auto* other = EntityManager::Instance()->GetEntity(branch.target); + auto* other = Game::entityManager->GetEntity(branch.target); if (other == nullptr) { Game::logger->Log("ProjectileAttackBehavior", "Invalid projectile target (%llu)!", branch.target); diff --git a/dGame/dBehaviors/PropertyTeleportBehavior.cpp b/dGame/dBehaviors/PropertyTeleportBehavior.cpp index 447b085b..309fc929 100644 --- a/dGame/dBehaviors/PropertyTeleportBehavior.cpp +++ b/dGame/dBehaviors/PropertyTeleportBehavior.cpp @@ -12,7 +12,7 @@ #include "dZoneManager.h" void PropertyTeleportBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - auto* caster = EntityManager::Instance()->GetEntity(context->caster); + auto* caster = Game::entityManager->GetEntity(context->caster); if (!caster) return; auto* character = caster->GetCharacter(); @@ -23,16 +23,16 @@ void PropertyTeleportBehavior::Handle(BehaviorContext* context, RakNet::BitStrea LWOMAPID targetMapId = m_MapId; LWOCLONEID targetCloneId = character->GetPropertyCloneID(); - if (dZoneManager::Instance()->GetZoneID().GetCloneID() == character->GetPropertyCloneID()) { + if (Game::zoneManager->GetZoneID().GetCloneID() == character->GetPropertyCloneID()) { targetMapId = character->GetLastNonInstanceZoneID(); targetCloneId = 0; } else { - character->SetLastNonInstanceZoneID(dZoneManager::Instance()->GetZoneID().GetMapID()); + character->SetLastNonInstanceZoneID(Game::zoneManager->GetZoneID().GetMapID()); } ZoneInstanceManager::Instance()->RequestZoneTransfer(Game::server, targetMapId, targetCloneId, false, [objId](bool mythranShift, uint32_t zoneID, uint32_t zoneInstance, uint32_t zoneClone, std::string serverIP, uint16_t serverPort) { - auto* entity = EntityManager::Instance()->GetEntity(objId); + auto* entity = Game::entityManager->GetEntity(objId); if (!entity) return; const auto sysAddr = entity->GetSystemAddress(); diff --git a/dGame/dBehaviors/PullToPointBehavior.cpp b/dGame/dBehaviors/PullToPointBehavior.cpp index 7427ccc4..e18443f7 100644 --- a/dGame/dBehaviors/PullToPointBehavior.cpp +++ b/dGame/dBehaviors/PullToPointBehavior.cpp @@ -6,9 +6,9 @@ #include "MovementAIComponent.h" void PullToPointBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - auto* entity = EntityManager::Instance()->GetEntity(context->originator); + auto* entity = Game::entityManager->GetEntity(context->originator); - auto* target = EntityManager::Instance()->GetEntity(branch.target); + auto* target = Game::entityManager->GetEntity(branch.target); if (entity == nullptr || target == nullptr) { return; diff --git a/dGame/dBehaviors/RemoveBuffBehavior.cpp b/dGame/dBehaviors/RemoveBuffBehavior.cpp index be3066ac..c6d2c9c9 100644 --- a/dGame/dBehaviors/RemoveBuffBehavior.cpp +++ b/dGame/dBehaviors/RemoveBuffBehavior.cpp @@ -6,7 +6,7 @@ #include "BuffComponent.h" void RemoveBuffBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - auto* entity = EntityManager::Instance()->GetEntity(context->caster); + auto* entity = Game::entityManager->GetEntity(context->caster); if (!entity) return; auto* buffComponent = entity->GetComponent(); diff --git a/dGame/dBehaviors/RepairBehavior.cpp b/dGame/dBehaviors/RepairBehavior.cpp index ce2e5fd2..d2967921 100644 --- a/dGame/dBehaviors/RepairBehavior.cpp +++ b/dGame/dBehaviors/RepairBehavior.cpp @@ -8,7 +8,7 @@ #include "eReplicaComponentType.h" void RepairBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bit_stream, const BehaviorBranchContext branch) { - auto* entity = EntityManager::Instance()->GetEntity(branch.target); + auto* entity = Game::entityManager->GetEntity(branch.target); if (entity == nullptr) { Game::logger->Log("RepairBehavior", "Failed to find entity for (%llu)!", branch.target); diff --git a/dGame/dBehaviors/SkillEventBehavior.cpp b/dGame/dBehaviors/SkillEventBehavior.cpp index 837d70c9..4205c28b 100644 --- a/dGame/dBehaviors/SkillEventBehavior.cpp +++ b/dGame/dBehaviors/SkillEventBehavior.cpp @@ -5,8 +5,8 @@ #include "CppScripts.h" void SkillEventBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - auto* target = EntityManager::Instance()->GetEntity(branch.target); - auto* caster = EntityManager::Instance()->GetEntity(context->originator); + auto* target = Game::entityManager->GetEntity(branch.target); + auto* caster = Game::entityManager->GetEntity(context->originator); if (caster != nullptr && target != nullptr && this->m_effectHandle != nullptr && !this->m_effectHandle->empty()) { for (CppScripts::Script* script : CppScripts::GetEntityScripts(target)) { @@ -17,8 +17,8 @@ void SkillEventBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bit void SkillEventBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - auto* target = EntityManager::Instance()->GetEntity(branch.target); - auto* caster = EntityManager::Instance()->GetEntity(context->originator); + auto* target = Game::entityManager->GetEntity(branch.target); + auto* caster = Game::entityManager->GetEntity(context->originator); if (caster != nullptr && target != nullptr && this->m_effectHandle != nullptr && !this->m_effectHandle->empty()) { for (CppScripts::Script* script : CppScripts::GetEntityScripts(target)) { diff --git a/dGame/dBehaviors/SpawnBehavior.cpp b/dGame/dBehaviors/SpawnBehavior.cpp index 75c84f6c..2803251a 100644 --- a/dGame/dBehaviors/SpawnBehavior.cpp +++ b/dGame/dBehaviors/SpawnBehavior.cpp @@ -12,7 +12,7 @@ #include "eReplicaComponentType.h" void SpawnBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - auto* origin = EntityManager::Instance()->GetEntity(context->originator); + auto* origin = Game::entityManager->GetEntity(context->originator); if (origin == nullptr) { Game::logger->Log("SpawnBehavior", "Failed to find self entity (%llu)!", context->originator); @@ -21,7 +21,7 @@ void SpawnBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStrea } if (branch.isProjectile) { - auto* target = EntityManager::Instance()->GetEntity(branch.target); + auto* target = Game::entityManager->GetEntity(branch.target); if (target != nullptr) { origin = target; @@ -38,10 +38,10 @@ void SpawnBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStrea info.spawnerNodeID = 0; info.pos = info.pos + (info.rot.GetForwardVector() * m_Distance); - auto* entity = EntityManager::Instance()->CreateEntity( + auto* entity = Game::entityManager->CreateEntity( info, nullptr, - EntityManager::Instance()->GetEntity(context->originator) + Game::entityManager->GetEntity(context->originator) ); if (entity == nullptr) { @@ -59,7 +59,7 @@ void SpawnBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStrea rebuildComponent->SetRepositionPlayer(false); } - EntityManager::Instance()->ConstructEntity(entity); + Game::entityManager->ConstructEntity(entity); if (branch.duration > 0) { context->RegisterTimerBehavior(this, branch, entity->GetObjectID()); @@ -79,7 +79,7 @@ void SpawnBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitSt } void SpawnBehavior::Timer(BehaviorContext* context, const BehaviorBranchContext branch, const LWOOBJID second) { - auto* entity = EntityManager::Instance()->GetEntity(second); + auto* entity = Game::entityManager->GetEntity(second); if (entity == nullptr) { Game::logger->Log("SpawnBehavior", "Failed to find spawned entity (%llu)!", second); diff --git a/dGame/dBehaviors/SpeedBehavior.cpp b/dGame/dBehaviors/SpeedBehavior.cpp index d326aa45..5dbad8ec 100644 --- a/dGame/dBehaviors/SpeedBehavior.cpp +++ b/dGame/dBehaviors/SpeedBehavior.cpp @@ -9,14 +9,14 @@ void SpeedBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { if (m_AffectsCaster) branch.target = context->caster; - auto* target = EntityManager::Instance()->GetEntity(branch.target); + auto* target = Game::entityManager->GetEntity(branch.target); if (!target) return; auto* controllablePhysicsComponent = target->GetComponent(); if (!controllablePhysicsComponent) return; controllablePhysicsComponent->AddSpeedboost(m_RunSpeed); - EntityManager::Instance()->SerializeEntity(target); + Game::entityManager->SerializeEntity(target); if (branch.duration > 0.0f) { context->RegisterTimerBehavior(this, branch); @@ -38,14 +38,14 @@ void SpeedBehavior::Timer(BehaviorContext* context, BehaviorBranchContext branch } void SpeedBehavior::End(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) { - auto* target = EntityManager::Instance()->GetEntity(branch.target); + auto* target = Game::entityManager->GetEntity(branch.target); if (!target) return; auto* controllablePhysicsComponent = target->GetComponent(); if (!controllablePhysicsComponent) return; controllablePhysicsComponent->RemoveSpeedboost(m_RunSpeed); - EntityManager::Instance()->SerializeEntity(target); + Game::entityManager->SerializeEntity(target); } void SpeedBehavior::Load() { diff --git a/dGame/dBehaviors/StunBehavior.cpp b/dGame/dBehaviors/StunBehavior.cpp index 4e34d3a2..8e160338 100644 --- a/dGame/dBehaviors/StunBehavior.cpp +++ b/dGame/dBehaviors/StunBehavior.cpp @@ -21,7 +21,7 @@ void StunBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream return; }; - auto* target = EntityManager::Instance()->GetEntity(branch.target); + auto* target = Game::entityManager->GetEntity(branch.target); if (target == nullptr) { Game::logger->Log("StunBehavior", "Failed to find target (%llu)!", branch.target); @@ -44,7 +44,7 @@ void StunBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream void StunBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) { if (this->m_stunCaster || branch.target == context->originator) { - auto* self = EntityManager::Instance()->GetEntity(context->originator); + auto* self = Game::entityManager->GetEntity(context->originator); if (self == nullptr) { Game::logger->Log("StunBehavior", "Invalid self entity (%llu)!", context->originator); @@ -69,7 +69,7 @@ void StunBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStr bool blocked = false; - auto* target = EntityManager::Instance()->GetEntity(branch.target); + auto* target = Game::entityManager->GetEntity(branch.target); if (target != nullptr) { auto* destroyableComponent = target->GetComponent(); diff --git a/dGame/dBehaviors/SwitchBehavior.cpp b/dGame/dBehaviors/SwitchBehavior.cpp index c010f31b..d65191d2 100644 --- a/dGame/dBehaviors/SwitchBehavior.cpp +++ b/dGame/dBehaviors/SwitchBehavior.cpp @@ -16,7 +16,7 @@ void SwitchBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStre }; } - auto* entity = EntityManager::Instance()->GetEntity(context->originator); + auto* entity = Game::entityManager->GetEntity(context->originator); if (entity == nullptr) { return; @@ -30,7 +30,7 @@ void SwitchBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStre Game::logger->LogDebug("SwitchBehavior", "[%i] State: (%d), imagination: (%i) / (%f)", entity->GetLOT(), state, destroyableComponent->GetImagination(), destroyableComponent->GetMaxImagination()); - if (state || (entity->GetLOT() == 8092 && destroyableComponent->GetImagination() >= m_imagination)) { + if (state) { this->m_actionTrue->Handle(context, bitStream, branch); } else { this->m_actionFalse->Handle(context, bitStream, branch); @@ -41,7 +41,7 @@ void SwitchBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitS auto state = true; if (this->m_imagination > 0 || !this->m_isEnemyFaction) { - auto* entity = EntityManager::Instance()->GetEntity(branch.target); + auto* entity = Game::entityManager->GetEntity(branch.target); state = entity != nullptr; diff --git a/dGame/dBehaviors/TacArcBehavior.cpp b/dGame/dBehaviors/TacArcBehavior.cpp index 91df3879..b9d871f4 100644 --- a/dGame/dBehaviors/TacArcBehavior.cpp +++ b/dGame/dBehaviors/TacArcBehavior.cpp @@ -76,7 +76,7 @@ void TacArcBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStre } void TacArcBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - auto* self = EntityManager::Instance()->GetEntity(context->originator); + auto* self = Game::entityManager->GetEntity(context->originator); if (self == nullptr) { Game::logger->Log("TacArcBehavior", "Invalid self for (%llu)!", context->originator); return; @@ -85,7 +85,7 @@ void TacArcBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitS const auto* destroyableComponent = self->GetComponent(); if ((this->m_usePickedTarget || context->clientInitalized) && branch.target > 0) { - const auto* target = EntityManager::Instance()->GetEntity(branch.target); + const auto* target = Game::entityManager->GetEntity(branch.target); if (target == nullptr) { return; @@ -120,7 +120,7 @@ void TacArcBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitS // Find all valid targets, based on whether we target enemies or friends for (const auto& contextTarget : context->GetValidTargets()) { if (destroyableComponent != nullptr) { - const auto* targetEntity = EntityManager::Instance()->GetEntity(contextTarget); + const auto* targetEntity = Game::entityManager->GetEntity(contextTarget); if (m_targetEnemy && destroyableComponent->IsEnemy(targetEntity) || m_targetFriend && destroyableComponent->IsFriend(targetEntity)) { @@ -136,7 +136,7 @@ void TacArcBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitS break; } - auto* entity = EntityManager::Instance()->GetEntity(validTarget); + auto* entity = Game::entityManager->GetEntity(validTarget); if (entity == nullptr) { Game::logger->Log("TacArcBehavior", "Invalid target (%llu) for (%llu)!", validTarget, context->originator); diff --git a/dGame/dBehaviors/TauntBehavior.cpp b/dGame/dBehaviors/TauntBehavior.cpp index 7ed3b897..b86cd7b5 100644 --- a/dGame/dBehaviors/TauntBehavior.cpp +++ b/dGame/dBehaviors/TauntBehavior.cpp @@ -7,7 +7,7 @@ void TauntBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - auto* target = EntityManager::Instance()->GetEntity(branch.target); + auto* target = Game::entityManager->GetEntity(branch.target); if (target == nullptr) { Game::logger->Log("TauntBehavior", "Failed to find target (%llu)!", branch.target); @@ -23,7 +23,7 @@ void TauntBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStrea } void TauntBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - auto* target = EntityManager::Instance()->GetEntity(branch.target); + auto* target = Game::entityManager->GetEntity(branch.target); if (target == nullptr) { Game::logger->Log("TauntBehavior", "Failed to find target (%llu)!", branch.target); diff --git a/dGame/dBehaviors/VentureVisionBehavior.cpp b/dGame/dBehaviors/VentureVisionBehavior.cpp index 93feb8e9..397bdebf 100644 --- a/dGame/dBehaviors/VentureVisionBehavior.cpp +++ b/dGame/dBehaviors/VentureVisionBehavior.cpp @@ -5,7 +5,7 @@ void VentureVisionBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - const auto targetEntity = EntityManager::Instance()->GetEntity(branch.target); + const auto targetEntity = Game::entityManager->GetEntity(branch.target); if (targetEntity) { auto characterComponent = targetEntity->GetComponent(); @@ -21,7 +21,7 @@ void VentureVisionBehavior::Handle(BehaviorContext* context, RakNet::BitStream* } void VentureVisionBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext branch) { - const auto targetEntity = EntityManager::Instance()->GetEntity(branch.target); + const auto targetEntity = Game::entityManager->GetEntity(branch.target); if (targetEntity) { auto characterComponent = targetEntity->GetComponent(); diff --git a/dGame/dBehaviors/VerifyBehavior.cpp b/dGame/dBehaviors/VerifyBehavior.cpp index 608e965b..6824a25f 100644 --- a/dGame/dBehaviors/VerifyBehavior.cpp +++ b/dGame/dBehaviors/VerifyBehavior.cpp @@ -8,14 +8,14 @@ void VerifyBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - auto* entity = EntityManager::Instance()->GetEntity(branch.target); + auto* entity = Game::entityManager->GetEntity(branch.target); auto success = true; if (entity == nullptr) { success = false; } else if (this->m_rangeCheck) { - auto* self = EntityManager::Instance()->GetEntity(context->originator); + auto* self = Game::entityManager->GetEntity(context->originator); if (self == nullptr) { Game::logger->Log("VerifyBehavior", "Invalid self for (%llu)", context->originator); diff --git a/dGame/dComponents/BaseCombatAIComponent.cpp b/dGame/dComponents/BaseCombatAIComponent.cpp index cccaad23..77f7a493 100644 --- a/dGame/dComponents/BaseCombatAIComponent.cpp +++ b/dGame/dComponents/BaseCombatAIComponent.cpp @@ -173,7 +173,7 @@ void BaseCombatAIComponent::Update(const float deltaTime) { } if (m_SoftTimer <= 0.0f) { - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); m_SoftTimer = 5.0f; } else { @@ -305,7 +305,7 @@ void BaseCombatAIComponent::CalculateCombat(const float deltaTime) { } if (serilizationRequired) { - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } GameMessages::SendPlayFXEffect(m_Parent->GetObjectID(), 6270, u"tether", "tether"); @@ -412,7 +412,7 @@ LWOOBJID BaseCombatAIComponent::FindTarget() { float biggestThreat = 0; for (const auto& entry : possibleTargets) { - auto* entity = EntityManager::Instance()->GetEntity(entry); + auto* entity = Game::entityManager->GetEntity(entry); if (entity == nullptr) { continue; @@ -458,7 +458,7 @@ LWOOBJID BaseCombatAIComponent::FindTarget() { std::vector deadThreats{}; for (const auto& threatTarget : m_ThreatEntries) { - auto* entity = EntityManager::Instance()->GetEntity(threatTarget.first); + auto* entity = Game::entityManager->GetEntity(threatTarget.first); if (entity == nullptr) { deadThreats.push_back(threatTarget.first); @@ -497,7 +497,7 @@ std::vector BaseCombatAIComponent::GetTargetWithinAggroRange() const { std::vector targets; for (auto id : m_Parent->GetTargetsInPhantom()) { - auto* other = EntityManager::Instance()->GetEntity(id); + auto* other = Game::entityManager->GetEntity(id); const auto distance = Vector3::DistanceSquared(m_Parent->GetPosition(), other->GetPosition()); @@ -535,11 +535,11 @@ void BaseCombatAIComponent::SetAiState(AiState newState) { if (newState == this->m_State) return; this->m_State = newState; m_DirtyStateOrTarget = true; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } bool BaseCombatAIComponent::IsEnemy(LWOOBJID target) const { - auto* entity = EntityManager::Instance()->GetEntity(target); + auto* entity = Game::entityManager->GetEntity(target); if (entity == nullptr) { Game::logger->Log("BaseCombatAIComponent", "Invalid entity for checking validity (%llu)!", target); @@ -588,11 +588,11 @@ void BaseCombatAIComponent::SetTarget(const LWOOBJID target) { if (this->m_Target == target) return; m_Target = target; m_DirtyStateOrTarget = true; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } Entity* BaseCombatAIComponent::GetTargetEntity() const { - return EntityManager::Instance()->GetEntity(m_Target); + return Game::entityManager->GetEntity(m_Target); } void BaseCombatAIComponent::Taunt(LWOOBJID offender, float threat) { diff --git a/dGame/dComponents/BouncerComponent.cpp b/dGame/dComponents/BouncerComponent.cpp index f6a53261..bbf928dc 100644 --- a/dGame/dComponents/BouncerComponent.cpp +++ b/dGame/dComponents/BouncerComponent.cpp @@ -36,7 +36,7 @@ Entity* BouncerComponent::GetParentEntity() const { void BouncerComponent::SetPetEnabled(bool value) { m_PetEnabled = value; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } void BouncerComponent::SetPetBouncerEnabled(bool value) { @@ -44,7 +44,7 @@ void BouncerComponent::SetPetBouncerEnabled(bool value) { GameMessages::SendBouncerActiveStatus(m_Parent->GetObjectID(), value, UNASSIGNED_SYSTEM_ADDRESS); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); if (value) { m_Parent->TriggerEvent(eTriggerEventType::PET_ON_SWITCH, m_Parent); @@ -68,7 +68,7 @@ void BouncerComponent::LookupPetSwitch() { const auto& groups = m_Parent->GetGroups(); for (const auto& group : groups) { - const auto& entities = EntityManager::Instance()->GetEntitiesInGroup(group); + const auto& entities = Game::entityManager->GetEntitiesInGroup(group); for (auto* entity : entities) { auto* switchComponent = entity->GetComponent(); @@ -79,7 +79,7 @@ void BouncerComponent::LookupPetSwitch() { m_PetSwitchLoaded = true; m_PetEnabled = true; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); Game::logger->Log("BouncerComponent", "Loaded pet bouncer"); } diff --git a/dGame/dComponents/BuildBorderComponent.cpp b/dGame/dComponents/BuildBorderComponent.cpp index f9ead9e4..af31f939 100644 --- a/dGame/dComponents/BuildBorderComponent.cpp +++ b/dGame/dComponents/BuildBorderComponent.cpp @@ -17,7 +17,7 @@ BuildBorderComponent::~BuildBorderComponent() { void BuildBorderComponent::OnUse(Entity* originator) { if (originator->GetCharacter()) { - const auto& entities = EntityManager::Instance()->GetEntitiesInGroup("PropertyPlaque"); + const auto& entities = Game::entityManager->GetEntitiesInGroup("PropertyPlaque"); auto buildArea = m_Parent->GetObjectID(); diff --git a/dGame/dComponents/CharacterComponent.cpp b/dGame/dComponents/CharacterComponent.cpp index 82ad5507..10a4e9db 100644 --- a/dGame/dComponents/CharacterComponent.cpp +++ b/dGame/dComponents/CharacterComponent.cpp @@ -13,7 +13,7 @@ #include "VehiclePhysicsComponent.h" #include "GameMessages.h" #include "Item.h" -#include "AMFFormat.h" +#include "Amf3.h" #include "eGameMasterLevel.h" #include "eGameActivity.h" @@ -419,7 +419,7 @@ void CharacterComponent::TrackMissionCompletion(bool isAchievement) { // Achievements are tracked separately for the zone if (isAchievement) { - const auto mapID = dZoneManager::Instance()->GetZoneID().GetMapID(); + const auto mapID = Game::zoneManager->GetZoneID().GetMapID(); GetZoneStatisticsForMap(mapID).m_AchievementsCollected++; } } @@ -480,7 +480,7 @@ void CharacterComponent::TrackArmorDelta(int32_t armor) { void CharacterComponent::TrackRebuildComplete() { UpdatePlayerStatistic(QuickBuildsCompleted); - const auto mapID = dZoneManager::Instance()->GetZoneID().GetMapID(); + const auto mapID = Game::zoneManager->GetZoneID().GetMapID(); GetZoneStatisticsForMap(mapID).m_QuickBuildsCompleted++; } @@ -734,6 +734,6 @@ void CharacterComponent::RemoveVentureVisionEffect(std::string ventureVisionType void CharacterComponent::UpdateClientMinimap(bool showFaction, std::string ventureVisionType) const { if (!m_Parent) return; AMFArrayValue arrayToSend; - arrayToSend.InsertValue(ventureVisionType, showFaction ? static_cast(new AMFTrueValue()) : static_cast(new AMFFalseValue())); - GameMessages::SendUIMessageServerToSingleClient(m_Parent, m_Parent ? m_Parent->GetSystemAddress() : UNASSIGNED_SYSTEM_ADDRESS, "SetFactionVisibility", &arrayToSend); + arrayToSend.Insert(ventureVisionType, showFaction); + GameMessages::SendUIMessageServerToSingleClient(m_Parent, m_Parent ? m_Parent->GetSystemAddress() : UNASSIGNED_SYSTEM_ADDRESS, "SetFactionVisibility", arrayToSend); } diff --git a/dGame/dComponents/ControllablePhysicsComponent.cpp b/dGame/dComponents/ControllablePhysicsComponent.cpp index 1b8627a7..a658ccd7 100644 --- a/dGame/dComponents/ControllablePhysicsComponent.cpp +++ b/dGame/dComponents/ControllablePhysicsComponent.cpp @@ -194,7 +194,7 @@ void ControllablePhysicsComponent::UpdateXml(tinyxml2::XMLDocument* doc) { return; } - auto zoneInfo = dZoneManager::Instance()->GetZone()->GetZoneID(); + auto zoneInfo = Game::zoneManager->GetZone()->GetZoneID(); if (zoneInfo.GetMapID() != 0 && zoneInfo.GetCloneID() == 0) { character->SetAttribute("lzx", m_Position.x); @@ -300,7 +300,7 @@ void ControllablePhysicsComponent::RemovePickupRadiusScale(float value) { auto candidateRadius = m_ActivePickupRadiusScales[i]; if (m_PickupRadius < candidateRadius) m_PickupRadius = candidateRadius; } - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } void ControllablePhysicsComponent::AddSpeedboost(float value) { @@ -320,14 +320,14 @@ void ControllablePhysicsComponent::RemoveSpeedboost(float value) { // Recalculate speedboost since we removed one m_SpeedBoost = 0.0f; - if (m_ActiveSpeedBoosts.size() == 0) { // no active speed boosts left, so return to base speed + if (m_ActiveSpeedBoosts.empty()) { // no active speed boosts left, so return to base speed auto* levelProgressionComponent = m_Parent->GetComponent(); if (levelProgressionComponent) m_SpeedBoost = levelProgressionComponent->GetSpeedBase(); } else { // Used the last applied speedboost m_SpeedBoost = m_ActiveSpeedBoosts.back(); } SetSpeedMultiplier(m_SpeedBoost / 500.0f); // 500 being the base speed - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } void ControllablePhysicsComponent::ActivateBubbleBuff(eBubbleType bubbleType, bool specialAnims){ @@ -339,13 +339,13 @@ void ControllablePhysicsComponent::ActivateBubbleBuff(eBubbleType bubbleType, bo m_IsInBubble = true; m_DirtyBubble = true; m_SpecialAnims = specialAnims; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } void ControllablePhysicsComponent::DeactivateBubbleBuff(){ m_DirtyBubble = true; m_IsInBubble = false; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); }; void ControllablePhysicsComponent::SetStunImmunity( diff --git a/dGame/dComponents/ControllablePhysicsComponent.h b/dGame/dComponents/ControllablePhysicsComponent.h index d6088718..470a7af4 100644 --- a/dGame/dComponents/ControllablePhysicsComponent.h +++ b/dGame/dComponents/ControllablePhysicsComponent.h @@ -276,7 +276,7 @@ public: * The speed boosts of this component. * @return All active Speed boosts for this component. */ - std::vector GetActiveSpeedboosts() { return m_ActivePickupRadiusScales; }; + std::vector GetActiveSpeedboosts() { return m_ActiveSpeedBoosts; }; /** * Activates the Bubble Buff diff --git a/dGame/dComponents/DestroyableComponent.cpp b/dGame/dComponents/DestroyableComponent.cpp index 7e7d44aa..4c726bad 100644 --- a/dGame/dComponents/DestroyableComponent.cpp +++ b/dGame/dComponents/DestroyableComponent.cpp @@ -4,8 +4,8 @@ #include "Game.h" #include "dConfig.h" -#include "AMFFormat.h" -#include "AMFFormat_BitStream.h" +#include "Amf3.h" +#include "AmfSerialize.h" #include "GameMessages.h" #include "User.h" #include "CDClientManager.h" @@ -51,7 +51,7 @@ DestroyableComponent::DestroyableComponent(Entity* parent) : Component(parent) { m_IsGMImmune = false; m_IsShielded = false; m_DamageToAbsorb = 0; - m_HasBricks = false; + m_IsModuleAssembly = m_Parent->HasComponent(eReplicaComponentType::MODULE_ASSEMBLY); m_DirtyThreatList = false; m_HasThreats = false; m_ExplodeFactor = 1.0f; @@ -163,7 +163,7 @@ void DestroyableComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsIn outBitStream->Write(m_IsSmashed); if (m_IsSmashable) { - outBitStream->Write(m_HasBricks); + outBitStream->Write(m_IsModuleAssembly); outBitStream->Write(m_ExplodeFactor != 1.0f); if (m_ExplodeFactor != 1.0f) outBitStream->Write(m_ExplodeFactor); } @@ -245,19 +245,15 @@ void DestroyableComponent::SetMaxHealth(float value, bool playAnim) { if (playAnim) { // Now update the player bar if (!m_Parent->GetParentUser()) return; - AMFStringValue* amount = new AMFStringValue(); - amount->SetStringValue(std::to_string(difference)); - AMFStringValue* type = new AMFStringValue(); - type->SetStringValue("health"); AMFArrayValue args; - args.InsertValue("amount", amount); - args.InsertValue("type", type); + args.Insert("amount", std::to_string(difference)); + args.Insert("type", "health"); - GameMessages::SendUIMessageServerToSingleClient(m_Parent, m_Parent->GetParentUser()->GetSystemAddress(), "MaxPlayerBarUpdate", &args); + GameMessages::SendUIMessageServerToSingleClient(m_Parent, m_Parent->GetParentUser()->GetSystemAddress(), "MaxPlayerBarUpdate", args); } - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } void DestroyableComponent::SetArmor(int32_t value) { @@ -290,19 +286,15 @@ void DestroyableComponent::SetMaxArmor(float value, bool playAnim) { if (playAnim) { // Now update the player bar if (!m_Parent->GetParentUser()) return; - AMFStringValue* amount = new AMFStringValue(); - amount->SetStringValue(std::to_string(value)); - AMFStringValue* type = new AMFStringValue(); - type->SetStringValue("armor"); AMFArrayValue args; - args.InsertValue("amount", amount); - args.InsertValue("type", type); + args.Insert("amount", std::to_string(value)); + args.Insert("type", "armor"); - GameMessages::SendUIMessageServerToSingleClient(m_Parent, m_Parent->GetParentUser()->GetSystemAddress(), "MaxPlayerBarUpdate", &args); + GameMessages::SendUIMessageServerToSingleClient(m_Parent, m_Parent->GetParentUser()->GetSystemAddress(), "MaxPlayerBarUpdate", args); } - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } void DestroyableComponent::SetImagination(int32_t value) { @@ -334,18 +326,14 @@ void DestroyableComponent::SetMaxImagination(float value, bool playAnim) { if (playAnim) { // Now update the player bar if (!m_Parent->GetParentUser()) return; - AMFStringValue* amount = new AMFStringValue(); - amount->SetStringValue(std::to_string(difference)); - AMFStringValue* type = new AMFStringValue(); - type->SetStringValue("imagination"); AMFArrayValue args; - args.InsertValue("amount", amount); - args.InsertValue("type", type); + args.Insert("amount", std::to_string(difference)); + args.Insert("type", "imagination"); - GameMessages::SendUIMessageServerToSingleClient(m_Parent, m_Parent->GetParentUser()->GetSystemAddress(), "MaxPlayerBarUpdate", &args); + GameMessages::SendUIMessageServerToSingleClient(m_Parent, m_Parent->GetParentUser()->GetSystemAddress(), "MaxPlayerBarUpdate", args); } - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } void DestroyableComponent::SetDamageToAbsorb(int32_t value) { @@ -494,11 +482,11 @@ LWOOBJID DestroyableComponent::GetKillerID() const { } Entity* DestroyableComponent::GetKiller() const { - return EntityManager::Instance()->GetEntity(m_KillerID); + return Game::entityManager->GetEntity(m_KillerID); } bool DestroyableComponent::CheckValidity(const LWOOBJID target, const bool ignoreFactions, const bool targetEnemy, const bool targetFriend) const { - auto* targetEntity = EntityManager::Instance()->GetEntity(target); + auto* targetEntity = Game::entityManager->GetEntity(target); if (targetEntity == nullptr) { Game::logger->Log("DestroyableComponent", "Invalid entity for checking validity (%llu)!", target); @@ -544,7 +532,7 @@ void DestroyableComponent::Heal(const uint32_t health) { SetHealth(current); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } @@ -562,7 +550,7 @@ void DestroyableComponent::Imagine(const int32_t deltaImagination) { SetImagination(current); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } @@ -576,7 +564,7 @@ void DestroyableComponent::Repair(const uint32_t armor) { SetArmor(current); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } @@ -638,7 +626,7 @@ void DestroyableComponent::Damage(uint32_t damage, const LWOOBJID source, uint32 if (possessor) { auto possessableId = possessor->GetPossessable(); if (possessableId != LWOOBJID_EMPTY) { - auto possessable = EntityManager::Instance()->GetEntity(possessableId); + auto possessable = Game::entityManager->GetEntity(possessableId); if (possessable) { possessor->Dismount(possessable); } @@ -650,10 +638,10 @@ void DestroyableComponent::Damage(uint32_t damage, const LWOOBJID source, uint32 } if (echo) { - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } - auto* attacker = EntityManager::Instance()->GetEntity(source); + auto* attacker = Game::entityManager->GetEntity(source); m_Parent->OnHit(attacker); m_Parent->OnHitOrHealResult(attacker, sourceDamage); NotifySubscribers(attacker, sourceDamage); @@ -673,7 +661,7 @@ void DestroyableComponent::Damage(uint32_t damage, const LWOOBJID source, uint32 } //check if hardcore mode is enabled - if (EntityManager::Instance()->GetHardcoreMode()) { + if (Game::entityManager->GetHardcoreMode()) { DoHardcoreModeDrops(source); } @@ -708,12 +696,12 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType SetArmor(0); SetHealth(0); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } m_KillerID = source; - auto* owner = EntityManager::Instance()->GetEntity(source); + auto* owner = Game::entityManager->GetEntity(source); if (owner != nullptr) { owner = owner->GetOwner(); // If the owner is overwritten, we collect that here @@ -733,7 +721,7 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType if (missions != nullptr) { if (team != nullptr) { for (const auto memberId : team->members) { - auto* member = EntityManager::Instance()->GetEntity(memberId); + auto* member = Game::entityManager->GetEntity(memberId); if (member == nullptr) continue; @@ -773,12 +761,12 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType if (team->lootOption == 0) { // Round robin specificOwner = TeamManager::Instance()->GetNextLootOwner(team); - auto* member = EntityManager::Instance()->GetEntity(specificOwner); + auto* member = Game::entityManager->GetEntity(specificOwner); if (member) LootGenerator::Instance().DropLoot(member, m_Parent, lootMatrixId, GetMinCoins(), GetMaxCoins()); } else { for (const auto memberId : team->members) { // Free for all - auto* member = EntityManager::Instance()->GetEntity(memberId); + auto* member = Game::entityManager->GetEntity(memberId); if (member == nullptr) continue; @@ -791,13 +779,13 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType } } else { //Check if this zone allows coin drops - if (dZoneManager::Instance()->GetPlayerLoseCoinOnDeath()) { + if (Game::zoneManager->GetPlayerLoseCoinOnDeath()) { auto* character = m_Parent->GetCharacter(); uint64_t coinsTotal = character->GetCoins(); - const uint64_t minCoinsToLose = dZoneManager::Instance()->GetWorldConfig()->coinsLostOnDeathMin; + const uint64_t minCoinsToLose = Game::zoneManager->GetWorldConfig()->coinsLostOnDeathMin; if (coinsTotal >= minCoinsToLose) { - const uint64_t maxCoinsToLose = dZoneManager::Instance()->GetWorldConfig()->coinsLostOnDeathMax; - const float coinPercentageToLose = dZoneManager::Instance()->GetWorldConfig()->coinsLostOnDeathPercent; + const uint64_t maxCoinsToLose = Game::zoneManager->GetWorldConfig()->coinsLostOnDeathMax; + const float coinPercentageToLose = Game::zoneManager->GetWorldConfig()->coinsLostOnDeathPercent; uint64_t coinsToLose = std::max(static_cast(coinsTotal * coinPercentageToLose), minCoinsToLose); coinsToLose = std::min(maxCoinsToLose, coinsToLose); @@ -809,12 +797,12 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType } } - Entity* zoneControl = EntityManager::Instance()->GetZoneControlEntity(); + Entity* zoneControl = Game::entityManager->GetZoneControlEntity(); for (CppScripts::Script* script : CppScripts::GetEntityScripts(zoneControl)) { script->OnPlayerDied(zoneControl, m_Parent); } - std::vector scriptedActs = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::SCRIPTED_ACTIVITY); + std::vector scriptedActs = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SCRIPTED_ACTIVITY); for (Entity* scriptEntity : scriptedActs) { if (scriptEntity->GetObjectID() != zoneControl->GetObjectID()) { // Don't want to trigger twice on instance worlds for (CppScripts::Script* script : CppScripts::GetEntityScripts(scriptEntity)) { @@ -977,7 +965,7 @@ void DestroyableComponent::FixStats() { destroyableComponent->SetImagination(currentImagination); // Serialize the entity - EntityManager::Instance()->SerializeEntity(entity); + Game::entityManager->SerializeEntity(entity); } void DestroyableComponent::AddOnHitCallback(const std::function& callback) { @@ -991,12 +979,12 @@ void DestroyableComponent::DoHardcoreModeDrops(const LWOOBJID source){ auto* character = m_Parent->GetComponent(); auto uscore = character->GetUScore(); - auto uscoreToLose = uscore * (EntityManager::Instance()->GetHardcoreLoseUscoreOnDeathPercent() / 100); + auto uscoreToLose = uscore * (Game::entityManager->GetHardcoreLoseUscoreOnDeathPercent() / 100); character->SetUScore(uscore - uscoreToLose); GameMessages::SendModifyLEGOScore(m_Parent, m_Parent->GetSystemAddress(), -uscoreToLose, eLootSourceType::MISSION); - if (EntityManager::Instance()->GetHardcoreDropinventoryOnDeath()) { + if (Game::entityManager->GetHardcoreDropinventoryOnDeath()) { //drop all items from inventory: auto* inventory = m_Parent->GetComponent(); if (inventory) { @@ -1013,7 +1001,7 @@ void DestroyableComponent::DoHardcoreModeDrops(const LWOOBJID source){ GameMessages::SendDropClientLoot(m_Parent, source, item.second->GetLot(), 0, m_Parent->GetPosition(), item.second->GetCount()); item.second->SetCount(0, false, false); } - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } } } @@ -1033,25 +1021,25 @@ void DestroyableComponent::DoHardcoreModeDrops(const LWOOBJID source){ // Reload the player since we can't normally reduce uscore from the server and we want the UI to update // do this last so we don't get killed.... again - EntityManager::Instance()->DestructEntity(m_Parent); - EntityManager::Instance()->ConstructEntity(m_Parent); + Game::entityManager->DestructEntity(m_Parent); + Game::entityManager->ConstructEntity(m_Parent); return; } //award the player some u-score: - auto* player = EntityManager::Instance()->GetEntity(source); + auto* player = Game::entityManager->GetEntity(source); if (player && player->IsPlayer()) { auto* playerStats = player->GetComponent(); if (playerStats) { //get the maximum health from this enemy: auto maxHealth = GetMaxHealth(); - int uscore = maxHealth * EntityManager::Instance()->GetHardcoreUscoreEnemiesMultiplier(); + int uscore = maxHealth * Game::entityManager->GetHardcoreUscoreEnemiesMultiplier(); playerStats->SetUScore(playerStats->GetUScore() + uscore); GameMessages::SendModifyLEGOScore(player, player->GetSystemAddress(), uscore, eLootSourceType::MISSION); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } } } diff --git a/dGame/dComponents/DestroyableComponent.h b/dGame/dComponents/DestroyableComponent.h index 66c8374d..5e5133b7 100644 --- a/dGame/dComponents/DestroyableComponent.h +++ b/dGame/dComponents/DestroyableComponent.h @@ -239,7 +239,7 @@ public: * Returns whether or not this entity has bricks flying out when smashed * @return whether or not this entity has bricks flying out when smashed */ - bool GetHasBricks() const { return m_HasBricks; } + bool GetHasBricks() const { return m_IsModuleAssembly; } /** * Sets the multiplier for the explosion that's visible when the bricks fly out when this entity is smashed @@ -546,7 +546,7 @@ private: /** * Whether this entity has bricks flying out when smashed (causes the client to look up the files) */ - bool m_HasBricks; + bool m_IsModuleAssembly; /** * The rate at which bricks fly out when smashed diff --git a/dGame/dComponents/InventoryComponent.cpp b/dGame/dComponents/InventoryComponent.cpp index 907356ce..66b47e52 100644 --- a/dGame/dComponents/InventoryComponent.cpp +++ b/dGame/dComponents/InventoryComponent.cpp @@ -38,7 +38,7 @@ #include "CDObjectSkillsTable.h" #include "CDSkillBehaviorTable.h" -InventoryComponent::InventoryComponent(Entity* parent, tinyxml2::XMLDocument* document): Component(parent) { +InventoryComponent::InventoryComponent(Entity* parent, tinyxml2::XMLDocument* document) : Component(parent) { this->m_Dirty = true; this->m_Equipped = {}; this->m_Pushed = {}; @@ -826,18 +826,26 @@ void InventoryComponent::EquipItem(Item* item, const bool skipChecks) { if (character != nullptr && !skipChecks) { // Hacky proximity rocket if (item->GetLot() == 6416) { - const auto rocketLauchPads = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::ROCKET_LAUNCH); + const auto rocketLauchPads = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::ROCKET_LAUNCH); const auto position = m_Parent->GetPosition(); - for (auto* lauchPad : rocketLauchPads) { - if (Vector3::DistanceSquared(lauchPad->GetPosition(), position) > 13 * 13) continue; + for (auto* launchPad : rocketLauchPads) { + if (!launchPad) continue; + + auto prereq = launchPad->GetVarAsString(u"rocketLaunchPreCondition"); + if (!prereq.empty()) { + PreconditionExpression expression(prereq); + if (!expression.Check(m_Parent)) continue; + } + + if (Vector3::DistanceSquared(launchPad->GetPosition(), position) > 13 * 13) continue; auto* characterComponent = m_Parent->GetComponent(); if (characterComponent != nullptr) characterComponent->SetLastRocketItemID(item->GetId()); - lauchPad->OnUse(m_Parent); + launchPad->OnUse(m_Parent); break; } @@ -879,7 +887,7 @@ void InventoryComponent::EquipItem(Item* item, const bool skipChecks) { EquipScripts(item); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } void InventoryComponent::UnEquipItem(Item* item) { @@ -909,12 +917,12 @@ void InventoryComponent::UnEquipItem(Item* item) { UnequipScripts(item); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); // Trigger property event if (PropertyManagementComponent::Instance() != nullptr && item->GetCount() > 0 && Inventory::FindInventoryTypeForLot(item->GetLot()) == MODELS) { PropertyManagementComponent::Instance()->GetParent()->OnZonePropertyModelRemovedWhileEquipped(m_Parent); - dZoneManager::Instance()->GetZoneControlObject()->OnZonePropertyModelRemovedWhileEquipped(m_Parent); + Game::zoneManager->GetZoneControlObject()->OnZonePropertyModelRemovedWhileEquipped(m_Parent); } } @@ -960,7 +968,7 @@ void InventoryComponent::HandlePossession(Item* item) { if (possessorComponent->GetIsDismounting()) return; // Check to see if we are already mounting something - auto* currentlyPossessedEntity = EntityManager::Instance()->GetEntity(possessorComponent->GetPossessable()); + auto* currentlyPossessedEntity = Game::entityManager->GetEntity(possessorComponent->GetPossessable()); auto currentlyPossessedItem = possessorComponent->GetMountItemID(); if (currentlyPossessedItem) { @@ -983,26 +991,15 @@ void InventoryComponent::HandlePossession(Item* item) { info.rot = startRotation; info.spawnerID = m_Parent->GetObjectID(); - auto* mount = EntityManager::Instance()->CreateEntity(info, nullptr, m_Parent); + auto* mount = Game::entityManager->CreateEntity(info, nullptr, m_Parent); // Check to see if the mount is a vehicle, if so, flip it auto* vehicleComponent = mount->GetComponent(); - if (vehicleComponent) { - auto angles = startRotation.GetEulerAngles(); - // Make it right side up - angles.x -= PI; - // Make it going in the direction of the player - angles.y -= PI; - startRotation = NiQuaternion::FromEulerAngles(angles); - mount->SetRotation(startRotation); - // We're pod racing now - characterComponent->SetIsRacing(true); - } + if (vehicleComponent) characterComponent->SetIsRacing(true); // Setup the destroyable stats auto* destroyableComponent = mount->GetComponent(); if (destroyableComponent) { - destroyableComponent->SetIsSmashable(false); destroyableComponent->SetIsImmune(true); } @@ -1019,9 +1016,9 @@ void InventoryComponent::HandlePossession(Item* item) { GameMessages::SendSetJetPackMode(m_Parent, false); // Make it go to the client - EntityManager::Instance()->ConstructEntity(mount); + Game::entityManager->ConstructEntity(mount); // Update the possessor - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); // have to unlock the input so it vehicle can be driven if (vehicleComponent) GameMessages::SendVehicleUnlockInput(mount->GetObjectID(), false, m_Parent->GetSystemAddress()); @@ -1083,7 +1080,7 @@ void InventoryComponent::PopEquippedItems() { destroyableComponent->SetHealth(static_cast(destroyableComponent->GetMaxHealth())); destroyableComponent->SetArmor(static_cast(destroyableComponent->GetMaxArmor())); destroyableComponent->SetImagination(static_cast(destroyableComponent->GetMaxImagination())); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } m_Dirty = true; @@ -1259,7 +1256,7 @@ void InventoryComponent::SpawnPet(Item* item) { info.rot = NiQuaternion::IDENTITY; info.spawnerID = m_Parent->GetObjectID(); - auto* pet = EntityManager::Instance()->CreateEntity(info); + auto* pet = Game::entityManager->CreateEntity(info); auto* petComponent = pet->GetComponent(); @@ -1267,7 +1264,7 @@ void InventoryComponent::SpawnPet(Item* item) { petComponent->Activate(item); } - EntityManager::Instance()->ConstructEntity(pet); + Game::entityManager->ConstructEntity(pet); } void InventoryComponent::SetDatabasePet(LWOOBJID id, const DatabasePet& data) { @@ -1376,7 +1373,7 @@ void InventoryComponent::SetNPCItems(const std::vector& items) { UpdateSlot(info.equipLocation, { id, static_cast(item), 1, slot++ }, true); } - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } InventoryComponent::~InventoryComponent() { diff --git a/dGame/dComponents/LUPExhibitComponent.cpp b/dGame/dComponents/LUPExhibitComponent.cpp index 7b8c85ba..deb3cc8c 100644 --- a/dGame/dComponents/LUPExhibitComponent.cpp +++ b/dGame/dComponents/LUPExhibitComponent.cpp @@ -35,7 +35,7 @@ void LUPExhibitComponent::NextExhibit() { m_Exhibit = m_Exhibits[m_ExhibitIndex]; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } void LUPExhibitComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, uint32_t& flags) { diff --git a/dGame/dComponents/MissionComponent.cpp b/dGame/dComponents/MissionComponent.cpp index 0ae0f07e..40411902 100644 --- a/dGame/dComponents/MissionComponent.cpp +++ b/dGame/dComponents/MissionComponent.cpp @@ -13,7 +13,7 @@ #include "InventoryComponent.h" #include "GameMessages.h" #include "Game.h" -#include "AMFFormat.h" +#include "Amf3.h" #include "dZoneManager.h" #include "Mail.h" #include "MissionPrerequisites.h" @@ -26,7 +26,7 @@ std::unordered_map> MissionComponent: //! Initializer MissionComponent::MissionComponent(Entity* parent) : Component(parent) { - m_LastUsedMissionOrderUID = dZoneManager::Instance()->GetUniqueMissionIdStartingValue(); + m_LastUsedMissionOrderUID = Game::zoneManager->GetUniqueMissionIdStartingValue(); } //! Destructor diff --git a/dGame/dComponents/MovementAIComponent.cpp b/dGame/dComponents/MovementAIComponent.cpp index 2a0155a6..f1df7172 100644 --- a/dGame/dComponents/MovementAIComponent.cpp +++ b/dGame/dComponents/MovementAIComponent.cpp @@ -377,7 +377,7 @@ bool MovementAIComponent::Warp(const NiPoint3& point) { SetPosition(destination); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); return true; } @@ -406,7 +406,7 @@ void MovementAIComponent::Stop() { m_CurrentSpeed = 0; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } void MovementAIComponent::PullToPoint(const NiPoint3& point) { @@ -448,13 +448,14 @@ float MovementAIComponent::GetBaseSpeed(LOT lot) { foundComponent: - float speed; + // Client defaults speed to 10 and if the speed is also null in the table, it defaults to 10. + float speed = 10.0f; - if (physicsComponent == nullptr) { - speed = 8; - } else { - speed = physicsComponent->speed; - } + if (physicsComponent) speed = physicsComponent->speed; + + float delta = fabs(speed) - 1.0f; + + if (delta <= std::numeric_limits::epsilon()) speed = 10.0f; m_PhysicsSpeedCache[lot] = speed; diff --git a/dGame/dComponents/MovingPlatformComponent.cpp b/dGame/dComponents/MovingPlatformComponent.cpp index 2666c60c..f4dcdbe9 100644 --- a/dGame/dComponents/MovingPlatformComponent.cpp +++ b/dGame/dComponents/MovingPlatformComponent.cpp @@ -59,7 +59,7 @@ MovingPlatformComponent::MovingPlatformComponent(Entity* parent, const std::stri m_MoverSubComponentType = eMoverSubComponentType::mover; m_MoverSubComponent = new MoverSubComponent(m_Parent->GetDefaultPosition()); m_PathName = GeneralUtils::ASCIIToUTF16(pathName); - m_Path = dZoneManager::Instance()->GetZone()->GetPath(pathName); + m_Path = Game::zoneManager->GetZone()->GetPath(pathName); m_NoAutoStart = false; if (m_Path == nullptr) { @@ -133,7 +133,7 @@ void MovingPlatformComponent::SetMovementState(eMovementPlatformState value) { subComponent->mState = value; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } void MovingPlatformComponent::GotoWaypoint(uint32_t index, bool stopAtWaypoint) { @@ -194,7 +194,7 @@ void MovingPlatformComponent::StartPathing() { //GameMessages::SendPlatformResync(m_Parent, UNASSIGNED_SYSTEM_ADDRESS); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } void MovingPlatformComponent::ContinuePathing() { @@ -242,7 +242,7 @@ void MovingPlatformComponent::ContinuePathing() { subComponent->mCurrentWaypointIndex = pathSize; switch (behavior) { case PathBehavior::Once: - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); return; case PathBehavior::Bounce: @@ -304,7 +304,7 @@ void MovingPlatformComponent::ContinuePathing() { ContinuePathing(); }); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } void MovingPlatformComponent::StopPathing() { @@ -318,7 +318,7 @@ void MovingPlatformComponent::StopPathing() { subComponent->mDesiredWaypointIndex = -1; subComponent->mShouldStopAtDesiredWaypoint = false; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); //GameMessages::SendPlatformResync(m_Parent, UNASSIGNED_SYSTEM_ADDRESS); } @@ -341,7 +341,7 @@ void MovingPlatformComponent::WarpToWaypoint(size_t index) { m_Parent->SetPosition(waypoint.position); m_Parent->SetRotation(waypoint.rotation); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } size_t MovingPlatformComponent::GetLastWaypointIndex() const { diff --git a/dGame/dComponents/PetComponent.cpp b/dGame/dComponents/PetComponent.cpp index 774aa92b..167fbb2f 100644 --- a/dGame/dComponents/PetComponent.cpp +++ b/dGame/dComponents/PetComponent.cpp @@ -26,6 +26,7 @@ #include "Database.h" #include "EntityInfo.h" #include "eMissionTaskType.h" +#include "RenderComponent.h" #include "eObjectBits.h" #include "eGameMasterLevel.h" @@ -153,7 +154,7 @@ void PetComponent::OnUse(Entity* originator) { } if (m_Tamer != LWOOBJID_EMPTY) { - auto* tamer = EntityManager::Instance()->GetEntity(m_Tamer); + auto* tamer = Game::entityManager->GetEntity(m_Tamer); if (tamer != nullptr) { return; @@ -235,7 +236,7 @@ void PetComponent::OnUse(Entity* originator) { return; } - auto& bricks = BrickDatabase::Instance()->GetBricks(buildFile); + const auto& bricks = BrickDatabase::GetBricks(buildFile); if (bricks.empty()) { ChatPackets::SendSystemMessage(originator->GetSystemAddress(), u"Failed to load the puzzle minigame for this pet."); @@ -343,7 +344,7 @@ void PetComponent::Update(float deltaTime) { if (m_Timer <= 0) { Wander(); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } } else { m_Timer = 5; @@ -368,7 +369,7 @@ void PetComponent::Update(float deltaTime) { } if (m_TresureTime > 0) { - auto* tresure = EntityManager::Instance()->GetEntity(m_Interaction); + auto* tresure = Game::entityManager->GetEntity(m_Interaction); if (tresure == nullptr) { m_TresureTime = 0; @@ -448,7 +449,7 @@ void PetComponent::Update(float deltaTime) { NiPoint3 tresurePosition = closestTresure->GetPosition(); float distance = Vector3::DistanceSquared(position, tresurePosition); - if (distance < 3 * 3) { + if (distance < 5 * 5) { m_Interaction = closestTresure->GetObjectID(); Command(NiPoint3::ZERO, LWOOBJID_EMPTY, 1, 202, true); @@ -475,7 +476,7 @@ skipTresure: void PetComponent::TryBuild(uint32_t numBricks, bool clientFailed) { if (m_Tamer == LWOOBJID_EMPTY) return; - auto* tamer = EntityManager::Instance()->GetEntity(m_Tamer); + auto* tamer = Game::entityManager->GetEntity(m_Tamer); if (tamer == nullptr) { m_Tamer = LWOOBJID_EMPTY; @@ -497,7 +498,7 @@ void PetComponent::TryBuild(uint32_t numBricks, bool clientFailed) { destroyableComponent->SetImagination(imagination); - EntityManager::Instance()->SerializeEntity(tamer); + Game::entityManager->SerializeEntity(tamer); if (clientFailed) { if (imagination < cached->second.imaginationCost) { @@ -515,7 +516,7 @@ void PetComponent::TryBuild(uint32_t numBricks, bool clientFailed) { void PetComponent::NotifyTamingBuildSuccess(NiPoint3 position) { if (m_Tamer == LWOOBJID_EMPTY) return; - auto* tamer = EntityManager::Instance()->GetEntity(m_Tamer); + auto* tamer = Game::entityManager->GetEntity(m_Tamer); if (tamer == nullptr) { m_Tamer = LWOOBJID_EMPTY; @@ -530,7 +531,7 @@ void PetComponent::NotifyTamingBuildSuccess(NiPoint3 position) { } GameMessages::SendPlayFXEffect(tamer, -1, u"petceleb", "", LWOOBJID_EMPTY, 1, 1, true); - GameMessages::SendPlayAnimation(tamer, u"rebuild-celebrate"); + RenderComponent::PlayAnimation(tamer, u"rebuild-celebrate"); EntityInfo info{}; info.lot = cached->second.puzzleModelLot; @@ -538,11 +539,11 @@ void PetComponent::NotifyTamingBuildSuccess(NiPoint3 position) { info.rot = NiQuaternion::IDENTITY; info.spawnerID = tamer->GetObjectID(); - auto* modelEntity = EntityManager::Instance()->CreateEntity(info); + auto* modelEntity = Game::entityManager->CreateEntity(info); m_ModelId = modelEntity->GetObjectID(); - EntityManager::Instance()->ConstructEntity(modelEntity); + Game::entityManager->ConstructEntity(modelEntity); GameMessages::SendNotifyTamingModelLoadedOnServer(m_Tamer, tamer->GetSystemAddress()); @@ -638,7 +639,7 @@ void PetComponent::RequestSetPetName(std::u16string name) { return; } - auto* tamer = EntityManager::Instance()->GetEntity(m_Tamer); + auto* tamer = Game::entityManager->GetEntity(m_Tamer); if (tamer == nullptr) { m_Tamer = LWOOBJID_EMPTY; @@ -660,7 +661,7 @@ void PetComponent::RequestSetPetName(std::u16string name) { //Save our pet's new name to the db: SetPetNameForModeration(GeneralUtils::UTF16ToWTF8(name)); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); std::u16string u16name = GeneralUtils::UTF8ToUTF16(m_Name); std::u16string u16ownerName = GeneralUtils::UTF8ToUTF16(m_OwnerName); @@ -683,7 +684,7 @@ void PetComponent::RequestSetPetName(std::u16string name) { GameMessages::SendTerminateInteraction(m_Tamer, eTerminateType::FROM_INTERACTION, m_Parent->GetObjectID()); - auto* modelEntity = EntityManager::Instance()->GetEntity(m_ModelId); + auto* modelEntity = Game::entityManager->GetEntity(m_ModelId); if (modelEntity != nullptr) { modelEntity->Smash(m_Tamer); @@ -702,7 +703,7 @@ void PetComponent::RequestSetPetName(std::u16string name) { void PetComponent::ClientExitTamingMinigame(bool voluntaryExit) { if (m_Tamer == LWOOBJID_EMPTY) return; - auto* tamer = EntityManager::Instance()->GetEntity(m_Tamer); + auto* tamer = Game::entityManager->GetEntity(m_Tamer); if (tamer == nullptr) { m_Tamer = LWOOBJID_EMPTY; @@ -732,7 +733,7 @@ void PetComponent::ClientExitTamingMinigame(bool voluntaryExit) { m_Tamer = LWOOBJID_EMPTY; m_Timer = 0; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); // Notify the end of a pet taming minigame for (CppScripts::Script* script : CppScripts::GetEntityScripts(m_Parent)) { @@ -753,7 +754,7 @@ void PetComponent::StartTimer() { void PetComponent::ClientFailTamingMinigame() { if (m_Tamer == LWOOBJID_EMPTY) return; - auto* tamer = EntityManager::Instance()->GetEntity(m_Tamer); + auto* tamer = Game::entityManager->GetEntity(m_Tamer); if (tamer == nullptr) { m_Tamer = LWOOBJID_EMPTY; @@ -783,7 +784,7 @@ void PetComponent::ClientFailTamingMinigame() { m_Tamer = LWOOBJID_EMPTY; m_Timer = 0; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); // Notify the end of a pet taming minigame for (CppScripts::Script* script : CppScripts::GetEntityScripts(m_Parent)) { @@ -886,7 +887,7 @@ void PetComponent::Activate(Item* item, bool registerPet, bool fromTaming) { m_Timer = 3; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); owner->GetCharacter()->SetPlayerFlag(ePlayerFlag::FIRST_MANUAL_PET_HIBERNATE, true); @@ -1003,7 +1004,7 @@ LWOOBJID PetComponent::GetOwnerId() const { } Entity* PetComponent::GetOwner() const { - return EntityManager::Instance()->GetEntity(m_Owner); + return Game::entityManager->GetEntity(m_Owner); } LWOOBJID PetComponent::GetDatabaseId() const { @@ -1045,7 +1046,7 @@ PetComponent* PetComponent::GetTamingPet(LWOOBJID tamer) { return nullptr; } - auto* entity = EntityManager::Instance()->GetEntity(pair->second); + auto* entity = Game::entityManager->GetEntity(pair->second); if (entity == nullptr) { currentActivities.erase(tamer); @@ -1063,7 +1064,7 @@ PetComponent* PetComponent::GetActivePet(LWOOBJID owner) { return nullptr; } - auto* entity = EntityManager::Instance()->GetEntity(pair->second); + auto* entity = Game::entityManager->GetEntity(pair->second); if (entity == nullptr) { activePets.erase(owner); diff --git a/dGame/dComponents/PhantomPhysicsComponent.cpp b/dGame/dComponents/PhantomPhysicsComponent.cpp index e6272aa4..640281f8 100644 --- a/dGame/dComponents/PhantomPhysicsComponent.cpp +++ b/dGame/dComponents/PhantomPhysicsComponent.cpp @@ -362,7 +362,7 @@ void PhantomPhysicsComponent::Update(float deltaTime) { //If we are a respawn volume, inform the client: if (m_IsRespawnVolume) { - auto entity = EntityManager::Instance()->GetEntity(en->GetObjectID()); + auto entity = Game::entityManager->GetEntity(en->GetObjectID()); if (entity) { GameMessages::SendPlayerReachedRespawnCheckpoint(entity, m_RespawnPos, m_RespawnRot); @@ -403,8 +403,8 @@ void PhantomPhysicsComponent::SpawnVertices() { info.spawnerID = m_Parent->GetObjectID(); info.spawnerNodeID = 0; - Entity* newEntity = EntityManager::Instance()->CreateEntity(info, nullptr); - EntityManager::Instance()->ConstructEntity(newEntity); + Entity* newEntity = Game::entityManager->CreateEntity(info, nullptr); + Game::entityManager->ConstructEntity(newEntity); } } diff --git a/dGame/dComponents/PossessorComponent.cpp b/dGame/dComponents/PossessorComponent.cpp index 387b3479..8019f91c 100644 --- a/dGame/dComponents/PossessorComponent.cpp +++ b/dGame/dComponents/PossessorComponent.cpp @@ -13,7 +13,7 @@ PossessorComponent::PossessorComponent(Entity* parent) : Component(parent) { PossessorComponent::~PossessorComponent() { if (m_Possessable != LWOOBJID_EMPTY) { - auto* mount = EntityManager::Instance()->GetEntity(m_Possessable); + auto* mount = Game::entityManager->GetEntity(m_Possessable); if (mount) { auto* possessable = mount->GetComponent(); if (possessable) { @@ -58,8 +58,8 @@ void PossessorComponent::Mount(Entity* mount) { GameMessages::SendVehicleUnlockInput(mount->GetObjectID(), false, m_Parent->GetSystemAddress()); GameMessages::SendSetStunned(m_Parent->GetObjectID(), eStateChangeType::PUSH, m_Parent->GetSystemAddress(), LWOOBJID_EMPTY, true, false, true, false, false, false, false, true, true, true, true, true, true, true, true, true); - EntityManager::Instance()->SerializeEntity(m_Parent); - EntityManager::Instance()->SerializeEntity(mount); + Game::entityManager->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(mount); } void PossessorComponent::Dismount(Entity* mount, bool forceDismount) { @@ -73,8 +73,8 @@ void PossessorComponent::Dismount(Entity* mount, bool forceDismount) { possessableComponent->SetPossessor(LWOOBJID_EMPTY); if (forceDismount) possessableComponent->ForceDepossess(); } - EntityManager::Instance()->SerializeEntity(m_Parent); - EntityManager::Instance()->SerializeEntity(mount); + Game::entityManager->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(mount); auto characterComponent = m_Parent->GetComponent(); if (characterComponent) characterComponent->SetIsRacing(false); diff --git a/dGame/dComponents/PropertyEntranceComponent.cpp b/dGame/dComponents/PropertyEntranceComponent.cpp index 5da9a3c4..bff917d8 100644 --- a/dGame/dComponents/PropertyEntranceComponent.cpp +++ b/dGame/dComponents/PropertyEntranceComponent.cpp @@ -11,7 +11,7 @@ #include "CharacterComponent.h" #include "UserManager.h" #include "dLogger.h" -#include "AMFFormat.h" +#include "Amf3.h" #include "eObjectBits.h" #include "eGameMasterLevel.h" @@ -36,12 +36,9 @@ void PropertyEntranceComponent::OnUse(Entity* entity) { AMFArrayValue args; - auto* state = new AMFStringValue(); - state->SetStringValue("property_menu"); + args.Insert("state", "property_menu"); - args.InsertValue("state", state); - - GameMessages::SendUIMessageServerToSingleClient(entity, entity->GetSystemAddress(), "pushGameState", &args); + GameMessages::SendUIMessageServerToSingleClient(entity, entity->GetSystemAddress(), "pushGameState", args); } void PropertyEntranceComponent::OnEnterProperty(Entity* entity, uint32_t index, bool returnToZone, const SystemAddress& sysAddr) { diff --git a/dGame/dComponents/PropertyManagementComponent.cpp b/dGame/dComponents/PropertyManagementComponent.cpp index c87d0744..c8937c35 100644 --- a/dGame/dComponents/PropertyManagementComponent.cpp +++ b/dGame/dComponents/PropertyManagementComponent.cpp @@ -38,7 +38,7 @@ PropertyManagementComponent::PropertyManagementComponent(Entity* parent) : Compo instance = this; - const auto& worldId = dZoneManager::Instance()->GetZone()->GetZoneID(); + const auto& worldId = Game::zoneManager->GetZone()->GetZoneID(); const auto zoneId = worldId.GetMapID(); const auto cloneId = worldId.GetCloneID(); @@ -90,7 +90,7 @@ LWOOBJID PropertyManagementComponent::GetOwnerId() const { } Entity* PropertyManagementComponent::GetOwner() const { - return EntityManager::Instance()->GetEntity(owner); + return Game::entityManager->GetEntity(owner); } void PropertyManagementComponent::SetOwner(Entity* value) { @@ -98,7 +98,7 @@ void PropertyManagementComponent::SetOwner(Entity* value) { } std::vector PropertyManagementComponent::GetPaths() const { - const auto zoneId = dZoneManager::Instance()->GetZone()->GetWorldID(); + const auto zoneId = Game::zoneManager->GetZone()->GetWorldID(); auto query = CDClientDatabase::CreatePreppedStmt( "SELECT path FROM PropertyTemplate WHERE mapID = ?;"); @@ -185,14 +185,14 @@ bool PropertyManagementComponent::Claim(const LWOOBJID playerId) { return false; } - auto* entity = EntityManager::Instance()->GetEntity(playerId); + auto* entity = Game::entityManager->GetEntity(playerId); auto* user = entity->GetParentUser(); auto character = entity->GetCharacter(); if (!character) return false; - auto* zone = dZoneManager::Instance()->GetZone(); + auto* zone = Game::zoneManager->GetZone(); const auto& worldId = zone->GetZoneID(); const auto propertyZoneId = worldId.GetMapID(); @@ -240,7 +240,7 @@ bool PropertyManagementComponent::Claim(const LWOOBJID playerId) { return false; } - auto* zoneControlObject = dZoneManager::Instance()->GetZoneControlObject(); + auto* zoneControlObject = Game::zoneManager->GetZoneControlObject(); for (CppScripts::Script* script : CppScripts::GetEntityScripts(zoneControlObject)) { script->OnZonePropertyRented(zoneControlObject, entity); } @@ -256,7 +256,7 @@ void PropertyManagementComponent::OnStartBuilding() { LWOMAPID zoneId = 1100; - const auto entrance = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::PROPERTY_ENTRANCE); + const auto entrance = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::PROPERTY_ENTRANCE); originalPrivacyOption = privacyOption; @@ -339,9 +339,9 @@ void PropertyManagementComponent::UpdateModelPosition(const LWOOBJID id, const N info.settings.push_back(setting->Copy()); } - Entity* newEntity = EntityManager::Instance()->CreateEntity(info); + Entity* newEntity = Game::entityManager->CreateEntity(info); if (newEntity != nullptr) { - EntityManager::Instance()->ConstructEntity(newEntity); + Game::entityManager->ConstructEntity(newEntity); // Make sure the propMgmt doesn't delete our model after the server dies // Trying to do this after the entity is constructed. Shouldn't really change anything but @@ -371,14 +371,14 @@ void PropertyManagementComponent::UpdateModelPosition(const LWOOBJID id, const N info.respawnTime = 10; info.emulated = true; - info.emulator = EntityManager::Instance()->GetZoneControlEntity()->GetObjectID(); + info.emulator = Game::entityManager->GetZoneControlEntity()->GetObjectID(); info.spawnerID = persistentId; GeneralUtils::SetBit(info.spawnerID, eObjectBits::CLIENT); - const auto spawnerId = dZoneManager::Instance()->MakeSpawner(info); + const auto spawnerId = Game::zoneManager->MakeSpawner(info); - auto* spawner = dZoneManager::Instance()->GetSpawner(spawnerId); + auto* spawner = Game::zoneManager->GetSpawner(spawnerId); auto ldfModelBehavior = new LDFData(u"modelBehaviors", 0); auto userModelID = new LDFData(u"userModelID", info.spawnerID); @@ -401,7 +401,7 @@ void PropertyManagementComponent::UpdateModelPosition(const LWOOBJID id, const N GameMessages::SendGetModelsOnProperty(entity->GetObjectID(), GetModels(), UNASSIGNED_SYSTEM_ADDRESS); - EntityManager::Instance()->GetZoneControlEntity()->OnZonePropertyModelPlaced(entity); + Game::entityManager->GetZoneControlEntity()->OnZonePropertyModelPlaced(entity); }); // Progress place model missions auto missionComponent = entity->GetComponent(); @@ -433,7 +433,7 @@ void PropertyManagementComponent::DeleteModel(const LWOOBJID id, const int delet const auto spawnerId = index->second; - auto* spawner = dZoneManager::Instance()->GetSpawner(spawnerId); + auto* spawner = Game::zoneManager->GetSpawner(spawnerId); models.erase(id); @@ -441,7 +441,7 @@ void PropertyManagementComponent::DeleteModel(const LWOOBJID id, const int delet Game::logger->Log("PropertyManagementComponent", "Failed to find spawner"); } - auto* model = EntityManager::Instance()->GetEntity(id); + auto* model = Game::entityManager->GetEntity(id); if (model == nullptr) { Game::logger->Log("PropertyManagementComponent", "Failed to find model entity"); @@ -449,7 +449,7 @@ void PropertyManagementComponent::DeleteModel(const LWOOBJID id, const int delet return; } - EntityManager::Instance()->DestructEntity(model); + Game::entityManager->DestructEntity(model); Game::logger->Log("PropertyManagementComponent", "Deleting model LOT %i", model->GetLOT()); @@ -496,7 +496,7 @@ void PropertyManagementComponent::DeleteModel(const LWOOBJID id, const int delet GameMessages::SendPlaceModelResponse(entity->GetObjectID(), entity->GetSystemAddress(), NiPoint3::ZERO, LWOOBJID_EMPTY, 16, NiQuaternion::IDENTITY); if (spawner != nullptr) { - dZoneManager::Instance()->RemoveSpawner(spawner->m_Info.spawnerID); + Game::zoneManager->RemoveSpawner(spawner->m_Info.spawnerID); } else { model->Smash(LWOOBJID_EMPTY, eKillType::SILENT); } @@ -520,13 +520,13 @@ void PropertyManagementComponent::DeleteModel(const LWOOBJID id, const int delet item->Equip(); GameMessages::SendUGCEquipPostDeleteBasedOnEditMode(entity->GetObjectID(), entity->GetSystemAddress(), item->GetId(), item->GetCount()); - EntityManager::Instance()->GetZoneControlEntity()->OnZonePropertyModelPickedUp(entity); + Game::entityManager->GetZoneControlEntity()->OnZonePropertyModelPickedUp(entity); break; } case 1: // Return to inv { - EntityManager::Instance()->GetZoneControlEntity()->OnZonePropertyModelRemoved(entity); + Game::entityManager->GetZoneControlEntity()->OnZonePropertyModelRemoved(entity); break; } @@ -549,7 +549,7 @@ void PropertyManagementComponent::DeleteModel(const LWOOBJID id, const int delet GameMessages::SendPlaceModelResponse(entity->GetObjectID(), entity->GetSystemAddress(), NiPoint3::ZERO, LWOOBJID_EMPTY, 16, NiQuaternion::IDENTITY); if (spawner != nullptr) { - dZoneManager::Instance()->RemoveSpawner(spawner->m_Info.spawnerID); + Game::zoneManager->RemoveSpawner(spawner->m_Info.spawnerID); } else { model->Smash(LWOOBJID_EMPTY, eKillType::SILENT); } @@ -613,7 +613,7 @@ void PropertyManagementComponent::Load() { info.respawnTime = 10; //info.emulated = true; - //info.emulator = EntityManager::Instance()->GetZoneControlEntity()->GetObjectID(); + //info.emulator = Game::entityManager->GetZoneControlEntity()->GetObjectID(); info.spawnerID = id; @@ -652,9 +652,9 @@ void PropertyManagementComponent::Load() { node->config = settings; - const auto spawnerId = dZoneManager::Instance()->MakeSpawner(info); + const auto spawnerId = Game::zoneManager->MakeSpawner(info); - auto* spawner = dZoneManager::Instance()->GetSpawner(spawnerId); + auto* spawner = Game::zoneManager->GetSpawner(spawnerId); auto* model = spawner->Spawn(); @@ -698,7 +698,7 @@ void PropertyManagementComponent::Save() { modelIds.push_back(id); - auto* entity = EntityManager::Instance()->GetEntity(pair.first); + auto* entity = Game::entityManager->GetEntity(pair.first); if (entity == nullptr) { continue; @@ -786,7 +786,7 @@ void PropertyManagementComponent::OnQueryPropertyData(Entity* originator, const author = m_Parent->GetObjectID(); } - const auto& worldId = dZoneManager::Instance()->GetZone()->GetZoneID(); + const auto& worldId = Game::zoneManager->GetZone()->GetZoneID(); const auto zoneId = worldId.GetMapID(); Game::logger->Log("Properties", "Getting property info for %d", zoneId); diff --git a/dGame/dComponents/PropertyVendorComponent.cpp b/dGame/dComponents/PropertyVendorComponent.cpp index ed89bfc7..cff4995c 100644 --- a/dGame/dComponents/PropertyVendorComponent.cpp +++ b/dGame/dComponents/PropertyVendorComponent.cpp @@ -43,7 +43,7 @@ void PropertyVendorComponent::OnBuyFromVendor(Entity* originator, const bool con GameMessages::SendPropertyRentalResponse(m_Parent->GetObjectID(), 0, 0, 0, 0, originator->GetSystemAddress()); - auto* controller = dZoneManager::Instance()->GetZoneControlObject(); + auto* controller = Game::zoneManager->GetZoneControlObject(); controller->OnFireEventServerSide(m_Parent, "propertyRented"); diff --git a/dGame/dComponents/RacingControlComponent.cpp b/dGame/dComponents/RacingControlComponent.cpp index 703ec7f3..5de24445 100644 --- a/dGame/dComponents/RacingControlComponent.cpp +++ b/dGame/dComponents/RacingControlComponent.cpp @@ -23,6 +23,9 @@ #include "dConfig.h" #include "Loot.h" #include "eMissionTaskType.h" +#include "LeaderboardManager.h" +#include "dZoneManager.h" +#include "CDActivitiesTable.h" #ifndef M_PI #define M_PI 3.14159265358979323846264338327950288 @@ -45,36 +48,14 @@ RacingControlComponent::RacingControlComponent(Entity* parent) m_EmptyTimer = 0; m_SoloRacing = Game::config->GetValue("solo_racing") == "1"; - // Select the main world ID as fallback when a player fails to load. - + m_MainWorld = 1200; const auto worldID = Game::server->GetZoneID(); + if (Game::zoneManager->CheckIfAccessibleZone((worldID/10)*10)) m_MainWorld = (worldID/10)*10; - switch (worldID) { - case 1203: - m_ActivityID = 42; - m_MainWorld = 1200; - break; - - case 1261: - m_ActivityID = 60; - m_MainWorld = 1260; - break; - - case 1303: - m_ActivityID = 39; - m_MainWorld = 1300; - break; - - case 1403: - m_ActivityID = 54; - m_MainWorld = 1400; - break; - - default: - m_ActivityID = 42; - m_MainWorld = 1200; - break; - } + m_ActivityID = 42; + CDActivitiesTable* activitiesTable = CDClientManager::Instance().GetTable(); + std::vector activities = activitiesTable->Query([=](CDActivities entry) {return (entry.instanceMapID == worldID); }); + for (CDActivities activity : activities) m_ActivityID = activity.ActivityID; } RacingControlComponent::~RacingControlComponent() {} @@ -125,10 +106,10 @@ void RacingControlComponent::LoadPlayerVehicle(Entity* player, // Calculate the vehicle's starting position. - auto* path = dZoneManager::Instance()->GetZone()->GetPath( + auto* path = Game::zoneManager->GetZone()->GetPath( GeneralUtils::UTF16ToWTF8(m_PathName)); - auto spawnPointEntities = EntityManager::Instance()->GetEntitiesByLOT(4843); + auto spawnPointEntities = Game::entityManager->GetEntitiesByLOT(4843); auto startPosition = NiPoint3::ZERO; auto startRotation = NiQuaternion::IDENTITY; const std::string placementAsString = std::to_string(positionNumber); @@ -144,8 +125,7 @@ void RacingControlComponent::LoadPlayerVehicle(Entity* player, // Make sure the player is at the correct position. GameMessages::SendTeleport(player->GetObjectID(), startPosition, - startRotation, player->GetSystemAddress(), true, - true); + startRotation, player->GetSystemAddress(), true); // Spawn the vehicle entity. @@ -156,7 +136,7 @@ void RacingControlComponent::LoadPlayerVehicle(Entity* player, info.spawnerID = m_Parent->GetObjectID(); auto* carEntity = - EntityManager::Instance()->CreateEntity(info, nullptr, m_Parent); + Game::entityManager->CreateEntity(info, nullptr, m_Parent); // Make the vehicle a child of the racing controller. m_Parent->AddChild(carEntity); @@ -227,9 +207,9 @@ void RacingControlComponent::LoadPlayerVehicle(Entity* player, // Construct and serialize everything when done. - EntityManager::Instance()->ConstructEntity(carEntity); - EntityManager::Instance()->SerializeEntity(player); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->ConstructEntity(carEntity); + Game::entityManager->SerializeEntity(player); + Game::entityManager->SerializeEntity(m_Parent); GameMessages::SendRacingSetPlayerResetInfo( m_Parent->GetObjectID(), 0, 0, player->GetObjectID(), startPosition, 1, @@ -240,7 +220,7 @@ void RacingControlComponent::LoadPlayerVehicle(Entity* player, // Reset the player to the start position during downtime, in case something // went wrong. m_Parent->AddCallbackTimer(1, [this, playerID]() { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) { return; @@ -263,11 +243,9 @@ void RacingControlComponent::LoadPlayerVehicle(Entity* player, // Make sure everything has the correct position. GameMessages::SendTeleport(player->GetObjectID(), startPosition, - startRotation, player->GetSystemAddress(), true, - true); + startRotation, player->GetSystemAddress(), true); GameMessages::SendTeleport(carEntity->GetObjectID(), startPosition, - startRotation, player->GetSystemAddress(), true, - true); + startRotation, player->GetSystemAddress(), true); } void RacingControlComponent::OnRacingClientReady(Entity* player) { @@ -291,7 +269,7 @@ void RacingControlComponent::OnRacingClientReady(Entity* player) { racingPlayer.vehicleID, UNASSIGNED_SYSTEM_ADDRESS); } - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } void RacingControlComponent::OnRequestDie(Entity* player) { @@ -304,7 +282,7 @@ void RacingControlComponent::OnRequestDie(Entity* player) { } auto* vehicle = - EntityManager::Instance()->GetEntity(racingPlayer.vehicleID); + Game::entityManager->GetEntity(racingPlayer.vehicleID); if (!vehicle) return; @@ -341,7 +319,7 @@ void RacingControlComponent::OnRequestDie(Entity* player) { auto* destroyableComponent = vehicle->GetComponent(); // Reset imagination to half its current value, rounded up to the nearest value divisible by 10, as it was done in live. if (destroyableComponent) destroyableComponent->SetImagination(respawnImagination); - EntityManager::Instance()->SerializeEntity(vehicle); + Game::entityManager->SerializeEntity(vehicle); }); auto* characterComponent = player->GetComponent(); @@ -370,7 +348,7 @@ void RacingControlComponent::OnRacingPlayerInfoResetFinished(Entity* player) { } auto* vehicle = - EntityManager::Instance()->GetEntity(racingPlayer.vehicleID); + Game::entityManager->GetEntity(racingPlayer.vehicleID); if (vehicle == nullptr) { return; @@ -382,8 +360,7 @@ void RacingControlComponent::OnRacingPlayerInfoResetFinished(Entity* player) { } } -void RacingControlComponent::HandleMessageBoxResponse(Entity* player, - const std::string& id) { +void RacingControlComponent::HandleMessageBoxResponse(Entity* player, int32_t button, const std::string& id) { auto* data = GetPlayerData(player->GetObjectID()); if (data == nullptr) { @@ -391,15 +368,17 @@ void RacingControlComponent::HandleMessageBoxResponse(Entity* player, } if (id == "rewardButton") { - if (data->collectedRewards) { - return; - } + if (data->collectedRewards) return; data->collectedRewards = true; // Calculate the score, different loot depending on player count - const auto score = m_LoadedPlayers * 10 + data->finished; + auto playersRating = m_LoadedPlayers; + if(m_LoadedPlayers == 1 && m_SoloRacing) { + playersRating *= 2; + } + const auto score = playersRating * 10 + data->finished; LootGenerator::Instance().GiveActivityLoot(player, m_Parent, m_ActivityID, score); // Giving rewards @@ -418,15 +397,15 @@ void RacingControlComponent::HandleMessageBoxResponse(Entity* player, if (m_SoloRacing || m_LoadedPlayers > 2) { missionComponent->Progress(eMissionTaskType::RACING, data->finished, (LWOOBJID)eRacingTaskParam::FINISH_WITH_PLACEMENT); // Finish in 1st place on a race if (data->finished == 1) { - missionComponent->Progress(eMissionTaskType::RACING, dZoneManager::Instance()->GetZone()->GetWorldID(), (LWOOBJID)eRacingTaskParam::FIRST_PLACE_MULTIPLE_TRACKS); // Finish in 1st place on multiple tracks. - missionComponent->Progress(eMissionTaskType::RACING, dZoneManager::Instance()->GetZone()->GetWorldID(), (LWOOBJID)eRacingTaskParam::WIN_RACE_IN_WORLD); // Finished first place in specific world. + missionComponent->Progress(eMissionTaskType::RACING, Game::zoneManager->GetZone()->GetWorldID(), (LWOOBJID)eRacingTaskParam::FIRST_PLACE_MULTIPLE_TRACKS); // Finish in 1st place on multiple tracks. + missionComponent->Progress(eMissionTaskType::RACING, Game::zoneManager->GetZone()->GetWorldID(), (LWOOBJID)eRacingTaskParam::WIN_RACE_IN_WORLD); // Finished first place in specific world. } if (data->finished == m_LoadedPlayers) { - missionComponent->Progress(eMissionTaskType::RACING, dZoneManager::Instance()->GetZone()->GetWorldID(), (LWOOBJID)eRacingTaskParam::LAST_PLACE_FINISH); // Finished first place in specific world. + missionComponent->Progress(eMissionTaskType::RACING, Game::zoneManager->GetZone()->GetWorldID(), (LWOOBJID)eRacingTaskParam::LAST_PLACE_FINISH); // Finished first place in specific world. } } - } else if (id == "ACT_RACE_EXIT_THE_RACE?" || id == "Exit") { - auto* vehicle = EntityManager::Instance()->GetEntity(data->vehicleID); + } else if ((id == "ACT_RACE_EXIT_THE_RACE?" || id == "Exit") && button == m_ActivityExitConfirm) { + auto* vehicle = Game::entityManager->GetEntity(data->vehicleID); if (vehicle == nullptr) { return; @@ -527,7 +506,7 @@ void RacingControlComponent::Update(float deltaTime) { // Check if any players has disconnected before loading in for (size_t i = 0; i < m_LobbyPlayers.size(); i++) { auto* playerEntity = - EntityManager::Instance()->GetEntity(m_LobbyPlayers[i]); + Game::entityManager->GetEntity(m_LobbyPlayers[i]); if (playerEntity == nullptr) { --m_LoadedPlayers; @@ -549,7 +528,7 @@ void RacingControlComponent::Update(float deltaTime) { if (m_EmptyTimer >= 30) { for (const auto player : m_LobbyPlayers) { auto* playerEntity = - EntityManager::Instance()->GetEntity(player); + Game::entityManager->GetEntity(player); if (playerEntity == nullptr) { continue; @@ -574,7 +553,7 @@ void RacingControlComponent::Update(float deltaTime) { "Loading player now!"); auto* player = - EntityManager::Instance()->GetEntity(m_LobbyPlayers[positionNumber]); + Game::entityManager->GetEntity(m_LobbyPlayers[positionNumber]); if (player == nullptr) { return; @@ -598,7 +577,7 @@ void RacingControlComponent::Update(float deltaTime) { if (!m_Started) { // Check if anyone has disconnected during this period for (size_t i = 0; i < m_RacingPlayers.size(); i++) { - auto* playerEntity = EntityManager::Instance()->GetEntity( + auto* playerEntity = Game::entityManager->GetEntity( m_RacingPlayers[i].playerID); if (playerEntity == nullptr) { @@ -614,7 +593,7 @@ void RacingControlComponent::Update(float deltaTime) { if (m_LoadedPlayers < 2 && !(m_LoadedPlayers == 1 && m_SoloRacing)) { for (const auto player : m_LobbyPlayers) { auto* playerEntity = - EntityManager::Instance()->GetEntity(player); + Game::entityManager->GetEntity(player); if (playerEntity == nullptr) { continue; @@ -647,15 +626,15 @@ void RacingControlComponent::Update(float deltaTime) { for (const auto& player : m_RacingPlayers) { auto* vehicle = - EntityManager::Instance()->GetEntity(player.vehicleID); + Game::entityManager->GetEntity(player.vehicleID); auto* playerEntity = - EntityManager::Instance()->GetEntity(player.playerID); + Game::entityManager->GetEntity(player.playerID); if (vehicle != nullptr && playerEntity != nullptr) { GameMessages::SendTeleport( player.playerID, player.respawnPosition, player.respawnRotation, - playerEntity->GetSystemAddress(), true, true); + playerEntity->GetSystemAddress(), true); vehicle->SetPosition(player.respawnPosition); vehicle->SetRotation(player.respawnRotation); @@ -667,18 +646,18 @@ void RacingControlComponent::Update(float deltaTime) { destroyableComponent->SetImagination(0); } - EntityManager::Instance()->SerializeEntity(vehicle); - EntityManager::Instance()->SerializeEntity( + Game::entityManager->SerializeEntity(vehicle); + Game::entityManager->SerializeEntity( playerEntity); } } // Spawn imagination pickups - auto* minSpawner = dZoneManager::Instance()->GetSpawnersByName( + auto* minSpawner = Game::zoneManager->GetSpawnersByName( "ImaginationSpawn_Min")[0]; - auto* medSpawner = dZoneManager::Instance()->GetSpawnersByName( + auto* medSpawner = Game::zoneManager->GetSpawnersByName( "ImaginationSpawn_Med")[0]; - auto* maxSpawner = dZoneManager::Instance()->GetSpawnersByName( + auto* maxSpawner = Game::zoneManager->GetSpawnersByName( "ImaginationSpawn_Max")[0]; minSpawner->Activate(); @@ -694,9 +673,9 @@ void RacingControlComponent::Update(float deltaTime) { // Reset players to their start location, without smashing them for (auto& player : m_RacingPlayers) { auto* vehicleEntity = - EntityManager::Instance()->GetEntity(player.vehicleID); + Game::entityManager->GetEntity(player.vehicleID); auto* playerEntity = - EntityManager::Instance()->GetEntity(player.playerID); + Game::entityManager->GetEntity(player.playerID); if (vehicleEntity == nullptr || playerEntity == nullptr) { continue; @@ -713,9 +692,9 @@ void RacingControlComponent::Update(float deltaTime) { // Activate the players movement for (auto& player : m_RacingPlayers) { auto* vehicleEntity = - EntityManager::Instance()->GetEntity(player.vehicleID); + Game::entityManager->GetEntity(player.vehicleID); auto* playerEntity = - EntityManager::Instance()->GetEntity(player.playerID); + Game::entityManager->GetEntity(player.playerID); if (vehicleEntity == nullptr || playerEntity == nullptr) { continue; @@ -733,7 +712,7 @@ void RacingControlComponent::Update(float deltaTime) { Game::logger->Log("RacingControlComponent", "Starting race"); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); m_StartTime = std::time(nullptr); } @@ -747,13 +726,13 @@ void RacingControlComponent::Update(float deltaTime) { } // Race routines - auto* path = dZoneManager::Instance()->GetZone()->GetPath( + auto* path = Game::zoneManager->GetZone()->GetPath( GeneralUtils::UTF16ToWTF8(m_PathName)); for (auto& player : m_RacingPlayers) { - auto* vehicle = EntityManager::Instance()->GetEntity(player.vehicleID); + auto* vehicle = Game::entityManager->GetEntity(player.vehicleID); auto* playerEntity = - EntityManager::Instance()->GetEntity(player.playerID); + Game::entityManager->GetEntity(player.playerID); if (vehicle == nullptr || playerEntity == nullptr) { continue; @@ -859,6 +838,7 @@ void RacingControlComponent::Update(float deltaTime) { "Completed time %llu, %llu", raceTime, raceTime * 1000); + LeaderboardManager::SaveScore(playerEntity->GetObjectID(), m_ActivityID, static_cast(player.raceTime), static_cast(player.bestLapTime), static_cast(player.finished == 1)); // Entire race time missionComponent->Progress(eMissionTaskType::RACING, (raceTime) * 1000, (LWOOBJID)eRacingTaskParam::TOTAL_TRACK_TIME); diff --git a/dGame/dComponents/RacingControlComponent.h b/dGame/dComponents/RacingControlComponent.h index 91ab2fd4..a81121e1 100644 --- a/dGame/dComponents/RacingControlComponent.h +++ b/dGame/dComponents/RacingControlComponent.h @@ -144,7 +144,7 @@ public: /** * Invoked when the player responds to the GUI. */ - void HandleMessageBoxResponse(Entity* player, const std::string& id); + void HandleMessageBoxResponse(Entity* player, int32_t button, const std::string& id); /** * Get the racing data from a player's LWOOBJID. @@ -246,4 +246,9 @@ private: float m_EmptyTimer; bool m_SoloRacing; + + /** + * Value for message box response to know if we are exiting the race via the activity dialogue + */ + const int32_t m_ActivityExitConfirm = 1; }; diff --git a/dGame/dComponents/RailActivatorComponent.cpp b/dGame/dComponents/RailActivatorComponent.cpp index e4091046..c7d58999 100644 --- a/dGame/dComponents/RailActivatorComponent.cpp +++ b/dGame/dComponents/RailActivatorComponent.cpp @@ -7,6 +7,8 @@ #include "RebuildComponent.h" #include "Game.h" #include "dLogger.h" +#include "RenderComponent.h" +#include "EntityManager.h" #include "eStateChangeType.h" RailActivatorComponent::RailActivatorComponent(Entity* parent, int32_t componentID) : Component(parent) { @@ -57,29 +59,16 @@ void RailActivatorComponent::OnUse(Entity* originator) { GameMessages::SendPlayFXEffect(originator->GetObjectID(), m_StartEffect.first, m_StartEffect.second, std::to_string(m_StartEffect.first)); } - + + float animationLength = 0.5f; if (!m_StartAnimation.empty()) { - GameMessages::SendPlayAnimation(originator, m_StartAnimation); - } - - float animationLength; - - if (m_StartAnimation == u"whirlwind-rail-up-earth") { - animationLength = 1.5f; - } else if (m_StartAnimation == u"whirlwind-rail-up-lightning") { - animationLength = 0.5f; - } else if (m_StartAnimation == u"whirlwind-rail-up-ice") { - animationLength = 0.5f; - } else if (m_StartAnimation == u"whirlwind-rail-up-fire") { - animationLength = 0.5f; - } else { - animationLength = 0.5f; + animationLength = RenderComponent::PlayAnimation(originator, m_StartAnimation); } const auto originatorID = originator->GetObjectID(); m_Parent->AddCallbackTimer(animationLength, [originatorID, this]() { - auto* originator = EntityManager::Instance()->GetEntity(originatorID); + auto* originator = Game::entityManager->GetEntity(originatorID); if (originator == nullptr) { return; @@ -112,7 +101,7 @@ void RailActivatorComponent::OnRailMovementReady(Entity* originator) const { } if (!m_LoopAnimation.empty()) { - GameMessages::SendPlayAnimation(originator, m_LoopAnimation); + RenderComponent::PlayAnimation(originator, m_LoopAnimation); } GameMessages::SendSetRailMovement(originator->GetObjectID(), m_PathDirection, m_Path, m_PathStart, @@ -147,7 +136,7 @@ void RailActivatorComponent::OnCancelRailMovement(Entity* originator) { } if (!m_StopAnimation.empty()) { - GameMessages::SendPlayAnimation(originator, m_StopAnimation); + RenderComponent::PlayAnimation(originator, m_StopAnimation); } // Remove the player after they've signalled they're done railing diff --git a/dGame/dComponents/RebuildComponent.cpp b/dGame/dComponents/RebuildComponent.cpp index fcf2738c..13854bd6 100644 --- a/dGame/dComponents/RebuildComponent.cpp +++ b/dGame/dComponents/RebuildComponent.cpp @@ -20,6 +20,7 @@ #include "Preconditions.h" #include "Loot.h" #include "TeamManager.h" +#include "RenderComponent.h" #include "CppScripts.h" @@ -119,7 +120,7 @@ void RebuildComponent::Update(float deltaTime) { else { m_SoftTimer = 5.0f; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); }*/ switch (m_State) { @@ -138,7 +139,7 @@ void RebuildComponent::Update(float deltaTime) { if (m_TimerIncomplete >= m_TimeBeforeSmash - 4.0f) { m_ShowResetEffect = true; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } if (m_TimerIncomplete >= m_TimeBeforeSmash) { @@ -162,7 +163,7 @@ void RebuildComponent::Update(float deltaTime) { if (!m_ShowResetEffect) { m_ShowResetEffect = true; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } } @@ -196,18 +197,18 @@ void RebuildComponent::Update(float deltaTime) { DestroyableComponent* destComp = builder->GetComponent(); if (!destComp) break; - int newImagination = destComp->GetImagination() - 1; - - destComp->SetImagination(newImagination); - EntityManager::Instance()->SerializeEntity(builder); - - ++m_DrainedImagination; - - if (newImagination == 0 && m_DrainedImagination < m_TakeImagination) { + int newImagination = destComp->GetImagination(); + if (newImagination <= 0) { CancelRebuild(builder, eQuickBuildFailReason::OUT_OF_IMAGINATION, true); - break; } + + ++m_DrainedImagination; + --newImagination; + destComp->SetImagination(newImagination); + Game::entityManager->SerializeEntity(builder); + + } if (m_Timer >= m_CompleteTime && m_DrainedImagination >= m_TakeImagination) { @@ -224,7 +225,7 @@ void RebuildComponent::Update(float deltaTime) { if (m_TimerIncomplete >= m_TimeBeforeSmash - 4.0f) { m_ShowResetEffect = true; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } if (m_TimerIncomplete >= m_TimeBeforeSmash) { @@ -262,20 +263,20 @@ void RebuildComponent::SpawnActivator() { info.spawnerID = m_Parent->GetObjectID(); info.pos = m_ActivatorPosition == NiPoint3::ZERO ? m_Parent->GetPosition() : m_ActivatorPosition; - m_Activator = EntityManager::Instance()->CreateEntity(info, nullptr, m_Parent); + m_Activator = Game::entityManager->CreateEntity(info, nullptr, m_Parent); if (m_Activator) { m_ActivatorId = m_Activator->GetObjectID(); - EntityManager::Instance()->ConstructEntity(m_Activator); + Game::entityManager->ConstructEntity(m_Activator); } - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } } } void RebuildComponent::DespawnActivator() { if (m_Activator) { - EntityManager::Instance()->DestructEntity(m_Activator); + Game::entityManager->DestructEntity(m_Activator); m_Activator->ScheduleKillAfterUpdate(); @@ -286,7 +287,7 @@ void RebuildComponent::DespawnActivator() { } Entity* RebuildComponent::GetActivator() { - return EntityManager::Instance()->GetEntity(m_ActivatorId); + return Game::entityManager->GetEntity(m_ActivatorId); } NiPoint3 RebuildComponent::GetActivatorPosition() { @@ -334,7 +335,7 @@ eRebuildState RebuildComponent::GetState() { } Entity* RebuildComponent::GetBuilder() const { - auto* builder = EntityManager::Instance()->GetEntity(m_Builder); + auto* builder = Game::entityManager->GetEntity(m_Builder); return builder; } @@ -402,14 +403,14 @@ void RebuildComponent::StartRebuild(Entity* user) { auto* character = user->GetComponent(); character->SetCurrentActivity(eGameActivity::QUICKBUILDING); - EntityManager::Instance()->SerializeEntity(user); + Game::entityManager->SerializeEntity(user); GameMessages::SendRebuildNotifyState(m_Parent, m_State, eRebuildState::BUILDING, user->GetObjectID()); GameMessages::SendEnableRebuild(m_Parent, true, false, false, eQuickBuildFailReason::NOT_GIVEN, 0.0f, user->GetObjectID()); m_State = eRebuildState::BUILDING; m_StateDirty = true; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); auto* movingPlatform = m_Parent->GetComponent(); if (movingPlatform != nullptr) { @@ -442,7 +443,7 @@ void RebuildComponent::CompleteRebuild(Entity* user) { return; } - EntityManager::Instance()->SerializeEntity(user); + Game::entityManager->SerializeEntity(user); GameMessages::SendRebuildNotifyState(m_Parent, m_State, eRebuildState::COMPLETED, user->GetObjectID()); GameMessages::SendPlayFXEffect(m_Parent, 507, u"create", "BrickFadeUpVisCompleteEffect", LWOOBJID_EMPTY, 0.4f, 1.0f, true); @@ -455,7 +456,7 @@ void RebuildComponent::CompleteRebuild(Entity* user) { m_Timer = 0.0f; m_DrainedImagination = 0; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); // Removes extra item requirements, isn't live accurate. // In live, all items were removed at the start of the quickbuild, then returned if it was cancelled. @@ -475,7 +476,7 @@ void RebuildComponent::CompleteRebuild(Entity* user) { auto* team = TeamManager::Instance()->GetTeam(builder->GetObjectID()); if (team) { for (const auto memberId : team->members) { // progress missions for all team members - auto* member = EntityManager::Instance()->GetEntity(memberId); + auto* member = Game::entityManager->GetEntity(memberId); if (member) { auto* missionComponent = member->GetComponent(); if (missionComponent) missionComponent->Progress(eMissionTaskType::ACTIVITY, m_ActivityId); @@ -517,7 +518,7 @@ void RebuildComponent::CompleteRebuild(Entity* user) { character->SetPlayerFlag(flagNumber, true); } } - GameMessages::SendPlayAnimation(user, u"rebuild-celebrate", 1.09f); + RenderComponent::PlayAnimation(user, u"rebuild-celebrate", 1.09f); } void RebuildComponent::ResetRebuild(bool failed) { @@ -527,7 +528,7 @@ void RebuildComponent::ResetRebuild(bool failed) { GameMessages::SendEnableRebuild(m_Parent, false, false, failed, eQuickBuildFailReason::NOT_GIVEN, m_ResetTime, builder->GetObjectID()); if (failed) { - GameMessages::SendPlayAnimation(builder, u"rebuild-fail"); + RenderComponent::PlayAnimation(builder, u"rebuild-fail"); } } @@ -540,7 +541,7 @@ void RebuildComponent::ResetRebuild(bool failed) { m_ShowResetEffect = false; m_DrainedImagination = 0; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); // Notify scripts and possible subscribers for (auto* script : CppScripts::GetEntityScripts(m_Parent)) @@ -580,7 +581,7 @@ void RebuildComponent::CancelRebuild(Entity* entity, eQuickBuildFailReason failR for (const auto& cb : m_RebuildStateCallbacks) cb(m_State); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } if (entity == nullptr) { @@ -590,7 +591,7 @@ void RebuildComponent::CancelRebuild(Entity* entity, eQuickBuildFailReason failR CharacterComponent* characterComponent = entity->GetComponent(); if (characterComponent) { characterComponent->SetCurrentActivity(eGameActivity::NONE); - EntityManager::Instance()->SerializeEntity(entity); + Game::entityManager->SerializeEntity(entity); } } diff --git a/dGame/dComponents/RenderComponent.cpp b/dGame/dComponents/RenderComponent.cpp index ee42acba..94f5fb5d 100644 --- a/dGame/dComponents/RenderComponent.cpp +++ b/dGame/dComponents/RenderComponent.cpp @@ -11,72 +11,36 @@ #include "GameMessages.h" #include "Game.h" #include "dLogger.h" +#include "CDAnimationsTable.h" std::unordered_map RenderComponent::m_DurationCache{}; -RenderComponent::RenderComponent(Entity* parent) : Component(parent) { +RenderComponent::RenderComponent(Entity* parent, int32_t componentId): Component(parent) { m_Effects = std::vector(); + m_LastAnimationName = ""; + if (componentId == -1) return; - return; + auto query = CDClientDatabase::CreatePreppedStmt("SELECT * FROM RenderComponent WHERE id = ?;"); + query.bind(1, componentId); + auto result = query.execQuery(); - /* - auto* table = CDClientManager::Instance().GetTable(); - - const auto entry = table->GetByIDAndType(parent->GetLOT(), eReplicaComponentType::RENDER); - - std::stringstream query; - - query << "SELECT effect1, effect2, effect3, effect4, effect5, effect6 FROM RenderComponent WHERE id = " << std::to_string(entry) << ";"; - - auto result = CDClientDatabase::ExecuteQuery(query.str()); - - if (result.eof()) - { - return; - } - - for (auto i = 0; i < 6; ++i) - { - if (result.fieldIsNull(i)) - { - continue; - } - - const auto id = result.getIntField(i); - - if (id <= 0) - { - continue; - } - - query.clear(); - - query << "SELECT effectType, effectName FROM BehaviorEffect WHERE effectID = " << std::to_string(id) << ";"; - - auto effectResult = CDClientDatabase::ExecuteQuery(query.str()); - - while (!effectResult.eof()) - { - const auto type = effectResult.fieldIsNull(0) ? "" : std::string(effectResult.getStringField(0)); - - const auto name = effectResult.fieldIsNull(1) ? "" : std::string(effectResult.getStringField(1)); - - auto* effect = new Effect(); - - effect->name = name; - effect->type = GeneralUtils::ASCIIToUTF16(type); - effect->scale = 1; - effect->effectID = id; - effect->secondary = LWOOBJID_EMPTY; - - m_Effects.push_back(effect); - - effectResult.nextRow(); + if (!result.eof()) { + auto animationGroupIDs = std::string(result.getStringField("animationGroupIDs", "")); + if (!animationGroupIDs.empty()) { + auto* animationsTable = CDClientManager::Instance().GetTable(); + auto groupIdsSplit = GeneralUtils::SplitString(animationGroupIDs, ','); + for (auto& groupId : groupIdsSplit) { + int32_t groupIdInt; + if (!GeneralUtils::TryParse(groupId, groupIdInt)) { + Game::logger->Log("RenderComponent", "bad animation group Id %s", groupId.c_str()); + continue; + } + m_animationGroupIds.push_back(groupIdInt); + animationsTable->CacheAnimationGroup(groupIdInt); + } } } - result.finalize(); - */ } RenderComponent::~RenderComponent() { @@ -224,3 +188,45 @@ void RenderComponent::StopEffect(const std::string& name, const bool killImmedia std::vector& RenderComponent::GetEffects() { return m_Effects; } + + +float RenderComponent::PlayAnimation(Entity* self, const std::u16string& animation, float priority, float scale) { + if (!self) return 0.0f; + return RenderComponent::PlayAnimation(self, GeneralUtils::UTF16ToWTF8(animation), priority, scale); +} + +float RenderComponent::PlayAnimation(Entity* self, const std::string& animation, float priority, float scale) { + if (!self) return 0.0f; + return RenderComponent::DoAnimation(self, animation, true, priority, scale); +} + +float RenderComponent::GetAnimationTime(Entity* self, const std::u16string& animation) { + if (!self) return 0.0f; + return RenderComponent::GetAnimationTime(self, GeneralUtils::UTF16ToWTF8(animation)); +} + +float RenderComponent::GetAnimationTime(Entity* self, const std::string& animation) { + if (!self) return 0.0f; + return RenderComponent::DoAnimation(self, animation, false); +} + + +float RenderComponent::DoAnimation(Entity* self, const std::string& animation, bool sendAnimation, float priority, float scale) { + float returnlength = 0.0f; + if (!self) return returnlength; + auto* renderComponent = self->GetComponent(); + if (!renderComponent) return returnlength; + + auto* animationsTable = CDClientManager::Instance().GetTable(); + for (auto& groupId : renderComponent->m_animationGroupIds) { + auto animationGroup = animationsTable->GetAnimation(animation, renderComponent->GetLastAnimationName(), groupId); + if (animationGroup.FoundData()) { + auto data = animationGroup.Data(); + renderComponent->SetLastAnimationName(data.animation_name); + returnlength = data.animation_length; + } + } + if (sendAnimation) GameMessages::SendPlayAnimation(self, GeneralUtils::ASCIIToUTF16(animation), priority, scale); + if (returnlength == 0.0f) Game::logger->Log("RenderComponent", "WARNING: Unable to find animation %s for lot %i in any group.", animation.c_str(), self->GetLOT()); + return returnlength; +} diff --git a/dGame/dComponents/RenderComponent.h b/dGame/dComponents/RenderComponent.h index de8b2907..cdf32160 100644 --- a/dGame/dComponents/RenderComponent.h +++ b/dGame/dComponents/RenderComponent.h @@ -6,7 +6,7 @@ #include #include -#include "AMFFormat.h" +#include "Amf3.h" #include "Component.h" #include "eReplicaComponentType.h" @@ -58,7 +58,7 @@ class RenderComponent : public Component { public: static const eReplicaComponentType ComponentType = eReplicaComponentType::RENDER; - RenderComponent(Entity* entity); + RenderComponent(Entity* entity, int32_t componentId = -1); ~RenderComponent() override; void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); @@ -104,6 +104,32 @@ public: */ std::vector& GetEffects(); + /** + * Verifies that an animation can be played on this entity by checking + * if it has the animation assigned to its group. If it does, the animation is echo'd + * down to all clients to be played and the duration of the played animation is returned. + * If the animation did not exist or the function was called in an invalid state, 0 is returned. + * + * The logic here matches the exact client logic. + * + * @param self The entity that wants to play an animation + * @param animation The animation_type (animationID in the client) to be played. + * @param sendAnimation Whether or not to echo the animation down to all clients. + * @param priority The priority of the animation. Only used if sendAnimation is true. + * @param scale The scale of the animation. Only used if sendAnimation is true. + * + * @return The duration of the animation that was played. + */ + static float DoAnimation(Entity* self, const std::string& animation, bool sendAnimation, float priority = 0.0f, float scale = 1.0f); + + static float PlayAnimation(Entity* self, const std::u16string& animation, float priority = 0.0f, float scale = 1.0f); + static float PlayAnimation(Entity* self, const std::string& animation, float priority = 0.0f, float scale = 1.0f); + static float GetAnimationTime(Entity* self, const std::string& animation); + static float GetAnimationTime(Entity* self, const std::u16string& animation); + + const std::string& GetLastAnimationName() const { return m_LastAnimationName; }; + void SetLastAnimationName(const std::string& name) { m_LastAnimationName = name; }; + private: /** @@ -111,6 +137,11 @@ private: */ std::vector m_Effects; + std::vector m_animationGroupIds; + + // The last animationName that was played + std::string m_LastAnimationName; + /** * Cache of queries that look for the length of each effect, indexed by effect ID */ diff --git a/dGame/dComponents/RocketLaunchpadControlComponent.cpp b/dGame/dComponents/RocketLaunchpadControlComponent.cpp index 3cac9e42..10908d9e 100644 --- a/dGame/dComponents/RocketLaunchpadControlComponent.cpp +++ b/dGame/dComponents/RocketLaunchpadControlComponent.cpp @@ -81,7 +81,7 @@ void RocketLaunchpadControlComponent::Launch(Entity* originator, LWOMAPID mapId, GameMessages::SendChangeObjectWorldState(rocket->GetId(), eObjectWorldState::ATTACHED, UNASSIGNED_SYSTEM_ADDRESS); - EntityManager::Instance()->SerializeEntity(originator); + Game::entityManager->SerializeEntity(originator); } void RocketLaunchpadControlComponent::OnUse(Entity* originator) { diff --git a/dGame/dComponents/ScriptedActivityComponent.cpp b/dGame/dComponents/ScriptedActivityComponent.cpp index eb4ab761..81b3e9a9 100644 --- a/dGame/dComponents/ScriptedActivityComponent.cpp +++ b/dGame/dComponents/ScriptedActivityComponent.cpp @@ -27,6 +27,7 @@ #include "CDCurrencyTableTable.h" #include "CDActivityRewardsTable.h" #include "CDActivitiesTable.h" +#include "LeaderboardManager.h" ScriptedActivityComponent::ScriptedActivityComponent(Entity* parent, int activityID) : Component(parent) { m_ActivityID = activityID; @@ -35,10 +36,7 @@ ScriptedActivityComponent::ScriptedActivityComponent(Entity* parent, int activit for (CDActivities activity : activities) { m_ActivityInfo = activity; - - const auto mapID = m_ActivityInfo.instanceMapID; - - if ((mapID == 1203 || mapID == 1261 || mapID == 1303 || mapID == 1403) && Game::config->GetValue("solo_racing") == "1") { + if (static_cast(activity.leaderboardType) == Leaderboard::Type::Racing && Game::config->GetValue("solo_racing") == "1") { m_ActivityInfo.minTeamSize = 1; m_ActivityInfo.minTeams = 1; } @@ -139,7 +137,7 @@ void ScriptedActivityComponent::PlayerJoin(Entity* player) { instance->AddParticipant(player); } - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } void ScriptedActivityComponent::PlayerJoinLobby(Entity* player) { @@ -151,7 +149,7 @@ void ScriptedActivityComponent::PlayerJoinLobby(Entity* player) { auto* character = player->GetCharacter(); if (character != nullptr) - character->SetLastNonInstanceZoneID(dZoneManager::Instance()->GetZone()->GetWorldID()); + character->SetLastNonInstanceZoneID(Game::zoneManager->GetZone()->GetWorldID()); for (Lobby* lobby : m_Queue) { if (lobby->players.size() < m_ActivityInfo.maxTeamSize || m_ActivityInfo.maxTeamSize == 1 && lobby->players.size() < m_ActivityInfo.maxTeams) { @@ -312,7 +310,7 @@ bool ScriptedActivityComponent::IsValidActivity(Entity* player) { } ChatPackets::SendSystemMessage(player->GetSystemAddress(), u"Sorry, this activity is not ready."); - static_cast(player)->SendToZone(dZoneManager::Instance()->GetZone()->GetWorldID()); // Gets them out of this stuck state + static_cast(player)->SendToZone(Game::zoneManager->GetZone()->GetWorldID()); // Gets them out of this stuck state return false; }*/ @@ -447,7 +445,7 @@ void ScriptedActivityComponent::RemoveActivityPlayerData(LWOOBJID playerID) { m_ActivityPlayers[i] = nullptr; m_ActivityPlayers.erase(m_ActivityPlayers.begin() + i); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); return; } @@ -460,7 +458,7 @@ ActivityPlayer* ScriptedActivityComponent::AddActivityPlayerData(LWOOBJID player return data; m_ActivityPlayers.push_back(new ActivityPlayer{ playerID, {} }); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); return GetActivityPlayerData(playerID); } @@ -482,7 +480,7 @@ void ScriptedActivityComponent::SetActivityValue(LWOOBJID playerID, uint32_t ind data->values[std::min(index, (uint32_t)9)] = value; } - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } void ScriptedActivityComponent::PlayerRemove(LWOOBJID playerID) { @@ -537,7 +535,7 @@ void ActivityInstance::StartZone() { const auto objid = player->GetObjectID(); ZoneInstanceManager::Instance()->RequestZoneTransfer(Game::server, m_ActivityInfo.instanceMapID, cloneId, false, [objid](bool mythranShift, uint32_t zoneID, uint32_t zoneInstance, uint32_t zoneClone, std::string serverIP, uint16_t serverPort) { - auto* player = EntityManager::Instance()->GetEntity(objid); + auto* player = Game::entityManager->GetEntity(objid); if (player == nullptr) return; @@ -587,7 +585,7 @@ std::vector ActivityInstance::GetParticipants() const { entities.reserve(m_Participants.size()); for (const auto& id : m_Participants) { - auto* entity = EntityManager::Instance()->GetEntity(id); + auto* entity = Game::entityManager->GetEntity(id); if (entity != nullptr) entities.push_back(entity); } @@ -619,5 +617,5 @@ void ActivityInstance::SetScore(uint32_t score) { } Entity* LobbyPlayer::GetEntity() const { - return EntityManager::Instance()->GetEntity(entityID); + return Game::entityManager->GetEntity(entityID); } diff --git a/dGame/dComponents/ShootingGalleryComponent.cpp b/dGame/dComponents/ShootingGalleryComponent.cpp index d5e12b28..ed91ac96 100644 --- a/dGame/dComponents/ShootingGalleryComponent.cpp +++ b/dGame/dComponents/ShootingGalleryComponent.cpp @@ -14,7 +14,7 @@ void ShootingGalleryComponent::SetStaticParams(const StaticShootingGalleryParams void ShootingGalleryComponent::SetDynamicParams(const DynamicShootingGalleryParams& params) { m_DynamicParams = params; m_Dirty = true; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } void ShootingGalleryComponent::Serialize(RakNet::BitStream* outBitStream, bool isInitialUpdate, uint32_t& flags) const { diff --git a/dGame/dComponents/SkillComponent.cpp b/dGame/dComponents/SkillComponent.cpp index c2f07425..5c1d221a 100644 --- a/dGame/dComponents/SkillComponent.cpp +++ b/dGame/dComponents/SkillComponent.cpp @@ -292,7 +292,7 @@ SkillExecutionResult SkillComponent::CalculateBehavior(const uint32_t skillId, c start.optionalOriginatorID = context->originator; start.optionalTargetID = target; - auto* originator = EntityManager::Instance()->GetEntity(context->originator); + auto* originator = Game::entityManager->GetEntity(context->originator); if (originator != nullptr) { start.originatorRot = originator->GetRotation(); @@ -338,7 +338,7 @@ void SkillComponent::CalculateUpdate(const float deltaTime) { entry.time += deltaTime; - auto* origin = EntityManager::Instance()->GetEntity(entry.context->originator); + auto* origin = Game::entityManager->GetEntity(entry.context->originator); if (origin == nullptr) { continue; @@ -349,7 +349,7 @@ void SkillComponent::CalculateUpdate(const float deltaTime) { const auto position = entry.startPosition + (entry.velocity * entry.time); for (const auto& targetId : targets) { - auto* target = EntityManager::Instance()->GetEntity(targetId); + auto* target = Game::entityManager->GetEntity(targetId); const auto targetPosition = target->GetPosition(); @@ -397,7 +397,7 @@ void SkillComponent::CalculateUpdate(const float deltaTime) { void SkillComponent::SyncProjectileCalculation(const ProjectileSyncEntry& entry) const { - auto* other = EntityManager::Instance()->GetEntity(entry.branchContext.target); + auto* other = Game::entityManager->GetEntity(entry.branchContext.target); if (other == nullptr) { if (entry.branchContext.target != LWOOBJID_EMPTY) { diff --git a/dGame/dComponents/SoundTriggerComponent.cpp b/dGame/dComponents/SoundTriggerComponent.cpp index be62beee..21d30948 100644 --- a/dGame/dComponents/SoundTriggerComponent.cpp +++ b/dGame/dComponents/SoundTriggerComponent.cpp @@ -76,7 +76,7 @@ void SoundTriggerComponent::ActivateMusicCue(const std::string& name) { -1.0f }); dirty = true; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } } @@ -88,6 +88,6 @@ void SoundTriggerComponent::DeactivateMusicCue(const std::string& name) { if (musicCue != this->musicCues.end()) { this->musicCues.erase(musicCue); dirty = true; - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } } diff --git a/dGame/dComponents/SwitchComponent.cpp b/dGame/dComponents/SwitchComponent.cpp index c59559c2..eee54342 100644 --- a/dGame/dComponents/SwitchComponent.cpp +++ b/dGame/dComponents/SwitchComponent.cpp @@ -1,6 +1,7 @@ #include "SwitchComponent.h" #include "EntityManager.h" #include "eTriggerEventType.h" +#include "RenderComponent.h" std::vector SwitchComponent::petSwitches; @@ -48,7 +49,7 @@ void SwitchComponent::EntityEnter(Entity* entity) { const auto grpName = m_Parent->GetVarAsString(u"grp_name"); if (!grpName.empty()) { - const auto entities = EntityManager::Instance()->GetEntitiesInGroup(grpName); + const auto entities = Game::entityManager->GetEntitiesInGroup(grpName); for (auto* entity : entities) { entity->OnFireEventServerSide(entity, "OnActivated"); @@ -59,10 +60,10 @@ void SwitchComponent::EntityEnter(Entity* entity) { if (m_PetBouncer != nullptr) { GameMessages::SendPlayFXEffect(m_Parent->GetObjectID(), 2602, u"pettriggeractive", "BounceEffect", LWOOBJID_EMPTY, 1, 1, true); - GameMessages::SendPlayAnimation(m_Parent, u"engaged", 0, 1); + RenderComponent::PlayAnimation(m_Parent, u"engaged"); m_PetBouncer->SetPetBouncerEnabled(true); } else { - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } } @@ -84,7 +85,7 @@ void SwitchComponent::Update(float deltaTime) { const auto grpName = m_Parent->GetVarAsString(u"grp_name"); if (!grpName.empty()) { - const auto entities = EntityManager::Instance()->GetEntitiesInGroup(grpName); + const auto entities = Game::entityManager->GetEntitiesInGroup(grpName); for (auto* entity : entities) { entity->OnFireEventServerSide(entity, "OnDectivated"); @@ -94,7 +95,7 @@ void SwitchComponent::Update(float deltaTime) { if (m_PetBouncer != nullptr) { m_PetBouncer->SetPetBouncerEnabled(false); } else { - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } } } diff --git a/dGame/dComponents/TriggerComponent.cpp b/dGame/dComponents/TriggerComponent.cpp index 3f05d805..ab52c4e5 100644 --- a/dGame/dComponents/TriggerComponent.cpp +++ b/dGame/dComponents/TriggerComponent.cpp @@ -26,7 +26,7 @@ TriggerComponent::TriggerComponent(Entity* parent, const std::string triggerInfo uint32_t triggerID; GeneralUtils::TryParse(tokens.at(1), triggerID); - m_Trigger = dZoneManager::Instance()->GetZone()->GetTrigger(sceneID, triggerID); + m_Trigger = Game::zoneManager->GetZone()->GetTrigger(sceneID, triggerID); if (!m_Trigger) m_Trigger = new LUTriggers::Trigger(); } @@ -170,10 +170,10 @@ std::vector TriggerComponent::GatherTargets(LUTriggers::Command* comman 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); + auto* member = Game::entityManager->GetEntity(memberId); if (member) entities.push_back(member); } - } else if (command->target == "objGroup") entities = EntityManager::Instance()->GetEntitiesInGroup(command->targetName); + } else if (command->target == "objGroup") entities = Game::entityManager->GetEntitiesInGroup(command->targetName); else if (command->target == "allPlayers") { for (auto* player : Player::GetAllPlayers()) { entities.push_back(player); @@ -235,6 +235,8 @@ void TriggerComponent::HandleRotateObject(Entity* targetEntity, std::vector argArray){ + if (argArray.size() < 3) return; + auto* phantomPhysicsComponent = m_Parent->GetComponent(); if (!phantomPhysicsComponent) { Game::logger->LogDebug("TriggerComponent::HandlePushObject", "Phantom Physics component not found!"); @@ -247,7 +249,7 @@ void TriggerComponent::HandlePushObject(Entity* targetEntity, std::vectorSetDirection(direction); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } @@ -272,7 +274,7 @@ void TriggerComponent::HandleRepelObject(Entity* targetEntity, std::string args) NiPoint3 direction = delta / length; phantomPhysicsComponent->SetDirection(direction); - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); } void TriggerComponent::HandleSetTimer(Entity* targetEntity, std::vector argArray){ @@ -393,7 +395,7 @@ void TriggerComponent::HandleSetPhysicsVolumeEffect(Entity* targetEntity, std::v phantomPhysicsComponent->SetMax(max); } - EntityManager::Instance()->SerializeEntity(targetEntity); + Game::entityManager->SerializeEntity(targetEntity); } void TriggerComponent::HandleSetPhysicsVolumeStatus(Entity* targetEntity, std::string args) { @@ -403,29 +405,29 @@ void TriggerComponent::HandleSetPhysicsVolumeStatus(Entity* targetEntity, std::s return; } phantomPhysicsComponent->SetPhysicsEffectActive(args == "On"); - EntityManager::Instance()->SerializeEntity(targetEntity); + Game::entityManager->SerializeEntity(targetEntity); } void TriggerComponent::HandleActivateSpawnerNetwork(std::string args){ - for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(args)) { + for (auto* spawner : Game::zoneManager->GetSpawnersByName(args)) { if (spawner) spawner->Activate(); } } void TriggerComponent::HandleDeactivateSpawnerNetwork(std::string args){ - for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(args)) { + for (auto* spawner : Game::zoneManager->GetSpawnersByName(args)) { if (spawner) spawner->Deactivate(); } } void TriggerComponent::HandleResetSpawnerNetwork(std::string args){ - for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(args)) { + for (auto* spawner : Game::zoneManager->GetSpawnersByName(args)) { if (spawner) spawner->Reset(); } } void TriggerComponent::HandleDestroySpawnerNetworkObjects(std::string args){ - for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(args)) { + for (auto* spawner : Game::zoneManager->GetSpawnersByName(args)) { if (spawner) spawner->DestroyAllEntities(); } } diff --git a/dGame/dComponents/VehiclePhysicsComponent.cpp b/dGame/dComponents/VehiclePhysicsComponent.cpp index d981acf7..684b135b 100644 --- a/dGame/dComponents/VehiclePhysicsComponent.cpp +++ b/dGame/dComponents/VehiclePhysicsComponent.cpp @@ -19,34 +19,47 @@ VehiclePhysicsComponent::~VehiclePhysicsComponent() { } void VehiclePhysicsComponent::SetPosition(const NiPoint3& pos) { + if (pos == m_Position) return; + m_DirtyPosition = true; m_Position = pos; } void VehiclePhysicsComponent::SetRotation(const NiQuaternion& rot) { + if (rot == m_Rotation) return; m_DirtyPosition = true; m_Rotation = rot; } void VehiclePhysicsComponent::SetVelocity(const NiPoint3& vel) { + if (vel == m_Velocity) return; m_DirtyPosition = true; m_Velocity = vel; } void VehiclePhysicsComponent::SetAngularVelocity(const NiPoint3& vel) { + if (vel == m_AngularVelocity) return; m_DirtyPosition = true; m_AngularVelocity = vel; } void VehiclePhysicsComponent::SetIsOnGround(bool val) { + if (val == m_IsOnGround) return; m_DirtyPosition = true; m_IsOnGround = val; } void VehiclePhysicsComponent::SetIsOnRail(bool val) { + if (val == m_IsOnRail) return; m_DirtyPosition = true; m_IsOnRail = val; } +void VehiclePhysicsComponent::SetRemoteInputInfo(const RemoteInputInfo& remoteInputInfo) { + if (m_RemoteInputInfo == remoteInputInfo) return; + this->m_RemoteInputInfo = remoteInputInfo; + m_DirtyRemoteInput = true; +} + void VehiclePhysicsComponent::SetDirtyPosition(bool val) { m_DirtyPosition = val; } @@ -63,9 +76,15 @@ void VehiclePhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bI outBitStream->Write(bIsInitialUpdate || m_DirtyPosition); if (bIsInitialUpdate || m_DirtyPosition) { - outBitStream->Write(m_Position); + m_DirtyPosition = false; + outBitStream->Write(m_Position.x); + outBitStream->Write(m_Position.y); + outBitStream->Write(m_Position.z); - outBitStream->Write(m_Rotation); + outBitStream->Write(m_Rotation.x); + outBitStream->Write(m_Rotation.y); + outBitStream->Write(m_Rotation.z); + outBitStream->Write(m_Rotation.w); outBitStream->Write(m_IsOnGround); outBitStream->Write(m_IsOnRail); @@ -73,20 +92,33 @@ void VehiclePhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bI outBitStream->Write(bIsInitialUpdate || m_DirtyVelocity); if (bIsInitialUpdate || m_DirtyVelocity) { - outBitStream->Write(m_Velocity); + outBitStream->Write(m_Velocity.x); + outBitStream->Write(m_Velocity.y); + outBitStream->Write(m_Velocity.z); + m_DirtyVelocity = false; } outBitStream->Write(bIsInitialUpdate || m_DirtyAngularVelocity); if (bIsInitialUpdate || m_DirtyAngularVelocity) { - outBitStream->Write(m_AngularVelocity); + outBitStream->Write(m_AngularVelocity.x); + outBitStream->Write(m_AngularVelocity.y); + outBitStream->Write(m_AngularVelocity.z); + m_DirtyAngularVelocity = false; } - outBitStream->Write0(); + outBitStream->Write0(); // local_space_info. TODO: Implement this - outBitStream->Write0(); + outBitStream->Write(m_DirtyRemoteInput || bIsInitialUpdate); // remote_input_info + if (m_DirtyRemoteInput || bIsInitialUpdate) { + outBitStream->Write(m_RemoteInputInfo.m_RemoteInputX); + outBitStream->Write(m_RemoteInputInfo.m_RemoteInputY); + outBitStream->Write(m_RemoteInputInfo.m_IsPowersliding); + outBitStream->Write(m_RemoteInputInfo.m_IsModified); + m_DirtyRemoteInput = false; + } - outBitStream->Write(0.0f); + outBitStream->Write(125.0f); // remote_input_ping TODO: Figure out how this should be calculated as it seems to be constant through the whole race. if (!bIsInitialUpdate) { outBitStream->Write0(); @@ -95,7 +127,7 @@ void VehiclePhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bI if (bIsInitialUpdate) { outBitStream->Write(m_EndBehavior); - outBitStream->Write1(); + outBitStream->Write1(); // is input locked? } outBitStream->Write0(); @@ -103,8 +135,7 @@ void VehiclePhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bI void VehiclePhysicsComponent::Update(float deltaTime) { if (m_SoftUpdate > 5) { - EntityManager::Instance()->SerializeEntity(m_Parent); - + Game::entityManager->SerializeEntity(m_Parent); m_SoftUpdate = 0; } else { m_SoftUpdate += deltaTime; diff --git a/dGame/dComponents/VehiclePhysicsComponent.h b/dGame/dComponents/VehiclePhysicsComponent.h index 64609edf..e314bef1 100644 --- a/dGame/dComponents/VehiclePhysicsComponent.h +++ b/dGame/dComponents/VehiclePhysicsComponent.h @@ -5,6 +5,24 @@ #include "Component.h" #include "eReplicaComponentType.h" +struct RemoteInputInfo { + void operator=(const RemoteInputInfo& other) { + m_RemoteInputX = other.m_RemoteInputX; + m_RemoteInputY = other.m_RemoteInputY; + m_IsPowersliding = other.m_IsPowersliding; + m_IsModified = other.m_IsModified; + } + + bool operator==(const RemoteInputInfo& other) { + return m_RemoteInputX == other.m_RemoteInputX && m_RemoteInputY == other.m_RemoteInputY && m_IsPowersliding == other.m_IsPowersliding && m_IsModified == other.m_IsModified; + } + + float m_RemoteInputX; + float m_RemoteInputY; + bool m_IsPowersliding; + bool m_IsModified; +}; + /** * Physics component for vehicles. */ @@ -94,6 +112,7 @@ public: void SetDirtyPosition(bool val); void SetDirtyVelocity(bool val); void SetDirtyAngularVelocity(bool val); + void SetRemoteInputInfo(const RemoteInputInfo&); private: bool m_DirtyPosition; @@ -110,4 +129,6 @@ private: float m_SoftUpdate = 0; uint32_t m_EndBehavior; + RemoteInputInfo m_RemoteInputInfo; + bool m_DirtyRemoteInput; }; diff --git a/dGame/dComponents/VendorComponent.cpp b/dGame/dComponents/VendorComponent.cpp index c9178785..e89cc926 100644 --- a/dGame/dComponents/VendorComponent.cpp +++ b/dGame/dComponents/VendorComponent.cpp @@ -134,3 +134,7 @@ void VendorComponent::SetupConstants() { m_RefreshTimeSeconds = vendorComps[0].refreshTimeSeconds; m_LootMatrixID = vendorComps[0].LootMatrixIndex; } + +bool VendorComponent::SellsItem(const LOT item) const { + return m_Inventory.find(item) != m_Inventory.end(); +} diff --git a/dGame/dComponents/VendorComponent.h b/dGame/dComponents/VendorComponent.h index bf372bf2..cbff0cfd 100644 --- a/dGame/dComponents/VendorComponent.h +++ b/dGame/dComponents/VendorComponent.h @@ -67,6 +67,8 @@ public: * Called on startup of vendor to setup the variables for the component. */ void SetupConstants(); + + bool SellsItem(const LOT item) const; private: /** * The buy scalar. diff --git a/dGame/dGameMessages/GameMessageHandler.cpp b/dGame/dGameMessages/GameMessageHandler.cpp index 50c7876b..83005b6f 100644 --- a/dGame/dGameMessages/GameMessageHandler.cpp +++ b/dGame/dGameMessages/GameMessageHandler.cpp @@ -42,7 +42,7 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System CBITSTREAM; // Get the entity - Entity* entity = EntityManager::Instance()->GetEntity(objectID); + Entity* entity = Game::entityManager->GetEntity(objectID); User* usr = UserManager::Instance()->GetUser(sysAddr); @@ -122,9 +122,9 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System auto* destroyable = entity->GetComponent(); destroyable->SetImagination(destroyable->GetImagination()); - EntityManager::Instance()->SerializeEntity(entity); + Game::entityManager->SerializeEntity(entity); - std::vector racingControllers = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::RACING_CONTROL); + std::vector racingControllers = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::RACING_CONTROL); for (Entity* racingController : racingControllers) { auto* racingComponent = racingController->GetComponent(); if (racingComponent != nullptr) { @@ -132,12 +132,12 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System } } - Entity* zoneControl = EntityManager::Instance()->GetZoneControlEntity(); + Entity* zoneControl = Game::entityManager->GetZoneControlEntity(); for (CppScripts::Script* script : CppScripts::GetEntityScripts(zoneControl)) { script->OnPlayerLoaded(zoneControl, player); } - std::vector scriptedActs = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::SCRIPT); + std::vector scriptedActs = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SCRIPT); for (Entity* scriptEntity : scriptedActs) { if (scriptEntity->GetObjectID() != zoneControl->GetObjectID()) { // Don't want to trigger twice on instance worlds for (CppScripts::Script* script : CppScripts::GetEntityScripts(scriptEntity)) { @@ -170,7 +170,7 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System // After we've done our thing, tell the client they're ready GameMessages::SendPlayerReady(entity, sysAddr); - GameMessages::SendPlayerReady(dZoneManager::Instance()->GetZoneControlObject(), sysAddr); + GameMessages::SendPlayerReady(Game::zoneManager->GetZoneControlObject(), sysAddr); break; } @@ -248,7 +248,7 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System dest->SetHealth(4); dest->SetArmor(0); dest->SetImagination(6); - EntityManager::Instance()->SerializeEntity(entity); + Game::entityManager->SerializeEntity(entity); }*/ break; } @@ -560,7 +560,7 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System break; case eGameMessageType::ZONE_PROPERTY_MODEL_ROTATED: - EntityManager::Instance()->GetZoneControlEntity()->OnZonePropertyModelRotated(usr->GetLastUsedChar()->GetEntity()); + Game::entityManager->GetZoneControlEntity()->OnZonePropertyModelRotated(usr->GetLastUsedChar()->GetEntity()); break; case eGameMessageType::UPDATE_PROPERTY_OR_MODEL_FOR_FILTER_CHECK: @@ -677,6 +677,9 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System case eGameMessageType::ZONE_SUMMARY_DISMISSED: GameMessages::HandleZoneSummaryDismissed(inStream, entity); break; + case eGameMessageType::REQUEST_ACTIVITY_EXIT: + GameMessages::HandleRequestActivityExit(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 caab6459..8d8085a9 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -28,7 +28,7 @@ #include "eUnequippableActiveType.h" #include "eMovementPlatformState.h" #include "LeaderboardManager.h" -#include "AMFFormat.h" +#include "Amf3.h" #include "Loot.h" #include "eRacingTaskParam.h" #include "eMissionTaskType.h" @@ -70,6 +70,7 @@ #include "PetComponent.h" #include "ModuleAssemblyComponent.h" #include "VehiclePhysicsComponent.h" +#include "RenderComponent.h" #include "PossessableComponent.h" #include "PossessorComponent.h" #include "RacingControlComponent.h" @@ -87,10 +88,11 @@ #include "AMFDeserialize.h" #include "eBlueprintSaveResponseType.h" #include "eAninmationFlags.h" -#include "AMFFormat_BitStream.h" +#include "AmfSerialize.h" #include "eReplicaComponentType.h" #include "eClientMessageType.h" #include "eGameMessageType.h" +#include "ActivityManager.h" #include "CDComponentsRegistryTable.h" #include "CDObjectsTable.h" @@ -118,7 +120,7 @@ void GameMessages::SendFireEventClientSide(const LWOOBJID& objectID, const Syste SEND_PACKET; } -void GameMessages::SendTeleport(const LWOOBJID& objectID, const NiPoint3& pos, const NiQuaternion& rot, const SystemAddress& sysAddr, bool bSetRotation, bool noGravTeleport) { +void GameMessages::SendTeleport(const LWOOBJID& objectID, const NiPoint3& pos, const NiQuaternion& rot, const SystemAddress& sysAddr, bool bSetRotation) { CBITSTREAM; CMSGHEADER; bitStream.Write(objectID); @@ -139,7 +141,6 @@ void GameMessages::SendTeleport(const LWOOBJID& objectID, const NiPoint3& pos, c bitStream.Write(pos.y); bitStream.Write(pos.z); bitStream.Write(bUseNavmesh); - bitStream.Write(noGravTeleport); bitStream.Write(rot.w != 1.0f); if (rot.w != 1.0f) bitStream.Write(rot.w); @@ -595,14 +596,14 @@ void GameMessages::SendModifyLEGOScore(Entity* entity, const SystemAddress& sysA SEND_PACKET; } -void GameMessages::SendUIMessageServerToSingleClient(Entity* entity, const SystemAddress& sysAddr, const std::string& message, AMFValue* args) { +void GameMessages::SendUIMessageServerToSingleClient(Entity* entity, const SystemAddress& sysAddr, const std::string& message, AMFBaseValue& args) { CBITSTREAM; CMSGHEADER; bitStream.Write(entity->GetObjectID()); bitStream.Write((uint16_t)eGameMessageType::UI_MESSAGE_SERVER_TO_SINGLE_CLIENT); - bitStream.Write(args); + bitStream.Write(args); uint32_t strMessageNameLength = message.size(); bitStream.Write(strMessageNameLength); @@ -613,7 +614,7 @@ void GameMessages::SendUIMessageServerToSingleClient(Entity* entity, const Syste SEND_PACKET; } -void GameMessages::SendUIMessageServerToAllClients(const std::string& message, AMFValue* args) { +void GameMessages::SendUIMessageServerToAllClients(const std::string& message, AMFBaseValue& args) { CBITSTREAM; CMSGHEADER; @@ -621,7 +622,7 @@ void GameMessages::SendUIMessageServerToAllClients(const std::string& message, A bitStream.Write(empty); bitStream.Write((uint16_t)eGameMessageType::UI_MESSAGE_SERVER_TO_ALL_CLIENTS); - bitStream.Write(args); + bitStream.Write(args); uint32_t strMessageNameLength = message.size(); bitStream.Write(strMessageNameLength); @@ -1100,7 +1101,7 @@ void GameMessages::SendDropClientLoot(Entity* entity, const LWOOBJID& sourceID, if (object.type != "Powerup") { for (const auto memberId : team->members) { - auto* member = EntityManager::Instance()->GetEntity(memberId); + auto* member = Game::entityManager->GetEntity(memberId); if (member == nullptr) continue; @@ -1644,20 +1645,7 @@ void GameMessages::SendActivitySummaryLeaderboardData(const LWOOBJID& objectID, bitStream.Write(objectID); bitStream.Write(eGameMessageType::SEND_ACTIVITY_SUMMARY_LEADERBOARD_DATA); - bitStream.Write(leaderboard->GetGameID()); - bitStream.Write(leaderboard->GetInfoType()); - - // Leaderboard is written back as LDF string - const auto leaderboardString = leaderboard->ToString(); - bitStream.Write(leaderboardString.size()); - for (const auto c : leaderboardString) { - bitStream.Write(c); - } - if (!leaderboardString.empty()) bitStream.Write(uint16_t(0)); - - bitStream.Write0(); - bitStream.Write0(); - + leaderboard->Serialize(&bitStream); SEND_PACKET; } @@ -1665,8 +1653,8 @@ void GameMessages::HandleRequestActivitySummaryLeaderboardData(RakNet::BitStream int32_t gameID = 0; if (inStream->ReadBit()) inStream->Read(gameID); - int32_t queryType = 1; - if (inStream->ReadBit()) inStream->Read(queryType); + Leaderboard::InfoType queryType = Leaderboard::InfoType::MyStanding; + if (inStream->ReadBit()) inStream->Read(queryType); int32_t resultsEnd = 10; if (inStream->ReadBit()) inStream->Read(resultsEnd); @@ -1679,9 +1667,7 @@ void GameMessages::HandleRequestActivitySummaryLeaderboardData(RakNet::BitStream bool weekly = inStream->ReadBit(); - const auto* leaderboard = LeaderboardManager::GetLeaderboard(gameID, (InfoType)queryType, weekly, entity->GetObjectID()); - SendActivitySummaryLeaderboardData(entity->GetObjectID(), leaderboard, sysAddr); - delete leaderboard; + LeaderboardManager::SendLeaderboard(gameID, queryType, weekly, entity->GetObjectID(), entity->GetObjectID(), resultsStart, resultsEnd); } void GameMessages::HandleActivityStateChangeRequest(RakNet::BitStream* inStream, Entity* entity) { @@ -1704,11 +1690,11 @@ void GameMessages::HandleActivityStateChangeRequest(RakNet::BitStream* inStream, stringValue.push_back(character); } - auto* assosiate = EntityManager::Instance()->GetEntity(objectID); + auto* assosiate = Game::entityManager->GetEntity(objectID); Game::logger->Log("Activity State Change", "%s [%i, %i] from %i to %i", GeneralUtils::UTF16ToWTF8(stringValue).c_str(), value1, value2, entity->GetLOT(), assosiate != nullptr ? assosiate->GetLOT() : 0); - std::vector scriptedActs = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::SHOOTING_GALLERY); + std::vector scriptedActs = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SHOOTING_GALLERY); for (Entity* scriptEntity : scriptedActs) { scriptEntity->OnActivityStateChangeRequest(objectID, value1, value2, stringValue); } @@ -2237,7 +2223,7 @@ void GameMessages::HandleQueryPropertyData(RakNet::BitStream* inStream, Entity* Game::logger->Log("HandleQueryPropertyData", "Entity (%i) requesting data", entity->GetLOT()); /* - auto entites = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::PROPERTY_VENDOR); + auto entites = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::PROPERTY_VENDOR); entity = entites[0]; */ @@ -2249,7 +2235,7 @@ void GameMessages::HandleQueryPropertyData(RakNet::BitStream* inStream, Entity* } /* - entites = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::PROPERTY_MANAGEMENT); + entites = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::PROPERTY_MANAGEMENT); entity = entites[0]; */ @@ -2284,7 +2270,7 @@ void GameMessages::HandleSetBuildMode(RakNet::BitStream* inStream, Entity* entit if (inStream->ReadBit()) inStream->Read(startPosition); - auto* player = EntityManager::Instance()->GetEntity(playerId); + auto* player = Game::entityManager->GetEntity(playerId); if (startPosition == NiPoint3::ZERO) { startPosition = player->GetPosition(); @@ -2332,7 +2318,7 @@ void GameMessages::HandleStartBuildingWithItem(RakNet::BitStream* inStream, Enti auto* user = UserManager::Instance()->GetUser(sysAddr); - auto* player = EntityManager::Instance()->GetEntity(user->GetLoggedInChar()); + auto* player = Game::entityManager->GetEntity(user->GetLoggedInChar()); SendStartArrangingWithItem( player, @@ -2354,25 +2340,25 @@ void GameMessages::HandleStartBuildingWithItem(RakNet::BitStream* inStream, Enti void GameMessages::HandlePropertyEditorBegin(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { PropertyManagementComponent::Instance()->OnStartBuilding(); - dZoneManager::Instance()->GetZoneControlObject()->OnZonePropertyEditBegin(); + Game::zoneManager->GetZoneControlObject()->OnZonePropertyEditBegin(); } void GameMessages::HandlePropertyEditorEnd(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { PropertyManagementComponent::Instance()->OnFinishBuilding(); - dZoneManager::Instance()->GetZoneControlObject()->OnZonePropertyEditEnd(); + Game::zoneManager->GetZoneControlObject()->OnZonePropertyEditEnd(); } void GameMessages::HandlePropertyContentsFromClient(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { User* user = UserManager::Instance()->GetUser(sysAddr); - Entity* player = EntityManager::Instance()->GetEntity(user->GetLoggedInChar()); + Entity* player = Game::entityManager->GetEntity(user->GetLoggedInChar()); SendGetModelsOnProperty(player->GetObjectID(), PropertyManagementComponent::Instance()->GetModels(), UNASSIGNED_SYSTEM_ADDRESS); } void GameMessages::HandlePropertyModelEquipped(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { - dZoneManager::Instance()->GetZoneControlObject()->OnZonePropertyModelEquipped(); + Game::zoneManager->GetZoneControlObject()->OnZonePropertyModelEquipped(); } void GameMessages::HandlePlacePropertyModel(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { @@ -2485,8 +2471,8 @@ void GameMessages::SendUnSmash(Entity* entity, LWOOBJID builderID, float duratio void GameMessages::HandleControlBehaviors(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { AMFDeserialize reader; - std::unique_ptr amfArguments(reader.Read(inStream)); - if (amfArguments->GetValueType() != AMFValueType::AMFArray) return; + std::unique_ptr amfArguments(reader.Read(inStream)); + if (amfArguments->GetValueType() != eAmf::Array) return; uint32_t commandLength{}; inStream->Read(commandLength); @@ -2598,7 +2584,7 @@ void GameMessages::HandleBBBSaveRequest(RakNet::BitStream* inStream, Entity* ent GeneralUtils::SetBit(blueprintID, eObjectBits::PERSISTENT); //We need to get the propertyID: (stolen from Wincent's propertyManagementComp) - const auto& worldId = dZoneManager::Instance()->GetZone()->GetZoneID(); + const auto& worldId = Game::zoneManager->GetZone()->GetZoneID(); const auto zoneId = worldId.GetMapID(); const auto cloneId = worldId.GetCloneID(); @@ -2729,9 +2715,9 @@ void GameMessages::HandleBBBSaveRequest(RakNet::BitStream* inStream, Entity* ent info.settings.push_back(propertyObjectID); info.settings.push_back(userModelID); - Entity* newEntity = EntityManager::Instance()->CreateEntity(info, nullptr); + Entity* newEntity = Game::entityManager->CreateEntity(info, nullptr); if (newEntity) { - EntityManager::Instance()->ConstructEntity(newEntity); + Game::entityManager->ConstructEntity(newEntity); //Make sure the propMgmt doesn't delete our model after the server dies //Trying to do this after the entity is constructed. Shouldn't really change anything but @@ -2927,7 +2913,7 @@ void GameMessages::HandleCinematicUpdate(RakNet::BitStream* inStream, Entity* en inStream->Read(waypoint); } - std::vector scriptedActs = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::SCRIPT); + std::vector scriptedActs = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SCRIPT); for (Entity* scriptEntity : scriptedActs) { scriptEntity->OnCinematicUpdate(scriptEntity, entity, event, pathName, pathTime, overallTime, waypoint); } @@ -3307,7 +3293,7 @@ void GameMessages::HandleClientTradeRequest(RakNet::BitStream* inStream, Entity* inStream->Read(i64Invitee); - auto* invitee = EntityManager::Instance()->GetEntity(i64Invitee); + auto* invitee = Game::entityManager->GetEntity(i64Invitee); if (invitee != nullptr && invitee->IsPlayer()) { character = invitee->GetCharacter(); @@ -3470,7 +3456,7 @@ void GameMessages::SendNotifyTamingModelLoadedOnServer(LWOOBJID objectId, const SEND_PACKET; } -void GameMessages::SendNotifyPetTamingPuzzleSelected(LWOOBJID objectId, std::vector& bricks, const SystemAddress& sysAddr) { +void GameMessages::SendNotifyPetTamingPuzzleSelected(LWOOBJID objectId, const std::vector& bricks, const SystemAddress& sysAddr) { CBITSTREAM; CMSGHEADER; @@ -3891,10 +3877,10 @@ void GameMessages::HandleMessageBoxResponse(RakNet::BitStream* inStream, Entity* auto* racingControlComponent = entity->GetComponent(); if (racingControlComponent != nullptr) { - racingControlComponent->HandleMessageBoxResponse(userEntity, GeneralUtils::UTF16ToWTF8(identifier)); + racingControlComponent->HandleMessageBoxResponse(userEntity, iButton, GeneralUtils::UTF16ToWTF8(identifier)); } - for (auto* shootingGallery : EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::SHOOTING_GALLERY)) { + for (auto* shootingGallery : Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SHOOTING_GALLERY)) { shootingGallery->OnMessageBoxResponse(userEntity, iButton, identifier, userData); } } @@ -4055,7 +4041,7 @@ void GameMessages::HandleDismountComplete(RakNet::BitStream* inStream, Entity* e // If we aren't possessing somethings, the don't do anything if (objectId != LWOOBJID_EMPTY) { auto* possessorComponent = entity->GetComponent(); - auto* mount = EntityManager::Instance()->GetEntity(objectId); + auto* mount = Game::entityManager->GetEntity(objectId); // make sure we have the things we need and they aren't null if (possessorComponent && mount) { if (!possessorComponent->GetIsDismounting()) return; @@ -4080,7 +4066,7 @@ void GameMessages::HandleDismountComplete(RakNet::BitStream* inStream, Entity* e if (possessableComponent) possessableComponent->Dismount(); // Update the entity that was possessing - EntityManager::Instance()->SerializeEntity(entity); + Game::entityManager->SerializeEntity(entity); // We aren't mounted so remove the stun GameMessages::SendSetStunned(entity->GetObjectID(), eStateChangeType::POP, UNASSIGNED_SYSTEM_ADDRESS, LWOOBJID_EMPTY, true, false, true, false, false, false, false, true, true, true, true, true, true, true, true, true); @@ -4090,11 +4076,11 @@ void GameMessages::HandleDismountComplete(RakNet::BitStream* inStream, Entity* e void GameMessages::HandleAcknowledgePossession(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { - EntityManager::Instance()->SerializeEntity(entity); + Game::entityManager->SerializeEntity(entity); LWOOBJID objectId{}; inStream->Read(objectId); - auto* mount = EntityManager::Instance()->GetEntity(objectId); - if (mount) EntityManager::Instance()->SerializeEntity(mount); + auto* mount = Game::entityManager->GetEntity(objectId); + if (mount) Game::entityManager->SerializeEntity(mount); } //Racing @@ -4130,13 +4116,13 @@ void GameMessages::HandleRacingClientReady(RakNet::BitStream* inStream, Entity* inStream->Read(playerID); - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) { return; } - auto* racingControlComponent = dZoneManager::Instance()->GetZoneControlObject()->GetComponent(); + auto* racingControlComponent = Game::zoneManager->GetZoneControlObject()->GetComponent(); if (racingControlComponent == nullptr) { return; @@ -4184,7 +4170,7 @@ void GameMessages::HandleRequestDie(RakNet::BitStream* inStream, Entity* entity, inStream->Read(lootOwnerID); } - auto* zoneController = dZoneManager::Instance()->GetZoneControlObject(); + auto* zoneController = Game::zoneManager->GetZoneControlObject(); auto* racingControlComponent = zoneController->GetComponent(); @@ -4194,7 +4180,7 @@ void GameMessages::HandleRequestDie(RakNet::BitStream* inStream, Entity* entity, auto* possessableComponent = entity->GetComponent(); if (possessableComponent != nullptr) { - entity = EntityManager::Instance()->GetEntity(possessableComponent->GetPossessor()); + entity = Game::entityManager->GetEntity(possessableComponent->GetPossessor()); if (entity == nullptr) { return; @@ -4221,13 +4207,13 @@ void GameMessages::HandleRacingPlayerInfoResetFinished(RakNet::BitStream* inStre inStream->Read(playerID); - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) { return; } - auto* zoneController = dZoneManager::Instance()->GetZoneControlObject(); + auto* zoneController = Game::zoneManager->GetZoneControlObject(); auto* racingControlComponent = zoneController->GetComponent(); @@ -4257,7 +4243,7 @@ void GameMessages::HandleUpdatePropertyPerformanceCost(RakNet::BitStream* inStre if (performanceCost == 0.0f) return; - auto zone = dZoneManager::Instance()->GetZone(); + auto zone = Game::zoneManager->GetZone(); const auto& worldId = zone->GetZoneID(); const auto cloneId = worldId.GetCloneID(); const auto zoneId = worldId.GetMapID(); @@ -4285,7 +4271,7 @@ void GameMessages::HandleVehicleNotifyHitImaginationServer(RakNet::BitStream* in if (inStream->ReadBit()) inStream->Read(pickupSpawnerIndex); if (inStream->ReadBit()) inStream->Read(vehiclePosition); - auto* pickup = EntityManager::Instance()->GetEntity(pickupObjID); + auto* pickup = Game::entityManager->GetEntity(pickupObjID); if (pickup == nullptr) { return; @@ -4294,7 +4280,7 @@ void GameMessages::HandleVehicleNotifyHitImaginationServer(RakNet::BitStream* in auto* possessableComponent = entity->GetComponent(); if (possessableComponent != nullptr) { - entity = EntityManager::Instance()->GetEntity(possessableComponent->GetPossessor()); + entity = Game::entityManager->GetEntity(possessableComponent->GetPossessor()); if (entity == nullptr) { return; @@ -4685,7 +4671,7 @@ void GameMessages::HandleToggleGhostReferenceOverride(RakNet::BitStream* inStrea if (player != nullptr) { player->SetGhostOverride(bOverride); - EntityManager::Instance()->UpdateGhosting(player); + Game::entityManager->UpdateGhosting(player); } } @@ -4700,7 +4686,7 @@ void GameMessages::HandleSetGhostReferencePosition(RakNet::BitStream* inStream, if (player != nullptr) { player->SetGhostOverridePoint(position); - EntityManager::Instance()->UpdateGhosting(player); + Game::entityManager->UpdateGhosting(player); } } @@ -4718,7 +4704,7 @@ void GameMessages::HandleBuyFromVendor(RakNet::BitStream* inStream, Entity* enti User* user = UserManager::Instance()->GetUser(sysAddr); if (!user) return; - Entity* player = EntityManager::Instance()->GetEntity(user->GetLoggedInChar()); + Entity* player = Game::entityManager->GetEntity(user->GetLoggedInChar()); if (!player) return; auto* propertyVendorComponent = static_cast(entity->GetComponent(eReplicaComponentType::PROPERTY_VENDOR)); @@ -4731,12 +4717,17 @@ void GameMessages::HandleBuyFromVendor(RakNet::BitStream* inStream, Entity* enti const auto isCommendationVendor = entity->GetLOT() == 13806; - VendorComponent* vend = static_cast(entity->GetComponent(eReplicaComponentType::VENDOR)); + auto* vend = entity->GetComponent(); if (!vend && !isCommendationVendor) return; - InventoryComponent* inv = static_cast(player->GetComponent(eReplicaComponentType::INVENTORY)); + auto* inv = player->GetComponent(); if (!inv) return; + if (!isCommendationVendor && !vend->SellsItem(item)) { + Game::logger->Log("GameMessages", "User %llu %s tried to buy an item %i from a vendor when they do not sell said item", player->GetObjectID(), user->GetUsername().c_str(), item); + return; + } + CDComponentsRegistryTable* compRegistryTable = CDClientManager::Instance().GetTable(); CDItemComponentTable* itemComponentTable = CDClientManager::Instance().GetTable(); @@ -4816,7 +4807,7 @@ void GameMessages::HandleSellToVendor(RakNet::BitStream* inStream, Entity* entit User* user = UserManager::Instance()->GetUser(sysAddr); if (!user) return; - Entity* player = EntityManager::Instance()->GetEntity(user->GetLoggedInChar()); + Entity* player = Game::entityManager->GetEntity(user->GetLoggedInChar()); if (!player) return; Character* character = player->GetCharacter(); if (!character) return; @@ -4847,7 +4838,7 @@ void GameMessages::HandleSellToVendor(RakNet::BitStream* inStream, Entity* entit //inv->RemoveItem(count, -1, iObjID); inv->MoveItemToInventory(item, eInventoryType::VENDOR_BUYBACK, count, true, false, true); character->SetCoins(std::floor(character->GetCoins() + (static_cast(itemComp.baseValue * sellScalar) * count)), eLootSourceType::VENDOR); - //EntityManager::Instance()->SerializeEntity(player); // so inventory updates + //Game::entityManager->SerializeEntity(player); // so inventory updates GameMessages::SendVendorTransactionResult(entity, sysAddr); } @@ -4866,7 +4857,7 @@ void GameMessages::HandleBuybackFromVendor(RakNet::BitStream* inStream, Entity* User* user = UserManager::Instance()->GetUser(sysAddr); if (!user) return; - Entity* player = EntityManager::Instance()->GetEntity(user->GetLoggedInChar()); + Entity* player = Game::entityManager->GetEntity(user->GetLoggedInChar()); if (!player) return; Character* character = player->GetCharacter(); if (!character) return; @@ -4906,7 +4897,7 @@ void GameMessages::HandleBuybackFromVendor(RakNet::BitStream* inStream, Entity* //inv->RemoveItem(count, -1, iObjID); inv->MoveItemToInventory(item, Inventory::FindInventoryTypeForLot(item->GetLot()), count, true, false); character->SetCoins(character->GetCoins() - cost, eLootSourceType::VENDOR); - //EntityManager::Instance()->SerializeEntity(player); // so inventory updates + //Game::entityManager->SerializeEntity(player); // so inventory updates GameMessages::SendVendorTransactionResult(entity, sysAddr); } @@ -4953,7 +4944,7 @@ void GameMessages::HandleFireEventServerSide(RakNet::BitStream* inStream, Entity if (param3IsDefault) inStream->Read(param3); inStream->Read(senderID); - auto* sender = EntityManager::Instance()->GetEntity(senderID); + auto* sender = Game::entityManager->GetEntity(senderID); auto* player = Player::GetPlayer(sysAddr); if (!player) { @@ -4984,7 +4975,7 @@ void GameMessages::HandleFireEventServerSide(RakNet::BitStream* inStream, Entity } if (mapId == 0) { - mapId = dZoneManager::Instance()->GetZoneID().GetMapID(); // Fallback to sending the player back to the same zone. + mapId = Game::zoneManager->GetZoneID().GetMapID(); // Fallback to sending the player back to the same zone. } Game::logger->Log("FireEventServerSide", "Player %llu has requested zone transfer to (%i, %i).", sender->GetObjectID(), (int)mapId, (int)cloneId); @@ -5027,7 +5018,7 @@ void GameMessages::HandleRebuildCancel(RakNet::BitStream* inStream, Entity* enti RebuildComponent* rebComp = static_cast(entity->GetComponent(eReplicaComponentType::QUICK_BUILD)); if (!rebComp) return; - rebComp->CancelRebuild(EntityManager::Instance()->GetEntity(userID), eQuickBuildFailReason::CANCELED_EARLY); + rebComp->CancelRebuild(Game::entityManager->GetEntity(userID), eQuickBuildFailReason::CANCELED_EARLY); } void GameMessages::HandleRequestUse(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { @@ -5043,7 +5034,7 @@ void GameMessages::HandleRequestUse(RakNet::BitStream* inStream, Entity* entity, inStream->Read(objectID); inStream->Read(secondary); - Entity* interactedObject = EntityManager::Instance()->GetEntity(objectID); + Entity* interactedObject = Game::entityManager->GetEntity(objectID); if (interactedObject == nullptr) { Game::logger->Log("GameMessages", "Object %llu tried to interact, but doesn't exist!", objectID); @@ -5096,7 +5087,7 @@ void GameMessages::HandlePlayEmote(RakNet::BitStream* inStream, Entity* entity) if (!missionComponent) return; if (targetID != LWOOBJID_EMPTY) { - auto* targetEntity = EntityManager::Instance()->GetEntity(targetID); + auto* targetEntity = Game::entityManager->GetEntity(targetID); Game::logger->LogDebug("GameMessages", "Emote target found (%d)", targetEntity != nullptr); @@ -5106,7 +5097,7 @@ void GameMessages::HandlePlayEmote(RakNet::BitStream* inStream, Entity* entity) } } else { Game::logger->LogDebug("GameMessages", "Target ID is empty, using backup"); - const auto scriptedEntities = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::SCRIPT); + const auto scriptedEntities = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SCRIPT); const auto& referencePoint = entity->GetPosition(); @@ -5124,7 +5115,7 @@ void GameMessages::HandlePlayEmote(RakNet::BitStream* inStream, Entity* entity) if (emote) sAnimationName = emote->animationName; } - GameMessages::SendPlayAnimation(entity, GeneralUtils::ASCIIToUTF16(sAnimationName)); + RenderComponent::PlayAnimation(entity, sAnimationName); } void GameMessages::HandleModularBuildConvertModel(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { @@ -5134,7 +5125,7 @@ void GameMessages::HandleModularBuildConvertModel(RakNet::BitStream* inStream, E User* user = UserManager::Instance()->GetUser(sysAddr); if (!user) return; - Entity* character = EntityManager::Instance()->GetEntity(user->GetLoggedInChar()); + Entity* character = Game::entityManager->GetEntity(user->GetLoggedInChar()); if (!character) return; InventoryComponent* inv = static_cast(character->GetComponent(eReplicaComponentType::INVENTORY)); if (!inv) return; @@ -5192,7 +5183,7 @@ void GameMessages::HandleRespondToMission(RakNet::BitStream* inStream, Entity* e Game::logger->Log("GameMessages", "Unable to get mission %i for entity %llu to update reward in RespondToMission", missionID, playerID); } - Entity* offerer = EntityManager::Instance()->GetEntity(receiverID); + Entity* offerer = Game::entityManager->GetEntity(receiverID); if (offerer == nullptr) { Game::logger->Log("GameMessages", "Unable to get receiver entity %llu for RespondToMission", receiverID); @@ -5200,7 +5191,7 @@ void GameMessages::HandleRespondToMission(RakNet::BitStream* inStream, Entity* e } for (CppScripts::Script* script : CppScripts::GetEntityScripts(offerer)) { - script->OnRespondToMission(offerer, missionID, EntityManager::Instance()->GetEntity(playerID), reward); + script->OnRespondToMission(offerer, missionID, Game::entityManager->GetEntity(playerID), reward); } } @@ -5215,7 +5206,7 @@ void GameMessages::HandleMissionDialogOK(RakNet::BitStream* inStream, Entity* en inStream->Read(iMissionState); inStream->Read(missionID); inStream->Read(responder); - player = EntityManager::Instance()->GetEntity(responder); + player = Game::entityManager->GetEntity(responder); for (CppScripts::Script* script : CppScripts::GetEntityScripts(entity)) { script->OnMissionDialogueOK(entity, player, missionID, iMissionState); @@ -5244,7 +5235,7 @@ void GameMessages::HandleRequestLinkedMission(RakNet::BitStream* inStream, Entit inStream->Read(missionId); inStream->Read(bMissionOffered); - auto* player = EntityManager::Instance()->GetEntity(playerId); + auto* player = Game::entityManager->GetEntity(playerId); auto* missionOfferComponent = static_cast(entity->GetComponent(eReplicaComponentType::MISSION_OFFER)); @@ -5257,7 +5248,7 @@ void GameMessages::HandleHasBeenCollected(RakNet::BitStream* inStream, Entity* e LWOOBJID playerID; inStream->Read(playerID); - Entity* player = EntityManager::Instance()->GetEntity(playerID); + Entity* player = Game::entityManager->GetEntity(playerID); if (!player || !entity || entity->GetCollectibleID() == 0) return; MissionComponent* missionComponent = static_cast(player->GetComponent(eReplicaComponentType::MISSION)); @@ -5371,7 +5362,7 @@ void GameMessages::HandleEquipItem(RakNet::BitStream* inStream, Entity* entity) item->Equip(); - EntityManager::Instance()->SerializeEntity(entity); + Game::entityManager->SerializeEntity(entity); } void GameMessages::HandleUnequipItem(RakNet::BitStream* inStream, Entity* entity) { @@ -5391,7 +5382,7 @@ void GameMessages::HandleUnequipItem(RakNet::BitStream* inStream, Entity* entity item->UnEquip(); - EntityManager::Instance()->SerializeEntity(entity); + Game::entityManager->SerializeEntity(entity); } void GameMessages::HandleRemoveItemFromInventory(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { @@ -5476,7 +5467,7 @@ void GameMessages::HandleRemoveItemFromInventory(RakNet::BitStream* inStream, En } item->SetCount(item->GetCount() - iStackCount, true); - EntityManager::Instance()->SerializeEntity(entity); + Game::entityManager->SerializeEntity(entity); auto* missionComponent = entity->GetComponent(); @@ -5510,7 +5501,7 @@ void GameMessages::HandleMoveItemInInventory(RakNet::BitStream* inStream, Entity } inv->MoveStack(item, static_cast(destInvType), slot); - EntityManager::Instance()->SerializeEntity(entity); + Game::entityManager->SerializeEntity(entity); } void GameMessages::HandleMoveItemBetweenInventoryTypes(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { @@ -5556,7 +5547,7 @@ void GameMessages::HandleMoveItemBetweenInventoryTypes(RakNet::BitStream* inStre } inv->MoveItemToInventory(item, inventoryTypeB, stackCount, showFlyingLoot); - EntityManager::Instance()->SerializeEntity(entity); + Game::entityManager->SerializeEntity(entity); } void GameMessages::HandleBuildModeSet(RakNet::BitStream* inStream, Entity* entity) { @@ -5575,7 +5566,7 @@ void GameMessages::HandleBuildModeSet(RakNet::BitStream* inStream, Entity* entit void GameMessages::HandleModularBuildFinish(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { User* user = UserManager::Instance()->GetUser(sysAddr); if (!user) return; - Entity* character = EntityManager::Instance()->GetEntity(user->GetLoggedInChar()); + Entity* character = Game::entityManager->GetEntity(user->GetLoggedInChar()); if (!character) return; InventoryComponent* inv = static_cast(character->GetComponent(eReplicaComponentType::INVENTORY)); if (!inv) return; @@ -5586,7 +5577,7 @@ void GameMessages::HandleModularBuildFinish(RakNet::BitStream* inStream, Entity* GameMessages::SendModularBuildEnd(character); // i dont know if this does anything but DLUv2 did it //inv->UnequipItem(inv->GetItemStackByLOT(6086, eInventoryType::ITEMS)); // take off the thinking cap - //EntityManager::Instance()->SerializeEntity(entity); + //Game::entityManager->SerializeEntity(entity); uint8_t count; // 3 for rockets, 7 for cars @@ -5663,7 +5654,7 @@ void GameMessages::HandleModularBuildFinish(RakNet::BitStream* inStream, Entity* void GameMessages::HandleDoneArrangingWithItem(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { User* user = UserManager::Instance()->GetUser(sysAddr); if (!user) return; - Entity* character = EntityManager::Instance()->GetEntity(user->GetLoggedInChar()); + Entity* character = Game::entityManager->GetEntity(user->GetLoggedInChar()); if (!character) return; InventoryComponent* inv = static_cast(character->GetComponent(eReplicaComponentType::INVENTORY)); if (!inv) return; @@ -5716,9 +5707,9 @@ void GameMessages::HandleDoneArrangingWithItem(RakNet::BitStream* inStream, Enti */ if (PropertyManagementComponent::Instance() != nullptr) { - const auto& buildAreas = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::BUILD_BORDER); + const auto& buildAreas = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::BUILD_BORDER); - const auto& entities = EntityManager::Instance()->GetEntitiesInGroup("PropertyPlaque"); + const auto& entities = Game::entityManager->GetEntitiesInGroup("PropertyPlaque"); Entity* buildArea; @@ -5774,7 +5765,7 @@ void GameMessages::HandleDoneArrangingWithItem(RakNet::BitStream* inStream, Enti void GameMessages::HandleModularBuildMoveAndEquip(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { User* user = UserManager::Instance()->GetUser(sysAddr); if (!user) return; - Entity* character = EntityManager::Instance()->GetEntity(user->GetLoggedInChar()); + Entity* character = Game::entityManager->GetEntity(user->GetLoggedInChar()); if (!character) return; Game::logger->Log("GameMessages", "Build and move"); @@ -5807,7 +5798,7 @@ void GameMessages::HandlePickupItem(RakNet::BitStream* inStream, Entity* entity) if (team != nullptr) { for (const auto memberId : team->members) { - auto* member = EntityManager::Instance()->GetEntity(memberId); + auto* member = Game::entityManager->GetEntity(memberId); if (member == nullptr || memberId == playerID) continue; @@ -5819,12 +5810,12 @@ void GameMessages::HandlePickupItem(RakNet::BitStream* inStream, Entity* entity) void GameMessages::HandleResurrect(RakNet::BitStream* inStream, Entity* entity) { bool immediate = inStream->ReadBit(); - Entity* zoneControl = EntityManager::Instance()->GetZoneControlEntity(); + Entity* zoneControl = Game::entityManager->GetZoneControlEntity(); for (CppScripts::Script* script : CppScripts::GetEntityScripts(zoneControl)) { script->OnPlayerResurrected(zoneControl, entity); } - std::vector scriptedActs = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::SCRIPTED_ACTIVITY); + std::vector scriptedActs = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SCRIPTED_ACTIVITY); for (Entity* scriptEntity : scriptedActs) { if (scriptEntity->GetObjectID() != zoneControl->GetObjectID()) { // Don't want to trigger twice on instance worlds for (CppScripts::Script* script : CppScripts::GetEntityScripts(scriptEntity)) { @@ -5844,7 +5835,7 @@ void GameMessages::HandlePopEquippedItemsState(RakNet::BitStream* inStream, Enti InventoryComponent* inv = static_cast(entity->GetComponent(eReplicaComponentType::INVENTORY)); if (!inv) return; inv->PopEquippedItems(); - EntityManager::Instance()->SerializeEntity(entity); // so it updates on client side + Game::entityManager->SerializeEntity(entity); // so it updates on client side } @@ -5910,7 +5901,7 @@ void GameMessages::HandleMatchRequest(RakNet::BitStream* inStream, Entity* entit inStream->Read(type); inStream->Read(value); - std::vector scriptedActs = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::SCRIPTED_ACTIVITY); + std::vector scriptedActs = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SCRIPTED_ACTIVITY); if (type == 0) { // join if (value != 0) { for (Entity* scriptedAct : scriptedActs) { @@ -6043,7 +6034,7 @@ void GameMessages::HandleReportBug(RakNet::BitStream* inStream, Entity* entity) void GameMessages::HandleClientRailMovementReady(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { - const auto possibleRails = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::RAIL_ACTIVATOR); + const auto possibleRails = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::RAIL_ACTIVATOR); for (const auto* possibleRail : possibleRails) { const auto* rail = possibleRail->GetComponent(); if (rail != nullptr) { @@ -6055,7 +6046,7 @@ GameMessages::HandleClientRailMovementReady(RakNet::BitStream* inStream, Entity* void GameMessages::HandleCancelRailMovement(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { const auto immediate = inStream->ReadBit(); - const auto possibleRails = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::RAIL_ACTIVATOR); + const auto possibleRails = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::RAIL_ACTIVATOR); for (const auto* possibleRail : possibleRails) { auto* rail = possibleRail->GetComponent(); if (rail != nullptr) { @@ -6079,7 +6070,7 @@ void GameMessages::HandlePlayerRailArrivedNotification(RakNet::BitStream* inStre int32_t waypointNumber; inStream->Read(waypointNumber); - const auto possibleRails = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::RAIL_ACTIVATOR); + const auto possibleRails = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::RAIL_ACTIVATOR); for (auto* possibleRail : possibleRails) { for (CppScripts::Script* script : CppScripts::GetEntityScripts(possibleRail)) { script->OnPlayerRailArrived(possibleRail, entity, pathName, waypointNumber); @@ -6172,7 +6163,7 @@ void GameMessages::SendDeactivateBubbleBuffFromServer(LWOOBJID objectId, const S void GameMessages::HandleZoneSummaryDismissed(RakNet::BitStream* inStream, Entity* entity) { LWOOBJID player_id; inStream->Read(player_id); - auto target = EntityManager::Instance()->GetEntity(player_id); + auto target = Game::entityManager->GetEntity(player_id); entity->TriggerEvent(eTriggerEventType::ZONE_SUMMARY_DISMISSED, target); }; @@ -6204,3 +6195,15 @@ void GameMessages::SendShowBillboardInteractIcon(const SystemAddress& sysAddr, L if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST else SEND_PACKET } + +void GameMessages::HandleRequestActivityExit(RakNet::BitStream* inStream, Entity* entity) { + bool canceled = false; + inStream->Read(canceled); + if (!canceled) return; + + LWOOBJID player_id = LWOOBJID_EMPTY; + inStream->Read(player_id); + auto player = Game::entityManager->GetEntity(player_id); + if (!entity || !player) return; + entity->RequestActivityExit(entity, player_id, canceled); +} diff --git a/dGame/dGameMessages/GameMessages.h b/dGame/dGameMessages/GameMessages.h index ce24a105..bd1224d3 100644 --- a/dGame/dGameMessages/GameMessages.h +++ b/dGame/dGameMessages/GameMessages.h @@ -12,7 +12,7 @@ #include "eLootSourceType.h" #include "Brick.h" -class AMFValue; +class AMFBaseValue; class Entity; class Item; class NiQuaternion; @@ -40,7 +40,7 @@ enum class eRebuildState : uint32_t; namespace GameMessages { class PropertyDataMessage; void SendFireEventClientSide(const LWOOBJID& objectID, const SystemAddress& sysAddr, std::u16string args, const LWOOBJID& object, int64_t param1, int param2, const LWOOBJID& sender); - void SendTeleport(const LWOOBJID& objectID, const NiPoint3& pos, const NiQuaternion& rot, const SystemAddress& sysAddr, bool bSetRotation = false, bool noGravTeleport = true); + void SendTeleport(const LWOOBJID& objectID, const NiPoint3& pos, const NiQuaternion& rot, const SystemAddress& sysAddr, bool bSetRotation = false); void SendPlayAnimation(Entity* entity, const std::u16string& animationName, float fPriority = 0.0f, float fScale = 1.0f); void SendPlayerReady(Entity* entity, const SystemAddress& sysAddr); void SendPlayerAllowedRespawn(LWOOBJID entityID, bool doNotPromptRespawn, const SystemAddress& systemAddress); @@ -88,8 +88,8 @@ namespace GameMessages { void NotifyLevelRewards(LWOOBJID objectID, const SystemAddress& sysAddr, int level, bool sending_rewards); void SendModifyLEGOScore(Entity* entity, const SystemAddress& sysAddr, int64_t score, eLootSourceType sourceType); - void SendUIMessageServerToSingleClient(Entity* entity, const SystemAddress& sysAddr, const std::string& message, AMFValue* args); - void SendUIMessageServerToAllClients(const std::string& message, AMFValue* args); + void SendUIMessageServerToSingleClient(Entity* entity, const SystemAddress& sysAddr, const std::string& message, AMFBaseValue& args); + void SendUIMessageServerToAllClients(const std::string& message, AMFBaseValue& args); void SendPlayEmbeddedEffectOnAllClientsNearObject(Entity* entity, std::u16string effectName, const LWOOBJID& fromObjectID, float radius); void SendPlayFXEffect(Entity* entity, int32_t effectID, const std::u16string& effectType, const std::string& name, LWOOBJID secondary, float priority = 1, float scale = 1, bool serialize = true); @@ -364,7 +364,7 @@ namespace GameMessages { //Pets: void SendNotifyPetTamingMinigame(LWOOBJID objectId, LWOOBJID petId, LWOOBJID playerTamingId, bool bForceTeleport, ePetTamingNotifyType notifyType, NiPoint3 petsDestPos, NiPoint3 telePos, NiQuaternion teleRot, const SystemAddress& sysAddr); - void SendNotifyPetTamingPuzzleSelected(LWOOBJID objectId, std::vector& bricks, const SystemAddress& sysAddr); + void SendNotifyPetTamingPuzzleSelected(LWOOBJID objectId, const std::vector& bricks, const SystemAddress& sysAddr); void SendNotifyTamingModelLoadedOnServer(LWOOBJID objectId, const SystemAddress& sysAddr); @@ -648,6 +648,7 @@ namespace GameMessages { void SendDeactivateBubbleBuffFromServer(LWOOBJID objectId, const SystemAddress& sysAddr); void HandleZoneSummaryDismissed(RakNet::BitStream* inStream, Entity* entity); + void HandleRequestActivityExit(RakNet::BitStream* inStream, Entity* entity); }; #endif // GAMEMESSAGES_H diff --git a/dGame/dInventory/Item.cpp b/dGame/dInventory/Item.cpp index 83ac8869..64f1dfbd 100644 --- a/dGame/dInventory/Item.cpp +++ b/dGame/dInventory/Item.cpp @@ -100,7 +100,7 @@ Item::Item( Game::logger->Log("Item", "Move and equipped (%i) from (%i)", this->lot, this->inventory->GetType()); - EntityManager::Instance()->SerializeEntity(inventory->GetComponent()->GetParent()); + Game::entityManager->SerializeEntity(inventory->GetComponent()->GetParent()); } } diff --git a/dGame/dInventory/ItemSetPassiveAbility.cpp b/dGame/dInventory/ItemSetPassiveAbility.cpp index bf7c19cb..3030904d 100644 --- a/dGame/dInventory/ItemSetPassiveAbility.cpp +++ b/dGame/dInventory/ItemSetPassiveAbility.cpp @@ -44,7 +44,7 @@ void ItemSetPassiveAbility::Activate(Entity* target) { return; } - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); const auto id = static_cast(m_ItemSet->GetID()); const auto parentID = m_Parent->GetObjectID(); @@ -203,7 +203,7 @@ void ItemSetPassiveAbility::OnEnemySmshed(Entity* target) { return; } - EntityManager::Instance()->SerializeEntity(m_Parent); + Game::entityManager->SerializeEntity(m_Parent); const auto id = static_cast(m_ItemSet->GetID()); const auto parentID = m_Parent->GetObjectID(); diff --git a/dGame/dMission/Mission.cpp b/dGame/dMission/Mission.cpp index 32a930e4..34641335 100644 --- a/dGame/dMission/Mission.cpp +++ b/dGame/dMission/Mission.cpp @@ -34,7 +34,7 @@ Mission::Mission(MissionComponent* missionComponent, const uint32_t missionId) { m_Timestamp = 0; - m_UniqueMissionID = dZoneManager::Instance()->GetUniqueMissionIdStartingValue(); + m_UniqueMissionID = Game::zoneManager->GetUniqueMissionIdStartingValue(); m_Reward = 0; @@ -443,9 +443,9 @@ void Mission::YieldRewards() { int32_t coinsToSend = 0; if (info->LegoScore > 0) { eLootSourceType lootSource = info->isMission ? eLootSourceType::MISSION : eLootSourceType::ACHIEVEMENT; - if (levelComponent->GetLevel() >= dZoneManager::Instance()->GetWorldConfig()->levelCap) { + if (levelComponent->GetLevel() >= Game::zoneManager->GetWorldConfig()->levelCap) { // Since the character is at the level cap we reward them with coins instead of UScore. - coinsToSend += info->LegoScore * dZoneManager::Instance()->GetWorldConfig()->levelCapCurrencyConversion; + coinsToSend += info->LegoScore * Game::zoneManager->GetWorldConfig()->levelCapCurrencyConversion; } else { characterComponent->SetUScore(characterComponent->GetUScore() + info->LegoScore); GameMessages::SendModifyLEGOScore(entity, entity->GetSystemAddress(), info->LegoScore, lootSource); @@ -547,7 +547,7 @@ void Mission::YieldRewards() { destroyableComponent->SetMaxImagination(destroyableComponent->GetMaxImagination() + static_cast(info->reward_maximagination), true); } - EntityManager::Instance()->SerializeEntity(entity); + Game::entityManager->SerializeEntity(entity); if (info->reward_emote > 0) { character->UnlockEmote(info->reward_emote); diff --git a/dGame/dMission/MissionTask.cpp b/dGame/dMission/MissionTask.cpp index 344427c6..6bc12b72 100644 --- a/dGame/dMission/MissionTask.cpp +++ b/dGame/dMission/MissionTask.cpp @@ -230,7 +230,7 @@ void MissionTask::Progress(int32_t value, LWOOBJID associate, const std::string& break; } - entity = EntityManager::Instance()->GetEntity(associate); + entity = Game::entityManager->GetEntity(associate); if (entity == nullptr) { if (associate != LWOOBJID_EMPTY) { Game::logger->Log("MissionTask", "Failed to find associated entity (%llu)!", associate); @@ -272,7 +272,7 @@ void MissionTask::Progress(int32_t value, LWOOBJID associate, const std::string& { if (!InParameters(value)) break; - entity = EntityManager::Instance()->GetEntity(associate); + entity = Game::entityManager->GetEntity(associate); if (entity == nullptr) { Game::logger->Log("MissionTask", "Failed to find associated entity (%llu)!", associate); @@ -302,7 +302,7 @@ void MissionTask::Progress(int32_t value, LWOOBJID associate, const std::string& case eMissionTaskType::PERFORM_ACTIVITY: { - auto* minigameManager = EntityManager::Instance()->GetEntity(associate); + auto* minigameManager = Game::entityManager->GetEntity(associate); if (minigameManager == nullptr) break; @@ -346,7 +346,7 @@ void MissionTask::Progress(int32_t value, LWOOBJID associate, const std::string& { if (!InAllTargets(value)) break; - entity = EntityManager::Instance()->GetEntity(associate); + entity = Game::entityManager->GetEntity(associate); if (entity == nullptr) { Game::logger->Log("MissionTask", "Failed to find associated entity (%llu)!", associate); @@ -391,7 +391,7 @@ void MissionTask::Progress(int32_t value, LWOOBJID associate, const std::string& // The meaning of associate can be found in eRacingTaskParam.h if (parameters.empty()) break; - if (!InAllTargets(dZoneManager::Instance()->GetZone()->GetWorldID()) && !(parameters[0] == 4 || parameters[0] == 5) && !InAllTargets(value)) break; + if (!InAllTargets(Game::zoneManager->GetZone()->GetWorldID()) && !(parameters[0] == 4 || parameters[0] == 5) && !InAllTargets(value)) break; if (parameters[0] != associate) break; diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.cpp index 7da286b0..eabe76b7 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.cpp @@ -12,19 +12,19 @@ Action::Action(AMFArrayValue* arguments) { valueParameterName = ""; valueParameterString = ""; valueParameterDouble = 0.0; - for (auto& typeValueMap : arguments->GetAssociativeMap()) { + for (auto& typeValueMap : arguments->GetAssociative()) { if (typeValueMap.first == "Type") { - if (typeValueMap.second->GetValueType() != AMFValueType::AMFString) continue; - type = static_cast(typeValueMap.second)->GetStringValue(); + if (typeValueMap.second->GetValueType() != eAmf::String) continue; + type = static_cast(typeValueMap.second)->GetValue(); } else { valueParameterName = typeValueMap.first; // Message is the only known string parameter if (valueParameterName == "Message") { - if (typeValueMap.second->GetValueType() != AMFValueType::AMFString) continue; - valueParameterString = static_cast(typeValueMap.second)->GetStringValue(); + if (typeValueMap.second->GetValueType() != eAmf::String) continue; + valueParameterString = static_cast(typeValueMap.second)->GetValue(); } else { - if (typeValueMap.second->GetValueType() != AMFValueType::AMFDouble) continue; - valueParameterDouble = static_cast(typeValueMap.second)->GetDoubleValue(); + if (typeValueMap.second->GetValueType() != eAmf::Double) continue; + valueParameterDouble = static_cast(typeValueMap.second)->GetValue(); } } } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/ActionContext.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/ActionContext.cpp index 480eef45..c2ba2eeb 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/ActionContext.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/ActionContext.cpp @@ -2,7 +2,7 @@ #include -#include "AMFFormat.h" +#include "Amf3.h" ActionContext::ActionContext() { stripId = 0; @@ -17,15 +17,15 @@ ActionContext::ActionContext(AMFArrayValue* arguments, std::string customStateKe } BehaviorState ActionContext::GetBehaviorStateFromArgument(AMFArrayValue* arguments, const std::string& key) { - auto* stateIDValue = arguments->FindValue(key); + auto* stateIDValue = arguments->Get(key); if (!stateIDValue) throw std::invalid_argument("Unable to find behavior state from argument \"" + key + "\""); - return static_cast(stateIDValue->GetDoubleValue()); + return static_cast(stateIDValue->GetValue()); } StripId ActionContext::GetStripIdFromArgument(AMFArrayValue* arguments, const std::string& key) { - auto* stripIdValue = arguments->FindValue(key); + auto* stripIdValue = arguments->Get(key); if (!stripIdValue) throw std::invalid_argument("Unable to find strip ID from argument \"" + key + "\""); - return static_cast(stripIdValue->GetDoubleValue()); + return static_cast(stripIdValue->GetValue()); } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddActionMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddActionMessage.cpp index 4fc7f82b..98672909 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddActionMessage.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddActionMessage.cpp @@ -4,7 +4,7 @@ AddActionMessage::AddActionMessage(AMFArrayValue* arguments) : BehaviorMessageBa actionContext = ActionContext(arguments); actionIndex = GetActionIndexFromArgument(arguments); - auto* actionValue = arguments->FindValue("action"); + auto* actionValue = arguments->GetArray("action"); if (!actionValue) return; action = Action(actionValue); diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddMessage.cpp index 4f2123b4..badee2c2 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddMessage.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddMessage.cpp @@ -2,10 +2,10 @@ AddMessage::AddMessage(AMFArrayValue* arguments) : BehaviorMessageBase(arguments) { behaviorIndex = 0; - auto* behaviorIndexValue = arguments->FindValue("BehaviorIndex"); + auto* behaviorIndexValue = arguments->Get("BehaviorIndex"); if (!behaviorIndexValue) return; - behaviorIndex = static_cast(behaviorIndexValue->GetDoubleValue()); + behaviorIndex = static_cast(behaviorIndexValue->GetValue()); Game::logger->LogDebug("AddMessage", "behaviorId %i index %i", behaviorId, behaviorIndex); } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddStripMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddStripMessage.cpp index c4729c57..261b3462 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddStripMessage.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddStripMessage.cpp @@ -4,17 +4,16 @@ AddStripMessage::AddStripMessage(AMFArrayValue* arguments) : BehaviorMessageBase(arguments) { actionContext = ActionContext(arguments); - position = StripUiPosition(arguments); - auto* strip = arguments->FindValue("strip"); + auto* strip = arguments->GetArray("strip"); if (!strip) return; - auto* actions = strip->FindValue("actions"); + auto* actions = strip->GetArray("actions"); if (!actions) return; - for (uint32_t actionNumber = 0; actionNumber < actions->GetDenseValueSize(); actionNumber++) { - auto* actionValue = actions->GetValueAt(actionNumber); + for (uint32_t actionNumber = 0; actionNumber < actions->GetDense().size(); actionNumber++) { + auto* actionValue = actions->GetArray(actionNumber); if (!actionValue) continue; actionsToAdd.push_back(Action(actionValue)); diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.cpp index b3d98d51..3286504a 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.cpp @@ -1,6 +1,6 @@ #include "BehaviorMessageBase.h" -#include "AMFFormat.h" +#include "Amf3.h" #include "BehaviorStates.h" #include "dCommonVars.h" @@ -11,12 +11,12 @@ BehaviorMessageBase::BehaviorMessageBase(AMFArrayValue* arguments) { int32_t BehaviorMessageBase::GetBehaviorIdFromArgument(AMFArrayValue* arguments) { const auto* key = "BehaviorID"; - auto* behaviorIDValue = arguments->FindValue(key); + auto* behaviorIDValue = arguments->Get(key); int32_t behaviorID = -1; - if (behaviorIDValue) { - behaviorID = std::stoul(behaviorIDValue->GetStringValue()); - } else if (!arguments->FindValue(key)) { + if (behaviorIDValue && behaviorIDValue->GetValueType() == eAmf::String) { + behaviorID = std::stoul(behaviorIDValue->GetValue()); + } else if (arguments->Get(key)->GetValueType() != eAmf::Undefined) { throw std::invalid_argument("Unable to find behavior ID"); } @@ -24,10 +24,10 @@ int32_t BehaviorMessageBase::GetBehaviorIdFromArgument(AMFArrayValue* arguments) } uint32_t BehaviorMessageBase::GetActionIndexFromArgument(AMFArrayValue* arguments, const std::string& keyName) { - auto* actionIndexAmf = arguments->FindValue(keyName); + auto* actionIndexAmf = arguments->Get(keyName); if (!actionIndexAmf) { throw std::invalid_argument("Unable to find actionIndex"); } - return static_cast(actionIndexAmf->GetDoubleValue()); + return static_cast(actionIndexAmf->GetValue()); } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.h index 13b00a35..8771286c 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.h @@ -4,7 +4,7 @@ #include #include -#include "AMFFormat.h" +#include "Amf3.h" #include "dCommonVars.h" #include "Game.h" diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MoveToInventoryMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MoveToInventoryMessage.cpp index 92700076..5b61ee32 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MoveToInventoryMessage.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MoveToInventoryMessage.cpp @@ -1,9 +1,9 @@ #include "MoveToInventoryMessage.h" MoveToInventoryMessage::MoveToInventoryMessage(AMFArrayValue* arguments) : BehaviorMessageBase(arguments) { - auto* behaviorIndexValue = arguments->FindValue("BehaviorIndex"); + auto* behaviorIndexValue = arguments->Get("BehaviorIndex"); if (!behaviorIndexValue) return; - behaviorIndex = static_cast(behaviorIndexValue->GetDoubleValue()); + behaviorIndex = static_cast(behaviorIndexValue->GetValue()); Game::logger->LogDebug("MoveToInventoryMessage", "behaviorId %i behaviorIndex %i", behaviorId, behaviorIndex); } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RenameMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RenameMessage.cpp index 0ea3b6d6..a1c2abbc 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RenameMessage.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RenameMessage.cpp @@ -1,9 +1,9 @@ #include "RenameMessage.h" RenameMessage::RenameMessage(AMFArrayValue* arguments) : BehaviorMessageBase(arguments) { - auto* nameAmf = arguments->FindValue("Name"); + auto* nameAmf = arguments->Get("Name"); if (!nameAmf) return; - name = nameAmf->GetStringValue(); + name = nameAmf->GetValue(); Game::logger->LogDebug("RenameMessage", "behaviorId %i n %s", behaviorId, name.c_str()); } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.cpp index 4ddccc55..de612b45 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.cpp @@ -1,6 +1,6 @@ #include "StripUiPosition.h" -#include "AMFFormat.h" +#include "Amf3.h" StripUiPosition::StripUiPosition() { xPosition = 0.0; @@ -10,13 +10,13 @@ StripUiPosition::StripUiPosition() { StripUiPosition::StripUiPosition(AMFArrayValue* arguments, std::string uiKeyName) { xPosition = 0.0; yPosition = 0.0; - auto* uiArray = arguments->FindValue(uiKeyName); + auto* uiArray = arguments->GetArray(uiKeyName); if (!uiArray) return; - auto* xPositionValue = uiArray->FindValue("x"); - auto* yPositionValue = uiArray->FindValue("y"); + auto* xPositionValue = uiArray->Get("x"); + auto* yPositionValue = uiArray->Get("y"); if (!xPositionValue || !yPositionValue) return; - yPosition = yPositionValue->GetDoubleValue(); - xPosition = xPositionValue->GetDoubleValue(); + yPosition = yPositionValue->GetValue(); + xPosition = xPositionValue->GetValue(); } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateActionMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateActionMessage.cpp index 53e2d570..23a0050d 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateActionMessage.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateActionMessage.cpp @@ -5,7 +5,7 @@ UpdateActionMessage::UpdateActionMessage(AMFArrayValue* arguments) : BehaviorMessageBase(arguments) { actionContext = ActionContext(arguments); - auto* actionValue = arguments->FindValue("action"); + auto* actionValue = arguments->GetArray("action"); if (!actionValue) return; action = Action(actionValue); diff --git a/dGame/dPropertyBehaviors/ControlBehaviors.cpp b/dGame/dPropertyBehaviors/ControlBehaviors.cpp index dfb22b59..d8a062ca 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviors.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviors.cpp @@ -1,6 +1,6 @@ #include "ControlBehaviors.h" -#include "AMFFormat.h" +#include "Amf3.h" #include "Entity.h" #include "Game.h" #include "GameMessages.h" @@ -43,11 +43,11 @@ void ControlBehaviors::RequestUpdatedID(int32_t behaviorID, ModelComponent* mode // AMFArrayValue args; // AMFStringValue* behaviorIDString = new AMFStringValue(); - // behaviorIDString->SetStringValue(std::to_string(persistentId)); + // behaviorIDString->SetValue(std::to_string(persistentId)); // args.InsertValue("behaviorID", behaviorIDString); // AMFStringValue* objectIDAsString = new AMFStringValue(); - // objectIDAsString->SetStringValue(std::to_string(modelComponent->GetParent()->GetObjectID())); + // objectIDAsString->SetValue(std::to_string(modelComponent->GetParent()->GetObjectID())); // args.InsertValue("objectID", objectIDAsString); // GameMessages::SendUIMessageServerToSingleClient(modelOwner, sysAddr, "UpdateBehaviorID", &args); @@ -63,8 +63,6 @@ void ControlBehaviors::SendBehaviorListToClient(Entity* modelEntity, const Syste AMFArrayValue behaviorsToSerialize; - AMFArrayValue* behaviors = new AMFArrayValue(); // Empty for now - /** * The behaviors AMFArray will have up to 5 elements in the dense portion. * Each element in the dense portion will be made up of another AMFArray @@ -75,20 +73,17 @@ void ControlBehaviors::SendBehaviorListToClient(Entity* modelEntity, const Syste * "name": The name of the behavior formatted as an AMFString */ - behaviorsToSerialize.InsertValue("behaviors", behaviors); + behaviorsToSerialize.Insert("behaviors"); + behaviorsToSerialize.Insert("objectID", std::to_string(modelComponent->GetParent()->GetObjectID())); - AMFStringValue* amfStringValueForObjectID = new AMFStringValue(); - amfStringValueForObjectID->SetStringValue(std::to_string(modelComponent->GetParent()->GetObjectID())); - - behaviorsToSerialize.InsertValue("objectID", amfStringValueForObjectID); - GameMessages::SendUIMessageServerToSingleClient(modelOwner, sysAddr, "UpdateBehaviorList", &behaviorsToSerialize); + GameMessages::SendUIMessageServerToSingleClient(modelOwner, sysAddr, "UpdateBehaviorList", behaviorsToSerialize); } void ControlBehaviors::ModelTypeChanged(AMFArrayValue* arguments, ModelComponent* ModelComponent) { - auto* modelTypeAmf = arguments->FindValue("ModelType"); + auto* modelTypeAmf = arguments->Get("ModelType"); if (!modelTypeAmf) return; - uint32_t modelType = static_cast(modelTypeAmf->GetDoubleValue()); + uint32_t modelType = static_cast(modelTypeAmf->GetValue()); //TODO Update the model type here } @@ -179,7 +174,7 @@ void ControlBehaviors::SendBehaviorBlocksToClient(ModelComponent* modelComponent // AMFArrayValue* state = new AMFArrayValue(); // AMFDoubleValue* stateAsDouble = new AMFDoubleValue(); - // stateAsDouble->SetDoubleValue(it->first); + // stateAsDouble->SetValue(it->first); // state->InsertValue("id", stateAsDouble); // AMFArrayValue* strips = new AMFArrayValue(); @@ -189,16 +184,16 @@ void ControlBehaviors::SendBehaviorBlocksToClient(ModelComponent* modelComponent // AMFArrayValue* thisStrip = new AMFArrayValue(); // AMFDoubleValue* stripID = new AMFDoubleValue(); - // stripID->SetDoubleValue(strip->first); + // stripID->SetValue(strip->first); // thisStrip->InsertValue("id", stripID); // AMFArrayValue* uiArray = new AMFArrayValue(); // AMFDoubleValue* yPosition = new AMFDoubleValue(); - // yPosition->SetDoubleValue(strip->second->GetYPosition()); + // yPosition->SetValue(strip->second->GetYPosition()); // uiArray->InsertValue("y", yPosition); // AMFDoubleValue* xPosition = new AMFDoubleValue(); - // xPosition->SetDoubleValue(strip->second->GetXPosition()); + // xPosition->SetValue(strip->second->GetXPosition()); // uiArray->InsertValue("x", xPosition); // thisStrip->InsertValue("ui", uiArray); @@ -211,19 +206,19 @@ void ControlBehaviors::SendBehaviorBlocksToClient(ModelComponent* modelComponent // AMFArrayValue* thisAction = new AMFArrayValue(); // AMFStringValue* actionName = new AMFStringValue(); - // actionName->SetStringValue(behaviorAction->actionName); + // actionName->SetValue(behaviorAction->actionName); // thisAction->InsertValue("Type", actionName); // if (behaviorAction->parameterValueString != "") // { // AMFStringValue* valueAsString = new AMFStringValue(); - // valueAsString->SetStringValue(behaviorAction->parameterValueString); + // valueAsString->SetValue(behaviorAction->parameterValueString); // thisAction->InsertValue(behaviorAction->parameterName, valueAsString); // } // else if (behaviorAction->parameterValueDouble != 0.0) // { // AMFDoubleValue* valueAsDouble = new AMFDoubleValue(); - // valueAsDouble->SetDoubleValue(behaviorAction->parameterValueDouble); + // valueAsDouble->SetValue(behaviorAction->parameterValueDouble); // thisAction->InsertValue(behaviorAction->parameterName, valueAsDouble); // } // stripSerialize->PushBackValue(thisAction); @@ -237,11 +232,11 @@ void ControlBehaviors::SendBehaviorBlocksToClient(ModelComponent* modelComponent // behaviorInfo.InsertValue("states", stateSerialize); // AMFStringValue* objectidAsString = new AMFStringValue(); - // objectidAsString->SetStringValue(std::to_string(targetObjectID)); + // objectidAsString->SetValue(std::to_string(targetObjectID)); // behaviorInfo.InsertValue("objectID", objectidAsString); // AMFStringValue* behaviorIDAsString = new AMFStringValue(); - // behaviorIDAsString->SetStringValue(std::to_string(behaviorID)); + // behaviorIDAsString->SetValue(std::to_string(behaviorID)); // behaviorInfo.InsertValue("BehaviorID", behaviorIDAsString); // GameMessages::SendUIMessageServerToSingleClient(modelOwner, sysAddr, "UpdateBehaviorBlocks", &behaviorInfo); @@ -275,10 +270,9 @@ void ControlBehaviors::MoveToInventory(ModelComponent* modelComponent, const Sys // This closes the UI menu should it be open while the player is removing behaviors AMFArrayValue args; - AMFFalseValue* stateToPop = new AMFFalseValue(); - args.InsertValue("visible", stateToPop); + args.Insert("visible", false); - GameMessages::SendUIMessageServerToSingleClient(modelOwner, modelOwner->GetParentUser()->GetSystemAddress(), "ToggleBehaviorEditor", &args); + GameMessages::SendUIMessageServerToSingleClient(modelOwner, modelOwner->GetParentUser()->GetSystemAddress(), "ToggleBehaviorEditor", args); MoveToInventoryMessage moveToInventoryMessage(arguments); diff --git a/dGame/dUtilities/BrickDatabase.cpp b/dGame/dUtilities/BrickDatabase.cpp index a6c43d52..e4a6a714 100644 --- a/dGame/dUtilities/BrickDatabase.cpp +++ b/dGame/dUtilities/BrickDatabase.cpp @@ -5,14 +5,12 @@ #include "Game.h" #include "AssetManager.h" #include "tinyxml2.h" +#include "Brick.h" -std::vector BrickDatabase::emptyCache{}; -BrickDatabase* BrickDatabase::m_Address = nullptr; +const BrickList& BrickDatabase::GetBricks(const LxfmlPath& lxfmlPath) { + static std::unordered_map m_Cache; + static const BrickList emptyCache; -BrickDatabase::BrickDatabase() = default; -BrickDatabase::~BrickDatabase() = default; - -std::vector& BrickDatabase::GetBricks(const std::string& lxfmlPath) { const auto cached = m_Cache.find(lxfmlPath); if (cached != m_Cache.end()) { @@ -45,7 +43,7 @@ std::vector& BrickDatabase::GetBricks(const std::string& lxfmlPath) { return emptyCache; } - std::vector parts; + BrickList parts; auto* lxfml = doc->FirstChildElement("LXFML"); auto* bricks = lxfml->FirstChildElement("Bricks"); diff --git a/dGame/dUtilities/BrickDatabase.h b/dGame/dUtilities/BrickDatabase.h index 589d46ae..11c64416 100644 --- a/dGame/dUtilities/BrickDatabase.h +++ b/dGame/dUtilities/BrickDatabase.h @@ -1,29 +1,16 @@ +#ifndef __BRICKDATABASE__H__ +#define __BRICKDATABASE__H__ + #pragma once + #include "Entity.h" -class BrickDatabase -{ -public: - static BrickDatabase* Instance() { - if (m_Address == nullptr) { - m_Address = new BrickDatabase(); - } +class Brick; +using BrickList = std::vector; +using LxfmlPath = std::string; - return m_Address; - } - - std::vector& GetBricks(const std::string& lxfmlPath); - - explicit BrickDatabase(); - - ~BrickDatabase(); - -private: - std::unordered_map> m_Cache; - - static std::vector emptyCache; - - static BrickDatabase* m_Address; //For singleton method - - /* data */ +namespace BrickDatabase { + const BrickList& GetBricks(const LxfmlPath& lxfmlPath); }; + +#endif //!__BRICKDATABASE__H__ diff --git a/dGame/dUtilities/Mail.cpp b/dGame/dUtilities/Mail.cpp index 5dc55765..d33af6dc 100644 --- a/dGame/dUtilities/Mail.cpp +++ b/dGame/dUtilities/Mail.cpp @@ -195,7 +195,7 @@ void Mail::HandleSendMail(RakNet::BitStream* packet, const SystemAddress& sysAdd uint32_t itemID = static_cast(attachmentID); LOT itemLOT = 0; //Inventory::InventoryType itemType; - int mailCost = dZoneManager::Instance()->GetWorldConfig()->mailBaseFee; + int mailCost = Game::zoneManager->GetWorldConfig()->mailBaseFee; int stackSize = 0; auto inv = static_cast(entity->GetComponent(eReplicaComponentType::INVENTORY)); Item* item = nullptr; @@ -203,7 +203,7 @@ void Mail::HandleSendMail(RakNet::BitStream* packet, const SystemAddress& sysAdd if (itemID > 0 && attachmentCount > 0 && inv) { item = inv->FindItemById(attachmentID); if (item) { - mailCost += (item->GetInfo().baseValue * dZoneManager::Instance()->GetWorldConfig()->mailPercentAttachmentFee); + mailCost += (item->GetInfo().baseValue * Game::zoneManager->GetWorldConfig()->mailPercentAttachmentFee); stackSize = item->GetCount(); itemLOT = item->GetLot(); } else { diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index 07950d7a..03e3cc89 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -69,7 +69,7 @@ #include "BinaryPathFinder.h" #include "dConfig.h" #include "eBubbleType.h" -#include "AMFFormat.h" +#include "Amf3.h" #include "MovingPlatformComponent.h" #include "eMissionState.h" #include "TriggerComponent.h" @@ -77,6 +77,7 @@ #include "eObjectBits.h" #include "eGameMasterLevel.h" #include "eReplicaComponentType.h" +#include "RenderComponent.h" #include "eControlScheme.h" #include "eConnectionType.h" #include "eChatInternalMessageType.h" @@ -183,7 +184,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } character->SetPvpEnabled(!character->GetPvpEnabled()); - EntityManager::Instance()->SerializeEntity(entity); + Game::entityManager->SerializeEntity(entity); std::stringstream message; message << character->GetName() << " changed their PVP flag to " << std::to_string(character->GetPvpEnabled()) << "!"; @@ -251,35 +252,29 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit { AMFArrayValue args; - auto* state = new AMFStringValue(); - state->SetStringValue("Story"); + args.Insert("state", "Story"); - args.InsertValue("state", state); - - GameMessages::SendUIMessageServerToSingleClient(entity, entity->GetSystemAddress(), "pushGameState", &args); + GameMessages::SendUIMessageServerToSingleClient(entity, entity->GetSystemAddress(), "pushGameState", args); } entity->AddCallbackTimer(0.5f, [customText, entity]() { AMFArrayValue args; - auto* text = new AMFStringValue(); - text->SetStringValue(customText); - - args.InsertValue("visible", new AMFTrueValue()); - args.InsertValue("text", text); + args.Insert("visible", true); + args.Insert("text", customText); Game::logger->Log("SlashCommandHandler", "Sending %s", customText.c_str()); - GameMessages::SendUIMessageServerToSingleClient(entity, entity->GetSystemAddress(), "ToggleStoryBox", &args); + GameMessages::SendUIMessageServerToSingleClient(entity, entity->GetSystemAddress(), "ToggleStoryBox", args); }); return; } if (chatCommand == "leave-zone") { - const auto currentZone = dZoneManager::Instance()->GetZone()->GetZoneID().GetMapID(); + const auto currentZone = Game::zoneManager->GetZone()->GetZoneID().GetMapID(); - auto newZone = 0; + LWOMAPID newZone = 0; if (currentZone % 100 == 0) { ChatPackets::SendSystemMessage(sysAddr, u"You are not in an instanced zone."); return; @@ -287,14 +282,14 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit newZone = (currentZone / 100) * 100; } // If new zone would be inaccessible, then default to Avant Gardens. - if (!CheckIfAccessibleZone(newZone)) newZone = 1100; + if (!Game::zoneManager->CheckIfAccessibleZone(newZone)) newZone = 1100; ChatPackets::SendSystemMessage(sysAddr, u"Leaving zone..."); const auto objid = entity->GetObjectID(); ZoneInstanceManager::Instance()->RequestZoneTransfer(Game::server, newZone, 0, false, [objid](bool mythranShift, uint32_t zoneID, uint32_t zoneInstance, uint32_t zoneClone, std::string serverIP, uint16_t serverPort) { - auto* entity = EntityManager::Instance()->GetEntity(objid); + auto* entity = Game::entityManager->GetEntity(objid); if (entity == nullptr) { return; @@ -341,7 +336,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } if (chatCommand == "resurrect") { - ScriptedActivityComponent* scriptedActivityComponent = dZoneManager::Instance()->GetZoneControlObject()->GetComponent(); + ScriptedActivityComponent* scriptedActivityComponent = Game::zoneManager->GetZoneControlObject()->GetComponent(); if (scriptedActivityComponent) { // check if user is in activity world and if so, they can't resurrect ChatPackets::SendSystemMessage(sysAddr, u"You cannot resurrect in an activity world."); @@ -356,7 +351,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } if (chatCommand == "instanceinfo") { - const auto zoneId = dZoneManager::Instance()->GetZone()->GetZoneID(); + const auto zoneId = Game::zoneManager->GetZone()->GetZoneID(); ChatPackets::SendSystemMessage(sysAddr, u"Map: " + (GeneralUtils::to_u16string(zoneId.GetMapID())) + u"\nClone: " + (GeneralUtils::to_u16string(zoneId.GetCloneID())) + u"\nInstance: " + (GeneralUtils::to_u16string(zoneId.GetInstanceID()))); } @@ -377,7 +372,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit ChatPackets::SendSystemMessage(sysAddr, u"Invalid Minifig Item Id ID."); return; } - EntityManager::Instance()->DestructEntity(entity, sysAddr); + Game::entityManager->DestructEntity(entity, sysAddr); auto* charComp = entity->GetComponent(); std::string lowerName = args[0]; if (lowerName.empty()) return; @@ -404,12 +399,12 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit charComp->m_Character->SetLeftHand(minifigItemId); charComp->m_Character->SetRightHand(minifigItemId); } else { - EntityManager::Instance()->ConstructEntity(entity); + Game::entityManager->ConstructEntity(entity); ChatPackets::SendSystemMessage(sysAddr, u"Invalid Minifig item to change, try one of the following: Eyebrows, Eyes, HairColor, HairStyle, Pants, LeftHand, Mouth, RightHand, Shirt, Hands"); return; } - EntityManager::Instance()->ConstructEntity(entity); + Game::entityManager->ConstructEntity(entity); ChatPackets::SendSystemMessage(sysAddr, GeneralUtils::ASCIIToUTF16(lowerName) + u" set to " + (GeneralUtils::to_u16string(minifigItemId))); GameMessages::SendToggleGMInvis(entity->GetObjectID(), false, UNASSIGNED_SYSTEM_ADDRESS); // need to retoggle because it gets reenabled on creation of new character @@ -417,16 +412,16 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if ((chatCommand == "playanimation" || chatCommand == "playanim") && args.size() == 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { std::u16string anim = GeneralUtils::ASCIIToUTF16(args[0], args[0].size()); - GameMessages::SendPlayAnimation(entity, anim); + RenderComponent::PlayAnimation(entity, anim); auto* possessorComponent = entity->GetComponent(); if (possessorComponent) { - auto* possessedComponent = EntityManager::Instance()->GetEntity(possessorComponent->GetPossessable()); - if (possessedComponent) GameMessages::SendPlayAnimation(possessedComponent, anim); + auto* possessedComponent = Game::entityManager->GetEntity(possessorComponent->GetPossessable()); + if (possessedComponent) RenderComponent::PlayAnimation(possessedComponent, anim); } } if (chatCommand == "list-spawns" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { - for (const auto& pair : EntityManager::Instance()->GetSpawnPointEntities()) { + for (const auto& pair : Game::entityManager->GetSpawnPointEntities()) { ChatPackets::SendSystemMessage(sysAddr, GeneralUtils::ASCIIToUTF16(pair.first)); } @@ -455,7 +450,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit auto* user = UserManager::Instance()->GetUser(args[0]); if (user) { - auto* player = EntityManager::Instance()->GetEntity(user->GetLoggedInChar()); + auto* player = Game::entityManager->GetEntity(user->GetLoggedInChar()); player->Smash(entity->GetObjectID()); ChatPackets::SendSystemMessage(sysAddr, u"It has been done, do you feel good about yourself now?"); return; @@ -483,7 +478,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if (possessor) { auto possessedID = possessor->GetPossessable(); if (possessedID != LWOOBJID_EMPTY) { - auto possessable = EntityManager::Instance()->GetEntity(possessedID); + auto possessable = Game::entityManager->GetEntity(possessedID); if (possessable) { auto* possessControllablePhysicsComponent = possessable->GetComponent(); if (possessControllablePhysicsComponent) { @@ -493,7 +488,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } } - EntityManager::Instance()->SerializeEntity(entity); + Game::entityManager->SerializeEntity(entity); } if (chatCommand == "freecam" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { @@ -530,12 +525,11 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } if (chatCommand == "setuistate" && args.size() == 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { - AMFStringValue* value = new AMFStringValue(); - value->SetStringValue(args[0]); + AMFArrayValue uiState; - AMFArrayValue args; - args.InsertValue("state", value); - GameMessages::SendUIMessageServerToSingleClient(entity, sysAddr, "pushGameState", &args); + uiState.Insert("state", args.at(0)); + + GameMessages::SendUIMessageServerToSingleClient(entity, sysAddr, "pushGameState", uiState); ChatPackets::SendSystemMessage(sysAddr, u"Switched UI state."); @@ -543,11 +537,11 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } if (chatCommand == "toggle" && args.size() == 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { - AMFTrueValue* value = new AMFTrueValue(); - AMFArrayValue amfArgs; - amfArgs.InsertValue("visible", value); - GameMessages::SendUIMessageServerToSingleClient(entity, sysAddr, args[0], &amfArgs); + + amfArgs.Insert("visible", true); + + GameMessages::SendUIMessageServerToSingleClient(entity, sysAddr, args[0], amfArgs); ChatPackets::SendSystemMessage(sysAddr, u"Toggled UI state."); @@ -943,13 +937,13 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit auto* possessorComponent = entity->GetComponent(); if (possessorComponent) { - auto* possassableEntity = EntityManager::Instance()->GetEntity(possessorComponent->GetPossessable()); + auto* possassableEntity = Game::entityManager->GetEntity(possessorComponent->GetPossessable()); if (possassableEntity != nullptr) { auto* vehiclePhysicsComponent = possassableEntity->GetComponent(); if (vehiclePhysicsComponent) { vehiclePhysicsComponent->SetPosition(pos); - EntityManager::Instance()->SerializeEntity(possassableEntity); + Game::entityManager->SerializeEntity(possassableEntity); } else GameMessages::SendTeleport(possassableEntity->GetObjectID(), pos, NiQuaternion(), sysAddr); } } @@ -958,7 +952,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if (chatCommand == "tpall" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { const auto pos = entity->GetPosition(); - const auto characters = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::CHARACTER); + const auto characters = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::CHARACTER); for (auto* character : characters) { GameMessages::SendTeleport(character->GetObjectID(), pos, NiQuaternion(), character->GetSystemAddress()); @@ -972,7 +966,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if (possessorComponent) { auto possessableId = possessorComponent->GetPossessable(); if (possessableId != LWOOBJID_EMPTY) { - auto* possessableEntity = EntityManager::Instance()->GetEntity(possessableId); + auto* possessableEntity = Game::entityManager->GetEntity(possessableId); if (possessableEntity) possessorComponent->Dismount(possessableEntity, true); } } @@ -1186,7 +1180,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit dest->SetImagination(999); dest->SetMaxImagination(999.0f); } - EntityManager::Instance()->SerializeEntity(entity); + Game::entityManager->SerializeEntity(entity); } if (chatCommand == "startcelebration" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() == 1) { @@ -1210,7 +1204,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit dest->SetImagination(9); dest->SetMaxImagination(9.0f); } - EntityManager::Instance()->SerializeEntity(entity); + Game::entityManager->SerializeEntity(entity); } if (chatCommand == "refillstats" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { @@ -1222,7 +1216,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit dest->SetImagination((int)dest->GetMaxImagination()); } - EntityManager::Instance()->SerializeEntity(entity); + Game::entityManager->SerializeEntity(entity); } if (chatCommand == "lookup" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 1) { @@ -1266,26 +1260,14 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit info.spawnerID = entity->GetObjectID(); info.spawnerNodeID = 0; - Entity* newEntity = EntityManager::Instance()->CreateEntity(info, nullptr); + Entity* newEntity = Game::entityManager->CreateEntity(info, nullptr); if (newEntity == nullptr) { ChatPackets::SendSystemMessage(sysAddr, u"Failed to spawn entity."); return; } - auto vehiclePhysicsComponent = newEntity->GetComponent(); - if (vehiclePhysicsComponent) { - auto newRot = newEntity->GetRotation(); - auto angles = newRot.GetEulerAngles(); - // make it right side up - angles.x -= PI; - // make it going in the direction of the player - angles.y -= PI; - newRot = NiQuaternion::FromEulerAngles(angles); - newEntity->SetRotation(newRot); - } - - EntityManager::Instance()->ConstructEntity(newEntity); + Game::entityManager->ConstructEntity(newEntity); } if (chatCommand == "spawngroup" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 3) { @@ -1328,13 +1310,13 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit info.pos = playerPosition + NiPoint3(cos(randomAngle) * randomRadius, 0.0f, sin(randomAngle) * randomRadius); info.rot = NiQuaternion(); - auto newEntity = EntityManager::Instance()->CreateEntity(info); + auto newEntity = Game::entityManager->CreateEntity(info); if (newEntity == nullptr) { ChatPackets::SendSystemMessage(sysAddr, u"Failed to spawn entity."); return; } - EntityManager::Instance()->ConstructEntity(newEntity); + Game::entityManager->ConstructEntity(newEntity); numberToSpawn--; } } @@ -1461,7 +1443,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } if ((chatCommand == "freemoney" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) && args.size() == 1) { - int32_t money; + int64_t money; if (!GeneralUtils::TryParse(args[0], money)) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid money."); @@ -1559,11 +1541,11 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit const auto objid = entity->GetObjectID(); - if (force || CheckIfAccessibleZone(reqZone)) { // to prevent tomfoolery + if (force || Game::zoneManager->CheckIfAccessibleZone(reqZone)) { // to prevent tomfoolery ZoneInstanceManager::Instance()->RequestZoneTransfer(Game::server, reqZone, cloneId, false, [objid](bool mythranShift, uint32_t zoneID, uint32_t zoneInstance, uint32_t zoneClone, std::string serverIP, uint16_t serverPort) { - auto* entity = EntityManager::Instance()->GetEntity(objid); + auto* entity = Game::entityManager->GetEntity(objid); if (!entity) return; const auto sysAddr = entity->GetSystemAddress(); @@ -1617,7 +1599,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if ((chatCommand == "debugui") && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { ChatPackets::SendSystemMessage(sysAddr, u"Opening UIDebugger..."); AMFArrayValue args; - GameMessages::SendUIMessageServerToSingleClient(entity, sysAddr, "ToggleUIDebugger;", nullptr); + GameMessages::SendUIMessageServerToSingleClient(entity, sysAddr, "ToggleUIDebugger;", args); } if ((chatCommand == "boost") && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { @@ -1627,7 +1609,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - auto* vehicle = EntityManager::Instance()->GetEntity(possessorComponent->GetPossessable()); + auto* vehicle = Game::entityManager->GetEntity(possessorComponent->GetPossessable()); if (vehicle == nullptr) { return; @@ -1656,20 +1638,20 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit auto* possessorComponent = entity->GetComponent(); if (possessorComponent == nullptr) return; - auto* vehicle = EntityManager::Instance()->GetEntity(possessorComponent->GetPossessable()); + auto* vehicle = Game::entityManager->GetEntity(possessorComponent->GetPossessable()); if (vehicle == nullptr) return; GameMessages::SendVehicleRemovePassiveBoostAction(vehicle->GetObjectID(), UNASSIGNED_SYSTEM_ADDRESS); } if (chatCommand == "activatespawner" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 1) { - auto spawners = dZoneManager::Instance()->GetSpawnersByName(args[0]); + auto spawners = Game::zoneManager->GetSpawnersByName(args[0]); for (auto* spawner : spawners) { spawner->Activate(); } - spawners = dZoneManager::Instance()->GetSpawnersInGroup(args[0]); + spawners = Game::zoneManager->GetSpawnersInGroup(args[0]); for (auto* spawner : spawners) { spawner->Activate(); @@ -1678,7 +1660,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if (chatCommand == "spawnphysicsverts" && entity->GetGMLevel() >= eGameMasterLevel::JUNIOR_DEVELOPER) { //Go tell physics to spawn all the vertices: - auto entities = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::PHANTOM_PHYSICS); + auto entities = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::PHANTOM_PHYSICS); for (auto en : entities) { auto phys = static_cast(en->GetComponent(eReplicaComponentType::PHANTOM_PHYSICS)); if (phys) @@ -1687,7 +1669,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } if (chatCommand == "reportproxphys" && entity->GetGMLevel() >= eGameMasterLevel::JUNIOR_DEVELOPER) { - auto entities = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::PROXIMITY_MONITOR); + auto entities = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::PROXIMITY_MONITOR); for (auto en : entities) { auto phys = static_cast(en->GetComponent(eReplicaComponentType::PROXIMITY_MONITOR)); if (phys) { @@ -1703,13 +1685,13 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } if (chatCommand == "triggerspawner" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 1) { - auto spawners = dZoneManager::Instance()->GetSpawnersByName(args[0]); + auto spawners = Game::zoneManager->GetSpawnersByName(args[0]); for (auto* spawner : spawners) { spawner->Spawn(); } - spawners = dZoneManager::Instance()->GetSpawnersInGroup(args[0]); + spawners = Game::zoneManager->GetSpawnersInGroup(args[0]); for (auto* spawner : spawners) { spawner->Spawn(); @@ -1783,7 +1765,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit Game::config->ReloadConfig(); VanityUtilities::SpawnVanity(); dpWorld::Instance().Reload(); - auto entities = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::SCRIPTED_ACTIVITY); + auto entities = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SCRIPTED_ACTIVITY); for (auto entity : entities) { auto* scriptedActivityComponent = entity->GetComponent(); if (!scriptedActivityComponent) continue; @@ -1880,7 +1862,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit auto closestDistance = 0.0f; - const auto candidates = EntityManager::Instance()->GetEntitiesByComponent(component); + const auto candidates = Game::entityManager->GetEntitiesByComponent(component); for (auto* candidate : candidates) { if (candidate->GetLOT() == 1 || candidate->GetLOT() == 8092) { @@ -1912,7 +1894,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - EntityManager::Instance()->SerializeEntity(closest); + Game::entityManager->SerializeEntity(closest); auto* table = CDClientManager::Instance().GetTable(); @@ -1952,9 +1934,9 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit movingPlatformComponent->GotoWaypoint(value); } - EntityManager::Instance()->SerializeEntity(closest); + Game::entityManager->SerializeEntity(closest); } else if (args[1] == "-a" && args.size() >= 3) { - GameMessages::SendPlayAnimation(closest, GeneralUtils::UTF8ToUTF16(args[2])); + RenderComponent::PlayAnimation(closest, args.at(2)); } else if (args[1] == "-s") { for (auto* entry : closest->GetSettings()) { ChatPackets::SendSystemMessage(sysAddr, GeneralUtils::UTF8ToUTF16(entry->GetString())); @@ -2021,28 +2003,13 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } } -bool SlashCommandHandler::CheckIfAccessibleZone(const unsigned int zoneID) { - //We're gonna go ahead and presume we've got the db loaded already: - CDZoneTableTable* zoneTable = CDClientManager::Instance().GetTable(); - const CDZoneTable* zone = zoneTable->Query(zoneID); - if (zone != nullptr) { - return Game::assetManager->HasFile(("maps/" + zone->zoneName).c_str()); - } else { - return false; - } -} - void SlashCommandHandler::SendAnnouncement(const std::string& title, const std::string& message) { AMFArrayValue args; - auto* titleValue = new AMFStringValue(); - titleValue->SetStringValue(title); - auto* messageValue = new AMFStringValue(); - messageValue->SetStringValue(message); - args.InsertValue("title", titleValue); - args.InsertValue("message", messageValue); + args.Insert("title", title); + args.Insert("message", message); - GameMessages::SendUIMessageServerToAllClients("ToggleAnnounce", &args); + GameMessages::SendUIMessageServerToAllClients("ToggleAnnounce", args); //Notify chat about it CBITSTREAM; diff --git a/dGame/dUtilities/SlashCommandHandler.h b/dGame/dUtilities/SlashCommandHandler.h index 9ef09a2f..85b7c697 100644 --- a/dGame/dUtilities/SlashCommandHandler.h +++ b/dGame/dUtilities/SlashCommandHandler.h @@ -13,8 +13,6 @@ class Entity; namespace SlashCommandHandler { void HandleChatCommand(const std::u16string& command, Entity* entity, const SystemAddress& sysAddr); - bool CheckIfAccessibleZone(const unsigned int zoneID); - void SendAnnouncement(const std::string& title, const std::string& message); }; diff --git a/dGame/dUtilities/VanityUtilities.cpp b/dGame/dUtilities/VanityUtilities.cpp index 7fabfbce..86fa9503 100644 --- a/dGame/dUtilities/VanityUtilities.cpp +++ b/dGame/dUtilities/VanityUtilities.cpp @@ -119,7 +119,7 @@ void VanityUtilities::SpawnVanity() { auto* scriptComponent = npcEntity->GetComponent(); - if (scriptComponent != nullptr) { + if (scriptComponent && !npc.m_Script.empty()) { scriptComponent->SetScript(npc.m_Script); scriptComponent->SetSerialized(false); @@ -137,14 +137,14 @@ void VanityUtilities::SpawnVanity() { info.lot = 8139; info.pos = { 259.5f, 246.4f, -705.2f }; info.rot = { 0.0f, 0.0f, 1.0f, 0.0f }; - info.spawnerID = EntityManager::Instance()->GetZoneControlEntity()->GetObjectID(); + info.spawnerID = Game::entityManager->GetZoneControlEntity()->GetObjectID(); info.settings = { new LDFData(u"hasCustomText", true), new LDFData(u"customText", ParseMarkdown((BinaryPathFinder::GetBinaryDir() / "vanity/TESTAMENT.md").string())) }; - auto* entity = EntityManager::Instance()->CreateEntity(info); + auto* entity = Game::entityManager->CreateEntity(info); - EntityManager::Instance()->ConstructEntity(entity); + Game::entityManager->ConstructEntity(entity); } } } @@ -155,15 +155,15 @@ Entity* VanityUtilities::SpawnNPC(LOT lot, const std::string& name, const NiPoin info.lot = lot; info.pos = position; info.rot = rotation; - info.spawnerID = EntityManager::Instance()->GetZoneControlEntity()->GetObjectID(); + info.spawnerID = Game::entityManager->GetZoneControlEntity()->GetObjectID(); info.settings = ldf; - auto* entity = EntityManager::Instance()->CreateEntity(info); + auto* entity = Game::entityManager->CreateEntity(info); entity->SetVar(u"npcName", name); auto* inventoryComponent = entity->GetComponent(); - if (inventoryComponent != nullptr) { + if (inventoryComponent && !inventory.empty()) { inventoryComponent->SetNPCItems(inventory); } @@ -175,7 +175,7 @@ Entity* VanityUtilities::SpawnNPC(LOT lot, const std::string& name, const NiPoin destroyableComponent->SetHealth(0); } - EntityManager::Instance()->ConstructEntity(entity); + Game::entityManager->ConstructEntity(entity); return entity; } @@ -535,7 +535,7 @@ void VanityUtilities::NPCTalk(Entity* npc) { npc->GetObjectID(), u"sendToclient_bubble", 0, 0, npc->GetObjectID(), selected, UNASSIGNED_SYSTEM_ADDRESS); } - EntityManager::Instance()->SerializeEntity(npc); + Game::entityManager->SerializeEntity(npc); const float nextTime = GeneralUtils::GenerateRandomNumber(15, 60); diff --git a/dMasterServer/MasterServer.cpp b/dMasterServer/MasterServer.cpp index 4b524d8d..ce237eac 100644 --- a/dMasterServer/MasterServer.cpp +++ b/dMasterServer/MasterServer.cpp @@ -50,6 +50,7 @@ namespace Game { dConfig* config = nullptr; AssetManager* assetManager = nullptr; bool shouldShutdown = false; + std::mt19937 randomEngine; } //namespace Game bool shutdownSequenceStarted = false; @@ -291,6 +292,7 @@ int main(int argc, char** argv) { return EXIT_SUCCESS; } + Game::randomEngine = std::mt19937(time(0)); uint32_t maxClients = 999; uint32_t ourPort = 1000; if (Game::config->GetValue("max_clients") != "") maxClients = std::stoi(Game::config->GetValue("max_clients")); @@ -335,7 +337,6 @@ int main(int argc, char** argv) { Game::im->GetInstance(0, false, 0); Game::im->GetInstance(1000, false, 0); - StartAuthServer(); } @@ -495,6 +496,8 @@ void HandlePacket(Packet* packet) { } } + if (packet->length < 4) return; + if (static_cast(packet->data[1]) == eConnectionType::MASTER) { switch (static_cast(packet->data[3])) { case eMasterMessageType::REQUEST_PERSISTENT_ID: { diff --git a/dNavigation/dTerrain/RawFile.h b/dNavigation/dTerrain/RawFile.h index 84afae94..2a702c53 100644 --- a/dNavigation/dTerrain/RawFile.h +++ b/dNavigation/dTerrain/RawFile.h @@ -2,6 +2,7 @@ #include #include +#include class RawChunk; struct RawMesh; diff --git a/dNet/AuthPackets.cpp b/dNet/AuthPackets.cpp index 4bbb0576..978540c1 100644 --- a/dNet/AuthPackets.cpp +++ b/dNet/AuthPackets.cpp @@ -8,6 +8,7 @@ #include "ZoneInstanceManager.h" #include "MD5.h" #include "SHA512.h" +#include "GeneralUtils.h" #ifdef _WIN32 #include @@ -211,7 +212,7 @@ void AuthPackets::SendLoginResponse(dServer* server, const SystemAddress& sysAdd packet.Write(static_cast(64)); // Version Minor // Writes the user key - uint32_t sessionKey = rand(); // not mt but whatever + uint32_t sessionKey = GeneralUtils::GenerateRandomNumber(); std::string userHash = std::to_string(sessionKey); userHash = md5(userHash); PacketUtils::WritePacketWString(userHash, 33, &packet); diff --git a/dNet/ClientPackets.cpp b/dNet/ClientPackets.cpp index 4ccbb609..8bebda93 100644 --- a/dNet/ClientPackets.cpp +++ b/dNet/ClientPackets.cpp @@ -46,9 +46,7 @@ void ClientPackets::HandleChatMessage(const SystemAddress& sysAddr, Packet* pack return; } - CINSTREAM; - uint64_t header; - inStream.Read(header); + CINSTREAM_SKIP_HEADER; char chatChannel; uint16_t unknown; @@ -82,11 +80,9 @@ void ClientPackets::HandleClientPositionUpdate(const SystemAddress& sysAddr, Pac return; } - CINSTREAM; - uint64_t header; - inStream.Read(header); + CINSTREAM_SKIP_HEADER; - Entity* entity = EntityManager::Instance()->GetEntity(user->GetLastUsedChar()->GetObjectID()); + Entity* entity = Game::entityManager->GetEntity(user->GetLastUsedChar()->GetObjectID()); if (!entity) return; ControllablePhysicsComponent* comp = static_cast(entity->GetComponent(eReplicaComponentType::CONTROLLABLE_PHYSICS)); @@ -99,7 +95,7 @@ void ClientPackets::HandleClientPositionUpdate(const SystemAddress& sysAddr, Pac comp->SetVelocity(zeroVel); comp->SetAngularVelocity(zeroVel); comp->SetIsOnGround(true); //probably8 - EntityManager::Instance()->SerializeEntity(entity); + Game::entityManager->SerializeEntity(entity); return; } */ @@ -140,10 +136,37 @@ void ClientPackets::HandleClientPositionUpdate(const SystemAddress& sysAddr, Pac inStream.Read(angVelocity.z); } + // TODO figure out how to use these. Ignoring for now, but reading in if they exist. + bool hasLocalSpaceInfo{}; + LWOOBJID objectId{}; + NiPoint3 localSpacePosition{}; + bool hasLinearVelocity{}; + NiPoint3 linearVelocity{}; + if (inStream.Read(hasLocalSpaceInfo) && hasLocalSpaceInfo) { + inStream.Read(objectId); + inStream.Read(localSpacePosition.x); + inStream.Read(localSpacePosition.y); + inStream.Read(localSpacePosition.z); + if (inStream.Read(hasLinearVelocity) && hasLinearVelocity) { + inStream.Read(linearVelocity.x); + inStream.Read(linearVelocity.y); + inStream.Read(linearVelocity.z); + } + } + bool hasRemoteInputInfo{}; + RemoteInputInfo remoteInput{}; + + if (inStream.Read(hasRemoteInputInfo) && hasRemoteInputInfo) { + inStream.Read(remoteInput.m_RemoteInputX); + inStream.Read(remoteInput.m_RemoteInputY); + inStream.Read(remoteInput.m_IsPowersliding); + inStream.Read(remoteInput.m_IsModified); + } + bool updateChar = true; if (possessorComponent != nullptr) { - auto* possassableEntity = EntityManager::Instance()->GetEntity(possessorComponent->GetPossessable()); + auto* possassableEntity = Game::entityManager->GetEntity(possessorComponent->GetPossessable()); if (possassableEntity != nullptr) { auto* possessableComponent = possassableEntity->GetComponent(); @@ -154,9 +177,6 @@ void ClientPackets::HandleClientPositionUpdate(const SystemAddress& sysAddr, Pac auto* vehiclePhysicsComponent = possassableEntity->GetComponent(); if (vehiclePhysicsComponent != nullptr) { - // This is flipped for whatever reason - rotation = NiQuaternion(rotation.z, rotation.y, rotation.x, rotation.w); - vehiclePhysicsComponent->SetPosition(position); vehiclePhysicsComponent->SetRotation(rotation); vehiclePhysicsComponent->SetIsOnGround(onGround); @@ -165,6 +185,7 @@ void ClientPackets::HandleClientPositionUpdate(const SystemAddress& sysAddr, Pac vehiclePhysicsComponent->SetDirtyVelocity(velocityFlag); vehiclePhysicsComponent->SetAngularVelocity(angVelocity); vehiclePhysicsComponent->SetDirtyAngularVelocity(angVelocityFlag); + vehiclePhysicsComponent->SetRemoteInputInfo(remoteInput); } else { // Need to get the mount's controllable physics auto* controllablePhysicsComponent = possassableEntity->GetComponent(); @@ -178,7 +199,7 @@ void ClientPackets::HandleClientPositionUpdate(const SystemAddress& sysAddr, Pac controllablePhysicsComponent->SetAngularVelocity(angVelocity); controllablePhysicsComponent->SetDirtyAngularVelocity(angVelocityFlag); } - EntityManager::Instance()->SerializeEntity(possassableEntity); + Game::entityManager->SerializeEntity(possassableEntity); } } @@ -206,9 +227,9 @@ void ClientPackets::HandleClientPositionUpdate(const SystemAddress& sysAddr, Pac auto* player = static_cast(entity); player->SetGhostReferencePoint(position); - EntityManager::Instance()->QueueGhostUpdate(player->GetObjectID()); + Game::entityManager->QueueGhostUpdate(player->GetObjectID()); - if (updateChar) EntityManager::Instance()->SerializeEntity(entity); + if (updateChar) Game::entityManager->SerializeEntity(entity); //TODO: add moving platform stuffs /*bool movingPlatformFlag; @@ -246,7 +267,7 @@ void ClientPackets::HandleClientPositionUpdate(const SystemAddress& sysAddr, Pac continue; } - EntityManager::Instance()->SerializeEntity(entity, player); + Game::entityManager->SerializeEntity(entity, player); } */ } diff --git a/dNet/PacketUtils.h b/dNet/PacketUtils.h index 7c917f2e..d07759a0 100644 --- a/dNet/PacketUtils.h +++ b/dNet/PacketUtils.h @@ -10,10 +10,10 @@ enum class eConnectionType : uint16_t; namespace PacketUtils { template void WriteHeader(RakNet::BitStream& bitStream, eConnectionType connectionType, T internalPacketID) { - bitStream.Write(MessageID(ID_USER_PACKET_ENUM)); - bitStream.Write(connectionType); - bitStream.Write(internalPacketID); - bitStream.Write(uint8_t(0)); + bitStream.Write(MessageID(ID_USER_PACKET_ENUM)); + bitStream.Write(connectionType); + bitStream.Write(static_cast(internalPacketID)); + bitStream.Write(0); } uint16_t ReadPacketU16(uint32_t startLoc, Packet* packet); diff --git a/dNet/WorldPackets.cpp b/dNet/WorldPackets.cpp index 5fce14d3..35c985eb 100644 --- a/dNet/WorldPackets.cpp +++ b/dNet/WorldPackets.cpp @@ -19,7 +19,7 @@ void WorldPackets::SendLoadStaticZone(const SystemAddress& sysAddr, float x, flo RakNet::BitStream bitStream; PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::LOAD_STATIC_ZONE); - auto zone = dZoneManager::Instance()->GetZone()->GetZoneID(); + auto zone = Game::zoneManager->GetZone()->GetZoneID(); bitStream.Write(static_cast(zone.GetMapID())); bitStream.Write(static_cast(zone.GetInstanceID())); //bitStream.Write(static_cast(zone.GetCloneID())); diff --git a/dPhysics/dpGrid.cpp b/dPhysics/dpGrid.cpp index b4fe385e..c3259b51 100644 --- a/dPhysics/dpGrid.cpp +++ b/dPhysics/dpGrid.cpp @@ -43,8 +43,8 @@ void dpGrid::Add(dpEntity* entity) { if (cellX < 0) cellX = 0; if (cellZ < 0) cellZ = 0; - if (cellX > NUM_CELLS) cellX = NUM_CELLS; - if (cellZ > NUM_CELLS) cellZ = NUM_CELLS; + if (cellX >= NUM_CELLS) cellX = NUM_CELLS - 1; + if (cellZ >= NUM_CELLS) cellZ = NUM_CELLS - 1; //Add to cell: m_Cells[cellX][cellZ].push_front(entity); @@ -63,13 +63,13 @@ void dpGrid::Move(dpEntity* entity, float x, float z) { if (cellX < 0) cellX = 0; if (cellZ < 0) cellZ = 0; - if (cellX > NUM_CELLS) cellX = NUM_CELLS; - if (cellZ > NUM_CELLS) cellZ = NUM_CELLS; + if (cellX >= NUM_CELLS) cellX = NUM_CELLS - 1; + if (cellZ >= NUM_CELLS) cellZ = NUM_CELLS - 1; if (oldCellX < 0) oldCellX = 0; if (oldCellZ < 0) oldCellZ = 0; - if (oldCellX > NUM_CELLS) oldCellX = NUM_CELLS; - if (oldCellZ > NUM_CELLS) oldCellZ = NUM_CELLS; + if (oldCellX >= NUM_CELLS) oldCellX = NUM_CELLS - 1; + if (oldCellZ >= NUM_CELLS) oldCellZ = NUM_CELLS - 1; if (oldCellX == cellX && oldCellZ == cellZ) return; @@ -87,8 +87,8 @@ void dpGrid::Delete(dpEntity* entity) { if (oldCellX < 0) oldCellX = 0; if (oldCellZ < 0) oldCellZ = 0; - if (oldCellX > NUM_CELLS) oldCellX = NUM_CELLS; - if (oldCellZ > NUM_CELLS) oldCellZ = NUM_CELLS; + if (oldCellX >= NUM_CELLS) oldCellX = NUM_CELLS - 1; + if (oldCellZ >= NUM_CELLS) oldCellZ = NUM_CELLS - 1; m_Cells[oldCellX][oldCellZ].remove(entity); diff --git a/dScripts/02_server/DLU/DLUVanityNPC.cpp b/dScripts/02_server/DLU/DLUVanityNPC.cpp index e3db2353..ba2c6604 100644 --- a/dScripts/02_server/DLU/DLUVanityNPC.cpp +++ b/dScripts/02_server/DLU/DLUVanityNPC.cpp @@ -2,6 +2,7 @@ #include "GameMessages.h" #include "dServer.h" #include "VanityUtilities.h" +#include "RenderComponent.h" void DLUVanityNPC::OnStartup(Entity* self) { m_NPC = VanityUtilities::GetNPC("averysumner - Destroyer of Worlds"); @@ -17,7 +18,7 @@ void DLUVanityNPC::OnStartup(Entity* self) { void DLUVanityNPC::OnTimerDone(Entity* self, std::string timerName) { if (timerName == "setupTeleport") { - GameMessages::SendPlayAnimation(self, u"interact"); + RenderComponent::PlayAnimation(self, u"interact"); GameMessages::SendPlayFXEffect(self->GetObjectID(), 6478, u"teleportBeam", "teleportBeam"); GameMessages::SendPlayFXEffect(self->GetObjectID(), 6478, u"teleportRings", "teleportRings"); diff --git a/dScripts/02_server/Enemy/AG/BossSpiderQueenEnemyServer.cpp b/dScripts/02_server/Enemy/AG/BossSpiderQueenEnemyServer.cpp index a3b9cc3f..8d092078 100644 --- a/dScripts/02_server/Enemy/AG/BossSpiderQueenEnemyServer.cpp +++ b/dScripts/02_server/Enemy/AG/BossSpiderQueenEnemyServer.cpp @@ -14,6 +14,7 @@ #include "GameMessages.h" #include "SkillComponent.h" #include "eReplicaComponentType.h" +#include "RenderComponent.h" #include @@ -51,7 +52,7 @@ void BossSpiderQueenEnemyServer::OnStartup(Entity* self) { } void BossSpiderQueenEnemyServer::OnDie(Entity* self, Entity* killer) { - if (dZoneManager::Instance()->GetZoneID().GetMapID() == instanceZoneID) { + if (Game::zoneManager->GetZoneID().GetMapID() == instanceZoneID) { auto* missionComponent = killer->GetComponent(); if (missionComponent == nullptr) return; @@ -60,13 +61,13 @@ void BossSpiderQueenEnemyServer::OnDie(Entity* self, Entity* killer) { } // There is suppose to be a 0.1 second delay here but that may be admitted? - auto* controller = EntityManager::Instance()->GetZoneControlEntity(); + auto* controller = Game::entityManager->GetZoneControlEntity(); GameMessages::SendNotifyClientObject(self->GetObjectID(), u"SetColGroup", 10, 0, 0, "", UNASSIGNED_SYSTEM_ADDRESS); self->SetPosition({ 10000, 0, 10000 }); - EntityManager::Instance()->SerializeEntity(self); + Game::entityManager->SerializeEntity(self); controller->OnFireEventServerSide(self, "ClearProperty"); } @@ -96,7 +97,7 @@ void BossSpiderQueenEnemyServer::WithdrawSpider(Entity* self, const bool withdra rot = controllable->GetRotation(); - EntityManager::Instance()->SerializeEntity(self); + Game::entityManager->SerializeEntity(self); auto* baseCombatAi = self->GetComponent(); @@ -112,7 +113,7 @@ void BossSpiderQueenEnemyServer::WithdrawSpider(Entity* self, const bool withdra //TODO: Set faction to -1 and set immunity destroyable->SetFaction(-1); destroyable->SetIsImmune(true); - EntityManager::Instance()->SerializeEntity(self); + Game::entityManager->SerializeEntity(self); self->AddTimer("WithdrawComplete", withdrawTime + 1.0f); waitForIdle = true; @@ -145,7 +146,7 @@ void BossSpiderQueenEnemyServer::WithdrawSpider(Entity* self, const bool withdra //Reset the current wave death counter m_DeathCounter = 0; - EntityManager::Instance()->SerializeEntity(self); + Game::entityManager->SerializeEntity(self); // Prepare a timer for post leap attack self->AddTimer("AdvanceAttack", attackPause); @@ -178,7 +179,7 @@ void BossSpiderQueenEnemyServer::SpiderWaveManager(Entity* self) { std::vector spiderEggs{}; - auto spooders = EntityManager::Instance()->GetEntitiesInGroup("EGG"); + auto spooders = Game::entityManager->GetEntitiesInGroup("EGG"); for (auto spodder : spooders) { spiderEggs.push_back(spodder->GetObjectID()); } @@ -200,7 +201,7 @@ void BossSpiderQueenEnemyServer::SpiderWaveManager(Entity* self) { } if (randomEgg) { - auto* eggEntity = EntityManager::Instance()->GetEntity(randomEgg); + auto* eggEntity = Game::entityManager->GetEntity(randomEgg); if (eggEntity == nullptr) { continue; @@ -233,7 +234,7 @@ void BossSpiderQueenEnemyServer::SpiderWaveManager(Entity* self) { // We have successfully readied a full wave // initiate hatching! for (auto egg : hatchList) { - auto* eggEntity = EntityManager::Instance()->GetEntity(egg); + auto* eggEntity = Game::entityManager->GetEntity(egg); if (eggEntity == nullptr) { continue; @@ -275,7 +276,7 @@ void BossSpiderQueenEnemyServer::RunRainOfFire(Entity* self) { auto index = 0u; for (const auto& rofGroup : ROFTargetGroupIDTable) { - const auto spawners = dZoneManager::Instance()->GetSpawnersInGroup(rofGroup); + const auto spawners = Game::zoneManager->GetSpawnersInGroup(rofGroup); std::vector spawned; @@ -303,7 +304,7 @@ void BossSpiderQueenEnemyServer::RunRainOfFire(Entity* self) { void BossSpiderQueenEnemyServer::RainOfFireManager(Entity* self) { if (!impactList.empty()) { - auto* entity = EntityManager::Instance()->GetEntity(impactList[0]); + auto* entity = Game::entityManager->GetEntity(impactList[0]); impactList.erase(impactList.begin()); @@ -407,7 +408,7 @@ void BossSpiderQueenEnemyServer::OnTimerDone(Entity* self, const std::string tim controllable->SetStatic(false); controllable->SetRotation(rot); controllable->SetStatic(true); - EntityManager::Instance()->SerializeEntity(self); + Game::entityManager->SerializeEntity(self); //Play the Spider Boss' mountain idle anim auto time = PlayAnimAndReturnTime(self, spiderWithdrawIdle); @@ -418,7 +419,7 @@ void BossSpiderQueenEnemyServer::OnTimerDone(Entity* self, const std::string tim rot = controllable->GetRotation(); //If there are still baby spiders, don't do anyhting either - const auto spiders = EntityManager::Instance()->GetEntitiesInGroup("BabySpider"); + const auto spiders = Game::entityManager->GetEntitiesInGroup("BabySpider"); if (spiders.size() > 0) self->AddTimer("checkForSpiders", time); else @@ -490,7 +491,7 @@ void BossSpiderQueenEnemyServer::OnTimerDone(Entity* self, const std::string tim }*/ auto landingTarget = self->GetI64(u"LandingTarget"); - auto landingEntity = EntityManager::Instance()->GetEntity(landingTarget); + auto landingEntity = Game::entityManager->GetEntity(landingTarget); auto* skillComponent = self->GetComponent(); @@ -546,10 +547,10 @@ void BossSpiderQueenEnemyServer::OnTimerDone(Entity* self, const std::string tim destroyable->SetIsImmune(false); destroyable->SetFaction(4); - EntityManager::Instance()->SerializeEntity(self); + Game::entityManager->SerializeEntity(self); } else if (timerName == "Clear") { - EntityManager::Instance()->FireEventServerSide(self, "ClearProperty"); + Game::entityManager->FireEventServerSide(self, "ClearProperty"); self->CancelAllTimers(); } else if (timerName == "UnlockSpecials") { //We no longer need to lock specials @@ -604,7 +605,7 @@ void BossSpiderQueenEnemyServer::OnUpdate(Entity* self) { controllable->SetRotation(NiQuaternion::IDENTITY); controllable->SetStatic(true); - EntityManager::Instance()->SerializeEntity(self); + Game::entityManager->SerializeEntity(self); } //---------------------------------------------- @@ -616,11 +617,11 @@ float BossSpiderQueenEnemyServer::PlayAnimAndReturnTime(Entity* self, const std: //TODO: Get the actual animation time // Get the anim time - float animTimer = defaultAnimPause; //self:GetAnimationTime{animationID = animID}.time + float animTimer = RenderComponent::GetAnimationTime(self, animID); // If we have an animation play it if (animTimer > 0) { - GameMessages::SendPlayAnimation(self, animID); + animTimer = RenderComponent::PlayAnimation(self, animID); } // If the anim time is less than the the default time use default diff --git a/dScripts/02_server/Enemy/AM/AmDarklingDragon.cpp b/dScripts/02_server/Enemy/AM/AmDarklingDragon.cpp index 28ba0044..9895395c 100644 --- a/dScripts/02_server/Enemy/AM/AmDarklingDragon.cpp +++ b/dScripts/02_server/Enemy/AM/AmDarklingDragon.cpp @@ -7,6 +7,7 @@ #include "BaseCombatAIComponent.h" #include "EntityInfo.h" #include "eAninmationFlags.h" +#include "RenderComponent.h" void AmDarklingDragon::OnStartup(Entity* self) { self->SetVar(u"weakspot", 0); @@ -27,7 +28,7 @@ void AmDarklingDragon::OnDie(Entity* self, Entity* killer) { auto golemId = self->GetVar(u"Golem"); - auto* golem = EntityManager::Instance()->GetEntity(golemId); + auto* golem = Game::entityManager->GetEntity(golemId); if (golem != nullptr) { golem->Smash(self->GetObjectID()); @@ -70,9 +71,9 @@ void AmDarklingDragon::OnHitOrHealResult(Entity* self, Entity* attacker, int32_t self->SetVar(u"weakpoint", 2); GameMessages::SendChangeIdleFlags(self->GetObjectID(), eAnimationFlags::IDLE_NONE, eAnimationFlags::IDLE_COMBAT, UNASSIGNED_SYSTEM_ADDRESS); - GameMessages::SendPlayAnimation(self, u"stunstart", 1.7f); + float animationTime = RenderComponent::PlayAnimation(self, u"stunstart", 1.7f); - self->AddTimer("timeToStunLoop", 1); + self->AddTimer("timeToStunLoop", 1.0f); auto position = self->GetPosition(); auto forward = self->GetRotation().GetForwardVector(); @@ -108,9 +109,9 @@ void AmDarklingDragon::OnHitOrHealResult(Entity* self, Entity* attacker, int32_t new LDFData(u"Dragon", self->GetObjectID()) }; - auto* golemObject = EntityManager::Instance()->CreateEntity(info); + auto* golemObject = Game::entityManager->CreateEntity(info); - EntityManager::Instance()->ConstructEntity(golemObject); + Game::entityManager->ConstructEntity(golemObject); } } } @@ -121,9 +122,9 @@ void AmDarklingDragon::OnTimerDone(Entity* self, std::string timerName) { } else if (timerName == "ExposeWeakSpotTimer") { self->SetVar(u"weakspot", 1); } else if (timerName == "timeToStunLoop") { - GameMessages::SendPlayAnimation(self, u"stunloop", 1.8f); + RenderComponent::PlayAnimation(self, u"stunloop", 1.8f); } else if (timerName == "ReviveTimer") { - GameMessages::SendPlayAnimation(self, u"stunend", 2.0f); + RenderComponent::PlayAnimation(self, u"stunend", 2.0f); self->AddTimer("backToAttack", 1); } else if (timerName == "backToAttack") { auto* baseCombatAIComponent = self->GetComponent(); @@ -153,5 +154,5 @@ void AmDarklingDragon::OnFireEventServerSide(Entity* self, Entity* sender, std:: self->SetVar(u"Golem", sender->GetObjectID()); - GameMessages::SendPlayAnimation(self, u"quickbuildhold", 1.9f); + RenderComponent::PlayAnimation(self, u"quickbuildhold", 1.9f); } diff --git a/dScripts/02_server/Enemy/FV/FvMaelstromCavalry.cpp b/dScripts/02_server/Enemy/FV/FvMaelstromCavalry.cpp index 9214667e..84eb70e7 100644 --- a/dScripts/02_server/Enemy/FV/FvMaelstromCavalry.cpp +++ b/dScripts/02_server/Enemy/FV/FvMaelstromCavalry.cpp @@ -3,7 +3,7 @@ void FvMaelstromCavalry::OnStartup(Entity* self) { for (const auto& group : self->GetGroups()) { - const auto& objects = EntityManager::Instance()->GetEntitiesInGroup(group); + const auto& objects = Game::entityManager->GetEntitiesInGroup(group); for (auto* obj : objects) { if (obj->GetLOT() != 8551) continue; @@ -22,7 +22,7 @@ void FvMaelstromCavalry::OnDie(Entity* self, Entity* killer) { return; } - const auto& triggers = EntityManager::Instance()->GetEntitiesInGroup("HorsemenTrigger"); + const auto& triggers = Game::entityManager->GetEntitiesInGroup("HorsemenTrigger"); for (auto* trigger : triggers) { trigger->OnFireEventServerSide(self, "HorsemenDeath"); diff --git a/dScripts/02_server/Enemy/FV/FvMaelstromDragon.cpp b/dScripts/02_server/Enemy/FV/FvMaelstromDragon.cpp index e78f537f..ff7e7a51 100644 --- a/dScripts/02_server/Enemy/FV/FvMaelstromDragon.cpp +++ b/dScripts/02_server/Enemy/FV/FvMaelstromDragon.cpp @@ -5,6 +5,7 @@ #include "DestroyableComponent.h" #include "eAninmationFlags.h" #include "EntityInfo.h" +#include "RenderComponent.h" void FvMaelstromDragon::OnStartup(Entity* self) { self->SetVar(u"weakspot", 0); @@ -34,13 +35,13 @@ void FvMaelstromDragon::OnDie(Entity* self, Entity* killer) { info.rot = rotation; info.spawnerID = self->GetObjectID(); - auto* chest = EntityManager::Instance()->CreateEntity(info); + auto* chest = Game::entityManager->CreateEntity(info); - EntityManager::Instance()->ConstructEntity(chest); + Game::entityManager->ConstructEntity(chest); auto golemId = self->GetVar(u"Golem"); - auto* golem = EntityManager::Instance()->GetEntity(golemId); + auto* golem = Game::entityManager->GetEntity(golemId); if (golem != nullptr) { golem->Smash(self->GetObjectID()); @@ -86,9 +87,9 @@ void FvMaelstromDragon::OnHitOrHealResult(Entity* self, Entity* attacker, int32_ self->SetVar(u"weakpoint", 2); GameMessages::SendChangeIdleFlags(self->GetObjectID(), eAnimationFlags::IDLE_NONE, eAnimationFlags::IDLE_COMBAT, UNASSIGNED_SYSTEM_ADDRESS); - GameMessages::SendPlayAnimation(self, u"stunstart", 1.7f); + RenderComponent::PlayAnimation(self, u"stunstart", 1.7f); - self->AddTimer("timeToStunLoop", 1); + self->AddTimer("timeToStunLoop", 1.0f); auto position = self->GetPosition(); auto forward = self->GetRotation().GetForwardVector(); @@ -124,9 +125,9 @@ void FvMaelstromDragon::OnHitOrHealResult(Entity* self, Entity* attacker, int32_ new LDFData(u"Dragon", self->GetObjectID()) }; - auto* golemObject = EntityManager::Instance()->CreateEntity(info); + auto* golemObject = Game::entityManager->CreateEntity(info); - EntityManager::Instance()->ConstructEntity(golemObject); + Game::entityManager->ConstructEntity(golemObject); } } } @@ -137,10 +138,10 @@ void FvMaelstromDragon::OnTimerDone(Entity* self, std::string timerName) { } else if (timerName == "ExposeWeakSpotTimer") { self->SetVar(u"weakspot", 1); } else if (timerName == "timeToStunLoop") { - GameMessages::SendPlayAnimation(self, u"stunloop", 1.8f); + RenderComponent::PlayAnimation(self, u"stunloop", 1.8f); } else if (timerName == "ReviveTimer") { - GameMessages::SendPlayAnimation(self, u"stunend", 2.0f); - self->AddTimer("backToAttack", 1); + RenderComponent::PlayAnimation(self, u"stunend", 2.0f); + self->AddTimer("backToAttack", 1.0f); } else if (timerName == "backToAttack") { auto* baseCombatAIComponent = self->GetComponent(); auto* skillComponent = self->GetComponent(); @@ -174,5 +175,5 @@ FvMaelstromDragon::OnFireEventServerSide(Entity* self, Entity* sender, std::stri self->SetVar(u"Golem", sender->GetObjectID()); - GameMessages::SendPlayAnimation(self, u"quickbuildhold", 1.9f); + RenderComponent::PlayAnimation(self, u"quickbuildhold", 1.9f); } diff --git a/dScripts/02_server/Enemy/General/BaseEnemyApe.cpp b/dScripts/02_server/Enemy/General/BaseEnemyApe.cpp index e9863b17..07221248 100644 --- a/dScripts/02_server/Enemy/General/BaseEnemyApe.cpp +++ b/dScripts/02_server/Enemy/General/BaseEnemyApe.cpp @@ -6,6 +6,7 @@ #include "EntityInfo.h" #include "SkillComponent.h" #include "eAninmationFlags.h" +#include "RenderComponent.h" #include "eStateChangeType.h" void BaseEnemyApe::OnStartup(Entity* self) { @@ -14,7 +15,7 @@ void BaseEnemyApe::OnStartup(Entity* self) { } void BaseEnemyApe::OnDie(Entity* self, Entity* killer) { - auto* anchor = EntityManager::Instance()->GetEntity(self->GetVar(u"QB")); + auto* anchor = Game::entityManager->GetEntity(self->GetVar(u"QB")); if (anchor != nullptr && !anchor->GetIsDead()) { anchor->Smash(self->GetObjectID(), eKillType::SILENT); } @@ -38,7 +39,7 @@ void BaseEnemyApe::OnHit(Entity* self, Entity* attacker) { if (skillComponent) { skillComponent->Reset(); } - GameMessages::SendPlayAnimation(self, u"disable", 1.7f); + RenderComponent::PlayAnimation(self, u"disable", 1.7f); GameMessages::SendChangeIdleFlags(self->GetObjectID(), eAnimationFlags::IDLE_NONE, eAnimationFlags::IDLE_COMBAT, UNASSIGNED_SYSTEM_ADDRESS); const auto reviveTime = self->GetVar(u"reviveTime") != 0.0f ? self->GetVar(u"reviveTime") : 12.0f; @@ -55,7 +56,7 @@ void BaseEnemyApe::OnTimerDone(Entity* self, std::string timerName) { if (destroyableComponent != nullptr) { destroyableComponent->SetArmor(destroyableComponent->GetMaxArmor() / timesStunned); } - EntityManager::Instance()->SerializeEntity(self); + Game::entityManager->SerializeEntity(self); GameMessages::SendChangeIdleFlags(self->GetObjectID(), eAnimationFlags::IDLE_COMBAT, eAnimationFlags::IDLE_NONE, UNASSIGNED_SYSTEM_ADDRESS); self->SetVar(u"timesStunned", timesStunned + 1); StunApe(self, false); @@ -91,14 +92,14 @@ void BaseEnemyApe::OnTimerDone(Entity* self, std::string timerName) { new LDFData(u"ape", self->GetObjectID()) }; - auto* anchor = EntityManager::Instance()->CreateEntity(entityInfo); - EntityManager::Instance()->ConstructEntity(anchor); + auto* anchor = Game::entityManager->CreateEntity(entityInfo); + Game::entityManager->ConstructEntity(anchor); self->SetVar(u"QB", anchor->GetObjectID()); } else if (timerName == "anchorDamageTimer") { // Attacks the ape with some god skill - const auto* player = EntityManager::Instance()->GetEntity(self->GetVar(u"smasher")); + const auto* player = Game::entityManager->GetEntity(self->GetVar(u"smasher")); if (player == nullptr) { return; } diff --git a/dScripts/02_server/Enemy/General/BaseEnemyMech.cpp b/dScripts/02_server/Enemy/General/BaseEnemyMech.cpp index ce42585c..c652dab0 100644 --- a/dScripts/02_server/Enemy/General/BaseEnemyMech.cpp +++ b/dScripts/02_server/Enemy/General/BaseEnemyMech.cpp @@ -38,8 +38,8 @@ void BaseEnemyMech::OnDie(Entity* self, Entity* killer) { info.spawnerID = self->GetObjectID(); info.settings = cfg; - Entity* turret = EntityManager::Instance()->CreateEntity(info, nullptr); + Entity* turret = Game::entityManager->CreateEntity(info, nullptr); if (turret) { - EntityManager::Instance()->ConstructEntity(turret); + Game::entityManager->ConstructEntity(turret); } } diff --git a/dScripts/02_server/Enemy/General/GfApeSmashingQB.cpp b/dScripts/02_server/Enemy/General/GfApeSmashingQB.cpp index 5bba6450..aa4a56a7 100644 --- a/dScripts/02_server/Enemy/General/GfApeSmashingQB.cpp +++ b/dScripts/02_server/Enemy/General/GfApeSmashingQB.cpp @@ -1,6 +1,8 @@ #include "GfApeSmashingQB.h" #include "EntityManager.h" #include "GameMessages.h" +#include "Entity.h" +#include "RenderComponent.h" void GfApeSmashingQB::OnStartup(Entity* self) { self->SetNetworkVar(u"lootTagOwner", self->GetVar(u"lootTagOwner")); @@ -13,10 +15,10 @@ void GfApeSmashingQB::OnTimerDone(Entity* self, std::string timerName) { } void GfApeSmashingQB::OnRebuildComplete(Entity* self, Entity* target) { - auto* ape = EntityManager::Instance()->GetEntity(self->GetVar(u"ape")); + auto* ape = Game::entityManager->GetEntity(self->GetVar(u"ape")); if (ape != nullptr) { ape->OnFireEventServerSide(target, "rebuildDone"); - GameMessages::SendPlayAnimation(self, u"smash", 1.7f); + RenderComponent::PlayAnimation(self, u"smash", 1.7f); self->AddTimer("anchorBreakTime", 1.0f); } } diff --git a/dScripts/02_server/Enemy/General/TreasureChestDragonServer.cpp b/dScripts/02_server/Enemy/General/TreasureChestDragonServer.cpp index 19788677..87416b4d 100644 --- a/dScripts/02_server/Enemy/General/TreasureChestDragonServer.cpp +++ b/dScripts/02_server/Enemy/General/TreasureChestDragonServer.cpp @@ -29,7 +29,7 @@ void TreasureChestDragonServer::OnUse(Entity* self, Entity* user) { rating = team->members.size(); for (const auto member : team->members) { - auto* memberObject = EntityManager::Instance()->GetEntity(member); + auto* memberObject = Game::entityManager->GetEntity(member); if (memberObject == nullptr) continue; diff --git a/dScripts/02_server/Equipment/BootyDigServer.cpp b/dScripts/02_server/Equipment/BootyDigServer.cpp index 190c232b..d27d1faa 100644 --- a/dScripts/02_server/Equipment/BootyDigServer.cpp +++ b/dScripts/02_server/Equipment/BootyDigServer.cpp @@ -7,14 +7,14 @@ #include "Loot.h" void BootyDigServer::OnStartup(Entity* self) { - auto* zoneControlObject = EntityManager::Instance()->GetZoneControlEntity(); + auto* zoneControlObject = Game::entityManager->GetZoneControlEntity(); if (zoneControlObject != nullptr) { zoneControlObject->OnFireEventServerSide(self, "CheckForPropertyOwner"); } } void BootyDigServer::OnPlayerLoaded(Entity* self, Entity* player) { - auto* zoneControlObject = EntityManager::Instance()->GetZoneControlEntity(); + auto* zoneControlObject = Game::entityManager->GetZoneControlEntity(); if (zoneControlObject != nullptr) { zoneControlObject->OnFireEventServerSide(self, "CheckForPropertyOwner"); } diff --git a/dScripts/02_server/Equipment/MaestromExtracticatorServer.cpp b/dScripts/02_server/Equipment/MaestromExtracticatorServer.cpp index c01d2362..689eaac3 100644 --- a/dScripts/02_server/Equipment/MaestromExtracticatorServer.cpp +++ b/dScripts/02_server/Equipment/MaestromExtracticatorServer.cpp @@ -4,22 +4,21 @@ #include "EntityManager.h" #include "MissionComponent.h" #include "eMissionTaskType.h" +#include "RenderComponent.h" void MaestromExtracticatorServer::OnStartup(Entity* self) { - //self:SetNetworkVar("current_anim", failAnim) - GameMessages::SendPlayAnimation(self, GeneralUtils::ASCIIToUTF16(failAnim)); + float animTime = RenderComponent::PlayAnimation(self, failAnim); + if (animTime == 0.0f) animTime = defaultTime; - self->AddTimer("PlayFail", defaultTime); + self->AddTimer("PlayFail", animTime); self->AddTimer("RemoveSample", destroyAfterNoSampleTime); } -void MaestromExtracticatorServer::OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, - int32_t param2, int32_t param3) { - if (sender == nullptr) - return; +void MaestromExtracticatorServer::OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2, int32_t param3) { + if (sender == nullptr) return; if (args == "attemptCollection") { - Entity* player = EntityManager::Instance()->GetEntity(self->GetSpawnerID()); + Entity* player = Game::entityManager->GetEntity(self->GetSpawnerID()); if (!player) return; auto missionComponent = player->GetComponent(); @@ -32,20 +31,17 @@ void MaestromExtracticatorServer::OnFireEventServerSide(Entity* self, Entity* se } void MaestromExtracticatorServer::CollectSample(Entity* self, LWOOBJID sampleObj) { - PlayAnimAndReturnTime(self, collectAnim); - self->AddTimer("RemoveSample", defaultTime); + self->AddTimer("RemoveSample", PlayAnimAndReturnTime(self, collectAnim)); } -void MaestromExtracticatorServer::PlayAnimAndReturnTime(Entity* self, std::string animID) { - GameMessages::SendPlayAnimation(self, GeneralUtils::ASCIIToUTF16(animID)); +float MaestromExtracticatorServer::PlayAnimAndReturnTime(Entity* self, std::string animID) { + return RenderComponent::PlayAnimation(self, animID); } void MaestromExtracticatorServer::OnTimerDone(Entity* self, std::string timerName) { if (timerName == "RemoveSample") { self->ScheduleKillAfterUpdate(); - } - - if (timerName == "PlayFail") { - GameMessages::SendPlayAnimation(self, GeneralUtils::ASCIIToUTF16(failAnim)); + } else if (timerName == "PlayFail") { + RenderComponent::PlayAnimation(self, failAnim); } } diff --git a/dScripts/02_server/Equipment/MaestromExtracticatorServer.h b/dScripts/02_server/Equipment/MaestromExtracticatorServer.h index c4adb51e..f0e976f3 100644 --- a/dScripts/02_server/Equipment/MaestromExtracticatorServer.h +++ b/dScripts/02_server/Equipment/MaestromExtracticatorServer.h @@ -7,7 +7,7 @@ public: void OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2, int32_t param3); void CollectSample(Entity* self, LWOOBJID sampleObj); - void PlayAnimAndReturnTime(Entity* self, std::string animID); + float PlayAnimAndReturnTime(Entity* self, std::string animID); void OnTimerDone(Entity* self, std::string timerName); private: diff --git a/dScripts/02_server/Map/AG/AgCagedBricksServer.cpp b/dScripts/02_server/Map/AG/AgCagedBricksServer.cpp index 13c9c04b..4d7e8a64 100644 --- a/dScripts/02_server/Map/AG/AgCagedBricksServer.cpp +++ b/dScripts/02_server/Map/AG/AgCagedBricksServer.cpp @@ -8,7 +8,7 @@ void AgCagedBricksServer::OnUse(Entity* self, Entity* user) { //Tell the client to spawn the baby spiderling: - auto spooders = EntityManager::Instance()->GetEntitiesInGroup("cagedSpider"); + auto spooders = Game::entityManager->GetEntitiesInGroup("cagedSpider"); for (auto spodder : spooders) { GameMessages::SendFireEventClientSide(spodder->GetObjectID(), user->GetSystemAddress(), u"toggle", LWOOBJID_EMPTY, 0, 0, user->GetObjectID()); } diff --git a/dScripts/02_server/Map/AG/AgLaserSensorServer.cpp b/dScripts/02_server/Map/AG/AgLaserSensorServer.cpp index 703625d2..7fcea9fa 100644 --- a/dScripts/02_server/Map/AG/AgLaserSensorServer.cpp +++ b/dScripts/02_server/Map/AG/AgLaserSensorServer.cpp @@ -2,56 +2,27 @@ #include "PhantomPhysicsComponent.h" #include "SkillComponent.h" -#include "EntityManager.h" -#include "AgMonumentLaserServer.h" -#include "EntityManager.h" #include "ePhysicsEffectType.h" -#include "eReplicaComponentType.h" void AgLaserSensorServer::OnStartup(Entity* self) { - - PhantomPhysicsComponent* physComp = static_cast(self->GetComponent(eReplicaComponentType::PHANTOM_PHYSICS)); - physComp->SetPhysicsEffectActive(true); - physComp->SetEffectType(ePhysicsEffectType::REPULSE); - physComp->SetDirectionalMultiplier(static_cast(m_RepelForce)); - physComp->SetDirection(NiPoint3::UNIT_Y); - - m_Skill = self->GetComponent(); + self->SetBoolean(u"active", true); + auto repelForce = self->GetVarAs(u"repelForce"); + if (!repelForce) repelForce = m_RepelForce; + auto* phantomPhysicsComponent = self->GetComponent(); + if (!phantomPhysicsComponent) return; + phantomPhysicsComponent->SetPhysicsEffectActive(true); + phantomPhysicsComponent->SetEffectType(ePhysicsEffectType::REPULSE); + phantomPhysicsComponent->SetDirectionalMultiplier(repelForce); + phantomPhysicsComponent->SetDirection(NiPoint3::UNIT_Y); } void AgLaserSensorServer::OnCollisionPhantom(Entity* self, Entity* target) { - - if (!m_Skill) return; - - - Entity* laser = nullptr; - - for (auto script : EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::SCRIPT)) { - - AgMonumentLaserServer* hasLaser = (AgMonumentLaserServer*)script; - - if (hasLaser) { - const auto source = script->GetPosition(); - const auto obj = self->GetObjectID(); - - if (obj == 76690936093053 && Vector3::DistanceSquared(source, NiPoint3(149.007f, 417.083f, 218.346f)) <= 1.0f) { - laser = script; - break; - } else if (obj == 75866302318824 && Vector3::DistanceSquared(source, NiPoint3(48.6403f, 403.803f, 196.711f)) <= 1.0f) { - laser = script; - break; - } else if (obj == 75866302318822 && Vector3::DistanceSquared(source, NiPoint3(19.2155f, 420.083f, 249.226f)) <= 1.0f) { - laser = script; - break; - } else if (obj == 75866302318823 && Vector3::DistanceSquared(source, NiPoint3(-6.61596f, 404.633f, 274.323f)) <= 1.0f) { - laser = script; - break; - } - } - } - - if (laser != nullptr) { - m_Skill->CalculateBehavior(m_SkillCastID, 15714, target->GetObjectID()); - } + auto active = self->GetVar(u"active"); + if (!active) return; + auto skillCastID = self->GetVarAs(u"skillCastID"); + if (skillCastID == 0) skillCastID = m_SkillCastID; + auto* skillComponent = self->GetComponent(); + if (!skillComponent) return; + skillComponent->CastSkill(m_SkillCastID, target->GetObjectID()); } diff --git a/dScripts/02_server/Map/AG/AgLaserSensorServer.h b/dScripts/02_server/Map/AG/AgLaserSensorServer.h index 72e09dd8..ee7fb6ec 100644 --- a/dScripts/02_server/Map/AG/AgLaserSensorServer.h +++ b/dScripts/02_server/Map/AG/AgLaserSensorServer.h @@ -8,8 +8,7 @@ public: void OnStartup(Entity* self); void OnCollisionPhantom(Entity* self, Entity* target); private: - SkillComponent* m_Skill; - int m_RepelForce = -25; + float m_RepelForce = -25.0f; int m_SkillCastID = 163; }; diff --git a/dScripts/02_server/Map/AG/AgMonumentBirds.cpp b/dScripts/02_server/Map/AG/AgMonumentBirds.cpp index ad3417a4..c9df4dc1 100644 --- a/dScripts/02_server/Map/AG/AgMonumentBirds.cpp +++ b/dScripts/02_server/Map/AG/AgMonumentBirds.cpp @@ -1,5 +1,8 @@ #include "AgMonumentBirds.h" #include "GameMessages.h" +#include "Entity.h" +#include "RenderComponent.h" +#include "EntityManager.h" //-------------------------------------------------------------- //Makes the ag birds fly away when you get close and smashes them. @@ -16,7 +19,7 @@ void AgMonumentBirds::OnProximityUpdate(Entity* self, Entity* entering, std::str if (name == "MonumentBirds" && status == "ENTER") { self->AddTimer("killBird", 1.0f); - GameMessages::SendPlayAnimation(self, sOnProximityAnim); + RenderComponent::PlayAnimation(self, sOnProximityAnim); self->SetVar(u"IsFlying", true); self->SetVar(u"PlayerID", entering->GetObjectID()); } @@ -25,7 +28,7 @@ void AgMonumentBirds::OnProximityUpdate(Entity* self, Entity* entering, std::str void AgMonumentBirds::OnTimerDone(Entity* self, std::string timerName) { if (timerName != "killBird") return; - auto* player = EntityManager::Instance()->GetEntity(self->GetVar(u"PlayerID")); + auto* player = Game::entityManager->GetEntity(self->GetVar(u"PlayerID")); if (player == nullptr) return; diff --git a/dScripts/02_server/Map/AG/AgMonumentLaserServer.cpp b/dScripts/02_server/Map/AG/AgMonumentLaserServer.cpp index 6efda89e..34c5c9a6 100644 --- a/dScripts/02_server/Map/AG/AgMonumentLaserServer.cpp +++ b/dScripts/02_server/Map/AG/AgMonumentLaserServer.cpp @@ -1,20 +1,17 @@ #include "AgMonumentLaserServer.h" +#include "EntityManager.h" void AgMonumentLaserServer::OnStartup(Entity* self) { - /* - self->SetProximityRadius(m_Radius, "MonumentLaser"); - - std::cout << "Monument Laser " << self->GetObjectID() << " is at " << self->GetPosition().GetX() - << ","<< self->GetPosition().GetY() << "," << self->GetPosition().GetZ() << std::endl; - */ -} - -void AgMonumentLaserServer::OnProximityUpdate(Entity* self, Entity* entering, std::string name, std::string status) { - /* - if (status == "ENTER") { - - std::cout << "Monument laser ID: " << self->GetObjectID() << std::endl; + auto lasers = Game::entityManager->GetEntitiesInGroup(self->GetVarAsString(u"volGroup")); + for (auto laser : lasers) { + if (laser) laser->SetBoolean(u"active", true); + } +} + +void AgMonumentLaserServer::OnDie(Entity* self, Entity* killer) { + auto lasers = Game::entityManager->GetEntitiesInGroup(self->GetVarAsString(u"volGroup")); + for (auto laser : lasers) { + if (laser) laser->SetBoolean(u"active", false); } - */ } diff --git a/dScripts/02_server/Map/AG/AgMonumentLaserServer.h b/dScripts/02_server/Map/AG/AgMonumentLaserServer.h index 56979c55..8163948b 100644 --- a/dScripts/02_server/Map/AG/AgMonumentLaserServer.h +++ b/dScripts/02_server/Map/AG/AgMonumentLaserServer.h @@ -3,8 +3,6 @@ class AgMonumentLaserServer : public CppScripts::Script { public: - void OnStartup(Entity* self); - void OnProximityUpdate(Entity* self, Entity* entering, std::string name, std::string status); -private: - float m_Radius = 25.0f; + void OnStartup(Entity* self) override; + void OnDie(Entity* self, Entity* killer) override; }; diff --git a/dScripts/02_server/Map/AG/AgMonumentRaceCancel.cpp b/dScripts/02_server/Map/AG/AgMonumentRaceCancel.cpp index 2e744434..1f0db946 100644 --- a/dScripts/02_server/Map/AG/AgMonumentRaceCancel.cpp +++ b/dScripts/02_server/Map/AG/AgMonumentRaceCancel.cpp @@ -2,7 +2,7 @@ #include "EntityManager.h" void AgMonumentRaceCancel::OnCollisionPhantom(Entity* self, Entity* target) { - auto managers = EntityManager::Instance()->GetEntitiesInGroup("race_manager"); + auto managers = Game::entityManager->GetEntitiesInGroup("race_manager"); if (!managers.empty()) { managers[0]->OnFireEventServerSide(target, "course_cancel"); } diff --git a/dScripts/02_server/Map/AG/AgMonumentRaceGoal.cpp b/dScripts/02_server/Map/AG/AgMonumentRaceGoal.cpp index 0dd91bf2..6d305d4b 100644 --- a/dScripts/02_server/Map/AG/AgMonumentRaceGoal.cpp +++ b/dScripts/02_server/Map/AG/AgMonumentRaceGoal.cpp @@ -8,7 +8,7 @@ void AgMonumentRaceGoal::OnStartup(Entity* self) { void AgMonumentRaceGoal::OnProximityUpdate(Entity* self, Entity* entering, std::string name, std::string status) { if (name == "RaceGoal" && entering && entering->IsPlayer() && status == "ENTER") { - auto managers = EntityManager::Instance()->GetEntitiesInGroup("race_manager"); + auto managers = Game::entityManager->GetEntitiesInGroup("race_manager"); if (managers.empty() || !managers.at(0)) return; managers.at(0)->OnFireEventServerSide(entering, "course_finish"); } diff --git a/dScripts/02_server/Map/AG/NpcAgCourseStarter.cpp b/dScripts/02_server/Map/AG/NpcAgCourseStarter.cpp index d2cc647e..b47260f9 100644 --- a/dScripts/02_server/Map/AG/NpcAgCourseStarter.cpp +++ b/dScripts/02_server/Map/AG/NpcAgCourseStarter.cpp @@ -40,7 +40,7 @@ void NpcAgCourseStarter::OnMessageBoxResponse(Entity* self, Entity* sender, int3 scriptedActivityComponent->RemoveActivityPlayerData(sender->GetObjectID()); - EntityManager::Instance()->SerializeEntity(self); + Game::entityManager->SerializeEntity(self); } else if (identifier == u"player_dialog_start_course" && button == 1) { GameMessages::SendNotifyClientObject(self->GetObjectID(), u"start_timer", 0, 0, LWOOBJID_EMPTY, "", sender->GetSystemAddress()); @@ -54,7 +54,7 @@ void NpcAgCourseStarter::OnMessageBoxResponse(Entity* self, Entity* sender, int3 data->values[1] = *(float*)&startTime; - EntityManager::Instance()->SerializeEntity(self); + Game::entityManager->SerializeEntity(self); } else if (identifier == u"FootRaceCancel") { GameMessages::SendNotifyClientObject(self->GetObjectID(), u"stop_timer", 0, 0, LWOOBJID_EMPTY, "", sender->GetSystemAddress()); @@ -68,15 +68,12 @@ void NpcAgCourseStarter::OnMessageBoxResponse(Entity* self, Entity* sender, int3 } } -void NpcAgCourseStarter::OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2, - int32_t param3) { +void NpcAgCourseStarter::OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2, int32_t param3) { auto* scriptedActivityComponent = self->GetComponent(); - if (scriptedActivityComponent == nullptr) - return; + if (scriptedActivityComponent == nullptr) return; auto* data = scriptedActivityComponent->GetActivityPlayerData(sender->GetObjectID()); - if (data == nullptr) - return; + if (data == nullptr) return; if (args == "course_cancel") { GameMessages::SendNotifyClientObject(self->GetObjectID(), u"cancel_timer", 0, 0, @@ -95,9 +92,8 @@ void NpcAgCourseStarter::OnFireEventServerSide(Entity* self, Entity* sender, std "performact_time"); } - EntityManager::Instance()->SerializeEntity(self); - LeaderboardManager::SaveScore(sender->GetObjectID(), scriptedActivityComponent->GetActivityID(), - 0, (uint32_t)finish); + Game::entityManager->SerializeEntity(self); + LeaderboardManager::SaveScore(sender->GetObjectID(), scriptedActivityComponent->GetActivityID(), static_cast(finish)); GameMessages::SendNotifyClientObject(self->GetObjectID(), u"ToggleLeaderBoard", scriptedActivityComponent->GetActivityID(), 0, sender->GetObjectID(), diff --git a/dScripts/02_server/Map/AG/NpcWispServer.cpp b/dScripts/02_server/Map/AG/NpcWispServer.cpp index 84196c8c..e3b5398d 100644 --- a/dScripts/02_server/Map/AG/NpcWispServer.cpp +++ b/dScripts/02_server/Map/AG/NpcWispServer.cpp @@ -35,7 +35,7 @@ void NpcWispServer::OnMissionDialogueOK(Entity* self, Entity* target, int missio : std::vector{ "MaelstromSamples", "MaelstromSamples2ndary1", "MaelstromSamples2ndary2" }; for (const auto& group : groups) { - auto samples = EntityManager::Instance()->GetEntitiesInGroup(group); + auto samples = Game::entityManager->GetEntitiesInGroup(group); for (auto* sample : samples) { GameMessages::SendNotifyClientObject(sample->GetObjectID(), u"SetVisibility", visible, 0, target->GetObjectID(), "", target->GetSystemAddress()); diff --git a/dScripts/02_server/Map/AG_Spider_Queen/ZoneAgSpiderQueen.cpp b/dScripts/02_server/Map/AG_Spider_Queen/ZoneAgSpiderQueen.cpp index 5996548f..2091041b 100644 --- a/dScripts/02_server/Map/AG_Spider_Queen/ZoneAgSpiderQueen.cpp +++ b/dScripts/02_server/Map/AG_Spider_Queen/ZoneAgSpiderQueen.cpp @@ -9,8 +9,8 @@ void ZoneAgSpiderQueen::SetGameVariables(Entity* self) { ZoneAgProperty::SetGameVariables(self); // Disable property flags - self->SetVar(defeatedProperyFlag, 0); - self->SetVar(placedModelFlag, 0); + self->SetVar(defeatedProperyFlag, 0); + self->SetVar(placedModelFlag, 0); self->SetVar(guardFirstMissionFlag, 0); self->SetVar(guardMissionFlag, 0); self->SetVar(brickLinkMissionIDFlag, 0); @@ -63,7 +63,7 @@ void ZoneAgSpiderQueen::OnTimerDone(Entity* self, std::string timerName) { return; if (timerName == "killSpider") { - auto spawnTargets = EntityManager::Instance()->GetEntitiesInGroup(self->GetVar(LandTargetGroup)); + auto spawnTargets = Game::entityManager->GetEntitiesInGroup(self->GetVar(LandTargetGroup)); for (auto* spawnTarget : spawnTargets) { EntityInfo info{}; @@ -75,8 +75,8 @@ void ZoneAgSpiderQueen::OnTimerDone(Entity* self, std::string timerName) { new LDFData(u"parent_tag", self->GetObjectID()) }; - auto* chest = EntityManager::Instance()->CreateEntity(info); - EntityManager::Instance()->ConstructEntity(chest); + auto* chest = Game::entityManager->CreateEntity(info); + Game::entityManager->ConstructEntity(chest); } } diff --git a/dScripts/02_server/Map/AM/AmBlueX.cpp b/dScripts/02_server/Map/AM/AmBlueX.cpp index 312cdc47..180d4c54 100644 --- a/dScripts/02_server/Map/AM/AmBlueX.cpp +++ b/dScripts/02_server/Map/AM/AmBlueX.cpp @@ -18,7 +18,7 @@ void AmBlueX::OnSkillEventFired(Entity* self, Entity* caster, const std::string& auto* character = caster->GetCharacter(); if (character != nullptr) { - character->SetPlayerFlag(self->GetVar(m_FlagVariable), true); + character->SetPlayerFlag(self->GetVar(m_FlagVariable), true); } EntityInfo info{}; @@ -27,16 +27,16 @@ void AmBlueX::OnSkillEventFired(Entity* self, Entity* caster, const std::string& info.rot = self->GetRotation(); info.spawnerID = self->GetObjectID(); - auto* fxObject = EntityManager::Instance()->CreateEntity(info, nullptr, self); - EntityManager::Instance()->ConstructEntity(fxObject); + auto* fxObject = Game::entityManager->CreateEntity(info, nullptr, self); + Game::entityManager->ConstructEntity(fxObject); auto fxObjectID = fxObject->GetObjectID(); auto playerID = caster->GetObjectID(); // Add a callback for the bomb to explode self->AddCallbackTimer(m_BombTime, [this, self, fxObjectID, playerID]() { - auto* fxObject = EntityManager::Instance()->GetEntity(fxObjectID); - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* fxObject = Game::entityManager->GetEntity(fxObjectID); + auto* player = Game::entityManager->GetEntity(playerID); auto* skillComponent = self->GetComponent(); if (skillComponent == nullptr) diff --git a/dScripts/02_server/Map/AM/AmBridge.cpp b/dScripts/02_server/Map/AM/AmBridge.cpp index 719ca058..2fce627d 100644 --- a/dScripts/02_server/Map/AM/AmBridge.cpp +++ b/dScripts/02_server/Map/AM/AmBridge.cpp @@ -6,7 +6,7 @@ void AmBridge::OnStartup(Entity* self) { } void AmBridge::OnRebuildComplete(Entity* self, Entity* target) { - const auto consoles = EntityManager::Instance()->GetEntitiesInGroup("Console" + GeneralUtils::UTF16ToWTF8(self->GetVar(u"bridge"))); + const auto consoles = Game::entityManager->GetEntitiesInGroup("Console" + GeneralUtils::UTF16ToWTF8(self->GetVar(u"bridge"))); if (consoles.empty()) { return; diff --git a/dScripts/02_server/Map/AM/AmConsoleTeleportServer.cpp b/dScripts/02_server/Map/AM/AmConsoleTeleportServer.cpp index f3931e0d..0627b27a 100644 --- a/dScripts/02_server/Map/AM/AmConsoleTeleportServer.cpp +++ b/dScripts/02_server/Map/AM/AmConsoleTeleportServer.cpp @@ -1,6 +1,6 @@ #include "AmConsoleTeleportServer.h" #include "ChooseYourDestinationNsToNt.h" -#include "AMFFormat.h" +#include "Amf3.h" void AmConsoleTeleportServer::OnStartup(Entity* self) { self->SetVar(u"teleportAnim", m_TeleportAnim); diff --git a/dScripts/02_server/Map/AM/AmDrawBridge.cpp b/dScripts/02_server/Map/AM/AmDrawBridge.cpp index 3c4dcce6..e6b80764 100644 --- a/dScripts/02_server/Map/AM/AmDrawBridge.cpp +++ b/dScripts/02_server/Map/AM/AmDrawBridge.cpp @@ -68,7 +68,7 @@ void AmDrawBridge::OnTimerDone(Entity* self, std::string timerName) { simplePhysicsComponent->SetAngularVelocity(NiPoint3::ZERO); - EntityManager::Instance()->SerializeEntity(bridge); + Game::entityManager->SerializeEntity(bridge); } } @@ -103,7 +103,7 @@ void AmDrawBridge::MoveBridgeDown(Entity* self, Entity* bridge, bool down) { simplePhysicsComponent->SetAngularVelocity(forwardVect); - EntityManager::Instance()->SerializeEntity(bridge); + Game::entityManager->SerializeEntity(bridge); self->AddTimer("rotateBridgeDown", travelTime); } @@ -118,5 +118,5 @@ void AmDrawBridge::NotifyDie(Entity* self, Entity* other) { Entity* AmDrawBridge::GetBridge(Entity* self) { const auto bridgeID = self->GetVar(u"BridgeID"); - return EntityManager::Instance()->GetEntity(bridgeID); + return Game::entityManager->GetEntity(bridgeID); } diff --git a/dScripts/02_server/Map/AM/AmDropshipComputer.cpp b/dScripts/02_server/Map/AM/AmDropshipComputer.cpp index f23fa93f..1ee2aba3 100644 --- a/dScripts/02_server/Map/AM/AmDropshipComputer.cpp +++ b/dScripts/02_server/Map/AM/AmDropshipComputer.cpp @@ -42,7 +42,7 @@ void AmDropshipComputer::OnDie(Entity* self, Entity* killer) { const auto nextPipeNum = pipeNum + 1; - const auto samePipeSpawners = dZoneManager::Instance()->GetSpawnersByName(myGroup); + const auto samePipeSpawners = Game::zoneManager->GetSpawnersByName(myGroup); if (!samePipeSpawners.empty()) { samePipeSpawners[0]->SoftReset(); @@ -53,7 +53,7 @@ void AmDropshipComputer::OnDie(Entity* self, Entity* killer) { if (killer != nullptr && killer->IsPlayer()) { const auto nextPipe = pipeGroup + std::to_string(nextPipeNum); - const auto nextPipeSpawners = dZoneManager::Instance()->GetSpawnersByName(nextPipe); + const auto nextPipeSpawners = Game::zoneManager->GetSpawnersByName(nextPipe); if (!nextPipeSpawners.empty()) { nextPipeSpawners[0]->Activate(); @@ -61,7 +61,7 @@ void AmDropshipComputer::OnDie(Entity* self, Entity* killer) { } else { const auto nextPipe = pipeGroup + "1"; - const auto firstPipeSpawners = dZoneManager::Instance()->GetSpawnersByName(nextPipe); + const auto firstPipeSpawners = Game::zoneManager->GetSpawnersByName(nextPipe); if (!firstPipeSpawners.empty()) { firstPipeSpawners[0]->Activate(); diff --git a/dScripts/02_server/Map/AM/AmShieldGenerator.cpp b/dScripts/02_server/Map/AM/AmShieldGenerator.cpp index 5d1b7d08..e39233eb 100644 --- a/dScripts/02_server/Map/AM/AmShieldGenerator.cpp +++ b/dScripts/02_server/Map/AM/AmShieldGenerator.cpp @@ -49,7 +49,7 @@ void AmShieldGenerator::OnProximityUpdate(Entity* self, Entity* entering, std::s void AmShieldGenerator::OnDie(Entity* self, Entity* killer) { self->CancelAllTimers(); - auto* child = EntityManager::Instance()->GetEntity(self->GetVar(u"Child")); + auto* child = Game::entityManager->GetEntity(self->GetVar(u"Child")); if (child != nullptr) { child->Kill(); @@ -69,7 +69,7 @@ void AmShieldGenerator::OnTimerDone(Entity* self, std::string timerName) { auto enemiesInProximity = self->GetVar>(u"Enemies"); for (const auto enemyID : enemiesInProximity) { - auto* enemy = EntityManager::Instance()->GetEntity(enemyID); + auto* enemy = Game::entityManager->GetEntity(enemyID); if (enemy != nullptr) { EnemyEnteredShield(self, enemy); @@ -94,7 +94,7 @@ void AmShieldGenerator::StartShield(Entity* self) { info.rot = myRot; info.spawnerID = self->GetObjectID(); - auto* child = EntityManager::Instance()->CreateEntity(info); + auto* child = Game::entityManager->CreateEntity(info); self->SetVar(u"Child", child->GetObjectID()); @@ -111,7 +111,7 @@ void AmShieldGenerator::BuffPlayers(Entity* self) { auto entitiesInProximity = self->GetVar>(u"Players"); for (const auto playerID : entitiesInProximity) { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) { return; diff --git a/dScripts/02_server/Map/AM/AmShieldGeneratorQuickbuild.cpp b/dScripts/02_server/Map/AM/AmShieldGeneratorQuickbuild.cpp index 381c13bc..506f5580 100644 --- a/dScripts/02_server/Map/AM/AmShieldGeneratorQuickbuild.cpp +++ b/dScripts/02_server/Map/AM/AmShieldGeneratorQuickbuild.cpp @@ -69,7 +69,7 @@ void AmShieldGeneratorQuickbuild::OnProximityUpdate(Entity* self, Entity* enteri void AmShieldGeneratorQuickbuild::OnDie(Entity* self, Entity* killer) { self->CancelAllTimers(); - auto* child = EntityManager::Instance()->GetEntity(self->GetVar(u"Child")); + auto* child = Game::entityManager->GetEntity(self->GetVar(u"Child")); if (child != nullptr) { child->Kill(); @@ -89,7 +89,7 @@ void AmShieldGeneratorQuickbuild::OnTimerDone(Entity* self, std::string timerNam auto enemiesInProximity = self->GetVar>(u"Enemies"); for (const auto enemyID : enemiesInProximity) { - auto* enemy = EntityManager::Instance()->GetEntity(enemyID); + auto* enemy = Game::entityManager->GetEntity(enemyID); if (enemy != nullptr) { EnemyEnteredShield(self, enemy); @@ -106,7 +106,7 @@ void AmShieldGeneratorQuickbuild::OnRebuildComplete(Entity* self, Entity* target auto enemiesInProximity = self->GetVar>(u"Enemies"); for (const auto enemyID : enemiesInProximity) { - auto* enemy = EntityManager::Instance()->GetEntity(enemyID); + auto* enemy = Game::entityManager->GetEntity(enemyID); if (enemy != nullptr) { enemy->Smash(); @@ -116,7 +116,7 @@ void AmShieldGeneratorQuickbuild::OnRebuildComplete(Entity* self, Entity* target auto entitiesInProximity = self->GetVar>(u"Players"); for (const auto playerID : entitiesInProximity) { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) { continue; @@ -146,7 +146,7 @@ void AmShieldGeneratorQuickbuild::StartShield(Entity* self) { info.rot = myRot; info.spawnerID = self->GetObjectID(); - auto* child = EntityManager::Instance()->CreateEntity(info); + auto* child = Game::entityManager->CreateEntity(info); self->SetVar(u"Child", child->GetObjectID()); @@ -163,7 +163,7 @@ void AmShieldGeneratorQuickbuild::BuffPlayers(Entity* self) { auto entitiesInProximity = self->GetVar>(u"Players"); for (const auto playerID : entitiesInProximity) { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) { return; diff --git a/dScripts/02_server/Map/AM/AmSkullkinDrill.cpp b/dScripts/02_server/Map/AM/AmSkullkinDrill.cpp index d26218a2..576688e7 100644 --- a/dScripts/02_server/Map/AM/AmSkullkinDrill.cpp +++ b/dScripts/02_server/Map/AM/AmSkullkinDrill.cpp @@ -5,6 +5,7 @@ #include "ProximityMonitorComponent.h" #include "MissionComponent.h" #include "EntityInfo.h" +#include "RenderComponent.h" #include "eStateChangeType.h" void AmSkullkinDrill::OnStartup(Entity* self) { @@ -43,7 +44,7 @@ Entity* AmSkullkinDrill::GetStandObj(Entity* self) { groupName.push_back(myGroup[0][myGroup[0].size() - 1]); - const auto standObjs = EntityManager::Instance()->GetEntitiesInGroup(groupName); + const auto standObjs = Game::entityManager->GetEntitiesInGroup(groupName); if (standObjs.empty()) { return nullptr; @@ -71,7 +72,7 @@ void AmSkullkinDrill::OnSkillEventFired(Entity* self, Entity* caster, const std: } void AmSkullkinDrill::TriggerDrill(Entity* self) { - GameMessages::SendPlayAnimation(self, u"slowdown"); + RenderComponent::PlayAnimation(self, u"slowdown"); self->AddTimer("killDrill", 10.0f); @@ -104,16 +105,16 @@ void AmSkullkinDrill::OnWaypointReached(Entity* self, uint32_t waypointIndex) { info.scale = 3; // Needs the scale, otherwise attacks fail info.spawnerID = self->GetObjectID(); - auto* child = EntityManager::Instance()->CreateEntity(info); + auto* child = Game::entityManager->CreateEntity(info); - EntityManager::Instance()->ConstructEntity(child); + Game::entityManager->ConstructEntity(child); self->SetVar(u"ChildSmash", child->GetObjectID()); child->AddDieCallback([this, self]() { const auto& userID = self->GetVar(u"activaterID"); - auto* player = EntityManager::Instance()->GetEntity(userID); + auto* player = Game::entityManager->GetEntity(userID); if (player == nullptr) { return; @@ -171,7 +172,7 @@ void AmSkullkinDrill::OnArrived(Entity* self, uint32_t waypointIndex) { auto* standObj = GetStandObj(self); if (waypointIndex == 1) { - GameMessages::SendPlayAnimation(self, u"no-spin"); + RenderComponent::PlayAnimation(self, u"no-spin"); GameMessages::SendStopFXEffect(self, true, "active"); GameMessages::SendPlayFXEffect(self->GetObjectID(), -1, u"indicator", "indicator"); @@ -179,7 +180,7 @@ void AmSkullkinDrill::OnArrived(Entity* self, uint32_t waypointIndex) { const auto playerID = self->GetVar(u"userID"); - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player != nullptr) { PlayAnim(self, player, "spinjitzu-staff-end"); @@ -191,14 +192,14 @@ void AmSkullkinDrill::OnArrived(Entity* self, uint32_t waypointIndex) { return; } else { - GameMessages::SendPlayAnimation(self, u"idle"); + RenderComponent::PlayAnimation(self, u"idle"); GameMessages::SendPlayFXEffect(self->GetObjectID(), -1, u"spin", "active"); GameMessages::SendStopFXEffect(self, true, "indicator"); } } void AmSkullkinDrill::PlayCinematic(Entity* self) { - auto* player = EntityManager::Instance()->GetEntity(self->GetVar(u"userID")); + auto* player = Game::entityManager->GetEntity(self->GetVar(u"userID")); if (player == nullptr) { return; @@ -216,7 +217,7 @@ void AmSkullkinDrill::PlayCinematic(Entity* self) { void AmSkullkinDrill::PlayAnim(Entity* self, Entity* player, const std::string& animName) { const auto animTime = animName == "spinjitzu-staff-end" ? 0.5f : 1.0f; - GameMessages::SendPlayAnimation(player, GeneralUtils::ASCIIToUTF16(animName)); + RenderComponent::PlayAnimation(player, animName); self->AddTimer("AnimDone_" + animName, animTime); } @@ -234,7 +235,7 @@ void AmSkullkinDrill::OnHitOrHealResult(Entity* self, Entity* attacker, int32_t const auto activaterID = self->GetVar(u"activaterID"); - auto* activator = EntityManager::Instance()->GetEntity(activaterID); + auto* activator = Game::entityManager->GetEntity(activaterID); // TODO: Missions if (activator != nullptr) { @@ -262,7 +263,7 @@ void AmSkullkinDrill::OnTimerDone(Entity* self, std::string timerName) { if (timerName == "killDrill") { const auto childID = self->GetVar(u"ChildSmash"); - auto* child = EntityManager::Instance()->GetEntity(childID); + auto* child = Game::entityManager->GetEntity(childID); if (child != nullptr) { child->Smash(self->GetObjectID(), eKillType::SILENT); @@ -300,7 +301,7 @@ void AmSkullkinDrill::OnTimerDone(Entity* self, std::string timerName) { const auto playerID = self->GetVar(u"userID"); - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) { return; @@ -309,7 +310,7 @@ void AmSkullkinDrill::OnTimerDone(Entity* self, std::string timerName) { if (animName == "spinjitzu-staff-windup") { TriggerDrill(self); - GameMessages::SendPlayAnimation(player, u"spinjitzu-staff-loop"); + RenderComponent::PlayAnimation(player, u"spinjitzu-staff-loop"); } else if (animName == "spinjitzu-staff-end") { FreezePlayer(self, player, false); diff --git a/dScripts/02_server/Map/AM/AmSkullkinDrillStand.cpp b/dScripts/02_server/Map/AM/AmSkullkinDrillStand.cpp index 628d616a..5493dc24 100644 --- a/dScripts/02_server/Map/AM/AmSkullkinDrillStand.cpp +++ b/dScripts/02_server/Map/AM/AmSkullkinDrillStand.cpp @@ -1,6 +1,8 @@ #include "AmSkullkinDrillStand.h" #include "GameMessages.h" #include "dpEntity.h" +#include "Entity.h" +#include "RenderComponent.h" void AmSkullkinDrillStand::OnStartup(Entity* self) { self->SetVar(u"bActive", true); @@ -31,5 +33,5 @@ void AmSkullkinDrillStand::OnProximityUpdate(Entity* self, Entity* entering, std GameMessages::SendPlayFXEffect(entering->GetObjectID(), 1378, u"create", "pushBack"); - GameMessages::SendPlayAnimation(entering, u"knockback-recovery"); + RenderComponent::PlayAnimation(entering, u"knockback-recovery"); } diff --git a/dScripts/02_server/Map/AM/AmSkullkinTower.cpp b/dScripts/02_server/Map/AM/AmSkullkinTower.cpp index 01acdeaf..0c0f7515 100644 --- a/dScripts/02_server/Map/AM/AmSkullkinTower.cpp +++ b/dScripts/02_server/Map/AM/AmSkullkinTower.cpp @@ -5,6 +5,7 @@ #include "EntityInfo.h" #include "GameMessages.h" #include "MissionComponent.h" +#include "RenderComponent.h" void AmSkullkinTower::OnStartup(Entity* self) { self->SetProximityRadius(20, "Tower"); @@ -63,9 +64,9 @@ void AmSkullkinTower::SpawnLegs(Entity* self, const std::string& loc) { info.rot = NiQuaternion::LookAt(info.pos, self->GetPosition()); - auto* entity = EntityManager::Instance()->CreateEntity(info); + auto* entity = Game::entityManager->CreateEntity(info); - EntityManager::Instance()->ConstructEntity(entity); + Game::entityManager->ConstructEntity(entity); OnChildLoaded(self, entity); } @@ -80,7 +81,7 @@ void AmSkullkinTower::OnChildLoaded(Entity* self, Entity* child) { const auto selfID = self->GetObjectID(); child->AddDieCallback([this, selfID, child]() { - auto* self = EntityManager::Instance()->GetEntity(selfID); + auto* self = Game::entityManager->GetEntity(selfID); auto* destroyableComponent = child->GetComponent(); if (destroyableComponent == nullptr || self == nullptr) { @@ -117,13 +118,13 @@ void AmSkullkinTower::OnChildRemoved(Entity* self, Entity* child) { self->SetVar(u"legTable", legTable); if (legTable.size() == 2) { - GameMessages::SendPlayAnimation(self, u"wobble-1"); + RenderComponent::PlayAnimation(self, u"wobble-1"); } else if (legTable.size() == 1) { - GameMessages::SendPlayAnimation(self, u"wobble-2"); + RenderComponent::PlayAnimation(self, u"wobble-2"); } else if (legTable.empty()) { const auto animTime = 2.5f; - GameMessages::SendPlayAnimation(self, u"fall"); + RenderComponent::PlayAnimation(self, u"fall"); self->AddTimer("spawnGuys", animTime - 0.2f); @@ -156,7 +157,7 @@ void AmSkullkinTower::OnChildRemoved(Entity* self, Entity* child) { const auto& players = self->GetVar>(u"Players"); for (const auto& playerID : players) { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) { continue; @@ -232,9 +233,9 @@ void AmSkullkinTower::OnTimerDone(Entity* self, std::string timerName) { for (size_t i = 0; i < 2; i++) { info.pos.x += i * 2; // Just to set the apart a bit - auto* entity = EntityManager::Instance()->CreateEntity(info); + auto* entity = Game::entityManager->CreateEntity(info); - EntityManager::Instance()->ConstructEntity(entity); + Game::entityManager->ConstructEntity(entity); } self->AddTimer("killTower", 0.7f); diff --git a/dScripts/02_server/Map/FV/EnemyRoninSpawner.cpp b/dScripts/02_server/Map/FV/EnemyRoninSpawner.cpp index cfc58fa0..ddaafc65 100644 --- a/dScripts/02_server/Map/FV/EnemyRoninSpawner.cpp +++ b/dScripts/02_server/Map/FV/EnemyRoninSpawner.cpp @@ -22,13 +22,13 @@ void EnemyRoninSpawner::OnTimerDone(Entity* self, std::string timerName) { info.rot = self->GetRotation(); info.spawnerID = self->GetObjectID(); - auto* spawnedEntity = EntityManager::Instance()->CreateEntity(info); + auto* spawnedEntity = Game::entityManager->CreateEntity(info); if (spawnedEntity == nullptr) { return; } - EntityManager::Instance()->ConstructEntity(spawnedEntity); + Game::entityManager->ConstructEntity(spawnedEntity); spawnedEntity->AddCallbackTimer(60, [spawnedEntity]() { spawnedEntity->Smash(spawnedEntity->GetObjectID()); diff --git a/dScripts/02_server/Map/FV/FvHorsemenTrigger.cpp b/dScripts/02_server/Map/FV/FvHorsemenTrigger.cpp index e87d9629..04bf94c5 100644 --- a/dScripts/02_server/Map/FV/FvHorsemenTrigger.cpp +++ b/dScripts/02_server/Map/FV/FvHorsemenTrigger.cpp @@ -33,7 +33,7 @@ FvHorsemenTrigger::OnFireEventServerSide(Entity* self, Entity* sender, std::stri if (args == "HorsemenDeath") { for (const auto& playerId : self->GetVar>(u"players")) { - auto* player = EntityManager::Instance()->GetEntity(playerId); + auto* player = Game::entityManager->GetEntity(playerId); if (player == nullptr) { continue; diff --git a/dScripts/02_server/Map/FV/ImgBrickConsoleQB.cpp b/dScripts/02_server/Map/FV/ImgBrickConsoleQB.cpp index 7d86cc73..cf065ad6 100644 --- a/dScripts/02_server/Map/FV/ImgBrickConsoleQB.cpp +++ b/dScripts/02_server/Map/FV/ImgBrickConsoleQB.cpp @@ -23,7 +23,7 @@ void ImgBrickConsoleQB::OnUse(Entity* self, Entity* user) { if (rebuildComponent->GetState() == eRebuildState::COMPLETED) { if (!self->GetNetworkVar(u"used")) { - const auto consoles = EntityManager::Instance()->GetEntitiesInGroup("Console"); + const auto consoles = Game::entityManager->GetEntitiesInGroup("Console"); auto bothBuilt = false; @@ -59,7 +59,7 @@ void ImgBrickConsoleQB::OnUse(Entity* self, Entity* user) { onFX = 2779; } - const auto& facility = EntityManager::Instance()->GetEntitiesInGroup("FacilityPipes"); + const auto& facility = Game::entityManager->GetEntitiesInGroup("FacilityPipes"); if (!facility.empty()) { GameMessages::SendStopFXEffect(facility[0], true, location + "PipeEnergy"); @@ -93,31 +93,31 @@ void ImgBrickConsoleQB::OnUse(Entity* self, Entity* user) { } void ImgBrickConsoleQB::SpawnBrick(Entity* self) { - const auto netDevil = dZoneManager::Instance()->GetSpawnersByName("MaelstromBug"); + const auto netDevil = Game::zoneManager->GetSpawnersByName("MaelstromBug"); if (!netDevil.empty()) { netDevil[0]->Reset(); netDevil[0]->Deactivate(); } - const auto brick = dZoneManager::Instance()->GetSpawnersByName("Imagination"); + const auto brick = Game::zoneManager->GetSpawnersByName("Imagination"); if (!brick.empty()) { brick[0]->Activate(); } } void ImgBrickConsoleQB::SmashCanister(Entity* self) { - const auto brick = EntityManager::Instance()->GetEntitiesInGroup("Imagination"); + const auto brick = Game::entityManager->GetEntitiesInGroup("Imagination"); if (!brick.empty()) { GameMessages::SendPlayFXEffect(brick[0]->GetObjectID(), 122, u"create", "bluebrick"); GameMessages::SendPlayFXEffect(brick[0]->GetObjectID(), 1034, u"cast", "imaginationexplosion"); } - const auto canisters = EntityManager::Instance()->GetEntitiesInGroup("Canister"); + const auto canisters = Game::entityManager->GetEntitiesInGroup("Canister"); for (auto* canister : canisters) { canister->Smash(canister->GetObjectID(), eKillType::VIOLENT); } - const auto canister = dZoneManager::Instance()->GetSpawnersByName("BrickCanister"); + const auto canister = Game::zoneManager->GetSpawnersByName("BrickCanister"); if (!canister.empty()) { canister[0]->Reset(); canister[0]->Deactivate(); @@ -135,14 +135,14 @@ void ImgBrickConsoleQB::OnRebuildComplete(Entity* self, Entity* target) { energyFX = 2778; } - const auto& facility = EntityManager::Instance()->GetEntitiesInGroup("FacilityPipes"); + const auto& facility = Game::entityManager->GetEntitiesInGroup("FacilityPipes"); if (!facility.empty()) { GameMessages::SendStopFXEffect(facility[0], true, location + "PipeOff"); GameMessages::SendPlayFXEffect(facility[0]->GetObjectID(), energyFX, u"create", location + "PipeEnergy"); } - const auto consoles = EntityManager::Instance()->GetEntitiesInGroup("Console"); + const auto consoles = Game::entityManager->GetEntitiesInGroup("Console"); for (auto* console : consoles) { auto* consoleRebuildComponent = console->GetComponent(); @@ -179,7 +179,7 @@ void ImgBrickConsoleQB::OnDie(Entity* self, Entity* killer) { offFX = 2777; } - const auto& facility = EntityManager::Instance()->GetEntitiesInGroup("FacilityPipes"); + const auto& facility = Game::entityManager->GetEntitiesInGroup("FacilityPipes"); if (!facility.empty()) { GameMessages::SendStopFXEffect(facility[0], true, location + "PipeEnergy"); @@ -195,29 +195,29 @@ void ImgBrickConsoleQB::OnDie(Entity* self, Entity* killer) { const auto firstPipe = pipeGroup + "1"; - const auto samePipeSpawner = dZoneManager::Instance()->GetSpawnersByName(myGroup); + const auto samePipeSpawner = Game::zoneManager->GetSpawnersByName(myGroup); if (!samePipeSpawner.empty()) { samePipeSpawner[0]->Reset(); samePipeSpawner[0]->Deactivate(); } - const auto firstPipeSpawner = dZoneManager::Instance()->GetSpawnersByName(firstPipe); + const auto firstPipeSpawner = Game::zoneManager->GetSpawnersByName(firstPipe); if (!firstPipeSpawner.empty()) { firstPipeSpawner[0]->Activate(); } - const auto netdevil = dZoneManager::Instance()->GetSpawnersByName("Imagination"); + const auto netdevil = Game::zoneManager->GetSpawnersByName("Imagination"); if (!netdevil.empty()) { netdevil[0]->Reset(); netdevil[0]->Deactivate(); } - const auto brick = dZoneManager::Instance()->GetSpawnersByName("MaelstromBug"); + const auto brick = Game::zoneManager->GetSpawnersByName("MaelstromBug"); if (!brick.empty()) { brick[0]->Activate(); } - const auto canister = dZoneManager::Instance()->GetSpawnersByName("BrickCanister"); + const auto canister = Game::zoneManager->GetSpawnersByName("BrickCanister"); if (!canister.empty()) { canister[0]->Activate(); } @@ -233,7 +233,7 @@ void ImgBrickConsoleQB::OnTimerDone(Entity* self, std::string timerName) { self->Smash(self->GetObjectID(), eKillType::SILENT); } } else if (timerName == "Die") { - const auto consoles = EntityManager::Instance()->GetEntitiesInGroup("Console"); + const auto consoles = Game::entityManager->GetEntitiesInGroup("Console"); for (auto* console : consoles) { console->Smash(console->GetObjectID(), eKillType::VIOLENT); diff --git a/dScripts/02_server/Map/FV/Racing/RaceMaelstromGeiser.cpp b/dScripts/02_server/Map/FV/Racing/RaceMaelstromGeiser.cpp index 155be92b..48d1b255 100644 --- a/dScripts/02_server/Map/FV/Racing/RaceMaelstromGeiser.cpp +++ b/dScripts/02_server/Map/FV/Racing/RaceMaelstromGeiser.cpp @@ -29,7 +29,7 @@ void RaceMaelstromGeiser::OnProximityUpdate(Entity* self, Entity* entering, std: Entity* player; if (possessableComponent != nullptr) { - player = EntityManager::Instance()->GetEntity(possessableComponent->GetPossessor()); + player = Game::entityManager->GetEntity(possessableComponent->GetPossessor()); if (player == nullptr) { return; @@ -43,7 +43,7 @@ void RaceMaelstromGeiser::OnProximityUpdate(Entity* self, Entity* entering, std: return; } - vehicle = EntityManager::Instance()->GetEntity(possessorComponent->GetPossessable()); + vehicle = Game::entityManager->GetEntity(possessorComponent->GetPossessable()); if (vehicle == nullptr) { return; @@ -57,7 +57,7 @@ void RaceMaelstromGeiser::OnProximityUpdate(Entity* self, Entity* entering, std: GameMessages::SendDie(vehicle, self->GetObjectID(), LWOOBJID_EMPTY, true, eKillType::VIOLENT, u"", 0, 0, 0, true, false, 0); - auto* zoneController = dZoneManager::Instance()->GetZoneControlObject(); + auto* zoneController = Game::zoneManager->GetZoneControlObject(); auto* racingControlComponent = zoneController->GetComponent(); diff --git a/dScripts/02_server/Map/GF/GfCaptainsCannon.cpp b/dScripts/02_server/Map/GF/GfCaptainsCannon.cpp index 13e2e4e5..242bfe4f 100644 --- a/dScripts/02_server/Map/GF/GfCaptainsCannon.cpp +++ b/dScripts/02_server/Map/GF/GfCaptainsCannon.cpp @@ -2,6 +2,7 @@ #include "GameMessages.h" #include "EntityManager.h" #include "MissionComponent.h" +#include "RenderComponent.h" #include "eTerminateType.h" #include "eStateChangeType.h" @@ -29,7 +30,7 @@ void GfCaptainsCannon::OnUse(Entity* self, Entity* user) { GameMessages::SendTeleport(user->GetObjectID(), position, rotation, user->GetSystemAddress()); - GameMessages::SendPlayAnimation(user, u"cannon-strike-no-equip"); + RenderComponent::PlayAnimation(user, u"cannon-strike-no-equip"); GameMessages::SendPlayFXEffect(user->GetObjectID(), 6039, u"hook", "hook", LWOOBJID_EMPTY, 1, 1, true); @@ -39,7 +40,7 @@ void GfCaptainsCannon::OnUse(Entity* self, Entity* user) { void GfCaptainsCannon::OnTimerDone(Entity* self, std::string timerName) { const auto playerId = self->GetVar(u"userID"); - auto* player = EntityManager::Instance()->GetEntity(playerId); + auto* player = Game::entityManager->GetEntity(playerId); if (player == nullptr) { self->SetVar(u"bIsInUse", false); @@ -55,12 +56,12 @@ void GfCaptainsCannon::OnTimerDone(Entity* self, std::string timerName) { self->AddTimer("cinematicTimer", cinematicTime); - const auto sharkObjects = EntityManager::Instance()->GetEntitiesInGroup("SharkCannon"); + const auto sharkObjects = Game::entityManager->GetEntitiesInGroup("SharkCannon"); for (auto* shark : sharkObjects) { if (shark->GetLOT() != m_SharkItemID) continue; - GameMessages::SendPlayAnimation(shark, u"cannon"); + RenderComponent::PlayAnimation(shark, u"cannon"); } GameMessages::SendPlay2DAmbientSound(player, "{7457d85c-4537-4317-ac9d-2f549219ea87}"); diff --git a/dScripts/02_server/Map/GF/GfTikiTorch.cpp b/dScripts/02_server/Map/GF/GfTikiTorch.cpp index 8528192f..e61abd76 100644 --- a/dScripts/02_server/Map/GF/GfTikiTorch.cpp +++ b/dScripts/02_server/Map/GF/GfTikiTorch.cpp @@ -5,6 +5,7 @@ #include "RenderComponent.h" #include "eMissionTaskType.h" #include "eReplicaComponentType.h" +#include "RenderComponent.h" #include "eTerminateType.h" void GfTikiTorch::OnStartup(Entity* self) { @@ -17,7 +18,7 @@ void GfTikiTorch::OnUse(Entity* self, Entity* killer) { return; } - GameMessages::SendPlayAnimation(self, u"interact"); + RenderComponent::PlayAnimation(self, u"interact"); self->SetI64(u"userID", killer->GetObjectID()); for (int i = 0; i < m_numspawn; i++) { @@ -31,7 +32,7 @@ void GfTikiTorch::OnTimerDone(Entity* self, std::string timerName) { if (timerName == "Relight") { LightTorch(self); } else if (timerName == "InteractionCooldown") { - Entity* player = EntityManager::Instance()->GetEntity(self->GetI64(u"userID")); + Entity* player = Game::entityManager->GetEntity(self->GetI64(u"userID")); if (player != nullptr && player->GetCharacter()) { GameMessages::SendTerminateInteraction(player->GetObjectID(), eTerminateType::FROM_INTERACTION, self->GetObjectID()); @@ -56,7 +57,7 @@ void GfTikiTorch::LightTorch(Entity* self) { void GfTikiTorch::OnSkillEventFired(Entity* self, Entity* caster, const std::string& message) { if (self->GetBoolean(u"isBurning") && message == "waterspray") { - GameMessages::SendPlayAnimation(self, u"water"); + RenderComponent::PlayAnimation(self, u"water"); auto* renderComponent = self->GetComponent(); if (renderComponent != nullptr) { diff --git a/dScripts/02_server/Map/GF/MastTeleport.cpp b/dScripts/02_server/Map/GF/MastTeleport.cpp index 97b126b4..29df4bf5 100644 --- a/dScripts/02_server/Map/GF/MastTeleport.cpp +++ b/dScripts/02_server/Map/GF/MastTeleport.cpp @@ -10,6 +10,7 @@ #define _USE_MATH_DEFINES #include #endif +#include "RenderComponent.h" void MastTeleport::OnStartup(Entity* self) { self->SetNetworkVar(u"hookPreconditions", "154;44", UNASSIGNED_SYSTEM_ADDRESS); @@ -32,7 +33,7 @@ void MastTeleport::OnRebuildComplete(Entity* self, Entity* target) { void MastTeleport::OnTimerDone(Entity* self, std::string timerName) { const auto playerId = self->GetVar(u"userID"); - auto* player = EntityManager::Instance()->GetEntity(playerId); + auto* player = Game::entityManager->GetEntity(playerId); if (player == nullptr) return; @@ -42,12 +43,7 @@ void MastTeleport::OnTimerDone(Entity* self, std::string timerName) { GameMessages::SendTeleport(playerId, position, rotation, player->GetSystemAddress(), true); - // Hacky fix for odd rotations - if (self->GetVar(u"MastName") != u"Jail") { - GameMessages::SendOrientToAngle(playerId, true, (M_PI / 180) * 140.0f, player->GetSystemAddress()); - } else { - GameMessages::SendOrientToAngle(playerId, true, (M_PI / 180) * 100.0f, player->GetSystemAddress()); - } + GameMessages::SendTeleport(playerId, position, rotation, player->GetSystemAddress(), true); const auto cinematic = GeneralUtils::UTF16ToWTF8(self->GetVar(u"Cinematic")); const auto leanIn = self->GetVar(u"LeanIn"); @@ -60,11 +56,12 @@ void MastTeleport::OnTimerDone(Entity* self, std::string timerName) { GameMessages::SendPlayFXEffect(playerId, 6039, u"hook", "hook", LWOOBJID_EMPTY, 1, 1, true); - GameMessages::SendPlayAnimation(player, u"crow-swing-no-equip", 4.0f); + float animationTime = 6.25f; + animationTime = RenderComponent::PlayAnimation(player, "crow-swing-no-equip", 4.0f); - GameMessages::SendPlayAnimation(self, u"swing"); + RenderComponent::PlayAnimation(self, u"swing"); - self->AddTimer("PlayerAnimDone", 6.25f); + self->AddTimer("PlayerAnimDone", animationTime); } else if (timerName == "PlayerAnimDone") { GameMessages::SendStopFXEffect(player, true, "hook"); @@ -91,6 +88,6 @@ void MastTeleport::OnTimerDone(Entity* self, std::string timerName) { ); auto* destroyableComponent = player->GetComponent(); if (destroyableComponent) destroyableComponent->SetStatusImmunity(eStateChangeType::POP, true, true, true, true, true, false, false, true, true); - EntityManager::Instance()->SerializeEntity(player); + Game::entityManager->SerializeEntity(player); } } diff --git a/dScripts/02_server/Map/General/BankInteractServer.cpp b/dScripts/02_server/Map/General/BankInteractServer.cpp index b96187cf..9b563491 100644 --- a/dScripts/02_server/Map/General/BankInteractServer.cpp +++ b/dScripts/02_server/Map/General/BankInteractServer.cpp @@ -1,24 +1,24 @@ #include "BankInteractServer.h" #include "GameMessages.h" #include "Entity.h" -#include "AMFFormat.h" +#include "Amf3.h" void BankInteractServer::OnUse(Entity* self, Entity* user) { AMFArrayValue args; - AMFStringValue* bank = new AMFStringValue(); - bank->SetStringValue("bank"); - args.InsertValue("state", bank); - GameMessages::SendUIMessageServerToSingleClient(user, user->GetSystemAddress(), "pushGameState", &args); + args.Insert("state", "bank"); + + GameMessages::SendUIMessageServerToSingleClient(user, user->GetSystemAddress(), "pushGameState", args); } void BankInteractServer::OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2, int32_t param3) { if (args == "ToggleBank") { AMFArrayValue args; - args.InsertValue("visible", new AMFFalseValue()); - GameMessages::SendUIMessageServerToSingleClient(sender, sender->GetSystemAddress(), "ToggleBank", &args); + args.Insert("visible", false); + + GameMessages::SendUIMessageServerToSingleClient(sender, sender->GetSystemAddress(), "ToggleBank", args); GameMessages::SendNotifyClientObject(self->GetObjectID(), u"CloseBank", 0, 0, LWOOBJID_EMPTY, "", sender->GetSystemAddress()); } diff --git a/dScripts/02_server/Map/General/ExplodingAsset.cpp b/dScripts/02_server/Map/General/ExplodingAsset.cpp index 16340ee6..ee8f8e68 100644 --- a/dScripts/02_server/Map/General/ExplodingAsset.cpp +++ b/dScripts/02_server/Map/General/ExplodingAsset.cpp @@ -4,6 +4,7 @@ #include "MissionComponent.h" #include "SkillComponent.h" #include "eMissionTaskType.h" +#include "RenderComponent.h" //TODO: this has to be updated so that you only get killed if you're in a certain radius. //And so that all entities in a certain radius are killed, not just the attacker. @@ -69,23 +70,6 @@ void ExplodingAsset::OnHit(Entity* self, Entity* attacker) { } void ExplodingAsset::OnProximityUpdate(Entity* self, Entity* entering, std::string name, std::string status) { - /* - if msg.objId:BelongsToFaction{factionID = 1}.bIsInFaction then - if (msg.status == "ENTER") then - self:PlayAnimation{ animationID = "bounce" } - self:PlayFXEffect{ name = "bouncin", effectType = "anim" } - self:SetVar("playersNearChest", (self:GetVar("playersNearChest") + 1 )) - elseif (msg.status == "LEAVE") then - self:SetVar("playersNearChest", (self:GetVar("playersNearChest") - 1 )) - if self:GetVar("playersNearChest") < 1 then - self:PlayAnimation{ animationID = "idle" } - self:StopFXEffect{ name = "bouncin" } - self:SetVar("playersNearChest", 0) - end - end - end - */ - auto* destuctableComponent = entering->GetComponent(); if (destuctableComponent == nullptr) return; @@ -95,14 +79,14 @@ void ExplodingAsset::OnProximityUpdate(Entity* self, Entity* entering, std::stri if (!std::count(factions.begin(), factions.end(), 1)) return; if (status == "ENTER") { - GameMessages::SendPlayAnimation(self, u"bounce"); + RenderComponent::PlayAnimation(self, u"bounce"); GameMessages::SendPlayFXEffect(self, -1, u"anim", "bouncin", LWOOBJID_EMPTY, 1, 1, true); self->SetVar(u"playersNearChest", self->GetVar(u"playersNearChest") + 1); } else if (status == "LEAVE") { self->SetVar(u"playersNearChest", self->GetVar(u"playersNearChest") - 1); if (self->GetVar(u"playersNearChest") < 1) { - GameMessages::SendPlayAnimation(self, u"idle"); + RenderComponent::PlayAnimation(self, u"idle"); GameMessages::SendStopFXEffect(self, true, "bouncin"); self->SetVar(u"playersNearChest", 0); } diff --git a/dScripts/02_server/Map/General/ForceVolumeServer.cpp b/dScripts/02_server/Map/General/ForceVolumeServer.cpp index ed9024c1..7febe87e 100644 --- a/dScripts/02_server/Map/General/ForceVolumeServer.cpp +++ b/dScripts/02_server/Map/General/ForceVolumeServer.cpp @@ -18,5 +18,5 @@ void ForceVolumeServer::OnStartup(Entity* self) { phantomPhysicsComponent->SetDirection({ forceX, forceY, forceZ }); phantomPhysicsComponent->SetPhysicsEffectActive(true); - EntityManager::Instance()->SerializeEntity(self); + Game::entityManager->SerializeEntity(self); } diff --git a/dScripts/02_server/Map/General/MailBoxServer.cpp b/dScripts/02_server/Map/General/MailBoxServer.cpp index c2534f3e..53f3b3a2 100644 --- a/dScripts/02_server/Map/General/MailBoxServer.cpp +++ b/dScripts/02_server/Map/General/MailBoxServer.cpp @@ -1,19 +1,20 @@ #include "MailBoxServer.h" -#include "AMFFormat.h" +#include "Amf3.h" #include "GameMessages.h" +#include "Entity.h" void MailBoxServer::OnUse(Entity* self, Entity* user) { - AMFStringValue* value = new AMFStringValue(); - value->SetStringValue("Mail"); AMFArrayValue args; - args.InsertValue("state", value); - GameMessages::SendUIMessageServerToSingleClient(user, user->GetSystemAddress(), "pushGameState", &args); + + args.Insert("state", "Mail"); + + GameMessages::SendUIMessageServerToSingleClient(user, user->GetSystemAddress(), "pushGameState", args); } void MailBoxServer::OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2, int32_t param3) { if (args == "toggleMail") { AMFArrayValue args; - args.InsertValue("visible", new AMFFalseValue()); - GameMessages::SendUIMessageServerToSingleClient(sender, sender->GetSystemAddress(), "ToggleMail", &args); + args.Insert("visible", false); + GameMessages::SendUIMessageServerToSingleClient(sender, sender->GetSystemAddress(), "ToggleMail", args); } } diff --git a/dScripts/02_server/Map/General/Ninjago/NjIceRailActivator.cpp b/dScripts/02_server/Map/General/Ninjago/NjIceRailActivator.cpp index 2549cd0f..f7f6a117 100644 --- a/dScripts/02_server/Map/General/Ninjago/NjIceRailActivator.cpp +++ b/dScripts/02_server/Map/General/Ninjago/NjIceRailActivator.cpp @@ -1,6 +1,8 @@ #include "NjIceRailActivator.h" #include "EntityManager.h" #include "GameMessages.h" +#include "Entity.h" +#include "RenderComponent.h" void NjIceRailActivator::OnPlayerRailArrived(Entity* self, Entity* sender, const std::u16string& pathName, int32_t waypoint) { @@ -8,13 +10,13 @@ void NjIceRailActivator::OnPlayerRailArrived(Entity* self, Entity* sender, const if (breakPoint == waypoint) { const auto& blockGroup = self->GetVar(BlockGroupVariable); - for (auto* block : EntityManager::Instance()->GetEntitiesInGroup(GeneralUtils::UTF16ToWTF8(blockGroup))) { - GameMessages::SendPlayAnimation(block, u"explode"); + for (auto* block : Game::entityManager->GetEntitiesInGroup(GeneralUtils::UTF16ToWTF8(blockGroup))) { + RenderComponent::PlayAnimation(block, u"explode"); const auto blockID = block->GetObjectID(); self->AddCallbackTimer(1.0f, [self, blockID]() { - auto* block = EntityManager::Instance()->GetEntity(blockID); + auto* block = Game::entityManager->GetEntity(blockID); if (block != nullptr) { block->Kill(self); diff --git a/dScripts/02_server/Map/General/Ninjago/NjRailPostServer.cpp b/dScripts/02_server/Map/General/Ninjago/NjRailPostServer.cpp index 2c435705..f47f7e7b 100644 --- a/dScripts/02_server/Map/General/Ninjago/NjRailPostServer.cpp +++ b/dScripts/02_server/Map/General/Ninjago/NjRailPostServer.cpp @@ -42,7 +42,7 @@ void NjRailPostServer::OnRebuildNotifyState(Entity* self, eRebuildState state) { Entity* NjRailPostServer::GetRelatedRail(Entity* self) { const auto& railGroup = self->GetVar(RailGroupVariable); if (!railGroup.empty()) { - for (auto* entity : EntityManager::Instance()->GetEntitiesInGroup(GeneralUtils::UTF16ToWTF8(railGroup))) { + for (auto* entity : Game::entityManager->GetEntitiesInGroup(GeneralUtils::UTF16ToWTF8(railGroup))) { return entity; } } diff --git a/dScripts/02_server/Map/General/PetDigServer.cpp b/dScripts/02_server/Map/General/PetDigServer.cpp index 8c819a8d..0ea78e4f 100644 --- a/dScripts/02_server/Map/General/PetDigServer.cpp +++ b/dScripts/02_server/Map/General/PetDigServer.cpp @@ -48,8 +48,8 @@ void PetDigServer::OnStartup(Entity* self) { // Reset any bouncers that might've been created by the previous dig if (digInfo.bouncer) { auto bounceNumber = GeneralUtils::UTF16ToWTF8(self->GetVar(u"BouncerNumber")); - auto bouncerSpawners = dZoneManager::Instance()->GetSpawnersByName("PetBouncer" + bounceNumber); - auto switchSpawners = dZoneManager::Instance()->GetSpawnersByName("PetBouncerSwitch" + bounceNumber); + auto bouncerSpawners = Game::zoneManager->GetSpawnersByName("PetBouncer" + bounceNumber); + auto switchSpawners = Game::zoneManager->GetSpawnersByName("PetBouncerSwitch" + bounceNumber); for (auto* bouncerSpawner : bouncerSpawners) { for (auto* bouncer : bouncerSpawner->m_Info.nodes) @@ -95,7 +95,7 @@ void PetDigServer::OnDie(Entity* self, Entity* killer) { // TODO: Reset other pets // Handles smashing leftovers (edge case for the AG X) - auto* xObject = EntityManager::Instance()->GetEntity(self->GetVar(u"X")); + auto* xObject = Game::entityManager->GetEntity(self->GetVar(u"X")); if (xObject != nullptr) { xObject->Smash(xObject->GetObjectID(), eKillType::VIOLENT); } @@ -106,7 +106,7 @@ void PetDigServer::HandleXBuildDig(const Entity* self, Entity* owner, Entity* pe if (playerID == LWOOBJID_EMPTY || playerID != owner->GetObjectID()) return; - auto* playerEntity = EntityManager::Instance()->GetEntity(playerID); + auto* playerEntity = Game::entityManager->GetEntity(playerID); if (!playerEntity || !playerEntity->GetParentUser() || !playerEntity->GetParentUser()->GetLastUsedChar()) return; @@ -134,7 +134,7 @@ void PetDigServer::HandleXBuildDig(const Entity* self, Entity* owner, Entity* pe player->SetPlayerFlag(playerFlag, true); } - auto* xObject = EntityManager::Instance()->GetEntity(self->GetVar(u"X")); + auto* xObject = Game::entityManager->GetEntity(self->GetVar(u"X")); if (xObject != nullptr) { xObject->Smash(xObject->GetObjectID(), eKillType::VIOLENT); } @@ -142,8 +142,8 @@ void PetDigServer::HandleXBuildDig(const Entity* self, Entity* owner, Entity* pe void PetDigServer::HandleBouncerDig(const Entity* self, const Entity* owner) { auto bounceNumber = GeneralUtils::UTF16ToWTF8(self->GetVar(u"BouncerNumber")); - auto bouncerSpawners = dZoneManager::Instance()->GetSpawnersByName("PetBouncer" + bounceNumber); - auto switchSpawners = dZoneManager::Instance()->GetSpawnersByName("PetBouncerSwitch" + bounceNumber); + auto bouncerSpawners = Game::zoneManager->GetSpawnersByName("PetBouncer" + bounceNumber); + auto switchSpawners = Game::zoneManager->GetSpawnersByName("PetBouncerSwitch" + bounceNumber); for (auto* bouncerSpawner : bouncerSpawners) { bouncerSpawner->Activate(); @@ -211,8 +211,8 @@ void PetDigServer::SpawnPet(Entity* self, const Entity* owner, const DigInfo dig new LDFData(u"spawnTimer", 1.0) }; - auto* spawnedPet = EntityManager::Instance()->CreateEntity(info); - EntityManager::Instance()->ConstructEntity(spawnedPet); + auto* spawnedPet = Game::entityManager->CreateEntity(info); + Game::entityManager->ConstructEntity(spawnedPet); } Entity* PetDigServer::GetClosestTresure(NiPoint3 position) { @@ -220,7 +220,7 @@ Entity* PetDigServer::GetClosestTresure(NiPoint3 position) { Entity* closest = nullptr; for (const auto tresureId : treasures) { - auto* tresure = EntityManager::Instance()->GetEntity(tresureId); + auto* tresure = Game::entityManager->GetEntity(tresureId); if (tresure == nullptr) continue; diff --git a/dScripts/02_server/Map/General/PropertyDevice.cpp b/dScripts/02_server/Map/General/PropertyDevice.cpp index 0ad9f5c9..61ebe96e 100644 --- a/dScripts/02_server/Map/General/PropertyDevice.cpp +++ b/dScripts/02_server/Map/General/PropertyDevice.cpp @@ -5,7 +5,7 @@ #include "eMissionState.h" void PropertyDevice::OnStartup(Entity* self) { - auto* zoneControl = EntityManager::Instance()->GetZoneControlEntity(); + auto* zoneControl = Game::entityManager->GetZoneControlEntity(); if (zoneControl != nullptr) { zoneControl->OnFireEventServerSide(self, "CheckForPropertyOwner"); } diff --git a/dScripts/02_server/Map/General/QbSpawner.cpp b/dScripts/02_server/Map/General/QbSpawner.cpp index d5c9d001..6776c8ea 100644 --- a/dScripts/02_server/Map/General/QbSpawner.cpp +++ b/dScripts/02_server/Map/General/QbSpawner.cpp @@ -41,7 +41,7 @@ void QbSpawner::OnTimerDone(Entity* self, std::string timerName) { auto gateObjID = self->GetVar(u"gateObj"); if (!gateObjID) return; - auto* gate = EntityManager::Instance()->GetEntity(gateObjID); + auto* gate = Game::entityManager->GetEntity(gateObjID); if (!gate) return; auto oPos = gate->GetPosition(); @@ -75,12 +75,12 @@ void QbSpawner::OnTimerDone(Entity* self, std::string timerName) { new LDFData(u"mobTableLoc", i) }; - auto* child = EntityManager::Instance()->CreateEntity(info, nullptr, self); - EntityManager::Instance()->ConstructEntity(child); + auto* child = Game::entityManager->CreateEntity(info, nullptr, self); + Game::entityManager->ConstructEntity(child); OnChildLoaded(self, child); } else { - auto* mob = EntityManager::Instance()->GetEntity(mobTable[i]); + auto* mob = Game::entityManager->GetEntity(mobTable[i]); AggroTargetObject(self, mob); } } @@ -100,7 +100,7 @@ void QbSpawner::OnChildLoaded(Entity* self, Entity* child) { const auto selfID = self->GetObjectID(); child->AddDieCallback([this, selfID, child]() { - auto* self = EntityManager::Instance()->GetEntity(selfID); + auto* self = Game::entityManager->GetEntity(selfID); OnChildRemoved(self, child); } ); @@ -120,7 +120,7 @@ void QbSpawner::AggroTargetObject(Entity* self, Entity* enemy) { auto gateObjID = self->GetVar(u"gateObj"); if (gateObjID) { - auto* gate = EntityManager::Instance()->GetEntity(gateObjID); + auto* gate = Game::entityManager->GetEntity(gateObjID); if (gate) { auto* movementAIComponent = enemy->GetComponent(); if (movementAIComponent) movementAIComponent->SetDestination(gate->GetPosition()); diff --git a/dScripts/02_server/Map/General/StoryBoxInteractServer.cpp b/dScripts/02_server/Map/General/StoryBoxInteractServer.cpp index 2683ddd4..9a1a4908 100644 --- a/dScripts/02_server/Map/General/StoryBoxInteractServer.cpp +++ b/dScripts/02_server/Map/General/StoryBoxInteractServer.cpp @@ -2,7 +2,8 @@ #include "Character.h" #include "GameMessages.h" #include "dServer.h" -#include "AMFFormat.h" +#include "Amf3.h" +#include "Entity.h" void StoryBoxInteractServer::OnUse(Entity* self, Entity* user) { if (self->GetVar(u"hasCustomText")) { @@ -11,24 +12,18 @@ void StoryBoxInteractServer::OnUse(Entity* self, Entity* user) { { AMFArrayValue args; - auto* state = new AMFStringValue(); - state->SetStringValue("Story"); + args.Insert("state", "Story"); - args.InsertValue("state", state); - - GameMessages::SendUIMessageServerToSingleClient(user, user->GetSystemAddress(), "pushGameState", &args); + GameMessages::SendUIMessageServerToSingleClient(user, user->GetSystemAddress(), "pushGameState", args); } user->AddCallbackTimer(0.1f, [user, customText]() { AMFArrayValue args; - auto* text = new AMFStringValue(); - text->SetStringValue(customText); + args.Insert("visible", true); + args.Insert("text", customText); - args.InsertValue("visible", new AMFTrueValue()); - args.InsertValue("text", text); - - GameMessages::SendUIMessageServerToSingleClient(user, user->GetSystemAddress(), "ToggleStoryBox", &args); + GameMessages::SendUIMessageServerToSingleClient(user, user->GetSystemAddress(), "ToggleStoryBox", args); }); return; diff --git a/dScripts/02_server/Map/General/WishingWellServer.cpp b/dScripts/02_server/Map/General/WishingWellServer.cpp index 58ce1c72..51f742ec 100644 --- a/dScripts/02_server/Map/General/WishingWellServer.cpp +++ b/dScripts/02_server/Map/General/WishingWellServer.cpp @@ -33,7 +33,7 @@ void WishingWellServer::OnUse(Entity* self, Entity* user) { const auto userID = user->GetObjectID(); self->AddCallbackTimer(10, [self, userID]() { - auto* user = EntityManager::Instance()->GetEntity(userID); + auto* user = Game::entityManager->GetEntity(userID); if (user == nullptr) return; diff --git a/dScripts/02_server/Map/NS/NsConcertChoiceBuildManager.cpp b/dScripts/02_server/Map/NS/NsConcertChoiceBuildManager.cpp index a338d9c9..554eabac 100644 --- a/dScripts/02_server/Map/NS/NsConcertChoiceBuildManager.cpp +++ b/dScripts/02_server/Map/NS/NsConcertChoiceBuildManager.cpp @@ -40,8 +40,8 @@ void NsConcertChoiceBuildManager::SpawnCrate(Entity* self) { new LDFData(u"crateTime", crate.time), }; - auto* spawnedCrate = EntityManager::Instance()->CreateEntity(info); - EntityManager::Instance()->ConstructEntity(spawnedCrate); + auto* spawnedCrate = Game::entityManager->CreateEntity(info); + Game::entityManager->ConstructEntity(spawnedCrate); spawnedCrate->AddDieCallback([self]() { self->CancelAllTimers(); // Don't switch if the crate was smashed @@ -56,7 +56,7 @@ void NsConcertChoiceBuildManager::SpawnCrate(Entity* self) { self->AddCallbackTimer(crate.time, [self]() { auto crateID = self->GetVar(u"currentCrate"); if (crateID != LWOOBJID_EMPTY) { - EntityManager::Instance()->DestroyEntity(crateID); + Game::entityManager->DestroyEntity(crateID); self->SetVar(u"currentCrate", LWOOBJID_EMPTY); } diff --git a/dScripts/02_server/Map/NS/NsLegoClubDoor.cpp b/dScripts/02_server/Map/NS/NsLegoClubDoor.cpp index 56a213b8..35d4735c 100644 --- a/dScripts/02_server/Map/NS/NsLegoClubDoor.cpp +++ b/dScripts/02_server/Map/NS/NsLegoClubDoor.cpp @@ -1,10 +1,10 @@ #include "NsLegoClubDoor.h" #include "dZoneManager.h" #include "GameMessages.h" -#include "AMFFormat.h" +#include "Amf3.h" void NsLegoClubDoor::OnStartup(Entity* self) { - self->SetVar(u"currentZone", (int32_t)dZoneManager::Instance()->GetZoneID().GetMapID()); + self->SetVar(u"currentZone", (int32_t)Game::zoneManager->GetZoneID().GetMapID()); self->SetVar(u"choiceZone", m_ChoiceZoneID); self->SetVar(u"teleportAnim", m_TeleportAnim); self->SetVar(u"teleportString", m_TeleportString); @@ -12,116 +12,56 @@ void NsLegoClubDoor::OnStartup(Entity* self) { args = {}; - AMFStringValue* callbackClient = new AMFStringValue(); - callbackClient->SetStringValue(std::to_string(self->GetObjectID())); - args.InsertValue("callbackClient", callbackClient); + args.Insert("callbackClient", std::to_string(self->GetObjectID())); + args.Insert("strIdentifier", "choiceDoor"); + args.Insert("title", "%[UI_CHOICE_DESTINATION]"); - AMFStringValue* strIdentifier = new AMFStringValue(); - strIdentifier->SetStringValue("choiceDoor"); - args.InsertValue("strIdentifier", strIdentifier); - - AMFStringValue* title = new AMFStringValue(); - title->SetStringValue("%[UI_CHOICE_DESTINATION]"); - args.InsertValue("title", title); - - AMFArrayValue* choiceOptions = new AMFArrayValue(); + AMFArrayValue* choiceOptions = args.InsertArray("options"); { - AMFArrayValue* nsArgs = new AMFArrayValue(); + AMFArrayValue* nsArgs = choiceOptions->PushArray(); - AMFStringValue* image = new AMFStringValue(); - image->SetStringValue("textures/ui/zone_thumnails/Nimbus_Station.dds"); - nsArgs->InsertValue("image", image); - - AMFStringValue* caption = new AMFStringValue(); - caption->SetStringValue("%[UI_CHOICE_NS]"); - nsArgs->InsertValue("caption", caption); - - AMFStringValue* identifier = new AMFStringValue(); - identifier->SetStringValue("zoneID_1200"); - nsArgs->InsertValue("identifier", identifier); - - AMFStringValue* tooltipText = new AMFStringValue(); - tooltipText->SetStringValue("%[UI_CHOICE_NS_HOVER]"); - nsArgs->InsertValue("tooltipText", tooltipText); - - choiceOptions->PushBackValue(nsArgs); + nsArgs->Insert("image", "textures/ui/zone_thumnails/Nimbus_Station.dds"); + nsArgs->Insert("caption", "%[UI_CHOICE_NS]"); + nsArgs->Insert("identifier", "zoneID_1200"); + nsArgs->Insert("tooltipText", "%[UI_CHOICE_NS_HOVER]"); } { - AMFArrayValue* ntArgs = new AMFArrayValue(); + AMFArrayValue* ntArgs = choiceOptions->PushArray(); - AMFStringValue* image = new AMFStringValue(); - image->SetStringValue("textures/ui/zone_thumnails/Nexus_Tower.dds"); - ntArgs->InsertValue("image", image); - - AMFStringValue* caption = new AMFStringValue(); - caption->SetStringValue("%[UI_CHOICE_NT]"); - ntArgs->InsertValue("caption", caption); - - AMFStringValue* identifier = new AMFStringValue(); - identifier->SetStringValue("zoneID_1900"); - ntArgs->InsertValue("identifier", identifier); - - AMFStringValue* tooltipText = new AMFStringValue(); - tooltipText->SetStringValue("%[UI_CHOICE_NT_HOVER]"); - ntArgs->InsertValue("tooltipText", tooltipText); - - choiceOptions->PushBackValue(ntArgs); + ntArgs->Insert("image", "textures/ui/zone_thumnails/Nexus_Tower.dds"); + ntArgs->Insert("caption", "%[UI_CHOICE_NT]"); + ntArgs->Insert("identifier", "zoneID_1900"); + ntArgs->Insert("tooltipText", "%[UI_CHOICE_NT_HOVER]"); } options = choiceOptions; - - args.InsertValue("options", choiceOptions); } void NsLegoClubDoor::OnUse(Entity* self, Entity* user) { auto* player = user; if (CheckChoice(self, player)) { - AMFArrayValue* multiArgs = new AMFArrayValue(); + AMFArrayValue multiArgs; - AMFStringValue* callbackClient = new AMFStringValue(); - callbackClient->SetStringValue(std::to_string(self->GetObjectID())); - multiArgs->InsertValue("callbackClient", callbackClient); - - AMFStringValue* strIdentifier = new AMFStringValue(); - strIdentifier->SetStringValue("choiceDoor"); - multiArgs->InsertValue("strIdentifier", strIdentifier); - - AMFStringValue* title = new AMFStringValue(); - title->SetStringValue("%[UI_CHOICE_DESTINATION]"); - multiArgs->InsertValue("title", title); - - multiArgs->InsertValue("options", options); + multiArgs.Insert("callbackClient", std::to_string(self->GetObjectID())); + multiArgs.Insert("strIdentifier", "choiceDoor"); + multiArgs.Insert("title", "%[UI_CHOICE_DESTINATION]"); + multiArgs.Insert("options", static_cast(options)); GameMessages::SendUIMessageServerToSingleClient(player, player->GetSystemAddress(), "QueueChoiceBox", multiArgs); + + multiArgs.Remove("options", false); // We do not want the local amf to delete the options! } else if (self->GetVar(u"currentZone") != m_ChoiceZoneID) { - AMFArrayValue* multiArgs = new AMFArrayValue(); + AMFArrayValue multiArgs; + multiArgs.Insert("state", "Lobby"); - AMFStringValue* state = new AMFStringValue(); - state->SetStringValue("Lobby"); - multiArgs->InsertValue("state", state); - - AMFArrayValue* context = new AMFArrayValue(); - - AMFStringValue* user = new AMFStringValue(); - user->SetStringValue(std::to_string(player->GetObjectID())); - context->InsertValue("user", user); - - AMFStringValue* callbackObj = new AMFStringValue(); - callbackObj->SetStringValue(std::to_string(self->GetObjectID())); - context->InsertValue("callbackObj", callbackObj); - - AMFStringValue* helpVisible = new AMFStringValue(); - helpVisible->SetStringValue("show"); - context->InsertValue("HelpVisible", helpVisible); - - AMFStringValue* type = new AMFStringValue(); - type->SetStringValue("Lego_Club_Valid"); - context->InsertValue("type", type); - - multiArgs->InsertValue("context", context); + AMFArrayValue* context = multiArgs.InsertArray("context"); + context->Insert("user", std::to_string(player->GetObjectID())); + context->Insert("callbackObj", std::to_string(self->GetObjectID())); + context->Insert("HelpVisible", "show"); + context->Insert("type", "Lego_Club_Valid"); GameMessages::SendUIMessageServerToSingleClient(player, player->GetSystemAddress(), "pushGameState", multiArgs); } else { diff --git a/dScripts/02_server/Map/NS/NsLegoClubDoor.h b/dScripts/02_server/Map/NS/NsLegoClubDoor.h index db1dcae4..5b25ba6d 100644 --- a/dScripts/02_server/Map/NS/NsLegoClubDoor.h +++ b/dScripts/02_server/Map/NS/NsLegoClubDoor.h @@ -2,7 +2,7 @@ #include "CppScripts.h" #include "ChooseYourDestinationNsToNt.h" #include "BaseConsoleTeleportServer.h" -#include "AMFFormat.h" +#include "Amf3.h" class NsLegoClubDoor : public CppScripts::Script, ChooseYourDestinationNsToNt, BaseConsoleTeleportServer { diff --git a/dScripts/02_server/Map/NS/NsLupTeleport.cpp b/dScripts/02_server/Map/NS/NsLupTeleport.cpp index 9cd4359b..c75143fc 100644 --- a/dScripts/02_server/Map/NS/NsLupTeleport.cpp +++ b/dScripts/02_server/Map/NS/NsLupTeleport.cpp @@ -1,10 +1,10 @@ #include "NsLupTeleport.h" #include "dZoneManager.h" #include "GameMessages.h" -#include "AMFFormat.h" +#include "Amf3.h" void NsLupTeleport::OnStartup(Entity* self) { - self->SetVar(u"currentZone", (int32_t)dZoneManager::Instance()->GetZoneID().GetMapID()); + self->SetVar(u"currentZone", (int32_t)Game::zoneManager->GetZoneID().GetMapID()); self->SetVar(u"choiceZone", m_ChoiceZoneID); self->SetVar(u"teleportAnim", m_TeleportAnim); self->SetVar(u"teleportString", m_TeleportString); @@ -12,72 +12,36 @@ void NsLupTeleport::OnStartup(Entity* self) { args = {}; - AMFStringValue* callbackClient = new AMFStringValue(); - callbackClient->SetStringValue(std::to_string(self->GetObjectID())); - args.InsertValue("callbackClient", callbackClient); + args.Insert("callbackClient", std::to_string(self->GetObjectID())); + args.Insert("strIdentifier", "choiceDoor"); + args.Insert("title", "%[UI_CHOICE_DESTINATION]"); - AMFStringValue* strIdentifier = new AMFStringValue(); - strIdentifier->SetStringValue("choiceDoor"); - args.InsertValue("strIdentifier", strIdentifier); - - AMFStringValue* title = new AMFStringValue(); - title->SetStringValue("%[UI_CHOICE_DESTINATION]"); - args.InsertValue("title", title); - - AMFArrayValue* choiceOptions = new AMFArrayValue(); + AMFArrayValue* choiceOptions = args.InsertArray("options"); { - AMFArrayValue* nsArgs = new AMFArrayValue(); + AMFArrayValue* nsArgs = choiceOptions->PushArray(); - AMFStringValue* image = new AMFStringValue(); - image->SetStringValue("textures/ui/zone_thumnails/Nimbus_Station.dds"); - nsArgs->InsertValue("image", image); - - AMFStringValue* caption = new AMFStringValue(); - caption->SetStringValue("%[UI_CHOICE_NS]"); - nsArgs->InsertValue("caption", caption); - - AMFStringValue* identifier = new AMFStringValue(); - identifier->SetStringValue("zoneID_1200"); - nsArgs->InsertValue("identifier", identifier); - - AMFStringValue* tooltipText = new AMFStringValue(); - tooltipText->SetStringValue("%[UI_CHOICE_NS_HOVER]"); - nsArgs->InsertValue("tooltipText", tooltipText); - - choiceOptions->PushBackValue(nsArgs); + nsArgs->Insert("image", "textures/ui/zone_thumnails/Nimbus_Station.dds"); + nsArgs->Insert("caption", "%[UI_CHOICE_NS]"); + nsArgs->Insert("identifier", "zoneID_1200"); + nsArgs->Insert("tooltipText", "%[UI_CHOICE_NS_HOVER]"); } { - AMFArrayValue* ntArgs = new AMFArrayValue(); + AMFArrayValue* ntArgs = choiceOptions->PushArray(); - AMFStringValue* image = new AMFStringValue(); - image->SetStringValue("textures/ui/zone_thumnails/Nexus_Tower.dds"); - ntArgs->InsertValue("image", image); - - AMFStringValue* caption = new AMFStringValue(); - caption->SetStringValue("%[UI_CHOICE_NT]"); - ntArgs->InsertValue("caption", caption); - - AMFStringValue* identifier = new AMFStringValue(); - identifier->SetStringValue("zoneID_1900"); - ntArgs->InsertValue("identifier", identifier); - - AMFStringValue* tooltipText = new AMFStringValue(); - tooltipText->SetStringValue("%[UI_CHOICE_NT_HOVER]"); - ntArgs->InsertValue("tooltipText", tooltipText); - - choiceOptions->PushBackValue(ntArgs); + ntArgs->Insert("image", "textures/ui/zone_thumnails/Nexus_Tower.dds"); + ntArgs->Insert("caption", "%[UI_CHOICE_NT]"); + ntArgs->Insert("identifier", "zoneID_1900"); + ntArgs->Insert("tooltipText", "%[UI_CHOICE_NT_HOVER]"); } - - args.InsertValue("options", choiceOptions); } void NsLupTeleport::OnUse(Entity* self, Entity* user) { auto* player = user; if (CheckChoice(self, player)) { - GameMessages::SendUIMessageServerToSingleClient(player, player->GetSystemAddress(), "QueueChoiceBox", &args); + GameMessages::SendUIMessageServerToSingleClient(player, player->GetSystemAddress(), "QueueChoiceBox", args); } else { BaseOnUse(self, player); } diff --git a/dScripts/02_server/Map/NS/NsLupTeleport.h b/dScripts/02_server/Map/NS/NsLupTeleport.h index 28bab016..385e92c7 100644 --- a/dScripts/02_server/Map/NS/NsLupTeleport.h +++ b/dScripts/02_server/Map/NS/NsLupTeleport.h @@ -2,7 +2,7 @@ #include "CppScripts.h" #include "ChooseYourDestinationNsToNt.h" #include "BaseConsoleTeleportServer.h" -#include "AMFFormat.h" +#include "Amf3.h" class NsLupTeleport : public CppScripts::Script, ChooseYourDestinationNsToNt, BaseConsoleTeleportServer { diff --git a/dScripts/02_server/Map/NT/NtAssemblyTubeServer.cpp b/dScripts/02_server/Map/NT/NtAssemblyTubeServer.cpp index 5f1619ab..6ae4c767 100644 --- a/dScripts/02_server/Map/NT/NtAssemblyTubeServer.cpp +++ b/dScripts/02_server/Map/NT/NtAssemblyTubeServer.cpp @@ -4,6 +4,7 @@ #include "MissionComponent.h" #include "eMissionTaskType.h" #include "eMissionState.h" +#include "RenderComponent.h" #include "eEndBehavior.h" #include "eStateChangeType.h" @@ -51,12 +52,12 @@ void NtAssemblyTubeServer::RunAssemblyTube(Entity* self, Entity* player) { ); } - GameMessages::SendPlayAnimation(player, u"tube-sucker", 4.0f); + RenderComponent::PlayAnimation(player, u"tube-sucker", 4.0f); const auto animTime = 3; self->AddCallbackTimer(animTime, [this, self, playerID]() { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) { return; @@ -72,7 +73,7 @@ void NtAssemblyTubeServer::TeleportPlayer(Entity* self, Entity* player) { auto* destination = self; if (!destinationGroup.empty()) { - const auto& groupObjs = EntityManager::Instance()->GetEntitiesInGroup(GeneralUtils::UTF16ToWTF8(destinationGroup)); + const auto& groupObjs = Game::entityManager->GetEntitiesInGroup(GeneralUtils::UTF16ToWTF8(destinationGroup)); if (!groupObjs.empty()) { destination = groupObjs[0]; @@ -84,14 +85,14 @@ void NtAssemblyTubeServer::TeleportPlayer(Entity* self, Entity* player) { GameMessages::SendTeleport(player->GetObjectID(), destPosition, destRotation, player->GetSystemAddress(), true); - GameMessages::SendPlayAnimation(player, u"tube-resurrect", 4.0f); + RenderComponent::PlayAnimation(player, u"tube-resurrect", 4.0f); const auto animTime = 2; const auto playerID = player->GetObjectID(); self->AddCallbackTimer(animTime, [this, self, playerID]() { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) { return; diff --git a/dScripts/02_server/Map/NT/NtCombatChallengeDummy.cpp b/dScripts/02_server/Map/NT/NtCombatChallengeDummy.cpp index c9cd8f0a..5be5a9b3 100644 --- a/dScripts/02_server/Map/NT/NtCombatChallengeDummy.cpp +++ b/dScripts/02_server/Map/NT/NtCombatChallengeDummy.cpp @@ -4,7 +4,7 @@ void NtCombatChallengeDummy::OnDie(Entity* self, Entity* killer) { const auto challengeObjectID = self->GetVar(u"challengeObjectID"); - auto* challengeObject = EntityManager::Instance()->GetEntity(challengeObjectID); + auto* challengeObject = Game::entityManager->GetEntity(challengeObjectID); if (challengeObject != nullptr) { for (CppScripts::Script* script : CppScripts::GetEntityScripts(challengeObject)) { @@ -16,7 +16,7 @@ void NtCombatChallengeDummy::OnDie(Entity* self, Entity* killer) { void NtCombatChallengeDummy::OnHitOrHealResult(Entity* self, Entity* attacker, int32_t damage) { const auto challengeObjectID = self->GetVar(u"challengeObjectID"); - auto* challengeObject = EntityManager::Instance()->GetEntity(challengeObjectID); + auto* challengeObject = Game::entityManager->GetEntity(challengeObjectID); if (challengeObject != nullptr) { for (CppScripts::Script* script : CppScripts::GetEntityScripts(challengeObject)) { diff --git a/dScripts/02_server/Map/NT/NtCombatChallengeExplodingDummy.cpp b/dScripts/02_server/Map/NT/NtCombatChallengeExplodingDummy.cpp index c117c63a..de27e106 100644 --- a/dScripts/02_server/Map/NT/NtCombatChallengeExplodingDummy.cpp +++ b/dScripts/02_server/Map/NT/NtCombatChallengeExplodingDummy.cpp @@ -5,7 +5,7 @@ void NtCombatChallengeExplodingDummy::OnDie(Entity* self, Entity* killer) { const auto challengeObjectID = self->GetVar(u"challengeObjectID"); - auto* challengeObject = EntityManager::Instance()->GetEntity(challengeObjectID); + auto* challengeObject = Game::entityManager->GetEntity(challengeObjectID); if (challengeObject != nullptr) { for (CppScripts::Script* script : CppScripts::GetEntityScripts(challengeObject)) { @@ -17,7 +17,7 @@ void NtCombatChallengeExplodingDummy::OnDie(Entity* self, Entity* killer) { void NtCombatChallengeExplodingDummy::OnHitOrHealResult(Entity* self, Entity* attacker, int32_t damage) { const auto challengeObjectID = self->GetVar(u"challengeObjectID"); - auto* challengeObject = EntityManager::Instance()->GetEntity(challengeObjectID); + auto* challengeObject = Game::entityManager->GetEntity(challengeObjectID); if (challengeObject != nullptr) { for (CppScripts::Script* script : CppScripts::GetEntityScripts(challengeObject)) { diff --git a/dScripts/02_server/Map/NT/NtCombatChallengeServer.cpp b/dScripts/02_server/Map/NT/NtCombatChallengeServer.cpp index d27ac1f6..011a67ea 100644 --- a/dScripts/02_server/Map/NT/NtCombatChallengeServer.cpp +++ b/dScripts/02_server/Map/NT/NtCombatChallengeServer.cpp @@ -19,7 +19,7 @@ void NtCombatChallengeServer::OnDie(Entity* self, Entity* killer) { void NtCombatChallengeServer::OnHitOrHealResult(Entity* self, Entity* attacker, int32_t damage) { const auto playerID = self->GetVar(u"playerID"); - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) { return; @@ -43,7 +43,7 @@ void NtCombatChallengeServer::OnFireEventServerSide(Entity* self, Entity* sender void NtCombatChallengeServer::OnMessageBoxResponse(Entity* self, Entity* sender, int32_t button, const std::u16string& identifier, const std::u16string& userData) { - if (identifier == u"PlayButton" && button == 1) { + if (identifier == u"PlayButton" && button == 1 && !self->GetNetworkVar(u"bInUse")) { self->SetNetworkVar(u"bInUse", true); self->SetVar(u"playerID", sender->GetObjectID()); @@ -69,7 +69,7 @@ void NtCombatChallengeServer::OnMessageBoxResponse(Entity* self, Entity* sender, void NtCombatChallengeServer::SpawnTargetDummy(Entity* self) { const auto playerID = self->GetVar(u"playerID"); - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) { return; @@ -91,11 +91,11 @@ void NtCombatChallengeServer::SpawnTargetDummy(Entity* self) { info.rot = self->GetRotation(); info.settings = { new LDFData(u"custom_script_server", "scripts\\02_server\\Map\\NT\\L_NT_COMBAT_CHALLENGE_DUMMY.lua") }; - auto* dummy = EntityManager::Instance()->CreateEntity(info); + auto* dummy = Game::entityManager->CreateEntity(info); dummy->SetVar(u"challengeObjectID", self->GetObjectID()); - EntityManager::Instance()->ConstructEntity(dummy); + Game::entityManager->ConstructEntity(dummy); self->SetVar(u"currentDummy", dummy->GetObjectID()); } @@ -111,7 +111,7 @@ void NtCombatChallengeServer::OnChildLoaded(Entity* self, Entity* child) { const auto playerID = self->GetVar(u"playerID"); - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) { return; @@ -121,7 +121,7 @@ void NtCombatChallengeServer::OnChildLoaded(Entity* self, Entity* child) { self->SetVar(u"currentTargetID", child->GetObjectID()); - EntityManager::Instance()->SerializeEntity(child); + Game::entityManager->SerializeEntity(child); child->GetGroups().push_back("targets_" + std::to_string(self->GetObjectID())); } @@ -130,7 +130,7 @@ void NtCombatChallengeServer::ResetGame(Entity* self) { const auto totalDmg = self->GetVar(u"totalDmg"); const auto playerID = self->GetVar(u"playerID"); - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player != nullptr) { auto* missionComponent = player->GetComponent(); @@ -150,7 +150,7 @@ void NtCombatChallengeServer::ResetGame(Entity* self) { self->SetNetworkVar(u"totalDmg", false); self->SetNetworkVar(u"update_time", 0); - const auto& targetObjs = EntityManager::Instance()->GetEntitiesInGroup("targets_" + std::to_string(self->GetObjectID())); + const auto& targetObjs = Game::entityManager->GetEntitiesInGroup("targets_" + std::to_string(self->GetObjectID())); for (auto* target : targetObjs) { target->Smash(self->GetObjectID()); @@ -158,7 +158,7 @@ void NtCombatChallengeServer::ResetGame(Entity* self) { const auto currentID = self->GetVar(u"currentDummy"); - auto* current = EntityManager::Instance()->GetEntity(currentID); + auto* current = Game::entityManager->GetEntity(currentID); if (current != nullptr) { current->Smash(self->GetObjectID()); diff --git a/dScripts/02_server/Map/NT/NtConsoleTeleportServer.cpp b/dScripts/02_server/Map/NT/NtConsoleTeleportServer.cpp index 324a2fc0..8ba697ce 100644 --- a/dScripts/02_server/Map/NT/NtConsoleTeleportServer.cpp +++ b/dScripts/02_server/Map/NT/NtConsoleTeleportServer.cpp @@ -1,6 +1,6 @@ #include "NtConsoleTeleportServer.h" #include "Entity.h" -#include "AMFFormat.h" +#include "Amf3.h" void NtConsoleTeleportServer::OnStartup(Entity* self) { self->SetVar(u"teleportAnim", m_TeleportAnim); diff --git a/dScripts/02_server/Map/NT/NtImagBeamBuffer.cpp b/dScripts/02_server/Map/NT/NtImagBeamBuffer.cpp index d98a7403..961e93cd 100644 --- a/dScripts/02_server/Map/NT/NtImagBeamBuffer.cpp +++ b/dScripts/02_server/Map/NT/NtImagBeamBuffer.cpp @@ -40,7 +40,7 @@ void NtImagBeamBuffer::OnTimerDone(Entity* self, std::string timerName) { } for (const auto entityID : m_EntitiesInProximity) { - auto* entity = EntityManager::Instance()->GetEntity(entityID); + auto* entity = Game::entityManager->GetEntity(entityID); if (entity == nullptr) { continue; diff --git a/dScripts/02_server/Map/NT/NtOverbuildServer.cpp b/dScripts/02_server/Map/NT/NtOverbuildServer.cpp index f8520d87..e75d8add 100644 --- a/dScripts/02_server/Map/NT/NtOverbuildServer.cpp +++ b/dScripts/02_server/Map/NT/NtOverbuildServer.cpp @@ -21,7 +21,7 @@ void NtOverbuildServer::SetVariables(Entity* self) { // Find the second object Dr. Overbuild interacts with LWOOBJID otherConvoObjectID = LWOOBJID_EMPTY; - for (auto* otherConvoObject : EntityManager::Instance()->GetEntitiesInGroup(GeneralUtils::UTF16ToWTF8(self->GetVar(m_OtherEntitiesGroupVariable)))) { + for (auto* otherConvoObject : Game::entityManager->GetEntitiesInGroup(GeneralUtils::UTF16ToWTF8(self->GetVar(m_OtherEntitiesGroupVariable)))) { otherConvoObjectID = otherConvoObject->GetObjectID(); break; } diff --git a/dScripts/02_server/Map/NT/NtParadoxPanelServer.cpp b/dScripts/02_server/Map/NT/NtParadoxPanelServer.cpp index 23d336a7..0fe97a26 100644 --- a/dScripts/02_server/Map/NT/NtParadoxPanelServer.cpp +++ b/dScripts/02_server/Map/NT/NtParadoxPanelServer.cpp @@ -4,6 +4,7 @@ #include "EntityManager.h" #include "Character.h" #include "eMissionState.h" +#include "RenderComponent.h" #include "eTerminateType.h" #include "eStateChangeType.h" @@ -24,7 +25,7 @@ void NtParadoxPanelServer::OnUse(Entity* self, Entity* user) { } self->AddCallbackTimer(2, [this, self, playerID]() { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) { return; @@ -34,18 +35,18 @@ void NtParadoxPanelServer::OnUse(Entity* self, Entity* user) { player->GetCharacter()->SetPlayerFlag(flag, true); - GameMessages::SendPlayAnimation(player, u"rebuild-celebrate"); + RenderComponent::PlayAnimation(player, u"rebuild-celebrate"); GameMessages::SendNotifyClientObject(self->GetObjectID(), u"SparkStop", 0, 0, player->GetObjectID(), "", player->GetSystemAddress()); GameMessages::SendSetStunned(player->GetObjectID(), eStateChangeType::POP, player->GetSystemAddress(), LWOOBJID_EMPTY, false, false, true, false, true, true, false, false, true); self->SetVar(u"bActive", false); }); - GameMessages::SendPlayAnimation(user, u"nexus-powerpanel", 6.0f); + RenderComponent::PlayAnimation(user, u"nexus-powerpanel", 6.0f); GameMessages::SendSetStunned(user->GetObjectID(), eStateChangeType::PUSH, user->GetSystemAddress(), LWOOBJID_EMPTY, false, false, true, false, true, true, false, false, true); return; } - GameMessages::SendPlayAnimation(user, shockAnim); + RenderComponent::PlayAnimation(user, shockAnim); const auto dir = self->GetRotation().GetRightVector(); @@ -54,7 +55,7 @@ void NtParadoxPanelServer::OnUse(Entity* self, Entity* user) { GameMessages::SendPlayFXEffect(self, 6432, u"create", "console_sparks", LWOOBJID_EMPTY, 1.0, 1.0, true); self->AddCallbackTimer(2, [this, self, playerID]() { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) { return; diff --git a/dScripts/02_server/Map/NT/NtParadoxTeleServer.cpp b/dScripts/02_server/Map/NT/NtParadoxTeleServer.cpp index b19c8c0b..67ff4bec 100644 --- a/dScripts/02_server/Map/NT/NtParadoxTeleServer.cpp +++ b/dScripts/02_server/Map/NT/NtParadoxTeleServer.cpp @@ -3,6 +3,7 @@ #include "EntityManager.h" #include "MissionComponent.h" #include "eMissionTaskType.h" +#include "RenderComponent.h" #include "eStateChangeType.h" void NtParadoxTeleServer::OnStartup(Entity* self) { @@ -28,12 +29,11 @@ void NtParadoxTeleServer::OnProximityUpdate(Entity* self, Entity* entering, std: true, true, true, true, true, true, true ); - GameMessages::SendPlayAnimation(player, u"teledeath", 4.0f); - - const auto animTime = 2; + auto animTime = RenderComponent::PlayAnimation(player, u"teledeath", 4.0f); + if (animTime == 0.0f) animTime = 2.0f; self->AddCallbackTimer(animTime, [this, self, playerID]() { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) { return; @@ -55,7 +55,7 @@ void NtParadoxTeleServer::TeleportPlayer(Entity* self, Entity* player) { auto* destination = self; if (!destinationGroup.empty()) { - const auto& groupObjs = EntityManager::Instance()->GetEntitiesInGroup(GeneralUtils::UTF16ToWTF8(destinationGroup)); + const auto& groupObjs = Game::entityManager->GetEntitiesInGroup(GeneralUtils::UTF16ToWTF8(destinationGroup)); if (!groupObjs.empty()) { destination = groupObjs[0]; @@ -74,14 +74,14 @@ void NtParadoxTeleServer::TeleportPlayer(Entity* self, Entity* player) { GameMessages::SendTeleport(player->GetObjectID(), destPosition, destRotation, player->GetSystemAddress(), true); - GameMessages::SendPlayAnimation(player, u"paradox-teleport-in", 4.0f); + RenderComponent::PlayAnimation(player, u"paradox-teleport-in", 4.0f); const auto animTime = 2; const auto playerID = player->GetObjectID(); self->AddCallbackTimer(animTime, [this, self, playerID]() { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) { return; diff --git a/dScripts/02_server/Map/NT/NtSentinelWalkwayServer.cpp b/dScripts/02_server/Map/NT/NtSentinelWalkwayServer.cpp index 257bf6da..cac0c75f 100644 --- a/dScripts/02_server/Map/NT/NtSentinelWalkwayServer.cpp +++ b/dScripts/02_server/Map/NT/NtSentinelWalkwayServer.cpp @@ -25,7 +25,7 @@ void NtSentinelWalkwayServer::OnStartup(Entity* self) { phantomPhysicsComponent->SetDirection(forward); phantomPhysicsComponent->SetPhysicsEffectActive(true); - EntityManager::Instance()->SerializeEntity(self); + Game::entityManager->SerializeEntity(self); self->SetProximityRadius(3, "speedboost"); } diff --git a/dScripts/02_server/Map/NT/NtSleepingGuard.cpp b/dScripts/02_server/Map/NT/NtSleepingGuard.cpp index 145df6c8..92a80582 100644 --- a/dScripts/02_server/Map/NT/NtSleepingGuard.cpp +++ b/dScripts/02_server/Map/NT/NtSleepingGuard.cpp @@ -1,6 +1,7 @@ #include "NtSleepingGuard.h" #include "GameMessages.h" #include "MissionComponent.h" +#include "RenderComponent.h" void NtSleepingGuard::OnStartup(Entity* self) { self->SetNetworkVar(u"asleep", true); @@ -17,7 +18,7 @@ void NtSleepingGuard::OnEmoteReceived(Entity* self, const int32_t emote, Entity* // Set asleep to false self->SetNetworkVar(u"asleep", false); - GameMessages::SendPlayAnimation(self, u"greet"); + RenderComponent::PlayAnimation(self, u"greet"); auto* missionComponent = target->GetComponent(); diff --git a/dScripts/02_server/Map/NT/NtVentureCannonServer.cpp b/dScripts/02_server/Map/NT/NtVentureCannonServer.cpp index 38f929a1..7e38ac12 100644 --- a/dScripts/02_server/Map/NT/NtVentureCannonServer.cpp +++ b/dScripts/02_server/Map/NT/NtVentureCannonServer.cpp @@ -1,6 +1,9 @@ #include "NtVentureCannonServer.h" #include "GameMessages.h" #include "EntityManager.h" +#include "Entity.h" +#include "GeneralUtils.h" +#include "RenderComponent.h" #include "eEndBehavior.h" #include "eTerminateType.h" #include "eStateChangeType.h" @@ -29,7 +32,7 @@ void NtVentureCannonServer::OnUse(Entity* self, Entity* user) { GameMessages::SendTeleport(playerID, destPosition, destRotation, player->GetSystemAddress(), true); - GameMessages::SendPlayAnimation(player, u"scale-down", 4.0f); + RenderComponent::PlayAnimation(player, u"scale-down", 4.0f); const auto enterCinematicUname = enterCinematic; GameMessages::SendPlayCinematic(player->GetObjectID(), enterCinematicUname, player->GetSystemAddress()); @@ -41,7 +44,7 @@ void NtVentureCannonServer::OnUse(Entity* self, Entity* user) { }); self->AddCallbackTimer(1.5f, [this, self, playerID]() { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) { return; @@ -54,7 +57,7 @@ void NtVentureCannonServer::OnUse(Entity* self, Entity* user) { void NtVentureCannonServer::EnterCannonEnded(Entity* self, Entity* player) { const auto playerID = player->GetObjectID(); - const auto& cannonEffectGroup = EntityManager::Instance()->GetEntitiesInGroup("cannonEffect"); + const auto& cannonEffectGroup = Game::entityManager->GetEntitiesInGroup("cannonEffect"); if (!cannonEffectGroup.empty()) { auto* cannonEffect = cannonEffectGroup[0]; @@ -80,7 +83,7 @@ void NtVentureCannonServer::EnterCannonEnded(Entity* self, Entity* player) { ); self->AddCallbackTimer(1.5f, [this, self, playerID]() { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) { return; @@ -109,7 +112,7 @@ void NtVentureCannonServer::FirePlayer(Entity* self, Entity* player) { auto* destination = self; if (!destinationGroup.empty()) { - const auto& groupObjs = EntityManager::Instance()->GetEntitiesInGroup(GeneralUtils::UTF16ToWTF8(destinationGroup)); + const auto& groupObjs = Game::entityManager->GetEntitiesInGroup(GeneralUtils::UTF16ToWTF8(destinationGroup)); if (!groupObjs.empty()) { destination = groupObjs[0]; @@ -121,5 +124,5 @@ void NtVentureCannonServer::FirePlayer(Entity* self, Entity* player) { GameMessages::SendTeleport(player->GetObjectID(), destPosition, destRotation, player->GetSystemAddress(), true); - GameMessages::SendPlayAnimation(player, u"venture-cannon-out", 4.0f); + RenderComponent::PlayAnimation(player, u"venture-cannon-out", 4.0f); } diff --git a/dScripts/02_server/Map/PR/HydrantBroken.cpp b/dScripts/02_server/Map/PR/HydrantBroken.cpp index 1409c9fb..2694b425 100644 --- a/dScripts/02_server/Map/PR/HydrantBroken.cpp +++ b/dScripts/02_server/Map/PR/HydrantBroken.cpp @@ -7,7 +7,7 @@ void HydrantBroken::OnStartup(Entity* self) { const auto hydrant = "hydrant" + self->GetVar(u"hydrant"); - const auto bouncers = EntityManager::Instance()->GetEntitiesInGroup(hydrant); + const auto bouncers = Game::entityManager->GetEntitiesInGroup(hydrant); for (auto* bouncer : bouncers) { self->SetVar(u"bouncer", bouncer->GetObjectID()); @@ -22,7 +22,7 @@ void HydrantBroken::OnStartup(Entity* self) { void HydrantBroken::OnTimerDone(Entity* self, std::string timerName) { if (timerName == "KillBroken") { - auto* bouncer = EntityManager::Instance()->GetEntity(self->GetVar(u"bouncer")); + auto* bouncer = Game::entityManager->GetEntity(self->GetVar(u"bouncer")); if (bouncer != nullptr) { GameMessages::SendBouncerActiveStatus(bouncer->GetObjectID(), false, UNASSIGNED_SYSTEM_ADDRESS); diff --git a/dScripts/02_server/Map/Property/AG_Med/ZoneAgMedProperty.cpp b/dScripts/02_server/Map/Property/AG_Med/ZoneAgMedProperty.cpp index db1c4c4b..46ec7bbd 100644 --- a/dScripts/02_server/Map/Property/AG_Med/ZoneAgMedProperty.cpp +++ b/dScripts/02_server/Map/Property/AG_Med/ZoneAgMedProperty.cpp @@ -31,8 +31,8 @@ void ZoneAgMedProperty::SetGameVariables(Entity* self) { self->SetVar>(AmbientFXSpawner, { "BirdFX", "SunBeam" }); self->SetVar>(BehaviorObjsSpawner, {}); - self->SetVar(defeatedProperyFlag, 118); - self->SetVar(placedModelFlag, 119); + self->SetVar(defeatedProperyFlag, 118); + self->SetVar(placedModelFlag, 119); self->SetVar(guardMissionFlag, 1293); self->SetVar(brickLinkMissionIDFlag, 1294); self->SetVar(passwordFlag, "s3kratK1ttN"); diff --git a/dScripts/02_server/Map/Property/AG_Small/EnemySpiderSpawner.cpp b/dScripts/02_server/Map/Property/AG_Small/EnemySpiderSpawner.cpp index 0d4f568e..641845a9 100644 --- a/dScripts/02_server/Map/Property/AG_Small/EnemySpiderSpawner.cpp +++ b/dScripts/02_server/Map/Property/AG_Small/EnemySpiderSpawner.cpp @@ -19,7 +19,7 @@ void EnemySpiderSpawner::OnFireEventServerSide(Entity* self, Entity* sender, std if (dest) { dest->SetFaction(-1); } - EntityManager::Instance()->SerializeEntity(self); + Game::entityManager->SerializeEntity(self); // Keep track of who prepped me self->SetI64(u"SpawnOwner", sender->GetObjectID()); @@ -48,9 +48,9 @@ void EnemySpiderSpawner::OnTimerDone(Entity* self, std::string timerName) { info.spawnerID = self->GetI64(u"SpawnOwner"); info.spawnerNodeID = 0; - Entity* newEntity = EntityManager::Instance()->CreateEntity(info, nullptr); + Entity* newEntity = Game::entityManager->CreateEntity(info, nullptr); if (newEntity) { - EntityManager::Instance()->ConstructEntity(newEntity); + Game::entityManager->ConstructEntity(newEntity); newEntity->GetGroups().push_back("BabySpider"); /* diff --git a/dScripts/02_server/Map/Property/AG_Small/ZoneAgProperty.cpp b/dScripts/02_server/Map/Property/AG_Small/ZoneAgProperty.cpp index 635eb8b3..6f2f6d36 100644 --- a/dScripts/02_server/Map/Property/AG_Small/ZoneAgProperty.cpp +++ b/dScripts/02_server/Map/Property/AG_Small/ZoneAgProperty.cpp @@ -39,8 +39,8 @@ void ZoneAgProperty::SetGameVariables(Entity* self) { self->SetVar(LauncherSpawner, "Launcher"); self->SetVar(InstancerSpawner, "Instancer"); - self->SetVar(defeatedProperyFlag, 71); - self->SetVar(placedModelFlag, 73); + self->SetVar(defeatedProperyFlag, 71); + self->SetVar(placedModelFlag, 73); self->SetVar(guardFirstMissionFlag, 891); self->SetVar(guardMissionFlag, 320); self->SetVar(brickLinkMissionIDFlag, 951); @@ -61,7 +61,7 @@ void ZoneAgProperty::OnPlayerLoaded(Entity* self, Entity* player) { self->SetVar(u"numberOfPlayers", numberOfPlayers + 1); } - if (dZoneManager::Instance()->GetZone()->GetZoneID().GetMapID() == 1102) { + if (Game::zoneManager->GetZone()->GetZoneID().GetMapID() == 1102) { GameMessages::SendPlay2DAmbientSound(player, GUIDMaelstrom); GameMessages::SendNotifyClientObject(self->GetObjectID(), u"maelstromSkyOn", 0, 0, LWOOBJID_EMPTY, "", player->GetSystemAddress()); @@ -93,7 +93,7 @@ void ZoneAgProperty::OnZoneLoadedInfo(Entity* self) { void ZoneAgProperty::LoadInstance(Entity* self) { SetGameVariables(self); - for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(self->GetVar(InstancerSpawner))) { + for (auto* spawner : Game::zoneManager->GetSpawnersByName(self->GetVar(InstancerSpawner))) { for (auto* spawnerNode : spawner->m_Info.nodes) { spawnerNode->config.push_back( new LDFData(u"custom_script_server", @@ -128,13 +128,13 @@ void ZoneAgProperty::KillSpots(Entity* self) { } for (const auto& groupName : self->GetVar>(ROFTargetsGroup)) { - for (auto* spot : EntityManager::Instance()->GetEntitiesInGroup(groupName)) { + for (auto* spot : Game::entityManager->GetEntitiesInGroup(groupName)) { spot->Kill(); } } DeactivateSpawner(self->GetVar(LandTargetSpawner)); - for (auto* landTarget : EntityManager::Instance()->GetEntitiesInGroup(self->GetVar(LandTargetSpawner))) { + for (auto* landTarget : Game::entityManager->GetEntitiesInGroup(self->GetVar(LandTargetSpawner))) { landTarget->Kill(); } } @@ -180,7 +180,7 @@ void ZoneAgProperty::StartMaelstrom(Entity* self, Entity* player) { } uint32_t ZoneAgProperty::RetrieveSpawnerId(Entity* self, const std::string& spawner) { - auto spawnerIDs = dZoneManager::Instance()->GetSpawnersByName(spawner); + auto spawnerIDs = Game::zoneManager->GetSpawnersByName(spawner); if (spawnerIDs.empty()) return 0; @@ -193,24 +193,24 @@ void ZoneAgProperty::OnTimerDone(Entity* self, std::string timerName) { void ZoneAgProperty::BaseTimerDone(Entity* self, const std::string& timerName) { if (timerName == "GuardFlyAway") { - const auto zoneId = dZoneManager::Instance()->GetZone()->GetWorldID(); + const auto zoneId = Game::zoneManager->GetZone()->GetWorldID(); if (zoneId != 1150) return; - const auto entities = EntityManager::Instance()->GetEntitiesInGroup(self->GetVar(GuardGroup)); + const auto entities = Game::entityManager->GetEntitiesInGroup(self->GetVar(GuardGroup)); if (entities.empty()) return; auto* entity = entities[0]; - GameMessages::SendNotifyClientObject(EntityManager::Instance()->GetZoneControlEntity()->GetObjectID(), u"GuardChat", 0, 0, entity->GetObjectID(), "", UNASSIGNED_SYSTEM_ADDRESS); + GameMessages::SendNotifyClientObject(Game::entityManager->GetZoneControlEntity()->GetObjectID(), u"GuardChat", 0, 0, entity->GetObjectID(), "", UNASSIGNED_SYSTEM_ADDRESS); LoadProperty(self); self->AddTimer("KillGuard", 5); } else if (timerName == "KillGuard") { KillGuard(self); } else if (timerName == "tornadoOff") { - for (auto* entity : EntityManager::Instance()->GetEntitiesInGroup(self->GetVar(FXManagerGroup))) { + for (auto* entity : Game::entityManager->GetEntitiesInGroup(self->GetVar(FXManagerGroup))) { auto* renderComponent = entity->GetComponent(); if (renderComponent != nullptr) { renderComponent->StopEffect("TornadoDebris", false); @@ -222,7 +222,7 @@ void ZoneAgProperty::BaseTimerDone(Entity* self, const std::string& timerName) { self->AddTimer("ShowVendor", 1.2f); self->AddTimer("ShowClearEffects", 2); } else if (timerName == "ShowClearEffects") { - for (auto* entity : EntityManager::Instance()->GetEntitiesInGroup(self->GetVar(FXManagerGroup))) { + for (auto* entity : Game::entityManager->GetEntitiesInGroup(self->GetVar(FXManagerGroup))) { auto* renderComponent = entity->GetComponent(); if (renderComponent != nullptr) { renderComponent->PlayEffect(-1, u"beamOn", "beam"); @@ -236,7 +236,7 @@ void ZoneAgProperty::BaseTimerDone(Entity* self, const std::string& timerName) { GameMessages::SendNotifyClientObject(self->GetObjectID(), u"SkyOff", 0, 0, LWOOBJID_EMPTY, "", UNASSIGNED_SYSTEM_ADDRESS); } else if (timerName == "killSpider") { - for (auto* entity : EntityManager::Instance()->GetEntitiesInGroup(self->GetVar(EnemiesGroup))) { + for (auto* entity : Game::entityManager->GetEntitiesInGroup(self->GetVar(EnemiesGroup))) { entity->Kill(); } @@ -257,7 +257,7 @@ void ZoneAgProperty::BaseTimerDone(Entity* self, const std::string& timerName) { DeactivateSpawner(self->GetVar(SpiderScreamSpawner)); DestroySpawner(self->GetVar(SpiderScreamSpawner)); - for (auto* player : EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::CHARACTER)) { + for (auto* player : Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::CHARACTER)) { GameMessages::SendStop2DAmbientSound(player, true, GUIDMaelstrom); GameMessages::SendPlay2DAmbientSound(player, GUIDPeaceful); } @@ -274,7 +274,7 @@ void ZoneAgProperty::BaseTimerDone(Entity* self, const std::string& timerName) { } else if (timerName == "pollTornadoFX") { StartTornadoFx(self); } else if (timerName == "killFXObject") { - for (auto* entity : EntityManager::Instance()->GetEntitiesInGroup(self->GetVar(FXManagerGroup))) { + for (auto* entity : Game::entityManager->GetEntitiesInGroup(self->GetVar(FXManagerGroup))) { auto* renderComponent = entity->GetComponent(); if (renderComponent != nullptr) { renderComponent->StopEffect("beam"); @@ -385,7 +385,7 @@ void ZoneAgProperty::RemovePlayerRef(Entity* self) { void ZoneAgProperty::BaseOnFireEventServerSide(Entity* self, Entity* sender, std::string args) { if (args == "propertyRented") { const auto playerId = self->GetVar(u"playerID"); - auto* player = EntityManager::Instance()->GetEntity(playerId); + auto* player = Game::entityManager->GetEntity(playerId); if (player == nullptr) return; @@ -409,7 +409,7 @@ void ZoneAgProperty::BaseOnFireEventServerSide(Entity* self, Entity* sender, std sender->SetNetworkVar(u"PropertyOwnerID", std::to_string(self->GetVar(u"PropertyOwner"))); } else if (args == "ClearProperty") { const auto playerId = self->GetVar(u"playerID"); - auto* player = EntityManager::Instance()->GetEntity(playerId); + auto* player = Game::entityManager->GetEntity(playerId); if (player == nullptr) return; diff --git a/dScripts/02_server/Map/Property/PropertyBankInteract.cpp b/dScripts/02_server/Map/Property/PropertyBankInteract.cpp index 9e727f39..50fea9a0 100644 --- a/dScripts/02_server/Map/Property/PropertyBankInteract.cpp +++ b/dScripts/02_server/Map/Property/PropertyBankInteract.cpp @@ -1,17 +1,18 @@ #include "PropertyBankInteract.h" #include "EntityManager.h" #include "GameMessages.h" -#include "AMFFormat.h" +#include "Amf3.h" +#include "Entity.h" void PropertyBankInteract::OnStartup(Entity* self) { - auto* zoneControl = EntityManager::Instance()->GetZoneControlEntity(); + auto* zoneControl = Game::entityManager->GetZoneControlEntity(); if (zoneControl != nullptr) { zoneControl->OnFireEventServerSide(self, "CheckForPropertyOwner"); } } void PropertyBankInteract::OnPlayerLoaded(Entity* self, Entity* player) { - auto* zoneControl = EntityManager::Instance()->GetZoneControlEntity(); + auto* zoneControl = Game::entityManager->GetZoneControlEntity(); if (zoneControl != nullptr) { zoneControl->OnFireEventServerSide(self, "CheckForPropertyOwner"); } @@ -20,11 +21,10 @@ void PropertyBankInteract::OnPlayerLoaded(Entity* self, Entity* player) { void PropertyBankInteract::OnUse(Entity* self, Entity* user) { AMFArrayValue args; - auto* value = new AMFStringValue(); - value->SetStringValue("bank"); - args.InsertValue("state", value); - GameMessages::SendUIMessageServerToSingleClient(user, user->GetSystemAddress(), "pushGameState", &args); + args.Insert("state", "bank"); + + GameMessages::SendUIMessageServerToSingleClient(user, user->GetSystemAddress(), "pushGameState", args); GameMessages::SendNotifyClientObject(self->GetObjectID(), u"OpenBank", 0, 0, LWOOBJID_EMPTY, "", user->GetSystemAddress()); @@ -34,9 +34,10 @@ void PropertyBankInteract::OnFireEventServerSide(Entity* self, Entity* sender, s int32_t param2, int32_t param3) { if (args == "ToggleBank") { AMFArrayValue amfArgs; - amfArgs.InsertValue("visible", new AMFFalseValue()); - GameMessages::SendUIMessageServerToSingleClient(sender, sender->GetSystemAddress(), "ToggleBank", &amfArgs); + amfArgs.Insert("visible", false); + + GameMessages::SendUIMessageServerToSingleClient(sender, sender->GetSystemAddress(), "ToggleBank", amfArgs); GameMessages::SendNotifyClientObject(self->GetObjectID(), u"CloseBank", 0, 0, LWOOBJID_EMPTY, "", sender->GetSystemAddress()); diff --git a/dScripts/02_server/Map/VE/VeBricksampleServer.cpp b/dScripts/02_server/Map/VE/VeBricksampleServer.cpp index 0ead6a87..7535d261 100644 --- a/dScripts/02_server/Map/VE/VeBricksampleServer.cpp +++ b/dScripts/02_server/Map/VE/VeBricksampleServer.cpp @@ -14,7 +14,7 @@ void VeBricksampleServer::OnUse(Entity* self, Entity* user) { if (loot && inventoryComponent != nullptr && inventoryComponent->GetLotCount(loot) == 0) { inventoryComponent->AddItem(loot, 1, eLootSourceType::ACTIVITY); - for (auto* brickEntity : EntityManager::Instance()->GetEntitiesInGroup("Bricks")) { + for (auto* brickEntity : Game::entityManager->GetEntitiesInGroup("Bricks")) { GameMessages::SendNotifyClientObject(brickEntity->GetObjectID(), u"Pickedup"); } } diff --git a/dScripts/02_server/Map/VE/VeEpsilonServer.cpp b/dScripts/02_server/Map/VE/VeEpsilonServer.cpp index c69f9cc2..4e8cb4e9 100644 --- a/dScripts/02_server/Map/VE/VeEpsilonServer.cpp +++ b/dScripts/02_server/Map/VE/VeEpsilonServer.cpp @@ -21,7 +21,7 @@ void VeEpsilonServer::OnMissionDialogueOK(Entity* self, Entity* target, int miss // Notify the client that all objects have updated self->AddCallbackTimer(3.0f, [this]() { - for (const auto* console : EntityManager::Instance()->GetEntitiesInGroup(m_ConsoleGroup)) { + for (const auto* console : Game::entityManager->GetEntitiesInGroup(m_ConsoleGroup)) { GameMessages::SendNotifyClientObject(console->GetObjectID(), u""); } }); diff --git a/dScripts/02_server/Map/njhub/CatapultBaseServer.cpp b/dScripts/02_server/Map/njhub/CatapultBaseServer.cpp index 2df32658..8bed629c 100644 --- a/dScripts/02_server/Map/njhub/CatapultBaseServer.cpp +++ b/dScripts/02_server/Map/njhub/CatapultBaseServer.cpp @@ -1,6 +1,8 @@ #include "CatapultBaseServer.h" #include "GameMessages.h" #include "EntityManager.h" +#include "Entity.h" +#include "RenderComponent.h" void CatapultBaseServer::OnNotifyObject(Entity* self, Entity* sender, const std::string& name, int32_t param1, int32_t param2) { if (name == "BouncerBuilt") { @@ -17,11 +19,11 @@ void CatapultBaseServer::OnNotifyObject(Entity* self, Entity* sender, const std: void CatapultBaseServer::OnTimerDone(Entity* self, std::string timerName) { if (timerName == "PlatAnim") { // get the arm asset - const auto arm = EntityManager::Instance()->GetEntitiesInGroup(self->GetVarAsString(u"ArmGroup")); + const auto arm = Game::entityManager->GetEntitiesInGroup(self->GetVarAsString(u"ArmGroup")); // tell the arm to the play the platform animation, which is just the arm laying there but with bouncer for (auto* obj : arm) { - GameMessages::SendPlayAnimation(obj, u"idle-platform"); + RenderComponent::PlayAnimation(obj, u"idle-platform"); GameMessages::SendPlayNDAudioEmitter(obj, UNASSIGNED_SYSTEM_ADDRESS, "{8cccf912-69e3-4041-a20b-63e4afafc993}"); // set the art so we can use it again self->SetVar(u"Arm", obj->GetObjectID()); @@ -32,15 +34,15 @@ void CatapultBaseServer::OnTimerDone(Entity* self, std::string timerName) { self->AddTimer("bounce", 3); } else if (timerName == "launchAnim") { // get the arm asset - auto* arm = EntityManager::Instance()->GetEntity(self->GetVar(u"Arm")); + auto* arm = Game::entityManager->GetEntity(self->GetVar(u"Arm")); if (arm == nullptr) return; // tell the arm to player the launcher animation auto animTime = 1; self->AddTimer("resetArm", animTime); - GameMessages::SendPlayAnimation(arm, u"launch"); + RenderComponent::PlayAnimation(arm, u"launch"); } else if (timerName == "bounce") { - auto* bouncer = EntityManager::Instance()->GetEntity(self->GetVar(u"Bouncer")); + auto* bouncer = Game::entityManager->GetEntity(self->GetVar(u"Bouncer")); if (bouncer == nullptr) return; // bounce all players @@ -48,13 +50,13 @@ void CatapultBaseServer::OnTimerDone(Entity* self, std::string timerName) { // add a delay to play the animation self->AddTimer("launchAnim", .3); } else if (timerName == "resetArm") { - auto* arm = EntityManager::Instance()->GetEntity(self->GetVar(u"Arm")); + auto* arm = Game::entityManager->GetEntity(self->GetVar(u"Arm")); if (arm == nullptr) return; // set the arm back to natural state - GameMessages::SendPlayAnimation(arm, u"idle"); + RenderComponent::PlayAnimation(arm, u"idle"); - auto* bouncer = EntityManager::Instance()->GetEntity(self->GetVar(u"Bouncer")); + auto* bouncer = Game::entityManager->GetEntity(self->GetVar(u"Bouncer")); if (bouncer == nullptr) return; // kill the bouncer diff --git a/dScripts/02_server/Map/njhub/CatapultBouncerServer.cpp b/dScripts/02_server/Map/njhub/CatapultBouncerServer.cpp index 89faf001..98b8a29d 100644 --- a/dScripts/02_server/Map/njhub/CatapultBouncerServer.cpp +++ b/dScripts/02_server/Map/njhub/CatapultBouncerServer.cpp @@ -7,7 +7,7 @@ void CatapultBouncerServer::OnRebuildComplete(Entity* self, Entity* target) { self->SetNetworkVar(u"Built", true); - const auto base = EntityManager::Instance()->GetEntitiesInGroup(self->GetVarAsString(u"BaseGroup")); + const auto base = Game::entityManager->GetEntitiesInGroup(self->GetVarAsString(u"BaseGroup")); for (auto* obj : base) { obj->NotifyObject(self, "BouncerBuilt"); diff --git a/dScripts/02_server/Map/njhub/CavePrisonCage.cpp b/dScripts/02_server/Map/njhub/CavePrisonCage.cpp index 60bd1b88..9bd89067 100644 --- a/dScripts/02_server/Map/njhub/CavePrisonCage.cpp +++ b/dScripts/02_server/Map/njhub/CavePrisonCage.cpp @@ -4,6 +4,7 @@ #include "GameMessages.h" #include "Character.h" #include "dZoneManager.h" +#include "RenderComponent.h" void CavePrisonCage::OnStartup(Entity* self) { const auto& myNum = self->GetVar(u"myNumber"); @@ -12,7 +13,7 @@ void CavePrisonCage::OnStartup(Entity* self) { return; } - auto* spawner = dZoneManager::Instance()->GetSpawnersByName("PrisonCounterweight_0" + GeneralUtils::UTF16ToWTF8(myNum))[0]; + auto* spawner = Game::zoneManager->GetSpawnersByName("PrisonCounterweight_0" + GeneralUtils::UTF16ToWTF8(myNum))[0]; self->SetVar(u"CWSpawner", spawner); @@ -35,13 +36,13 @@ void CavePrisonCage::Setup(Entity* self, Spawner* spawner) { info.spawnerID = self->GetObjectID(); // Spawn the villager inside the jail - auto* entity = EntityManager::Instance()->CreateEntity(info); + auto* entity = Game::entityManager->CreateEntity(info); // Save the villeger ID self->SetVar(u"villager", entity->GetObjectID()); // Construct the entity - EntityManager::Instance()->ConstructEntity(entity); + Game::entityManager->ConstructEntity(entity); } void CavePrisonCage::OnRebuildNotifyState(Entity* self, eRebuildState state) { @@ -76,7 +77,7 @@ void CavePrisonCage::SpawnCounterweight(Entity* self, Spawner* spawner) { rebuildComponent->AddRebuildCompleteCallback([this, self](Entity* user) { // The counterweight is a simple mover, which is not implemented, so we'll just set it's position - auto* counterweight = EntityManager::Instance()->GetEntity(self->GetVar(u"Counterweight")); + auto* counterweight = Game::entityManager->GetEntity(self->GetVar(u"Counterweight")); if (counterweight == nullptr) { return; @@ -86,7 +87,7 @@ void CavePrisonCage::SpawnCounterweight(Entity* self, Spawner* spawner) { counterweight->SetPosition(counterweight->GetPosition() + NiPoint3(0, -2, 0)); // Serialize the counterweight - EntityManager::Instance()->SerializeEntity(counterweight); + Game::entityManager->SerializeEntity(counterweight); // notifyPlatformAtLastWaypoint @@ -94,14 +95,14 @@ void CavePrisonCage::SpawnCounterweight(Entity* self, Spawner* spawner) { self->SetVar(u"Builder", user->GetObjectID()); // Get the button and make sure it still exists - auto* button = EntityManager::Instance()->GetEntity(self->GetVar(u"Button")); + auto* button = Game::entityManager->GetEntity(self->GetVar(u"Button")); if (button == nullptr) { return; } // Play the 'down' animation on the button - GameMessages::SendPlayAnimation(button, u"down"); + RenderComponent::PlayAnimation(button, u"down"); // Setup a timer named 'buttonGoingDown' to be triggered in 5 seconds self->AddTimer("buttonGoingDown", 5.0f); @@ -116,7 +117,7 @@ void CavePrisonCage::SpawnCounterweight(Entity* self, Spawner* spawner) { } void CavePrisonCage::GetButton(Entity* self) { - const auto buttons = EntityManager::Instance()->GetEntitiesInGroup("PrisonButton_0" + std::to_string(self->GetVarAs(u"myNumber"))); + const auto buttons = Game::entityManager->GetEntitiesInGroup("PrisonButton_0" + std::to_string(self->GetVarAs(u"myNumber"))); if (buttons.size() == 0) { // Try again in 0.5 seconds @@ -136,16 +137,16 @@ void CavePrisonCage::OnTimerDone(Entity* self, std::string timerName) { // the anim of the button down is over if (timerName == "buttonGoingDown") { // Play the 'up' animation - GameMessages::SendPlayAnimation(self, u"up"); + RenderComponent::PlayAnimation(self, u"up"); // Setup a timer named 'CageOpen' to be triggered in 1 second self->AddTimer("CageOpen", 1.0f); } else if (timerName == "CageOpen") { // play the idle open anim - GameMessages::SendPlayAnimation(self, u"idle-up"); + RenderComponent::PlayAnimation(self, u"idle-up"); // Get the villeger - auto* villager = EntityManager::Instance()->GetEntity(self->GetVar(u"villager")); + auto* villager = Game::entityManager->GetEntity(self->GetVar(u"villager")); if (villager == nullptr) { return; @@ -154,7 +155,7 @@ void CavePrisonCage::OnTimerDone(Entity* self, std::string timerName) { GameMessages::SendNotifyClientObject(villager->GetObjectID(), u"TimeToChat", 0, 0, LWOOBJID_EMPTY, "", UNASSIGNED_SYSTEM_ADDRESS); // Get the builder and make sure it still exists - auto* builder = EntityManager::Instance()->GetEntity(self->GetVar(u"Builder")); + auto* builder = Game::entityManager->GetEntity(self->GetVar(u"Builder")); if (builder == nullptr) { return; @@ -169,7 +170,7 @@ void CavePrisonCage::OnTimerDone(Entity* self, std::string timerName) { self->AddTimer("VillagerEscape", 5.0f); } else if (timerName == "VillagerEscape") { // Get the villeger and make sure it still exists - auto* villager = EntityManager::Instance()->GetEntity(self->GetVar(u"villager")); + auto* villager = Game::entityManager->GetEntity(self->GetVar(u"villager")); if (villager == nullptr) { return; @@ -182,7 +183,7 @@ void CavePrisonCage::OnTimerDone(Entity* self, std::string timerName) { self->AddTimer("SmashCounterweight", 2.0f); } else if (timerName == "SmashCounterweight") { // Get the counterweight and make sure it still exists - auto* counterweight = EntityManager::Instance()->GetEntity(self->GetVar(u"Counterweight")); + auto* counterweight = Game::entityManager->GetEntity(self->GetVar(u"Counterweight")); if (counterweight == nullptr) { return; @@ -192,20 +193,20 @@ void CavePrisonCage::OnTimerDone(Entity* self, std::string timerName) { counterweight->Smash(); // Get the button and make sure it still exists - auto* button = EntityManager::Instance()->GetEntity(self->GetVar(u"Button")); + auto* button = Game::entityManager->GetEntity(self->GetVar(u"Button")); if (button == nullptr) { return; } // Play the 'up' animation on the button - GameMessages::SendPlayAnimation(button, u"up"); + RenderComponent::PlayAnimation(button, u"up"); // Setup a timer named 'CageClosed' to be triggered in 1 second self->AddTimer("CageClosed", 1.0f); } else if (timerName == "CageClosed") { // play the idle closed anim - GameMessages::SendPlayAnimation(self, u"idle"); + RenderComponent::PlayAnimation(self, u"idle"); // Setup a timer named 'ResetPrison' to be triggered in 10 seconds self->AddTimer("ResetPrison", 10.0f); diff --git a/dScripts/02_server/Map/njhub/EnemySkeletonSpawner.cpp b/dScripts/02_server/Map/njhub/EnemySkeletonSpawner.cpp index 0e2e4005..7f4d471c 100644 --- a/dScripts/02_server/Map/njhub/EnemySkeletonSpawner.cpp +++ b/dScripts/02_server/Map/njhub/EnemySkeletonSpawner.cpp @@ -28,13 +28,13 @@ void EnemySkeletonSpawner::OnTimerDone(Entity* self, std::string timerName) { info.rot = self->GetRotation(); info.spawnerID = self->GetObjectID(); - auto* spawnedEntity = EntityManager::Instance()->CreateEntity(info); + auto* spawnedEntity = Game::entityManager->CreateEntity(info); if (spawnedEntity == nullptr) { return; } - EntityManager::Instance()->ConstructEntity(spawnedEntity); + Game::entityManager->ConstructEntity(spawnedEntity); spawnedEntity->AddCallbackTimer(60, [spawnedEntity]() { spawnedEntity->Smash(spawnedEntity->GetObjectID()); diff --git a/dScripts/02_server/Map/njhub/Lieutenant.cpp b/dScripts/02_server/Map/njhub/Lieutenant.cpp index d3b0fc1f..74f0e215 100644 --- a/dScripts/02_server/Map/njhub/Lieutenant.cpp +++ b/dScripts/02_server/Map/njhub/Lieutenant.cpp @@ -31,7 +31,7 @@ void Lieutenant::OnDie(Entity* self, Entity* killer) { return; } - const auto spawners = dZoneManager::Instance()->GetSpawnersByName(spawnerName); + const auto spawners = Game::zoneManager->GetSpawnersByName(spawnerName); if (spawners.empty()) { return; diff --git a/dScripts/02_server/Map/njhub/MonCoreNookDoors.cpp b/dScripts/02_server/Map/njhub/MonCoreNookDoors.cpp index dc759c50..a6db5064 100644 --- a/dScripts/02_server/Map/njhub/MonCoreNookDoors.cpp +++ b/dScripts/02_server/Map/njhub/MonCoreNookDoors.cpp @@ -12,7 +12,7 @@ void MonCoreNookDoors::SpawnDoor(Entity* self) { return; } - const auto spawners = dZoneManager::Instance()->GetSpawnersByName("MonCoreNookDoor0" + doorNum); + const auto spawners = Game::zoneManager->GetSpawnersByName("MonCoreNookDoor0" + doorNum); if (spawners.empty()) { return; diff --git a/dScripts/02_server/Map/njhub/MonCoreSmashableDoors.cpp b/dScripts/02_server/Map/njhub/MonCoreSmashableDoors.cpp index 4ec11e56..f9bd6b98 100644 --- a/dScripts/02_server/Map/njhub/MonCoreSmashableDoors.cpp +++ b/dScripts/02_server/Map/njhub/MonCoreSmashableDoors.cpp @@ -9,7 +9,7 @@ void MonCoreSmashableDoors::OnDie(Entity* self, Entity* killer) { auto triggerGroup = "CoreNookTrig0" + myNum; // Get the trigger - auto triggers = EntityManager::Instance()->GetEntitiesInGroup(triggerGroup); + auto triggers = Game::entityManager->GetEntitiesInGroup(triggerGroup); if (triggers.empty()) { return; diff --git a/dScripts/02_server/Map/njhub/NjNPCMissionSpinjitzuServer.cpp b/dScripts/02_server/Map/njhub/NjNPCMissionSpinjitzuServer.cpp index 30bba804..37a5754c 100644 --- a/dScripts/02_server/Map/njhub/NjNPCMissionSpinjitzuServer.cpp +++ b/dScripts/02_server/Map/njhub/NjNPCMissionSpinjitzuServer.cpp @@ -12,7 +12,7 @@ void NjNPCMissionSpinjitzuServer::OnMissionDialogueOK(Entity* self, Entity* targ // Wait for an animation to complete and flag that the player has learned spinjitzu self->AddCallbackTimer(5.0f, [targetID, element]() { - auto* target = EntityManager::Instance()->GetEntity(targetID); + auto* target = Game::entityManager->GetEntity(targetID); if (target != nullptr) { auto* character = target->GetCharacter(); if (character != nullptr) { diff --git a/dScripts/02_server/Map/njhub/NjWuNPC.cpp b/dScripts/02_server/Map/njhub/NjWuNPC.cpp index f4969074..1a5d30fd 100644 --- a/dScripts/02_server/Map/njhub/NjWuNPC.cpp +++ b/dScripts/02_server/Map/njhub/NjWuNPC.cpp @@ -28,7 +28,7 @@ void NjWuNPC::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, e character->SetPlayerFlag(ePlayerFlag::NJ_WU_SHOW_DAILY_CHEST, false); // Hide the chest - for (auto* chest : EntityManager::Instance()->GetEntitiesInGroup(m_DragonChestGroup)) { + for (auto* chest : Game::entityManager->GetEntitiesInGroup(m_DragonChestGroup)) { GameMessages::SendNotifyClientObject(chest->GetObjectID(), m_ShowChestNotification, 0, -1, target->GetObjectID(), "", target->GetSystemAddress()); } @@ -41,19 +41,19 @@ void NjWuNPC::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, e character->SetPlayerFlag(ePlayerFlag::NJ_WU_SHOW_DAILY_CHEST, true); // Show the chest - for (auto* chest : EntityManager::Instance()->GetEntitiesInGroup(m_DragonChestGroup)) { + for (auto* chest : Game::entityManager->GetEntitiesInGroup(m_DragonChestGroup)) { GameMessages::SendNotifyClientObject(chest->GetObjectID(), m_ShowChestNotification, 1, -1, target->GetObjectID(), "", target->GetSystemAddress()); } auto playerID = target->GetObjectID(); self->AddCallbackTimer(5.0f, [this, playerID]() { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) return; // Stop the dragon effects - for (auto* dragon : EntityManager::Instance()->GetEntitiesInGroup(m_DragonStatueGroup)) { + for (auto* dragon : Game::entityManager->GetEntitiesInGroup(m_DragonStatueGroup)) { GameMessages::SendStopFXEffect(dragon, true, "on"); } }); diff --git a/dScripts/02_server/Map/njhub/RainOfArrows.cpp b/dScripts/02_server/Map/njhub/RainOfArrows.cpp index b7c4c074..8a8f9c50 100644 --- a/dScripts/02_server/Map/njhub/RainOfArrows.cpp +++ b/dScripts/02_server/Map/njhub/RainOfArrows.cpp @@ -18,9 +18,9 @@ void RainOfArrows::OnRebuildComplete(Entity* self, Entity* target) { info.rot = myRot; info.spawnerID = self->GetObjectID(); - auto* entity = EntityManager::Instance()->CreateEntity(info); + auto* entity = Game::entityManager->CreateEntity(info); - EntityManager::Instance()->ConstructEntity(entity); + Game::entityManager->ConstructEntity(entity); self->SetVar(u"ChildFX", entity->GetObjectID()); self->SetVar(u"playerID", target->GetObjectID()); @@ -30,11 +30,11 @@ void RainOfArrows::OnRebuildComplete(Entity* self, Entity* target) { } void RainOfArrows::OnTimerDone(Entity* self, std::string timerName) { - auto* child = EntityManager::Instance()->GetEntity( + auto* child = Game::entityManager->GetEntity( self->GetVar(u"ChildFX") ); - auto* player = EntityManager::Instance()->GetEntity( + auto* player = Game::entityManager->GetEntity( self->GetVar(u"playerID") ); diff --git a/dScripts/02_server/Map/njhub/boss_instance/NjMonastryBossInstance.cpp b/dScripts/02_server/Map/njhub/boss_instance/NjMonastryBossInstance.cpp index 4de7638f..d31f7b17 100644 --- a/dScripts/02_server/Map/njhub/boss_instance/NjMonastryBossInstance.cpp +++ b/dScripts/02_server/Map/njhub/boss_instance/NjMonastryBossInstance.cpp @@ -9,6 +9,7 @@ #include "SkillComponent.h" #include "TeamManager.h" #include +#include "RenderComponent.h" // // // // // // // // Event handling // @@ -21,7 +22,7 @@ void NjMonastryBossInstance::OnStartup(Entity* self) { // Add a notification request for all the spawned entities, corresponds to notifySpawnedObjectLoaded for (const auto& spawnerName : spawnerNames) { - for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(spawnerName)) { + for (auto* spawner : Game::zoneManager->GetSpawnersByName(spawnerName)) { spawner->AddEntitySpawnedCallback([self, this](Entity* entity) { const auto lot = entity->GetLOT(); switch (lot) { @@ -121,7 +122,7 @@ void NjMonastryBossInstance::OnActivityTimerDone(Entity* self, const std::string if (timerName == WaitingForPlayersTimer) { StartFight(self); } else if (timerName == SpawnNextWaveTimer) { - auto* frakjaw = EntityManager::Instance()->GetEntity(self->GetVar(LedgeFrakjawVariable)); + auto* frakjaw = Game::entityManager->GetEntity(self->GetVar(LedgeFrakjawVariable)); if (frakjaw != nullptr) { SummonWave(self, frakjaw); } @@ -144,7 +145,7 @@ void NjMonastryBossInstance::OnActivityTimerDone(Entity* self, const std::string } } } else if (timerName + TimerSplitChar == UnstunTimer) { - auto* entity = EntityManager::Instance()->GetEntity(objectID); + auto* entity = Game::entityManager->GetEntity(objectID); if (entity != nullptr) { auto* combatAI = entity->GetComponent(); if (combatAI != nullptr) { @@ -152,7 +153,7 @@ void NjMonastryBossInstance::OnActivityTimerDone(Entity* self, const std::string } } } else if (timerName == SpawnCounterWeightTimer) { - auto spawners = dZoneManager::Instance()->GetSpawnersByName(CounterweightSpawner); + auto spawners = Game::zoneManager->GetSpawnersByName(CounterweightSpawner); if (!spawners.empty()) { // Spawn the counter weight at a specific waypoint, there's one for each round auto* spawner = spawners.front(); @@ -163,7 +164,7 @@ void NjMonastryBossInstance::OnActivityTimerDone(Entity* self, const std::string } } else if (timerName == LowerFrakjawCamTimer) { // Destroy the frakjaw on the ledge - auto* ledgeFrakjaw = EntityManager::Instance()->GetEntity(self->GetVar(LedgeFrakjawVariable)); + auto* ledgeFrakjaw = Game::entityManager->GetEntity(self->GetVar(LedgeFrakjawVariable)); if (ledgeFrakjaw != nullptr) { ledgeFrakjaw->Kill(); } @@ -172,7 +173,7 @@ void NjMonastryBossInstance::OnActivityTimerDone(Entity* self, const std::string GameMessages::SendNotifyClientObject(self->GetObjectID(), PlayCinematicNotification, 0, 0, LWOOBJID_EMPTY, BottomFrakSpawn, UNASSIGNED_SYSTEM_ADDRESS); } else if (timerName == SpawnLowerFrakjawTimer) { - auto spawners = dZoneManager::Instance()->GetSpawnersByName(LowerFrakjawSpawner); + auto spawners = Game::zoneManager->GetSpawnersByName(LowerFrakjawSpawner); if (!spawners.empty()) { auto* spawner = spawners.front(); spawner->Activate(); @@ -181,13 +182,13 @@ void NjMonastryBossInstance::OnActivityTimerDone(Entity* self, const std::string GameMessages::SendNotifyClientObject(self->GetObjectID(), PlayCinematicNotification, 0, 0, LWOOBJID_EMPTY, FireRailSpawn, UNASSIGNED_SYSTEM_ADDRESS); - auto spawners = dZoneManager::Instance()->GetSpawnersByName(FireRailSpawner); + auto spawners = Game::zoneManager->GetSpawnersByName(FireRailSpawner); if (!spawners.empty()) { auto* spawner = spawners.front(); spawner->Activate(); } } else if (timerName + TimerSplitChar == FrakjawSpawnInTimer) { - auto* lowerFrakjaw = EntityManager::Instance()->GetEntity(objectID); + auto* lowerFrakjaw = Game::entityManager->GetEntity(objectID); if (lowerFrakjaw != nullptr) { LowerFrakjawSummon(self, lowerFrakjaw); } @@ -209,7 +210,7 @@ void NjMonastryBossInstance::StartFight(Entity* self) { self->SetVar(FightStartedVariable, true); // Activate the frakjaw spawner - for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(LedgeFrakjawSpawner)) { + for (auto* spawner : Game::zoneManager->GetSpawnersByName(LedgeFrakjawSpawner)) { spawner->Activate(); } } @@ -249,7 +250,7 @@ void NjMonastryBossInstance::HandleCounterWeightSpawned(Entity* self, Entity* co counterWeight->Kill(); } - auto* frakjaw = EntityManager::Instance()->GetEntity(self->GetVar(LedgeFrakjawVariable)); + auto* frakjaw = Game::entityManager->GetEntity(self->GetVar(LedgeFrakjawVariable)); if (frakjaw == nullptr) { GameMessages::SendNotifyClientObject(self->GetObjectID(), u"LedgeFrakjawDead", 0, 0, LWOOBJID_EMPTY, "", UNASSIGNED_SYSTEM_ADDRESS); @@ -261,7 +262,7 @@ void NjMonastryBossInstance::HandleCounterWeightSpawned(Entity* self, Entity* co skillComponent->CalculateBehavior(1635, 39097, frakjaw->GetObjectID(), true, false); } - GameMessages::SendPlayAnimation(frakjaw, StunnedAnimation); + RenderComponent::PlayAnimation(frakjaw, StunnedAnimation); GameMessages::SendPlayNDAudioEmitter(frakjaw, UNASSIGNED_SYSTEM_ADDRESS, CounterSmashAudio); // Before wave 4 we should lower frakjaw from the ledge @@ -281,7 +282,7 @@ void NjMonastryBossInstance::HandleCounterWeightSpawned(Entity* self, Entity* co } void NjMonastryBossInstance::HandleLowerFrakjawSpawned(Entity* self, Entity* lowerFrakjaw) { - GameMessages::SendPlayAnimation(lowerFrakjaw, TeleportInAnimation); + RenderComponent::PlayAnimation(lowerFrakjaw, TeleportInAnimation); self->SetVar(LowerFrakjawVariable, lowerFrakjaw->GetObjectID()); auto* combatAI = lowerFrakjaw->GetComponent(); @@ -341,7 +342,7 @@ void NjMonastryBossInstance::HandleLowerFrakjawHit(Entity* self, Entity* lowerFr std::vector newTrashMobs = {}; for (const auto& trashMobID : trashMobsAlive) { - auto* trashMob = EntityManager::Instance()->GetEntity(trashMobID); + auto* trashMob = Game::entityManager->GetEntity(trashMobID); if (trashMob != nullptr) { newTrashMobs.push_back(trashMobID); @@ -392,7 +393,7 @@ void NjMonastryBossInstance::HandleWaveEnemyDied(Entity* self, Entity* waveEnemy } void NjMonastryBossInstance::TeleportPlayer(Entity* player, uint32_t position) { - for (const auto* spawnPoint : EntityManager::Instance()->GetEntitiesInGroup("SpawnPoint" + std::to_string(position))) { + for (const auto* spawnPoint : Game::entityManager->GetEntitiesInGroup("SpawnPoint" + std::to_string(position))) { GameMessages::SendTeleport(player->GetObjectID(), spawnPoint->GetPosition(), spawnPoint->GetRotation(), player->GetSystemAddress(), true); } @@ -401,7 +402,7 @@ void NjMonastryBossInstance::TeleportPlayer(Entity* player, uint32_t position) { void NjMonastryBossInstance::SummonWave(Entity* self, Entity* frakjaw) { GameMessages::SendNotifyClientObject(self->GetObjectID(), PlayCinematicNotification, 0, 0, LWOOBJID_EMPTY, LedgeFrakSummon, UNASSIGNED_SYSTEM_ADDRESS); - GameMessages::SendPlayAnimation(frakjaw, SummonAnimation); + RenderComponent::PlayAnimation(frakjaw, SummonAnimation); // Stop the music for the first, fourth and fifth wave const auto wave = self->GetVar(WaveNumberVariable); @@ -425,14 +426,14 @@ void NjMonastryBossInstance::LowerFrakjawSummon(Entity* self, Entity* frakjaw) { GameMessages::SendNotifyClientObject(self->GetObjectID(), PlayCinematicNotification, 0, 0, LWOOBJID_EMPTY, BottomFrakSummon, UNASSIGNED_SYSTEM_ADDRESS); ActivityTimerStart(self, SpawnWaveTimer, 2.0f, 2.0f); - GameMessages::SendPlayAnimation(frakjaw, SummonAnimation); + RenderComponent::PlayAnimation(frakjaw, SummonAnimation); } void NjMonastryBossInstance::RemovePoison(Entity* self) { const auto& totalPlayer = self->GetVar>(TotalPlayersLoadedVariable); for (const auto& playerID : totalPlayer) { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player != nullptr) { auto* buffComponent = player->GetComponent(); @@ -444,7 +445,7 @@ void NjMonastryBossInstance::RemovePoison(Entity* self) { } void NjMonastryBossInstance::LowerFrakjaw(Entity* self, Entity* frakjaw) { - GameMessages::SendPlayAnimation(frakjaw, TeleportOutAnimation); + RenderComponent::PlayAnimation(frakjaw, TeleportOutAnimation); ActivityTimerStart(self, LowerFrakjawCamTimer, 2.0f, 2.0f); GameMessages::SendNotifyClientObject(frakjaw->GetObjectID(), StopMusicNotification, 0, 0, @@ -454,7 +455,7 @@ void NjMonastryBossInstance::LowerFrakjaw(Entity* self, Entity* frakjaw) { } void NjMonastryBossInstance::SpawnOnNetwork(Entity* self, const LOT& toSpawn, const uint32_t& numberToSpawn, const std::string& spawnerName) { - auto spawners = dZoneManager::Instance()->GetSpawnersByName(spawnerName); + auto spawners = Game::zoneManager->GetSpawnersByName(spawnerName); if (spawners.empty() || numberToSpawn <= 0) return; @@ -484,7 +485,7 @@ void NjMonastryBossInstance::FightOver(Entity* self) { // Remove all the enemies from the battlefield for (auto i = 1; i < 5; i++) { - auto spawners = dZoneManager::Instance()->GetSpawnersByName(BaseEnemiesSpawner + std::to_string(i)); + auto spawners = Game::zoneManager->GetSpawnersByName(BaseEnemiesSpawner + std::to_string(i)); if (!spawners.empty()) { auto* spawner = spawners.front(); spawner->Deactivate(); @@ -504,7 +505,7 @@ void NjMonastryBossInstance::FightOver(Entity* self) { GameMessages::SendNotifyClientObject(self->GetObjectID(), PlayCinematicNotification, 0, 0, LWOOBJID_EMPTY, TreasureChestSpawning, UNASSIGNED_SYSTEM_ADDRESS); - auto treasureChests = EntityManager::Instance()->GetEntitiesInGroup(ChestSpawnpointGroup); + auto treasureChests = Game::entityManager->GetEntitiesInGroup(ChestSpawnpointGroup); for (auto* treasureChest : treasureChests) { auto info = EntityInfo{}; @@ -517,7 +518,7 @@ void NjMonastryBossInstance::FightOver(Entity* self) { }; // Finally spawn a treasure chest at the correct spawn point - auto* chestObject = EntityManager::Instance()->CreateEntity(info); - EntityManager::Instance()->ConstructEntity(chestObject); + auto* chestObject = Game::entityManager->CreateEntity(info); + Game::entityManager->ConstructEntity(chestObject); } } diff --git a/dScripts/02_server/Minigame/General/MinigameTreasureChestServer.cpp b/dScripts/02_server/Minigame/General/MinigameTreasureChestServer.cpp index 7df8fc12..e06ed1d9 100644 --- a/dScripts/02_server/Minigame/General/MinigameTreasureChestServer.cpp +++ b/dScripts/02_server/Minigame/General/MinigameTreasureChestServer.cpp @@ -21,7 +21,7 @@ void MinigameTreasureChestServer::OnUse(Entity* self, Entity* user) { uint32_t activityRating = 0; if (team != nullptr) { for (const auto& teamMemberID : team->members) { - auto* teamMember = EntityManager::Instance()->GetEntity(teamMemberID); + auto* teamMember = Game::entityManager->GetEntity(teamMemberID); if (teamMember != nullptr) { activityRating = CalculateActivityRating(self, teamMemberID); @@ -40,7 +40,7 @@ void MinigameTreasureChestServer::OnUse(Entity* self, Entity* user) { sac->PlayerRemove(user->GetObjectID()); - auto* zoneControl = dZoneManager::Instance()->GetZoneControlObject(); + auto* zoneControl = Game::zoneManager->GetZoneControlObject(); if (zoneControl != nullptr) { zoneControl->OnFireEventServerSide(self, "Survival_Update", 0); } @@ -56,7 +56,7 @@ uint32_t MinigameTreasureChestServer::CalculateActivityRating(Entity* self, LWOO void MinigameTreasureChestServer::OnStartup(Entity* self) { // BONS treasure chest thinks it's on FV, causing it to start a lobby - if (dZoneManager::Instance()->GetZoneID().GetMapID() == 1204) { + if (Game::zoneManager->GetZoneID().GetMapID() == 1204) { auto* sac = self->GetComponent(); if (sac != nullptr) { sac->SetInstanceMapID(1204); diff --git a/dScripts/02_server/Objects/AgSurvivalBuffStation.cpp b/dScripts/02_server/Objects/AgSurvivalBuffStation.cpp index 4d3482c4..2ce44bd1 100644 --- a/dScripts/02_server/Objects/AgSurvivalBuffStation.cpp +++ b/dScripts/02_server/Objects/AgSurvivalBuffStation.cpp @@ -53,7 +53,7 @@ void AgSurvivalBuffStation::OnTimerDone(Entity* self, std::string timerName) { } auto team = self->GetVar>(u"BuilderTeam"); for (auto memberID : team) { - auto member = EntityManager::Instance()->GetEntity(memberID); + auto member = Game::entityManager->GetEntity(memberID); if (member != nullptr && !member->GetIsDead()) { GameMessages::SendDropClientLoot(member, self->GetObjectID(), powerupToDrop, 0, self->GetPosition()); } else { diff --git a/dScripts/02_server/Objects/StinkyFishTarget.cpp b/dScripts/02_server/Objects/StinkyFishTarget.cpp index 459e0bbe..9840235d 100644 --- a/dScripts/02_server/Objects/StinkyFishTarget.cpp +++ b/dScripts/02_server/Objects/StinkyFishTarget.cpp @@ -25,8 +25,8 @@ void StinkyFishTarget::OnSkillEventFired(Entity* self, Entity* caster, const std new LDFData(u"no_timed_spawn", true) }; - auto* fish = EntityManager::Instance()->CreateEntity(entityInfo); - EntityManager::Instance()->ConstructEntity(fish); + auto* fish = Game::entityManager->CreateEntity(entityInfo); + Game::entityManager->ConstructEntity(fish); self->SetVar(u"fish", fish->GetObjectID()); self->AddTimer("smash", 5.0f); @@ -35,7 +35,7 @@ void StinkyFishTarget::OnSkillEventFired(Entity* self, Entity* caster, const std void StinkyFishTarget::OnTimerDone(Entity* self, std::string timerName) { if (timerName == "smash") { const auto playerID = self->GetVar(u"player"); - auto* fish = EntityManager::Instance()->GetEntity(self->GetVar(u"fish")); + auto* fish = Game::entityManager->GetEntity(self->GetVar(u"fish")); if (fish) { fish->Smash(playerID); diff --git a/dScripts/ActivityManager.cpp b/dScripts/ActivityManager.cpp index 249b2282..c846c944 100644 --- a/dScripts/ActivityManager.cpp +++ b/dScripts/ActivityManager.cpp @@ -20,7 +20,7 @@ void ActivityManager::UpdatePlayer(Entity* self, LWOOBJID playerID, const bool r if (remove) { sac->PlayerRemove(playerID); } else { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player != nullptr) { sac->PlayerJoin(player); SetActivityScore(self, playerID, 0); @@ -63,7 +63,7 @@ void ActivityManager::StopActivity(Entity* self, const LWOOBJID playerID, const if (quit) { UpdatePlayer(self, playerID, true); } else { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) return; @@ -73,30 +73,31 @@ void ActivityManager::StopActivity(Entity* self, const LWOOBJID playerID, const LootGenerator::Instance().GiveActivityLoot(player, self, gameID, CalculateActivityRating(self, playerID)); - // Save the new score to the leaderboard and show the leaderboard to the player - LeaderboardManager::SaveScore(playerID, gameID, score, value1); - const auto* leaderboard = LeaderboardManager::GetLeaderboard(gameID, InfoType::Standings, - false, player->GetObjectID()); - GameMessages::SendActivitySummaryLeaderboardData(self->GetObjectID(), leaderboard, player->GetSystemAddress()); - delete leaderboard; - - // Makes the leaderboard show up for the player - GameMessages::SendNotifyClientObject(self->GetObjectID(), u"ToggleLeaderBoard", - gameID, 0, playerID, "", - player->GetSystemAddress()); - if (sac != nullptr) { sac->PlayerRemove(player->GetObjectID()); } } } +void ActivityManager::SaveScore(Entity* self, const LWOOBJID playerID, const float primaryScore, const float secondaryScore, const float tertiaryScore) const { + auto* player = Game::entityManager->GetEntity(playerID); + if (!player) return; + + auto* sac = self->GetComponent(); + uint32_t gameID = sac != nullptr ? sac->GetActivityID() : self->GetLOT(); + // Save the new score to the leaderboard and show the leaderboard to the player + LeaderboardManager::SaveScore(playerID, gameID, primaryScore, secondaryScore, tertiaryScore); + + // Makes the leaderboard show up for the player + GameMessages::SendNotifyClientObject(self->GetObjectID(), u"ToggleLeaderBoard", gameID, 0, playerID, "", player->GetSystemAddress()); +} + bool ActivityManager::TakeActivityCost(const Entity* self, const LWOOBJID playerID) { auto* sac = self->GetComponent(); if (sac == nullptr) return false; - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) return false; @@ -117,7 +118,10 @@ uint32_t ActivityManager::GetActivityID(const Entity* self) { } void ActivityManager::GetLeaderboardData(Entity* self, const LWOOBJID playerID, const uint32_t activityID, uint32_t numResults) { - LeaderboardManager::SendLeaderboard(activityID, Standings, false, self->GetObjectID(), playerID); + auto* sac = self->GetComponent(); + uint32_t gameID = sac != nullptr ? sac->GetActivityID() : self->GetLOT(); + // Save the new score to the leaderboard and show the leaderboard to the player + LeaderboardManager::SendLeaderboard(activityID, Leaderboard::InfoType::MyStanding, false, playerID, self->GetObjectID(), 0, numResults); } void ActivityManager::ActivityTimerStart(Entity* self, const std::string& timerName, const float_t updateInterval, diff --git a/dScripts/ActivityManager.h b/dScripts/ActivityManager.h index 640cf4bf..a2202bfb 100644 --- a/dScripts/ActivityManager.h +++ b/dScripts/ActivityManager.h @@ -18,6 +18,7 @@ public: static bool TakeActivityCost(const Entity* self, LWOOBJID playerID); static uint32_t GetActivityID(const Entity* self); void StopActivity(Entity* self, LWOOBJID playerID, uint32_t score, uint32_t value1 = 0, uint32_t value2 = 0, bool quit = false); + void SaveScore(Entity* self, const LWOOBJID playerID, const float primaryScore, const float secondaryScore = 0.0f, const float tertiaryScore = 0.0f) const; virtual uint32_t CalculateActivityRating(Entity* self, LWOOBJID playerID); static void GetLeaderboardData(Entity* self, LWOOBJID playerID, uint32_t activityID, uint32_t numResults = 0); // void FreezePlayer(Entity *self, const LWOOBJID playerID, const bool state) const; diff --git a/dScripts/BaseConsoleTeleportServer.cpp b/dScripts/BaseConsoleTeleportServer.cpp index 4a059535..27d2bcfc 100644 --- a/dScripts/BaseConsoleTeleportServer.cpp +++ b/dScripts/BaseConsoleTeleportServer.cpp @@ -1,6 +1,8 @@ #include "BaseConsoleTeleportServer.h" #include "GameMessages.h" #include "Player.h" +#include "RenderComponent.h" +#include "EntityManager.h" #include "eTerminateType.h" #include "eStateChangeType.h" @@ -33,19 +35,17 @@ void BaseConsoleTeleportServer::BaseOnMessageBoxResponse(Entity* self, Entity* s } const auto& teleIntroAnim = self->GetVar(u"teleportAnim"); - + auto animTime = 3.32999992370605f; if (!teleIntroAnim.empty()) { - GameMessages::SendPlayAnimation(player, teleIntroAnim); + animTime = RenderComponent::PlayAnimation(player, teleIntroAnim); } - const auto animTime = 3.32999992370605f; - UpdatePlayerTable(self, player, true); const auto playerID = player->GetObjectID(); self->AddCallbackTimer(animTime, [playerID, self]() { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) { return; diff --git a/dScripts/BasePropertyServer.cpp b/dScripts/BasePropertyServer.cpp index 1522ef26..fe20b09d 100644 --- a/dScripts/BasePropertyServer.cpp +++ b/dScripts/BasePropertyServer.cpp @@ -38,8 +38,8 @@ void BasePropertyServer::SetGameVariables(Entity* self) { self->SetVar>(AmbientFXSpawner, {}); self->SetVar>(BehaviorObjsSpawner, {}); - self->SetVar(defeatedProperyFlag, 0); - self->SetVar(placedModelFlag, 0); + self->SetVar(defeatedProperyFlag, 0); + self->SetVar(placedModelFlag, 0); self->SetVar(guardMissionFlag, 0); self->SetVar(brickLinkMissionIDFlag, 0); self->SetVar(passwordFlag, "s3kratK1ttN"); @@ -49,7 +49,7 @@ void BasePropertyServer::SetGameVariables(Entity* self) { } void BasePropertyServer::CheckForOwner(Entity* self) { - if (EntityManager::Instance()->GetEntitiesInGroup(self->GetVar(PropertyPlaqueGroup)).empty()) { + if (Game::entityManager->GetEntitiesInGroup(self->GetVar(PropertyPlaqueGroup)).empty()) { self->AddTimer(RunPlayerLoadedAgainTimer, 0.5f); return; } @@ -87,12 +87,12 @@ void BasePropertyServer::BasePlayerLoaded(Entity* self, Entity* player) { self->SetNetworkVar(PropertyOwnerIDVariable, propertyOwner); if (rented) { - auto plaques = EntityManager::Instance()->GetEntitiesInGroup("PropertyVendor"); + auto plaques = Game::entityManager->GetEntitiesInGroup("PropertyVendor"); for (auto* plaque : plaques) { - EntityManager::Instance()->DestructEntity(plaque); + Game::entityManager->DestructEntity(plaque); } - const auto& mapID = dZoneManager::Instance()->GetZone()->GetZoneID(); + const auto& mapID = Game::zoneManager->GetZone()->GetZoneID(); if (propertyOwner > 0) { auto* missionComponent = player->GetComponent(); @@ -164,9 +164,9 @@ void BasePropertyServer::BaseZonePropertyRented(Entity* self, Entity* player) co self->AddTimer(BoundsVisOnTimer, 2); self->SetVar(PropertyOwnerVariable, player->GetObjectID()); - auto plaques = EntityManager::Instance()->GetEntitiesInGroup("PropertyVendor"); + auto plaques = Game::entityManager->GetEntitiesInGroup("PropertyVendor"); for (auto* plaque : plaques) { - EntityManager::Instance()->DestructEntity(plaque); + Game::entityManager->DestructEntity(plaque); } auto brickLinkMissionID = self->GetVar(brickLinkMissionIDFlag); @@ -234,7 +234,7 @@ void BasePropertyServer::StartMaelstrom(Entity* self, Entity* player) { } void BasePropertyServer::StartTornadoFx(Entity* self) const { - const auto entities = EntityManager::Instance()->GetEntitiesInGroup(self->GetVar(FXManagerGroup)); + const auto entities = Game::entityManager->GetEntitiesInGroup(self->GetVar(FXManagerGroup)); if (entities.empty()) { self->AddTimer("pollTornadoFX", 0.1f); return; @@ -259,7 +259,7 @@ void BasePropertyServer::BasePlayerExit(Entity* self, Entity* player) { } void BasePropertyServer::KillGuard(Entity* self) { - const auto entities = EntityManager::Instance()->GetEntitiesInGroup(self->GetVar(GuardGroup)); + const auto entities = Game::entityManager->GetEntitiesInGroup(self->GetVar(GuardGroup)); if (entities.empty()) return; @@ -278,31 +278,31 @@ void BasePropertyServer::RequestDie(Entity* self, Entity* other) { } void BasePropertyServer::ActivateSpawner(const std::string& spawnerName) { - for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(spawnerName)) { + for (auto* spawner : Game::zoneManager->GetSpawnersByName(spawnerName)) { spawner->Activate(); } } void BasePropertyServer::DeactivateSpawner(const std::string& spawnerName) { - for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(spawnerName)) { + for (auto* spawner : Game::zoneManager->GetSpawnersByName(spawnerName)) { spawner->Deactivate(); } } void BasePropertyServer::TriggerSpawner(const std::string& spawnerName) { - for (auto* spawner : dZoneManager::Instance()->GetSpawnersInGroup(spawnerName)) { + for (auto* spawner : Game::zoneManager->GetSpawnersInGroup(spawnerName)) { spawner->Spawn(); } } void BasePropertyServer::ResetSpawner(const std::string& spawnerName) { - for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(spawnerName)) { + for (auto* spawner : Game::zoneManager->GetSpawnersByName(spawnerName)) { spawner->Reset(); } } void BasePropertyServer::DestroySpawner(const std::string& spawnerName) { - for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(spawnerName)) { + for (auto* spawner : Game::zoneManager->GetSpawnersByName(spawnerName)) { if (!spawner) return; spawner->DestroyAllEntities(); spawner->Deactivate(); @@ -322,18 +322,18 @@ void BasePropertyServer::BaseTimerDone(Entity* self, const std::string& timerNam } else if (timerName == StartQuickbuildTimer) { HandleQuickBuildTimer(self); } else if (timerName == "GuardFlyAway") { - const auto zoneId = dZoneManager::Instance()->GetZone()->GetWorldID(); + const auto zoneId = Game::zoneManager->GetZone()->GetWorldID(); // No guard for the spider instance fight - if (dZoneManager::Instance()->GetZoneID().GetMapID() == 1150) + if (Game::zoneManager->GetZoneID().GetMapID() == 1150) return; - const auto entities = EntityManager::Instance()->GetEntitiesInGroup(self->GetVar(GuardGroup)); + const auto entities = Game::entityManager->GetEntitiesInGroup(self->GetVar(GuardGroup)); if (entities.empty()) return; auto* guard = entities[0]; - GameMessages::SendNotifyClientObject(EntityManager::Instance()->GetZoneControlEntity()->GetObjectID(), + GameMessages::SendNotifyClientObject(Game::entityManager->GetZoneControlEntity()->GetObjectID(), u"GuardChat", 0, 0, guard->GetObjectID(), "", UNASSIGNED_SYSTEM_ADDRESS); @@ -341,7 +341,7 @@ void BasePropertyServer::BaseTimerDone(Entity* self, const std::string& timerNam } else if (timerName == KillGuardTimer) { KillGuard(self); } else if (timerName == TornadoOffTimer) { - auto fxManagers = EntityManager::Instance()->GetEntitiesInGroup(self->GetVar(FXManagerGroup)); + auto fxManagers = Game::entityManager->GetEntitiesInGroup(self->GetVar(FXManagerGroup)); for (auto* fxManager : fxManagers) { auto* renderComponent = fxManager->GetComponent(); @@ -354,7 +354,7 @@ void BasePropertyServer::BaseTimerDone(Entity* self, const std::string& timerNam self->AddTimer(ShowClearEffectsTimer, 2); } else if (timerName == ShowClearEffectsTimer) { - auto fxManagers = EntityManager::Instance()->GetEntitiesInGroup(self->GetVar(FXManagerGroup)); + auto fxManagers = Game::entityManager->GetEntitiesInGroup(self->GetVar(FXManagerGroup)); for (auto* fxManager : fxManagers) { auto* renderComponent = fxManager->GetComponent(); @@ -366,11 +366,11 @@ void BasePropertyServer::BaseTimerDone(Entity* self, const std::string& timerNam self->AddTimer(TurnSkyOffTimer, 1.5f); self->AddTimer(KillFXObjectTimer, 8.0f); } else if (timerName == TurnSkyOffTimer) { - auto* controller = dZoneManager::Instance()->GetZoneControlObject(); + auto* controller = Game::zoneManager->GetZoneControlObject(); GameMessages::SendNotifyClientObject(controller->GetObjectID(), u"SkyOff", 0, 0, LWOOBJID_EMPTY, "", UNASSIGNED_SYSTEM_ADDRESS); } else if (timerName == KillStrombiesTimer) { - const auto enemies = EntityManager::Instance()->GetEntitiesInGroup(self->GetVar(EnemiesGroup)); + const auto enemies = Game::entityManager->GetEntitiesInGroup(self->GetVar(EnemiesGroup)); for (auto* enemy : enemies) { RequestDie(self, enemy); } @@ -378,7 +378,7 @@ void BasePropertyServer::BaseTimerDone(Entity* self, const std::string& timerNam DestroySpawner(self->GetVar(SmashablesSpawner)); KillSpots(self); - auto* player = EntityManager::Instance()->GetEntity(self->GetVar(PlayerIDVariable)); + auto* player = Game::entityManager->GetEntity(self->GetVar(PlayerIDVariable)); if (player == nullptr) return; @@ -393,7 +393,7 @@ void BasePropertyServer::BaseTimerDone(Entity* self, const std::string& timerNam DestroySpawner(behaviorObjectSpawner); } - for (auto* entity : EntityManager::Instance()->GetEntitiesInGroup(self->GetVar(ImagOrbGroup))) { + for (auto* entity : Game::entityManager->GetEntitiesInGroup(self->GetVar(ImagOrbGroup))) { entity->Smash(); } @@ -401,7 +401,7 @@ void BasePropertyServer::BaseTimerDone(Entity* self, const std::string& timerNam self->AddTimer(ShowVendorTimer, 1.0f); } else if (timerName == ShowVendorTimer) { - GameMessages::SendNotifyClientObject(EntityManager::Instance()->GetZoneControlEntity()->GetObjectID(), + GameMessages::SendNotifyClientObject(Game::entityManager->GetZoneControlEntity()->GetObjectID(), u"vendorOn", 0, 0, LWOOBJID_EMPTY, "", UNASSIGNED_SYSTEM_ADDRESS); @@ -416,7 +416,7 @@ void BasePropertyServer::BaseTimerDone(Entity* self, const std::string& timerNam } else if (timerName == PollTornadoFXTimer) { StartTornadoFx(self); } else if (timerName == KillFXObjectTimer) { - const auto fxManagers = EntityManager::Instance()->GetEntitiesInGroup(self->GetVar(FXManagerGroup)); + const auto fxManagers = Game::entityManager->GetEntitiesInGroup(self->GetVar(FXManagerGroup)); if (fxManagers.empty()) { self->AddTimer(KillFXObjectTimer, 1.0f); return; @@ -436,7 +436,7 @@ void BasePropertyServer::BaseTimerDone(Entity* self, const std::string& timerNam void BasePropertyServer::HandleOrbsTimer(Entity* self) { self->SetVar(CollidedVariable, false); - auto orbs = EntityManager::Instance()->GetEntitiesInGroup(self->GetVar(ImagOrbGroup)); + auto orbs = Game::entityManager->GetEntitiesInGroup(self->GetVar(ImagOrbGroup)); if (orbs.empty()) { self->AddTimer(StartOrbTimer, 0.5f); return; @@ -455,12 +455,12 @@ void BasePropertyServer::HandleOrbsTimer(Entity* self) { } DestroySpawner(self->GetVar(GeneratorFXSpawner)); - GameMessages::SendNotifyClientObject(EntityManager::Instance()->GetZoneControlEntity()->GetObjectID(), + GameMessages::SendNotifyClientObject(Game::entityManager->GetZoneControlEntity()->GetObjectID(), u"PlayCinematic", 0, 0, LWOOBJID_EMPTY, "DestroyMaelstrom", UNASSIGNED_SYSTEM_ADDRESS); // Notifies the client that the property has been claimed with a flag, completes missions too - auto* player = EntityManager::Instance()->GetEntity(self->GetVar(PlayerIDVariable)); + auto* player = Game::entityManager->GetEntity(self->GetVar(PlayerIDVariable)); if (player != nullptr) { auto* character = player->GetCharacter(); if (character != nullptr) { @@ -476,7 +476,7 @@ void BasePropertyServer::HandleOrbsTimer(Entity* self) { } void BasePropertyServer::HandleGeneratorTimer(Entity* self) { - auto generators = EntityManager::Instance()->GetEntitiesInGroup(self->GetVar(GeneratorGroup)); + auto generators = Game::entityManager->GetEntitiesInGroup(self->GetVar(GeneratorGroup)); if (generators.empty()) { self->AddTimer(StartGeneratorTimer, 0.5f); return; @@ -496,7 +496,7 @@ void BasePropertyServer::HandleGeneratorTimer(Entity* self) { } void BasePropertyServer::HandleQuickBuildTimer(Entity* self) { - auto claimMarkers = EntityManager::Instance()->GetEntitiesInGroup(self->GetVar(ClaimMarkerGroup)); + auto claimMarkers = Game::entityManager->GetEntitiesInGroup(self->GetVar(ClaimMarkerGroup)); if (claimMarkers.empty()) { self->AddTimer(StartQuickbuildTimer, 0.5f); return; diff --git a/dScripts/BaseRandomServer.cpp b/dScripts/BaseRandomServer.cpp index 8cc4f993..293fb79a 100644 --- a/dScripts/BaseRandomServer.cpp +++ b/dScripts/BaseRandomServer.cpp @@ -52,7 +52,7 @@ void BaseRandomServer::SpawnSection(Entity* self, const std::string& sectionName } void BaseRandomServer::SetSpawnerNetwork(Entity* self, const std::string& spawnerName, int32_t spawnNum, LOT spawnLOT) { - const auto& spawners = dZoneManager::Instance()->GetSpawnersByName(spawnerName); + const auto& spawners = Game::zoneManager->GetSpawnersByName(spawnerName); if (spawnLOT == 11217 && spawnNum > 1) { spawnNum = 1; diff --git a/dScripts/BaseSurvivalServer.cpp b/dScripts/BaseSurvivalServer.cpp index 3d72628d..0e8d0431 100644 --- a/dScripts/BaseSurvivalServer.cpp +++ b/dScripts/BaseSurvivalServer.cpp @@ -8,6 +8,8 @@ #include "eMissionState.h" #include "MissionComponent.h" #include "Character.h" +#include "Game.h" +#include "dConfig.h" void BaseSurvivalServer::SetGameVariables(Entity* self) { this->constants = std::move(GetConstants()); @@ -212,7 +214,7 @@ void BaseSurvivalServer::OnActivityTimerDone(Entity* self, const std::string& na ActivityTimerStart(self, PlaySpawnSoundTimer, 3, 3); } else if (name == PlaySpawnSoundTimer) { for (const auto& playerID : state.players) { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player != nullptr) { GameMessages::SendPlayNDAudioEmitter(player, player->GetSystemAddress(), spawnSoundGUID); } @@ -221,7 +223,7 @@ void BaseSurvivalServer::OnActivityTimerDone(Entity* self, const std::string& na } void BaseSurvivalServer::ResetStats(LWOOBJID playerID) { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player != nullptr) { // Boost all the player stats when loading in @@ -284,7 +286,7 @@ void BaseSurvivalServer::StartWaves(Entity* self) { state.waitingPlayers.clear(); for (const auto& playerID : state.players) { - const auto player = EntityManager::Instance()->GetEntity(playerID); + const auto player = Game::entityManager->GetEntity(playerID); if (player != nullptr) { state.waitingPlayers.push_back(playerID); UpdatePlayer(self, playerID); @@ -311,7 +313,7 @@ bool BaseSurvivalServer::CheckAllPlayersDead() { auto deadPlayers = 0; for (const auto& playerID : state.players) { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr || player->GetIsDead()) { deadPlayers++; } @@ -323,9 +325,9 @@ bool BaseSurvivalServer::CheckAllPlayersDead() { void BaseSurvivalServer::SetPlayerSpawnPoints() { auto spawnerIndex = 1; for (const auto& playerID : state.players) { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player != nullptr) { - auto possibleSpawners = EntityManager::Instance()->GetEntitiesInGroup("P" + std::to_string(spawnerIndex) + "_Spawn"); + auto possibleSpawners = Game::entityManager->GetEntitiesInGroup("P" + std::to_string(spawnerIndex) + "_Spawn"); if (!possibleSpawners.empty()) { auto* spawner = possibleSpawners.at(0); GameMessages::SendTeleport(playerID, spawner->GetPosition(), spawner->GetRotation(), player->GetSystemAddress(), true); @@ -348,12 +350,13 @@ void BaseSurvivalServer::GameOver(Entity* self) { SpawnerReset(spawnerNetworks.rewardNetworks); for (const auto& playerID : state.players) { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) continue; const auto score = GetActivityValue(self, playerID, 0); const auto time = GetActivityValue(self, playerID, 1); + SaveScore(self, playerID, score, time); GameMessages::SendNotifyClientZoneObject(self->GetObjectID(), u"Update_ScoreBoard", time, 0, playerID, std::to_string(score), UNASSIGNED_SYSTEM_ADDRESS); @@ -399,7 +402,7 @@ void BaseSurvivalServer::SpawnerReset(SpawnerNetworkCollection& spawnerNetworkCo for (auto& spawner : spawnerNetworkCollection.networks) { for (auto& spawnerName : spawner.names) { - auto spawners = dZoneManager::Instance()->GetSpawnersByName(spawnerName + spawner.number); + auto spawners = Game::zoneManager->GetSpawnersByName(spawnerName + spawner.number); if (!spawners.empty()) { auto* spawnerObject = spawners.at(0); @@ -428,7 +431,7 @@ void BaseSurvivalServer::SpawnerUpdate(Entity* self, SpawnerNetworkCollection& s // If we want to spawn something specific now if (amount != 0) { auto spawnerNetwork = spawnerNetworkCollection.networks.at(0); - auto possibleSpawners = dZoneManager::Instance()->GetSpawnersByName(spawnerNetwork.names.at(0) + spawnerNetwork.number); + auto possibleSpawners = Game::zoneManager->GetSpawnersByName(spawnerNetwork.names.at(0) + spawnerNetwork.number); if (!possibleSpawners.empty()) { SpawnNow(possibleSpawners.at(0), amount); return; @@ -444,7 +447,7 @@ void BaseSurvivalServer::SpawnerUpdate(Entity* self, SpawnerNetworkCollection& s const auto& name = spawnerNetwork.names.at(i); const auto& toSpawn = newSet.at(i); - auto possibleSpawners = dZoneManager::Instance()->GetSpawnersByName(name + spawnerNetwork.number); + auto possibleSpawners = Game::zoneManager->GetSpawnersByName(name + spawnerNetwork.number); if (!possibleSpawners.empty()) { SpawnNow(possibleSpawners.front(), toSpawn); } @@ -495,7 +498,7 @@ SpawnerNetwork BaseSurvivalServer::GetRandomSpawner(SpawnerNetworkCollection& sp void BaseSurvivalServer::ActivateSpawnerNetwork(SpawnerNetworkCollection& spawnerNetworkCollection) { for (auto& spawner : spawnerNetworkCollection.networks) { for (const auto& spawnerName : spawner.names) { - auto possibleSpawners = dZoneManager::Instance()->GetSpawnersByName(spawnerName + spawner.number); + auto possibleSpawners = Game::zoneManager->GetSpawnersByName(spawnerName + spawner.number); if (!possibleSpawners.empty()) { auto* spawnerObject = possibleSpawners.at(0); spawnerObject->Activate(); @@ -509,7 +512,7 @@ void BaseSurvivalServer::UpdateMobLots(SpawnerNetworkCollection& spawnerNetworkC for (auto& spawner : spawnerNetworkCollection.networks) { for (auto& spawnerName : spawner.names) { if (!spawnerName.empty()) { - auto spawnerObjects = dZoneManager::Instance()->GetSpawnersByName(spawnerName + spawner.number); + auto spawnerObjects = Game::zoneManager->GetSpawnersByName(spawnerName + spawner.number); if (!spawnerObjects.empty()) { auto splitName = GeneralUtils::SplitString(spawnerName, '_'); auto cleanName = splitName.size() > 1 ? splitName.at(1) : splitName.at(0); diff --git a/dScripts/BaseWavesGenericEnemy.cpp b/dScripts/BaseWavesGenericEnemy.cpp index 3270e2d8..1e66bfeb 100644 --- a/dScripts/BaseWavesGenericEnemy.cpp +++ b/dScripts/BaseWavesGenericEnemy.cpp @@ -6,7 +6,7 @@ void BaseWavesGenericEnemy::OnStartup(Entity* self) { } void BaseWavesGenericEnemy::OnDie(Entity* self, Entity* killer) { - auto* zoneControlObject = dZoneManager::Instance()->GetZoneControlObject(); + auto* zoneControlObject = Game::zoneManager->GetZoneControlObject(); if (zoneControlObject != nullptr) { zoneControlObject->OnFireEventServerSide(killer, "Survival_Update", GetPoints()); } diff --git a/dScripts/BaseWavesServer.cpp b/dScripts/BaseWavesServer.cpp index 00340bd0..1090d8c5 100644 --- a/dScripts/BaseWavesServer.cpp +++ b/dScripts/BaseWavesServer.cpp @@ -195,7 +195,7 @@ void BaseWavesServer::OnActivityTimerDone(Entity* self, const std::string& name) ActivityTimerStart(self, PlaySpawnSoundTimer, 3, 3); } else if (name == PlaySpawnSoundTimer) { for (const auto& playerID : state.players) { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player != nullptr) { GameMessages::SendPlayNDAudioEmitter(player, player->GetSystemAddress(), spawnSoundGUID); } @@ -216,7 +216,7 @@ void BaseWavesServer::OnActivityTimerDone(Entity* self, const std::string& name) } else if (name == GameOverWinTimer) { GameOver(self, true); } else if (name == CinematicDoneTimer) { - for (auto* boss : EntityManager::Instance()->GetEntitiesInGroup("boss")) { + for (auto* boss : Game::entityManager->GetEntitiesInGroup("boss")) { boss->OnFireEventServerSide(self, "startAI"); } } @@ -224,7 +224,7 @@ void BaseWavesServer::OnActivityTimerDone(Entity* self, const std::string& name) // Done void BaseWavesServer::ResetStats(LWOOBJID playerID) { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player != nullptr) { // Boost all the player stats when loading in @@ -284,7 +284,7 @@ void BaseWavesServer::StartWaves(Entity* self) { state.waitingPlayers.clear(); for (const auto& playerID : state.players) { - const auto player = EntityManager::Instance()->GetEntity(playerID); + const auto player = Game::entityManager->GetEntity(playerID); if (player != nullptr) { state.waitingPlayers.push_back(playerID); @@ -309,7 +309,7 @@ bool BaseWavesServer::CheckAllPlayersDead() { auto deadPlayers = 0; for (const auto& playerID : state.players) { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr || player->GetIsDead()) { deadPlayers++; } @@ -322,9 +322,9 @@ bool BaseWavesServer::CheckAllPlayersDead() { void BaseWavesServer::SetPlayerSpawnPoints(const LWOOBJID& specificPlayerID) { auto spawnerIndex = 1; for (const auto& playerID : state.players) { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player != nullptr && (specificPlayerID == LWOOBJID_EMPTY || playerID == specificPlayerID)) { - auto possibleSpawners = EntityManager::Instance()->GetEntitiesInGroup("P" + std::to_string(spawnerIndex) + "_Spawn"); + auto possibleSpawners = Game::entityManager->GetEntitiesInGroup("P" + std::to_string(spawnerIndex) + "_Spawn"); if (!possibleSpawners.empty()) { auto* spawner = possibleSpawners.at(0); GameMessages::SendTeleport(playerID, spawner->GetPosition(), spawner->GetRotation(), player->GetSystemAddress(), true); @@ -353,7 +353,7 @@ void BaseWavesServer::GameOver(Entity* self, bool won) { ClearSpawners(); for (const auto& playerID : state.players) { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) continue; @@ -378,6 +378,7 @@ void BaseWavesServer::GameOver(Entity* self, bool won) { } StopActivity(self, playerID, wave, time, score); + SaveScore(self, playerID, wave, time); } } @@ -392,7 +393,7 @@ void BaseWavesServer::GameWon(Entity* self) { // Done void BaseWavesServer::SpawnNow(const std::string& spawnerName, uint32_t amount, LOT spawnLot) { - const auto spawners = dZoneManager::Instance()->GetSpawnersByName(spawnerName); + const auto spawners = Game::zoneManager->GetSpawnersByName(spawnerName); for (auto* spawner : spawners) { if (spawnLot != LOT_NULL) { spawner->SetSpawnLot(spawnLot); @@ -429,7 +430,7 @@ void BaseWavesServer::SpawnWave(Entity* self) { } for (const auto& playerID : state.players) { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player && player->GetIsDead()) { player->Resurrect(); } @@ -471,7 +472,7 @@ bool BaseWavesServer::UpdateSpawnedEnemies(Entity* self, LWOOBJID enemyID, uint3 state.currentSpawned--; - auto* enemy = EntityManager::Instance()->GetEntity(enemyID); + auto* enemy = Game::entityManager->GetEntity(enemyID); if (enemy != nullptr && enemy->IsPlayer() && IsPlayerInActivity(self, enemyID)) { SetActivityValue(self, enemyID, 0, GetActivityValue(self, enemyID, 0) + score); } @@ -499,7 +500,7 @@ bool BaseWavesServer::UpdateSpawnedEnemies(Entity* self, LWOOBJID enemyID, uint3 const auto soloWaveMissions = waves.at(completedWave).soloMissions; for (const auto& playerID : state.players) { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player != nullptr && !player->GetIsDead()) { SetActivityValue(self, playerID, 1, currentTime); SetActivityValue(self, playerID, 2, state.waveNumber); @@ -558,7 +559,7 @@ bool BaseWavesServer::UpdateSpawnedEnemies(Entity* self, LWOOBJID enemyID, uint3 // Done void BaseWavesServer::UpdateMissionForAllPlayers(Entity* self, uint32_t missionID) { for (const auto& playerID : state.players) { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player != nullptr) { auto* missionComponent = player->GetComponent(); if (missionComponent == nullptr) return; @@ -581,7 +582,7 @@ void BaseWavesServer::UpdateMissionForAllPlayers(Entity* self, uint32_t missionI void BaseWavesServer::ClearSpawners() { for (const auto& spawnerName : spawners) { - const auto spawnerObjects = dZoneManager::Instance()->GetSpawnersByName(spawnerName); + const auto spawnerObjects = Game::zoneManager->GetSpawnersByName(spawnerName); for (auto* spawnerObject : spawnerObjects) { spawnerObject->Reset(); diff --git a/dScripts/CppScripts.h b/dScripts/CppScripts.h index 4bf3720f..1b9d0591 100644 --- a/dScripts/CppScripts.h +++ b/dScripts/CppScripts.h @@ -349,6 +349,15 @@ namespace CppScripts { * @param itemObjId The items Object ID */ virtual void OnFactionTriggerItemUnequipped(Entity* itemOwner, LWOOBJID itemObjId) {}; + + /** + * Handles exiting a scripted activity + * + * @param sender + * @param player the player to remove + * @param canceled if it was done via the cancel button + */ + virtual void OnRequestActivityExit(Entity* sender, LWOOBJID player, bool canceled){}; }; Script* GetScript(Entity* parent, const std::string& scriptName); diff --git a/dScripts/Darkitect.cpp b/dScripts/Darkitect.cpp index b4364332..2881bde8 100644 --- a/dScripts/Darkitect.cpp +++ b/dScripts/Darkitect.cpp @@ -12,7 +12,7 @@ void Darkitect::Reveal(Entity* self, Entity* player) { GameMessages::SendNotifyClientObject(self->GetObjectID(), u"reveal", 0, 0, playerID, "", player->GetSystemAddress()); self->AddCallbackTimer(20, [this, self, playerID]() { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (!player) return; @@ -29,7 +29,7 @@ void Darkitect::Reveal(Entity* self, Entity* player) { character->SetPlayerFlag(1911, true); } - EntityManager::Instance()->SerializeEntity(player); + Game::entityManager->SerializeEntity(player); } }); } diff --git a/dScripts/EquipmentScripts/BuccaneerValiantShip.cpp b/dScripts/EquipmentScripts/BuccaneerValiantShip.cpp index 3db214b5..15954622 100644 --- a/dScripts/EquipmentScripts/BuccaneerValiantShip.cpp +++ b/dScripts/EquipmentScripts/BuccaneerValiantShip.cpp @@ -11,7 +11,7 @@ void BuccaneerValiantShip::OnStartup(Entity* self) { // Kill self if missed self->AddCallbackTimer(1.1F, [self]() { - self->Kill(); + self->Smash(); }); } }); diff --git a/dScripts/EquipmentScripts/PersonalFortress.cpp b/dScripts/EquipmentScripts/PersonalFortress.cpp index f1fe73ee..7e6d3566 100644 --- a/dScripts/EquipmentScripts/PersonalFortress.cpp +++ b/dScripts/EquipmentScripts/PersonalFortress.cpp @@ -26,7 +26,7 @@ void PersonalFortress::OnStartup(Entity* self) { true, true, true, true, true, true, true, true, true ); - EntityManager::Instance()->SerializeEntity(owner); + Game::entityManager->SerializeEntity(owner); } void PersonalFortress::OnDie(Entity* self, Entity* killer) { @@ -47,7 +47,7 @@ void PersonalFortress::OnDie(Entity* self, Entity* killer) { true, true, true, true, true, true, true, true, true ); - EntityManager::Instance()->SerializeEntity(owner); + Game::entityManager->SerializeEntity(owner); } void PersonalFortress::OnTimerDone(Entity* self, std::string timerName) { diff --git a/dScripts/ScriptedPowerupSpawner.cpp b/dScripts/ScriptedPowerupSpawner.cpp index 3c1d1cca..2c502f26 100644 --- a/dScripts/ScriptedPowerupSpawner.cpp +++ b/dScripts/ScriptedPowerupSpawner.cpp @@ -21,7 +21,7 @@ void ScriptedPowerupSpawner::OnTimerDone(Entity* self, std::string message) { drops.emplace(itemLOT, 1); // Spawn the required number of powerups - auto* owner = EntityManager::Instance()->GetEntity(self->GetSpawnerID()); + auto* owner = Game::entityManager->GetEntity(self->GetSpawnerID()); if (owner != nullptr) { auto* renderComponent = self->GetComponent(); for (auto i = 0; i < self->GetVar(u"numberOfPowerups"); i++) { diff --git a/dScripts/SpawnPetBaseServer.cpp b/dScripts/SpawnPetBaseServer.cpp index 75b46382..395a20c2 100644 --- a/dScripts/SpawnPetBaseServer.cpp +++ b/dScripts/SpawnPetBaseServer.cpp @@ -11,7 +11,7 @@ void SpawnPetBaseServer::OnStartup(Entity* self) { } void SpawnPetBaseServer::OnUse(Entity* self, Entity* user) { - auto possibleSpawners = EntityManager::Instance()->GetEntitiesInGroup(self->GetVar(u"petType") + "Spawner"); + auto possibleSpawners = Game::entityManager->GetEntitiesInGroup(self->GetVar(u"petType") + "Spawner"); if (possibleSpawners.empty()) return; @@ -33,8 +33,8 @@ void SpawnPetBaseServer::OnUse(Entity* self, Entity* user) { new LDFData(u"spawnTimer", 1.0f) }; - auto* pet = EntityManager::Instance()->CreateEntity(info); - EntityManager::Instance()->ConstructEntity(pet); + auto* pet = Game::entityManager->CreateEntity(info); + Game::entityManager->ConstructEntity(pet); self->SetVar(u"spawnedPets", self->GetVar(u"spawnedPets") + "," + std::to_string(pet->GetObjectID())); @@ -57,7 +57,7 @@ bool SpawnPetBaseServer::CheckNumberOfPets(Entity* self, Entity* user) { if (petID.empty()) continue; - const auto* spawnedPet = EntityManager::Instance()->GetEntity(std::stoull(petID)); + const auto* spawnedPet = Game::entityManager->GetEntity(std::stoull(petID)); if (spawnedPet == nullptr) continue; diff --git a/dScripts/ai/ACT/ActVehicleDeathTrigger.cpp b/dScripts/ai/ACT/ActVehicleDeathTrigger.cpp index 76c0289e..90333063 100644 --- a/dScripts/ai/ACT/ActVehicleDeathTrigger.cpp +++ b/dScripts/ai/ACT/ActVehicleDeathTrigger.cpp @@ -14,7 +14,7 @@ void ActVehicleDeathTrigger::OnCollisionPhantom(Entity* self, Entity* target) { Entity* player; if (possessableComponent != nullptr) { - auto* player = EntityManager::Instance()->GetEntity(possessableComponent->GetPossessor()); + auto* player = Game::entityManager->GetEntity(possessableComponent->GetPossessor()); if (player == nullptr) { return; @@ -28,7 +28,7 @@ void ActVehicleDeathTrigger::OnCollisionPhantom(Entity* self, Entity* target) { return; } - vehicle = EntityManager::Instance()->GetEntity(possessorComponent->GetPossessable()); + vehicle = Game::entityManager->GetEntity(possessorComponent->GetPossessable()); if (vehicle == nullptr) { return; @@ -42,7 +42,7 @@ void ActVehicleDeathTrigger::OnCollisionPhantom(Entity* self, Entity* target) { GameMessages::SendDie(vehicle, self->GetObjectID(), LWOOBJID_EMPTY, true, eKillType::VIOLENT, u"", 0, 0, 0, true, false, 0); - auto* zoneController = dZoneManager::Instance()->GetZoneControlObject(); + auto* zoneController = Game::zoneManager->GetZoneControlObject(); auto* racingControlComponent = zoneController->GetComponent(); diff --git a/dScripts/ai/ACT/FootRace/BaseFootRaceManager.cpp b/dScripts/ai/ACT/FootRace/BaseFootRaceManager.cpp index 4d1ae5f5..c02bf565 100644 --- a/dScripts/ai/ACT/FootRace/BaseFootRaceManager.cpp +++ b/dScripts/ai/ACT/FootRace/BaseFootRaceManager.cpp @@ -1,18 +1,18 @@ #include "BaseFootRaceManager.h" #include "EntityManager.h" #include "Character.h" +#include "Entity.h" void BaseFootRaceManager::OnStartup(Entity* self) { // TODO: Add to FootRaceStarter group } -void BaseFootRaceManager::OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, - int32_t param2, int32_t param3) { +void BaseFootRaceManager::OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2, int32_t param3) { const auto splitArguments = GeneralUtils::SplitString(args, '_'); if (splitArguments.size() > 1) { const auto eventName = splitArguments[0]; - const auto player = EntityManager::Instance()->GetEntity(std::stoull(splitArguments[1])); + const auto player = Game::entityManager->GetEntity(std::stoull(splitArguments[1])); if (player != nullptr) { if (eventName == "updatePlayer") { @@ -37,10 +37,11 @@ void BaseFootRaceManager::OnFireEventServerSide(Entity* self, Entity* sender, st if (character != nullptr) { character->SetPlayerFlag(115, false); if (param2 != -1) // Certain footraces set a flag - character->SetPlayerFlag(static_cast(param2), true); + character->SetPlayerFlag(param2, true); } StopActivity(self, player->GetObjectID(), 0, param1); + SaveScore(self, player->GetObjectID(), static_cast(param1), static_cast(param2), static_cast(param3)); } } } diff --git a/dScripts/ai/AG/AgBusDoor.cpp b/dScripts/ai/AG/AgBusDoor.cpp index 4910d0c5..fd6c272e 100644 --- a/dScripts/ai/AG/AgBusDoor.cpp +++ b/dScripts/ai/AG/AgBusDoor.cpp @@ -24,12 +24,12 @@ void AgBusDoor::OnProximityUpdate(Entity* self, Entity* entering, std::string na m_OuterCounter = 0; for (const auto& pair : proximityMonitorComponent->GetProximityObjects("busDoor")) { - auto* entity = EntityManager::Instance()->GetEntity(pair.first); + auto* entity = Game::entityManager->GetEntity(pair.first); if (entity != nullptr && entity->IsPlayer()) m_Counter++; } for (const auto& pair : proximityMonitorComponent->GetProximityObjects("busDoorOuter")) { - auto* entity = EntityManager::Instance()->GetEntity(pair.first); + auto* entity = Game::entityManager->GetEntity(pair.first); if (entity != nullptr && entity->IsPlayer()) m_OuterCounter++; } diff --git a/dScripts/ai/AG/AgFans.cpp b/dScripts/ai/AG/AgFans.cpp index e05fe68d..15f2ed0f 100644 --- a/dScripts/ai/AG/AgFans.cpp +++ b/dScripts/ai/AG/AgFans.cpp @@ -5,6 +5,8 @@ #include "PhantomPhysicsComponent.h" #include "RenderComponent.h" #include "eReplicaComponentType.h" +#include "RenderComponent.h" +#include "Entity.h" void AgFans::OnStartup(Entity* self) { self->SetVar(u"alive", true); @@ -23,7 +25,7 @@ void AgFans::OnStartup(Entity* self) { void AgFans::ToggleFX(Entity* self, bool hit) { std::string fanGroup = self->GetGroups()[0]; - std::vector fanVolumes = EntityManager::Instance()->GetEntitiesInGroup(fanGroup); + std::vector fanVolumes = Game::entityManager->GetEntitiesInGroup(fanGroup); auto* renderComponent = static_cast(self->GetComponent(eReplicaComponentType::RENDER)); @@ -34,7 +36,7 @@ void AgFans::ToggleFX(Entity* self, bool hit) { if (fanVolumes.size() == 0 || !self->GetVar(u"alive")) return; if (self->GetVar(u"on")) { - GameMessages::SendPlayAnimation(self, u"fan-off"); + RenderComponent::PlayAnimation(self, u"fan-off"); renderComponent->StopEffect("fanOn"); self->SetVar(u"on", false); @@ -43,14 +45,14 @@ void AgFans::ToggleFX(Entity* self, bool hit) { PhantomPhysicsComponent* volumePhys = static_cast(volume->GetComponent(eReplicaComponentType::PHANTOM_PHYSICS)); if (!volumePhys) continue; volumePhys->SetPhysicsEffectActive(false); - EntityManager::Instance()->SerializeEntity(volume); + Game::entityManager->SerializeEntity(volume); if (!hit) { - Entity* fxObj = EntityManager::Instance()->GetEntitiesInGroup(fanGroup + "fx")[0]; - GameMessages::SendPlayAnimation(fxObj, u"trigger"); + Entity* fxObj = Game::entityManager->GetEntitiesInGroup(fanGroup + "fx")[0]; + RenderComponent::PlayAnimation(fxObj, u"trigger"); } } } else if (!self->GetVar(u"on") && self->GetVar(u"alive")) { - GameMessages::SendPlayAnimation(self, u"fan-on"); + RenderComponent::PlayAnimation(self, u"fan-on"); renderComponent->PlayEffect(495, u"fanOn", "fanOn"); self->SetVar(u"on", true); @@ -59,10 +61,10 @@ void AgFans::ToggleFX(Entity* self, bool hit) { PhantomPhysicsComponent* volumePhys = static_cast(volume->GetComponent(eReplicaComponentType::PHANTOM_PHYSICS)); if (!volumePhys) continue; volumePhys->SetPhysicsEffectActive(true); - EntityManager::Instance()->SerializeEntity(volume); + Game::entityManager->SerializeEntity(volume); if (!hit) { - Entity* fxObj = EntityManager::Instance()->GetEntitiesInGroup(fanGroup + "fx")[0]; - GameMessages::SendPlayAnimation(fxObj, u"idle"); + Entity* fxObj = Game::entityManager->GetEntitiesInGroup(fanGroup + "fx")[0]; + RenderComponent::PlayAnimation(fxObj, u"idle"); } } } diff --git a/dScripts/ai/AG/AgImagSmashable.cpp b/dScripts/ai/AG/AgImagSmashable.cpp index 5e8331b1..2a35ed9a 100644 --- a/dScripts/ai/AG/AgImagSmashable.cpp +++ b/dScripts/ai/AG/AgImagSmashable.cpp @@ -36,9 +36,9 @@ void AgImagSmashable::CrateAnimal(Entity* self) { info.spawnerID = self->GetSpawnerID(); info.spawnerNodeID = 0; - Entity* newEntity = EntityManager::Instance()->CreateEntity(info, nullptr); + Entity* newEntity = Game::entityManager->CreateEntity(info, nullptr); if (newEntity) { - EntityManager::Instance()->ConstructEntity(newEntity); + Game::entityManager->ConstructEntity(newEntity); } } } diff --git a/dScripts/ai/AG/AgJetEffectServer.cpp b/dScripts/ai/AG/AgJetEffectServer.cpp index 3d132991..5d25c9e0 100644 --- a/dScripts/ai/AG/AgJetEffectServer.cpp +++ b/dScripts/ai/AG/AgJetEffectServer.cpp @@ -3,6 +3,7 @@ #include "EntityManager.h" #include "SkillComponent.h" #include "eReplicaComponentType.h" +#include "RenderComponent.h" void AgJetEffectServer::OnUse(Entity* self, Entity* user) { if (inUse || self->GetLOT() != 6859) return; @@ -11,7 +12,7 @@ void AgJetEffectServer::OnUse(Entity* self, Entity* user) { ); inUse = true; - auto entities = EntityManager::Instance()->GetEntitiesInGroup("Jet_FX"); + auto entities = Game::entityManager->GetEntitiesInGroup("Jet_FX"); if (entities.empty()) return; GameMessages::SendPlayFXEffect(entities.at(0), 641, u"create", "radarDish", LWOOBJID_EMPTY, 1, 1, true); self->AddTimer("radarDish", 2.0f); @@ -21,9 +22,9 @@ void AgJetEffectServer::OnUse(Entity* self, Entity* user) { void AgJetEffectServer::OnRebuildComplete(Entity* self, Entity* target) { if (self->GetLOT() != 6209) return; - auto entities = EntityManager::Instance()->GetEntitiesInGroup("Jet_FX"); + auto entities = Game::entityManager->GetEntitiesInGroup("Jet_FX"); if (entities.empty()) return; - GameMessages::SendPlayAnimation(entities.at(0), u"jetFX"); + RenderComponent::PlayAnimation(entities.at(0), u"jetFX"); // So we can give kill credit to person who build this builder = target->GetObjectID(); @@ -39,7 +40,7 @@ void AgJetEffectServer::OnTimerDone(Entity* self, std::string timerName) { if (timerName == "radarDish") { GameMessages::SendStopFXEffect(self, true, "radarDish"); } else if (timerName == "PlayEffect") { - auto entities = EntityManager::Instance()->GetEntitiesInGroup("mortarMain"); + auto entities = Game::entityManager->GetEntitiesInGroup("mortarMain"); if (entities.empty()) return; const auto selected = GeneralUtils::GenerateRandomNumber(0, entities.size() - 1); diff --git a/dScripts/ai/AG/AgQbElevator.cpp b/dScripts/ai/AG/AgQbElevator.cpp index e1d78a21..5a535347 100644 --- a/dScripts/ai/AG/AgQbElevator.cpp +++ b/dScripts/ai/AG/AgQbElevator.cpp @@ -26,7 +26,7 @@ void AgQbElevator::OnProximityUpdate(Entity* self, Entity* entering, std::string if (self->GetBoolean(u"qbPlayerRdy")) return; if (status == "ENTER") { - Entity* builder = EntityManager::Instance()->GetEntity(self->GetI64(u"qbPlayer")); + Entity* builder = Game::entityManager->GetEntity(self->GetI64(u"qbPlayer")); if (builder && builder == entering) { //the builder has entered so cancel the start timer and just start moving self->SetBoolean(u"qbPlayerRdy", true); diff --git a/dScripts/ai/AG/AgQbWall.cpp b/dScripts/ai/AG/AgQbWall.cpp index d6222419..3e7d9c2b 100644 --- a/dScripts/ai/AG/AgQbWall.cpp +++ b/dScripts/ai/AG/AgQbWall.cpp @@ -4,7 +4,7 @@ void AgQbWall::OnRebuildComplete(Entity* self, Entity* player) { self->SetVar(u"player", player->GetObjectID()); auto targetWallSpawners = GeneralUtils::UTF16ToWTF8(self->GetVar(u"spawner")); if (targetWallSpawners != "") { - auto groupObjs = EntityManager::Instance()->GetEntitiesInGroup(targetWallSpawners); + auto groupObjs = Game::entityManager->GetEntitiesInGroup(targetWallSpawners); for (auto* obj : groupObjs) { if (obj) { obj->SetVar(u"player", player->GetObjectID()); diff --git a/dScripts/ai/AG/AgSalutingNpcs.cpp b/dScripts/ai/AG/AgSalutingNpcs.cpp index 4e4d8b2c..d3bbe9ab 100644 --- a/dScripts/ai/AG/AgSalutingNpcs.cpp +++ b/dScripts/ai/AG/AgSalutingNpcs.cpp @@ -1,11 +1,10 @@ #include "AgSalutingNpcs.h" -#include "GameMessages.h" - +#include "RenderComponent.h" void AgSalutingNpcs::OnEmoteReceived(Entity* self, const int32_t emote, Entity* target) { if (emote != 356) { return; } - GameMessages::SendPlayAnimation(self, u"salutePlayer"); + RenderComponent::PlayAnimation(self, u"salutePlayer"); } diff --git a/dScripts/ai/AG/AgShipPlayerShockServer.cpp b/dScripts/ai/AG/AgShipPlayerShockServer.cpp index 9e6c90d4..e14d48ae 100644 --- a/dScripts/ai/AG/AgShipPlayerShockServer.cpp +++ b/dScripts/ai/AG/AgShipPlayerShockServer.cpp @@ -1,5 +1,7 @@ #include "AgShipPlayerShockServer.h" #include "GameMessages.h" +#include "RenderComponent.h" +#include "Entity.h" #include "eTerminateType.h" void AgShipPlayerShockServer::OnUse(Entity* self, Entity* user) { @@ -8,7 +10,7 @@ void AgShipPlayerShockServer::OnUse(Entity* self, Entity* user) { return; } active = true; - GameMessages::SendPlayAnimation(user, shockAnim); + RenderComponent::PlayAnimation(user, shockAnim); GameMessages::SendKnockback(user->GetObjectID(), self->GetObjectID(), self->GetObjectID(), 0, NiPoint3(-20, 10, -20)); GameMessages::SendPlayFXEffect(self, 1430, u"create", "console_sparks", LWOOBJID_EMPTY, 1.0, 1.0, true); diff --git a/dScripts/ai/AG/AgSpaceStuff.cpp b/dScripts/ai/AG/AgSpaceStuff.cpp index 30929ebf..130d4354 100644 --- a/dScripts/ai/AG/AgSpaceStuff.cpp +++ b/dScripts/ai/AG/AgSpaceStuff.cpp @@ -3,6 +3,8 @@ #include "GeneralUtils.h" #include "GameMessages.h" #include "EntityManager.h" +#include "RenderComponent.h" +#include "Entity.h" void AgSpaceStuff::OnStartup(Entity* self) { self->AddTimer("FloaterScale", 5.0f); @@ -13,9 +15,9 @@ void AgSpaceStuff::OnStartup(Entity* self) { info.lot = 33; info.spawnerID = self->GetObjectID(); - auto* ref = EntityManager::Instance()->CreateEntity(info); + auto* ref = Game::entityManager->CreateEntity(info); - EntityManager::Instance()->ConstructEntity(ref); + Game::entityManager->ConstructEntity(ref); self->SetVar(u"ShakeObject", ref->GetObjectID()); @@ -27,13 +29,13 @@ void AgSpaceStuff::OnTimerDone(Entity* self, std::string timerName) { if (timerName == "FloaterScale") { int scaleType = GeneralUtils::GenerateRandomNumber(1, 5); - GameMessages::SendPlayAnimation(self, u"scale_0" + GeneralUtils::to_u16string(scaleType)); + RenderComponent::PlayAnimation(self, u"scale_0" + GeneralUtils::to_u16string(scaleType)); self->AddTimer("FloaterPath", 0.4); } else if (timerName == "FloaterPath") { int pathType = GeneralUtils::GenerateRandomNumber(1, 4); int randTime = GeneralUtils::GenerateRandomNumber(20, 25); - GameMessages::SendPlayAnimation(self, u"path_0" + (GeneralUtils::to_u16string(pathType))); + RenderComponent::PlayAnimation(self, u"path_0" + (GeneralUtils::to_u16string(pathType))); self->AddTimer("FloaterScale", randTime); } else if (timerName == "ShipShakeExplode") { DoShake(self, true); @@ -45,7 +47,7 @@ void AgSpaceStuff::OnTimerDone(Entity* self, std::string timerName) { void AgSpaceStuff::DoShake(Entity* self, bool explodeIdle) { if (!explodeIdle) { - auto* ref = EntityManager::Instance()->GetEntity(self->GetVar(u"ShakeObject")); + auto* ref = Game::entityManager->GetEntity(self->GetVar(u"ShakeObject")); const auto randomTime = self->GetVar(u"RandomTime"); auto time = GeneralUtils::GenerateRandomNumber(0, randomTime + 1); @@ -76,21 +78,21 @@ void AgSpaceStuff::DoShake(Entity* self, bool explodeIdle) { auto* shipFxObject2 = GetEntityInGroup(ShipFX2); if (shipFxObject2) - GameMessages::SendPlayAnimation(shipFxObject2, u"explosion"); + RenderComponent::PlayAnimation(shipFxObject2, u"explosion"); } else { auto* shipFxObject = GetEntityInGroup(ShipFX); auto* shipFxObject2 = GetEntityInGroup(ShipFX2); if (shipFxObject) - GameMessages::SendPlayAnimation(shipFxObject, u"idle"); + RenderComponent::PlayAnimation(shipFxObject, u"idle"); if (shipFxObject2) - GameMessages::SendPlayAnimation(shipFxObject2, u"idle"); + RenderComponent::PlayAnimation(shipFxObject2, u"idle"); } } Entity* AgSpaceStuff::GetEntityInGroup(const std::string& group) { - auto entities = EntityManager::Instance()->GetEntitiesInGroup(group); + auto entities = Game::entityManager->GetEntitiesInGroup(group); Entity* en = nullptr; for (auto entity : entities) { diff --git a/dScripts/ai/FV/ActNinjaSensei.cpp b/dScripts/ai/FV/ActNinjaSensei.cpp index 27e42219..6a7dc893 100644 --- a/dScripts/ai/FV/ActNinjaSensei.cpp +++ b/dScripts/ai/FV/ActNinjaSensei.cpp @@ -4,7 +4,7 @@ #include "GameMessages.h" void ActNinjaSensei::OnStartup(Entity* self) { - auto students = EntityManager::Instance()->GetEntitiesInGroup(this->m_StudentGroup); + auto students = Game::entityManager->GetEntitiesInGroup(this->m_StudentGroup); std::vector validStudents = {}; for (auto* student : students) { if (student && student->GetLOT() == this->m_StudentLOT) validStudents.push_back(student); diff --git a/dScripts/ai/FV/ActParadoxPipeFix.cpp b/dScripts/ai/FV/ActParadoxPipeFix.cpp index 10a1e652..aad74dec 100644 --- a/dScripts/ai/FV/ActParadoxPipeFix.cpp +++ b/dScripts/ai/FV/ActParadoxPipeFix.cpp @@ -8,7 +8,7 @@ void ActParadoxPipeFix::OnRebuildComplete(Entity* self, Entity* target) { const auto myGroup = "AllPipes"; - const auto groupObjs = EntityManager::Instance()->GetEntitiesInGroup(myGroup); + const auto groupObjs = Game::entityManager->GetEntitiesInGroup(myGroup); auto indexCount = 0; @@ -27,14 +27,14 @@ void ActParadoxPipeFix::OnRebuildComplete(Entity* self, Entity* target) { } if (indexCount >= 2) { - const auto refinery = EntityManager::Instance()->GetEntitiesInGroup("Paradox"); + const auto refinery = Game::entityManager->GetEntitiesInGroup("Paradox"); if (!refinery.empty()) { GameMessages::SendPlayFXEffect(refinery[0]->GetObjectID(), 3999, u"create", "pipeFX"); } for (auto* object : groupObjs) { - auto* player = EntityManager::Instance()->GetEntity(object->GetVar(u"PlayerID")); + auto* player = Game::entityManager->GetEntity(object->GetVar(u"PlayerID")); if (player != nullptr) { auto* missionComponent = player->GetComponent(); @@ -53,7 +53,7 @@ void ActParadoxPipeFix::OnRebuildComplete(Entity* self, Entity* target) { void ActParadoxPipeFix::OnRebuildNotifyState(Entity* self, eRebuildState state) { if (state == eRebuildState::RESETTING) { - const auto refinery = EntityManager::Instance()->GetEntitiesInGroup("Paradox"); + const auto refinery = Game::entityManager->GetEntitiesInGroup("Paradox"); if (!refinery.empty()) { GameMessages::SendStopFXEffect(refinery[0], true, "pipeFX"); diff --git a/dScripts/ai/FV/FvBrickPuzzleServer.cpp b/dScripts/ai/FV/FvBrickPuzzleServer.cpp index 887b9a4d..ce12d76e 100644 --- a/dScripts/ai/FV/FvBrickPuzzleServer.cpp +++ b/dScripts/ai/FV/FvBrickPuzzleServer.cpp @@ -29,7 +29,7 @@ void FvBrickPuzzleServer::OnDie(Entity* self, Entity* killer) { const auto nextPipeNum = pipeNum + 1; - const auto samePipeSpawners = dZoneManager::Instance()->GetSpawnersByName(myGroup); + const auto samePipeSpawners = Game::zoneManager->GetSpawnersByName(myGroup); if (!samePipeSpawners.empty()) { samePipeSpawners[0]->SoftReset(); @@ -40,7 +40,7 @@ void FvBrickPuzzleServer::OnDie(Entity* self, Entity* killer) { if (killer != nullptr && killer->IsPlayer()) { const auto nextPipe = pipeGroup + std::to_string(nextPipeNum); - const auto nextPipeSpawners = dZoneManager::Instance()->GetSpawnersByName(nextPipe); + const auto nextPipeSpawners = Game::zoneManager->GetSpawnersByName(nextPipe); if (!nextPipeSpawners.empty()) { nextPipeSpawners[0]->Activate(); @@ -48,7 +48,7 @@ void FvBrickPuzzleServer::OnDie(Entity* self, Entity* killer) { } else { const auto nextPipe = pipeGroup + "1"; - const auto firstPipeSpawners = dZoneManager::Instance()->GetSpawnersByName(nextPipe); + const auto firstPipeSpawners = Game::zoneManager->GetSpawnersByName(nextPipe); if (!firstPipeSpawners.empty()) { firstPipeSpawners[0]->Activate(); diff --git a/dScripts/ai/FV/FvConsoleLeftQuickbuild.cpp b/dScripts/ai/FV/FvConsoleLeftQuickbuild.cpp index 3f495ed7..29de1fe5 100644 --- a/dScripts/ai/FV/FvConsoleLeftQuickbuild.cpp +++ b/dScripts/ai/FV/FvConsoleLeftQuickbuild.cpp @@ -13,7 +13,7 @@ void FvConsoleLeftQuickbuild::OnRebuildNotifyState(Entity* self, eRebuildState s if (state == eRebuildState::COMPLETED) { self->SetVar(u"IAmBuilt", true); - const auto objects = EntityManager::Instance()->GetEntitiesInGroup("Facility"); + const auto objects = Game::entityManager->GetEntitiesInGroup("Facility"); if (!objects.empty()) { objects[0]->NotifyObject(self, "ConsoleLeftUp"); @@ -22,7 +22,7 @@ void FvConsoleLeftQuickbuild::OnRebuildNotifyState(Entity* self, eRebuildState s self->SetVar(u"IAmBuilt", false); self->SetVar(u"AmActive", false); - const auto objects = EntityManager::Instance()->GetEntitiesInGroup("Facility"); + const auto objects = Game::entityManager->GetEntitiesInGroup("Facility"); if (!objects.empty()) { objects[0]->NotifyObject(self, "ConsoleLeftDown"); @@ -38,7 +38,7 @@ void FvConsoleLeftQuickbuild::OnUse(Entity* self, Entity* user) { if (self->GetVar(u"IAmBuilt")) { self->SetVar(u"AmActive", true); - const auto objects = EntityManager::Instance()->GetEntitiesInGroup("Facility"); + const auto objects = Game::entityManager->GetEntitiesInGroup("Facility"); if (!objects.empty()) { objects[0]->NotifyObject(self, "ConsoleLeftActive"); diff --git a/dScripts/ai/FV/FvConsoleRightQuickbuild.cpp b/dScripts/ai/FV/FvConsoleRightQuickbuild.cpp index e03e4135..20194f8d 100644 --- a/dScripts/ai/FV/FvConsoleRightQuickbuild.cpp +++ b/dScripts/ai/FV/FvConsoleRightQuickbuild.cpp @@ -13,7 +13,7 @@ void FvConsoleRightQuickbuild::OnRebuildNotifyState(Entity* self, eRebuildState if (state == eRebuildState::COMPLETED) { self->SetVar(u"IAmBuilt", true); - const auto objects = EntityManager::Instance()->GetEntitiesInGroup("Facility"); + const auto objects = Game::entityManager->GetEntitiesInGroup("Facility"); if (!objects.empty()) { objects[0]->NotifyObject(self, "ConsoleRightUp"); @@ -22,7 +22,7 @@ void FvConsoleRightQuickbuild::OnRebuildNotifyState(Entity* self, eRebuildState self->SetVar(u"IAmBuilt", false); self->SetVar(u"AmActive", false); - const auto objects = EntityManager::Instance()->GetEntitiesInGroup("Facility"); + const auto objects = Game::entityManager->GetEntitiesInGroup("Facility"); if (!objects.empty()) { objects[0]->NotifyObject(self, "ConsoleRightDown"); @@ -38,7 +38,7 @@ void FvConsoleRightQuickbuild::OnUse(Entity* self, Entity* user) { if (self->GetVar(u"IAmBuilt")) { self->SetVar(u"AmActive", true); - const auto objects = EntityManager::Instance()->GetEntitiesInGroup("Facility"); + const auto objects = Game::entityManager->GetEntitiesInGroup("Facility"); if (!objects.empty()) { objects[0]->NotifyObject(self, "ConsoleRightActive"); diff --git a/dScripts/ai/FV/FvDragonSmashingGolemQb.cpp b/dScripts/ai/FV/FvDragonSmashingGolemQb.cpp index 9cf7fa18..3f3121ef 100644 --- a/dScripts/ai/FV/FvDragonSmashingGolemQb.cpp +++ b/dScripts/ai/FV/FvDragonSmashingGolemQb.cpp @@ -1,6 +1,8 @@ #include "FvDragonSmashingGolemQb.h" #include "GameMessages.h" #include "EntityManager.h" +#include "RenderComponent.h" +#include "Entity.h" #include "eRebuildState.h" void FvDragonSmashingGolemQb::OnStartup(Entity* self) { @@ -15,11 +17,11 @@ void FvDragonSmashingGolemQb::OnTimerDone(Entity* self, std::string timerName) { void FvDragonSmashingGolemQb::OnRebuildNotifyState(Entity* self, eRebuildState state) { if (state == eRebuildState::COMPLETED) { - GameMessages::SendPlayAnimation(self, u"dragonsmash"); + RenderComponent::PlayAnimation(self, u"dragonsmash"); const auto dragonId = self->GetVar(u"Dragon"); - auto* dragon = EntityManager::Instance()->GetEntity(dragonId); + auto* dragon = Game::entityManager->GetEntity(dragonId); if (dragon != nullptr) { dragon->OnFireEventServerSide(self, "rebuildDone"); diff --git a/dScripts/ai/FV/FvFacilityBrick.cpp b/dScripts/ai/FV/FvFacilityBrick.cpp index 6ff12750..26c07647 100644 --- a/dScripts/ai/FV/FvFacilityBrick.cpp +++ b/dScripts/ai/FV/FvFacilityBrick.cpp @@ -9,9 +9,9 @@ void FvFacilityBrick::OnStartup(Entity* self) { } void FvFacilityBrick::OnNotifyObject(Entity* self, Entity* sender, const std::string& name, int32_t param1, int32_t param2) { - auto* brickSpawner = dZoneManager::Instance()->GetSpawnersByName("ImaginationBrick")[0]; - auto* bugSpawner = dZoneManager::Instance()->GetSpawnersByName("MaelstromBug")[0]; - auto* canisterSpawner = dZoneManager::Instance()->GetSpawnersByName("BrickCanister")[0]; + auto* brickSpawner = Game::zoneManager->GetSpawnersByName("ImaginationBrick")[0]; + auto* bugSpawner = Game::zoneManager->GetSpawnersByName("MaelstromBug")[0]; + auto* canisterSpawner = Game::zoneManager->GetSpawnersByName("BrickCanister")[0]; if (name == "ConsoleLeftUp") { GameMessages::SendStopFXEffect(self, true, "LeftPipeOff"); @@ -46,14 +46,14 @@ void FvFacilityBrick::OnNotifyObject(Entity* self, Entity* sender, const std::st } if (self->GetVar(u"ConsoleLEFTActive") && self->GetVar(u"ConsoleRIGHTActive")) { - auto* object = EntityManager::Instance()->GetEntitiesInGroup("Brick")[0]; + auto* object = Game::entityManager->GetEntitiesInGroup("Brick")[0]; if (object != nullptr) { GameMessages::SendPlayFXEffect(object->GetObjectID(), 122, u"create", "bluebrick"); GameMessages::SendPlayFXEffect(object->GetObjectID(), 1034, u"cast", "imaginationexplosion"); } - object = EntityManager::Instance()->GetEntitiesInGroup("Canister")[0]; + object = Game::entityManager->GetEntitiesInGroup("Canister")[0]; if (object != nullptr) { object->Smash(self->GetObjectID(), eKillType::SILENT); @@ -64,7 +64,7 @@ void FvFacilityBrick::OnNotifyObject(Entity* self, Entity* sender, const std::st } else if (self->GetVar(u"ConsoleLEFTActive") || self->GetVar(u"ConsoleRIGHTActive")) { brickSpawner->Activate(); - auto* object = EntityManager::Instance()->GetEntitiesInGroup("Brick")[0]; + auto* object = Game::entityManager->GetEntitiesInGroup("Brick")[0]; if (object != nullptr) { GameMessages::SendStopFXEffect(object, true, "bluebrick"); diff --git a/dScripts/ai/FV/FvFlyingCreviceDragon.cpp b/dScripts/ai/FV/FvFlyingCreviceDragon.cpp index 16eda512..c8ef9ab5 100644 --- a/dScripts/ai/FV/FvFlyingCreviceDragon.cpp +++ b/dScripts/ai/FV/FvFlyingCreviceDragon.cpp @@ -3,6 +3,7 @@ #include "EntityManager.h" #include "SkillComponent.h" #include "GeneralUtils.h" +#include "RenderComponent.h" void FvFlyingCreviceDragon::OnStartup(Entity* self) { self->AddTimer("waypoint", 5); @@ -33,7 +34,7 @@ void FvFlyingCreviceDragon::OnTimerDone(Entity* self, std::string timerName) { groupName = "dragonFireballs3"; } - const auto& group = EntityManager::Instance()->GetEntitiesInGroup(groupName); + const auto& group = Game::entityManager->GetEntitiesInGroup(groupName); if (group.empty()) { return; @@ -67,12 +68,12 @@ void FvFlyingCreviceDragon::OnArrived(Entity* self) { auto point = self->GetVar(u"waypoint"); if (point == 4) { - GameMessages::SendPlayAnimation(self, u"attack1", 2); + RenderComponent::PlayAnimation(self, u"attack1", 2.0f); self->AddTimer("platform1attack", 1.75f); } else if (point == 12) { - GameMessages::SendPlayAnimation(self, u"attack2", 2); + RenderComponent::PlayAnimation(self, u"attack2", 2.0f); - const auto& group2 = EntityManager::Instance()->GetEntitiesInGroup("dragonFireballs2"); + const auto& group2 = Game::entityManager->GetEntitiesInGroup("dragonFireballs2"); if (group2.empty()) { return; @@ -101,7 +102,7 @@ void FvFlyingCreviceDragon::OnArrived(Entity* self) { } } } else if (point == 16) { - GameMessages::SendPlayAnimation(self, u"attack3", 2); + RenderComponent::PlayAnimation(self, u"attack3", 2.0f); self->AddTimer("platform3attack", 0.5f); } } diff --git a/dScripts/ai/FV/FvNinjaGuard.cpp b/dScripts/ai/FV/FvNinjaGuard.cpp index 58267999..c087c6df 100644 --- a/dScripts/ai/FV/FvNinjaGuard.cpp +++ b/dScripts/ai/FV/FvNinjaGuard.cpp @@ -1,6 +1,8 @@ #include "FvNinjaGuard.h" #include "GameMessages.h" #include "MissionComponent.h" +#include "RenderComponent.h" +#include "EntityManager.h" void FvNinjaGuard::OnStartup(Entity* self) { if (self->GetLOT() == 7412) { @@ -12,24 +14,24 @@ void FvNinjaGuard::OnStartup(Entity* self) { void FvNinjaGuard::OnEmoteReceived(Entity* self, const int32_t emote, Entity* target) { if (emote != 392) { - GameMessages::SendPlayAnimation(self, u"no"); + RenderComponent::PlayAnimation(self, u"no"); return; } - GameMessages::SendPlayAnimation(self, u"scared"); + RenderComponent::PlayAnimation(self, u"scared"); if (self->GetLOT() == 7412) { - auto* rightGuard = EntityManager::Instance()->GetEntity(m_RightGuard); + auto* rightGuard = Game::entityManager->GetEntity(m_RightGuard); if (rightGuard != nullptr) { - GameMessages::SendPlayAnimation(rightGuard, u"laugh_rt"); + RenderComponent::PlayAnimation(rightGuard, u"laugh_rt"); } } else if (self->GetLOT() == 11128) { - auto* leftGuard = EntityManager::Instance()->GetEntity(m_LeftGuard); + auto* leftGuard = Game::entityManager->GetEntity(m_LeftGuard); if (leftGuard != nullptr) { - GameMessages::SendPlayAnimation(leftGuard, u"laugh_lt"); + RenderComponent::PlayAnimation(leftGuard, u"laugh_lt"); } } } diff --git a/dScripts/ai/FV/FvPandaSpawnerServer.cpp b/dScripts/ai/FV/FvPandaSpawnerServer.cpp index d7dcabcd..bc9f1c8a 100644 --- a/dScripts/ai/FV/FvPandaSpawnerServer.cpp +++ b/dScripts/ai/FV/FvPandaSpawnerServer.cpp @@ -9,7 +9,7 @@ void FvPandaSpawnerServer::OnCollisionPhantom(Entity* self, Entity* target) { auto* character = target->GetCharacter(); if (character != nullptr && character->GetPlayerFlag(81)) { - auto raceObjects = EntityManager::Instance()->GetEntitiesInGroup("PandaRaceObject"); + auto raceObjects = Game::entityManager->GetEntitiesInGroup("PandaRaceObject"); if (raceObjects.empty()) return; @@ -19,7 +19,7 @@ void FvPandaSpawnerServer::OnCollisionPhantom(Entity* self, Entity* target) { return; // If the player already spawned a panda - auto playerPandas = EntityManager::Instance()->GetEntitiesInGroup("panda" + std::to_string(target->GetObjectID())); + auto playerPandas = Game::entityManager->GetEntitiesInGroup("panda" + std::to_string(target->GetObjectID())); if (!playerPandas.empty()) { GameMessages::SendFireEventClientSide(self->GetObjectID(), target->GetSystemAddress(), u"playerPanda", target->GetObjectID(), 0, 0, target->GetObjectID()); @@ -27,7 +27,7 @@ void FvPandaSpawnerServer::OnCollisionPhantom(Entity* self, Entity* target) { } // If there's already too many spawned pandas - auto pandas = EntityManager::Instance()->GetEntitiesInGroup("pandas"); + auto pandas = Game::entityManager->GetEntitiesInGroup("pandas"); if (pandas.size() > 4) { GameMessages::SendFireEventClientSide(self->GetObjectID(), target->GetSystemAddress(), u"tooManyPandas", target->GetObjectID(), 0, 0, target->GetObjectID()); @@ -43,7 +43,7 @@ void FvPandaSpawnerServer::OnCollisionPhantom(Entity* self, Entity* target) { new LDFData(u"groupID", u"panda" + (GeneralUtils::to_u16string(target->GetObjectID())) + u";pandas") }; - auto* panda = EntityManager::Instance()->CreateEntity(info); - EntityManager::Instance()->ConstructEntity(panda); + auto* panda = Game::entityManager->CreateEntity(info); + Game::entityManager->ConstructEntity(panda); } } diff --git a/dScripts/ai/GENERAL/LegoDieRoll.cpp b/dScripts/ai/GENERAL/LegoDieRoll.cpp index 18082065..763a4704 100644 --- a/dScripts/ai/GENERAL/LegoDieRoll.cpp +++ b/dScripts/ai/GENERAL/LegoDieRoll.cpp @@ -2,6 +2,7 @@ #include "Entity.h" #include "GameMessages.h" #include "MissionComponent.h" +#include "RenderComponent.h" #include "eMissionState.h" void LegoDieRoll::OnStartup(Entity* self) { @@ -17,23 +18,23 @@ void LegoDieRoll::OnTimerDone(Entity* self, std::string timerName) { switch (dieRoll) { case 1: - GameMessages::SendPlayAnimation(self, u"roll-die-1"); + RenderComponent::PlayAnimation(self, u"roll-die-1"); break; case 2: - GameMessages::SendPlayAnimation(self, u"roll-die-2"); + RenderComponent::PlayAnimation(self, u"roll-die-2"); break; case 3: - GameMessages::SendPlayAnimation(self, u"roll-die-3"); + RenderComponent::PlayAnimation(self, u"roll-die-3"); break; case 4: - GameMessages::SendPlayAnimation(self, u"roll-die-4"); + RenderComponent::PlayAnimation(self, u"roll-die-4"); break; case 5: - GameMessages::SendPlayAnimation(self, u"roll-die-5"); + RenderComponent::PlayAnimation(self, u"roll-die-5"); break; case 6: { - GameMessages::SendPlayAnimation(self, u"roll-die-6"); + RenderComponent::PlayAnimation(self, u"roll-die-6"); // tracking the It's Truly Random Achievement auto* owner = self->GetOwner(); auto* missionComponent = owner->GetComponent(); diff --git a/dScripts/ai/GF/GfBanana.cpp b/dScripts/ai/GF/GfBanana.cpp index 95a831cd..6bc5c179 100644 --- a/dScripts/ai/GF/GfBanana.cpp +++ b/dScripts/ai/GF/GfBanana.cpp @@ -20,9 +20,9 @@ void GfBanana::SpawnBanana(Entity* self) { info.lot = 6909; info.spawnerID = self->GetObjectID(); - auto* entity = EntityManager::Instance()->CreateEntity(info); + auto* entity = Game::entityManager->CreateEntity(info); - EntityManager::Instance()->ConstructEntity(entity); + Game::entityManager->ConstructEntity(entity); self->SetVar(u"banana", entity->GetObjectID()); @@ -46,7 +46,7 @@ void GfBanana::OnHit(Entity* self, Entity* attacker) { if (bananaId == LWOOBJID_EMPTY) return; - auto* bananaEntity = EntityManager::Instance()->GetEntity(bananaId); + auto* bananaEntity = Game::entityManager->GetEntity(bananaId); if (bananaEntity == nullptr) { self->SetVar(u"banana", LWOOBJID_EMPTY); @@ -79,12 +79,12 @@ void GfBanana::OnHit(Entity* self, Entity* attacker) { info.lot = 6718; info.spawnerID = self->GetObjectID(); - auto* entity = EntityManager::Instance()->CreateEntity(info); + auto* entity = Game::entityManager->CreateEntity(info); - EntityManager::Instance()->ConstructEntity(entity, UNASSIGNED_SYSTEM_ADDRESS); + Game::entityManager->ConstructEntity(entity, UNASSIGNED_SYSTEM_ADDRESS); */ - EntityManager::Instance()->SerializeEntity(self); + Game::entityManager->SerializeEntity(self); } void GfBanana::OnTimerDone(Entity* self, std::string timerName) { diff --git a/dScripts/ai/GF/GfCampfire.cpp b/dScripts/ai/GF/GfCampfire.cpp index 6a10b39e..aa03da89 100644 --- a/dScripts/ai/GF/GfCampfire.cpp +++ b/dScripts/ai/GF/GfCampfire.cpp @@ -83,7 +83,7 @@ void GfCampfire::OnTimerDone(Entity* self, std::string timerName) { const auto targetId = self->GetVar("target"); - auto* entering = EntityManager::Instance()->GetEntity(targetId); + auto* entering = Game::entityManager->GetEntity(targetId); if (entering == nullptr) { diff --git a/dScripts/ai/GF/GfJailWalls.cpp b/dScripts/ai/GF/GfJailWalls.cpp index 1835faa2..1efca1cf 100644 --- a/dScripts/ai/GF/GfJailWalls.cpp +++ b/dScripts/ai/GF/GfJailWalls.cpp @@ -6,11 +6,11 @@ void GfJailWalls::OnRebuildComplete(Entity* self, Entity* target) { const auto wall = GeneralUtils::UTF16ToWTF8(self->GetVar(u"Wall")); - for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName("Jail0" + wall)) { + for (auto* spawner : Game::zoneManager->GetSpawnersByName("Jail0" + wall)) { spawner->Deactivate(); } - for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName("JailCaptain0" + wall)) { + for (auto* spawner : Game::zoneManager->GetSpawnersByName("JailCaptain0" + wall)) { spawner->Deactivate(); } } @@ -20,11 +20,11 @@ void GfJailWalls::OnRebuildNotifyState(Entity* self, eRebuildState state) { const auto wall = GeneralUtils::UTF16ToWTF8(self->GetVar(u"Wall")); - for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName("Jail0" + wall)) { + for (auto* spawner : Game::zoneManager->GetSpawnersByName("Jail0" + wall)) { spawner->Activate(); } - for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName("JailCaptain0" + wall)) { + for (auto* spawner : Game::zoneManager->GetSpawnersByName("JailCaptain0" + wall)) { spawner->Activate(); } } diff --git a/dScripts/ai/GF/GfOrgan.cpp b/dScripts/ai/GF/GfOrgan.cpp index 372ed3a2..3184aa82 100644 --- a/dScripts/ai/GF/GfOrgan.cpp +++ b/dScripts/ai/GF/GfOrgan.cpp @@ -1,5 +1,7 @@ #include "GfOrgan.h" #include "GameMessages.h" +#include "Entity.h" +#include "RenderComponent.h" void GfOrgan::OnUse(Entity* self, Entity* user) { if (self->GetBoolean(u"bIsInUse")) { @@ -11,7 +13,7 @@ void GfOrgan::OnUse(Entity* self, Entity* user) { self->SetBoolean(u"bIsInUse", true); self->AddTimer("reset", 5.0f); - GameMessages::SendPlayAnimation(user, u"jig"); + RenderComponent::PlayAnimation(user, u"jig"); } void GfOrgan::OnTimerDone(Entity* self, std::string timerName) { diff --git a/dScripts/ai/GF/PetDigBuild.cpp b/dScripts/ai/GF/PetDigBuild.cpp index 504a1199..9732e56b 100644 --- a/dScripts/ai/GF/PetDigBuild.cpp +++ b/dScripts/ai/GF/PetDigBuild.cpp @@ -30,8 +30,8 @@ void PetDigBuild::OnRebuildComplete(Entity* self, Entity* target) { } } - auto* treasure = EntityManager::Instance()->CreateEntity(info); - EntityManager::Instance()->ConstructEntity(treasure); + auto* treasure = Game::entityManager->CreateEntity(info); + Game::entityManager->ConstructEntity(treasure); self->SetVar(u"chestObj", treasure->GetObjectID()); } @@ -40,7 +40,7 @@ void PetDigBuild::OnDie(Entity* self, Entity* killer) { if (treasureID == LWOOBJID_EMPTY) return; - auto treasure = EntityManager::Instance()->GetEntity(treasureID); + auto treasure = Game::entityManager->GetEntity(treasureID); if (treasure == nullptr) return; diff --git a/dScripts/ai/GF/TriggerAmbush.cpp b/dScripts/ai/GF/TriggerAmbush.cpp index 726b45d7..7ac329ea 100644 --- a/dScripts/ai/GF/TriggerAmbush.cpp +++ b/dScripts/ai/GF/TriggerAmbush.cpp @@ -13,7 +13,7 @@ void TriggerAmbush::OnProximityUpdate(Entity* self, Entity* entering, std::strin self->SetVar(u"triggered", true); - const auto spawners = dZoneManager::Instance()->GetSpawnersByName("Ambush"); + const auto spawners = Game::zoneManager->GetSpawnersByName("Ambush"); for (auto* spawner : spawners) { spawner->Activate(); @@ -27,7 +27,7 @@ void TriggerAmbush::OnTimerDone(Entity* self, std::string timerName) { self->SetVar(u"triggered", false); - const auto spawners = dZoneManager::Instance()->GetSpawnersByName("Ambush"); + const auto spawners = Game::zoneManager->GetSpawnersByName("Ambush"); for (auto* spawner : spawners) { spawner->Reset(); diff --git a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp index de2d6f5c..325e6295 100644 --- a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp +++ b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp @@ -15,6 +15,7 @@ #include "InventoryComponent.h" #include "eMissionTaskType.h" #include "eReplicaComponentType.h" +#include "RenderComponent.h" #include "eGameActivity.h" #include "MovingPlatformComponent.h" @@ -78,7 +79,7 @@ void SGCannon::OnActivityStateChangeRequest(Entity* self, LWOOBJID senderID, int const std::u16string& stringValue) { Game::logger->Log("SGCannon", "Got activity state change request: %s", GeneralUtils::UTF16ToWTF8(stringValue).c_str()); if (stringValue == u"clientready") { - auto* player = EntityManager::Instance()->GetEntity(self->GetVar(PlayerIDVariable)); + auto* player = Game::entityManager->GetEntity(self->GetVar(PlayerIDVariable)); if (player != nullptr) { Game::logger->Log("SGCannon", "Player is ready"); /*GameMessages::SendSetStunned(player->GetObjectID(), eStateChangeType::PUSH, player->GetSystemAddress(), LWOOBJID_EMPTY, @@ -95,7 +96,7 @@ void SGCannon::OnActivityStateChangeRequest(Entity* self, LWOOBJID senderID, int Game::logger->Log("SGCannon", "Setting player ID"); - EntityManager::Instance()->SerializeEntity(self); + Game::entityManager->SerializeEntity(self); } else { Game::logger->Log("SGCannon", "Shooting gallery component is null"); } @@ -111,7 +112,7 @@ void SGCannon::OnActivityStateChangeRequest(Entity* self, LWOOBJID senderID, int possessor->SetPossessableType(ePossessionType::NO_POSSESSION); } - EntityManager::Instance()->SerializeEntity(player); + Game::entityManager->SerializeEntity(player); } self->SetNetworkVar(HideScoreBoardVariable, true); @@ -136,38 +137,26 @@ void SGCannon::OnActivityStateChangeRequest(Entity* self, LWOOBJID senderID, int } } -void SGCannon::OnMessageBoxResponse(Entity* self, Entity* sender, int32_t button, const std::u16string& identifier, - const std::u16string& userData) { - auto* player = EntityManager::Instance()->GetEntity(self->GetVar(PlayerIDVariable)); - if (player != nullptr) { - if (button == 1 && identifier == u"Shooting_Gallery_Stop") { +void SGCannon::OnMessageBoxResponse(Entity* self, Entity* sender, int32_t button, const std::u16string& identifier, const std::u16string& userData) { + auto* player = Game::entityManager->GetEntity(self->GetVar(PlayerIDVariable)); + if (!player) return; + + if (identifier == u"Scoreboardinfo") { + GameMessages::SendDisplayMessageBox(player->GetObjectID(), true, + Game::zoneManager->GetZoneControlObject()->GetObjectID(), + u"Shooting_Gallery_Retry", 2, u"Retry?", + u"", player->GetSystemAddress()); + } else { + if ((button == 1 && (identifier == u"Shooting_Gallery_Retry" || identifier == u"RePlay")) || identifier == u"SG1" || button == 0) { + if (IsPlayerInActivity(self, player->GetObjectID())) return; + self->SetNetworkVar(ClearVariable, true); + StartGame(self); + } else if (button == 0 && ((identifier == u"Shooting_Gallery_Retry" || identifier == u"RePlay"))) { + RemovePlayer(player->GetObjectID()); + UpdatePlayer(self, player->GetObjectID(), true); + } else if (button == 1 && identifier == u"Shooting_Gallery_Exit") { UpdatePlayer(self, player->GetObjectID(), true); RemovePlayer(player->GetObjectID()); - StopGame(self, true); - return; - } - - if (identifier == u"Scoreboardinfo") { - GameMessages::SendDisplayMessageBox(player->GetObjectID(), true, - dZoneManager::Instance()->GetZoneControlObject()->GetObjectID(), - u"Shooting_Gallery_Retry?", 2, u"Retry?", - u"", player->GetSystemAddress()); - } else { - if ((button == 1 && (identifier == u"Shooting_Gallery_Retry" || identifier == u"RePlay")) - || identifier == u"SG1" || button == 0) { - - if (identifier == u"RePlay") { - static_cast(player)->SendToZone(1300); - - return; - } - - self->SetNetworkVar(ClearVariable, true); - StartGame(self); - } else if (button == 1 && identifier == u"Shooting_Gallery_Exit") { - UpdatePlayer(self, player->GetObjectID(), true); - RemovePlayer(player->GetObjectID()); - } } } } @@ -205,7 +194,7 @@ void SGCannon::OnActivityTimerDone(Entity* self, const std::string& name) { ActivityTimerStart(self, EndWaveTimer, timeLimit, timeLimit); } - const auto* player = EntityManager::Instance()->GetEntity(self->GetVar(PlayerIDVariable)); + const auto* player = Game::entityManager->GetEntity(self->GetVar(PlayerIDVariable)); if (player != nullptr) { GameMessages::SendPlayFXEffect(player->GetObjectID(), -1, u"SG-start", ""); @@ -246,13 +235,13 @@ void SGCannon::OnActivityTimerDone(Entity* self, const std::string& name) { PauseChargeCannon(self); } } else if (name == GameOverTimer) { - auto* player = EntityManager::Instance()->GetEntity(self->GetVar(PlayerIDVariable)); + auto* player = Game::entityManager->GetEntity(self->GetVar(PlayerIDVariable)); if (player != nullptr) { Game::logger->Log("SGCannon", "Sending ActivityPause true"); GameMessages::SendActivityPause(self->GetObjectID(), true, player->GetSystemAddress()); - /*const auto leftoverCannonballs = EntityManager::Instance()->GetEntitiesInGroup("cannonball"); + /*const auto leftoverCannonballs = Game::entityManager->GetEntitiesInGroup("cannonball"); if (leftoverCannonballs.empty()) { RecordPlayerScore(self); @@ -268,13 +257,17 @@ void SGCannon::OnActivityTimerDone(Entity* self, const std::string& name) { if (self->GetVar(GameStartedVariable)) { const auto spawnNumber = (uint32_t)std::stoi(name.substr(7)); const auto& activeSpawns = self->GetVar>(ActiveSpawnsVariable); + if (activeSpawns.size() < spawnNumber) { + Game::logger->Log("SGCannon", "Trying to spawn %i when spawns size is only %i", spawnNumber, activeSpawns.size()); + return; + } const auto& toSpawn = activeSpawns.at(spawnNumber); - const auto pathIndex = GeneralUtils::GenerateRandomNumber(0, toSpawn.spawnPaths.size() - 1); - - const auto* path = dZoneManager::Instance()->GetZone()->GetPath( - toSpawn.spawnPaths.at(pathIndex) - ); + const auto* path = Game::zoneManager->GetZone()->GetPath(toSpawn.spawnPaths.at(pathIndex)); + if (!path) { + Game::logger->Log("SGCannon", "Path %s at index %i is null", toSpawn.spawnPaths.at(pathIndex).c_str(), pathIndex); + return; + } auto info = EntityInfo{}; info.lot = toSpawn.lot; @@ -292,9 +285,9 @@ void SGCannon::OnActivityTimerDone(Entity* self, const std::string& name) { Game::logger->Log("SGCannon", "Spawning enemy %i on path %s", toSpawn.lot, path->pathName.c_str()); - auto* enemy = EntityManager::Instance()->CreateEntity(info, nullptr, self); + auto* enemy = Game::entityManager->CreateEntity(info, nullptr, self); if (enemy) { - EntityManager::Instance()->ConstructEntity(enemy); + Game::entityManager->ConstructEntity(enemy); auto* movementAI = enemy->GetComponent(); if (!movementAI) return; @@ -327,18 +320,19 @@ SGCannon::OnActivityTimerUpdate(Entity* self, const std::string& name, float_t t } void SGCannon::StartGame(Entity* self) { + if (self->GetVar(GameStartedVariable)) return; self->SetNetworkVar(TimeLimitVariable, self->GetVar(TimeLimitVariable)); self->SetNetworkVar(AudioStartIntroVariable, true); self->SetVar(CurrentRewardVariable, LOT_NULL); - auto rewardObjects = EntityManager::Instance()->GetEntitiesInGroup(constants.rewardModelGroup); + auto rewardObjects = Game::entityManager->GetEntitiesInGroup(constants.rewardModelGroup); for (auto* reward : rewardObjects) { reward->OnFireEventServerSide(self, ModelToBuildEvent); } - auto* player = EntityManager::Instance()->GetEntity(self->GetVar(PlayerIDVariable)); + auto* player = Game::entityManager->GetEntity(self->GetVar(PlayerIDVariable)); if (player != nullptr) { - GetLeaderboardData(self, player->GetObjectID(), GetActivityID(self)); + GetLeaderboardData(self, player->GetObjectID(), GetActivityID(self), 1); Game::logger->Log("SGCannon", "Sending ActivityStart"); GameMessages::SendActivityStart(self->GetObjectID(), player->GetSystemAddress()); @@ -381,9 +375,9 @@ void SGCannon::SpawnNewModel(Entity* self) { self->SetNetworkVar(RewardAddedVariable, currentReward); } - auto* player = EntityManager::Instance()->GetEntity(self->GetVar(PlayerIDVariable)); + auto* player = Game::entityManager->GetEntity(self->GetVar(PlayerIDVariable)); if (player != nullptr) { - for (auto* rewardModel : EntityManager::Instance()->GetEntitiesInGroup(constants.rewardModelGroup)) { + for (auto* rewardModel : Game::entityManager->GetEntitiesInGroup(constants.rewardModelGroup)) { uint32_t lootMatrix; switch (self->GetVar(MatrixVariable)) { case 1: @@ -419,7 +413,7 @@ void SGCannon::SpawnNewModel(Entity* self) { } void SGCannon::RemovePlayer(LWOOBJID playerID) { - auto* player = EntityManager::Instance()->GetEntity(playerID); + auto* player = Game::entityManager->GetEntity(playerID); if (player == nullptr) return; @@ -433,6 +427,14 @@ void SGCannon::RemovePlayer(LWOOBJID playerID) { } } +void SGCannon::OnRequestActivityExit(Entity* self, LWOOBJID player, bool canceled) { + if (canceled) { + StopGame(self, canceled); + RemovePlayer(player); + } +} + + void SGCannon::StartChargedCannon(Entity* self, uint32_t optionalTime) { optionalTime = optionalTime == 0 ? constants.chargedTime : optionalTime; self->SetVar(SuperChargePausedVariable, false); @@ -497,18 +499,18 @@ void SGCannon::RecordPlayerScore(Entity* self) { } void SGCannon::PlaySceneAnimation(Entity* self, const std::u16string& animationName, bool onCannon, bool onPlayer, float_t priority) { - for (auto* cannon : EntityManager::Instance()->GetEntitiesInGroup("cannongroup")) { - GameMessages::SendPlayAnimation(cannon, animationName, priority); + for (auto* cannon : Game::entityManager->GetEntitiesInGroup("cannongroup")) { + RenderComponent::PlayAnimation(cannon, animationName, priority); } if (onCannon) { - GameMessages::SendPlayAnimation(self, animationName, priority); + RenderComponent::PlayAnimation(self, animationName, priority); } if (onPlayer) { - auto* player = EntityManager::Instance()->GetEntity(self->GetVar(PlayerIDVariable)); + auto* player = Game::entityManager->GetEntity(self->GetVar(PlayerIDVariable)); if (player != nullptr) { - GameMessages::SendPlayAnimation(player, animationName, priority); + RenderComponent::PlayAnimation(player, animationName, priority); } } } @@ -527,7 +529,7 @@ void SGCannon::StopGame(Entity* self, bool cancel) { self->SetNetworkVar(ReSetSuperChargeVariable, true); self->SetNetworkVar(HideSuperChargeVariable, true); - auto* player = EntityManager::Instance()->GetEntity(self->GetVar(PlayerIDVariable)); + auto* player = Game::entityManager->GetEntity(self->GetVar(PlayerIDVariable)); if (player == nullptr) return; @@ -535,7 +537,7 @@ void SGCannon::StopGame(Entity* self, bool cancel) { // The player won, store all the score and send rewards if (!cancel) { - auto percentage = 0; + int32_t percentage = 0.0f; auto misses = self->GetVar(MissesVariable); auto fired = self->GetVar(ShotsFiredVariable); @@ -553,6 +555,9 @@ void SGCannon::StopGame(Entity* self, bool cancel) { LootGenerator::Instance().GiveActivityLoot(player, self, GetGameID(self), self->GetVar(TotalScoreVariable)); + SaveScore(self, player->GetObjectID(), + static_cast(self->GetVar(TotalScoreVariable)), static_cast(self->GetVar(MaxStreakVariable)), percentage); + StopActivity(self, player->GetObjectID(), self->GetVar(TotalScoreVariable), self->GetVar(MaxStreakVariable), percentage); self->SetNetworkVar(AudioFinalWaveDoneVariable, true); @@ -566,17 +571,6 @@ void SGCannon::StopGame(Entity* self, bool cancel) { self->SetNetworkVar(u"UI_Rewards", GeneralUtils::to_u16string(self->GetVar(TotalScoreVariable)) + u"_0_0_0_0_0_0" - ); - - GameMessages::SendRequestActivitySummaryLeaderboardData( - player->GetObjectID(), - self->GetObjectID(), - player->GetSystemAddress(), - GetGameID(self), - 1, - 10, - 0, - false ); } @@ -585,7 +579,7 @@ void SGCannon::StopGame(Entity* self, bool cancel) { ActivityTimerStopAllTimers(self); // Destroy all spawners - for (auto* entity : EntityManager::Instance()->GetEntitiesInGroup("SGEnemy")) { + for (auto* entity : Game::entityManager->GetEntitiesInGroup("SGEnemy")) { entity->Kill(); } @@ -652,7 +646,7 @@ void SGCannon::RegisterHit(Entity* self, Entity* target, const std::string& time self->SetNetworkVar(u"beatHighScore", GeneralUtils::to_u16string(newScore)); - auto* player = EntityManager::Instance()->GetEntity(self->GetVar(PlayerIDVariable)); + auto* player = Game::entityManager->GetEntity(self->GetVar(PlayerIDVariable)); if (player == nullptr) return; auto missionComponent = player->GetComponent(); @@ -702,7 +696,7 @@ void SGCannon::ToggleSuperCharge(Entity* self, bool enable) { if (enable && self->GetVar(SuperChargeActiveVariable)) return; - auto* player = EntityManager::Instance()->GetEntity(self->GetVar(PlayerIDVariable)); + auto* player = Game::entityManager->GetEntity(self->GetVar(PlayerIDVariable)); if (player == nullptr) { Game::logger->Log("SGCannon", "Player not found in toggle super charge"); @@ -777,8 +771,8 @@ void SGCannon::ToggleSuperCharge(Entity* self, bool enable) { shootingGalleryComponent->SetDynamicParams(properties); - EntityManager::Instance()->SerializeEntity(self); - EntityManager::Instance()->SerializeEntity(player); + Game::entityManager->SerializeEntity(self); + Game::entityManager->SerializeEntity(player); self->SetNetworkVar(CannonBallSkillIDVariable, skillID); self->SetVar(SuperChargeActiveVariable, enable); diff --git a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.h b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.h index df9831ad..b20fae6d 100644 --- a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.h +++ b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.h @@ -63,12 +63,11 @@ public: void OnStartup(Entity* self) override; void OnPlayerLoaded(Entity* self, Entity* player) override; void OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2, int32_t param3) override; - void OnActivityStateChangeRequest(Entity* self, LWOOBJID senderID, int32_t value1, - int32_t value2, const std::u16string& stringValue) override; - void OnMessageBoxResponse(Entity* self, Entity* sender, int32_t button, const std::u16string& identifier, - const std::u16string& userData) override; + void OnActivityStateChangeRequest(Entity* self, LWOOBJID senderID, int32_t value1, int32_t value2, const std::u16string& stringValue) override; + void OnMessageBoxResponse(Entity* self, Entity* sender, int32_t button, const std::u16string& identifier, const std::u16string& userData) override; void OnActivityTimerDone(Entity* self, const std::string& name) override; void OnActivityTimerUpdate(Entity* self, const std::string& name, float_t timeRemaining, float_t elapsedTime) override; + void OnRequestActivityExit(Entity* self, LWOOBJID player, bool canceled) override; private: static std::vector> GetWaves(); static SGConstants GetConstants(); diff --git a/dScripts/ai/MINIGAME/SG_GF/ZoneSGServer.cpp b/dScripts/ai/MINIGAME/SG_GF/ZoneSGServer.cpp index 6822abda..b1de87c9 100644 --- a/dScripts/ai/MINIGAME/SG_GF/ZoneSGServer.cpp +++ b/dScripts/ai/MINIGAME/SG_GF/ZoneSGServer.cpp @@ -2,7 +2,7 @@ #include "EntityManager.h" void ZoneSGServer::OnStartup(Entity* self) { - const auto cannons = EntityManager::Instance()->GetEntitiesByLOT(1864); + const auto cannons = Game::entityManager->GetEntitiesByLOT(1864); for (const auto& cannon : cannons) self->SetVar(CannonIDVariable, cannon->GetObjectID()); } @@ -10,7 +10,7 @@ void ZoneSGServer::OnStartup(Entity* self) { void ZoneSGServer::OnActivityStateChangeRequest(Entity* self, const LWOOBJID senderID, const int32_t value1, const int32_t value2, const std::u16string& stringValue) { - auto* cannon = EntityManager::Instance()->GetEntity(self->GetVar(CannonIDVariable)); + auto* cannon = Game::entityManager->GetEntity(self->GetVar(CannonIDVariable)); if (cannon != nullptr) { cannon->OnActivityStateChangeRequest(senderID, value1, value2, stringValue); } @@ -19,7 +19,7 @@ void ZoneSGServer::OnActivityStateChangeRequest(Entity* self, const LWOOBJID sen void ZoneSGServer::OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2, int32_t param3) { - auto* cannon = EntityManager::Instance()->GetEntity(self->GetVar(CannonIDVariable)); + auto* cannon = Game::entityManager->GetEntity(self->GetVar(CannonIDVariable)); if (cannon != nullptr) { cannon->OnFireEventServerSide(sender, args, param1, param2, param3); } diff --git a/dScripts/ai/NS/NS_PP_01/PropertyDeathPlane.cpp b/dScripts/ai/NS/NS_PP_01/PropertyDeathPlane.cpp index ab659d8a..8f8906d3 100644 --- a/dScripts/ai/NS/NS_PP_01/PropertyDeathPlane.cpp +++ b/dScripts/ai/NS/NS_PP_01/PropertyDeathPlane.cpp @@ -4,7 +4,7 @@ #include "EntityManager.h" void PropertyDeathPlane::OnCollisionPhantom(Entity* self, Entity* target) { - const auto teleportGroup = EntityManager::Instance()->GetEntitiesInGroup("Teleport"); + const auto teleportGroup = Game::entityManager->GetEntitiesInGroup("Teleport"); if (teleportGroup.size() == 0) { return; diff --git a/dScripts/ai/NS/NsConcertInstrument.cpp b/dScripts/ai/NS/NsConcertInstrument.cpp index 7db1ca16..bd397fbb 100644 --- a/dScripts/ai/NS/NsConcertInstrument.cpp +++ b/dScripts/ai/NS/NsConcertInstrument.cpp @@ -9,6 +9,7 @@ #include "MissionComponent.h" #include "eMissionState.h" #include "eMissionTaskType.h" +#include "RenderComponent.h" // Constants are at the bottom @@ -48,7 +49,7 @@ void NsConcertInstrument::OnFireEventServerSide(Entity* self, Entity* sender, st if (activePlayerID == LWOOBJID_EMPTY) return; - const auto activePlayer = EntityManager::Instance()->GetEntity(activePlayerID); + const auto activePlayer = Game::entityManager->GetEntity(activePlayerID); if (activePlayer == nullptr) return; @@ -62,7 +63,7 @@ void NsConcertInstrument::OnTimerDone(Entity* self, std::string name) { return; // If for some reason the player becomes null (for example an unexpected leave), we need to clean up - const auto activePlayer = EntityManager::Instance()->GetEntity(activePlayerID); + const auto activePlayer = Game::entityManager->GetEntity(activePlayerID); if (activePlayer == nullptr && name != "cleanupAfterStop") { StopPlayingInstrument(self, nullptr); return; @@ -122,10 +123,10 @@ void NsConcertInstrument::StartPlayingInstrument(Entity* self, Entity* player) { player->GetObjectID(), "", UNASSIGNED_SYSTEM_ADDRESS); GameMessages::SendPlayCinematic(player->GetObjectID(), cinematics.at(instrumentLot), UNASSIGNED_SYSTEM_ADDRESS); self->AddCallbackTimer(1.0f, [player, instrumentLot]() { - GameMessages::SendPlayAnimation(player, animations.at(instrumentLot), 2.0f); + RenderComponent::PlayAnimation(player, animations.at(instrumentLot), 2.0f); }); - for (auto* soundBox : EntityManager::Instance()->GetEntitiesInGroup("Audio-Concert")) { + for (auto* soundBox : Game::entityManager->GetEntitiesInGroup("Audio-Concert")) { auto* soundTrigger = soundBox->GetComponent(); if (soundTrigger != nullptr) { soundTrigger->ActivateMusicCue(music.at(instrumentLot)); @@ -153,14 +154,14 @@ void NsConcertInstrument::StopPlayingInstrument(Entity* self, Entity* player) { } GameMessages::SendEndCinematic(player->GetObjectID(), cinematics.at(instrumentLot), UNASSIGNED_SYSTEM_ADDRESS, 1.0f); - GameMessages::SendPlayAnimation(player, smashAnimations.at(instrumentLot), 2.0f); + RenderComponent::PlayAnimation(player, smashAnimations.at(instrumentLot), 2.0f); GameMessages::SendNotifyClientObject(self->GetObjectID(), u"stopCheckingMovement", 0, 0, player->GetObjectID(), "", UNASSIGNED_SYSTEM_ADDRESS); } self->SetVar(u"beingPlayed", false); - for (auto* soundBox : EntityManager::Instance()->GetEntitiesInGroup("Audio-Concert")) { + for (auto* soundBox : Game::entityManager->GetEntitiesInGroup("Audio-Concert")) { auto* soundTrigger = soundBox->GetComponent(); if (soundTrigger != nullptr) { soundTrigger->DeactivateMusicCue(music.at(instrumentLot)); diff --git a/dScripts/ai/NS/NsConcertQuickBuild.cpp b/dScripts/ai/NS/NsConcertQuickBuild.cpp index 4589ee6a..960b90d5 100644 --- a/dScripts/ai/NS/NsConcertQuickBuild.cpp +++ b/dScripts/ai/NS/NsConcertQuickBuild.cpp @@ -42,7 +42,7 @@ void NsConcertQuickBuild::OnStartup(Entity* self) { // Get the manager of the crate of this quick build const auto groupNumber = std::stoi(splitGroup.at(3)); - const auto managerObjects = EntityManager::Instance()->GetEntitiesInGroup("CB_" + std::to_string(groupNumber)); + const auto managerObjects = Game::entityManager->GetEntitiesInGroup("CB_" + std::to_string(groupNumber)); if (managerObjects.empty()) return; @@ -67,7 +67,7 @@ float NsConcertQuickBuild::GetBlinkTime(float time) { } void NsConcertQuickBuild::OnDie(Entity* self, Entity* killer) { - auto* managerObject = EntityManager::Instance()->GetEntity(self->GetVar(u"managerObject")); + auto* managerObject = Game::entityManager->GetEntity(self->GetVar(u"managerObject")); if (managerObject) { managerObject->CancelAllTimers(); managerObject->AddCallbackTimer(1.0f, [managerObject]() { @@ -90,7 +90,7 @@ void NsConcertQuickBuild::OnRebuildComplete(Entity* self, Entity* target) { // Find all the quick build objects of the same lot auto finishedQuickBuildObjects = std::vector(); for (auto quickBuildID : finishedQuickBuilds) { - const auto quickBuildObject = EntityManager::Instance()->GetEntity(quickBuildID); + const auto quickBuildObject = Game::entityManager->GetEntity(quickBuildID); if (quickBuildObject && quickBuildObject->GetLOT() == self->GetLOT()) { quickBuildObject->SetVar(u"Player_" + (GeneralUtils::to_u16string(groupNumber)), target->GetObjectID()); finishedQuickBuildObjects.push_back(quickBuildObject); @@ -101,7 +101,7 @@ void NsConcertQuickBuild::OnRebuildComplete(Entity* self, Entity* target) { if (finishedQuickBuildObjects.size() >= 4) { // Move all the platforms so the user can collect the imagination brick - const auto movingPlatforms = EntityManager::Instance()->GetEntitiesInGroup("ConcertPlatforms"); + const auto movingPlatforms = Game::entityManager->GetEntitiesInGroup("ConcertPlatforms"); for (auto* movingPlatform : movingPlatforms) { auto* component = movingPlatform->GetComponent(); if (component) { @@ -184,7 +184,7 @@ void NsConcertQuickBuild::ProgressLicensedTechnician(Entity* self) { for (auto i = 1; i < 5; i++) { const auto playerID = self->GetVar(u"Player_" + (GeneralUtils::to_u16string(i))); if (playerID != LWOOBJID_EMPTY) { - const auto player = EntityManager::Instance()->GetEntity(playerID); + const auto player = Game::entityManager->GetEntity(playerID); if (player) { auto playerMissionComponent = player->GetComponent(); if (playerMissionComponent) @@ -202,7 +202,7 @@ void NsConcertQuickBuild::UpdateEffects(Entity* self) { return; for (const auto& effectName : setIterator->second.effects) { - const auto effectObjects = EntityManager::Instance()->GetEntitiesInGroup(quickBuildFX.at(effectName)); + const auto effectObjects = Game::entityManager->GetEntitiesInGroup(quickBuildFX.at(effectName)); for (auto* effectObject : effectObjects) { GameMessages::SendPlayFXEffect(effectObject, 0, GeneralUtils::ASCIIToUTF16(effectName), effectName + "Effect", LWOOBJID_EMPTY, 1, 1, true); @@ -216,7 +216,7 @@ void NsConcertQuickBuild::CancelEffects(Entity* self) { return; for (const auto& effectName : setIterator->second.effects) { - const auto effectObjects = EntityManager::Instance()->GetEntitiesInGroup(quickBuildFX.at(effectName)); + const auto effectObjects = Game::entityManager->GetEntitiesInGroup(quickBuildFX.at(effectName)); for (auto* effectObject : effectObjects) { GameMessages::SendStopFXEffect(effectObject, true, effectName + "Effect"); } diff --git a/dScripts/ai/NS/NsQbImaginationStatue.cpp b/dScripts/ai/NS/NsQbImaginationStatue.cpp index a2e335b7..8f9a0b09 100644 --- a/dScripts/ai/NS/NsQbImaginationStatue.cpp +++ b/dScripts/ai/NS/NsQbImaginationStatue.cpp @@ -31,7 +31,7 @@ void NsQbImaginationStatue::OnTimerDone(Entity* self, std::string timerName) { void NsQbImaginationStatue::SpawnLoot(Entity* self) { const auto playerId = self->GetVar(u"Player"); - auto* player = EntityManager::Instance()->GetEntity(playerId); + auto* player = Game::entityManager->GetEntity(playerId); if (player == nullptr) return; diff --git a/dScripts/ai/NS/WH/RockHydrantBroken.cpp b/dScripts/ai/NS/WH/RockHydrantBroken.cpp index 835d52f6..243761d3 100644 --- a/dScripts/ai/NS/WH/RockHydrantBroken.cpp +++ b/dScripts/ai/NS/WH/RockHydrantBroken.cpp @@ -7,7 +7,7 @@ void RockHydrantBroken::OnStartup(Entity* self) { const auto hydrant = "hydrant" + self->GetVar(u"hydrant"); - const auto bouncers = EntityManager::Instance()->GetEntitiesInGroup(hydrant); + const auto bouncers = Game::entityManager->GetEntitiesInGroup(hydrant); for (auto* bouncer : bouncers) { self->SetVar(u"bouncer", bouncer->GetObjectID()); @@ -23,7 +23,7 @@ void RockHydrantBroken::OnStartup(Entity* self) { void RockHydrantBroken::OnTimerDone(Entity* self, std::string timerName) { if (timerName == "KillBroken") { - auto* bouncer = EntityManager::Instance()->GetEntity(self->GetVar(u"bouncer")); + auto* bouncer = Game::entityManager->GetEntity(self->GetVar(u"bouncer")); if (bouncer != nullptr) { GameMessages::SendBouncerActiveStatus(bouncer->GetObjectID(), false, UNASSIGNED_SYSTEM_ADDRESS); diff --git a/dScripts/ai/NS/WH/RockHydrantSmashable.cpp b/dScripts/ai/NS/WH/RockHydrantSmashable.cpp index b3a01567..d388baac 100644 --- a/dScripts/ai/NS/WH/RockHydrantSmashable.cpp +++ b/dScripts/ai/NS/WH/RockHydrantSmashable.cpp @@ -15,7 +15,7 @@ void RockHydrantSmashable::OnDie(Entity* self, Entity* killer) { info.settings = { data }; info.spawnerID = self->GetSpawnerID(); - auto* hydrant = EntityManager::Instance()->CreateEntity(info); + auto* hydrant = Game::entityManager->CreateEntity(info); - EntityManager::Instance()->ConstructEntity(hydrant); + Game::entityManager->ConstructEntity(hydrant); } diff --git a/dScripts/ai/NS/WhFans.cpp b/dScripts/ai/NS/WhFans.cpp index 44354127..a41a2c23 100644 --- a/dScripts/ai/NS/WhFans.cpp +++ b/dScripts/ai/NS/WhFans.cpp @@ -4,6 +4,8 @@ #include "GameMessages.h" #include "EntityManager.h" #include "PhantomPhysicsComponent.h" +#include "RenderComponent.h" +#include "Entity.h" void WhFans::OnStartup(Entity* self) { self->SetVar(u"alive", true); @@ -21,7 +23,7 @@ void WhFans::ToggleFX(Entity* self, bool hit) { fanGroup = ""; } - std::vector fanVolumes = EntityManager::Instance()->GetEntitiesInGroup(fanGroup); + std::vector fanVolumes = Game::entityManager->GetEntitiesInGroup(fanGroup); auto* renderComponent = self->GetComponent(); @@ -30,7 +32,7 @@ void WhFans::ToggleFX(Entity* self, bool hit) { if (fanVolumes.size() == 0 || !self->GetVar(u"alive")) return; if (self->GetVar(u"on")) { - GameMessages::SendPlayAnimation(self, u"fan-off"); + RenderComponent::PlayAnimation(self, u"fan-off"); renderComponent->StopEffect("fanOn"); self->SetVar(u"on", false); @@ -39,10 +41,10 @@ void WhFans::ToggleFX(Entity* self, bool hit) { auto volumePhys = volume->GetComponent(); if (!volumePhys) continue; volumePhys->SetPhysicsEffectActive(false); - EntityManager::Instance()->SerializeEntity(volume); + Game::entityManager->SerializeEntity(volume); } } else if (!self->GetVar(u"on") && self->GetVar(u"alive")) { - GameMessages::SendPlayAnimation(self, u"fan-on"); + RenderComponent::PlayAnimation(self, u"fan-on"); self->SetVar(u"on", true); @@ -50,7 +52,7 @@ void WhFans::ToggleFX(Entity* self, bool hit) { auto volumePhys = volume->GetComponent(); if (!volumePhys) continue; volumePhys->SetPhysicsEffectActive(true); - EntityManager::Instance()->SerializeEntity(volume); + Game::entityManager->SerializeEntity(volume); } } } diff --git a/dScripts/ai/PETS/HydrantSmashable.cpp b/dScripts/ai/PETS/HydrantSmashable.cpp index 1ff082ea..fc83a5d3 100644 --- a/dScripts/ai/PETS/HydrantSmashable.cpp +++ b/dScripts/ai/PETS/HydrantSmashable.cpp @@ -15,7 +15,7 @@ void HydrantSmashable::OnDie(Entity* self, Entity* killer) { info.settings = { data }; info.spawnerID = self->GetSpawnerID(); - auto* hydrant = EntityManager::Instance()->CreateEntity(info); + auto* hydrant = Game::entityManager->CreateEntity(info); - EntityManager::Instance()->ConstructEntity(hydrant); + Game::entityManager->ConstructEntity(hydrant); } diff --git a/dScripts/ai/PROPERTY/AG/AgPropGuard.cpp b/dScripts/ai/PROPERTY/AG/AgPropGuard.cpp index 853da92d..e8e94b53 100644 --- a/dScripts/ai/PROPERTY/AG/AgPropGuard.cpp +++ b/dScripts/ai/PROPERTY/AG/AgPropGuard.cpp @@ -31,10 +31,10 @@ void AgPropGuard::OnMissionDialogueOK(Entity* self, Entity* target, int missionI (missionID == 320 && state == eMissionState::AVAILABLE) /*|| (state == eMissionState::COMPLETE && missionID == 891 && missionState == eMissionState::READY_TO_COMPLETE)*/ ) { - //GameMessages::SendNotifyClientObject(EntityManager::Instance()->GetZoneControlEntity()->GetObjectID(), u"GuardChat", target->GetObjectID(), 0, target->GetObjectID(), "", target->GetSystemAddress()); + //GameMessages::SendNotifyClientObject(Game::entityManager->GetZoneControlEntity()->GetObjectID(), u"GuardChat", target->GetObjectID(), 0, target->GetObjectID(), "", target->GetSystemAddress()); target->GetCharacter()->SetPlayerFlag(113, true); - EntityManager::Instance()->GetZoneControlEntity()->AddTimer("GuardFlyAway", 1.0f); + Game::entityManager->GetZoneControlEntity()->AddTimer("GuardFlyAway", 1.0f); } } diff --git a/dScripts/ai/PROPERTY/AgPropguards.cpp b/dScripts/ai/PROPERTY/AgPropguards.cpp index 9fc6010a..c514031a 100644 --- a/dScripts/ai/PROPERTY/AgPropguards.cpp +++ b/dScripts/ai/PROPERTY/AgPropguards.cpp @@ -20,7 +20,7 @@ void AgPropguards::OnMissionDialogueOK(Entity* self, Entity* target, int mission GameMessages::SendPlayCinematic(target->GetObjectID(), u"MissionCam", target->GetSystemAddress()); } else if (missionState == eMissionState::COMPLETE_READY_TO_COMPLETE) { // Makes the guard disappear once the mission has been completed - const auto zoneControlID = EntityManager::Instance()->GetZoneControlEntity()->GetObjectID(); + const auto zoneControlID = Game::entityManager->GetZoneControlEntity()->GetObjectID(); GameMessages::SendNotifyClientObject(zoneControlID, u"GuardChat", 0, 0, self->GetObjectID(), "", UNASSIGNED_SYSTEM_ADDRESS); @@ -29,7 +29,7 @@ void AgPropguards::OnMissionDialogueOK(Entity* self, Entity* target, int mission if (spawnerName.empty()) spawnerName = "Guard"; - auto spawners = dZoneManager::Instance()->GetSpawnersByName(spawnerName); + auto spawners = Game::zoneManager->GetSpawnersByName(spawnerName); for (auto* spawner : spawners) { spawner->Deactivate(); } @@ -39,7 +39,7 @@ void AgPropguards::OnMissionDialogueOK(Entity* self, Entity* target, int mission } } -uint32_t AgPropguards::GetFlagForMission(uint32_t missionID) { +int32_t AgPropguards::GetFlagForMission(uint32_t missionID) { switch (missionID) { case 872: return 97; diff --git a/dScripts/ai/PROPERTY/AgPropguards.h b/dScripts/ai/PROPERTY/AgPropguards.h index 25701f86..ed2e3cb0 100644 --- a/dScripts/ai/PROPERTY/AgPropguards.h +++ b/dScripts/ai/PROPERTY/AgPropguards.h @@ -4,5 +4,5 @@ class AgPropguards : public CppScripts::Script { void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) override; private: - static uint32_t GetFlagForMission(uint32_t missionID); + static int32_t GetFlagForMission(uint32_t missionID); }; diff --git a/dScripts/ai/RACING/OBJECTS/FvRaceSmashEggImagineServer.cpp b/dScripts/ai/RACING/OBJECTS/FvRaceSmashEggImagineServer.cpp index f69a3eb6..2bdb0364 100644 --- a/dScripts/ai/RACING/OBJECTS/FvRaceSmashEggImagineServer.cpp +++ b/dScripts/ai/RACING/OBJECTS/FvRaceSmashEggImagineServer.cpp @@ -12,14 +12,14 @@ void FvRaceSmashEggImagineServer::OnDie(Entity* self, Entity* killer) { auto* destroyableComponent = killer->GetComponent(); if (destroyableComponent != nullptr) { destroyableComponent->SetImagination(destroyableComponent->GetImagination() + 10); - EntityManager::Instance()->SerializeEntity(killer); + Game::entityManager->SerializeEntity(killer); } // get possessor to progress statistics and tasks. auto* possessableComponent = killer->GetComponent(); if (possessableComponent != nullptr) { - auto* possessor = EntityManager::Instance()->GetEntity(possessableComponent->GetPossessor()); + auto* possessor = Game::entityManager->GetEntity(possessableComponent->GetPossessor()); if (possessor != nullptr) { auto* missionComponent = possessor->GetComponent(); diff --git a/dScripts/ai/RACING/OBJECTS/RaceImagineCrateServer.cpp b/dScripts/ai/RACING/OBJECTS/RaceImagineCrateServer.cpp index 6a29f9a8..20a3c0cc 100644 --- a/dScripts/ai/RACING/OBJECTS/RaceImagineCrateServer.cpp +++ b/dScripts/ai/RACING/OBJECTS/RaceImagineCrateServer.cpp @@ -30,14 +30,14 @@ void RaceImagineCrateServer::OnDie(Entity* self, Entity* killer) { if (destroyableComponent != nullptr) { destroyableComponent->SetImagination(60); - EntityManager::Instance()->SerializeEntity(killer); + Game::entityManager->SerializeEntity(killer); } // Find possessor of race car to progress missions and update stats. auto* possessableComponent = killer->GetComponent(); if (possessableComponent != nullptr) { - auto* possessor = EntityManager::Instance()->GetEntity(possessableComponent->GetPossessor()); + auto* possessor = Game::entityManager->GetEntity(possessableComponent->GetPossessor()); if (possessor != nullptr) { auto* missionComponent = possessor->GetComponent(); diff --git a/dScripts/ai/RACING/OBJECTS/RaceImaginePowerup.cpp b/dScripts/ai/RACING/OBJECTS/RaceImaginePowerup.cpp index 92a50873..d55eeffd 100644 --- a/dScripts/ai/RACING/OBJECTS/RaceImaginePowerup.cpp +++ b/dScripts/ai/RACING/OBJECTS/RaceImaginePowerup.cpp @@ -15,7 +15,7 @@ void RaceImaginePowerup::OnFireEventServerSide(Entity* self, Entity* sender, std return; } - auto* vehicle = EntityManager::Instance()->GetEntity(possessorComponent->GetPossessable()); + auto* vehicle = Game::entityManager->GetEntity(possessorComponent->GetPossessable()); if (vehicle == nullptr) { return; diff --git a/dScripts/ai/RACING/OBJECTS/RaceSmashServer.cpp b/dScripts/ai/RACING/OBJECTS/RaceSmashServer.cpp index 295f38ee..5fcb2ff4 100644 --- a/dScripts/ai/RACING/OBJECTS/RaceSmashServer.cpp +++ b/dScripts/ai/RACING/OBJECTS/RaceSmashServer.cpp @@ -11,7 +11,7 @@ void RaceSmashServer::OnDie(Entity* self, Entity* killer) { auto* possessableComponent = killer->GetComponent(); if (possessableComponent != nullptr) { - auto* possessor = EntityManager::Instance()->GetEntity(possessableComponent->GetPossessor()); + auto* possessor = Game::entityManager->GetEntity(possessableComponent->GetPossessor()); if (possessor != nullptr) { auto* missionComponent = possessor->GetComponent(); diff --git a/dScripts/ai/WILD/WildAmbients.cpp b/dScripts/ai/WILD/WildAmbients.cpp index 16dfa043..c21b6d76 100644 --- a/dScripts/ai/WILD/WildAmbients.cpp +++ b/dScripts/ai/WILD/WildAmbients.cpp @@ -1,6 +1,7 @@ #include "WildAmbients.h" #include "GameMessages.h" +#include "RenderComponent.h" void WildAmbients::OnUse(Entity* self, Entity* user) { - GameMessages::SendPlayAnimation(self, u"interact"); + RenderComponent::PlayAnimation(self, u"interact"); } diff --git a/dScripts/ai/WILD/WildNinjaSensei.cpp b/dScripts/ai/WILD/WildNinjaSensei.cpp index 42ddfa21..0941e41c 100644 --- a/dScripts/ai/WILD/WildNinjaSensei.cpp +++ b/dScripts/ai/WILD/WildNinjaSensei.cpp @@ -8,27 +8,27 @@ void WildNinjaSensei::OnStartup(Entity* self) { void WildNinjaSensei::OnTimerDone(Entity* self, std::string timerName) { if (timerName == "CraneStart") { - auto ninjas = EntityManager::Instance()->GetEntitiesInGroup("Ninjastuff"); + auto ninjas = Game::entityManager->GetEntitiesInGroup("Ninjastuff"); for (auto ninja : ninjas) ninja->NotifyObject(self, "Crane"); self->AddTimer("Bow", 15.5f); self->AddTimer("TigerStart", 25); GameMessages::SendPlayAnimation(self, u"crane"); } else if (timerName == "TigerStart") { - auto ninjas = EntityManager::Instance()->GetEntitiesInGroup("Ninjastuff"); + auto ninjas = Game::entityManager->GetEntitiesInGroup("Ninjastuff"); GameMessages::SendPlayAnimation(self, u"bow"); for (auto ninja : ninjas) ninja->NotifyObject(self, "Tiger"); self->AddTimer("Bow", 15.5f); self->AddTimer("MantisStart", 25); GameMessages::SendPlayAnimation(self, u"tiger"); } else if (timerName == "MantisStart") { - auto ninjas = EntityManager::Instance()->GetEntitiesInGroup("Ninjastuff"); + auto ninjas = Game::entityManager->GetEntitiesInGroup("Ninjastuff"); GameMessages::SendPlayAnimation(self, u"tiger"); for (auto ninja : ninjas) ninja->NotifyObject(self, "Mantis"); self->AddTimer("Bow", 15.5f); self->AddTimer("CraneStart", 25); GameMessages::SendPlayAnimation(self, u"mantis"); } else if (timerName == "Bow") { - auto ninjas = EntityManager::Instance()->GetEntitiesInGroup("Ninjastuff"); + auto ninjas = Game::entityManager->GetEntitiesInGroup("Ninjastuff"); for (auto ninja : ninjas) ninja->NotifyObject(self, "Bow"); GameMessages::SendPlayAnimation(self, u"bow"); } diff --git a/dScripts/zone/PROPERTY/FV/ZoneFvProperty.cpp b/dScripts/zone/PROPERTY/FV/ZoneFvProperty.cpp index 67ada039..8b8072ad 100644 --- a/dScripts/zone/PROPERTY/FV/ZoneFvProperty.cpp +++ b/dScripts/zone/PROPERTY/FV/ZoneFvProperty.cpp @@ -29,8 +29,8 @@ void ZoneFvProperty::SetGameVariables(Entity* self) { self->SetVar>(AmbientFXSpawner, { "Ash", "FX", "Fog" }); self->SetVar>(BehaviorObjsSpawner, {}); - self->SetVar(defeatedProperyFlag, 99); - self->SetVar(placedModelFlag, 107); + self->SetVar(defeatedProperyFlag, 99); + self->SetVar(placedModelFlag, 107); self->SetVar(guardMissionFlag, 874); self->SetVar(brickLinkMissionIDFlag, 950); self->SetVar(passwordFlag, "s3kratK1ttN"); diff --git a/dScripts/zone/PROPERTY/GF/ZoneGfProperty.cpp b/dScripts/zone/PROPERTY/GF/ZoneGfProperty.cpp index 565d8cd6..87b2345d 100644 --- a/dScripts/zone/PROPERTY/GF/ZoneGfProperty.cpp +++ b/dScripts/zone/PROPERTY/GF/ZoneGfProperty.cpp @@ -29,8 +29,8 @@ void ZoneGfProperty::SetGameVariables(Entity* self) { self->SetVar>(AmbientFXSpawner, { "Birds", "Falls", "Sunbeam" }); self->SetVar>(BehaviorObjsSpawner, { "TrappedPlatform", "IceBarrier", "FireBeast" }); - self->SetVar(defeatedProperyFlag, 98); - self->SetVar(placedModelFlag, 106); + self->SetVar(defeatedProperyFlag, 98); + self->SetVar(placedModelFlag, 106); self->SetVar(guardMissionFlag, 873); self->SetVar(brickLinkMissionIDFlag, 949); self->SetVar(passwordFlag, "s3kratK1ttN"); diff --git a/dScripts/zone/PROPERTY/NS/ZoneNsProperty.cpp b/dScripts/zone/PROPERTY/NS/ZoneNsProperty.cpp index 49364ee8..52bb02e2 100644 --- a/dScripts/zone/PROPERTY/NS/ZoneNsProperty.cpp +++ b/dScripts/zone/PROPERTY/NS/ZoneNsProperty.cpp @@ -30,8 +30,8 @@ void ZoneNsProperty::SetGameVariables(Entity* self) { self->SetVar>(AmbientFXSpawner, { "Rockets" }); self->SetVar>(BehaviorObjsSpawner, { "Cage", "Platform", "Door" }); - self->SetVar(defeatedProperyFlag, 97); - self->SetVar(placedModelFlag, 105); + self->SetVar(defeatedProperyFlag, 97); + self->SetVar(placedModelFlag, 105); self->SetVar(guardMissionFlag, 872); self->SetVar(brickLinkMissionIDFlag, 948); self->SetVar(passwordFlag, "s3kratK1ttN"); diff --git a/dWorldServer/ObjectIDManager.cpp b/dWorldServer/ObjectIDManager.cpp index ef5fb9a5..9490c0a7 100644 --- a/dWorldServer/ObjectIDManager.cpp +++ b/dWorldServer/ObjectIDManager.cpp @@ -1,8 +1,5 @@ #include "ObjectIDManager.h" -// Std -#include - // Custom Classes #include "MasterPackets.h" #include "Database.h" @@ -48,11 +45,7 @@ void ObjectIDManager::HandleRequestPersistentIDResponse(uint64_t requestID, uint //! Handles cases where we have to get a unique object ID synchronously uint32_t ObjectIDManager::GenerateRandomObjectID() { - std::random_device rd; - - std::mt19937 rng(rd()); - - return uni(rng); + return uni(Game::randomEngine); } diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index 4eca86f2..f07c17e3 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -60,7 +60,7 @@ #include "AssetManager.h" #include "LevelProgressionComponent.h" #include "eBlueprintSaveResponseType.h" -#include "AMFFormat.h" +#include "Amf3.h" #include "NiPoint3.h" #include "eServerDisconnectIdentifiers.h" #include "eObjectBits.h" @@ -71,6 +71,7 @@ #include "eMasterMessageType.h" #include "eGameMessageType.h" #include "ZCompression.h" +#include "EntityManager.h" namespace Game { dLogger* logger = nullptr; @@ -83,6 +84,8 @@ namespace Game { std::mt19937 randomEngine; SystemAddress chatSysAddr; bool shouldShutdown = false; + EntityManager* entityManager = nullptr; + dZoneManager* zoneManager = nullptr; } // namespace Game bool chatDisabled = false; @@ -251,10 +254,12 @@ int main(int argc, char** argv) { PerformanceManager::SelectProfile(zoneID); + Game::entityManager = new EntityManager(); + Game::zoneManager = new dZoneManager(); //Load our level: if (zoneID != 0) { dpWorld::Instance().Initialize(zoneID); - dZoneManager::Instance()->Initialize(LWOZONEID(zoneID, instanceID, cloneID)); + Game::zoneManager->Initialize(LWOZONEID(zoneID, instanceID, cloneID)); g_CloneID = cloneID; // pre calculate the FDB checksum @@ -297,6 +302,8 @@ int main(int argc, char** argv) { Game::logger->Log("WorldServer", "FDB Checksum calculated as: %s", databaseChecksum.c_str()); } + } else { + Game::entityManager->Initialize(); } uint32_t currentFrameDelta = highFrameDelta; @@ -383,18 +390,18 @@ int main(int argc, char** argv) { Metrics::EndMeasurement(MetricVariable::Physics); Metrics::StartMeasurement(MetricVariable::UpdateEntities); - EntityManager::Instance()->UpdateEntities(deltaTime); + Game::entityManager->UpdateEntities(deltaTime); Metrics::EndMeasurement(MetricVariable::UpdateEntities); Metrics::StartMeasurement(MetricVariable::Ghosting); if (std::chrono::duration(currentTime - ghostingLastTime).count() >= 1.0f) { - EntityManager::Instance()->UpdateGhosting(); + Game::entityManager->UpdateGhosting(); ghostingLastTime = currentTime; } Metrics::EndMeasurement(MetricVariable::Ghosting); Metrics::StartMeasurement(MetricVariable::UpdateSpawners); - dZoneManager::Instance()->Update(deltaTime); + Game::zoneManager->Update(deltaTime); Metrics::EndMeasurement(MetricVariable::UpdateSpawners); } @@ -554,12 +561,11 @@ void HandlePacketChat(Packet* packet) { if (static_cast(packet->data[1]) == eConnectionType::CHAT_INTERNAL) { switch (static_cast(packet->data[3])) { case eChatInternalMessageType::ROUTE_TO_PLAYER: { - CINSTREAM; + CINSTREAM_SKIP_HEADER; LWOOBJID playerID; inStream.Read(playerID); - inStream.Read(playerID); - auto player = EntityManager::Instance()->GetEntity(playerID); + auto player = Game::entityManager->GetEntity(playerID); if (!player) return; auto sysAddr = player->GetSystemAddress(); @@ -576,9 +582,7 @@ void HandlePacketChat(Packet* packet) { } case eChatInternalMessageType::ANNOUNCEMENT: { - CINSTREAM; - LWOOBJID header; - inStream.Read(header); + CINSTREAM_SKIP_HEADER; std::string title; std::string msg; @@ -601,28 +605,23 @@ void HandlePacketChat(Packet* packet) { //Send to our clients: AMFArrayValue args; - auto* titleValue = new AMFStringValue(); - titleValue->SetStringValue(title.c_str()); - auto* messageValue = new AMFStringValue(); - messageValue->SetStringValue(msg.c_str()); - args.InsertValue("title", titleValue); - args.InsertValue("message", messageValue); + args.Insert("title", title); + args.Insert("message", msg); - GameMessages::SendUIMessageServerToAllClients("ToggleAnnounce", &args); + GameMessages::SendUIMessageServerToAllClients("ToggleAnnounce", args); break; } case eChatInternalMessageType::MUTE_UPDATE: { - CINSTREAM; + CINSTREAM_SKIP_HEADER; LWOOBJID playerId; time_t expire = 0; inStream.Read(playerId); - inStream.Read(playerId); inStream.Read(expire); - auto* entity = EntityManager::Instance()->GetEntity(playerId); + auto* entity = Game::entityManager->GetEntity(playerId); if (entity != nullptr) { entity->GetParentUser()->SetMuteExpire(expire); @@ -634,9 +633,7 @@ void HandlePacketChat(Packet* packet) { } case eChatInternalMessageType::TEAM_UPDATE: { - CINSTREAM; - LWOOBJID header; - inStream.Read(header); + CINSTREAM_SKIP_HEADER; LWOOBJID teamID = 0; char lootOption = 0; @@ -688,7 +685,7 @@ void HandlePacket(Packet* packet) { return; } - auto* entity = EntityManager::Instance()->GetEntity(c->GetObjectID()); + auto* entity = Game::entityManager->GetEntity(c->GetObjectID()); if (!entity) { entity = Player::GetPlayer(packet->systemAddress); @@ -705,7 +702,7 @@ void HandlePacket(Packet* packet) { Game::logger->Log("WorldServer", "Deleting player %llu", entity->GetObjectID()); - EntityManager::Instance()->DestroyEntity(entity); + Game::entityManager->DestroyEntity(entity); } { @@ -728,7 +725,7 @@ void HandlePacket(Packet* packet) { Game::server->SendToMaster(&bitStream); } - if (packet->data[0] != ID_USER_PACKET_ENUM) return; + if (packet->data[0] != ID_USER_PACKET_ENUM || packet->length < 4) return; if (static_cast(packet->data[1]) == eConnectionType::SERVER) { if (static_cast(packet->data[3]) == eServerMessageType::VERSION_CONFIRM) { AuthPackets::HandleHandshake(Game::server, packet); @@ -781,7 +778,7 @@ void HandlePacket(Packet* packet) { //Create our user and send them in: UserManager::Instance()->CreateUser(it->second.sysAddr, username, userHash); - auto zone = dZoneManager::Instance()->GetZone(); + auto zone = Game::zoneManager->GetZone(); if (zone) { float x = 0.0f; float y = 0.0f; @@ -927,7 +924,7 @@ void HandlePacket(Packet* packet) { if (Game::server->GetZoneID() != 0) { auto user = UserManager::Instance()->GetUser(packet->systemAddress); if (!user) return; - EntityManager::Instance()->DestroyEntity(user->GetLastUsedChar()->GetEntity()); + Game::entityManager->DestroyEntity(user->GetLastUsedChar()->GetEntity()); } //This loops prevents users who aren't authenticated to double-request the char list, which @@ -1015,20 +1012,20 @@ void HandlePacket(Packet* packet) { EntityInfo info{}; info.lot = 1; - Entity* player = EntityManager::Instance()->CreateEntity(info, UserManager::Instance()->GetUser(packet->systemAddress)); + Entity* player = Game::entityManager->CreateEntity(info, UserManager::Instance()->GetUser(packet->systemAddress)); WorldPackets::SendCreateCharacter(packet->systemAddress, player, c->GetXMLData(), username, c->GetGMLevel()); WorldPackets::SendServerState(packet->systemAddress); - const auto respawnPoint = player->GetCharacter()->GetRespawnPoint(dZoneManager::Instance()->GetZone()->GetWorldID()); + const auto respawnPoint = player->GetCharacter()->GetRespawnPoint(Game::zoneManager->GetZone()->GetWorldID()); - EntityManager::Instance()->ConstructEntity(player, UNASSIGNED_SYSTEM_ADDRESS, true); + Game::entityManager->ConstructEntity(player, UNASSIGNED_SYSTEM_ADDRESS, true); if (respawnPoint != NiPoint3::ZERO) { GameMessages::SendPlayerReachedRespawnCheckpoint(player, respawnPoint, NiQuaternion::IDENTITY); } - EntityManager::Instance()->ConstructAllEntities(packet->systemAddress); + Game::entityManager->ConstructAllEntities(packet->systemAddress); auto* characterComponent = player->GetComponent(); if (characterComponent) { @@ -1070,7 +1067,7 @@ void HandlePacket(Packet* packet) { //Tell the player to generate BBB models, if any: if (g_CloneID != 0) { - const auto& worldId = dZoneManager::Instance()->GetZone()->GetZoneID(); + const auto& worldId = Game::zoneManager->GetZone()->GetZoneID(); const auto zoneId = Game::server->GetZoneID(); const auto cloneId = g_CloneID; @@ -1180,7 +1177,7 @@ void HandlePacket(Packet* packet) { bitStream.Write(playerName[i]); } - auto zone = dZoneManager::Instance()->GetZone()->GetZoneID(); + auto zone = Game::zoneManager->GetZone()->GetZoneID(); bitStream.Write(zone.GetMapID()); bitStream.Write(zone.GetInstanceID()); bitStream.Write(zone.GetCloneID()); @@ -1213,10 +1210,8 @@ void HandlePacket(Packet* packet) { case eWorldMessageType::ROUTE_PACKET: { //Yeet to chat - CINSTREAM; - uint64_t header = 0; + CINSTREAM_SKIP_HEADER; uint32_t size = 0; - inStream.Read(header); inStream.Read(size); if (size > 20000) { @@ -1339,9 +1334,11 @@ void FinalizeShutdown() { Metrics::Clear(); Database::Destroy("WorldServer"); if (Game::chatFilter) delete Game::chatFilter; + if (Game::zoneManager) delete Game::zoneManager; if (Game::server) delete Game::server; - if (Game::logger) delete Game::logger; if (Game::config) delete Game::config; + if (Game::entityManager) delete Game::entityManager; + if (Game::logger) delete Game::logger; worldShutdownSequenceComplete = true; diff --git a/dZoneManager/LUTriggers.h b/dZoneManager/LUTriggers.h index a93cd67d..75662778 100644 --- a/dZoneManager/LUTriggers.h +++ b/dZoneManager/LUTriggers.h @@ -3,6 +3,7 @@ #include #include +#include class Command; class Event; diff --git a/dZoneManager/Level.cpp b/dZoneManager/Level.cpp index 55790592..7d248588 100644 --- a/dZoneManager/Level.cpp +++ b/dZoneManager/Level.cpp @@ -179,8 +179,8 @@ void Level::ReadSceneObjectDataChunk(std::istream& file, Header& header) { //This is a little bit of a bodge, but because the alpha client (HF) doesn't store the //spawn position / rotation like the later versions do, we need to check the LOT for the spawn pos & set it. if (obj.lot == LOT_MARKER_PLAYER_START) { - dZoneManager::Instance()->GetZone()->SetSpawnPos(obj.position); - dZoneManager::Instance()->GetZone()->SetSpawnRot(obj.rotation); + Game::zoneManager->GetZone()->SetSpawnPos(obj.position); + Game::zoneManager->GetZone()->SetSpawnRot(obj.rotation); } std::u16string ldfString = u""; @@ -297,7 +297,7 @@ void Level::ReadSceneObjectDataChunk(std::istream& file, Header& header) { } } Spawner* spawner = new Spawner(spawnInfo); - dZoneManager::Instance()->AddSpawner(obj.id, spawner); + Game::zoneManager->AddSpawner(obj.id, spawner); } else { //Regular object EntityInfo info; info.spawnerID = 0; @@ -328,11 +328,11 @@ void Level::ReadSceneObjectDataChunk(std::istream& file, Header& header) { if (!clientOnly) { // We should never have more than 1 zone control object - const auto zoneControlObject = dZoneManager::Instance()->GetZoneControlObject(); + const auto zoneControlObject = Game::zoneManager->GetZoneControlObject(); if (zoneControlObject != nullptr && info.lot == zoneControlObject->GetLOT()) goto deleteSettings; - EntityManager::Instance()->CreateEntity(info, nullptr); + Game::entityManager->CreateEntity(info, nullptr); } else { deleteSettings: diff --git a/dZoneManager/Level.h b/dZoneManager/Level.h index 83daeedb..0f8fa72d 100644 --- a/dZoneManager/Level.h +++ b/dZoneManager/Level.h @@ -30,12 +30,6 @@ public: struct SceneObjectDataChunk { std::map objects; - SceneObject& GetObject(LWOOBJID id) { - for (std::map::iterator it = objects.begin(); it != objects.end(); ++it) { - if (it->first == id) return it->second; - } - } - const void PrintAllObjects() { for (std::map::iterator it = objects.begin(); it != objects.end(); ++it) { std::cout << "\t ID: " << it->first << " LOT: " << it->second.lot << std::endl; diff --git a/dZoneManager/Spawner.cpp b/dZoneManager/Spawner.cpp index 28f77fea..bd1970c6 100644 --- a/dZoneManager/Spawner.cpp +++ b/dZoneManager/Spawner.cpp @@ -46,9 +46,9 @@ Spawner::Spawner(const SpawnerInfo info) { } if (m_Info.spawnOnSmashGroupName != "") { - std::vector spawnSmashEntities = EntityManager::Instance()->GetEntitiesInGroup(m_Info.spawnOnSmashGroupName); - std::vector spawnSmashSpawners = dZoneManager::Instance()->GetSpawnersInGroup(m_Info.spawnOnSmashGroupName); - std::vector spawnSmashSpawnersN = dZoneManager::Instance()->GetSpawnersByName(m_Info.spawnOnSmashGroupName); + std::vector spawnSmashEntities = Game::entityManager->GetEntitiesInGroup(m_Info.spawnOnSmashGroupName); + std::vector spawnSmashSpawners = Game::zoneManager->GetSpawnersInGroup(m_Info.spawnOnSmashGroupName); + std::vector spawnSmashSpawnersN = Game::zoneManager->GetSpawnersByName(m_Info.spawnOnSmashGroupName); for (Entity* ssEntity : spawnSmashEntities) { m_SpawnSmashFoundGroup = true; ssEntity->AddDieCallback([=]() { @@ -102,11 +102,11 @@ Entity* Spawner::Spawn(std::vector freeNodes, const bool force) { m_EntityInfo.spawnerID = m_Info.spawnerID; } - Entity* rezdE = EntityManager::Instance()->CreateEntity(m_EntityInfo, nullptr); + Entity* rezdE = Game::entityManager->CreateEntity(m_EntityInfo, nullptr); rezdE->GetGroups() = m_Info.groups; - EntityManager::Instance()->ConstructEntity(rezdE); + Game::entityManager->ConstructEntity(rezdE); m_Entities.insert({ rezdE->GetObjectID(), spawnNode }); spawnNode->entities.push_back(rezdE->GetObjectID()); @@ -143,7 +143,7 @@ void Spawner::Reset() { void Spawner::DestroyAllEntities(){ for (auto* node : m_Info.nodes) { for (const auto& element : node->entities) { - auto* entity = EntityManager::Instance()->GetEntity(element); + auto* entity = Game::entityManager->GetEntity(element); if (entity == nullptr) continue; entity->Kill(); } diff --git a/dZoneManager/Zone.cpp b/dZoneManager/Zone.cpp index 03444af5..90b45f22 100644 --- a/dZoneManager/Zone.cpp +++ b/dZoneManager/Zone.cpp @@ -149,7 +149,7 @@ void Zone::LoadZoneIntoMemory() { info.activeOnLoad = path.spawner.spawnerNetActive; info.isNetwork = true; Spawner* spawner = new Spawner(info); - dZoneManager::Instance()->AddSpawner(info.spawnerID, spawner); + Game::zoneManager->AddSpawner(info.spawnerID, spawner); } } diff --git a/dZoneManager/dZoneManager.cpp b/dZoneManager/dZoneManager.cpp index 1a40748d..51f6e640 100644 --- a/dZoneManager/dZoneManager.cpp +++ b/dZoneManager/dZoneManager.cpp @@ -12,11 +12,11 @@ #include "CDZoneTableTable.h" #include #include "eObjectBits.h" +#include "CDZoneTableTable.h" +#include "AssetManager.h" #include "../dWorldServer/ObjectIDManager.h" -dZoneManager* dZoneManager::m_Address = nullptr; - void dZoneManager::Initialize(const LWOZONEID& zoneID) { Game::logger->Log("dZoneManager", "Preparing zone: %i/%i/%i", zoneID.GetMapID(), zoneID.GetInstanceID(), zoneID.GetCloneID()); @@ -37,8 +37,8 @@ void dZoneManager::Initialize(const LWOZONEID& zoneID) { zoneControlTemplate = zone->zoneControlTemplate != -1 ? zone->zoneControlTemplate : 2365; const auto min = zone->ghostdistance_min != -1.0f ? zone->ghostdistance_min : 100; const auto max = zone->ghostdistance != -1.0f ? zone->ghostdistance : 100; - EntityManager::Instance()->SetGhostDistanceMax(max + min); - EntityManager::Instance()->SetGhostDistanceMin(max); + Game::entityManager->SetGhostDistanceMax(max + min); + Game::entityManager->SetGhostDistanceMin(max); m_PlayerLoseCoinsOnDeath = zone->PlayerLoseCoinsOnDeath; } } @@ -46,10 +46,15 @@ void dZoneManager::Initialize(const LWOZONEID& zoneID) { Game::logger->Log("dZoneManager", "Creating zone control object %i", zoneControlTemplate); // Create ZoneControl object + if (!Game::entityManager) { + Game::logger->Log("dZoneManager", "ERROR: No entity manager loaded. Cannot proceed."); + throw std::invalid_argument("No entity manager loaded. Cannot proceed."); + } + Game::entityManager->Initialize(); EntityInfo info; info.lot = zoneControlTemplate; info.id = 70368744177662; - Entity* zoneControl = EntityManager::Instance()->CreateEntity(info, nullptr, nullptr, true); + Entity* zoneControl = Game::entityManager->CreateEntity(info, nullptr, nullptr, true); m_ZoneControlObject = zoneControl; m_pZone->Initalize(); @@ -146,9 +151,9 @@ LWOOBJID dZoneManager::MakeSpawner(SpawnerInfo info) { entityInfo.id = objectId; entityInfo.lot = 176; - auto* entity = EntityManager::Instance()->CreateEntity(entityInfo, nullptr, nullptr, false, objectId); + auto* entity = Game::entityManager->CreateEntity(entityInfo, nullptr, nullptr, false, objectId); - EntityManager::Instance()->ConstructEntity(entity); + Game::entityManager->ConstructEntity(entity); AddSpawner(objectId, spawner); @@ -173,7 +178,7 @@ void dZoneManager::RemoveSpawner(const LWOOBJID id) { return; } - auto* entity = EntityManager::Instance()->GetEntity(id); + auto* entity = Game::entityManager->GetEntity(id); if (entity != nullptr) { entity->Kill(); @@ -227,6 +232,17 @@ uint32_t dZoneManager::GetUniqueMissionIdStartingValue() { return m_UniqueMissionIdStart; } +bool dZoneManager::CheckIfAccessibleZone(LWOMAPID zoneID) { + //We're gonna go ahead and presume we've got the db loaded already: + CDZoneTableTable* zoneTable = CDClientManager::Instance().GetTable(); + const CDZoneTable* zone = zoneTable->Query(zoneID); + if (zone != nullptr) { + return Game::assetManager->HasFile(("maps/" + zone->zoneName).c_str()); + } else { + return false; + } +} + void dZoneManager::LoadWorldConfig() { Game::logger->Log("dZoneManager", "Loading WorldConfig into memory"); diff --git a/dZoneManager/dZoneManager.h b/dZoneManager/dZoneManager.h index c1776e79..1e08b008 100644 --- a/dZoneManager/dZoneManager.h +++ b/dZoneManager/dZoneManager.h @@ -25,14 +25,6 @@ private: void LoadWorldConfig(); public: - static dZoneManager* Instance() { - if (!m_Address) { - m_Address = new dZoneManager(); - } - - return m_Address; - } - void Initialize(const LWOZONEID& zoneID); ~dZoneManager(); @@ -50,6 +42,7 @@ public: Entity* GetZoneControlObject() { return m_ZoneControlObject; } bool GetPlayerLoseCoinOnDeath() { return m_PlayerLoseCoinsOnDeath; } uint32_t GetUniqueMissionIdStartingValue(); + bool CheckIfAccessibleZone(LWOMAPID zoneID); // The world config should not be modified by a caller. const WorldConfig* GetWorldConfig() { @@ -63,7 +56,6 @@ private: */ uint32_t m_UniqueMissionIdStart = 0; - static dZoneManager* m_Address; //Singleton Zone* m_pZone = nullptr; LWOZONEID m_ZoneID; bool m_PlayerLoseCoinsOnDeath; //Do players drop coins in this zone when smashed diff --git a/docker/Dockerfile b/docker/Dockerfile index a7d91855..c5638a20 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,4 +1,4 @@ -FROM gcc:11 as build +FROM gcc:12 as build WORKDIR /build @@ -40,7 +40,7 @@ RUN echo "Build server" && \ cmake .. -DCMAKE_BUILD_RPATH_USE_ORIGIN=TRUE && \ make -j $BUILD_THREADS -FROM gcc:11 as runtime +FROM gcc:12 as runtime RUN --mount=type=cache,id=runtime-apt-cache,target=/var/cache/apt \ apt update && \ diff --git a/migrations/dlu/9_Update_Leaderboard_Storage.sql b/migrations/dlu/9_Update_Leaderboard_Storage.sql new file mode 100644 index 00000000..c87e3501 --- /dev/null +++ b/migrations/dlu/9_Update_Leaderboard_Storage.sql @@ -0,0 +1,18 @@ +ALTER TABLE leaderboard + ADD COLUMN tertiaryScore FLOAT NOT NULL DEFAULT 0, + ADD COLUMN numWins INT NOT NULL DEFAULT 0, + ADD COLUMN timesPlayed INT NOT NULL DEFAULT 1, + MODIFY time INT NOT NULL DEFAULT 0; + +/* Can only ALTER one column at a time... */ +ALTER TABLE leaderboard CHANGE score primaryScore FLOAT NOT NULL DEFAULT 0; +ALTER TABLE leaderboard CHANGE time secondaryScore FLOAT NOT NULL DEFAULT 0 AFTER primaryScore; + +/* A bit messy, but better than going through a bunch of code fixes all to be run once. */ +UPDATE leaderboard SET + primaryScore = secondaryScore, + secondaryScore = 0 WHERE game_id IN (1, 44, 46, 47, 48, 49, 53, 103, 104, 108, 1901); + +/* Do this last so we dont update entry times erroneously */ +ALTER TABLE leaderboard + CHANGE last_played last_played TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP() ON UPDATE CURRENT_TIMESTAMP(); diff --git a/tests/dCommonTests/AMFDeserializeTests.cpp b/tests/dCommonTests/AMFDeserializeTests.cpp index b679ea78..5a9d91e6 100644 --- a/tests/dCommonTests/AMFDeserializeTests.cpp +++ b/tests/dCommonTests/AMFDeserializeTests.cpp @@ -3,14 +3,17 @@ #include #include "AMFDeserialize.h" -#include "AMFFormat.h" +#include "Amf3.h" + +#include "Game.h" +#include "dLogger.h" /** * Helper method that all tests use to get their respective AMF. */ -std::unique_ptr ReadFromBitStream(RakNet::BitStream* bitStream) { +AMFBaseValue* ReadFromBitStream(RakNet::BitStream* bitStream) { AMFDeserialize deserializer; - std::unique_ptr returnValue(deserializer.Read(bitStream)); + AMFBaseValue* returnValue(deserializer.Read(bitStream)); return returnValue; } @@ -18,10 +21,10 @@ std::unique_ptr ReadFromBitStream(RakNet::BitStream* bitStream) { * @brief Test reading an AMFUndefined value from a BitStream. */ TEST(dCommonTests, AMFDeserializeAMFUndefinedTest) { - CBITSTREAM + CBITSTREAM; bitStream.Write(0x00); - std::unique_ptr res(ReadFromBitStream(&bitStream)); - ASSERT_EQ(res->GetValueType(), AMFValueType::AMFUndefined); + std::unique_ptr res(ReadFromBitStream(&bitStream)); + ASSERT_EQ(res->GetValueType(), eAmf::Undefined); } /** @@ -29,54 +32,54 @@ TEST(dCommonTests, AMFDeserializeAMFUndefinedTest) { * */ TEST(dCommonTests, AMFDeserializeAMFNullTest) { - CBITSTREAM + CBITSTREAM; bitStream.Write(0x01); - std::unique_ptr res(ReadFromBitStream(&bitStream)); - ASSERT_EQ(res->GetValueType(), AMFValueType::AMFNull); + std::unique_ptr res(ReadFromBitStream(&bitStream)); + ASSERT_EQ(res->GetValueType(), eAmf::Null); } /** * @brief Test reading an AMFFalse value from a BitStream. */ TEST(dCommonTests, AMFDeserializeAMFFalseTest) { - CBITSTREAM + CBITSTREAM; bitStream.Write(0x02); - std::unique_ptr res(ReadFromBitStream(&bitStream)); - ASSERT_EQ(res->GetValueType(), AMFValueType::AMFFalse); + std::unique_ptr res(ReadFromBitStream(&bitStream)); + ASSERT_EQ(res->GetValueType(), eAmf::False); } /** * @brief Test reading an AMFTrue value from a BitStream. */ TEST(dCommonTests, AMFDeserializeAMFTrueTest) { - CBITSTREAM + CBITSTREAM; bitStream.Write(0x03); - std::unique_ptr res(ReadFromBitStream(&bitStream)); - ASSERT_EQ(res->GetValueType(), AMFValueType::AMFTrue); + std::unique_ptr res(ReadFromBitStream(&bitStream)); + ASSERT_EQ(res->GetValueType(), eAmf::True); } /** * @brief Test reading an AMFInteger value from a BitStream. */ TEST(dCommonTests, AMFDeserializeAMFIntegerTest) { - CBITSTREAM + CBITSTREAM; { bitStream.Write(0x04); // 127 == 01111111 bitStream.Write(127); - std::unique_ptr res(ReadFromBitStream(&bitStream)); - ASSERT_EQ(res->GetValueType(), AMFValueType::AMFInteger); + std::unique_ptr res(ReadFromBitStream(&bitStream)); + ASSERT_EQ(res->GetValueType(), eAmf::Integer); // Check that the max value of a byte can be read correctly - ASSERT_EQ(static_cast(res.get())->GetIntegerValue(), 127); + ASSERT_EQ(static_cast(res.get())->GetValue(), 127); } bitStream.Reset(); { bitStream.Write(0x04); bitStream.Write(UINT32_MAX); - std::unique_ptr res(ReadFromBitStream(&bitStream)); - ASSERT_EQ(res->GetValueType(), AMFValueType::AMFInteger); + std::unique_ptr res(ReadFromBitStream(&bitStream)); + ASSERT_EQ(res->GetValueType(), eAmf::Integer); // Check that we can read the maximum value correctly - ASSERT_EQ(static_cast(res.get())->GetIntegerValue(), 536870911); + ASSERT_EQ(static_cast(res.get())->GetValue(), 536870911); } bitStream.Reset(); { @@ -87,10 +90,10 @@ TEST(dCommonTests, AMFDeserializeAMFIntegerTest) { bitStream.Write(255); // 127 == 01111111 bitStream.Write(127); - std::unique_ptr res(ReadFromBitStream(&bitStream)); - ASSERT_EQ(res->GetValueType(), AMFValueType::AMFInteger); + std::unique_ptr res(ReadFromBitStream(&bitStream)); + ASSERT_EQ(res->GetValueType(), eAmf::Integer); // Check that short max can be read correctly - ASSERT_EQ(static_cast(res.get())->GetIntegerValue(), UINT16_MAX); + ASSERT_EQ(static_cast(res.get())->GetValue(), UINT16_MAX); } bitStream.Reset(); { @@ -99,10 +102,10 @@ TEST(dCommonTests, AMFDeserializeAMFIntegerTest) { bitStream.Write(255); // 127 == 01111111 bitStream.Write(127); - std::unique_ptr res(ReadFromBitStream(&bitStream)); - ASSERT_EQ(res->GetValueType(), AMFValueType::AMFInteger); + std::unique_ptr res(ReadFromBitStream(&bitStream)); + ASSERT_EQ(res->GetValueType(), eAmf::Integer); // Check that 2 byte max can be read correctly - ASSERT_EQ(static_cast(res.get())->GetIntegerValue(), 16383); + ASSERT_EQ(static_cast(res.get())->GetValue(), 16383); } } @@ -110,42 +113,42 @@ TEST(dCommonTests, AMFDeserializeAMFIntegerTest) { * @brief Test reading an AMFDouble value from a BitStream. */ TEST(dCommonTests, AMFDeserializeAMFDoubleTest) { - CBITSTREAM + CBITSTREAM; bitStream.Write(0x05); bitStream.Write(25346.4f); - std::unique_ptr res(ReadFromBitStream(&bitStream)); - ASSERT_EQ(res->GetValueType(), AMFValueType::AMFDouble); - ASSERT_EQ(static_cast(res.get())->GetDoubleValue(), 25346.4f); + std::unique_ptr res(ReadFromBitStream(&bitStream)); + ASSERT_EQ(res->GetValueType(), eAmf::Double); + ASSERT_EQ(static_cast(res.get())->GetValue(), 25346.4f); } /** * @brief Test reading an AMFString value from a BitStream. */ TEST(dCommonTests, AMFDeserializeAMFStringTest) { - CBITSTREAM + CBITSTREAM; bitStream.Write(0x06); bitStream.Write(0x0F); std::string toWrite = "stateID"; for (auto e : toWrite) bitStream.Write(e); - std::unique_ptr res(ReadFromBitStream(&bitStream)); - ASSERT_EQ(res->GetValueType(), AMFValueType::AMFString); - ASSERT_EQ(static_cast(res.get())->GetStringValue(), "stateID"); + std::unique_ptr res(ReadFromBitStream(&bitStream)); + ASSERT_EQ(res->GetValueType(), eAmf::String); + ASSERT_EQ(static_cast(res.get())->GetValue(), "stateID"); } /** * @brief Test reading an AMFArray value from a BitStream. */ TEST(dCommonTests, AMFDeserializeAMFArrayTest) { - CBITSTREAM + CBITSTREAM; // Test empty AMFArray bitStream.Write(0x09); bitStream.Write(0x01); bitStream.Write(0x01); { - std::unique_ptr res(ReadFromBitStream(&bitStream)); - ASSERT_EQ(res->GetValueType(), AMFValueType::AMFArray); - ASSERT_EQ(static_cast(res.get())->GetAssociativeMap().size(), 0); - ASSERT_EQ(static_cast(res.get())->GetDenseArray().size(), 0); + std::unique_ptr res(ReadFromBitStream(&bitStream)); + ASSERT_EQ(res->GetValueType(), eAmf::Array); + ASSERT_EQ(static_cast(res.get())->GetAssociative().size(), 0); + ASSERT_EQ(static_cast(res.get())->GetDense().size(), 0); } bitStream.Reset(); // Test a key'd value and dense value @@ -161,32 +164,32 @@ TEST(dCommonTests, AMFDeserializeAMFArrayTest) { bitStream.Write(0x0B); for (auto e : "10447") if (e != '\0') bitStream.Write(e); { - std::unique_ptr res(ReadFromBitStream(&bitStream)); - ASSERT_EQ(res->GetValueType(), AMFValueType::AMFArray); - ASSERT_EQ(static_cast(res.get())->GetAssociativeMap().size(), 1); - ASSERT_EQ(static_cast(res.get())->GetDenseArray().size(), 1); - ASSERT_EQ(static_cast(res.get())->FindValue("BehaviorID")->GetStringValue(), "10447"); - ASSERT_EQ(static_cast(res.get())->GetValueAt(0)->GetStringValue(), "10447"); + std::unique_ptr res(ReadFromBitStream(&bitStream)); + ASSERT_EQ(res->GetValueType(), eAmf::Array); + ASSERT_EQ(static_cast(res.get())->GetAssociative().size(), 1); + ASSERT_EQ(static_cast(res.get())->GetDense().size(), 1); + ASSERT_EQ(static_cast(res.get())->Get("BehaviorID")->GetValue(), "10447"); + ASSERT_EQ(static_cast(res.get())->Get(0)->GetValue(), "10447"); } } /** - * @brief This test checks that if we recieve an unimplemented AMFValueType + * @brief This test checks that if we recieve an unimplemented eAmf * we correctly throw an error and can actch it. * Yes this leaks memory. */ TEST(dCommonTests, AMFDeserializeUnimplementedValuesTest) { - std::vector unimplementedValues = { - AMFValueType::AMFXMLDoc, - AMFValueType::AMFDate, - AMFValueType::AMFObject, - AMFValueType::AMFXML, - AMFValueType::AMFByteArray, - AMFValueType::AMFVectorInt, - AMFValueType::AMFVectorUInt, - AMFValueType::AMFVectorDouble, - AMFValueType::AMFVectorObject, - AMFValueType::AMFDictionary + std::vector unimplementedValues = { + eAmf::XMLDoc, + eAmf::Date, + eAmf::Object, + eAmf::XML, + eAmf::ByteArray, + eAmf::VectorInt, + eAmf::VectorUInt, + eAmf::VectorDouble, + eAmf::VectorObject, + eAmf::Dictionary }; // Run unimplemented tests to check that errors are thrown if // unimplemented AMF values are attempted to be parsed. @@ -202,16 +205,16 @@ TEST(dCommonTests, AMFDeserializeUnimplementedValuesTest) { fileStream.close(); - for (auto amfValueType : unimplementedValues) { + for (auto value : unimplementedValues) { RakNet::BitStream testBitStream; for (auto element : baseBitStream) { testBitStream.Write(element); } - testBitStream.Write(amfValueType); + testBitStream.Write(value); bool caughtException = false; try { ReadFromBitStream(&testBitStream); - } catch (AMFValueType unimplementedValueType) { + } catch (eAmf unimplementedValueType) { caughtException = true; } @@ -235,116 +238,116 @@ TEST(dCommonTests, AMFDeserializeLivePacketTest) { testFileStream.close(); - auto resultFromFn = ReadFromBitStream(&testBitStream); + std::unique_ptr resultFromFn(ReadFromBitStream(&testBitStream)); auto result = static_cast(resultFromFn.get()); // Test the outermost array - ASSERT_EQ(result->FindValue("BehaviorID")->GetStringValue(), "10447"); - ASSERT_EQ(result->FindValue("objectID")->GetStringValue(), "288300744895913279"); + ASSERT_EQ(result->Get("BehaviorID")->GetValue(), "10447"); + ASSERT_EQ(result->Get("objectID")->GetValue(), "288300744895913279"); // Test the execution state array - auto executionState = result->FindValue("executionState"); + auto executionState = result->GetArray("executionState"); ASSERT_NE(executionState, nullptr); - auto strips = executionState->FindValue("strips")->GetDenseArray(); + auto strips = executionState->GetArray("strips")->GetDense(); ASSERT_EQ(strips.size(), 1); auto stripsPosition0 = dynamic_cast(strips[0]); - auto actionIndex = stripsPosition0->FindValue("actionIndex"); + auto actionIndex = stripsPosition0->Get("actionIndex"); - ASSERT_EQ(actionIndex->GetDoubleValue(), 0.0f); + ASSERT_EQ(actionIndex->GetValue(), 0.0f); - auto stripIdExecution = stripsPosition0->FindValue("id"); + auto stripIdExecution = stripsPosition0->Get("id"); - ASSERT_EQ(stripIdExecution->GetDoubleValue(), 0.0f); + ASSERT_EQ(stripIdExecution->GetValue(), 0.0f); - auto stateIDExecution = executionState->FindValue("stateID"); + auto stateIdExecution = executionState->Get("stateID"); - ASSERT_EQ(stateIDExecution->GetDoubleValue(), 0.0f); + ASSERT_EQ(stateIdExecution->GetValue(), 0.0f); - auto states = result->FindValue("states")->GetDenseArray(); + auto states = result->GetArray("states")->GetDense(); ASSERT_EQ(states.size(), 1); auto firstState = dynamic_cast(states[0]); - auto stateID = firstState->FindValue("id"); + auto stateID = firstState->Get("id"); - ASSERT_EQ(stateID->GetDoubleValue(), 0.0f); + ASSERT_EQ(stateID->GetValue(), 0.0f); - auto stripsInState = firstState->FindValue("strips")->GetDenseArray(); + auto stripsInState = firstState->GetArray("strips")->GetDense(); ASSERT_EQ(stripsInState.size(), 1); auto firstStrip = dynamic_cast(stripsInState[0]); - auto actionsInFirstStrip = firstStrip->FindValue("actions")->GetDenseArray(); + auto actionsInFirstStrip = firstStrip->GetArray("actions")->GetDense(); ASSERT_EQ(actionsInFirstStrip.size(), 3); - auto actionID = firstStrip->FindValue("id"); + auto actionID = firstStrip->Get("id"); - ASSERT_EQ(actionID->GetDoubleValue(), 0.0f); + ASSERT_EQ(actionID->GetValue(), 0.0f); - auto uiArray = firstStrip->FindValue("ui"); + auto uiArray = firstStrip->GetArray("ui"); - auto xPos = uiArray->FindValue("x"); - auto yPos = uiArray->FindValue("y"); + auto xPos = uiArray->Get("x"); + auto yPos = uiArray->Get("y"); - ASSERT_EQ(xPos->GetDoubleValue(), 103.0f); - ASSERT_EQ(yPos->GetDoubleValue(), 82.0f); + ASSERT_EQ(xPos->GetValue(), 103.0f); + ASSERT_EQ(yPos->GetValue(), 82.0f); - auto stripId = firstStrip->FindValue("id"); + auto stripId = firstStrip->Get("id"); - ASSERT_EQ(stripId->GetDoubleValue(), 0.0f); + ASSERT_EQ(stripId->GetValue(), 0.0f); auto firstAction = dynamic_cast(actionsInFirstStrip[0]); - auto firstType = firstAction->FindValue("Type"); + auto firstType = firstAction->Get("Type"); - ASSERT_EQ(firstType->GetStringValue(), "OnInteract"); + ASSERT_EQ(firstType->GetValue(), "OnInteract"); - auto firstCallback = firstAction->FindValue("__callbackID__"); + auto firstCallback = firstAction->Get("__callbackID__"); - ASSERT_EQ(firstCallback->GetStringValue(), ""); + ASSERT_EQ(firstCallback->GetValue(), ""); auto secondAction = dynamic_cast(actionsInFirstStrip[1]); - auto secondType = secondAction->FindValue("Type"); + auto secondType = secondAction->Get("Type"); - ASSERT_EQ(secondType->GetStringValue(), "FlyUp"); + ASSERT_EQ(secondType->GetValue(), "FlyUp"); - auto secondCallback = secondAction->FindValue("__callbackID__"); + auto secondCallback = secondAction->Get("__callbackID__"); - ASSERT_EQ(secondCallback->GetStringValue(), ""); + ASSERT_EQ(secondCallback->GetValue(), ""); - auto secondDistance = secondAction->FindValue("Distance"); + auto secondDistance = secondAction->Get("Distance"); - ASSERT_EQ(secondDistance->GetDoubleValue(), 25.0f); + ASSERT_EQ(secondDistance->GetValue(), 25.0f); auto thirdAction = dynamic_cast(actionsInFirstStrip[2]); - auto thirdType = thirdAction->FindValue("Type"); + auto thirdType = thirdAction->Get("Type"); - ASSERT_EQ(thirdType->GetStringValue(), "FlyDown"); + ASSERT_EQ(thirdType->GetValue(), "FlyDown"); - auto thirdCallback = thirdAction->FindValue("__callbackID__"); + auto thirdCallback = thirdAction->Get("__callbackID__"); - ASSERT_EQ(thirdCallback->GetStringValue(), ""); + ASSERT_EQ(thirdCallback->GetValue(), ""); - auto thirdDistance = thirdAction->FindValue("Distance"); + auto thirdDistance = thirdAction->Get("Distance"); - ASSERT_EQ(thirdDistance->GetDoubleValue(), 25.0f); + ASSERT_EQ(thirdDistance->GetValue(), 25.0f); } /** * @brief Tests that having no BitStream returns a nullptr. */ TEST(dCommonTests, AMFDeserializeNullTest) { - auto result = ReadFromBitStream(nullptr); + std::unique_ptr result(ReadFromBitStream(nullptr)); ASSERT_EQ(result.get(), nullptr); } @@ -361,25 +364,25 @@ TEST(dCommonTests, AMFBadConversionTest) { testFileStream.close(); - auto resultFromFn = ReadFromBitStream(&testBitStream); + std::unique_ptr resultFromFn(ReadFromBitStream(&testBitStream)); auto result = static_cast(resultFromFn.get()); // Actually a string value. - ASSERT_EQ(result->FindValue("BehaviorID"), nullptr); + ASSERT_EQ(result->Get("BehaviorID"), nullptr); // Does not exist in the associative portion - ASSERT_EQ(result->FindValue("DOES_NOT_EXIST"), nullptr); + ASSERT_EQ(result->Get("DOES_NOT_EXIST"), nullptr); - result->PushBackValue(new AMFTrueValue()); + result->Push(true); // Exists and is correct type - ASSERT_NE(result->GetValueAt(0), nullptr); + ASSERT_NE(result->Get(0), nullptr); // Value exists but is wrong typing - ASSERT_EQ(result->GetValueAt(0), nullptr); + ASSERT_EQ(result->Get(0), nullptr); // Value is out of bounds - ASSERT_EQ(result->GetValueAt(1), nullptr); + ASSERT_EQ(result->Get(1), nullptr); } /** diff --git a/tests/dCommonTests/Amf3Tests.cpp b/tests/dCommonTests/Amf3Tests.cpp new file mode 100644 index 00000000..a51fe4ba --- /dev/null +++ b/tests/dCommonTests/Amf3Tests.cpp @@ -0,0 +1,116 @@ +#include + +#include + +#include "Amf3.h" + +TEST(dCommonTests, AMF3AssociativeArrayTest) { + + AMFArrayValue array; + array.Insert("true", true); + array.Insert("false", false); + + // test associative can insert values + ASSERT_EQ(array.GetAssociative().size(), 2); + ASSERT_EQ(array.Get("true")->GetValueType(), eAmf::True); + ASSERT_EQ(array.Get("false")->GetValueType(), eAmf::False); + + // Test associative can remove values + array.Remove("true"); + ASSERT_EQ(array.GetAssociative().size(), 1); + ASSERT_EQ(array.Get("true"), nullptr); + ASSERT_EQ(array.Get("false")->GetValueType(), eAmf::False); + + array.Remove("false"); + ASSERT_EQ(array.GetAssociative().size(), 0); + ASSERT_EQ(array.Get("true"), nullptr); + ASSERT_EQ(array.Get("false"), nullptr); + + // Test that multiple of the same key respect only the first element of that key + array.Insert("true", true); + array.Insert("true", false); + ASSERT_EQ(array.GetAssociative().size(), 1); + ASSERT_EQ(array.Get("true")->GetValueType(), eAmf::True); + array.Remove("true"); + + // Now test the dense portion + // Get some out of bounds values and cast to incorrect template types + array.Push(true); + array.Push(false); + + ASSERT_EQ(array.GetDense().size(), 2); + ASSERT_EQ(array.Get(0)->GetValueType(), eAmf::True); + ASSERT_EQ(array.Get(0), nullptr); + ASSERT_EQ(array.Get(1)->GetValueType(), eAmf::False); + ASSERT_EQ(array.Get(155), nullptr); + + array.Pop(); + + ASSERT_EQ(array.GetDense().size(), 1); + ASSERT_EQ(array.Get(0)->GetValueType(), eAmf::True); + ASSERT_EQ(array.Get(0), nullptr); + ASSERT_EQ(array.Get(1), nullptr); + + array.Pop(); + + ASSERT_EQ(array.GetDense().size(), 0); + ASSERT_EQ(array.Get(0), nullptr); + ASSERT_EQ(array.Get(0), nullptr); + ASSERT_EQ(array.Get(1), nullptr); +} + +TEST(dCommonTests, AMF3InsertionAssociativeTest) { + AMFArrayValue array; + array.Insert("CString", "string"); + array.Insert("String", std::string("string")); + array.Insert("False", false); + array.Insert("True", true); + array.Insert("Integer", 42U); + array.Insert("Double", 42.0); + array.InsertArray("Array"); + array.Insert>("Undefined", {}); + array.Insert("Null", nullptr); + + std::cout << "test" << std::endl; + ASSERT_EQ(array.Get("CString")->GetValueType(), eAmf::String); + std::cout << "test" << std::endl; + ASSERT_EQ(array.Get("String")->GetValueType(), eAmf::String); + std::cout << "test" << std::endl; + ASSERT_EQ(array.Get("False")->GetValueType(), eAmf::False); + std::cout << "test" << std::endl; + ASSERT_EQ(array.Get("True")->GetValueType(), eAmf::True); + std::cout << "test" << std::endl; + ASSERT_EQ(array.Get("Integer")->GetValueType(), eAmf::Integer); + std::cout << "test" << std::endl; + ASSERT_EQ(array.Get("Double")->GetValueType(), eAmf::Double); + std::cout << "test" << std::endl; + ASSERT_EQ(array.GetArray("Array")->GetValueType(), eAmf::Array); + std::cout << "test" << std::endl; + ASSERT_EQ(array.Get("Null")->GetValueType(), eAmf::Null); + std::cout << "test" << std::endl; + ASSERT_EQ(array.Get>("Undefined")->GetValueType(), eAmf::Undefined); + std::cout << "test" << std::endl; +} + +TEST(dCommonTests, AMF3InsertionDenseTest) { + AMFArrayValue array; + array.Push("string"); + array.Push("CString"); + array.Push(false); + array.Push(true); + array.Push(42U); + array.Push(42.0); + array.PushArray(); + array.Push(nullptr); + array.Push>({}); + + ASSERT_EQ(array.Get(0)->GetValueType(), eAmf::String); + ASSERT_EQ(array.Get(1)->GetValueType(), eAmf::String); + ASSERT_EQ(array.Get(2)->GetValueType(), eAmf::False); + ASSERT_EQ(array.Get(3)->GetValueType(), eAmf::True); + ASSERT_EQ(array.Get(4)->GetValueType(), eAmf::Integer); + ASSERT_EQ(array.Get(5)->GetValueType(), eAmf::Double); + ASSERT_EQ(array.GetArray(6)->GetValueType(), eAmf::Array); + ASSERT_EQ(array.Get(7)->GetValueType(), eAmf::Null); + ASSERT_EQ(array.Get>(8)->GetValueType(), eAmf::Undefined); +} diff --git a/tests/dCommonTests/CMakeLists.txt b/tests/dCommonTests/CMakeLists.txt index dd282cb5..a345863d 100644 --- a/tests/dCommonTests/CMakeLists.txt +++ b/tests/dCommonTests/CMakeLists.txt @@ -1,5 +1,7 @@ set(DCOMMONTEST_SOURCES "AMFDeserializeTests.cpp" + "Amf3Tests.cpp" + "HeaderSkipTest.cpp" "TestLDFFormat.cpp" "TestNiPoint3.cpp" "TestEncoding.cpp" diff --git a/tests/dCommonTests/HeaderSkipTest.cpp b/tests/dCommonTests/HeaderSkipTest.cpp new file mode 100644 index 00000000..a8f78078 --- /dev/null +++ b/tests/dCommonTests/HeaderSkipTest.cpp @@ -0,0 +1,37 @@ +#include + +#include "dCommonDependencies.h" +#include "dCommonVars.h" +#include "BitStream.h" + +#define PacketUniquePtr std::unique_ptr + +TEST(dCommonTests, HeaderSkipExcessTest) { + PacketUniquePtr packet = std::make_unique(); + unsigned char headerAndData[] = { 0x53, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00 }; // positive + packet->data = headerAndData; + packet->length = sizeof(headerAndData); + CINSTREAM_SKIP_HEADER; + ASSERT_EQ(inStream.GetNumberOfUnreadBits(), 64); + ASSERT_EQ(inStream.GetNumberOfBitsAllocated(), 128); +} + +TEST(dCommonTests, HeaderSkipExactDataTest) { + PacketUniquePtr packet = std::make_unique(); + unsigned char header[] = { 0x53, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00 }; // positive + packet->data = header; + packet->length = sizeof(header); + CINSTREAM_SKIP_HEADER; + ASSERT_EQ(inStream.GetNumberOfUnreadBits(), 0); + ASSERT_EQ(inStream.GetNumberOfBitsAllocated(), 64); +} + +TEST(dCommonTests, HeaderSkipNotEnoughDataTest) { + PacketUniquePtr packet = std::make_unique(); + unsigned char notEnoughData[] = { 0x53, 0x02, 0x00, 0x07, 0x00, 0x00 }; // negative + packet->data = notEnoughData; + packet->length = sizeof(notEnoughData); + CINSTREAM_SKIP_HEADER; + ASSERT_EQ(inStream.GetNumberOfUnreadBits(), 0); + ASSERT_EQ(inStream.GetNumberOfBitsAllocated(), 48); +} diff --git a/tests/dGameTests/GameDependencies.cpp b/tests/dGameTests/GameDependencies.cpp index 7b0a8412..1765bd9b 100644 --- a/tests/dGameTests/GameDependencies.cpp +++ b/tests/dGameTests/GameDependencies.cpp @@ -1,13 +1,14 @@ #include "GameDependencies.h" namespace Game { - dLogger* logger; - dServer* server; - dZoneManager* zoneManager; - dChatFilter* chatFilter; - dConfig* config; + dLogger* logger = nullptr; + dServer* server = nullptr; + dZoneManager* zoneManager = nullptr; + dChatFilter* chatFilter = nullptr; + dConfig* config = nullptr; std::mt19937 randomEngine; - RakPeerInterface* chatServer; - AssetManager* assetManager; + RakPeerInterface* chatServer = nullptr; + AssetManager* assetManager = nullptr; SystemAddress chatSysAddr; + EntityManager* entityManager = nullptr; } diff --git a/tests/dGameTests/GameDependencies.h b/tests/dGameTests/GameDependencies.h index 353b53b8..95ef2f9f 100644 --- a/tests/dGameTests/GameDependencies.h +++ b/tests/dGameTests/GameDependencies.h @@ -32,11 +32,12 @@ protected: Game::logger = new dLogger("./testing.log", true, true); Game::server = new dServerMock(); Game::config = new dConfig("worldconfig.ini"); + Game::entityManager = new EntityManager(); } void TearDownDependencies() { if (Game::server) delete Game::server; - delete EntityManager::Instance(); + if (Game::entityManager) delete Game::entityManager; if (Game::logger) { Game::logger->Flush(); delete Game::logger; @@ -44,7 +45,7 @@ protected: if (Game::config) delete Game::config; } - EntityInfo info; + EntityInfo info{}; }; #endif //!__GAMEDEPENDENCIES__H__ diff --git a/tests/dGameTests/dGameMessagesTests/GameMessageTests.cpp b/tests/dGameTests/dGameMessagesTests/GameMessageTests.cpp index 631f0d2d..047f56d6 100644 --- a/tests/dGameTests/dGameMessagesTests/GameMessageTests.cpp +++ b/tests/dGameTests/dGameMessagesTests/GameMessageTests.cpp @@ -1,5 +1,5 @@ #include "Action.h" -#include "AMFFormat.h" +#include "Amf3.h" #include "AMFDeserialize.h" #include "GameMessages.h" #include "GameDependencies.h" @@ -40,8 +40,8 @@ protected: } AMFArrayValue* ReadArrayFromBitStream(RakNet::BitStream* inStream) { AMFDeserialize des; - AMFValue* readArray = des.Read(inStream); - EXPECT_EQ(readArray->GetValueType(), AMFValueType::AMFArray); + AMFBaseValue* readArray = des.Read(inStream); + EXPECT_EQ(readArray->GetValueType(), eAmf::Array); return static_cast(readArray); } }; diff --git a/thirdparty/CMakeMariaDBLists.txt b/thirdparty/CMakeMariaDBLists.txt index cb1e28e7..81b15a6f 100644 --- a/thirdparty/CMakeMariaDBLists.txt +++ b/thirdparty/CMakeMariaDBLists.txt @@ -10,30 +10,42 @@ if(WIN32 AND NOT MARIADB_BUILD_SOURCE) file(MAKE_DIRECTORY "${MARIADB_MSI_DIR}") file(MAKE_DIRECTORY "${MARIADB_CONNECTOR_DIR}") - if(NOT EXISTS "${MARIADB_MSI_DIR}/mariadb-connector-c-3.2.5-win64.msi" ) + # These values need to be updated whenever a new minor release replaces an old one + # Go to https://mariadb.com/downloads/connectors/ to find the up-to-date URL parts + set(MARIADB_CONNECTOR_C_VERSION "3.2.7") + set(MARIADB_CONNECTOR_C_BUCKET "2319651") + set(MARIADB_CONNECTOR_C_MD5 "f8636d733f1d093af9d4f22f3239f885") + set(MARIADB_CONNECTOR_CPP_VERSION "1.0.2") + set(MARIADB_CONNECTOR_CPP_BUCKET "2531525") + set(MARIADB_CONNECTOR_CPP_MD5 "3034bbd6ca00a0125345f9fd1a178401") + + set(MARIADB_CONNECTOR_C_MSI "mariadb-connector-c-${MARIADB_CONNECTOR_C_VERSION}-win64.msi") + set(MARIADB_CONNECTOR_CPP_MSI "mariadb-connector-cpp-${MARIADB_CONNECTOR_CPP_VERSION}-win64.msi") + + if(NOT EXISTS "${MARIADB_MSI_DIR}/${MARIADB_CONNECTOR_C_MSI}" ) message("Downloading mariadb connector/c") - file(DOWNLOAD https://dlm.mariadb.com/1936366/connectors/c/connector-c-3.2.5/mariadb-connector-c-3.2.5-win64.msi - "${MARIADB_MSI_DIR}/mariadb-connector-c-3.2.5-win64.msi" - EXPECTED_HASH MD5=09d418c290109068a5bea136dafca36b) + file(DOWNLOAD https://dlm.mariadb.com/${MARIADB_CONNECTOR_C_BUCKET}/Connectors/c/connector-c-${MARIADB_CONNECTOR_C_VERSION}/${MARIADB_CONNECTOR_C_MSI} + "${MARIADB_MSI_DIR}/${MARIADB_CONNECTOR_C_MSI}" + EXPECTED_HASH MD5=${MARIADB_CONNECTOR_C_MD5}) endif() - if(NOT EXISTS "${MARIADB_MSI_DIR}/mariadb-connector-cpp-1.0.1-win64.msi" ) + if(NOT EXISTS "${MARIADB_MSI_DIR}/${MARIADB_CONNECTOR_CPP_MSI}" ) message("Downloading mariadb connector/c++") - file(DOWNLOAD https://dlm.mariadb.com/1683453/connectors/cpp/connector-cpp-1.0.1/mariadb-connector-cpp-1.0.1-win64.msi - "${MARIADB_MSI_DIR}/mariadb-connector-cpp-1.0.1-win64.msi" - EXPECTED_HASH MD5=548e743fbf067d21d42b81d958bf4ed7) + file(DOWNLOAD https://dlm.mariadb.com/${MARIADB_CONNECTOR_CPP_BUCKET}/Connectors/cpp/connector-cpp-${MARIADB_CONNECTOR_CPP_VERSION}/${MARIADB_CONNECTOR_CPP_MSI} + "${MARIADB_MSI_DIR}/${MARIADB_CONNECTOR_CPP_MSI}" + EXPECTED_HASH MD5=${MARIADB_CONNECTOR_CPP_MD5}) endif() file(TO_NATIVE_PATH "${MARIADB_CONNECTOR_DIR}" MSIEXEC_TARGETDIR) # extract msi files without installing to users system if(NOT EXISTS "${MARIADB_C_CONNECTOR_DIR}") - file(TO_NATIVE_PATH "${MARIADB_MSI_DIR}/mariadb-connector-c-3.2.5-win64.msi" MSI_DIR) + file(TO_NATIVE_PATH "${MARIADB_MSI_DIR}/${MARIADB_CONNECTOR_C_MSI}" MSI_DIR) execute_process(COMMAND msiexec /a ${MSI_DIR} /qn TARGETDIR=${MSIEXEC_TARGETDIR}) endif() if(NOT EXISTS "${MARIADB_CPP_CONNECTOR_DIR}") - file(TO_NATIVE_PATH "${MARIADB_MSI_DIR}/mariadb-connector-cpp-1.0.1-win64.msi" MSI_DIR) + file(TO_NATIVE_PATH "${MARIADB_MSI_DIR}/${MARIADB_CONNECTOR_CPP_MSI}" MSI_DIR) execute_process(COMMAND msiexec /a ${MSI_DIR} /qn TARGETDIR=${MSIEXEC_TARGETDIR}) endif()