tibia-rme/source/brush.cpp

698 lines
17 KiB
C++
Raw Permalink Normal View History

//////////////////////////////////////////////////////////////////////
// This file is part of Remere's Map Editor
//////////////////////////////////////////////////////////////////////
2020-07-30 11:42:28 -03:00
// 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.
//
2020-07-30 11:42:28 -03:00
// Remere's Map Editor is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
2020-07-30 11:42:28 -03:00
// 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
2020-07-30 11:42:28 -03:00
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//////////////////////////////////////////////////////////////////////
#include "main.h"
#include "brush.h"
#include "carpet_brush.h"
#include "monster_brush.h"
#include "npc_brush.h"
#include "doodad_brush.h"
#include "ground_brush.h"
#include "house_brush.h"
#include "house_exit_brush.h"
#include "raw_brush.h"
#include "spawn_monster_brush.h"
#include "spawn_npc_brush.h"
#include "table_brush.h"
#include "wall_brush.h"
#include "waypoint_brush.h"
#include "settings.h"
#include "sprites.h"
#include "item.h"
#include "complexitem.h"
#include "monsters.h"
#include "monster.h"
#include "npcs.h"
#include "npc.h"
#include "map.h"
#include "gui.h"
Brushes g_brushes;
2023-10-09 19:12:16 -07:00
Brushes::Brushes() {
2015-12-06 11:42:37 -03:00
////
}
2023-10-09 19:12:16 -07:00
Brushes::~Brushes() {
2015-12-06 11:42:37 -03:00
////
}
2023-10-09 19:12:16 -07:00
void Brushes::clear() {
for (auto brushEntry : brushes) {
2014-03-01 14:44:11 +01:00
delete brushEntry.second;
}
brushes.clear();
2014-03-01 14:44:11 +01:00
2023-10-09 19:12:16 -07:00
for (auto borderEntry : borders) {
2014-03-01 14:44:11 +01:00
delete borderEntry.second;
}
borders.clear();
}
2023-10-09 19:12:16 -07:00
void Brushes::init() {
addBrush(g_gui.optional_brush = newd OptionalBorderBrush());
addBrush(g_gui.eraser = newd EraserBrush());
addBrush(g_gui.spawn_brush = newd SpawnMonsterBrush());
addBrush(g_gui.spawn_npc_brush = newd SpawnNpcBrush());
addBrush(g_gui.normal_door_brush = newd DoorBrush(WALL_DOOR_NORMAL));
addBrush(g_gui.locked_door_brush = newd DoorBrush(WALL_DOOR_LOCKED));
addBrush(g_gui.magic_door_brush = newd DoorBrush(WALL_DOOR_MAGIC));
addBrush(g_gui.quest_door_brush = newd DoorBrush(WALL_DOOR_QUEST));
addBrush(g_gui.hatch_door_brush = newd DoorBrush(WALL_HATCH_WINDOW));
addBrush(g_gui.window_door_brush = newd DoorBrush(WALL_WINDOW));
addBrush(g_gui.house_brush = newd HouseBrush());
addBrush(g_gui.house_exit_brush = newd HouseExitBrush());
addBrush(g_gui.waypoint_brush = newd WaypointBrush());
addBrush(g_gui.pz_brush = newd FlagBrush(TILESTATE_PROTECTIONZONE));
addBrush(g_gui.rook_brush = newd FlagBrush(TILESTATE_NOPVP));
addBrush(g_gui.nolog_brush = newd FlagBrush(TILESTATE_NOLOGOUT));
addBrush(g_gui.pvp_brush = newd FlagBrush(TILESTATE_PVPZONE));
GroundBrush::init();
WallBrush::init();
TableBrush::init();
CarpetBrush::init();
}
2023-10-09 19:12:16 -07:00
bool Brushes::unserializeBrush(pugi::xml_node node, wxArrayString &warnings) {
pugi::xml_attribute attribute;
2023-10-09 19:12:16 -07:00
if (!(attribute = node.attribute("name"))) {
2016-11-05 15:28:14 +01:00
warnings.push_back("Brush node without name.");
return false;
}
2023-10-09 19:12:16 -07:00
const std::string &brushName = attribute.as_string();
if (brushName == "all" || brushName == "none") {
2016-11-05 15:28:14 +01:00
warnings.push_back(wxString("Using reserved brushname \"") << wxstr(brushName) << "\".");
return false;
}
Brush* brush = getBrush(brushName);
2023-10-09 19:12:16 -07:00
if (!brush) {
if (!(attribute = node.attribute("type"))) {
2016-11-05 15:28:14 +01:00
warnings.push_back("Couldn't read brush type");
return false;
}
const std::string brushType = attribute.as_string();
2023-10-09 19:12:16 -07:00
if (brushType == "border" || brushType == "ground") {
brush = newd GroundBrush();
2023-10-09 19:12:16 -07:00
} else if (brushType == "wall") {
brush = newd WallBrush();
2023-10-09 19:12:16 -07:00
} else if (brushType == "wall decoration") {
brush = newd WallDecorationBrush();
2023-10-09 19:12:16 -07:00
} else if (brushType == "carpet") {
brush = newd CarpetBrush();
2023-10-09 19:12:16 -07:00
} else if (brushType == "table") {
brush = newd TableBrush();
2023-10-09 19:12:16 -07:00
} else if (brushType == "doodad") {
brush = newd DoodadBrush();
} else {
2016-11-05 15:28:14 +01:00
warnings.push_back(wxString("Unknown brush type ") << wxstr(brushType));
return false;
}
ASSERT(brush);
brush->setName(brushName);
}
2023-10-09 19:12:16 -07:00
if (!node.first_child()) {
brushes.insert(std::make_pair(brush->getName(), brush));
return true;
}
wxArrayString subWarnings;
brush->load(node, subWarnings);
2023-10-09 19:12:16 -07:00
if (!subWarnings.empty()) {
2016-11-05 15:28:14 +01:00
warnings.push_back(wxString("Errors while loading brush \"") << wxstr(brush->getName()) << "\"");
warnings.insert(warnings.end(), subWarnings.begin(), subWarnings.end());
}
2023-10-09 19:12:16 -07:00
if (brush->getName() == "all" || brush->getName() == "none") {
2016-11-05 15:28:14 +01:00
warnings.push_back(wxString("Using reserved brushname '") << wxstr(brush->getName()) << "'.");
delete brush;
return false;
}
Brush* otherBrush = getBrush(brush->getName());
2023-10-09 19:12:16 -07:00
if (otherBrush) {
if (otherBrush != brush) {
2016-11-05 15:28:14 +01:00
warnings.push_back(wxString("Duplicate brush name ") << wxstr(brush->getName()) << ". Undefined behaviour may ensue.");
} else {
// Don't insert
return true;
}
}
brushes.insert(std::make_pair(brush->getName(), brush));
return true;
}
2023-10-09 19:12:16 -07:00
bool Brushes::unserializeBorder(pugi::xml_node node, wxArrayString &warnings) {
pugi::xml_attribute attribute = node.attribute("id");
2023-10-09 19:12:16 -07:00
if (!attribute) {
2016-11-05 15:28:14 +01:00
warnings.push_back("Couldn't read border id node");
return false;
}
uint32_t id = attribute.as_uint();
2023-10-09 19:12:16 -07:00
if (borders[id]) {
2016-11-05 15:28:14 +01:00
warnings.push_back("Border ID " + std::to_string(id) + " already exists");
return false;
}
AutoBorder* border = newd AutoBorder(id);
border->load(node, warnings);
borders[id] = border;
return true;
}
2023-10-09 19:12:16 -07:00
void Brushes::addBrush(Brush* brush) {
brushes.insert(std::make_pair(brush->getName(), brush));
}
2023-10-09 19:12:16 -07:00
Brush* Brushes::getBrush(const std::string &name) const {
2014-03-01 14:44:11 +01:00
auto it = brushes.find(name);
2023-10-09 19:12:16 -07:00
if (it != brushes.end()) {
return it->second;
2014-03-01 14:44:11 +01:00
}
return nullptr;
}
// Brush
uint32_t Brush::id_counter = 0;
Brush::Brush() :
2023-10-09 19:12:16 -07:00
id(++id_counter), visible(false) {
2015-12-06 11:42:37 -03:00
////
}
2023-10-09 19:12:16 -07:00
Brush::~Brush() {
2015-12-06 11:42:37 -03:00
////
}
// TerrainBrush
TerrainBrush::TerrainBrush() :
2023-10-09 19:12:16 -07:00
look_id(0), hate_friends(false) {
2015-12-06 11:42:37 -03:00
////
}
2023-10-09 19:12:16 -07:00
TerrainBrush::~TerrainBrush() {
2015-12-06 11:42:37 -03:00
////
}
2023-10-09 19:12:16 -07:00
bool TerrainBrush::friendOf(TerrainBrush* other) {
uint32_t borderID = other->getID();
2023-10-09 19:12:16 -07:00
for (uint32_t friendId : friends) {
if (friendId == borderID) {
// printf("%s is friend of %s\n", getName().c_str(), other->getName().c_str());
return !hate_friends;
2023-10-09 19:12:16 -07:00
} else if (friendId == 0xFFFFFFFF) {
// printf("%s is generic friend of %s\n", getName().c_str(), other->getName().c_str());
return !hate_friends;
}
}
2023-10-09 19:12:16 -07:00
// printf("%s is enemy of %s\n", getName().c_str(), other->getName().c_str());
return hate_friends;
}
//=============================================================================
// Flag brush
// draws pz etc.
2023-10-09 19:12:16 -07:00
FlagBrush::FlagBrush(uint32_t _flag) :
flag(_flag) {
2015-12-06 11:42:37 -03:00
////
}
2023-10-09 19:12:16 -07:00
FlagBrush::~FlagBrush() {
2015-12-06 11:42:37 -03:00
////
}
2023-10-09 19:12:16 -07:00
std::string FlagBrush::getName() const {
switch (flag) {
case TILESTATE_PROTECTIONZONE:
return "PZ brush (0x01)";
case TILESTATE_NOPVP:
return "No combat zone brush (0x04)";
case TILESTATE_NOLOGOUT:
return "No logout zone brush (0x08)";
case TILESTATE_PVPZONE:
return "PVP Zone brush (0x10)";
}
return "Unknown flag brush";
}
2023-10-09 19:12:16 -07:00
int FlagBrush::getLookID() const {
switch (flag) {
case TILESTATE_PROTECTIONZONE:
return EDITOR_SPRITE_PZ_TOOL;
case TILESTATE_NOPVP:
return EDITOR_SPRITE_NOPVP_TOOL;
case TILESTATE_NOLOGOUT:
return EDITOR_SPRITE_NOLOG_TOOL;
case TILESTATE_PVPZONE:
return EDITOR_SPRITE_PVPZ_TOOL;
}
return 0;
}
2023-10-09 19:12:16 -07:00
bool FlagBrush::canDraw(BaseMap* map, const Position &position) const {
2014-03-01 14:44:11 +01:00
Tile* tile = map->getTile(position);
return tile && tile->hasGround();
}
2023-10-09 19:12:16 -07:00
void FlagBrush::undraw(BaseMap* map, Tile* tile) {
tile->unsetMapFlags(flag);
}
2023-10-09 19:12:16 -07:00
void FlagBrush::draw(BaseMap* map, Tile* tile, void* parameter) {
if (tile->hasGround()) {
tile->setMapFlags(flag);
}
}
//=============================================================================
// Door brush
2023-10-09 19:12:16 -07:00
DoorBrush::DoorBrush(DoorType _doortype) :
doortype(_doortype) {
2015-12-06 11:42:37 -03:00
////
}
2023-10-09 19:12:16 -07:00
DoorBrush::~DoorBrush() {
2015-12-06 11:42:37 -03:00
////
}
2023-10-09 19:12:16 -07:00
std::string DoorBrush::getName() const {
switch (doortype) {
case WALL_DOOR_NORMAL:
return "Normal door brush";
case WALL_DOOR_LOCKED:
return "Locked door brush";
case WALL_DOOR_MAGIC:
return "Magic door brush";
case WALL_DOOR_QUEST:
return "Quest door brush";
case WALL_WINDOW:
return "Window brush";
case WALL_HATCH_WINDOW:
return "Hatch window brush";
default:
return "Unknown door brush";
}
}
2023-10-09 19:12:16 -07:00
int DoorBrush::getLookID() const {
switch (doortype) {
case WALL_DOOR_NORMAL:
return EDITOR_SPRITE_DOOR_NORMAL;
case WALL_DOOR_LOCKED:
return EDITOR_SPRITE_DOOR_LOCKED;
case WALL_DOOR_MAGIC:
return EDITOR_SPRITE_DOOR_MAGIC;
case WALL_DOOR_QUEST:
return EDITOR_SPRITE_DOOR_QUEST;
case WALL_WINDOW:
return EDITOR_SPRITE_WINDOW_NORMAL;
case WALL_HATCH_WINDOW:
return EDITOR_SPRITE_WINDOW_HATCH;
default:
return EDITOR_SPRITE_DOOR_NORMAL;
}
}
2023-10-16 01:17:54 -03:00
void DoorBrush::switchDoor(std::shared_ptr<Item> item) {
ASSERT(item);
ASSERT(item->isBrushDoor());
WallBrush* wb = item->getWallBrush();
2023-10-09 19:12:16 -07:00
if (!wb) {
return;
}
bool new_open = !item->isOpen();
BorderType wall_alignment = item->getWallAlignment();
DoorType doortype = WALL_UNDEFINED;
2023-10-09 19:12:16 -07:00
for (std::vector<WallBrush::DoorType>::iterator iter = wb->door_items[wall_alignment].begin(); iter != wb->door_items[wall_alignment].end(); ++iter) {
WallBrush::DoorType &dt = *iter;
if (dt.id == item->getID()) {
doortype = dt.type;
break;
}
}
2023-10-09 19:12:16 -07:00
if (doortype == WALL_UNDEFINED) {
return;
}
2023-10-09 19:12:16 -07:00
for (std::vector<WallBrush::DoorType>::iterator iter = wb->door_items[wall_alignment].begin(); iter != wb->door_items[wall_alignment].end(); ++iter) {
WallBrush::DoorType &dt = *iter;
if (dt.type == doortype) {
ASSERT(dt.id);
2023-10-09 19:12:16 -07:00
const ItemType &type = g_items.getItemType(dt.id);
feat: synchronizing commits with the official rme repository (#36) * Show indicators for pickupable and moveable items * Fix: drawing always refreshing ui * Fix crash on invalid friend for wallbrush * Option to remove empty spawns * Draws position indicator, some code cleanup * Teleport copy/paste improvements * Fix flood fill * Add function to get minimap/8bit color * Small code cleanup * Cleanup Position * Code cleanup and small optimizations * Code cleanup * Code cleanup and small optimizations (#406) * Cleanup and cast functions. * Avoid adding a new Unique ID if it already exists * Code cleanup and small optimizations * More changes and cleanup * Changes and cleanup * Some changes * Fix copy position. * Only show uid/aid alert if it really changed * Add actions history panel * Does not draw tooltips on minimap mode * Use constexpr * Replace items fix (#408) * Draw grid small optimization * Small change in selection box and Fix #409 * Fix some xpm * Ingame box improvements, add lights support. * Fix go to previous position (#410) * Fix depot crash (#411) * Fix XPMs * Export minimap as .otmm (otclient format) or .png (#413) * Fix glitch after drawing secondary map * fix * Update about_window.cpp * sonar * fix Minimap and progress bar * fix erro load items.xml * fix * fix doodad brush * fix: slightly more accurate house size estimation * feat: update items.otb and items.xml * fix: bad merge * Revert "feat: update items.otb and items.xml" This reverts commit 40f1edc70f17c423282d546a41541a8fe9b92dcc. --------- Co-authored-by: Nailson <Mignari@users.noreply.github.com> Co-authored-by: wtver <51377408+maattch@users.noreply.github.com> Co-authored-by: Majesty <32709570+majestyotbr@users.noreply.github.com> Co-authored-by: Luan Santos <github@luan.sh>
2023-10-09 23:02:37 -03:00
ASSERT(type.id != 0);
2023-10-09 19:12:16 -07:00
if (type.isOpen == new_open) {
item->setID(dt.id);
return;
}
}
}
}
2023-10-09 19:12:16 -07:00
bool DoorBrush::canDraw(BaseMap* map, const Position &position) const {
2014-03-01 14:44:11 +01:00
Tile* tile = map->getTile(position);
2023-10-09 19:12:16 -07:00
if (!tile) {
2014-03-01 14:44:11 +01:00
return false;
}
2023-10-16 04:18:32 +00:00
const auto &item = tile->getWall();
2023-10-09 19:12:16 -07:00
if (!item) {
2014-03-01 14:44:11 +01:00
return false;
}
WallBrush* wb = item->getWallBrush();
2023-10-09 19:12:16 -07:00
if (!wb) {
2014-03-01 14:44:11 +01:00
return false;
}
BorderType wall_alignment = item->getWallAlignment();
uint16_t discarded_id = 0; // The id of a discarded match
bool close_match = false;
bool open = false;
2023-10-09 19:12:16 -07:00
if (item->isBrushDoor()) {
open = item->isOpen();
}
WallBrush* test_brush = wb;
do {
2023-10-09 19:12:16 -07:00
for (std::vector<WallBrush::DoorType>::iterator iter = test_brush->door_items[wall_alignment].begin();
iter != test_brush->door_items[wall_alignment].end();
++iter) {
WallBrush::DoorType &dt = *iter;
if (dt.type == doortype) {
ASSERT(dt.id);
2023-10-09 19:12:16 -07:00
const ItemType &type = g_items.getItemType(dt.id);
feat: synchronizing commits with the official rme repository (#36) * Show indicators for pickupable and moveable items * Fix: drawing always refreshing ui * Fix crash on invalid friend for wallbrush * Option to remove empty spawns * Draws position indicator, some code cleanup * Teleport copy/paste improvements * Fix flood fill * Add function to get minimap/8bit color * Small code cleanup * Cleanup Position * Code cleanup and small optimizations * Code cleanup * Code cleanup and small optimizations (#406) * Cleanup and cast functions. * Avoid adding a new Unique ID if it already exists * Code cleanup and small optimizations * More changes and cleanup * Changes and cleanup * Some changes * Fix copy position. * Only show uid/aid alert if it really changed * Add actions history panel * Does not draw tooltips on minimap mode * Use constexpr * Replace items fix (#408) * Draw grid small optimization * Small change in selection box and Fix #409 * Fix some xpm * Ingame box improvements, add lights support. * Fix go to previous position (#410) * Fix depot crash (#411) * Fix XPMs * Export minimap as .otmm (otclient format) or .png (#413) * Fix glitch after drawing secondary map * fix * Update about_window.cpp * sonar * fix Minimap and progress bar * fix erro load items.xml * fix * fix doodad brush * fix: slightly more accurate house size estimation * feat: update items.otb and items.xml * fix: bad merge * Revert "feat: update items.otb and items.xml" This reverts commit 40f1edc70f17c423282d546a41541a8fe9b92dcc. --------- Co-authored-by: Nailson <Mignari@users.noreply.github.com> Co-authored-by: wtver <51377408+maattch@users.noreply.github.com> Co-authored-by: Majesty <32709570+majestyotbr@users.noreply.github.com> Co-authored-by: Luan Santos <github@luan.sh>
2023-10-09 23:02:37 -03:00
ASSERT(type.id != 0);
2023-10-09 19:12:16 -07:00
if (type.isOpen == open) {
return true;
2023-10-09 19:12:16 -07:00
} else if (!close_match) {
discarded_id = dt.id;
close_match = true;
}
2023-10-09 19:12:16 -07:00
if (!close_match && discarded_id == 0) {
discarded_id = dt.id;
}
}
}
test_brush = test_brush->redirect_to;
2023-10-09 19:12:16 -07:00
} while (test_brush != wb && test_brush != nullptr);
// If we've found no perfect match, use a close-to perfect
2023-10-09 19:12:16 -07:00
if (discarded_id) {
return true;
}
return false;
}
2023-10-09 19:12:16 -07:00
void DoorBrush::undraw(BaseMap* map, Tile* tile) {
for (ItemVector::iterator it = tile->items.begin(); it != tile->items.end(); ++it) {
2023-10-16 04:18:32 +00:00
const auto &item = *it;
2023-10-09 19:12:16 -07:00
if (item->isBrushDoor()) {
item->getWallBrush()->draw(map, tile, nullptr);
2023-10-09 19:12:16 -07:00
if (g_settings.getInteger(Config::USE_AUTOMAGIC)) {
tile->wallize(map);
}
return;
}
}
}
2023-10-09 19:12:16 -07:00
void DoorBrush::draw(BaseMap* map, Tile* tile, void* parameter) {
for (ItemVector::iterator item_iter = tile->items.begin(); item_iter != tile->items.end();) {
2023-10-16 01:17:54 -03:00
auto item = *item_iter;
2023-10-09 19:12:16 -07:00
if (!item->isWall()) {
++item_iter;
continue;
}
WallBrush* wb = item->getWallBrush();
2023-10-09 19:12:16 -07:00
if (!wb) {
++item_iter;
continue;
}
BorderType wall_alignment = item->getWallAlignment();
uint16_t discarded_id = 0; // The id of a discarded match
bool close_match = false;
bool perfect_match = false;
bool open = false;
2023-10-09 19:12:16 -07:00
if (parameter) {
open = *reinterpret_cast<bool*>(parameter);
}
2023-10-09 19:12:16 -07:00
if (item->isBrushDoor()) {
open = item->isOpen();
}
WallBrush* test_brush = wb;
do {
2023-10-09 19:12:16 -07:00
for (std::vector<WallBrush::DoorType>::iterator iter = test_brush->door_items[wall_alignment].begin();
iter != test_brush->door_items[wall_alignment].end();
++iter) {
WallBrush::DoorType &dt = *iter;
if (dt.type == doortype) {
ASSERT(dt.id);
2023-10-09 19:12:16 -07:00
const ItemType &type = g_items.getItemType(dt.id);
feat: synchronizing commits with the official rme repository (#36) * Show indicators for pickupable and moveable items * Fix: drawing always refreshing ui * Fix crash on invalid friend for wallbrush * Option to remove empty spawns * Draws position indicator, some code cleanup * Teleport copy/paste improvements * Fix flood fill * Add function to get minimap/8bit color * Small code cleanup * Cleanup Position * Code cleanup and small optimizations * Code cleanup * Code cleanup and small optimizations (#406) * Cleanup and cast functions. * Avoid adding a new Unique ID if it already exists * Code cleanup and small optimizations * More changes and cleanup * Changes and cleanup * Some changes * Fix copy position. * Only show uid/aid alert if it really changed * Add actions history panel * Does not draw tooltips on minimap mode * Use constexpr * Replace items fix (#408) * Draw grid small optimization * Small change in selection box and Fix #409 * Fix some xpm * Ingame box improvements, add lights support. * Fix go to previous position (#410) * Fix depot crash (#411) * Fix XPMs * Export minimap as .otmm (otclient format) or .png (#413) * Fix glitch after drawing secondary map * fix * Update about_window.cpp * sonar * fix Minimap and progress bar * fix erro load items.xml * fix * fix doodad brush * fix: slightly more accurate house size estimation * feat: update items.otb and items.xml * fix: bad merge * Revert "feat: update items.otb and items.xml" This reverts commit 40f1edc70f17c423282d546a41541a8fe9b92dcc. --------- Co-authored-by: Nailson <Mignari@users.noreply.github.com> Co-authored-by: wtver <51377408+maattch@users.noreply.github.com> Co-authored-by: Majesty <32709570+majestyotbr@users.noreply.github.com> Co-authored-by: Luan Santos <github@luan.sh>
2023-10-09 23:02:37 -03:00
ASSERT(type.id != 0);
2023-10-09 19:12:16 -07:00
if (type.isOpen == open) {
item = transformItem(item, dt.id, tile);
perfect_match = true;
break;
2023-10-09 19:12:16 -07:00
} else if (!close_match) {
discarded_id = dt.id;
close_match = true;
}
2023-10-09 19:12:16 -07:00
if (!close_match && discarded_id == 0) {
discarded_id = dt.id;
}
}
}
test_brush = test_brush->redirect_to;
2023-10-09 19:12:16 -07:00
if (perfect_match) {
break;
}
2023-10-09 19:12:16 -07:00
} while (test_brush != wb && test_brush != nullptr);
// If we've found no perfect match, use a close-to perfect
2023-10-09 19:12:16 -07:00
if (!perfect_match && discarded_id) {
item = transformItem(item, discarded_id, tile);
}
2023-10-09 19:12:16 -07:00
if (g_settings.getInteger(Config::AUTO_ASSIGN_DOORID) && tile->isHouseTile()) {
Map* mmap = dynamic_cast<Map*>(map);
2023-10-16 01:17:54 -03:00
const std::shared_ptr<Door> &door = static_self_cast<Door>(item);
2023-10-09 19:12:16 -07:00
if (mmap && door) {
House* house = mmap->houses.getHouse(tile->getHouseID());
ASSERT(house);
Map* real_map = dynamic_cast<Map*>(map);
2023-10-09 19:12:16 -07:00
if (real_map) {
door->setDoorID(house->getEmptyDoorID());
}
}
}
// We need to consider decorations!
2023-10-09 19:12:16 -07:00
while (true) {
// Vector has been modified, before we can use the iterator again we need to find the wall item again
item_iter = tile->items.begin();
2023-10-09 19:12:16 -07:00
while (true) {
if (item_iter == tile->items.end()) {
return;
}
2023-10-09 19:12:16 -07:00
if (*item_iter == item) {
++item_iter;
2023-10-09 19:12:16 -07:00
if (item_iter == tile->items.end()) {
return;
}
break;
}
++item_iter;
}
// Now it points to the correct item!
item = *item_iter;
2023-10-09 19:12:16 -07:00
if (item->isWall()) {
2016-11-12 10:30:06 -03:00
WallBrush* brush = item->getWallBrush();
2023-10-09 19:12:16 -07:00
if (brush && brush->isWallDecoration()) {
// We got a decoration!
2016-11-12 10:30:06 -03:00
for (std::vector<WallBrush::DoorType>::iterator it = brush->door_items[wall_alignment].begin(); it != brush->door_items[wall_alignment].end(); ++it) {
2023-10-09 19:12:16 -07:00
WallBrush::DoorType &dt = (*it);
if (dt.type == doortype) {
ASSERT(dt.id);
2023-10-09 19:12:16 -07:00
const ItemType &type = g_items.getItemType(dt.id);
feat: synchronizing commits with the official rme repository (#36) * Show indicators for pickupable and moveable items * Fix: drawing always refreshing ui * Fix crash on invalid friend for wallbrush * Option to remove empty spawns * Draws position indicator, some code cleanup * Teleport copy/paste improvements * Fix flood fill * Add function to get minimap/8bit color * Small code cleanup * Cleanup Position * Code cleanup and small optimizations * Code cleanup * Code cleanup and small optimizations (#406) * Cleanup and cast functions. * Avoid adding a new Unique ID if it already exists * Code cleanup and small optimizations * More changes and cleanup * Changes and cleanup * Some changes * Fix copy position. * Only show uid/aid alert if it really changed * Add actions history panel * Does not draw tooltips on minimap mode * Use constexpr * Replace items fix (#408) * Draw grid small optimization * Small change in selection box and Fix #409 * Fix some xpm * Ingame box improvements, add lights support. * Fix go to previous position (#410) * Fix depot crash (#411) * Fix XPMs * Export minimap as .otmm (otclient format) or .png (#413) * Fix glitch after drawing secondary map * fix * Update about_window.cpp * sonar * fix Minimap and progress bar * fix erro load items.xml * fix * fix doodad brush * fix: slightly more accurate house size estimation * feat: update items.otb and items.xml * fix: bad merge * Revert "feat: update items.otb and items.xml" This reverts commit 40f1edc70f17c423282d546a41541a8fe9b92dcc. --------- Co-authored-by: Nailson <Mignari@users.noreply.github.com> Co-authored-by: wtver <51377408+maattch@users.noreply.github.com> Co-authored-by: Majesty <32709570+majestyotbr@users.noreply.github.com> Co-authored-by: Luan Santos <github@luan.sh>
2023-10-09 23:02:37 -03:00
ASSERT(type.id != 0);
2023-10-09 19:12:16 -07:00
if (type.isOpen == open) {
item = transformItem(item, dt.id, tile);
perfect_match = true;
break;
2023-10-09 19:12:16 -07:00
} else if (!close_match) {
discarded_id = dt.id;
close_match = true;
}
2023-10-09 19:12:16 -07:00
if (!close_match && discarded_id == 0) {
discarded_id = dt.id;
}
}
}
// If we've found no perfect match, use a close-to perfect
2023-10-09 19:12:16 -07:00
if (!perfect_match && discarded_id) {
item = transformItem(item, discarded_id, tile);
}
continue;
}
}
break;
}
// If we get this far in the loop we should return
return;
}
}
//=============================================================================
// Gravel brush
2023-10-09 19:12:16 -07:00
OptionalBorderBrush::OptionalBorderBrush() {
2015-12-06 11:42:37 -03:00
////
}
2023-10-09 19:12:16 -07:00
OptionalBorderBrush::~OptionalBorderBrush() {
2015-12-06 11:42:37 -03:00
////
}
2023-10-09 19:12:16 -07:00
std::string OptionalBorderBrush::getName() const {
return "Optional Border Tool";
}
2023-10-09 19:12:16 -07:00
int OptionalBorderBrush::getLookID() const {
return EDITOR_SPRITE_OPTIONAL_BORDER_TOOL;
}
2023-10-09 19:12:16 -07:00
bool OptionalBorderBrush::canDraw(BaseMap* map, const Position &position) const {
2014-03-01 14:44:11 +01:00
Tile* tile = map->getTile(position);
// You can't do gravel on a mountain tile
2023-10-09 19:12:16 -07:00
if (tile) {
if (GroundBrush* bb = tile->getGroundBrush()) {
if (bb->hasOptionalBorder()) {
return false;
}
}
}
2014-03-01 14:44:11 +01:00
uint32_t x = position.x;
uint32_t y = position.y;
uint32_t z = position.z;
tile = map->getTile(x - 1, y - 1, z);
2023-10-09 19:12:16 -07:00
if (tile) {
if (GroundBrush* bb = tile->getGroundBrush()) {
if (bb->hasOptionalBorder()) {
return true;
}
}
}
tile = map->getTile(x, y - 1, z);
if (tile) {
if (GroundBrush* bb = tile->getGroundBrush()) {
if (bb->hasOptionalBorder()) {
return true;
}
}
}
tile = map->getTile(x + 1, y - 1, z);
2023-10-09 19:12:16 -07:00
if (tile) {
if (GroundBrush* bb = tile->getGroundBrush()) {
if (bb->hasOptionalBorder()) {
return true;
}
}
}
tile = map->getTile(x - 1, y, z);
if (tile) {
if (GroundBrush* bb = tile->getGroundBrush()) {
if (bb->hasOptionalBorder()) {
return true;
}
}
}
tile = map->getTile(x + 1, y, z);
if (tile) {
if (GroundBrush* bb = tile->getGroundBrush()) {
if (bb->hasOptionalBorder()) {
return true;
}
}
}
tile = map->getTile(x - 1, y + 1, z);
2023-10-09 19:12:16 -07:00
if (tile) {
if (GroundBrush* bb = tile->getGroundBrush()) {
if (bb->hasOptionalBorder()) {
return true;
}
}
}
tile = map->getTile(x, y + 1, z);
if (tile) {
if (GroundBrush* bb = tile->getGroundBrush()) {
if (bb->hasOptionalBorder()) {
return true;
}
}
}
tile = map->getTile(x + 1, y + 1, z);
2023-10-09 19:12:16 -07:00
if (tile) {
if (GroundBrush* bb = tile->getGroundBrush()) {
if (bb->hasOptionalBorder()) {
return true;
}
}
}
return false;
}
2023-10-09 19:12:16 -07:00
void OptionalBorderBrush::undraw(BaseMap* map, Tile* tile) {
tile->setOptionalBorder(false); // The bordering algorithm will handle this automagicaly
}
2023-10-09 19:12:16 -07:00
void OptionalBorderBrush::draw(BaseMap* map, Tile* tile, void* parameter) {
tile->setOptionalBorder(true); // The bordering algorithm will handle this automagicaly
}