1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00
vcmi/mapeditor/inspector/inspector.cpp

953 lines
27 KiB
C++
Raw Normal View History

2022-10-08 22:32:02 +02:00
/*
* inspector.cpp, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
2022-09-18 01:23:17 +02:00
#include "StdInc.h"
#include "inspector.h"
2023-05-17 16:05:09 +02:00
#include "../lib/ArtifactUtils.h"
2022-09-18 01:23:17 +02:00
#include "../lib/CArtHandler.h"
#include "../lib/entities/hero/CHeroClass.h"
#include "../lib/entities/hero/CHeroHandler.h"
2022-09-18 01:23:17 +02:00
#include "../lib/spells/CSpellHandler.h"
#include "../lib/CRandomGenerator.h"
#include "../lib/mapObjectConstructors/AObjectTypeHandler.h"
#include "../lib/mapObjectConstructors/CObjectClassesHandler.h"
#include "../lib/mapObjects/ObjectTemplate.h"
2022-09-18 01:23:17 +02:00
#include "../lib/mapping/CMap.h"
2023-09-10 22:05:57 +02:00
#include "../lib/constants/StringConstants.h"
2022-09-18 01:23:17 +02:00
#include "townbuildingswidget.h"
#include "towneventswidget.h"
#include "townspellswidget.h"
2022-09-18 01:23:17 +02:00
#include "armywidget.h"
#include "messagewidget.h"
#include "rewardswidget.h"
2022-10-16 23:16:27 +02:00
#include "questwidget.h"
2023-09-10 23:39:54 +02:00
#include "heroskillswidget.h"
#include "herospellwidget.h"
2023-10-13 20:15:11 +02:00
#include "portraitwidget.h"
#include "PickObjectDelegate.h"
#include "../mapcontroller.h"
2022-09-18 01:23:17 +02:00
2023-09-10 22:05:57 +02:00
static QList<std::pair<QString, QVariant>> CharacterIdentifiers
{
{QObject::tr("Compliant"), QVariant::fromValue(int(CGCreature::Character::COMPLIANT))},
{QObject::tr("Friendly"), QVariant::fromValue(int(CGCreature::Character::FRIENDLY))},
2023-10-17 22:06:08 +02:00
{QObject::tr("Aggressive"), QVariant::fromValue(int(CGCreature::Character::AGGRESSIVE))},
2023-09-10 22:05:57 +02:00
{QObject::tr("Hostile"), QVariant::fromValue(int(CGCreature::Character::HOSTILE))},
{QObject::tr("Savage"), QVariant::fromValue(int(CGCreature::Character::SAVAGE))},
};
2022-09-18 01:23:17 +02:00
//===============IMPLEMENT OBJECT INITIALIZATION FUNCTIONS================
Initializer::Initializer(CGObjectInstance * o, const PlayerColor & pl) : defaultPlayer(pl)
{
logGlobal->info("New object instance initialized");
///IMPORTANT! initialize order should be from base objects to derived objects
INIT_OBJ_TYPE(CGResource);
INIT_OBJ_TYPE(CGArtifact);
INIT_OBJ_TYPE(CArmedInstance);
INIT_OBJ_TYPE(CGShipyard);
INIT_OBJ_TYPE(CGGarrison);
INIT_OBJ_TYPE(CGMine);
INIT_OBJ_TYPE(CGDwelling);
INIT_OBJ_TYPE(CGTownInstance);
INIT_OBJ_TYPE(CGCreature);
2023-10-16 22:24:12 +02:00
INIT_OBJ_TYPE(CGHeroPlaceholder);
2022-09-18 01:23:17 +02:00
INIT_OBJ_TYPE(CGHeroInstance);
INIT_OBJ_TYPE(CGSignBottle);
INIT_OBJ_TYPE(FlaggableMapObject);
2023-09-16 05:34:27 +02:00
//INIT_OBJ_TYPE(CRewardableObject);
2022-09-18 01:23:17 +02:00
//INIT_OBJ_TYPE(CGPandoraBox);
2022-10-16 01:20:24 +02:00
//INIT_OBJ_TYPE(CGEvent);
//INIT_OBJ_TYPE(CGSeerHut);
2022-09-18 01:23:17 +02:00
}
void Initializer::initialize(CArmedInstance * o)
{
if(!o) return;
}
void Initializer::initialize(CGSignBottle * o)
{
if(!o) return;
}
void Initializer::initialize(CGCreature * o)
{
if(!o) return;
o->character = CGCreature::Character::HOSTILE;
2022-12-04 23:32:50 +02:00
if(!o->hasStackAtSlot(SlotID(0)))
o->putStack(SlotID(0), new CStackInstance(CreatureID(o->subID), 0, false));
2022-09-18 01:23:17 +02:00
}
void Initializer::initialize(CGDwelling * o)
{
if(!o) return;
o->tempOwner = defaultPlayer;
}
void Initializer::initialize(CGGarrison * o)
{
if(!o) return;
o->tempOwner = defaultPlayer;
o->removableUnits = true;
}
void Initializer::initialize(CGShipyard * o)
{
if(!o) return;
o->tempOwner = defaultPlayer;
}
void Initializer::initialize(FlaggableMapObject * o)
2022-09-18 01:23:17 +02:00
{
if(!o) return;
o->tempOwner = defaultPlayer;
}
2023-10-16 22:24:12 +02:00
void Initializer::initialize(CGHeroPlaceholder * o)
{
if(!o) return;
o->tempOwner = defaultPlayer;
2023-10-16 22:24:12 +02:00
if(!o->powerRank.has_value() && !o->heroType.has_value())
o->powerRank = 0;
if(o->powerRank.has_value() && o->heroType.has_value())
o->powerRank.reset();
}
2022-09-18 01:23:17 +02:00
void Initializer::initialize(CGHeroInstance * o)
{
if(!o)
return;
2022-09-18 01:23:17 +02:00
o->tempOwner = defaultPlayer;
2022-09-24 22:55:05 +02:00
if(o->ID == Obj::PRISON)
2023-09-03 23:38:55 +02:00
{
o->subID = 0;
2022-09-24 22:55:05 +02:00
o->tempOwner = PlayerColor::NEUTRAL;
2023-09-03 23:38:55 +02:00
}
if(o->ID == Obj::HERO)
{
for(auto const & t : VLC->heroh->objects)
{
if(t->heroClass->getId() == HeroClassID(o->subID))
{
o->subID = t->getId();
break;
}
}
}
if(o->getHeroTypeID().hasValue())
2023-09-10 16:57:41 +02:00
{
o->gender = o->getHeroType()->gender;
o->randomizeArmy(o->getFactionID());
2023-09-10 16:57:41 +02:00
}
2022-09-18 01:23:17 +02:00
}
void Initializer::initialize(CGTownInstance * o)
{
if(!o) return;
const std::vector<std::string> castleLevels{"village", "fort", "citadel", "castle", "capitol"};
int lvl = vstd::find_pos(castleLevels, o->appearance->stringID);
o->addBuilding(BuildingID::DEFAULT);
if(lvl > -1) o->addBuilding(BuildingID::TAVERN);
if(lvl > 0) o->addBuilding(BuildingID::FORT);
if(lvl > 1) o->addBuilding(BuildingID::CITADEL);
if(lvl > 2) o->addBuilding(BuildingID::CASTLE);
if(lvl > 3) o->addBuilding(BuildingID::CAPITOL);
2022-09-18 01:23:17 +02:00
if(o->possibleSpells.empty())
2022-09-18 01:23:17 +02:00
{
for(auto const & spellId : VLC->spellh->getDefaultAllowed()) //add all regular spells to town
{
o->possibleSpells.push_back(spellId);
}
2022-09-18 01:23:17 +02:00
}
}
void Initializer::initialize(CGArtifact * o)
{
if(!o) return;
if(o->ID == Obj::SPELL_SCROLL)
{
std::vector<SpellID> out;
for(auto const & spell : VLC->spellh->objects) //spellh size appears to be greater (?)
2022-09-18 01:23:17 +02:00
{
if(VLC->spellh->getDefaultAllowed().count(spell->id) != 0)
2022-09-18 01:23:17 +02:00
{
out.push_back(spell->id);
}
}
2023-05-17 16:05:09 +02:00
auto a = ArtifactUtils::createScroll(*RandomGeneratorUtil::nextItem(out, CRandomGenerator::getDefault()));
2022-09-18 01:23:17 +02:00
o->storedArtifact = a;
}
}
void Initializer::initialize(CGMine * o)
{
if(!o) return;
o->tempOwner = defaultPlayer;
2023-09-03 21:41:57 +02:00
if(o->isAbandoned())
{
for(auto r = GameResID(0); r < GameResID::COUNT; ++r)
o->abandonedMineResources.insert(r);
}
else
{
o->producedResource = GameResID(o->subID);
o->producedQuantity = o->defaultResProduction();
}
2022-09-18 01:23:17 +02:00
}
void Initializer::initialize(CGResource * o)
{
if(!o) return;
o->amount = CGResource::RANDOM_AMOUNT;
}
//===============IMPLEMENT PROPERTIES SETUP===============================
void Inspector::updateProperties(CArmedInstance * o)
{
if(!o) return;
auto * delegate = new ArmyDelegate(*o);
addProperty("Army", PropertyEditorPlaceholder(), delegate, false);
}
void Inspector::updateProperties(CGDwelling * o)
{
if(!o) return;
2024-02-29 23:11:28 +02:00
addProperty("Owner", o->tempOwner, new OwnerDelegate(controller), false);
2023-11-01 16:10:33 +02:00
if (o->ID == Obj::RANDOM_DWELLING || o->ID == Obj::RANDOM_DWELLING_LVL)
{
auto * delegate = new PickObjectDelegate(controller, PickObjectDelegate::typedFilter<CGTownInstance>);
addProperty("Same as town", PropertyEditorPlaceholder(), delegate, false);
}
2022-09-18 01:23:17 +02:00
}
void Inspector::updateProperties(FlaggableMapObject * o)
2022-09-18 01:23:17 +02:00
{
if(!o) return;
2024-02-29 23:11:28 +02:00
addProperty("Owner", o->tempOwner, new OwnerDelegate(controller), false);
2022-09-18 01:23:17 +02:00
}
void Inspector::updateProperties(CGGarrison * o)
{
if(!o) return;
2024-02-29 23:11:28 +02:00
addProperty("Owner", o->tempOwner, new OwnerDelegate(controller), false);
2023-09-10 18:10:50 +02:00
addProperty("Removable units", o->removableUnits, false);
2022-09-18 01:23:17 +02:00
}
void Inspector::updateProperties(CGShipyard * o)
{
if(!o) return;
2024-02-29 23:11:28 +02:00
addProperty("Owner", o->tempOwner, new OwnerDelegate(controller), false);
2022-09-18 01:23:17 +02:00
}
2023-10-16 22:24:12 +02:00
void Inspector::updateProperties(CGHeroPlaceholder * o)
{
if(!o) return;
2024-02-29 23:11:28 +02:00
addProperty("Owner", o->tempOwner, new OwnerDelegate(controller), false);
2023-10-16 22:24:12 +02:00
bool type = false;
if(o->heroType.has_value())
type = true;
else if(!o->powerRank.has_value())
assert(0); //one of values must be initialized
{
auto * delegate = new InspectorDelegate;
delegate->options = {{"POWER RANK", QVariant::fromValue(false)}, {"HERO TYPE", QVariant::fromValue(true)}};
addProperty("Placeholder type", delegate->options[type].first, delegate, false);
}
addProperty("Power rank", o->powerRank.has_value() ? o->powerRank.value() : 0, type);
{
auto * delegate = new InspectorDelegate;
for(int i = 0; i < VLC->heroh->objects.size(); ++i)
{
delegate->options.push_back({QObject::tr(VLC->heroh->objects[i]->getNameTranslated().c_str()), QVariant::fromValue(VLC->heroh->objects[i]->getId().getNum())});
}
addProperty("Hero type", o->heroType.has_value() ? VLC->heroh->getById(o->heroType.value())->getNameTranslated() : "", delegate, !type);
}
}
2022-09-18 01:23:17 +02:00
void Inspector::updateProperties(CGHeroInstance * o)
{
if(!o) return;
auto isPrison = o->ID == Obj::PRISON;
addProperty("Owner", o->tempOwner, new OwnerDelegate(controller, isPrison), isPrison); //field is not editable for prison
2022-09-18 01:23:17 +02:00
addProperty<int>("Experience", o->exp, false);
addProperty("Hero class", o->getHeroClassID().hasValue() ? o->getHeroClass()->getNameTranslated() : "", true);
2022-09-18 01:23:17 +02:00
2023-09-10 22:05:57 +02:00
{ //Gender
2022-09-18 01:23:17 +02:00
auto * delegate = new InspectorDelegate;
2023-09-10 22:05:57 +02:00
delegate->options = {{"MALE", QVariant::fromValue(int(EHeroGender::MALE))}, {"FEMALE", QVariant::fromValue(int(EHeroGender::FEMALE))}};
addProperty<std::string>("Gender", (o->gender == EHeroGender::FEMALE ? "FEMALE" : "MALE"), delegate , false);
2022-09-18 01:23:17 +02:00
}
2023-09-28 14:03:58 +02:00
addProperty("Name", o->getNameTranslated(), false);
addProperty("Biography", o->getBiographyTranslated(), new MessageDelegate, false);
2023-10-13 20:15:11 +02:00
addProperty("Portrait", PropertyEditorPlaceholder(), new PortraitDelegate(*o), false);
2022-09-18 01:23:17 +02:00
2023-09-10 23:39:54 +02:00
auto * delegate = new HeroSkillsDelegate(*o);
addProperty("Skills", PropertyEditorPlaceholder(), delegate, false);
addProperty("Spells", PropertyEditorPlaceholder(), new HeroSpellDelegate(*o), false);
2023-09-10 23:39:54 +02:00
if(o->getHeroTypeID().hasValue() || o->ID == Obj::PRISON)
2022-10-16 01:20:24 +02:00
{ //Hero type
2022-09-18 01:23:17 +02:00
auto * delegate = new InspectorDelegate;
for(const auto & heroPtr : VLC->heroh->objects)
2022-09-18 01:23:17 +02:00
{
if(controller.map()->allowedHeroes.count(heroPtr->getId()) != 0)
2022-09-18 01:23:17 +02:00
{
if(o->ID == Obj::PRISON || heroPtr->heroClass->getIndex() == o->getHeroClassID())
2023-09-10 22:05:57 +02:00
{
delegate->options.push_back({QObject::tr(heroPtr->getNameTranslated().c_str()), QVariant::fromValue(heroPtr->getIndex())});
2023-09-10 22:05:57 +02:00
}
2022-09-18 01:23:17 +02:00
}
}
addProperty("Hero type", o->getHeroTypeID().hasValue() ? o->getHeroType()->getNameTranslated() : "", delegate, false);
2022-09-18 01:23:17 +02:00
}
{
const int maxRadius = 60;
auto * patrolDelegate = new InspectorDelegate;
patrolDelegate->options = { {QObject::tr("No patrol"), QVariant::fromValue(CGHeroInstance::NO_PATROLLING)} };
for(int i = 0; i <= maxRadius; ++i)
2024-10-29 22:22:10 +02:00
patrolDelegate->options.push_back({ QObject::tr("%n tile(s)", "", i), QVariant::fromValue(i)});
auto patrolRadiusText = o->patrol.patrolling ? QObject::tr("%n tile(s)", "", o->patrol.patrolRadius) : QObject::tr("No patrol");
addProperty("Patrol radius", patrolRadiusText, patrolDelegate, false);
}
2022-09-18 01:23:17 +02:00
}
void Inspector::updateProperties(CGTownInstance * o)
{
if(!o) return;
addProperty("Town name", o->getNameTranslated(), false);
2022-09-18 01:23:17 +02:00
auto * delegate = new TownBuildingsDelegate(*o);
addProperty("Buildings", PropertyEditorPlaceholder(), delegate, false);
addProperty("Spells", PropertyEditorPlaceholder(), new TownSpellsDelegate(*o), false);
addProperty("Events", PropertyEditorPlaceholder(), new TownEventsDelegate(*o, controller), false);
2022-09-18 01:23:17 +02:00
}
void Inspector::updateProperties(CGArtifact * o)
{
if(!o) return;
addProperty("Message", o->message, false);
CArtifactInstance * instance = o->storedArtifact;
if(instance)
{
2023-04-13 19:40:36 +02:00
SpellID spellId = instance->getScrollSpellID();
if(spellId != SpellID::NONE)
2022-09-18 01:23:17 +02:00
{
auto * delegate = new InspectorDelegate;
for(auto const & spell : VLC->spellh->objects)
2022-09-18 01:23:17 +02:00
{
if(controller.map()->allowedSpells.count(spell->id) != 0)
2023-09-10 22:05:57 +02:00
delegate->options.push_back({QObject::tr(spell->getNameTranslated().c_str()), QVariant::fromValue(int(spell->getId()))});
2022-09-18 01:23:17 +02:00
}
2023-09-04 01:33:01 +02:00
addProperty("Spell", VLC->spellh->getById(spellId)->getNameTranslated(), delegate, false);
2022-09-18 01:23:17 +02:00
}
}
}
void Inspector::updateProperties(CGMine * o)
{
if(!o) return;
2024-02-29 23:11:28 +02:00
addProperty("Owner", o->tempOwner, new OwnerDelegate(controller), false);
2022-09-18 01:23:17 +02:00
addProperty("Resource", o->producedResource);
addProperty("Productivity", o->producedQuantity);
2022-09-18 01:23:17 +02:00
}
void Inspector::updateProperties(CGResource * o)
{
if(!o) return;
addProperty("Amount", o->amount, false);
addProperty("Message", o->message, false);
}
void Inspector::updateProperties(CGSignBottle * o)
{
if(!o) return;
addProperty("Message", o->message, new MessageDelegate, false);
}
void Inspector::updateProperties(CGCreature * o)
{
if(!o) return;
addProperty("Message", o->message, false);
2022-10-16 01:20:24 +02:00
{ //Character
2022-09-18 01:23:17 +02:00
auto * delegate = new InspectorDelegate;
2023-09-10 22:05:57 +02:00
delegate->options = CharacterIdentifiers;
2022-09-18 01:23:17 +02:00
addProperty<CGCreature::Character>("Character", (CGCreature::Character)o->character, delegate, false);
}
2023-09-10 18:10:50 +02:00
addProperty("Never flees", o->neverFlees, false);
addProperty("Not growing", o->notGrowingTeam, false);
2022-09-18 01:23:17 +02:00
addProperty("Artifact reward", o->gainedArtifact); //TODO: implement in setProperty
addProperty("Army", PropertyEditorPlaceholder(), true);
addProperty("Amount", o->stacks[SlotID(0)]->count, false);
//addProperty("Resources reward", o->resources); //TODO: implement in setProperty
}
2023-09-16 05:34:27 +02:00
void Inspector::updateProperties(CRewardableObject * o)
{
if(!o) return;
auto * delegate = new RewardsDelegate(*controller.map(), *o);
2023-09-16 05:34:27 +02:00
addProperty("Reward", PropertyEditorPlaceholder(), delegate, false);
}
2022-09-18 01:23:17 +02:00
void Inspector::updateProperties(CGPandoraBox * o)
{
if(!o) return;
2022-09-20 00:38:10 +02:00
addProperty("Message", o->message, new MessageDelegate, false);
2022-09-18 01:23:17 +02:00
}
void Inspector::updateProperties(CGEvent * o)
{
if(!o) return;
2023-09-10 18:10:50 +02:00
addProperty("Remove after", o->removeAfterVisit, false);
addProperty("Human trigger", o->humanActivate, false);
addProperty("Cpu trigger", o->computerActivate, false);
2022-09-18 01:23:17 +02:00
//ui8 availableFor; //players whom this event is available for
}
2022-10-16 01:20:24 +02:00
void Inspector::updateProperties(CGSeerHut * o)
{
2023-10-09 15:54:14 +02:00
if(!o || !o->quest) return;
2022-10-16 01:20:24 +02:00
addProperty("First visit text", o->quest->firstVisitText, new MessageDelegate, false);
addProperty("Next visit text", o->quest->nextVisitText, new MessageDelegate, false);
addProperty("Completed text", o->quest->completedText, new MessageDelegate, false);
2023-10-09 15:54:14 +02:00
addProperty("Repeat quest", o->quest->repeatedQuest, false);
2023-10-10 01:53:25 +02:00
addProperty("Time limit", o->quest->lastDay, false);
2022-10-16 01:20:24 +02:00
2022-10-16 23:16:27 +02:00
{ //Quest
2023-10-09 15:54:14 +02:00
auto * delegate = new QuestDelegate(controller, *o->quest);
2022-10-16 23:16:27 +02:00
addProperty("Quest", PropertyEditorPlaceholder(), delegate, false);
}
2022-10-16 01:20:24 +02:00
}
2022-09-18 01:23:17 +02:00
2023-10-11 23:28:10 +02:00
void Inspector::updateProperties(CGQuestGuard * o)
{
if(!o || !o->quest) return;
addProperty("Reward", PropertyEditorPlaceholder(), nullptr, true);
addProperty("Repeat quest", o->quest->repeatedQuest, true);
}
2022-09-18 01:23:17 +02:00
void Inspector::updateProperties()
{
if(!obj)
return;
table->setRowCount(0); //cleanup table
addProperty("Identifier", obj);
2022-09-18 01:23:17 +02:00
addProperty("ID", obj->ID.getNum());
addProperty("SubID", obj->subID);
addProperty("InstanceName", obj->instanceName);
2024-08-24 13:34:22 +02:00
if(obj->ID != Obj::HERO_PLACEHOLDER && !dynamic_cast<CGHeroInstance*>(obj))
2022-09-18 01:23:17 +02:00
{
auto factory = VLC->objtypeh->getHandlerFor(obj->ID, obj->subID);
addProperty("IsStatic", factory->isStaticObject());
}
2024-02-29 23:11:28 +02:00
addProperty("Owner", obj->tempOwner, new OwnerDelegate(controller), true);
2022-09-18 01:23:17 +02:00
UPDATE_OBJ_PROPERTIES(CArmedInstance);
UPDATE_OBJ_PROPERTIES(CGResource);
UPDATE_OBJ_PROPERTIES(CGArtifact);
UPDATE_OBJ_PROPERTIES(CGMine);
UPDATE_OBJ_PROPERTIES(CGGarrison);
UPDATE_OBJ_PROPERTIES(CGShipyard);
UPDATE_OBJ_PROPERTIES(CGDwelling);
UPDATE_OBJ_PROPERTIES(CGTownInstance);
UPDATE_OBJ_PROPERTIES(CGCreature);
2023-10-16 22:24:12 +02:00
UPDATE_OBJ_PROPERTIES(CGHeroPlaceholder);
2022-09-18 01:23:17 +02:00
UPDATE_OBJ_PROPERTIES(CGHeroInstance);
UPDATE_OBJ_PROPERTIES(CGSignBottle);
UPDATE_OBJ_PROPERTIES(FlaggableMapObject);
2023-09-16 05:34:27 +02:00
UPDATE_OBJ_PROPERTIES(CRewardableObject);
2022-09-18 01:23:17 +02:00
UPDATE_OBJ_PROPERTIES(CGPandoraBox);
UPDATE_OBJ_PROPERTIES(CGEvent);
2022-10-16 01:20:24 +02:00
UPDATE_OBJ_PROPERTIES(CGSeerHut);
2023-10-11 23:28:10 +02:00
UPDATE_OBJ_PROPERTIES(CGQuestGuard);
2022-09-18 01:23:17 +02:00
table->show();
}
//===============IMPLEMENT PROPERTY UPDATE================================
2023-09-10 22:05:57 +02:00
void Inspector::setProperty(const QString & key, const QTableWidgetItem * item)
{
if(!item->data(Qt::UserRole).isNull())
{
setProperty(key, item->data(Qt::UserRole));
return;
}
if(item->flags() & Qt::ItemIsUserCheckable)
{
setProperty(key, QVariant::fromValue(item->checkState() == Qt::Checked));
return;
}
setProperty(key, item->text());
}
2022-09-18 01:23:17 +02:00
void Inspector::setProperty(const QString & key, const QVariant & value)
{
if(!obj)
return;
if(key == "Owner")
2023-09-10 22:05:57 +02:00
obj->tempOwner = PlayerColor(value.toInt());
2022-09-18 01:23:17 +02:00
SET_PROPERTIES(CArmedInstance);
SET_PROPERTIES(CGTownInstance);
SET_PROPERTIES(CGArtifact);
SET_PROPERTIES(CGMine);
SET_PROPERTIES(CGResource);
SET_PROPERTIES(CGDwelling);
SET_PROPERTIES(CGGarrison);
SET_PROPERTIES(CGCreature);
2023-10-16 22:24:12 +02:00
SET_PROPERTIES(CGHeroPlaceholder);
2022-09-18 01:23:17 +02:00
SET_PROPERTIES(CGHeroInstance);
SET_PROPERTIES(CGShipyard);
SET_PROPERTIES(CGSignBottle);
SET_PROPERTIES(FlaggableMapObject);
2023-09-16 05:34:27 +02:00
SET_PROPERTIES(CRewardableObject);
2022-09-18 01:23:17 +02:00
SET_PROPERTIES(CGPandoraBox);
SET_PROPERTIES(CGEvent);
2022-10-16 01:20:24 +02:00
SET_PROPERTIES(CGSeerHut);
2023-10-11 23:28:10 +02:00
SET_PROPERTIES(CGQuestGuard);
2022-09-18 01:23:17 +02:00
}
void Inspector::setProperty(CArmedInstance * o, const QString & key, const QVariant & value)
{
if(!o) return;
}
void Inspector::setProperty(FlaggableMapObject * o, const QString & key, const QVariant & value)
2022-09-18 01:23:17 +02:00
{
if(!o) return;
}
2023-09-16 05:34:27 +02:00
void Inspector::setProperty(CRewardableObject * o, const QString & key, const QVariant & value)
{
if(!o) return;
}
2022-09-18 01:23:17 +02:00
void Inspector::setProperty(CGPandoraBox * o, const QString & key, const QVariant & value)
{
if(!o) return;
if(key == "Message")
2023-10-10 01:20:55 +02:00
o->message = MetaString::createFromTextID(mapRegisterLocalizedString("map", *controller.map(),
TextIdentifier("guards", o->instanceName, "message"), value.toString().toStdString()));
2022-09-18 01:23:17 +02:00
}
void Inspector::setProperty(CGEvent * o, const QString & key, const QVariant & value)
{
if(!o) return;
2022-09-24 22:55:05 +02:00
if(key == "Remove after")
2023-09-10 18:10:50 +02:00
o->removeAfterVisit = value.toBool();
2022-09-18 01:23:17 +02:00
2022-09-24 22:55:05 +02:00
if(key == "Human trigger")
2023-09-10 18:10:50 +02:00
o->humanActivate = value.toBool();
2022-09-18 01:23:17 +02:00
2022-09-24 22:55:05 +02:00
if(key == "Cpu trigger")
2023-09-10 18:10:50 +02:00
o->computerActivate = value.toBool();
2022-09-18 01:23:17 +02:00
}
void Inspector::setProperty(CGTownInstance * o, const QString & key, const QVariant & value)
{
if(!o) return;
if(key == "Town name")
2023-10-10 01:20:55 +02:00
o->setNameTextId(mapRegisterLocalizedString("map", *controller.map(),
TextIdentifier("town", o->instanceName, "name"), value.toString().toStdString()));
2022-09-18 01:23:17 +02:00
}
void Inspector::setProperty(CGSignBottle * o, const QString & key, const QVariant & value)
{
if(!o) return;
if(key == "Message")
2023-10-10 01:20:55 +02:00
o->message = MetaString::createFromTextID(mapRegisterLocalizedString("map", *controller.map(),
TextIdentifier("sign", o->instanceName, "message"), value.toString().toStdString()));
2022-09-18 01:23:17 +02:00
}
void Inspector::setProperty(CGMine * o, const QString & key, const QVariant & value)
{
if(!o) return;
if(key == "Productivity")
o->producedQuantity = value.toString().toInt();
}
void Inspector::setProperty(CGArtifact * o, const QString & key, const QVariant & value)
{
if(!o) return;
if(key == "Message")
2023-10-10 01:20:55 +02:00
o->message = MetaString::createFromTextID(mapRegisterLocalizedString("map", *controller.map(),
TextIdentifier("guards", o->instanceName, "message"), value.toString().toStdString()));
2022-09-18 01:23:17 +02:00
if(o->storedArtifact && key == "Spell")
{
2023-09-10 22:05:57 +02:00
o->storedArtifact = ArtifactUtils::createScroll(SpellID(value.toInt()));
2022-09-18 01:23:17 +02:00
}
}
void Inspector::setProperty(CGDwelling * o, const QString & key, const QVariant & value)
{
if(!o) return;
if(key == "Same as town")
{
2023-10-25 20:56:00 +02:00
if (!o->randomizationInfo.has_value())
o->randomizationInfo = CGDwellingRandomizationInfo();
o->randomizationInfo->instanceId = "";
if(CGTownInstance * town = data_cast<CGTownInstance>(value.toLongLong()))
o->randomizationInfo->instanceId = town->instanceName;
}
2022-09-18 01:23:17 +02:00
}
void Inspector::setProperty(CGGarrison * o, const QString & key, const QVariant & value)
{
if(!o) return;
if(key == "Removable units")
2023-09-10 18:10:50 +02:00
o->removableUnits = value.toBool();
2022-09-18 01:23:17 +02:00
}
2023-10-16 22:24:12 +02:00
void Inspector::setProperty(CGHeroPlaceholder * o, const QString & key, const QVariant & value)
{
if(!o) return;
if(key == "Placeholder type")
{
if(value.toBool())
{
if(!o->heroType.has_value())
o->heroType = HeroTypeID(0);
o->powerRank.reset();
}
else
{
if(!o->powerRank.has_value())
o->powerRank = 0;
o->heroType.reset();
}
updateProperties();
}
if(key == "Power rank")
o->powerRank = value.toInt();
if(key == "Hero type")
{
o->heroType = HeroTypeID(value.toInt());
2023-10-16 22:24:12 +02:00
}
}
2022-09-18 01:23:17 +02:00
void Inspector::setProperty(CGHeroInstance * o, const QString & key, const QVariant & value)
{
if(!o) return;
if(key == "Gender")
2023-09-10 22:05:57 +02:00
o->gender = EHeroGender(value.toInt());
2022-09-18 01:23:17 +02:00
if(key == "Name")
2023-10-10 01:20:55 +02:00
o->nameCustomTextId = mapRegisterLocalizedString("map", *controller.map(),
TextIdentifier("hero", o->instanceName, "name"), value.toString().toStdString());
2023-09-28 14:03:58 +02:00
if(key == "Biography")
2023-10-10 01:20:55 +02:00
o->biographyCustomTextId = mapRegisterLocalizedString("map", *controller.map(),
TextIdentifier("hero", o->instanceName, "biography"), value.toString().toStdString());
2022-09-18 01:23:17 +02:00
2022-12-04 14:58:30 +02:00
if(key == "Experience")
2023-09-10 22:05:57 +02:00
o->exp = value.toString().toInt();
2022-12-04 14:58:30 +02:00
2022-09-18 01:23:17 +02:00
if(key == "Hero type")
{
for(auto const & t : VLC->heroh->objects)
2022-09-18 01:23:17 +02:00
{
2023-10-16 22:24:12 +02:00
if(t->getId() == value.toInt())
o->subID = value.toInt();
2022-09-18 01:23:17 +02:00
}
o->gender = o->getHeroType()->gender;
o->randomizeArmy(o->getHeroType()->heroClass->faction);
2022-09-18 01:23:17 +02:00
updateProperties(); //updating other properties after change
}
if(key == "Patrol radius")
{
auto radius = value.toInt();
o->patrol.patrolRadius = radius;
o->patrol.patrolling = radius != CGHeroInstance::NO_PATROLLING;
}
2022-09-18 01:23:17 +02:00
}
void Inspector::setProperty(CGShipyard * o, const QString & key, const QVariant & value)
{
if(!o) return;
}
void Inspector::setProperty(CGResource * o, const QString & key, const QVariant & value)
{
if(!o) return;
if(key == "Amount")
o->amount = value.toString().toInt();
}
void Inspector::setProperty(CGCreature * o, const QString & key, const QVariant & value)
{
if(!o) return;
if(key == "Message")
2023-10-10 01:20:55 +02:00
o->message = MetaString::createFromTextID(mapRegisterLocalizedString("map", *controller.map(),
TextIdentifier("monster", o->instanceName, "message"), value.toString().toStdString()));
2022-09-18 01:23:17 +02:00
if(key == "Character")
2023-09-10 22:05:57 +02:00
o->character = CGCreature::Character(value.toInt());
2022-09-18 01:23:17 +02:00
if(key == "Never flees")
2023-09-10 18:10:50 +02:00
o->neverFlees = value.toBool();
2022-09-18 01:23:17 +02:00
if(key == "Not growing")
2023-09-10 18:10:50 +02:00
o->notGrowingTeam = value.toBool();
2022-09-18 01:23:17 +02:00
if(key == "Amount")
o->stacks[SlotID(0)]->count = value.toString().toInt();
}
2022-10-16 01:20:24 +02:00
void Inspector::setProperty(CGSeerHut * o, const QString & key, const QVariant & value)
{
if(!o) return;
if(key == "First visit text")
2023-10-10 01:20:55 +02:00
o->quest->firstVisitText = MetaString::createFromTextID(mapRegisterLocalizedString("map", *controller.map(),
TextIdentifier("quest", o->instanceName, "firstVisit"), value.toString().toStdString()));
2022-10-16 01:20:24 +02:00
if(key == "Next visit text")
2023-10-10 01:20:55 +02:00
o->quest->nextVisitText = MetaString::createFromTextID(mapRegisterLocalizedString("map", *controller.map(),
TextIdentifier("quest", o->instanceName, "nextVisit"), value.toString().toStdString()));
2022-10-16 01:20:24 +02:00
if(key == "Completed text")
2023-10-10 01:20:55 +02:00
o->quest->completedText = MetaString::createFromTextID(mapRegisterLocalizedString("map", *controller.map(),
TextIdentifier("quest", o->instanceName, "completed"), value.toString().toStdString()));
if(key == "Repeat quest")
o->quest->repeatedQuest = value.toBool();
2023-10-10 01:53:25 +02:00
if(key == "Time limit")
o->quest->lastDay = value.toString().toInt();
2022-10-16 01:20:24 +02:00
}
2023-10-11 23:28:10 +02:00
void Inspector::setProperty(CGQuestGuard * o, const QString & key, const QVariant & value)
{
if(!o) return;
}
2022-09-18 01:23:17 +02:00
//===============IMPLEMENT PROPERTY VALUE TYPE============================
QTableWidgetItem * Inspector::addProperty(CGObjectInstance * value)
{
2023-09-10 22:05:57 +02:00
auto * item = new QTableWidgetItem(QString::number(data_cast<CGObjectInstance>(value)));
item->setFlags(Qt::NoItemFlags);
return item;
2022-09-18 01:23:17 +02:00
}
QTableWidgetItem * Inspector::addProperty(Inspector::PropertyEditorPlaceholder value)
{
2023-09-10 22:05:57 +02:00
auto item = new QTableWidgetItem("...");
item->setFlags(Qt::NoItemFlags);
2022-09-18 01:23:17 +02:00
return item;
}
QTableWidgetItem * Inspector::addProperty(unsigned int value)
{
2023-09-10 22:05:57 +02:00
auto * item = new QTableWidgetItem(QString::number(value));
item->setFlags(Qt::NoItemFlags);
//item->setData(Qt::UserRole, QVariant::fromValue(value));
return item;
2022-09-18 01:23:17 +02:00
}
QTableWidgetItem * Inspector::addProperty(int value)
{
2023-09-10 22:05:57 +02:00
auto * item = new QTableWidgetItem(QString::number(value));
item->setFlags(Qt::NoItemFlags);
//item->setData(Qt::UserRole, QVariant::fromValue(value));
return item;
2022-09-18 01:23:17 +02:00
}
QTableWidgetItem * Inspector::addProperty(bool value)
{
2023-09-10 18:10:50 +02:00
auto item = new QTableWidgetItem;
2023-09-10 22:05:57 +02:00
item->setFlags(Qt::ItemIsUserCheckable);
2023-09-10 18:10:50 +02:00
item->setCheckState(value ? Qt::Checked : Qt::Unchecked);
return item;
2022-09-18 01:23:17 +02:00
}
QTableWidgetItem * Inspector::addProperty(const std::string & value)
{
return addProperty(QString::fromStdString(value));
}
2023-09-28 14:03:58 +02:00
QTableWidgetItem * Inspector::addProperty(const TextIdentifier & value)
{
return addProperty(VLC->generaltexth->translate(value.get()));
}
2023-09-28 13:28:37 +02:00
QTableWidgetItem * Inspector::addProperty(const MetaString & value)
{
return addProperty(value.toString());
}
2022-09-18 01:23:17 +02:00
QTableWidgetItem * Inspector::addProperty(const QString & value)
{
2023-09-10 22:05:57 +02:00
auto * item = new QTableWidgetItem(value);
item->setFlags(Qt::NoItemFlags);
return item;
2022-09-18 01:23:17 +02:00
}
QTableWidgetItem * Inspector::addProperty(const int3 & value)
{
2023-09-10 22:05:57 +02:00
auto * item = new QTableWidgetItem(QString("(%1, %2, %3)").arg(value.x, value.y, value.z));
item->setFlags(Qt::NoItemFlags);
return item;
2022-09-18 01:23:17 +02:00
}
QTableWidgetItem * Inspector::addProperty(const PlayerColor & value)
{
2023-09-10 22:05:57 +02:00
auto str = QObject::tr("UNFLAGGABLE");
2022-09-18 01:23:17 +02:00
if(value == PlayerColor::NEUTRAL)
2023-09-10 22:05:57 +02:00
str = QObject::tr("neutral");
if(value.isValidPlayer())
str = QString::fromStdString(GameConstants::PLAYER_COLOR_NAMES[value]);
auto * item = new QTableWidgetItem(str);
item->setFlags(Qt::NoItemFlags);
item->setData(Qt::UserRole, QVariant::fromValue(value.getNum()));
return item;
2022-09-18 01:23:17 +02:00
}
2023-04-05 02:26:29 +02:00
QTableWidgetItem * Inspector::addProperty(const GameResID & value)
2022-09-18 01:23:17 +02:00
{
2023-09-10 22:05:57 +02:00
auto * item = new QTableWidgetItem(QString::fromStdString(GameConstants::RESOURCE_NAMES[value.toEnum()]));
item->setFlags(Qt::NoItemFlags);
item->setData(Qt::UserRole, QVariant::fromValue(value.getNum()));
return item;
2022-09-18 01:23:17 +02:00
}
QTableWidgetItem * Inspector::addProperty(CGCreature::Character value)
{
2023-09-10 22:05:57 +02:00
auto * item = new QTableWidgetItem;
item->setFlags(Qt::NoItemFlags);
item->setData(Qt::UserRole, QVariant::fromValue(int(value)));
for(auto & i : CharacterIdentifiers)
{
if(i.second.toInt() == value)
{
item->setText(i.first);
2022-09-18 01:23:17 +02:00
break;
2023-09-10 22:05:57 +02:00
}
2022-09-18 01:23:17 +02:00
}
2023-09-10 22:05:57 +02:00
return item;
2022-09-18 01:23:17 +02:00
}
//========================================================================
Inspector::Inspector(MapController & c, CGObjectInstance * o, QTableWidget * t): obj(o), table(t), controller(c)
2022-09-18 01:23:17 +02:00
{
}
/*
* Delegates
*/
QWidget * InspectorDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
return new QComboBox(parent);
}
void InspectorDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
if(QComboBox *ed = qobject_cast<QComboBox *>(editor))
{
2023-09-10 22:05:57 +02:00
for(auto & i : options)
{
ed->addItem(i.first);
ed->setItemData(ed->count() - 1, i.second);
}
2022-09-18 01:23:17 +02:00
}
else
{
QStyledItemDelegate::setEditorData(editor, index);
}
}
void InspectorDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
if(QComboBox *ed = qobject_cast<QComboBox *>(editor))
{
if(!options.isEmpty())
{
QMap<int, QVariant> data;
2023-09-10 22:05:57 +02:00
data[Qt::DisplayRole] = options[ed->currentIndex()].first;
data[Qt::UserRole] = options[ed->currentIndex()].second;
2022-09-18 01:23:17 +02:00
model->setItemData(index, data);
}
}
else
{
QStyledItemDelegate::setModelData(editor, model, index);
}
}
2024-02-29 23:11:28 +02:00
OwnerDelegate::OwnerDelegate(MapController & controller, bool addNeutral)
2024-02-29 23:11:28 +02:00
{
if(addNeutral)
options.push_back({QObject::tr("neutral"), QVariant::fromValue(PlayerColor::NEUTRAL.getNum()) });
2024-02-29 23:11:28 +02:00
for(int p = 0; p < controller.map()->players.size(); ++p)
if(controller.map()->players[p].canAnyonePlay())
options.push_back({QString::fromStdString(GameConstants::PLAYER_COLOR_NAMES[p]), QVariant::fromValue(PlayerColor(p).getNum()) });
}