diff --git a/AI/GeniusAI/CGeniusAI.h b/AI/GeniusAI/CGeniusAI.h index 157a4eec8..4bd09903c 100644 --- a/AI/GeniusAI/CGeniusAI.h +++ b/AI/GeniusAI/CGeniusAI.h @@ -181,7 +181,7 @@ public: virtual void heroKilled(const CGHeroInstance *); virtual void heroCreated(const CGHeroInstance *); virtual void heroMoved(const TryMoveHero &); - virtual void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, int val) {}; + virtual void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, si64 val) {}; virtual void showSelDialog(std::string text, std::vector & components, int askID){}; virtual void showBlockingDialog(const std::string &text, const std::vector &components, ui32 askID, const int soundID, bool selection, bool cancel); //Show a dialog, player must take decision. If selection then he has to choose between one of given components, if cancel he is allowed to not choose. After making choice, CCallback::selectionMade should be called with number of selected component (1 - n) or 0 for cancel (if allowed) and askID. virtual void tileRevealed(int3 pos); diff --git a/CGameInterface.h b/CGameInterface.h index 1f6ffd32e..e4baa668d 100644 --- a/CGameInterface.h +++ b/CGameInterface.h @@ -78,7 +78,7 @@ public: virtual void heroInGarrisonChange(const CGTownInstance *town){}; //virtual void heroKilled(const CGHeroInstance*){}; virtual void heroMoved(const TryMoveHero & details){}; - virtual void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, int val){}; + virtual void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, si64 val){}; virtual void heroManaPointsChanged(const CGHeroInstance * hero){} //not called at the beginning of turn and after spell casts virtual void heroMovePointsChanged(const CGHeroInstance * hero){} //not called at the beginning of turn and after movement virtual void heroVisitsTown(const CGHeroInstance* hero, const CGTownInstance * town){}; diff --git a/client/CPlayerInterface.cpp b/client/CPlayerInterface.cpp index b304ad924..70639d0bd 100644 --- a/client/CPlayerInterface.cpp +++ b/client/CPlayerInterface.cpp @@ -804,7 +804,7 @@ int3 CPlayerInterface::repairScreenPos(int3 pos) pos.y = CGI->mh->map->height - this->adventureInt->terrain.tilesh + CGI->mh->frameH; return pos; } -void CPlayerInterface::heroPrimarySkillChanged(const CGHeroInstance * hero, int which, int val) +void CPlayerInterface::heroPrimarySkillChanged(const CGHeroInstance * hero, int which, si64 val) { if(which >= PRIMARY_SKILLS) //no need to redraw infowin if this is experience (exp is treated as prim skill with id==4) return; diff --git a/client/CPlayerInterface.h b/client/CPlayerInterface.h index 782d48019..cc2a20e80 100644 --- a/client/CPlayerInterface.h +++ b/client/CPlayerInterface.h @@ -139,7 +139,7 @@ public: void heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector &skills, boost::function &callback); void heroInGarrisonChange(const CGTownInstance *town); void heroMoved(const TryMoveHero & details); - void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, int val); + void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, si64 val); void heroManaPointsChanged(const CGHeroInstance * hero); void heroMovePointsChanged(const CGHeroInstance * hero); void heroVisitsTown(const CGHeroInstance* hero, const CGTownInstance * town); diff --git a/client/Client.h b/client/Client.h index 698a51f7f..5e54cb2f1 100644 --- a/client/Client.h +++ b/client/Client.h @@ -89,7 +89,7 @@ public: void setOwner(int objid, ui8 owner){}; void setHoverName(int objid, MetaString * name){}; void setObjProperty(int objid, int prop, int val){}; - void changePrimSkill(int ID, int which, int val, bool abs=false){}; + void changePrimSkill(int ID, int which, si64 val, bool abs=false){}; void changeSecSkill(int ID, int which, int val, bool abs=false){}; void showInfoDialog(InfoWindow *iw){}; void showBlockingDialog(BlockingDialog *iw, const CFunctionList &callback){}; diff --git a/hch/CHeroHandler.cpp b/hch/CHeroHandler.cpp index e0b2f7b13..a6df2131c 100644 --- a/hch/CHeroHandler.cpp +++ b/hch/CHeroHandler.cpp @@ -378,27 +378,30 @@ void CHeroHandler::initHeroClasses() loadNativeTerrains(); } -unsigned int CHeroHandler::level(ui64 experience) +unsigned int CHeroHandler::level (ui64 experience) { int i; - if(experience <= expPerLevel.back()) + if (experience <= expPerLevel.back()) { for(i = expPerLevel.size()-1; experience < expPerLevel[i]; i--); return i + 1; } else { - for(i = expPerLevel.size(); experience > reqExp(i); i++); - return i - 1; + //for(i = expPerLevel.size(); experience > reqExp(i); i++); + i = expPerLevel.size(); + while (experience > reqExp (i)) + i++; + return i; } } -ui64 CHeroHandler::reqExp(unsigned int level) +ui64 CHeroHandler::reqExp (unsigned int level) { if(!level) return 0; - if(level<=expPerLevel.size()) + if(level <= expPerLevel.size()) { return expPerLevel[level - 1]; } @@ -412,7 +415,13 @@ ui64 CHeroHandler::reqExp(unsigned int level) // exp*=1.2; //} //return exp; - return (ui64)(reqExp(level - 1) + (reqExp(level - 1) - reqExp(level - 2)) * 1.2); //inefficient but follows exactly H3 values + while (level > expPerLevel.size()) + { + int i = expPerLevel.size() - 1; + expPerLevel.push_back ((ui64)(expPerLevel[i] + (expPerLevel[i] - expPerLevel[i-1]) * 1.2)); + } + return expPerLevel[level-1]; + //return (ui64)(reqExp(level - 1) + (reqExp(level - 1) - reqExp(level - 2)) * 1.2); //inefficient but follows exactly H3 values } } diff --git a/hch/CObjectHandler.cpp b/hch/CObjectHandler.cpp index 39ea736af..392bbb56a 100644 --- a/hch/CObjectHandler.cpp +++ b/hch/CObjectHandler.cpp @@ -1373,7 +1373,7 @@ void CGVisitableOPH::initObj() ttype = -1; } -void CGVisitableOPH::treeSelected( int heroID, int resType, int resVal, int expVal, ui32 result ) const +void CGVisitableOPH::treeSelected( int heroID, int resType, int resVal, ui64 expVal, ui32 result ) const { if(result) //player agreed to give res for exp { @@ -2781,7 +2781,7 @@ void CGEvent::onHeroVisit( const CGHeroInstance * h ) const activated(h); } -void CGEvent::endBattle( const CGHeroInstance *h, BattleResult *result ) const +void CGPandoraBox::endBattle( const CGHeroInstance *h, BattleResult *result ) const { if(result->winner) return; @@ -2808,7 +2808,49 @@ void CGEvent::activated( const CGHeroInstance * h ) const } } -void CGEvent::giveContents( const CGHeroInstance *h, bool afterBattle ) const +void CGPandoraBox::initObj() +{ + blockVisit = true; +} +void CGPandoraBox::onHeroVisit(const CGHeroInstance * h) const +{ + BlockingDialog bd (true, false); + bd.player = h->getOwner(); + bd.soundID = soundBase::QUEST; + bd.text.addTxt (MetaString::ADVOB_TXT, 14); + cb->showBlockingDialog (&bd, boost::bind (&CGPandoraBox::open, this, h, _1)); +} +void CGPandoraBox::open( const CGHeroInstance * h, ui32 accept ) const +{ + if (accept) + { + if (army) + { + InfoWindow iw; + iw.player = h->tempOwner; + iw.text.addTxt(MetaString::ADVOB_TXT, 16); + cb->showInfoDialog(&iw); + cb->startBattleI(h, this, boost::bind(&CGPandoraBox::endBattle, this, h,_1)); + } + else if (message.size() == resources.size() == + primskills.size() == abilities.size() == + abilityLevels.size() == artifacts.size() == + spells.size() == creatures == + gainedExp == manaDiff == moraleDiff == luckDiff == 0) //yeaha! + { + InfoWindow iw; + iw.player = h->tempOwner; + iw.text.addTxt(MetaString::ADVOB_TXT, 15); + cb->showInfoDialog(&iw); + + } + else + { + giveContents (h, false); + } + } +} +void CGPandoraBox::giveContents( const CGHeroInstance *h, bool afterBattle ) const { InfoWindow iw; iw.player = h->getOwner(); @@ -3011,12 +3053,7 @@ void CGEvent::giveContents( const CGHeroInstance *h, bool afterBattle ) const SetGarrisons sg; sg.garrs[id] = creatures; cb->sendAndApply(&sg); - - if(removeAfterVisit) - cb->showGarrisonDialog(id,h->id,boost::bind(&IGameCallback::removeObject,cb,id)); - else - cb->showGarrisonDialog(id,h->id,0); - return; + cb->showGarrisonDialog(id,h->id,boost::bind(&IGameCallback::removeObject,cb,id)); } if(!afterBattle && message.size()) @@ -3024,12 +3061,10 @@ void CGEvent::giveContents( const CGHeroInstance *h, bool afterBattle ) const iw.text << message; cb->showInfoDialog(&iw); } - - if(removeAfterVisit) - cb->removeObject(id); + cb->removeObject(id); } -void CGEvent::getText( InfoWindow &iw, bool &afterBattle, int text, const CGHeroInstance * h ) const +void CGPandoraBox::getText( InfoWindow &iw, bool &afterBattle, int text, const CGHeroInstance * h ) const { if(afterBattle || !message.size()) { @@ -3043,7 +3078,7 @@ void CGEvent::getText( InfoWindow &iw, bool &afterBattle, int text, const CGHero } } -void CGEvent::getText( InfoWindow &iw, bool &afterBattle, int val, int negative, int positive, const CGHeroInstance * h ) const +void CGPandoraBox::getText( InfoWindow &iw, bool &afterBattle, int val, int negative, int positive, const CGHeroInstance * h ) const { iw.components.clear(); iw.text.clear(); diff --git a/hch/CObjectHandler.h b/hch/CObjectHandler.h index fecbce764..215d7ad9a 100644 --- a/hch/CObjectHandler.h +++ b/hch/CObjectHandler.h @@ -413,7 +413,7 @@ public: void onHeroVisit(const CGHeroInstance * h) const; void onNAHeroVisit(int heroID, bool alreadyVisited) const; void initObj(); - void treeSelected(int heroID, int resType, int resVal, int expVal, ui32 result) const; //handle player's anwer to the Tree of Knowledge dialog + void treeSelected(int heroID, int resType, int resVal, ui64 expVal, ui32 result) const; //handle player's anwer to the Tree of Knowledge dialog void schoolSelected(int heroID, ui32 which) const; void arenaSelected(int heroID, int primSkill) const; @@ -424,10 +424,13 @@ public: } }; -class DLL_EXPORT CGEvent : public CArmedInstance //event objects +class DLL_EXPORT CGPandoraBox : public CArmedInstance { public: std::string message; + ui8 removeAfterVisit; //true if event is removed after occurring + + //gained things: ui32 gainedExp; si32 manaDiff; //amount of gained / lost mana si32 moraleDiff; //morale modifier @@ -439,26 +442,42 @@ public: std::vector artifacts; //gained artifacts std::vector spells; //gained spells CCreatureSet creatures; //gained creatures + + void CGPandoraBox::initObj(); + void onHeroVisit(const CGHeroInstance * h) const; + void open (const CGHeroInstance * h, ui32 accept) const; + void endBattle(const CGHeroInstance *h, BattleResult *result) const; + void giveContents(const CGHeroInstance *h, bool afterBattle) const; + void getText( InfoWindow &iw, bool &afterBattle, int val, int negative, int positive, const CGHeroInstance * h ) const; + void getText( InfoWindow &iw, bool &afterBattle, int text, const CGHeroInstance * h ) const; + + template void serialize(Handler &h, const int version) + { + h & static_cast(*this); + h & message & gainedExp & manaDiff & moraleDiff & luckDiff & resources & primskills + & abilities & abilityLevels & artifacts & spells & creatures & army; + } +}; + +class DLL_EXPORT CGEvent : public CGPandoraBox //event objects +{ +public: + ui8 availableFor; //players whom this event is available for ui8 computerActivate; //true if computre player can activate this event ui8 humanActivate; //true if human player can activate this event - ui8 removeAfterVisit; //true if event is removed after occurring template void serialize(Handler &h, const int version) { h & static_cast(*this); h & message & gainedExp & manaDiff & moraleDiff & luckDiff & resources & primskills & abilities & abilityLevels & artifacts & spells & creatures & availableFor - & computerActivate & humanActivate; + & computerActivate & humanActivate & army; } - - void activated(const CGHeroInstance * h) const; + void onHeroVisit(const CGHeroInstance * h) const; - void endBattle(const CGHeroInstance *h, BattleResult *result) const; - void giveContents(const CGHeroInstance *h, bool afterBattle) const; + void activated(const CGHeroInstance * h) const; - void getText( InfoWindow &iw, bool &afterBattle, int val, int negative, int positive, const CGHeroInstance * h ) const; - void getText( InfoWindow &iw, bool &afterBattle, int text, const CGHeroInstance * h ) const; }; class DLL_EXPORT CGCreature : public CArmedInstance //creatures on map @@ -634,32 +653,6 @@ public: } }; -class DLL_EXPORT CGPandoraBox : public CArmedInstance -{ -public: - std::string message; - - //gained things: - ui32 gainedExp; - si32 manaDiff; //amount of gained / lost mana - si32 moraleDiff; //morale modifier - si32 luckDiff; //luck modifier - std::vector resources;//gained / lost resources - std::vector primskills;//gained / lost resources - std::vector abilities; //gained abilities - std::vector abilityLevels; //levels of gained abilities - std::vector artifacts; //gained artifacts - std::vector spells; //gained spells - CCreatureSet creatures; //gained creatures - - template void serialize(Handler &h, const int version) - { - h & static_cast(*this); - h & message & gainedExp & manaDiff & moraleDiff & luckDiff & resources & primskills - & abilities & abilityLevels & artifacts & spells & creatures; - } -}; - class DLL_EXPORT CGQuestGuard : public CGObjectInstance, public CQuest { public: diff --git a/lib/IGameCallback.h b/lib/IGameCallback.h index 933b2005d..f58b2861a 100644 --- a/lib/IGameCallback.h +++ b/lib/IGameCallback.h @@ -65,7 +65,7 @@ public: virtual void setOwner(int objid, ui8 owner)=0; virtual void setHoverName(int objid, MetaString * name)=0; virtual void setObjProperty(int objid, int prop, int val)=0; - virtual void changePrimSkill(int ID, int which, int val, bool abs=false)=0; + virtual void changePrimSkill(int ID, int which, si64 val, bool abs=false)=0; virtual void changeSecSkill(int ID, int which, int val, bool abs=false)=0; virtual void showInfoDialog(InfoWindow *iw)=0; virtual void showBlockingDialog(BlockingDialog *iw, const CFunctionList &callback)=0; diff --git a/lib/NetPacks.h b/lib/NetPacks.h index d4f6d5e7b..7f997c34c 100644 --- a/lib/NetPacks.h +++ b/lib/NetPacks.h @@ -237,7 +237,8 @@ struct SetPrimSkill : public CPackForClient //105 ui8 abs; //0 - changes by value; 1 - sets to value si32 id; - ui16 which, val; + ui16 which; + si64 val; template void serialize(Handler &h, const int version) { diff --git a/lib/RegisterTypes.cpp b/lib/RegisterTypes.cpp index b112d4b6d..025d1769d 100644 --- a/lib/RegisterTypes.cpp +++ b/lib/RegisterTypes.cpp @@ -22,6 +22,7 @@ void registerTypes1(Serializer &s) { s.template registerType(); s.template registerType(); + s.template registerType(); s.template registerType(); s.template registerType(); s.template registerType(); @@ -37,7 +38,6 @@ void registerTypes1(Serializer &s) s.template registerType(); s.template registerType(); s.template registerType(); - s.template registerType(); s.template registerType(); s.template registerType(); s.template registerType(); diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index f00caca4d..704e711e0 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -211,7 +211,7 @@ void CGameHandler::changeSecSkill( int ID, int which, int val, bool abs/*=false* } } -void CGameHandler::changePrimSkill(int ID, int which, int val, bool abs) +void CGameHandler::changePrimSkill(int ID, int which, si64 val, bool abs) { SetPrimSkill sps; sps.id = ID; diff --git a/server/CGameHandler.h b/server/CGameHandler.h index b1f5f6910..79e1b3b2f 100644 --- a/server/CGameHandler.h +++ b/server/CGameHandler.h @@ -108,7 +108,7 @@ public: void setOwner(int objid, ui8 owner); void setHoverName(int objid, MetaString * name); void setObjProperty(int objid, int prop, int val); - void changePrimSkill(int ID, int which, int val, bool abs=false); + void changePrimSkill(int ID, int which, si64 val, bool abs=false); void changeSecSkill(int ID, int which, int val, bool abs=false); void showInfoDialog(InfoWindow *iw); void showBlockingDialog(BlockingDialog *iw, const CFunctionList &callback);