1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-03-21 21:17:49 +02:00

Partial interactive mode for Commander level-up dialog. It is possible to select secondary skill.

This commit is contained in:
DjWarmonger 2012-07-03 08:07:34 +00:00
parent 406346a6ab
commit ac997b8214
5 changed files with 143 additions and 43 deletions

@ -29,6 +29,7 @@ using namespace CSDL_Ext;
class CBonusItem;
class CCreatureArtifactInstance;
class CSelectableSkill;
/*
* CCreatureWindow.cpp, part of VCMI engine
@ -146,6 +147,28 @@ CCreatureWindow::CCreatureWindow (const CCommanderInstance * Commander):
dismiss = new CAdventureMapButton("",CGI->generaltexth->zelp[445].second, cfl, 333, 148,"IVIEWCR2.DEF", SDLK_d);
}
CCreatureWindow::CCreatureWindow (std::vector<ui32> &skills, const CCommanderInstance * Commander, boost::function<void(ui32)> &callback):
CWindowObject(PLAYER_COLORED),
type(COMMANDER_LEVEL_UP),
upgradeOptions(skills), //copy skills to choose from
commander (Commander),
levelUp (callback),
selectedOption (0) //choose something before drawing
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
init(commander, commander, dynamic_cast<const CGHeroInstance*>(commander->armyObj));
boost::function<void()> Dsm;
CFunctionList<void()> fs[2];
//on dismiss confirmed
fs[0] += Dsm; //dismiss
fs[0] += boost::bind(&CCreatureWindow::close,this);//close this window
CFunctionList<void()> cfl;
cfl = boost::bind(&CPlayerInterface::showYesNoDialog,LOCPLINT,CGI->generaltexth->allTexts[12],fs[0],fs[1],false,std::vector<CComponent*>());
dismiss = new CAdventureMapButton("",CGI->generaltexth->zelp[445].second, cfl, 333, 148,"IVIEWCR2.DEF", SDLK_d);
}
void CCreatureWindow::init(const CStackInstance *Stack, const CBonusSystemNode *StackNode, const CGHeroInstance *HeroOwner)
{
creatureArtifact = NULL; //may be set later
@ -311,41 +334,11 @@ void CCreatureWindow::init(const CStackInstance *Stack, const CBonusSystemNode *
creArt = true;
for (int i = ECommander::ATTACK; i <= ECommander::SPELL_POWER; ++i)
{
if (commander->secondarySkills[i])
if (commander->secondarySkills[i] || vstd::contains(upgradeOptions, i))
{
std::string file = "zvs/Lib1.res/_";
switch (i)
{
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)(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";
std::string file = skillToFile(i);
new CPicture(file, 37 + i * 84, 224);
skillPictures.push_back(new CPicture(file, 37 + i * 84, 224));
}
}
//print commander level
@ -354,6 +347,30 @@ void CCreatureWindow::init(const CStackInstance *Stack, const CBonusSystemNode *
new CLabel(488, 82, FONT_SMALL, CENTER, Colors::Cornsilk,
boost::lexical_cast<std::string>(stack->experience));
if (type == COMMANDER_LEVEL_UP)
{
BOOST_FOREACH (auto option, upgradeOptions)
{
ui32 index = selectableSkills.size();
CSelectableSkill * selectableSkill = new CSelectableSkill();
if (option < 100)
{
selectableSkill->pos = skillPictures[option]->pos; //should match picture
}
else
{
selectableSkill->pos = Rect (95, 256, 55, 55); //TODO: scroll
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)));
}
selectableSkill->callback = boost::bind(&CCreatureWindow::selectSkill, this, index);
selectableSkills.push_back (selectableSkill);
//TODO: add clickable abilities to bonusItems
}
}
}
if (creArt) //stack or commander artifacts
{
@ -492,6 +509,15 @@ void CCreatureWindow::showAll(SDL_Surface * to)
BOOST_FOREACH(CBonusItem* b, bonusItems)
b->showAll (to);
BOOST_FOREACH(auto s, selectableSkills)
s->showAll (to);
for (int i = 0; i < skillPictures.size(); i++)
{
skillPictures[i]->bg = BitmapHandler::loadBitmap (skillToFile(i));
skillPictures[i]->showAll (to);
}
}
void CCreatureWindow::show(SDL_Surface * to)
@ -501,12 +527,57 @@ void CCreatureWindow::show(SDL_Surface * to)
}
void CCreatureWindow::close()
{
if (upgradeOptions.size()) //a skill for commander was chosen
levelUp (upgradeOptions[selectedOption]); //callback
GH.popIntTotally(this);
}
void CCreatureWindow::sliderMoved(int newpos)
{
recreateSkillList(newpos); //move components
redraw();
}
std::string CCreatureWindow::skillToFile (int skill)
{
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)(commander->secondarySkills[skill])); //casting ui8 causes ascii char conversion
if (type == COMMANDER_LEVEL_UP)
{
if (upgradeOptions.size() && upgradeOptions[selectedOption] == skill)//that one specific skill is selected
sufix += "="; //level-up highlight
else if (!vstd::contains(upgradeOptions, skill))
sufix = "no"; //not avaliable - no number
}
file += sufix += ".bmp";
return file;
}
void CCreatureWindow::setArt(const CArtifactInstance *art)
{
creatureArtifact = art;
@ -562,6 +633,12 @@ void CCreatureWindow::artifactMoved (const ArtifactLocation &artLoc, const Artif
artifactRemoved (artLoc); //same code
}
void CCreatureWindow::selectSkill (ui32 which)
{
selectedOption = which;
redraw();
}
CCreatureWindow::~CCreatureWindow()
{
for (int i=0; i<upgResCost.size(); ++i)
@ -605,6 +682,12 @@ CBonusItem::~CBonusItem()
//delete bonusGraphics; //automatic destruction
}
void CSelectableSkill::clickLeft(tribool down, bool previousState)
{
if (down)
callback();
}
void CCreInfoWindow::show(SDL_Surface * to)
{
CIntObject::show(to);

@ -35,6 +35,7 @@ class LRClickableAreaWTextComp;
class CSlider;
class CLabel;
class CAnimImage;
class CSelectableSkill;
// New creature window
class CCreatureWindow : public CWindowObject, public CArtifactHolder
@ -66,6 +67,14 @@ public:
CAdventureMapButton * passArtToHero;
CAnimImage *artifactImage;
//commander level-up
int selectedOption;
std::vector<ui32> upgradeOptions;
std::vector<CSelectableSkill *> selectableSkills;
std::vector<CPicture *> skillPictures; //secondary skills
std::string skillToFile(int skill); //return bitmap for secondary skill depending on selection / avaliability
void selectSkill (ui32 which);
void setArt(const CArtifactInstance *creatureArtifact);
void artifactRemoved (const ArtifactLocation &artLoc);
@ -75,11 +84,13 @@ public:
boost::function<void()> dsm; //dismiss button callback
boost::function<void()> Upg; //upgrade button callback
boost::function<void(ui32)> levelUp; //choose commander skill to level up
CCreatureWindow(const CStack & stack, int type); //battle c-tor
CCreatureWindow (const CStackInstance &stack, int Type); //pop-up c-tor
CCreatureWindow(const CStackInstance &st, int Type, boost::function<void()> Upg, boost::function<void()> Dsm, UpgradeInfo *ui); //full garrison window
CCreatureWindow(const CCommanderInstance * commander); //commander window
CCreatureWindow(std::vector<ui32> &skills, const CCommanderInstance * commander, boost::function<void(ui32)> &callback);
CCreatureWindow(int Cid, int Type, int creatureCount); //c-tor
void init(const CStackInstance *stack, const CBonusSystemNode *stackNode, const CGHeroInstance *heroOwner);
@ -87,6 +98,7 @@ public:
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);
@ -109,6 +121,15 @@ public:
void showAll (SDL_Surface * to);
};
class CSelectableSkill : public LRClickableAreaWText
{
public:
boost::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
{

@ -482,14 +482,12 @@ void CPlayerInterface::commanderGotLevel (const CCommanderInstance * commander,
waitWhileDialog();
CCS->soundh->playSound(soundBase::heroNewLevel);
//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*>());
//auto callback2 = boost::bind (&CCallback::selectionMade, cb, 0, playerID);
//showYesNoDialog ("Commander got level", callback2, callback2, true, std::vector<CComponent*>());
//TODO: display full window
//CCreatureWindow * cw = new CCreatureWindow(commander);
//GH.pushInt(cw);
CCreatureWindow * cw = new CCreatureWindow(skills, commander, callback);
GH.pushInt(cw);
}
void CPlayerInterface::heroInGarrisonChange(const CGTownInstance *town)
{

@ -543,9 +543,7 @@ void CommanderLevelUp::applyCl( CClient *cl )
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);
cl->playerint[player]->commanderGotLevel(commander, skills, callback);
}
}

@ -1167,7 +1167,7 @@ struct CommanderLevelUp : public Query
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
std::vector<ui32> skills; //0-5 - secondary skills, val-100 - special skill
CommanderLevelUp(){type = 2005;};