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

1.Support for Keymaster Tent & Borderguard, Eye & Hut of The Magi, Stables.

2.Partially done support for creature banks. ToDo: load config file, start battle with surrounding enemies
3.Attempt to increase hero exp capacity. You may ignore it at the moment.
4.Fixed negative countdown in timeHandler.
This commit is contained in:
DjWarmonger
2009-08-11 07:50:29 +00:00
parent 575840f641
commit 4653396d76
19 changed files with 647 additions and 29 deletions

View File

@ -38,7 +38,25 @@ IGameCallback * IObjectInterface::cb = NULL;
DLL_EXPORT void loadToIt(std::string &dest, std::string &src, int &iter, int mode);
extern CLodHandler * bitmaph;
extern boost::rand48 ran;
std::map <ui8, std::set <ui8> > CGKeys::playerKeyMap;
std::map <si32, std::vector<CGMagi>> CGMagi::eyelist;
std::map <ui32, std::vector <BankConfig>> banksInfo; //[index][preset], TODO: load it
struct BankConfig
{
BankConfig() {chance = upgradeChance = combatValue = value = rewardDifficulty = easiest = 0; };
//std::string name;
ui8 chance;
ui8 upgradeChance;
std::vector< std::pair <ui16, ui32>> guards;
ui32 combatValue;
std::map<ui8, si32> resources;
std::vector< std::pair <ui16, ui32>> creatures;
std::map<ui8, ui16> artifacts;
ui32 value;
ui32 rewardDifficulty; //?
ui16 easiest; //?
};
void IObjectInterface::onHeroVisit(const CGHeroInstance * h) const
{};
@ -1666,6 +1684,25 @@ int CArmedInstance::getArmyStrength() const
return ret;
}
/*const std::string & CGCreature::getHoverText() const
{
hoverName = VLC->generaltexth->names[ID];
hoverName += "\n Power rating: ";
float ratio = ((float)getArmyStrength() / cb->getSelectedHero(cb->getCurrentPlayer())->getTotalStrength());
if (ratio < 0.1) hoverName += "Effortless";
else if (ratio < 0.3) hoverName += "Very Weak";
else if (ratio < 0.6) hoverName += "Weak";
else if (ratio < 0.9) hoverName += "A bit weaker";
else if (ratio < 1.1) hoverName += "Equal";
else if (ratio < 1.3) hoverName += "A bit stronger";
else if (ratio < 1.8) hoverName += "Strong";
else if (ratio < 2.5) hoverName += "Very Strong";
else if (ratio < 4) hoverName += "Challenging";
else if (ratio < 8) hoverName += "Overpowering";
else if (ratio < 20) hoverName += "Deadly";
else hoverName += "Impossible";
return hoverName;
}*/
void CGCreature::onHeroVisit( const CGHeroInstance * h ) const
{
int action = takenAction(h);
@ -2634,10 +2671,17 @@ void CGBonusingObject::onHeroVisit( const CGHeroInstance * h ) const
gbonus.bdescr << std::pair<ui8,ui32>(6,103);
bonusMove = 400;
break;
case 94: //Stables TODO: upgrade Cavaliers
sound = soundBase::horse20;
messageID = 137;
gbonus.bonus.type = HeroBonus::LAND_MOVEMENT;
gbonus.bonus.val = 600;
gbonus.bdescr << std::pair<ui8,ui32>(6, 100);
break;
}
if(visited)
{
if(ID==64 || ID==96 || ID==56 || ID == 52)
if(ID==64 || ID==96 || ID==56 || ID==52 || ID==94)
messageID--;
else
messageID++;
@ -3386,24 +3430,369 @@ void CGOnceVisitable::searchTomb(const CGHeroInstance *h, ui32 accept) const
cb->giveHeroArtifact(bonusType,h->id,-2);
}
if(!h->getBonus(HeroBonus::OBJECT,ID)) //we don't have modifier from this object yet
{
//ruin morale
GiveBonus gb;
gb.hid = h->id;
gb.bonus = HeroBonus(HeroBonus::ONE_BATTLE,HeroBonus::MORALE,HeroBonus::OBJECT,-3,id,"");
gb.bdescr.addTxt(MetaString::ARRAY_TXT,104); //Warrior Tomb Visited -3
cb->giveHeroBonus(&gb);
}
cb->showInfoDialog(&iw);
//add player to the visitors (for visited tooltop)
cb->setObjProperty(id,10,h->getOwner());
}
}
void CBank::initObj()
{
index = 0;
switch (ID) //find apriopriate key
{
case 16: //bank
index = subID; break;
case 24: //derelict ship
index = 8;
case 25: //utopia
index = 10; break;
case 84: //crypt
index = 9; break;
case 85: //shipwreck
index = 7; break;
}
bc = NULL;
daycounter = 0;
multiplier = 1;
}
void CBank::reset()
{
int val1 = ran()%100;
int chance = 0;
for (ui8 i = 1; i <= banksInfo[index].size(); i++)
{
if (val1 < (chance += banksInfo[index][i].chance))
cb->setObjProperty (id, 13, i);
}
artifacts.clear();
for (ui8 i = 1; i <= 4; i++)
{
for (ui8 j = 1; j <= bc->artifacts[i]; j++)
cb->setObjProperty (id, 18, i);
}
}
void CBank::setPropertyDer (ui8 what, ui32 val)
{
switch (what)
{
case 11: //daycounter
daycounter++;
break;
case 12: //multiplier
multiplier *= ((float)val)/100;
break;
case 13: //bank preset
bc = &banksInfo[index][val];
break;
case 18: //Artifacts
{
std::vector<CArtifact*> arts;
switch (val)
{
case 1:
cb->getAllowed (arts, CArtifact::ART_TREASURE);
break;
case 2:
cb->getAllowed (arts, CArtifact::ART_MINOR);
break;
case 3:
cb->getAllowed (arts, CArtifact::ART_MAJOR);
break;
case 4:
cb->getAllowed (arts, CArtifact::ART_RELIC);
break;
}
artifacts.push_back (arts[ran() % arts.size()]->id);
}
break;
}
}
void CBank::newTurn()
{
if (bc == NULL)
{
if (daycounter >= 28 || cb->getDate(0) == 1)
{
reset();
daycounter = 0;
if (ID == 24 && cb->getDate(0) > 1)
{
artifacts.clear(); //derelict ships are usable only once
}
}
else
daycounter++;
}
}
void CBank::onHeroVisit (const CGHeroInstance * h) const
{
if (bc != NULL)
{
int banktext = 0;
switch (ID)
{
case 16: //generic bank
banktext = 32;
break;
case 24:
banktext = 41;
break;
case 25: //utopia
banktext = 47;
break;
case 84: //crypt
banktext = 119;
break;
case 85: //shipwreck
banktext = 122;
break;
}
BlockingDialog bd (true, false);
bd.player = h->getOwner();
bd.soundID = soundBase::DANGER;
std::string desc = VLC->generaltexth->allTexts[banktext];
boost::algorithm::replace_first (desc, "%s", VLC->generaltexth->names[ID]);
bd.text << desc;
cb->showBlockingDialog (&bd, boost::bind (&CBank::fightGuards, this, h, _1));
}
else
{
InfoWindow iw;
if (ID == 85)
iw.components.push_back (Component (Component::MORALE, 0 , -2, 0));
iw.soundID = soundBase::GRAVEYARD;
iw.player = h->getOwner();
iw.text.addTxt (MetaString::ADVOB_TXT, 33);
cb->showInfoDialog(&iw);
}
}
void CBank::fightGuards (const CGHeroInstance * h, ui32 accept) const
{
if (accept)
{
int upgraded = 0;
if (ran()%100 < bc->upgradeChance) upgraded = 1;
CCreatureSet ourArmy;
switch (bc->guards.size())
{
case 1:
for (int i = 1; i <= 5; i++)
ourArmy.setCreature (i, bc->guards[1].first + upgraded, bc->guards[1].second / 5 );
break;
case 4:
{
std::vector< std::pair <ui16, ui32>>::const_iterator it;
for (it = bc->guards.begin(); it != bc->guards.end(); it++)
ourArmy.setCreature (ourArmy.slots.size() + 1, it->first, it->second );
}
break;
default:
tlog1 << "Error: Unexpected army data: " << bc->guards.size() <<" items found";
return;
}
//TODO: start combat
}
}
void CBank::endBattle (const BattleResult *result)
{
if (result->winner == 0)
{
int textID = -1;
InfoWindow iw;
switch (ID)
{
case 16: //generic bank
textID = 34;
break;
case 24: //derelict ship
if (bc->resources.size() != 0)
textID = 43;
else
{
textID = 42;
iw.components.push_back (Component (Component::MORALE, 0 , -2, 0));
}
break;
case 25: //utopia
textID = 47;
break;
case 84: //crypt
textID = 121;
break;
case 85: //shipwreck
if (bc->resources.size() != 0)
textID = 124;
else
{
textID = 123;
}
break;
}
iw.text.addTxt (MetaString::ADVOB_TXT, textID);
iw.player = cb->getCurrentPlayer();
for (std::map<ui8, si32>::iterator it = bc->resources.begin(); it != bc->resources.end(); it++)
{
iw.components.push_back (Component (Component::RESOURCE, it->first, it->second, 0));
cb->giveResource (cb->getCurrentPlayer(), it->first, it->second);
}
for (std::vector<si32>::iterator it = artifacts.begin(); it != artifacts.end(); it++)
{
iw.components.push_back (Component (Component::ARTIFACT, *it, 0, 0));
iw.text.addReplacement (MetaString::ART_NAMES, *it);
cb->giveHeroArtifact (*it, cb->getSelectedHero() ,-2);
}
CCreatureSet ourArmy;
for (std::vector< std::pair <ui16, ui32>>::iterator it = bc->creatures.begin(); it != bc->creatures.end(); it++)
{
int slot = ourArmy.getSlotFor (it->second);
ourArmy.slots[slot] = *it; //assuming we're not going to add multiple stacks of same creature
}
cb->giveCreatures (id, cb->getHero (cb->getSelectedHero()), &ourArmy);
bc = NULL;
}
else
reset();
}
void CGKeys::setPropertyDer (ui8 what, ui32 val) //101-108 - enable key for player 1-8
{
if (what >= 101 && what <= (100 + PLAYER_LIMIT))
playerKeyMap.find(what-101)->second.insert(val);
}
bool CGKeys::wasMyColorVisited (int player) const
{
if (vstd::contains(playerKeyMap[player], subID)) //creates set if it's not there
return true;
else
return false;
}
const std::string & CGKeymasterTent::getHoverText() const
{
hoverName = VLC->generaltexth->names[ID];
if (wasMyColorVisited (cb->getCurrentPlayer()) )//TODO: use local player, not current
hoverName += "\n" + VLC->generaltexth->allTexts[352];
else
hoverName += "\n" + VLC->generaltexth->allTexts[353];
return hoverName;
}
void CGKeymasterTent::onHeroVisit( const CGHeroInstance * h ) const
{
InfoWindow iw;
iw.soundID = soundBase::CAVEHEAD;
iw.player = h->getOwner();
if (!wasMyColorVisited (h->getOwner()) )
{
cb->setObjProperty(id, h->tempOwner+101, subID);
iw.text << std::pair<ui8,ui32>(11,19);
}
else
iw.text << std::pair<ui8,ui32>(11,20);
cb->showInfoDialog(&iw);
}
void CGBorderGuard::initObj()
{
blockVisit = true;
}
const std::string & CGBorderGuard::getHoverText() const
{
hoverName = VLC->generaltexth->names[ID];
if (wasMyColorVisited (cb->getCurrentPlayer()) )//TODO: use local player, not current
hoverName += "\n" + VLC->generaltexth->allTexts[352];
else
hoverName += "\n" + VLC->generaltexth->allTexts[353];
return hoverName;
}
void CGBorderGuard::onHeroVisit( const CGHeroInstance * h ) const
{
if (wasMyColorVisited (h->getOwner()) )
{
BlockingDialog bd (true, false);
bd.player = h->getOwner();
bd.soundID = soundBase::QUEST;
bd.text.addTxt (MetaString::ADVOB_TXT, 17);
cb->showBlockingDialog (&bd, boost::bind (&CGBorderGuard::openGate, this, h, _1));
}
else
{
InfoWindow iw;
iw.player = h->getOwner();
iw.soundID = soundBase::CAVEHEAD;
iw.text << std::pair<ui8,ui32>(11,18);
cb->showInfoDialog (&iw);
}
}
void CGBorderGuard::openGate(const CGHeroInstance *h, ui32 accept) const
{
if (accept)
cb->removeObject(id);
}
void CGBorderGate::onHeroVisit( const CGHeroInstance * h ) const //TODO: passability
{
InfoWindow iw;
iw.player = h->getOwner();
if (!wasMyColorVisited (h->getOwner()) )
{
iw.text << std::pair<ui8,ui32>(11,18);
cb->showInfoDialog(&iw);
}
}
void CGMagi::initObj()
{
if (ID == 27)
{
blockVisit = true;
eyelist[subID].push_back (*this);
}
}
void CGMagi::onHeroVisit(const CGHeroInstance * h) const
{
if (ID == 37)
{
InfoWindow iw;
CenterView cv;
FoWChange fw;
cv.player = iw.player = fw.player = h->tempOwner;
iw.soundID = soundBase::LIGHTHOUSE;
iw.player = h->tempOwner;
iw.text.addTxt (MetaString::ADVOB_TXT, 61);
cb->showInfoDialog(&iw);
fw.mode = 1;
TakeYourTime tyt;
std::vector<CGMagi>::iterator it;
for (it = eyelist[subID].begin() ; it < eyelist[subID].end(); it++)
{
cb->getTilesInRange (fw.tiles, it->pos, 5, h->tempOwner, 1);
cb->sendAndApply(&fw);
cv.id = it->id;
cb->sendAndApply(&cv);
tyt.time = 2000;
cb->sendAndApply(&tyt);
}
cv.id = h->id;
cb->sendAndApply(&cv);
}
else if (ID == 27)
{
InfoWindow iw;
iw.player = h->tempOwner;
iw.text.addTxt (MetaString::ADVOB_TXT, 48);
cb->showInfoDialog(&iw);
}
}
void CGBoat::initObj()
{
hero = NULL;