1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-01-12 02:28:11 +02:00

Gui cleanup3 - UI refactoring to use smart pointers (#440)

* Changed most gui classes to use shared pointers
* Store and use IImage as shared_ptr
* CSpellWindow redesign
* AdventureMapClasses cleanup
* CLabel: store background as smart pointer
* Store CObjectList items as smart pointers
* Removed destroy function of list item
* Store toggle buttons as smart pointers
* Use CComponent as smart pointer
* Attempt to fix artifact merchant drawing
This commit is contained in:
Alexander Shishkin 2018-04-07 14:34:11 +03:00 committed by ArseniyShestakov
parent db60983b5a
commit 5c09f751b3
73 changed files with 4793 additions and 4544 deletions

View File

@ -447,7 +447,7 @@ void VCAI::advmapSpellCast(const CGHeroInstance * caster, int spellID)
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
} }
void VCAI::showInfoDialog(const std::string &text, const std::vector<Component*> &components, int soundID) void VCAI::showInfoDialog(const std::string &text, const std::vector<Component> &components, int soundID)
{ {
LOG_TRACE_PARAMS(logAi, "soundID '%i'", soundID); LOG_TRACE_PARAMS(logAi, "soundID '%i'", soundID);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;

View File

@ -231,7 +231,7 @@ public:
virtual void playerBonusChanged(const Bonus &bonus, bool gain) override; virtual void playerBonusChanged(const Bonus &bonus, bool gain) override;
virtual void heroCreated(const CGHeroInstance*) override; virtual void heroCreated(const CGHeroInstance*) override;
virtual void advmapSpellCast(const CGHeroInstance * caster, int spellID) override; virtual void advmapSpellCast(const CGHeroInstance * caster, int spellID) override;
virtual void showInfoDialog(const std::string &text, const std::vector<Component*> &components, int soundID) override; virtual void showInfoDialog(const std::string &text, const std::vector<Component> &components, int soundID) override;
virtual void requestRealized(PackageApplied *pa) override; virtual void requestRealized(PackageApplied *pa) override;
virtual void receivedResource() override; virtual void receivedResource() override;
virtual void objectRemoved(const CGObjectInstance *obj) override; virtual void objectRemoved(const CGObjectInstance *obj) override;

View File

@ -1341,7 +1341,7 @@ void handleQuit(bool ask)
if(CSH->client && LOCPLINT && ask) if(CSH->client && LOCPLINT && ask)
{ {
CCS->curh->changeGraphic(ECursor::ADVENTURE, 0); CCS->curh->changeGraphic(ECursor::ADVENTURE, 0);
LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[69], quitApplication, 0); LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[69], quitApplication, nullptr);
} }
else else
{ {

View File

@ -39,30 +39,30 @@ template <typename T, typename U> std::pair<T,U> max(const std::pair<T,U> &x, co
class ComponentResolved : public CIntObject class ComponentResolved : public CIntObject
{ {
public: public:
CComponent *comp; std::shared_ptr<CComponent> comp;
//blit component with image centered at this position //blit component with image centered at this position
void showAll(SDL_Surface * to) override; void showAll(SDL_Surface * to) override;
//ComponentResolved(); //ComponentResolved();
ComponentResolved(CComponent *Comp); ComponentResolved(std::shared_ptr<CComponent> Comp);
~ComponentResolved(); ~ComponentResolved();
}; };
// Full set of components for blitting on dialog box // Full set of components for blitting on dialog box
struct ComponentsToBlit struct ComponentsToBlit
{ {
std::vector< std::vector<ComponentResolved*> > comps; std::vector< std::vector<std::shared_ptr<ComponentResolved>>> comps;
int w, h; int w, h;
void blitCompsOnSur(bool blitOr, int inter, int &curh, SDL_Surface *ret); void blitCompsOnSur(bool blitOr, int inter, int &curh, SDL_Surface *ret);
ComponentsToBlit(std::vector<CComponent*> & SComps, int maxw, bool blitOr); ComponentsToBlit(std::vector<std::shared_ptr<CComponent>> & SComps, int maxw, bool blitOr);
~ComponentsToBlit(); ~ComponentsToBlit();
}; };
namespace namespace
{ {
std::array<std::unique_ptr<CAnimation>, PlayerColor::PLAYER_LIMIT_I> dialogBorders; std::array<std::unique_ptr<CAnimation>, PlayerColor::PLAYER_LIMIT_I> dialogBorders;
std::array<std::vector<const IImage*>, PlayerColor::PLAYER_LIMIT_I> piecesOfBox; std::array<std::vector<std::shared_ptr<IImage>>, PlayerColor::PLAYER_LIMIT_I> piecesOfBox;
SDL_Surface * background = nullptr;//todo: should be CFilledTexture SDL_Surface * background = nullptr;//todo: should be CFilledTexture
} }
@ -298,7 +298,7 @@ void CMessage::drawBorder(PlayerColor playerColor, SDL_Surface * ret, int w, int
{ {
if(playerColor.isSpectator()) if(playerColor.isSpectator())
playerColor = PlayerColor(1); playerColor = PlayerColor(1);
std::vector<const IImage*> &box = piecesOfBox.at(playerColor.getNum()); auto & box = piecesOfBox.at(playerColor.getNum());
// Note: this code assumes that the corner dimensions are all the same. // Note: this code assumes that the corner dimensions are all the same.
@ -358,7 +358,7 @@ void CMessage::drawBorder(PlayerColor playerColor, SDL_Surface * ret, int w, int
box[3]->draw(ret, &dstR, nullptr); box[3]->draw(ret, &dstR, nullptr);
} }
ComponentResolved::ComponentResolved( CComponent *Comp ): ComponentResolved::ComponentResolved(std::shared_ptr<CComponent> Comp):
comp(Comp) comp(Comp)
{ {
//Temporary assign ownership on comp //Temporary assign ownership on comp
@ -367,10 +367,10 @@ ComponentResolved::ComponentResolved( CComponent *Comp ):
if (comp->parent) if (comp->parent)
{ {
comp->parent->addChild(this); comp->parent->addChild(this);
comp->parent->removeChild(comp); comp->parent->removeChild(comp.get());
} }
addChild(comp); addChild(comp.get());
defActions = 255 - DISPOSE; defActions = 255 - DISPOSE;
pos.x = pos.y = 0; pos.x = pos.y = 0;
@ -382,8 +382,8 @@ ComponentResolved::~ComponentResolved()
{ {
if (parent) if (parent)
{ {
removeChild(comp); removeChild(comp.get());
parent->addChild(comp); parent->addChild(comp.get());
} }
} }
@ -393,15 +393,9 @@ void ComponentResolved::showAll(SDL_Surface *to)
comp->showAll(to); comp->showAll(to);
} }
ComponentsToBlit::~ComponentsToBlit() ComponentsToBlit::~ComponentsToBlit() = default;
{
for(auto & elem : comps)
for(size_t j = 0; j < elem.size(); j++)
delete elem[j];
} ComponentsToBlit::ComponentsToBlit(std::vector<std::shared_ptr<CComponent>> & SComps, int maxw, bool blitOr)
ComponentsToBlit::ComponentsToBlit(std::vector<CComponent*> & SComps, int maxw, bool blitOr)
{ {
int orWidth = graphics->fonts[FONT_MEDIUM]->getStringWidth(CGI->generaltexth->allTexts[4]); int orWidth = graphics->fonts[FONT_MEDIUM]->getStringWidth(CGI->generaltexth->allTexts[4]);
@ -415,7 +409,7 @@ ComponentsToBlit::ComponentsToBlit(std::vector<CComponent*> & SComps, int maxw,
for(auto & SComp : SComps) for(auto & SComp : SComps)
{ {
auto cur = new ComponentResolved(SComp); auto cur = std::make_shared<ComponentResolved>(SComp);
int toadd = (cur->pos.w + BETWEEN_COMPS + (blitOr ? orWidth : 0)); int toadd = (cur->pos.w + BETWEEN_COMPS + (blitOr ? orWidth : 0));
if (curw + toadd > maxw) if (curw + toadd > maxw)
@ -453,7 +447,7 @@ void ComponentsToBlit::blitCompsOnSur( bool blitOr, int inter, int &curh, SDL_Su
int totalw=0, maxHeight=0; int totalw=0, maxHeight=0;
for(size_t j=0;j<elem.size();j++)//find max height & total width in this row for(size_t j=0;j<elem.size();j++)//find max height & total width in this row
{ {
ComponentResolved *cur = elem[j]; auto cur = elem[j];
totalw += cur->pos.w; totalw += cur->pos.w;
vstd::amax(maxHeight, cur->pos.h); vstd::amax(maxHeight, cur->pos.h);
} }
@ -469,7 +463,7 @@ void ComponentsToBlit::blitCompsOnSur( bool blitOr, int inter, int &curh, SDL_Su
for(size_t j=0;j<elem.size();j++) for(size_t j=0;j<elem.size();j++)
{ {
ComponentResolved *cur = elem[j]; auto cur = elem[j];
cur->moveTo(Point(curw, curh)); cur->moveTo(Point(curw, curh));
//blit component //blit component

View File

@ -196,8 +196,8 @@ void CPlayerInterface::yourTurn()
makingTurn = true; makingTurn = true;
std::string msg = CGI->generaltexth->allTexts[13]; std::string msg = CGI->generaltexth->allTexts[13];
boost::replace_first(msg, "%s", cb->getStartInfo()->playerInfos.find(playerID)->second.name); boost::replace_first(msg, "%s", cb->getStartInfo()->playerInfos.find(playerID)->second.name);
std::vector<CComponent*> cmp; std::vector<std::shared_ptr<CComponent>> cmp;
cmp.push_back(new CComponent(CComponent::flag, playerID.getNum(), 0)); cmp.push_back(std::make_shared<CComponent>(CComponent::flag, playerID.getNum(), 0));
showInfoDialog(msg, cmp); showInfoDialog(msg, cmp);
} }
else else
@ -363,9 +363,8 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details)
GH.mainFPSmng->framerateDelay(); //for animation purposes GH.mainFPSmng->framerateDelay(); //for animation purposes
logGlobal->trace("after [un]locks in %s", __FUNCTION__); logGlobal->trace("after [un]locks in %s", __FUNCTION__);
} }
//CSDL_Ext::update(screen);
} //for (int i=1; i<32; i+=4) }
//main moving done //main moving done
//finishing move //finishing move
@ -905,8 +904,7 @@ void CPlayerInterface::battleEnd(const BattleResult *br)
if (!battleInt) if (!battleInt)
{ {
SDL_Rect temp_rect = genRect(561, 470, (screen->w - 800)/2 + 165, (screen->h - 600)/2 + 19); auto resWindow = new CBattleResultWindow(*br, *this);
auto resWindow = new CBattleResultWindow(*br, temp_rect, *this);
GH.pushInt(resWindow); GH.pushInt(resWindow);
// #1490 - during AI turn when quick combat is on, we need to display the message and wait for user to close it. // #1490 - during AI turn when quick combat is on, we need to display the message and wait for user to close it.
// Otherwise NewTurn causes freeze. // Otherwise NewTurn causes freeze.
@ -1100,29 +1098,29 @@ void CPlayerInterface::showComp(const Component &comp, std::string message)
adventureInt->infoBar.showComponent(comp, message); adventureInt->infoBar.showComponent(comp, message);
} }
void CPlayerInterface::showInfoDialog(const std::string &text, const std::vector<Component*> &components, int soundID) void CPlayerInterface::showInfoDialog(const std::string &text, const std::vector<Component> & components, int soundID)
{ {
EVENT_HANDLER_CALLED_BY_CLIENT; EVENT_HANDLER_CALLED_BY_CLIENT;
if (settings["session"]["autoSkip"].Bool() && !LOCPLINT->shiftPressed()) if (settings["session"]["autoSkip"].Bool() && !LOCPLINT->shiftPressed())
{ {
return; return;
} }
std::vector<CComponent*> intComps; std::vector<std::shared_ptr<CComponent>> intComps;
for (auto & component : components) for (auto & component : components)
intComps.push_back(new CComponent(*component)); intComps.push_back(std::make_shared<CComponent>(component));
showInfoDialog(text,intComps,soundID); showInfoDialog(text,intComps,soundID);
} }
void CPlayerInterface::showInfoDialog(const std::string &text, CComponent * component) void CPlayerInterface::showInfoDialog(const std::string & text, std::shared_ptr<CComponent> component)
{ {
std::vector<CComponent*> intComps; std::vector<std::shared_ptr<CComponent>> intComps;
intComps.push_back(component); intComps.push_back(component);
showInfoDialog(text, intComps, soundBase::sound_todo, true); showInfoDialog(text, intComps, soundBase::sound_todo);
} }
void CPlayerInterface::showInfoDialog(const std::string &text, const std::vector<CComponent*> & components, int soundID, bool delComps) void CPlayerInterface::showInfoDialog(const std::string &text, const std::vector<std::shared_ptr<CComponent>> & components, int soundID)
{ {
LOG_TRACE_PARAMS(logGlobal, "player=%s, text=%s, is LOCPLINT=%d", playerID % text % (this==LOCPLINT)); LOG_TRACE_PARAMS(logGlobal, "player=%s, text=%s, is LOCPLINT=%d", playerID % text % (this==LOCPLINT));
waitWhileDialog(); waitWhileDialog();
@ -1131,8 +1129,8 @@ void CPlayerInterface::showInfoDialog(const std::string &text, const std::vector
{ {
return; return;
} }
CInfoWindow *temp = CInfoWindow::create(text, playerID, &components); CInfoWindow *temp = CInfoWindow::create(text, playerID, components);
temp->setDelComps(delComps);
if (makingTurn && GH.listInt.size() && LOCPLINT == this) if (makingTurn && GH.listInt.size() && LOCPLINT == this)
{ {
CCS->soundh->playSound(static_cast<soundBase::soundID>(soundID)); CCS->soundh->playSound(static_cast<soundBase::soundID>(soundID));
@ -1149,46 +1147,37 @@ void CPlayerInterface::showInfoDialog(const std::string &text, const std::vector
void CPlayerInterface::showInfoDialogAndWait(std::vector<Component> & components, const MetaString & text) void CPlayerInterface::showInfoDialogAndWait(std::vector<Component> & components, const MetaString & text)
{ {
EVENT_HANDLER_CALLED_BY_CLIENT; EVENT_HANDLER_CALLED_BY_CLIENT;
std::vector<Component*> comps;
for (auto & elem : components)
{
comps.push_back(&elem);
}
std::string str; std::string str;
text.toString(str); text.toString(str);
showInfoDialog(str,comps, 0); showInfoDialog(str, components, 0);
waitWhileDialog(); waitWhileDialog();
} }
void CPlayerInterface::showYesNoDialog(const std::string &text, CFunctionList<void()> onYes, CFunctionList<void()> onNo, bool DelComps, const std::vector<CComponent*> & components) void CPlayerInterface::showYesNoDialog(const std::string &text, CFunctionList<void()> onYes, CFunctionList<void()> onNo, const std::vector<std::shared_ptr<CComponent>> & components)
{ {
boost::unique_lock<boost::recursive_mutex> un(*pim); boost::unique_lock<boost::recursive_mutex> un(*pim);
stopMovement(); stopMovement();
LOCPLINT->showingDialog->setn(true); LOCPLINT->showingDialog->setn(true);
CInfoWindow::showYesNoDialog(text, &components, onYes, onNo, DelComps, playerID); CInfoWindow::showYesNoDialog(text, components, onYes, onNo, playerID);
} }
void CPlayerInterface::showOkDialog(std::vector<Component> & components, const MetaString & text, const std::function<void()> & onOk) void CPlayerInterface::showOkDialog(std::vector<Component> & components, const MetaString & text, const std::function<void()> & onOk)
{ {
boost::unique_lock<boost::recursive_mutex> un(*pim); boost::unique_lock<boost::recursive_mutex> un(*pim);
std::vector<Component*> comps;
for (auto & elem : components)
{
comps.push_back(&elem);
}
std::string str; std::string str;
text.toString(str); text.toString(str);
stopMovement(); stopMovement();
showingDialog->setn(true); showingDialog->setn(true);
std::vector<CComponent*> intComps; std::vector<std::shared_ptr<CComponent>> intComps;
for (auto & component : comps) for (auto & component : components)
intComps.push_back(new CComponent(*component)); intComps.push_back(std::make_shared<CComponent>(component));
CInfoWindow::showOkDialog(str, &intComps, onOk, true, playerID); CInfoWindow::showOkDialog(str, intComps, onOk, playerID);
} }
void CPlayerInterface::showBlockingDialog( const std::string &text, const std::vector<Component> &components, QueryID askID, const int soundID, bool selection, bool cancel ) void CPlayerInterface::showBlockingDialog( const std::string &text, const std::vector<Component> &components, QueryID askID, const int soundID, bool selection, bool cancel )
@ -1201,17 +1190,17 @@ void CPlayerInterface::showBlockingDialog( const std::string &text, const std::v
if (!selection && cancel) //simple yes/no dialog if (!selection && cancel) //simple yes/no dialog
{ {
std::vector<CComponent*> intComps; std::vector<std::shared_ptr<CComponent>> intComps;
for (auto & component : components) for (auto & component : components)
intComps.push_back(new CComponent(component)); //will be deleted by close in window intComps.push_back(std::make_shared<CComponent>(component)); //will be deleted by close in window
showYesNoDialog(text, [=](){ cb->selectionMade(1, askID); }, [=](){ cb->selectionMade(0, askID); }, true, intComps); showYesNoDialog(text, [=](){ cb->selectionMade(1, askID); }, [=](){ cb->selectionMade(0, askID); }, intComps);
} }
else if (selection) else if (selection)
{ {
std::vector<CSelectableComponent*> intComps; std::vector<std::shared_ptr<CSelectableComponent>> intComps;
for (auto & component : components) for (auto & component : components)
intComps.push_back(new CSelectableComponent(component)); //will be deleted by CSelWindow::close intComps.push_back(std::make_shared<CSelectableComponent>(component)); //will be deleted by CSelWindow::close
std::vector<std::pair<std::string,CFunctionList<void()> > > pom; std::vector<std::pair<std::string,CFunctionList<void()> > > pom;
pom.push_back(std::pair<std::string,CFunctionList<void()> >("IOKAY.DEF",0)); pom.push_back(std::pair<std::string,CFunctionList<void()> >("IOKAY.DEF",0));
@ -1269,8 +1258,8 @@ void CPlayerInterface::showMapObjectSelectDialog(QueryID askID, const Component
CComponent * localIconC = new CComponent(icon); CComponent * localIconC = new CComponent(icon);
CIntObject * localIcon = localIconC->image; std::shared_ptr<CIntObject> localIcon = localIconC->image;
localIconC->removeChild(localIcon, false); localIconC->removeChild(localIcon.get(), false);
delete localIconC; delete localIconC;
CObjectListWindow * wnd = new CObjectListWindow(tempList, localIcon, localTitle, localDescription, selectCallback); CObjectListWindow * wnd = new CObjectListWindow(tempList, localIcon, localTitle, localDescription, selectCallback);
@ -1302,46 +1291,6 @@ void CPlayerInterface::openHeroWindow(const CGHeroInstance *hero)
boost::unique_lock<boost::recursive_mutex> un(*pim); boost::unique_lock<boost::recursive_mutex> un(*pim);
GH.pushInt(new CHeroWindow(hero)); GH.pushInt(new CHeroWindow(hero));
} }
/*
void CPlayerInterface::heroArtifactSetChanged(const CGHeroInstance*hero)
{
boost::unique_lock<boost::recursive_mutex> un(*pim);
if (adventureInt->heroWindow->curHero && adventureInt->heroWindow->curHero->id == hero->id) //hero window is opened
{
adventureInt->heroWindow->deactivate();
adventureInt->heroWindow->setHero(hero);
adventureInt->heroWindow->activate();
}
else if (CExchangeWindow* cew = dynamic_cast<CExchangeWindow*>(GH.topInt())) //exchange window is open
{
cew->deactivate();
for (int g=0; g<ARRAY_COUNT(cew->heroInst); ++g)
{
if (cew->heroInst[g]->id == hero->id)
{
cew->heroInst[g] = hero;
cew->artifs[g]->updateState = true;
cew->artifs[g]->setHero(hero);
cew->artifs[g]->updateState = false;
}
}
cew->prepareBackground();
cew->activate();
}
else if (CTradeWindow *caw = dynamic_cast<CTradeWindow*>(GH.topInt()))
{
if (caw->arts)
{
caw->deactivate();
caw->arts->updateState = true;
caw->arts->setHero(hero);
caw->arts->updateState = false;
caw->activate();
}
}
updateInfo(hero);
}*/
void CPlayerInterface::availableCreaturesChanged( const CGDwelling *town ) void CPlayerInterface::availableCreaturesChanged( const CGDwelling *town )
{ {
@ -1504,25 +1453,28 @@ void CPlayerInterface::showArtifactAssemblyDialog (ui32 artifactID, ui32 assembl
const CArtifact &artifact = *CGI->arth->artifacts[artifactID]; const CArtifact &artifact = *CGI->arth->artifacts[artifactID];
std::string text = artifact.Description(); std::string text = artifact.Description();
text += "\n\n"; text += "\n\n";
std::vector<CComponent*> scs; std::vector<std::shared_ptr<CComponent>> scs;
if (assemble) { if(assemble)
{
const CArtifact &assembledArtifact = *CGI->arth->artifacts[assembleTo]; const CArtifact &assembledArtifact = *CGI->arth->artifacts[assembleTo];
// You possess all of the components to... // You possess all of the components to...
text += boost::str(boost::format(CGI->generaltexth->allTexts[732]) % assembledArtifact.Name()); text += boost::str(boost::format(CGI->generaltexth->allTexts[732]) % assembledArtifact.Name());
// Picture of assembled artifact at bottom. // Picture of assembled artifact at bottom.
auto sc = new CComponent(CComponent::artifact, assembledArtifact.id, 0); auto sc = std::make_shared<CComponent>(CComponent::artifact, assembledArtifact.id, 0);
//sc->description = assembledArtifact.Description(); //sc->description = assembledArtifact.Description();
//sc->subtitle = assembledArtifact.Name(); //sc->subtitle = assembledArtifact.Name();
scs.push_back(sc); scs.push_back(sc);
} else { }
else
{
// Do you wish to disassemble this artifact? // Do you wish to disassemble this artifact?
text += CGI->generaltexth->allTexts[733]; text += CGI->generaltexth->allTexts[733];
} }
showYesNoDialog(text, onYes, onNo, true, scs); showYesNoDialog(text, onYes, onNo, scs);
} }
void CPlayerInterface::requestRealized( PackageApplied *pa ) void CPlayerInterface::requestRealized( PackageApplied *pa )
@ -2230,7 +2182,7 @@ void CPlayerInterface::gameOver(PlayerColor player, const EVictoryLossCheckResul
{ {
std::string str = victoryLossCheckResult.messageToSelf; std::string str = victoryLossCheckResult.messageToSelf;
boost::algorithm::replace_first(str, "%s", CGI->generaltexth->capColors[player.getNum()]); boost::algorithm::replace_first(str, "%s", CGI->generaltexth->capColors[player.getNum()]);
showInfoDialog(str, std::vector<CComponent*>(1, new CComponent(CComponent::flag, player.getNum(), 0))); showInfoDialog(str, std::vector<std::shared_ptr<CComponent>>(1, std::make_shared<CComponent>(CComponent::flag, player.getNum(), 0)));
} }
} }
} }
@ -2661,7 +2613,7 @@ void CPlayerInterface::waitForAllDialogs(bool unlockPim)
void CPlayerInterface::proposeLoadingGame() void CPlayerInterface::proposeLoadingGame()
{ {
showYesNoDialog(CGI->generaltexth->allTexts[68], [this](){ sendCustomEvent(EUserEvent::RETURN_TO_MENU_LOAD); }, 0, false); showYesNoDialog(CGI->generaltexth->allTexts[68], [this](){ sendCustomEvent(EUserEvent::RETURN_TO_MENU_LOAD); }, nullptr);
} }
CPlayerInterface::SpellbookLastSetting::SpellbookLastSetting() CPlayerInterface::SpellbookLastSetting::SpellbookLastSetting()

View File

@ -39,7 +39,6 @@ class CSlider;
struct UpgradeInfo; struct UpgradeInfo;
template <typename T> struct CondSh; template <typename T> struct CondSh;
class CInGameConsole; class CInGameConsole;
class CGarrisonInt;
class CInGameConsole; class CInGameConsole;
union SDL_Event; union SDL_Event;
class CInfoWindow; class CInfoWindow;
@ -139,7 +138,7 @@ public:
void heroMovePointsChanged(const CGHeroInstance * hero) override; void heroMovePointsChanged(const CGHeroInstance * hero) override;
void heroVisitsTown(const CGHeroInstance* hero, const CGTownInstance * town) override; void heroVisitsTown(const CGHeroInstance* hero, const CGTownInstance * town) override;
void receivedResource() override; void receivedResource() override;
void showInfoDialog(const std::string &text, const std::vector<Component*> &components, int soundID) override; void showInfoDialog(const std::string & text, const std::vector<Component> & components, int soundID) override;
void showRecruitmentDialog(const CGDwelling *dwelling, const CArmedInstance *dst, int level) override; void showRecruitmentDialog(const CGDwelling *dwelling, const CArmedInstance *dst, int level) override;
void showShipyardDialog(const IShipyard *obj) override; //obj may be town or shipyard; void showShipyardDialog(const IShipyard *obj) override; //obj may be town or shipyard;
void showBlockingDialog(const std::string &text, const std::vector<Component> &components, QueryID 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. void showBlockingDialog(const std::string &text, const std::vector<Component> &components, QueryID 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.
@ -215,11 +214,11 @@ public:
void activateForSpectator(); // TODO: spectator probably need own player interface class void activateForSpectator(); // TODO: spectator probably need own player interface class
// show dialogs // show dialogs
void showInfoDialog(const std::string &text, CComponent * component); void showInfoDialog(const std::string &text, std::shared_ptr<CComponent> component);
void showInfoDialog(const std::string &text, const std::vector<CComponent*> & components = std::vector<CComponent*>(), int soundID = 0, bool delComps = false); void showInfoDialog(const std::string &text, const std::vector<std::shared_ptr<CComponent>> & components = std::vector<std::shared_ptr<CComponent>>(), int soundID = 0);
void showInfoDialogAndWait(std::vector<Component> & components, const MetaString & text); void showInfoDialogAndWait(std::vector<Component> & components, const MetaString & text);
void showOkDialog(std::vector<Component> & components, const MetaString & text, const std::function<void()> & onOk); void showOkDialog(std::vector<Component> & components, const MetaString & text, const std::function<void()> & onOk);
void showYesNoDialog(const std::string &text, CFunctionList<void()> onYes, CFunctionList<void()> onNo, bool DelComps = false, const std::vector<CComponent*> & components = std::vector<CComponent*>()); //deactivateCur - whether current main interface should be deactivated; delComps - if components will be deleted on window close void showYesNoDialog(const std::string &text, CFunctionList<void()> onYes, CFunctionList<void()> onNo, const std::vector<std::shared_ptr<CComponent>> & components = std::vector<std::shared_ptr<CComponent>>());
void stopMovement(); void stopMovement();
void moveHero(const CGHeroInstance *h, CGPath path); void moveHero(const CGHeroInstance *h, CGPath path);

View File

@ -9,9 +9,19 @@
*/ */
#include "StdInc.h" #include "StdInc.h"
#include "CreatureCostBox.h" #include "CreatureCostBox.h"
#include "windows/CAdvmapInterface.h" #include "widgets/Images.h"
#include "widgets/TextControls.h"
#include "gui/CGuiHandler.h" #include "gui/CGuiHandler.h"
CreatureCostBox::CreatureCostBox(Rect position, std::string titleText)
{
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
type |= REDRAW_PARENT;
pos = position + pos;
title = std::make_shared<CLabel>(pos.w/2, 10, FONT_SMALL, CENTER, Colors::WHITE, titleText);
}
void CreatureCostBox::set(TResources res) void CreatureCostBox::set(TResources res)
{ {
@ -19,40 +29,27 @@ void CreatureCostBox::set(TResources res)
item.second.first->setText(boost::lexical_cast<std::string>(res[item.first])); item.second.first->setText(boost::lexical_cast<std::string>(res[item.first]));
} }
CreatureCostBox::CreatureCostBox(Rect position, std::string title)
{
type |= REDRAW_PARENT;
pos = position + pos;
OBJ_CONSTRUCTION_CAPTURING_ALL;
new CLabel(pos.w/2, 10, FONT_SMALL, CENTER, Colors::WHITE, title);
}
void CreatureCostBox::createItems(TResources res) void CreatureCostBox::createItems(TResources res)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL;
for(auto & curr : resources)
{
delete curr.second.first;
delete curr.second.second;
}
resources.clear(); resources.clear();
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
TResources::nziterator iter(res); TResources::nziterator iter(res);
while (iter.valid()) while(iter.valid())
{ {
CAnimImage * image = new CAnimImage("RESOURCE", iter->resType); ImagePtr image = std::make_shared<CAnimImage>("RESOURCE", iter->resType);
CLabel * text = new CLabel(15, 43, FONT_SMALL, CENTER, Colors::WHITE, "0"); LabelPtr text = std::make_shared<CLabel>(15, 43, FONT_SMALL, CENTER, Colors::WHITE, "0");
resources.insert(std::make_pair(iter->resType, std::make_pair(text, image))); resources.insert(std::make_pair(iter->resType, std::make_pair(text, image)));
iter++; iter++;
} }
if (!resources.empty()) if(!resources.empty())
{ {
int curx = pos.w / 2 - (16 * resources.size()) - (8 * (resources.size() - 1)); int curx = pos.w / 2 - (16 * resources.size()) - (8 * (resources.size() - 1));
//reverse to display gold as first resource //reverse to display gold as first resource
for (auto & res : boost::adaptors::reverse(resources)) for(auto & res : boost::adaptors::reverse(resources))
{ {
res.second.first->moveBy(Point(curx, 22)); res.second.first->moveBy(Point(curx, 22));
res.second.second->moveBy(Point(curx, 22)); res.second.second->moveBy(Point(curx, 22));

View File

@ -9,15 +9,22 @@
*/ */
#pragma once #pragma once
#include "widgets/Images.h"
#include "../lib/ResourceSet.h" #include "../lib/ResourceSet.h"
#include "gui/CIntObject.h"
class CLabel;
class CAnimImage;
class CreatureCostBox : public CIntObject class CreatureCostBox : public CIntObject
{ {
public: public:
void set(TResources res); void set(TResources res);
CreatureCostBox(Rect position, std::string title); CreatureCostBox(Rect position, std::string titleText);
void createItems(TResources res); void createItems(TResources res);
private: private:
std::map<int, std::pair<CLabel *, CAnimImage * > > resources; using LabelPtr = std::shared_ptr<CLabel>;
using ImagePtr = std::shared_ptr<CAnimImage>;
LabelPtr title;
std::map<int, std::pair<LabelPtr, ImagePtr>> resources;
}; };

View File

@ -264,7 +264,7 @@ void Graphics::blueToPlayersAdv(SDL_Surface * sur, PlayerColor player)
{ {
if(sur->format->palette) if(sur->format->palette)
{ {
SDL_Color *palette = nullptr; SDL_Color * palette = nullptr;
if(player < PlayerColor::PLAYER_LIMIT) if(player < PlayerColor::PLAYER_LIMIT)
{ {
palette = playerColorPalette + 32*player.getNum(); palette = playerColorPalette + 32*player.getNum();
@ -278,7 +278,44 @@ void Graphics::blueToPlayersAdv(SDL_Surface * sur, PlayerColor player)
logGlobal->error("Wrong player id in blueToPlayersAdv (%s)!", player.getStr()); logGlobal->error("Wrong player id in blueToPlayersAdv (%s)!", player.getStr());
return; return;
} }
//FIXME: not all player colored images have player palette at last 32 indexes
//NOTE: following code is much more correct but still not perfect (bugged with status bar)
SDL_SetColors(sur, palette, 224, 32); SDL_SetColors(sur, palette, 224, 32);
#if 0
SDL_Color * bluePalette = playerColorPalette + 32;
SDL_Palette * oldPalette = sur->format->palette;
SDL_Palette * newPalette = SDL_AllocPalette(256);
for(size_t destIndex = 0; destIndex < 256; destIndex++)
{
SDL_Color old = oldPalette->colors[destIndex];
bool found = false;
for(size_t srcIndex = 0; srcIndex < 32; srcIndex++)
{
if(old.b == bluePalette[srcIndex].b && old.g == bluePalette[srcIndex].g && old.r == bluePalette[srcIndex].r)
{
found = true;
newPalette->colors[destIndex] = palette[srcIndex];
break;
}
}
if(!found)
newPalette->colors[destIndex] = old;
}
SDL_SetSurfacePalette(sur, newPalette);
SDL_FreePalette(newPalette);
#endif // 0
} }
else else
{ {

View File

@ -534,15 +534,10 @@ void GiveHero::applyFirstCl(CClient *cl)
void InfoWindow::applyCl(CClient *cl) void InfoWindow::applyCl(CClient *cl)
{ {
std::vector<Component*> comps;
for(auto & elem : components)
{
comps.push_back(&elem);
}
std::string str; std::string str;
text.toString(str); text.toString(str);
if(!callInterfaceIfPresent(cl, player, &CGameInterface::showInfoDialog, str,comps,(soundBase::soundID)soundID)) if(!callInterfaceIfPresent(cl, player, &CGameInterface::showInfoDialog, str,components,(soundBase::soundID)soundID))
logNetwork->warn("We received InfoWindow for not our player..."); logNetwork->warn("We received InfoWindow for not our player...");
} }

View File

@ -803,7 +803,7 @@ void CBattleInterface::bSurrenderf()
enemyHeroName = "#ENEMY#"; //TODO: should surrendering without enemy hero be enabled? enemyHeroName = "#ENEMY#"; //TODO: should surrendering without enemy hero be enabled?
std::string surrenderMessage = boost::str(boost::format(CGI->generaltexth->allTexts[32]) % enemyHeroName % cost); //%s states: "I will accept your surrender and grant you and your troops safe passage for the price of %d gold." std::string surrenderMessage = boost::str(boost::format(CGI->generaltexth->allTexts[32]) % enemyHeroName % cost); //%s states: "I will accept your surrender and grant you and your troops safe passage for the price of %d gold."
curInt->showYesNoDialog(surrenderMessage, [this](){ reallySurrender(); }, 0, false); curInt->showYesNoDialog(surrenderMessage, [this](){ reallySurrender(); }, nullptr);
} }
} }
@ -815,11 +815,11 @@ void CBattleInterface::bFleef()
if ( curInt->cb->battleCanFlee() ) if ( curInt->cb->battleCanFlee() )
{ {
CFunctionList<void()> ony = std::bind(&CBattleInterface::reallyFlee,this); CFunctionList<void()> ony = std::bind(&CBattleInterface::reallyFlee,this);
curInt->showYesNoDialog(CGI->generaltexth->allTexts[28], ony, 0, false); //Are you sure you want to retreat? curInt->showYesNoDialog(CGI->generaltexth->allTexts[28], ony, nullptr); //Are you sure you want to retreat?
} }
else else
{ {
std::vector<CComponent*> comps; std::vector<std::shared_ptr<CComponent>> comps;
std::string heroName; std::string heroName;
//calculating fleeing hero's name //calculating fleeing hero's name
if (attackingHeroInstance) if (attackingHeroInstance)
@ -1280,8 +1280,7 @@ void CBattleInterface::displayBattleFinished()
return; return;
} }
SDL_Rect temp_rect = genRect(561, 470, (screen->w - 800)/2 + 165, (screen->h - 600)/2 + 19); resWindow = new CBattleResultWindow(*bresult, *this->curInt);
resWindow = new CBattleResultWindow(*bresult, temp_rect, *this->curInt);
GH.pushInt(resWindow); GH.pushInt(resWindow);
curInt->waitWhileDialog(); // Avoid freeze when AI end turn after battle. Check bug #1897 curInt->waitWhileDialog(); // Avoid freeze when AI end turn after battle. Check bug #1897
} }
@ -3637,7 +3636,7 @@ void CBattleInterface::updateBattleAnimations()
} }
} }
IImage * CBattleInterface::getObstacleImage(const CObstacleInstance & oi) std::shared_ptr<IImage> CBattleInterface::getObstacleImage(const CObstacleInstance & oi)
{ {
int frameIndex = (animCount+1) *25 / getAnimSpeed(); int frameIndex = (animCount+1) *25 / getAnimSpeed();
std::shared_ptr<CAnimation> animation; std::shared_ptr<CAnimation> animation;
@ -3650,7 +3649,7 @@ IImage * CBattleInterface::getObstacleImage(const CObstacleInstance & oi)
{ {
const SpellCreatedObstacle * spellObstacle = dynamic_cast<const SpellCreatedObstacle *>(&oi); const SpellCreatedObstacle * spellObstacle = dynamic_cast<const SpellCreatedObstacle *>(&oi);
if(!spellObstacle) if(!spellObstacle)
return nullptr; return std::shared_ptr<IImage>();
std::string animationName = spellObstacle->animation; std::string animationName = spellObstacle->animation;
@ -3679,7 +3678,7 @@ IImage * CBattleInterface::getObstacleImage(const CObstacleInstance & oi)
return nullptr; return nullptr;
} }
Point CBattleInterface::getObstaclePosition(IImage * image, const CObstacleInstance & obstacle) Point CBattleInterface::getObstaclePosition(std::shared_ptr<IImage> image, const CObstacleInstance & obstacle)
{ {
int offset = obstacle.getAnimationYOffset(image->height()); int offset = obstacle.getAnimationYOffset(image->height());

View File

@ -254,9 +254,9 @@ private:
BattleObjectsByHex sortObjectsByHex(); BattleObjectsByHex sortObjectsByHex();
void updateBattleAnimations(); void updateBattleAnimations();
IImage * getObstacleImage(const CObstacleInstance & oi); std::shared_ptr<IImage> getObstacleImage(const CObstacleInstance & oi);
Point getObstaclePosition(IImage * image, const CObstacleInstance & obstacle); Point getObstaclePosition(std::shared_ptr<IImage> image, const CObstacleInstance & obstacle);
void redrawBackgroundWithHexes(const CStack *activeStack); void redrawBackgroundWithHexes(const CStack *activeStack);
/** End of battle screen blitting methods */ /** End of battle screen blitting methods */

View File

@ -277,55 +277,111 @@ CBattleHero::CBattleHero(const std::string & animationPath, bool flipG, PlayerCo
CBattleHero::~CBattleHero() = default; CBattleHero::~CBattleHero() = default;
CHeroInfoWindow::CHeroInfoWindow(const InfoAboutHero & hero, Point * position)
: CWindowObject(RCLICK_POPUP | SHADOW_DISABLED, "CHRPOP")
{
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
if (position != nullptr)
moveTo(*position);
background->colorize(hero.owner); //maybe add this functionality to base class?
auto attack = hero.details->primskills[0];
auto defense = hero.details->primskills[1];
auto power = hero.details->primskills[2];
auto knowledge = hero.details->primskills[3];
auto morale = hero.details->morale;
auto luck = hero.details->luck;
auto currentSpellPoints = hero.details->mana;
auto maxSpellPoints = hero.details->manaLimit;
icons.push_back(std::make_shared<CAnimImage>("PortraitsLarge", hero.portrait, 0, 10, 6));
//primary stats
labels.push_back(std::make_shared<CLabel>(9, 75, EFonts::FONT_TINY, EAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[380] + ":"));
labels.push_back(std::make_shared<CLabel>(9, 87, EFonts::FONT_TINY, EAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[381] + ":"));
labels.push_back(std::make_shared<CLabel>(9, 99, EFonts::FONT_TINY, EAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[382] + ":"));
labels.push_back(std::make_shared<CLabel>(9, 111, EFonts::FONT_TINY, EAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[383] + ":"));
labels.push_back(std::make_shared<CLabel>(69, 87, EFonts::FONT_TINY, EAlignment::BOTTOMRIGHT, Colors::WHITE, std::to_string(attack)));
labels.push_back(std::make_shared<CLabel>(69, 99, EFonts::FONT_TINY, EAlignment::BOTTOMRIGHT, Colors::WHITE, std::to_string(defense)));
labels.push_back(std::make_shared<CLabel>(69, 111, EFonts::FONT_TINY, EAlignment::BOTTOMRIGHT, Colors::WHITE, std::to_string(power)));
labels.push_back(std::make_shared<CLabel>(69, 123, EFonts::FONT_TINY, EAlignment::BOTTOMRIGHT, Colors::WHITE, std::to_string(knowledge)));
//morale+luck
labels.push_back(std::make_shared<CLabel>(9, 131, EFonts::FONT_TINY, EAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[384] + ":"));
labels.push_back(std::make_shared<CLabel>(9, 143, EFonts::FONT_TINY, EAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[385] + ":"));
icons.push_back(std::make_shared<CAnimImage>("IMRL22", morale + 3, 0, 47, 131));
icons.push_back(std::make_shared<CAnimImage>("ILCK22", luck + 3, 0, 47, 143));
//spell points
labels.push_back(std::make_shared<CLabel>(39, 174, EFonts::FONT_TINY, EAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[387]));
labels.push_back(std::make_shared<CLabel>(39, 186, EFonts::FONT_TINY, EAlignment::CENTER, Colors::WHITE, std::to_string(currentSpellPoints) + "/" + std::to_string(maxSpellPoints)));
}
CBattleOptionsWindow::CBattleOptionsWindow(const SDL_Rect & position, CBattleInterface *owner) CBattleOptionsWindow::CBattleOptionsWindow(const SDL_Rect & position, CBattleInterface *owner)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
pos = position; pos = position;
background = new CPicture("comopbck.bmp");
background = std::make_shared<CPicture>("comopbck.bmp");
background->colorize(owner->getCurrentPlayerInterface()->playerID); background->colorize(owner->getCurrentPlayerInterface()->playerID);
viewGrid = new CToggleButton(Point(25, 56), "sysopchk.def", CGI->generaltexth->zelp[427], [=](bool on){owner->setPrintCellBorders(on);} ); auto viewGrid = std::make_shared<CToggleButton>(Point(25, 56), "sysopchk.def", CGI->generaltexth->zelp[427], [=](bool on){owner->setPrintCellBorders(on);} );
viewGrid->setSelected(settings["battle"]["cellBorders"].Bool()); viewGrid->setSelected(settings["battle"]["cellBorders"].Bool());
movementShadow = new CToggleButton(Point(25, 89), "sysopchk.def", CGI->generaltexth->zelp[428], [=](bool on){owner->setPrintStackRange(on);}); toggles.push_back(viewGrid);
movementShadow->setSelected(settings["battle"]["stackRange"].Bool());
mouseShadow = new CToggleButton(Point(25, 122), "sysopchk.def", CGI->generaltexth->zelp[429], [=](bool on){owner->setPrintMouseShadow(on);}); auto movementShadow = std::make_shared<CToggleButton>(Point(25, 89), "sysopchk.def", CGI->generaltexth->zelp[428], [=](bool on){owner->setPrintStackRange(on);});
mouseShadow->setSelected(settings["battle"]["mouseShadow"].Bool()); movementShadow->setSelected(settings["battle"]["stackRange"].Bool());
toggles.push_back(movementShadow);
auto mouseShadow = std::make_shared<CToggleButton>(Point(25, 122), "sysopchk.def", CGI->generaltexth->zelp[429], [=](bool on){owner->setPrintMouseShadow(on);});
mouseShadow->setSelected(settings["battle"]["mouseShadow"].Bool());
toggles.push_back(mouseShadow);
animSpeeds = std::make_shared<CToggleGroup>([=](int value){ owner->setAnimSpeed(value);});
std::shared_ptr<CToggleButton> toggle;
toggle = std::make_shared<CToggleButton>(Point( 28, 225), "sysopb9.def", CGI->generaltexth->zelp[422]);
animSpeeds->addToggle(40, toggle);
toggle = std::make_shared<CToggleButton>(Point( 92, 225), "sysob10.def", CGI->generaltexth->zelp[423]);
animSpeeds->addToggle(63, toggle);
toggle = std::make_shared<CToggleButton>(Point(156, 225), "sysob11.def", CGI->generaltexth->zelp[424]);
animSpeeds->addToggle(100, toggle);
animSpeeds = new CToggleGroup([=](int value){ owner->setAnimSpeed(value);});
animSpeeds->addToggle(40, new CToggleButton(Point( 28, 225), "sysopb9.def", CGI->generaltexth->zelp[422]));
animSpeeds->addToggle(63, new CToggleButton(Point( 92, 225), "sysob10.def", CGI->generaltexth->zelp[423]));
animSpeeds->addToggle(100, new CToggleButton(Point(156, 225), "sysob11.def", CGI->generaltexth->zelp[424]));
animSpeeds->setSelected(owner->getAnimSpeed()); animSpeeds->setSelected(owner->getAnimSpeed());
setToDefault = new CButton (Point(246, 359), "codefaul.def", CGI->generaltexth->zelp[393], [&](){ bDefaultf(); }); setToDefault = std::make_shared<CButton>(Point(246, 359), "codefaul.def", CGI->generaltexth->zelp[393], [&](){ bDefaultf(); });
setToDefault->setImageOrder(1, 0, 2, 3); setToDefault->setImageOrder(1, 0, 2, 3);
exit = new CButton (Point(357, 359), "soretrn.def", CGI->generaltexth->zelp[392], [&](){ bExitf();}, SDLK_RETURN); exit = std::make_shared<CButton>(Point(357, 359), "soretrn.def", CGI->generaltexth->zelp[392], [&](){ bExitf();}, SDLK_RETURN);
exit->setImageOrder(1, 0, 2, 3); exit->setImageOrder(1, 0, 2, 3);
//creating labels //creating labels
labels.push_back(new CLabel(242, 32, FONT_BIG, CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[392]));//window title labels.push_back(std::make_shared<CLabel>(242, 32, FONT_BIG, CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[392]));//window title
labels.push_back(new CLabel(122, 214, FONT_MEDIUM, CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[393]));//animation speed labels.push_back(std::make_shared<CLabel>(122, 214, FONT_MEDIUM, CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[393]));//animation speed
labels.push_back(new CLabel(122, 293, FONT_MEDIUM, CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[394]));//music volume labels.push_back(std::make_shared<CLabel>(122, 293, FONT_MEDIUM, CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[394]));//music volume
labels.push_back(new CLabel(122, 359, FONT_MEDIUM, CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[395]));//effects' volume labels.push_back(std::make_shared<CLabel>(122, 359, FONT_MEDIUM, CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[395]));//effects' volume
labels.push_back(new CLabel(353, 66, FONT_MEDIUM, CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[396]));//auto - combat options labels.push_back(std::make_shared<CLabel>(353, 66, FONT_MEDIUM, CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[396]));//auto - combat options
labels.push_back(new CLabel(353, 265, FONT_MEDIUM, CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[397]));//creature info labels.push_back(std::make_shared<CLabel>(353, 265, FONT_MEDIUM, CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[397]));//creature info
//auto - combat options //auto - combat options
labels.push_back(new CLabel(283, 86, FONT_MEDIUM, TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[398]));//creatures labels.push_back(std::make_shared<CLabel>(283, 86, FONT_MEDIUM, TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[398]));//creatures
labels.push_back(new CLabel(283, 116, FONT_MEDIUM, TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[399]));//spells labels.push_back(std::make_shared<CLabel>(283, 116, FONT_MEDIUM, TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[399]));//spells
labels.push_back(new CLabel(283, 146, FONT_MEDIUM, TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[400]));//catapult labels.push_back(std::make_shared<CLabel>(283, 146, FONT_MEDIUM, TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[400]));//catapult
labels.push_back(new CLabel(283, 176, FONT_MEDIUM, TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[151]));//ballista labels.push_back(std::make_shared<CLabel>(283, 176, FONT_MEDIUM, TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[151]));//ballista
labels.push_back(new CLabel(283, 206, FONT_MEDIUM, TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[401]));//first aid tent labels.push_back(std::make_shared<CLabel>(283, 206, FONT_MEDIUM, TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[401]));//first aid tent
//creature info //creature info
labels.push_back(new CLabel(283, 285, FONT_MEDIUM, TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[402]));//all stats labels.push_back(std::make_shared<CLabel>(283, 285, FONT_MEDIUM, TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[402]));//all stats
labels.push_back(new CLabel(283, 315, FONT_MEDIUM, TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[403]));//spells only labels.push_back(std::make_shared<CLabel>(283, 315, FONT_MEDIUM, TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[403]));//spells only
//general options //general options
labels.push_back(new CLabel(61, 57, FONT_MEDIUM, TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[404])); labels.push_back(std::make_shared<CLabel>(61, 57, FONT_MEDIUM, TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[404]));
labels.push_back(new CLabel(61, 90, FONT_MEDIUM, TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[405])); labels.push_back(std::make_shared<CLabel>(61, 90, FONT_MEDIUM, TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[405]));
labels.push_back(new CLabel(61, 123, FONT_MEDIUM, TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[406])); labels.push_back(std::make_shared<CLabel>(61, 123, FONT_MEDIUM, TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[406]));
labels.push_back(new CLabel(61, 156, FONT_MEDIUM, TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[407])); labels.push_back(std::make_shared<CLabel>(61, 156, FONT_MEDIUM, TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[407]));
} }
void CBattleOptionsWindow::bDefaultf() void CBattleOptionsWindow::bDefaultf()
@ -338,31 +394,32 @@ void CBattleOptionsWindow::bExitf()
GH.popIntTotally(this); GH.popIntTotally(this);
} }
CBattleResultWindow::CBattleResultWindow(const BattleResult &br, const SDL_Rect & pos, CPlayerInterface &_owner) CBattleResultWindow::CBattleResultWindow(const BattleResult & br, CPlayerInterface & _owner)
: owner(_owner) : owner(_owner)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
this->pos = pos;
CPicture * bg = new CPicture("CPRESULT");
bg->colorize(owner.playerID);
exit = new CButton (Point(384, 505), "iok6432.def", std::make_pair("", ""), [&](){ bExitf();}, SDLK_RETURN); pos = genRect(561, 470, (screen->w - 800)/2 + 165, (screen->h - 600)/2 + 19);
background = std::make_shared<CPicture>("CPRESULT");
background->colorize(owner.playerID);
exit = std::make_shared<CButton>(Point(384, 505), "iok6432.def", std::make_pair("", ""), [&](){ bExitf();}, SDLK_RETURN);
exit->setBorderColor(Colors::METALLIC_GOLD); exit->setBorderColor(Colors::METALLIC_GOLD);
if(br.winner==0) //attacker won if(br.winner==0) //attacker won
{ {
new CLabel( 59, 124, FONT_SMALL, CENTER, Colors::WHITE, CGI->generaltexth->allTexts[410]); labels.push_back(std::make_shared<CLabel>(59, 124, FONT_SMALL, CENTER, Colors::WHITE, CGI->generaltexth->allTexts[410]));
new CLabel(408, 124, FONT_SMALL, CENTER, Colors::WHITE, CGI->generaltexth->allTexts[411]); labels.push_back(std::make_shared<CLabel>(408, 124, FONT_SMALL, CENTER, Colors::WHITE, CGI->generaltexth->allTexts[411]));
} }
else //if(br.winner==1) else //if(br.winner==1)
{ {
new CLabel( 59, 124, FONT_SMALL, CENTER, Colors::WHITE, CGI->generaltexth->allTexts[411]); labels.push_back(std::make_shared<CLabel>(59, 124, FONT_SMALL, CENTER, Colors::WHITE, CGI->generaltexth->allTexts[411]));
new CLabel(412, 124, FONT_SMALL, CENTER, Colors::WHITE, CGI->generaltexth->allTexts[410]); labels.push_back(std::make_shared<CLabel>(412, 124, FONT_SMALL, CENTER, Colors::WHITE, CGI->generaltexth->allTexts[410]));
} }
new CLabel(232, 302, FONT_BIG, CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[407]); labels.push_back(std::make_shared<CLabel>(232, 302, FONT_BIG, CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[407]));
new CLabel(232, 332, FONT_SMALL, CENTER, Colors::WHITE, CGI->generaltexth->allTexts[408]); labels.push_back(std::make_shared<CLabel>(232, 332, FONT_SMALL, CENTER, Colors::WHITE, CGI->generaltexth->allTexts[408]));
new CLabel(232, 428, FONT_SMALL, CENTER, Colors::WHITE, CGI->generaltexth->allTexts[409]); labels.push_back(std::make_shared<CLabel>(232, 428, FONT_SMALL, CENTER, Colors::WHITE, CGI->generaltexth->allTexts[409]));
std::string sideNames[2] = {"N/A", "N/A"}; std::string sideNames[2] = {"N/A", "N/A"};
@ -373,45 +430,51 @@ CBattleResultWindow::CBattleResultWindow(const BattleResult &br, const SDL_Rect
if(heroInfo.portrait >= 0) //attacking hero if(heroInfo.portrait >= 0) //attacking hero
{ {
new CAnimImage("PortraitsLarge", heroInfo.portrait, 0, xs[i], 38); icons.push_back(std::make_shared<CAnimImage>("PortraitsLarge", heroInfo.portrait, 0, xs[i], 38));
sideNames[i] = heroInfo.name; sideNames[i] = heroInfo.name;
} }
else else
{ {
auto stacks = owner.cb->battleGetAllStacks(); auto stacks = owner.cb->battleGetAllStacks();
vstd::erase_if(stacks, [i](const CStack *stack) //erase stack of other side and not coming from garrison vstd::erase_if(stacks, [i](const CStack * stack) //erase stack of other side and not coming from garrison
{ return stack->side != i || !stack->base; }); {
return stack->side != i || !stack->base;
});
auto best = vstd::maxElementByFun(stacks, [](const CStack * stack)
{
return stack->type->AIValue;
});
auto best = vstd::maxElementByFun(stacks, [](const CStack *stack){ return stack->type->AIValue; });
if(best != stacks.end()) //should be always but to be safe... if(best != stacks.end()) //should be always but to be safe...
{ {
new CAnimImage("TWCRPORT", (*best)->type->idNumber+2, 0, xs[i], 38); icons.push_back(std::make_shared<CAnimImage>("TWCRPORT", (*best)->type->idNumber+2, 0, xs[i], 38));
sideNames[i] = CGI->creh->creatures[(*best)->type->idNumber]->namePl; sideNames[i] = CGI->creh->creatures[(*best)->type->idNumber]->namePl;
} }
} }
} }
//printing attacker and defender's names //printing attacker and defender's names
new CLabel( 89, 37, FONT_SMALL, TOPLEFT, Colors::WHITE, sideNames[0]); labels.push_back(std::make_shared<CLabel>(89, 37, FONT_SMALL, TOPLEFT, Colors::WHITE, sideNames[0]));
new CLabel( 381, 53, FONT_SMALL, BOTTOMRIGHT, Colors::WHITE, sideNames[1]); labels.push_back(std::make_shared<CLabel>(381, 53, FONT_SMALL, BOTTOMRIGHT, Colors::WHITE, sideNames[1]));
//printing casualties //printing casualties
for(int step = 0; step < 2; ++step) for(int step = 0; step < 2; ++step)
{ {
if(br.casualties[step].size()==0) if(br.casualties[step].size()==0)
{ {
new CLabel( 235, 360 + 97*step, FONT_SMALL, CENTER, Colors::WHITE, CGI->generaltexth->allTexts[523]); labels.push_back(std::make_shared<CLabel>(235, 360 + 97 * step, FONT_SMALL, CENTER, Colors::WHITE, CGI->generaltexth->allTexts[523]));
} }
else else
{ {
int xPos = 235 - (br.casualties[step].size()*32 + (br.casualties[step].size() - 1)*10)/2; //increment by 42 with each picture int xPos = 235 - (br.casualties[step].size()*32 + (br.casualties[step].size() - 1)*10)/2; //increment by 42 with each picture
int yPos = 344 + step*97; int yPos = 344 + step * 97;
for(auto & elem : br.casualties[step]) for(auto & elem : br.casualties[step])
{ {
new CAnimImage("CPRSMALL", CGI->creh->creatures[elem.first]->iconIndex, 0, xPos, yPos); icons.push_back(std::make_shared<CAnimImage>("CPRSMALL", CGI->creh->creatures[elem.first]->iconIndex, 0, xPos, yPos));
std::ostringstream amount; std::ostringstream amount;
amount<<elem.second; amount<<elem.second;
new CLabel( xPos+16, yPos + 42, FONT_SMALL, CENTER, Colors::WHITE, amount.str()); labels.push_back(std::make_shared<CLabel>(xPos + 16, yPos + 42, FONT_SMALL, CENTER, Colors::WHITE, amount.str()));
xPos += 42; xPos += 42;
} }
} }
@ -420,12 +483,20 @@ CBattleResultWindow::CBattleResultWindow(const BattleResult &br, const SDL_Rect
bool weAreAttacker = !(owner.cb->battleGetMySide()); bool weAreAttacker = !(owner.cb->battleGetMySide());
if((br.winner == 0 && weAreAttacker) || (br.winner == 1 && !weAreAttacker)) //we've won if((br.winner == 0 && weAreAttacker) || (br.winner == 1 && !weAreAttacker)) //we've won
{ {
int text=-1; int text = 304;
switch(br.result) switch(br.result)
{ {
case BattleResult::NORMAL: text = 304; break; case BattleResult::NORMAL:
case BattleResult::ESCAPE: text = 303; break; break;
case BattleResult::SURRENDER: text = 302; break; case BattleResult::ESCAPE:
text = 303;
break;
case BattleResult::SURRENDER:
text = 302;
break;
default:
logGlobal->error("Invalid battle result code %d. Assumed normal.", static_cast<int>(br.result));
break;
} }
CCS->musich->playMusic("Music/Win Battle", false); CCS->musich->playMusic("Music/Win Battle", false);
@ -436,44 +507,43 @@ CBattleResultWindow::CBattleResultWindow(const BattleResult &br, const SDL_Rect
if (ourHero) if (ourHero)
{ {
str += CGI->generaltexth->allTexts[305]; str += CGI->generaltexth->allTexts[305];
boost::algorithm::replace_first(str,"%s",ourHero->name); boost::algorithm::replace_first(str, "%s", ourHero->name);
boost::algorithm::replace_first(str,"%d",boost::lexical_cast<std::string>(br.exp[weAreAttacker?0:1])); boost::algorithm::replace_first(str, "%d", boost::lexical_cast<std::string>(br.exp[weAreAttacker ? 0 : 1]));
} }
new CTextBox(str, Rect(69, 203, 330, 68), 0, FONT_SMALL, CENTER, Colors::WHITE); description = std::make_shared<CTextBox>(str, Rect(69, 203, 330, 68), 0, FONT_SMALL, CENTER, Colors::WHITE);
} }
else // we lose else // we lose
{ {
int text = 311;
std::string musicName = "Music/LoseCombat";
std::string videoName = "LBSTART.BIK";
switch(br.result) switch(br.result)
{ {
case BattleResult::NORMAL: case BattleResult::NORMAL:
{ break;
CCS->musich->playMusic("Music/LoseCombat", false); case BattleResult::ESCAPE:
CCS->videoh->open("LBSTART.BIK"); musicName = "Music/Retreat Battle";
new CLabel(235, 235, FONT_SMALL, CENTER, Colors::WHITE, CGI->generaltexth->allTexts[311]); videoName = "RTSTART.BIK";
break; text = 310;
} break;
case BattleResult::ESCAPE: //flee
{
CCS->musich->playMusic("Music/Retreat Battle", false);
CCS->videoh->open("RTSTART.BIK");
new CLabel(235, 235, FONT_SMALL, CENTER, Colors::WHITE, CGI->generaltexth->allTexts[310]);
break;
}
case BattleResult::SURRENDER: case BattleResult::SURRENDER:
{ musicName = "Music/Surrender Battle";
CCS->musich->playMusic("Music/Surrender Battle", false); videoName = "SURRENDER.BIK";
CCS->videoh->open("SURRENDER.BIK"); text = 309;
new CLabel(235, 235, FONT_SMALL, CENTER, Colors::WHITE, CGI->generaltexth->allTexts[309]); break;
break; default:
} logGlobal->error("Invalid battle result code %d. Assumed normal.", static_cast<int>(br.result));
break;
} }
CCS->musich->playMusic(musicName, false);
CCS->videoh->open(videoName);
labels.push_back(std::make_shared<CLabel>(235, 235, FONT_SMALL, CENTER, Colors::WHITE, CGI->generaltexth->allTexts[text]));
} }
} }
CBattleResultWindow::~CBattleResultWindow() CBattleResultWindow::~CBattleResultWindow() = default;
{
}
void CBattleResultWindow::activate() void CBattleResultWindow::activate()
{ {
@ -628,52 +698,11 @@ void CClickableHex::clickRight(tribool down, bool previousState)
} }
} }
CHeroInfoWindow::CHeroInfoWindow(const InfoAboutHero &hero, Point *position) : CWindowObject(RCLICK_POPUP | SHADOW_DISABLED, "CHRPOP")
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
if (position != nullptr)
moveTo(*position);
background->colorize(hero.owner); //maybe add this functionality to base class?
int attack = hero.details->primskills[0];
int defense = hero.details->primskills[1];
int power = hero.details->primskills[2];
int knowledge = hero.details->primskills[3];
int morale = hero.details->morale;
int luck = hero.details->luck;
int currentSpellPoints = hero.details->mana;
int maxSpellPoints = hero.details->manaLimit;
new CAnimImage("PortraitsLarge", hero.portrait, 0, 10, 6);
//primary stats
new CLabel(9, 75, EFonts::FONT_TINY, EAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[380] + ":");
new CLabel(9, 87, EFonts::FONT_TINY, EAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[381] + ":");
new CLabel(9, 99, EFonts::FONT_TINY, EAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[382] + ":");
new CLabel(9, 111, EFonts::FONT_TINY, EAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[383] + ":");
new CLabel(69, 87, EFonts::FONT_TINY, EAlignment::BOTTOMRIGHT, Colors::WHITE, std::to_string(attack));
new CLabel(69, 99, EFonts::FONT_TINY, EAlignment::BOTTOMRIGHT, Colors::WHITE, std::to_string(defense));
new CLabel(69, 111, EFonts::FONT_TINY, EAlignment::BOTTOMRIGHT, Colors::WHITE, std::to_string(power));
new CLabel(69, 123, EFonts::FONT_TINY, EAlignment::BOTTOMRIGHT, Colors::WHITE, std::to_string(knowledge));
//morale+luck
new CLabel(9, 131, EFonts::FONT_TINY, EAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[384] + ":");
new CLabel(9, 143, EFonts::FONT_TINY, EAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[385] + ":");
new CAnimImage("IMRL22", morale + 3, 0, 47, 131);
new CAnimImage("ILCK22", luck + 3, 0, 47, 143);
//spell points
new CLabel(39, 174, EFonts::FONT_TINY, EAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[387]);
new CLabel(39, 186, EFonts::FONT_TINY, EAlignment::CENTER, Colors::WHITE, std::to_string(currentSpellPoints) + "/" + std::to_string(maxSpellPoints));
}
CStackQueue::CStackQueue(bool Embedded, CBattleInterface * _owner) CStackQueue::CStackQueue(bool Embedded, CBattleInterface * _owner)
: embedded(Embedded), : embedded(Embedded),
owner(_owner) owner(_owner)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
if(embedded) if(embedded)
{ {
pos.w = QUEUE_SIZE * 37; pos.w = QUEUE_SIZE * 37;
@ -689,7 +718,7 @@ CStackQueue::CStackQueue(bool Embedded, CBattleInterface * _owner)
pos.w = 800; pos.w = 800;
pos.h = 85; pos.h = 85;
new CFilledTexture("DIBOXBCK", Rect(0,0, pos.w, pos.h)); background = std::make_shared<CFilledTexture>("DIBOXBCK", Rect(0, 0, pos.w, pos.h));
icons = std::make_shared<CAnimation>("TWCRPORT"); icons = std::make_shared<CAnimation>("TWCRPORT");
stateIcons = std::make_shared<CAnimation>("VCMI/BATTLEQUEUE/STATESSMALL"); stateIcons = std::make_shared<CAnimation>("VCMI/BATTLEQUEUE/STATESSMALL");
@ -701,14 +730,12 @@ CStackQueue::CStackQueue(bool Embedded, CBattleInterface * _owner)
stackBoxes.resize(QUEUE_SIZE); stackBoxes.resize(QUEUE_SIZE);
for (int i = 0; i < stackBoxes.size(); i++) for (int i = 0; i < stackBoxes.size(); i++)
{ {
stackBoxes[i] = new StackBox(this); stackBoxes[i] = std::make_shared<StackBox>(this);
stackBoxes[i]->moveBy(Point(1 + (embedded ? 36 : 80)*i, 0)); stackBoxes[i]->moveBy(Point(1 + (embedded ? 36 : 80) * i, 0));
} }
} }
CStackQueue::~CStackQueue() CStackQueue::~CStackQueue() = default;
{
}
void CStackQueue::update() void CStackQueue::update()
{ {
@ -721,60 +748,56 @@ void CStackQueue::update()
for(size_t turn = 0; turn < queueData.size() && boxIndex < stackBoxes.size(); turn++) for(size_t turn = 0; turn < queueData.size() && boxIndex < stackBoxes.size(); turn++)
{ {
for(size_t unitIndex = 0; unitIndex < queueData[turn].size() && boxIndex < stackBoxes.size(); boxIndex++, unitIndex++) for(size_t unitIndex = 0; unitIndex < queueData[turn].size() && boxIndex < stackBoxes.size(); boxIndex++, unitIndex++)
stackBoxes[boxIndex]->setStack(queueData[turn][unitIndex], turn); stackBoxes[boxIndex]->setUnit(queueData[turn][unitIndex], turn);
} }
for(; boxIndex < stackBoxes.size(); boxIndex++) for(; boxIndex < stackBoxes.size(); boxIndex++)
stackBoxes[boxIndex]->setStack(nullptr); stackBoxes[boxIndex]->setUnit(nullptr);
} }
CStackQueue::StackBox::StackBox(CStackQueue * owner) CStackQueue::StackBox::StackBox(CStackQueue * owner)
: bg(nullptr),
icon(nullptr),
amount(nullptr),
stateIcon(nullptr)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
bg = new CPicture(owner->embedded ? "StackQueueSmall" : "StackQueueLarge" ); background = std::make_shared<CPicture>(owner->embedded ? "StackQueueSmall" : "StackQueueLarge");
pos.w = bg->pos.w; pos.w = background->pos.w;
pos.h = bg->pos.h; pos.h = background->pos.h;
if(owner->embedded) if(owner->embedded)
{ {
icon = new CAnimImage(owner->icons, 0, 0, 5, 2); icon = std::make_shared<CAnimImage>(owner->icons, 0, 0, 5, 2);
amount = new CLabel(pos.w/2, pos.h - 7, FONT_SMALL, CENTER, Colors::WHITE); amount = std::make_shared<CLabel>(pos.w/2, pos.h - 7, FONT_SMALL, CENTER, Colors::WHITE);
} }
else else
{ {
icon = new CAnimImage(owner->icons, 0, 0, 9, 1); icon = std::make_shared<CAnimImage>(owner->icons, 0, 0, 9, 1);
amount = new CLabel(pos.w/2, pos.h - 8, FONT_MEDIUM, CENTER, Colors::WHITE); amount = std::make_shared<CLabel>(pos.w/2, pos.h - 8, FONT_MEDIUM, CENTER, Colors::WHITE);
int icon_x = pos.w - 17; int icon_x = pos.w - 17;
int icon_y = pos.h - 18; int icon_y = pos.h - 18;
stateIcon = new CAnimImage(owner->stateIcons, 0, 0, icon_x, icon_y); stateIcon = std::make_shared<CAnimImage>(owner->stateIcons, 0, 0, icon_x, icon_y);
stateIcon->visible = false; stateIcon->visible = false;
} }
} }
void CStackQueue::StackBox::setStack(const battle::Unit * nStack, size_t turn) void CStackQueue::StackBox::setUnit(const battle::Unit * unit, size_t turn)
{ {
if(nStack) if(unit)
{ {
bg->colorize(nStack->unitOwner()); background->colorize(unit->unitOwner());
icon->visible = true; icon->visible = true;
icon->setFrame(nStack->creatureIconIndex()); icon->setFrame(unit->creatureIconIndex());
amount->setText(makeNumberShort(nStack->getCount())); amount->setText(makeNumberShort(unit->getCount()));
if(stateIcon) if(stateIcon)
{ {
if(nStack->defended(turn) || (turn > 0 && nStack->defended(turn - 1))) if(unit->defended(turn) || (turn > 0 && unit->defended(turn - 1)))
{ {
stateIcon->setFrame(0, 0); stateIcon->setFrame(0, 0);
stateIcon->visible = true; stateIcon->visible = true;
} }
else if(nStack->waited(turn)) else if(unit->waited(turn))
{ {
stateIcon->setFrame(1, 0); stateIcon->setFrame(1, 0);
stateIcon->visible = true; stateIcon->visible = true;
@ -787,7 +810,7 @@ void CStackQueue::StackBox::setStack(const battle::Unit * nStack, size_t turn)
} }
else else
{ {
bg->colorize(PlayerColor::NEUTRAL); background->colorize(PlayerColor::NEUTRAL);
icon->visible = false; icon->visible = false;
icon->setFrame(0); icon->setFrame(0);
amount->setText(""); amount->setText("");

View File

@ -17,10 +17,12 @@ struct SDL_Surface;
class CGHeroInstance; class CGHeroInstance;
class CBattleInterface; class CBattleInterface;
class CPicture; class CPicture;
class CFilledTexture;
class CButton; class CButton;
class CToggleButton; class CToggleButton;
class CToggleGroup; class CToggleGroup;
class CLabel; class CLabel;
class CTextBox;
struct BattleResult; struct BattleResult;
class CStack; class CStack;
namespace battle namespace battle
@ -79,22 +81,25 @@ public:
class CHeroInfoWindow : public CWindowObject class CHeroInfoWindow : public CWindowObject
{ {
private:
std::vector<std::shared_ptr<CLabel>> labels;
std::vector<std::shared_ptr<CAnimImage>> icons;
public: public:
CHeroInfoWindow(const InfoAboutHero &hero, Point *position); CHeroInfoWindow(const InfoAboutHero & hero, Point * position);
}; };
/// Class which manages the battle options window /// Class which manages the battle options window
class CBattleOptionsWindow : public CIntObject class CBattleOptionsWindow : public CIntObject
{ {
private: private:
CPicture * background; std::shared_ptr<CPicture> background;
CButton * setToDefault, * exit; std::shared_ptr<CButton> setToDefault;
CToggleButton * viewGrid, * movementShadow, * mouseShadow; std::shared_ptr<CButton> exit;
CToggleGroup * animSpeeds; std::shared_ptr<CToggleGroup> animSpeeds;
std::vector<std::shared_ptr<CLabel>> labels;
std::vector<CLabel*> labels; std::vector<std::shared_ptr<CToggleButton>> toggles;
public: public:
CBattleOptionsWindow(const SDL_Rect &position, CBattleInterface *owner); CBattleOptionsWindow(const SDL_Rect & position, CBattleInterface * owner);
void bDefaultf(); //default button callback void bDefaultf(); //default button callback
void bExitf(); //exit button callback void bExitf(); //exit button callback
@ -104,10 +109,14 @@ public:
class CBattleResultWindow : public CIntObject class CBattleResultWindow : public CIntObject
{ {
private: private:
CButton *exit; std::shared_ptr<CPicture> background;
CPlayerInterface &owner; std::vector<std::shared_ptr<CLabel>> labels;
std::shared_ptr<CButton> exit;
std::vector<std::shared_ptr<CAnimImage>> icons;
std::shared_ptr<CTextBox> description;
CPlayerInterface & owner;
public: public:
CBattleResultWindow(const BattleResult & br, const SDL_Rect & pos, CPlayerInterface &_owner); CBattleResultWindow(const BattleResult & br, CPlayerInterface & _owner);
~CBattleResultWindow(); ~CBattleResultWindow();
void bExitf(); //exit button callback void bExitf(); //exit button callback
@ -143,24 +152,26 @@ class CStackQueue : public CIntObject
class StackBox : public CIntObject class StackBox : public CIntObject
{ {
public: public:
CPicture * bg; std::shared_ptr<CPicture> background;
CAnimImage * icon; std::shared_ptr<CAnimImage> icon;
CLabel * amount; std::shared_ptr<CLabel> amount;
CAnimImage * stateIcon; std::shared_ptr<CAnimImage> stateIcon;
void setStack(const battle::Unit * nStack, size_t turn = 0); void setUnit(const battle::Unit * unit, size_t turn = 0);
StackBox(CStackQueue * owner); StackBox(CStackQueue * owner);
}; };
public:
static const int QUEUE_SIZE = 10; static const int QUEUE_SIZE = 10;
const bool embedded; std::shared_ptr<CFilledTexture> background;
std::vector<StackBox *> stackBoxes; std::vector<std::shared_ptr<StackBox>> stackBoxes;
CBattleInterface * owner; CBattleInterface * owner;
std::shared_ptr<CAnimation> icons; std::shared_ptr<CAnimation> icons;
std::shared_ptr<CAnimation> stateIcons; std::shared_ptr<CAnimation> stateIcons;
public:
const bool embedded;
CStackQueue(bool Embedded, CBattleInterface * _owner); CStackQueue(bool Embedded, CBattleInterface * _owner);
~CStackQueue(); ~CStackQueue();
void update(); void update();

View File

@ -286,7 +286,7 @@ void CCreatureAnimation::nextFrame(SDL_Surface * dest, bool attacker)
{ {
size_t frame = floor(currentFrame); size_t frame = floor(currentFrame);
IImage * image = nullptr; std::shared_ptr<IImage> image;
if(attacker) if(attacker)
image = forward->getImage(frame, type); image = forward->getImage(frame, type);

View File

@ -90,7 +90,7 @@ public:
void draw(SDL_Surface * where, int posX=0, int posY=0, Rect *src=nullptr, ui8 alpha=255) const override; void draw(SDL_Surface * where, int posX=0, int posY=0, Rect *src=nullptr, ui8 alpha=255) const override;
void draw(SDL_Surface * where, SDL_Rect * dest, SDL_Rect * src, ui8 alpha=255) const override; void draw(SDL_Surface * where, SDL_Rect * dest, SDL_Rect * src, ui8 alpha=255) const override;
std::unique_ptr<IImage> scaleFast(float scale) const override; std::shared_ptr<IImage> scaleFast(float scale) const override;
void exportBitmap(const boost::filesystem::path & path) const override; void exportBitmap(const boost::filesystem::path & path) const override;
void playerColored(PlayerColor player) override; void playerColored(PlayerColor player) override;
void setFlagColor(PlayerColor player) override; void setFlagColor(PlayerColor player) override;
@ -148,7 +148,7 @@ public:
void draw(SDL_Surface *where, int posX=0, int posY=0, Rect *src=nullptr, ui8 alpha=255) const override; void draw(SDL_Surface *where, int posX=0, int posY=0, Rect *src=nullptr, ui8 alpha=255) const override;
void draw(SDL_Surface * where, SDL_Rect * dest, SDL_Rect * src, ui8 alpha=255) const override; void draw(SDL_Surface * where, SDL_Rect * dest, SDL_Rect * src, ui8 alpha=255) const override;
std::unique_ptr<IImage> scaleFast(float scale) const override; std::shared_ptr<IImage> scaleFast(float scale) const override;
void exportBitmap(const boost::filesystem::path & path) const override; void exportBitmap(const boost::filesystem::path & path) const override;
@ -801,22 +801,9 @@ CompImageLoader::~CompImageLoader()
* Classes for images, support loading from file and drawing on surface * * Classes for images, support loading from file and drawing on surface *
*************************************************************************/ *************************************************************************/
IImage::IImage(): IImage::IImage() = default;
refCount(1) IImage::~IImage() = default;
{
}
bool IImage::decreaseRef()
{
refCount--;
return refCount <= 0;
}
void IImage::increaseRef()
{
refCount++;
}
SDLImage::SDLImage(CDefFile * data, size_t frame, size_t group, bool compressed) SDLImage::SDLImage(CDefFile * data, size_t frame, size_t group, bool compressed)
: surf(nullptr), : surf(nullptr),
@ -957,7 +944,7 @@ void SDLImage::draw(SDL_Surface* where, SDL_Rect* dest, SDL_Rect* src, ui8 alpha
} }
} }
std::unique_ptr<IImage> SDLImage::scaleFast(float scale) const std::shared_ptr<IImage> SDLImage::scaleFast(float scale) const
{ {
auto scaled = CSDL_Ext::scaleSurfaceFast(surf, surf->w * scale, surf->h * scale); auto scaled = CSDL_Ext::scaleSurfaceFast(surf, surf->w * scale, surf->h * scale);
@ -976,7 +963,7 @@ std::unique_ptr<IImage> SDLImage::scaleFast(float scale) const
ret->margins.x = (int) round((float)margins.x * scale); ret->margins.x = (int) round((float)margins.x * scale);
ret->margins.y = (int) round((float)margins.y * scale); ret->margins.y = (int) round((float)margins.y * scale);
return std::unique_ptr<IImage>(ret); return std::shared_ptr<IImage>(ret);
} }
void SDLImage::exportBitmap(const boost::filesystem::path& path) const void SDLImage::exportBitmap(const boost::filesystem::path& path) const
@ -1156,7 +1143,7 @@ void CompImage::draw(SDL_Surface* where, SDL_Rect* dest, SDL_Rect* src, ui8 alph
} }
std::unique_ptr<IImage> CompImage::scaleFast(float scale) const std::shared_ptr<IImage> CompImage::scaleFast(float scale) const
{ {
//todo: CompImage::scaleFast //todo: CompImage::scaleFast
@ -1331,7 +1318,7 @@ void CompImage::exportBitmap(const boost::filesystem::path & path) const
* CAnimation for animations handling, can load part of file if needed * * CAnimation for animations handling, can load part of file if needed *
*************************************************************************/ *************************************************************************/
IImage * CAnimation::getFromExtraDef(std::string filename) std::shared_ptr<IImage> CAnimation::getFromExtraDef(std::string filename)
{ {
size_t pos = filename.find(':'); size_t pos = filename.find(':');
if (pos == -1) if (pos == -1)
@ -1364,7 +1351,6 @@ bool CAnimation::loadFrame(size_t frame, size_t group)
auto image = getImage(frame, group, false); auto image = getImage(frame, group, false);
if(image) if(image)
{ {
image->increaseRef();
return true; return true;
} }
@ -1378,22 +1364,22 @@ bool CAnimation::loadFrame(size_t frame, size_t group)
if(vstd::contains(frameList, group) && frameList.at(group) > frame) // frame is present if(vstd::contains(frameList, group) && frameList.at(group) > frame) // frame is present
{ {
if(compressed) if(compressed)
images[group][frame] = new CompImage(defFile, frame, group); images[group][frame] = std::make_shared<CompImage>(defFile, frame, group);
else else
images[group][frame] = new SDLImage(defFile, frame, group); images[group][frame] = std::make_shared<SDLImage>(defFile, frame, group);
return true; return true;
} }
} }
// still here? image is missing // still here? image is missing
printError(frame, group, "LoadFrame"); printError(frame, group, "LoadFrame");
images[group][frame] = new SDLImage("DEFAULT", compressed); images[group][frame] = std::make_shared<SDLImage>("DEFAULT", compressed);
} }
else //load from separate file else //load from separate file
{ {
auto img = getFromExtraDef(source[group][frame]["file"].String()); auto img = getFromExtraDef(source[group][frame]["file"].String());
if(!img) if(!img)
img = new SDLImage(source[group][frame]); img = std::make_shared<SDLImage>(source[group][frame]);
images[group][frame] = img; images[group][frame] = img;
return true; return true;
@ -1404,15 +1390,11 @@ bool CAnimation::loadFrame(size_t frame, size_t group)
bool CAnimation::unloadFrame(size_t frame, size_t group) bool CAnimation::unloadFrame(size_t frame, size_t group)
{ {
auto image = getImage(frame, group, false); auto image = getImage(frame, group, false);
if (image) if(image)
{ {
//decrease ref count for image and delete if needed images[group].erase(frame);
if (image->decreaseRef())
{ if(images[group].empty())
delete image;
images[group].erase(frame);
}
if (images[group].empty())
images.erase(group); images.erase(group);
return true; return true;
} }
@ -1558,16 +1540,6 @@ CAnimation::CAnimation():
CAnimation::~CAnimation() CAnimation::~CAnimation()
{ {
if(preloaded)
unload();
if(!images.empty())
{
logGlobal->warn("Warning: not all frames were unloaded from %s", name);
for (auto & elem : images)
for (auto & _image : elem.second)
delete _image.second;
}
if(defFile) if(defFile)
delete defFile; delete defFile;
} }
@ -1599,7 +1571,7 @@ void CAnimation::setCustom(std::string filename, size_t frame, size_t group)
//FIXME: update image if already loaded //FIXME: update image if already loaded
} }
IImage * CAnimation::getImage(size_t frame, size_t group, bool verbose) const std::shared_ptr<IImage> CAnimation::getImage(size_t frame, size_t group, bool verbose) const
{ {
auto groupIter = images.find(group); auto groupIter = images.find(group);
if (groupIter != images.end()) if (groupIter != images.end())

View File

@ -22,7 +22,6 @@ class CDefFile;
*/ */
class IImage class IImage
{ {
int refCount;
public: public:
using BorderPallete = std::array<SDL_Color, 3>; using BorderPallete = std::array<SDL_Color, 3>;
@ -30,14 +29,10 @@ public:
virtual void draw(SDL_Surface * where, int posX = 0, int posY = 0, Rect * src = nullptr, ui8 alpha = 255) const=0; virtual void draw(SDL_Surface * where, int posX = 0, int posY = 0, Rect * src = nullptr, ui8 alpha = 255) const=0;
virtual void draw(SDL_Surface * where, SDL_Rect * dest, SDL_Rect * src, ui8 alpha = 255) const = 0; virtual void draw(SDL_Surface * where, SDL_Rect * dest, SDL_Rect * src, ui8 alpha = 255) const = 0;
virtual std::unique_ptr<IImage> scaleFast(float scale) const = 0; virtual std::shared_ptr<IImage> scaleFast(float scale) const = 0;
virtual void exportBitmap(const boost::filesystem::path & path) const = 0; virtual void exportBitmap(const boost::filesystem::path & path) const = 0;
//decrease ref count, returns true if image can be deleted (refCount <= 0)
bool decreaseRef();
void increaseRef();
//Change palette to specific player //Change palette to specific player
virtual void playerColored(PlayerColor player)=0; virtual void playerColored(PlayerColor player)=0;
@ -57,7 +52,7 @@ public:
virtual void verticalFlip() = 0; virtual void verticalFlip() = 0;
IImage(); IImage();
virtual ~IImage() {}; virtual ~IImage();
}; };
/// Class for handling animation /// Class for handling animation
@ -68,7 +63,7 @@ private:
std::map<size_t, std::vector <JsonNode> > source; std::map<size_t, std::vector <JsonNode> > source;
//bitmap[group][position], store objects with loaded bitmaps //bitmap[group][position], store objects with loaded bitmaps
std::map<size_t, std::map<size_t, IImage* > > images; std::map<size_t, std::map<size_t, std::shared_ptr<IImage> > > images;
//animation file name //animation file name
std::string name; std::string name;
@ -95,7 +90,7 @@ private:
//not a very nice method to get image from another def file //not a very nice method to get image from another def file
//TODO: remove after implementing resource manager //TODO: remove after implementing resource manager
IImage * getFromExtraDef(std::string filename); std::shared_ptr<IImage> getFromExtraDef(std::string filename);
public: public:
CAnimation(std::string Name, bool Compressed = false); CAnimation(std::string Name, bool Compressed = false);
@ -109,8 +104,7 @@ public:
//add custom surface to the selected position. //add custom surface to the selected position.
void setCustom(std::string filename, size_t frame, size_t group=0); void setCustom(std::string filename, size_t frame, size_t group=0);
//get pointer to image from specific group, nullptr if not found std::shared_ptr<IImage> getImage(size_t frame, size_t group=0, bool verbose=true) const;
IImage * getImage(size_t frame, size_t group=0, bool verbose=true) const;
void exportBitmaps(const boost::filesystem::path & path) const; void exportBitmaps(const boost::filesystem::path & path) const;

View File

@ -150,7 +150,6 @@ struct SSetCaptureState
#define OBJ_CONSTRUCTION SObjectConstruction obj__i(this) #define OBJ_CONSTRUCTION SObjectConstruction obj__i(this)
#define OBJECT_CONSTRUCTION_CAPTURING(actions) defActions = actions; SSetCaptureState obj__i1(true, actions); SObjectConstruction obj__i(this) #define OBJECT_CONSTRUCTION_CAPTURING(actions) defActions = actions; SSetCaptureState obj__i1(true, actions); SObjectConstruction obj__i(this)
#define OBJ_CONSTRUCTION_CAPTURING_ALL defActions = 255; SSetCaptureState obj__i1(true, 255); SObjectConstruction obj__i(this) #define OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(actions) SSetCaptureState obj__i1(true, actions); SObjectConstruction obj__i(this)
#define OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE defActions = 255 - DISPOSE; SSetCaptureState obj__i1(true, 255 - DISPOSE); SObjectConstruction obj__i(this) #define OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE defActions = 255 - DISPOSE; SSetCaptureState obj__i1(true, 255 - DISPOSE); SObjectConstruction obj__i(this)
#define BLOCK_CAPTURING SSetCaptureState obj__i(false, 0)
#define BLOCK_CAPTURING_DONT_TOUCH_REC_ACTIONS SSetCaptureState obj__i(false, GH.defActionsDef)

View File

@ -40,6 +40,23 @@ CIntObject::CIntObject(int used_, Point pos_):
GH.createdObj.front()->addChild(this, true); GH.createdObj.front()->addChild(this, true);
} }
CIntObject::~CIntObject()
{
if(active_m)
deactivate();
while(!children.empty())
{
if((defActions & DISPOSE) && (children.front()->recActions & DISPOSE))
delete children.front();
else
removeChild(children.front());
}
if(parent_m)
parent_m->removeChild(this);
}
void CIntObject::setTimer(int msToTrigger) void CIntObject::setTimer(int msToTrigger)
{ {
if (!(active & TIME)) if (!(active & TIME))
@ -125,24 +142,6 @@ void CIntObject::deactivate(ui16 what)
GH.handleElementDeActivate(this, what); GH.handleElementDeActivate(this, what);
} }
CIntObject::~CIntObject()
{
if (active_m)
deactivate();
if(defActions & DISPOSE)
{
while (!children.empty())
if(children.front()->recActions & DISPOSE)
delete children.front();
else
removeChild(children.front());
}
if(parent_m)
parent_m->removeChild(this);
}
void CIntObject::click(EIntObjMouseBtnType btn, tribool down, bool previousState) void CIntObject::click(EIntObjMouseBtnType btn, tribool down, bool previousState)
{ {
switch(btn) switch(btn)
@ -291,8 +290,12 @@ void CIntObject::removeChild(CIntObject * child, bool adjustPosition)
if (!child) if (!child)
return; return;
assert(vstd::contains(children, child)); if(!vstd::contains(children, child))
assert(child->parent_m == this); throw std::runtime_error("Wrong child object");
if(child->parent_m != this)
throw std::runtime_error("Wrong child object");
children -= child; children -= child;
child->parent_m = nullptr; child->parent_m = nullptr;
if(adjustPosition) if(adjustPosition)

View File

@ -66,7 +66,6 @@ enum class EIntObjMouseBtnType { LEFT, MIDDLE, RIGHT };
// Base UI element // Base UI element
class CIntObject : public IShowActivatable //interface object class CIntObject : public IShowActivatable //interface object
{ {
ui16 used;//change via addUsed() or delUsed ui16 used;//change via addUsed() or delUsed
//time handling //time handling
@ -80,6 +79,7 @@ class CIntObject : public IShowActivatable //interface object
//non-const versions of fields to allow changing them in CIntObject //non-const versions of fields to allow changing them in CIntObject
CIntObject *parent_m; //parent object CIntObject *parent_m; //parent object
ui16 active_m; ui16 active_m;
protected: protected:
//activate or deactivate specific action (LCLICK, RCLICK...) //activate or deactivate specific action (LCLICK, RCLICK...)
void activate(ui16 what); void activate(ui16 what);

View File

@ -323,7 +323,7 @@ void CBonusSelection::createBonusesIcons()
break; break;
} }
CToggleButton * bonusButton = new CToggleButton(Point(475 + i * 68, 455), "", CButton::tooltip(desc, desc)); std::shared_ptr<CToggleButton> bonusButton = std::make_shared<CToggleButton>(Point(475 + i * 68, 455), "", CButton::tooltip(desc, desc));
if(picNumber != -1) if(picNumber != -1)
picName += ":" + boost::lexical_cast<std::string>(picNumber); picName += ":" + boost::lexical_cast<std::string>(picNumber);

View File

@ -134,7 +134,7 @@ void CLobbyScreen::startScenario(bool allowOnlyAI)
catch(ExceptionNoHuman & e) catch(ExceptionNoHuman & e)
{ {
// You must position yourself prior to starting the game. // You must position yourself prior to starting the game.
CInfoWindow::showYesNoDialog(std::ref(CGI->generaltexth->allTexts[530]), nullptr, 0, std::bind(&CLobbyScreen::startScenario, this, true), false, PlayerColor(1)); CInfoWindow::showYesNoDialog(std::ref(CGI->generaltexth->allTexts[530]), CInfoWindow::TCompsInfo(), 0, std::bind(&CLobbyScreen::startScenario, this, true), PlayerColor(1));
} }
catch(ExceptionNoTemplate & e) catch(ExceptionNoTemplate & e)
{ {

View File

@ -88,7 +88,7 @@ void CSavingScreen::saveGame()
{ {
std::string hlp = CGI->generaltexth->allTexts[493]; //%s exists. Overwrite? std::string hlp = CGI->generaltexth->allTexts[493]; //%s exists. Overwrite?
boost::algorithm::replace_first(hlp, "%s", tabSel->inputName->text); boost::algorithm::replace_first(hlp, "%s", tabSel->inputName->text);
LOCPLINT->showYesNoDialog(hlp, overWrite, 0, false); LOCPLINT->showYesNoDialog(hlp, overWrite, nullptr);
} }
else else
{ {

View File

@ -148,7 +148,7 @@ InfoCard::InfoCard()
for(int i = 0; i < 5; i++) for(int i = 0; i < 5; i++)
{ {
auto button = new CToggleButton(Point(110 + i * 32, 450), difButns[i], CGI->generaltexth->zelp[24 + i]); auto button = std::make_shared<CToggleButton>(Point(110 + i * 32, 450), difButns[i], CGI->generaltexth->zelp[24 + i]);
iconDifficulty->addToggle(i, button); iconDifficulty->addToggle(i, button);
if(SEL->screenType != ESelectionScreen::newGame) if(SEL->screenType != ESelectionScreen::newGame)

View File

@ -367,12 +367,12 @@ void OptionsTab::CPlayerOptionTooltipBox::genTownWindow()
genHeader(); genHeader();
labelAssociatedCreatures = std::make_shared<CLabel>(pos.w / 2 + 8, 122, FONT_MEDIUM, CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[79]); labelAssociatedCreatures = std::make_shared<CLabel>(pos.w / 2 + 8, 122, FONT_MEDIUM, CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[79]);
std::vector<CComponent *> components; std::vector<std::shared_ptr<CComponent>> components;
const CTown * town = CGI->townh->factions[settings.castle]->town; const CTown * town = CGI->townh->factions[settings.castle]->town;
for(auto & elem : town->creatures) for(auto & elem : town->creatures)
{ {
if(!elem.empty()) if(!elem.empty())
components.push_back(new CComponent(CComponent::creature, elem.front(), 0, CComponent::tiny)); components.push_back(std::make_shared<CComponent>(CComponent::creature, elem.front(), 0, CComponent::tiny));
} }
boxAssociatedCreatures = std::make_shared<CComponentBox>(components, Rect(10, 140, pos.w - 20, 140)); boxAssociatedCreatures = std::make_shared<CComponentBox>(components, Rect(10, 140, pos.w - 20, 140));
} }

View File

@ -219,7 +219,7 @@ void RandomMapTab::addButtonsWithRandToGroup(CToggleGroup * group, const std::ve
// Buttons are relative to button group, TODO better solution? // Buttons are relative to button group, TODO better solution?
SObjectConstruction obj__i(group); SObjectConstruction obj__i(group);
const std::string RANDOM_DEF = "RANRAND"; const std::string RANDOM_DEF = "RANRAND";
group->addToggle(CMapGenOptions::RANDOM_SIZE, new CToggleButton(Point(256, 0), RANDOM_DEF, CGI->generaltexth->zelp[helpRandIndex])); group->addToggle(CMapGenOptions::RANDOM_SIZE, std::make_shared<CToggleButton>(Point(256, 0), RANDOM_DEF, CGI->generaltexth->zelp[helpRandIndex]));
group->setSelected(CMapGenOptions::RANDOM_SIZE); group->setSelected(CMapGenOptions::RANDOM_SIZE);
} }
@ -230,10 +230,9 @@ void RandomMapTab::addButtonsToGroup(CToggleGroup * group, const std::vector<std
int cnt = nEnd - nStart + 1; int cnt = nEnd - nStart + 1;
for(int i = 0; i < cnt; ++i) for(int i = 0; i < cnt; ++i)
{ {
auto button = new CToggleButton(Point(i * btnWidth, 0), defs[i + nStart], CGI->generaltexth->zelp[helpStartIndex + i]); auto button = std::make_shared<CToggleButton>(Point(i * btnWidth, 0), defs[i + nStart], CGI->generaltexth->zelp[helpStartIndex + i]);
// For blocked state we should use pressed image actually // For blocked state we should use pressed image actually
button->setImageOrder(0, 1, 1, 3); button->setImageOrder(0, 1, 1, 3);
group->addToggle(i + nStart, button); group->addToggle(i + nStart, button);
} }
} }
@ -243,7 +242,7 @@ void RandomMapTab::deactivateButtonsFrom(CToggleGroup * group, int startId)
logGlobal->debug("Blocking buttons from %d", startId); logGlobal->debug("Blocking buttons from %d", startId);
for(auto toggle : group->buttons) for(auto toggle : group->buttons)
{ {
if(auto button = dynamic_cast<CToggleButton *>(toggle.second)) if(auto button = std::dynamic_pointer_cast<CToggleButton>(toggle.second))
{ {
if(startId == CMapGenOptions::RANDOM_SIZE || toggle.first < startId) if(startId == CMapGenOptions::RANDOM_SIZE || toggle.first < startId)
{ {

View File

@ -94,16 +94,16 @@ CMenuScreen::CMenuScreen(const JsonNode & configNode)
//Hardcoded entry //Hardcoded entry
menuNameToEntry.push_back("credits"); menuNameToEntry.push_back("credits");
tabs = std::make_shared<CTabbedInt>(std::bind(&CMenuScreen::createTab, this, _1), CTabbedInt::DestroyFunc()); tabs = std::make_shared<CTabbedInt>(std::bind(&CMenuScreen::createTab, this, _1));
tabs->type |= REDRAW_PARENT; tabs->type |= REDRAW_PARENT;
} }
CIntObject * CMenuScreen::createTab(size_t index) std::shared_ptr<CIntObject> CMenuScreen::createTab(size_t index)
{ {
if(config["items"].Vector().size() == index) if(config["items"].Vector().size() == index)
return new CreditsScreen(); return std::make_shared<CreditsScreen>();
else
return new CMenuEntry(this, config["items"].Vector()[index]); return std::make_shared<CMenuEntry>(this, config["items"].Vector()[index]);
} }
void CMenuScreen::show(SDL_Surface * to) void CMenuScreen::show(SDL_Surface * to)
@ -175,7 +175,7 @@ static std::function<void()> genCommand(CMenuScreen * menu, std::vector<std::str
case 2: case 2:
return std::bind(CMainMenu::openLobby, ESelectionScreen::campaignList, true, nullptr, ELoadMode::NONE); return std::bind(CMainMenu::openLobby, ESelectionScreen::campaignList, true, nullptr, ELoadMode::NONE);
case 3: case 3:
return std::bind(CInfoWindow::showInfoDialog, "Sorry, tutorial is not implemented yet\n", (const std::vector<CComponent *> *)nullptr, false, PlayerColor(1)); return std::bind(CInfoWindow::showInfoDialog, "Sorry, tutorial is not implemented yet\n", std::vector<std::shared_ptr<CComponent>>(), PlayerColor(1));
} }
break; break;
} }
@ -190,18 +190,18 @@ static std::function<void()> genCommand(CMenuScreen * menu, std::vector<std::str
case 2: case 2:
return std::bind(CMainMenu::openLobby, ESelectionScreen::loadGame, true, nullptr, ELoadMode::CAMPAIGN); return std::bind(CMainMenu::openLobby, ESelectionScreen::loadGame, true, nullptr, ELoadMode::CAMPAIGN);
case 3: case 3:
return std::bind(CInfoWindow::showInfoDialog, "Sorry, tutorial is not implemented yet\n", (const std::vector<CComponent *> *)nullptr, false, PlayerColor(1)); return std::bind(CInfoWindow::showInfoDialog, "Sorry, tutorial is not implemented yet\n", std::vector<std::shared_ptr<CComponent>>(), PlayerColor(1));
} }
} }
break; break;
case 4: //exit case 4: //exit
{ {
return std::bind(CInfoWindow::showYesNoDialog, std::ref(CGI->generaltexth->allTexts[69]), (const std::vector<CComponent *> *)nullptr, do_quit, 0, false, PlayerColor(1)); return std::bind(CInfoWindow::showYesNoDialog, std::ref(CGI->generaltexth->allTexts[69]), std::vector<std::shared_ptr<CComponent>>(), do_quit, 0, PlayerColor(1));
} }
break; break;
case 5: //highscores case 5: //highscores
{ {
return std::bind(CInfoWindow::showInfoDialog, "Sorry, high scores menu is not implemented yet\n", (const std::vector<CComponent *> *)nullptr, false, PlayerColor(1)); return std::bind(CInfoWindow::showInfoDialog, "Sorry, high scores menu is not implemented yet\n", std::vector<std::shared_ptr<CComponent>>(), PlayerColor(1));
} }
} }
} }
@ -383,7 +383,7 @@ CMultiMode::CMultiMode(ESelectionScreen ScreenType)
blitAt(CPicture("MUMAP.bmp"), 16, 77, *background); blitAt(CPicture("MUMAP.bmp"), 16, 77, *background);
pos = background->center(); //center, window has size of bg graphic pos = background->center(); //center, window has size of bg graphic
statusBar = std::make_shared<CGStatusBar>(new CPicture(Rect(7, 465, 440, 18), 0)); //226, 472 statusBar = std::make_shared<CGStatusBar>(std::make_shared<CPicture>(Rect(7, 465, 440, 18), 0)); //226, 472
playerName = std::make_shared<CTextInput>(Rect(19, 436, 334, 16), *background); playerName = std::make_shared<CTextInput>(Rect(19, 436, 334, 16), *background);
playerName->setText(settings["general"]["playerName"].String()); playerName->setText(settings["general"]["playerName"].String());
playerName->cb += std::bind(&CMultiMode::onNameChange, this, _1); playerName->cb += std::bind(&CMultiMode::onNameChange, this, _1);
@ -431,7 +431,7 @@ CMultiPlayers::CMultiPlayers(const std::string & firstPlayer, ESelectionScreen S
buttonOk = std::make_shared<CButton>(Point(95, 338), "MUBCHCK.DEF", CGI->generaltexth->zelp[560], std::bind(&CMultiPlayers::enterSelectionScreen, this), SDLK_RETURN); buttonOk = std::make_shared<CButton>(Point(95, 338), "MUBCHCK.DEF", CGI->generaltexth->zelp[560], std::bind(&CMultiPlayers::enterSelectionScreen, this), SDLK_RETURN);
buttonCancel = std::make_shared<CButton>(Point(205, 338), "MUBCANC.DEF", CGI->generaltexth->zelp[561], std::bind(&CGuiHandler::popIntTotally, std::ref(GH), this), SDLK_ESCAPE); buttonCancel = std::make_shared<CButton>(Point(205, 338), "MUBCANC.DEF", CGI->generaltexth->zelp[561], std::bind(&CGuiHandler::popIntTotally, std::ref(GH), this), SDLK_ESCAPE);
statusBar = std::make_shared<CGStatusBar>(new CPicture(Rect(7, 381, 348, 18), 0)); //226, 472 statusBar = std::make_shared<CGStatusBar>(std::make_shared<CPicture>(Rect(7, 381, 348, 18), 0)); //226, 472
inputNames[0]->setText(firstPlayer, true); inputNames[0]->setText(firstPlayer, true);
inputNames[0]->giveFocus(); inputNames[0]->giveFocus();
@ -489,7 +489,7 @@ CSimpleJoinScreen::CSimpleJoinScreen(bool host)
inputPort->setText(CServerHandler::getDefaultPortStr(), true); inputPort->setText(CServerHandler::getDefaultPortStr(), true);
buttonCancel = std::make_shared<CButton>(Point(142, 142), "MUBCANC.DEF", CGI->generaltexth->zelp[561], std::bind(&CSimpleJoinScreen::leaveScreen, this), SDLK_ESCAPE); buttonCancel = std::make_shared<CButton>(Point(142, 142), "MUBCANC.DEF", CGI->generaltexth->zelp[561], std::bind(&CSimpleJoinScreen::leaveScreen, this), SDLK_ESCAPE);
statusBar = std::make_shared<CGStatusBar>(new CPicture(Rect(7, 186, 218, 18), 0)); statusBar = std::make_shared<CGStatusBar>(std::make_shared<CPicture>(Rect(7, 186, 218, 18), 0));
} }
void CSimpleJoinScreen::connectToServer() void CSimpleJoinScreen::connectToServer()

View File

@ -42,7 +42,7 @@ class CMenuScreen : public CWindowObject
std::shared_ptr<CPicture> background; std::shared_ptr<CPicture> background;
std::vector<std::shared_ptr<CPicture>> images; std::vector<std::shared_ptr<CPicture>> images;
CIntObject * createTab(size_t index); std::shared_ptr<CIntObject> createTab(size_t index);
public: public:
std::vector<std::string> menuNameToEntry; std::vector<std::string> menuNameToEntry;

View File

@ -398,7 +398,7 @@ CMapHandler::CMapBlitter *CMapHandler::resolveBlitter(const MapDrawingInfo * inf
return normalBlitter; return normalBlitter;
} }
void CMapHandler::CMapNormalBlitter::drawElement(EMapCacheType cacheType, const IImage * source, SDL_Rect * sourceRect, SDL_Surface * targetSurf, SDL_Rect * destRect) const void CMapHandler::CMapNormalBlitter::drawElement(EMapCacheType cacheType, std::shared_ptr<IImage> source, SDL_Rect * sourceRect, SDL_Surface * targetSurf, SDL_Rect * destRect) const
{ {
source->draw(targetSurf, destRect, sourceRect); source->draw(targetSurf, destRect, sourceRect);
} }
@ -470,7 +470,7 @@ CMapHandler::CMapNormalBlitter::CMapNormalBlitter(CMapHandler * parent)
defaultTileRect = Rect(0, 0, tileSize, tileSize); defaultTileRect = Rect(0, 0, tileSize, tileSize);
} }
IImage * CMapHandler::CMapWorldViewBlitter::objectToIcon(Obj id, si32 subId, PlayerColor owner) const std::shared_ptr<IImage> CMapHandler::CMapWorldViewBlitter::objectToIcon(Obj id, si32 subId, PlayerColor owner) const
{ {
int ownerIndex = 0; int ownerIndex = 0;
if(owner < PlayerColor::PLAYER_LIMIT) if(owner < PlayerColor::PLAYER_LIMIT)
@ -501,7 +501,7 @@ IImage * CMapHandler::CMapWorldViewBlitter::objectToIcon(Obj id, si32 subId, Pla
case Obj::RESOURCE: case Obj::RESOURCE:
return info->icons->getImage((int)EWorldViewIcon::RES_WOOD + subId + ownerIndex); return info->icons->getImage((int)EWorldViewIcon::RES_WOOD + subId + ownerIndex);
} }
return nullptr; return std::shared_ptr<IImage>();
} }
void CMapHandler::CMapWorldViewBlitter::calculateWorldViewCameraPos() void CMapHandler::CMapWorldViewBlitter::calculateWorldViewCameraPos()
@ -536,7 +536,7 @@ void CMapHandler::CMapWorldViewBlitter::calculateWorldViewCameraPos()
topTile.y = parent->sizes.y - tileCount.y; topTile.y = parent->sizes.y - tileCount.y;
} }
void CMapHandler::CMapWorldViewBlitter::drawElement(EMapCacheType cacheType, const IImage * source, SDL_Rect * sourceRect, SDL_Surface * targetSurf, SDL_Rect * destRect) const void CMapHandler::CMapWorldViewBlitter::drawElement(EMapCacheType cacheType, std::shared_ptr<IImage> source, SDL_Rect * sourceRect, SDL_Surface * targetSurf, SDL_Rect * destRect) const
{ {
auto scaled = parent->cache.requestWorldViewCacheOrCreate(cacheType, source); auto scaled = parent->cache.requestWorldViewCacheOrCreate(cacheType, source);
@ -604,7 +604,7 @@ void CMapHandler::CMapWorldViewBlitter::drawOverlayEx(SDL_Surface * targetSurf)
} }
} }
void CMapHandler::CMapWorldViewBlitter::drawHeroFlag(SDL_Surface * targetSurf, const IImage * source, SDL_Rect * sourceRect, SDL_Rect * destRect, bool moving) const void CMapHandler::CMapWorldViewBlitter::drawHeroFlag(SDL_Surface * targetSurf, std::shared_ptr<IImage> source, SDL_Rect * sourceRect, SDL_Rect * destRect, bool moving) const
{ {
if (moving) if (moving)
return; return;
@ -612,7 +612,7 @@ void CMapHandler::CMapWorldViewBlitter::drawHeroFlag(SDL_Surface * targetSurf, c
CMapBlitter::drawHeroFlag(targetSurf, source, sourceRect, destRect, false); CMapBlitter::drawHeroFlag(targetSurf, source, sourceRect, destRect, false);
} }
void CMapHandler::CMapWorldViewBlitter::drawObject(SDL_Surface * targetSurf, const IImage * source, SDL_Rect * sourceRect, bool moving) const void CMapHandler::CMapWorldViewBlitter::drawObject(SDL_Surface * targetSurf, std::shared_ptr<IImage> source, SDL_Rect * sourceRect, bool moving) const
{ {
if (moving) if (moving)
return; return;
@ -729,12 +729,12 @@ void CMapHandler::CMapBlitter::drawOverlayEx(SDL_Surface * targetSurf)
//nothing to do here //nothing to do here
} }
void CMapHandler::CMapBlitter::drawHeroFlag(SDL_Surface * targetSurf, const IImage * source, SDL_Rect * sourceRect, SDL_Rect * destRect, bool moving) const void CMapHandler::CMapBlitter::drawHeroFlag(SDL_Surface * targetSurf, std::shared_ptr<IImage> source, SDL_Rect * sourceRect, SDL_Rect * destRect, bool moving) const
{ {
drawElement(EMapCacheType::HERO_FLAGS, source, sourceRect, targetSurf, destRect); drawElement(EMapCacheType::HERO_FLAGS, source, sourceRect, targetSurf, destRect);
} }
void CMapHandler::CMapBlitter::drawObject(SDL_Surface * targetSurf, const IImage * source, SDL_Rect * sourceRect, bool moving) const void CMapHandler::CMapBlitter::drawObject(SDL_Surface * targetSurf, std::shared_ptr<IImage> source, SDL_Rect * sourceRect, bool moving) const
{ {
Rect dstRect(realTileRect); Rect dstRect(realTileRect);
drawElement(EMapCacheType::OBJECTS, source, sourceRect, targetSurf, &dstRect); drawElement(EMapCacheType::OBJECTS, source, sourceRect, targetSurf, &dstRect);
@ -830,7 +830,7 @@ void CMapHandler::CMapBlitter::drawFow(SDL_Surface * targetSurf) const
if (retBitmapID < 0) if (retBitmapID < 0)
retBitmapID = - parent->hideBitmap[pos.x][pos.y][pos.z] - 1; //fully hidden retBitmapID = - parent->hideBitmap[pos.x][pos.y][pos.z] - 1; //fully hidden
const IImage * image = nullptr; std::shared_ptr<IImage> image;
if (retBitmapID >= 0) if (retBitmapID >= 0)
image = parent->FoWpartialHide.at(retBitmapID); image = parent->FoWpartialHide.at(retBitmapID);
@ -1006,22 +1006,22 @@ CMapHandler::AnimBitmapHolder CMapHandler::CMapBlitter::findBoatBitmap(const CGB
return CMapHandler::AnimBitmapHolder(); return CMapHandler::AnimBitmapHolder();
} }
IImage * CMapHandler::CMapBlitter::findFlagBitmap(const CGHeroInstance * hero, int anim, const PlayerColor * color, int group) const std::shared_ptr<IImage> CMapHandler::CMapBlitter::findFlagBitmap(const CGHeroInstance * hero, int anim, const PlayerColor * color, int group) const
{ {
if (!hero) if(!hero)
return nullptr; return std::shared_ptr<IImage>();
if (hero->boat) if(hero->boat)
return findBoatFlagBitmap(hero->boat, anim, color, group, hero->moveDir); return findBoatFlagBitmap(hero->boat, anim, color, group, hero->moveDir);
return findHeroFlagBitmap(hero, anim, color, group); return findHeroFlagBitmap(hero, anim, color, group);
} }
IImage * CMapHandler::CMapBlitter::findHeroFlagBitmap(const CGHeroInstance * hero, int anim, const PlayerColor * color, int group) const std::shared_ptr<IImage> CMapHandler::CMapBlitter::findHeroFlagBitmap(const CGHeroInstance * hero, int anim, const PlayerColor * color, int group) const
{ {
return findFlagBitmapInternal(graphics->heroFlagAnimations.at(color->getNum()), anim, group, hero->moveDir, !hero->isStanding); return findFlagBitmapInternal(graphics->heroFlagAnimations.at(color->getNum()), anim, group, hero->moveDir, !hero->isStanding);
} }
IImage * CMapHandler::CMapBlitter::findBoatFlagBitmap(const CGBoat * boat, int anim, const PlayerColor * color, int group, ui8 dir) const std::shared_ptr<IImage> CMapHandler::CMapBlitter::findBoatFlagBitmap(const CGBoat * boat, int anim, const PlayerColor * color, int group, ui8 dir) const
{ {
int boatType = boat->subID; int boatType = boat->subID;
if(boatType < 0 || boatType >= graphics->boatFlagAnimations.size()) if(boatType < 0 || boatType >= graphics->boatFlagAnimations.size())
@ -1043,7 +1043,7 @@ IImage * CMapHandler::CMapBlitter::findBoatFlagBitmap(const CGBoat * boat, int a
return findFlagBitmapInternal(subtypeFlags.at(colorIndex), anim, group, dir, false); return findFlagBitmapInternal(subtypeFlags.at(colorIndex), anim, group, dir, false);
} }
IImage * CMapHandler::CMapBlitter::findFlagBitmapInternal(std::shared_ptr<CAnimation> animation, int anim, int group, ui8 dir, bool moving) const std::shared_ptr<IImage> CMapHandler::CMapBlitter::findFlagBitmapInternal(std::shared_ptr<CAnimation> animation, int anim, int group, ui8 dir, bool moving) const
{ {
size_t groupSize = animation->size(group); size_t groupSize = animation->size(group);
if(groupSize == 0) if(groupSize == 0)
@ -1438,22 +1438,21 @@ void CMapHandler::CMapCache::updateWorldViewScale(float scale)
worldViewCachedScale = scale; worldViewCachedScale = scale;
} }
IImage * CMapHandler::CMapCache::requestWorldViewCacheOrCreate(CMapHandler::EMapCacheType type, const IImage * fullSurface) std::shared_ptr<IImage> CMapHandler::CMapCache::requestWorldViewCacheOrCreate(CMapHandler::EMapCacheType type, std::shared_ptr<IImage> fullSurface)
{ {
intptr_t key = (intptr_t) fullSurface; intptr_t key = (intptr_t) (fullSurface.get());
auto & cache = data[(ui8)type]; auto & cache = data[(ui8)type];
auto iter = cache.find(key); auto iter = cache.find(key);
if(iter == cache.end()) if(iter == cache.end())
{ {
auto scaled = fullSurface->scaleFast(worldViewCachedScale); auto scaled = fullSurface->scaleFast(worldViewCachedScale);
IImage * ret = scaled.get(); cache[key] = scaled;
cache[key] = std::move(scaled); return scaled;
return ret;
} }
else else
{ {
return (*iter).second.get(); return (*iter).second;
} }
} }

View File

@ -159,7 +159,7 @@ class CMapHandler
/// temporarily caches rescaled frames for map world view redrawing /// temporarily caches rescaled frames for map world view redrawing
class CMapCache class CMapCache
{ {
std::array< std::map<intptr_t, std::unique_ptr<IImage>>, (ui8)EMapCacheType::AFTER_LAST> data; std::array< std::map<intptr_t, std::shared_ptr<IImage>>, (ui8)EMapCacheType::AFTER_LAST> data;
float worldViewCachedScale; float worldViewCachedScale;
public: public:
CMapCache(); CMapCache();
@ -168,17 +168,17 @@ class CMapHandler
/// updates scale and determines if currently cached data is still valid /// updates scale and determines if currently cached data is still valid
void updateWorldViewScale(float scale); void updateWorldViewScale(float scale);
/// asks for cached data; @returns cached data if found, new scaled surface otherwise, may return nullptr in case of scaling error /// asks for cached data; @returns cached data if found, new scaled surface otherwise, may return nullptr in case of scaling error
IImage * requestWorldViewCacheOrCreate(EMapCacheType type, const IImage * fullSurface); std::shared_ptr<IImage> requestWorldViewCacheOrCreate(EMapCacheType type, std::shared_ptr<IImage> fullSurface);
}; };
/// helper struct to pass around resolved bitmaps of an object; images can be nullptr if object doesn't have bitmap of that type /// helper struct to pass around resolved bitmaps of an object; images can be nullptr if object doesn't have bitmap of that type
struct AnimBitmapHolder struct AnimBitmapHolder
{ {
IImage * objBitmap; // main object bitmap std::shared_ptr<IImage> objBitmap; // main object bitmap
IImage * flagBitmap; // flag bitmap for the object (probably only for heroes and boats with heroes) std::shared_ptr<IImage> flagBitmap; // flag bitmap for the object (probably only for heroes and boats with heroes)
bool isMoving; // indicates if the object is moving (again, heroes/boats only) bool isMoving; // indicates if the object is moving (again, heroes/boats only)
AnimBitmapHolder(IImage * objBitmap_ = nullptr, IImage * flagBitmap_ = nullptr, bool moving = false) AnimBitmapHolder(std::shared_ptr<IImage> objBitmap_ = nullptr, std::shared_ptr<IImage> flagBitmap_ = nullptr, bool moving = false)
: objBitmap(objBitmap_), : objBitmap(objBitmap_),
flagBitmap(flagBitmap_), flagBitmap(flagBitmap_),
isMoving(moving) isMoving(moving)
@ -202,7 +202,7 @@ class CMapHandler
const MapDrawingInfo * info; // data for drawing passed from outside const MapDrawingInfo * info; // data for drawing passed from outside
/// general drawing method, called internally by more specialized ones /// general drawing method, called internally by more specialized ones
virtual void drawElement(EMapCacheType cacheType, const IImage * source, SDL_Rect * sourceRect, SDL_Surface * targetSurf, SDL_Rect * destRect) const = 0; virtual void drawElement(EMapCacheType cacheType, std::shared_ptr<IImage> source, SDL_Rect * sourceRect, SDL_Surface * targetSurf, SDL_Rect * destRect) const = 0;
// first drawing pass // first drawing pass
@ -214,8 +214,8 @@ class CMapHandler
virtual void drawRoad(SDL_Surface * targetSurf, const TerrainTile & tinfo, const TerrainTile * tinfoUpper) const; virtual void drawRoad(SDL_Surface * targetSurf, const TerrainTile & tinfo, const TerrainTile * tinfoUpper) const;
/// draws all objects on current tile (higher-level logic, unlike other draw*** methods) /// draws all objects on current tile (higher-level logic, unlike other draw*** methods)
virtual void drawObjects(SDL_Surface * targetSurf, const TerrainTile2 & tile) const; virtual void drawObjects(SDL_Surface * targetSurf, const TerrainTile2 & tile) const;
virtual void drawObject(SDL_Surface * targetSurf, const IImage * source, SDL_Rect * sourceRect, bool moving) const; virtual void drawObject(SDL_Surface * targetSurf, std::shared_ptr<IImage> source, SDL_Rect * sourceRect, bool moving) const;
virtual void drawHeroFlag(SDL_Surface * targetSurf, const IImage * source, SDL_Rect * sourceRect, SDL_Rect * destRect, bool moving) const; virtual void drawHeroFlag(SDL_Surface * targetSurf, std::shared_ptr<IImage> source, SDL_Rect * sourceRect, SDL_Rect * destRect, bool moving) const;
// second drawing pass // second drawing pass
@ -249,10 +249,10 @@ class CMapHandler
// internal helper methods to choose correct bitmap(s) for object; called internally by findObjectBitmap // internal helper methods to choose correct bitmap(s) for object; called internally by findObjectBitmap
AnimBitmapHolder findHeroBitmap(const CGHeroInstance * hero, int anim) const; AnimBitmapHolder findHeroBitmap(const CGHeroInstance * hero, int anim) const;
AnimBitmapHolder findBoatBitmap(const CGBoat * hero, int anim) const; AnimBitmapHolder findBoatBitmap(const CGBoat * hero, int anim) const;
IImage * findFlagBitmap(const CGHeroInstance * obj, int anim, const PlayerColor * color, int group) const; std::shared_ptr<IImage> findFlagBitmap(const CGHeroInstance * obj, int anim, const PlayerColor * color, int group) const;
IImage * findHeroFlagBitmap(const CGHeroInstance * obj, int anim, const PlayerColor * color, int group) const; std::shared_ptr<IImage> findHeroFlagBitmap(const CGHeroInstance * obj, int anim, const PlayerColor * color, int group) const;
IImage * findBoatFlagBitmap(const CGBoat * obj, int anim, const PlayerColor * color, int group, ui8 dir) const; std::shared_ptr<IImage> findBoatFlagBitmap(const CGBoat * obj, int anim, const PlayerColor * color, int group, ui8 dir) const;
IImage * findFlagBitmapInternal(std::shared_ptr<CAnimation> animation, int anim, int group, ui8 dir, bool moving) const; std::shared_ptr<IImage> findFlagBitmapInternal(std::shared_ptr<CAnimation> animation, int anim, int group, ui8 dir, bool moving) const;
public: public:
CMapBlitter(CMapHandler * p); CMapBlitter(CMapHandler * p);
@ -265,7 +265,7 @@ class CMapHandler
class CMapNormalBlitter : public CMapBlitter class CMapNormalBlitter : public CMapBlitter
{ {
protected: protected:
void drawElement(EMapCacheType cacheType, const IImage * source, SDL_Rect * sourceRect, SDL_Surface * targetSurf, SDL_Rect * destRect) const override; void drawElement(EMapCacheType cacheType, std::shared_ptr<IImage> source, SDL_Rect * sourceRect, SDL_Surface * targetSurf, SDL_Rect * destRect) const override;
void drawTileOverlay(SDL_Surface * targetSurf,const TerrainTile2 & tile) const override {} void drawTileOverlay(SDL_Surface * targetSurf,const TerrainTile2 & tile) const override {}
void init(const MapDrawingInfo * info) override; void init(const MapDrawingInfo * info) override;
SDL_Rect clip(SDL_Surface * targetSurf) const override; SDL_Rect clip(SDL_Surface * targetSurf) const override;
@ -277,12 +277,12 @@ class CMapHandler
class CMapWorldViewBlitter : public CMapBlitter class CMapWorldViewBlitter : public CMapBlitter
{ {
private: private:
IImage * objectToIcon(Obj id, si32 subId, PlayerColor owner) const; std::shared_ptr<IImage> objectToIcon(Obj id, si32 subId, PlayerColor owner) const;
protected: protected:
void drawElement(EMapCacheType cacheType, const IImage * source, SDL_Rect * sourceRect, SDL_Surface * targetSurf, SDL_Rect * destRect) const override; void drawElement(EMapCacheType cacheType, std::shared_ptr<IImage> source, SDL_Rect * sourceRect, SDL_Surface * targetSurf, SDL_Rect * destRect) const override;
void drawTileOverlay(SDL_Surface * targetSurf, const TerrainTile2 & tile) const override; void drawTileOverlay(SDL_Surface * targetSurf, const TerrainTile2 & tile) const override;
void drawHeroFlag(SDL_Surface * targetSurf, const IImage * source, SDL_Rect * sourceRect, SDL_Rect * destRect, bool moving) const override; void drawHeroFlag(SDL_Surface * targetSurf, std::shared_ptr<IImage> source, SDL_Rect * sourceRect, SDL_Rect * destRect, bool moving) const override;
void drawObject(SDL_Surface * targetSurf, const IImage * source, SDL_Rect * sourceRect, bool moving) const override; void drawObject(SDL_Surface * targetSurf, std::shared_ptr<IImage> source, SDL_Rect * sourceRect, bool moving) const override;
void drawFrame(SDL_Surface * targetSurf) const override {} void drawFrame(SDL_Surface * targetSurf) const override {}
void drawOverlayEx(SDL_Surface * targetSurf) override; void drawOverlayEx(SDL_Surface * targetSurf) override;
void init(const MapDrawingInfo * info) override; void init(const MapDrawingInfo * info) override;
@ -347,7 +347,7 @@ public:
//FIXME: unique_ptr should be enough, but fails to compile in MSVS 2013 //FIXME: unique_ptr should be enough, but fails to compile in MSVS 2013
typedef std::vector<std::array<std::shared_ptr<CAnimation>, 4>> TFlippedAnimations; //[type, rotation] typedef std::vector<std::array<std::shared_ptr<CAnimation>, 4>> TFlippedAnimations; //[type, rotation]
typedef std::vector<std::vector<std::array<IImage *, 4>>> TFlippedCache;//[type, view type, rotation] typedef std::vector<std::vector<std::array<std::shared_ptr<IImage>, 4>>> TFlippedCache;//[type, view type, rotation]
TFlippedAnimations terrainAnimations;//[terrain type, rotation] TFlippedAnimations terrainAnimations;//[terrain type, rotation]
TFlippedCache terrainImages;//[terrain type, view type, rotation] TFlippedCache terrainImages;//[terrain type, view type, rotation]
@ -359,14 +359,14 @@ public:
TFlippedCache riverImages;//[river type, view type, rotation] TFlippedCache riverImages;//[river type, view type, rotation]
//Fog of War cache (not owned) //Fog of War cache (not owned)
std::vector<const IImage *> FoWfullHide; std::vector<std::shared_ptr<IImage>> FoWfullHide;
std::vector<std::vector<std::vector<ui8> > > hideBitmap; //frame indexes (in FoWfullHide) of graphic that should be used to fully hide a tile std::vector<std::vector<std::vector<ui8> > > hideBitmap; //frame indexes (in FoWfullHide) of graphic that should be used to fully hide a tile
std::vector<const IImage *> FoWpartialHide; std::vector<std::shared_ptr<IImage>> FoWpartialHide;
//edge graphics //edge graphics
std::unique_ptr<CAnimation> egdeAnimation; std::unique_ptr<CAnimation> egdeAnimation;
std::vector<const IImage *> egdeImages;//cache of links to egdeAnimation (for faster access) std::vector<std::shared_ptr<IImage>> egdeImages;//cache of links to egdeAnimation (for faster access)
PseudoV< PseudoV< PseudoV <ui8> > > edgeFrames; //frame indexes (in egdeImages) of tile outside of map PseudoV< PseudoV< PseudoV <ui8> > > edgeFrames; //frame indexes (in egdeImages) of tile outside of map
mutable std::map<const CGObjectInstance*, ui8> animationPhase; mutable std::map<const CGObjectInstance*, ui8> animationPhase;

View File

@ -48,18 +48,16 @@
#include "../../lib/NetPacksBase.h" #include "../../lib/NetPacksBase.h"
#include "../../lib/StringConstants.h" #include "../../lib/StringConstants.h"
CList::CListItem::CListItem(CList * Parent): CList::CListItem::CListItem(CList * Parent)
CIntObject(LCLICK | RCLICK | HOVER), : CIntObject(LCLICK | RCLICK | HOVER),
parent(Parent), parent(Parent),
selection(nullptr) selection()
{ {
defActions = 255-DISPOSE;
} }
CList::CListItem::~CListItem() CList::CListItem::~CListItem()
{ {
// select() method in this was already destroyed so we can't safely call method in parent
if (parent->selected == this)
parent->selected = nullptr;
} }
void CList::CListItem::clickRight(tribool down, bool previousState) void CList::CListItem::clickRight(tribool down, bool previousState)
@ -70,15 +68,17 @@ void CList::CListItem::clickRight(tribool down, bool previousState)
void CList::CListItem::clickLeft(tribool down, bool previousState) void CList::CListItem::clickLeft(tribool down, bool previousState)
{ {
if (down == true) if(down == true)
{ {
//second click on already selected item //second click on already selected item
if (parent->selected == this) if(parent->selected == this->shared_from_this())
{
open(); open();
}
else else
{ {
//first click - switch selection //first click - switch selection
parent->select(this); parent->select(this->shared_from_this());
} }
} }
} }
@ -93,53 +93,54 @@ void CList::CListItem::hover(bool on)
void CList::CListItem::onSelect(bool on) void CList::CListItem::onSelect(bool on)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
vstd::clear_pointer(selection); selection.reset();
if (on) if(on)
selection = genSelection(); selection = genSelection();
select(on); select(on);
GH.totalRedraw(); GH.totalRedraw();
} }
CList::CList(int Size, Point position, std::string btnUp, std::string btnDown, size_t listAmount, CList::CList(int Size, Point position, std::string btnUp, std::string btnDown, size_t listAmount, int helpUp, int helpDown, CListBox::CreateFunc create)
int helpUp, int helpDown, CListBox::CreateFunc create, CListBox::DestroyFunc destroy): : CIntObject(0, position),
CIntObject(0, position),
size(Size), size(Size),
selected(nullptr) selected(nullptr)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
scrollUp = new CButton(Point(0, 0), btnUp, CGI->generaltexth->zelp[helpUp]); scrollUp = std::make_shared<CButton>(Point(0, 0), btnUp, CGI->generaltexth->zelp[helpUp]);
list = new CListBox(create, destroy, Point(1,scrollUp->pos.h), Point(0, 32), size, listAmount); scrollDown = std::make_shared<CButton>(Point(0, scrollUp->pos.h + 32*size), btnDown, CGI->generaltexth->zelp[helpDown]);
listBox = std::make_shared<CListBox>(create, Point(1,scrollUp->pos.h), Point(0, 32), size, listAmount);
//assign callback only after list was created //assign callback only after list was created
scrollUp->addCallback(std::bind(&CListBox::moveToPrev, list)); scrollUp->addCallback(std::bind(&CListBox::moveToPrev, listBox));
scrollDown = new CButton(Point(0, scrollUp->pos.h + 32*size), btnDown, CGI->generaltexth->zelp[helpDown], std::bind(&CListBox::moveToNext, list)); scrollDown->addCallback(std::bind(&CListBox::moveToNext, listBox));
scrollDown->addCallback(std::bind(&CList::update, this));
scrollUp->addCallback(std::bind(&CList::update, this)); scrollUp->addCallback(std::bind(&CList::update, this));
scrollDown->addCallback(std::bind(&CList::update, this));
update(); update();
} }
void CList::update() void CList::update()
{ {
bool onTop = list->getPos() == 0; bool onTop = listBox->getPos() == 0;
bool onBottom = list->getPos() + size >= list->size(); bool onBottom = listBox->getPos() + size >= listBox->size();
scrollUp->block(onTop); scrollUp->block(onTop);
scrollDown->block(onBottom); scrollDown->block(onBottom);
} }
void CList::select(CListItem *which) void CList::select(std::shared_ptr<CListItem> which)
{ {
if (selected == which) if(selected == which)
return; return;
if (selected) if(selected)
selected->onSelect(false); selected->onSelect(false);
selected = which; selected = which;
if (which) if(which)
{ {
which->onSelect(true); which->onSelect(true);
onSelect(); onSelect();
@ -148,28 +149,28 @@ void CList::select(CListItem *which)
int CList::getSelectedIndex() int CList::getSelectedIndex()
{ {
return list->getIndexOf(selected); return listBox->getIndexOf(selected);
} }
void CList::selectIndex(int which) void CList::selectIndex(int which)
{ {
if (which < 0) if(which < 0)
{ {
if (selected) if(selected)
select(nullptr); select(nullptr);
} }
else else
{ {
list->scrollTo(which); listBox->scrollTo(which);
update(); update();
select(dynamic_cast<CListItem*>(list->getItem(which))); select(std::dynamic_pointer_cast<CListItem>(listBox->getItem(which)));
} }
} }
void CList::selectNext() void CList::selectNext()
{ {
int index = getSelectedIndex() + 1; int index = getSelectedIndex() + 1;
if (index >= list->size()) if(index >= listBox->size())
index = 0; index = 0;
selectIndex(index); selectIndex(index);
} }
@ -177,7 +178,7 @@ void CList::selectNext()
void CList::selectPrev() void CList::selectPrev()
{ {
int index = getSelectedIndex(); int index = getSelectedIndex();
if (index <= 0) if(index <= 0)
selectIndex(0); selectIndex(0);
else else
selectIndex(index-1); selectIndex(index-1);
@ -185,23 +186,23 @@ void CList::selectPrev()
CHeroList::CEmptyHeroItem::CEmptyHeroItem() CHeroList::CEmptyHeroItem::CEmptyHeroItem()
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
auto move = new CAnimImage("IMOBIL", 0, 0, 0, 1); movement = std::make_shared<CAnimImage>("IMOBIL", 0, 0, 0, 1);
auto img = new CPicture("HPSXXX", move->pos.w + 1); portrait = std::make_shared<CPicture>("HPSXXX", movement->pos.w + 1);
auto mana = new CAnimImage("IMANA", 0, 0, move->pos.w + img->pos.w + 2, 1 ); mana = std::make_shared<CAnimImage>("IMANA", 0, 0, movement->pos.w + portrait->pos.w + 2, 1 );
pos.w = mana->pos.w + mana->pos.x - pos.x; pos.w = mana->pos.w + mana->pos.x - pos.x;
pos.h = std::max(std::max<SDLX_Size>(move->pos.h + 1, mana->pos.h + 1), img->pos.h); pos.h = std::max(std::max<SDLX_Size>(movement->pos.h + 1, mana->pos.h + 1), portrait->pos.h);
} }
CHeroList::CHeroItem::CHeroItem(CHeroList *parent, const CGHeroInstance * Hero): CHeroList::CHeroItem::CHeroItem(CHeroList *parent, const CGHeroInstance * Hero)
CListItem(parent), : CListItem(parent),
hero(Hero) hero(Hero)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
movement = new CAnimImage("IMOBIL", 0, 0, 0, 1); movement = std::make_shared<CAnimImage>("IMOBIL", 0, 0, 0, 1);
portrait = new CAnimImage("PortraitsSmall", hero->portrait, 0, movement->pos.w + 1); portrait = std::make_shared<CAnimImage>("PortraitsSmall", hero->portrait, 0, movement->pos.w + 1);
mana = new CAnimImage("IMANA", 0, 0, movement->pos.w + portrait->pos.w + 2, 1 ); mana = std::make_shared<CAnimImage>("IMANA", 0, 0, movement->pos.w + portrait->pos.w + 2, 1);
pos.w = mana->pos.w + mana->pos.x - pos.x; pos.w = mana->pos.w + mana->pos.x - pos.x;
pos.h = std::max(std::max<SDLX_Size>(movement->pos.h + 1, mana->pos.h + 1), portrait->pos.h); pos.h = std::max(std::max<SDLX_Size>(movement->pos.h + 1, mana->pos.h + 1), portrait->pos.h);
@ -216,15 +217,15 @@ void CHeroList::CHeroItem::update()
redraw(); redraw();
} }
CIntObject * CHeroList::CHeroItem::genSelection() std::shared_ptr<CIntObject> CHeroList::CHeroItem::genSelection()
{ {
return new CPicture("HPSYYY", movement->pos.w + 1); return std::make_shared<CPicture>("HPSYYY", movement->pos.w + 1);
} }
void CHeroList::CHeroItem::select(bool on) void CHeroList::CHeroItem::select(bool on)
{ {
if (on && adventureInt->selection != hero) if(on && adventureInt->selection != hero)
adventureInt->select(hero); adventureInt->select(hero);
} }
void CHeroList::CHeroItem::open() void CHeroList::CHeroItem::open()
@ -242,11 +243,11 @@ std::string CHeroList::CHeroItem::getHoverText()
return boost::str(boost::format(CGI->generaltexth->allTexts[15]) % hero->name % hero->type->heroClass->name); return boost::str(boost::format(CGI->generaltexth->allTexts[15]) % hero->name % hero->type->heroClass->name);
} }
CIntObject * CHeroList::createHeroItem(size_t index) std::shared_ptr<CIntObject> CHeroList::createHeroItem(size_t index)
{ {
if (LOCPLINT->wanderingHeroes.size() > index) if (LOCPLINT->wanderingHeroes.size() > index)
return new CHeroItem(this, LOCPLINT->wanderingHeroes[index]); return std::make_shared<CHeroItem>(this, LOCPLINT->wanderingHeroes[index]);
return new CEmptyHeroItem(); return std::make_shared<CEmptyHeroItem>();
} }
CHeroList::CHeroList(int size, Point position, std::string btnUp, std::string btnDown): CHeroList::CHeroList(int size, Point position, std::string btnUp, std::string btnDown):
@ -262,10 +263,10 @@ void CHeroList::select(const CGHeroInstance * hero)
void CHeroList::update(const CGHeroInstance * hero) void CHeroList::update(const CGHeroInstance * hero)
{ {
//this hero is already present, update its status //this hero is already present, update its status
for (auto & elem : list->getItems()) for(auto & elem : listBox->getItems())
{ {
auto item = dynamic_cast<CHeroItem*>(elem); auto item = std::dynamic_pointer_cast<CHeroItem>(elem);
if (item && item->hero == hero && vstd::contains(LOCPLINT->wanderingHeroes, hero)) if(item && item->hero == hero && vstd::contains(LOCPLINT->wanderingHeroes, hero))
{ {
item->update(); item->update();
return; return;
@ -273,7 +274,7 @@ void CHeroList::update(const CGHeroInstance * hero)
} }
//simplest solution for now: reset list and restore selection //simplest solution for now: reset list and restore selection
list->resize(LOCPLINT->wanderingHeroes.size()); listBox->resize(LOCPLINT->wanderingHeroes.size());
if (adventureInt->selection) if (adventureInt->selection)
{ {
auto hero = dynamic_cast<const CGHeroInstance *>(adventureInt->selection); auto hero = dynamic_cast<const CGHeroInstance *>(adventureInt->selection);
@ -283,26 +284,26 @@ void CHeroList::update(const CGHeroInstance * hero)
CList::update(); CList::update();
} }
CIntObject * CTownList::createTownItem(size_t index) std::shared_ptr<CIntObject> CTownList::createTownItem(size_t index)
{ {
if (LOCPLINT->towns.size() > index) if (LOCPLINT->towns.size() > index)
return new CTownItem(this, LOCPLINT->towns[index]); return std::make_shared<CTownItem>(this, LOCPLINT->towns[index]);
return new CAnimImage("ITPA", 0); return std::make_shared<CAnimImage>("ITPA", 0);
} }
CTownList::CTownItem::CTownItem(CTownList *parent, const CGTownInstance *Town): CTownList::CTownItem::CTownItem(CTownList *parent, const CGTownInstance *Town):
CListItem(parent), CListItem(parent),
town(Town) town(Town)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
picture = new CAnimImage("ITPA", 0); picture = std::make_shared<CAnimImage>("ITPA", 0);
pos = picture->pos; pos = picture->pos;
update(); update();
} }
CIntObject * CTownList::CTownItem::genSelection() std::shared_ptr<CIntObject> CTownList::CTownItem::genSelection()
{ {
return new CAnimImage("ITPA", 1); return std::make_shared<CAnimImage>("ITPA", 1);
} }
void CTownList::CTownItem::update() void CTownList::CTownItem::update()
@ -348,7 +349,7 @@ void CTownList::update(const CGTownInstance *)
{ {
//simplest solution for now: reset list and restore selection //simplest solution for now: reset list and restore selection
list->resize(LOCPLINT->towns.size()); listBox->resize(LOCPLINT->towns.size());
if (adventureInt->selection) if (adventureInt->selection)
{ {
auto town = dynamic_cast<const CGTownInstance *>(adventureInt->selection); auto town = dynamic_cast<const CGTownInstance *>(adventureInt->selection);
@ -475,7 +476,7 @@ CMinimapInstance::~CMinimapInstance()
SDL_FreeSurface(minimap); SDL_FreeSurface(minimap);
} }
void CMinimapInstance::showAll(SDL_Surface *to) void CMinimapInstance::showAll(SDL_Surface * to)
{ {
blitAtLoc(minimap, 0, 0, to); blitAtLoc(minimap, 0, 0, to);
@ -484,7 +485,7 @@ void CMinimapInstance::showAll(SDL_Surface *to)
for(auto & hero : heroes) for(auto & hero : heroes)
{ {
int3 position = hero->getPosition(false); int3 position = hero->getPosition(false);
if (position.z == level) if(position.z == level)
{ {
const SDL_Color & color = graphics->playerColors[hero->getOwner().getNum()]; const SDL_Color & color = graphics->playerColors[hero->getOwner().getNum()];
blitTileWithColor(color, position, to, pos.x, pos.y); blitTileWithColor(color, position, to, pos.x, pos.y);
@ -531,15 +532,17 @@ std::map<int, std::pair<SDL_Color, SDL_Color> > CMinimap::loadColors(std::string
return ret; return ret;
} }
CMinimap::CMinimap(const Rect &position): CMinimap::CMinimap(const Rect & position)
CIntObject(LCLICK | RCLICK | HOVER | MOVE, position.topLeft()), : CIntObject(LCLICK | RCLICK | HOVER | MOVE, position.topLeft()),
aiShield(nullptr),
minimap(nullptr),
level(0), level(0),
colors(loadColors("config/terrains.json")) colors(loadColors("config/terrains.json"))
{ {
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
pos.w = position.w; pos.w = position.w;
pos.h = position.h; pos.h = position.h;
aiShield = std::make_shared<CPicture>("AIShield");
aiShield->disable();
} }
int3 CMinimap::translateMousePosition() int3 CMinimap::translateMousePosition()
@ -567,7 +570,7 @@ void CMinimap::moveAdvMapSelection()
void CMinimap::clickLeft(tribool down, bool previousState) void CMinimap::clickLeft(tribool down, bool previousState)
{ {
if (down) if(down)
moveAdvMapSelection(); moveAdvMapSelection();
} }
@ -578,7 +581,7 @@ void CMinimap::clickRight(tribool down, bool previousState)
void CMinimap::hover(bool on) void CMinimap::hover(bool on)
{ {
if (on) if(on)
GH.statusbar->setText(CGI->generaltexth->zelp[291].first); GH.statusbar->setText(CGI->generaltexth->zelp[291].first);
else else
GH.statusbar->clear(); GH.statusbar->clear();
@ -593,7 +596,7 @@ void CMinimap::mouseMoved(const SDL_MouseMotionEvent & sEvent)
void CMinimap::showAll(SDL_Surface * to) void CMinimap::showAll(SDL_Surface * to)
{ {
CIntObject::showAll(to); CIntObject::showAll(to);
if (minimap) if(minimap)
{ {
int3 mapSizes = LOCPLINT->cb->getMapSize(); int3 mapSizes = LOCPLINT->cb->getMapSize();
int3 tileCountOnScreen = adventureInt->terrain.tileCountOnScreen(); int3 tileCountOnScreen = adventureInt->terrain.tileCountOnScreen();
@ -608,13 +611,13 @@ void CMinimap::showAll(SDL_Surface * to)
ui16(tileCountOnScreen.y * pos.h / mapSizes.y) ui16(tileCountOnScreen.y * pos.h / mapSizes.y)
}; };
if (adventureInt->mode == EAdvMapMode::WORLD_VIEW) if(adventureInt->mode == EAdvMapMode::WORLD_VIEW)
{ {
// adjusts radar so that it doesn't go out of map in world view mode (since there's no frame) // adjusts radar so that it doesn't go out of map in world view mode (since there's no frame)
radar.x = std::min<int>(std::max(pos.x, radar.x), pos.x + pos.w - radar.w); radar.x = std::min<int>(std::max(pos.x, radar.x), pos.x + pos.w - radar.w);
radar.y = std::min<int>(std::max(pos.y, radar.y), pos.y + pos.h - radar.h); radar.y = std::min<int>(std::max(pos.y, radar.y), pos.y + pos.h - radar.h);
if (radar.x < pos.x && radar.y < pos.y) if(radar.x < pos.x && radar.y < pos.y)
return; // whole map is visible at once, no point in redrawing border return; // whole map is visible at once, no point in redrawing border
} }
@ -627,12 +630,11 @@ void CMinimap::showAll(SDL_Surface * to)
void CMinimap::update() void CMinimap::update()
{ {
if (aiShield) //AI turn is going on. There is no need to update minimap if(aiShield->recActions & UPDATE) //AI turn is going on. There is no need to update minimap
return; return;
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
vstd::clear_pointer(minimap); minimap = std::make_shared<CMinimapInstance>(this, level);
minimap = new CMinimapInstance(this, level);
redraw(); redraw();
} }
@ -644,16 +646,14 @@ void CMinimap::setLevel(int newLevel)
void CMinimap::setAIRadar(bool on) void CMinimap::setAIRadar(bool on)
{ {
if (on) if(on)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; aiShield->enable();
vstd::clear_pointer(minimap); minimap.reset();
if (!aiShield)
aiShield = new CPicture("AIShield");
} }
else else
{ {
vstd::clear_pointer(aiShield); aiShield->disable();
update(); update();
} }
// this my happen during AI turn when this interface is inactive // this my happen during AI turn when this interface is inactive
@ -663,123 +663,98 @@ void CMinimap::setAIRadar(bool on)
void CMinimap::hideTile(const int3 &pos) void CMinimap::hideTile(const int3 &pos)
{ {
if (minimap) if(minimap)
minimap->refreshTile(pos); minimap->refreshTile(pos);
} }
void CMinimap::showTile(const int3 &pos) void CMinimap::showTile(const int3 &pos)
{ {
if (minimap) if(minimap)
minimap->refreshTile(pos); minimap->refreshTile(pos);
} }
CInfoBar::CVisibleInfo::CVisibleInfo(Point position): CInfoBar::CVisibleInfo::CVisibleInfo()
CIntObject(0, position), : CIntObject(0, Point(8, 12))
aiProgress(nullptr)
{ {
} }
void CInfoBar::CVisibleInfo::show(SDL_Surface *to) void CInfoBar::CVisibleInfo::show(SDL_Surface * to)
{ {
CIntObject::show(to); CIntObject::show(to);
for(auto object : forceRefresh) for(auto object : forceRefresh)
object->showAll(to); object->showAll(to);
} }
void CInfoBar::CVisibleInfo::loadHero(const CGHeroInstance * hero) CInfoBar::EmptyVisibleInfo::EmptyVisibleInfo()
{ {
assert(children.empty()); // visible info should be re-created to change type
OBJ_CONSTRUCTION_CAPTURING_ALL;
new CPicture("ADSTATHR");
new CHeroTooltip(Point(0,0), hero);
} }
void CInfoBar::CVisibleInfo::loadTown(const CGTownInstance *town) CInfoBar::VisibleHeroInfo::VisibleHeroInfo(const CGHeroInstance * hero)
{ {
assert(children.empty()); // visible info should be re-created to change type OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
background = std::make_shared<CPicture>("ADSTATHR");
OBJ_CONSTRUCTION_CAPTURING_ALL; heroTooltip = std::make_shared<CHeroTooltip>(Point(0,0), hero);
new CPicture("ADSTATCS");
new CTownTooltip(Point(0,0), town);
} }
void CInfoBar::CVisibleInfo::playNewDaySound() CInfoBar::VisibleTownInfo::VisibleTownInfo(const CGTownInstance * town)
{ {
if (LOCPLINT->cb->getDate(Date::DAY_OF_WEEK) != 1) // not first day of the week OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
CCS->soundh->playSound(soundBase::newDay); background = std::make_shared<CPicture>("ADSTATCS");
else townTooltip = std::make_shared<CTownTooltip>(Point(0,0), town);
if (LOCPLINT->cb->getDate(Date::WEEK) != 1) // not first week in month
CCS->soundh->playSound(soundBase::newWeek);
else
if (LOCPLINT->cb->getDate(Date::MONTH) != 1) // not first month
CCS->soundh->playSound(soundBase::newMonth);
else
CCS->soundh->playSound(soundBase::newDay);
} }
std::string CInfoBar::CVisibleInfo::getNewDayName() CInfoBar::VisibleDateInfo::VisibleDateInfo()
{ {
if (LOCPLINT->cb->getDate(Date::DAY) == 1) OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
return "NEWDAY";
if (LOCPLINT->cb->getDate(Date::DAY) != 1) animation = std::make_shared<CShowableAnim>(1, 0, getNewDayName(), CShowableAnim::PLAY_ONCE);
return "NEWDAY";
switch(LOCPLINT->cb->getDate(Date::WEEK))
{
case 1: return "NEWWEEK1";
case 2: return "NEWWEEK2";
case 3: return "NEWWEEK3";
case 4: return "NEWWEEK4";
default: assert(0); return "";
}
}
void CInfoBar::CVisibleInfo::loadDay()
{
assert(children.empty()); // visible info should be re-created first to change type
playNewDaySound();
OBJ_CONSTRUCTION_CAPTURING_ALL;
new CShowableAnim(1, 0, getNewDayName(), CShowableAnim::PLAY_ONCE);
std::string labelText; std::string labelText;
if (LOCPLINT->cb->getDate(Date::DAY_OF_WEEK) == 1 && LOCPLINT->cb->getDate(Date::DAY) != 1) // monday of any week but first - show new week info if(LOCPLINT->cb->getDate(Date::DAY_OF_WEEK) == 1 && LOCPLINT->cb->getDate(Date::DAY) != 1) // monday of any week but first - show new week info
labelText = CGI->generaltexth->allTexts[63] + " " + boost::lexical_cast<std::string>(LOCPLINT->cb->getDate(Date::WEEK)); labelText = CGI->generaltexth->allTexts[63] + " " + boost::lexical_cast<std::string>(LOCPLINT->cb->getDate(Date::WEEK));
else else
labelText = CGI->generaltexth->allTexts[64] + " " + boost::lexical_cast<std::string>(LOCPLINT->cb->getDate(Date::DAY_OF_WEEK)); labelText = CGI->generaltexth->allTexts[64] + " " + boost::lexical_cast<std::string>(LOCPLINT->cb->getDate(Date::DAY_OF_WEEK));
forceRefresh.push_back(new CLabel(95, 31, FONT_MEDIUM, CENTER, Colors::WHITE, labelText)); label = std::make_shared<CLabel>(95, 31, FONT_MEDIUM, CENTER, Colors::WHITE, labelText);
forceRefresh.push_back(label);
} }
void CInfoBar::CVisibleInfo::loadEnemyTurn(PlayerColor player) std::string CInfoBar::VisibleDateInfo::getNewDayName()
{ {
assert(children.empty()); // visible info should be re-created to change type if(LOCPLINT->cb->getDate(Date::DAY) == 1)
return "NEWDAY";
OBJ_CONSTRUCTION_CAPTURING_ALL; if(LOCPLINT->cb->getDate(Date::DAY) != 1)
new CPicture("ADSTATNX"); return "NEWDAY";
new CAnimImage("CREST58", player.getNum(), 0, 20, 51);
new CShowableAnim(99, 51, "HOURSAND");
// FIXME: currently there is no way to get progress from VCAI switch(LOCPLINT->cb->getDate(Date::WEEK))
// if this will change at some point switch this ifdef to enable correct code {
#if 0 case 1:
//prepare hourglass for updating AI turn return "NEWWEEK1";
aiProgress = new CAnimImage("HOURGLAS", 0, 0, 99, 51); case 2:
forceRefresh.push_back(aiProgress); return "NEWWEEK2";
#else case 3:
//create hourglass that will be always animated ignoring AI status return "NEWWEEK3";
new CShowableAnim(99, 51, "HOURGLAS", CShowableAnim::PLAY_ONCE, 40); case 4:
#endif return "NEWWEEK4";
default:
return "";
}
} }
void CInfoBar::CVisibleInfo::loadGameStatus() CInfoBar::VisibleEnemyTurnInfo::VisibleEnemyTurnInfo(PlayerColor player)
{ {
assert(children.empty()); // visible info should be re-created to change type OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
background = std::make_shared<CPicture>("ADSTATNX");
banner = std::make_shared<CAnimImage>("CREST58", player.getNum(), 0, 20, 51);
sand = std::make_shared<CShowableAnim>(99, 51, "HOURSAND");
glass = std::make_shared<CShowableAnim>(99, 51, "HOURGLAS", CShowableAnim::PLAY_ONCE, 40);
}
CInfoBar::VisibleGameStatusInfo::VisibleGameStatusInfo()
{
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
//get amount of halls of each level //get amount of halls of each level
std::vector<int> halls(4, 0); std::vector<int> halls(4, 0);
for(auto town : LOCPLINT->towns) for(auto town : LOCPLINT->towns)
@ -797,83 +772,84 @@ void CInfoBar::CVisibleInfo::loadGameStatus()
{ {
if(LOCPLINT->cb->getPlayerStatus(PlayerColor(i), false) == EPlayerStatus::INGAME) if(LOCPLINT->cb->getPlayerStatus(PlayerColor(i), false) == EPlayerStatus::INGAME)
{ {
if (LOCPLINT->cb->getPlayerRelations(LOCPLINT->playerID, PlayerColor(i)) != PlayerRelations::ENEMIES) if(LOCPLINT->cb->getPlayerRelations(LOCPLINT->playerID, PlayerColor(i)) != PlayerRelations::ENEMIES)
allies.push_back(PlayerColor(i)); allies.push_back(PlayerColor(i));
else else
enemies.push_back(PlayerColor(i)); enemies.push_back(PlayerColor(i));
} }
} }
//generate component //generate widgets
OBJ_CONSTRUCTION_CAPTURING_ALL; background = std::make_shared<CPicture>("ADSTATIN");
new CPicture("ADSTATIN"); allyLabel = std::make_shared<CLabel>(10, 106, FONT_SMALL, TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[390] + ":");
auto allyLabel = new CLabel(10, 106, FONT_SMALL, TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[390] + ":"); enemyLabel = std::make_shared<CLabel>(10, 136, FONT_SMALL, TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[391] + ":");
auto enemyLabel = new CLabel(10, 136, FONT_SMALL, TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[391] + ":");
int posx = allyLabel->pos.w + allyLabel->pos.x - pos.x + 4; int posx = allyLabel->pos.w + allyLabel->pos.x - pos.x + 4;
for(PlayerColor & player : allies) for(PlayerColor & player : allies)
{ {
auto image = new CAnimImage("ITGFLAGS", player.getNum(), 0, posx, 102); auto image = std::make_shared<CAnimImage>("ITGFLAGS", player.getNum(), 0, posx, 102);
posx += image->pos.w; posx += image->pos.w;
flags.push_back(image);
} }
posx = enemyLabel->pos.w + enemyLabel->pos.x - pos.x + 4; posx = enemyLabel->pos.w + enemyLabel->pos.x - pos.x + 4;
for(PlayerColor & player : enemies) for(PlayerColor & player : enemies)
{ {
auto image = new CAnimImage("ITGFLAGS", player.getNum(), 0, posx, 132); auto image = std::make_shared<CAnimImage>("ITGFLAGS", player.getNum(), 0, posx, 132);
posx += image->pos.w; posx += image->pos.w;
flags.push_back(image);
} }
for (size_t i=0; i<halls.size(); i++) for(size_t i=0; i<halls.size(); i++)
{ {
new CAnimImage("itmtl", i, 0, 6 + 42 * i , 11); hallIcons.push_back(std::make_shared<CAnimImage>("itmtl", i, 0, 6 + 42 * i , 11));
if (halls[i]) if(halls[i])
new CLabel( 26 + 42 * i, 64, FONT_SMALL, CENTER, Colors::WHITE, boost::lexical_cast<std::string>(halls[i])); hallLabels.push_back(std::make_shared<CLabel>( 26 + 42 * i, 64, FONT_SMALL, CENTER, Colors::WHITE, boost::lexical_cast<std::string>(halls[i])));
} }
} }
void CInfoBar::CVisibleInfo::loadComponent(const Component & compToDisplay, std::string message) CInfoBar::VisibleComponentInfo::VisibleComponentInfo(const Component & compToDisplay, std::string message)
{ {
assert(children.empty()); // visible info should be re-created to change type OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
OBJ_CONSTRUCTION_CAPTURING_ALL; background = std::make_shared<CPicture>("ADSTATOT", 1);
new CPicture("ADSTATOT", 1); comp = std::make_shared<CComponent>(compToDisplay);
auto comp = new CComponent(compToDisplay);
comp->moveTo(Point(pos.x+47, pos.y+50)); comp->moveTo(Point(pos.x+47, pos.y+50));
new CTextBox(message, Rect(10, 4, 160, 50), 0, FONT_SMALL, CENTER, Colors::WHITE); text = std::make_shared<CTextBox>(message, Rect(10, 4, 160, 50), 0, FONT_SMALL, CENTER, Colors::WHITE);
} }
void CInfoBar::CVisibleInfo::updateEnemyTurn(double progress) void CInfoBar::playNewDaySound()
{ {
if (aiProgress) if(LOCPLINT->cb->getDate(Date::DAY_OF_WEEK) != 1) // not first day of the week
aiProgress->setFrame((aiProgress->size() - 1) * progress); CCS->soundh->playSound(soundBase::newDay);
else if(LOCPLINT->cb->getDate(Date::WEEK) != 1) // not first week in month
CCS->soundh->playSound(soundBase::newWeek);
else if(LOCPLINT->cb->getDate(Date::MONTH) != 1) // not first month
CCS->soundh->playSound(soundBase::newMonth);
else
CCS->soundh->playSound(soundBase::newDay);
} }
void CInfoBar::reset(EState newState = EMPTY) void CInfoBar::reset()
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
state = EMPTY;
vstd::clear_pointer(visibleInfo); visibleInfo = std::make_shared<EmptyVisibleInfo>();
currentObject = nullptr;
state = newState;
visibleInfo = new CVisibleInfo(Point(8, 12));
} }
void CInfoBar::showSelection() void CInfoBar::showSelection()
{ {
if (adventureInt->selection) OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
if(adventureInt->selection)
{ {
auto hero = dynamic_cast<const CGHeroInstance *>(adventureInt->selection); if(auto hero = dynamic_cast<const CGHeroInstance *>(adventureInt->selection))
if (hero)
{ {
showHeroSelection(hero); showHeroSelection(hero);
return; return;
} }
auto town = dynamic_cast<const CGTownInstance *>(adventureInt->selection); else if(auto town = dynamic_cast<const CGTownInstance *>(adventureInt->selection))
if (town)
{ {
showTownSelection(town); showTownSelection(town);
return; return;
@ -891,11 +867,11 @@ void CInfoBar::tick()
void CInfoBar::clickLeft(tribool down, bool previousState) void CInfoBar::clickLeft(tribool down, bool previousState)
{ {
if (down) if(down)
{ {
if (state == HERO || state == TOWN) if(state == HERO || state == TOWN)
showGameStatus(); showGameStatus();
else if (state == GAME) else if(state == GAME)
showDate(); showDate();
else else
showSelection(); showSelection();
@ -909,83 +885,96 @@ void CInfoBar::clickRight(tribool down, bool previousState)
void CInfoBar::hover(bool on) void CInfoBar::hover(bool on)
{ {
if (on) if(on)
GH.statusbar->setText(CGI->generaltexth->zelp[292].first); GH.statusbar->setText(CGI->generaltexth->zelp[292].first);
else else
GH.statusbar->clear(); GH.statusbar->clear();
} }
CInfoBar::CInfoBar(const Rect &position): CInfoBar::CInfoBar(const Rect & position)
CIntObject(LCLICK | RCLICK | HOVER, position.topLeft()), : CIntObject(LCLICK | RCLICK | HOVER, position.topLeft()),
visibleInfo(nullptr), state(EMPTY)
state(EMPTY),
currentObject(nullptr)
{ {
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
pos.w = position.w; pos.w = position.w;
pos.h = position.h; pos.h = position.h;
//FIXME: enable some mode? Should be done by advMap::select() when game starts but just in case? reset();
} }
void CInfoBar::showDate() void CInfoBar::showDate()
{ {
reset(DATE); OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
visibleInfo->loadDay(); playNewDaySound();
state = DATE;
visibleInfo = std::make_shared<VisibleDateInfo>();
setTimer(3000); setTimer(3000);
redraw(); redraw();
} }
void CInfoBar::showComponent(const Component & comp, std::string message) void CInfoBar::showComponent(const Component & comp, std::string message)
{ {
reset(COMPONENT); OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
visibleInfo->loadComponent(comp, message); state = COMPONENT;
visibleInfo = std::make_shared<VisibleComponentInfo>(comp, message);
setTimer(3000); setTimer(3000);
redraw(); redraw();
} }
void CInfoBar::startEnemyTurn(PlayerColor color) void CInfoBar::startEnemyTurn(PlayerColor color)
{ {
reset(AITURN); OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
visibleInfo->loadEnemyTurn(color); state = AITURN;
redraw(); visibleInfo = std::make_shared<VisibleEnemyTurnInfo>(color);
}
void CInfoBar::updateEnemyTurn(double progress)
{
assert(state == AITURN);
visibleInfo->updateEnemyTurn(progress);
redraw(); redraw();
} }
void CInfoBar::showHeroSelection(const CGHeroInstance * hero) void CInfoBar::showHeroSelection(const CGHeroInstance * hero)
{ {
if (!hero) OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
return; if(!hero)
{
reset(HERO); reset();
currentObject = hero; }
visibleInfo->loadHero(hero); else
{
state = HERO;
visibleInfo = std::make_shared<VisibleHeroInfo>(hero);
}
redraw(); redraw();
} }
void CInfoBar::showTownSelection(const CGTownInstance * town) void CInfoBar::showTownSelection(const CGTownInstance * town)
{ {
if (!town) OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
return; if(!town)
{
reset(TOWN); reset();
currentObject = town; }
visibleInfo->loadTown(town); else
{
state = TOWN;
visibleInfo = std::make_shared<VisibleTownInfo>(town);
}
redraw(); redraw();
} }
void CInfoBar::showGameStatus() void CInfoBar::showGameStatus()
{ {
reset(GAME); OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
visibleInfo->loadGameStatus(); state = GAME;
visibleInfo = std::make_shared<VisibleGameStatusInfo>();
setTimer(3000); setTimer(3000);
redraw(); redraw();
} }
CInGameConsole::CInGameConsole()
: CIntObject(KEYBOARD | TEXTINPUT),
prevEntDisp(-1),
defaultTimeout(10000),
maxDisplayedTexts(10)
{
}
void CInGameConsole::show(SDL_Surface * to) void CInGameConsole::show(SDL_Surface * to)
{ {
int number = 0; int number = 0;
@ -1207,11 +1196,6 @@ void CInGameConsole::refreshEnteredText()
} }
} }
CInGameConsole::CInGameConsole() : prevEntDisp(-1), defaultTimeout(10000), maxDisplayedTexts(10)
{
addUsedEvents(KEYBOARD | TEXTINPUT);
}
CAdvMapPanel::CAdvMapPanel(SDL_Surface * bg, Point position) CAdvMapPanel::CAdvMapPanel(SDL_Surface * bg, Point position)
: CIntObject(), : CIntObject(),
background(bg) background(bg)
@ -1233,32 +1217,34 @@ CAdvMapPanel::~CAdvMapPanel()
SDL_FreeSurface(background); SDL_FreeSurface(background);
} }
void CAdvMapPanel::addChildColorableButton(CButton * btn) void CAdvMapPanel::addChildColorableButton(std::shared_ptr<CButton> button)
{ {
buttons.push_back(btn); colorableButtons.push_back(button);
addChildToPanel(btn, ACTIVATE | DEACTIVATE); addChildToPanel(button, ACTIVATE | DEACTIVATE);
} }
void CAdvMapPanel::setPlayerColor(const PlayerColor & clr) void CAdvMapPanel::setPlayerColor(const PlayerColor & clr)
{ {
for (auto &btn : buttons) for(auto & button : colorableButtons)
{ {
btn->setPlayerColor(clr); button->setPlayerColor(clr);
} }
} }
void CAdvMapPanel::showAll(SDL_Surface * to) void CAdvMapPanel::showAll(SDL_Surface * to)
{ {
if (background) if(background)
blitAt(background, pos.x, pos.y, to); blitAt(background, pos.x, pos.y, to);
CIntObject::showAll(to); CIntObject::showAll(to);
} }
void CAdvMapPanel::addChildToPanel(CIntObject * obj, ui8 actions) void CAdvMapPanel::addChildToPanel(std::shared_ptr<CIntObject> obj, ui8 actions)
{ {
otherObjects.push_back(obj);
obj->recActions |= actions | SHOWALL; obj->recActions |= actions | SHOWALL;
addChild(obj, false); obj->recActions &= ~DISPOSE;
addChild(obj.get(), false);
} }
CAdvMapWorldViewPanel::CAdvMapWorldViewPanel(std::shared_ptr<CAnimation> _icons, SDL_Surface * bg, Point position, int spaceBottom, const PlayerColor &color) CAdvMapWorldViewPanel::CAdvMapWorldViewPanel(std::shared_ptr<CAnimation> _icons, SDL_Surface * bg, Point position, int spaceBottom, const PlayerColor &color)
@ -1280,7 +1266,7 @@ CAdvMapWorldViewPanel::~CAdvMapWorldViewPanel()
SDL_FreeSurface(tmpBackgroundFiller); SDL_FreeSurface(tmpBackgroundFiller);
} }
void CAdvMapWorldViewPanel::recolorIcons(const PlayerColor &color, int indexOffset) void CAdvMapWorldViewPanel::recolorIcons(const PlayerColor & color, int indexOffset)
{ {
assert(iconsData.size() == currentIcons.size()); assert(iconsData.size() == currentIcons.size());
@ -1290,9 +1276,9 @@ void CAdvMapWorldViewPanel::recolorIcons(const PlayerColor &color, int indexOffs
currentIcons[idx]->setFrame(data.first + indexOffset); currentIcons[idx]->setFrame(data.first + indexOffset);
} }
if (fillerHeight > 0) if(fillerHeight > 0)
{ {
if (tmpBackgroundFiller) if(tmpBackgroundFiller)
SDL_FreeSurface(tmpBackgroundFiller); SDL_FreeSurface(tmpBackgroundFiller);
tmpBackgroundFiller = CMessage::drawDialogBox(pos.w, fillerHeight, color); tmpBackgroundFiller = CMessage::drawDialogBox(pos.w, fillerHeight, color);
} }
@ -1300,9 +1286,9 @@ void CAdvMapWorldViewPanel::recolorIcons(const PlayerColor &color, int indexOffs
void CAdvMapWorldViewPanel::addChildIcon(std::pair<int, Point> data, int indexOffset) void CAdvMapWorldViewPanel::addChildIcon(std::pair<int, Point> data, int indexOffset)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
iconsData.push_back(data); iconsData.push_back(data);
currentIcons.push_back(new CAnimImage(icons, data.first + indexOffset, 0, data.second.x, data.second.y)); currentIcons.push_back(std::make_shared<CAnimImage>(icons, data.first + indexOffset, 0, data.second.x, data.second.y));
} }
void CAdvMapWorldViewPanel::showAll(SDL_Surface * to) void CAdvMapWorldViewPanel::showAll(SDL_Surface * to)

View File

@ -22,18 +22,22 @@ class CGHeroInstance;
class CGTownInstance; class CGTownInstance;
class CButton; class CButton;
struct Component; struct Component;
class CComponent;
struct InfoAboutArmy; struct InfoAboutArmy;
struct InfoAboutHero; struct InfoAboutHero;
struct InfoAboutTown; struct InfoAboutTown;
class CHeroTooltip;
class CTownTooltip;
class CTextBox;
/// Base UI Element for hero\town lists /// Base UI Element for hero\town lists
class CList : public CIntObject class CList : public CIntObject
{ {
protected: protected:
class CListItem : public CIntObject class CListItem : public CIntObject, public std::enable_shared_from_this<CListItem>
{ {
CList * parent; CList * parent;
CIntObject * selection; std::shared_ptr<CIntObject> selection;
public: public:
CListItem(CList * parent); CListItem(CList * parent);
~CListItem(); ~CListItem();
@ -44,7 +48,7 @@ protected:
void onSelect(bool on); void onSelect(bool on);
/// create object with selection rectangle /// create object with selection rectangle
virtual CIntObject * genSelection()=0; virtual std::shared_ptr<CIntObject> genSelection()=0;
/// reaction on item selection (e.g. enable selection border) /// reaction on item selection (e.g. enable selection border)
/// NOTE: item may be deleted in selected state /// NOTE: item may be deleted in selected state
virtual void select(bool on)=0; virtual void select(bool on)=0;
@ -56,7 +60,7 @@ protected:
virtual std::string getHoverText()=0; virtual std::string getHoverText()=0;
}; };
CListBox * list; std::shared_ptr<CListBox> listBox;
const size_t size; const size_t size;
/** /**
@ -71,22 +75,20 @@ protected:
* @param create - function for creating items in listbox * @param create - function for creating items in listbox
* @param destroy - function for deleting items in listbox * @param destroy - function for deleting items in listbox
*/ */
CList(int size, Point position, std::string btnUp, std::string btnDown, size_t listAmount, int helpUp, int helpDown, CList(int size, Point position, std::string btnUp, std::string btnDown, size_t listAmount, int helpUp, int helpDown, CListBox::CreateFunc create);
CListBox::CreateFunc create, CListBox::DestroyFunc destroy = CListBox::DestroyFunc());
//for selection\deselection //for selection\deselection
CListItem *selected; std::shared_ptr<CListItem> selected;
void select(CListItem * which); void select(std::shared_ptr<CListItem> which);
friend class CListItem; friend class CListItem;
std::shared_ptr<CButton> scrollUp;
std::shared_ptr<CButton> scrollDown;
/// should be called when list is invalidated /// should be called when list is invalidated
void update(); void update();
public: public:
CButton * scrollUp;
CButton * scrollDown;
/// functions that will be called when selection changes /// functions that will be called when selection changes
CFunctionList<void()> onSelect; CFunctionList<void()> onSelect;
@ -105,21 +107,24 @@ class CHeroList : public CList
/// Empty hero item used as placeholder for unused entries in list /// Empty hero item used as placeholder for unused entries in list
class CEmptyHeroItem : public CIntObject class CEmptyHeroItem : public CIntObject
{ {
std::shared_ptr<CAnimImage> movement;
std::shared_ptr<CAnimImage> mana;
std::shared_ptr<CPicture> portrait;
public: public:
CEmptyHeroItem(); CEmptyHeroItem();
}; };
class CHeroItem : public CListItem class CHeroItem : public CListItem
{ {
CAnimImage * movement; std::shared_ptr<CAnimImage> movement;
CAnimImage * mana; std::shared_ptr<CAnimImage> mana;
CAnimImage * portrait; std::shared_ptr<CAnimImage> portrait;
public: public:
const CGHeroInstance * const hero; const CGHeroInstance * const hero;
CHeroItem(CHeroList *parent, const CGHeroInstance * hero); CHeroItem(CHeroList * parent, const CGHeroInstance * hero);
CIntObject * genSelection() override; std::shared_ptr<CIntObject> genSelection() override;
void update(); void update();
void select(bool on) override; void select(bool on) override;
void open() override; void open() override;
@ -127,7 +132,7 @@ class CHeroList : public CList
std::string getHoverText() override; std::string getHoverText() override;
}; };
CIntObject * createHeroItem(size_t index); std::shared_ptr<CIntObject> createHeroItem(size_t index);
public: public:
/** /**
* @brief CHeroList * @brief CHeroList
@ -147,13 +152,13 @@ class CTownList : public CList
{ {
class CTownItem : public CListItem class CTownItem : public CListItem
{ {
CAnimImage * picture; std::shared_ptr<CAnimImage> picture;
public: public:
const CGTownInstance * const town; const CGTownInstance * const town;
CTownItem(CTownList *parent, const CGTownInstance * town); CTownItem(CTownList *parent, const CGTownInstance * town);
CIntObject * genSelection() override; std::shared_ptr<CIntObject> genSelection() override;
void update(); void update();
void select(bool on) override; void select(bool on) override;
void open() override; void open() override;
@ -161,7 +166,7 @@ class CTownList : public CList
std::string getHoverText() override; std::string getHoverText() override;
}; };
CIntObject * createTownItem(size_t index); std::shared_ptr<CIntObject> createTownItem(size_t index);
public: public:
/** /**
* @brief CTownList * @brief CTownList
@ -180,14 +185,14 @@ class CMinimap;
class CMinimapInstance : public CIntObject class CMinimapInstance : public CIntObject
{ {
CMinimap *parent; CMinimap * parent;
SDL_Surface * minimap; SDL_Surface * minimap;
int level; int level;
//get color of selected tile on minimap //get color of selected tile on minimap
const SDL_Color & getTileColor(const int3 & pos); const SDL_Color & getTileColor(const int3 & pos);
void blitTileWithColor(const SDL_Color & color, const int3 & pos, SDL_Surface *to, int x, int y); void blitTileWithColor(const SDL_Color & color, const int3 & pos, SDL_Surface * to, int x, int y);
//draw minimap already scaled. //draw minimap already scaled.
//result is not antialiased. Will result in "missing" pixels on huge maps (>144) //result is not antialiased. Will result in "missing" pixels on huge maps (>144)
@ -196,19 +201,17 @@ public:
CMinimapInstance(CMinimap * parent, int level); CMinimapInstance(CMinimap * parent, int level);
~CMinimapInstance(); ~CMinimapInstance();
void showAll(SDL_Surface *to) override; void showAll(SDL_Surface * to) override;
void tileToPixels (const int3 &tile, int &x, int &y,int toX = 0, int toY = 0); void tileToPixels (const int3 & tile, int & x, int & y, int toX = 0, int toY = 0);
void refreshTile(const int3 & pos);
void refreshTile(const int3 &pos);
}; };
/// Minimap which is displayed at the right upper corner of adventure map /// Minimap which is displayed at the right upper corner of adventure map
class CMinimap : public CIntObject class CMinimap : public CIntObject
{ {
protected: protected:
std::shared_ptr<CPicture> aiShield; //the graphic displayed during AI turn
CPicture *aiShield; //the graphic displayed during AI turn std::shared_ptr<CMinimapInstance> minimap;
CMinimapInstance * minimap;
int level; int level;
//to initialize colors //to initialize colors
@ -245,30 +248,73 @@ class CInfoBar : public CIntObject
//all visible information located in one object - for ease of replacing //all visible information located in one object - for ease of replacing
class CVisibleInfo : public CIntObject class CVisibleInfo : public CIntObject
{ {
//list of objects that must be redrawed on each frame on a top of animation public:
std::list<CIntObject *> forceRefresh; void show(SDL_Surface * to) override;
//the only part of gui we need to know about for updating - AI progress protected:
CAnimImage *aiProgress; std::shared_ptr<CPicture> background;
std::list<std::shared_ptr<CIntObject>> forceRefresh;
CVisibleInfo();
};
class EmptyVisibleInfo : public CVisibleInfo
{
public:
EmptyVisibleInfo();
};
class VisibleHeroInfo : public CVisibleInfo
{
std::shared_ptr<CHeroTooltip> heroTooltip;
public:
VisibleHeroInfo(const CGHeroInstance * hero);
};
class VisibleTownInfo : public CVisibleInfo
{
std::shared_ptr<CTownTooltip> townTooltip;
public:
VisibleTownInfo(const CGTownInstance * town);
};
class VisibleDateInfo : public CVisibleInfo
{
std::shared_ptr<CShowableAnim> animation;
std::shared_ptr<CLabel> label;
std::string getNewDayName(); std::string getNewDayName();
void playNewDaySound();
public: public:
CVisibleInfo(Point position); VisibleDateInfo();
};
void show(SDL_Surface *to) override; class VisibleEnemyTurnInfo : public CVisibleInfo
{
std::shared_ptr<CAnimImage> banner;
std::shared_ptr<CShowableAnim> glass;
std::shared_ptr<CShowableAnim> sand;
public:
VisibleEnemyTurnInfo(PlayerColor player);
};
//functions that must be called only once class VisibleGameStatusInfo : public CVisibleInfo
void loadHero(const CGHeroInstance * hero); {
void loadTown(const CGTownInstance * town); std::shared_ptr<CLabel> allyLabel;
void loadDay(); std::shared_ptr<CLabel> enemyLabel;
void loadEnemyTurn(PlayerColor player);
void loadGameStatus();
void loadComponent(const Component &comp, std::string message);
//can be called multiple times std::vector<std::shared_ptr<CAnimImage>> flags;
void updateEnemyTurn(double progress); std::vector<std::shared_ptr<CAnimImage>> hallIcons;
std::vector<std::shared_ptr<CLabel>> hallLabels;
public:
VisibleGameStatusInfo();
};
class VisibleComponentInfo : public CVisibleInfo
{
std::shared_ptr<CComponent> comp;
std::shared_ptr<CTextBox> text;
public:
VisibleComponentInfo(const Component & compToDisplay, std::string message);
}; };
enum EState enum EState
@ -276,13 +322,11 @@ class CInfoBar : public CIntObject
EMPTY, HERO, TOWN, DATE, GAME, AITURN, COMPONENT EMPTY, HERO, TOWN, DATE, GAME, AITURN, COMPONENT
}; };
CVisibleInfo * visibleInfo; std::shared_ptr<CVisibleInfo> visibleInfo;
EState state; EState state;
//currently displayed object. May be null if state is not hero or town
const CGObjectInstance * currentObject;
//removes all information about current state, deactivates timer (if any) //removes all information about current state, deactivates timer (if any)
void reset(EState newState); void reset();
void tick() override; void tick() override;
@ -290,6 +334,7 @@ class CInfoBar : public CIntObject
void clickRight(tribool down, bool previousState) override; void clickRight(tribool down, bool previousState) override;
void hover(bool on) override; void hover(bool on) override;
void playNewDaySound();
public: public:
CInfoBar(const Rect & pos); CInfoBar(const Rect & pos);
@ -301,9 +346,6 @@ public:
/// print enemy turn progress /// print enemy turn progress
void startEnemyTurn(PlayerColor color); void startEnemyTurn(PlayerColor color);
/// updates enemy turn.
/// NOTE: currently DISABLED. Check comments in CInfoBar::CVisibleInfo::loadEnemyTurn()
void updateEnemyTurn(double progress);
/// reset to default view - selected object /// reset to default view - selected object
void showSelection(); void showSelection();
@ -319,16 +361,16 @@ public:
/// simple panel that contains other displayable elements; used to separate groups of controls /// simple panel that contains other displayable elements; used to separate groups of controls
class CAdvMapPanel : public CIntObject class CAdvMapPanel : public CIntObject
{ {
/// ptrs to child-buttons that can be recolored with setPlayerColor() std::vector<std::shared_ptr<CButton>> colorableButtons;
std::vector<CButton *> buttons; std::vector<std::shared_ptr<CIntObject>> otherObjects;
/// the surface passed to this obj will be freed in dtor /// the surface passed to this obj will be freed in dtor
SDL_Surface * background; SDL_Surface * background;
public: public:
CAdvMapPanel(SDL_Surface * bg, Point position); CAdvMapPanel(SDL_Surface * bg, Point position);
virtual ~CAdvMapPanel(); virtual ~CAdvMapPanel();
void addChildToPanel(CIntObject * obj, ui8 actions = 0); void addChildToPanel(std::shared_ptr<CIntObject> obj, ui8 actions = 0);
void addChildColorableButton(CButton * btn); void addChildColorableButton(std::shared_ptr<CButton> button);
/// recolors all buttons to given player color /// recolors all buttons to given player color
void setPlayerColor(const PlayerColor & clr); void setPlayerColor(const PlayerColor & clr);
@ -341,7 +383,7 @@ class CAdvMapWorldViewPanel : public CAdvMapPanel
/// data that allows reconstruction of panel info icons /// data that allows reconstruction of panel info icons
std::vector<std::pair<int, Point>> iconsData; std::vector<std::pair<int, Point>> iconsData;
/// ptrs to child-pictures constructed from iconsData /// ptrs to child-pictures constructed from iconsData
std::vector<CAnimImage *> currentIcons; std::vector<std::shared_ptr<CAnimImage>> currentIcons;
/// temporary surface drawn below world view panel on higher resolutions (won't be needed when world view panel is configured for extraResolutions mod) /// temporary surface drawn below world view panel on higher resolutions (won't be needed when world view panel is configured for extraResolutions mod)
SDL_Surface * tmpBackgroundFiller; SDL_Surface * tmpBackgroundFiller;
int fillerHeight; int fillerHeight;
@ -352,7 +394,7 @@ public:
void addChildIcon(std::pair<int, Point> data, int indexOffset); void addChildIcon(std::pair<int, Point> data, int indexOffset);
/// recreates all pictures from given def to recolor them according to current player color /// recreates all pictures from given def to recolor them according to current player color
void recolorIcons(const PlayerColor &color, int indexOffset); void recolorIcons(const PlayerColor & color, int indexOffset);
void showAll(SDL_Surface * to) override; void showAll(SDL_Surface * to) override;
}; };

View File

@ -74,18 +74,17 @@ void CButton::addCallback(std::function<void()> callback)
this->callback += callback; this->callback += callback;
} }
void CButton::addTextOverlay( const std::string &Text, EFonts font, SDL_Color color) void CButton::addTextOverlay(const std::string & Text, EFonts font, SDL_Color color)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
addOverlay(new CLabel(pos.w/2, pos.h/2, font, CENTER, color, Text)); addOverlay(std::make_shared<CLabel>(pos.w/2, pos.h/2, font, CENTER, color, Text));
update(); update();
} }
void CButton::addOverlay(CIntObject *newOverlay) void CButton::addOverlay(std::shared_ptr<CIntObject> newOverlay)
{ {
delete overlay;
overlay = newOverlay; overlay = newOverlay;
addChild(newOverlay); addChild(newOverlay.get());
overlay->moveTo(overlay->pos.centerIn(pos).topLeft()); overlay->moveTo(overlay->pos.centerIn(pos).topLeft());
update(); update();
} }
@ -235,6 +234,7 @@ CButton::CButton(Point position, const std::string &defName, const std::pair<std
CKeyShortcut(key), CKeyShortcut(key),
callback(Callback) callback(Callback)
{ {
defActions = 255-DISPOSE;
addUsedEvents(LCLICK | RCLICK | HOVER | KEYBOARD); addUsedEvents(LCLICK | RCLICK | HOVER | KEYBOARD);
stateToIndex[0] = 0; stateToIndex[0] = 0;
@ -243,8 +243,6 @@ CButton::CButton(Point position, const std::string &defName, const std::pair<std
stateToIndex[3] = 3; stateToIndex[3] = 3;
state=NORMAL; state=NORMAL;
image = nullptr;
overlay = nullptr;
currentImage = -1; currentImage = -1;
hoverable = actOnDown = soundDisabled = false; hoverable = actOnDown = soundDisabled = false;
@ -272,9 +270,9 @@ void CButton::setIndex(size_t index, bool playerColoredButton)
void CButton::setImage(std::shared_ptr<CAnimation> anim, bool playerColoredButton, int animFlags) void CButton::setImage(std::shared_ptr<CAnimation> anim, bool playerColoredButton, int animFlags)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
image = new CAnimImage(anim, getState(), 0, 0, 0, animFlags); image = std::make_shared<CAnimImage>(anim, getState(), 0, 0, 0, animFlags);
if (playerColoredButton) if (playerColoredButton)
image->playerColored(LOCPLINT->playerID); image->playerColored(LOCPLINT->playerID);
pos = image->pos; pos = image->pos;
@ -317,9 +315,7 @@ CToggleBase::CToggleBase(CFunctionList<void (bool)> callback):
{ {
} }
CToggleBase::~CToggleBase() CToggleBase::~CToggleBase() = default;
{
}
void CToggleBase::doSelect(bool on) void CToggleBase::doSelect(bool on)
{ {
@ -399,25 +395,30 @@ void CToggleGroup::addCallback(std::function<void(int)> callback)
onChange += callback; onChange += callback;
} }
void CToggleGroup::addToggle(int identifier, CToggleBase* bt) void CToggleGroup::resetCallback()
{ {
if (auto intObj = dynamic_cast<CIntObject*>(bt)) // hack-ish workagound to avoid diamond problem with inheritance onChange.clear();
}
void CToggleGroup::addToggle(int identifier, std::shared_ptr<CToggleBase> button)
{
if(auto intObj = std::dynamic_pointer_cast<CIntObject>(button)) // hack-ish workagound to avoid diamond problem with inheritance
{ {
if (intObj->parent) addChild(intObj.get());
intObj->parent->removeChild(intObj);
addChild(intObj);
} }
bt->addCallback([=] (bool on) { if (on) selectionChanged(identifier);}); button->addCallback([=] (bool on) { if (on) selectionChanged(identifier);});
bt->allowDeselection = false; button->allowDeselection = false;
assert(buttons[identifier] == nullptr); if(buttons.count(identifier)>0)
buttons[identifier] = bt; logAnim->error("Duplicated toggle button id %d", identifier);
buttons[identifier] = button;
} }
CToggleGroup::CToggleGroup(const CFunctionList<void(int)> &OnChange) CToggleGroup::CToggleGroup(const CFunctionList<void(int)> &OnChange)
: onChange(OnChange), selectedID(-2) : onChange(OnChange), selectedID(-2)
{} {
}
void CToggleGroup::setSelected(int id) void CToggleGroup::setSelected(int id)
{ {
@ -443,15 +444,13 @@ void CToggleGroup::selectionChanged(int to)
parent->redraw(); parent->redraw();
} }
CVolumeSlider::CVolumeSlider(const Point &position, const std::string &defName, const int value, CVolumeSlider::CVolumeSlider(const Point & position, const std::string & defName, const int value, const std::pair<std::string, std::string> * const help)
const std::pair<std::string, std::string> * const help) : : CIntObject(LCLICK | RCLICK | WHEEL),
value(value), value(value),
helpHandlers(help) helpHandlers(help)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
animImage = new CAnimImage(std::make_shared<CAnimation>(defName), 0, 0, position.x, position.y), animImage = std::make_shared<CAnimImage>(std::make_shared<CAnimation>(defName), 0, 0, position.x, position.y),
assert(!defName.empty());
addUsedEvents(LCLICK | RCLICK | WHEEL);
pos.x += position.x; pos.x += position.x;
pos.y += position.y; pos.y += position.y;
pos.w = (animImage->pos.w + 1) * animImage->size(); pos.w = (animImage->pos.w + 1) * animImage->size();
@ -658,25 +657,20 @@ void CSlider::clickLeft(tribool down, bool previousState)
removeUsedEvents(MOVE); removeUsedEvents(MOVE);
} }
CSlider::~CSlider() CSlider::CSlider(Point position, int totalw, std::function<void(int)> Moved, int Capacity, int Amount, int Value, bool Horizontal, CSlider::EStyle style)
: CIntObject(LCLICK | RCLICK | WHEEL),
capacity(Capacity),
horizontal(Horizontal),
amount(Amount),
value(Value),
scrollStep(1),
moved(Moved)
{ {
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
}
CSlider::CSlider(Point position, int totalw, std::function<void(int)> Moved, int Capacity, int Amount, int Value, bool Horizontal, CSlider::EStyle style):
capacity(Capacity),
horizontal(Horizontal),
amount(Amount),
value(Value),
scrollStep(1),
moved(Moved)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
setAmount(amount); setAmount(amount);
vstd::amax(value, 0); vstd::amax(value, 0);
vstd::amin(value, positions); vstd::amin(value, positions);
addUsedEvents(LCLICK | KEYBOARD | WHEEL);
strongInterest = true; strongInterest = true;
pos.x += position.x; pos.x += position.x;
@ -684,12 +678,12 @@ CSlider::CSlider(Point position, int totalw, std::function<void(int)> Moved, int
if(style == BROWN) if(style == BROWN)
{ {
std::string name = horizontal?"IGPCRDIV.DEF":"OVBUTN2.DEF"; std::string name = horizontal ? "IGPCRDIV.DEF" : "OVBUTN2.DEF";
//NOTE: this images do not have "blocked" frames. They should be implemented somehow (e.g. palette transform or something...) //NOTE: this images do not have "blocked" frames. They should be implemented somehow (e.g. palette transform or something...)
left = new CButton(Point(), name, CButton::tooltip()); left = std::make_shared<CButton>(Point(), name, CButton::tooltip());
right = new CButton(Point(), name, CButton::tooltip()); right = std::make_shared<CButton>(Point(), name, CButton::tooltip());
slider = new CButton(Point(), name, CButton::tooltip()); slider = std::make_shared<CButton>(Point(), name, CButton::tooltip());
left->setImageOrder(0, 1, 1, 1); left->setImageOrder(0, 1, 1, 1);
right->setImageOrder(2, 3, 3, 3); right->setImageOrder(2, 3, 3, 3);
@ -697,9 +691,9 @@ CSlider::CSlider(Point position, int totalw, std::function<void(int)> Moved, int
} }
else else
{ {
left = new CButton(Point(), horizontal ? "SCNRBLF.DEF" : "SCNRBUP.DEF", CButton::tooltip()); left = std::make_shared<CButton>(Point(), horizontal ? "SCNRBLF.DEF" : "SCNRBUP.DEF", CButton::tooltip());
right = new CButton(Point(), horizontal ? "SCNRBRT.DEF" : "SCNRBDN.DEF", CButton::tooltip()); right = std::make_shared<CButton>(Point(), horizontal ? "SCNRBRT.DEF" : "SCNRBDN.DEF", CButton::tooltip());
slider = new CButton(Point(), "SCNRBSL.DEF", CButton::tooltip()); slider = std::make_shared<CButton>(Point(), "SCNRBSL.DEF", CButton::tooltip());
} }
slider->actOnDown = true; slider->actOnDown = true;
slider->soundDisabled = true; slider->soundDisabled = true;
@ -729,6 +723,8 @@ CSlider::CSlider(Point position, int totalw, std::function<void(int)> Moved, int
updateSliderPos(); updateSliderPos();
} }
CSlider::~CSlider() = default;
void CSlider::block( bool on ) void CSlider::block( bool on )
{ {
left->block(on); left->block(on);

View File

@ -50,8 +50,8 @@ private:
std::array<boost::optional<SDL_Color>, 4> stateToBorderColor; // mapping of button state to border color std::array<boost::optional<SDL_Color>, 4> stateToBorderColor; // mapping of button state to border color
std::string helpBox; //for right-click help std::string helpBox; //for right-click help
CAnimImage * image; //image for this button std::shared_ptr<CAnimImage> image; //image for this button
CIntObject * overlay;//object-overlay, can be null std::shared_ptr<CIntObject> overlay;//object-overlay, can be null
bool animateLonelyFrame = false; bool animateLonelyFrame = false;
protected: protected:
void onButtonClicked(); // calls callback void onButtonClicked(); // calls callback
@ -80,8 +80,8 @@ public:
void addCallback(std::function<void()> callback); void addCallback(std::function<void()> callback);
/// adds overlay on top of button image. Only one overlay can be active at once /// adds overlay on top of button image. Only one overlay can be active at once
void addOverlay(CIntObject * newOverlay); void addOverlay(std::shared_ptr<CIntObject> newOverlay);
void addTextOverlay(const std::string &Text, EFonts font, SDL_Color color = Colors::WHITE); void addTextOverlay(const std::string & Text, EFonts font, SDL_Color color = Colors::WHITE);
void addImage(std::string filename); void addImage(std::string filename);
void addHoverText(ButtonState state, std::string text); void addHoverText(ButtonState state, std::string text);
@ -95,7 +95,7 @@ public:
bool isHighlighted(); bool isHighlighted();
/// Constructor /// Constructor
CButton(Point position, const std::string &defName, const std::pair<std::string, std::string> &help, CButton(Point position, const std::string & defName, const std::pair<std::string, std::string> & help,
CFunctionList<void()> Callback = 0, int key=0, bool playerColoredButton = false ); CFunctionList<void()> Callback = 0, int key=0, bool playerColoredButton = false );
/// Appearance modifiers /// Appearance modifiers
@ -162,14 +162,15 @@ class CToggleGroup : public CIntObject
int selectedID; int selectedID;
void selectionChanged(int to); void selectionChanged(int to);
public: public:
std::map<int, CToggleBase*> buttons; std::map<int, std::shared_ptr<CToggleBase>> buttons;
CToggleGroup(const CFunctionList<void(int)> & OnChange); CToggleGroup(const CFunctionList<void(int)> & OnChange);
void addCallback(std::function<void(int)> callback); void addCallback(std::function<void(int)> callback);
void resetCallback();
/// add one toggle/button into group /// add one toggle/button into group
void addToggle(int index, CToggleBase * button); void addToggle(int index, std::shared_ptr<CToggleBase> button);
/// Changes selection to specific value. Will select toggle with this ID, if present /// Changes selection to specific value. Will select toggle with this ID, if present
void setSelected(int id); void setSelected(int id);
}; };
@ -179,7 +180,7 @@ class CVolumeSlider : public CIntObject
{ {
int value; int value;
CFunctionList<void(int)> onChange; CFunctionList<void(int)> onChange;
CAnimImage * animImage; std::shared_ptr<CAnimImage> animImage;
const std::pair<std::string, std::string> * const helpHandlers; const std::pair<std::string, std::string> * const helpHandlers;
void setVolume(const int v); void setVolume(const int v);
public: public:
@ -188,7 +189,7 @@ public:
/// @param defName name of def animation for slider /// @param defName name of def animation for slider
/// @param value initial value for volume /// @param value initial value for volume
/// @param help pointer to first helptext of slider /// @param help pointer to first helptext of slider
CVolumeSlider(const Point &position, const std::string &defName, const int value, CVolumeSlider(const Point & position, const std::string & defName, const int value,
const std::pair<std::string, std::string> * const help); const std::pair<std::string, std::string> * const help);
void moveTo(int id); void moveTo(int id);
@ -203,7 +204,11 @@ public:
/// A typical slider which can be orientated horizontally/vertically. /// A typical slider which can be orientated horizontally/vertically.
class CSlider : public CIntObject class CSlider : public CIntObject
{ {
CButton *left, *right, *slider; //if vertical then left=up //if vertical then left=up
std::shared_ptr<CButton> left;
std::shared_ptr<CButton> right;
std::shared_ptr<CButton> slider;
int capacity;//how many elements can be active at same time (e.g. hero list = 5) int capacity;//how many elements can be active at same time (e.g. hero list = 5)
int positions; //number of highest position (0 if there is only one) int positions; //number of highest position (0 if there is only one)
bool horizontal; bool horizontal;
@ -216,7 +221,8 @@ class CSlider : public CIntObject
void sliderClicked(); void sliderClicked();
public: public:
enum EStyle { enum EStyle
{
BROWN, BROWN,
BLUE BLUE
}; };

View File

@ -30,27 +30,31 @@
#include "../../lib/mapObjects/CGHeroInstance.h" #include "../../lib/mapObjects/CGHeroInstance.h"
CHeroArtPlace::CHeroArtPlace(Point position, const CArtifactInstance * Art): CArtPlace(position, Art), CHeroArtPlace::CHeroArtPlace(Point position, const CArtifactInstance * Art)
locked(false), picked(false), marked(false), ourOwner(nullptr) : CArtPlace(position, Art),
locked(false),
picked(false),
marked(false),
ourOwner(nullptr)
{ {
createImage(); createImage();
} }
void CHeroArtPlace::createImage() void CHeroArtPlace::createImage()
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
int imageIndex = 0; si32 imageIndex = 0;
if (ourArt) if(ourArt)
imageIndex = ourArt->artType->iconIndex; imageIndex = ourArt->artType->iconIndex;
if (locked) if(locked)
imageIndex = ArtifactID::ART_LOCK; imageIndex = ArtifactID::ART_LOCK;
image = new CAnimImage("artifact", imageIndex); image = std::make_shared<CAnimImage>("artifact", imageIndex);
if (!ourArt) if(!ourArt)
image->disable(); image->disable();
selection = new CAnimImage("artifact", ArtifactID::ART_SELECTION); selection = std::make_shared<CAnimImage>("artifact", ArtifactID::ART_SELECTION);
selection->disable(); selection->disable();
} }
@ -137,7 +141,7 @@ void CHeroArtPlace::clickLeft(tribool down, bool previousState)
{ {
if(ourArt->artType->id == ArtifactID::CATAPULT) //catapult cannot be highlighted if(ourArt->artType->id == ArtifactID::CATAPULT) //catapult cannot be highlighted
{ {
std::vector<CComponent *> catapult(1, new CComponent(CComponent::artifact, 3, 0)); std::vector<std::shared_ptr<CComponent>> catapult(1, std::make_shared<CComponent>(CComponent::artifact, 3, 0));
LOCPLINT->showInfoDialog(CGI->generaltexth->allTexts[312], catapult); //The Catapult must be equipped. LOCPLINT->showInfoDialog(CGI->generaltexth->allTexts[312], catapult); //The Catapult must be equipped.
return; return;
} }
@ -284,8 +288,8 @@ void CHeroArtPlace::select ()
{ {
for(int i = 0; i < GameConstants::BACKPACK_START; i++) for(int i = 0; i < GameConstants::BACKPACK_START; i++)
{ {
CHeroArtPlace * ap = ourOwner->getArtPlace(i); auto ap = ourOwner->getArtPlace(i);
if(nullptr != ap)//getArtPlace may return null if(ap)//getArtPlace may return null
ap->pickSlot(ourArt->isPart(ap->ourArt)); ap->pickSlot(ourArt->isPart(ap->ourArt));
} }
} }
@ -492,7 +496,7 @@ void CArtifactsOfHero::scrollBackpack(int dir)
{ {
if(elem->marked) if(elem->marked)
{ {
highlightModeCallback(elem); highlightModeCallback(elem.get());
break; break;
} }
} }
@ -504,7 +508,6 @@ void CArtifactsOfHero::scrollBackpack(int dir)
rightArtRoll->block(!scrollingPossible); rightArtRoll->block(!scrollingPossible);
safeRedraw(); safeRedraw();
} }
/** /**
@ -538,9 +541,10 @@ void CArtifactsOfHero::unmarkSlots(bool withRedraw)
void CArtifactsOfHero::unmarkLocalSlots(bool withRedraw) void CArtifactsOfHero::unmarkLocalSlots(bool withRedraw)
{ {
for(auto p : artWorn) for(auto & p : artWorn)
p.second->selectSlot(false); p.second->selectSlot(false);
for(CHeroArtPlace *place : backpack)
for(auto & place : backpack)
place->selectSlot(false); place->selectSlot(false);
if(withRedraw) if(withRedraw)
@ -550,7 +554,7 @@ void CArtifactsOfHero::unmarkLocalSlots(bool withRedraw)
/** /**
* Assigns an artifacts to an artifact place depending on it's new slot ID. * Assigns an artifacts to an artifact place depending on it's new slot ID.
*/ */
void CArtifactsOfHero::setSlotData(CHeroArtPlace* artPlace, ArtifactPosition slotID) void CArtifactsOfHero::setSlotData(ArtPlacePtr artPlace, ArtifactPosition slotID)
{ {
if(!artPlace && slotID >= GameConstants::BACKPACK_START) //spurious call from artifactMoved in attempt to update hidden backpack slot if(!artPlace && slotID >= GameConstants::BACKPACK_START) //spurious call from artifactMoved in attempt to update hidden backpack slot
{ {
@ -572,21 +576,25 @@ void CArtifactsOfHero::setSlotData(CHeroArtPlace* artPlace, ArtifactPosition slo
/** /**
* Makes given artifact slot appear as empty with a certain slot ID. * Makes given artifact slot appear as empty with a certain slot ID.
*/ */
void CArtifactsOfHero::eraseSlotData (CHeroArtPlace* artPlace, ArtifactPosition slotID) void CArtifactsOfHero::eraseSlotData(ArtPlacePtr artPlace, ArtifactPosition slotID)
{ {
artPlace->pickSlot(false); artPlace->pickSlot(false);
artPlace->slotID = slotID; artPlace->slotID = slotID;
artPlace->setArtifact(nullptr); artPlace->setArtifact(nullptr);
} }
CArtifactsOfHero::CArtifactsOfHero(std::map<ArtifactPosition, CHeroArtPlace *> ArtWorn, std::vector<CHeroArtPlace *> Backpack, CArtifactsOfHero::CArtifactsOfHero(ArtPlaceMap ArtWorn, std::vector<ArtPlacePtr> Backpack,
CButton *leftScroll, CButton *rightScroll, bool createCommonPart): std::shared_ptr<CButton> leftScroll, std::shared_ptr<CButton> rightScroll, bool createCommonPart)
: curHero(nullptr),
curHero(nullptr), artWorn(ArtWorn),
artWorn(ArtWorn), backpack(Backpack), backpack(Backpack),
backpackPos(0), commonInfo(nullptr), updateState(false), backpackPos(0),
leftArtRoll(leftScroll), rightArtRoll(rightScroll), commonInfo(nullptr),
allowedAssembling(true), highlightModeCallback(nullptr) updateState(false),
leftArtRoll(leftScroll),
rightArtRoll(rightScroll),
allowedAssembling(true),
highlightModeCallback(nullptr)
{ {
if(createCommonPart) if(createCommonPart)
{ {
@ -595,7 +603,7 @@ CArtifactsOfHero::CArtifactsOfHero(std::map<ArtifactPosition, CHeroArtPlace *> A
} }
// Init slots for worn artifacts. // Init slots for worn artifacts.
for (auto p : artWorn) for(auto p : artWorn)
{ {
p.second->ourOwner = this; p.second->ourOwner = this;
eraseSlotData(p.second, p.first); eraseSlotData(p.second, p.first);
@ -608,12 +616,17 @@ CArtifactsOfHero::CArtifactsOfHero(std::map<ArtifactPosition, CHeroArtPlace *> A
eraseSlotData(backpack[s], ArtifactPosition(GameConstants::BACKPACK_START + s)); eraseSlotData(backpack[s], ArtifactPosition(GameConstants::BACKPACK_START + s));
} }
leftArtRoll->addCallback(std::bind(&CArtifactsOfHero::scrollBackpack,this,-1)); leftArtRoll->addCallback(std::bind(&CArtifactsOfHero::scrollBackpack, this,-1));
rightArtRoll->addCallback(std::bind(&CArtifactsOfHero::scrollBackpack,this,+1)); rightArtRoll->addCallback(std::bind(&CArtifactsOfHero::scrollBackpack, this,+1));
} }
CArtifactsOfHero::CArtifactsOfHero(const Point& position, bool createCommonPart) CArtifactsOfHero::CArtifactsOfHero(const Point & position, bool createCommonPart)
: curHero(nullptr), backpackPos(0), commonInfo(nullptr), updateState(false), allowedAssembling(true), highlightModeCallback(nullptr) : curHero(nullptr),
backpackPos(0),
commonInfo(nullptr),
updateState(false),
allowedAssembling(true),
highlightModeCallback(nullptr)
{ {
if(createCommonPart) if(createCommonPart)
{ {
@ -621,7 +634,7 @@ CArtifactsOfHero::CArtifactsOfHero(const Point& position, bool createCommonPart)
commonInfo->participants.insert(this); commonInfo->participants.insert(this);
} }
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
pos += position; pos += position;
std::vector<Point> slotPos = std::vector<Point> slotPos =
@ -636,9 +649,9 @@ CArtifactsOfHero::CArtifactsOfHero(const Point& position, bool createCommonPart)
}; };
// Create slots for worn artifacts. // Create slots for worn artifacts.
for (size_t g = 0; g < GameConstants::BACKPACK_START ; g++) for(size_t g = 0; g < GameConstants::BACKPACK_START; g++)
{ {
artWorn[ArtifactPosition(g)] = new CHeroArtPlace(slotPos[g]); artWorn[ArtifactPosition(g)] = std::make_shared<CHeroArtPlace>(slotPos[g]);
artWorn[ArtifactPosition(g)]->ourOwner = this; artWorn[ArtifactPosition(g)]->ourOwner = this;
eraseSlotData(artWorn[ArtifactPosition(g)], ArtifactPosition(g)); eraseSlotData(artWorn[ArtifactPosition(g)], ArtifactPosition(g));
} }
@ -646,7 +659,7 @@ CArtifactsOfHero::CArtifactsOfHero(const Point& position, bool createCommonPart)
// Create slots for the backpack. // Create slots for the backpack.
for(size_t s=0; s<5; ++s) for(size_t s=0; s<5; ++s)
{ {
auto add = new CHeroArtPlace(Point(403 + 46 * s, 365)); auto add = std::make_shared<CHeroArtPlace>(Point(403 + 46 * s, 365));
add->ourOwner = this; add->ourOwner = this;
eraseSlotData(add, ArtifactPosition(GameConstants::BACKPACK_START + s)); eraseSlotData(add, ArtifactPosition(GameConstants::BACKPACK_START + s));
@ -654,8 +667,8 @@ CArtifactsOfHero::CArtifactsOfHero(const Point& position, bool createCommonPart)
backpack.push_back(add); backpack.push_back(add);
} }
leftArtRoll = new CButton(Point(379, 364), "hsbtns3.def", CButton::tooltip(), [&](){ scrollBackpack(-1);}, SDLK_LEFT); leftArtRoll = std::make_shared<CButton>(Point(379, 364), "hsbtns3.def", CButton::tooltip(), [&](){ scrollBackpack(-1);}, SDLK_LEFT);
rightArtRoll = new CButton(Point(632, 364), "hsbtns5.def", CButton::tooltip(), [&](){ scrollBackpack(+1);}, SDLK_RIGHT); rightArtRoll = std::make_shared<CButton>(Point(632, 364), "hsbtns5.def", CButton::tooltip(), [&](){ scrollBackpack(+1);}, SDLK_RIGHT);
} }
CArtifactsOfHero::~CArtifactsOfHero() CArtifactsOfHero::~CArtifactsOfHero()
@ -674,7 +687,6 @@ void CArtifactsOfHero::updateParentWindow()
} }
else if(CExchangeWindow* cew = dynamic_cast<CExchangeWindow*>(GH.topInt())) else if(CExchangeWindow* cew = dynamic_cast<CExchangeWindow*>(GH.topInt()))
{ {
//use our copy of hero to draw window //use our copy of hero to draw window
if(cew->heroInst[0]->id == curHero->id) if(cew->heroInst[0]->id == curHero->id)
cew->heroInst[0] = curHero; cew->heroInst[0] = curHero;
@ -684,16 +696,7 @@ void CArtifactsOfHero::updateParentWindow()
if(!updateState) if(!updateState)
{ {
cew->deactivate(); cew->deactivate();
// for(int g=0; g<ARRAY_COUNT(cew->heroInst); ++g) cew->updateWidgets();
// {
// if(cew->heroInst[g] == curHero)
// {
// cew->artifs[g]->setHero(curHero);
// }
// }
cew->prepareBackground();
cew->redraw(); cew->redraw();
cew->activate(); cew->activate();
} }
@ -746,7 +749,7 @@ void CArtifactsOfHero::artifactMoved(const ArtifactLocation &src, const Artifact
assert(dst.slot >= GameConstants::BACKPACK_START); assert(dst.slot >= GameConstants::BACKPACK_START);
commonInfo->reset(); commonInfo->reset();
CHeroArtPlace *ap = nullptr; CArtifactsOfHero::ArtPlacePtr ap;
for(CArtifactsOfHero *aoh : commonInfo->participants) for(CArtifactsOfHero *aoh : commonInfo->participants)
{ {
if(dst.isHolder(aoh->curHero)) if(dst.isHolder(aoh->curHero))
@ -811,7 +814,7 @@ void CArtifactsOfHero::artifactRemoved(const ArtifactLocation &al)
} }
} }
CHeroArtPlace * CArtifactsOfHero::getArtPlace(int slot) CArtifactsOfHero::ArtPlacePtr CArtifactsOfHero::getArtPlace(int slot)
{ {
if(slot < GameConstants::BACKPACK_START) if(slot < GameConstants::BACKPACK_START)
{ {
@ -825,7 +828,7 @@ CHeroArtPlace * CArtifactsOfHero::getArtPlace(int slot)
} }
else else
{ {
for(CHeroArtPlace *ap : backpack) for(ArtPlacePtr ap : backpack)
if(ap->slotID == slot) if(ap->slotID == slot)
return ap; return ap;
return nullptr; return nullptr;
@ -867,21 +870,47 @@ CArtifactHolder::CArtifactHolder()
{ {
} }
void CWindowWithArtifacts::addSet(std::shared_ptr<CArtifactsOfHero> artSet)
{
artSets.emplace_back(artSet);
}
std::shared_ptr<CArtifactsOfHero::SCommonPart> CWindowWithArtifacts::getCommonPart()
{
for(auto artSetWeak : artSets)
{
std::shared_ptr<CArtifactsOfHero> realPtr = artSetWeak.lock();
if(realPtr)
return realPtr->commonInfo;
}
return std::shared_ptr<CArtifactsOfHero::SCommonPart>();
}
void CWindowWithArtifacts::artifactRemoved(const ArtifactLocation &artLoc) void CWindowWithArtifacts::artifactRemoved(const ArtifactLocation &artLoc)
{ {
for(CArtifactsOfHero *aoh : artSets) for(auto artSetWeak : artSets)
aoh->artifactRemoved(artLoc); {
std::shared_ptr<CArtifactsOfHero> realPtr = artSetWeak.lock();
if(realPtr)
realPtr->artifactRemoved(artLoc);
}
} }
void CWindowWithArtifacts::artifactMoved(const ArtifactLocation &artLoc, const ArtifactLocation &destLoc) void CWindowWithArtifacts::artifactMoved(const ArtifactLocation &artLoc, const ArtifactLocation &destLoc)
{ {
CArtifactsOfHero *destaoh = nullptr; CArtifactsOfHero * destaoh = nullptr;
for(CArtifactsOfHero *aoh : artSets)
for(auto artSetWeak : artSets)
{ {
aoh->artifactMoved(artLoc, destLoc); std::shared_ptr<CArtifactsOfHero> realPtr = artSetWeak.lock();
aoh->redraw(); if(realPtr)
if(destLoc.isHolder(aoh->getHero())) {
destaoh = aoh; realPtr->artifactMoved(artLoc, destLoc);
realPtr->redraw();
if(destLoc.isHolder(realPtr->getHero()))
destaoh = realPtr.get();
}
} }
//Make sure the status bar is updated so it does not display old text //Make sure the status bar is updated so it does not display old text
@ -893,14 +922,22 @@ void CWindowWithArtifacts::artifactMoved(const ArtifactLocation &artLoc, const A
void CWindowWithArtifacts::artifactDisassembled(const ArtifactLocation &artLoc) void CWindowWithArtifacts::artifactDisassembled(const ArtifactLocation &artLoc)
{ {
for(CArtifactsOfHero *aoh : artSets) for(auto artSetWeak : artSets)
aoh->artifactDisassembled(artLoc); {
std::shared_ptr<CArtifactsOfHero> realPtr = artSetWeak.lock();
if(realPtr)
realPtr->artifactDisassembled(artLoc);
}
} }
void CWindowWithArtifacts::artifactAssembled(const ArtifactLocation &artLoc) void CWindowWithArtifacts::artifactAssembled(const ArtifactLocation &artLoc)
{ {
for(CArtifactsOfHero *aoh : artSets) for(auto artSetWeak : artSets)
aoh->artifactAssembled(artLoc); {
std::shared_ptr<CArtifactsOfHero> realPtr = artSetWeak.lock();
if(realPtr)
realPtr->artifactAssembled(artLoc);
}
} }
void CArtifactsOfHero::SCommonPart::Artpos::clear() void CArtifactsOfHero::SCommonPart::Artpos::clear()
@ -979,14 +1016,14 @@ void CCommanderArtPlace::clickRight(tribool down, bool previousState)
void CCommanderArtPlace::createImage() void CCommanderArtPlace::createImage()
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
int imageIndex = 0; int imageIndex = 0;
if (ourArt) if(ourArt)
imageIndex = ourArt->artType->iconIndex; imageIndex = ourArt->artType->iconIndex;
image = new CAnimImage("artifact", imageIndex); image = std::make_shared<CAnimImage>("artifact", imageIndex);
if (!ourArt) if(!ourArt)
image->disable(); image->disable();
} }

View File

@ -9,7 +9,6 @@
*/ */
#pragma once #pragma once
//#include "CComponent.h"
#include "MiscWidgets.h" #include "MiscWidgets.h"
class CArtifactsOfHero; class CArtifactsOfHero;
@ -29,21 +28,10 @@ public:
virtual void artifactAssembled(const ArtifactLocation &artLoc)=0; virtual void artifactAssembled(const ArtifactLocation &artLoc)=0;
}; };
class CWindowWithArtifacts : public CArtifactHolder
{
public:
std::vector<CArtifactsOfHero *> artSets;
void artifactRemoved(const ArtifactLocation &artLoc) override;
void artifactMoved(const ArtifactLocation &artLoc, const ArtifactLocation &destLoc) override;
void artifactDisassembled(const ArtifactLocation &artLoc) override;
void artifactAssembled(const ArtifactLocation &artLoc) override;
};
class CArtPlace : public LRClickableAreaWTextComp class CArtPlace : public LRClickableAreaWTextComp
{ {
protected: protected:
CAnimImage *image; std::shared_ptr<CAnimImage> image;
virtual void createImage()=0; virtual void createImage()=0;
public: public:
const CArtifactInstance * ourArt; // should be changed only with setArtifact() const CArtifactInstance * ourArt; // should be changed only with setArtifact()
@ -75,7 +63,7 @@ public:
/// Artifacts can be placed there. Gets shown at the hero window /// Artifacts can be placed there. Gets shown at the hero window
class CHeroArtPlace: public CArtPlace class CHeroArtPlace: public CArtPlace
{ {
CAnimImage *selection; std::shared_ptr<CAnimImage> selection;
void createImage() override; void createImage() override;
@ -111,14 +99,10 @@ public:
/// Contains artifacts of hero. Distincts which artifacts are worn or backpacked /// Contains artifacts of hero. Distincts which artifacts are worn or backpacked
class CArtifactsOfHero : public CIntObject class CArtifactsOfHero : public CIntObject
{ {
const CGHeroInstance * curHero;
std::map<ArtifactPosition, CHeroArtPlace *> artWorn;
std::vector<CHeroArtPlace *> backpack; //hero's visible backpack (only 5 elements!)
int backpackPos; //number of first art visible in backpack (in hero's vector)
public: public:
using ArtPlacePtr = std::shared_ptr<CHeroArtPlace>;
using ArtPlaceMap = std::map<ArtifactPosition, ArtPlacePtr>;
struct SCommonPart struct SCommonPart
{ {
struct Artpos struct Artpos
@ -142,8 +126,10 @@ public:
bool updateState; // Whether the commonInfo should be updated on setHero or not. bool updateState; // Whether the commonInfo should be updated on setHero or not.
CButton * leftArtRoll, * rightArtRoll; std::shared_ptr<CButton> leftArtRoll;
std::shared_ptr<CButton> rightArtRoll;
bool allowedAssembling; bool allowedAssembling;
std::multiset<const CArtifactInstance*> artifactsOnAltar; //artifacts id that are technically present in backpack but in GUI are moved to the altar - they'll be omitted in backpack slots std::multiset<const CArtifactInstance*> artifactsOnAltar; //artifacts id that are technically present in backpack but in GUI are moved to the altar - they'll be omitted in backpack slots
std::function<void(CHeroArtPlace*)> highlightModeCallback; //if set, clicking on art place doesn't pick artifact but highlights the slot and calls this function std::function<void(CHeroArtPlace*)> highlightModeCallback; //if set, clicking on art place doesn't pick artifact but highlights the slot and calls this function
@ -152,7 +138,7 @@ public:
void artifactRemoved(const ArtifactLocation &al); void artifactRemoved(const ArtifactLocation &al);
void artifactAssembled(const ArtifactLocation &al); void artifactAssembled(const ArtifactLocation &al);
void artifactDisassembled(const ArtifactLocation &al); void artifactDisassembled(const ArtifactLocation &al);
CHeroArtPlace *getArtPlace(int slot);//may return null ArtPlacePtr getArtPlace(int slot);//may return null
void setHero(const CGHeroInstance * hero); void setHero(const CGHeroInstance * hero);
const CGHeroInstance *getHero() const; const CGHeroInstance *getHero() const;
@ -163,17 +149,41 @@ public:
void markPossibleSlots(const CArtifactInstance* art); void markPossibleSlots(const CArtifactInstance* art);
void unmarkSlots(bool withRedraw = true); //unmarks slots in all visible AOHs void unmarkSlots(bool withRedraw = true); //unmarks slots in all visible AOHs
void unmarkLocalSlots(bool withRedraw = true); //unmarks slots in that particular AOH void unmarkLocalSlots(bool withRedraw = true); //unmarks slots in that particular AOH
void setSlotData (CHeroArtPlace* artPlace, ArtifactPosition slotID);
void updateWornSlots (bool redrawParent = true); void updateWornSlots (bool redrawParent = true);
void updateSlot(ArtifactPosition i); void updateSlot(ArtifactPosition i);
void eraseSlotData (CHeroArtPlace* artPlace, ArtifactPosition slotID);
CArtifactsOfHero(const Point& position, bool createCommonPart = false); CArtifactsOfHero(const Point& position, bool createCommonPart = false);
//Alternative constructor, used if custom artifacts positioning required (Kingdom interface) //Alternative constructor, used if custom artifacts positioning required (Kingdom interface)
CArtifactsOfHero(std::map<ArtifactPosition, CHeroArtPlace *> ArtWorn, std::vector<CHeroArtPlace *> Backpack, CArtifactsOfHero(ArtPlaceMap ArtWorn, std::vector<ArtPlacePtr> Backpack,
CButton *leftScroll, CButton *rightScroll, bool createCommonPart = false); std::shared_ptr<CButton> leftScroll, std::shared_ptr<CButton> rightScroll, bool createCommonPart = false);
~CArtifactsOfHero(); ~CArtifactsOfHero();
void updateParentWindow(); void updateParentWindow();
friend class CHeroArtPlace; friend class CHeroArtPlace;
private:
const CGHeroInstance * curHero;
ArtPlaceMap artWorn;
std::vector<ArtPlacePtr> backpack; //hero's visible backpack (only 5 elements!)
int backpackPos; //number of first art visible in backpack (in hero's vector)
void eraseSlotData(ArtPlacePtr artPlace, ArtifactPosition slotID);
void setSlotData(ArtPlacePtr artPlace, ArtifactPosition slotID);
};
class CWindowWithArtifacts : public CArtifactHolder
{
std::vector<std::weak_ptr<CArtifactsOfHero>> artSets;
public:
void addSet(std::shared_ptr<CArtifactsOfHero> artSet);
std::shared_ptr<CArtifactsOfHero::SCommonPart> getCommonPart();
void artifactRemoved(const ArtifactLocation &artLoc) override;
void artifactMoved(const ArtifactLocation &artLoc, const ArtifactLocation &destLoc) override;
void artifactDisassembled(const ArtifactLocation &artLoc) override;
void artifactAssembled(const ArtifactLocation &artLoc) override;
}; };

View File

@ -27,29 +27,26 @@
#include "../../lib/CGeneralTextHandler.h" #include "../../lib/CGeneralTextHandler.h"
#include "../../lib/NetPacksBase.h" #include "../../lib/NetPacksBase.h"
CComponent::CComponent(Etype Type, int Subtype, int Val, ESize imageSize): CComponent::CComponent(Etype Type, int Subtype, int Val, ESize imageSize)
image(nullptr), : perDay(false)
perDay(false)
{ {
addUsedEvents(RCLICK);
init(Type, Subtype, Val, imageSize); init(Type, Subtype, Val, imageSize);
} }
CComponent::CComponent(const Component &c, ESize imageSize): CComponent::CComponent(const Component & c, ESize imageSize)
image(nullptr), : perDay(false)
perDay(false)
{ {
addUsedEvents(RCLICK);
if(c.id == Component::RESOURCE && c.when==-1) if(c.id == Component::RESOURCE && c.when==-1)
perDay = true; perDay = true;
init((Etype)c.id,c.subtype,c.val, imageSize); init((Etype)c.id, c.subtype, c.val, imageSize);
} }
void CComponent::init(Etype Type, int Subtype, int Val, ESize imageSize) void CComponent::init(Etype Type, int Subtype, int Val, ESize imageSize)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
addUsedEvents(RCLICK);
compType = Type; compType = Type;
subtype = Subtype; subtype = Subtype;
@ -74,14 +71,15 @@ void CComponent::init(Etype Type, int Subtype, int Val, ESize imageSize)
for(auto & line : textLines) for(auto & line : textLines)
{ {
int height = graphics->fonts[font]->getLineHeight(); int height = graphics->fonts[font]->getLineHeight();
auto label = new CLabel(pos.w/2, pos.h + height/2, font, CENTER, Colors::WHITE, line); auto label = std::make_shared<CLabel>(pos.w/2, pos.h + height/2, font, CENTER, Colors::WHITE, line);
pos.h += height; pos.h += height;
if (label->pos.w > pos.w) if(label->pos.w > pos.w)
{ {
pos.x -= (label->pos.w - pos.w)/2; pos.x -= (label->pos.w - pos.w)/2;
pos.w = label->pos.w; pos.w = label->pos.w;
} }
lines.push_back(label);
} }
} }
@ -232,9 +230,8 @@ std::string CComponent::getSubtitleInternal()
void CComponent::setSurface(std::string defName, int imgPos) void CComponent::setSurface(std::string defName, int imgPos)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
vstd::clear_pointer(image); image = std::make_shared<CAnimImage>(defName, imgPos);
image = new CAnimImage(defName, imgPos);
} }
void CComponent::clickRight(tribool down, bool previousState) void CComponent::clickRight(tribool down, bool previousState)
@ -291,7 +288,7 @@ void CSelectableComponent::showAll(SDL_Surface * to)
} }
} }
void CComponentBox::selectionChanged(CSelectableComponent * newSelection) void CComponentBox::selectionChanged(std::shared_ptr<CSelectableComponent> newSelection)
{ {
if (newSelection == selected) if (newSelection == selected)
return; return;
@ -339,14 +336,14 @@ void CComponentBox::placeComponents(bool selectable)
{ {
static const int betweenRows = 22; static const int betweenRows = 22;
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
if (components.empty()) if (components.empty())
return; return;
//prepare components //prepare components
for(auto & comp : components) for(auto & comp : components)
{ {
addChild(comp); addChild(comp.get());
comp->moveTo(Point(pos.x, pos.y)); comp->moveTo(Point(pos.x, pos.y));
} }
@ -362,14 +359,14 @@ void CComponentBox::placeComponents(bool selectable)
rows.push_back (RowData (0,0,0)); rows.push_back (RowData (0,0,0));
//split components in rows //split components in rows
CComponent * prevComp = nullptr; std::shared_ptr<CComponent> prevComp;
for(CComponent * comp : components) for(std::shared_ptr<CComponent> comp : components)
{ {
//make sure that components are smaller than our width //make sure that components are smaller than our width
//assert(pos.w == 0 || pos.w < comp->pos.w); //assert(pos.w == 0 || pos.w < comp->pos.w);
const int distance = prevComp ? getDistance(prevComp, comp) : 0; const int distance = prevComp ? getDistance(prevComp.get(), comp.get()) : 0;
//start next row //start next row
if ((pos.w != 0 && rows.back().width + comp->pos.w + distance > pos.w) // row is full if ((pos.w != 0 && rows.back().width + comp->pos.w + distance > pos.w) // row is full
@ -421,11 +418,11 @@ void CComponentBox::placeComponents(bool selectable)
{ {
if (selectable) if (selectable)
{ {
Point orPos = Point(currentX - freeSpace, currentY) + getOrTextPos(prevComp, *iter); Point orPos = Point(currentX - freeSpace, currentY) + getOrTextPos(prevComp.get(), iter->get());
new CLabel(orPos.x, orPos.y, FONT_MEDIUM, CENTER, Colors::WHITE, CGI->generaltexth->allTexts[4]); orLabels.push_back(std::make_shared<CLabel>(orPos.x, orPos.y, FONT_MEDIUM, CENTER, Colors::WHITE, CGI->generaltexth->allTexts[4]));
} }
currentX += getDistance(prevComp, *iter); currentX += getDistance(prevComp.get(), iter->get());
} }
(*iter)->moveBy(Point(currentX, currentY)); (*iter)->moveBy(Point(currentX, currentY));
@ -438,27 +435,16 @@ void CComponentBox::placeComponents(bool selectable)
} }
} }
CComponentBox::CComponentBox(CComponent * _components, Rect position): CComponentBox::CComponentBox(std::vector<std::shared_ptr<CComponent>> _components, Rect position):
components(1, _components), components(_components)
selected(nullptr)
{ {
type |= REDRAW_PARENT; type |= REDRAW_PARENT;
pos = position + pos; pos = position + pos;
placeComponents(false); placeComponents(false);
} }
CComponentBox::CComponentBox(std::vector<CComponent *> _components, Rect position): CComponentBox::CComponentBox(std::vector<std::shared_ptr<CSelectableComponent>> _components, Rect position, std::function<void(int newID)> _onSelect):
components(_components),
selected(nullptr)
{
type |= REDRAW_PARENT;
pos = position + pos;
placeComponents(false);
}
CComponentBox::CComponentBox(std::vector<CSelectableComponent *> _components, Rect position, std::function<void(int newID)> _onSelect):
components(_components.begin(), _components.end()), components(_components.begin(), _components.end()),
selected(nullptr),
onSelect(_onSelect) onSelect(_onSelect)
{ {
type |= REDRAW_PARENT; type |= REDRAW_PARENT;

View File

@ -13,6 +13,7 @@
struct Component; struct Component;
class CAnimImage; class CAnimImage;
class CLabel;
/// common popup window component /// common popup window component
class CComponent : public virtual CIntObject class CComponent : public virtual CIntObject
@ -34,6 +35,8 @@ public:
}; };
private: private:
std::vector<std::shared_ptr<CLabel>> lines;
size_t getIndex(); size_t getIndex();
const std::vector<std::string> getFileName(); const std::vector<std::string> getFileName();
void setSurface(std::string defName, int imgPos); void setSurface(std::string defName, int imgPos);
@ -42,7 +45,7 @@ private:
void init(Etype Type, int Subtype, int Val, ESize imageSize); void init(Etype Type, int Subtype, int Val, ESize imageSize);
public: public:
CAnimImage *image; //our image std::shared_ptr<CAnimImage> image;
Etype compType; //component type Etype compType; //component type
ESize size; //component size. ESize size; //component size.
@ -72,19 +75,21 @@ public:
void clickLeft(tribool down, bool previousState) override; //call-in void clickLeft(tribool down, bool previousState) override; //call-in
CSelectableComponent(Etype Type, int Sub, int Val, ESize imageSize=large, std::function<void()> OnSelect = nullptr); CSelectableComponent(Etype Type, int Sub, int Val, ESize imageSize=large, std::function<void()> OnSelect = nullptr);
CSelectableComponent(const Component &c, std::function<void()> OnSelect = nullptr); CSelectableComponent(const Component & c, std::function<void()> OnSelect = nullptr);
}; };
/// box with multiple components (up to 8?) /// box with multiple components (up to 8?)
/// will take ownership on components and delete them afterwards /// will take ownership on components and delete them afterwards
class CComponentBox : public CIntObject class CComponentBox : public CIntObject
{ {
std::vector<CComponent *> components; std::vector<std::shared_ptr<CComponent>> components;
CSelectableComponent * selected; std::vector<std::shared_ptr<CLabel>> orLabels;
std::shared_ptr<CSelectableComponent> selected;
std::function<void(int newID)> onSelect; std::function<void(int newID)> onSelect;
void selectionChanged(CSelectableComponent * newSelection); void selectionChanged(std::shared_ptr<CSelectableComponent> newSelection);
//get position of "or" text between these comps //get position of "or" text between these comps
//it will place "or" equidistant to both images //it will place "or" equidistant to both images
@ -98,14 +103,11 @@ public:
/// return index of selected item /// return index of selected item
int selectedIndex(); int selectedIndex();
/// constructor for quite common 1-components popups
/// if position width or height are 0 then it will be determined automatically
CComponentBox(CComponent * components, Rect position);
/// constructor for non-selectable components /// constructor for non-selectable components
CComponentBox(std::vector<CComponent *> components, Rect position); CComponentBox(std::vector<std::shared_ptr<CComponent>> components, Rect position);
/// constructor for selectable components /// constructor for selectable components
/// will also create "or" labels between components /// will also create "or" labels between components
/// onSelect - optional function that will be called every time on selection change /// onSelect - optional function that will be called every time on selection change
CComponentBox(std::vector<CSelectableComponent *> components, Rect position, std::function<void(int newID)> onSelect = nullptr); CComponentBox(std::vector<std::shared_ptr<CSelectableComponent>> components, Rect position, std::function<void(int newID)> onSelect = nullptr);
}; };

View File

@ -172,8 +172,12 @@ bool CGarrisonSlot::highlightOrDropArtifact()
bool artSelected = false; bool artSelected = false;
if (CWindowWithArtifacts* chw = dynamic_cast<CWindowWithArtifacts*>(GH.topInt())) //dirty solution if (CWindowWithArtifacts* chw = dynamic_cast<CWindowWithArtifacts*>(GH.topInt())) //dirty solution
{ {
const std::shared_ptr<CArtifactsOfHero::SCommonPart> commonInfo = chw->artSets.front()->commonInfo; const std::shared_ptr<CArtifactsOfHero::SCommonPart> commonInfo = chw->getCommonPart();
if (const CArtifactInstance *art = commonInfo->src.art) const CArtifactInstance * art = nullptr;
if(commonInfo)
art = commonInfo->src.art;
if(art)
{ {
const CGHeroInstance *srcHero = commonInfo->src.AOH->getHero(); const CGHeroInstance *srcHero = commonInfo->src.AOH->getHero();
artSelected = true; artSelected = true;
@ -335,7 +339,7 @@ void CGarrisonSlot::clickLeft(tribool down, bool previousState)
void CGarrisonSlot::update() void CGarrisonSlot::update()
{ {
if (getObj() != nullptr) if(getObj() != nullptr)
{ {
addUsedEvents(LCLICK | RCLICK | HOVER); addUsedEvents(LCLICK | RCLICK | HOVER);
myStack = getObj()->getStackPtr(ID); myStack = getObj()->getStackPtr(ID);
@ -348,7 +352,7 @@ void CGarrisonSlot::update()
creature = nullptr; creature = nullptr;
} }
if (creature) if(creature)
{ {
creatureImage->enable(); creatureImage->enable();
creatureImage->setFrame(creature->iconIndex); creatureImage->setFrame(creature->iconIndex);
@ -363,26 +367,24 @@ void CGarrisonSlot::update()
} }
} }
CGarrisonSlot::CGarrisonSlot(CGarrisonInt *Owner, int x, int y, SlotID IID, CGarrisonSlot::EGarrisonType Upg, const CStackInstance * Creature): CGarrisonSlot::CGarrisonSlot(CGarrisonInt * Owner, int x, int y, SlotID IID, CGarrisonSlot::EGarrisonType Upg, const CStackInstance * Creature)
ID(IID), : ID(IID),
owner(Owner), owner(Owner),
myStack(Creature), myStack(Creature),
creature(Creature ? Creature->type : nullptr), creature(nullptr),
upg(Upg) upg(Upg)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
if (getObj())
addUsedEvents(LCLICK | RCLICK | HOVER);
pos.x += x; pos.x += x;
pos.y += y; pos.y += y;
std::string imgName = owner->smallIcons ? "cprsmall" : "TWCRPORT"; std::string imgName = owner->smallIcons ? "cprsmall" : "TWCRPORT";
creatureImage = new CAnimImage(imgName, creature ? creature->iconIndex : 0); creatureImage = std::make_shared<CAnimImage>(imgName, 0);
if (!creature) creatureImage->disable();
creatureImage->disable();
selectionImage = new CAnimImage(imgName, 1); selectionImage = std::make_shared<CAnimImage>(imgName, 1);
selectionImage->disable(); selectionImage->disable();
if(Owner->smallIcons) if(Owner->smallIcons)
@ -396,11 +398,9 @@ CGarrisonSlot::CGarrisonSlot(CGarrisonInt *Owner, int x, int y, SlotID IID, CGar
pos.h = 64; pos.h = 64;
} }
stackCount = new CLabel(pos.w, pos.h, owner->smallIcons ? FONT_TINY : FONT_MEDIUM, BOTTOMRIGHT, Colors::WHITE); stackCount = std::make_shared<CLabel>(pos.w, pos.h, owner->smallIcons ? FONT_TINY : FONT_MEDIUM, BOTTOMRIGHT, Colors::WHITE);
if (!creature)
stackCount->disable(); update();
else
stackCount->setText(boost::lexical_cast<std::string>(myStack->count));
} }
void CGarrisonSlot::splitIntoParts(CGarrisonSlot::EGarrisonType type, int amount, int maxOfSplittedSlots) void CGarrisonSlot::splitIntoParts(CGarrisonSlot::EGarrisonType type, int amount, int maxOfSplittedSlots)
@ -419,8 +419,9 @@ void CGarrisonSlot::splitIntoParts(CGarrisonSlot::EGarrisonType type, int amount
void CGarrisonSlot::handleSplittingShortcuts() void CGarrisonSlot::handleSplittingShortcuts()
{ {
const Uint8 * state = SDL_GetKeyboardState(NULL); const Uint8 * state = SDL_GetKeyboardState(NULL);
if(owner->getSelection() && owner->getEmptySlots(owner->getSelection()->upg).size() && owner->getSelection()->myStack->count > 1){ if(owner->getSelection() && owner->getEmptySlots(owner->getSelection()->upg).size() && owner->getSelection()->myStack->count > 1)
if (state[SDL_SCANCODE_LCTRL] && state[SDL_SCANCODE_LSHIFT]) {
if(state[SDL_SCANCODE_LCTRL] && state[SDL_SCANCODE_LSHIFT])
splitIntoParts(owner->getSelection()->upg, 1, 7); splitIntoParts(owner->getSelection()->upg, 1, 7);
else if(state[SDL_SCANCODE_LCTRL]) else if(state[SDL_SCANCODE_LCTRL])
splitIntoParts(owner->getSelection()->upg, 1, 1); splitIntoParts(owner->getSelection()->upg, 1, 1);
@ -432,39 +433,38 @@ void CGarrisonSlot::handleSplittingShortcuts()
} }
} }
void CGarrisonInt::addSplitBtn(CButton * button) void CGarrisonInt::addSplitBtn(std::shared_ptr<CButton> button)
{ {
addChild(button); addChild(button.get());
button->recActions = defActions; button->recActions &= ~DISPOSE;
splitButtons.push_back(button); splitButtons.push_back(button);
button->block(getSelection() == nullptr); button->block(getSelection() == nullptr);
} }
void CGarrisonInt::createSlots() void CGarrisonInt::createSlots()
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; int distance = interx + (smallIcons ? 32 : 58);
int distance = interx + (smallIcons? 32 : 58);
for(int i=0; i<2; i++) for(int i=0; i<2; i++)
{ {
std::vector<CGarrisonSlot*> garrisonSlots; std::vector<std::shared_ptr<CGarrisonSlot>> garrisonSlots;
garrisonSlots.resize(7); garrisonSlots.resize(7);
if (armedObjs[i]) if(armedObjs[i])
{ {
for(auto & elem : armedObjs[i]->Slots()) for(auto & elem : armedObjs[i]->Slots())
{ {
garrisonSlots[elem.first.getNum()] = new CGarrisonSlot(this, i*garOffset.x + (elem.first.getNum()*distance), i*garOffset.y, elem.first, static_cast<CGarrisonSlot::EGarrisonType>(i), elem.second); garrisonSlots[elem.first.getNum()] = std::make_shared<CGarrisonSlot>(this, i*garOffset.x + (elem.first.getNum()*distance), i*garOffset.y, elem.first, static_cast<CGarrisonSlot::EGarrisonType>(i), elem.second);
} }
} }
for(int j=0; j<7; j++) for(int j=0; j<7; j++)
{ {
if(!garrisonSlots[j]) if(!garrisonSlots[j])
garrisonSlots[j] = new CGarrisonSlot(this, i*garOffset.x + (j*distance), i*garOffset.y, SlotID(j), static_cast<CGarrisonSlot::EGarrisonType>(i), nullptr); garrisonSlots[j] = std::make_shared<CGarrisonSlot>(this, i*garOffset.x + (j*distance), i*garOffset.y, SlotID(j), static_cast<CGarrisonSlot::EGarrisonType>(i), nullptr);
if (twoRows && j>=4) if(twoRows && j>=4)
{ {
garrisonSlots[j]->moveBy(Point(-126, 37)); garrisonSlots[j]->moveBy(Point(-126, 37));
} }
} }
std::copy(garrisonSlots.begin(), garrisonSlots.end(), std::back_inserter(availableSlots)); vstd::concatenate(availableSlots, garrisonSlots);
} }
} }
@ -476,10 +476,8 @@ void CGarrisonInt::recreateSlots()
for(auto & elem : splitButtons) for(auto & elem : splitButtons)
elem->block(true); elem->block(true);
for(auto slot : availableSlots)
for(CGarrisonSlot * slot : availableSlots)
slot->update(); slot->update();
} }
void CGarrisonInt::splitClick() void CGarrisonInt::splitClick()
@ -494,19 +492,20 @@ void CGarrisonInt::splitStacks(int, int amountRight)
LOCPLINT->cb->splitStack(armedObjs[getSelection()->upg], armedObjs[pb], getSelection()->ID, p2, amountRight); LOCPLINT->cb->splitStack(armedObjs[getSelection()->upg], armedObjs[pb], getSelection()->ID, p2, amountRight);
} }
CGarrisonInt::CGarrisonInt(int x, int y, int inx, const Point &garsOffset, CGarrisonInt::CGarrisonInt(int x, int y, int inx, const Point & garsOffset,
SDL_Surface *pomsur, const Point& SurOffset, const CArmedInstance * s1, const CArmedInstance * s2,
const CArmedInstance *s1, const CArmedInstance *s2, bool _removableUnits, bool smallImgs, bool _twoRows)
bool _removableUnits, bool smallImgs, bool _twoRows ) : : highlighted(nullptr),
highlighted(nullptr), inSplittingMode(false),
inSplittingMode(false), interx(inx),
interx(inx), garOffset(garsOffset),
garOffset(garsOffset), pb(false),
pb(false), smallIcons(smallImgs),
smallIcons(smallImgs), removableUnits(_removableUnits),
removableUnits(_removableUnits), twoRows(_twoRows)
twoRows(_twoRows)
{ {
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
setArmy(s1, false); setArmy(s1, false);
setArmy(s2, true); setArmy(s2, true);
pos.x += x; pos.x += x;
@ -521,16 +520,16 @@ const CGarrisonSlot * CGarrisonInt::getSelection()
void CGarrisonInt::selectSlot(CGarrisonSlot *slot) void CGarrisonInt::selectSlot(CGarrisonSlot *slot)
{ {
if (slot != highlighted) if(slot != highlighted)
{ {
if (highlighted) if(highlighted)
highlighted->setHighlight(false); highlighted->setHighlight(false);
highlighted = slot; highlighted = slot;
for (auto button : splitButtons) for(auto button : splitButtons)
button->block(highlighted == nullptr || !slot->our()); button->block(highlighted == nullptr || !slot->our());
if (highlighted) if(highlighted)
highlighted->setHighlight(true); highlighted->setHighlight(true);
} }
} }
@ -539,11 +538,11 @@ void CGarrisonInt::setSplittingMode(bool on)
{ {
assert(on == false || highlighted != nullptr); //can't be in splitting mode without selection assert(on == false || highlighted != nullptr); //can't be in splitting mode without selection
if (inSplittingMode || on) if(inSplittingMode || on)
{ {
for(CGarrisonSlot * slot : availableSlots) for(auto slot : availableSlots)
{ {
if(slot!=getSelection()) if(slot.get() != getSelection())
slot->setHighlight( ( on && (slot->our() || slot->ally()) && (slot->creature == nullptr || slot->creature == getSelection()->creature))); slot->setHighlight( ( on && (slot->our() || slot->ally()) && (slot->creature == nullptr || slot->creature == getSelection()->creature)));
} }
inSplittingMode = on; inSplittingMode = on;
@ -558,58 +557,16 @@ bool CGarrisonInt::getSplittingMode()
std::vector<CGarrisonSlot *> CGarrisonInt::getEmptySlots(CGarrisonSlot::EGarrisonType type) std::vector<CGarrisonSlot *> CGarrisonInt::getEmptySlots(CGarrisonSlot::EGarrisonType type)
{ {
std::vector<CGarrisonSlot *> emptySlots; std::vector<CGarrisonSlot *> emptySlots;
for(CGarrisonSlot * slot : availableSlots) for(auto slot : availableSlots)
{ {
if(type == slot->upg && ((slot->our() || slot->ally()) && slot->creature == nullptr)) if(type == slot->upg && ((slot->our() || slot->ally()) && slot->creature == nullptr))
emptySlots.push_back(slot); emptySlots.push_back(slot.get());
} }
return emptySlots; return emptySlots;
} }
void CGarrisonInt::setArmy(const CArmedInstance *army, bool bottomGarrison) void CGarrisonInt::setArmy(const CArmedInstance * army, bool bottomGarrison)
{ {
owned[bottomGarrison] = army ? (army->tempOwner == LOCPLINT->playerID || army->tempOwner == PlayerColor::UNFLAGGABLE) : false; owned[bottomGarrison] = army ? (army->tempOwner == LOCPLINT->playerID || army->tempOwner == PlayerColor::UNFLAGGABLE) : false;
armedObjs[bottomGarrison] = army; armedObjs[bottomGarrison] = army;
} }
CGarrisonWindow::CGarrisonWindow( const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits ):
CWindowObject(PLAYER_COLORED, "GARRISON")
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
garr = new CGarrisonInt(92, 127, 4, Point(0,96), background->bg, Point(93,127), up, down, removableUnits);
{
CButton *split = new CButton(Point(88, 314), "IDV6432.DEF", CButton::tooltip(CGI->generaltexth->tcommands[3], ""), [&](){ garr->splitClick(); } );
removeChild(split);
garr->addSplitBtn(split);
}
quit = new CButton(Point(399, 314), "IOK6432.DEF", CButton::tooltip(CGI->generaltexth->tcommands[8], ""), [&](){ close(); }, SDLK_RETURN);
std::string titleText;
if (down->tempOwner == up->tempOwner)
titleText = CGI->generaltexth->allTexts[709];
else
{
//assume that this is joining monsters dialog
if(up->Slots().size() > 0)
{
titleText = CGI->generaltexth->allTexts[35];
boost::algorithm::replace_first(titleText, "%s", up->Slots().begin()->second->type->namePl);
}
else
logGlobal->error("Invalid armed instance for garrison window.");
}
new CLabel(275, 30, FONT_BIG, CENTER, Colors::YELLOW, titleText);
new CAnimImage("CREST58", up->getOwner().getNum(), 0, 28, 124);
new CAnimImage("PortraitsLarge", down->portrait, 0, 29, 222);
}
CGarrisonHolder::CGarrisonHolder()
{
}
void CWindowWithGarrison::updateGarrisons()
{
garr->recreateSlots();
}

View File

@ -25,8 +25,8 @@ class CGarrisonSlot : public CIntObject
{ {
SlotID ID; //for identification SlotID ID; //for identification
CGarrisonInt *owner; CGarrisonInt *owner;
const CStackInstance *myStack; //nullptr if slot is empty const CStackInstance * myStack; //nullptr if slot is empty
const CCreature *creature; const CCreature * creature;
/// Type of Garrison for slot (up or down) /// Type of Garrison for slot (up or down)
enum EGarrisonType enum EGarrisonType
@ -35,9 +35,9 @@ class CGarrisonSlot : public CIntObject
DOWN, ///< 1 - down garrison (Visiting) DOWN, ///< 1 - down garrison (Visiting)
} upg; ///< Flag indicating if it is the up or down garrison } upg; ///< Flag indicating if it is the up or down garrison
CAnimImage * creatureImage; std::shared_ptr<CAnimImage> creatureImage;
CAnimImage * selectionImage; // image for selection, not always visible std::shared_ptr<CAnimImage> selectionImage; // image for selection, not always visible
CLabel * stackCount; std::shared_ptr<CLabel> stackCount;
bool viewInfo(); bool viewInfo();
bool highlightOrDropArtifact(); bool highlightOrDropArtifact();
@ -65,19 +65,15 @@ public:
class CGarrisonInt :public CIntObject class CGarrisonInt :public CIntObject
{ {
/// Chosen slot. Should be changed only via selectSlot. /// Chosen slot. Should be changed only via selectSlot.
CGarrisonSlot *highlighted; CGarrisonSlot * highlighted;
bool inSplittingMode; bool inSplittingMode;
std::vector<std::shared_ptr<CGarrisonSlot>> availableSlots; ///< Slots of upper and lower garrison
void createSlots();
public: public:
void selectSlot(CGarrisonSlot * slot); ///< @param slot null = deselect
const CGarrisonSlot * getSelection();
void setSplittingMode(bool on);
bool getSplittingMode();
int interx; ///< Space between slots int interx; ///< Space between slots
Point garOffset; ///< Offset between garrisons (not used if only one hero) Point garOffset; ///< Offset between garrisons (not used if only one hero)
std::vector<CButton *> splitButtons; ///< May be empty if no buttons std::vector<std::shared_ptr<CButton>> splitButtons; ///< May be empty if no buttons
SlotID p2; ///< TODO: comment me SlotID p2; ///< TODO: comment me
bool pb, bool pb,
@ -86,15 +82,19 @@ public:
twoRows, ///< slots Will be placed in 2 rows twoRows, ///< slots Will be placed in 2 rows
owned[2]; ///< player Owns up or down army ([0] upper, [1] lower) owned[2]; ///< player Owns up or down army ([0] upper, [1] lower)
std::vector<CGarrisonSlot *> availableSlots; ///< Slots of upper and lower garrison void selectSlot(CGarrisonSlot * slot); ///< @param slot null = deselect
const CGarrisonSlot * getSelection();
void setSplittingMode(bool on);
bool getSplittingMode();
std::vector<CGarrisonSlot *> getEmptySlots(CGarrisonSlot::EGarrisonType type); std::vector<CGarrisonSlot *> getEmptySlots(CGarrisonSlot::EGarrisonType type);
const CArmedInstance *armedObjs[2]; ///< [0] is upper, [1] is down const CArmedInstance * armedObjs[2]; ///< [0] is upper, [1] is down
void setArmy(const CArmedInstance *army, bool bottomGarrison); void setArmy(const CArmedInstance * army, bool bottomGarrison);
void addSplitBtn(CButton * button); void addSplitBtn(std::shared_ptr<CButton> button);
void createSlots();
void recreateSlots(); void recreateSlots();
void splitClick(); ///< handles click on split button void splitClick(); ///< handles click on split button
@ -104,40 +104,21 @@ public:
/// @param x, y Position /// @param x, y Position
/// @param inx Distance between slots; /// @param inx Distance between slots;
/// @param garsOffset /// @param garsOffset
/// @param pomsur, SurOffset UNUSED
/// @param s1, s2 Top and bottom armies /// @param s1, s2 Top and bottom armies
/// @param _removableUnits You can take units from top /// @param _removableUnits You can take units from top
/// @param smallImgs Units images size 64x58 or 32x32 /// @param smallImgs Units images size 64x58 or 32x32
/// @param _twoRows Display slots in 2 row (1st row = 4 slots, 2nd = 3 slots) /// @param _twoRows Display slots in 2 row (1st row = 4 slots, 2nd = 3 slots)
CGarrisonInt(int x, int y, CGarrisonInt(int x, int y, int inx,
int inx, const Point & garsOffset,
const Point &garsOffset, const CArmedInstance * s1, const CArmedInstance * s2 = nullptr,
SDL_Surface *pomsur, const Point &SurOffset, bool _removableUnits = true,
const CArmedInstance *s1, const CArmedInstance *s2=nullptr, bool smallImgs = false,
bool _removableUnits = true, bool _twoRows = false);
bool smallImgs = false,
bool _twoRows=false);
}; };
class CGarrisonHolder class CGarrisonHolder
{ {
public: public:
CGarrisonHolder(); virtual void updateGarrisons() = 0;
virtual void updateGarrisons()=0;
}; };
class CWindowWithGarrison : public virtual CGarrisonHolder
{
public:
CGarrisonInt *garr;
virtual void updateGarrisons() override;
};
/// Garrison window where you can take creatures out of the hero to place it on the garrison
class CGarrisonWindow : public CWindowObject, public CWindowWithGarrison
{
public:
CButton * quit;
CGarrisonWindow(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits);
};

View File

@ -179,13 +179,6 @@ void CPicture::createSimpleRect(const Rect &r, bool screenFormat, ui32 color)
freeSurf = true; freeSurf = true;
} }
void CPicture::colorizeAndConvert(PlayerColor player)
{
assert(bg);
colorize(player);
convertToScreenBPP();
}
void CPicture::colorize(PlayerColor player) void CPicture::colorize(PlayerColor player)
{ {
assert(bg); assert(bg);
@ -257,9 +250,6 @@ void CAnimImage::init()
CAnimImage::~CAnimImage() CAnimImage::~CAnimImage()
{ {
anim->unload(frame, group);
if (flags & CShowableAnim::BASE)
anim->unload(0,group);
} }
void CAnimImage::showAll(SDL_Surface * to) void CAnimImage::showAll(SDL_Surface * to)
@ -281,7 +271,6 @@ void CAnimImage::setFrame(size_t Frame, size_t Group)
return; return;
if (anim->size(Group) > Frame) if (anim->size(Group) > Frame)
{ {
anim->unload(frame, group);
anim->load(Frame, Group); anim->load(Frame, Group);
frame = Frame; frame = Frame;
group = Group; group = Group;
@ -348,8 +337,9 @@ bool CShowableAnim::set(size_t Group, size_t from, size_t to)
if (max < from || max == 0) if (max < from || max == 0)
return false; return false;
anim->load(Group); anim->unloadGroup(group);
anim->unload(group); anim->loadGroup(Group);
group = Group; group = Group;
frame = first = from; frame = first = from;
last = max; last = max;
@ -363,8 +353,9 @@ bool CShowableAnim::set(size_t Group)
return false; return false;
if (group != Group) if (group != Group)
{ {
anim->loadGroup(Group);
anim->unloadGroup(group); anim->unloadGroup(group);
anim->loadGroup(Group);
first = 0; first = 0;
group = Group; group = Group;
last = anim->size(Group); last = anim->size(Group);

View File

@ -50,7 +50,6 @@ public:
void show(SDL_Surface * to) override; void show(SDL_Surface * to) override;
void showAll(SDL_Surface * to) override; void showAll(SDL_Surface * to) override;
void convertToScreenBPP(); void convertToScreenBPP();
void colorizeAndConvert(PlayerColor player);
void colorize(PlayerColor player); void colorize(PlayerColor player);
}; };

View File

@ -87,7 +87,7 @@ void LRClickableAreaWTextComp::clickLeft(tribool down, bool previousState)
{ {
if((!down) && previousState) if((!down) && previousState)
{ {
std::vector<CComponent*> comp(1, createComponent()); std::vector<std::shared_ptr<CComponent>> comp(1, createComponent());
LOCPLINT->showInfoDialog(text, comp); LOCPLINT->showInfoDialog(text, comp);
} }
} }
@ -98,19 +98,19 @@ LRClickableAreaWTextComp::LRClickableAreaWTextComp(const Rect &Pos, int BaseType
type = -1; type = -1;
} }
CComponent * LRClickableAreaWTextComp::createComponent() const std::shared_ptr<CComponent> LRClickableAreaWTextComp::createComponent() const
{ {
if(baseType >= 0) if(baseType >= 0)
return new CComponent(CComponent::Etype(baseType), type, bonusValue); return std::make_shared<CComponent>(CComponent::Etype(baseType), type, bonusValue);
else else
return nullptr; return std::shared_ptr<CComponent>();
} }
void LRClickableAreaWTextComp::clickRight(tribool down, bool previousState) void LRClickableAreaWTextComp::clickRight(tribool down, bool previousState)
{ {
if(down) if(down)
{ {
if(CComponent *comp = createComponent()) if(auto comp = createComponent())
{ {
CRClickPopup::createAndPush(text, CInfoWindow::TCompsInfo(1, comp)); CRClickPopup::createAndPush(text, CInfoWindow::TCompsInfo(1, comp));
return; return;
@ -120,16 +120,19 @@ void LRClickableAreaWTextComp::clickRight(tribool down, bool previousState)
LRClickableAreaWText::clickRight(down, previousState); //only if with-component variant not occurred LRClickableAreaWText::clickRight(down, previousState); //only if with-component variant not occurred
} }
CHeroArea::CHeroArea(int x, int y, const CGHeroInstance * _hero):hero(_hero) CHeroArea::CHeroArea(int x, int y, const CGHeroInstance * _hero)
: CIntObject(LCLICK | RCLICK | HOVER),
hero(_hero)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
addUsedEvents(LCLICK | RCLICK | HOVER); pos.x += x;
pos.x += x; pos.w = 58; pos.w = 58;
pos.y += y; pos.h = 64; pos.y += y;
pos.h = 64;
if (hero) if(hero)
new CAnimImage("PortraitsLarge", hero->portrait); portrait = std::make_shared<CAnimImage>("PortraitsLarge", hero->portrait);
} }
void CHeroArea::clickLeft(tribool down, bool previousState) void CHeroArea::clickLeft(tribool down, bool previousState)
@ -181,7 +184,8 @@ void CMinorResDataBar::show(SDL_Surface * to)
void CMinorResDataBar::showAll(SDL_Surface * to) void CMinorResDataBar::showAll(SDL_Surface * to)
{ {
blitAt(bg,pos.x,pos.y,to); CIntObject::showAll(to);
for (Res::ERes i=Res::WOOD; i<=Res::GOLD; vstd::advance(i, 1)) for (Res::ERes i=Res::WOOD; i<=Res::GOLD; vstd::advance(i, 1))
{ {
std::string text = boost::lexical_cast<std::string>(LOCPLINT->cb->getResourceAmount(i)); std::string text = boost::lexical_cast<std::string>(LOCPLINT->cb->getResourceAmount(i));
@ -202,34 +206,34 @@ void CMinorResDataBar::showAll(SDL_Surface * to)
CMinorResDataBar::CMinorResDataBar() CMinorResDataBar::CMinorResDataBar()
{ {
bg = BitmapHandler::loadBitmap("KRESBAR.bmp"); OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
CSDL_Ext::setDefaultColorKey(bg);
graphics->blueToPlayersAdv(bg,LOCPLINT->playerID);
pos.x = 7; pos.x = 7;
pos.y = 575; pos.y = 575;
pos.w = bg->w;
pos.h = bg->h; background = std::make_shared<CPicture>("KRESBAR.bmp");
background->colorize(LOCPLINT->playerID);
pos.w = background->pos.w;
pos.h = background->pos.h;
} }
CMinorResDataBar::~CMinorResDataBar() CMinorResDataBar::~CMinorResDataBar() = default;
{
SDL_FreeSurface(bg);
}
void CArmyTooltip::init(const InfoAboutArmy &army) void CArmyTooltip::init(const InfoAboutArmy &army)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
new CLabel(66, 2, FONT_SMALL, TOPLEFT, Colors::WHITE, army.name); title = std::make_shared<CLabel>(66, 2, FONT_SMALL, TOPLEFT, Colors::WHITE, army.name);
std::vector<Point> slotsPos; std::vector<Point> slotsPos;
slotsPos.push_back(Point(36,73)); slotsPos.push_back(Point(36, 73));
slotsPos.push_back(Point(72,73)); slotsPos.push_back(Point(72, 73));
slotsPos.push_back(Point(108,73)); slotsPos.push_back(Point(108, 73));
slotsPos.push_back(Point(18,122)); slotsPos.push_back(Point(18, 122));
slotsPos.push_back(Point(54,122)); slotsPos.push_back(Point(54, 122));
slotsPos.push_back(Point(90,122)); slotsPos.push_back(Point(90, 122));
slotsPos.push_back(Point(126,122)); slotsPos.push_back(Point(126, 122));
for(auto & slot : army.army) for(auto & slot : army.army)
{ {
@ -239,24 +243,26 @@ void CArmyTooltip::init(const InfoAboutArmy &army)
continue; continue;
} }
new CAnimImage("CPRSMALL", slot.second.type->iconIndex, 0, slotsPos[slot.first.getNum()].x, slotsPos[slot.first.getNum()].y); icons.push_back(std::make_shared<CAnimImage>("CPRSMALL", slot.second.type->iconIndex, 0, slotsPos[slot.first.getNum()].x, slotsPos[slot.first.getNum()].y));
std::string subtitle; std::string subtitle;
if(army.army.isDetailed) if(army.army.isDetailed)
{
subtitle = boost::lexical_cast<std::string>(slot.second.count); subtitle = boost::lexical_cast<std::string>(slot.second.count);
}
else else
{ {
//if =0 - we have no information about stack size at all //if =0 - we have no information about stack size at all
if (slot.second.count) if(slot.second.count)
subtitle = CGI->generaltexth->arraytxt[171 + 3*(slot.second.count)]; subtitle = CGI->generaltexth->arraytxt[171 + 3*(slot.second.count)];
} }
new CLabel(slotsPos[slot.first.getNum()].x + 17, slotsPos[slot.first.getNum()].y + 41, FONT_TINY, CENTER, Colors::WHITE, subtitle); subtitles.push_back(std::make_shared<CLabel>(slotsPos[slot.first.getNum()].x + 17, slotsPos[slot.first.getNum()].y + 41, FONT_TINY, CENTER, Colors::WHITE, subtitle));
} }
} }
CArmyTooltip::CArmyTooltip(Point pos, const InfoAboutArmy &army): CArmyTooltip::CArmyTooltip(Point pos, const InfoAboutArmy & army):
CIntObject(0, pos) CIntObject(0, pos)
{ {
init(army); init(army);
@ -268,22 +274,21 @@ CArmyTooltip::CArmyTooltip(Point pos, const CArmedInstance * army):
init(InfoAboutArmy(army, true)); init(InfoAboutArmy(army, true));
} }
void CHeroTooltip::init(const InfoAboutHero &hero) void CHeroTooltip::init(const InfoAboutHero & hero)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
new CAnimImage("PortraitsLarge", hero.portrait, 0, 3, 2); portrait = std::make_shared<CAnimImage>("PortraitsLarge", hero.portrait, 0, 3, 2);
if(hero.details) if(hero.details)
{ {
for (size_t i = 0; i < hero.details->primskills.size(); i++) for(size_t i = 0; i < hero.details->primskills.size(); i++)
new CLabel(75 + 28 * i, 58, FONT_SMALL, CENTER, Colors::WHITE, labels.push_back(std::make_shared<CLabel>(75 + 28 * i, 58, FONT_SMALL, CENTER, Colors::WHITE,
boost::lexical_cast<std::string>(hero.details->primskills[i])); boost::lexical_cast<std::string>(hero.details->primskills[i])));
new CLabel(158, 98, FONT_TINY, CENTER, Colors::WHITE, labels.push_back(std::make_shared<CLabel>(158, 98, FONT_TINY, CENTER, Colors::WHITE, boost::lexical_cast<std::string>(hero.details->mana)));
boost::lexical_cast<std::string>(hero.details->mana));
new CAnimImage("IMRL22", hero.details->morale + 3, 0, 5, 74); morale = std::make_shared<CAnimImage>("IMRL22", hero.details->morale + 3, 0, 5, 74);
new CAnimImage("ILCK22", hero.details->luck + 3, 0, 5, 91); luck = std::make_shared<CAnimImage>("ILCK22", hero.details->luck + 3, 0, 5, 91);
} }
} }
@ -299,61 +304,64 @@ CHeroTooltip::CHeroTooltip(Point pos, const CGHeroInstance * hero):
init(InfoAboutHero(hero, InfoAboutHero::EInfoLevel::DETAILED)); init(InfoAboutHero(hero, InfoAboutHero::EInfoLevel::DETAILED));
} }
void CTownTooltip::init(const InfoAboutTown &town) void CTownTooltip::init(const InfoAboutTown & town)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
//order of icons in def: fort, citadel, castle, no fort //order of icons in def: fort, citadel, castle, no fort
size_t fortIndex = town.fortLevel ? town.fortLevel - 1 : 3; size_t fortIndex = town.fortLevel ? town.fortLevel - 1 : 3;
new CAnimImage("ITMCLS", fortIndex, 0, 105, 31); fort = std::make_shared<CAnimImage>("ITMCLS", fortIndex, 0, 105, 31);
assert(town.tType); assert(town.tType);
size_t iconIndex = town.tType->clientInfo.icons[town.fortLevel > 0][town.built >= CGI->modh->settings.MAX_BUILDING_PER_TURN]; size_t iconIndex = town.tType->clientInfo.icons[town.fortLevel > 0][town.built >= CGI->modh->settings.MAX_BUILDING_PER_TURN];
new CAnimImage("itpt", iconIndex, 0, 3, 2); build = std::make_shared<CAnimImage>("itpt", iconIndex, 0, 3, 2);
if(town.details) if(town.details)
{ {
new CAnimImage("ITMTLS", town.details->hallLevel, 0, 67, 31); fort = std::make_shared<CAnimImage>("ITMTLS", town.details->hallLevel, 0, 67, 31);
if (town.details->goldIncome) if(town.details->goldIncome)
new CLabel(157, 58, FONT_TINY, CENTER, Colors::WHITE, {
income = std::make_shared<CLabel>(157, 58, FONT_TINY, CENTER, Colors::WHITE,
boost::lexical_cast<std::string>(town.details->goldIncome)); boost::lexical_cast<std::string>(town.details->goldIncome));
}
if(town.details->garrisonedHero) //garrisoned hero icon if(town.details->garrisonedHero) //garrisoned hero icon
new CPicture("TOWNQKGH", 149, 76); garrisonedHero = std::make_shared<CPicture>("TOWNQKGH", 149, 76);
if(town.details->customRes)//silo is built if(town.details->customRes)//silo is built
{ {
if (town.tType->primaryRes == Res::WOOD_AND_ORE )// wood & ore if(town.tType->primaryRes == Res::WOOD_AND_ORE )// wood & ore
{ {
new CAnimImage("SMALRES", Res::WOOD, 0, 7, 75); res1 = std::make_shared<CAnimImage>("SMALRES", Res::WOOD, 0, 7, 75);
new CAnimImage("SMALRES", Res::ORE , 0, 7, 88); res2 = std::make_shared<CAnimImage>("SMALRES", Res::ORE , 0, 7, 88);
} }
else else
new CAnimImage("SMALRES", town.tType->primaryRes, 0, 7, 81); {
res1 = std::make_shared<CAnimImage>("SMALRES", town.tType->primaryRes, 0, 7, 81);
}
} }
} }
} }
CTownTooltip::CTownTooltip(Point pos, const InfoAboutTown &town): CTownTooltip::CTownTooltip(Point pos, const InfoAboutTown & town)
CArmyTooltip(pos, town) : CArmyTooltip(pos, town)
{ {
init(town); init(town);
} }
CTownTooltip::CTownTooltip(Point pos, const CGTownInstance * town): CTownTooltip::CTownTooltip(Point pos, const CGTownInstance * town)
CArmyTooltip(pos, InfoAboutTown(town, true)) : CArmyTooltip(pos, InfoAboutTown(town, true))
{ {
init(InfoAboutTown(town, true)); init(InfoAboutTown(town, true));
} }
void MoraleLuckBox::set(const IBonusBearer * node)
void MoraleLuckBox::set(const IBonusBearer *node)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
const int textId[] = {62, 88}; //eg %s \n\n\n {Current Luck Modifiers:} const int textId[] = {62, 88}; //eg %s \n\n\n {Current Luck Modifiers:}
const int noneTxtId = 108; //Russian version uses same text for neutral morale\luck const int noneTxtId = 108; //Russian version uses same text for neutral morale\luck
const int neutralDescr[] = {60, 86}; //eg {Neutral Morale} \n\n Neutral morale means your armies will neither be blessed with extra attacks or freeze in combat. const int neutralDescr[] = {60, 86}; //eg {Neutral Morale} \n\n Neutral morale means your armies will neither be blessed with extra attacks or freeze in combat.
@ -363,13 +371,15 @@ void MoraleLuckBox::set(const IBonusBearer *node)
int (IBonusBearer::*getValue[])() const = {&IBonusBearer::LuckVal, &IBonusBearer::MoraleVal}; int (IBonusBearer::*getValue[])() const = {&IBonusBearer::LuckVal, &IBonusBearer::MoraleVal};
TBonusListPtr modifierList(new BonusList()); TBonusListPtr modifierList(new BonusList());
if (node) if(node)
{ {
modifierList = node->getBonuses(Selector::type(bonusType[morale])); modifierList = node->getBonuses(Selector::type(bonusType[morale]));
bonusValue = (node->*getValue[morale])(); bonusValue = (node->*getValue[morale])();
} }
else else
{
bonusValue = 0; bonusValue = 0;
}
int mrlt = (bonusValue>0)-(bonusValue<0); //signum: -1 - bad luck / morale, 0 - neutral, 1 - good int mrlt = (bonusValue>0)-(bonusValue<0); //signum: -1 - bad luck / morale, 0 - neutral, 1 - good
hoverText = CGI->generaltexth->heroscrn[hoverTextBase[morale] - mrlt]; hoverText = CGI->generaltexth->heroscrn[hoverTextBase[morale] - mrlt];
@ -420,23 +430,22 @@ void MoraleLuckBox::set(const IBonusBearer *node)
else else
imageName = morale ? "IMRL42" : "ILCK42"; imageName = morale ? "IMRL42" : "ILCK42";
delete image; image = std::make_shared<CAnimImage>(imageName, bonusValue + 3);
image = new CAnimImage(imageName, bonusValue + 3);
image->moveBy(Point(pos.w/2 - image->pos.w/2, pos.h/2 - image->pos.h/2));//center icon image->moveBy(Point(pos.w/2 - image->pos.w/2, pos.h/2 - image->pos.h/2));//center icon
} }
MoraleLuckBox::MoraleLuckBox(bool Morale, const Rect &r, bool Small): MoraleLuckBox::MoraleLuckBox(bool Morale, const Rect &r, bool Small)
image(nullptr), : morale(Morale),
morale(Morale),
small(Small) small(Small)
{ {
bonusValue = 0; bonusValue = 0;
pos = r + pos; pos = r + pos;
defActions = 255-DISPOSE;
} }
CCreaturePic::CCreaturePic(int x, int y, const CCreature *cre, bool Big, bool Animated) CCreaturePic::CCreaturePic(int x, int y, const CCreature * cre, bool Big, bool Animated)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
pos.x+=x; pos.x+=x;
pos.y+=y; pos.y+=y;
@ -445,20 +454,20 @@ CCreaturePic::CCreaturePic(int x, int y, const CCreature *cre, bool Big, bool An
assert(CGI->townh->factions.size() > faction); assert(CGI->townh->factions.size() > faction);
if(Big) if(Big)
bg = new CPicture(CGI->townh->factions[faction]->creatureBg130); bg = std::make_shared<CPicture>(CGI->townh->factions[faction]->creatureBg130);
else else
bg = new CPicture(CGI->townh->factions[faction]->creatureBg120); bg = std::make_shared<CPicture>(CGI->townh->factions[faction]->creatureBg120);
anim = new CCreatureAnim(0, 0, cre->animDefName, Rect()); anim = std::make_shared<CCreatureAnim>(0, 0, cre->animDefName, Rect());
anim->clipRect(cre->isDoubleWide()?170:150, 155, bg->pos.w, bg->pos.h); anim->clipRect(cre->isDoubleWide()?170:150, 155, bg->pos.w, bg->pos.h);
anim->startPreview(cre->hasBonusOfType(Bonus::SIEGE_WEAPON)); anim->startPreview(cre->hasBonusOfType(Bonus::SIEGE_WEAPON));
amount = new CLabel(bg->pos.w, bg->pos.h, FONT_MEDIUM, BOTTOMRIGHT, Colors::WHITE); amount = std::make_shared<CLabel>(bg->pos.w, bg->pos.h, FONT_MEDIUM, BOTTOMRIGHT, Colors::WHITE);
pos.w = bg->pos.w; pos.w = bg->pos.w;
pos.h = bg->pos.h; pos.h = bg->pos.h;
} }
void CCreaturePic::show(SDL_Surface *to) void CCreaturePic::show(SDL_Surface * to)
{ {
// redraw everything in a proper order // redraw everything in a proper order
bg->showAll(to); bg->showAll(to);
@ -468,7 +477,7 @@ void CCreaturePic::show(SDL_Surface *to)
void CCreaturePic::setAmount(int newAmount) void CCreaturePic::setAmount(int newAmount)
{ {
if (newAmount != 0) if(newAmount != 0)
amount->setText(boost::lexical_cast<std::string>(newAmount)); amount->setText(boost::lexical_cast<std::string>(newAmount));
else else
amount->setText(""); amount->setText("");

View File

@ -15,7 +15,6 @@ class CLabel;
class CCreatureAnim; class CCreatureAnim;
class CComponent; class CComponent;
class CGGarrison; class CGGarrison;
class CSelectableComponent;
struct InfoAboutArmy; struct InfoAboutArmy;
class CArmedInstance; class CArmedInstance;
class IBonusBearer; class IBonusBearer;
@ -40,7 +39,7 @@ public:
std::string text; std::string text;
LRClickableAreaWText(); LRClickableAreaWText();
LRClickableAreaWText(const Rect &Pos, const std::string &HoverText = "", const std::string &ClickText = ""); LRClickableAreaWText(const Rect & Pos, const std::string & HoverText = "", const std::string & ClickText = "");
virtual ~LRClickableAreaWText(); virtual ~LRClickableAreaWText();
void init(); void init();
@ -51,9 +50,12 @@ public:
/// base class for hero/town/garrison tooltips /// base class for hero/town/garrison tooltips
class CArmyTooltip : public CIntObject class CArmyTooltip : public CIntObject
{ {
void init(const InfoAboutArmy &army); std::shared_ptr<CLabel> title;
std::vector<std::shared_ptr<CAnimImage>> icons;
std::vector<std::shared_ptr<CLabel>> subtitles;
void init(const InfoAboutArmy & army);
public: public:
CArmyTooltip(Point pos, const InfoAboutArmy &army); CArmyTooltip(Point pos, const InfoAboutArmy & army);
CArmyTooltip(Point pos, const CArmedInstance * army); CArmyTooltip(Point pos, const CArmedInstance * army);
}; };
@ -62,9 +64,14 @@ public:
/// background for tooltip: HEROQVBK /// background for tooltip: HEROQVBK
class CHeroTooltip : public CArmyTooltip class CHeroTooltip : public CArmyTooltip
{ {
void init(const InfoAboutHero &hero); std::shared_ptr<CAnimImage> portrait;
std::vector<std::shared_ptr<CLabel>> labels;
std::shared_ptr<CAnimImage> morale;
std::shared_ptr<CAnimImage> luck;
void init(const InfoAboutHero & hero);
public: public:
CHeroTooltip(Point pos, const InfoAboutHero &hero); CHeroTooltip(Point pos, const InfoAboutHero & hero);
CHeroTooltip(Point pos, const CGHeroInstance * hero); CHeroTooltip(Point pos, const CGHeroInstance * hero);
}; };
@ -73,9 +80,17 @@ public:
/// background for tooltip: TOWNQVBK /// background for tooltip: TOWNQVBK
class CTownTooltip : public CArmyTooltip class CTownTooltip : public CArmyTooltip
{ {
void init(const InfoAboutTown &town); std::shared_ptr<CAnimImage> fort;
std::shared_ptr<CAnimImage> hall;
std::shared_ptr<CAnimImage> build;
std::shared_ptr<CLabel> income;
std::shared_ptr<CPicture> garrisonedHero;
std::shared_ptr<CAnimImage> res1;
std::shared_ptr<CAnimImage> res2;
void init(const InfoAboutTown & town);
public: public:
CTownTooltip(Point pos, const InfoAboutTown &town); CTownTooltip(Point pos, const InfoAboutTown & town);
CTownTooltip(Point pos, const CGTownInstance * town); CTownTooltip(Point pos, const CGTownInstance * town);
}; };
@ -83,22 +98,21 @@ public:
class CCreaturePic : public CIntObject class CCreaturePic : public CIntObject
{ {
private: private:
CPicture *bg; std::shared_ptr<CPicture> bg;
CCreatureAnim *anim; //displayed animation std::shared_ptr<CCreatureAnim> anim; //displayed animation
CLabel * amount; std::shared_ptr<CLabel> amount;
void show(SDL_Surface *to) override; void show(SDL_Surface * to) override;
public: public:
CCreaturePic(int x, int y, const CCreature *cre, bool Big=true, bool Animated=true); CCreaturePic(int x, int y, const CCreature * cre, bool Big=true, bool Animated=true);
void setAmount(int newAmount); void setAmount(int newAmount);
}; };
/// Resource bar like that at the bottom of the adventure map screen /// Resource bar like that at the bottom of the adventure map screen
class CMinorResDataBar : public CIntObject class CMinorResDataBar : public CIntObject
{ {
std::shared_ptr<CPicture> background;
public: public:
SDL_Surface *bg; //background bitmap
void show(SDL_Surface * to) override; void show(SDL_Surface * to) override;
void showAll(SDL_Surface * to) override; void showAll(SDL_Surface * to) override;
CMinorResDataBar(); CMinorResDataBar();
@ -109,8 +123,9 @@ public:
class CHeroArea: public CIntObject class CHeroArea: public CIntObject
{ {
const CGHeroInstance * hero; const CGHeroInstance * hero;
public: std::shared_ptr<CAnimImage> portrait;
public:
CHeroArea(int x, int y, const CGHeroInstance * _hero); CHeroArea(int x, int y, const CGHeroInstance * _hero);
void clickLeft(tribool down, bool previousState) override; void clickLeft(tribool down, bool previousState) override;
@ -128,7 +143,7 @@ public:
virtual void clickRight(tribool down, bool previousState) override; virtual void clickRight(tribool down, bool previousState) override;
LRClickableAreaWTextComp(const Rect &Pos = Rect(0,0,0,0), int BaseType = -1); LRClickableAreaWTextComp(const Rect &Pos = Rect(0,0,0,0), int BaseType = -1);
CComponent * createComponent() const; std::shared_ptr<CComponent> createComponent() const;
}; };
/// Opens town screen by left-clicking on it /// Opens town screen by left-clicking on it
@ -143,7 +158,7 @@ public:
class MoraleLuckBox : public LRClickableAreaWTextComp class MoraleLuckBox : public LRClickableAreaWTextComp
{ {
CAnimImage *image; std::shared_ptr<CAnimImage> image;
public: public:
bool morale; //true if morale, false if luck bool morale; //true if morale, false if luck
bool small; bool small;

View File

@ -13,53 +13,45 @@
#include "../gui/CGuiHandler.h" #include "../gui/CGuiHandler.h"
#include "Buttons.h" #include "Buttons.h"
CObjectList::CObjectList(CreateFunc create)
static void intDeleter(CIntObject* object) : createObject(create)
{ {
delete object;
} }
CObjectList::CObjectList(CreateFunc create, DestroyFunc destroy): void CObjectList::deleteItem(std::shared_ptr<CIntObject> item)
createObject(create),
destroyObject(destroy)
{ {
if (!destroyObject) if(!item)
destroyObject = intDeleter;
}
void CObjectList::deleteItem(CIntObject* item)
{
if (!item)
return; return;
removeChild(item); item->deactivate();
destroyObject(item); removeChild(item.get());
} }
CIntObject* CObjectList::createItem(size_t index) std::shared_ptr<CIntObject> CObjectList::createItem(size_t index)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
CIntObject * item = createObject(index); std::shared_ptr<CIntObject> item = createObject(index);
if (item == nullptr) if(!item)
item = new CIntObject(); item = std::make_shared<CIntObject>();
item->recActions = defActions; item->recActions = defActions;
addChild(item.get());
addChild(item); item->activate();
return item; return item;
} }
CTabbedInt::CTabbedInt(CreateFunc create, DestroyFunc destroy, Point position, size_t ActiveID): CTabbedInt::CTabbedInt(CreateFunc create, Point position, size_t ActiveID)
CObjectList(create, destroy), : CObjectList(create),
activeTab(nullptr), activeTab(nullptr),
activeID(ActiveID) activeID(ActiveID)
{ {
defActions &= ~DISPOSE;
pos += position; pos += position;
reset(); reset();
} }
void CTabbedInt::setActive(size_t which) void CTabbedInt::setActive(size_t which)
{ {
if (which != activeID) if(which != activeID)
{ {
activeID = which; activeID = which;
reset(); reset();
@ -72,30 +64,29 @@ void CTabbedInt::reset()
activeTab = createItem(activeID); activeTab = createItem(activeID);
activeTab->moveTo(pos.topLeft()); activeTab->moveTo(pos.topLeft());
if (active) if(active)
redraw(); redraw();
} }
CIntObject * CTabbedInt::getItem() std::shared_ptr<CIntObject> CTabbedInt::getItem()
{ {
return activeTab; return activeTab;
} }
CListBox::CListBox(CreateFunc create, DestroyFunc destroy, Point Pos, Point ItemOffset, size_t VisibleSize, CListBox::CListBox(CreateFunc create, Point Pos, Point ItemOffset, size_t VisibleSize,
size_t TotalSize, size_t InitialPos, int Slider, Rect SliderPos): size_t TotalSize, size_t InitialPos, int Slider, Rect SliderPos)
CObjectList(create, destroy), : CObjectList(create),
first(InitialPos), first(InitialPos),
totalSize(TotalSize), totalSize(TotalSize),
itemOffset(ItemOffset), itemOffset(ItemOffset)
slider(nullptr)
{ {
pos += Pos; pos += Pos;
items.resize(VisibleSize, nullptr); items.resize(VisibleSize, nullptr);
if (Slider & 1) if(Slider & 1)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
slider = new CSlider(SliderPos.topLeft(), SliderPos.w, std::bind(&CListBox::moveToPos, this, _1), slider = std::make_shared<CSlider>(SliderPos.topLeft(), SliderPos.w, std::bind(&CListBox::moveToPos, this, _1),
VisibleSize, TotalSize, InitialPos, Slider & 2, Slider & 4 ? CSlider::BLUE : CSlider::BROWN); VisibleSize, TotalSize, InitialPos, Slider & 2, Slider & 4 ? CSlider::BLUE : CSlider::BROWN);
} }
reset(); reset();
@ -142,22 +133,22 @@ size_t CListBox::size()
return totalSize; return totalSize;
} }
CIntObject * CListBox::getItem(size_t which) std::shared_ptr<CIntObject> CListBox::getItem(size_t which)
{ {
if (which < first || which > first + items.size() || which > totalSize) if(which < first || which > first + items.size() || which > totalSize)
return nullptr; return std::shared_ptr<CIntObject>();
size_t i=first; size_t i=first;
for (auto iter = items.begin(); iter != items.end(); iter++, i++) for (auto iter = items.begin(); iter != items.end(); iter++, i++)
if( i == which) if( i == which)
return *iter; return *iter;
return nullptr; return std::shared_ptr<CIntObject>();
} }
size_t CListBox::getIndexOf(CIntObject *item) size_t CListBox::getIndexOf(std::shared_ptr<CIntObject> item)
{ {
size_t i=first; size_t i=first;
for (auto iter = items.begin(); iter != items.end(); iter++, i++) for(auto iter = items.begin(); iter != items.end(); iter++, i++)
if(*iter == item) if(*iter == item)
return i; return i;
return size_t(-1); return size_t(-1);
@ -166,7 +157,7 @@ size_t CListBox::getIndexOf(CIntObject *item)
void CListBox::scrollTo(size_t which) void CListBox::scrollTo(size_t which)
{ {
//scroll up //scroll up
if (first > which) if(first > which)
moveToPos(which); moveToPos(which);
//scroll down //scroll down
else if (first + items.size() <= which && which < totalSize) else if (first + items.size() <= which && which < totalSize)
@ -177,7 +168,7 @@ void CListBox::moveToPos(size_t which)
{ {
//Calculate new position //Calculate new position
size_t maxPossible; size_t maxPossible;
if (totalSize > items.size()) if(totalSize > items.size())
maxPossible = totalSize - items.size(); maxPossible = totalSize - items.size();
else else
maxPossible = 0; maxPossible = 0;
@ -185,11 +176,15 @@ void CListBox::moveToPos(size_t which)
size_t newPos = std::min(which, maxPossible); size_t newPos = std::min(which, maxPossible);
//If move distance is 1 (most of calls from Slider) - use faster shifts instead of resetting all items //If move distance is 1 (most of calls from Slider) - use faster shifts instead of resetting all items
if (first - newPos == 1) if(first - newPos == 1)
{
moveToPrev(); moveToPrev();
else if (newPos - first == 1) }
else if(newPos - first == 1)
{
moveToNext(); moveToNext();
else if (newPos != first) }
else if(newPos != first)
{ {
first = newPos; first = newPos;
reset(); reset();
@ -199,7 +194,7 @@ void CListBox::moveToPos(size_t which)
void CListBox::moveToNext() void CListBox::moveToNext()
{ {
//Remove front item and insert new one to end //Remove front item and insert new one to end
if (first + items.size() < totalSize) if(first + items.size() < totalSize)
{ {
first++; first++;
deleteItem(items.front()); deleteItem(items.front());
@ -212,7 +207,7 @@ void CListBox::moveToNext()
void CListBox::moveToPrev() void CListBox::moveToPrev()
{ {
//Remove last item and insert new one at start //Remove last item and insert new one at start
if (first) if(first)
{ {
first--; first--;
deleteItem(items.back()); deleteItem(items.back());
@ -227,7 +222,7 @@ size_t CListBox::getPos()
return first; return first;
} }
const std::list<CIntObject *> &CListBox::getItems() const std::list<std::shared_ptr<CIntObject>> & CListBox::getItems()
{ {
return items; return items;
} }

View File

@ -22,52 +22,50 @@ class CAnimation;
class CObjectList : public CIntObject class CObjectList : public CIntObject
{ {
public: public:
typedef std::function<CIntObject* (size_t)> CreateFunc; typedef std::function<std::shared_ptr<CIntObject>(size_t)> CreateFunc;
typedef std::function<void(CIntObject *)> DestroyFunc;
private: private:
CreateFunc createObject; CreateFunc createObject;
DestroyFunc destroyObject;
protected: protected:
//Internal methods for safe creation of items (Children capturing and activation/deactivation if needed) //Internal methods for safe creation of items (Children capturing and activation/deactivation if needed)
void deleteItem(CIntObject* item); void deleteItem(std::shared_ptr<CIntObject> item);
CIntObject* createItem(size_t index); std::shared_ptr<CIntObject> createItem(size_t index);
CObjectList(CreateFunc create, DestroyFunc destroy = DestroyFunc());//Protected constructor CObjectList(CreateFunc create);
}; };
/// Window element with multiple tabs /// Window element with multiple tabs
class CTabbedInt : public CObjectList class CTabbedInt : public CObjectList
{ {
private: private:
CIntObject * activeTab; std::shared_ptr<CIntObject> activeTab;
size_t activeID; size_t activeID;
public: public:
//CreateFunc, DestroyFunc - see CObjectList //CreateFunc, DestroyFunc - see CObjectList
//Pos - position of object, all tabs will be moved to this position //Pos - position of object, all tabs will be moved to this position
//ActiveID - ID of initially active tab //ActiveID - ID of initially active tab
CTabbedInt(CreateFunc create, DestroyFunc destroy = DestroyFunc(), Point position=Point(), size_t ActiveID=0); CTabbedInt(CreateFunc create, Point position=Point(), size_t ActiveID=0);
void setActive(size_t which); void setActive(size_t which);
//recreate active tab //recreate active tab
void reset(); void reset();
//return currently active item //return currently active item
CIntObject * getItem(); std::shared_ptr<CIntObject> getItem();
}; };
/// List of IntObjects with optional slider /// List of IntObjects with optional slider
class CListBox : public CObjectList class CListBox : public CObjectList
{ {
private: private:
std::list< CIntObject* > items; std::list<std::shared_ptr<CIntObject>> items;
size_t first; size_t first;
size_t totalSize; size_t totalSize;
Point itemOffset; Point itemOffset;
CSlider * slider; std::shared_ptr<CSlider> slider;
void updatePositions(); void updatePositions();
public: public:
@ -78,7 +76,7 @@ public:
//TotalSize //TotalSize
//Slider - slider style, bit field: 1 = present(disabled), 2=horisontal(vertical), 4=blue(brown) //Slider - slider style, bit field: 1 = present(disabled), 2=horisontal(vertical), 4=blue(brown)
//SliderPos - position of slider, if present //SliderPos - position of slider, if present
CListBox(CreateFunc create, DestroyFunc destroy, Point Pos, Point ItemOffset, size_t VisibleSize, CListBox(CreateFunc create, Point Pos, Point ItemOffset, size_t VisibleSize,
size_t TotalSize, size_t InitialPos=0, int Slider=0, Rect SliderPos=Rect() ); size_t TotalSize, size_t InitialPos=0, int Slider=0, Rect SliderPos=Rect() );
//recreate all visible items //recreate all visible items
@ -89,13 +87,13 @@ public:
size_t size(); size_t size();
//return item with index which or null if not present //return item with index which or null if not present
CIntObject * getItem(size_t which); std::shared_ptr<CIntObject> getItem(size_t which);
//return currently active items //return currently active items
const std::list< CIntObject * > & getItems(); const std::list<std::shared_ptr<CIntObject>> & getItems();
//get index of this item. -1 if not found //get index of this item. -1 if not found
size_t getIndexOf(CIntObject * item); size_t getIndexOf(std::shared_ptr<CIntObject> item);
//scroll list to make item which visible //scroll list to make item which visible
void scrollTo(size_t which); void scrollTo(size_t which);

View File

@ -36,17 +36,16 @@ void CLabel::showAll(SDL_Surface * to)
} }
CLabel::CLabel(int x, int y, EFonts Font, EAlignment Align, const SDL_Color &Color, const std::string &Text) CLabel::CLabel(int x, int y, EFonts Font, EAlignment Align, const SDL_Color & Color, const std::string & Text)
:CTextContainer(Align, Font, Color), text(Text) : CTextContainer(Align, Font, Color), text(Text)
{ {
type |= REDRAW_PARENT; type |= REDRAW_PARENT;
autoRedraw = true; autoRedraw = true;
pos.x += x; pos.x += x;
pos.y += y; pos.y += y;
pos.w = pos.h = 0; pos.w = pos.h = 0;
bg = nullptr;
if (alignment == TOPLEFT) // causes issues for MIDDLE if(alignment == TOPLEFT) // causes issues for MIDDLE
{ {
pos.w = graphics->fonts[font]->getStringWidth(visibleText().c_str()); pos.w = graphics->fonts[font]->getStringWidth(visibleText().c_str());
pos.h = graphics->fonts[font]->getLineHeight(); pos.h = graphics->fonts[font]->getLineHeight();
@ -73,7 +72,7 @@ void CLabel::setText(const std::string &Txt)
text = Txt; text = Txt;
if(autoRedraw) if(autoRedraw)
{ {
if(bg || !parent) if(background || !parent)
redraw(); redraw();
else else
parent->redraw(); parent->redraw();
@ -85,7 +84,7 @@ void CLabel::setColor(const SDL_Color & Color)
color = Color; color = Color;
if(autoRedraw) if(autoRedraw)
{ {
if(bg || !parent) if(background || !parent)
redraw(); redraw();
else else
parent->redraw(); parent->redraw();
@ -259,14 +258,16 @@ Rect CMultiLineLabel::getTextLocation()
return Rect(); return Rect();
} }
CLabelGroup::CLabelGroup(EFonts Font, EAlignment Align, const SDL_Color &Color): CLabelGroup::CLabelGroup(EFonts Font, EAlignment Align, const SDL_Color & Color)
font(Font), align(Align), color(Color) : font(Font), align(Align), color(Color)
{} {
defActions = 255-DISPOSE;
}
void CLabelGroup::add(int x, int y, const std::string &text) void CLabelGroup::add(int x, int y, const std::string &text)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
labels.push_back(new CLabel(x, y, font, align, color, text)); labels.push_back(std::make_shared<CLabel>(x, y, font, align, color, text));
} }
size_t CLabelGroup::currentSize() const size_t CLabelGroup::currentSize() const
@ -278,8 +279,8 @@ CTextBox::CTextBox(std::string Text, const Rect &rect, int SliderStyle, EFonts F
sliderStyle(SliderStyle), sliderStyle(SliderStyle),
slider(nullptr) slider(nullptr)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
label = new CMultiLineLabel(rect, Font, Align, Color); label = std::make_shared<CMultiLineLabel>(rect, Font, Align, Color);
type |= REDRAW_PARENT; type |= REDRAW_PARENT;
pos.x += rect.x; pos.x += rect.x;
@ -302,9 +303,8 @@ void CTextBox::resize(Point newSize)
pos.h = newSize.y; pos.h = newSize.y;
label->pos.w = pos.w; label->pos.w = pos.w;
label->pos.h = pos.h; label->pos.h = pos.h;
if (slider)
vstd::clear_pointer(slider); // will be recreated if needed later
slider.reset();
setText(label->getText()); // force refresh setText(label->getText()); // force refresh
} }
@ -315,7 +315,7 @@ void CTextBox::setText(const std::string &text)
if(label->textSize.y <= label->pos.h && slider) if(label->textSize.y <= label->pos.h && slider)
{ {
// slider is no longer needed // slider is no longer needed
vstd::clear_pointer(slider); slider.reset();
} }
else if(slider) else if(slider)
{ {
@ -330,8 +330,8 @@ void CTextBox::setText(const std::string &text)
label->pos.w = pos.w - 32; label->pos.w = pos.w - 32;
label->setText(text); label->setText(text);
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
slider = new CSlider(Point(pos.w - 32, 0), pos.h, std::bind(&CTextBox::sliderMoved, this, _1), slider = std::make_shared<CSlider>(Point(pos.w - 32, 0), pos.h, std::bind(&CTextBox::sliderMoved, this, _1),
label->pos.h, label->textSize.y, 0, false, CSlider::EStyle(sliderStyle)); label->pos.h, label->textSize.y, 0, false, CSlider::EStyle(sliderStyle));
slider->setScrollStep(graphics->fonts[label->font]->getLineHeight()); slider->setScrollStep(graphics->fonts[label->font]->getLineHeight());
} }
@ -348,28 +348,28 @@ void CGStatusBar::clear()
setText(""); setText("");
} }
CGStatusBar::CGStatusBar(CPicture *BG, EFonts Font, EAlignment Align, const SDL_Color &Color) CGStatusBar::CGStatusBar(std::shared_ptr<CPicture> background_, EFonts Font, EAlignment Align, const SDL_Color & Color)
: CLabel(BG->pos.x, BG->pos.y, Font, Align, Color, "") : CLabel(background_->pos.x, background_->pos.y, Font, Align, Color, "")
{ {
init(); init();
bg = BG; background = background_;
addChild(bg); addChild(background.get());
pos = bg->pos; pos = background->pos;
getBorderSize(); getBorderSize();
textLock = false; textLock = false;
} }
CGStatusBar::CGStatusBar(int x, int y, std::string name, int maxw) CGStatusBar::CGStatusBar(int x, int y, std::string name, int maxw)
: CLabel(x, y, FONT_SMALL, CENTER) : CLabel(x, y, FONT_SMALL, CENTER)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
init(); init();
bg = new CPicture(name); background = std::make_shared<CPicture>(name);
pos = bg->pos; pos = background->pos;
if((unsigned int)maxw < pos.w) if((unsigned int)maxw < pos.w)
{ {
vstd::amin(pos.w, maxw); vstd::amin(pos.w, maxw);
bg->srcRect = new Rect(0, 0, maxw, pos.h); background->srcRect = new Rect(0, 0, maxw, pos.h);
} }
textLock = false; textLock = false;
} }
@ -410,8 +410,8 @@ void CGStatusBar::lock(bool shouldLock)
textLock = shouldLock; textLock = shouldLock;
} }
CTextInput::CTextInput(const Rect &Pos, EFonts font, const CFunctionList<void(const std::string &)> &CB): CTextInput::CTextInput(const Rect &Pos, EFonts font, const CFunctionList<void(const std::string &)> &CB)
CLabel(Pos.x, Pos.y, font, CENTER), : CLabel(Pos.x, Pos.y, font, CENTER),
cb(CB) cb(CB)
{ {
type |= REDRAW_PARENT; type |= REDRAW_PARENT;
@ -419,38 +419,38 @@ CTextInput::CTextInput(const Rect &Pos, EFonts font, const CFunctionList<void(co
pos.h = Pos.h; pos.h = Pos.h;
pos.w = Pos.w; pos.w = Pos.w;
captureAllKeys = true; captureAllKeys = true;
bg = nullptr; background.reset();
addUsedEvents(LCLICK | KEYBOARD | TEXTINPUT); addUsedEvents(LCLICK | KEYBOARD | TEXTINPUT);
giveFocus(); giveFocus();
} }
CTextInput::CTextInput( const Rect &Pos, const Point &bgOffset, const std::string &bgName, const CFunctionList<void(const std::string &)> &CB ) CTextInput::CTextInput(const Rect & Pos, const Point & bgOffset, const std::string & bgName, const CFunctionList<void(const std::string &)> & CB)
:cb(CB) :cb(CB)
{ {
focus = false; focus = false;
pos += Pos; pos += Pos;
captureAllKeys = true; captureAllKeys = true;
OBJ_CONSTRUCTION; OBJ_CONSTRUCTION;
bg = new CPicture(bgName, bgOffset.x, bgOffset.y); background = std::make_shared<CPicture>(bgName, bgOffset.x, bgOffset.y);
addUsedEvents(LCLICK | KEYBOARD | TEXTINPUT); addUsedEvents(LCLICK | KEYBOARD | TEXTINPUT);
giveFocus(); giveFocus();
} }
CTextInput::CTextInput(const Rect &Pos, SDL_Surface *srf) CTextInput::CTextInput(const Rect & Pos, SDL_Surface * srf)
{ {
focus = false; focus = false;
pos += Pos; pos += Pos;
captureAllKeys = true; captureAllKeys = true;
OBJ_CONSTRUCTION; OBJ_CONSTRUCTION;
bg = new CPicture(Pos, 0, true); background = std::make_shared<CPicture>(Pos, 0, true);
Rect hlp = Pos; Rect hlp = Pos;
if(srf) if(srf)
CSDL_Ext::blitSurface(srf, &hlp, *bg, nullptr); CSDL_Ext::blitSurface(srf, &hlp, *background.get(), nullptr);
else else
SDL_FillRect(*bg, nullptr, 0); SDL_FillRect(*background.get(), nullptr, 0);
pos.w = bg->pos.w; pos.w = background->pos.w;
pos.h = bg->pos.h; pos.h = background->pos.h;
bg->pos = pos; background->pos = pos;
addUsedEvents(LCLICK | KEYBOARD | TEXTINPUT); addUsedEvents(LCLICK | KEYBOARD | TEXTINPUT);
giveFocus(); giveFocus();
} }

View File

@ -40,7 +40,7 @@ protected:
Point getBorderSize() override; Point getBorderSize() override;
virtual std::string visibleText(); virtual std::string visibleText();
CPicture *bg; std::shared_ptr<CPicture> background;
public: public:
std::string text; std::string text;
@ -60,7 +60,7 @@ public:
/// Small helper class to manage group of similar labels /// Small helper class to manage group of similar labels
class CLabelGroup : public CIntObject class CLabelGroup : public CIntObject
{ {
std::list<CLabel*> labels; std::vector<std::shared_ptr<CLabel>> labels;
EFonts font; EFonts font;
EAlignment align; EAlignment align;
SDL_Color color; SDL_Color color;
@ -103,13 +103,13 @@ class CTextBox : public CIntObject
{ {
int sliderStyle; int sliderStyle;
public: public:
CMultiLineLabel * label; std::shared_ptr<CMultiLineLabel> label;
CSlider *slider; std::shared_ptr<CSlider> slider;
CTextBox(std::string Text, const Rect &rect, int SliderStyle, EFonts Font = FONT_SMALL, EAlignment Align = TOPLEFT, const SDL_Color &Color = Colors::WHITE); CTextBox(std::string Text, const Rect & rect, int SliderStyle, EFonts Font = FONT_SMALL, EAlignment Align = TOPLEFT, const SDL_Color & Color = Colors::WHITE);
void resize(Point newSize); void resize(Point newSize);
void setText(const std::string &Txt); void setText(const std::string & Txt);
void sliderMoved(int to); void sliderMoved(int to);
}; };
@ -119,19 +119,18 @@ class CGStatusBar : public CLabel
bool textLock; //Used for blocking changes to the text bool textLock; //Used for blocking changes to the text
void init(); void init();
CGStatusBar *oldStatusBar; CGStatusBar * oldStatusBar;
protected: protected:
Point getBorderSize() override; Point getBorderSize() override;
public: public:
void clear();//clears statusbar and refreshes void clear();//clears statusbar and refreshes
void setText(const std::string & Text) override; //prints text and refreshes statusbar void setText(const std::string & Text) override; //prints text and refreshes statusbar
void show(SDL_Surface * to) override; //shows statusbar (with current text) void show(SDL_Surface * to) override; //shows statusbar (with current text)
CGStatusBar(CPicture *BG, EFonts Font = FONT_SMALL, EAlignment Align = CENTER, const SDL_Color &Color = Colors::WHITE); //given CPicture will be captured by created sbar and it's pos will be used as pos for sbar CGStatusBar(std::shared_ptr<CPicture> background_, EFonts Font = FONT_SMALL, EAlignment Align = CENTER, const SDL_Color & Color = Colors::WHITE);
CGStatusBar(int x, int y, std::string name, int maxw=-1); CGStatusBar(int x, int y, std::string name, int maxw = -1);
~CGStatusBar(); ~CGStatusBar();
void lock(bool shouldLock); //If true, current text cannot be changed until lock(false) is called void lock(bool shouldLock); //If true, current text cannot be changed until lock(false) is called
@ -180,7 +179,7 @@ public:
void clickLeft(tribool down, bool previousState) override; void clickLeft(tribool down, bool previousState) override;
void keyPressed(const SDL_KeyboardEvent & key) override; void keyPressed(const SDL_KeyboardEvent & key) override;
bool captureThisEvent(const SDL_KeyboardEvent & key) override; bool captureThisEvent(const SDL_KeyboardEvent & key) override;
void textInputed(const SDL_TextInputEvent & event) override; void textInputed(const SDL_TextInputEvent & event) override;
void textEdited(const SDL_TextEditingEvent & event) override; void textEdited(const SDL_TextEditingEvent & event) override;

View File

@ -90,7 +90,7 @@ static void setScrollingCursor(ui8 direction)
CTerrainRect::CTerrainRect() CTerrainRect::CTerrainRect()
: fadeSurface(nullptr), : fadeSurface(nullptr),
lastRedrawStatus(EMapAnimRedrawStatus::OK), lastRedrawStatus(EMapAnimRedrawStatus::OK),
fadeAnim(new CFadeAnimation()), fadeAnim(std::make_shared<CFadeAnimation>()),
curHoveredTile(-1,-1,-1), curHoveredTile(-1,-1,-1),
currentPath(nullptr) currentPath(nullptr)
{ {
@ -106,9 +106,8 @@ CTerrainRect::CTerrainRect()
CTerrainRect::~CTerrainRect() CTerrainRect::~CTerrainRect()
{ {
if (fadeSurface) if(fadeSurface)
SDL_FreeSurface(fadeSurface); SDL_FreeSurface(fadeSurface);
delete fadeAnim;
} }
void CTerrainRect::deactivate() void CTerrainRect::deactivate()
@ -475,12 +474,16 @@ void CResDataBar::clickRight(tribool down, bool previousState)
{ {
} }
CResDataBar::CResDataBar(const std::string &defname, int x, int y, int offx, int offy, int resdist, int datedist) CResDataBar::CResDataBar(const std::string & defname, int x, int y, int offx, int offy, int resdist, int datedist)
{ {
bg = BitmapHandler::loadBitmap(defname); pos.x += x;
CSDL_Ext::setDefaultColorKey(bg); pos.y += y;
graphics->blueToPlayersAdv(bg,LOCPLINT->playerID); OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
pos = genRect(bg->h, bg->w, pos.x+x, pos.y+y); background = std::make_shared<CPicture>(defname, 0, 0);
background->colorize(LOCPLINT->playerID);
pos.w = background->bg->w;
pos.h = background->bg->h;
txtpos.resize(8); txtpos.resize(8);
for (int i = 0; i < 8 ; i++) for (int i = 0; i < 8 ; i++)
@ -496,10 +499,15 @@ CResDataBar::CResDataBar(const std::string &defname, int x, int y, int offx, int
CResDataBar::CResDataBar() CResDataBar::CResDataBar()
{ {
bg = BitmapHandler::loadBitmap(ADVOPT.resdatabarG); pos.x += ADVOPT.resdatabarX;
CSDL_Ext::setDefaultColorKey(bg); pos.y += ADVOPT.resdatabarY;
graphics->blueToPlayersAdv(bg,LOCPLINT->playerID);
pos = genRect(bg->h,bg->w,ADVOPT.resdatabarX,ADVOPT.resdatabarY); OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
background = std::make_shared<CPicture>(ADVOPT.resdatabarG, 0, 0);
background->colorize(LOCPLINT->playerID);
pos.w = background->bg->w;
pos.h = background->bg->h;
txtpos.resize(8); txtpos.resize(8);
for (int i = 0; i < 8 ; i++) for (int i = 0; i < 8 ; i++)
@ -512,13 +520,11 @@ CResDataBar::CResDataBar()
+ ": %s, " + CGI->generaltexth->allTexts[64] + ": %s"; + ": %s, " + CGI->generaltexth->allTexts[64] + ": %s";
} }
CResDataBar::~CResDataBar() CResDataBar::~CResDataBar() = default;
{
SDL_FreeSurface(bg);
}
void CResDataBar::draw(SDL_Surface * to) void CResDataBar::draw(SDL_Surface * to)
{ {
blitAt(bg,pos.x,pos.y,to); //TODO: all this should be labels, but they require proper text update on change
for (auto i=Res::WOOD; i<=Res::GOLD; vstd::advance(i, 1)) for (auto i=Res::WOOD; i<=Res::GOLD; vstd::advance(i, 1))
{ {
std::string text = boost::lexical_cast<std::string>(LOCPLINT->cb->getResourceAmount(i)); std::string text = boost::lexical_cast<std::string>(LOCPLINT->cb->getResourceAmount(i));
@ -541,6 +547,7 @@ void CResDataBar::show(SDL_Surface * to)
void CResDataBar::showAll(SDL_Surface * to) void CResDataBar::showAll(SDL_Surface * to)
{ {
CIntObject::showAll(to);
draw(to); draw(to);
} }
@ -552,13 +559,13 @@ CAdvMapInt::CAdvMapInt():
heroList(ADVOPT.hlistSize, Point(ADVOPT.hlistX, ADVOPT.hlistY), ADVOPT.hlistAU, ADVOPT.hlistAD), heroList(ADVOPT.hlistSize, Point(ADVOPT.hlistX, ADVOPT.hlistY), ADVOPT.hlistAU, ADVOPT.hlistAD),
townList(ADVOPT.tlistSize, Point(ADVOPT.tlistX, ADVOPT.tlistY), ADVOPT.tlistAU, ADVOPT.tlistAD), townList(ADVOPT.tlistSize, Point(ADVOPT.tlistX, ADVOPT.tlistY), ADVOPT.tlistAU, ADVOPT.tlistAD),
infoBar(Rect(ADVOPT.infoboxX, ADVOPT.infoboxY, 192, 192)), state(NA), infoBar(Rect(ADVOPT.infoboxX, ADVOPT.infoboxY, 192, 192)), state(NA),
spellBeingCasted(nullptr), position(int3(0, 0, 0)), selection(nullptr), spellBeingCasted(nullptr), position(int3(0, 0, 0)), selection(nullptr),
updateScreen(false), anim(0), animValHitCount(0), heroAnim(0), heroAnimValHitCount(0), updateScreen(false), anim(0), animValHitCount(0), heroAnim(0), heroAnimValHitCount(0),
activeMapPanel(nullptr), duringAITurn(false), scrollingDir(0), scrollingState(false), activeMapPanel(nullptr), duringAITurn(false), scrollingDir(0), scrollingState(false),
swipeEnabled(settings["general"]["swipe"].Bool()), swipeMovementRequested(false), swipeEnabled(settings["general"]["swipe"].Bool()), swipeMovementRequested(false),
swipeTargetPosition(int3(-1, -1, -1)) swipeTargetPosition(int3(-1, -1, -1))
{ {
adventureInt = this; adventureInt = this;
pos.x = pos.y = 0; pos.x = pos.y = 0;
pos.w = screen->w; pos.w = screen->w;
pos.h = screen->h; pos.h = screen->h;
@ -580,18 +587,17 @@ CAdvMapInt::CAdvMapInt():
} }
worldViewIcons = std::make_shared<CAnimation>("VwSymbol");//todo: customize with ADVOPT worldViewIcons = std::make_shared<CAnimation>("VwSymbol");//todo: customize with ADVOPT
//preload all for faster map drawing worldViewIcons->preload();
worldViewIcons->load();//TODO: make special method in CAnimation fro that
for (int g=0; g<ADVOPT.gemG.size(); ++g) for(int g = 0; g < ADVOPT.gemG.size(); ++g)
{ {
gems.push_back(new CAnimImage(ADVOPT.gemG[g], 0, 0, ADVOPT.gemX[g], ADVOPT.gemY[g])); gems.push_back(std::make_shared<CAnimImage>(ADVOPT.gemG[g], 0, 0, ADVOPT.gemX[g], ADVOPT.gemY[g]));
} }
auto makeButton = [&] (int textID, std::function<void()> callback, config::ButtonInfo info, int key) -> CButton * auto makeButton = [&](int textID, std::function<void()> callback, config::ButtonInfo info, int key) -> std::shared_ptr<CButton>
{ {
auto button = new CButton(Point(info.x, info.y), info.defName, CGI->generaltexth->zelp[textID], callback, key, info.playerColoured); auto button = std::make_shared<CButton>(Point(info.x, info.y), info.defName, CGI->generaltexth->zelp[textID], callback, key, info.playerColoured);
for (auto image : info.additionalDefs) for(auto image : info.additionalDefs)
button->addImage(image); button->addImage(image);
return button; return button;
}; };
@ -609,9 +615,9 @@ CAdvMapInt::CAdvMapInt():
int panelSpaceBottom = screen->h - resdatabar.pos.h - 4; int panelSpaceBottom = screen->h - resdatabar.pos.h - 4;
panelMain = new CAdvMapPanel(nullptr, Point(0, 0)); panelMain = std::make_shared<CAdvMapPanel>(nullptr, Point(0, 0));
// TODO correct drawing position // TODO correct drawing position
panelWorldView = new CAdvMapWorldViewPanel(worldViewIcons, bgWorldView, Point(heroList.pos.x - 2, 195), panelSpaceBottom, LOCPLINT->playerID); panelWorldView = std::make_shared<CAdvMapWorldViewPanel>(worldViewIcons, bgWorldView, Point(heroList.pos.x - 2, 195), panelSpaceBottom, LOCPLINT->playerID);
panelMain->addChildColorableButton(kingOverview); panelMain->addChildColorableButton(kingOverview);
panelMain->addChildColorableButton(underground); panelMain->addChildColorableButton(underground);
@ -640,7 +646,7 @@ CAdvMapInt::CAdvMapInt():
worldViewPuzzleConfig.y = 343 + 195; worldViewPuzzleConfig.y = 343 + 195;
worldViewPuzzleConfig.playerColoured = false; worldViewPuzzleConfig.playerColoured = false;
panelWorldView->addChildToPanel( // no help text for this one panelWorldView->addChildToPanel( // no help text for this one
new CButton(Point(worldViewPuzzleConfig.x, worldViewPuzzleConfig.y), worldViewPuzzleConfig.defName, std::pair<std::string, std::string>(), std::make_shared<CButton>(Point(worldViewPuzzleConfig.x, worldViewPuzzleConfig.y), worldViewPuzzleConfig.defName, std::pair<std::string, std::string>(),
std::bind(&CPlayerInterface::showPuzzleMap,LOCPLINT), SDLK_p, worldViewPuzzleConfig.playerColoured), ACTIVATE | DEACTIVATE); std::bind(&CPlayerInterface::showPuzzleMap,LOCPLINT), SDLK_p, worldViewPuzzleConfig.playerColoured), ACTIVATE | DEACTIVATE);
config::ButtonInfo worldViewScale1xConfig = config::ButtonInfo(); config::ButtonInfo worldViewScale1xConfig = config::ButtonInfo();
@ -684,19 +690,19 @@ CAdvMapInt::CAdvMapInt():
for (int i = 0; i < 5; ++i) for (int i = 0; i < 5; ++i)
{ {
panelWorldView->addChildIcon(std::pair<int, Point>(i, Point(5, 58 + i * 20)), iconColorMultiplier); panelWorldView->addChildIcon(std::pair<int, Point>(i, Point(5, 58 + i * 20)), iconColorMultiplier);
panelWorldView->addChildToPanel(new CLabel(wvLeft + 45, 263 + i * 20, EFonts::FONT_SMALL, EAlignment::TOPLEFT, panelWorldView->addChildToPanel(std::make_shared<CLabel>(wvLeft + 45, 263 + i * 20, EFonts::FONT_SMALL, EAlignment::TOPLEFT,
Colors::WHITE, CGI->generaltexth->allTexts[612 + i])); Colors::WHITE, CGI->generaltexth->allTexts[612 + i]));
} }
for (int i = 0; i < 7; ++i) for (int i = 0; i < 7; ++i)
{ {
panelWorldView->addChildIcon(std::pair<int, Point>(i + 5, Point(5, 182 + i * 20)), iconColorMultiplier); panelWorldView->addChildIcon(std::pair<int, Point>(i + 5, Point(5, 182 + i * 20)), iconColorMultiplier);
panelWorldView->addChildIcon(std::pair<int, Point>(i + 12, Point(160, 182 + i * 20)), iconColorMultiplier); panelWorldView->addChildIcon(std::pair<int, Point>(i + 12, Point(160, 182 + i * 20)), iconColorMultiplier);
panelWorldView->addChildToPanel(new CLabel(wvLeft + 45, 387 + i * 20, EFonts::FONT_SMALL, EAlignment::TOPLEFT, panelWorldView->addChildToPanel(std::make_shared<CLabel>(wvLeft + 45, 387 + i * 20, EFonts::FONT_SMALL, EAlignment::TOPLEFT,
Colors::WHITE, CGI->generaltexth->allTexts[619 + i])); Colors::WHITE, CGI->generaltexth->allTexts[619 + i]));
} }
panelWorldView->addChildToPanel(new CLabel(wvLeft + 5, 367, EFonts::FONT_SMALL, EAlignment::TOPLEFT, panelWorldView->addChildToPanel(std::make_shared<CLabel>(wvLeft + 5, 367, EFonts::FONT_SMALL, EAlignment::TOPLEFT,
Colors::WHITE, CGI->generaltexth->allTexts[617])); Colors::WHITE, CGI->generaltexth->allTexts[617]));
panelWorldView->addChildToPanel(new CLabel(wvLeft + 185, 387, EFonts::FONT_SMALL, EAlignment::BOTTOMRIGHT, panelWorldView->addChildToPanel(std::make_shared<CLabel>(wvLeft + 45, 367, EFonts::FONT_SMALL, EAlignment::TOPLEFT,
Colors::WHITE, CGI->generaltexth->allTexts[618])); Colors::WHITE, CGI->generaltexth->allTexts[618]));
activeMapPanel = panelMain; activeMapPanel = panelMain;
@ -713,8 +719,6 @@ CAdvMapInt::CAdvMapInt():
CAdvMapInt::~CAdvMapInt() CAdvMapInt::~CAdvMapInt()
{ {
SDL_FreeSurface(bg); SDL_FreeSurface(bg);
worldViewIcons->unload();
} }
void CAdvMapInt::fshowOverview() void CAdvMapInt::fshowOverview()
@ -846,7 +850,7 @@ void CAdvMapInt::fendTurn()
auto path = LOCPLINT->getAndVerifyPath(hero); auto path = LOCPLINT->getAndVerifyPath(hero);
if(!path || path->nodes.size() < 2 || !path->nodes[path->nodes.size()-2].turns) if(!path || path->nodes.size() < 2 || !path->nodes[path->nodes.size()-2].turns)
{ {
LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[55], std::bind(&CAdvMapInt::endingTurn, this), 0, false); LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[55], std::bind(&CAdvMapInt::endingTurn, this), nullptr);
return; return;
} }
} }
@ -996,7 +1000,7 @@ void CAdvMapInt::showAll(SDL_Surface * to)
show(to); show(to);
resdatabar.draw(to); resdatabar.showAll(to);
statusbar.show(to); statusbar.show(to);
@ -1240,8 +1244,7 @@ void CAdvMapInt::keyPressed(const SDL_KeyboardEvent & key)
if(isActive() && LOCPLINT->ctrlPressed()) if(isActive() && LOCPLINT->ctrlPressed())
{ {
LOCPLINT->showYesNoDialog("Are you sure you want to restart game?", LOCPLINT->showYesNoDialog("Are you sure you want to restart game?",
[](){ LOCPLINT->sendCustomEvent(EUserEvent::RESTART_GAME); }, [](){ LOCPLINT->sendCustomEvent(EUserEvent::RESTART_GAME); }, nullptr);
[](){}, true);
} }
return; return;
case SDLK_SPACE: //space - try to revisit current object with selected hero case SDLK_SPACE: //space - try to revisit current object with selected hero
@ -1503,7 +1506,7 @@ void CAdvMapInt::setPlayer(PlayerColor Player)
panelMain->setPlayerColor(player); panelMain->setPlayerColor(player);
panelWorldView->setPlayerColor(player); panelWorldView->setPlayerColor(player);
panelWorldView->recolorIcons(player, player.getNum() * 19); panelWorldView->recolorIcons(player, player.getNum() * 19);
graphics->blueToPlayersAdv(resdatabar.bg,player); resdatabar.background->colorize(player);
} }
void CAdvMapInt::startTurn() void CAdvMapInt::startTurn()
@ -1926,24 +1929,24 @@ void CAdvMapInt::changeMode(EAdvMapMode newMode, float newScale)
} }
} }
CAdventureOptions::CAdventureOptions(): CAdventureOptions::CAdventureOptions()
CWindowObject(PLAYER_COLORED, "ADVOPTS") : CWindowObject(PLAYER_COLORED, "ADVOPTS")
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
viewWorld = new CButton(Point(24, 23), "ADVVIEW.DEF", CButton::tooltip(), [&](){ close(); }, SDLK_v); viewWorld = std::make_shared<CButton>(Point(24, 23), "ADVVIEW.DEF", CButton::tooltip(), [&](){ close(); }, SDLK_v);
viewWorld->addCallback(std::bind(&CPlayerInterface::viewWorldMap, LOCPLINT)); viewWorld->addCallback(std::bind(&CPlayerInterface::viewWorldMap, LOCPLINT));
exit = new CButton(Point(204, 313), "IOK6432.DEF", CButton::tooltip(), std::bind(&CAdventureOptions::close, this), SDLK_RETURN); exit = std::make_shared<CButton>(Point(204, 313), "IOK6432.DEF", CButton::tooltip(), std::bind(&CAdventureOptions::close, this), SDLK_RETURN);
exit->assignedKeys.insert(SDLK_ESCAPE); exit->assignedKeys.insert(SDLK_ESCAPE);
scenInfo = new CButton(Point(24, 198), "ADVINFO.DEF", CButton::tooltip(), [&](){ close(); }, SDLK_i); scenInfo = std::make_shared<CButton>(Point(24, 198), "ADVINFO.DEF", CButton::tooltip(), [&](){ close(); }, SDLK_i);
scenInfo->addCallback(CAdventureOptions::showScenarioInfo); scenInfo->addCallback(CAdventureOptions::showScenarioInfo);
puzzle = new CButton(Point(24, 81), "ADVPUZ.DEF", CButton::tooltip(), [&](){ close(); }, SDLK_p); puzzle = std::make_shared<CButton>(Point(24, 81), "ADVPUZ.DEF", CButton::tooltip(), [&](){ close(); }, SDLK_p);
puzzle->addCallback(std::bind(&CPlayerInterface::showPuzzleMap, LOCPLINT)); puzzle->addCallback(std::bind(&CPlayerInterface::showPuzzleMap, LOCPLINT));
dig = new CButton(Point(24, 139), "ADVDIG.DEF", CButton::tooltip(), [&](){ close(); }, SDLK_d); dig = std::make_shared<CButton>(Point(24, 139), "ADVDIG.DEF", CButton::tooltip(), [&](){ close(); }, SDLK_d);
if(const CGHeroInstance *h = adventureInt->curHero()) if(const CGHeroInstance *h = adventureInt->curHero())
dig->addCallback(std::bind(&CPlayerInterface::tryDiggging, LOCPLINT, h)); dig->addCallback(std::bind(&CPlayerInterface::tryDiggging, LOCPLINT, h));
else else

View File

@ -38,23 +38,27 @@ enum class EAdvMapMode
WORLD_VIEW WORLD_VIEW
}; };
/// Adventure options dialogue where you can view the world, dig, play the replay of the last turn,... /// Adventure options dialog where you can view the world, dig, play the replay of the last turn,...
class CAdventureOptions : public CWindowObject class CAdventureOptions : public CWindowObject
{ {
public: public:
CButton *exit, *viewWorld, *puzzle, *dig, *scenInfo/*, *replay*/; std::shared_ptr<CButton> exit;
std::shared_ptr<CButton> viewWorld;
std::shared_ptr<CButton> puzzle;
std::shared_ptr<CButton> dig;
std::shared_ptr<CButton> scenInfo;
/*std::shared_ptr<CButton> replay*/
CAdventureOptions(); CAdventureOptions();
static void showScenarioInfo(); static void showScenarioInfo();
}; };
/// Holds information about which tiles of the terrain are shown/not shown at the screen /// Holds information about which tiles of the terrain are shown/not shown at the screen
class CTerrainRect class CTerrainRect : public CIntObject
: public CIntObject
{ {
SDL_Surface * fadeSurface; SDL_Surface * fadeSurface;
EMapAnimRedrawStatus lastRedrawStatus; EMapAnimRedrawStatus lastRedrawStatus;
CFadeAnimation * fadeAnim; std::shared_ptr<CFadeAnimation> fadeAnim;
int3 swipeInitialMapPos; int3 swipeInitialMapPos;
int3 swipeInitialRealPos; int3 swipeInitialRealPos;
@ -69,10 +73,10 @@ public:
int tilesw, tilesh; //width and height of terrain to blit in tiles int tilesw, tilesh; //width and height of terrain to blit in tiles
int3 curHoveredTile; int3 curHoveredTile;
int moveX, moveY; //shift between actual position of screen and the one we wil blit; ranges from -31 to 31 (in pixels) int moveX, moveY; //shift between actual position of screen and the one we wil blit; ranges from -31 to 31 (in pixels)
CGPath * currentPath;
CTerrainRect(); CTerrainRect();
virtual ~CTerrainRect(); virtual ~CTerrainRect();
CGPath * currentPath;
void deactivate() override; void deactivate() override;
void clickLeft(tribool down, bool previousState) override; void clickLeft(tribool down, bool previousState) override;
void clickRight(tribool down, bool previousState) override; void clickRight(tribool down, bool previousState) override;
@ -90,7 +94,6 @@ public:
/// animates view by caching current surface and crossfading it with normal screen /// animates view by caching current surface and crossfading it with normal screen
void fadeFromCurrentView(); void fadeFromCurrentView();
bool needsAnimUpdate(); bool needsAnimUpdate();
}; };
/// Resources bar which shows information about how many gold, crystals,... you have /// Resources bar which shows information about how many gold, crystals,... you have
@ -98,7 +101,8 @@ public:
class CResDataBar : public CIntObject class CResDataBar : public CIntObject
{ {
public: public:
SDL_Surface * bg; std::shared_ptr<CPicture> background;
std::vector<std::pair<int,int> > txtpos; std::vector<std::pair<int,int> > txtpos;
std::string datetext; std::string datetext;
@ -162,22 +166,22 @@ public:
SDL_Surface * bg; SDL_Surface * bg;
SDL_Surface * bgWorldView; SDL_Surface * bgWorldView;
std::vector<CAnimImage *> gems; std::vector<std::shared_ptr<CAnimImage>> gems;
CMinimap minimap; CMinimap minimap;
CGStatusBar statusbar; CGStatusBar statusbar;
CButton * kingOverview; std::shared_ptr<CButton> kingOverview;
CButton * underground; std::shared_ptr<CButton> underground;
CButton * questlog; std::shared_ptr<CButton> questlog;
CButton * sleepWake; std::shared_ptr<CButton> sleepWake;
CButton * moveHero; std::shared_ptr<CButton> moveHero;
CButton * spellbook; std::shared_ptr<CButton> spellbook;
CButton * advOptions; std::shared_ptr<CButton> advOptions;
CButton * sysOptions; std::shared_ptr<CButton> sysOptions;
CButton * nextHero; std::shared_ptr<CButton> nextHero;
CButton * endTurn; std::shared_ptr<CButton> endTurn;
CButton * worldViewUnderground; std::shared_ptr<CButton> worldViewUnderground;
CTerrainRect terrain; //visible terrain CTerrainRect terrain; //visible terrain
CResDataBar resdatabar; CResDataBar resdatabar;
@ -185,9 +189,9 @@ public:
CTownList townList; CTownList townList;
CInfoBar infoBar; CInfoBar infoBar;
CAdvMapPanel *panelMain; // panel that holds all right-side buttons in normal view std::shared_ptr<CAdvMapPanel> panelMain; // panel that holds all right-side buttons in normal view
CAdvMapWorldViewPanel *panelWorldView; // panel that holds all buttons and other ui in world view std::shared_ptr<CAdvMapWorldViewPanel> panelWorldView; // panel that holds all buttons and other ui in world view
CAdvMapPanel *activeMapPanel; // currently active panel (either main or world view, depending on current mode) std::shared_ptr<CAdvMapPanel> activeMapPanel; // currently active panel (either main or world view, depending on current mode)
std::shared_ptr<CAnimation> worldViewIcons;// images for world view overlay std::shared_ptr<CAnimation> worldViewIcons;// images for world view overlay

File diff suppressed because it is too large Load Diff

View File

@ -29,6 +29,8 @@ struct CStructure;
class CGHeroInstance; class CGHeroInstance;
class CGarrisonInt; class CGarrisonInt;
class CCreature; class CCreature;
class CComponent;
class CComponentBox;
/// Building "button" /// Building "button"
class CBuildingRect : public CShowableAnim class CBuildingRect : public CShowableAnim
@ -60,38 +62,43 @@ public:
/// Dwelling info box - right-click screen for dwellings /// Dwelling info box - right-click screen for dwellings
class CDwellingInfoBox : public CWindowObject class CDwellingInfoBox : public CWindowObject
{ {
CLabel *title; std::shared_ptr<CLabel> title;
CCreaturePic *animation; std::shared_ptr<CCreaturePic> animation;
CLabel *available; std::shared_ptr<CLabel> available;
CLabel *costPerTroop; std::shared_ptr<CLabel> costPerTroop;
std::vector<CAnimImage *> resPicture; std::vector<std::shared_ptr<CAnimImage>> resPicture;
std::vector<CLabel *> resAmount; std::vector<std::shared_ptr<CLabel>> resAmount;
public: public:
CDwellingInfoBox(int centerX, int centerY, const CGTownInstance *Town, int level); CDwellingInfoBox(int centerX, int centerY, const CGTownInstance * Town, int level);
~CDwellingInfoBox();
}; };
class HeroSlots; class HeroSlots;
/// Hero icon slot /// Hero icon slot
class CHeroGSlot : public CIntObject class CHeroGSlot : public CIntObject
{ {
public: std::shared_ptr<CAnimImage> portrait;
HeroSlots *owner; std::shared_ptr<CAnimImage> flag;
const CGHeroInstance *hero; std::shared_ptr<CAnimImage> selection; //selection border. nullptr if not selected
HeroSlots * owner;
const CGHeroInstance * hero;
int upg; //0 - up garrison, 1 - down garrison int upg; //0 - up garrison, 1 - down garrison
CAnimImage *image; public:
CAnimImage *selection; //selection border. nullptr if not selected CHeroGSlot(int x, int y, int updown, const CGHeroInstance *h, HeroSlots * Owner);
~CHeroGSlot();
bool isSelected() const;
void setHighlight(bool on); void setHighlight(bool on);
void set(const CGHeroInstance *newHero); void set(const CGHeroInstance * newHero);
void hover (bool on) override; void hover (bool on) override;
void clickLeft(tribool down, bool previousState) override; void clickLeft(tribool down, bool previousState) override;
void clickRight(tribool down, bool previousState) override; void clickRight(tribool down, bool previousState) override;
void deactivate() override; void deactivate() override;
CHeroGSlot(int x, int y, int updown, const CGHeroInstance *h, HeroSlots * Owner);
~CHeroGSlot();
}; };
/// Two hero slots that can interact with each other /// Two hero slots that can interact with each other
@ -101,11 +108,12 @@ public:
bool showEmpty; bool showEmpty;
const CGTownInstance * town; const CGTownInstance * town;
CGarrisonInt *garr; std::shared_ptr<CGarrisonInt> garr;
CHeroGSlot * garrisonedHero; std::shared_ptr<CHeroGSlot> garrisonedHero;
CHeroGSlot * visitingHero; std::shared_ptr<CHeroGSlot> visitingHero;
HeroSlots(const CGTownInstance * town, Point garrPos, Point visitPos, CGarrisonInt *Garrison, bool ShowEmpty); HeroSlots(const CGTownInstance * town, Point garrPos, Point visitPos, std::shared_ptr<CGarrisonInt> Garrison, bool ShowEmpty);
~HeroSlots();
void splitClicked(); //for hero meeting only (splitting stacks is handled by garrison int) void splitClicked(); //for hero meeting only (splitting stacks is handled by garrison int)
void update(); void update();
@ -115,11 +123,11 @@ public:
/// Class for town screen management (town background and structures) /// Class for town screen management (town background and structures)
class CCastleBuildings : public CIntObject class CCastleBuildings : public CIntObject
{ {
CPicture *background; std::shared_ptr<CPicture> background;
//List of buildings and structures that can represent them //List of buildings and structures that can represent them
std::map< BuildingID, std::vector<const CStructure*> > groups; std::map<BuildingID, std::vector<const CStructure *> > groups;
// actual IntObject's visible on screen // actual IntObject's visible on screen
std::vector< CBuildingRect * > buildings; std::vector<std::shared_ptr<CBuildingRect>> buildings;
const CGTownInstance * town; const CGTownInstance * town;
@ -139,7 +147,7 @@ class CCastleBuildings : public CIntObject
public: public:
CBuildingRect * selectedBuilding; CBuildingRect * selectedBuilding;
CCastleBuildings(const CGTownInstance* town); CCastleBuildings(const CGTownInstance * town);
~CCastleBuildings(); ~CCastleBuildings();
void enterDwelling(int level); void enterDwelling(int level);
@ -157,18 +165,17 @@ public:
class CCreaInfo : public CIntObject class CCreaInfo : public CIntObject
{ {
const CGTownInstance * town; const CGTownInstance * town;
const CCreature *creature; const CCreature * creature;
int level; int level;
bool showAvailable; bool showAvailable;
CAnimImage *picture; std::shared_ptr<CAnimImage> picture;
CLabel * label; std::shared_ptr<CLabel> label;
int AddToString(std::string from, std::string & to, int numb);
std::string genGrowthText(); std::string genGrowthText();
public: public:
CCreaInfo(Point position, const CGTownInstance *Town, int Level, bool compact=false, bool showAvailable=false); CCreaInfo(Point position, const CGTownInstance * Town, int Level, bool compact=false, bool showAvailable=false);
void update(); void update();
void hover(bool on) override; void hover(bool on) override;
@ -179,48 +186,53 @@ public:
/// Town hall and fort icons for town screen /// Town hall and fort icons for town screen
class CTownInfo : public CIntObject class CTownInfo : public CIntObject
{ {
const CGTownInstance *town; const CGTownInstance * town;
const CBuilding *building; const CBuilding * building;
public: public:
CAnimImage * picture; std::shared_ptr<CAnimImage> picture;
//if (townHall) hall-capital else fort - castle //if (townHall) hall-capital else fort - castle
CTownInfo(int posX, int posY, const CGTownInstance* town, bool townHall); CTownInfo(int posX, int posY, const CGTownInstance * town, bool townHall);
void hover(bool on) override; void hover(bool on) override;
void clickRight(tribool down, bool previousState) override; void clickRight(tribool down, bool previousState) override;
}; };
/// Class which manages the castle window /// Class which manages the castle window
class CCastleInterface : public CWindowObject, public CWindowWithGarrison class CCastleInterface : public CWindowObject, public CGarrisonHolder
{ {
CLabel *title; std::shared_ptr<CLabel> title;
CLabel *income; std::shared_ptr<CLabel> income;
CAnimImage *icon; std::shared_ptr<CAnimImage> icon;
CPicture * panel; std::shared_ptr<CPicture> panel;
CResDataBar *resdatabar; std::shared_ptr<CResDataBar> resdatabar;
CGStatusBar * statusbar; std::shared_ptr<CGStatusBar> statusbar;
CTownInfo *hall, *fort; std::shared_ptr<CTownInfo> hall;
std::shared_ptr<CTownInfo> fort;
CButton *exit; std::shared_ptr<CButton> exit;
CButton *split; std::shared_ptr<CButton> split;
CButton * fastArmyPurhase; std::shared_ptr<CButton> fastArmyPurhase;
std::vector<CCreaInfo*> creainfo;//small icons of creatures (bottom-left corner); std::vector<std::shared_ptr<CCreaInfo>> creainfo;//small icons of creatures (bottom-left corner);
public: public:
CTownList * townlist; std::shared_ptr<CTownList> townlist;
//TODO: move to private //TODO: move to private
const CGTownInstance * town; const CGTownInstance * town;
HeroSlots *heroes; std::shared_ptr<HeroSlots> heroes;
CCastleBuildings *builds; std::shared_ptr<CCastleBuildings> builds;
std::shared_ptr<CGarrisonInt> garr;
//from - previously selected castle (if any) //from - previously selected castle (if any)
CCastleInterface(const CGTownInstance * Town, const CGTownInstance * from = nullptr); CCastleInterface(const CGTownInstance * Town, const CGTownInstance * from = nullptr);
~CCastleInterface(); ~CCastleInterface();
virtual void updateGarrisons() override;
void castleTeleport(int where); void castleTeleport(int where);
void townChange(); void townChange();
void keyPressed(const SDL_KeyboardEvent & key) override; void keyPressed(const SDL_KeyboardEvent & key) override;
@ -233,13 +245,17 @@ public:
/// Hall window where you can build things /// Hall window where you can build things
class CHallInterface : public CWindowObject class CHallInterface : public CWindowObject
{ {
/// Building box from town hall (building icon + subtitle)
class CBuildingBox : public CIntObject class CBuildingBox : public CIntObject
{ {
const CGTownInstance * town; const CGTownInstance * town;
const CBuilding * building; const CBuilding * building;
ui32 state;//Buildings::EBuildStructure enum ui32 state;//Buildings::EBuildStructure enum
std::shared_ptr<CAnimImage> header;
std::shared_ptr<CAnimImage> icon;
std::shared_ptr<CAnimImage> mark;
std::shared_ptr<CLabel> name;
public: public:
CBuildingBox(int x, int y, const CGTownInstance * Town, const CBuilding * Building); CBuildingBox(int x, int y, const CGTownInstance * Town, const CBuilding * Building);
void hover(bool on) override; void hover(bool on) override;
@ -248,11 +264,11 @@ class CHallInterface : public CWindowObject
}; };
const CGTownInstance * town; const CGTownInstance * town;
std::vector< std::vector<CBuildingBox*> >boxes; std::vector<std::vector<std::shared_ptr<CBuildingBox>>> boxes;
CLabel *title; std::shared_ptr<CLabel> title;
CGStatusBar *statusBar; std::shared_ptr<CMinorResDataBar> resdatabar;
CMinorResDataBar * resdatabar; std::shared_ptr<CGStatusBar> statusbar;
CButton *exit; std::shared_ptr<CButton> exit;
public: public:
CHallInterface(const CGTownInstance * Town); CHallInterface(const CGTownInstance * Town);
@ -261,8 +277,18 @@ public:
/// Window where you can decide to buy a building or not /// Window where you can decide to buy a building or not
class CBuildWindow: public CWindowObject class CBuildWindow: public CWindowObject
{ {
const CGTownInstance *town; const CGTownInstance * town;
const CBuilding *building; const CBuilding * building;
std::shared_ptr<CAnimImage> icon;
std::shared_ptr<CGStatusBar> statusbar;
std::shared_ptr<CLabel> name;
std::shared_ptr<CTextBox> description;
std::shared_ptr<CTextBox> stateText;
std::shared_ptr<CComponentBox> cost;
std::shared_ptr<CButton> buy;
std::shared_ptr<CButton> cancel;
std::string getTextForState(int state); std::string getTextForState(int state);
void buyFunc(); void buyFunc();
@ -274,8 +300,8 @@ public:
class LabeledValue : public CIntObject class LabeledValue : public CIntObject
{ {
std::string hoverText; std::string hoverText;
CLabel *name; std::shared_ptr<CLabel> name;
CLabel *value; std::shared_ptr<CLabel> value;
void init(std::string name, std::string descr, int min, int max); void init(std::string name, std::string descr, int min, int max);
public: public:
@ -289,14 +315,16 @@ class CFortScreen : public CWindowObject
{ {
class RecruitArea : public CIntObject class RecruitArea : public CIntObject
{ {
const CGTownInstance *town; const CGTownInstance * town;
int level; int level;
std::string hoverText; std::string hoverText;
CLabel * availableCount; std::shared_ptr<CLabel> availableCount;
std::vector<LabeledValue*> values; std::vector<std::shared_ptr<LabeledValue>> values;
CPicture *icons; std::shared_ptr<CPicture> icons;
std::shared_ptr<CAnimImage> buildingIcon;
std::shared_ptr<CLabel> buildingName;
const CCreature * getMyCreature(); const CCreature * getMyCreature();
const CBuilding * getMyBuilding(); const CBuilding * getMyBuilding();
@ -308,13 +336,13 @@ class CFortScreen : public CWindowObject
void clickLeft(tribool down, bool previousState) override; void clickLeft(tribool down, bool previousState) override;
void clickRight(tribool down, bool previousState) override; void clickRight(tribool down, bool previousState) override;
}; };
CLabel *title; std::shared_ptr<CLabel> title;
std::vector<RecruitArea*> recAreas; std::vector<std::shared_ptr<RecruitArea>> recAreas;
CMinorResDataBar * resdatabar; std::shared_ptr<CMinorResDataBar> resdatabar;
CGStatusBar *statusBar; std::shared_ptr<CGStatusBar> statusbar;
CButton *exit; std::shared_ptr<CButton> exit;
std::string getBgName(const CGTownInstance *town); std::string getBgName(const CGTownInstance * town);
public: public:
CFortScreen(const CGTownInstance * town); CFortScreen(const CGTownInstance * town);
@ -327,8 +355,8 @@ class CMageGuildScreen : public CWindowObject
{ {
class Scroll : public CIntObject class Scroll : public CIntObject
{ {
const CSpell *spell; const CSpell * spell;
CAnimImage *image; std::shared_ptr<CAnimImage> image;
public: public:
Scroll(Point position, const CSpell *Spell); Scroll(Point position, const CSpell *Spell);
@ -336,11 +364,13 @@ class CMageGuildScreen : public CWindowObject
void clickRight(tribool down, bool previousState) override; void clickRight(tribool down, bool previousState) override;
void hover(bool on) override; void hover(bool on) override;
}; };
CPicture *window; std::shared_ptr<CPicture> window;
CButton *exit; std::shared_ptr<CButton> exit;
std::vector<Scroll *> spells; std::vector<std::shared_ptr<Scroll>> spells;
CMinorResDataBar * resdatabar; std::vector<std::shared_ptr<CAnimImage>> emptyScrolls;
CGStatusBar *statusBar;
std::shared_ptr<CMinorResDataBar> resdatabar;
std::shared_ptr<CGStatusBar> statusbar;
public: public:
CMageGuildScreen(CCastleInterface * owner,std::string image); CMageGuildScreen(CCastleInterface * owner,std::string image);
@ -349,13 +379,15 @@ public:
/// The blacksmith window where you can buy available in town war machine /// The blacksmith window where you can buy available in town war machine
class CBlacksmithDialog : public CWindowObject class CBlacksmithDialog : public CWindowObject
{ {
CButton *buy, *cancel; std::shared_ptr<CButton> buy;
CPicture *animBG; std::shared_ptr<CButton> cancel;
CCreatureAnim * anim; std::shared_ptr<CPicture> animBG;
CLabel * title; std::shared_ptr<CCreatureAnim> anim;
CLabel * costText; std::shared_ptr<CLabel> title;
CLabel * costValue; std::shared_ptr<CAnimImage> costIcon;
CGStatusBar *statusBar; std::shared_ptr<CLabel> costText;
std::shared_ptr<CLabel> costValue;
std::shared_ptr<CGStatusBar> statusbar;
public: public:
CBlacksmithDialog(bool possible, CreatureID creMachineID, ArtifactID aid, ObjectInstanceID hid); CBlacksmithDialog(bool possible, CreatureID creMachineID, ArtifactID aid, ObjectInstanceID hid);

File diff suppressed because it is too large Load Diff

View File

@ -13,26 +13,29 @@
#include "../widgets/MiscWidgets.h" #include "../widgets/MiscWidgets.h"
#include "CWindowObject.h" #include "CWindowObject.h"
struct StackWindowInfo; class UnitView;
class CCommanderInstance; class CCommanderInstance;
class CStackInstance; class CStackInstance;
class CStack; class CStack;
struct UpgradeInfo; struct UpgradeInfo;
class CTabbedInt; class CTabbedInt;
class CButton; class CButton;
class CMultiLineLabel;
class CListBox;
class CCommanderArtPlace;
class CCommanderSkillIcon : public LRClickableAreaWText //TODO: maybe bring commander skill button initialization logic inside? class CCommanderSkillIcon : public LRClickableAreaWText //TODO: maybe bring commander skill button initialization logic inside?
{ {
CIntObject * object; // passive object that will be used to determine clickable area std::shared_ptr<CIntObject> object; // passive object that will be used to determine clickable area
public: public:
CCommanderSkillIcon(CIntObject * object, std::function<void()> callback); CCommanderSkillIcon(std::shared_ptr<CIntObject> object_, std::function<void()> callback);
std::function<void()> callback; std::function<void()> callback;
void clickLeft(tribool down, bool previousState) override; void clickLeft(tribool down, bool previousState) override;
void clickRight(tribool down, bool previousState) override; void clickRight(tribool down, bool previousState) override;
void setObject(CIntObject * object); void setObject(std::shared_ptr<CIntObject> object);
}; };
class CStackWindow : public CWindowObject class CStackWindow : public CWindowObject
@ -46,48 +49,123 @@ class CStackWindow : public CWindowObject
class CWindowSection : public CIntObject class CWindowSection : public CIntObject
{ {
CStackWindow *parent; private:
std::shared_ptr<CPicture> background;
void createBackground(std::string path); protected:
void createBonusItem(size_t index, Point position); CStackWindow * parent;
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: public:
void createStackInfo(bool showExp, bool showArt); CWindowSection(CStackWindow * parent, std::string backgroundPath, int yOffset);
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);
}; };
std::unique_ptr<CAnimImage> stackArtifactIcon; class ActiveSpellsSection : public CWindowSection
std::unique_ptr<LRClickableAreaWTextComp> stackArtifactHelp; {
std::unique_ptr<CButton> stackArtifactButton; std::vector<std::shared_ptr<CAnimImage>> spellIcons;
CAnimImage *expRankIcon; std::vector<std::shared_ptr<LRClickableAreaWText>> clickableAreas;
LRClickableAreaWText *expArea; public:
CLabel *expLabel; ActiveSpellsSection(CStackWindow * owner, int yOffset);
};
std::unique_ptr<StackWindowInfo> info; class BonusLineSection : public CWindowSection
{
std::array<std::shared_ptr<CPicture>, 2> icon;
std::array<std::shared_ptr<CLabel>, 2> name;
std::array<std::shared_ptr<CMultiLineLabel>, 2> description;
public:
BonusLineSection(CStackWindow * owner, size_t lineIndex);
};
class BonusesSection : public CWindowSection
{
std::shared_ptr<CListBox> lines;
public:
BonusesSection(CStackWindow * owner, int yOffset, boost::optional<size_t> preferredSize = boost::optional<size_t>());
};
class ButtonsSection : public CWindowSection
{
std::shared_ptr<CButton> dismiss;
std::array<std::shared_ptr<CButton>, 3> upgrade;// no more than 3 buttons - space limit
std::shared_ptr<CButton> exit;
public:
ButtonsSection(CStackWindow * owner, int yOffset);
};
class CommanderMainSection : public CWindowSection
{
std::vector<std::shared_ptr<CCommanderSkillIcon>> skillIcons;
std::vector<std::shared_ptr<CCommanderArtPlace>> artifacts;
std::shared_ptr<CPicture> abilitiesBackground;
std::shared_ptr<CListBox> abilities;
std::shared_ptr<CButton> leftBtn;
std::shared_ptr<CButton> rightBtn;
public:
CommanderMainSection(CStackWindow * owner, int yOffset);
};
class MainSection : public CWindowSection
{
enum class EStat : size_t
{
ATTACK,
DEFENCE,
SHOTS,
DAMAGE,
HEALTH,
HEALTH_LEFT,
SPEED,
MANA,
AFTER_LAST
};
std::shared_ptr<CCreaturePic> animation;
std::shared_ptr<CLabel> name;
std::shared_ptr<CPicture> icons;
std::shared_ptr<MoraleLuckBox> morale;
std::shared_ptr<MoraleLuckBox> luck;
std::vector<std::shared_ptr<CLabel>> stats;
std::shared_ptr<CAnimImage> expRankIcon;
std::shared_ptr<LRClickableAreaWText> expArea;
std::shared_ptr<CLabel> expLabel;
void addStatLabel(EStat index, int64_t value1, int64_t value2);
void addStatLabel(EStat index, int64_t value);
static std::string getBackgroundName(bool showExp, bool showArt);
std::array<std::string, 8> statNames;
std::array<std::string, 8> statFormats;
public:
MainSection(CStackWindow * owner, int yOffset, bool showExp, bool showArt);
};
std::shared_ptr<CAnimImage> stackArtifactIcon;
std::shared_ptr<LRClickableAreaWTextComp> stackArtifactHelp;
std::shared_ptr<CButton> stackArtifactButton;
std::shared_ptr<UnitView> info;
std::vector<BonusInfo> activeBonuses; std::vector<BonusInfo> activeBonuses;
size_t activeTab; size_t activeTab;
CTabbedInt *commanderTab; std::shared_ptr<CTabbedInt> commanderTab;
std::map<int, CButton *> switchButtons; std::map<size_t, std::shared_ptr<CButton>> switchButtons;
void setSelection(si32 newSkill, CCommanderSkillIcon * newIcon); std::shared_ptr<CWindowSection> mainSection;
CCommanderSkillIcon * selectedIcon; std::shared_ptr<CWindowSection> activeSpellsSection;
std::shared_ptr<CWindowSection> commanderMainSection;
std::shared_ptr<CWindowSection> commanderBonusesSection;
std::shared_ptr<CWindowSection> bonusesSection;
std::shared_ptr<CWindowSection> buttonsSection;
std::shared_ptr<CCommanderSkillIcon> selectedIcon;
si32 selectedSkill; si32 selectedSkill;
CIntObject * createBonusEntry(size_t index); void setSelection(si32 newSkill, std::shared_ptr<CCommanderSkillIcon> newIcon);
CIntObject * switchTab(size_t index); std::shared_ptr<CIntObject> switchTab(size_t index);
void removeStackArtifact(ArtifactPosition pos); void removeStackArtifact(ArtifactPosition pos);
@ -98,8 +176,6 @@ class CStackWindow : public CWindowObject
std::string generateStackExpDescription(); std::string generateStackExpDescription();
CIntObject * createSkillEntry(int index);
public: public:
// for battles // for battles
CStackWindow(const CStack * stack, bool popup); CStackWindow(const CStack * stack, bool popup);

View File

@ -40,17 +40,15 @@
#include "../mapHandler.h" #include "../mapHandler.h"
const TBonusListPtr CHeroWithMaybePickedArtifact::getAllBonuses(const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root, const std::string & cachingStr) const const TBonusListPtr CHeroWithMaybePickedArtifact::getAllBonuses(const CSelector & selector, const CSelector & limit, const CBonusSystemNode * root, const std::string & cachingStr) const
{ {
TBonusListPtr out(new BonusList()); TBonusListPtr out(new BonusList());
TBonusListPtr heroBonuses = hero->getAllBonuses(selector, limit, hero); TBonusListPtr heroBonuses = hero->getAllBonuses(selector, limit, hero, cachingStr);
TBonusListPtr bonusesFromPickedUpArtifact; TBonusListPtr bonusesFromPickedUpArtifact;
std::shared_ptr<CArtifactsOfHero::SCommonPart> cp = cww->artSets.size() ? cww->artSets.front()->commonInfo : nullptr; std::shared_ptr<CArtifactsOfHero::SCommonPart> cp = cww->getCommonPart();
if(cp && cp->src.art && cp->src.valid() && cp->src.AOH && cp->src.AOH->getHero() == hero) if(cp && cp->src.art && cp->src.valid() && cp->src.AOH && cp->src.AOH->getHero() == hero)
{
bonusesFromPickedUpArtifact = cp->src.art->getAllBonuses(selector, limit, hero); bonusesFromPickedUpArtifact = cp->src.art->getAllBonuses(selector, limit, hero);
}
else else
bonusesFromPickedUpArtifact = TBonusListPtr(new BonusList()); bonusesFromPickedUpArtifact = TBonusListPtr(new BonusList());
@ -66,8 +64,8 @@ int64_t CHeroWithMaybePickedArtifact::getTreeVersion() const
return hero->getTreeVersion(); //this assumes that hero and artifact belongs to main bonus tree return hero->getTreeVersion(); //this assumes that hero and artifact belongs to main bonus tree
} }
CHeroWithMaybePickedArtifact::CHeroWithMaybePickedArtifact(CWindowWithArtifacts *Cww, const CGHeroInstance *Hero) CHeroWithMaybePickedArtifact::CHeroWithMaybePickedArtifact(CWindowWithArtifacts * Cww, const CGHeroInstance * Hero)
: hero(Hero), cww(Cww) : hero(Hero), cww(Cww)
{ {
} }
@ -75,114 +73,128 @@ void CHeroSwitcher::clickLeft(tribool down, bool previousState)
{ {
if(!down) if(!down)
{ {
//TODO: do not recreate window
#if 0
owner->update(hero, true);
#else
const CGHeroInstance * buf = hero; const CGHeroInstance * buf = hero;
GH.popIntTotally(parent); GH.popIntTotally(parent);
GH.pushInt(new CHeroWindow(buf)); GH.pushInt(new CHeroWindow(buf));
#endif // 0
} }
} }
CHeroSwitcher::CHeroSwitcher(Point _pos, const CGHeroInstance * _hero): CHeroSwitcher::CHeroSwitcher(CHeroWindow * owner_, Point pos_, const CGHeroInstance * hero_)
hero(_hero) : CIntObject(LCLICK),
owner(owner_),
hero(hero_)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
pos += _pos; pos += pos_;
addUsedEvents(LCLICK);
image = new CAnimImage("PortraitsSmall", hero->portrait); image = std::make_shared<CAnimImage>("PortraitsSmall", hero->portrait);
pos.w = image->pos.w; pos.w = image->pos.w;
pos.h = image->pos.h; pos.h = image->pos.h;
} }
CHeroWindow::CHeroWindow(const CGHeroInstance *hero): CHeroWindow::CHeroWindow(const CGHeroInstance * hero)
CWindowObject(PLAYER_COLORED, "HeroScr4"), : CWindowObject(PLAYER_COLORED, "HeroScr4"),
heroWArt(this, hero) heroWArt(this, hero)
{ {
auto & heroscrn = CGI->generaltexth->heroscrn; auto & heroscrn = CGI->generaltexth->heroscrn;
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
garr = nullptr;
tacticsButton = nullptr;
curHero = hero; curHero = hero;
listSelection = nullptr;
new CAnimImage("CREST58", LOCPLINT->playerID.getNum(), 0, 606, 8); banner = std::make_shared<CAnimImage>("CREST58", LOCPLINT->playerID.getNum(), 0, 606, 8);
name = std::make_shared<CLabel>(190, 38, EFonts::FONT_BIG, EAlignment::CENTER, Colors::YELLOW);
title = std::make_shared<CLabel>(190, 65, EFonts::FONT_MEDIUM, EAlignment::CENTER, Colors::WHITE);
//artifs = new CArtifactsOfHero(pos.topLeft(), true); statusBar = std::make_shared<CGStatusBar>(7, 559, "ADROLLVR.bmp", 660);
ourBar = new CGStatusBar(7, 559, "ADROLLVR.bmp", 660); // new CStatusBar(pos.x+72, pos.y+567, "ADROLLVR.bmp", 660);
quitButton = new CButton(Point(609, 516), "hsbtns.def", CButton::tooltip(heroscrn[17]), [&](){ close(); }, SDLK_RETURN); quitButton = std::make_shared<CButton>(Point(609, 516), "hsbtns.def", CButton::tooltip(heroscrn[17]), [=](){ close(); }, SDLK_RETURN);
quitButton->assignedKeys.insert(SDLK_ESCAPE); quitButton->assignedKeys.insert(SDLK_ESCAPE);
dismissButton = new CButton(Point(454, 429), "hsbtns2.def", CButton::tooltip(heroscrn[28]), [&](){ dismissCurrent(); }, SDLK_d);
questlogButton = new CButton(Point(314, 429), "hsbtns4.def", CButton::tooltip(heroscrn[0]), [=](){ LOCPLINT->showQuestLog(); }, SDLK_q);
formations = new CToggleGroup(0); dismissLabel = std::make_shared<CTextBox>(CGI->generaltexth->jktexts[8], Rect(370, 430, 65, 35), 0, FONT_SMALL, TOPLEFT, Colors::WHITE);
formations->addToggle(0, new CToggleButton(Point(481, 483), "hsbtns6.def", std::make_pair(heroscrn[23], heroscrn[29]), 0, SDLK_t)); dismissButton = std::make_shared<CButton>(Point(454, 429), "hsbtns2.def", CButton::tooltip(heroscrn[28]), [=](){ dismissCurrent(); }, SDLK_d);
formations->addToggle(1, new CToggleButton(Point(481, 519), "hsbtns7.def", std::make_pair(heroscrn[24], heroscrn[30]), 0, SDLK_l));
if (hero->commander) questlogLabel = std::make_shared<CTextBox>(CGI->generaltexth->jktexts[9], Rect(510, 430, 65, 35), 0, FONT_SMALL, TOPLEFT, Colors::WHITE);
questlogButton = std::make_shared<CButton>(Point(314, 429), "hsbtns4.def", CButton::tooltip(heroscrn[0]), [=](){ LOCPLINT->showQuestLog(); }, SDLK_q);
formations = std::make_shared<CToggleGroup>(0);
formations->addToggle(0, std::make_shared<CToggleButton>(Point(481, 483), "hsbtns6.def", std::make_pair(heroscrn[23], heroscrn[29]), 0, SDLK_t));
formations->addToggle(1, std::make_shared<CToggleButton>(Point(481, 519), "hsbtns7.def", std::make_pair(heroscrn[24], heroscrn[30]), 0, SDLK_l));
if(hero->commander)
{ {
auto texts = CGI->generaltexth->localizedTexts["heroWindow"]["openCommander"]; auto texts = CGI->generaltexth->localizedTexts["heroWindow"]["openCommander"];
commanderButton = new CButton (Point(317, 18), "buttons/commander", CButton::tooltip(texts), [&](){ commanderWindow(); }, SDLK_c); commanderButton = std::make_shared<CButton>(Point(317, 18), "buttons/commander", CButton::tooltip(texts), [&](){ commanderWindow(); }, SDLK_c);
} }
//right list of heroes //right list of heroes
for(int i=0; i < std::min(LOCPLINT->cb->howManyHeroes(false), 8); i++) for(int i=0; i < std::min(LOCPLINT->cb->howManyHeroes(false), 8); i++)
heroList.push_back(new CHeroSwitcher(Point(612, 87 + i * 54), LOCPLINT->cb->getHeroBySerial(i, false))); heroList.push_back(std::make_shared<CHeroSwitcher>(this, Point(612, 87 + i * 54), LOCPLINT->cb->getHeroBySerial(i, false)));
//areas //areas
portraitArea = new LRClickableAreaWText(Rect(18, 18, 58, 64)); portraitArea = std::make_shared<LRClickableAreaWText>(Rect(18, 18, 58, 64));
portraitImage = new CAnimImage("PortraitsLarge", 0, 0, 19, 19); portraitImage = std::make_shared<CAnimImage>("PortraitsLarge", 0, 0, 19, 19);
for(int v=0; v<GameConstants::PRIMARY_SKILLS; ++v) for(int v = 0; v < GameConstants::PRIMARY_SKILLS; ++v)
{ {
auto area = new LRClickableAreaWTextComp(Rect(30 + 70*v, 109, 42, 64), CComponent::primskill); auto area = std::make_shared<LRClickableAreaWTextComp>(Rect(30 + 70 * v, 109, 42, 64), CComponent::primskill);
area->text = CGI->generaltexth->arraytxt[2+v]; area->text = CGI->generaltexth->arraytxt[2+v];
area->type = v; area->type = v;
area->hoverText = boost::str(boost::format(CGI->generaltexth->heroscrn[1]) % CGI->generaltexth->primarySkillNames[v]); area->hoverText = boost::str(boost::format(CGI->generaltexth->heroscrn[1]) % CGI->generaltexth->primarySkillNames[v]);
primSkillAreas.push_back(area); primSkillAreas.push_back(area);
auto value = std::make_shared<CLabel>(53 + 70 * v, 166, FONT_SMALL, CENTER);
primSkillValues.push_back(value);
} }
specImage = new CAnimImage("UN44", 0, 0, 18, 180); auto primSkills = std::make_shared<CAnimation>("PSKIL42");
primSkills->preload();
primSkillImages.push_back(std::make_shared<CAnimImage>(primSkills, 0, 0, 32, 111));
primSkillImages.push_back(std::make_shared<CAnimImage>(primSkills, 1, 0, 102, 111));
primSkillImages.push_back(std::make_shared<CAnimImage>(primSkills, 2, 0, 172, 111));
primSkillImages.push_back(std::make_shared<CAnimImage>(primSkills, 3, 0, 162, 230));
primSkillImages.push_back(std::make_shared<CAnimImage>(primSkills, 4, 0, 20, 230));
primSkillImages.push_back(std::make_shared<CAnimImage>(primSkills, 5, 0, 242, 111));
specArea = new LRClickableAreaWText(Rect(18, 180, 136, 42), CGI->generaltexth->heroscrn[27]); specImage = std::make_shared<CAnimImage>("UN44", 0, 0, 18, 180);
expArea = new LRClickableAreaWText(Rect(18, 228, 136, 42), CGI->generaltexth->heroscrn[9]); specArea = std::make_shared<LRClickableAreaWText>(Rect(18, 180, 136, 42), CGI->generaltexth->heroscrn[27]);
morale = new MoraleLuckBox(true, Rect(175,179,53,45)); specName = std::make_shared<CLabel>(69, 205);
luck = new MoraleLuckBox(false, Rect(233,179,53,45));
spellPointsArea = new LRClickableAreaWText(Rect(162,228, 136, 42), CGI->generaltexth->heroscrn[22]); expArea = std::make_shared<LRClickableAreaWText>(Rect(18, 228, 136, 42), CGI->generaltexth->heroscrn[9]);
morale = std::make_shared<MoraleLuckBox>(true, Rect(175, 179, 53, 45));
luck = std::make_shared<MoraleLuckBox>(false, Rect(233, 179, 53, 45));
spellPointsArea = std::make_shared<LRClickableAreaWText>(Rect(162,228, 136, 42), CGI->generaltexth->heroscrn[22]);
expValue = std::make_shared<CLabel>(68, 252);
manaValue = std::make_shared<CLabel>(211, 252);
auto secSkills = std::make_shared<CAnimation>("SECSKILL"); auto secSkills = std::make_shared<CAnimation>("SECSKILL");
for(int i = 0; i < std::min<size_t>(hero->secSkills.size(), 8u); ++i) for(int i = 0; i < std::min<size_t>(hero->secSkills.size(), 8u); ++i)
{ {
Rect r = Rect(i%2 == 0 ? 18 : 162, 276 + 48 * (i/2), 136, 42); Rect r = Rect(i%2 == 0 ? 18 : 162, 276 + 48 * (i/2), 136, 42);
secSkillAreas.push_back(new LRClickableAreaWTextComp(r, CComponent::secskill)); secSkillAreas.push_back(std::make_shared<LRClickableAreaWTextComp>(r, CComponent::secskill));
secSkillImages.push_back(new CAnimImage(secSkills, 0, 0, r.x, r.y)); secSkillImages.push_back(std::make_shared<CAnimImage>(secSkills, 0, 0, r.x, r.y));
int x = (i % 2) ? 212 : 68;
int y = 280 + 48 * (i/2);
secSkillValues.push_back(std::make_shared<CLabel>(x, y, FONT_SMALL, TOPLEFT));
secSkillNames.push_back(std::make_shared<CLabel>(x, y+20, FONT_SMALL, TOPLEFT));
} }
//dismiss / quest log
new CTextBox(CGI->generaltexth->jktexts[8], Rect(370, 430, 65, 35), 0, FONT_SMALL, TOPLEFT, Colors::WHITE);
new CTextBox(CGI->generaltexth->jktexts[9], Rect(510, 430, 65, 35), 0, FONT_SMALL, TOPLEFT, Colors::WHITE);
//////////////////////////////////////////////////////////////////////////???????????????
//primary skills & exp and mana
auto primSkills = std::make_shared<CAnimation>("PSKIL42");
primSkills->preload();
new CAnimImage(primSkills, 0, 0, 32, 111);
new CAnimImage(primSkills, 1, 0, 102, 111);
new CAnimImage(primSkills, 2, 0, 172, 111);
new CAnimImage(primSkills, 3, 0, 162, 230);
new CAnimImage(primSkills, 4, 0, 20, 230);
new CAnimImage(primSkills, 5, 0, 242, 111);
// various texts // various texts
new CLabel( 52, 99, FONT_SMALL, CENTER, Colors::YELLOW, CGI->generaltexth->jktexts[1]); labels.push_back(std::make_shared<CLabel>(52, 99, FONT_SMALL, CENTER, Colors::YELLOW, CGI->generaltexth->jktexts[1]));
new CLabel(123, 99, FONT_SMALL, CENTER, Colors::YELLOW, CGI->generaltexth->jktexts[2]); labels.push_back(std::make_shared<CLabel>(123, 99, FONT_SMALL, CENTER, Colors::YELLOW, CGI->generaltexth->jktexts[2]));
new CLabel(193, 99, FONT_SMALL, CENTER, Colors::YELLOW, CGI->generaltexth->jktexts[3]); labels.push_back(std::make_shared<CLabel>(193, 99, FONT_SMALL, CENTER, Colors::YELLOW, CGI->generaltexth->jktexts[3]));
new CLabel(262, 99, FONT_SMALL, CENTER, Colors::YELLOW, CGI->generaltexth->jktexts[4]); labels.push_back(std::make_shared<CLabel>(262, 99, FONT_SMALL, CENTER, Colors::YELLOW, CGI->generaltexth->jktexts[4]));
new CLabel( 69, 183, FONT_SMALL, TOPLEFT, Colors::YELLOW, CGI->generaltexth->jktexts[5]); labels.push_back(std::make_shared<CLabel>(69, 183, FONT_SMALL, TOPLEFT, Colors::YELLOW, CGI->generaltexth->jktexts[5]));
new CLabel( 69, 232, FONT_SMALL, TOPLEFT, Colors::YELLOW, CGI->generaltexth->jktexts[6]); labels.push_back(std::make_shared<CLabel>(69, 232, FONT_SMALL, TOPLEFT, Colors::YELLOW, CGI->generaltexth->jktexts[6]));
new CLabel(213, 232, FONT_SMALL, TOPLEFT, Colors::YELLOW, CGI->generaltexth->jktexts[7]); labels.push_back(std::make_shared<CLabel>(213, 232, FONT_SMALL, TOPLEFT, Colors::YELLOW, CGI->generaltexth->jktexts[7]));
update(hero); update(hero);
} }
@ -199,11 +211,14 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded)
assert(hero == curHero); assert(hero == curHero);
name->setText(curHero->name);
title->setText((boost::format(CGI->generaltexth->allTexts[342]) % curHero->level % curHero->type->heroClass->name).str());
specArea->text = curHero->type->specDescr; specArea->text = curHero->type->specDescr;
specImage->setFrame(curHero->type->imageIndex); specImage->setFrame(curHero->type->imageIndex);
specName->setText(curHero->type->specName);
delete tacticsButton; tacticsButton = std::make_shared<CToggleButton>(Point(539, 483), "hsbtns8.def", std::make_pair(heroscrn[26], heroscrn[31]), 0, SDLK_b);
tacticsButton = new CToggleButton(Point(539, 483), "hsbtns8.def", std::make_pair(heroscrn[26], heroscrn[31]), 0, SDLK_b);
tacticsButton->addHoverText(CButton::HIGHLIGHTED, CGI->generaltexth->heroscrn[25]); tacticsButton->addHoverText(CButton::HIGHLIGHTED, CGI->generaltexth->heroscrn[25]);
dismissButton->addHoverText(CButton::NORMAL, boost::str(boost::format(CGI->generaltexth->heroscrn[16]) % curHero->name % curHero->type->heroClass->name)); dismissButton->addHoverText(CButton::NORMAL, boost::str(boost::format(CGI->generaltexth->heroscrn[16]) % curHero->name % curHero->type->heroClass->name));
@ -212,49 +227,62 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded)
portraitImage->setFrame(curHero->portrait); portraitImage->setFrame(curHero->portrait);
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
if(!garr) if(!garr)
{ {
std::string helpBox = heroscrn[32]; std::string helpBox = heroscrn[32];
boost::algorithm::replace_first(helpBox, "%s", CGI->generaltexth->allTexts[43]); boost::algorithm::replace_first(helpBox, "%s", CGI->generaltexth->allTexts[43]);
garr = new CGarrisonInt(15, 485, 8, Point(), background->bg, Point(15,485), curHero); garr = std::make_shared<CGarrisonInt>(15, 485, 8, Point(), curHero);
auto split = new CButton(Point(539, 519), "hsbtns9.def", CButton::tooltip(CGI->generaltexth->allTexts[256], helpBox), [&](){ garr->splitClick(); }); auto split = std::make_shared<CButton>(Point(539, 519), "hsbtns9.def", CButton::tooltip(CGI->generaltexth->allTexts[256], helpBox), [&](){ garr->splitClick(); });
garr->addSplitBtn(split); garr->addSplitBtn(split);
} }
if(!artSets.size()) if(!arts)
{ {
auto arts = new CArtifactsOfHero(Point(-65, -8), true); arts = std::make_shared<CArtifactsOfHero>(Point(-65, -8), true);
arts->setHero(curHero); arts->setHero(curHero);
artSets.push_back(arts); addSet(arts);
} }
int serial = LOCPLINT->cb->getHeroSerial(curHero, false); int serial = LOCPLINT->cb->getHeroSerial(curHero, false);
vstd::clear_pointer(listSelection); listSelection.reset();
if (serial >= 0) if(serial >= 0)
listSelection = new CPicture("HPSYYY", 612, 33 + serial * 54); listSelection = std::make_shared<CPicture>("HPSYYY", 612, 33 + serial * 54);
} }
//primary skills support //primary skills support
for(size_t g=0; g<primSkillAreas.size(); ++g) for(size_t g=0; g<primSkillAreas.size(); ++g)
{ {
primSkillAreas[g]->bonusValue = heroWArt.getPrimSkillLevel(static_cast<PrimarySkill::PrimarySkill>(g)); primSkillAreas[g]->bonusValue = heroWArt.getPrimSkillLevel(static_cast<PrimarySkill::PrimarySkill>(g));
primSkillValues[g]->setText(boost::lexical_cast<std::string>(primSkillAreas[g]->bonusValue));
} }
//secondary skills support //secondary skills support
for(size_t g=0; g< secSkillAreas.size(); ++g) for(size_t g=0; g< secSkillAreas.size(); ++g)
{ {
int skill = curHero->secSkills[g].first, int skill = curHero->secSkills[g].first;
level = curHero->getSecSkillLevel(SecondarySkill(curHero->secSkills[g].first)); int level = curHero->getSecSkillLevel(SecondarySkill(curHero->secSkills[g].first));
std::string skillName = CGI->skillh->skillName(skill);
std::string skillValue = CGI->generaltexth->levels[level-1];
secSkillAreas[g]->type = skill; secSkillAreas[g]->type = skill;
secSkillAreas[g]->bonusValue = level; secSkillAreas[g]->bonusValue = level;
secSkillAreas[g]->text = CGI->skillh->skillInfo(skill, level); secSkillAreas[g]->text = CGI->skillh->skillInfo(skill, level);
secSkillAreas[g]->hoverText = boost::str(boost::format(heroscrn[21]) % CGI->generaltexth->levels[level-1] % CGI->skillh->skillName(skill)); secSkillAreas[g]->hoverText = boost::str(boost::format(heroscrn[21]) % skillValue % skillName);
secSkillImages[g]->setFrame(skill*3 + level + 2); secSkillImages[g]->setFrame(skill*3 + level + 2);
secSkillNames[g]->setText(skillName);
secSkillValues[g]->setText(skillValue);
} }
std::ostringstream expstr;
expstr << curHero->exp;
expValue->setText(expstr.str());
std::ostringstream manastr;
manastr << curHero->mana << '/' << heroWArt.manaLimit();
manaValue->setText(manastr.str());
//printing experience - original format does not support ui64 //printing experience - original format does not support ui64
expArea->text = CGI->generaltexth->allTexts[2]; expArea->text = CGI->generaltexth->allTexts[2];
boost::replace_first(expArea->text, "%d", boost::lexical_cast<std::string>(curHero->level)); boost::replace_first(expArea->text, "%d", boost::lexical_cast<std::string>(curHero->level));
@ -269,14 +297,16 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded)
//if we have exchange window with this curHero open //if we have exchange window with this curHero open
bool noDismiss=false; bool noDismiss=false;
for(IShowActivatable *isa : GH.listInt) for(IShowActivatable * isa : GH.listInt)
{ {
if(CExchangeWindow * cew = dynamic_cast<CExchangeWindow*>(isa)) if(CExchangeWindow * cew = dynamic_cast<CExchangeWindow*>(isa))
for(int g=0; g < ARRAY_COUNT(cew->heroInst); ++g) {
for(int g=0; g < cew->heroInst.size(); ++g)
if(cew->heroInst[g] == curHero) if(cew->heroInst[g] == curHero)
noDismiss = true; noDismiss = true;
}
if (dynamic_cast<CKingdomInterface*>(isa)) if(dynamic_cast<CKingdomInterface*>(isa))
noDismiss = true; noDismiss = true;
} }
//if player only have one hero and no towns //if player only have one hero and no towns
@ -289,17 +319,19 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded)
dismissButton->block(!!curHero->visitedTown || noDismiss); dismissButton->block(!!curHero->visitedTown || noDismiss);
if(curHero->getSecSkillLevel(SecondarySkill::TACTICS) == 0) if(curHero->getSecSkillLevel(SecondarySkill::TACTICS) == 0)
{
tacticsButton->block(true); tacticsButton->block(true);
}
else else
{ {
tacticsButton->block(false); tacticsButton->block(false);
tacticsButton->addCallback( [&](bool on) {curHero->tacticFormationEnabled = on;}); tacticsButton->addCallback([&](bool on){curHero->tacticFormationEnabled = on;});
} }
formations->resetCallback();
//setting formations //setting formations
formations->setSelected(curHero->formation); formations->setSelected(curHero->formation);
formations->addCallback([&] (int value) { LOCPLINT->cb->setFormation(curHero, value); }); formations->addCallback([=](int value){ LOCPLINT->cb->setFormation(curHero, value);});
morale->set(&heroWArt); morale->set(&heroWArt);
luck->set(&heroWArt); luck->set(&heroWArt);
@ -312,26 +344,25 @@ void CHeroWindow::dismissCurrent()
{ {
CFunctionList<void()> ony = [=](){ close(); }; CFunctionList<void()> ony = [=](){ close(); };
ony += [=](){ LOCPLINT->cb->dismissHero(curHero); }; ony += [=](){ LOCPLINT->cb->dismissHero(curHero); };
LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[22], ony, 0, false); LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[22], ony, nullptr);
} }
void CHeroWindow::commanderWindow() void CHeroWindow::commanderWindow()
{ {
//TODO: allow equipping commander artifacts by drag / drop
//bool artSelected = false; //bool artSelected = false;
const std::shared_ptr<CArtifactsOfHero::SCommonPart> commonInfo = artSets.front()->commonInfo; const std::shared_ptr<CArtifactsOfHero::SCommonPart> commonInfo = getCommonPart();
if (const CArtifactInstance *art = commonInfo->src.art) if(const CArtifactInstance *art = commonInfo->src.art)
{ {
const CGHeroInstance *srcHero = commonInfo->src.AOH->getHero(); const CGHeroInstance *srcHero = commonInfo->src.AOH->getHero();
//artSelected = true; //artSelected = true;
ArtifactPosition freeSlot = art->firstAvailableSlot (curHero->commander); ArtifactPosition freeSlot = art->firstAvailableSlot (curHero->commander);
if (freeSlot < ArtifactPosition::COMMANDER_AFTER_LAST) //we don't want to put it in commander's backpack! if(freeSlot < ArtifactPosition::COMMANDER_AFTER_LAST) //we don't want to put it in commander's backpack!
{ {
ArtifactLocation src (srcHero, commonInfo->src.slotID); ArtifactLocation src(srcHero, commonInfo->src.slotID);
ArtifactLocation dst (curHero->commander.get(), freeSlot); ArtifactLocation dst(curHero->commander.get(), freeSlot);
if (art->canBePutAt(dst, true)) if(art->canBePutAt(dst, true))
{ //equip clicked stack { //equip clicked stack
if(dst.getArt()) if(dst.getArt())
{ {
@ -342,51 +373,13 @@ void CHeroWindow::commanderWindow()
} }
} }
else else
{
GH.pushInt(new CStackWindow(curHero->commander, false)); GH.pushInt(new CStackWindow(curHero->commander, false));
}
} }
void CHeroWindow::updateGarrisons() void CHeroWindow::updateGarrisons()
{ {
CWindowWithGarrison::updateGarrisons(); garr->recreateSlots();
morale->set(&heroWArt); morale->set(&heroWArt);
} }
void CHeroWindow::showAll(SDL_Surface * to)
{
CIntObject::showAll(to);
//printing hero's name
printAtMiddleLoc(curHero->name, 190, 38, FONT_BIG, Colors::YELLOW, to);
//printing hero's level
std::string secondLine= CGI->generaltexth->allTexts[342];
boost::algorithm::replace_first(secondLine,"%d",boost::lexical_cast<std::string>(curHero->level));
boost::algorithm::replace_first(secondLine,"%s",curHero->type->heroClass->name);
printAtMiddleLoc(secondLine, 190, 65, FONT_MEDIUM, Colors::WHITE, to);
//printing primary skills' amounts
for(int m=0; m<4; ++m)
{
std::ostringstream primarySkill;
primarySkill << primSkillAreas[m]->bonusValue;
printAtMiddleLoc(primarySkill.str(), 53 + 70 * m, 166, FONT_SMALL, Colors::WHITE, to);
}
//secondary skills
for(size_t v=0; v<std::min(secSkillAreas.size(), curHero->secSkills.size()); ++v)
{
printAtLoc(CGI->generaltexth->levels[curHero->secSkills[v].second-1], (v%2) ? 212 : 68, 280 + 48 * (v/2), FONT_SMALL, Colors::WHITE, to);
printAtLoc(CGI->skillh->skillName(curHero->secSkills[v].first), (v%2) ? 212 : 68, 300 + 48 * (v/2), FONT_SMALL, Colors::WHITE, to);
}
//printing special ability
printAtLoc(curHero->type->specName, 69, 205, FONT_SMALL, Colors::WHITE, to);
std::ostringstream expstr;
expstr << curHero->exp;
printAtLoc(expstr.str(), 68, 252, FONT_SMALL, Colors::WHITE, to);
std::ostringstream manastr;
manastr << curHero->mana << '/' << heroWArt.manaLimit();
printAtLoc(manastr.str(), 211, 252, FONT_SMALL, Colors::WHITE, to);
}

View File

@ -26,71 +26,95 @@ class MoraleLuckBox;
class CToggleButton; class CToggleButton;
class CToggleGroup; class CToggleGroup;
class CGStatusBar; class CGStatusBar;
class CTextBox;
/// Button which switches hero selection /// Button which switches hero selection
class CHeroSwitcher : public CIntObject class CHeroSwitcher : public CIntObject
{ {
const CGHeroInstance * hero; const CGHeroInstance * hero;
CAnimImage *image; std::shared_ptr<CAnimImage> image;
CHeroWindow * owner;
public: public:
virtual void clickLeft(tribool down, bool previousState) override; void clickLeft(tribool down, bool previousState) override;
CHeroSwitcher(Point pos, const CGHeroInstance * hero); CHeroSwitcher(CHeroWindow * owner_, Point pos_, const CGHeroInstance * hero_);
}; };
//helper class for calculating values of hero bonuses without bonuses from picked up artifact //helper class for calculating values of hero bonuses without bonuses from picked up artifact
class CHeroWithMaybePickedArtifact : public virtual IBonusBearer class CHeroWithMaybePickedArtifact : public virtual IBonusBearer
{ {
public: public:
const CGHeroInstance *hero; const CGHeroInstance * hero;
CWindowWithArtifacts *cww; CWindowWithArtifacts * cww;
CHeroWithMaybePickedArtifact(CWindowWithArtifacts *Cww, const CGHeroInstance *Hero); CHeroWithMaybePickedArtifact(CWindowWithArtifacts * Cww, const CGHeroInstance * Hero);
const TBonusListPtr getAllBonuses(const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root = nullptr, const std::string &cachingStr = "") const override; const TBonusListPtr getAllBonuses(const CSelector & selector, const CSelector & limit, const CBonusSystemNode * root = nullptr, const std::string & cachingStr = "") const override;
int64_t getTreeVersion() const override; int64_t getTreeVersion() const override;
}; };
class CHeroWindow: public CWindowObject, public CWindowWithGarrison, public CWindowWithArtifacts class CHeroWindow : public CWindowObject, public CGarrisonHolder, public CWindowWithArtifacts
{ {
CGStatusBar * ourBar; //heroWindow's statusBar std::shared_ptr<CLabel> name;
std::shared_ptr<CLabel> title;
//buttons std::shared_ptr<CAnimImage> banner;
//CButton * gar4button; //splitting std::shared_ptr<CGStatusBar> statusBar;
std::vector<CHeroSwitcher *> heroList; //list of heroes
CPicture * listSelection; //selection border
//clickable areas std::vector<std::shared_ptr<CHeroSwitcher>> heroList;
LRClickableAreaWText * portraitArea; std::shared_ptr<CPicture> listSelection;
CAnimImage * portraitImage;
std::shared_ptr<LRClickableAreaWText> portraitArea;
std::shared_ptr<CAnimImage> portraitImage;
std::vector<std::shared_ptr<LRClickableAreaWTextComp>> primSkillAreas;
std::vector<std::shared_ptr<CAnimImage>> primSkillImages;
std::vector<std::shared_ptr<CLabel>> primSkillValues;
std::shared_ptr<CLabel> expValue;
std::shared_ptr<LRClickableAreaWText> expArea;
std::shared_ptr<CLabel> manaValue;
std::shared_ptr<LRClickableAreaWText> spellPointsArea;
std::shared_ptr<LRClickableAreaWText> specArea;
std::shared_ptr<CAnimImage> specImage;
std::shared_ptr<CLabel> specName;
std::shared_ptr<MoraleLuckBox> morale;
std::shared_ptr<MoraleLuckBox> luck;
std::vector<std::shared_ptr<LRClickableAreaWTextComp>> secSkillAreas;
std::vector<std::shared_ptr<CAnimImage>> secSkillImages;
std::vector<std::shared_ptr<CLabel>> secSkillNames;
std::vector<std::shared_ptr<CLabel>> secSkillValues;
std::vector<LRClickableAreaWTextComp *> primSkillAreas;
LRClickableAreaWText * expArea;
LRClickableAreaWText * spellPointsArea;
LRClickableAreaWText * specArea;//specialty
CAnimImage *specImage;
MoraleLuckBox * morale, * luck;
std::vector<LRClickableAreaWTextComp *> secSkillAreas;
std::vector<CAnimImage *> secSkillImages;
CHeroWithMaybePickedArtifact heroWArt; CHeroWithMaybePickedArtifact heroWArt;
CButton * quitButton, * dismissButton, * questlogButton, * commanderButton; //general std::shared_ptr<CButton> quitButton;
std::shared_ptr<CTextBox> dismissLabel;
std::shared_ptr<CButton> dismissButton;
std::shared_ptr<CTextBox> questlogLabel;
std::shared_ptr<CButton> questlogButton;
std::shared_ptr<CButton> commanderButton;
CToggleButton *tacticsButton; //garrison / formation handling; std::shared_ptr<CToggleButton> tacticsButton;
CToggleGroup *formations; std::shared_ptr<CToggleGroup> formations;
std::shared_ptr<CGarrisonInt> garr;
std::shared_ptr<CArtifactsOfHero> arts;
std::vector<std::shared_ptr<CLabel>> labels;
public: public:
const CGHeroInstance * curHero; const CGHeroInstance * curHero;
CHeroWindow(const CGHeroInstance *hero); CHeroWindow(const CGHeroInstance * hero);
void update(const CGHeroInstance * hero, bool redrawNeeded = false); //sets main displayed hero void update(const CGHeroInstance * hero, bool redrawNeeded = false); //sets main displayed hero
void showAll(SDL_Surface * to) override;
void dismissCurrent(); //dissmissed currently displayed hero (curHero) void dismissCurrent(); //dissmissed currently displayed hero (curHero)
void commanderWindow(); void commanderWindow();
void switchHero(); //changes displayed hero void switchHero(); //changes displayed hero
virtual void updateGarrisons() override; //updates the morale widget and calls the parent void updateGarrisons() override;
//friends //friends
friend void CHeroArtPlace::clickLeft(tribool down, bool previousState); friend void CHeroArtPlace::clickLeft(tribool down, bool previousState);

View File

@ -34,7 +34,7 @@
#include "../../lib/mapObjects/CGTownInstance.h" #include "../../lib/mapObjects/CGTownInstance.h"
#include "../../lib/mapObjects/MiscObjects.h" #include "../../lib/mapObjects/MiscObjects.h"
InfoBox::InfoBox(Point position, InfoPos Pos, InfoSize Size, IInfoBoxData *Data): InfoBox::InfoBox(Point position, InfoPos Pos, InfoSize Size, std::shared_ptr<IInfoBoxData> Data):
size(Size), size(Size),
infoPos(Pos), infoPos(Pos),
data(Data), data(Data),
@ -45,52 +45,51 @@ InfoBox::InfoBox(Point position, InfoPos Pos, InfoSize Size, IInfoBoxData *Data)
addUsedEvents(LCLICK | RCLICK); addUsedEvents(LCLICK | RCLICK);
EFonts font = (size < SIZE_MEDIUM)? FONT_SMALL: FONT_MEDIUM; EFonts font = (size < SIZE_MEDIUM)? FONT_SMALL: FONT_MEDIUM;
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
pos+=position; pos+=position;
image = new CAnimImage(data->getImageName(size), data->getImageIndex()); image = std::make_shared<CAnimImage>(data->getImageName(size), data->getImageIndex());
pos = image->pos; pos = image->pos;
if (infoPos == POS_CORNER) switch(infoPos)
value = new CLabel(pos.w, pos.h, font, BOTTOMRIGHT, Colors::WHITE, data->getValueText());
if (infoPos == POS_INSIDE)
value = new CLabel(pos.w/2, pos.h-6, font, CENTER, Colors::WHITE, data->getValueText());
if (infoPos == POS_UP_DOWN || infoPos == POS_DOWN)
value = new CLabel(pos.w/2, pos.h+8, font, CENTER, Colors::WHITE, data->getValueText());
if (infoPos == POS_UP_DOWN)
name = new CLabel(pos.w/2, -12, font, CENTER, Colors::WHITE, data->getNameText());
if (infoPos == POS_RIGHT)
{ {
name = new CLabel(pos.w+6, 6, font, TOPLEFT, Colors::WHITE, data->getNameText()); case POS_CORNER:
value = new CLabel(pos.w+6, pos.h-16, font, TOPLEFT, Colors::WHITE, data->getValueText()); value = std::make_shared<CLabel>(pos.w, pos.h, font, BOTTOMRIGHT, Colors::WHITE, data->getValueText());
break;
case POS_INSIDE:
value = std::make_shared<CLabel>(pos.w/2, pos.h-6, font, CENTER, Colors::WHITE, data->getValueText());
break;
case POS_UP_DOWN:
name = std::make_shared<CLabel>(pos.w/2, -12, font, CENTER, Colors::WHITE, data->getNameText());
FALLTHROUGH;
case POS_DOWN:
value = std::make_shared<CLabel>(pos.w/2, pos.h+8, font, CENTER, Colors::WHITE, data->getValueText());
break;
case POS_RIGHT:
name = std::make_shared<CLabel>(pos.w+6, 6, font, TOPLEFT, Colors::WHITE, data->getNameText());
value = std::make_shared<CLabel>(pos.w+6, pos.h-16, font, TOPLEFT, Colors::WHITE, data->getValueText());
break;
} }
pos = image->pos;
if (name) if(name)
pos = pos | name->pos; pos = pos | name->pos;
if (value) if(value)
pos = pos | value->pos; pos = pos | value->pos;
hover = new CHoverableArea(); hover = std::make_shared<CHoverableArea>();
hover->hoverText = data->getHoverText(); hover->hoverText = data->getHoverText();
hover->pos = pos; hover->pos = pos;
} }
InfoBox::~InfoBox() InfoBox::~InfoBox() = default;
{
delete data;
}
void InfoBox::clickRight(tribool down, bool previousState) void InfoBox::clickRight(tribool down, bool previousState)
{ {
if (down) if (down)
{ {
CComponent *comp = nullptr; std::shared_ptr<CComponent> comp;
std::string text; std::string text;
data->prepareMessage(text, &comp); data->prepareMessage(text, comp);
if (comp) if (comp)
CRClickPopup::createAndPush(text, CInfoWindow::TCompsInfo(1, comp)); CRClickPopup::createAndPush(text, CInfoWindow::TCompsInfo(1, comp));
else if (!text.empty()) else if (!text.empty())
@ -102,16 +101,12 @@ void InfoBox::clickLeft(tribool down, bool previousState)
{ {
if((!down) && previousState) if((!down) && previousState)
{ {
CComponent *comp = nullptr; std::shared_ptr<CComponent> comp;
std::string text; std::string text;
data->prepareMessage(text, &comp); data->prepareMessage(text, comp);
std::vector<CComponent*> compVector; if(comp)
if (comp) LOCPLINT->showInfoDialog(text, CInfoWindow::TCompsInfo(1, comp));
{
compVector.push_back(comp);
LOCPLINT->showInfoDialog(text, compVector);
}
} }
} }
@ -123,13 +118,13 @@ void InfoBox::update()
} }
*/ */
IInfoBoxData::IInfoBoxData(InfoType Type): IInfoBoxData::IInfoBoxData(InfoType Type)
type(Type) : type(Type)
{ {
} }
InfoBoxAbstractHeroData::InfoBoxAbstractHeroData(InfoType Type): InfoBoxAbstractHeroData::InfoBoxAbstractHeroData(InfoType Type)
IInfoBoxData(Type) : IInfoBoxData(Type)
{ {
} }
@ -255,40 +250,37 @@ size_t InfoBoxAbstractHeroData::getImageIndex()
} }
} }
bool InfoBoxAbstractHeroData::prepareMessage(std::string &text, CComponent **comp) void InfoBoxAbstractHeroData::prepareMessage(std::string & text, std::shared_ptr<CComponent> & comp)
{ {
comp.reset();
switch (type) switch (type)
{ {
case HERO_SPECIAL: case HERO_SPECIAL:
text = CGI->heroh->heroes[getSubID()]->specDescr; text = CGI->heroh->heroes[getSubID()]->specDescr;
*comp = nullptr; break;
return true;
case HERO_PRIMARY_SKILL: case HERO_PRIMARY_SKILL:
text = CGI->generaltexth->arraytxt[2+getSubID()]; text = CGI->generaltexth->arraytxt[2+getSubID()];
*comp =new CComponent(CComponent::primskill, getSubID(), getValue()); comp = std::make_shared<CComponent>(CComponent::primskill, getSubID(), getValue());
return true; break;
case HERO_MANA: case HERO_MANA:
text = CGI->generaltexth->allTexts[149]; text = CGI->generaltexth->allTexts[149];
*comp = nullptr; break;
return true;
case HERO_EXPERIENCE: case HERO_EXPERIENCE:
text = CGI->generaltexth->allTexts[241]; text = CGI->generaltexth->allTexts[241];
*comp = nullptr; break;
return true;
case HERO_SECONDARY_SKILL: case HERO_SECONDARY_SKILL:
{ {
si64 value = getValue(); si64 value = getValue();
int subID = getSubID(); int subID = getSubID();
if (!value) if(value)
return false; {
text = CGI->skillh->skillInfo(subID, value);
text = CGI->skillh->skillInfo(subID, value); comp = std::make_shared<CComponent>(CComponent::secskill, subID, value);
*comp = new CComponent(CComponent::secskill, subID, value); }
return true; break;
} }
default: default:
assert(0); break;
return false;
} }
} }
@ -388,8 +380,9 @@ std::string InfoBoxHeroData::getValueText()
return InfoBoxAbstractHeroData::getValueText(); return InfoBoxAbstractHeroData::getValueText();
} }
bool InfoBoxHeroData::prepareMessage(std::string &text, CComponent**comp) void InfoBoxHeroData::prepareMessage(std::string & text, std::shared_ptr<CComponent> & comp)
{ {
comp.reset();
switch(type) switch(type)
{ {
case HERO_MANA: case HERO_MANA:
@ -397,19 +390,16 @@ bool InfoBoxHeroData::prepareMessage(std::string &text, CComponent**comp)
boost::replace_first(text, "%s", boost::lexical_cast<std::string>(hero->name)); boost::replace_first(text, "%s", boost::lexical_cast<std::string>(hero->name));
boost::replace_first(text, "%d", boost::lexical_cast<std::string>(hero->mana)); boost::replace_first(text, "%d", boost::lexical_cast<std::string>(hero->mana));
boost::replace_first(text, "%d", boost::lexical_cast<std::string>(hero->manaLimit())); boost::replace_first(text, "%d", boost::lexical_cast<std::string>(hero->manaLimit()));
*comp = nullptr; break;
return true;
case HERO_EXPERIENCE: case HERO_EXPERIENCE:
text = CGI->generaltexth->allTexts[2]; text = CGI->generaltexth->allTexts[2];
boost::replace_first(text, "%d", boost::lexical_cast<std::string>(hero->level)); boost::replace_first(text, "%d", boost::lexical_cast<std::string>(hero->level));
boost::replace_first(text, "%d", boost::lexical_cast<std::string>(CGI->heroh->reqExp(hero->level+1))); boost::replace_first(text, "%d", boost::lexical_cast<std::string>(CGI->heroh->reqExp(hero->level+1)));
boost::replace_first(text, "%d", boost::lexical_cast<std::string>(hero->exp)); boost::replace_first(text, "%d", boost::lexical_cast<std::string>(hero->exp));
*comp = nullptr; break;
return true;
default: default:
return InfoBoxAbstractHeroData::prepareMessage(text, comp); InfoBoxAbstractHeroData::prepareMessage(text, comp);
break;
} }
} }
@ -465,26 +455,25 @@ std::string InfoBoxCustom::getValueText()
return valueText; return valueText;
} }
bool InfoBoxCustom::prepareMessage(std::string &text, CComponent **comp) void InfoBoxCustom::prepareMessage(std::string & text, std::shared_ptr<CComponent> & comp)
{ {
return false;
} }
CKingdomInterface::CKingdomInterface(): CKingdomInterface::CKingdomInterface()
CWindowObject(PLAYER_COLORED | BORDERED, conf.go()->ac.overviewBg) : CWindowObject(PLAYER_COLORED | BORDERED, conf.go()->ac.overviewBg)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
ui32 footerPos = conf.go()->ac.overviewSize * 116; ui32 footerPos = conf.go()->ac.overviewSize * 116;
tabArea = new CTabbedInt(std::bind(&CKingdomInterface::createMainTab, this, _1), CTabbedInt::DestroyFunc(), Point(4,4)); tabArea = std::make_shared<CTabbedInt>(std::bind(&CKingdomInterface::createMainTab, this, _1), Point(4,4));
std::vector<const CGObjectInstance * > ownedObjects = LOCPLINT->cb->getMyObjects(); std::vector<const CGObjectInstance * > ownedObjects = LOCPLINT->cb->getMyObjects();
generateObjectsList(ownedObjects); generateObjectsList(ownedObjects);
generateMinesList(ownedObjects); generateMinesList(ownedObjects);
generateButtons(); generateButtons();
statusbar = new CGStatusBar(new CPicture("KSTATBAR", 10,pos.h - 45)); statusbar = std::make_shared<CGStatusBar>(std::make_shared<CPicture>("KSTATBAR", 10,pos.h - 45));
resdatabar= new CResDataBar("KRESBAR", 3, 111+footerPos, 32, 2, 76, 76); resdatabar = std::make_shared<CResDataBar>("KRESBAR", 3, 111+footerPos, 32, 2, 76, 76);
} }
void CKingdomInterface::generateObjectsList(const std::vector<const CGObjectInstance * > &ownedObjects) void CKingdomInterface::generateObjectsList(const std::vector<const CGObjectInstance * > &ownedObjects)
@ -508,10 +497,10 @@ void CKingdomInterface::generateObjectsList(const std::vector<const CGObjectInst
for(const CGObjectInstance * object : ownedObjects) for(const CGObjectInstance * object : ownedObjects)
{ {
//Dwellings //Dwellings
if ( object->ID == Obj::CREATURE_GENERATOR1 ) if(object->ID == Obj::CREATURE_GENERATOR1)
{ {
OwnedObjectInfo &info = visibleObjects[object->subID]; OwnedObjectInfo & info = visibleObjects[object->subID];
if (info.count++ == 0) if(info.count++ == 0)
{ {
info.hoverText = object->getObjectName(); info.hoverText = object->getObjectName();
info.imageID = object->subID; info.imageID = object->subID;
@ -519,10 +508,10 @@ void CKingdomInterface::generateObjectsList(const std::vector<const CGObjectInst
} }
//Special objects from idToImage map that should be displayed in objects list //Special objects from idToImage map that should be displayed in objects list
auto iter = idToImage.find(std::make_pair(object->ID, object->subID)); auto iter = idToImage.find(std::make_pair(object->ID, object->subID));
if (iter != idToImage.end()) if(iter != idToImage.end())
{ {
OwnedObjectInfo &info = visibleObjects[iter->second]; OwnedObjectInfo & info = visibleObjects[iter->second];
if (info.count++ == 0) if(info.count++ == 0)
{ {
info.hoverText = object->getObjectName(); info.hoverText = object->getObjectName();
info.imageID = iter->second; info.imageID = iter->second;
@ -535,34 +524,37 @@ void CKingdomInterface::generateObjectsList(const std::vector<const CGObjectInst
{ {
objects.push_back(element.second); objects.push_back(element.second);
} }
dwellingsList = new CListBox(std::bind(&CKingdomInterface::createOwnedObject, this, _1), CListBox::DestroyFunc(), dwellingsList = std::make_shared<CListBox>(std::bind(&CKingdomInterface::createOwnedObject, this, _1),
Point(740,44), Point(0,57), dwellSize, visibleObjects.size()); Point(740,44), Point(0,57), dwellSize, visibleObjects.size());
} }
CIntObject* CKingdomInterface::createOwnedObject(size_t index) std::shared_ptr<CIntObject> CKingdomInterface::createOwnedObject(size_t index)
{ {
if (index < objects.size()) if(index < objects.size())
{ {
OwnedObjectInfo &obj = objects[index]; OwnedObjectInfo & obj = objects[index];
std::string value = boost::lexical_cast<std::string>(obj.count); std::string value = boost::lexical_cast<std::string>(obj.count);
return new InfoBox(Point(), InfoBox::POS_CORNER, InfoBox::SIZE_SMALL, auto data = std::make_shared<InfoBoxCustom>(value, "", "FLAGPORT", obj.imageID, obj.hoverText);
new InfoBoxCustom(value,"", "FLAGPORT", obj.imageID, obj.hoverText)); return std::make_shared<InfoBox>(Point(), InfoBox::POS_CORNER, InfoBox::SIZE_SMALL, data);
} }
return nullptr; return std::shared_ptr<CIntObject>();
} }
CIntObject * CKingdomInterface::createMainTab(size_t index) std::shared_ptr<CIntObject> CKingdomInterface::createMainTab(size_t index)
{ {
size_t size = conf.go()->ac.overviewSize; size_t size = conf.go()->ac.overviewSize;
switch (index) switch(index)
{ {
case 0: return new CKingdHeroList(size); case 0:
case 1: return new CKingdTownList(size); return std::make_shared<CKingdHeroList>(size);
default:return nullptr; case 1:
return std::make_shared<CKingdTownList>(size);
default:
return std::shared_ptr<CIntObject>();
} }
} }
void CKingdomInterface::generateMinesList(const std::vector<const CGObjectInstance * > &ownedObjects) void CKingdomInterface::generateMinesList(const std::vector<const CGObjectInstance *> & ownedObjects)
{ {
ui32 footerPos = conf.go()->ac.overviewSize * 116; ui32 footerPos = conf.go()->ac.overviewSize * 116;
std::vector<int> minesCount(GameConstants::RESOURCE_QUANTITY, 0); std::vector<int> minesCount(GameConstants::RESOURCE_QUANTITY, 0);
@ -573,7 +565,7 @@ void CKingdomInterface::generateMinesList(const std::vector<const CGObjectInstan
//Mines //Mines
if(object->ID == Obj::MINE || object->ID == Obj::ABANDONED_MINE) if(object->ID == Obj::MINE || object->ID == Obj::ABANDONED_MINE)
{ {
const CGMine *mine = dynamic_cast<const CGMine*>(object); const CGMine * mine = dynamic_cast<const CGMine *>(object);
assert(mine); assert(mine);
minesCount[mine->producedResource]++; minesCount[mine->producedResource]++;
@ -596,18 +588,17 @@ void CKingdomInterface::generateMinesList(const std::vector<const CGObjectInstan
{ {
totalIncome += town->dailyIncome()[Res::GOLD]; totalIncome += town->dailyIncome()[Res::GOLD];
} }
for (int i=0; i<7; i++) for(int i=0; i<7; i++)
{ {
std::string value = boost::lexical_cast<std::string>(minesCount[i]); std::string value = boost::lexical_cast<std::string>(minesCount[i]);
minesBox[i] = new InfoBox(Point(20+i*80, 31+footerPos), InfoBox::POS_INSIDE, InfoBox::SIZE_SMALL, auto data = std::make_shared<InfoBoxCustom>(value, "", "OVMINES", i, CGI->generaltexth->mines[i].first);
new InfoBoxCustom(value, "", "OVMINES", i, CGI->generaltexth->mines[i].first)); minesBox[i] = std::make_shared<InfoBox>(Point(20+i*80, 31+footerPos), InfoBox::POS_INSIDE, InfoBox::SIZE_SMALL, data);
minesBox[i]->removeUsedEvents(LCLICK|RCLICK); //fixes #890 - mines boxes ignore clicks minesBox[i]->removeUsedEvents(LCLICK|RCLICK); //fixes #890 - mines boxes ignore clicks
} }
incomeArea = new CHoverableArea(); incomeArea = std::make_shared<CHoverableArea>();
incomeArea->pos = Rect(pos.x+580, pos.y+31+footerPos, 136, 68); incomeArea->pos = Rect(pos.x+580, pos.y+31+footerPos, 136, 68);
incomeArea->hoverText = CGI->generaltexth->allTexts[255]; incomeArea->hoverText = CGI->generaltexth->allTexts[255];
incomeAmount = new CLabel(628, footerPos + 70, FONT_SMALL, TOPLEFT, Colors::WHITE, boost::lexical_cast<std::string>(totalIncome)); incomeAmount = std::make_shared<CLabel>(628, footerPos + 70, FONT_SMALL, TOPLEFT, Colors::WHITE, boost::lexical_cast<std::string>(totalIncome));
} }
void CKingdomInterface::generateButtons() void CKingdomInterface::generateButtons()
@ -615,28 +606,28 @@ void CKingdomInterface::generateButtons()
ui32 footerPos = conf.go()->ac.overviewSize * 116; ui32 footerPos = conf.go()->ac.overviewSize * 116;
//Main control buttons //Main control buttons
btnHeroes = new CButton (Point(748, 28+footerPos), "OVBUTN1.DEF", CButton::tooltip(CGI->generaltexth->overview[11], CGI->generaltexth->overview[6]), btnHeroes = std::make_shared<CButton>(Point(748, 28+footerPos), "OVBUTN1.DEF", CButton::tooltip(CGI->generaltexth->overview[11], CGI->generaltexth->overview[6]),
std::bind(&CKingdomInterface::activateTab, this, 0), SDLK_h); std::bind(&CKingdomInterface::activateTab, this, 0), SDLK_h);
btnHeroes->block(true); btnHeroes->block(true);
btnTowns = new CButton (Point(748, 64+footerPos), "OVBUTN6.DEF", CButton::tooltip(CGI->generaltexth->overview[12], CGI->generaltexth->overview[7]), btnTowns = std::make_shared<CButton>(Point(748, 64+footerPos), "OVBUTN6.DEF", CButton::tooltip(CGI->generaltexth->overview[12], CGI->generaltexth->overview[7]),
std::bind(&CKingdomInterface::activateTab, this, 1), SDLK_t); std::bind(&CKingdomInterface::activateTab, this, 1), SDLK_t);
btnExit = new CButton (Point(748,99+footerPos), "OVBUTN1.DEF", CButton::tooltip(CGI->generaltexth->allTexts[600]), btnExit = std::make_shared<CButton>(Point(748,99+footerPos), "OVBUTN1.DEF", CButton::tooltip(CGI->generaltexth->allTexts[600]),
std::bind(&CKingdomInterface::close, this), SDLK_RETURN); std::bind(&CKingdomInterface::close, this), SDLK_RETURN);
btnExit->assignedKeys.insert(SDLK_ESCAPE); btnExit->assignedKeys.insert(SDLK_ESCAPE);
btnExit->setImageOrder(3, 4, 5, 6); btnExit->setImageOrder(3, 4, 5, 6);
//Object list control buttons //Object list control buttons
dwellTop = new CButton (Point(733, 4), "OVBUTN4.DEF", CButton::tooltip(), [&](){ dwellingsList->moveToPos(0);}); dwellTop = std::make_shared<CButton>(Point(733, 4), "OVBUTN4.DEF", CButton::tooltip(), [&](){ dwellingsList->moveToPos(0);});
dwellBottom = new CButton (Point(733, footerPos+2), "OVBUTN4.DEF", CButton::tooltip(), [&](){ dwellingsList->moveToPos(-1); }); dwellBottom = std::make_shared<CButton>(Point(733, footerPos+2), "OVBUTN4.DEF", CButton::tooltip(), [&](){ dwellingsList->moveToPos(-1); });
dwellBottom->setImageOrder(2, 3, 4, 5); dwellBottom->setImageOrder(2, 3, 4, 5);
dwellUp = new CButton (Point(733, 24), "OVBUTN4.DEF", CButton::tooltip(), [&](){ dwellingsList->moveToPrev(); }); dwellUp = std::make_shared<CButton>(Point(733, 24), "OVBUTN4.DEF", CButton::tooltip(), [&](){ dwellingsList->moveToPrev(); });
dwellUp->setImageOrder(4, 5, 6, 7); dwellUp->setImageOrder(4, 5, 6, 7);
dwellDown = new CButton (Point(733, footerPos-18), "OVBUTN4.DEF", CButton::tooltip(), [&](){ dwellingsList->moveToNext(); }); dwellDown = std::make_shared<CButton>(Point(733, footerPos-18), "OVBUTN4.DEF", CButton::tooltip(), [&](){ dwellingsList->moveToNext(); });
dwellDown->setImageOrder(6, 7, 8, 9); dwellDown->setImageOrder(6, 7, 8, 9);
} }
@ -649,160 +640,148 @@ void CKingdomInterface::activateTab(size_t which)
void CKingdomInterface::townChanged(const CGTownInstance *town) void CKingdomInterface::townChanged(const CGTownInstance *town)
{ {
if (CKingdTownList * townList = dynamic_cast<CKingdTownList*>(tabArea->getItem())) if(auto townList = std::dynamic_pointer_cast<CKingdTownList>(tabArea->getItem()))
townList->townChanged(town); townList->townChanged(town);
} }
void CKingdomInterface::updateGarrisons() void CKingdomInterface::updateGarrisons()
{ {
if (CGarrisonHolder * garrison = dynamic_cast<CGarrisonHolder*>(tabArea->getItem())) if(auto garrison = std::dynamic_pointer_cast<CGarrisonHolder>(tabArea->getItem()))
garrison->updateGarrisons(); garrison->updateGarrisons();
} }
void CKingdomInterface::artifactAssembled(const ArtifactLocation& artLoc) void CKingdomInterface::artifactAssembled(const ArtifactLocation& artLoc)
{ {
if (CArtifactHolder * arts = dynamic_cast<CArtifactHolder*>(tabArea->getItem())) if(auto arts = std::dynamic_pointer_cast<CArtifactHolder>(tabArea->getItem()))
arts->artifactAssembled(artLoc); arts->artifactAssembled(artLoc);
} }
void CKingdomInterface::artifactDisassembled(const ArtifactLocation& artLoc) void CKingdomInterface::artifactDisassembled(const ArtifactLocation& artLoc)
{ {
if (CArtifactHolder * arts = dynamic_cast<CArtifactHolder*>(tabArea->getItem())) if(auto arts = std::dynamic_pointer_cast<CArtifactHolder>(tabArea->getItem()))
arts->artifactDisassembled(artLoc); arts->artifactDisassembled(artLoc);
} }
void CKingdomInterface::artifactMoved(const ArtifactLocation& artLoc, const ArtifactLocation& destLoc) void CKingdomInterface::artifactMoved(const ArtifactLocation& artLoc, const ArtifactLocation& destLoc)
{ {
if (CArtifactHolder * arts = dynamic_cast<CArtifactHolder*>(tabArea->getItem())) if(auto arts = std::dynamic_pointer_cast<CArtifactHolder>(tabArea->getItem()))
arts->artifactMoved(artLoc, destLoc); arts->artifactMoved(artLoc, destLoc);
} }
void CKingdomInterface::artifactRemoved(const ArtifactLocation& artLoc) void CKingdomInterface::artifactRemoved(const ArtifactLocation& artLoc)
{ {
if (CArtifactHolder * arts = dynamic_cast<CArtifactHolder*>(tabArea->getItem())) if(auto arts = std::dynamic_pointer_cast<CArtifactHolder>(tabArea->getItem()))
arts->artifactRemoved(artLoc); arts->artifactRemoved(artLoc);
} }
CKingdHeroList::CKingdHeroList(size_t maxSize) CKingdHeroList::CKingdHeroList(size_t maxSize)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
title = new CPicture("OVTITLE",16,0); title = std::make_shared<CPicture>("OVTITLE",16,0);
title->colorize(LOCPLINT->playerID); title->colorize(LOCPLINT->playerID);
heroLabel = new CLabel(150, 10, FONT_MEDIUM, CENTER, Colors::WHITE, CGI->generaltexth->overview[0]); heroLabel = std::make_shared<CLabel>(150, 10, FONT_MEDIUM, CENTER, Colors::WHITE, CGI->generaltexth->overview[0]);
skillsLabel = new CLabel(500, 10, FONT_MEDIUM, CENTER, Colors::WHITE, CGI->generaltexth->overview[1]); skillsLabel = std::make_shared<CLabel>(500, 10, FONT_MEDIUM, CENTER, Colors::WHITE, CGI->generaltexth->overview[1]);
ui32 townCount = LOCPLINT->cb->howManyHeroes(false); ui32 townCount = LOCPLINT->cb->howManyHeroes(false);
ui32 size = conf.go()->ac.overviewSize*116 + 19; ui32 size = conf.go()->ac.overviewSize*116 + 19;
heroes = new CListBox(std::bind(&CKingdHeroList::createHeroItem, this, _1), std::bind(&CKingdHeroList::destroyHeroItem, this, _1), heroes = std::make_shared<CListBox>(std::bind(&CKingdHeroList::createHeroItem, this, _1),
Point(19,21), Point(0,116), maxSize, townCount, 0, 1, Rect(-19, -21, size, size) ); Point(19,21), Point(0,116), maxSize, townCount, 0, 1, Rect(-19, -21, size, size));
} }
void CKingdHeroList::updateGarrisons() void CKingdHeroList::updateGarrisons()
{ {
std::list<CIntObject*> list = heroes->getItems(); for(std::shared_ptr<CIntObject> object : heroes->getItems())
for(CIntObject* object : list)
{ {
if (CGarrisonHolder * garrison = dynamic_cast<CGarrisonHolder*>(object) ) if(CGarrisonHolder * garrison = dynamic_cast<CGarrisonHolder*>(object.get()))
garrison->updateGarrisons(); garrison->updateGarrisons();
} }
} }
CIntObject* CKingdHeroList::createHeroItem(size_t index) std::shared_ptr<CIntObject> CKingdHeroList::createHeroItem(size_t index)
{ {
ui32 picCount = conf.go()->ac.overviewPics; ui32 picCount = conf.go()->ac.overviewPics;
size_t heroesCount = LOCPLINT->cb->howManyHeroes(false); size_t heroesCount = LOCPLINT->cb->howManyHeroes(false);
if (index < heroesCount) if(index < heroesCount)
{ {
auto hero = new CHeroItem(LOCPLINT->cb->getHeroBySerial(index, false)); auto hero = std::make_shared<CHeroItem>(LOCPLINT->cb->getHeroBySerial(index, false));
artSets.push_back(hero->heroArts); addSet(hero->heroArts);
return hero; return hero;
} }
else else
{ {
return new CAnimImage("OVSLOT", (index-2) % picCount ); return std::make_shared<CAnimImage>("OVSLOT", (index-2) % picCount );
} }
} }
void CKingdHeroList::destroyHeroItem(CIntObject *object)
{
if (CHeroItem * hero = dynamic_cast<CHeroItem*>(object))
{
artSets.erase(std::find(artSets.begin(), artSets.end(), hero->heroArts));
}
delete object;
}
CKingdTownList::CKingdTownList(size_t maxSize) CKingdTownList::CKingdTownList(size_t maxSize)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
title = new CPicture("OVTITLE",16,0); title = std::make_shared<CPicture>("OVTITLE", 16, 0);
title->colorize(LOCPLINT->playerID); title->colorize(LOCPLINT->playerID);
townLabel = new CLabel(146,10,FONT_MEDIUM, CENTER, Colors::WHITE, CGI->generaltexth->overview[3]); townLabel = std::make_shared<CLabel>(146, 10,FONT_MEDIUM, CENTER, Colors::WHITE, CGI->generaltexth->overview[3]);
garrHeroLabel = new CLabel(375,10,FONT_MEDIUM, CENTER, Colors::WHITE, CGI->generaltexth->overview[4]); garrHeroLabel = std::make_shared<CLabel>(375, 10, FONT_MEDIUM, CENTER, Colors::WHITE, CGI->generaltexth->overview[4]);
visitHeroLabel = new CLabel(608,10,FONT_MEDIUM, CENTER, Colors::WHITE, CGI->generaltexth->overview[5]); visitHeroLabel = std::make_shared<CLabel>(608, 10, FONT_MEDIUM, CENTER, Colors::WHITE, CGI->generaltexth->overview[5]);
ui32 townCount = LOCPLINT->cb->howManyTowns(); ui32 townCount = LOCPLINT->cb->howManyTowns();
ui32 size = conf.go()->ac.overviewSize*116 + 19; ui32 size = conf.go()->ac.overviewSize*116 + 19;
towns = new CListBox(std::bind(&CKingdTownList::createTownItem, this, _1), CListBox::DestroyFunc(), towns = std::make_shared<CListBox>(std::bind(&CKingdTownList::createTownItem, this, _1),
Point(19,21), Point(0,116), maxSize, townCount, 0, 1, Rect(-19, -21, size, size) ); Point(19,21), Point(0,116), maxSize, townCount, 0, 1, Rect(-19, -21, size, size));
} }
void CKingdTownList::townChanged(const CGTownInstance *town) void CKingdTownList::townChanged(const CGTownInstance * town)
{ {
std::list<CIntObject*> list = towns->getItems(); for(std::shared_ptr<CIntObject> object : towns->getItems())
for(CIntObject* object : list)
{ {
CTownItem * townItem = dynamic_cast<CTownItem*>(object); CTownItem * townItem = dynamic_cast<CTownItem *>(object.get());
if ( townItem && townItem->town == town) if(townItem && townItem->town == town)
townItem->update(); townItem->update();
} }
} }
void CKingdTownList::updateGarrisons() void CKingdTownList::updateGarrisons()
{ {
std::list<CIntObject*> list = towns->getItems(); for(std::shared_ptr<CIntObject> object : towns->getItems())
for(CIntObject* object : list)
{ {
if (CGarrisonHolder * garrison = dynamic_cast<CGarrisonHolder*>(object) ) if(CGarrisonHolder * garrison = dynamic_cast<CGarrisonHolder*>(object.get()))
garrison->updateGarrisons(); garrison->updateGarrisons();
} }
} }
CIntObject* CKingdTownList::createTownItem(size_t index) std::shared_ptr<CIntObject> CKingdTownList::createTownItem(size_t index)
{ {
ui32 picCount = conf.go()->ac.overviewPics; ui32 picCount = conf.go()->ac.overviewPics;
size_t townsCount = LOCPLINT->cb->howManyTowns(); size_t townsCount = LOCPLINT->cb->howManyTowns();
if (index < townsCount) if(index < townsCount)
return new CTownItem(LOCPLINT->cb->getTownBySerial(index)); return std::make_shared<CTownItem>(LOCPLINT->cb->getTownBySerial(index));
else else
return new CAnimImage("OVSLOT", (index-2) % picCount ); return std::make_shared<CAnimImage>("OVSLOT", (index-2) % picCount );
} }
CTownItem::CTownItem(const CGTownInstance* Town): CTownItem::CTownItem(const CGTownInstance * Town)
town(Town) : town(Town)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
background = new CAnimImage("OVSLOT", 6); background = std::make_shared<CAnimImage>("OVSLOT", 6);
name = new CLabel(74, 8, FONT_SMALL, TOPLEFT, Colors::WHITE, town->name); name = std::make_shared<CLabel>(74, 8, FONT_SMALL, TOPLEFT, Colors::WHITE, town->name);
income = new CLabel( 190, 60, FONT_SMALL, CENTER, Colors::WHITE, boost::lexical_cast<std::string>(town->dailyIncome()[Res::GOLD])); income = std::make_shared<CLabel>( 190, 60, FONT_SMALL, CENTER, Colors::WHITE, boost::lexical_cast<std::string>(town->dailyIncome()[Res::GOLD]));
hall = new CTownInfo( 69, 31, town, true); hall = std::make_shared<CTownInfo>( 69, 31, town, true);
fort = new CTownInfo(111, 31, town, false); fort = std::make_shared<CTownInfo>(111, 31, town, false);
garr = new CGarrisonInt(313, 3, 4, Point(232,0), nullptr, Point(313,2), town->getUpperArmy(), town->visitingHero, true, true, true); garr = std::make_shared<CGarrisonInt>(313, 3, 4, Point(232,0), town->getUpperArmy(), town->visitingHero, true, true, true);
heroes = new HeroSlots(town, Point(244,6), Point(475,6), garr, false); heroes = std::make_shared<HeroSlots>(town, Point(244,6), Point(475,6), garr, false);
size_t iconIndex = town->town->clientInfo.icons[town->hasFort()][town->builded >= CGI->modh->settings.MAX_BUILDING_PER_TURN]; size_t iconIndex = town->town->clientInfo.icons[town->hasFort()][town->builded >= CGI->modh->settings.MAX_BUILDING_PER_TURN];
picture = new CAnimImage("ITPT", iconIndex, 0, 5, 6); picture = std::make_shared<CAnimImage>("ITPT", iconIndex, 0, 5, 6);
new LRClickableAreaOpenTown(Rect(5, 6, 58, 64), town); openTown = std::make_shared<LRClickableAreaOpenTown>(Rect(5, 6, 58, 64), town);
for (size_t i=0; i<town->creatures.size(); i++) for(size_t i=0; i<town->creatures.size(); i++)
{ {
growth.push_back(new CCreaInfo(Point(401+37*i, 78), town, i, true, true)); growth.push_back(std::make_shared<CCreaInfo>(Point(401+37*i, 78), town, i, true, true));
available.push_back(new CCreaInfo(Point(48+37*i, 78), town, i, true, false)); available.push_back(std::make_shared<CCreaInfo>(Point(48+37*i, 78), town, i, true, false));
} }
} }
@ -832,62 +811,62 @@ void CTownItem::update()
class ArtSlotsTab : public CIntObject class ArtSlotsTab : public CIntObject
{ {
public: public:
CAnimImage * background; std::shared_ptr<CAnimImage> background;
std::vector<CHeroArtPlace*> arts; std::vector<std::shared_ptr<CHeroArtPlace>> arts;
ArtSlotsTab() ArtSlotsTab()
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
background = new CAnimImage("OVSLOT", 4); background = std::make_shared<CAnimImage>("OVSLOT", 4);
pos = background->pos; pos = background->pos;
for (size_t i=0; i<9; i++) for(size_t i=0; i<9; i++)
arts.push_back(new CHeroArtPlace(Point(270+i*48, 65))); arts.push_back(std::make_shared<CHeroArtPlace>(Point(270+i*48, 65)));
} }
}; };
class BackpackTab : public CIntObject class BackpackTab : public CIntObject
{ {
public: public:
CAnimImage * background; std::shared_ptr<CAnimImage> background;
std::vector<CHeroArtPlace*> arts; std::vector<std::shared_ptr<CHeroArtPlace>> arts;
CButton *btnLeft; std::shared_ptr<CButton> btnLeft;
CButton *btnRight; std::shared_ptr<CButton> btnRight;
BackpackTab() BackpackTab()
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
background = new CAnimImage("OVSLOT", 5); background = std::make_shared<CAnimImage>("OVSLOT", 5);
pos = background->pos; pos = background->pos;
btnLeft = new CButton(Point(269, 66), "HSBTNS3", CButton::tooltip(), 0); btnLeft = std::make_shared<CButton>(Point(269, 66), "HSBTNS3", CButton::tooltip(), 0);
btnRight = new CButton(Point(675, 66), "HSBTNS5", CButton::tooltip(), 0); btnRight = std::make_shared<CButton>(Point(675, 66), "HSBTNS5", CButton::tooltip(), 0);
for (size_t i=0; i<8; i++) for(size_t i=0; i<8; i++)
arts.push_back(new CHeroArtPlace(Point(295+i*48, 65))); arts.push_back(std::make_shared<CHeroArtPlace>(Point(295+i*48, 65)));
} }
}; };
CHeroItem::CHeroItem(const CGHeroInstance* Hero): CHeroItem::CHeroItem(const CGHeroInstance * Hero)
hero(Hero) : hero(Hero)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
artTabs.resize(3); artTabs.resize(3);
auto arts1 = new ArtSlotsTab(); auto arts1 = std::make_shared<ArtSlotsTab>();
auto arts2 = new ArtSlotsTab(); auto arts2 = std::make_shared<ArtSlotsTab>();
auto backpack = new BackpackTab(); auto backpack = std::make_shared<BackpackTab>();
artTabs[0] = arts1; artTabs[0] = arts1;
artTabs[1] = arts2; artTabs[1] = arts2;
artTabs[2] = backpack; artTabs[2] = backpack;
arts1->recActions = DISPOSE | SHARE_POS; arts1->recActions = SHARE_POS;
arts2->recActions = DISPOSE | SHARE_POS; arts2->recActions = SHARE_POS;
backpack->recActions = DISPOSE | SHARE_POS; backpack->recActions = SHARE_POS;
name = new CLabel(75, 7, FONT_SMALL, TOPLEFT, Colors::WHITE, hero->name); name = std::make_shared<CLabel>(75, 7, FONT_SMALL, TOPLEFT, Colors::WHITE, hero->name);
//layout is not trivial: MACH4 - catapult - excluded, MISC[x] rearranged //layout is not trivial: MACH4 - catapult - excluded, MISC[x] rearranged
assert(arts1->arts.size() == 9); assert(arts1->arts.size() == 9);
assert(arts2->arts.size() == 9); assert(arts2->arts.size() == 9);
std::map<ArtifactPosition, CHeroArtPlace*> arts = CArtifactsOfHero::ArtPlaceMap arts =
{ {
{ArtifactPosition::HEAD, arts1->arts[0]}, {ArtifactPosition::HEAD, arts1->arts[0]},
{ArtifactPosition::SHOULDERS,arts1->arts[1]}, {ArtifactPosition::SHOULDERS,arts1->arts[1]},
@ -911,20 +890,20 @@ CHeroItem::CHeroItem(const CGHeroInstance* Hero):
}; };
heroArts = new CArtifactsOfHero(arts, backpack->arts, backpack->btnLeft, backpack->btnRight, true); heroArts = std::make_shared<CArtifactsOfHero>(arts, backpack->arts, backpack->btnLeft, backpack->btnRight, true);
heroArts->setHero(hero); heroArts->setHero(hero);
artsTabs = new CTabbedInt(std::bind(&CHeroItem::onTabSelected, this, _1), std::bind(&CHeroItem::onTabDeselected, this, _1)); artsTabs = std::make_shared<CTabbedInt>(std::bind(&CHeroItem::onTabSelected, this, _1));
artButtons = new CToggleGroup(0); artButtons = std::make_shared<CToggleGroup>(0);
for (size_t it = 0; it<3; it++) for(size_t it = 0; it<3; it++)
{ {
int stringID[3] = {259, 261, 262}; int stringID[3] = {259, 261, 262};
std::string hover = CGI->generaltexth->overview[13+it]; std::string hover = CGI->generaltexth->overview[13+it];
std::string overlay = CGI->generaltexth->overview[8+it]; std::string overlay = CGI->generaltexth->overview[8+it];
auto button = new CToggleButton(Point(364+it*112, 46), "OVBUTN3", CButton::tooltip(hover, overlay), 0); auto button = std::make_shared<CToggleButton>(Point(364+it*112, 46), "OVBUTN3", CButton::tooltip(hover, overlay), 0);
button->addTextOverlay(CGI->generaltexth->allTexts[stringID[it]], FONT_SMALL, Colors::YELLOW); button->addTextOverlay(CGI->generaltexth->allTexts[stringID[it]], FONT_SMALL, Colors::YELLOW);
artButtons->addToggle(it, button); artButtons->addToggle(it, button);
} }
@ -932,53 +911,58 @@ CHeroItem::CHeroItem(const CGHeroInstance* Hero):
artButtons->addCallback(std::bind(&CHeroItem::onArtChange, this, _1)); artButtons->addCallback(std::bind(&CHeroItem::onArtChange, this, _1));
artButtons->setSelected(0); artButtons->setSelected(0);
garr = new CGarrisonInt(6, 78, 4, Point(), nullptr, Point(), hero, nullptr, true, true); garr = std::make_shared<CGarrisonInt>(6, 78, 4, Point(), hero, nullptr, true, true);
portrait = new CAnimImage("PortraitsLarge", hero->portrait, 0, 5, 6); portrait = std::make_shared<CAnimImage>("PortraitsLarge", hero->portrait, 0, 5, 6);
heroArea = new CHeroArea(5, 6, hero); heroArea = std::make_shared<CHeroArea>(5, 6, hero);
name = new CLabel(73, 7, FONT_SMALL, TOPLEFT, Colors::WHITE, hero->name); name = std::make_shared<CLabel>(73, 7, FONT_SMALL, TOPLEFT, Colors::WHITE, hero->name);
artsText = new CLabel(320, 55, FONT_SMALL, CENTER, Colors::WHITE, CGI->generaltexth->overview[2]); artsText = std::make_shared<CLabel>(320, 55, FONT_SMALL, CENTER, Colors::WHITE, CGI->generaltexth->overview[2]);
for (size_t i=0; i<GameConstants::PRIMARY_SKILLS; i++) for(size_t i=0; i<GameConstants::PRIMARY_SKILLS; i++)
heroInfo.push_back(new InfoBox(Point(78+i*36, 26), InfoBox::POS_DOWN, InfoBox::SIZE_SMALL, {
new InfoBoxHeroData(IInfoBoxData::HERO_PRIMARY_SKILL, hero, i))); auto data = std::make_shared<InfoBoxHeroData>(IInfoBoxData::HERO_PRIMARY_SKILL, hero, i);
heroInfo.push_back(std::make_shared<InfoBox>(Point(78+i*36, 26), InfoBox::POS_DOWN, InfoBox::SIZE_SMALL, data));
}
for (size_t i=0; i<GameConstants::SKILL_PER_HERO; i++) for(size_t i=0; i<GameConstants::SKILL_PER_HERO; i++)
heroInfo.push_back(new InfoBox(Point(410+i*36, 5), InfoBox::POS_NONE, InfoBox::SIZE_SMALL, {
new InfoBoxHeroData(IInfoBoxData::HERO_SECONDARY_SKILL, hero, i))); auto data = std::make_shared<InfoBoxHeroData>(IInfoBoxData::HERO_SECONDARY_SKILL, hero, i);
heroInfo.push_back(std::make_shared<InfoBox>(Point(410+i*36, 5), InfoBox::POS_NONE, InfoBox::SIZE_SMALL, data));
}
heroInfo.push_back(new InfoBox(Point(375, 5), InfoBox::POS_NONE, InfoBox::SIZE_SMALL, {
new InfoBoxHeroData(IInfoBoxData::HERO_SPECIAL, hero))); auto data = std::make_shared<InfoBoxHeroData>(IInfoBoxData::HERO_SPECIAL, hero);
heroInfo.push_back(std::make_shared<InfoBox>(Point(375, 5), InfoBox::POS_NONE, InfoBox::SIZE_SMALL, data));
heroInfo.push_back(new InfoBox(Point(330, 5), InfoBox::POS_INSIDE, InfoBox::SIZE_SMALL, data = std::make_shared<InfoBoxHeroData>(IInfoBoxData::HERO_EXPERIENCE, hero);
new InfoBoxHeroData(IInfoBoxData::HERO_EXPERIENCE, hero))); heroInfo.push_back(std::make_shared<InfoBox>(Point(330, 5), InfoBox::POS_INSIDE, InfoBox::SIZE_SMALL, data));
heroInfo.push_back(new InfoBox(Point(280, 5), InfoBox::POS_INSIDE, InfoBox::SIZE_SMALL, data = std::make_shared<InfoBoxHeroData>(IInfoBoxData::HERO_MANA, hero);
new InfoBoxHeroData(IInfoBoxData::HERO_MANA, hero))); heroInfo.push_back(std::make_shared<InfoBox>(Point(280, 5), InfoBox::POS_INSIDE, InfoBox::SIZE_SMALL, data));
}
morale = new MoraleLuckBox(true, Rect(225, 53, 30, 22), true); morale = std::make_shared<MoraleLuckBox>(true, Rect(225, 53, 30, 22), true);
luck = new MoraleLuckBox(false, Rect(225, 28, 30, 22), true); luck = std::make_shared<MoraleLuckBox>(false, Rect(225, 28, 30, 22), true);
morale->set(hero); morale->set(hero);
luck->set(hero); luck->set(hero);
} }
CIntObject * CHeroItem::onTabSelected(size_t index)
void CHeroItem::updateGarrisons()
{ {
return artTabs[index]; garr->recreateSlots();
} }
void CHeroItem::onTabDeselected(CIntObject *object) std::shared_ptr<CIntObject> CHeroItem::onTabSelected(size_t index)
{ {
addChild(object, false); return artTabs.at(index);
object->deactivate();
object->recActions = DISPOSE | SHARE_POS;
} }
void CHeroItem::onArtChange(int tabIndex) void CHeroItem::onArtChange(int tabIndex)
{ {
//redraw item after background change //redraw item after background change
if (active) if(active)
redraw(); redraw();
} }

View File

@ -61,16 +61,16 @@ public:
private: private:
InfoSize size; InfoSize size;
InfoPos infoPos; InfoPos infoPos;
IInfoBoxData *data; std::shared_ptr<IInfoBoxData> data;
CLabel * value; std::shared_ptr<CLabel> value;
CLabel * name; std::shared_ptr<CLabel> name;
CAnimImage * image; std::shared_ptr<CAnimImage> image;
CHoverableArea *hover; std::shared_ptr<CHoverableArea> hover;
public: public:
InfoBox(Point position, InfoPos Pos, InfoSize Size, IInfoBoxData *Data); InfoBox(Point position, InfoPos Pos, InfoSize Size, std::shared_ptr<IInfoBoxData> Data);
~InfoBox(); ~InfoBox();
void clickRight(tribool down, bool previousState) override; void clickRight(tribool down, bool previousState) override;
@ -106,7 +106,7 @@ public:
virtual size_t getImageIndex()=0; virtual size_t getImageIndex()=0;
//TODO: replace with something better //TODO: replace with something better
virtual bool prepareMessage(std::string &text, CComponent **comp)=0; virtual void prepareMessage(std::string & text, std::shared_ptr<CComponent> & comp)=0;
virtual ~IInfoBoxData(){}; virtual ~IInfoBoxData(){};
}; };
@ -126,7 +126,7 @@ public:
std::string getHoverText() override; std::string getHoverText() override;
size_t getImageIndex() override; size_t getImageIndex() override;
bool prepareMessage(std::string &text, CComponent **comp) override; void prepareMessage(std::string & text, std::shared_ptr<CComponent> & comp) override;
}; };
class InfoBoxHeroData : public InfoBoxAbstractHeroData class InfoBoxHeroData : public InfoBoxAbstractHeroData
@ -144,7 +144,7 @@ public:
std::string getHoverText() override; std::string getHoverText() override;
std::string getValueText() override; std::string getValueText() override;
bool prepareMessage(std::string &text, CComponent **comp) override; void prepareMessage(std::string & text, std::shared_ptr<CComponent> & comp) override;
}; };
class InfoBoxCustomHeroData : public InfoBoxAbstractHeroData class InfoBoxCustomHeroData : public InfoBoxAbstractHeroData
@ -176,7 +176,7 @@ public:
std::string getHoverText() override; std::string getHoverText() override;
size_t getImageIndex() override; size_t getImageIndex() override;
bool prepareMessage(std::string &text, CComponent **comp) override; void prepareMessage(std::string & text, std::shared_ptr<CComponent> & comp) override;
}; };
//TODO!!! //TODO!!!
@ -197,8 +197,6 @@ public:
size_t getImageIndex() override; size_t getImageIndex() override;
}; };
////////////////////////////////////////////////////////////////////////////////
/// Class which holds all parts of kingdom overview window /// Class which holds all parts of kingdom overview window
class CKingdomInterface : public CWindowObject, public CGarrisonHolder, public CArtifactHolder class CKingdomInterface : public CWindowObject, public CGarrisonHolder, public CArtifactHolder
{ {
@ -215,25 +213,27 @@ private:
}; };
std::vector<OwnedObjectInfo> objects; std::vector<OwnedObjectInfo> objects;
CListBox * dwellingsList; std::shared_ptr<CListBox> dwellingsList;
CTabbedInt * tabArea; std::shared_ptr<CTabbedInt> tabArea;
//Main buttons //Main buttons
CButton *btnTowns; std::shared_ptr<CButton> btnTowns;
CButton *btnHeroes; std::shared_ptr<CButton> btnHeroes;
CButton *btnExit; std::shared_ptr<CButton> btnExit;
//Buttons for scrolling dwellings list //Buttons for scrolling dwellings list
CButton *dwellUp, *dwellDown; std::shared_ptr<CButton> dwellUp;
CButton *dwellTop, *dwellBottom; std::shared_ptr<CButton> dwellDown;
std::shared_ptr<CButton> dwellTop;
std::shared_ptr<CButton> dwellBottom;
InfoBox * minesBox[7]; std::array<std::shared_ptr<InfoBox>, 7> minesBox;
CHoverableArea * incomeArea; std::shared_ptr<CHoverableArea> incomeArea;
CLabel * incomeAmount; std::shared_ptr<CLabel> incomeAmount;
CGStatusBar * statusbar; std::shared_ptr<CGStatusBar> statusbar;
CResDataBar *resdatabar; std::shared_ptr<CResDataBar> resdatabar;
void activateTab(size_t which); void activateTab(size_t which);
@ -242,8 +242,8 @@ private:
void generateObjectsList(const std::vector<const CGObjectInstance * > &ownedObjects); void generateObjectsList(const std::vector<const CGObjectInstance * > &ownedObjects);
void generateMinesList(const std::vector<const CGObjectInstance * > &ownedObjects); void generateMinesList(const std::vector<const CGObjectInstance * > &ownedObjects);
CIntObject* createOwnedObject(size_t index); std::shared_ptr<CIntObject> createOwnedObject(size_t index);
CIntObject* createMainTab(size_t index); std::shared_ptr<CIntObject> createMainTab(size_t index);
public: public:
CKingdomInterface(); CKingdomInterface();
@ -259,67 +259,73 @@ public:
/// List item with town /// List item with town
class CTownItem : public CIntObject, public CGarrisonHolder class CTownItem : public CIntObject, public CGarrisonHolder
{ {
CAnimImage *background; std::shared_ptr<CAnimImage> background;
CAnimImage *picture; std::shared_ptr<CAnimImage> picture;
CLabel *name; std::shared_ptr<CLabel> name;
CLabel *income; std::shared_ptr<CLabel> income;
CGarrisonInt *garr; std::shared_ptr<CGarrisonInt> garr;
HeroSlots *heroes; std::shared_ptr<HeroSlots> heroes;
CTownInfo *hall, *fort; std::shared_ptr<CTownInfo> hall;
std::vector<CCreaInfo*> available; std::shared_ptr<CTownInfo> fort;
std::vector<CCreaInfo*> growth;
std::vector<std::shared_ptr<CCreaInfo>> available;
std::vector<std::shared_ptr<CCreaInfo>> growth;
std::shared_ptr<LRClickableAreaOpenTown> openTown;
public: public:
const CGTownInstance * town; const CGTownInstance * town;
CTownItem(const CGTownInstance* town); CTownItem(const CGTownInstance * Town);
void updateGarrisons() override; void updateGarrisons() override;
void update(); void update();
}; };
/// List item with hero /// List item with hero
class CHeroItem : public CIntObject, public CWindowWithGarrison class CHeroItem : public CIntObject, public CGarrisonHolder
{ {
const CGHeroInstance * hero; const CGHeroInstance * hero;
std::vector<CIntObject *> artTabs; std::vector<std::shared_ptr<CIntObject>> artTabs;
CAnimImage *portrait; std::shared_ptr<CAnimImage> portrait;
CLabel *name; std::shared_ptr<CLabel> name;
CHeroArea *heroArea; std::shared_ptr<CHeroArea> heroArea;
CLabel *artsText; std::shared_ptr<CLabel> artsText;
CTabbedInt *artsTabs; std::shared_ptr<CTabbedInt> artsTabs;
CToggleGroup *artButtons; std::shared_ptr<CToggleGroup> artButtons;
std::vector<InfoBox*> heroInfo; std::vector<std::shared_ptr<InfoBox>> heroInfo;
MoraleLuckBox * morale, * luck; std::shared_ptr<MoraleLuckBox> morale;
std::shared_ptr<MoraleLuckBox> luck;
std::shared_ptr<CGarrisonInt> garr;
void onArtChange(int tabIndex); void onArtChange(int tabIndex);
CIntObject * onTabSelected(size_t index); std::shared_ptr<CIntObject> onTabSelected(size_t index);
void onTabDeselected(CIntObject *object);
public: public:
CArtifactsOfHero *heroArts; std::shared_ptr<CArtifactsOfHero> heroArts;
CHeroItem(const CGHeroInstance* hero); void updateGarrisons() override;
CHeroItem(const CGHeroInstance * hero);
}; };
/// Tab with all hero-specific data /// Tab with all hero-specific data
class CKingdHeroList : public CIntObject, public CGarrisonHolder, public CWindowWithArtifacts class CKingdHeroList : public CIntObject, public CGarrisonHolder, public CWindowWithArtifacts
{ {
private: private:
std::vector<CHeroItem*> heroItems; std::shared_ptr<CListBox> heroes;
CListBox * heroes; std::shared_ptr<CPicture> title;
CPicture * title; std::shared_ptr<CLabel> heroLabel;
CLabel * heroLabel; std::shared_ptr<CLabel> skillsLabel;
CLabel * skillsLabel;
CIntObject* createHeroItem(size_t index); std::shared_ptr<CIntObject> createHeroItem(size_t index);
void destroyHeroItem(CIntObject *item);
public: public:
CKingdHeroList(size_t maxSize); CKingdHeroList(size_t maxSize);
@ -330,17 +336,16 @@ public:
class CKingdTownList : public CIntObject, public CGarrisonHolder class CKingdTownList : public CIntObject, public CGarrisonHolder
{ {
private: private:
std::vector<CTownItem*> townItems; std::shared_ptr<CListBox> towns;
CListBox * towns; std::shared_ptr<CPicture> title;
CPicture * title; std::shared_ptr<CLabel> townLabel;
CLabel * townLabel; std::shared_ptr<CLabel> garrHeroLabel;
CLabel * garrHeroLabel; std::shared_ptr<CLabel> visitHeroLabel;
CLabel * visitHeroLabel;
CIntObject* createTownItem(size_t index); std::shared_ptr<CIntObject> createTownItem(size_t index);
public: public:
CKingdTownList(size_t maxSize); CKingdTownList(size_t maxSize);
void townChanged(const CGTownInstance *town); void townChanged(const CGTownInstance * town);
void updateGarrisons() override; void updateGarrisons() override;
}; };

View File

@ -62,15 +62,15 @@ void CQuestIcon::showAll(SDL_Surface * to)
CAnimImage::showAll(to); CAnimImage::showAll(to);
} }
CQuestMinimap::CQuestMinimap (const Rect & position) : CQuestMinimap::CQuestMinimap(const Rect & position)
CMinimap (position), : CMinimap(position),
currentQuest (nullptr) currentQuest(nullptr)
{ {
} }
void CQuestMinimap::addQuestMarks (const QuestInfo * q) void CQuestMinimap::addQuestMarks (const QuestInfo * q)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
icons.clear(); icons.clear();
int3 tile; int3 tile;
@ -96,13 +96,13 @@ void CQuestMinimap::addQuestMarks (const QuestInfo * q)
void CQuestMinimap::update() void CQuestMinimap::update()
{ {
CMinimap::update(); CMinimap::update();
if (currentQuest) if(currentQuest)
addQuestMarks (currentQuest); addQuestMarks(currentQuest);
} }
void CQuestMinimap::iconClicked() void CQuestMinimap::iconClicked()
{ {
if (currentQuest->obj) if(currentQuest->obj)
adventureInt->centerOn (currentQuest->obj->pos); adventureInt->centerOn (currentQuest->obj->pos);
//moveAdvMapSelection(); //moveAdvMapSelection();
} }
@ -110,44 +110,38 @@ void CQuestMinimap::iconClicked()
void CQuestMinimap::showAll(SDL_Surface * to) void CQuestMinimap::showAll(SDL_Surface * to)
{ {
CIntObject::showAll(to); // blitting IntObject directly to hide radar CIntObject::showAll(to); // blitting IntObject directly to hide radar
for (auto pic : icons) // for (auto pic : icons)
pic->showAll(to); // pic->showAll(to);
} }
CQuestLog::CQuestLog (const std::vector<QuestInfo> & Quests) : CQuestLog::CQuestLog (const std::vector<QuestInfo> & Quests)
CWindowObject(PLAYER_COLORED | BORDERED, "questDialog"), : CWindowObject(PLAYER_COLORED | BORDERED, "questDialog"),
questIndex(0), questIndex(0),
currentQuest(nullptr), currentQuest(nullptr),
componentsBox(nullptr),
hideComplete(false), hideComplete(false),
quests(Quests), quests(Quests)
slider(nullptr)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
init();
}
void CQuestLog::init()
{
const JsonNode & texts = CGI->generaltexth->localizedTexts["questLog"]; const JsonNode & texts = CGI->generaltexth->localizedTexts["questLog"];
minimap = new CQuestMinimap (Rect (12, 12, 169, 169)); minimap = std::make_shared<CQuestMinimap>(Rect(12, 12, 169, 169));
// TextBox have it's own 4 pixel padding from top at least for English. To achieve 10px from both left and top only add 6px margin // TextBox have it's own 4 pixel padding from top at least for English. To achieve 10px from both left and top only add 6px margin
description = new CTextBox ("", Rect(205, 18, 385, DESCRIPTION_HEIGHT_MAX), CSlider::BROWN, FONT_MEDIUM, TOPLEFT, Colors::WHITE); description = std::make_shared<CTextBox>("", Rect(205, 18, 385, DESCRIPTION_HEIGHT_MAX), CSlider::BROWN, FONT_MEDIUM, TOPLEFT, Colors::WHITE);
ok = new CButton(Point(539, 398), "IOKAY.DEF", CGI->generaltexth->zelp[445], std::bind(&CQuestLog::close,this), SDLK_RETURN); ok = std::make_shared<CButton>(Point(539, 398), "IOKAY.DEF", CGI->generaltexth->zelp[445], std::bind(&CQuestLog::close, this), SDLK_RETURN);
// Both button and lable are shifted to -2px by x and y to not make them actually look like they're on same line with quests list and ok button // Both button and lable are shifted to -2px by x and y to not make them actually look like they're on same line with quests list and ok button
hideCompleteButton = new CToggleButton(Point(10, 396), "sysopchk.def", CButton::tooltip(texts["hideComplete"]), std::bind(&CQuestLog::toggleComplete, this, _1)); hideCompleteButton = std::make_shared<CToggleButton>(Point(10, 396), "sysopchk.def", CButton::tooltip(texts["hideComplete"]), std::bind(&CQuestLog::toggleComplete, this, _1));
hideCompleteLabel = new CLabel(46, 398, FONT_MEDIUM, TOPLEFT, Colors::WHITE, texts["hideComplete"]["label"].String()); hideCompleteLabel = std::make_shared<CLabel>(46, 398, FONT_MEDIUM, TOPLEFT, Colors::WHITE, texts["hideComplete"]["label"].String());
slider = new CSlider(Point(166, 195), 191, std::bind(&CQuestLog::sliderMoved, this, _1), QUEST_COUNT, 0, false, CSlider::BROWN); slider = std::make_shared<CSlider>(Point(166, 195), 191, std::bind(&CQuestLog::sliderMoved, this, _1), QUEST_COUNT, 0, false, CSlider::BROWN);
recreateLabelList(); recreateLabelList();
recreateQuestList (0); recreateQuestList(0);
} }
void CQuestLog::recreateLabelList() void CQuestLog::recreateLabelList()
{ {
if (labels.size()) OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
labels.clear(); labels.clear();
bool completeMissing = true; bool completeMissing = true;
int currentLabel = 0; int currentLabel = 0;
@ -209,8 +203,8 @@ void CQuestLog::recreateLabelList()
void CQuestLog::showAll(SDL_Surface * to) void CQuestLog::showAll(SDL_Surface * to)
{ {
CWindowObject::showAll (to); CWindowObject::showAll(to);
if (labels.size() && labels[questIndex]->active) if(labels.size() && labels[questIndex]->active)
{ {
Rect rect = Rect::around(labels[questIndex]->pos); Rect rect = Rect::around(labels[questIndex]->pos);
rect.x -= 2; // Adjustment needed as we want selection box on top of border in graphics rect.x -= 2; // Adjustment needed as we want selection box on top of border in graphics
@ -232,7 +226,7 @@ void CQuestLog::recreateQuestList (int newpos)
minimap->update(); minimap->update();
} }
void CQuestLog::selectQuest (int which, int labelId) void CQuestLog::selectQuest(int which, int labelId)
{ {
questIndex = labelId; questIndex = labelId;
currentQuest = &quests[which]; currentQuest = &quests[which];
@ -241,14 +235,15 @@ void CQuestLog::selectQuest (int which, int labelId)
MetaString text; MetaString text;
std::vector<Component> components; std::vector<Component> components;
currentQuest->quest->getVisitText (text, components, currentQuest->quest->isCustomFirst, true); currentQuest->quest->getVisitText (text, components, currentQuest->quest->isCustomFirst, true);
if (description->slider) if(description->slider)
description->slider->moveToMin(); // scroll text to start position description->slider->moveToMin(); // scroll text to start position
description->setText (text.toString()); //TODO: use special log entry text description->setText(text.toString()); //TODO: use special log entry text
componentsBox.reset();
vstd::clear_pointer(componentsBox);
int componentsSize = components.size(); int componentsSize = components.size();
int descriptionHeight = DESCRIPTION_HEIGHT_MAX; int descriptionHeight = DESCRIPTION_HEIGHT_MAX;
if (componentsSize) if(componentsSize)
{ {
descriptionHeight -= 15; descriptionHeight -= 15;
CComponent::ESize imageSize = CComponent::large; CComponent::ESize imageSize = CComponent::large;
@ -290,12 +285,16 @@ void CQuestLog::selectQuest (int which, int labelId)
break; break;
} }
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
std::vector<CComponent *> comps;
for (auto & component : components)
comps.push_back(new CComponent(component, imageSize));
componentsBox = new CComponentBox(comps, Rect(202, 20+descriptionHeight+15, 391, DESCRIPTION_HEIGHT_MAX-(20+descriptionHeight))); std::vector<std::shared_ptr<CComponent>> comps;
for(auto & component : components)
{
auto c = std::make_shared<CComponent>(component, imageSize);
comps.push_back(c);
}
componentsBox = std::make_shared<CComponentBox>(comps, Rect(202, 20+descriptionHeight+15, 391, DESCRIPTION_HEIGHT_MAX-(20+descriptionHeight)));
} }
description->resize(Point(385, descriptionHeight)); description->resize(Point(385, descriptionHeight));
@ -303,15 +302,14 @@ void CQuestLog::selectQuest (int which, int labelId)
redraw(); redraw();
} }
void CQuestLog::sliderMoved (int newpos) void CQuestLog::sliderMoved(int newpos)
{ {
recreateQuestList (newpos); //move components recreateQuestList(newpos); //move components
redraw(); redraw();
} }
void CQuestLog::toggleComplete(bool on) void CQuestLog::toggleComplete(bool on)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL;
hideComplete = on; hideComplete = on;
recreateLabelList(); recreateLabelList();
recreateQuestList(0); recreateQuestList(0);

View File

@ -38,7 +38,7 @@ class CQuestLabel : public LRClickableAreaWText, public CMultiLineLabel
public: public:
std::function<void()> callback; std::function<void()> callback;
CQuestLabel (Rect position, EFonts Font = FONT_SMALL, EAlignment Align = TOPLEFT, const SDL_Color &Color = Colors::WHITE, const std::string &Text = "") CQuestLabel(Rect position, EFonts Font = FONT_SMALL, EAlignment Align = TOPLEFT, const SDL_Color &Color = Colors::WHITE, const std::string &Text = "")
: CMultiLineLabel (position, FONT_SMALL, TOPLEFT, Colors::WHITE, Text){}; : CMultiLineLabel (position, FONT_SMALL, TOPLEFT, Colors::WHITE, Text){};
void clickLeft(tribool down, bool previousState) override; void clickLeft(tribool down, bool previousState) override;
void showAll(SDL_Surface * to) override; void showAll(SDL_Surface * to) override;
@ -49,7 +49,7 @@ class CQuestIcon : public CAnimImage
public: public:
std::function<void()> callback; //TODO: merge with other similar classes? std::function<void()> callback; //TODO: merge with other similar classes?
CQuestIcon (const std::string &defname, int index, int x=0, int y=0); CQuestIcon(const std::string &defname, int index, int x=0, int y=0);
void clickLeft(tribool down, bool previousState) override; void clickLeft(tribool down, bool previousState) override;
void showAll(SDL_Surface * to) override; void showAll(SDL_Surface * to) override;
@ -57,17 +57,16 @@ public:
class CQuestMinimap : public CMinimap class CQuestMinimap : public CMinimap
{ {
std::vector <std::shared_ptr<CQuestIcon>> icons; std::vector<std::shared_ptr<CQuestIcon>> icons;
void clickLeft(tribool down, bool previousState) override{}; //minimap ignores clicking on its surface void clickLeft(tribool down, bool previousState) override{}; //minimap ignores clicking on its surface
void iconClicked(); void iconClicked();
void mouseMoved (const SDL_MouseMotionEvent & sEvent) override{}; void mouseMoved (const SDL_MouseMotionEvent & sEvent) override{};
public: public:
const QuestInfo * currentQuest; const QuestInfo * currentQuest;
CQuestMinimap (const Rect & position); CQuestMinimap(const Rect & position);
//should be called to invalidate whole map - different player or level //should be called to invalidate whole map - different player or level
void update(); void update();
void addQuestMarks (const QuestInfo * q); void addQuestMarks (const QuestInfo * q);
@ -79,22 +78,20 @@ class CQuestLog : public CWindowObject
{ {
int questIndex; int questIndex;
const QuestInfo * currentQuest; const QuestInfo * currentQuest;
CComponentBox * componentsBox; std::shared_ptr<CComponentBox> componentsBox;
bool hideComplete; bool hideComplete;
CToggleButton * hideCompleteButton; std::shared_ptr<CToggleButton> hideCompleteButton;
CLabel * hideCompleteLabel; std::shared_ptr<CLabel> hideCompleteLabel;
const std::vector<QuestInfo> quests; const std::vector<QuestInfo> quests;
std::vector <std::shared_ptr<CQuestLabel>> labels; std::vector<std::shared_ptr<CQuestLabel>> labels;
CTextBox * description; std::shared_ptr<CTextBox> description;
CQuestMinimap * minimap; std::shared_ptr<CQuestMinimap> minimap;
CSlider * slider; //scrolls quests std::shared_ptr<CSlider> slider; //scrolls quests
CButton *ok; std::shared_ptr<CButton> ok;
void init ();
public: public:
CQuestLog(const std::vector<QuestInfo> & Quests);
CQuestLog (const std::vector<QuestInfo> & Quests);
~CQuestLog(){}; ~CQuestLog(){};

View File

@ -102,7 +102,7 @@ CSpellWindow::CSpellWindow(const CGHeroInstance * _myHero, CPlayerInterface * _m
myHero(_myHero), myHero(_myHero),
myInt(_myInt) myInt(_myInt)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
//initializing castable spells //initializing castable spells
mySpells.reserve(CGI->spellh->objects.size()); mySpells.reserve(CGI->spellh->objects.size());
for(const CSpell * spell : CGI->spellh->objects) for(const CSpell * spell : CGI->spellh->objects)
@ -168,13 +168,13 @@ CSpellWindow::CSpellWindow(const CGHeroInstance * _myHero, CPlayerInterface * _m
//numbers of spell pages computed //numbers of spell pages computed
leftCorner = new CPicture("SpelTrnL.bmp", 97, 77); leftCorner = std::make_shared<CPicture>("SpelTrnL.bmp", 97, 77);
rightCorner = new CPicture("SpelTrnR.bmp", 487, 72); rightCorner = std::make_shared<CPicture>("SpelTrnR.bmp", 487, 72);
spells = std::make_shared<CAnimation>("Spells"); spellIcons = std::make_shared<CAnimation>("Spells");
spellTab = new CAnimImage("SpelTab", selectedTab, 0, 524, 88); schoolTab = std::make_shared<CAnimImage>("SpelTab", selectedTab, 0, 524, 88);
schools = new CAnimImage("Schools",0,0,117,74); schoolPicture = std::make_shared<CAnimImage>("Schools", 0, 0, 117, 74);
schoolBorders[0] = std::make_shared<CAnimation>("SplevA.def"); schoolBorders[0] = std::make_shared<CAnimation>("SplevA.def");
schoolBorders[1] = std::make_shared<CAnimation>("SplevF.def"); schoolBorders[1] = std::make_shared<CAnimation>("SplevF.def");
@ -182,34 +182,34 @@ CSpellWindow::CSpellWindow(const CGHeroInstance * _myHero, CPlayerInterface * _m
schoolBorders[3] = std::make_shared<CAnimation>("SplevE.def"); schoolBorders[3] = std::make_shared<CAnimation>("SplevE.def");
for(auto item : schoolBorders) for(auto item : schoolBorders)
item->load(); item->preload();
mana = new CLabel(435, 426, FONT_SMALL, CENTER, Colors::YELLOW, boost::lexical_cast<std::string>(myHero->mana)); mana = std::make_shared<CLabel>(435, 426, FONT_SMALL, CENTER, Colors::YELLOW, boost::lexical_cast<std::string>(myHero->mana));
statusBar = new CGStatusBar(7, 569, "Spelroll.bmp"); statusBar = std::make_shared<CGStatusBar>(7, 569, "Spelroll.bmp");
SDL_Rect temp_rect = genRect(45, 35, 479 + pos.x, 405 + pos.y); SDL_Rect temp_rect = genRect(45, 35, 479 + pos.x, 405 + pos.y);
new InteractiveArea(temp_rect, std::bind(&CSpellWindow::fexitb, this), 460, this); interactiveAreas.push_back(std::make_shared<InteractiveArea>(temp_rect, std::bind(&CSpellWindow::fexitb, this), 460, this));
temp_rect = genRect(45, 35, 221 + pos.x, 405 + pos.y); temp_rect = genRect(45, 35, 221 + pos.x, 405 + pos.y);
new InteractiveArea(temp_rect, std::bind(&CSpellWindow::fbattleSpellsb, this), 453, this); interactiveAreas.push_back(std::make_shared<InteractiveArea>(temp_rect, std::bind(&CSpellWindow::fbattleSpellsb, this), 453, this));
temp_rect = genRect(45, 35, 355 + pos.x, 405 + pos.y); temp_rect = genRect(45, 35, 355 + pos.x, 405 + pos.y);
new InteractiveArea(temp_rect, std::bind(&CSpellWindow::fadvSpellsb, this), 452, this); interactiveAreas.push_back(std::make_shared<InteractiveArea>(temp_rect, std::bind(&CSpellWindow::fadvSpellsb, this), 452, this));
temp_rect = genRect(45, 35, 418 + pos.x, 405 + pos.y); temp_rect = genRect(45, 35, 418 + pos.x, 405 + pos.y);
new InteractiveArea(temp_rect, std::bind(&CSpellWindow::fmanaPtsb, this), 459, this); interactiveAreas.push_back(std::make_shared<InteractiveArea>(temp_rect, std::bind(&CSpellWindow::fmanaPtsb, this), 459, this));
temp_rect = genRect(36, 56, 549 + pos.x, 94 + pos.y); temp_rect = genRect(36, 56, 549 + pos.x, 94 + pos.y);
new InteractiveArea(temp_rect, std::bind(&CSpellWindow::selectSchool, this, 0), 454, this); interactiveAreas.push_back(std::make_shared<InteractiveArea>(temp_rect, std::bind(&CSpellWindow::selectSchool, this, 0), 454, this));
temp_rect = genRect(36, 56, 549 + pos.x, 151 + pos.y); temp_rect = genRect(36, 56, 549 + pos.x, 151 + pos.y);
new InteractiveArea(temp_rect, std::bind(&CSpellWindow::selectSchool, this, 3), 457, this); interactiveAreas.push_back(std::make_shared<InteractiveArea>(temp_rect, std::bind(&CSpellWindow::selectSchool, this, 3), 457, this));
temp_rect = genRect(36, 56, 549 + pos.x, 210 + pos.y); temp_rect = genRect(36, 56, 549 + pos.x, 210 + pos.y);
new InteractiveArea(temp_rect, std::bind(&CSpellWindow::selectSchool, this, 1), 455, this); interactiveAreas.push_back(std::make_shared<InteractiveArea>(temp_rect, std::bind(&CSpellWindow::selectSchool, this, 1), 455, this));
temp_rect = genRect(36, 56, 549 + pos.x, 270 + pos.y); temp_rect = genRect(36, 56, 549 + pos.x, 270 + pos.y);
new InteractiveArea(temp_rect, std::bind(&CSpellWindow::selectSchool, this, 2), 456, this); interactiveAreas.push_back(std::make_shared<InteractiveArea>(temp_rect, std::bind(&CSpellWindow::selectSchool, this, 2), 456, this));
temp_rect = genRect(36, 56, 549 + pos.x, 330 + pos.y); temp_rect = genRect(36, 56, 549 + pos.x, 330 + pos.y);
new InteractiveArea(temp_rect, std::bind(&CSpellWindow::selectSchool, this, 4), 458, this); interactiveAreas.push_back(std::make_shared<InteractiveArea>(temp_rect, std::bind(&CSpellWindow::selectSchool, this, 4), 458, this));
temp_rect = genRect(leftCorner->bg->h, leftCorner->bg->w, 97 + pos.x, 77 + pos.y); temp_rect = genRect(leftCorner->bg->h, leftCorner->bg->w, 97 + pos.x, 77 + pos.y);
new InteractiveArea(temp_rect, std::bind(&CSpellWindow::fLcornerb, this), 450, this); interactiveAreas.push_back(std::make_shared<InteractiveArea>(temp_rect, std::bind(&CSpellWindow::fLcornerb, this), 450, this));
temp_rect = genRect(rightCorner->bg->h, rightCorner->bg->w, 487 + pos.x, 72 + pos.y); temp_rect = genRect(rightCorner->bg->h, rightCorner->bg->w, 487 + pos.x, 72 + pos.y);
new InteractiveArea(temp_rect, std::bind(&CSpellWindow::fRcornerb, this), 451, this); interactiveAreas.push_back(std::make_shared<InteractiveArea>(temp_rect, std::bind(&CSpellWindow::fRcornerb, this), 451, this));
//areas for spells //areas for spells
int xpos = 117 + pos.x, ypos = 90 + pos.y; int xpos = 117 + pos.x, ypos = 90 + pos.y;
@ -217,7 +217,7 @@ CSpellWindow::CSpellWindow(const CGHeroInstance * _myHero, CPlayerInterface * _m
for(int v=0; v<12; ++v) for(int v=0; v<12; ++v)
{ {
temp_rect = genRect(65, 78, xpos, ypos); temp_rect = genRect(65, 78, xpos, ypos);
spellAreas[v] = new SpellArea(temp_rect, this); spellAreas[v] = std::make_shared<SpellArea>(temp_rect, this);
if(v == 5) //to right page if(v == 5) //to right page
{ {
@ -237,7 +237,7 @@ CSpellWindow::CSpellWindow(const CGHeroInstance * _myHero, CPlayerInterface * _m
} }
selectedTab = battleSpellsOnly ? myInt->spellbookSettings.spellbookLastTabBattle : myInt->spellbookSettings.spellbookLastTabAdvmap; selectedTab = battleSpellsOnly ? myInt->spellbookSettings.spellbookLastTabBattle : myInt->spellbookSettings.spellbookLastTabAdvmap;
spellTab->setFrame(selectedTab, 0); schoolTab->setFrame(selectedTab, 0);
int cp = battleSpellsOnly ? myInt->spellbookSettings.spellbookLastPageBattle : myInt->spellbookSettings.spellbokLastPageAdvmap; int cp = battleSpellsOnly ? myInt->spellbookSettings.spellbookLastPageBattle : myInt->spellbookSettings.spellbokLastPageAdvmap;
// spellbook last page battle index is not reset after battle, so this needs to stay here // spellbook last page battle index is not reset after battle, so this needs to stay here
vstd::abetween(cp, 0, std::max(0, pagesWithinCurrentTab() - 1)); vstd::abetween(cp, 0, std::max(0, pagesWithinCurrentTab() - 1));
@ -248,9 +248,6 @@ CSpellWindow::CSpellWindow(const CGHeroInstance * _myHero, CPlayerInterface * _m
CSpellWindow::~CSpellWindow() CSpellWindow::~CSpellWindow()
{ {
for(auto item : schoolBorders)
item->unload();
spells->unload();
} }
void CSpellWindow::fexitb() void CSpellWindow::fexitb()
@ -263,7 +260,7 @@ void CSpellWindow::fexitb()
void CSpellWindow::fadvSpellsb() void CSpellWindow::fadvSpellsb()
{ {
if (battleSpellsOnly == true) if(battleSpellsOnly == true)
{ {
turnPageRight(); turnPageRight();
battleSpellsOnly = false; battleSpellsOnly = false;
@ -274,7 +271,7 @@ void CSpellWindow::fadvSpellsb()
void CSpellWindow::fbattleSpellsb() void CSpellWindow::fbattleSpellsb()
{ {
if (battleSpellsOnly == false) if(battleSpellsOnly == false)
{ {
turnPageLeft(); turnPageLeft();
battleSpellsOnly = true; battleSpellsOnly = true;
@ -289,14 +286,14 @@ void CSpellWindow::fmanaPtsb()
void CSpellWindow::selectSchool(int school) void CSpellWindow::selectSchool(int school)
{ {
if (selectedTab != school) if(selectedTab != school)
{ {
if (selectedTab < school) if(selectedTab < school)
turnPageLeft(); turnPageLeft();
else else
turnPageRight(); turnPageRight();
selectedTab = school; selectedTab = school;
spellTab->setFrame(selectedTab, 0); schoolTab->setFrame(selectedTab, 0);
setCurrentPage(0); setCurrentPage(0);
} }
computeSpellsPerArea(); computeSpellsPerArea();
@ -405,9 +402,9 @@ void CSpellWindow::computeSpellsPerArea()
void CSpellWindow::setCurrentPage(int value) void CSpellWindow::setCurrentPage(int value)
{ {
currentPage = value; currentPage = value;
schools->visible = selectedTab!=4 && currentPage == 0; schoolPicture->visible = selectedTab!=4 && currentPage == 0;
if(selectedTab != 4) if(selectedTab != 4)
schools->setFrame(selectedTab, 0); schoolPicture->setFrame(selectedTab, 0);
leftCorner->visible = currentPage != 0; leftCorner->visible = currentPage != 0;
rightCorner->visible = (currentPage+1) < pagesWithinCurrentTab(); rightCorner->visible = (currentPage+1) < pagesWithinCurrentTab();
@ -416,13 +413,13 @@ void CSpellWindow::setCurrentPage(int value)
void CSpellWindow::turnPageLeft() void CSpellWindow::turnPageLeft()
{ {
if (settings["video"]["spellbookAnimation"].Bool()) if(settings["video"]["spellbookAnimation"].Bool())
CCS->videoh->openAndPlayVideo("PGTRNLFT.SMK", pos.x+13, pos.y+15, screen); CCS->videoh->openAndPlayVideo("PGTRNLFT.SMK", pos.x+13, pos.y+15, screen);
} }
void CSpellWindow::turnPageRight() void CSpellWindow::turnPageRight()
{ {
if (settings["video"]["spellbookAnimation"].Bool()) if(settings["video"]["spellbookAnimation"].Bool())
CCS->videoh->openAndPlayVideo("PGTRNRGH.SMK", pos.x+13, pos.y+15, screen); CCS->videoh->openAndPlayVideo("PGTRNRGH.SMK", pos.x+13, pos.y+15, screen);
} }
@ -503,27 +500,23 @@ CSpellWindow::SpellArea::SpellArea(SDL_Rect pos, CSpellWindow * owner)
this->owner = owner; this->owner = owner;
addUsedEvents(LCLICK | RCLICK | HOVER); addUsedEvents(LCLICK | RCLICK | HOVER);
spellCost = whichSchool = schoolLevel = -1; schoolLevel = -1;
mySpell = nullptr; mySpell = nullptr;
schoolBorder = nullptr;
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
image = new CAnimImage(owner->spells, 0, 0); image = std::make_shared<CAnimImage>(owner->spellIcons, 0, 0);
image->visible = false; image->visible = false;
name = new CLabel(39, 70, FONT_TINY, CENTER); name = std::make_shared<CLabel>(39, 70, FONT_TINY, CENTER);
level = new CLabel(39, 82, FONT_TINY, CENTER); level = std::make_shared<CLabel>(39, 82, FONT_TINY, CENTER);
cost = new CLabel(39, 94, FONT_TINY, CENTER); cost = std::make_shared<CLabel>(39, 94, FONT_TINY, CENTER);
for(auto l : {name, level, cost}) for(auto l : {name, level, cost})
l->autoRedraw = false; l->autoRedraw = false;
} }
CSpellWindow::SpellArea::~SpellArea() CSpellWindow::SpellArea::~SpellArea() = default;
{
}
void CSpellWindow::SpellArea::clickLeft(tribool down, bool previousState) void CSpellWindow::SpellArea::clickLeft(tribool down, bool previousState)
{ {
@ -551,7 +544,7 @@ void CSpellWindow::SpellArea::clickLeft(tribool down, bool previousState)
//battle spell on adv map or adventure map spell during combat => display infowindow, not cast //battle spell on adv map or adventure map spell during combat => display infowindow, not cast
if((combatSpell ^ inCombat) || inCastle) if((combatSpell ^ inCombat) || inCastle)
{ {
std::vector<CComponent*> hlp(1, new CComponent(CComponent::spell, mySpell->id, 0)); std::vector<std::shared_ptr<CComponent>> hlp(1, std::make_shared<CComponent>(CComponent::spell, mySpell->id, 0));
owner->myInt->showInfoDialog(mySpell->getLevelInfo(schoolLevel).description, hlp); owner->myInt->showInfoDialog(mySpell->getLevelInfo(schoolLevel).description, hlp);
} }
else if(combatSpell) else if(combatSpell)
@ -607,8 +600,7 @@ void CSpellWindow::SpellArea::clickRight(tribool down, bool previousState)
boost::algorithm::replace_first(dmgInfo, "%d", boost::lexical_cast<std::string>(causedDmg)); boost::algorithm::replace_first(dmgInfo, "%d", boost::lexical_cast<std::string>(causedDmg));
} }
CRClickPopup::createAndPush(mySpell->getLevelInfo(schoolLevel).description + dmgInfo, CRClickPopup::createAndPush(mySpell->getLevelInfo(schoolLevel).description + dmgInfo, std::make_shared<CComponent>(CComponent::spell, mySpell->id));
new CComponent(CComponent::spell, mySpell->id));
} }
} }
@ -623,20 +615,9 @@ void CSpellWindow::SpellArea::hover(bool on)
} }
} }
void CSpellWindow::SpellArea::showAll(SDL_Surface * to)
{
if(mySpell)
{
//printing border (indicates level of magic school)
if(schoolBorder)
schoolBorder->draw(to, pos.x, pos.y);
CIntObject::showAll(to);
}
}
void CSpellWindow::SpellArea::setSpell(const CSpell * spell) void CSpellWindow::SpellArea::setSpell(const CSpell * spell)
{ {
schoolBorder = nullptr; schoolBorder.reset();
image->visible = false; image->visible = false;
name->setText(""); name->setText("");
level->setText(""); level->setText("");
@ -644,12 +625,17 @@ void CSpellWindow::SpellArea::setSpell(const CSpell * spell)
mySpell = spell; mySpell = spell;
if(mySpell) if(mySpell)
{ {
int whichSchool = 0; //0 - air magic, 1 - fire magic, 2 - water magic, 3 - earth magic,
schoolLevel = owner->myHero->getSpellSchoolLevel(mySpell, &whichSchool); schoolLevel = owner->myHero->getSpellSchoolLevel(mySpell, &whichSchool);
spellCost = owner->myInt->cb->getSpellCost(mySpell, owner->myHero); auto spellCost = owner->myInt->cb->getSpellCost(mySpell, owner->myHero);
image->setFrame(mySpell->id); image->setFrame(mySpell->id);
image->visible = true; image->visible = true;
schoolBorder = owner->schoolBorders[owner->selectedTab >= 4 ? whichSchool : owner->selectedTab]->getImage(schoolLevel,0);
{
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
schoolBorder = std::make_shared<CAnimImage>(owner->schoolBorders[owner->selectedTab >= 4 ? whichSchool : owner->selectedTab], schoolLevel);
}
SDL_Color firstLineColor, secondLineColor; SDL_Color firstLineColor, secondLineColor;
if(spellCost > owner->myHero->mana) //hero cannot cast this spell if(spellCost > owner->myHero->mana) //hero cannot cast this spell

View File

@ -30,12 +30,12 @@ class CSpellWindow : public CWindowObject
{ {
const CSpell * mySpell; const CSpell * mySpell;
int schoolLevel; //range: 0 none, 3 - expert int schoolLevel; //range: 0 none, 3 - expert
int whichSchool; //0 - air magic, 1 - fire magic, 2 - water magic, 3 - earth magic,
int spellCost;
CSpellWindow * owner; CSpellWindow * owner;
CAnimImage * image; std::shared_ptr<CAnimImage> image;
IImage * schoolBorder; std::shared_ptr<CAnimImage> schoolBorder;
CLabel * name, * level, * cost; std::shared_ptr<CLabel> name;
std::shared_ptr<CLabel> level;
std::shared_ptr<CLabel> cost;
public: public:
SpellArea(SDL_Rect pos, CSpellWindow * owner); SpellArea(SDL_Rect pos, CSpellWindow * owner);
~SpellArea(); ~SpellArea();
@ -44,7 +44,6 @@ class CSpellWindow : public CWindowObject
void clickLeft(tribool down, bool previousState) override; void clickLeft(tribool down, bool previousState) override;
void clickRight(tribool down, bool previousState) override; void clickRight(tribool down, bool previousState) override;
void hover(bool on) override; void hover(bool on) override;
void showAll(SDL_Surface * to) override;
}; };
class InteractiveArea : public CIntObject class InteractiveArea : public CIntObject
@ -62,17 +61,20 @@ class CSpellWindow : public CWindowObject
InteractiveArea(const SDL_Rect & myRect, std::function<void()> funcL, int helpTextId, CSpellWindow * _owner); InteractiveArea(const SDL_Rect & myRect, std::function<void()> funcL, int helpTextId, CSpellWindow * _owner);
}; };
CPicture * leftCorner, * rightCorner; std::shared_ptr<CAnimation> spellIcons;
std::array<std::shared_ptr<CAnimation>, 4> schoolBorders; //[0]: air, [1]: fire, [2]: water, [3]: earth
std::shared_ptr<CAnimation> spells; //pictures of spells std::shared_ptr<CPicture> leftCorner;
std::shared_ptr<CPicture> rightCorner;
CAnimImage * spellTab; //school select std::shared_ptr<CAnimImage> schoolTab;
CAnimImage * schools; //schools' pictures std::shared_ptr<CAnimImage> schoolPicture;
std::array< std::shared_ptr<CAnimation>, 4> schoolBorders; //schools' 'borders': [0]: air, [1]: fire, [2]: water, [3]: earth
SpellArea * spellAreas[12]; std::array<std::shared_ptr<SpellArea>, 12> spellAreas;
CLabel * mana; std::shared_ptr<CLabel> mana;
CGStatusBar * statusBar; std::shared_ptr<CGStatusBar> statusBar;
std::vector<std::shared_ptr<InteractiveArea>> interactiveAreas;
int sitesPerTabAdv[5]; int sitesPerTabAdv[5];
int sitesPerTabBattle[5]; int sitesPerTabBattle[5];

View File

@ -31,34 +31,35 @@
#include "../../lib/mapObjects/CGTownInstance.h" #include "../../lib/mapObjects/CGTownInstance.h"
#include "../../lib/mapObjects/CGMarket.h" #include "../../lib/mapObjects/CGMarket.h"
CTradeWindow::CTradeableItem::CTradeableItem(Point pos, EType Type, int ID, bool Left, int Serial): CTradeWindow::CTradeableItem::CTradeableItem(Point pos, EType Type, int ID, bool Left, int Serial)
CIntObject(LCLICK | HOVER | RCLICK, pos), : CIntObject(LCLICK | HOVER | RCLICK, pos),
type(EType(-1)),// set to invalid, will be corrected in setType type(EType(-1)),// set to invalid, will be corrected in setType
id(ID), id(ID),
serial(Serial), serial(Serial),
left(Left) left(Left)
{ {
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
downSelection = false; downSelection = false;
hlp = nullptr; hlp = nullptr;
image = nullptr;
setType(Type); setType(Type);
} }
void CTradeWindow::CTradeableItem::setType(EType newType) void CTradeWindow::CTradeableItem::setType(EType newType)
{ {
if (type != newType) if(type != newType)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
type = newType; type = newType;
delete image;
if (getIndex() < 0) if(getIndex() < 0)
{ {
image = new CAnimImage(getFilename(), 0); image = std::make_shared<CAnimImage>(getFilename(), 0);
image->disable(); image->disable();
} }
else else
image = new CAnimImage(getFilename(), getIndex()); {
image = std::make_shared<CAnimImage>(getFilename(), getIndex());
}
} }
} }
@ -177,11 +178,11 @@ void CTradeWindow::CTradeableItem::clickLeft(tribool down, bool previousState)
CAltarWindow *aw = static_cast<CAltarWindow *>(mw); CAltarWindow *aw = static_cast<CAltarWindow *>(mw);
if(const CArtifactInstance *movedArt = aw->arts->commonInfo->src.art) if(const CArtifactInstance *movedArt = aw->arts->commonInfo->src.art)
{ {
aw->moveFromSlotToAltar(aw->arts->commonInfo->src.slotID, this, movedArt); aw->moveFromSlotToAltar(aw->arts->commonInfo->src.slotID, this->shared_from_this(), movedArt);
} }
else if(const CArtifactInstance *art = getArtInstance()) else if(const CArtifactInstance *art = getArtInstance())
{ {
aw->arts->commonInfo->src.AOH = aw->arts; aw->arts->commonInfo->src.AOH = aw->arts.get();
aw->arts->commonInfo->src.art = art; aw->arts->commonInfo->src.art = art;
aw->arts->commonInfo->src.slotID = aw->hero->getArtPos(art); aw->arts->commonInfo->src.slotID = aw->hero->getArtPos(art);
aw->arts->markPossibleSlots(art); aw->arts->markPossibleSlots(art);
@ -200,15 +201,15 @@ void CTradeWindow::CTradeableItem::clickLeft(tribool down, bool previousState)
} }
if(left) if(left)
{ {
if(mw->hLeft != this) if(mw->hLeft != this->shared_from_this())
mw->hLeft = this; mw->hLeft = this->shared_from_this();
else else
return; return;
} }
else else
{ {
if(mw->hRight != this) if(mw->hRight != this->shared_from_this())
mw->hRight = this; mw->hRight = this->shared_from_this();
else else
return; return;
} }
@ -301,7 +302,7 @@ const CArtifactInstance * CTradeWindow::CTradeableItem::getArtInstance() const
{ {
case ARTIFACT_PLACEHOLDER: case ARTIFACT_PLACEHOLDER:
case ARTIFACT_INSTANCE: case ARTIFACT_INSTANCE:
return (const CArtifactInstance *)hlp; return hlp;
default: default:
return nullptr; return nullptr;
} }
@ -321,15 +322,10 @@ CTradeWindow::CTradeWindow(std::string bgName, const IMarket *Market, const CGHe
CWindowObject(PLAYER_COLORED, bgName), CWindowObject(PLAYER_COLORED, bgName),
market(Market), market(Market),
hero(Hero), hero(Hero),
arts(nullptr),
hLeft(nullptr),
hRight(nullptr),
ok(nullptr),
max(nullptr),
deal(nullptr),
slider(nullptr),
readyToTrade(false) readyToTrade(false)
{ {
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
type |= BLOCK_ADV_HOTKEYS; type |= BLOCK_ADV_HOTKEYS;
mode = Mode; mode = Mode;
initTypes(); initTypes();
@ -372,6 +368,8 @@ void CTradeWindow::initTypes()
void CTradeWindow::initItems(bool Left) void CTradeWindow::initItems(bool Left)
{ {
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
if(Left && (itemsType[1] == ARTIFACT_TYPE || itemsType[1] == ARTIFACT_INSTANCE)) if(Left && (itemsType[1] == ARTIFACT_TYPE || itemsType[1] == ARTIFACT_INSTANCE))
{ {
int xOffset = 0, yOffset = 0; int xOffset = 0, yOffset = 0;
@ -380,9 +378,9 @@ void CTradeWindow::initItems(bool Left)
xOffset = -361; xOffset = -361;
yOffset = +46; yOffset = +46;
auto hlp = new CTradeableItem(Point(137, 469), itemsType[Left], -1, 1, 0); auto item = std::make_shared<CTradeableItem>(Point(137, 469), itemsType[Left], -1, 1, 0);
hlp->recActions &= ~(UPDATE | SHOWALL); item->recActions &= ~(UPDATE | SHOWALL);
items[Left].push_back(hlp); items[Left].push_back(item);
} }
else //ARTIFACT_EXP else //ARTIFACT_EXP
{ {
@ -390,47 +388,44 @@ void CTradeWindow::initItems(bool Left)
yOffset = -12; yOffset = -12;
} }
BLOCK_CAPTURING; arts = std::make_shared<CArtifactsOfHero>(Point(xOffset, yOffset), true);
arts = new CArtifactsOfHero(Point(pos.x+xOffset, pos.y+yOffset)); arts->recActions = 255-DISPOSE;
arts->commonInfo = std::make_shared<CArtifactsOfHero::SCommonPart>();
arts->commonInfo->participants.insert(arts);
arts->recActions = 255;
arts->setHero(hero); arts->setHero(hero);
arts->allowedAssembling = false; arts->allowedAssembling = false;
addChild(arts); addSet(arts);
artSets.push_back(arts);
if(mode == EMarketMode::ARTIFACT_RESOURCE) if(mode == EMarketMode::ARTIFACT_RESOURCE)
arts->highlightModeCallback = std::bind(&CTradeWindow::artifactSelected, this, _1); arts->highlightModeCallback = std::bind(&CTradeWindow::artifactSelected, this, _1);
return;
} }
std::vector<int> *ids = getItemsIds(Left);
std::vector<Rect> pos;
int amount = -1;
getPositionsFor(pos, Left, itemsType[Left]);
if(Left || !ids)
amount = 7;
else else
amount = ids->size();
if(ids)
vstd::amin(amount, ids->size());
for(int j=0; j<amount; j++)
{ {
int id = (ids && ids->size()>j) ? (*ids)[j] : j; std::vector<int> *ids = getItemsIds(Left);
if(id < 0 && mode != EMarketMode::ARTIFACT_EXP) //when sacrificing artifacts we need to prepare empty slots std::vector<Rect> pos;
continue; int amount = -1;
auto hlp = new CTradeableItem(pos[j].topLeft(), itemsType[Left], id, Left, j); getPositionsFor(pos, Left, itemsType[Left]);
hlp->pos = pos[j] + this->pos.topLeft();
items[Left].push_back(hlp); if(Left || !ids)
amount = 7;
else
amount = ids->size();
if(ids)
vstd::amin(amount, ids->size());
for(int j=0; j<amount; j++)
{
int id = (ids && ids->size()>j) ? (*ids)[j] : j;
if(id < 0 && mode != EMarketMode::ARTIFACT_EXP) //when sacrificing artifacts we need to prepare empty slots
continue;
auto item = std::make_shared<CTradeableItem>(pos[j].topLeft(), itemsType[Left], id, Left, j);
item->pos = pos[j] + this->pos.topLeft();
items[Left].push_back(item);
}
vstd::clear_pointer(ids);
initSubs(Left);
} }
vstd::clear_pointer(ids);
initSubs(Left);
} }
std::vector<int> *CTradeWindow::getItemsIds(bool Left) std::vector<int> *CTradeWindow::getItemsIds(bool Left)
@ -523,17 +518,17 @@ void CTradeWindow::getPositionsFor(std::vector<Rect> &poss, bool Left, EType typ
void CTradeWindow::initSubs(bool Left) void CTradeWindow::initSubs(bool Left)
{ {
for(CTradeableItem *t : items[Left]) for(auto item : items[Left])
{ {
if(Left) if(Left)
{ {
switch(itemsType[1]) switch(itemsType[1])
{ {
case CREATURE: case CREATURE:
t->subtitle = boost::lexical_cast<std::string>(hero->getStackCount(SlotID(t->serial))); item->subtitle = boost::lexical_cast<std::string>(hero->getStackCount(SlotID(item->serial)));
break; break;
case RESOURCE: case RESOURCE:
t->subtitle = boost::lexical_cast<std::string>(LOCPLINT->cb->getResourceAmount(static_cast<Res::ERes>(t->serial))); item->subtitle = boost::lexical_cast<std::string>(LOCPLINT->cb->getResourceAmount(static_cast<Res::ERes>(item->serial)));
break; break;
} }
} }
@ -541,25 +536,25 @@ void CTradeWindow::initSubs(bool Left)
{ {
if(itemsType[0] == PLAYER) if(itemsType[0] == PLAYER)
{ {
t->subtitle = CGI->generaltexth->capColors[t->id]; item->subtitle = CGI->generaltexth->capColors[item->id];
} }
else if(hLeft)//artifact, creature else if(hLeft)//artifact, creature
{ {
int h1, h2; //hlp variables for getting offer int h1, h2; //hlp variables for getting offer
market->getOffer(hLeft->id, t->id, h1, h2, mode); market->getOffer(hLeft->id, item->id, h1, h2, mode);
if(t->id != hLeft->id || mode != EMarketMode::RESOURCE_RESOURCE) //don't allow exchanging same resources if(item->id != hLeft->id || mode != EMarketMode::RESOURCE_RESOURCE) //don't allow exchanging same resources
{ {
std::ostringstream oss; std::ostringstream oss;
oss << h2; oss << h2;
if(h1!=1) if(h1!=1)
oss << "/" << h1; oss << "/" << h1;
t->subtitle = oss.str(); item->subtitle = oss.str();
} }
else else
t->subtitle = CGI->generaltexth->allTexts[164]; // n/a item->subtitle = CGI->generaltexth->allTexts[164]; // n/a
} }
else else
t->subtitle = ""; item->subtitle = "";
} }
} }
} }
@ -569,9 +564,9 @@ void CTradeWindow::showAll(SDL_Surface * to)
CWindowObject::showAll(to); CWindowObject::showAll(to);
if(hRight) if(hRight)
CSDL_Ext::drawBorder(to,hRight->pos.x-1,hRight->pos.y-1,hRight->pos.w+2,hRight->pos.h+2,int3(255,231,148)); CSDL_Ext::drawBorder(to, hRight->pos.x-1, hRight->pos.y-1, hRight->pos.w+2, hRight->pos.h+2, int3(255,231,148));
if(hLeft && hLeft->type != ARTIFACT_INSTANCE) if(hLeft && hLeft->type != ARTIFACT_INSTANCE)
CSDL_Ext::drawBorder(to,hLeft->pos.x-1,hLeft->pos.y-1,hLeft->pos.w+2,hLeft->pos.h+2,int3(255,231,148)); CSDL_Ext::drawBorder(to, hLeft->pos.x-1, hLeft->pos.y-1, hLeft->pos.w+2, hLeft->pos.h+2, int3(255,231,148));
if(readyToTrade) if(readyToTrade)
{ {
@ -582,29 +577,28 @@ void CTradeWindow::showAll(SDL_Surface * to)
} }
} }
void CTradeWindow::removeItems(const std::set<CTradeableItem *> &toRemove) void CTradeWindow::removeItems(const std::set<std::shared_ptr<CTradeableItem>> & toRemove)
{ {
for(CTradeableItem *t : toRemove) for(auto item : toRemove)
removeItem(t); removeItem(item);
} }
void CTradeWindow::removeItem(CTradeableItem * t) void CTradeWindow::removeItem(std::shared_ptr<CTradeableItem> item)
{ {
items[t->left] -= t; items[item->left] -= item;
delete t;
if(hRight == t) if(hRight == item)
{ {
hRight = nullptr; hRight.reset();
selectionChanged(false); selectionChanged(false);
} }
} }
void CTradeWindow::getEmptySlots(std::set<CTradeableItem *> &toRemove) void CTradeWindow::getEmptySlots(std::set<std::shared_ptr<CTradeableItem>> & toRemove)
{ {
for(CTradeableItem *t : items[1]) for(auto item : items[1])
if(!hero->getStackCount(SlotID(t->serial))) if(!hero->getStackCount(SlotID(item->serial)))
toRemove.insert(t); toRemove.insert(item);
} }
void CTradeWindow::setMode(EMarketMode::EMarketMode Mode) void CTradeWindow::setMode(EMarketMode::EMarketMode Mode)
@ -660,35 +654,36 @@ std::string CMarketplaceWindow::getBackgroundForMode(EMarketMode::EMarketMode mo
return ""; return "";
} }
CMarketplaceWindow::CMarketplaceWindow(const IMarket *Market, const CGHeroInstance *Hero, EMarketMode::EMarketMode Mode) CMarketplaceWindow::CMarketplaceWindow(const IMarket * Market, const CGHeroInstance * Hero, EMarketMode::EMarketMode Mode)
: CTradeWindow(getBackgroundForMode(Mode), Market, Hero, Mode) : CTradeWindow(getBackgroundForMode(Mode), Market, Hero, Mode)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
madeTransaction = false; madeTransaction = false;
bool sliderNeeded = true; bool sliderNeeded = true;
new CGStatusBar(new CPicture(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26)); statusBar = std::make_shared<CGStatusBar>(std::make_shared<CPicture>(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
std::string title; std::string title;
if (market->o->ID == Obj::TOWN) if(market->o->ID == Obj::TOWN)
{ {
switch (mode) switch (mode)
{ {
break; case EMarketMode::CREATURE_RESOURCE: case EMarketMode::CREATURE_RESOURCE:
title = CGI->townh->factions[ETownType::STRONGHOLD]->town->buildings[BuildingID::FREELANCERS_GUILD]->Name(); title = CGI->townh->factions[ETownType::STRONGHOLD]->town->buildings[BuildingID::FREELANCERS_GUILD]->Name();
break;
break; case EMarketMode::RESOURCE_ARTIFACT: case EMarketMode::RESOURCE_ARTIFACT:
title = CGI->townh->factions[market->o->subID]->town->buildings[BuildingID::ARTIFACT_MERCHANT]->Name(); title = CGI->townh->factions[market->o->subID]->town->buildings[BuildingID::ARTIFACT_MERCHANT]->Name();
sliderNeeded = false; sliderNeeded = false;
break;
break; case EMarketMode::ARTIFACT_RESOURCE: case EMarketMode::ARTIFACT_RESOURCE:
title = CGI->townh->factions[market->o->subID]->town->buildings[BuildingID::ARTIFACT_MERCHANT]->Name(); title = CGI->townh->factions[market->o->subID]->town->buildings[BuildingID::ARTIFACT_MERCHANT]->Name();
sliderNeeded = false; sliderNeeded = false;
break;
break; default: default:
title = CGI->generaltexth->allTexts[158]; title = CGI->generaltexth->allTexts[158];
break;
} }
} }
else else
@ -707,55 +702,51 @@ CMarketplaceWindow::CMarketplaceWindow(const IMarket *Market, const CGHeroInstan
break; break;
default: default:
title = market->o->getObjectName(); title = market->o->getObjectName();
break;
} }
} }
new CLabel(300, 27, FONT_BIG, CENTER, Colors::YELLOW, title); titleLabel = std::make_shared<CLabel>(300, 27, FONT_BIG, CENTER, Colors::YELLOW, title);
initItems(false); initItems(false);
initItems(true); initItems(true);
ok = new CButton(Point(516, 520), "IOK6432.DEF", CGI->generaltexth->zelp[600], [&](){ close(); }, SDLK_RETURN); ok = std::make_shared<CButton>(Point(516, 520), "IOK6432.DEF", CGI->generaltexth->zelp[600], [&](){ close(); }, SDLK_RETURN);
ok->assignedKeys.insert(SDLK_ESCAPE); ok->assignedKeys.insert(SDLK_ESCAPE);
deal = new CButton(Point(307, 520), "TPMRKB.DEF", CGI->generaltexth->zelp[595], [&](){ makeDeal(); } ); deal = std::make_shared<CButton>(Point(307, 520), "TPMRKB.DEF", CGI->generaltexth->zelp[595], [&](){ makeDeal(); } );
deal->block(true); deal->block(true);
if(sliderNeeded) if(sliderNeeded)
{ {
slider = new CSlider(Point(231, 490),137, std::bind(&CMarketplaceWindow::sliderMoved,this,_1),0,0); slider = std::make_shared<CSlider>(Point(231, 490),137, std::bind(&CMarketplaceWindow::sliderMoved,this,_1),0,0);
max = new CButton(Point(229, 520), "IRCBTNS.DEF", CGI->generaltexth->zelp[596], [&](){ setMax(); }); max = std::make_shared<CButton>(Point(229, 520), "IRCBTNS.DEF", CGI->generaltexth->zelp[596], [&](){ setMax(); });
max->block(true); max->block(true);
} }
else else
{ {
slider = nullptr;
max = nullptr;
deal->moveBy(Point(-30, 0)); deal->moveBy(Point(-30, 0));
} }
Rect traderTextRect;
//left side //left side
switch(Mode) switch(Mode)
{ {
case EMarketMode::RESOURCE_RESOURCE: case EMarketMode::RESOURCE_RESOURCE:
case EMarketMode::RESOURCE_PLAYER: case EMarketMode::RESOURCE_PLAYER:
case EMarketMode::RESOURCE_ARTIFACT: case EMarketMode::RESOURCE_ARTIFACT:
new CLabel(154, 148, FONT_SMALL, CENTER, Colors::WHITE, CGI->generaltexth->allTexts[270]); labels.push_back(std::make_shared<CLabel>(154, 148, FONT_SMALL, CENTER, Colors::WHITE, CGI->generaltexth->allTexts[270]));
break; break;
case EMarketMode::CREATURE_RESOURCE: case EMarketMode::CREATURE_RESOURCE:
//%s's Creatures //%s's Creatures
new CLabel(152, 102, FONT_SMALL, CENTER, Colors::WHITE, labels.push_back(std::make_shared<CLabel>(152, 102, FONT_SMALL, CENTER, Colors::WHITE, boost::str(boost::format(CGI->generaltexth->allTexts[272]) % hero->name)));
boost::str(boost::format(CGI->generaltexth->allTexts[272]) % hero->name));
break; break;
case EMarketMode::ARTIFACT_RESOURCE: case EMarketMode::ARTIFACT_RESOURCE:
//%s's Artifacts //%s's Artifacts
new CLabel(152, 56, FONT_SMALL, CENTER, Colors::WHITE, labels.push_back(std::make_shared<CLabel>(152, 56, FONT_SMALL, CENTER, Colors::WHITE, boost::str(boost::format(CGI->generaltexth->allTexts[271]) % hero->name)));
boost::str(boost::format(CGI->generaltexth->allTexts[271]) % hero->name));
break; break;
} }
Rect traderTextRect;
//right side //right side
switch(Mode) switch(Mode)
{ {
@ -763,45 +754,33 @@ CMarketplaceWindow::CMarketplaceWindow(const IMarket *Market, const CGHeroInstan
case EMarketMode::CREATURE_RESOURCE: case EMarketMode::CREATURE_RESOURCE:
case EMarketMode::RESOURCE_ARTIFACT: case EMarketMode::RESOURCE_ARTIFACT:
case EMarketMode::ARTIFACT_RESOURCE: case EMarketMode::ARTIFACT_RESOURCE:
new CLabel(445, 148, FONT_SMALL, CENTER, Colors::WHITE, CGI->generaltexth->allTexts[168]); labels.push_back(std::make_shared<CLabel>(445, 148, FONT_SMALL, CENTER, Colors::WHITE, CGI->generaltexth->allTexts[168]));
traderTextRect = Rect(316, 48, 260, 75); traderTextRect = Rect(316, 48, 260, 75);
break; break;
case EMarketMode::RESOURCE_PLAYER: case EMarketMode::RESOURCE_PLAYER:
new CLabel(445, 55, FONT_SMALL, CENTER, Colors::WHITE, CGI->generaltexth->allTexts[169]); labels.push_back(std::make_shared<CLabel>(445, 55, FONT_SMALL, CENTER, Colors::WHITE, CGI->generaltexth->allTexts[169]));
traderTextRect = Rect(28, 48, 260, 75); traderTextRect = Rect(28, 48, 260, 75);
break; break;
} }
traderText = new CTextBox("", traderTextRect, 0, FONT_SMALL, CENTER); traderText = std::make_shared<CTextBox>("", traderTextRect, 0, FONT_SMALL, CENTER);
int specialOffset = mode == EMarketMode::ARTIFACT_RESOURCE ? 35 : 0; //in selling artifacts mode we need to move res-res and art-res buttons down int specialOffset = mode == EMarketMode::ARTIFACT_RESOURCE ? 35 : 0; //in selling artifacts mode we need to move res-res and art-res buttons down
if(printButtonFor(EMarketMode::RESOURCE_PLAYER)) if(printButtonFor(EMarketMode::RESOURCE_PLAYER))
new CButton(Point(18, 520),"TPMRKBU1.DEF", CGI->generaltexth->zelp[612], [&](){ setMode(EMarketMode::RESOURCE_PLAYER);}); buttons.push_back(std::make_shared<CButton>(Point(18, 520),"TPMRKBU1.DEF", CGI->generaltexth->zelp[612], [&](){ setMode(EMarketMode::RESOURCE_PLAYER);}));
if(printButtonFor(EMarketMode::RESOURCE_RESOURCE)) if(printButtonFor(EMarketMode::RESOURCE_RESOURCE))
new CButton(Point(516, 450 + specialOffset),"TPMRKBU5.DEF", CGI->generaltexth->zelp[605], [&](){ setMode(EMarketMode::RESOURCE_RESOURCE);}); buttons.push_back(std::make_shared<CButton>(Point(516, 450 + specialOffset),"TPMRKBU5.DEF", CGI->generaltexth->zelp[605], [&](){ setMode(EMarketMode::RESOURCE_RESOURCE);}));
if(printButtonFor(EMarketMode::CREATURE_RESOURCE)) if(printButtonFor(EMarketMode::CREATURE_RESOURCE))
new CButton(Point(516, 485),"TPMRKBU4.DEF", CGI->generaltexth->zelp[599], [&](){ setMode(EMarketMode::CREATURE_RESOURCE);}); buttons.push_back(std::make_shared<CButton>(Point(516, 485),"TPMRKBU4.DEF", CGI->generaltexth->zelp[599], [&](){ setMode(EMarketMode::CREATURE_RESOURCE);}));
if(printButtonFor(EMarketMode::RESOURCE_ARTIFACT)) if(printButtonFor(EMarketMode::RESOURCE_ARTIFACT))
new CButton(Point(18, 450 + specialOffset),"TPMRKBU2.DEF", CGI->generaltexth->zelp[598], [&](){ setMode(EMarketMode::RESOURCE_ARTIFACT);}); buttons.push_back(std::make_shared<CButton>(Point(18, 450 + specialOffset),"TPMRKBU2.DEF", CGI->generaltexth->zelp[598], [&](){ setMode(EMarketMode::RESOURCE_ARTIFACT);}));
if(printButtonFor(EMarketMode::ARTIFACT_RESOURCE)) if(printButtonFor(EMarketMode::ARTIFACT_RESOURCE))
new CButton(Point(18, 485),"TPMRKBU3.DEF", CGI->generaltexth->zelp[613], [&](){ setMode(EMarketMode::ARTIFACT_RESOURCE);}); buttons.push_back(std::make_shared<CButton>(Point(18, 485),"TPMRKBU3.DEF", CGI->generaltexth->zelp[613], [&](){ setMode(EMarketMode::ARTIFACT_RESOURCE);}));
updateTraderText(); updateTraderText();
} }
CMarketplaceWindow::~CMarketplaceWindow() CMarketplaceWindow::~CMarketplaceWindow() = default;
{
hLeft = hRight = nullptr;
for(auto & elem : items[1])
delete elem;
for(auto & elem : items[0])
delete elem;
items[1].clear();
items[0].clear();
}
void CMarketplaceWindow::setMax() void CMarketplaceWindow::setMax()
{ {
@ -918,10 +897,8 @@ void CMarketplaceWindow::garrisonChanged()
if(mode != EMarketMode::CREATURE_RESOURCE) if(mode != EMarketMode::CREATURE_RESOURCE)
return; return;
std::set<CTradeableItem *> toRemove; std::set<std::shared_ptr<CTradeableItem>> toRemove;
getEmptySlots(toRemove); getEmptySlots(toRemove);
removeItems(toRemove); removeItems(toRemove);
initSubs(true); initSubs(true);
} }
@ -933,10 +910,10 @@ void CMarketplaceWindow::artifactsChanged(bool Left)
return; return;
std::vector<int> available = market->availableItemsIds(mode); std::vector<int> available = market->availableItemsIds(mode);
std::set<CTradeableItem *> toRemove; std::set<std::shared_ptr<CTradeableItem>> toRemove;
for(CTradeableItem *t : items[0]) for(auto item : items[0])
if(!vstd::contains(available, t->id)) if(!vstd::contains(available, item->id))
toRemove.insert(t); toRemove.insert(item);
removeItems(toRemove); removeItems(toRemove);
redraw(); redraw();
@ -1113,93 +1090,88 @@ void CMarketplaceWindow::updateTraderText()
} }
CAltarWindow::CAltarWindow(const IMarket * Market, const CGHeroInstance * Hero, EMarketMode::EMarketMode Mode) CAltarWindow::CAltarWindow(const IMarket * Market, const CGHeroInstance * Hero, EMarketMode::EMarketMode Mode)
:CTradeWindow((Mode == EMarketMode::CREATURE_EXP ? "ALTARMON.bmp" : "ALTRART2.bmp"), Market, Hero, Mode) : CTradeWindow((Mode == EMarketMode::CREATURE_EXP ? "ALTARMON.bmp" : "ALTRART2.bmp"), Market, Hero, Mode)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
if(Mode == EMarketMode::CREATURE_EXP) if(Mode == EMarketMode::CREATURE_EXP)
{ {
//%s's Creatures //%s's Creatures
new CLabel(155, 30, FONT_SMALL, CENTER, Colors::YELLOW, labels.push_back(std::make_shared<CLabel>(155, 30, FONT_SMALL, CENTER, Colors::YELLOW,
boost::str(boost::format(CGI->generaltexth->allTexts[272]) % hero->name)); boost::str(boost::format(CGI->generaltexth->allTexts[272]) % hero->name)));
//Altar of Sacrifice //Altar of Sacrifice
new CLabel(450, 30, FONT_SMALL, CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[479]); labels.push_back(std::make_shared<CLabel>(450, 30, FONT_SMALL, CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[479]));
//To sacrifice creatures, move them from your army on to the Altar and click Sacrifice //To sacrifice creatures, move them from your army on to the Altar and click Sacrifice
new CTextBox(CGI->generaltexth->allTexts[480], Rect(320, 56, 256, 40), 0, FONT_SMALL, CENTER, Colors::YELLOW); new CTextBox(CGI->generaltexth->allTexts[480], Rect(320, 56, 256, 40), 0, FONT_SMALL, CENTER, Colors::YELLOW);
slider = new CSlider(Point(231,481),137,std::bind(&CAltarWindow::sliderMoved,this,_1),0,0); slider = std::make_shared<CSlider>(Point(231,481),137,std::bind(&CAltarWindow::sliderMoved,this,_1),0,0);
max = new CButton(Point(147, 520), "IRCBTNS.DEF", CGI->generaltexth->zelp[578], std::bind(&CSlider::moveToMax, slider)); max = std::make_shared<CButton>(Point(147, 520), "IRCBTNS.DEF", CGI->generaltexth->zelp[578], std::bind(&CSlider::moveToMax, slider));
sacrificedUnits.resize(GameConstants::ARMY_SIZE, 0); sacrificedUnits.resize(GameConstants::ARMY_SIZE, 0);
sacrificeAll = new CButton(Point(393, 520), "ALTARMY.DEF", CGI->generaltexth->zelp[579], std::bind(&CAltarWindow::SacrificeAll,this)); sacrificeAll = std::make_shared<CButton>(Point(393, 520), "ALTARMY.DEF", CGI->generaltexth->zelp[579], std::bind(&CAltarWindow::SacrificeAll,this));
sacrificeBackpack = nullptr;
initItems(true); initItems(true);
mimicCres(); mimicCres();
artIcon = nullptr;
} }
else else
{ {
//Sacrifice artifacts for experience //Sacrifice artifacts for experience
new CLabel(450, 34, FONT_SMALL, CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[477]); labels.push_back(std::make_shared<CLabel>(450, 34, FONT_SMALL, CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[477]));
//%s's Creatures //%s's Creatures
new CLabel(302, 423, FONT_SMALL, CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[478]); labels.push_back(std::make_shared<CLabel>(302, 423, FONT_SMALL, CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[478]));
sacrificeAll = new CButton(Point(393, 520), "ALTFILL.DEF", CGI->generaltexth->zelp[571], std::bind(&CAltarWindow::SacrificeAll,this)); sacrificeAll = std::make_shared<CButton>(Point(393, 520), "ALTFILL.DEF", CGI->generaltexth->zelp[571], std::bind(&CAltarWindow::SacrificeAll,this));
sacrificeAll->block(hero->artifactsInBackpack.empty() && hero->artifactsWorn.empty()); sacrificeAll->block(hero->artifactsInBackpack.empty() && hero->artifactsWorn.empty());
sacrificeBackpack = new CButton(Point(147, 520), "ALTEMBK.DEF", CGI->generaltexth->zelp[570], std::bind(&CAltarWindow::SacrificeBackpack,this)); sacrificeBackpack = std::make_shared<CButton>(Point(147, 520), "ALTEMBK.DEF", CGI->generaltexth->zelp[570], std::bind(&CAltarWindow::SacrificeBackpack,this));
sacrificeBackpack->block(hero->artifactsInBackpack.empty()); sacrificeBackpack->block(hero->artifactsInBackpack.empty());
slider = nullptr;
max = nullptr;
initItems(true); initItems(true);
initItems(false); initItems(false);
artIcon = new CAnimImage("ARTIFACT", 0, 0, 281, 442); artIcon = std::make_shared<CAnimImage>("ARTIFACT", 0, 0, 281, 442);
artIcon->disable(); artIcon->disable();
} }
//Experience needed to reach next level //Experience needed to reach next level
new CTextBox(CGI->generaltexth->allTexts[475], Rect(15, 415, 125, 50), 0, FONT_SMALL, CENTER, Colors::YELLOW); texts.push_back(std::make_shared<CTextBox>(CGI->generaltexth->allTexts[475], Rect(15, 415, 125, 50), 0, FONT_SMALL, CENTER, Colors::YELLOW));
//Total experience on the Altar //Total experience on the Altar
new CTextBox(CGI->generaltexth->allTexts[476], Rect(15, 495, 125, 40), 0, FONT_SMALL, CENTER, Colors::YELLOW); texts.push_back(std::make_shared<CTextBox>(CGI->generaltexth->allTexts[476], Rect(15, 495, 125, 40), 0, FONT_SMALL, CENTER, Colors::YELLOW));
new CGStatusBar(new CPicture(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26)); statusBar = std::make_shared<CGStatusBar>(std::make_shared<CPicture>(*background, Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
ok = new CButton(Point(516, 520), "IOK6432.DEF", CGI->generaltexth->zelp[568], [&](){ close();}, SDLK_RETURN); ok = std::make_shared<CButton>(Point(516, 520), "IOK6432.DEF", CGI->generaltexth->zelp[568], [&](){ close();}, SDLK_RETURN);
ok->assignedKeys.insert(SDLK_ESCAPE); ok->assignedKeys.insert(SDLK_ESCAPE);
deal = new CButton(Point(269, 520), "ALTSACR.DEF", CGI->generaltexth->zelp[585], std::bind(&CAltarWindow::makeDeal,this)); deal = std::make_shared<CButton>(Point(269, 520), "ALTSACR.DEF", CGI->generaltexth->zelp[585], std::bind(&CAltarWindow::makeDeal,this));
if(Mode == EMarketMode::CREATURE_EXP) if(Mode == EMarketMode::CREATURE_EXP)
{ {
CButton *changeMode = new CButton(Point(516, 421), "ALTART.DEF", CGI->generaltexth->zelp[580], std::bind(&CTradeWindow::setMode,this, EMarketMode::ARTIFACT_EXP)); auto changeMode = std::make_shared<CButton>(Point(516, 421), "ALTART.DEF", CGI->generaltexth->zelp[580], std::bind(&CTradeWindow::setMode,this, EMarketMode::ARTIFACT_EXP));
if (Hero->getAlignment() == ::EAlignment::EVIL) if(Hero->getAlignment() == ::EAlignment::EVIL)
changeMode->block(true); changeMode->block(true);
buttons.push_back(changeMode);
} }
if(Mode == EMarketMode::ARTIFACT_EXP) else if(Mode == EMarketMode::ARTIFACT_EXP)
{ {
CButton *changeMode = new CButton(Point(516, 421), "ALTSACC.DEF", CGI->generaltexth->zelp[572], std::bind(&CTradeWindow::setMode,this, EMarketMode::CREATURE_EXP)); auto changeMode = std::make_shared<CButton>(Point(516, 421), "ALTSACC.DEF", CGI->generaltexth->zelp[572], std::bind(&CTradeWindow::setMode,this, EMarketMode::CREATURE_EXP));
if (Hero->getAlignment() == ::EAlignment::GOOD) if(Hero->getAlignment() == ::EAlignment::GOOD)
changeMode->block(true); changeMode->block(true);
buttons.push_back(changeMode);
} }
expPerUnit.resize(GameConstants::ARMY_SIZE, 0); expPerUnit.resize(GameConstants::ARMY_SIZE, 0);
getExpValues(); getExpValues();
expToLevel = new CLabel(73, 475, FONT_SMALL, CENTER); expToLevel = std::make_shared<CLabel>(73, 475, FONT_SMALL, CENTER);
expOnAltar = new CLabel(73, 543, FONT_SMALL, CENTER); expOnAltar = std::make_shared<CLabel>(73, 543, FONT_SMALL, CENTER);
setExpToLevel(); setExpToLevel();
calcTotalExp(); calcTotalExp();
blockTrade(); blockTrade();
} }
CAltarWindow::~CAltarWindow() CAltarWindow::~CAltarWindow() = default;
{
}
void CAltarWindow::getBaseForPositions(EType type, int &dx, int &dy, int &x, int &y, int &h, int &w, bool Right, int &leftToRightOffset) const void CAltarWindow::getBaseForPositions(EType type, int &dx, int &dy, int &x, int &y, int &h, int &w, bool Right, int &leftToRightOffset) const
{ {
@ -1248,10 +1220,10 @@ void CAltarWindow::makeDeal()
for(int& val : sacrificedUnits) for(int& val : sacrificedUnits)
val = 0; val = 0;
for(CTradeableItem *t : items[0]) for(auto item : items[0])
{ {
t->setType(CREATURE_PLACEHOLDER); item->setType(CREATURE_PLACEHOLDER);
t->subtitle = ""; item->subtitle = "";
} }
} }
else else
@ -1265,10 +1237,10 @@ void CAltarWindow::makeDeal()
LOCPLINT->cb->trade(market->o, mode, positions, {}, {}, hero); LOCPLINT->cb->trade(market->o, mode, positions, {}, {}, hero);
arts->artifactsOnAltar.clear(); arts->artifactsOnAltar.clear();
for(CTradeableItem *t : items[0]) for(auto item : items[0])
{ {
t->setID(-1); item->setID(-1);
t->subtitle = ""; item->subtitle = "";
} }
arts->commonInfo->reset(); arts->commonInfo->reset();
@ -1284,15 +1256,15 @@ void CAltarWindow::SacrificeAll()
if(mode == EMarketMode::CREATURE_EXP) if(mode == EMarketMode::CREATURE_EXP)
{ {
bool movedAnything = false; bool movedAnything = false;
for(CTradeableItem *t : items[1]) for(auto item : items[1])
sacrificedUnits[t->serial] = hero->getStackCount(SlotID(t->serial)); sacrificedUnits[item->serial] = hero->getStackCount(SlotID(item->serial));
sacrificedUnits[items[1].front()->serial]--; sacrificedUnits[items[1].front()->serial]--;
for(CTradeableItem *t : items[0]) for(auto item : items[0])
{ {
updateRight(t); updateRight(item);
if(t->type == CREATURE) if(item->type == CREATURE)
movedAnything = true; movedAnything = true;
} }
@ -1350,13 +1322,14 @@ void CAltarWindow::selectOppositeItem(bool side)
void CAltarWindow::mimicCres() void CAltarWindow::mimicCres()
{ {
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
std::vector<Rect> positions; std::vector<Rect> positions;
getPositionsFor(positions, false, CREATURE); getPositionsFor(positions, false, CREATURE);
for(CTradeableItem *t : items[1]) for(auto item : items[1])
{ {
auto hlp = new CTradeableItem(positions[t->serial].topLeft(), CREATURE_PLACEHOLDER, t->id, false, t->serial); auto hlp = std::make_shared<CTradeableItem>(positions[item->serial].topLeft(), CREATURE_PLACEHOLDER, item->id, false, item->serial);
hlp->pos = positions[t->serial] + this->pos.topLeft(); hlp->pos = positions[item->serial] + this->pos.topLeft();
items[0].push_back(hlp); items[0].push_back(hlp);
} }
} }
@ -1389,7 +1362,7 @@ void CAltarWindow::garrisonChanged()
if(mode != EMarketMode::CREATURE_EXP) if(mode != EMarketMode::CREATURE_EXP)
return; return;
std::set<CTradeableItem *> empty; std::set<std::shared_ptr<CTradeableItem>> empty;
getEmptySlots(empty); getEmptySlots(empty);
removeItems(empty); removeItems(empty);
@ -1401,9 +1374,11 @@ void CAltarWindow::garrisonChanged()
void CAltarWindow::getExpValues() void CAltarWindow::getExpValues()
{ {
int dump; int dump;
for(CTradeableItem *t : items[1]) for(auto item : items[1])
if(t->id >= 0) {
market->getOffer(t->id, 0, dump, expPerUnit[t->serial], EMarketMode::CREATURE_EXP); if(item->id >= 0)
market->getOffer(item->id, 0, dump, expPerUnit[item->serial], EMarketMode::CREATURE_EXP);
}
} }
void CAltarWindow::calcTotalExp() void CAltarWindow::calcTotalExp()
@ -1446,7 +1421,7 @@ void CAltarWindow::blockTrade()
deal->block(true); deal->block(true);
} }
void CAltarWindow::updateRight(CTradeableItem *toUpdate) void CAltarWindow::updateRight(std::shared_ptr<CTradeableItem> toUpdate)
{ {
int val = sacrificedUnits[toUpdate->serial]; int val = sacrificedUnits[toUpdate->serial];
toUpdate->setType(val ? CREATURE : CREATURE_PLACEHOLDER); toUpdate->setType(val ? CREATURE : CREATURE_PLACEHOLDER);
@ -1500,7 +1475,7 @@ void CAltarWindow::showAll(SDL_Surface * to)
} }
} }
bool CAltarWindow::putOnAltar(CTradeableItem* altarSlot, const CArtifactInstance *art) bool CAltarWindow::putOnAltar(std::shared_ptr<CTradeableItem> altarSlot, const CArtifactInstance *art)
{ {
if(!art->artType->isTradable()) //special art if(!art->artType->isTradable()) //special art
{ {
@ -1531,13 +1506,13 @@ bool CAltarWindow::putOnAltar(CTradeableItem* altarSlot, const CArtifactInstance
return true; return true;
} }
void CAltarWindow::moveFromSlotToAltar(ArtifactPosition slotID, CTradeableItem* altarSlot, const CArtifactInstance *art) void CAltarWindow::moveFromSlotToAltar(ArtifactPosition slotID, std::shared_ptr<CTradeableItem> altarSlot, const CArtifactInstance *art)
{ {
auto freeBackpackSlot = ArtifactPosition(hero->artifactsInBackpack.size() + GameConstants::BACKPACK_START); auto freeBackpackSlot = ArtifactPosition(hero->artifactsInBackpack.size() + GameConstants::BACKPACK_START);
if(arts->commonInfo->src.art) if(arts->commonInfo->src.art)
{ {
arts->commonInfo->dst.slotID = freeBackpackSlot; arts->commonInfo->dst.slotID = freeBackpackSlot;
arts->commonInfo->dst.AOH = arts; arts->commonInfo->dst.AOH = arts.get();
} }
if(putOnAltar(altarSlot, art)) if(putOnAltar(altarSlot, art))

View File

@ -16,6 +16,7 @@
class IMarket; class IMarket;
class CSlider; class CSlider;
class CTextBox; class CTextBox;
class CGStatusBar;
class CTradeWindow : public CWindowObject, public CWindowWithArtifacts //base for markets and altar of sacrifice class CTradeWindow : public CWindowObject, public CWindowWithArtifacts //base for markets and altar of sacrifice
{ {
@ -24,14 +25,14 @@ public:
{ {
RESOURCE, PLAYER, ARTIFACT_TYPE, CREATURE, CREATURE_PLACEHOLDER, ARTIFACT_PLACEHOLDER, ARTIFACT_INSTANCE RESOURCE, PLAYER, ARTIFACT_TYPE, CREATURE, CREATURE_PLACEHOLDER, ARTIFACT_PLACEHOLDER, ARTIFACT_INSTANCE
}; };
class CTradeableItem : public CIntObject
{
CAnimImage * image;
class CTradeableItem : public CIntObject, public std::enable_shared_from_this<CTradeableItem>
{
std::shared_ptr<CAnimImage> image;
std::string getFilename(); std::string getFilename();
int getIndex(); int getIndex();
public: public:
const CArtifactInstance *hlp; //holds ptr to artifact instance id type artifact const CArtifactInstance * hlp; //holds ptr to artifact instance id type artifact
EType type; EType type;
int id; int id;
const int serial; const int serial;
@ -41,37 +42,43 @@ public:
void setType(EType newType); void setType(EType newType);
void setID(int newID); void setID(int newID);
const CArtifactInstance *getArtInstance() const; const CArtifactInstance * getArtInstance() const;
void setArtInstance(const CArtifactInstance *art); void setArtInstance(const CArtifactInstance * art);
CFunctionList<void()> callback; CFunctionList<void()> callback;
bool downSelection; bool downSelection;
void showAllAt(const Point &dstPos, const std::string &customSub, SDL_Surface * to); void showAllAt(const Point & dstPos, const std::string & customSub, SDL_Surface * to);
void clickRight(tribool down, bool previousState) override; void clickRight(tribool down, bool previousState) override;
void hover (bool on) override; void hover(bool on) override;
void showAll(SDL_Surface * to) override; void showAll(SDL_Surface * to) override;
void clickLeft(tribool down, bool previousState) override; void clickLeft(tribool down, bool previousState) override;
std::string getName(int number = -1) const; std::string getName(int number = -1) const;
CTradeableItem(Point pos, EType Type, int ID, bool Left, int Serial); CTradeableItem(Point pos, EType Type, int ID, bool Left, int Serial);
}; };
const IMarket *market; const IMarket * market;
const CGHeroInstance *hero; const CGHeroInstance * hero;
CArtifactsOfHero *arts; std::shared_ptr<CArtifactsOfHero> arts;
//all indexes: 1 = left, 0 = right //all indexes: 1 = left, 0 = right
std::vector<CTradeableItem*> items[2]; std::array<std::vector<std::shared_ptr<CTradeableItem>>, 2> items;
CTradeableItem *hLeft, *hRight; //highlighted items (nullptr if no highlight)
//highlighted items (nullptr if no highlight)
std::shared_ptr<CTradeableItem> hLeft;
std::shared_ptr<CTradeableItem> hRight;
EType itemsType[2]; EType itemsType[2];
EMarketMode::EMarketMode mode;//0 - res<->res; 1 - res<->plauer; 2 - buy artifact; 3 - sell artifact EMarketMode::EMarketMode mode;
CButton *ok, *max, *deal; std::shared_ptr<CButton> ok;
CSlider *slider; //for choosing amount to be exchanged std::shared_ptr<CButton> max;
std::shared_ptr<CButton> deal;
std::shared_ptr<CSlider> slider; //for choosing amount to be exchanged
bool readyToTrade; bool readyToTrade;
CTradeWindow(std::string bgName, const IMarket *Market, const CGHeroInstance *Hero, EMarketMode::EMarketMode Mode); //c CTradeWindow(std::string bgName, const IMarket * Market, const CGHeroInstance * Hero, EMarketMode::EMarketMode Mode); //c
void showAll(SDL_Surface * to) override; void showAll(SDL_Surface * to) override;
@ -80,9 +87,9 @@ public:
void initItems(bool Left); void initItems(bool Left);
std::vector<int> *getItemsIds(bool Left); //nullptr if default std::vector<int> *getItemsIds(bool Left); //nullptr if default
void getPositionsFor(std::vector<Rect> &poss, bool Left, EType type) const; void getPositionsFor(std::vector<Rect> &poss, bool Left, EType type) const;
void removeItems(const std::set<CTradeableItem *> &toRemove); void removeItems(const std::set<std::shared_ptr<CTradeableItem>> & toRemove);
void removeItem(CTradeableItem * t); void removeItem(std::shared_ptr<CTradeableItem> item);
void getEmptySlots(std::set<CTradeableItem *> &toRemove); void getEmptySlots(std::set<std::shared_ptr<CTradeableItem>> & toRemove);
void setMode(EMarketMode::EMarketMode Mode); //mode setter void setMode(EMarketMode::EMarketMode Mode); //mode setter
void artifactSelected(CHeroArtPlace *slot); //used when selling artifacts -> called when user clicked on artifact slot void artifactSelected(CHeroArtPlace *slot); //used when selling artifacts -> called when user clicked on artifact slot
@ -93,29 +100,35 @@ public:
virtual std::string selectionSubtitle(bool Left) const = 0; virtual std::string selectionSubtitle(bool Left) const = 0;
virtual void garrisonChanged() = 0; virtual void garrisonChanged() = 0;
virtual void artifactsChanged(bool left) = 0; virtual void artifactsChanged(bool left) = 0;
protected:
std::shared_ptr<CGStatusBar> statusBar;
std::vector<std::shared_ptr<CLabel>> labels;
std::vector<std::shared_ptr<CButton>> buttons;
std::vector<std::shared_ptr<CTextBox>> texts;
}; };
class CMarketplaceWindow : public CTradeWindow class CMarketplaceWindow : public CTradeWindow
{ {
std::shared_ptr<CLabel> titleLabel;
bool printButtonFor(EMarketMode::EMarketMode M) const; bool printButtonFor(EMarketMode::EMarketMode M) const;
std::string getBackgroundForMode(EMarketMode::EMarketMode mode); std::string getBackgroundForMode(EMarketMode::EMarketMode mode);
public: public:
int r1, r2; //suggested amounts of traded resources int r1, r2; //suggested amounts of traded resources
bool madeTransaction; //if player made at least one transaction bool madeTransaction; //if player made at least one transaction
CTextBox *traderText; std::shared_ptr<CTextBox> traderText;
void setMax(); void setMax();
void sliderMoved(int to); void sliderMoved(int to);
void makeDeal(); void makeDeal();
void selectionChanged(bool side) override; //true == left void selectionChanged(bool side) override; //true == left
CMarketplaceWindow(const IMarket *Market, const CGHeroInstance *Hero = nullptr, EMarketMode::EMarketMode Mode = EMarketMode::RESOURCE_RESOURCE); CMarketplaceWindow(const IMarket * Market, const CGHeroInstance * Hero = nullptr, EMarketMode::EMarketMode Mode = EMarketMode::RESOURCE_RESOURCE);
~CMarketplaceWindow(); ~CMarketplaceWindow();
Point selectionOffset(bool Left) const override; Point selectionOffset(bool Left) const override;
std::string selectionSubtitle(bool Left) const override; std::string selectionSubtitle(bool Left) const override;
void garrisonChanged() override; //removes creatures with count 0 from the list (apparently whole stack has been sold) void garrisonChanged() override; //removes creatures with count 0 from the list (apparently whole stack has been sold)
void artifactsChanged(bool left) override; void artifactsChanged(bool left) override;
void resourceChanged(); void resourceChanged();
@ -126,19 +139,20 @@ public:
class CAltarWindow : public CTradeWindow class CAltarWindow : public CTradeWindow
{ {
CAnimImage * artIcon; std::shared_ptr<CAnimImage> artIcon;
public: public:
CAltarWindow(const IMarket *Market, const CGHeroInstance *Hero, EMarketMode::EMarketMode Mode); std::vector<int> sacrificedUnits; //[slot_nr] -> how many creatures from that slot will be sacrificed
std::vector<int> expPerUnit;
void getExpValues(); std::shared_ptr<CButton> sacrificeAll;
std::shared_ptr<CButton> sacrificeBackpack;
std::shared_ptr<CLabel> expToLevel;
std::shared_ptr<CLabel> expOnAltar;
CAltarWindow(const IMarket * Market, const CGHeroInstance * Hero, EMarketMode::EMarketMode Mode);
~CAltarWindow(); ~CAltarWindow();
std::vector<int> sacrificedUnits, //[slot_nr] -> how many creatures from that slot will be sacrificed void getExpValues();
expPerUnit;
CButton *sacrificeAll, *sacrificeBackpack;
CLabel *expToLevel, *expOnAltar;
void selectionChanged(bool side) override; //true == left void selectionChanged(bool side) override; //true == left
void selectOppositeItem(bool side); void selectOppositeItem(bool side);
@ -146,7 +160,7 @@ public:
void SacrificeBackpack(); void SacrificeBackpack();
void putOnAltar(int backpackIndex); void putOnAltar(int backpackIndex);
bool putOnAltar(CTradeableItem* altarSlot, const CArtifactInstance *art); bool putOnAltar(std::shared_ptr<CTradeableItem> altarSlot, const CArtifactInstance * art);
void makeDeal(); void makeDeal();
void showAll(SDL_Surface * to) override; void showAll(SDL_Surface * to) override;
@ -161,9 +175,9 @@ public:
void artifactsChanged(bool left) override; void artifactsChanged(bool left) override;
void calcTotalExp(); void calcTotalExp();
void setExpToLevel(); void setExpToLevel();
void updateRight(CTradeableItem *toUpdate); void updateRight(std::shared_ptr<CTradeableItem> toUpdate);
void artifactPicked(); void artifactPicked();
int firstFreeSlot(); int firstFreeSlot();
void moveFromSlotToAltar(ArtifactPosition slotID, CTradeableItem* altarSlot, const CArtifactInstance *art); void moveFromSlotToAltar(ArtifactPosition slotID, std::shared_ptr<CTradeableItem>, const CArtifactInstance * art);
}; };

View File

@ -34,13 +34,15 @@
#include "../../lib/CGeneralTextHandler.h" //for Unicode related stuff #include "../../lib/CGeneralTextHandler.h" //for Unicode related stuff
CWindowObject::CWindowObject(int options_, std::string imageName, Point centerAt): CWindowObject::CWindowObject(int options_, std::string imageName, Point centerAt):
CIntObject(getUsedEvents(options_), Point()), CIntObject(getUsedEvents(options_), Point()),
shadow(nullptr), shadow(nullptr),
options(options_), options(options_),
background(createBg(imageName, options & PLAYER_COLORED)) background(createBg(imageName, options & PLAYER_COLORED))
{ {
assert(parent == nullptr); //Safe to remove, but windows should not have parent assert(parent == nullptr); //Safe to remove, but windows should not have parent
defActions = 255-DISPOSE;
if (options & RCLICK_POPUP) if (options & RCLICK_POPUP)
CCS->curh->hide(); CCS->curh->hide();
@ -54,51 +56,48 @@ CWindowObject::CWindowObject(int options_, std::string imageName, Point centerAt
} }
CWindowObject::CWindowObject(int options_, std::string imageName): CWindowObject::CWindowObject(int options_, std::string imageName):
CIntObject(getUsedEvents(options_), Point()), CIntObject(getUsedEvents(options_), Point()),
shadow(nullptr), options(options_),
options(options_), background(createBg(imageName, options_ & PLAYER_COLORED))
background(createBg(imageName, options & PLAYER_COLORED))
{ {
assert(parent == nullptr); //Safe to remove, but windows should not have parent assert(parent == nullptr); //Safe to remove, but windows should not have parent
if (options & RCLICK_POPUP) defActions = 255-DISPOSE;
if(options & RCLICK_POPUP)
CCS->curh->hide(); CCS->curh->hide();
if (background) if(background)
pos = background->center(); pos = background->center();
else else
center(Point(screen->w/2, screen->h/2)); center(Point(screen->w/2, screen->h/2));
if (!(options & SHADOW_DISABLED)) if(!(options & SHADOW_DISABLED))
setShadow(true); setShadow(true);
} }
CWindowObject::~CWindowObject() CWindowObject::~CWindowObject() = default;
{
setShadow(false);
}
CPicture * CWindowObject::createBg(std::string imageName, bool playerColored) std::shared_ptr<CPicture> CWindowObject::createBg(std::string imageName, bool playerColored)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
if (imageName.empty()) if(imageName.empty())
return nullptr; return nullptr;
auto image = new CPicture(imageName); auto image = std::make_shared<CPicture>(imageName);
if (playerColored) if(playerColored)
image->colorize(LOCPLINT->playerID); image->colorize(LOCPLINT->playerID);
return image; return image;
} }
void CWindowObject::setBackground(std::string filename) void CWindowObject::setBackground(std::string filename)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
delete background;
background = createBg(filename, options & PLAYER_COLORED); background = createBg(filename, options & PLAYER_COLORED);
if (background) if(background)
pos = background->center(Point(pos.w/2 + pos.x, pos.h/2 + pos.y)); pos = background->center(Point(pos.w/2 + pos.x, pos.h/2 + pos.y));
updateShadow(); updateShadow();
@ -123,16 +122,16 @@ void CWindowObject::setShadow(bool on)
//size of shadow //size of shadow
static const int size = 8; static const int size = 8;
if (on == bool(shadow)) if(on == bool(shadow))
return; return;
vstd::clear_pointer(shadow); shadow.reset();
//object too small to cast shadow //object too small to cast shadow
if (pos.h <= size || pos.w <= size) if(pos.h <= size || pos.w <= size)
return; return;
if (on) if(on)
{ {
//helper to set last row //helper to set last row
@ -164,7 +163,7 @@ void CWindowObject::setShadow(bool on)
static SDL_Surface * shadowRightTempl = nullptr; static SDL_Surface * shadowRightTempl = nullptr;
//one-time initialization //one-time initialization
if (!shadowCornerTempl) if(!shadowCornerTempl)
{ {
//create "template" surfaces //create "template" surfaces
shadowCornerTempl = CSDL_Ext::createSurfaceWithBpp<4>(size, size); shadowCornerTempl = CSDL_Ext::createSurfaceWithBpp<4>(size, size);
@ -185,8 +184,6 @@ void CWindowObject::setShadow(bool on)
blitAlphaRow(shadowCornerTempl, size-1); blitAlphaRow(shadowCornerTempl, size-1);
} }
OBJ_CONSTRUCTION_CAPTURING_ALL;
//FIXME: do something with this points //FIXME: do something with this points
Point shadowStart; Point shadowStart;
if (options & BORDERED) if (options & BORDERED)
@ -215,10 +212,18 @@ void CWindowObject::setShadow(bool on)
blitAlphaRow(shadowRight, 0); blitAlphaRow(shadowRight, 0);
//generate "shadow" object with these 3 pieces in it //generate "shadow" object with these 3 pieces in it
shadow = new CIntObject(); {
shadow->addChild(new CPicture(shadowCorner, shadowPos.x, shadowPos.y)); OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
shadow->addChild(new CPicture(shadowRight, shadowPos.x, shadowStart.y)); shadow = std::make_shared<CIntObject>();
shadow->addChild(new CPicture(shadowBottom, shadowStart.x, shadowPos.y)); }
{
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255);
shadow->addChild(new CPicture(shadowCorner, shadowPos.x, shadowPos.y));
shadow->addChild(new CPicture(shadowRight, shadowPos.x, shadowStart.y));
shadow->addChild(new CPicture(shadowBottom, shadowStart.x, shadowPos.y));
}
} }
} }

View File

@ -14,26 +14,24 @@
/// Basic class for windows /// Basic class for windows
class CWindowObject : public CIntObject class CWindowObject : public CIntObject
{ {
CPicture * createBg(std::string imageName, bool playerColored); std::shared_ptr<CPicture> createBg(std::string imageName, bool playerColored);
int getUsedEvents(int options); int getUsedEvents(int options);
CIntObject *shadow; std::shared_ptr<CIntObject> shadow;
void setShadow(bool on); void setShadow(bool on);
int options; int options;
protected: protected:
CPicture * background; std::shared_ptr<CPicture> background;
//Simple function with call to GH.popInt //Simple function with call to GH.popInt
void close(); void close();
//Used only if RCLICK_POPUP was set //Used only if RCLICK_POPUP was set
void clickRight(tribool down, bool previousState) override; void clickRight(tribool down, bool previousState) override;
//To display border //To display border
void showAll(SDL_Surface *to) override;
//change or set background image
void setBackground(std::string filename);
void updateShadow(); void updateShadow();
void setBackground(std::string filename);
public: public:
enum EOptions enum EOptions
{ {
@ -51,4 +49,6 @@ public:
CWindowObject(int options, std::string imageName, Point centerAt); CWindowObject(int options, std::string imageName, Point centerAt);
CWindowObject(int options, std::string imageName = ""); CWindowObject(int options, std::string imageName = "");
~CWindowObject(); ~CWindowObject();
void showAll(SDL_Surface * to) override;
}; };

View File

@ -75,7 +75,6 @@ void CreaturePurchaseCard::initCostBox()
cost->createItems(creatureOnTheCard->cost); cost->createItems(creatureOnTheCard->cost);
} }
void CreaturePurchaseCard::sliderMoved(int to) void CreaturePurchaseCard::sliderMoved(int to)
{ {
updateAmountInfo(to); updateAmountInfo(to);

File diff suppressed because it is too large Load Diff

View File

@ -33,53 +33,62 @@ class CToggleButton;
class CToggleGroup; class CToggleGroup;
class CVolumeSlider; class CVolumeSlider;
class CGStatusBar; class CGStatusBar;
class CTextBox;
class CResDataBar;
class CHeroWithMaybePickedArtifact;
/// Recruitment window where you can recruit creatures /// Recruitment window where you can recruit creatures
class CRecruitmentWindow : public CWindowObject class CRecruitmentWindow : public CWindowObject
{ {
class CCreatureCard : public CIntObject class CCreatureCard : public CIntObject, public std::enable_shared_from_this<CCreatureCard>
{ {
CRecruitmentWindow * parent; CRecruitmentWindow * parent;
CCreaturePic *pic; //creature's animation std::shared_ptr<CCreaturePic> animation;
bool selected; bool selected;
void clickLeft(tribool down, bool previousState) override;
void clickRight(tribool down, bool previousState) override;
void showAll(SDL_Surface *to) override;
public: public:
const CCreature * creature; const CCreature * creature;
si32 amount; si32 amount;
void select(bool on); void select(bool on);
CCreatureCard(CRecruitmentWindow * window, const CCreature *crea, int totalAmount); CCreatureCard(CRecruitmentWindow * window, const CCreature * crea, int totalAmount);
void clickLeft(tribool down, bool previousState) override;
void clickRight(tribool down, bool previousState) override;
void showAll(SDL_Surface * to) override;
}; };
std::function<void(CreatureID,int)> onRecruit; //void (int ID, int amount) <-- call to recruit creatures std::function<void(CreatureID,int)> onRecruit; //void (int ID, int amount) <-- call to recruit creatures
int level; int level;
const CArmedInstance *dst; const CArmedInstance * dst;
CCreatureCard * selected; std::shared_ptr<CGStatusBar> statusBar;
std::vector<CCreatureCard *> cards;
CSlider *slider; //for selecting amount std::shared_ptr<CCreatureCard> selected;
CButton *maxButton, *buyButton, *cancelButton; std::vector<std::shared_ptr<CCreatureCard>> cards;
//labels for visible values
CLabel * title;
CLabel * availableValue;
CLabel * toRecruitValue;
CreatureCostBox * costPerTroopValue;
CreatureCostBox * totalCostValue;
void select(CCreatureCard * card); std::shared_ptr<CSlider> slider;
std::shared_ptr<CButton> maxButton;
std::shared_ptr<CButton> buyButton;
std::shared_ptr<CButton> cancelButton;
std::shared_ptr<CLabel> title;
std::shared_ptr<CLabel> availableValue;
std::shared_ptr<CLabel> toRecruitValue;
std::shared_ptr<CLabel> availableTitle;
std::shared_ptr<CLabel> toRecruitTitle;
std::shared_ptr<CreatureCostBox> costPerTroopValue;
std::shared_ptr<CreatureCostBox> totalCostValue;
void select(std::shared_ptr<CCreatureCard> card);
void buy(); void buy();
void sliderMoved(int to); void sliderMoved(int to);
void showAll(SDL_Surface *to) override; void showAll(SDL_Surface * to) override;
public: public:
const CGDwelling * const dwelling; const CGDwelling * const dwelling;
CRecruitmentWindow(const CGDwelling *Dwelling, int Level, const CArmedInstance *Dst, const std::function<void(CreatureID,int)> & Recruit, int y_offset = 0); //creatures - pairs<creature_ID,amount> //c-tor CRecruitmentWindow(const CGDwelling * Dwelling, int Level, const CArmedInstance * Dst, const std::function<void(CreatureID,int)> & Recruit, int y_offset = 0);
void availableCreaturesChanged(); void availableCreaturesChanged();
}; };
@ -92,12 +101,15 @@ class CSplitWindow : public CWindowObject
int leftMin; int leftMin;
int rightMin; int rightMin;
std::shared_ptr<CLabel> title;
std::shared_ptr<CSlider> slider;
std::shared_ptr<CCreaturePic> animLeft;
std::shared_ptr<CCreaturePic> animRight;
std::shared_ptr<CButton> ok;
std::shared_ptr<CButton> cancel;
std::shared_ptr<CTextInput> leftInput;
std::shared_ptr<CTextInput> rightInput;
CSlider *slider;
CCreaturePic *animLeft, *animRight; //creature's animation
CButton *ok, *cancel;
CTextInput *leftInput, *rightInput;
void setAmountText(std::string text, bool left); void setAmountText(std::string text, bool left);
void setAmount(int value, bool left); void setAmount(int value, bool left);
void sliderMoved(int value); void sliderMoved(int value);
@ -110,22 +122,27 @@ public:
* leftMin, rightMin - minimal amount of creatures in each stack * leftMin, rightMin - minimal amount of creatures in each stack
* leftAmount, rightAmount - amount of creatures in each stack * leftAmount, rightAmount - amount of creatures in each stack
*/ */
CSplitWindow(const CCreature * creature, std::function<void(int, int)> callback, CSplitWindow(const CCreature * creature, std::function<void(int, int)> callback, int leftMin, int rightMin, int leftAmount, int rightAmount);
int leftMin, int rightMin, int leftAmount, int rightAmount);
}; };
/// Raised up level windowe where you can select one out of two skills /// Raised up level window where you can select one out of two skills
class CLevelWindow : public CWindowObject class CLevelWindow : public CWindowObject
{ {
CComponentBox * box; //skills to select std::shared_ptr<CAnimImage> portrait;
std::shared_ptr<CButton> ok;
std::shared_ptr<CLabel> mainTitle;
std::shared_ptr<CLabel> levelTitle;
std::shared_ptr<CAnimImage> skillIcon;
std::shared_ptr<CLabel> skillValue;
std::shared_ptr<CComponentBox> box; //skills to select
std::function<void(ui32)> cb; std::function<void(ui32)> cb;
void selectionChanged(unsigned to); void selectionChanged(unsigned to);
public:
public:
CLevelWindow(const CGHeroInstance *hero, PrimarySkill::PrimarySkill pskill, std::vector<SecondarySkill> &skills, std::function<void(ui32)> callback); CLevelWindow(const CGHeroInstance *hero, PrimarySkill::PrimarySkill pskill, std::vector<SecondarySkill> &skills, std::function<void(ui32)> callback);
~CLevelWindow(); ~CLevelWindow();
}; };
/// Town portal, castle gate window /// Town portal, castle gate window
@ -133,27 +150,29 @@ class CObjectListWindow : public CWindowObject
{ {
class CItem : public CIntObject class CItem : public CIntObject
{ {
CObjectListWindow *parent; CObjectListWindow * parent;
CLabel *text; std::shared_ptr<CLabel> text;
CPicture *border; std::shared_ptr<CPicture> border;
public: public:
const size_t index; const size_t index;
CItem(CObjectListWindow *parent, size_t id, std::string text); CItem(CObjectListWindow * parent, size_t id, std::string text);
void select(bool on); void select(bool on);
void clickLeft(tribool down, bool previousState) override; void clickLeft(tribool down, bool previousState) override;
}; };
std::function<void(int)> onSelect;//called when OK button is pressed, returns id of selected item. std::function<void(int)> onSelect;//called when OK button is pressed, returns id of selected item.
CLabel * title; std::shared_ptr<CIntObject> titleWidget;
CLabel * descr; std::shared_ptr<CLabel> title;
std::shared_ptr<CLabel> descr;
CListBox * list; std::shared_ptr<CListBox> list;
CButton *ok, *exit; std::shared_ptr<CButton> ok;
std::shared_ptr<CButton> exit;
std::vector< std::pair<int, std::string> > items;//all items present in list std::vector< std::pair<int, std::string> > items;//all items present in list
void init(CIntObject * titlePic, std::string _title, std::string _descr); void init(std::shared_ptr<CIntObject> titleWidget_, std::string _title, std::string _descr);
void exitPressed(); void exitPressed();
public: public:
size_t selected;//index of currently selected item size_t selected;//index of currently selected item
@ -163,13 +182,10 @@ public:
/// Callback will be called when OK button is pressed, returns id of selected item. initState = initially selected item /// Callback will be called when OK button is pressed, returns id of selected item. initState = initially selected item
/// Image can be nullptr /// Image can be nullptr
///item names will be taken from map objects ///item names will be taken from map objects
CObjectListWindow(const std::vector<int> &_items, CIntObject * titlePic, std::string _title, std::string _descr, CObjectListWindow(const std::vector<int> &_items, std::shared_ptr<CIntObject> titleWidget_, std::string _title, std::string _descr, std::function<void(int)> Callback);
std::function<void(int)> Callback); CObjectListWindow(const std::vector<std::string> &_items, std::shared_ptr<CIntObject> titleWidget_, std::string _title, std::string _descr, std::function<void(int)> Callback);
CObjectListWindow(const std::vector<std::string> &_items, CIntObject * titlePic, std::string _title, std::string _descr, std::shared_ptr<CIntObject> genItem(size_t index);
std::function<void(int)> Callback);
CIntObject *genItem(size_t index);
void elementSelected();//call callback and close this window void elementSelected();//call callback and close this window
void changeSelection(size_t which); void changeSelection(size_t which);
void keyPressed (const SDL_KeyboardEvent & key) override; void keyPressed (const SDL_KeyboardEvent & key) override;
@ -178,23 +194,28 @@ public:
class CSystemOptionsWindow : public CWindowObject class CSystemOptionsWindow : public CWindowObject
{ {
private: private:
CLabel *title; std::shared_ptr<CLabel> title;
CLabelGroup *leftGroup; std::shared_ptr<CLabelGroup> leftGroup;
CLabelGroup *rightGroup; std::shared_ptr<CLabelGroup> rightGroup;
CButton *load, *save, *restart, *mainMenu, *quitGame, *backToMap; //load and restart are not used yet std::shared_ptr<CButton> load;
CToggleGroup * heroMoveSpeed; std::shared_ptr<CButton> save;
CToggleGroup * enemyMoveSpeed; std::shared_ptr<CButton> restart;
CToggleGroup * mapScrollSpeed; std::shared_ptr<CButton> mainMenu;
CVolumeSlider * musicVolume, * effectsVolume; std::shared_ptr<CButton> quitGame;
std::shared_ptr<CButton> backToMap; //load and restart are not used yet
std::shared_ptr<CToggleGroup> heroMoveSpeed;
std::shared_ptr<CToggleGroup> enemyMoveSpeed;
std::shared_ptr<CToggleGroup> mapScrollSpeed;
std::shared_ptr<CVolumeSlider> musicVolume;
std::shared_ptr<CVolumeSlider> effectsVolume;
//CHighlightableButton * showPath; std::shared_ptr<CToggleButton> showReminder;
CToggleButton * showReminder; std::shared_ptr<CToggleButton> quickCombat;
CToggleButton * quickCombat; std::shared_ptr<CToggleButton> spellbookAnim;
CToggleButton * spellbookAnim; std::shared_ptr<CToggleButton> fullscreen;
CToggleButton * fullscreen;
CButton *gameResButton; std::shared_ptr<CButton> gameResButton;
CLabel *gameResLabel; std::shared_ptr<CLabel> gameResLabel;
SettingsListener onFullscreenChanged; SettingsListener onFullscreenChanged;
@ -222,26 +243,39 @@ public:
public: public:
std::string hoverName; std::string hoverName;
std::string description; // "XXX is a level Y ZZZ with N artifacts" std::string description; // "XXX is a level Y ZZZ with N artifacts"
const CGHeroInstance *h; const CGHeroInstance * h;
void clickLeft(tribool down, bool previousState) override; void clickLeft(tribool down, bool previousState) override;
void clickRight(tribool down, bool previousState) override; void clickRight(tribool down, bool previousState) override;
void hover (bool on) override; void hover (bool on) override;
HeroPortrait(int &sel, int id, int x, int y, const CGHeroInstance *H); HeroPortrait(int & sel, int id, int x, int y, const CGHeroInstance * H);
private: private:
int *_sel; int *_sel;
const int _id; const int _id;
} *h1, *h2; //recruitable heroes std::shared_ptr<CAnimImage> portrait;
};
//recruitable heroes
std::shared_ptr<HeroPortrait> h1;
std::shared_ptr<HeroPortrait> h2; //recruitable heroes
int selected;//0 (left) or 1 (right) int selected;//0 (left) or 1 (right)
int oldSelected;//0 (left) or 1 (right) int oldSelected;//0 (left) or 1 (right)
CButton *thiefGuild, *cancel, *recruit; std::shared_ptr<CButton> thiefGuild;
const CGObjectInstance *tavernObj; std::shared_ptr<CButton> cancel;
std::shared_ptr<CButton> recruit;
CTavernWindow(const CGObjectInstance *TavernObj); const CGObjectInstance * tavernObj;
std::shared_ptr<CLabel> title;
std::shared_ptr<CLabel> cost;
std::shared_ptr<CTextBox> rumor;
std::shared_ptr<CGStatusBar> statusBar;
CTavernWindow(const CGObjectInstance * TavernObj);
~CTavernWindow(); ~CTavernWindow();
void recruitb(); void recruitb();
@ -249,29 +283,47 @@ public:
void show(SDL_Surface * to) override; void show(SDL_Surface * to) override;
}; };
class CExchangeWindow : public CWindowObject, public CWindowWithGarrison, public CWindowWithArtifacts class CExchangeWindow : public CWindowObject, public CGarrisonHolder, public CWindowWithArtifacts
{ {
CGStatusBar * ourBar; //internal statusbar std::array<std::shared_ptr<CHeroWithMaybePickedArtifact>, 2> herosWArt;
CButton * quit, * questlogButton[2]; std::array<std::shared_ptr<CLabel>, 2> titles;
std::vector<std::shared_ptr<CAnimImage>> primSkillImages;//shared for both heroes
std::array<std::vector<std::shared_ptr<CLabel>>, 2> primSkillValues;
std::array<std::vector<std::shared_ptr<CAnimImage>>, 2> secSkillIcons;
std::array<std::shared_ptr<CAnimImage>, 2> specImages;
std::array<std::shared_ptr<CAnimImage>, 2> expImages;
std::array<std::shared_ptr<CLabel>, 2> expValues;
std::array<std::shared_ptr<CAnimImage>, 2> manaImages;
std::array<std::shared_ptr<CLabel>, 2> manaValues;
std::array<std::shared_ptr<CAnimImage>, 2> portraits;
std::vector<LRClickableAreaWTextComp *> secSkillAreas[2], primSkillAreas; std::vector<std::shared_ptr<LRClickableAreaWTextComp>> primSkillAreas;
std::array<std::vector<std::shared_ptr<LRClickableAreaWTextComp>>, 2> secSkillAreas;
MoraleLuckBox *morale[2], *luck[2]; std::array<std::shared_ptr<CHeroArea>, 2> heroAreas;
std::array<std::shared_ptr<LRClickableAreaWText>, 2> specialtyAreas;
std::array<std::shared_ptr<LRClickableAreaWText>, 2> experienceAreas;
std::array<std::shared_ptr<LRClickableAreaWText>, 2> spellPointsAreas;
LRClickableAreaWText *specialty[2]; std::array<std::shared_ptr<MoraleLuckBox>, 2> morale;
LRClickableAreaWText *experience[2]; std::array<std::shared_ptr<MoraleLuckBox>, 2> luck;
LRClickableAreaWText *spellPoints[2];
CHeroArea *portrait[2]; std::shared_ptr<CButton> quit;
std::array<std::shared_ptr<CButton>, 2> questlogButton;
std::shared_ptr<CGStatusBar> statusBar;
std::shared_ptr<CGarrisonInt> garr;
public: public:
std::array<const CGHeroInstance *, 2> heroInst;
std::array<std::shared_ptr<CArtifactsOfHero>, 2> artifs;
const CGHeroInstance* heroInst[2]; void updateGarrisons() override;
CArtifactsOfHero * artifs[2];
void questlog(int whichHero); //questlog button callback; whichHero: 0 - left, 1 - right void questlog(int whichHero); //questlog button callback; whichHero: 0 - left, 1 - right
void prepareBackground(); //prepares or redraws bg void updateWidgets();
CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2, QueryID queryID); CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2, QueryID queryID);
~CExchangeWindow(); ~CExchangeWindow();
@ -280,22 +332,23 @@ public:
/// Here you can buy ships /// Here you can buy ships
class CShipyardWindow : public CWindowObject class CShipyardWindow : public CWindowObject
{ {
std::shared_ptr<CPicture> bgWater;
std::shared_ptr<CAnimImage> bgShip;
std::shared_ptr<CLabel> title;
std::shared_ptr<CLabel> costLabel;
std::shared_ptr<CAnimImage> woodPic;
std::shared_ptr<CAnimImage> goldPic;
std::shared_ptr<CLabel> woodCost;
std::shared_ptr<CLabel> goldCost;
std::shared_ptr<CButton> build;
std::shared_ptr<CButton> quit;
std::shared_ptr<CGStatusBar> statusBar;
public: public:
CGStatusBar *bar; CShipyardWindow(const std::vector<si32> & cost, int state, int boatType, const std::function<void()> & onBuy);
CPicture *bgWater;
CLabel *title;
CLabel *costLabel;
CAnimImage *woodPic, *goldPic;
CLabel *woodCost, *goldCost;
CAnimImage *bgShip;
CButton *build, *quit;
CGStatusBar * statusBar;
CShipyardWindow(const std::vector<si32> &cost, int state, int boatType, const std::function<void()> &onBuy);
}; };
/// Puzzle screen which gets uncovered when you visit obilisks /// Puzzle screen which gets uncovered when you visit obilisks
@ -303,23 +356,25 @@ class CPuzzleWindow : public CWindowObject
{ {
private: private:
int3 grailPos; int3 grailPos;
std::shared_ptr<CPicture> logo;
std::shared_ptr<CLabel> title;
std::shared_ptr<CButton> quitb;
std::shared_ptr<CResDataBar> resDataBar;
CButton * quitb; std::vector<std::shared_ptr<CPicture>> piecesToRemove;
std::vector<std::shared_ptr<CPicture>> visiblePieces;
std::vector<CPicture * > piecesToRemove;
ui8 currentAlpha; ui8 currentAlpha;
public: public:
void showAll(SDL_Surface * to) override; void showAll(SDL_Surface * to) override;
void show(SDL_Surface * to) override; void show(SDL_Surface * to) override;
CPuzzleWindow(const int3 &grailPos, double discoveredRatio); CPuzzleWindow(const int3 & grailPos, double discoveredRatio);
}; };
/// Creature transformer window /// Creature transformer window
class CTransformerWindow : public CWindowObject, public CGarrisonHolder class CTransformerWindow : public CWindowObject, public CGarrisonHolder
{ {
public:
class CItem : public CIntObject class CItem : public CIntObject
{ {
public: public:
@ -327,7 +382,8 @@ public:
bool left;//position of the item bool left;//position of the item
int size; //size of creature stack int size; //size of creature stack
CTransformerWindow * parent; CTransformerWindow * parent;
CAnimImage *icon; std::shared_ptr<CAnimImage> icon;
std::shared_ptr<CLabel> count;
void move(); void move();
void clickLeft(tribool down, bool previousState) override; void clickLeft(tribool down, bool previousState) override;
@ -335,13 +391,23 @@ public:
CItem(CTransformerWindow * parent, int size, int id); CItem(CTransformerWindow * parent, int size, int id);
}; };
const CArmedInstance *army;//object with army for transforming (hero or town) const CArmedInstance * army;//object with army for transforming (hero or town)
const CGHeroInstance *hero;//only if we have hero in town const CGHeroInstance * hero;//only if we have hero in town
const CGTownInstance *town;//market, town garrison is used if hero == nullptr const CGTownInstance * town;//market, town garrison is used if hero == nullptr
std::vector<CItem*> items;
std::shared_ptr<CLabel> titleLeft;
std::shared_ptr<CLabel> titleRight;
std::shared_ptr<CTextBox> helpLeft;
std::shared_ptr<CTextBox> helpRight;
std::vector<std::shared_ptr<CItem>> items;
std::shared_ptr<CButton> all;
std::shared_ptr<CButton> convert;
std::shared_ptr<CButton> cancel;
std::shared_ptr<CGStatusBar> statusBar;
public:
CButton *all, *convert, *cancel;
CGStatusBar *bar;
void makeDeal(); void makeDeal();
void addAll(); void addAll();
void updateGarrisons() override; void updateGarrisons() override;
@ -350,8 +416,13 @@ public:
class CUniversityWindow : public CWindowObject class CUniversityWindow : public CWindowObject
{ {
class CItem : public CAnimImage class CItem : public CIntObject
{ {
std::shared_ptr<CAnimImage> icon;
std::shared_ptr<CAnimImage> topBar;
std::shared_ptr<CAnimImage> bottomBar;
std::shared_ptr<CLabel> name;
std::shared_ptr<CLabel> level;
public: public:
int ID;//id of selected skill int ID;//id of selected skill
CUniversityWindow * parent; CUniversityWindow * parent;
@ -364,33 +435,66 @@ class CUniversityWindow : public CWindowObject
CItem(CUniversityWindow * _parent, int _ID, int X, int Y); CItem(CUniversityWindow * _parent, int _ID, int X, int Y);
}; };
public: const CGHeroInstance * hero;
const CGHeroInstance *hero;
const IMarket * market; const IMarket * market;
CPicture * green, * yellow, * red;//colored bars near skills std::shared_ptr<CAnimation> bars;
std::vector<CItem*> items;
CButton *cancel; std::vector<std::shared_ptr<CItem>> items;
CGStatusBar *bar;
std::shared_ptr<CButton> cancel;
std::shared_ptr<CGStatusBar> statusBar;
std::shared_ptr<CIntObject> titlePic;
std::shared_ptr<CLabel> title;
std::shared_ptr<CTextBox> clerkSpeech;
public:
CUniversityWindow(const CGHeroInstance * _hero, const IMarket * _market); CUniversityWindow(const CGHeroInstance * _hero, const IMarket * _market);
void makeDeal(int skill);
}; };
/// Confirmation window for University /// Confirmation window for University
class CUnivConfirmWindow : public CWindowObject class CUnivConfirmWindow : public CWindowObject
{ {
public: std::shared_ptr<CTextBox> clerkSpeech;
CUniversityWindow * parent; std::shared_ptr<CLabel> name;
CGStatusBar *bar; std::shared_ptr<CLabel> level;
CButton *confirm, *cancel; std::shared_ptr<CAnimImage> icon;
CUniversityWindow * owner;
std::shared_ptr<CGStatusBar> statusBar;
std::shared_ptr<CButton> confirm;
std::shared_ptr<CButton> cancel;
std::shared_ptr<CAnimImage> costIcon;
std::shared_ptr<CLabel> cost;
CUnivConfirmWindow(CUniversityWindow * PARENT, int SKILL, bool available);
void makeDeal(int skill); void makeDeal(int skill);
public:
CUnivConfirmWindow(CUniversityWindow * PARENT, int SKILL, bool available);
};
/// Garrison window where you can take creatures out of the hero to place it on the garrison
class CGarrisonWindow : public CWindowObject, public CGarrisonHolder
{
std::shared_ptr<CLabel> title;
std::shared_ptr<CAnimImage> banner;
std::shared_ptr<CAnimImage> portrait;
std::shared_ptr<CGarrisonInt> garr;
public:
std::shared_ptr<CButton> quit;
CGarrisonWindow(const CArmedInstance * up, const CGHeroInstance * down, bool removableUnits);
void updateGarrisons() override;
}; };
/// Hill fort is the building where you can upgrade units /// Hill fort is the building where you can upgrade units
class CHillFortWindow : public CWindowObject, public CWindowWithGarrison class CHillFortWindow : public CWindowObject, public CGarrisonHolder
{ {
private: private:
static const int slotsCount = 7; static const int slotsCount = 7;
@ -400,23 +504,29 @@ private:
const CGObjectInstance * fort; const CGObjectInstance * fort;
const CGHeroInstance * hero; const CGHeroInstance * hero;
CGStatusBar * bar; std::shared_ptr<CLabel> title;
CHeroArea * heroPic;//clickable hero image std::shared_ptr<CHeroArea> heroPic;
CButton * quit;//closes window
CButton * upgradeAll;//upgrade all creatures
std::array<CButton *, slotsCount> upgrade;//upgrade single creature std::array<std::shared_ptr<CAnimImage>, resCount> totalIcons;
std::array<std::shared_ptr<CLabel>, resCount> totalLabels;
std::array<std::shared_ptr<CButton>, slotsCount> upgrade;//upgrade single creature
std::array<int, slotsCount + 1> currState;//current state of slot - to avoid calls to getState or updating buttons std::array<int, slotsCount + 1> currState;//current state of slot - to avoid calls to getState or updating buttons
//there is a place for only 2 resources per slot //there is a place for only 2 resources per slot
std::array< std::array<CAnimImage *, 2>, slotsCount> slotIcons; std::array< std::array<std::shared_ptr<CAnimImage>, 2>, slotsCount> slotIcons;
std::array< std::array<CLabel *, 2>, slotsCount> slotLabels; std::array< std::array<std::shared_ptr<CLabel>, 2>, slotsCount> slotLabels;
std::array<CAnimImage *, resCount> totalIcons; std::shared_ptr<CButton> upgradeAll;
std::array<CLabel *, resCount> totalLabels; std::shared_ptr<CButton> quit;
std::shared_ptr<CGarrisonInt> garr;
std::shared_ptr<CGStatusBar> statusBar;
std::string getDefForSlot(SlotID slot);
std::string getTextForSlot(SlotID slot);
std::string getDefForSlot(SlotID slot);//return def name for this slot
std::string getTextForSlot(SlotID slot);//return hover text for this slot
void makeDeal(SlotID slot);//-1 for upgrading all creatures void makeDeal(SlotID slot);//-1 for upgrading all creatures
int getState(SlotID slot); //-1 = no creature 0=can't upgrade, 1=upgraded, 2=can upgrade int getState(SlotID slot); //-1 = no creature 0=can't upgrade, 1=upgraded, 2=can upgrade
public: public:
@ -428,10 +538,22 @@ class CThievesGuildWindow : public CWindowObject
{ {
const CGObjectInstance * owner; const CGObjectInstance * owner;
CGStatusBar * statusBar; std::shared_ptr<CGStatusBar> statusBar;
CButton * exitb; std::shared_ptr<CButton> exitb;
CMinorResDataBar * resdatabar; std::shared_ptr<CMinorResDataBar> resdatabar;
std::vector<std::shared_ptr<CLabel>> rowHeaders;
std::vector<std::shared_ptr<CAnimImage>> columnBackgrounds;
std::vector<std::shared_ptr<CLabel>> columnHeaders;
std::vector<std::shared_ptr<CAnimImage>> cells;
std::vector<std::shared_ptr<CPicture>> banners;
std::vector<std::shared_ptr<CAnimImage>> bestHeroes;
std::vector<std::shared_ptr<CTextBox>> primSkillHeaders;
std::vector<std::shared_ptr<CLabel>> primSkillValues;
std::vector<std::shared_ptr<CAnimImage>> bestCreatures;
std::vector<std::shared_ptr<CLabel>> personalities;
public: public:
CThievesGuildWindow(const CGObjectInstance * _owner); CThievesGuildWindow(const CGObjectInstance * _owner);
}; };

View File

@ -57,7 +57,7 @@ void CSelWindow::selectionChange(unsigned to)
{ {
for (unsigned i=0;i<components.size();i++) for (unsigned i=0;i<components.size();i++)
{ {
CSelectableComponent * pom = dynamic_cast<CSelectableComponent*>(components[i]); auto pom = std::dynamic_pointer_cast<CSelectableComponent>(components[i]);
if (!pom) if (!pom)
continue; continue;
pom->select(i==to); pom->select(i==to);
@ -65,19 +65,19 @@ void CSelWindow::selectionChange(unsigned to)
redraw(); redraw();
} }
CSelWindow::CSelWindow(const std::string &Text, PlayerColor player, int charperline, const std::vector<CSelectableComponent*> &comps, const std::vector<std::pair<std::string, CFunctionList<void()> > > &Buttons, QueryID askID) CSelWindow::CSelWindow(const std::string &Text, PlayerColor player, int charperline, const std::vector<std::shared_ptr<CSelectableComponent>> & comps, const std::vector<std::pair<std::string, CFunctionList<void()> > > &Buttons, QueryID askID)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
ID = askID; ID = askID;
for (int i = 0; i < Buttons.size(); i++) for (int i = 0; i < Buttons.size(); i++)
{ {
buttons.push_back(new CButton(Point(0, 0), Buttons[i].first, CButton::tooltip(), Buttons[i].second)); buttons.push_back(std::make_shared<CButton>(Point(0, 0), Buttons[i].first, CButton::tooltip(), Buttons[i].second));
if (!i && askID.getNum() >= 0) if (!i && askID.getNum() >= 0)
buttons.back()->addCallback(std::bind(&CSelWindow::madeChoice, this)); buttons.back()->addCallback(std::bind(&CSelWindow::madeChoice, this));
buttons[i]->addCallback(std::bind(&CInfoWindow::close, this)); //each button will close the window apart from call-defined actions buttons[i]->addCallback(std::bind(&CInfoWindow::close, this)); //each button will close the window apart from call-defined actions
} }
text = new CTextBox(Text, Rect(0, 0, 250, 100), 0, FONT_MEDIUM, CENTER, Colors::WHITE); text = std::make_shared<CTextBox>(Text, Rect(0, 0, 250, 100), 0, FONT_MEDIUM, CENTER, Colors::WHITE);
buttons.front()->assignedKeys.insert(SDLK_RETURN); //first button - reacts on enter buttons.front()->assignedKeys.insert(SDLK_RETURN); //first button - reacts on enter
buttons.back()->assignedKeys.insert(SDLK_ESCAPE); //last button - reacts on escape buttons.back()->assignedKeys.insert(SDLK_ESCAPE); //last button - reacts on escape
@ -92,8 +92,8 @@ CSelWindow::CSelWindow(const std::string &Text, PlayerColor player, int charperl
for(int i=0;i<comps.size();i++) for(int i=0;i<comps.size();i++)
{ {
comps[i]->recActions = 255; comps[i]->recActions = 255-DISPOSE;
addChild(comps[i]); addChild(comps[i].get());
components.push_back(comps[i]); components.push_back(comps[i]);
comps[i]->onSelect = std::bind(&CSelWindow::selectionChange,this,i); comps[i]->onSelect = std::bind(&CSelWindow::selectionChange,this,i);
if(i<9) if(i<9)
@ -109,7 +109,7 @@ void CSelWindow::madeChoice()
int ret = -1; int ret = -1;
for (int i=0;i<components.size();i++) for (int i=0;i<components.size();i++)
{ {
if(dynamic_cast<CSelectableComponent*>(components[i])->selected) if(std::dynamic_pointer_cast<CSelectableComponent>(components[i])->selected)
{ {
ret = i; ret = i;
} }
@ -117,21 +117,21 @@ void CSelWindow::madeChoice()
LOCPLINT->cb->selectionMade(ret+1,ID); LOCPLINT->cb->selectionMade(ret+1,ID);
} }
CInfoWindow::CInfoWindow(std::string Text, PlayerColor player, const TCompsInfo &comps, const TButtonsInfo &Buttons, bool delComps) CInfoWindow::CInfoWindow(std::string Text, PlayerColor player, const TCompsInfo & comps, const TButtonsInfo & Buttons)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
type |= BLOCK_ADV_HOTKEYS; type |= BLOCK_ADV_HOTKEYS;
ID = QueryID(-1); ID = QueryID(-1);
for(auto & Button : Buttons) for(auto & Button : Buttons)
{ {
CButton *button = new CButton(Point(0,0), Button.first, CButton::tooltip(), std::bind(&CInfoWindow::close,this)); std::shared_ptr<CButton> button = std::make_shared<CButton>(Point(0,0), Button.first, CButton::tooltip(), std::bind(&CInfoWindow::close, this));
button->setBorderColor(Colors::METALLIC_GOLD); button->setBorderColor(Colors::METALLIC_GOLD);
button->addCallback(Button.second); //each button will close the window apart from call-defined actions button->addCallback(Button.second); //each button will close the window apart from call-defined actions
buttons.push_back(button); buttons.push_back(button);
} }
text = new CTextBox(Text, Rect(0, 0, 250, 100), 0, FONT_MEDIUM, CENTER, Colors::WHITE); text = std::make_shared<CTextBox>(Text, Rect(0, 0, 250, 100), 0, FONT_MEDIUM, CENTER, Colors::WHITE);
if(!text->slider) if(!text->slider)
{ {
text->resize(text->label->textSize); text->resize(text->label->textSize);
@ -145,20 +145,18 @@ CInfoWindow::CInfoWindow(std::string Text, PlayerColor player, const TCompsInfo
for(auto & comp : comps) for(auto & comp : comps)
{ {
comp->recActions = 0xff; comp->recActions = 0xff & ~DISPOSE;
addChild(comp); addChild(comp.get());
comp->recActions &= ~(SHOWALL | UPDATE); comp->recActions &= ~(SHOWALL | UPDATE);
components.push_back(comp); components.push_back(comp);
} }
setDelComps(delComps);
CMessage::drawIWindow(this,Text,player); CMessage::drawIWindow(this,Text,player);
} }
CInfoWindow::CInfoWindow() CInfoWindow::CInfoWindow()
{ {
ID = QueryID(-1); ID = QueryID(-1);
setDelComps(false);
text = nullptr;
} }
void CInfoWindow::close() void CInfoWindow::close()
@ -173,14 +171,7 @@ void CInfoWindow::show(SDL_Surface * to)
CIntObject::show(to); CIntObject::show(to);
} }
CInfoWindow::~CInfoWindow() CInfoWindow::~CInfoWindow() = default;
{
if(!delComps)
{
for (auto & elem : components)
removeChild(elem);
}
}
void CInfoWindow::showAll(SDL_Surface * to) void CInfoWindow::showAll(SDL_Surface * to)
{ {
@ -188,19 +179,19 @@ void CInfoWindow::showAll(SDL_Surface * to)
CIntObject::showAll(to); CIntObject::showAll(to);
} }
void CInfoWindow::showInfoDialog(const std::string &text, const std::vector<CComponent *> *components, bool DelComps, PlayerColor player) void CInfoWindow::showInfoDialog(const std::string &text, const TCompsInfo & components, PlayerColor player)
{ {
CInfoWindow * window = CInfoWindow::create(text, player, components, DelComps); CInfoWindow * window = CInfoWindow::create(text, player, components);
GH.pushInt(window); GH.pushInt(window);
} }
void CInfoWindow::showYesNoDialog(const std::string & text, const std::vector<CComponent*> *components, const CFunctionList<void( ) > &onYes, const CFunctionList<void()> &onNo, bool DelComps, PlayerColor player) void CInfoWindow::showYesNoDialog(const std::string & text, const TCompsInfo & components, const CFunctionList<void( ) > &onYes, const CFunctionList<void()> &onNo, PlayerColor player)
{ {
assert(!LOCPLINT || LOCPLINT->showingDialog->get()); assert(!LOCPLINT || LOCPLINT->showingDialog->get());
std::vector<std::pair<std::string,CFunctionList<void()> > > pom; std::vector<std::pair<std::string,CFunctionList<void()> > > pom;
pom.push_back(std::pair<std::string,CFunctionList<void()> >("IOKAY.DEF",0)); pom.push_back(std::pair<std::string,CFunctionList<void()> >("IOKAY.DEF",0));
pom.push_back(std::pair<std::string,CFunctionList<void()> >("ICANCEL.DEF",0)); pom.push_back(std::pair<std::string,CFunctionList<void()> >("ICANCEL.DEF",0));
CInfoWindow * temp = new CInfoWindow(text, player, components ? *components : std::vector<CComponent*>(), pom, DelComps); CInfoWindow * temp = new CInfoWindow(text, player, components, pom);
temp->buttons[0]->addCallback( onYes ); temp->buttons[0]->addCallback( onYes );
temp->buttons[1]->addCallback( onNo ); temp->buttons[1]->addCallback( onNo );
@ -208,21 +199,21 @@ void CInfoWindow::showYesNoDialog(const std::string & text, const std::vector<CC
GH.pushInt(temp); GH.pushInt(temp);
} }
void CInfoWindow::showOkDialog(const std::string & text, const std::vector<CComponent*> *components, const std::function<void()> & onOk, bool delComps, PlayerColor player) void CInfoWindow::showOkDialog(const std::string & text, const TCompsInfo & components, const std::function<void()> & onOk, PlayerColor player)
{ {
std::vector<std::pair<std::string,CFunctionList<void()> > > pom; std::vector<std::pair<std::string,CFunctionList<void()> > > pom;
pom.push_back(std::pair<std::string,CFunctionList<void()> >("IOKAY.DEF",0)); pom.push_back(std::pair<std::string,CFunctionList<void()> >("IOKAY.DEF",0));
CInfoWindow * temp = new CInfoWindow(text, player, *components, pom, delComps); CInfoWindow * temp = new CInfoWindow(text, player, components, pom);
temp->buttons[0]->addCallback(onOk); temp->buttons[0]->addCallback(onOk);
GH.pushInt(temp); GH.pushInt(temp);
} }
CInfoWindow * CInfoWindow::create(const std::string &text, PlayerColor playerID, const std::vector<CComponent*> *components, bool DelComps) CInfoWindow * CInfoWindow::create(const std::string &text, PlayerColor playerID, const TCompsInfo & components)
{ {
std::vector<std::pair<std::string,CFunctionList<void()> > > pom; std::vector<std::pair<std::string,CFunctionList<void()> > > pom;
pom.push_back(std::pair<std::string,CFunctionList<void()> >("IOKAY.DEF",0)); pom.push_back(std::pair<std::string,CFunctionList<void()> >("IOKAY.DEF",0));
CInfoWindow * ret = new CInfoWindow(text, playerID, components ? *components : std::vector<CComponent*>(), pom, DelComps); CInfoWindow * ret = new CInfoWindow(text, playerID, components, pom);
return ret; return ret;
} }
@ -231,18 +222,6 @@ std::string CInfoWindow::genText(std::string title, std::string description)
return std::string("{") + title + "}" + "\n\n" + description; return std::string("{") + title + "}" + "\n\n" + description;
} }
void CInfoWindow::setDelComps(bool DelComps)
{
delComps = DelComps;
for(CComponent *comp : components)
{
if(delComps)
comp->recActions |= DISPOSE;
else
comp->recActions &= ~DISPOSE;
}
}
CInfoPopup::CInfoPopup(SDL_Surface * Bitmap, int x, int y, bool Free) CInfoPopup::CInfoPopup(SDL_Surface * Bitmap, int x, int y, bool Free)
:free(Free),bitmap(Bitmap) :free(Free),bitmap(Bitmap)
{ {
@ -344,7 +323,7 @@ void CRClickPopup::createAndPush(const std::string &txt, const CInfoWindow::TCom
GH.pushInt(rcpi); GH.pushInt(rcpi);
} }
void CRClickPopup::createAndPush(const std::string &txt, CComponent * component) void CRClickPopup::createAndPush(const std::string & txt, std::shared_ptr<CComponent> component)
{ {
CInfoWindow::TCompsInfo intComps; CInfoWindow::TCompsInfo intComps;
intComps.push_back(component); intComps.push_back(component);
@ -408,47 +387,47 @@ Point CInfoBoxPopup::toScreen(Point p)
return p; return p;
} }
CInfoBoxPopup::CInfoBoxPopup(Point position, const CGTownInstance * town): CInfoBoxPopup::CInfoBoxPopup(Point position, const CGTownInstance * town)
CWindowObject(RCLICK_POPUP | PLAYER_COLORED, "TOWNQVBK", toScreen(position)) : CWindowObject(RCLICK_POPUP | PLAYER_COLORED, "TOWNQVBK", toScreen(position))
{ {
InfoAboutTown iah; InfoAboutTown iah;
LOCPLINT->cb->getTownInfo(town, iah, adventureInt->selection); //todo: should this be nearest hero? LOCPLINT->cb->getTownInfo(town, iah, adventureInt->selection); //todo: should this be nearest hero?
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
new CTownTooltip(Point(9, 10), iah); tooltip = std::make_shared<CTownTooltip>(Point(9, 10), iah);
} }
CInfoBoxPopup::CInfoBoxPopup(Point position, const CGHeroInstance * hero): CInfoBoxPopup::CInfoBoxPopup(Point position, const CGHeroInstance * hero)
CWindowObject(RCLICK_POPUP | PLAYER_COLORED, "HEROQVBK", toScreen(position)) : CWindowObject(RCLICK_POPUP | PLAYER_COLORED, "HEROQVBK", toScreen(position))
{ {
InfoAboutHero iah; InfoAboutHero iah;
LOCPLINT->cb->getHeroInfo(hero, iah, adventureInt->selection);//todo: should this be nearest hero? LOCPLINT->cb->getHeroInfo(hero, iah, adventureInt->selection);//todo: should this be nearest hero?
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
new CHeroTooltip(Point(9, 10), iah); tooltip = std::make_shared<CHeroTooltip>(Point(9, 10), iah);
} }
CInfoBoxPopup::CInfoBoxPopup(Point position, const CGGarrison * garr): CInfoBoxPopup::CInfoBoxPopup(Point position, const CGGarrison * garr)
CWindowObject(RCLICK_POPUP | PLAYER_COLORED, "TOWNQVBK", toScreen(position)) : CWindowObject(RCLICK_POPUP | PLAYER_COLORED, "TOWNQVBK", toScreen(position))
{ {
InfoAboutTown iah; InfoAboutTown iah;
LOCPLINT->cb->getTownInfo(garr, iah); LOCPLINT->cb->getTownInfo(garr, iah);
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
new CArmyTooltip(Point(9, 10), iah); tooltip = std::make_shared<CArmyTooltip>(Point(9, 10), iah);
} }
CIntObject * CRClickPopup::createInfoWin(Point position, const CGObjectInstance * specific) //specific=0 => draws info about selected town/hero CIntObject * CRClickPopup::createInfoWin(Point position, const CGObjectInstance * specific) //specific=0 => draws info about selected town/hero
{ {
if(nullptr == specific) if(nullptr == specific)
specific = adventureInt->selection; specific = adventureInt->selection;
if(nullptr == specific) if(nullptr == specific)
{ {
logGlobal->error("createInfoWin: no object to describe"); logGlobal->error("createInfoWin: no object to describe");
return nullptr; return nullptr;
} }
switch(specific->ID) switch(specific->ID)
{ {
case Obj::HERO: case Obj::HERO:

View File

@ -10,7 +10,6 @@
#pragma once #pragma once
#include "CWindowObject.h" #include "CWindowObject.h"
//#include "../gui/SDL_Extensions.h"
#include "../../lib/FunctionList.h" #include "../../lib/FunctionList.h"
struct SDL_Surface; struct SDL_Surface;
@ -24,6 +23,7 @@ class CGGarrison;
class CTextBox; class CTextBox;
class CButton; class CButton;
class CSlider; class CSlider;
class CArmyTooltip;
// Window GUI class // Window GUI class
class CSimpleWindow : public CIntObject class CSimpleWindow : public CIntObject
@ -37,33 +37,30 @@ public:
/// text + comp. + ok button /// text + comp. + ok button
class CInfoWindow : public CSimpleWindow class CInfoWindow : public CSimpleWindow
{ //window able to delete its components when closed {
bool delComps; //whether comps will be deleted
public: public:
typedef std::vector<std::pair<std::string,CFunctionList<void()> > > TButtonsInfo; typedef std::vector<std::pair<std::string, CFunctionList<void()> > > TButtonsInfo;
typedef std::vector<CComponent*> TCompsInfo; typedef std::vector<std::shared_ptr<CComponent>> TCompsInfo;
QueryID ID; //for identification QueryID ID; //for identification
CTextBox *text; std::shared_ptr<CTextBox> text;
std::vector<CButton *> buttons; std::vector<std::shared_ptr<CButton>> buttons;
std::vector<CComponent*> components; TCompsInfo components;
void setDelComps(bool DelComps);
virtual void close(); virtual void close();
void show(SDL_Surface * to) override; void show(SDL_Surface * to) override;
void showAll(SDL_Surface * to) override; void showAll(SDL_Surface * to) override;
void sliderMoved(int to); void sliderMoved(int to);
CInfoWindow(std::string Text, PlayerColor player, const TCompsInfo &comps = TCompsInfo(), const TButtonsInfo &Buttons = TButtonsInfo(), bool delComps = true); CInfoWindow(std::string Text, PlayerColor player, const TCompsInfo & comps = TCompsInfo(), const TButtonsInfo & Buttons = TButtonsInfo());
CInfoWindow(); CInfoWindow();
~CInfoWindow(); ~CInfoWindow();
//use only before the game starts! (showYesNoDialog in LOCPLINT must be used then) //use only before the game starts! (showYesNoDialog in LOCPLINT must be used then)
static void showInfoDialog( const std::string & text, const std::vector<CComponent*> *components, bool DelComps = true, PlayerColor player = PlayerColor(1)); static void showInfoDialog( const std::string & text, const TCompsInfo & components, PlayerColor player = PlayerColor(1));
static void showOkDialog(const std::string & text, const std::vector<CComponent*> *components, const std::function<void()> & onOk, bool delComps = true, PlayerColor player = PlayerColor(1)); static void showOkDialog(const std::string & text, const TCompsInfo & components, const std::function<void()> & onOk, PlayerColor player = PlayerColor(1));
static void showYesNoDialog( const std::string & text, const std::vector<CComponent*> *components, const CFunctionList<void( ) > &onYes, const CFunctionList<void()> &onNo, bool DelComps = true, PlayerColor player = PlayerColor(1)); static void showYesNoDialog( const std::string & text, const TCompsInfo & components, const CFunctionList<void()> & onYes, const CFunctionList<void()> & onNo, PlayerColor player = PlayerColor(1));
static CInfoWindow *create(const std::string &text, PlayerColor playerID = PlayerColor(1), const std::vector<CComponent*> *components = nullptr, bool DelComps = false); static CInfoWindow * create(const std::string & text, PlayerColor playerID = PlayerColor(1), const TCompsInfo & components = TCompsInfo());
/// create text from title and description: {title}\n\n description /// create text from title and description: {title}\n\n description
static std::string genText(std::string title, std::string description); static std::string genText(std::string title, std::string description);
@ -80,9 +77,9 @@ public:
virtual ~CRClickPopup(); virtual ~CRClickPopup();
static CIntObject* createInfoWin(Point position, const CGObjectInstance * specific); static CIntObject* createInfoWin(Point position, const CGObjectInstance * specific);
static void createAndPush(const std::string &txt, const CInfoWindow::TCompsInfo &comps = CInfoWindow::TCompsInfo()); static void createAndPush(const std::string & txt, const CInfoWindow::TCompsInfo &comps = CInfoWindow::TCompsInfo());
static void createAndPush(const std::string &txt, CComponent * component); static void createAndPush(const std::string & txt, std::shared_ptr<CComponent> component);
static void createAndPush(const CGObjectInstance *obj, const Point &p, EAlignment alignment = BOTTOMRIGHT); static void createAndPush(const CGObjectInstance * obj, const Point & p, EAlignment alignment = BOTTOMRIGHT);
}; };
/// popup displayed on R-click /// popup displayed on R-click
@ -116,6 +113,7 @@ public:
/// popup on adventure map for town\hero objects /// popup on adventure map for town\hero objects
class CInfoBoxPopup : public CWindowObject class CInfoBoxPopup : public CWindowObject
{ {
std::shared_ptr<CArmyTooltip> tooltip;
Point toScreen(Point pos); Point toScreen(Point pos);
public: public:
CInfoBoxPopup(Point position, const CGTownInstance * town); CInfoBoxPopup(Point position, const CGTownInstance * town);
@ -129,7 +127,7 @@ class CSelWindow : public CInfoWindow
public: public:
void selectionChange(unsigned to); void selectionChange(unsigned to);
void madeChoice(); //looks for selected component and calls callback void madeChoice(); //looks for selected component and calls callback
CSelWindow(const std::string& text, PlayerColor player, int charperline ,const std::vector<CSelectableComponent*> &comps, const std::vector<std::pair<std::string,CFunctionList<void()> > > &Buttons, QueryID askID); CSelWindow(const std::string & text, PlayerColor player, int charperline ,const std::vector<std::shared_ptr<CSelectableComponent>> & comps, const std::vector<std::pair<std::string,CFunctionList<void()> > > &Buttons, QueryID askID);
CSelWindow(){}; CSelWindow(){};
//notification - this class inherits important destructor from CInfoWindow //notification - this class inherits important destructor from CInfoWindow
}; };

View File

@ -23,7 +23,6 @@ class CBattleCallback;
class ICallback; class ICallback;
class CGlobalAI; class CGlobalAI;
struct Component; struct Component;
class CSelectableComponent;
struct TryMoveHero; struct TryMoveHero;
class CGHeroInstance; class CGHeroInstance;
class CGTownInstance; class CGTownInstance;

View File

@ -99,7 +99,7 @@ public:
virtual void heroMovePointsChanged(const CGHeroInstance * hero){} //not called at the beginning of turn and after movement virtual void heroMovePointsChanged(const CGHeroInstance * hero){} //not called at the beginning of turn and after movement
virtual void heroVisitsTown(const CGHeroInstance* hero, const CGTownInstance * town){}; virtual void heroVisitsTown(const CGHeroInstance* hero, const CGTownInstance * town){};
virtual void receivedResource(){}; virtual void receivedResource(){};
virtual void showInfoDialog(const std::string &text, const std::vector<Component*> &components, int soundID){}; virtual void showInfoDialog(const std::string & text, const std::vector<Component> & components, int soundID){};
virtual void showRecruitmentDialog(const CGDwelling *dwelling, const CArmedInstance *dst, int level){} virtual void showRecruitmentDialog(const CGDwelling *dwelling, const CArmedInstance *dst, int level){}
virtual void showShipyardDialog(const IShipyard *obj){} //obj may be town or shipyard; state: 0 - can buid, 1 - lack of resources, 2 - dest tile is blocked, 3 - no water virtual void showShipyardDialog(const IShipyard *obj){} //obj may be town or shipyard; state: 0 - can buid, 1 - lack of resources, 2 - dest tile is blocked, 3 - no water