mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2024-11-09 17:58:20 +00:00
chore: Speed up and cleanup level and zone loading; Add safer asset buffer reading (#1314)
* Remove std::couts littered throughout the base * working End of optimizations for now going faster * Remove extraneous compare function std::less<LWOSCENEID> already does this in a map. * gaming * Update Zone.cpp * dlu is moving to bitbucket again * Update Level.cpp --------- Co-authored-by: Jettford <mrjettbradford@gmail.com>
This commit is contained in:
parent
fcf4d6c6fa
commit
e58218cfbc
@ -1,14 +1,6 @@
|
|||||||
#include "BinaryIO.h"
|
#include "BinaryIO.h"
|
||||||
#include <string>
|
#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
|
//For reading null-terminated strings
|
||||||
std::string BinaryIO::ReadString(std::istream& instream) {
|
std::string BinaryIO::ReadString(std::istream& instream) {
|
||||||
std::string toReturn;
|
std::string toReturn;
|
||||||
@ -23,36 +15,3 @@ std::string BinaryIO::ReadString(std::istream& instream) {
|
|||||||
|
|
||||||
return toReturn;
|
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
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef __BINARYIO__H__
|
||||||
|
#define __BINARYIO__H__
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "Game.h"
|
||||||
|
#include "Logger.h"
|
||||||
|
|
||||||
namespace BinaryIO {
|
namespace BinaryIO {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
std::ostream& BinaryWrite(std::ostream& stream, const T& value) {
|
std::ostream& BinaryWrite(std::ostream& stream, const T& value) {
|
||||||
return stream.write(reinterpret_cast<const char*>(&value), sizeof(T));
|
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));
|
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);
|
||||||
std::string ReadString(std::istream& instream, size_t size);
|
|
||||||
std::string ReadWString(std::istream& instream);
|
|
||||||
|
|
||||||
inline bool DoesFileExist(const std::string& name) {
|
inline bool DoesFileExist(const std::string& name) {
|
||||||
std::ifstream f(name.c_str());
|
std::ifstream f(name.c_str());
|
||||||
return f.good();
|
return f.good();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif //!__BINARYIO__H__
|
||||||
|
@ -28,19 +28,17 @@ FdbToSqlite::Convert::Convert(std::string binaryOutPath) {
|
|||||||
this->m_BinaryOutPath = binaryOutPath;
|
this->m_BinaryOutPath = binaryOutPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FdbToSqlite::Convert::ConvertDatabase(AssetMemoryBuffer& buffer) {
|
bool FdbToSqlite::Convert::ConvertDatabase(AssetStream& buffer) {
|
||||||
if (m_ConversionStarted) return false;
|
if (m_ConversionStarted) return false;
|
||||||
|
|
||||||
std::istream cdClientBuffer(&buffer);
|
|
||||||
|
|
||||||
this->m_ConversionStarted = true;
|
this->m_ConversionStarted = true;
|
||||||
try {
|
try {
|
||||||
CDClientDatabase::Connect(m_BinaryOutPath + "/CDServer.sqlite");
|
CDClientDatabase::Connect(m_BinaryOutPath + "/CDServer.sqlite");
|
||||||
|
|
||||||
CDClientDatabase::ExecuteQuery("BEGIN TRANSACTION;");
|
CDClientDatabase::ExecuteQuery("BEGIN TRANSACTION;");
|
||||||
|
|
||||||
int32_t numberOfTables = ReadInt32(cdClientBuffer);
|
int32_t numberOfTables = ReadInt32(buffer);
|
||||||
ReadTables(numberOfTables, cdClientBuffer);
|
ReadTables(numberOfTables, buffer);
|
||||||
|
|
||||||
CDClientDatabase::ExecuteQuery("COMMIT;");
|
CDClientDatabase::ExecuteQuery("COMMIT;");
|
||||||
} catch (CppSQLite3Exception& e) {
|
} catch (CppSQLite3Exception& e) {
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
class AssetMemoryBuffer;
|
#include "AssetManager.h"
|
||||||
|
|
||||||
enum class eSqliteDataType : int32_t;
|
enum class eSqliteDataType : int32_t;
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ namespace FdbToSqlite {
|
|||||||
*
|
*
|
||||||
* @return true if the database was converted properly, false otherwise.
|
* @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.
|
* @brief Reads a 32 bit int from the fdb file.
|
||||||
|
@ -152,13 +152,12 @@ bool AssetManager::GetFile(const char* name, char** data, uint32_t* len) {
|
|||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
AssetMemoryBuffer AssetManager::GetFileAsBuffer(const char* name) {
|
AssetStream AssetManager::GetFile(const char* name) {
|
||||||
char* buf;
|
char* buf; uint32_t len;
|
||||||
uint32_t len;
|
|
||||||
|
|
||||||
bool success = this->GetFile(name, &buf, &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) {
|
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);
|
this->setg(base, base, base + n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~AssetMemoryBuffer() {
|
||||||
|
free(m_Base);
|
||||||
|
}
|
||||||
|
|
||||||
pos_type seekpos(pos_type sp, std::ios_base::openmode which) override {
|
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);
|
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());
|
setg(eback(), eback() + off, egptr());
|
||||||
return gptr() - eback();
|
return gptr() - eback();
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
void close() {
|
struct AssetStream : std::istream {
|
||||||
free(m_Base);
|
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 HasFile(const char* name);
|
||||||
bool GetFile(const char* name, char** data, uint32_t* len);
|
bool GetFile(const char* name, char** data, uint32_t* len);
|
||||||
AssetMemoryBuffer GetFileAsBuffer(const char* name);
|
AssetStream GetFile(const char* name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void LoadPackIndex();
|
void LoadPackIndex();
|
||||||
|
@ -9,20 +9,9 @@ PackIndex::PackIndex(const std::filesystem::path& filePath) {
|
|||||||
BinaryIO::BinaryRead<uint32_t>(m_FileStream, m_Version);
|
BinaryIO::BinaryRead<uint32_t>(m_FileStream, m_Version);
|
||||||
BinaryIO::BinaryRead<uint32_t>(m_FileStream, m_PackPathCount);
|
BinaryIO::BinaryRead<uint32_t>(m_FileStream, m_PackPathCount);
|
||||||
|
|
||||||
for (int i = 0; i < m_PackPathCount; i++) {
|
m_PackPaths.resize(m_PackPathCount);
|
||||||
uint32_t stringLen = 0;
|
for (auto& item : m_PackPaths) {
|
||||||
BinaryIO::BinaryRead<uint32_t>(m_FileStream, stringLen);
|
BinaryIO::ReadString<uint32_t>(m_FileStream, item, BinaryIO::ReadType::String);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BinaryIO::BinaryRead<uint32_t>(m_FileStream, m_PackFileIndexCount);
|
BinaryIO::BinaryRead<uint32_t>(m_FileStream, m_PackFileIndexCount);
|
||||||
|
@ -44,57 +44,53 @@ inline void StripCR(std::string& str) {
|
|||||||
void UserManager::Initialize() {
|
void UserManager::Initialize() {
|
||||||
std::string line;
|
std::string line;
|
||||||
|
|
||||||
AssetMemoryBuffer fnBuff = Game::assetManager->GetFileAsBuffer("names/minifigname_first.txt");
|
auto fnStream = Game::assetManager->GetFile("names/minifigname_first.txt");
|
||||||
if (!fnBuff.m_Success) {
|
if (!fnStream) {
|
||||||
LOG("Failed to load %s", (Game::assetManager->GetResPath() / "names/minifigname_first.txt").string().c_str());
|
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.");
|
throw std::runtime_error("Aborting initialization due to missing minifigure name file.");
|
||||||
}
|
}
|
||||||
std::istream fnStream = std::istream(&fnBuff);
|
|
||||||
while (std::getline(fnStream, line, '\n')) {
|
while (std::getline(fnStream, line, '\n')) {
|
||||||
std::string name = line;
|
std::string name = line;
|
||||||
StripCR(name);
|
StripCR(name);
|
||||||
m_FirstNames.push_back(name);
|
m_FirstNames.push_back(name);
|
||||||
}
|
}
|
||||||
fnBuff.close();
|
|
||||||
|
|
||||||
AssetMemoryBuffer mnBuff = Game::assetManager->GetFileAsBuffer("names/minifigname_middle.txt");
|
auto mnStream = Game::assetManager->GetFile("names/minifigname_middle.txt");
|
||||||
if (!mnBuff.m_Success) {
|
if (!mnStream) {
|
||||||
LOG("Failed to load %s", (Game::assetManager->GetResPath() / "names/minifigname_middle.txt").string().c_str());
|
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.");
|
throw std::runtime_error("Aborting initialization due to missing minifigure name file.");
|
||||||
}
|
}
|
||||||
std::istream mnStream = std::istream(&mnBuff);
|
|
||||||
while (std::getline(mnStream, line, '\n')) {
|
while (std::getline(mnStream, line, '\n')) {
|
||||||
std::string name = line;
|
std::string name = line;
|
||||||
StripCR(name);
|
StripCR(name);
|
||||||
m_MiddleNames.push_back(name);
|
m_MiddleNames.push_back(name);
|
||||||
}
|
}
|
||||||
mnBuff.close();
|
|
||||||
|
|
||||||
AssetMemoryBuffer lnBuff = Game::assetManager->GetFileAsBuffer("names/minifigname_last.txt");
|
auto lnStream = Game::assetManager->GetFile("names/minifigname_last.txt");
|
||||||
if (!lnBuff.m_Success) {
|
if (!lnStream) {
|
||||||
LOG("Failed to load %s", (Game::assetManager->GetResPath() / "names/minifigname_last.txt").string().c_str());
|
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.");
|
throw std::runtime_error("Aborting initialization due to missing minifigure name file.");
|
||||||
}
|
}
|
||||||
std::istream lnStream = std::istream(&lnBuff);
|
|
||||||
while (std::getline(lnStream, line, '\n')) {
|
while (std::getline(lnStream, line, '\n')) {
|
||||||
std::string name = line;
|
std::string name = line;
|
||||||
StripCR(name);
|
StripCR(name);
|
||||||
m_LastNames.push_back(name);
|
m_LastNames.push_back(name);
|
||||||
}
|
}
|
||||||
lnBuff.close();
|
|
||||||
|
|
||||||
//Load our pre-approved names:
|
// Load our pre-approved names:
|
||||||
AssetMemoryBuffer chatListBuff = Game::assetManager->GetFileAsBuffer("chatplus_en_us.txt");
|
auto chatListStream = Game::assetManager->GetFile("chatplus_en_us.txt");
|
||||||
if (!chatListBuff.m_Success) {
|
if (!chatListStream) {
|
||||||
LOG("Failed to load %s", (Game::assetManager->GetResPath() / "chatplus_en_us.txt").string().c_str());
|
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.");
|
throw std::runtime_error("Aborting initialization due to missing chat whitelist file.");
|
||||||
}
|
}
|
||||||
std::istream chatListStream = std::istream(&chatListBuff);
|
|
||||||
while (std::getline(chatListStream, line, '\n')) {
|
while (std::getline(chatListStream, line, '\n')) {
|
||||||
StripCR(line);
|
StripCR(line);
|
||||||
m_PreapprovedNames.push_back(line);
|
m_PreapprovedNames.push_back(line);
|
||||||
}
|
}
|
||||||
chatListBuff.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UserManager::~UserManager() {
|
UserManager::~UserManager() {
|
||||||
|
@ -423,25 +423,16 @@ void Item::DisassembleModel(uint32_t numToDismantle) {
|
|||||||
if (renderAssetSplit.empty()) return;
|
if (renderAssetSplit.empty()) return;
|
||||||
|
|
||||||
std::string lxfmlPath = "BrickModels" + lxfmlFolderName + "/" + GeneralUtils::SplitString(renderAssetSplit.back(), '.').at(0) + ".lxfml";
|
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());
|
LOG("Failed to load %s to disassemble model into bricks, check that this file exists", lxfmlPath.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::istream file(&buffer);
|
|
||||||
|
|
||||||
if (!file.good()) {
|
|
||||||
buffer.close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::stringstream data;
|
std::stringstream data;
|
||||||
data << file.rdbuf();
|
data << file.rdbuf();
|
||||||
|
|
||||||
buffer.close();
|
|
||||||
|
|
||||||
uint32_t fileSize;
|
uint32_t fileSize;
|
||||||
file.seekg(0, std::ios::end);
|
file.seekg(0, std::ios::end);
|
||||||
fileSize = static_cast<uint32_t>(file.tellg());
|
fileSize = static_cast<uint32_t>(file.tellg());
|
||||||
|
@ -324,14 +324,9 @@ void ControlBehaviors::ProcessCommand(Entity* modelEntity, const SystemAddress&
|
|||||||
}
|
}
|
||||||
|
|
||||||
ControlBehaviors::ControlBehaviors() {
|
ControlBehaviors::ControlBehaviors() {
|
||||||
auto blocksDefStreamBuffer = Game::assetManager->GetFileAsBuffer("ui\\ingame\\blocksdef.xml");
|
auto blocksBuffer = Game::assetManager->GetFile("ui\\ingame\\blocksdef.xml");
|
||||||
if (!blocksDefStreamBuffer.m_Success) {
|
if (!blocksBuffer) {
|
||||||
LOG("failed to open blocksdef");
|
LOG("Failed to open blocksdef.xml");
|
||||||
return;
|
|
||||||
}
|
|
||||||
std::istream blocksBuffer(&blocksDefStreamBuffer);
|
|
||||||
if (!blocksBuffer.good()) {
|
|
||||||
LOG("Blocks buffer is not good!");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,26 +17,18 @@ const BrickList& BrickDatabase::GetBricks(const LxfmlPath& lxfmlPath) {
|
|||||||
return cached->second;
|
return cached->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
AssetMemoryBuffer buffer = Game::assetManager->GetFileAsBuffer((lxfmlPath).c_str());
|
auto file = Game::assetManager->GetFile((lxfmlPath).c_str());
|
||||||
|
|
||||||
if (!buffer.m_Success) {
|
if (!file) {
|
||||||
return emptyCache;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::istream file(&buffer);
|
|
||||||
if (!file.good()) {
|
|
||||||
return emptyCache;
|
return emptyCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::stringstream data;
|
std::stringstream data;
|
||||||
data << file.rdbuf();
|
data << file.rdbuf();
|
||||||
if (data.str().empty()) {
|
if (data.str().empty()) {
|
||||||
buffer.close();
|
|
||||||
return emptyCache;
|
return emptyCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer.close();
|
|
||||||
|
|
||||||
auto* doc = new tinyxml2::XMLDocument();
|
auto* doc = new tinyxml2::XMLDocument();
|
||||||
if (doc->Parse(data.str().c_str(), data.str().size()) != 0) {
|
if (doc->Parse(data.str().c_str(), data.str().size()) != 0) {
|
||||||
delete doc;
|
delete doc;
|
||||||
|
@ -621,15 +621,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;
|
||||||
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?");
|
ChatPackets::SendSystemMessage(sysAddr, u"Unknown macro! Is the filename right?");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::istream infile(&buf);
|
|
||||||
|
|
||||||
if (infile.good()) {
|
if (infile.good()) {
|
||||||
std::string line;
|
std::string line;
|
||||||
while (std::getline(infile, line)) {
|
while (std::getline(infile, line)) {
|
||||||
@ -639,8 +637,6 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
|
|||||||
ChatPackets::SendSystemMessage(sysAddr, u"Unknown macro! Is the filename right?");
|
ChatPackets::SendSystemMessage(sysAddr, u"Unknown macro! Is the filename right?");
|
||||||
}
|
}
|
||||||
|
|
||||||
buf.close();
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,8 +169,8 @@ int main(int argc, char** argv) {
|
|||||||
(BinaryPathFinder::GetBinaryDir() / "resServer" / "CDServer.sqlite").c_str(),
|
(BinaryPathFinder::GetBinaryDir() / "resServer" / "CDServer.sqlite").c_str(),
|
||||||
(Game::assetManager->GetResPath() / "cdclient.fdb").c_str());
|
(Game::assetManager->GetResPath() / "cdclient.fdb").c_str());
|
||||||
|
|
||||||
AssetMemoryBuffer cdClientBuffer = Game::assetManager->GetFileAsBuffer("cdclient.fdb");
|
auto cdclientStream = Game::assetManager->GetFile("cdclient.fdb");
|
||||||
if (!cdClientBuffer.m_Success) {
|
if (!cdclientStream) {
|
||||||
LOG("Failed to load %s", (Game::assetManager->GetResPath() / "cdclient.fdb").c_str());
|
LOG("Failed to load %s", (Game::assetManager->GetResPath() / "cdclient.fdb").c_str());
|
||||||
throw std::runtime_error("Aborting initialization due to missing cdclient.fdb.");
|
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());
|
LOG("Found %s. Converting to SQLite", (Game::assetManager->GetResPath() / "cdclient.fdb").c_str());
|
||||||
Game::logger->Flush();
|
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.");
|
LOG("Failed to convert fdb to sqlite.");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
cdClientBuffer.close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,36 +16,20 @@
|
|||||||
#include "AssetManager.h"
|
#include "AssetManager.h"
|
||||||
#include "dConfig.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) {
|
Level::Level(Zone* parentZone, const std::string& filepath) {
|
||||||
m_ParentZone = parentZone;
|
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());
|
LOG("Failed to load %s", filepath.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::istream file(&buffer);
|
ReadChunks(stream);
|
||||||
ReadChunks(file);
|
|
||||||
|
|
||||||
buffer.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Level::~Level() {
|
void Level::MakeSpawner(SceneObject obj) {
|
||||||
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){
|
|
||||||
SpawnerInfo spawnInfo = SpawnerInfo();
|
SpawnerInfo spawnInfo = SpawnerInfo();
|
||||||
SpawnerNode* node = new SpawnerNode();
|
SpawnerNode* node = new SpawnerNode();
|
||||||
spawnInfo.templateID = obj.lot;
|
spawnInfo.templateID = obj.lot;
|
||||||
@ -56,7 +40,7 @@ void Level::MakeSpawner(SceneObject obj){
|
|||||||
node->config = obj.settings;
|
node->config = obj.settings;
|
||||||
spawnInfo.nodes.push_back(node);
|
spawnInfo.nodes.push_back(node);
|
||||||
for (LDFBaseData* data : obj.settings) {
|
for (LDFBaseData* data : obj.settings) {
|
||||||
if (data) {
|
if (!data) continue;
|
||||||
if (data->GetKey() == u"spawntemplate") {
|
if (data->GetKey() == u"spawntemplate") {
|
||||||
spawnInfo.templateID = std::stoi(data->GetValueAsString());
|
spawnInfo.templateID = std::stoi(data->GetValueAsString());
|
||||||
}
|
}
|
||||||
@ -111,16 +95,8 @@ void Level::MakeSpawner(SceneObject obj){
|
|||||||
spawnInfo.spawnActivator = static_cast<LDFData<bool>*>(data)->GetValue();
|
spawnInfo.spawnActivator = static_cast<LDFData<bool>*>(data)->GetValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
Game::zoneManager->MakeSpawner(spawnInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
const void Level::PrintAllObjects() {
|
Game::zoneManager->MakeSpawner(spawnInfo);
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Level::ReadChunks(std::istream& file) {
|
void Level::ReadChunks(std::istream& file) {
|
||||||
@ -155,11 +131,10 @@ void Level::ReadChunks(std::istream& file) {
|
|||||||
file.seekg(0);
|
file.seekg(0);
|
||||||
Header header;
|
Header header;
|
||||||
header.id = ChunkTypeID::FileInfo; //I guess?
|
header.id = ChunkTypeID::FileInfo; //I guess?
|
||||||
FileInfoChunk* fileInfo = new FileInfoChunk();
|
|
||||||
BinaryIO::BinaryRead(file, header.chunkVersion);
|
BinaryIO::BinaryRead(file, header.chunkVersion);
|
||||||
BinaryIO::BinaryRead(file, header.chunkType);
|
BinaryIO::BinaryRead(file, header.chunkType);
|
||||||
file.ignore(1);
|
file.ignore(1);
|
||||||
BinaryIO::BinaryRead(file, fileInfo->revision);
|
BinaryIO::BinaryRead(file, header.fileInfo.revision);
|
||||||
|
|
||||||
if (header.chunkVersion >= 45) file.ignore(4);
|
if (header.chunkVersion >= 45) file.ignore(4);
|
||||||
file.ignore(4 * (4 * 3));
|
file.ignore(4 * (4 * 3));
|
||||||
@ -172,9 +147,7 @@ void Level::ReadChunks(std::istream& file) {
|
|||||||
uint32_t s = 0;
|
uint32_t s = 0;
|
||||||
BinaryIO::BinaryRead(file, s);
|
BinaryIO::BinaryRead(file, s);
|
||||||
for (uint32_t i = 0; i < s; ++i) {
|
for (uint32_t i = 0; i < s; ++i) {
|
||||||
file.ignore(4); //a uint
|
file.ignore(4 * 3); //a uint and two floats
|
||||||
file.ignore(4); //two floats
|
|
||||||
file.ignore(4);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -208,7 +181,6 @@ void Level::ReadChunks(std::istream& file) {
|
|||||||
BinaryIO::BinaryRead(file, count);
|
BinaryIO::BinaryRead(file, count);
|
||||||
file.ignore(count * 12);
|
file.ignore(count * 12);
|
||||||
|
|
||||||
header.fileInfo = fileInfo;
|
|
||||||
m_ChunkHeaders.insert(std::make_pair(header.id, header));
|
m_ChunkHeaders.insert(std::make_pair(header.id, header));
|
||||||
|
|
||||||
//Now pretend to be a normal file and read Objects chunk:
|
//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) {
|
void Level::ReadFileInfoChunk(std::istream& file, Header& header) {
|
||||||
FileInfoChunk* fi = new FileInfoChunk;
|
BinaryIO::BinaryRead(file, header.fileInfo.version);
|
||||||
BinaryIO::BinaryRead(file, fi->version);
|
BinaryIO::BinaryRead(file, header.fileInfo.revision);
|
||||||
BinaryIO::BinaryRead(file, fi->revision);
|
BinaryIO::BinaryRead(file, header.fileInfo.enviromentChunkStart);
|
||||||
BinaryIO::BinaryRead(file, fi->enviromentChunkStart);
|
BinaryIO::BinaryRead(file, header.fileInfo.objectChunkStart);
|
||||||
BinaryIO::BinaryRead(file, fi->objectChunkStart);
|
BinaryIO::BinaryRead(file, header.fileInfo.particleChunkStart);
|
||||||
BinaryIO::BinaryRead(file, fi->particleChunkStart);
|
|
||||||
header.fileInfo = fi;
|
|
||||||
|
|
||||||
//PATCH FOR AG: (messed up file?)
|
//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) {
|
void Level::ReadSceneObjectDataChunk(std::istream& file, Header& header) {
|
||||||
SceneObjectDataChunk* chunk = new SceneObjectDataChunk;
|
|
||||||
uint32_t objectsCount = 0;
|
uint32_t objectsCount = 0;
|
||||||
BinaryIO::BinaryRead(file, objectsCount);
|
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_current"), gating.current);
|
||||||
GeneralUtils::TryParse<int32_t>(Game::config->GetValue("version_minor"), gating.minor);
|
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) {
|
for (uint32_t i = 0; i < objectsCount; ++i) {
|
||||||
|
std::u16string ldfString;
|
||||||
SceneObject obj;
|
SceneObject obj;
|
||||||
BinaryIO::BinaryRead(file, obj.id);
|
BinaryIO::BinaryRead(file, obj.id);
|
||||||
BinaryIO::BinaryRead(file, obj.lot);
|
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.position);
|
||||||
BinaryIO::BinaryRead(file, obj.rotation);
|
BinaryIO::BinaryRead(file, obj.rotation);
|
||||||
BinaryIO::BinaryRead(file, obj.scale);
|
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
|
//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.
|
//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);
|
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::string sData = GeneralUtils::UTF16ToWTF8(ldfString);
|
||||||
std::stringstream ssData(sData);
|
std::stringstream ssData(sData);
|
||||||
std::string token;
|
std::string token;
|
||||||
@ -288,35 +252,40 @@ void Level::ReadSceneObjectDataChunk(std::istream& file, Header& header) {
|
|||||||
obj.settings.push_back(ldfData);
|
obj.settings.push_back(ldfData);
|
||||||
}
|
}
|
||||||
|
|
||||||
BinaryIO::BinaryRead(file, obj.value3);
|
|
||||||
|
|
||||||
// Feature gating
|
// We should never have more than 1 zone control object
|
||||||
bool gated = false;
|
bool skipLoadingObject = obj.lot == zoneControlObject->GetLOT();
|
||||||
for (LDFBaseData* data : obj.settings) {
|
for (LDFBaseData* data : obj.settings) {
|
||||||
|
if (!data) continue;
|
||||||
if (data->GetKey() == u"gatingOnFeature") {
|
if (data->GetKey() == u"gatingOnFeature") {
|
||||||
gating.featureName = data->GetValueAsString();
|
gating.featureName = data->GetValueAsString();
|
||||||
if (gating.featureName == Game::config->GetValue("event_1")) break;
|
if (gating.featureName == Game::config->GetValue("event_1")) continue;
|
||||||
else if (gating.featureName == Game::config->GetValue("event_2")) break;
|
else if (gating.featureName == Game::config->GetValue("event_2")) continue;
|
||||||
else if (gating.featureName == Game::config->GetValue("event_3")) break;
|
else if (gating.featureName == Game::config->GetValue("event_3")) continue;
|
||||||
else if (gating.featureName == Game::config->GetValue("event_4")) break;
|
else if (gating.featureName == Game::config->GetValue("event_4")) continue;
|
||||||
else if (gating.featureName == Game::config->GetValue("event_5")) break;
|
else if (gating.featureName == Game::config->GetValue("event_5")) continue;
|
||||||
else if (gating.featureName == Game::config->GetValue("event_6")) break;
|
else if (gating.featureName == Game::config->GetValue("event_6")) continue;
|
||||||
else if (gating.featureName == Game::config->GetValue("event_7")) break;
|
else if (gating.featureName == Game::config->GetValue("event_7")) continue;
|
||||||
else if (gating.featureName == Game::config->GetValue("event_8")) break;
|
else if (gating.featureName == Game::config->GetValue("event_8")) continue;
|
||||||
else if (!featureGatingTable->FeatureUnlocked(gating)) {
|
else if (!featureGatingTable->FeatureUnlocked(gating)) {
|
||||||
gated = true;
|
// The feature is not unlocked, so we can skip loading this object
|
||||||
|
skipLoadingObject = true;
|
||||||
break;
|
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) {
|
for (auto* setting : obj.settings) {
|
||||||
delete setting;
|
delete setting;
|
||||||
|
setting = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
obj.settings.clear();
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -331,45 +300,7 @@ void Level::ReadSceneObjectDataChunk(std::istream& file, Header& header) {
|
|||||||
info.rot = obj.rotation;
|
info.rot = obj.rotation;
|
||||||
info.settings = obj.settings;
|
info.settings = obj.settings;
|
||||||
info.scale = obj.scale;
|
info.scale = obj.scale;
|
||||||
|
Game::entityManager->CreateEntity(info);
|
||||||
//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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
header.sceneObjects = chunk;
|
|
||||||
}
|
}
|
||||||
|
@ -27,33 +27,21 @@ public:
|
|||||||
uint32_t particleChunkStart;
|
uint32_t particleChunkStart;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SceneObjectDataChunk {
|
|
||||||
std::map<LWOOBJID, SceneObject> objects;
|
|
||||||
|
|
||||||
void PrintAllObjects() const;
|
|
||||||
|
|
||||||
uint32_t GetObjectCount() { return objects.size(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Header {
|
struct Header {
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
uint16_t chunkVersion;
|
uint16_t chunkVersion;
|
||||||
ChunkTypeID chunkType;
|
ChunkTypeID chunkType;
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
uint32_t startPosition;
|
uint32_t startPosition;
|
||||||
FileInfoChunk* fileInfo;
|
FileInfoChunk fileInfo;
|
||||||
SceneObjectDataChunk* sceneObjects;
|
|
||||||
LWOSCENEID lwoSceneID;
|
LWOSCENEID lwoSceneID;
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Level(Zone* parentZone, const std::string& filepath);
|
Level(Zone* parentZone, const std::string& filepath);
|
||||||
~Level();
|
|
||||||
|
|
||||||
static void MakeSpawner(SceneObject obj);
|
static void MakeSpawner(SceneObject obj);
|
||||||
|
|
||||||
const void PrintAllObjects();
|
|
||||||
|
|
||||||
std::map<uint32_t, Header> m_ChunkHeaders;
|
std::map<uint32_t, Header> m_ChunkHeaders;
|
||||||
private:
|
private:
|
||||||
Zone* m_ParentZone;
|
Zone* m_ParentZone;
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
|
|
||||||
Zone::Zone(const LWOMAPID& mapID, const LWOINSTANCEID& instanceID, const LWOCLONEID& cloneID) :
|
Zone::Zone(const LWOMAPID& mapID, const LWOINSTANCEID& instanceID, const LWOCLONEID& cloneID) :
|
||||||
m_ZoneID(mapID, instanceID, cloneID) {
|
m_ZoneID(mapID, instanceID, cloneID) {
|
||||||
m_NumberOfScenesLoaded = 0;
|
|
||||||
m_NumberOfObjectsLoaded = 0;
|
m_NumberOfObjectsLoaded = 0;
|
||||||
m_NumberOfSceneTransitionsLoaded = 0;
|
m_NumberOfSceneTransitionsLoaded = 0;
|
||||||
m_CheckSum = 0;
|
m_CheckSum = 0;
|
||||||
@ -46,14 +45,13 @@ void Zone::LoadZoneIntoMemory() {
|
|||||||
m_ZonePath = m_ZoneFilePath.substr(0, m_ZoneFilePath.rfind('/') + 1);
|
m_ZonePath = m_ZoneFilePath.substr(0, m_ZoneFilePath.rfind('/') + 1);
|
||||||
if (m_ZoneFilePath == "ERR") return;
|
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());
|
LOG("Failed to load %s", m_ZoneFilePath.c_str());
|
||||||
throw std::runtime_error("Aborting Zone loading due to no Zone File.");
|
throw std::runtime_error("Aborting Zone loading due to no Zone File.");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::istream file(&buffer);
|
|
||||||
if (file) {
|
if (file) {
|
||||||
BinaryIO::BinaryRead(file, m_FileFormatVersion);
|
BinaryIO::BinaryRead(file, m_FileFormatVersion);
|
||||||
|
|
||||||
@ -81,18 +79,10 @@ void Zone::LoadZoneIntoMemory() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Read generic zone info:
|
//Read generic zone info:
|
||||||
uint8_t stringLength;
|
BinaryIO::ReadString<uint8_t>(file, m_ZonePath, BinaryIO::ReadType::String);
|
||||||
BinaryIO::BinaryRead(file, stringLength);
|
BinaryIO::ReadString<uint8_t>(file, m_ZoneRawPath, BinaryIO::ReadType::String);
|
||||||
m_ZonePath = BinaryIO::ReadString(file, stringLength);
|
BinaryIO::ReadString<uint8_t>(file, m_ZoneName, BinaryIO::ReadType::String);
|
||||||
|
BinaryIO::ReadString<uint8_t>(file, m_ZoneDesc, BinaryIO::ReadType::String);
|
||||||
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);
|
|
||||||
|
|
||||||
if (m_FileFormatVersion >= Zone::FileFormatVersion::PreAlpha) {
|
if (m_FileFormatVersion >= Zone::FileFormatVersion::PreAlpha) {
|
||||||
BinaryIO::BinaryRead(file, m_NumberOfSceneTransitionsLoaded);
|
BinaryIO::BinaryRead(file, m_NumberOfSceneTransitionsLoaded);
|
||||||
@ -108,59 +98,57 @@ void Zone::LoadZoneIntoMemory() {
|
|||||||
uint32_t pathCount;
|
uint32_t pathCount;
|
||||||
BinaryIO::BinaryRead(file, pathCount);
|
BinaryIO::BinaryRead(file, pathCount);
|
||||||
|
|
||||||
|
m_Paths.reserve(pathCount);
|
||||||
for (uint32_t i = 0; i < pathCount; ++i) LoadPath(file);
|
for (uint32_t i = 0; i < pathCount; ++i) LoadPath(file);
|
||||||
|
|
||||||
for (Path path : m_Paths) {
|
for (Path path : m_Paths) {
|
||||||
if (path.pathType == PathType::Spawner) {
|
if (path.pathType != PathType::Spawner) continue;
|
||||||
SpawnerInfo info = SpawnerInfo();
|
SpawnerInfo info = SpawnerInfo();
|
||||||
for (PathWaypoint waypoint : path.pathWaypoints) {
|
for (PathWaypoint waypoint : path.pathWaypoints) {
|
||||||
SpawnerNode* node = new SpawnerNode();
|
SpawnerNode* node = new SpawnerNode();
|
||||||
node->position = waypoint.position;
|
node->position = waypoint.position;
|
||||||
node->rotation = waypoint.rotation;
|
node->rotation = waypoint.rotation;
|
||||||
node->nodeID = 0;
|
node->nodeID = 0;
|
||||||
node->config = waypoint.config;
|
node->config = waypoint.config;
|
||||||
|
|
||||||
for (LDFBaseData* data : waypoint.config) {
|
for (LDFBaseData* data : waypoint.config) {
|
||||||
if (data) {
|
if (!data) continue;
|
||||||
if (data->GetKey() == u"spawner_node_id") {
|
|
||||||
node->nodeID = std::stoi(data->GetValueAsString());
|
if (data->GetKey() == u"spawner_node_id") {
|
||||||
} else if (data->GetKey() == u"spawner_max_per_node") {
|
node->nodeID = std::stoi(data->GetValueAsString());
|
||||||
node->nodeMax = std::stoi(data->GetValueAsString());
|
} else if (data->GetKey() == u"spawner_max_per_node") {
|
||||||
} else if (data->GetKey() == u"groupID") { // Load object group
|
node->nodeMax = std::stoi(data->GetValueAsString());
|
||||||
std::string groupStr = data->GetValueAsString();
|
} else if (data->GetKey() == u"groupID") { // Load object group
|
||||||
info.groups = GeneralUtils::SplitString(groupStr, ';');
|
std::string groupStr = data->GetValueAsString();
|
||||||
info.groups.erase(info.groups.end() - 1);
|
info.groups = GeneralUtils::SplitString(groupStr, ';');
|
||||||
} else if (data->GetKey() == u"grpNameQBShowBricks") {
|
info.groups.erase(info.groups.end() - 1);
|
||||||
if (data->GetValueAsString() == "") continue;
|
} else if (data->GetKey() == u"grpNameQBShowBricks") {
|
||||||
/*std::string groupStr = data->GetValueAsString();
|
if (data->GetValueAsString() == "") continue;
|
||||||
info.groups.push_back(groupStr);*/
|
/*std::string groupStr = data->GetValueAsString();
|
||||||
info.grpNameQBShowBricks = data->GetValueAsString();
|
info.groups.push_back(groupStr);*/
|
||||||
} else if (data->GetKey() == u"spawner_name") {
|
info.grpNameQBShowBricks = data->GetValueAsString();
|
||||||
info.name = data->GetValueAsString();
|
} else if (data->GetKey() == u"spawner_name") {
|
||||||
}
|
info.name = data->GetValueAsString();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
info.nodes.push_back(node);
|
|
||||||
}
|
}
|
||||||
info.templateID = path.spawner.spawnedLOT;
|
info.nodes.push_back(node);
|
||||||
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.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 {
|
} else {
|
||||||
LOG("Failed to open: %s", m_ZoneFilePath.c_str());
|
LOG("Failed to open: %s", m_ZoneFilePath.c_str());
|
||||||
}
|
}
|
||||||
m_ZonePath = m_ZoneFilePath.substr(0, m_ZoneFilePath.rfind('/') + 1);
|
|
||||||
|
|
||||||
buffer.close();
|
m_ZonePath = m_ZoneFilePath.substr(0, m_ZoneFilePath.rfind('/') + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Zone::GetFilePathForZoneID() {
|
std::string Zone::GetFilePathForZoneID() {
|
||||||
@ -180,16 +168,16 @@ std::string Zone::GetFilePathForZoneID() {
|
|||||||
uint32_t Zone::CalculateChecksum() {
|
uint32_t Zone::CalculateChecksum() {
|
||||||
uint32_t sum1 = 0xffff, sum2 = 0xffff;
|
uint32_t sum1 = 0xffff, sum2 = 0xffff;
|
||||||
|
|
||||||
for (std::map<LWOSCENEID, uint32_t>::const_iterator it = m_MapRevisions.cbegin(); it != m_MapRevisions.cend(); ++it) {
|
for (const auto& [scene, sceneRevision] : m_MapRevisions) {
|
||||||
uint32_t sceneID = it->first.GetSceneID();
|
uint32_t sceneID = scene.GetSceneID();
|
||||||
sum2 += sum1 += (sceneID >> 16);
|
sum2 += sum1 += (sceneID >> 16);
|
||||||
sum2 += sum1 += (sceneID & 0xffff);
|
sum2 += sum1 += (sceneID & 0xffff);
|
||||||
|
|
||||||
uint32_t layerID = it->first.GetLayerID();
|
uint32_t layerID = scene.GetLayerID();
|
||||||
sum2 += sum1 += (layerID >> 16);
|
sum2 += sum1 += (layerID >> 16);
|
||||||
sum2 += sum1 += (layerID & 0xffff);
|
sum2 += sum1 += (layerID & 0xffff);
|
||||||
|
|
||||||
uint32_t revision = it->second;
|
uint32_t revision = sceneRevision;
|
||||||
sum2 += sum1 += (revision >> 16);
|
sum2 += sum1 += (revision >> 16);
|
||||||
sum2 += sum1 += (revision & 0xffff);
|
sum2 += sum1 += (revision & 0xffff);
|
||||||
}
|
}
|
||||||
@ -201,30 +189,20 @@ uint32_t Zone::CalculateChecksum() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Zone::LoadLevelsIntoMemory() {
|
void Zone::LoadLevelsIntoMemory() {
|
||||||
for (std::map<LWOSCENEID, SceneRef>::iterator it = m_Scenes.begin(); it != m_Scenes.end(); ++it) {
|
for (auto& [sceneID, scene] : m_Scenes) {
|
||||||
if (it->second.level == nullptr) {
|
if (scene.level) continue;
|
||||||
it->second.level = new Level(this, m_ZonePath + it->second.filename);
|
scene.level = new Level(this, m_ZonePath + scene.filename);
|
||||||
|
|
||||||
if (it->second.level->m_ChunkHeaders.size() > 0) {
|
if (scene.level->m_ChunkHeaders.empty()) continue;
|
||||||
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);
|
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) {
|
void Zone::AddRevision(LWOSCENEID sceneID, uint32_t revision) {
|
||||||
for (std::pair<LWOSCENEID, uint32_t> item : m_MapRevisions) {
|
if (m_MapRevisions.find(sceneID) == m_MapRevisions.end()) {
|
||||||
if (item.first == sceneID) return;
|
m_MapRevisions.insert(std::make_pair(sceneID, revision));
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,17 +211,10 @@ void Zone::LoadScene(std::istream& file) {
|
|||||||
scene.level = nullptr;
|
scene.level = nullptr;
|
||||||
LWOSCENEID lwoSceneID(LWOZONEID_INVALID, 0);
|
LWOSCENEID lwoSceneID(LWOZONEID_INVALID, 0);
|
||||||
|
|
||||||
uint8_t sceneFilenameLength;
|
BinaryIO::ReadString<uint8_t>(file, scene.filename, BinaryIO::ReadType::String);
|
||||||
BinaryIO::BinaryRead(file, sceneFilenameLength);
|
|
||||||
scene.filename = BinaryIO::ReadString(file, sceneFilenameLength);
|
|
||||||
|
|
||||||
std::string luTriggersPath = scene.filename.substr(0, scene.filename.size() - 4) + ".lutriggers";
|
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())) LoadLUTriggers(luTriggersPath, scene);
|
||||||
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 (m_FileFormatVersion >= Zone::FileFormatVersion::LatePreAlpha || m_FileFormatVersion < Zone::FileFormatVersion::PrePreAlpha) {
|
if (m_FileFormatVersion >= Zone::FileFormatVersion::LatePreAlpha || m_FileFormatVersion < Zone::FileFormatVersion::PrePreAlpha) {
|
||||||
BinaryIO::BinaryRead(file, scene.id);
|
BinaryIO::BinaryRead(file, scene.id);
|
||||||
@ -253,12 +224,10 @@ void Zone::LoadScene(std::istream& file) {
|
|||||||
BinaryIO::BinaryRead(file, scene.sceneType);
|
BinaryIO::BinaryRead(file, scene.sceneType);
|
||||||
lwoSceneID.SetLayerID(scene.sceneType);
|
lwoSceneID.SetLayerID(scene.sceneType);
|
||||||
|
|
||||||
uint8_t sceneNameLength;
|
BinaryIO::ReadString<uint8_t>(file, scene.name, BinaryIO::ReadType::String);
|
||||||
BinaryIO::BinaryRead(file, sceneNameLength);
|
|
||||||
scene.name = BinaryIO::ReadString(file, sceneNameLength);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_FileFormatVersion == Zone::FileFormatVersion::LatePreAlpha){
|
if (m_FileFormatVersion == Zone::FileFormatVersion::LatePreAlpha) {
|
||||||
BinaryIO::BinaryRead(file, scene.unknown1);
|
BinaryIO::BinaryRead(file, scene.unknown1);
|
||||||
BinaryIO::BinaryRead(file, scene.unknown2);
|
BinaryIO::BinaryRead(file, scene.unknown2);
|
||||||
}
|
}
|
||||||
@ -270,61 +239,51 @@ void Zone::LoadScene(std::istream& file) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_Scenes.insert(std::make_pair(lwoSceneID, scene));
|
m_Scenes.insert(std::make_pair(lwoSceneID, scene));
|
||||||
m_NumberOfScenesLoaded++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<LUTriggers::Trigger*> Zone::LoadLUTriggers(std::string triggerFile, LWOSCENEID sceneID) {
|
void Zone::LoadLUTriggers(std::string triggerFile, SceneRef& scene) {
|
||||||
std::vector<LUTriggers::Trigger*> lvlTriggers;
|
auto file = Game::assetManager->GetFile((m_ZonePath + triggerFile).c_str());
|
||||||
|
|
||||||
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);
|
|
||||||
std::stringstream data;
|
std::stringstream data;
|
||||||
data << file.rdbuf();
|
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();
|
tinyxml2::XMLDocument doc;
|
||||||
if (!doc) return lvlTriggers;
|
|
||||||
|
|
||||||
if (doc->Parse(data.str().c_str(), data.str().size()) == 0) {
|
if (doc.Parse(data.str().c_str(), size) != tinyxml2::XML_SUCCESS) {
|
||||||
//LOG("Loaded LUTriggers from file %s!", triggerFile.c_str());
|
|
||||||
} else {
|
|
||||||
LOG("Failed to load LUTriggers from file %s", triggerFile.c_str());
|
LOG("Failed to load LUTriggers from file %s", triggerFile.c_str());
|
||||||
return lvlTriggers;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
tinyxml2::XMLElement* triggers = doc->FirstChildElement("triggers");
|
auto* triggers = doc.FirstChildElement("triggers");
|
||||||
if (!triggers) return lvlTriggers;
|
if (!triggers) return;
|
||||||
|
|
||||||
auto currentTrigger = triggers->FirstChildElement("trigger");
|
auto* currentTrigger = triggers->FirstChildElement("trigger");
|
||||||
while (currentTrigger) {
|
while (currentTrigger) {
|
||||||
LUTriggers::Trigger* newTrigger = new LUTriggers::Trigger();
|
LUTriggers::Trigger* newTrigger = new LUTriggers::Trigger();
|
||||||
currentTrigger->QueryAttribute("enabled", &newTrigger->enabled);
|
currentTrigger->QueryAttribute("enabled", &newTrigger->enabled);
|
||||||
currentTrigger->QueryAttribute("id", &newTrigger->id);
|
currentTrigger->QueryAttribute("id", &newTrigger->id);
|
||||||
|
|
||||||
auto currentEvent = currentTrigger->FirstChildElement("event");
|
auto* currentEvent = currentTrigger->FirstChildElement("event");
|
||||||
while (currentEvent) {
|
while (currentEvent) {
|
||||||
LUTriggers::Event* newEvent = new LUTriggers::Event();
|
LUTriggers::Event* newEvent = new LUTriggers::Event();
|
||||||
newEvent->id = TriggerEventType::StringToTriggerEventType(currentEvent->Attribute("id"));
|
newEvent->id = TriggerEventType::StringToTriggerEventType(currentEvent->Attribute("id"));
|
||||||
auto currentCommand = currentEvent->FirstChildElement("command");
|
auto* currentCommand = currentEvent->FirstChildElement("command");
|
||||||
while (currentCommand) {
|
while (currentCommand) {
|
||||||
LUTriggers::Command* newCommand = new LUTriggers::Command();
|
LUTriggers::Command* newCommand = new LUTriggers::Command();
|
||||||
newCommand->id = TriggerCommandType::StringToTriggerCommandType(currentCommand->Attribute("id"));
|
newCommand->id = TriggerCommandType::StringToTriggerCommandType(currentCommand->Attribute("id"));
|
||||||
newCommand->target = currentCommand->Attribute("target");
|
newCommand->target = currentCommand->Attribute("target");
|
||||||
if (currentCommand->Attribute("targetName") != NULL) {
|
if (currentCommand->Attribute("targetName")) {
|
||||||
newCommand->targetName = currentCommand->Attribute("targetName");
|
newCommand->targetName = currentCommand->Attribute("targetName");
|
||||||
}
|
} else if (currentCommand->Attribute("args")) {
|
||||||
if (currentCommand->Attribute("args") != NULL) {
|
|
||||||
newCommand->args = currentCommand->Attribute("args");
|
newCommand->args = currentCommand->Attribute("args");
|
||||||
}
|
}
|
||||||
|
|
||||||
newEvent->commands.push_back(newCommand);
|
newEvent->commands.push_back(newCommand);
|
||||||
currentCommand = currentCommand->NextSiblingElement("command");
|
currentCommand = currentCommand->NextSiblingElement("command");
|
||||||
}
|
}
|
||||||
@ -332,19 +291,18 @@ std::vector<LUTriggers::Trigger*> Zone::LoadLUTriggers(std::string triggerFile,
|
|||||||
currentEvent = currentEvent->NextSiblingElement("event");
|
currentEvent = currentEvent->NextSiblingElement("event");
|
||||||
}
|
}
|
||||||
currentTrigger = currentTrigger->NextSiblingElement("trigger");
|
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) {
|
LUTriggers::Trigger* Zone::GetTrigger(uint32_t sceneID, uint32_t triggerID) {
|
||||||
if (m_Scenes.find(sceneID) == m_Scenes.end()) return nullptr;
|
auto scene = m_Scenes.find(sceneID);
|
||||||
if (m_Scenes[sceneID].triggers.find(triggerID) == m_Scenes[sceneID].triggers.end()) return nullptr;
|
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 {
|
const Path* Zone::GetPath(std::string name) const {
|
||||||
@ -360,15 +318,14 @@ const Path* Zone::GetPath(std::string name) const {
|
|||||||
void Zone::LoadSceneTransition(std::istream& file) {
|
void Zone::LoadSceneTransition(std::istream& file) {
|
||||||
SceneTransition sceneTrans;
|
SceneTransition sceneTrans;
|
||||||
if (m_FileFormatVersion < Zone::FileFormatVersion::Auramar) {
|
if (m_FileFormatVersion < Zone::FileFormatVersion::Auramar) {
|
||||||
uint8_t length;
|
BinaryIO::ReadString<uint8_t>(file, sceneTrans.name, BinaryIO::ReadType::String);
|
||||||
BinaryIO::BinaryRead(file, length);
|
|
||||||
sceneTrans.name = BinaryIO::ReadString(file, length);
|
|
||||||
BinaryIO::BinaryRead(file, sceneTrans.width);
|
BinaryIO::BinaryRead(file, sceneTrans.width);
|
||||||
}
|
}
|
||||||
|
|
||||||
//BR<42>THER MAY I HAVE SOME L<><4C>PS?
|
//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;
|
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) {
|
for (uint8_t i = 0; i < loops; ++i) {
|
||||||
sceneTrans.points.push_back(LoadSceneTransitionInfo(file));
|
sceneTrans.points.push_back(LoadSceneTransitionInfo(file));
|
||||||
}
|
}
|
||||||
@ -388,13 +345,7 @@ void Zone::LoadPath(std::istream& file) {
|
|||||||
|
|
||||||
BinaryIO::BinaryRead(file, path.pathVersion);
|
BinaryIO::BinaryRead(file, path.pathVersion);
|
||||||
|
|
||||||
uint8_t stringLength;
|
BinaryIO::ReadString<uint8_t>(file, path.pathName, BinaryIO::ReadType::WideString);
|
||||||
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::BinaryRead(file, path.pathType);
|
BinaryIO::BinaryRead(file, path.pathType);
|
||||||
BinaryIO::BinaryRead(file, path.flags);
|
BinaryIO::BinaryRead(file, path.flags);
|
||||||
@ -404,13 +355,7 @@ void Zone::LoadPath(std::istream& file) {
|
|||||||
if (path.pathVersion >= 18) {
|
if (path.pathVersion >= 18) {
|
||||||
BinaryIO::BinaryRead(file, path.movingPlatform.timeBasedMovement);
|
BinaryIO::BinaryRead(file, path.movingPlatform.timeBasedMovement);
|
||||||
} else if (path.pathVersion >= 13) {
|
} else if (path.pathVersion >= 13) {
|
||||||
uint8_t count;
|
BinaryIO::ReadString<uint8_t>(file, path.movingPlatform.platformTravelSound, BinaryIO::ReadType::WideString);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (path.pathType == PathType::Property) {
|
} else if (path.pathType == PathType::Property) {
|
||||||
BinaryIO::BinaryRead(file, path.property.pathType);
|
BinaryIO::BinaryRead(file, path.property.pathType);
|
||||||
@ -419,20 +364,8 @@ void Zone::LoadPath(std::istream& file) {
|
|||||||
BinaryIO::BinaryRead(file, path.property.associatedZone);
|
BinaryIO::BinaryRead(file, path.property.associatedZone);
|
||||||
|
|
||||||
if (path.pathVersion >= 5) {
|
if (path.pathVersion >= 5) {
|
||||||
uint8_t count1;
|
BinaryIO::ReadString<uint8_t>(file, path.property.displayName, BinaryIO::ReadType::WideString);
|
||||||
BinaryIO::BinaryRead(file, count1);
|
BinaryIO::ReadString<uint32_t>(file, path.property.displayDesc, BinaryIO::ReadType::WideString);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path.pathVersion >= 6) BinaryIO::BinaryRead(file, path.property.type);
|
if (path.pathVersion >= 6) BinaryIO::BinaryRead(file, path.property.type);
|
||||||
@ -449,13 +382,7 @@ void Zone::LoadPath(std::istream& file) {
|
|||||||
BinaryIO::BinaryRead(file, path.property.maxBuildHeight);
|
BinaryIO::BinaryRead(file, path.property.maxBuildHeight);
|
||||||
}
|
}
|
||||||
} else if (path.pathType == PathType::Camera) {
|
} else if (path.pathType == PathType::Camera) {
|
||||||
uint8_t count;
|
BinaryIO::ReadString<uint8_t>(file, path.camera.nextPath, BinaryIO::ReadType::WideString);
|
||||||
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);
|
|
||||||
}
|
|
||||||
if (path.pathVersion >= 14) {
|
if (path.pathVersion >= 14) {
|
||||||
BinaryIO::BinaryRead(file, path.camera.rotatePlayer);
|
BinaryIO::BinaryRead(file, path.camera.rotatePlayer);
|
||||||
|
|
||||||
@ -472,7 +399,7 @@ void Zone::LoadPath(std::istream& file) {
|
|||||||
// Read waypoints
|
// Read waypoints
|
||||||
|
|
||||||
BinaryIO::BinaryRead(file, path.waypointCount);
|
BinaryIO::BinaryRead(file, path.waypointCount);
|
||||||
|
path.pathWaypoints.reserve(path.waypointCount);
|
||||||
for (uint32_t i = 0; i < path.waypointCount; ++i) {
|
for (uint32_t i = 0; i < path.waypointCount; ++i) {
|
||||||
PathWaypoint waypoint = PathWaypoint();
|
PathWaypoint waypoint = PathWaypoint();
|
||||||
|
|
||||||
@ -493,20 +420,8 @@ void Zone::LoadPath(std::istream& file) {
|
|||||||
BinaryIO::BinaryRead(file, waypoint.movingPlatform.speed);
|
BinaryIO::BinaryRead(file, waypoint.movingPlatform.speed);
|
||||||
BinaryIO::BinaryRead(file, waypoint.movingPlatform.wait);
|
BinaryIO::BinaryRead(file, waypoint.movingPlatform.wait);
|
||||||
if (path.pathVersion >= 13) {
|
if (path.pathVersion >= 13) {
|
||||||
uint8_t count1;
|
BinaryIO::ReadString<uint8_t>(file, waypoint.movingPlatform.departSound, BinaryIO::ReadType::WideString);
|
||||||
BinaryIO::BinaryRead(file, count1);
|
BinaryIO::ReadString<uint8_t>(file, waypoint.movingPlatform.arriveSound, BinaryIO::ReadType::WideString);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (path.pathType == PathType::Camera) {
|
} else if (path.pathType == PathType::Camera) {
|
||||||
BinaryIO::BinaryRead(file, waypoint.camera.time);
|
BinaryIO::BinaryRead(file, waypoint.camera.time);
|
||||||
@ -529,22 +444,11 @@ void Zone::LoadPath(std::istream& file) {
|
|||||||
uint32_t count;
|
uint32_t count;
|
||||||
BinaryIO::BinaryRead(file, count);
|
BinaryIO::BinaryRead(file, count);
|
||||||
for (uint32_t i = 0; i < count; ++i) {
|
for (uint32_t i = 0; i < count; ++i) {
|
||||||
uint8_t count1;
|
|
||||||
std::string parameter;
|
std::string parameter;
|
||||||
|
BinaryIO::ReadString<uint8_t>(file, parameter, BinaryIO::ReadType::WideString);
|
||||||
|
|
||||||
std::string value;
|
std::string value;
|
||||||
BinaryIO::BinaryRead(file, count1);
|
BinaryIO::ReadString<uint8_t>(file, value, BinaryIO::ReadType::WideString);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
LDFBaseData* ldfConfig = nullptr;
|
LDFBaseData* ldfConfig = nullptr;
|
||||||
if (path.pathType == PathType::Movement || path.pathType == PathType::Rail) {
|
if (path.pathType == PathType::Movement || path.pathType == PathType::Rail) {
|
||||||
|
@ -210,7 +210,6 @@ public:
|
|||||||
void AddRevision(LWOSCENEID sceneID, uint32_t revision);
|
void AddRevision(LWOSCENEID sceneID, uint32_t revision);
|
||||||
const LWOZONEID& GetZoneID() const { return m_ZoneID; }
|
const LWOZONEID& GetZoneID() const { return m_ZoneID; }
|
||||||
const uint32_t GetChecksum() const { return m_CheckSum; }
|
const uint32_t GetChecksum() const { return m_CheckSum; }
|
||||||
const void PrintAllGameObjects();
|
|
||||||
LUTriggers::Trigger* GetTrigger(uint32_t sceneID, uint32_t triggerID);
|
LUTriggers::Trigger* GetTrigger(uint32_t sceneID, uint32_t triggerID);
|
||||||
const Path* GetPath(std::string name) const;
|
const Path* GetPath(std::string name) const;
|
||||||
|
|
||||||
@ -228,7 +227,6 @@ public:
|
|||||||
private:
|
private:
|
||||||
LWOZONEID m_ZoneID;
|
LWOZONEID m_ZoneID;
|
||||||
std::string m_ZoneFilePath;
|
std::string m_ZoneFilePath;
|
||||||
uint32_t m_NumberOfScenesLoaded;
|
|
||||||
uint32_t m_NumberOfObjectsLoaded;
|
uint32_t m_NumberOfObjectsLoaded;
|
||||||
uint32_t m_NumberOfSceneTransitionsLoaded;
|
uint32_t m_NumberOfSceneTransitionsLoaded;
|
||||||
FileFormatVersion m_FileFormatVersion;
|
FileFormatVersion m_FileFormatVersion;
|
||||||
@ -243,18 +241,17 @@ private:
|
|||||||
std::string m_ZoneDesc; //Description of the zone by a level designer
|
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::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;
|
std::vector<SceneTransition> m_SceneTransitions;
|
||||||
|
|
||||||
uint32_t m_PathDataLength;
|
uint32_t m_PathDataLength;
|
||||||
uint32_t m_PathChunkVersion;
|
uint32_t m_PathChunkVersion;
|
||||||
std::vector<Path> m_Paths;
|
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:
|
//private ("helper") functions:
|
||||||
void LoadScene(std::istream& file);
|
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);
|
void LoadSceneTransition(std::istream& file);
|
||||||
SceneTransitionInfo LoadSceneTransitionInfo(std::istream& file);
|
SceneTransitionInfo LoadSceneTransitionInfo(std::istream& file);
|
||||||
void LoadPath(std::istream& file);
|
void LoadPath(std::istream& file);
|
||||||
|
@ -5,10 +5,6 @@
|
|||||||
#include "LDFFormat.h"
|
#include "LDFFormat.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
struct mapCompareLwoSceneIDs {
|
|
||||||
bool operator()(const LWOSCENEID& lhs, const LWOSCENEID& rhs) const { return lhs < rhs; }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SceneObject {
|
struct SceneObject {
|
||||||
LWOOBJID id;
|
LWOOBJID id;
|
||||||
LOT lot;
|
LOT lot;
|
||||||
|
@ -94,33 +94,6 @@ void dZoneManager::LoadZone(const LWOZONEID& zoneID) {
|
|||||||
m_pZone = new Zone(zoneID.GetMapID(), zoneID.GetInstanceID(), zoneID.GetCloneID());
|
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) {
|
void dZoneManager::AddSpawner(LWOOBJID id, Spawner* spawner) {
|
||||||
m_Spawners.insert_or_assign(id, 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
|
ReloadZone, //Forces the server and all connects clients to reload the map
|
||||||
UserJoined,
|
UserJoined,
|
||||||
UserMoved,
|
UserMoved,
|
||||||
PrintAllGameObjects, //Using this is a BAD idea in production
|
|
||||||
InvalidNotifier
|
InvalidNotifier
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -30,7 +29,6 @@ public:
|
|||||||
|
|
||||||
Zone* GetZone(); //Gets a pointer to the currently loaded zone.
|
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 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);
|
void AddSpawner(LWOOBJID id, Spawner* spawner);
|
||||||
LWOZONEID GetZoneID() const;
|
LWOZONEID GetZoneID() const;
|
||||||
LWOOBJID MakeSpawner(SpawnerInfo info);
|
LWOOBJID MakeSpawner(SpawnerInfo info);
|
||||||
|
Loading…
Reference in New Issue
Block a user