[jasper/world/studio] Add tile placement in world editing
All checks were successful
Build / build (push) Successful in 3m11s
All checks were successful
Build / build (push) Successful in 3m11s
This commit is contained in:
parent
3d2b3da7f5
commit
abba35d64e
@ -87,6 +87,24 @@ struct WorldDoc {
|
|||||||
TileMap tiles;
|
TileMap tiles;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
constexpr ox::Result<ox::String> objectSetPath(WorldDoc const&wd, uint64_t setId) noexcept {
|
||||||
|
auto obj = ox::find_if(wd.objSets.begin(), wd.objSets.end(), [setId](ObjectSetEntry const&e) {
|
||||||
|
return e.id == setId;
|
||||||
|
});
|
||||||
|
oxReturnError(OxError(obj == wd.objSets.end(), "Obj set not found"));
|
||||||
|
return obj->path;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
constexpr ox::Result<uint64_t> objectSetId(WorldDoc const&wd, ox::StringView setPath) noexcept {
|
||||||
|
auto obj = ox::find_if(wd.objSets.begin(), wd.objSets.end(), [setPath](ObjectSetEntry const&e) {
|
||||||
|
return e.path == setPath;
|
||||||
|
});
|
||||||
|
oxReturnError(OxError(obj == wd.objSets.end(), "Obj set not found"));
|
||||||
|
return obj->id;
|
||||||
|
}
|
||||||
|
|
||||||
oxModelBegin(WorldDoc)
|
oxModelBegin(WorldDoc)
|
||||||
oxModelFieldRename(objSets, object_sets)
|
oxModelFieldRename(objSets, object_sets)
|
||||||
oxModelFieldRename(objSetIdIdx, object_set_id_idx)
|
oxModelFieldRename(objSetIdIdx, object_set_id_idx)
|
||||||
@ -99,8 +117,8 @@ oxModelEnd()
|
|||||||
ObjectSetEntry const*objSetEntry(WorldDoc const&doc, size_t id) noexcept;
|
ObjectSetEntry const*objSetEntry(WorldDoc const&doc, size_t id) noexcept;
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
auto &tile(ox::CommonRefWith<WorldDoc> auto &doc, size_t lyr, size_t col, size_t row) noexcept {
|
auto &tile(ox::CommonRefWith<WorldDoc> auto &doc, size_t lyr, ox::Integer_c auto col, ox::Integer_c auto row) noexcept {
|
||||||
return doc.tiles[lyr][row][col];
|
return doc.tiles[lyr][static_cast<size_t>(row)][static_cast<size_t>(col)];
|
||||||
}
|
}
|
||||||
|
|
||||||
void resize(WorldDoc &doc, ox::Size const&sz) noexcept;
|
void resize(WorldDoc &doc, ox::Size const&sz) noexcept;
|
||||||
|
@ -77,6 +77,7 @@ struct WorldObjectSet {
|
|||||||
static constexpr auto TypeName = "net.drinkingtea.jasper.world.WorldObjectSet";
|
static constexpr auto TypeName = "net.drinkingtea.jasper.world.WorldObjectSet";
|
||||||
static constexpr auto TypeVersion = 1;
|
static constexpr auto TypeVersion = 1;
|
||||||
static constexpr auto Preloadable = true;
|
static constexpr auto Preloadable = true;
|
||||||
|
// index used to assign unique IDs to objects in the set
|
||||||
ObjectId objIdIdx = 0;
|
ObjectId objIdIdx = 0;
|
||||||
ox::FileAddress tilesheet;
|
ox::FileAddress tilesheet;
|
||||||
ox::Vector<PaletteCycle> palettes;
|
ox::Vector<PaletteCycle> palettes;
|
||||||
|
@ -105,11 +105,13 @@ oxModelBegin(WorldStatic)
|
|||||||
oxModelField(map)
|
oxModelField(map)
|
||||||
oxModelEnd()
|
oxModelEnd()
|
||||||
|
|
||||||
|
void loadTile(ObjectCache const&objCache, TileStatic &dst, TileDoc const&src) noexcept;
|
||||||
|
|
||||||
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, size_t col, size_t 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 = row * static_cast<size_t>(ws.columns) + 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];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
target_sources(
|
target_sources(
|
||||||
JasperWorld-Studio PRIVATE
|
JasperWorld-Studio PRIVATE
|
||||||
commands/addrmobjectset.cpp
|
commands/addrmobjectset.cpp
|
||||||
|
commands/modifytiles.cpp
|
||||||
commands/editsize.cpp
|
commands/editsize.cpp
|
||||||
objectexplorer.cpp
|
objectexplorer.cpp
|
||||||
worldeditor-imgui.cpp
|
worldeditor-imgui.cpp
|
||||||
|
@ -11,6 +11,7 @@ enum class WorldEditorCommand {
|
|||||||
AddObjectSet,
|
AddObjectSet,
|
||||||
RmObjectSet,
|
RmObjectSet,
|
||||||
EditWorldSize,
|
EditWorldSize,
|
||||||
|
ModifyTiles,
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2023 - 2024 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "commands.hpp"
|
||||||
|
#include "modifytiles.hpp"
|
||||||
|
|
||||||
|
namespace jasper::world {
|
||||||
|
|
||||||
|
ModifyTilesCommand::ModifyTilesCommand(WorldDoc &doc,
|
||||||
|
WorldStatic &worldStatic,
|
||||||
|
ObjectCache &objCache,
|
||||||
|
ox::Vector<Mod> mods):
|
||||||
|
m_doc(doc),
|
||||||
|
m_worldStatic(worldStatic),
|
||||||
|
m_objCache(objCache),
|
||||||
|
m_mods(std::move(mods)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModifyTilesCommand::redo() noexcept {
|
||||||
|
swap();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModifyTilesCommand::undo() noexcept {
|
||||||
|
swap();
|
||||||
|
}
|
||||||
|
|
||||||
|
int ModifyTilesCommand::commandId() const noexcept {
|
||||||
|
return static_cast<int>(WorldEditorCommand::ModifyTiles);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModifyTilesCommand::swap() noexcept {
|
||||||
|
for (auto &mod : m_mods) {
|
||||||
|
auto &docTile = tile(m_doc, mod.layer, mod.tileAddr.x, mod.tileAddr.y);
|
||||||
|
auto &activeTile = tile(m_worldStatic, mod.layer, mod.tileAddr.x, mod.tileAddr.y);
|
||||||
|
std::swap(docTile.obj.worldObjectId, mod.objId);
|
||||||
|
std::swap(docTile.obj.worldObjectSetId, mod.setId);
|
||||||
|
loadTile(m_objCache, activeTile, docTile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2023 - 2024 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <studio/undostack.hpp>
|
||||||
|
|
||||||
|
#include <jasper/world/world.hpp>
|
||||||
|
|
||||||
|
namespace jasper::world {
|
||||||
|
|
||||||
|
class ModifyTilesCommand: public studio::UndoCommand {
|
||||||
|
public:
|
||||||
|
struct Mod {
|
||||||
|
uint8_t layer{};
|
||||||
|
ox::Point tileAddr;
|
||||||
|
ObjectId objId{};
|
||||||
|
uint64_t setId{};
|
||||||
|
};
|
||||||
|
private:
|
||||||
|
WorldDoc &m_doc;
|
||||||
|
WorldStatic &m_worldStatic;
|
||||||
|
ObjectCache &m_objCache;
|
||||||
|
ox::Vector<Mod> m_mods;
|
||||||
|
public:
|
||||||
|
ModifyTilesCommand(
|
||||||
|
WorldDoc &doc,
|
||||||
|
WorldStatic &worldStatic,
|
||||||
|
ObjectCache &objCache,
|
||||||
|
ox::Vector<Mod> mods);
|
||||||
|
void redo() noexcept override;
|
||||||
|
void undo() noexcept override;
|
||||||
|
[[nodiscard]]
|
||||||
|
int commandId() const noexcept override;
|
||||||
|
private:
|
||||||
|
void swap() noexcept;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include "commands/addrmobjectset.hpp"
|
#include "commands/addrmobjectset.hpp"
|
||||||
#include "commands/editsize.hpp"
|
#include "commands/editsize.hpp"
|
||||||
|
#include "commands/modifytiles.hpp"
|
||||||
|
|
||||||
#include "worldeditor-imgui.hpp"
|
#include "worldeditor-imgui.hpp"
|
||||||
|
|
||||||
@ -25,13 +26,13 @@ constexpr auto SqrBtnSize = ImVec2(ig::BtnSz.y, ig::BtnSz.y);
|
|||||||
struct WorldTileDragDrop {
|
struct WorldTileDragDrop {
|
||||||
static constexpr auto TypeName = "net.drinkingtea.jasper.world.studio.WorldTileDragDrop";
|
static constexpr auto TypeName = "net.drinkingtea.jasper.world.studio.WorldTileDragDrop";
|
||||||
static constexpr auto TypeVersion = 1;
|
static constexpr auto TypeVersion = 1;
|
||||||
ox::String setPath;
|
uint64_t setId{};
|
||||||
ox::String objName;
|
ObjectId objId{};
|
||||||
};
|
};
|
||||||
|
|
||||||
oxModelBegin(WorldTileDragDrop)
|
oxModelBegin(WorldTileDragDrop)
|
||||||
oxModelField(setPath)
|
oxModelField(setId)
|
||||||
oxModelField(objName)
|
oxModelField(objId)
|
||||||
oxModelEnd()
|
oxModelEnd()
|
||||||
|
|
||||||
|
|
||||||
@ -45,6 +46,38 @@ static WorldDoc makeValid(WorldDoc doc) noexcept {
|
|||||||
return doc;
|
return doc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
constexpr ox::Point fbPtToTileAddr(
|
||||||
|
ox::Vec2 const&fbPt,
|
||||||
|
ox::Size const&fbSz,
|
||||||
|
ox::Size const&mapSz) noexcept {
|
||||||
|
// fbw - framebuffer width
|
||||||
|
// fbh - framebuffer height
|
||||||
|
// fbx - framebuffer pt x
|
||||||
|
// fby - framebuffer pt y
|
||||||
|
// sw - scaled width
|
||||||
|
// sh - scaled height
|
||||||
|
// mw - map width
|
||||||
|
// mw - map height
|
||||||
|
// mx - map loc x
|
||||||
|
// my - map loc y
|
||||||
|
// sw = fbw / mw
|
||||||
|
// sh = fbh / mh
|
||||||
|
// tile addr x = sw * fbx
|
||||||
|
// tile addr y = sh * fby
|
||||||
|
auto const fbw = static_cast<float>(fbSz.width);
|
||||||
|
auto const fbh = static_cast<float>(fbSz.height);
|
||||||
|
auto const mw = static_cast<float>(mapSz.width);
|
||||||
|
auto const mh = static_cast<float>(mapSz.height);
|
||||||
|
auto const sw = fbw / mw;
|
||||||
|
auto const sh = fbh / mh;
|
||||||
|
auto const fbx = fbPt.x / fbw;
|
||||||
|
auto const fby = fbPt.y / fbh;
|
||||||
|
return {
|
||||||
|
static_cast<int>(sw * fbx),
|
||||||
|
static_cast<int>(sh * fby),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
WorldEditorImGui::WorldEditorImGui(studio::StudioContext &sctx, ox::StringView path):
|
WorldEditorImGui::WorldEditorImGui(studio::StudioContext &sctx, ox::StringView path):
|
||||||
Editor(path),
|
Editor(path),
|
||||||
@ -57,6 +90,7 @@ WorldEditorImGui::WorldEditorImGui(studio::StudioContext &sctx, ox::StringView p
|
|||||||
setRequiresConstantRefresh(false);
|
setRequiresConstantRefresh(false);
|
||||||
m_objSetPicker.filePicked.connect(this, &WorldEditorImGui::addObjSet);
|
m_objSetPicker.filePicked.connect(this, &WorldEditorImGui::addObjSet);
|
||||||
m_sctx.project->fileUpdated.connect(this, &WorldEditorImGui::handleObjectSetUpdate);
|
m_sctx.project->fileUpdated.connect(this, &WorldEditorImGui::handleObjectSetUpdate);
|
||||||
|
studio::Editor::undoStack()->changeTriggered.connect(this, &WorldEditorImGui::undoStackChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldEditorImGui::draw(studio::StudioContext&) noexcept {
|
void WorldEditorImGui::draw(studio::StudioContext&) noexcept {
|
||||||
@ -100,17 +134,18 @@ void WorldEditorImGui::drawObjSetSelector() noexcept {
|
|||||||
|
|
||||||
void WorldEditorImGui::drawObjSelector() noexcept {
|
void WorldEditorImGui::drawObjSelector() noexcept {
|
||||||
ig::IDStackItem const idStackItem("ObjSelector");
|
ig::IDStackItem const idStackItem("ObjSelector");
|
||||||
for (auto const&set : m_objSets) {
|
for (auto const&[setName, setId, set] : m_objSets) {
|
||||||
constexpr auto flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick;
|
constexpr auto flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick;
|
||||||
if (ImGui::TreeNodeEx(set.name.c_str(), flags)) {
|
if (ImGui::TreeNodeEx(setName.c_str(), flags)) {
|
||||||
for (auto const&obj : set.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)) {
|
||||||
ImGui::TreePop();
|
ImGui::TreePop();
|
||||||
}
|
}
|
||||||
ig::dragDropSource([set, obj] {
|
ig::dragDropSource([&] {
|
||||||
std::ignore = ig::setDragDropPayload("WorldTile", WorldTileDragDrop{
|
std::ignore = ig::setDragDropPayload("WorldTile", WorldTileDragDrop{
|
||||||
.setPath = ox::String(set.name),
|
.setId = setId,
|
||||||
.objName = ox::String(obj.name)});
|
.objId = obj.id,
|
||||||
|
});
|
||||||
ImGui::Text("%s", obj.name.c_str());
|
ImGui::Text("%s", obj.name.c_str());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -170,13 +205,26 @@ void WorldEditorImGui::drawWorldView() noexcept {
|
|||||||
paneSize,
|
paneSize,
|
||||||
ImVec2(0, 1),
|
ImVec2(0, 1),
|
||||||
ImVec2(xScale, 1 - yScale));
|
ImVec2(xScale, 1 - yScale));
|
||||||
std::ignore = ig::dragDropTarget([] {
|
std::ignore = ig::dragDropTarget([&, this] {
|
||||||
oxRequire(obj, ig::getDragDropPayload<WorldTileDragDrop>("WorldTile"));
|
oxRequire(objId, ig::getDragDropPayload<WorldTileDragDrop>("WorldTile"));
|
||||||
oxDebugf("{}: {}", obj.setPath, obj.objName);
|
|
||||||
auto const&io = ImGui::GetIO();
|
auto const&io = ImGui::GetIO();
|
||||||
auto const mousePos = ox::Vec2(io.MousePos);
|
auto const dropPos = world::dropPos(ox::Vec2(io.MousePos));
|
||||||
auto const dropPos = world::dropPos(mousePos);
|
auto const mw = m_doc.columns * ncore::TileWidth * 2;
|
||||||
std::cout << dropPos.x << ", " << dropPos.y << '\n';
|
auto const mh = m_doc.rows * ncore::TileHeight * 2;
|
||||||
|
auto const tileAddr = fbPtToTileAddr(dropPos, fb.size(), {mw, mh});
|
||||||
|
pushCommand<ModifyTilesCommand>(
|
||||||
|
m_doc,
|
||||||
|
m_worldStatic,
|
||||||
|
m_objCache,
|
||||||
|
ox::Vector<ModifyTilesCommand::Mod>{
|
||||||
|
{
|
||||||
|
.layer = m_activeLayer,
|
||||||
|
.tileAddr = tileAddr,
|
||||||
|
.objId = objId.objId,
|
||||||
|
.setId = objId.setId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
oxReturnError(loadWorldStatic(m_objCache, m_doc).moveTo(m_worldStatic));
|
||||||
return ox::Error{};
|
return ox::Error{};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -203,9 +251,14 @@ ox::Error WorldEditorImGui::loadObjectSets() noexcept {
|
|||||||
m_objSets.clear();
|
m_objSets.clear();
|
||||||
for (auto const&set : m_doc.objSets) {
|
for (auto const&set : m_doc.objSets) {
|
||||||
oxRequireM(os, readObj<WorldObjectSet>(keelCtx(m_sctx.tctx), set.path));
|
oxRequireM(os, readObj<WorldObjectSet>(keelCtx(m_sctx.tctx), set.path));
|
||||||
m_objSets.emplace_back(ObjSetRef{ox::String(set.path), std::move(os)});
|
m_objSets.emplace_back(ox::String(set.path), set.id, std::move(os));
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ox::Error WorldEditorImGui::undoStackChanged(const studio::UndoCommand *) {
|
||||||
|
oxReturnError(m_view.setupWorld());
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <ox/std/smallmap.hpp>
|
||||||
|
|
||||||
#include <studio/studio.hpp>
|
#include <studio/studio.hpp>
|
||||||
|
|
||||||
#include <turbine/context.hpp>
|
#include <turbine/context.hpp>
|
||||||
@ -17,6 +19,7 @@ namespace jasper::world {
|
|||||||
class WorldEditorImGui: public studio::Editor {
|
class WorldEditorImGui: public studio::Editor {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
uint8_t m_activeLayer{};
|
||||||
studio::StudioContext &m_sctx;
|
studio::StudioContext &m_sctx;
|
||||||
studio::ig::FilePicker m_objSetPicker{
|
studio::ig::FilePicker m_objSetPicker{
|
||||||
m_sctx, ox::String("Choose Object Set"), ox::String(FileExt_jwob)};
|
m_sctx, ox::String("Choose Object Set"), ox::String(FileExt_jwob)};
|
||||||
@ -24,6 +27,7 @@ class WorldEditorImGui: public studio::Editor {
|
|||||||
ObjectCache m_objCache;
|
ObjectCache m_objCache;
|
||||||
struct ObjSetRef {
|
struct ObjSetRef {
|
||||||
ox::String name;
|
ox::String name;
|
||||||
|
uint64_t id{};
|
||||||
keel::AssetRef<WorldObjectSet> set;
|
keel::AssetRef<WorldObjectSet> set;
|
||||||
};
|
};
|
||||||
ox::Vector<ObjSetRef> m_objSets;
|
ox::Vector<ObjSetRef> m_objSets;
|
||||||
@ -63,6 +67,7 @@ class WorldEditorImGui: public studio::Editor {
|
|||||||
|
|
||||||
ox::Error loadObjectSets() noexcept;
|
ox::Error loadObjectSets() noexcept;
|
||||||
|
|
||||||
|
ox::Error undoStackChanged(studio::UndoCommand const*);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ void WorldEditorView::draw(ox::Size const&targetSz) noexcept {
|
|||||||
auto const scaleSz = targetSz / ncore::gl::drawSize(1);
|
auto const scaleSz = targetSz / ncore::gl::drawSize(1);
|
||||||
if (m_scaleSz != scaleSz) [[unlikely]] {
|
if (m_scaleSz != scaleSz) [[unlikely]] {
|
||||||
m_scale = ox::max(1, ox::max(scaleSz.width, scaleSz.height));
|
m_scale = ox::max(1, ox::max(scaleSz.width, scaleSz.height));
|
||||||
|
m_scaleSz = ncore::gl::drawSize(m_scale);
|
||||||
glutils::resizeInitFrameBuffer(m_frameBuffer, ncore::gl::drawSize(m_scale));
|
glutils::resizeInitFrameBuffer(m_frameBuffer, ncore::gl::drawSize(m_scale));
|
||||||
}
|
}
|
||||||
glutils::FrameBufferBind const frameBufferBind(m_frameBuffer);
|
glutils::FrameBufferBind const frameBufferBind(m_frameBuffer);
|
||||||
@ -33,4 +34,8 @@ glutils::FrameBuffer const&WorldEditorView::framebuffer() const noexcept {
|
|||||||
return m_frameBuffer;
|
return m_frameBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ox::Size WorldEditorView::drawSize() const noexcept {
|
||||||
|
return ncore::gl::drawSize(m_scale);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,12 @@ class WorldEditorView {
|
|||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
glutils::FrameBuffer const&framebuffer() const noexcept;
|
glutils::FrameBuffer const&framebuffer() const noexcept;
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
constexpr int scale() const noexcept { return m_scale; }
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
ox::Size drawSize() const noexcept;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
namespace jasper::world {
|
namespace jasper::world {
|
||||||
|
|
||||||
static void loadTile(ObjectCache const&objCache, TileStatic &dst, TileDoc const&src) noexcept {
|
void loadTile(ObjectCache const&objCache, TileStatic &dst, TileDoc const&src) noexcept {
|
||||||
auto const obj = objCache.obj(src.obj.worldObjectSetId, src.obj.worldObjectId).or_value({});
|
auto const obj = objCache.obj(src.obj.worldObjectSetId, src.obj.worldObjectId).or_value({});
|
||||||
dst.palBank = src.palBank;
|
dst.palBank = src.palBank;
|
||||||
dst.tileIdx = static_cast<uint16_t>(obj.tileIdx);
|
dst.tileIdx = static_cast<uint16_t>(obj.tileIdx);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user