tibia-rme/source/spawn_monster.h
Victor cbf183cbb1
fix: NPC spawn use-after-free on map import, progress bar freeze, and improved diagnostics (#167)
Bug Fixes:
- Fixed tile merge behavior to properly handle both monster and NPC spawns when importing maps.
- Improved spawn size validation to check input bounds before assignment.
- Removed duplicate NPC transfer logic in tile operations.

Improvements:
- Enhanced diagnostic messages during map loading with contextual information about tile areas and file positions.
- Updated error messaging for tile position parsing failures in map formats.
2026-04-21 11:56:46 -03:00

92 lines
2.4 KiB
C++

//////////////////////////////////////////////////////////////////////
// This file is part of Remere's Map Editor
//////////////////////////////////////////////////////////////////////
// Remere's Map Editor is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Remere's Map Editor is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//////////////////////////////////////////////////////////////////////
#ifndef RME_SPAWN_MONSTER_H_
#define RME_SPAWN_MONSTER_H_
class Tile;
class SpawnMonster {
public:
SpawnMonster(int size = 3);
SpawnMonster* deepCopy() const;
bool isSelected() const noexcept {
return selected;
}
void select() noexcept {
selected = true;
}
void deselect() noexcept {
selected = false;
}
int getSize() const noexcept {
return size;
}
// Does not compare selection!
bool operator==(const SpawnMonster &other) {
return size == other.size;
}
bool operator!=(const SpawnMonster &other) {
return size != other.size;
}
void setSize(int newsize) {
ASSERT(newsize >= 0 && newsize < 100);
size = newsize;
}
protected:
int size;
bool selected;
};
typedef std::set<Position> SpawnMonsterPositionList;
typedef std::list<SpawnMonster*> SpawnMonsterList;
class SpawnsMonster {
public:
void addSpawnMonster(Tile* tile);
void removeSpawnMonster(Tile* tile);
SpawnMonsterPositionList::iterator begin() noexcept {
return spawnsMonster.begin();
}
SpawnMonsterPositionList::const_iterator begin() const noexcept {
return spawnsMonster.begin();
}
SpawnMonsterPositionList::iterator end() noexcept {
return spawnsMonster.end();
}
SpawnMonsterPositionList::const_iterator end() const noexcept {
return spawnsMonster.end();
}
void erase(SpawnMonsterPositionList::iterator iter) noexcept {
spawnsMonster.erase(iter);
}
SpawnMonsterPositionList::iterator find(Position &pos) {
return spawnsMonster.find(pos);
}
private:
SpawnMonsterPositionList spawnsMonster;
};
#endif