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

Fixed all the issues with Quests, #828 and #1223.

Upgrade cost will never be negative.
This commit is contained in:
DjWarmonger 2013-07-23 15:03:01 +00:00
parent b1a569910b
commit 66d6aebe32
7 changed files with 37 additions and 18 deletions

View File

@ -993,7 +993,17 @@ std::string CComponent::getSubtitleInternal()
case resource: return boost::lexical_cast<std::string>(val); 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 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 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 spell: return CGI->spellh->spells[subtype]->name;
case morale: return ""; case morale: return "";
case luck: return ""; case luck: return "";

View File

@ -1728,6 +1728,9 @@ UpgradeInfo CGameState::getUpgradeInfo(const CStackInstance &stack)
if(ret.newID.size()) if(ret.newID.size())
ret.oldID = base->idNumber; ret.oldID = base->idNumber;
for (Res::ResourceSet &cost : ret.cost)
cost.positive(); //upgrade cost can't be negative, ignore missing resources
return ret; return ret;
} }

View File

@ -241,10 +241,10 @@ CGeneralTextHandler::CGeneralTextHandler()
//skip header //skip header
parser.endLine(); parser.endLine();
parser.endLine();
for (int i = 0; i < 6; ++i) for (int i = 0; i < 6; ++i)
seerEmpty.push_back(parser.readString()); seerEmpty.push_back(parser.readString());
parser.endLine();
quests.resize(10); quests.resize(10);
for (int i = 0; i < 9; ++i) //9 types of quests for (int i = 0; i < 9; ++i) //9 types of quests

View File

@ -4390,17 +4390,17 @@ void CQuest::getVisitText (MetaString &iwText, std::vector<Component> &component
if (firstVisit) if (firstVisit)
{ {
isCustom = isCustomFirst; isCustom = isCustomFirst;
iwText << firstVisitText; iwText << (text = firstVisitText);
} }
else if (failRequirements) else if (failRequirements)
{ {
isCustom = isCustomNext; isCustom = isCustomNext;
iwText << nextVisitText; iwText << (text = nextVisitText);
} }
switch (missionType) switch (missionType)
{ {
case MISSION_LEVEL: case MISSION_LEVEL:
components.push_back(Component (Component::EXPERIENCE, 1, m13489val, 0)); components.push_back(Component (Component::EXPERIENCE, 0, m13489val, 0));
if (!isCustom) if (!isCustom)
iwText.addReplacement(m13489val); iwText.addReplacement(m13489val);
break; break;
@ -4435,8 +4435,10 @@ void CQuest::getVisitText (MetaString &iwText, std::vector<Component> &component
{ {
components.push_back(Component(stackToKill)); components.push_back(Component(stackToKill));
if (!isCustom) if (!isCustom)
{
addReplacements(iwText, text); addReplacements(iwText, text);
} }
}
break; break;
case MISSION_ART: case MISSION_ART:
{ {
@ -4687,7 +4689,10 @@ void CGSeerHut::initObj()
quest->completedText = VLC->generaltexth->quests[quest->missionType-1][2][quest->textOption]; quest->completedText = VLC->generaltexth->quests[quest->missionType-1][2][quest->textOption];
} }
else else
{
quest->progress = CQuest::COMPLETE;
quest->firstVisitText = VLC->generaltexth->seerEmpty[quest->textOption]; quest->firstVisitText = VLC->generaltexth->seerEmpty[quest->textOption];
}
} }
@ -4788,17 +4793,13 @@ void CGSeerHut::setPropertyDer (ui8 what, ui32 val)
case 10: case 10:
quest->progress = static_cast<CQuest::Eprogress>(val); quest->progress = static_cast<CQuest::Eprogress>(val);
break; break;
case 11:
quest->missionType = CQuest::MISSION_NONE;
break;
} }
} }
void CGSeerHut::newTurn() const 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, CQuest::COMPLETE);
cb->setObjProperty (id, 10, 0);
} }
} }
@ -4806,7 +4807,7 @@ void CGSeerHut::onHeroVisit( const CGHeroInstance * h ) const
{ {
InfoWindow iw; InfoWindow iw;
iw.player = h->getOwner(); iw.player = h->getOwner();
if (quest->missionType) if (quest->progress < CQuest::COMPLETE)
{ {
bool firstVisit = !quest->progress; bool firstVisit = !quest->progress;
bool failRequirements = !checkQuest(h); bool failRequirements = !checkQuest(h);
@ -4908,9 +4909,8 @@ void CGSeerHut::finishQuest(const CGHeroInstance * h, ui32 accept) const
default: default:
break; break;
} }
cb->setObjProperty (id, 10, CQuest::COMPLETE); //mission complete - for AI cb->setObjProperty (id, 10, CQuest::COMPLETE); //mission complete
cb->setObjProperty (id, 11, 0); //no more mission available - redundant? completeQuest(h); //make sure to remove QuestGuard at the very end
completeQuest(h); //make sure to remove QuestQuard at the very end
} }
} }
void CGSeerHut::completeQuest (const CGHeroInstance * h) const //reward void CGSeerHut::completeQuest (const CGHeroInstance * h) const //reward

View File

@ -335,10 +335,10 @@ DLL_LINKAGE void RemoveObject::applyGs( CGameState *gs )
return; return;
} }
auto quest = dynamic_cast<const CQuest *>(obj); auto quest = dynamic_cast<const IQuestObject *>(obj);
if (quest) if (quest)
{ {
gs->map->quests[quest->qid] = nullptr; gs->map->quests[quest->quest->qid] = nullptr;
for (auto &player : gs->players) for (auto &player : gs->players)
{ {
for (auto &q : player.second.quests) 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(); gs->map->objects[id.getNum()].dellNull();

View File

@ -40,6 +40,12 @@ void Res::ResourceSet::amax(const TResourceCap &val)
::vstd::amax(elem, 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 bool Res::ResourceSet::canBeAfforded(const ResourceSet &res) const
{ {
return Res::canAfford(res, *this); return Res::canAfford(res, *this);

View File

@ -125,6 +125,7 @@ namespace Res
} }
DLL_LINKAGE void amax(const TResourceCap &val); //performs vstd::amax on each element 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 nonZero() const; //returns true if at least one value is non-zero;
DLL_LINKAGE bool canAfford(const ResourceSet &price) const; DLL_LINKAGE bool canAfford(const ResourceSet &price) const;
DLL_LINKAGE bool canBeAfforded(const ResourceSet &res) const; DLL_LINKAGE bool canBeAfforded(const ResourceSet &res) const;