mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +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:
parent
575840f641
commit
4653396d76
@ -76,7 +76,7 @@ public:
|
||||
virtual void heroCreated(const CGHeroInstance*){};
|
||||
virtual void heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector<ui16> &skills, boost::function<void(ui32)> &callback)=0; //pskill is gained primary skill, interface has to choose one of given skills and call callback with selection id
|
||||
virtual void heroInGarrisonChange(const CGTownInstance *town){};
|
||||
//virtual void heroKilled(const CGHeroInstance*){};
|
||||
virtual void heroKilled(const CGHeroInstance*){};
|
||||
virtual void heroMoved(const TryMoveHero & details){};
|
||||
virtual void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, int val){};
|
||||
virtual void heroManaPointsChanged(const CGHeroInstance * hero){} //not called at the beginning of turn and after spell casts
|
||||
@ -93,6 +93,7 @@ public:
|
||||
virtual void tileRevealed(const std::set<int3> &pos){};
|
||||
virtual void newObject(const CGObjectInstance * obj){}; //eg. ship built in shipyard
|
||||
virtual void yourTurn(){};
|
||||
virtual void centerView (int3 pos){};
|
||||
virtual void availableCreaturesChanged(const CGDwelling *town){};
|
||||
virtual void heroBonusChanged(const CGHeroInstance *hero, const HeroBonus &bonus, bool gain){};//if gain hero received bonus, else he lost it
|
||||
virtual void requestRealized(PackageApplied *pa){};
|
||||
|
@ -1545,6 +1545,11 @@ void CPlayerInterface::newObject( const CGObjectInstance * obj )
|
||||
}
|
||||
}
|
||||
|
||||
void CPlayerInterface::centerView (int3 pos)
|
||||
{
|
||||
LOCPLINT->adventureInt->centerOn (pos);
|
||||
}
|
||||
|
||||
void CPlayerInterface::objectRemoved( const CGObjectInstance *obj )
|
||||
{
|
||||
if(obj->ID == HEROI_TYPE && obj->tempOwner == playerID)
|
||||
|
@ -157,6 +157,7 @@ public:
|
||||
void heroBonusChanged(const CGHeroInstance *hero, const HeroBonus &bonus, bool gain);//if gain hero received bonus, else he lost it
|
||||
void requestRealized(PackageApplied *pa);
|
||||
void heroExchangeStarted(si32 hero1, si32 hero2);
|
||||
void centerView (int3 pos);
|
||||
void objectPropertyChanged(const SetObjectProperty * sop);
|
||||
void objectRemoved(const CGObjectInstance *obj);
|
||||
void serialize(COSer<CSaveFile> &h, const int version); //saving
|
||||
@ -179,7 +180,6 @@ public:
|
||||
void battleStacksHealedRes(const std::vector<std::pair<ui32, ui32> > & healedStacks); //called when stacks are healed / resurrected
|
||||
void battleNewStackAppeared(int stackID); //not called at the beginning of a battle or by resurrection; called eg. when elemental is summoned
|
||||
|
||||
|
||||
//-------------//
|
||||
void heroKilled(const CGHeroInstance* hero);
|
||||
void waitWhileDialog();
|
||||
|
@ -96,6 +96,7 @@ public:
|
||||
ui32 showBlockingDialog(BlockingDialog *iw){return 0;}; //synchronous version of above
|
||||
void showGarrisonDialog(int upobj, int hid, const boost::function<void()> &cb){};
|
||||
void giveResource(int player, int which, int val){};
|
||||
void giveCreatures (int objid, const CGHeroInstance * h, CCreatureSet *creatures){};
|
||||
void showCompInfo(ShowInInfobox * comp){};
|
||||
void heroVisitCastle(int obj, int heroID){};
|
||||
void stopHeroVisitCastle(int obj, int heroID){};
|
||||
|
@ -550,6 +550,17 @@ void OpenWindow::applyCl(CClient *cl)
|
||||
|
||||
}
|
||||
|
||||
void CenterView::applyCl(CClient *cl)
|
||||
{
|
||||
int3 pos = (cl->getObj(id))->pos;
|
||||
INTERFACE_CALL_IF_PRESENT (player, centerView, pos);
|
||||
}
|
||||
|
||||
void TakeYourTime::applyCl(CClient *cl)
|
||||
{
|
||||
SDL_Delay(time);
|
||||
}
|
||||
|
||||
void NewObject::applyCl(CClient *cl)
|
||||
{
|
||||
const CGObjectInstance *obj = cl->getObj(id);
|
||||
|
@ -378,7 +378,7 @@ void CHeroHandler::initHeroClasses()
|
||||
loadNativeTerrains();
|
||||
}
|
||||
|
||||
unsigned int CHeroHandler::level(unsigned int experience)
|
||||
unsigned int CHeroHandler::level(ui64 experience)
|
||||
{
|
||||
int i;
|
||||
if(experience <= expPerLevel.back())
|
||||
@ -393,7 +393,7 @@ unsigned int CHeroHandler::level(unsigned int experience)
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int CHeroHandler::reqExp(unsigned int level)
|
||||
ui64 CHeroHandler::reqExp(unsigned int level)
|
||||
{
|
||||
if(!level)
|
||||
return 0;
|
||||
@ -404,6 +404,14 @@ unsigned int CHeroHandler::reqExp(unsigned int level)
|
||||
}
|
||||
else
|
||||
{
|
||||
ui64 exp = expPerLevel[expPerLevel.size()-1];
|
||||
level-=(expPerLevel.size()-1);
|
||||
while(level>0)
|
||||
{
|
||||
--level;
|
||||
exp*=1.2;
|
||||
}
|
||||
return exp;
|
||||
return reqExp(level - 1) + (reqExp(level - 1) - reqExp(level - 2)) * 1.2; //inefficient but follows exactly H3 values
|
||||
}
|
||||
}
|
||||
|
@ -113,8 +113,8 @@ public:
|
||||
|
||||
void loadObstacles(); //loads info about obstacles
|
||||
|
||||
unsigned int level(unsigned int experience); //calculates level corresponding to given experience amount
|
||||
unsigned int reqExp(unsigned int level); //calculates experience resuired for given level
|
||||
unsigned int level(ui64 experience); //calculates level corresponding to given experience amount
|
||||
ui64 reqExp(unsigned int level); //calculates experience resuired for given level
|
||||
|
||||
void loadHeroes();
|
||||
void loadHeroClasses();
|
||||
|
@ -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;
|
||||
|
@ -42,6 +42,7 @@ class CGDefInfo;
|
||||
class CSpecObjInfo;
|
||||
struct TerrainTile;
|
||||
struct InfoWindow;
|
||||
struct BankConfig;
|
||||
class CGBoat;
|
||||
|
||||
class DLL_EXPORT CCastleEvent
|
||||
@ -184,7 +185,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_EXPORT CArmedInstance: public CGObjectInstance
|
||||
class DLL_EXPORT CArmedInstance: public CGObjectInstance
|
||||
{
|
||||
public:
|
||||
CCreatureSet army; //army
|
||||
@ -211,7 +212,7 @@ public:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CHero * type;
|
||||
ui32 exp; //experience point
|
||||
ui64 exp; //experience point
|
||||
si32 level; //current level of hero
|
||||
std::string name; //may be custom
|
||||
std::string biography; //if custom
|
||||
@ -474,6 +475,7 @@ public:
|
||||
|
||||
void fight(const CGHeroInstance *h) const;
|
||||
void onHeroVisit(const CGHeroInstance * h) const;
|
||||
//const std::string & getHoverText() const;
|
||||
|
||||
void flee( const CGHeroInstance * h ) const;
|
||||
void endBattle(BattleResult *result) const;
|
||||
@ -759,6 +761,54 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class DLL_EXPORT CGKeys : public CGObjectInstance //Base class for Keymaster and guards, ToDo Border Gate
|
||||
{
|
||||
public:
|
||||
static std::map <ui8, std::set <ui8> > playerKeyMap; //[players][keysowned]
|
||||
//SubID 0 - lightblue, 1 - green, 2 - red, 3 - darkblue, 4 - brown, 5 - purple, 6 - white, 7 - black
|
||||
|
||||
void setPropertyDer (ui8 what, ui32 val);
|
||||
bool wasMyColorVisited (int player) const;
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & static_cast<CGObjectInstance&>(*this);
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_EXPORT CGKeymasterTent : public CGKeys
|
||||
{
|
||||
public:
|
||||
void onHeroVisit(const CGHeroInstance * h) const;
|
||||
const std::string & getHoverText() const;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & static_cast<CGObjectInstance&>(*this);
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_EXPORT CGBorderGuard : public CGKeys
|
||||
{
|
||||
public:
|
||||
void initObj();
|
||||
const std::string & getHoverText() const;
|
||||
void onHeroVisit(const CGHeroInstance * h) const;
|
||||
void openGate(const CGHeroInstance *h, ui32 accept) const;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & static_cast<CGObjectInstance&>(*this);
|
||||
h & blockVisit;
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_EXPORT CGBorderGate : public CGBorderGuard //not fully imlemented, waiting for garrison
|
||||
{
|
||||
public:
|
||||
void onHeroVisit(const CGHeroInstance * h) const;
|
||||
};
|
||||
|
||||
class DLL_EXPORT CGBoat : public CGObjectInstance
|
||||
{
|
||||
public:
|
||||
@ -778,7 +828,8 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_EXPORT CGOnceVisitable : public CPlayersVisited //wagon, corpse, lean to, warriors tomb
|
||||
class DLL_EXPORT CGOnceVisitable
|
||||
: public CPlayersVisited //wagon, corpse, lean to, warriors tomb
|
||||
{
|
||||
public:
|
||||
ui8 artOrRes; //0 - nothing; 1 - artifact; 2 - resource
|
||||
@ -797,6 +848,30 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_EXPORT CBank : public CArmedInstance
|
||||
{
|
||||
public:
|
||||
int index; //banks have unusal numbering - see ZCRBANK.txt and initObj()
|
||||
BankConfig *bc;
|
||||
ui8 multiplier; //for improved banks script, in percent
|
||||
std::vector<si32> artifacts; //fixed and deterministic
|
||||
mutable ui32 daycounter;
|
||||
|
||||
void initObj();
|
||||
void setPropertyDer (ui8 what, ui32 val);
|
||||
void reset();
|
||||
void newTurn();
|
||||
void onHeroVisit (const CGHeroInstance * h) const;
|
||||
void fightGuards (const CGHeroInstance *h, ui32 accept) const;
|
||||
void endBattle (const BattleResult *result);
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & static_cast<CGObjectInstance&>(*this);
|
||||
h & index & multiplier & artifacts & daycounter;
|
||||
}
|
||||
};
|
||||
|
||||
class CGShipyard : public CGObjectInstance, public IShipyard
|
||||
{
|
||||
public:
|
||||
@ -819,4 +894,17 @@ public:
|
||||
|
||||
|
||||
|
||||
class DLL_EXPORT CGMagi : public CGObjectInstance
|
||||
{
|
||||
public:
|
||||
static std::map <si32, std::vector<CGMagi>> eyelist; //[subID][id], supports multiple sets as in H5
|
||||
|
||||
void initObj();
|
||||
void onHeroVisit(const CGHeroInstance * h) const;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & static_cast<CGObjectInstance&>(*this);
|
||||
}
|
||||
};
|
||||
#endif // __COBJECTHANDLER_H__
|
||||
|
8
int3.h
8
int3.h
@ -18,8 +18,14 @@ class CCreature;
|
||||
class CCreatureSet //seven combined creatures
|
||||
{
|
||||
public:
|
||||
std::map<si32,std::pair<ui32,si32> > slots; //slots[slot_id]=> pair(creature_id,creature_quantity)
|
||||
std::map<si32, std::pair<ui32,si32>> slots; //slots[slot_id]=> pair(creature_id,creature_quantity)
|
||||
bool formation; //false - wide, true - tight
|
||||
bool setCreature (si32 slot, ui32 type, si32 quantity) //slots 1 to 7
|
||||
{
|
||||
slots.find(slot)->second = std::pair<ui32,si32>(type, quantity); //brutal force
|
||||
if (slots.size() > 7) return false;
|
||||
else return true;
|
||||
}
|
||||
si32 getSlotFor(ui32 creature, ui32 slotsAmount=7) const //returns -1 if no slot available
|
||||
{
|
||||
for(std::map<si32,std::pair<ui32,si32> >::const_iterator i=slots.begin(); i!=slots.end(); ++i)
|
||||
|
@ -72,6 +72,7 @@ public:
|
||||
virtual ui32 showBlockingDialog(BlockingDialog *iw) =0; //synchronous version of above //TODO:
|
||||
virtual void showGarrisonDialog(int upobj, int hid, const boost::function<void()> &cb) =0; //cb will be called when player closes garrison window
|
||||
virtual void giveResource(int player, int which, int val)=0;
|
||||
virtual void giveCreatures (int objid, const CGHeroInstance * h, CCreatureSet *creatures)=0;
|
||||
virtual void showCompInfo(ShowInInfobox * comp)=0;
|
||||
virtual void heroVisitCastle(int obj, int heroID)=0;
|
||||
virtual void stopHeroVisitCastle(int obj, int heroID)=0;
|
||||
|
@ -1290,10 +1290,43 @@ struct SetSelection : public CPackForClient, public CPackForServer //514
|
||||
ui8 player;
|
||||
ui32 id;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & id & player;
|
||||
}
|
||||
};
|
||||
|
||||
struct TakeYourTime : public CPackForClient//515
|
||||
{
|
||||
TakeYourTime(){CPackForClient::type = 515;};
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
void applyCl(CClient *cl);
|
||||
bool applyGh(CGameHandler *gh);
|
||||
|
||||
ui8 player;
|
||||
ui32 time;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & time & player;
|
||||
}
|
||||
};
|
||||
|
||||
struct CenterView : public CPackForClient//516
|
||||
{
|
||||
CenterView(){CPackForClient::type = 516;};
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
void applyCl(CClient *cl);
|
||||
bool applyGh(CGameHandler *gh);
|
||||
|
||||
ui8 player;
|
||||
si32 id;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & id & player;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif //__NETPACKS_H__
|
||||
|
@ -1001,8 +1001,16 @@ DLL_EXPORT void YourTurn::applyGs( CGameState *gs )
|
||||
gs->currentPlayer = player;
|
||||
}
|
||||
|
||||
|
||||
DLL_EXPORT void SetSelection::applyGs( CGameState *gs )
|
||||
{
|
||||
gs->getPlayer(player)->currentSelection = id;
|
||||
}
|
||||
|
||||
DLL_EXPORT void CenterView::applyGs( CGameState *gs )
|
||||
{
|
||||
gs->getPlayer(player)->currentSelection = id;
|
||||
}
|
||||
|
||||
DLL_EXPORT void TakeYourTime::applyGs( CGameState *gs )
|
||||
{
|
||||
}
|
||||
|
@ -42,9 +42,14 @@ void registerTypes1(Serializer &s)
|
||||
s.template registerType<CGBonusingObject>();
|
||||
s.template registerType<CGMagicWell>();
|
||||
s.template registerType<CGObservatory>();
|
||||
s.template registerType<CGKeys>();
|
||||
s.template registerType<CGKeymasterTent>();
|
||||
s.template registerType<CGBorderGuard>();
|
||||
s.template registerType<CGBoat>();
|
||||
s.template registerType<CGMagi>();
|
||||
s.template registerType<CGSirens>();
|
||||
s.template registerType<CGOnceVisitable>();
|
||||
s.template registerType<CBank>();
|
||||
s.template registerType<CGShipyard>();
|
||||
s.template registerType<CGObjectInstance>();
|
||||
}
|
||||
@ -105,6 +110,8 @@ void registerTypes2(Serializer &s)
|
||||
s.template registerType<SaveGame>();
|
||||
s.template registerType<SetSelection>();
|
||||
s.template registerType<PlayerMessage>();
|
||||
s.template registerType<TakeYourTime>();
|
||||
s.template registerType<CenterView>();
|
||||
}
|
||||
|
||||
template<typename Serializer> DLL_EXPORT
|
||||
|
30
lib/map.cpp
30
lib/map.cpp
@ -101,6 +101,8 @@ static EDefType getDefType(CGDefInfo * a)
|
||||
return ARTIFACT_DEF; //handled
|
||||
case 6:
|
||||
return PANDORA_DEF; //hanled
|
||||
case 10:
|
||||
return EVENTOBJ_DEF; //???
|
||||
case 26:
|
||||
return EVENTOBJ_DEF; //handled
|
||||
case 33:
|
||||
@ -135,7 +137,7 @@ static EDefType getDefType(CGDefInfo * a)
|
||||
return WITCHHUT_DEF; //handled
|
||||
case 214:
|
||||
return HEROPLACEHOLDER_DEF; //partially handled
|
||||
case 215:
|
||||
case 215: case 9: //???
|
||||
return BORDERGUARD_DEF; //handled by analogy to seer huts ;]
|
||||
case 216:
|
||||
return CREGEN2_DEF; //handled
|
||||
@ -1852,6 +1854,7 @@ void Mapa::readObjects( unsigned char * bufor, int &i)
|
||||
case 31: //Fountain of Youth
|
||||
case 11: //Buoy
|
||||
case 52: //Mermaid
|
||||
case 94: //Stables
|
||||
{
|
||||
nobj = new CGBonusingObject();
|
||||
break;
|
||||
@ -1895,6 +1898,31 @@ void Mapa::readObjects( unsigned char * bufor, int &i)
|
||||
{
|
||||
i+=3; //TODO: handle it more properly
|
||||
}
|
||||
case 10: //Keymaster
|
||||
{
|
||||
nobj = new CGKeymasterTent();
|
||||
break;
|
||||
}
|
||||
case 9: //Border Guard
|
||||
{
|
||||
nobj = new CGBorderGuard();
|
||||
break;
|
||||
}
|
||||
case 212: //Border Gate
|
||||
{
|
||||
nobj = new CGBorderGate();
|
||||
break;
|
||||
}
|
||||
case 27: case 37: //Eye and Hut of Magi
|
||||
{
|
||||
nobj = new CGMagi();
|
||||
break;
|
||||
}
|
||||
case 16: case 24: case 25: case 84: case 85: //treasure bank
|
||||
{
|
||||
nobj = new CBank();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
nobj = new CGObjectInstance();
|
||||
} //end of main switch
|
||||
|
@ -406,6 +406,8 @@ struct DLL_EXPORT Mapa : public CMapHeader
|
||||
}
|
||||
|
||||
h & CGTeleport::objs;
|
||||
h & CGKeys::playerKeyMap;
|
||||
h & CGMagi::eyelist;
|
||||
|
||||
for(int i=0; i<objects.size(); i++)
|
||||
{
|
||||
|
@ -1431,6 +1431,35 @@ void CGameHandler::giveResource(int player, int which, int val)
|
||||
sr.val = gs->players.find(player)->second.resources[which]+val;
|
||||
sendAndApply(&sr);
|
||||
}
|
||||
void CGameHandler::giveCreatures (int objid, const CGHeroInstance * h, CCreatureSet *creatures)
|
||||
{
|
||||
CCreatureSet heroArmy = h->army;
|
||||
while(creatures)
|
||||
{
|
||||
int slot = heroArmy.getSlotFor(creatures->slots.begin()->second.first);
|
||||
if(slot < 0)
|
||||
break;
|
||||
|
||||
heroArmy.slots[slot].first = creatures->slots.begin()->second.first;
|
||||
heroArmy.slots[slot].second += creatures->slots.begin()->second.second;
|
||||
creatures->slots.erase(creatures->slots.begin());
|
||||
}
|
||||
|
||||
if(!creatures) //all creatures can be moved to hero army - do that
|
||||
{
|
||||
SetGarrisons sg;
|
||||
sg.garrs[h->id] = heroArmy;
|
||||
sendAndApply(&sg);
|
||||
}
|
||||
else //show garrison window and let player pick creatures
|
||||
{
|
||||
SetGarrisons sg;
|
||||
sg.garrs[objid] = *creatures;
|
||||
sendAndApply(&sg);
|
||||
showGarrisonDialog(objid, h->id, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
void CGameHandler::showCompInfo(ShowInInfobox * comp)
|
||||
{
|
||||
sendToAllClients(comp);
|
||||
|
@ -115,6 +115,7 @@ public:
|
||||
ui32 showBlockingDialog(BlockingDialog *iw); //synchronous version of above
|
||||
void showGarrisonDialog(int upobj, int hid, const boost::function<void()> &cb);
|
||||
void giveResource(int player, int which, int val);
|
||||
void giveCreatures (int objid, const CGHeroInstance * h, CCreatureSet *creatures);
|
||||
void showCompInfo(ShowInInfobox * comp);
|
||||
void heroVisitCastle(int obj, int heroID);
|
||||
void stopHeroVisitCastle(int obj, int heroID);
|
||||
|
@ -21,7 +21,7 @@ public:
|
||||
long getDif(){long ret=clock()-last;last=clock();return ret;};
|
||||
void update(){last=clock();};
|
||||
void remember(){mem=clock();};
|
||||
long memDif(){return mem-clock();};
|
||||
long memDif(){return clock()-mem;};
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user