mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-22 22:13:35 +02:00
Implemented object placement and filtering
This commit is contained in:
parent
c17b1f909d
commit
0fffa846b4
@ -42,6 +42,11 @@ int CMapGenerator::getRandomSeed() const
|
||||
return randomSeed;
|
||||
}
|
||||
|
||||
void CMapGenerator::disableModificator(const std::string & modificator)
|
||||
{
|
||||
disabledModificators.insert(modificator);
|
||||
}
|
||||
|
||||
void CMapGenerator::loadConfig()
|
||||
{
|
||||
static const ResourceID path("config/randomMap.json");
|
||||
@ -137,7 +142,7 @@ std::unique_ptr<CMap> CMapGenerator::generate(bool empty)
|
||||
genZones();
|
||||
Load::Progress::step();
|
||||
map->map().calculateGuardingGreaturePositions(); //clear map so that all tiles are unguarded
|
||||
map->addModificators();
|
||||
map->addModificators(disabledModificators);
|
||||
Load::Progress::step(3);
|
||||
fillZones();
|
||||
//updated guarded tiles will be calculated in CGameState::initMapObjects()
|
||||
|
@ -57,6 +57,7 @@ public:
|
||||
const CMapGenOptions& getMapGenOptions() const;
|
||||
|
||||
std::unique_ptr<CMap> generate(bool emptyMap = false);
|
||||
void disableModificator(const std::string & modificator);
|
||||
|
||||
void findZonesForQuestArts();
|
||||
|
||||
@ -76,6 +77,7 @@ private:
|
||||
CMapGenOptions& mapGenOptions;
|
||||
Config config;
|
||||
std::unique_ptr<RmgMap> map;
|
||||
std::set<std::string> disabledModificators;
|
||||
|
||||
std::vector<rmg::ZoneConnection> connectionsLeft;
|
||||
|
||||
|
@ -108,38 +108,38 @@ void RmgMap::initTiles(CMapGenerator & generator)
|
||||
}
|
||||
}
|
||||
|
||||
void RmgMap::addModificators()
|
||||
void RmgMap::addModificators(const std::set<std::string> & disableModificators)
|
||||
{
|
||||
for(auto & z : getZones())
|
||||
{
|
||||
auto zone = z.second;
|
||||
|
||||
zone->addModificator<ObjectManager>();
|
||||
zone->addModificator<TreasurePlacer>();
|
||||
zone->addModificator<ObstaclePlacer>();
|
||||
zone->addModificator<TerrainPainter>();
|
||||
zone->addModificator<TreasurePlacer>(!disableModificators.count("TreasurePlacer"));
|
||||
zone->addModificator<ObstaclePlacer>(!disableModificators.count("ObstaclePlacer"));
|
||||
zone->addModificator<TerrainPainter>(!disableModificators.count("TerrainPainter"));
|
||||
|
||||
if(zone->getType() == ETemplateZoneType::WATER)
|
||||
{
|
||||
for(auto & z1 : getZones())
|
||||
{
|
||||
z1.second->addModificator<WaterAdopter>();
|
||||
z1.second->addModificator<WaterAdopter>(!disableModificators.count("Water"));
|
||||
z1.second->getModificator<WaterAdopter>()->setWaterZone(zone->getId());
|
||||
}
|
||||
zone->addModificator<WaterProxy>();
|
||||
zone->addModificator<WaterRoutes>();
|
||||
zone->addModificator<WaterProxy>(!disableModificators.count("Water"));
|
||||
zone->addModificator<WaterRoutes>(!disableModificators.count("WaterRoutes") && !disableModificators.count("Water"));
|
||||
}
|
||||
else
|
||||
{
|
||||
zone->addModificator<TownPlacer>();
|
||||
zone->addModificator<ConnectionsPlacer>();
|
||||
zone->addModificator<RoadPlacer>();
|
||||
zone->addModificator<RiverPlacer>();
|
||||
zone->addModificator<ConnectionsPlacer>(!disableModificators.count("ConnectionsPlacer"));
|
||||
zone->addModificator<RoadPlacer>(!disableModificators.count("RoadPlacer"));
|
||||
zone->addModificator<RiverPlacer>(!disableModificators.count("RiverPlacer"));
|
||||
}
|
||||
|
||||
if(zone->isUnderground())
|
||||
{
|
||||
zone->addModificator<RockPlacer>();
|
||||
zone->addModificator<RockPlacer>(!disableModificators.count("RockPlacer"));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ public:
|
||||
ui32 getZoneCount(TFaction faction);
|
||||
ui32 getTotalZoneCount() const;
|
||||
void initTiles(CMapGenerator & generator);
|
||||
void addModificators();
|
||||
void addModificators(const std::set<std::string> & disableModificators);
|
||||
|
||||
bool isAllowedSpell(SpellID sid) const;
|
||||
|
||||
|
@ -304,6 +304,11 @@ Modificator::Modificator(Zone & zone, RmgMap & map, CMapGenerator & generator) :
|
||||
{
|
||||
}
|
||||
|
||||
void Modificator::disable()
|
||||
{
|
||||
enabled = false;
|
||||
}
|
||||
|
||||
void Modificator::setName(const std::string & n)
|
||||
{
|
||||
name = n;
|
||||
@ -333,7 +338,8 @@ void Modificator::run()
|
||||
CStopWatch processTime;
|
||||
try
|
||||
{
|
||||
process();
|
||||
if(enabled)
|
||||
process();
|
||||
}
|
||||
catch(rmgException &e)
|
||||
{
|
||||
|
@ -50,6 +50,8 @@ public:
|
||||
|
||||
void setName(const std::string & n);
|
||||
const std::string & getName() const;
|
||||
|
||||
void disable();
|
||||
|
||||
void run();
|
||||
void dependency(Modificator * modificator);
|
||||
@ -66,6 +68,7 @@ private:
|
||||
std::string name;
|
||||
bool started = false;
|
||||
bool finished = false;
|
||||
bool enabled = true;
|
||||
std::list<Modificator*> preceeders; //must be ordered container
|
||||
void dump();
|
||||
};
|
||||
@ -115,9 +118,11 @@ public:
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void addModificator()
|
||||
void addModificator(bool enabled = true)
|
||||
{
|
||||
modificators.emplace_back(new T(*this, map, generator));
|
||||
if(!enabled)
|
||||
modificators.back()->disable();
|
||||
}
|
||||
|
||||
void initModificators();
|
||||
|
@ -14,6 +14,7 @@ set(editor_SRCS
|
||||
generatorprogress.cpp
|
||||
mapview.cpp
|
||||
radiopushbutton.cpp
|
||||
objectbrowser.cpp
|
||||
)
|
||||
|
||||
set(editor_HEADERS
|
||||
@ -31,6 +32,7 @@ set(editor_HEADERS
|
||||
generatorprogress.h
|
||||
mapview.h
|
||||
radiopushbutton.h
|
||||
objectbrowser.h
|
||||
)
|
||||
|
||||
set(editor_FORMS
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "maphandler.h"
|
||||
#include "graphics.h"
|
||||
#include "windownewmap.h"
|
||||
#include "objectbrowser.h"
|
||||
|
||||
static CBasicLogConfigurator * logConfig;
|
||||
|
||||
@ -91,7 +92,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
}
|
||||
|
||||
//now let's try to draw
|
||||
auto resPath = *CResourceHandler::get()->getResourceName(ResourceID("DATA/new-menu/Background.png"));
|
||||
//auto resPath = *CResourceHandler::get()->getResourceName(ResourceID("DATA/new-menu/Background.png"));
|
||||
|
||||
scenes[0] = new MapScene(this, 0);
|
||||
scenes[1] = new MapScene(this, 1);
|
||||
@ -103,7 +104,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
scenePreview = new QGraphicsScene(this);
|
||||
ui->objectPreview->setScene(scenePreview);
|
||||
|
||||
scenes[0]->addPixmap(QPixmap(QString::fromStdString(resPath.native())));
|
||||
//scenes[0]->addPixmap(QPixmap(QString::fromStdString(resPath.native())));
|
||||
|
||||
//loading objects
|
||||
loadObjectsTree();
|
||||
@ -292,86 +293,241 @@ void MainWindow::terrainButtonClicked(Terrain terrain)
|
||||
scenes[mapLevel]->terrainView.draw();
|
||||
}
|
||||
|
||||
void MainWindow::addGroupIntoCatalog(const std::string & groupName, bool staticOnly)
|
||||
{
|
||||
auto knownObjects = VLC->objtypeh->knownObjects();
|
||||
for(auto ID : knownObjects)
|
||||
{
|
||||
if(catalog.count(ID))
|
||||
continue;
|
||||
|
||||
addGroupIntoCatalog(groupName, staticOnly, ID);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::addGroupIntoCatalog(const std::string & groupName, bool staticOnly, int ID)
|
||||
{
|
||||
QStandardItem * itemGroup = nullptr;
|
||||
auto itms = objectsModel.findItems(QString::fromStdString(groupName));
|
||||
if(itms.empty())
|
||||
{
|
||||
itemGroup = new QStandardItem(QString::fromStdString(groupName));
|
||||
objectsModel.appendRow(itemGroup);
|
||||
}
|
||||
else
|
||||
{
|
||||
itemGroup = itms.front();
|
||||
}
|
||||
|
||||
auto knownSubObjects = VLC->objtypeh->knownSubObjects(ID);
|
||||
bool singleSubObject = knownSubObjects.size() == 1;
|
||||
for(auto secondaryID : knownSubObjects)
|
||||
{
|
||||
auto factory = VLC->objtypeh->getHandlerFor(ID, secondaryID);
|
||||
auto templates = factory->getTemplates();
|
||||
bool singleTemplate = templates.size() == 1;
|
||||
if(staticOnly && !factory->isStaticObject())
|
||||
continue;
|
||||
|
||||
auto * itemType = new QStandardItem(QString::fromStdString(factory->subTypeName));
|
||||
for(int templateId = 0; templateId < templates.size(); ++templateId)
|
||||
{
|
||||
auto templ = templates[templateId];
|
||||
QJsonObject data{{"id", QJsonValue(ID)},
|
||||
{"subid", QJsonValue(secondaryID)},
|
||||
{"template", QJsonValue(templateId)},
|
||||
{"animationEditor", QString::fromStdString(templ.editorAnimationFile)},
|
||||
{"animation", QString::fromStdString(templ.animationFile)}};
|
||||
|
||||
if(singleTemplate)
|
||||
{
|
||||
itemType->setData(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto * item = new QStandardItem(QString::fromStdString(templ.stringID));
|
||||
item->setData(data);
|
||||
itemType->appendRow(item);
|
||||
}
|
||||
}
|
||||
itemGroup->appendRow(itemType);
|
||||
catalog.insert(ID);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::loadObjectsTree()
|
||||
{
|
||||
ui->terrainFilterCombo->addItem("");
|
||||
//adding terrains
|
||||
for(auto & terrain : Terrain::Manager::terrains())
|
||||
{
|
||||
QPushButton *b = new QPushButton(QString::fromStdString(terrain));
|
||||
ui->terrainLayout->addWidget(b);
|
||||
connect(b, &QPushButton::clicked, this, [this, terrain]{ terrainButtonClicked(terrain); });
|
||||
|
||||
//filter
|
||||
ui->terrainFilterCombo->addItem(QString::fromStdString(terrain));
|
||||
}
|
||||
|
||||
//add spacer to keep terrain button on the top
|
||||
ui->terrainLayout->addItem(new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding));
|
||||
|
||||
if(objectBrowser)
|
||||
throw std::runtime_error("object browser exists");
|
||||
|
||||
//model
|
||||
objectsModel.setHorizontalHeaderLabels(QStringList() << QStringLiteral("Type"));
|
||||
|
||||
//adding towns
|
||||
auto * itemGroup = new QStandardItem("TOWNS");
|
||||
for(auto secondaryID : VLC->objtypeh->knownSubObjects(Obj::TOWN))
|
||||
{
|
||||
auto factory = VLC->objtypeh->getHandlerFor(Obj::TOWN, secondaryID);
|
||||
auto * itemType = new QStandardItem(QString::fromStdString(factory->subTypeName));
|
||||
for(int templateId = 0; templateId < factory->getTemplates().size(); ++templateId)
|
||||
{
|
||||
auto templ = factory->getTemplates()[templateId];
|
||||
auto * item = new QStandardItem(QString::fromStdString(templ.stringID));
|
||||
QJsonObject data{{"id", QJsonValue(Obj::TOWN)},
|
||||
{"subid", QJsonValue(secondaryID)},
|
||||
{"animationEditor", QString::fromStdString(templ.editorAnimationFile)},
|
||||
{"animation", QString::fromStdString(templ.animationFile)}};
|
||||
item->setData(data);
|
||||
itemType->appendRow(item);
|
||||
}
|
||||
itemGroup->appendRow(itemType);
|
||||
}
|
||||
objectsModel.appendRow(itemGroup);
|
||||
|
||||
|
||||
/*
|
||||
createHandler(bth, "Bonus type", pomtime);
|
||||
createHandler(generaltexth, "General text", pomtime);
|
||||
createHandler(heroh, "Hero", pomtime);
|
||||
createHandler(arth, "Artifact", pomtime);
|
||||
createHandler(creh, "Creature", pomtime);
|
||||
createHandler(townh, "Town", pomtime);
|
||||
createHandler(objh, "Object", pomtime);
|
||||
createHandler(objtypeh, "Object types information", pomtime);
|
||||
createHandler(spellh, "Spell", pomtime);
|
||||
createHandler(skillh, "Skill", pomtime);
|
||||
createHandler(terviewh, "Terrain view pattern", pomtime);
|
||||
createHandler(tplh, "Template", pomtime); //templates need already resolved identifiers (refactor?)
|
||||
createHandler(scriptHandler, "Script", pomtime);
|
||||
createHandler(battlefieldsHandler, "Battlefields", pomtime);
|
||||
createHandler(obstacleHandler, "Obstacles", pomtime);*/
|
||||
|
||||
//for(auto primaryID : VLC->objtypeh->knownObjects())
|
||||
{
|
||||
//QList<QStandardItem*> objTypes;
|
||||
|
||||
//for(auto secondaryID : VLC->objtypeh->knownSubObjects(primaryID))
|
||||
{
|
||||
//QList<QStandardItem*> objSubTypes;
|
||||
//auto handler = VLC->objtypeh->getHandlerFor(primaryID, secondaryID);
|
||||
|
||||
/*if(handler->isStaticObject())
|
||||
{
|
||||
for(auto temp : handler->getTemplates())
|
||||
{
|
||||
|
||||
}
|
||||
}*/
|
||||
|
||||
//identifiers[handler->typeName].push_back(handler->subTypeName);
|
||||
}
|
||||
}
|
||||
|
||||
ui->treeView->setModel(&objectsModel);
|
||||
objectBrowser = new ObjectBrowser(this);
|
||||
objectBrowser->setSourceModel(&objectsModel);
|
||||
objectBrowser->setDynamicSortFilter(false);
|
||||
objectBrowser->setRecursiveFilteringEnabled(true);
|
||||
ui->treeView->setModel(objectBrowser);
|
||||
ui->treeView->setSelectionBehavior(QAbstractItemView::SelectItems);
|
||||
ui->treeView->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
connect(ui->treeView->selectionModel(), SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)), this, SLOT(treeViewSelected(const QModelIndex &, const QModelIndex &)));
|
||||
|
||||
|
||||
//adding objects
|
||||
addGroupIntoCatalog("TOWNS", false, Obj::TOWN);
|
||||
addGroupIntoCatalog("TOWNS", false, Obj::RANDOM_TOWN);
|
||||
addGroupIntoCatalog("TOWNS", false, Obj::SHIPYARD);
|
||||
addGroupIntoCatalog("TOWNS", false, Obj::GARRISON);
|
||||
addGroupIntoCatalog("TOWNS", false, Obj::GARRISON2);
|
||||
addGroupIntoCatalog("MISC", false, Obj::ALTAR_OF_SACRIFICE);
|
||||
addGroupIntoCatalog("MISC", false, Obj::ARENA);
|
||||
addGroupIntoCatalog("MISC", false, Obj::BLACK_MARKET);
|
||||
addGroupIntoCatalog("MISC", false, Obj::BORDERGUARD);
|
||||
addGroupIntoCatalog("MISC", false, Obj::KEYMASTER);
|
||||
addGroupIntoCatalog("MISC", false, Obj::BUOY);
|
||||
addGroupIntoCatalog("MISC", false, Obj::CAMPFIRE);
|
||||
addGroupIntoCatalog("MISC", false, Obj::CARTOGRAPHER);
|
||||
addGroupIntoCatalog("MISC", false, Obj::SWAN_POND);
|
||||
addGroupIntoCatalog("MISC", false, Obj::COVER_OF_DARKNESS);
|
||||
addGroupIntoCatalog("MISC", false, Obj::CORPSE);
|
||||
addGroupIntoCatalog("MISC", false, Obj::MARLETTO_TOWER);
|
||||
addGroupIntoCatalog("MISC", false, Obj::DERELICT_SHIP);
|
||||
addGroupIntoCatalog("MISC", false, Obj::DRAGON_UTOPIA);
|
||||
addGroupIntoCatalog("MISC", false, Obj::FAERIE_RING);
|
||||
addGroupIntoCatalog("MISC", false, Obj::FLOTSAM);
|
||||
addGroupIntoCatalog("MISC", false, Obj::FOUNTAIN_OF_FORTUNE);
|
||||
addGroupIntoCatalog("MISC", false, Obj::FOUNTAIN_OF_YOUTH);
|
||||
addGroupIntoCatalog("MISC", false, Obj::GARDEN_OF_REVELATION);
|
||||
addGroupIntoCatalog("MISC", false, Obj::HILL_FORT);
|
||||
addGroupIntoCatalog("MISC", false, Obj::IDOL_OF_FORTUNE);
|
||||
addGroupIntoCatalog("MISC", false, Obj::LIBRARY_OF_ENLIGHTENMENT);
|
||||
addGroupIntoCatalog("MISC", false, Obj::LIGHTHOUSE);
|
||||
addGroupIntoCatalog("MISC", false, Obj::SCHOOL_OF_MAGIC);
|
||||
addGroupIntoCatalog("MISC", false, Obj::MAGIC_SPRING);
|
||||
addGroupIntoCatalog("MISC", false, Obj::MAGIC_WELL);
|
||||
addGroupIntoCatalog("MISC", false, Obj::MERCENARY_CAMP);
|
||||
addGroupIntoCatalog("MISC", false, Obj::MERMAID);
|
||||
addGroupIntoCatalog("MISC", false, Obj::MYSTICAL_GARDEN);
|
||||
addGroupIntoCatalog("MISC", false, Obj::OASIS);
|
||||
addGroupIntoCatalog("MISC", false, Obj::OBELISK);
|
||||
addGroupIntoCatalog("MISC", false, Obj::REDWOOD_OBSERVATORY);
|
||||
addGroupIntoCatalog("MISC", false, Obj::OCEAN_BOTTLE);
|
||||
addGroupIntoCatalog("MISC", false, Obj::PILLAR_OF_FIRE);
|
||||
addGroupIntoCatalog("MISC", false, Obj::STAR_AXIS);
|
||||
addGroupIntoCatalog("MISC", false, Obj::RALLY_FLAG);
|
||||
addGroupIntoCatalog("MISC", false, Obj::LEAN_TO);
|
||||
addGroupIntoCatalog("MISC", false, Obj::WATERING_HOLE);
|
||||
addGroupIntoCatalog("PRISON", false, Obj::PRISON);
|
||||
addGroupIntoCatalog("ARTIFACTS", false, Obj::ARTIFACT);
|
||||
addGroupIntoCatalog("ARTIFACTS", false, Obj::RANDOM_ART);
|
||||
addGroupIntoCatalog("ARTIFACTS", false, Obj::RANDOM_TREASURE_ART);
|
||||
addGroupIntoCatalog("ARTIFACTS", false, Obj::RANDOM_MINOR_ART);
|
||||
addGroupIntoCatalog("ARTIFACTS", false, Obj::RANDOM_MAJOR_ART);
|
||||
addGroupIntoCatalog("ARTIFACTS", false, Obj::RANDOM_RELIC_ART);
|
||||
addGroupIntoCatalog("RESOURCES", false, Obj::PANDORAS_BOX);
|
||||
addGroupIntoCatalog("RESOURCES", false, Obj::RANDOM_RESOURCE);
|
||||
addGroupIntoCatalog("RESOURCES", false, Obj::RESOURCE);
|
||||
addGroupIntoCatalog("RESOURCES", false, Obj::SEA_CHEST);
|
||||
addGroupIntoCatalog("RESOURCES", false, Obj::TREASURE_CHEST);
|
||||
addGroupIntoCatalog("RESOURCES", false, Obj::SPELL_SCROLL);
|
||||
addGroupIntoCatalog("BANKS", false, Obj::CREATURE_BANK);
|
||||
addGroupIntoCatalog("DWELLINGS", false, Obj::CREATURE_GENERATOR1);
|
||||
addGroupIntoCatalog("DWELLINGS", false, Obj::CREATURE_GENERATOR2);
|
||||
addGroupIntoCatalog("DWELLINGS", false, Obj::CREATURE_GENERATOR3);
|
||||
addGroupIntoCatalog("DWELLINGS", false, Obj::CREATURE_GENERATOR4);
|
||||
addGroupIntoCatalog("DWELLINGS", false, Obj::RANDOM_DWELLING);
|
||||
addGroupIntoCatalog("DWELLINGS", false, Obj::RANDOM_DWELLING_LVL);
|
||||
addGroupIntoCatalog("DWELLINGS", false, Obj::RANDOM_DWELLING_FACTION);
|
||||
addGroupIntoCatalog("GROUNDS", false, Obj::CURSED_GROUND1);
|
||||
addGroupIntoCatalog("GROUNDS", false, Obj::MAGIC_PLAINS1);
|
||||
addGroupIntoCatalog("GROUNDS", false, Obj::CLOVER_FIELD);
|
||||
addGroupIntoCatalog("GROUNDS", false, Obj::CURSED_GROUND2);
|
||||
addGroupIntoCatalog("GROUNDS", false, Obj::EVIL_FOG);
|
||||
addGroupIntoCatalog("GROUNDS", false, Obj::FAVORABLE_WINDS);
|
||||
addGroupIntoCatalog("GROUNDS", false, Obj::FIERY_FIELDS);
|
||||
addGroupIntoCatalog("GROUNDS", false, Obj::HOLY_GROUNDS);
|
||||
addGroupIntoCatalog("GROUNDS", false, Obj::LUCID_POOLS);
|
||||
addGroupIntoCatalog("GROUNDS", false, Obj::MAGIC_CLOUDS);
|
||||
addGroupIntoCatalog("GROUNDS", false, Obj::MAGIC_PLAINS2);
|
||||
addGroupIntoCatalog("GROUNDS", false, Obj::ROCKLANDS);
|
||||
addGroupIntoCatalog("TELEPORTS", false, Obj::MONOLITH_ONE_WAY_ENTRANCE);
|
||||
addGroupIntoCatalog("TELEPORTS", false, Obj::MONOLITH_ONE_WAY_EXIT);
|
||||
addGroupIntoCatalog("TELEPORTS", false, Obj::MONOLITH_TWO_WAY);
|
||||
addGroupIntoCatalog("TELEPORTS", false, Obj::SUBTERRANEAN_GATE);
|
||||
addGroupIntoCatalog("TELEPORTS", false, Obj::WHIRLPOOL);
|
||||
addGroupIntoCatalog("MINES", false, Obj::MINE);
|
||||
addGroupIntoCatalog("MINES", false, Obj::ABANDONED_MINE);
|
||||
addGroupIntoCatalog("MINES", false, Obj::WINDMILL);
|
||||
addGroupIntoCatalog("MINES", false, Obj::WATER_WHEEL);
|
||||
addGroupIntoCatalog("TRIGGERS", false, Obj::EVENT);
|
||||
addGroupIntoCatalog("TRIGGERS", false, Obj::GRAIL);
|
||||
addGroupIntoCatalog("TRIGGERS", false, Obj::SIGN);
|
||||
addGroupIntoCatalog("MONSTERS", false, Obj::MONSTER);
|
||||
addGroupIntoCatalog("MONSTERS", false, Obj::RANDOM_MONSTER);
|
||||
addGroupIntoCatalog("MONSTERS", false, Obj::RANDOM_MONSTER_L1);
|
||||
addGroupIntoCatalog("MONSTERS", false, Obj::RANDOM_MONSTER_L2);
|
||||
addGroupIntoCatalog("MONSTERS", false, Obj::RANDOM_MONSTER_L3);
|
||||
addGroupIntoCatalog("MONSTERS", false, Obj::RANDOM_MONSTER_L4);
|
||||
addGroupIntoCatalog("MONSTERS", false, Obj::RANDOM_MONSTER_L5);
|
||||
addGroupIntoCatalog("MONSTERS", false, Obj::RANDOM_MONSTER_L6);
|
||||
addGroupIntoCatalog("MONSTERS", false, Obj::RANDOM_MONSTER_L7);
|
||||
addGroupIntoCatalog("QUESTS", false, Obj::SEER_HUT);
|
||||
addGroupIntoCatalog("QUESTS", false, Obj::BORDER_GATE);
|
||||
addGroupIntoCatalog("QUESTS", false, Obj::QUEST_GUARD);
|
||||
addGroupIntoCatalog("QUESTS", false, Obj::HUT_OF_MAGI);
|
||||
addGroupIntoCatalog("QUESTS", false, Obj::EYE_OF_MAGI);
|
||||
addGroupIntoCatalog("OBSTACLES", true);
|
||||
addGroupIntoCatalog("OTHER", false);
|
||||
|
||||
|
||||
/*
|
||||
HERO = 34,
|
||||
LEAN_TO = 39,
|
||||
PYRAMID = 63,//subtype 0
|
||||
WOG_OBJECT = 63,//subtype > 0
|
||||
RANDOM_HERO = 70,
|
||||
REFUGEE_CAMP = 78,
|
||||
SANCTUARY = 80,
|
||||
SCHOLAR = 81,
|
||||
CRYPT = 84,
|
||||
SHIPWRECK = 85,
|
||||
SHIPWRECK_SURVIVOR = 86,
|
||||
SHRINE_OF_MAGIC_INCANTATION = 88,
|
||||
SHRINE_OF_MAGIC_GESTURE = 89,
|
||||
SHRINE_OF_MAGIC_THOUGHT = 90,
|
||||
SIRENS = 92,
|
||||
STABLES = 94,
|
||||
TAVERN = 95,
|
||||
TEMPLE = 96,
|
||||
DEN_OF_THIEVES = 97,
|
||||
TRADING_POST = 99,
|
||||
LEARNING_STONE = 100,
|
||||
TREE_OF_KNOWLEDGE = 102,
|
||||
UNIVERSITY = 104,
|
||||
WAGON = 105,
|
||||
WAR_MACHINE_FACTORY = 106,
|
||||
SCHOOL_OF_WAR = 107,
|
||||
WARRIORS_TOMB = 108,
|
||||
WITCH_HUT = 113,
|
||||
HOLE = 124,
|
||||
FREELANCERS_GUILD = 213,
|
||||
HERO_PLACEHOLDER = 214,
|
||||
TRADING_POST_SNOW = 221,
|
||||
*/
|
||||
}
|
||||
|
||||
void MainWindow::on_actionLevel_triggered()
|
||||
@ -400,8 +556,6 @@ void MainWindow::on_actionGrid_triggered(bool checked)
|
||||
scenes[0]->gridView.show(checked);
|
||||
scenes[1]->gridView.show(checked);
|
||||
}
|
||||
|
||||
auto idx = ui->treeView->selectionModel()->currentIndex();
|
||||
}
|
||||
|
||||
|
||||
@ -453,34 +607,48 @@ void MainWindow::on_toolErase_clicked()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::treeViewSelected(const QModelIndex & index, const QModelIndex & deselected)
|
||||
void MainWindow::preparePreview(const QModelIndex &index, bool createNew)
|
||||
{
|
||||
objPreview.fill(QColor(255, 255, 255));
|
||||
auto * item = objectsModel.itemFromIndex(index);
|
||||
if(item)
|
||||
auto data = objectsModel.itemFromIndex(objectBrowser->mapToSource(index))->data().toJsonObject();
|
||||
|
||||
if(!data.empty())
|
||||
{
|
||||
auto data = item->data().toJsonObject();
|
||||
|
||||
if(!data.empty())
|
||||
auto animfile = data["animationEditor"];
|
||||
if(animfile != QJsonValue::Undefined)
|
||||
{
|
||||
auto animfile = data["animationEditor"];
|
||||
if(animfile != QJsonValue::Undefined)
|
||||
{
|
||||
if(animfile.toString().isEmpty())
|
||||
animfile = data["animation"];
|
||||
if(animfile.toString().isEmpty())
|
||||
animfile = data["animation"];
|
||||
|
||||
QPainter painter(&objPreview);
|
||||
Animation animation(animfile.toString().toStdString());
|
||||
animation.preload();
|
||||
auto picture = animation.getImage(0);
|
||||
if(picture && picture->width() && picture->height())
|
||||
{
|
||||
qreal xscale = qreal(128) / qreal(picture->width()), yscale = qreal(128) / qreal(picture->height());
|
||||
qreal scale = std::min(xscale, yscale);
|
||||
painter.scale(scale, scale);
|
||||
painter.drawImage(QPoint(0, 0), *picture);
|
||||
}
|
||||
QPainter painter(&objPreview);
|
||||
Animation animation(animfile.toString().toStdString());
|
||||
animation.preload();
|
||||
auto picture = animation.getImage(0);
|
||||
if(picture && picture->width() && picture->height())
|
||||
{
|
||||
qreal xscale = qreal(128) / qreal(picture->width()), yscale = qreal(128) / qreal(picture->height());
|
||||
qreal scale = std::min(xscale, yscale);
|
||||
painter.scale(scale, scale);
|
||||
painter.drawImage(QPoint(0, 0), *picture);
|
||||
}
|
||||
|
||||
auto objId = data["id"].toInt();
|
||||
auto objSubId = data["subid"].toInt();
|
||||
auto templateId = data["template"].toInt();
|
||||
|
||||
scenes[mapLevel]->selectionObjectsView.clear();
|
||||
if(scenes[mapLevel]->selectionObjectsView.newObject)
|
||||
{
|
||||
createNew = true;
|
||||
delete scenes[mapLevel]->selectionObjectsView.newObject;
|
||||
}
|
||||
|
||||
if(createNew)
|
||||
{
|
||||
auto factory = VLC->objtypeh->getHandlerFor(objId, objSubId);
|
||||
auto templ = factory->getTemplates()[templateId];
|
||||
scenes[mapLevel]->selectionObjectsView.newObject = factory->create(templ);
|
||||
scenes[mapLevel]->selectionObjectsView.draw();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -489,3 +657,44 @@ void MainWindow::treeViewSelected(const QModelIndex & index, const QModelIndex &
|
||||
scenePreview->addPixmap(objPreview);
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::treeViewSelected(const QModelIndex & index, const QModelIndex & deselected)
|
||||
{
|
||||
preparePreview(index, false);
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_treeView_activated(const QModelIndex &index)
|
||||
{
|
||||
ui->toolBrush->setChecked(false);
|
||||
ui->toolBrush2->setChecked(false);
|
||||
ui->toolBrush4->setChecked(false);
|
||||
ui->toolArea->setChecked(false);
|
||||
ui->toolLasso->setChecked(false);
|
||||
ui->mapView->selectionTool = MapView::SelectionTool::None;
|
||||
|
||||
preparePreview(index, true);
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_terrainFilterCombo_currentTextChanged(const QString &arg1)
|
||||
{
|
||||
if(!objectBrowser)
|
||||
return;
|
||||
|
||||
objectBrowser->terrain = arg1.isEmpty() ? Terrain::ANY : Terrain(arg1.toStdString());
|
||||
objectBrowser->invalidate();
|
||||
objectBrowser->sort(0);
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_filter_textChanged(const QString &arg1)
|
||||
{
|
||||
if(!objectBrowser)
|
||||
return;
|
||||
|
||||
objectBrowser->filter = arg1;
|
||||
objectBrowser->invalidate();
|
||||
objectBrowser->sort(0);
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "mapview.h"
|
||||
|
||||
class CMap;
|
||||
class ObjectBrowser;
|
||||
|
||||
namespace Ui {
|
||||
class MainWindow;
|
||||
@ -38,6 +39,8 @@ public:
|
||||
|
||||
MapView * getMapView();
|
||||
|
||||
int getMapLevel() const {return mapLevel;}
|
||||
|
||||
private slots:
|
||||
void on_actionOpen_triggered();
|
||||
|
||||
@ -61,13 +64,24 @@ private slots:
|
||||
|
||||
void on_toolErase_clicked();
|
||||
|
||||
void on_treeView_activated(const QModelIndex &index);
|
||||
|
||||
void on_terrainFilterCombo_currentTextChanged(const QString &arg1);
|
||||
|
||||
void on_filter_textChanged(const QString &arg1);
|
||||
|
||||
public slots:
|
||||
|
||||
void treeViewSelected(const QModelIndex &selected, const QModelIndex &deselected);
|
||||
|
||||
private:
|
||||
void preparePreview(const QModelIndex &index, bool createNew);
|
||||
void addGroupIntoCatalog(const std::string & groupName, bool staticOnly);
|
||||
void addGroupIntoCatalog(const std::string & groupName, bool staticOnly, int ID);
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
|
||||
ObjectBrowser * objectBrowser = nullptr;
|
||||
std::unique_ptr<MapHandler> mapHandler;
|
||||
std::array<MapScene *, 2> scenes;
|
||||
QGraphicsScene * sceneMini;
|
||||
@ -82,6 +96,8 @@ private:
|
||||
QStandardItemModel objectsModel;
|
||||
|
||||
int mapLevel = 0;
|
||||
|
||||
std::set<int> catalog;
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
|
@ -35,6 +35,9 @@
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="mouseTracking">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QAbstractScrollArea::AdjustToContents</enum>
|
||||
</property>
|
||||
@ -88,7 +91,7 @@
|
||||
</widget>
|
||||
<widget class="QDockWidget" name="dockWidget_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
@ -161,7 +164,7 @@
|
||||
</widget>
|
||||
<widget class="QDockWidget" name="dockWidget_3">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
@ -169,7 +172,7 @@
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>192</width>
|
||||
<height>183</height>
|
||||
<height>196</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
@ -223,6 +226,9 @@
|
||||
<string>Objects</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
@ -245,6 +251,9 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="filter"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTreeView" name="treeView">
|
||||
<property name="sizePolicy">
|
||||
@ -253,12 +262,21 @@
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="mouseTracking">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
<property name="dragDropMode">
|
||||
<enum>QAbstractItemView::NoDragDrop</enum>
|
||||
</property>
|
||||
<property name="selectionBehavior">
|
||||
<enum>QAbstractItemView::SelectItems</enum>
|
||||
</property>
|
||||
<property name="sortingEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="headerHidden">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
|
@ -97,6 +97,53 @@ void MapHandler::drawTerrainTile(QPainter & painter, int x, int y, int z)
|
||||
painter.drawImage(x * tileSize, y * tileSize, terrainImages.at(tinfo.terType)[tinfo.terView]->mirrored(hflip, vflip));
|
||||
}
|
||||
|
||||
void MapHandler::drawRoad(QPainter & painter, int x, int y, int z)
|
||||
{
|
||||
auto & tinfo = map->getTile(int3(x, y, z));
|
||||
auto * tinfoUpper = map->isInTheMap(int3(x, y - 1, z)) ? &map->getTile(int3(x, y - 1, z)) : nullptr;
|
||||
|
||||
/*if(tinfoUpper && tinfoUpper->roadType != ROAD_NAMES[0])
|
||||
{
|
||||
ui8 rotation = (tinfoUpper->extTileFlags >> 4) % 4;
|
||||
|
||||
bool hflip = (rotation == 1 || rotation == 3), vflip = (rotation == 2 || rotation == 3);
|
||||
|
||||
if(roadImages.at(tinfoUpper->roadType).size() > tinfoUpper->roadDir)
|
||||
{
|
||||
painter.drawImage(x * tileSize, y * tileSize, roadImages.at(tinfoUpper->roadType)[tinfoUpper->roadDir]->mirrored(hflip, vflip));
|
||||
}
|
||||
}*/
|
||||
|
||||
if(tinfo.roadType != ROAD_NAMES[0]) //print road from this tile
|
||||
{
|
||||
ui8 rotation = (tinfo.extTileFlags >> 4) % 4;
|
||||
|
||||
bool hflip = (rotation == 1 || rotation == 3), vflip = (rotation == 2 || rotation == 3);
|
||||
|
||||
if(roadImages.at(tinfo.roadType).size() > tinfo.roadDir)
|
||||
{
|
||||
painter.drawImage(x * tileSize, y * tileSize, roadImages.at(tinfo.roadType)[tinfo.roadDir]->mirrored(hflip, vflip));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MapHandler::drawRiver(QPainter & painter, int x, int y, int z)
|
||||
{
|
||||
auto & tinfo = map->getTile(int3(x, y, z));
|
||||
|
||||
if(tinfo.riverType == RIVER_NAMES[0])
|
||||
return;
|
||||
|
||||
if(riverImages.at(tinfo.riverType).size() <= tinfo.riverDir)
|
||||
return;
|
||||
|
||||
ui8 rotation = (tinfo.extTileFlags >> 2) % 4;
|
||||
|
||||
bool hflip = (rotation == 1 || rotation == 3), vflip = (rotation == 2 || rotation == 3);
|
||||
|
||||
painter.drawImage(x * tileSize, y * tileSize, riverImages.at(tinfo.riverType)[tinfo.riverDir]->mirrored(hflip, vflip));
|
||||
}
|
||||
|
||||
void MapHandler::initObjectRects()
|
||||
{
|
||||
//initializing objects / rects
|
||||
|
@ -88,9 +88,9 @@ public:
|
||||
|
||||
void drawTerrainTile(QPainter & painter, int x, int y, int z);
|
||||
/// draws a river segment on current tile
|
||||
//void drawRiver(const TerrainTile & tinfo) const;
|
||||
void drawRiver(QPainter & painter, int x, int y, int z);
|
||||
/// draws a road segment on current tile
|
||||
//void drawRoad(const TerrainTile & tinfo, const TerrainTile * tinfoUpper) const;
|
||||
void drawRoad(QPainter & painter, int x, int y, int z);
|
||||
/// draws all objects on current tile (higher-level logic, unlike other draw*** methods)
|
||||
void drawObjects(QPainter & painter, int x, int y, int z);
|
||||
void drawObject(QPainter & painter, const TerrainTileObject & object);
|
||||
|
@ -37,14 +37,17 @@ void MapView::mouseMoveEvent(QMouseEvent *mouseEvent)
|
||||
switch(selectionTool)
|
||||
{
|
||||
case MapView::SelectionTool::Brush:
|
||||
if(pressedOnSelected)
|
||||
if(mouseEvent->buttons() & Qt::RightButton)
|
||||
sc->selectionTerrainView.erase(tile);
|
||||
else
|
||||
else if(mouseEvent->buttons() == Qt::LeftButton)
|
||||
sc->selectionTerrainView.select(tile);
|
||||
sc->selectionTerrainView.draw();
|
||||
break;
|
||||
|
||||
case MapView::SelectionTool::Area:
|
||||
if(mouseEvent->buttons() & Qt::RightButton)
|
||||
break;
|
||||
|
||||
sc->selectionTerrainView.clear();
|
||||
for(int j = std::min(tile.y, tileStart.y); j < std::max(tile.y, tileStart.y); ++j)
|
||||
{
|
||||
@ -57,8 +60,18 @@ void MapView::mouseMoveEvent(QMouseEvent *mouseEvent)
|
||||
break;
|
||||
|
||||
case MapView::SelectionTool::None:
|
||||
if(mouseEvent->buttons() & Qt::RightButton)
|
||||
break;
|
||||
|
||||
auto sh = tile - tileStart;
|
||||
sc->selectionObjectsView.shift = QPoint(sh.x, sh.y);
|
||||
|
||||
if((sh.x || sh.y) && sc->selectionObjectsView.newObject)
|
||||
{
|
||||
sc->selectionObjectsView.shift = QPoint(tile.x, tile.y);
|
||||
sc->selectionObjectsView.selectObject(sc->selectionObjectsView.newObject);
|
||||
}
|
||||
|
||||
sc->selectionObjectsView.draw();
|
||||
break;
|
||||
}
|
||||
@ -85,14 +98,18 @@ void MapView::mousePressEvent(QMouseEvent *event)
|
||||
case MapView::SelectionTool::Brush:
|
||||
sc->selectionObjectsView.clear();
|
||||
sc->selectionObjectsView.draw();
|
||||
if(pressedOnSelected)
|
||||
|
||||
if(event->button() == Qt::RightButton)
|
||||
sc->selectionTerrainView.erase(tileStart);
|
||||
else
|
||||
else if(event->button() == Qt::LeftButton)
|
||||
sc->selectionTerrainView.select(tileStart);
|
||||
sc->selectionTerrainView.draw();
|
||||
break;
|
||||
|
||||
case MapView::SelectionTool::Area:
|
||||
if(event->button() == Qt::RightButton)
|
||||
break;
|
||||
|
||||
sc->selectionTerrainView.clear();
|
||||
sc->selectionTerrainView.draw();
|
||||
sc->selectionObjectsView.clear();
|
||||
@ -102,9 +119,18 @@ void MapView::mousePressEvent(QMouseEvent *event)
|
||||
case MapView::SelectionTool::None:
|
||||
sc->selectionTerrainView.clear();
|
||||
sc->selectionTerrainView.draw();
|
||||
sc->selectionObjectsView.clear();
|
||||
sc->selectionObjectsView.selectObjectAt(tileStart.x, tileStart.y);
|
||||
sc->selectionObjectsView.draw();
|
||||
|
||||
if(sc->selectionObjectsView.newObject && sc->selectionObjectsView.isSelected(sc->selectionObjectsView.newObject))
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
sc->selectionObjectsView.clear();
|
||||
if(event->button() == Qt::LeftButton)
|
||||
sc->selectionObjectsView.selectObjectAt(tileStart.x, tileStart.y);
|
||||
sc->selectionObjectsView.draw();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -119,12 +145,24 @@ void MapView::mouseReleaseEvent(QMouseEvent *event)
|
||||
if(!sc)
|
||||
return;
|
||||
|
||||
if(sc->selectionObjectsView.newObject)
|
||||
{
|
||||
if(!sc->selectionObjectsView.isSelected(sc->selectionObjectsView.newObject) || event->button() == Qt::RightButton)
|
||||
{
|
||||
delete sc->selectionObjectsView.newObject;
|
||||
sc->selectionObjectsView.newObject = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
switch(selectionTool)
|
||||
{
|
||||
case MapView::SelectionTool::None:
|
||||
if(event->button() == Qt::RightButton)
|
||||
break;
|
||||
//switch position
|
||||
if(sc->selectionObjectsView.applyShift())
|
||||
{
|
||||
sc->selectionObjectsView.newObject = nullptr;
|
||||
main->resetMapHandler();
|
||||
sc->updateViews();
|
||||
}
|
||||
@ -406,14 +444,24 @@ void TerrainView::draw(bool onlyDirty)
|
||||
}
|
||||
for(auto & t : forRedrawing)
|
||||
{
|
||||
//TODO: fix water and roads
|
||||
main->getMapHandler()->drawTerrainTile(painter, t.x, t.y, scene->level);
|
||||
//main->getMapHandler()->drawRiver(painter, t.x, t.y, scene->level);
|
||||
//main->getMapHandler()->drawRoad(painter, t.x, t.y, scene->level);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int j = 0; j < map->height; ++j)
|
||||
{
|
||||
for(int i = 0; i < map->width; ++i)
|
||||
{
|
||||
//TODO: fix water and roads
|
||||
main->getMapHandler()->drawTerrainTile(painter, i, j, scene->level);
|
||||
//main->getMapHandler()->drawRiver(painter, i, j, scene->level);
|
||||
//main->getMapHandler()->drawRoad(painter, i, j, scene->level);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dirty.clear();
|
||||
@ -489,7 +537,7 @@ void ObjectsView::setDirty(const CGObjectInstance * object)
|
||||
dirty.insert(object);
|
||||
}
|
||||
|
||||
SelectionObjectsView::SelectionObjectsView(MainWindow * m, MapScene * s): BasicView(m, s)
|
||||
SelectionObjectsView::SelectionObjectsView(MainWindow * m, MapScene * s): BasicView(m, s), newObject(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
@ -501,6 +549,9 @@ void SelectionObjectsView::update()
|
||||
|
||||
selectedObjects.clear();
|
||||
shift = QPoint();
|
||||
if(newObject)
|
||||
delete newObject;
|
||||
newObject = nullptr;
|
||||
|
||||
pixmap.reset(new QPixmap(map->width * 32, map->height * 32));
|
||||
//pixmap->fill(QColor(0, 0, 0, 0));
|
||||
@ -521,17 +572,20 @@ void SelectionObjectsView::draw()
|
||||
|
||||
for(auto * obj : selectedObjects)
|
||||
{
|
||||
QRect bbox(obj->getPosition().x, obj->getPosition().y, 1, 1);
|
||||
for(auto & t : obj->getBlockedPos())
|
||||
if(obj != newObject)
|
||||
{
|
||||
QPoint topLeft(std::min(t.x, bbox.topLeft().x()), std::min(t.y, bbox.topLeft().y()));
|
||||
bbox.setTopLeft(topLeft);
|
||||
QPoint bottomRight(std::max(t.x, bbox.bottomRight().x()), std::max(t.y, bbox.bottomRight().y()));
|
||||
bbox.setBottomRight(bottomRight);
|
||||
}
|
||||
QRect bbox(obj->getPosition().x, obj->getPosition().y, 1, 1);
|
||||
for(auto & t : obj->getBlockedPos())
|
||||
{
|
||||
QPoint topLeft(std::min(t.x, bbox.topLeft().x()), std::min(t.y, bbox.topLeft().y()));
|
||||
bbox.setTopLeft(topLeft);
|
||||
QPoint bottomRight(std::max(t.x, bbox.bottomRight().x()), std::max(t.y, bbox.bottomRight().y()));
|
||||
bbox.setBottomRight(bottomRight);
|
||||
}
|
||||
|
||||
painter.setOpacity(1.0);
|
||||
painter.drawRect(bbox.x() * 32, bbox.y() * 32, bbox.width() * 32, bbox.height() * 32);
|
||||
painter.setOpacity(1.0);
|
||||
painter.drawRect(bbox.x() * 32, bbox.y() * 32, bbox.width() * 32, bbox.height() * 32);
|
||||
}
|
||||
|
||||
//show translation
|
||||
if(shift.x() || shift.y())
|
||||
@ -601,8 +655,18 @@ bool SelectionObjectsView::applyShift()
|
||||
for(auto * obj : selectedObjects)
|
||||
{
|
||||
int3 pos = obj->pos;
|
||||
pos.z = main->getMapLevel();
|
||||
pos.x += shift.x(); pos.y += shift.y();
|
||||
main->getMap()->getEditManager()->moveObject(obj, pos);
|
||||
|
||||
if(obj == newObject)
|
||||
{
|
||||
newObject->pos = pos;
|
||||
main->getMap()->getEditManager()->insertObject(newObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
main->getMap()->getEditManager()->moveObject(obj, pos);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -614,6 +678,7 @@ void SelectionObjectsView::deleteSelection()
|
||||
for(auto * obj : selectedObjects)
|
||||
{
|
||||
main->getMap()->getEditManager()->removeObject(obj);
|
||||
delete obj;
|
||||
}
|
||||
clear();
|
||||
}
|
||||
@ -625,6 +690,16 @@ std::set<CGObjectInstance *> SelectionObjectsView::selectObjects(int x1, int y1,
|
||||
return result;
|
||||
}
|
||||
|
||||
void SelectionObjectsView::selectObject(CGObjectInstance * obj)
|
||||
{
|
||||
selectedObjects.insert(obj);
|
||||
}
|
||||
|
||||
bool SelectionObjectsView::isSelected(const CGObjectInstance * obj) const
|
||||
{
|
||||
return selectedObjects.count(const_cast<CGObjectInstance*>(obj));
|
||||
}
|
||||
|
||||
void SelectionObjectsView::clear()
|
||||
{
|
||||
selectedObjects.clear();
|
||||
|
@ -136,6 +136,8 @@ public:
|
||||
|
||||
CGObjectInstance * selectObjectAt(int x, int y);
|
||||
std::set<CGObjectInstance *> selectObjects(int x1, int y1, int x2, int y2);
|
||||
void selectObject(CGObjectInstance *);
|
||||
bool isSelected(const CGObjectInstance *) const;
|
||||
void moveSelection(int x, int y);
|
||||
void clear();
|
||||
|
||||
@ -143,6 +145,7 @@ public:
|
||||
void deleteSelection();
|
||||
|
||||
QPoint shift;
|
||||
CGObjectInstance * newObject;
|
||||
|
||||
private:
|
||||
std::set<CGObjectInstance *> selectedObjects;
|
||||
|
87
mapeditor/objectbrowser.cpp
Normal file
87
mapeditor/objectbrowser.cpp
Normal file
@ -0,0 +1,87 @@
|
||||
#include "objectbrowser.h"
|
||||
#include "../lib/mapObjects/CObjectClassesHandler.h"
|
||||
|
||||
ObjectBrowser::ObjectBrowser(QObject *parent)
|
||||
: QSortFilterProxyModel{parent}, terrain(Terrain::ANY)
|
||||
{
|
||||
}
|
||||
|
||||
bool ObjectBrowser::filterAcceptsRow(int source_row, const QModelIndex & source_parent) const
|
||||
{
|
||||
bool result = QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
|
||||
|
||||
QModelIndex currentIndex = sourceModel()->index(source_row, 0, source_parent);
|
||||
int childCount = currentIndex.model()->rowCount(currentIndex);
|
||||
if(childCount)
|
||||
return false;
|
||||
|
||||
auto item = dynamic_cast<QStandardItemModel*>(sourceModel())->itemFromIndex(currentIndex);
|
||||
if(!item)
|
||||
return result;
|
||||
|
||||
if(!filterAcceptsRowText(source_row, source_parent))
|
||||
return false;
|
||||
|
||||
if(terrain == Terrain::ANY)
|
||||
return result;
|
||||
|
||||
auto data = item->data().toJsonObject();
|
||||
if(data.empty())
|
||||
return result;
|
||||
|
||||
auto objIdJson = data["id"];
|
||||
if(objIdJson == QJsonValue::Undefined)
|
||||
return result;
|
||||
|
||||
auto objId = data["id"].toInt();
|
||||
auto objSubId = data["subid"].toInt();
|
||||
auto templateId = data["template"].toInt();
|
||||
|
||||
auto factory = VLC->objtypeh->getHandlerFor(objId, objSubId);
|
||||
auto templ = factory->getTemplates()[templateId];
|
||||
|
||||
result = result & templ.canBePlacedAt(terrain);
|
||||
|
||||
//text filter
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool ObjectBrowser::filterAcceptsRowText(int source_row, const QModelIndex &source_parent) const
|
||||
{
|
||||
if(source_parent.isValid())
|
||||
{
|
||||
if(filterAcceptsRowText(source_parent.row(), source_parent.parent()))
|
||||
return true;
|
||||
}
|
||||
|
||||
QModelIndex index = sourceModel()->index(source_row, 0 ,source_parent);
|
||||
if(!index.isValid())
|
||||
return false;
|
||||
|
||||
auto item = dynamic_cast<QStandardItemModel*>(sourceModel())->itemFromIndex(index);
|
||||
if(!item)
|
||||
return false;
|
||||
|
||||
return (filter.isNull() || filter.isEmpty() || item->text().contains(filter, Qt::CaseInsensitive));
|
||||
}
|
||||
|
||||
/*bool ObjectBrowser::filterAcceptsRowItself(int source_row, const QModelIndex & source_parent) const
|
||||
{
|
||||
//accept if any of the parents is accepted on it's own merits
|
||||
QModelIndex parent = source_parent;
|
||||
while(parent.isValid())
|
||||
{
|
||||
if (filterAcceptsRowItself(parent.row(), parent.parent()))
|
||||
return true;
|
||||
parent = parent.parent();
|
||||
}
|
||||
|
||||
//accept if any of the children is accepted on it's own merits
|
||||
if (hasAcceptedChildren(source_row, source_parent))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}*/
|
20
mapeditor/objectbrowser.h
Normal file
20
mapeditor/objectbrowser.h
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef OBJECTBROWSER_H
|
||||
#define OBJECTBROWSER_H
|
||||
|
||||
#include <QSortFilterProxyModel>
|
||||
#include "../lib/Terrain.h"
|
||||
|
||||
class ObjectBrowser : public QSortFilterProxyModel
|
||||
{
|
||||
public:
|
||||
explicit ObjectBrowser(QObject *parent = nullptr);
|
||||
|
||||
Terrain terrain;
|
||||
QString filter;
|
||||
|
||||
protected:
|
||||
bool filterAcceptsRow(int source_row, const QModelIndex & source_parent) const override;
|
||||
bool filterAcceptsRowText(int source_row, const QModelIndex &source_parent) const;
|
||||
};
|
||||
|
||||
#endif // OBJECTBROWSER_H
|
@ -70,6 +70,10 @@ void WindowNewMap::on_okButtong_clicked()
|
||||
mapGenOptions.setMonsterStrength(monster);
|
||||
CMapGenerator generator(mapGenOptions);
|
||||
|
||||
//TODO: fix water and roads
|
||||
generator.disableModificator("RoadPlacer");
|
||||
generator.disableModificator("RiverPlacer");
|
||||
|
||||
auto progressBarWnd = new GeneratorProgress(generator, this);
|
||||
progressBarWnd->show();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user