diff --git a/client/GUIClasses.cpp b/client/GUIClasses.cpp index e6c0cff67..3cd97554a 100644 --- a/client/GUIClasses.cpp +++ b/client/GUIClasses.cpp @@ -993,7 +993,17 @@ std::string CComponent::getSubtitleInternal() case resource: return boost::lexical_cast(val); case creature: return (val? boost::lexical_cast(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(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(val)); + return level; + } + else + return boost::lexical_cast(val); //amount of experience OR level required for seer hut; + } case spell: return CGI->spellh->spells[subtype]->name; case morale: return ""; case luck: return ""; diff --git a/lib/CGameState.cpp b/lib/CGameState.cpp index c2d585452..4b7456b70 100644 --- a/lib/CGameState.cpp +++ b/lib/CGameState.cpp @@ -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; } diff --git a/lib/CGeneralTextHandler.cpp b/lib/CGeneralTextHandler.cpp index 73095ce54..81bbf3aca 100644 --- a/lib/CGeneralTextHandler.cpp +++ b/lib/CGeneralTextHandler.cpp @@ -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 diff --git a/lib/CObjectHandler.cpp b/lib/CObjectHandler.cpp index 538fc7ad6..1daa1823f 100644 --- a/lib/CObjectHandler.cpp +++ b/lib/CObjectHandler.cpp @@ -4390,17 +4390,17 @@ void CQuest::getVisitText (MetaString &iwText, std::vector &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 { 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(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 diff --git a/lib/NetPacksLib.cpp b/lib/NetPacksLib.cpp index b24ec9aa2..eab7546cf 100644 --- a/lib/NetPacksLib.cpp +++ b/lib/NetPacksLib.cpp @@ -335,10 +335,10 @@ DLL_LINKAGE void RemoveObject::applyGs( CGameState *gs ) return; } - auto quest = dynamic_cast(obj); + auto quest = dynamic_cast(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(); diff --git a/lib/ResourceSet.cpp b/lib/ResourceSet.cpp index 5605e41c8..42fb44862 100644 --- a/lib/ResourceSet.cpp +++ b/lib/ResourceSet.cpp @@ -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); diff --git a/lib/ResourceSet.h b/lib/ResourceSet.h index 556fccecd..98f629ede 100644 --- a/lib/ResourceSet.h +++ b/lib/ResourceSet.h @@ -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;