[jasper/world]/studio] Make World refer to obj sets with UUIDs
Some checks failed
Build / build (push) Failing after 30s
Some checks failed
Build / build (push) Failing after 30s
This commit is contained in:
parent
8e9274a84b
commit
299a91fd66
@ -110,13 +110,17 @@ void loadTile(ObjectCache const&objCache, TileStatic &dst, TileDoc const&src) no
|
||||
ox::Result<WorldStatic> loadWorldStatic(ObjectCache const&objCache, WorldDoc const&doc) noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
auto &tile(ox::CommonRefWith<WorldStatic> auto &ws, size_t lyr, ox::Integer_c auto col, ox::Integer_c auto row) noexcept {
|
||||
auto &tile(
|
||||
ox::CommonRefWith<WorldStatic> auto&ws,
|
||||
size_t lyr,
|
||||
ox::Integer_c auto col,
|
||||
ox::Integer_c auto row) noexcept {
|
||||
auto const idx = static_cast<size_t>(row) * static_cast<size_t>(ws.columns) + static_cast<size_t>(col);
|
||||
return ws.map[lyr].tiles[idx];
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
auto &cbb(ox::CommonRefWith<WorldStatic> auto &ws, size_t lyr) noexcept {
|
||||
auto &cbb(ox::CommonRefWith<WorldStatic> auto&ws, size_t lyr) noexcept {
|
||||
return ws.map[lyr].cbb;
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
namespace jasper::world {
|
||||
|
||||
class StudioModule: public studio::Module {
|
||||
static class: public studio::Module {
|
||||
public:
|
||||
ox::Vector<studio::EditorMaker> editors(studio::StudioContext &ctx) const noexcept override {
|
||||
return {
|
||||
@ -21,13 +21,14 @@ class StudioModule: public studio::Module {
|
||||
}
|
||||
ox::Vector<ox::UPtr<studio::ItemMaker>> itemMakers(studio::StudioContext&) const noexcept override {
|
||||
ox::Vector<ox::UPtr<studio::ItemMaker>> out;
|
||||
out.emplace_back(ox::make<studio::ItemMakerT<WorldObjectSet>>("World Object Set", "WorldObjectSets", FileExt_jwob, ox::ClawFormat::Organic));
|
||||
out.emplace_back(ox::make<studio::ItemMakerT<WorldDoc>>("World", "Worlds", FileExt_jwld, ox::ClawFormat::Organic));
|
||||
out.emplace_back(ox::make<studio::ItemMakerT<WorldObjectSet>>(
|
||||
"World Object Set", "WorldObjectSets", FileExt_jwob, ox::ClawFormat::Organic));
|
||||
out.emplace_back(ox::make<studio::ItemMakerT<WorldDoc>>(
|
||||
"World", "Worlds", FileExt_jwld, ox::ClawFormat::Organic));
|
||||
return out;
|
||||
}
|
||||
};
|
||||
} mod;
|
||||
|
||||
static StudioModule const mod;
|
||||
studio::Module const*studioModule() noexcept {
|
||||
return &mod;
|
||||
}
|
||||
|
@ -7,14 +7,14 @@
|
||||
|
||||
namespace jasper::world {
|
||||
|
||||
AddObjectSet::AddObjectSet(WorldDoc &doc, ox::StringView objSetPath):
|
||||
AddObjectSet::AddObjectSet(WorldDoc &doc, ox::UUID const&objSetUuid):
|
||||
m_doc(doc),
|
||||
m_path(ox::String(objSetPath)) {
|
||||
m_path(ox::sfmt("uuid://{}", objSetUuid.toString())) {
|
||||
for (auto const&o : m_doc.objSets) {
|
||||
if (o.path > objSetPath) {
|
||||
if (o.path > m_path) {
|
||||
break;
|
||||
} else if (o.path == objSetPath) {
|
||||
throw ox::Exception(OxError(1, "Path already exists in doc"));
|
||||
} else if (o.path == m_path) {
|
||||
throw OxException(1, "Path already exists in doc");
|
||||
}
|
||||
++m_insertIdx;
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ class AddObjectSet: public studio::UndoCommand {
|
||||
size_t m_insertIdx{};
|
||||
ox::String m_path;
|
||||
public:
|
||||
AddObjectSet(WorldDoc &doc, ox::StringView objSetPath);
|
||||
AddObjectSet(WorldDoc &doc, ox::UUID const&objSetUuid);
|
||||
void redo() noexcept override;
|
||||
void undo() noexcept override;
|
||||
[[nodiscard]]
|
||||
|
@ -7,7 +7,8 @@
|
||||
|
||||
namespace jasper::world {
|
||||
|
||||
ModifyTilesCommand::ModifyTilesCommand(WorldDoc &doc,
|
||||
ModifyTilesCommand::ModifyTilesCommand(
|
||||
WorldDoc &doc,
|
||||
WorldStatic &worldStatic,
|
||||
ObjectCache &objCache,
|
||||
ox::Vector<Mod> mods):
|
||||
@ -15,6 +16,17 @@ ModifyTilesCommand::ModifyTilesCommand(WorldDoc &doc,
|
||||
m_worldStatic(worldStatic),
|
||||
m_objCache(objCache),
|
||||
m_mods(std::move(mods)) {
|
||||
bool noChanges = true;
|
||||
for (auto const&mod : m_mods) {
|
||||
auto const&docTile = tile(m_doc, mod.layer, mod.tileAddr.x, mod.tileAddr.y);
|
||||
if (docTile.obj.worldObjectId != mod.objId || docTile.obj.worldObjectSetId != mod.setId) {
|
||||
noChanges = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (noChanges) {
|
||||
throw studio::NoChangesException();
|
||||
}
|
||||
}
|
||||
|
||||
void ModifyTilesCommand::redo() noexcept {
|
||||
|
@ -47,6 +47,14 @@ static WorldDoc makeValid(WorldDoc doc) noexcept {
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
static ox::Vec2 dropPos(ox::Vec2 dropPos) noexcept {
|
||||
auto const winPos = ImGui::GetWindowPos();
|
||||
dropPos.x -= winPos.x;
|
||||
dropPos.y -= winPos.y;
|
||||
return dropPos;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr ox::Point fbPtToTileAddr(
|
||||
ox::Vec2 const&fbPt,
|
||||
ox::Vec2 const&mapSz) noexcept {
|
||||
@ -98,7 +106,7 @@ void WorldEditorImGui::onActivated() noexcept {
|
||||
}
|
||||
|
||||
ox::Error WorldEditorImGui::saveItem() noexcept {
|
||||
return m_sctx.project->writeObj(itemPath(), m_doc, ox::ClawFormat::Organic);
|
||||
return m_sctx.project->writeObj(itemPath(), m_doc, ox::ClawFormat::Metal);
|
||||
}
|
||||
|
||||
void WorldEditorImGui::drawObjSetSelector() noexcept {
|
||||
@ -111,14 +119,23 @@ void WorldEditorImGui::drawObjSetSelector() noexcept {
|
||||
rmObjSet();
|
||||
}
|
||||
ig::ListBox("Object Sets", [this](size_t i) -> ox::CStringView {
|
||||
return m_doc.objSets[i].path;
|
||||
auto const&uuidUrl = m_doc.objSets[i].path;
|
||||
auto [setName, err] = uuidUrlToPath(keelCtx(m_sctx.tctx), uuidUrl);
|
||||
if (err) {
|
||||
setName = uuidUrl;
|
||||
}
|
||||
return setName;
|
||||
}, m_doc.objSets.size(), m_palMgr.selectedIdx);
|
||||
}
|
||||
|
||||
void WorldEditorImGui::drawObjSelector() noexcept {
|
||||
ig::IDStackItem const idStackItem("ObjSelector");
|
||||
for (auto const&[setName, setId, set] : m_objSets) {
|
||||
for (auto const&[uuidUrl, setId, set] : m_objSets) {
|
||||
constexpr auto flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick;
|
||||
auto [setName, err] = uuidUrlToPath(keelCtx(m_sctx.tctx), uuidUrl);
|
||||
if (err) {
|
||||
setName = uuidUrl;
|
||||
}
|
||||
if (ImGui::TreeNodeEx(setName.c_str(), flags)) {
|
||||
for (auto const&obj : set->objects) {
|
||||
if (ImGui::TreeNodeEx(obj.name.c_str(), ImGuiTreeNodeFlags_Leaf)) {
|
||||
@ -155,14 +172,6 @@ void WorldEditorImGui::drawResources() noexcept {
|
||||
drawObjSelector();
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
static ox::Vec2 dropPos(ox::Vec2 dropPos) noexcept {
|
||||
auto const winPos = ImGui::GetWindowPos();
|
||||
dropPos.x -= winPos.x;
|
||||
dropPos.y -= winPos.y;
|
||||
return dropPos;
|
||||
}
|
||||
|
||||
void WorldEditorImGui::drawWorldView() noexcept {
|
||||
ig::IDStackItem const idStackItem("WorldView");
|
||||
auto const paneSize = ImGui::GetContentRegionAvail();
|
||||
@ -221,7 +230,8 @@ void WorldEditorImGui::drawWorldView() noexcept {
|
||||
}
|
||||
|
||||
ox::Error WorldEditorImGui::addObjSet(ox::StringView path) noexcept {
|
||||
pushCommand<AddObjectSet>(m_doc, path);
|
||||
oxRequire(uuid, keel::pathToUuid(keelCtx(m_sctx.tctx), path));
|
||||
pushCommand<AddObjectSet>(m_doc, uuid);
|
||||
return {};
|
||||
}
|
||||
|
||||
@ -247,7 +257,7 @@ ox::Error WorldEditorImGui::loadObjectSets() noexcept {
|
||||
return {};
|
||||
}
|
||||
|
||||
ox::Error WorldEditorImGui::undoStackChanged(const studio::UndoCommand *) {
|
||||
ox::Error WorldEditorImGui::undoStackChanged(studio::UndoCommand const*) {
|
||||
oxReturnError(m_view.setupWorld());
|
||||
return {};
|
||||
}
|
||||
|
@ -19,6 +19,10 @@ namespace jasper::world {
|
||||
class WorldEditorImGui: public studio::Editor {
|
||||
|
||||
private:
|
||||
struct Selection {
|
||||
ox::Point begin, end;
|
||||
};
|
||||
ox::Optional<Selection> m_selection;
|
||||
uint8_t m_activeLayer{};
|
||||
studio::StudioContext &m_sctx;
|
||||
studio::ig::FilePicker m_objSetPicker{
|
||||
|
@ -8,8 +8,6 @@
|
||||
|
||||
namespace jasper::world {
|
||||
|
||||
namespace ncore = nostalgia::core;
|
||||
|
||||
World::World(WorldStatic const&worldStatic) noexcept:
|
||||
m_worldStatic(worldStatic) {
|
||||
}
|
||||
@ -37,9 +35,11 @@ void World::setupLayer(
|
||||
uint_t cbb) const noexcept {
|
||||
ncore::setBgStatus(ctx, lyr, true);
|
||||
ncore::setBgCbb(ctx, lyr, cbb);
|
||||
for (auto y = 0; y < m_worldStatic.rows; ++y) {
|
||||
for (auto x = 0; x < m_worldStatic.columns; ++x) {
|
||||
auto &t = tile(m_worldStatic, lyr, static_cast<size_t>(x), static_cast<size_t>(y));
|
||||
auto const rows = ox::min<int>(m_worldStatic.rows, ncore::tileRows(ctx) / 2);
|
||||
auto const columns = ox::min<int>(m_worldStatic.columns, ncore::tileColumns(ctx) / 2);
|
||||
for (auto y = 0; y < rows; ++y) {
|
||||
for (auto x = 0; x < columns; ++x) {
|
||||
auto &t = tile(m_worldStatic, lyr, x, y);
|
||||
auto const tx = x * 2;
|
||||
auto const ty = y * 2;
|
||||
ncore::setBgTile(ctx, lyr, tx + 0, ty + 0, {
|
||||
|
Loading…
x
Reference in New Issue
Block a user