mirror of
https://github.com/GabsPuNs/Project-Zenith-Main.git
synced 2026-05-22 02:35:26 +00:00
357 lines
10 KiB
C++
357 lines
10 KiB
C++
#include "stdafx.h"
|
|
#include "StructureTable.h"
|
|
#include "../Minecraft.World/StringHelpers.h"
|
|
|
|
unordered_map<wstring, eMinecraftStructureFeature> StructureTable::s_structureFeatureNamesMap;
|
|
unordered_map<wstring, eMinecraftStructurePiece> StructureTable::s_structurePieceNamesMap;
|
|
unordered_map<wstring, eGenerateObject> StructureTable::s_generateObjectNamesMap;
|
|
unordered_map<wstring, eGenerateEntity> StructureTable::s_generateEntityNamesMap;
|
|
unordered_map<wstring, eGenerateStructure> StructureTable::s_generateStructureNamesMap;
|
|
|
|
const wchar_t *StructureTable::StructureFeatureElements[eMinecraftStructureFeature_Count] =
|
|
{
|
|
L"NOTSET",
|
|
L"VillageFeature",
|
|
};
|
|
|
|
const wchar_t *StructureTable::StructurePieceElements[eMinecraftStructurePiece_Count] =
|
|
{
|
|
L"NOTSET",
|
|
L"DesertPyramidPiece",
|
|
L"SimpleHouse",
|
|
L"SmallTemple",
|
|
L"BookHouse",
|
|
L"SmallHut",
|
|
L"PigHouse",
|
|
L"DoubleFarmland",
|
|
L"Farmland",
|
|
L"Smithy",
|
|
L"TwoRoomHouse",
|
|
L"LightPost",
|
|
L"Well",
|
|
};
|
|
|
|
const wchar_t *StructureTable::GenerateObjectElements[eGenerateObject_Count] =
|
|
{
|
|
L"Chest",
|
|
L"Dispenser",
|
|
};
|
|
|
|
const wchar_t *StructureTable::GenerateEntityElements[eGenerateEntity_Count] =
|
|
{
|
|
L"Villager",
|
|
L"Witch",
|
|
};
|
|
|
|
const wchar_t *StructureTable::GenerateStructureElements[eGenerateStructure_Count] =
|
|
{
|
|
L"Block",
|
|
L"maybeGenerateBlock",
|
|
L"AirBox",
|
|
L"Box",
|
|
L"MaybeBox",
|
|
L"UpperHalfSphere",
|
|
L"FullSphere",
|
|
L"AirColumnUp",
|
|
L"fillColumnDown",
|
|
L"fillBoxDown",
|
|
L"generateAirBoxUp",
|
|
L"Crops",
|
|
L"CreateDoor",
|
|
L"CheckBlock",
|
|
};
|
|
|
|
void StructureTable::staticCtor()
|
|
{
|
|
for(unsigned int i = 0; i < eMinecraftStructureFeature_Count; ++i)
|
|
{
|
|
s_structureFeatureNamesMap.insert( unordered_map<wstring,eMinecraftStructureFeature>::value_type( StructureFeatureElements[i], (eMinecraftStructureFeature)i) );
|
|
}
|
|
|
|
for(unsigned int i = 0; i < eMinecraftStructurePiece_Count; ++i)
|
|
{
|
|
s_structurePieceNamesMap.insert(unordered_map<wstring,eMinecraftStructurePiece>::value_type( StructurePieceElements[i], (eMinecraftStructurePiece)i) );
|
|
}
|
|
|
|
for(unsigned int i = 0; i < eGenerateObject_Count; ++i)
|
|
{
|
|
s_generateObjectNamesMap.insert( unordered_map<wstring,eGenerateObject>::value_type( GenerateObjectElements[i], (eGenerateObject)i) );
|
|
}
|
|
|
|
for(unsigned int i = 0; i < eGenerateEntity_Count; ++i)
|
|
{
|
|
s_generateEntityNamesMap.insert( unordered_map<wstring,eGenerateEntity>::value_type( GenerateEntityElements[i], (eGenerateEntity)i) );
|
|
}
|
|
|
|
for(unsigned int i = 0; i < eGenerateStructure_Count; ++i)
|
|
{
|
|
s_generateStructureNamesMap.insert(unordered_map<wstring,eGenerateStructure>::value_type( GenerateStructureElements[i], (eGenerateStructure)i) );
|
|
}
|
|
}
|
|
|
|
StructureTable::StructureTable(PBYTE pbData, DWORD dwLength)
|
|
{
|
|
loadStructuresFromData(pbData, dwLength);
|
|
}
|
|
|
|
StructureTable::StructurePiece* StructureTable::getStructurePiece(eMinecraftStructurePiece piece)
|
|
{
|
|
return &m_structurePieces[(int)piece];
|
|
}
|
|
|
|
StructureTable::StructureFeature* StructureTable::getStructureFeature(eMinecraftStructureFeature feature)
|
|
{
|
|
return &m_structureFeatures[(int)feature];
|
|
}
|
|
|
|
void StructureTable::loadStructuresFromData(PBYTE pbData, DWORD dwLength)
|
|
{
|
|
byteArray src(pbData, dwLength);
|
|
|
|
ByteArrayInputStream bais(src);
|
|
DataInputStream dis(&bais);
|
|
|
|
int versionNumber = dis.readInt();
|
|
int featureCount = dis.readInt();
|
|
int pieceCount = dis.readInt();
|
|
|
|
for(int i = 0; i < featureCount; ++i)
|
|
{
|
|
StructureFeature feature;
|
|
feature.name = dis.readUTF();
|
|
|
|
int optionsCount = dis.readInt();
|
|
int tilesCount = dis.readInt();
|
|
|
|
for(int j = 0; j < optionsCount; ++j)
|
|
{
|
|
feature.options.push_back(dis.readInt());
|
|
}
|
|
|
|
for(int j = 0; j < tilesCount; ++j)
|
|
{
|
|
std::wstring tile = dis.readUTF();
|
|
size_t comma = tile.find(L',');
|
|
if(comma != std::wstring::npos)
|
|
{
|
|
int k = std::stoi(tile.substr(0, comma));
|
|
int v = std::stoi(tile.substr(comma + 1));
|
|
feature.tiles[k] = v;
|
|
}
|
|
}
|
|
|
|
auto it = s_structureFeatureNamesMap.find(feature.name);
|
|
if (it != s_structureFeatureNamesMap.end())
|
|
{
|
|
m_structureFeatures[(int)it->second] = feature;
|
|
}
|
|
}
|
|
|
|
for(int i = 0; i < pieceCount; ++i)
|
|
{
|
|
StructurePiece structurePiece;
|
|
|
|
structurePiece.name = dis.readUTF();
|
|
structurePiece.width = dis.readInt();
|
|
structurePiece.height = dis.readInt();
|
|
structurePiece.depth = dis.readInt();
|
|
|
|
int treasureCount = dis.readInt();
|
|
int structuresCount = dis.readInt();
|
|
int objectsCount = dis.readInt();
|
|
int entitiesCount = dis.readInt();
|
|
|
|
// ?
|
|
structurePiece.v8 = dis.readInt();
|
|
|
|
// @3UR: some sort of count/size?
|
|
int unk_count1 = dis.readInt();
|
|
int numCropTiles = dis.readInt();
|
|
|
|
// ?
|
|
for(int j = 0; j < unk_count1; ++j)
|
|
{
|
|
structurePiece.v11.push_back(dis.readInt());
|
|
}
|
|
for(int j = 0; j < numCropTiles; ++j)
|
|
{
|
|
structurePiece.cropTiles.push_back(dis.readInt());
|
|
}
|
|
|
|
for(int j = 0; j < treasureCount; ++j)
|
|
{
|
|
TreasureData t;
|
|
t.itemId = dis.readInt();
|
|
t.auxValue = dis.readInt();
|
|
t.minCount = dis.readInt();
|
|
t.maxCount = dis.readInt();
|
|
t.weight = dis.readInt();
|
|
structurePiece.treasure.push_back(t);
|
|
}
|
|
|
|
for(int j = 0; j < structuresCount; ++j)
|
|
{
|
|
StructureData s;
|
|
std::wstring name = dis.readUTF();
|
|
|
|
auto it = s_generateStructureNamesMap.find(name);
|
|
s.id = (it != s_generateStructureNamesMap.end()) ? (int)it->second : 0;
|
|
s.name = name;
|
|
|
|
s.tileId = dis.readInt();
|
|
s.data = dis.readInt();
|
|
s.dataType = dis.readInt();
|
|
|
|
bool hasSecondTile = dis.readBoolean();
|
|
if(hasSecondTile)
|
|
{
|
|
s.secondTileId = dis.readInt();
|
|
s.secondData = dis.readInt();
|
|
s.secondDataType = dis.readInt();
|
|
}
|
|
else
|
|
{
|
|
s.secondTileId = 0;
|
|
s.secondData = 0;
|
|
s.secondDataType = 0;
|
|
}
|
|
|
|
s.x0 = dis.readInt();
|
|
s.y0 = dis.readInt();
|
|
s.z0 = dis.readInt();
|
|
|
|
bool hasBounds = dis.readBoolean();
|
|
if(hasBounds)
|
|
{
|
|
s.x1 = dis.readInt();
|
|
s.y1 = dis.readInt();
|
|
s.z1 = dis.readInt();
|
|
}
|
|
else
|
|
{
|
|
s.x1 = 0;
|
|
s.y1 = 0;
|
|
s.z1 = 0;
|
|
}
|
|
|
|
// ?
|
|
bool hasStartRemaps = dis.readBoolean();
|
|
if(hasStartRemaps)
|
|
{
|
|
s.startRemap0 = dis.readInt();
|
|
s.startRemap1 = dis.readInt();
|
|
s.startRemap2 = dis.readInt();
|
|
}
|
|
else
|
|
{
|
|
s.startRemap0 = -1;
|
|
s.startRemap1 = -1;
|
|
s.startRemap2 = -1;
|
|
}
|
|
|
|
// ?
|
|
bool hasEndRemaps = dis.readBoolean();
|
|
if(hasEndRemaps)
|
|
{
|
|
s.endRemap0 = dis.readInt();
|
|
s.endRemap1 = dis.readInt();
|
|
s.endRemap2 = dis.readInt();
|
|
}
|
|
else
|
|
{
|
|
s.endRemap0 = -1;
|
|
s.endRemap1 = -1;
|
|
s.endRemap2 = -1;
|
|
}
|
|
|
|
readIntSaveData(dis, s.cropAges);
|
|
readIntSaveData(dis, s.v25);
|
|
readIntSaveData(dis, s.v26);
|
|
readIntSaveData(dis, s.v27);
|
|
|
|
structurePiece.structures.push_back(s);
|
|
}
|
|
|
|
for(int j = 0; j < objectsCount; ++j)
|
|
{
|
|
ObjectData o;
|
|
std::wstring name = dis.readUTF();
|
|
|
|
auto it = s_generateObjectNamesMap.find(name);
|
|
o.id = (it != s_generateObjectNamesMap.end()) ? (int)it->second : 0;
|
|
o.name = name;
|
|
|
|
o.x = dis.readInt();
|
|
o.y = dis.readInt();
|
|
o.z = dis.readInt();
|
|
|
|
o.minEnchantedBooks = dis.readInt();
|
|
o.maxEnchantedBooks = dis.readInt();
|
|
o.enchantedBookWeight = dis.readInt();
|
|
o.rollCount = dis.readInt();
|
|
o.canGenEnchantedBooks = dis.readBoolean();
|
|
o.rollWeight = dis.readInt();
|
|
o.dispenserDir = dis.readInt();
|
|
|
|
structurePiece.objects.push_back(o);
|
|
}
|
|
|
|
for(int j = 0; j < entitiesCount; ++j)
|
|
{
|
|
EntityData e;
|
|
std::wstring name = dis.readUTF();
|
|
|
|
auto it = s_generateEntityNamesMap.find(name);
|
|
e.id = (it != s_generateEntityNamesMap.end()) ? (int)it->second : 0;
|
|
e.x = dis.readInt();
|
|
e.y = dis.readInt();
|
|
e.z = dis.readInt();
|
|
e.count = dis.readInt();
|
|
|
|
std::wstring professionsCsv = dis.readUTF();
|
|
|
|
size_t start = 0, end;
|
|
while((end = professionsCsv.find(L',', start)) != std::wstring::npos)
|
|
{
|
|
e.professions.push_back(std::stoi(professionsCsv.substr(start, end - start)));
|
|
start = end + 1;
|
|
}
|
|
if(start < professionsCsv.size())
|
|
{
|
|
e.professions.push_back(std::stoi(professionsCsv.substr(start)));
|
|
}
|
|
|
|
structurePiece.entities.push_back(e);
|
|
}
|
|
|
|
setStructurePiece(structurePiece.name, structurePiece);
|
|
}
|
|
|
|
bais.reset();
|
|
}
|
|
|
|
void StructureTable::setStructurePiece(const wstring& name, const StructurePiece& piece)
|
|
{
|
|
auto it = s_structurePieceNamesMap.find(name);
|
|
if (it != s_structurePieceNamesMap.end())
|
|
{
|
|
m_structurePieces[(int)it->second] = piece;
|
|
}
|
|
}
|
|
|
|
void StructureTable::readIntSaveData(DataInputStream& dis, vector<int>& container)
|
|
{
|
|
wstring data = dis.readUTF();
|
|
|
|
vector<wstring> tokens = stringSplit(data, L',');
|
|
|
|
for (size_t i = 0; i < tokens.size(); ++i)
|
|
{
|
|
wistringstream wiss(tokens[i]);
|
|
int outVal = 0;
|
|
|
|
wiss >> dec >> outVal;
|
|
|
|
container.push_back(outVal);
|
|
}
|
|
} |