1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +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;
}
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);
NET_EVENT_HANDLER;

View File

@ -231,7 +231,7 @@ public:
virtual void playerBonusChanged(const Bonus &bonus, bool gain) override;
virtual void heroCreated(const CGHeroInstance*) 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 receivedResource() override;
virtual void objectRemoved(const CGObjectInstance *obj) override;

View File

@ -1341,7 +1341,7 @@ void handleQuit(bool ask)
if(CSH->client && LOCPLINT && ask)
{
CCS->curh->changeGraphic(ECursor::ADVENTURE, 0);
LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[69], quitApplication, 0);
LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[69], quitApplication, nullptr);
}
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
{
public:
CComponent *comp;
std::shared_ptr<CComponent> comp;
//blit component with image centered at this position
void showAll(SDL_Surface * to) override;
//ComponentResolved();
ComponentResolved(CComponent *Comp);
ComponentResolved(std::shared_ptr<CComponent> Comp);
~ComponentResolved();
};
// Full set of components for blitting on dialog box
struct ComponentsToBlit
{
std::vector< std::vector<ComponentResolved*> > comps;
std::vector< std::vector<std::shared_ptr<ComponentResolved>>> comps;
int w, h;
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();
};
namespace
{
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
}
@ -298,7 +298,7 @@ void CMessage::drawBorder(PlayerColor playerColor, SDL_Surface * ret, int w, int
{
if(playerColor.isSpectator())
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.
@ -358,7 +358,7 @@ void CMessage::drawBorder(PlayerColor playerColor, SDL_Surface * ret, int w, int
box[3]->draw(ret, &dstR, nullptr);
}
ComponentResolved::ComponentResolved( CComponent *Comp ):
ComponentResolved::ComponentResolved(std::shared_ptr<CComponent> Comp):
comp(Comp)
{
//Temporary assign ownership on comp
@ -367,10 +367,10 @@ ComponentResolved::ComponentResolved( CComponent *Comp ):
if (comp->parent)
{
comp->parent->addChild(this);
comp->parent->removeChild(comp);
comp->parent->removeChild(comp.get());
}
addChild(comp);
addChild(comp.get());
defActions = 255 - DISPOSE;
pos.x = pos.y = 0;
@ -382,8 +382,8 @@ ComponentResolved::~ComponentResolved()
{
if (parent)
{
removeChild(comp);
parent->addChild(comp);
removeChild(comp.get());
parent->addChild(comp.get());
}
}
@ -393,15 +393,9 @@ void ComponentResolved::showAll(SDL_Surface *to)
comp->showAll(to);
}
ComponentsToBlit::~ComponentsToBlit()
{
for(auto & elem : comps)
for(size_t j = 0; j < elem.size(); j++)
delete elem[j];
ComponentsToBlit::~ComponentsToBlit() = default;
}
ComponentsToBlit::ComponentsToBlit(std::vector<CComponent*> & SComps, int maxw, bool blitOr)
ComponentsToBlit::ComponentsToBlit(std::vector<std::shared_ptr<CComponent>> & SComps, int maxw, bool blitOr)
{
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)
{
auto cur = new ComponentResolved(SComp);
auto cur = std::make_shared<ComponentResolved>(SComp);
int toadd = (cur->pos.w + BETWEEN_COMPS + (blitOr ? orWidth : 0));
if (curw + toadd > maxw)
@ -453,7 +447,7 @@ void ComponentsToBlit::blitCompsOnSur( bool blitOr, int inter, int &curh, SDL_Su
int totalw=0, maxHeight=0;
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;
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++)
{
ComponentResolved *cur = elem[j];
auto cur = elem[j];
cur->moveTo(Point(curw, curh));
//blit component

View File

@ -196,8 +196,8 @@ void CPlayerInterface::yourTurn()
makingTurn = true;
std::string msg = CGI->generaltexth->allTexts[13];
boost::replace_first(msg, "%s", cb->getStartInfo()->playerInfos.find(playerID)->second.name);
std::vector<CComponent*> cmp;
cmp.push_back(new CComponent(CComponent::flag, playerID.getNum(), 0));
std::vector<std::shared_ptr<CComponent>> cmp;
cmp.push_back(std::make_shared<CComponent>(CComponent::flag, playerID.getNum(), 0));
showInfoDialog(msg, cmp);
}
else
@ -363,9 +363,8 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details)
GH.mainFPSmng->framerateDelay(); //for animation purposes
logGlobal->trace("after [un]locks in %s", __FUNCTION__);
}
//CSDL_Ext::update(screen);
} //for (int i=1; i<32; i+=4)
}
//main moving done
//finishing move
@ -905,8 +904,7 @@ void CPlayerInterface::battleEnd(const BattleResult *br)
if (!battleInt)
{
SDL_Rect temp_rect = genRect(561, 470, (screen->w - 800)/2 + 165, (screen->h - 600)/2 + 19);
auto resWindow = new CBattleResultWindow(*br, temp_rect, *this);
auto resWindow = new CBattleResultWindow(*br, *this);
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.
// Otherwise NewTurn causes freeze.
@ -1100,29 +1098,29 @@ void CPlayerInterface::showComp(const Component &comp, std::string 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;
if (settings["session"]["autoSkip"].Bool() && !LOCPLINT->shiftPressed())
{
return;
}
std::vector<CComponent*> intComps;
std::vector<std::shared_ptr<CComponent>> intComps;
for (auto & component : components)
intComps.push_back(new CComponent(*component));
intComps.push_back(std::make_shared<CComponent>(component));
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);
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));
waitWhileDialog();
@ -1131,8 +1129,8 @@ void CPlayerInterface::showInfoDialog(const std::string &text, const std::vector
{
return;
}
CInfoWindow *temp = CInfoWindow::create(text, playerID, &components);
temp->setDelComps(delComps);
CInfoWindow *temp = CInfoWindow::create(text, playerID, components);
if (makingTurn && GH.listInt.size() && LOCPLINT == this)
{
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)
{
EVENT_HANDLER_CALLED_BY_CLIENT;
std::vector<Component*> comps;
for (auto & elem : components)
{
comps.push_back(&elem);
}
std::string str;
text.toString(str);
showInfoDialog(str,comps, 0);
showInfoDialog(str, components, 0);
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);
stopMovement();
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)
{
boost::unique_lock<boost::recursive_mutex> un(*pim);
std::vector<Component*> comps;
for (auto & elem : components)
{
comps.push_back(&elem);
}
std::string str;
text.toString(str);
stopMovement();
showingDialog->setn(true);
std::vector<CComponent*> intComps;
for (auto & component : comps)
intComps.push_back(new CComponent(*component));
CInfoWindow::showOkDialog(str, &intComps, onOk, true, playerID);
std::vector<std::shared_ptr<CComponent>> intComps;
for (auto & component : components)
intComps.push_back(std::make_shared<CComponent>(component));
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 )
@ -1201,17 +1190,17 @@ void CPlayerInterface::showBlockingDialog( const std::string &text, const std::v
if (!selection && cancel) //simple yes/no dialog
{
std::vector<CComponent*> intComps;
std::vector<std::shared_ptr<CComponent>> intComps;
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)
{
std::vector<CSelectableComponent*> intComps;
std::vector<std::shared_ptr<CSelectableComponent>> intComps;
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;
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);
CIntObject * localIcon = localIconC->image;
localIconC->removeChild(localIcon, false);
std::shared_ptr<CIntObject> localIcon = localIconC->image;
localIconC->removeChild(localIcon.get(), false);
delete localIconC;
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);
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 )
{
@ -1504,25 +1453,28 @@ void CPlayerInterface::showArtifactAssemblyDialog (ui32 artifactID, ui32 assembl
const CArtifact &artifact = *CGI->arth->artifacts[artifactID];
std::string text = artifact.Description();
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];
// You possess all of the components to...
text += boost::str(boost::format(CGI->generaltexth->allTexts[732]) % assembledArtifact.Name());
// 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->subtitle = assembledArtifact.Name();
scs.push_back(sc);
} else {
}
else
{
// Do you wish to disassemble this artifact?
text += CGI->generaltexth->allTexts[733];
}
showYesNoDialog(text, onYes, onNo, true, scs);
showYesNoDialog(text, onYes, onNo, scs);
}
void CPlayerInterface::requestRealized( PackageApplied *pa )
@ -2230,7 +2182,7 @@ void CPlayerInterface::gameOver(PlayerColor player, const EVictoryLossCheckResul
{
std::string str = victoryLossCheckResult.messageToSelf;
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()
{
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()

View File

@ -39,7 +39,6 @@ class CSlider;
struct UpgradeInfo;
template <typename T> struct CondSh;
class CInGameConsole;
class CGarrisonInt;
class CInGameConsole;
union SDL_Event;
class CInfoWindow;
@ -139,7 +138,7 @@ public:
void heroMovePointsChanged(const CGHeroInstance * hero) override;
void heroVisitsTown(const CGHeroInstance* hero, const CGTownInstance * town) 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 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.
@ -215,11 +214,11 @@ public:
void activateForSpectator(); // TODO: spectator probably need own player interface class
// show dialogs
void showInfoDialog(const std::string &text, 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, std::shared_ptr<CComponent> component);
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 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 moveHero(const CGHeroInstance *h, CGPath path);

View File

@ -9,9 +9,19 @@
*/
#include "StdInc.h"
#include "CreatureCostBox.h"
#include "windows/CAdvmapInterface.h"
#include "widgets/Images.h"
#include "widgets/TextControls.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)
{
@ -19,40 +29,27 @@ void CreatureCostBox::set(TResources res)
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)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
for(auto & curr : resources)
{
delete curr.second.first;
delete curr.second.second;
}
resources.clear();
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
TResources::nziterator iter(res);
while (iter.valid())
while(iter.valid())
{
CAnimImage * image = new CAnimImage("RESOURCE", iter->resType);
CLabel * text = new CLabel(15, 43, FONT_SMALL, CENTER, Colors::WHITE, "0");
ImagePtr image = std::make_shared<CAnimImage>("RESOURCE", iter->resType);
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)));
iter++;
}
if (!resources.empty())
if(!resources.empty())
{
int curx = pos.w / 2 - (16 * resources.size()) - (8 * (resources.size() - 1));
//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.second->moveBy(Point(curx, 22));

View File

@ -9,15 +9,22 @@
*/
#pragma once
#include "widgets/Images.h"
#include "../lib/ResourceSet.h"
#include "gui/CIntObject.h"
class CLabel;
class CAnimImage;
class CreatureCostBox : public CIntObject
{
public:
void set(TResources res);
CreatureCostBox(Rect position, std::string title);
CreatureCostBox(Rect position, std::string titleText);
void createItems(TResources res);
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)
{
SDL_Color *palette = nullptr;
SDL_Color * palette = nullptr;
if(player < PlayerColor::PLAYER_LIMIT)
{
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());
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);
#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
{

View File

@ -534,15 +534,10 @@ void GiveHero::applyFirstCl(CClient *cl)
void InfoWindow::applyCl(CClient *cl)
{
std::vector<Component*> comps;
for(auto & elem : components)
{
comps.push_back(&elem);
}
std::string 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...");
}

View File

@ -803,7 +803,7 @@ void CBattleInterface::bSurrenderf()
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."
curInt->showYesNoDialog(surrenderMessage, [this](){ reallySurrender(); }, 0, false);
curInt->showYesNoDialog(surrenderMessage, [this](){ reallySurrender(); }, nullptr);
}
}
@ -815,11 +815,11 @@ void CBattleInterface::bFleef()
if ( curInt->cb->battleCanFlee() )
{
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
{
std::vector<CComponent*> comps;
std::vector<std::shared_ptr<CComponent>> comps;
std::string heroName;
//calculating fleeing hero's name
if (attackingHeroInstance)
@ -1280,8 +1280,7 @@ void CBattleInterface::displayBattleFinished()
return;
}
SDL_Rect temp_rect = genRect(561, 470, (screen->w - 800)/2 + 165, (screen->h - 600)/2 + 19);
resWindow = new CBattleResultWindow(*bresult, temp_rect, *this->curInt);
resWindow = new CBattleResultWindow(*bresult, *this->curInt);
GH.pushInt(resWindow);
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();
std::shared_ptr<CAnimation> animation;
@ -3650,7 +3649,7 @@ IImage * CBattleInterface::getObstacleImage(const CObstacleInstance & oi)
{
const SpellCreatedObstacle * spellObstacle = dynamic_cast<const SpellCreatedObstacle *>(&oi);
if(!spellObstacle)
return nullptr;
return std::shared_ptr<IImage>();
std::string animationName = spellObstacle->animation;
@ -3679,7 +3678,7 @@ IImage * CBattleInterface::getObstacleImage(const CObstacleInstance & oi)
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());

View File

@ -254,9 +254,9 @@ private:
BattleObjectsByHex sortObjectsByHex();
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);
/** End of battle screen blitting methods */

View File

@ -277,55 +277,111 @@ CBattleHero::CBattleHero(const std::string & animationPath, bool flipG, PlayerCo
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)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
pos = position;
background = new CPicture("comopbck.bmp");
background = std::make_shared<CPicture>("comopbck.bmp");
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());
movementShadow = new CToggleButton(Point(25, 89), "sysopchk.def", CGI->generaltexth->zelp[428], [=](bool on){owner->setPrintStackRange(on);});
movementShadow->setSelected(settings["battle"]["stackRange"].Bool());
mouseShadow = new CToggleButton(Point(25, 122), "sysopchk.def", CGI->generaltexth->zelp[429], [=](bool on){owner->setPrintMouseShadow(on);});
mouseShadow->setSelected(settings["battle"]["mouseShadow"].Bool());
toggles.push_back(viewGrid);
auto movementShadow = std::make_shared<CToggleButton>(Point(25, 89), "sysopchk.def", CGI->generaltexth->zelp[428], [=](bool on){owner->setPrintStackRange(on);});
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());
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);
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);
//creating labels
labels.push_back(new 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(new 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(new 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>(242, 32, FONT_BIG, CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[392]));//window title
labels.push_back(std::make_shared<CLabel>(122, 214, FONT_MEDIUM, CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[393]));//animation speed
labels.push_back(std::make_shared<CLabel>(122, 293, FONT_MEDIUM, CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[394]));//music volume
labels.push_back(std::make_shared<CLabel>(122, 359, FONT_MEDIUM, CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[395]));//effects' volume
labels.push_back(std::make_shared<CLabel>(353, 66, FONT_MEDIUM, CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[396]));//auto - combat options
labels.push_back(std::make_shared<CLabel>(353, 265, FONT_MEDIUM, CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[397]));//creature info
//auto - combat options
labels.push_back(new 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(new 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(new CLabel(283, 206, FONT_MEDIUM, TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[401]));//first aid tent
labels.push_back(std::make_shared<CLabel>(283, 86, FONT_MEDIUM, TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[398]));//creatures
labels.push_back(std::make_shared<CLabel>(283, 116, FONT_MEDIUM, TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[399]));//spells
labels.push_back(std::make_shared<CLabel>(283, 146, FONT_MEDIUM, TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[400]));//catapult
labels.push_back(std::make_shared<CLabel>(283, 176, FONT_MEDIUM, TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[151]));//ballista
labels.push_back(std::make_shared<CLabel>(283, 206, FONT_MEDIUM, TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[401]));//first aid tent
//creature info
labels.push_back(new 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, 285, FONT_MEDIUM, TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[402]));//all stats
labels.push_back(std::make_shared<CLabel>(283, 315, FONT_MEDIUM, TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[403]));//spells only
//general options
labels.push_back(new 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(new 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, 57, FONT_MEDIUM, TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[404]));
labels.push_back(std::make_shared<CLabel>(61, 90, FONT_MEDIUM, TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[405]));
labels.push_back(std::make_shared<CLabel>(61, 123, FONT_MEDIUM, TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[406]));
labels.push_back(std::make_shared<CLabel>(61, 156, FONT_MEDIUM, TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[407]));
}
void CBattleOptionsWindow::bDefaultf()
@ -338,31 +394,32 @@ void CBattleOptionsWindow::bExitf()
GH.popIntTotally(this);
}
CBattleResultWindow::CBattleResultWindow(const BattleResult &br, const SDL_Rect & pos, CPlayerInterface &_owner)
: owner(_owner)
CBattleResultWindow::CBattleResultWindow(const BattleResult & br, CPlayerInterface & _owner)
: owner(_owner)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
this->pos = pos;
CPicture * bg = new CPicture("CPRESULT");
bg->colorize(owner.playerID);
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
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);
if(br.winner==0) //attacker won
{
new 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>(59, 124, FONT_SMALL, CENTER, Colors::WHITE, CGI->generaltexth->allTexts[410]));
labels.push_back(std::make_shared<CLabel>(408, 124, FONT_SMALL, CENTER, Colors::WHITE, CGI->generaltexth->allTexts[411]));
}
else //if(br.winner==1)
{
new 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>(59, 124, FONT_SMALL, CENTER, Colors::WHITE, CGI->generaltexth->allTexts[411]));
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]);
new 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, 302, FONT_BIG, CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[407]));
labels.push_back(std::make_shared<CLabel>(232, 332, FONT_SMALL, CENTER, Colors::WHITE, CGI->generaltexth->allTexts[408]));
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"};
@ -373,45 +430,51 @@ CBattleResultWindow::CBattleResultWindow(const BattleResult &br, const SDL_Rect
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;
}
else
{
auto stacks = owner.cb->battleGetAllStacks();
vstd::erase_if(stacks, [i](const CStack *stack) //erase stack of other side and not coming from garrison
{ return stack->side != i || !stack->base; });
vstd::erase_if(stacks, [i](const CStack * stack) //erase stack of other side and not coming from garrison
{
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...
{
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;
}
}
}
//printing attacker and defender's names
new 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>(89, 37, FONT_SMALL, TOPLEFT, Colors::WHITE, sideNames[0]));
labels.push_back(std::make_shared<CLabel>(381, 53, FONT_SMALL, BOTTOMRIGHT, Colors::WHITE, sideNames[1]));
//printing casualties
for(int step = 0; step < 2; ++step)
{
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
{
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])
{
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;
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;
}
}
@ -420,12 +483,20 @@ CBattleResultWindow::CBattleResultWindow(const BattleResult &br, const SDL_Rect
bool weAreAttacker = !(owner.cb->battleGetMySide());
if((br.winner == 0 && weAreAttacker) || (br.winner == 1 && !weAreAttacker)) //we've won
{
int text=-1;
int text = 304;
switch(br.result)
{
case BattleResult::NORMAL: text = 304; break;
case BattleResult::ESCAPE: text = 303; break;
case BattleResult::SURRENDER: text = 302; break;
case BattleResult::NORMAL:
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);
@ -436,44 +507,43 @@ CBattleResultWindow::CBattleResultWindow(const BattleResult &br, const SDL_Rect
if (ourHero)
{
str += CGI->generaltexth->allTexts[305];
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, "%s", ourHero->name);
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
{
int text = 311;
std::string musicName = "Music/LoseCombat";
std::string videoName = "LBSTART.BIK";
switch(br.result)
{
case BattleResult::NORMAL:
{
CCS->musich->playMusic("Music/LoseCombat", false);
CCS->videoh->open("LBSTART.BIK");
new CLabel(235, 235, FONT_SMALL, CENTER, Colors::WHITE, CGI->generaltexth->allTexts[311]);
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;
}
break;
case BattleResult::ESCAPE:
musicName = "Music/Retreat Battle";
videoName = "RTSTART.BIK";
text = 310;
break;
case BattleResult::SURRENDER:
{
CCS->musich->playMusic("Music/Surrender Battle", false);
CCS->videoh->open("SURRENDER.BIK");
new CLabel(235, 235, FONT_SMALL, CENTER, Colors::WHITE, CGI->generaltexth->allTexts[309]);
break;
}
musicName = "Music/Surrender Battle";
videoName = "SURRENDER.BIK";
text = 309;
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()
{
@ -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)
: embedded(Embedded),
owner(_owner)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
if(embedded)
{
pos.w = QUEUE_SIZE * 37;
@ -689,7 +718,7 @@ CStackQueue::CStackQueue(bool Embedded, CBattleInterface * _owner)
pos.w = 800;
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");
stateIcons = std::make_shared<CAnimation>("VCMI/BATTLEQUEUE/STATESSMALL");
@ -701,14 +730,12 @@ CStackQueue::CStackQueue(bool Embedded, CBattleInterface * _owner)
stackBoxes.resize(QUEUE_SIZE);
for (int i = 0; i < stackBoxes.size(); i++)
{
stackBoxes[i] = new StackBox(this);
stackBoxes[i]->moveBy(Point(1 + (embedded ? 36 : 80)*i, 0));
stackBoxes[i] = std::make_shared<StackBox>(this);
stackBoxes[i]->moveBy(Point(1 + (embedded ? 36 : 80) * i, 0));
}
}
CStackQueue::~CStackQueue()
{
}
CStackQueue::~CStackQueue() = default;
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 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++)
stackBoxes[boxIndex]->setStack(nullptr);
stackBoxes[boxIndex]->setUnit(nullptr);
}
CStackQueue::StackBox::StackBox(CStackQueue * owner)
: bg(nullptr),
icon(nullptr),
amount(nullptr),
stateIcon(nullptr)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
bg = new CPicture(owner->embedded ? "StackQueueSmall" : "StackQueueLarge" );
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
background = std::make_shared<CPicture>(owner->embedded ? "StackQueueSmall" : "StackQueueLarge");
pos.w = bg->pos.w;
pos.h = bg->pos.h;
pos.w = background->pos.w;
pos.h = background->pos.h;
if(owner->embedded)
{
icon = new CAnimImage(owner->icons, 0, 0, 5, 2);
amount = new CLabel(pos.w/2, pos.h - 7, FONT_SMALL, CENTER, Colors::WHITE);
icon = std::make_shared<CAnimImage>(owner->icons, 0, 0, 5, 2);
amount = std::make_shared<CLabel>(pos.w/2, pos.h - 7, FONT_SMALL, CENTER, Colors::WHITE);
}
else
{
icon = new CAnimImage(owner->icons, 0, 0, 9, 1);
amount = new CLabel(pos.w/2, pos.h - 8, FONT_MEDIUM, CENTER, Colors::WHITE);
icon = std::make_shared<CAnimImage>(owner->icons, 0, 0, 9, 1);
amount = std::make_shared<CLabel>(pos.w/2, pos.h - 8, FONT_MEDIUM, CENTER, Colors::WHITE);
int icon_x = pos.w - 17;
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;
}
}
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->setFrame(nStack->creatureIconIndex());
amount->setText(makeNumberShort(nStack->getCount()));
icon->setFrame(unit->creatureIconIndex());
amount->setText(makeNumberShort(unit->getCount()));
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->visible = true;
}
else if(nStack->waited(turn))
else if(unit->waited(turn))
{
stateIcon->setFrame(1, 0);
stateIcon->visible = true;
@ -787,7 +810,7 @@ void CStackQueue::StackBox::setStack(const battle::Unit * nStack, size_t turn)
}
else
{
bg->colorize(PlayerColor::NEUTRAL);
background->colorize(PlayerColor::NEUTRAL);
icon->visible = false;
icon->setFrame(0);
amount->setText("");

View File

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

View File

@ -286,7 +286,7 @@ void CCreatureAnimation::nextFrame(SDL_Surface * dest, bool attacker)
{
size_t frame = floor(currentFrame);
IImage * image = nullptr;
std::shared_ptr<IImage> image;
if(attacker)
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, 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 playerColored(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, 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;
@ -801,22 +801,9 @@ CompImageLoader::~CompImageLoader()
* Classes for images, support loading from file and drawing on surface *
*************************************************************************/
IImage::IImage():
refCount(1)
{
IImage::IImage() = default;
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)
: 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);
@ -976,7 +963,7 @@ std::unique_ptr<IImage> SDLImage::scaleFast(float scale) const
ret->margins.x = (int) round((float)margins.x * 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
@ -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
@ -1331,7 +1318,7 @@ void CompImage::exportBitmap(const boost::filesystem::path & path) const
* 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(':');
if (pos == -1)
@ -1364,7 +1351,6 @@ bool CAnimation::loadFrame(size_t frame, size_t group)
auto image = getImage(frame, group, false);
if(image)
{
image->increaseRef();
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(compressed)
images[group][frame] = new CompImage(defFile, frame, group);
images[group][frame] = std::make_shared<CompImage>(defFile, frame, group);
else
images[group][frame] = new SDLImage(defFile, frame, group);
images[group][frame] = std::make_shared<SDLImage>(defFile, frame, group);
return true;
}
}
// still here? image is missing
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
{
auto img = getFromExtraDef(source[group][frame]["file"].String());
if(!img)
img = new SDLImage(source[group][frame]);
img = std::make_shared<SDLImage>(source[group][frame]);
images[group][frame] = img;
return true;
@ -1404,15 +1390,11 @@ bool CAnimation::loadFrame(size_t frame, size_t group)
bool CAnimation::unloadFrame(size_t frame, size_t group)
{
auto image = getImage(frame, group, false);
if (image)
if(image)
{
//decrease ref count for image and delete if needed
if (image->decreaseRef())
{
delete image;
images[group].erase(frame);
}
if (images[group].empty())
images[group].erase(frame);
if(images[group].empty())
images.erase(group);
return true;
}
@ -1558,16 +1540,6 @@ 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)
delete defFile;
}
@ -1599,7 +1571,7 @@ void CAnimation::setCustom(std::string filename, size_t frame, size_t group)
//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);
if (groupIter != images.end())

View File

@ -22,7 +22,6 @@ class CDefFile;
*/
class IImage
{
int refCount;
public:
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, 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;
//decrease ref count, returns true if image can be deleted (refCount <= 0)
bool decreaseRef();
void increaseRef();
//Change palette to specific player
virtual void playerColored(PlayerColor player)=0;
@ -57,7 +52,7 @@ public:
virtual void verticalFlip() = 0;
IImage();
virtual ~IImage() {};
virtual ~IImage();
};
/// Class for handling animation
@ -68,7 +63,7 @@ private:
std::map<size_t, std::vector <JsonNode> > source;
//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
std::string name;
@ -95,7 +90,7 @@ private:
//not a very nice method to get image from another def file
//TODO: remove after implementing resource manager
IImage * getFromExtraDef(std::string filename);
std::shared_ptr<IImage> getFromExtraDef(std::string filename);
public:
CAnimation(std::string Name, bool Compressed = false);
@ -109,8 +104,7 @@ public:
//add custom surface to the selected position.
void setCustom(std::string filename, size_t frame, size_t group=0);
//get pointer to image from specific group, nullptr if not found
IImage * getImage(size_t frame, size_t group=0, bool verbose=true) const;
std::shared_ptr<IImage> getImage(size_t frame, size_t group=0, bool verbose=true) 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 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 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);
}
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)
{
if (!(active & TIME))
@ -125,24 +142,6 @@ void CIntObject::deactivate(ui16 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)
{
switch(btn)
@ -291,8 +290,12 @@ void CIntObject::removeChild(CIntObject * child, bool adjustPosition)
if (!child)
return;
assert(vstd::contains(children, child));
assert(child->parent_m == this);
if(!vstd::contains(children, child))
throw std::runtime_error("Wrong child object");
if(child->parent_m != this)
throw std::runtime_error("Wrong child object");
children -= child;
child->parent_m = nullptr;
if(adjustPosition)

View File

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

View File

@ -323,7 +323,7 @@ void CBonusSelection::createBonusesIcons()
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)
picName += ":" + boost::lexical_cast<std::string>(picNumber);

View File

@ -134,7 +134,7 @@ void CLobbyScreen::startScenario(bool allowOnlyAI)
catch(ExceptionNoHuman & e)
{
// 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)
{

View File

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

View File

@ -148,7 +148,7 @@ InfoCard::InfoCard()
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);
if(SEL->screenType != ESelectionScreen::newGame)

View File

@ -367,12 +367,12 @@ void OptionsTab::CPlayerOptionTooltipBox::genTownWindow()
genHeader();
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;
for(auto & elem : town->creatures)
{
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));
}

View File

@ -219,7 +219,7 @@ void RandomMapTab::addButtonsWithRandToGroup(CToggleGroup * group, const std::ve
// Buttons are relative to button group, TODO better solution?
SObjectConstruction obj__i(group);
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);
}
@ -230,10 +230,9 @@ void RandomMapTab::addButtonsToGroup(CToggleGroup * group, const std::vector<std
int cnt = nEnd - nStart + 1;
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
button->setImageOrder(0, 1, 1, 3);
group->addToggle(i + nStart, button);
}
}
@ -243,7 +242,7 @@ void RandomMapTab::deactivateButtonsFrom(CToggleGroup * group, int startId)
logGlobal->debug("Blocking buttons from %d", startId);
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)
{

View File

@ -94,16 +94,16 @@ CMenuScreen::CMenuScreen(const JsonNode & configNode)
//Hardcoded entry
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;
}
CIntObject * CMenuScreen::createTab(size_t index)
std::shared_ptr<CIntObject> CMenuScreen::createTab(size_t index)
{
if(config["items"].Vector().size() == index)
return new CreditsScreen();
return new CMenuEntry(this, config["items"].Vector()[index]);
return std::make_shared<CreditsScreen>();
else
return std::make_shared<CMenuEntry>(this, config["items"].Vector()[index]);
}
void CMenuScreen::show(SDL_Surface * to)
@ -175,7 +175,7 @@ static std::function<void()> genCommand(CMenuScreen * menu, std::vector<std::str
case 2:
return std::bind(CMainMenu::openLobby, ESelectionScreen::campaignList, true, nullptr, ELoadMode::NONE);
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;
}
@ -190,18 +190,18 @@ static std::function<void()> genCommand(CMenuScreen * menu, std::vector<std::str
case 2:
return std::bind(CMainMenu::openLobby, ESelectionScreen::loadGame, true, nullptr, ELoadMode::CAMPAIGN);
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;
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;
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);
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->setText(settings["general"]["playerName"].String());
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);
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]->giveFocus();
@ -489,7 +489,7 @@ CSimpleJoinScreen::CSimpleJoinScreen(bool host)
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);
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()

View File

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

View File

@ -398,7 +398,7 @@ CMapHandler::CMapBlitter *CMapHandler::resolveBlitter(const MapDrawingInfo * inf
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);
}
@ -470,7 +470,7 @@ CMapHandler::CMapNormalBlitter::CMapNormalBlitter(CMapHandler * parent)
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;
if(owner < PlayerColor::PLAYER_LIMIT)
@ -501,7 +501,7 @@ IImage * CMapHandler::CMapWorldViewBlitter::objectToIcon(Obj id, si32 subId, Pla
case Obj::RESOURCE:
return info->icons->getImage((int)EWorldViewIcon::RES_WOOD + subId + ownerIndex);
}
return nullptr;
return std::shared_ptr<IImage>();
}
void CMapHandler::CMapWorldViewBlitter::calculateWorldViewCameraPos()
@ -536,7 +536,7 @@ void CMapHandler::CMapWorldViewBlitter::calculateWorldViewCameraPos()
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);
@ -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)
return;
@ -612,7 +612,7 @@ void CMapHandler::CMapWorldViewBlitter::drawHeroFlag(SDL_Surface * targetSurf, c
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)
return;
@ -729,12 +729,12 @@ void CMapHandler::CMapBlitter::drawOverlayEx(SDL_Surface * targetSurf)
//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);
}
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);
drawElement(EMapCacheType::OBJECTS, source, sourceRect, targetSurf, &dstRect);
@ -830,7 +830,7 @@ void CMapHandler::CMapBlitter::drawFow(SDL_Surface * targetSurf) const
if (retBitmapID < 0)
retBitmapID = - parent->hideBitmap[pos.x][pos.y][pos.z] - 1; //fully hidden
const IImage * image = nullptr;
std::shared_ptr<IImage> image;
if (retBitmapID >= 0)
image = parent->FoWpartialHide.at(retBitmapID);
@ -1006,22 +1006,22 @@ CMapHandler::AnimBitmapHolder CMapHandler::CMapBlitter::findBoatBitmap(const CGB
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)
return nullptr;
if(!hero)
return std::shared_ptr<IImage>();
if (hero->boat)
if(hero->boat)
return findBoatFlagBitmap(hero->boat, anim, color, group, hero->moveDir);
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);
}
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;
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);
}
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);
if(groupSize == 0)
@ -1438,22 +1438,21 @@ void CMapHandler::CMapCache::updateWorldViewScale(float 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 iter = cache.find(key);
if(iter == cache.end())
{
auto scaled = fullSurface->scaleFast(worldViewCachedScale);
IImage * ret = scaled.get();
cache[key] = std::move(scaled);
return ret;
cache[key] = scaled;
return scaled;
}
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
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;
public:
CMapCache();
@ -168,17 +168,17 @@ class CMapHandler
/// updates scale and determines if currently cached data is still valid
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
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
struct AnimBitmapHolder
{
IImage * objBitmap; // main object bitmap
IImage * flagBitmap; // flag bitmap for the object (probably only for heroes and boats with heroes)
std::shared_ptr<IImage> objBitmap; // main object bitmap
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)
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_),
flagBitmap(flagBitmap_),
isMoving(moving)
@ -202,7 +202,7 @@ class CMapHandler
const MapDrawingInfo * info; // data for drawing passed from outside
/// 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
@ -214,8 +214,8 @@ class CMapHandler
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)
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 drawHeroFlag(SDL_Surface * targetSurf, const IImage * source, SDL_Rect * sourceRect, SDL_Rect * destRect, 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, std::shared_ptr<IImage> source, SDL_Rect * sourceRect, SDL_Rect * destRect, bool moving) const;
// second drawing pass
@ -249,10 +249,10 @@ class CMapHandler
// internal helper methods to choose correct bitmap(s) for object; called internally by findObjectBitmap
AnimBitmapHolder findHeroBitmap(const CGHeroInstance * 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;
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;
IImage * findFlagBitmapInternal(std::shared_ptr<CAnimation> animation, int anim, int group, ui8 dir, bool moving) const;
std::shared_ptr<IImage> findFlagBitmap(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;
std::shared_ptr<IImage> findBoatFlagBitmap(const CGBoat * obj, int anim, const PlayerColor * color, int group, ui8 dir) const;
std::shared_ptr<IImage> findFlagBitmapInternal(std::shared_ptr<CAnimation> animation, int anim, int group, ui8 dir, bool moving) const;
public:
CMapBlitter(CMapHandler * p);
@ -265,7 +265,7 @@ class CMapHandler
class CMapNormalBlitter : public CMapBlitter
{
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 init(const MapDrawingInfo * info) override;
SDL_Rect clip(SDL_Surface * targetSurf) const override;
@ -277,12 +277,12 @@ class CMapHandler
class CMapWorldViewBlitter : public CMapBlitter
{
private:
IImage * objectToIcon(Obj id, si32 subId, PlayerColor owner) const;
std::shared_ptr<IImage> objectToIcon(Obj id, si32 subId, PlayerColor owner) const;
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 drawHeroFlag(SDL_Surface * targetSurf, const 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 drawHeroFlag(SDL_Surface * targetSurf, std::shared_ptr<IImage> source, SDL_Rect * sourceRect, SDL_Rect * destRect, 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 drawOverlayEx(SDL_Surface * targetSurf) 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
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]
TFlippedCache terrainImages;//[terrain type, view type, rotation]
@ -359,14 +359,14 @@ public:
TFlippedCache riverImages;//[river type, view type, rotation]
//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<const IImage *> FoWpartialHide;
std::vector<std::shared_ptr<IImage>> FoWpartialHide;
//edge graphics
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
mutable std::map<const CGObjectInstance*, ui8> animationPhase;

View File

@ -48,18 +48,16 @@
#include "../../lib/NetPacksBase.h"
#include "../../lib/StringConstants.h"
CList::CListItem::CListItem(CList * Parent):
CIntObject(LCLICK | RCLICK | HOVER),
CList::CListItem::CListItem(CList * Parent)
: CIntObject(LCLICK | RCLICK | HOVER),
parent(Parent),
selection(nullptr)
selection()
{
defActions = 255-DISPOSE;
}
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)
@ -70,15 +68,17 @@ void CList::CListItem::clickRight(tribool down, bool previousState)
void CList::CListItem::clickLeft(tribool down, bool previousState)
{
if (down == true)
if(down == true)
{
//second click on already selected item
if (parent->selected == this)
if(parent->selected == this->shared_from_this())
{
open();
}
else
{
//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)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
vstd::clear_pointer(selection);
if (on)
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
selection.reset();
if(on)
selection = genSelection();
select(on);
GH.totalRedraw();
}
CList::CList(int Size, Point position, std::string btnUp, std::string btnDown, size_t listAmount,
int helpUp, int helpDown, CListBox::CreateFunc create, CListBox::DestroyFunc destroy):
CIntObject(0, position),
CList::CList(int Size, Point position, std::string btnUp, std::string btnDown, size_t listAmount, int helpUp, int helpDown, CListBox::CreateFunc create)
: CIntObject(0, position),
size(Size),
selected(nullptr)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
scrollUp = new CButton(Point(0, 0), btnUp, CGI->generaltexth->zelp[helpUp]);
list = new CListBox(create, destroy, Point(1,scrollUp->pos.h), Point(0, 32), size, listAmount);
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
scrollUp = std::make_shared<CButton>(Point(0, 0), btnUp, CGI->generaltexth->zelp[helpUp]);
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
scrollUp->addCallback(std::bind(&CListBox::moveToPrev, list));
scrollDown = new CButton(Point(0, scrollUp->pos.h + 32*size), btnDown, CGI->generaltexth->zelp[helpDown], std::bind(&CListBox::moveToNext, list));
scrollUp->addCallback(std::bind(&CListBox::moveToPrev, listBox));
scrollDown->addCallback(std::bind(&CListBox::moveToNext, listBox));
scrollDown->addCallback(std::bind(&CList::update, this));
scrollUp->addCallback(std::bind(&CList::update, this));
scrollDown->addCallback(std::bind(&CList::update, this));
update();
}
void CList::update()
{
bool onTop = list->getPos() == 0;
bool onBottom = list->getPos() + size >= list->size();
bool onTop = listBox->getPos() == 0;
bool onBottom = listBox->getPos() + size >= listBox->size();
scrollUp->block(onTop);
scrollDown->block(onBottom);
}
void CList::select(CListItem *which)
void CList::select(std::shared_ptr<CListItem> which)
{
if (selected == which)
if(selected == which)
return;
if (selected)
if(selected)
selected->onSelect(false);
selected = which;
if (which)
if(which)
{
which->onSelect(true);
onSelect();
@ -148,28 +149,28 @@ void CList::select(CListItem *which)
int CList::getSelectedIndex()
{
return list->getIndexOf(selected);
return listBox->getIndexOf(selected);
}
void CList::selectIndex(int which)
{
if (which < 0)
if(which < 0)
{
if (selected)
if(selected)
select(nullptr);
}
else
{
list->scrollTo(which);
listBox->scrollTo(which);
update();
select(dynamic_cast<CListItem*>(list->getItem(which)));
select(std::dynamic_pointer_cast<CListItem>(listBox->getItem(which)));
}
}
void CList::selectNext()
{
int index = getSelectedIndex() + 1;
if (index >= list->size())
if(index >= listBox->size())
index = 0;
selectIndex(index);
}
@ -177,7 +178,7 @@ void CList::selectNext()
void CList::selectPrev()
{
int index = getSelectedIndex();
if (index <= 0)
if(index <= 0)
selectIndex(0);
else
selectIndex(index-1);
@ -185,23 +186,23 @@ void CList::selectPrev()
CHeroList::CEmptyHeroItem::CEmptyHeroItem()
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
auto move = new CAnimImage("IMOBIL", 0, 0, 0, 1);
auto img = new CPicture("HPSXXX", move->pos.w + 1);
auto mana = new CAnimImage("IMANA", 0, 0, move->pos.w + img->pos.w + 2, 1 );
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
movement = std::make_shared<CAnimImage>("IMOBIL", 0, 0, 0, 1);
portrait = std::make_shared<CPicture>("HPSXXX", movement->pos.w + 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.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):
CListItem(parent),
CHeroList::CHeroItem::CHeroItem(CHeroList *parent, const CGHeroInstance * Hero)
: CListItem(parent),
hero(Hero)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
movement = new CAnimImage("IMOBIL", 0, 0, 0, 1);
portrait = new CAnimImage("PortraitsSmall", hero->portrait, 0, movement->pos.w + 1);
mana = new CAnimImage("IMANA", 0, 0, movement->pos.w + portrait->pos.w + 2, 1 );
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
movement = std::make_shared<CAnimImage>("IMOBIL", 0, 0, 0, 1);
portrait = std::make_shared<CAnimImage>("PortraitsSmall", hero->portrait, 0, movement->pos.w + 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.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();
}
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)
{
if (on && adventureInt->selection != hero)
adventureInt->select(hero);
if(on && adventureInt->selection != hero)
adventureInt->select(hero);
}
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);
}
CIntObject * CHeroList::createHeroItem(size_t index)
std::shared_ptr<CIntObject> CHeroList::createHeroItem(size_t index)
{
if (LOCPLINT->wanderingHeroes.size() > index)
return new CHeroItem(this, LOCPLINT->wanderingHeroes[index]);
return new CEmptyHeroItem();
return std::make_shared<CHeroItem>(this, LOCPLINT->wanderingHeroes[index]);
return std::make_shared<CEmptyHeroItem>();
}
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)
{
//this hero is already present, update its status
for (auto & elem : list->getItems())
for(auto & elem : listBox->getItems())
{
auto item = dynamic_cast<CHeroItem*>(elem);
if (item && item->hero == hero && vstd::contains(LOCPLINT->wanderingHeroes, hero))
auto item = std::dynamic_pointer_cast<CHeroItem>(elem);
if(item && item->hero == hero && vstd::contains(LOCPLINT->wanderingHeroes, hero))
{
item->update();
return;
@ -273,7 +274,7 @@ void CHeroList::update(const CGHeroInstance * hero)
}
//simplest solution for now: reset list and restore selection
list->resize(LOCPLINT->wanderingHeroes.size());
listBox->resize(LOCPLINT->wanderingHeroes.size());
if (adventureInt->selection)
{
auto hero = dynamic_cast<const CGHeroInstance *>(adventureInt->selection);
@ -283,26 +284,26 @@ void CHeroList::update(const CGHeroInstance * hero)
CList::update();
}
CIntObject * CTownList::createTownItem(size_t index)
std::shared_ptr<CIntObject> CTownList::createTownItem(size_t index)
{
if (LOCPLINT->towns.size() > index)
return new CTownItem(this, LOCPLINT->towns[index]);
return new CAnimImage("ITPA", 0);
return std::make_shared<CTownItem>(this, LOCPLINT->towns[index]);
return std::make_shared<CAnimImage>("ITPA", 0);
}
CTownList::CTownItem::CTownItem(CTownList *parent, const CGTownInstance *Town):
CListItem(parent),
town(Town)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
picture = new CAnimImage("ITPA", 0);
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
picture = std::make_shared<CAnimImage>("ITPA", 0);
pos = picture->pos;
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()
@ -348,7 +349,7 @@ void CTownList::update(const CGTownInstance *)
{
//simplest solution for now: reset list and restore selection
list->resize(LOCPLINT->towns.size());
listBox->resize(LOCPLINT->towns.size());
if (adventureInt->selection)
{
auto town = dynamic_cast<const CGTownInstance *>(adventureInt->selection);
@ -475,7 +476,7 @@ CMinimapInstance::~CMinimapInstance()
SDL_FreeSurface(minimap);
}
void CMinimapInstance::showAll(SDL_Surface *to)
void CMinimapInstance::showAll(SDL_Surface * to)
{
blitAtLoc(minimap, 0, 0, to);
@ -484,7 +485,7 @@ void CMinimapInstance::showAll(SDL_Surface *to)
for(auto & hero : heroes)
{
int3 position = hero->getPosition(false);
if (position.z == level)
if(position.z == level)
{
const SDL_Color & color = graphics->playerColors[hero->getOwner().getNum()];
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;
}
CMinimap::CMinimap(const Rect &position):
CIntObject(LCLICK | RCLICK | HOVER | MOVE, position.topLeft()),
aiShield(nullptr),
minimap(nullptr),
CMinimap::CMinimap(const Rect & position)
: CIntObject(LCLICK | RCLICK | HOVER | MOVE, position.topLeft()),
level(0),
colors(loadColors("config/terrains.json"))
{
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
pos.w = position.w;
pos.h = position.h;
aiShield = std::make_shared<CPicture>("AIShield");
aiShield->disable();
}
int3 CMinimap::translateMousePosition()
@ -567,7 +570,7 @@ void CMinimap::moveAdvMapSelection()
void CMinimap::clickLeft(tribool down, bool previousState)
{
if (down)
if(down)
moveAdvMapSelection();
}
@ -578,7 +581,7 @@ void CMinimap::clickRight(tribool down, bool previousState)
void CMinimap::hover(bool on)
{
if (on)
if(on)
GH.statusbar->setText(CGI->generaltexth->zelp[291].first);
else
GH.statusbar->clear();
@ -593,7 +596,7 @@ void CMinimap::mouseMoved(const SDL_MouseMotionEvent & sEvent)
void CMinimap::showAll(SDL_Surface * to)
{
CIntObject::showAll(to);
if (minimap)
if(minimap)
{
int3 mapSizes = LOCPLINT->cb->getMapSize();
int3 tileCountOnScreen = adventureInt->terrain.tileCountOnScreen();
@ -608,13 +611,13 @@ void CMinimap::showAll(SDL_Surface * to)
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)
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);
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
}
@ -627,12 +630,11 @@ void CMinimap::showAll(SDL_Surface * to)
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;
OBJ_CONSTRUCTION_CAPTURING_ALL;
vstd::clear_pointer(minimap);
minimap = new CMinimapInstance(this, level);
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
minimap = std::make_shared<CMinimapInstance>(this, level);
redraw();
}
@ -644,16 +646,14 @@ void CMinimap::setLevel(int newLevel)
void CMinimap::setAIRadar(bool on)
{
if (on)
if(on)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
vstd::clear_pointer(minimap);
if (!aiShield)
aiShield = new CPicture("AIShield");
aiShield->enable();
minimap.reset();
}
else
{
vstd::clear_pointer(aiShield);
aiShield->disable();
update();
}
// 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)
{
if (minimap)
if(minimap)
minimap->refreshTile(pos);
}
void CMinimap::showTile(const int3 &pos)
{
if (minimap)
if(minimap)
minimap->refreshTile(pos);
}
CInfoBar::CVisibleInfo::CVisibleInfo(Point position):
CIntObject(0, position),
aiProgress(nullptr)
CInfoBar::CVisibleInfo::CVisibleInfo()
: CIntObject(0, Point(8, 12))
{
}
void CInfoBar::CVisibleInfo::show(SDL_Surface *to)
void CInfoBar::CVisibleInfo::show(SDL_Surface * to)
{
CIntObject::show(to);
for(auto object : forceRefresh)
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
OBJ_CONSTRUCTION_CAPTURING_ALL;
new CPicture("ADSTATCS");
new CTownTooltip(Point(0,0), town);
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
background = std::make_shared<CPicture>("ADSTATHR");
heroTooltip = std::make_shared<CHeroTooltip>(Point(0,0), hero);
}
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
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);
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
background = std::make_shared<CPicture>("ADSTATCS");
townTooltip = std::make_shared<CTownTooltip>(Point(0,0), town);
}
std::string CInfoBar::CVisibleInfo::getNewDayName()
CInfoBar::VisibleDateInfo::VisibleDateInfo()
{
if (LOCPLINT->cb->getDate(Date::DAY) == 1)
return "NEWDAY";
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
if (LOCPLINT->cb->getDate(Date::DAY) != 1)
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);
animation = std::make_shared<CShowableAnim>(1, 0, getNewDayName(), CShowableAnim::PLAY_ONCE);
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));
else
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;
new CPicture("ADSTATNX");
new CAnimImage("CREST58", player.getNum(), 0, 20, 51);
new CShowableAnim(99, 51, "HOURSAND");
if(LOCPLINT->cb->getDate(Date::DAY) != 1)
return "NEWDAY";
// FIXME: currently there is no way to get progress from VCAI
// if this will change at some point switch this ifdef to enable correct code
#if 0
//prepare hourglass for updating AI turn
aiProgress = new CAnimImage("HOURGLAS", 0, 0, 99, 51);
forceRefresh.push_back(aiProgress);
#else
//create hourglass that will be always animated ignoring AI status
new CShowableAnim(99, 51, "HOURGLAS", CShowableAnim::PLAY_ONCE, 40);
#endif
switch(LOCPLINT->cb->getDate(Date::WEEK))
{
case 1:
return "NEWWEEK1";
case 2:
return "NEWWEEK2";
case 3:
return "NEWWEEK3";
case 4:
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
std::vector<int> halls(4, 0);
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->getPlayerRelations(LOCPLINT->playerID, PlayerColor(i)) != PlayerRelations::ENEMIES)
if(LOCPLINT->cb->getPlayerRelations(LOCPLINT->playerID, PlayerColor(i)) != PlayerRelations::ENEMIES)
allies.push_back(PlayerColor(i));
else
enemies.push_back(PlayerColor(i));
}
}
//generate component
OBJ_CONSTRUCTION_CAPTURING_ALL;
new CPicture("ADSTATIN");
auto allyLabel = new CLabel(10, 106, FONT_SMALL, TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[390] + ":");
auto enemyLabel = new CLabel(10, 136, FONT_SMALL, TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[391] + ":");
//generate widgets
background = std::make_shared<CPicture>("ADSTATIN");
allyLabel = std::make_shared<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] + ":");
int posx = allyLabel->pos.w + allyLabel->pos.x - pos.x + 4;
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;
flags.push_back(image);
}
posx = enemyLabel->pos.w + enemyLabel->pos.x - pos.x + 4;
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;
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);
if (halls[i])
new CLabel( 26 + 42 * i, 64, FONT_SMALL, CENTER, Colors::WHITE, boost::lexical_cast<std::string>(halls[i]));
hallIcons.push_back(std::make_shared<CAnimImage>("itmtl", i, 0, 6 + 42 * i , 11));
if(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);
auto comp = new CComponent(compToDisplay);
comp = std::make_shared<CComponent>(compToDisplay);
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)
aiProgress->setFrame((aiProgress->size() - 1) * progress);
if(LOCPLINT->cb->getDate(Date::DAY_OF_WEEK) != 1) // not first day of the week
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;
vstd::clear_pointer(visibleInfo);
currentObject = nullptr;
state = newState;
visibleInfo = new CVisibleInfo(Point(8, 12));
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
state = EMPTY;
visibleInfo = std::make_shared<EmptyVisibleInfo>();
}
void CInfoBar::showSelection()
{
if (adventureInt->selection)
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
if(adventureInt->selection)
{
auto hero = dynamic_cast<const CGHeroInstance *>(adventureInt->selection);
if (hero)
if(auto hero = dynamic_cast<const CGHeroInstance *>(adventureInt->selection))
{
showHeroSelection(hero);
return;
}
auto town = dynamic_cast<const CGTownInstance *>(adventureInt->selection);
if (town)
else if(auto town = dynamic_cast<const CGTownInstance *>(adventureInt->selection))
{
showTownSelection(town);
return;
@ -891,11 +867,11 @@ void CInfoBar::tick()
void CInfoBar::clickLeft(tribool down, bool previousState)
{
if (down)
if(down)
{
if (state == HERO || state == TOWN)
if(state == HERO || state == TOWN)
showGameStatus();
else if (state == GAME)
else if(state == GAME)
showDate();
else
showSelection();
@ -909,83 +885,96 @@ void CInfoBar::clickRight(tribool down, bool previousState)
void CInfoBar::hover(bool on)
{
if (on)
if(on)
GH.statusbar->setText(CGI->generaltexth->zelp[292].first);
else
GH.statusbar->clear();
}
CInfoBar::CInfoBar(const Rect &position):
CIntObject(LCLICK | RCLICK | HOVER, position.topLeft()),
visibleInfo(nullptr),
state(EMPTY),
currentObject(nullptr)
CInfoBar::CInfoBar(const Rect & position)
: CIntObject(LCLICK | RCLICK | HOVER, position.topLeft()),
state(EMPTY)
{
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
pos.w = position.w;
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()
{
reset(DATE);
visibleInfo->loadDay();
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
playNewDaySound();
state = DATE;
visibleInfo = std::make_shared<VisibleDateInfo>();
setTimer(3000);
redraw();
}
void CInfoBar::showComponent(const Component & comp, std::string message)
{
reset(COMPONENT);
visibleInfo->loadComponent(comp, message);
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
state = COMPONENT;
visibleInfo = std::make_shared<VisibleComponentInfo>(comp, message);
setTimer(3000);
redraw();
}
void CInfoBar::startEnemyTurn(PlayerColor color)
{
reset(AITURN);
visibleInfo->loadEnemyTurn(color);
redraw();
}
void CInfoBar::updateEnemyTurn(double progress)
{
assert(state == AITURN);
visibleInfo->updateEnemyTurn(progress);
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
state = AITURN;
visibleInfo = std::make_shared<VisibleEnemyTurnInfo>(color);
redraw();
}
void CInfoBar::showHeroSelection(const CGHeroInstance * hero)
{
if (!hero)
return;
reset(HERO);
currentObject = hero;
visibleInfo->loadHero(hero);
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
if(!hero)
{
reset();
}
else
{
state = HERO;
visibleInfo = std::make_shared<VisibleHeroInfo>(hero);
}
redraw();
}
void CInfoBar::showTownSelection(const CGTownInstance * town)
{
if (!town)
return;
reset(TOWN);
currentObject = town;
visibleInfo->loadTown(town);
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
if(!town)
{
reset();
}
else
{
state = TOWN;
visibleInfo = std::make_shared<VisibleTownInfo>(town);
}
redraw();
}
void CInfoBar::showGameStatus()
{
reset(GAME);
visibleInfo->loadGameStatus();
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
state = GAME;
visibleInfo = std::make_shared<VisibleGameStatusInfo>();
setTimer(3000);
redraw();
}
CInGameConsole::CInGameConsole()
: CIntObject(KEYBOARD | TEXTINPUT),
prevEntDisp(-1),
defaultTimeout(10000),
maxDisplayedTexts(10)
{
}
void CInGameConsole::show(SDL_Surface * to)
{
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)
: CIntObject(),
background(bg)
@ -1233,32 +1217,34 @@ CAdvMapPanel::~CAdvMapPanel()
SDL_FreeSurface(background);
}
void CAdvMapPanel::addChildColorableButton(CButton * btn)
void CAdvMapPanel::addChildColorableButton(std::shared_ptr<CButton> button)
{
buttons.push_back(btn);
addChildToPanel(btn, ACTIVATE | DEACTIVATE);
colorableButtons.push_back(button);
addChildToPanel(button, ACTIVATE | DEACTIVATE);
}
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)
{
if (background)
if(background)
blitAt(background, pos.x, pos.y, 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;
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)
@ -1280,7 +1266,7 @@ CAdvMapWorldViewPanel::~CAdvMapWorldViewPanel()
SDL_FreeSurface(tmpBackgroundFiller);
}
void CAdvMapWorldViewPanel::recolorIcons(const PlayerColor &color, int indexOffset)
void CAdvMapWorldViewPanel::recolorIcons(const PlayerColor & color, int indexOffset)
{
assert(iconsData.size() == currentIcons.size());
@ -1290,9 +1276,9 @@ void CAdvMapWorldViewPanel::recolorIcons(const PlayerColor &color, int indexOffs
currentIcons[idx]->setFrame(data.first + indexOffset);
}
if (fillerHeight > 0)
if(fillerHeight > 0)
{
if (tmpBackgroundFiller)
if(tmpBackgroundFiller)
SDL_FreeSurface(tmpBackgroundFiller);
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)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
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)

View File

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

View File

@ -74,18 +74,17 @@ void CButton::addCallback(std::function<void()> 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;
addOverlay(new CLabel(pos.w/2, pos.h/2, font, CENTER, color, Text));
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
addOverlay(std::make_shared<CLabel>(pos.w/2, pos.h/2, font, CENTER, color, Text));
update();
}
void CButton::addOverlay(CIntObject *newOverlay)
void CButton::addOverlay(std::shared_ptr<CIntObject> newOverlay)
{
delete overlay;
overlay = newOverlay;
addChild(newOverlay);
addChild(newOverlay.get());
overlay->moveTo(overlay->pos.centerIn(pos).topLeft());
update();
}
@ -235,6 +234,7 @@ CButton::CButton(Point position, const std::string &defName, const std::pair<std
CKeyShortcut(key),
callback(Callback)
{
defActions = 255-DISPOSE;
addUsedEvents(LCLICK | RCLICK | HOVER | KEYBOARD);
stateToIndex[0] = 0;
@ -243,8 +243,6 @@ CButton::CButton(Point position, const std::string &defName, const std::pair<std
stateToIndex[3] = 3;
state=NORMAL;
image = nullptr;
overlay = nullptr;
currentImage = -1;
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)
{
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)
image->playerColored(LOCPLINT->playerID);
pos = image->pos;
@ -317,9 +315,7 @@ CToggleBase::CToggleBase(CFunctionList<void (bool)> callback):
{
}
CToggleBase::~CToggleBase()
{
}
CToggleBase::~CToggleBase() = default;
void CToggleBase::doSelect(bool on)
{
@ -399,25 +395,30 @@ void CToggleGroup::addCallback(std::function<void(int)> 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)
intObj->parent->removeChild(intObj);
addChild(intObj);
addChild(intObj.get());
}
bt->addCallback([=] (bool on) { if (on) selectionChanged(identifier);});
bt->allowDeselection = false;
button->addCallback([=] (bool on) { if (on) selectionChanged(identifier);});
button->allowDeselection = false;
assert(buttons[identifier] == nullptr);
buttons[identifier] = bt;
if(buttons.count(identifier)>0)
logAnim->error("Duplicated toggle button id %d", identifier);
buttons[identifier] = button;
}
CToggleGroup::CToggleGroup(const CFunctionList<void(int)> &OnChange)
: onChange(OnChange), selectedID(-2)
{}
: onChange(OnChange), selectedID(-2)
{
}
void CToggleGroup::setSelected(int id)
{
@ -443,15 +444,13 @@ void CToggleGroup::selectionChanged(int to)
parent->redraw();
}
CVolumeSlider::CVolumeSlider(const Point &position, const std::string &defName, const int value,
const std::pair<std::string, std::string> * const help) :
CVolumeSlider::CVolumeSlider(const Point & position, const std::string & defName, const int value, const std::pair<std::string, std::string> * const help)
: CIntObject(LCLICK | RCLICK | WHEEL),
value(value),
helpHandlers(help)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
animImage = new CAnimImage(std::make_shared<CAnimation>(defName), 0, 0, position.x, position.y),
assert(!defName.empty());
addUsedEvents(LCLICK | RCLICK | WHEEL);
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
animImage = std::make_shared<CAnimImage>(std::make_shared<CAnimation>(defName), 0, 0, position.x, position.y),
pos.x += position.x;
pos.y += position.y;
pos.w = (animImage->pos.w + 1) * animImage->size();
@ -658,25 +657,20 @@ void CSlider::clickLeft(tribool down, bool previousState)
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)
{
}
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;
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
setAmount(amount);
vstd::amax(value, 0);
vstd::amin(value, positions);
addUsedEvents(LCLICK | KEYBOARD | WHEEL);
strongInterest = true;
pos.x += position.x;
@ -684,12 +678,12 @@ CSlider::CSlider(Point position, int totalw, std::function<void(int)> Moved, int
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...)
left = new CButton(Point(), name, CButton::tooltip());
right = new CButton(Point(), name, CButton::tooltip());
slider = new CButton(Point(), name, CButton::tooltip());
left = std::make_shared<CButton>(Point(), name, CButton::tooltip());
right = std::make_shared<CButton>(Point(), name, CButton::tooltip());
slider = std::make_shared<CButton>(Point(), name, CButton::tooltip());
left->setImageOrder(0, 1, 1, 1);
right->setImageOrder(2, 3, 3, 3);
@ -697,9 +691,9 @@ CSlider::CSlider(Point position, int totalw, std::function<void(int)> Moved, int
}
else
{
left = new CButton(Point(), horizontal ? "SCNRBLF.DEF" : "SCNRBUP.DEF", CButton::tooltip());
right = new CButton(Point(), horizontal ? "SCNRBRT.DEF" : "SCNRBDN.DEF", CButton::tooltip());
slider = new CButton(Point(), "SCNRBSL.DEF", CButton::tooltip());
left = std::make_shared<CButton>(Point(), horizontal ? "SCNRBLF.DEF" : "SCNRBUP.DEF", CButton::tooltip());
right = std::make_shared<CButton>(Point(), horizontal ? "SCNRBRT.DEF" : "SCNRBDN.DEF", CButton::tooltip());
slider = std::make_shared<CButton>(Point(), "SCNRBSL.DEF", CButton::tooltip());
}
slider->actOnDown = true;
slider->soundDisabled = true;
@ -729,6 +723,8 @@ CSlider::CSlider(Point position, int totalw, std::function<void(int)> Moved, int
updateSliderPos();
}
CSlider::~CSlider() = default;
void CSlider::block( bool 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::string helpBox; //for right-click help
CAnimImage * image; //image for this button
CIntObject * overlay;//object-overlay, can be null
std::shared_ptr<CAnimImage> image; //image for this button
std::shared_ptr<CIntObject> overlay;//object-overlay, can be null
bool animateLonelyFrame = false;
protected:
void onButtonClicked(); // calls callback
@ -80,8 +80,8 @@ public:
void addCallback(std::function<void()> callback);
/// adds overlay on top of button image. Only one overlay can be active at once
void addOverlay(CIntObject * newOverlay);
void addTextOverlay(const std::string &Text, EFonts font, SDL_Color color = Colors::WHITE);
void addOverlay(std::shared_ptr<CIntObject> newOverlay);
void addTextOverlay(const std::string & Text, EFonts font, SDL_Color color = Colors::WHITE);
void addImage(std::string filename);
void addHoverText(ButtonState state, std::string text);
@ -95,7 +95,7 @@ public:
bool isHighlighted();
/// 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 );
/// Appearance modifiers
@ -162,14 +162,15 @@ class CToggleGroup : public CIntObject
int selectedID;
void selectionChanged(int to);
public:
std::map<int, CToggleBase*> buttons;
std::map<int, std::shared_ptr<CToggleBase>> buttons;
CToggleGroup(const CFunctionList<void(int)> & OnChange);
void addCallback(std::function<void(int)> callback);
void resetCallback();
/// 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
void setSelected(int id);
};
@ -179,7 +180,7 @@ class CVolumeSlider : public CIntObject
{
int value;
CFunctionList<void(int)> onChange;
CAnimImage * animImage;
std::shared_ptr<CAnimImage> animImage;
const std::pair<std::string, std::string> * const helpHandlers;
void setVolume(const int v);
public:
@ -188,7 +189,7 @@ public:
/// @param defName name of def animation for slider
/// @param value initial value for volume
/// @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);
void moveTo(int id);
@ -203,7 +204,11 @@ public:
/// A typical slider which can be orientated horizontally/vertically.
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 positions; //number of highest position (0 if there is only one)
bool horizontal;
@ -216,7 +221,8 @@ class CSlider : public CIntObject
void sliderClicked();
public:
enum EStyle {
enum EStyle
{
BROWN,
BLUE
};

View File

@ -30,27 +30,31 @@
#include "../../lib/mapObjects/CGHeroInstance.h"
CHeroArtPlace::CHeroArtPlace(Point position, const CArtifactInstance * Art): CArtPlace(position, Art),
locked(false), picked(false), marked(false), ourOwner(nullptr)
CHeroArtPlace::CHeroArtPlace(Point position, const CArtifactInstance * Art)
: CArtPlace(position, Art),
locked(false),
picked(false),
marked(false),
ourOwner(nullptr)
{
createImage();
}
void CHeroArtPlace::createImage()
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
int imageIndex = 0;
if (ourArt)
si32 imageIndex = 0;
if(ourArt)
imageIndex = ourArt->artType->iconIndex;
if (locked)
if(locked)
imageIndex = ArtifactID::ART_LOCK;
image = new CAnimImage("artifact", imageIndex);
if (!ourArt)
image = std::make_shared<CAnimImage>("artifact", imageIndex);
if(!ourArt)
image->disable();
selection = new CAnimImage("artifact", ArtifactID::ART_SELECTION);
selection = std::make_shared<CAnimImage>("artifact", ArtifactID::ART_SELECTION);
selection->disable();
}
@ -137,7 +141,7 @@ void CHeroArtPlace::clickLeft(tribool down, bool previousState)
{
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.
return;
}
@ -284,8 +288,8 @@ void CHeroArtPlace::select ()
{
for(int i = 0; i < GameConstants::BACKPACK_START; i++)
{
CHeroArtPlace * ap = ourOwner->getArtPlace(i);
if(nullptr != ap)//getArtPlace may return null
auto ap = ourOwner->getArtPlace(i);
if(ap)//getArtPlace may return null
ap->pickSlot(ourArt->isPart(ap->ourArt));
}
}
@ -492,7 +496,7 @@ void CArtifactsOfHero::scrollBackpack(int dir)
{
if(elem->marked)
{
highlightModeCallback(elem);
highlightModeCallback(elem.get());
break;
}
}
@ -504,7 +508,6 @@ void CArtifactsOfHero::scrollBackpack(int dir)
rightArtRoll->block(!scrollingPossible);
safeRedraw();
}
/**
@ -538,9 +541,10 @@ void CArtifactsOfHero::unmarkSlots(bool withRedraw)
void CArtifactsOfHero::unmarkLocalSlots(bool withRedraw)
{
for(auto p : artWorn)
for(auto & p : artWorn)
p.second->selectSlot(false);
for(CHeroArtPlace *place : backpack)
for(auto & place : backpack)
place->selectSlot(false);
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.
*/
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
{
@ -572,21 +576,25 @@ void CArtifactsOfHero::setSlotData(CHeroArtPlace* artPlace, ArtifactPosition slo
/**
* 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->slotID = slotID;
artPlace->setArtifact(nullptr);
}
CArtifactsOfHero::CArtifactsOfHero(std::map<ArtifactPosition, CHeroArtPlace *> ArtWorn, std::vector<CHeroArtPlace *> Backpack,
CButton *leftScroll, CButton *rightScroll, bool createCommonPart):
curHero(nullptr),
artWorn(ArtWorn), backpack(Backpack),
backpackPos(0), commonInfo(nullptr), updateState(false),
leftArtRoll(leftScroll), rightArtRoll(rightScroll),
allowedAssembling(true), highlightModeCallback(nullptr)
CArtifactsOfHero::CArtifactsOfHero(ArtPlaceMap ArtWorn, std::vector<ArtPlacePtr> Backpack,
std::shared_ptr<CButton> leftScroll, std::shared_ptr<CButton> rightScroll, bool createCommonPart)
: curHero(nullptr),
artWorn(ArtWorn),
backpack(Backpack),
backpackPos(0),
commonInfo(nullptr),
updateState(false),
leftArtRoll(leftScroll),
rightArtRoll(rightScroll),
allowedAssembling(true),
highlightModeCallback(nullptr)
{
if(createCommonPart)
{
@ -595,7 +603,7 @@ CArtifactsOfHero::CArtifactsOfHero(std::map<ArtifactPosition, CHeroArtPlace *> A
}
// Init slots for worn artifacts.
for (auto p : artWorn)
for(auto p : artWorn)
{
p.second->ourOwner = this;
eraseSlotData(p.second, p.first);
@ -608,12 +616,17 @@ CArtifactsOfHero::CArtifactsOfHero(std::map<ArtifactPosition, CHeroArtPlace *> A
eraseSlotData(backpack[s], ArtifactPosition(GameConstants::BACKPACK_START + s));
}
leftArtRoll->addCallback(std::bind(&CArtifactsOfHero::scrollBackpack,this,-1));
rightArtRoll->addCallback(std::bind(&CArtifactsOfHero::scrollBackpack,this,+1));
leftArtRoll->addCallback(std::bind(&CArtifactsOfHero::scrollBackpack, this,-1));
rightArtRoll->addCallback(std::bind(&CArtifactsOfHero::scrollBackpack, this,+1));
}
CArtifactsOfHero::CArtifactsOfHero(const Point& position, bool createCommonPart)
: curHero(nullptr), backpackPos(0), commonInfo(nullptr), updateState(false), allowedAssembling(true), highlightModeCallback(nullptr)
CArtifactsOfHero::CArtifactsOfHero(const Point & position, bool createCommonPart)
: curHero(nullptr),
backpackPos(0),
commonInfo(nullptr),
updateState(false),
allowedAssembling(true),
highlightModeCallback(nullptr)
{
if(createCommonPart)
{
@ -621,7 +634,7 @@ CArtifactsOfHero::CArtifactsOfHero(const Point& position, bool createCommonPart)
commonInfo->participants.insert(this);
}
OBJ_CONSTRUCTION_CAPTURING_ALL;
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
pos += position;
std::vector<Point> slotPos =
@ -636,9 +649,9 @@ CArtifactsOfHero::CArtifactsOfHero(const Point& position, bool createCommonPart)
};
// 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;
eraseSlotData(artWorn[ArtifactPosition(g)], ArtifactPosition(g));
}
@ -646,7 +659,7 @@ CArtifactsOfHero::CArtifactsOfHero(const Point& position, bool createCommonPart)
// Create slots for the backpack.
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;
eraseSlotData(add, ArtifactPosition(GameConstants::BACKPACK_START + s));
@ -654,8 +667,8 @@ CArtifactsOfHero::CArtifactsOfHero(const Point& position, bool createCommonPart)
backpack.push_back(add);
}
leftArtRoll = new 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);
leftArtRoll = std::make_shared<CButton>(Point(379, 364), "hsbtns3.def", CButton::tooltip(), [&](){ scrollBackpack(-1);}, SDLK_LEFT);
rightArtRoll = std::make_shared<CButton>(Point(632, 364), "hsbtns5.def", CButton::tooltip(), [&](){ scrollBackpack(+1);}, SDLK_RIGHT);
}
CArtifactsOfHero::~CArtifactsOfHero()
@ -674,7 +687,6 @@ void CArtifactsOfHero::updateParentWindow()
}
else if(CExchangeWindow* cew = dynamic_cast<CExchangeWindow*>(GH.topInt()))
{
//use our copy of hero to draw window
if(cew->heroInst[0]->id == curHero->id)
cew->heroInst[0] = curHero;
@ -684,16 +696,7 @@ void CArtifactsOfHero::updateParentWindow()
if(!updateState)
{
cew->deactivate();
// for(int g=0; g<ARRAY_COUNT(cew->heroInst); ++g)
// {
// if(cew->heroInst[g] == curHero)
// {
// cew->artifs[g]->setHero(curHero);
// }
// }
cew->prepareBackground();
cew->updateWidgets();
cew->redraw();
cew->activate();
}
@ -746,7 +749,7 @@ void CArtifactsOfHero::artifactMoved(const ArtifactLocation &src, const Artifact
assert(dst.slot >= GameConstants::BACKPACK_START);
commonInfo->reset();
CHeroArtPlace *ap = nullptr;
CArtifactsOfHero::ArtPlacePtr ap;
for(CArtifactsOfHero *aoh : commonInfo->participants)
{
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)
{
@ -825,7 +828,7 @@ CHeroArtPlace * CArtifactsOfHero::getArtPlace(int slot)
}
else
{
for(CHeroArtPlace *ap : backpack)
for(ArtPlacePtr ap : backpack)
if(ap->slotID == slot)
return ap;
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)
{
for(CArtifactsOfHero *aoh : artSets)
aoh->artifactRemoved(artLoc);
for(auto artSetWeak : artSets)
{
std::shared_ptr<CArtifactsOfHero> realPtr = artSetWeak.lock();
if(realPtr)
realPtr->artifactRemoved(artLoc);
}
}
void CWindowWithArtifacts::artifactMoved(const ArtifactLocation &artLoc, const ArtifactLocation &destLoc)
{
CArtifactsOfHero *destaoh = nullptr;
for(CArtifactsOfHero *aoh : artSets)
CArtifactsOfHero * destaoh = nullptr;
for(auto artSetWeak : artSets)
{
aoh->artifactMoved(artLoc, destLoc);
aoh->redraw();
if(destLoc.isHolder(aoh->getHero()))
destaoh = aoh;
std::shared_ptr<CArtifactsOfHero> realPtr = artSetWeak.lock();
if(realPtr)
{
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
@ -893,14 +922,22 @@ void CWindowWithArtifacts::artifactMoved(const ArtifactLocation &artLoc, const A
void CWindowWithArtifacts::artifactDisassembled(const ArtifactLocation &artLoc)
{
for(CArtifactsOfHero *aoh : artSets)
aoh->artifactDisassembled(artLoc);
for(auto artSetWeak : artSets)
{
std::shared_ptr<CArtifactsOfHero> realPtr = artSetWeak.lock();
if(realPtr)
realPtr->artifactDisassembled(artLoc);
}
}
void CWindowWithArtifacts::artifactAssembled(const ArtifactLocation &artLoc)
{
for(CArtifactsOfHero *aoh : artSets)
aoh->artifactAssembled(artLoc);
for(auto artSetWeak : artSets)
{
std::shared_ptr<CArtifactsOfHero> realPtr = artSetWeak.lock();
if(realPtr)
realPtr->artifactAssembled(artLoc);
}
}
void CArtifactsOfHero::SCommonPart::Artpos::clear()
@ -979,14 +1016,14 @@ void CCommanderArtPlace::clickRight(tribool down, bool previousState)
void CCommanderArtPlace::createImage()
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
int imageIndex = 0;
if (ourArt)
if(ourArt)
imageIndex = ourArt->artType->iconIndex;
image = new CAnimImage("artifact", imageIndex);
if (!ourArt)
image = std::make_shared<CAnimImage>("artifact", imageIndex);
if(!ourArt)
image->disable();
}

View File

@ -9,7 +9,6 @@
*/
#pragma once
//#include "CComponent.h"
#include "MiscWidgets.h"
class CArtifactsOfHero;
@ -29,21 +28,10 @@ public:
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
{
protected:
CAnimImage *image;
std::shared_ptr<CAnimImage> image;
virtual void createImage()=0;
public:
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
class CHeroArtPlace: public CArtPlace
{
CAnimImage *selection;
std::shared_ptr<CAnimImage> selection;
void createImage() override;
@ -111,14 +99,10 @@ public:
/// Contains artifacts of hero. Distincts which artifacts are worn or backpacked
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:
using ArtPlacePtr = std::shared_ptr<CHeroArtPlace>;
using ArtPlaceMap = std::map<ArtifactPosition, ArtPlacePtr>;
struct SCommonPart
{
struct Artpos
@ -142,8 +126,10 @@ public:
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;
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
@ -152,7 +138,7 @@ public:
void artifactRemoved(const ArtifactLocation &al);
void artifactAssembled(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);
const CGHeroInstance *getHero() const;
@ -163,17 +149,41 @@ public:
void markPossibleSlots(const CArtifactInstance* art);
void unmarkSlots(bool withRedraw = true); //unmarks slots in all visible AOHs
void unmarkLocalSlots(bool withRedraw = true); //unmarks slots in that particular AOH
void setSlotData (CHeroArtPlace* artPlace, ArtifactPosition slotID);
void updateWornSlots (bool redrawParent = true);
void updateSlot(ArtifactPosition i);
void eraseSlotData (CHeroArtPlace* artPlace, ArtifactPosition slotID);
CArtifactsOfHero(const Point& position, bool createCommonPart = false);
//Alternative constructor, used if custom artifacts positioning required (Kingdom interface)
CArtifactsOfHero(std::map<ArtifactPosition, CHeroArtPlace *> ArtWorn, std::vector<CHeroArtPlace *> Backpack,
CButton *leftScroll, CButton *rightScroll, bool createCommonPart = false);
CArtifactsOfHero(ArtPlaceMap ArtWorn, std::vector<ArtPlacePtr> Backpack,
std::shared_ptr<CButton> leftScroll, std::shared_ptr<CButton> rightScroll, bool createCommonPart = false);
~CArtifactsOfHero();
void updateParentWindow();
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/NetPacksBase.h"
CComponent::CComponent(Etype Type, int Subtype, int Val, ESize imageSize):
image(nullptr),
perDay(false)
CComponent::CComponent(Etype Type, int Subtype, int Val, ESize imageSize)
: perDay(false)
{
addUsedEvents(RCLICK);
init(Type, Subtype, Val, imageSize);
}
CComponent::CComponent(const Component &c, ESize imageSize):
image(nullptr),
perDay(false)
CComponent::CComponent(const Component & c, ESize imageSize)
: perDay(false)
{
addUsedEvents(RCLICK);
if(c.id == Component::RESOURCE && c.when==-1)
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)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
addUsedEvents(RCLICK);
compType = Type;
subtype = Subtype;
@ -74,14 +71,15 @@ void CComponent::init(Etype Type, int Subtype, int Val, ESize imageSize)
for(auto & line : textLines)
{
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;
if (label->pos.w > pos.w)
if(label->pos.w > pos.w)
{
pos.x -= (label->pos.w - pos.w)/2;
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)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
vstd::clear_pointer(image);
image = new CAnimImage(defName, imgPos);
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
image = std::make_shared<CAnimImage>(defName, imgPos);
}
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)
return;
@ -339,14 +336,14 @@ void CComponentBox::placeComponents(bool selectable)
{
static const int betweenRows = 22;
OBJ_CONSTRUCTION_CAPTURING_ALL;
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
if (components.empty())
return;
//prepare components
for(auto & comp : components)
{
addChild(comp);
addChild(comp.get());
comp->moveTo(Point(pos.x, pos.y));
}
@ -362,14 +359,14 @@ void CComponentBox::placeComponents(bool selectable)
rows.push_back (RowData (0,0,0));
//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
//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
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)
{
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));
@ -438,27 +435,16 @@ void CComponentBox::placeComponents(bool selectable)
}
}
CComponentBox::CComponentBox(CComponent * _components, Rect position):
components(1, _components),
selected(nullptr)
CComponentBox::CComponentBox(std::vector<std::shared_ptr<CComponent>> _components, Rect position):
components(_components)
{
type |= REDRAW_PARENT;
pos = position + pos;
placeComponents(false);
}
CComponentBox::CComponentBox(std::vector<CComponent *> _components, Rect position):
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):
CComponentBox::CComponentBox(std::vector<std::shared_ptr<CSelectableComponent>> _components, Rect position, std::function<void(int newID)> _onSelect):
components(_components.begin(), _components.end()),
selected(nullptr),
onSelect(_onSelect)
{
type |= REDRAW_PARENT;

View File

@ -13,6 +13,7 @@
struct Component;
class CAnimImage;
class CLabel;
/// common popup window component
class CComponent : public virtual CIntObject
@ -34,6 +35,8 @@ public:
};
private:
std::vector<std::shared_ptr<CLabel>> lines;
size_t getIndex();
const std::vector<std::string> getFileName();
void setSurface(std::string defName, int imgPos);
@ -42,7 +45,7 @@ private:
void init(Etype Type, int Subtype, int Val, ESize imageSize);
public:
CAnimImage *image; //our image
std::shared_ptr<CAnimImage> image;
Etype compType; //component type
ESize size; //component size.
@ -72,19 +75,21 @@ public:
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(const Component &c, std::function<void()> OnSelect = nullptr);
CSelectableComponent(const Component & c, std::function<void()> OnSelect = nullptr);
};
/// box with multiple components (up to 8?)
/// will take ownership on components and delete them afterwards
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;
void selectionChanged(CSelectableComponent * newSelection);
void selectionChanged(std::shared_ptr<CSelectableComponent> newSelection);
//get position of "or" text between these comps
//it will place "or" equidistant to both images
@ -98,14 +103,11 @@ public:
/// return index of selected item
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
CComponentBox(std::vector<CComponent *> components, Rect position);
CComponentBox(std::vector<std::shared_ptr<CComponent>> components, Rect position);
/// constructor for selectable components
/// will also create "or" labels between components
/// 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;
if (CWindowWithArtifacts* chw = dynamic_cast<CWindowWithArtifacts*>(GH.topInt())) //dirty solution
{
const std::shared_ptr<CArtifactsOfHero::SCommonPart> commonInfo = chw->artSets.front()->commonInfo;
if (const CArtifactInstance *art = commonInfo->src.art)
const std::shared_ptr<CArtifactsOfHero::SCommonPart> commonInfo = chw->getCommonPart();
const CArtifactInstance * art = nullptr;
if(commonInfo)
art = commonInfo->src.art;
if(art)
{
const CGHeroInstance *srcHero = commonInfo->src.AOH->getHero();
artSelected = true;
@ -335,7 +339,7 @@ void CGarrisonSlot::clickLeft(tribool down, bool previousState)
void CGarrisonSlot::update()
{
if (getObj() != nullptr)
if(getObj() != nullptr)
{
addUsedEvents(LCLICK | RCLICK | HOVER);
myStack = getObj()->getStackPtr(ID);
@ -348,7 +352,7 @@ void CGarrisonSlot::update()
creature = nullptr;
}
if (creature)
if(creature)
{
creatureImage->enable();
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):
ID(IID),
owner(Owner),
myStack(Creature),
creature(Creature ? Creature->type : nullptr),
upg(Upg)
CGarrisonSlot::CGarrisonSlot(CGarrisonInt * Owner, int x, int y, SlotID IID, CGarrisonSlot::EGarrisonType Upg, const CStackInstance * Creature)
: ID(IID),
owner(Owner),
myStack(Creature),
creature(nullptr),
upg(Upg)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
if (getObj())
addUsedEvents(LCLICK | RCLICK | HOVER);
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
pos.x += x;
pos.y += y;
std::string imgName = owner->smallIcons ? "cprsmall" : "TWCRPORT";
creatureImage = new CAnimImage(imgName, creature ? creature->iconIndex : 0);
if (!creature)
creatureImage->disable();
creatureImage = std::make_shared<CAnimImage>(imgName, 0);
creatureImage->disable();
selectionImage = new CAnimImage(imgName, 1);
selectionImage = std::make_shared<CAnimImage>(imgName, 1);
selectionImage->disable();
if(Owner->smallIcons)
@ -396,11 +398,9 @@ CGarrisonSlot::CGarrisonSlot(CGarrisonInt *Owner, int x, int y, SlotID IID, CGar
pos.h = 64;
}
stackCount = new CLabel(pos.w, pos.h, owner->smallIcons ? FONT_TINY : FONT_MEDIUM, BOTTOMRIGHT, Colors::WHITE);
if (!creature)
stackCount->disable();
else
stackCount->setText(boost::lexical_cast<std::string>(myStack->count));
stackCount = std::make_shared<CLabel>(pos.w, pos.h, owner->smallIcons ? FONT_TINY : FONT_MEDIUM, BOTTOMRIGHT, Colors::WHITE);
update();
}
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()
{
const Uint8 * state = SDL_GetKeyboardState(NULL);
if(owner->getSelection() && owner->getEmptySlots(owner->getSelection()->upg).size() && owner->getSelection()->myStack->count > 1){
if (state[SDL_SCANCODE_LCTRL] && state[SDL_SCANCODE_LSHIFT])
if(owner->getSelection() && owner->getEmptySlots(owner->getSelection()->upg).size() && owner->getSelection()->myStack->count > 1)
{
if(state[SDL_SCANCODE_LCTRL] && state[SDL_SCANCODE_LSHIFT])
splitIntoParts(owner->getSelection()->upg, 1, 7);
else if(state[SDL_SCANCODE_LCTRL])
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);
button->recActions = defActions;
addChild(button.get());
button->recActions &= ~DISPOSE;
splitButtons.push_back(button);
button->block(getSelection() == nullptr);
}
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++)
{
std::vector<CGarrisonSlot*> garrisonSlots;
std::vector<std::shared_ptr<CGarrisonSlot>> garrisonSlots;
garrisonSlots.resize(7);
if (armedObjs[i])
if(armedObjs[i])
{
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++)
{
if(!garrisonSlots[j])
garrisonSlots[j] = new CGarrisonSlot(this, i*garOffset.x + (j*distance), i*garOffset.y, SlotID(j), static_cast<CGarrisonSlot::EGarrisonType>(i), nullptr);
if (twoRows && j>=4)
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)
{
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)
elem->block(true);
for(CGarrisonSlot * slot : availableSlots)
for(auto slot : availableSlots)
slot->update();
}
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);
}
CGarrisonInt::CGarrisonInt(int x, int y, int inx, const Point &garsOffset,
SDL_Surface *pomsur, const Point& SurOffset,
const CArmedInstance *s1, const CArmedInstance *s2,
bool _removableUnits, bool smallImgs, bool _twoRows ) :
highlighted(nullptr),
inSplittingMode(false),
interx(inx),
garOffset(garsOffset),
pb(false),
smallIcons(smallImgs),
removableUnits(_removableUnits),
twoRows(_twoRows)
CGarrisonInt::CGarrisonInt(int x, int y, int inx, const Point & garsOffset,
const CArmedInstance * s1, const CArmedInstance * s2,
bool _removableUnits, bool smallImgs, bool _twoRows)
: highlighted(nullptr),
inSplittingMode(false),
interx(inx),
garOffset(garsOffset),
pb(false),
smallIcons(smallImgs),
removableUnits(_removableUnits),
twoRows(_twoRows)
{
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
setArmy(s1, false);
setArmy(s2, true);
pos.x += x;
@ -521,16 +520,16 @@ const CGarrisonSlot * CGarrisonInt::getSelection()
void CGarrisonInt::selectSlot(CGarrisonSlot *slot)
{
if (slot != highlighted)
if(slot != highlighted)
{
if (highlighted)
if(highlighted)
highlighted->setHighlight(false);
highlighted = slot;
for (auto button : splitButtons)
for(auto button : splitButtons)
button->block(highlighted == nullptr || !slot->our());
if (highlighted)
if(highlighted)
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
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)));
}
inSplittingMode = on;
@ -558,58 +557,16 @@ bool CGarrisonInt::getSplittingMode()
std::vector<CGarrisonSlot *> CGarrisonInt::getEmptySlots(CGarrisonSlot::EGarrisonType type)
{
std::vector<CGarrisonSlot *> emptySlots;
for(CGarrisonSlot * slot : availableSlots)
for(auto slot : availableSlots)
{
if(type == slot->upg && ((slot->our() || slot->ally()) && slot->creature == nullptr))
emptySlots.push_back(slot);
emptySlots.push_back(slot.get());
}
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;
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
CGarrisonInt *owner;
const CStackInstance *myStack; //nullptr if slot is empty
const CCreature *creature;
const CStackInstance * myStack; //nullptr if slot is empty
const CCreature * creature;
/// Type of Garrison for slot (up or down)
enum EGarrisonType
@ -35,9 +35,9 @@ class CGarrisonSlot : public CIntObject
DOWN, ///< 1 - down garrison (Visiting)
} upg; ///< Flag indicating if it is the up or down garrison
CAnimImage * creatureImage;
CAnimImage * selectionImage; // image for selection, not always visible
CLabel * stackCount;
std::shared_ptr<CAnimImage> creatureImage;
std::shared_ptr<CAnimImage> selectionImage; // image for selection, not always visible
std::shared_ptr<CLabel> stackCount;
bool viewInfo();
bool highlightOrDropArtifact();
@ -65,19 +65,15 @@ public:
class CGarrisonInt :public CIntObject
{
/// Chosen slot. Should be changed only via selectSlot.
CGarrisonSlot *highlighted;
CGarrisonSlot * highlighted;
bool inSplittingMode;
std::vector<std::shared_ptr<CGarrisonSlot>> availableSlots; ///< Slots of upper and lower garrison
void createSlots();
public:
void selectSlot(CGarrisonSlot * slot); ///< @param slot null = deselect
const CGarrisonSlot * getSelection();
void setSplittingMode(bool on);
bool getSplittingMode();
int interx; ///< Space between slots
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
bool pb,
@ -86,15 +82,19 @@ public:
twoRows, ///< slots Will be placed in 2 rows
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);
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 addSplitBtn(CButton * button);
void setArmy(const CArmedInstance * army, bool bottomGarrison);
void addSplitBtn(std::shared_ptr<CButton> button);
void createSlots();
void recreateSlots();
void splitClick(); ///< handles click on split button
@ -104,40 +104,21 @@ public:
/// @param x, y Position
/// @param inx Distance between slots;
/// @param garsOffset
/// @param pomsur, SurOffset UNUSED
/// @param s1, s2 Top and bottom armies
/// @param _removableUnits You can take units from top
/// @param smallImgs Units images size 64x58 or 32x32
/// @param _twoRows Display slots in 2 row (1st row = 4 slots, 2nd = 3 slots)
CGarrisonInt(int x, int y,
int inx,
const Point &garsOffset,
SDL_Surface *pomsur, const Point &SurOffset,
const CArmedInstance *s1, const CArmedInstance *s2=nullptr,
bool _removableUnits = true,
bool smallImgs = false,
bool _twoRows=false);
CGarrisonInt(int x, int y, int inx,
const Point & garsOffset,
const CArmedInstance * s1, const CArmedInstance * s2 = nullptr,
bool _removableUnits = true,
bool smallImgs = false,
bool _twoRows = false);
};
class CGarrisonHolder
{
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;
}
void CPicture::colorizeAndConvert(PlayerColor player)
{
assert(bg);
colorize(player);
convertToScreenBPP();
}
void CPicture::colorize(PlayerColor player)
{
assert(bg);
@ -257,9 +250,6 @@ void CAnimImage::init()
CAnimImage::~CAnimImage()
{
anim->unload(frame, group);
if (flags & CShowableAnim::BASE)
anim->unload(0,group);
}
void CAnimImage::showAll(SDL_Surface * to)
@ -281,7 +271,6 @@ void CAnimImage::setFrame(size_t Frame, size_t Group)
return;
if (anim->size(Group) > Frame)
{
anim->unload(frame, group);
anim->load(Frame, Group);
frame = Frame;
group = Group;
@ -348,8 +337,9 @@ bool CShowableAnim::set(size_t Group, size_t from, size_t to)
if (max < from || max == 0)
return false;
anim->load(Group);
anim->unload(group);
anim->unloadGroup(group);
anim->loadGroup(Group);
group = Group;
frame = first = from;
last = max;
@ -363,8 +353,9 @@ bool CShowableAnim::set(size_t Group)
return false;
if (group != Group)
{
anim->loadGroup(Group);
anim->unloadGroup(group);
anim->loadGroup(Group);
first = 0;
group = Group;
last = anim->size(Group);

View File

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

View File

@ -87,7 +87,7 @@ void LRClickableAreaWTextComp::clickLeft(tribool down, bool previousState)
{
if((!down) && previousState)
{
std::vector<CComponent*> comp(1, createComponent());
std::vector<std::shared_ptr<CComponent>> comp(1, createComponent());
LOCPLINT->showInfoDialog(text, comp);
}
}
@ -98,19 +98,19 @@ LRClickableAreaWTextComp::LRClickableAreaWTextComp(const Rect &Pos, int BaseType
type = -1;
}
CComponent * LRClickableAreaWTextComp::createComponent() const
std::shared_ptr<CComponent> LRClickableAreaWTextComp::createComponent() const
{
if(baseType >= 0)
return new CComponent(CComponent::Etype(baseType), type, bonusValue);
return std::make_shared<CComponent>(CComponent::Etype(baseType), type, bonusValue);
else
return nullptr;
return std::shared_ptr<CComponent>();
}
void LRClickableAreaWTextComp::clickRight(tribool down, bool previousState)
{
if(down)
{
if(CComponent *comp = createComponent())
if(auto comp = createComponent())
{
CRClickPopup::createAndPush(text, CInfoWindow::TCompsInfo(1, comp));
return;
@ -120,16 +120,19 @@ void LRClickableAreaWTextComp::clickRight(tribool down, bool previousState)
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.w = 58;
pos.y += y; pos.h = 64;
pos.x += x;
pos.w = 58;
pos.y += y;
pos.h = 64;
if (hero)
new CAnimImage("PortraitsLarge", hero->portrait);
if(hero)
portrait = std::make_shared<CAnimImage>("PortraitsLarge", hero->portrait);
}
void CHeroArea::clickLeft(tribool down, bool previousState)
@ -181,7 +184,8 @@ void CMinorResDataBar::show(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))
{
std::string text = boost::lexical_cast<std::string>(LOCPLINT->cb->getResourceAmount(i));
@ -202,34 +206,34 @@ void CMinorResDataBar::showAll(SDL_Surface * to)
CMinorResDataBar::CMinorResDataBar()
{
bg = BitmapHandler::loadBitmap("KRESBAR.bmp");
CSDL_Ext::setDefaultColorKey(bg);
graphics->blueToPlayersAdv(bg,LOCPLINT->playerID);
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
pos.x = 7;
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()
{
SDL_FreeSurface(bg);
}
CMinorResDataBar::~CMinorResDataBar() = default;
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;
slotsPos.push_back(Point(36,73));
slotsPos.push_back(Point(72,73));
slotsPos.push_back(Point(108,73));
slotsPos.push_back(Point(18,122));
slotsPos.push_back(Point(54,122));
slotsPos.push_back(Point(90,122));
slotsPos.push_back(Point(126,122));
slotsPos.push_back(Point(36, 73));
slotsPos.push_back(Point(72, 73));
slotsPos.push_back(Point(108, 73));
slotsPos.push_back(Point(18, 122));
slotsPos.push_back(Point(54, 122));
slotsPos.push_back(Point(90, 122));
slotsPos.push_back(Point(126, 122));
for(auto & slot : army.army)
{
@ -239,24 +243,26 @@ void CArmyTooltip::init(const InfoAboutArmy &army)
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;
if(army.army.isDetailed)
{
subtitle = boost::lexical_cast<std::string>(slot.second.count);
}
else
{
//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)];
}
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)
{
init(army);
@ -268,22 +274,21 @@ CArmyTooltip::CArmyTooltip(Point pos, const CArmedInstance * army):
init(InfoAboutArmy(army, true));
}
void CHeroTooltip::init(const InfoAboutHero &hero)
void CHeroTooltip::init(const InfoAboutHero & hero)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
new CAnimImage("PortraitsLarge", hero.portrait, 0, 3, 2);
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
portrait = std::make_shared<CAnimImage>("PortraitsLarge", hero.portrait, 0, 3, 2);
if(hero.details)
{
for (size_t i = 0; i < hero.details->primskills.size(); i++)
new CLabel(75 + 28 * i, 58, FONT_SMALL, CENTER, Colors::WHITE,
boost::lexical_cast<std::string>(hero.details->primskills[i]));
for(size_t i = 0; i < hero.details->primskills.size(); i++)
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])));
new CLabel(158, 98, FONT_TINY, CENTER, Colors::WHITE,
boost::lexical_cast<std::string>(hero.details->mana));
labels.push_back(std::make_shared<CLabel>(158, 98, FONT_TINY, CENTER, Colors::WHITE, boost::lexical_cast<std::string>(hero.details->mana)));
new CAnimImage("IMRL22", hero.details->morale + 3, 0, 5, 74);
new CAnimImage("ILCK22", hero.details->luck + 3, 0, 5, 91);
morale = std::make_shared<CAnimImage>("IMRL22", hero.details->morale + 3, 0, 5, 74);
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));
}
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
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);
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)
{
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)
new CLabel(157, 58, FONT_TINY, CENTER, Colors::WHITE,
if(town.details->goldIncome)
{
income = std::make_shared<CLabel>(157, 58, FONT_TINY, CENTER, Colors::WHITE,
boost::lexical_cast<std::string>(town.details->goldIncome));
}
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.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);
new CAnimImage("SMALRES", Res::ORE , 0, 7, 88);
res1 = std::make_shared<CAnimImage>("SMALRES", Res::WOOD, 0, 7, 75);
res2 = std::make_shared<CAnimImage>("SMALRES", Res::ORE , 0, 7, 88);
}
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):
CArmyTooltip(pos, town)
CTownTooltip::CTownTooltip(Point pos, const InfoAboutTown & town)
: CArmyTooltip(pos, town)
{
init(town);
}
CTownTooltip::CTownTooltip(Point pos, const CGTownInstance * town):
CArmyTooltip(pos, InfoAboutTown(town, true))
CTownTooltip::CTownTooltip(Point pos, const CGTownInstance * town)
: CArmyTooltip(pos, 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 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.
@ -363,13 +371,15 @@ void MoraleLuckBox::set(const IBonusBearer *node)
int (IBonusBearer::*getValue[])() const = {&IBonusBearer::LuckVal, &IBonusBearer::MoraleVal};
TBonusListPtr modifierList(new BonusList());
if (node)
if(node)
{
modifierList = node->getBonuses(Selector::type(bonusType[morale]));
bonusValue = (node->*getValue[morale])();
}
else
{
bonusValue = 0;
}
int mrlt = (bonusValue>0)-(bonusValue<0); //signum: -1 - bad luck / morale, 0 - neutral, 1 - good
hoverText = CGI->generaltexth->heroscrn[hoverTextBase[morale] - mrlt];
@ -420,23 +430,22 @@ void MoraleLuckBox::set(const IBonusBearer *node)
else
imageName = morale ? "IMRL42" : "ILCK42";
delete image;
image = new CAnimImage(imageName, bonusValue + 3);
image = std::make_shared<CAnimImage>(imageName, bonusValue + 3);
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):
image(nullptr),
morale(Morale),
MoraleLuckBox::MoraleLuckBox(bool Morale, const Rect &r, bool Small)
: morale(Morale),
small(Small)
{
bonusValue = 0;
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.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);
if(Big)
bg = new CPicture(CGI->townh->factions[faction]->creatureBg130);
bg = std::make_shared<CPicture>(CGI->townh->factions[faction]->creatureBg130);
else
bg = new CPicture(CGI->townh->factions[faction]->creatureBg120);
anim = new CCreatureAnim(0, 0, cre->animDefName, Rect());
bg = std::make_shared<CPicture>(CGI->townh->factions[faction]->creatureBg120);
anim = std::make_shared<CCreatureAnim>(0, 0, cre->animDefName, Rect());
anim->clipRect(cre->isDoubleWide()?170:150, 155, bg->pos.w, bg->pos.h);
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.h = bg->pos.h;
}
void CCreaturePic::show(SDL_Surface *to)
void CCreaturePic::show(SDL_Surface * to)
{
// redraw everything in a proper order
bg->showAll(to);
@ -468,7 +477,7 @@ void CCreaturePic::show(SDL_Surface *to)
void CCreaturePic::setAmount(int newAmount)
{
if (newAmount != 0)
if(newAmount != 0)
amount->setText(boost::lexical_cast<std::string>(newAmount));
else
amount->setText("");

View File

@ -15,7 +15,6 @@ class CLabel;
class CCreatureAnim;
class CComponent;
class CGGarrison;
class CSelectableComponent;
struct InfoAboutArmy;
class CArmedInstance;
class IBonusBearer;
@ -40,7 +39,7 @@ public:
std::string text;
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();
void init();
@ -51,9 +50,12 @@ public:
/// base class for hero/town/garrison tooltips
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:
CArmyTooltip(Point pos, const InfoAboutArmy &army);
CArmyTooltip(Point pos, const InfoAboutArmy & army);
CArmyTooltip(Point pos, const CArmedInstance * army);
};
@ -62,9 +64,14 @@ public:
/// background for tooltip: HEROQVBK
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:
CHeroTooltip(Point pos, const InfoAboutHero &hero);
CHeroTooltip(Point pos, const InfoAboutHero & hero);
CHeroTooltip(Point pos, const CGHeroInstance * hero);
};
@ -73,9 +80,17 @@ public:
/// background for tooltip: TOWNQVBK
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:
CTownTooltip(Point pos, const InfoAboutTown &town);
CTownTooltip(Point pos, const InfoAboutTown & town);
CTownTooltip(Point pos, const CGTownInstance * town);
};
@ -83,22 +98,21 @@ public:
class CCreaturePic : public CIntObject
{
private:
CPicture *bg;
CCreatureAnim *anim; //displayed animation
CLabel * amount;
std::shared_ptr<CPicture> bg;
std::shared_ptr<CCreatureAnim> anim; //displayed animation
std::shared_ptr<CLabel> amount;
void show(SDL_Surface *to) override;
void show(SDL_Surface * to) override;
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);
};
/// Resource bar like that at the bottom of the adventure map screen
class CMinorResDataBar : public CIntObject
{
std::shared_ptr<CPicture> background;
public:
SDL_Surface *bg; //background bitmap
void show(SDL_Surface * to) override;
void showAll(SDL_Surface * to) override;
CMinorResDataBar();
@ -109,8 +123,9 @@ public:
class CHeroArea: public CIntObject
{
const CGHeroInstance * hero;
public:
std::shared_ptr<CAnimImage> portrait;
public:
CHeroArea(int x, int y, const CGHeroInstance * _hero);
void clickLeft(tribool down, bool previousState) override;
@ -128,7 +143,7 @@ public:
virtual void clickRight(tribool down, bool previousState) override;
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
@ -143,7 +158,7 @@ public:
class MoraleLuckBox : public LRClickableAreaWTextComp
{
CAnimImage *image;
std::shared_ptr<CAnimImage> image;
public:
bool morale; //true if morale, false if luck
bool small;

View File

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

View File

@ -22,52 +22,50 @@ class CAnimation;
class CObjectList : public CIntObject
{
public:
typedef std::function<CIntObject* (size_t)> CreateFunc;
typedef std::function<void(CIntObject *)> DestroyFunc;
typedef std::function<std::shared_ptr<CIntObject>(size_t)> CreateFunc;
private:
CreateFunc createObject;
DestroyFunc destroyObject;
protected:
//Internal methods for safe creation of items (Children capturing and activation/deactivation if needed)
void deleteItem(CIntObject* item);
CIntObject* createItem(size_t index);
void deleteItem(std::shared_ptr<CIntObject> item);
std::shared_ptr<CIntObject> createItem(size_t index);
CObjectList(CreateFunc create, DestroyFunc destroy = DestroyFunc());//Protected constructor
CObjectList(CreateFunc create);
};
/// Window element with multiple tabs
class CTabbedInt : public CObjectList
{
private:
CIntObject * activeTab;
std::shared_ptr<CIntObject> activeTab;
size_t activeID;
public:
//CreateFunc, DestroyFunc - see CObjectList
//Pos - position of object, all tabs will be moved to this position
//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);
//recreate active tab
void reset();
//return currently active item
CIntObject * getItem();
std::shared_ptr<CIntObject> getItem();
};
/// List of IntObjects with optional slider
class CListBox : public CObjectList
{
private:
std::list< CIntObject* > items;
std::list<std::shared_ptr<CIntObject>> items;
size_t first;
size_t totalSize;
Point itemOffset;
CSlider * slider;
std::shared_ptr<CSlider> slider;
void updatePositions();
public:
@ -78,7 +76,7 @@ public:
//TotalSize
//Slider - slider style, bit field: 1 = present(disabled), 2=horisontal(vertical), 4=blue(brown)
//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() );
//recreate all visible items
@ -89,13 +87,13 @@ public:
size_t size();
//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
const std::list< CIntObject * > & getItems();
const std::list<std::shared_ptr<CIntObject>> & getItems();
//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
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)
:CTextContainer(Align, Font, Color), text(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)
{
type |= REDRAW_PARENT;
autoRedraw = true;
pos.x += x;
pos.y += y;
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.h = graphics->fonts[font]->getLineHeight();
@ -73,7 +72,7 @@ void CLabel::setText(const std::string &Txt)
text = Txt;
if(autoRedraw)
{
if(bg || !parent)
if(background || !parent)
redraw();
else
parent->redraw();
@ -85,7 +84,7 @@ void CLabel::setColor(const SDL_Color & Color)
color = Color;
if(autoRedraw)
{
if(bg || !parent)
if(background || !parent)
redraw();
else
parent->redraw();
@ -259,14 +258,16 @@ Rect CMultiLineLabel::getTextLocation()
return Rect();
}
CLabelGroup::CLabelGroup(EFonts Font, EAlignment Align, const SDL_Color &Color):
font(Font), align(Align), color(Color)
{}
CLabelGroup::CLabelGroup(EFonts Font, EAlignment Align, const SDL_Color & Color)
: font(Font), align(Align), color(Color)
{
defActions = 255-DISPOSE;
}
void CLabelGroup::add(int x, int y, const std::string &text)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
labels.push_back(new CLabel(x, y, font, align, color, text));
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
labels.push_back(std::make_shared<CLabel>(x, y, font, align, color, text));
}
size_t CLabelGroup::currentSize() const
@ -278,8 +279,8 @@ CTextBox::CTextBox(std::string Text, const Rect &rect, int SliderStyle, EFonts F
sliderStyle(SliderStyle),
slider(nullptr)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
label = new CMultiLineLabel(rect, Font, Align, Color);
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
label = std::make_shared<CMultiLineLabel>(rect, Font, Align, Color);
type |= REDRAW_PARENT;
pos.x += rect.x;
@ -302,9 +303,8 @@ void CTextBox::resize(Point newSize)
pos.h = newSize.y;
label->pos.w = pos.w;
label->pos.h = pos.h;
if (slider)
vstd::clear_pointer(slider); // will be recreated if needed later
slider.reset();
setText(label->getText()); // force refresh
}
@ -315,7 +315,7 @@ void CTextBox::setText(const std::string &text)
if(label->textSize.y <= label->pos.h && slider)
{
// slider is no longer needed
vstd::clear_pointer(slider);
slider.reset();
}
else if(slider)
{
@ -330,8 +330,8 @@ void CTextBox::setText(const std::string &text)
label->pos.w = pos.w - 32;
label->setText(text);
OBJ_CONSTRUCTION_CAPTURING_ALL;
slider = new CSlider(Point(pos.w - 32, 0), pos.h, std::bind(&CTextBox::sliderMoved, this, _1),
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
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));
slider->setScrollStep(graphics->fonts[label->font]->getLineHeight());
}
@ -348,28 +348,28 @@ void CGStatusBar::clear()
setText("");
}
CGStatusBar::CGStatusBar(CPicture *BG, EFonts Font, EAlignment Align, const SDL_Color &Color)
: CLabel(BG->pos.x, BG->pos.y, Font, Align, Color, "")
CGStatusBar::CGStatusBar(std::shared_ptr<CPicture> background_, EFonts Font, EAlignment Align, const SDL_Color & Color)
: CLabel(background_->pos.x, background_->pos.y, Font, Align, Color, "")
{
init();
bg = BG;
addChild(bg);
pos = bg->pos;
background = background_;
addChild(background.get());
pos = background->pos;
getBorderSize();
textLock = false;
}
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();
bg = new CPicture(name);
pos = bg->pos;
background = std::make_shared<CPicture>(name);
pos = background->pos;
if((unsigned int)maxw < pos.w)
{
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;
}
@ -410,8 +410,8 @@ void CGStatusBar::lock(bool shouldLock)
textLock = shouldLock;
}
CTextInput::CTextInput(const Rect &Pos, EFonts font, const CFunctionList<void(const std::string &)> &CB):
CLabel(Pos.x, Pos.y, font, CENTER),
CTextInput::CTextInput(const Rect &Pos, EFonts font, const CFunctionList<void(const std::string &)> &CB)
: CLabel(Pos.x, Pos.y, font, CENTER),
cb(CB)
{
type |= REDRAW_PARENT;
@ -419,38 +419,38 @@ CTextInput::CTextInput(const Rect &Pos, EFonts font, const CFunctionList<void(co
pos.h = Pos.h;
pos.w = Pos.w;
captureAllKeys = true;
bg = nullptr;
background.reset();
addUsedEvents(LCLICK | KEYBOARD | TEXTINPUT);
giveFocus();
}
CTextInput::CTextInput( const Rect &Pos, const Point &bgOffset, const std::string &bgName, const CFunctionList<void(const std::string &)> &CB )
:cb(CB)
CTextInput::CTextInput(const Rect & Pos, const Point & bgOffset, const std::string & bgName, const CFunctionList<void(const std::string &)> & CB)
:cb(CB)
{
focus = false;
pos += Pos;
captureAllKeys = true;
OBJ_CONSTRUCTION;
bg = new CPicture(bgName, bgOffset.x, bgOffset.y);
background = std::make_shared<CPicture>(bgName, bgOffset.x, bgOffset.y);
addUsedEvents(LCLICK | KEYBOARD | TEXTINPUT);
giveFocus();
}
CTextInput::CTextInput(const Rect &Pos, SDL_Surface *srf)
CTextInput::CTextInput(const Rect & Pos, SDL_Surface * srf)
{
focus = false;
pos += Pos;
captureAllKeys = true;
OBJ_CONSTRUCTION;
bg = new CPicture(Pos, 0, true);
background = std::make_shared<CPicture>(Pos, 0, true);
Rect hlp = Pos;
if(srf)
CSDL_Ext::blitSurface(srf, &hlp, *bg, nullptr);
CSDL_Ext::blitSurface(srf, &hlp, *background.get(), nullptr);
else
SDL_FillRect(*bg, nullptr, 0);
pos.w = bg->pos.w;
pos.h = bg->pos.h;
bg->pos = pos;
SDL_FillRect(*background.get(), nullptr, 0);
pos.w = background->pos.w;
pos.h = background->pos.h;
background->pos = pos;
addUsedEvents(LCLICK | KEYBOARD | TEXTINPUT);
giveFocus();
}

View File

@ -40,7 +40,7 @@ protected:
Point getBorderSize() override;
virtual std::string visibleText();
CPicture *bg;
std::shared_ptr<CPicture> background;
public:
std::string text;
@ -60,7 +60,7 @@ public:
/// Small helper class to manage group of similar labels
class CLabelGroup : public CIntObject
{
std::list<CLabel*> labels;
std::vector<std::shared_ptr<CLabel>> labels;
EFonts font;
EAlignment align;
SDL_Color color;
@ -103,13 +103,13 @@ class CTextBox : public CIntObject
{
int sliderStyle;
public:
CMultiLineLabel * label;
CSlider *slider;
std::shared_ptr<CMultiLineLabel> label;
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 setText(const std::string &Txt);
void setText(const std::string & Txt);
void sliderMoved(int to);
};
@ -119,19 +119,18 @@ class CGStatusBar : public CLabel
bool textLock; //Used for blocking changes to the text
void init();
CGStatusBar *oldStatusBar;
CGStatusBar * oldStatusBar;
protected:
Point getBorderSize() override;
public:
void clear();//clears statusbar and refreshes
void setText(const std::string & Text) override; //prints text and refreshes statusbar
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(int x, int y, std::string name, int maxw=-1);
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();
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 keyPressed(const SDL_KeyboardEvent & key) override;
bool captureThisEvent(const SDL_KeyboardEvent & key) override;
void textInputed(const SDL_TextInputEvent & event) override;
void textEdited(const SDL_TextEditingEvent & event) override;

View File

@ -90,7 +90,7 @@ static void setScrollingCursor(ui8 direction)
CTerrainRect::CTerrainRect()
: fadeSurface(nullptr),
lastRedrawStatus(EMapAnimRedrawStatus::OK),
fadeAnim(new CFadeAnimation()),
fadeAnim(std::make_shared<CFadeAnimation>()),
curHoveredTile(-1,-1,-1),
currentPath(nullptr)
{
@ -106,9 +106,8 @@ CTerrainRect::CTerrainRect()
CTerrainRect::~CTerrainRect()
{
if (fadeSurface)
if(fadeSurface)
SDL_FreeSurface(fadeSurface);
delete fadeAnim;
}
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);
CSDL_Ext::setDefaultColorKey(bg);
graphics->blueToPlayersAdv(bg,LOCPLINT->playerID);
pos = genRect(bg->h, bg->w, pos.x+x, pos.y+y);
pos.x += x;
pos.y += y;
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
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);
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()
{
bg = BitmapHandler::loadBitmap(ADVOPT.resdatabarG);
CSDL_Ext::setDefaultColorKey(bg);
graphics->blueToPlayersAdv(bg,LOCPLINT->playerID);
pos = genRect(bg->h,bg->w,ADVOPT.resdatabarX,ADVOPT.resdatabarY);
pos.x += ADVOPT.resdatabarX;
pos.y += 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);
for (int i = 0; i < 8 ; i++)
@ -512,13 +520,11 @@ CResDataBar::CResDataBar()
+ ": %s, " + CGI->generaltexth->allTexts[64] + ": %s";
}
CResDataBar::~CResDataBar()
{
SDL_FreeSurface(bg);
}
CResDataBar::~CResDataBar() = default;
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))
{
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)
{
CIntObject::showAll(to);
draw(to);
}
@ -552,13 +559,13 @@ CAdvMapInt::CAdvMapInt():
heroList(ADVOPT.hlistSize, Point(ADVOPT.hlistX, ADVOPT.hlistY), ADVOPT.hlistAU, ADVOPT.hlistAD),
townList(ADVOPT.tlistSize, Point(ADVOPT.tlistX, ADVOPT.tlistY), ADVOPT.tlistAU, ADVOPT.tlistAD),
infoBar(Rect(ADVOPT.infoboxX, ADVOPT.infoboxY, 192, 192)), state(NA),
spellBeingCasted(nullptr), position(int3(0, 0, 0)), selection(nullptr),
updateScreen(false), anim(0), animValHitCount(0), heroAnim(0), heroAnimValHitCount(0),
spellBeingCasted(nullptr), position(int3(0, 0, 0)), selection(nullptr),
updateScreen(false), anim(0), animValHitCount(0), heroAnim(0), heroAnimValHitCount(0),
activeMapPanel(nullptr), duringAITurn(false), scrollingDir(0), scrollingState(false),
swipeEnabled(settings["general"]["swipe"].Bool()), swipeMovementRequested(false),
swipeTargetPosition(int3(-1, -1, -1))
{
adventureInt = this;
adventureInt = this;
pos.x = pos.y = 0;
pos.w = screen->w;
pos.h = screen->h;
@ -580,18 +587,17 @@ CAdvMapInt::CAdvMapInt():
}
worldViewIcons = std::make_shared<CAnimation>("VwSymbol");//todo: customize with ADVOPT
//preload all for faster map drawing
worldViewIcons->load();//TODO: make special method in CAnimation fro that
worldViewIcons->preload();
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);
for (auto image : info.additionalDefs)
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)
button->addImage(image);
return button;
};
@ -609,9 +615,9 @@ CAdvMapInt::CAdvMapInt():
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
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(underground);
@ -640,7 +646,7 @@ CAdvMapInt::CAdvMapInt():
worldViewPuzzleConfig.y = 343 + 195;
worldViewPuzzleConfig.playerColoured = false;
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);
config::ButtonInfo worldViewScale1xConfig = config::ButtonInfo();
@ -684,19 +690,19 @@ CAdvMapInt::CAdvMapInt():
for (int i = 0; i < 5; ++i)
{
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]));
}
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 + 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]));
}
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]));
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]));
activeMapPanel = panelMain;
@ -713,8 +719,6 @@ CAdvMapInt::CAdvMapInt():
CAdvMapInt::~CAdvMapInt()
{
SDL_FreeSurface(bg);
worldViewIcons->unload();
}
void CAdvMapInt::fshowOverview()
@ -846,7 +850,7 @@ void CAdvMapInt::fendTurn()
auto path = LOCPLINT->getAndVerifyPath(hero);
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;
}
}
@ -996,7 +1000,7 @@ void CAdvMapInt::showAll(SDL_Surface * to)
show(to);
resdatabar.draw(to);
resdatabar.showAll(to);
statusbar.show(to);
@ -1240,8 +1244,7 @@ void CAdvMapInt::keyPressed(const SDL_KeyboardEvent & key)
if(isActive() && LOCPLINT->ctrlPressed())
{
LOCPLINT->showYesNoDialog("Are you sure you want to restart game?",
[](){ LOCPLINT->sendCustomEvent(EUserEvent::RESTART_GAME); },
[](){}, true);
[](){ LOCPLINT->sendCustomEvent(EUserEvent::RESTART_GAME); }, nullptr);
}
return;
case SDLK_SPACE: //space - try to revisit current object with selected hero
@ -1503,7 +1506,7 @@ void CAdvMapInt::setPlayer(PlayerColor Player)
panelMain->setPlayerColor(player);
panelWorldView->setPlayerColor(player);
panelWorldView->recolorIcons(player, player.getNum() * 19);
graphics->blueToPlayersAdv(resdatabar.bg,player);
resdatabar.background->colorize(player);
}
void CAdvMapInt::startTurn()
@ -1926,24 +1929,24 @@ void CAdvMapInt::changeMode(EAdvMapMode newMode, float newScale)
}
}
CAdventureOptions::CAdventureOptions():
CWindowObject(PLAYER_COLORED, "ADVOPTS")
CAdventureOptions::CAdventureOptions()
: 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));
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);
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);
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));
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())
dig->addCallback(std::bind(&CPlayerInterface::tryDiggging, LOCPLINT, h));
else

View File

@ -38,23 +38,27 @@ enum class EAdvMapMode
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
{
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();
static void showScenarioInfo();
};
/// Holds information about which tiles of the terrain are shown/not shown at the screen
class CTerrainRect
: public CIntObject
class CTerrainRect : public CIntObject
{
SDL_Surface * fadeSurface;
EMapAnimRedrawStatus lastRedrawStatus;
CFadeAnimation * fadeAnim;
std::shared_ptr<CFadeAnimation> fadeAnim;
int3 swipeInitialMapPos;
int3 swipeInitialRealPos;
@ -69,10 +73,10 @@ public:
int tilesw, tilesh; //width and height of terrain to blit in tiles
int3 curHoveredTile;
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();
virtual ~CTerrainRect();
CGPath * currentPath;
void deactivate() override;
void clickLeft(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
void fadeFromCurrentView();
bool needsAnimUpdate();
};
/// Resources bar which shows information about how many gold, crystals,... you have
@ -98,7 +101,8 @@ public:
class CResDataBar : public CIntObject
{
public:
SDL_Surface * bg;
std::shared_ptr<CPicture> background;
std::vector<std::pair<int,int> > txtpos;
std::string datetext;
@ -162,22 +166,22 @@ public:
SDL_Surface * bg;
SDL_Surface * bgWorldView;
std::vector<CAnimImage *> gems;
std::vector<std::shared_ptr<CAnimImage>> gems;
CMinimap minimap;
CGStatusBar statusbar;
CButton * kingOverview;
CButton * underground;
CButton * questlog;
CButton * sleepWake;
CButton * moveHero;
CButton * spellbook;
CButton * advOptions;
CButton * sysOptions;
CButton * nextHero;
CButton * endTurn;
std::shared_ptr<CButton> kingOverview;
std::shared_ptr<CButton> underground;
std::shared_ptr<CButton> questlog;
std::shared_ptr<CButton> sleepWake;
std::shared_ptr<CButton> moveHero;
std::shared_ptr<CButton> spellbook;
std::shared_ptr<CButton> advOptions;
std::shared_ptr<CButton> sysOptions;
std::shared_ptr<CButton> nextHero;
std::shared_ptr<CButton> endTurn;
CButton * worldViewUnderground;
std::shared_ptr<CButton> worldViewUnderground;
CTerrainRect terrain; //visible terrain
CResDataBar resdatabar;
@ -185,9 +189,9 @@ public:
CTownList townList;
CInfoBar infoBar;
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
CAdvMapPanel *activeMapPanel; // currently active panel (either main or world view, depending on current mode)
std::shared_ptr<CAdvMapPanel> panelMain; // panel that holds all right-side buttons in normal view
std::shared_ptr<CAdvMapWorldViewPanel> panelWorldView; // panel that holds all buttons and other ui in world view
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

File diff suppressed because it is too large Load Diff

View File

@ -29,6 +29,8 @@ struct CStructure;
class CGHeroInstance;
class CGarrisonInt;
class CCreature;
class CComponent;
class CComponentBox;
/// Building "button"
class CBuildingRect : public CShowableAnim
@ -60,38 +62,43 @@ public:
/// Dwelling info box - right-click screen for dwellings
class CDwellingInfoBox : public CWindowObject
{
CLabel *title;
CCreaturePic *animation;
CLabel *available;
CLabel *costPerTroop;
std::shared_ptr<CLabel> title;
std::shared_ptr<CCreaturePic> animation;
std::shared_ptr<CLabel> available;
std::shared_ptr<CLabel> costPerTroop;
std::vector<CAnimImage *> resPicture;
std::vector<CLabel *> resAmount;
std::vector<std::shared_ptr<CAnimImage>> resPicture;
std::vector<std::shared_ptr<CLabel>> resAmount;
public:
CDwellingInfoBox(int centerX, int centerY, const CGTownInstance *Town, int level);
CDwellingInfoBox(int centerX, int centerY, const CGTownInstance * Town, int level);
~CDwellingInfoBox();
};
class HeroSlots;
/// Hero icon slot
class CHeroGSlot : public CIntObject
{
public:
HeroSlots *owner;
const CGHeroInstance *hero;
std::shared_ptr<CAnimImage> portrait;
std::shared_ptr<CAnimImage> flag;
std::shared_ptr<CAnimImage> selection; //selection border. nullptr if not selected
HeroSlots * owner;
const CGHeroInstance * hero;
int upg; //0 - up garrison, 1 - down garrison
CAnimImage *image;
CAnimImage *selection; //selection border. nullptr if not selected
public:
CHeroGSlot(int x, int y, int updown, const CGHeroInstance *h, HeroSlots * Owner);
~CHeroGSlot();
bool isSelected() const;
void setHighlight(bool on);
void set(const CGHeroInstance *newHero);
void set(const CGHeroInstance * newHero);
void hover (bool on) override;
void clickLeft(tribool down, bool previousState) override;
void clickRight(tribool down, bool previousState) 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
@ -101,11 +108,12 @@ public:
bool showEmpty;
const CGTownInstance * town;
CGarrisonInt *garr;
CHeroGSlot * garrisonedHero;
CHeroGSlot * visitingHero;
std::shared_ptr<CGarrisonInt> garr;
std::shared_ptr<CHeroGSlot> garrisonedHero;
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 update();
@ -115,11 +123,11 @@ public:
/// Class for town screen management (town background and structures)
class CCastleBuildings : public CIntObject
{
CPicture *background;
std::shared_ptr<CPicture> background;
//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
std::vector< CBuildingRect * > buildings;
std::vector<std::shared_ptr<CBuildingRect>> buildings;
const CGTownInstance * town;
@ -139,7 +147,7 @@ class CCastleBuildings : public CIntObject
public:
CBuildingRect * selectedBuilding;
CCastleBuildings(const CGTownInstance* town);
CCastleBuildings(const CGTownInstance * town);
~CCastleBuildings();
void enterDwelling(int level);
@ -157,18 +165,17 @@ public:
class CCreaInfo : public CIntObject
{
const CGTownInstance * town;
const CCreature *creature;
const CCreature * creature;
int level;
bool showAvailable;
CAnimImage *picture;
CLabel * label;
std::shared_ptr<CAnimImage> picture;
std::shared_ptr<CLabel> label;
int AddToString(std::string from, std::string & to, int numb);
std::string genGrowthText();
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 hover(bool on) override;
@ -179,48 +186,53 @@ public:
/// Town hall and fort icons for town screen
class CTownInfo : public CIntObject
{
const CGTownInstance *town;
const CBuilding *building;
const CGTownInstance * town;
const CBuilding * building;
public:
CAnimImage * picture;
std::shared_ptr<CAnimImage> picture;
//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 clickRight(tribool down, bool previousState) override;
};
/// Class which manages the castle window
class CCastleInterface : public CWindowObject, public CWindowWithGarrison
class CCastleInterface : public CWindowObject, public CGarrisonHolder
{
CLabel *title;
CLabel *income;
CAnimImage *icon;
std::shared_ptr<CLabel> title;
std::shared_ptr<CLabel> income;
std::shared_ptr<CAnimImage> icon;
CPicture * panel;
CResDataBar *resdatabar;
CGStatusBar * statusbar;
std::shared_ptr<CPicture> panel;
std::shared_ptr<CResDataBar> resdatabar;
std::shared_ptr<CGStatusBar> statusbar;
CTownInfo *hall, *fort;
std::shared_ptr<CTownInfo> hall;
std::shared_ptr<CTownInfo> fort;
CButton *exit;
CButton *split;
CButton * fastArmyPurhase;
std::shared_ptr<CButton> exit;
std::shared_ptr<CButton> split;
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:
CTownList * townlist;
std::shared_ptr<CTownList> townlist;
//TODO: move to private
const CGTownInstance * town;
HeroSlots *heroes;
CCastleBuildings *builds;
std::shared_ptr<HeroSlots> heroes;
std::shared_ptr<CCastleBuildings> builds;
std::shared_ptr<CGarrisonInt> garr;
//from - previously selected castle (if any)
CCastleInterface(const CGTownInstance * Town, const CGTownInstance * from = nullptr);
~CCastleInterface();
virtual void updateGarrisons() override;
void castleTeleport(int where);
void townChange();
void keyPressed(const SDL_KeyboardEvent & key) override;
@ -233,13 +245,17 @@ public:
/// Hall window where you can build things
class CHallInterface : public CWindowObject
{
/// Building box from town hall (building icon + subtitle)
class CBuildingBox : public CIntObject
{
const CGTownInstance * town;
const CBuilding * building;
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:
CBuildingBox(int x, int y, const CGTownInstance * Town, const CBuilding * Building);
void hover(bool on) override;
@ -248,11 +264,11 @@ class CHallInterface : public CWindowObject
};
const CGTownInstance * town;
std::vector< std::vector<CBuildingBox*> >boxes;
CLabel *title;
CGStatusBar *statusBar;
CMinorResDataBar * resdatabar;
CButton *exit;
std::vector<std::vector<std::shared_ptr<CBuildingBox>>> boxes;
std::shared_ptr<CLabel> title;
std::shared_ptr<CMinorResDataBar> resdatabar;
std::shared_ptr<CGStatusBar> statusbar;
std::shared_ptr<CButton> exit;
public:
CHallInterface(const CGTownInstance * Town);
@ -261,8 +277,18 @@ public:
/// Window where you can decide to buy a building or not
class CBuildWindow: public CWindowObject
{
const CGTownInstance *town;
const CBuilding *building;
const CGTownInstance * town;
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);
void buyFunc();
@ -274,8 +300,8 @@ public:
class LabeledValue : public CIntObject
{
std::string hoverText;
CLabel *name;
CLabel *value;
std::shared_ptr<CLabel> name;
std::shared_ptr<CLabel> value;
void init(std::string name, std::string descr, int min, int max);
public:
@ -289,14 +315,16 @@ class CFortScreen : public CWindowObject
{
class RecruitArea : public CIntObject
{
const CGTownInstance *town;
const CGTownInstance * town;
int level;
std::string hoverText;
CLabel * availableCount;
std::shared_ptr<CLabel> availableCount;
std::vector<LabeledValue*> values;
CPicture *icons;
std::vector<std::shared_ptr<LabeledValue>> values;
std::shared_ptr<CPicture> icons;
std::shared_ptr<CAnimImage> buildingIcon;
std::shared_ptr<CLabel> buildingName;
const CCreature * getMyCreature();
const CBuilding * getMyBuilding();
@ -308,13 +336,13 @@ class CFortScreen : public CWindowObject
void clickLeft(tribool down, bool previousState) override;
void clickRight(tribool down, bool previousState) override;
};
CLabel *title;
std::vector<RecruitArea*> recAreas;
CMinorResDataBar * resdatabar;
CGStatusBar *statusBar;
CButton *exit;
std::shared_ptr<CLabel> title;
std::vector<std::shared_ptr<RecruitArea>> recAreas;
std::shared_ptr<CMinorResDataBar> resdatabar;
std::shared_ptr<CGStatusBar> statusbar;
std::shared_ptr<CButton> exit;
std::string getBgName(const CGTownInstance *town);
std::string getBgName(const CGTownInstance * town);
public:
CFortScreen(const CGTownInstance * town);
@ -327,8 +355,8 @@ class CMageGuildScreen : public CWindowObject
{
class Scroll : public CIntObject
{
const CSpell *spell;
CAnimImage *image;
const CSpell * spell;
std::shared_ptr<CAnimImage> image;
public:
Scroll(Point position, const CSpell *Spell);
@ -336,11 +364,13 @@ class CMageGuildScreen : public CWindowObject
void clickRight(tribool down, bool previousState) override;
void hover(bool on) override;
};
CPicture *window;
CButton *exit;
std::vector<Scroll *> spells;
CMinorResDataBar * resdatabar;
CGStatusBar *statusBar;
std::shared_ptr<CPicture> window;
std::shared_ptr<CButton> exit;
std::vector<std::shared_ptr<Scroll>> spells;
std::vector<std::shared_ptr<CAnimImage>> emptyScrolls;
std::shared_ptr<CMinorResDataBar> resdatabar;
std::shared_ptr<CGStatusBar> statusbar;
public:
CMageGuildScreen(CCastleInterface * owner,std::string image);
@ -349,13 +379,15 @@ public:
/// The blacksmith window where you can buy available in town war machine
class CBlacksmithDialog : public CWindowObject
{
CButton *buy, *cancel;
CPicture *animBG;
CCreatureAnim * anim;
CLabel * title;
CLabel * costText;
CLabel * costValue;
CGStatusBar *statusBar;
std::shared_ptr<CButton> buy;
std::shared_ptr<CButton> cancel;
std::shared_ptr<CPicture> animBG;
std::shared_ptr<CCreatureAnim> anim;
std::shared_ptr<CLabel> title;
std::shared_ptr<CAnimImage> costIcon;
std::shared_ptr<CLabel> costText;
std::shared_ptr<CLabel> costValue;
std::shared_ptr<CGStatusBar> statusbar;
public:
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 "CWindowObject.h"
struct StackWindowInfo;
class UnitView;
class CCommanderInstance;
class CStackInstance;
class CStack;
struct UpgradeInfo;
class CTabbedInt;
class CButton;
class CMultiLineLabel;
class CListBox;
class CCommanderArtPlace;
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:
CCommanderSkillIcon(CIntObject * object, std::function<void()> callback);
CCommanderSkillIcon(std::shared_ptr<CIntObject> object_, std::function<void()> callback);
std::function<void()> callback;
void clickLeft(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
@ -46,48 +49,123 @@ class CStackWindow : public CWindowObject
class CWindowSection : public CIntObject
{
CStackWindow *parent;
void createBackground(std::string path);
void createBonusItem(size_t index, Point position);
void printStatString(int index, std::string name, std::string value);
void printStatRange(int index, std::string name, int min, int max);
void printStatBase(int index, std::string name, int base, int current);
void printStat(int index, std::string name, int value);
private:
std::shared_ptr<CPicture> background;
protected:
CStackWindow * parent;
public:
void createStackInfo(bool showExp, bool showArt);
void createActiveSpells();
void createCommanderSection();
void createCommander();
void createCommanderAbilities();
void createBonuses(boost::optional<size_t> size = boost::optional<size_t>());
void createBonusEntry(size_t index);
void createButtonPanel();
CWindowSection(CStackWindow * parent);
CWindowSection(CStackWindow * parent, std::string backgroundPath, int yOffset);
};
std::unique_ptr<CAnimImage> stackArtifactIcon;
std::unique_ptr<LRClickableAreaWTextComp> stackArtifactHelp;
std::unique_ptr<CButton> stackArtifactButton;
CAnimImage *expRankIcon;
LRClickableAreaWText *expArea;
CLabel *expLabel;
class ActiveSpellsSection : public CWindowSection
{
std::vector<std::shared_ptr<CAnimImage>> spellIcons;
std::vector<std::shared_ptr<LRClickableAreaWText>> clickableAreas;
public:
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;
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);
CCommanderSkillIcon * selectedIcon;
std::shared_ptr<CWindowSection> mainSection;
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;
CIntObject * createBonusEntry(size_t index);
CIntObject * switchTab(size_t index);
void setSelection(si32 newSkill, std::shared_ptr<CCommanderSkillIcon> newIcon);
std::shared_ptr<CIntObject> switchTab(size_t index);
void removeStackArtifact(ArtifactPosition pos);
@ -98,8 +176,6 @@ class CStackWindow : public CWindowObject
std::string generateStackExpDescription();
CIntObject * createSkillEntry(int index);
public:
// for battles
CStackWindow(const CStack * stack, bool popup);

View File

@ -40,17 +40,15 @@
#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 heroBonuses = hero->getAllBonuses(selector, limit, hero);
TBonusListPtr heroBonuses = hero->getAllBonuses(selector, limit, hero, cachingStr);
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)
{
bonusesFromPickedUpArtifact = cp->src.art->getAllBonuses(selector, limit, hero);
}
else
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
}
CHeroWithMaybePickedArtifact::CHeroWithMaybePickedArtifact(CWindowWithArtifacts *Cww, const CGHeroInstance *Hero)
: hero(Hero), cww(Cww)
CHeroWithMaybePickedArtifact::CHeroWithMaybePickedArtifact(CWindowWithArtifacts * Cww, const CGHeroInstance * Hero)
: hero(Hero), cww(Cww)
{
}
@ -75,114 +73,128 @@ void CHeroSwitcher::clickLeft(tribool down, bool previousState)
{
if(!down)
{
//TODO: do not recreate window
#if 0
owner->update(hero, true);
#else
const CGHeroInstance * buf = hero;
GH.popIntTotally(parent);
GH.pushInt(new CHeroWindow(buf));
#endif // 0
}
}
CHeroSwitcher::CHeroSwitcher(Point _pos, const CGHeroInstance * _hero):
hero(_hero)
CHeroSwitcher::CHeroSwitcher(CHeroWindow * owner_, Point pos_, const CGHeroInstance * hero_)
: CIntObject(LCLICK),
owner(owner_),
hero(hero_)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
pos += _pos;
addUsedEvents(LCLICK);
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
pos += pos_;
image = new CAnimImage("PortraitsSmall", hero->portrait);
image = std::make_shared<CAnimImage>("PortraitsSmall", hero->portrait);
pos.w = image->pos.w;
pos.h = image->pos.h;
}
CHeroWindow::CHeroWindow(const CGHeroInstance *hero):
CWindowObject(PLAYER_COLORED, "HeroScr4"),
CHeroWindow::CHeroWindow(const CGHeroInstance * hero)
: CWindowObject(PLAYER_COLORED, "HeroScr4"),
heroWArt(this, hero)
{
auto & heroscrn = CGI->generaltexth->heroscrn;
OBJ_CONSTRUCTION_CAPTURING_ALL;
garr = nullptr;
tacticsButton = nullptr;
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
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);
ourBar = new CGStatusBar(7, 559, "ADROLLVR.bmp", 660); // new CStatusBar(pos.x+72, pos.y+567, "ADROLLVR.bmp", 660);
statusBar = std::make_shared<CGStatusBar>(7, 559, "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);
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);
formations->addToggle(0, new CToggleButton(Point(481, 483), "hsbtns6.def", std::make_pair(heroscrn[23], heroscrn[29]), 0, SDLK_t));
formations->addToggle(1, new CToggleButton(Point(481, 519), "hsbtns7.def", std::make_pair(heroscrn[24], heroscrn[30]), 0, SDLK_l));
dismissLabel = std::make_shared<CTextBox>(CGI->generaltexth->jktexts[8], Rect(370, 430, 65, 35), 0, FONT_SMALL, TOPLEFT, Colors::WHITE);
dismissButton = std::make_shared<CButton>(Point(454, 429), "hsbtns2.def", CButton::tooltip(heroscrn[28]), [=](){ dismissCurrent(); }, SDLK_d);
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"];
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
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
portraitArea = new LRClickableAreaWText(Rect(18, 18, 58, 64));
portraitImage = new CAnimImage("PortraitsLarge", 0, 0, 19, 19);
portraitArea = std::make_shared<LRClickableAreaWText>(Rect(18, 18, 58, 64));
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->type = v;
area->hoverText = boost::str(boost::format(CGI->generaltexth->heroscrn[1]) % CGI->generaltexth->primarySkillNames[v]);
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]);
expArea = new LRClickableAreaWText(Rect(18, 228, 136, 42), CGI->generaltexth->heroscrn[9]);
morale = new MoraleLuckBox(true, Rect(175,179,53,45));
luck = new MoraleLuckBox(false, Rect(233,179,53,45));
spellPointsArea = new LRClickableAreaWText(Rect(162,228, 136, 42), CGI->generaltexth->heroscrn[22]);
specImage = std::make_shared<CAnimImage>("UN44", 0, 0, 18, 180);
specArea = std::make_shared<LRClickableAreaWText>(Rect(18, 180, 136, 42), CGI->generaltexth->heroscrn[27]);
specName = std::make_shared<CLabel>(69, 205);
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");
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);
secSkillAreas.push_back(new LRClickableAreaWTextComp(r, CComponent::secskill));
secSkillImages.push_back(new CAnimImage(secSkills, 0, 0, r.x, r.y));
secSkillAreas.push_back(std::make_shared<LRClickableAreaWTextComp>(r, CComponent::secskill));
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
new 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]);
new 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>(52, 99, FONT_SMALL, CENTER, Colors::YELLOW, CGI->generaltexth->jktexts[1]));
labels.push_back(std::make_shared<CLabel>(123, 99, FONT_SMALL, CENTER, Colors::YELLOW, CGI->generaltexth->jktexts[2]));
labels.push_back(std::make_shared<CLabel>(193, 99, FONT_SMALL, CENTER, Colors::YELLOW, CGI->generaltexth->jktexts[3]));
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]);
new 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>(69, 183, FONT_SMALL, TOPLEFT, Colors::YELLOW, CGI->generaltexth->jktexts[5]));
labels.push_back(std::make_shared<CLabel>(69, 232, FONT_SMALL, TOPLEFT, Colors::YELLOW, CGI->generaltexth->jktexts[6]));
labels.push_back(std::make_shared<CLabel>(213, 232, FONT_SMALL, TOPLEFT, Colors::YELLOW, CGI->generaltexth->jktexts[7]));
update(hero);
}
@ -199,11 +211,14 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded)
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;
specImage->setFrame(curHero->type->imageIndex);
specName->setText(curHero->type->specName);
delete tacticsButton;
tacticsButton = new CToggleButton(Point(539, 483), "hsbtns8.def", std::make_pair(heroscrn[26], heroscrn[31]), 0, SDLK_b);
tacticsButton = std::make_shared<CToggleButton>(Point(539, 483), "hsbtns8.def", std::make_pair(heroscrn[26], heroscrn[31]), 0, SDLK_b);
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));
@ -212,49 +227,62 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded)
portraitImage->setFrame(curHero->portrait);
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
if(!garr)
{
std::string helpBox = heroscrn[32];
boost::algorithm::replace_first(helpBox, "%s", CGI->generaltexth->allTexts[43]);
garr = new CGarrisonInt(15, 485, 8, Point(), background->bg, Point(15,485), curHero);
auto split = new CButton(Point(539, 519), "hsbtns9.def", CButton::tooltip(CGI->generaltexth->allTexts[256], helpBox), [&](){ garr->splitClick(); });
garr = std::make_shared<CGarrisonInt>(15, 485, 8, Point(), curHero);
auto split = std::make_shared<CButton>(Point(539, 519), "hsbtns9.def", CButton::tooltip(CGI->generaltexth->allTexts[256], helpBox), [&](){ garr->splitClick(); });
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);
artSets.push_back(arts);
addSet(arts);
}
int serial = LOCPLINT->cb->getHeroSerial(curHero, false);
vstd::clear_pointer(listSelection);
if (serial >= 0)
listSelection = new CPicture("HPSYYY", 612, 33 + serial * 54);
listSelection.reset();
if(serial >= 0)
listSelection = std::make_shared<CPicture>("HPSYYY", 612, 33 + serial * 54);
}
//primary skills support
for(size_t g=0; g<primSkillAreas.size(); ++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
for(size_t g=0; g< secSkillAreas.size(); ++g)
{
int skill = curHero->secSkills[g].first,
level = curHero->getSecSkillLevel(SecondarySkill(curHero->secSkills[g].first));
int skill = 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]->bonusValue = 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);
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
expArea->text = CGI->generaltexth->allTexts[2];
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
bool noDismiss=false;
for(IShowActivatable *isa : GH.listInt)
for(IShowActivatable * isa : GH.listInt)
{
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)
noDismiss = true;
}
if (dynamic_cast<CKingdomInterface*>(isa))
if(dynamic_cast<CKingdomInterface*>(isa))
noDismiss = true;
}
//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);
if(curHero->getSecSkillLevel(SecondarySkill::TACTICS) == 0)
{
tacticsButton->block(true);
}
else
{
tacticsButton->block(false);
tacticsButton->addCallback( [&](bool on) {curHero->tacticFormationEnabled = on;});
tacticsButton->addCallback([&](bool on){curHero->tacticFormationEnabled = on;});
}
formations->resetCallback();
//setting formations
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);
luck->set(&heroWArt);
@ -312,26 +344,25 @@ void CHeroWindow::dismissCurrent()
{
CFunctionList<void()> ony = [=](){ close(); };
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()
{
//TODO: allow equipping commander artifacts by drag / drop
//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();
//artSelected = true;
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 dst (curHero->commander.get(), freeSlot);
ArtifactLocation src(srcHero, commonInfo->src.slotID);
ArtifactLocation dst(curHero->commander.get(), freeSlot);
if (art->canBePutAt(dst, true))
if(art->canBePutAt(dst, true))
{ //equip clicked stack
if(dst.getArt())
{
@ -342,51 +373,13 @@ void CHeroWindow::commanderWindow()
}
}
else
{
GH.pushInt(new CStackWindow(curHero->commander, false));
}
}
void CHeroWindow::updateGarrisons()
{
CWindowWithGarrison::updateGarrisons();
garr->recreateSlots();
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 CToggleGroup;
class CGStatusBar;
class CTextBox;
/// Button which switches hero selection
class CHeroSwitcher : public CIntObject
{
const CGHeroInstance * hero;
CAnimImage *image;
std::shared_ptr<CAnimImage> image;
CHeroWindow * owner;
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
class CHeroWithMaybePickedArtifact : public virtual IBonusBearer
{
public:
const CGHeroInstance *hero;
CWindowWithArtifacts *cww;
const CGHeroInstance * hero;
CWindowWithArtifacts * cww;
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;
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;
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
//CButton * gar4button; //splitting
std::vector<CHeroSwitcher *> heroList; //list of heroes
CPicture * listSelection; //selection border
std::shared_ptr<CAnimImage> banner;
std::shared_ptr<CGStatusBar> statusBar;
//clickable areas
LRClickableAreaWText * portraitArea;
CAnimImage * portraitImage;
std::vector<std::shared_ptr<CHeroSwitcher>> heroList;
std::shared_ptr<CPicture> listSelection;
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;
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;
CToggleGroup *formations;
std::shared_ptr<CToggleButton> tacticsButton;
std::shared_ptr<CToggleGroup> formations;
std::shared_ptr<CGarrisonInt> garr;
std::shared_ptr<CArtifactsOfHero> arts;
std::vector<std::shared_ptr<CLabel>> labels;
public:
const CGHeroInstance * curHero;
CHeroWindow(const CGHeroInstance *hero);
CHeroWindow(const CGHeroInstance * 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 commanderWindow();
void switchHero(); //changes displayed hero
virtual void updateGarrisons() override; //updates the morale widget and calls the parent
void updateGarrisons() override;
//friends
friend void CHeroArtPlace::clickLeft(tribool down, bool previousState);

View File

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

View File

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

View File

@ -62,15 +62,15 @@ void CQuestIcon::showAll(SDL_Surface * to)
CAnimImage::showAll(to);
}
CQuestMinimap::CQuestMinimap (const Rect & position) :
CMinimap (position),
currentQuest (nullptr)
CQuestMinimap::CQuestMinimap(const Rect & position)
: CMinimap(position),
currentQuest(nullptr)
{
}
void CQuestMinimap::addQuestMarks (const QuestInfo * q)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
icons.clear();
int3 tile;
@ -96,13 +96,13 @@ void CQuestMinimap::addQuestMarks (const QuestInfo * q)
void CQuestMinimap::update()
{
CMinimap::update();
if (currentQuest)
addQuestMarks (currentQuest);
if(currentQuest)
addQuestMarks(currentQuest);
}
void CQuestMinimap::iconClicked()
{
if (currentQuest->obj)
if(currentQuest->obj)
adventureInt->centerOn (currentQuest->obj->pos);
//moveAdvMapSelection();
}
@ -110,44 +110,38 @@ void CQuestMinimap::iconClicked()
void CQuestMinimap::showAll(SDL_Surface * to)
{
CIntObject::showAll(to); // blitting IntObject directly to hide radar
for (auto pic : icons)
pic->showAll(to);
// for (auto pic : icons)
// pic->showAll(to);
}
CQuestLog::CQuestLog (const std::vector<QuestInfo> & Quests) :
CWindowObject(PLAYER_COLORED | BORDERED, "questDialog"),
CQuestLog::CQuestLog (const std::vector<QuestInfo> & Quests)
: CWindowObject(PLAYER_COLORED | BORDERED, "questDialog"),
questIndex(0),
currentQuest(nullptr),
componentsBox(nullptr),
hideComplete(false),
quests(Quests),
slider(nullptr)
quests(Quests)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
init();
}
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
void CQuestLog::init()
{
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
description = new 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);
description = std::make_shared<CTextBox>("", Rect(205, 18, 385, DESCRIPTION_HEIGHT_MAX), CSlider::BROWN, FONT_MEDIUM, TOPLEFT, Colors::WHITE);
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
hideCompleteButton = new 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());
slider = new CSlider(Point(166, 195), 191, std::bind(&CQuestLog::sliderMoved, this, _1), QUEST_COUNT, 0, false, CSlider::BROWN);
hideCompleteButton = std::make_shared<CToggleButton>(Point(10, 396), "sysopchk.def", CButton::tooltip(texts["hideComplete"]), std::bind(&CQuestLog::toggleComplete, this, _1));
hideCompleteLabel = std::make_shared<CLabel>(46, 398, FONT_MEDIUM, TOPLEFT, Colors::WHITE, texts["hideComplete"]["label"].String());
slider = std::make_shared<CSlider>(Point(166, 195), 191, std::bind(&CQuestLog::sliderMoved, this, _1), QUEST_COUNT, 0, false, CSlider::BROWN);
recreateLabelList();
recreateQuestList (0);
recreateQuestList(0);
}
void CQuestLog::recreateLabelList()
{
if (labels.size())
labels.clear();
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
labels.clear();
bool completeMissing = true;
int currentLabel = 0;
@ -209,8 +203,8 @@ void CQuestLog::recreateLabelList()
void CQuestLog::showAll(SDL_Surface * to)
{
CWindowObject::showAll (to);
if (labels.size() && labels[questIndex]->active)
CWindowObject::showAll(to);
if(labels.size() && labels[questIndex]->active)
{
Rect rect = Rect::around(labels[questIndex]->pos);
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();
}
void CQuestLog::selectQuest (int which, int labelId)
void CQuestLog::selectQuest(int which, int labelId)
{
questIndex = labelId;
currentQuest = &quests[which];
@ -241,14 +235,15 @@ void CQuestLog::selectQuest (int which, int labelId)
MetaString text;
std::vector<Component> components;
currentQuest->quest->getVisitText (text, components, currentQuest->quest->isCustomFirst, true);
if (description->slider)
if(description->slider)
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 descriptionHeight = DESCRIPTION_HEIGHT_MAX;
if (componentsSize)
if(componentsSize)
{
descriptionHeight -= 15;
CComponent::ESize imageSize = CComponent::large;
@ -290,12 +285,16 @@ void CQuestLog::selectQuest (int which, int labelId)
break;
}
OBJ_CONSTRUCTION_CAPTURING_ALL;
std::vector<CComponent *> comps;
for (auto & component : components)
comps.push_back(new CComponent(component, imageSize));
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
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));
@ -303,15 +302,14 @@ void CQuestLog::selectQuest (int which, int labelId)
redraw();
}
void CQuestLog::sliderMoved (int newpos)
void CQuestLog::sliderMoved(int newpos)
{
recreateQuestList (newpos); //move components
recreateQuestList(newpos); //move components
redraw();
}
void CQuestLog::toggleComplete(bool on)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
hideComplete = on;
recreateLabelList();
recreateQuestList(0);

View File

@ -38,7 +38,7 @@ class CQuestLabel : public LRClickableAreaWText, public CMultiLineLabel
public:
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){};
void clickLeft(tribool down, bool previousState) override;
void showAll(SDL_Surface * to) override;
@ -49,7 +49,7 @@ class CQuestIcon : public CAnimImage
public:
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 showAll(SDL_Surface * to) override;
@ -57,17 +57,16 @@ public:
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 iconClicked();
void mouseMoved (const SDL_MouseMotionEvent & sEvent) override{};
public:
const QuestInfo * currentQuest;
CQuestMinimap (const Rect & position);
CQuestMinimap(const Rect & position);
//should be called to invalidate whole map - different player or level
void update();
void addQuestMarks (const QuestInfo * q);
@ -79,22 +78,20 @@ class CQuestLog : public CWindowObject
{
int questIndex;
const QuestInfo * currentQuest;
CComponentBox * componentsBox;
std::shared_ptr<CComponentBox> componentsBox;
bool hideComplete;
CToggleButton * hideCompleteButton;
CLabel * hideCompleteLabel;
std::shared_ptr<CToggleButton> hideCompleteButton;
std::shared_ptr<CLabel> hideCompleteLabel;
const std::vector<QuestInfo> quests;
std::vector <std::shared_ptr<CQuestLabel>> labels;
CTextBox * description;
CQuestMinimap * minimap;
CSlider * slider; //scrolls quests
CButton *ok;
std::vector<std::shared_ptr<CQuestLabel>> labels;
std::shared_ptr<CTextBox> description;
std::shared_ptr<CQuestMinimap> minimap;
std::shared_ptr<CSlider> slider; //scrolls quests
std::shared_ptr<CButton> ok;
void init ();
public:
CQuestLog (const std::vector<QuestInfo> & Quests);
CQuestLog(const std::vector<QuestInfo> & Quests);
~CQuestLog(){};

View File

@ -102,7 +102,7 @@ CSpellWindow::CSpellWindow(const CGHeroInstance * _myHero, CPlayerInterface * _m
myHero(_myHero),
myInt(_myInt)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
//initializing castable spells
mySpells.reserve(CGI->spellh->objects.size());
for(const CSpell * spell : CGI->spellh->objects)
@ -168,13 +168,13 @@ CSpellWindow::CSpellWindow(const CGHeroInstance * _myHero, CPlayerInterface * _m
//numbers of spell pages computed
leftCorner = new CPicture("SpelTrnL.bmp", 97, 77);
rightCorner = new CPicture("SpelTrnR.bmp", 487, 72);
leftCorner = std::make_shared<CPicture>("SpelTrnL.bmp", 97, 77);
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);
schools = new CAnimImage("Schools",0,0,117,74);
schoolTab = std::make_shared<CAnimImage>("SpelTab", selectedTab, 0, 524, 88);
schoolPicture = std::make_shared<CAnimImage>("Schools", 0, 0, 117, 74);
schoolBorders[0] = std::make_shared<CAnimation>("SplevA.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");
for(auto item : schoolBorders)
item->load();
mana = new CLabel(435, 426, FONT_SMALL, CENTER, Colors::YELLOW, boost::lexical_cast<std::string>(myHero->mana));
statusBar = new CGStatusBar(7, 569, "Spelroll.bmp");
item->preload();
mana = std::make_shared<CLabel>(435, 426, FONT_SMALL, CENTER, Colors::YELLOW, boost::lexical_cast<std::string>(myHero->mana));
statusBar = std::make_shared<CGStatusBar>(7, 569, "Spelroll.bmp");
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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
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)
{
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
{
@ -237,7 +237,7 @@ CSpellWindow::CSpellWindow(const CGHeroInstance * _myHero, CPlayerInterface * _m
}
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;
// 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));
@ -248,9 +248,6 @@ CSpellWindow::CSpellWindow(const CGHeroInstance * _myHero, CPlayerInterface * _m
CSpellWindow::~CSpellWindow()
{
for(auto item : schoolBorders)
item->unload();
spells->unload();
}
void CSpellWindow::fexitb()
@ -263,7 +260,7 @@ void CSpellWindow::fexitb()
void CSpellWindow::fadvSpellsb()
{
if (battleSpellsOnly == true)
if(battleSpellsOnly == true)
{
turnPageRight();
battleSpellsOnly = false;
@ -274,7 +271,7 @@ void CSpellWindow::fadvSpellsb()
void CSpellWindow::fbattleSpellsb()
{
if (battleSpellsOnly == false)
if(battleSpellsOnly == false)
{
turnPageLeft();
battleSpellsOnly = true;
@ -289,14 +286,14 @@ void CSpellWindow::fmanaPtsb()
void CSpellWindow::selectSchool(int school)
{
if (selectedTab != school)
if(selectedTab != school)
{
if (selectedTab < school)
if(selectedTab < school)
turnPageLeft();
else
turnPageRight();
selectedTab = school;
spellTab->setFrame(selectedTab, 0);
schoolTab->setFrame(selectedTab, 0);
setCurrentPage(0);
}
computeSpellsPerArea();
@ -405,9 +402,9 @@ void CSpellWindow::computeSpellsPerArea()
void CSpellWindow::setCurrentPage(int value)
{
currentPage = value;
schools->visible = selectedTab!=4 && currentPage == 0;
schoolPicture->visible = selectedTab!=4 && currentPage == 0;
if(selectedTab != 4)
schools->setFrame(selectedTab, 0);
schoolPicture->setFrame(selectedTab, 0);
leftCorner->visible = currentPage != 0;
rightCorner->visible = (currentPage+1) < pagesWithinCurrentTab();
@ -416,13 +413,13 @@ void CSpellWindow::setCurrentPage(int value)
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);
}
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);
}
@ -503,27 +500,23 @@ CSpellWindow::SpellArea::SpellArea(SDL_Rect pos, CSpellWindow * owner)
this->owner = owner;
addUsedEvents(LCLICK | RCLICK | HOVER);
spellCost = whichSchool = schoolLevel = -1;
schoolLevel = -1;
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;
name = new CLabel(39, 70, FONT_TINY, CENTER);
level = new CLabel(39, 82, FONT_TINY, CENTER);
cost = new CLabel(39, 94, FONT_TINY, CENTER);
name = std::make_shared<CLabel>(39, 70, FONT_TINY, CENTER);
level = std::make_shared<CLabel>(39, 82, FONT_TINY, CENTER);
cost = std::make_shared<CLabel>(39, 94, FONT_TINY, CENTER);
for(auto l : {name, level, cost})
l->autoRedraw = false;
}
CSpellWindow::SpellArea::~SpellArea()
{
}
CSpellWindow::SpellArea::~SpellArea() = default;
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
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);
}
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));
}
CRClickPopup::createAndPush(mySpell->getLevelInfo(schoolLevel).description + dmgInfo,
new CComponent(CComponent::spell, mySpell->id));
CRClickPopup::createAndPush(mySpell->getLevelInfo(schoolLevel).description + dmgInfo, std::make_shared<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)
{
schoolBorder = nullptr;
schoolBorder.reset();
image->visible = false;
name->setText("");
level->setText("");
@ -644,12 +625,17 @@ void CSpellWindow::SpellArea::setSpell(const CSpell * spell)
mySpell = spell;
if(mySpell)
{
int whichSchool = 0; //0 - air magic, 1 - fire magic, 2 - water magic, 3 - earth magic,
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->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;
if(spellCost > owner->myHero->mana) //hero cannot cast this spell

View File

@ -30,12 +30,12 @@ class CSpellWindow : public CWindowObject
{
const CSpell * mySpell;
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;
CAnimImage * image;
IImage * schoolBorder;
CLabel * name, * level, * cost;
std::shared_ptr<CAnimImage> image;
std::shared_ptr<CAnimImage> schoolBorder;
std::shared_ptr<CLabel> name;
std::shared_ptr<CLabel> level;
std::shared_ptr<CLabel> cost;
public:
SpellArea(SDL_Rect pos, CSpellWindow * owner);
~SpellArea();
@ -44,7 +44,6 @@ class CSpellWindow : public CWindowObject
void clickLeft(tribool down, bool previousState) override;
void clickRight(tribool down, bool previousState) override;
void hover(bool on) override;
void showAll(SDL_Surface * to) override;
};
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);
};
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
CAnimImage * schools; //schools' pictures
std::array< std::shared_ptr<CAnimation>, 4> schoolBorders; //schools' 'borders': [0]: air, [1]: fire, [2]: water, [3]: earth
std::shared_ptr<CAnimImage> schoolTab;
std::shared_ptr<CAnimImage> schoolPicture;
SpellArea * spellAreas[12];
CLabel * mana;
CGStatusBar * statusBar;
std::array<std::shared_ptr<SpellArea>, 12> spellAreas;
std::shared_ptr<CLabel> mana;
std::shared_ptr<CGStatusBar> statusBar;
std::vector<std::shared_ptr<InteractiveArea>> interactiveAreas;
int sitesPerTabAdv[5];
int sitesPerTabBattle[5];

View File

@ -31,34 +31,35 @@
#include "../../lib/mapObjects/CGTownInstance.h"
#include "../../lib/mapObjects/CGMarket.h"
CTradeWindow::CTradeableItem::CTradeableItem(Point pos, EType Type, int ID, bool Left, int Serial):
CIntObject(LCLICK | HOVER | RCLICK, pos),
CTradeWindow::CTradeableItem::CTradeableItem(Point pos, EType Type, int ID, bool Left, int Serial)
: CIntObject(LCLICK | HOVER | RCLICK, pos),
type(EType(-1)),// set to invalid, will be corrected in setType
id(ID),
serial(Serial),
left(Left)
{
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
downSelection = false;
hlp = nullptr;
image = nullptr;
setType(Type);
}
void CTradeWindow::CTradeableItem::setType(EType newType)
{
if (type != newType)
if(type != newType)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
type = newType;
delete image;
if (getIndex() < 0)
if(getIndex() < 0)
{
image = new CAnimImage(getFilename(), 0);
image = std::make_shared<CAnimImage>(getFilename(), 0);
image->disable();
}
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);
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())
{
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.slotID = aw->hero->getArtPos(art);
aw->arts->markPossibleSlots(art);
@ -200,15 +201,15 @@ void CTradeWindow::CTradeableItem::clickLeft(tribool down, bool previousState)
}
if(left)
{
if(mw->hLeft != this)
mw->hLeft = this;
if(mw->hLeft != this->shared_from_this())
mw->hLeft = this->shared_from_this();
else
return;
}
else
{
if(mw->hRight != this)
mw->hRight = this;
if(mw->hRight != this->shared_from_this())
mw->hRight = this->shared_from_this();
else
return;
}
@ -301,7 +302,7 @@ const CArtifactInstance * CTradeWindow::CTradeableItem::getArtInstance() const
{
case ARTIFACT_PLACEHOLDER:
case ARTIFACT_INSTANCE:
return (const CArtifactInstance *)hlp;
return hlp;
default:
return nullptr;
}
@ -321,15 +322,10 @@ CTradeWindow::CTradeWindow(std::string bgName, const IMarket *Market, const CGHe
CWindowObject(PLAYER_COLORED, bgName),
market(Market),
hero(Hero),
arts(nullptr),
hLeft(nullptr),
hRight(nullptr),
ok(nullptr),
max(nullptr),
deal(nullptr),
slider(nullptr),
readyToTrade(false)
{
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
type |= BLOCK_ADV_HOTKEYS;
mode = Mode;
initTypes();
@ -372,6 +368,8 @@ void CTradeWindow::initTypes()
void CTradeWindow::initItems(bool Left)
{
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
if(Left && (itemsType[1] == ARTIFACT_TYPE || itemsType[1] == ARTIFACT_INSTANCE))
{
int xOffset = 0, yOffset = 0;
@ -380,9 +378,9 @@ void CTradeWindow::initItems(bool Left)
xOffset = -361;
yOffset = +46;
auto hlp = new CTradeableItem(Point(137, 469), itemsType[Left], -1, 1, 0);
hlp->recActions &= ~(UPDATE | SHOWALL);
items[Left].push_back(hlp);
auto item = std::make_shared<CTradeableItem>(Point(137, 469), itemsType[Left], -1, 1, 0);
item->recActions &= ~(UPDATE | SHOWALL);
items[Left].push_back(item);
}
else //ARTIFACT_EXP
{
@ -390,47 +388,44 @@ void CTradeWindow::initItems(bool Left)
yOffset = -12;
}
BLOCK_CAPTURING;
arts = new CArtifactsOfHero(Point(pos.x+xOffset, pos.y+yOffset));
arts->commonInfo = std::make_shared<CArtifactsOfHero::SCommonPart>();
arts->commonInfo->participants.insert(arts);
arts->recActions = 255;
arts = std::make_shared<CArtifactsOfHero>(Point(xOffset, yOffset), true);
arts->recActions = 255-DISPOSE;
arts->setHero(hero);
arts->allowedAssembling = false;
addChild(arts);
artSets.push_back(arts);
addSet(arts);
if(mode == EMarketMode::ARTIFACT_RESOURCE)
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
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;
std::vector<int> *ids = getItemsIds(Left);
std::vector<Rect> pos;
int amount = -1;
auto hlp = new CTradeableItem(pos[j].topLeft(), itemsType[Left], id, Left, j);
hlp->pos = pos[j] + this->pos.topLeft();
items[Left].push_back(hlp);
getPositionsFor(pos, Left, itemsType[Left]);
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)
@ -523,17 +518,17 @@ void CTradeWindow::getPositionsFor(std::vector<Rect> &poss, bool Left, EType typ
void CTradeWindow::initSubs(bool Left)
{
for(CTradeableItem *t : items[Left])
for(auto item : items[Left])
{
if(Left)
{
switch(itemsType[1])
{
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;
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;
}
}
@ -541,25 +536,25 @@ void CTradeWindow::initSubs(bool Left)
{
if(itemsType[0] == PLAYER)
{
t->subtitle = CGI->generaltexth->capColors[t->id];
item->subtitle = CGI->generaltexth->capColors[item->id];
}
else if(hLeft)//artifact, creature
{
int h1, h2; //hlp variables for getting offer
market->getOffer(hLeft->id, t->id, h1, h2, mode);
if(t->id != hLeft->id || mode != EMarketMode::RESOURCE_RESOURCE) //don't allow exchanging same resources
market->getOffer(hLeft->id, item->id, h1, h2, mode);
if(item->id != hLeft->id || mode != EMarketMode::RESOURCE_RESOURCE) //don't allow exchanging same resources
{
std::ostringstream oss;
oss << h2;
if(h1!=1)
oss << "/" << h1;
t->subtitle = oss.str();
item->subtitle = oss.str();
}
else
t->subtitle = CGI->generaltexth->allTexts[164]; // n/a
item->subtitle = CGI->generaltexth->allTexts[164]; // n/a
}
else
t->subtitle = "";
item->subtitle = "";
}
}
}
@ -569,9 +564,9 @@ void CTradeWindow::showAll(SDL_Surface * to)
CWindowObject::showAll(to);
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)
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)
{
@ -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)
removeItem(t);
for(auto item : toRemove)
removeItem(item);
}
void CTradeWindow::removeItem(CTradeableItem * t)
void CTradeWindow::removeItem(std::shared_ptr<CTradeableItem> item)
{
items[t->left] -= t;
delete t;
items[item->left] -= item;
if(hRight == t)
if(hRight == item)
{
hRight = nullptr;
hRight.reset();
selectionChanged(false);
}
}
void CTradeWindow::getEmptySlots(std::set<CTradeableItem *> &toRemove)
void CTradeWindow::getEmptySlots(std::set<std::shared_ptr<CTradeableItem>> & toRemove)
{
for(CTradeableItem *t : items[1])
if(!hero->getStackCount(SlotID(t->serial)))
toRemove.insert(t);
for(auto item : items[1])
if(!hero->getStackCount(SlotID(item->serial)))
toRemove.insert(item);
}
void CTradeWindow::setMode(EMarketMode::EMarketMode Mode)
@ -660,35 +654,36 @@ std::string CMarketplaceWindow::getBackgroundForMode(EMarketMode::EMarketMode mo
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)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
madeTransaction = false;
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;
if (market->o->ID == Obj::TOWN)
if(market->o->ID == Obj::TOWN)
{
switch (mode)
{
break; case EMarketMode::CREATURE_RESOURCE:
case EMarketMode::CREATURE_RESOURCE:
title = CGI->townh->factions[ETownType::STRONGHOLD]->town->buildings[BuildingID::FREELANCERS_GUILD]->Name();
break; case EMarketMode::RESOURCE_ARTIFACT:
break;
case EMarketMode::RESOURCE_ARTIFACT:
title = CGI->townh->factions[market->o->subID]->town->buildings[BuildingID::ARTIFACT_MERCHANT]->Name();
sliderNeeded = false;
break; case EMarketMode::ARTIFACT_RESOURCE:
break;
case EMarketMode::ARTIFACT_RESOURCE:
title = CGI->townh->factions[market->o->subID]->town->buildings[BuildingID::ARTIFACT_MERCHANT]->Name();
sliderNeeded = false;
break; default:
break;
default:
title = CGI->generaltexth->allTexts[158];
break;
}
}
else
@ -707,55 +702,51 @@ CMarketplaceWindow::CMarketplaceWindow(const IMarket *Market, const CGHeroInstan
break;
default:
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(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);
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);
if(sliderNeeded)
{
slider = new 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(); });
slider = std::make_shared<CSlider>(Point(231, 490),137, std::bind(&CMarketplaceWindow::sliderMoved,this,_1),0,0);
max = std::make_shared<CButton>(Point(229, 520), "IRCBTNS.DEF", CGI->generaltexth->zelp[596], [&](){ setMax(); });
max->block(true);
}
else
{
slider = nullptr;
max = nullptr;
deal->moveBy(Point(-30, 0));
}
Rect traderTextRect;
//left side
switch(Mode)
{
case EMarketMode::RESOURCE_RESOURCE:
case EMarketMode::RESOURCE_PLAYER:
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;
case EMarketMode::CREATURE_RESOURCE:
//%s's Creatures
new CLabel(152, 102, FONT_SMALL, CENTER, Colors::WHITE,
boost::str(boost::format(CGI->generaltexth->allTexts[272]) % hero->name));
labels.push_back(std::make_shared<CLabel>(152, 102, FONT_SMALL, CENTER, Colors::WHITE, boost::str(boost::format(CGI->generaltexth->allTexts[272]) % hero->name)));
break;
case EMarketMode::ARTIFACT_RESOURCE:
//%s's Artifacts
new CLabel(152, 56, FONT_SMALL, CENTER, Colors::WHITE,
boost::str(boost::format(CGI->generaltexth->allTexts[271]) % hero->name));
labels.push_back(std::make_shared<CLabel>(152, 56, FONT_SMALL, CENTER, Colors::WHITE, boost::str(boost::format(CGI->generaltexth->allTexts[271]) % hero->name)));
break;
}
Rect traderTextRect;
//right side
switch(Mode)
{
@ -763,45 +754,33 @@ CMarketplaceWindow::CMarketplaceWindow(const IMarket *Market, const CGHeroInstan
case EMarketMode::CREATURE_RESOURCE:
case EMarketMode::RESOURCE_ARTIFACT:
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);
break;
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);
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
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))
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))
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))
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))
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();
}
CMarketplaceWindow::~CMarketplaceWindow()
{
hLeft = hRight = nullptr;
for(auto & elem : items[1])
delete elem;
for(auto & elem : items[0])
delete elem;
items[1].clear();
items[0].clear();
}
CMarketplaceWindow::~CMarketplaceWindow() = default;
void CMarketplaceWindow::setMax()
{
@ -918,10 +897,8 @@ void CMarketplaceWindow::garrisonChanged()
if(mode != EMarketMode::CREATURE_RESOURCE)
return;
std::set<CTradeableItem *> toRemove;
std::set<std::shared_ptr<CTradeableItem>> toRemove;
getEmptySlots(toRemove);
removeItems(toRemove);
initSubs(true);
}
@ -933,10 +910,10 @@ void CMarketplaceWindow::artifactsChanged(bool Left)
return;
std::vector<int> available = market->availableItemsIds(mode);
std::set<CTradeableItem *> toRemove;
for(CTradeableItem *t : items[0])
if(!vstd::contains(available, t->id))
toRemove.insert(t);
std::set<std::shared_ptr<CTradeableItem>> toRemove;
for(auto item : items[0])
if(!vstd::contains(available, item->id))
toRemove.insert(item);
removeItems(toRemove);
redraw();
@ -1113,93 +1090,88 @@ void CMarketplaceWindow::updateTraderText()
}
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)
{
//%s's Creatures
new CLabel(155, 30, FONT_SMALL, CENTER, Colors::YELLOW,
boost::str(boost::format(CGI->generaltexth->allTexts[272]) % hero->name));
labels.push_back(std::make_shared<CLabel>(155, 30, FONT_SMALL, CENTER, Colors::YELLOW,
boost::str(boost::format(CGI->generaltexth->allTexts[272]) % hero->name)));
//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
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);
max = new CButton(Point(147, 520), "IRCBTNS.DEF", CGI->generaltexth->zelp[578], std::bind(&CSlider::moveToMax, slider));
slider = std::make_shared<CSlider>(Point(231,481),137,std::bind(&CAltarWindow::sliderMoved,this,_1),0,0);
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);
sacrificeAll = new CButton(Point(393, 520), "ALTARMY.DEF", CGI->generaltexth->zelp[579], std::bind(&CAltarWindow::SacrificeAll,this));
sacrificeBackpack = nullptr;
sacrificeAll = std::make_shared<CButton>(Point(393, 520), "ALTARMY.DEF", CGI->generaltexth->zelp[579], std::bind(&CAltarWindow::SacrificeAll,this));
initItems(true);
mimicCres();
artIcon = nullptr;
}
else
{
//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
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());
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());
slider = nullptr;
max = nullptr;
initItems(true);
initItems(false);
artIcon = new CAnimImage("ARTIFACT", 0, 0, 281, 442);
artIcon = std::make_shared<CAnimImage>("ARTIFACT", 0, 0, 281, 442);
artIcon->disable();
}
//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
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);
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)
{
CButton *changeMode = new CButton(Point(516, 421), "ALTART.DEF", CGI->generaltexth->zelp[580], std::bind(&CTradeWindow::setMode,this, EMarketMode::ARTIFACT_EXP));
if (Hero->getAlignment() == ::EAlignment::EVIL)
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)
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));
if (Hero->getAlignment() == ::EAlignment::GOOD)
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)
changeMode->block(true);
buttons.push_back(changeMode);
}
expPerUnit.resize(GameConstants::ARMY_SIZE, 0);
getExpValues();
expToLevel = new CLabel(73, 475, FONT_SMALL, CENTER);
expOnAltar = new CLabel(73, 543, FONT_SMALL, CENTER);
expToLevel = std::make_shared<CLabel>(73, 475, FONT_SMALL, CENTER);
expOnAltar = std::make_shared<CLabel>(73, 543, FONT_SMALL, CENTER);
setExpToLevel();
calcTotalExp();
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
{
@ -1248,10 +1220,10 @@ void CAltarWindow::makeDeal()
for(int& val : sacrificedUnits)
val = 0;
for(CTradeableItem *t : items[0])
for(auto item : items[0])
{
t->setType(CREATURE_PLACEHOLDER);
t->subtitle = "";
item->setType(CREATURE_PLACEHOLDER);
item->subtitle = "";
}
}
else
@ -1265,10 +1237,10 @@ void CAltarWindow::makeDeal()
LOCPLINT->cb->trade(market->o, mode, positions, {}, {}, hero);
arts->artifactsOnAltar.clear();
for(CTradeableItem *t : items[0])
for(auto item : items[0])
{
t->setID(-1);
t->subtitle = "";
item->setID(-1);
item->subtitle = "";
}
arts->commonInfo->reset();
@ -1284,15 +1256,15 @@ void CAltarWindow::SacrificeAll()
if(mode == EMarketMode::CREATURE_EXP)
{
bool movedAnything = false;
for(CTradeableItem *t : items[1])
sacrificedUnits[t->serial] = hero->getStackCount(SlotID(t->serial));
for(auto item : items[1])
sacrificedUnits[item->serial] = hero->getStackCount(SlotID(item->serial));
sacrificedUnits[items[1].front()->serial]--;
for(CTradeableItem *t : items[0])
for(auto item : items[0])
{
updateRight(t);
if(t->type == CREATURE)
updateRight(item);
if(item->type == CREATURE)
movedAnything = true;
}
@ -1350,13 +1322,14 @@ void CAltarWindow::selectOppositeItem(bool side)
void CAltarWindow::mimicCres()
{
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
std::vector<Rect> positions;
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);
hlp->pos = positions[t->serial] + this->pos.topLeft();
auto hlp = std::make_shared<CTradeableItem>(positions[item->serial].topLeft(), CREATURE_PLACEHOLDER, item->id, false, item->serial);
hlp->pos = positions[item->serial] + this->pos.topLeft();
items[0].push_back(hlp);
}
}
@ -1389,7 +1362,7 @@ void CAltarWindow::garrisonChanged()
if(mode != EMarketMode::CREATURE_EXP)
return;
std::set<CTradeableItem *> empty;
std::set<std::shared_ptr<CTradeableItem>> empty;
getEmptySlots(empty);
removeItems(empty);
@ -1401,9 +1374,11 @@ void CAltarWindow::garrisonChanged()
void CAltarWindow::getExpValues()
{
int dump;
for(CTradeableItem *t : items[1])
if(t->id >= 0)
market->getOffer(t->id, 0, dump, expPerUnit[t->serial], EMarketMode::CREATURE_EXP);
for(auto item : items[1])
{
if(item->id >= 0)
market->getOffer(item->id, 0, dump, expPerUnit[item->serial], EMarketMode::CREATURE_EXP);
}
}
void CAltarWindow::calcTotalExp()
@ -1446,7 +1421,7 @@ void CAltarWindow::blockTrade()
deal->block(true);
}
void CAltarWindow::updateRight(CTradeableItem *toUpdate)
void CAltarWindow::updateRight(std::shared_ptr<CTradeableItem> toUpdate)
{
int val = sacrificedUnits[toUpdate->serial];
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
{
@ -1531,13 +1506,13 @@ bool CAltarWindow::putOnAltar(CTradeableItem* altarSlot, const CArtifactInstance
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);
if(arts->commonInfo->src.art)
{
arts->commonInfo->dst.slotID = freeBackpackSlot;
arts->commonInfo->dst.AOH = arts;
arts->commonInfo->dst.AOH = arts.get();
}
if(putOnAltar(altarSlot, art))

View File

@ -16,6 +16,7 @@
class IMarket;
class CSlider;
class CTextBox;
class CGStatusBar;
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
};
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();
int getIndex();
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;
int id;
const int serial;
@ -41,37 +42,43 @@ public:
void setType(EType newType);
void setID(int newID);
const CArtifactInstance *getArtInstance() const;
void setArtInstance(const CArtifactInstance *art);
const CArtifactInstance * getArtInstance() const;
void setArtInstance(const CArtifactInstance * art);
CFunctionList<void()> callback;
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 hover (bool on) override;
void hover(bool on) override;
void showAll(SDL_Surface * to) override;
void clickLeft(tribool down, bool previousState) override;
std::string getName(int number = -1) const;
CTradeableItem(Point pos, EType Type, int ID, bool Left, int Serial);
};
const IMarket *market;
const CGHeroInstance *hero;
const IMarket * market;
const CGHeroInstance * hero;
CArtifactsOfHero *arts;
std::shared_ptr<CArtifactsOfHero> arts;
//all indexes: 1 = left, 0 = right
std::vector<CTradeableItem*> items[2];
CTradeableItem *hLeft, *hRight; //highlighted items (nullptr if no highlight)
std::array<std::vector<std::shared_ptr<CTradeableItem>>, 2> items;
//highlighted items (nullptr if no highlight)
std::shared_ptr<CTradeableItem> hLeft;
std::shared_ptr<CTradeableItem> hRight;
EType itemsType[2];
EMarketMode::EMarketMode mode;//0 - res<->res; 1 - res<->plauer; 2 - buy artifact; 3 - sell artifact
CButton *ok, *max, *deal;
CSlider *slider; //for choosing amount to be exchanged
EMarketMode::EMarketMode mode;
std::shared_ptr<CButton> ok;
std::shared_ptr<CButton> max;
std::shared_ptr<CButton> deal;
std::shared_ptr<CSlider> slider; //for choosing amount to be exchanged
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;
@ -80,9 +87,9 @@ public:
void initItems(bool Left);
std::vector<int> *getItemsIds(bool Left); //nullptr if default
void getPositionsFor(std::vector<Rect> &poss, bool Left, EType type) const;
void removeItems(const std::set<CTradeableItem *> &toRemove);
void removeItem(CTradeableItem * t);
void getEmptySlots(std::set<CTradeableItem *> &toRemove);
void removeItems(const std::set<std::shared_ptr<CTradeableItem>> & toRemove);
void removeItem(std::shared_ptr<CTradeableItem> item);
void getEmptySlots(std::set<std::shared_ptr<CTradeableItem>> & toRemove);
void setMode(EMarketMode::EMarketMode Mode); //mode setter
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 void garrisonChanged() = 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
{
std::shared_ptr<CLabel> titleLabel;
bool printButtonFor(EMarketMode::EMarketMode M) const;
std::string getBackgroundForMode(EMarketMode::EMarketMode mode);
public:
int r1, r2; //suggested amounts of traded resources
bool madeTransaction; //if player made at least one transaction
CTextBox *traderText;
std::shared_ptr<CTextBox> traderText;
void setMax();
void sliderMoved(int to);
void makeDeal();
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();
Point selectionOffset(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 artifactsChanged(bool left) override;
void resourceChanged();
@ -126,19 +139,20 @@ public:
class CAltarWindow : public CTradeWindow
{
CAnimImage * artIcon;
std::shared_ptr<CAnimImage> artIcon;
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();
std::vector<int> sacrificedUnits, //[slot_nr] -> how many creatures from that slot will be sacrificed
expPerUnit;
CButton *sacrificeAll, *sacrificeBackpack;
CLabel *expToLevel, *expOnAltar;
void getExpValues();
void selectionChanged(bool side) override; //true == left
void selectOppositeItem(bool side);
@ -146,7 +160,7 @@ public:
void SacrificeBackpack();
void putOnAltar(int backpackIndex);
bool putOnAltar(CTradeableItem* altarSlot, const CArtifactInstance *art);
bool putOnAltar(std::shared_ptr<CTradeableItem> altarSlot, const CArtifactInstance * art);
void makeDeal();
void showAll(SDL_Surface * to) override;
@ -161,9 +175,9 @@ public:
void artifactsChanged(bool left) override;
void calcTotalExp();
void setExpToLevel();
void updateRight(CTradeableItem *toUpdate);
void updateRight(std::shared_ptr<CTradeableItem> toUpdate);
void artifactPicked();
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
CWindowObject::CWindowObject(int options_, std::string imageName, Point centerAt):
CIntObject(getUsedEvents(options_), Point()),
shadow(nullptr),
options(options_),
background(createBg(imageName, options & PLAYER_COLORED))
CIntObject(getUsedEvents(options_), Point()),
shadow(nullptr),
options(options_),
background(createBg(imageName, options & PLAYER_COLORED))
{
assert(parent == nullptr); //Safe to remove, but windows should not have parent
defActions = 255-DISPOSE;
if (options & RCLICK_POPUP)
CCS->curh->hide();
@ -54,51 +56,48 @@ CWindowObject::CWindowObject(int options_, std::string imageName, Point centerAt
}
CWindowObject::CWindowObject(int options_, std::string imageName):
CIntObject(getUsedEvents(options_), Point()),
shadow(nullptr),
options(options_),
background(createBg(imageName, options & PLAYER_COLORED))
CIntObject(getUsedEvents(options_), Point()),
options(options_),
background(createBg(imageName, options_ & PLAYER_COLORED))
{
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();
if (background)
if(background)
pos = background->center();
else
center(Point(screen->w/2, screen->h/2));
if (!(options & SHADOW_DISABLED))
if(!(options & SHADOW_DISABLED))
setShadow(true);
}
CWindowObject::~CWindowObject()
{
setShadow(false);
}
CWindowObject::~CWindowObject() = default;
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;
auto image = new CPicture(imageName);
if (playerColored)
auto image = std::make_shared<CPicture>(imageName);
if(playerColored)
image->colorize(LOCPLINT->playerID);
return image;
}
void CWindowObject::setBackground(std::string filename)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
delete background;
background = createBg(filename, options & PLAYER_COLORED);
if (background)
if(background)
pos = background->center(Point(pos.w/2 + pos.x, pos.h/2 + pos.y));
updateShadow();
@ -123,16 +122,16 @@ void CWindowObject::setShadow(bool on)
//size of shadow
static const int size = 8;
if (on == bool(shadow))
if(on == bool(shadow))
return;
vstd::clear_pointer(shadow);
shadow.reset();
//object too small to cast shadow
if (pos.h <= size || pos.w <= size)
if(pos.h <= size || pos.w <= size)
return;
if (on)
if(on)
{
//helper to set last row
@ -164,7 +163,7 @@ void CWindowObject::setShadow(bool on)
static SDL_Surface * shadowRightTempl = nullptr;
//one-time initialization
if (!shadowCornerTempl)
if(!shadowCornerTempl)
{
//create "template" surfaces
shadowCornerTempl = CSDL_Ext::createSurfaceWithBpp<4>(size, size);
@ -185,8 +184,6 @@ void CWindowObject::setShadow(bool on)
blitAlphaRow(shadowCornerTempl, size-1);
}
OBJ_CONSTRUCTION_CAPTURING_ALL;
//FIXME: do something with this points
Point shadowStart;
if (options & BORDERED)
@ -215,10 +212,18 @@ void CWindowObject::setShadow(bool on)
blitAlphaRow(shadowRight, 0);
//generate "shadow" object with these 3 pieces in it
shadow = new CIntObject();
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));
{
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
shadow = std::make_shared<CIntObject>();
}
{
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
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);
CIntObject *shadow;
std::shared_ptr<CIntObject> shadow;
void setShadow(bool on);
int options;
protected:
CPicture * background;
std::shared_ptr<CPicture> background;
//Simple function with call to GH.popInt
void close();
//Used only if RCLICK_POPUP was set
void clickRight(tribool down, bool previousState) override;
//To display border
void showAll(SDL_Surface *to) override;
//change or set background image
void setBackground(std::string filename);
void updateShadow();
void setBackground(std::string filename);
public:
enum EOptions
{
@ -51,4 +49,6 @@ public:
CWindowObject(int options, std::string imageName, Point centerAt);
CWindowObject(int options, std::string imageName = "");
~CWindowObject();
void showAll(SDL_Surface * to) override;
};

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -33,53 +33,62 @@ class CToggleButton;
class CToggleGroup;
class CVolumeSlider;
class CGStatusBar;
class CTextBox;
class CResDataBar;
class CHeroWithMaybePickedArtifact;
/// Recruitment window where you can recruit creatures
class CRecruitmentWindow : public CWindowObject
{
class CCreatureCard : public CIntObject
class CCreatureCard : public CIntObject, public std::enable_shared_from_this<CCreatureCard>
{
CRecruitmentWindow * parent;
CCreaturePic *pic; //creature's animation
std::shared_ptr<CCreaturePic> animation;
bool selected;
void clickLeft(tribool down, bool previousState) override;
void clickRight(tribool down, bool previousState) override;
void showAll(SDL_Surface *to) override;
public:
const CCreature * creature;
si32 amount;
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
int level;
const CArmedInstance *dst;
const CArmedInstance * dst;
CCreatureCard * selected;
std::vector<CCreatureCard *> cards;
std::shared_ptr<CGStatusBar> statusBar;
CSlider *slider; //for selecting amount
CButton *maxButton, *buyButton, *cancelButton;
//labels for visible values
CLabel * title;
CLabel * availableValue;
CLabel * toRecruitValue;
CreatureCostBox * costPerTroopValue;
CreatureCostBox * totalCostValue;
std::shared_ptr<CCreatureCard> selected;
std::vector<std::shared_ptr<CCreatureCard>> cards;
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 sliderMoved(int to);
void showAll(SDL_Surface *to) override;
void showAll(SDL_Surface * to) override;
public:
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();
};
@ -92,12 +101,15 @@ class CSplitWindow : public CWindowObject
int leftMin;
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 setAmount(int value, bool left);
void sliderMoved(int value);
@ -110,22 +122,27 @@ public:
* leftMin, rightMin - minimal amount of creatures in each stack
* leftAmount, rightAmount - amount of creatures in each stack
*/
CSplitWindow(const CCreature * creature, std::function<void(int, int)> callback,
int leftMin, int rightMin, int leftAmount, int rightAmount);
CSplitWindow(const CCreature * creature, std::function<void(int, int)> callback, 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
{
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;
void selectionChanged(unsigned to);
public:
public:
CLevelWindow(const CGHeroInstance *hero, PrimarySkill::PrimarySkill pskill, std::vector<SecondarySkill> &skills, std::function<void(ui32)> callback);
~CLevelWindow();
};
/// Town portal, castle gate window
@ -133,27 +150,29 @@ class CObjectListWindow : public CWindowObject
{
class CItem : public CIntObject
{
CObjectListWindow *parent;
CLabel *text;
CPicture *border;
CObjectListWindow * parent;
std::shared_ptr<CLabel> text;
std::shared_ptr<CPicture> border;
public:
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 clickLeft(tribool down, bool previousState) override;
};
std::function<void(int)> onSelect;//called when OK button is pressed, returns id of selected item.
CLabel * title;
CLabel * descr;
std::shared_ptr<CIntObject> titleWidget;
std::shared_ptr<CLabel> title;
std::shared_ptr<CLabel> descr;
CListBox * list;
CButton *ok, *exit;
std::shared_ptr<CListBox> list;
std::shared_ptr<CButton> ok;
std::shared_ptr<CButton> exit;
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();
public:
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
/// Image can be nullptr
///item names will be taken from map objects
CObjectListWindow(const std::vector<int> &_items, CIntObject * titlePic, std::string _title, std::string _descr,
std::function<void(int)> Callback);
CObjectListWindow(const std::vector<int> &_items, std::shared_ptr<CIntObject> titleWidget_, std::string _title, std::string _descr, 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::function<void(int)> Callback);
CIntObject *genItem(size_t index);
std::shared_ptr<CIntObject> genItem(size_t index);
void elementSelected();//call callback and close this window
void changeSelection(size_t which);
void keyPressed (const SDL_KeyboardEvent & key) override;
@ -178,23 +194,28 @@ public:
class CSystemOptionsWindow : public CWindowObject
{
private:
CLabel *title;
CLabelGroup *leftGroup;
CLabelGroup *rightGroup;
CButton *load, *save, *restart, *mainMenu, *quitGame, *backToMap; //load and restart are not used yet
CToggleGroup * heroMoveSpeed;
CToggleGroup * enemyMoveSpeed;
CToggleGroup * mapScrollSpeed;
CVolumeSlider * musicVolume, * effectsVolume;
std::shared_ptr<CLabel> title;
std::shared_ptr<CLabelGroup> leftGroup;
std::shared_ptr<CLabelGroup> rightGroup;
std::shared_ptr<CButton> load;
std::shared_ptr<CButton> save;
std::shared_ptr<CButton> restart;
std::shared_ptr<CButton> mainMenu;
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;
CToggleButton * showReminder;
CToggleButton * quickCombat;
CToggleButton * spellbookAnim;
CToggleButton * fullscreen;
std::shared_ptr<CToggleButton> showReminder;
std::shared_ptr<CToggleButton> quickCombat;
std::shared_ptr<CToggleButton> spellbookAnim;
std::shared_ptr<CToggleButton> fullscreen;
CButton *gameResButton;
CLabel *gameResLabel;
std::shared_ptr<CButton> gameResButton;
std::shared_ptr<CLabel> gameResLabel;
SettingsListener onFullscreenChanged;
@ -222,26 +243,39 @@ public:
public:
std::string hoverName;
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 clickRight(tribool down, bool previousState) 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:
int *_sel;
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 oldSelected;//0 (left) or 1 (right)
CButton *thiefGuild, *cancel, *recruit;
const CGObjectInstance *tavernObj;
std::shared_ptr<CButton> thiefGuild;
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();
void recruitb();
@ -249,29 +283,47 @@ public:
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];
LRClickableAreaWText *experience[2];
LRClickableAreaWText *spellPoints[2];
CHeroArea *portrait[2];
std::array<std::shared_ptr<MoraleLuckBox>, 2> morale;
std::array<std::shared_ptr<MoraleLuckBox>, 2> luck;
std::shared_ptr<CButton> quit;
std::array<std::shared_ptr<CButton>, 2> questlogButton;
std::shared_ptr<CGStatusBar> statusBar;
std::shared_ptr<CGarrisonInt> garr;
public:
std::array<const CGHeroInstance *, 2> heroInst;
std::array<std::shared_ptr<CArtifactsOfHero>, 2> artifs;
const CGHeroInstance* heroInst[2];
CArtifactsOfHero * artifs[2];
void updateGarrisons() override;
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();
@ -280,22 +332,23 @@ public:
/// Here you can buy ships
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:
CGStatusBar *bar;
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);
CShipyardWindow(const std::vector<si32> & cost, int state, int boatType, const std::function<void()> & onBuy);
};
/// Puzzle screen which gets uncovered when you visit obilisks
@ -303,23 +356,25 @@ class CPuzzleWindow : public CWindowObject
{
private:
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<CPicture * > piecesToRemove;
std::vector<std::shared_ptr<CPicture>> piecesToRemove;
std::vector<std::shared_ptr<CPicture>> visiblePieces;
ui8 currentAlpha;
public:
void showAll(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
class CTransformerWindow : public CWindowObject, public CGarrisonHolder
{
public:
class CItem : public CIntObject
{
public:
@ -327,7 +382,8 @@ public:
bool left;//position of the item
int size; //size of creature stack
CTransformerWindow * parent;
CAnimImage *icon;
std::shared_ptr<CAnimImage> icon;
std::shared_ptr<CLabel> count;
void move();
void clickLeft(tribool down, bool previousState) override;
@ -335,13 +391,23 @@ public:
CItem(CTransformerWindow * parent, int size, int id);
};
const CArmedInstance *army;//object with army for transforming (hero or town)
const CGHeroInstance *hero;//only if we have hero in town
const CGTownInstance *town;//market, town garrison is used if hero == nullptr
std::vector<CItem*> items;
const CArmedInstance * army;//object with army for transforming (hero or town)
const CGHeroInstance * hero;//only if we have hero in town
const CGTownInstance * town;//market, town garrison is used if hero == nullptr
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 addAll();
void updateGarrisons() override;
@ -350,8 +416,13 @@ public:
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:
int ID;//id of selected skill
CUniversityWindow * parent;
@ -364,33 +435,66 @@ class CUniversityWindow : public CWindowObject
CItem(CUniversityWindow * _parent, int _ID, int X, int Y);
};
public:
const CGHeroInstance *hero;
const CGHeroInstance * hero;
const IMarket * market;
CPicture * green, * yellow, * red;//colored bars near skills
std::vector<CItem*> items;
std::shared_ptr<CAnimation> bars;
CButton *cancel;
CGStatusBar *bar;
std::vector<std::shared_ptr<CItem>> items;
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);
void makeDeal(int skill);
};
/// Confirmation window for University
class CUnivConfirmWindow : public CWindowObject
{
public:
CUniversityWindow * parent;
CGStatusBar *bar;
CButton *confirm, *cancel;
std::shared_ptr<CTextBox> clerkSpeech;
std::shared_ptr<CLabel> name;
std::shared_ptr<CLabel> level;
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);
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
class CHillFortWindow : public CWindowObject, public CWindowWithGarrison
class CHillFortWindow : public CWindowObject, public CGarrisonHolder
{
private:
static const int slotsCount = 7;
@ -400,23 +504,29 @@ private:
const CGObjectInstance * fort;
const CGHeroInstance * hero;
CGStatusBar * bar;
CHeroArea * heroPic;//clickable hero image
CButton * quit;//closes window
CButton * upgradeAll;//upgrade all creatures
std::shared_ptr<CLabel> title;
std::shared_ptr<CHeroArea> heroPic;
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
//there is a place for only 2 resources per slot
std::array< std::array<CAnimImage *, 2>, slotsCount> slotIcons;
std::array< std::array<CLabel *, 2>, slotsCount> slotLabels;
std::array< std::array<std::shared_ptr<CAnimImage>, 2>, slotsCount> slotIcons;
std::array< std::array<std::shared_ptr<CLabel>, 2>, slotsCount> slotLabels;
std::array<CAnimImage *, resCount> totalIcons;
std::array<CLabel *, resCount> totalLabels;
std::shared_ptr<CButton> upgradeAll;
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
int getState(SlotID slot); //-1 = no creature 0=can't upgrade, 1=upgraded, 2=can upgrade
public:
@ -428,10 +538,22 @@ class CThievesGuildWindow : public CWindowObject
{
const CGObjectInstance * owner;
CGStatusBar * statusBar;
CButton * exitb;
CMinorResDataBar * resdatabar;
std::shared_ptr<CGStatusBar> statusBar;
std::shared_ptr<CButton> exitb;
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:
CThievesGuildWindow(const CGObjectInstance * _owner);
};

View File

@ -57,7 +57,7 @@ void CSelWindow::selectionChange(unsigned to)
{
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)
continue;
pom->select(i==to);
@ -65,19 +65,19 @@ void CSelWindow::selectionChange(unsigned to)
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;
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)
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
}
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.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++)
{
comps[i]->recActions = 255;
addChild(comps[i]);
comps[i]->recActions = 255-DISPOSE;
addChild(comps[i].get());
components.push_back(comps[i]);
comps[i]->onSelect = std::bind(&CSelWindow::selectionChange,this,i);
if(i<9)
@ -109,7 +109,7 @@ void CSelWindow::madeChoice()
int ret = -1;
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;
}
@ -117,21 +117,21 @@ void CSelWindow::madeChoice()
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;
ID = QueryID(-1);
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->addCallback(Button.second); //each button will close the window apart from call-defined actions
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)
{
text->resize(text->label->textSize);
@ -145,20 +145,18 @@ CInfoWindow::CInfoWindow(std::string Text, PlayerColor player, const TCompsInfo
for(auto & comp : comps)
{
comp->recActions = 0xff;
addChild(comp);
comp->recActions = 0xff & ~DISPOSE;
addChild(comp.get());
comp->recActions &= ~(SHOWALL | UPDATE);
components.push_back(comp);
}
setDelComps(delComps);
CMessage::drawIWindow(this,Text,player);
}
CInfoWindow::CInfoWindow()
{
ID = QueryID(-1);
setDelComps(false);
text = nullptr;
}
void CInfoWindow::close()
@ -173,14 +171,7 @@ void CInfoWindow::show(SDL_Surface * to)
CIntObject::show(to);
}
CInfoWindow::~CInfoWindow()
{
if(!delComps)
{
for (auto & elem : components)
removeChild(elem);
}
}
CInfoWindow::~CInfoWindow() = default;
void CInfoWindow::showAll(SDL_Surface * to)
{
@ -188,19 +179,19 @@ void CInfoWindow::showAll(SDL_Surface * 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);
}
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());
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()> >("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[1]->addCallback( onNo );
@ -208,21 +199,21 @@ void CInfoWindow::showYesNoDialog(const std::string & text, const std::vector<CC
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;
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);
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;
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;
}
@ -231,18 +222,6 @@ std::string CInfoWindow::genText(std::string title, std::string 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)
:free(Free),bitmap(Bitmap)
{
@ -344,7 +323,7 @@ void CRClickPopup::createAndPush(const std::string &txt, const CInfoWindow::TCom
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;
intComps.push_back(component);
@ -408,47 +387,47 @@ Point CInfoBoxPopup::toScreen(Point p)
return p;
}
CInfoBoxPopup::CInfoBoxPopup(Point position, const CGTownInstance * town):
CWindowObject(RCLICK_POPUP | PLAYER_COLORED, "TOWNQVBK", toScreen(position))
CInfoBoxPopup::CInfoBoxPopup(Point position, const CGTownInstance * town)
: CWindowObject(RCLICK_POPUP | PLAYER_COLORED, "TOWNQVBK", toScreen(position))
{
InfoAboutTown iah;
LOCPLINT->cb->getTownInfo(town, iah, adventureInt->selection); //todo: should this be nearest hero?
OBJ_CONSTRUCTION_CAPTURING_ALL;
new CTownTooltip(Point(9, 10), iah);
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
tooltip = std::make_shared<CTownTooltip>(Point(9, 10), iah);
}
CInfoBoxPopup::CInfoBoxPopup(Point position, const CGHeroInstance * hero):
CWindowObject(RCLICK_POPUP | PLAYER_COLORED, "HEROQVBK", toScreen(position))
CInfoBoxPopup::CInfoBoxPopup(Point position, const CGHeroInstance * hero)
: CWindowObject(RCLICK_POPUP | PLAYER_COLORED, "HEROQVBK", toScreen(position))
{
InfoAboutHero iah;
LOCPLINT->cb->getHeroInfo(hero, iah, adventureInt->selection);//todo: should this be nearest hero?
OBJ_CONSTRUCTION_CAPTURING_ALL;
new CHeroTooltip(Point(9, 10), iah);
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
tooltip = std::make_shared<CHeroTooltip>(Point(9, 10), iah);
}
CInfoBoxPopup::CInfoBoxPopup(Point position, const CGGarrison * garr):
CWindowObject(RCLICK_POPUP | PLAYER_COLORED, "TOWNQVBK", toScreen(position))
CInfoBoxPopup::CInfoBoxPopup(Point position, const CGGarrison * garr)
: CWindowObject(RCLICK_POPUP | PLAYER_COLORED, "TOWNQVBK", toScreen(position))
{
InfoAboutTown iah;
LOCPLINT->cb->getTownInfo(garr, iah);
OBJ_CONSTRUCTION_CAPTURING_ALL;
new CArmyTooltip(Point(9, 10), iah);
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
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
{
if(nullptr == specific)
specific = adventureInt->selection;
if(nullptr == specific)
{
logGlobal->error("createInfoWin: no object to describe");
return nullptr;
}
}
switch(specific->ID)
{
case Obj::HERO:

View File

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

View File

@ -23,7 +23,6 @@ class CBattleCallback;
class ICallback;
class CGlobalAI;
struct Component;
class CSelectableComponent;
struct TryMoveHero;
class CGHeroInstance;
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 heroVisitsTown(const CGHeroInstance* hero, const CGTownInstance * town){};
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 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