Compare commits

..

11 Commits

Author SHA1 Message Date
Till Wübbers
d6e0cbf41c more tutorial text 2025-06-26 11:12:10 +02:00
Asuro
f95d9dee91 final build ig 2025-06-21 12:31:46 +02:00
Asuro
3c0af71470 puzzle 2025-06-21 12:21:14 +02:00
Asuro
7e89d93a7d bridge 2025-06-21 12:10:53 +02:00
Asuro
05cf88d986 fixes 2025-06-21 11:06:05 +02:00
Asuro
d6bec9e870 rotation fix 2025-06-21 10:57:36 +02:00
Asuro
3ccbbf493f walls 2025-06-21 03:27:25 +02:00
Asuro
b47a0cf841 test puzzles 2025-06-21 00:26:44 +02:00
Asuro
db47297ea4 less sticky movement 2025-06-21 00:26:37 +02:00
Asuro
6461b442de (kinda) fix ui offset 2025-06-21 00:13:51 +02:00
Asuro
146bf4aa22 color changes 2025-06-21 00:04:33 +02:00
34 changed files with 273 additions and 97 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -20,6 +20,8 @@
namespace Game namespace Game
{ {
int32_t GetNextRenderID();
struct EntityRenderData struct EntityRenderData
{ {
Gen::Vec4 DotColor{1.0f, 1.0f, 1.0f, 1.0f}; Gen::Vec4 DotColor{1.0f, 1.0f, 1.0f, 1.0f};
@@ -29,7 +31,7 @@ namespace Game
Gen::TextureHandle TextureHandle; Gen::TextureHandle TextureHandle;
Gen::ModelHandle ModelH; Gen::ModelHandle ModelH;
bool Visible = true; bool Visible = true;
bool DebugBreakOnRender = false; int32_t RenderID = 0;
void Render(const Model* models, const Material* materials, const Texture* textures); void Render(const Model* models, const Material* materials, const Texture* textures);
void LoadFromSaved(const Gen::SavedEntityRenderData& saved); void LoadFromSaved(const Gen::SavedEntityRenderData& saved);
@@ -124,6 +126,7 @@ namespace Game
return {}; return {};
} }
Data[Count] = {}; Data[Count] = {};
Data[Count].EData.RenderID = GetNextRenderID();
HandleT H; HandleT H;
H.Idx = Count; H.Idx = Count;
++Count; ++Count;

View File

@@ -60,6 +60,8 @@ namespace Game
Gen::AssetHandle AssetHandles[MaxAssets]{0}; Gen::AssetHandle AssetHandles[MaxAssets]{0};
char AssetHandlePaths[MaxAssets][128]; char AssetHandlePaths[MaxAssets][128];
bool ShowImguiDemo = false; bool ShowImguiDemo = false;
bool DebugBreakIDEnabled = false;
int DebugBreakID = -1;
uint8_t DebugCardRotation = 0; uint8_t DebugCardRotation = 0;
bool ShortenLogFileNames = true; bool ShortenLogFileNames = true;
bool ShowStats = true; bool ShowStats = true;

View File

@@ -29,10 +29,11 @@ namespace Game
{ {
void EntityRenderData::Render(const Model* models, const Material* materials, const Texture* textures) void EntityRenderData::Render(const Model* models, const Material* materials, const Texture* textures)
{ {
if (DebugBreakOnRender) auto& debug = GetInstance().DebugData;
if ((int32_t)debug.DebugBreakID == RenderID && debug.DebugBreakIDEnabled)
{ {
bx::debugBreak(); bx::debugBreak();
DebugBreakOnRender = false; debug.DebugBreakIDEnabled = false;
} }
if (models == nullptr || materials == nullptr || textures == nullptr) return; if (models == nullptr || materials == nullptr || textures == nullptr) return;
@@ -107,9 +108,8 @@ namespace Game
if (rendering.SetupData.UseImgui) if (rendering.SetupData.UseImgui)
{ {
auto& IO = ImGui::GetIO(); auto& IO = ImGui::GetIO();
IO.ConfigFlags = FlagBool(IO.ConfigFlags, IO.ConfigFlags =
ImGuiConfigFlags_NoMouse | ImGuiConfigFlags_NoKeyboard, FlagBool(IO.ConfigFlags, ImGuiConfigFlags_NoMouse | ImGuiConfigFlags_NoKeyboard, captureMouse);
GetInstance().Player.InteractionM == InteractionMode::Walk);
} }
rendering.UIVisible = IsGaming ? UIVisibilityState::Game : UIVisibilityState::Debug; rendering.UIVisible = IsGaming ? UIVisibilityState::Game : UIVisibilityState::Debug;
} }
@@ -211,6 +211,21 @@ namespace Game
ReloadLevelEntities(); ReloadLevelEntities();
UpdatePlayerInputMode(); UpdatePlayerInputMode();
for (int32_t i = 0; i < BX_COUNTOF(Puzzles); ++i)
{
Puzzles[i].WorldPosition = {0.0f, 0.0f, i * 50.0f};
}
}
bool IsInPuzzle(WorldPuzzle& puz, Vec3 worldPos)
{
Vec3 offsetToPuzzle = worldPos - puz.WorldPosition + (Vec3{0.5f, 0.0f, 0.5f} * Puzzle::Config::CardScaleWorld);
Vec3 scaledOffset = offsetToPuzzle / Puzzle::Config::CardScaleWorld;
int32_t offsetX = (int32_t)bx::floor(scaledOffset.x);
int32_t offsetY = (int32_t)bx::floor(scaledOffset.z);
return (offsetX >= 0 && offsetX < puz.Data.WidthTiles / 2 && offsetY >= -1 &&
offsetY < puz.Data.HeightTiles / 2);
} }
bool IsOnGround(Level& level, Vec3 worldPos) bool IsOnGround(Level& level, Vec3 worldPos)
@@ -221,7 +236,10 @@ namespace Game
worldPos - puz.WorldPosition + (Vec3{0.5f, 0.0f, 0.5f} * Puzzle::Config::CardScaleWorld); worldPos - puz.WorldPosition + (Vec3{0.5f, 0.0f, 0.5f} * Puzzle::Config::CardScaleWorld);
Vec3 scaledOffset = offsetToPuzzle / Puzzle::Config::CardScaleWorld; Vec3 scaledOffset = offsetToPuzzle / Puzzle::Config::CardScaleWorld;
int32_t offsetX = (int32_t)bx::floor(scaledOffset.x); int32_t offsetX = (int32_t)bx::floor(scaledOffset.x);
int32_t offsetY = (int32_t)bx::floor(scaledOffset.z); int32_t offsetY = puz.Data.HeightTiles / 2 - (int32_t)bx::floor(scaledOffset.z) - 1;
float fracOffsetX = scaledOffset.x - offsetX;
float fracOffsetY = scaledOffset.z - bx::floor(scaledOffset.z);
if (offsetX >= 0 && offsetX < puz.Data.WidthTiles / 2 && offsetY >= 0 && offsetY < puz.Data.HeightTiles / 2) if (offsetX >= 0 && offsetX < puz.Data.WidthTiles / 2 && offsetY >= 0 && offsetY < puz.Data.HeightTiles / 2)
{ {
auto& card = puz.Data.PlacedCards[offsetY * Puzzle::Config::MaxPuzzleSizeCards + offsetX]; auto& card = puz.Data.PlacedCards[offsetY * Puzzle::Config::MaxPuzzleSizeCards + offsetX];
@@ -238,8 +256,6 @@ namespace Game
} }
auto& heightmap = GameRendering::Get().Models[refCard.BaseModelHandle.ModelIdx].Height; auto& heightmap = GameRendering::Get().Models[refCard.BaseModelHandle.ModelIdx].Height;
float fracOffsetX = scaledOffset.x - offsetX;
float fracOffsetY = scaledOffset.z - offsetY;
int32_t xPos = (int32_t)(fracOffsetX * heightmap.Width); int32_t xPos = (int32_t)(fracOffsetX * heightmap.Width);
int32_t yPos = (int32_t)(fracOffsetY * heightmap.Height); int32_t yPos = (int32_t)(fracOffsetY * heightmap.Height);
@@ -250,7 +266,7 @@ namespace Game
height = heightmap.Values[yPos * heightmap.Width + xPos]; height = heightmap.Values[yPos * heightmap.Width + xPos];
break; break;
case 1: case 1:
height = heightmap.Values[(heightmap.Height - xPos - 1) * heightmap.Width + yPos]; height = heightmap.Values[xPos * heightmap.Width + (heightmap.Height - yPos - 1)];
break; break;
case 2: case 2:
height = height =
@@ -258,11 +274,19 @@ namespace Game
.Values[(heightmap.Height - yPos - 1) * heightmap.Width + (heightmap.Width - xPos - 1)]; .Values[(heightmap.Height - yPos - 1) * heightmap.Width + (heightmap.Width - xPos - 1)];
break; break;
default: default:
height = heightmap.Values[xPos * heightmap.Width + (heightmap.Height - yPos - 1)]; height = heightmap.Values[(heightmap.Height - xPos - 1) * heightmap.Width + yPos];
break; break;
} }
return height >= 110 && height <= 125; return height >= 110 && height <= 125;
} }
if (offsetX == 1 && offsetY == puz.Data.HeightTiles / Puzzle::Config::CardSize)
{
if (puz.IsSolved)
{
return true;
}
return true; // TODO!
}
} }
return false; return false;
} }
@@ -319,14 +343,37 @@ namespace Game
else if (player.CameraM == CameraMode::Walk) else if (player.CameraM == CameraMode::Walk)
{ {
auto newTransform = player.PlayerCamTransform; auto newTransform = player.PlayerCamTransform;
TranslateLocal(newTransform, {0.0f, 0.0f, inputVec.z}); // Global and local are inverted because camera
TranslateLocal(newTransform, {inputVec.x, 0.0f, 0.0f}); Vec3 globalInput = GlobalToLocalDirection(newTransform, {inputVec.x, 0.0f, inputVec.z});
Translate(newTransform, globalInput);
newTransform.Position.y = 3.0f; newTransform.Position.y = 3.0f;
if (IsOnGround(*this, newTransform.Position)) if (IsOnGround(*this, newTransform.Position))
{ {
player.PlayerCamTransform = newTransform; player.PlayerCamTransform = newTransform;
} }
else
{
auto newTransform = player.PlayerCamTransform;
Translate(newTransform, {globalInput.x, 0.0f, 0.0f});
newTransform.Position.y = 3.0f;
if (IsOnGround(*this, newTransform.Position))
{
player.PlayerCamTransform = newTransform;
}
else
{
auto newTransform = player.PlayerCamTransform;
Translate(newTransform, {0.0f, 0.0f, globalInput.z});
newTransform.Position.y = 3.0f;
if (IsOnGround(*this, newTransform.Position))
{
player.PlayerCamTransform = newTransform;
}
}
}
player.WalkXRot += rotInput.x; player.WalkXRot += rotInput.x;
player.WalkYRot += rotInput.y; player.WalkYRot += rotInput.y;
@@ -347,16 +394,20 @@ namespace Game
} }
// Puzzle tiles // Puzzle tiles
Puzzle::PuzzleSolver solver;
uint16_t activeIdx = GetInstance().DebugData.SelectedDebugLevel; 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)
{ {
if (IsInPuzzle(Puzzles[i], player.PlayerCamTransform.Position))
{
activeIdx = i;
}
Puzzles[i].IsActive = activeIdx == i; Puzzles[i].IsActive = activeIdx == i;
Puzzles[i].Update(); Puzzles[i].Update();
Puzzles[i].IsSolved = solver.IsPuzzleSolved(Puzzles[i].Data);
} }
Puzzle::PuzzleSolver solver; PuzzleUI.Update(Puzzles[activeIdx].Data, Puzzles[activeIdx].IsSolved);
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);
} }
@@ -422,26 +473,52 @@ namespace Game
void WorldPuzzle::Setup() void WorldPuzzle::Setup()
{ {
auto& level = GetInstance().GameLevel; Level& level = GetInstance().GameLevel;
for (int32_t i = 0; i < Puzzle::Config::MaxCardsInPuzzle; ++i) for (int32_t i = 0; i < Puzzle::Config::MaxCardsInPuzzle; ++i)
{ {
TileHandles[i] = level.PuzzleTiles.New(); TileHandles[i] = level.PuzzleTiles.New();
auto& tile = level.PuzzleTiles.Get(TileHandles[i]); PuzzleTileEntity& tile = level.PuzzleTiles.Get(TileHandles[i]);
tile.EData.MaterialHandle = EMaterial::Default; tile.EData.MaterialHandle = EMaterial::Default;
for (int32_t j = 0; j < Puzzle::Config::MaxCoversInTile; ++j) for (int32_t j = 0; j < Puzzle::Config::MaxCoversInTile; ++j)
{ {
int32_t idx = i * Puzzle::Config::MaxCoversInTile + j; int32_t idx = i * Puzzle::Config::MaxCoversInTile + j;
CoverHandles[idx] = level.PuzzleTileCovers.New(); CoverHandles[idx] = level.PuzzleTileCovers.New();
auto& cover = level.PuzzleTileCovers.Get(CoverHandles[idx]); PuzzleTileCover& cover = level.PuzzleTileCovers.Get(CoverHandles[idx]);
cover.EData.Visible = false; cover.EData.Visible = false;
} }
} }
for (int32_t i = 0; i < BX_COUNTOF(EndHandles); ++i)
{
EndHandles[i] = level.PuzzleTiles.New();
PuzzleTileEntity& tile = level.PuzzleTiles.Get(EndHandles[i]);
tile.EData.MaterialHandle = EMaterial::Default;
}
WallHandle = level.PuzzleTiles.New();
PuzzleTileEntity& wHandle = level.PuzzleTiles.Get(WallHandle);
wHandle.EData.MaterialHandle = EMaterial::Default;
wHandle.EData.ModelH = GameRendering::Get().GetModelHandleFromPath("models/GateWall.glb");
DoorHandle = level.PuzzleTiles.New();
PuzzleTileEntity& dHandle = level.PuzzleTiles.Get(DoorHandle);
dHandle.EData.MaterialHandle = EMaterial::Default;
dHandle.EData.ModelH = GameRendering::Get().GetModelHandleFromPath("models/GateDoor.glb");
IsSetup = true; IsSetup = true;
LOG("finished setup!"); LOG("finished setup!");
} }
Vec3 PuzPosToWorldPos(const PuzzleData& data, int32_t x, int32_t y)
{
return {
(float)x * Puzzle::Config::CardScaleWorld,
-5.0f,
(float)(data.HeightTiles / 2 - y - 1) * Puzzle::Config::CardScaleWorld,
};
}
void WorldPuzzle::Update() void WorldPuzzle::Update()
{ {
Level& level = GetInstance().GameLevel; Level& level = GetInstance().GameLevel;
@@ -468,17 +545,13 @@ namespace Game
tile.EData.DotColor = visuals.TileDotColor; tile.EData.DotColor = visuals.TileDotColor;
tile.EData.BaseColor = visuals.TileBaseColor; tile.EData.BaseColor = visuals.TileBaseColor;
Vec3 cardPos = { Vec3 cardPos = PuzPosToWorldPos(Data, card.Position.X, card.Position.Y);
(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}; cardPos = PuzPosToWorldPos(Data, x, y);
} }
tile.EData.Transform.Position = cardPos + WorldPosition; tile.EData.Transform.Position = cardPos + WorldPosition;
bx::mtxRotateY(tile.EData.Transform.Rotation.M, card.Rotation * bx::kPi * 0.5f); bx::mtxRotateY(tile.EData.Transform.Rotation.M, card.Rotation * bx::kPi * -0.5f);
// Covers // Covers
if (IsValid(staticCard.BaseModelHandle)) if (IsValid(staticCard.BaseModelHandle))
@@ -491,12 +564,48 @@ namespace Game
cover.EData.Visible = IsActive; cover.EData.Visible = IsActive;
cover.EData.ModelH = staticCard.Sockets[i].Model; cover.EData.ModelH = staticCard.Sockets[i].Model;
cover.EData.Transform = tile.EData.Transform; cover.EData.Transform = tile.EData.Transform;
cover.EData.MaterialHandle = EMaterial::Default;
cover.EData.BaseColor = {0.2f, 0.1f, 0.7f, 1.0f};
cover.EData.DotColor = {0.2f, 0.2f, 0.8f, 1.0f};
Gen::TranslateLocal(cover.EData.Transform, model.Sockets[i].Pos); Gen::TranslateLocal(cover.EData.Transform, model.Sockets[i].Pos);
Gen::RotateLocal(cover.EData.Transform, Gen::EulerFromRotation(model.Sockets[i].Rot)); Gen::RotateLocal(cover.EData.Transform, Gen::EulerFromRotation(model.Sockets[i].Rot));
} }
} }
} }
} }
// End
for (int32_t i = 0; i < BX_COUNTOF(EndHandles); ++i)
{
auto& tile = level.PuzzleTiles.Get(EndHandles[i]);
if (i < Data.WidthTiles / 2)
{
tile.EData.Visible = true;
tile.EData.ModelH = staticCards[0].BaseModelHandle;
tile.EData.TextureHandle = staticCards[0].ModelTextureHandle;
tile.EData.DotColor = visuals.TileDotColor;
tile.EData.BaseColor = visuals.TileBaseColor + Vec4{0.1f, 0.1f, 0.1f, 0.0f};
tile.EData.Transform.Position = WorldPosition + Vec3{
i * Puzzle::Config::CardScaleWorld,
-5.0f,
(float)Data.HeightTiles / Puzzle::Config::CardSize *
Puzzle::Config::CardScaleWorld,
};
}
else
{
tile.EData.Visible = false;
}
}
auto& wall = level.PuzzleTiles.Get(WallHandle);
wall.EData.Visible = true;
wall.EData.Transform.Position =
WorldPosition + Vec3{0.0f, 0.0f, Data.HeightTiles * 5.0f} + Vec3{30.0f, -5.0f, 0.2f};
auto& door = level.PuzzleTiles.Get(DoorHandle);
door.EData.Visible = !IsSolved;
door.EData.Transform.Position =
WorldPosition + Vec3{0.0f, 0.0f, Data.HeightTiles * 5.0f} + Vec3{30.0f, -5.0f, 0.2f};
} }
void Level::ReloadLevelEntities() void Level::ReloadLevelEntities()
@@ -510,4 +619,10 @@ namespace Game
} }
} }
int32_t GetNextRenderID()
{
static int32_t RenderIDCounter = 0;
RenderIDCounter++;
return RenderIDCounter;
}
} // namespace Game } // namespace Game

View File

@@ -18,12 +18,15 @@ namespace Game
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];
PuzzleTileEntityHandle EndHandles[Puzzle::Config::MaxPuzzleSizeCards];
PuzzleTileEntityHandle WallHandle;
PuzzleTileEntityHandle DoorHandle;
bool IsSetup = false; bool IsSetup = false;
bool IsActive = false; bool IsActive = false;
bool IsSolved = false;
void Setup(); void Setup();
void Update(); void Update();
void Reset(); // TODO!
}; };
class Level class Level

View File

@@ -1,7 +1,6 @@
#include "../gen/Def.h" #include "../gen/Def.h"
#include "Gen.h" #include "Gen.h"
#include "Global.h" #include "Global.h"
#include "Instance.h"
#include "Log.h" #include "Log.h"
#include "Puzzle.h" #include "Puzzle.h"

View File

@@ -19,7 +19,8 @@ namespace Puzzle
static constexpr uint32_t MaxCardsInPuzzle = MaxPuzzleSizeCards * MaxPuzzleSizeCards; static constexpr uint32_t MaxCardsInPuzzle = MaxPuzzleSizeCards * MaxPuzzleSizeCards;
static constexpr uint32_t MaxPuzzleSizeTiles = 16 * CardSize; static constexpr uint32_t MaxPuzzleSizeTiles = 16 * CardSize;
static constexpr uint32_t MaxTilesInPuzzle = MaxPuzzleSizeTiles * MaxPuzzleSizeTiles; static constexpr uint32_t MaxTilesInPuzzle = MaxPuzzleSizeTiles * MaxPuzzleSizeTiles;
static constexpr uint32_t MaxTilesTotal = MaxTilesInPuzzle * MaxVisiblePuzzles; static constexpr uint32_t MaxTilesTotal =
MaxTilesInPuzzle * MaxVisiblePuzzles + MaxPuzzleSizeCards * MaxVisiblePuzzles + 64;
static constexpr uint32_t MaxAvailableStacks = 16; static constexpr uint32_t MaxAvailableStacks = 16;
static constexpr uint32_t MaxGoalPositions = 16; static constexpr uint32_t MaxGoalPositions = 16;
static constexpr float CardScaleWorld = 10.0f; static constexpr float CardScaleWorld = 10.0f;

View File

@@ -566,13 +566,12 @@ namespace Tools
ImGui::Text("%u", i); ImGui::Text("%u", i);
ImGui::SameLine(); ImGui::SameLine();
auto& quad = level.UIQuads.Get({i}); auto& quad = level.UIQuads.Get({i});
ImGui::Checkbox("Debug Break on Render", &quad.EData.DebugBreakOnRender);
ImGui::SameLine();
ImGui::Checkbox("Visible", &quad.EData.Visible); ImGui::Checkbox("Visible", &quad.EData.Visible);
TextureDropdown(quad.EData.TextureHandle); TextureDropdown(quad.EData.TextureHandle);
MaterialDropdown(quad.EData.MaterialHandle); MaterialDropdown(quad.EData.MaterialHandle);
ImGui::DragFloat3("Pos", &quad.EData.Transform.Position.x); ImGui::DragFloat3("Pos", &quad.EData.Transform.Position.x);
ImGui::DragFloat3("UI Pos", &quad.UIPos.x); ImGui::DragFloat3("UI Pos", &quad.UIPos.x);
ImGui::Text("RenderID: %i", quad.EData.RenderID);
ImGui::PopID(); ImGui::PopID();
} }
ImGui::TreePop(); ImGui::TreePop();
@@ -587,12 +586,11 @@ namespace Tools
ImGui::Text("%u", i); ImGui::Text("%u", i);
ImGui::SameLine(); ImGui::SameLine();
auto& levelEnt = level.LevelEntities.Get({i}); auto& levelEnt = level.LevelEntities.Get({i});
ImGui::Checkbox("Debug Break on Render", &levelEnt.EData.DebugBreakOnRender);
ImGui::SameLine();
ImGui::Checkbox("Visible", &levelEnt.EData.Visible); ImGui::Checkbox("Visible", &levelEnt.EData.Visible);
TextureDropdown(levelEnt.EData.TextureHandle); TextureDropdown(levelEnt.EData.TextureHandle);
MaterialDropdown(levelEnt.EData.MaterialHandle); MaterialDropdown(levelEnt.EData.MaterialHandle);
ImGui::DragFloat3("Pos", &levelEnt.EData.Transform.Position.x); ImGui::DragFloat3("Pos", &levelEnt.EData.Transform.Position.x);
ImGui::Text("RenderID: %i", levelEnt.EData.RenderID);
ImGui::PopID(); ImGui::PopID();
} }
ImGui::TreePop(); ImGui::TreePop();
@@ -670,6 +668,11 @@ namespace Tools
{ {
if (ImGui::Button("Spiel Neustarten")) if (ImGui::Button("Spiel Neustarten"))
{ {
player.PlayerCamTransform.Position = {0.0f, 3.0f, 0.0f};
for (int32_t i = 0; i < BX_COUNTOF(level.Puzzles); ++i)
{
Puzzle::ResetPuzzle(level.Puzzles[i].Data);
}
} }
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::Button("Zurück zum Anfang")) if (ImGui::Button("Zurück zum Anfang"))
@@ -680,16 +683,25 @@ namespace Tools
ImGui::Text("Anleitung:"); ImGui::Text("Anleitung:");
ImGui::Text("Bewege dich mit"); ImGui::Text("Bewege dich mit");
ImGui::SameLine(); ImGui::SameLine();
ImGui::TextColored({1.0f, 0.8f, 0.8f, 1.0f}, "W, A, S, D"); ImGui::TextColored({1.0f, 0.6f, 0.6f, 1.0f}, "W, A, S, D");
ImGui::SameLine(); ImGui::SameLine();
ImGui::Text("und schau dich um mit der"); ImGui::Text("und schau dich um mit der");
ImGui::SameLine(); ImGui::SameLine();
ImGui::TextColored({1.0f, 0.8f, 0.8f, 1.0f}, "Maus."); ImGui::TextColored({1.0f, 0.6f, 0.6f, 1.0f}, "Maus.");
ImGui::Text("Drücke"); ImGui::Text("Drücke");
ImGui::SameLine(); ImGui::SameLine();
ImGui::TextColored({1.0f, 0.8f, 0.8f, 1.0f}, "Leertaste"); ImGui::TextColored({1.0f, 0.6f, 0.6f, 1.0f}, "Leertaste");
ImGui::SameLine(); ImGui::SameLine();
ImGui::Text("um den Spielplan zu öffnen."); ImGui::Text("um den Spielplan zu öffnen.");
ImGui::Text("Auf dem Spielplan kannst du Karten verschieben.");
ImGui::Text("Mit");
ImGui::SameLine();
ImGui::TextColored({1.0f, 0.6f, 0.6f, 1.0f}, "Rechter Maustaste");
ImGui::SameLine();
ImGui::Text("kannst du Karten drehen.");
ImGui::Text("");
ImGui::Text("Dein Ziel: Verbinde die Pumpe mit dem Abfluss, um das");
ImGui::Text("Tor zum nächsten Level zu öffnen!");
ImGui::Text(""); ImGui::Text("");
auto& inflowTexture = rendering.Textures[10]; auto& inflowTexture = rendering.Textures[10];
auto& outflowTexture = rendering.Textures[9]; auto& outflowTexture = rendering.Textures[9];
@@ -715,6 +727,11 @@ namespace Tools
{ {
ImGui::Checkbox("ImGui Demo", &debug.ShowImguiDemo); ImGui::Checkbox("ImGui Demo", &debug.ShowImguiDemo);
ImGui::SliderFloat("Font Scale", &ImGui::GetIO().FontGlobalScale, 0.5f, 4.0f); ImGui::SliderFloat("Font Scale", &ImGui::GetIO().FontGlobalScale, 0.5f, 4.0f);
ImGui::Checkbox("Break on ID", &debug.DebugBreakIDEnabled);
ImGui::SameLine();
ImGui::PushID("@#$");
ImGui::InputInt("", &debug.DebugBreakID);
ImGui::PopID();
ImGui::Separator(); ImGui::Separator();
ImGui::Text("Arenas"); ImGui::Text("Arenas");

View File

@@ -114,6 +114,32 @@ namespace Game
} }
} }
Vec3 CalcBoardOffset(const Gen::PuzzleData& puzData)
{
return Vec3{
(float)(puzData.WidthTiles) / 2.0f - 0.5f,
(float)(puzData.HeightTiles) / 2.0f - 0.5f,
0.0f,
} *
WorldPuzzleUI::UICardScale * WorldPuzzleUI::UICardScale;
}
Vec3 CardPosToUIPos(const Gen::PuzzleData& data, int32_t cardX, int32_t cardY)
{
return Vec3{(float)cardX, (float)(data.HeightTiles / 2 - cardY - 1), -0.3f} * WorldPuzzleUI::UICardOffset *
WorldPuzzleUI::UICardScale -
CalcBoardOffset(data);
}
void UIPosToCardPos(const Gen::PuzzleData& data, Vec3 uiPos, int32_t& cardXOut, int32_t& cardYOut)
{
Vec3 boardOffset = CalcBoardOffset(data) / WorldPuzzleUI::UICardScale;
Vec3 boardPos = GlobalToLocalPoint(StaticData.UITransform, uiPos);
Vec3 boardTilePos = (boardPos + boardOffset) / WorldPuzzleUI::UICardOffset;
cardXOut = (int32_t)bx::round(boardTilePos.x);
cardYOut = data.HeightTiles / 2 - (int32_t)bx::round(boardTilePos.y) - 1;
}
void WorldPuzzleUI::UpdateAvailableCards(Gen::PuzzleData& Data) void WorldPuzzleUI::UpdateAvailableCards(Gen::PuzzleData& Data)
{ {
auto& level = GetInstance().GameLevel; auto& level = GetInstance().GameLevel;
@@ -159,10 +185,9 @@ namespace Game
dragPos += StaticData.ZAxis * -0.01f; dragPos += StaticData.ZAxis * -0.01f;
quad.EData.Transform.Position = dragPos; quad.EData.Transform.Position = dragPos;
Vec3 boardPos = GlobalToLocalPoint(StaticData.UITransform, quadPlaneIntersectPos); int32_t xPos;
Vec3 boardTilePos = boardPos / UICardOffset; int32_t yPos;
int32_t xPos = (int32_t)bx::round(boardTilePos.x); UIPosToCardPos(Data, quadPlaneIntersectPos, xPos, yPos);
int32_t yPos = (int32_t)bx::round(boardTilePos.y);
if (!GetMouseButton(MouseButton::Left)) if (!GetMouseButton(MouseButton::Left))
{ {
@@ -190,17 +215,6 @@ namespace Game
} }
} }
Vec3 CalcBoardOffset(const Gen::PuzzleData& puzData)
{
return {};
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) void WorldPuzzleUI::UpdateBoardCards(Gen::PuzzleData& Data)
{ {
auto& level = GetInstance().GameLevel; auto& level = GetInstance().GameLevel;
@@ -219,9 +233,8 @@ namespace Game
bool isLocked = GetFlag(card.Flags, PlacedPuzzleCardFlags::Locked); bool isLocked = GetFlag(card.Flags, PlacedPuzzleCardFlags::Locked);
auto& quad = level.UIQuads.Get(UIPlacedCards[cardIdx]); auto& quad = level.UIQuads.Get(UIPlacedCards[cardIdx]);
quad.UIPos = Vec3{(float)card.Position.X, (float)card.Position.Y, -0.3f} * UICardOffset * UICardScale; quad.UIPos = CardPosToUIPos(Data, card.Position.X, card.Position.Y);
quad.UIPos -= boardOffset; quad.UIRot = card.Rotation * bx::kPi * -0.5f;
quad.UIRot = card.Rotation * bx::kPi * 0.5f;
UpdateQuad(level.UIQuads, UIPlacedCards[cardIdx]); UpdateQuad(level.UIQuads, UIPlacedCards[cardIdx]);
quad.EData.Visible = isValid; quad.EData.Visible = isValid;
@@ -253,10 +266,9 @@ namespace Game
dragPos += StaticData.ZAxis * -0.01f; dragPos += StaticData.ZAxis * -0.01f;
quad.EData.Transform.Position = dragPos; quad.EData.Transform.Position = dragPos;
Vec3 boardPos = GlobalToLocalPoint(StaticData.UITransform, quadPlaneIntersectPos); int32_t xPos;
Vec3 boardTilePos = boardPos / UICardOffset; int32_t yPos;
int32_t xPos = (int32_t)bx::round(boardTilePos.x); UIPosToCardPos(Data, quadPlaneIntersectPos, xPos, yPos);
int32_t yPos = (int32_t)bx::round(boardTilePos.y);
Gen::PuzPos srcCardPos = {(int8_t)DraggedCard.X, (int8_t)DraggedCard.Y}; Gen::PuzPos srcCardPos = {(int8_t)DraggedCard.X, (int8_t)DraggedCard.Y};
Gen::PlacedPuzzleCard& srcCard = Gen::PlacedPuzzleCard& srcCard =
Data.PlacedCards[srcCardPos.Y * Puzzle::Config::MaxPuzzleSizeCards + srcCardPos.X]; Data.PlacedCards[srcCardPos.Y * Puzzle::Config::MaxPuzzleSizeCards + srcCardPos.X];

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -86,12 +86,26 @@ float dither(float brightness, vec2 inputUv)
vec4 rgbToCmyk(vec3 rgb) vec4 rgbToCmyk(vec3 rgb)
{ {
return vec4(1.0, 1.0, 1.0, 1.0); float k = min(1.0 - rgb.r, min(1.0 - rgb.g, 1.0 - rgb.b));
vec3 cmy = vec3(0.0, 0.0, 0.0);
float invK = 1.0 - k;
if (invK != 0.0)
{
cmy.x = 1.0 - rgb.r - k;
cmy.y = 1.0 - rgb.g - k;
cmy.z = 1.0 - rgb.b - k;
cmy /= invK;
}
return saturate(vec4(cmy, k));
} }
vec3 cmykToRgb(vec4 cmyk) vec3 cmykToRgb(vec4 cmyk)
{ {
return vec3(1.0, 1.0, 1.0); float invK = 1.0 - cmyk.w;
float r = 1.0 - min(1.0, cmyk.x * invK + cmyk.w);
float g = 1.0 - min(1.0, cmyk.y * invK + cmyk.w);
float b = 1.0 - min(1.0, cmyk.z * invK + cmyk.w);
return saturate(vec3(r,g,b));
} }
vec2 rotateUV(vec2 uv, vec2 angle) vec2 rotateUV(vec2 uv, vec2 angle)
@@ -117,17 +131,17 @@ void main()
float r = dither(texColor.r * brightness, v_uv0); float r = dither(texColor.r * brightness, v_uv0);
float g = dither(texColor.g * brightness, v_uv0); float g = dither(texColor.g * brightness, v_uv0);
float b = dither(texColor.b * brightness, v_uv0); float b = dither(texColor.b * brightness, v_uv0);
vec3 ditheredColor = vec3(r,g,b); // vec3 ditheredColor = vec3(r,g,b);
vec4 cmyk = rgbToCmyk(texColor * brightness); vec4 cmyk = rgbToCmyk(texColor * brightness);
cmyk.x = dither(cmyk.x, rotateUV(v_uv0, float2(0.966, 0.259))); cmyk.x = dither(cmyk.x, rotateUV(v_uv0, float2(0.966, 0.259)));
cmyk.y = dither(cmyk.y, rotateUV(v_uv0, float2(0.259, 0.966))); cmyk.y = dither(cmyk.y, rotateUV(v_uv0, float2(0.259, 0.966)));
cmyk.z = dither(cmyk.z, rotateUV(v_uv0, float2(1.000, 0.000))); cmyk.z = dither(cmyk.z, rotateUV(v_uv0, float2(1.000, 0.000)));
cmyk.w = dither(cmyk.w, rotateUV(v_uv0, float2(0.707, 0.707))); cmyk.w = dither(cmyk.w, rotateUV(v_uv0, float2(0.707, 0.707)));
// vec3 ditheredColor = cmykToRgb(cmyk); vec3 ditheredColor = cmykToRgb(cmyk);
// finalize // finalize
vec3 finalColor = mix(baseColor, ditheredColor, ditheredColor); vec3 finalColor = mix(baseColor, ditheredColor, ditheredColor);
gl_FragColor = vec4(finalColor, 1.0); gl_FragColor = vec4(finalColor.rg, finalColor.b * 0.99, 1.0);
// gl_FragColor = vec4(texColor * brightness, 1.0); // gl_FragColor = vec4(ditheredColor, 1.0);
} }

Binary file not shown.

BIN
src/models/GateDoor.glb LFS Normal file

Binary file not shown.

BIN
src/models/GateWall.glb LFS Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
src/models/z_water_cover.glb LFS Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,17 +1,18 @@
// raddbg 0.9.19 project file // raddbg 0.9.19 project file
recent_file: path: "../src/game/level.cpp" recent_file: path: "../src/game/level.cpp"
recent_file: path: "../src/game/puzzle.cpp"
recent_file: path: "../src/dependency/bgfx.cmake/bx/src/debug.cpp"
recent_file: path: "../src/game/entity.h"
recent_file: path: "../src/game/ui.cpp"
recent_file: path: "../src/game/Log.cpp" recent_file: path: "../src/game/Log.cpp"
recent_file: path: "../src/game/rendering/dither.cpp" recent_file: path: "../src/game/rendering/dither.cpp"
recent_file: path: "../src/game/rendering/rendering.cpp" recent_file: path: "../src/game/rendering/rendering.cpp"
recent_file: path: "../src/game/entity.h"
recent_file: path: "../src/game/ui.cpp"
recent_file: path: "../src/gen/generated.cpp" recent_file: path: "../src/gen/generated.cpp"
recent_file: path: "../src/engine/main.cpp" recent_file: path: "../src/engine/main.cpp"
recent_file: path: "../src/game/setup.cpp" recent_file: path: "../src/game/setup.cpp"
recent_file: path: "../src/dependency/imgui/imgui_widgets.cpp" recent_file: path: "../src/dependency/imgui/imgui_widgets.cpp"
recent_file: path: "../src/game/tools.cpp" recent_file: path: "../src/game/tools.cpp"
recent_file: path: "../src/dependency/bgfx.cmake/bx/src/debug.cpp"
recent_file: path: "../src/gen/def.h" recent_file: path: "../src/gen/def.h"
recent_file: path: "../src/game/global.cpp" recent_file: path: "../src/game/global.cpp"
target: target: