mirror of
https://github.com/vcmi/vcmi.git
synced 2025-08-13 19:54:17 +02:00
Commanders can level up. It's non-interactive yet.
Printing secondary skills for Commanders.
This commit is contained in:
@@ -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 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 commanderGotLevel (const CCommanderInstance * commander, std::vector<std::pair<ui8, ui8> > secondarySkills,
|
||||
std::vector<Bonus *> specialSkills, boost::function<void(ui32)> &callback) {};
|
||||
void commanderGotLevel (const CCommanderInstance * commander, std::vector<ui32> skills, boost::function<void(ui32)> &callback) {}; //TODO
|
||||
};
|
||||
|
||||
#define NAME "EmptyAI 0.1"
|
||||
|
@@ -210,8 +210,7 @@ public:
|
||||
virtual void init(CCallback * CB);
|
||||
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 commanderGotLevel (const CCommanderInstance * commander, std::vector<std::pair<ui8, ui8> > secondarySkills,
|
||||
std::vector<Bonus *> specialSkills, boost::function<void(ui32)> &callback) {};
|
||||
virtual void commanderGotLevel (const CCommanderInstance * commander, std::vector<ui32> skills, boost::function<void(ui32)> &callback) {}; //TODO
|
||||
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 serialize(COSer<CSaveFile> &h, const int version) OVERRIDE; //saving
|
||||
|
@@ -301,8 +301,7 @@ void CCreatureWindow::init(const CStackInstance *Stack, const CBonusSystemNode *
|
||||
{
|
||||
for (int i = ECommander::ATTACK; i <= ECommander::SPELL_POWER; ++i)
|
||||
{
|
||||
auto it = commander->secondarySkills.find(i);
|
||||
if (it != commander->secondarySkills.end())
|
||||
if (commander->secondarySkills[i])
|
||||
{
|
||||
std::string file = "zvs/Lib1.res/_";
|
||||
switch (i)
|
||||
@@ -326,10 +325,22 @@ void CCreatureWindow::init(const CStackInstance *Stack, const CBonusSystemNode *
|
||||
file += "MP";
|
||||
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);
|
||||
blitAtLoc(skillGraphics->bg, 0, 0, bitmap->bg);
|
||||
//bonusGraphics = new CPicture(graphicsName, 26, 232);
|
||||
//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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -40,7 +40,7 @@ class CAnimImage;
|
||||
class CCreatureWindow : public CArtifactHolder
|
||||
{
|
||||
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
|
||||
int type;//0 - rclick popup; 1 - normal window
|
||||
int bonusRows; //height of skill window
|
||||
|
@@ -487,15 +487,20 @@ void CPlayerInterface::heroGotLevel(const CGHeroInstance *hero, int pskill, std:
|
||||
CLevelWindow *lw = new CLevelWindow(hero,pskill,skills,callback);
|
||||
GH.pushInt(lw);
|
||||
}
|
||||
void CPlayerInterface::commanderGotLevel (const CCommanderInstance * commander, std::vector<std::pair<ui8, ui8> > secondarySkills,
|
||||
std::vector<Bonus *> specialSkills, boost::function<void(ui32)> &callback)
|
||||
void CPlayerInterface::commanderGotLevel (const CCommanderInstance * commander, std::vector<ui32> skills, boost::function<void(ui32)> &callback)
|
||||
{
|
||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||
waitWhileDialog();
|
||||
CCS->soundh->playSound(soundBase::heroNewLevel);
|
||||
|
||||
CCreatureWindow * cw = new CCreatureWindow(commander);
|
||||
GH.pushInt(cw);
|
||||
//boost::function<void(ui32)>(boost::bind(&CCallback::selectionMade,cl->callbacks[h->tempOwner].get(),_1,id))
|
||||
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)
|
||||
{
|
||||
|
@@ -139,8 +139,7 @@ public:
|
||||
|
||||
void heroCreated(const CGHeroInstance* hero) 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,
|
||||
std::vector<Bonus *> specialSkills, boost::function<void(ui32)> &callback) OVERRIDE;
|
||||
void commanderGotLevel (const CCommanderInstance * commander, std::vector<ui32> skills, boost::function<void(ui32)> &callback) OVERRIDE;
|
||||
void heroInGarrisonChange(const CGTownInstance *town) OVERRIDE;
|
||||
void heroMoved(const TryMoveHero & details) OVERRIDE;
|
||||
void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, si64 val) OVERRIDE;
|
||||
|
@@ -537,8 +537,15 @@ void HeroLevelUp::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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -24,16 +24,16 @@
|
||||
//Value of bonuses given by each skill level
|
||||
"skillLevels":
|
||||
[
|
||||
{"ATTACK": [2, 5, 9, 15, 25]}, //0
|
||||
{"DEFENSE": [4, 10, 18, 30, 50]}, //1
|
||||
{"HEALTH": [10, 25, 45, 70, 100]}, //2
|
||||
{"DAMAGE": [10, 25, 45, 70, 100]}, //3
|
||||
{"SPEED": [1, 2, 3, 4, 6]}, //4
|
||||
{"SPELL_POWER":[1, 3, 6, 14, 29]}, //5
|
||||
{"CASTS": [1, 2, 3, 4, 5]},
|
||||
{"RESISTANCE": [5, 15, 35, 60, 90]}
|
||||
{"name": "ATTACK", "levels": [2, 5, 9, 15, 25]}, //0
|
||||
{"name": "DEFENSE", "levels": [4, 10, 18, 30, 50]}, //1
|
||||
{"name": "HEALTH", "levels": [10, 25, 45, 70, 100]}, //2
|
||||
{"name": "DAMAGE", "levels": [10, 25, 45, 70, 100]}, //3
|
||||
{"name": "SPEED", "levels": [1, 2, 3, 4, 6]}, //4
|
||||
{"name": "SPELL_POWER", "levels": [1, 3, 6, 14, 29]}, //5
|
||||
{"name": "CASTS", "levels": [1, 2, 3, 4, 5]},
|
||||
{"name": "RESISTANCE", "levels": [5, 15, 35, 60, 90]}
|
||||
],
|
||||
"abilityRequiremenets":
|
||||
"abilityRequirements":
|
||||
//Two secondary skills needed for each special ability
|
||||
[
|
||||
{"ability": ["ENEMY_DEFENCE_REDUCTION", 50, 0, 0 ], "skills": [0, 1]},
|
||||
|
@@ -624,7 +624,8 @@ void CCreatureHandler::loadCreatures()
|
||||
i = 0;
|
||||
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());
|
||||
}
|
||||
|
@@ -981,11 +981,13 @@ void CCommanderInstance::init()
|
||||
{
|
||||
alive = true;
|
||||
experience = 0;
|
||||
level = 1;
|
||||
count = 1;
|
||||
type = NULL;
|
||||
idRand = -1;
|
||||
_armyObj = NULL;
|
||||
setNodeType (Bonus::COMMANDER);
|
||||
setNodeType (Bonus::COMMANDER);
|
||||
secondarySkills.resize (ECommander::SPELL_POWER + 1);
|
||||
}
|
||||
|
||||
CCommanderInstance::~CCommanderInstance()
|
||||
@@ -1016,6 +1018,7 @@ int CCommanderInstance::getExpRank() const
|
||||
|
||||
void CCommanderInstance::levelUp ()
|
||||
{
|
||||
level++;
|
||||
BOOST_FOREACH (auto bonus, VLC->creh->commanderLevelPremy)
|
||||
{ //grant all regular level-up bonuses
|
||||
accumulateBonus (*bonus);
|
||||
|
@@ -80,8 +80,9 @@ public:
|
||||
|
||||
//commander class is determined by its base creature
|
||||
ui8 alive;
|
||||
ui8 level; //required only to count callbacks
|
||||
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;
|
||||
void init() OVERRIDE;
|
||||
CCommanderInstance();
|
||||
@@ -98,7 +99,7 @@ public:
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & static_cast<CStackInstance&>(*this);
|
||||
h & alive & name & secondarySkills;
|
||||
h & alive & level & name & secondarySkills;
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -75,8 +75,7 @@ public:
|
||||
virtual void init(CCallback * CB){};
|
||||
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 commanderGotLevel (const CCommanderInstance * commander, std::vector<std::pair<ui8, ui8> > secondarySkills,
|
||||
std::vector<Bonus *> specialSkills, boost::function<void(ui32)> &callback) = 0;
|
||||
virtual void commanderGotLevel (const CCommanderInstance * commander, std::vector<ui32> skills, 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 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
|
||||
|
@@ -178,6 +178,7 @@ namespace EBattleStackState
|
||||
namespace ECommander
|
||||
{
|
||||
enum SecondarySkills {ATTACK, DEFENSE, HEALTH, DAMAGE, SPEED, SPELL_POWER, CASTS, RESISTANCE};
|
||||
const int MAX_SKILL_LEVEL = 5;
|
||||
}
|
||||
|
||||
namespace Obj
|
||||
|
@@ -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?
|
||||
if(bonus)
|
||||
bonus += b.val;
|
||||
bonus->val += b.val;
|
||||
else
|
||||
addNewBonus(new Bonus(b)); //duplicate needed, original may get destroyed
|
||||
}
|
||||
|
@@ -33,6 +33,7 @@ class CSelectionScreen;
|
||||
class CGObjectInstance;
|
||||
class CArtifactInstance;
|
||||
//class CMapInfo;
|
||||
struct StackLocation;
|
||||
struct ArtSlotInfo;
|
||||
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;
|
||||
}
|
||||
};
|
||||
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){};
|
||||
DLL_LINKAGE void applyGs(CGameState *gs){};
|
||||
DLL_LINKAGE void applyGs(CGameState *gs);
|
||||
|
||||
ui8 which;
|
||||
ui8 alive;
|
||||
si32 heroid; //for commander attached to hero
|
||||
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;
|
||||
|
||||
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
|
||||
@@ -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
|
||||
{
|
||||
};
|
||||
@@ -1159,15 +1164,16 @@ struct CommanderLevelUp : public Query
|
||||
void applyCl(CClient *cl);
|
||||
DLL_LINKAGE void applyGs(CGameState *gs);
|
||||
|
||||
CCommanderInstance * commander;
|
||||
std::vector<std::pair<ui8, ui8> > secondarySkills;
|
||||
std::vector<Bonus *> specialSkills;
|
||||
si32 heroid; //for commander attached to hero
|
||||
StackLocation sl; //for commander not on the hero?
|
||||
|
||||
std::vector<ui32> skills; //1-6 - secondary skills, val - 100 - special skill
|
||||
|
||||
CommanderLevelUp(){type = 2005;};
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & id & commander & secondarySkills & specialSkills;
|
||||
h & id & heroid & sl & skills;
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -76,6 +76,28 @@ DLL_LINKAGE void SetSecSkill::applyGs( CGameState *gs )
|
||||
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 )
|
||||
{
|
||||
CGHeroInstance *h = gs->getHero(hid);
|
||||
@@ -901,6 +923,8 @@ DLL_LINKAGE void HeroLevelUp::applyGs( CGameState *gs )
|
||||
|
||||
DLL_LINKAGE void CommanderLevelUp::applyGs (CGameState *gs)
|
||||
{
|
||||
CCommanderInstance * commander = gs->getHero(heroid)->commander;
|
||||
assert (commander);
|
||||
commander->levelUp();
|
||||
}
|
||||
|
||||
@@ -1007,7 +1031,7 @@ void BattleResult::applyGs( CGameState *gs )
|
||||
if (h)
|
||||
{
|
||||
h->getBonusList().remove_if(Bonus::OneBattle);
|
||||
if (h->commander)
|
||||
if (h->commander && h->commander->alive)
|
||||
{
|
||||
h->commander->giveStackExp(exp[i]);
|
||||
CBonusSystemNode::treeHasChanged();
|
||||
|
@@ -139,6 +139,7 @@ void registerTypes2(Serializer &s)
|
||||
s.template registerType<SetHoverName>();
|
||||
s.template registerType<HeroLevelUp>();
|
||||
s.template registerType<CommanderLevelUp>();
|
||||
s.template registerType<SetCommanderProperty>();
|
||||
s.template registerType<BlockingDialog>();
|
||||
s.template registerType<GarrisonDialog>();
|
||||
s.template registerType<BattleStart>();
|
||||
|
@@ -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();
|
||||
std::advance(it, specialSKill); //suboptimal, use bmap?
|
||||
//c->accumulateBonus(it->first);
|
||||
auto difference = [](std::vector< std::vector <ui8> > skillLevels, std::vector <ui8> secondarySkills, int skill)->int
|
||||
{
|
||||
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);
|
||||
//c->levelUp(); //change standard parameters
|
||||
}
|
||||
|
||||
void CGameHandler::levelUpCommander(const CCommanderInstance * c)
|
||||
{
|
||||
return;
|
||||
if (c->experience < VLC->heroh->reqExp (c->level + 1))
|
||||
{
|
||||
return;
|
||||
}
|
||||
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
|
||||
|
||||
int secondarySkill = -1, specialSkill = -1;
|
||||
|
||||
int skills = clu.secondarySkills.size() + clu.specialSkills.size();
|
||||
|
||||
if (skills > 1) //apply and ask for secondary skill
|
||||
for (int i = 0; i <= ECommander::SPELL_POWER; ++i)
|
||||
{
|
||||
//auto callback = boost::bind (callWith<ui16>, clu.specialSkills, boost::bind(&CGameHandler::levelUpCommander, this, c, _1), _1);
|
||||
//applyAndAsk (&clu, c->armyObj->tempOwner, callback); //call levelUpCommander when client responds
|
||||
if (c->secondarySkills[i] < ECommander::MAX_SKILL_LEVEL)
|
||||
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);
|
||||
levelUpCommander(c, secondarySkill, specialSkill);
|
||||
levelUpCommander(c, clu.skills.back());
|
||||
}
|
||||
else //apply and send info
|
||||
{
|
||||
|
@@ -182,7 +182,7 @@ public:
|
||||
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);//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 afterBattleCallback(); // called after level-ups are finished
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
Reference in New Issue
Block a user