New creature window made without use of H3 graphics
This is import of ancient unfinished branch from svn. As of now window is largely finished but commander-related elements are still TODO. Note that I also uploading graphical content - this is intended and necessary for final goal - to make VCMI functional without any additional graphical pack.
BIN
Mods/vcmi/Data/stackWindow/bonus-effects.png
Normal file
After Width: | Height: | Size: 29 KiB |
BIN
Mods/vcmi/Data/stackWindow/button-panel.png
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
Mods/vcmi/Data/stackWindow/commander-bg.png
Normal file
After Width: | Height: | Size: 97 KiB |
BIN
Mods/vcmi/Data/stackWindow/icons.png
Normal file
After Width: | Height: | Size: 4.0 KiB |
BIN
Mods/vcmi/Data/stackWindow/info-panel-0.png
Normal file
After Width: | Height: | Size: 94 KiB |
BIN
Mods/vcmi/Data/stackWindow/info-panel-1.png
Normal file
After Width: | Height: | Size: 92 KiB |
BIN
Mods/vcmi/Data/stackWindow/info-panel-2.png
Normal file
After Width: | Height: | Size: 89 KiB |
BIN
Mods/vcmi/Data/stackWindow/spell-effects.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
Mods/vcmi/Sprites/stackWindow/level-0.png
Normal file
After Width: | Height: | Size: 182 B |
BIN
Mods/vcmi/Sprites/stackWindow/level-1.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
Mods/vcmi/Sprites/stackWindow/level-10.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
Mods/vcmi/Sprites/stackWindow/level-2.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
Mods/vcmi/Sprites/stackWindow/level-3.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
Mods/vcmi/Sprites/stackWindow/level-4.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
Mods/vcmi/Sprites/stackWindow/level-5.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
Mods/vcmi/Sprites/stackWindow/level-6.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
Mods/vcmi/Sprites/stackWindow/level-7.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
Mods/vcmi/Sprites/stackWindow/level-8.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
Mods/vcmi/Sprites/stackWindow/level-9.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
17
Mods/vcmi/Sprites/stackWindow/levels.json
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"basepath" : "stackWindow/",
|
||||||
|
"images" :
|
||||||
|
[
|
||||||
|
{ "frame" : 0, "file" : "level-0.png"},
|
||||||
|
{ "frame" : 1, "file" : "level-1.png"},
|
||||||
|
{ "frame" : 2, "file" : "level-2.png"},
|
||||||
|
{ "frame" : 3, "file" : "level-3.png"},
|
||||||
|
{ "frame" : 4, "file" : "level-4.png"},
|
||||||
|
{ "frame" : 5, "file" : "level-5.png"},
|
||||||
|
{ "frame" : 6, "file" : "level-6.png"},
|
||||||
|
{ "frame" : 7, "file" : "level-7.png"},
|
||||||
|
{ "frame" : 8, "file" : "level-8.png"},
|
||||||
|
{ "frame" : 9, "file" : "level-9.png"},
|
||||||
|
{ "frame" : 10,"file" : "level-10.png"}
|
||||||
|
]
|
||||||
|
}
|
8
Mods/vcmi/Sprites/stackWindow/switch-mode-button.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"basepath" : "stackWindow/",
|
||||||
|
"images" :
|
||||||
|
[
|
||||||
|
{ "frame" : 0, "file" : "switch-mode-normal.png"},
|
||||||
|
{ "frame" : 0, "file" : "switch-mode-pressed.png"}
|
||||||
|
]
|
||||||
|
}
|
BIN
Mods/vcmi/Sprites/stackWindow/switch-mode-normal.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
Mods/vcmi/Sprites/stackWindow/switch-mode-pressed.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
8
Mods/vcmi/Sprites/stackWindow/switchModeIcons.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"images" :
|
||||||
|
[
|
||||||
|
{ "frame" : 0, "file" : "SECSK32:69"},
|
||||||
|
{ "frame" : 1, "file" : "SECSK32:28"},
|
||||||
|
{ "frame" : 2, "file" : "SECSK32:78"}
|
||||||
|
]
|
||||||
|
}
|
BIN
Mods/vcmi/Sprites/stackWindow/upgrade-normal.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
Mods/vcmi/Sprites/stackWindow/upgrade-pressed.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
8
Mods/vcmi/Sprites/stackWindow/upgradeButton.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"basepath" : "stackWindow/",
|
||||||
|
"images" :
|
||||||
|
[
|
||||||
|
{ "frame" : 0, "file" : "stackWindow/upgrade-normal.png"},
|
||||||
|
{ "frame" : 1, "file" : "stackWindow/upgrade-pressed.png"}
|
||||||
|
]
|
||||||
|
}
|
@ -1,28 +1,16 @@
|
|||||||
#include "StdInc.h"
|
#include "StdInc.h"
|
||||||
#include "CCreatureWindow.h"
|
#include "CCreatureWindow.h"
|
||||||
|
|
||||||
#include "../lib/CCreatureSet.h"
|
|
||||||
#include "CGameInfo.h"
|
#include "CGameInfo.h"
|
||||||
#include "../lib/CGeneralTextHandler.h"
|
|
||||||
#include "../lib/BattleState.h"
|
|
||||||
#include "../CCallback.h"
|
|
||||||
|
|
||||||
#include <SDL.h>
|
|
||||||
#include "gui/SDL_Extensions.h"
|
|
||||||
#include "CBitmapHandler.h"
|
|
||||||
#include "CDefHandler.h"
|
|
||||||
#include "Graphics.h"
|
|
||||||
#include "CPlayerInterface.h"
|
#include "CPlayerInterface.h"
|
||||||
#include "../lib/CConfigHandler.h"
|
#include "GUIClasses.h"
|
||||||
#include "CAnimation.h"
|
|
||||||
|
|
||||||
#include "../lib/CGameState.h"
|
#include "../CCallback.h"
|
||||||
#include "../lib/BattleState.h"
|
#include "../lib/BattleState.h"
|
||||||
#include "../lib/CSpellHandler.h"
|
#include "../lib/CBonusTypeHandler.h"
|
||||||
#include "../lib/CArtHandler.h"
|
#include "../lib/CGeneralTextHandler.h"
|
||||||
#include "../lib/NetPacksBase.h" //ArtifactLocation
|
|
||||||
#include "../lib/CModHandler.h"
|
#include "../lib/CModHandler.h"
|
||||||
#include "../lib/IBonusTypeHandler.h"
|
#include "../lib/CSpellHandler.h"
|
||||||
|
|
||||||
#include "gui/CGuiHandler.h"
|
#include "gui/CGuiHandler.h"
|
||||||
#include "gui/CIntObjectClasses.h"
|
#include "gui/CIntObjectClasses.h"
|
||||||
@ -42,6 +30,595 @@ class CSelectableSkill;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
namespace EStat
|
||||||
|
{
|
||||||
|
enum EStat
|
||||||
|
{
|
||||||
|
ATTACK,
|
||||||
|
DEFENCE,
|
||||||
|
SHOTS,
|
||||||
|
DAMAGE,
|
||||||
|
HEALTH,
|
||||||
|
HEALTH_LEFT,
|
||||||
|
SPEED,
|
||||||
|
MANA
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StackWindowInfo::StackWindowInfo():
|
||||||
|
creature(nullptr),
|
||||||
|
commander(nullptr),
|
||||||
|
stackNode(nullptr),
|
||||||
|
owner(nullptr),
|
||||||
|
creatureCount(0),
|
||||||
|
popupWindow(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CStackWindow::CWindowSection::createBackground(std::string path)
|
||||||
|
{
|
||||||
|
background = new CPicture("stackWindow/" + path);
|
||||||
|
pos = background->pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CStackWindow::CWindowSection::printStatString(int index, std::string name, std::string value)
|
||||||
|
{
|
||||||
|
new CLabel(145, 32 + index*19, FONT_SMALL, TOPLEFT, Colors::WHITE, name);
|
||||||
|
new CLabel(307, 48 + index*19, FONT_SMALL, BOTTOMRIGHT, Colors::WHITE, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CStackWindow::CWindowSection::printStatRange(int index, std::string name, int min, int max)
|
||||||
|
{
|
||||||
|
if(min != max)
|
||||||
|
printStatString(index, name, boost::str(boost::format("%d - %d") % min % max));
|
||||||
|
else
|
||||||
|
printStatString(index, name, boost::str(boost::format("%d") % min));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CStackWindow::CWindowSection::printStatBase(int index, std::string name, int base, int current)
|
||||||
|
{
|
||||||
|
if(base != current)
|
||||||
|
printStatString(index, name, boost::str(boost::format("%d (%d)") % base % current));
|
||||||
|
else
|
||||||
|
printStatString(index, name, boost::str(boost::format("%d") % base));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CStackWindow::CWindowSection::printStat(int index, std::string name, int value)
|
||||||
|
{
|
||||||
|
printStatBase(index, name, value, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CStackWindow::CWindowSection::createStackInfo(bool showExp, bool showArt)
|
||||||
|
{
|
||||||
|
OBJ_CONSTRUCTION_CAPTURING_ALL;
|
||||||
|
if (showExp && showArt)
|
||||||
|
createBackground("info-panel-2");
|
||||||
|
else if (showExp || showArt)
|
||||||
|
createBackground("info-panel-1");
|
||||||
|
else
|
||||||
|
createBackground("info-panel-0");
|
||||||
|
|
||||||
|
new CCreaturePic(5, 41, parent->info.creature);
|
||||||
|
|
||||||
|
std::string visibleName;
|
||||||
|
if (parent->info.commander != nullptr)
|
||||||
|
visibleName = parent->info.commander->type->nameSing;
|
||||||
|
else
|
||||||
|
visibleName = parent->info.creature->namePl;
|
||||||
|
new CLabel(215, 12, FONT_SMALL, CENTER, Colors::YELLOW, visibleName);
|
||||||
|
|
||||||
|
//TODO
|
||||||
|
int dmgMultiply = 1;
|
||||||
|
if(parent->info.owner && parent->info.stackNode->hasBonusOfType(Bonus::SIEGE_WEAPON))
|
||||||
|
dmgMultiply += parent->info.owner->Attack();
|
||||||
|
|
||||||
|
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::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);
|
||||||
|
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());
|
||||||
|
|
||||||
|
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 caster = parent->info.stackNode->valOfBonuses(Bonus::CASTS);
|
||||||
|
|
||||||
|
if (battleStack != nullptr) // in battle
|
||||||
|
{
|
||||||
|
if (shooter)
|
||||||
|
printStatBase(EStat::SHOTS, CGI->generaltexth->allTexts[198], battleStack->valOfBonuses(Bonus::SHOTS), battleStack->shots);
|
||||||
|
if (caster)
|
||||||
|
printStatBase(EStat::MANA, CGI->generaltexth->allTexts[399], battleStack->valOfBonuses(Bonus::CASTS), battleStack->casts);
|
||||||
|
printStat(EStat::HEALTH_LEFT, CGI->generaltexth->allTexts[200], battleStack->firstHPleft);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (shooter)
|
||||||
|
printStat(EStat::SHOTS, CGI->generaltexth->allTexts[198], parent->info.stackNode->valOfBonuses(Bonus::SHOTS));
|
||||||
|
if (caster)
|
||||||
|
printStat(EStat::MANA, CGI->generaltexth->allTexts[399], parent->info.stackNode->valOfBonuses(Bonus::CASTS));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto morale = new MoraleLuckBox(true, genRect(42, 42, 321, 110));
|
||||||
|
morale->set(parent->info.stackNode);
|
||||||
|
auto luck = new MoraleLuckBox(false, genRect(42, 42, 375, 110));
|
||||||
|
luck->set(parent->info.stackNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CStackWindow::CWindowSection::createActiveSpells()
|
||||||
|
{
|
||||||
|
static const Point firstPos(7 ,4); // position of 1st spell box
|
||||||
|
static const Point offset(54, 0); // offset of each spell box from previous
|
||||||
|
|
||||||
|
OBJ_CONSTRUCTION_CAPTURING_ALL;
|
||||||
|
createBackground("spell-effects");
|
||||||
|
|
||||||
|
const CStack * battleStack = dynamic_cast<const CStack*>(parent->info.stackNode);
|
||||||
|
|
||||||
|
assert(battleStack); // Section should be created only for battles
|
||||||
|
|
||||||
|
//spell effects
|
||||||
|
int printed=0; //how many effect pics have been printed
|
||||||
|
std::vector<si32> spells = battleStack->activeSpells();
|
||||||
|
for(si32 effect : spells)
|
||||||
|
{
|
||||||
|
std::string spellText;
|
||||||
|
if (effect < 77) //not all effects have graphics (for eg. Acid Breath)
|
||||||
|
{
|
||||||
|
spellText = CGI->generaltexth->allTexts[610]; //"%s, duration: %d rounds."
|
||||||
|
boost::replace_first (spellText, "%s", CGI->spellh->objects[effect]->name);
|
||||||
|
int duration = battleStack->getBonusLocalFirst(Selector::source(Bonus::SPELL_EFFECT,effect))->turnsRemain;
|
||||||
|
boost::replace_first (spellText, "%d", boost::lexical_cast<std::string>(duration));
|
||||||
|
|
||||||
|
new CAnimImage("SpellInt", effect + 1, 0, firstPos.x + offset.x * printed, firstPos.x + offset.y * printed);
|
||||||
|
new LRClickableAreaWText(Rect(firstPos + offset * printed, Point(50, 38)), spellText, spellText);
|
||||||
|
if (++printed >= 8) // interface limit reached
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CStackWindow::CWindowSection::createCommanderSection()
|
||||||
|
{
|
||||||
|
OBJ_CONSTRUCTION_CAPTURING_ALL;
|
||||||
|
auto onCreate = [=](size_t index) -> CIntObject *
|
||||||
|
{
|
||||||
|
return parent->switchTab(index);
|
||||||
|
};
|
||||||
|
auto onDestroy = [=](CIntObject * obj)
|
||||||
|
{
|
||||||
|
delete obj;
|
||||||
|
};
|
||||||
|
new CTabbedInt(onCreate, onDestroy, Point(0,0), 0);
|
||||||
|
pos.w = parent->pos.w;
|
||||||
|
pos.h = 177; //fixed height
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string skillToFile (int skill, int level, bool canUpgrade, bool selected)
|
||||||
|
{
|
||||||
|
std::string file = "zvs/Lib1.res/_";
|
||||||
|
switch (skill)
|
||||||
|
{
|
||||||
|
case ECommander::ATTACK:
|
||||||
|
file += "AT";
|
||||||
|
break;
|
||||||
|
case ECommander::DEFENSE:
|
||||||
|
file += "DF";
|
||||||
|
break;
|
||||||
|
case ECommander::HEALTH:
|
||||||
|
file += "HP";
|
||||||
|
break;
|
||||||
|
case ECommander::DAMAGE:
|
||||||
|
file += "DM";
|
||||||
|
break;
|
||||||
|
case ECommander::SPEED:
|
||||||
|
file += "SP";
|
||||||
|
break;
|
||||||
|
case ECommander::SPELL_POWER:
|
||||||
|
file += "MP";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
std::string sufix = boost::lexical_cast<std::string>((int)level);
|
||||||
|
if (selected)
|
||||||
|
sufix += "="; //level-up highlight
|
||||||
|
else if (canUpgrade && level == 0)
|
||||||
|
sufix = "no"; //not avaliable - no number
|
||||||
|
|
||||||
|
file += sufix + ".bmp";
|
||||||
|
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CStackWindow::CWindowSection::createCommander()
|
||||||
|
{/*
|
||||||
|
OBJ_CONSTRUCTION_CAPTURING_ALL;
|
||||||
|
createBackground("commander-bg");
|
||||||
|
|
||||||
|
auto getSkillPos = [&](int index)
|
||||||
|
{
|
||||||
|
return Point(10 + 80 * (index%3), 20 + 80 * (index/3));
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int i = ECommander::ATTACK; i <= ECommander::SPELL_POWER; ++i)
|
||||||
|
{
|
||||||
|
bool haveSkill = parent->info.commander->secondarySkills[i] != 0;
|
||||||
|
bool canLevel = parent->info.levelupInfo && vstd::contains(parent->info.levelupInfo->skills, i);
|
||||||
|
|
||||||
|
Point skillPos = getSkillPos(i);
|
||||||
|
if (canLevel)
|
||||||
|
new CPicture(skillToFile(i, parent->info.commander->secondarySkills[i], true, false), skillPos.x, skillPos.y);
|
||||||
|
if (haveSkill && !canLevel)
|
||||||
|
new CPicture(skillToFile(i, parent->info.commander->secondarySkills[i], false, false), skillPos.x, skillPos.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
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()
|
||||||
|
{/*
|
||||||
|
for (auto option : parent->info.levelupInfo->skills)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
selectableSkill->pos = Rect (95, 256, 55, 55); //TODO: scroll
|
||||||
|
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)));
|
||||||
|
selectableBonuses.push_back (selectableSkill); //insert these before other bonuses
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void CStackWindow::CWindowSection::createBonuses(boost::optional<size_t> preferredSize)
|
||||||
|
{
|
||||||
|
// size of single image for an item
|
||||||
|
static const int itemHeight = 59;
|
||||||
|
OBJ_CONSTRUCTION_CAPTURING_ALL;
|
||||||
|
size_t totalSize = (parent->activeBonuses.size() + 1) / 2;
|
||||||
|
size_t visibleSize = preferredSize ? preferredSize.get() : std::min<size_t>(3, totalSize);
|
||||||
|
|
||||||
|
pos.w = parent->pos.w;
|
||||||
|
pos.h = itemHeight * visibleSize;
|
||||||
|
|
||||||
|
auto onCreate = [=](size_t index) -> CIntObject *
|
||||||
|
{
|
||||||
|
return parent->createBonusEntry(index);
|
||||||
|
};
|
||||||
|
auto onDestroy = [=](CIntObject * obj)
|
||||||
|
{
|
||||||
|
delete obj;
|
||||||
|
};
|
||||||
|
new CListBox(onCreate, onDestroy, Point(0, 0), Point(0, itemHeight), visibleSize, totalSize, 0, 1, Rect(pos.w - 15, 0, pos.h, pos.h));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CStackWindow::CWindowSection::createButtonPanel()
|
||||||
|
{
|
||||||
|
//TODO: localization, place creature icon on button, proper path to animation-button
|
||||||
|
OBJ_CONSTRUCTION_CAPTURING_ALL;
|
||||||
|
createBackground("button-panel");
|
||||||
|
|
||||||
|
if (parent->info.dismissInfo)
|
||||||
|
{
|
||||||
|
auto onDismiss = [=]()
|
||||||
|
{
|
||||||
|
parent->info.dismissInfo->callback();
|
||||||
|
parent->close();
|
||||||
|
};
|
||||||
|
auto onClick = [=] ()
|
||||||
|
{
|
||||||
|
LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[12], onDismiss, 0, false, std::vector<CComponent*>());
|
||||||
|
};
|
||||||
|
new CAdventureMapButton(CGI->generaltexth->zelp[445], onClick, 5, 5,"IVIEWCR2.DEF",SDLK_d);
|
||||||
|
}
|
||||||
|
if (parent->info.upgradeInfo)
|
||||||
|
{
|
||||||
|
// used space overlaps with commander switch button
|
||||||
|
// besides - should commander really be upgradeable?
|
||||||
|
assert(!parent->info.commander);
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
for (size_t i=0; i<buttonsToCreate; i++)
|
||||||
|
{
|
||||||
|
TResources totalCost = upgradeInfo.info.cost[i] * parent->info.creatureCount;
|
||||||
|
|
||||||
|
auto onUpgrade = [=]()
|
||||||
|
{
|
||||||
|
upgradeInfo.callback(upgradeInfo.info.newID[i]);
|
||||||
|
parent->close();
|
||||||
|
};
|
||||||
|
auto onClick = [=]()
|
||||||
|
{
|
||||||
|
std::vector<CComponent*> resComps;
|
||||||
|
for(TResources::nziterator i(totalCost); i.valid(); i++)
|
||||||
|
{
|
||||||
|
resComps.push_back(new CComponent(CComponent::resource, i->resType, i->resVal));
|
||||||
|
}
|
||||||
|
LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[207], onUpgrade, nullptr, true, resComps);
|
||||||
|
};
|
||||||
|
auto upgradeBtn = new CAdventureMapButton(CGI->generaltexth->zelp[446], onClick, 221 + i * 40, 5, "stackWindow/upgradeButton", SDLK_1);
|
||||||
|
if (!LOCPLINT->cb->getResourceAmount().canAfford(totalCost))
|
||||||
|
upgradeBtn->block(true);
|
||||||
|
// else
|
||||||
|
// upgradeBtn->addOverlay(new CPicture());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parent->info.commander)
|
||||||
|
{
|
||||||
|
//TODO: replace with 3 buttons, using upgrade button as base + sec skill image:
|
||||||
|
// 0) Switch to commander skills: Basic Offence
|
||||||
|
// 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);
|
||||||
|
};
|
||||||
|
new CAdventureMapButton(std::make_pair("switch to commander", "help box"), onSwitch, 280, 5, "stackWindow/commanderToggle", SDLK_TAB);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto exitBtn = new CAdventureMapButton(CGI->generaltexth->zelp[445], [=]{ parent->close(); }, 382, 5, "hsbtns.def", SDLK_RETURN);
|
||||||
|
exitBtn->assignedKeys.insert(SDLK_ESCAPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
CStackWindow::CWindowSection::CWindowSection(CStackWindow * parent):
|
||||||
|
parent(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CStackWindow::CSelectableSkill::clickLeft(tribool down, bool previousState)
|
||||||
|
{
|
||||||
|
if (down)
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
|
||||||
|
CIntObject * CStackWindow::createBonusEntry(size_t index)
|
||||||
|
{
|
||||||
|
auto section = new CWindowSection(this);
|
||||||
|
section->createBonusEntry(index);
|
||||||
|
return section;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CStackWindow::CWindowSection::createBonusEntry(size_t index)
|
||||||
|
{
|
||||||
|
OBJ_CONSTRUCTION_CAPTURING_ALL;
|
||||||
|
createBackground("bonus-effects");
|
||||||
|
createBonusItem(index * 2, Point(6, 4));
|
||||||
|
createBonusItem(index * 2 + 1, Point(214, 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CStackWindow::CWindowSection::createBonusItem(size_t index, Point position)
|
||||||
|
{
|
||||||
|
if (parent->activeBonuses.size() > index)
|
||||||
|
{
|
||||||
|
BonusInfo & bi = parent->activeBonuses[index];
|
||||||
|
new CPicture(bi.imagePath, position.x, position.y);
|
||||||
|
new CLabel(position.x + 60, position.y + 2, FONT_SMALL, TOPLEFT, Colors::WHITE, bi.name);
|
||||||
|
new CLabel(position.x + 60, position.y + 25, FONT_SMALL, TOPLEFT, Colors::WHITE, bi.description);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CIntObject * CStackWindow::switchTab(size_t index)
|
||||||
|
{
|
||||||
|
switch (index)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
{
|
||||||
|
activeTab = 0;
|
||||||
|
auto ret = new CWindowSection(this);
|
||||||
|
ret->createCommanderSection();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
activeTab = 1;
|
||||||
|
auto ret = new CWindowSection(this);
|
||||||
|
ret->createBonuses(3);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
activeTab = 2;
|
||||||
|
auto ret = new CWindowSection(this);
|
||||||
|
ret->createCommanderAbilities();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CStackWindow::initSections()
|
||||||
|
{
|
||||||
|
OBJ_CONSTRUCTION_CAPTURING_ALL;
|
||||||
|
CWindowSection * currentSection;
|
||||||
|
|
||||||
|
bool showArt = CGI->modh->modules.STACK_ARTIFACT && info.commander == nullptr;
|
||||||
|
bool showExp = CGI->modh->modules.STACK_EXP || info.commander != nullptr;
|
||||||
|
currentSection = new CWindowSection(this);
|
||||||
|
currentSection->createStackInfo(showExp, showArt);
|
||||||
|
pos.w = currentSection->pos.w;
|
||||||
|
pos.h += currentSection->pos.h;
|
||||||
|
|
||||||
|
if (dynamic_cast<const CStack*>(info.stackNode)) // in battle
|
||||||
|
{
|
||||||
|
currentSection = new CWindowSection(this);
|
||||||
|
currentSection->pos.y += pos.h;
|
||||||
|
currentSection->createActiveSpells();
|
||||||
|
pos.h += currentSection->pos.h;
|
||||||
|
}
|
||||||
|
if (info.commander)
|
||||||
|
{
|
||||||
|
currentSection = new CWindowSection(this);
|
||||||
|
currentSection->pos.y += pos.h;
|
||||||
|
currentSection->createCommanderSection();
|
||||||
|
pos.h += currentSection->pos.h;
|
||||||
|
}
|
||||||
|
if (!info.commander && !activeBonuses.empty())
|
||||||
|
{
|
||||||
|
currentSection = new CWindowSection(this);
|
||||||
|
currentSection->pos.y += pos.h;
|
||||||
|
currentSection->createBonuses();
|
||||||
|
pos.h += currentSection->pos.h;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!info.popupWindow)
|
||||||
|
{
|
||||||
|
currentSection = new CWindowSection(this);
|
||||||
|
currentSection->pos.y += pos.h;
|
||||||
|
currentSection->createButtonPanel();
|
||||||
|
pos.h += currentSection->pos.h;
|
||||||
|
}
|
||||||
|
updateShadow();
|
||||||
|
pos = center(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CStackWindow::initBonusesList()
|
||||||
|
{
|
||||||
|
BonusList output, input;
|
||||||
|
input = *(info.stackNode->getBonuses(Selector::durationType(Bonus::PERMANENT).And(Selector::anyRange())));
|
||||||
|
|
||||||
|
while (!input.empty())
|
||||||
|
{
|
||||||
|
Bonus * b = input.front();
|
||||||
|
|
||||||
|
output.push_back(new Bonus(*b));
|
||||||
|
output.back()->val = input.valOfBonuses(Selector::typeSubtype(b->type, b->subtype)); //merge multiple bonuses into one
|
||||||
|
input.remove_if (Selector::typeSubtype(b->type, b->subtype)); //remove used bonuses
|
||||||
|
}
|
||||||
|
|
||||||
|
BonusInfo bonusInfo;
|
||||||
|
for(Bonus* b : output)
|
||||||
|
{
|
||||||
|
bonusInfo.name = info.stackNode->bonusToString(b, false);
|
||||||
|
bonusInfo.imagePath = info.stackNode->bonusToGraphics(b);
|
||||||
|
|
||||||
|
//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
|
||||||
|
if (!bonusInfo.name.empty() || !bonusInfo.imagePath.empty())
|
||||||
|
activeBonuses.push_back(bonusInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
//handle Magic resistance separately :/
|
||||||
|
int magicResistance = info.stackNode->magicResistance();
|
||||||
|
|
||||||
|
if (magicResistance)
|
||||||
|
{
|
||||||
|
BonusInfo bonusInfo;
|
||||||
|
Bonus b;
|
||||||
|
b.type = Bonus::MAGIC_RESISTANCE;
|
||||||
|
|
||||||
|
bonusInfo.name = VLC->getBth()->bonusToString(&b, info.stackNode, false);
|
||||||
|
bonusInfo.description = VLC->getBth()->bonusToString(&b, info.stackNode, true);
|
||||||
|
bonusInfo.imagePath = info.stackNode->bonusToGraphics(&b);
|
||||||
|
activeBonuses.push_back(bonusInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CStackWindow::init()
|
||||||
|
{
|
||||||
|
selectedIcon = nullptr;
|
||||||
|
selectedSkill = 0;
|
||||||
|
if (info.levelupInfo)
|
||||||
|
selectedSkill = info.levelupInfo->skills.front();
|
||||||
|
|
||||||
|
commanderTab = nullptr;
|
||||||
|
activeTab = 0;
|
||||||
|
|
||||||
|
initBonusesList();
|
||||||
|
initSections();
|
||||||
|
}
|
||||||
|
|
||||||
|
CStackWindow::CStackWindow(const CStack * stack, bool popup):
|
||||||
|
CWindowObject(BORDERED | (popup ? RCLICK_POPUP : 0))
|
||||||
|
{
|
||||||
|
info.stackNode = stack->base;
|
||||||
|
info.creature = stack->type;
|
||||||
|
info.creatureCount = stack->count;
|
||||||
|
info.popupWindow = popup;
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
CStackWindow::CStackWindow(const CCreature * creature, bool popup):
|
||||||
|
CWindowObject(BORDERED | (popup ? RCLICK_POPUP : 0))
|
||||||
|
{
|
||||||
|
info.stackNode = new CStackInstance(creature, 1); // FIXME: free data
|
||||||
|
info.creature = creature;
|
||||||
|
info.popupWindow = popup;
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
CStackWindow::CStackWindow(const CStackInstance * stack, bool popup):
|
||||||
|
CWindowObject(BORDERED | (popup ? RCLICK_POPUP : 0))
|
||||||
|
{
|
||||||
|
info.stackNode = stack;
|
||||||
|
info.creature = stack->type;
|
||||||
|
info.creatureCount = stack->count;
|
||||||
|
info.popupWindow = popup;
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
CStackWindow::CStackWindow(const CStackInstance * stack, std::function<void()> dismiss, const UpgradeInfo & upgradeInfo, std::function<void(CreatureID)> callback):
|
||||||
|
CWindowObject(BORDERED)
|
||||||
|
{
|
||||||
|
info.stackNode = stack;
|
||||||
|
info.creature = stack->type;
|
||||||
|
info.creatureCount = stack->count;
|
||||||
|
|
||||||
|
info.upgradeInfo = StackWindowInfo::StackUpgradeInfo();
|
||||||
|
info.dismissInfo = StackWindowInfo::StackDismissInfo();
|
||||||
|
info.upgradeInfo->info = upgradeInfo;
|
||||||
|
info.upgradeInfo->callback = callback;
|
||||||
|
info.dismissInfo->callback = dismiss;
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
CStackWindow::CStackWindow(const CCommanderInstance * commander, bool popup):
|
||||||
|
CWindowObject(BORDERED | (popup ? RCLICK_POPUP : 0))
|
||||||
|
{
|
||||||
|
info.stackNode = commander;
|
||||||
|
info.creature = commander->type;
|
||||||
|
info.commander = commander;
|
||||||
|
info.creatureCount = 1;
|
||||||
|
info.popupWindow = popup;
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
CStackWindow::CStackWindow(const CCommanderInstance * commander, std::vector<ui32> &skills, std::function<void(ui32)> callback):
|
||||||
|
CWindowObject(BORDERED)
|
||||||
|
{
|
||||||
|
info.stackNode = commander;
|
||||||
|
info.creature = commander->type;
|
||||||
|
info.commander = commander;
|
||||||
|
info.creatureCount = 1;
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
CCreatureWindow::CCreatureWindow (const CStack &stack, CreWinType Type):
|
CCreatureWindow::CCreatureWindow (const CStack &stack, CreWinType Type):
|
||||||
CWindowObject(PLAYER_COLORED | (Type == OTHER ? RCLICK_POPUP : 0 ) ),
|
CWindowObject(PLAYER_COLORED | (Type == OTHER ? RCLICK_POPUP : 0 ) ),
|
||||||
type(Type)
|
type(Type)
|
||||||
@ -458,7 +1035,7 @@ void CCreatureWindow::init(const CStackInstance *Stack, const CBonusSystemNode *
|
|||||||
//AUIDAT.DEF
|
//AUIDAT.DEF
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCreatureWindow::printLine(int nr, const std::string &text, int baseVal, int val/*=-1*/, bool range/*=false*/)
|
void CCreatureWindow::printLine(int nr, const std::string &text, int baseVal, int val, bool range)
|
||||||
{
|
{
|
||||||
new CLabel(162, 48 + nr*19, FONT_SMALL, TOPLEFT, Colors::WHITE, text);
|
new CLabel(162, 48 + nr*19, FONT_SMALL, TOPLEFT, Colors::WHITE, text);
|
||||||
|
|
||||||
@ -821,7 +1398,7 @@ CCreInfoWindow::~CCreInfoWindow()
|
|||||||
delete object;
|
delete object;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCreInfoWindow::printLine(int position, const std::string &text, int baseVal, int val/*=-1*/, bool range/*=false*/)
|
void CCreInfoWindow::printLine(int position, const std::string &text, int baseVal, int val, bool range)
|
||||||
{
|
{
|
||||||
infoTexts[position].first = new CLabel(155, 48 + position*19, FONT_SMALL, TOPLEFT, Colors::WHITE, text);
|
infoTexts[position].first = new CLabel(155, 48 + position*19, FONT_SMALL, TOPLEFT, Colors::WHITE, text);
|
||||||
std::string valueStr;
|
std::string valueStr;
|
||||||
@ -901,8 +1478,7 @@ void CCreInfoWindow::init(const CCreature *creature, const CBonusSystemNode *sta
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CIntObject * createCreWindow(
|
CIntObject * createCreWindow(const CStack *s, bool lclick)
|
||||||
const CStack *s, bool lclick/* = false*/)
|
|
||||||
{
|
{
|
||||||
auto c = dynamic_cast<const CCommanderInstance *>(s->base);
|
auto c = dynamic_cast<const CCommanderInstance *>(s->base);
|
||||||
if (c)
|
if (c)
|
||||||
@ -933,3 +1509,4 @@ CIntObject * createCreWindow(const CStackInstance *s, CCreatureWindow::CreWinTyp
|
|||||||
else
|
else
|
||||||
return new CCreatureWindow(*s, type, Upg, Dsm, ui);
|
return new CCreatureWindow(*s, type, Upg, Dsm, ui);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "gui/CIntObject.h"
|
#include "gui/CIntObjectClasses.h"
|
||||||
#include "../lib/HeroBonus.h"
|
#include "../lib/HeroBonus.h"
|
||||||
#include "GUIClasses.h"
|
#include "../lib/CGameState.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CCreatureWindow.h, part of VCMI engine
|
* CCreatureWindow.h, part of VCMI engine
|
||||||
@ -14,150 +14,114 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct Bonus;
|
struct StackWindowInfo
|
||||||
class CCreature;
|
|
||||||
class CStackInstance;
|
|
||||||
class CCommanderInstance;
|
|
||||||
class CStack;
|
|
||||||
struct ArtifactLocation;
|
|
||||||
class CCreatureArtifactInstance;
|
|
||||||
class CAdventureMapButton;
|
|
||||||
class CBonusItem;
|
|
||||||
class CGHeroInstance;
|
|
||||||
class CComponent;
|
|
||||||
class LRClickableAreaWText;
|
|
||||||
class MoraleLuckBox;
|
|
||||||
class CAdventureMapButton;
|
|
||||||
struct UpgradeInfo;
|
|
||||||
class CPicture;
|
|
||||||
class CCreaturePic;
|
|
||||||
class LRClickableAreaWTextComp;
|
|
||||||
class CSlider;
|
|
||||||
class CLabel;
|
|
||||||
class CAnimImage;
|
|
||||||
class CSelectableSkill;
|
|
||||||
|
|
||||||
// New creature window
|
|
||||||
class CCreatureWindow : public CWindowObject, public CArtifactHolder
|
|
||||||
{
|
{
|
||||||
public:
|
// helper structs
|
||||||
enum CreWinType {OTHER = 0, BATTLE = 1, ARMY = 2, HERO = 3, COMMANDER = 4, COMMANDER_LEVEL_UP = 5, COMMANDER_BATTLE = 6}; // > 3 are opened permanently
|
struct CommanderLevelInfo
|
||||||
//bool active; //TODO: comment me
|
{
|
||||||
CreWinType type;
|
std::vector<ui32> skills;
|
||||||
int bonusRows; //height of skill window
|
std::function<void(ui32)> callback;
|
||||||
ArtifactPosition displayedArtifact;
|
};
|
||||||
|
struct StackDismissInfo
|
||||||
|
{
|
||||||
|
std::function<void()> callback;
|
||||||
|
};
|
||||||
|
struct StackUpgradeInfo
|
||||||
|
{
|
||||||
|
UpgradeInfo info;
|
||||||
|
std::function<void(CreatureID)> callback;
|
||||||
|
};
|
||||||
|
|
||||||
std::string count; //creature count in text format
|
// pointers to permament objects in game state
|
||||||
const CCreature *c; //related creature
|
const CCreature * creature;
|
||||||
const CStackInstance *stack;
|
|
||||||
const CBonusSystemNode *stackNode;
|
|
||||||
const CCommanderInstance * commander;
|
const CCommanderInstance * commander;
|
||||||
const CGHeroInstance *heroOwner;
|
const CStackInstance * stackNode;
|
||||||
const CArtifactInstance *creatureArtifact; //currently worn artifact
|
const CGHeroInstance * owner;
|
||||||
std::vector<CComponent*> upgResCost; //cost of upgrade (if not possible then empty)
|
|
||||||
std::vector<CBonusItem*> bonusItems;
|
|
||||||
std::vector<LRClickableAreaWText*> spellEffects;
|
|
||||||
|
|
||||||
CCreaturePic *anim; //related creature's animation
|
// temporary objects which should be kept as copy if needed
|
||||||
MoraleLuckBox *luck, *morale;
|
boost::optional<CommanderLevelInfo> levelupInfo;
|
||||||
LRClickableAreaWTextComp * expArea; //displays exp details
|
boost::optional<StackDismissInfo> dismissInfo;
|
||||||
CSlider * slider; //Abilities
|
boost::optional<StackUpgradeInfo> upgradeInfo;
|
||||||
CAdventureMapButton *dismiss, *upgrade, *ok;
|
|
||||||
CAdventureMapButton * leftArtRoll, * rightArtRoll; //artifact selection
|
|
||||||
CAdventureMapButton * passArtToHero;
|
|
||||||
CAnimImage * artifactImage;
|
|
||||||
CAnimation * spellEffectsPics; //bitmaps representing spells affecting a stack in battle
|
|
||||||
|
|
||||||
//commander level-up
|
// misc fields
|
||||||
int selectedOption; //index for upgradeOptions
|
unsigned int creatureCount;
|
||||||
std::vector<ui32> upgradeOptions; //value 0-5 - secondary skills, 100+ - special skills
|
bool popupWindow;
|
||||||
std::vector<CSelectableSkill *> selectableSkills, selectableBonuses;
|
|
||||||
std::vector<CPicture *> skillPictures; //secondary skills
|
|
||||||
|
|
||||||
std::string skillToFile(int skill); //return bitmap for secondary skill depending on selection / avaliability
|
StackWindowInfo();
|
||||||
void selectSkill (ui32 which);
|
|
||||||
void setArt(const CArtifactInstance *creatureArtifact);
|
|
||||||
|
|
||||||
void artifactRemoved (const ArtifactLocation &artLoc);
|
|
||||||
void artifactMoved (const ArtifactLocation &artLoc, const ArtifactLocation &destLoc);
|
|
||||||
void artifactDisassembled (const ArtifactLocation &artLoc) {return;};
|
|
||||||
void artifactAssembled (const ArtifactLocation &artLoc) {return;};
|
|
||||||
|
|
||||||
std::function<void()> dsm; //dismiss button callback
|
|
||||||
std::function<void()> Upg; //upgrade button callback
|
|
||||||
std::function<void(ui32)> levelUp; //choose commander skill to level up
|
|
||||||
|
|
||||||
CCreatureWindow(const CStack & stack, CreWinType type); //battle c-tor
|
|
||||||
CCreatureWindow (const CStackInstance &stack, CreWinType Type); //pop-up c-tor
|
|
||||||
CCreatureWindow(const CStackInstance &st, CreWinType Type, std::function<void()> Upg, std::function<void()> Dsm, UpgradeInfo *ui); //full garrison window
|
|
||||||
CCreatureWindow(const CCommanderInstance * commander, const CStack * stack = nullptr); //commander window
|
|
||||||
CCreatureWindow(std::vector<ui32> &skills, const CCommanderInstance * commander, std::function<void(ui32)> callback);
|
|
||||||
CCreatureWindow(CreatureID Cid, CreWinType Type, int creatureCount); //c-tor
|
|
||||||
|
|
||||||
void init(const CStackInstance *stack, const CBonusSystemNode *stackNode, const CGHeroInstance *heroOwner);
|
|
||||||
void showAll(SDL_Surface * to);
|
|
||||||
void show(SDL_Surface * to);
|
|
||||||
void printLine(int nr, const std::string &text, int baseVal, int val=-1, bool range=false);
|
|
||||||
void sliderMoved(int newpos);
|
|
||||||
void close();
|
|
||||||
~CCreatureWindow(); //d-tor
|
|
||||||
|
|
||||||
void recreateSkillList(int pos);
|
|
||||||
void scrollArt(int dir);
|
|
||||||
void passArtifactToHero();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CBonusItem : public LRClickableAreaWTextComp //responsible for displaying creature skill, active or not
|
class CStackWindow : public CWindowObject
|
||||||
{
|
{
|
||||||
|
struct BonusInfo
|
||||||
|
{
|
||||||
|
std::string name;
|
||||||
|
std::string description;
|
||||||
|
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
|
||||||
|
{
|
||||||
|
CStackWindow * parent;
|
||||||
|
|
||||||
|
CPicture * background;
|
||||||
|
|
||||||
|
void createBackground(std::string path);
|
||||||
|
void createBonusItem(size_t index, Point position);
|
||||||
|
|
||||||
|
void printStatString(int index, std::string name, std::string value);
|
||||||
|
void printStatRange(int index, std::string name, int min, int max);
|
||||||
|
void printStatBase(int index, std::string name, int base, int current);
|
||||||
|
void printStat(int index, std::string name, int value);
|
||||||
|
public:
|
||||||
|
void createStackInfo(bool showExp, bool showArt);
|
||||||
|
void createActiveSpells();
|
||||||
|
void createCommanderSection();
|
||||||
|
void createCommander();
|
||||||
|
void createCommanderAbilities();
|
||||||
|
void createBonuses(boost::optional<size_t> size = boost::optional<size_t>());
|
||||||
|
void createBonusEntry(size_t index);
|
||||||
|
void createButtonPanel();
|
||||||
|
|
||||||
|
CWindowSection(CStackWindow * parent);
|
||||||
|
};
|
||||||
|
|
||||||
|
StackWindowInfo info;
|
||||||
|
std::vector<BonusInfo> activeBonuses;
|
||||||
|
size_t activeTab;
|
||||||
|
CTabbedInt * commanderTab;
|
||||||
|
|
||||||
|
CSelectableSkill * selectedIcon;
|
||||||
|
si32 selectedSkill;
|
||||||
|
|
||||||
|
CIntObject * createBonusEntry(size_t index);
|
||||||
|
CIntObject * switchTab(size_t index);
|
||||||
|
|
||||||
|
void initSections();
|
||||||
|
void initBonusesList();
|
||||||
|
|
||||||
|
void init();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::string name, description;
|
// for battles
|
||||||
CPicture * bonusGraphics;
|
CStackWindow(const CStack * stack, bool popup);
|
||||||
bool visible;
|
|
||||||
|
|
||||||
CBonusItem();
|
// for non-existing stacks, e.g. recruit screen
|
||||||
CBonusItem(const Rect &Pos, const std::string &Name, const std::string &Description, const std::string &graphicsName);
|
CStackWindow(const CCreature * creature, bool popup);
|
||||||
~CBonusItem();
|
|
||||||
|
|
||||||
void showAll (SDL_Surface * to);
|
// for normal stacks in armies
|
||||||
|
CStackWindow(const CStackInstance * stack, bool popup);
|
||||||
|
CStackWindow(const CStackInstance * stack, std::function<void()> dismiss, const UpgradeInfo & info, std::function<void(CreatureID)> callback);
|
||||||
|
|
||||||
|
// for commanders & commander level-up dialog
|
||||||
|
CStackWindow(const CCommanderInstance * commander, bool popup);
|
||||||
|
CStackWindow(const CCommanderInstance * commander, std::vector<ui32> &skills, std::function<void(ui32)> callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
class CSelectableSkill : public LRClickableAreaWText
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
std::function<void()> callback; //TODO: create more generic clickable class than AdvMapButton?
|
|
||||||
|
|
||||||
virtual void clickLeft(tribool down, bool previousState);
|
|
||||||
virtual void clickRight(tribool down, bool previousState){};
|
|
||||||
};
|
|
||||||
|
|
||||||
/// original creature info window
|
|
||||||
class CCreInfoWindow : public CWindowObject
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CLabel * creatureCount;
|
|
||||||
CLabel * creatureName;
|
|
||||||
CLabel * abilityText;
|
|
||||||
|
|
||||||
CCreaturePic * animation;
|
|
||||||
std::vector<CComponent *> upgResCost; //cost of upgrade (if not possible then empty)
|
|
||||||
std::vector<CAnimImage *> effects;
|
|
||||||
std::map<size_t, std::pair<CLabel *, CLabel * > > infoTexts;
|
|
||||||
|
|
||||||
MoraleLuckBox * luck, * morale;
|
|
||||||
|
|
||||||
CAdventureMapButton * dismiss, * upgrade, * ok;
|
|
||||||
|
|
||||||
CCreInfoWindow(const CStackInstance & st, bool LClicked, std::function<void()> Upg = nullptr, std::function<void()> Dsm = nullptr, UpgradeInfo * ui = nullptr);
|
|
||||||
CCreInfoWindow(const CStack & st, bool LClicked = 0);
|
|
||||||
CCreInfoWindow(int Cid, bool LClicked, int creatureCount);
|
|
||||||
~CCreInfoWindow();
|
|
||||||
|
|
||||||
void init(const CCreature * cre, const CBonusSystemNode * stackNode, const CGHeroInstance * heroOwner, int creatureCount, bool LClicked);
|
|
||||||
void printLine(int nr, const std::string & text, int baseVal, int val = -1, bool range = false);
|
|
||||||
|
|
||||||
void show(SDL_Surface * to);
|
|
||||||
};
|
|
||||||
|
|
||||||
CIntObject *createCreWindow(const CStack *s, bool lclick = false);
|
|
||||||
CIntObject *createCreWindow(CreatureID Cid, CCreatureWindow::CreWinType Type, int creatureCount);
|
|
||||||
CIntObject *createCreWindow(const CStackInstance *s, CCreatureWindow::CreWinType type, std::function<void()> Upg = nullptr, std::function<void()> Dsm = nullptr, UpgradeInfo *ui = nullptr);
|
|
||||||
|
@ -328,7 +328,7 @@ void CHeroWindow::commanderWindow()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
GH.pushInt(new CCreatureWindow (curHero->commander));
|
GH.pushInt(new CStackWindow(curHero->commander, true));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -482,10 +482,12 @@ void CPlayerInterface::commanderGotLevel (const CCommanderInstance * commander,
|
|||||||
waitWhileDialog();
|
waitWhileDialog();
|
||||||
CCS->soundh->playSound(soundBase::heroNewLevel);
|
CCS->soundh->playSound(soundBase::heroNewLevel);
|
||||||
|
|
||||||
CCreatureWindow * cw = new CCreatureWindow(skills, commander,
|
GH.pushInt(new CStackWindow(commander, skills, [=](ui32 selection)
|
||||||
[=](ui32 selection){ cb->selectionMade(selection, queryID); });
|
{
|
||||||
GH.pushInt(cw);
|
cb->selectionMade(selection, queryID);
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlayerInterface::heroInGarrisonChange(const CGTownInstance *town)
|
void CPlayerInterface::heroInGarrisonChange(const CGTownInstance *town)
|
||||||
{
|
{
|
||||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||||
|
@ -303,7 +303,7 @@ void CGarrisonSlot::clickRight(tribool down, bool previousState)
|
|||||||
{
|
{
|
||||||
if(down && creature)
|
if(down && creature)
|
||||||
{
|
{
|
||||||
GH.pushInt(createCreWindow(myStack, CCreatureWindow::ARMY));
|
GH.pushInt(new CStackWindow(creature, true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void CGarrisonSlot::clickLeft(tribool down, bool previousState)
|
void CGarrisonSlot::clickLeft(tribool down, bool previousState)
|
||||||
@ -320,9 +320,9 @@ void CGarrisonSlot::clickLeft(tribool down, bool previousState)
|
|||||||
|
|
||||||
bool canUpgrade = getObj()->tempOwner == LOCPLINT->playerID && pom.oldID>=0; //upgrade is possible
|
bool canUpgrade = getObj()->tempOwner == LOCPLINT->playerID && pom.oldID>=0; //upgrade is possible
|
||||||
bool canDismiss = getObj()->tempOwner == LOCPLINT->playerID && (getObj()->stacksCount()>1 || !getObj()->needsLastStack());
|
bool canDismiss = getObj()->tempOwner == LOCPLINT->playerID && (getObj()->stacksCount()>1 || !getObj()->needsLastStack());
|
||||||
std::function<void()> upgr = nullptr;
|
std::function<void(CreatureID)> upgr = nullptr;
|
||||||
std::function<void()> dism = nullptr;
|
std::function<void()> dism = nullptr;
|
||||||
if(canUpgrade) upgr = [=] { LOCPLINT->cb->upgradeCreature(getObj(), ID, pom.newID[0]); };
|
if(canUpgrade) upgr = [=] (CreatureID newID) { LOCPLINT->cb->upgradeCreature(getObj(), ID, newID); };
|
||||||
if(canDismiss) dism = [=] { LOCPLINT->cb->dismissCreature(getObj(), ID); };
|
if(canDismiss) dism = [=] { LOCPLINT->cb->dismissCreature(getObj(), ID); };
|
||||||
|
|
||||||
owner->selectSlot(nullptr);
|
owner->selectSlot(nullptr);
|
||||||
@ -333,8 +333,7 @@ void CGarrisonSlot::clickLeft(tribool down, bool previousState)
|
|||||||
|
|
||||||
redraw();
|
redraw();
|
||||||
refr = true;
|
refr = true;
|
||||||
CIntObject *creWindow = createCreWindow(myStack, CCreatureWindow::HERO, upgr, dism, &pom);
|
GH.pushInt(new CStackWindow(myStack, dism, pom, upgr));
|
||||||
GH.pushInt(creWindow);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1386,7 +1385,7 @@ void CRecruitmentWindow::CCreatureCard::clickLeft(tribool down, bool previousSta
|
|||||||
void CRecruitmentWindow::CCreatureCard::clickRight(tribool down, bool previousState)
|
void CRecruitmentWindow::CCreatureCard::clickRight(tribool down, bool previousState)
|
||||||
{
|
{
|
||||||
if (down)
|
if (down)
|
||||||
GH.pushInt(createCreWindow(creature->idNumber, CCreatureWindow::OTHER, 0));
|
GH.pushInt(new CStackWindow(creature, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRecruitmentWindow::CCreatureCard::showAll(SDL_Surface * to)
|
void CRecruitmentWindow::CCreatureCard::showAll(SDL_Surface * to)
|
||||||
|
@ -2432,7 +2432,7 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
|
|||||||
{
|
{
|
||||||
cursorFrame = ECursor::COMBAT_QUERY;
|
cursorFrame = ECursor::COMBAT_QUERY;
|
||||||
consoleMsg = (boost::format(CGI->generaltexth->allTexts[297]) % shere->getName()).str();
|
consoleMsg = (boost::format(CGI->generaltexth->allTexts[297]) % shere->getName()).str();
|
||||||
realizeAction = [=]{ GH.pushInt(createCreWindow(shere, true)); };
|
realizeAction = [=]{ GH.pushInt(new CStackWindow(shere, false)); };
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -606,7 +606,7 @@ void CClickableHex::clickRight(tribool down, bool previousState)
|
|||||||
if(!myst->alive()) return;
|
if(!myst->alive()) return;
|
||||||
if(down)
|
if(down)
|
||||||
{
|
{
|
||||||
GH.pushInt(createCreWindow(myst));
|
GH.pushInt(new CStackWindow(myst, true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|