1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-06 09:09:40 +02:00

Quests in map now use shared_ptr instead of const ptr

This commit is contained in:
Ivan Savenko
2025-03-09 22:44:36 +00:00
parent 417ea6451a
commit 797646cc05
20 changed files with 64 additions and 39 deletions

View File

@@ -15,6 +15,7 @@
#include "../../lib/UnlockGuard.h"
#include "../../lib/CConfigHandler.h"
#include "../../lib/mapObjects/MapObjects.h"
#include "../../lib/mapObjects/CQuest.h"
#include "../../lib/mapping/CMapDefines.h"
#include "../../lib/gameState/QuestInfo.h"
#include "../../lib/IGameSettings.h"

View File

@@ -12,6 +12,7 @@
#include "../Behaviors/CaptureObjectsBehavior.h"
#include "../AIGateway.h"
#include "../../../lib/GameLibrary.h"
#include "../../../lib/mapObjects/CQuest.h"
#include "../../../lib/texts/CGeneralTextHandler.h"
namespace NKAI

View File

@@ -12,6 +12,7 @@
#include "QuestAction.h"
#include "../../AIGateway.h"
#include "../../Goals/CompleteQuest.h"
#include "../../../lib/mapObjects/CQuest.h"
namespace NKAI
{

View File

@@ -12,6 +12,7 @@
#include "AIPathfinderConfig.h"
#include "../../../lib/CRandomGenerator.h"
#include "../../../CCallback.h"
#include "../../../lib/mapObjects/CQuest.h"
#include "../../../lib/mapping/CMap.h"
#include "../Engine/Nullkiller.h"
#include "../../../lib/logging/VisualLogger.h"
@@ -82,11 +83,11 @@ void GraphPaths::calculatePaths(const CGHeroInstance * targetHero, const Nullkil
|| node.obj->ID == Obj::BORDER_GATE)
{
auto questObj = dynamic_cast<const IQuestObject *>(node.obj);
auto questInfo = QuestInfo(questObj->quest, node.obj, pos.coord);
auto questInfo = QuestInfo(questObj->getQuest(), node.obj, pos.coord);
if(node.obj->ID == Obj::QUEST_GUARD
&& questObj->quest->mission == Rewardable::Limiter{}
&& questObj->quest->killTarget == ObjectInstanceID::NONE)
&& questObj->getQuest()->mission == Rewardable::Limiter{}
&& questObj->getQuest()->killTarget == ObjectInstanceID::NONE)
{
continue;
}

View File

@@ -14,6 +14,7 @@
#include "../Actions/WhirlpoolAction.h"
#include "../../Goals/Invalid.h"
#include "AIPreviousNodeRule.h"
#include "../../../../lib/mapObjects/CQuest.h"
#include "../../../../lib/pathfinder/PathfinderOptions.h"
#include "../../../../lib/pathfinder/CPathfinder.h"
@@ -165,12 +166,12 @@ namespace AIPathfinding
{
const AIPathNode * destinationNode = nodeStorage->getAINode(destination.node);
auto questObj = dynamic_cast<const IQuestObject *>(destination.nodeObject);
auto questInfo = QuestInfo(questObj->quest, destination.nodeObject, destination.coord);
auto questInfo = QuestInfo(questObj->getQuest(), destination.nodeObject, destination.coord);
QuestAction questAction(questInfo);
if(destination.nodeObject->ID == Obj::QUEST_GUARD
&& questObj->quest->mission == Rewardable::Limiter{}
&& questObj->quest->killTarget == ObjectInstanceID::NONE)
&& questObj->getQuest()->mission == Rewardable::Limiter{}
&& questObj->getQuest()->killTarget == ObjectInstanceID::NONE)
{
return false;
}

View File

@@ -10,7 +10,6 @@
#pragma once
#include "CGoal.h"
#include "../../../lib/GameLibrary.h"
#include "../../../lib/gameState/QuestInfo.h"
namespace Goals

View File

@@ -224,7 +224,7 @@ Goals::TSubgoal PathfindingManager::clearWayTo(HeroPtr hero, int3 firstTileToGet
if(questObj)
{
auto questInfo = QuestInfo(questObj->quest, topObj, topObj->visitablePos());
auto questInfo = QuestInfo(questObj->getQuest(), topObj, topObj->visitablePos());
return sptr(Goals::CompleteQuest(questInfo));
}

View File

@@ -29,6 +29,7 @@
#include "../../lib/bonuses/Updaters.h"
#include "../../lib/bonuses/Propagators.h"
#include "../../lib/entities/building/CBuilding.h"
#include "../../lib/mapObjects/CQuest.h"
#include "../../lib/networkPacks/PacksForClient.h"
#include "../../lib/networkPacks/PacksForClientBattle.h"
#include "../../lib/networkPacks/PacksForServer.h"

View File

@@ -32,6 +32,7 @@
#include "../../CCallback.h"
#include "../../lib/CConfigHandler.h"
#include "../../lib/CPlayerState.h"
#include "../../lib/texts/CGeneralTextHandler.h"
#include "../../lib/mapObjects/CGHeroInstance.h"
#include "../../lib/mapObjects/CGTownInstance.h"
@@ -553,7 +554,7 @@ void AdventureMapShortcuts::moveHeroDirectional(const Point & direction)
bool AdventureMapShortcuts::optionCanViewQuests()
{
return optionInMapView() && !GAME->map().getMap()->quests.empty();
return optionInMapView() && !GAME->interface()->cb->getPlayerState(GAME->interface()->playerID)->quests.empty();
}
bool AdventureMapShortcuts::optionCanToggleLevel()

View File

@@ -592,7 +592,7 @@ void CGSeerHut::onHeroVisit(const CGHeroInstance * h) const
cb->setObjPropertyID(id, ObjProperty::SEERHUT_VISITED, h->getOwner());
AddQuest aq;
aq.quest = QuestInfo (quest, this, visitablePos());
aq.quest = QuestInfo(quest.get(), this, visitablePos());
aq.player = h->tempOwner;
cb->sendAndApply(aq); //TODO: merge with setObjProperty?
}
@@ -869,7 +869,7 @@ void CGBorderGuard::onHeroVisit(const CGHeroInstance * h) const
h->showInfoDialog(18);
AddQuest aq;
aq.quest = QuestInfo (quest, this, visitablePos());
aq.quest = QuestInfo (quest.get(), this, visitablePos());
aq.player = h->tempOwner;
cb->sendAndApply(aq);
//TODO: add this quest only once OR check for multiple instances later
@@ -894,7 +894,7 @@ void CGBorderGate::onHeroVisit(const CGHeroInstance * h) const //TODO: passabili
h->showInfoDialog(18);
AddQuest aq;
aq.quest = QuestInfo (quest, this, visitablePos());
aq.quest = QuestInfo (quest.get(), this, visitablePos());
aq.player = h->tempOwner;
cb->sendAndApply(aq);
}

View File

@@ -118,14 +118,25 @@ public:
class DLL_LINKAGE IQuestObject : public virtual Serializeable
{
public:
CQuest * quest = new CQuest();
friend class CMapLoaderH3M;
friend class TreasurePlacer; // RMG
friend class Inspector; // Map editor
protected:
std::shared_ptr<CQuest> quest;
public:
IQuestObject()
:quest(std::make_shared<CQuest>())
{}
///Information about quest should remain accessible even if IQuestObject removed from map
///All CQuest objects are freed in CMap destructor
virtual ~IQuestObject() = default;
virtual void getVisitText (MetaString &text, std::vector<Component> &components, bool FirstVisit, const CGHeroInstance * h = nullptr) const = 0;
virtual bool checkQuest (const CGHeroInstance * h) const;
const CQuest * getQuest() const
{
return quest.get();
}
template <typename Handler> void serialize(Handler &h)
{

View File

@@ -21,4 +21,3 @@
#include "CGPandoraBox.h"
#include "CRewardableObject.h"
#include "MiscObjects.h"
#include "CQuest.h"

View File

@@ -194,9 +194,6 @@ CMap::~CMap()
for(auto obj : objects)
obj.dellNull();
for(auto quest : quests)
quest.dellNull();
for(auto artInstance : artInstances)
artInstance.dellNull();
@@ -527,17 +524,15 @@ void CMap::removeArtifactInstance(CArtifactSet & set, const ArtifactPosition & s
art->addPlacementMap(partsMap);
}
void CMap::addNewQuestInstance(CQuest* quest)
void CMap::addNewQuestInstance(std::shared_ptr<CQuest> quest)
{
quest->qid = static_cast<si32>(quests.size());
quests.emplace_back(quest);
}
void CMap::removeQuestInstance(CQuest * quest)
void CMap::removeQuestInstance(std::shared_ptr<CQuest> quest)
{
//TODO: should be called only by map editor.
//During game, completed quests or quests from removed objects stay forever
//Shift indexes
auto iter = std::next(quests.begin(), quest->qid);
@@ -548,6 +543,13 @@ void CMap::removeQuestInstance(CQuest * quest)
}
}
void CMap::clearQuestInstance(const CQuest * quest)
{
assert(quests.at(quest->qid).get() == quest);
quests.at(quest->qid) = nullptr;
}
void CMap::setUniqueInstanceName(CGObjectInstance * obj)
{
//this gives object unique name even if objects are removed later

View File

@@ -59,7 +59,11 @@ struct DLL_LINKAGE Rumor
/// The map contains the map header, the tiles of the terrain, objects, heroes, towns, rumors...
class DLL_LINKAGE CMap : public CMapHeader, public GameCallbackHolder
{
friend class CSerializer;
std::unique_ptr<GameSettings> gameSettings;
std::vector< std::shared_ptr<CQuest> > quests;
public:
explicit CMap(IGameCallback *cb);
~CMap();
@@ -86,8 +90,9 @@ public:
void putArtifactInstance(CArtifactSet & set, CArtifactInstance * art, const ArtifactPosition & slot);
void removeArtifactInstance(CArtifactSet & set, const ArtifactPosition & slot);
void addNewQuestInstance(CQuest * quest);
void removeQuestInstance(CQuest * quest);
void addNewQuestInstance(std::shared_ptr<CQuest> quest);
void removeQuestInstance(std::shared_ptr<CQuest> quest);
void clearQuestInstance(const CQuest * quest);
void setUniqueInstanceName(CGObjectInstance * obj);
///Use only this method when creating new map object instances
@@ -130,7 +135,6 @@ public:
std::vector< ConstTransitivePtr<CGObjectInstance> > objects;
std::vector< ConstTransitivePtr<CGTownInstance> > towns;
std::vector< ConstTransitivePtr<CArtifactInstance> > artInstances;
std::vector< ConstTransitivePtr<CQuest> > quests;
std::vector< ConstTransitivePtr<CGHeroInstance> > allHeroes; //indexed by [hero_type_id]; on map, disposed, prisons, etc.
//Helper lists

View File

@@ -34,6 +34,7 @@
#include "../mapObjectConstructors/CommonConstructors.h"
#include "../mapObjects/CGCreature.h"
#include "../mapObjects/CGResource.h"
#include "../mapObjects/CQuest.h"
#include "../mapObjects/MapObjects.h"
#include "../mapObjects/ObjectTemplate.h"
#include "../modding/ModScope.h"

View File

@@ -1247,7 +1247,7 @@ void RemoveObject::applyGs(CGameState *gs)
const auto * quest = dynamic_cast<const IQuestObject *>(obj);
if (quest)
{
gs->getMap().quests[quest->quest->qid] = nullptr;
gs->getMap().clearQuestInstance(quest->getQuest());
for (auto &player : gs->players)
{
vstd::erase_if(player.second.quests, [obj](const QuestInfo & q){

View File

@@ -522,7 +522,7 @@ void TreasurePlacer::addSeerHuts()
{
auto * seer = dynamic_cast<CGSeerHut *>(obj);
// Artifact can be used again
ArtifactID artid = seer->quest->mission.artifacts.front();
ArtifactID artid = seer->getQuest()->mission.artifacts.front();
qap->addRandomArtifact(artid);
qap->removeQuestArtifact(artid);
};

View File

@@ -29,8 +29,9 @@ void CSerializer::addStdVecItems(CGameState *gs, GameLibrary *lib)
[](const CGHeroInstance &h){ return h.getHeroType()->getId(); });
registerVectoredType<CArtifactInstance, ArtifactInstanceID>(&gs->getMap().artInstances,
[](const CArtifactInstance &artInst){ return artInst.getId(); });
registerVectoredType<CQuest, si32>(&gs->getMap().quests,
[](const CQuest &q){ return q.qid; });
// TODO
// registerVectoredType<CQuest, si32>(&gs->getMap().quests,
// [](const CQuest &q){ return q.qid; });
smartVectorMembersSerialization = true;
}

View File

@@ -454,13 +454,13 @@ void Inspector::updateProperties(CGEvent * o)
void Inspector::updateProperties(CGSeerHut * o)
{
if(!o || !o->quest) return;
if(!o || !o->getQuest()) return;
addProperty(QObject::tr("First visit text"), o->quest->firstVisitText, new MessageDelegate, false);
addProperty(QObject::tr("Next visit text"), o->quest->nextVisitText, new MessageDelegate, false);
addProperty(QObject::tr("Completed text"), o->quest->completedText, new MessageDelegate, false);
addProperty(QObject::tr("Repeat quest"), o->quest->repeatedQuest, false);
addProperty(QObject::tr("Time limit"), o->quest->lastDay, false);
addProperty(QObject::tr("First visit text"), o->getQuest()->firstVisitText, new MessageDelegate, false);
addProperty(QObject::tr("Next visit text"), o->getQuest()->nextVisitText, new MessageDelegate, false);
addProperty(QObject::tr("Completed text"), o->getQuest()->completedText, new MessageDelegate, false);
addProperty(QObject::tr("Repeat quest"), o->getQuest()->repeatedQuest, false);
addProperty(QObject::tr("Time limit"), o->getQuest()->lastDay, false);
{ //Quest
auto * delegate = new QuestDelegate(controller, *o->quest);
@@ -470,10 +470,10 @@ void Inspector::updateProperties(CGSeerHut * o)
void Inspector::updateProperties(CGQuestGuard * o)
{
if(!o || !o->quest) return;
if(!o || !o->getQuest()) return;
addProperty(QObject::tr("Reward"), PropertyEditorPlaceholder(), nullptr, true);
addProperty(QObject::tr("Repeat quest"), o->quest->repeatedQuest, true);
addProperty(QObject::tr("Repeat quest"), o->getQuest()->repeatedQuest, true);
}
void Inspector::updateProperties()

View File

@@ -18,6 +18,7 @@
#include "../lib/GameConstants.h"
#include "../lib/mapObjects/CGCreature.h"
#include "../lib/mapObjects/CGResource.h"
#include "../lib/mapObjects/CQuest.h"
#include "../lib/mapObjects/MapObjects.h"
#include "../lib/mapObjects/FlaggableMapObject.h"
#include "../lib/mapObjects/CRewardableObject.h"