diff --git a/src/game/Level.cpp b/src/game/Level.cpp index d5b93b4..7321042 100644 --- a/src/game/Level.cpp +++ b/src/game/Level.cpp @@ -334,10 +334,9 @@ namespace Game boardTransform.Rotation = camTransform.Rotation; Vec3 fw = {camTransform.M.M[8], camTransform.M.M[9], camTransform.M.M[10]}; Vec3 pos = cameraPos; - pos += fw * 10.0f; + pos += fw * 1.0f; boardTransform.SetPosition(pos); - bool clicked = GetMouseButtonPressedNow(MouseButton::Left); Vec2 mousePos = GetMousePos(); mousePos.x = mousePos.x / window.WindowWidth; mousePos.y = mousePos.y / window.WindowHeight; @@ -362,70 +361,90 @@ namespace Game 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); tile.EData.Visible = true; - tile.EData.ModelH = IsValid ? staticCards[card.RefCard.Idx].ModelHandle : staticCards[0].ModelHandle; + tile.EData.ModelH = isValid ? staticCards[card.RefCard.Idx].ModelHandle : staticCards[0].ModelHandle; Vec3 cardPos = { (float)card.Position.X * Puzzle::Config::CardScaleWorld, -5.0f, (float)card.Position.Y * Puzzle::Config::CardScaleWorld, }; - if (!IsValid) + if (!isValid) { cardPos = {x * Puzzle::Config::CardScaleWorld, -5.0f, y * Puzzle::Config::CardScaleWorld}; } tile.EData.Transform.SetPosition(cardPos); bx::mtxRotateY(tile.EData.Transform.Rotation.M, card.Rotation * bx::kPi * 0.5f); - quad.EData.Visible = IsValid; + quad.EData.Visible = isValid; quad.EData.TextureHandle = - IsValid ? staticCards[card.RefCard.Idx].BoardTextureHandle : Generated::TextureHandle{}; + isValid ? staticCards[card.RefCard.Idx].BoardTextureHandle : Generated::TextureHandle{}; quad.EData.Transform = boardTransform; - quad.EData.Transform.TranslateLocal(Vec3{(float)card.Position.X, (float)card.Position.Y, 0.0f} * 3.0f); - quad.EData.Transform.Scale = {1.0f, 1.0f, 1.0f}; - // quad.EData.Transform.Scale = {0.1f, 0.1f, 0.1f}; - quad.EData.Transform.Rotate(Vec3{bx::kPi * 0.5f, 0.0f, bx::kPi}); + quad.EData.Transform.TranslateLocal(Vec3{(float)card.Position.X, (float)card.Position.Y, 0.0f} * + UICardOffset); + quad.EData.Transform.Scale = {0.1f, 0.1f, 0.1f}; + quad.EData.Transform.Rotate(Vec3{bx::kPi * 0.5f, 0.0f, (1.0f + card.Rotation * 0.5f) * bx::kPi}); - if (clicked && IsValid) + Vec3 quadPosWorld = quad.EData.Transform.GetPosition(); + Vec3 quadXWorld = quad.EData.Transform.LocalToGlobalPoint({1, 0, 0}); + Vec3 quadZWorld = quad.EData.Transform.LocalToGlobalPoint({0, 0, 1}); + Vec3 intersectPos; + if (RayPlaneIntersect( + camTransform.GetPosition(), mousePosWorld, quadPosWorld, quadXWorld, quadZWorld, intersectPos)) { - Vec3 quadPosWorld = quad.EData.Transform.GetPosition(); - Vec3 quadXWorld = quad.EData.Transform.LocalToGlobalPoint({1, 0, 0}); - Vec3 quadYWorld = quad.EData.Transform.LocalToGlobalPoint({0, 0, 1}); - Vec3 intersectPos; - if (RayPlaneIntersect(camTransform.GetPosition(), - mousePosWorld, - quadPosWorld, - quadXWorld, - quadYWorld, - intersectPos)) + Vec3 quadSpaceIntersect = quad.EData.Transform.GlobalToLocalPoint(intersectPos); + if (quadSpaceIntersect.x >= -1.0f && quadSpaceIntersect.x <= 1.0f && + quadSpaceIntersect.z >= -1.0f && quadSpaceIntersect.z <= 1.0f) { - Vec3 quadSpaceIntersect = quad.EData.Transform.GlobalToLocalPoint(intersectPos); - if (quadSpaceIntersect.x >= -1.0f && quadSpaceIntersect.x <= 1.0f && - quadSpaceIntersect.z >= -1.0f && quadSpaceIntersect.z <= 1.0f) + if (isValid && !card.IsLocked && DraggedCard.X == -1 && + GetMouseButtonPressedNow(MouseButton::Left)) { - // LOG("---"); - // LOG("%.03f %.03f: Click", mousePos.x, mousePos.y); - // LOG("%.03f %.03f %.03f: MouseCam", mousePosCam.x, mousePosCam.y, mousePosCam.z); - // LOG("%.03f %.03f %.03f: MouseWorld", mousePosWorld.x, mousePosWorld.y, mousePosWorld.z); - // LOG("%.03f %.03f %.03f: Player", - // camTransform.Position.x, - // camTransform.Position.y, - // camTransform.Position.z); - // LOG("%.03f %.03f %.03f: QuadWorld", quadPosWorld.x, quadPosWorld.y, quadPosWorld.z); - // LOG("%.03f %.03f %.03f: QuadX", quadXWorld.x, quadXWorld.y, quadXWorld.z); - // LOG("%.03f %.03f %.03f: QuadY", quadYWorld.x, quadYWorld.y, quadYWorld.z); - // LOG("%.03f %.03f %.03f: Intersect", intersectPos.x, intersectPos.y, intersectPos.z); - // LOG("%.03f %.03f %.03f: IntersectQ", - // quadSpaceIntersect.x, - // quadSpaceIntersect.y, - // quadSpaceIntersect.z); - LOG("Clicked %u %u", x, y); + DraggedCard.X = x; + DraggedCard.Y = y; } } } + if (DraggedCard.X == x && DraggedCard.Y == y) + { + Vec3 dragPos = intersectPos; + dragPos -= fw * 0.01f; + quad.EData.Transform.SetPosition(dragPos); + + Vec3 boardPos = boardTransform.GlobalToLocalPoint(intersectPos); + Vec3 boardTilePos = boardPos / UICardOffset; + int32_t xPos = (int32_t)bx::round(boardTilePos.x); + int32_t yPos = (int32_t)bx::round(boardTilePos.y); + Generated::PuzPos srcCardPos = {(int8_t)DraggedCard.X, (int8_t)DraggedCard.Y}; + Generated::PlacedPuzzleCard& srcCard = + Data.PlacedCards[srcCardPos.Y * Puzzle::Config::MaxPuzzleSizeCards + srcCardPos.X]; + + if (GetMouseButtonPressedNow(MouseButton::Right)) + { + srcCard.Rotation += 1; + if (srcCard.Rotation >= 4) srcCard.Rotation = 0; + } + + if (!GetMouseButton(MouseButton::Left)) + { + Generated::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) + { + Generated::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)) + { + Puzzle::DragAvailableCardTo(Data, targetCardPos, 0, srcCard.Rotation); + } + } + DraggedCard.X = -1; + DraggedCard.Y = -1; + } + } } } } diff --git a/src/game/Level.h b/src/game/Level.h index fbcbcd2..78df129 100644 --- a/src/game/Level.h +++ b/src/game/Level.h @@ -136,10 +136,12 @@ namespace Game struct WorldPuzzle { static constexpr Vec2 WorldCardSize{10.0f, 10.0f}; + static constexpr float UICardOffset = 0.21f; Generated::PuzzleData Data; Vec3 WorldPosition; PuzzleTileEntityHandle TileHandles[Puzzle::Config::MaxCardsInPuzzle]; UIQuadEntityHandle UIPlacedCards[Puzzle::Config::MaxCardsInPuzzle]; + Generated::PuzPos DraggedCard{-1, -1}; bool IsSetup = false; void Setup(); diff --git a/src/game/Puzzle.cpp b/src/game/Puzzle.cpp index 9bae4a7..997eb33 100644 --- a/src/game/Puzzle.cpp +++ b/src/game/Puzzle.cpp @@ -277,13 +277,16 @@ namespace Puzzle bx::snprintf(buf, bufSize, "%s/%u.pzl", Puzzle::PuzzleFileDir, puzID); } - // TODO: targetPos is of type CardPos bool ReturnPlacedCard(PuzzleData& obj, PuzPos targetPos) { auto& placedCard = obj.PlacedCards[targetPos.Y * Config::MaxPuzzleSizeCards + targetPos.X]; if (IsValid(placedCard.RefCard)) { - if (placedCard.IsLocked) return false; + if (placedCard.IsLocked) + { + LOG_WARN("Card at %i %i is locked!", targetPos.X, targetPos.Y); + return false; + } bool found = false; for (int32_t i = 0; i < obj.AvailableCardCount; ++i) { @@ -304,7 +307,6 @@ namespace Puzzle return true; } - // TODO: targetPos is of type CardPos bool DragAvailableCardTo(PuzzleData& obj, PuzPos targetPos, int32_t availIdx, uint8_t rotation) { if (availIdx >= obj.AvailableCardCount) diff --git a/src/game/Puzzle.h b/src/game/Puzzle.h index 42fdb5f..e951f6b 100644 --- a/src/game/Puzzle.h +++ b/src/game/Puzzle.h @@ -2,7 +2,7 @@ #include #include -#include "Gen.h" +#include "Gen.h" // IWYU pragma: keep namespace Puzzle { @@ -36,6 +36,11 @@ namespace Puzzle PuzzleElementType::Enum& EditCardNodeAt(StaticPuzzleCard& card, uint8_t rotation, int8_t x, int8_t y); void DrawCard(const StaticPuzzleCard& card, uint8_t rotation, ImVec2 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); + struct PuzzleSolver { bool IsPuzzleSolved(const Generated::PuzzleData& puzzle); diff --git a/src/game/rendering/Rendering.cpp b/src/game/rendering/Rendering.cpp index be48267..987e2b5 100644 --- a/src/game/rendering/Rendering.cpp +++ b/src/game/rendering/Rendering.cpp @@ -6,7 +6,7 @@ #include "../Tools.h" #include "Rendering.h" -#include "SDL3/SDL_events.h" +#include "SDL3/SDL_events.h" // IWYU pragma: keep #include "backends/imgui_impl_sdl3.h" #include "bgfx/defines.h" #include "bx/bx.h" diff --git a/src/game/rendering/Rendering.h b/src/game/rendering/Rendering.h index 1f39ec4..e5e9737 100644 --- a/src/game/rendering/Rendering.h +++ b/src/game/rendering/Rendering.h @@ -4,7 +4,7 @@ #include #include -#include "../Gen.h" +#include "../Gen.h" // IWYU pragma: keep #include "../Global.h" #include "Dither.h"