mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Quests will now be handled as object member instead of inheritance. Enabled quest objects for AI.
This commit is contained in:
		| @@ -3462,7 +3462,7 @@ bool shouldVisit(HeroPtr h, const CGObjectInstance * obj) | ||||
| 		case Obj::SEER_HUT: | ||||
| 		case Obj::QUEST_GUARD: | ||||
| 		{ | ||||
| 			return false; //fixme: avoid crash | ||||
| 			//return false; //fixme: avoid crash | ||||
| 			BOOST_FOREACH (auto q, ai->myCb->getMyQuests()) | ||||
| 			{ | ||||
| 				if (q.obj == obj) | ||||
|   | ||||
| @@ -1281,7 +1281,8 @@ void CBoundedLabel::showAll(SDL_Surface * to) | ||||
| 	for (int i = 0; i < lineCapacity; i++) | ||||
| 	{ | ||||
| 		const std::string &line = lines[i]; | ||||
| 		if(!line.size()) continue; | ||||
| 		if ( !(lines.size() && line.size())) //empty message or empty line | ||||
| 			continue; | ||||
|  | ||||
| 		int x = pos.x; | ||||
| 		if(alignment == CENTER) | ||||
|   | ||||
| @@ -4404,41 +4404,41 @@ void CQuest::getCompletionText (MetaString &iwText, std::vector<Component> &comp | ||||
| } | ||||
| void CGSeerHut::setObjToKill() | ||||
| { | ||||
| 	if (missionType == MISSION_KILL_CREATURE) | ||||
| 	if (quest.missionType == CQuest::MISSION_KILL_CREATURE) | ||||
| 	{ | ||||
| 		stackToKill = getCreatureToKill(false)->getStack(0); //FIXME: stacks tend to dissapear (desync?) on server :? | ||||
| 		stackToKill.count = 0; //no count in info window | ||||
| 		stackDirection = checkDirection(); | ||||
| 		quest.stackToKill = getCreatureToKill(false)->getStack(0); //FIXME: stacks tend to dissapear (desync?) on server :? | ||||
| 		quest.stackToKill.count = 0; //no count in info window | ||||
| 		quest.stackDirection = checkDirection(); | ||||
| 	} | ||||
| 	else if (missionType == MISSION_KILL_HERO) | ||||
| 	else if (quest.missionType == CQuest::MISSION_KILL_HERO) | ||||
| 	{ | ||||
| 		heroName = getHeroToKill(false)->name; | ||||
| 		heroPortrait = getHeroToKill(false)->portrait; | ||||
| 		quest.heroName = getHeroToKill(false)->name; | ||||
| 		quest.heroPortrait = getHeroToKill(false)->portrait; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void CGSeerHut::initObj() | ||||
| { | ||||
| 	seerName = VLC->generaltexth->seerNames[ran()%VLC->generaltexth->seerNames.size()]; | ||||
| 	textOption = ran()%3; | ||||
| 	progress = 0; | ||||
| 	if (missionType) | ||||
| 	quest.textOption = ran()%3; | ||||
| 	quest.progress = 0; | ||||
| 	if (quest.missionType) | ||||
| 	{ | ||||
| 		if (!isCustomFirst) | ||||
| 			firstVisitText = VLC->generaltexth->quests[missionType-1][0][textOption]; | ||||
| 		if (!isCustomNext) | ||||
| 			nextVisitText = VLC->generaltexth->quests[missionType-1][1][textOption]; | ||||
| 		if (!isCustomComplete) | ||||
| 			completedText = VLC->generaltexth->quests[missionType-1][2][textOption]; | ||||
| 		if (!quest.isCustomFirst) | ||||
| 			quest.firstVisitText = VLC->generaltexth->quests[quest.missionType-1][0][quest.textOption]; | ||||
| 		if (!quest.isCustomNext) | ||||
| 			quest.nextVisitText = VLC->generaltexth->quests[quest.missionType-1][1][quest.textOption]; | ||||
| 		if (!quest.isCustomComplete) | ||||
| 			quest.completedText = VLC->generaltexth->quests[quest.missionType-1][2][quest.textOption]; | ||||
| 	} | ||||
| 	else | ||||
| 		firstVisitText = VLC->generaltexth->seerEmpty[textOption]; | ||||
| 		quest.firstVisitText = VLC->generaltexth->seerEmpty[quest.textOption]; | ||||
|  | ||||
| } | ||||
|  | ||||
| void CGSeerHut::getRolloverText (MetaString &text, bool onHover) const | ||||
| { | ||||
| 	CQuest::getRolloverText (text, onHover);//TODO: simplify? | ||||
| 	quest.getRolloverText (text, onHover);//TODO: simplify? | ||||
| 	if (!onHover) | ||||
| 		text.addReplacement(seerName); | ||||
| } | ||||
| @@ -4448,7 +4448,7 @@ const std::string & CGSeerHut::getHoverText() const | ||||
| 	switch (ID) | ||||
| 	{ | ||||
| 			case 83: | ||||
| 				if (progress) | ||||
| 				if (quest.progress) | ||||
| 				{ | ||||
| 					hoverName = VLC->generaltexth->allTexts[347]; | ||||
| 					boost::algorithm::replace_first(hoverName,"%s", seerName); | ||||
| @@ -4462,7 +4462,7 @@ const std::string & CGSeerHut::getHoverText() const | ||||
| 			default: | ||||
| 				tlog5 << "unrecognized quest object\n"; | ||||
| 	} | ||||
| 	if (progress & missionType) //rollover when the quest is active | ||||
| 	if (quest.progress & quest.missionType) //rollover when the quest is active | ||||
| 	{ | ||||
| 		MetaString ms; | ||||
| 		getRolloverText (ms, true); | ||||
| @@ -4488,9 +4488,19 @@ void CQuest::addReplacements(MetaString &out, const std::string &base) const | ||||
| 	} | ||||
| } | ||||
|  | ||||
| bool IQuestObject::checkQuest(const CGHeroInstance* h) const | ||||
| { | ||||
| 	return quest.checkQuest(h); | ||||
| } | ||||
|  | ||||
| void IQuestObject::getVisitText (MetaString &text, std::vector<Component> &components, bool isCustom, bool FirstVisit, const CGHeroInstance * h) const | ||||
| { | ||||
| 	quest.getVisitText (text,components, isCustom, FirstVisit, h); | ||||
| } | ||||
|  | ||||
| void CGSeerHut::getCompletionText(MetaString &text, std::vector<Component> &components, bool isCustom, const CGHeroInstance * h) const | ||||
| { | ||||
| 	CQuest::getCompletionText (text, components, isCustom, h); | ||||
| 	quest.getCompletionText (text, components, isCustom, h); | ||||
| 	switch (rewardType) | ||||
| 	{ | ||||
| 		case 1: components.push_back(Component (Component::EXPERIENCE, 0, rVal*(100+h->getSecSkillLevel(CGHeroInstance::LEARNING)*5)/100.0, 0)); | ||||
| @@ -4521,16 +4531,16 @@ void CGSeerHut::setPropertyDer (ui8 what, ui32 val) | ||||
| 	switch (what) | ||||
| 	{ | ||||
| 		case 10: | ||||
| 			progress = val; | ||||
| 			quest.progress = val; | ||||
| 			break; | ||||
| 		case 11: | ||||
| 			missionType = CQuest::MISSION_NONE; | ||||
| 			quest.missionType = CQuest::MISSION_NONE; | ||||
| 			break; | ||||
| 	} | ||||
| } | ||||
| void CGSeerHut::newTurn() const | ||||
| { | ||||
| 	if (lastDay >= 0 && lastDay < cb->getDate(0)) //time is up | ||||
| 	if (quest.lastDay >= 0 && quest.lastDay < cb->getDate(0)) //time is up | ||||
| 	{ | ||||
| 		cb->setObjProperty (id, 11, 0); | ||||
| 		cb->setObjProperty (id, 10, 0); | ||||
| @@ -4541,25 +4551,25 @@ void CGSeerHut::onHeroVisit( const CGHeroInstance * h ) const | ||||
| { | ||||
| 	InfoWindow iw; | ||||
| 	iw.player = h->getOwner(); | ||||
| 	if (missionType) | ||||
| 	if (quest.missionType) | ||||
| 	{ | ||||
| 		bool firstVisit = !progress; | ||||
| 		bool firstVisit = !quest.progress; | ||||
| 		bool failRequirements = !checkQuest(h); | ||||
| 		bool isCustom=false; | ||||
|  | ||||
| 		if (firstVisit) | ||||
| 		{ | ||||
| 			isCustom = isCustomFirst; | ||||
| 			cb->setObjProperty (id, 10, IN_PROGRESS); | ||||
| 			isCustom = quest.isCustomFirst; | ||||
| 			cb->setObjProperty (id, 10, CQuest::IN_PROGRESS); | ||||
|  | ||||
| 			AddQuest aq; | ||||
| 			aq.quest = QuestInfo (this, this, visitablePos()); | ||||
| 			aq.quest = QuestInfo (&quest, this, visitablePos()); | ||||
| 			aq.player = h->tempOwner; | ||||
| 			cb->sendAndApply (&aq); //TODO: merge with setObjProperty? | ||||
| 		} | ||||
| 		else if (failRequirements) | ||||
| 		{ | ||||
| 			isCustom = isCustomNext; | ||||
| 			isCustom = quest.isCustomNext; | ||||
| 		} | ||||
|  | ||||
| 		if (firstVisit || failRequirements) | ||||
| @@ -4582,7 +4592,7 @@ void CGSeerHut::onHeroVisit( const CGHeroInstance * h ) const | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		iw.text << VLC->generaltexth->seerEmpty[textOption]; | ||||
| 		iw.text << VLC->generaltexth->seerEmpty[quest.textOption]; | ||||
| 		if (ID == 83) | ||||
| 			iw.text.addReplacement(seerName); | ||||
| 		cb->showInfoDialog(&iw); | ||||
| @@ -4623,27 +4633,27 @@ void CGSeerHut::finishQuest(const CGHeroInstance * h, ui32 accept) const | ||||
| { | ||||
| 	if (accept) | ||||
| 	{ | ||||
| 		switch (missionType) | ||||
| 		switch (quest.missionType) | ||||
| 		{ | ||||
| 			case CQuest::MISSION_ART: | ||||
| 				for (std::vector<ui16>::const_iterator it = m5arts.begin(); it != m5arts.end(); ++it) | ||||
| 				for (std::vector<ui16>::const_iterator it = quest.m5arts.begin(); it != quest.m5arts.end(); ++it) | ||||
| 				{ | ||||
| 					cb->removeArtifact(ArtifactLocation(h, h->getArtPos(*it, false))); | ||||
| 				} | ||||
| 				break; | ||||
| 			case CQuest::MISSION_ARMY: | ||||
| 					cb->takeCreatures(h->id, m6creatures); | ||||
| 					cb->takeCreatures(h->id, quest.m6creatures); | ||||
| 				break; | ||||
| 			case CQuest::MISSION_RESOURCES: | ||||
| 				for (int i = 0; i < 7; ++i) | ||||
| 				{ | ||||
| 					cb->giveResource(h->getOwner(), i, -m7resources[i]); | ||||
| 					cb->giveResource(h->getOwner(), i, -quest.m7resources[i]); | ||||
| 				} | ||||
| 				break; | ||||
| 			default: | ||||
| 				break; | ||||
| 		} | ||||
| 		cb->setObjProperty (id, 10, COMPLETE); //mission complete - for AI | ||||
| 		cb->setObjProperty (id, 10, CQuest::COMPLETE); //mission complete - for AI | ||||
| 		cb->setObjProperty (id, 11, 0); //no more mission available - redundant? | ||||
| 		completeQuest(h); //make sure to remove QuestQuard at the very end | ||||
| 	} | ||||
| @@ -4706,7 +4716,7 @@ void CGSeerHut::completeQuest (const CGHeroInstance * h) const //reward | ||||
|  | ||||
| const CGHeroInstance * CGSeerHut::getHeroToKill(bool allowNull) const | ||||
| { | ||||
| 	const CGObjectInstance *o = cb->getObjByQuestIdentifier(m13489val); | ||||
| 	const CGObjectInstance *o = cb->getObjByQuestIdentifier(quest.m13489val); | ||||
| 	if(allowNull && !o) | ||||
| 		return NULL; | ||||
| 	assert(o && o->ID == GameConstants::HEROI_TYPE); | ||||
| @@ -4715,7 +4725,7 @@ const CGHeroInstance * CGSeerHut::getHeroToKill(bool allowNull) const | ||||
|  | ||||
| const CGCreature * CGSeerHut::getCreatureToKill(bool allowNull) const | ||||
| { | ||||
| 	const CGObjectInstance *o = cb->getObjByQuestIdentifier(m13489val); | ||||
| 	const CGObjectInstance *o = cb->getObjByQuestIdentifier(quest.m13489val); | ||||
| 	if(allowNull && !o) | ||||
| 		return NULL; | ||||
| 	assert(o && o->ID == 54); | ||||
| @@ -4725,19 +4735,19 @@ const CGCreature * CGSeerHut::getCreatureToKill(bool allowNull) const | ||||
| void CGQuestGuard::initObj() | ||||
| { | ||||
| 	blockVisit = true; | ||||
| 	progress = 0; | ||||
| 	textOption = ran()%3 + 3; //3-5 | ||||
| 	if (missionType) | ||||
| 	quest.progress = 0; | ||||
| 	quest.textOption = ran()%3 + 3; //3-5 | ||||
| 	if (quest.missionType) | ||||
| 	{ | ||||
| 		if (!isCustomFirst) | ||||
| 			firstVisitText = VLC->generaltexth->quests[missionType-1][0][textOption]; | ||||
| 		if (!isCustomNext) | ||||
| 			nextVisitText = VLC->generaltexth->quests[missionType-1][1][textOption]; | ||||
| 		if (!isCustomComplete) | ||||
| 			completedText = VLC->generaltexth->quests[missionType-1][2][textOption]; | ||||
| 		if (!quest.isCustomFirst) | ||||
| 			quest.firstVisitText = VLC->generaltexth->quests[quest.missionType-1][0][quest.textOption]; | ||||
| 		if (!quest.isCustomNext) | ||||
| 			quest.nextVisitText = VLC->generaltexth->quests[quest.missionType-1][1][quest.textOption]; | ||||
| 		if (!quest.isCustomComplete) | ||||
| 			quest.completedText = VLC->generaltexth->quests[quest.missionType-1][2][quest.textOption]; | ||||
| 	} | ||||
| 	else | ||||
| 		firstVisitText = VLC->generaltexth->seerEmpty[textOption]; | ||||
| 		quest.firstVisitText = VLC->generaltexth->seerEmpty[quest.textOption]; | ||||
| } | ||||
| void CGQuestGuard::completeQuest(const CGHeroInstance *h) const | ||||
| { | ||||
| @@ -6361,7 +6371,7 @@ void CGBorderGuard::onHeroVisit( const CGHeroInstance * h ) const | ||||
| 		cb->showInfoDialog (&iw); | ||||
|  | ||||
| 		AddQuest aq; | ||||
| 		aq.quest = QuestInfo (this, this, visitablePos()); | ||||
| 		aq.quest = QuestInfo (&quest, this, visitablePos()); | ||||
| 		aq.player = h->tempOwner; | ||||
| 		cb->sendAndApply (&aq); | ||||
| 		//TODO: add this quest only once OR check for multiple instances later | ||||
| @@ -6384,7 +6394,7 @@ void CGBorderGate::onHeroVisit( const CGHeroInstance * h ) const //TODO: passabi | ||||
| 		cb->showInfoDialog(&iw); | ||||
|  | ||||
| 		AddQuest aq; | ||||
| 		aq.quest = QuestInfo (this, this, visitablePos()); | ||||
| 		aq.quest = QuestInfo (&quest, this, visitablePos()); | ||||
| 		aq.player = h->tempOwner; | ||||
| 		cb->sendAndApply (&aq); | ||||
| 	} | ||||
|   | ||||
| @@ -759,7 +759,21 @@ public: | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| class DLL_LINKAGE CGSeerHut : public CArmedInstance, public CQuest //army is used when giving reward | ||||
| class DLL_LINKAGE IQuestObject | ||||
| { | ||||
| public: | ||||
| 	CQuest quest; | ||||
|  | ||||
| 	virtual void getVisitText (MetaString &text, std::vector<Component> &components, bool isCustom, bool FirstVisit, const CGHeroInstance * h = NULL) const; | ||||
| 	virtual bool checkQuest (const CGHeroInstance * h) const; | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & quest; | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| class DLL_LINKAGE CGSeerHut : public CArmedInstance, public IQuestObject //army is used when giving reward | ||||
| { | ||||
| public: | ||||
| 	ui8 rewardType; //type of reward: 0 - no reward; 1 - experience; 2 - mana points; 3 - morale bonus; 4 - luck bonus; 5 - resources; 6 - main ability bonus (attak, defence etd.); 7 - secondary ability gain; 8 - artifact; 9 - spell; 10 - creature | ||||
| @@ -770,21 +784,21 @@ public: | ||||
| 	void initObj(); | ||||
| 	const std::string & getHoverText() const; | ||||
| 	void setPropertyDer (ui8 what, ui32 val); | ||||
| 	int checkDirection() const; //calculates the region of map where monster is placed | ||||
| 	void newTurn() const; | ||||
| 	void onHeroVisit (const CGHeroInstance * h) const; | ||||
|  | ||||
| 	int checkDirection() const; //calculates the region of map where monster is placed | ||||
| 	void setObjToKill(); //remember creatures / heroes to kill after they are initialized | ||||
| 	const CGHeroInstance *getHeroToKill(bool allowNull = false) const; | ||||
| 	const CGCreature *getCreatureToKill(bool allowNull = false) const; | ||||
| 	void getRolloverText (MetaString &text, bool onHover) const; | ||||
| 	void getCompletionText(MetaString &text, std::vector<Component> &components, bool isCustom, const CGHeroInstance * h = NULL) const; | ||||
| 	void finishQuest (const CGHeroInstance * h, ui32 accept) const; //common for both objects | ||||
| 	void completeQuest (const CGHeroInstance * h) const; | ||||
|  | ||||
| 	void setObjToKill(); //remember creatures / heroes to kill after they are initialized | ||||
| 	const CGHeroInstance *getHeroToKill(bool allowNull = false) const; | ||||
| 	const CGCreature *getCreatureToKill(bool allowNull = false) const; | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & static_cast<CArmedInstance&>(*this) & static_cast<CQuest&>(*this); | ||||
| 		h & static_cast<CArmedInstance&>(*this) & static_cast<IQuestObject&>(*this); | ||||
| 		h & rewardType & rID & rVal & seerName; | ||||
| 	} | ||||
| }; | ||||
| @@ -1067,7 +1081,7 @@ public: | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| class DLL_LINKAGE CGBorderGuard : public CGKeys, public CQuest | ||||
| class DLL_LINKAGE CGBorderGuard : public CGKeys, public IQuestObject | ||||
| { | ||||
| public: | ||||
| 	void initObj(); | ||||
| @@ -1080,7 +1094,7 @@ public: | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & static_cast<CQuest&>(*this); | ||||
| 		h & static_cast<IQuestObject&>(*this); | ||||
| 		h & static_cast<CGObjectInstance&>(*this); | ||||
| 		h & blockVisit; | ||||
| 	} | ||||
|   | ||||
| @@ -38,6 +38,7 @@ void registerTypes1(Serializer &s) | ||||
| 	s.template registerType<CGCreature>(); | ||||
| 	s.template registerType<CGSignBottle>(); | ||||
| 	s.template registerType<CQuest>(); | ||||
| 	s.template registerType<IQuestObject>(); | ||||
| 	s.template registerType<CGSeerHut>(); | ||||
| 	s.template registerType<CGQuestGuard>(); | ||||
| 	s.template registerType<CGWitchHut>(); | ||||
|   | ||||
							
								
								
									
										68
									
								
								lib/map.cpp
									
									
									
									
									
								
							
							
						
						
									
										68
									
								
								lib/map.cpp
									
									
									
									
									
								
							| @@ -567,18 +567,18 @@ int Mapa::loadSeerHut( const ui8 * bufor, int i, CGObjectInstance *& nobj ) | ||||
| 		int artID = bufor[i]; ++i; | ||||
| 		if (artID != 255) //not none quest | ||||
| 		{ | ||||
| 			hut->m5arts.push_back (artID); | ||||
| 			hut->missionType = CQuest::MISSION_ART; | ||||
| 			hut->quest.m5arts.push_back (artID); | ||||
| 			hut->quest.missionType = CQuest::MISSION_ART; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			hut->missionType = CQuest::MISSION_NONE; //no mission | ||||
| 			hut->quest.missionType = CQuest::MISSION_NONE; //no mission | ||||
| 		} | ||||
| 		hut->lastDay = -1; //no timeout | ||||
| 		hut->isCustomFirst = hut->isCustomNext = hut->isCustomComplete = false; | ||||
| 		hut->quest.lastDay = -1; //no timeout | ||||
| 		hut->quest.isCustomFirst = hut->quest.isCustomNext = hut->quest.isCustomComplete = false; | ||||
| 	} | ||||
|  | ||||
| 	if (hut->missionType) | ||||
| 	if (hut->quest.missionType) | ||||
| 	{ | ||||
| 		ui8 rewardType = bufor[i]; ++i; | ||||
| 		hut->rewardType = rewardType; | ||||
| @@ -1461,7 +1461,7 @@ void Mapa::readObjects( const ui8 * bufor, int &i) | ||||
| 		case 83: //seer's hut | ||||
| 			{ | ||||
| 				i = loadSeerHut(bufor, i, nobj); | ||||
| 				addQuest (dynamic_cast<CQuest *>(nobj)); | ||||
| 				addQuest (dynamic_cast<IQuestObject *>(nobj)); | ||||
| 				break; | ||||
| 			} | ||||
| 		case 113: //witch hut | ||||
| @@ -1722,7 +1722,7 @@ void Mapa::readObjects( const ui8 * bufor, int &i) | ||||
| 				CGQuestGuard *guard = new CGQuestGuard(); | ||||
| 				nobj = guard; | ||||
| 				loadQuest(guard, bufor, i); | ||||
| 				addQuest (dynamic_cast <CQuest *>(guard)); | ||||
| 				addQuest (dynamic_cast <IQuestObject *>(guard)); | ||||
| 				break; | ||||
| 			} | ||||
| 		case 28: //faerie ring | ||||
| @@ -1803,13 +1803,13 @@ void Mapa::readObjects( const ui8 * bufor, int &i) | ||||
| 		case 9: //Border Guard | ||||
| 			{ | ||||
| 				nobj = new CGBorderGuard(); | ||||
| 				addQuest (dynamic_cast<CQuest *>(nobj)); | ||||
| 				addQuest (dynamic_cast<IQuestObject *>(nobj)); | ||||
| 				break; | ||||
| 			} | ||||
| 		case 212: //Border Gate | ||||
| 			{ | ||||
| 				nobj = new CGBorderGate(); | ||||
| 				addQuest (dynamic_cast<CQuest *>(nobj)); | ||||
| 				addQuest (dynamic_cast<IQuestObject *>(nobj)); | ||||
| 				break; | ||||
| 			} | ||||
| 		case 27: case 37: //Eye and Hut of Magi | ||||
| @@ -1945,20 +1945,20 @@ bool Mapa::isInTheMap(const int3 &pos) const | ||||
| 	else return true; | ||||
| } | ||||
|  | ||||
| void Mapa::loadQuest(CQuest * guard, const ui8 * bufor, int & i) | ||||
| void Mapa::loadQuest(IQuestObject * guard, const ui8 * bufor, int & i) | ||||
| { | ||||
| 	guard->missionType = bufor[i]; ++i; | ||||
| 	guard->quest.missionType = bufor[i]; ++i; | ||||
| 	//int len1, len2, len3; | ||||
| 	switch(guard->missionType) | ||||
| 	switch(guard->quest.missionType) | ||||
| 	{ | ||||
| 	case 0: | ||||
| 		return; | ||||
| 	case 2: | ||||
| 		{ | ||||
| 			guard->m2stats.resize(4); | ||||
| 			guard->quest.m2stats.resize(4); | ||||
| 			for(int x=0; x<4; x++) | ||||
| 			{ | ||||
| 				guard->m2stats[x] = bufor[i++]; | ||||
| 				guard->quest.m2stats[x] = bufor[i++]; | ||||
| 			} | ||||
| 		} | ||||
| 		break; | ||||
| @@ -1966,7 +1966,7 @@ void Mapa::loadQuest(CQuest * guard, const ui8 * bufor, int & i) | ||||
| 	case 3: | ||||
| 	case 4: | ||||
| 		{ | ||||
| 			guard->m13489val = read_le_u32(bufor + i); i+=4; | ||||
| 			guard->quest.m13489val = read_le_u32(bufor + i); i+=4; | ||||
| 			break; | ||||
| 		} | ||||
| 	case 5: | ||||
| @@ -1975,7 +1975,7 @@ void Mapa::loadQuest(CQuest * guard, const ui8 * bufor, int & i) | ||||
| 			for(int yy=0; yy<artNumber; ++yy) | ||||
| 			{ | ||||
| 				int artid = read_le_u16(bufor + i); i+=2; | ||||
| 				guard->m5arts.push_back(artid);  | ||||
| 				guard->quest.m5arts.push_back(artid);  | ||||
| 				allowedArtifact[artid] = false; //these are unavailable for random generation | ||||
| 			} | ||||
| 			break; | ||||
| @@ -1983,20 +1983,20 @@ void Mapa::loadQuest(CQuest * guard, const ui8 * bufor, int & i) | ||||
| 	case 6: | ||||
| 		{ | ||||
| 			int typeNumber = bufor[i]; ++i; | ||||
| 			guard->m6creatures.resize(typeNumber); | ||||
| 			guard->quest.m6creatures.resize(typeNumber); | ||||
| 			for(int hh=0; hh<typeNumber; ++hh) | ||||
| 			{ | ||||
| 				guard->m6creatures[hh].type = VLC->creh->creatures[read_le_u16(bufor + i)]; i+=2; | ||||
| 				guard->m6creatures[hh].count = read_le_u16(bufor + i); i+=2; | ||||
| 				guard->quest.m6creatures[hh].type = VLC->creh->creatures[read_le_u16(bufor + i)]; i+=2; | ||||
| 				guard->quest.m6creatures[hh].count = read_le_u16(bufor + i); i+=2; | ||||
| 			} | ||||
| 			break; | ||||
| 		} | ||||
| 	case 7: | ||||
| 		{ | ||||
| 			guard->m7resources.resize(7); | ||||
| 			guard->quest.m7resources.resize(7); | ||||
| 			for(int x=0; x<7; x++) | ||||
| 			{ | ||||
| 				guard->m7resources[x] = read_le_u32(bufor + i);  | ||||
| 				guard->quest.m7resources[x] = read_le_u32(bufor + i);  | ||||
| 				i+=4; | ||||
| 			} | ||||
| 			break; | ||||
| @@ -2004,7 +2004,7 @@ void Mapa::loadQuest(CQuest * guard, const ui8 * bufor, int & i) | ||||
| 	case 8: | ||||
| 	case 9: | ||||
| 		{ | ||||
| 			guard->m13489val = bufor[i]; ++i; | ||||
| 			guard->quest.m13489val = bufor[i]; ++i; | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| @@ -2013,18 +2013,18 @@ void Mapa::loadQuest(CQuest * guard, const ui8 * bufor, int & i) | ||||
| 	int limit = read_le_u32(bufor + i); i+=4; | ||||
| 	if(limit == ((int)0xffffffff)) | ||||
| 	{ | ||||
| 		guard->lastDay = -1; | ||||
| 		guard->quest.lastDay = -1; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		guard->lastDay = limit; | ||||
| 		guard->quest.lastDay = limit; | ||||
| 	} | ||||
| 	guard->firstVisitText = readString(bufor,i); | ||||
| 	guard->nextVisitText = readString(bufor,i); | ||||
| 	guard->completedText = readString(bufor,i); | ||||
| 	guard->isCustomFirst = guard->firstVisitText.size() > 0; | ||||
| 	guard->isCustomNext = guard->nextVisitText.size() > 0; | ||||
| 	guard->isCustomComplete = guard->completedText.size() > 0; | ||||
| 	guard->quest.firstVisitText = readString(bufor,i); | ||||
| 	guard->quest.nextVisitText = readString(bufor,i); | ||||
| 	guard->quest.completedText = readString(bufor,i); | ||||
| 	guard->quest.isCustomFirst = guard->quest.firstVisitText.size() > 0; | ||||
| 	guard->quest.isCustomNext = guard->quest.nextVisitText.size() > 0; | ||||
| 	guard->quest.isCustomComplete = guard->quest.completedText.size() > 0; | ||||
| } | ||||
|  | ||||
| TerrainTile & Mapa::getTile( const int3 & tile ) | ||||
| @@ -2070,10 +2070,10 @@ void Mapa::addNewArtifactInstance( CArtifactInstance *art ) | ||||
| 	artInstances.push_back(art); | ||||
| } | ||||
|  | ||||
| void Mapa::addQuest (CQuest *quest) | ||||
| void Mapa::addQuest (IQuestObject *obj) | ||||
| { | ||||
| 	quest->qid = quests.size(); | ||||
| 	quests.push_back(quest); | ||||
| 	obj->quest.qid = quests.size(); | ||||
| 	quests.push_back(&obj->quest); | ||||
| } | ||||
|  | ||||
| bool Mapa::loadArtifactToSlot(CGHeroInstance *h, int slot, const ui8 * bufor, int &i) | ||||
|   | ||||
							
								
								
									
										20
									
								
								lib/map.h
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								lib/map.h
									
									
									
									
									
								
							| @@ -30,6 +30,7 @@ class CGCreature; | ||||
| class CQuest; | ||||
| class CGTownInstance; | ||||
| class IModableArt; | ||||
| class IQuestObject; | ||||
|  | ||||
| /// Struct which describes a single terrain tile | ||||
| struct DLL_LINKAGE TerrainTile | ||||
| @@ -306,7 +307,7 @@ struct DLL_LINKAGE Mapa : public CMapHeader | ||||
| 	std::vector< ConstTransitivePtr<CGHeroInstance> > heroes; | ||||
| 	std::vector< ConstTransitivePtr<CGTownInstance> > towns; | ||||
| 	std::vector< ConstTransitivePtr<CArtifactInstance> > artInstances; //stores all artifacts | ||||
| 	std::vector< ConstTransitivePtr<CQuest> > quests; | ||||
| 	std::vector< ConstTransitivePtr<CQuest> > quests; //FIXME: allow to serialize quests not related to objects | ||||
| 	//std::vector< ConstTransitivePtr<CCommanderInstance> > commanders; | ||||
| 	//bmap<ui16, ConstTransitivePtr<CGCreature> > monsters; | ||||
| 	//bmap<ui16, ConstTransitivePtr<CGHeroInstance> > heroesToBeat; | ||||
| @@ -317,7 +318,7 @@ struct DLL_LINKAGE Mapa : public CMapHeader | ||||
|  | ||||
| 	void readEvents( const ui8 * bufor, int &i); | ||||
| 	void readObjects( const ui8 * bufor, int &i); | ||||
| 	void loadQuest( CQuest * guard, const ui8 * bufor, int & i); | ||||
| 	void loadQuest( IQuestObject * guard, const ui8 * bufor, int & i); | ||||
| 	void readDefInfo( const ui8 * bufor, int &i); | ||||
| 	void readTerrain( const ui8 * bufor, int &i); | ||||
| 	void readPredefinedHeroes( const ui8 * bufor, int &i); | ||||
| @@ -331,7 +332,7 @@ struct DLL_LINKAGE Mapa : public CMapHeader | ||||
|  | ||||
| 	CArtifactInstance *createArt(int aid, int spellID = -1); | ||||
| 	void addNewArtifactInstance(CArtifactInstance *art); | ||||
| 	void addQuest (CQuest *quest); | ||||
| 	void addQuest (IQuestObject *quest); | ||||
| 	void eraseArtifactInstance(CArtifactInstance *art); | ||||
|  | ||||
|  | ||||
| @@ -447,11 +448,16 @@ struct DLL_LINKAGE Mapa : public CMapHeader | ||||
| 			for(ui32 i=0; i<objects.size(); i++) | ||||
| 			{ | ||||
| 				if(!objects[i]) continue; | ||||
| 				if(objects[i]->ID == GameConstants::HEROI_TYPE) | ||||
| 					heroes.push_back(static_cast<CGHeroInstance*>(+objects[i])); | ||||
| 				else if(objects[i]->ID == GameConstants::TOWNI_TYPE) | ||||
| 					towns.push_back(static_cast<CGTownInstance*>(+objects[i])); | ||||
|  | ||||
| 				switch (objects[i]->ID) | ||||
| 				{ | ||||
| 					case GameConstants::HEROI_TYPE: | ||||
| 						heroes.push_back (static_cast<CGHeroInstance*>(+objects[i])); | ||||
| 						break; | ||||
| 					case GameConstants::TOWNI_TYPE: | ||||
| 						towns.push_back (static_cast<CGTownInstance*>(+objects[i])); | ||||
| 						break; | ||||
| 				} | ||||
| 				addBlockVisTiles(objects[i]); //recreate blockvis map | ||||
| 			} | ||||
| 			for(ui32 i=0; i<heroes.size(); i++) //if hero is visiting/garrisoned in town set appropriate pointers | ||||
|   | ||||
		Reference in New Issue
	
	Block a user