mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-12-30 16:10:56 -06:00
Compare commits
1 Commits
EmosewaMC-
...
EmosewaMC-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2ae58086ba |
@@ -19,7 +19,6 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # Export the compile commands for debuggi
|
||||
set(CMAKE_POLICY_DEFAULT_CMP0063 NEW) # Set CMAKE visibility policy to NEW on project and subprojects
|
||||
set(CMAKE_VISIBILITY_INLINES_HIDDEN ON) # Set C and C++ symbol visibility to hide inlined functions
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
|
||||
set(FETCHCONTENT_QUIET FALSE) # GLM takes a long time to clone, this will at least show _something_ while its downloading
|
||||
|
||||
# Read variables from file
|
||||
FILE(READ "${CMAKE_SOURCE_DIR}/CMakeVariables.txt" variables)
|
||||
@@ -307,7 +306,7 @@ add_subdirectory(dServer)
|
||||
add_subdirectory(dWeb)
|
||||
|
||||
# Create a list of common libraries shared between all binaries
|
||||
set(COMMON_LIBRARIES glm::glm "dCommon" "dDatabase" "dNet" "raknet" "magic_enum")
|
||||
set(COMMON_LIBRARIES "dCommon" "dDatabase" "dNet" "raknet" "magic_enum")
|
||||
|
||||
# Add platform specific common libraries
|
||||
if(UNIX)
|
||||
|
||||
@@ -187,8 +187,7 @@ Now that you are logged in, run the following commands.
|
||||
```bash
|
||||
# Creates a user for this computer which uses a password and grant said user all privileges.
|
||||
# Change mydarkflameuser to a custom username and password to a custom password.
|
||||
CREATE USER 'mydarkflameuser'@'localhost' IDENTIFIED BY 'password';
|
||||
GRANT ALL ON *.* TO 'mydarkflameuser'@'localhost' WITH GRANT OPTION;
|
||||
GRANT ALL ON *.* TO 'mydarkflameuser'@'localhost' IDENTIFIED BY 'password' WITH GRANT OPTION;
|
||||
FLUSH PRIVILEGES;
|
||||
|
||||
# Then create a database for Darkflame Universe to use.
|
||||
|
||||
@@ -6,8 +6,6 @@ FetchContent_Declare(
|
||||
googletest
|
||||
GIT_REPOSITORY https://github.com/google/googletest.git
|
||||
GIT_TAG release-1.12.1
|
||||
GIT_PROGRESS TRUE
|
||||
GIT_SHALLOW 1
|
||||
)
|
||||
|
||||
# For Windows: Prevent overriding the parent project's compiler/linker settings
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
//Auth includes:
|
||||
#include "AuthPackets.h"
|
||||
#include "ServiceType.h"
|
||||
#include "eConnectionType.h"
|
||||
#include "MessageType/Server.h"
|
||||
#include "MessageType/Auth.h"
|
||||
|
||||
@@ -92,7 +92,7 @@ int main(int argc, char** argv) {
|
||||
const auto externalIPString = Game::config->GetValue("external_ip");
|
||||
if (!externalIPString.empty()) ourIP = externalIPString;
|
||||
|
||||
Game::server = new dServer(ourIP, ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServiceType::AUTH, Game::config, &Game::lastSignal, masterPassword);
|
||||
Game::server = new dServer(ourIP, ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Auth, Game::config, &Game::lastSignal, masterPassword);
|
||||
|
||||
//Run it until server gets a kill message from Master:
|
||||
auto t = std::chrono::high_resolution_clock::now();
|
||||
@@ -167,11 +167,11 @@ void HandlePacket(Packet* packet) {
|
||||
if (packet->length < 4) return;
|
||||
|
||||
if (packet->data[0] == ID_USER_PACKET_ENUM) {
|
||||
if (static_cast<ServiceType>(packet->data[1]) == ServiceType::COMMON) {
|
||||
if (static_cast<eConnectionType>(packet->data[1]) == eConnectionType::SERVER) {
|
||||
if (static_cast<MessageType::Server>(packet->data[3]) == MessageType::Server::VERSION_CONFIRM) {
|
||||
AuthPackets::HandleHandshake(Game::server, packet);
|
||||
}
|
||||
} else if (static_cast<ServiceType>(packet->data[1]) == ServiceType::AUTH) {
|
||||
} else if (static_cast<eConnectionType>(packet->data[1]) == eConnectionType::AUTH) {
|
||||
if (static_cast<MessageType::Auth>(packet->data[3]) == MessageType::Auth::LOGIN_REQUEST) {
|
||||
AuthPackets::HandleLoginRequest(Game::server, packet);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
set(DCHATFILTER_SOURCES "dChatFilter.cpp")
|
||||
|
||||
add_library(dChatFilter STATIC ${DCHATFILTER_SOURCES})
|
||||
target_link_libraries(dChatFilter dDatabase glm::glm)
|
||||
target_link_libraries(dChatFilter dDatabase)
|
||||
|
||||
@@ -14,6 +14,6 @@ add_compile_definitions(ChatServer PRIVATE PROJECT_VERSION="\"${PROJECT_VERSION}
|
||||
add_library(dChatServer ${DCHATSERVER_SOURCES})
|
||||
target_include_directories(dChatServer PRIVATE "${PROJECT_SOURCE_DIR}/dServer" "${PROJECT_SOURCE_DIR}/dChatFilter")
|
||||
|
||||
target_link_libraries(dChatServer ${COMMON_LIBRARIES} dChatFilter glm::glm)
|
||||
target_link_libraries(dChatServer ${COMMON_LIBRARIES} dChatFilter)
|
||||
target_link_libraries(ChatServer ${COMMON_LIBRARIES} dChatFilter dChatServer dServer mongoose dWeb)
|
||||
|
||||
|
||||
@@ -13,11 +13,11 @@
|
||||
// The only thing not auto-handled is instance activities force joining the team on the server.
|
||||
|
||||
void WriteOutgoingReplyHeader(RakNet::BitStream& bitStream, const LWOOBJID& receivingPlayer, const MessageType::Client type) {
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
bitStream.Write(receivingPlayer);
|
||||
|
||||
//portion that will get routed:
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, type);
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, type);
|
||||
}
|
||||
|
||||
void ChatIgnoreList::GetIgnoreList(Packet* packet) {
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include "RakString.h"
|
||||
#include "dConfig.h"
|
||||
#include "eObjectBits.h"
|
||||
#include "ServiceType.h"
|
||||
#include "eConnectionType.h"
|
||||
#include "MessageType/Chat.h"
|
||||
#include "MessageType/Client.h"
|
||||
#include "MessageType/Game.h"
|
||||
@@ -61,11 +61,11 @@ void ChatPacketHandler::HandleFriendlistRequest(Packet* packet) {
|
||||
|
||||
//Now, we need to send the friendlist to the server they came from:
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
bitStream.Write(playerID);
|
||||
|
||||
//portion that will get routed:
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::GET_FRIENDS_LIST_RESPONSE);
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::GET_FRIENDS_LIST_RESPONSE);
|
||||
bitStream.Write<uint8_t>(0);
|
||||
bitStream.Write<uint16_t>(1); //Length of packet -- just writing one as it doesn't matter, client skips it.
|
||||
bitStream.Write<uint16_t>(player.friends.size());
|
||||
@@ -375,10 +375,10 @@ void ChatPacketHandler::HandleWho(Packet* packet) {
|
||||
bool online = player;
|
||||
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
bitStream.Write(request.requestor);
|
||||
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::WHO_RESPONSE);
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::WHO_RESPONSE);
|
||||
bitStream.Write<uint8_t>(online);
|
||||
bitStream.Write(player.zoneID.GetMapID());
|
||||
bitStream.Write(player.zoneID.GetInstanceID());
|
||||
@@ -398,10 +398,10 @@ void ChatPacketHandler::HandleShowAll(Packet* packet) {
|
||||
if (!sender) return;
|
||||
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
bitStream.Write(request.requestor);
|
||||
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::SHOW_ALL_RESPONSE);
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::SHOW_ALL_RESPONSE);
|
||||
bitStream.Write<uint8_t>(!request.displayZoneData && !request.displayIndividualPlayers);
|
||||
bitStream.Write(Game::playerContainer.GetPlayerCount());
|
||||
bitStream.Write(Game::playerContainer.GetSimCount());
|
||||
@@ -533,7 +533,7 @@ void ChatPacketHandler::OnAchievementNotify(RakNet::BitStream& bitstream, const
|
||||
LOG_DEBUG("Sending achievement notify to %s", notify.targetPlayerName.GetAsString().c_str());
|
||||
|
||||
RakNet::BitStream worldStream;
|
||||
BitStreamUtils::WriteHeader(worldStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
BitStreamUtils::WriteHeader(worldStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
worldStream.Write(friendData.playerID);
|
||||
notify.WriteHeader(worldStream);
|
||||
notify.Serialize(worldStream);
|
||||
@@ -544,10 +544,10 @@ void ChatPacketHandler::OnAchievementNotify(RakNet::BitStream& bitstream, const
|
||||
|
||||
void ChatPacketHandler::SendPrivateChatMessage(const PlayerData& sender, const PlayerData& receiver, const PlayerData& routeTo, const LUWString& message, const eChatChannel channel, const eChatMessageResponseCode responseCode) {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
bitStream.Write(routeTo.playerID);
|
||||
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::PRIVATE_CHAT_MESSAGE);
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::PRIVATE_CHAT_MESSAGE);
|
||||
bitStream.Write(sender.playerID);
|
||||
bitStream.Write(channel);
|
||||
bitStream.Write<uint32_t>(0); // not used
|
||||
@@ -579,11 +579,11 @@ void ChatPacketHandler::SendFriendUpdate(const PlayerData& friendData, const Pla
|
||||
[bool] - is FTP*/
|
||||
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
bitStream.Write(friendData.playerID);
|
||||
|
||||
//portion that will get routed:
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::UPDATE_FRIEND_NOTIFY);
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::UPDATE_FRIEND_NOTIFY);
|
||||
bitStream.Write<uint8_t>(notifyType);
|
||||
|
||||
std::string playerName = playerData.playerName.c_str();
|
||||
@@ -616,11 +616,11 @@ void ChatPacketHandler::SendFriendRequest(const PlayerData& receiver, const Play
|
||||
}
|
||||
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
bitStream.Write(receiver.playerID);
|
||||
|
||||
//portion that will get routed:
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::ADD_FRIEND_REQUEST);
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::ADD_FRIEND_REQUEST);
|
||||
bitStream.Write(LUWString(sender.playerName));
|
||||
bitStream.Write<uint8_t>(0); // This is a BFF flag however this is unused in live and does not have an implementation client side.
|
||||
|
||||
@@ -630,11 +630,11 @@ void ChatPacketHandler::SendFriendRequest(const PlayerData& receiver, const Play
|
||||
|
||||
void ChatPacketHandler::SendFriendResponse(const PlayerData& receiver, const PlayerData& sender, eAddFriendResponseType responseCode, uint8_t isBestFriendsAlready, uint8_t isBestFriendRequest) {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
bitStream.Write(receiver.playerID);
|
||||
|
||||
// Portion that will get routed:
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::ADD_FRIEND_RESPONSE);
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::ADD_FRIEND_RESPONSE);
|
||||
bitStream.Write(responseCode);
|
||||
// For all requests besides accepted, write a flag that says whether or not we are already best friends with the receiver.
|
||||
bitStream.Write<uint8_t>(responseCode != eAddFriendResponseType::ACCEPTED ? isBestFriendsAlready : sender.worldServerSysAddr != UNASSIGNED_SYSTEM_ADDRESS);
|
||||
@@ -653,11 +653,11 @@ void ChatPacketHandler::SendFriendResponse(const PlayerData& receiver, const Pla
|
||||
|
||||
void ChatPacketHandler::SendRemoveFriend(const PlayerData& receiver, std::string& personToRemove, bool isSuccessful) {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
bitStream.Write(receiver.playerID);
|
||||
|
||||
//portion that will get routed:
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::REMOVE_FRIEND_RESPONSE);
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::REMOVE_FRIEND_RESPONSE);
|
||||
bitStream.Write<uint8_t>(isSuccessful); //isOnline
|
||||
bitStream.Write(LUWString(personToRemove));
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include "Diagnostics.h"
|
||||
#include "AssetManager.h"
|
||||
#include "BinaryPathFinder.h"
|
||||
#include "ServiceType.h"
|
||||
#include "eConnectionType.h"
|
||||
#include "PlayerContainer.h"
|
||||
#include "ChatPacketHandler.h"
|
||||
#include "MessageType/Chat.h"
|
||||
@@ -123,7 +123,7 @@ int main(int argc, char** argv) {
|
||||
const auto externalIPString = Game::config->GetValue("external_ip");
|
||||
if (!externalIPString.empty()) ourIP = externalIPString;
|
||||
|
||||
Game::server = new dServer(ourIP, ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServiceType::CHAT, Game::config, &Game::lastSignal, masterPassword);
|
||||
Game::server = new dServer(ourIP, ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Chat, Game::config, &Game::lastSignal, masterPassword);
|
||||
|
||||
const bool dontGenerateDCF = GeneralUtils::TryParse<bool>(Game::config->GetValue("dont_generate_dcf")).value_or(false);
|
||||
Game::chatFilter = new dChatFilter(Game::assetManager->GetResPath().string() + "/chatplus_en_us", dontGenerateDCF);
|
||||
@@ -218,11 +218,11 @@ void HandlePacket(Packet* packet) {
|
||||
CINSTREAM;
|
||||
inStream.SetReadOffset(BYTES_TO_BITS(1));
|
||||
|
||||
ServiceType connection;
|
||||
inStream.Read(connection);
|
||||
if (connection != ServiceType::CHAT) return;
|
||||
|
||||
eConnectionType connection;
|
||||
MessageType::Chat chatMessageID;
|
||||
|
||||
inStream.Read(connection);
|
||||
if (connection != eConnectionType::CHAT) return;
|
||||
inStream.Read(chatMessageID);
|
||||
|
||||
// Our packing byte wasnt there? Probably a false packet
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include "GeneralUtils.h"
|
||||
#include "BitStreamUtils.h"
|
||||
#include "Database.h"
|
||||
#include "ServiceType.h"
|
||||
#include "eConnectionType.h"
|
||||
#include "ChatPackets.h"
|
||||
#include "dConfig.h"
|
||||
#include "MessageType/Chat.h"
|
||||
@@ -147,7 +147,7 @@ void PlayerContainer::MuteUpdate(Packet* packet) {
|
||||
|
||||
void PlayerContainer::BroadcastMuteUpdate(LWOOBJID player, time_t time) {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::GM_MUTE);
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::GM_MUTE);
|
||||
|
||||
bitStream.Write(player);
|
||||
bitStream.Write(time);
|
||||
|
||||
@@ -264,11 +264,11 @@ void TeamContainer::HandleTeamStatusRequest(Packet* packet) {
|
||||
|
||||
void TeamContainer::SendTeamInvite(const PlayerData& receiver, const PlayerData& sender) {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
bitStream.Write(receiver.playerID);
|
||||
|
||||
//portion that will get routed:
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::TEAM_INVITE);
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::TEAM_INVITE);
|
||||
|
||||
bitStream.Write(LUWString(sender.playerName.c_str()));
|
||||
bitStream.Write(sender.playerID);
|
||||
@@ -279,7 +279,7 @@ void TeamContainer::SendTeamInvite(const PlayerData& receiver, const PlayerData&
|
||||
|
||||
void TeamContainer::SendTeamInviteConfirm(const PlayerData& receiver, bool bLeaderIsFreeTrial, LWOOBJID i64LeaderID, LWOZONEID i64LeaderZoneID, uint8_t ucLootFlag, uint8_t ucNumOfOtherPlayers, uint8_t ucResponseCode, std::u16string wsLeaderName) {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
bitStream.Write(receiver.playerID);
|
||||
|
||||
//portion that will get routed:
|
||||
@@ -306,7 +306,7 @@ void TeamContainer::SendTeamInviteConfirm(const PlayerData& receiver, bool bLead
|
||||
|
||||
void TeamContainer::SendTeamStatus(const PlayerData& receiver, LWOOBJID i64LeaderID, LWOZONEID i64LeaderZoneID, uint8_t ucLootFlag, uint8_t ucNumOfOtherPlayers, std::u16string wsLeaderName) {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
bitStream.Write(receiver.playerID);
|
||||
|
||||
//portion that will get routed:
|
||||
@@ -331,7 +331,7 @@ void TeamContainer::SendTeamStatus(const PlayerData& receiver, LWOOBJID i64Leade
|
||||
|
||||
void TeamContainer::SendTeamSetLeader(const PlayerData& receiver, LWOOBJID i64PlayerID) {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
bitStream.Write(receiver.playerID);
|
||||
|
||||
//portion that will get routed:
|
||||
@@ -348,7 +348,7 @@ void TeamContainer::SendTeamSetLeader(const PlayerData& receiver, LWOOBJID i64Pl
|
||||
|
||||
void TeamContainer::SendTeamAddPlayer(const PlayerData& receiver, bool bIsFreeTrial, bool bLocal, bool bNoLootOnDeath, LWOOBJID i64PlayerID, std::u16string wsPlayerName, LWOZONEID zoneID) {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
bitStream.Write(receiver.playerID);
|
||||
|
||||
//portion that will get routed:
|
||||
@@ -377,7 +377,7 @@ void TeamContainer::SendTeamAddPlayer(const PlayerData& receiver, bool bIsFreeTr
|
||||
|
||||
void TeamContainer::SendTeamRemovePlayer(const PlayerData& receiver, bool bDisband, bool bIsKicked, bool bIsLeaving, bool bLocal, LWOOBJID i64LeaderID, LWOOBJID i64PlayerID, std::u16string wsPlayerName) {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
bitStream.Write(receiver.playerID);
|
||||
|
||||
//portion that will get routed:
|
||||
@@ -403,7 +403,7 @@ void TeamContainer::SendTeamRemovePlayer(const PlayerData& receiver, bool bDisba
|
||||
|
||||
void TeamContainer::SendTeamSetOffWorldFlag(const PlayerData& receiver, LWOOBJID i64PlayerID, LWOZONEID zoneID) {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
||||
bitStream.Write(receiver.playerID);
|
||||
|
||||
//portion that will get routed:
|
||||
@@ -652,7 +652,7 @@ void TeamContainer::TeamStatusUpdate(TeamData* team) {
|
||||
|
||||
void TeamContainer::UpdateTeamsOnWorld(TeamData* team, bool deleteTeam) {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::TEAM_GET_STATUS);
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::TEAM_GET_STATUS);
|
||||
|
||||
bitStream.Write(team->teamID);
|
||||
bitStream.Write(deleteTeam);
|
||||
|
||||
@@ -20,7 +20,6 @@ set(DCOMMON_SOURCES
|
||||
"TinyXmlUtils.cpp"
|
||||
"Sd0.cpp"
|
||||
"Lxfml.cpp"
|
||||
"LxfmlBugged.cpp"
|
||||
)
|
||||
|
||||
# Workaround for compiler bug where the optimized code could result in a memcpy of 0 bytes, even though that isnt possible.
|
||||
@@ -54,8 +53,6 @@ elseif (WIN32)
|
||||
zlib
|
||||
URL https://github.com/madler/zlib/archive/refs/tags/v1.2.11.zip
|
||||
URL_HASH MD5=9d6a627693163bbbf3f26403a3a0b0b1
|
||||
GIT_PROGRESS TRUE
|
||||
GIT_SHALLOW 1
|
||||
)
|
||||
|
||||
# Disable warning about no project version.
|
||||
@@ -76,6 +73,5 @@ else ()
|
||||
endif ()
|
||||
|
||||
target_link_libraries(dCommon
|
||||
PUBLIC glm::glm
|
||||
PRIVATE ZLIB::ZLIB bcrypt tinyxml2
|
||||
INTERFACE dDatabase)
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
// C++
|
||||
#include <charconv>
|
||||
#include <cstdint>
|
||||
#include <cmath>
|
||||
#include <ctime>
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
@@ -20,8 +19,6 @@
|
||||
#include "Game.h"
|
||||
#include "Logger.h"
|
||||
|
||||
#include <glm/ext/vector_float3.hpp>
|
||||
|
||||
enum eInventoryType : uint32_t;
|
||||
enum class eObjectBits : size_t;
|
||||
enum class eReplicaComponentType : uint32_t;
|
||||
@@ -148,7 +145,7 @@ namespace GeneralUtils {
|
||||
template <typename... Bases>
|
||||
struct overload : Bases... {
|
||||
using is_transparent = void;
|
||||
using Bases::operator() ...;
|
||||
using Bases::operator() ... ;
|
||||
};
|
||||
|
||||
struct char_pointer_hash {
|
||||
@@ -205,7 +202,7 @@ namespace GeneralUtils {
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
requires(!Numeric<T>)
|
||||
requires(!Numeric<T>)
|
||||
[[nodiscard]] std::optional<T> TryParse(std::string_view str);
|
||||
|
||||
#if !(__GNUC__ >= 11 || _MSC_VER >= 1924)
|
||||
@@ -224,7 +221,7 @@ namespace GeneralUtils {
|
||||
*/
|
||||
template <std::floating_point T>
|
||||
[[nodiscard]] std::optional<T> TryParse(std::string_view str) noexcept
|
||||
try {
|
||||
try {
|
||||
while (!str.empty() && std::isspace(str.front())) str.remove_prefix(1);
|
||||
|
||||
size_t parseNum;
|
||||
@@ -246,7 +243,7 @@ namespace GeneralUtils {
|
||||
* @returns An std::optional containing the desired NiPoint3 if it can be constructed from the string parameters
|
||||
*/
|
||||
template <typename T>
|
||||
[[nodiscard]] std::optional<T> TryParse(const std::string_view strX, const std::string_view strY, const std::string_view strZ) {
|
||||
[[nodiscard]] std::optional<NiPoint3> TryParse(const std::string_view strX, const std::string_view strY, const std::string_view strZ) {
|
||||
const auto x = TryParse<float>(strX);
|
||||
if (!x) return std::nullopt;
|
||||
|
||||
@@ -254,7 +251,7 @@ namespace GeneralUtils {
|
||||
if (!y) return std::nullopt;
|
||||
|
||||
const auto z = TryParse<float>(strZ);
|
||||
return z ? std::make_optional<T>(x.value(), y.value(), z.value()) : std::nullopt;
|
||||
return z ? std::make_optional<NiPoint3>(x.value(), y.value(), z.value()) : std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -263,8 +260,8 @@ namespace GeneralUtils {
|
||||
* @returns An std::optional containing the desired NiPoint3 if it can be constructed from the string parameters
|
||||
*/
|
||||
template <typename T>
|
||||
[[nodiscard]] std::optional<T> TryParse(const std::span<const std::string> str) {
|
||||
return (str.size() == 3) ? TryParse<T>(str[0], str[1], str[2]) : std::nullopt;
|
||||
[[nodiscard]] std::optional<NiPoint3> TryParse(const std::span<const std::string> str) {
|
||||
return (str.size() == 3) ? TryParse<NiPoint3>(str[0], str[1], str[2]) : std::nullopt;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@@ -302,12 +299,6 @@ namespace GeneralUtils {
|
||||
return T();
|
||||
}
|
||||
|
||||
template<typename Container>
|
||||
inline Container::value_type GetRandomElement(const Container& container) {
|
||||
DluAssert(!container.empty());
|
||||
return container[GenerateRandomNumber<typename Container::value_type>(0, container.size() - 1)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Casts the value of an enum entry to its underlying type
|
||||
* @param entry Enum entry to cast
|
||||
@@ -332,28 +323,4 @@ namespace GeneralUtils {
|
||||
|
||||
return GenerateRandomNumber<T>(std::numeric_limits<T>::min(), std::numeric_limits<T>::max());
|
||||
}
|
||||
|
||||
// https://www.quora.com/How-do-you-round-to-specific-increments-like-0-5-in-C
|
||||
// Rounds to the nearest floating point value specified.
|
||||
template <typename T, std::enable_if_t<std::is_floating_point_v<T>, int> = 0>
|
||||
T RountToNearestEven(const T value, const T modulus) {
|
||||
const auto modulo = std::fmod(value, modulus);
|
||||
const auto abs_modulo_2 = std::abs(modulo * 2);
|
||||
const auto abs_modulus = std::abs(modulus);
|
||||
|
||||
bool round_away_from_zero = false;
|
||||
if (abs_modulo_2 > abs_modulus) {
|
||||
round_away_from_zero = true;
|
||||
} else if (abs_modulo_2 == abs_modulus) {
|
||||
const auto trunc_quot = std::floor(std::abs(value / modulus));
|
||||
const auto odd = std::fmod(trunc_quot, T{ 2 }) != 0;
|
||||
round_away_from_zero = odd;
|
||||
}
|
||||
|
||||
if (round_away_from_zero) {
|
||||
return value + (std::copysign(modulus, value) - modulo);
|
||||
} else {
|
||||
return value - modulo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#include <ranges>
|
||||
|
||||
Lxfml::Result Lxfml::NormalizePosition(const std::string_view data, const NiPoint3& curPosition) {
|
||||
Lxfml::Result Lxfml::NormalizePosition(const std::string_view data) {
|
||||
Result toReturn;
|
||||
tinyxml2::XMLDocument doc;
|
||||
const auto err = doc.Parse(data.data());
|
||||
@@ -27,7 +27,7 @@ Lxfml::Result Lxfml::NormalizePosition(const std::string_view data, const NiPoin
|
||||
// First get all the positions of bricks
|
||||
for (const auto& brick : lxfml["Bricks"]) {
|
||||
const auto* part = brick.FirstChildElement("Part");
|
||||
while (part) {
|
||||
if (part) {
|
||||
const auto* bone = part->FirstChildElement("Bone");
|
||||
if (bone) {
|
||||
auto* transformation = bone->Attribute("transformation");
|
||||
@@ -36,7 +36,6 @@ Lxfml::Result Lxfml::NormalizePosition(const std::string_view data, const NiPoin
|
||||
if (refID) transformations[refID] = transformation;
|
||||
}
|
||||
}
|
||||
part = part->NextSiblingElement("Part");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,42 +43,29 @@ Lxfml::Result Lxfml::NormalizePosition(const std::string_view data, const NiPoin
|
||||
NiPoint3 lowest{ 10'000.0f, 10'000.0f, 10'000.0f };
|
||||
NiPoint3 highest{ -10'000.0f, -10'000.0f, -10'000.0f };
|
||||
|
||||
NiPoint3 delta = NiPoint3Constant::ZERO;
|
||||
if (curPosition == NiPoint3Constant::ZERO) {
|
||||
// Calculate the lowest and highest points on the entire model
|
||||
for (const auto& transformation : transformations | std::views::values) {
|
||||
auto split = GeneralUtils::SplitString(transformation, ',');
|
||||
if (split.size() < 12) {
|
||||
LOG("Not enough in the split?");
|
||||
continue;
|
||||
}
|
||||
|
||||
auto x = GeneralUtils::TryParse<float>(split[9]).value();
|
||||
auto y = GeneralUtils::TryParse<float>(split[10]).value();
|
||||
auto z = GeneralUtils::TryParse<float>(split[11]).value();
|
||||
if (x < lowest.x) lowest.x = x;
|
||||
if (y < lowest.y) lowest.y = y;
|
||||
if (z < lowest.z) lowest.z = z;
|
||||
|
||||
if (highest.x < x) highest.x = x;
|
||||
if (highest.y < y) highest.y = y;
|
||||
if (highest.z < z) highest.z = z;
|
||||
// Calculate the lowest and highest points on the entire model
|
||||
for (const auto& transformation : transformations | std::views::values) {
|
||||
auto split = GeneralUtils::SplitString(transformation, ',');
|
||||
if (split.size() < 12) {
|
||||
LOG("Not enough in the split?");
|
||||
continue;
|
||||
}
|
||||
|
||||
delta = (highest - lowest) / 2.0f;
|
||||
} else {
|
||||
lowest = curPosition;
|
||||
highest = curPosition;
|
||||
delta = NiPoint3Constant::ZERO;
|
||||
auto x = GeneralUtils::TryParse<float>(split[9]).value();
|
||||
auto y = GeneralUtils::TryParse<float>(split[10]).value();
|
||||
auto z = GeneralUtils::TryParse<float>(split[11]).value();
|
||||
if (x < lowest.x) lowest.x = x;
|
||||
if (y < lowest.y) lowest.y = y;
|
||||
if (z < lowest.z) lowest.z = z;
|
||||
|
||||
if (highest.x < x) highest.x = x;
|
||||
if (highest.y < y) highest.y = y;
|
||||
if (highest.z < z) highest.z = z;
|
||||
}
|
||||
|
||||
auto delta = (highest - lowest) / 2.0f;
|
||||
auto newRootPos = lowest + delta;
|
||||
|
||||
// Need to snap this chosen position to the nearest valid spot
|
||||
// on the LEGO grid
|
||||
newRootPos.x = GeneralUtils::RountToNearestEven(newRootPos.x, 0.8f);
|
||||
newRootPos.z = GeneralUtils::RountToNearestEven(newRootPos.z, 0.8f);
|
||||
|
||||
// Clamp the Y to the lowest point on the model
|
||||
newRootPos.y = lowest.y;
|
||||
|
||||
@@ -91,9 +77,9 @@ Lxfml::Result Lxfml::NormalizePosition(const std::string_view data, const NiPoin
|
||||
continue;
|
||||
}
|
||||
|
||||
auto x = GeneralUtils::TryParse<float>(split[9]).value() - newRootPos.x + curPosition.x;
|
||||
auto y = GeneralUtils::TryParse<float>(split[10]).value() - newRootPos.y + curPosition.y;
|
||||
auto z = GeneralUtils::TryParse<float>(split[11]).value() - newRootPos.z + curPosition.z;
|
||||
auto x = GeneralUtils::TryParse<float>(split[9]).value() - newRootPos.x;
|
||||
auto y = GeneralUtils::TryParse<float>(split[10]).value() - newRootPos.y;
|
||||
auto z = GeneralUtils::TryParse<float>(split[11]).value() - newRootPos.z;
|
||||
std::stringstream stream;
|
||||
for (int i = 0; i < 9; i++) {
|
||||
stream << split[i];
|
||||
@@ -106,7 +92,7 @@ Lxfml::Result Lxfml::NormalizePosition(const std::string_view data, const NiPoin
|
||||
// Finally write the new transformation back into the lxfml
|
||||
for (auto& brick : lxfml["Bricks"]) {
|
||||
auto* part = brick.FirstChildElement("Part");
|
||||
while (part) {
|
||||
if (part) {
|
||||
auto* bone = part->FirstChildElement("Bone");
|
||||
if (bone) {
|
||||
auto* transformation = bone->Attribute("transformation");
|
||||
@@ -117,7 +103,6 @@ Lxfml::Result Lxfml::NormalizePosition(const std::string_view data, const NiPoin
|
||||
}
|
||||
}
|
||||
}
|
||||
part = part->NextSiblingElement("Part");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,11 +17,7 @@ namespace Lxfml {
|
||||
|
||||
// Normalizes a LXFML model to be positioned relative to its local 0, 0, 0 rather than a game worlds 0, 0, 0.
|
||||
// Returns a struct of its new center and the updated LXFML containing these edits.
|
||||
[[nodiscard]] Result NormalizePosition(const std::string_view data, const NiPoint3& curPosition = NiPoint3Constant::ZERO);
|
||||
|
||||
// these are only for the migrations due to a bug in one of the implementations.
|
||||
[[nodiscard]] Result NormalizePositionOnlyFirstPart(const std::string_view data);
|
||||
[[nodiscard]] Result NormalizePositionAfterFirstPart(const std::string_view data, const NiPoint3& position);
|
||||
[[nodiscard]] Result NormalizePosition(const std::string_view data);
|
||||
};
|
||||
|
||||
#endif //!LXFML_H
|
||||
|
||||
@@ -1,210 +0,0 @@
|
||||
#include "Lxfml.h"
|
||||
|
||||
#include "GeneralUtils.h"
|
||||
#include "StringifiedEnum.h"
|
||||
#include "TinyXmlUtils.h"
|
||||
|
||||
#include <ranges>
|
||||
|
||||
// this file should not be touched
|
||||
|
||||
Lxfml::Result Lxfml::NormalizePositionOnlyFirstPart(const std::string_view data) {
|
||||
Result toReturn;
|
||||
tinyxml2::XMLDocument doc;
|
||||
const auto err = doc.Parse(data.data());
|
||||
if (err != tinyxml2::XML_SUCCESS) {
|
||||
LOG("Failed to parse xml %s.", StringifiedEnum::ToString(err).data());
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
TinyXmlUtils::DocumentReader reader(doc);
|
||||
std::map<std::string/* refID */, std::string> transformations;
|
||||
|
||||
auto lxfml = reader["LXFML"];
|
||||
if (!lxfml) {
|
||||
LOG("Failed to find LXFML element.");
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
// First get all the positions of bricks
|
||||
for (const auto& brick : lxfml["Bricks"]) {
|
||||
const auto* part = brick.FirstChildElement("Part");
|
||||
if (part) {
|
||||
const auto* bone = part->FirstChildElement("Bone");
|
||||
if (bone) {
|
||||
auto* transformation = bone->Attribute("transformation");
|
||||
if (transformation) {
|
||||
auto* refID = bone->Attribute("refID");
|
||||
if (refID) transformations[refID] = transformation;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// These points are well out of bounds for an actual player
|
||||
NiPoint3 lowest{ 10'000.0f, 10'000.0f, 10'000.0f };
|
||||
NiPoint3 highest{ -10'000.0f, -10'000.0f, -10'000.0f };
|
||||
|
||||
// Calculate the lowest and highest points on the entire model
|
||||
for (const auto& transformation : transformations | std::views::values) {
|
||||
auto split = GeneralUtils::SplitString(transformation, ',');
|
||||
if (split.size() < 12) {
|
||||
LOG("Not enough in the split?");
|
||||
continue;
|
||||
}
|
||||
|
||||
auto x = GeneralUtils::TryParse<float>(split[9]).value();
|
||||
auto y = GeneralUtils::TryParse<float>(split[10]).value();
|
||||
auto z = GeneralUtils::TryParse<float>(split[11]).value();
|
||||
if (x < lowest.x) lowest.x = x;
|
||||
if (y < lowest.y) lowest.y = y;
|
||||
if (z < lowest.z) lowest.z = z;
|
||||
|
||||
if (highest.x < x) highest.x = x;
|
||||
if (highest.y < y) highest.y = y;
|
||||
if (highest.z < z) highest.z = z;
|
||||
}
|
||||
|
||||
auto delta = (highest - lowest) / 2.0f;
|
||||
auto newRootPos = lowest + delta;
|
||||
|
||||
// Clamp the Y to the lowest point on the model
|
||||
newRootPos.y = lowest.y;
|
||||
|
||||
// Adjust all positions to account for the new origin
|
||||
for (auto& transformation : transformations | std::views::values) {
|
||||
auto split = GeneralUtils::SplitString(transformation, ',');
|
||||
if (split.size() < 12) {
|
||||
LOG("Not enough in the split?");
|
||||
continue;
|
||||
}
|
||||
|
||||
auto x = GeneralUtils::TryParse<float>(split[9]).value() - newRootPos.x;
|
||||
auto y = GeneralUtils::TryParse<float>(split[10]).value() - newRootPos.y;
|
||||
auto z = GeneralUtils::TryParse<float>(split[11]).value() - newRootPos.z;
|
||||
std::stringstream stream;
|
||||
for (int i = 0; i < 9; i++) {
|
||||
stream << split[i];
|
||||
stream << ',';
|
||||
}
|
||||
stream << x << ',' << y << ',' << z;
|
||||
transformation = stream.str();
|
||||
}
|
||||
|
||||
// Finally write the new transformation back into the lxfml
|
||||
for (auto& brick : lxfml["Bricks"]) {
|
||||
auto* part = brick.FirstChildElement("Part");
|
||||
if (part) {
|
||||
auto* bone = part->FirstChildElement("Bone");
|
||||
if (bone) {
|
||||
auto* transformation = bone->Attribute("transformation");
|
||||
if (transformation) {
|
||||
auto* refID = bone->Attribute("refID");
|
||||
if (refID) {
|
||||
bone->SetAttribute("transformation", transformations[refID].c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tinyxml2::XMLPrinter printer;
|
||||
doc.Print(&printer);
|
||||
|
||||
toReturn.lxfml = printer.CStr();
|
||||
toReturn.center = newRootPos;
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
Lxfml::Result Lxfml::NormalizePositionAfterFirstPart(const std::string_view data, const NiPoint3& position) {
|
||||
Result toReturn;
|
||||
tinyxml2::XMLDocument doc;
|
||||
const auto err = doc.Parse(data.data());
|
||||
if (err != tinyxml2::XML_SUCCESS) {
|
||||
LOG("Failed to parse xml %s.", StringifiedEnum::ToString(err).data());
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
TinyXmlUtils::DocumentReader reader(doc);
|
||||
std::map<std::string/* refID */, std::string> transformations;
|
||||
|
||||
auto lxfml = reader["LXFML"];
|
||||
if (!lxfml) {
|
||||
LOG("Failed to find LXFML element.");
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
// First get all the positions of bricks
|
||||
for (const auto& brick : lxfml["Bricks"]) {
|
||||
const auto* part = brick.FirstChildElement("Part");
|
||||
bool firstPart = true;
|
||||
while (part) {
|
||||
if (firstPart) {
|
||||
firstPart = false;
|
||||
} else {
|
||||
LOG("Found extra bricks");
|
||||
const auto* bone = part->FirstChildElement("Bone");
|
||||
if (bone) {
|
||||
auto* transformation = bone->Attribute("transformation");
|
||||
if (transformation) {
|
||||
auto* refID = bone->Attribute("refID");
|
||||
if (refID) transformations[refID] = transformation;
|
||||
}
|
||||
}
|
||||
}
|
||||
part = part->NextSiblingElement("Part");
|
||||
}
|
||||
}
|
||||
|
||||
auto newRootPos = position;
|
||||
|
||||
// Adjust all positions to account for the new origin
|
||||
for (auto& transformation : transformations | std::views::values) {
|
||||
auto split = GeneralUtils::SplitString(transformation, ',');
|
||||
if (split.size() < 12) {
|
||||
LOG("Not enough in the split?");
|
||||
continue;
|
||||
}
|
||||
|
||||
auto x = GeneralUtils::TryParse<float>(split[9]).value() - newRootPos.x;
|
||||
auto y = GeneralUtils::TryParse<float>(split[10]).value() - newRootPos.y;
|
||||
auto z = GeneralUtils::TryParse<float>(split[11]).value() - newRootPos.z;
|
||||
std::stringstream stream;
|
||||
for (int i = 0; i < 9; i++) {
|
||||
stream << split[i];
|
||||
stream << ',';
|
||||
}
|
||||
stream << x << ',' << y << ',' << z;
|
||||
transformation = stream.str();
|
||||
}
|
||||
|
||||
// Finally write the new transformation back into the lxfml
|
||||
for (auto& brick : lxfml["Bricks"]) {
|
||||
auto* part = brick.FirstChildElement("Part");
|
||||
bool firstPart = true;
|
||||
while (part) {
|
||||
if (firstPart) {
|
||||
firstPart = false;
|
||||
} else {
|
||||
auto* bone = part->FirstChildElement("Bone");
|
||||
if (bone) {
|
||||
auto* transformation = bone->Attribute("transformation");
|
||||
if (transformation) {
|
||||
auto* refID = bone->Attribute("refID");
|
||||
if (refID) {
|
||||
bone->SetAttribute("transformation", transformations[refID].c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
part = part->NextSiblingElement("Part");
|
||||
}
|
||||
}
|
||||
|
||||
tinyxml2::XMLPrinter printer;
|
||||
doc.Print(&printer);
|
||||
|
||||
toReturn.lxfml = printer.CStr();
|
||||
toReturn.center = newRootPos;
|
||||
return toReturn;
|
||||
}
|
||||
@@ -6,14 +6,10 @@
|
||||
\brief Defines a point in space in XYZ coordinates
|
||||
*/
|
||||
|
||||
|
||||
class NiPoint3;
|
||||
class NiQuaternion;
|
||||
typedef NiPoint3 Vector3; //!< The Vector3 class is technically the NiPoint3 class, but typedef'd for clarity in some cases
|
||||
|
||||
#include <glm/ext/vector_float3.hpp>
|
||||
|
||||
#include "NiQuaternion.h"
|
||||
|
||||
//! A custom class the defines a point in space
|
||||
class NiPoint3 {
|
||||
public:
|
||||
@@ -25,12 +21,6 @@ public:
|
||||
//! Initializer
|
||||
constexpr NiPoint3() = default;
|
||||
|
||||
constexpr NiPoint3(const glm::vec3& vec) noexcept
|
||||
: x{ vec.x }
|
||||
, y{ vec.y }
|
||||
, z{ vec.z } {
|
||||
}
|
||||
|
||||
//! Initializer
|
||||
/*!
|
||||
\param x The x coordinate
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#endif
|
||||
|
||||
#include "NiQuaternion.h"
|
||||
#include <glm/ext/quaternion_float.hpp>
|
||||
|
||||
// MARK: Getters / Setters
|
||||
|
||||
|
||||
@@ -3,18 +3,37 @@
|
||||
// C++
|
||||
#include <cmath>
|
||||
|
||||
#include <glm/gtx/quaternion.hpp>
|
||||
|
||||
// MARK: Member Functions
|
||||
|
||||
Vector3 QuatUtils::Euler(const NiQuaternion& quat) {
|
||||
return glm::eulerAngles(quat);
|
||||
Vector3 NiQuaternion::GetEulerAngles() const {
|
||||
Vector3 angles;
|
||||
|
||||
// roll (x-axis rotation)
|
||||
const float sinr_cosp = 2 * (w * x + y * z);
|
||||
const float cosr_cosp = 1 - 2 * (x * x + y * y);
|
||||
angles.x = std::atan2(sinr_cosp, cosr_cosp);
|
||||
|
||||
// pitch (y-axis rotation)
|
||||
const float sinp = 2 * (w * y - z * x);
|
||||
|
||||
if (std::abs(sinp) >= 1) {
|
||||
angles.y = std::copysign(3.14 / 2, sinp); // use 90 degrees if out of range
|
||||
} else {
|
||||
angles.y = std::asin(sinp);
|
||||
}
|
||||
|
||||
// yaw (z-axis rotation)
|
||||
const float siny_cosp = 2 * (w * z + x * y);
|
||||
const float cosy_cosp = 1 - 2 * (y * y + z * z);
|
||||
angles.z = std::atan2(siny_cosp, cosy_cosp);
|
||||
|
||||
return angles;
|
||||
}
|
||||
|
||||
// MARK: Helper Functions
|
||||
|
||||
//! Look from a specific point in space to another point in space (Y-locked)
|
||||
NiQuaternion QuatUtils::LookAt(const NiPoint3& sourcePoint, const NiPoint3& destPoint) {
|
||||
NiQuaternion NiQuaternion::LookAt(const NiPoint3& sourcePoint, const NiPoint3& destPoint) {
|
||||
//To make sure we don't orient around the X/Z axis:
|
||||
NiPoint3 source = sourcePoint;
|
||||
NiPoint3 dest = destPoint;
|
||||
@@ -32,11 +51,11 @@ NiQuaternion QuatUtils::LookAt(const NiPoint3& sourcePoint, const NiPoint3& dest
|
||||
NiPoint3 vecB = vecA.CrossProduct(posZ);
|
||||
|
||||
if (vecB.DotProduct(forwardVector) < 0) rotAngle = -rotAngle;
|
||||
return glm::angleAxis(rotAngle, glm::vec3{vecA.x, vecA.y, vecA.z});
|
||||
return NiQuaternion::CreateFromAxisAngle(vecA, rotAngle);
|
||||
}
|
||||
|
||||
//! Look from a specific point in space to another point in space
|
||||
NiQuaternion QuatUtils::LookAtUnlocked(const NiPoint3& sourcePoint, const NiPoint3& destPoint) {
|
||||
NiQuaternion NiQuaternion::LookAtUnlocked(const NiPoint3& sourcePoint, const NiPoint3& destPoint) {
|
||||
NiPoint3 forwardVector = NiPoint3(destPoint - sourcePoint).Unitize();
|
||||
|
||||
NiPoint3 posZ = NiPoint3Constant::UNIT_Z;
|
||||
@@ -48,26 +67,37 @@ NiQuaternion QuatUtils::LookAtUnlocked(const NiPoint3& sourcePoint, const NiPoin
|
||||
NiPoint3 vecB = vecA.CrossProduct(posZ);
|
||||
|
||||
if (vecB.DotProduct(forwardVector) < 0) rotAngle = -rotAngle;
|
||||
return glm::angleAxis(rotAngle, glm::vec3{vecA.x, vecA.y, vecA.z});
|
||||
return NiQuaternion::CreateFromAxisAngle(vecA, rotAngle);
|
||||
}
|
||||
|
||||
//! Creates a Quaternion from a specific axis and angle relative to that axis
|
||||
NiQuaternion QuatUtils::AxisAngle(const Vector3& axis, float angle) {
|
||||
return glm::angleAxis(angle, glm::vec3(axis.x, axis.y, axis.z));
|
||||
NiQuaternion NiQuaternion::CreateFromAxisAngle(const Vector3& axis, float angle) {
|
||||
float halfAngle = angle * 0.5f;
|
||||
float s = static_cast<float>(sin(halfAngle));
|
||||
|
||||
NiQuaternion q;
|
||||
q.x = axis.GetX() * s;
|
||||
q.y = axis.GetY() * s;
|
||||
q.z = axis.GetZ() * s;
|
||||
q.w = static_cast<float>(cos(halfAngle));
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
NiQuaternion QuatUtils::FromEuler(const NiPoint3& eulerAngles) {
|
||||
return glm::quat(glm::vec3(eulerAngles.x, eulerAngles.y, eulerAngles.z));
|
||||
}
|
||||
NiQuaternion NiQuaternion::FromEulerAngles(const NiPoint3& eulerAngles) {
|
||||
// Abbreviations for the various angular functions
|
||||
float cy = cos(eulerAngles.z * 0.5);
|
||||
float sy = sin(eulerAngles.z * 0.5);
|
||||
float cp = cos(eulerAngles.y * 0.5);
|
||||
float sp = sin(eulerAngles.y * 0.5);
|
||||
float cr = cos(eulerAngles.x * 0.5);
|
||||
float sr = sin(eulerAngles.x * 0.5);
|
||||
|
||||
Vector3 QuatUtils::Forward(const NiQuaternion& quat) {
|
||||
return quat * glm::vec3(0, 0, 1);
|
||||
}
|
||||
NiQuaternion q;
|
||||
q.w = cr * cp * cy + sr * sp * sy;
|
||||
q.x = sr * cp * cy - cr * sp * sy;
|
||||
q.y = cr * sp * cy + sr * cp * sy;
|
||||
q.z = cr * cp * sy - sr * sp * cy;
|
||||
|
||||
Vector3 QuatUtils::Up(const NiQuaternion& quat) {
|
||||
return quat * glm::vec3(0, 1, 0);
|
||||
}
|
||||
|
||||
Vector3 QuatUtils::Right(const NiQuaternion& quat) {
|
||||
return quat * glm::vec3(1, 0, 0);
|
||||
return q;
|
||||
}
|
||||
|
||||
@@ -1,27 +1,158 @@
|
||||
#ifndef NIQUATERNION_H
|
||||
#define NIQUATERNION_H
|
||||
#ifndef __NIQUATERNION_H__
|
||||
#define __NIQUATERNION_H__
|
||||
|
||||
// Custom Classes
|
||||
#include "NiPoint3.h"
|
||||
|
||||
#define GLM_FORCE_QUAT_DATA_WXYZ
|
||||
/*!
|
||||
\file NiQuaternion.hpp
|
||||
\brief Defines a quaternion in space in WXYZ coordinates
|
||||
*/
|
||||
|
||||
#include <glm/ext/quaternion_float.hpp>
|
||||
class NiQuaternion;
|
||||
typedef NiQuaternion Quaternion; //!< A typedef for a shorthand version of NiQuaternion
|
||||
|
||||
using Quaternion = glm::quat;
|
||||
using NiQuaternion = Quaternion;
|
||||
//! A class that defines a rotation in space
|
||||
class NiQuaternion {
|
||||
public:
|
||||
float w{ 1 }; //!< The w coordinate
|
||||
float x{ 0 }; //!< The x coordinate
|
||||
float y{ 0 }; //!< The y coordinate
|
||||
float z{ 0 }; //!< The z coordinate
|
||||
|
||||
namespace QuatUtils {
|
||||
constexpr NiQuaternion IDENTITY = glm::identity<NiQuaternion>();
|
||||
Vector3 Forward(const NiQuaternion& quat);
|
||||
Vector3 Up(const NiQuaternion& quat);
|
||||
Vector3 Right(const NiQuaternion& quat);
|
||||
NiQuaternion LookAt(const NiPoint3& from, const NiPoint3& to);
|
||||
NiQuaternion LookAtUnlocked(const NiPoint3& from, const NiPoint3& to);
|
||||
Vector3 Euler(const NiQuaternion& quat);
|
||||
NiQuaternion AxisAngle(const Vector3& axis, float angle);
|
||||
NiQuaternion FromEuler(const NiPoint3& eulerAngles);
|
||||
constexpr float PI_OVER_180 = glm::pi<float>() / 180.0f;
|
||||
|
||||
//! The initializer
|
||||
constexpr NiQuaternion() = default;
|
||||
|
||||
//! The initializer
|
||||
/*!
|
||||
\param w The w coordinate
|
||||
\param x The x coordinate
|
||||
\param y The y coordinate
|
||||
\param z The z coordinate
|
||||
*/
|
||||
constexpr NiQuaternion(const float w, const float x, const float y, const float z) noexcept
|
||||
: w{ w }
|
||||
, x{ x }
|
||||
, y{ y }
|
||||
, z{ z } {
|
||||
}
|
||||
|
||||
// MARK: Setters / Getters
|
||||
|
||||
//! Gets the W coordinate
|
||||
/*!
|
||||
\return The w coordinate
|
||||
*/
|
||||
[[nodiscard]] constexpr float GetW() const noexcept;
|
||||
|
||||
//! Sets the W coordinate
|
||||
/*!
|
||||
\param w The w coordinate
|
||||
*/
|
||||
constexpr void SetW(const float w) noexcept;
|
||||
|
||||
//! Gets the X coordinate
|
||||
/*!
|
||||
\return The x coordinate
|
||||
*/
|
||||
[[nodiscard]] constexpr float GetX() const noexcept;
|
||||
|
||||
//! Sets the X coordinate
|
||||
/*!
|
||||
\param x The x coordinate
|
||||
*/
|
||||
constexpr void SetX(const float x) noexcept;
|
||||
|
||||
//! Gets the Y coordinate
|
||||
/*!
|
||||
\return The y coordinate
|
||||
*/
|
||||
[[nodiscard]] constexpr float GetY() const noexcept;
|
||||
|
||||
//! Sets the Y coordinate
|
||||
/*!
|
||||
\param y The y coordinate
|
||||
*/
|
||||
constexpr void SetY(const float y) noexcept;
|
||||
|
||||
//! Gets the Z coordinate
|
||||
/*!
|
||||
\return The z coordinate
|
||||
*/
|
||||
[[nodiscard]] constexpr float GetZ() const noexcept;
|
||||
|
||||
//! Sets the Z coordinate
|
||||
/*!
|
||||
\param z The z coordinate
|
||||
*/
|
||||
constexpr void SetZ(const float z) noexcept;
|
||||
|
||||
// MARK: Member Functions
|
||||
|
||||
//! Returns the forward vector from the quaternion
|
||||
/*!
|
||||
\return The forward vector of the quaternion
|
||||
*/
|
||||
[[nodiscard]] constexpr Vector3 GetForwardVector() const noexcept;
|
||||
|
||||
//! Returns the up vector from the quaternion
|
||||
/*!
|
||||
\return The up vector fo the quaternion
|
||||
*/
|
||||
[[nodiscard]] constexpr Vector3 GetUpVector() const noexcept;
|
||||
|
||||
//! Returns the right vector from the quaternion
|
||||
/*!
|
||||
\return The right vector of the quaternion
|
||||
*/
|
||||
[[nodiscard]] constexpr Vector3 GetRightVector() const noexcept;
|
||||
|
||||
[[nodiscard]] Vector3 GetEulerAngles() const;
|
||||
|
||||
// MARK: Operators
|
||||
|
||||
//! Operator to check for equality
|
||||
constexpr bool operator==(const NiQuaternion& rot) const noexcept;
|
||||
|
||||
//! Operator to check for inequality
|
||||
constexpr bool operator!=(const NiQuaternion& rot) const noexcept;
|
||||
|
||||
// MARK: Helper Functions
|
||||
|
||||
//! Look from a specific point in space to another point in space (Y-locked)
|
||||
/*!
|
||||
\param sourcePoint The source location
|
||||
\param destPoint The destination location
|
||||
\return The Quaternion with the rotation towards the destination
|
||||
*/
|
||||
[[nodiscard]] static NiQuaternion LookAt(const NiPoint3& sourcePoint, const NiPoint3& destPoint);
|
||||
|
||||
//! Look from a specific point in space to another point in space
|
||||
/*!
|
||||
\param sourcePoint The source location
|
||||
\param destPoint The destination location
|
||||
\return The Quaternion with the rotation towards the destination
|
||||
*/
|
||||
[[nodiscard]] static NiQuaternion LookAtUnlocked(const NiPoint3& sourcePoint, const NiPoint3& destPoint);
|
||||
|
||||
//! Creates a Quaternion from a specific axis and angle relative to that axis
|
||||
/*!
|
||||
\param axis The axis that is used
|
||||
\param angle The angle relative to this axis
|
||||
\return A quaternion created from the axis and angle
|
||||
*/
|
||||
[[nodiscard]] static NiQuaternion CreateFromAxisAngle(const Vector3& axis, float angle);
|
||||
|
||||
[[nodiscard]] static NiQuaternion FromEulerAngles(const NiPoint3& eulerAngles);
|
||||
};
|
||||
|
||||
#endif // !NIQUATERNION_H
|
||||
// Static Variables
|
||||
namespace NiQuaternionConstant {
|
||||
constexpr NiQuaternion IDENTITY(1, 0, 0, 0);
|
||||
}
|
||||
|
||||
// Include constexpr and inline function definitions in a seperate file for readability
|
||||
#include "NiQuaternion.inl"
|
||||
|
||||
#endif // !__NIQUATERNION_H__
|
||||
|
||||
75
dCommon/NiQuaternion.inl
Normal file
75
dCommon/NiQuaternion.inl
Normal file
@@ -0,0 +1,75 @@
|
||||
#pragma once
|
||||
#ifndef __NIQUATERNION_H__
|
||||
#error "This should only be included inline in NiQuaternion.h: Do not include directly!"
|
||||
#endif
|
||||
|
||||
// MARK: Setters / Getters
|
||||
|
||||
//! Gets the W coordinate
|
||||
constexpr float NiQuaternion::GetW() const noexcept {
|
||||
return this->w;
|
||||
}
|
||||
|
||||
//! Sets the W coordinate
|
||||
constexpr void NiQuaternion::SetW(const float w) noexcept {
|
||||
this->w = w;
|
||||
}
|
||||
|
||||
//! Gets the X coordinate
|
||||
constexpr float NiQuaternion::GetX() const noexcept {
|
||||
return this->x;
|
||||
}
|
||||
|
||||
//! Sets the X coordinate
|
||||
constexpr void NiQuaternion::SetX(const float x) noexcept {
|
||||
this->x = x;
|
||||
}
|
||||
|
||||
//! Gets the Y coordinate
|
||||
constexpr float NiQuaternion::GetY() const noexcept {
|
||||
return this->y;
|
||||
}
|
||||
|
||||
//! Sets the Y coordinate
|
||||
constexpr void NiQuaternion::SetY(const float y) noexcept {
|
||||
this->y = y;
|
||||
}
|
||||
|
||||
//! Gets the Z coordinate
|
||||
constexpr float NiQuaternion::GetZ() const noexcept {
|
||||
return this->z;
|
||||
}
|
||||
|
||||
//! Sets the Z coordinate
|
||||
constexpr void NiQuaternion::SetZ(const float z) noexcept {
|
||||
this->z = z;
|
||||
}
|
||||
|
||||
// MARK: Member Functions
|
||||
|
||||
//! Returns the forward vector from the quaternion
|
||||
constexpr Vector3 NiQuaternion::GetForwardVector() const noexcept {
|
||||
return Vector3(2 * (x * z + w * y), 2 * (y * z - w * x), 1 - 2 * (x * x + y * y));
|
||||
}
|
||||
|
||||
//! Returns the up vector from the quaternion
|
||||
constexpr Vector3 NiQuaternion::GetUpVector() const noexcept {
|
||||
return Vector3(2 * (x * y - w * z), 1 - 2 * (x * x + z * z), 2 * (y * z + w * x));
|
||||
}
|
||||
|
||||
//! Returns the right vector from the quaternion
|
||||
constexpr Vector3 NiQuaternion::GetRightVector() const noexcept {
|
||||
return Vector3(1 - 2 * (y * y + z * z), 2 * (x * y + w * z), 2 * (x * z - w * y));
|
||||
}
|
||||
|
||||
// MARK: Operators
|
||||
|
||||
//! Operator to check for equality
|
||||
constexpr bool NiQuaternion::operator==(const NiQuaternion& rot) const noexcept {
|
||||
return rot.x == this->x && rot.y == this->y && rot.z == this->z && rot.w == this->w;
|
||||
}
|
||||
|
||||
//! Operator to check for inequality
|
||||
constexpr bool NiQuaternion::operator!=(const NiQuaternion& rot) const noexcept {
|
||||
return !(*this == rot);
|
||||
}
|
||||
@@ -24,7 +24,7 @@ struct LocalSpaceInfo {
|
||||
|
||||
struct PositionUpdate {
|
||||
NiPoint3 position = NiPoint3Constant::ZERO;
|
||||
NiQuaternion rotation = QuatUtils::IDENTITY;
|
||||
NiQuaternion rotation = NiQuaternionConstant::IDENTITY;
|
||||
bool onGround = false;
|
||||
bool onRail = false;
|
||||
NiPoint3 velocity = NiPoint3Constant::ZERO;
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
#ifndef __SERVICETYPE__H__
|
||||
#define __SERVICETYPE__H__
|
||||
|
||||
enum class ServiceType : uint16_t {
|
||||
COMMON = 0,
|
||||
AUTH,
|
||||
CHAT,
|
||||
WORLD = 4,
|
||||
CLIENT,
|
||||
MASTER,
|
||||
UNKNOWN
|
||||
};
|
||||
|
||||
#endif //!__SERVICETYPE__H__
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "BitStream.h"
|
||||
#include "BitStreamUtils.h"
|
||||
#include "MessageType/Client.h"
|
||||
#include "ServiceType.h"
|
||||
#include "eConnectionType.h"
|
||||
|
||||
#pragma warning (disable:4251) //Disables SQL warnings
|
||||
|
||||
@@ -34,7 +34,7 @@ constexpr uint32_t lowFrameDelta = FRAMES_TO_MS(lowFramerate);
|
||||
#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 BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::GAME_MSG);
|
||||
#define CMSGHEADER BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::GAME_MSG);
|
||||
#define SEND_PACKET Game::server->Send(bitStream, sysAddr, false);
|
||||
#define SEND_PACKET_BROADCAST Game::server->Send(bitStream, UNASSIGNED_SYSTEM_ADDRESS, true);
|
||||
|
||||
|
||||
14
dCommon/dEnums/eConnectionType.h
Normal file
14
dCommon/dEnums/eConnectionType.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef __ECONNECTIONTYPE__H__
|
||||
#define __ECONNECTIONTYPE__H__
|
||||
|
||||
enum class eConnectionType : uint16_t {
|
||||
SERVER = 0,
|
||||
AUTH,
|
||||
CHAT,
|
||||
WORLD = 4,
|
||||
CLIENT,
|
||||
MASTER,
|
||||
UNKNOWN
|
||||
};
|
||||
|
||||
#endif //!__ECONNECTIONTYPE__H__
|
||||
@@ -15,7 +15,7 @@ target_include_directories(dDatabaseCDClient PUBLIC "."
|
||||
"${PROJECT_SOURCE_DIR}/dCommon"
|
||||
"${PROJECT_SOURCE_DIR}/dCommon/dEnums"
|
||||
)
|
||||
target_link_libraries(dDatabaseCDClient PRIVATE sqlite3 glm::glm)
|
||||
target_link_libraries(dDatabaseCDClient PRIVATE sqlite3)
|
||||
|
||||
if (${CDCLIENT_CACHE_ALL})
|
||||
add_compile_definitions(dDatabaseCDClient PRIVATE CDCLIENT_CACHE_ALL=${CDCLIENT_CACHE_ALL})
|
||||
|
||||
@@ -10,5 +10,4 @@ add_dependencies(dDatabase conncpp_dylib)
|
||||
|
||||
target_include_directories(dDatabase PUBLIC ".")
|
||||
target_link_libraries(dDatabase
|
||||
PUBLIC dDatabaseCDClient dDatabaseGame
|
||||
PRIVATE glm::glm)
|
||||
PUBLIC dDatabaseCDClient dDatabaseGame)
|
||||
|
||||
@@ -29,7 +29,7 @@ target_include_directories(dDatabaseGame PUBLIC "."
|
||||
|
||||
target_link_libraries(dDatabaseGame
|
||||
INTERFACE dCommon
|
||||
PRIVATE sqlite3 MariaDB::ConnCpp glm::glm)
|
||||
PRIVATE sqlite3 MariaDB::ConnCpp)
|
||||
|
||||
# Glob together all headers that need to be precompiled
|
||||
file(
|
||||
|
||||
@@ -14,7 +14,6 @@ public:
|
||||
std::string bcryptPassword;
|
||||
uint32_t id{};
|
||||
uint32_t playKeyId{};
|
||||
uint64_t muteExpire{};
|
||||
bool banned{};
|
||||
bool locked{};
|
||||
eGameMasterLevel maxGmLevel{};
|
||||
|
||||
@@ -8,15 +8,15 @@
|
||||
class IBehaviors {
|
||||
public:
|
||||
struct Info {
|
||||
LWOOBJID behaviorId{};
|
||||
int32_t behaviorId{};
|
||||
uint32_t characterId{};
|
||||
std::string behaviorInfo;
|
||||
};
|
||||
|
||||
// This Add also takes care of updating if it exists.
|
||||
virtual void AddBehavior(const Info& info) = 0;
|
||||
virtual std::string GetBehavior(const LWOOBJID behaviorId) = 0;
|
||||
virtual void RemoveBehavior(const LWOOBJID behaviorId) = 0;
|
||||
virtual std::string GetBehavior(const int32_t behaviorId) = 0;
|
||||
virtual void RemoveBehavior(const int32_t behaviorId) = 0;
|
||||
};
|
||||
|
||||
#endif //!IBEHAVIORS_H
|
||||
|
||||
@@ -13,11 +13,11 @@ public:
|
||||
}
|
||||
|
||||
NiPoint3 position;
|
||||
NiQuaternion rotation = QuatUtils::IDENTITY;
|
||||
NiQuaternion rotation;
|
||||
LWOOBJID id{};
|
||||
LOT lot{};
|
||||
uint32_t ugcId{};
|
||||
std::array<LWOOBJID, 5> behaviors{};
|
||||
std::array<int32_t, 5> behaviors{};
|
||||
};
|
||||
|
||||
// Inserts a new UGC model into the database.
|
||||
@@ -34,9 +34,9 @@ public:
|
||||
virtual void InsertNewPropertyModel(const LWOOBJID& propertyId, const IPropertyContents::Model& model, const std::string_view name) = 0;
|
||||
|
||||
// Update the model position and rotation for the given property id.
|
||||
virtual void UpdateModel(const LWOOBJID& modelID, const NiPoint3& position, const NiQuaternion& rotation, const std::array<std::pair<LWOOBJID, std::string>, 5>& behaviors) = 0;
|
||||
virtual void UpdateModel(const LWOOBJID& modelID, const NiPoint3& position, const NiQuaternion& rotation, const std::array<LWOOBJID, 5> behaviorIDs) {
|
||||
std::array<std::pair<LWOOBJID, std::string>, 5> behaviors;
|
||||
virtual void UpdateModel(const LWOOBJID& modelID, const NiPoint3& position, const NiQuaternion& rotation, const std::array<std::pair<int32_t, std::string>, 5>& behaviors) = 0;
|
||||
virtual void UpdateModel(const LWOOBJID& modelID, const NiPoint3& position, const NiQuaternion& rotation, const std::array<int32_t, 5> behaviorIDs) {
|
||||
std::array<std::pair<int32_t, std::string>, 5> behaviors;
|
||||
for (int32_t i = 0; i < behaviors.size(); i++) behaviors[i].first = behaviorIDs[i];
|
||||
UpdateModel(modelID, position, rotation, behaviors);
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ public:
|
||||
std::vector<IPropertyContents::Model> GetPropertyModels(const LWOOBJID& propertyId) override;
|
||||
void RemoveUnreferencedUgcModels() override;
|
||||
void InsertNewPropertyModel(const LWOOBJID& propertyId, const IPropertyContents::Model& model, const std::string_view name) override;
|
||||
void UpdateModel(const LWOOBJID& modelID, const NiPoint3& position, const NiQuaternion& rotation, const std::array<std::pair<LWOOBJID, std::string>, 5>& behaviors) override;
|
||||
void UpdateModel(const LWOOBJID& modelID, const NiPoint3& position, const NiQuaternion& rotation, const std::array<std::pair<int32_t, std::string>, 5>& behaviors) override;
|
||||
void RemoveModel(const LWOOBJID& modelId) override;
|
||||
void UpdatePerformanceCost(const LWOZONEID& zoneId, const float performanceCost) override;
|
||||
void InsertNewBugReport(const IBugReports::Info& info) override;
|
||||
@@ -110,8 +110,8 @@ public:
|
||||
void InsertRewardCode(const uint32_t account_id, const uint32_t reward_code) override;
|
||||
std::vector<uint32_t> GetRewardCodesByAccountID(const uint32_t account_id) override;
|
||||
void AddBehavior(const IBehaviors::Info& info) override;
|
||||
std::string GetBehavior(const LWOOBJID behaviorId) override;
|
||||
void RemoveBehavior(const LWOOBJID characterId) override;
|
||||
std::string GetBehavior(const int32_t behaviorId) override;
|
||||
void RemoveBehavior(const int32_t characterId) override;
|
||||
void UpdateAccountGmLevel(const uint32_t accountId, const eGameMasterLevel gmLevel) override;
|
||||
std::optional<IProperty::PropertyEntranceResult> GetProperties(const IProperty::PropertyLookup& params) override;
|
||||
std::vector<ILeaderboard::Entry> GetDescendingLeaderboard(const uint32_t activityId) override;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include "eGameMasterLevel.h"
|
||||
|
||||
std::optional<IAccounts::Info> MySQLDatabase::GetAccountInfo(const std::string_view username) {
|
||||
auto result = ExecuteSelect("SELECT id, password, banned, locked, play_key_id, gm_level, mute_expire FROM accounts WHERE name = ? LIMIT 1;", username);
|
||||
auto result = ExecuteSelect("SELECT id, password, banned, locked, play_key_id, gm_level FROM accounts WHERE name = ? LIMIT 1;", username);
|
||||
|
||||
if (!result->next()) {
|
||||
return std::nullopt;
|
||||
@@ -16,7 +16,6 @@ std::optional<IAccounts::Info> MySQLDatabase::GetAccountInfo(const std::string_v
|
||||
toReturn.banned = result->getBoolean("banned");
|
||||
toReturn.locked = result->getBoolean("locked");
|
||||
toReturn.playKeyId = result->getUInt("play_key_id");
|
||||
toReturn.muteExpire = result->getUInt64("mute_expire");
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
@@ -9,11 +9,11 @@ void MySQLDatabase::AddBehavior(const IBehaviors::Info& info) {
|
||||
);
|
||||
}
|
||||
|
||||
void MySQLDatabase::RemoveBehavior(const LWOOBJID behaviorId) {
|
||||
void MySQLDatabase::RemoveBehavior(const int32_t behaviorId) {
|
||||
ExecuteDelete("DELETE FROM behaviors WHERE behavior_id = ?", behaviorId);
|
||||
}
|
||||
|
||||
std::string MySQLDatabase::GetBehavior(const LWOOBJID behaviorId) {
|
||||
std::string MySQLDatabase::GetBehavior(const int32_t behaviorId) {
|
||||
auto result = ExecuteSelect("SELECT behavior_info FROM behaviors WHERE behavior_id = ?", behaviorId);
|
||||
return result->next() ? result->getString("behavior_info").c_str() : "";
|
||||
}
|
||||
|
||||
@@ -20,11 +20,11 @@ std::vector<IPropertyContents::Model> MySQLDatabase::GetPropertyModels(const LWO
|
||||
model.rotation.y = result->getFloat("ry");
|
||||
model.rotation.z = result->getFloat("rz");
|
||||
model.ugcId = result->getUInt64("ugc_id");
|
||||
model.behaviors[0] = result->getUInt64("behavior_1");
|
||||
model.behaviors[1] = result->getUInt64("behavior_2");
|
||||
model.behaviors[2] = result->getUInt64("behavior_3");
|
||||
model.behaviors[3] = result->getUInt64("behavior_4");
|
||||
model.behaviors[4] = result->getUInt64("behavior_5");
|
||||
model.behaviors[0] = result->getInt("behavior_1");
|
||||
model.behaviors[1] = result->getInt("behavior_2");
|
||||
model.behaviors[2] = result->getInt("behavior_3");
|
||||
model.behaviors[3] = result->getInt("behavior_4");
|
||||
model.behaviors[4] = result->getInt("behavior_5");
|
||||
|
||||
toReturn.push_back(std::move(model));
|
||||
}
|
||||
@@ -52,7 +52,7 @@ void MySQLDatabase::InsertNewPropertyModel(const LWOOBJID& propertyId, const IPr
|
||||
}
|
||||
}
|
||||
|
||||
void MySQLDatabase::UpdateModel(const LWOOBJID& modelID, const NiPoint3& position, const NiQuaternion& rotation, const std::array<std::pair<LWOOBJID, std::string>, 5>& behaviors) {
|
||||
void MySQLDatabase::UpdateModel(const LWOOBJID& modelID, const NiPoint3& position, const NiQuaternion& rotation, const std::array<std::pair<int32_t, std::string>, 5>& behaviors) {
|
||||
ExecuteUpdate(
|
||||
"UPDATE properties_contents SET x = ?, y = ?, z = ?, rx = ?, ry = ?, rz = ?, rw = ?, "
|
||||
"behavior_1 = ?, behavior_2 = ?, behavior_3 = ?, behavior_4 = ?, behavior_5 = ? WHERE id = ?;",
|
||||
@@ -79,11 +79,11 @@ IPropertyContents::Model MySQLDatabase::GetModel(const LWOOBJID modelID) {
|
||||
model.rotation.y = result->getFloat("ry");
|
||||
model.rotation.z = result->getFloat("rz");
|
||||
model.ugcId = result->getUInt64("ugc_id");
|
||||
model.behaviors[0] = result->getUInt64("behavior_1");
|
||||
model.behaviors[1] = result->getUInt64("behavior_2");
|
||||
model.behaviors[2] = result->getUInt64("behavior_3");
|
||||
model.behaviors[3] = result->getUInt64("behavior_4");
|
||||
model.behaviors[4] = result->getUInt64("behavior_5");
|
||||
model.behaviors[0] = result->getInt("behavior_1");
|
||||
model.behaviors[1] = result->getInt("behavior_2");
|
||||
model.behaviors[2] = result->getInt("behavior_3");
|
||||
model.behaviors[3] = result->getInt("behavior_4");
|
||||
model.behaviors[4] = result->getInt("behavior_5");
|
||||
}
|
||||
|
||||
return model;
|
||||
|
||||
@@ -73,7 +73,7 @@ public:
|
||||
std::vector<IPropertyContents::Model> GetPropertyModels(const LWOOBJID& propertyId) override;
|
||||
void RemoveUnreferencedUgcModels() override;
|
||||
void InsertNewPropertyModel(const LWOOBJID& propertyId, const IPropertyContents::Model& model, const std::string_view name) override;
|
||||
void UpdateModel(const LWOOBJID& modelID, const NiPoint3& position, const NiQuaternion& rotation, const std::array<std::pair<LWOOBJID, std::string>, 5>& behaviors) override;
|
||||
void UpdateModel(const LWOOBJID& modelID, const NiPoint3& position, const NiQuaternion& rotation, const std::array<std::pair<int32_t, std::string>, 5>& behaviors) override;
|
||||
void RemoveModel(const LWOOBJID& modelId) override;
|
||||
void UpdatePerformanceCost(const LWOZONEID& zoneId, const float performanceCost) override;
|
||||
void InsertNewBugReport(const IBugReports::Info& info) override;
|
||||
@@ -108,8 +108,8 @@ public:
|
||||
void InsertRewardCode(const uint32_t account_id, const uint32_t reward_code) override;
|
||||
std::vector<uint32_t> GetRewardCodesByAccountID(const uint32_t account_id) override;
|
||||
void AddBehavior(const IBehaviors::Info& info) override;
|
||||
std::string GetBehavior(const LWOOBJID behaviorId) override;
|
||||
void RemoveBehavior(const LWOOBJID characterId) override;
|
||||
std::string GetBehavior(const int32_t behaviorId) override;
|
||||
void RemoveBehavior(const int32_t characterId) override;
|
||||
void UpdateAccountGmLevel(const uint32_t accountId, const eGameMasterLevel gmLevel) override;
|
||||
std::optional<IProperty::PropertyEntranceResult> GetProperties(const IProperty::PropertyLookup& params) override;
|
||||
std::vector<ILeaderboard::Entry> GetDescendingLeaderboard(const uint32_t activityId) override;
|
||||
|
||||
@@ -17,7 +17,6 @@ std::optional<IAccounts::Info> SQLiteDatabase::GetAccountInfo(const std::string_
|
||||
toReturn.banned = result.getIntField("banned");
|
||||
toReturn.locked = result.getIntField("locked");
|
||||
toReturn.playKeyId = result.getIntField("play_key_id");
|
||||
toReturn.muteExpire = static_cast<uint64_t>(result.getInt64Field("mute_expire"));
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
@@ -9,11 +9,11 @@ void SQLiteDatabase::AddBehavior(const IBehaviors::Info& info) {
|
||||
);
|
||||
}
|
||||
|
||||
void SQLiteDatabase::RemoveBehavior(const LWOOBJID behaviorId) {
|
||||
void SQLiteDatabase::RemoveBehavior(const int32_t behaviorId) {
|
||||
ExecuteDelete("DELETE FROM behaviors WHERE behavior_id = ?", behaviorId);
|
||||
}
|
||||
|
||||
std::string SQLiteDatabase::GetBehavior(const LWOOBJID behaviorId) {
|
||||
std::string SQLiteDatabase::GetBehavior(const int32_t behaviorId) {
|
||||
auto [_, result] = ExecuteSelect("SELECT behavior_info FROM behaviors WHERE behavior_id = ?", behaviorId);
|
||||
return !result.eof() ? result.getStringField("behavior_info") : "";
|
||||
}
|
||||
|
||||
@@ -19,11 +19,11 @@ std::vector<IPropertyContents::Model> SQLiteDatabase::GetPropertyModels(const LW
|
||||
model.rotation.y = result.getFloatField("ry");
|
||||
model.rotation.z = result.getFloatField("rz");
|
||||
model.ugcId = result.getInt64Field("ugc_id");
|
||||
model.behaviors[0] = result.getInt64Field("behavior_1");
|
||||
model.behaviors[1] = result.getInt64Field("behavior_2");
|
||||
model.behaviors[2] = result.getInt64Field("behavior_3");
|
||||
model.behaviors[3] = result.getInt64Field("behavior_4");
|
||||
model.behaviors[4] = result.getInt64Field("behavior_5");
|
||||
model.behaviors[0] = result.getIntField("behavior_1");
|
||||
model.behaviors[1] = result.getIntField("behavior_2");
|
||||
model.behaviors[2] = result.getIntField("behavior_3");
|
||||
model.behaviors[3] = result.getIntField("behavior_4");
|
||||
model.behaviors[4] = result.getIntField("behavior_5");
|
||||
|
||||
toReturn.push_back(std::move(model));
|
||||
result.nextRow();
|
||||
@@ -52,7 +52,7 @@ void SQLiteDatabase::InsertNewPropertyModel(const LWOOBJID& propertyId, const IP
|
||||
}
|
||||
}
|
||||
|
||||
void SQLiteDatabase::UpdateModel(const LWOOBJID& modelID, const NiPoint3& position, const NiQuaternion& rotation, const std::array<std::pair<LWOOBJID, std::string>, 5>& behaviors) {
|
||||
void SQLiteDatabase::UpdateModel(const LWOOBJID& modelID, const NiPoint3& position, const NiQuaternion& rotation, const std::array<std::pair<int32_t, std::string>, 5>& behaviors) {
|
||||
ExecuteUpdate(
|
||||
"UPDATE properties_contents SET x = ?, y = ?, z = ?, rx = ?, ry = ?, rz = ?, rw = ?, "
|
||||
"behavior_1 = ?, behavior_2 = ?, behavior_3 = ?, behavior_4 = ?, behavior_5 = ? WHERE id = ?;",
|
||||
@@ -80,11 +80,11 @@ IPropertyContents::Model SQLiteDatabase::GetModel(const LWOOBJID modelID) {
|
||||
model.rotation.y = result.getFloatField("ry");
|
||||
model.rotation.z = result.getFloatField("rz");
|
||||
model.ugcId = result.getInt64Field("ugc_id");
|
||||
model.behaviors[0] = result.getInt64Field("behavior_1");
|
||||
model.behaviors[1] = result.getInt64Field("behavior_2");
|
||||
model.behaviors[2] = result.getInt64Field("behavior_3");
|
||||
model.behaviors[3] = result.getInt64Field("behavior_4");
|
||||
model.behaviors[4] = result.getInt64Field("behavior_5");
|
||||
model.behaviors[0] = result.getIntField("behavior_1");
|
||||
model.behaviors[1] = result.getIntField("behavior_2");
|
||||
model.behaviors[2] = result.getIntField("behavior_3");
|
||||
model.behaviors[3] = result.getIntField("behavior_4");
|
||||
model.behaviors[4] = result.getIntField("behavior_5");
|
||||
} while (result.nextRow());
|
||||
}
|
||||
|
||||
|
||||
@@ -168,7 +168,7 @@ void TestSQLDatabase::InsertNewPropertyModel(const LWOOBJID& propertyId, const I
|
||||
|
||||
}
|
||||
|
||||
void TestSQLDatabase::UpdateModel(const LWOOBJID& modelID, const NiPoint3& position, const NiQuaternion& rotation, const std::array<std::pair<LWOOBJID, std::string>, 5>& behaviors) {
|
||||
void TestSQLDatabase::UpdateModel(const LWOOBJID& modelID, const NiPoint3& position, const NiQuaternion& rotation, const std::array<std::pair<int32_t, std::string>, 5>& behaviors) {
|
||||
|
||||
}
|
||||
|
||||
@@ -292,11 +292,11 @@ void TestSQLDatabase::AddBehavior(const IBehaviors::Info& info) {
|
||||
|
||||
}
|
||||
|
||||
std::string TestSQLDatabase::GetBehavior(const LWOOBJID behaviorId) {
|
||||
std::string TestSQLDatabase::GetBehavior(const int32_t behaviorId) {
|
||||
return {};
|
||||
}
|
||||
|
||||
void TestSQLDatabase::RemoveBehavior(const LWOOBJID behaviorId) {
|
||||
void TestSQLDatabase::RemoveBehavior(const int32_t behaviorId) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ class TestSQLDatabase : public GameDatabase {
|
||||
std::vector<IPropertyContents::Model> GetPropertyModels(const LWOOBJID& propertyId) override;
|
||||
void RemoveUnreferencedUgcModels() override;
|
||||
void InsertNewPropertyModel(const LWOOBJID& propertyId, const IPropertyContents::Model& model, const std::string_view name) override;
|
||||
void UpdateModel(const LWOOBJID& modelID, const NiPoint3& position, const NiQuaternion& rotation, const std::array<std::pair<LWOOBJID, std::string>, 5>& behaviors) override;
|
||||
void UpdateModel(const LWOOBJID& modelID, const NiPoint3& position, const NiQuaternion& rotation, const std::array<std::pair<int32_t, std::string>, 5>& behaviors) override;
|
||||
void RemoveModel(const LWOOBJID& modelId) override;
|
||||
void UpdatePerformanceCost(const LWOZONEID& zoneId, const float performanceCost) override;
|
||||
void InsertNewBugReport(const IBugReports::Info& info) override;
|
||||
@@ -87,8 +87,8 @@ class TestSQLDatabase : public GameDatabase {
|
||||
void InsertRewardCode(const uint32_t account_id, const uint32_t reward_code) override;
|
||||
std::vector<uint32_t> GetRewardCodesByAccountID(const uint32_t account_id) override;
|
||||
void AddBehavior(const IBehaviors::Info& info) override;
|
||||
std::string GetBehavior(const LWOOBJID behaviorId) override;
|
||||
void RemoveBehavior(const LWOOBJID behaviorId) override;
|
||||
std::string GetBehavior(const int32_t behaviorId) override;
|
||||
void RemoveBehavior(const int32_t behaviorId) override;
|
||||
void UpdateAccountGmLevel(const uint32_t accountId, const eGameMasterLevel gmLevel) override;
|
||||
std::optional<IProperty::PropertyEntranceResult> GetProperties(const IProperty::PropertyLookup& params) override { return {}; };
|
||||
std::vector<ILeaderboard::Entry> GetDescendingLeaderboard(const uint32_t activityId) override { return {}; };
|
||||
|
||||
@@ -47,8 +47,6 @@ void MigrationRunner::RunMigrations() {
|
||||
std::string finalSQL = "";
|
||||
bool runSd0Migrations = false;
|
||||
bool runNormalizeMigrations = false;
|
||||
bool runNormalizeAfterFirstPartMigrations = false;
|
||||
bool runBrickBuildsNotOnGrid = false;
|
||||
for (const auto& entry : GeneralUtils::GetSqlFileNamesFromFolder((BinaryPathFinder::GetBinaryDir() / "./migrations/dlu/" / migrationFolder).string())) {
|
||||
auto migration = LoadMigration("dlu/" + migrationFolder + "/", entry);
|
||||
|
||||
@@ -63,10 +61,6 @@ void MigrationRunner::RunMigrations() {
|
||||
runSd0Migrations = true;
|
||||
} else if (migration.name.ends_with("_normalize_model_positions.sql")) {
|
||||
runNormalizeMigrations = true;
|
||||
} else if (migration.name.ends_with("_normalize_model_positions_after_first_part.sql")) {
|
||||
runNormalizeAfterFirstPartMigrations = true;
|
||||
} else if (migration.name.ends_with("_brickbuilds_not_on_grid.sql")) {
|
||||
runBrickBuildsNotOnGrid = true;
|
||||
} else {
|
||||
finalSQL.append(migration.data.c_str());
|
||||
}
|
||||
@@ -74,7 +68,7 @@ void MigrationRunner::RunMigrations() {
|
||||
Database::Get()->InsertMigration(migration.name);
|
||||
}
|
||||
|
||||
if (finalSQL.empty() && !runSd0Migrations && !runNormalizeMigrations && !runNormalizeAfterFirstPartMigrations && !runBrickBuildsNotOnGrid) {
|
||||
if (finalSQL.empty() && !runSd0Migrations && !runNormalizeMigrations) {
|
||||
LOG("Server database is up to date.");
|
||||
return;
|
||||
}
|
||||
@@ -102,14 +96,6 @@ void MigrationRunner::RunMigrations() {
|
||||
if (runNormalizeMigrations) {
|
||||
ModelNormalizeMigration::Run();
|
||||
}
|
||||
|
||||
if (runNormalizeAfterFirstPartMigrations) {
|
||||
ModelNormalizeMigration::RunAfterFirstPart();
|
||||
}
|
||||
|
||||
if (runBrickBuildsNotOnGrid) {
|
||||
ModelNormalizeMigration::RunBrickBuildGrid();
|
||||
}
|
||||
}
|
||||
|
||||
void MigrationRunner::RunSQLiteMigrations() {
|
||||
|
||||
@@ -14,7 +14,7 @@ void ModelNormalizeMigration::Run() {
|
||||
|
||||
Sd0 sd0(lxfmlData);
|
||||
const auto asStr = sd0.GetAsStringUncompressed();
|
||||
const auto [newLxfml, newCenter] = Lxfml::NormalizePositionOnlyFirstPart(asStr);
|
||||
const auto [newLxfml, newCenter] = Lxfml::NormalizePosition(asStr);
|
||||
if (newCenter == NiPoint3Constant::ZERO) {
|
||||
LOG("Failed to update model %llu due to failure reading xml.");
|
||||
continue;
|
||||
@@ -28,44 +28,3 @@ void ModelNormalizeMigration::Run() {
|
||||
}
|
||||
Database::Get()->SetAutoCommit(oldCommit);
|
||||
}
|
||||
|
||||
void ModelNormalizeMigration::RunAfterFirstPart() {
|
||||
const auto oldCommit = Database::Get()->GetAutoCommit();
|
||||
Database::Get()->SetAutoCommit(false);
|
||||
for (auto& [lxfmlData, id, modelID] : Database::Get()->GetAllUgcModels()) {
|
||||
const auto model = Database::Get()->GetModel(modelID);
|
||||
// only BBB models (lot 14) need to have their position fixed from the above blunder
|
||||
if (model.lot != 14) continue;
|
||||
|
||||
Sd0 sd0(lxfmlData);
|
||||
const auto asStr = sd0.GetAsStringUncompressed();
|
||||
const auto [newLxfml, newCenter] = Lxfml::NormalizePositionAfterFirstPart(asStr, model.position);
|
||||
|
||||
sd0.FromData(reinterpret_cast<const uint8_t*>(newLxfml.data()), newLxfml.size());
|
||||
auto asStream = sd0.GetAsStream();
|
||||
Database::Get()->UpdateModel(model.id, newCenter, model.rotation, model.behaviors);
|
||||
Database::Get()->UpdateUgcModelData(id, asStream);
|
||||
}
|
||||
Database::Get()->SetAutoCommit(oldCommit);
|
||||
}
|
||||
|
||||
void ModelNormalizeMigration::RunBrickBuildGrid() {
|
||||
const auto oldCommit = Database::Get()->GetAutoCommit();
|
||||
Database::Get()->SetAutoCommit(false);
|
||||
for (auto& [lxfmlData, id, modelID] : Database::Get()->GetAllUgcModels()) {
|
||||
const auto model = Database::Get()->GetModel(modelID);
|
||||
// only BBB models (lot 14) need to have their position fixed from the above blunder
|
||||
if (model.lot != 14) continue;
|
||||
|
||||
Sd0 sd0(lxfmlData);
|
||||
const auto asStr = sd0.GetAsStringUncompressed();
|
||||
const auto [newLxfml, newCenter] = Lxfml::NormalizePosition(asStr, model.position);
|
||||
|
||||
sd0.FromData(reinterpret_cast<const uint8_t*>(newLxfml.data()), newLxfml.size());
|
||||
LOG("Updated model %llu to have a center of %f %f %f", modelID, newCenter.x, newCenter.y, newCenter.z);
|
||||
auto asStream = sd0.GetAsStream();
|
||||
Database::Get()->UpdateModel(model.id, newCenter, model.rotation, model.behaviors);
|
||||
Database::Get()->UpdateUgcModelData(id, asStream);
|
||||
}
|
||||
Database::Get()->SetAutoCommit(oldCommit);
|
||||
}
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
|
||||
namespace ModelNormalizeMigration {
|
||||
void Run();
|
||||
void RunAfterFirstPart();
|
||||
void RunBrickBuildGrid();
|
||||
};
|
||||
|
||||
#endif //!MODELNORMALIZEMIGRATION_H
|
||||
|
||||
@@ -496,7 +496,7 @@ void Character::OnZoneLoad() {
|
||||
|
||||
// Remove all GM items
|
||||
for (const auto lot : Inventory::GetAllGMItems()) {
|
||||
inventoryComponent->RemoveItem(lot, inventoryComponent->GetLotCount(lot), eInventoryType::ALL);
|
||||
inventoryComponent->RemoveItem(lot, inventoryComponent->GetLotCount(lot));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -654,7 +654,7 @@ private:
|
||||
/**
|
||||
* The spawn rotation of this character when loading in
|
||||
*/
|
||||
NiQuaternion m_OriginalRotation = QuatUtils::IDENTITY;
|
||||
NiQuaternion m_OriginalRotation;
|
||||
|
||||
/**
|
||||
* The respawn points of this character, per world
|
||||
|
||||
581
dGame/Entity.cpp
581
dGame/Entity.cpp
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,6 @@
|
||||
|
||||
#include <map>
|
||||
#include <functional>
|
||||
#include <tuple>
|
||||
#include <typeinfo>
|
||||
#include <type_traits>
|
||||
#include <unordered_map>
|
||||
@@ -35,6 +34,7 @@ namespace tinyxml2 {
|
||||
};
|
||||
|
||||
class Player;
|
||||
class EntityInfo;
|
||||
class User;
|
||||
class Spawner;
|
||||
class ScriptComponent;
|
||||
@@ -45,7 +45,6 @@ class Item;
|
||||
class Character;
|
||||
class EntityCallbackTimer;
|
||||
class PositionUpdate;
|
||||
struct EntityInfo;
|
||||
enum class eTriggerEventType;
|
||||
enum class eGameMasterLevel : uint8_t;
|
||||
enum class eReplicaComponentType : uint32_t;
|
||||
@@ -61,7 +60,7 @@ namespace CppScripts {
|
||||
*/
|
||||
class Entity {
|
||||
public:
|
||||
Entity(const LWOOBJID& objectID, const EntityInfo& info, User* parentUser = nullptr, Entity* parentEntity = nullptr);
|
||||
explicit Entity(const LWOOBJID& objectID, EntityInfo info, User* parentUser = nullptr, Entity* parentEntity = nullptr);
|
||||
~Entity();
|
||||
|
||||
void Initialize();
|
||||
@@ -114,7 +113,7 @@ public:
|
||||
|
||||
float GetDefaultScale() const;
|
||||
|
||||
NiPoint3 GetPosition() const;
|
||||
const NiPoint3& GetPosition() const;
|
||||
|
||||
const NiQuaternion& GetRotation() const;
|
||||
|
||||
@@ -147,9 +146,9 @@ public:
|
||||
|
||||
void SetRotation(const NiQuaternion& rotation);
|
||||
|
||||
void SetRespawnPos(const NiPoint3& position) const;
|
||||
void SetRespawnPos(const NiPoint3& position);
|
||||
|
||||
void SetRespawnRot(const NiQuaternion& rotation) const;
|
||||
void SetRespawnRot(const NiQuaternion& rotation);
|
||||
|
||||
void SetVelocity(const NiPoint3& velocity);
|
||||
|
||||
@@ -162,12 +161,6 @@ public:
|
||||
template<typename T>
|
||||
T* GetComponent() const;
|
||||
|
||||
template<typename... T>
|
||||
auto GetComponents() const;
|
||||
|
||||
template<typename... T>
|
||||
auto GetComponentsMut() const;
|
||||
|
||||
template<typename T>
|
||||
bool TryGetComponent(eReplicaComponentType componentId, T*& component) const;
|
||||
|
||||
@@ -175,10 +168,8 @@ public:
|
||||
|
||||
void AddComponent(eReplicaComponentType componentId, Component* component);
|
||||
|
||||
bool MsgRequestServerObjectInfo(GameMessages::GameMsg& msg);
|
||||
|
||||
// This is expceted to never return nullptr, an assert checks this.
|
||||
CppScripts::Script* const GetScript() const;
|
||||
CppScripts::Script* const GetScript();
|
||||
|
||||
void Subscribe(LWOOBJID scriptObjId, CppScripts::Script* scriptToAdd, const std::string& notificationName);
|
||||
void Unsubscribe(LWOOBJID scriptObjId, const std::string& notificationName);
|
||||
@@ -191,8 +182,8 @@ public:
|
||||
void RemoveParent();
|
||||
|
||||
// Adds a timer to start next frame with the given name and time.
|
||||
void AddTimer(const std::string& name, float time);
|
||||
void AddCallbackTimer(float time, const std::function<void()> callback);
|
||||
void AddTimer(std::string name, float time);
|
||||
void AddCallbackTimer(float time, std::function<void()> callback);
|
||||
bool HasTimer(const std::string& name);
|
||||
void CancelCallbackTimers();
|
||||
void CancelAllTimers();
|
||||
@@ -204,7 +195,7 @@ public:
|
||||
std::unordered_map<eReplicaComponentType, Component*>& GetComponents() { return m_Components; } // TODO: Remove
|
||||
|
||||
void WriteBaseReplicaData(RakNet::BitStream& outBitStream, eReplicaPacketType packetType);
|
||||
void WriteComponents(RakNet::BitStream& outBitStream, eReplicaPacketType packetType) const;
|
||||
void WriteComponents(RakNet::BitStream& outBitStream, eReplicaPacketType packetType);
|
||||
void UpdateXMLDoc(tinyxml2::XMLDocument& doc);
|
||||
void Update(float deltaTime);
|
||||
|
||||
@@ -251,21 +242,21 @@ public:
|
||||
void AddDieCallback(const std::function<void()>& callback);
|
||||
void Resurrect();
|
||||
|
||||
void AddLootItem(const Loot::Info& info) const;
|
||||
void PickupItem(const LWOOBJID& objectID) const;
|
||||
void AddLootItem(const Loot::Info& info);
|
||||
void PickupItem(const LWOOBJID& objectID);
|
||||
|
||||
bool PickupCoins(uint64_t count) const;
|
||||
void RegisterCoinDrop(uint64_t count) const;
|
||||
bool CanPickupCoins(uint64_t count);
|
||||
void RegisterCoinDrop(uint64_t count);
|
||||
|
||||
void ScheduleKillAfterUpdate(Entity* murderer = nullptr);
|
||||
void TriggerEvent(eTriggerEventType event, Entity* optionalTarget = nullptr) const;
|
||||
void TriggerEvent(eTriggerEventType event, Entity* optionalTarget = nullptr);
|
||||
void ScheduleDestructionAfterUpdate() { m_ShouldDestroyAfterUpdate = true; }
|
||||
|
||||
const NiPoint3& GetRespawnPosition() const;
|
||||
const NiQuaternion& GetRespawnRotation() const;
|
||||
|
||||
void Sleep() const;
|
||||
void Wake() const;
|
||||
void Sleep();
|
||||
void Wake();
|
||||
bool IsSleeping() const;
|
||||
|
||||
/*
|
||||
@@ -275,7 +266,7 @@ public:
|
||||
* Retroactively corrects the model vault size due to incorrect initialization in a previous patch.
|
||||
*
|
||||
*/
|
||||
void RetroactiveVaultSize() const;
|
||||
void RetroactiveVaultSize();
|
||||
bool GetBoolean(const std::u16string& name) const;
|
||||
int32_t GetI32(const std::u16string& name) const;
|
||||
int64_t GetI64(const std::u16string& name) const;
|
||||
@@ -338,17 +329,12 @@ public:
|
||||
|
||||
bool HandleMsg(GameMessages::GameMsg& msg) const;
|
||||
|
||||
void RegisterMsg(const MessageType::Game msgId, auto* self, const auto handler) {
|
||||
RegisterMsg(msgId, std::bind(handler, self, std::placeholders::_1));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The observable for player entity position updates.
|
||||
*/
|
||||
static Observable<Entity*, const PositionUpdate&> OnPlayerPositionUpdate;
|
||||
|
||||
private:
|
||||
void WriteLDFData(const std::vector<LDFBaseData*>& ldf, RakNet::BitStream& outBitStream) const;
|
||||
protected:
|
||||
LWOOBJID m_ObjectID;
|
||||
|
||||
LOT m_TemplateID;
|
||||
@@ -357,7 +343,7 @@ private:
|
||||
std::vector<LDFBaseData*> m_NetworkSettings;
|
||||
|
||||
NiPoint3 m_DefaultPosition;
|
||||
NiQuaternion m_DefaultRotation = QuatUtils::IDENTITY;
|
||||
NiQuaternion m_DefaultRotation;
|
||||
float m_Scale;
|
||||
|
||||
Spawner* m_Spawner;
|
||||
@@ -371,6 +357,7 @@ private:
|
||||
Entity* m_ParentEntity; //For spawners and the like
|
||||
std::vector<Entity*> m_ChildEntities;
|
||||
eGameMasterLevel m_GMLevel;
|
||||
uint16_t m_CollectibleID;
|
||||
std::vector<std::string> m_Groups;
|
||||
uint16_t m_NetworkID;
|
||||
std::vector<std::function<void()>> m_DieCallbacks;
|
||||
@@ -396,8 +383,6 @@ private:
|
||||
|
||||
bool m_IsParentChildDirty = true;
|
||||
|
||||
bool m_IsSleeping = false;
|
||||
|
||||
/*
|
||||
* Collision
|
||||
*/
|
||||
@@ -406,7 +391,7 @@ private:
|
||||
// objectID of receiver and map of notification name to script
|
||||
std::map<LWOOBJID, std::map<std::string, CppScripts::Script*>> m_Subscriptions;
|
||||
|
||||
std::unordered_multimap<MessageType::Game, std::function<bool(GameMessages::GameMsg&)>> m_MsgHandlers;
|
||||
std::multimap<MessageType::Game, std::function<bool(GameMessages::GameMsg&)>> m_MsgHandlers;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -592,13 +577,3 @@ inline ComponentType* Entity::AddComponent(VaArgs... args) {
|
||||
// To allow a static cast here instead of a dynamic one.
|
||||
return dynamic_cast<ComponentType*>(componentToReturn);
|
||||
}
|
||||
|
||||
template<typename... T>
|
||||
auto Entity::GetComponents() const {
|
||||
return GetComponentsMut<const T...>();
|
||||
}
|
||||
|
||||
template<typename... T>
|
||||
auto Entity::GetComponentsMut() const {
|
||||
return std::tuple{GetComponent<T>()...};
|
||||
}
|
||||
|
||||
@@ -129,8 +129,6 @@ Entity* EntityManager::CreateEntity(EntityInfo info, User* user, Entity* parentE
|
||||
// Set the zone control entity if the entity is a zone control object, this should only happen once
|
||||
if (controller) {
|
||||
m_ZoneControlEntity = entity;
|
||||
// Proooooobably shouldn't ghost zoneControl
|
||||
m_ZoneControlEntity->SetIsGhostingCandidate(false);
|
||||
}
|
||||
|
||||
// Check if this entity is a respawn point, if so add it to the registry
|
||||
@@ -281,8 +279,6 @@ std::vector<Entity*> EntityManager::GetEntitiesByComponent(const eReplicaCompone
|
||||
|
||||
withComp.push_back(entity);
|
||||
}
|
||||
} else {
|
||||
for (auto* const entity : m_Entities | std::views::values) withComp.push_back(entity);
|
||||
}
|
||||
return withComp;
|
||||
}
|
||||
@@ -421,7 +417,7 @@ void EntityManager::DestructEntity(Entity* entity, const SystemAddress& sysAddr)
|
||||
|
||||
void EntityManager::SerializeEntity(Entity* entity) {
|
||||
if (!entity) return;
|
||||
|
||||
|
||||
EntityManager::SerializeEntity(*entity);
|
||||
}
|
||||
|
||||
@@ -515,9 +511,9 @@ void EntityManager::UpdateGhosting(Entity* player) {
|
||||
|
||||
ghostComponent->ObserveEntity(id);
|
||||
|
||||
entity->SetObservers(entity->GetObservers() + 1);
|
||||
|
||||
ConstructEntity(entity, player->GetSystemAddress());
|
||||
|
||||
entity->SetObservers(entity->GetObservers() + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -606,14 +602,3 @@ void EntityManager::FireEventServerSide(Entity* origin, std::string args) {
|
||||
bool EntityManager::IsExcludedFromGhosting(LOT lot) {
|
||||
return std::find(m_GhostingExcludedLOTs.begin(), m_GhostingExcludedLOTs.end(), lot) != m_GhostingExcludedLOTs.end();
|
||||
}
|
||||
|
||||
bool EntityManager::SendMessage(GameMessages::GameMsg& msg) const {
|
||||
bool handled = false;
|
||||
const auto entityItr = m_Entities.find(msg.target);
|
||||
if (entityItr != m_Entities.end()) {
|
||||
auto* const entity = entityItr->second;
|
||||
if (entity) handled = entity->HandleMsg(msg);
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
@@ -9,15 +9,11 @@
|
||||
#include "dCommonVars.h"
|
||||
|
||||
class Entity;
|
||||
struct EntityInfo;
|
||||
class EntityInfo;
|
||||
class Player;
|
||||
class User;
|
||||
enum class eReplicaComponentType : uint32_t;
|
||||
|
||||
namespace GameMessages {
|
||||
struct GameMsg;
|
||||
}
|
||||
|
||||
struct SystemAddress;
|
||||
|
||||
class EntityManager {
|
||||
@@ -76,9 +72,6 @@ public:
|
||||
const bool GetHardcoreDropinventoryOnDeath() { return m_HardcoreDropinventoryOnDeath; };
|
||||
const uint32_t GetHardcoreUscoreEnemiesMultiplier() { return m_HardcoreUscoreEnemiesMultiplier; };
|
||||
|
||||
// Messaging
|
||||
bool SendMessage(GameMessages::GameMsg& msg) const;
|
||||
|
||||
private:
|
||||
void SerializeEntities();
|
||||
void KillEntities();
|
||||
|
||||
@@ -7,10 +7,6 @@
|
||||
#include "dZoneManager.h"
|
||||
#include "eServerDisconnectIdentifiers.h"
|
||||
#include "eGameMasterLevel.h"
|
||||
#include "BitStreamUtils.h"
|
||||
#include "MessageType/Chat.h"
|
||||
#include <chrono>
|
||||
#include <ctime>
|
||||
|
||||
User::User(const SystemAddress& sysAddr, const std::string& username, const std::string& sessionKey) {
|
||||
m_AccountID = 0;
|
||||
@@ -32,7 +28,7 @@ User::User(const SystemAddress& sysAddr, const std::string& username, const std:
|
||||
if (userInfo) {
|
||||
m_AccountID = userInfo->id;
|
||||
m_MaxGMLevel = userInfo->maxGmLevel;
|
||||
m_MuteExpire = userInfo->muteExpire;
|
||||
m_MuteExpire = 0; //res->getUInt64(3);
|
||||
}
|
||||
|
||||
//If we're loading a zone, we'll load the last used (aka current) character:
|
||||
@@ -95,28 +91,8 @@ Character* User::GetLastUsedChar() {
|
||||
}
|
||||
}
|
||||
|
||||
bool User::GetIsMuted() {
|
||||
using namespace std::chrono;
|
||||
constexpr auto refreshInterval = seconds{ 60 };
|
||||
const auto now = steady_clock::now();
|
||||
if (now - m_LastMuteCheck >= refreshInterval) {
|
||||
m_LastMuteCheck = now;
|
||||
if (const auto info = Database::Get()->GetAccountInfo(m_Username)) {
|
||||
const auto expire = static_cast<time_t>(info->muteExpire);
|
||||
if (expire != m_MuteExpire) {
|
||||
m_MuteExpire = expire;
|
||||
|
||||
if (Game::chatServer && m_LoggedInCharID != 0) {
|
||||
RakNet::BitStream bitStream;
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::GM_MUTE);
|
||||
bitStream.Write(m_LoggedInCharID);
|
||||
bitStream.Write(m_MuteExpire);
|
||||
Game::chatServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE, 0, Game::chatSysAddr, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return m_MuteExpire == 1 || m_MuteExpire > std::time(nullptr);
|
||||
bool User::GetIsMuted() const {
|
||||
return m_MuteExpire == 1 || m_MuteExpire > time(NULL);
|
||||
}
|
||||
|
||||
time_t User::GetMuteExpire() const {
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <chrono>
|
||||
#include "RakNetTypes.h"
|
||||
#include "dCommonVars.h"
|
||||
|
||||
@@ -47,7 +46,7 @@ public:
|
||||
const std::unordered_map<std::string, bool>& GetIsBestFriendMap() { return m_IsBestFriendMap; }
|
||||
void UpdateBestFriendValue(const std::string_view playerName, const bool newValue);
|
||||
|
||||
bool GetIsMuted();
|
||||
bool GetIsMuted() const;
|
||||
|
||||
time_t GetMuteExpire() const;
|
||||
void SetMuteExpire(time_t value);
|
||||
@@ -73,8 +72,7 @@ private:
|
||||
bool m_LastChatMessageApproved = false;
|
||||
int m_AmountOfTimesOutOfSync = 0;
|
||||
const int m_MaxDesyncAllowed = 12;
|
||||
uint64_t m_MuteExpire;
|
||||
std::chrono::steady_clock::time_point m_LastMuteCheck{};
|
||||
time_t m_MuteExpire;
|
||||
};
|
||||
|
||||
#endif // USER_H
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include "eGameMasterLevel.h"
|
||||
#include "eCharacterCreationResponse.h"
|
||||
#include "eRenameResponse.h"
|
||||
#include "ServiceType.h"
|
||||
#include "eConnectionType.h"
|
||||
#include "MessageType/Chat.h"
|
||||
#include "BitStreamUtils.h"
|
||||
#include "CheatDetection.h"
|
||||
@@ -217,7 +217,7 @@ void UserManager::RequestCharacterList(const SystemAddress& sysAddr) {
|
||||
}
|
||||
|
||||
RakNet::BitStream bitStream;
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::CHARACTER_LIST_RESPONSE);
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::CHARACTER_LIST_RESPONSE);
|
||||
|
||||
std::vector<Character*> characters = u->GetCharacters();
|
||||
bitStream.Write<uint8_t>(characters.size());
|
||||
@@ -427,7 +427,7 @@ void UserManager::DeleteCharacter(const SystemAddress& sysAddr, Packet* packet)
|
||||
Database::Get()->DeleteCharacter(charID);
|
||||
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::UNEXPECTED_DISCONNECT);
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::UNEXPECTED_DISCONNECT);
|
||||
bitStream.Write(objectID);
|
||||
Game::chatServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE, 0, Game::chatSysAddr, false);
|
||||
|
||||
@@ -526,7 +526,7 @@ void UserManager::LoginCharacter(const SystemAddress& sysAddr, uint32_t playerID
|
||||
ZoneInstanceManager::Instance()->RequestZoneTransfer(Game::server, zoneID, character->GetZoneClone(), false, [=](bool mythranShift, uint32_t zoneID, uint32_t zoneInstance, uint32_t zoneClone, std::string serverIP, uint16_t serverPort) {
|
||||
LOG("Transferring %s to Zone %i (Instance %i | Clone %i | Mythran Shift: %s) with IP %s and Port %i", character->GetName().c_str(), zoneID, zoneInstance, zoneClone, mythranShift == true ? "true" : "false", serverIP.c_str(), serverPort);
|
||||
if (character) {
|
||||
auto* entity = Game::entityManager->GetEntity(character->GetObjectID());
|
||||
auto* entity = character->GetEntity();
|
||||
if (entity) {
|
||||
auto* characterComponent = entity->GetComponent<CharacterComponent>();
|
||||
if (characterComponent) {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include "QuickBuildComponent.h"
|
||||
#include "eReplicaComponentType.h"
|
||||
#include "TeamManager.h"
|
||||
#include "ServiceType.h"
|
||||
#include "eConnectionType.h"
|
||||
|
||||
BehaviorSyncEntry::BehaviorSyncEntry() {
|
||||
}
|
||||
@@ -212,7 +212,7 @@ void BehaviorContext::UpdatePlayerSyncs(float deltaTime) {
|
||||
echo.sBitStream.assign(reinterpret_cast<char*>(bitStream.GetData()), bitStream.GetNumberOfBytesUsed());
|
||||
|
||||
RakNet::BitStream message;
|
||||
BitStreamUtils::WriteHeader(message, ServiceType::CLIENT, MessageType::Client::GAME_MSG);
|
||||
BitStreamUtils::WriteHeader(message, eConnectionType::CLIENT, MessageType::Client::GAME_MSG);
|
||||
message.Write(this->originator);
|
||||
echo.Serialize(message);
|
||||
|
||||
@@ -285,7 +285,7 @@ bool BehaviorContext::CalculateUpdate(const float deltaTime) {
|
||||
// Write message
|
||||
RakNet::BitStream message;
|
||||
|
||||
BitStreamUtils::WriteHeader(message, ServiceType::CLIENT, MessageType::Client::GAME_MSG);
|
||||
BitStreamUtils::WriteHeader(message, eConnectionType::CLIENT, MessageType::Client::GAME_MSG);
|
||||
message.Write(this->originator);
|
||||
echo.Serialize(message);
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
#include "BehaviorContext.h"
|
||||
#include "EntityManager.h"
|
||||
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
|
||||
void ChangeOrientationBehavior::Calculate(BehaviorContext* context, RakNet::BitStream& bitStream, BehaviorBranchContext branch) {
|
||||
Entity* sourceEntity;
|
||||
if (this->m_orientCaster) sourceEntity = Game::entityManager->GetEntity(context->originator);
|
||||
@@ -18,12 +16,12 @@ void ChangeOrientationBehavior::Calculate(BehaviorContext* context, RakNet::BitS
|
||||
if (!destinationEntity) return;
|
||||
|
||||
sourceEntity->SetRotation(
|
||||
QuatUtils::LookAt(sourceEntity->GetPosition(), destinationEntity->GetPosition())
|
||||
NiQuaternion::LookAt(sourceEntity->GetPosition(), destinationEntity->GetPosition())
|
||||
);
|
||||
} else if (this->m_toAngle){
|
||||
auto baseAngle = NiPoint3(0, 0, this->m_angle);
|
||||
if (this->m_relative) baseAngle += QuatUtils::Forward(sourceEntity->GetRotation());
|
||||
sourceEntity->SetRotation(glm::quat(glm::vec3(baseAngle.x, baseAngle.y, baseAngle.z)));
|
||||
if (this->m_relative) baseAngle += sourceEntity->GetRotation().GetForwardVector();
|
||||
sourceEntity->SetRotation(NiQuaternion::FromEulerAngles(baseAngle));
|
||||
} else return;
|
||||
Game::entityManager->SerializeEntity(sourceEntity);
|
||||
return;
|
||||
|
||||
@@ -12,7 +12,7 @@ void ConsumeItemBehavior::Handle(BehaviorContext* context, RakNet::BitStream& bi
|
||||
auto inventoryComponent = caster->GetComponent<InventoryComponent>();
|
||||
if (!inventoryComponent) return;
|
||||
|
||||
if (inventoryComponent->RemoveItem(this->m_ConsumeLOT, this->m_NumToConsume, eInventoryType::ALL, false, true)){
|
||||
if (inventoryComponent->RemoveItem(this->m_ConsumeLOT, this->m_NumToConsume, eInventoryType::INVALID, false, true)){
|
||||
action_to_cast = m_ActionConsumed;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ void ForceMovementBehavior::Calculate(BehaviorContext* context, RakNet::BitStrea
|
||||
if (controllablePhysicsComponent != nullptr) {
|
||||
|
||||
if (m_Forward == 1) {
|
||||
controllablePhysicsComponent->SetVelocity(QuatUtils::Forward(controllablePhysicsComponent->GetRotation()) * 25);
|
||||
controllablePhysicsComponent->SetVelocity(controllablePhysicsComponent->GetRotation().GetForwardVector() * 25);
|
||||
}
|
||||
|
||||
Game::entityManager->SerializeEntity(casterEntity);
|
||||
|
||||
@@ -92,7 +92,7 @@ void ProjectileAttackBehavior::Calculate(BehaviorContext* context, RakNet::BitSt
|
||||
|
||||
const auto time = distance / this->m_projectileSpeed;
|
||||
|
||||
const auto rotation = QuatUtils::LookAtUnlocked(position, other->GetPosition());
|
||||
const auto rotation = NiQuaternion::LookAtUnlocked(position, other->GetPosition());
|
||||
|
||||
const auto targetPosition = other->GetPosition();
|
||||
|
||||
@@ -112,13 +112,13 @@ void ProjectileAttackBehavior::Calculate(BehaviorContext* context, RakNet::BitSt
|
||||
|
||||
bitStream.Write(id);
|
||||
|
||||
auto eulerAngles = QuatUtils::Euler(rotation);
|
||||
auto eulerAngles = rotation.GetEulerAngles();
|
||||
|
||||
eulerAngles.y += angle * (glm::pi<float>() / 180.0f);
|
||||
eulerAngles.y += angle * (3.14 / 180);
|
||||
|
||||
const auto angledRotation = QuatUtils::FromEuler(eulerAngles);
|
||||
const auto angledRotation = NiQuaternion::FromEulerAngles(eulerAngles);
|
||||
|
||||
const auto direction = QuatUtils::Forward(angledRotation);
|
||||
const auto direction = angledRotation.GetForwardVector();
|
||||
|
||||
const auto destination = position + direction * distance;
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ void SpawnBehavior::Handle(BehaviorContext* context, RakNet::BitStream& bitStrea
|
||||
info.spawner = nullptr;
|
||||
info.spawnerID = context->originator;
|
||||
info.spawnerNodeID = 0;
|
||||
info.pos = info.pos + (QuatUtils::Forward(info.rot) * m_Distance);
|
||||
info.pos = info.pos + (info.rot.GetForwardVector() * m_Distance);
|
||||
|
||||
auto* entity = Game::entityManager->CreateEntity(
|
||||
info,
|
||||
|
||||
@@ -125,7 +125,7 @@ void TacArcBehavior::Calculate(BehaviorContext* context, RakNet::BitStream& bitS
|
||||
if (targetPos.y > reference.y && heightDifference > this->m_upperBound || targetPos.y < reference.y && heightDifference > this->m_lowerBound)
|
||||
continue;
|
||||
|
||||
const auto forward = QuatUtils::Forward(self->GetRotation());
|
||||
const auto forward = self->GetRotation().GetForwardVector();
|
||||
|
||||
// forward is a normalized vector of where the caster is facing.
|
||||
// targetPos is the position of the target.
|
||||
|
||||
@@ -64,11 +64,12 @@ void AchievementVendorComponent::Buy(Entity* buyer, LOT lot, uint32_t count) {
|
||||
}
|
||||
|
||||
const uint32_t altCurrencyCost = itemComp.commendationCost * count;
|
||||
if (inventoryComponent->GetLotCount(costLOT) < altCurrencyCost || !inventoryComponent->RemoveItem(costLOT, altCurrencyCost, eInventoryType::ALL)) {
|
||||
if (inventoryComponent->GetLotCount(costLOT) < altCurrencyCost) {
|
||||
GameMessages::SendVendorTransactionResult(buyer, buyer->GetSystemAddress(), eVendorTransactionResult::PURCHASE_FAIL);
|
||||
return;
|
||||
}
|
||||
|
||||
inventoryComponent->RemoveItem(costLOT, altCurrencyCost);
|
||||
inventoryComponent->AddItem(lot, count, eLootSourceType::VENDOR);
|
||||
GameMessages::SendVendorTransactionResult(buyer, buyer->GetSystemAddress(), eVendorTransactionResult::PURCHASE_SUCCESS);
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#include "Loot.h"
|
||||
#include "eMissionTaskType.h"
|
||||
#include "eMatchUpdate.h"
|
||||
#include "ServiceType.h"
|
||||
#include "eConnectionType.h"
|
||||
#include "MessageType/Chat.h"
|
||||
|
||||
#include "CDCurrencyTableTable.h"
|
||||
@@ -28,11 +28,8 @@
|
||||
#include "CDActivitiesTable.h"
|
||||
#include "LeaderboardManager.h"
|
||||
#include "CharacterComponent.h"
|
||||
#include "Amf3.h"
|
||||
|
||||
ActivityComponent::ActivityComponent(Entity* parent, int32_t activityID) : Component(parent) {
|
||||
using namespace GameMessages;
|
||||
RegisterMsg<GetObjectReportInfo>(this, &ActivityComponent::OnGetObjectReportInfo);
|
||||
/*
|
||||
* This is precisely what the client does functionally
|
||||
* Use the component id as the default activity id and load its data from the database
|
||||
@@ -351,10 +348,14 @@ bool ActivityComponent::CheckCost(Entity* player) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ActivityComponent::TakeCost(Entity* player) const {
|
||||
|
||||
bool ActivityComponent::TakeCost(Entity* player) const{
|
||||
|
||||
auto* inventoryComponent = player->GetComponent<InventoryComponent>();
|
||||
return CheckCost(player) && inventoryComponent->RemoveItem(m_ActivityInfo.optionalCostLOT, m_ActivityInfo.optionalCostCount, eInventoryType::ALL);
|
||||
if (CheckCost(player)) {
|
||||
inventoryComponent->RemoveItem(m_ActivityInfo.optionalCostLOT, m_ActivityInfo.optionalCostCount);
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
void ActivityComponent::PlayerReady(Entity* player, bool bReady) {
|
||||
@@ -509,7 +510,7 @@ void ActivityInstance::StartZone() {
|
||||
// only make a team if we have more than one participant
|
||||
if (participants.size() > 1) {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::CREATE_TEAM);
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::CREATE_TEAM);
|
||||
|
||||
bitStream.Write(leader->GetObjectID());
|
||||
bitStream.Write(m_Participants.size());
|
||||
@@ -574,7 +575,7 @@ void ActivityInstance::RewardParticipant(Entity* participant) {
|
||||
maxCoins = currencyTable[0].maxvalue;
|
||||
}
|
||||
|
||||
Loot::DropLoot(participant, m_Parent->GetObjectID(), activityRewards[0].LootMatrixIndex, minCoins, maxCoins);
|
||||
Loot::DropLoot(participant, m_Parent, activityRewards[0].LootMatrixIndex, minCoins, maxCoins);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -617,91 +618,3 @@ void ActivityInstance::SetScore(uint32_t score) {
|
||||
Entity* LobbyPlayer::GetEntity() const {
|
||||
return Game::entityManager->GetEntity(entityID);
|
||||
}
|
||||
|
||||
bool ActivityComponent::OnGetObjectReportInfo(GameMessages::GameMsg& msg) {
|
||||
auto& reportInfo = static_cast<GameMessages::GetObjectReportInfo&>(msg);
|
||||
|
||||
auto& activityInfo = reportInfo.info->PushDebug("Activity");
|
||||
|
||||
auto& instances = activityInfo.PushDebug("Instances: " + std::to_string(m_Instances.size()));
|
||||
size_t i = 0;
|
||||
for (const auto& activityInstance : m_Instances) {
|
||||
if (!activityInstance) continue;
|
||||
auto& instance = instances.PushDebug("Instance " + std::to_string(i++));
|
||||
instance.PushDebug<AMFIntValue>("Score") = activityInstance->GetScore();
|
||||
instance.PushDebug<AMFIntValue>("Next Zone Clone ID") = activityInstance->GetNextZoneCloneID();
|
||||
|
||||
{
|
||||
auto& activityInfo = instance.PushDebug("Activity Info");
|
||||
const auto& instanceActInfo = activityInstance->GetActivityInfo();
|
||||
activityInfo.PushDebug<AMFIntValue>("ActivityID") = instanceActInfo.ActivityID;
|
||||
activityInfo.PushDebug<AMFIntValue>("locStatus") = instanceActInfo.locStatus;
|
||||
activityInfo.PushDebug<AMFIntValue>("instanceMapID") = instanceActInfo.instanceMapID;
|
||||
activityInfo.PushDebug<AMFIntValue>("minTeams") = instanceActInfo.minTeams;
|
||||
activityInfo.PushDebug<AMFIntValue>("maxTeams") = instanceActInfo.maxTeams;
|
||||
activityInfo.PushDebug<AMFIntValue>("minTeamSize") = instanceActInfo.minTeamSize;
|
||||
activityInfo.PushDebug<AMFIntValue>("maxTeamSize") = instanceActInfo.maxTeamSize;
|
||||
activityInfo.PushDebug<AMFIntValue>("waitTime") = instanceActInfo.waitTime;
|
||||
activityInfo.PushDebug<AMFIntValue>("startDelay") = instanceActInfo.startDelay;
|
||||
activityInfo.PushDebug<AMFBoolValue>("requiresUniqueData") = instanceActInfo.requiresUniqueData;
|
||||
activityInfo.PushDebug<AMFIntValue>("leaderboardType") = instanceActInfo.leaderboardType;
|
||||
activityInfo.PushDebug<AMFBoolValue>("localize") = instanceActInfo.localize;
|
||||
activityInfo.PushDebug<AMFIntValue>("optionalCostLOT") = instanceActInfo.optionalCostLOT;
|
||||
activityInfo.PushDebug<AMFIntValue>("optionalCostCount") = instanceActInfo.optionalCostCount;
|
||||
activityInfo.PushDebug<AMFBoolValue>("showUIRewards") = instanceActInfo.showUIRewards;
|
||||
activityInfo.PushDebug<AMFIntValue>("CommunityActivityFlagID") = instanceActInfo.CommunityActivityFlagID;
|
||||
activityInfo.PushDebug<AMFStringValue>("gate_version") = instanceActInfo.gate_version;
|
||||
activityInfo.PushDebug<AMFBoolValue>("noTeamLootOnDeath") = instanceActInfo.noTeamLootOnDeath;
|
||||
activityInfo.PushDebug<AMFDoubleValue>("optionalPercentage") = instanceActInfo.optionalPercentage;
|
||||
}
|
||||
|
||||
auto& participants = instance.PushDebug("Participants");
|
||||
for (const auto* participant : activityInstance->GetParticipants()) {
|
||||
if (!participant) continue;
|
||||
auto* character = participant->GetCharacter();
|
||||
if (!character) continue;
|
||||
participants.PushDebug<AMFStringValue>(std::to_string(participant->GetObjectID()) + ": " + character->GetName()) = "";
|
||||
}
|
||||
}
|
||||
|
||||
auto& queue = activityInfo.PushDebug("Queue");
|
||||
i = 0;
|
||||
for (const auto& lobbyQueue : m_Queue) {
|
||||
auto& lobby = queue.PushDebug("Lobby " + std::to_string(i++));
|
||||
lobby.PushDebug<AMFDoubleValue>("Timer") = lobbyQueue->timer;
|
||||
|
||||
auto& players = lobby.PushDebug("Players");
|
||||
for (const auto* player : lobbyQueue->players) {
|
||||
if (!player) continue;
|
||||
auto* playerEntity = player->GetEntity();
|
||||
if (!playerEntity) continue;
|
||||
auto* character = playerEntity->GetCharacter();
|
||||
if (!character) continue;
|
||||
|
||||
players.PushDebug<AMFStringValue>(std::to_string(playerEntity->GetObjectID()) + ": " + character->GetName()) = player->ready ? "Ready" : "Not Ready";
|
||||
}
|
||||
}
|
||||
|
||||
auto& activityPlayers = activityInfo.PushDebug("Activity Players");
|
||||
for (const auto* activityPlayer : m_ActivityPlayers) {
|
||||
if (!activityPlayer) continue;
|
||||
auto* const activityPlayerEntity = Game::entityManager->GetEntity(activityPlayer->playerID);
|
||||
if (!activityPlayerEntity) continue;
|
||||
auto* character = activityPlayerEntity->GetCharacter();
|
||||
if (!character) continue;
|
||||
|
||||
auto& playerData = activityPlayers.PushDebug(std::to_string(activityPlayer->playerID) + " " + character->GetName());
|
||||
|
||||
auto& scores = playerData.PushDebug("Scores");
|
||||
for (size_t i = 0; i < 10; ++i) {
|
||||
scores.PushDebug<AMFDoubleValue>(std::to_string(i)) = activityPlayer->values[i];
|
||||
}
|
||||
}
|
||||
|
||||
auto& lootMatrices = activityInfo.PushDebug("Loot Matrices");
|
||||
for (const auto& [activityRating, lootMatrixID] : m_ActivityLootMatrices) {
|
||||
lootMatrices.PushDebug<AMFIntValue>("Loot Matrix " + std::to_string(activityRating)) = lootMatrixID;
|
||||
}
|
||||
activityInfo.PushDebug<AMFIntValue>("ActivityID") = m_ActivityID;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -9,10 +9,6 @@
|
||||
|
||||
#include "CDActivitiesTable.h"
|
||||
|
||||
namespace GameMessages {
|
||||
class GameMsg;
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents an instance of an activity, having participants and score
|
||||
*/
|
||||
@@ -64,10 +60,6 @@ public:
|
||||
* Currently unused
|
||||
*/
|
||||
void SetScore(uint32_t score);
|
||||
|
||||
[[nodiscard]] uint32_t GetNextZoneCloneID() const noexcept { return m_NextZoneCloneID; }
|
||||
|
||||
const CDActivities& GetActivityInfo() const noexcept { return m_ActivityInfo; }
|
||||
private:
|
||||
|
||||
/**
|
||||
@@ -83,12 +75,12 @@ private:
|
||||
/**
|
||||
* The database information for this activity
|
||||
*/
|
||||
CDActivities m_ActivityInfo{};
|
||||
CDActivities m_ActivityInfo;
|
||||
|
||||
/**
|
||||
* The entity that owns this activity (the entity that has the ScriptedActivityComponent)
|
||||
*/
|
||||
Entity* m_Parent{};
|
||||
Entity* m_Parent;
|
||||
|
||||
/**
|
||||
* All the participants of this activity
|
||||
@@ -349,7 +341,6 @@ public:
|
||||
uint32_t GetLootMatrixForTeamSize(uint32_t teamSize) { return m_ActivityLootMatrices[teamSize]; }
|
||||
private:
|
||||
|
||||
bool OnGetObjectReportInfo(GameMessages::GameMsg& msg);
|
||||
/**
|
||||
* The database information for this activity
|
||||
*/
|
||||
|
||||
@@ -767,7 +767,7 @@ void BaseCombatAIComponent::LookAt(const NiPoint3& point) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_Parent->SetRotation(QuatUtils::LookAt(m_Parent->GetPosition(), point));
|
||||
m_Parent->SetRotation(NiQuaternion::LookAt(m_Parent->GetPosition(), point));
|
||||
}
|
||||
|
||||
void BaseCombatAIComponent::SetDisabled(bool value) {
|
||||
|
||||
@@ -77,4 +77,4 @@ target_include_directories(dComponents PUBLIC "."
|
||||
)
|
||||
target_precompile_headers(dComponents REUSE_FROM dGameBase)
|
||||
|
||||
target_link_libraries(dComponents INTERFACE dBehaviors PRIVATE glm::glm)
|
||||
target_link_libraries(dComponents INTERFACE dBehaviors)
|
||||
|
||||
@@ -49,13 +49,19 @@ CharacterComponent::CharacterComponent(Entity* parent, Character* character, con
|
||||
m_LastUpdateTimestamp = std::time(nullptr);
|
||||
m_SystemAddress = systemAddress;
|
||||
|
||||
RegisterMsg(MessageType::Game::GET_OBJECT_REPORT_INFO, this, &CharacterComponent::OnGetObjectReportInfo);
|
||||
RegisterMsg(MessageType::Game::REQUEST_SERVER_OBJECT_INFO, this, &CharacterComponent::OnRequestServerObjectInfo);
|
||||
}
|
||||
|
||||
bool CharacterComponent::OnGetObjectReportInfo(GameMessages::GameMsg& msg) {
|
||||
auto& reportInfo = static_cast<GameMessages::GetObjectReportInfo&>(msg);
|
||||
bool CharacterComponent::OnRequestServerObjectInfo(GameMessages::GameMsg& msg) {
|
||||
auto& request = static_cast<GameMessages::RequestServerObjectInfo&>(msg);
|
||||
AMFArrayValue response;
|
||||
|
||||
auto& cmptType = reportInfo.info->PushDebug("Character");
|
||||
response.Insert("visible", true);
|
||||
response.Insert("objectID", std::to_string(request.targetForReport));
|
||||
response.Insert("serverInfo", true);
|
||||
|
||||
auto& data = *response.InsertArray("data");
|
||||
auto& cmptType = data.PushDebug("Character");
|
||||
|
||||
cmptType.PushDebug<AMFIntValue>("Component ID") = GeneralUtils::ToUnderlying(ComponentType);
|
||||
cmptType.PushDebug<AMFIntValue>("Character's account ID") = m_Character->GetParentUser()->GetAccountID();
|
||||
@@ -66,13 +72,6 @@ bool CharacterComponent::OnGetObjectReportInfo(GameMessages::GameMsg& msg) {
|
||||
cmptType.PushDebug<AMFStringValue>("Total currency") = std::to_string(m_Character->GetCoins());
|
||||
cmptType.PushDebug<AMFStringValue>("Currency able to be picked up") = std::to_string(m_DroppedCoins);
|
||||
cmptType.PushDebug<AMFStringValue>("Tooltip flags value") = "0";
|
||||
auto& vl = cmptType.PushDebug("Visited Levels");
|
||||
for (const auto zoneID : m_VisitedLevels) {
|
||||
std::stringstream sstream;
|
||||
sstream << "MapID: " << zoneID.GetMapID() << " CloneID: " << zoneID.GetCloneID();
|
||||
vl.PushDebug<AMFStringValue>(sstream.str()) = "";
|
||||
}
|
||||
|
||||
// visited locations
|
||||
cmptType.PushDebug<AMFBoolValue>("is a GM") = m_GMLevel > eGameMasterLevel::CIVILIAN;
|
||||
cmptType.PushDebug<AMFBoolValue>("Has PVP flag turned on") = m_PvpEnabled;
|
||||
@@ -84,6 +83,9 @@ bool CharacterComponent::OnGetObjectReportInfo(GameMessages::GameMsg& msg) {
|
||||
cmptType.PushDebug<AMFIntValue>("Current Activity Type") = GeneralUtils::ToUnderlying(m_CurrentActivity);
|
||||
cmptType.PushDebug<AMFDoubleValue>("Property Clone ID") = m_Character->GetPropertyCloneID();
|
||||
|
||||
GameMessages::SendUIMessageServerToSingleClient("ToggleObjectDebugger", response, m_Parent->GetSystemAddress());
|
||||
|
||||
LOG("Handled!");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -331,7 +331,7 @@ public:
|
||||
void LoadVisitedLevelsXml(const tinyxml2::XMLElement& doc);
|
||||
private:
|
||||
|
||||
bool OnGetObjectReportInfo(GameMessages::GameMsg& msg);
|
||||
bool OnRequestServerObjectInfo(GameMessages::GameMsg& msg);
|
||||
|
||||
/**
|
||||
* The map of active venture vision effects
|
||||
@@ -622,7 +622,7 @@ private:
|
||||
|
||||
NiPoint3 m_respawnPos;
|
||||
|
||||
NiQuaternion m_respawnRot = QuatUtils::IDENTITY;
|
||||
NiQuaternion m_respawnRot;
|
||||
|
||||
std::map<LWOOBJID, Loot::Info> m_DroppedLoot;
|
||||
|
||||
|
||||
@@ -56,16 +56,10 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
inline void RegisterMsg(const MessageType::Game msgId, auto* self, const auto handler) {
|
||||
void RegisterMsg(const MessageType::Game msgId, auto* self, const auto handler) {
|
||||
m_Parent->RegisterMsg(msgId, std::bind(handler, self, std::placeholders::_1));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void RegisterMsg(auto* self, const auto handler) {
|
||||
T msg;
|
||||
RegisterMsg(msg.msgId, self, handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* The entity that owns this component
|
||||
*/
|
||||
|
||||
@@ -14,12 +14,8 @@
|
||||
#include "dZoneManager.h"
|
||||
#include "LevelProgressionComponent.h"
|
||||
#include "eStateChangeType.h"
|
||||
#include "StringifiedEnum.h"
|
||||
#include "Amf3.h"
|
||||
|
||||
ControllablePhysicsComponent::ControllablePhysicsComponent(Entity* entity, int32_t componentId) : PhysicsComponent(entity, componentId) {
|
||||
RegisterMsg(MessageType::Game::GET_OBJECT_REPORT_INFO, this, &ControllablePhysicsComponent::OnGetObjectReportInfo);
|
||||
|
||||
m_Velocity = {};
|
||||
m_AngularVelocity = {};
|
||||
m_InJetpackMode = false;
|
||||
@@ -358,58 +354,3 @@ void ControllablePhysicsComponent::SetStunImmunity(
|
||||
bImmuneToStunUseItem
|
||||
);
|
||||
}
|
||||
|
||||
bool ControllablePhysicsComponent::OnGetObjectReportInfo(GameMessages::GameMsg& msg) {
|
||||
PhysicsComponent::OnGetObjectReportInfo(msg);
|
||||
auto& reportInfo = static_cast<GameMessages::GetObjectReportInfo&>(msg);
|
||||
auto& info = reportInfo.subCategory->PushDebug("Controllable Info");
|
||||
|
||||
auto& vel = info.PushDebug("Velocity");
|
||||
vel.PushDebug<AMFDoubleValue>("x") = m_Velocity.x;
|
||||
vel.PushDebug<AMFDoubleValue>("y") = m_Velocity.y;
|
||||
vel.PushDebug<AMFDoubleValue>("z") = m_Velocity.z;
|
||||
|
||||
auto& angularVelocity = info.PushDebug("Angular Velocity");
|
||||
angularVelocity.PushDebug<AMFDoubleValue>("x") = m_AngularVelocity.x;
|
||||
angularVelocity.PushDebug<AMFDoubleValue>("y") = m_AngularVelocity.y;
|
||||
angularVelocity.PushDebug<AMFDoubleValue>("z") = m_AngularVelocity.z;
|
||||
|
||||
info.PushDebug<AMFBoolValue>("Is On Ground") = m_IsOnGround;
|
||||
info.PushDebug<AMFBoolValue>("Is On Rail") = m_IsOnRail;
|
||||
info.PushDebug<AMFBoolValue>("Is In Jetpack Mode") = m_InJetpackMode;
|
||||
info.PushDebug<AMFBoolValue>("Is Jetpack Flying") = m_JetpackFlying;
|
||||
info.PushDebug<AMFBoolValue>("Is Bypassing Jetpack Checks") = m_JetpackBypassChecks;
|
||||
info.PushDebug<AMFIntValue>("Jetpack Effect ID") = m_JetpackEffectID;
|
||||
info.PushDebug<AMFDoubleValue>("Speed Multiplier") = m_SpeedMultiplier;
|
||||
info.PushDebug<AMFDoubleValue>("Gravity Scale") = m_GravityScale;
|
||||
info.PushDebug<AMFBoolValue>("Is Static") = m_Static;
|
||||
|
||||
auto& pickupRadii = info.PushDebug("Active Pickup Radius Scales");
|
||||
|
||||
size_t i = 0;
|
||||
for (const auto& scale : m_ActivePickupRadiusScales) {
|
||||
pickupRadii.PushDebug<AMFStringValue>(std::to_string(i++) + " " + std::to_string(scale)) = "";
|
||||
}
|
||||
|
||||
info.PushDebug<AMFDoubleValue>("Largest Pickup Radius") = m_PickupRadius;
|
||||
info.PushDebug<AMFBoolValue>("Is Teleporting") = m_IsTeleporting;
|
||||
|
||||
auto& activeSpeedBoosts = info.PushDebug("Active Speed Boosts");
|
||||
i = 0;
|
||||
for (const auto& boost : m_ActiveSpeedBoosts) {
|
||||
activeSpeedBoosts.PushDebug<AMFStringValue>(std::to_string(i++) + " " + std::to_string(boost)) = "";
|
||||
}
|
||||
|
||||
info.PushDebug<AMFDoubleValue>("Speed Boost") = m_SpeedBoost;
|
||||
info.PushDebug<AMFBoolValue>("Is In Bubble") = m_IsInBubble;
|
||||
info.PushDebug<AMFStringValue>("Bubble Type") = StringifiedEnum::ToString(m_BubbleType).data();
|
||||
info.PushDebug<AMFBoolValue>("Special Anims") = m_SpecialAnims;
|
||||
info.PushDebug<AMFIntValue>("Immune To Stun Attack Count") = m_ImmuneToStunAttackCount;
|
||||
info.PushDebug<AMFIntValue>("Immune To Stun Equip Count") = m_ImmuneToStunEquipCount;
|
||||
info.PushDebug<AMFIntValue>("Immune To Stun Interact Count") = m_ImmuneToStunInteractCount;
|
||||
info.PushDebug<AMFIntValue>("Immune To Stun Jump Count") = m_ImmuneToStunJumpCount;
|
||||
info.PushDebug<AMFIntValue>("Immune To Stun Move Count") = m_ImmuneToStunMoveCount;
|
||||
info.PushDebug<AMFIntValue>("Immune To Stun Turn Count") = m_ImmuneToStunTurnCount;
|
||||
info.PushDebug<AMFIntValue>("Immune To Stun UseItem Count") = m_ImmuneToStunUseItemCount;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
#ifndef CONTROLLABLEPHYSICSCOMPONENT_H
|
||||
#define CONTROLLABLEPHYSICSCOMPONENT_H
|
||||
|
||||
#include "PhysicsComponent.h"
|
||||
#include "eReplicaComponentType.h"
|
||||
#include "dCommonVars.h"
|
||||
#include "RakNetTypes.h"
|
||||
#include "NiPoint3.h"
|
||||
#include "NiQuaternion.h"
|
||||
#include "tinyxml2.h"
|
||||
#include "PhysicsComponent.h"
|
||||
#include "dpCollisionChecks.h"
|
||||
#include "PhantomPhysicsComponent.h"
|
||||
#include "eBubbleType.h"
|
||||
|
||||
namespace tinyxml2 {
|
||||
class XMLDocument;
|
||||
}
|
||||
#include "eReplicaComponentType.h"
|
||||
|
||||
class Entity;
|
||||
class dpEntity;
|
||||
@@ -283,8 +281,6 @@ public:
|
||||
const bool GetImmuneToStunUseItem() { return m_ImmuneToStunUseItemCount > 0;};
|
||||
|
||||
private:
|
||||
|
||||
bool OnGetObjectReportInfo(GameMessages::GameMsg& msg);
|
||||
/**
|
||||
* The entity that owns this component
|
||||
*/
|
||||
@@ -378,7 +374,7 @@ private:
|
||||
/**
|
||||
* The active speed boost for this entity
|
||||
*/
|
||||
float m_SpeedBoost = 500.0f;
|
||||
float m_SpeedBoost;
|
||||
|
||||
/*
|
||||
* If Bubble info is dirty
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include "BuffComponent.h"
|
||||
#include "SkillComponent.h"
|
||||
#include "Item.h"
|
||||
#include "Amf3.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
@@ -30,7 +29,6 @@
|
||||
#include "CharacterComponent.h"
|
||||
#include "PossessableComponent.h"
|
||||
#include "PossessorComponent.h"
|
||||
#include "ModelComponent.h"
|
||||
#include "InventoryComponent.h"
|
||||
#include "dZoneManager.h"
|
||||
#include "WorldConfig.h"
|
||||
@@ -44,7 +42,6 @@ Implementation<bool, const Entity*> DestroyableComponent::IsEnemyImplentation;
|
||||
Implementation<bool, const Entity*> DestroyableComponent::IsFriendImplentation;
|
||||
|
||||
DestroyableComponent::DestroyableComponent(Entity* parent) : Component(parent) {
|
||||
using namespace GameMessages;
|
||||
m_iArmor = 0;
|
||||
m_fMaxArmor = 0.0f;
|
||||
m_iImagination = 0;
|
||||
@@ -81,9 +78,6 @@ DestroyableComponent::DestroyableComponent(Entity* parent) : Component(parent) {
|
||||
m_DeathBehavior = -1;
|
||||
|
||||
m_DamageCooldownTimer = 0.0f;
|
||||
|
||||
RegisterMsg<GetObjectReportInfo>(this, &DestroyableComponent::OnGetObjectReportInfo);
|
||||
RegisterMsg<GameMessages::SetFaction>(this, &DestroyableComponent::OnSetFaction);
|
||||
}
|
||||
|
||||
DestroyableComponent::~DestroyableComponent() {
|
||||
@@ -581,14 +575,6 @@ void DestroyableComponent::Damage(uint32_t damage, const LWOOBJID source, uint32
|
||||
return;
|
||||
}
|
||||
|
||||
// Client does the same check, so we're doing it too
|
||||
auto* const modelComponent = m_Parent->GetComponent<ModelComponent>();
|
||||
if (modelComponent) {
|
||||
modelComponent->OnHit();
|
||||
// Don't actually deal the damage so the model doesn't die
|
||||
return;
|
||||
}
|
||||
|
||||
// If this entity has damage reduction, reduce the damage to a minimum of 1
|
||||
if (m_DamageReduction > 0 && damage > 0) {
|
||||
if (damage > m_DamageReduction) {
|
||||
@@ -769,18 +755,18 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType
|
||||
|
||||
auto* member = Game::entityManager->GetEntity(specificOwner);
|
||||
|
||||
if (member) Loot::DropLoot(member, m_Parent->GetObjectID(), lootMatrixId, GetMinCoins(), GetMaxCoins());
|
||||
if (member) Loot::DropLoot(member, m_Parent, lootMatrixId, GetMinCoins(), GetMaxCoins());
|
||||
} else {
|
||||
for (const auto memberId : team->members) { // Free for all
|
||||
auto* member = Game::entityManager->GetEntity(memberId);
|
||||
|
||||
if (member == nullptr) continue;
|
||||
|
||||
Loot::DropLoot(member, m_Parent->GetObjectID(), lootMatrixId, GetMinCoins(), GetMaxCoins());
|
||||
Loot::DropLoot(member, m_Parent, lootMatrixId, GetMinCoins(), GetMaxCoins());
|
||||
}
|
||||
}
|
||||
} else { // drop loot for non team user
|
||||
Loot::DropLoot(owner, m_Parent->GetObjectID(), GetLootMatrixID(), GetMinCoins(), GetMaxCoins());
|
||||
Loot::DropLoot(owner, m_Parent, GetLootMatrixID(), GetMinCoins(), GetMaxCoins());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -798,7 +784,7 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType
|
||||
|
||||
coinsTotal -= coinsToLose;
|
||||
|
||||
Loot::DropLoot(m_Parent, m_Parent->GetObjectID(), -1, coinsToLose, coinsToLose);
|
||||
Loot::DropLoot(m_Parent, m_Parent, -1, coinsToLose, coinsToLose);
|
||||
character->SetCoins(coinsTotal, eLootSourceType::PICKUP);
|
||||
}
|
||||
}
|
||||
@@ -1045,65 +1031,3 @@ void DestroyableComponent::DoHardcoreModeDrops(const LWOOBJID source) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool DestroyableComponent::OnGetObjectReportInfo(GameMessages::GameMsg& msg) {
|
||||
auto& reportInfo = static_cast<GameMessages::GetObjectReportInfo&>(msg);
|
||||
|
||||
auto& destroyableInfo = reportInfo.info->PushDebug("Destroyable");
|
||||
destroyableInfo.PushDebug<AMFIntValue>("Health") = m_iHealth;
|
||||
destroyableInfo.PushDebug<AMFDoubleValue>("Max Health") = m_fMaxHealth;
|
||||
destroyableInfo.PushDebug<AMFIntValue>("Armor") = m_iArmor;
|
||||
destroyableInfo.PushDebug<AMFDoubleValue>("Max Armor") = m_fMaxArmor;
|
||||
destroyableInfo.PushDebug<AMFIntValue>("Imagination") = m_iImagination;
|
||||
destroyableInfo.PushDebug<AMFDoubleValue>("Max Imagination") = m_fMaxImagination;
|
||||
destroyableInfo.PushDebug<AMFIntValue>("Damage To Absorb") = m_DamageToAbsorb;
|
||||
destroyableInfo.PushDebug<AMFBoolValue>("Is GM Immune") = m_IsGMImmune;
|
||||
destroyableInfo.PushDebug<AMFBoolValue>("Is Shielded") = m_IsShielded;
|
||||
destroyableInfo.PushDebug<AMFIntValue>("Attacks To Block") = m_AttacksToBlock;
|
||||
destroyableInfo.PushDebug<AMFIntValue>("Damage Reduction") = m_DamageReduction;
|
||||
auto& factions = destroyableInfo.PushDebug("Factions");
|
||||
size_t i = 0;
|
||||
for (const auto factionID : m_FactionIDs) {
|
||||
factions.PushDebug<AMFStringValue>(std::to_string(i++) + " " + std::to_string(factionID)) = "";
|
||||
}
|
||||
auto& enemyFactions = destroyableInfo.PushDebug("Enemy Factions");
|
||||
i = 0;
|
||||
for (const auto enemyFactionID : m_EnemyFactionIDs) {
|
||||
enemyFactions.PushDebug<AMFStringValue>(std::to_string(i++) + " " + std::to_string(enemyFactionID)) = "";
|
||||
}
|
||||
destroyableInfo.PushDebug<AMFBoolValue>("Is Smashable") = m_IsSmashable;
|
||||
destroyableInfo.PushDebug<AMFBoolValue>("Is Dead") = m_IsDead;
|
||||
destroyableInfo.PushDebug<AMFBoolValue>("Is Smashed") = m_IsSmashed;
|
||||
destroyableInfo.PushDebug<AMFBoolValue>("Is Module Assembly") = m_IsModuleAssembly;
|
||||
destroyableInfo.PushDebug<AMFDoubleValue>("Explode Factor") = m_ExplodeFactor;
|
||||
destroyableInfo.PushDebug<AMFBoolValue>("Has Threats") = m_HasThreats;
|
||||
destroyableInfo.PushDebug<AMFIntValue>("Loot Matrix ID") = m_LootMatrixID;
|
||||
destroyableInfo.PushDebug<AMFIntValue>("Min Coins") = m_MinCoins;
|
||||
destroyableInfo.PushDebug<AMFIntValue>("Max Coins") = m_MaxCoins;
|
||||
destroyableInfo.PushDebug<AMFStringValue>("Killer ID") = std::to_string(m_KillerID);
|
||||
|
||||
// "Scripts"; idk what to do about scripts yet
|
||||
auto& immuneCounts = destroyableInfo.PushDebug("Immune Counts");
|
||||
immuneCounts.PushDebug<AMFIntValue>("Basic Attack") = m_ImmuneToBasicAttackCount;
|
||||
immuneCounts.PushDebug<AMFIntValue>("Damage Over Time") = m_ImmuneToDamageOverTimeCount;
|
||||
immuneCounts.PushDebug<AMFIntValue>("Knockback") = m_ImmuneToKnockbackCount;
|
||||
immuneCounts.PushDebug<AMFIntValue>("Interrupt") = m_ImmuneToInterruptCount;
|
||||
immuneCounts.PushDebug<AMFIntValue>("Speed") = m_ImmuneToSpeedCount;
|
||||
immuneCounts.PushDebug<AMFIntValue>("Imagination Gain") = m_ImmuneToImaginationGainCount;
|
||||
immuneCounts.PushDebug<AMFIntValue>("Imagination Loss") = m_ImmuneToImaginationLossCount;
|
||||
immuneCounts.PushDebug<AMFIntValue>("Quickbuild Interrupt") = m_ImmuneToQuickbuildInterruptCount;
|
||||
immuneCounts.PushDebug<AMFIntValue>("Pull To Point") = m_ImmuneToPullToPointCount;
|
||||
|
||||
destroyableInfo.PushDebug<AMFIntValue>("Death Behavior") = m_DeathBehavior;
|
||||
destroyableInfo.PushDebug<AMFDoubleValue>("Damage Cooldown Timer") = m_DamageCooldownTimer;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DestroyableComponent::OnSetFaction(GameMessages::GameMsg& msg) {
|
||||
auto& modifyFaction = static_cast<GameMessages::SetFaction&>(msg);
|
||||
m_DirtyHealth = true;
|
||||
Game::entityManager->SerializeEntity(m_Parent);
|
||||
SetFaction(modifyFaction.factionID, modifyFaction.bIgnoreChecks);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -9,10 +9,6 @@
|
||||
#include "eReplicaComponentType.h"
|
||||
#include "Implementation.h"
|
||||
|
||||
namespace GameMessages {
|
||||
struct GetObjectReportInfo;
|
||||
};
|
||||
|
||||
namespace CppScripts {
|
||||
class Script;
|
||||
}; //! namespace CppScripts
|
||||
@@ -468,9 +464,6 @@ public:
|
||||
// handle hardcode mode drops
|
||||
void DoHardcoreModeDrops(const LWOOBJID source);
|
||||
|
||||
bool OnGetObjectReportInfo(GameMessages::GameMsg& msg);
|
||||
bool OnSetFaction(GameMessages::GameMsg& msg);
|
||||
|
||||
static Implementation<bool, const Entity*> IsEnemyImplentation;
|
||||
static Implementation<bool, const Entity*> IsFriendImplentation;
|
||||
|
||||
@@ -598,7 +591,7 @@ private:
|
||||
/**
|
||||
* The ID of the entity that smashed this entity, if any
|
||||
*/
|
||||
LWOOBJID m_KillerID{};
|
||||
LWOOBJID m_KillerID;
|
||||
|
||||
/**
|
||||
* The list of callbacks that will be called when this entity gets hit
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
#include "HavokVehiclePhysicsComponent.h"
|
||||
#include "EntityManager.h"
|
||||
#include "Amf3.h"
|
||||
|
||||
HavokVehiclePhysicsComponent::HavokVehiclePhysicsComponent(Entity* parent, int32_t componentId) : PhysicsComponent(parent, componentId) {
|
||||
RegisterMsg(MessageType::Game::GET_OBJECT_REPORT_INFO, this, &HavokVehiclePhysicsComponent::OnGetObjectReportInfo);
|
||||
|
||||
m_Velocity = NiPoint3Constant::ZERO;
|
||||
m_AngularVelocity = NiPoint3Constant::ZERO;
|
||||
m_IsOnGround = true;
|
||||
@@ -101,34 +98,3 @@ void HavokVehiclePhysicsComponent::Serialize(RakNet::BitStream& outBitStream, bo
|
||||
|
||||
outBitStream.Write0();
|
||||
}
|
||||
|
||||
bool HavokVehiclePhysicsComponent::OnGetObjectReportInfo(GameMessages::GameMsg& msg) {
|
||||
PhysicsComponent::OnGetObjectReportInfo(msg);
|
||||
auto& reportInfo = static_cast<GameMessages::GetObjectReportInfo&>(msg);
|
||||
if (!reportInfo.subCategory) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto& info = reportInfo.subCategory->PushDebug("Havok Vehicle Physics Info");
|
||||
|
||||
auto& velocity = info.PushDebug("Velocity");
|
||||
velocity.PushDebug<AMFDoubleValue>("x") = m_Velocity.x;
|
||||
velocity.PushDebug<AMFDoubleValue>("y") = m_Velocity.y;
|
||||
velocity.PushDebug<AMFDoubleValue>("z") = m_Velocity.z;
|
||||
|
||||
auto& angularVelocity = info.PushDebug("Angular Velocity");
|
||||
angularVelocity.PushDebug<AMFDoubleValue>("x") = m_AngularVelocity.x;
|
||||
angularVelocity.PushDebug<AMFDoubleValue>("y") = m_AngularVelocity.y;
|
||||
angularVelocity.PushDebug<AMFDoubleValue>("z") = m_AngularVelocity.z;
|
||||
|
||||
info.PushDebug<AMFBoolValue>("Is On Ground") = m_IsOnGround;
|
||||
info.PushDebug<AMFBoolValue>("Is On Rail") = m_IsOnRail;
|
||||
info.PushDebug<AMFIntValue>("End Behavior") = m_EndBehavior;
|
||||
|
||||
auto& remoteInputInfo = info.PushDebug("Remote Input Info");
|
||||
remoteInputInfo.PushDebug<AMFDoubleValue>("Remote Input X") = m_RemoteInputInfo.m_RemoteInputX;
|
||||
remoteInputInfo.PushDebug<AMFDoubleValue>("Remote Input Y") = m_RemoteInputInfo.m_RemoteInputY;
|
||||
remoteInputInfo.PushDebug<AMFBoolValue>("Is Powersliding") = m_RemoteInputInfo.m_IsPowersliding;
|
||||
remoteInputInfo.PushDebug<AMFBoolValue>("Is Modified") = m_RemoteInputInfo.m_IsModified;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -68,8 +68,6 @@ public:
|
||||
void SetRemoteInputInfo(const RemoteInputInfo&);
|
||||
|
||||
private:
|
||||
bool OnGetObjectReportInfo(GameMessages::GameMsg& msg);
|
||||
|
||||
NiPoint3 m_Velocity;
|
||||
NiPoint3 m_AngularVelocity;
|
||||
|
||||
|
||||
@@ -1279,7 +1279,7 @@ void InventoryComponent::SpawnPet(Item* item) {
|
||||
EntityInfo info{};
|
||||
info.lot = item->GetLot();
|
||||
info.pos = m_Parent->GetPosition();
|
||||
info.rot = QuatUtils::IDENTITY;
|
||||
info.rot = NiQuaternionConstant::IDENTITY;
|
||||
info.spawnerID = m_Parent->GetObjectID();
|
||||
|
||||
auto* pet = Game::entityManager->CreateEntity(info);
|
||||
|
||||
@@ -7,23 +7,20 @@
|
||||
#include "BehaviorStates.h"
|
||||
#include "ControlBehaviorMsgs.h"
|
||||
#include "tinyxml2.h"
|
||||
#include "InventoryComponent.h"
|
||||
#include "SimplePhysicsComponent.h"
|
||||
#include "eObjectBits.h"
|
||||
|
||||
#include "Database.h"
|
||||
#include "DluAssert.h"
|
||||
|
||||
ModelComponent::ModelComponent(Entity* parent) : Component(parent) {
|
||||
using namespace GameMessages;
|
||||
m_OriginalPosition = m_Parent->GetDefaultPosition();
|
||||
m_OriginalRotation = m_Parent->GetDefaultRotation();
|
||||
m_IsPaused = false;
|
||||
m_NumListeningInteract = 0;
|
||||
|
||||
m_userModelID = m_Parent->GetVarAs<LWOOBJID>(u"userModelID");
|
||||
RegisterMsg<RequestUse>(this, &ModelComponent::OnRequestUse);
|
||||
RegisterMsg<ResetModelToDefaults>(this, &ModelComponent::OnResetModelToDefaults);
|
||||
RegisterMsg(MessageType::Game::REQUEST_USE, this, &ModelComponent::OnRequestUse);
|
||||
RegisterMsg(MessageType::Game::RESET_MODEL_TO_DEFAULTS, this, &ModelComponent::OnResetModelToDefaults);
|
||||
}
|
||||
|
||||
bool ModelComponent::OnResetModelToDefaults(GameMessages::GameMsg& msg) {
|
||||
@@ -38,17 +35,8 @@ bool ModelComponent::OnResetModelToDefaults(GameMessages::GameMsg& msg) {
|
||||
m_Parent->SetRotation(m_OriginalRotation);
|
||||
m_Parent->SetVelocity(NiPoint3Constant::ZERO);
|
||||
|
||||
m_Speed = 3.0f;
|
||||
m_NumListeningInteract = 0;
|
||||
m_NumActiveUnSmash = 0;
|
||||
|
||||
m_NumActiveAttack = 0;
|
||||
GameMessages::SetFaction set{};
|
||||
set.target = m_Parent->GetObjectID();
|
||||
set.factionID = -1; // Default faction for smashables
|
||||
set.bIgnoreChecks = true; // Remove the attack faction
|
||||
set.Send();
|
||||
|
||||
m_Dirty = true;
|
||||
Game::entityManager->SerializeEntity(GetParent());
|
||||
|
||||
@@ -72,12 +60,6 @@ void ModelComponent::Update(float deltaTime) {
|
||||
for (auto& behavior : m_Behaviors) {
|
||||
behavior.Update(deltaTime, *this);
|
||||
}
|
||||
|
||||
if (!m_RestartAtEndOfFrame) return;
|
||||
|
||||
GameMessages::ResetModelToDefaults reset{};
|
||||
OnResetModelToDefaults(reset);
|
||||
m_RestartAtEndOfFrame = false;
|
||||
}
|
||||
|
||||
void ModelComponent::LoadBehaviors() {
|
||||
@@ -85,30 +67,25 @@ void ModelComponent::LoadBehaviors() {
|
||||
for (const auto& behavior : behaviors) {
|
||||
if (behavior.empty()) continue;
|
||||
|
||||
const auto behaviorId = GeneralUtils::TryParse<LWOOBJID>(behavior);
|
||||
const auto behaviorId = GeneralUtils::TryParse<int32_t>(behavior);
|
||||
if (!behaviorId.has_value() || behaviorId.value() == 0) continue;
|
||||
|
||||
// add behavior at the back
|
||||
LoadBehavior(behaviorId.value(), m_Behaviors.size(), false);
|
||||
}
|
||||
}
|
||||
LOG_DEBUG("Loading behavior %d", behaviorId.value());
|
||||
auto& inserted = m_Behaviors.emplace_back();
|
||||
inserted.SetBehaviorId(*behaviorId);
|
||||
|
||||
void ModelComponent::LoadBehavior(const LWOOBJID behaviorID, const size_t index, const bool isIndexed) {
|
||||
LOG_DEBUG("Loading behavior %d", behaviorID);
|
||||
auto& inserted = *m_Behaviors.emplace(m_Behaviors.begin() + index, PropertyBehavior(isIndexed));
|
||||
inserted.SetBehaviorId(behaviorID);
|
||||
const auto behaviorStr = Database::Get()->GetBehavior(behaviorId.value());
|
||||
|
||||
const auto behaviorStr = Database::Get()->GetBehavior(behaviorID);
|
||||
tinyxml2::XMLDocument behaviorXml;
|
||||
auto res = behaviorXml.Parse(behaviorStr.c_str(), behaviorStr.size());
|
||||
LOG_DEBUG("Behavior %i %d: %s", res, behaviorId.value(), behaviorStr.c_str());
|
||||
|
||||
tinyxml2::XMLDocument behaviorXml;
|
||||
auto res = behaviorXml.Parse(behaviorStr.c_str(), behaviorStr.size());
|
||||
LOG_DEBUG("Behavior %i %llu: %s", res, behaviorID, behaviorStr.c_str());
|
||||
|
||||
const auto* const behaviorRoot = behaviorXml.FirstChildElement("Behavior");
|
||||
if (behaviorRoot) {
|
||||
const auto* const behaviorRoot = behaviorXml.FirstChildElement("Behavior");
|
||||
if (!behaviorRoot) {
|
||||
LOG("Failed to load behavior %d due to missing behavior root", behaviorId.value());
|
||||
continue;
|
||||
}
|
||||
inserted.Deserialize(*behaviorRoot);
|
||||
} else {
|
||||
LOG("Failed to load behavior %d due to missing behavior root", behaviorID);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,12 +116,8 @@ void ModelComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialU
|
||||
if (bIsInitialUpdate) outBitStream.Write0(); // We are not writing model editing info
|
||||
}
|
||||
|
||||
void ModelComponent::UpdatePendingBehaviorId(const LWOOBJID newId, const LWOOBJID oldId) {
|
||||
for (auto& behavior : m_Behaviors) {
|
||||
if (behavior.GetBehaviorId() != oldId) continue;
|
||||
behavior.SetBehaviorId(newId);
|
||||
behavior.SetIsLoot(false);
|
||||
}
|
||||
void ModelComponent::UpdatePendingBehaviorId(const int32_t newId) {
|
||||
for (auto& behavior : m_Behaviors) if (behavior.GetBehaviorId() == -1) behavior.SetBehaviorId(newId);
|
||||
}
|
||||
|
||||
void ModelComponent::SendBehaviorListToClient(AMFArrayValue& args) const {
|
||||
@@ -161,7 +134,7 @@ void ModelComponent::VerifyBehaviors() {
|
||||
for (auto& behavior : m_Behaviors) behavior.VerifyLastEditedState();
|
||||
}
|
||||
|
||||
void ModelComponent::SendBehaviorBlocksToClient(const LWOOBJID behaviorToSend, AMFArrayValue& args) const {
|
||||
void ModelComponent::SendBehaviorBlocksToClient(int32_t behaviorToSend, AMFArrayValue& args) const {
|
||||
args.Insert("BehaviorID", std::to_string(behaviorToSend));
|
||||
args.Insert("objectID", std::to_string(m_Parent->GetObjectID()));
|
||||
for (auto& behavior : m_Behaviors) if (behavior.GetBehaviorId() == behaviorToSend) behavior.SendBehaviorBlocksToClient(args);
|
||||
@@ -170,21 +143,8 @@ void ModelComponent::SendBehaviorBlocksToClient(const LWOOBJID behaviorToSend, A
|
||||
void ModelComponent::AddBehavior(AddMessage& msg) {
|
||||
// Can only have 1 of the loot behaviors
|
||||
for (auto& behavior : m_Behaviors) if (behavior.GetBehaviorId() == msg.GetBehaviorId()) return;
|
||||
|
||||
// If we're loading a behavior from an ADD, it is from the database.
|
||||
// Mark it as not modified by default to prevent wasting persistentIDs.
|
||||
LoadBehavior(msg.GetBehaviorId(), msg.GetBehaviorIndex(), true);
|
||||
auto& insertedBehavior = m_Behaviors[msg.GetBehaviorIndex()];
|
||||
|
||||
auto* const playerEntity = Game::entityManager->GetEntity(msg.GetOwningPlayerID());
|
||||
if (playerEntity) {
|
||||
auto* inventoryComponent = playerEntity->GetComponent<InventoryComponent>();
|
||||
if (inventoryComponent) {
|
||||
// Check if this behavior is able to be found via lot (if so, its a loot behavior).
|
||||
insertedBehavior.SetIsLoot(inventoryComponent->FindItemByLot(msg.GetBehaviorId(), eInventoryType::BEHAVIORS));
|
||||
}
|
||||
}
|
||||
|
||||
m_Behaviors.insert(m_Behaviors.begin() + msg.GetBehaviorIndex(), PropertyBehavior());
|
||||
m_Behaviors.at(msg.GetBehaviorIndex()).HandleMsg(msg);
|
||||
auto* const simplePhysComponent = m_Parent->GetComponent<SimplePhysicsComponent>();
|
||||
if (simplePhysComponent) {
|
||||
simplePhysComponent->SetPhysicsMotionState(1);
|
||||
@@ -192,41 +152,8 @@ void ModelComponent::AddBehavior(AddMessage& msg) {
|
||||
}
|
||||
}
|
||||
|
||||
std::string ModelComponent::SaveBehavior(const PropertyBehavior& behavior) const {
|
||||
tinyxml2::XMLDocument doc;
|
||||
auto* root = doc.NewElement("Behavior");
|
||||
behavior.Serialize(*root);
|
||||
doc.InsertFirstChild(root);
|
||||
|
||||
tinyxml2::XMLPrinter printer(0, true, 0);
|
||||
doc.Print(&printer);
|
||||
return printer.CStr();
|
||||
}
|
||||
|
||||
void ModelComponent::RemoveBehavior(MoveToInventoryMessage& msg, const bool keepItem) {
|
||||
void ModelComponent::MoveToInventory(MoveToInventoryMessage& msg) {
|
||||
if (msg.GetBehaviorIndex() >= m_Behaviors.size() || m_Behaviors.at(msg.GetBehaviorIndex()).GetBehaviorId() != msg.GetBehaviorId()) return;
|
||||
const auto behavior = m_Behaviors[msg.GetBehaviorIndex()];
|
||||
if (keepItem) {
|
||||
auto* const playerEntity = Game::entityManager->GetEntity(msg.GetOwningPlayerID());
|
||||
if (playerEntity) {
|
||||
auto* const inventoryComponent = playerEntity->GetComponent<InventoryComponent>();
|
||||
if (inventoryComponent && !behavior.GetIsLoot()) {
|
||||
// config is owned by the item
|
||||
std::vector<LDFBaseData*> config;
|
||||
config.push_back(new LDFData<std::string>(u"userModelName", behavior.GetName()));
|
||||
inventoryComponent->AddItem(7965, 1, eLootSourceType::PROPERTY, eInventoryType::BEHAVIORS, config, LWOOBJID_EMPTY, true, false, msg.GetBehaviorId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// save the behavior before deleting it so players can re-add them
|
||||
IBehaviors::Info info{};
|
||||
info.behaviorId = msg.GetBehaviorId();
|
||||
info.behaviorInfo = SaveBehavior(behavior);
|
||||
info.characterId = msg.GetOwningPlayerID();
|
||||
|
||||
Database::Get()->AddBehavior(info);
|
||||
|
||||
m_Behaviors.erase(m_Behaviors.begin() + msg.GetBehaviorIndex());
|
||||
// TODO move to the inventory
|
||||
if (m_Behaviors.empty()) {
|
||||
@@ -238,14 +165,22 @@ void ModelComponent::RemoveBehavior(MoveToInventoryMessage& msg, const bool keep
|
||||
}
|
||||
}
|
||||
|
||||
std::array<std::pair<LWOOBJID, std::string>, 5> ModelComponent::GetBehaviorsForSave() const {
|
||||
std::array<std::pair<LWOOBJID, std::string>, 5> toReturn{};
|
||||
std::array<std::pair<int32_t, std::string>, 5> ModelComponent::GetBehaviorsForSave() const {
|
||||
std::array<std::pair<int32_t, std::string>, 5> toReturn{};
|
||||
for (auto i = 0; i < m_Behaviors.size(); i++) {
|
||||
const auto& behavior = m_Behaviors.at(i);
|
||||
if (behavior.GetBehaviorId() == -1) continue;
|
||||
auto& [id, behaviorData] = toReturn[i];
|
||||
id = behavior.GetBehaviorId();
|
||||
behaviorData = SaveBehavior(behavior);
|
||||
|
||||
tinyxml2::XMLDocument doc;
|
||||
auto* root = doc.NewElement("Behavior");
|
||||
behavior.Serialize(*root);
|
||||
doc.InsertFirstChild(root);
|
||||
|
||||
tinyxml2::XMLPrinter printer(0, true, 0);
|
||||
doc.Print(&printer);
|
||||
behaviorData = printer.CStr();
|
||||
}
|
||||
return toReturn;
|
||||
}
|
||||
@@ -280,7 +215,7 @@ bool ModelComponent::TrySetVelocity(const NiPoint3& velocity) const {
|
||||
|
||||
// If we're currently moving on an axis, prevent the move so only 1 behavior can have control over an axis
|
||||
if (velocity != NiPoint3Constant::ZERO) {
|
||||
const auto [x, y, z] = velocity * m_Speed;
|
||||
const auto [x, y, z] = velocity;
|
||||
if (x != 0.0f) {
|
||||
if (currentVelocity.x != 0.0f) return false;
|
||||
currentVelocity.x = x;
|
||||
@@ -306,35 +241,3 @@ void ModelComponent::SetVelocity(const NiPoint3& velocity) const {
|
||||
void ModelComponent::OnChatMessageReceived(const std::string& sMessage) {
|
||||
for (auto& behavior : m_Behaviors) behavior.OnChatMessageReceived(sMessage);
|
||||
}
|
||||
|
||||
void ModelComponent::OnHit() {
|
||||
for (auto& behavior : m_Behaviors) {
|
||||
behavior.OnHit();
|
||||
}
|
||||
}
|
||||
|
||||
void ModelComponent::AddAttack() {
|
||||
LOG_DEBUG("Adding attack %i", m_NumActiveAttack);
|
||||
m_Dirty = true;
|
||||
if (m_NumActiveAttack == 0) {
|
||||
GameMessages::SetFaction set{};
|
||||
set.target = m_Parent->GetObjectID();
|
||||
set.factionID = 6; // Default faction for smashables
|
||||
set.Send();
|
||||
}
|
||||
m_NumActiveAttack++;
|
||||
}
|
||||
|
||||
void ModelComponent::RemoveAttack() {
|
||||
LOG_DEBUG("Removing attack %i", m_NumActiveAttack);
|
||||
DluAssert(m_NumActiveAttack > 0);
|
||||
m_Dirty = true;
|
||||
m_NumActiveAttack--;
|
||||
if (m_NumActiveAttack == 0) {
|
||||
GameMessages::SetFaction set{};
|
||||
set.target = m_Parent->GetObjectID();
|
||||
set.factionID = -1; // Default faction for smashables
|
||||
set.bIgnoreChecks = true; // Remove the attack faction
|
||||
set.Send();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,18 +66,15 @@ public:
|
||||
*
|
||||
* @tparam Msg The message type to pass
|
||||
* @param args the arguments of the message to be deserialized
|
||||
*
|
||||
* @return returns true if a new behaviorID is needed.
|
||||
*/
|
||||
template<typename Msg>
|
||||
bool HandleControlBehaviorsMsg(const AMFArrayValue& args) {
|
||||
void HandleControlBehaviorsMsg(const AMFArrayValue& args) {
|
||||
static_assert(std::is_base_of_v<BehaviorMessageBase, Msg>, "Msg must be a BehaviorMessageBase");
|
||||
Msg msg{ args };
|
||||
for (auto&& behavior : m_Behaviors) {
|
||||
if (behavior.GetBehaviorId() == msg.GetBehaviorId()) {
|
||||
behavior.CheckModifyState(msg);
|
||||
behavior.HandleMsg(msg);
|
||||
return msg.GetNeedsNewBehaviorID();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,24 +82,22 @@ public:
|
||||
if (m_Behaviors.size() > 5) m_Behaviors.resize(5);
|
||||
|
||||
// Do not allow more than 5 to be added. The client UI will break if you do!
|
||||
if (m_Behaviors.size() == 5) return false;
|
||||
if (m_Behaviors.size() == 5) return;
|
||||
|
||||
auto newBehavior = m_Behaviors.insert(m_Behaviors.begin(), PropertyBehavior());
|
||||
// Generally if we are inserting a new behavior, it is because the client is creating a new behavior.
|
||||
// However if we are testing behaviors the behavior will not exist on the initial pass, so we set the ID here to that of the msg.
|
||||
// This will either set the ID to -1 (no change in the current default) or set the ID to the ID of the behavior we are testing.
|
||||
newBehavior->SetBehaviorId(msg.GetBehaviorId());
|
||||
newBehavior->CheckModifyState(msg);
|
||||
newBehavior->HandleMsg(msg);
|
||||
return msg.GetNeedsNewBehaviorID();
|
||||
};
|
||||
|
||||
void AddBehavior(AddMessage& msg);
|
||||
|
||||
void RemoveBehavior(MoveToInventoryMessage& msg, const bool keepItem);
|
||||
void MoveToInventory(MoveToInventoryMessage& msg);
|
||||
|
||||
// Updates the pending behavior ID to the new ID.
|
||||
void UpdatePendingBehaviorId(const LWOOBJID newId, const LWOOBJID oldId);
|
||||
void UpdatePendingBehaviorId(const int32_t newId);
|
||||
|
||||
// Sends the behavior list to the client.
|
||||
|
||||
@@ -117,11 +112,11 @@ public:
|
||||
*/
|
||||
void SendBehaviorListToClient(AMFArrayValue& args) const;
|
||||
|
||||
void SendBehaviorBlocksToClient(const LWOOBJID behaviorToSend, AMFArrayValue& args) const;
|
||||
void SendBehaviorBlocksToClient(int32_t behaviorToSend, AMFArrayValue& args) const;
|
||||
|
||||
void VerifyBehaviors();
|
||||
|
||||
std::array<std::pair<LWOOBJID, std::string>, 5> GetBehaviorsForSave() const;
|
||||
std::array<std::pair<int32_t, std::string>, 5> GetBehaviorsForSave() const;
|
||||
|
||||
const std::vector<PropertyBehavior>& GetBehaviors() const { return m_Behaviors; };
|
||||
|
||||
@@ -145,30 +140,7 @@ public:
|
||||
void SetVelocity(const NiPoint3& velocity) const;
|
||||
|
||||
void OnChatMessageReceived(const std::string& sMessage);
|
||||
|
||||
void OnHit();
|
||||
|
||||
// Sets the speed of the model
|
||||
void SetSpeed(const float newSpeed) { m_Speed = newSpeed; }
|
||||
|
||||
// Whether or not to restart at the end of the frame
|
||||
void RestartAtEndOfFrame() { m_RestartAtEndOfFrame = true; }
|
||||
|
||||
// Increments the number of strips listening for an attack.
|
||||
// If this is the first strip adding an attack, it will set the factions to the correct values.
|
||||
void AddAttack();
|
||||
|
||||
// Decrements the number of strips listening for an attack.
|
||||
// If this is the last strip removing an attack, it will reset the factions to the default of -1.
|
||||
void RemoveAttack();
|
||||
private:
|
||||
|
||||
// Loads a behavior from the database.
|
||||
void LoadBehavior(const LWOOBJID behaviorID, const size_t index, const bool isIndexed);
|
||||
|
||||
// Writes a behavior to a string so it can be saved.
|
||||
std::string SaveBehavior(const PropertyBehavior& behavior) const;
|
||||
|
||||
// Number of Actions that are awaiting an UnSmash to finish.
|
||||
uint32_t m_NumActiveUnSmash{};
|
||||
|
||||
@@ -178,9 +150,6 @@ private:
|
||||
// The number of strips listening for a RequestUse GM to come in.
|
||||
uint32_t m_NumListeningInteract{};
|
||||
|
||||
// The number of strips listening for an attack.
|
||||
uint32_t m_NumActiveAttack{};
|
||||
|
||||
// Whether or not the model is paused and should reject all interactions regarding behaviors.
|
||||
bool m_IsPaused{};
|
||||
/**
|
||||
@@ -198,16 +167,10 @@ private:
|
||||
/**
|
||||
* The rotation original of the model
|
||||
*/
|
||||
NiQuaternion m_OriginalRotation = QuatUtils::IDENTITY;
|
||||
NiQuaternion m_OriginalRotation;
|
||||
|
||||
/**
|
||||
* The ID of the user that made the model
|
||||
*/
|
||||
LWOOBJID m_userModelID;
|
||||
|
||||
// The speed at which this model moves
|
||||
float m_Speed{ 3.0f };
|
||||
|
||||
// Whether or not to restart at the end of the frame.
|
||||
bool m_RestartAtEndOfFrame{ false };
|
||||
};
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include "dZoneManager.h"
|
||||
|
||||
#include "CDComponentsRegistryTable.h"
|
||||
#include "QuickBuildComponent.h"
|
||||
#include "CDPhysicsComponentTable.h"
|
||||
|
||||
#include "dNavMesh.h"
|
||||
@@ -83,16 +82,13 @@ void MovementAIComponent::Resume() {
|
||||
m_Paused = false;
|
||||
SetVelocity(m_SavedVelocity);
|
||||
m_SavedVelocity = NiPoint3Constant::ZERO;
|
||||
SetRotation(QuatUtils::LookAt(m_Parent->GetPosition(), m_NextWaypoint));
|
||||
SetRotation(NiQuaternion::LookAt(m_Parent->GetPosition(), m_NextWaypoint));
|
||||
Game::entityManager->SerializeEntity(m_Parent);
|
||||
}
|
||||
|
||||
void MovementAIComponent::Update(const float deltaTime) {
|
||||
if (m_Paused) return;
|
||||
|
||||
auto* const quickBuildComponent = m_Parent->GetComponent<QuickBuildComponent>();
|
||||
if (quickBuildComponent && quickBuildComponent->GetState() != eQuickBuildState::COMPLETED) return;
|
||||
|
||||
if (m_PullingToPoint) {
|
||||
const auto source = GetCurrentWaypoint();
|
||||
|
||||
@@ -154,11 +150,10 @@ void MovementAIComponent::Update(const float deltaTime) {
|
||||
m_TimeTravelled = 0.0f;
|
||||
m_TimeToTravel = length / speed;
|
||||
|
||||
SetRotation(QuatUtils::LookAt(source, m_NextWaypoint));
|
||||
SetRotation(NiQuaternion::LookAt(source, m_NextWaypoint));
|
||||
}
|
||||
} else {
|
||||
// Check if there are more waypoints in the queue, if so set our next destination to the next waypoint
|
||||
const auto waypointNum = m_IsBounced ? m_CurrentPath.size() : m_CurrentPathWaypointCount - m_CurrentPath.size() - 1;
|
||||
if (m_CurrentPath.empty()) {
|
||||
if (m_Path) {
|
||||
if (m_Path->pathBehavior == PathBehavior::Loop) {
|
||||
@@ -166,24 +161,20 @@ void MovementAIComponent::Update(const float deltaTime) {
|
||||
} else if (m_Path->pathBehavior == PathBehavior::Bounce) {
|
||||
m_IsBounced = !m_IsBounced;
|
||||
std::vector<PathWaypoint> waypoints = m_Path->pathWaypoints;
|
||||
if (m_IsBounced) std::ranges::reverse(waypoints);
|
||||
if (m_IsBounced) std::reverse(waypoints.begin(), waypoints.end());
|
||||
SetPath(waypoints);
|
||||
} else if (m_Path->pathBehavior == PathBehavior::Once) {
|
||||
m_Parent->GetScript()->OnWaypointReached(m_Parent, waypointNum);
|
||||
Stop();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
m_Parent->GetScript()->OnWaypointReached(m_Parent, waypointNum);
|
||||
Stop();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
m_Parent->GetScript()->OnWaypointReached(m_Parent, waypointNum);
|
||||
SetDestination(m_CurrentPath.top().position);
|
||||
|
||||
m_CurrentPath.pop();
|
||||
}
|
||||
SetDestination(m_CurrentPath.top().position);
|
||||
|
||||
m_CurrentPath.pop();
|
||||
}
|
||||
|
||||
Game::entityManager->SerializeEntity(m_Parent);
|
||||
@@ -259,7 +250,6 @@ void MovementAIComponent::Stop() {
|
||||
|
||||
m_InterpolatedWaypoints.clear();
|
||||
while (!m_CurrentPath.empty()) m_CurrentPath.pop();
|
||||
m_CurrentPathWaypointCount = 0;
|
||||
|
||||
m_PathIndex = 0;
|
||||
|
||||
@@ -282,7 +272,6 @@ void MovementAIComponent::SetPath(std::vector<PathWaypoint> path) {
|
||||
this->m_CurrentPath.push(point);
|
||||
});
|
||||
|
||||
m_CurrentPathWaypointCount = path.size();
|
||||
SetDestination(path.front().position);
|
||||
}
|
||||
|
||||
|
||||
@@ -209,8 +209,6 @@ public:
|
||||
*/
|
||||
static float GetBaseSpeed(LOT lot);
|
||||
|
||||
bool IsPaused() const { return m_Paused; }
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
@@ -325,9 +323,6 @@ private:
|
||||
NiPoint3 m_SavedVelocity;
|
||||
|
||||
bool m_IsBounced{};
|
||||
|
||||
// The number of waypoints that were on the path in the call to SetPath
|
||||
uint32_t m_CurrentPathWaypointCount{ 0 };
|
||||
};
|
||||
|
||||
#endif // MOVEMENTAICOMPONENT_H
|
||||
|
||||
@@ -168,7 +168,7 @@ void PetComponent::OnUse(Entity* originator) {
|
||||
|
||||
const auto originatorPosition = originator->GetPosition();
|
||||
|
||||
m_Parent->SetRotation(QuatUtils::LookAt(petPosition, originatorPosition));
|
||||
m_Parent->SetRotation(NiQuaternion::LookAt(petPosition, originatorPosition));
|
||||
|
||||
float interactionDistance = m_Parent->GetVar<float>(u"interaction_distance");
|
||||
if (interactionDistance <= 0) {
|
||||
@@ -177,7 +177,7 @@ void PetComponent::OnUse(Entity* originator) {
|
||||
|
||||
auto position = originatorPosition;
|
||||
|
||||
NiPoint3 forward = QuatUtils::Forward(QuatUtils::LookAt(m_Parent->GetPosition(), originator->GetPosition()));
|
||||
NiPoint3 forward = NiQuaternion::LookAt(m_Parent->GetPosition(), originator->GetPosition()).GetForwardVector();
|
||||
forward.y = 0;
|
||||
|
||||
if (dpWorld::IsLoaded()) {
|
||||
@@ -186,7 +186,7 @@ void PetComponent::OnUse(Entity* originator) {
|
||||
NiPoint3 nearestPoint = dpWorld::GetNavMesh()->NearestPoint(attempt);
|
||||
|
||||
while (std::abs(nearestPoint.y - petPosition.y) > 4 && interactionDistance > 10) {
|
||||
const NiPoint3 forward = QuatUtils::Forward(m_Parent->GetRotation());
|
||||
const NiPoint3 forward = m_Parent->GetRotation().GetForwardVector();
|
||||
|
||||
attempt = originatorPosition + forward * interactionDistance;
|
||||
|
||||
@@ -200,7 +200,7 @@ void PetComponent::OnUse(Entity* originator) {
|
||||
position = petPosition + forward * interactionDistance;
|
||||
}
|
||||
|
||||
auto rotation = QuatUtils::LookAt(position, petPosition);
|
||||
auto rotation = NiQuaternion::LookAt(position, petPosition);
|
||||
|
||||
GameMessages::SendNotifyPetTamingMinigame(
|
||||
originator->GetObjectID(),
|
||||
@@ -460,7 +460,7 @@ void PetComponent::NotifyTamingBuildSuccess(NiPoint3 position) {
|
||||
EntityInfo info{};
|
||||
info.lot = entry->puzzleModelLot;
|
||||
info.pos = position;
|
||||
info.rot = QuatUtils::IDENTITY;
|
||||
info.rot = NiQuaternionConstant::IDENTITY;
|
||||
info.spawnerID = tamer->GetObjectID();
|
||||
|
||||
auto* modelEntity = Game::entityManager->CreateEntity(info);
|
||||
@@ -522,7 +522,7 @@ void PetComponent::NotifyTamingBuildSuccess(NiPoint3 position) {
|
||||
ePetTamingNotifyType::NAMINGPET,
|
||||
NiPoint3Constant::ZERO,
|
||||
NiPoint3Constant::ZERO,
|
||||
QuatUtils::IDENTITY,
|
||||
NiQuaternionConstant::IDENTITY,
|
||||
UNASSIGNED_SYSTEM_ADDRESS
|
||||
);
|
||||
|
||||
@@ -601,7 +601,7 @@ void PetComponent::RequestSetPetName(std::u16string name) {
|
||||
ePetTamingNotifyType::SUCCESS,
|
||||
NiPoint3Constant::ZERO,
|
||||
NiPoint3Constant::ZERO,
|
||||
QuatUtils::IDENTITY,
|
||||
NiQuaternionConstant::IDENTITY,
|
||||
UNASSIGNED_SYSTEM_ADDRESS
|
||||
);
|
||||
|
||||
@@ -645,7 +645,7 @@ void PetComponent::ClientExitTamingMinigame(bool voluntaryExit) {
|
||||
ePetTamingNotifyType::QUIT,
|
||||
NiPoint3Constant::ZERO,
|
||||
NiPoint3Constant::ZERO,
|
||||
QuatUtils::IDENTITY,
|
||||
NiQuaternionConstant::IDENTITY,
|
||||
UNASSIGNED_SYSTEM_ADDRESS
|
||||
);
|
||||
|
||||
@@ -696,7 +696,7 @@ void PetComponent::ClientFailTamingMinigame() {
|
||||
ePetTamingNotifyType::FAILED,
|
||||
NiPoint3Constant::ZERO,
|
||||
NiPoint3Constant::ZERO,
|
||||
QuatUtils::IDENTITY,
|
||||
NiQuaternionConstant::IDENTITY,
|
||||
UNASSIGNED_SYSTEM_ADDRESS
|
||||
);
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include "CDPhysicsComponentTable.h"
|
||||
#include "dServer.h"
|
||||
#include "EntityInfo.h"
|
||||
#include "Amf3.h"
|
||||
|
||||
#include "dpWorld.h"
|
||||
#include "dpEntity.h"
|
||||
@@ -29,8 +28,6 @@
|
||||
#include "dpShapeSphere.h"
|
||||
|
||||
PhantomPhysicsComponent::PhantomPhysicsComponent(Entity* parent, int32_t componentId) : PhysicsComponent(parent, componentId) {
|
||||
RegisterMsg(MessageType::Game::GET_OBJECT_REPORT_INFO, this, &PhantomPhysicsComponent::OnGetObjectReportInfo);
|
||||
|
||||
m_Position = m_Parent->GetDefaultPosition();
|
||||
m_Rotation = m_Parent->GetDefaultRotation();
|
||||
m_Scale = m_Parent->GetDefaultScale();
|
||||
@@ -241,43 +238,3 @@ void PhantomPhysicsComponent::SetRotation(const NiQuaternion& rot) {
|
||||
PhysicsComponent::SetRotation(rot);
|
||||
if (m_dpEntity) m_dpEntity->SetRotation(rot);
|
||||
}
|
||||
|
||||
bool PhantomPhysicsComponent::OnGetObjectReportInfo(GameMessages::GameMsg& msg) {
|
||||
PhysicsComponent::OnGetObjectReportInfo(msg);
|
||||
auto& reportInfo = static_cast<GameMessages::GetObjectReportInfo&>(msg);
|
||||
if (!reportInfo.subCategory) {
|
||||
return false;
|
||||
}
|
||||
auto& info = reportInfo.subCategory->PushDebug("Phantom Physics Info");
|
||||
info.PushDebug<AMFDoubleValue>("Scale") = m_Scale;
|
||||
info.PushDebug<AMFBoolValue>("Is Physics Effect Active") = m_IsPhysicsEffectActive;
|
||||
info.PushDebug<AMFIntValue>("Effect Type") = static_cast<int>(m_EffectType);
|
||||
info.PushDebug<AMFDoubleValue>("Directional Multiplier") = m_DirectionalMultiplier;
|
||||
info.PushDebug<AMFBoolValue>("Is Directional") = m_IsDirectional;
|
||||
auto& direction = info.PushDebug("Direction");
|
||||
direction.PushDebug<AMFDoubleValue>("x") = m_Direction.x;
|
||||
direction.PushDebug<AMFDoubleValue>("y") = m_Direction.y;
|
||||
direction.PushDebug<AMFDoubleValue>("z") = m_Direction.z;
|
||||
|
||||
if (m_MinMax) {
|
||||
auto& minMaxInfo = info.PushDebug("Min Max Info");
|
||||
minMaxInfo.PushDebug<AMFIntValue>("Min") = m_Min;
|
||||
minMaxInfo.PushDebug<AMFIntValue>("Max") = m_Max;
|
||||
}
|
||||
|
||||
if (m_IsRespawnVolume) {
|
||||
auto& respawnInfo = info.PushDebug("Respawn Info");
|
||||
respawnInfo.PushDebug<AMFBoolValue>("Is Respawn Volume") = m_IsRespawnVolume;
|
||||
auto& respawnPos = respawnInfo.PushDebug("Respawn Position");
|
||||
respawnPos.PushDebug<AMFDoubleValue>("x") = m_RespawnPos.x;
|
||||
respawnPos.PushDebug<AMFDoubleValue>("y") = m_RespawnPos.y;
|
||||
respawnPos.PushDebug<AMFDoubleValue>("z") = m_RespawnPos.z;
|
||||
auto& respawnRot = respawnInfo.PushDebug("Respawn Rotation");
|
||||
respawnRot.PushDebug<AMFDoubleValue>("w") = m_RespawnRot.w;
|
||||
respawnRot.PushDebug<AMFDoubleValue>("x") = m_RespawnRot.x;
|
||||
respawnRot.PushDebug<AMFDoubleValue>("y") = m_RespawnRot.y;
|
||||
respawnRot.PushDebug<AMFDoubleValue>("z") = m_RespawnRot.z;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#include "NiQuaternion.h"
|
||||
#include "BitStream.h"
|
||||
#include <vector>
|
||||
#include "CppScripts.h"
|
||||
#include "InvalidScript.h"
|
||||
#include "eReplicaComponentType.h"
|
||||
#include "PhysicsComponent.h"
|
||||
|
||||
@@ -116,8 +118,6 @@ public:
|
||||
void SetMax(uint32_t max);
|
||||
|
||||
private:
|
||||
bool OnGetObjectReportInfo(GameMessages::GameMsg& msg);
|
||||
|
||||
/**
|
||||
* A scale to apply to the size of the physics object
|
||||
*/
|
||||
@@ -175,5 +175,5 @@ private:
|
||||
/**
|
||||
* If this is a respawn volume, the exact rotation an entity will respawn
|
||||
*/
|
||||
NiQuaternion m_RespawnRot = QuatUtils::IDENTITY;
|
||||
NiQuaternion m_RespawnRot;
|
||||
};
|
||||
|
||||
@@ -13,11 +13,10 @@
|
||||
#include "dpShapeSphere.h"
|
||||
|
||||
#include "EntityInfo.h"
|
||||
#include "Amf3.h"
|
||||
|
||||
PhysicsComponent::PhysicsComponent(Entity* parent, int32_t componentId) : Component(parent) {
|
||||
m_Position = NiPoint3Constant::ZERO;
|
||||
m_Rotation = QuatUtils::IDENTITY;
|
||||
m_Rotation = NiQuaternionConstant::IDENTITY;
|
||||
m_DirtyPosition = false;
|
||||
|
||||
CDPhysicsComponentTable* physicsComponentTable = CDClientManager::GetTable<CDPhysicsComponentTable>();
|
||||
@@ -30,13 +29,6 @@ PhysicsComponent::PhysicsComponent(Entity* parent, int32_t componentId) : Compon
|
||||
}
|
||||
|
||||
if (m_Parent->HasVar(u"CollisionGroupID")) m_CollisionGroup = m_Parent->GetVar<int32_t>(u"CollisionGroupID");
|
||||
|
||||
RegisterMsg(MessageType::Game::GET_POSITION, this, &PhysicsComponent::OnGetPosition);
|
||||
}
|
||||
|
||||
bool PhysicsComponent::OnGetPosition(GameMessages::GameMsg& msg) {
|
||||
static_cast<GameMessages::GetPosition&>(msg).pos = GetPosition();
|
||||
return true;
|
||||
}
|
||||
|
||||
void PhysicsComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
||||
@@ -81,10 +73,10 @@ dpEntity* PhysicsComponent::CreatePhysicsEntity(eReplicaComponentType type) {
|
||||
toReturn = new dpEntity(m_Parent->GetObjectID(), 1.0f, 12.5f, 20.0f); // Not sure what the real size is
|
||||
} else if (info->physicsAsset == "env\\NG_NinjaGo\\env_ng_gen_gate_chamber_puzzle_ceiling_tile_falling_phantom.hkx") {
|
||||
toReturn = new dpEntity(m_Parent->GetObjectID(), 18.0f, 5.0f, 15.0f);
|
||||
m_Position += QuatUtils::Forward(m_Rotation) * 7.5f;
|
||||
m_Position += m_Rotation.GetForwardVector() * 7.5f;
|
||||
} else if (info->physicsAsset == "env\\NG_NinjaGo\\ng_flamejet_brick_phantom.HKX") {
|
||||
toReturn = new dpEntity(m_Parent->GetObjectID(), 1.0f, 1.0f, 12.0f);
|
||||
m_Position += QuatUtils::Forward(m_Rotation) * 6.0f;
|
||||
m_Position += m_Rotation.GetForwardVector() * 6.0f;
|
||||
} else if (info->physicsAsset == "env\\Ring_Trigger.hkx") {
|
||||
toReturn = new dpEntity(m_Parent->GetObjectID(), 6.0f, 6.0f, 6.0f);
|
||||
} else if (info->physicsAsset == "env\\vfx_propertyImaginationBall.hkx") {
|
||||
@@ -98,9 +90,9 @@ dpEntity* PhysicsComponent::CreatePhysicsEntity(eReplicaComponentType type) {
|
||||
} else if (info->physicsAsset == "env\\GFTrack_DeathVolume2_RoadGaps.hkx") {
|
||||
toReturn = new dpEntity(m_Parent->GetObjectID(), 48.386536f, 50.363434f, 259.361755f);
|
||||
} */ else {
|
||||
// LOG_DEBUG("This one is supposed to have %s", info->physicsAsset.c_str());
|
||||
// LOG_DEBUG("This one is supposed to have %s", info->physicsAsset.c_str());
|
||||
|
||||
//add fallback cube:
|
||||
//add fallback cube:
|
||||
toReturn = new dpEntity(m_Parent->GetObjectID(), 2.0f, 2.0f, 2.0f);
|
||||
}
|
||||
return toReturn;
|
||||
@@ -244,24 +236,3 @@ void PhysicsComponent::SpawnVertices(dpEntity* entity) const {
|
||||
Game::entityManager->ConstructEntity(newEntity);
|
||||
}
|
||||
}
|
||||
|
||||
bool PhysicsComponent::OnGetObjectReportInfo(GameMessages::GameMsg& msg) {
|
||||
auto& reportInfo = static_cast<GameMessages::GetObjectReportInfo&>(msg);
|
||||
auto& info = reportInfo.info->PushDebug("Physics");
|
||||
reportInfo.subCategory = &info;
|
||||
|
||||
auto& pos = info.PushDebug("Position");
|
||||
pos.PushDebug<AMFDoubleValue>("x") = m_Position.x;
|
||||
pos.PushDebug<AMFDoubleValue>("y") = m_Position.y;
|
||||
pos.PushDebug<AMFDoubleValue>("z") = m_Position.z;
|
||||
|
||||
auto& rot = info.PushDebug("Rotation");
|
||||
rot.PushDebug<AMFDoubleValue>("w") = m_Rotation.w;
|
||||
rot.PushDebug<AMFDoubleValue>("x") = m_Rotation.x;
|
||||
rot.PushDebug<AMFDoubleValue>("y") = m_Rotation.y;
|
||||
rot.PushDebug<AMFDoubleValue>("z") = m_Rotation.z;
|
||||
|
||||
info.PushDebug<AMFIntValue>("CollisionGroup") = m_CollisionGroup;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -5,10 +5,6 @@
|
||||
#include "NiPoint3.h"
|
||||
#include "NiQuaternion.h"
|
||||
|
||||
namespace GameMessages {
|
||||
struct GetObjectReportInfo;
|
||||
};
|
||||
|
||||
namespace Raknet {
|
||||
class BitStream;
|
||||
};
|
||||
@@ -24,7 +20,7 @@ public:
|
||||
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
|
||||
const NiPoint3& GetPosition() const noexcept { return m_Position; }
|
||||
const NiPoint3& GetPosition() const { return m_Position; }
|
||||
virtual void SetPosition(const NiPoint3& pos) { if (m_Position == pos) return; m_Position = pos; m_DirtyPosition = true; }
|
||||
|
||||
const NiQuaternion& GetRotation() const { return m_Rotation; }
|
||||
@@ -33,19 +29,15 @@ public:
|
||||
int32_t GetCollisionGroup() const noexcept { return m_CollisionGroup; }
|
||||
void SetCollisionGroup(int32_t group) noexcept { m_CollisionGroup = group; }
|
||||
protected:
|
||||
bool OnGetObjectReportInfo(GameMessages::GameMsg& msg);
|
||||
|
||||
dpEntity* CreatePhysicsEntity(eReplicaComponentType type);
|
||||
|
||||
dpEntity* CreatePhysicsLnv(const float scale, const eReplicaComponentType type) const;
|
||||
|
||||
void SpawnVertices(dpEntity* entity) const;
|
||||
|
||||
bool OnGetPosition(GameMessages::GameMsg& msg);
|
||||
|
||||
NiPoint3 m_Position;
|
||||
|
||||
NiQuaternion m_Rotation = QuatUtils::IDENTITY;
|
||||
NiQuaternion m_Rotation;
|
||||
|
||||
bool m_DirtyPosition;
|
||||
|
||||
|
||||
@@ -333,7 +333,7 @@ void PropertyManagementComponent::UpdateModelPosition(const LWOOBJID id, const N
|
||||
|
||||
const auto modelLOT = item->GetLot();
|
||||
|
||||
if (rotation != QuatUtils::IDENTITY) {
|
||||
if (rotation != NiQuaternionConstant::IDENTITY) {
|
||||
rotation = { rotation.w, rotation.z, rotation.y, rotation.x };
|
||||
}
|
||||
|
||||
@@ -516,7 +516,7 @@ void PropertyManagementComponent::DeleteModel(const LWOOBJID id, const int delet
|
||||
|
||||
GameMessages::SendGetModelsOnProperty(entity->GetObjectID(), GetModels(), UNASSIGNED_SYSTEM_ADDRESS);
|
||||
|
||||
GameMessages::SendPlaceModelResponse(entity->GetObjectID(), entity->GetSystemAddress(), NiPoint3Constant::ZERO, LWOOBJID_EMPTY, 16, QuatUtils::IDENTITY);
|
||||
GameMessages::SendPlaceModelResponse(entity->GetObjectID(), entity->GetSystemAddress(), NiPoint3Constant::ZERO, LWOOBJID_EMPTY, 16, NiQuaternionConstant::IDENTITY);
|
||||
|
||||
if (spawner != nullptr) {
|
||||
Game::zoneManager->RemoveSpawner(spawner->m_Info.spawnerID);
|
||||
@@ -569,7 +569,7 @@ void PropertyManagementComponent::DeleteModel(const LWOOBJID id, const int delet
|
||||
|
||||
GameMessages::SendGetModelsOnProperty(entity->GetObjectID(), GetModels(), UNASSIGNED_SYSTEM_ADDRESS);
|
||||
|
||||
GameMessages::SendPlaceModelResponse(entity->GetObjectID(), entity->GetSystemAddress(), NiPoint3Constant::ZERO, LWOOBJID_EMPTY, 16, QuatUtils::IDENTITY);
|
||||
GameMessages::SendPlaceModelResponse(entity->GetObjectID(), entity->GetSystemAddress(), NiPoint3Constant::ZERO, LWOOBJID_EMPTY, 16, NiQuaternionConstant::IDENTITY);
|
||||
|
||||
if (spawner != nullptr) {
|
||||
Game::zoneManager->RemoveSpawner(spawner->m_Info.spawnerID);
|
||||
|
||||
@@ -459,7 +459,7 @@ void QuickBuildComponent::CompleteQuickBuild(Entity* const user) {
|
||||
auto* missionComponent = builder->GetComponent<MissionComponent>();
|
||||
if (missionComponent) missionComponent->Progress(eMissionTaskType::ACTIVITY, m_ActivityId);
|
||||
}
|
||||
Loot::DropActivityLoot(builder, m_Parent->GetObjectID(), m_ActivityId, 1);
|
||||
Loot::DropActivityLoot(builder, m_Parent, m_ActivityId, 1);
|
||||
}
|
||||
|
||||
// Notify scripts
|
||||
|
||||
@@ -123,7 +123,7 @@ void RacingControlComponent::LoadPlayerVehicle(Entity* player,
|
||||
|
||||
auto spawnPointEntities = Game::entityManager->GetEntitiesByLOT(4843);
|
||||
auto startPosition = NiPoint3Constant::ZERO;
|
||||
auto startRotation = QuatUtils::IDENTITY;
|
||||
auto startRotation = NiQuaternionConstant::IDENTITY;
|
||||
const std::string placementAsString = std::to_string(positionNumber);
|
||||
for (auto entity : spawnPointEntities) {
|
||||
if (!entity) continue;
|
||||
@@ -393,7 +393,7 @@ void RacingControlComponent::HandleMessageBoxResponse(Entity* player, int32_t bu
|
||||
}
|
||||
|
||||
const auto score = playersRating * 10 + data->finished;
|
||||
Loot::GiveActivityLoot(player, m_Parent->GetObjectID(), m_ActivityID, score);
|
||||
Loot::GiveActivityLoot(player, m_Parent, m_ActivityID, score);
|
||||
|
||||
// Giving rewards
|
||||
GameMessages::SendNotifyRacingClient(
|
||||
|
||||
@@ -48,7 +48,7 @@ struct RacingPlayerInfo {
|
||||
/**
|
||||
* Rotation that the player will respawn at if they smash their car
|
||||
*/
|
||||
NiQuaternion respawnRotation = QuatUtils::IDENTITY;
|
||||
NiQuaternion respawnRotation;
|
||||
|
||||
/**
|
||||
* The index in the respawn point the player is now at
|
||||
|
||||
@@ -10,12 +10,9 @@
|
||||
#include "dpWorld.h"
|
||||
#include "dpShapeBox.h"
|
||||
#include "dpShapeSphere.h"
|
||||
#include "EntityInfo.h"
|
||||
#include "Amf3.h"
|
||||
#include"EntityInfo.h"
|
||||
|
||||
RigidbodyPhantomPhysicsComponent::RigidbodyPhantomPhysicsComponent(Entity* parent, int32_t componentId) : PhysicsComponent(parent, componentId) {
|
||||
RegisterMsg(MessageType::Game::GET_OBJECT_REPORT_INFO, this, &RigidbodyPhantomPhysicsComponent::OnGetObjectReportInfo);
|
||||
|
||||
m_Position = m_Parent->GetDefaultPosition();
|
||||
m_Rotation = m_Parent->GetDefaultRotation();
|
||||
m_Scale = m_Parent->GetDefaultScale();
|
||||
@@ -58,11 +55,3 @@ void RigidbodyPhantomPhysicsComponent::SpawnVertices() const {
|
||||
}
|
||||
PhysicsComponent::SpawnVertices(m_dpEntity);
|
||||
}
|
||||
|
||||
bool RigidbodyPhantomPhysicsComponent::OnGetObjectReportInfo(GameMessages::GameMsg& msg) {
|
||||
PhysicsComponent::OnGetObjectReportInfo(msg);
|
||||
auto& reportInfo = static_cast<GameMessages::GetObjectReportInfo&>(msg);
|
||||
auto& info = reportInfo.subCategory->PushDebug("Rigidbody Phantom Info");
|
||||
info.PushDebug<AMFDoubleValue>("Scale") = m_Scale;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -29,8 +29,6 @@ public:
|
||||
|
||||
void SpawnVertices() const;
|
||||
private:
|
||||
bool OnGetObjectReportInfo(GameMessages::GameMsg& msg);
|
||||
|
||||
float m_Scale{};
|
||||
|
||||
dpEntity* m_dpEntity{};
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#include "dServer.h"
|
||||
#include "BitStreamUtils.h"
|
||||
#include "eObjectWorldState.h"
|
||||
#include "ServiceType.h"
|
||||
#include "eConnectionType.h"
|
||||
#include "MessageType/Master.h"
|
||||
|
||||
RocketLaunchpadControlComponent::RocketLaunchpadControlComponent(Entity* parent, int rocketId) : Component(parent) {
|
||||
@@ -137,7 +137,7 @@ LWOCLONEID RocketLaunchpadControlComponent::GetSelectedCloneId(LWOOBJID player)
|
||||
|
||||
void RocketLaunchpadControlComponent::TellMasterToPrepZone(int zoneID) {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::MASTER, MessageType::Master::PREP_ZONE);
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, MessageType::Master::PREP_ZONE);
|
||||
bitStream.Write(zoneID);
|
||||
Game::server->SendToMaster(bitStream);
|
||||
}
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
#include "EntityManager.h"
|
||||
#include "ScriptedActivityComponent.h"
|
||||
|
||||
ShootingGalleryComponent::ShootingGalleryComponent(Entity* parent, int32_t activityID) : ActivityComponent(parent, activityID) {
|
||||
ShootingGalleryComponent::ShootingGalleryComponent(Entity* parent) : Component(parent) {
|
||||
}
|
||||
|
||||
ShootingGalleryComponent::~ShootingGalleryComponent() = default;
|
||||
|
||||
void ShootingGalleryComponent::SetStaticParams(const StaticShootingGalleryParams& params) {
|
||||
m_StaticParams = params;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#include "Entity.h"
|
||||
#include "Component.h"
|
||||
#include "eReplicaComponentType.h"
|
||||
#include "ActivityComponent.h"
|
||||
|
||||
/**
|
||||
* Parameters for the shooting gallery that change during playtime
|
||||
@@ -72,11 +71,12 @@ struct StaticShootingGalleryParams {
|
||||
* A very ancient component that was used to guide shooting galleries, it's still kind of used but a lot of logic is
|
||||
* also in the related scripts.
|
||||
*/
|
||||
class ShootingGalleryComponent final : public ActivityComponent {
|
||||
class ShootingGalleryComponent final : public Component {
|
||||
public:
|
||||
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::SHOOTING_GALLERY;
|
||||
|
||||
explicit ShootingGalleryComponent(Entity* parent, int32_t activityID);
|
||||
explicit ShootingGalleryComponent(Entity* parent);
|
||||
~ShootingGalleryComponent();
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool isInitialUpdate) override;
|
||||
|
||||
/**
|
||||
|
||||
@@ -12,12 +12,8 @@
|
||||
#include "CDPhysicsComponentTable.h"
|
||||
|
||||
#include "Entity.h"
|
||||
#include "StringifiedEnum.h"
|
||||
#include "Amf3.h"
|
||||
|
||||
SimplePhysicsComponent::SimplePhysicsComponent(Entity* parent, int32_t componentID) : PhysicsComponent(parent, componentID) {
|
||||
RegisterMsg(MessageType::Game::GET_OBJECT_REPORT_INFO, this, &SimplePhysicsComponent::OnGetObjectReportInfo);
|
||||
|
||||
m_Position = m_Parent->GetDefaultPosition();
|
||||
m_Rotation = m_Parent->GetDefaultRotation();
|
||||
|
||||
@@ -75,20 +71,3 @@ void SimplePhysicsComponent::SetPhysicsMotionState(uint32_t value) {
|
||||
m_DirtyPhysicsMotionState = m_PhysicsMotionState != value;
|
||||
m_PhysicsMotionState = value;
|
||||
}
|
||||
|
||||
bool SimplePhysicsComponent::OnGetObjectReportInfo(GameMessages::GameMsg& msg) {
|
||||
PhysicsComponent::OnGetObjectReportInfo(msg);
|
||||
auto& reportInfo = static_cast<GameMessages::GetObjectReportInfo&>(msg);
|
||||
auto& info = reportInfo.subCategory->PushDebug("Simple Physics Info");
|
||||
auto& velocity = info.PushDebug("Velocity");
|
||||
velocity.PushDebug<AMFDoubleValue>("x") = m_Velocity.x;
|
||||
velocity.PushDebug<AMFDoubleValue>("y") = m_Velocity.y;
|
||||
velocity.PushDebug<AMFDoubleValue>("z") = m_Velocity.z;
|
||||
auto& angularVelocity = info.PushDebug("Angular Velocity");
|
||||
angularVelocity.PushDebug<AMFDoubleValue>("x") = m_AngularVelocity.x;
|
||||
angularVelocity.PushDebug<AMFDoubleValue>("y") = m_AngularVelocity.y;
|
||||
angularVelocity.PushDebug<AMFDoubleValue>("z") = m_AngularVelocity.z;
|
||||
info.PushDebug<AMFIntValue>("Physics Motion State") = m_PhysicsMotionState;
|
||||
info.PushDebug<AMFStringValue>("Climbable Type") = StringifiedEnum::ToString(m_ClimbableType).data();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -86,8 +86,6 @@ public:
|
||||
void SetClimbableType(const eClimbableType& value) { m_ClimbableType = value; }
|
||||
|
||||
private:
|
||||
bool OnGetObjectReportInfo(GameMessages::GameMsg& msg);
|
||||
|
||||
/**
|
||||
* The current velocity of the entity
|
||||
*/
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include "DoClientProjectileImpact.h"
|
||||
#include "CDClientManager.h"
|
||||
#include "CDSkillBehaviorTable.h"
|
||||
#include "ServiceType.h"
|
||||
#include "eConnectionType.h"
|
||||
#include "MessageType/Client.h"
|
||||
|
||||
ProjectileSyncEntry::ProjectileSyncEntry() {
|
||||
@@ -316,7 +316,7 @@ SkillExecutionResult SkillComponent::CalculateBehavior(
|
||||
start.originatorRot = originator->GetRotation();
|
||||
}
|
||||
|
||||
if (rotationOverride != QuatUtils::IDENTITY) {
|
||||
if (rotationOverride != NiQuaternionConstant::IDENTITY) {
|
||||
start.originatorRot = rotationOverride;
|
||||
}
|
||||
//start.optionalTargetID = target;
|
||||
@@ -326,7 +326,7 @@ SkillExecutionResult SkillComponent::CalculateBehavior(
|
||||
// Write message
|
||||
RakNet::BitStream message;
|
||||
|
||||
BitStreamUtils::WriteHeader(message, ServiceType::CLIENT, MessageType::Client::GAME_MSG);
|
||||
BitStreamUtils::WriteHeader(message, eConnectionType::CLIENT, MessageType::Client::GAME_MSG);
|
||||
message.Write(this->m_Parent->GetObjectID());
|
||||
start.Serialize(message);
|
||||
|
||||
@@ -457,7 +457,7 @@ void SkillComponent::SyncProjectileCalculation(const ProjectileSyncEntry& entry)
|
||||
|
||||
RakNet::BitStream message;
|
||||
|
||||
BitStreamUtils::WriteHeader(message, ServiceType::CLIENT, MessageType::Client::GAME_MSG);
|
||||
BitStreamUtils::WriteHeader(message, eConnectionType::CLIENT, MessageType::Client::GAME_MSG);
|
||||
message.Write(this->m_Parent->GetObjectID());
|
||||
projectileImpact.Serialize(message);
|
||||
|
||||
|
||||
@@ -129,7 +129,7 @@ public:
|
||||
* @param optionalOriginatorID change the originator of the skill
|
||||
* @return if the case succeeded
|
||||
*/
|
||||
bool CastSkill(const uint32_t skillId, LWOOBJID target = LWOOBJID_EMPTY, const LWOOBJID optionalOriginatorID = LWOOBJID_EMPTY, const int32_t castType = 0, const NiQuaternion rotationOverride = QuatUtils::IDENTITY);
|
||||
bool CastSkill(const uint32_t skillId, LWOOBJID target = LWOOBJID_EMPTY, const LWOOBJID optionalOriginatorID = LWOOBJID_EMPTY, const int32_t castType = 0, const NiQuaternion rotationOverride = NiQuaternionConstant::IDENTITY);
|
||||
|
||||
/**
|
||||
* Initializes a server-side skill calculation.
|
||||
@@ -141,7 +141,7 @@ public:
|
||||
* @param originatorOverride an override for the originator of the skill calculation
|
||||
* @return the result of the skill calculation
|
||||
*/
|
||||
SkillExecutionResult CalculateBehavior(uint32_t skillId, uint32_t behaviorId, LWOOBJID target, bool ignoreTarget = false, bool clientInitalized = false, LWOOBJID originatorOverride = LWOOBJID_EMPTY, const int32_t castType = 0, const NiQuaternion rotationOverride = QuatUtils::IDENTITY);
|
||||
SkillExecutionResult CalculateBehavior(uint32_t skillId, uint32_t behaviorId, LWOOBJID target, bool ignoreTarget = false, bool clientInitalized = false, LWOOBJID originatorOverride = LWOOBJID_EMPTY, const int32_t castType = 0, const NiQuaternion rotationOverride = NiQuaternionConstant::IDENTITY);
|
||||
|
||||
/**
|
||||
* Register a server-side projectile.
|
||||
|
||||
@@ -17,8 +17,6 @@
|
||||
#include "EntityManager.h"
|
||||
#include "MovementAIComponent.h"
|
||||
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
|
||||
TriggerComponent::TriggerComponent(Entity* parent, const std::string triggerInfo) : Component(parent) {
|
||||
m_Parent = parent;
|
||||
m_Trigger = nullptr;
|
||||
@@ -242,9 +240,10 @@ void TriggerComponent::HandleMoveObject(Entity* targetEntity, std::vector<std::s
|
||||
void TriggerComponent::HandleRotateObject(Entity* targetEntity, std::vector<std::string> argArray) {
|
||||
if (argArray.size() <= 2) return;
|
||||
|
||||
const auto vector = GeneralUtils::TryParse<glm::vec3>(argArray).value_or(glm::zero<glm::vec3>());
|
||||
const NiPoint3 vector = GeneralUtils::TryParse<NiPoint3>(argArray).value_or(NiPoint3Constant::ZERO);
|
||||
|
||||
targetEntity->SetRotation(glm::quat(vector));
|
||||
NiQuaternion rotation = NiQuaternion::FromEulerAngles(vector);
|
||||
targetEntity->SetRotation(rotation);
|
||||
}
|
||||
|
||||
void TriggerComponent::HandlePushObject(Entity* targetEntity, std::vector<std::string> argArray) {
|
||||
|
||||
@@ -164,17 +164,10 @@ void VendorComponent::Buy(Entity* buyer, LOT lot, uint32_t count) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool success = true;
|
||||
for (const auto& [crafintCurrencyLOT, crafintCurrencyCount]: craftingCurrencies) {
|
||||
success = inventoryComponent->RemoveItem(crafintCurrencyLOT, crafintCurrencyCount * count, eInventoryType::ALL);
|
||||
if (!success) break;
|
||||
inventoryComponent->RemoveItem(crafintCurrencyLOT, crafintCurrencyCount * count);
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
GameMessages::SendVendorTransactionResult(buyer, buyer->GetSystemAddress(), eVendorTransactionResult::PURCHASE_FAIL);
|
||||
return;
|
||||
}
|
||||
|
||||
float buyScalar = GetBuyScalar();
|
||||
const auto coinCost = static_cast<uint32_t>(std::floor((itemComp.baseValue * buyScalar) * count));
|
||||
@@ -191,7 +184,7 @@ void VendorComponent::Buy(Entity* buyer, LOT lot, uint32_t count) {
|
||||
GameMessages::SendVendorTransactionResult(buyer, buyer->GetSystemAddress(), eVendorTransactionResult::PURCHASE_FAIL);
|
||||
return;
|
||||
}
|
||||
inventoryComponent->RemoveItem(itemComp.currencyLOT, altCurrencyCost, eInventoryType::ALL);
|
||||
inventoryComponent->RemoveItem(itemComp.currencyLOT, altCurrencyCost);
|
||||
}
|
||||
|
||||
character->SetCoins(character->GetCoins() - (coinCost), eLootSourceType::VENDOR);
|
||||
|
||||
@@ -33,7 +33,7 @@ struct EntityInfo {
|
||||
LWOOBJID id;
|
||||
LOT lot;
|
||||
NiPoint3 pos;
|
||||
NiQuaternion rot = QuatUtils::IDENTITY;
|
||||
NiQuaternion rot;
|
||||
std::vector<LDFBaseData*> settings;
|
||||
std::vector<LDFBaseData*> networkSettings;
|
||||
float scale;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user