1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-02-03 13:01:33 +02:00

Last part of Seer Hut & Quest Guard code:

1.Required artifacts & army are now taken on completion.
2.Hoover tooltip.
3.Fixed bugs.
This commit is contained in:
DjWarmonger 2010-02-07 16:05:27 +00:00
parent 69bed4a8d6
commit 53365af90e
9 changed files with 221 additions and 80 deletions

View File

@ -84,7 +84,7 @@ public:
void showThievesGuildWindow(int requestingObjId){};
void giveResource(int player, int which, int val){};
void giveCreatures (int objid, const CGHeroInstance * h, CCreatureSet creatures) {};
void takeCreatures (int objid, CCreatureSet creatures){};
void takeCreatures (int objid, TSlots creatures){};
void showCompInfo(ShowInInfobox * comp){};
void heroVisitCastle(int obj, int heroID){};
void stopHeroVisitCastle(int obj, int heroID){};

View File

@ -150,15 +150,6 @@ namespace vstd
{
return c.find(i)!=c.end();
}
#if 0
template <typename V, typename Item, typename Item2>
bool contains2(const std::map<Item,V> & c, const Item2 &i) //returns true if map c leads to item i
{
for (std::map<Item,V>::const_iterator it = c.begin(); it!= c.end(); ++it)
if (it->second == i) return true;
return false;
}
#endif
template <typename Container1, typename Container2>
typename Container2::iterator findFirstNot(Container1 &c1, Container2 &c2)//returns first element of c2 not present in c1
{

View File

@ -3176,9 +3176,9 @@ bool CQuest::checkQuest (const CGHeroInstance * h) const
return true;
break;
case MISSION_KILL_CREATURE:
if (h->cb->gameState()->map->monsters[m13489val])
return false;
return true;
if (h->cb->gameState()->map->monsters[m13489val]->pos == int3(-1,-1,-1))
return true;
return false;
break;
case MISSION_ART:
for (int i = 0; i < m5arts.size(); ++i)
@ -3245,9 +3245,80 @@ void CGSeerHut::initObj()
const std::string & CGSeerHut::getHoverText() const
{
hoverName = VLC->generaltexth->allTexts[347];
boost::algorithm::replace_first(hoverName,"%s", seerName);
if (progress){}//what does it seek for?
switch (ID)
{
case 83:
hoverName = VLC->generaltexth->allTexts[347];
boost::algorithm::replace_first(hoverName,"%s", seerName);
break;
case 215:
hoverName = VLC->generaltexth->names[ID];
break;
default:
tlog5 << "unrecognized quest object\n";
}
if (progress & missionType) //rollover when the quest is active
{
MetaString ms;
ms << "\n\n" << VLC->generaltexth->quests[missionType-1][3][textOption];
std::string str;
switch (missionType)
{
case MISSION_LEVEL:
ms.addReplacement (m13489val);
break;
case MISSION_PRIMARY_STAT:
{
MetaString loot;
for (int i = 0; i < 4; ++i)
{
if (m2stats[i])
{
loot << "%d %s";
loot.addReplacement (m2stats[i]);
loot.addReplacement (VLC->generaltexth->primarySkillNames[i]);
}
}
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);
break;
case MISSION_KILL_CREATURE:
{
const TStack* stack = cb->gameState()->map->monsters[m13489val]->army.getStack(0);
if (stack->first == 1)
ms.addReplacement (MetaString::CRE_SING_NAMES, stack->first);
else
ms.addReplacement (MetaString::CRE_PL_NAMES, stack->first);
}
break;
case MISSION_ART:
{
MetaString loot;
for (std::vector<ui16>::const_iterator it = m5arts.begin(); it != m5arts.end(); ++it)
{
loot << "%s";
loot.addReplacement (MetaString::ART_NAMES, *it);
}
ms.addReplacement(loot.buildList());
}
break;
case MISSION_ARMY:
case MISSION_RESOURCES:
case MISSION_PLAYER:
ms.addReplacement (VLC->generaltexth->colors[m13489val]);
break;
default:
break;
}
ms.toString(str);
hoverName += str;
}
return hoverName;
}
@ -3375,57 +3446,104 @@ void CGSeerHut::onHeroVisit( const CGHeroInstance * h ) const
break;
}
cb->setObjProperty (id,10,1);
cb->showInfoDialog(&iw);
}
else
else if (!checkQuest(h))
{
if (!checkQuest(h))
iw.text << nextVisitText;
else
iw.text << nextVisitText;
cb->showInfoDialog(&iw);
}
if (checkQuest(h)) // propose completion, also on first visit
{
BlockingDialog bd (true, false);
bd.player = h->getOwner();
bd.soundID = soundBase::QUEST;
bd.text << completedText;
switch (missionType)
{
BlockingDialog bd (true, false);
bd.player = h->getOwner();
bd.soundID = soundBase::QUEST;
bd.text << completedText;
switch (missionType)
{
case CQuest::MISSION_LEVEL:
bd.text.addReplacement(m13489val);
break;
case CQuest::MISSION_PRIMARY_STAT:
if (vstd::contains (completedText,'%')) //there's one case when there's nothing to replace
case CQuest::MISSION_LEVEL:
bd.text.addReplacement(m13489val);
break;
case CQuest::MISSION_PRIMARY_STAT:
if (vstd::contains (completedText,'%')) //there's one case when there's nothing to replace
{
MetaString loot;
for (int i = 0; i < 4; ++i)
{
MetaString loot;
for (int i = 0; i < 4; ++i)
if (m2stats[i])
{
if (m2stats[i])
{
loot << "%d %s";
loot.addReplacement (m2stats[i]);
loot.addReplacement (VLC->generaltexth->primarySkillNames[i]);
}
loot << "%d %s";
loot.addReplacement (m2stats[i]);
loot.addReplacement (VLC->generaltexth->primarySkillNames[i]);
}
bd.text.addReplacement (loot.buildList());
}
break;
case CQuest::MISSION_ART:
for (std::vector<ui16>::const_iterator it = m5arts.begin(); it != m5arts.end(); ++it)
bd.components.push_back (Component (Component::ARTIFACT, *it, 0, 0));
break;
case CQuest::MISSION_ARMY:
for (TSlots::const_iterator it = m6creatures.begin(); it != m6creatures.end(); ++it)
bd.components.push_back (Component (Component::CREATURE, it->second.first, it->second.second, 0));
break;
case CQuest::MISSION_RESOURCES:
for (int i = 0; i < 7; ++i)
{
if (m7resources[i])
bd.components.push_back (Component (Component::RESOURCE, i, m7resources[i], 0));
}
break;
bd.text.addReplacement (loot.buildList());
}
break;
case CQuest::MISSION_ART:
{
MetaString loot;
for (std::vector<ui16>::const_iterator it = m5arts.begin(); it != m5arts.end(); ++it)
{
bd.components.push_back (Component (Component::ARTIFACT, *it, 0, 0));
loot << "%s";
loot.addReplacement (MetaString::ART_NAMES, *it);
}
bd.text.addReplacement (loot.buildList());
}
break;
case CQuest::MISSION_ARMY:
{
MetaString loot;
for (TSlots::const_iterator it = m6creatures.begin(); it != m6creatures.end(); ++it)
{
bd.components.push_back (Component (Component::CREATURE, it->second.first, it->second.second, 0));
loot << "%s";
if (it->second.second == 1)
loot.addReplacement (MetaString::CRE_SING_NAMES, it->second.first);
else
loot.addReplacement (MetaString::CRE_PL_NAMES, it->second.first);
}
bd.text.addReplacement (loot.buildList());
}
break;
case CQuest::MISSION_RESOURCES:
{
MetaString loot;
for (int i = 0; i < 7; ++i)
{
if (m7resources[i])
{
bd.components.push_back (Component (Component::RESOURCE, i, m7resources[i], 0));
loot << "%d %s";
loot.addReplacement (iw.components.back().val);
loot.addReplacement (MetaString::RES_NAMES, iw.components.back().subtype);
}
}
bd.text.addReplacement (loot.buildList());
}
break;
case MISSION_KILL_HERO:
bd.text.addReplacement(cb->gameState()->map->heroesToBeat[m13489val]->name);
break;
case MISSION_HERO:
bd.text.addReplacement(VLC->heroh->heroes[m13489val]->name);
break;
case MISSION_KILL_CREATURE:
{
const TStack* stack = cb->gameState()->map->monsters[m13489val]->army.getStack(0);
if (stack->first == 1)
bd.text.addReplacement (MetaString::CRE_SING_NAMES, stack->first);
else
bd.text.addReplacement (MetaString::CRE_PL_NAMES, stack->first);
if (std::count(firstVisitText.begin(), firstVisitText.end(), '%') == 2) //say where is placed monster
{
bd.text.addReplacement (VLC->generaltexth->arraytxt[147+checkDirection()]);
}
}
cb->showBlockingDialog (&bd, boost::bind (&CGSeerHut::finishQuest, this, h, _1));
return;
}
cb->showBlockingDialog (&bd, boost::bind (&CGSeerHut::finishQuest, this, h, _1));
return;
}
}
else
@ -3433,8 +3551,8 @@ void CGSeerHut::onHeroVisit( const CGHeroInstance * h ) const
iw.text << VLC->generaltexth->seerEmpty[textOption];
if (ID == 83)
iw.text.addReplacement(seerName);
cb->showInfoDialog(&iw);
}
cb->showInfoDialog(&iw);
}
int CGSeerHut::checkDirection() const
{
@ -3475,10 +3593,12 @@ void CGSeerHut::finishQuest (const CGHeroInstance * h, ui32 accept) const
{
case CQuest::MISSION_ART:
for (std::vector<ui16>::const_iterator it = m5arts.begin(); it != m5arts.end(); ++it)
{}
{
cb->removeArtifact(*it, h->id);
}
break;
case CQuest::MISSION_ARMY:
//cb->takeCreatures (h->id, m7creatures);
cb->takeCreatures (h->id, m6creatures);
break;
case CQuest::MISSION_RESOURCES:
for (int i = 0; i < 7; ++i)
@ -3489,7 +3609,8 @@ void CGSeerHut::finishQuest (const CGHeroInstance * h, ui32 accept) const
default:
break;
}
completeQuest(h);
cb->setObjProperty (id,11,0); //no more mission avaliable
completeQuest(h); //make sure to remove QuestQuard at the very end
}
}
void CGSeerHut::completeQuest (const CGHeroInstance * h) const //reward
@ -3555,7 +3676,6 @@ void CGSeerHut::completeQuest (const CGHeroInstance * h) const //reward
break;
}
cb->showInfoDialog(&iw);
cb->setObjProperty (id,11,0); //no more mission avaliable
}
void CGQuestGuard::initObj()
@ -3572,12 +3692,6 @@ void CGQuestGuard::initObj()
else
firstVisitText = VLC->generaltexth->seerEmpty[textOption];
}
const std::string & CGQuestGuard::getHoverText() const
{
hoverName = VLC->generaltexth->names[ID];
if (progress){}//what does it seek for?
return hoverName;
}
void CGQuestGuard::completeQuest(const CGHeroInstance *h) const
{
cb->removeObject(id);

View File

@ -248,7 +248,6 @@ public:
std::vector<si32> primSkills; //0-attack, 1-defence, 2-spell power, 3-knowledge
std::vector<std::pair<ui8,ui8> > secSkills; //first - ID of skill, second - level of skill (1 - basic, 2 - adv., 3 - expert); if hero has ability (-1, -1) it meansthat it should have default secondary abilities
si32 movement; //remaining movement points
si32 identifier; //from the map file
ui8 sex;
ui8 inTownGarrison; // if hero is in town garrison
CGTownInstance * visitedTown; //set if hero is visiting town or in the town garrison
@ -276,7 +275,7 @@ public:
{
h & static_cast<CArmedInstance&>(*this);
h & exp & level & name & biography & portrait & mana & primSkills & secSkills & movement
& identifier & sex & inTownGarrison & artifacts & artifWorn & spells & patrol & bonuses
& sex & inTownGarrison & artifacts & artifWorn & spells & patrol & bonuses
& moveDir;
ui8 standardType = (VLC->heroh->heroes[subID] == type);
@ -636,8 +635,6 @@ class DLL_EXPORT CGQuestGuard : public CGSeerHut
{
public:
void initObj();
const std::string & getHoverText() const;
//void onHeroVisit( const CGHeroInstance * h ) const;
void completeQuest (const CGHeroInstance * h) const;
template <typename Handler> void serialize(Handler &h, const int version)

View File

@ -80,7 +80,7 @@ public:
virtual void showThievesGuildWindow(int requestingObjId) =0;
virtual void giveResource(int player, int which, int val)=0;
virtual void giveCreatures (int objid, const CGHeroInstance * h, CCreatureSet creatures) =0;
virtual void takeCreatures (int objid, CCreatureSet creatures) =0;
virtual void takeCreatures (int objid, TSlots creatures) =0;
virtual void showCompInfo(ShowInInfobox * comp)=0;
virtual void heroVisitCastle(int obj, int heroID)=0;
virtual void stopHeroVisitCastle(int obj, int heroID)=0;

View File

@ -252,7 +252,7 @@ DLL_EXPORT void RemoveObject::applyGs( CGameState *gs )
else if (obj->ID==CREI_TYPE) //only fixed monsters can be a part of quest
{
CGCreature *cre = static_cast<CGCreature*>(obj);
gs->map->monsters[cre->identifier] = NULL;
gs->map->monsters[cre->identifier]->pos = int3 (-1,-1,-1); //use nonexistent monster for quest :>
}
gs->map->objects[id] = NULL;

View File

@ -922,7 +922,6 @@ void Mapa::loadHero( CGObjectInstance * &nobj, const unsigned char * bufor, int
break;
}
}
nhi->identifier = identifier; //probably redundant
heroesToBeat[identifier] = nhi;
if(readChar(bufor,i))//true if hero has nonstandard name
nhi->name = readString(bufor,i);

View File

@ -1734,8 +1734,25 @@ void CGameHandler::giveCreatures (int objid, const CGHeroInstance * h, CCreature
return;
}
}
void CGameHandler::takeCreatures (int objid, CCreatureSet creatures)
{}
void CGameHandler::takeCreatures (int objid, TSlots creatures) //probably we could use ArmedInstance as well
{
if (creatures.size() <= 0)
return;
const CArmedInstance* obj = static_cast<const CArmedInstance*>(getObj(objid));
CCreatureSet newArmy = obj->army;
while (creatures.size() > 0)
{
int slot = newArmy.getSlotFor (creatures.begin()->second.first);
if (slot < 0)
break;
newArmy.slots[slot].first = creatures.begin()->second.first;
newArmy.slots[slot].second -= creatures.begin()->second.second;
creatures.erase (creatures.begin());
}
SetGarrisons sg;
sg.garrs[objid] = newArmy;
sendAndApply(&sg);
}
void CGameHandler::showCompInfo(ShowInInfobox * comp)
{
sendToAllClients(comp);
@ -1816,7 +1833,30 @@ void CGameHandler::giveHeroArtifact(int artid, int hid, int position) //pos==-1
sendAndApply(&sha);
}
void CGameHandler::removeArtifact(int artid, int hid)
{}
{
const CGHeroInstance* h = getHero(hid);
SetHeroArtifacts sha;
sha.hid = hid;
sha.artifacts = h->artifacts;
sha.artifWorn = h->artifWorn;
std::vector<ui32>::iterator it;
if ((it = std::find(sha.artifacts.begin(), sha.artifacts.end(), artid)) != sha.artifacts.end()) //it is in backpack
sha.artifacts.erase(it);
else //worn
{
for (std::map<ui16,ui32>::iterator itr = sha.artifWorn.begin(); itr != sha.artifWorn.end(); ++itr)
{
if (itr->second == artid)
{
sha.artifWorn.erase(itr);
break;
}
}
}
sendAndApply(&sha);
}
void CGameHandler::startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool creatureBank, boost::function<void(BattleResult*)> cb, const CGTownInstance *town) //use hero=NULL for no hero
{

View File

@ -129,7 +129,7 @@ public:
void showThievesGuildWindow(int requestingObjId); //TODO: make something more general?
void giveResource(int player, int which, int val);
void giveCreatures (int objid, const CGHeroInstance * h, CCreatureSet creatures);
void takeCreatures (int objid, CCreatureSet creatures);
void takeCreatures (int objid, TSlots creatures);
void showCompInfo(ShowInInfobox * comp);
void heroVisitCastle(int obj, int heroID);
void vistiCastleObjects (const CGTownInstance *t, const CGHeroInstance *h);