diff --git a/AI/GeniusAI/CGeniusAI.cpp b/AI/GeniusAI/CGeniusAI.cpp index 3ce6ba6d0..f83e66dfa 100644 --- a/AI/GeniusAI/CGeniusAI.cpp +++ b/AI/GeniusAI/CGeniusAI.cpp @@ -1305,7 +1305,7 @@ void CGeniusAI::battleNewRound(int round) /** * */ -void CGeniusAI::battleStackMoved(int ID, int dest, int distance, bool end) +void CGeniusAI::battleStackMoved(int ID, THex dest, int distance, bool end) { std::string message("\t\t\tCGeniusAI::battleStackMoved ID("); message += boost::lexical_cast(ID); @@ -1338,13 +1338,13 @@ void CGeniusAI::battleSpellCast(const BattleSpellCast *sc) /** * */ -void CGeniusAI::battleStackMoved(int ID, - int dest, - bool startMoving, - bool endMoving) -{ - DbgBox("\t\t\tCGeniusAI::battleStackMoved"); -} +// void CGeniusAI::battleStackMoved(int ID, +// THex dest, +// bool startMoving, +// bool endMoving) +// { +// DbgBox("\t\t\tCGeniusAI::battleStackMoved"); +// } /** @@ -1372,15 +1372,25 @@ void CGeniusAI::battleStackIsAttacked(int ID, /** * called when it's turn of that stack */ -BattleAction CGeniusAI::activeStack(int stackID) +BattleAction CGeniusAI::activeStack(const CStack * stack) { std::string message("\t\t\tCGeniusAI::activeStack stackID("); - message += boost::lexical_cast(stackID); + message += boost::lexical_cast(stack->ID); message += ")"; DbgBox(message.c_str()); - BattleAction bact = m_battleLogic->MakeDecision(stackID); + BattleAction bact = m_battleLogic->MakeDecision(stack->ID); assert(m_cb->battleGetStackByID(bact.stackNumber)); return bact; -}; +} + + +//WTF?!? why is this needed?!?!?! +BattleAction CGlobalAI::activeStack( const CStack * stack ) +{ + BattleAction ba; ba.actionType = BattleAction::DEFEND; + ba.stackNumber = stack->ID; + return ba; +} + diff --git a/AI/GeniusAI/CGeniusAI.h b/AI/GeniusAI/CGeniusAI.h index 8cd1e5f8a..477513e14 100644 --- a/AI/GeniusAI/CGeniusAI.h +++ b/AI/GeniusAI/CGeniusAI.h @@ -205,15 +205,15 @@ public: virtual void battleStacksAttacked(const std::set & bsa); //called when stack receives damage (after battleAttack()) virtual void battleEnd(const BattleResult *br); virtual void battleNewRound(int round); //called at the beggining of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn - virtual void battleStackMoved(int ID, int dest, int distance, bool end); + virtual void battleStackMoved(int ID, THex dest, int distance, bool end); virtual void battleSpellCast(const BattleSpellCast *sc); virtual void battleStart(const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool side); //called by engine when battle starts; side=0 - left, side=1 - right //virtual void battlefieldPrepared(int battlefieldType, std::vector obstacles); //called when battlefield is prepared, prior the battle beginning // - virtual void battleStackMoved(int ID, int dest, bool startMoving, bool endMoving); + //virtual void battleStackMoved(int ID, int dest, bool startMoving, bool endMoving); virtual void battleStackAttacking(int ID, int dest); virtual void battleStackIsAttacked(int ID, int dmg, int killed, int IDby, bool byShooting); - virtual BattleAction activeStack(int stackID); + virtual BattleAction activeStack(const CStack * stack); void battleResultsApplied(); friend class Priorities; }; diff --git a/AI/StupidAI/StupidAI.cpp b/AI/StupidAI/StupidAI.cpp index 854dad265..2ef10e5b8 100644 --- a/AI/StupidAI/StupidAI.cpp +++ b/AI/StupidAI/StupidAI.cpp @@ -1,5 +1,6 @@ #include "stdafx.h" #include "StupidAI.h" +#include "../../lib/CGameState.h" CStupidAI::CStupidAI(void) { @@ -25,10 +26,10 @@ void CStupidAI::actionStarted( const BattleAction *action ) } -BattleAction CStupidAI::activeStack( int stackID ) +BattleAction CStupidAI::activeStack( const CStack * stack ) { BattleAction ba; - ba.DEFEND; - ba.stackNumber = stackID; + ba.actionType = BattleAction::DEFEND; + ba.stackNumber = stack->ID; return ba; } \ No newline at end of file diff --git a/AI/StupidAI/StupidAI.h b/AI/StupidAI/StupidAI.h index b750995ba..1859c2629 100644 --- a/AI/StupidAI/StupidAI.h +++ b/AI/StupidAI/StupidAI.h @@ -9,6 +9,6 @@ public: void init(IBattleCallback * CB) OVERRIDE; void actionFinished(const BattleAction *action) OVERRIDE;//occurs AFTER every action taken by any stack or by the hero void actionStarted(const BattleAction *action) OVERRIDE;//occurs BEFORE every action taken by any stack or by the hero - BattleAction activeStack(int stackID) OVERRIDE; //called when it's turn of that stack + BattleAction activeStack(const CStack * stack) OVERRIDE; //called when it's turn of that stack }; diff --git a/CGameInterface.cpp b/CGameInterface.cpp index ced9c862b..ed2293e86 100644 --- a/CGameInterface.cpp +++ b/CGameInterface.cpp @@ -1,5 +1,6 @@ #include "stdafx.h" #include "CGameInterface.h" +#include "lib/CGameState.h" #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN //excludes rarely used stuff from windows headers - delete this line if something is missing @@ -70,3 +71,10 @@ CBattleGameInterface * CAIHandler::getNewBattleAI( CCallback * cb, std::string d { return createAnyAI(cb, dllname, "GetNewBattleAI"); } + +BattleAction CGlobalAI::activeStack( const CStack * stack ) +{ + BattleAction ba; ba.actionType = BattleAction::DEFEND; + ba.stackNumber = stack->ID; + return ba; +} diff --git a/CGameInterface.h b/CGameInterface.h index 9075d4ef0..ca40476cc 100644 --- a/CGameInterface.h +++ b/CGameInterface.h @@ -45,6 +45,7 @@ struct CatapultAttack; struct BattleStacksRemoved; struct StackLocation; class CStackInstance; +class CStack; class CCreature; class CLoadFile; class CSaveFile; @@ -66,20 +67,19 @@ public: //battle call-ins virtual void actionFinished(const BattleAction *action){};//occurs AFTER every action taken by any stack or by the hero virtual void actionStarted(const BattleAction *action){};//occurs BEFORE every action taken by any stack or by the hero - virtual BattleAction activeStack(int stackID)=0; //called when it's turn of that stack + virtual BattleAction activeStack(const CStack * stack)=0; //called when it's turn of that stack virtual void battleAttack(const BattleAttack *ba){}; //called when stack is performing attack virtual void battleStacksAttacked(const std::vector & bsa){}; //called when stack receives damage (after battleAttack()) virtual void battleEnd(const BattleResult *br){}; virtual void battleResultsApplied(){}; //called when all effects of last battle are applied virtual void battleNewRoundFirst(int round){}; //called at the beginning of each turn before changes are applied; virtual void battleNewRound(int round){}; //called at the beggining of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn - virtual void battleStackMoved(int ID, int dest, int distance, bool end){}; + virtual void battleStackMoved(int ID, THex dest, int distance, bool end){}; virtual void battleSpellCast(const BattleSpellCast *sc){}; virtual void battleStacksEffectsSet(const SetStackEffect & sse){};//called when a specific effect is set to stacks virtual void battleStart(const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool side){}; //called by engine when battle starts; side=0 - left, side=1 - right - //virtual void battlefieldPrepared(int battlefieldType, std::vector obstacles){}; //called when battlefield is prepared, prior the battle beginning virtual void battleStacksHealedRes(const std::vector > & healedStacks, bool lifeDrain, si32 lifeDrainFrom){}; //called when stacks are healed / resurrected first element of pair - stack id, second - healed hp - virtual void battleNewStackAppeared(int stackID){}; //not called at the beginning of a battle or by resurrection; called eg. when elemental is summoned + virtual void battleNewStackAppeared(const CStack * stack){}; //not called at the beginning of a battle or by resurrection; called eg. when elemental is summoned virtual void battleObstaclesRemoved(const std::set & removedObstacles){}; //called when a certain set of obstacles is removed from batlefield; IDs of them are given virtual void battleCatapultAttacked(const CatapultAttack & ca){}; //called when catapult makes an attack virtual void battleStacksRemoved(const BattleStacksRemoved & bsr){}; //called when certain stack is completely removed from battlefield @@ -154,13 +154,13 @@ class CGlobalAI : public CGameInterface // AI class (to derivate) { public: //CGlobalAI(); - virtual void yourTurn(){}; + virtual void yourTurn() OVERRIDE{}; virtual void heroKilled(const CGHeroInstance*){}; - virtual void heroCreated(const CGHeroInstance*){}; - virtual void battleStackMoved(int ID, int dest, int distance){}; - virtual void battleStackAttacking(int ID, int dest){}; - virtual void battleStackIsAttacked(int ID, int dmg, int killed, int IDby, bool byShooting){}; - virtual BattleAction activeStack(int stackID) {BattleAction ba; ba.actionType = 3; ba.stackNumber = stackID; return ba;}; + virtual void heroCreated(const CGHeroInstance*) OVERRIDE{}; + virtual void battleStackMoved(int ID, THex dest, int distance, bool end) OVERRIDE{}; + virtual void battleStackAttacking(int ID, int dest) {}; + virtual void battleStacksAttacked(const std::vector & bsa) OVERRIDE{}; + virtual BattleAction activeStack(const CStack * stack) OVERRIDE; }; #endif // __CGAMEINTERFACE_H__ diff --git a/client/CBattleInterface.cpp b/client/CBattleInterface.cpp index 706408498..f711d9d4c 100644 --- a/client/CBattleInterface.cpp +++ b/client/CBattleInterface.cpp @@ -304,7 +304,7 @@ void CSpellEffectAnim::endAnim() delete this; } -CSpellEffectAnim::CSpellEffectAnim(CBattleInterface * _owner, ui32 _effect, int _destTile, int _dx, int _dy, bool _Vflip) +CSpellEffectAnim::CSpellEffectAnim(CBattleInterface * _owner, ui32 _effect, THex _destTile, int _dx, int _dy, bool _Vflip) :CBattleAnimation(_owner), effect(_effect), destTile(_destTile), customAnim(""), dx(_dx), dy(_dy), Vflip(_Vflip) { } @@ -321,7 +321,7 @@ CBattleStackAnimation::CBattleStackAnimation(CBattleInterface * _owner, int stac { } -bool CBattleStackAnimation::isToReverseHlp(int hexFrom, int hexTo, bool curDir) +bool CBattleStackAnimation::isToReverseHlp(THex hexFrom, THex hexTo, bool curDir) { int fromMod = hexFrom % BFIELD_WIDTH; int fromDiv = hexFrom / BFIELD_WIDTH; @@ -347,7 +347,7 @@ bool CBattleStackAnimation::isToReverseHlp(int hexFrom, int hexTo, bool curDir) return false; //should never happen } -bool CBattleStackAnimation::isToReverse(int hexFrom, int hexTo, bool curDir, bool toDoubleWide, bool toDir) +bool CBattleStackAnimation::isToReverse(THex hexFrom, THex hexTo, bool curDir, bool toDoubleWide, bool toDir) { if(hexTo < 0) //turret return false; @@ -442,7 +442,7 @@ void CReverseAnim::endAnim() delete this; } -CReverseAnim::CReverseAnim(CBattleInterface * _owner, int stack, int dest, bool _priority) +CReverseAnim::CReverseAnim(CBattleInterface * _owner, int stack, THex dest, bool _priority) : CBattleStackAnimation(_owner, stack), partOfAnim(1), secondPartSetup(false), hex(dest), priority(_priority) { } @@ -723,7 +723,7 @@ void CBattleStackMoved::endAnim() delete this; } -CBattleStackMoved::CBattleStackMoved(CBattleInterface * _owner, int _number, int _destHex, bool _endMoving, int _distance) +CBattleStackMoved::CBattleStackMoved(CBattleInterface * _owner, int _number, THex _destHex, bool _endMoving, int _distance) : CBattleStackAnimation(_owner, _number), destHex(_destHex), endMoving(_endMoving), distance(_distance), stepX(0.0f), stepY(0.0f) { curStackPos = owner->curInt->cb->battleGetPos(stackID); @@ -815,7 +815,7 @@ void CBattleMoveEnd::endAnim() delete this; } -CBattleMoveEnd::CBattleMoveEnd(CBattleInterface * _owner, int stack, int destTile) +CBattleMoveEnd::CBattleMoveEnd(CBattleInterface * _owner, int stack, THex destTile) : CBattleStackAnimation(_owner, stack), destinationTile(destTile) { } @@ -847,7 +847,7 @@ bool CBattleAttack::checkInitialConditions() return isEarliest(false); } -CBattleAttack::CBattleAttack(CBattleInterface * _owner, int _stackID, int _dest, int _attackedID) +CBattleAttack::CBattleAttack(CBattleInterface * _owner, int _stackID, THex _dest, int _attackedID) : CBattleStackAnimation(_owner, _stackID), dest(_dest) { attackedStack = owner->curInt->cb->battleGetStackByID(_attackedID, false); @@ -954,7 +954,7 @@ void CMeleeAttack::endAnim() delete this; } -CMeleeAttack::CMeleeAttack(CBattleInterface * _owner, int attacker, int _dest, int _attackedID) +CMeleeAttack::CMeleeAttack(CBattleInterface * _owner, int attacker, THex _dest, int _attackedID) : CBattleAttack(_owner, attacker, _dest, _attackedID) { } @@ -1081,7 +1081,7 @@ void CShootingAnim::endAnim() delete this; } -CShootingAnim::CShootingAnim(CBattleInterface * _owner, int attacker, int _dest, int _attackedID, bool _catapult, int _catapultDmg) +CShootingAnim::CShootingAnim(CBattleInterface * _owner, int attacker, THex _dest, int _attackedID, bool _catapult, int _catapultDmg) : CBattleAttack(_owner, attacker, _dest, _attackedID), catapultDamage(_catapultDmg), catapult(_catapult) { if(catapult) //catapult attack @@ -1145,7 +1145,7 @@ CBattleInterface::CBattleInterface(const CCreatureSet * army1, const CCreatureSe std::vector stacks = curInt->cb->battleGetStacks(); BOOST_FOREACH(const CStack *s, stacks) { - newStack(s->ID); + newStack(s); } //preparing menu background and terrain @@ -2225,37 +2225,36 @@ void CBattleInterface::bConsoleDownf() console->scrollDown(); } -void CBattleInterface::newStack(int stackID) +void CBattleInterface::newStack(const CStack * stack) { - const CStack * newStack = curInt->cb->battleGetStackByID(stackID); + Point coords = CBattleHex::getXYUnitAnim(stack->position, stack->owner == attackingHeroInstance->tempOwner, stack, this);; - Point coords = CBattleHex::getXYUnitAnim(newStack->position, newStack->owner == attackingHeroInstance->tempOwner, newStack, this);; - - if(newStack->position < 0) //turret + if(stack->position < 0) //turret { const CCreature & turretCreature = *CGI->creh->creatures[ CGI->creh->factionToTurretCreature[siegeH->town->town->typeID] ]; - creAnims[stackID] = new CCreatureAnimation(turretCreature.animDefName); + creAnims[stack->ID] = new CCreatureAnimation(turretCreature.animDefName); } else { - creAnims[stackID] = new CCreatureAnimation(newStack->getCreature()->animDefName); + creAnims[stack->ID] = new CCreatureAnimation(stack->getCreature()->animDefName); } - creAnims[stackID]->setType(2); - creAnims[stackID]->pos = Rect(coords.x, coords.y, creAnims[newStack->ID]->fullWidth, creAnims[newStack->ID]->fullHeight); - creDir[stackID] = newStack->attackerOwned; + creAnims[stack->ID]->setType(2); + creAnims[stack->ID]->pos = Rect(coords.x, coords.y, creAnims[stack->ID]->fullWidth, creAnims[stack->ID]->fullHeight); + creDir[stack->ID] = stack->attackerOwned; } -void CBattleInterface::stackRemoved(int stackID) +void CBattleInterface::stackRemoved(const CStack * stack) { + int stackID = stack->ID; delete creAnims[stackID]; creAnims.erase(stackID); creDir.erase(stackID); } -void CBattleInterface::stackActivated(int number) +void CBattleInterface::stackActivated(const CStack * stack) { //givenCommand = NULL; - stackToActivate = number; + stackToActivate = stack->ID; if(pendingAnims.size() == 0) activateStack(); } @@ -2273,9 +2272,16 @@ void CBattleInterface::stacksAreAttacked(std::vector attacke } } -void CBattleInterface::stackAttacking(int ID, int dest, int attackedID) +void CBattleInterface::stackAttacking( const CStack * attacker, THex dest, const CStack * attacked, bool shooting ) { - addNewAnim(new CMeleeAttack(this, ID, dest, attackedID)); + if (shooting) + { + addNewAnim(new CShootingAnim(this, attacker->ID, dest, attacked->ID)); + } + else + { + addNewAnim(new CMeleeAttack(this, attacker->ID, dest, attacked->ID)); + } } void CBattleInterface::newRoundFirst( int round ) @@ -2636,11 +2642,6 @@ void CBattleInterface::hexLclicked(int whichOne) } } -void CBattleInterface::stackIsShooting(int ID, int dest, int attackedID) -{ - addNewAnim(new CShootingAnim(this, ID, dest, attackedID)); -} - void CBattleInterface::stackIsCatapulting(const CatapultAttack & ca) { for(std::set< std::pair< std::pair< ui8, si16 >, ui8> >::const_iterator it = ca.attackedParts.begin(); it != ca.attackedParts.end(); ++it) diff --git a/client/CBattleInterface.h b/client/CBattleInterface.h index 0052c6add..3a34e5327 100644 --- a/client/CBattleInterface.h +++ b/client/CBattleInterface.h @@ -91,7 +91,7 @@ class CSpellEffectAnim : public CBattleAnimation { private: ui32 effect; - int destTile; + THex destTile; std::string customAnim; int x, y, dx, dy; bool Vflip; @@ -100,7 +100,7 @@ public: void nextFrame(); void endAnim(); - CSpellEffectAnim(CBattleInterface * _owner, ui32 _effect, int _destTile, int _dx = 0, int _dy = 0, bool _Vflip = false); + CSpellEffectAnim(CBattleInterface * _owner, ui32 _effect, THex _destTile, int _dx = 0, int _dy = 0, bool _Vflip = false); CSpellEffectAnim(CBattleInterface * _owner, std::string _customAnim, int _x, int _y, int _dx = 0, int _dy = 0, bool _Vflip = false); }; @@ -110,8 +110,8 @@ public: int stackID; //id of stack whose animation it is CBattleStackAnimation(CBattleInterface * _owner, int stack); - static bool isToReverseHlp(int hexFrom, int hexTo, bool curDir); //helper for isToReverse - static bool isToReverse(int hexFrom, int hexTo, bool curDir /*if true, creature is in attacker's direction*/, bool toDoubleWide, bool toDir); //determines if creature should be reversed (it stands on hexFrom and should 'see' hexTo) + static bool isToReverseHlp(THex hexFrom, THex hexTo, bool curDir); //helper for isToReverse + static bool isToReverse(THex hexFrom, THex hexTo, bool curDir /*if true, creature is in attacker's direction*/, bool toDoubleWide, bool toDir); //determines if creature should be reversed (it stands on hexFrom and should 'see' hexTo) }; class CReverseAnim : public CBattleStackAnimation @@ -119,14 +119,14 @@ class CReverseAnim : public CBattleStackAnimation private: int partOfAnim; //1 - first, 2 - second bool secondPartSetup; - int hex; + THex hex; public: bool priority; //true - high, false - low bool init(); void nextFrame(); void endAnim(); - CReverseAnim(CBattleInterface * _owner, int stack, int dest, bool _priority); + CReverseAnim(CBattleInterface * _owner, int stack, THex dest, bool _priority); }; class CDefenceAnim : public CBattleStackAnimation @@ -149,7 +149,7 @@ public: class CBattleStackMoved : public CBattleStackAnimation { private: - int destHex; //destination + THex destHex; //destination bool endMoving; //if this is end of move int distance; float stepX, stepY; //how far stack is moved in one frame @@ -161,7 +161,7 @@ public: void nextFrame(); void endAnim(); - CBattleStackMoved(CBattleInterface * _owner, int _number, int _destHex, bool _endMoving, int _distance); + CBattleStackMoved(CBattleInterface * _owner, int _number, THex _destHex, bool _endMoving, int _distance); }; class CBattleMoveStart : public CBattleStackAnimation @@ -177,20 +177,20 @@ public: class CBattleMoveEnd : public CBattleStackAnimation { private: - int destinationTile; + THex destinationTile; public: bool init(); void nextFrame(); void endAnim(); - CBattleMoveEnd(CBattleInterface * _owner, int stack, int destTile); + CBattleMoveEnd(CBattleInterface * _owner, int stack, THex destTile); }; class CBattleAttack : public CBattleStackAnimation { protected: int IDby; //attacked stack - int dest; //atacked hex + THex dest; //atacked hex int posShiftDueToDist; bool shooting; int group; //if shooting is true, print this animation group @@ -203,7 +203,7 @@ public: bool checkInitialConditions(); - CBattleAttack(CBattleInterface * _owner, int _stackID, int _dest, int _attackedID); + CBattleAttack(CBattleInterface * _owner, int _stackID, THex _dest, int _attackedID); }; class CMeleeAttack : public CBattleAttack @@ -213,7 +213,7 @@ public: void nextFrame(); void endAnim(); - CMeleeAttack(CBattleInterface * _owner, int attacker, int _dest, int _attackedID); + CMeleeAttack(CBattleInterface * _owner, int attacker, THex _dest, int _attackedID); }; class CShootingAnim : public CBattleAttack @@ -226,7 +226,7 @@ public: void nextFrame(); void endAnim(); - CShootingAnim(CBattleInterface * _owner, int attacker, int _dest, int _attackedID, bool _catapult = false, int _catapultDmg = 0); //last param only for catapult attacks + CShootingAnim(CBattleInterface * _owner, int attacker, THex _dest, int _attackedID, bool _catapult = false, int _catapultDmg = 0); //last param only for catapult attacks }; //end of battle animation handlers @@ -491,17 +491,15 @@ public: //call-ins void startAction(const BattleAction* action); - void newStack(int stackID); //new stack appeared on battlefield - void stackRemoved(int stackID); //stack disappeared from batlefiled - //void stackKilled(int ID, int dmg, int killed, int IDby, bool byShooting); //stack has been killed (but corpses remain) - void stackActivated(int number); //active stack has been changed + void newStack(const CStack * stack); //new stack appeared on battlefield + void stackRemoved(const CStack * stack); //stack disappeared from batlefiled + void stackActivated(const CStack * stack); //active stack has been changed void stackMoved(int number, int destHex, bool endMoving, int distance); //stack with id number moved to destHex void stacksAreAttacked(std::vector attackedInfos); //called when a certain amount of stacks has been attacked - void stackAttacking(int ID, int dest, int attackedID); //called when stack with id ID is attacking something on hex dest + void stackAttacking(const CStack * attacker, THex dest, const CStack * attacked, bool shooting); //called when stack with id ID is attacking something on hex dest void newRoundFirst( int round ); void newRound(int number); //caled when round is ended; number is the number of round void hexLclicked(int whichOne); //hex only call-in - void stackIsShooting(int ID, int dest, int attackedID); //called when stack with id ID is shooting to hex dest void stackIsCatapulting(const CatapultAttack & ca); //called when a stack is attacking walls void battleFinished(const BattleResult& br); //called when battle is finished - battleresult window should be printed const BattleResult * bresult; //result of a battle; if non-zero then display when all animations end diff --git a/client/CHeroWindow.cpp b/client/CHeroWindow.cpp index 5ecd926d9..461622e93 100644 --- a/client/CHeroWindow.cpp +++ b/client/CHeroWindow.cpp @@ -201,7 +201,7 @@ void CHeroWindow::setHero(const CGHeroInstance *hero) for(size_t g=0; gsecSkills.size()); ++g) { int skill = hero->secSkills[g].first, - level = hero->getSecSkillLevel(hero->secSkills[g].first); + level = hero->getSecSkillLevel(static_cast(hero->secSkills[g].first)); secSkillAreas[g]->type = skill; secSkillAreas[g]->bonusValue = level; secSkillAreas[g]->text = CGI->generaltexth->skillInfoTexts[skill][level-1]; @@ -232,7 +232,7 @@ void CHeroWindow::setHero(const CGHeroInstance *hero) } dismissButton->block(!!hero->visitedTown || noDismiss); - if(hero->getSecSkillLevel(19) == 0) + if(hero->getSecSkillLevel(CGHeroInstance::TACTICS) == 0) tacticsButton->block(true); else { diff --git a/client/CKingdomInterface.cpp b/client/CKingdomInterface.cpp index c18f09031..18b9dc128 100644 --- a/client/CKingdomInterface.cpp +++ b/client/CKingdomInterface.cpp @@ -164,7 +164,7 @@ CKingdomInterface::CKingdomInterface() incomesVal[7] = incomesVal[6]*1000;//gold mines -> total income std::vector heroes = LOCPLINT->cb->getHeroesInfo(true); for(size_t i=0; igetSecSkillLevel(13))//some heroes may have estates + switch(heroes[i]->getSecSkillLevel(CGHeroInstance::ESTATES))//some heroes may have estates { case 1: //basic incomesVal[7] += 125; diff --git a/client/CPlayerInterface.cpp b/client/CPlayerInterface.cpp index e87fa2b47..1ceebdb05 100644 --- a/client/CPlayerInterface.cpp +++ b/client/CPlayerInterface.cpp @@ -600,7 +600,7 @@ void CPlayerInterface::battleStacksHealedRes(const std::vectornewStack(stackID); + battleInt->newStack(stack); } void CPlayerInterface::battleObstaclesRemoved(const std::set & removedObstacles) @@ -652,7 +652,7 @@ void CPlayerInterface::battleStacksRemoved(const BattleStacksRemoved & bsr) for(std::set::const_iterator it = bsr.stackIDs.begin(); it != bsr.stackIDs.end(); ++it) //for each removed stack { - battleInt->stackRemoved(*it); + battleInt->stackRemoved(LOCPLINT->cb->battleGetStackByID(*it)); } } @@ -692,14 +692,13 @@ void CPlayerInterface::actionFinished(const BattleAction* action) battleInt->endAction(action); } -BattleAction CPlayerInterface::activeStack(int stackID) //called when it's turn of that stack +BattleAction CPlayerInterface::activeStack(const CStack * stack) //called when it's turn of that stack { CBattleInterface *b = battleInt; { boost::unique_lock un(*pim); - const CStack *stack = cb->battleGetStackByID(stackID); if(vstd::contains(stack->state,MOVED)) //this stack has moved and makes second action -> high morale { std::string hlp = CGI->generaltexth->allTexts[33]; @@ -708,7 +707,7 @@ BattleAction CPlayerInterface::activeStack(int stackID) //called when it's turn battleInt->console->addText(hlp); } - b->stackActivated(stackID); + b->stackActivated(stack); } //wait till BattleInterface sets its command boost::unique_lock lock(b->givenCommand->mx); @@ -735,7 +734,7 @@ void CPlayerInterface::battleEnd(const BattleResult *br) battleInt->battleFinished(*br); } -void CPlayerInterface::battleStackMoved(int ID, int dest, int distance, bool end) +void CPlayerInterface::battleStackMoved(int ID, THex dest, int distance, bool end) { if(LOCPLINT != this) { //another local interface should do this @@ -819,14 +818,18 @@ void CPlayerInterface::battleAttack(const BattleAttack *ba) } //TODO: bad luck? + const CStack * attacker = cb->battleGetStackByID(ba->stackAttacking); + if(ba->shot()) { for(std::vector::const_iterator i = ba->bsa.begin(); i != ba->bsa.end(); i++) - battleInt->stackIsShooting(ba->stackAttacking,cb->battleGetPos(i->stackAttacked), i->stackAttacked); + { + const CStack * attacked = cb->battleGetStackByID(i->stackAttacked); + battleInt->stackAttacking(attacker, cb->battleGetPos(i->stackAttacked), attacked, true); + } } else {//WARNING: does not support multiple attacked creatures - const CStack * attacker = cb->battleGetStackByID(ba->stackAttacking); int shift = 0; if(ba->counter() && BattleInfo::mutualPosition(curAction->destinationTile, attacker->position) < 0) { @@ -838,7 +841,8 @@ void CPlayerInterface::battleAttack(const BattleAttack *ba) else shift = -1; } - battleInt->stackAttacking( ba->stackAttacking, ba->counter() ? curAction->destinationTile + shift : curAction->additionalInfo, ba->bsa.begin()->stackAttacked ); + const CStack * attacked = cb->battleGetStackByID(ba->bsa.begin()->stackAttacked); + battleInt->stackAttacking( attacker, ba->counter() ? curAction->destinationTile + shift : curAction->additionalInfo, attacked, false); } } diff --git a/client/CPlayerInterface.h b/client/CPlayerInterface.h index 939e5d30e..36abd20ed 100644 --- a/client/CPlayerInterface.h +++ b/client/CPlayerInterface.h @@ -158,7 +158,7 @@ public: const CGHeroInstance *getWHero(int pos); //returns NULL if position is not valid int getLastIndex(std::string namePrefix); - //overloaded funcs from CGameInterface + //overridden funcs from CGameInterface void buildChanged(const CGTownInstance *town, int buildingID, int what) OVERRIDE; //what: 1 - built, 2 - demolished void stackChagedCount(const StackLocation &location, const TQuantity &change, bool isAbsolute) OVERRIDE; //if absolute, change is the new count; otherwise count was modified by adding change void stackChangedType(const StackLocation &location, const CCreature &newType) OVERRIDE; //used eg. when upgrading creatures @@ -208,19 +208,18 @@ public: //for battles void actionFinished(const BattleAction* action) OVERRIDE;//occurs AFTER action taken by active stack or by the hero void actionStarted(const BattleAction* action) OVERRIDE;//occurs BEFORE action taken by active stack or by the hero - BattleAction activeStack(int stackID) OVERRIDE; //called when it's turn of that stack + BattleAction activeStack(const CStack * stack) OVERRIDE; //called when it's turn of that stack void battleAttack(const BattleAttack *ba) OVERRIDE; //stack performs attack void battleEnd(const BattleResult *br) OVERRIDE; //end of battle - //void battleResultQuited(); void battleNewRoundFirst(int round) OVERRIDE; //called at the beginning of each turn before changes are applied; used for HP regen handling void battleNewRound(int round) OVERRIDE; //called at the beggining of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn - void battleStackMoved(int ID, int dest, int distance, bool end) OVERRIDE; + void battleStackMoved(int ID, THex dest, int distance, bool end) OVERRIDE; void battleSpellCast(const BattleSpellCast *sc) OVERRIDE; void battleStacksEffectsSet(const SetStackEffect & sse) OVERRIDE; //called when a specific effect is set to stacks void battleStacksAttacked(const std::vector & bsa) OVERRIDE; void battleStart(const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool side) OVERRIDE; //called by engine when battle starts; side=0 - left, side=1 - right void battleStacksHealedRes(const std::vector > & healedStacks, bool lifeDrain, si32 lifeDrainFrom) OVERRIDE; //called when stacks are healed / resurrected - void battleNewStackAppeared(int stackID) OVERRIDE; //not called at the beginning of a battle or by resurrection; called eg. when elemental is summoned + void battleNewStackAppeared(const CStack * stack) OVERRIDE; //not called at the beginning of a battle or by resurrection; called eg. when elemental is summoned void battleObstaclesRemoved(const std::set & removedObstacles) OVERRIDE; //called when a certain set of obstacles is removed from batlefield; IDs of them are given void battleCatapultAttacked(const CatapultAttack & ca) OVERRIDE; //called when catapult makes an attack void battleStacksRemoved(const BattleStacksRemoved & bsr) OVERRIDE; //called when certain stack is completely removed from battlefield diff --git a/client/Client.cpp b/client/Client.cpp index 3b9053e43..1095b01a4 100644 --- a/client/Client.cpp +++ b/client/Client.cpp @@ -116,7 +116,7 @@ void CClient::waitForMoveAndSend(int color) { try { - BattleAction ba = playerint[color]->activeStack(gs->curB->activeStack); + BattleAction ba = playerint[color]->activeStack(gs->curB->getStack(gs->curB->activeStack, false)); *serv << &MakeAction(ba); return; }HANDLE_EXCEPTION diff --git a/client/GUIClasses.cpp b/client/GUIClasses.cpp index 7a96d644a..1d59b1f92 100644 --- a/client/GUIClasses.cpp +++ b/client/GUIClasses.cpp @@ -2304,7 +2304,9 @@ CLevelWindow::CLevelWindow(const CGHeroInstance *hero, int pskill, std::vectorgetSecSkillLevel(skills[i])+1,boost::bind(&CLevelWindow::selectionChanged,this,i))); + comps.push_back(new CSelectableComponent(SComponent::secskill44, skills[i], + hero->getSecSkillLevel( static_cast(skills[i]) )+1, + boost::bind(&CLevelWindow::selectionChanged,this,i))); comps.back()->assignedKeys.insert(SDLK_1 + i); } SDL_Surface *hhlp = BitmapHandler::loadBitmap("LVLUPBKG.bmp"); @@ -3734,7 +3736,7 @@ void CAltarWindow::calcTotalExp() val += valOfArt * arts->artifactsOnAltar.count(*i); } } - val *=(100+hero->getSecSkillLevel(21)*5)/100.0f; + val *=(100+hero->getSecSkillLevel(CGHeroInstance::LEARNING)*5)/100.0f; expOnAltar->setTxt(boost::lexical_cast(val)); } @@ -5866,7 +5868,7 @@ void CUniversityWindow::CItem::hover(bool on) int CUniversityWindow::CItem::state() { - if (parent->hero->getSecSkillLevel(ID))//hero know this skill + if (parent->hero->getSecSkillLevel(static_cast(ID)))//hero know this skill return 1; if (parent->hero->secSkills.size() >= SKILL_PER_HERO)//can't learn more skills return 0; diff --git a/client/NetPacksClient.cpp b/client/NetPacksClient.cpp index 42cdf7e54..7405f0709 100644 --- a/client/NetPacksClient.cpp +++ b/client/NetPacksClient.cpp @@ -575,9 +575,9 @@ void BattleSpellCast::applyCl( CClient *cl ) if(id >= 66 && id <= 69) //elemental summoning { if(cl->playerint.find(GS(cl)->curB->side1) != cl->playerint.end()) - cl->playerint[GS(cl)->curB->side1]->battleNewStackAppeared(GS(cl)->curB->stacks.size() - 1); + cl->playerint[GS(cl)->curB->side1]->battleNewStackAppeared(GS(cl)->curB->stacks[GS(cl)->curB->stacks.size() - 1]); if(cl->playerint.find(GS(cl)->curB->side2) != cl->playerint.end()) - cl->playerint[GS(cl)->curB->side2]->battleNewStackAppeared(GS(cl)->curB->stacks.size() - 1); + cl->playerint[GS(cl)->curB->side2]->battleNewStackAppeared(GS(cl)->curB->stacks[GS(cl)->curB->stacks.size() - 1]); } } diff --git a/global.h b/global.h index d379de21a..36d301773 100644 --- a/global.h +++ b/global.h @@ -16,6 +16,7 @@ typedef boost::int16_t si16; //signed int 16 bits (2 bytes) typedef boost::int8_t si8; //signed int 8 bits (1 byte) typedef si64 expType; typedef ui16 spelltype; +typedef ui16 THex; //for battle stacks' positions #include "int3.h" #include #include diff --git a/lib/CGameState.cpp b/lib/CGameState.cpp index fb8a75d97..47bbb5ef4 100644 --- a/lib/CGameState.cpp +++ b/lib/CGameState.cpp @@ -393,7 +393,7 @@ const CStack * BattleInfo::getStack(int stackID, bool onlyAlive) const return const_cast(this)->getStack(stackID, onlyAlive); } -CStack * BattleInfo::getStackT(int tileID, bool onlyAlive) +CStack * BattleInfo::getStackT(THex tileID, bool onlyAlive) { for(unsigned int g=0; g(this)->getStackT(tileID, onlyAlive); } @@ -639,7 +639,7 @@ bool BattleInfo::isStackBlocked(int ID) return false; } -signed char BattleInfo::mutualPosition(int hex1, int hex2) +signed char BattleInfo::mutualPosition(THex hex1, THex hex2) { if(hex2 == hex1 - ( (hex1/17)%2 ? 18 : 17 )) //top left return 0; @@ -1864,7 +1864,7 @@ void CGameState::init( StartInfo * si, ui32 checksum, int Seed ) } break; case 6: //sec skills - hero->setSecSkillLevel(curBonus.info2, curBonus.info3, true); + hero->setSecSkillLevel(static_cast(curBonus.info2), curBonus.info3, true); break; } } @@ -4789,7 +4789,7 @@ si8 BattleInfo::canTeleportTo(int stackID, int destHex, int telportLevel) // } // } -si8 BattleInfo::getDistance( int hex1, int hex2 ) +si8 BattleInfo::getDistance( THex hex1, THex hex2 ) { int xDst = std::abs(hex1 % BFIELD_WIDTH - hex2 % BFIELD_WIDTH), yDst = std::abs(hex1 / BFIELD_WIDTH - hex2 / BFIELD_WIDTH); diff --git a/lib/CGameState.h b/lib/CGameState.h index 5d7e27631..dc9467abf 100644 --- a/lib/CGameState.h +++ b/lib/CGameState.h @@ -229,8 +229,8 @@ struct DLL_EXPORT BattleInfo : public CBonusSystemNode void getStackQueue(std::vector &out, int howMany, int turn = 0, int lastMoved = -1) const; //returns stack in order of their movement action CStack * getStack(int stackID, bool onlyAlive = true); const CStack * getStack(int stackID, bool onlyAlive = true) const; - CStack * getStackT(int tileID, bool onlyAlive = true); - const CStack * getStackT(int tileID, bool onlyAlive = true) const; + CStack * getStackT(THex tileID, bool onlyAlive = true); + const CStack * getStackT(THex tileID, bool onlyAlive = true) const; void getAccessibilityMap(bool *accessibility, bool twoHex, bool attackerOwned, bool addOccupiable, std::set & occupyable, bool flying, int stackToOmmit=-1) const; //send pointer to at least 187 allocated bytes static bool isAccessible(int hex, bool * accessibility, bool twoHex, bool attackerOwned, bool flying, bool lastPos); //helper for makeBFS void makeBFS(int start, bool*accessibility, int *predecessor, int *dists, bool twoHex, bool attackerOwned, bool flying, bool fillPredecessors) const; //*accessibility must be prepared bool[187] array; last two pointers must point to the at least 187-elements int arrays - there is written result @@ -238,9 +238,9 @@ struct DLL_EXPORT BattleInfo : public CBonusSystemNode std::vector getAccessibility(int stackID, bool addOccupiable) const; //returns vector of accessible tiles (taking into account the creature range) bool isStackBlocked(int ID); //returns true if there is neighboring enemy stack - static signed char mutualPosition(int hex1, int hex2); //returns info about mutual position of given hexes (-1 - they're distant, 0 - left top, 1 - right top, 2 - right, 3 - right bottom, 4 - left bottom, 5 - left) + static signed char mutualPosition(THex hex1, THex hex2); //returns info about mutual position of given hexes (-1 - they're distant, 0 - left top, 1 - right top, 2 - right, 3 - right bottom, 4 - left bottom, 5 - left) static std::vector neighbouringTiles(int hex); - static si8 getDistance(int hex1, int hex2); //returns distance between given hexes + static si8 getDistance(THex hex1, THex hex2); //returns distance between given hexes ui32 calculateDmg(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting, ui8 charge, bool lucky); //charge - number of hexes travelled before attack (for champion's jousting) std::pair calculateDmgRange(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting, ui8 charge, bool lucky); //charge - number of hexes travelled before attack (for champion's jousting); returns pair void calculateCasualties(std::map *casualties) const; //casualties are array of maps size 2 (attacker, defeneder), maps are (crid => amount) @@ -272,7 +272,7 @@ public: ui32 firstHPleft; //HP of first creature in stack ui8 owner, slot; //owner - player colour (255 for neutrals), slot - position in garrison (may be 255 for neutrals/called creatures) ui8 attackerOwned; //if true, this stack is owned by attakcer (this one from left hand side of battle) - si16 position; //position on battlefield; -2 - keep, -3 - lower tower, -4 - upper tower + THex position; //position on battlefield; -2 - keep, -3 - lower tower, -4 - upper tower ui8 counterAttacks; //how many counter attacks can be performed more in this turn (by default set at the beginning of the round to 1) si16 shots; //how many shots left diff --git a/lib/CObjectHandler.cpp b/lib/CObjectHandler.cpp index fa48477ea..bbf153731 100644 --- a/lib/CObjectHandler.cpp +++ b/lib/CObjectHandler.cpp @@ -591,7 +591,7 @@ unsigned int CGHeroInstance::getTileCost(const TerrainTile &dest, const TerrainT else { ret = type->heroClass->terrCosts[from.tertype]; - ret = std::max(ret - 25*unsigned(getSecSkillLevel(0)), 100u); //reduce 25% of terrain penalty for each pathfinding level + ret = std::max(ret - 25*unsigned(getSecSkillLevel(CGHeroInstance::PATHFINDING)), 100u); //reduce 25% of terrain penalty for each pathfinding level } return ret; } @@ -660,7 +660,7 @@ int CGHeroInstance::getPrimSkillLevel(int id) const return ret; } -ui8 CGHeroInstance::getSecSkillLevel(const int & ID) const +ui8 CGHeroInstance::getSecSkillLevel(SecondarySkill skill) const { for(size_t i=0; i < secSkills.size(); ++i) if(secSkills[i].first==ID) @@ -668,7 +668,7 @@ ui8 CGHeroInstance::getSecSkillLevel(const int & ID) const return 0; } -void CGHeroInstance::setSecSkillLevel(int which, int val, bool abs) +void CGHeroInstance::setSecSkillLevel(SecondarySkill which, int val, bool abs) { if(getSecSkillLevel(which) == 0) { @@ -1277,7 +1277,9 @@ ui8 CGHeroInstance::getSpellSchoolLevel(const CSpell * spell, int *outSelectedSc #define TRY_SCHOOL(schoolName, schoolMechanicsId, schoolOutId) \ if(spell-> schoolName) \ { \ - int thisSchool = std::max(getSecSkillLevel(14 + (schoolMechanicsId)), valOfBonuses(Bonus::MAGIC_SCHOOL_SKILL, 1 << (schoolMechanicsId))); \ + int thisSchool = std::max(getSecSkillLevel( \ + static_cast(14 + (schoolMechanicsId))), \ + valOfBonuses(Bonus::MAGIC_SCHOOL_SKILL, 1 << (schoolMechanicsId))); \ if(thisSchool > skill) \ { \ skill = thisSchool; \ @@ -1328,7 +1330,7 @@ bool CGHeroInstance::canCastThisSpell(const CSpell * spell) const */ CStackBasicDescriptor CGHeroInstance::calculateNecromancy (const BattleResult &battleResult) const { - const ui8 necromancyLevel = getSecSkillLevel(12); + const ui8 necromancyLevel = getSecSkillLevel(CGHeroInstance::NECROMANCY); // Hero knows necromancy. if (necromancyLevel > 0) @@ -1405,7 +1407,7 @@ int3 CGHeroInstance::getSightCenter() const int CGHeroInstance::getSightRadious() const { - return 5 + getSecSkillLevel(3) + valOfBonuses(Bonus::SIGHT_RADIOUS); //default + scouting + return 5 + getSecSkillLevel(CGHeroInstance::SCOUTING) + valOfBonuses(Bonus::SIGHT_RADIOUS); //default + scouting } si32 CGHeroInstance::manaRegain() const @@ -2515,7 +2517,7 @@ void CGVisitableOPH::onNAHeroVisit(int heroID, bool alreadyVisited) const case 100: //give exp { const CGHeroInstance *h = cb->getHero(heroID); - val = val*(100+h->getSecSkillLevel(21)*5)/100.0f; + val = val*(100+h->getSecSkillLevel(CGHeroInstance::LEARNING)*5)/100.0f; InfoWindow iw; iw.soundID = sound; iw.components.push_back(Component(id,subid,val,0)); @@ -2582,7 +2584,7 @@ void CGVisitableOPH::onNAHeroVisit(int heroID, bool alreadyVisited) const case 41://library of enlightenment { const CGHeroInstance *h = cb->getHero(heroID); - if(h->level < 10 - 2*h->getSecSkillLevel(4)) //not enough level + if(h->level < 10 - 2*h->getSecSkillLevel(CGHeroInstance::DIPLOMACY)) //not enough level { InfoWindow iw; iw.soundID = sound; @@ -2810,7 +2812,7 @@ void CTownBonus::onHeroVisit (const CGHeroInstance * h) const break; case 5://academy of battle scholars what = 4; - val = 1000*(100+h->getSecSkillLevel(21)*5)/100.0f; + val = 1000*(100+h->getSecSkillLevel(CGHeroInstance::LEARNING)*5)/100.0f; mid = 583; iw.components.push_back (Component(Component::EXPERIENCE, 0, val, 0)); break; @@ -3033,12 +3035,12 @@ int CGCreature::takenAction(const CGHeroInstance *h, bool allowJoin) const sympathy++; - int charisma = factor + h->getSecSkillLevel(4) + sympathy; + int charisma = factor + h->getSecSkillLevel(CGHeroInstance::DIPLOMACY) + sympathy; if(charisma >= character) //creatures might join... { - if(h->getSecSkillLevel(4) + sympathy + 1 >= character) + if(h->getSecSkillLevel(CGHeroInstance::DIPLOMACY) + sympathy + 1 >= character) return 0; //join for free - else if(h->getSecSkillLevel(4) * 2 + sympathy + 1 >= character) + else if(h->getSecSkillLevel(CGHeroInstance::DIPLOMACY) * 2 + sympathy + 1 >= character) return VLC->creh->creatures[subID]->cost[6] * getStackCount(0); //join for gold } } @@ -3864,7 +3866,7 @@ void CGPickable::onHeroVisit( const CGHeroInstance * h ) const sd.player = h->tempOwner; sd.text << std::pair(11,146); sd.components.push_back(Component(2,6,val1,0)); - int expVal = val2*(100+h->getSecSkillLevel(21)*5)/100.0f; + int expVal = val2*(100+h->getSecSkillLevel(CGHeroInstance::LEARNING)*5)/100.0f; sd.components.push_back(Component(5,0,expVal, 0)); sd.soundID = soundBase::chest; boost::function fun = boost::bind(&CGPickable::chosen,this,_1,h->id); @@ -3885,7 +3887,7 @@ void CGPickable::chosen( int which, int heroID ) const cb->giveResource(cb->getOwner(heroID),6,val1); break; case 2: //player pick exp - cb->changePrimSkill(heroID, 4, val2*(100+h->getSecSkillLevel(21)*5)/100.0f); + cb->changePrimSkill(heroID, 4, val2*(100+h->getSecSkillLevel(CGHeroInstance::LEARNING)*5)/100.0f); break; default: throw std::string("Unhandled treasure choice"); @@ -4322,7 +4324,7 @@ void CGSeerHut::onHeroVisit( const CGHeroInstance * h ) const switch (rewardType) { - case 1: bd.components.push_back (Component (Component::EXPERIENCE, 0, rVal*(100+h->getSecSkillLevel(21)*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)); break; @@ -4421,7 +4423,7 @@ void CGSeerHut::completeQuest (const CGHeroInstance * h) const //reward { case 1: //experience { - int expVal = rVal*(100+h->getSecSkillLevel(21)*5)/100.0f; + int expVal = rVal*(100+h->getSecSkillLevel(CGHeroInstance::LEARNING)*5)/100.0f; cb->changePrimSkill(h->id, 4, expVal, false); break; } @@ -4502,7 +4504,7 @@ void CGWitchHut::onHeroVisit( const CGHeroInstance * h ) const if(!hasVisited(h->tempOwner)) cb->setObjProperty(id,10,h->tempOwner); - if(h->getSecSkillLevel(ability)) //you alredy know this skill + if(h->getSecSkillLevel(static_cast(ability))) //you alredy know this skill { iw.text << std::pair(11,172); iw.text.addReplacement(MetaString::SEC_SKILL_NAME, ability); @@ -4531,7 +4533,7 @@ const std::string & CGWitchHut::getHoverText() const hoverName += "\n" + VLC->generaltexth->allTexts[356]; // + (learn %s) boost::algorithm::replace_first(hoverName,"%s",VLC->generaltexth->skillName[ability]); const CGHeroInstance *h = cb->getSelectedHero(cb->getCurrentPlayer()); - if(h && h->getSecSkillLevel(ability)) //hero knows that ability + if(h && h->getSecSkillLevel(static_cast(ability))) //hero knows that ability hoverName += "\n\n" + VLC->generaltexth->allTexts[357]; // (Already learned) } return hoverName; @@ -4874,7 +4876,7 @@ void CGPandoraBox::giveContents( const CGHeroInstance *h, bool afterBattle ) con if(gainedExp || changesPrimSkill || abilities.size()) { - expType expVal = gainedExp*(100+h->getSecSkillLevel(21)*5)/100.0f; + expType expVal = gainedExp*(100+h->getSecSkillLevel(CGHeroInstance::LEARNING)*5)/100.0f; getText(iw,afterBattle,175,h); if(expVal) @@ -4899,7 +4901,7 @@ void CGPandoraBox::giveContents( const CGHeroInstance *h, bool afterBattle ) con //give sec skills for(int i=0; igetSecSkillLevel(abilities[i]); + int curLev = h->getSecSkillLevel(static_cast(abilities[i])); if( (curLev && curLev < abilityLevels[i]) || (h->secSkills.size() < SKILL_PER_HERO) ) @@ -4917,7 +4919,7 @@ void CGPandoraBox::giveContents( const CGHeroInstance *h, bool afterBattle ) con std::vector > * sp = &VLC->spellh->spells; for(std::vector::const_iterator i=spells.begin(); i != spells.end(); i++) { - if ((*sp)[*i]->level <= h->getSecSkillLevel(7) + 2) //enough wisdom + if ((*sp)[*i]->level <= h->getSecSkillLevel(CGHeroInstance::WISDOM) + 2) //enough wisdom { iw.components.push_back(Component(Component::SPELL,*i,0,0)); spellsToGive.insert(*i); @@ -5156,7 +5158,7 @@ void CGShrine::onHeroVisit( const CGHeroInstance * h ) const { iw.text.addTxt(MetaString::ADVOB_TXT,131); } - else if(ID == 90 && !h->getSecSkillLevel(7)) //it's third level spell and hero doesn't have wisdom + else if(ID == 90 && !h->getSecSkillLevel(CGHeroInstance::WISDOM)) //it's third level spell and hero doesn't have wisdom { iw.text.addTxt(MetaString::ADVOB_TXT,130); } @@ -5243,10 +5245,11 @@ void CGScholar::onHeroVisit( const CGHeroInstance * h ) const int type = bonusType; int bid = bonusID; //check if the bonus if applicable, if not - give primary skill (always possible) - int ssl = h->getSecSkillLevel(bid); //current sec skill level, used if bonusType == 1 + int ssl = h->getSecSkillLevel(static_cast(bid)); //current sec skill level, used if bonusType == 1 if((type == 1 && ((ssl == 3) || (!ssl && h->secSkills.size() == SKILL_PER_HERO))) ////hero already has expert level in the skill or (don't know skill and doesn't have free slot) - || (type == 2 && (!h->getArt(17) || vstd::contains(h->spells, (ui32) bid) || (VLC->spellh->spells[bid]->level > h->getSecSkillLevel(7) + 2) + || (type == 2 && (!h->getArt(17) || vstd::contains(h->spells, (ui32) bid) + || (VLC->spellh->spells[bid]->level > h->getSecSkillLevel(CGHeroInstance::WISDOM) + 2) ))) //hero doesn't have a spellbook or already knows the spell or doesn't have Wisdom { type = 0; @@ -5976,7 +5979,7 @@ void CGPyramid::endBattle (const CGHeroInstance *h, const BattleResult *result) iw.text.addTxt (MetaString::SPELL_NAME, spell); if (!h->getArt(17)) iw.text.addTxt (MetaString::ADVOB_TXT, 109); //no spellbook - else if (h->getSecSkillLevel(7) < 3) + else if (h->getSecSkillLevel(CGHeroInstance::WISDOM) < 3) iw.text.addTxt (MetaString::ADVOB_TXT, 108); //no expert Wisdom else { diff --git a/lib/CObjectHandler.h b/lib/CObjectHandler.h index 426df8a92..671630445 100644 --- a/lib/CObjectHandler.h +++ b/lib/CObjectHandler.h @@ -246,6 +246,13 @@ public: class DLL_EXPORT CGHeroInstance : public CArmedInstance, public IBoatGenerator { public: + enum SecondarySkill + { + PATHFINDING = 0, ARCHERY, LOGISTICS, SCOUTING, DIPLOMACY, NAVIGATION, LEADERSHIP, WISDOM, MYSTICISM, + LUCK, BALLISTICS, EAGLE_EYE, NECROMANCY, ESTATES, FIRE_MAGIC, AIR_MAGIC, WATER_MAGIC, EARTH_MAGIC, + SCHOLAR, TACTICS, ARTILLERY, LEARNING, OFFENCE, ARMORER, INTELLIGENCE, SORCERY, RESISTANCE, + FIRST_AID + }; ////////////////////////////////////////////////////////////////////////// ui8 moveDir; //format: 123 @@ -338,8 +345,8 @@ public: int getCurrentMorale(int stack=-1, bool town=false) const; //if stack - position of creature, if -1 then morale for hero is calculated; town - if bonuses from town (tavern) should be considered TModDescr getCurrentMoraleModifiers(int stack=-1, bool town=false) const; //args as above int getPrimSkillLevel(int id) const; //0-attack, 1-defence, 2-spell power, 3-knowledge - ui8 getSecSkillLevel(const int & ID) const; //0 - no skill - void setSecSkillLevel(int which, int val, bool abs);// abs == 0 - changes by value; 1 - sets to value + ui8 getSecSkillLevel(SecondarySkill skill) const; //0 - no skill + void setSecSkillLevel(SecondarySkill which, int val, bool abs);// abs == 0 - changes by value; 1 - sets to value int maxMovePoints(bool onLand) const; diff --git a/lib/NetPacksLib.cpp b/lib/NetPacksLib.cpp index fb2cff9c2..6fae92571 100644 --- a/lib/NetPacksLib.cpp +++ b/lib/NetPacksLib.cpp @@ -77,7 +77,7 @@ DLL_EXPORT void SetPrimSkill::applyGs( CGameState *gs ) DLL_EXPORT void SetSecSkill::applyGs( CGameState *gs ) { CGHeroInstance *hero = gs->getHero(id); - hero->setSecSkillLevel(which, val, abs); + hero->setSecSkillLevel(static_cast(which), val, abs); } DLL_EXPORT void HeroVisitCastle::applyGs( CGameState *gs ) diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index 16cfdbbf1..e83650154 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -332,9 +332,9 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer //end battle, remove all info, free memory giveExp(*battleResult.data); if (hero1) - battleResult.data->exp[0] *= (100+hero1->getSecSkillLevel(21)*5)/100.0f;//sholar skill + battleResult.data->exp[0] *= (100+hero1->getSecSkillLevel(CGHeroInstance::LEARNING)*5)/100.0f;//sholar skill if (hero2) - battleResult.data->exp[1] *= (100+hero2->getSecSkillLevel(21)*5)/100.0f; + battleResult.data->exp[1] *= (100+hero2->getSecSkillLevel(CGHeroInstance::LEARNING)*5)/100.0f; ui8 sides[2]; sides[0] = gs->curB->side1; @@ -1201,7 +1201,7 @@ void CGameHandler::giveSpells( const CGTownInstance *t, const CGHeroInstance *h ChangeSpells cs; cs.hid = h->id; cs.learn = true; - for(int i=0; imageGuildLevel(),h->getSecSkillLevel(7)+2);i++) + for(int i=0; imageGuildLevel(),h->getSecSkillLevel(CGHeroInstance::WISDOM)+2);i++) { if (t->subID == 8 && vstd::contains(t->builtBuildings, 26)) //Aurora Borealis { @@ -1842,18 +1842,18 @@ void CGameHandler::useScholarSkill(si32 fromHero, si32 toHero) const CGHeroInstance * h1 = getHero(fromHero); const CGHeroInstance * h2 = getHero(toHero); - if ( h1->getSecSkillLevel(18) < h2->getSecSkillLevel(18) ) + if ( h1->getSecSkillLevel(CGHeroInstance::SCHOLAR) < h2->getSecSkillLevel(CGHeroInstance::SCHOLAR) ) { std::swap (h1,h2);//1st hero need to have higher scholar level for correct message std::swap(fromHero, toHero); } - int ScholarLevel = h1->getSecSkillLevel(18);//heroes can trade up to this level + int ScholarLevel = h1->getSecSkillLevel(CGHeroInstance::SCHOLAR);//heroes can trade up to this level if (!ScholarLevel || !vstd::contains(h1->artifWorn,17) || !vstd::contains(h2->artifWorn,17) ) return;//no scholar skill or no spellbook - int h1Lvl = std::min(ScholarLevel+1, h1->getSecSkillLevel(7)+2), - h2Lvl = std::min(ScholarLevel+1, h2->getSecSkillLevel(7)+2);//heroes can receive this levels + int h1Lvl = std::min(ScholarLevel+1, h1->getSecSkillLevel(CGHeroInstance::WISDOM)+2), + h2Lvl = std::min(ScholarLevel+1, h2->getSecSkillLevel(CGHeroInstance::WISDOM)+2);//heroes can receive this levels ChangeSpells cs1; cs1.learn = true; @@ -2855,7 +2855,7 @@ bool CGameHandler::buySecSkill( const IMarket *m, const CGHeroInstance *h, int s if (!h) COMPLAIN_RET("You need hero to buy a skill!"); - if (h->getSecSkillLevel(skill)) + if (h->getSecSkillLevel(static_cast(skill))) COMPLAIN_RET("Hero already know this skill"); if (h->secSkills.size() >= SKILL_PER_HERO)//can't learn more skills @@ -3258,7 +3258,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba ) { sendAndApply(&StartAction(ba)); const CGHeroInstance * attackingHero = gs->curB->heroes[ba.side]; - CHeroHandler::SBallisticsLevelInfo sbi = VLC->heroh->ballistics[attackingHero->getSecSkillLevel(10)]; //ballistics + CHeroHandler::SBallisticsLevelInfo sbi = VLC->heroh->ballistics[attackingHero->getSecSkillLevel(CGHeroInstance::BALLISTICS)]; int attackedPart = gs->curB->hexToWallPart(ba.destinationTile); if(attackedPart == -1) @@ -4637,7 +4637,7 @@ bool CGameHandler::sacrificeCreatures(const IMarket *market, const CGHeroInstanc int dump, exp; market->getOffer(crid, 0, dump, exp, CREATURE_EXP); exp *= count; - changePrimSkill(hero->id, 4, exp*(100+hero->getSecSkillLevel(21)*5)/100.0f); + changePrimSkill(hero->id, 4, exp*(100+hero->getSecSkillLevel(CGHeroInstance::LEARNING)*5)/100.0f); return true; } @@ -4804,8 +4804,8 @@ void CGameHandler::runBattle() //tactic round { - if( (gs->curB->heroes[0] && gs->curB->heroes[0]->getSecSkillLevel(19)>0) || - ( gs->curB->heroes[1] && gs->curB->heroes[1]->getSecSkillLevel(19)>0) )//someone has tactics + if( (gs->curB->heroes[0] && gs->curB->heroes[0]->getSecSkillLevel(CGHeroInstance::TACTICS)>0) || + ( gs->curB->heroes[1] && gs->curB->heroes[1]->getSecSkillLevel(CGHeroInstance::TACTICS)>0) )//someone has tactics { //TODO: tactic round (round -1) NEW_ROUND; @@ -4891,8 +4891,8 @@ void CGameHandler::runBattle() const CGHeroInstance * curOwner = gs->battleGetOwner(next->ID); - if( (next->position < 0 && (!curOwner || curOwner->getSecSkillLevel(10) == 0)) //arrow turret, hero has no ballistics - || (next->getCreature()->idNumber == 146 && (!curOwner || curOwner->getSecSkillLevel(20) == 0))) //ballista, hero has no artillery + if( (next->position < 0 && (!curOwner || curOwner->getSecSkillLevel(CGHeroInstance::BALLISTICS) == 0)) //arrow turret, hero has no ballistics + || (next->getCreature()->idNumber == 146 && (!curOwner || curOwner->getSecSkillLevel(CGHeroInstance::ARTILLERY) == 0))) //ballista, hero has no artillery { BattleAction attack; attack.actionType = BattleAction::SHOOT; @@ -4914,7 +4914,7 @@ void CGameHandler::runBattle() continue; } - if(next->getCreature()->idNumber == 145 && (!curOwner || curOwner->getSecSkillLevel(10) == 0)) //catapult, hero has no ballistics + if(next->getCreature()->idNumber == 145 && (!curOwner || curOwner->getSecSkillLevel(CGHeroInstance::BALLISTICS) == 0)) //catapult, hero has no ballistics { BattleAction attack; static const int wallHexes[] = {50, 183, 182, 130, 62, 29, 12, 95}; @@ -4929,7 +4929,7 @@ void CGameHandler::runBattle() continue; } - if(next->getCreature()->idNumber == 147 && (!curOwner || curOwner->getSecSkillLevel(27) == 0)) //first aid tent, hero has no first aid + if(next->getCreature()->idNumber == 147 && (!curOwner || curOwner->getSecSkillLevel(CGHeroInstance::FIRST_AID) == 0)) //first aid tent, hero has no first aid { BattleAction heal;