mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Upgrade cost will never be negative.
This commit is contained in:
		| @@ -993,7 +993,17 @@ std::string CComponent::getSubtitleInternal() | ||||
| 	case resource:   return boost::lexical_cast<std::string>(val); | ||||
| 	case creature:   return (val? boost::lexical_cast<std::string>(val) + " " : "") + CGI->creh->creatures[subtype]->*(val != 1 ? &CCreature::namePl : &CCreature::nameSing); | ||||
| 	case artifact:   return CGI->arth->artifacts[subtype]->Name(); | ||||
| 	case experience: return (subtype && val==1) ? CGI->generaltexth->allTexts[442] : boost::lexical_cast<std::string>(val); | ||||
| 	case experience: | ||||
| 		{ | ||||
| 			if (subtype == 1) //+1 level - tree of knowledge | ||||
| 			{ | ||||
| 				std::string level = CGI->generaltexth->allTexts[442]; | ||||
| 				boost::replace_first(level, "1", boost::lexical_cast<std::string>(val)); | ||||
| 				return level; | ||||
| 			} | ||||
| 			else | ||||
| 				return boost::lexical_cast<std::string>(val); //amount of experience OR level required for seer hut; | ||||
| 		} | ||||
| 	case spell:      return CGI->spellh->spells[subtype]->name; | ||||
| 	case morale:     return ""; | ||||
| 	case luck:       return ""; | ||||
|   | ||||
| @@ -1728,6 +1728,9 @@ UpgradeInfo CGameState::getUpgradeInfo(const CStackInstance &stack) | ||||
| 	if(ret.newID.size()) | ||||
| 		ret.oldID = base->idNumber; | ||||
|  | ||||
| 	for (Res::ResourceSet &cost : ret.cost) | ||||
| 		cost.positive(); //upgrade cost can't be negative, ignore missing resources | ||||
|  | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -241,10 +241,10 @@ CGeneralTextHandler::CGeneralTextHandler() | ||||
|  | ||||
| 		//skip header | ||||
| 		parser.endLine(); | ||||
| 		parser.endLine(); | ||||
|  | ||||
| 		for (int i = 0; i < 6; ++i) | ||||
| 			seerEmpty.push_back(parser.readString()); | ||||
| 		parser.endLine(); | ||||
|  | ||||
| 		quests.resize(10); | ||||
| 		for (int i = 0; i < 9; ++i) //9 types of quests | ||||
|   | ||||
| @@ -4390,17 +4390,17 @@ void CQuest::getVisitText (MetaString &iwText, std::vector<Component> &component | ||||
| 	if (firstVisit) | ||||
| 	{ | ||||
| 		isCustom = isCustomFirst; | ||||
| 		iwText << firstVisitText; | ||||
| 		iwText << (text = firstVisitText); | ||||
| 	} | ||||
| 	else if (failRequirements) | ||||
| 	{ | ||||
| 		isCustom = isCustomNext; | ||||
| 		iwText << nextVisitText; | ||||
| 		iwText << (text = nextVisitText); | ||||
| 	} | ||||
| 	switch (missionType) | ||||
| 	{ | ||||
| 		case MISSION_LEVEL: | ||||
| 			components.push_back(Component (Component::EXPERIENCE, 1, m13489val, 0)); | ||||
| 			components.push_back(Component (Component::EXPERIENCE, 0, m13489val, 0)); | ||||
| 			if (!isCustom) | ||||
| 				iwText.addReplacement(m13489val); | ||||
| 			break; | ||||
| @@ -4435,7 +4435,9 @@ void CQuest::getVisitText (MetaString &iwText, std::vector<Component> &component | ||||
| 			{ | ||||
| 				components.push_back(Component(stackToKill)); | ||||
| 				if (!isCustom) | ||||
| 				{ | ||||
| 					addReplacements(iwText, text); | ||||
| 				} | ||||
| 			} | ||||
| 			break; | ||||
| 		case MISSION_ART: | ||||
| @@ -4687,7 +4689,10 @@ void CGSeerHut::initObj() | ||||
| 			quest->completedText = VLC->generaltexth->quests[quest->missionType-1][2][quest->textOption]; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		quest->progress = CQuest::COMPLETE; | ||||
| 		quest->firstVisitText = VLC->generaltexth->seerEmpty[quest->textOption]; | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| @@ -4788,17 +4793,13 @@ void CGSeerHut::setPropertyDer (ui8 what, ui32 val) | ||||
| 		case 10: | ||||
| 			quest->progress = static_cast<CQuest::Eprogress>(val); | ||||
| 			break; | ||||
| 		case 11: | ||||
| 			quest->missionType = CQuest::MISSION_NONE; | ||||
| 			break; | ||||
| 	} | ||||
| } | ||||
| void CGSeerHut::newTurn() const | ||||
| { | ||||
| 	if (quest->lastDay >= 0 && quest->lastDay < cb->getDate()) //time is up | ||||
| 	if (quest->lastDay >= 0 && quest->lastDay < cb->getDate()-1) //time is up | ||||
| 	{ | ||||
| 		cb->setObjProperty (id, 11, 0); | ||||
| 		cb->setObjProperty (id, 10, 0); | ||||
| 		cb->setObjProperty (id, 10, CQuest::COMPLETE); | ||||
| 	} | ||||
|  | ||||
| } | ||||
| @@ -4806,7 +4807,7 @@ void CGSeerHut::onHeroVisit( const CGHeroInstance * h ) const | ||||
| { | ||||
| 	InfoWindow iw; | ||||
| 	iw.player = h->getOwner(); | ||||
| 	if (quest->missionType) | ||||
| 	if (quest->progress < CQuest::COMPLETE) | ||||
| 	{ | ||||
| 		bool firstVisit = !quest->progress; | ||||
| 		bool failRequirements = !checkQuest(h); | ||||
| @@ -4908,9 +4909,8 @@ void CGSeerHut::finishQuest(const CGHeroInstance * h, ui32 accept) const | ||||
| 			default: | ||||
| 				break; | ||||
| 		} | ||||
| 		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 | ||||
| 		cb->setObjProperty (id, 10, CQuest::COMPLETE); //mission complete | ||||
| 		completeQuest(h); //make sure to remove QuestGuard at the very end | ||||
| 	} | ||||
| } | ||||
| void CGSeerHut::completeQuest (const CGHeroInstance * h) const //reward | ||||
|   | ||||
| @@ -335,10 +335,10 @@ DLL_LINKAGE void RemoveObject::applyGs( CGameState *gs ) | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	auto quest = dynamic_cast<const CQuest *>(obj); | ||||
| 	auto quest = dynamic_cast<const IQuestObject *>(obj); | ||||
| 	if (quest) | ||||
| 	{ | ||||
| 		gs->map->quests[quest->qid] = nullptr; | ||||
| 		gs->map->quests[quest->quest->qid] = nullptr; | ||||
| 		for (auto &player : gs->players) | ||||
| 		{ | ||||
| 			for (auto &q : player.second.quests) | ||||
| @@ -349,7 +349,6 @@ DLL_LINKAGE void RemoveObject::applyGs( CGameState *gs ) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		//gs->map->quests[quest->qid].dellNull(); | ||||
| 	} | ||||
|  | ||||
| 	gs->map->objects[id.getNum()].dellNull(); | ||||
|   | ||||
| @@ -40,6 +40,12 @@ void Res::ResourceSet::amax(const TResourceCap &val) | ||||
| 		::vstd::amax(elem, val); | ||||
| } | ||||
|  | ||||
| void Res::ResourceSet::positive() | ||||
| { | ||||
| 	for(auto & elem : *this) | ||||
| 		::vstd::amax(elem, 0); | ||||
| } | ||||
|  | ||||
| bool Res::ResourceSet::canBeAfforded(const ResourceSet &res) const | ||||
| { | ||||
| 	return Res::canAfford(res, *this); | ||||
|   | ||||
| @@ -125,6 +125,7 @@ namespace Res | ||||
| 		} | ||||
|  | ||||
| 		DLL_LINKAGE void amax(const TResourceCap &val); //performs vstd::amax on each element | ||||
| 		DLL_LINKAGE void positive(); //values below 0 are set to 0 - upgrade cost can't be negative, for example | ||||
| 		DLL_LINKAGE bool nonZero() const; //returns true if at least one value is non-zero; | ||||
| 		DLL_LINKAGE bool canAfford(const ResourceSet &price) const; | ||||
| 		DLL_LINKAGE bool canBeAfforded(const ResourceSet &res) const; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user