refactor
This commit is contained in:
151
src/game/Entity.h
Normal file
151
src/game/Entity.h
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../gen/Generated.h"
|
||||||
|
#include "Log.h"
|
||||||
|
#include "Puzzle.h" // TODO: remove
|
||||||
|
#include "rendering/Rendering.h"
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#define ENTITY_HANDLE(X) \
|
||||||
|
struct X \
|
||||||
|
{ \
|
||||||
|
uint16_t Idx = UINT16_MAX; \
|
||||||
|
}; \
|
||||||
|
inline bool IsValid(X h) \
|
||||||
|
{ \
|
||||||
|
return h.Idx != UINT16_MAX; \
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Game
|
||||||
|
{
|
||||||
|
struct EntityRenderData
|
||||||
|
{
|
||||||
|
Gen::Vec4 DotColor{1.0f, 1.0f, 1.0f, 1.0f};
|
||||||
|
Gen::Vec4 BaseColor{0.0f, 0.0f, 0.0f, 1.0f};
|
||||||
|
Gen::Transform Transform;
|
||||||
|
Gen::EMaterial::Enum MaterialHandle = Gen::EMaterial::UI;
|
||||||
|
Gen::TextureHandle TextureHandle;
|
||||||
|
Gen::ModelHandle ModelH;
|
||||||
|
bool Visible = true;
|
||||||
|
|
||||||
|
void Render(const Model* models, const Material* materials, const Texture* textures);
|
||||||
|
void LoadFromSaved(const Gen::SavedEntityRenderData& saved);
|
||||||
|
};
|
||||||
|
|
||||||
|
ENTITY_HANDLE(CubeHandle);
|
||||||
|
struct Cube
|
||||||
|
{
|
||||||
|
int32_t TestX = -1;
|
||||||
|
int32_t TestY = -1;
|
||||||
|
EntityRenderData EData;
|
||||||
|
|
||||||
|
void Setup();
|
||||||
|
void Update();
|
||||||
|
};
|
||||||
|
|
||||||
|
ENTITY_HANDLE(TestEntityHandle);
|
||||||
|
struct TestEntity
|
||||||
|
{
|
||||||
|
EntityRenderData EData;
|
||||||
|
|
||||||
|
void Setup();
|
||||||
|
};
|
||||||
|
|
||||||
|
ENTITY_HANDLE(PuzzleTileEntityHandle);
|
||||||
|
struct PuzzleTileEntity
|
||||||
|
{
|
||||||
|
EntityRenderData EData;
|
||||||
|
};
|
||||||
|
|
||||||
|
ENTITY_HANDLE(PuzzleTileCoverHandle);
|
||||||
|
struct PuzzleTileCover
|
||||||
|
{
|
||||||
|
EntityRenderData EData;
|
||||||
|
};
|
||||||
|
|
||||||
|
ENTITY_HANDLE(UIQuadEntityHandle);
|
||||||
|
struct UIQuadEntity
|
||||||
|
{
|
||||||
|
EntityRenderData EData;
|
||||||
|
Gen::Vec3 UIPos;
|
||||||
|
float UIRot = 0.0f;
|
||||||
|
};
|
||||||
|
|
||||||
|
ENTITY_HANDLE(LevelEntityHandle);
|
||||||
|
struct LevelEntity
|
||||||
|
{
|
||||||
|
EntityRenderData EData;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IEntityManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual bool Setup(uint8_t*& ptr, bool forceReset) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename HandleT, uint32_t C> class EntityManager : public IEntityManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
uint16_t Count = 0;
|
||||||
|
T* Data = nullptr;
|
||||||
|
uint32_t EntitySize = 0;
|
||||||
|
T InvalidObject{};
|
||||||
|
bool IsEnabled = true;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Returns true if size changed
|
||||||
|
bool Setup(uint8_t*& ptr, bool forceReset)
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
if (EntitySize != sizeof(T) || forceReset)
|
||||||
|
{
|
||||||
|
Count = 0;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
EntitySize = sizeof(T);
|
||||||
|
Data = reinterpret_cast<T*>(ptr);
|
||||||
|
ptr += C * EntitySize;
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
HandleT New()
|
||||||
|
{
|
||||||
|
if (Data == nullptr)
|
||||||
|
{
|
||||||
|
ERROR_ONCE("Accessed EntityManager before setup!");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
if (Count >= C)
|
||||||
|
{
|
||||||
|
ERROR_ONCE("Too many entities!");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
Data[Count] = {};
|
||||||
|
HandleT H;
|
||||||
|
H.Idx = Count;
|
||||||
|
++Count;
|
||||||
|
return H;
|
||||||
|
}
|
||||||
|
|
||||||
|
T& Get(HandleT handle)
|
||||||
|
{
|
||||||
|
if (handle.Idx >= Count)
|
||||||
|
{
|
||||||
|
ERROR_ONCE("OOB Access!");
|
||||||
|
return InvalidObject;
|
||||||
|
}
|
||||||
|
return Data[handle.Idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Render(const Model* models, const Material* materials, const Texture* textures)
|
||||||
|
{
|
||||||
|
if (!IsEnabled) return;
|
||||||
|
for (uint16_t i = 0; i < Count; ++i)
|
||||||
|
{
|
||||||
|
Get({i}).EData.Render(models, materials, textures);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef EntityManager<UIQuadEntity, UIQuadEntityHandle, Puzzle::Config::MaxTilesInPuzzle * 2> UIQuadEntityManager;
|
||||||
|
} // namespace Game
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "Level.h"
|
#include "Level.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "Puzzle.h"
|
#include "Puzzle.h"
|
||||||
|
#include "UI.h"
|
||||||
#include "bx/bx.h"
|
#include "bx/bx.h"
|
||||||
#include "rendering/Rendering.h"
|
#include "rendering/Rendering.h"
|
||||||
|
|
||||||
@@ -189,6 +190,7 @@ namespace Game
|
|||||||
Puzzles[i].Setup();
|
Puzzles[i].Setup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
PuzzleUI.Setup();
|
||||||
TabletHandle = UIQuads.New();
|
TabletHandle = UIQuads.New();
|
||||||
UpdatePlayerInputMode();
|
UpdatePlayerInputMode();
|
||||||
|
|
||||||
@@ -286,12 +288,17 @@ namespace Game
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Puzzle tiles
|
// Puzzle tiles
|
||||||
|
uint16_t activeIdx = GetInstance().DebugData.SelectedDebugLevel;
|
||||||
for (int32_t i = 0; i < BX_COUNTOF(Puzzles); ++i)
|
for (int32_t i = 0; i < BX_COUNTOF(Puzzles); ++i)
|
||||||
{
|
{
|
||||||
Puzzles[i].IsActive = GetInstance().DebugData.SelectedDebugLevel == i;
|
Puzzles[i].IsActive = activeIdx == i;
|
||||||
Puzzles[i].Update();
|
Puzzles[i].Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Puzzle::PuzzleSolver solver;
|
||||||
|
bool isPuzzleSolved = solver.IsPuzzleSolved(Puzzles[activeIdx].Data);
|
||||||
|
PuzzleUI.Update(Puzzles[activeIdx].Data, isPuzzleSolved);
|
||||||
|
|
||||||
END_PERF(GetShared().Window.PerfCounters, PerfCounterType::GameLevelUpdate, GetShared().Window.FrameCounter);
|
END_PERF(GetShared().Window.PerfCounters, PerfCounterType::GameLevelUpdate, GetShared().Window.FrameCounter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -369,187 +376,18 @@ namespace Game
|
|||||||
auto& cover = level.PuzzleTileCovers.Get(CoverHandles[idx]);
|
auto& cover = level.PuzzleTileCovers.Get(CoverHandles[idx]);
|
||||||
cover.EData.Visible = false;
|
cover.EData.Visible = false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
UIPlacedCards[i] = level.UIQuads.New();
|
|
||||||
auto& quad = level.UIQuads.Get(UIPlacedCards[i]);
|
|
||||||
quad.EData.ModelH = GameRendering::Get().GetModelHandleFromPath("models/plane.glb");
|
|
||||||
quad.EData.MaterialHandle = EMaterial::UI;
|
|
||||||
}
|
|
||||||
for (int32_t i = 0; i < Puzzle::Config::MaxAvailableStacks * WorldPuzzle::UIAvailableCardMaxStackPreview; ++i)
|
|
||||||
{
|
|
||||||
UIAvailableCards[i] = level.UIQuads.New();
|
|
||||||
auto& quad = level.UIQuads.Get(UIAvailableCards[i]);
|
|
||||||
quad.EData.MaterialHandle = EMaterial::UI;
|
|
||||||
quad.EData.ModelH = GameRendering::Get().GetModelHandleFromPath("models/plane.glb");
|
|
||||||
}
|
|
||||||
SolvedQuad = level.UIQuads.New();
|
|
||||||
ResetQuad = level.UIQuads.New();
|
|
||||||
IsSetup = true;
|
IsSetup = true;
|
||||||
LOG("finished setup!");
|
LOG("finished setup!");
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec3 GetMousePosWorld()
|
|
||||||
{
|
|
||||||
auto& window = GetShared().Window;
|
|
||||||
Vec2 mousePos = GetMousePos();
|
|
||||||
mousePos.x = mousePos.x / window.WindowWidth;
|
|
||||||
mousePos.y = mousePos.y / window.WindowHeight;
|
|
||||||
mousePos *= 2.0f;
|
|
||||||
mousePos -= 1.0f;
|
|
||||||
Vec4 mousePosView = {mousePos.x, -mousePos.y, 0.0f, 1.0f};
|
|
||||||
Vec4 mousePosCam4 = Mul(GetInstance().Player.ProjectionInverse, mousePosView);
|
|
||||||
Vec3 mousePosCam = Vec3{
|
|
||||||
mousePosCam4.x /= mousePosCam4.w,
|
|
||||||
mousePosCam4.y /= mousePosCam4.w,
|
|
||||||
mousePosCam4.z /= mousePosCam4.w,
|
|
||||||
};
|
|
||||||
|
|
||||||
return LocalToGlobalPoint(GetInstance().Player.PlayerCamTransform, mousePosCam);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsQuadHovered(Transform& quadTransform, Vec3 mousePosWorld, Vec3& outQuadPlaneIntersectPos)
|
|
||||||
{
|
|
||||||
Vec3 quadPosWorld = quadTransform.Position;
|
|
||||||
Vec3 quadXWorld = LocalToGlobalPoint(quadTransform, {1, 0, 0});
|
|
||||||
Vec3 quadZWorld = LocalToGlobalPoint(quadTransform, {0, 0, 1});
|
|
||||||
if (RayPlaneIntersect(GetInstance().Player.PlayerCamTransform.Position,
|
|
||||||
mousePosWorld,
|
|
||||||
quadPosWorld,
|
|
||||||
quadXWorld,
|
|
||||||
quadZWorld,
|
|
||||||
outQuadPlaneIntersectPos))
|
|
||||||
{
|
|
||||||
Vec3 quadSpaceIntersect = GlobalToLocalPoint(quadTransform, outQuadPlaneIntersectPos);
|
|
||||||
if (quadSpaceIntersect.x >= -1.0f && quadSpaceIntersect.x <= 1.0f && quadSpaceIntersect.z >= -1.0f &&
|
|
||||||
quadSpaceIntersect.z <= 1.0f)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void WorldPuzzle::Update()
|
void WorldPuzzle::Update()
|
||||||
{
|
{
|
||||||
Level& level = GetInstance().GameLevel;
|
Level& level = GetInstance().GameLevel;
|
||||||
auto& staticCards = Puzzle::GetStaticPuzzleData().Cards;
|
auto& staticCards = Puzzle::GetStaticPuzzleData().Cards;
|
||||||
auto& visuals = Puzzle::GetStaticPuzzleData().Visuals;
|
auto& visuals = Puzzle::GetStaticPuzzleData().Visuals;
|
||||||
|
|
||||||
Transform& camTransform = GetInstance().Player.PlayerCamTransform;
|
|
||||||
UpdateMatrix(camTransform);
|
|
||||||
Vec3 cameraPos = camTransform.Position;
|
|
||||||
|
|
||||||
// TODO: disable warning & check if parentheses make sense like this
|
|
||||||
Vec2 uiOffset = Vec2{static_cast<float>(Data.WidthTiles / Puzzle::Config::CardSize) - 1,
|
|
||||||
static_cast<float>(Data.HeightTiles / Puzzle::Config::CardSize) - 1};
|
|
||||||
uiOffset *= -UICardOffset * 0.5f;
|
|
||||||
|
|
||||||
Transform& boardTransform = level.UIQuads.Get(level.TabletHandle).EData.Transform;
|
|
||||||
Transform tileOriginTransform = boardTransform;
|
|
||||||
tileOriginTransform.Position += AxisForward(camTransform.M) * -0.01f;
|
|
||||||
TranslateLocal(tileOriginTransform, Vec3{uiOffset.x, 0.0f, uiOffset.y} * 1.0f);
|
|
||||||
UpdateMatrix(tileOriginTransform);
|
|
||||||
|
|
||||||
Vec3 mousePosWorld = GetMousePosWorld();
|
|
||||||
Vec3 quadPlaneIntersectPos;
|
|
||||||
|
|
||||||
Puzzle::PuzzleSolver solver;
|
|
||||||
EntityRenderData solvedData;
|
|
||||||
solvedData.LoadFromSaved(GetInstance().Player.Config.TabletStatusRenderData);
|
|
||||||
auto& solvedQuad = level.UIQuads.Get(SolvedQuad);
|
|
||||||
solvedQuad.EData = solvedData;
|
|
||||||
solvedQuad.EData.Visible = IsActive;
|
|
||||||
solvedQuad.EData.TextureHandle = solver.IsPuzzleSolved(Data)
|
|
||||||
? GetInstance().Player.Config.TabletStatusSolvedTexture
|
|
||||||
: solvedData.TextureHandle;
|
|
||||||
solvedQuad.EData.Transform.Position = tileOriginTransform.Position;
|
|
||||||
solvedQuad.EData.Transform.Rotation = camTransform.Rotation;
|
|
||||||
TranslateLocal(solvedQuad.EData.Transform, solvedData.Transform.Position);
|
|
||||||
Rotate(solvedQuad.EData.Transform, Vec3{bx::kPi * 0.5f, 0.0f, (1.0f - 0 * 0.5f) * bx::kPi});
|
|
||||||
|
|
||||||
EntityRenderData resetData;
|
|
||||||
resetData.LoadFromSaved(GetInstance().Player.Config.TabletResetRenderData);
|
|
||||||
auto& resetQuad = level.UIQuads.Get(ResetQuad);
|
|
||||||
resetQuad.EData = resetData;
|
|
||||||
resetQuad.EData.Visible = IsActive;
|
|
||||||
resetQuad.EData.Transform.Position = tileOriginTransform.Position;
|
|
||||||
resetQuad.EData.Transform.Rotation = camTransform.Rotation;
|
|
||||||
TranslateLocal(resetQuad.EData.Transform, resetData.Transform.Position);
|
|
||||||
Rotate(resetQuad.EData.Transform, Vec3{bx::kPi * 0.5f, 0.0f, (1.0f - 0 * 0.5f) * bx::kPi});
|
|
||||||
if (GetMouseButtonPressedNow(MouseButton::Left) &&
|
|
||||||
IsQuadHovered(resetQuad.EData.Transform, mousePosWorld, quadPlaneIntersectPos))
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
// Available Cards
|
|
||||||
for (int32_t i = 0; i < Puzzle::Config::MaxAvailableStacks; ++i)
|
|
||||||
{
|
|
||||||
auto& card = Data.AvailableCards[i];
|
|
||||||
for (int32_t j = 0; j < UIAvailableCardMaxStackPreview; j++)
|
|
||||||
{
|
|
||||||
auto& quad = level.UIQuads.Get(UIAvailableCards[i * UIAvailableCardMaxStackPreview + j]);
|
|
||||||
int32_t remaining = (int32_t)card.MaxAvailableCount - (int32_t)card.UsedCount;
|
|
||||||
if (i < Data.AvailableCardCount && j < remaining)
|
|
||||||
{
|
|
||||||
quad.EData.Visible = IsActive;
|
|
||||||
quad.EData.TextureHandle = Puzzle::IsValid(Data.AvailableCards[i].RefCard)
|
|
||||||
? staticCards[Data.AvailableCards[i].RefCard.Idx].BoardTextureHandle
|
|
||||||
: Gen::TextureHandle{};
|
|
||||||
quad.EData.Transform.Position = tileOriginTransform.Position;
|
|
||||||
quad.EData.Transform.Rotation = camTransform.Rotation;
|
|
||||||
TranslateLocal(quad.EData.Transform,
|
|
||||||
Vec3{j * 0.05f + i * 1.2f, 6.0f + (j % 2 == 0 ? 0.02f : 0.0f), j * 0.001f} *
|
|
||||||
UICardOffset * UICardScale);
|
|
||||||
Rotate(quad.EData.Transform, Vec3{bx::kPi * 0.5f, 0.0f, (1.0f - 0 * 0.5f) * bx::kPi});
|
|
||||||
quad.EData.Transform.Scale = {UICardScale, UICardScale, UICardScale};
|
|
||||||
quad.EData.DotColor = {1.0f, 1.0f, 1.0f, 1.0f};
|
|
||||||
quad.EData.BaseColor = {1.0f, 1.0f, 1.0f, 1.0f};
|
|
||||||
|
|
||||||
if (j == 0)
|
|
||||||
{
|
|
||||||
if (IsQuadHovered(quad.EData.Transform, mousePosWorld, quadPlaneIntersectPos) &&
|
|
||||||
DraggedAvailableCardIdx == UINT16_MAX && DraggedCard.X == -1 &&
|
|
||||||
GetMouseButtonPressedNow(MouseButton::Left))
|
|
||||||
{
|
|
||||||
DraggedAvailableCardIdx = i;
|
|
||||||
}
|
|
||||||
if (DraggedAvailableCardIdx == i)
|
|
||||||
{
|
|
||||||
Vec3 dragPos = quadPlaneIntersectPos;
|
|
||||||
dragPos -= AxisForward(camTransform.M) * 0.01f;
|
|
||||||
quad.EData.Transform.Position = dragPos;
|
|
||||||
|
|
||||||
Vec3 boardPos = GlobalToLocalPoint(tileOriginTransform, quadPlaneIntersectPos);
|
|
||||||
Vec3 boardTilePos = boardPos / UICardOffset;
|
|
||||||
int32_t xPos = (int32_t)bx::round(boardTilePos.x);
|
|
||||||
int32_t yPos = (int32_t)bx::round(boardTilePos.z);
|
|
||||||
|
|
||||||
if (!GetMouseButton(MouseButton::Left))
|
|
||||||
{
|
|
||||||
if (xPos >= 0 && xPos < Data.WidthTiles / Puzzle::Config::CardSize && yPos >= 0 &&
|
|
||||||
yPos < Data.HeightTiles / Puzzle::Config::CardSize)
|
|
||||||
{
|
|
||||||
Gen::PuzPos targetCardPos = {(int8_t)xPos, (int8_t)yPos};
|
|
||||||
Gen::PlacedPuzzleCard& targetCard =
|
|
||||||
Data.PlacedCards[yPos * Puzzle::Config::MaxPuzzleSizeCards + xPos];
|
|
||||||
if (!Puzzle::IsValid(targetCard.RefCard) || targetCard.RefCard.Idx == 0)
|
|
||||||
{
|
|
||||||
Puzzle::DragAvailableCardTo(Data, targetCardPos, DraggedAvailableCardIdx, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DraggedAvailableCardIdx = UINT16_MAX;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
quad.EData.Visible = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Board
|
// Board
|
||||||
for (int8_t y = 0; y < Data.HeightTiles / Puzzle::Config::CardSize; ++y)
|
for (int8_t y = 0; y < Data.HeightTiles / Puzzle::Config::CardSize; ++y)
|
||||||
{
|
{
|
||||||
@@ -558,7 +396,6 @@ namespace Game
|
|||||||
int32_t cardIdx = y * Puzzle::Config::MaxPuzzleSizeCards + x;
|
int32_t cardIdx = y * Puzzle::Config::MaxPuzzleSizeCards + x;
|
||||||
Gen::PlacedPuzzleCard& card = Data.PlacedCards[cardIdx];
|
Gen::PlacedPuzzleCard& card = Data.PlacedCards[cardIdx];
|
||||||
auto& tile = level.PuzzleTiles.Get(TileHandles[cardIdx]);
|
auto& tile = level.PuzzleTiles.Get(TileHandles[cardIdx]);
|
||||||
auto& quad = level.UIQuads.Get(UIPlacedCards[cardIdx]);
|
|
||||||
|
|
||||||
bool isValid = Puzzle::IsValid(card.RefCard);
|
bool isValid = Puzzle::IsValid(card.RefCard);
|
||||||
auto& staticCard = isValid ? staticCards[card.RefCard.Idx] : staticCards[0];
|
auto& staticCard = isValid ? staticCards[card.RefCard.Idx] : staticCards[0];
|
||||||
@@ -597,96 +434,6 @@ namespace Game
|
|||||||
Gen::RotateLocal(cover.EData.Transform, Gen::EulerFromRotation(model.Sockets[i].Rot));
|
Gen::RotateLocal(cover.EData.Transform, Gen::EulerFromRotation(model.Sockets[i].Rot));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// UI Quad
|
|
||||||
quad.EData.Visible = isValid && IsActive;
|
|
||||||
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.Transform.Position = tileOriginTransform.Position;
|
|
||||||
quad.EData.Transform.Rotation = camTransform.Rotation;
|
|
||||||
TranslateLocal(quad.EData.Transform,
|
|
||||||
Vec3{(float)card.Position.X, (float)card.Position.Y, 0.0f} * UICardOffset * UICardScale);
|
|
||||||
Rotate(quad.EData.Transform, Vec3{bx::kPi * 0.5f, 0.0f, (1.0f - card.Rotation * 0.5f) * bx::kPi});
|
|
||||||
quad.EData.Transform.Scale = {UICardScale, UICardScale, UICardScale};
|
|
||||||
|
|
||||||
Vec3 quadPlaneIntersectPos;
|
|
||||||
if (isValid && IsQuadHovered(quad.EData.Transform, mousePosWorld, quadPlaneIntersectPos))
|
|
||||||
{
|
|
||||||
if (!card.IsLocked && DraggedCard.X == -1 && DraggedAvailableCardIdx == UINT16_MAX)
|
|
||||||
{
|
|
||||||
if (GetMouseButtonPressedNow(MouseButton::Left))
|
|
||||||
{
|
|
||||||
DraggedCard.X = x;
|
|
||||||
DraggedCard.Y = y;
|
|
||||||
}
|
|
||||||
if (GetMouseButtonPressedNow(MouseButton::Right))
|
|
||||||
{
|
|
||||||
Puzzle::RotateCard(card);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (DraggedCard.X == x && DraggedCard.Y == y)
|
|
||||||
{
|
|
||||||
Vec3 dragPos = quadPlaneIntersectPos;
|
|
||||||
dragPos -= AxisForward(camTransform.M) * 0.01f;
|
|
||||||
quad.EData.Transform.Position = dragPos;
|
|
||||||
|
|
||||||
Vec3 boardPos = GlobalToLocalPoint(tileOriginTransform, quadPlaneIntersectPos);
|
|
||||||
Vec3 boardTilePos = boardPos / UICardOffset;
|
|
||||||
int32_t xPos = (int32_t)bx::round(boardTilePos.x);
|
|
||||||
int32_t yPos = (int32_t)bx::round(boardTilePos.z);
|
|
||||||
Gen::PuzPos srcCardPos = {(int8_t)DraggedCard.X, (int8_t)DraggedCard.Y};
|
|
||||||
Gen::PlacedPuzzleCard& srcCard =
|
|
||||||
Data.PlacedCards[srcCardPos.Y * Puzzle::Config::MaxPuzzleSizeCards + srcCardPos.X];
|
|
||||||
|
|
||||||
if (GetMouseButtonPressedNow(MouseButton::Right))
|
|
||||||
{
|
|
||||||
Puzzle::RotateCard(srcCard);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!GetMouseButton(MouseButton::Left))
|
|
||||||
{
|
|
||||||
Gen::PuzPos targetCardPos = {(int8_t)xPos, (int8_t)yPos};
|
|
||||||
if (xPos >= 0 && xPos < Data.WidthTiles / Puzzle::Config::CardSize && yPos >= 0 &&
|
|
||||||
yPos < Data.HeightTiles / Puzzle::Config::CardSize)
|
|
||||||
{
|
|
||||||
PlacedPuzzleCard srcCardCopy = srcCard;
|
|
||||||
Gen::PlacedPuzzleCard& targetCard =
|
|
||||||
Data.PlacedCards[yPos * Puzzle::Config::MaxPuzzleSizeCards + xPos];
|
|
||||||
bool canBeReplaced = !Puzzle::IsValid(targetCard.RefCard) || targetCard.RefCard.Idx == 0;
|
|
||||||
if (canBeReplaced && Puzzle::ReturnPlacedCard(Data, srcCardPos))
|
|
||||||
{
|
|
||||||
int32_t foundIdx = -1;
|
|
||||||
for (int32_t availCardIdx = 0; availCardIdx < Data.AvailableCardCount; ++availCardIdx)
|
|
||||||
{
|
|
||||||
LOG("CHECK: %u", Data.AvailableCards[availCardIdx].RefCard.Idx);
|
|
||||||
if (Data.AvailableCards[availCardIdx].RefCard.Idx == srcCardCopy.RefCard.Idx)
|
|
||||||
{
|
|
||||||
foundIdx = availCardIdx;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (foundIdx >= 0)
|
|
||||||
{
|
|
||||||
Puzzle::DragAvailableCardTo(Data, targetCardPos, foundIdx, srcCard.Rotation);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG_ERROR("NOTFOUND: %u", srcCardCopy.RefCard.Idx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Puzzle::ReturnPlacedCard(Data, srcCardPos);
|
|
||||||
}
|
|
||||||
DraggedCard.X = -1;
|
|
||||||
DraggedCard.Y = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
152
src/game/Level.h
152
src/game/Level.h
@@ -1,166 +1,21 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../engine/Shared.h"
|
#include "../engine/Shared.h"
|
||||||
#include "Log.h"
|
|
||||||
#include "Puzzle.h"
|
#include "Puzzle.h"
|
||||||
|
#include "UI.h"
|
||||||
#include "rendering/Rendering.h"
|
#include "rendering/Rendering.h"
|
||||||
#include <bgfx/bgfx.h>
|
#include <bgfx/bgfx.h>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
#define ENTITY_HANDLE(X) \
|
|
||||||
struct X \
|
|
||||||
{ \
|
|
||||||
uint16_t Idx = UINT16_MAX; \
|
|
||||||
}; \
|
|
||||||
inline bool IsValid(X h) \
|
|
||||||
{ \
|
|
||||||
return h.Idx != UINT16_MAX; \
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Game
|
namespace Game
|
||||||
{
|
{
|
||||||
struct EntityRenderData
|
|
||||||
{
|
|
||||||
Gen::Vec4 DotColor{1.0f, 1.0f, 1.0f, 1.0f};
|
|
||||||
Gen::Vec4 BaseColor{0.0f, 0.0f, 0.0f, 1.0f};
|
|
||||||
Gen::Transform Transform;
|
|
||||||
Gen::EMaterial::Enum MaterialHandle = Gen::EMaterial::UI;
|
|
||||||
Gen::TextureHandle TextureHandle;
|
|
||||||
Gen::ModelHandle ModelH;
|
|
||||||
bool Visible = true;
|
|
||||||
|
|
||||||
void Render(const Model* models, const Material* materials, const Texture* textures);
|
|
||||||
void LoadFromSaved(const Gen::SavedEntityRenderData& saved);
|
|
||||||
};
|
|
||||||
|
|
||||||
ENTITY_HANDLE(CubeHandle);
|
|
||||||
struct Cube
|
|
||||||
{
|
|
||||||
int32_t TestX = -1;
|
|
||||||
int32_t TestY = -1;
|
|
||||||
EntityRenderData EData;
|
|
||||||
|
|
||||||
void Setup();
|
|
||||||
void Update();
|
|
||||||
};
|
|
||||||
|
|
||||||
ENTITY_HANDLE(TestEntityHandle);
|
|
||||||
struct TestEntity
|
|
||||||
{
|
|
||||||
EntityRenderData EData;
|
|
||||||
|
|
||||||
void Setup();
|
|
||||||
};
|
|
||||||
|
|
||||||
ENTITY_HANDLE(PuzzleTileEntityHandle);
|
|
||||||
struct PuzzleTileEntity
|
|
||||||
{
|
|
||||||
EntityRenderData EData;
|
|
||||||
};
|
|
||||||
|
|
||||||
ENTITY_HANDLE(PuzzleTileCoverHandle);
|
|
||||||
struct PuzzleTileCover
|
|
||||||
{
|
|
||||||
EntityRenderData EData;
|
|
||||||
};
|
|
||||||
|
|
||||||
ENTITY_HANDLE(UIQuadEntityHandle);
|
|
||||||
struct UIQuadEntity
|
|
||||||
{
|
|
||||||
EntityRenderData EData;
|
|
||||||
};
|
|
||||||
|
|
||||||
ENTITY_HANDLE(LevelEntityHandle);
|
|
||||||
struct LevelEntity
|
|
||||||
{
|
|
||||||
EntityRenderData EData;
|
|
||||||
};
|
|
||||||
|
|
||||||
class IEntityManager
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual bool Setup(uint8_t*& ptr, bool forceReset) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T, typename HandleT, uint32_t C> class EntityManager : public IEntityManager
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
uint16_t Count = 0;
|
|
||||||
T* Data = nullptr;
|
|
||||||
uint32_t EntitySize = 0;
|
|
||||||
T InvalidObject{};
|
|
||||||
bool IsEnabled = true;
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Returns true if size changed
|
|
||||||
bool Setup(uint8_t*& ptr, bool forceReset)
|
|
||||||
{
|
|
||||||
bool changed = false;
|
|
||||||
if (EntitySize != sizeof(T) || forceReset)
|
|
||||||
{
|
|
||||||
Count = 0;
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
EntitySize = sizeof(T);
|
|
||||||
Data = reinterpret_cast<T*>(ptr);
|
|
||||||
ptr += C * EntitySize;
|
|
||||||
return changed;
|
|
||||||
}
|
|
||||||
|
|
||||||
HandleT New()
|
|
||||||
{
|
|
||||||
if (Data == nullptr)
|
|
||||||
{
|
|
||||||
ERROR_ONCE("Accessed EntityManager before setup!");
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
if (Count >= C)
|
|
||||||
{
|
|
||||||
ERROR_ONCE("Too many entities!");
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
Data[Count] = {};
|
|
||||||
HandleT H;
|
|
||||||
H.Idx = Count;
|
|
||||||
++Count;
|
|
||||||
return H;
|
|
||||||
}
|
|
||||||
|
|
||||||
T& Get(HandleT handle)
|
|
||||||
{
|
|
||||||
if (handle.Idx >= Count)
|
|
||||||
{
|
|
||||||
ERROR_ONCE("OOB Access!");
|
|
||||||
return InvalidObject;
|
|
||||||
}
|
|
||||||
return Data[handle.Idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
void Render(const Model* models, const Material* materials, const Texture* textures)
|
|
||||||
{
|
|
||||||
if (!IsEnabled) return;
|
|
||||||
for (uint16_t i = 0; i < Count; ++i)
|
|
||||||
{
|
|
||||||
Get({i}).EData.Render(models, materials, textures);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct WorldPuzzle
|
struct WorldPuzzle
|
||||||
{
|
{
|
||||||
static constexpr Gen::Vec2 WorldCardSize{10.0f, 10.0f};
|
static constexpr Gen::Vec2 WorldCardSize{10.0f, 10.0f};
|
||||||
static constexpr float UICardScale = 0.05f;
|
|
||||||
static constexpr float UICardOffset = 2.1f * UICardScale;
|
|
||||||
static constexpr int32_t UIAvailableCardMaxStackPreview = 3;
|
|
||||||
Gen::PuzzleData Data;
|
Gen::PuzzleData Data;
|
||||||
Gen::Vec3 WorldPosition;
|
Gen::Vec3 WorldPosition;
|
||||||
PuzzleTileEntityHandle TileHandles[Puzzle::Config::MaxCardsInPuzzle];
|
PuzzleTileEntityHandle TileHandles[Puzzle::Config::MaxCardsInPuzzle];
|
||||||
PuzzleTileCoverHandle CoverHandles[Puzzle::Config::MaxCardsInPuzzle * Puzzle::Config::MaxCoversInTile];
|
PuzzleTileCoverHandle CoverHandles[Puzzle::Config::MaxCardsInPuzzle * Puzzle::Config::MaxCoversInTile];
|
||||||
UIQuadEntityHandle UIPlacedCards[Puzzle::Config::MaxCardsInPuzzle];
|
|
||||||
UIQuadEntityHandle UIAvailableCards[Puzzle::Config::MaxAvailableStacks * UIAvailableCardMaxStackPreview];
|
|
||||||
UIQuadEntityHandle SolvedQuad;
|
|
||||||
UIQuadEntityHandle ResetQuad;
|
|
||||||
Gen::PuzPos DraggedCard{-1, -1};
|
|
||||||
uint16_t DraggedAvailableCardIdx = UINT16_MAX;
|
|
||||||
bool IsSetup = false;
|
bool IsSetup = false;
|
||||||
bool IsActive = false;
|
bool IsActive = false;
|
||||||
|
|
||||||
@@ -176,7 +31,7 @@ namespace Game
|
|||||||
EntityManager<TestEntity, TestEntityHandle, 32> Tests;
|
EntityManager<TestEntity, TestEntityHandle, 32> Tests;
|
||||||
EntityManager<PuzzleTileEntity, PuzzleTileEntityHandle, Puzzle::Config::MaxTilesTotal> PuzzleTiles;
|
EntityManager<PuzzleTileEntity, PuzzleTileEntityHandle, Puzzle::Config::MaxTilesTotal> PuzzleTiles;
|
||||||
EntityManager<PuzzleTileCover, PuzzleTileCoverHandle, Puzzle::Config::MaxCoversTotal> PuzzleTileCovers;
|
EntityManager<PuzzleTileCover, PuzzleTileCoverHandle, Puzzle::Config::MaxCoversTotal> PuzzleTileCovers;
|
||||||
EntityManager<UIQuadEntity, UIQuadEntityHandle, Puzzle::Config::MaxTilesInPuzzle * 2> UIQuads;
|
UIQuadEntityManager UIQuads;
|
||||||
EntityManager<LevelEntity, LevelEntityHandle, 64> LevelEntities;
|
EntityManager<LevelEntity, LevelEntityHandle, 64> LevelEntities;
|
||||||
|
|
||||||
CubeHandle PlayerOutsideViewCube;
|
CubeHandle PlayerOutsideViewCube;
|
||||||
@@ -185,6 +40,7 @@ namespace Game
|
|||||||
public:
|
public:
|
||||||
Gen::StaticPuzzleData PuzzleData;
|
Gen::StaticPuzzleData PuzzleData;
|
||||||
WorldPuzzle Puzzles[Puzzle::Config::MaxVisiblePuzzles];
|
WorldPuzzle Puzzles[Puzzle::Config::MaxVisiblePuzzles];
|
||||||
|
WorldPuzzleUI PuzzleUI;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void Setup(GameData& data);
|
void Setup(GameData& data);
|
||||||
|
|||||||
@@ -306,6 +306,8 @@ namespace Tools
|
|||||||
ImGui::Text("Status");
|
ImGui::Text("Status");
|
||||||
bTabletChanged |= Tools::EntityDataSettings(player.Config.TabletStatusRenderData);
|
bTabletChanged |= Tools::EntityDataSettings(player.Config.TabletStatusRenderData);
|
||||||
bTabletChanged |= Tools::TextureDropdown(player.Config.TabletStatusSolvedTexture, "Solved Texture");
|
bTabletChanged |= Tools::TextureDropdown(player.Config.TabletStatusSolvedTexture, "Solved Texture");
|
||||||
|
bTabletChanged |=
|
||||||
|
Tools::TextureDropdown(player.Config.TabletStatusNotSolvedTexture, "Not Solved Texture");
|
||||||
ImGui::Text("Reset");
|
ImGui::Text("Reset");
|
||||||
bTabletChanged |= Tools::EntityDataSettings(player.Config.TabletResetRenderData);
|
bTabletChanged |= Tools::EntityDataSettings(player.Config.TabletResetRenderData);
|
||||||
if (bTabletChanged)
|
if (bTabletChanged)
|
||||||
@@ -314,6 +316,7 @@ namespace Tools
|
|||||||
s.Init("game/data/static/uiconfig.dat", "UICO");
|
s.Init("game/data/static/uiconfig.dat", "UICO");
|
||||||
s.WriteT(player.Config);
|
s.WriteT(player.Config);
|
||||||
s.Finish();
|
s.Finish();
|
||||||
|
level.PuzzleUI.Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|||||||
333
src/game/UI.cpp
Normal file
333
src/game/UI.cpp
Normal file
@@ -0,0 +1,333 @@
|
|||||||
|
#include "UI.h"
|
||||||
|
|
||||||
|
#include "Gen.h"
|
||||||
|
#include "Global.h"
|
||||||
|
#include "Input.h"
|
||||||
|
#include "Instance.h"
|
||||||
|
#include "Level.h"
|
||||||
|
|
||||||
|
#include "bx/math.h"
|
||||||
|
|
||||||
|
using namespace Gen;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
Game::StaticUIData StaticData;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Game
|
||||||
|
{
|
||||||
|
UIQuadEntityHandle NewQuad(UIQuadEntityManager& manager, const Gen::SavedEntityRenderData& loadData)
|
||||||
|
{
|
||||||
|
UIQuadEntityHandle h = manager.New();
|
||||||
|
if (!IsValid(h)) return h;
|
||||||
|
|
||||||
|
UIQuadEntity& entity = manager.Get(h);
|
||||||
|
entity.EData.LoadFromSaved(loadData);
|
||||||
|
entity.UIPos = entity.EData.Transform.Position;
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateQuad(UIQuadEntityManager& manager, UIQuadEntityHandle handle)
|
||||||
|
{
|
||||||
|
if (!IsValid(handle)) return;
|
||||||
|
|
||||||
|
UIQuadEntity& entity = manager.Get(handle);
|
||||||
|
entity.EData.Transform.Position = StaticData.UITransform.Position;
|
||||||
|
entity.EData.Transform.Rotation = StaticData.UITransform.Rotation;
|
||||||
|
TranslateLocal(entity.EData.Transform, entity.UIPos);
|
||||||
|
Rotate(entity.EData.Transform, Vec3{bx::kPi * 0.5f, 0.0f, (1.0f - 0 * 0.5f) * bx::kPi});
|
||||||
|
Rotate(entity.EData.Transform, {0.0f, entity.UIRot, 0.0f});
|
||||||
|
}
|
||||||
|
|
||||||
|
Vec3 GetMousePosWorld()
|
||||||
|
{
|
||||||
|
auto& window = GetShared().Window;
|
||||||
|
Vec2 mousePos = GetMousePos();
|
||||||
|
mousePos.x = mousePos.x / window.WindowWidth;
|
||||||
|
mousePos.y = mousePos.y / window.WindowHeight;
|
||||||
|
mousePos *= 2.0f;
|
||||||
|
mousePos -= 1.0f;
|
||||||
|
Vec4 mousePosView = {mousePos.x, -mousePos.y, 0.0f, 1.0f};
|
||||||
|
Vec4 mousePosCam4 = Mul(GetInstance().Player.ProjectionInverse, mousePosView);
|
||||||
|
Vec3 mousePosCam = Vec3{
|
||||||
|
mousePosCam4.x /= mousePosCam4.w,
|
||||||
|
mousePosCam4.y /= mousePosCam4.w,
|
||||||
|
mousePosCam4.z /= mousePosCam4.w,
|
||||||
|
};
|
||||||
|
|
||||||
|
return LocalToGlobalPoint(GetInstance().Player.PlayerCamTransform, mousePosCam);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsQuadHovered(Transform& quadTransform, Vec3 mousePosWorld, Vec3& outQuadPlaneIntersectPos)
|
||||||
|
{
|
||||||
|
Vec3 quadPosWorld = quadTransform.Position;
|
||||||
|
Vec3 quadXWorld = LocalToGlobalPoint(quadTransform, {1, 0, 0});
|
||||||
|
Vec3 quadZWorld = LocalToGlobalPoint(quadTransform, {0, 0, 1});
|
||||||
|
if (RayPlaneIntersect(GetInstance().Player.PlayerCamTransform.Position,
|
||||||
|
mousePosWorld,
|
||||||
|
quadPosWorld,
|
||||||
|
quadXWorld,
|
||||||
|
quadZWorld,
|
||||||
|
outQuadPlaneIntersectPos))
|
||||||
|
{
|
||||||
|
Vec3 quadSpaceIntersect = GlobalToLocalPoint(quadTransform, outQuadPlaneIntersectPos);
|
||||||
|
if (quadSpaceIntersect.x >= -1.0f && quadSpaceIntersect.x <= 1.0f && quadSpaceIntersect.z >= -1.0f &&
|
||||||
|
quadSpaceIntersect.z <= 1.0f)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldPuzzleUI::Setup()
|
||||||
|
{
|
||||||
|
auto& level = GetInstance().GameLevel;
|
||||||
|
SolvedQuad = NewQuad(level.UIQuads, GetInstance().Player.Config.TabletStatusRenderData);
|
||||||
|
ResetQuad = NewQuad(level.UIQuads, GetInstance().Player.Config.TabletResetRenderData);
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < Puzzle::Config::MaxCardsInPuzzle; ++i)
|
||||||
|
{
|
||||||
|
UIPlacedCards[i] = level.UIQuads.New();
|
||||||
|
auto& quad = level.UIQuads.Get(UIPlacedCards[i]);
|
||||||
|
quad.EData.ModelH = GameRendering::Get().GetModelHandleFromPath("models/plane.glb");
|
||||||
|
quad.EData.MaterialHandle = EMaterial::UI;
|
||||||
|
}
|
||||||
|
for (int32_t i = 0; i < Puzzle::Config::MaxAvailableStacks * UIAvailableCardMaxStackPreview; ++i)
|
||||||
|
{
|
||||||
|
UIAvailableCards[i] = level.UIQuads.New();
|
||||||
|
auto& quad = level.UIQuads.Get(UIAvailableCards[i]);
|
||||||
|
quad.EData.MaterialHandle = EMaterial::UI;
|
||||||
|
quad.EData.ModelH = GameRendering::Get().GetModelHandleFromPath("models/plane.glb");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldPuzzleUI::UpdateAvailableCards(Gen::PuzzleData& Data)
|
||||||
|
{
|
||||||
|
auto& level = GetInstance().GameLevel;
|
||||||
|
auto& staticCards = Puzzle::GetStaticPuzzleData().Cards;
|
||||||
|
|
||||||
|
Vec3 quadPlaneIntersectPos;
|
||||||
|
Vec3 mousePosWorld = GetMousePosWorld();
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < Puzzle::Config::MaxAvailableStacks; ++i)
|
||||||
|
{
|
||||||
|
auto& card = Data.AvailableCards[i];
|
||||||
|
for (int32_t j = 0; j < UIAvailableCardMaxStackPreview; j++)
|
||||||
|
{
|
||||||
|
auto h = UIAvailableCards[i * UIAvailableCardMaxStackPreview + j];
|
||||||
|
auto& quad = level.UIQuads.Get(h);
|
||||||
|
int32_t remaining = (int32_t)card.MaxAvailableCount - (int32_t)card.UsedCount;
|
||||||
|
if (i < Data.AvailableCardCount && j < remaining)
|
||||||
|
{
|
||||||
|
quad.UIPos = Vec3{j * 0.05f + i * 1.2f, 4.2f + (j % 2 == 0 ? 0.02f : 0.0f), j * 0.001f} *
|
||||||
|
UICardOffset * UICardScale;
|
||||||
|
UpdateQuad(level.UIQuads, h);
|
||||||
|
quad.EData.Visible = true;
|
||||||
|
quad.EData.TextureHandle = Puzzle::IsValid(Data.AvailableCards[i].RefCard)
|
||||||
|
? staticCards[Data.AvailableCards[i].RefCard.Idx].BoardTextureHandle
|
||||||
|
: Gen::TextureHandle{};
|
||||||
|
quad.EData.Transform.Scale = {UICardScale, UICardScale, UICardScale};
|
||||||
|
quad.EData.DotColor = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||||
|
quad.EData.BaseColor = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||||
|
|
||||||
|
if (j == 0)
|
||||||
|
{
|
||||||
|
if (IsQuadHovered(quad.EData.Transform, mousePosWorld, quadPlaneIntersectPos) &&
|
||||||
|
DraggedAvailableCardIdx == UINT16_MAX && DraggedCard.X == -1 &&
|
||||||
|
GetMouseButtonPressedNow(MouseButton::Left))
|
||||||
|
{
|
||||||
|
DraggedAvailableCardIdx = i;
|
||||||
|
}
|
||||||
|
if (DraggedAvailableCardIdx == i)
|
||||||
|
{
|
||||||
|
Vec3 dragPos = quadPlaneIntersectPos;
|
||||||
|
dragPos += StaticData.ZAxis * -0.01f;
|
||||||
|
quad.EData.Transform.Position = dragPos;
|
||||||
|
|
||||||
|
Vec3 boardPos = GlobalToLocalPoint(StaticData.UITransform, quadPlaneIntersectPos);
|
||||||
|
Vec3 boardTilePos = boardPos / UICardOffset;
|
||||||
|
int32_t xPos = (int32_t)bx::round(boardTilePos.x);
|
||||||
|
int32_t yPos = (int32_t)bx::round(boardTilePos.y);
|
||||||
|
|
||||||
|
if (!GetMouseButton(MouseButton::Left))
|
||||||
|
{
|
||||||
|
if (xPos >= 0 && xPos < Data.WidthTiles / Puzzle::Config::CardSize && yPos >= 0 &&
|
||||||
|
yPos < Data.HeightTiles / Puzzle::Config::CardSize)
|
||||||
|
{
|
||||||
|
Gen::PuzPos targetCardPos = {(int8_t)xPos, (int8_t)yPos};
|
||||||
|
Gen::PlacedPuzzleCard& targetCard =
|
||||||
|
Data.PlacedCards[yPos * Puzzle::Config::MaxPuzzleSizeCards + xPos];
|
||||||
|
if (!Puzzle::IsValid(targetCard.RefCard) || targetCard.RefCard.Idx == 0)
|
||||||
|
{
|
||||||
|
Puzzle::DragAvailableCardTo(Data, targetCardPos, DraggedAvailableCardIdx, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DraggedAvailableCardIdx = UINT16_MAX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
quad.EData.Visible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldPuzzleUI::UpdateBoardCards(Gen::PuzzleData& Data)
|
||||||
|
{
|
||||||
|
auto& level = GetInstance().GameLevel;
|
||||||
|
auto& staticCards = Puzzle::GetStaticPuzzleData().Cards;
|
||||||
|
Vec3 quadPlaneIntersectPos;
|
||||||
|
|
||||||
|
for (int8_t y = 0; y < Data.HeightTiles / Puzzle::Config::CardSize; ++y)
|
||||||
|
{
|
||||||
|
for (int8_t x = 0; x < Data.WidthTiles / Puzzle::Config::CardSize; ++x)
|
||||||
|
{
|
||||||
|
// UI Quad
|
||||||
|
int32_t cardIdx = y * Puzzle::Config::MaxPuzzleSizeCards + x;
|
||||||
|
PlacedPuzzleCard& card = Data.PlacedCards[cardIdx];
|
||||||
|
bool isValid = Puzzle::IsValid(card.RefCard);
|
||||||
|
|
||||||
|
auto& quad = level.UIQuads.Get(UIPlacedCards[cardIdx]);
|
||||||
|
quad.UIPos = Vec3{(float)card.Position.X, (float)card.Position.Y, 0.0f} * UICardOffset * UICardScale;
|
||||||
|
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.Transform.Scale = {UICardScale, UICardScale, UICardScale};
|
||||||
|
|
||||||
|
if (isValid && IsQuadHovered(quad.EData.Transform, StaticData.MousePosWorld, quadPlaneIntersectPos))
|
||||||
|
{
|
||||||
|
if (!card.IsLocked && DraggedCard.X == -1 && DraggedAvailableCardIdx == UINT16_MAX)
|
||||||
|
{
|
||||||
|
if (GetMouseButtonPressedNow(MouseButton::Left))
|
||||||
|
{
|
||||||
|
DraggedCard.X = x;
|
||||||
|
DraggedCard.Y = y;
|
||||||
|
}
|
||||||
|
if (GetMouseButtonPressedNow(MouseButton::Right))
|
||||||
|
{
|
||||||
|
Puzzle::RotateCard(card);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DraggedCard.X == x && DraggedCard.Y == y)
|
||||||
|
{
|
||||||
|
Vec3 dragPos = quadPlaneIntersectPos;
|
||||||
|
dragPos += StaticData.ZAxis * -0.01f;
|
||||||
|
quad.EData.Transform.Position = dragPos;
|
||||||
|
|
||||||
|
Vec3 boardPos = GlobalToLocalPoint(StaticData.UITransform, quadPlaneIntersectPos);
|
||||||
|
Vec3 boardTilePos = boardPos / UICardOffset;
|
||||||
|
int32_t xPos = (int32_t)bx::round(boardTilePos.x);
|
||||||
|
int32_t yPos = (int32_t)bx::round(boardTilePos.y);
|
||||||
|
Gen::PuzPos srcCardPos = {(int8_t)DraggedCard.X, (int8_t)DraggedCard.Y};
|
||||||
|
Gen::PlacedPuzzleCard& srcCard =
|
||||||
|
Data.PlacedCards[srcCardPos.Y * Puzzle::Config::MaxPuzzleSizeCards + srcCardPos.X];
|
||||||
|
|
||||||
|
if (GetMouseButtonPressedNow(MouseButton::Right))
|
||||||
|
{
|
||||||
|
Puzzle::RotateCard(srcCard);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetMouseButton(MouseButton::Left))
|
||||||
|
{
|
||||||
|
Gen::PuzPos targetCardPos = {(int8_t)xPos, (int8_t)yPos};
|
||||||
|
if (xPos >= 0 && xPos < Data.WidthTiles / Puzzle::Config::CardSize && yPos >= 0 &&
|
||||||
|
yPos < Data.HeightTiles / Puzzle::Config::CardSize)
|
||||||
|
{
|
||||||
|
PlacedPuzzleCard srcCardCopy = srcCard;
|
||||||
|
Gen::PlacedPuzzleCard& targetCard =
|
||||||
|
Data.PlacedCards[yPos * Puzzle::Config::MaxPuzzleSizeCards + xPos];
|
||||||
|
bool canBeReplaced = !Puzzle::IsValid(targetCard.RefCard) || targetCard.RefCard.Idx == 0;
|
||||||
|
if (canBeReplaced && Puzzle::ReturnPlacedCard(Data, srcCardPos))
|
||||||
|
{
|
||||||
|
int32_t foundIdx = -1;
|
||||||
|
for (int32_t availCardIdx = 0; availCardIdx < Data.AvailableCardCount; ++availCardIdx)
|
||||||
|
{
|
||||||
|
if (Data.AvailableCards[availCardIdx].RefCard.Idx == srcCardCopy.RefCard.Idx)
|
||||||
|
{
|
||||||
|
foundIdx = availCardIdx;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (foundIdx >= 0)
|
||||||
|
{
|
||||||
|
Puzzle::DragAvailableCardTo(Data, targetCardPos, foundIdx, srcCard.Rotation);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG_ERROR("NOTFOUND: %u", srcCardCopy.RefCard.Idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Puzzle::ReturnPlacedCard(Data, srcCardPos);
|
||||||
|
}
|
||||||
|
DraggedCard.X = -1;
|
||||||
|
DraggedCard.Y = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldPuzzleUI::Update(Gen::PuzzleData& Data, bool IsPuzzleSolved)
|
||||||
|
{
|
||||||
|
auto& level = GetInstance().GameLevel;
|
||||||
|
|
||||||
|
Transform& camTransform = GetInstance().Player.PlayerCamTransform;
|
||||||
|
UpdateMatrix(camTransform);
|
||||||
|
|
||||||
|
StaticData.UITransform = level.UIQuads.Get(level.TabletHandle).EData.Transform;
|
||||||
|
StaticData.UITransform.Rotation = camTransform.Rotation;
|
||||||
|
StaticData.ZAxis = AxisForward(StaticData.UITransform.M);
|
||||||
|
StaticData.UITransform.Position += StaticData.ZAxis * -0.01f;
|
||||||
|
StaticData.MousePosWorld = GetMousePosWorld();
|
||||||
|
|
||||||
|
// TODO: disable warning & check if parentheses make sense like this
|
||||||
|
Vec2 uiOffset = Vec2{static_cast<float>(Data.WidthTiles / Puzzle::Config::CardSize) - 1,
|
||||||
|
static_cast<float>(Data.HeightTiles / Puzzle::Config::CardSize) - 1};
|
||||||
|
uiOffset *= -UICardOffset * 0.5f;
|
||||||
|
|
||||||
|
Transform tileOriginTransform = StaticData.UITransform;
|
||||||
|
tileOriginTransform.Position += AxisForward(StaticData.UITransform.M) * -1.0f;
|
||||||
|
TranslateLocal(tileOriginTransform, Vec3{uiOffset.x, 0.0f, uiOffset.y} * 1.0f);
|
||||||
|
UpdateMatrix(tileOriginTransform);
|
||||||
|
|
||||||
|
auto& solvedQuad = level.UIQuads.Get(SolvedQuad);
|
||||||
|
solvedQuad.EData.Visible = true;
|
||||||
|
solvedQuad.EData.TextureHandle = IsPuzzleSolved ? GetInstance().Player.Config.TabletStatusSolvedTexture
|
||||||
|
: GetInstance().Player.Config.TabletStatusNotSolvedTexture;
|
||||||
|
UpdateQuad(level.UIQuads, SolvedQuad);
|
||||||
|
auto& resetQuad = level.UIQuads.Get(ResetQuad);
|
||||||
|
resetQuad.EData.Visible = true;
|
||||||
|
UpdateQuad(level.UIQuads, ResetQuad);
|
||||||
|
|
||||||
|
Vec3 hoverPosWorld;
|
||||||
|
if (GetMouseButtonPressedNow(MouseButton::Left) &&
|
||||||
|
IsQuadHovered(resetQuad.EData.Transform, StaticData.MousePosWorld, hoverPosWorld))
|
||||||
|
{
|
||||||
|
LOG_WARN("TODO!");
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateAvailableCards(Data);
|
||||||
|
UpdateBoardCards(Data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldPuzzleUI::Reset()
|
||||||
|
{
|
||||||
|
auto& level = GetInstance().GameLevel;
|
||||||
|
}
|
||||||
|
} // namespace Game
|
||||||
41
src/game/UI.h
Normal file
41
src/game/UI.h
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../gen/Generated.h"
|
||||||
|
#include "Entity.h"
|
||||||
|
#include "Puzzle.h"
|
||||||
|
|
||||||
|
namespace Game
|
||||||
|
{
|
||||||
|
struct StaticUIData
|
||||||
|
{
|
||||||
|
Gen::Transform UITransform;
|
||||||
|
Gen::Vec3 ZAxis;
|
||||||
|
Gen::Vec3 MousePosWorld;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct WorldPuzzleUI
|
||||||
|
{
|
||||||
|
static constexpr float UICardScale = 0.05f;
|
||||||
|
static constexpr float UICardOffset = 2.1f * UICardScale;
|
||||||
|
static constexpr int32_t UIAvailableCardMaxStackPreview = 3;
|
||||||
|
|
||||||
|
UIQuadEntityHandle SolvedQuad;
|
||||||
|
UIQuadEntityHandle ResetQuad;
|
||||||
|
|
||||||
|
UIQuadEntityHandle UIPlacedCards[Puzzle::Config::MaxCardsInPuzzle];
|
||||||
|
UIQuadEntityHandle UIAvailableCards[Puzzle::Config::MaxAvailableStacks * UIAvailableCardMaxStackPreview];
|
||||||
|
Gen::PuzPos DraggedCard{-1, -1};
|
||||||
|
uint16_t DraggedAvailableCardIdx = UINT16_MAX;
|
||||||
|
|
||||||
|
void Setup();
|
||||||
|
void UpdateAvailableCards(Gen::PuzzleData& Data);
|
||||||
|
void UpdateBoardCards(Gen::PuzzleData& Data);
|
||||||
|
void Update(Gen::PuzzleData& Data, bool IsPuzzleSolved);
|
||||||
|
void Reset();
|
||||||
|
};
|
||||||
|
|
||||||
|
UIQuadEntityHandle NewQuad(UIQuadEntityManager& manager, const Gen::SavedEntityRenderData& loadData);
|
||||||
|
void UpdateQuad(UIQuadEntityManager& manager, UIQuadEntityHandle handle);
|
||||||
|
Gen::Vec3 GetMousePosWorld();
|
||||||
|
bool IsQuadHovered(Gen::Transform& quadTransform, Gen::Vec3 mousePosWorld, Gen::Vec3& outQuadPlaneIntersectPos);
|
||||||
|
} // namespace Game
|
||||||
Binary file not shown.
@@ -170,6 +170,7 @@ type SavedPlayerConfig
|
|||||||
{
|
{
|
||||||
SavedEntityRenderData TabletBackgroundRenderData
|
SavedEntityRenderData TabletBackgroundRenderData
|
||||||
SavedEntityRenderData TabletStatusRenderData
|
SavedEntityRenderData TabletStatusRenderData
|
||||||
|
TextureHandle TabletStatusNotSolvedTexture
|
||||||
TextureHandle TabletStatusSolvedTexture
|
TextureHandle TabletStatusSolvedTexture
|
||||||
SavedEntityRenderData TabletResetRenderData
|
SavedEntityRenderData TabletResetRenderData
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2452,6 +2452,7 @@ namespace Gen
|
|||||||
{
|
{
|
||||||
isOk = Save(&obj[i].TabletBackgroundRenderData, 1, serializer) && isOk;
|
isOk = Save(&obj[i].TabletBackgroundRenderData, 1, serializer) && isOk;
|
||||||
isOk = Save(&obj[i].TabletStatusRenderData, 1, serializer) && isOk;
|
isOk = Save(&obj[i].TabletStatusRenderData, 1, serializer) && isOk;
|
||||||
|
isOk = Save(&obj[i].TabletStatusNotSolvedTexture, 1, serializer) && isOk;
|
||||||
isOk = Save(&obj[i].TabletStatusSolvedTexture, 1, serializer) && isOk;
|
isOk = Save(&obj[i].TabletStatusSolvedTexture, 1, serializer) && isOk;
|
||||||
isOk = Save(&obj[i].TabletResetRenderData, 1, serializer) && isOk;
|
isOk = Save(&obj[i].TabletResetRenderData, 1, serializer) && isOk;
|
||||||
}
|
}
|
||||||
@@ -2472,6 +2473,7 @@ namespace Gen
|
|||||||
{
|
{
|
||||||
isOk = Load(&obj[i].TabletBackgroundRenderData, 1, serializer) && isOk;
|
isOk = Load(&obj[i].TabletBackgroundRenderData, 1, serializer) && isOk;
|
||||||
isOk = Load(&obj[i].TabletStatusRenderData, 1, serializer) && isOk;
|
isOk = Load(&obj[i].TabletStatusRenderData, 1, serializer) && isOk;
|
||||||
|
isOk = Load(&obj[i].TabletStatusNotSolvedTexture, 1, serializer) && isOk;
|
||||||
isOk = Load(&obj[i].TabletStatusSolvedTexture, 1, serializer) && isOk;
|
isOk = Load(&obj[i].TabletStatusSolvedTexture, 1, serializer) && isOk;
|
||||||
isOk = Load(&obj[i].TabletResetRenderData, 1, serializer) && isOk;
|
isOk = Load(&obj[i].TabletResetRenderData, 1, serializer) && isOk;
|
||||||
}
|
}
|
||||||
@@ -2509,6 +2511,10 @@ namespace Gen
|
|||||||
{
|
{
|
||||||
WriteDestinations[i] = offsetof(SavedPlayerConfig, TabletStatusRenderData);
|
WriteDestinations[i] = offsetof(SavedPlayerConfig, TabletStatusRenderData);
|
||||||
}
|
}
|
||||||
|
if (bx::strCmp(memberName, "TabletStatusNotSolvedTexture") == 0 && bx::strCmp(memberTypeName, "TextureHandle") == 0)
|
||||||
|
{
|
||||||
|
WriteDestinations[i] = offsetof(SavedPlayerConfig, TabletStatusNotSolvedTexture);
|
||||||
|
}
|
||||||
if (bx::strCmp(memberName, "TabletStatusSolvedTexture") == 0 && bx::strCmp(memberTypeName, "TextureHandle") == 0)
|
if (bx::strCmp(memberName, "TabletStatusSolvedTexture") == 0 && bx::strCmp(memberTypeName, "TextureHandle") == 0)
|
||||||
{
|
{
|
||||||
WriteDestinations[i] = offsetof(SavedPlayerConfig, TabletStatusSolvedTexture);
|
WriteDestinations[i] = offsetof(SavedPlayerConfig, TabletStatusSolvedTexture);
|
||||||
@@ -2549,6 +2555,12 @@ namespace Gen
|
|||||||
isOk = Load(fieldPtr, 1, serializer) && isOk;
|
isOk = Load(fieldPtr, 1, serializer) && isOk;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (bx::strCmp(memberName, "TabletStatusNotSolvedTexture") == 0)
|
||||||
|
{
|
||||||
|
auto* fieldPtr = reinterpret_cast<TextureHandle*>(objBasePtr + WriteDestinations[j]);
|
||||||
|
isOk = Load(fieldPtr, 1, serializer) && isOk;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (bx::strCmp(memberName, "TabletStatusSolvedTexture") == 0)
|
if (bx::strCmp(memberName, "TabletStatusSolvedTexture") == 0)
|
||||||
{
|
{
|
||||||
auto* fieldPtr = reinterpret_cast<TextureHandle*>(objBasePtr + WriteDestinations[j]);
|
auto* fieldPtr = reinterpret_cast<TextureHandle*>(objBasePtr + WriteDestinations[j]);
|
||||||
|
|||||||
@@ -224,6 +224,7 @@ namespace Gen
|
|||||||
static constexpr uint16_t TypeIdx = 31;
|
static constexpr uint16_t TypeIdx = 31;
|
||||||
SavedEntityRenderData TabletBackgroundRenderData = {};
|
SavedEntityRenderData TabletBackgroundRenderData = {};
|
||||||
SavedEntityRenderData TabletStatusRenderData = {};
|
SavedEntityRenderData TabletStatusRenderData = {};
|
||||||
|
TextureHandle TabletStatusNotSolvedTexture = {};
|
||||||
TextureHandle TabletStatusSolvedTexture = {};
|
TextureHandle TabletStatusSolvedTexture = {};
|
||||||
SavedEntityRenderData TabletResetRenderData = {};
|
SavedEntityRenderData TabletResetRenderData = {};
|
||||||
};
|
};
|
||||||
@@ -351,11 +352,11 @@ namespace Gen
|
|||||||
TypeDef{sizeof(PlacedPuzzleCard), 3555575973, "PlacedPuzzleCard", 4, {24, 21, 4, 8}, {0, 0, 0, 0}, {{313, 7}, {320, 8}, {328, 8}, {336, 8}}},
|
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(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(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), 2457294139, "SavedPlayerConfig", 4, {30, 30, 20, 30}, {0, 0, 0, 0}, {{517, 26}, {543, 22}, {565, 25}, {590, 21}}},
|
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(PuzzleElementType::Enum), 2983807453, "PuzzleElementType", 0, {}, {}, {}},
|
TypeDef{sizeof(PuzzleElementType::Enum), 2983807453, "PuzzleElementType", 0, {}, {}, {}},
|
||||||
TypeDef{sizeof(EMaterial::Enum), 2024002654, "EMaterial", 0, {}, {}, {}},
|
TypeDef{sizeof(EMaterial::Enum), 2024002654, "EMaterial", 0, {}, {}, {}},
|
||||||
};
|
};
|
||||||
char MemberNameBuffer[64*64*64]{"xyxyzxyzwMMMMIPositionRotationScaleIdxModelIdxAssetTextureIdxAssetXYModelConnectionDirectionElementsBaseModelHandleNorthCoverHandleEastCoverHandleSouthCoverHandleWestCoverHandleSocketsModelTextureHandleBoardTextureHandleIdxTileBaseColorTileDotColorTestDisabledCardTintCardsVisualsRefCardMaxAvailableCountUsedCountRefCardPositionRotationIsLockedIDPuzzleNameWidthTilesHeightTilesAvailableCardCountAvailableCardsPlacedCardsBackgroundTilesGoalPositionCountGoalPositionsBaseColorHighlightColorTFMaterialTextureModelVisibleTabletBackgroundRenderDataTabletStatusRenderDataTabletStatusSolvedTextureTabletResetRenderData"};
|
char MemberNameBuffer[64*64*64]{"xyxyzxyzwMMMMIPositionRotationScaleIdxModelIdxAssetTextureIdxAssetXYModelConnectionDirectionElementsBaseModelHandleNorthCoverHandleEastCoverHandleSouthCoverHandleWestCoverHandleSocketsModelTextureHandleBoardTextureHandleIdxTileBaseColorTileDotColorTestDisabledCardTintCardsVisualsRefCardMaxAvailableCountUsedCountRefCardPositionRotationIsLockedIDPuzzleNameWidthTilesHeightTilesAvailableCardCountAvailableCardsPlacedCardsBackgroundTilesGoalPositionCountGoalPositionsBaseColorHighlightColorTFMaterialTextureModelVisibleTabletBackgroundRenderDataTabletStatusRenderDataTabletStatusNotSolvedTextureTabletStatusSolvedTextureTabletResetRenderData"};
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr MetadataTable Metadata;
|
constexpr MetadataTable Metadata;
|
||||||
|
|||||||
Reference in New Issue
Block a user