[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;
|
ox::Result<WorldStatic> loadWorldStatic(ObjectCache const&objCache, WorldDoc const&doc) noexcept;
|
||||||
|
|
||||||
[[nodiscard]]
|
[[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);
|
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];
|
return ws.map[lyr].tiles[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[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;
|
return ws.map[lyr].cbb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
namespace jasper::world {
|
namespace jasper::world {
|
||||||
|
|
||||||
class StudioModule: public studio::Module {
|
static class: public studio::Module {
|
||||||
public:
|
public:
|
||||||
ox::Vector<studio::EditorMaker> editors(studio::StudioContext &ctx) const noexcept override {
|
ox::Vector<studio::EditorMaker> editors(studio::StudioContext &ctx) const noexcept override {
|
||||||
return {
|
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>> itemMakers(studio::StudioContext&) const noexcept override {
|
||||||
ox::Vector<ox::UPtr<studio::ItemMaker>> out;
|
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<WorldObjectSet>>(
|
||||||
out.emplace_back(ox::make<studio::ItemMakerT<WorldDoc>>("World", "Worlds", FileExt_jwld, ox::ClawFormat::Organic));
|
"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;
|
return out;
|
||||||
}
|
}
|
||||||
};
|
} mod;
|
||||||
|
|
||||||
static StudioModule const mod;
|
|
||||||
studio::Module const*studioModule() noexcept {
|
studio::Module const*studioModule() noexcept {
|
||||||
return &mod;
|
return &mod;
|
||||||
}
|
}
|
||||||
|
@ -7,14 +7,14 @@
|
|||||||
|
|
||||||
namespace jasper::world {
|
namespace jasper::world {
|
||||||
|
|
||||||
AddObjectSet::AddObjectSet(WorldDoc &doc, ox::StringView objSetPath):
|
AddObjectSet::AddObjectSet(WorldDoc &doc, ox::UUID const&objSetUuid):
|
||||||
m_doc(doc),
|
m_doc(doc),
|
||||||
m_path(ox::String(objSetPath)) {
|
m_path(ox::sfmt("uuid://{}", objSetUuid.toString())) {
|
||||||
for (auto const&o : m_doc.objSets) {
|
for (auto const&o : m_doc.objSets) {
|
||||||
if (o.path > objSetPath) {
|
if (o.path > m_path) {
|
||||||
break;
|
break;
|
||||||
} else if (o.path == objSetPath) {
|
} else if (o.path == m_path) {
|
||||||
throw ox::Exception(OxError(1, "Path already exists in doc"));
|
throw OxException(1, "Path already exists in doc");
|
||||||
}
|
}
|
||||||
++m_insertIdx;
|
++m_insertIdx;
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ class AddObjectSet: public studio::UndoCommand {
|
|||||||
size_t m_insertIdx{};
|
size_t m_insertIdx{};
|
||||||
ox::String m_path;
|
ox::String m_path;
|
||||||
public:
|
public:
|
||||||
AddObjectSet(WorldDoc &doc, ox::StringView objSetPath);
|
AddObjectSet(WorldDoc &doc, ox::UUID const&objSetUuid);
|
||||||
void redo() noexcept override;
|
void redo() noexcept override;
|
||||||
void undo() noexcept override;
|
void undo() noexcept override;
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
|
@ -7,7 +7,8 @@
|
|||||||
|
|
||||||
namespace jasper::world {
|
namespace jasper::world {
|
||||||
|
|
||||||
ModifyTilesCommand::ModifyTilesCommand(WorldDoc &doc,
|
ModifyTilesCommand::ModifyTilesCommand(
|
||||||
|
WorldDoc &doc,
|
||||||
WorldStatic &worldStatic,
|
WorldStatic &worldStatic,
|
||||||
ObjectCache &objCache,
|
ObjectCache &objCache,
|
||||||
ox::Vector<Mod> mods):
|
ox::Vector<Mod> mods):
|
||||||
@ -15,6 +16,17 @@ ModifyTilesCommand::ModifyTilesCommand(WorldDoc &doc,
|
|||||||
m_worldStatic(worldStatic),
|
m_worldStatic(worldStatic),
|
||||||
m_objCache(objCache),
|
m_objCache(objCache),
|
||||||
m_mods(std::move(mods)) {
|
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 {
|
void ModifyTilesCommand::redo() noexcept {
|
||||||
|
@ -47,6 +47,14 @@ static WorldDoc makeValid(WorldDoc doc) noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[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(
|
constexpr ox::Point fbPtToTileAddr(
|
||||||
ox::Vec2 const&fbPt,
|
ox::Vec2 const&fbPt,
|
||||||
ox::Vec2 const&mapSz) noexcept {
|
ox::Vec2 const&mapSz) noexcept {
|
||||||
@ -98,7 +106,7 @@ void WorldEditorImGui::onActivated() noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ox::Error WorldEditorImGui::saveItem() 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 {
|
void WorldEditorImGui::drawObjSetSelector() noexcept {
|
||||||
@ -111,14 +119,23 @@ void WorldEditorImGui::drawObjSetSelector() noexcept {
|
|||||||
rmObjSet();
|
rmObjSet();
|
||||||
}
|
}
|
||||||
ig::ListBox("Object Sets", [this](size_t i) -> ox::CStringView {
|
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);
|
}, m_doc.objSets.size(), m_palMgr.selectedIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldEditorImGui::drawObjSelector() noexcept {
|
void WorldEditorImGui::drawObjSelector() noexcept {
|
||||||
ig::IDStackItem const idStackItem("ObjSelector");
|
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;
|
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)) {
|
if (ImGui::TreeNodeEx(setName.c_str(), flags)) {
|
||||||
for (auto const&obj : set->objects) {
|
for (auto const&obj : set->objects) {
|
||||||
if (ImGui::TreeNodeEx(obj.name.c_str(), ImGuiTreeNodeFlags_Leaf)) {
|
if (ImGui::TreeNodeEx(obj.name.c_str(), ImGuiTreeNodeFlags_Leaf)) {
|
||||||
@ -155,14 +172,6 @@ void WorldEditorImGui::drawResources() noexcept {
|
|||||||
drawObjSelector();
|
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 {
|
void WorldEditorImGui::drawWorldView() noexcept {
|
||||||
ig::IDStackItem const idStackItem("WorldView");
|
ig::IDStackItem const idStackItem("WorldView");
|
||||||
auto const paneSize = ImGui::GetContentRegionAvail();
|
auto const paneSize = ImGui::GetContentRegionAvail();
|
||||||
@ -221,7 +230,8 @@ void WorldEditorImGui::drawWorldView() noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ox::Error WorldEditorImGui::addObjSet(ox::StringView path) 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 {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,7 +257,7 @@ ox::Error WorldEditorImGui::loadObjectSets() noexcept {
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
ox::Error WorldEditorImGui::undoStackChanged(const studio::UndoCommand *) {
|
ox::Error WorldEditorImGui::undoStackChanged(studio::UndoCommand const*) {
|
||||||
oxReturnError(m_view.setupWorld());
|
oxReturnError(m_view.setupWorld());
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,10 @@ namespace jasper::world {
|
|||||||
class WorldEditorImGui: public studio::Editor {
|
class WorldEditorImGui: public studio::Editor {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct Selection {
|
||||||
|
ox::Point begin, end;
|
||||||
|
};
|
||||||
|
ox::Optional<Selection> m_selection;
|
||||||
uint8_t m_activeLayer{};
|
uint8_t m_activeLayer{};
|
||||||
studio::StudioContext &m_sctx;
|
studio::StudioContext &m_sctx;
|
||||||
studio::ig::FilePicker m_objSetPicker{
|
studio::ig::FilePicker m_objSetPicker{
|
||||||
|
@ -8,8 +8,6 @@
|
|||||||
|
|
||||||
namespace jasper::world {
|
namespace jasper::world {
|
||||||
|
|
||||||
namespace ncore = nostalgia::core;
|
|
||||||
|
|
||||||
World::World(WorldStatic const&worldStatic) noexcept:
|
World::World(WorldStatic const&worldStatic) noexcept:
|
||||||
m_worldStatic(worldStatic) {
|
m_worldStatic(worldStatic) {
|
||||||
}
|
}
|
||||||
@ -37,9 +35,11 @@ void World::setupLayer(
|
|||||||
uint_t cbb) const noexcept {
|
uint_t cbb) const noexcept {
|
||||||
ncore::setBgStatus(ctx, lyr, true);
|
ncore::setBgStatus(ctx, lyr, true);
|
||||||
ncore::setBgCbb(ctx, lyr, cbb);
|
ncore::setBgCbb(ctx, lyr, cbb);
|
||||||
for (auto y = 0; y < m_worldStatic.rows; ++y) {
|
auto const rows = ox::min<int>(m_worldStatic.rows, ncore::tileRows(ctx) / 2);
|
||||||
for (auto x = 0; x < m_worldStatic.columns; ++x) {
|
auto const columns = ox::min<int>(m_worldStatic.columns, ncore::tileColumns(ctx) / 2);
|
||||||
auto &t = tile(m_worldStatic, lyr, static_cast<size_t>(x), static_cast<size_t>(y));
|
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 tx = x * 2;
|
||||||
auto const ty = y * 2;
|
auto const ty = y * 2;
|
||||||
ncore::setBgTile(ctx, lyr, tx + 0, ty + 0, {
|
ncore::setBgTile(ctx, lyr, tx + 0, ty + 0, {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user