new puzzle tool

This commit is contained in:
Till W
2025-05-25 13:07:52 +02:00
parent 410f401aef
commit cac2ef3330
12 changed files with 275 additions and 122 deletions

View File

@@ -52,10 +52,10 @@ namespace Game
struct InstanceDebugData
{
uint16_t SelectedDebugLevel = UINT16_MAX;
static constexpr uint32_t MaxAssets = 128;
uint16_t SelectedDebugLevel = 0;
uint64_t ImguiIniSize = 0;
char ImguiIni[4096]{0};
static constexpr uint32_t MaxAssets = 128;
uint32_t AssetCount = 0;
Gen::AssetHandle AssetHandles[MaxAssets]{0};
char AssetHandlePaths[MaxAssets][128];

View File

@@ -22,6 +22,7 @@ namespace
StaticPuzzleData StaticData;
StaticPuzzleCard InvalidCard;
PlacedPuzzleCard InvalidPlacedCard;
} // namespace
namespace Puzzle
@@ -104,6 +105,24 @@ namespace Puzzle
return puz.BackgroundTiles[pos.Y * Puzzle::Config::MaxPuzzleSizeTiles + pos.X];
}
PuzzleElementType::Enum GetInitialNodeAt(const PuzzleData& puz, PuzPos pos)
{
assert(pos.X < Puzzle::Config::MaxPuzzleSizeTiles && pos.Y < Puzzle::Config::MaxPuzzleSizeTiles && pos.X >= 0 &&
pos.Y >= 0);
int32_t cardIdxX = pos.X / Puzzle::Config::CardSize;
int32_t cardIdxY = pos.Y / Puzzle::Config::CardSize;
auto& card = puz.InitialPlacedCards[cardIdxY * Puzzle::Config::MaxPuzzleSizeCards + cardIdxX];
int32_t offsetX = pos.X - (cardIdxX * Config::CardSize);
int32_t offsetY = pos.Y - (cardIdxY * Config::CardSize);
if (offsetX >= 0 && offsetX < Puzzle::Config::CardSize && offsetY >= 0 && offsetY < Puzzle::Config::CardSize &&
IsValid(card.RefCard))
{
PuzzleElementType::Enum cardVal = GetCardNodeAt(GetCard(card.RefCard), card.Rotation, offsetX, offsetY);
if (cardVal != PuzzleElementType::None) return cardVal;
}
return puz.BackgroundTiles[pos.Y * Puzzle::Config::MaxPuzzleSizeTiles + pos.X];
}
PuzzleElementType::Enum GetCardNodeAt(const StaticPuzzleCard& card, uint8_t rotation, int8_t x, int8_t y)
{
assert(x >= 0 && x < Puzzle::Config::CardSize);
@@ -288,12 +307,32 @@ namespace Puzzle
bx::snprintf(buf, bufSize, "%s/%u.pzl", Puzzle::PuzzleFileDir, puzID);
}
PlacedPuzzleCard& GetCardAt(PuzzleData& obj, PuzPos pos)
{
if (pos.X < 0 || pos.X >= Config::MaxPuzzleSizeCards || pos.Y < 0 || pos.Y >= Config::MaxPuzzleSizeCards)
{
LOG_ERROR("Invalid card access at %i %i!!", pos.X, pos.Y);
return InvalidPlacedCard;
}
return obj.PlacedCards[pos.Y * Config::MaxPuzzleSizeCards + pos.X];
}
PlacedPuzzleCard& GetInitialCardAt(PuzzleData& obj, PuzPos pos)
{
if (pos.X < 0 || pos.X >= Config::MaxPuzzleSizeCards || pos.Y < 0 || pos.Y >= Config::MaxPuzzleSizeCards)
{
LOG_ERROR("Invalid card access at %i %i!!", pos.X, pos.Y);
return InvalidPlacedCard;
}
return obj.InitialPlacedCards[pos.Y * Config::MaxPuzzleSizeCards + pos.X];
}
bool ReturnPlacedCard(PuzzleData& obj, PuzPos targetPos)
{
auto& placedCard = obj.PlacedCards[targetPos.Y * Config::MaxPuzzleSizeCards + targetPos.X];
PlacedPuzzleCard& placedCard = GetCardAt(obj, targetPos);
if (IsValid(placedCard.RefCard))
{
if (placedCard.IsLocked)
if (GetFlag(placedCard.Flags, PlacedPuzzleCardFlags::Locked))
{
LOG_WARN("Card at %i %i is locked!", targetPos.X, targetPos.Y);
return false;
@@ -330,9 +369,9 @@ namespace Puzzle
auto& draggedCard = obj.AvailableCards[availIdx];
draggedCard.UsedCount++;
auto& placedCard = obj.PlacedCards[targetPos.Y * Config::MaxPuzzleSizeCards + targetPos.X];
PlacedPuzzleCard& placedCard = GetCardAt(obj, targetPos);
placedCard.RefCard = draggedCard.RefCard;
placedCard.IsLocked = false;
placedCard.Flags = (PlacedPuzzleCardFlags::Enum)ClearFlags(placedCard.Flags, PlacedPuzzleCardFlags::Locked);
placedCard.Position = targetPos;
placedCard.Rotation = rotation;
return true;
@@ -340,9 +379,6 @@ namespace Puzzle
bool RenderDebugUI(PuzzleData& obj)
{
bool dataChanged = false;
uint8_t debugRot = Game::GetInstance().DebugData.DebugCardRotation;
bool isVisible = true;
if (ImGui::Begin("Puzzle", &isVisible))
{
@@ -356,17 +392,34 @@ namespace Puzzle
return false;
}
ImGui::SameLine();
if (ImGui::Button("Reload"))
if (ImGui::Button("Reset"))
{
// TODO
ResetPuzzle(obj);
}
ImGui::SameLine();
if (ImGui::Button("Save"))
{
ResetPuzzle(obj);
char path[128]{0};
WritePuzzleFilePath(path, sizeof(path), obj.ID);
Serializer ser;
if (ser.Init(path, "PZZL") && ser.WriteT(obj))
{
LOG("Saved to %s", path);
}
else
{
LOG_ERROR("Failed to save to %s", path);
}
ser.Finish();
}
int32_t val = obj.ID;
if (ImGui::InputInt("ID", &val))
{
obj.ID = val;
dataChanged = true;
}
dataChanged = ImGui::InputText("Name", obj.PuzzleName, sizeof(obj.PuzzleName)) || dataChanged;
ImGui::InputText("Name", obj.PuzzleName, sizeof(obj.PuzzleName));
int32_t W = obj.WidthTiles;
int32_t H = obj.HeightTiles;
@@ -375,7 +428,6 @@ namespace Puzzle
if (ImGui::DragInt("", &W, 0.3f, 0, Puzzle::Config::MaxPuzzleSizeTiles))
{
obj.WidthTiles = uint8_t(W);
dataChanged = true;
}
ImGui::PopID();
ImGui::SameLine();
@@ -386,7 +438,6 @@ namespace Puzzle
if (ImGui::DragInt("", &H, 0.3f, 0, Puzzle::Config::MaxPuzzleSizeTiles))
{
obj.HeightTiles = uint8_t(H);
dataChanged = true;
}
ImGui::PopID();
@@ -401,7 +452,7 @@ namespace Puzzle
{
ImGui::PushID(x);
PuzPos nodePos = {int8_t(x), int8_t(y)};
auto node = GetNodeAt(obj, nodePos);
auto node = GetInitialNodeAt(obj, nodePos);
if (node == PuzzleElementType::WaterGoal)
{
obj.GoalPositions[obj.GoalPositionCount] = nodePos;
@@ -414,36 +465,29 @@ namespace Puzzle
ImGui::SetCursorScreenPos(pos);
if (x % Puzzle::Config::CardSize == 0 && y % Puzzle::Config::CardSize == 0)
{
int32_t cardX = x / Config::CardSize;
int32_t cardY = y / Config::CardSize;
PuzPos cardPos = {int8_t(cardX), int8_t(cardY)};
auto& placedCard = obj.PlacedCards[cardY * Config::MaxPuzzleSizeCards + cardX];
PuzPos cardPos = {int8_t(x / Config::CardSize), int8_t(y / Config::CardSize)};
PlacedPuzzleCard& placedCard = GetInitialCardAt(obj, cardPos);
bool isLocked = GetFlag(placedCard.Flags, PlacedPuzzleCardFlags::Locked);
ImGui::InvisibleButton("bn", {UIPuzBoxSize * 2, UIPuzBoxSize * 2});
if (ImGui::IsItemClicked(ImGuiMouseButton_Right))
{
placedCard.Rotation += 1;
if (placedCard.Rotation >= 4) placedCard.Rotation = 0;
dataChanged = true;
}
if (ImGui::IsItemClicked(ImGuiMouseButton_Middle) && IsValid(placedCard.RefCard))
if (ImGui::IsItemClicked(ImGuiMouseButton_Middle))
{
if (placedCard.IsLocked)
if (ImGui::IsKeyDown(ImGuiKey_LeftShift))
{
placedCard.IsLocked = false;
placedCard.RefCard = {};
dataChanged = true;
placedCard = {};
}
else
{
if (!ReturnPlacedCard(obj, cardPos))
{
placedCard.IsLocked = false;
placedCard.RefCard = {};
dataChanged = true;
}
placedCard.Flags =
(PlacedPuzzleCardFlags::Enum)(placedCard.Flags ^ PlacedPuzzleCardFlags::Locked);
}
}
if (!placedCard.IsLocked && IsValid(placedCard.RefCard))
if (!isLocked && IsValid(placedCard.RefCard))
{
ImVec2 s = {puzCursorStart.x + x * UIPuzBoxSize, puzCursorStart.y + y * UIPuzBoxSize};
drawList.AddRectFilled(s,
@@ -458,17 +502,10 @@ namespace Puzzle
uint32_t CardIdx = *reinterpret_cast<uint32_t*>(payload->Data);
placedCard = {};
placedCard.RefCard = {(uint16_t)CardIdx};
placedCard.Rotation = debugRot;
placedCard.Rotation = 0;
placedCard.Position = cardPos;
placedCard.IsLocked = true;
dataChanged = true;
}
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("availcard", 0))
{
DragAvailableCardTo(obj,
cardPos,
*(int32_t*)payload->Data,
Game::GetInstance().DebugData.DebugCardRotation);
placedCard.Flags = (PlacedPuzzleCardFlags::Enum)SetFlags(placedCard.Flags,
PlacedPuzzleCardFlags::Locked);
}
ImGui::EndDragDropTarget();
}
@@ -534,7 +571,6 @@ namespace Puzzle
obj.AvailableCardCount++;
}
}
dataChanged = true;
}
ImGui::EndDragDropTarget();
}
@@ -547,14 +583,8 @@ namespace Puzzle
ImGui::SetCursorScreenPos(localPos);
ImGui::PushID(i);
auto& card = obj.AvailableCards[i];
DrawCard(GetCard(card.RefCard), debugRot, ImGui::GetCursorScreenPos());
DrawCard(GetCard(card.RefCard), 0, ImGui::GetCursorScreenPos());
int displayCount = card.MaxAvailableCount - card.UsedCount;
if (displayCount > 0 && ImGui::BeginDragDropSource())
{
ImGui::SetDragDropPayload("availcard", &i, sizeof(i));
DrawCard(GetCard(card.RefCard), debugRot, ImGui::GetCursorScreenPos());
ImGui::EndDragDropSource();
}
ImGui::SetCursorScreenPos({localPos.x, localPos.y + 55.0f});
ImGui::SetNextItemWidth(35);
@@ -563,7 +593,6 @@ namespace Puzzle
{
int diff = displayCount - (card.MaxAvailableCount - card.UsedCount);
card.MaxAvailableCount = bx::max(0, card.MaxAvailableCount + diff);
dataChanged = true;
}
ImGui::PopID();
ImGui::SameLine(0, 3);
@@ -582,22 +611,17 @@ namespace Puzzle
}
ImGui::End();
if (dataChanged)
{
char path[128]{0};
WritePuzzleFilePath(path, sizeof(path), obj.ID);
Serializer ser;
if (ser.Init(path, "PZZL") && ser.WriteT(obj))
{
LOG("Saved to %s", path);
}
else
{
LOG_ERROR("Failed to save to %s", path);
}
ser.Finish();
}
return isVisible;
}
void ResetPuzzle(PuzzleData& puz)
{
for (int32_t i = 0; i < puz.AvailableCardCount; ++i)
{
puz.AvailableCards[i].UsedCount = 0;
}
for (int32_t i = 0; i < BX_COUNTOF(puz.PlacedCards); ++i)
{
puz.PlacedCards[i] = puz.InitialPlacedCards[i];
}
}
} // namespace Puzzle

View File

@@ -35,15 +35,19 @@ namespace Puzzle
bool IsValid(StaticPuzzleCardHandle h);
uint8_t GetRemainingCount(const PuzzleCardStack& stack);
PuzzleElementType::Enum GetNodeAt(const PuzzleData& puz, PuzPos pos);
PuzzleElementType::Enum GetInitialNodeAt(const PuzzleData& puz, PuzPos pos);
PuzzleElementType::Enum GetCardNodeAt(const StaticPuzzleCard& card, uint8_t rotation, int8_t x, int8_t y);
PuzzleElementType::Enum& EditCardNodeAt(StaticPuzzleCard& card, uint8_t rotation, int8_t x, int8_t y);
void DrawCard(const StaticPuzzleCard& card, uint8_t rotation, ImVec2 pos);
void RotateCard(PlacedPuzzleCard& card);
PlacedPuzzleCard& GetCardAt(PuzzleData& obj, PuzPos pos);
PlacedPuzzleCard& GetInitialCardAt(PuzzleData& obj, PuzPos pos);
// TODO: targetPos is of type CardPos
bool ReturnPlacedCard(PuzzleData& obj, PuzPos targetPos);
// TODO: targetPos is of type CardPos
bool DragAvailableCardTo(PuzzleData& obj, PuzPos targetPos, int32_t availIdx, uint8_t rotation);
void ResetPuzzle(PuzzleData& puz);
struct PuzzleSolver
{

View File

@@ -483,6 +483,7 @@ namespace Tools
{
ImGui::Checkbox("Arenas", &debug.ShowArenaUsage);
ImGui::Checkbox("ImGui Demo", &debug.ShowImguiDemo);
ImGui::SliderFloat("Font Scale", &ImGui::GetIO().FontGlobalScale, 0.5f, 4.0f);
}
ImGui::End();
@@ -496,6 +497,23 @@ namespace Tools
}
ImGui::End();
}
if (ImGui::Begin("Entities"))
{
ImGui::Text("UIQuads");
for (uint16_t i = 0; i < level.UIQuads.Count; ++i)
{
ImGui::PushID(i);
auto& quad = level.UIQuads.Get({i});
ImGui::Checkbox("Visible", &quad.EData.Visible);
TextureDropdown(quad.EData.TextureHandle);
MaterialDropdown(quad.EData.MaterialHandle);
ImGui::DragFloat3("Pos", &quad.EData.Transform.Position.x);
ImGui::DragFloat3("UI Pos", &quad.UIPos.x);
ImGui::PopID();
}
}
ImGui::End();
}
if (debug.ShowStats)
{

View File

@@ -6,6 +6,7 @@
#include "Instance.h"
#include "Level.h"
#include "Puzzle.h"
#include "bx/math.h"
using namespace Gen;
@@ -177,11 +178,22 @@ namespace Game
}
}
Vec3 CalcBoardOffset(const Gen::PuzzleData& puzData)
{
return Vec3{
(float)(puzData.WidthTiles) / (2.0f * Puzzle::Config::CardSize),
(float)(puzData.HeightTiles) / (2.0f * Puzzle::Config::CardSize),
0.0f,
} *
2.0f * WorldPuzzleUI::UICardScale * WorldPuzzleUI::UICardScale;
}
void WorldPuzzleUI::UpdateBoardCards(Gen::PuzzleData& Data)
{
auto& level = GetInstance().GameLevel;
auto& staticCards = Puzzle::GetStaticPuzzleData().Cards;
Vec3 quadPlaneIntersectPos;
Vec3 boardOffset = CalcBoardOffset(Data);
for (int8_t y = 0; y < Data.HeightTiles / Puzzle::Config::CardSize; ++y)
{
@@ -191,22 +203,24 @@ namespace Game
int32_t cardIdx = y * Puzzle::Config::MaxPuzzleSizeCards + x;
PlacedPuzzleCard& card = Data.PlacedCards[cardIdx];
bool isValid = Puzzle::IsValid(card.RefCard);
bool isLocked = GetFlag(card.Flags, PlacedPuzzleCardFlags::Locked);
auto& quad = level.UIQuads.Get(UIPlacedCards[cardIdx]);
quad.UIPos = Vec3{(float)card.Position.X, (float)card.Position.Y, 0.0f} * UICardOffset * UICardScale;
quad.UIPos -= boardOffset;
quad.UIRot = card.Rotation * bx::kPi * 0.5f;
UpdateQuad(level.UIQuads, UIPlacedCards[cardIdx]);
quad.EData.Visible = isValid;
quad.EData.TextureHandle =
isValid ? staticCards[card.RefCard.Idx].BoardTextureHandle : Gen::TextureHandle{};
quad.EData.DotColor = card.IsLocked ? Puzzle::GetStaticPuzzleData().Visuals.DisabledCardTint
: Vec4{1.0f, 1.0f, 1.0f, 1.0f};
quad.EData.DotColor =
isLocked ? Puzzle::GetStaticPuzzleData().Visuals.DisabledCardTint : Vec4{1.0f, 1.0f, 1.0f, 1.0f};
quad.EData.Transform.Scale = {UICardScale, UICardScale, UICardScale};
if (isValid && IsQuadHovered(quad.EData.Transform, StaticData.MousePosWorld, quadPlaneIntersectPos))
{
if (!card.IsLocked && DraggedCard.X == -1 && DraggedAvailableCardIdx == UINT16_MAX)
if (!isLocked && DraggedCard.X == -1 && DraggedAvailableCardIdx == UINT16_MAX)
{
if (GetMouseButtonPressedNow(MouseButton::Left))
{
@@ -318,8 +332,7 @@ namespace Game
if (GetMouseButtonPressedNow(MouseButton::Left) &&
IsQuadHovered(resetQuad.EData.Transform, StaticData.MousePosWorld, hoverPosWorld))
{
LOG_WARN("TODO!");
// TODO
Puzzle::ResetPuzzle(Data);
}
UpdateAvailableCards(Data);

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -127,12 +127,18 @@ type PuzzleCardStack
u8 UsedCount
}
enum PlacedPuzzleCardFlags(u8) Flags
{
None
Locked
}
type PlacedPuzzleCard
{
StaticPuzzleCardHandle RefCard
PuzPos Position
u8 Rotation
b IsLocked
PlacedPuzzleCardFlags Flags
}
type PuzzleData
@@ -144,6 +150,7 @@ type PuzzleData
u32 AvailableCardCount
PuzzleCardStack AvailableCards Arr(16)
PlacedPuzzleCard PlacedCards Arr(256)
PlacedPuzzleCard InitialPlacedCards Arr(256)
PuzzleElementType BackgroundTiles Arr(1024)
u32 GoalPositionCount
PuzPos GoalPositions Arr(16)

View File

@@ -23,6 +23,26 @@ namespace Gen
}
return isOk;
}
bool Save(const PlacedPuzzleCardFlags::Enum* obj, uint32_t count, Serializer& serializer)
{
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
auto val = (uint8_t)obj[i];
isOk = Save(&val, 1, serializer) && isOk;
}
return isOk;
}
bool Load(PlacedPuzzleCardFlags::Enum* obj, uint32_t count, Deserializer& serializer)
{
bool isOk = true;
for (int32_t i = 0; i < count; ++i)
{
uint8_t& val = (uint8_t&)obj[i];
isOk = Load(&val, 1, serializer) && isOk;
}
return isOk;
}
bool Save(const EMaterial::Enum* obj, uint32_t count, Serializer& serializer)
{
bool isOk = true;
@@ -291,6 +311,7 @@ namespace Gen
}
// Failed to resolve hash, the type definition chaned since the file was saved! try to match by name.
*obj = {};
int32_t nameMatchIdx = serializer.TypeBuf.FindDefByName(typeName);
if (nameMatchIdx < 0)
{
@@ -311,11 +332,11 @@ namespace Gen
{
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[i].Offset], matchedDef.MemberNameIndices[i].Size};
const char* memberTypeName = serializer.TypeBuf.Defs[matchedDef.ChildIndices[i]].Name;
if (bx::strCmp(memberName, "x") == 0 && bx::strCmp(memberTypeName, "float") == 0)
if (bx::strCmp(memberName, "x") == 0 && bx::strCmp(memberTypeName, "f32") == 0)
{
WriteDestinations[i] = offsetof(Vec2, x);
}
if (bx::strCmp(memberName, "y") == 0 && bx::strCmp(memberTypeName, "float") == 0)
if (bx::strCmp(memberName, "y") == 0 && bx::strCmp(memberTypeName, "f32") == 0)
{
WriteDestinations[i] = offsetof(Vec2, y);
}
@@ -391,6 +412,7 @@ namespace Gen
}
// Failed to resolve hash, the type definition chaned since the file was saved! try to match by name.
*obj = {};
int32_t nameMatchIdx = serializer.TypeBuf.FindDefByName(typeName);
if (nameMatchIdx < 0)
{
@@ -411,15 +433,15 @@ namespace Gen
{
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[i].Offset], matchedDef.MemberNameIndices[i].Size};
const char* memberTypeName = serializer.TypeBuf.Defs[matchedDef.ChildIndices[i]].Name;
if (bx::strCmp(memberName, "x") == 0 && bx::strCmp(memberTypeName, "float") == 0)
if (bx::strCmp(memberName, "x") == 0 && bx::strCmp(memberTypeName, "f32") == 0)
{
WriteDestinations[i] = offsetof(Vec3, x);
}
if (bx::strCmp(memberName, "y") == 0 && bx::strCmp(memberTypeName, "float") == 0)
if (bx::strCmp(memberName, "y") == 0 && bx::strCmp(memberTypeName, "f32") == 0)
{
WriteDestinations[i] = offsetof(Vec3, y);
}
if (bx::strCmp(memberName, "z") == 0 && bx::strCmp(memberTypeName, "float") == 0)
if (bx::strCmp(memberName, "z") == 0 && bx::strCmp(memberTypeName, "f32") == 0)
{
WriteDestinations[i] = offsetof(Vec3, z);
}
@@ -503,6 +525,7 @@ namespace Gen
}
// Failed to resolve hash, the type definition chaned since the file was saved! try to match by name.
*obj = {};
int32_t nameMatchIdx = serializer.TypeBuf.FindDefByName(typeName);
if (nameMatchIdx < 0)
{
@@ -523,19 +546,19 @@ namespace Gen
{
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[i].Offset], matchedDef.MemberNameIndices[i].Size};
const char* memberTypeName = serializer.TypeBuf.Defs[matchedDef.ChildIndices[i]].Name;
if (bx::strCmp(memberName, "x") == 0 && bx::strCmp(memberTypeName, "float") == 0)
if (bx::strCmp(memberName, "x") == 0 && bx::strCmp(memberTypeName, "f32") == 0)
{
WriteDestinations[i] = offsetof(Vec4, x);
}
if (bx::strCmp(memberName, "y") == 0 && bx::strCmp(memberTypeName, "float") == 0)
if (bx::strCmp(memberName, "y") == 0 && bx::strCmp(memberTypeName, "f32") == 0)
{
WriteDestinations[i] = offsetof(Vec4, y);
}
if (bx::strCmp(memberName, "z") == 0 && bx::strCmp(memberTypeName, "float") == 0)
if (bx::strCmp(memberName, "z") == 0 && bx::strCmp(memberTypeName, "f32") == 0)
{
WriteDestinations[i] = offsetof(Vec4, z);
}
if (bx::strCmp(memberName, "w") == 0 && bx::strCmp(memberTypeName, "float") == 0)
if (bx::strCmp(memberName, "w") == 0 && bx::strCmp(memberTypeName, "f32") == 0)
{
WriteDestinations[i] = offsetof(Vec4, w);
}
@@ -619,6 +642,7 @@ namespace Gen
}
// Failed to resolve hash, the type definition chaned since the file was saved! try to match by name.
*obj = {};
int32_t nameMatchIdx = serializer.TypeBuf.FindDefByName(typeName);
if (nameMatchIdx < 0)
{
@@ -639,7 +663,7 @@ namespace Gen
{
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[i].Offset], matchedDef.MemberNameIndices[i].Size};
const char* memberTypeName = serializer.TypeBuf.Defs[matchedDef.ChildIndices[i]].Name;
if (bx::strCmp(memberName, "M") == 0 && bx::strCmp(memberTypeName, "float") == 0)
if (bx::strCmp(memberName, "M") == 0 && bx::strCmp(memberTypeName, "f32") == 0)
{
WriteDestinations[i] = offsetof(Mat3, M);
}
@@ -705,6 +729,7 @@ namespace Gen
}
// Failed to resolve hash, the type definition chaned since the file was saved! try to match by name.
*obj = {};
int32_t nameMatchIdx = serializer.TypeBuf.FindDefByName(typeName);
if (nameMatchIdx < 0)
{
@@ -725,7 +750,7 @@ namespace Gen
{
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[i].Offset], matchedDef.MemberNameIndices[i].Size};
const char* memberTypeName = serializer.TypeBuf.Defs[matchedDef.ChildIndices[i]].Name;
if (bx::strCmp(memberName, "M") == 0 && bx::strCmp(memberTypeName, "float") == 0)
if (bx::strCmp(memberName, "M") == 0 && bx::strCmp(memberTypeName, "f32") == 0)
{
WriteDestinations[i] = offsetof(Mat4, M);
}
@@ -799,6 +824,7 @@ namespace Gen
}
// Failed to resolve hash, the type definition chaned since the file was saved! try to match by name.
*obj = {};
int32_t nameMatchIdx = serializer.TypeBuf.FindDefByName(typeName);
if (nameMatchIdx < 0)
{
@@ -925,6 +951,7 @@ namespace Gen
}
// Failed to resolve hash, the type definition chaned since the file was saved! try to match by name.
*obj = {};
int32_t nameMatchIdx = serializer.TypeBuf.FindDefByName(typeName);
if (nameMatchIdx < 0)
{
@@ -945,7 +972,7 @@ namespace Gen
{
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[i].Offset], matchedDef.MemberNameIndices[i].Size};
const char* memberTypeName = serializer.TypeBuf.Defs[matchedDef.ChildIndices[i]].Name;
if (bx::strCmp(memberName, "Idx") == 0 && bx::strCmp(memberTypeName, "uint32_t") == 0)
if (bx::strCmp(memberName, "Idx") == 0 && bx::strCmp(memberTypeName, "u32") == 0)
{
WriteDestinations[i] = offsetof(AssetHandle, Idx);
}
@@ -1013,6 +1040,7 @@ namespace Gen
}
// Failed to resolve hash, the type definition chaned since the file was saved! try to match by name.
*obj = {};
int32_t nameMatchIdx = serializer.TypeBuf.FindDefByName(typeName);
if (nameMatchIdx < 0)
{
@@ -1033,7 +1061,7 @@ namespace Gen
{
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[i].Offset], matchedDef.MemberNameIndices[i].Size};
const char* memberTypeName = serializer.TypeBuf.Defs[matchedDef.ChildIndices[i]].Name;
if (bx::strCmp(memberName, "ModelIdx") == 0 && bx::strCmp(memberTypeName, "uint16_t") == 0)
if (bx::strCmp(memberName, "ModelIdx") == 0 && bx::strCmp(memberTypeName, "u16") == 0)
{
WriteDestinations[i] = offsetof(ModelHandle, ModelIdx);
}
@@ -1111,6 +1139,7 @@ namespace Gen
}
// Failed to resolve hash, the type definition chaned since the file was saved! try to match by name.
*obj = {};
int32_t nameMatchIdx = serializer.TypeBuf.FindDefByName(typeName);
if (nameMatchIdx < 0)
{
@@ -1131,7 +1160,7 @@ namespace Gen
{
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[i].Offset], matchedDef.MemberNameIndices[i].Size};
const char* memberTypeName = serializer.TypeBuf.Defs[matchedDef.ChildIndices[i]].Name;
if (bx::strCmp(memberName, "TextureIdx") == 0 && bx::strCmp(memberTypeName, "uint16_t") == 0)
if (bx::strCmp(memberName, "TextureIdx") == 0 && bx::strCmp(memberTypeName, "u16") == 0)
{
WriteDestinations[i] = offsetof(TextureHandle, TextureIdx);
}
@@ -1209,6 +1238,7 @@ namespace Gen
}
// Failed to resolve hash, the type definition chaned since the file was saved! try to match by name.
*obj = {};
int32_t nameMatchIdx = serializer.TypeBuf.FindDefByName(typeName);
if (nameMatchIdx < 0)
{
@@ -1229,11 +1259,11 @@ namespace Gen
{
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[i].Offset], matchedDef.MemberNameIndices[i].Size};
const char* memberTypeName = serializer.TypeBuf.Defs[matchedDef.ChildIndices[i]].Name;
if (bx::strCmp(memberName, "X") == 0 && bx::strCmp(memberTypeName, "int8_t") == 0)
if (bx::strCmp(memberName, "X") == 0 && bx::strCmp(memberTypeName, "i8") == 0)
{
WriteDestinations[i] = offsetof(PuzPos, X);
}
if (bx::strCmp(memberName, "Y") == 0 && bx::strCmp(memberTypeName, "int8_t") == 0)
if (bx::strCmp(memberName, "Y") == 0 && bx::strCmp(memberTypeName, "i8") == 0)
{
WriteDestinations[i] = offsetof(PuzPos, Y);
}
@@ -1307,6 +1337,7 @@ namespace Gen
}
// Failed to resolve hash, the type definition chaned since the file was saved! try to match by name.
*obj = {};
int32_t nameMatchIdx = serializer.TypeBuf.FindDefByName(typeName);
if (nameMatchIdx < 0)
{
@@ -1331,7 +1362,7 @@ namespace Gen
{
WriteDestinations[i] = offsetof(CardSocket, Model);
}
if (bx::strCmp(memberName, "ConnectionDirection") == 0 && bx::strCmp(memberTypeName, "uint8_t") == 0)
if (bx::strCmp(memberName, "ConnectionDirection") == 0 && bx::strCmp(memberTypeName, "u8") == 0)
{
WriteDestinations[i] = offsetof(CardSocket, ConnectionDirection);
}
@@ -1419,6 +1450,7 @@ namespace Gen
}
// Failed to resolve hash, the type definition chaned since the file was saved! try to match by name.
*obj = {};
int32_t nameMatchIdx = serializer.TypeBuf.FindDefByName(typeName);
if (nameMatchIdx < 0)
{
@@ -1585,6 +1617,7 @@ namespace Gen
}
// Failed to resolve hash, the type definition chaned since the file was saved! try to match by name.
*obj = {};
int32_t nameMatchIdx = serializer.TypeBuf.FindDefByName(typeName);
if (nameMatchIdx < 0)
{
@@ -1605,7 +1638,7 @@ namespace Gen
{
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[i].Offset], matchedDef.MemberNameIndices[i].Size};
const char* memberTypeName = serializer.TypeBuf.Defs[matchedDef.ChildIndices[i]].Name;
if (bx::strCmp(memberName, "Idx") == 0 && bx::strCmp(memberTypeName, "uint16_t") == 0)
if (bx::strCmp(memberName, "Idx") == 0 && bx::strCmp(memberTypeName, "u16") == 0)
{
WriteDestinations[i] = offsetof(StaticPuzzleCardHandle, Idx);
}
@@ -1677,6 +1710,7 @@ namespace Gen
}
// Failed to resolve hash, the type definition chaned since the file was saved! try to match by name.
*obj = {};
int32_t nameMatchIdx = serializer.TypeBuf.FindDefByName(typeName);
if (nameMatchIdx < 0)
{
@@ -1795,6 +1829,7 @@ namespace Gen
}
// Failed to resolve hash, the type definition chaned since the file was saved! try to match by name.
*obj = {};
int32_t nameMatchIdx = serializer.TypeBuf.FindDefByName(typeName);
if (nameMatchIdx < 0)
{
@@ -1895,6 +1930,7 @@ namespace Gen
}
// Failed to resolve hash, the type definition chaned since the file was saved! try to match by name.
*obj = {};
int32_t nameMatchIdx = serializer.TypeBuf.FindDefByName(typeName);
if (nameMatchIdx < 0)
{
@@ -1919,11 +1955,11 @@ namespace Gen
{
WriteDestinations[i] = offsetof(PuzzleCardStack, RefCard);
}
if (bx::strCmp(memberName, "MaxAvailableCount") == 0 && bx::strCmp(memberTypeName, "uint8_t") == 0)
if (bx::strCmp(memberName, "MaxAvailableCount") == 0 && bx::strCmp(memberTypeName, "u8") == 0)
{
WriteDestinations[i] = offsetof(PuzzleCardStack, MaxAvailableCount);
}
if (bx::strCmp(memberName, "UsedCount") == 0 && bx::strCmp(memberTypeName, "uint8_t") == 0)
if (bx::strCmp(memberName, "UsedCount") == 0 && bx::strCmp(memberTypeName, "u8") == 0)
{
WriteDestinations[i] = offsetof(PuzzleCardStack, UsedCount);
}
@@ -1979,7 +2015,7 @@ namespace Gen
isOk = Save(&obj[i].RefCard, 1, serializer) && isOk;
isOk = Save(&obj[i].Position, 1, serializer) && isOk;
isOk = Save(&obj[i].Rotation, 1, serializer) && isOk;
isOk = Save(&obj[i].IsLocked, 1, serializer) && isOk;
isOk = Save(&obj[i].Flags, 1, serializer) && isOk;
}
return isOk;
}
@@ -1999,7 +2035,7 @@ namespace Gen
isOk = Load(&obj[i].RefCard, 1, serializer) && isOk;
isOk = Load(&obj[i].Position, 1, serializer) && isOk;
isOk = Load(&obj[i].Rotation, 1, serializer) && isOk;
isOk = Load(&obj[i].IsLocked, 1, serializer) && isOk;
isOk = Load(&obj[i].Flags, 1, serializer) && isOk;
}
// if we're not ok here, something went really wrong
assert(isOk);
@@ -2007,6 +2043,7 @@ namespace Gen
}
// Failed to resolve hash, the type definition chaned since the file was saved! try to match by name.
*obj = {};
int32_t nameMatchIdx = serializer.TypeBuf.FindDefByName(typeName);
if (nameMatchIdx < 0)
{
@@ -2035,13 +2072,13 @@ namespace Gen
{
WriteDestinations[i] = offsetof(PlacedPuzzleCard, Position);
}
if (bx::strCmp(memberName, "Rotation") == 0 && bx::strCmp(memberTypeName, "uint8_t") == 0)
if (bx::strCmp(memberName, "Rotation") == 0 && bx::strCmp(memberTypeName, "u8") == 0)
{
WriteDestinations[i] = offsetof(PlacedPuzzleCard, Rotation);
}
if (bx::strCmp(memberName, "IsLocked") == 0 && bx::strCmp(memberTypeName, "bool") == 0)
if (bx::strCmp(memberName, "Flags") == 0 && bx::strCmp(memberTypeName, "PlacedPuzzleCardFlags") == 0)
{
WriteDestinations[i] = offsetof(PlacedPuzzleCard, IsLocked);
WriteDestinations[i] = offsetof(PlacedPuzzleCard, Flags);
}
}
@@ -2081,9 +2118,9 @@ namespace Gen
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "IsLocked") == 0)
if (bx::strCmp(memberName, "Flags") == 0)
{
auto* fieldPtr = reinterpret_cast<bool*>(objBasePtr + WriteDestinations[j]);
auto* fieldPtr = reinterpret_cast<PlacedPuzzleCardFlags::Enum*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
@@ -2105,6 +2142,7 @@ namespace Gen
isOk = Save(&obj[i].AvailableCardCount, 1, serializer) && isOk;
isOk = Save(obj[i].AvailableCards, 16, serializer) && isOk;
isOk = Save(obj[i].PlacedCards, 256, serializer) && isOk;
isOk = Save(obj[i].InitialPlacedCards, 256, serializer) && isOk;
isOk = Save(obj[i].BackgroundTiles, 1024, serializer) && isOk;
isOk = Save(&obj[i].GoalPositionCount, 1, serializer) && isOk;
isOk = Save(obj[i].GoalPositions, 16, serializer) && isOk;
@@ -2131,6 +2169,7 @@ namespace Gen
isOk = Load(&obj[i].AvailableCardCount, 1, serializer) && isOk;
isOk = Load(obj[i].AvailableCards, 16, serializer) && isOk;
isOk = Load(obj[i].PlacedCards, 256, serializer) && isOk;
isOk = Load(obj[i].InitialPlacedCards, 256, serializer) && isOk;
isOk = Load(obj[i].BackgroundTiles, 1024, serializer) && isOk;
isOk = Load(&obj[i].GoalPositionCount, 1, serializer) && isOk;
isOk = Load(obj[i].GoalPositions, 16, serializer) && isOk;
@@ -2141,6 +2180,7 @@ namespace Gen
}
// Failed to resolve hash, the type definition chaned since the file was saved! try to match by name.
*obj = {};
int32_t nameMatchIdx = serializer.TypeBuf.FindDefByName(typeName);
if (nameMatchIdx < 0)
{
@@ -2161,23 +2201,23 @@ namespace Gen
{
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[i].Offset], matchedDef.MemberNameIndices[i].Size};
const char* memberTypeName = serializer.TypeBuf.Defs[matchedDef.ChildIndices[i]].Name;
if (bx::strCmp(memberName, "ID") == 0 && bx::strCmp(memberTypeName, "uint16_t") == 0)
if (bx::strCmp(memberName, "ID") == 0 && bx::strCmp(memberTypeName, "u16") == 0)
{
WriteDestinations[i] = offsetof(PuzzleData, ID);
}
if (bx::strCmp(memberName, "PuzzleName") == 0 && bx::strCmp(memberTypeName, "char") == 0)
if (bx::strCmp(memberName, "PuzzleName") == 0 && bx::strCmp(memberTypeName, "str") == 0)
{
WriteDestinations[i] = offsetof(PuzzleData, PuzzleName);
}
if (bx::strCmp(memberName, "WidthTiles") == 0 && bx::strCmp(memberTypeName, "uint8_t") == 0)
if (bx::strCmp(memberName, "WidthTiles") == 0 && bx::strCmp(memberTypeName, "u8") == 0)
{
WriteDestinations[i] = offsetof(PuzzleData, WidthTiles);
}
if (bx::strCmp(memberName, "HeightTiles") == 0 && bx::strCmp(memberTypeName, "uint8_t") == 0)
if (bx::strCmp(memberName, "HeightTiles") == 0 && bx::strCmp(memberTypeName, "u8") == 0)
{
WriteDestinations[i] = offsetof(PuzzleData, HeightTiles);
}
if (bx::strCmp(memberName, "AvailableCardCount") == 0 && bx::strCmp(memberTypeName, "uint32_t") == 0)
if (bx::strCmp(memberName, "AvailableCardCount") == 0 && bx::strCmp(memberTypeName, "u32") == 0)
{
WriteDestinations[i] = offsetof(PuzzleData, AvailableCardCount);
}
@@ -2189,11 +2229,15 @@ namespace Gen
{
WriteDestinations[i] = offsetof(PuzzleData, PlacedCards);
}
if (bx::strCmp(memberName, "InitialPlacedCards") == 0 && bx::strCmp(memberTypeName, "PlacedPuzzleCard") == 0)
{
WriteDestinations[i] = offsetof(PuzzleData, InitialPlacedCards);
}
if (bx::strCmp(memberName, "BackgroundTiles") == 0 && bx::strCmp(memberTypeName, "PuzzleElementType") == 0)
{
WriteDestinations[i] = offsetof(PuzzleData, BackgroundTiles);
}
if (bx::strCmp(memberName, "GoalPositionCount") == 0 && bx::strCmp(memberTypeName, "uint32_t") == 0)
if (bx::strCmp(memberName, "GoalPositionCount") == 0 && bx::strCmp(memberTypeName, "u32") == 0)
{
WriteDestinations[i] = offsetof(PuzzleData, GoalPositionCount);
}
@@ -2263,6 +2307,12 @@ namespace Gen
isOk = Load(fieldPtr, 256, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "InitialPlacedCards") == 0)
{
auto* fieldPtr = reinterpret_cast<PlacedPuzzleCard*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 256, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "BackgroundTiles") == 0)
{
auto* fieldPtr = reinterpret_cast<PuzzleElementType::Enum*>(objBasePtr + WriteDestinations[j]);
@@ -2329,6 +2379,7 @@ namespace Gen
}
// Failed to resolve hash, the type definition chaned since the file was saved! try to match by name.
*obj = {};
int32_t nameMatchIdx = serializer.TypeBuf.FindDefByName(typeName);
if (nameMatchIdx < 0)
{
@@ -2373,7 +2424,7 @@ namespace Gen
{
WriteDestinations[i] = offsetof(SavedEntityRenderData, Model);
}
if (bx::strCmp(memberName, "Visible") == 0 && bx::strCmp(memberTypeName, "bool") == 0)
if (bx::strCmp(memberName, "Visible") == 0 && bx::strCmp(memberTypeName, "b") == 0)
{
WriteDestinations[i] = offsetof(SavedEntityRenderData, Visible);
}
@@ -2483,6 +2534,7 @@ namespace Gen
}
// Failed to resolve hash, the type definition chaned since the file was saved! try to match by name.
*obj = {};
int32_t nameMatchIdx = serializer.TypeBuf.FindDefByName(typeName);
if (nameMatchIdx < 0)
{

View File

@@ -54,10 +54,41 @@ namespace Gen
"#",
};
};
struct EMaterial
struct PlacedPuzzleCardFlags
{
static constexpr uint16_t TypeIdx = 33;
static constexpr int32_t EntryCount = 2;
enum Enum : uint8_t
{
None = 0,
Locked = 1 << 0,
};
static constexpr char EntryNames[EntryCount][64]
{
"None",
"Locked",
};
};
inline PlacedPuzzleCardFlags::Enum operator| (const PlacedPuzzleCardFlags::Enum& a, const PlacedPuzzleCardFlags::Enum& b)
{
return a | b;
}
inline PlacedPuzzleCardFlags::Enum operator& (const PlacedPuzzleCardFlags::Enum& a, const PlacedPuzzleCardFlags::Enum& b)
{
return a & b;
}
inline PlacedPuzzleCardFlags::Enum operator|= (PlacedPuzzleCardFlags::Enum& a, const PlacedPuzzleCardFlags::Enum& b)
{
return a |= b;
}
inline PlacedPuzzleCardFlags::Enum operator&= (PlacedPuzzleCardFlags::Enum& a, const PlacedPuzzleCardFlags::Enum& b)
{
return a &= b;
}
struct EMaterial
{
static constexpr uint16_t TypeIdx = 34;
static constexpr int32_t EntryCount = 2;
enum Enum : int32_t
{
Default,
@@ -192,7 +223,7 @@ namespace Gen
StaticPuzzleCardHandle RefCard = {};
PuzPos Position = {};
uint8_t Rotation = {};
bool IsLocked = {};
PlacedPuzzleCardFlags::Enum Flags = {};
};
struct PuzzleData
{
@@ -204,6 +235,7 @@ namespace Gen
uint32_t AvailableCardCount = {};
PuzzleCardStack AvailableCards[16] = {};
PlacedPuzzleCard PlacedCards[256] = {};
PlacedPuzzleCard InitialPlacedCards[256] = {};
PuzzleElementType::Enum BackgroundTiles[1024] = {};
uint32_t GoalPositionCount = {};
PuzPos GoalPositions[16] = {};
@@ -230,6 +262,8 @@ namespace Gen
};
bool Save(const PuzzleElementType::Enum* obj, uint32_t count, Serializer& serializer);
bool Load(PuzzleElementType::Enum* obj, uint32_t count, Deserializer& serializer);
bool Save(const PlacedPuzzleCardFlags::Enum* obj, uint32_t count, Serializer& serializer);
bool Load(PlacedPuzzleCardFlags::Enum* obj, uint32_t count, Deserializer& serializer);
bool Save(const EMaterial::Enum* obj, uint32_t count, Serializer& serializer);
bool Load(EMaterial::Enum* obj, uint32_t count, Deserializer& serializer);
bool Save(const int8_t* obj, uint32_t count, Serializer& serializer);
@@ -319,7 +353,7 @@ namespace Gen
struct MetadataTable
{
TypeDef TypeDefinitions[34]
TypeDef TypeDefinitions[35]
{
TypeDef{sizeof(int8_t), 0, "i8", 0, {}, {}, {}},
TypeDef{sizeof(int16_t), 1, "i16", 0, {}, {}, {}},
@@ -349,14 +383,15 @@ namespace Gen
TypeDef{sizeof(PuzzleVisualSettings), 2302077481, "PuzzleVisualSettings", 4, {14, 14, 13, 14}, {0, 0, 0, 0}, {{223, 13}, {236, 12}, {248, 4}, {252, 16}}},
TypeDef{sizeof(StaticPuzzleData), 2637647137, "StaticPuzzleData", 2, {23, 25}, {64, 0}, {{268, 5}, {273, 7}}},
TypeDef{sizeof(PuzzleCardStack), 53538532, "PuzzleCardStack", 3, {24, 4, 4}, {0, 0, 0}, {{280, 7}, {287, 17}, {304, 9}}},
TypeDef{sizeof(PlacedPuzzleCard), 3555575973, "PlacedPuzzleCard", 4, {24, 21, 4, 8}, {0, 0, 0, 0}, {{313, 7}, {320, 8}, {328, 8}, {336, 8}}},
TypeDef{sizeof(PuzzleData), 3349686056, "PuzzleData", 10, {5, 11, 4, 4, 6, 27, 28, 32, 6, 21}, {0, 64, 0, 0, 0, 16, 256, 1024, 0, 16}, {{344, 2}, {346, 10}, {356, 10}, {366, 11}, {377, 18}, {395, 14}, {409, 11}, {420, 15}, {435, 17}, {452, 13}}},
TypeDef{sizeof(SavedEntityRenderData), 3172756855, "SavedEntityRenderData", 7, {14, 14, 17, 33, 20, 19, 8}, {0, 0, 0, 0, 0, 0, 0}, {{465, 9}, {474, 14}, {488, 2}, {490, 8}, {498, 7}, {505, 5}, {510, 7}}},
TypeDef{sizeof(SavedPlayerConfig), 3685229621, "SavedPlayerConfig", 5, {30, 30, 20, 20, 30}, {0, 0, 0, 0, 0}, {{517, 26}, {543, 22}, {565, 28}, {593, 25}, {618, 21}}},
TypeDef{sizeof(PlacedPuzzleCard), 838818025, "PlacedPuzzleCard", 4, {24, 21, 4, 33}, {0, 0, 0, 0}, {{313, 7}, {320, 8}, {328, 8}, {336, 5}}},
TypeDef{sizeof(PuzzleData), 1562434765, "PuzzleData", 11, {5, 11, 4, 4, 6, 27, 28, 28, 32, 6, 21}, {0, 64, 0, 0, 0, 16, 256, 256, 1024, 0, 16}, {{341, 2}, {343, 10}, {353, 10}, {363, 11}, {374, 18}, {392, 14}, {406, 11}, {417, 18}, {435, 15}, {450, 17}, {467, 13}}},
TypeDef{sizeof(SavedEntityRenderData), 3172756855, "SavedEntityRenderData", 7, {14, 14, 17, 34, 20, 19, 8}, {0, 0, 0, 0, 0, 0, 0}, {{480, 9}, {489, 14}, {503, 2}, {505, 8}, {513, 7}, {520, 5}, {525, 7}}},
TypeDef{sizeof(SavedPlayerConfig), 3685229621, "SavedPlayerConfig", 5, {30, 30, 20, 20, 30}, {0, 0, 0, 0, 0}, {{532, 26}, {558, 22}, {580, 28}, {608, 25}, {633, 21}}},
TypeDef{sizeof(PuzzleElementType::Enum), 2983807453, "PuzzleElementType", 0, {}, {}, {}},
TypeDef{sizeof(PlacedPuzzleCardFlags::Enum), 2983807453, "PlacedPuzzleCardFlags", 0, {}, {}, {}},
TypeDef{sizeof(EMaterial::Enum), 2024002654, "EMaterial", 0, {}, {}, {}},
};
char MemberNameBuffer[64*64*64]{"xyxyzxyzwMMMMIPositionRotationScaleIdxModelIdxAssetTextureIdxAssetXYModelConnectionDirectionElementsBaseModelHandleNorthCoverHandleEastCoverHandleSouthCoverHandleWestCoverHandleSocketsModelTextureHandleBoardTextureHandleIdxTileBaseColorTileDotColorTestDisabledCardTintCardsVisualsRefCardMaxAvailableCountUsedCountRefCardPositionRotationIsLockedIDPuzzleNameWidthTilesHeightTilesAvailableCardCountAvailableCardsPlacedCardsBackgroundTilesGoalPositionCountGoalPositionsBaseColorHighlightColorTFMaterialTextureModelVisibleTabletBackgroundRenderDataTabletStatusRenderDataTabletStatusNotSolvedTextureTabletStatusSolvedTextureTabletResetRenderData"};
char MemberNameBuffer[64*64*64]{"xyxyzxyzwMMMMIPositionRotationScaleIdxModelIdxAssetTextureIdxAssetXYModelConnectionDirectionElementsBaseModelHandleNorthCoverHandleEastCoverHandleSouthCoverHandleWestCoverHandleSocketsModelTextureHandleBoardTextureHandleIdxTileBaseColorTileDotColorTestDisabledCardTintCardsVisualsRefCardMaxAvailableCountUsedCountRefCardPositionRotationFlagsIDPuzzleNameWidthTilesHeightTilesAvailableCardCountAvailableCardsPlacedCardsInitialPlacedCardsBackgroundTilesGoalPositionCountGoalPositionsBaseColorHighlightColorTFMaterialTextureModelVisibleTabletBackgroundRenderDataTabletStatusRenderDataTabletStatusNotSolvedTextureTabletStatusSolvedTextureTabletResetRenderData"};
};
constexpr MetadataTable Metadata;