1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-26 22:57:00 +02:00

* enum for secondary skills

* THex for battle positions
* towards removal of battleGetStackByID

TODO:
investigate the necessity of putting implementation of BattleAction CGlobalAI::activeStack( const CStack * stack ) in CGeniusAI.cpp
This commit is contained in:
mateuszb 2010-12-23 20:18:10 +00:00
parent 2fe8b07f4f
commit 4929cf9782
22 changed files with 191 additions and 157 deletions

View File

@ -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("); std::string message("\t\t\tCGeniusAI::battleStackMoved ID(");
message += boost::lexical_cast<std::string>(ID); message += boost::lexical_cast<std::string>(ID);
@ -1338,13 +1338,13 @@ void CGeniusAI::battleSpellCast(const BattleSpellCast *sc)
/** /**
* *
*/ */
void CGeniusAI::battleStackMoved(int ID, // void CGeniusAI::battleStackMoved(int ID,
int dest, // THex dest,
bool startMoving, // bool startMoving,
bool endMoving) // bool endMoving)
{ // {
DbgBox("\t\t\tCGeniusAI::battleStackMoved"); // DbgBox("\t\t\tCGeniusAI::battleStackMoved");
} // }
/** /**
@ -1372,15 +1372,25 @@ void CGeniusAI::battleStackIsAttacked(int ID,
/** /**
* called when it's turn of that stack * 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("); std::string message("\t\t\tCGeniusAI::activeStack stackID(");
message += boost::lexical_cast<std::string>(stackID); message += boost::lexical_cast<std::string>(stack->ID);
message += ")"; message += ")";
DbgBox(message.c_str()); DbgBox(message.c_str());
BattleAction bact = m_battleLogic->MakeDecision(stackID); BattleAction bact = m_battleLogic->MakeDecision(stack->ID);
assert(m_cb->battleGetStackByID(bact.stackNumber)); assert(m_cb->battleGetStackByID(bact.stackNumber));
return bact; 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;
}

View File

@ -205,15 +205,15 @@ public:
virtual void battleStacksAttacked(const std::set<BattleStackAttacked> & bsa); //called when stack receives damage (after battleAttack()) virtual void battleStacksAttacked(const std::set<BattleStackAttacked> & bsa); //called when stack receives damage (after battleAttack())
virtual void battleEnd(const BattleResult *br); 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 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 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 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<CObstacle*> obstacles); //called when battlefield is prepared, prior the battle beginning //virtual void battlefieldPrepared(int battlefieldType, std::vector<CObstacle*> 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 battleStackAttacking(int ID, int dest);
virtual void battleStackIsAttacked(int ID, int dmg, int killed, int IDby, bool byShooting); 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(); void battleResultsApplied();
friend class Priorities; friend class Priorities;
}; };

View File

@ -1,5 +1,6 @@
#include "stdafx.h" #include "stdafx.h"
#include "StupidAI.h" #include "StupidAI.h"
#include "../../lib/CGameState.h"
CStupidAI::CStupidAI(void) 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; BattleAction ba;
ba.DEFEND; ba.actionType = BattleAction::DEFEND;
ba.stackNumber = stackID; ba.stackNumber = stack->ID;
return ba; return ba;
} }

View File

@ -9,6 +9,6 @@ public:
void init(IBattleCallback * CB) OVERRIDE; void init(IBattleCallback * CB) OVERRIDE;
void actionFinished(const BattleAction *action) OVERRIDE;//occurs AFTER every action taken by any stack or by the hero 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 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
}; };

View File

@ -1,5 +1,6 @@
#include "stdafx.h" #include "stdafx.h"
#include "CGameInterface.h" #include "CGameInterface.h"
#include "lib/CGameState.h"
#ifdef _WIN32 #ifdef _WIN32
#define WIN32_LEAN_AND_MEAN //excludes rarely used stuff from windows headers - delete this line if something is missing #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<CBattleGameInterface>(cb, dllname, "GetNewBattleAI"); return createAnyAI<CBattleGameInterface>(cb, dllname, "GetNewBattleAI");
} }
BattleAction CGlobalAI::activeStack( const CStack * stack )
{
BattleAction ba; ba.actionType = BattleAction::DEFEND;
ba.stackNumber = stack->ID;
return ba;
}

View File

@ -45,6 +45,7 @@ struct CatapultAttack;
struct BattleStacksRemoved; struct BattleStacksRemoved;
struct StackLocation; struct StackLocation;
class CStackInstance; class CStackInstance;
class CStack;
class CCreature; class CCreature;
class CLoadFile; class CLoadFile;
class CSaveFile; class CSaveFile;
@ -66,20 +67,19 @@ public:
//battle call-ins //battle call-ins
virtual void actionFinished(const BattleAction *action){};//occurs AFTER every action taken by any stack or by the hero 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 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 battleAttack(const BattleAttack *ba){}; //called when stack is performing attack
virtual void battleStacksAttacked(const std::vector<BattleStackAttacked> & bsa){}; //called when stack receives damage (after battleAttack()) virtual void battleStacksAttacked(const std::vector<BattleStackAttacked> & bsa){}; //called when stack receives damage (after battleAttack())
virtual void battleEnd(const BattleResult *br){}; virtual void battleEnd(const BattleResult *br){};
virtual void battleResultsApplied(){}; //called when all effects of last battle are applied 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 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 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 battleSpellCast(const BattleSpellCast *sc){};
virtual void battleStacksEffectsSet(const SetStackEffect & sse){};//called when a specific effect is set to stacks 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 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<CObstacle*> obstacles){}; //called when battlefield is prepared, prior the battle beginning
virtual void battleStacksHealedRes(const std::vector<std::pair<ui32, ui32> > & healedStacks, bool lifeDrain, si32 lifeDrainFrom){}; //called when stacks are healed / resurrected first element of pair - stack id, second - healed hp virtual void battleStacksHealedRes(const std::vector<std::pair<ui32, ui32> > & 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<si32> & removedObstacles){}; //called when a certain set of obstacles is removed from batlefield; IDs of them are given virtual void battleObstaclesRemoved(const std::set<si32> & 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 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 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: public:
//CGlobalAI(); //CGlobalAI();
virtual void yourTurn(){}; virtual void yourTurn() OVERRIDE{};
virtual void heroKilled(const CGHeroInstance*){}; virtual void heroKilled(const CGHeroInstance*){};
virtual void heroCreated(const CGHeroInstance*){}; virtual void heroCreated(const CGHeroInstance*) OVERRIDE{};
virtual void battleStackMoved(int ID, int dest, int distance){}; virtual void battleStackMoved(int ID, THex dest, int distance, bool end) OVERRIDE{};
virtual void battleStackAttacking(int ID, int dest){}; virtual void battleStackAttacking(int ID, int dest) {};
virtual void battleStackIsAttacked(int ID, int dmg, int killed, int IDby, bool byShooting){}; virtual void battleStacksAttacked(const std::vector<BattleStackAttacked> & bsa) OVERRIDE{};
virtual BattleAction activeStack(int stackID) {BattleAction ba; ba.actionType = 3; ba.stackNumber = stackID; return ba;}; virtual BattleAction activeStack(const CStack * stack) OVERRIDE;
}; };
#endif // __CGAMEINTERFACE_H__ #endif // __CGAMEINTERFACE_H__

View File

@ -304,7 +304,7 @@ void CSpellEffectAnim::endAnim()
delete this; 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) :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 fromMod = hexFrom % BFIELD_WIDTH;
int fromDiv = 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 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 if(hexTo < 0) //turret
return false; return false;
@ -442,7 +442,7 @@ void CReverseAnim::endAnim()
delete this; 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) : CBattleStackAnimation(_owner, stack), partOfAnim(1), secondPartSetup(false), hex(dest), priority(_priority)
{ {
} }
@ -723,7 +723,7 @@ void CBattleStackMoved::endAnim()
delete this; 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) : CBattleStackAnimation(_owner, _number), destHex(_destHex), endMoving(_endMoving), distance(_distance), stepX(0.0f), stepY(0.0f)
{ {
curStackPos = owner->curInt->cb->battleGetPos(stackID); curStackPos = owner->curInt->cb->battleGetPos(stackID);
@ -815,7 +815,7 @@ void CBattleMoveEnd::endAnim()
delete this; delete this;
} }
CBattleMoveEnd::CBattleMoveEnd(CBattleInterface * _owner, int stack, int destTile) CBattleMoveEnd::CBattleMoveEnd(CBattleInterface * _owner, int stack, THex destTile)
: CBattleStackAnimation(_owner, stack), destinationTile(destTile) : CBattleStackAnimation(_owner, stack), destinationTile(destTile)
{ {
} }
@ -847,7 +847,7 @@ bool CBattleAttack::checkInitialConditions()
return isEarliest(false); 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) : CBattleStackAnimation(_owner, _stackID), dest(_dest)
{ {
attackedStack = owner->curInt->cb->battleGetStackByID(_attackedID, false); attackedStack = owner->curInt->cb->battleGetStackByID(_attackedID, false);
@ -954,7 +954,7 @@ void CMeleeAttack::endAnim()
delete this; 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) : CBattleAttack(_owner, attacker, _dest, _attackedID)
{ {
} }
@ -1081,7 +1081,7 @@ void CShootingAnim::endAnim()
delete this; 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) : CBattleAttack(_owner, attacker, _dest, _attackedID), catapultDamage(_catapultDmg), catapult(_catapult)
{ {
if(catapult) //catapult attack if(catapult) //catapult attack
@ -1145,7 +1145,7 @@ CBattleInterface::CBattleInterface(const CCreatureSet * army1, const CCreatureSe
std::vector<const CStack*> stacks = curInt->cb->battleGetStacks(); std::vector<const CStack*> stacks = curInt->cb->battleGetStacks();
BOOST_FOREACH(const CStack *s, stacks) BOOST_FOREACH(const CStack *s, stacks)
{ {
newStack(s->ID); newStack(s);
} }
//preparing menu background and terrain //preparing menu background and terrain
@ -2225,37 +2225,36 @@ void CBattleInterface::bConsoleDownf()
console->scrollDown(); 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(stack->position < 0) //turret
if(newStack->position < 0) //turret
{ {
const CCreature & turretCreature = *CGI->creh->creatures[ CGI->creh->factionToTurretCreature[siegeH->town->town->typeID] ]; 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 else
{ {
creAnims[stackID] = new CCreatureAnimation(newStack->getCreature()->animDefName); creAnims[stack->ID] = new CCreatureAnimation(stack->getCreature()->animDefName);
} }
creAnims[stackID]->setType(2); creAnims[stack->ID]->setType(2);
creAnims[stackID]->pos = Rect(coords.x, coords.y, creAnims[newStack->ID]->fullWidth, creAnims[newStack->ID]->fullHeight); creAnims[stack->ID]->pos = Rect(coords.x, coords.y, creAnims[stack->ID]->fullWidth, creAnims[stack->ID]->fullHeight);
creDir[stackID] = newStack->attackerOwned; creDir[stack->ID] = stack->attackerOwned;
} }
void CBattleInterface::stackRemoved(int stackID) void CBattleInterface::stackRemoved(const CStack * stack)
{ {
int stackID = stack->ID;
delete creAnims[stackID]; delete creAnims[stackID];
creAnims.erase(stackID); creAnims.erase(stackID);
creDir.erase(stackID); creDir.erase(stackID);
} }
void CBattleInterface::stackActivated(int number) void CBattleInterface::stackActivated(const CStack * stack)
{ {
//givenCommand = NULL; //givenCommand = NULL;
stackToActivate = number; stackToActivate = stack->ID;
if(pendingAnims.size() == 0) if(pendingAnims.size() == 0)
activateStack(); activateStack();
} }
@ -2273,9 +2272,16 @@ void CBattleInterface::stacksAreAttacked(std::vector<SStackAttackedInfo> 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 ) 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) 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) for(std::set< std::pair< std::pair< ui8, si16 >, ui8> >::const_iterator it = ca.attackedParts.begin(); it != ca.attackedParts.end(); ++it)

View File

@ -91,7 +91,7 @@ class CSpellEffectAnim : public CBattleAnimation
{ {
private: private:
ui32 effect; ui32 effect;
int destTile; THex destTile;
std::string customAnim; std::string customAnim;
int x, y, dx, dy; int x, y, dx, dy;
bool Vflip; bool Vflip;
@ -100,7 +100,7 @@ public:
void nextFrame(); void nextFrame();
void endAnim(); 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); 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 int stackID; //id of stack whose animation it is
CBattleStackAnimation(CBattleInterface * _owner, int stack); CBattleStackAnimation(CBattleInterface * _owner, int stack);
static bool isToReverseHlp(int hexFrom, int hexTo, bool curDir); //helper for isToReverse static bool isToReverseHlp(THex hexFrom, THex 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 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 class CReverseAnim : public CBattleStackAnimation
@ -119,14 +119,14 @@ class CReverseAnim : public CBattleStackAnimation
private: private:
int partOfAnim; //1 - first, 2 - second int partOfAnim; //1 - first, 2 - second
bool secondPartSetup; bool secondPartSetup;
int hex; THex hex;
public: public:
bool priority; //true - high, false - low bool priority; //true - high, false - low
bool init(); bool init();
void nextFrame(); void nextFrame();
void endAnim(); void endAnim();
CReverseAnim(CBattleInterface * _owner, int stack, int dest, bool _priority); CReverseAnim(CBattleInterface * _owner, int stack, THex dest, bool _priority);
}; };
class CDefenceAnim : public CBattleStackAnimation class CDefenceAnim : public CBattleStackAnimation
@ -149,7 +149,7 @@ public:
class CBattleStackMoved : public CBattleStackAnimation class CBattleStackMoved : public CBattleStackAnimation
{ {
private: private:
int destHex; //destination THex destHex; //destination
bool endMoving; //if this is end of move bool endMoving; //if this is end of move
int distance; int distance;
float stepX, stepY; //how far stack is moved in one frame float stepX, stepY; //how far stack is moved in one frame
@ -161,7 +161,7 @@ public:
void nextFrame(); void nextFrame();
void endAnim(); 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 class CBattleMoveStart : public CBattleStackAnimation
@ -177,20 +177,20 @@ public:
class CBattleMoveEnd : public CBattleStackAnimation class CBattleMoveEnd : public CBattleStackAnimation
{ {
private: private:
int destinationTile; THex destinationTile;
public: public:
bool init(); bool init();
void nextFrame(); void nextFrame();
void endAnim(); void endAnim();
CBattleMoveEnd(CBattleInterface * _owner, int stack, int destTile); CBattleMoveEnd(CBattleInterface * _owner, int stack, THex destTile);
}; };
class CBattleAttack : public CBattleStackAnimation class CBattleAttack : public CBattleStackAnimation
{ {
protected: protected:
int IDby; //attacked stack int IDby; //attacked stack
int dest; //atacked hex THex dest; //atacked hex
int posShiftDueToDist; int posShiftDueToDist;
bool shooting; bool shooting;
int group; //if shooting is true, print this animation group int group; //if shooting is true, print this animation group
@ -203,7 +203,7 @@ public:
bool checkInitialConditions(); bool checkInitialConditions();
CBattleAttack(CBattleInterface * _owner, int _stackID, int _dest, int _attackedID); CBattleAttack(CBattleInterface * _owner, int _stackID, THex _dest, int _attackedID);
}; };
class CMeleeAttack : public CBattleAttack class CMeleeAttack : public CBattleAttack
@ -213,7 +213,7 @@ public:
void nextFrame(); void nextFrame();
void endAnim(); void endAnim();
CMeleeAttack(CBattleInterface * _owner, int attacker, int _dest, int _attackedID); CMeleeAttack(CBattleInterface * _owner, int attacker, THex _dest, int _attackedID);
}; };
class CShootingAnim : public CBattleAttack class CShootingAnim : public CBattleAttack
@ -226,7 +226,7 @@ public:
void nextFrame(); void nextFrame();
void endAnim(); 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 //end of battle animation handlers
@ -491,17 +491,15 @@ public:
//call-ins //call-ins
void startAction(const BattleAction* action); void startAction(const BattleAction* action);
void newStack(int stackID); //new stack appeared on battlefield void newStack(const CStack * stack); //new stack appeared on battlefield
void stackRemoved(int stackID); //stack disappeared from batlefiled void stackRemoved(const CStack * stack); //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(const CStack * stack); //active stack has been changed
void stackActivated(int number); //active stack has been changed
void stackMoved(int number, int destHex, bool endMoving, int distance); //stack with id number moved to destHex void stackMoved(int number, int destHex, bool endMoving, int distance); //stack with id number moved to destHex
void stacksAreAttacked(std::vector<SStackAttackedInfo> attackedInfos); //called when a certain amount of stacks has been attacked void stacksAreAttacked(std::vector<SStackAttackedInfo> 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 newRoundFirst( int round );
void newRound(int number); //caled when round is ended; number is the number of 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 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 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 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 const BattleResult * bresult; //result of a battle; if non-zero then display when all animations end

View File

@ -201,7 +201,7 @@ void CHeroWindow::setHero(const CGHeroInstance *hero)
for(size_t g=0; g<std::min(secSkillAreas.size(),hero->secSkills.size()); ++g) for(size_t g=0; g<std::min(secSkillAreas.size(),hero->secSkills.size()); ++g)
{ {
int skill = hero->secSkills[g].first, int skill = hero->secSkills[g].first,
level = hero->getSecSkillLevel(hero->secSkills[g].first); level = hero->getSecSkillLevel(static_cast<CGHeroInstance::SecondarySkill>(hero->secSkills[g].first));
secSkillAreas[g]->type = skill; secSkillAreas[g]->type = skill;
secSkillAreas[g]->bonusValue = level; secSkillAreas[g]->bonusValue = level;
secSkillAreas[g]->text = CGI->generaltexth->skillInfoTexts[skill][level-1]; secSkillAreas[g]->text = CGI->generaltexth->skillInfoTexts[skill][level-1];
@ -232,7 +232,7 @@ void CHeroWindow::setHero(const CGHeroInstance *hero)
} }
dismissButton->block(!!hero->visitedTown || noDismiss); dismissButton->block(!!hero->visitedTown || noDismiss);
if(hero->getSecSkillLevel(19) == 0) if(hero->getSecSkillLevel(CGHeroInstance::TACTICS) == 0)
tacticsButton->block(true); tacticsButton->block(true);
else else
{ {

View File

@ -164,7 +164,7 @@ CKingdomInterface::CKingdomInterface()
incomesVal[7] = incomesVal[6]*1000;//gold mines -> total income incomesVal[7] = incomesVal[6]*1000;//gold mines -> total income
std::vector<const CGHeroInstance*> heroes = LOCPLINT->cb->getHeroesInfo(true); std::vector<const CGHeroInstance*> heroes = LOCPLINT->cb->getHeroesInfo(true);
for(size_t i=0; i<heroes.size();i++) for(size_t i=0; i<heroes.size();i++)
switch(heroes[i]->getSecSkillLevel(13))//some heroes may have estates switch(heroes[i]->getSecSkillLevel(CGHeroInstance::ESTATES))//some heroes may have estates
{ {
case 1: //basic case 1: //basic
incomesVal[7] += 125; incomesVal[7] += 125;

View File

@ -600,7 +600,7 @@ void CPlayerInterface::battleStacksHealedRes(const std::vector<std::pair<ui32, u
} }
} }
void CPlayerInterface::battleNewStackAppeared(int stackID) void CPlayerInterface::battleNewStackAppeared(const CStack * stack)
{ {
if(LOCPLINT != this) if(LOCPLINT != this)
{ //another local interface should do this { //another local interface should do this
@ -608,7 +608,7 @@ void CPlayerInterface::battleNewStackAppeared(int stackID)
} }
//changing necessary things in battle interface //changing necessary things in battle interface
battleInt->newStack(stackID); battleInt->newStack(stack);
} }
void CPlayerInterface::battleObstaclesRemoved(const std::set<si32> & removedObstacles) void CPlayerInterface::battleObstaclesRemoved(const std::set<si32> & removedObstacles)
@ -652,7 +652,7 @@ void CPlayerInterface::battleStacksRemoved(const BattleStacksRemoved & bsr)
for(std::set<ui32>::const_iterator it = bsr.stackIDs.begin(); it != bsr.stackIDs.end(); ++it) //for each removed stack for(std::set<ui32>::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); 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; CBattleInterface *b = battleInt;
{ {
boost::unique_lock<boost::recursive_mutex> un(*pim); boost::unique_lock<boost::recursive_mutex> un(*pim);
const CStack *stack = cb->battleGetStackByID(stackID);
if(vstd::contains(stack->state,MOVED)) //this stack has moved and makes second action -> high morale if(vstd::contains(stack->state,MOVED)) //this stack has moved and makes second action -> high morale
{ {
std::string hlp = CGI->generaltexth->allTexts[33]; 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); battleInt->console->addText(hlp);
} }
b->stackActivated(stackID); b->stackActivated(stack);
} }
//wait till BattleInterface sets its command //wait till BattleInterface sets its command
boost::unique_lock<boost::mutex> lock(b->givenCommand->mx); boost::unique_lock<boost::mutex> lock(b->givenCommand->mx);
@ -735,7 +734,7 @@ void CPlayerInterface::battleEnd(const BattleResult *br)
battleInt->battleFinished(*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) if(LOCPLINT != this)
{ //another local interface should do this { //another local interface should do this
@ -819,14 +818,18 @@ void CPlayerInterface::battleAttack(const BattleAttack *ba)
} }
//TODO: bad luck? //TODO: bad luck?
const CStack * attacker = cb->battleGetStackByID(ba->stackAttacking);
if(ba->shot()) if(ba->shot())
{ {
for(std::vector<BattleStackAttacked>::const_iterator i = ba->bsa.begin(); i != ba->bsa.end(); i++) for(std::vector<BattleStackAttacked>::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 else
{//WARNING: does not support multiple attacked creatures {//WARNING: does not support multiple attacked creatures
const CStack * attacker = cb->battleGetStackByID(ba->stackAttacking);
int shift = 0; int shift = 0;
if(ba->counter() && BattleInfo::mutualPosition(curAction->destinationTile, attacker->position) < 0) if(ba->counter() && BattleInfo::mutualPosition(curAction->destinationTile, attacker->position) < 0)
{ {
@ -838,7 +841,8 @@ void CPlayerInterface::battleAttack(const BattleAttack *ba)
else else
shift = -1; 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);
} }
} }

View File

@ -158,7 +158,7 @@ public:
const CGHeroInstance *getWHero(int pos); //returns NULL if position is not valid const CGHeroInstance *getWHero(int pos); //returns NULL if position is not valid
int getLastIndex(std::string namePrefix); 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 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 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 void stackChangedType(const StackLocation &location, const CCreature &newType) OVERRIDE; //used eg. when upgrading creatures
@ -208,19 +208,18 @@ public:
//for battles //for battles
void actionFinished(const BattleAction* action) OVERRIDE;//occurs AFTER action taken by active stack or by the hero 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 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 battleAttack(const BattleAttack *ba) OVERRIDE; //stack performs attack
void battleEnd(const BattleResult *br) OVERRIDE; //end of battle 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 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 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 battleSpellCast(const BattleSpellCast *sc) OVERRIDE;
void battleStacksEffectsSet(const SetStackEffect & sse) OVERRIDE; //called when a specific effect is set to stacks void battleStacksEffectsSet(const SetStackEffect & sse) OVERRIDE; //called when a specific effect is set to stacks
void battleStacksAttacked(const std::vector<BattleStackAttacked> & bsa) OVERRIDE; void battleStacksAttacked(const std::vector<BattleStackAttacked> & 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 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<std::pair<ui32, ui32> > & healedStacks, bool lifeDrain, si32 lifeDrainFrom) OVERRIDE; //called when stacks are healed / resurrected void battleStacksHealedRes(const std::vector<std::pair<ui32, ui32> > & 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<si32> & removedObstacles) OVERRIDE; //called when a certain set of obstacles is removed from batlefield; IDs of them are given void battleObstaclesRemoved(const std::set<si32> & 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 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 void battleStacksRemoved(const BattleStacksRemoved & bsr) OVERRIDE; //called when certain stack is completely removed from battlefield

View File

@ -116,7 +116,7 @@ void CClient::waitForMoveAndSend(int color)
{ {
try try
{ {
BattleAction ba = playerint[color]->activeStack(gs->curB->activeStack); BattleAction ba = playerint[color]->activeStack(gs->curB->getStack(gs->curB->activeStack, false));
*serv << &MakeAction(ba); *serv << &MakeAction(ba);
return; return;
}HANDLE_EXCEPTION }HANDLE_EXCEPTION

View File

@ -2304,7 +2304,9 @@ CLevelWindow::CLevelWindow(const CGHeroInstance *hero, int pskill, std::vector<u
cb = callback; cb = callback;
for(int i=0;i<skills.size();i++) for(int i=0;i<skills.size();i++)
{ {
comps.push_back(new CSelectableComponent(SComponent::secskill44,skills[i],hero->getSecSkillLevel(skills[i])+1,boost::bind(&CLevelWindow::selectionChanged,this,i))); comps.push_back(new CSelectableComponent(SComponent::secskill44, skills[i],
hero->getSecSkillLevel( static_cast<CGHeroInstance::SecondarySkill>(skills[i]) )+1,
boost::bind(&CLevelWindow::selectionChanged,this,i)));
comps.back()->assignedKeys.insert(SDLK_1 + i); comps.back()->assignedKeys.insert(SDLK_1 + i);
} }
SDL_Surface *hhlp = BitmapHandler::loadBitmap("LVLUPBKG.bmp"); SDL_Surface *hhlp = BitmapHandler::loadBitmap("LVLUPBKG.bmp");
@ -3734,7 +3736,7 @@ void CAltarWindow::calcTotalExp()
val += valOfArt * arts->artifactsOnAltar.count(*i); 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<std::string>(val)); expOnAltar->setTxt(boost::lexical_cast<std::string>(val));
} }
@ -5866,7 +5868,7 @@ void CUniversityWindow::CItem::hover(bool on)
int CUniversityWindow::CItem::state() int CUniversityWindow::CItem::state()
{ {
if (parent->hero->getSecSkillLevel(ID))//hero know this skill if (parent->hero->getSecSkillLevel(static_cast<CGHeroInstance::SecondarySkill>(ID)))//hero know this skill
return 1; return 1;
if (parent->hero->secSkills.size() >= SKILL_PER_HERO)//can't learn more skills if (parent->hero->secSkills.size() >= SKILL_PER_HERO)//can't learn more skills
return 0; return 0;

View File

@ -575,9 +575,9 @@ void BattleSpellCast::applyCl( CClient *cl )
if(id >= 66 && id <= 69) //elemental summoning if(id >= 66 && id <= 69) //elemental summoning
{ {
if(cl->playerint.find(GS(cl)->curB->side1) != cl->playerint.end()) 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()) 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]);
} }
} }

View File

@ -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 boost::int8_t si8; //signed int 8 bits (1 byte)
typedef si64 expType; typedef si64 expType;
typedef ui16 spelltype; typedef ui16 spelltype;
typedef ui16 THex; //for battle stacks' positions
#include "int3.h" #include "int3.h"
#include <map> #include <map>
#include <vector> #include <vector>

View File

@ -393,7 +393,7 @@ const CStack * BattleInfo::getStack(int stackID, bool onlyAlive) const
return const_cast<BattleInfo * const>(this)->getStack(stackID, onlyAlive); return const_cast<BattleInfo * const>(this)->getStack(stackID, onlyAlive);
} }
CStack * BattleInfo::getStackT(int tileID, bool onlyAlive) CStack * BattleInfo::getStackT(THex tileID, bool onlyAlive)
{ {
for(unsigned int g=0; g<stacks.size(); ++g) for(unsigned int g=0; g<stacks.size(); ++g)
{ {
@ -410,7 +410,7 @@ CStack * BattleInfo::getStackT(int tileID, bool onlyAlive)
return NULL; return NULL;
} }
const CStack * BattleInfo::getStackT(int tileID, bool onlyAlive) const const CStack * BattleInfo::getStackT(THex tileID, bool onlyAlive) const
{ {
return const_cast<BattleInfo * const>(this)->getStackT(tileID, onlyAlive); return const_cast<BattleInfo * const>(this)->getStackT(tileID, onlyAlive);
} }
@ -639,7 +639,7 @@ bool BattleInfo::isStackBlocked(int ID)
return false; 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 if(hex2 == hex1 - ( (hex1/17)%2 ? 18 : 17 )) //top left
return 0; return 0;
@ -1864,7 +1864,7 @@ void CGameState::init( StartInfo * si, ui32 checksum, int Seed )
} }
break; break;
case 6: //sec skills case 6: //sec skills
hero->setSecSkillLevel(curBonus.info2, curBonus.info3, true); hero->setSecSkillLevel(static_cast<CGHeroInstance::SecondarySkill>(curBonus.info2), curBonus.info3, true);
break; 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), int xDst = std::abs(hex1 % BFIELD_WIDTH - hex2 % BFIELD_WIDTH),
yDst = std::abs(hex1 / BFIELD_WIDTH - hex2 / BFIELD_WIDTH); yDst = std::abs(hex1 / BFIELD_WIDTH - hex2 / BFIELD_WIDTH);

View File

@ -229,8 +229,8 @@ struct DLL_EXPORT BattleInfo : public CBonusSystemNode
void getStackQueue(std::vector<const CStack *> &out, int howMany, int turn = 0, int lastMoved = -1) const; //returns stack in order of their movement action void getStackQueue(std::vector<const CStack *> &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); CStack * getStack(int stackID, bool onlyAlive = true);
const CStack * getStack(int stackID, bool onlyAlive = true) const; const CStack * getStack(int stackID, bool onlyAlive = true) const;
CStack * getStackT(int tileID, bool onlyAlive = true); CStack * getStackT(THex tileID, bool onlyAlive = true);
const CStack * getStackT(int tileID, bool onlyAlive = true) const; const CStack * getStackT(THex tileID, bool onlyAlive = true) const;
void getAccessibilityMap(bool *accessibility, bool twoHex, bool attackerOwned, bool addOccupiable, std::set<int> & occupyable, bool flying, int stackToOmmit=-1) const; //send pointer to at least 187 allocated bytes void getAccessibilityMap(bool *accessibility, bool twoHex, bool attackerOwned, bool addOccupiable, std::set<int> & 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 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 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<int> getAccessibility(int stackID, bool addOccupiable) const; //returns vector of accessible tiles (taking into account the creature range) std::vector<int> 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 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<int> neighbouringTiles(int hex); static std::vector<int> 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) 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<ui32, ui32> 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 <min dmg, max dmg> std::pair<ui32, ui32> 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 <min dmg, max dmg>
void calculateCasualties(std::map<ui32,si32> *casualties) const; //casualties are array of maps size 2 (attacker, defeneder), maps are (crid => amount) void calculateCasualties(std::map<ui32,si32> *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 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 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) 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) 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 si16 shots; //how many shots left

View File

@ -591,7 +591,7 @@ unsigned int CGHeroInstance::getTileCost(const TerrainTile &dest, const TerrainT
else else
{ {
ret = type->heroClass->terrCosts[from.tertype]; 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; return ret;
} }
@ -660,7 +660,7 @@ int CGHeroInstance::getPrimSkillLevel(int id) const
return ret; return ret;
} }
ui8 CGHeroInstance::getSecSkillLevel(const int & ID) const ui8 CGHeroInstance::getSecSkillLevel(SecondarySkill skill) const
{ {
for(size_t i=0; i < secSkills.size(); ++i) for(size_t i=0; i < secSkills.size(); ++i)
if(secSkills[i].first==ID) if(secSkills[i].first==ID)
@ -668,7 +668,7 @@ ui8 CGHeroInstance::getSecSkillLevel(const int & ID) const
return 0; return 0;
} }
void CGHeroInstance::setSecSkillLevel(int which, int val, bool abs) void CGHeroInstance::setSecSkillLevel(SecondarySkill which, int val, bool abs)
{ {
if(getSecSkillLevel(which) == 0) if(getSecSkillLevel(which) == 0)
{ {
@ -1277,7 +1277,9 @@ ui8 CGHeroInstance::getSpellSchoolLevel(const CSpell * spell, int *outSelectedSc
#define TRY_SCHOOL(schoolName, schoolMechanicsId, schoolOutId) \ #define TRY_SCHOOL(schoolName, schoolMechanicsId, schoolOutId) \
if(spell-> schoolName) \ if(spell-> schoolName) \
{ \ { \
int thisSchool = std::max<int>(getSecSkillLevel(14 + (schoolMechanicsId)), valOfBonuses(Bonus::MAGIC_SCHOOL_SKILL, 1 << (schoolMechanicsId))); \ int thisSchool = std::max<int>(getSecSkillLevel( \
static_cast<CGHeroInstance::SecondarySkill>(14 + (schoolMechanicsId))), \
valOfBonuses(Bonus::MAGIC_SCHOOL_SKILL, 1 << (schoolMechanicsId))); \
if(thisSchool > skill) \ if(thisSchool > skill) \
{ \ { \
skill = thisSchool; \ skill = thisSchool; \
@ -1328,7 +1330,7 @@ bool CGHeroInstance::canCastThisSpell(const CSpell * spell) const
*/ */
CStackBasicDescriptor CGHeroInstance::calculateNecromancy (const BattleResult &battleResult) const CStackBasicDescriptor CGHeroInstance::calculateNecromancy (const BattleResult &battleResult) const
{ {
const ui8 necromancyLevel = getSecSkillLevel(12); const ui8 necromancyLevel = getSecSkillLevel(CGHeroInstance::NECROMANCY);
// Hero knows necromancy. // Hero knows necromancy.
if (necromancyLevel > 0) if (necromancyLevel > 0)
@ -1405,7 +1407,7 @@ int3 CGHeroInstance::getSightCenter() const
int CGHeroInstance::getSightRadious() 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 si32 CGHeroInstance::manaRegain() const
@ -2515,7 +2517,7 @@ void CGVisitableOPH::onNAHeroVisit(int heroID, bool alreadyVisited) const
case 100: //give exp case 100: //give exp
{ {
const CGHeroInstance *h = cb->getHero(heroID); 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; InfoWindow iw;
iw.soundID = sound; iw.soundID = sound;
iw.components.push_back(Component(id,subid,val,0)); 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 case 41://library of enlightenment
{ {
const CGHeroInstance *h = cb->getHero(heroID); 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; InfoWindow iw;
iw.soundID = sound; iw.soundID = sound;
@ -2810,7 +2812,7 @@ void CTownBonus::onHeroVisit (const CGHeroInstance * h) const
break; break;
case 5://academy of battle scholars case 5://academy of battle scholars
what = 4; what = 4;
val = 1000*(100+h->getSecSkillLevel(21)*5)/100.0f; val = 1000*(100+h->getSecSkillLevel(CGHeroInstance::LEARNING)*5)/100.0f;
mid = 583; mid = 583;
iw.components.push_back (Component(Component::EXPERIENCE, 0, val, 0)); iw.components.push_back (Component(Component::EXPERIENCE, 0, val, 0));
break; break;
@ -3033,12 +3035,12 @@ int CGCreature::takenAction(const CGHeroInstance *h, bool allowJoin) const
sympathy++; sympathy++;
int charisma = factor + h->getSecSkillLevel(4) + sympathy; int charisma = factor + h->getSecSkillLevel(CGHeroInstance::DIPLOMACY) + sympathy;
if(charisma >= character) //creatures might join... 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 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 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.player = h->tempOwner;
sd.text << std::pair<ui8,ui32>(11,146); sd.text << std::pair<ui8,ui32>(11,146);
sd.components.push_back(Component(2,6,val1,0)); 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.components.push_back(Component(5,0,expVal, 0));
sd.soundID = soundBase::chest; sd.soundID = soundBase::chest;
boost::function<void(ui32)> fun = boost::bind(&CGPickable::chosen,this,_1,h->id); boost::function<void(ui32)> 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); cb->giveResource(cb->getOwner(heroID),6,val1);
break; break;
case 2: //player pick exp 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; break;
default: default:
throw std::string("Unhandled treasure choice"); throw std::string("Unhandled treasure choice");
@ -4322,7 +4324,7 @@ void CGSeerHut::onHeroVisit( const CGHeroInstance * h ) const
switch (rewardType) 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; break;
case 2: bd.components.push_back (Component (Component::PRIM_SKILL, 5, rVal, 0)); case 2: bd.components.push_back (Component (Component::PRIM_SKILL, 5, rVal, 0));
break; break;
@ -4421,7 +4423,7 @@ void CGSeerHut::completeQuest (const CGHeroInstance * h) const //reward
{ {
case 1: //experience 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); cb->changePrimSkill(h->id, 4, expVal, false);
break; break;
} }
@ -4502,7 +4504,7 @@ void CGWitchHut::onHeroVisit( const CGHeroInstance * h ) const
if(!hasVisited(h->tempOwner)) if(!hasVisited(h->tempOwner))
cb->setObjProperty(id,10,h->tempOwner); cb->setObjProperty(id,10,h->tempOwner);
if(h->getSecSkillLevel(ability)) //you alredy know this skill if(h->getSecSkillLevel(static_cast<CGHeroInstance::SecondarySkill>(ability))) //you alredy know this skill
{ {
iw.text << std::pair<ui8,ui32>(11,172); iw.text << std::pair<ui8,ui32>(11,172);
iw.text.addReplacement(MetaString::SEC_SKILL_NAME, ability); 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) hoverName += "\n" + VLC->generaltexth->allTexts[356]; // + (learn %s)
boost::algorithm::replace_first(hoverName,"%s",VLC->generaltexth->skillName[ability]); boost::algorithm::replace_first(hoverName,"%s",VLC->generaltexth->skillName[ability]);
const CGHeroInstance *h = cb->getSelectedHero(cb->getCurrentPlayer()); const CGHeroInstance *h = cb->getSelectedHero(cb->getCurrentPlayer());
if(h && h->getSecSkillLevel(ability)) //hero knows that ability if(h && h->getSecSkillLevel(static_cast<CGHeroInstance::SecondarySkill>(ability))) //hero knows that ability
hoverName += "\n\n" + VLC->generaltexth->allTexts[357]; // (Already learned) hoverName += "\n\n" + VLC->generaltexth->allTexts[357]; // (Already learned)
} }
return hoverName; return hoverName;
@ -4874,7 +4876,7 @@ void CGPandoraBox::giveContents( const CGHeroInstance *h, bool afterBattle ) con
if(gainedExp || changesPrimSkill || abilities.size()) 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); getText(iw,afterBattle,175,h);
if(expVal) if(expVal)
@ -4899,7 +4901,7 @@ void CGPandoraBox::giveContents( const CGHeroInstance *h, bool afterBattle ) con
//give sec skills //give sec skills
for(int i=0; i<abilities.size(); i++) for(int i=0; i<abilities.size(); i++)
{ {
int curLev = h->getSecSkillLevel(abilities[i]); int curLev = h->getSecSkillLevel(static_cast<CGHeroInstance::SecondarySkill>(abilities[i]));
if( (curLev && curLev < abilityLevels[i]) if( (curLev && curLev < abilityLevels[i])
|| (h->secSkills.size() < SKILL_PER_HERO) ) || (h->secSkills.size() < SKILL_PER_HERO) )
@ -4917,7 +4919,7 @@ void CGPandoraBox::giveContents( const CGHeroInstance *h, bool afterBattle ) con
std::vector<ConstTransitivePtr<CSpell> > * sp = &VLC->spellh->spells; std::vector<ConstTransitivePtr<CSpell> > * sp = &VLC->spellh->spells;
for(std::vector<si32>::const_iterator i=spells.begin(); i != spells.end(); i++) for(std::vector<si32>::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)); iw.components.push_back(Component(Component::SPELL,*i,0,0));
spellsToGive.insert(*i); spellsToGive.insert(*i);
@ -5156,7 +5158,7 @@ void CGShrine::onHeroVisit( const CGHeroInstance * h ) const
{ {
iw.text.addTxt(MetaString::ADVOB_TXT,131); 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); iw.text.addTxt(MetaString::ADVOB_TXT,130);
} }
@ -5243,10 +5245,11 @@ void CGScholar::onHeroVisit( const CGHeroInstance * h ) const
int type = bonusType; int type = bonusType;
int bid = bonusID; int bid = bonusID;
//check if the bonus if applicable, if not - give primary skill (always possible) //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<CGHeroInstance::SecondarySkill>(bid)); //current sec skill level, used if bonusType == 1
if((type == 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) && ((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 ))) //hero doesn't have a spellbook or already knows the spell or doesn't have Wisdom
{ {
type = 0; type = 0;
@ -5976,7 +5979,7 @@ void CGPyramid::endBattle (const CGHeroInstance *h, const BattleResult *result)
iw.text.addTxt (MetaString::SPELL_NAME, spell); iw.text.addTxt (MetaString::SPELL_NAME, spell);
if (!h->getArt(17)) if (!h->getArt(17))
iw.text.addTxt (MetaString::ADVOB_TXT, 109); //no spellbook 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 iw.text.addTxt (MetaString::ADVOB_TXT, 108); //no expert Wisdom
else else
{ {

View File

@ -246,6 +246,13 @@ public:
class DLL_EXPORT CGHeroInstance : public CArmedInstance, public IBoatGenerator class DLL_EXPORT CGHeroInstance : public CArmedInstance, public IBoatGenerator
{ {
public: 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 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 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 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 int getPrimSkillLevel(int id) const; //0-attack, 1-defence, 2-spell power, 3-knowledge
ui8 getSecSkillLevel(const int & ID) const; //0 - no skill ui8 getSecSkillLevel(SecondarySkill skill) const; //0 - no skill
void setSecSkillLevel(int which, int val, bool abs);// abs == 0 - changes by value; 1 - sets to value void setSecSkillLevel(SecondarySkill which, int val, bool abs);// abs == 0 - changes by value; 1 - sets to value
int maxMovePoints(bool onLand) const; int maxMovePoints(bool onLand) const;

View File

@ -77,7 +77,7 @@ DLL_EXPORT void SetPrimSkill::applyGs( CGameState *gs )
DLL_EXPORT void SetSecSkill::applyGs( CGameState *gs ) DLL_EXPORT void SetSecSkill::applyGs( CGameState *gs )
{ {
CGHeroInstance *hero = gs->getHero(id); CGHeroInstance *hero = gs->getHero(id);
hero->setSecSkillLevel(which, val, abs); hero->setSecSkillLevel(static_cast<CGHeroInstance::SecondarySkill>(which), val, abs);
} }
DLL_EXPORT void HeroVisitCastle::applyGs( CGameState *gs ) DLL_EXPORT void HeroVisitCastle::applyGs( CGameState *gs )

View File

@ -332,9 +332,9 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
//end battle, remove all info, free memory //end battle, remove all info, free memory
giveExp(*battleResult.data); giveExp(*battleResult.data);
if (hero1) 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) 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]; ui8 sides[2];
sides[0] = gs->curB->side1; sides[0] = gs->curB->side1;
@ -1201,7 +1201,7 @@ void CGameHandler::giveSpells( const CGTownInstance *t, const CGHeroInstance *h
ChangeSpells cs; ChangeSpells cs;
cs.hid = h->id; cs.hid = h->id;
cs.learn = true; cs.learn = true;
for(int i=0; i<std::min(t->mageGuildLevel(),h->getSecSkillLevel(7)+2);i++) for(int i=0; i<std::min(t->mageGuildLevel(),h->getSecSkillLevel(CGHeroInstance::WISDOM)+2);i++)
{ {
if (t->subID == 8 && vstd::contains(t->builtBuildings, 26)) //Aurora Borealis 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 * h1 = getHero(fromHero);
const CGHeroInstance * h2 = getHero(toHero); 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 (h1,h2);//1st hero need to have higher scholar level for correct message
std::swap(fromHero, toHero); 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) ) if (!ScholarLevel || !vstd::contains(h1->artifWorn,17) || !vstd::contains(h2->artifWorn,17) )
return;//no scholar skill or no spellbook return;//no scholar skill or no spellbook
int h1Lvl = std::min(ScholarLevel+1, h1->getSecSkillLevel(7)+2), int h1Lvl = std::min(ScholarLevel+1, h1->getSecSkillLevel(CGHeroInstance::WISDOM)+2),
h2Lvl = std::min(ScholarLevel+1, h2->getSecSkillLevel(7)+2);//heroes can receive this levels h2Lvl = std::min(ScholarLevel+1, h2->getSecSkillLevel(CGHeroInstance::WISDOM)+2);//heroes can receive this levels
ChangeSpells cs1; ChangeSpells cs1;
cs1.learn = true; cs1.learn = true;
@ -2855,7 +2855,7 @@ bool CGameHandler::buySecSkill( const IMarket *m, const CGHeroInstance *h, int s
if (!h) if (!h)
COMPLAIN_RET("You need hero to buy a skill!"); COMPLAIN_RET("You need hero to buy a skill!");
if (h->getSecSkillLevel(skill)) if (h->getSecSkillLevel(static_cast<CGHeroInstance::SecondarySkill>(skill)))
COMPLAIN_RET("Hero already know this skill"); COMPLAIN_RET("Hero already know this skill");
if (h->secSkills.size() >= SKILL_PER_HERO)//can't learn more skills if (h->secSkills.size() >= SKILL_PER_HERO)//can't learn more skills
@ -3258,7 +3258,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
{ {
sendAndApply(&StartAction(ba)); sendAndApply(&StartAction(ba));
const CGHeroInstance * attackingHero = gs->curB->heroes[ba.side]; 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); int attackedPart = gs->curB->hexToWallPart(ba.destinationTile);
if(attackedPart == -1) if(attackedPart == -1)
@ -4637,7 +4637,7 @@ bool CGameHandler::sacrificeCreatures(const IMarket *market, const CGHeroInstanc
int dump, exp; int dump, exp;
market->getOffer(crid, 0, dump, exp, CREATURE_EXP); market->getOffer(crid, 0, dump, exp, CREATURE_EXP);
exp *= count; 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; return true;
} }
@ -4804,8 +4804,8 @@ void CGameHandler::runBattle()
//tactic round //tactic round
{ {
if( (gs->curB->heroes[0] && gs->curB->heroes[0]->getSecSkillLevel(19)>0) || if( (gs->curB->heroes[0] && gs->curB->heroes[0]->getSecSkillLevel(CGHeroInstance::TACTICS)>0) ||
( gs->curB->heroes[1] && gs->curB->heroes[1]->getSecSkillLevel(19)>0) )//someone has tactics ( gs->curB->heroes[1] && gs->curB->heroes[1]->getSecSkillLevel(CGHeroInstance::TACTICS)>0) )//someone has tactics
{ {
//TODO: tactic round (round -1) //TODO: tactic round (round -1)
NEW_ROUND; NEW_ROUND;
@ -4891,8 +4891,8 @@ void CGameHandler::runBattle()
const CGHeroInstance * curOwner = gs->battleGetOwner(next->ID); const CGHeroInstance * curOwner = gs->battleGetOwner(next->ID);
if( (next->position < 0 && (!curOwner || curOwner->getSecSkillLevel(10) == 0)) //arrow turret, hero has no ballistics if( (next->position < 0 && (!curOwner || curOwner->getSecSkillLevel(CGHeroInstance::BALLISTICS) == 0)) //arrow turret, hero has no ballistics
|| (next->getCreature()->idNumber == 146 && (!curOwner || curOwner->getSecSkillLevel(20) == 0))) //ballista, hero has no artillery || (next->getCreature()->idNumber == 146 && (!curOwner || curOwner->getSecSkillLevel(CGHeroInstance::ARTILLERY) == 0))) //ballista, hero has no artillery
{ {
BattleAction attack; BattleAction attack;
attack.actionType = BattleAction::SHOOT; attack.actionType = BattleAction::SHOOT;
@ -4914,7 +4914,7 @@ void CGameHandler::runBattle()
continue; 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; BattleAction attack;
static const int wallHexes[] = {50, 183, 182, 130, 62, 29, 12, 95}; static const int wallHexes[] = {50, 183, 182, 130, 62, 29, 12, 95};
@ -4929,7 +4929,7 @@ void CGameHandler::runBattle()
continue; 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; BattleAction heal;