1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-07-03 00:46:55 +02:00

Various fixes and improvements around kill hero and kill monster quests. A few minor unrelated fixes.

This commit is contained in:
Michał W. Urbańczyk
2011-02-11 12:27:38 +00:00
parent c0f2b3f32b
commit ab20e024c0
12 changed files with 149 additions and 100 deletions

View File

@ -1116,6 +1116,7 @@ void CGHeroInstance::initObj()
UpdateSpeciality();
mana = manaLimit(); //after all bonuses are taken into account, make sure this line is the last one
type->name = name;
}
void CGHeroInstance::UpdateSpeciality()
{
@ -3871,12 +3872,10 @@ bool CQuest::checkQuest (const CGHeroInstance * h) const
{
case MISSION_NONE:
return true;
break;
case MISSION_LEVEL:
if (m13489val <= h->level)
return true;
return false;
break;
case MISSION_PRIMARY_STAT:
for (int i = 0; i < 4; ++i)
{
@ -3884,17 +3883,11 @@ bool CQuest::checkQuest (const CGHeroInstance * h) const
return false;
}
return true;
break;
case MISSION_KILL_HERO:
if (h->cb->gameState()->map->heroesToBeat[m13489val]->tempOwner < PLAYER_LIMIT)
return false; //if the pointer is not NULL
return true;
break;
case MISSION_KILL_CREATURE:
if (h->cb->gameState()->map->monsters[m13489val]->pos == int3(-1,-1,-1))
if (!h->cb->getObjByQuestIdentifier(m13489val))
return true;
return false;
break;
case MISSION_ART:
for (int i = 0; i < m5arts.size(); ++i)
{
@ -3903,7 +3896,6 @@ bool CQuest::checkQuest (const CGHeroInstance * h) const
return false; //if the artifact was not found
}
return true;
break;
case MISSION_ARMY:
{
std::vector<CStackBasicDescriptor>::const_iterator cre;
@ -3921,7 +3913,6 @@ bool CQuest::checkQuest (const CGHeroInstance * h) const
}
}
return true;
break;
case MISSION_RESOURCES:
for (int i = 0; i < 7; ++i) //including Mithril ?
{ //Quest has no direct access to callback
@ -3929,17 +3920,14 @@ bool CQuest::checkQuest (const CGHeroInstance * h) const
return false;
}
return true;
break;
case MISSION_HERO:
if (m13489val == h->type->ID)
return true;
return false;
break;
case MISSION_PLAYER:
if (m13489val == h->getOwner())
return true;
return false;
break;
default:
return false;
}
@ -3958,6 +3946,17 @@ void CGSeerHut::initObj()
nextVisitText = VLC->generaltexth->quests[missionType-1][1][textOption];
completedText = VLC->generaltexth->quests[missionType-1][2][textOption];
}
if(missionType == MISSION_KILL_CREATURE)
{
stackToKill = getCreatureToKill(false)->getStack(0);
stackDirection = checkDirection();
}
else if(missionType == MISSION_KILL_HERO)
{
heroName = getHeroToKill(false)->name;
heroPortrait = getHeroToKill(false)->portrait;
}
}
else
firstVisitText = VLC->generaltexth->seerEmpty[textOption];
@ -3989,30 +3988,25 @@ const std::string & CGSeerHut::getHoverText() const
ms.addReplacement(m13489val);
break;
case MISSION_PRIMARY_STAT:
{
MetaString loot;
for (int i = 0; i < 4; ++i)
{
if (m2stats[i])
MetaString loot;
for (int i = 0; i < 4; ++i)
{
loot << "%d %s";
loot.addReplacement(m2stats[i]);
loot.addReplacement(VLC->generaltexth->primarySkillNames[i]);
}
if (m2stats[i])
{
loot << "%d %s";
loot.addReplacement(m2stats[i]);
loot.addReplacement(VLC->generaltexth->primarySkillNames[i]);
}
}
ms.addReplacement(loot.buildList());
}
ms.addReplacement(loot.buildList());
}
break;
case MISSION_KILL_HERO:
ms.addReplacement(cb->gameState()->map->heroesToBeat[m13489val]->name);
break;
case MISSION_HERO:
ms.addReplacement(VLC->heroh->heroes[m13489val]->name);
ms.addReplacement(heroName);
break;
case MISSION_KILL_CREATURE:
{
ms.addReplacement(cb->gameState()->map->monsters[m13489val]->getStack(0));
}
ms.addReplacement(stackToKill);
break;
case MISSION_ART:
{
@ -4051,6 +4045,9 @@ const std::string & CGSeerHut::getHoverText() const
ms.addReplacement(loot.buildList());
}
break;
case MISSION_HERO:
ms.addReplacement(VLC->heroh->heroes[m13489val]->name);
break;
case MISSION_PLAYER:
ms.addReplacement(VLC->generaltexth->colors[m13489val]);
break;
@ -4096,7 +4093,7 @@ void CGSeerHut::onHeroVisit( const CGHeroInstance * h ) const
switch (missionType)
{
case MISSION_LEVEL:
iw.components.push_back (Component (Component::EXPERIENCE, 1, m13489val, 0));
iw.components.push_back(Component (Component::EXPERIENCE, 1, m13489val, 0));
if (!isCustom)
iw.text.addReplacement(m13489val);
break;
@ -4107,7 +4104,7 @@ void CGSeerHut::onHeroVisit( const CGHeroInstance * h ) const
{
if (m2stats[i])
{
iw.components.push_back (Component (Component::PRIM_SKILL, i, m2stats[i], 0));
iw.components.push_back(Component (Component::PRIM_SKILL, i, m2stats[i], 0));
loot << "%d %s";
loot.addReplacement(m2stats[i]);
loot.addReplacement(VLC->generaltexth->primarySkillNames[i]);
@ -4118,28 +4115,20 @@ void CGSeerHut::onHeroVisit( const CGHeroInstance * h ) const
}
break;
case MISSION_KILL_HERO:
iw.components.push_back (Component (Component::HERO,
cb->gameState()->map->heroesToBeat[m13489val]->type->ID, 0, 0));
iw.components.push_back(Component(Component::HERO, heroPortrait, 0, 0));
if (!isCustom)
iw.text.addReplacement(cb->gameState()->map->heroesToBeat[m13489val]->name);
addReplacements(iw.text, firstVisitText);
break;
case MISSION_HERO:
iw.components.push_back (Component (Component::HERO, m13489val, 0, 0));
iw.components.push_back(Component (Component::HERO, m13489val, 0, 0));
if (!isCustom)
iw.text.addReplacement(VLC->heroh->heroes[m13489val]->name);
break;
case MISSION_KILL_CREATURE:
{
CStackInstance stack = cb->gameState()->map->monsters[m13489val]->getStack(0);
iw.components.push_back (Component(stack));
iw.components.push_back(Component(stackToKill));
if (!isCustom)
{
iw.text.addReplacement(stack);
if (std::count(firstVisitText.begin(), firstVisitText.end(), '%') == 2) //say where is placed monster
{
iw.text.addReplacement(VLC->generaltexth->arraytxt[147+checkDirection()]);
}
}
addReplacements(iw.text, firstVisitText);
}
break;
case MISSION_ART:
@ -4147,12 +4136,12 @@ void CGSeerHut::onHeroVisit( const CGHeroInstance * h ) const
MetaString loot;
for (std::vector<ui16>::const_iterator it = m5arts.begin(); it != m5arts.end(); ++it)
{
iw.components.push_back (Component (Component::ARTIFACT, *it, 0, 0));
iw.components.push_back(Component (Component::ARTIFACT, *it, 0, 0));
loot << "%s";
loot.addReplacement(MetaString::ART_NAMES, *it);
}
if (!isCustom)
iw.text.addReplacement (loot.buildList());
iw.text.addReplacement(loot.buildList());
}
break;
case MISSION_ARMY:
@ -4165,7 +4154,7 @@ void CGSeerHut::onHeroVisit( const CGHeroInstance * h ) const
loot.addReplacement(*it);
}
if (!isCustom)
iw.text.addReplacement (loot.buildList());
iw.text.addReplacement(loot.buildList());
}
break;
case MISSION_RESOURCES:
@ -4175,20 +4164,20 @@ void CGSeerHut::onHeroVisit( const CGHeroInstance * h ) const
{
if (m7resources[i])
{
iw.components.push_back (Component (Component::RESOURCE, i, m7resources[i], 0));
iw.components.push_back(Component (Component::RESOURCE, i, m7resources[i], 0));
loot << "%d %s";
loot.addReplacement(m7resources[i]);
loot.addReplacement(MetaString::RES_NAMES, i);
}
}
if (!isCustom)
iw.text.addReplacement (loot.buildList());
iw.text.addReplacement(loot.buildList());
}
break;
case MISSION_PLAYER:
iw.components.push_back (Component (Component::FLAG, m13489val, 0, 0));
iw.components.push_back(Component (Component::FLAG, m13489val, 0, 0));
if (!isCustom)
iw.text.addReplacement (VLC->generaltexth->colors[m13489val]);
iw.text.addReplacement(VLC->generaltexth->colors[m13489val]);
break;
}
cb->setObjProperty (id,10,1);
@ -4197,6 +4186,8 @@ void CGSeerHut::onHeroVisit( const CGHeroInstance * h ) const
else if (!checkQuest(h))
{
iw.text << nextVisitText;
if(!isCustom)
addReplacements(iw.text, nextVisitText);
cb->showInfoDialog(&iw);
}
if (checkQuest(h)) // propose completion, also on first visit
@ -4269,23 +4260,14 @@ void CGSeerHut::onHeroVisit( const CGHeroInstance * h ) const
}
break;
case MISSION_KILL_HERO:
case MISSION_KILL_CREATURE:
if (!isCustom)
bd.text.addReplacement(cb->gameState()->map->heroesToBeat[m13489val]->name);
addReplacements(bd.text, completedText);
break;
case MISSION_HERO:
if (!isCustom)
bd.text.addReplacement(VLC->heroh->heroes[m13489val]->name);
break;
case MISSION_KILL_CREATURE:
{
{
bd.text.addReplacement(cb->gameState()->map->monsters[m13489val]->getArmy()[0]);
if (std::count(firstVisitText.begin(), firstVisitText.end(), '%') == 2) //say where is placed monster
{
bd.text.addReplacement(VLC->generaltexth->arraytxt[147+checkDirection()]);
}
}
}
case MISSION_PLAYER:
if (!isCustom)
bd.text.addReplacement(VLC->generaltexth->colors[m13489val]);
@ -4294,25 +4276,25 @@ void CGSeerHut::onHeroVisit( const CGHeroInstance * h ) const
switch (rewardType)
{
case 1: bd.components.push_back (Component (Component::EXPERIENCE, 0, rVal*(100+h->getSecSkillLevel(CGHeroInstance::LEARNING)*5)/100.0f, 0));
case 1: bd.components.push_back(Component (Component::EXPERIENCE, 0, rVal*(100+h->getSecSkillLevel(CGHeroInstance::LEARNING)*5)/100.0f, 0));
break;
case 2: bd.components.push_back (Component (Component::PRIM_SKILL, 5, rVal, 0));
case 2: bd.components.push_back(Component (Component::PRIM_SKILL, 5, rVal, 0));
break;
case 3: bd.components.push_back (Component (Component::MORALE, 0, rVal, 0));
case 3: bd.components.push_back(Component (Component::MORALE, 0, rVal, 0));
break;
case 4: bd.components.push_back (Component (Component::LUCK, 0, rVal, 0));
case 4: bd.components.push_back(Component (Component::LUCK, 0, rVal, 0));
break;
case 5: bd.components.push_back (Component (Component::RESOURCE, rID, rVal, 0));
case 5: bd.components.push_back(Component (Component::RESOURCE, rID, rVal, 0));
break;
case 6: bd.components.push_back (Component (Component::PRIM_SKILL, rID, rVal, 0));
case 6: bd.components.push_back(Component (Component::PRIM_SKILL, rID, rVal, 0));
break;
case 7: bd.components.push_back (Component (Component::SEC_SKILL, rID, rVal, 0));
case 7: bd.components.push_back(Component (Component::SEC_SKILL, rID, rVal, 0));
break;
case 8: bd.components.push_back (Component (Component::ARTIFACT, rID, 0, 0));
case 8: bd.components.push_back(Component (Component::ARTIFACT, rID, 0, 0));
break;
case 9: bd.components.push_back (Component (Component::SPELL, rID, 0, 0));
case 9: bd.components.push_back(Component (Component::SPELL, rID, 0, 0));
break;
case 10: bd.components.push_back (Component (Component::CREATURE, rID, rVal, 0));
case 10: bd.components.push_back(Component (Component::CREATURE, rID, rVal, 0));
break;
}
@ -4330,7 +4312,7 @@ void CGSeerHut::onHeroVisit( const CGHeroInstance * h ) const
}
int CGSeerHut::checkDirection() const
{
int3 cord = cb->gameState()->map->monsters[m13489val]->pos;
int3 cord = getCreatureToKill()->pos;
if ((double)cord.x/(double)cb->getMapSize().x < 0.34) //north
{
if ((double)cord.y/(double)cb->getMapSize().y < 0.34) //northwest
@ -4443,6 +4425,41 @@ void CGSeerHut::completeQuest (const CGHeroInstance * h) const //reward
}
}
const CGHeroInstance * CGSeerHut::getHeroToKill(bool allowNull) const
{
const CGObjectInstance *o = cb->getObjByQuestIdentifier(m13489val);
if(allowNull && !o)
return NULL;
assert(o && o->ID == HEROI_TYPE);
return static_cast<const CGHeroInstance*>(o);
}
const CGCreature * CGSeerHut::getCreatureToKill(bool allowNull) const
{
const CGObjectInstance *o = cb->getObjByQuestIdentifier(m13489val);
if(allowNull && !o)
return NULL;
assert(o && o->ID == 54);
return static_cast<const CGCreature*>(o);
}
void CGSeerHut::addReplacements(MetaString &out, const std::string &base) const
{
switch(missionType)
{
case MISSION_KILL_CREATURE:
out.addReplacement(stackToKill);
if (std::count(base.begin(), base.end(), '%') == 2) //say where is placed monster
{
out.addReplacement(VLC->generaltexth->arraytxt[147+stackDirection]);
}
break;
case MISSION_KILL_HERO:
out.addReplacement(heroName);
break;
}
}
void CGQuestGuard::initObj()
{
blockVisit = true;