1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-08-15 20:03:15 +02:00

Commanders can level up. It's non-interactive yet.

Printing secondary skills for Commanders.
This commit is contained in:
DjWarmonger
2012-05-18 14:02:27 +00:00
parent ed634a5f06
commit d491bc1c3a
19 changed files with 222 additions and 85 deletions

View File

@@ -22,8 +22,7 @@ public:
void showBlockingDialog(const std::string &text, const std::vector<Component> &components, ui32 askID, int soundID, bool selection, bool cancel){}; void showBlockingDialog(const std::string &text, const std::vector<Component> &components, ui32 askID, int soundID, bool selection, bool cancel){};
void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, boost::function<void()> &onEnd) {}; void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, boost::function<void()> &onEnd) {};
void heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector<ui16> &skills, boost::function<void(ui32)> &callback); void heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector<ui16> &skills, boost::function<void(ui32)> &callback);
void commanderGotLevel (const CCommanderInstance * commander, std::vector<std::pair<ui8, ui8> > secondarySkills, void commanderGotLevel (const CCommanderInstance * commander, std::vector<ui32> skills, boost::function<void(ui32)> &callback) {}; //TODO
std::vector<Bonus *> specialSkills, boost::function<void(ui32)> &callback) {};
}; };
#define NAME "EmptyAI 0.1" #define NAME "EmptyAI 0.1"

View File

@@ -210,8 +210,7 @@ public:
virtual void init(CCallback * CB); virtual void init(CCallback * CB);
virtual void yourTurn(); virtual void yourTurn();
virtual void heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector<ui16> &skills, boost::function<void(ui32)> &callback) OVERRIDE; //pskill is gained primary skill, interface has to choose one of given skills and call callback with selection id virtual void heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector<ui16> &skills, boost::function<void(ui32)> &callback) OVERRIDE; //pskill is gained primary skill, interface has to choose one of given skills and call callback with selection id
virtual void commanderGotLevel (const CCommanderInstance * commander, std::vector<std::pair<ui8, ui8> > secondarySkills, virtual void commanderGotLevel (const CCommanderInstance * commander, std::vector<ui32> skills, boost::function<void(ui32)> &callback) {}; //TODO
std::vector<Bonus *> specialSkills, boost::function<void(ui32)> &callback) {};
virtual void showBlockingDialog(const std::string &text, const std::vector<Component> &components, ui32 askID, const int soundID, bool selection, bool cancel) OVERRIDE; //Show a dialog, player must take decision. If selection then he has to choose between one of given components, if cancel he is allowed to not choose. After making choice, CCallback::selectionMade should be called with number of selected component (1 - n) or 0 for cancel (if allowed) and askID. virtual void showBlockingDialog(const std::string &text, const std::vector<Component> &components, ui32 askID, const int soundID, bool selection, bool cancel) OVERRIDE; //Show a dialog, player must take decision. If selection then he has to choose between one of given components, if cancel he is allowed to not choose. After making choice, CCallback::selectionMade should be called with number of selected component (1 - n) or 0 for cancel (if allowed) and askID.
virtual void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, boost::function<void()> &onEnd) OVERRIDE; //all stacks operations between these objects become allowed, interface has to call onEnd when done virtual void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, boost::function<void()> &onEnd) OVERRIDE; //all stacks operations between these objects become allowed, interface has to call onEnd when done
virtual void serialize(COSer<CSaveFile> &h, const int version) OVERRIDE; //saving virtual void serialize(COSer<CSaveFile> &h, const int version) OVERRIDE; //saving

View File

@@ -301,8 +301,7 @@ void CCreatureWindow::init(const CStackInstance *Stack, const CBonusSystemNode *
{ {
for (int i = ECommander::ATTACK; i <= ECommander::SPELL_POWER; ++i) for (int i = ECommander::ATTACK; i <= ECommander::SPELL_POWER; ++i)
{ {
auto it = commander->secondarySkills.find(i); if (commander->secondarySkills[i])
if (it != commander->secondarySkills.end())
{ {
std::string file = "zvs/Lib1.res/_"; std::string file = "zvs/Lib1.res/_";
switch (i) switch (i)
@@ -326,10 +325,22 @@ void CCreatureWindow::init(const CStackInstance *Stack, const CBonusSystemNode *
file += "MP"; file += "MP";
break; break;
} }
file += boost::lexical_cast<std::string>(it->second); std::string sufix = boost::lexical_cast<std::string>((int)(commander->secondarySkills[i] - 1)); //casting ui8 causes ascii char conversion
if (type == COMMANDER_LEVEL_UP)
{
if (commander->secondarySkills[i] < ECommander::MAX_SKILL_LEVEL)
sufix += "="; //level-up highlight
else
sufix = "no"; //not avaliable - no number
}
file += sufix += ".bmp";
auto skillGraphics = new CPicture(file, 40 + i * 82, 121); //bonusGraphics = new CPicture(graphicsName, 26, 232);
blitAtLoc(skillGraphics->bg, 0, 0, bitmap->bg); //blitAtLoc(bonusGraphics->bg, 12, 2, bitmap->bg);
auto skillGraphics = new CPicture(file, 39 + i * 82, 223);
//if (skillGraphics->bg)
// blitAtLoc(skillGraphics->bg, 0, 0, bitmap->bg);
} }
} }
} }

View File

@@ -40,7 +40,7 @@ class CAnimImage;
class CCreatureWindow : public CArtifactHolder class CCreatureWindow : public CArtifactHolder
{ {
public: public:
enum CreWinType {OTHER = 0, BATTLE = 1, ARMY = 2, HERO = 3, COMMANDER = 4}; // > 3 are opened permanently enum CreWinType {OTHER = 0, BATTLE = 1, ARMY = 2, HERO = 3, COMMANDER = 4, COMMANDER_LEVEL_UP = 5}; // > 3 are opened permanently
//bool active; //TODO: comment me //bool active; //TODO: comment me
int type;//0 - rclick popup; 1 - normal window int type;//0 - rclick popup; 1 - normal window
int bonusRows; //height of skill window int bonusRows; //height of skill window

View File

@@ -487,15 +487,20 @@ void CPlayerInterface::heroGotLevel(const CGHeroInstance *hero, int pskill, std:
CLevelWindow *lw = new CLevelWindow(hero,pskill,skills,callback); CLevelWindow *lw = new CLevelWindow(hero,pskill,skills,callback);
GH.pushInt(lw); GH.pushInt(lw);
} }
void CPlayerInterface::commanderGotLevel (const CCommanderInstance * commander, std::vector<std::pair<ui8, ui8> > secondarySkills, void CPlayerInterface::commanderGotLevel (const CCommanderInstance * commander, std::vector<ui32> skills, boost::function<void(ui32)> &callback)
std::vector<Bonus *> specialSkills, boost::function<void(ui32)> &callback)
{ {
EVENT_HANDLER_CALLED_BY_CLIENT; EVENT_HANDLER_CALLED_BY_CLIENT;
waitWhileDialog(); waitWhileDialog();
CCS->soundh->playSound(soundBase::heroNewLevel); CCS->soundh->playSound(soundBase::heroNewLevel);
CCreatureWindow * cw = new CCreatureWindow(commander); //boost::function<void(ui32)>(boost::bind(&CCallback::selectionMade,cl->callbacks[h->tempOwner].get(),_1,id))
GH.pushInt(cw); auto callback2 = boost::bind (&CCallback::selectionMade, cb, 0, playerID);
showYesNoDialog ("Commander got level", callback2, callback2, true, std::vector<CComponent*>());
//showYesNoDialog ("Commander got level", callback, callback, true, std::vector<CComponent*>());
//TODO: display full window
//CCreatureWindow * cw = new CCreatureWindow(commander);
//GH.pushInt(cw);
} }
void CPlayerInterface::heroInGarrisonChange(const CGTownInstance *town) void CPlayerInterface::heroInGarrisonChange(const CGTownInstance *town)
{ {

View File

@@ -139,8 +139,7 @@ public:
void heroCreated(const CGHeroInstance* hero) OVERRIDE; void heroCreated(const CGHeroInstance* hero) OVERRIDE;
void heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector<ui16> &skills, boost::function<void(ui32)> &callback) OVERRIDE; void heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector<ui16> &skills, boost::function<void(ui32)> &callback) OVERRIDE;
void commanderGotLevel (const CCommanderInstance * commander, std::vector<std::pair<ui8, ui8> > secondarySkills, void commanderGotLevel (const CCommanderInstance * commander, std::vector<ui32> skills, boost::function<void(ui32)> &callback) OVERRIDE;
std::vector<Bonus *> specialSkills, boost::function<void(ui32)> &callback) OVERRIDE;
void heroInGarrisonChange(const CGTownInstance *town) OVERRIDE; void heroInGarrisonChange(const CGTownInstance *town) OVERRIDE;
void heroMoved(const TryMoveHero & details) OVERRIDE; void heroMoved(const TryMoveHero & details) OVERRIDE;
void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, si64 val) OVERRIDE; void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, si64 val) OVERRIDE;

View File

@@ -537,8 +537,15 @@ void HeroLevelUp::applyCl( CClient *cl )
} }
void CommanderLevelUp::applyCl( CClient *cl ) void CommanderLevelUp::applyCl( CClient *cl )
{ {
if (commander->armyObj && vstd::contains(cl->playerint, commander->armyObj->tempOwner)) //is it possible for Commander to exist beyond armed instance? CCommanderInstance * commander = GS(cl)->getHero(heroid)->commander;
assert (commander);
ui8 player = commander->armyObj->tempOwner;
if (commander->armyObj && vstd::contains(cl->playerint, player)) //is it possible for Commander to exist beyond armed instance?
{ {
auto callback = boost::function<void(ui32)>(boost::bind(&CCallback::selectionMade,cl->callbacks[player].get(),_1,id));
cl->playerint[player]->showBlockingDialog("Commander got level", std::vector<Component>(), id, -1, false, true);
//cl->playerint[player]->commanderGotLevel(commander, skills, callback);
} }
} }

View File

@@ -24,16 +24,16 @@
//Value of bonuses given by each skill level //Value of bonuses given by each skill level
"skillLevels": "skillLevels":
[ [
{"ATTACK": [2, 5, 9, 15, 25]}, //0 {"name": "ATTACK", "levels": [2, 5, 9, 15, 25]}, //0
{"DEFENSE": [4, 10, 18, 30, 50]}, //1 {"name": "DEFENSE", "levels": [4, 10, 18, 30, 50]}, //1
{"HEALTH": [10, 25, 45, 70, 100]}, //2 {"name": "HEALTH", "levels": [10, 25, 45, 70, 100]}, //2
{"DAMAGE": [10, 25, 45, 70, 100]}, //3 {"name": "DAMAGE", "levels": [10, 25, 45, 70, 100]}, //3
{"SPEED": [1, 2, 3, 4, 6]}, //4 {"name": "SPEED", "levels": [1, 2, 3, 4, 6]}, //4
{"SPELL_POWER":[1, 3, 6, 14, 29]}, //5 {"name": "SPELL_POWER", "levels": [1, 3, 6, 14, 29]}, //5
{"CASTS": [1, 2, 3, 4, 5]}, {"name": "CASTS", "levels": [1, 2, 3, 4, 5]},
{"RESISTANCE": [5, 15, 35, 60, 90]} {"name": "RESISTANCE", "levels": [5, 15, 35, 60, 90]}
], ],
"abilityRequiremenets": "abilityRequirements":
//Two secondary skills needed for each special ability //Two secondary skills needed for each special ability
[ [
{"ability": ["ENEMY_DEFENCE_REDUCTION", 50, 0, 0 ], "skills": [0, 1]}, {"ability": ["ENEMY_DEFENCE_REDUCTION", 50, 0, 0 ], "skills": [0, 1]},

View File

@@ -624,7 +624,8 @@ void CCreatureHandler::loadCreatures()
i = 0; i = 0;
BOOST_FOREACH (auto skill, config3["skillLevels"].Vector()) BOOST_FOREACH (auto skill, config3["skillLevels"].Vector())
{ {
BOOST_FOREACH (auto skillLevel, skill.Vector()) skillLevels.push_back (std::vector<ui8>());
BOOST_FOREACH (auto skillLevel, skill["levels"].Vector())
{ {
skillLevels[i].push_back (skillLevel.Float()); skillLevels[i].push_back (skillLevel.Float());
} }

View File

@@ -981,11 +981,13 @@ void CCommanderInstance::init()
{ {
alive = true; alive = true;
experience = 0; experience = 0;
level = 1;
count = 1; count = 1;
type = NULL; type = NULL;
idRand = -1; idRand = -1;
_armyObj = NULL; _armyObj = NULL;
setNodeType (Bonus::COMMANDER); setNodeType (Bonus::COMMANDER);
secondarySkills.resize (ECommander::SPELL_POWER + 1);
} }
CCommanderInstance::~CCommanderInstance() CCommanderInstance::~CCommanderInstance()
@@ -1016,6 +1018,7 @@ int CCommanderInstance::getExpRank() const
void CCommanderInstance::levelUp () void CCommanderInstance::levelUp ()
{ {
level++;
BOOST_FOREACH (auto bonus, VLC->creh->commanderLevelPremy) BOOST_FOREACH (auto bonus, VLC->creh->commanderLevelPremy)
{ //grant all regular level-up bonuses { //grant all regular level-up bonuses
accumulateBonus (*bonus); accumulateBonus (*bonus);

View File

@@ -80,8 +80,9 @@ public:
//commander class is determined by its base creature //commander class is determined by its base creature
ui8 alive; ui8 alive;
ui8 level; //required only to count callbacks
std::string name; // each Commander has different name std::string name; // each Commander has different name
std::map <ui8, ui8> secondarySkills; //ID, level std::vector <ui8> secondarySkills; //ID -> level
//std::vector <CArtifactInstance *> arts; //std::vector <CArtifactInstance *> arts;
void init() OVERRIDE; void init() OVERRIDE;
CCommanderInstance(); CCommanderInstance();
@@ -98,7 +99,7 @@ public:
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
h & static_cast<CStackInstance&>(*this); h & static_cast<CStackInstance&>(*this);
h & alive & name & secondarySkills; h & alive & level & name & secondarySkills;
} }
}; };

View File

@@ -75,8 +75,7 @@ public:
virtual void init(CCallback * CB){}; virtual void init(CCallback * CB){};
virtual void yourTurn(){}; //called AFTER playerStartsTurn(player) virtual void yourTurn(){}; //called AFTER playerStartsTurn(player)
virtual void heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector<ui16> &skills, boost::function<void(ui32)> &callback)=0; //pskill is gained primary skill, interface has to choose one of given skills and call callback with selection id virtual void heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector<ui16> &skills, boost::function<void(ui32)> &callback)=0; //pskill is gained primary skill, interface has to choose one of given skills and call callback with selection id
virtual void commanderGotLevel (const CCommanderInstance * commander, std::vector<std::pair<ui8, ui8> > secondarySkills, virtual void commanderGotLevel (const CCommanderInstance * commander, std::vector<ui32> skills, boost::function<void(ui32)> &callback)=0;
std::vector<Bonus *> specialSkills, boost::function<void(ui32)> &callback) = 0;
virtual void showBlockingDialog(const std::string &text, const std::vector<Component> &components, ui32 askID, const int soundID, bool selection, bool cancel) = 0; //Show a dialog, player must take decision. If selection then he has to choose between one of given components, if cancel he is allowed to not choose. After making choice, CCallback::selectionMade should be called with number of selected component (1 - n) or 0 for cancel (if allowed) and askID. virtual void showBlockingDialog(const std::string &text, const std::vector<Component> &components, ui32 askID, const int soundID, bool selection, bool cancel) = 0; //Show a dialog, player must take decision. If selection then he has to choose between one of given components, if cancel he is allowed to not choose. After making choice, CCallback::selectionMade should be called with number of selected component (1 - n) or 0 for cancel (if allowed) and askID.
virtual void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, boost::function<void()> &onEnd) = 0; //all stacks operations between these objects become allowed, interface has to call onEnd when done virtual void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, boost::function<void()> &onEnd) = 0; //all stacks operations between these objects become allowed, interface has to call onEnd when done
virtual void serialize(COSer<CSaveFile> &h, const int version){}; //saving virtual void serialize(COSer<CSaveFile> &h, const int version){}; //saving

View File

@@ -178,6 +178,7 @@ namespace EBattleStackState
namespace ECommander namespace ECommander
{ {
enum SecondarySkills {ATTACK, DEFENSE, HEALTH, DAMAGE, SPEED, SPELL_POWER, CASTS, RESISTANCE}; enum SecondarySkills {ATTACK, DEFENSE, HEALTH, DAMAGE, SPEED, SPELL_POWER, CASTS, RESISTANCE};
const int MAX_SKILL_LEVEL = 5;
} }
namespace Obj namespace Obj

View File

@@ -658,7 +658,7 @@ void CBonusSystemNode::accumulateBonus(Bonus &b)
{ {
Bonus *bonus = exportedBonuses.getFirst(Selector::typeSubtype(b.type, b.subtype)); //only local bonuses are interesting //TODO: what about value type? Bonus *bonus = exportedBonuses.getFirst(Selector::typeSubtype(b.type, b.subtype)); //only local bonuses are interesting //TODO: what about value type?
if(bonus) if(bonus)
bonus += b.val; bonus->val += b.val;
else else
addNewBonus(new Bonus(b)); //duplicate needed, original may get destroyed addNewBonus(new Bonus(b)); //duplicate needed, original may get destroyed
} }

View File

@@ -33,6 +33,7 @@ class CSelectionScreen;
class CGObjectInstance; class CGObjectInstance;
class CArtifactInstance; class CArtifactInstance;
//class CMapInfo; //class CMapInfo;
struct StackLocation;
struct ArtSlotInfo; struct ArtSlotInfo;
struct QuestInfo; struct QuestInfo;
@@ -165,6 +166,27 @@ public:
} }
}; };
struct StackLocation
{
ConstTransitivePtr<CArmedInstance> army;
TSlot slot;
StackLocation()
{
slot = -1;
}
StackLocation(const CArmedInstance *Army, TSlot Slot)
{
army = const_cast<CArmedInstance*>(Army); //we are allowed here to const cast -> change will go through one of our packages... do not abuse!
slot = Slot;
}
DLL_LINKAGE const CStackInstance *getStack();
template <typename Handler> void serialize(Handler &h, const int version)
{
h & army & slot;
}
};
/***********************************************************************************************************/ /***********************************************************************************************************/
@@ -500,21 +522,25 @@ struct UpdateCampaignState : public CPackForClient //119
h & camp; h & camp;
} }
}; };
struct SetCommanderproperty : public CPackForClient //120 struct SetCommanderProperty : public CPackForClient //120
{ {
enum ECommanderProperty {ALIVE, BONUS}; enum ECommanderProperty {ALIVE, BONUS, SECONDARY_SKILL};
SetCommanderproperty(){type = 120;}; SetCommanderProperty(){type = 120;};
void applyCl(CClient *cl){}; void applyCl(CClient *cl){};
DLL_LINKAGE void applyGs(CGameState *gs){}; DLL_LINKAGE void applyGs(CGameState *gs);
ui8 which; si32 heroid; //for commander attached to hero
ui8 alive; StackLocation sl; //for commander not on the hero?
ui8 which; // use ECommanderProperty
ui8 amount; //0 for dead, >0 for alive
si32 additionalInfo; //for secondary skills choice
Bonus accumulatedBonus; Bonus accumulatedBonus;
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
h & which & alive & accumulatedBonus; h & heroid & sl & which & amount & additionalInfo & accumulatedBonus;
} }
}; };
struct AddQuest : public CPackForClient //121 struct AddQuest : public CPackForClient //121
@@ -762,27 +788,6 @@ struct NewArtifact : public CPackForClient //520
} }
}; };
struct StackLocation
{
ConstTransitivePtr<CArmedInstance> army;
TSlot slot;
StackLocation()
{
slot = -1;
}
StackLocation(const CArmedInstance *Army, TSlot Slot)
{
army = const_cast<CArmedInstance*>(Army); //we are allowed here to const cast -> change will go through one of our packages... do not abuse!
slot = Slot;
}
DLL_LINKAGE const CStackInstance *getStack();
template <typename Handler> void serialize(Handler &h, const int version)
{
h & army & slot;
}
};
struct CGarrisonOperationPack : CPackForClient struct CGarrisonOperationPack : CPackForClient
{ {
}; };
@@ -1159,15 +1164,16 @@ struct CommanderLevelUp : public Query
void applyCl(CClient *cl); void applyCl(CClient *cl);
DLL_LINKAGE void applyGs(CGameState *gs); DLL_LINKAGE void applyGs(CGameState *gs);
CCommanderInstance * commander; si32 heroid; //for commander attached to hero
std::vector<std::pair<ui8, ui8> > secondarySkills; StackLocation sl; //for commander not on the hero?
std::vector<Bonus *> specialSkills;
std::vector<ui32> skills; //1-6 - secondary skills, val - 100 - special skill
CommanderLevelUp(){type = 2005;}; CommanderLevelUp(){type = 2005;};
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
h & id & commander & secondarySkills & specialSkills; h & id & heroid & sl & skills;
} }
}; };

View File

@@ -76,6 +76,28 @@ DLL_LINKAGE void SetSecSkill::applyGs( CGameState *gs )
hero->setSecSkillLevel(static_cast<CGHeroInstance::SecondarySkill>(which), val, abs); hero->setSecSkillLevel(static_cast<CGHeroInstance::SecondarySkill>(which), val, abs);
} }
DLL_LINKAGE void SetCommanderProperty::applyGs(CGameState *gs)
{
CCommanderInstance * commander = gs->getHero(heroid)->commander;
assert (commander);
switch (which)
{
case BONUS:
commander->accumulateBonus (accumulatedBonus);
break;
case SECONDARY_SKILL:
commander->secondarySkills[additionalInfo] = amount;
break;
case ALIVE:
if (amount)
commander->setAlive(true);
else
commander->setAlive(false);
break;
}
}
DLL_LINKAGE void HeroVisitCastle::applyGs( CGameState *gs ) DLL_LINKAGE void HeroVisitCastle::applyGs( CGameState *gs )
{ {
CGHeroInstance *h = gs->getHero(hid); CGHeroInstance *h = gs->getHero(hid);
@@ -901,6 +923,8 @@ DLL_LINKAGE void HeroLevelUp::applyGs( CGameState *gs )
DLL_LINKAGE void CommanderLevelUp::applyGs (CGameState *gs) DLL_LINKAGE void CommanderLevelUp::applyGs (CGameState *gs)
{ {
CCommanderInstance * commander = gs->getHero(heroid)->commander;
assert (commander);
commander->levelUp(); commander->levelUp();
} }
@@ -1007,7 +1031,7 @@ void BattleResult::applyGs( CGameState *gs )
if (h) if (h)
{ {
h->getBonusList().remove_if(Bonus::OneBattle); h->getBonusList().remove_if(Bonus::OneBattle);
if (h->commander) if (h->commander && h->commander->alive)
{ {
h->commander->giveStackExp(exp[i]); h->commander->giveStackExp(exp[i]);
CBonusSystemNode::treeHasChanged(); CBonusSystemNode::treeHasChanged();

View File

@@ -139,6 +139,7 @@ void registerTypes2(Serializer &s)
s.template registerType<SetHoverName>(); s.template registerType<SetHoverName>();
s.template registerType<HeroLevelUp>(); s.template registerType<HeroLevelUp>();
s.template registerType<CommanderLevelUp>(); s.template registerType<CommanderLevelUp>();
s.template registerType<SetCommanderProperty>();
s.template registerType<BlockingDialog>(); s.template registerType<BlockingDialog>();
s.template registerType<GarrisonDialog>(); s.template registerType<GarrisonDialog>();
s.template registerType<BattleStart>(); s.template registerType<BattleStart>();

View File

@@ -285,42 +285,123 @@ void CGameHandler::levelUpHero(int ID)
} }
} }
void CGameHandler::levelUpCommander (const CCommanderInstance * c, int secondarySkill, int specialSKill) void CGameHandler::levelUpCommander (const CCommanderInstance * c, int skill)
{ {
if (secondarySkill >=0 ) SetCommanderProperty scp;
auto hero = dynamic_cast<const CGHeroInstance *>(c->armyObj);
if (hero)
scp.heroid = hero->id;
else
{ {
//c->secondarySkills[secondarySkill]++; //TODO: make sure to resize vector in first place complain ("Commander is not led by hero!");
return;
} }
if (specialSKill >= 0)
scp.which = SetCommanderProperty::BONUS;
scp.accumulatedBonus.additionalInfo = 0;
scp.accumulatedBonus.duration = Bonus::PERMANENT;
scp.accumulatedBonus.turnsRemain = 0;
scp.accumulatedBonus.source = Bonus::COMMANDER;
scp.accumulatedBonus.valType = Bonus::BASE_NUMBER;
if (skill <= ECommander::SPELL_POWER)
{ {
auto it = VLC->creh->skillRequirements.begin(); auto difference = [](std::vector< std::vector <ui8> > skillLevels, std::vector <ui8> secondarySkills, int skill)->int
std::advance(it, specialSKill); //suboptimal, use bmap? {
//c->accumulateBonus(it->first); return skillLevels[skill][secondarySkills[skill]] - (secondarySkills[skill] ? skillLevels[skill][secondarySkills[skill]-1] : 0);
};
switch (skill)
{
case ECommander::ATTACK:
scp.accumulatedBonus.type = Bonus::PRIMARY_SKILL;
scp.accumulatedBonus.subtype = PrimarySkill::ATTACK;
break;
case ECommander::DEFENSE:
scp.accumulatedBonus.type = Bonus::PRIMARY_SKILL;
scp.accumulatedBonus.subtype = PrimarySkill::DEFENSE;
break;
case ECommander::HEALTH:
scp.accumulatedBonus.type = Bonus::STACK_HEALTH;
scp.accumulatedBonus.valType = Bonus::PERCENT_TO_BASE;
break;
case ECommander::DAMAGE:
scp.accumulatedBonus.type = Bonus::CREATURE_DAMAGE;
scp.accumulatedBonus.subtype = 0;
scp.accumulatedBonus.valType = Bonus::PERCENT_TO_BASE;
break;
case ECommander::SPEED:
scp.accumulatedBonus.type = Bonus::STACKS_SPEED;
break;
case ECommander::SPELL_POWER:
scp.accumulatedBonus.type = Bonus::MAGIC_RESISTANCE;
scp.accumulatedBonus.val = difference (VLC->creh->skillLevels, c->secondarySkills, ECommander::RESISTANCE);
sendAndApply (&scp); //additional pack
scp.accumulatedBonus.type = Bonus::CASTS;
scp.accumulatedBonus.val = difference (VLC->creh->skillLevels, c->secondarySkills, ECommander::CASTS);
sendAndApply (&scp); //additional pack
scp.accumulatedBonus.type = Bonus::CREATURE_ENCHANT_POWER; //send normally
break;
}
scp.accumulatedBonus.val = difference (VLC->creh->skillLevels, c->secondarySkills, skill);
sendAndApply (&scp);
scp.which = SetCommanderProperty::SECONDARY_SKILL;
scp.additionalInfo = skill;
scp.amount = c->secondarySkills[skill] + 1;
sendAndApply (&scp);
}
else if (skill >= 100)
{
scp.accumulatedBonus = VLC->creh->skillRequirements[skill-100].first;
sendAndApply (&scp);
} }
levelUpCommander (c); levelUpCommander (c);
//c->levelUp(); //change standard parameters
} }
void CGameHandler::levelUpCommander(const CCommanderInstance * c) void CGameHandler::levelUpCommander(const CCommanderInstance * c)
{ {
return; if (c->experience < VLC->heroh->reqExp (c->level + 1))
{
return;
}
CommanderLevelUp clu; CommanderLevelUp clu;
auto hero = dynamic_cast<const CGHeroInstance *>(c->armyObj);
if (hero)
clu.heroid = hero->id;
else
{
complain ("Commander is not led by hero!");
return;
}
//picking sec. skills for choice //picking sec. skills for choice
int secondarySkill = -1, specialSkill = -1; for (int i = 0; i <= ECommander::SPELL_POWER; ++i)
int skills = clu.secondarySkills.size() + clu.specialSkills.size();
if (skills > 1) //apply and ask for secondary skill
{ {
//auto callback = boost::bind (callWith<ui16>, clu.specialSkills, boost::bind(&CGameHandler::levelUpCommander, this, c, _1), _1); if (c->secondarySkills[i] < ECommander::MAX_SKILL_LEVEL)
//applyAndAsk (&clu, c->armyObj->tempOwner, callback); //call levelUpCommander when client responds clu.skills.push_back(i);
} }
else if (skills == 1) //apply, give only possible skill and send info int i = 100;
BOOST_FOREACH (auto specialSkill, VLC->creh->skillRequirements)
{
if (c->secondarySkills[specialSkill.second.first] == ECommander::MAX_SKILL_LEVEL &&
c->secondarySkills[specialSkill.second.second] == ECommander::MAX_SKILL_LEVEL)
clu.skills.push_back (i);
++i;
}
int skillAmount = clu.skills.size();
if (skillAmount > 1) //apply and ask for secondary skill
{
auto callback = boost::function<void(ui32)>(boost::bind(callWith<ui32>, clu.skills, boost::function<void(ui32)>(boost::bind(&CGameHandler::levelUpCommander, this, c, _1)), _1));
applyAndAsk (&clu, c->armyObj->tempOwner, callback); //call levelUpCommander when client responds
}
else if (skillAmount == 1) //apply, give only possible skill and send info
{ {
sendAndApply(&clu); sendAndApply(&clu);
levelUpCommander(c, secondarySkill, specialSkill); levelUpCommander(c, clu.skills.back());
} }
else //apply and send info else //apply and send info
{ {

View File

@@ -182,7 +182,7 @@ public:
void vistiCastleObjects (const CGTownInstance *t, const CGHeroInstance *h); void vistiCastleObjects (const CGTownInstance *t, const CGHeroInstance *h);
void levelUpHero(int ID, int skill);//handle client respond and send one more request if needed void levelUpHero(int ID, int skill);//handle client respond and send one more request if needed
void levelUpHero(int ID);//initial call - check if hero have remaining levelups & handle them void levelUpHero(int ID);//initial call - check if hero have remaining levelups & handle them
void levelUpCommander (const CCommanderInstance * c, int secondarySkill, int specialSKill); void levelUpCommander (const CCommanderInstance * c, int skill); //secondary skill 1 to 6, special skill : skill - 100
void levelUpCommander (const CCommanderInstance * c); void levelUpCommander (const CCommanderInstance * c);
void afterBattleCallback(); // called after level-ups are finished void afterBattleCallback(); // called after level-ups are finished
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////