mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2024-12-24 06:23:35 +00:00
Merge branch 'main' into PetFixes
This commit is contained in:
commit
60b3f3c552
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -17,3 +17,6 @@
|
||||
[submodule "thirdparty/AccountManager"]
|
||||
path = thirdparty/AccountManager
|
||||
url = https://github.com/DarkflameUniverse/AccountManager
|
||||
[submodule "thirdparty/magic_enum"]
|
||||
path = thirdparty/magic_enum
|
||||
url = https://github.com/Neargye/magic_enum.git
|
||||
|
@ -269,6 +269,7 @@ set(INCLUDED_DIRECTORIES
|
||||
"dScripts/ai/GENERAL"
|
||||
"dScripts/ai/GF"
|
||||
"dScripts/ai/MINIGAME"
|
||||
"dScripts/ai/MINIGAME/Objects"
|
||||
"dScripts/ai/NP"
|
||||
"dScripts/ai/NS"
|
||||
"dScripts/ai/PETS"
|
||||
@ -292,6 +293,7 @@ set(INCLUDED_DIRECTORIES
|
||||
"dScripts/zone/PROPERTY/GF"
|
||||
"dScripts/zone/PROPERTY/NS"
|
||||
|
||||
"thirdparty/magic_enum/include/magic_enum"
|
||||
"thirdparty/raknet/Source"
|
||||
"thirdparty/tinyxml2"
|
||||
"thirdparty/recastnavigation"
|
||||
@ -373,7 +375,7 @@ add_subdirectory(dNavigation)
|
||||
add_subdirectory(dPhysics)
|
||||
|
||||
# Create a list of common libraries shared between all binaries
|
||||
set(COMMON_LIBRARIES "dCommon" "dDatabase" "dNet" "raknet" "mariadbConnCpp")
|
||||
set(COMMON_LIBRARIES "dCommon" "dDatabase" "dNet" "raknet" "mariadbConnCpp" "magic_enum")
|
||||
|
||||
# Add platform specific common libraries
|
||||
if (UNIX)
|
||||
|
@ -1,14 +1,6 @@
|
||||
#include "BinaryIO.h"
|
||||
#include <string>
|
||||
|
||||
void BinaryIO::WriteString(const std::string& stringToWrite, std::ofstream& outstream) {
|
||||
//BinaryWrite(outstream, uint32_t(stringToWrite.length()));
|
||||
|
||||
for (size_t i = 0; i < size_t(stringToWrite.length()); ++i) {
|
||||
BinaryIO::BinaryWrite(outstream, stringToWrite[i]);
|
||||
}
|
||||
}
|
||||
|
||||
//For reading null-terminated strings
|
||||
std::string BinaryIO::ReadString(std::istream& instream) {
|
||||
std::string toReturn;
|
||||
@ -23,36 +15,3 @@ std::string BinaryIO::ReadString(std::istream& instream) {
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
//For reading strings of a specific size
|
||||
std::string BinaryIO::ReadString(std::istream& instream, size_t size) {
|
||||
std::string toReturn;
|
||||
char buffer;
|
||||
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
BinaryIO::BinaryRead(instream, buffer);
|
||||
toReturn += buffer;
|
||||
}
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
std::string BinaryIO::ReadWString(std::istream& instream) {
|
||||
size_t size;
|
||||
BinaryRead(instream, size);
|
||||
//toReturn.resize(size);
|
||||
std::string test;
|
||||
unsigned char buf;
|
||||
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
//instream.ignore(1);
|
||||
BinaryRead(instream, buf);
|
||||
test += buf;
|
||||
}
|
||||
|
||||
//printf("%s\n", test.c_str());
|
||||
|
||||
//instream.read((char*)&toReturn[0], size * 2);
|
||||
//std::string str(toReturn.begin(), toReturn.end());
|
||||
return test;
|
||||
}
|
||||
|
@ -1,8 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef __BINARYIO__H__
|
||||
#define __BINARYIO__H__
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
#include "Game.h"
|
||||
#include "Logger.h"
|
||||
|
||||
namespace BinaryIO {
|
||||
|
||||
template<typename T>
|
||||
std::ostream& BinaryWrite(std::ostream& stream, const T& value) {
|
||||
return stream.write(reinterpret_cast<const char*>(&value), sizeof(T));
|
||||
@ -15,13 +24,51 @@ namespace BinaryIO {
|
||||
return stream.read(reinterpret_cast<char*>(&value), sizeof(T));
|
||||
}
|
||||
|
||||
void WriteString(const std::string& stringToWrite, std::ofstream& outstream);
|
||||
enum class ReadType : int8_t {
|
||||
WideString = 0,
|
||||
String = 1,
|
||||
};
|
||||
|
||||
template<typename SizeType>
|
||||
inline void ReadString(std::istream& stream, std::u16string& value) {
|
||||
static_assert(std::is_integral<SizeType>::value, "SizeType must be an integral type.");
|
||||
|
||||
SizeType size;
|
||||
BinaryRead(stream, size);
|
||||
|
||||
if (!stream.good()) throw std::runtime_error("Failed to read from istream.");
|
||||
value.resize(size);
|
||||
stream.read(reinterpret_cast<char*>(value.data()), size * sizeof(uint16_t));
|
||||
}
|
||||
|
||||
template<typename SizeType>
|
||||
inline void ReadString(std::istream& stream, std::string& value, ReadType readType) {
|
||||
static_assert(std::is_integral<SizeType>::value, "SizeType must be an integral type.");
|
||||
|
||||
SizeType size;
|
||||
BinaryRead(stream, size);
|
||||
|
||||
if (!stream.good()) throw std::runtime_error("Failed to read from istream.");
|
||||
value.resize(size);
|
||||
if (readType == ReadType::WideString) {
|
||||
uint16_t wideChar;
|
||||
|
||||
// Faster to do this than to read a u16string and convert it to a string since we only go through allocator once
|
||||
for (SizeType i = 0; i < size; ++i) {
|
||||
BinaryRead(stream, wideChar);
|
||||
value[i] = static_cast<char>(wideChar);
|
||||
}
|
||||
} else {
|
||||
stream.read(value.data(), size);
|
||||
}
|
||||
}
|
||||
|
||||
std::string ReadString(std::istream& instream);
|
||||
std::string ReadString(std::istream& instream, size_t size);
|
||||
std::string ReadWString(std::istream& instream);
|
||||
|
||||
inline bool DoesFileExist(const std::string& name) {
|
||||
std::ifstream f(name.c_str());
|
||||
return f.good();
|
||||
}
|
||||
}
|
||||
|
||||
#endif //!__BINARYIO__H__
|
||||
|
@ -28,19 +28,17 @@ FdbToSqlite::Convert::Convert(std::string binaryOutPath) {
|
||||
this->m_BinaryOutPath = binaryOutPath;
|
||||
}
|
||||
|
||||
bool FdbToSqlite::Convert::ConvertDatabase(AssetMemoryBuffer& buffer) {
|
||||
bool FdbToSqlite::Convert::ConvertDatabase(AssetStream& buffer) {
|
||||
if (m_ConversionStarted) return false;
|
||||
|
||||
std::istream cdClientBuffer(&buffer);
|
||||
|
||||
this->m_ConversionStarted = true;
|
||||
try {
|
||||
CDClientDatabase::Connect(m_BinaryOutPath + "/CDServer.sqlite");
|
||||
|
||||
CDClientDatabase::ExecuteQuery("BEGIN TRANSACTION;");
|
||||
|
||||
int32_t numberOfTables = ReadInt32(cdClientBuffer);
|
||||
ReadTables(numberOfTables, cdClientBuffer);
|
||||
int32_t numberOfTables = ReadInt32(buffer);
|
||||
ReadTables(numberOfTables, buffer);
|
||||
|
||||
CDClientDatabase::ExecuteQuery("COMMIT;");
|
||||
} catch (CppSQLite3Exception& e) {
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include <iosfwd>
|
||||
#include <map>
|
||||
|
||||
class AssetMemoryBuffer;
|
||||
#include "AssetManager.h"
|
||||
|
||||
enum class eSqliteDataType : int32_t;
|
||||
|
||||
@ -27,7 +27,7 @@ namespace FdbToSqlite {
|
||||
*
|
||||
* @return true if the database was converted properly, false otherwise.
|
||||
*/
|
||||
bool ConvertDatabase(AssetMemoryBuffer& buffer);
|
||||
bool ConvertDatabase(AssetStream& buffer);
|
||||
|
||||
/**
|
||||
* @brief Reads a 32 bit int from the fdb file.
|
||||
|
@ -234,18 +234,30 @@ namespace GeneralUtils {
|
||||
return T();
|
||||
}
|
||||
|
||||
// on Windows we need to undef these or else they conflict with our numeric limits calls
|
||||
// DEVELOPERS DEVELOPERS DEVELOPERS DEVELOPERS DEVELOPERS DEVELOPERS DEVELOPERS DEVELOPERS
|
||||
#ifdef _WIN32
|
||||
#undef min
|
||||
#undef max
|
||||
#endif
|
||||
/**
|
||||
* Casts the value of an enum entry to its underlying type
|
||||
* @param entry Enum entry to cast
|
||||
* @returns The enum entry's value in its underlying type
|
||||
*/
|
||||
template <typename eType>
|
||||
inline constexpr typename std::underlying_type_t<eType> CastUnderlyingType(const eType entry) {
|
||||
static_assert(std::is_enum_v<eType>, "Not an enum");
|
||||
|
||||
return static_cast<typename std::underlying_type_t<eType>>(entry);
|
||||
}
|
||||
|
||||
// on Windows we need to undef these or else they conflict with our numeric limits calls
|
||||
// DEVELOPERS DEVELOPERS DEVELOPERS DEVELOPERS DEVELOPERS DEVELOPERS DEVELOPERS DEVELOPERS
|
||||
#ifdef _WIN32
|
||||
#undef min
|
||||
#undef max
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
inline T GenerateRandomNumber() {
|
||||
// Make sure it is a numeric type
|
||||
static_assert(std::is_arithmetic<T>::value, "Not an arithmetic type");
|
||||
|
||||
|
||||
return GenerateRandomNumber<T>(std::numeric_limits<T>::min(), std::numeric_limits<T>::max());
|
||||
}
|
||||
}
|
||||
|
@ -152,13 +152,12 @@ bool AssetManager::GetFile(const char* name, char** data, uint32_t* len) {
|
||||
return success;
|
||||
}
|
||||
|
||||
AssetMemoryBuffer AssetManager::GetFileAsBuffer(const char* name) {
|
||||
char* buf;
|
||||
uint32_t len;
|
||||
AssetStream AssetManager::GetFile(const char* name) {
|
||||
char* buf; uint32_t len;
|
||||
|
||||
bool success = this->GetFile(name, &buf, &len);
|
||||
|
||||
return AssetMemoryBuffer(buf, len, success);
|
||||
return AssetStream(buf, len, success);
|
||||
}
|
||||
|
||||
uint32_t AssetManager::crc32b(uint32_t base, uint8_t* message, size_t l) {
|
||||
|
@ -25,6 +25,10 @@ struct AssetMemoryBuffer : std::streambuf {
|
||||
this->setg(base, base, base + n);
|
||||
}
|
||||
|
||||
~AssetMemoryBuffer() {
|
||||
if (m_Success) free(m_Base);
|
||||
}
|
||||
|
||||
pos_type seekpos(pos_type sp, std::ios_base::openmode which) override {
|
||||
return seekoff(sp - pos_type(off_type(0)), std::ios_base::beg, which);
|
||||
}
|
||||
@ -40,9 +44,17 @@ struct AssetMemoryBuffer : std::streambuf {
|
||||
setg(eback(), eback() + off, egptr());
|
||||
return gptr() - eback();
|
||||
}
|
||||
};
|
||||
|
||||
void close() {
|
||||
free(m_Base);
|
||||
struct AssetStream : std::istream {
|
||||
AssetStream(char* base, std::ptrdiff_t n, bool success) : std::istream(new AssetMemoryBuffer(base, n, success)) {}
|
||||
|
||||
~AssetStream() {
|
||||
delete rdbuf();
|
||||
}
|
||||
|
||||
operator bool() {
|
||||
return reinterpret_cast<AssetMemoryBuffer*>(rdbuf())->m_Success;
|
||||
}
|
||||
};
|
||||
|
||||
@ -56,7 +68,7 @@ public:
|
||||
|
||||
bool HasFile(const char* name);
|
||||
bool GetFile(const char* name, char** data, uint32_t* len);
|
||||
AssetMemoryBuffer GetFileAsBuffer(const char* name);
|
||||
AssetStream GetFile(const char* name);
|
||||
|
||||
private:
|
||||
void LoadPackIndex();
|
||||
|
@ -8,21 +8,10 @@ PackIndex::PackIndex(const std::filesystem::path& filePath) {
|
||||
|
||||
BinaryIO::BinaryRead<uint32_t>(m_FileStream, m_Version);
|
||||
BinaryIO::BinaryRead<uint32_t>(m_FileStream, m_PackPathCount);
|
||||
|
||||
for (int i = 0; i < m_PackPathCount; i++) {
|
||||
uint32_t stringLen = 0;
|
||||
BinaryIO::BinaryRead<uint32_t>(m_FileStream, stringLen);
|
||||
|
||||
std::string path;
|
||||
|
||||
for (int j = 0; j < stringLen; j++) {
|
||||
char inChar;
|
||||
BinaryIO::BinaryRead<char>(m_FileStream, inChar);
|
||||
|
||||
path += inChar;
|
||||
}
|
||||
|
||||
m_PackPaths.push_back(path);
|
||||
|
||||
m_PackPaths.resize(m_PackPathCount);
|
||||
for (auto& item : m_PackPaths) {
|
||||
BinaryIO::ReadString<uint32_t>(m_FileStream, item, BinaryIO::ReadType::String);
|
||||
}
|
||||
|
||||
BinaryIO::BinaryRead<uint32_t>(m_FileStream, m_PackFileIndexCount);
|
||||
|
29
dCommon/dEnums/StringifiedEnum.h
Normal file
29
dCommon/dEnums/StringifiedEnum.h
Normal file
@ -0,0 +1,29 @@
|
||||
#ifndef __STRINGIFIEDENUM_H__
|
||||
#define __STRINGIFIEDENUM_H__
|
||||
|
||||
#include <string>
|
||||
#include "magic_enum.hpp"
|
||||
|
||||
namespace StringifiedEnum {
|
||||
template<typename T>
|
||||
const std::string_view ToString(const T e) {
|
||||
static_assert(std::is_enum_v<T>, "Not an enum"); // Check type
|
||||
|
||||
constexpr auto sv = &magic_enum::enum_entries<T>();
|
||||
std::string_view output;
|
||||
|
||||
const auto it = std::lower_bound(
|
||||
sv->begin(), sv->end(), e,
|
||||
[&](const std::pair<T, std::string_view>& lhs, const T rhs) { return lhs.first < rhs; }
|
||||
);
|
||||
|
||||
if (it != sv->end() && it->first == e) {
|
||||
output = it->second;
|
||||
} else {
|
||||
output = "UNKNOWN";
|
||||
}
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // !__STRINGIFIEDENUM_H__
|
File diff suppressed because it is too large
Load Diff
@ -3,6 +3,8 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "magic_enum.hpp"
|
||||
|
||||
enum class eWorldMessageType : uint32_t {
|
||||
VALIDATION = 1, // Session info
|
||||
CHARACTER_LIST_REQUEST,
|
||||
@ -40,4 +42,10 @@ enum class eWorldMessageType : uint32_t {
|
||||
UI_HELP_TOP_5 = 91
|
||||
};
|
||||
|
||||
template <>
|
||||
struct magic_enum::customize::enum_range<eWorldMessageType> {
|
||||
static constexpr int min = 0;
|
||||
static constexpr int max = 91;
|
||||
};
|
||||
|
||||
#endif //!__EWORLDMESSAGETYPE__H__
|
||||
|
@ -166,7 +166,9 @@ void Entity::Initialize() {
|
||||
|
||||
if (!groupIDs.empty()) {
|
||||
m_Groups = GeneralUtils::SplitString(groupIDs, ';');
|
||||
m_Groups.erase(m_Groups.end() - 1);
|
||||
if (!m_Groups.empty()) {
|
||||
if (m_Groups.back().empty()) m_Groups.erase(m_Groups.end() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -334,7 +336,7 @@ void Entity::Initialize() {
|
||||
|
||||
CDDestructibleComponentTable* destCompTable = CDClientManager::Instance().GetTable<CDDestructibleComponentTable>();
|
||||
std::vector<CDDestructibleComponent> destCompData = destCompTable->Query([=](CDDestructibleComponent entry) { return (entry.id == componentID); });
|
||||
|
||||
|
||||
bool isSmashable = GetVarAs<int32_t>(u"is_smashable") != 0;
|
||||
if (buffComponentID > 0 || collectibleComponentID > 0 || isSmashable) {
|
||||
DestroyableComponent* comp = AddComponent<DestroyableComponent>();
|
||||
@ -541,8 +543,7 @@ void Entity::Initialize() {
|
||||
|
||||
// Known bug with moving platform in FV that casues it to build at the end instead of the start.
|
||||
// This extends the smash time so players can ride up the lift.
|
||||
if (m_TemplateID == 9483)
|
||||
{
|
||||
if (m_TemplateID == 9483) {
|
||||
rebuildComponent->SetResetTime(rebuildComponent->GetResetTime() + 25);
|
||||
}
|
||||
}
|
||||
|
@ -47,10 +47,6 @@ std::vector<LWOMAPID> EntityManager::m_GhostingExcludedZones = {
|
||||
|
||||
// Configure some exceptions for ghosting, nessesary for some special objects.
|
||||
std::vector<LOT> EntityManager::m_GhostingExcludedLOTs = {
|
||||
// NT - Pipes
|
||||
9524,
|
||||
12408,
|
||||
|
||||
// AG - Footrace
|
||||
4967
|
||||
};
|
||||
|
@ -60,6 +60,8 @@ void Player::SetSystemAddress(const SystemAddress& value) {
|
||||
}
|
||||
|
||||
void Player::SetRespawnPos(const NiPoint3 position) {
|
||||
if (!m_Character) return;
|
||||
|
||||
m_respawnPos = position;
|
||||
|
||||
m_Character->SetRespawnPoint(Game::zoneManager->GetZone()->GetWorldID(), position);
|
||||
|
@ -44,57 +44,53 @@ inline void StripCR(std::string& str) {
|
||||
void UserManager::Initialize() {
|
||||
std::string line;
|
||||
|
||||
AssetMemoryBuffer fnBuff = Game::assetManager->GetFileAsBuffer("names/minifigname_first.txt");
|
||||
if (!fnBuff.m_Success) {
|
||||
auto fnStream = Game::assetManager->GetFile("names/minifigname_first.txt");
|
||||
if (!fnStream) {
|
||||
LOG("Failed to load %s", (Game::assetManager->GetResPath() / "names/minifigname_first.txt").string().c_str());
|
||||
throw std::runtime_error("Aborting initialization due to missing minifigure name file.");
|
||||
}
|
||||
std::istream fnStream = std::istream(&fnBuff);
|
||||
|
||||
while (std::getline(fnStream, line, '\n')) {
|
||||
std::string name = line;
|
||||
StripCR(name);
|
||||
m_FirstNames.push_back(name);
|
||||
}
|
||||
fnBuff.close();
|
||||
|
||||
AssetMemoryBuffer mnBuff = Game::assetManager->GetFileAsBuffer("names/minifigname_middle.txt");
|
||||
if (!mnBuff.m_Success) {
|
||||
auto mnStream = Game::assetManager->GetFile("names/minifigname_middle.txt");
|
||||
if (!mnStream) {
|
||||
LOG("Failed to load %s", (Game::assetManager->GetResPath() / "names/minifigname_middle.txt").string().c_str());
|
||||
throw std::runtime_error("Aborting initialization due to missing minifigure name file.");
|
||||
}
|
||||
std::istream mnStream = std::istream(&mnBuff);
|
||||
|
||||
while (std::getline(mnStream, line, '\n')) {
|
||||
std::string name = line;
|
||||
StripCR(name);
|
||||
m_MiddleNames.push_back(name);
|
||||
}
|
||||
mnBuff.close();
|
||||
|
||||
AssetMemoryBuffer lnBuff = Game::assetManager->GetFileAsBuffer("names/minifigname_last.txt");
|
||||
if (!lnBuff.m_Success) {
|
||||
auto lnStream = Game::assetManager->GetFile("names/minifigname_last.txt");
|
||||
if (!lnStream) {
|
||||
LOG("Failed to load %s", (Game::assetManager->GetResPath() / "names/minifigname_last.txt").string().c_str());
|
||||
throw std::runtime_error("Aborting initialization due to missing minifigure name file.");
|
||||
}
|
||||
std::istream lnStream = std::istream(&lnBuff);
|
||||
|
||||
while (std::getline(lnStream, line, '\n')) {
|
||||
std::string name = line;
|
||||
StripCR(name);
|
||||
m_LastNames.push_back(name);
|
||||
}
|
||||
lnBuff.close();
|
||||
|
||||
//Load our pre-approved names:
|
||||
AssetMemoryBuffer chatListBuff = Game::assetManager->GetFileAsBuffer("chatplus_en_us.txt");
|
||||
if (!chatListBuff.m_Success) {
|
||||
// Load our pre-approved names:
|
||||
auto chatListStream = Game::assetManager->GetFile("chatplus_en_us.txt");
|
||||
if (!chatListStream) {
|
||||
LOG("Failed to load %s", (Game::assetManager->GetResPath() / "chatplus_en_us.txt").string().c_str());
|
||||
throw std::runtime_error("Aborting initialization due to missing chat whitelist file.");
|
||||
}
|
||||
std::istream chatListStream = std::istream(&chatListBuff);
|
||||
|
||||
while (std::getline(chatListStream, line, '\n')) {
|
||||
StripCR(line);
|
||||
m_PreapprovedNames.push_back(line);
|
||||
}
|
||||
chatListBuff.close();
|
||||
}
|
||||
|
||||
UserManager::~UserManager() {
|
||||
|
@ -22,7 +22,6 @@ void BasicAttackBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bi
|
||||
if (entity->IsPlayer() && !this->m_DontApplyImmune) {
|
||||
const float immunityTime = Game::zoneManager->GetWorldConfig()->globalImmunityTime;
|
||||
destroyableComponent->SetDamageCooldownTimer(immunityTime);
|
||||
LOG_DEBUG("Target targetEntity %llu took damage, setting damage cooldown timer to %f s", branch.target, immunityTime);
|
||||
}
|
||||
}
|
||||
|
||||
@ -188,11 +187,7 @@ void BasicAttackBehavior::DoBehaviorCalculation(BehaviorContext* context, RakNet
|
||||
return;
|
||||
}
|
||||
|
||||
const float immunityTime = Game::zoneManager->GetWorldConfig()->globalImmunityTime;
|
||||
LOG_DEBUG("Damage cooldown timer currently %f s", destroyableComponent->GetDamageCooldownTimer());
|
||||
|
||||
const bool isImmune = (destroyableComponent->IsImmune()) || (destroyableComponent->IsCooldownImmune());
|
||||
|
||||
const bool isImmune = destroyableComponent->IsImmune() || destroyableComponent->IsCooldownImmune();
|
||||
bitStream->Write(isImmune);
|
||||
|
||||
if (isImmune) {
|
||||
@ -219,8 +214,7 @@ void BasicAttackBehavior::DoBehaviorCalculation(BehaviorContext* context, RakNet
|
||||
|
||||
//Handle player damage cooldown
|
||||
if (isSuccess && targetEntity->IsPlayer() && !this->m_DontApplyImmune) {
|
||||
destroyableComponent->SetDamageCooldownTimer(immunityTime);
|
||||
LOG_DEBUG("Target targetEntity %llu took damage, setting damage cooldown timer to %f s", branch.target, immunityTime);
|
||||
destroyableComponent->SetDamageCooldownTimer(Game::zoneManager->GetWorldConfig()->globalImmunityTime);
|
||||
}
|
||||
|
||||
eBasicAttackSuccessTypes successState = eBasicAttackSuccessTypes::FAILIMMUNE;
|
||||
|
@ -398,7 +398,8 @@ void BuffComponent::UpdateXml(tinyxml2::XMLDocument* doc) {
|
||||
|
||||
for (const auto& [id, buff] : m_Buffs) {
|
||||
auto* buffEntry = doc->NewElement("b");
|
||||
if (buff.cancelOnZone || buff.cancelOnLogout) continue;
|
||||
// TODO: change this if to if (buff.cancelOnZone || buff.cancelOnLogout) handling at some point. No current way to differentiate between zone transfer and logout.
|
||||
if (buff.cancelOnZone) continue;
|
||||
|
||||
buffEntry->SetAttribute("id", id);
|
||||
buffEntry->SetAttribute("t", buff.time);
|
||||
|
@ -557,7 +557,7 @@ void DestroyableComponent::Damage(uint32_t damage, const LWOOBJID source, uint32
|
||||
}
|
||||
|
||||
if (IsImmune() || IsCooldownImmune()) {
|
||||
LOG_DEBUG("Target targetEntity %llu is immune!", m_Parent->GetObjectID()); //Immune is succesfully proc'd
|
||||
LOG_DEBUG("Target targetEntity %llu is immune!", m_Parent->GetObjectID());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -621,3 +621,12 @@ bool MissionComponent::HasCollectible(int32_t collectibleID) {
|
||||
bool MissionComponent::HasMission(uint32_t missionId) {
|
||||
return GetMission(missionId) != nullptr;
|
||||
}
|
||||
|
||||
void MissionComponent::ResetMission(const int32_t missionId) {
|
||||
auto* mission = GetMission(missionId);
|
||||
|
||||
if (!mission) return;
|
||||
|
||||
m_Missions.erase(missionId);
|
||||
GameMessages::SendResetMissions(m_Parent, m_Parent->GetSystemAddress(), missionId);
|
||||
}
|
||||
|
@ -170,6 +170,7 @@ public:
|
||||
*/
|
||||
bool HasMission(uint32_t missionId);
|
||||
|
||||
void ResetMission(const int32_t missionId);
|
||||
private:
|
||||
/**
|
||||
* All the missions owned by this entity, mapped by mission ID
|
||||
|
@ -29,11 +29,11 @@ uint32_t OfferedMission::GetMissionId() const {
|
||||
return this->missionId;
|
||||
}
|
||||
|
||||
bool OfferedMission::GetOfferMission() const {
|
||||
bool OfferedMission::GetOffersMission() const {
|
||||
return this->offersMission;
|
||||
}
|
||||
|
||||
bool OfferedMission::GetAcceptMission() const {
|
||||
bool OfferedMission::GetAcceptsMission() const {
|
||||
return this->acceptsMission;
|
||||
}
|
||||
|
||||
@ -203,7 +203,10 @@ void MissionOfferComponent::OfferMissions(Entity* entity, const uint32_t specifi
|
||||
const auto selected = canAcceptPool[GeneralUtils::GenerateRandomNumber<int>(0, canAcceptPool.size() - 1)];
|
||||
|
||||
GameMessages::SendOfferMission(entity->GetObjectID(), entity->GetSystemAddress(), selected, m_Parent->GetObjectID());
|
||||
} else if (std::find(offered.begin(), offered.end(), missionId) == offered.end() && offeredMission->GetOfferMission()) {
|
||||
} else if (
|
||||
std::find(offered.begin(), offered.end(), missionId) == offered.end()
|
||||
&&
|
||||
(offeredMission->GetOffersMission() || offeredMission->GetAcceptsMission())) {
|
||||
GameMessages::SendOfferMission(entity->GetObjectID(), entity->GetSystemAddress(), missionId, m_Parent->GetObjectID());
|
||||
}
|
||||
}
|
||||
|
@ -30,13 +30,13 @@ struct OfferedMission {
|
||||
* Returns if this mission is offered by the entity
|
||||
* @return true if this mission is offered by the entity, false otherwise
|
||||
*/
|
||||
bool GetOfferMission() const;
|
||||
bool GetOffersMission() const;
|
||||
|
||||
/**
|
||||
* Returns if this mission may be accepted by the entity (currently unused)
|
||||
* @return true if this mission may be accepted by the entity, false otherwise
|
||||
*/
|
||||
bool GetAcceptMission() const;
|
||||
bool GetAcceptsMission() const;
|
||||
|
||||
private:
|
||||
|
||||
|
@ -24,6 +24,7 @@ void ShootingGalleryComponent::Serialize(RakNet::BitStream* outBitStream, bool i
|
||||
outBitStream->Write<uint32_t>(0);
|
||||
} else {
|
||||
outBitStream->Write<uint32_t>(1);
|
||||
outBitStream->Write<LWOOBJID>(m_CurrentPlayerID);
|
||||
for (size_t i = 0; i < 10; i++) {
|
||||
outBitStream->Write<float_t>(0.0f);
|
||||
}
|
||||
@ -60,6 +61,7 @@ void ShootingGalleryComponent::Serialize(RakNet::BitStream* outBitStream, bool i
|
||||
outBitStream->Write<LWOOBJID>(m_CurrentPlayerID);
|
||||
outBitStream->Write<float_t>(m_DynamicParams.cannonTimeout);
|
||||
outBitStream->Write<float_t>(m_DynamicParams.cannonFOV);
|
||||
if (!isInitialUpdate) m_Dirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,10 +34,10 @@
|
||||
#include "eMissionTaskType.h"
|
||||
#include "eReplicaComponentType.h"
|
||||
#include "eConnectionType.h"
|
||||
#include "eGameMessageType.h"
|
||||
#include "ePlayerFlag.h"
|
||||
#include "dConfig.h"
|
||||
|
||||
using namespace std;
|
||||
#include "StringifiedEnum.h"
|
||||
|
||||
void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const SystemAddress& sysAddr, LWOOBJID objectID, eGameMessageType messageID) {
|
||||
|
||||
@ -49,11 +49,11 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System
|
||||
User* usr = UserManager::Instance()->GetUser(sysAddr);
|
||||
|
||||
if (!entity) {
|
||||
LOG("Failed to find associated entity (%llu), aborting GM (%X)!", objectID, messageID);
|
||||
LOG("Failed to find associated entity (%llu), aborting GM: %4i, %s!", objectID, messageID, StringifiedEnum::ToString(messageID).data());
|
||||
return;
|
||||
}
|
||||
|
||||
if (messageID != eGameMessageType::READY_FOR_UPDATES) LOG_DEBUG("received game message ID: %i", messageID);
|
||||
if (messageID != eGameMessageType::READY_FOR_UPDATES) LOG_DEBUG("Received GM with ID and name: %4i, %s", messageID, StringifiedEnum::ToString(messageID).data());
|
||||
|
||||
switch (messageID) {
|
||||
|
||||
@ -344,12 +344,12 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System
|
||||
|
||||
SyncSkill sync = SyncSkill(inStream); // inStream replaced &bitStream
|
||||
|
||||
ostringstream buffer;
|
||||
std::ostringstream buffer;
|
||||
|
||||
for (unsigned int k = 0; k < sync.sBitStream.size(); k++) {
|
||||
char s;
|
||||
s = sync.sBitStream.at(k);
|
||||
buffer << setw(2) << hex << setfill('0') << (int)s << " ";
|
||||
buffer << std::setw(2) << std::hex << std::setfill('0') << static_cast<int>(s) << " ";
|
||||
}
|
||||
|
||||
if (usr != nullptr) {
|
||||
@ -690,8 +690,11 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System
|
||||
case eGameMessageType::CANCEL_DONATION_ON_PLAYER:
|
||||
GameMessages::HandleCancelDonationOnPlayer(inStream, entity);
|
||||
break;
|
||||
case eGameMessageType::REQUEST_VENDOR_STATUS_UPDATE:
|
||||
GameMessages::SendVendorStatusUpdate(entity, sysAddr, true);
|
||||
break;
|
||||
default:
|
||||
LOG_DEBUG("Unknown game message ID: %i", messageID);
|
||||
LOG_DEBUG("Received Unknown GM with ID: %4i, %s", messageID, StringifiedEnum::ToString(messageID).data());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -19,8 +19,7 @@
|
||||
#include "Logger.h"
|
||||
#include "GameMessages.h"
|
||||
#include "CDClientDatabase.h"
|
||||
|
||||
enum class eGameMessageType : uint16_t;
|
||||
#include "eGameMessageType.h"
|
||||
|
||||
namespace GameMessageHandler {
|
||||
void HandleMessage(RakNet::BitStream* inStream, const SystemAddress& sysAddr, LWOOBJID objectID, eGameMessageType messageID);
|
||||
|
@ -113,7 +113,7 @@ void GameMessages::SendFireEventClientSide(const LWOOBJID& objectID, const Syste
|
||||
uint32_t argSize = args.size();
|
||||
bitStream.Write(argSize);
|
||||
for (uint32_t k = 0; k < argSize; k++) {
|
||||
bitStream.Write(static_cast<uint16_t>(args[k]));
|
||||
bitStream.Write<uint16_t>(args[k]);
|
||||
}
|
||||
bitStream.Write(object);
|
||||
bitStream.Write0();
|
||||
@ -223,13 +223,13 @@ void GameMessages::SendInvalidZoneTransferList(Entity* entity, const SystemAddre
|
||||
uint32_t CustomerFeedbackURLLength = feedbackURL.size();
|
||||
bitStream.Write(CustomerFeedbackURLLength);
|
||||
for (uint32_t k = 0; k < CustomerFeedbackURLLength; k++) {
|
||||
bitStream.Write(static_cast<uint16_t>(feedbackURL[k]));
|
||||
bitStream.Write<uint16_t>(feedbackURL[k]);
|
||||
}
|
||||
|
||||
uint32_t InvalidMapTransferListLength = invalidMapTransferList.size();
|
||||
bitStream.Write(InvalidMapTransferListLength);
|
||||
for (uint32_t k = 0; k < InvalidMapTransferListLength; k++) {
|
||||
bitStream.Write(static_cast<uint16_t>(invalidMapTransferList[k]));
|
||||
bitStream.Write<uint16_t>(invalidMapTransferList[k]);
|
||||
}
|
||||
|
||||
bitStream.Write(feedbackOnExit);
|
||||
@ -320,17 +320,17 @@ void GameMessages::SendPlayNDAudioEmitter(Entity* entity, const SystemAddress& s
|
||||
CMSGHEADER;
|
||||
|
||||
bitStream.Write(entity->GetObjectID());
|
||||
bitStream.Write((uint16_t)eGameMessageType::PLAY_ND_AUDIO_EMITTER);
|
||||
bitStream.Write(eGameMessageType::PLAY_ND_AUDIO_EMITTER);
|
||||
bitStream.Write0();
|
||||
bitStream.Write0();
|
||||
|
||||
uint32_t length = audioGUID.size();
|
||||
bitStream.Write(length);
|
||||
for (uint32_t k = 0; k < length; k++) {
|
||||
bitStream.Write(static_cast<char>(audioGUID[k]));
|
||||
bitStream.Write<char>(audioGUID[k]);
|
||||
}
|
||||
|
||||
bitStream.Write(uint32_t(0));
|
||||
bitStream.Write<uint32_t>(0);
|
||||
bitStream.Write0();
|
||||
bitStream.Write0();
|
||||
|
||||
@ -347,6 +347,19 @@ void GameMessages::SendStartPathing(Entity* entity) {
|
||||
SEND_PACKET_BROADCAST;
|
||||
}
|
||||
|
||||
void GameMessages::SendResetMissions(Entity* entity, const SystemAddress& sysAddr, const int32_t missionid) {
|
||||
CBITSTREAM;
|
||||
CMSGHEADER;
|
||||
|
||||
bitStream.Write(entity->GetObjectID());
|
||||
bitStream.Write(eGameMessageType::RESET_MISSIONS);
|
||||
|
||||
bitStream.Write(missionid != -1);
|
||||
if (missionid != -1) bitStream.Write(missionid);
|
||||
|
||||
SEND_PACKET;
|
||||
}
|
||||
|
||||
void GameMessages::SendPlatformResync(Entity* entity, const SystemAddress& sysAddr, bool bStopAtDesiredWaypoint,
|
||||
int iIndex, int iDesiredWaypointIndex, int nextIndex,
|
||||
eMovementPlatformState movementState) {
|
||||
@ -364,7 +377,7 @@ void GameMessages::SendPlatformResync(Entity* entity, const SystemAddress& sysAd
|
||||
}
|
||||
|
||||
bitStream.Write(entity->GetObjectID());
|
||||
bitStream.Write((uint16_t)eGameMessageType::PLATFORM_RESYNC);
|
||||
bitStream.Write(eGameMessageType::PLATFORM_RESYNC);
|
||||
|
||||
bool bReverse = false;
|
||||
int eCommand = 0;
|
||||
@ -421,7 +434,7 @@ void GameMessages::SendChatModeUpdate(const LWOOBJID& objectID, eGameMasterLevel
|
||||
CBITSTREAM;
|
||||
CMSGHEADER;
|
||||
bitStream.Write(objectID);
|
||||
bitStream.Write((uint16_t)eGameMessageType::UPDATE_CHAT_MODE);
|
||||
bitStream.Write(eGameMessageType::UPDATE_CHAT_MODE);
|
||||
bitStream.Write(level);
|
||||
SEND_PACKET_BROADCAST;
|
||||
}
|
||||
@ -430,7 +443,7 @@ void GameMessages::SendGMLevelBroadcast(const LWOOBJID& objectID, eGameMasterLev
|
||||
CBITSTREAM;
|
||||
CMSGHEADER;
|
||||
bitStream.Write(objectID);
|
||||
bitStream.Write((uint16_t)eGameMessageType::SET_GM_LEVEL);
|
||||
bitStream.Write(eGameMessageType::SET_GM_LEVEL);
|
||||
bitStream.Write1();
|
||||
bitStream.Write(level);
|
||||
SEND_PACKET_BROADCAST;
|
||||
@ -461,9 +474,9 @@ void GameMessages::SendAddItemToInventoryClientSync(Entity* entity, const System
|
||||
bitStream.Write<uint32_t>(extraInfo.name.size());
|
||||
if (extraInfo.name.size() > 0) {
|
||||
for (uint32_t i = 0; i < extraInfo.name.size(); ++i) {
|
||||
bitStream.Write(static_cast<uint16_t>(extraInfo.name[i]));
|
||||
bitStream.Write<uint16_t>(extraInfo.name[i]);
|
||||
}
|
||||
bitStream.Write(static_cast<uint16_t>(0x00));
|
||||
bitStream.Write<uint16_t>(0x00);
|
||||
}
|
||||
|
||||
bitStream.Write(item->GetLot());
|
||||
@ -500,7 +513,7 @@ void GameMessages::SendNotifyClientFlagChange(const LWOOBJID& objectID, uint32_t
|
||||
CMSGHEADER;
|
||||
|
||||
bitStream.Write(objectID);
|
||||
bitStream.Write((uint16_t)eGameMessageType::NOTIFY_CLIENT_FLAG_CHANGE);
|
||||
bitStream.Write(eGameMessageType::NOTIFY_CLIENT_FLAG_CHANGE);
|
||||
bitStream.Write(bFlag);
|
||||
bitStream.Write(iFlagID);
|
||||
|
||||
@ -523,7 +536,7 @@ void GameMessages::SendChangeObjectWorldState(const LWOOBJID& objectID, eObjectW
|
||||
CMSGHEADER;
|
||||
|
||||
bitStream.Write(objectID);
|
||||
bitStream.Write((uint16_t)eGameMessageType::CHANGE_OBJECT_WORLD_STATE);
|
||||
bitStream.Write(eGameMessageType::CHANGE_OBJECT_WORLD_STATE);
|
||||
bitStream.Write(state);
|
||||
|
||||
if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST
|
||||
@ -578,7 +591,7 @@ void GameMessages::SendNotifyMissionTask(Entity* entity, const SystemAddress& sy
|
||||
CMSGHEADER;
|
||||
|
||||
bitStream.Write(entity->GetObjectID());
|
||||
bitStream.Write((uint16_t)eGameMessageType::NOTIFY_MISSION_TASK);
|
||||
bitStream.Write(eGameMessageType::NOTIFY_MISSION_TASK);
|
||||
|
||||
bitStream.Write(missionID);
|
||||
bitStream.Write(taskMask);
|
||||
@ -596,7 +609,7 @@ void GameMessages::SendModifyLEGOScore(Entity* entity, const SystemAddress& sysA
|
||||
CMSGHEADER;
|
||||
|
||||
bitStream.Write(entity->GetObjectID());
|
||||
bitStream.Write((uint16_t)eGameMessageType::MODIFY_LEGO_SCORE);
|
||||
bitStream.Write(eGameMessageType::MODIFY_LEGO_SCORE);
|
||||
bitStream.Write(score);
|
||||
|
||||
bitStream.Write(sourceType != eLootSourceType::NONE);
|
||||
@ -610,14 +623,14 @@ void GameMessages::SendUIMessageServerToSingleClient(Entity* entity, const Syste
|
||||
CMSGHEADER;
|
||||
|
||||
bitStream.Write(entity->GetObjectID());
|
||||
bitStream.Write((uint16_t)eGameMessageType::UI_MESSAGE_SERVER_TO_SINGLE_CLIENT);
|
||||
bitStream.Write(eGameMessageType::UI_MESSAGE_SERVER_TO_SINGLE_CLIENT);
|
||||
|
||||
bitStream.Write<AMFBaseValue&>(args);
|
||||
uint32_t strMessageNameLength = message.size();
|
||||
bitStream.Write(strMessageNameLength);
|
||||
|
||||
for (uint32_t k = 0; k < strMessageNameLength; k++) {
|
||||
bitStream.Write(static_cast<char>(message[k]));
|
||||
bitStream.Write<char>(message[k]);
|
||||
}
|
||||
|
||||
SEND_PACKET;
|
||||
@ -629,14 +642,14 @@ void GameMessages::SendUIMessageServerToAllClients(const std::string& message, A
|
||||
|
||||
LWOOBJID empty = 0;
|
||||
bitStream.Write(empty);
|
||||
bitStream.Write((uint16_t)eGameMessageType::UI_MESSAGE_SERVER_TO_ALL_CLIENTS);
|
||||
bitStream.Write(eGameMessageType::UI_MESSAGE_SERVER_TO_ALL_CLIENTS);
|
||||
|
||||
bitStream.Write<AMFBaseValue&>(args);
|
||||
uint32_t strMessageNameLength = message.size();
|
||||
bitStream.Write(strMessageNameLength);
|
||||
|
||||
for (uint32_t k = 0; k < strMessageNameLength; k++) {
|
||||
bitStream.Write(static_cast<char>(message[k]));
|
||||
bitStream.Write<char>(message[k]);
|
||||
}
|
||||
|
||||
SEND_PACKET_BROADCAST;
|
||||
@ -647,11 +660,11 @@ void GameMessages::SendPlayEmbeddedEffectOnAllClientsNearObject(Entity* entity,
|
||||
CMSGHEADER;
|
||||
|
||||
bitStream.Write(entity->GetObjectID());
|
||||
bitStream.Write((uint16_t)eGameMessageType::PLAY_EMBEDDED_EFFECT_ON_ALL_CLIENTS_NEAR_OBJECT);
|
||||
bitStream.Write(eGameMessageType::PLAY_EMBEDDED_EFFECT_ON_ALL_CLIENTS_NEAR_OBJECT);
|
||||
|
||||
bitStream.Write(static_cast<uint32_t>(effectName.length()));
|
||||
bitStream.Write<uint32_t>(effectName.length());
|
||||
for (uint32_t k = 0; k < effectName.length(); k++) {
|
||||
bitStream.Write(static_cast<uint16_t>(effectName[k]));
|
||||
bitStream.Write<uint16_t>(effectName[k]);
|
||||
}
|
||||
bitStream.Write(fromObjectID);
|
||||
bitStream.Write(radius);
|
||||
@ -668,7 +681,7 @@ void GameMessages::SendPlayFXEffect(const LWOOBJID& entity, int32_t effectID, co
|
||||
CMSGHEADER;
|
||||
|
||||
bitStream.Write(entity);
|
||||
bitStream.Write((uint16_t)eGameMessageType::PLAY_FX_EFFECT);
|
||||
bitStream.Write(eGameMessageType::PLAY_FX_EFFECT);
|
||||
|
||||
bitStream.Write(effectID != -1);
|
||||
if (effectID != -1) bitStream.Write(effectID);
|
||||
@ -716,22 +729,22 @@ void GameMessages::SendBroadcastTextToChatbox(Entity* entity, const SystemAddres
|
||||
CMSGHEADER;
|
||||
|
||||
bitStream.Write(entity->GetObjectID());
|
||||
bitStream.Write((uint16_t)eGameMessageType::BROADCAST_TEXT_TO_CHATBOX);
|
||||
bitStream.Write(eGameMessageType::BROADCAST_TEXT_TO_CHATBOX);
|
||||
|
||||
LWONameValue attribs;
|
||||
attribs.name = attrs;
|
||||
attribs.length = attrs.size();
|
||||
|
||||
bitStream.Write(static_cast<uint32_t>(attribs.length));
|
||||
bitStream.Write<uint32_t>(attribs.length);
|
||||
for (uint32_t i = 0; i < attribs.length; ++i) {
|
||||
bitStream.Write(static_cast<uint16_t>(attribs.name[i]));
|
||||
bitStream.Write<uint16_t>(attribs.name[i]);
|
||||
}
|
||||
bitStream.Write(static_cast<uint16_t>(0x00)); // Null Terminator
|
||||
bitStream.Write<uint16_t>(0x00); // Null Terminator
|
||||
|
||||
uint32_t wsTextLength = wsText.size();
|
||||
bitStream.Write(wsTextLength);
|
||||
for (uint32_t k = 0; k < wsTextLength; k++) {
|
||||
bitStream.Write(static_cast<uint16_t>(wsText[k]));
|
||||
bitStream.Write<uint16_t>(wsText[k]);
|
||||
}
|
||||
|
||||
SEND_PACKET_BROADCAST;
|
||||
@ -772,7 +785,7 @@ void GameMessages::SendRebuildNotifyState(Entity* entity, eRebuildState prevStat
|
||||
CMSGHEADER;
|
||||
|
||||
bitStream.Write(entity->GetObjectID());
|
||||
bitStream.Write((uint16_t)eGameMessageType::REBUILD_NOTIFY_STATE);
|
||||
bitStream.Write(eGameMessageType::REBUILD_NOTIFY_STATE);
|
||||
|
||||
bitStream.Write(prevState);
|
||||
bitStream.Write(state);
|
||||
@ -786,7 +799,7 @@ void GameMessages::SendEnableRebuild(Entity* entity, bool enable, bool fail, boo
|
||||
CMSGHEADER;
|
||||
|
||||
bitStream.Write(entity->GetObjectID());
|
||||
bitStream.Write((uint16_t)eGameMessageType::ENABLE_REBUILD);
|
||||
bitStream.Write(eGameMessageType::ENABLE_REBUILD);
|
||||
|
||||
bitStream.Write(enable);
|
||||
bitStream.Write(fail);
|
||||
@ -806,7 +819,7 @@ void GameMessages::SendTerminateInteraction(const LWOOBJID& objectID, eTerminate
|
||||
CMSGHEADER;
|
||||
|
||||
bitStream.Write(objectID);
|
||||
bitStream.Write((uint16_t)eGameMessageType::TERMINATE_INTERACTION);
|
||||
bitStream.Write(eGameMessageType::TERMINATE_INTERACTION);
|
||||
|
||||
bitStream.Write(terminator);
|
||||
bitStream.Write(type);
|
||||
@ -842,7 +855,7 @@ void GameMessages::SendDie(Entity* entity, const LWOOBJID& killerID, const LWOOB
|
||||
|
||||
bitStream.Write(entity->GetObjectID());
|
||||
|
||||
bitStream.Write((uint16_t)eGameMessageType::DIE);
|
||||
bitStream.Write(eGameMessageType::DIE);
|
||||
|
||||
bitStream.Write(bClientDeath);
|
||||
bitStream.Write(bSpawnLoot);
|
||||
@ -853,7 +866,7 @@ void GameMessages::SendDie(Entity* entity, const LWOOBJID& killerID, const LWOOB
|
||||
uint32_t deathTypeLength = deathType.size();
|
||||
bitStream.Write(deathTypeLength);
|
||||
for (uint32_t k = 0; k < deathTypeLength; k++) {
|
||||
bitStream.Write(static_cast<uint16_t>(deathType[k]));
|
||||
bitStream.Write<uint16_t>(deathType[k]);
|
||||
}
|
||||
|
||||
bitStream.Write(directionRelative_AngleXZ);
|
||||
@ -976,7 +989,7 @@ void GameMessages::SendStop2DAmbientSound(Entity* entity, bool force, std::strin
|
||||
CMSGHEADER;
|
||||
|
||||
bitStream.Write(entity->GetObjectID());
|
||||
bitStream.Write((uint16_t)eGameMessageType::STOP2_D_AMBIENT_SOUND);
|
||||
bitStream.Write(eGameMessageType::STOP2_D_AMBIENT_SOUND);
|
||||
|
||||
uint32_t audioGUIDSize = audioGUID.size();
|
||||
|
||||
@ -984,7 +997,7 @@ void GameMessages::SendStop2DAmbientSound(Entity* entity, bool force, std::strin
|
||||
bitStream.Write(audioGUIDSize);
|
||||
|
||||
for (uint32_t k = 0; k < audioGUIDSize; k++) {
|
||||
bitStream.Write(static_cast<char>(audioGUID[k]));
|
||||
bitStream.Write<char>(audioGUID[k]);
|
||||
}
|
||||
|
||||
bitStream.Write(result);
|
||||
@ -999,13 +1012,12 @@ void GameMessages::SendPlay2DAmbientSound(Entity* entity, std::string audioGUID,
|
||||
CMSGHEADER;
|
||||
|
||||
bitStream.Write(entity->GetObjectID());
|
||||
bitStream.Write((uint16_t)eGameMessageType::PLAY2_D_AMBIENT_SOUND);
|
||||
|
||||
bitStream.Write(eGameMessageType::PLAY2_D_AMBIENT_SOUND);
|
||||
uint32_t audioGUIDSize = audioGUID.size();
|
||||
|
||||
bitStream.Write(audioGUIDSize);
|
||||
for (uint32_t k = 0; k < audioGUIDSize; k++) {
|
||||
bitStream.Write(static_cast<char>(audioGUID[k]));
|
||||
bitStream.Write<char>(audioGUID[k]);
|
||||
}
|
||||
bitStream.Write(result);
|
||||
|
||||
@ -1018,7 +1030,7 @@ void GameMessages::SendSetNetworkScriptVar(Entity* entity, const SystemAddress&
|
||||
CMSGHEADER;
|
||||
|
||||
bitStream.Write(entity->GetObjectID());
|
||||
bitStream.Write((uint16_t)eGameMessageType::SCRIPT_NETWORK_VAR_UPDATE);
|
||||
bitStream.Write(eGameMessageType::SCRIPT_NETWORK_VAR_UPDATE);
|
||||
|
||||
// FIXME: this is a bad place to need to do a conversion because we have no clue whether data is utf8 or plain ascii
|
||||
// an this has performance implications
|
||||
@ -1027,9 +1039,9 @@ void GameMessages::SendSetNetworkScriptVar(Entity* entity, const SystemAddress&
|
||||
|
||||
bitStream.Write(dataSize);
|
||||
for (auto value : u16Data) {
|
||||
bitStream.Write(uint16_t(value));
|
||||
bitStream.Write<uint16_t>(value);
|
||||
}
|
||||
if (dataSize > 0) bitStream.Write(uint16_t(0));
|
||||
if (dataSize > 0) bitStream.Write<uint16_t>(0);
|
||||
|
||||
if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST;
|
||||
SEND_PACKET;
|
||||
@ -1144,7 +1156,7 @@ void GameMessages::SendPlayerReachedRespawnCheckpoint(Entity* entity, const NiPo
|
||||
CMSGHEADER;
|
||||
|
||||
bitStream.Write(entity->GetObjectID());
|
||||
bitStream.Write((uint16_t)eGameMessageType::PLAYER_REACHED_RESPAWN_CHECKPOINT);
|
||||
bitStream.Write(eGameMessageType::PLAYER_REACHED_RESPAWN_CHECKPOINT);
|
||||
|
||||
bitStream.Write(position.x);
|
||||
bitStream.Write(position.y);
|
||||
@ -1176,7 +1188,7 @@ void GameMessages::SendAddSkill(Entity* entity, TSkillID skillID, BehaviorSlot s
|
||||
CMSGHEADER;
|
||||
|
||||
bitStream.Write(entity->GetObjectID());
|
||||
bitStream.Write((uint16_t)eGameMessageType::ADD_SKILL);
|
||||
bitStream.Write(eGameMessageType::ADD_SKILL);
|
||||
|
||||
bitStream.Write(AICombatWeight != 0);
|
||||
if (AICombatWeight != 0) bitStream.Write(AICombatWeight);
|
||||
@ -1345,8 +1357,8 @@ void GameMessages::SendRemoveItemFromInventory(Entity* entity, const SystemAddre
|
||||
bitStream.Write(eInvType);
|
||||
bitStream.Write1();
|
||||
bitStream.Write(eLootTypeSource);
|
||||
bitStream.Write(static_cast<uint32_t>(0)); //extra info
|
||||
//bitStream.Write(static_cast<uint16_t>(0)); //extra info
|
||||
bitStream.Write<uint32_t>(0); //extra info
|
||||
//bitStream.Write<uint16_t>(0); //extra info
|
||||
bitStream.Write(forceDeletion);
|
||||
bitStream.Write0();
|
||||
bitStream.Write1();
|
||||
@ -1469,11 +1481,11 @@ void GameMessages::SendMatchUpdate(Entity* entity, const SystemAddress& sysAddr,
|
||||
|
||||
bitStream.Write(entity->GetObjectID());
|
||||
bitStream.Write(eGameMessageType::MATCH_UPDATE);
|
||||
bitStream.Write(uint32_t(data.size()));
|
||||
bitStream.Write<uint32_t>(data.size());
|
||||
for (char character : data) {
|
||||
bitStream.Write(uint16_t(character));
|
||||
bitStream.Write<uint16_t>(character);
|
||||
}
|
||||
if (data.size() > 0) bitStream.Write(uint16_t(0));
|
||||
if (data.size() > 0) bitStream.Write<uint16_t>(0);
|
||||
bitStream.Write(type);
|
||||
|
||||
SEND_PACKET;
|
||||
@ -1557,7 +1569,7 @@ void GameMessages::NotifyLevelRewards(LWOOBJID objectID, const SystemAddress& sy
|
||||
CMSGHEADER;
|
||||
|
||||
bitStream.Write(objectID);
|
||||
bitStream.Write((uint16_t)eGameMessageType::NOTIFY_LEVEL_REWARDS);
|
||||
bitStream.Write(eGameMessageType::NOTIFY_LEVEL_REWARDS);
|
||||
|
||||
bitStream.Write(level);
|
||||
bitStream.Write(sending_rewards);
|
||||
@ -1743,7 +1755,7 @@ void GameMessages::SendSetRailMovement(const LWOOBJID& objectID, bool pathGoForw
|
||||
|
||||
bitStream.Write(pathGoForward);
|
||||
|
||||
bitStream.Write(uint32_t(pathName.size()));
|
||||
bitStream.Write<uint32_t>(pathName.size());
|
||||
for (auto character : pathName) {
|
||||
bitStream.Write<uint16_t>(character);
|
||||
}
|
||||
@ -1782,14 +1794,14 @@ void GameMessages::SendStartRailMovement(const LWOOBJID& objectID, std::u16strin
|
||||
bitStream.Write(cameraLocked);
|
||||
bitStream.Write(collisionEnabled);
|
||||
|
||||
bitStream.Write(uint32_t(loopSound.size()));
|
||||
bitStream.Write<uint32_t>(loopSound.size());
|
||||
for (auto character : loopSound) {
|
||||
bitStream.Write<uint16_t>(character);
|
||||
}
|
||||
|
||||
bitStream.Write(goForward);
|
||||
|
||||
bitStream.Write(uint32_t(pathName.size()));
|
||||
bitStream.Write<uint32_t>(pathName.size());
|
||||
for (auto character : pathName) {
|
||||
bitStream.Write<uint16_t>(character);
|
||||
}
|
||||
@ -1812,12 +1824,12 @@ void GameMessages::SendStartRailMovement(const LWOOBJID& objectID, std::u16strin
|
||||
bitStream.Write<LWOOBJID>(railActivatorObjectID);
|
||||
}
|
||||
|
||||
bitStream.Write(uint32_t(startSound.size()));
|
||||
bitStream.Write<uint32_t>(startSound.size());
|
||||
for (auto character : startSound) {
|
||||
bitStream.Write<uint16_t>(character);
|
||||
}
|
||||
|
||||
bitStream.Write(uint32_t(stopSound.size()));
|
||||
bitStream.Write<uint32_t>(stopSound.size());
|
||||
for (auto character : stopSound) {
|
||||
bitStream.Write<uint16_t>(character);
|
||||
}
|
||||
@ -1835,7 +1847,7 @@ void GameMessages::SendNotifyClientObject(const LWOOBJID& objectID, std::u16stri
|
||||
bitStream.Write(objectID);
|
||||
bitStream.Write(eGameMessageType::NOTIFY_CLIENT_OBJECT);
|
||||
|
||||
bitStream.Write(uint32_t(name.size()));
|
||||
bitStream.Write<uint32_t>(name.size());
|
||||
for (auto character : name) {
|
||||
bitStream.Write<uint16_t>(character);
|
||||
}
|
||||
@ -1846,7 +1858,7 @@ void GameMessages::SendNotifyClientObject(const LWOOBJID& objectID, std::u16stri
|
||||
|
||||
bitStream.Write(paramObj);
|
||||
|
||||
bitStream.Write(uint32_t(paramStr.size()));
|
||||
bitStream.Write<uint32_t>(paramStr.size());
|
||||
for (auto character : paramStr) {
|
||||
bitStream.Write(character);
|
||||
}
|
||||
@ -1864,7 +1876,7 @@ void GameMessages::SendNotifyClientZoneObject(const LWOOBJID& objectID, const st
|
||||
bitStream.Write(objectID);
|
||||
bitStream.Write(eGameMessageType::NOTIFY_CLIENT_ZONE_OBJECT);
|
||||
|
||||
bitStream.Write(uint32_t(name.size()));
|
||||
bitStream.Write<uint32_t>(name.size());
|
||||
for (const auto& character : name) {
|
||||
bitStream.Write<uint16_t>(character);
|
||||
}
|
||||
@ -1873,7 +1885,7 @@ void GameMessages::SendNotifyClientZoneObject(const LWOOBJID& objectID, const st
|
||||
bitStream.Write(param2);
|
||||
bitStream.Write(paramObj);
|
||||
|
||||
bitStream.Write(uint32_t(paramStr.size()));
|
||||
bitStream.Write<uint32_t>(paramStr.size());
|
||||
for (const auto& character : paramStr) {
|
||||
bitStream.Write(character);
|
||||
}
|
||||
@ -1890,9 +1902,9 @@ void GameMessages::SendNotifyClientFailedPrecondition(LWOOBJID objectId, const S
|
||||
bitStream.Write(objectId);
|
||||
bitStream.Write(eGameMessageType::NOTIFY_CLIENT_FAILED_PRECONDITION);
|
||||
|
||||
bitStream.Write(uint32_t(failedReason.size()));
|
||||
bitStream.Write<uint32_t>(failedReason.size());
|
||||
for (uint16_t character : failedReason) {
|
||||
bitStream.Write(uint16_t(character));
|
||||
bitStream.Write<uint16_t>(character);
|
||||
}
|
||||
|
||||
bitStream.Write(preconditionID);
|
||||
@ -2016,7 +2028,7 @@ void GameMessages::SendLockNodeRotation(Entity* entity, std::string nodeName) {
|
||||
bitStream.Write(entity->GetObjectID());
|
||||
bitStream.Write(eGameMessageType::LOCK_NODE_ROTATION);
|
||||
|
||||
bitStream.Write(uint32_t(nodeName.size()));
|
||||
bitStream.Write<uint32_t>(nodeName.size());
|
||||
for (char character : nodeName) {
|
||||
bitStream.Write(character);
|
||||
}
|
||||
@ -2051,7 +2063,7 @@ void GameMessages::SendGetModelsOnProperty(LWOOBJID objectId, std::map<LWOOBJID,
|
||||
bitStream.Write(objectId);
|
||||
bitStream.Write(eGameMessageType::GET_MODELS_ON_PROPERTY);
|
||||
|
||||
bitStream.Write(static_cast<uint32_t>(models.size()));
|
||||
bitStream.Write<uint32_t>(models.size());
|
||||
|
||||
for (const auto& pair : models) {
|
||||
bitStream.Write(pair.first);
|
||||
@ -2433,7 +2445,7 @@ void GameMessages::HandleBBBLoadItemRequest(RakNet::BitStream* inStream, Entity*
|
||||
void GameMessages::SendBlueprintLoadItemResponse(const SystemAddress& sysAddr, bool success, LWOOBJID oldItemId, LWOOBJID newItemId) {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::BLUEPRINT_LOAD_RESPONSE_ITEMID);
|
||||
bitStream.Write(static_cast<uint8_t>(success));
|
||||
bitStream.Write<uint8_t>(success);
|
||||
bitStream.Write<LWOOBJID>(oldItemId);
|
||||
bitStream.Write<LWOOBJID>(newItemId);
|
||||
SEND_PACKET;
|
||||
@ -3058,7 +3070,7 @@ void GameMessages::SendNotifyObject(LWOOBJID objectId, LWOOBJID objIDSender, std
|
||||
bitStream.Write(eGameMessageType::NOTIFY_OBJECT);
|
||||
|
||||
bitStream.Write(objIDSender);
|
||||
bitStream.Write(static_cast<uint32_t>(name.size()));
|
||||
bitStream.Write<uint32_t>(name.size());
|
||||
for (const auto character : name) {
|
||||
bitStream.Write(character);
|
||||
}
|
||||
@ -3115,7 +3127,7 @@ void GameMessages::SendServerTradeInvite(LWOOBJID objectId, bool bNeedInvitePopU
|
||||
|
||||
bitStream.Write(bNeedInvitePopUp);
|
||||
bitStream.Write(i64Requestor);
|
||||
bitStream.Write(static_cast<uint32_t>(wsName.size()));
|
||||
bitStream.Write<uint32_t>(wsName.size());
|
||||
for (const auto character : wsName) {
|
||||
bitStream.Write(character);
|
||||
}
|
||||
@ -3133,7 +3145,7 @@ void GameMessages::SendServerTradeInitialReply(LWOOBJID objectId, LWOOBJID i64In
|
||||
|
||||
bitStream.Write(i64Invitee);
|
||||
bitStream.Write(resultType);
|
||||
bitStream.Write(static_cast<uint32_t>(wsName.size()));
|
||||
bitStream.Write<uint32_t>(wsName.size());
|
||||
for (const auto character : wsName) {
|
||||
bitStream.Write(character);
|
||||
}
|
||||
@ -3151,7 +3163,7 @@ void GameMessages::SendServerTradeFinalReply(LWOOBJID objectId, bool bResult, LW
|
||||
|
||||
bitStream.Write(bResult);
|
||||
bitStream.Write(i64Invitee);
|
||||
bitStream.Write(static_cast<uint32_t>(wsName.size()));
|
||||
bitStream.Write<uint32_t>(wsName.size());
|
||||
for (const auto character : wsName) {
|
||||
bitStream.Write(character);
|
||||
}
|
||||
@ -3193,7 +3205,7 @@ void GameMessages::SendServerTradeUpdate(LWOOBJID objectId, uint64_t coins, cons
|
||||
|
||||
bitStream.Write(false);
|
||||
bitStream.Write(coins);
|
||||
bitStream.Write(static_cast<uint32_t>(items.size()));
|
||||
bitStream.Write<uint32_t>(items.size());
|
||||
|
||||
for (const auto& item : items) {
|
||||
bitStream.Write(item.itemId);
|
||||
@ -3402,7 +3414,7 @@ void GameMessages::SendNotifyPetTamingPuzzleSelected(LWOOBJID objectId, const st
|
||||
bitStream.Write(objectId);
|
||||
bitStream.Write(eGameMessageType::NOTIFY_TAMING_PUZZLE_SELECTED);
|
||||
|
||||
bitStream.Write(static_cast<uint32_t>(bricks.size()));
|
||||
bitStream.Write<uint32_t>(bricks.size());
|
||||
for (const auto& brick : bricks) {
|
||||
bitStream.Write(brick.designerID);
|
||||
bitStream.Write(brick.materialID);
|
||||
@ -3451,7 +3463,7 @@ void GameMessages::SendAddPetToPlayer(LWOOBJID objectId, int32_t iElementalType,
|
||||
bitStream.Write(eGameMessageType::ADD_PET_TO_PLAYER);
|
||||
|
||||
bitStream.Write(iElementalType);
|
||||
bitStream.Write(static_cast<uint32_t>(name.size()));
|
||||
bitStream.Write<uint32_t>(name.size());
|
||||
for (const auto character : name) {
|
||||
bitStream.Write(character);
|
||||
}
|
||||
@ -3585,7 +3597,7 @@ void GameMessages::SendSetPetName(LWOOBJID objectId, std::u16string name, LWOOBJ
|
||||
bitStream.Write(objectId);
|
||||
bitStream.Write(eGameMessageType::SET_PET_NAME);
|
||||
|
||||
bitStream.Write(static_cast<uint32_t>(name.size()));
|
||||
bitStream.Write<uint32_t>(name.size());
|
||||
for (const auto character : name) {
|
||||
bitStream.Write(character);
|
||||
}
|
||||
@ -3624,12 +3636,12 @@ void GameMessages::SendPetNameChanged(LWOOBJID objectId, int32_t moderationStatu
|
||||
|
||||
bitStream.Write(moderationStatus);
|
||||
|
||||
bitStream.Write(static_cast<uint32_t>(name.size()));
|
||||
bitStream.Write<uint32_t>(name.size());
|
||||
for (const auto character : name) {
|
||||
bitStream.Write(character);
|
||||
}
|
||||
|
||||
bitStream.Write(static_cast<uint32_t>(ownerName.size()));
|
||||
bitStream.Write<uint32_t>(ownerName.size());
|
||||
for (const auto character : ownerName) {
|
||||
bitStream.Write(character);
|
||||
}
|
||||
@ -3907,19 +3919,19 @@ void GameMessages::SendDisplayMessageBox(LWOOBJID objectId, bool bShow, LWOOBJID
|
||||
bitStream.Write(bShow);
|
||||
bitStream.Write(callbackClient);
|
||||
|
||||
bitStream.Write(static_cast<uint32_t>(identifier.size()));
|
||||
bitStream.Write<uint32_t>(identifier.size());
|
||||
for (const auto character : identifier) {
|
||||
bitStream.Write(character);
|
||||
}
|
||||
|
||||
bitStream.Write(imageID);
|
||||
|
||||
bitStream.Write(static_cast<uint32_t>(text.size()));
|
||||
bitStream.Write<uint32_t>(text.size());
|
||||
for (const auto character : text) {
|
||||
bitStream.Write(character);
|
||||
}
|
||||
|
||||
bitStream.Write(static_cast<uint32_t>(userData.size()));
|
||||
bitStream.Write<uint32_t>(userData.size());
|
||||
for (const auto character : userData) {
|
||||
bitStream.Write(character);
|
||||
}
|
||||
@ -3936,7 +3948,7 @@ void GameMessages::SendDisplayChatBubble(LWOOBJID objectId, const std::u16string
|
||||
bitStream.Write(objectId);
|
||||
bitStream.Write(eGameMessageType::DISPLAY_CHAT_BUBBLE);
|
||||
|
||||
bitStream.Write(static_cast<uint32_t>(text.size()));
|
||||
bitStream.Write<uint32_t>(text.size());
|
||||
for (const auto character : text) {
|
||||
bitStream.Write(character);
|
||||
}
|
||||
@ -4127,8 +4139,7 @@ void GameMessages::HandleRequestDie(RakNet::BitStream* inStream, Entity* entity,
|
||||
}
|
||||
|
||||
racingControlComponent->OnRequestDie(entity);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
auto* destroyableComponent = entity->GetComponent<DestroyableComponent>();
|
||||
|
||||
if (!destroyableComponent) return;
|
||||
@ -4245,7 +4256,7 @@ void GameMessages::SendModuleAssemblyDBDataForClient(LWOOBJID objectId, LWOOBJID
|
||||
|
||||
bitStream.Write(assemblyID);
|
||||
|
||||
bitStream.Write(static_cast<uint32_t>(data.size()));
|
||||
bitStream.Write<uint32_t>(data.size());
|
||||
for (auto character : data) {
|
||||
bitStream.Write(character);
|
||||
}
|
||||
@ -4390,7 +4401,7 @@ void GameMessages::SendNotifyRacingClient(LWOOBJID objectId, int32_t eventType,
|
||||
|
||||
bitStream.Write(paramObj);
|
||||
|
||||
bitStream.Write(static_cast<uint32_t>(paramStr.size()));
|
||||
bitStream.Write<uint32_t>(paramStr.size());
|
||||
for (auto character : paramStr) {
|
||||
bitStream.Write(character);
|
||||
}
|
||||
@ -4585,7 +4596,7 @@ void GameMessages::SendShowActivityCountdown(LWOOBJID objectId, bool bPlayAdditi
|
||||
|
||||
bitStream.Write(bPlayCountdownSound);
|
||||
|
||||
bitStream.Write(static_cast<uint32_t>(sndName.size()));
|
||||
bitStream.Write<uint32_t>(sndName.size());
|
||||
for (auto character : sndName) {
|
||||
bitStream.Write(character);
|
||||
}
|
||||
@ -5601,7 +5612,7 @@ void GameMessages::HandleModularBuildFinish(RakNet::BitStream* inStream, Entity*
|
||||
if (entity->GetLOT() != 9980 || Game::server->GetZoneID() != 1200) {
|
||||
if (missionComponent != nullptr) {
|
||||
missionComponent->Progress(eMissionTaskType::SCRIPT, entity->GetLOT(), entity->GetObjectID());
|
||||
if (count >= 7 && everyPieceSwapped) missionComponent->Progress(eMissionTaskType::RACING, LWOOBJID_EMPTY, (LWOOBJID)eRacingTaskParam::MODULAR_BUILDING);
|
||||
if (count >= 7 && everyPieceSwapped) missionComponent->Progress(eMissionTaskType::RACING, LWOOBJID_EMPTY, static_cast<LWOOBJID>(eRacingTaskParam::MODULAR_BUILDING));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,6 +76,7 @@ namespace GameMessages {
|
||||
int iIndex = 0, int iDesiredWaypointIndex = 1, int nextIndex = 1,
|
||||
eMovementPlatformState movementState = eMovementPlatformState::Moving);
|
||||
|
||||
void SendResetMissions(Entity* entity, const SystemAddress& sysAddr, const int32_t missionid = -1);
|
||||
void SendRestoreToPostLoadStats(Entity* entity, const SystemAddress& sysAddr);
|
||||
void SendServerDoneLoadingAllObjects(Entity* entity, const SystemAddress& sysAddr);
|
||||
void SendGMLevelBroadcast(const LWOOBJID& objectID, eGameMasterLevel level);
|
||||
|
@ -423,25 +423,16 @@ void Item::DisassembleModel(uint32_t numToDismantle) {
|
||||
if (renderAssetSplit.empty()) return;
|
||||
|
||||
std::string lxfmlPath = "BrickModels" + lxfmlFolderName + "/" + GeneralUtils::SplitString(renderAssetSplit.back(), '.').at(0) + ".lxfml";
|
||||
auto buffer = Game::assetManager->GetFileAsBuffer(lxfmlPath.c_str());
|
||||
auto file = Game::assetManager->GetFile(lxfmlPath.c_str());
|
||||
|
||||
if (!buffer.m_Success) {
|
||||
if (!file) {
|
||||
LOG("Failed to load %s to disassemble model into bricks, check that this file exists", lxfmlPath.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
std::istream file(&buffer);
|
||||
|
||||
if (!file.good()) {
|
||||
buffer.close();
|
||||
return;
|
||||
}
|
||||
|
||||
std::stringstream data;
|
||||
data << file.rdbuf();
|
||||
|
||||
buffer.close();
|
||||
|
||||
uint32_t fileSize;
|
||||
file.seekg(0, std::ios::end);
|
||||
fileSize = static_cast<uint32_t>(file.tellg());
|
||||
|
@ -324,14 +324,9 @@ void ControlBehaviors::ProcessCommand(Entity* modelEntity, const SystemAddress&
|
||||
}
|
||||
|
||||
ControlBehaviors::ControlBehaviors() {
|
||||
auto blocksDefStreamBuffer = Game::assetManager->GetFileAsBuffer("ui\\ingame\\blocksdef.xml");
|
||||
if (!blocksDefStreamBuffer.m_Success) {
|
||||
LOG("failed to open blocksdef");
|
||||
return;
|
||||
}
|
||||
std::istream blocksBuffer(&blocksDefStreamBuffer);
|
||||
if (!blocksBuffer.good()) {
|
||||
LOG("Blocks buffer is not good!");
|
||||
auto blocksBuffer = Game::assetManager->GetFile("ui\\ingame\\blocksdef.xml");
|
||||
if (!blocksBuffer) {
|
||||
LOG("Failed to open blocksdef.xml");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -342,7 +337,7 @@ ControlBehaviors::ControlBehaviors() {
|
||||
std::string buffer{};
|
||||
bool commentBlockStart = false;
|
||||
while (std::getline(blocksBuffer, read)) {
|
||||
// tinyxml2 should handle comment blocks but the client has one that fails the processing.
|
||||
// tinyxml2 should handle comment blocks but the client has one that fails the processing.
|
||||
// This preprocessing just removes all comments from the read file out of an abundance of caution.
|
||||
if (read.find("<!--") != std::string::npos) {
|
||||
commentBlockStart = true;
|
||||
|
@ -17,26 +17,18 @@ const BrickList& BrickDatabase::GetBricks(const LxfmlPath& lxfmlPath) {
|
||||
return cached->second;
|
||||
}
|
||||
|
||||
AssetMemoryBuffer buffer = Game::assetManager->GetFileAsBuffer((lxfmlPath).c_str());
|
||||
auto file = Game::assetManager->GetFile((lxfmlPath).c_str());
|
||||
|
||||
if (!buffer.m_Success) {
|
||||
return emptyCache;
|
||||
}
|
||||
|
||||
std::istream file(&buffer);
|
||||
if (!file.good()) {
|
||||
if (!file) {
|
||||
return emptyCache;
|
||||
}
|
||||
|
||||
std::stringstream data;
|
||||
data << file.rdbuf();
|
||||
if (data.str().empty()) {
|
||||
buffer.close();
|
||||
return emptyCache;
|
||||
}
|
||||
|
||||
buffer.close();
|
||||
|
||||
auto* doc = new tinyxml2::XMLDocument();
|
||||
if (doc->Parse(data.str().c_str(), data.str().size()) != 0) {
|
||||
delete doc;
|
||||
|
@ -289,11 +289,11 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
|
||||
return;
|
||||
}
|
||||
|
||||
if (chatCommand == "leave-zone") {
|
||||
if (chatCommand == "leave-zone" || chatCommand == "leavezone") {
|
||||
const auto currentZone = Game::zoneManager->GetZone()->GetZoneID().GetMapID();
|
||||
|
||||
LWOMAPID newZone = 0;
|
||||
if (currentZone % 100 == 0) {
|
||||
|
||||
if (currentZone == 1001 || currentZone % 100 == 0) {
|
||||
ChatPackets::SendSystemMessage(sysAddr, u"You are not in an instanced zone.");
|
||||
return;
|
||||
} else {
|
||||
@ -348,6 +348,17 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
|
||||
});
|
||||
}
|
||||
|
||||
if (chatCommand == "resetmission") {
|
||||
uint32_t missionId;
|
||||
if (!GeneralUtils::TryParse(args[0], missionId)) {
|
||||
ChatPackets::SendSystemMessage(sysAddr, u"Invalid mission ID.");
|
||||
return;
|
||||
}
|
||||
auto* missionComponent = entity->GetComponent<MissionComponent>();
|
||||
if (!missionComponent) return;
|
||||
missionComponent->ResetMission(missionId);
|
||||
}
|
||||
|
||||
if (user->GetMaxGMLevel() == eGameMasterLevel::CIVILIAN || entity->GetGMLevel() >= eGameMasterLevel::CIVILIAN) {
|
||||
if (chatCommand == "die") {
|
||||
entity->Smash(entity->GetObjectID());
|
||||
@ -609,15 +620,13 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
|
||||
if (args[0].find("/") != std::string::npos) return;
|
||||
if (args[0].find("\\") != std::string::npos) return;
|
||||
|
||||
auto buf = Game::assetManager->GetFileAsBuffer(("macros/" + args[0] + ".scm").c_str());
|
||||
auto infile = Game::assetManager->GetFile(("macros/" + args[0] + ".scm").c_str());
|
||||
|
||||
if (!buf.m_Success) {
|
||||
if (!infile) {
|
||||
ChatPackets::SendSystemMessage(sysAddr, u"Unknown macro! Is the filename right?");
|
||||
return;
|
||||
}
|
||||
|
||||
std::istream infile(&buf);
|
||||
|
||||
if (infile.good()) {
|
||||
std::string line;
|
||||
while (std::getline(infile, line)) {
|
||||
@ -627,8 +636,6 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
|
||||
ChatPackets::SendSystemMessage(sysAddr, u"Unknown macro! Is the filename right?");
|
||||
}
|
||||
|
||||
buf.close();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -169,8 +169,8 @@ int main(int argc, char** argv) {
|
||||
(BinaryPathFinder::GetBinaryDir() / "resServer" / "CDServer.sqlite").c_str(),
|
||||
(Game::assetManager->GetResPath() / "cdclient.fdb").c_str());
|
||||
|
||||
AssetMemoryBuffer cdClientBuffer = Game::assetManager->GetFileAsBuffer("cdclient.fdb");
|
||||
if (!cdClientBuffer.m_Success) {
|
||||
auto cdclientStream = Game::assetManager->GetFile("cdclient.fdb");
|
||||
if (!cdclientStream) {
|
||||
LOG("Failed to load %s", (Game::assetManager->GetResPath() / "cdclient.fdb").c_str());
|
||||
throw std::runtime_error("Aborting initialization due to missing cdclient.fdb.");
|
||||
}
|
||||
@ -178,11 +178,10 @@ int main(int argc, char** argv) {
|
||||
LOG("Found %s. Converting to SQLite", (Game::assetManager->GetResPath() / "cdclient.fdb").c_str());
|
||||
Game::logger->Flush();
|
||||
|
||||
if (FdbToSqlite::Convert((BinaryPathFinder::GetBinaryDir() / "resServer").string()).ConvertDatabase(cdClientBuffer) == false) {
|
||||
if (FdbToSqlite::Convert((BinaryPathFinder::GetBinaryDir() / "resServer").string()).ConvertDatabase(cdclientStream) == false) {
|
||||
LOG("Failed to convert fdb to sqlite.");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
cdClientBuffer.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -223,7 +223,7 @@ void AuthPackets::SendLoginResponse(dServer* server, const SystemAddress& sysAdd
|
||||
server->Send(&packet, sysAddr, false);
|
||||
|
||||
//Inform the master server that we've created a session for this user:
|
||||
{
|
||||
if (responseCode == eLoginResponse::SUCCESS) {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::SET_SESSION_KEY);
|
||||
bitStream.Write(sessionKey);
|
||||
|
@ -31,7 +31,7 @@ void MasterPackets::SendZoneTransferRequest(dServer* server, uint64_t requestID,
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::REQUEST_ZONE_TRANSFER);
|
||||
|
||||
bitStream.Write(requestID);
|
||||
bitStream.Write(static_cast<uint8_t>(mythranShift));
|
||||
bitStream.Write<uint8_t>(mythranShift);
|
||||
bitStream.Write(zoneID);
|
||||
bitStream.Write(cloneID);
|
||||
|
||||
@ -58,7 +58,7 @@ void MasterPackets::SendZoneRequestPrivate(dServer* server, uint64_t requestID,
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::REQUEST_PRIVATE_ZONE);
|
||||
|
||||
bitStream.Write(requestID);
|
||||
bitStream.Write(static_cast<uint8_t>(mythranShift));
|
||||
bitStream.Write<uint8_t>(mythranShift);
|
||||
|
||||
bitStream.Write<uint32_t>(password.size());
|
||||
for (auto character : password) {
|
||||
@ -83,11 +83,11 @@ void MasterPackets::SendZoneTransferResponse(dServer* server, const SystemAddres
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::REQUEST_ZONE_TRANSFER_RESPONSE);
|
||||
|
||||
bitStream.Write(requestID);
|
||||
bitStream.Write(static_cast<uint8_t>(mythranShift));
|
||||
bitStream.Write<uint8_t>(mythranShift);
|
||||
bitStream.Write(zoneID);
|
||||
bitStream.Write(zoneInstance);
|
||||
bitStream.Write(zoneClone);
|
||||
bitStream.Write(static_cast<uint16_t>(serverPort));
|
||||
bitStream.Write<uint16_t>(serverPort);
|
||||
bitStream.Write(LUString(serverIP, static_cast<uint32_t>(serverIP.size() + 1)));
|
||||
|
||||
server->Send(&bitStream, sysAddr, false);
|
||||
|
@ -21,19 +21,19 @@ void WorldPackets::SendLoadStaticZone(const SystemAddress& sysAddr, float x, flo
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::LOAD_STATIC_ZONE);
|
||||
|
||||
auto zone = Game::zoneManager->GetZone()->GetZoneID();
|
||||
bitStream.Write(static_cast<uint16_t>(zone.GetMapID()));
|
||||
bitStream.Write(static_cast<uint16_t>(zone.GetInstanceID()));
|
||||
//bitStream.Write(static_cast<uint32_t>(zone.GetCloneID()));
|
||||
bitStream.Write<uint16_t>(zone.GetMapID());
|
||||
bitStream.Write<uint16_t>(zone.GetInstanceID());
|
||||
//bitStream.Write<uint32_t>(zone.GetCloneID());
|
||||
bitStream.Write(0);
|
||||
|
||||
bitStream.Write(checksum);
|
||||
bitStream.Write(static_cast<uint16_t>(0)); // ??
|
||||
bitStream.Write<uint16_t>(0); // ??
|
||||
|
||||
bitStream.Write(x);
|
||||
bitStream.Write(y);
|
||||
bitStream.Write(z);
|
||||
|
||||
bitStream.Write(static_cast<uint32_t>(0)); // Change this to eventually use 4 on activity worlds
|
||||
bitStream.Write<uint32_t>(0); // Change this to eventually use 4 on activity worlds
|
||||
|
||||
SEND_PACKET;
|
||||
}
|
||||
@ -45,18 +45,18 @@ void WorldPackets::SendCharacterList(const SystemAddress& sysAddr, User* user) {
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::CHARACTER_LIST_RESPONSE);
|
||||
|
||||
std::vector<Character*> characters = user->GetCharacters();
|
||||
bitStream.Write(static_cast<uint8_t>(characters.size()));
|
||||
bitStream.Write(static_cast<uint8_t>(0)); //character index in front, just picking 0
|
||||
bitStream.Write<uint8_t>(characters.size());
|
||||
bitStream.Write<uint8_t>(0); //character index in front, just picking 0
|
||||
|
||||
for (uint32_t i = 0; i < characters.size(); ++i) {
|
||||
bitStream.Write(characters[i]->GetObjectID());
|
||||
bitStream.Write(static_cast<uint32_t>(0));
|
||||
bitStream.Write<uint32_t>(0);
|
||||
|
||||
bitStream.Write(LUWString(characters[i]->GetName()));
|
||||
bitStream.Write(LUWString(characters[i]->GetUnapprovedName()));
|
||||
|
||||
bitStream.Write(static_cast<uint8_t>(characters[i]->GetNameRejected()));
|
||||
bitStream.Write(static_cast<uint8_t>(false));
|
||||
bitStream.Write<uint8_t>(characters[i]->GetNameRejected());
|
||||
bitStream.Write<uint8_t>(false);
|
||||
|
||||
bitStream.Write(LUString("", 10));
|
||||
|
||||
@ -70,16 +70,16 @@ void WorldPackets::SendCharacterList(const SystemAddress& sysAddr, User* user) {
|
||||
bitStream.Write(characters[i]->GetEyebrows());
|
||||
bitStream.Write(characters[i]->GetEyes());
|
||||
bitStream.Write(characters[i]->GetMouth());
|
||||
bitStream.Write(static_cast<uint32_t>(0));
|
||||
bitStream.Write<uint32_t>(0);
|
||||
|
||||
bitStream.Write(static_cast<uint16_t>(characters[i]->GetZoneID()));
|
||||
bitStream.Write(static_cast<uint16_t>(characters[i]->GetZoneInstance()));
|
||||
bitStream.Write<uint16_t>(characters[i]->GetZoneID());
|
||||
bitStream.Write<uint16_t>(characters[i]->GetZoneInstance());
|
||||
bitStream.Write(characters[i]->GetZoneClone());
|
||||
|
||||
bitStream.Write(characters[i]->GetLastLogin());
|
||||
|
||||
const auto& equippedItems = characters[i]->GetEquippedItems();
|
||||
bitStream.Write(static_cast<uint16_t>(equippedItems.size()));
|
||||
bitStream.Write<uint16_t>(equippedItems.size());
|
||||
|
||||
for (uint32_t j = 0; j < equippedItems.size(); ++j) {
|
||||
bitStream.Write(equippedItems[j]);
|
||||
@ -106,7 +106,7 @@ void WorldPackets::SendCharacterRenameResponse(const SystemAddress& sysAddr, eRe
|
||||
void WorldPackets::SendCharacterDeleteResponse(const SystemAddress& sysAddr, bool response) {
|
||||
RakNet::BitStream bitStream;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::DELETE_CHARACTER_RESPONSE);
|
||||
bitStream.Write(static_cast<uint8_t>(response));
|
||||
bitStream.Write<uint8_t>(response);
|
||||
SEND_PACKET;
|
||||
}
|
||||
|
||||
@ -115,8 +115,8 @@ void WorldPackets::SendTransferToWorld(const SystemAddress& sysAddr, const std::
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::TRANSFER_TO_WORLD);
|
||||
|
||||
bitStream.Write(LUString(serverIP));
|
||||
bitStream.Write(static_cast<uint16_t>(serverPort));
|
||||
bitStream.Write(static_cast<uint8_t>(mythranShift));
|
||||
bitStream.Write<uint16_t>(serverPort);
|
||||
bitStream.Write<uint8_t>(mythranShift);
|
||||
|
||||
SEND_PACKET;
|
||||
}
|
||||
@ -124,7 +124,7 @@ void WorldPackets::SendTransferToWorld(const SystemAddress& sysAddr, const std::
|
||||
void WorldPackets::SendServerState(const SystemAddress& sysAddr) {
|
||||
RakNet::BitStream bitStream;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::SERVER_STATES);
|
||||
bitStream.Write(static_cast<uint8_t>(1)); //If the server is receiving this request, it probably is ready anyway.
|
||||
bitStream.Write<uint8_t>(1); //If the server is receiving this request, it probably is ready anyway.
|
||||
SEND_PACKET;
|
||||
}
|
||||
|
||||
@ -204,8 +204,8 @@ void WorldPackets::SendChatModerationResponse(const SystemAddress& sysAddr, bool
|
||||
bitStream.Write<uint8_t>(unacceptedItems.empty()); // Is sentence ok?
|
||||
bitStream.Write<uint16_t>(0x16); // Source ID, unknown
|
||||
|
||||
bitStream.Write(static_cast<uint8_t>(requestID)); // request ID
|
||||
bitStream.Write(static_cast<char>(0)); // chat mode
|
||||
bitStream.Write<uint8_t>(requestID); // request ID
|
||||
bitStream.Write<char>(0); // chat mode
|
||||
|
||||
bitStream.Write(LUWString(receiver, 42)); // receiver name
|
||||
|
||||
|
@ -3,6 +3,7 @@ set(DSCRIPTS_SOURCES_02_SERVER_MAP_GENERAL
|
||||
"BaseInteractDropLootServer.cpp"
|
||||
"Binoculars.cpp"
|
||||
"ExplodingAsset.cpp"
|
||||
"FrictionVolumeServer.cpp"
|
||||
"ForceVolumeServer.cpp"
|
||||
"GrowingFlower.cpp"
|
||||
"ImaginationBackpackHealServer.cpp"
|
||||
@ -17,6 +18,8 @@ set(DSCRIPTS_SOURCES_02_SERVER_MAP_GENERAL
|
||||
"StoryBoxInteractServer.cpp"
|
||||
"TokenConsoleServer.cpp"
|
||||
"TouchMissionUpdateServer.cpp"
|
||||
"VisToggleNotifierServer.cpp"
|
||||
"NTNaomiDirtServer.cpp"
|
||||
"WishingWellServer.cpp")
|
||||
|
||||
add_subdirectory(Ninjago)
|
||||
|
19
dScripts/02_server/Map/General/FrictionVolumeServer.cpp
Normal file
19
dScripts/02_server/Map/General/FrictionVolumeServer.cpp
Normal file
@ -0,0 +1,19 @@
|
||||
#include "FrictionVolumeServer.h"
|
||||
#include "PhantomPhysicsComponent.h"
|
||||
#include "ePhysicsEffectType.h"
|
||||
#include "Game.h"
|
||||
#include "EntityManager.h"
|
||||
|
||||
void FrictionVolumeServer::OnStartup(Entity* self) {
|
||||
auto frictionAmount = self->GetVar<float>(u"FrictionAmt");
|
||||
if (frictionAmount == 0.0f) frictionAmount = DefaultFrictionAmount;
|
||||
|
||||
auto* phantomPhysicsComponent = self->GetComponent<PhantomPhysicsComponent>();
|
||||
if (!phantomPhysicsComponent) return;
|
||||
|
||||
phantomPhysicsComponent->SetEffectType(ePhysicsEffectType::FRICTION);
|
||||
phantomPhysicsComponent->SetDirectionalMultiplier(frictionAmount);
|
||||
phantomPhysicsComponent->SetPhysicsEffectActive(true);
|
||||
|
||||
Game::entityManager->SerializeEntity(self);
|
||||
}
|
13
dScripts/02_server/Map/General/FrictionVolumeServer.h
Normal file
13
dScripts/02_server/Map/General/FrictionVolumeServer.h
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef __FRICTIONVOLUMESERVER__H__
|
||||
#define __FRICTIONVOLUMESERVER__H__
|
||||
|
||||
#include "CppScripts.h"
|
||||
|
||||
class FrictionVolumeServer : public CppScripts::Script {
|
||||
public:
|
||||
void OnStartup(Entity* self) override;
|
||||
private:
|
||||
const float DefaultFrictionAmount = 1.5f;
|
||||
};
|
||||
|
||||
#endif //!__FRICTIONVOLUMESERVER__H__
|
14
dScripts/02_server/Map/General/NTNaomiDirtServer.cpp
Normal file
14
dScripts/02_server/Map/General/NTNaomiDirtServer.cpp
Normal file
@ -0,0 +1,14 @@
|
||||
#include "NTNaomiDirtServer.h"
|
||||
|
||||
namespace {
|
||||
std::map<int32_t, std::string> VisibilityMissionTable = {
|
||||
{1253, std::string("Dirt_Clouds_Sent")},
|
||||
{1276, std::string("Dirt_Clouds_Assem")},
|
||||
{1277, std::string("Dirt_Clouds_Para")},
|
||||
{1283, std::string("Dirt_Clouds_Halls")}
|
||||
};
|
||||
};
|
||||
|
||||
void NTNaomiDirtServer::OnStartup(Entity* self) {
|
||||
SetGameVariables(VisibilityMissionTable);
|
||||
}
|
11
dScripts/02_server/Map/General/NTNaomiDirtServer.h
Normal file
11
dScripts/02_server/Map/General/NTNaomiDirtServer.h
Normal file
@ -0,0 +1,11 @@
|
||||
#ifndef __NTNAOMIDIRTSERVER__H__
|
||||
#define __NTNAOMIDIRTSERVER__H__
|
||||
|
||||
#include "VisToggleNotifierServer.h"
|
||||
|
||||
class NTNaomiDirtServer : public VisToggleNotifierServer {
|
||||
public:
|
||||
void OnStartup(Entity* self) override;
|
||||
};
|
||||
|
||||
#endif //!__NTNAOMIDIRTSERVER__H__
|
23
dScripts/02_server/Map/General/VisToggleNotifierServer.cpp
Normal file
23
dScripts/02_server/Map/General/VisToggleNotifierServer.cpp
Normal file
@ -0,0 +1,23 @@
|
||||
#include "VisToggleNotifierServer.h"
|
||||
#include "eMissionState.h"
|
||||
#include "Game.h"
|
||||
#include "dZoneManager.h"
|
||||
|
||||
void VisToggleNotifierServer::OnMissionDialogueOK(Entity* self, Entity* target, int missionId, eMissionState missionState) {
|
||||
auto itr = m_GameVariables.find(missionId);
|
||||
if (itr != m_GameVariables.end()) {
|
||||
bool visible = true;
|
||||
if (missionState == eMissionState::READY_TO_COMPLETE || missionState == eMissionState::COMPLETE_READY_TO_COMPLETE) {
|
||||
visible = false;
|
||||
}
|
||||
|
||||
auto spawners = Game::zoneManager->GetSpawnersByName(itr->second);
|
||||
if (spawners.empty()) return;
|
||||
for (const auto spawner : spawners) {
|
||||
auto spawnedObjIds = spawner->GetSpawnedObjectIDs();
|
||||
for (const auto& objId : spawnedObjIds) {
|
||||
GameMessages::SendNotifyClientObject(objId, u"SetVisibility", visible);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
15
dScripts/02_server/Map/General/VisToggleNotifierServer.h
Normal file
15
dScripts/02_server/Map/General/VisToggleNotifierServer.h
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef __VISTOGGLENOTIFIERSERVER__H__
|
||||
#define __VISTOGGLENOTIFIERSERVER__H__
|
||||
|
||||
#include "CppScripts.h"
|
||||
|
||||
class VisToggleNotifierServer : public CppScripts::Script {
|
||||
public:
|
||||
void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) override;
|
||||
protected:
|
||||
void SetGameVariables(std::map<int32_t, std::string>& gameVariables) { m_GameVariables = gameVariables; }
|
||||
private:
|
||||
std::map<int32_t, std::string> m_GameVariables;
|
||||
};
|
||||
|
||||
#endif //!__VISTOGGLENOTIFIERSERVER__H__
|
@ -18,9 +18,12 @@ set(DSCRIPTS_SOURCES_02_SERVER_MAP_NT
|
||||
"NtXRayServer.cpp"
|
||||
"NtSleepingGuard.cpp"
|
||||
"NtImagimeterVisibility.cpp"
|
||||
"NTPipeVisibilityServer.cpp"
|
||||
"NtSentinelWalkwayServer.cpp"
|
||||
"NtDarkitectRevealServer.cpp"
|
||||
"NtParadoxTeleServer.cpp"
|
||||
"NtVentureSpeedPadServer.cpp"
|
||||
"NtVentureCannonServer.cpp"
|
||||
"NtBcSubmitServer.cpp"
|
||||
"NtNaomiBreadcrumbServer.cpp"
|
||||
PARENT_SCOPE)
|
||||
|
15
dScripts/02_server/Map/NT/NTPipeVisibilityServer.cpp
Normal file
15
dScripts/02_server/Map/NT/NTPipeVisibilityServer.cpp
Normal file
@ -0,0 +1,15 @@
|
||||
#include "NTPipeVisibilityServer.h"
|
||||
#include "Entity.h"
|
||||
#include "Character.h"
|
||||
|
||||
void NTPipeVisibilityServer::OnRebuildComplete(Entity* self, Entity* target) {
|
||||
const auto flag = self->GetVar<int32_t>(u"flag");
|
||||
if (flag == 0) return;
|
||||
|
||||
auto* character = target->GetCharacter();
|
||||
if (!character) return;
|
||||
|
||||
character->SetPlayerFlag(flag, true);
|
||||
|
||||
GameMessages::SendNotifyClientObject(self->GetObjectID(), u"PipeBuilt");
|
||||
}
|
11
dScripts/02_server/Map/NT/NTPipeVisibilityServer.h
Normal file
11
dScripts/02_server/Map/NT/NTPipeVisibilityServer.h
Normal file
@ -0,0 +1,11 @@
|
||||
#ifndef __NTPIPEVISIBILITYSERVER__H__
|
||||
#define __NTPIPEVISIBILITYSERVER__H__
|
||||
|
||||
#include "CppScripts.h"
|
||||
|
||||
class NTPipeVisibilityServer : public CppScripts::Script {
|
||||
public:
|
||||
void OnRebuildComplete(Entity* self, Entity* target) override;
|
||||
};
|
||||
|
||||
#endif //!__NTPIPEVISIBILITYSERVER__H__
|
34
dScripts/02_server/Map/NT/NtBcSubmitServer.cpp
Normal file
34
dScripts/02_server/Map/NT/NtBcSubmitServer.cpp
Normal file
@ -0,0 +1,34 @@
|
||||
#include "NtBcSubmitServer.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
|
||||
#include "Entity.h"
|
||||
#include "MissionComponent.h"
|
||||
|
||||
// https://explorer.lu/missions/
|
||||
// Key is the main mission, value is the breadcrumb mission to reset upon Mission Dialogue Ok.
|
||||
// To see the actual missions, just append the number to the end of the URL.
|
||||
namespace {
|
||||
std::map<uint32_t, uint32_t> ResetMissionsTable = {
|
||||
{999, 1335},
|
||||
{1002, 1355},
|
||||
{1006, 1349},
|
||||
{1009, 1348},
|
||||
{1379, 1335},
|
||||
{1380, 1355},
|
||||
{1378, 1349},
|
||||
{1377, 1348},
|
||||
};
|
||||
}
|
||||
|
||||
void NtBcSubmitServer::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) {
|
||||
auto* missionComponent = target->GetComponent<MissionComponent>();
|
||||
if (!missionComponent) return;
|
||||
|
||||
auto it = ResetMissionsTable.find(missionID);
|
||||
if (it == ResetMissionsTable.end()) return;
|
||||
|
||||
const auto missionToReset = it->second;
|
||||
missionComponent->ResetMission(missionToReset);
|
||||
}
|
11
dScripts/02_server/Map/NT/NtBcSubmitServer.h
Normal file
11
dScripts/02_server/Map/NT/NtBcSubmitServer.h
Normal file
@ -0,0 +1,11 @@
|
||||
#ifndef __NTBCSUBMITSERVER__H__
|
||||
#define __NTBCSUBMITSERVER__H__
|
||||
|
||||
#include "CppScripts.h"
|
||||
|
||||
class NtBcSubmitServer : public virtual CppScripts::Script {
|
||||
public:
|
||||
void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) override;
|
||||
};
|
||||
|
||||
#endif //!__NTBCSUBMITSERVER__H__
|
@ -37,4 +37,5 @@ void NtDukeServer::OnMissionDialogueOK(Entity* self, Entity* target, int mission
|
||||
inventoryComponent->RemoveItem(m_SwordLot, lotCount);
|
||||
}
|
||||
}
|
||||
NtBcSubmitServer::OnMissionDialogueOK(self, target, missionID, missionState);
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
#pragma once
|
||||
#include "NtFactionSpyServer.h"
|
||||
#include "NtBcSubmitServer.h"
|
||||
|
||||
class NtDukeServer : public NtFactionSpyServer {
|
||||
class NtDukeServer : public NtFactionSpyServer, public NtBcSubmitServer {
|
||||
void SetVariables(Entity* self) override;
|
||||
void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) override;
|
||||
const uint32_t m_SwordMissionID = 1448;
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
#include "NtFactionSpyServer.h"
|
||||
#include "NtBcSubmitServer.h"
|
||||
|
||||
class NtHaelServer : public NtFactionSpyServer {
|
||||
class NtHaelServer : public NtFactionSpyServer, public NtBcSubmitServer {
|
||||
void SetVariables(Entity* self) override;
|
||||
};
|
||||
|
43
dScripts/02_server/Map/NT/NtNaomiBreadcrumbServer.cpp
Normal file
43
dScripts/02_server/Map/NT/NtNaomiBreadcrumbServer.cpp
Normal file
@ -0,0 +1,43 @@
|
||||
#include "NtNaomiBreadcrumbServer.h"
|
||||
#include <map>
|
||||
|
||||
#include "eMissionState.h"
|
||||
#include "MissionComponent.h"
|
||||
|
||||
// https://explorer.lu/missions/
|
||||
// Key is the main mission, value is the breadcrumb mission to reset upon Mission Dialogue Ok.
|
||||
// To see the actual missions, just append the number to the end of the URL.
|
||||
namespace {
|
||||
std::map<int32_t, std::vector<int32_t>> CompleteBcMissionTable = {
|
||||
{1377, {1378, 1379, 1380, 1349, 1335, 1355}},
|
||||
{1378, {1377, 1379, 1380, 1348, 1335, 1355}},
|
||||
{1379, {1377, 1378, 1380, 1348, 1349, 1355}},
|
||||
{1380, {1377, 1378, 1379, 1348, 1349, 1335}},
|
||||
};
|
||||
|
||||
std::map<int32_t, int32_t> MatchingBCTable = {
|
||||
{1377, 1348},
|
||||
{1378, 1349},
|
||||
{1379, 1335},
|
||||
{1380, 1355}
|
||||
};
|
||||
}
|
||||
|
||||
void NtNaomiBreadcrumbServer::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) {
|
||||
auto* missionComponent = target->GetComponent<MissionComponent>();
|
||||
if (!missionComponent) return;
|
||||
|
||||
auto itr = MatchingBCTable.find(missionID);
|
||||
if (itr == MatchingBCTable.end()) return;
|
||||
|
||||
missionComponent->AcceptMission(itr->second);
|
||||
|
||||
auto it = CompleteBcMissionTable.find(missionID);
|
||||
if (it == CompleteBcMissionTable.end()) return;
|
||||
|
||||
if (missionState == eMissionState::AVAILABLE || missionState == eMissionState::COMPLETE_AVAILABLE) {
|
||||
for (const auto& bcMission : it->second) {
|
||||
missionComponent->ResetMission(bcMission);
|
||||
}
|
||||
}
|
||||
}
|
11
dScripts/02_server/Map/NT/NtNaomiBreadcrumbServer.h
Normal file
11
dScripts/02_server/Map/NT/NtNaomiBreadcrumbServer.h
Normal file
@ -0,0 +1,11 @@
|
||||
#ifndef __NTNAOMIBREADCRUMBSERVER__H__
|
||||
#define __NTNAOMIBREADCRUMBSERVER__H__
|
||||
|
||||
#include "CppScripts.h"
|
||||
|
||||
class NtNaomiBreadcrumbServer : public CppScripts::Script {
|
||||
public:
|
||||
void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) override;
|
||||
};
|
||||
|
||||
#endif //!__NTNAOMIBREADCRUMBSERVER__H__
|
@ -1,7 +1,8 @@
|
||||
#pragma once
|
||||
#include "NtFactionSpyServer.h"
|
||||
#include "NtBcSubmitServer.h"
|
||||
|
||||
class NtOverbuildServer : public NtFactionSpyServer {
|
||||
class NtOverbuildServer : public NtFactionSpyServer, public NtBcSubmitServer {
|
||||
void SetVariables(Entity* self) override;
|
||||
const std::u16string m_OtherEntitiesGroupVariable = u"SpyConvo2Group";
|
||||
};
|
||||
|
@ -11,4 +11,5 @@ void NtVandaServer::OnMissionDialogueOK(Entity* self, Entity* target, int missio
|
||||
inventoryComponent->RemoveItem(alienPartLot, 1);
|
||||
}
|
||||
}
|
||||
NtBcSubmitServer::OnMissionDialogueOK(self, target, missionID, missionState);
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
#include "NtBcSubmitServer.h"
|
||||
|
||||
class NtVandaServer : public CppScripts::Script {
|
||||
class NtVandaServer : public NtBcSubmitServer {
|
||||
void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) override;
|
||||
const uint32_t m_AlienPartMissionID = 1183;
|
||||
const std::vector<LOT> m_AlienPartLots = { 12479, 12480, 12481 };
|
||||
|
@ -209,6 +209,11 @@
|
||||
#include "NtXRayServer.h"
|
||||
#include "NtSleepingGuard.h"
|
||||
#include "NtImagimeterVisibility.h"
|
||||
#include "FrictionVolumeServer.h"
|
||||
#include "NTPipeVisibilityServer.h"
|
||||
#include "NTNaomiDirtServer.h"
|
||||
#include "MinigameBlueMark.h"
|
||||
#include "NtNaomiBreadcrumbServer.h"
|
||||
|
||||
// DLU Scripts
|
||||
#include "DLUVanityNPC.h"
|
||||
@ -311,6 +316,7 @@
|
||||
#include "WildNinjaStudent.h"
|
||||
#include "WildNinjaSensei.h"
|
||||
#include "WildNinjaBricks.h"
|
||||
#include "VisToggleNotifierServer.h"
|
||||
|
||||
namespace {
|
||||
InvalidScript* invalidToReturn = new InvalidScript();
|
||||
@ -694,19 +700,30 @@ CppScripts::Script* CppScripts::GetScript(Entity* parent, const std::string& scr
|
||||
script = new NtDukeServer();
|
||||
else if (scriptName == "scripts\\02_server\\Map\\NT\\L_NT_HAEL_SERVER.lua")
|
||||
script = new NtHaelServer();
|
||||
else if (scriptName == "scripts\\02_server\\Map\\NT\\L_NT_FACTION_SPY_SERVER.lua")
|
||||
script = new NtFactionSpyServer();
|
||||
else if (scriptName == "scripts\\02_server\\Map\\NT\\L_NT_OVERBUILD_SERVER.lua")
|
||||
script = new NtOverbuildServer();
|
||||
else if (scriptName == "scripts\\02_server\\Map\\NT\\L_NT_VANDA_SERVER.lua")
|
||||
script = new NtVandaServer();
|
||||
else if (scriptName == "scripts\\02_server\\Map\\General\\L_FORCE_VOLUME_SERVER.lua")
|
||||
script = new ForceVolumeServer();
|
||||
else if (scriptName == "scripts\\02_server\\Map\\General\\L_FRICTION_VOLUME_SERVER.lua")
|
||||
script = new FrictionVolumeServer();
|
||||
else if (scriptName == "scripts\\02_server\\Map\\NT\\L_NT_XRAY_SERVER.lua")
|
||||
script = new NtXRayServer();
|
||||
else if (scriptName == "scripts\\02_server\\Map\\NT\\L_NT_SLEEPING_GUARD.lua")
|
||||
script = new NtSleepingGuard();
|
||||
else if (scriptName == "scripts\\02_server\\Map\\NT\\L_NT_IMAGIMETER_VISIBILITY_SERVER.lua") {
|
||||
else if (scriptName == "scripts\\02_server\\Map\\NT\\L_NT_IMAGIMETER_VISIBILITY_SERVER.lua")
|
||||
script = new NTImagimeterVisibility();
|
||||
}
|
||||
else if (scriptName == "scripts\\02_server\\Map\\NT\\L_NT_PIPE_VISIBILITY_SERVER.lua")
|
||||
script = new NTPipeVisibilityServer();
|
||||
else if (scriptName == "scripts\\ai\\MINIGAME\\Objects\\MINIGAME_BLUE_MARK.lua")
|
||||
script = new MinigameBlueMark();
|
||||
else if (scriptName == "scripts\\02_server\\Map\\NT\\L_NT_NAOMI_BREADCRUMB_SERVER.lua")
|
||||
script = new NtNaomiBreadcrumbServer();
|
||||
else if (scriptName == "scripts\\02_server\\Map\\NT\\L_NT_NAOMI_DIRT_SERVER.lua")
|
||||
script = new NTNaomiDirtServer();
|
||||
|
||||
//AM:
|
||||
else if (scriptName == "scripts\\02_server\\Map\\AM\\L_AM_CONSOLE_TELEPORT_SERVER.lua")
|
||||
|
@ -12,7 +12,7 @@ struct SpyData {
|
||||
uint32_t missionID;
|
||||
};
|
||||
|
||||
class NtFactionSpyServer : public CppScripts::Script {
|
||||
class NtFactionSpyServer : public virtual CppScripts::Script {
|
||||
void OnStartup(Entity* self) override;
|
||||
void OnProximityUpdate(Entity* self, Entity* entering, std::string name, std::string status) override;
|
||||
void OnCinematicUpdate(Entity* self, Entity* sender, eCinematicEvent event, const std::u16string& pathName, float_t pathTime, float_t totalTime, int32_t waypoint) override;
|
||||
|
@ -6,4 +6,10 @@ foreach(file ${DSCRIPTS_SOURCES_AI_MINIGAME_SG_GF})
|
||||
set(DSCRIPTS_SOURCES_AI_MINIGAME ${DSCRIPTS_SOURCES_AI_MINIGAME} "SG_GF/${file}")
|
||||
endforeach()
|
||||
|
||||
add_subdirectory(Objects)
|
||||
|
||||
foreach(file ${DSCRIPTS_SOURCES_AI_MINIGAME_OBJECTS})
|
||||
set(DSCRIPTS_SOURCES_AI_MINIGAME ${DSCRIPTS_SOURCES_AI_MINIGAME} "Objects/${file}")
|
||||
endforeach()
|
||||
|
||||
set(DSCRIPTS_SOURCES_AI_MINIGAME ${DSCRIPTS_SOURCES_AI_MINIGAME} PARENT_SCOPE)
|
||||
|
4
dScripts/ai/MINIGAME/Objects/CMakeLists.txt
Normal file
4
dScripts/ai/MINIGAME/Objects/CMakeLists.txt
Normal file
@ -0,0 +1,4 @@
|
||||
SET(DSCRIPTS_SOURCES_AI_MINIGAME_OBJECTS
|
||||
"MinigameBlueMark.cpp"
|
||||
PARENT_SCOPE
|
||||
)
|
7
dScripts/ai/MINIGAME/Objects/MinigameBlueMark.cpp
Normal file
7
dScripts/ai/MINIGAME/Objects/MinigameBlueMark.cpp
Normal file
@ -0,0 +1,7 @@
|
||||
#include "MinigameBlueMark.h"
|
||||
#include "Game.h"
|
||||
#include "dZoneManager.h"
|
||||
|
||||
void MinigameBlueMark::OnStartup(Entity* self) {
|
||||
Game::zoneManager->GetZoneControlObject()->NotifyObject(self, "Blue_Mark");
|
||||
}
|
6
dScripts/ai/MINIGAME/Objects/MinigameBlueMark.h
Normal file
6
dScripts/ai/MINIGAME/Objects/MinigameBlueMark.h
Normal file
@ -0,0 +1,6 @@
|
||||
#include "CppScripts.h"
|
||||
|
||||
class MinigameBlueMark : public CppScripts::Script {
|
||||
public:
|
||||
void OnStartup(Entity* self) override;
|
||||
};
|
@ -1040,6 +1040,13 @@ void SGCannon::ResetVars(Entity* self) {
|
||||
self->SetVar<std::vector<LOT>>(RewardsVariable, {});
|
||||
self->SetVar<uint32_t>(TotalScoreVariable, 0);
|
||||
|
||||
self->SetVar<uint32_t>(u"m_curStreak", 0);
|
||||
self->SetNetworkVar<float>(u"SuperChargeBar", 0);
|
||||
self->SetVar<uint32_t>(u"LastSuperTotal", 0);
|
||||
self->SetNetworkVar<float>(u"SuperChargeBar", 0.0f);
|
||||
self->SetNetworkVar<bool>(u"ShowStreak", 0);
|
||||
self->SetNetworkVar<bool>(u"UnMarkAll", true);
|
||||
|
||||
const_cast<std::vector<SGEnemy>&>(self->GetVar<std::vector<SGEnemy>>(ActiveSpawnsVariable)).clear();
|
||||
self->SetVar<std::vector<SGEnemy>>(ActiveSpawnsVariable, {});
|
||||
|
||||
|
@ -76,6 +76,7 @@
|
||||
#include "EntityManager.h"
|
||||
#include "CheatDetection.h"
|
||||
#include "eGameMasterLevel.h"
|
||||
#include "StringifiedEnum.h"
|
||||
|
||||
namespace Game {
|
||||
Logger* logger = nullptr;
|
||||
@ -216,7 +217,7 @@ int main(int argc, char** argv) {
|
||||
uint32_t chatPort = 1501;
|
||||
if (Game::config->GetValue("chat_server_port") != "") chatPort = std::atoi(Game::config->GetValue("chat_server_port").c_str());
|
||||
|
||||
auto chatSock = SocketDescriptor(uint16_t(ourPort + 2), 0);
|
||||
auto chatSock = SocketDescriptor(static_cast<uint16_t>(ourPort + 2), 0);
|
||||
Game::chatServer = RakNetworkFactory::GetRakPeerInterface();
|
||||
Game::chatServer->Startup(1, 30, &chatSock, 1);
|
||||
Game::chatServer->Connect(masterIP.c_str(), chatPort, "3.25 ND1", 8);
|
||||
@ -1244,7 +1245,9 @@ void HandlePacket(Packet* packet) {
|
||||
}
|
||||
|
||||
default:
|
||||
LOG("Unknown world packet received: %i", int(packet->data[3]));
|
||||
const auto messageId = *reinterpret_cast<eWorldMessageType*>(&packet->data[3]);
|
||||
const std::string_view messageIdString = StringifiedEnum::ToString(messageId);
|
||||
LOG("Unknown world packet received: %4i, %s", messageId, messageIdString.data());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,36 +16,20 @@
|
||||
#include "AssetManager.h"
|
||||
#include "dConfig.h"
|
||||
|
||||
void Level::SceneObjectDataChunk::PrintAllObjects() const {
|
||||
for (const auto& [id, sceneObj] : objects) {
|
||||
LOG("ID: %d LOT: %d", id, sceneObj.lot);
|
||||
}
|
||||
}
|
||||
|
||||
Level::Level(Zone* parentZone, const std::string& filepath) {
|
||||
m_ParentZone = parentZone;
|
||||
|
||||
auto buffer = Game::assetManager->GetFileAsBuffer(filepath.c_str());
|
||||
auto stream = Game::assetManager->GetFile(filepath.c_str());
|
||||
|
||||
if (!buffer.m_Success) {
|
||||
if (!stream) {
|
||||
LOG("Failed to load %s", filepath.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
std::istream file(&buffer);
|
||||
ReadChunks(file);
|
||||
|
||||
buffer.close();
|
||||
|
||||
ReadChunks(stream);
|
||||
}
|
||||
|
||||
Level::~Level() {
|
||||
for (auto& [id, header] : m_ChunkHeaders) {
|
||||
if (header.id == Level::ChunkTypeID::FileInfo) delete header.fileInfo;
|
||||
if (header.id == Level::ChunkTypeID::SceneObjectData) delete header.sceneObjects;
|
||||
}
|
||||
}
|
||||
|
||||
void Level::MakeSpawner(SceneObject obj){
|
||||
void Level::MakeSpawner(SceneObject obj) {
|
||||
SpawnerInfo spawnInfo = SpawnerInfo();
|
||||
SpawnerNode* node = new SpawnerNode();
|
||||
spawnInfo.templateID = obj.lot;
|
||||
@ -56,7 +40,7 @@ void Level::MakeSpawner(SceneObject obj){
|
||||
node->config = obj.settings;
|
||||
spawnInfo.nodes.push_back(node);
|
||||
for (LDFBaseData* data : obj.settings) {
|
||||
if (data) {
|
||||
if (!data) continue;
|
||||
if (data->GetKey() == u"spawntemplate") {
|
||||
spawnInfo.templateID = std::stoi(data->GetValueAsString());
|
||||
}
|
||||
@ -99,7 +83,7 @@ void Level::MakeSpawner(SceneObject obj){
|
||||
if (data->GetKey() == u"groupID") { // Load object groups
|
||||
std::string groupStr = data->GetValueAsString();
|
||||
spawnInfo.groups = GeneralUtils::SplitString(groupStr, ';');
|
||||
spawnInfo.groups.erase(spawnInfo.groups.end() - 1);
|
||||
if (spawnInfo.groups.back().empty()) spawnInfo.groups.erase(spawnInfo.groups.end() - 1);
|
||||
}
|
||||
if (data->GetKey() == u"no_auto_spawn") {
|
||||
spawnInfo.noAutoSpawn = static_cast<LDFData<bool>*>(data)->GetValue();
|
||||
@ -111,16 +95,8 @@ void Level::MakeSpawner(SceneObject obj){
|
||||
spawnInfo.spawnActivator = static_cast<LDFData<bool>*>(data)->GetValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
Game::zoneManager->MakeSpawner(spawnInfo);
|
||||
}
|
||||
|
||||
const void Level::PrintAllObjects() {
|
||||
for (std::map<uint32_t, Header>::iterator it = m_ChunkHeaders.begin(); it != m_ChunkHeaders.end(); ++it) {
|
||||
if (it->second.id == Level::ChunkTypeID::SceneObjectData) {
|
||||
it->second.sceneObjects->PrintAllObjects();
|
||||
}
|
||||
}
|
||||
Game::zoneManager->MakeSpawner(spawnInfo);
|
||||
}
|
||||
|
||||
void Level::ReadChunks(std::istream& file) {
|
||||
@ -155,11 +131,10 @@ void Level::ReadChunks(std::istream& file) {
|
||||
file.seekg(0);
|
||||
Header header;
|
||||
header.id = ChunkTypeID::FileInfo; //I guess?
|
||||
FileInfoChunk* fileInfo = new FileInfoChunk();
|
||||
BinaryIO::BinaryRead(file, header.chunkVersion);
|
||||
BinaryIO::BinaryRead(file, header.chunkType);
|
||||
file.ignore(1);
|
||||
BinaryIO::BinaryRead(file, fileInfo->revision);
|
||||
BinaryIO::BinaryRead(file, header.fileInfo.revision);
|
||||
|
||||
if (header.chunkVersion >= 45) file.ignore(4);
|
||||
file.ignore(4 * (4 * 3));
|
||||
@ -172,9 +147,7 @@ void Level::ReadChunks(std::istream& file) {
|
||||
uint32_t s = 0;
|
||||
BinaryIO::BinaryRead(file, s);
|
||||
for (uint32_t i = 0; i < s; ++i) {
|
||||
file.ignore(4); //a uint
|
||||
file.ignore(4); //two floats
|
||||
file.ignore(4);
|
||||
file.ignore(4 * 3); //a uint and two floats
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -208,7 +181,6 @@ void Level::ReadChunks(std::istream& file) {
|
||||
BinaryIO::BinaryRead(file, count);
|
||||
file.ignore(count * 12);
|
||||
|
||||
header.fileInfo = fileInfo;
|
||||
m_ChunkHeaders.insert(std::make_pair(header.id, header));
|
||||
|
||||
//Now pretend to be a normal file and read Objects chunk:
|
||||
@ -222,20 +194,17 @@ void Level::ReadChunks(std::istream& file) {
|
||||
}
|
||||
|
||||
void Level::ReadFileInfoChunk(std::istream& file, Header& header) {
|
||||
FileInfoChunk* fi = new FileInfoChunk;
|
||||
BinaryIO::BinaryRead(file, fi->version);
|
||||
BinaryIO::BinaryRead(file, fi->revision);
|
||||
BinaryIO::BinaryRead(file, fi->enviromentChunkStart);
|
||||
BinaryIO::BinaryRead(file, fi->objectChunkStart);
|
||||
BinaryIO::BinaryRead(file, fi->particleChunkStart);
|
||||
header.fileInfo = fi;
|
||||
BinaryIO::BinaryRead(file, header.fileInfo.version);
|
||||
BinaryIO::BinaryRead(file, header.fileInfo.revision);
|
||||
BinaryIO::BinaryRead(file, header.fileInfo.enviromentChunkStart);
|
||||
BinaryIO::BinaryRead(file, header.fileInfo.objectChunkStart);
|
||||
BinaryIO::BinaryRead(file, header.fileInfo.particleChunkStart);
|
||||
|
||||
//PATCH FOR AG: (messed up file?)
|
||||
if (header.fileInfo->revision == 3452816845 && m_ParentZone->GetZoneID().GetMapID() == 1100) header.fileInfo->revision = 26;
|
||||
if (header.fileInfo.revision == 0xCDCDCDCD && m_ParentZone->GetZoneID().GetMapID() == 1100) header.fileInfo.revision = 26;
|
||||
}
|
||||
|
||||
void Level::ReadSceneObjectDataChunk(std::istream& file, Header& header) {
|
||||
SceneObjectDataChunk* chunk = new SceneObjectDataChunk;
|
||||
uint32_t objectsCount = 0;
|
||||
BinaryIO::BinaryRead(file, objectsCount);
|
||||
|
||||
@ -249,7 +218,10 @@ void Level::ReadSceneObjectDataChunk(std::istream& file, Header& header) {
|
||||
GeneralUtils::TryParse<int32_t>(Game::config->GetValue("version_current"), gating.current);
|
||||
GeneralUtils::TryParse<int32_t>(Game::config->GetValue("version_minor"), gating.minor);
|
||||
|
||||
const auto zoneControlObject = Game::zoneManager->GetZoneControlObject();
|
||||
DluAssert(zoneControlObject != nullptr);
|
||||
for (uint32_t i = 0; i < objectsCount; ++i) {
|
||||
std::u16string ldfString;
|
||||
SceneObject obj;
|
||||
BinaryIO::BinaryRead(file, obj.id);
|
||||
BinaryIO::BinaryRead(file, obj.lot);
|
||||
@ -260,6 +232,8 @@ void Level::ReadSceneObjectDataChunk(std::istream& file, Header& header) {
|
||||
BinaryIO::BinaryRead(file, obj.position);
|
||||
BinaryIO::BinaryRead(file, obj.rotation);
|
||||
BinaryIO::BinaryRead(file, obj.scale);
|
||||
BinaryIO::ReadString<uint32_t>(file, ldfString);
|
||||
BinaryIO::BinaryRead(file, obj.value3);
|
||||
|
||||
//This is a little bit of a bodge, but because the alpha client (HF) doesn't store the
|
||||
//spawn position / rotation like the later versions do, we need to check the LOT for the spawn pos & set it.
|
||||
@ -268,16 +242,6 @@ void Level::ReadSceneObjectDataChunk(std::istream& file, Header& header) {
|
||||
Game::zoneManager->GetZone()->SetSpawnRot(obj.rotation);
|
||||
}
|
||||
|
||||
std::u16string ldfString = u"";
|
||||
uint32_t length = 0;
|
||||
BinaryIO::BinaryRead(file, length);
|
||||
|
||||
for (uint32_t i = 0; i < length; ++i) {
|
||||
uint16_t data;
|
||||
BinaryIO::BinaryRead(file, data);
|
||||
ldfString.push_back(data);
|
||||
}
|
||||
|
||||
std::string sData = GeneralUtils::UTF16ToWTF8(ldfString);
|
||||
std::stringstream ssData(sData);
|
||||
std::string token;
|
||||
@ -288,35 +252,40 @@ void Level::ReadSceneObjectDataChunk(std::istream& file, Header& header) {
|
||||
obj.settings.push_back(ldfData);
|
||||
}
|
||||
|
||||
BinaryIO::BinaryRead(file, obj.value3);
|
||||
|
||||
// Feature gating
|
||||
bool gated = false;
|
||||
// We should never have more than 1 zone control object
|
||||
bool skipLoadingObject = obj.lot == zoneControlObject->GetLOT();
|
||||
for (LDFBaseData* data : obj.settings) {
|
||||
if (!data) continue;
|
||||
if (data->GetKey() == u"gatingOnFeature") {
|
||||
gating.featureName = data->GetValueAsString();
|
||||
if (gating.featureName == Game::config->GetValue("event_1")) break;
|
||||
else if (gating.featureName == Game::config->GetValue("event_2")) break;
|
||||
else if (gating.featureName == Game::config->GetValue("event_3")) break;
|
||||
else if (gating.featureName == Game::config->GetValue("event_4")) break;
|
||||
else if (gating.featureName == Game::config->GetValue("event_5")) break;
|
||||
else if (gating.featureName == Game::config->GetValue("event_6")) break;
|
||||
else if (gating.featureName == Game::config->GetValue("event_7")) break;
|
||||
else if (gating.featureName == Game::config->GetValue("event_8")) break;
|
||||
if (gating.featureName == Game::config->GetValue("event_1")) continue;
|
||||
else if (gating.featureName == Game::config->GetValue("event_2")) continue;
|
||||
else if (gating.featureName == Game::config->GetValue("event_3")) continue;
|
||||
else if (gating.featureName == Game::config->GetValue("event_4")) continue;
|
||||
else if (gating.featureName == Game::config->GetValue("event_5")) continue;
|
||||
else if (gating.featureName == Game::config->GetValue("event_6")) continue;
|
||||
else if (gating.featureName == Game::config->GetValue("event_7")) continue;
|
||||
else if (gating.featureName == Game::config->GetValue("event_8")) continue;
|
||||
else if (!featureGatingTable->FeatureUnlocked(gating)) {
|
||||
gated = true;
|
||||
// The feature is not unlocked, so we can skip loading this object
|
||||
skipLoadingObject = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If this is a client only object, we can skip loading it
|
||||
if (data->GetKey() == u"loadOnClientOnly") {
|
||||
skipLoadingObject |= static_cast<bool>(std::stoi(data->GetValueAsString()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (gated) {
|
||||
if (skipLoadingObject) {
|
||||
for (auto* setting : obj.settings) {
|
||||
delete setting;
|
||||
setting = nullptr;
|
||||
}
|
||||
|
||||
obj.settings.clear();
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -331,45 +300,7 @@ void Level::ReadSceneObjectDataChunk(std::istream& file, Header& header) {
|
||||
info.rot = obj.rotation;
|
||||
info.settings = obj.settings;
|
||||
info.scale = obj.scale;
|
||||
|
||||
//Check to see if we shouldn't be loading this:
|
||||
bool clientOnly = false;
|
||||
bool serverOnly = false;
|
||||
std::string featureGate = "";
|
||||
for (LDFBaseData* data : obj.settings) {
|
||||
if (data) {
|
||||
if (data->GetKey() == u"loadOnClientOnly") {
|
||||
clientOnly = (bool)std::stoi(data->GetValueAsString());
|
||||
break;
|
||||
}
|
||||
if (data->GetKey() == u"loadSrvrOnly") {
|
||||
serverOnly = (bool)std::stoi(data->GetValueAsString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!clientOnly) {
|
||||
|
||||
// We should never have more than 1 zone control object
|
||||
const auto zoneControlObject = Game::zoneManager->GetZoneControlObject();
|
||||
if (zoneControlObject != nullptr && info.lot == zoneControlObject->GetLOT())
|
||||
goto deleteSettings;
|
||||
|
||||
Game::entityManager->CreateEntity(info, nullptr);
|
||||
} else {
|
||||
deleteSettings:
|
||||
|
||||
for (auto* setting : info.settings) {
|
||||
delete setting;
|
||||
setting = nullptr;
|
||||
}
|
||||
|
||||
info.settings.clear();
|
||||
obj.settings.clear();
|
||||
}
|
||||
Game::entityManager->CreateEntity(info);
|
||||
}
|
||||
}
|
||||
|
||||
header.sceneObjects = chunk;
|
||||
}
|
||||
|
@ -27,33 +27,21 @@ public:
|
||||
uint32_t particleChunkStart;
|
||||
};
|
||||
|
||||
struct SceneObjectDataChunk {
|
||||
std::map<LWOOBJID, SceneObject> objects;
|
||||
|
||||
void PrintAllObjects() const;
|
||||
|
||||
uint32_t GetObjectCount() { return objects.size(); }
|
||||
};
|
||||
|
||||
struct Header {
|
||||
uint32_t id;
|
||||
uint16_t chunkVersion;
|
||||
ChunkTypeID chunkType;
|
||||
uint32_t size;
|
||||
uint32_t startPosition;
|
||||
FileInfoChunk* fileInfo;
|
||||
SceneObjectDataChunk* sceneObjects;
|
||||
FileInfoChunk fileInfo;
|
||||
LWOSCENEID lwoSceneID;
|
||||
};
|
||||
|
||||
public:
|
||||
Level(Zone* parentZone, const std::string& filepath);
|
||||
~Level();
|
||||
|
||||
static void MakeSpawner(SceneObject obj);
|
||||
|
||||
const void PrintAllObjects();
|
||||
|
||||
std::map<uint32_t, Header> m_ChunkHeaders;
|
||||
private:
|
||||
Zone* m_ParentZone;
|
||||
|
@ -205,6 +205,15 @@ void Spawner::Update(const float deltaTime) {
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<LWOOBJID> Spawner::GetSpawnedObjectIDs() const {
|
||||
std::vector<LWOOBJID> ids;
|
||||
ids.reserve(m_Entities.size());
|
||||
for (const auto& [objId, spawnerNode] : m_Entities) {
|
||||
ids.push_back(objId);
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
void Spawner::NotifyOfEntityDeath(const LWOOBJID& objectID) {
|
||||
for (std::function<void()> cb : m_SpawnedEntityDieCallbacks) {
|
||||
cb();
|
||||
|
@ -66,6 +66,7 @@ public:
|
||||
void SetRespawnTime(float time);
|
||||
void SetNumToMaintain(int32_t value);
|
||||
bool GetIsSpawnSmashGroup() const { return m_SpawnSmashFoundGroup; };
|
||||
std::vector<LWOOBJID> GetSpawnedObjectIDs() const;
|
||||
|
||||
SpawnerInfo m_Info;
|
||||
bool m_Active = true;
|
||||
|
@ -20,7 +20,6 @@
|
||||
|
||||
Zone::Zone(const LWOMAPID& mapID, const LWOINSTANCEID& instanceID, const LWOCLONEID& cloneID) :
|
||||
m_ZoneID(mapID, instanceID, cloneID) {
|
||||
m_NumberOfScenesLoaded = 0;
|
||||
m_NumberOfObjectsLoaded = 0;
|
||||
m_NumberOfSceneTransitionsLoaded = 0;
|
||||
m_CheckSum = 0;
|
||||
@ -46,14 +45,13 @@ void Zone::LoadZoneIntoMemory() {
|
||||
m_ZonePath = m_ZoneFilePath.substr(0, m_ZoneFilePath.rfind('/') + 1);
|
||||
if (m_ZoneFilePath == "ERR") return;
|
||||
|
||||
AssetMemoryBuffer buffer = Game::assetManager->GetFileAsBuffer(m_ZoneFilePath.c_str());
|
||||
auto file = Game::assetManager->GetFile(m_ZoneFilePath.c_str());
|
||||
|
||||
if (!buffer.m_Success) {
|
||||
if (!file) {
|
||||
LOG("Failed to load %s", m_ZoneFilePath.c_str());
|
||||
throw std::runtime_error("Aborting Zone loading due to no Zone File.");
|
||||
}
|
||||
|
||||
std::istream file(&buffer);
|
||||
if (file) {
|
||||
BinaryIO::BinaryRead(file, m_FileFormatVersion);
|
||||
|
||||
@ -81,18 +79,10 @@ void Zone::LoadZoneIntoMemory() {
|
||||
}
|
||||
|
||||
//Read generic zone info:
|
||||
uint8_t stringLength;
|
||||
BinaryIO::BinaryRead(file, stringLength);
|
||||
m_ZonePath = BinaryIO::ReadString(file, stringLength);
|
||||
|
||||
BinaryIO::BinaryRead(file, stringLength);
|
||||
m_ZoneRawPath = BinaryIO::ReadString(file, stringLength);
|
||||
|
||||
BinaryIO::BinaryRead(file, stringLength);
|
||||
m_ZoneName = BinaryIO::ReadString(file, stringLength);
|
||||
|
||||
BinaryIO::BinaryRead(file, stringLength);
|
||||
m_ZoneDesc = BinaryIO::ReadString(file, stringLength);
|
||||
BinaryIO::ReadString<uint8_t>(file, m_ZonePath, BinaryIO::ReadType::String);
|
||||
BinaryIO::ReadString<uint8_t>(file, m_ZoneRawPath, BinaryIO::ReadType::String);
|
||||
BinaryIO::ReadString<uint8_t>(file, m_ZoneName, BinaryIO::ReadType::String);
|
||||
BinaryIO::ReadString<uint8_t>(file, m_ZoneDesc, BinaryIO::ReadType::String);
|
||||
|
||||
if (m_FileFormatVersion >= Zone::FileFormatVersion::PreAlpha) {
|
||||
BinaryIO::BinaryRead(file, m_NumberOfSceneTransitionsLoaded);
|
||||
@ -108,59 +98,57 @@ void Zone::LoadZoneIntoMemory() {
|
||||
uint32_t pathCount;
|
||||
BinaryIO::BinaryRead(file, pathCount);
|
||||
|
||||
m_Paths.reserve(pathCount);
|
||||
for (uint32_t i = 0; i < pathCount; ++i) LoadPath(file);
|
||||
|
||||
for (Path path : m_Paths) {
|
||||
if (path.pathType == PathType::Spawner) {
|
||||
SpawnerInfo info = SpawnerInfo();
|
||||
for (PathWaypoint waypoint : path.pathWaypoints) {
|
||||
SpawnerNode* node = new SpawnerNode();
|
||||
node->position = waypoint.position;
|
||||
node->rotation = waypoint.rotation;
|
||||
node->nodeID = 0;
|
||||
node->config = waypoint.config;
|
||||
if (path.pathType != PathType::Spawner) continue;
|
||||
SpawnerInfo info = SpawnerInfo();
|
||||
for (PathWaypoint waypoint : path.pathWaypoints) {
|
||||
SpawnerNode* node = new SpawnerNode();
|
||||
node->position = waypoint.position;
|
||||
node->rotation = waypoint.rotation;
|
||||
node->nodeID = 0;
|
||||
node->config = waypoint.config;
|
||||
|
||||
for (LDFBaseData* data : waypoint.config) {
|
||||
if (data) {
|
||||
if (data->GetKey() == u"spawner_node_id") {
|
||||
node->nodeID = std::stoi(data->GetValueAsString());
|
||||
} else if (data->GetKey() == u"spawner_max_per_node") {
|
||||
node->nodeMax = std::stoi(data->GetValueAsString());
|
||||
} else if (data->GetKey() == u"groupID") { // Load object group
|
||||
std::string groupStr = data->GetValueAsString();
|
||||
info.groups = GeneralUtils::SplitString(groupStr, ';');
|
||||
info.groups.erase(info.groups.end() - 1);
|
||||
} else if (data->GetKey() == u"grpNameQBShowBricks") {
|
||||
if (data->GetValueAsString() == "") continue;
|
||||
/*std::string groupStr = data->GetValueAsString();
|
||||
info.groups.push_back(groupStr);*/
|
||||
info.grpNameQBShowBricks = data->GetValueAsString();
|
||||
} else if (data->GetKey() == u"spawner_name") {
|
||||
info.name = data->GetValueAsString();
|
||||
}
|
||||
}
|
||||
for (LDFBaseData* data : waypoint.config) {
|
||||
if (!data) continue;
|
||||
|
||||
if (data->GetKey() == u"spawner_node_id") {
|
||||
node->nodeID = std::stoi(data->GetValueAsString());
|
||||
} else if (data->GetKey() == u"spawner_max_per_node") {
|
||||
node->nodeMax = std::stoi(data->GetValueAsString());
|
||||
} else if (data->GetKey() == u"groupID") { // Load object group
|
||||
std::string groupStr = data->GetValueAsString();
|
||||
info.groups = GeneralUtils::SplitString(groupStr, ';');
|
||||
if (info.groups.back().empty()) info.groups.erase(info.groups.end() - 1);
|
||||
} else if (data->GetKey() == u"grpNameQBShowBricks") {
|
||||
if (data->GetValueAsString().empty()) continue;
|
||||
/*std::string groupStr = data->GetValueAsString();
|
||||
info.groups.push_back(groupStr);*/
|
||||
info.grpNameQBShowBricks = data->GetValueAsString();
|
||||
} else if (data->GetKey() == u"spawner_name") {
|
||||
info.name = data->GetValueAsString();
|
||||
}
|
||||
info.nodes.push_back(node);
|
||||
}
|
||||
info.templateID = path.spawner.spawnedLOT;
|
||||
info.spawnerID = path.spawner.spawnerObjID;
|
||||
info.respawnTime = path.spawner.respawnTime;
|
||||
info.amountMaintained = path.spawner.amountMaintained;
|
||||
info.maxToSpawn = path.spawner.maxToSpawn;
|
||||
info.activeOnLoad = path.spawner.spawnerNetActive;
|
||||
info.isNetwork = true;
|
||||
Spawner* spawner = new Spawner(info);
|
||||
Game::zoneManager->AddSpawner(info.spawnerID, spawner);
|
||||
info.nodes.push_back(node);
|
||||
}
|
||||
|
||||
info.templateID = path.spawner.spawnedLOT;
|
||||
info.spawnerID = path.spawner.spawnerObjID;
|
||||
info.respawnTime = path.spawner.respawnTime;
|
||||
info.amountMaintained = path.spawner.amountMaintained;
|
||||
info.maxToSpawn = path.spawner.maxToSpawn;
|
||||
info.activeOnLoad = path.spawner.spawnerNetActive;
|
||||
info.isNetwork = true;
|
||||
Spawner* spawner = new Spawner(info);
|
||||
Game::zoneManager->AddSpawner(info.spawnerID, spawner);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LOG("Failed to open: %s", m_ZoneFilePath.c_str());
|
||||
}
|
||||
|
||||
m_ZonePath = m_ZoneFilePath.substr(0, m_ZoneFilePath.rfind('/') + 1);
|
||||
|
||||
buffer.close();
|
||||
}
|
||||
|
||||
std::string Zone::GetFilePathForZoneID() {
|
||||
@ -180,16 +168,16 @@ std::string Zone::GetFilePathForZoneID() {
|
||||
uint32_t Zone::CalculateChecksum() {
|
||||
uint32_t sum1 = 0xffff, sum2 = 0xffff;
|
||||
|
||||
for (std::map<LWOSCENEID, uint32_t>::const_iterator it = m_MapRevisions.cbegin(); it != m_MapRevisions.cend(); ++it) {
|
||||
uint32_t sceneID = it->first.GetSceneID();
|
||||
for (const auto& [scene, sceneRevision] : m_MapRevisions) {
|
||||
uint32_t sceneID = scene.GetSceneID();
|
||||
sum2 += sum1 += (sceneID >> 16);
|
||||
sum2 += sum1 += (sceneID & 0xffff);
|
||||
|
||||
uint32_t layerID = it->first.GetLayerID();
|
||||
uint32_t layerID = scene.GetLayerID();
|
||||
sum2 += sum1 += (layerID >> 16);
|
||||
sum2 += sum1 += (layerID & 0xffff);
|
||||
|
||||
uint32_t revision = it->second;
|
||||
uint32_t revision = sceneRevision;
|
||||
sum2 += sum1 += (revision >> 16);
|
||||
sum2 += sum1 += (revision & 0xffff);
|
||||
}
|
||||
@ -201,30 +189,20 @@ uint32_t Zone::CalculateChecksum() {
|
||||
}
|
||||
|
||||
void Zone::LoadLevelsIntoMemory() {
|
||||
for (std::map<LWOSCENEID, SceneRef>::iterator it = m_Scenes.begin(); it != m_Scenes.end(); ++it) {
|
||||
if (it->second.level == nullptr) {
|
||||
it->second.level = new Level(this, m_ZonePath + it->second.filename);
|
||||
for (auto& [sceneID, scene] : m_Scenes) {
|
||||
if (scene.level) continue;
|
||||
scene.level = new Level(this, m_ZonePath + scene.filename);
|
||||
|
||||
if (it->second.level->m_ChunkHeaders.size() > 0) {
|
||||
it->second.level->m_ChunkHeaders.begin()->second.lwoSceneID = it->first;
|
||||
AddRevision(it->second.level->m_ChunkHeaders.begin()->second.lwoSceneID, it->second.level->m_ChunkHeaders.begin()->second.fileInfo->revision);
|
||||
}
|
||||
}
|
||||
if (scene.level->m_ChunkHeaders.empty()) continue;
|
||||
|
||||
scene.level->m_ChunkHeaders.begin()->second.lwoSceneID = sceneID;
|
||||
AddRevision(scene.level->m_ChunkHeaders.begin()->second.lwoSceneID, scene.level->m_ChunkHeaders.begin()->second.fileInfo.revision);
|
||||
}
|
||||
}
|
||||
|
||||
void Zone::AddRevision(LWOSCENEID sceneID, uint32_t revision) {
|
||||
for (std::pair<LWOSCENEID, uint32_t> item : m_MapRevisions) {
|
||||
if (item.first == sceneID) return;
|
||||
}
|
||||
|
||||
m_MapRevisions[LWOSCENEID(sceneID)] = revision;
|
||||
}
|
||||
|
||||
const void Zone::PrintAllGameObjects() {
|
||||
for (std::pair<LWOSCENEID, SceneRef> scene : m_Scenes) {
|
||||
LOG("In sceneID: %i", scene.first.GetSceneID());
|
||||
scene.second.level->PrintAllObjects();
|
||||
if (m_MapRevisions.find(sceneID) == m_MapRevisions.end()) {
|
||||
m_MapRevisions.insert(std::make_pair(sceneID, revision));
|
||||
}
|
||||
}
|
||||
|
||||
@ -233,17 +211,10 @@ void Zone::LoadScene(std::istream& file) {
|
||||
scene.level = nullptr;
|
||||
LWOSCENEID lwoSceneID(LWOZONEID_INVALID, 0);
|
||||
|
||||
uint8_t sceneFilenameLength;
|
||||
BinaryIO::BinaryRead(file, sceneFilenameLength);
|
||||
scene.filename = BinaryIO::ReadString(file, sceneFilenameLength);
|
||||
BinaryIO::ReadString<uint8_t>(file, scene.filename, BinaryIO::ReadType::String);
|
||||
|
||||
std::string luTriggersPath = scene.filename.substr(0, scene.filename.size() - 4) + ".lutriggers";
|
||||
std::vector<LUTriggers::Trigger*> triggers;
|
||||
if(Game::assetManager->HasFile((m_ZonePath + luTriggersPath).c_str())) triggers = LoadLUTriggers(luTriggersPath, scene.id);
|
||||
|
||||
for (LUTriggers::Trigger* trigger : triggers) {
|
||||
scene.triggers.insert({ trigger->id, trigger });
|
||||
}
|
||||
if (Game::assetManager->HasFile((m_ZonePath + luTriggersPath).c_str())) LoadLUTriggers(luTriggersPath, scene);
|
||||
|
||||
if (m_FileFormatVersion >= Zone::FileFormatVersion::LatePreAlpha || m_FileFormatVersion < Zone::FileFormatVersion::PrePreAlpha) {
|
||||
BinaryIO::BinaryRead(file, scene.id);
|
||||
@ -253,12 +224,10 @@ void Zone::LoadScene(std::istream& file) {
|
||||
BinaryIO::BinaryRead(file, scene.sceneType);
|
||||
lwoSceneID.SetLayerID(scene.sceneType);
|
||||
|
||||
uint8_t sceneNameLength;
|
||||
BinaryIO::BinaryRead(file, sceneNameLength);
|
||||
scene.name = BinaryIO::ReadString(file, sceneNameLength);
|
||||
BinaryIO::ReadString<uint8_t>(file, scene.name, BinaryIO::ReadType::String);
|
||||
}
|
||||
|
||||
if (m_FileFormatVersion == Zone::FileFormatVersion::LatePreAlpha){
|
||||
if (m_FileFormatVersion == Zone::FileFormatVersion::LatePreAlpha) {
|
||||
BinaryIO::BinaryRead(file, scene.unknown1);
|
||||
BinaryIO::BinaryRead(file, scene.unknown2);
|
||||
}
|
||||
@ -270,61 +239,52 @@ void Zone::LoadScene(std::istream& file) {
|
||||
}
|
||||
|
||||
m_Scenes.insert(std::make_pair(lwoSceneID, scene));
|
||||
m_NumberOfScenesLoaded++;
|
||||
}
|
||||
|
||||
std::vector<LUTriggers::Trigger*> Zone::LoadLUTriggers(std::string triggerFile, LWOSCENEID sceneID) {
|
||||
std::vector<LUTriggers::Trigger*> lvlTriggers;
|
||||
|
||||
auto buffer = Game::assetManager->GetFileAsBuffer((m_ZonePath + triggerFile).c_str());
|
||||
|
||||
if (!buffer.m_Success) {
|
||||
LOG("Failed to load %s from disk. Skipping loading triggers", (m_ZonePath + triggerFile).c_str());
|
||||
return lvlTriggers;
|
||||
}
|
||||
|
||||
std::istream file(&buffer);
|
||||
void Zone::LoadLUTriggers(std::string triggerFile, SceneRef& scene) {
|
||||
auto file = Game::assetManager->GetFile((m_ZonePath + triggerFile).c_str());
|
||||
|
||||
std::stringstream data;
|
||||
data << file.rdbuf();
|
||||
|
||||
buffer.close();
|
||||
data.seekg(0, std::ios::end);
|
||||
int32_t size = data.tellg();
|
||||
data.seekg(0, std::ios::beg);
|
||||
|
||||
if (data.str().size() == 0) return lvlTriggers;
|
||||
if (size == 0) return;
|
||||
|
||||
tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument();
|
||||
if (!doc) return lvlTriggers;
|
||||
tinyxml2::XMLDocument doc;
|
||||
|
||||
if (doc->Parse(data.str().c_str(), data.str().size()) == 0) {
|
||||
//LOG("Loaded LUTriggers from file %s!", triggerFile.c_str());
|
||||
} else {
|
||||
if (doc.Parse(data.str().c_str(), size) != tinyxml2::XML_SUCCESS) {
|
||||
LOG("Failed to load LUTriggers from file %s", triggerFile.c_str());
|
||||
return lvlTriggers;
|
||||
return;
|
||||
}
|
||||
|
||||
tinyxml2::XMLElement* triggers = doc->FirstChildElement("triggers");
|
||||
if (!triggers) return lvlTriggers;
|
||||
auto* triggers = doc.FirstChildElement("triggers");
|
||||
if (!triggers) return;
|
||||
|
||||
auto currentTrigger = triggers->FirstChildElement("trigger");
|
||||
auto* currentTrigger = triggers->FirstChildElement("trigger");
|
||||
while (currentTrigger) {
|
||||
LUTriggers::Trigger* newTrigger = new LUTriggers::Trigger();
|
||||
currentTrigger->QueryAttribute("enabled", &newTrigger->enabled);
|
||||
currentTrigger->QueryAttribute("id", &newTrigger->id);
|
||||
|
||||
auto currentEvent = currentTrigger->FirstChildElement("event");
|
||||
auto* currentEvent = currentTrigger->FirstChildElement("event");
|
||||
while (currentEvent) {
|
||||
LUTriggers::Event* newEvent = new LUTriggers::Event();
|
||||
newEvent->id = TriggerEventType::StringToTriggerEventType(currentEvent->Attribute("id"));
|
||||
auto currentCommand = currentEvent->FirstChildElement("command");
|
||||
auto* currentCommand = currentEvent->FirstChildElement("command");
|
||||
while (currentCommand) {
|
||||
LUTriggers::Command* newCommand = new LUTriggers::Command();
|
||||
newCommand->id = TriggerCommandType::StringToTriggerCommandType(currentCommand->Attribute("id"));
|
||||
newCommand->target = currentCommand->Attribute("target");
|
||||
if (currentCommand->Attribute("targetName") != NULL) {
|
||||
if (currentCommand->Attribute("targetName")) {
|
||||
newCommand->targetName = currentCommand->Attribute("targetName");
|
||||
}
|
||||
if (currentCommand->Attribute("args") != NULL) {
|
||||
if (currentCommand->Attribute("args")) {
|
||||
newCommand->args = currentCommand->Attribute("args");
|
||||
}
|
||||
|
||||
newEvent->commands.push_back(newCommand);
|
||||
currentCommand = currentCommand->NextSiblingElement("command");
|
||||
}
|
||||
@ -332,19 +292,18 @@ std::vector<LUTriggers::Trigger*> Zone::LoadLUTriggers(std::string triggerFile,
|
||||
currentEvent = currentEvent->NextSiblingElement("event");
|
||||
}
|
||||
currentTrigger = currentTrigger->NextSiblingElement("trigger");
|
||||
lvlTriggers.push_back(newTrigger);
|
||||
scene.triggers.insert(std::make_pair(newTrigger->id, newTrigger));
|
||||
}
|
||||
|
||||
delete doc;
|
||||
|
||||
return lvlTriggers;
|
||||
}
|
||||
|
||||
LUTriggers::Trigger* Zone::GetTrigger(uint32_t sceneID, uint32_t triggerID) {
|
||||
if (m_Scenes.find(sceneID) == m_Scenes.end()) return nullptr;
|
||||
if (m_Scenes[sceneID].triggers.find(triggerID) == m_Scenes[sceneID].triggers.end()) return nullptr;
|
||||
auto scene = m_Scenes.find(sceneID);
|
||||
if (scene == m_Scenes.end()) return nullptr;
|
||||
|
||||
return m_Scenes[sceneID].triggers[triggerID];
|
||||
auto trigger = scene->second.triggers.find(triggerID);
|
||||
if (trigger == scene->second.triggers.end()) return nullptr;
|
||||
|
||||
return trigger->second;
|
||||
}
|
||||
|
||||
const Path* Zone::GetPath(std::string name) const {
|
||||
@ -360,15 +319,14 @@ const Path* Zone::GetPath(std::string name) const {
|
||||
void Zone::LoadSceneTransition(std::istream& file) {
|
||||
SceneTransition sceneTrans;
|
||||
if (m_FileFormatVersion < Zone::FileFormatVersion::Auramar) {
|
||||
uint8_t length;
|
||||
BinaryIO::BinaryRead(file, length);
|
||||
sceneTrans.name = BinaryIO::ReadString(file, length);
|
||||
BinaryIO::ReadString<uint8_t>(file, sceneTrans.name, BinaryIO::ReadType::String);
|
||||
BinaryIO::BinaryRead(file, sceneTrans.width);
|
||||
}
|
||||
|
||||
//BR<42>THER MAY I HAVE SOME L<><4C>PS?
|
||||
uint8_t loops = (m_FileFormatVersion <= Zone::FileFormatVersion::LatePreAlpha || m_FileFormatVersion >= Zone::FileFormatVersion::Launch) ? 2 : 5;
|
||||
|
||||
sceneTrans.points.reserve(loops);
|
||||
for (uint8_t i = 0; i < loops; ++i) {
|
||||
sceneTrans.points.push_back(LoadSceneTransitionInfo(file));
|
||||
}
|
||||
@ -388,13 +346,7 @@ void Zone::LoadPath(std::istream& file) {
|
||||
|
||||
BinaryIO::BinaryRead(file, path.pathVersion);
|
||||
|
||||
uint8_t stringLength;
|
||||
BinaryIO::BinaryRead(file, stringLength);
|
||||
for (uint8_t i = 0; i < stringLength; ++i) {
|
||||
uint16_t character;
|
||||
BinaryIO::BinaryRead(file, character);
|
||||
path.pathName.push_back(character);
|
||||
}
|
||||
BinaryIO::ReadString<uint8_t>(file, path.pathName, BinaryIO::ReadType::WideString);
|
||||
|
||||
BinaryIO::BinaryRead(file, path.pathType);
|
||||
BinaryIO::BinaryRead(file, path.flags);
|
||||
@ -404,13 +356,7 @@ void Zone::LoadPath(std::istream& file) {
|
||||
if (path.pathVersion >= 18) {
|
||||
BinaryIO::BinaryRead(file, path.movingPlatform.timeBasedMovement);
|
||||
} else if (path.pathVersion >= 13) {
|
||||
uint8_t count;
|
||||
BinaryIO::BinaryRead(file, count);
|
||||
for (uint8_t i = 0; i < count; ++i) {
|
||||
uint16_t character;
|
||||
BinaryIO::BinaryRead(file, character);
|
||||
path.movingPlatform.platformTravelSound.push_back(character);
|
||||
}
|
||||
BinaryIO::ReadString<uint8_t>(file, path.movingPlatform.platformTravelSound, BinaryIO::ReadType::WideString);
|
||||
}
|
||||
} else if (path.pathType == PathType::Property) {
|
||||
BinaryIO::BinaryRead(file, path.property.pathType);
|
||||
@ -419,20 +365,8 @@ void Zone::LoadPath(std::istream& file) {
|
||||
BinaryIO::BinaryRead(file, path.property.associatedZone);
|
||||
|
||||
if (path.pathVersion >= 5) {
|
||||
uint8_t count1;
|
||||
BinaryIO::BinaryRead(file, count1);
|
||||
for (uint8_t i = 0; i < count1; ++i) {
|
||||
uint16_t character;
|
||||
BinaryIO::BinaryRead(file, character);
|
||||
path.property.displayName.push_back(character);
|
||||
}
|
||||
uint32_t count2;
|
||||
BinaryIO::BinaryRead(file, count2);
|
||||
for (uint8_t i = 0; i < count2; ++i) {
|
||||
uint16_t character;
|
||||
BinaryIO::BinaryRead(file, character);
|
||||
path.property.displayDesc.push_back(character);
|
||||
}
|
||||
BinaryIO::ReadString<uint8_t>(file, path.property.displayName, BinaryIO::ReadType::WideString);
|
||||
BinaryIO::ReadString<uint32_t>(file, path.property.displayDesc, BinaryIO::ReadType::WideString);
|
||||
}
|
||||
|
||||
if (path.pathVersion >= 6) BinaryIO::BinaryRead(file, path.property.type);
|
||||
@ -449,13 +383,7 @@ void Zone::LoadPath(std::istream& file) {
|
||||
BinaryIO::BinaryRead(file, path.property.maxBuildHeight);
|
||||
}
|
||||
} else if (path.pathType == PathType::Camera) {
|
||||
uint8_t count;
|
||||
BinaryIO::BinaryRead(file, count);
|
||||
for (uint8_t i = 0; i < count; ++i) {
|
||||
uint16_t character;
|
||||
BinaryIO::BinaryRead(file, character);
|
||||
path.camera.nextPath.push_back(character);
|
||||
}
|
||||
BinaryIO::ReadString<uint8_t>(file, path.camera.nextPath, BinaryIO::ReadType::WideString);
|
||||
if (path.pathVersion >= 14) {
|
||||
BinaryIO::BinaryRead(file, path.camera.rotatePlayer);
|
||||
|
||||
@ -472,7 +400,7 @@ void Zone::LoadPath(std::istream& file) {
|
||||
// Read waypoints
|
||||
|
||||
BinaryIO::BinaryRead(file, path.waypointCount);
|
||||
|
||||
path.pathWaypoints.reserve(path.waypointCount);
|
||||
for (uint32_t i = 0; i < path.waypointCount; ++i) {
|
||||
PathWaypoint waypoint = PathWaypoint();
|
||||
|
||||
@ -493,20 +421,8 @@ void Zone::LoadPath(std::istream& file) {
|
||||
BinaryIO::BinaryRead(file, waypoint.movingPlatform.speed);
|
||||
BinaryIO::BinaryRead(file, waypoint.movingPlatform.wait);
|
||||
if (path.pathVersion >= 13) {
|
||||
uint8_t count1;
|
||||
BinaryIO::BinaryRead(file, count1);
|
||||
for (uint8_t i = 0; i < count1; ++i) {
|
||||
uint16_t character;
|
||||
BinaryIO::BinaryRead(file, character);
|
||||
waypoint.movingPlatform.departSound.push_back(character);
|
||||
}
|
||||
uint8_t count2;
|
||||
BinaryIO::BinaryRead(file, count2);
|
||||
for (uint8_t i = 0; i < count2; ++i) {
|
||||
uint16_t character;
|
||||
BinaryIO::BinaryRead(file, character);
|
||||
waypoint.movingPlatform.arriveSound.push_back(character);
|
||||
}
|
||||
BinaryIO::ReadString<uint8_t>(file, waypoint.movingPlatform.departSound, BinaryIO::ReadType::WideString);
|
||||
BinaryIO::ReadString<uint8_t>(file, waypoint.movingPlatform.arriveSound, BinaryIO::ReadType::WideString);
|
||||
}
|
||||
} else if (path.pathType == PathType::Camera) {
|
||||
BinaryIO::BinaryRead(file, waypoint.camera.time);
|
||||
@ -529,22 +445,11 @@ void Zone::LoadPath(std::istream& file) {
|
||||
uint32_t count;
|
||||
BinaryIO::BinaryRead(file, count);
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
uint8_t count1;
|
||||
std::string parameter;
|
||||
BinaryIO::ReadString<uint8_t>(file, parameter, BinaryIO::ReadType::WideString);
|
||||
|
||||
std::string value;
|
||||
BinaryIO::BinaryRead(file, count1);
|
||||
for (uint8_t i = 0; i < count1; ++i) {
|
||||
uint16_t character;
|
||||
BinaryIO::BinaryRead(file, character);
|
||||
parameter.push_back(character);
|
||||
}
|
||||
uint8_t count2;
|
||||
BinaryIO::BinaryRead(file, count2);
|
||||
for (uint8_t i = 0; i < count2; ++i) {
|
||||
uint16_t character;
|
||||
BinaryIO::BinaryRead(file, character);
|
||||
value.push_back(character);
|
||||
}
|
||||
BinaryIO::ReadString<uint8_t>(file, value, BinaryIO::ReadType::WideString);
|
||||
|
||||
LDFBaseData* ldfConfig = nullptr;
|
||||
if (path.pathType == PathType::Movement || path.pathType == PathType::Rail) {
|
||||
|
@ -210,7 +210,6 @@ public:
|
||||
void AddRevision(LWOSCENEID sceneID, uint32_t revision);
|
||||
const LWOZONEID& GetZoneID() const { return m_ZoneID; }
|
||||
const uint32_t GetChecksum() const { return m_CheckSum; }
|
||||
const void PrintAllGameObjects();
|
||||
LUTriggers::Trigger* GetTrigger(uint32_t sceneID, uint32_t triggerID);
|
||||
const Path* GetPath(std::string name) const;
|
||||
|
||||
@ -228,7 +227,6 @@ public:
|
||||
private:
|
||||
LWOZONEID m_ZoneID;
|
||||
std::string m_ZoneFilePath;
|
||||
uint32_t m_NumberOfScenesLoaded;
|
||||
uint32_t m_NumberOfObjectsLoaded;
|
||||
uint32_t m_NumberOfSceneTransitionsLoaded;
|
||||
FileFormatVersion m_FileFormatVersion;
|
||||
@ -243,18 +241,17 @@ private:
|
||||
std::string m_ZoneDesc; //Description of the zone by a level designer
|
||||
std::string m_ZoneRawPath; //Path to the .raw file of this zone.
|
||||
|
||||
std::map<LWOSCENEID, SceneRef, mapCompareLwoSceneIDs> m_Scenes;
|
||||
std::map<LWOSCENEID, SceneRef> m_Scenes;
|
||||
std::vector<SceneTransition> m_SceneTransitions;
|
||||
|
||||
uint32_t m_PathDataLength;
|
||||
uint32_t m_PathChunkVersion;
|
||||
std::vector<Path> m_Paths;
|
||||
|
||||
std::map<LWOSCENEID, uint32_t, mapCompareLwoSceneIDs> m_MapRevisions; //rhs is the revision!
|
||||
|
||||
std::map<LWOSCENEID, uint32_t> m_MapRevisions; //rhs is the revision!
|
||||
//private ("helper") functions:
|
||||
void LoadScene(std::istream& file);
|
||||
std::vector<LUTriggers::Trigger*> LoadLUTriggers(std::string triggerFile, LWOSCENEID sceneID);
|
||||
void LoadLUTriggers(std::string triggerFile, SceneRef& scene);
|
||||
void LoadSceneTransition(std::istream& file);
|
||||
SceneTransitionInfo LoadSceneTransitionInfo(std::istream& file);
|
||||
void LoadPath(std::istream& file);
|
||||
|
@ -5,10 +5,6 @@
|
||||
#include "LDFFormat.h"
|
||||
#include <vector>
|
||||
|
||||
struct mapCompareLwoSceneIDs {
|
||||
bool operator()(const LWOSCENEID& lhs, const LWOSCENEID& rhs) const { return lhs < rhs; }
|
||||
};
|
||||
|
||||
struct SceneObject {
|
||||
LWOOBJID id;
|
||||
LOT lot;
|
||||
|
@ -94,33 +94,6 @@ void dZoneManager::LoadZone(const LWOZONEID& zoneID) {
|
||||
m_pZone = new Zone(zoneID.GetMapID(), zoneID.GetInstanceID(), zoneID.GetCloneID());
|
||||
}
|
||||
|
||||
void dZoneManager::NotifyZone(const dZoneNotifier& notifier, const LWOOBJID& objectID) {
|
||||
switch (notifier) {
|
||||
case dZoneNotifier::SpawnedObjectDestroyed:
|
||||
break;
|
||||
case dZoneNotifier::SpawnedChildObjectDestroyed:
|
||||
break;
|
||||
case dZoneNotifier::ReloadZone:
|
||||
LOG("Forcing reload of zone %i", m_ZoneID.GetMapID());
|
||||
LoadZone(m_ZoneID);
|
||||
|
||||
m_pZone->Initalize();
|
||||
break;
|
||||
case dZoneNotifier::UserJoined:
|
||||
break;
|
||||
case dZoneNotifier::UserMoved:
|
||||
break;
|
||||
case dZoneNotifier::PrintAllGameObjects:
|
||||
m_pZone->PrintAllGameObjects();
|
||||
break;
|
||||
case dZoneNotifier::InvalidNotifier:
|
||||
LOG("Got an invalid zone notifier.");
|
||||
break;
|
||||
default:
|
||||
LOG("Unknown zone notifier: %i", int(notifier));
|
||||
}
|
||||
}
|
||||
|
||||
void dZoneManager::AddSpawner(LWOOBJID id, Spawner* spawner) {
|
||||
m_Spawners.insert_or_assign(id, spawner);
|
||||
}
|
||||
|
@ -14,7 +14,6 @@ public:
|
||||
ReloadZone, //Forces the server and all connects clients to reload the map
|
||||
UserJoined,
|
||||
UserMoved,
|
||||
PrintAllGameObjects, //Using this is a BAD idea in production
|
||||
InvalidNotifier
|
||||
};
|
||||
|
||||
@ -30,7 +29,6 @@ public:
|
||||
|
||||
Zone* GetZone(); //Gets a pointer to the currently loaded zone.
|
||||
void LoadZone(const LWOZONEID& zoneID); //Discard the current zone (if any) and loads a new zone.
|
||||
void NotifyZone(const dZoneNotifier& notifier, const LWOOBJID& objectID); //Notifies the zone of a certain event or command.
|
||||
void AddSpawner(LWOOBJID id, Spawner* spawner);
|
||||
LWOZONEID GetZoneID() const;
|
||||
LWOOBJID MakeSpawner(SpawnerInfo info);
|
||||
|
@ -1,6 +1,7 @@
|
||||
set(DCOMMONTEST_SOURCES
|
||||
"AMFDeserializeTests.cpp"
|
||||
"Amf3Tests.cpp"
|
||||
"CastUnderlyingTypeTests.cpp"
|
||||
"HeaderSkipTest.cpp"
|
||||
"TestCDFeatureGatingTable.cpp"
|
||||
"TestLDFFormat.cpp"
|
||||
@ -11,6 +12,9 @@ set(DCOMMONTEST_SOURCES
|
||||
"dCommonDependencies.cpp"
|
||||
)
|
||||
|
||||
add_subdirectory(dEnumsTests)
|
||||
list(APPEND DCOMMONTEST_SOURCES ${DENUMS_TESTS})
|
||||
|
||||
# Set our executable
|
||||
add_executable(dCommonTests ${DCOMMONTEST_SOURCES})
|
||||
|
||||
|
24
tests/dCommonTests/CastUnderlyingTypeTests.cpp
Normal file
24
tests/dCommonTests/CastUnderlyingTypeTests.cpp
Normal file
@ -0,0 +1,24 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "GeneralUtils.h"
|
||||
|
||||
#include "eGameMasterLevel.h"
|
||||
#include "eGameMessageType.h"
|
||||
#include "eWorldMessageType.h"
|
||||
|
||||
#define ASSERT_TYPE_EQ(TYPE, ENUM)\
|
||||
ASSERT_TRUE(typeid(TYPE) == typeid(GeneralUtils::CastUnderlyingType(static_cast<ENUM>(0))));
|
||||
|
||||
#define ASSERT_TYPE_NE(TYPE, ENUM)\
|
||||
ASSERT_FALSE(typeid(TYPE) == typeid(GeneralUtils::CastUnderlyingType(static_cast<ENUM>(0))));
|
||||
|
||||
// Verify that the underlying enum types are being cast correctly
|
||||
TEST(CastUnderlyingTypeTests, VerifyCastUnderlyingType) {
|
||||
ASSERT_TYPE_EQ(uint8_t, eGameMasterLevel);
|
||||
ASSERT_TYPE_EQ(uint16_t, eGameMessageType);
|
||||
ASSERT_TYPE_EQ(uint32_t, eWorldMessageType)
|
||||
|
||||
ASSERT_TYPE_NE(void, eGameMasterLevel);
|
||||
ASSERT_TYPE_NE(void, eGameMessageType);
|
||||
ASSERT_TYPE_NE(void, eWorldMessageType)
|
||||
}
|
10
tests/dCommonTests/dEnumsTests/CMakeLists.txt
Normal file
10
tests/dCommonTests/dEnumsTests/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
||||
set(DENUMS_TESTS
|
||||
"MagicEnumTests.cpp"
|
||||
)
|
||||
|
||||
# Get the folder name and prepend it to the files above
|
||||
get_filename_component(thisFolderName ${CMAKE_CURRENT_SOURCE_DIR} NAME)
|
||||
list(TRANSFORM DENUMS_TESTS PREPEND "${thisFolderName}/")
|
||||
|
||||
# Export to parent scope
|
||||
set(DENUMS_TESTS ${DENUMS_TESTS} PARENT_SCOPE)
|
142
tests/dCommonTests/dEnumsTests/MagicEnumTests.cpp
Normal file
142
tests/dCommonTests/dEnumsTests/MagicEnumTests.cpp
Normal file
@ -0,0 +1,142 @@
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "StringifiedEnum.h"
|
||||
#include "Logger.h"
|
||||
#include "Game.h"
|
||||
#include "eGameMessageType.h"
|
||||
#include "eWorldMessageType.h"
|
||||
#include "magic_enum.hpp"
|
||||
|
||||
#define ENUM_EQ(e, y, z)\
|
||||
LOG("%s %s", StringifiedEnum::ToString(static_cast<e>(y)).data(), #z);\
|
||||
ASSERT_STREQ(StringifiedEnum::ToString(static_cast<e>(y)).data(), #z);
|
||||
|
||||
#define ENUM_NE(e, y)\
|
||||
ENUM_EQ(e, y, UNKNOWN);
|
||||
|
||||
// Test World Message Enum Reflection
|
||||
TEST(MagicEnumTest, eWorldMessageTypeTest) {
|
||||
Game::logger = new Logger("./MagicEnumTest_eWorldMessageTypeTest.log", true, true);
|
||||
|
||||
ENUM_EQ(eWorldMessageType, 1, VALIDATION);
|
||||
ENUM_EQ(eWorldMessageType, 2, CHARACTER_LIST_REQUEST);
|
||||
ENUM_EQ(eWorldMessageType, 3, CHARACTER_CREATE_REQUEST);
|
||||
ENUM_EQ(eWorldMessageType, 4, LOGIN_REQUEST);
|
||||
ENUM_EQ(eWorldMessageType, 5, GAME_MSG);
|
||||
ENUM_EQ(eWorldMessageType, 6, CHARACTER_DELETE_REQUEST);
|
||||
ENUM_EQ(eWorldMessageType, 7, CHARACTER_RENAME_REQUEST);
|
||||
ENUM_EQ(eWorldMessageType, 8, HAPPY_FLOWER_MODE_NOTIFY);
|
||||
ENUM_EQ(eWorldMessageType, 9, SLASH_RELOAD_MAP);
|
||||
ENUM_EQ(eWorldMessageType, 10, SLASH_PUSH_MAP_REQUEST);
|
||||
ENUM_EQ(eWorldMessageType, 11, SLASH_PUSH_MAP);
|
||||
ENUM_EQ(eWorldMessageType, 12, SLASH_PULL_MAP);
|
||||
ENUM_EQ(eWorldMessageType, 13, LOCK_MAP_REQUEST);
|
||||
ENUM_EQ(eWorldMessageType, 14, GENERAL_CHAT_MESSAGE);
|
||||
ENUM_EQ(eWorldMessageType, 15, HTTP_MONITOR_INFO_REQUEST);
|
||||
ENUM_EQ(eWorldMessageType, 16, SLASH_DEBUG_SCRIPTS);
|
||||
ENUM_EQ(eWorldMessageType, 17, MODELS_CLEAR);
|
||||
ENUM_EQ(eWorldMessageType, 18, EXHIBIT_INSERT_MODEL);
|
||||
ENUM_EQ(eWorldMessageType, 19, LEVEL_LOAD_COMPLETE);
|
||||
ENUM_EQ(eWorldMessageType, 20, TMP_GUILD_CREATE);
|
||||
ENUM_EQ(eWorldMessageType, 21, ROUTE_PACKET);
|
||||
ENUM_EQ(eWorldMessageType, 22, POSITION_UPDATE);
|
||||
ENUM_EQ(eWorldMessageType, 23, MAIL);
|
||||
ENUM_EQ(eWorldMessageType, 24, WORD_CHECK);
|
||||
ENUM_EQ(eWorldMessageType, 25, STRING_CHECK);
|
||||
ENUM_EQ(eWorldMessageType, 26, GET_PLAYERS_IN_ZONE);
|
||||
ENUM_EQ(eWorldMessageType, 27, REQUEST_UGC_MANIFEST_INFO);
|
||||
ENUM_EQ(eWorldMessageType, 28, BLUEPRINT_GET_ALL_DATA_REQUEST);
|
||||
ENUM_EQ(eWorldMessageType, 29, CANCEL_MAP_QUEUE);
|
||||
ENUM_EQ(eWorldMessageType, 30, HANDLE_FUNNESS);
|
||||
ENUM_EQ(eWorldMessageType, 31, FAKE_PRG_CSR_MESSAGE);
|
||||
ENUM_EQ(eWorldMessageType, 32, REQUEST_FREE_TRIAL_REFRESH);
|
||||
ENUM_EQ(eWorldMessageType, 33, GM_SET_FREE_TRIAL_STATUS);
|
||||
ENUM_EQ(eWorldMessageType, 91, UI_HELP_TOP_5);
|
||||
ENUM_NE(eWorldMessageType, 37);
|
||||
ENUM_NE(eWorldMessageType, 123);
|
||||
|
||||
srand(time(NULL));
|
||||
auto begin = std::chrono::high_resolution_clock::now();
|
||||
for (int i = 0; i < 10000000; ++i) {
|
||||
volatile auto f = StringifiedEnum::ToString(static_cast<eWorldMessageType>(i)).data();
|
||||
|
||||
// To ensure the compiler doesn't optimize out the call, I print it at random intervals
|
||||
if (rand() % 100000 == 0) LOG("%i, %s", i, f);
|
||||
}
|
||||
auto end = std::chrono::high_resolution_clock::now();
|
||||
LOG("Time: %lld", std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count());
|
||||
|
||||
delete Game::logger;
|
||||
}
|
||||
|
||||
// Test Game Message Enum Reflection
|
||||
TEST(MagicEnumTest, eGameMessageTypeTest) {
|
||||
|
||||
Game::logger = new Logger("./MagicEnumTest_eGameMessageTypeTest.log", true, true);
|
||||
|
||||
// Only doing the first and last 10 for the sake of my sanity
|
||||
ENUM_EQ(eGameMessageType, 0, GET_POSITION);
|
||||
ENUM_EQ(eGameMessageType, 1, GET_ROTATION);
|
||||
ENUM_EQ(eGameMessageType, 2, GET_LINEAR_VELOCITY);
|
||||
ENUM_EQ(eGameMessageType, 3, GET_ANGULAR_VELOCITY);
|
||||
ENUM_EQ(eGameMessageType, 4, GET_FORWARD_VELOCITY);
|
||||
ENUM_EQ(eGameMessageType, 5, GET_PLAYER_FORWARD);
|
||||
ENUM_EQ(eGameMessageType, 6, GET_FORWARD_VECTOR);
|
||||
ENUM_EQ(eGameMessageType, 7, SET_POSITION);
|
||||
ENUM_EQ(eGameMessageType, 8, SET_LOCAL_POSITION);
|
||||
ENUM_EQ(eGameMessageType, 9, SET_ROTATION);
|
||||
ENUM_EQ(eGameMessageType, 10, SET_LINEAR_VELOCITY);
|
||||
ENUM_EQ(eGameMessageType, 1762, USE_SKILL_SET);
|
||||
ENUM_EQ(eGameMessageType, 1763, SET_SKILL_SET_POSSESSOR);
|
||||
ENUM_EQ(eGameMessageType, 1764, POPULATE_ACTION_BAR);
|
||||
ENUM_EQ(eGameMessageType, 1765, GET_COMPONENT_TEMPLATE_ID);
|
||||
ENUM_EQ(eGameMessageType, 1766, GET_POSSESSABLE_SKILL_SET);
|
||||
ENUM_EQ(eGameMessageType, 1767, MARK_INVENTORY_ITEM_AS_ACTIVE);
|
||||
ENUM_EQ(eGameMessageType, 1768, UPDATE_FORGED_ITEM);
|
||||
ENUM_EQ(eGameMessageType, 1769, CAN_ITEMS_BE_REFORGED);
|
||||
ENUM_EQ(eGameMessageType, 1771, NOTIFY_CLIENT_RAIL_START_FAILED);
|
||||
ENUM_EQ(eGameMessageType, 1772, GET_IS_ON_RAIL);
|
||||
ENUM_NE(eGameMessageType, 32);
|
||||
ENUM_NE(eGameMessageType, 1776);
|
||||
|
||||
srand(time(NULL));
|
||||
auto begin = std::chrono::high_resolution_clock::now();
|
||||
for (int i = 0; i < 10000000; ++i) {
|
||||
volatile auto f = StringifiedEnum::ToString(static_cast<eGameMessageType>(i)).data();
|
||||
|
||||
// To ensure the compiler doesn't optimize out the call, I print it at random intervals
|
||||
if (rand() % 100000 == 0) LOG("%i, %s", i, f);
|
||||
}
|
||||
auto end = std::chrono::high_resolution_clock::now();
|
||||
LOG("Time: %lld", std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count());
|
||||
|
||||
delete Game::logger;
|
||||
}
|
||||
|
||||
#define ASSERT_EARRAY_SORTED(EARRAY_VAR)\
|
||||
for (int i = 0; i < EARRAY_VAR->size(); i++) {\
|
||||
const auto entryCurr = EARRAY_VAR->at(i).first;\
|
||||
LOG_EARRAY(EARRAY_VAR, i, entryCurr);\
|
||||
const auto entryNext = EARRAY_VAR->at(++i).first;\
|
||||
LOG_EARRAY(EARRAY_VAR, i, entryNext);\
|
||||
ASSERT_TRUE(entryCurr < entryNext);\
|
||||
};\
|
||||
|
||||
#define LOG_EARRAY(EARRAY_VAR, INDICE, ENTRY)\
|
||||
LOG(#EARRAY_VAR"[%i] = %i, %s", INDICE, ENTRY, magic_enum::enum_name(ENTRY).data());
|
||||
|
||||
// Test that the magic enum arrays are pre-sorted
|
||||
TEST(MagicEnumTest, ArraysAreSorted) {
|
||||
Game::logger = new Logger("./MagicEnumTest_ArraysAreSorted.log", true, true);
|
||||
|
||||
constexpr auto wmArray = &magic_enum::enum_entries<eWorldMessageType>();
|
||||
ASSERT_EARRAY_SORTED(wmArray);
|
||||
|
||||
constexpr auto gmArray = &magic_enum::enum_entries<eGameMessageType>();
|
||||
ASSERT_EARRAY_SORTED(gmArray);
|
||||
|
||||
delete Game::logger;
|
||||
}
|
3
thirdparty/CMakeLists.txt
vendored
3
thirdparty/CMakeLists.txt
vendored
@ -19,6 +19,9 @@ add_library(bcrypt ${SOURCES_LIBBCRYPT})
|
||||
# Source code for sqlite
|
||||
add_subdirectory(SQLite)
|
||||
|
||||
# Source code for magic_enum
|
||||
add_subdirectory(magic_enum)
|
||||
|
||||
# MariaDB C++ Connector
|
||||
include(CMakeMariaDBLists.txt)
|
||||
|
||||
|
1
thirdparty/magic_enum
vendored
Submodule
1
thirdparty/magic_enum
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit e55b9b54d5cf61f8e117cafb17846d7d742dd3b4
|
Loading…
Reference in New Issue
Block a user