1
0
Fork 0
mirror of https://github.com/AquariaOSE/Aquaria.git synced 2025-01-24 17:26:41 +00:00

more editor fixes:

- correctly sort ElementTemplate by idx, not by pointer. oops.
- selecting tiles works again (new: including wraparound)
- don't display layer tile borders when switching to other edit modes
- make sure that tile selection wraparound doesn't pick up font letter tiles
This commit is contained in:
fgenesis 2023-10-25 00:46:12 +02:00
parent 0a2965e26b
commit 011b9f2a82
4 changed files with 82 additions and 53 deletions

View file

@ -774,14 +774,18 @@ void SceneEditor::init()
placer = new Quad; placer = new Quad;
game->addRenderObject(placer, LR_HUD); game->addRenderObject(placer, LR_HUD);
placer->alpha = 0; placer->alpha = 0;
curElement = 0; curElementId = 0;
selectedEntity.clear(); selectedEntity.clear();
nextElement(); nextElement();
const ElementTemplate *et = dsq->tilemgr.tileset.getIfExists(0);
if(!et)
dsq->tilemgr.tileset.getAdjacent(0, 1, false, 1024);
if (curElement < dsq->tilemgr.tileset.elementTemplates.size())
if (et)
{ {
placer->setTexture(dsq->tilemgr.tileset.elementTemplates[curElement]->gfx); placer->setTexture(et->gfx);
placer->scale = Vector(1,1); placer->scale = Vector(1,1);
} }
else else
@ -962,11 +966,11 @@ void SceneEditor::clearSelection()
void SceneEditor::editModeElements() void SceneEditor::editModeElements()
{ {
clearSelection(); setActiveLayer(bgLayer, editType != ET_ELEMENTS);
editType = ET_ELEMENTS; editType = ET_ELEMENTS;
if (curElement < dsq->tilemgr.tileset.elementTemplates.size()) if (const ElementTemplate *et = dsq->tilemgr.tileset.getIfExists(curElementId))
{ {
placer->setTexture(dsq->tilemgr.tileset.elementTemplates[curElement]->gfx); placer->setTexture(et->gfx);
placer->scale = Vector(1,1); placer->scale = Vector(1,1);
} }
placer->alpha = 0.5; placer->alpha = 0.5;
@ -977,6 +981,7 @@ void SceneEditor::editModeElements()
void SceneEditor::editModeEntities() void SceneEditor::editModeEntities()
{ {
unselectTileLayer();
clearSelection(); clearSelection();
editType = ET_ENTITIES; editType = ET_ENTITIES;
placer->setTexture(selectedEntity.prevGfx); placer->setTexture(selectedEntity.prevGfx);
@ -986,6 +991,7 @@ void SceneEditor::editModeEntities()
void SceneEditor::editModePaths() void SceneEditor::editModePaths()
{ {
unselectTileLayer();
clearSelection(); clearSelection();
editType = ET_PATHS; editType = ET_PATHS;
placer->alpha = 0; placer->alpha = 0;
@ -1731,14 +1737,18 @@ void SceneEditor::updateMultiSelect()
} }
} }
void SceneEditor::setActiveLayer(unsigned bglayer) void SceneEditor::unselectTileLayer()
{ {
if(this->bgLayer == bglayer)
return;
for(size_t i = 0; i < MAX_TILE_LAYERS; ++i) for(size_t i = 0; i < MAX_TILE_LAYERS; ++i)
dsq->tileRenders[i]->renderBorders = false; dsq->tileRenders[i]->renderBorders = false;
}
void SceneEditor::setActiveLayer(unsigned bglayer, bool force)
{
if(this->bgLayer == bglayer && !force)
return;
unselectTileLayer();
dsq->tileRenders[bglayer]->renderBorders = true; dsq->tileRenders[bglayer]->renderBorders = true;
destroyMultiTileHelper(); destroyMultiTileHelper();
@ -2078,7 +2088,7 @@ void SceneEditor::cycleSelectedTiles(int direction)
for(size_t i = 0; i < n; ++i) for(size_t i = 0; i < n; ++i)
{ {
TileData& t = ts.tiles[selectedTiles[i]]; TileData& t = ts.tiles[selectedTiles[i]];
const ElementTemplate *adj = dsq->tilemgr.tileset.getAdjacent(t.et->idx, direction, true); const ElementTemplate *adj = dsq->tilemgr.tileset.getAdjacent(t.et->idx, direction, true, 1024);
if(adj) if(adj)
t.et = adj; t.et = adj;
} }
@ -2158,17 +2168,12 @@ void SceneEditor::prevElement()
void SceneEditor::cyclePlacer(int direction) void SceneEditor::cyclePlacer(int direction)
{ {
const int maxn = (int)dsq->tilemgr.tileset.elementTemplates.size(); const ElementTemplate *next = dsq->tilemgr.tileset.getAdjacent(curElementId, direction, true, 1024);
int nextidx = (int)curElement + direction;
if(nextidx < 0)
nextidx += maxn;
if(nextidx >= maxn)
nextidx -= maxn;
if (maxn && dsq->tilemgr.tileset.elementTemplates[curElement]->idx < 1024) if (next)
{ {
placer->setTexture(dsq->tilemgr.tileset.elementTemplates[curElement]->gfx); placer->setTexture(next->gfx);
curElement = nextidx; curElementId = next->idx;
} }
} }
@ -2178,9 +2183,9 @@ void SceneEditor::selectZero()
if (editType == ET_ELEMENTS) if (editType == ET_ELEMENTS)
{ {
if (dsq->tilemgr.tileset.elementTemplates.empty()) return; curElementId = 0;
curElement = 0; const ElementTemplate *et = dsq->tilemgr.tileset.getIfExists(0);
placer->setTexture(dsq->tilemgr.tileset.elementTemplates[curElement]->gfx); placer->setTexture(et ? et->gfx : "missingimage");
} }
} }
@ -2189,19 +2194,12 @@ void SceneEditor::selectEnd()
if (state != ES_SELECTING) return; if (state != ES_SELECTING) return;
if (editType == ET_ELEMENTS) if (editType == ET_ELEMENTS)
{ {
if (dsq->tilemgr.tileset.elementTemplates.empty()) return; const ElementTemplate *next = dsq->tilemgr.tileset.getAdjacent(0, -1, true, 1024);
if(next)
size_t largest = 0;
for (size_t i = 0; i < dsq->tilemgr.tileset.elementTemplates.size(); i++)
{ {
ElementTemplate *et = dsq->tilemgr.tileset.elementTemplates[i]; curElementId = next->idx;
if (et->idx < 1024 && i > largest) placer->setTexture(next->gfx);
{
largest = i;
}
} }
curElement = largest;
placer->setTexture(dsq->tilemgr.tileset.elementTemplates[curElement]->gfx);
} }
} }
@ -2211,8 +2209,7 @@ void SceneEditor::placeElement()
{ {
if (!core->getShiftState() && !core->getKeyState(KEY_LALT)) if (!core->getShiftState() && !core->getKeyState(KEY_LALT))
{ {
unsigned tilesetID = dsq->tilemgr.tileset.elementTemplates[curElement]->idx; dsq->tilemgr.createOneTile(curElementId, bgLayer, placer->position.x, placer->position.y);
dsq->tilemgr.createOneTile(tilesetID, bgLayer, placer->position.x, placer->position.y);
// FIXME: need to update grid or no? // FIXME: need to update grid or no?
updateText(); updateText();
} }
@ -2414,6 +2411,13 @@ void SceneEditor::updateText()
os << " gfx: " << t.et->gfx; os << " gfx: " << t.et->gfx;
os << " F:" << ((t.flags & TILEFLAG_FH) ? "H" : "") << ((t.flags & TILEFLAG_FV) ? "V" : ""); os << " F:" << ((t.flags & TILEFLAG_FH) ? "H" : "") << ((t.flags & TILEFLAG_FV) ? "V" : "");
} }
else
{
os << " // id: " << curElementId;
const ElementTemplate *et = dsq->tilemgr.tileset.getIfExists(curElementId);
if(et)
os << " gfx: " << et->gfx;
}
break; break;
case ET_ENTITIES: case ET_ENTITIES:
os << "entities (" << dsq->entities.size() << ")"; os << "entities (" << dsq->entities.size() << ")";

View file

@ -223,13 +223,14 @@ protected:
void mouseButtonLeft(); void mouseButtonLeft();
void mouseButtonRight(); void mouseButtonRight();
void setActiveLayer(unsigned bglayer); void setActiveLayer(unsigned bglayer, bool force = false);
TileStorage& getCurrentLayerTiles(); TileStorage& getCurrentLayerTiles();
void clearSelection(); void clearSelection();
void unselectTileLayer();
MultiTileHelper *createMultiTileHelperFromSelection(); MultiTileHelper *createMultiTileHelperFromSelection();
void destroyMultiTileHelper(); void destroyMultiTileHelper();
size_t curElement; size_t curElementId;
Quad *placer; Quad *placer;
MultiTileHelper *multi; MultiTileHelper *multi;

View file

@ -14,6 +14,11 @@ Tileset::~Tileset()
clear(); clear();
} }
static bool _etsort(const ElementTemplate *a, const ElementTemplate *b)
{
return a->idx < b->idx;
}
bool Tileset::loadFile(const char *fn, const unsigned char *usedIdx, size_t usedIdxLen) bool Tileset::loadFile(const char *fn, const unsigned char *usedIdx, size_t usedIdxLen)
{ {
clear(); clear();
@ -50,7 +55,7 @@ bool Tileset::loadFile(const char *fn, const unsigned char *usedIdx, size_t used
if(warn) if(warn)
errorLog("Tileset indices of 1024 and above are reserved; ignored during load"); errorLog("Tileset indices of 1024 and above are reserved; ignored during load");
std::sort(elementTemplates.begin(), elementTemplates.end()); std::sort(elementTemplates.begin(), elementTemplates.end(), _etsort);
// begin preloading textures // begin preloading textures
@ -126,7 +131,7 @@ void Tileset::clear()
elementTemplates.clear(); elementTemplates.clear();
} }
const ElementTemplate *Tileset::getByIdx(size_t idx) const ElementTemplate * Tileset::getIfExists(size_t idx)
{ {
for (size_t i = 0; i < elementTemplates.size(); i++) for (size_t i = 0; i < elementTemplates.size(); i++)
{ {
@ -137,6 +142,13 @@ const ElementTemplate *Tileset::getByIdx(size_t idx)
return et; return et;
} }
} }
return NULL;
}
const ElementTemplate *Tileset::getByIdx(size_t idx)
{
if(const ElementTemplate *existing = getIfExists(idx))
return existing;
// a tile that gets an ET attached must remember its tileset id even if the entry is not present // a tile that gets an ET attached must remember its tileset id even if the entry is not present
// in the tileset. since the tile does not store the idx as an integer, we need to return a dummy element. // in the tileset. since the tile does not store the idx as an integer, we need to return a dummy element.
@ -161,9 +173,9 @@ const ElementTemplate *Tileset::getByIdx(size_t idx)
return dummy; return dummy;
} }
const ElementTemplate* Tileset::getAdjacent(size_t idx, int direction, bool wraparound) const ElementTemplate* Tileset::getAdjacent(size_t idx, int direction, bool wraparound, size_t maxidx)
{ {
ElementTemplate *et = _getAdjacent(idx, direction, wraparound); ElementTemplate *et = _getAdjacent(idx, direction, wraparound, maxidx);
if(et) if(et)
et->finalize(); // load just in case et->finalize(); // load just in case
return et; return et;
@ -207,10 +219,17 @@ void ElementTemplate::finalize()
} }
} }
ElementTemplate * Tileset::_getAdjacent(size_t idx, int direction, bool wraparound) ElementTemplate * Tileset::_getAdjacent(size_t idx, int direction, bool wraparound, size_t maxidx)
{ {
assert(direction == 1 || direction == -1); assert(direction == 1 || direction == -1);
const size_t maxn = elementTemplates.size(); const size_t maxn = elementTemplates.size();
if(!maxn)
return NULL;
if(idx >= maxidx)
return NULL;
size_t closest = 0; size_t closest = 0;
int mindiff = 0; int mindiff = 0;
for (size_t i = 0; i < maxn; i++) for (size_t i = 0; i < maxn; i++)
@ -220,14 +239,16 @@ ElementTemplate * Tileset::_getAdjacent(size_t idx, int direction, bool wraparou
if(wraparound) if(wraparound)
{ {
if(!i && direction < 0) if(!i && direction < 0)
return elementTemplates.back(); for(size_t k = maxn; k --> 0; )
if(i + direction >= maxn) if(elementTemplates[k]->idx < maxidx)
return elementTemplates[k];
if(i + direction >= maxn || elementTemplates[i+direction]->idx >= maxidx)
return elementTemplates[0]; return elementTemplates[0];
} }
else
i += direction; // may underflow i += direction; // may underflow
return i < maxn ? elementTemplates[i] : NULL; return i < maxn && elementTemplates[i]->idx < maxidx ? elementTemplates[i] : NULL;
} }
int diff = labs((int)elementTemplates[i]->idx - (int)idx); int diff = labs((int)elementTemplates[i]->idx - (int)idx);
if(diff < mindiff || !mindiff) if(diff < mindiff || !mindiff)
@ -247,11 +268,13 @@ ElementTemplate * Tileset::_getAdjacent(size_t idx, int direction, bool wraparou
else if(wraparound) else if(wraparound)
{ {
if(!closest && direction < 0) if(!closest && direction < 0)
return elementTemplates.back(); for(size_t k = maxn; k --> 0; )
if(closest + direction >= maxn) if(elementTemplates[k]->idx < maxidx)
return elementTemplates[k];
if(closest + direction >= maxn || elementTemplates[closest+direction]->idx >= maxidx)
return elementTemplates[0]; return elementTemplates[0];
} }
size_t i = closest + direction; size_t i = closest + direction;
return i < maxn ? elementTemplates[i] : NULL; return i < maxn && elementTemplates[i]->idx < maxidx ? elementTemplates[i] : NULL;
} }

View file

@ -13,7 +13,6 @@ class ElementTemplate
public: public:
ElementTemplate() { w=0; h=0; idx=-1; tc.setStandard(); grid = NULL; } ElementTemplate() { w=0; h=0; idx=-1; tc.setStandard(); grid = NULL; }
~ElementTemplate(); ~ElementTemplate();
inline bool operator<(const ElementTemplate& o) const { return idx < o.idx; }
void finalize(); // call after settings params void finalize(); // call after settings params
@ -46,14 +45,16 @@ public:
// return valid ET if found, or creates a dummy if not. never returns NULL. // return valid ET if found, or creates a dummy if not. never returns NULL.
const ElementTemplate *getByIdx(size_t idx); const ElementTemplate *getByIdx(size_t idx);
const ElementTemplate *getIfExists(size_t idx);
// search for non-dummy ET in a given direction. used to cycle through ETs. // search for non-dummy ET in a given direction. used to cycle through ETs.
// never returns dummy ET. May return NULL. // never returns dummy ET. May return NULL.
const ElementTemplate *getAdjacent(size_t idx, int direction, bool wraparound); const ElementTemplate *getAdjacent(size_t idx, int direction, bool wraparound, size_t maxidx);
std::vector<ElementTemplate*> elementTemplates; std::vector<ElementTemplate*> elementTemplates;
private: private:
ElementTemplate *_getAdjacent(size_t idx, int direction, bool wraparound); ElementTemplate *_getAdjacent(size_t idx, int direction, bool wraparound, size_t maxidx);
std::vector<ElementTemplate*> dummies; std::vector<ElementTemplate*> dummies;
}; };