working puzzle editor?
This commit is contained in:
@@ -19,6 +19,7 @@ namespace
|
||||
};
|
||||
|
||||
Generated::StaticPuzzleData StaticData;
|
||||
Generated::StaticPuzzleCard InvalidCard;
|
||||
} // namespace
|
||||
|
||||
namespace Puzzle
|
||||
@@ -61,7 +62,11 @@ namespace Puzzle
|
||||
}
|
||||
const StaticPuzzleCard& GetCard(StaticPuzzleCardHandle H)
|
||||
{
|
||||
assert(IsValid(H));
|
||||
if (H.Idx == UINT16_MAX)
|
||||
{
|
||||
LOG_ERROR("Invalid static card handle!");
|
||||
return InvalidCard;
|
||||
}
|
||||
return GetStaticPuzzleData().Cards[H.Idx];
|
||||
}
|
||||
|
||||
@@ -83,22 +88,20 @@ namespace Puzzle
|
||||
|
||||
PuzzleElementType::Enum GetNodeAt(const PuzzleData& puz, PuzPos pos)
|
||||
{
|
||||
assert(pos.X < Puzzle::Config::MaxPuzzleSizeCards && pos.Y < Puzzle::Config::MaxPuzzleSizeCards && pos.X >= 0 &&
|
||||
assert(pos.X < Puzzle::Config::MaxPuzzleSizeTiles && pos.Y < Puzzle::Config::MaxPuzzleSizeTiles && pos.X >= 0 &&
|
||||
pos.Y >= 0);
|
||||
// TODO: this is horrible
|
||||
for (int32_t i = 0; i < puz.PlacedCardCount; ++i)
|
||||
int32_t cardIdxX = pos.X / Puzzle::Config::CardSize;
|
||||
int32_t cardIdxY = pos.Y / Puzzle::Config::CardSize;
|
||||
auto& card = puz.PlacedCards[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))
|
||||
{
|
||||
auto& card = puz.PlacedCards[i];
|
||||
int8_t offsetX = pos.X - card.Position.X;
|
||||
int8_t offsetY = pos.Y - card.Position.Y;
|
||||
if (offsetX >= 0 && offsetX < Puzzle::Config::CardSize && offsetY >= 0 &&
|
||||
offsetY < Puzzle::Config::CardSize)
|
||||
{
|
||||
PuzzleElementType::Enum cardVal = GetCardNodeAt(GetCard(card.RefCard), card.Rotation, offsetX, offsetY);
|
||||
if (cardVal != PuzzleElementType::None) return cardVal;
|
||||
}
|
||||
PuzzleElementType::Enum cardVal = GetCardNodeAt(GetCard(card.RefCard), card.Rotation, offsetX, offsetY);
|
||||
if (cardVal != PuzzleElementType::None) return cardVal;
|
||||
}
|
||||
return puz.BackgroundTiles[pos.Y * Puzzle::Config::MaxPuzzleSizeCards + pos.X];
|
||||
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)
|
||||
@@ -260,9 +263,58 @@ 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;
|
||||
bool found = false;
|
||||
for (int32_t i = 0; i < obj.AvailableCardCount; ++i)
|
||||
{
|
||||
if (obj.AvailableCards[i].RefCard.Idx == placedCard.RefCard.Idx && obj.AvailableCards[i].UsedCount > 0)
|
||||
{
|
||||
obj.AvailableCards[i].UsedCount--;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
LOG_ERROR("Failed to find available card to return placed card of type %u to!", placedCard.RefCard.Idx);
|
||||
return false;
|
||||
}
|
||||
placedCard.RefCard = {};
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: targetPos is of type CardPos
|
||||
bool DragAvailableCardTo(PuzzleData& obj, PuzPos targetPos, int32_t availIdx, uint8_t rotation)
|
||||
{
|
||||
if (availIdx >= obj.AvailableCardCount)
|
||||
{
|
||||
LOG_ERROR("Invalid drag with avail idx %i!", availIdx);
|
||||
return false;
|
||||
}
|
||||
if (!ReturnPlacedCard(obj, targetPos)) return false;
|
||||
|
||||
auto& draggedCard = obj.AvailableCards[availIdx];
|
||||
draggedCard.UsedCount++;
|
||||
|
||||
auto& placedCard = obj.PlacedCards[targetPos.Y * Config::MaxPuzzleSizeCards + targetPos.X];
|
||||
placedCard.RefCard = draggedCard.RefCard;
|
||||
placedCard.IsLocked = false;
|
||||
placedCard.Position = targetPos;
|
||||
placedCard.Rotation = rotation;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RenderDebugUI(PuzzleData& obj)
|
||||
{
|
||||
bool dataChanged = false;
|
||||
uint8_t debugRot = Game::GetInstance().DebugData.DebugCardRotation;
|
||||
|
||||
bool isVisible = true;
|
||||
if (ImGui::Begin("Puzzle", &isVisible))
|
||||
@@ -327,14 +379,61 @@ 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];
|
||||
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 (placedCard.IsLocked)
|
||||
{
|
||||
placedCard.IsLocked = false;
|
||||
placedCard.RefCard = {};
|
||||
dataChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ReturnPlacedCard(obj, cardPos))
|
||||
{
|
||||
placedCard.IsLocked = false;
|
||||
placedCard.RefCard = {};
|
||||
dataChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!placedCard.IsLocked && IsValid(placedCard.RefCard))
|
||||
{
|
||||
ImVec2 s = {puzCursorStart.x + x * UIPuzBoxSize, puzCursorStart.y + y * UIPuzBoxSize};
|
||||
drawList.AddRectFilled(s,
|
||||
{s.x + UIPuzBoxSize * Puzzle::Config::CardSize,
|
||||
s.y + UIPuzBoxSize * Puzzle::Config::CardSize},
|
||||
0x33FFFFFF);
|
||||
}
|
||||
if (ImGui::BeginDragDropTarget())
|
||||
{
|
||||
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("cardtype", 0))
|
||||
{
|
||||
uint32_t CardIdx = *reinterpret_cast<uint32_t*>(payload->Data);
|
||||
obj.PlacedCards[obj.PlacedCardCount].RefCard = {(uint16_t)CardIdx};
|
||||
obj.PlacedCardCount++;
|
||||
placedCard = {};
|
||||
placedCard.RefCard = {(uint16_t)CardIdx};
|
||||
placedCard.Rotation = debugRot;
|
||||
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);
|
||||
}
|
||||
ImGui::EndDragDropTarget();
|
||||
}
|
||||
@@ -401,17 +500,42 @@ namespace Puzzle
|
||||
}
|
||||
if (bAvailOpen)
|
||||
{
|
||||
uint8_t debugRot = Game::GetInstance().DebugData.DebugCardRotation;
|
||||
ImVec2 startPos = ImGui::GetCursorScreenPos();
|
||||
for (uint32_t i = 0; i < obj.AvailableCardCount; ++i)
|
||||
{
|
||||
ImVec2 localPos = {startPos.x + i * 60.0f, startPos.y};
|
||||
ImGui::SetCursorScreenPos(localPos);
|
||||
ImGui::PushID(i);
|
||||
auto& card = obj.AvailableCards[i];
|
||||
DrawCard(GetCard(card.RefCard), debugRot, ImGui::GetCursorScreenPos());
|
||||
if (ImGui::BeginDragDropSource())
|
||||
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);
|
||||
ImGui::PushID("carc");
|
||||
if (ImGui::DragInt("", &displayCount, 0.25f))
|
||||
{
|
||||
int diff = displayCount - (card.MaxAvailableCount - card.UsedCount);
|
||||
card.MaxAvailableCount = bx::max(0, card.MaxAvailableCount + diff);
|
||||
dataChanged = true;
|
||||
}
|
||||
ImGui::PopID();
|
||||
ImGui::SameLine(0, 3);
|
||||
if (ImGui::Button("x"))
|
||||
{
|
||||
if (i < obj.AvailableCardCount - 1)
|
||||
{
|
||||
obj.AvailableCards[i] = obj.AvailableCards[obj.AvailableCardCount - 1];
|
||||
}
|
||||
obj.AvailableCardCount--;
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user