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

View file

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

View file

@ -14,6 +14,11 @@ Tileset::~Tileset()
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)
{
clear();
@ -50,7 +55,7 @@ bool Tileset::loadFile(const char *fn, const unsigned char *usedIdx, size_t used
if(warn)
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
@ -126,7 +131,7 @@ void Tileset::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++)
{
@ -137,6 +142,13 @@ const ElementTemplate *Tileset::getByIdx(size_t idx)
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
// 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;
}
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)
et->finalize(); // load just in case
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);
const size_t maxn = elementTemplates.size();
if(!maxn)
return NULL;
if(idx >= maxidx)
return NULL;
size_t closest = 0;
int mindiff = 0;
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(!i && direction < 0)
return elementTemplates.back();
if(i + direction >= maxn)
for(size_t k = maxn; k --> 0; )
if(elementTemplates[k]->idx < maxidx)
return elementTemplates[k];
if(i + direction >= maxn || elementTemplates[i+direction]->idx >= maxidx)
return elementTemplates[0];
}
else
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);
if(diff < mindiff || !mindiff)
@ -247,11 +268,13 @@ ElementTemplate * Tileset::_getAdjacent(size_t idx, int direction, bool wraparou
else if(wraparound)
{
if(!closest && direction < 0)
return elementTemplates.back();
if(closest + direction >= maxn)
for(size_t k = maxn; k --> 0; )
if(elementTemplates[k]->idx < maxidx)
return elementTemplates[k];
if(closest + direction >= maxn || elementTemplates[closest+direction]->idx >= maxidx)
return elementTemplates[0];
}
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:
ElementTemplate() { w=0; h=0; idx=-1; tc.setStandard(); grid = NULL; }
~ElementTemplate();
inline bool operator<(const ElementTemplate& o) const { return idx < o.idx; }
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.
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.
// 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;
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;
};