1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-05-13 22:06:58 +02:00

Leveling up commander skills seems to be working. Optimized some png's to decrease size

This commit is contained in:
Ivan Savenko 2014-06-27 18:33:30 +03:00
parent 617ea79d3c
commit b58bbcbdd8
9 changed files with 260 additions and 186 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 KiB

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -3,6 +3,6 @@
"images" : "images" :
[ [
{ "frame" : 0, "file" : "switch-mode-normal.png"}, { "frame" : 0, "file" : "switch-mode-normal.png"},
{ "frame" : 0, "file" : "switch-mode-pressed.png"} { "frame" : 1, "file" : "switch-mode-pressed.png"}
] ]
} }

View File

@ -30,6 +30,42 @@ class CSelectableSkill;
* *
*/ */
struct StackWindowInfo
{
// helper structs
struct CommanderLevelInfo
{
std::vector<ui32> skills;
std::function<void(ui32)> callback;
};
struct StackDismissInfo
{
std::function<void()> callback;
};
struct StackUpgradeInfo
{
UpgradeInfo info;
std::function<void(CreatureID)> callback;
};
// pointers to permament objects in game state
const CCreature * creature;
const CCommanderInstance * commander;
const CStackInstance * stackNode;
const CGHeroInstance * owner;
// temporary objects which should be kept as copy if needed
boost::optional<CommanderLevelInfo> levelupInfo;
boost::optional<StackDismissInfo> dismissInfo;
boost::optional<StackUpgradeInfo> upgradeInfo;
// misc fields
unsigned int creatureCount;
bool popupWindow;
StackWindowInfo();
};
namespace namespace
{ {
namespace EStat namespace EStat
@ -101,29 +137,29 @@ void CStackWindow::CWindowSection::createStackInfo(bool showExp, bool showArt)
else else
createBackground("info-panel-0"); createBackground("info-panel-0");
new CCreaturePic(5, 41, parent->info.creature); new CCreaturePic(5, 41, parent->info->creature);
std::string visibleName; std::string visibleName;
if (parent->info.commander != nullptr) if (parent->info->commander != nullptr)
visibleName = parent->info.commander->type->nameSing; visibleName = parent->info->commander->type->nameSing;
else else
visibleName = parent->info.creature->namePl; visibleName = parent->info->creature->namePl;
new CLabel(215, 12, FONT_SMALL, CENTER, Colors::YELLOW, visibleName); new CLabel(215, 12, FONT_SMALL, CENTER, Colors::YELLOW, visibleName);
int dmgMultiply = 1; int dmgMultiply = 1;
if(parent->info.owner && parent->info.stackNode->hasBonusOfType(Bonus::SIEGE_WEAPON)) if(parent->info->owner && parent->info->stackNode->hasBonusOfType(Bonus::SIEGE_WEAPON))
dmgMultiply += parent->info.owner->Attack(); dmgMultiply += parent->info->owner->Attack();
new CPicture("stackWindow/icons", 117, 32); new CPicture("stackWindow/icons", 117, 32);
printStatBase(EStat::ATTACK, CGI->generaltexth->primarySkillNames[0], parent->info.creature->valOfBonuses(Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK), parent->info.stackNode->Attack()); printStatBase(EStat::ATTACK, CGI->generaltexth->primarySkillNames[0], parent->info->creature->valOfBonuses(Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK), parent->info->stackNode->Attack());
printStatBase(EStat::DEFENCE, CGI->generaltexth->primarySkillNames[1], parent->info.creature->valOfBonuses(Bonus::PRIMARY_SKILL, PrimarySkill::DEFENSE), parent->info.stackNode->Defense()); printStatBase(EStat::DEFENCE, CGI->generaltexth->primarySkillNames[1], parent->info->creature->valOfBonuses(Bonus::PRIMARY_SKILL, PrimarySkill::DEFENSE), parent->info->stackNode->Defense());
printStatRange(EStat::DAMAGE, CGI->generaltexth->allTexts[199], parent->info.stackNode->getMinDamage() * dmgMultiply, parent->info.stackNode->getMaxDamage() * dmgMultiply); printStatRange(EStat::DAMAGE, CGI->generaltexth->allTexts[199], parent->info->stackNode->getMinDamage() * dmgMultiply, parent->info->stackNode->getMaxDamage() * dmgMultiply);
printStatBase(EStat::HEALTH, CGI->generaltexth->allTexts[388], parent->info.creature->valOfBonuses(Bonus::STACK_HEALTH), parent->info.stackNode->valOfBonuses(Bonus::STACK_HEALTH)); printStatBase(EStat::HEALTH, CGI->generaltexth->allTexts[388], parent->info->creature->valOfBonuses(Bonus::STACK_HEALTH), parent->info->stackNode->valOfBonuses(Bonus::STACK_HEALTH));
printStatBase(EStat::SPEED, CGI->generaltexth->zelp[441].first, parent->info.creature->Speed(), parent->info.stackNode->Speed()); printStatBase(EStat::SPEED, CGI->generaltexth->zelp[441].first, parent->info->creature->Speed(), parent->info->stackNode->Speed());
const CStack * battleStack = dynamic_cast<const CStack*>(parent->info.stackNode); const CStack * battleStack = dynamic_cast<const CStack*>(parent->info->stackNode);
bool shooter = parent->info.stackNode->hasBonusOfType(Bonus::SHOOTER) && parent->info.stackNode->valOfBonuses(Bonus::SHOTS); bool shooter = parent->info->stackNode->hasBonusOfType(Bonus::SHOOTER) && parent->info->stackNode->valOfBonuses(Bonus::SHOTS);
bool caster = parent->info.stackNode->valOfBonuses(Bonus::CASTS); bool caster = parent->info->stackNode->valOfBonuses(Bonus::CASTS);
if (battleStack != nullptr) // in battle if (battleStack != nullptr) // in battle
{ {
@ -136,15 +172,15 @@ void CStackWindow::CWindowSection::createStackInfo(bool showExp, bool showArt)
else else
{ {
if (shooter) if (shooter)
printStat(EStat::SHOTS, CGI->generaltexth->allTexts[198], parent->info.stackNode->valOfBonuses(Bonus::SHOTS)); printStat(EStat::SHOTS, CGI->generaltexth->allTexts[198], parent->info->stackNode->valOfBonuses(Bonus::SHOTS));
if (caster) if (caster)
printStat(EStat::MANA, CGI->generaltexth->allTexts[399], parent->info.stackNode->valOfBonuses(Bonus::CASTS)); printStat(EStat::MANA, CGI->generaltexth->allTexts[399], parent->info->stackNode->valOfBonuses(Bonus::CASTS));
} }
auto morale = new MoraleLuckBox(true, genRect(42, 42, 321, 110)); auto morale = new MoraleLuckBox(true, genRect(42, 42, 321, 110));
morale->set(parent->info.stackNode); morale->set(parent->info->stackNode);
auto luck = new MoraleLuckBox(false, genRect(42, 42, 375, 110)); auto luck = new MoraleLuckBox(false, genRect(42, 42, 375, 110));
luck->set(parent->info.stackNode); luck->set(parent->info->stackNode);
} }
void CStackWindow::CWindowSection::createActiveSpells() void CStackWindow::CWindowSection::createActiveSpells()
@ -155,7 +191,7 @@ void CStackWindow::CWindowSection::createActiveSpells()
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJ_CONSTRUCTION_CAPTURING_ALL;
createBackground("spell-effects"); createBackground("spell-effects");
const CStack * battleStack = dynamic_cast<const CStack*>(parent->info.stackNode); const CStack * battleStack = dynamic_cast<const CStack*>(parent->info->stackNode);
assert(battleStack); // Section should be created only for battles assert(battleStack); // Section should be created only for battles
@ -191,13 +227,17 @@ void CStackWindow::CWindowSection::createCommanderSection()
{ {
delete obj; delete obj;
}; };
new CTabbedInt(onCreate, onDestroy, Point(0,0), 0); parent->commanderTab = new CTabbedInt(onCreate, onDestroy, Point(0,0), 0);
pos.w = parent->pos.w; pos.w = parent->pos.w;
pos.h = 177; //fixed height pos.h = 177; //fixed height
} }
static std::string skillToFile (int skill, int level, bool canUpgrade, bool selected) static std::string skillToFile (int skill, int level, bool selected)
{ {
// FIXME: is this a correct hadling?
// level 0 = skill not present, use image with "no" suffix
// level 1-5 = skill available, mapped to images indexed as 0-4
// selecting skill means that it will appear one level higher (as if alredy upgraded)
std::string file = "zvs/Lib1.res/_"; std::string file = "zvs/Lib1.res/_";
switch (skill) switch (skill)
{ {
@ -220,19 +260,21 @@ static std::string skillToFile (int skill, int level, bool canUpgrade, bool sele
file += "MP"; file += "MP";
break; break;
} }
std::string sufix = boost::lexical_cast<std::string>((int)level); std::string sufix;
if (selected)
level++; // UI will display resulting level
if (level == 0)
sufix = "no"; //not avaliable - no number
else
sufix = boost::lexical_cast<std::string>(level-1);
if (selected) if (selected)
sufix += "="; //level-up highlight sufix += "="; //level-up highlight
else if (canUpgrade && level == 0)
sufix = "no"; //not avaliable - no number
file += sufix + ".bmp"; return file + sufix + ".bmp";
return file;
} }
void CStackWindow::CWindowSection::createCommander() void CStackWindow::CWindowSection::createCommander()
{/* {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJ_CONSTRUCTION_CAPTURING_ALL;
createBackground("commander-bg"); createBackground("commander-bg");
@ -241,46 +283,48 @@ void CStackWindow::CWindowSection::createCommander()
return Point(10 + 80 * (index%3), 20 + 80 * (index/3)); return Point(10 + 80 * (index%3), 20 + 80 * (index/3));
}; };
for (int i = ECommander::ATTACK; i <= ECommander::SPELL_POWER; ++i) auto getSkillImage = [this](int skillIndex) -> std::string
{ {
bool haveSkill = parent->info.commander->secondarySkills[i] != 0; bool selected = ((parent->selectedSkill == skillIndex) && parent->info->levelupInfo );
bool canLevel = parent->info.levelupInfo && vstd::contains(parent->info.levelupInfo->skills, i); return skillToFile(skillIndex, parent->info->commander->secondarySkills[skillIndex], selected);
};
Point skillPos = getSkillPos(i); for (int index = ECommander::ATTACK; index <= ECommander::SPELL_POWER; ++index)
if (canLevel) {
new CPicture(skillToFile(i, parent->info.commander->secondarySkills[i], true, false), skillPos.x, skillPos.y); Point skillPos = getSkillPos(index);
if (haveSkill && !canLevel)
new CPicture(skillToFile(i, parent->info.commander->secondarySkills[i], false, false), skillPos.x, skillPos.y); auto icon = new CClickableObject(new CPicture(getSkillImage(index), skillPos.x, skillPos.y), [=]{});
if (parent->selectedSkill == index)
parent->selectedIcon = icon;
if (parent->info->levelupInfo && vstd::contains(parent->info->levelupInfo->skills, index)) // can be upgraded - enable selection switch
{
icon->callback = [=]
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
int oldSelection = parent->selectedSkill; // update selection
parent->selectedSkill = index;
if (parent->selectedIcon) // recreate image on old selection
parent->selectedIcon->setObject(new CPicture(getSkillImage(oldSelection)));
parent->selectedIcon = icon; // update new selection
icon->setObject(new CPicture(getSkillImage(index)));
};
} }
bool createAbilities = false;
if (parent->info.levelupInfo)
{
for (auto option : parent->info.levelupInfo->skills)
{
if (option < 100)
{
auto selectableSkill = new CStackWindow::CSelectableSkill();
if (option == parent->selectedSkill)
selectedIcon = selectableSkill;
selectableSkill->callback = std::bind(parent->info.levelupInfo->callback, option);
selectableSkill->pos = Rect(getSkillPos(option), Point(70, 70)); //resize
} }
else
createAbilities = true;
}
}*/
} }
void CStackWindow::CWindowSection::createCommanderAbilities() void CStackWindow::CWindowSection::createCommanderAbilities()
{/* {/*
for (auto option : parent->info.levelupInfo->skills) for (auto option : parent->info->levelupInfo->skills)
{
if (option >= 100) // this is an ability
{ {
} }
}
selectableSkill->pos = Rect (95, 256, 55, 55); //TODO: scroll selectableSkill->pos = Rect (95, 256, 55, 55); //TODO: scroll
const Bonus *b = CGI->creh->skillRequirements[option-100].first; const Bonus *b = CGI->creh->skillRequirements[option-100].first;
bonusItems.push_back (new CBonusItem (genRect(0, 0, 251, 57), stack->bonusToString(b, false), stack->bonusToString(b, true), stack->bonusToGraphics(b))); bonusItems.push_back (new CBonusItem (genRect(0, 0, 251, 57), stack->bonusToString(b, false), stack->bonusToString(b, true), stack->bonusToGraphics(b)));
@ -316,11 +360,11 @@ void CStackWindow::CWindowSection::createButtonPanel()
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJ_CONSTRUCTION_CAPTURING_ALL;
createBackground("button-panel"); createBackground("button-panel");
if (parent->info.dismissInfo) if (parent->info->dismissInfo)
{ {
auto onDismiss = [=]() auto onDismiss = [=]()
{ {
parent->info.dismissInfo->callback(); parent->info->dismissInfo->callback();
parent->close(); parent->close();
}; };
auto onClick = [=] () auto onClick = [=] ()
@ -329,18 +373,18 @@ void CStackWindow::CWindowSection::createButtonPanel()
}; };
new CAdventureMapButton(CGI->generaltexth->zelp[445], onClick, 5, 5,"IVIEWCR2.DEF",SDLK_d); new CAdventureMapButton(CGI->generaltexth->zelp[445], onClick, 5, 5,"IVIEWCR2.DEF",SDLK_d);
} }
if (parent->info.upgradeInfo) if (parent->info->upgradeInfo)
{ {
// used space overlaps with commander switch button // used space overlaps with commander switch button
// besides - should commander really be upgradeable? // besides - should commander really be upgradeable?
assert(!parent->info.commander); assert(!parent->info->commander);
StackWindowInfo::StackUpgradeInfo & upgradeInfo = parent->info.upgradeInfo.get(); StackWindowInfo::StackUpgradeInfo & upgradeInfo = parent->info->upgradeInfo.get();
size_t buttonsToCreate = std::min<size_t>(upgradeInfo.info.newID.size(), 3); // no more than 3 windows on UI - space limit size_t buttonsToCreate = std::min<size_t>(upgradeInfo.info.newID.size(), 3); // no more than 3 windows on UI - space limit
for (size_t i=0; i<buttonsToCreate; i++) for (size_t i=0; i<buttonsToCreate; i++)
{ {
TResources totalCost = upgradeInfo.info.cost[i] * parent->info.creatureCount; TResources totalCost = upgradeInfo.info.cost[i] * parent->info->creatureCount;
auto onUpgrade = [=]() auto onUpgrade = [=]()
{ {
@ -365,17 +409,35 @@ void CStackWindow::CWindowSection::createButtonPanel()
} }
} }
if (parent->info.commander) if (parent->info->commander)
{ {
//TODO: replace with 3 buttons, using upgrade button as base + sec skill image: bool createAbilitiesTab = false;
// 0) Switch to commander skills: Basic Offence if (parent->info->levelupInfo)
// 1) Switch to upgradable skills: Advanced mysticism (level-up only)
// 2) Switch to bonuses view: Basic Sorcery
auto onSwitch = [=]()
{ {
parent->commanderTab->setActive(parent->activeTab == 0 ? 1 : 0); for (auto option : parent->info->levelupInfo->skills)
{
if (option >= 100)
createAbilitiesTab = true;
}
}
for (size_t i=0; i<3; i++)
{
auto onSwitch = [&, i]()
{
parent->switchButtons[parent->activeTab]->enable();
parent->commanderTab->setActive(i);
parent->switchButtons[i]->disable();
parent->redraw(); // FIXME: enable/disable don't redraw screen themselves
}; };
new CAdventureMapButton(std::make_pair("switch to commander", "help box"), onSwitch, 280, 5, "stackWindow/commanderToggle", SDLK_TAB);
parent->switchButtons[i] = new CAdventureMapButton(std::make_pair("",""), onSwitch, 262 + i*40, 5, "stackWindow/upgradeButton", SDLK_1 + i);
parent->switchButtons[i]->addOverlay(new CAnimImage("stackWindow/switchModeIcons", i));
}
parent->switchButtons[parent->activeTab]->disable();
if (!createAbilitiesTab)
parent->switchButtons[2]->disable();
} }
auto exitBtn = new CAdventureMapButton(CGI->generaltexth->zelp[445], [=]{ parent->close(); }, 382, 5, "hsbtns.def", SDLK_RETURN); auto exitBtn = new CAdventureMapButton(CGI->generaltexth->zelp[445], [=]{ parent->close(); }, 382, 5, "hsbtns.def", SDLK_RETURN);
@ -387,7 +449,24 @@ CStackWindow::CWindowSection::CWindowSection(CStackWindow * parent):
{ {
} }
void CStackWindow::CSelectableSkill::clickLeft(tribool down, bool previousState) CClickableObject::CClickableObject(CIntObject *object, std::function<void()> callback):
object(nullptr),
callback(callback)
{
pos = object->pos;
setObject(object);
}
void CClickableObject::setObject(CIntObject *newObject)
{
delete object;
object = newObject;
addChild(object);
object->moveTo(pos.topLeft());
redraw();
}
void CClickableObject::clickLeft(tribool down, bool previousState)
{ {
if (down) if (down)
callback(); callback();
@ -427,7 +506,7 @@ CIntObject * CStackWindow::switchTab(size_t index)
{ {
activeTab = 0; activeTab = 0;
auto ret = new CWindowSection(this); auto ret = new CWindowSection(this);
ret->createCommanderSection(); ret->createCommander();
return ret; return ret;
} }
case 1: case 1:
@ -456,28 +535,28 @@ void CStackWindow::initSections()
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJ_CONSTRUCTION_CAPTURING_ALL;
CWindowSection * currentSection; CWindowSection * currentSection;
bool showArt = CGI->modh->modules.STACK_ARTIFACT && info.commander == nullptr; bool showArt = CGI->modh->modules.STACK_ARTIFACT && info->commander == nullptr;
bool showExp = CGI->modh->modules.STACK_EXP || info.commander != nullptr; bool showExp = CGI->modh->modules.STACK_EXP || info->commander != nullptr;
currentSection = new CWindowSection(this); currentSection = new CWindowSection(this);
currentSection->createStackInfo(showExp, showArt); currentSection->createStackInfo(showExp, showArt);
pos.w = currentSection->pos.w; pos.w = currentSection->pos.w;
pos.h += currentSection->pos.h; pos.h += currentSection->pos.h;
if (dynamic_cast<const CStack*>(info.stackNode)) // in battle if (dynamic_cast<const CStack*>(info->stackNode)) // in battle
{ {
currentSection = new CWindowSection(this); currentSection = new CWindowSection(this);
currentSection->pos.y += pos.h; currentSection->pos.y += pos.h;
currentSection->createActiveSpells(); currentSection->createActiveSpells();
pos.h += currentSection->pos.h; pos.h += currentSection->pos.h;
} }
if (info.commander) if (info->commander)
{ {
currentSection = new CWindowSection(this); currentSection = new CWindowSection(this);
currentSection->pos.y += pos.h; currentSection->pos.y += pos.h;
currentSection->createCommanderSection(); currentSection->createCommanderSection();
pos.h += currentSection->pos.h; pos.h += currentSection->pos.h;
} }
if (!info.commander && !activeBonuses.empty()) if (!info->commander && !activeBonuses.empty())
{ {
currentSection = new CWindowSection(this); currentSection = new CWindowSection(this);
currentSection->pos.y += pos.h; currentSection->pos.y += pos.h;
@ -485,12 +564,13 @@ void CStackWindow::initSections()
pos.h += currentSection->pos.h; pos.h += currentSection->pos.h;
} }
if (!info.popupWindow) if (!info->popupWindow)
{ {
currentSection = new CWindowSection(this); currentSection = new CWindowSection(this);
currentSection->pos.y += pos.h; currentSection->pos.y += pos.h;
currentSection->createButtonPanel(); currentSection->createButtonPanel();
pos.h += currentSection->pos.h; pos.h += currentSection->pos.h;
//FIXME: add status bar to image?
} }
updateShadow(); updateShadow();
pos = center(pos); pos = center(pos);
@ -499,7 +579,7 @@ void CStackWindow::initSections()
void CStackWindow::initBonusesList() void CStackWindow::initBonusesList()
{ {
BonusList output, input; BonusList output, input;
input = *(info.stackNode->getBonuses(Selector::durationType(Bonus::PERMANENT).And(Selector::anyRange()))); input = *(info->stackNode->getBonuses(Selector::durationType(Bonus::PERMANENT).And(Selector::anyRange())));
while (!input.empty()) while (!input.empty())
{ {
@ -513,8 +593,8 @@ void CStackWindow::initBonusesList()
BonusInfo bonusInfo; BonusInfo bonusInfo;
for(Bonus* b : output) for(Bonus* b : output)
{ {
bonusInfo.name = info.stackNode->bonusToString(b, false); bonusInfo.name = info->stackNode->bonusToString(b, false);
bonusInfo.imagePath = info.stackNode->bonusToGraphics(b); bonusInfo.imagePath = info->stackNode->bonusToGraphics(b);
//if it's possible to give any description or image for this kind of bonus //if it's possible to give any description or image for this kind of bonus
//TODO: figure out why half of bonuses don't have proper description //TODO: figure out why half of bonuses don't have proper description
@ -523,7 +603,7 @@ void CStackWindow::initBonusesList()
} }
//handle Magic resistance separately :/ //handle Magic resistance separately :/
int magicResistance = info.stackNode->magicResistance(); int magicResistance = info->stackNode->magicResistance();
if (magicResistance) if (magicResistance)
{ {
@ -531,9 +611,9 @@ void CStackWindow::initBonusesList()
Bonus b; Bonus b;
b.type = Bonus::MAGIC_RESISTANCE; b.type = Bonus::MAGIC_RESISTANCE;
bonusInfo.name = VLC->getBth()->bonusToString(&b, info.stackNode, false); bonusInfo.name = VLC->getBth()->bonusToString(&b, info->stackNode, false);
bonusInfo.description = VLC->getBth()->bonusToString(&b, info.stackNode, true); bonusInfo.description = VLC->getBth()->bonusToString(&b, info->stackNode, true);
bonusInfo.imagePath = info.stackNode->bonusToGraphics(&b); bonusInfo.imagePath = info->stackNode->bonusToGraphics(&b);
activeBonuses.push_back(bonusInfo); activeBonuses.push_back(bonusInfo);
} }
} }
@ -542,8 +622,8 @@ void CStackWindow::init()
{ {
selectedIcon = nullptr; selectedIcon = nullptr;
selectedSkill = 0; selectedSkill = 0;
if (info.levelupInfo) if (info->levelupInfo)
selectedSkill = info.levelupInfo->skills.front(); selectedSkill = info->levelupInfo->skills.front();
commanderTab = nullptr; commanderTab = nullptr;
activeTab = 0; activeTab = 0;
@ -555,64 +635,80 @@ void CStackWindow::init()
CStackWindow::CStackWindow(const CStack * stack, bool popup): CStackWindow::CStackWindow(const CStack * stack, bool popup):
CWindowObject(BORDERED | (popup ? RCLICK_POPUP : 0)) CWindowObject(BORDERED | (popup ? RCLICK_POPUP : 0))
{ {
info.stackNode = stack->base; info->stackNode = stack->base;
info.creature = stack->type; info->creature = stack->type;
info.creatureCount = stack->count; info->creatureCount = stack->count;
info.popupWindow = popup; info->popupWindow = popup;
init(); init();
} }
CStackWindow::CStackWindow(const CCreature * creature, bool popup): CStackWindow::CStackWindow(const CCreature * creature, bool popup):
CWindowObject(BORDERED | (popup ? RCLICK_POPUP : 0)) CWindowObject(BORDERED | (popup ? RCLICK_POPUP : 0)),
info(new StackWindowInfo())
{ {
info.stackNode = new CStackInstance(creature, 1); // FIXME: free data info->stackNode = new CStackInstance(creature, 1); // FIXME: free data
info.creature = creature; info->creature = creature;
info.popupWindow = popup; info->popupWindow = popup;
init(); init();
} }
CStackWindow::CStackWindow(const CStackInstance * stack, bool popup): CStackWindow::CStackWindow(const CStackInstance * stack, bool popup):
CWindowObject(BORDERED | (popup ? RCLICK_POPUP : 0)) CWindowObject(BORDERED | (popup ? RCLICK_POPUP : 0)),
info(new StackWindowInfo())
{ {
info.stackNode = stack; info->stackNode = stack;
info.creature = stack->type; info->creature = stack->type;
info.creatureCount = stack->count; info->creatureCount = stack->count;
info.popupWindow = popup; info->popupWindow = popup;
init(); init();
} }
CStackWindow::CStackWindow(const CStackInstance * stack, std::function<void()> dismiss, const UpgradeInfo & upgradeInfo, std::function<void(CreatureID)> callback): CStackWindow::CStackWindow(const CStackInstance * stack, std::function<void()> dismiss, const UpgradeInfo & upgradeInfo, std::function<void(CreatureID)> callback):
CWindowObject(BORDERED) CWindowObject(BORDERED),
info(new StackWindowInfo())
{ {
info.stackNode = stack; info->stackNode = stack;
info.creature = stack->type; info->creature = stack->type;
info.creatureCount = stack->count; info->creatureCount = stack->count;
info.upgradeInfo = StackWindowInfo::StackUpgradeInfo(); info->upgradeInfo = StackWindowInfo::StackUpgradeInfo();
info.dismissInfo = StackWindowInfo::StackDismissInfo(); info->dismissInfo = StackWindowInfo::StackDismissInfo();
info.upgradeInfo->info = upgradeInfo; info->upgradeInfo->info = upgradeInfo;
info.upgradeInfo->callback = callback; info->upgradeInfo->callback = callback;
info.dismissInfo->callback = dismiss; info->dismissInfo->callback = dismiss;
init(); init();
} }
CStackWindow::CStackWindow(const CCommanderInstance * commander, bool popup): CStackWindow::CStackWindow(const CCommanderInstance * commander, bool popup):
CWindowObject(BORDERED | (popup ? RCLICK_POPUP : 0)) CWindowObject(BORDERED | (popup ? RCLICK_POPUP : 0)),
info(new StackWindowInfo())
{ {
info.stackNode = commander; info->stackNode = commander;
info.creature = commander->type; info->creature = commander->type;
info.commander = commander; info->commander = commander;
info.creatureCount = 1; info->creatureCount = 1;
info.popupWindow = popup; info->popupWindow = popup;
init(); init();
} }
CStackWindow::CStackWindow(const CCommanderInstance * commander, std::vector<ui32> &skills, std::function<void(ui32)> callback): CStackWindow::CStackWindow(const CCommanderInstance * commander, std::vector<ui32> &skills, std::function<void(ui32)> callback):
CWindowObject(BORDERED) CWindowObject(BORDERED),
info(new StackWindowInfo())
{ {
info.stackNode = commander; info->stackNode = commander;
info.creature = commander->type; info->creature = commander->type;
info.commander = commander; info->commander = commander;
info.creatureCount = 1; info->creatureCount = 1;
info->levelupInfo = StackWindowInfo::CommanderLevelInfo();
info->levelupInfo->skills = skills;
info->levelupInfo->callback = callback;
init(); init();
} }
CStackWindow::~CStackWindow()
{
if (info->levelupInfo)
{
info->levelupInfo->callback(selectedSkill);
}
}

View File

@ -2,7 +2,6 @@
#include "gui/CIntObjectClasses.h" #include "gui/CIntObjectClasses.h"
#include "../lib/HeroBonus.h" #include "../lib/HeroBonus.h"
#include "../lib/CGameState.h"
/* /*
* CCreatureWindow.h, part of VCMI engine * CCreatureWindow.h, part of VCMI engine
@ -14,40 +13,24 @@
* *
*/ */
struct StackWindowInfo class StackWindowInfo;
{ class CCommanderInstance;
// helper structs class CStackInstance;
struct CommanderLevelInfo class CStack;
{ struct UpgradeInfo;
std::vector<ui32> skills;
std::function<void(ui32)> callback;
};
struct StackDismissInfo
{
std::function<void()> callback;
};
struct StackUpgradeInfo
{
UpgradeInfo info;
std::function<void(CreatureID)> callback;
};
// pointers to permament objects in game state class CClickableObject : public LRClickableAreaWText
const CCreature * creature; {
const CCommanderInstance * commander; CIntObject * object; // passive object that will be used to determine clickable area
const CStackInstance * stackNode; public:
const CGHeroInstance * owner; CClickableObject(CIntObject * object, std::function<void()> callback);
// temporary objects which should be kept as copy if needed std::function<void()> callback; //TODO: create more generic clickable class than AdvMapButton?
boost::optional<CommanderLevelInfo> levelupInfo;
boost::optional<StackDismissInfo> dismissInfo;
boost::optional<StackUpgradeInfo> upgradeInfo;
// misc fields void clickLeft(tribool down, bool previousState);
unsigned int creatureCount; void clickRight(tribool down, bool previousState){};
bool popupWindow;
StackWindowInfo(); void setObject(CIntObject * object);
}; };
class CStackWindow : public CWindowObject class CStackWindow : public CWindowObject
@ -59,15 +42,6 @@ class CStackWindow : public CWindowObject
std::string imagePath; std::string imagePath;
}; };
class CSelectableSkill : public LRClickableAreaWText
{
public:
std::function<void()> callback; //TODO: create more generic clickable class than AdvMapButton?
void clickLeft(tribool down, bool previousState);
void clickRight(tribool down, bool previousState){};
};
class CWindowSection : public CIntObject class CWindowSection : public CIntObject
{ {
CStackWindow * parent; CStackWindow * parent;
@ -94,12 +68,14 @@ class CStackWindow : public CWindowObject
CWindowSection(CStackWindow * parent); CWindowSection(CStackWindow * parent);
}; };
StackWindowInfo info; std::unique_ptr<StackWindowInfo> info;
std::vector<BonusInfo> activeBonuses; std::vector<BonusInfo> activeBonuses;
size_t activeTab; size_t activeTab;
CTabbedInt * commanderTab; CTabbedInt * commanderTab;
CSelectableSkill * selectedIcon; std::map<int, CAdventureMapButton *> switchButtons;
CClickableObject * selectedIcon;
si32 selectedSkill; si32 selectedSkill;
CIntObject * createBonusEntry(size_t index); CIntObject * createBonusEntry(size_t index);
@ -124,4 +100,6 @@ public:
// for commanders & commander level-up dialog // for commanders & commander level-up dialog
CStackWindow(const CCommanderInstance * commander, bool popup); CStackWindow(const CCommanderInstance * commander, bool popup);
CStackWindow(const CCommanderInstance * commander, std::vector<ui32> &skills, std::function<void(ui32)> callback); CStackWindow(const CCommanderInstance * commander, std::vector<ui32> &skills, std::function<void(ui32)> callback);
~CStackWindow();
}; };

View File

@ -328,7 +328,7 @@ void CHeroWindow::commanderWindow()
} }
} }
else else
GH.pushInt(new CStackWindow(curHero->commander, true)); GH.pushInt(new CStackWindow(curHero->commander, false));
} }