mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Gui cleanup4 (#446)
* use smart pointers for almost all widget fields * use SDL2 texture for cursor * a lot af small tweaks and formatting * removed CompImage class, it is actually useless as long as regular SDLImage support margins * CGuiHandler: use smart pointers for [push|pop]Int
This commit is contained in:
parent
7c8b74a806
commit
75f8c8b29a
@ -166,7 +166,7 @@ bool CCallback::buildBuilding(const CGTownInstance *town, BuildingID buildingID)
|
||||
return true;
|
||||
}
|
||||
|
||||
int CBattleCallback::battleMakeAction(BattleAction* action)
|
||||
int CBattleCallback::battleMakeAction(const BattleAction * action)
|
||||
{
|
||||
assert(action->actionType == EActionType::HERO_SPELL);
|
||||
MakeCustomAction mca(*action);
|
||||
|
@ -36,8 +36,8 @@ public:
|
||||
bool waitTillRealize; //if true, request functions will return after they are realized by server
|
||||
bool unlockGsWhenWaiting;//if true after sending each request, gs mutex will be unlocked so the changes can be applied; NOTICE caller must have gs mx locked prior to any call to actiob callback!
|
||||
//battle
|
||||
virtual int battleMakeAction(BattleAction* action)=0;//for casting spells by hero - DO NOT use it for moving active stack
|
||||
virtual bool battleMakeTacticAction(BattleAction * action) =0; // performs tactic phase actions
|
||||
virtual int battleMakeAction(const BattleAction * action) = 0;//for casting spells by hero - DO NOT use it for moving active stack
|
||||
virtual bool battleMakeTacticAction(BattleAction * action) = 0; // performs tactic phase actions
|
||||
};
|
||||
|
||||
class IGameActionCallback
|
||||
@ -88,7 +88,7 @@ protected:
|
||||
|
||||
public:
|
||||
CBattleCallback(boost::optional<PlayerColor> Player, CClient *C);
|
||||
int battleMakeAction(BattleAction* action) override;//for casting spells by hero - DO NOT use it for moving active stack
|
||||
int battleMakeAction(const BattleAction * action) override;//for casting spells by hero - DO NOT use it for moving active stack
|
||||
bool battleMakeTacticAction(BattleAction * action) override; // performs tactic phase actions
|
||||
|
||||
friend class CCallback;
|
||||
|
@ -57,7 +57,7 @@ SDL_Surface * BitmapHandler::loadH3PCX(ui8 * pcx, size_t size)
|
||||
|
||||
if (format==PCX8B)
|
||||
{
|
||||
ret = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 8, 0, 0, 0, 0);
|
||||
ret = SDL_CreateRGBSurface(0, width, height, 8, 0, 0, 0, 0);
|
||||
|
||||
it = 0xC;
|
||||
for (int i=0; i<height; i++)
|
||||
@ -89,7 +89,7 @@ SDL_Surface * BitmapHandler::loadH3PCX(ui8 * pcx, size_t size)
|
||||
int gmask = 0x00ff00;
|
||||
int rmask = 0xff0000;
|
||||
#endif
|
||||
ret = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 24, rmask, gmask, bmask, 0);
|
||||
ret = SDL_CreateRGBSurface(0, width, height, 24, rmask, gmask, bmask, 0);
|
||||
|
||||
//it == 0xC;
|
||||
for (int i=0; i<height; i++)
|
||||
|
190
client/CMT.cpp
190
client/CMT.cpp
@ -118,32 +118,13 @@ static void mainLoop();
|
||||
|
||||
void init()
|
||||
{
|
||||
CStopWatch tmh, pomtime;
|
||||
CStopWatch tmh;
|
||||
|
||||
loadDLLClasses();
|
||||
const_cast<CGameInfo*>(CGI)->setFromLib();
|
||||
|
||||
logGlobal->info("Initializing VCMI_Lib: %d ms", tmh.getDiff());
|
||||
|
||||
|
||||
if(!settings["session"]["headless"].Bool())
|
||||
{
|
||||
pomtime.getDiff();
|
||||
CCS->curh = new CCursorHandler();
|
||||
graphics = new Graphics(); // should be before curh->init()
|
||||
|
||||
CCS->curh->initCursor();
|
||||
CCS->curh->show();
|
||||
logGlobal->info("Screen handler: %d ms", pomtime.getDiff());
|
||||
pomtime.getDiff();
|
||||
|
||||
graphics->load();
|
||||
logGlobal->info("\tMain graphics: %d ms", pomtime.getDiff());
|
||||
logGlobal->info("Initializing game graphics: %d ms", tmh.getDiff());
|
||||
|
||||
CMessage::init();
|
||||
logGlobal->info("Message handler: %d ms", tmh.getDiff());
|
||||
}
|
||||
}
|
||||
|
||||
static void prog_version()
|
||||
@ -466,8 +447,10 @@ int main(int argc, char * argv[])
|
||||
playIntro();
|
||||
SDL_SetRenderDrawColor(mainRenderer, 0, 0, 0, 255);
|
||||
SDL_RenderClear(mainRenderer);
|
||||
SDL_RenderPresent(mainRenderer);
|
||||
}
|
||||
SDL_RenderPresent(mainRenderer);
|
||||
|
||||
|
||||
#ifndef VCMI_NO_THREADED_LOAD
|
||||
#ifdef VCMI_ANDROID // android loads the data quite slowly so we display native progressbar to prevent having only black screen for few seconds
|
||||
{
|
||||
@ -480,6 +463,27 @@ int main(int argc, char * argv[])
|
||||
}
|
||||
#endif // ANDROID
|
||||
#endif // THREADED
|
||||
|
||||
if(!settings["session"]["headless"].Bool())
|
||||
{
|
||||
pomtime.getDiff();
|
||||
CCS->curh = new CCursorHandler();
|
||||
graphics = new Graphics(); // should be before curh->init()
|
||||
|
||||
CCS->curh->initCursor();
|
||||
logGlobal->info("Screen handler: %d ms", pomtime.getDiff());
|
||||
pomtime.getDiff();
|
||||
|
||||
graphics->load();//must be after Content loading but should be in main thread
|
||||
logGlobal->info("Main graphics: %d ms", pomtime.getDiff());
|
||||
|
||||
CMessage::init();
|
||||
logGlobal->info("Message handler: %d ms", pomtime.getDiff());
|
||||
|
||||
CCS->curh->show();
|
||||
}
|
||||
|
||||
|
||||
logGlobal->info("Initialization of VCMI (together): %d ms", total.getDiff());
|
||||
|
||||
session["autoSkip"].Bool() = vm.count("autoSkip");
|
||||
@ -500,7 +504,7 @@ int main(int argc, char * argv[])
|
||||
}
|
||||
else
|
||||
{
|
||||
GH.curInt = CMainMenu::create();
|
||||
GH.curInt = CMainMenu::create().get();
|
||||
}
|
||||
|
||||
if(!settings["session"]["headless"].Bool())
|
||||
@ -786,9 +790,9 @@ void processCommand(const std::string &message)
|
||||
}
|
||||
else if(cn == "gui")
|
||||
{
|
||||
for(const IShowActivatable *child : GH.listInt)
|
||||
for(auto child : GH.listInt)
|
||||
{
|
||||
if(const CIntObject *obj = dynamic_cast<const CIntObject *>(child))
|
||||
if(const CIntObject *obj = dynamic_cast<const CIntObject *>(child.get()))
|
||||
printInfoAboutIntObject(obj, 0);
|
||||
else
|
||||
std::cout << typeid(*child).name() << std::endl;
|
||||
@ -970,9 +974,9 @@ void processCommand(const std::string &message)
|
||||
//plays intro, ends when intro is over or button has been pressed (handles events)
|
||||
void playIntro()
|
||||
{
|
||||
if(CCS->videoh->openAndPlayVideo("3DOLOGO.SMK", 0, 1, screen, true, true))
|
||||
if(CCS->videoh->openAndPlayVideo("3DOLOGO.SMK", 0, 1, true, true))
|
||||
{
|
||||
CCS->videoh->openAndPlayVideo("AZVS.SMK", 0, 1, screen, true, true);
|
||||
CCS->videoh->openAndPlayVideo("AZVS.SMK", 0, 1, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1044,18 +1048,6 @@ static void cleanupRenderer()
|
||||
SDL_DestroyTexture(screenTexture);
|
||||
screenTexture = nullptr;
|
||||
}
|
||||
|
||||
if(nullptr != mainRenderer)
|
||||
{
|
||||
SDL_DestroyRenderer(mainRenderer);
|
||||
mainRenderer = nullptr;
|
||||
}
|
||||
|
||||
if(nullptr != mainWindow)
|
||||
{
|
||||
SDL_DestroyWindow(mainWindow);
|
||||
mainWindow = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
static bool recreateWindow(int w, int h, int bpp, bool fullscreen, int displayIndex)
|
||||
@ -1080,47 +1072,85 @@ static bool recreateWindow(int w, int h, int bpp, bool fullscreen, int displayIn
|
||||
}
|
||||
|
||||
bool bufOnScreen = (screenBuf == screen);
|
||||
bool realFullscreen = settings["video"]["realFullscreen"].Bool();
|
||||
|
||||
cleanupRenderer();
|
||||
|
||||
bool realFullscreen = settings["video"]["realFullscreen"].Bool();
|
||||
|
||||
#ifdef VCMI_ANDROID
|
||||
mainWindow = SDL_CreateWindow(NAME.c_str(), SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayIndex),SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayIndex), 0, 0, SDL_WINDOW_FULLSCREEN);
|
||||
#else
|
||||
|
||||
if(fullscreen)
|
||||
if(nullptr == mainWindow)
|
||||
{
|
||||
if(realFullscreen)
|
||||
mainWindow = SDL_CreateWindow(NAME.c_str(), SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayIndex), SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayIndex), w, h, SDL_WINDOW_FULLSCREEN);
|
||||
else //in windowed full-screen mode use desktop resolution
|
||||
mainWindow = SDL_CreateWindow(NAME.c_str(), SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayIndex),SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayIndex), 0, 0, SDL_WINDOW_FULLSCREEN_DESKTOP);
|
||||
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
|
||||
|
||||
#ifdef VCMI_ANDROID
|
||||
mainWindow = SDL_CreateWindow(NAME.c_str(), SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayIndex),SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayIndex), 0, 0, SDL_WINDOW_FULLSCREEN);
|
||||
#else
|
||||
|
||||
if(fullscreen)
|
||||
{
|
||||
if(realFullscreen)
|
||||
mainWindow = SDL_CreateWindow(NAME.c_str(), SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayIndex), SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayIndex), w, h, SDL_WINDOW_FULLSCREEN);
|
||||
else //in windowed full-screen mode use desktop resolution
|
||||
mainWindow = SDL_CreateWindow(NAME.c_str(), SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayIndex),SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayIndex), 0, 0, SDL_WINDOW_FULLSCREEN_DESKTOP);
|
||||
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
|
||||
}
|
||||
else
|
||||
{
|
||||
mainWindow = SDL_CreateWindow(NAME.c_str(), SDL_WINDOWPOS_CENTERED_DISPLAY(displayIndex),SDL_WINDOWPOS_CENTERED_DISPLAY(displayIndex), w, h, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
if(nullptr == mainWindow)
|
||||
{
|
||||
throw std::runtime_error("Unable to create window\n");
|
||||
}
|
||||
|
||||
//create first available renderer if preferred not set. Use no flags, so HW accelerated will be preferred but SW renderer also will possible
|
||||
mainRenderer = SDL_CreateRenderer(mainWindow,preferredDriverIndex,0);
|
||||
|
||||
if(nullptr == mainRenderer)
|
||||
{
|
||||
throw std::runtime_error("Unable to create renderer\n");
|
||||
}
|
||||
|
||||
|
||||
SDL_RendererInfo info;
|
||||
SDL_GetRendererInfo(mainRenderer, &info);
|
||||
logGlobal->info("Created renderer %s", info.name);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
mainWindow = SDL_CreateWindow(NAME.c_str(), SDL_WINDOWPOS_CENTERED_DISPLAY(displayIndex),SDL_WINDOWPOS_CENTERED_DISPLAY(displayIndex), w, h, 0);
|
||||
}
|
||||
#ifndef VCMI_ANDROID
|
||||
|
||||
if(fullscreen)
|
||||
{
|
||||
if(realFullscreen)
|
||||
{
|
||||
SDL_SetWindowFullscreen(mainWindow, SDL_WINDOW_FULLSCREEN);
|
||||
|
||||
SDL_DisplayMode mode;
|
||||
SDL_GetDesktopDisplayMode(displayIndex, &mode);
|
||||
mode.w = w;
|
||||
mode.h = h;
|
||||
|
||||
SDL_SetWindowDisplayMode(mainWindow, &mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_SetWindowFullscreen(mainWindow, SDL_WINDOW_FULLSCREEN_DESKTOP);
|
||||
}
|
||||
|
||||
SDL_SetWindowPosition(mainWindow, SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayIndex), SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayIndex));
|
||||
|
||||
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_SetWindowFullscreen(mainWindow, 0);
|
||||
SDL_SetWindowSize(mainWindow, w, h);
|
||||
SDL_SetWindowPosition(mainWindow, SDL_WINDOWPOS_CENTERED_DISPLAY(displayIndex), SDL_WINDOWPOS_CENTERED_DISPLAY(displayIndex));
|
||||
}
|
||||
#endif
|
||||
|
||||
if(nullptr == mainWindow)
|
||||
{
|
||||
throw std::runtime_error("Unable to create window\n");
|
||||
}
|
||||
|
||||
|
||||
//create first available renderer if preferred not set. Use no flags, so HW accelerated will be preferred but SW renderer also will possible
|
||||
mainRenderer = SDL_CreateRenderer(mainWindow,preferredDriverIndex,0);
|
||||
|
||||
if(nullptr == mainRenderer)
|
||||
{
|
||||
throw std::runtime_error("Unable to create renderer\n");
|
||||
}
|
||||
|
||||
SDL_RendererInfo info;
|
||||
SDL_GetRendererInfo(mainRenderer, &info);
|
||||
logGlobal->info("Created renderer %s", info.name);
|
||||
|
||||
if(!(fullscreen && realFullscreen))
|
||||
{
|
||||
SDL_RenderSetLogicalSize(mainRenderer, w, h);
|
||||
@ -1270,7 +1300,7 @@ static void handleEvent(SDL_Event & ev)
|
||||
};
|
||||
if(epilogue.hasPrologEpilog)
|
||||
{
|
||||
GH.pushInt(new CPrologEpilogVideo(epilogue, finisher));
|
||||
GH.pushIntT<CPrologEpilogVideo>(epilogue, finisher);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1306,6 +1336,13 @@ static void handleEvent(SDL_Event & ev)
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//preprocessing
|
||||
if(ev.type == SDL_MOUSEMOTION)
|
||||
{
|
||||
CCS->curh->cursorMove(ev.motion.x, ev.motion.y);
|
||||
}
|
||||
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lock(eventsM);
|
||||
events.push(ev);
|
||||
@ -1349,6 +1386,19 @@ void handleQuit(bool ask)
|
||||
if(!settings["session"]["headless"].Bool())
|
||||
{
|
||||
cleanupRenderer();
|
||||
|
||||
if(nullptr != mainRenderer)
|
||||
{
|
||||
SDL_DestroyRenderer(mainRenderer);
|
||||
mainRenderer = nullptr;
|
||||
}
|
||||
|
||||
if(nullptr != mainWindow)
|
||||
{
|
||||
SDL_DestroyWindow(mainWindow);
|
||||
mainWindow = nullptr;
|
||||
}
|
||||
|
||||
SDL_Quit();
|
||||
}
|
||||
|
||||
|
@ -97,7 +97,7 @@ void CMessage::dispose()
|
||||
SDL_Surface * CMessage::drawDialogBox(int w, int h, PlayerColor playerColor)
|
||||
{
|
||||
//prepare surface
|
||||
SDL_Surface * ret = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, screen->format->BitsPerPixel, screen->format->Rmask, screen->format->Gmask, screen->format->Bmask, screen->format->Amask);
|
||||
SDL_Surface * ret = SDL_CreateRGBSurface(0, w, h, screen->format->BitsPerPixel, screen->format->Rmask, screen->format->Gmask, screen->format->Bmask, screen->format->Amask);
|
||||
for (int i=0; i<w; i+=background->w)//background
|
||||
{
|
||||
for (int j=0; j<h; j+=background->h)
|
||||
|
@ -19,16 +19,13 @@ class CComponent;
|
||||
/// Class which draws formatted text messages and generates chat windows
|
||||
class CMessage
|
||||
{
|
||||
public:
|
||||
//Function usd only in CMessage.cpp
|
||||
static std::pair<int,int> getMaxSizes(std::vector<std::vector<SDL_Surface*> > * txtg, int fontHeight);
|
||||
|
||||
/// Draw border on exiting surface
|
||||
static void drawBorder(PlayerColor playerColor, SDL_Surface * ret, int w, int h, int x=0, int y=0);
|
||||
|
||||
/// Draw simple dialog box (borders and background only)
|
||||
static SDL_Surface * drawDialogBox(int w, int h, PlayerColor playerColor = PlayerColor(1));
|
||||
|
||||
public:
|
||||
/// Draw border on exiting surface
|
||||
static void drawBorder(PlayerColor playerColor, SDL_Surface * ret, int w, int h, int x=0, int y=0);
|
||||
|
||||
static void drawIWindow(CInfoWindow * ret, std::string text, PlayerColor player);
|
||||
|
||||
/// split text in lines
|
||||
|
@ -121,8 +121,8 @@ CPlayerInterface::CPlayerInterface(PlayerColor Player)
|
||||
playerID=Player;
|
||||
human=true;
|
||||
currentSelection = nullptr;
|
||||
castleInt = nullptr;
|
||||
battleInt = nullptr;
|
||||
castleInt = nullptr;
|
||||
makingTurn = false;
|
||||
showingDialog = new CondSh<bool>(false);
|
||||
cingconsole = new CInGameConsole();
|
||||
@ -150,9 +150,7 @@ void CPlayerInterface::init(std::shared_ptr<CCallback> CB)
|
||||
initializeHeroTownList();
|
||||
|
||||
// always recreate advmap interface to avoid possible memory-corruption bugs
|
||||
if (adventureInt)
|
||||
delete adventureInt;
|
||||
adventureInt = new CAdvMapInt();
|
||||
adventureInt.reset(new CAdvMapInt());
|
||||
}
|
||||
void CPlayerInterface::yourTurn()
|
||||
{
|
||||
@ -464,11 +462,13 @@ void CPlayerInterface::heroCreated(const CGHeroInstance * hero)
|
||||
}
|
||||
void CPlayerInterface::openTownWindow(const CGTownInstance * town)
|
||||
{
|
||||
if (castleInt)
|
||||
if(castleInt)
|
||||
castleInt->close();
|
||||
castleInt = nullptr;
|
||||
|
||||
castleInt = new CCastleInterface(town);
|
||||
GH.pushInt(castleInt);
|
||||
auto newCastleInt = std::make_shared<CCastleInterface>(town);
|
||||
|
||||
GH.pushInt(newCastleInt);
|
||||
}
|
||||
|
||||
int3 CPlayerInterface::repairScreenPos(int3 pos)
|
||||
@ -496,7 +496,7 @@ void CPlayerInterface::heroPrimarySkillChanged(const CGHeroInstance * hero, int
|
||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||
if (which == 4)
|
||||
{
|
||||
if (CAltarWindow *ctw = dynamic_cast<CAltarWindow *>(GH.topInt()))
|
||||
if (CAltarWindow *ctw = dynamic_cast<CAltarWindow *>(GH.topInt().get()))
|
||||
ctw->setExpToLevel();
|
||||
}
|
||||
else if (which < GameConstants::PRIMARY_SKILLS) //no need to redraw infowin if this is experience (exp is treated as prim skill with id==4)
|
||||
@ -506,7 +506,7 @@ void CPlayerInterface::heroPrimarySkillChanged(const CGHeroInstance * hero, int
|
||||
void CPlayerInterface::heroSecondarySkillChanged(const CGHeroInstance * hero, int which, int val)
|
||||
{
|
||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||
CUniversityWindow* cuw = dynamic_cast<CUniversityWindow*>(GH.topInt());
|
||||
CUniversityWindow* cuw = dynamic_cast<CUniversityWindow*>(GH.topInt().get());
|
||||
if (cuw) //university window is open
|
||||
{
|
||||
GH.totalRedraw();
|
||||
@ -529,7 +529,7 @@ void CPlayerInterface::heroMovePointsChanged(const CGHeroInstance * hero)
|
||||
void CPlayerInterface::receivedResource()
|
||||
{
|
||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||
if (CMarketplaceWindow *mw = dynamic_cast<CMarketplaceWindow *>(GH.topInt()))
|
||||
if (CMarketplaceWindow *mw = dynamic_cast<CMarketplaceWindow *>(GH.topInt().get()))
|
||||
mw->resourceChanged();
|
||||
|
||||
GH.totalRedraw();
|
||||
@ -540,21 +540,21 @@ void CPlayerInterface::heroGotLevel(const CGHeroInstance *hero, PrimarySkill::Pr
|
||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||
waitWhileDialog();
|
||||
CCS->soundh->playSound(soundBase::heroNewLevel);
|
||||
|
||||
CLevelWindow *lw = new CLevelWindow(hero,pskill,skills,
|
||||
[=](ui32 selection){ cb->selectionMade(selection, queryID); });
|
||||
GH.pushInt(lw);
|
||||
GH.pushIntT<CLevelWindow>(hero, pskill, skills, [=](ui32 selection)
|
||||
{
|
||||
cb->selectionMade(selection, queryID);
|
||||
});
|
||||
}
|
||||
|
||||
void CPlayerInterface::commanderGotLevel (const CCommanderInstance * commander, std::vector<ui32> skills, QueryID queryID)
|
||||
{
|
||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||
waitWhileDialog();
|
||||
CCS->soundh->playSound(soundBase::heroNewLevel);
|
||||
|
||||
GH.pushInt(new CStackWindow(commander, skills, [=](ui32 selection)
|
||||
GH.pushIntT<CStackWindow>(commander, skills, [=](ui32 selection)
|
||||
{
|
||||
cb->selectionMade(selection, queryID);
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
void CPlayerInterface::heroInGarrisonChange(const CGTownInstance *town)
|
||||
@ -578,17 +578,17 @@ void CPlayerInterface::heroInGarrisonChange(const CGTownInstance *town)
|
||||
adventureInt->heroList.update();
|
||||
adventureInt->updateNextHero(nullptr);
|
||||
|
||||
if (CCastleInterface *c = castleInt)
|
||||
if(castleInt)
|
||||
{
|
||||
c->garr->selectSlot(nullptr);
|
||||
c->garr->setArmy(town->getUpperArmy(), 0);
|
||||
c->garr->setArmy(town->visitingHero, 1);
|
||||
c->garr->recreateSlots();
|
||||
c->heroes->update();
|
||||
castleInt->garr->selectSlot(nullptr);
|
||||
castleInt->garr->setArmy(town->getUpperArmy(), 0);
|
||||
castleInt->garr->setArmy(town->visitingHero, 1);
|
||||
castleInt->garr->recreateSlots();
|
||||
castleInt->heroes->update();
|
||||
}
|
||||
for (IShowActivatable *isa : GH.listInt)
|
||||
for (auto isa : GH.listInt)
|
||||
{
|
||||
CKingdomInterface *ki = dynamic_cast<CKingdomInterface*>(isa);
|
||||
CKingdomInterface *ki = dynamic_cast<CKingdomInterface*>(isa.get());
|
||||
if (ki)
|
||||
{
|
||||
ki->townChanged(town);
|
||||
@ -632,11 +632,11 @@ void CPlayerInterface::garrisonsChanged(std::vector<const CGObjectInstance *> ob
|
||||
|
||||
for (auto & elem : GH.listInt)
|
||||
{
|
||||
CGarrisonHolder *cgh = dynamic_cast<CGarrisonHolder*>(elem);
|
||||
CGarrisonHolder *cgh = dynamic_cast<CGarrisonHolder*>(elem.get());
|
||||
if (cgh)
|
||||
cgh->updateGarrisons();
|
||||
|
||||
if (CTradeWindow *cmw = dynamic_cast<CTradeWindow*>(elem))
|
||||
if (CTradeWindow *cmw = dynamic_cast<CTradeWindow*>(elem.get()))
|
||||
{
|
||||
if (vstd::contains(objs, cmw->hero))
|
||||
cmw->garrisonChanged();
|
||||
@ -739,7 +739,7 @@ void CPlayerInterface::battleUnitsChanged(const std::vector<UnitChanges> & units
|
||||
continue;
|
||||
}
|
||||
|
||||
CCreatureAnimation * animation = iter->second;
|
||||
auto animation = iter->second;
|
||||
|
||||
if(unit->alive() && animation->isDead())
|
||||
animation->setType(CCreatureAnim::HOLDING);
|
||||
@ -905,8 +905,7 @@ void CPlayerInterface::battleEnd(const BattleResult *br)
|
||||
|
||||
if (!battleInt)
|
||||
{
|
||||
auto resWindow = new CBattleResultWindow(*br, *this);
|
||||
GH.pushInt(resWindow);
|
||||
GH.pushIntT<CBattleResultWindow>(*br, *this);
|
||||
// #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.
|
||||
waitWhileDialog();
|
||||
@ -1129,7 +1128,7 @@ void CPlayerInterface::showInfoDialog(const std::string &text, const std::vector
|
||||
{
|
||||
return;
|
||||
}
|
||||
CInfoWindow *temp = CInfoWindow::create(text, playerID, components);
|
||||
std::shared_ptr<CInfoWindow> temp = CInfoWindow::create(text, playerID, components);
|
||||
|
||||
if (makingTurn && GH.listInt.size() && LOCPLINT == this)
|
||||
{
|
||||
@ -1164,22 +1163,6 @@ void CPlayerInterface::showYesNoDialog(const std::string &text, CFunctionList<vo
|
||||
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::string str;
|
||||
text.toString(str);
|
||||
|
||||
stopMovement();
|
||||
showingDialog->setn(true);
|
||||
|
||||
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 )
|
||||
{
|
||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||
@ -1212,11 +1195,9 @@ void CPlayerInterface::showBlockingDialog( const std::string &text, const std::v
|
||||
int charperline = 35;
|
||||
if (pom.size() > 1)
|
||||
charperline = 50;
|
||||
auto temp = new CSelWindow(text, playerID, charperline, intComps, pom, askID);
|
||||
GH.pushInt(temp);
|
||||
GH.pushIntT<CSelWindow>(text, playerID, charperline, intComps, pom, askID);
|
||||
intComps[0]->clickLeft(true, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CPlayerInterface::showTeleportDialog(TeleportChannelID channel, TTeleportExitsList exits, bool impassable, QueryID askID)
|
||||
@ -1256,13 +1237,12 @@ void CPlayerInterface::showMapObjectSelectDialog(QueryID askID, const Component
|
||||
for(auto item : objects)
|
||||
tempList.push_back(item.getNum());
|
||||
|
||||
CComponent * localIconC = new CComponent(icon);
|
||||
CComponent localIconC(icon);
|
||||
|
||||
std::shared_ptr<CIntObject> localIcon = localIconC->image;
|
||||
localIconC->removeChild(localIcon.get(), false);
|
||||
delete localIconC;
|
||||
std::shared_ptr<CIntObject> localIcon = localIconC.image;
|
||||
localIconC.removeChild(localIcon.get(), false);
|
||||
|
||||
CObjectListWindow * wnd = new CObjectListWindow(tempList, localIcon, localTitle, localDescription, selectCallback);
|
||||
std::shared_ptr<CObjectListWindow> wnd = std::make_shared<CObjectListWindow>(tempList, localIcon, localTitle, localDescription, selectCallback);
|
||||
wnd->onExit = cancelCallback;
|
||||
GH.pushInt(wnd);
|
||||
}
|
||||
@ -1289,7 +1269,7 @@ void CPlayerInterface::tileHidden(const std::unordered_set<int3, ShashInt3> &pos
|
||||
void CPlayerInterface::openHeroWindow(const CGHeroInstance *hero)
|
||||
{
|
||||
boost::unique_lock<boost::recursive_mutex> un(*pim);
|
||||
GH.pushInt(new CHeroWindow(hero));
|
||||
GH.pushIntT<CHeroWindow>(hero);
|
||||
}
|
||||
|
||||
void CPlayerInterface::availableCreaturesChanged( const CGDwelling *town )
|
||||
@ -1297,13 +1277,13 @@ void CPlayerInterface::availableCreaturesChanged( const CGDwelling *town )
|
||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||
if (const CGTownInstance * townObj = dynamic_cast<const CGTownInstance*>(town))
|
||||
{
|
||||
CFortScreen *fs = dynamic_cast<CFortScreen*>(GH.topInt());
|
||||
CFortScreen *fs = dynamic_cast<CFortScreen*>(GH.topInt().get());
|
||||
if (fs)
|
||||
fs->creaturesChanged();
|
||||
|
||||
for (IShowActivatable *isa : GH.listInt)
|
||||
for(auto isa : GH.listInt)
|
||||
{
|
||||
CKingdomInterface *ki = dynamic_cast<CKingdomInterface*>(isa);
|
||||
CKingdomInterface *ki = dynamic_cast<CKingdomInterface*>(isa.get());
|
||||
if (ki && townObj)
|
||||
ki->townChanged(townObj);
|
||||
}
|
||||
@ -1311,7 +1291,7 @@ void CPlayerInterface::availableCreaturesChanged( const CGDwelling *town )
|
||||
else if (GH.listInt.size() && (town->ID == Obj::CREATURE_GENERATOR1
|
||||
|| town->ID == Obj::CREATURE_GENERATOR4 || town->ID == Obj::WAR_MACHINE_FACTORY))
|
||||
{
|
||||
CRecruitmentWindow *crw = dynamic_cast<CRecruitmentWindow*>(GH.topInt());
|
||||
CRecruitmentWindow *crw = dynamic_cast<CRecruitmentWindow*>(GH.topInt().get());
|
||||
if (crw && crw->dwelling == town)
|
||||
crw->availableCreaturesChanged();
|
||||
}
|
||||
@ -1434,7 +1414,7 @@ void CPlayerInterface::showGarrisonDialog( const CArmedInstance *up, const CGHer
|
||||
|
||||
waitForAllDialogs();
|
||||
|
||||
auto cgw = new CGarrisonWindow(up,down,removableUnits);
|
||||
auto cgw = std::make_shared<CGarrisonWindow>(up, down, removableUnits);
|
||||
cgw->quit->addCallback(onEnd);
|
||||
GH.pushInt(cgw);
|
||||
}
|
||||
@ -1497,7 +1477,7 @@ void CPlayerInterface::requestRealized( PackageApplied *pa )
|
||||
void CPlayerInterface::heroExchangeStarted(ObjectInstanceID hero1, ObjectInstanceID hero2, QueryID query)
|
||||
{
|
||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||
GH.pushInt(new CExchangeWindow(hero1, hero2, query));
|
||||
GH.pushIntT<CExchangeWindow>(hero1, hero2, query);
|
||||
}
|
||||
|
||||
void CPlayerInterface::objectPropertyChanged(const SetObjectProperty * sop)
|
||||
@ -1551,9 +1531,11 @@ void CPlayerInterface::showRecruitmentDialog(const CGDwelling *dwelling, const C
|
||||
{
|
||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||
waitWhileDialog();
|
||||
auto recruitCb = [=](CreatureID id, int count){ LOCPLINT->cb->recruitCreatures(dwelling, dst, id, count, -1); };
|
||||
CRecruitmentWindow *cr = new CRecruitmentWindow(dwelling, level, dst, recruitCb);
|
||||
GH.pushInt(cr);
|
||||
auto recruitCb = [=](CreatureID id, int count)
|
||||
{
|
||||
LOCPLINT->cb->recruitCreatures(dwelling, dst, id, count, -1);
|
||||
};
|
||||
GH.pushIntT<CRecruitmentWindow>(dwelling, level, dst, recruitCb);
|
||||
}
|
||||
|
||||
void CPlayerInterface::waitWhileDialog(bool unlockPim)
|
||||
@ -1576,8 +1558,7 @@ void CPlayerInterface::showShipyardDialog(const IShipyard *obj)
|
||||
auto state = obj->shipyardStatus();
|
||||
std::vector<si32> cost;
|
||||
obj->getBoatCost(cost);
|
||||
CShipyardWindow *csw = new CShipyardWindow(cost, state, obj->getBoatType(), [=](){ cb->buildBoat(obj); });
|
||||
GH.pushInt(csw);
|
||||
GH.pushIntT<CShipyardWindow>(cost, state, obj->getBoatType(), [=](){ cb->buildBoat(obj); });
|
||||
}
|
||||
|
||||
void CPlayerInterface::newObject( const CGObjectInstance * obj )
|
||||
@ -2159,7 +2140,7 @@ void CPlayerInterface::gameOver(PlayerColor player, const EVictoryLossCheckResul
|
||||
adventureInt->deactivate();
|
||||
if (GH.topInt() == adventureInt)
|
||||
GH.popInt(adventureInt);
|
||||
vstd::clear_pointer(adventureInt);
|
||||
adventureInt.reset();
|
||||
}
|
||||
}
|
||||
|
||||
@ -2201,7 +2182,7 @@ void CPlayerInterface::showPuzzleMap()
|
||||
double ratio = 0;
|
||||
int3 grailPos = cb->getGrailPos(&ratio);
|
||||
|
||||
GH.pushInt(new CPuzzleWindow(grailPos, ratio));
|
||||
GH.pushIntT<CPuzzleWindow>(grailPos, ratio);
|
||||
}
|
||||
|
||||
void CPlayerInterface::viewWorldMap()
|
||||
@ -2213,8 +2194,8 @@ void CPlayerInterface::advmapSpellCast(const CGHeroInstance * caster, int spellI
|
||||
{
|
||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||
|
||||
if(dynamic_cast<CSpellWindow *>(GH.topInt()))
|
||||
GH.popIntTotally(GH.topInt());
|
||||
if(dynamic_cast<CSpellWindow *>(GH.topInt().get()))
|
||||
GH.popInts(1);
|
||||
|
||||
if(spellID == SpellID::FLY || spellID == SpellID::WATER_WALK)
|
||||
eraseCurrentPathOf(caster, false);
|
||||
@ -2287,7 +2268,7 @@ void CPlayerInterface::acceptTurn()
|
||||
if (settings["session"]["autoSkip"].Bool())
|
||||
{
|
||||
centerView = false;
|
||||
while(CInfoWindow *iw = dynamic_cast<CInfoWindow *>(GH.topInt()))
|
||||
while(CInfoWindow *iw = dynamic_cast<CInfoWindow *>(GH.topInt().get()))
|
||||
iw->close();
|
||||
}
|
||||
waitWhileDialog();
|
||||
@ -2328,7 +2309,7 @@ void CPlayerInterface::acceptTurn()
|
||||
|
||||
if(settings["session"]["autoSkip"].Bool() && !LOCPLINT->shiftPressed())
|
||||
{
|
||||
if(CInfoWindow *iw = dynamic_cast<CInfoWindow *>(GH.topInt()))
|
||||
if(CInfoWindow *iw = dynamic_cast<CInfoWindow *>(GH.topInt().get()))
|
||||
iw->close();
|
||||
|
||||
adventureInt->fendTurn();
|
||||
@ -2425,54 +2406,51 @@ void CPlayerInterface::showMarketWindow(const IMarket *market, const CGHeroInsta
|
||||
{
|
||||
//EEMarketMode mode = market->availableModes().front();
|
||||
if (market->allowsTrade(EMarketMode::ARTIFACT_EXP) && visitor->getAlignment() != EAlignment::EVIL)
|
||||
GH.pushInt(new CAltarWindow(market, visitor, EMarketMode::ARTIFACT_EXP));
|
||||
GH.pushIntT<CAltarWindow>(market, visitor, EMarketMode::ARTIFACT_EXP);
|
||||
else if (market->allowsTrade(EMarketMode::CREATURE_EXP) && visitor->getAlignment() != EAlignment::GOOD)
|
||||
GH.pushInt(new CAltarWindow(market, visitor, EMarketMode::CREATURE_EXP));
|
||||
GH.pushIntT<CAltarWindow>(market, visitor, EMarketMode::CREATURE_EXP);
|
||||
}
|
||||
else
|
||||
GH.pushInt(new CMarketplaceWindow(market, visitor, market->availableModes().front()));
|
||||
{
|
||||
GH.pushIntT<CMarketplaceWindow>(market, visitor, market->availableModes().front());
|
||||
}
|
||||
}
|
||||
|
||||
void CPlayerInterface::showUniversityWindow(const IMarket *market, const CGHeroInstance *visitor)
|
||||
{
|
||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||
auto cuw = new CUniversityWindow(visitor, market);
|
||||
GH.pushInt(cuw);
|
||||
GH.pushIntT<CUniversityWindow>(visitor, market);
|
||||
}
|
||||
|
||||
void CPlayerInterface::showHillFortWindow(const CGObjectInstance *object, const CGHeroInstance *visitor)
|
||||
{
|
||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||
auto chfw = new CHillFortWindow(visitor, object);
|
||||
GH.pushInt(chfw);
|
||||
GH.pushIntT<CHillFortWindow>(visitor, object);
|
||||
}
|
||||
|
||||
void CPlayerInterface::availableArtifactsChanged(const CGBlackMarket * bm)
|
||||
{
|
||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||
if (CMarketplaceWindow *cmw = dynamic_cast<CMarketplaceWindow*>(GH.topInt()))
|
||||
if (CMarketplaceWindow *cmw = dynamic_cast<CMarketplaceWindow*>(GH.topInt().get()))
|
||||
cmw->artifactsChanged(false);
|
||||
}
|
||||
|
||||
void CPlayerInterface::showTavernWindow(const CGObjectInstance *townOrTavern)
|
||||
{
|
||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||
auto tv = new CTavernWindow(townOrTavern);
|
||||
GH.pushInt(tv);
|
||||
GH.pushIntT<CTavernWindow>(townOrTavern);
|
||||
}
|
||||
|
||||
void CPlayerInterface::showThievesGuildWindow (const CGObjectInstance * obj)
|
||||
{
|
||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||
auto tgw = new CThievesGuildWindow(obj);
|
||||
GH.pushInt(tgw);
|
||||
GH.pushIntT<CThievesGuildWindow>(obj);
|
||||
}
|
||||
|
||||
void CPlayerInterface::showQuestLog()
|
||||
{
|
||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||
CQuestLog * ql = new CQuestLog (LOCPLINT->cb->getMyQuests());
|
||||
GH.pushInt (ql);
|
||||
GH.pushIntT<CQuestLog>(LOCPLINT->cb->getMyQuests());
|
||||
}
|
||||
|
||||
void CPlayerInterface::showShipyardDialogOrProblemPopup(const IShipyard *obj)
|
||||
@ -2529,9 +2507,9 @@ void CPlayerInterface::artifactRemoved(const ArtifactLocation &al)
|
||||
{
|
||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||
adventureInt->infoBar.showSelection();
|
||||
for (IShowActivatable *isa : GH.listInt)
|
||||
for(auto isa : GH.listInt)
|
||||
{
|
||||
auto artWin = dynamic_cast<CArtifactHolder*>(isa);
|
||||
auto artWin = dynamic_cast<CArtifactHolder*>(isa.get());
|
||||
if (artWin)
|
||||
artWin->artifactRemoved(al);
|
||||
}
|
||||
@ -2541,9 +2519,9 @@ void CPlayerInterface::artifactMoved(const ArtifactLocation &src, const Artifact
|
||||
{
|
||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||
adventureInt->infoBar.showSelection();
|
||||
for (IShowActivatable *isa : GH.listInt)
|
||||
for(auto isa : GH.listInt)
|
||||
{
|
||||
auto artWin = dynamic_cast<CArtifactHolder*>(isa);
|
||||
auto artWin = dynamic_cast<CArtifactHolder*>(isa.get());
|
||||
if (artWin)
|
||||
artWin->artifactMoved(src, dst);
|
||||
}
|
||||
@ -2554,9 +2532,9 @@ void CPlayerInterface::artifactAssembled(const ArtifactLocation &al)
|
||||
{
|
||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||
adventureInt->infoBar.showSelection();
|
||||
for (IShowActivatable *isa : GH.listInt)
|
||||
for(auto isa : GH.listInt)
|
||||
{
|
||||
auto artWin = dynamic_cast<CArtifactHolder*>(isa);
|
||||
auto artWin = dynamic_cast<CArtifactHolder*>(isa.get());
|
||||
if (artWin)
|
||||
artWin->artifactAssembled(al);
|
||||
}
|
||||
@ -2566,9 +2544,9 @@ void CPlayerInterface::artifactDisassembled(const ArtifactLocation &al)
|
||||
{
|
||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||
adventureInt->infoBar.showSelection();
|
||||
for (IShowActivatable *isa : GH.listInt)
|
||||
for(auto isa : GH.listInt)
|
||||
{
|
||||
auto artWin = dynamic_cast<CArtifactHolder*>(isa);
|
||||
auto artWin = dynamic_cast<CArtifactHolder*>(isa.get());
|
||||
if (artWin)
|
||||
artWin->artifactDisassembled(al);
|
||||
}
|
||||
@ -2585,7 +2563,7 @@ void CPlayerInterface::playerStartsTurn(PlayerColor player)
|
||||
else
|
||||
{
|
||||
adventureInt->infoBar.showSelection();
|
||||
while (GH.listInt.front() != adventureInt && !dynamic_cast<CInfoWindow*>(GH.listInt.front())) //don't remove dialogs that expect query answer
|
||||
while (GH.listInt.front() != adventureInt && !dynamic_cast<CInfoWindow*>(GH.listInt.front().get())) //don't remove dialogs that expect query answer
|
||||
GH.popInts(1);
|
||||
}
|
||||
|
||||
@ -2820,7 +2798,7 @@ void CPlayerInterface::updateAmbientSounds(bool resetAll)
|
||||
CCS->soundh->ambientStopAllChannels();
|
||||
return;
|
||||
}
|
||||
else if(!dynamic_cast<CAdvMapInt *>(GH.topInt()))
|
||||
else if(!dynamic_cast<CAdvMapInt *>(GH.topInt().get()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ public:
|
||||
std::shared_ptr<CCallback> cb; //to communicate with engine
|
||||
const BattleAction *curAction; //during the battle - action currently performed by active stack (or nullptr)
|
||||
|
||||
std::list<CInfoWindow *> dialogs; //queue of dialogs awaiting to be shown (not currently shown!)
|
||||
std::list<std::shared_ptr<CInfoWindow>> dialogs; //queue of dialogs awaiting to be shown (not currently shown!)
|
||||
|
||||
std::vector<const CGHeroInstance *> wanderingHeroes; //our heroes on the adventure map (not the garrisoned ones)
|
||||
std::vector<const CGTownInstance *> towns; //our towns on the adventure map
|
||||
@ -217,7 +217,6 @@ public:
|
||||
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, const std::vector<std::shared_ptr<CComponent>> & components = std::vector<std::shared_ptr<CComponent>>());
|
||||
|
||||
void stopMovement();
|
||||
|
@ -494,12 +494,12 @@ void CServerHandler::endGameplay(bool closeConnection, bool restart)
|
||||
{
|
||||
if(CMM)
|
||||
{
|
||||
GH.curInt = CMM;
|
||||
GH.curInt = CMM.get();
|
||||
CMM->enable();
|
||||
}
|
||||
else
|
||||
{
|
||||
GH.curInt = CMainMenu::create();
|
||||
GH.curInt = CMainMenu::create().get();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -566,7 +566,7 @@ void CServerHandler::debugStartTest(std::string filename, bool save)
|
||||
else
|
||||
startLocalServerAndConnect();
|
||||
|
||||
while(!settings["session"]["headless"].Bool() && !dynamic_cast<CLobbyScreen *>(GH.topInt()))
|
||||
while(!settings["session"]["headless"].Bool() && !dynamic_cast<CLobbyScreen *>(GH.topInt().get()))
|
||||
boost::this_thread::sleep(boost::posix_time::milliseconds(50));
|
||||
while(!mi || mapInfo->fileURI != CSH->mi->fileURI)
|
||||
{
|
||||
|
@ -396,7 +396,7 @@ void CVideoPlayer::close()
|
||||
}
|
||||
|
||||
// Plays a video. Only works for overlays.
|
||||
bool CVideoPlayer::playVideo(int x, int y, SDL_Surface *dst, bool stopOnKey)
|
||||
bool CVideoPlayer::playVideo(int x, int y, bool stopOnKey)
|
||||
{
|
||||
// Note: either the windows player or the linux player is
|
||||
// broken. Compensate here until the bug is found.
|
||||
@ -407,11 +407,10 @@ bool CVideoPlayer::playVideo(int x, int y, SDL_Surface *dst, bool stopOnKey)
|
||||
|
||||
while(nextFrame())
|
||||
{
|
||||
|
||||
if(stopOnKey && keyDown())
|
||||
return false;
|
||||
|
||||
SDL_RenderCopy(mainRenderer, texture, NULL, &pos);
|
||||
SDL_RenderCopy(mainRenderer, texture, nullptr, &pos);
|
||||
SDL_RenderPresent(mainRenderer);
|
||||
|
||||
// Wait 3 frames
|
||||
@ -423,10 +422,10 @@ bool CVideoPlayer::playVideo(int x, int y, SDL_Surface *dst, bool stopOnKey)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CVideoPlayer::openAndPlayVideo(std::string name, int x, int y, SDL_Surface *dst, bool stopOnKey, bool scale)
|
||||
bool CVideoPlayer::openAndPlayVideo(std::string name, int x, int y, bool stopOnKey, bool scale)
|
||||
{
|
||||
open(name, false, true, scale);
|
||||
bool ret = playVideo(x, y, dst, stopOnKey);
|
||||
bool ret = playVideo(x, y, stopOnKey);
|
||||
close();
|
||||
return ret;
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ public:
|
||||
std::string fname; //name of current video file (empty if idle)
|
||||
|
||||
virtual void update(int x, int y, SDL_Surface *dst, bool forceRedraw, bool update = true){}
|
||||
virtual bool openAndPlayVideo(std::string name, int x, int y, SDL_Surface *dst, bool stopOnKey = false, bool scale = false)
|
||||
virtual bool openAndPlayVideo(std::string name, int x, int y, bool stopOnKey = false, bool scale = false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -111,7 +111,7 @@ class CVideoPlayer : public IMainVideoPlayer
|
||||
int refreshCount;
|
||||
bool doLoop; // loop through video
|
||||
|
||||
bool playVideo(int x, int y, SDL_Surface *dst, bool stopOnKey);
|
||||
bool playVideo(int x, int y, bool stopOnKey);
|
||||
bool open(std::string fname, bool loop, bool useOverlay = false, bool scale = false);
|
||||
|
||||
public:
|
||||
@ -128,7 +128,7 @@ public:
|
||||
void update(int x, int y, SDL_Surface *dst, bool forceRedraw, bool update = true) override; //moves to next frame if appropriate, and blits it or blits only if redraw parameter is set true
|
||||
|
||||
// Opens video, calls playVideo, closes video; returns playVideo result (if whole video has been played)
|
||||
bool openAndPlayVideo(std::string name, int x, int y, SDL_Surface *dst, bool stopOnKey = false, bool scale = false) override;
|
||||
bool openAndPlayVideo(std::string name, int x, int y, bool stopOnKey = false, bool scale = false) override;
|
||||
|
||||
//TODO:
|
||||
bool wait() override {return false;};
|
||||
|
@ -491,14 +491,11 @@ void CClient::battleStarted(const BattleInfo * info)
|
||||
|
||||
if(!settings["session"]["headless"].Bool())
|
||||
{
|
||||
Rect battleIntRect((screen->w - 800)/2, (screen->h - 600)/2, 800, 600);
|
||||
if(!!att || !!def)
|
||||
{
|
||||
boost::unique_lock<boost::recursive_mutex> un(*CPlayerInterface::pim);
|
||||
auto bi = new CBattleInterface(leftSide.armyObject, rightSide.armyObject, leftSide.hero, rightSide.hero,
|
||||
Rect((screen->w - 800)/2,
|
||||
(screen->h - 600)/2, 800, 600), att, def);
|
||||
|
||||
GH.pushInt(bi);
|
||||
GH.pushIntT<CBattleInterface>(leftSide.armyObject, rightSide.armyObject, leftSide.hero, rightSide.hero, battleIntRect, att, def);
|
||||
}
|
||||
else if(settings["session"]["spectate"].Bool() && !settings["session"]["spectate-skip-battle"].Bool())
|
||||
{
|
||||
@ -506,11 +503,7 @@ void CClient::battleStarted(const BattleInfo * info)
|
||||
auto spectratorInt = std::dynamic_pointer_cast<CPlayerInterface>(playerint[PlayerColor::SPECTATOR]);
|
||||
spectratorInt->cb->setBattle(info);
|
||||
boost::unique_lock<boost::recursive_mutex> un(*CPlayerInterface::pim);
|
||||
auto bi = new CBattleInterface(leftSide.armyObject, rightSide.armyObject, leftSide.hero, rightSide.hero,
|
||||
Rect((screen->w - 800) / 2,
|
||||
(screen->h - 600) / 2, 800, 600), att, def, spectratorInt);
|
||||
|
||||
GH.pushInt(bi);
|
||||
GH.pushIntT<CBattleInterface>(leftSide.armyObject, rightSide.armyObject, leftSide.hero, rightSide.hero, battleIntRect, att, def, spectratorInt);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ bool LobbyClientConnected::applyOnLobbyHandler(CServerHandler * handler)
|
||||
{
|
||||
handler->c->connectionID = clientId;
|
||||
if(!settings["session"]["headless"].Bool())
|
||||
GH.pushInt(new CLobbyScreen(static_cast<ESelectionScreen>(handler->screenType)));
|
||||
GH.pushIntT<CLobbyScreen>(static_cast<ESelectionScreen>(handler->screenType));
|
||||
handler->state = EClientState::LOBBY;
|
||||
return true;
|
||||
}
|
||||
@ -60,7 +60,7 @@ bool LobbyClientDisconnected::applyOnLobbyHandler(CServerHandler * handler)
|
||||
|
||||
void LobbyClientDisconnected::applyOnLobbyScreen(CLobbyScreen * lobby, CServerHandler * handler)
|
||||
{
|
||||
GH.popIntTotally(lobby);
|
||||
GH.popInts(1);
|
||||
}
|
||||
|
||||
void LobbyChatMessage::applyOnLobbyScreen(CLobbyScreen * lobby, CServerHandler * handler)
|
||||
@ -114,7 +114,7 @@ bool LobbyStartGame::applyOnLobbyHandler(CServerHandler * handler)
|
||||
|
||||
void LobbyStartGame::applyOnLobbyScreen(CLobbyScreen * lobby, CServerHandler * handler)
|
||||
{
|
||||
GH.pushInt(new CLoadingScreen(std::bind(&CServerHandler::startGameplay, handler)));
|
||||
GH.pushIntT<CLoadingScreen>(std::bind(&CServerHandler::startGameplay, handler));
|
||||
}
|
||||
|
||||
bool LobbyUpdateState::applyOnLobbyHandler(CServerHandler * handler)
|
||||
@ -128,7 +128,7 @@ void LobbyUpdateState::applyOnLobbyScreen(CLobbyScreen * lobby, CServerHandler *
|
||||
{
|
||||
if(!lobby->bonusSel && handler->si->campState && handler->state == EClientState::LOBBY_CAMPAIGN)
|
||||
{
|
||||
lobby->bonusSel = new CBonusSelection();
|
||||
lobby->bonusSel = std::make_shared<CBonusSelection>();
|
||||
GH.pushInt(lobby->bonusSel);
|
||||
}
|
||||
|
||||
|
@ -207,7 +207,7 @@ bool CDefenceAnimation::init()
|
||||
if (!rangedAttack && getMyAnimType() != CCreatureAnim::DEFENCE)
|
||||
{
|
||||
float frameLength = AnimationControls::getCreatureAnimationSpeed(
|
||||
stack->getCreature(), owner->creAnims[stack->ID], getMyAnimType());
|
||||
stack->getCreature(), owner->creAnims[stack->ID].get(), getMyAnimType());
|
||||
|
||||
timeToWait = myAnim->framesInGroup(getMyAnimType()) * frameLength / 2;
|
||||
|
||||
|
@ -39,7 +39,7 @@ public:
|
||||
class CBattleStackAnimation : public CBattleAnimation
|
||||
{
|
||||
public:
|
||||
CCreatureAnimation * myAnim; //animation for our stack, managed by CBattleInterface
|
||||
std::shared_ptr<CCreatureAnimation> myAnim; //animation for our stack, managed by CBattleInterface
|
||||
const CStack * stack; //id of stack whose animation it is
|
||||
|
||||
CBattleStackAnimation(CBattleInterface * _owner, const CStack * _stack);
|
||||
|
@ -47,7 +47,7 @@
|
||||
CondSh<bool> CBattleInterface::animsAreDisplayed(false);
|
||||
CondSh<BattleAction *> CBattleInterface::givenCommand(nullptr);
|
||||
|
||||
static void onAnimationFinished(const CStack *stack, CCreatureAnimation *anim)
|
||||
static void onAnimationFinished(const CStack *stack, std::shared_ptr<CCreatureAnimation> anim)
|
||||
{
|
||||
if (anim->isIdle())
|
||||
{
|
||||
@ -92,36 +92,37 @@ void CBattleInterface::addNewAnim(CBattleAnimation *anim)
|
||||
}
|
||||
|
||||
CBattleInterface::CBattleInterface(const CCreatureSet *army1, const CCreatureSet *army2,
|
||||
const CGHeroInstance *hero1, const CGHeroInstance *hero2,
|
||||
const SDL_Rect & myRect,
|
||||
std::shared_ptr<CPlayerInterface> att, std::shared_ptr<CPlayerInterface> defen, std::shared_ptr<CPlayerInterface> spectatorInt)
|
||||
: background(nullptr), queue(nullptr), attackingHeroInstance(hero1), defendingHeroInstance(hero2), animCount(0),
|
||||
activeStack(nullptr), mouseHoveredStack(nullptr), stackToActivate(nullptr), selectedStack(nullptr), previouslyHoveredHex(-1),
|
||||
currentlyHoveredHex(-1), attackingHex(-1), stackCanCastSpell(false), creatureCasting(false), spellDestSelectMode(false), spellToCast(nullptr), sp(nullptr),
|
||||
creatureSpellToCast(-1),
|
||||
siegeH(nullptr), attackerInt(att), defenderInt(defen), curInt(att), animIDhelper(0),
|
||||
myTurn(false), resWindow(nullptr), moveStarted(false), moveSoundHander(-1), bresult(nullptr)
|
||||
const CGHeroInstance *hero1, const CGHeroInstance *hero2,
|
||||
const SDL_Rect & myRect,
|
||||
std::shared_ptr<CPlayerInterface> att, std::shared_ptr<CPlayerInterface> defen, std::shared_ptr<CPlayerInterface> spectatorInt)
|
||||
: background(nullptr), attackingHeroInstance(hero1), defendingHeroInstance(hero2), animCount(0),
|
||||
activeStack(nullptr), mouseHoveredStack(nullptr), stackToActivate(nullptr), selectedStack(nullptr), previouslyHoveredHex(-1),
|
||||
currentlyHoveredHex(-1), attackingHex(-1), stackCanCastSpell(false), creatureCasting(false), spellDestSelectMode(false), spellToCast(nullptr), sp(nullptr),
|
||||
creatureSpellToCast(-1),
|
||||
siegeH(nullptr), attackerInt(att), defenderInt(defen), curInt(att), animIDhelper(0),
|
||||
myTurn(false), moveStarted(false), moveSoundHander(-1), bresult(nullptr)
|
||||
{
|
||||
OBJ_CONSTRUCTION;
|
||||
|
||||
if(spectatorInt)
|
||||
{
|
||||
curInt = spectatorInt;
|
||||
}
|
||||
else if(!curInt)
|
||||
{
|
||||
//May happen when we are defending during network MP game -> attacker interface is just not present
|
||||
curInt = defenderInt;
|
||||
}
|
||||
|
||||
|
||||
animsAreDisplayed.setn(false);
|
||||
pos = myRect;
|
||||
strongInterest = true;
|
||||
givenCommand.setn(nullptr);
|
||||
|
||||
//hot-seat -> check tactics for both players (defender may be local human)
|
||||
if (attackerInt && attackerInt->cb->battleGetTacticDist())
|
||||
if(attackerInt && attackerInt->cb->battleGetTacticDist())
|
||||
tacticianInterface = attackerInt;
|
||||
else if (defenderInt && defenderInt->cb->battleGetTacticDist())
|
||||
else if(defenderInt && defenderInt->cb->battleGetTacticDist())
|
||||
tacticianInterface = defenderInt;
|
||||
|
||||
//if we found interface of player with tactics, then enter tactics mode
|
||||
@ -138,7 +139,7 @@ CBattleInterface::CBattleInterface(const CCreatureSet *army1, const CCreatureSet
|
||||
else
|
||||
embedQueue = screen->h < 700 || queueSize == "small";
|
||||
|
||||
queue = new CStackQueue(embedQueue, this);
|
||||
queue = std::make_shared<CStackQueue>(embedQueue, this);
|
||||
if(!embedQueue)
|
||||
{
|
||||
if (settings["battle"]["showQueue"].Bool())
|
||||
@ -150,24 +151,24 @@ CBattleInterface::CBattleInterface(const CCreatureSet *army1, const CCreatureSet
|
||||
|
||||
//preparing siege info
|
||||
const CGTownInstance *town = curInt->cb->battleGetDefendedTown();
|
||||
if (town && town->hasFort())
|
||||
if(town && town->hasFort())
|
||||
{
|
||||
siegeH = new SiegeHelper(town, this);
|
||||
}
|
||||
|
||||
curInt->battleInt = this;
|
||||
CPlayerInterface::battleInt = this;
|
||||
|
||||
//initializing armies
|
||||
this->army1 = army1;
|
||||
this->army2 = army2;
|
||||
std::vector<const CStack*> stacks = curInt->cb->battleGetAllStacks(true);
|
||||
for (const CStack *s : stacks)
|
||||
for(const CStack * s : stacks)
|
||||
{
|
||||
unitAdded(s);
|
||||
}
|
||||
|
||||
//preparing menu background and terrain
|
||||
if (siegeH)
|
||||
if(siegeH)
|
||||
{
|
||||
background = BitmapHandler::loadBitmap( siegeH->getSiegeName(0), false );
|
||||
ui8 siegeLevel = curInt->cb->battleGetSiegeLevel();
|
||||
@ -204,9 +205,6 @@ CBattleInterface::CBattleInterface(const CCreatureSet *army1, const CCreatureSet
|
||||
}
|
||||
}
|
||||
|
||||
//preparing menu background
|
||||
//graphics->blueToPlayersAdv(menu, hero1->tempOwner);
|
||||
|
||||
//preparing graphics for displaying amounts of creatures
|
||||
amountNormal = BitmapHandler::loadBitmap("CMNUMWIN.BMP");
|
||||
CSDL_Ext::alphaTransform(amountNormal);
|
||||
@ -224,77 +222,68 @@ CBattleInterface::CBattleInterface(const CCreatureSet *army1, const CCreatureSet
|
||||
CSDL_Ext::alphaTransform(amountEffNeutral);
|
||||
transformPalette(amountEffNeutral, 1.00, 1.00, 0.18);
|
||||
|
||||
////blitting menu background and terrain
|
||||
// blitAt(background, pos.x, pos.y);
|
||||
// blitAt(menu, pos.x, 556 + pos.y);
|
||||
|
||||
//preparing buttons and console
|
||||
bOptions = new CButton (Point( 3, 561), "icm003.def", CGI->generaltexth->zelp[381], std::bind(&CBattleInterface::bOptionsf,this), SDLK_o);
|
||||
bSurrender = new CButton (Point( 54, 561), "icm001.def", CGI->generaltexth->zelp[379], std::bind(&CBattleInterface::bSurrenderf,this), SDLK_s);
|
||||
bFlee = new CButton (Point(105, 561), "icm002.def", CGI->generaltexth->zelp[380], std::bind(&CBattleInterface::bFleef,this), SDLK_r);
|
||||
bAutofight = new CButton (Point(157, 561), "icm004.def", CGI->generaltexth->zelp[382], std::bind(&CBattleInterface::bAutofightf,this), SDLK_a);
|
||||
bSpell = new CButton (Point(645, 561), "icm005.def", CGI->generaltexth->zelp[385], std::bind(&CBattleInterface::bSpellf,this), SDLK_c);
|
||||
bWait = new CButton (Point(696, 561), "icm006.def", CGI->generaltexth->zelp[386], std::bind(&CBattleInterface::bWaitf,this), SDLK_w);
|
||||
bDefence = new CButton (Point(747, 561), "icm007.def", CGI->generaltexth->zelp[387], std::bind(&CBattleInterface::bDefencef,this), SDLK_d);
|
||||
bOptions = std::make_shared<CButton>(Point( 3, 561), "icm003.def", CGI->generaltexth->zelp[381], std::bind(&CBattleInterface::bOptionsf,this), SDLK_o);
|
||||
bSurrender = std::make_shared<CButton>(Point( 54, 561), "icm001.def", CGI->generaltexth->zelp[379], std::bind(&CBattleInterface::bSurrenderf,this), SDLK_s);
|
||||
bFlee = std::make_shared<CButton>(Point(105, 561), "icm002.def", CGI->generaltexth->zelp[380], std::bind(&CBattleInterface::bFleef,this), SDLK_r);
|
||||
bAutofight = std::make_shared<CButton>(Point(157, 561), "icm004.def", CGI->generaltexth->zelp[382], std::bind(&CBattleInterface::bAutofightf,this), SDLK_a);
|
||||
bSpell = std::make_shared<CButton>(Point(645, 561), "icm005.def", CGI->generaltexth->zelp[385], std::bind(&CBattleInterface::bSpellf,this), SDLK_c);
|
||||
bWait = std::make_shared<CButton>(Point(696, 561), "icm006.def", CGI->generaltexth->zelp[386], std::bind(&CBattleInterface::bWaitf,this), SDLK_w);
|
||||
bDefence = std::make_shared<CButton>(Point(747, 561), "icm007.def", CGI->generaltexth->zelp[387], std::bind(&CBattleInterface::bDefencef,this), SDLK_d);
|
||||
bDefence->assignedKeys.insert(SDLK_SPACE);
|
||||
bConsoleUp = new CButton (Point(624, 561), "ComSlide.def", std::make_pair("", ""), std::bind(&CBattleInterface::bConsoleUpf,this), SDLK_UP);
|
||||
bConsoleDown = new CButton (Point(624, 580), "ComSlide.def", std::make_pair("", ""), std::bind(&CBattleInterface::bConsoleDownf,this), SDLK_DOWN);
|
||||
bConsoleUp = std::make_shared<CButton>(Point(624, 561), "ComSlide.def", std::make_pair("", ""), std::bind(&CBattleInterface::bConsoleUpf,this), SDLK_UP);
|
||||
bConsoleDown = std::make_shared<CButton>(Point(624, 580), "ComSlide.def", std::make_pair("", ""), std::bind(&CBattleInterface::bConsoleDownf,this), SDLK_DOWN);
|
||||
bConsoleDown->setImageOrder(2, 3, 4, 5);
|
||||
console = new CBattleConsole();
|
||||
|
||||
console = std::make_shared<CBattleConsole>();
|
||||
console->pos.x += 211;
|
||||
console->pos.y += 560;
|
||||
console->pos.w = 406;
|
||||
console->pos.h = 38;
|
||||
if (tacticsMode)
|
||||
if(tacticsMode)
|
||||
{
|
||||
btactNext = new CButton(Point(213, 560), "icm011.def", std::make_pair("", ""), [&](){ bTacticNextStack(nullptr);}, SDLK_SPACE);
|
||||
btactEnd = new CButton(Point(419, 560), "icm012.def", std::make_pair("", ""), [&](){ bEndTacticPhase();}, SDLK_RETURN);
|
||||
btactNext = std::make_shared<CButton>(Point(213, 560), "icm011.def", std::make_pair("", ""), [&](){ bTacticNextStack(nullptr);}, SDLK_SPACE);
|
||||
btactEnd = std::make_shared<CButton>(Point(419, 560), "icm012.def", std::make_pair("", ""), [&](){ bEndTacticPhase();}, SDLK_RETURN);
|
||||
menu = BitmapHandler::loadBitmap("COPLACBR.BMP");
|
||||
}
|
||||
else
|
||||
{
|
||||
menu = BitmapHandler::loadBitmap("CBAR.BMP");
|
||||
btactEnd = btactNext = nullptr;
|
||||
}
|
||||
graphics->blueToPlayersAdv(menu, curInt->playerID);
|
||||
|
||||
//loading hero animations
|
||||
if (hero1) // attacking hero
|
||||
if(hero1) // attacking hero
|
||||
{
|
||||
std::string battleImage;
|
||||
if ( hero1->sex )
|
||||
if(hero1->sex)
|
||||
battleImage = hero1->type->heroClass->imageBattleFemale;
|
||||
else
|
||||
battleImage = hero1->type->heroClass->imageBattleMale;
|
||||
|
||||
attackingHero = new CBattleHero(battleImage, false, hero1->tempOwner, hero1->tempOwner == curInt->playerID ? hero1 : nullptr, this);
|
||||
attackingHero = std::make_shared<CBattleHero>(battleImage, false, hero1->tempOwner, hero1->tempOwner == curInt->playerID ? hero1 : nullptr, this);
|
||||
|
||||
auto img = attackingHero->animation->getImage(0, 0, true);
|
||||
if(img)
|
||||
attackingHero->pos = genRect(img->height(), img->width(), pos.x - 43, pos.y - 19);
|
||||
}
|
||||
else
|
||||
{
|
||||
attackingHero = nullptr;
|
||||
}
|
||||
if (hero2) // defending hero
|
||||
|
||||
|
||||
if(hero2) // defending hero
|
||||
{
|
||||
std::string battleImage;
|
||||
if ( hero2->sex )
|
||||
if(hero2->sex)
|
||||
battleImage = hero2->type->heroClass->imageBattleFemale;
|
||||
else
|
||||
battleImage = hero2->type->heroClass->imageBattleMale;
|
||||
|
||||
defendingHero = new CBattleHero(battleImage, true, hero2->tempOwner, hero2->tempOwner == curInt->playerID ? hero2 : nullptr, this);
|
||||
defendingHero = std::make_shared<CBattleHero>(battleImage, true, hero2->tempOwner, hero2->tempOwner == curInt->playerID ? hero2 : nullptr, this);
|
||||
|
||||
auto img = defendingHero->animation->getImage(0, 0, true);
|
||||
if(img)
|
||||
defendingHero->pos = genRect(img->height(), img->width(), pos.x + 693, pos.y - 19);
|
||||
}
|
||||
else
|
||||
{
|
||||
defendingHero = nullptr;
|
||||
}
|
||||
|
||||
|
||||
//preparing cells and hexes
|
||||
cellBorder = BitmapHandler::loadBitmap("CCELLGRD.BMP");
|
||||
@ -303,7 +292,7 @@ CBattleInterface::CBattleInterface(const CCreatureSet *army1, const CCreatureSet
|
||||
CSDL_Ext::alphaTransform(cellShade);
|
||||
for (int h = 0; h < GameConstants::BFIELD_SIZE; ++h)
|
||||
{
|
||||
auto hex = new CClickableHex();
|
||||
auto hex = std::make_shared<CClickableHex>();
|
||||
hex->myNumber = h;
|
||||
hex->pos = hexPosition(h);
|
||||
hex->accessible = true;
|
||||
@ -385,8 +374,8 @@ CBattleInterface::CBattleInterface(const CCreatureSet *army1, const CCreatureSet
|
||||
}
|
||||
}
|
||||
|
||||
for (auto hex : bfield)
|
||||
addChild(hex);
|
||||
for(auto hex : bfield)
|
||||
addChild(hex.get());
|
||||
|
||||
if (tacticsMode)
|
||||
bTacticNextStack();
|
||||
@ -412,7 +401,7 @@ CBattleInterface::CBattleInterface(const CCreatureSet *army1, const CCreatureSet
|
||||
|
||||
CBattleInterface::~CBattleInterface()
|
||||
{
|
||||
curInt->battleInt = nullptr;
|
||||
CPlayerInterface::battleInt = nullptr;
|
||||
givenCommand.cond.notify_all(); //that two lines should make any activeStack waiting thread to finish
|
||||
|
||||
if (active) //dirty fix for #485
|
||||
@ -427,31 +416,11 @@ CBattleInterface::~CBattleInterface()
|
||||
SDL_FreeSurface(amountEffNeutral);
|
||||
SDL_FreeSurface(cellBorders);
|
||||
SDL_FreeSurface(backgroundWithHexes);
|
||||
delete bOptions;
|
||||
delete bSurrender;
|
||||
delete bFlee;
|
||||
delete bAutofight;
|
||||
delete bSpell;
|
||||
delete bWait;
|
||||
delete bDefence;
|
||||
|
||||
for (auto hex : bfield)
|
||||
delete hex;
|
||||
|
||||
delete bConsoleUp;
|
||||
delete bConsoleDown;
|
||||
delete console;
|
||||
|
||||
delete attackingHero;
|
||||
delete defendingHero;
|
||||
delete queue;
|
||||
|
||||
SDL_FreeSurface(cellBorder);
|
||||
SDL_FreeSurface(cellShade);
|
||||
|
||||
for (auto & elem : creAnims)
|
||||
delete elem.second;
|
||||
|
||||
delete siegeH;
|
||||
|
||||
//TODO: play AI tracks if battle was during AI turn
|
||||
@ -588,7 +557,7 @@ void CBattleInterface::keyPressed(const SDL_KeyboardEvent & key)
|
||||
}
|
||||
void CBattleInterface::mouseMoved(const SDL_MouseMotionEvent &sEvent)
|
||||
{
|
||||
auto hexItr = std::find_if (bfield.begin(), bfield.end(), [](const CClickableHex *hex)
|
||||
auto hexItr = std::find_if(bfield.begin(), bfield.end(), [](std::shared_ptr<CClickableHex> hex)
|
||||
{
|
||||
return hex->hovered && hex->strictHovered;
|
||||
});
|
||||
@ -786,8 +755,7 @@ void CBattleInterface::bOptionsf()
|
||||
|
||||
Rect tempRect = genRect(431, 481, 160, 84);
|
||||
tempRect += pos.topLeft();
|
||||
auto optionsWin = new CBattleOptionsWindow(tempRect, this);
|
||||
GH.pushInt(optionsWin);
|
||||
GH.pushIntT<CBattleOptionsWindow>(tempRect, this);
|
||||
}
|
||||
|
||||
void CBattleInterface::bSurrenderf()
|
||||
@ -900,7 +868,7 @@ void CBattleInterface::bSpellf()
|
||||
|
||||
if(spellCastProblem == ESpellCastProblem::OK)
|
||||
{
|
||||
GH.pushInt(new CSpellWindow(myHero, curInt.get()));
|
||||
GH.pushIntT<CSpellWindow>(myHero, curInt.get());
|
||||
}
|
||||
else if (spellCastProblem == ESpellCastProblem::MAGIC_IS_BLOCKED)
|
||||
{
|
||||
@ -1276,13 +1244,13 @@ void CBattleInterface::displayBattleFinished()
|
||||
CCS->curh->changeGraphic(ECursor::ADVENTURE,0);
|
||||
if(settings["session"]["spectate"].Bool() && settings["session"]["spectate-skip-battle-result"].Bool())
|
||||
{
|
||||
GH.popIntTotally(this);
|
||||
close();
|
||||
return;
|
||||
}
|
||||
|
||||
resWindow = new CBattleResultWindow(*bresult, *this->curInt);
|
||||
GH.pushInt(resWindow);
|
||||
GH.pushInt(std::make_shared<CBattleResultWindow>(*bresult, *(this->curInt)));
|
||||
curInt->waitWhileDialog(); // Avoid freeze when AI end turn after battle. Check bug #1897
|
||||
CPlayerInterface::battleInt = nullptr;
|
||||
}
|
||||
|
||||
void CBattleInterface::spellCast(const BattleSpellCast * sc)
|
||||
@ -1436,7 +1404,7 @@ void CBattleInterface::setHeroAnimation(ui8 side, int phase)
|
||||
|
||||
void CBattleInterface::castThisSpell(SpellID spellID)
|
||||
{
|
||||
spellToCast = new BattleAction();
|
||||
spellToCast = std::make_shared<BattleAction>();
|
||||
spellToCast->actionType = EActionType::HERO_SPELL;
|
||||
spellToCast->actionSubtype = spellID; //spell number
|
||||
spellToCast->stackNumber = (attackingHeroInstance->tempOwner == curInt->playerID) ? -1 : -2;
|
||||
@ -1453,7 +1421,7 @@ void CBattleInterface::castThisSpell(SpellID spellID)
|
||||
if (spellSelMode == NO_LOCATION) //user does not have to select location
|
||||
{
|
||||
spellToCast->aimToHex(BattleHex::INVALID);
|
||||
curInt->cb->battleMakeAction(spellToCast);
|
||||
curInt->cb->battleMakeAction(spellToCast.get());
|
||||
endCastingSpell();
|
||||
}
|
||||
else
|
||||
@ -1680,15 +1648,15 @@ void CBattleInterface::activateStack()
|
||||
|
||||
void CBattleInterface::endCastingSpell()
|
||||
{
|
||||
if (spellDestSelectMode)
|
||||
if(spellDestSelectMode)
|
||||
{
|
||||
vstd::clear_pointer(spellToCast);
|
||||
spellToCast.reset();
|
||||
|
||||
sp = nullptr;
|
||||
spellDestSelectMode = false;
|
||||
CCS->curh->changeGraphic(ECursor::COMBAT, ECursor::COMBAT_POINTER);
|
||||
|
||||
if (activeStack)
|
||||
if(activeStack)
|
||||
{
|
||||
getPossibleActionsForStack(activeStack, false); //restore actions after they were cleared
|
||||
myTurn = true;
|
||||
@ -1696,7 +1664,7 @@ void CBattleInterface::endCastingSpell()
|
||||
}
|
||||
else
|
||||
{
|
||||
if (activeStack)
|
||||
if(activeStack)
|
||||
{
|
||||
getPossibleActionsForStack(activeStack, false);
|
||||
GH.fakeMouseMove();
|
||||
@ -2419,7 +2387,7 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
|
||||
{
|
||||
cursorFrame = ECursor::COMBAT_QUERY;
|
||||
consoleMsg = (boost::format(CGI->generaltexth->allTexts[297]) % shere->getName()).str();
|
||||
realizeAction = [=](){ GH.pushInt(new CStackWindow(shere, false)); };
|
||||
realizeAction = [=](){ GH.pushIntT<CStackWindow>(shere, false); };
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2511,7 +2479,7 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
|
||||
spellToCast->aimToHex(myNumber);
|
||||
break;
|
||||
}
|
||||
curInt->cb->battleMakeAction(spellToCast);
|
||||
curInt->cb->battleMakeAction(spellToCast.get());
|
||||
endCastingSpell();
|
||||
}
|
||||
selectedStack = nullptr;
|
||||
|
@ -106,7 +106,7 @@ struct CatapultProjectileInfo
|
||||
|
||||
/// Big class which handles the overall battle interface actions and it is also responsible for
|
||||
/// drawing everything correctly.
|
||||
class CBattleInterface : public CIntObject
|
||||
class CBattleInterface : public WindowBase
|
||||
{
|
||||
enum PossibleActions // actions performed at l-click
|
||||
{
|
||||
@ -121,14 +121,26 @@ class CBattleInterface : public CIntObject
|
||||
private:
|
||||
SDL_Surface *background, *menu, *amountNormal, *amountNegative, *amountPositive, *amountEffNeutral, *cellBorders, *backgroundWithHexes;
|
||||
|
||||
CButton *bOptions, *bSurrender, *bFlee, *bAutofight, *bSpell,
|
||||
* bWait, *bDefence, *bConsoleUp, *bConsoleDown, *btactNext, *btactEnd;
|
||||
CBattleConsole *console;
|
||||
CBattleHero *attackingHero, *defendingHero; //fighting heroes
|
||||
CStackQueue *queue;
|
||||
std::shared_ptr<CButton> bOptions;
|
||||
std::shared_ptr<CButton> bSurrender;
|
||||
std::shared_ptr<CButton> bFlee;
|
||||
std::shared_ptr<CButton> bAutofight;
|
||||
std::shared_ptr<CButton> bSpell;
|
||||
std::shared_ptr<CButton> bWait;
|
||||
std::shared_ptr<CButton> bDefence;
|
||||
std::shared_ptr<CButton> bConsoleUp;
|
||||
std::shared_ptr<CButton> bConsoleDown;
|
||||
std::shared_ptr<CButton> btactNext;
|
||||
std::shared_ptr<CButton> btactEnd;
|
||||
|
||||
std::shared_ptr<CBattleConsole> console;
|
||||
std::shared_ptr<CBattleHero> attackingHero;
|
||||
std::shared_ptr<CBattleHero> defendingHero;
|
||||
std::shared_ptr<CStackQueue> queue;
|
||||
|
||||
const CCreatureSet *army1, *army2; //copy of initial armies (for result window)
|
||||
const CGHeroInstance *attackingHeroInstance, *defendingHeroInstance;
|
||||
std::map<int, CCreatureAnimation *> creAnims; //animations of creatures from fighting armies (order by BattleInfo's stacks' ID)
|
||||
std::map<int32_t, std::shared_ptr<CCreatureAnimation>> creAnims; //animations of creatures from fighting armies (order by BattleInfo's stacks' ID)
|
||||
|
||||
std::map<int, std::shared_ptr<CAnimation>> idToProjectile;
|
||||
|
||||
@ -154,7 +166,7 @@ private:
|
||||
bool stackCanCastSpell; //if true, active stack could possibly cast some target spell
|
||||
bool creatureCasting; //if true, stack currently aims to cats a spell
|
||||
bool spellDestSelectMode; //if true, player is choosing destination for his spell - only for GUI / console
|
||||
BattleAction *spellToCast; //spell for which player is choosing destination
|
||||
std::shared_ptr<BattleAction> spellToCast; //spell for which player is choosing destination
|
||||
const CSpell *sp; //spell pointer for convenience
|
||||
si32 creatureSpellToCast;
|
||||
std::vector<PossibleActions> possibleActions; //all actions possible to call at the moment by player
|
||||
@ -284,11 +296,10 @@ public:
|
||||
int getAnimSpeed() const; //speed of animation; range 1..100
|
||||
CPlayerInterface *getCurrentPlayerInterface() const;
|
||||
|
||||
std::vector<CClickableHex*> bfield; //11 lines, 17 hexes on each
|
||||
std::vector<std::shared_ptr<CClickableHex>> bfield; //11 lines, 17 hexes on each
|
||||
SDL_Surface *cellBorder, *cellShade;
|
||||
|
||||
bool myTurn; //if true, interface is active (commands can be ordered)
|
||||
CBattleResultWindow *resWindow; //window of end of battle
|
||||
|
||||
bool moveStarted; //if true, the creature that is already moving is going to make its first step
|
||||
int moveSoundHander; // sound handler used when moving a unit
|
||||
|
@ -212,7 +212,7 @@ void CBattleHero::clickLeft(tribool down, bool previousState)
|
||||
}
|
||||
CCS->curh->changeGraphic(ECursor::ADVENTURE, 0);
|
||||
|
||||
GH.pushInt(new CSpellWindow(myHero, myOwner->getCurrentPlayerInterface()));
|
||||
GH.pushIntT<CSpellWindow>(myHero, myOwner->getCurrentPlayerInterface());
|
||||
}
|
||||
}
|
||||
|
||||
@ -230,7 +230,7 @@ void CBattleHero::clickRight(tribool down, bool previousState)
|
||||
{
|
||||
auto h = flip ? myOwner->defendingHeroInstance : myOwner->attackingHeroInstance;
|
||||
targetHero.initFromHero(h, InfoAboutHero::EInfoLevel::INBATTLE);
|
||||
GH.pushInt(new CHeroInfoWindow(targetHero, &windowPosition));
|
||||
GH.pushIntT<CHeroInfoWindow>(targetHero, &windowPosition);
|
||||
}
|
||||
}
|
||||
|
||||
@ -391,7 +391,7 @@ void CBattleOptionsWindow::bDefaultf()
|
||||
|
||||
void CBattleOptionsWindow::bExitf()
|
||||
{
|
||||
GH.popIntTotally(this);
|
||||
close();
|
||||
}
|
||||
|
||||
CBattleResultWindow::CBattleResultWindow(const BattleResult & br, CPlayerInterface & _owner)
|
||||
@ -560,8 +560,10 @@ void CBattleResultWindow::show(SDL_Surface * to)
|
||||
void CBattleResultWindow::bExitf()
|
||||
{
|
||||
CPlayerInterface &intTmp = owner; //copy reference because "this" will be destructed soon
|
||||
GH.popIntTotally(this);
|
||||
if(dynamic_cast<CBattleInterface*>(GH.topInt()))
|
||||
|
||||
close();
|
||||
|
||||
if(dynamic_cast<CBattleInterface*>(GH.topInt().get()))
|
||||
GH.popInts(1); //pop battle interface if present
|
||||
|
||||
//Result window and battle interface are gone. We requested all dialogs to be closed before opening the battle,
|
||||
@ -689,11 +691,10 @@ void CClickableHex::clickRight(tribool down, bool previousState)
|
||||
const CStack * myst = myInterface->getCurrentPlayerInterface()->cb->battleGetStackByPos(myNumber); //stack info
|
||||
if(hovered && strictHovered && myst!=nullptr)
|
||||
{
|
||||
|
||||
if(!myst->alive()) return;
|
||||
if(down)
|
||||
{
|
||||
GH.pushInt(new CStackWindow(myst, true));
|
||||
GH.pushIntT<CStackWindow>(myst, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ public:
|
||||
};
|
||||
|
||||
/// Class which manages the battle options window
|
||||
class CBattleOptionsWindow : public CIntObject
|
||||
class CBattleOptionsWindow : public WindowBase
|
||||
{
|
||||
private:
|
||||
std::shared_ptr<CPicture> background;
|
||||
@ -106,7 +106,7 @@ public:
|
||||
};
|
||||
|
||||
/// Class which is responsible for showing the battle result window
|
||||
class CBattleResultWindow : public CIntObject
|
||||
class CBattleResultWindow : public WindowBase
|
||||
{
|
||||
private:
|
||||
std::shared_ptr<CPicture> background;
|
||||
|
@ -34,10 +34,10 @@ SDL_Color AnimationControls::getNoBorder()
|
||||
return creatureNoBorder;
|
||||
}
|
||||
|
||||
CCreatureAnimation * AnimationControls::getAnimation(const CCreature * creature)
|
||||
std::shared_ptr<CCreatureAnimation> AnimationControls::getAnimation(const CCreature * creature)
|
||||
{
|
||||
auto func = std::bind(&AnimationControls::getCreatureAnimationSpeed, creature, _1, _2);
|
||||
return new CCreatureAnimation(creature->animDefName, func);
|
||||
return std::make_shared<CCreatureAnimation>(creature->animDefName, func);
|
||||
}
|
||||
|
||||
float AnimationControls::getCreatureAnimationSpeed(const CCreature * creature, const CCreatureAnimation * anim, size_t group)
|
||||
|
@ -25,7 +25,7 @@ namespace AnimationControls
|
||||
SDL_Color getNoBorder();
|
||||
|
||||
/// creates animation object with preset speed control
|
||||
CCreatureAnimation * getAnimation(const CCreature * creature);
|
||||
std::shared_ptr<CCreatureAnimation> getAnimation(const CCreature * creature);
|
||||
|
||||
/// returns animation speed of specific group, taking in mind game setting (in frames per second)
|
||||
float getCreatureAnimationSpeed(const CCreature * creature, const CCreatureAnimation * anim, size_t groupID);
|
||||
|
@ -23,7 +23,6 @@
|
||||
#include "../lib/CRandomGenerator.h"
|
||||
|
||||
class SDLImageLoader;
|
||||
class CompImageLoader;
|
||||
|
||||
typedef std::map <size_t, std::vector <JsonNode> > source_map;
|
||||
typedef std::map<size_t, IImage* > image_map;
|
||||
@ -79,9 +78,9 @@ public:
|
||||
|
||||
public:
|
||||
//Load image from def file
|
||||
SDLImage(CDefFile *data, size_t frame, size_t group=0, bool compressed=false);
|
||||
SDLImage(CDefFile *data, size_t frame, size_t group=0);
|
||||
//Load from bitmap file
|
||||
SDLImage(std::string filename, bool compressed=false);
|
||||
SDLImage(std::string filename);
|
||||
|
||||
SDLImage(const JsonNode & conf);
|
||||
//Create using existing surface, extraRef will increase refcount on SDL_Surface
|
||||
@ -107,65 +106,6 @@ public:
|
||||
friend class SDLImageLoader;
|
||||
};
|
||||
|
||||
/*
|
||||
* RLE-compressed image data for 8-bit images with alpha-channel, currently far from finished
|
||||
* primary purpose is not high compression ratio but fast drawing.
|
||||
* Consist of repeatable segments with format similar to H3 def compression:
|
||||
* 1st byte:
|
||||
* if (byte == 0xff)
|
||||
* raw data, opaque and semi-transparent data always in separate blocks
|
||||
* else
|
||||
* RLE-compressed image data with this color
|
||||
* 2nd byte = size of segment
|
||||
* raw data (if any)
|
||||
*/
|
||||
class CompImage : public IImage
|
||||
{
|
||||
//x,y - margins, w,h - sprite size
|
||||
Rect sprite;
|
||||
//total size including borders
|
||||
Point fullSize;
|
||||
|
||||
//RLE-d data
|
||||
ui8 * surf;
|
||||
//array of offsets for each line
|
||||
ui32 * line;
|
||||
//palette
|
||||
SDL_Color *palette;
|
||||
|
||||
//Used internally to blit one block of data
|
||||
template<int bpp, int dir>
|
||||
void BlitBlock(ui8 type, ui8 size, ui8 *&data, ui8 *&dest, ui8 alpha) const;
|
||||
void BlitBlockWithBpp(ui8 bpp, ui8 type, ui8 size, ui8 *&data, ui8 *&dest, ui8 alpha, bool rotated) const;
|
||||
|
||||
public:
|
||||
//Load image from def file
|
||||
CompImage(const CDefFile *data, size_t frame, size_t group=0);
|
||||
//TODO: load image from SDL_Surface
|
||||
CompImage(SDL_Surface * surf);
|
||||
~CompImage();
|
||||
|
||||
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::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;
|
||||
int width() const override;
|
||||
int height() const override;
|
||||
|
||||
void horizontalFlip() override;
|
||||
void verticalFlip() override;
|
||||
|
||||
void shiftPalette(int from, int howMany) override;
|
||||
void setBorderPallete(const BorderPallete & borderPallete) override;
|
||||
|
||||
friend class CompImageLoader;
|
||||
};
|
||||
|
||||
class SDLImageLoader
|
||||
{
|
||||
SDLImage * image;
|
||||
@ -184,30 +124,6 @@ public:
|
||||
~SDLImageLoader();
|
||||
};
|
||||
|
||||
class CompImageLoader
|
||||
{
|
||||
CompImage * image;
|
||||
ui8 *position;
|
||||
ui8 *entry;
|
||||
ui32 currentLine;
|
||||
|
||||
inline ui8 typeOf(ui8 color);
|
||||
inline void NewEntry(ui8 color, size_t size);
|
||||
inline void NewEntry(const ui8 * &data, size_t size);
|
||||
|
||||
public:
|
||||
//load size raw pixels from data
|
||||
inline void Load(size_t size, const ui8 * data);
|
||||
//set size pixels to color
|
||||
inline void Load(size_t size, ui8 color=0);
|
||||
inline void EndLine();
|
||||
//init image with these sizes and palette
|
||||
inline void init(Point SpriteSize, Point Margins, Point FullSize, SDL_Color *pal);
|
||||
|
||||
CompImageLoader(CompImage * Img);
|
||||
~CompImageLoader();
|
||||
};
|
||||
|
||||
// Extremely simple file cache. TODO: smarter, more general solution
|
||||
class CFileCache
|
||||
{
|
||||
@ -576,7 +492,7 @@ SDLImageLoader::SDLImageLoader(SDLImage * Img):
|
||||
void SDLImageLoader::init(Point SpriteSize, Point Margins, Point FullSize, SDL_Color *pal)
|
||||
{
|
||||
//Init image
|
||||
image->surf = SDL_CreateRGBSurface(SDL_SWSURFACE, SpriteSize.x, SpriteSize.y, 8, 0, 0, 0, 0);
|
||||
image->surf = SDL_CreateRGBSurface(0, SpriteSize.x, SpriteSize.y, 8, 0, 0, 0, 0);
|
||||
image->margins = Margins;
|
||||
image->fullSize = FullSize;
|
||||
|
||||
@ -621,182 +537,6 @@ SDLImageLoader::~SDLImageLoader()
|
||||
//TODO: RLE if compressed and bpp>1
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CompImageLoader::CompImageLoader(CompImage * Img):
|
||||
image(Img),
|
||||
position(nullptr),
|
||||
entry(nullptr),
|
||||
currentLine(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CompImageLoader::init(Point SpriteSize, Point Margins, Point FullSize, SDL_Color *pal)
|
||||
{
|
||||
image->sprite = Rect(Margins, SpriteSize);
|
||||
image->fullSize = FullSize;
|
||||
if (SpriteSize.x && SpriteSize.y)
|
||||
{
|
||||
image->palette = new SDL_Color[256];
|
||||
memcpy((void*)image->palette, (void*)pal, 256*sizeof(SDL_Color));
|
||||
//Allocate enought space for worst possible case, c-style malloc used due to resizing after load
|
||||
image->surf = (ui8*)malloc(SpriteSize.x*SpriteSize.y*3);
|
||||
image->line = new ui32[SpriteSize.y+1];
|
||||
image->line[0] = 0;
|
||||
position = image->surf;
|
||||
}
|
||||
}
|
||||
|
||||
inline void CompImageLoader::NewEntry(ui8 color, size_t size)
|
||||
{
|
||||
assert(color != 0xff);
|
||||
assert(size && size<256);
|
||||
entry = position;
|
||||
entry[0] = color;
|
||||
entry[1] = size;
|
||||
position +=2;
|
||||
}
|
||||
|
||||
inline void CompImageLoader::NewEntry(const ui8 * &data, size_t size)
|
||||
{
|
||||
assert(size && size<256);
|
||||
entry = position;
|
||||
entry[0] = 0xff;
|
||||
entry[1] = size;
|
||||
position +=2;
|
||||
memcpy(position, data, size);
|
||||
position+=size;
|
||||
data+=size;
|
||||
}
|
||||
|
||||
inline ui8 CompImageLoader::typeOf(ui8 color)
|
||||
{
|
||||
if (color == 0)
|
||||
return 0;
|
||||
|
||||
if (image->palette[color].a != 255)
|
||||
return 1;
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
inline void CompImageLoader::Load(size_t size, const ui8 * data)
|
||||
{
|
||||
while (size)
|
||||
{
|
||||
//Try to compress data
|
||||
while(true)
|
||||
{
|
||||
ui8 color = data[0];
|
||||
if (color != 0xff)
|
||||
{
|
||||
size_t runLength = 1;
|
||||
while (runLength < size && color == data[runLength])
|
||||
runLength++;
|
||||
|
||||
if (runLength > 1 && runLength < 255)//Row of one color found - use RLE
|
||||
{
|
||||
Load(runLength, color);
|
||||
data += runLength;
|
||||
size -= runLength;
|
||||
if (!size)
|
||||
return;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
//Select length for new raw entry
|
||||
size_t runLength = 1;
|
||||
ui8 color = data[0];
|
||||
ui8 type = typeOf(color);
|
||||
ui8 color2;
|
||||
ui8 type2;
|
||||
|
||||
if (size > 1)
|
||||
{
|
||||
do
|
||||
{
|
||||
color2 = data[runLength];
|
||||
type2 = typeOf(color2);
|
||||
runLength++;
|
||||
}
|
||||
//While we have data of this type and different colors
|
||||
while ((runLength < size) && (type == type2) && ( (color2 != 0xff) || (color2 != color)));
|
||||
}
|
||||
size -= runLength;
|
||||
|
||||
//add data to last entry
|
||||
if (entry && entry[0] == 0xff && type == typeOf(entry[2]))
|
||||
{
|
||||
size_t toCopy = std::min<size_t>(runLength, 255 - entry[1]);
|
||||
runLength -= toCopy;
|
||||
entry[1] += toCopy;
|
||||
memcpy(position, data, toCopy);
|
||||
data+=toCopy;
|
||||
position+=toCopy;
|
||||
}
|
||||
//Create new entries
|
||||
while (runLength > 255)
|
||||
{
|
||||
NewEntry(data, 255);
|
||||
runLength -= 255;
|
||||
}
|
||||
if (runLength)
|
||||
NewEntry(data, runLength);
|
||||
}
|
||||
}
|
||||
|
||||
inline void CompImageLoader::Load(size_t size, ui8 color)
|
||||
{
|
||||
if (!size)
|
||||
return;
|
||||
if (color==0xff)
|
||||
{
|
||||
auto tmpbuf = new ui8[size];
|
||||
memset((void*)tmpbuf, color, size);
|
||||
Load(size, tmpbuf);
|
||||
delete [] tmpbuf;
|
||||
return;
|
||||
}
|
||||
//Current entry is RLE with same color as new block
|
||||
if (entry && entry[0] == color)
|
||||
{
|
||||
size_t toCopy = std::min<size_t>(size, 255 - entry[1]);
|
||||
size -= toCopy;
|
||||
entry[1] += toCopy;
|
||||
}
|
||||
//Create new entries
|
||||
while (size > 255)
|
||||
{
|
||||
NewEntry(color, 255);
|
||||
size -= 255;
|
||||
}
|
||||
if (size)
|
||||
NewEntry(color, size);
|
||||
}
|
||||
|
||||
void CompImageLoader::EndLine()
|
||||
{
|
||||
currentLine++;
|
||||
image->line[currentLine] = position - image->surf;
|
||||
entry = nullptr;
|
||||
|
||||
}
|
||||
|
||||
CompImageLoader::~CompImageLoader()
|
||||
{
|
||||
if (!image->surf)
|
||||
return;
|
||||
|
||||
ui8* newPtr = (ui8*)realloc((void*)image->surf, position - image->surf);
|
||||
if (newPtr)
|
||||
image->surf = newPtr;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* Classes for images, support loading from file and drawing on surface *
|
||||
*************************************************************************/
|
||||
@ -805,7 +545,7 @@ IImage::IImage() = default;
|
||||
IImage::~IImage() = default;
|
||||
|
||||
|
||||
SDLImage::SDLImage(CDefFile * data, size_t frame, size_t group, bool compressed)
|
||||
SDLImage::SDLImage(CDefFile * data, size_t frame, size_t group)
|
||||
: surf(nullptr),
|
||||
margins(0, 0),
|
||||
fullSize(0, 0)
|
||||
@ -857,15 +597,14 @@ SDLImage::SDLImage(const JsonNode & conf)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SDLImage::SDLImage(std::string filename, bool compressed)
|
||||
SDLImage::SDLImage(std::string filename)
|
||||
: surf(nullptr),
|
||||
margins(0, 0),
|
||||
fullSize(0, 0)
|
||||
{
|
||||
surf = BitmapHandler::loadBitmap(filename);
|
||||
|
||||
if (surf == nullptr)
|
||||
if(surf == nullptr)
|
||||
{
|
||||
logGlobal->error("Error: failed to load image %s", filename);
|
||||
return;
|
||||
@ -875,23 +614,8 @@ SDLImage::SDLImage(std::string filename, bool compressed)
|
||||
fullSize.x = surf->w;
|
||||
fullSize.y = surf->h;
|
||||
}
|
||||
if (compressed)
|
||||
{
|
||||
SDL_Surface *temp = surf;
|
||||
// add RLE flag
|
||||
if (surf->format->palette)
|
||||
{
|
||||
CSDL_Ext::setColorKey(temp,temp->format->palette->colors[0]);
|
||||
}
|
||||
SDL_SetSurfaceRLE(temp, SDL_RLEACCEL);
|
||||
|
||||
// convert surface to enable RLE
|
||||
surf = SDL_ConvertSurface(temp, temp->format, temp->flags);
|
||||
SDL_FreeSurface(temp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SDLImage::draw(SDL_Surface *where, int posX, int posY, Rect *src, ui8 alpha) const
|
||||
{
|
||||
if(!surf)
|
||||
@ -1042,282 +766,6 @@ SDLImage::~SDLImage()
|
||||
SDL_FreeSurface(surf);
|
||||
}
|
||||
|
||||
CompImage::CompImage(const CDefFile *data, size_t frame, size_t group):
|
||||
surf(nullptr),
|
||||
line(nullptr),
|
||||
palette(nullptr)
|
||||
|
||||
{
|
||||
CompImageLoader loader(this);
|
||||
data->loadFrame(frame, group, loader);
|
||||
}
|
||||
|
||||
CompImage::CompImage(SDL_Surface * surf)
|
||||
{
|
||||
//TODO
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void CompImage::draw(SDL_Surface *where, int posX, int posY, Rect *src, ui8 alpha) const
|
||||
{
|
||||
Rect dest(posX,posY, width(), height());
|
||||
draw(where, &dest, src, alpha);
|
||||
}
|
||||
|
||||
void CompImage::draw(SDL_Surface* where, SDL_Rect* dest, SDL_Rect* src, ui8 alpha) const
|
||||
{
|
||||
int rotation = 0; //TODO
|
||||
//rotation & 2 = horizontal rotation
|
||||
//rotation & 4 = vertical rotation
|
||||
if (!surf)
|
||||
return;
|
||||
Rect sourceRect(sprite);
|
||||
//TODO: rotation and scaling
|
||||
if (src)
|
||||
sourceRect = sourceRect & *src;
|
||||
//Limit source rect to sizes of surface
|
||||
sourceRect = sourceRect & Rect(0, 0, where->w, where->h);
|
||||
|
||||
//Starting point on SDL surface
|
||||
Point dst(sourceRect.x,sourceRect.y);
|
||||
|
||||
if (dest)
|
||||
{
|
||||
dst.x += dest->x;
|
||||
dst.y += dest->y;
|
||||
}
|
||||
|
||||
if (rotation & 2)
|
||||
dst.y += sourceRect.h;
|
||||
if (rotation & 4)
|
||||
dst.x += sourceRect.w;
|
||||
|
||||
sourceRect -= sprite.topLeft();
|
||||
|
||||
for (int currY = 0; currY <sourceRect.h; currY++)
|
||||
{
|
||||
ui8* data = surf + line[currY+sourceRect.y];
|
||||
ui8 type = *(data++);
|
||||
ui8 size = *(data++);
|
||||
int currX = sourceRect.x;
|
||||
|
||||
//Skip blocks until starting position reached
|
||||
while ( currX > size )
|
||||
{
|
||||
currX -= size;
|
||||
if (type == 0xff)
|
||||
data += size;
|
||||
type = *(data++);
|
||||
size = *(data++);
|
||||
}
|
||||
//This block will be shown partially - calculate size\position
|
||||
size -= currX;
|
||||
if (type == 0xff)
|
||||
data += currX;
|
||||
|
||||
currX = 0;
|
||||
ui8 bpp = where->format->BytesPerPixel;
|
||||
|
||||
//Calculate position for blitting: pixels + Y + X
|
||||
ui8* blitPos = (ui8*) where->pixels;
|
||||
if (rotation & 4)
|
||||
blitPos += (dst.y - currY) * where->pitch;
|
||||
else
|
||||
blitPos += (dst.y + currY) * where->pitch;
|
||||
blitPos += dst.x * bpp;
|
||||
|
||||
//Blit blocks that must be fully visible
|
||||
while (currX + size < sourceRect.w)
|
||||
{
|
||||
//blit block, pointers will be modified if needed
|
||||
BlitBlockWithBpp(bpp, type, size, data, blitPos, alpha, rotation & 2);
|
||||
|
||||
currX += size;
|
||||
type = *(data++);
|
||||
size = *(data++);
|
||||
}
|
||||
//Blit last, semi-visible block
|
||||
size = sourceRect.w - currX;
|
||||
BlitBlockWithBpp(bpp, type, size, data, blitPos, alpha, rotation & 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<IImage> CompImage::scaleFast(float scale) const
|
||||
{
|
||||
//todo: CompImage::scaleFast
|
||||
|
||||
logAnim->error("CompImage::scaleFast is not implemented");
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#define CASEBPP(x,y) case x: BlitBlock<x,y>(type, size, data, dest, alpha); break
|
||||
|
||||
//FIXME: better way to get blitter
|
||||
void CompImage::BlitBlockWithBpp(ui8 bpp, ui8 type, ui8 size, ui8 *&data, ui8 *&dest, ui8 alpha, bool rotated) const
|
||||
{
|
||||
assert(bpp>1 && bpp<5);
|
||||
|
||||
if (rotated)
|
||||
switch (bpp)
|
||||
{
|
||||
CASEBPP(2,1);
|
||||
CASEBPP(3,1);
|
||||
CASEBPP(4,1);
|
||||
}
|
||||
else
|
||||
switch (bpp)
|
||||
{
|
||||
CASEBPP(2,1);
|
||||
CASEBPP(3,1);
|
||||
CASEBPP(4,1);
|
||||
}
|
||||
}
|
||||
#undef CASEBPP
|
||||
|
||||
//Blit one block from RLE-d surface
|
||||
template<int bpp, int dir>
|
||||
void CompImage::BlitBlock(ui8 type, ui8 size, ui8 *&data, ui8 *&dest, ui8 alpha) const
|
||||
{
|
||||
//Raw data
|
||||
if (type == 0xff)
|
||||
{
|
||||
ui8 color = *data;
|
||||
if (alpha != 255)//Per-surface alpha is set
|
||||
{
|
||||
for (size_t i=0; i<size; i++)
|
||||
{
|
||||
SDL_Color col = palette[*(data++)];
|
||||
col.a = (ui32)col.a*alpha/255;
|
||||
ColorPutter<bpp, 1>::PutColorAlpha(dest, col);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (palette[color].a == 255)
|
||||
{
|
||||
//Put row of RGB data
|
||||
for (size_t i=0; i<size; i++)
|
||||
ColorPutter<bpp, 1>::PutColor(dest, palette[*(data++)]);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Put row of RGBA data
|
||||
for (size_t i=0; i<size; i++)
|
||||
ColorPutter<bpp, 1>::PutColorAlpha(dest, palette[*(data++)]);
|
||||
|
||||
}
|
||||
}
|
||||
//RLE-d sequence
|
||||
else
|
||||
{
|
||||
if (alpha != 255 && palette[type].a !=0)//Per-surface alpha is set
|
||||
{
|
||||
SDL_Color col = palette[type];
|
||||
col.a = (int)col.a*(255-alpha)/255;
|
||||
for (size_t i=0; i<size; i++)
|
||||
ColorPutter<bpp, 1>::PutColorAlpha(dest, col);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (palette[type].a)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
//Skip row
|
||||
dest += size*bpp;
|
||||
break;
|
||||
}
|
||||
case 255:
|
||||
{
|
||||
//Put RGB row
|
||||
ColorPutter<bpp, 1>::PutColorRow(dest, palette[type], size);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
//Put RGBA row
|
||||
for (size_t i=0; i<size; i++)
|
||||
ColorPutter<bpp, 1>::PutColorAlpha(dest, palette[type]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CompImage::playerColored(PlayerColor player)
|
||||
{
|
||||
SDL_Color *pal = nullptr;
|
||||
if(player < PlayerColor::PLAYER_LIMIT)
|
||||
{
|
||||
pal = graphics->playerColorPalette + 32*player.getNum();
|
||||
}
|
||||
else if(player == PlayerColor::NEUTRAL)
|
||||
{
|
||||
pal = graphics->neutralColorPalette;
|
||||
}
|
||||
else
|
||||
assert(0);
|
||||
|
||||
for(int i=0; i<32; ++i)
|
||||
{
|
||||
CSDL_Ext::colorAssign(palette[224+i],pal[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void CompImage::setFlagColor(PlayerColor player)
|
||||
{
|
||||
logAnim->error("CompImage::setFlagColor is not implemented");
|
||||
}
|
||||
|
||||
int CompImage::width() const
|
||||
{
|
||||
return fullSize.x;
|
||||
}
|
||||
|
||||
int CompImage::height() const
|
||||
{
|
||||
return fullSize.y;
|
||||
}
|
||||
|
||||
CompImage::~CompImage()
|
||||
{
|
||||
free(surf);
|
||||
delete [] line;
|
||||
delete [] palette;
|
||||
}
|
||||
|
||||
void CompImage::horizontalFlip()
|
||||
{
|
||||
logAnim->error("%s is not implemented", BOOST_CURRENT_FUNCTION);
|
||||
}
|
||||
|
||||
void CompImage::verticalFlip()
|
||||
{
|
||||
logAnim->error("%s is not implemented", BOOST_CURRENT_FUNCTION);
|
||||
}
|
||||
|
||||
void CompImage::shiftPalette(int from, int howMany)
|
||||
{
|
||||
logAnim->error("%s is not implemented", BOOST_CURRENT_FUNCTION);
|
||||
}
|
||||
|
||||
void CompImage::setBorderPallete(const IImage::BorderPallete & borderPallete)
|
||||
{
|
||||
logAnim->error("%s is not implemented", BOOST_CURRENT_FUNCTION);
|
||||
}
|
||||
|
||||
void CompImage::exportBitmap(const boost::filesystem::path & path) const
|
||||
{
|
||||
logAnim->error("%s is not implemented", BOOST_CURRENT_FUNCTION);
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* CAnimation for animations handling, can load part of file if needed *
|
||||
*************************************************************************/
|
||||
|
||||
std::shared_ptr<IImage> CAnimation::getFromExtraDef(std::string filename)
|
||||
{
|
||||
size_t pos = filename.find(':');
|
||||
@ -1363,17 +811,14 @@ 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] = std::make_shared<CompImage>(defFile, frame, group);
|
||||
else
|
||||
images[group][frame] = std::make_shared<SDLImage>(defFile, frame, group);
|
||||
images[group][frame] = std::make_shared<SDLImage>(defFile.get(), frame, group);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// still here? image is missing
|
||||
|
||||
printError(frame, group, "LoadFrame");
|
||||
images[group][frame] = std::make_shared<SDLImage>("DEFAULT", compressed);
|
||||
images[group][frame] = std::make_shared<SDLImage>("DEFAULT");
|
||||
}
|
||||
else //load from separate file
|
||||
{
|
||||
@ -1507,11 +952,10 @@ void CAnimation::printError(size_t frame, size_t group, std::string type) const
|
||||
logGlobal->error("%s error: Request for frame not present in CAnimation! File name: %s, Group: %d, Frame: %d", type, name, group, frame);
|
||||
}
|
||||
|
||||
CAnimation::CAnimation(std::string Name, bool Compressed):
|
||||
CAnimation::CAnimation(std::string Name):
|
||||
name(Name),
|
||||
compressed(Compressed),
|
||||
preloaded(false),
|
||||
defFile(nullptr)
|
||||
defFile()
|
||||
{
|
||||
size_t dotPos = name.find_last_of('.');
|
||||
if ( dotPos!=-1 )
|
||||
@ -1521,7 +965,7 @@ CAnimation::CAnimation(std::string Name, bool Compressed):
|
||||
ResourceID resource(std::string("SPRITES/") + name, EResType::ANIMATION);
|
||||
|
||||
if(CResourceHandler::get()->existsResource(resource))
|
||||
defFile = new CDefFile(name);
|
||||
defFile = std::make_shared<CDefFile>(name);
|
||||
|
||||
init();
|
||||
|
||||
@ -1531,21 +975,28 @@ CAnimation::CAnimation(std::string Name, bool Compressed):
|
||||
|
||||
CAnimation::CAnimation():
|
||||
name(""),
|
||||
compressed(false),
|
||||
preloaded(false),
|
||||
defFile(nullptr)
|
||||
defFile()
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
CAnimation::~CAnimation()
|
||||
{
|
||||
if(defFile)
|
||||
delete defFile;
|
||||
}
|
||||
CAnimation::~CAnimation() = default;
|
||||
|
||||
void CAnimation::duplicateImage(const size_t sourceGroup, const size_t sourceFrame, const size_t targetGroup)
|
||||
{
|
||||
if(!source.count(sourceGroup))
|
||||
{
|
||||
logAnim->error("Group %d missing in %s", sourceGroup, name);
|
||||
return;
|
||||
}
|
||||
|
||||
if(source[sourceGroup].size() <= sourceFrame)
|
||||
{
|
||||
logAnim->error("Frame [%d %d] missing in %s", sourceGroup, sourceFrame, name);
|
||||
return;
|
||||
}
|
||||
|
||||
//todo: clone actual loaded Image object
|
||||
JsonNode clone(source[sourceGroup][sourceFrame]);
|
||||
|
||||
|
@ -68,12 +68,9 @@ private:
|
||||
//animation file name
|
||||
std::string name;
|
||||
|
||||
//if true all frames will be stored in compressed (RLE) state
|
||||
const bool compressed;
|
||||
|
||||
bool preloaded;
|
||||
|
||||
CDefFile * defFile;
|
||||
std::shared_ptr<CDefFile> defFile;
|
||||
|
||||
//loader, will be called by load(), require opened def file for loading from it. Returns true if image is loaded
|
||||
bool loadFrame(size_t frame, size_t group);
|
||||
@ -93,7 +90,7 @@ private:
|
||||
std::shared_ptr<IImage> getFromExtraDef(std::string filename);
|
||||
|
||||
public:
|
||||
CAnimation(std::string Name, bool Compressed = false);
|
||||
CAnimation(std::string Name);
|
||||
CAnimation();
|
||||
~CAnimation();
|
||||
|
||||
|
@ -18,8 +18,31 @@
|
||||
|
||||
#include "../CMT.h"
|
||||
|
||||
void CCursorHandler::clearBuffer()
|
||||
{
|
||||
Uint32 fillColor = SDL_MapRGBA(buffer->format, 0, 0, 0, 0);
|
||||
CSDL_Ext::fillRect(buffer, nullptr, fillColor);
|
||||
}
|
||||
|
||||
void CCursorHandler::updateBuffer(CIntObject * payload)
|
||||
{
|
||||
payload->moveTo(Point(0,0));
|
||||
payload->showAll(buffer);
|
||||
|
||||
needUpdate = true;
|
||||
}
|
||||
|
||||
void CCursorHandler::replaceBuffer(CIntObject * payload)
|
||||
{
|
||||
clearBuffer();
|
||||
updateBuffer(payload);
|
||||
}
|
||||
|
||||
void CCursorHandler::initCursor()
|
||||
{
|
||||
cursorLayer = SDL_CreateTexture(mainRenderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 40, 40);
|
||||
SDL_SetTextureBlendMode(cursorLayer, SDL_BLENDMODE_BLEND);
|
||||
|
||||
xpos = ypos = 0;
|
||||
type = ECursor::DEFAULT;
|
||||
dndObject = nullptr;
|
||||
@ -34,9 +57,9 @@ void CCursorHandler::initCursor()
|
||||
|
||||
currentCursor = cursors.at(int(ECursor::DEFAULT)).get();
|
||||
|
||||
help = CSDL_Ext::newSurface(40,40);
|
||||
//No blending. Ensure, that we are copying pixels during "screen restore draw"
|
||||
SDL_SetSurfaceBlendMode(help,SDL_BLENDMODE_NONE);
|
||||
buffer = CSDL_Ext::newSurface(40,40);
|
||||
|
||||
SDL_SetSurfaceBlendMode(buffer, SDL_BLENDMODE_NONE);
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
|
||||
changeGraphic(ECursor::ADVENTURE, 0);
|
||||
@ -56,11 +79,17 @@ void CCursorHandler::changeGraphic(ECursor::ECursorTypes type, int index)
|
||||
this->frame = index;
|
||||
currentCursor->setFrame(index);
|
||||
}
|
||||
|
||||
replaceBuffer(currentCursor);
|
||||
}
|
||||
|
||||
void CCursorHandler::dragAndDropCursor(std::unique_ptr<CAnimImage> object)
|
||||
{
|
||||
dndObject = std::move(object);
|
||||
if(dndObject)
|
||||
replaceBuffer(dndObject.get());
|
||||
else
|
||||
replaceBuffer(currentCursor);
|
||||
}
|
||||
|
||||
void CCursorHandler::cursorMove(const int & x, const int & y)
|
||||
@ -69,40 +98,6 @@ void CCursorHandler::cursorMove(const int & x, const int & y)
|
||||
ypos = y;
|
||||
}
|
||||
|
||||
void CCursorHandler::drawWithScreenRestore()
|
||||
{
|
||||
if(!showing) return;
|
||||
int x = xpos, y = ypos;
|
||||
shiftPos(x, y);
|
||||
|
||||
SDL_Rect temp_rect1 = genRect(40,40,x,y);
|
||||
SDL_Rect temp_rect2 = genRect(40,40,0,0);
|
||||
SDL_BlitSurface(screen, &temp_rect1, help, &temp_rect2);
|
||||
|
||||
if (dndObject)
|
||||
{
|
||||
dndObject->moveTo(Point(x - dndObject->pos.w/2, y - dndObject->pos.h/2));
|
||||
dndObject->showAll(screen);
|
||||
}
|
||||
else
|
||||
{
|
||||
currentCursor->moveTo(Point(x,y));
|
||||
currentCursor->showAll(screen);
|
||||
}
|
||||
}
|
||||
|
||||
void CCursorHandler::drawRestored()
|
||||
{
|
||||
if(!showing)
|
||||
return;
|
||||
|
||||
int x = xpos, y = ypos;
|
||||
shiftPos(x, y);
|
||||
|
||||
SDL_Rect temp_rect = genRect(40, 40, x, y);
|
||||
SDL_BlitSurface(help, nullptr, screen, &temp_rect);
|
||||
}
|
||||
|
||||
void CCursorHandler::shiftPos( int &x, int &y )
|
||||
{
|
||||
if(( type == ECursor::COMBAT && frame != ECursor::COMBAT_POINTER) || type == ECursor::SPELLBOOK)
|
||||
@ -221,15 +216,54 @@ void CCursorHandler::centerCursor()
|
||||
|
||||
void CCursorHandler::render()
|
||||
{
|
||||
drawWithScreenRestore();
|
||||
CSDL_Ext::update(screen);
|
||||
drawRestored();
|
||||
if(!showing)
|
||||
return;
|
||||
|
||||
//the must update texture in the main (renderer) thread, but changes to cursor type may come from other threads
|
||||
updateTexture();
|
||||
|
||||
int x = xpos;
|
||||
int y = ypos;
|
||||
shiftPos(x, y);
|
||||
|
||||
if(dndObject)
|
||||
{
|
||||
x -= dndObject->pos.w/2;
|
||||
y -= dndObject->pos.h/2;
|
||||
}
|
||||
|
||||
SDL_Rect destRect;
|
||||
destRect.x = x;
|
||||
destRect.y = y;
|
||||
destRect.w = 40;
|
||||
destRect.h = 40;
|
||||
|
||||
SDL_RenderCopy(mainRenderer, cursorLayer, nullptr, &destRect);
|
||||
}
|
||||
|
||||
CCursorHandler::CCursorHandler() = default;
|
||||
void CCursorHandler::updateTexture()
|
||||
{
|
||||
if(needUpdate)
|
||||
{
|
||||
SDL_UpdateTexture(cursorLayer, nullptr, buffer->pixels, buffer->pitch);
|
||||
needUpdate = false;
|
||||
}
|
||||
}
|
||||
|
||||
CCursorHandler::CCursorHandler()
|
||||
: needUpdate(true),
|
||||
buffer(nullptr),
|
||||
cursorLayer(nullptr),
|
||||
showing(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CCursorHandler::~CCursorHandler()
|
||||
{
|
||||
if(help)
|
||||
SDL_FreeSurface(help);
|
||||
if(buffer)
|
||||
SDL_FreeSurface(buffer);
|
||||
|
||||
if(cursorLayer)
|
||||
SDL_DestroyTexture(cursorLayer);
|
||||
}
|
||||
|
@ -8,9 +8,10 @@
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
class CIntObject;
|
||||
class CAnimImage;
|
||||
struct SDL_Surface;
|
||||
struct SDL_Texture;
|
||||
|
||||
namespace ECursor
|
||||
{
|
||||
@ -26,7 +27,10 @@ namespace ECursor
|
||||
/// handles mouse cursor
|
||||
class CCursorHandler final
|
||||
{
|
||||
SDL_Surface * help;
|
||||
bool needUpdate;
|
||||
SDL_Texture * cursorLayer;
|
||||
|
||||
SDL_Surface * buffer;
|
||||
CAnimImage * currentCursor;
|
||||
|
||||
std::unique_ptr<CAnimImage> dndObject; //if set, overrides currentCursor
|
||||
@ -35,10 +39,12 @@ class CCursorHandler final
|
||||
|
||||
bool showing;
|
||||
|
||||
/// Draw cursor preserving original image below cursor
|
||||
void drawWithScreenRestore();
|
||||
/// Restore original image below cursor
|
||||
void drawRestored();
|
||||
void clearBuffer();
|
||||
void updateBuffer(CIntObject * payload);
|
||||
void replaceBuffer(CIntObject * payload);
|
||||
void shiftPos( int &x, int &y );
|
||||
|
||||
void updateTexture();
|
||||
public:
|
||||
/// position of cursor
|
||||
int xpos, ypos;
|
||||
@ -63,9 +69,8 @@ public:
|
||||
|
||||
void render();
|
||||
|
||||
void shiftPos( int &x, int &y );
|
||||
void hide() { showing=0; };
|
||||
void show() { showing=1; };
|
||||
void hide() { showing=false; };
|
||||
void show() { showing=true; };
|
||||
|
||||
/// change cursor's positions to (x, y)
|
||||
void cursorMove(const int & x, const int & y);
|
||||
|
@ -96,10 +96,11 @@ void CGuiHandler::handleElementDeActivate(CIntObject * elem, ui16 activityFlag)
|
||||
elem->active_m &= ~activityFlag;
|
||||
}
|
||||
|
||||
void CGuiHandler::popInt(IShowActivatable *top)
|
||||
void CGuiHandler::popInt(std::shared_ptr<IShowActivatable> top)
|
||||
{
|
||||
assert(listInt.front() == top);
|
||||
top->deactivate();
|
||||
disposed.push_back(top);
|
||||
listInt.pop_front();
|
||||
objsToBlit -= top;
|
||||
if(!listInt.empty())
|
||||
@ -109,18 +110,10 @@ void CGuiHandler::popInt(IShowActivatable *top)
|
||||
pushSDLEvent(SDL_USEREVENT, EUserEvent::INTERFACE_CHANGED);
|
||||
}
|
||||
|
||||
void CGuiHandler::popIntTotally(IShowActivatable *top)
|
||||
{
|
||||
assert(listInt.front() == top);
|
||||
popInt(top);
|
||||
delete top;
|
||||
fakeMouseMove();
|
||||
}
|
||||
|
||||
void CGuiHandler::pushInt(IShowActivatable *newInt)
|
||||
void CGuiHandler::pushInt(std::shared_ptr<IShowActivatable> newInt)
|
||||
{
|
||||
assert(newInt);
|
||||
assert(boost::range::find(listInt, newInt) == listInt.end()); // do not add same object twice
|
||||
assert(!vstd::contains(listInt, newInt)); // do not add same object twice
|
||||
|
||||
//a new interface will be present, we'll need to use buffer surface (unless it's advmapint that will alter screenBuf on activate anyway)
|
||||
screenBuf = screen2;
|
||||
@ -128,6 +121,7 @@ void CGuiHandler::pushInt(IShowActivatable *newInt)
|
||||
if(!listInt.empty())
|
||||
listInt.front()->deactivate();
|
||||
listInt.push_front(newInt);
|
||||
CCS->curh->changeGraphic(ECursor::ADVENTURE, 0);
|
||||
newInt->activate();
|
||||
objsToBlit.push_back(newInt);
|
||||
totalRedraw();
|
||||
@ -144,7 +138,7 @@ void CGuiHandler::popInts(int howMany)
|
||||
for(int i=0; i < howMany; i++)
|
||||
{
|
||||
objsToBlit -= listInt.front();
|
||||
delete listInt.front();
|
||||
disposed.push_back(listInt.front());
|
||||
listInt.pop_front();
|
||||
}
|
||||
|
||||
@ -158,10 +152,10 @@ void CGuiHandler::popInts(int howMany)
|
||||
pushSDLEvent(SDL_USEREVENT, EUserEvent::INTERFACE_CHANGED);
|
||||
}
|
||||
|
||||
IShowActivatable * CGuiHandler::topInt()
|
||||
std::shared_ptr<IShowActivatable> CGuiHandler::topInt()
|
||||
{
|
||||
if(listInt.empty())
|
||||
return nullptr;
|
||||
return std::shared_ptr<IShowActivatable>();
|
||||
else
|
||||
return listInt.front();
|
||||
}
|
||||
@ -234,11 +228,11 @@ void CGuiHandler::handleCurrentEvent()
|
||||
|
||||
case SDLK_F9:
|
||||
//not working yet since CClient::run remain locked after CBattleInterface removal
|
||||
if(LOCPLINT->battleInt)
|
||||
{
|
||||
GH.popIntTotally(GH.topInt());
|
||||
vstd::clear_pointer(LOCPLINT->battleInt);
|
||||
}
|
||||
// if(LOCPLINT->battleInt)
|
||||
// {
|
||||
// GH.popInts(1);
|
||||
// vstd::clear_pointer(LOCPLINT->battleInt);
|
||||
// }
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -271,7 +265,6 @@ void CGuiHandler::handleCurrentEvent()
|
||||
}
|
||||
else if(current->type == SDL_MOUSEMOTION)
|
||||
{
|
||||
CCS->curh->cursorMove(current->motion.x, current->motion.y);
|
||||
handleMouseMotion();
|
||||
}
|
||||
else if(current->type == SDL_MOUSEBUTTONDOWN)
|
||||
@ -457,15 +450,18 @@ void CGuiHandler::renderFrame()
|
||||
if(nullptr != curInt)
|
||||
curInt->update();
|
||||
|
||||
if (settings["general"]["showfps"].Bool())
|
||||
if(settings["general"]["showfps"].Bool())
|
||||
drawFPSCounter();
|
||||
|
||||
// draw the mouse cursor and update the screen
|
||||
CCS->curh->render();
|
||||
SDL_UpdateTexture(screenTexture, nullptr, screen->pixels, screen->pitch);
|
||||
|
||||
SDL_RenderCopy(mainRenderer, screenTexture, nullptr, nullptr);
|
||||
|
||||
CCS->curh->render();
|
||||
|
||||
SDL_RenderPresent(mainRenderer);
|
||||
|
||||
disposed.clear();
|
||||
}
|
||||
|
||||
mainFPSmng->framerateDelay(); // holds a constant FPS
|
||||
|
@ -58,10 +58,12 @@ class CGuiHandler
|
||||
{
|
||||
public:
|
||||
CFramerateManager * mainFPSmng; //to keep const framerate
|
||||
std::list<IShowActivatable *> listInt; //list of interfaces - front=foreground; back = background (includes adventure map, window interfaces, all kind of active dialogs, and so on)
|
||||
std::list<std::shared_ptr<IShowActivatable>> listInt; //list of interfaces - front=foreground; back = background (includes adventure map, window interfaces, all kind of active dialogs, and so on)
|
||||
CGStatusBar * statusbar;
|
||||
|
||||
private:
|
||||
std::vector<std::shared_ptr<IShowActivatable>> disposed;
|
||||
|
||||
std::atomic<bool> continueEventHandling;
|
||||
typedef std::list<CIntObject*> CIntObjectList;
|
||||
|
||||
@ -86,7 +88,7 @@ public:
|
||||
|
||||
public:
|
||||
//objs to blit
|
||||
std::vector<IShowable*> objsToBlit;
|
||||
std::vector<std::shared_ptr<IShowActivatable>> objsToBlit;
|
||||
|
||||
SDL_Event * current; //current event - can be set to nullptr to stop handling event
|
||||
IUpdateable *curInt;
|
||||
@ -106,11 +108,19 @@ public:
|
||||
void totalRedraw(); //forces total redraw (using showAll), sets a flag, method gets called at the end of the rendering
|
||||
void simpleRedraw(); //update only top interface and draw background from buffer, sets a flag, method gets called at the end of the rendering
|
||||
|
||||
void popInt(IShowActivatable *top); //removes given interface from the top and activates next
|
||||
void popIntTotally(IShowActivatable *top); //deactivates, deletes, removes given interface from the top and activates next
|
||||
void pushInt(IShowActivatable *newInt); //deactivate old top interface, activates this one and pushes to the top
|
||||
void pushInt(std::shared_ptr<IShowActivatable> newInt); //deactivate old top interface, activates this one and pushes to the top
|
||||
template <typename T, typename ... Args>
|
||||
void pushIntT(Args && ... args)
|
||||
{
|
||||
auto newInt = std::make_shared<T>(std::forward<Args>(args)...);
|
||||
pushInt(newInt);
|
||||
}
|
||||
|
||||
void popInts(int howMany); //pops one or more interfaces - deactivates top, deletes and removes given number of interfaces, activates new front
|
||||
IShowActivatable *topInt(); //returns top interface
|
||||
|
||||
void popInt(std::shared_ptr<IShowActivatable> top); //removes given interface from the top and activates next
|
||||
|
||||
std::shared_ptr<IShowActivatable> topInt(); //returns top interface
|
||||
|
||||
void updateTime(); //handles timeInterested
|
||||
void handleEvents(); //takes events from queue and calls interested objects
|
||||
|
@ -164,11 +164,6 @@ void CIntObject::printAtLoc(const std::string & text, int x, int y, EFonts font,
|
||||
graphics->fonts[font]->renderTextLeft(dst, text, kolor, Point(pos.x + x, pos.y + y));
|
||||
}
|
||||
|
||||
void CIntObject::printAtRightLoc(const std::string & text, int x, int y, EFonts font, SDL_Color kolor, SDL_Surface * dst)
|
||||
{
|
||||
graphics->fonts[font]->renderTextRight(dst, text, kolor, Point(pos.x + x, pos.y + y));
|
||||
}
|
||||
|
||||
void CIntObject::printAtMiddleLoc(const std::string & text, int x, int y, EFonts font, SDL_Color kolor, SDL_Surface * dst)
|
||||
{
|
||||
printAtMiddleLoc(text, Point(x,y), font, kolor, dst);
|
||||
@ -194,11 +189,6 @@ void CIntObject::printAtMiddleWBLoc( const std::string & text, int x, int y, EFo
|
||||
graphics->fonts[font]->renderTextLinesCenter(dst, CMessage::breakText(text, charpr, font), kolor, Point(pos.x + x, pos.y + y));
|
||||
}
|
||||
|
||||
void CIntObject::printToLoc( const std::string & text, int x, int y, EFonts font, SDL_Color kolor, SDL_Surface * dst )
|
||||
{
|
||||
graphics->fonts[font]->renderTextRight(dst, text, kolor, Point(pos.x + x, pos.y + y));
|
||||
}
|
||||
|
||||
void CIntObject::addUsedEvents(ui16 newActions)
|
||||
{
|
||||
if (active_m)
|
||||
@ -223,7 +213,7 @@ void CIntObject::disable()
|
||||
|
||||
void CIntObject::enable()
|
||||
{
|
||||
if(!active_m && parent_m->active)
|
||||
if(!active_m && (!parent_m || parent_m->active))
|
||||
activate();
|
||||
|
||||
recActions = 255;
|
||||
@ -302,11 +292,6 @@ void CIntObject::removeChild(CIntObject * child, bool adjustPosition)
|
||||
child->pos -= pos;
|
||||
}
|
||||
|
||||
void CIntObject::drawBorderLoc(SDL_Surface * sur, const Rect &r, const int3 &color)
|
||||
{
|
||||
CSDL_Ext::drawBorder(sur, r + pos, color);
|
||||
}
|
||||
|
||||
void CIntObject::redraw()
|
||||
{
|
||||
//currently most of calls come from active objects so this check won't affect them
|
||||
@ -375,3 +360,16 @@ void CKeyShortcut::keyPressed(const SDL_KeyboardEvent & key)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
WindowBase::WindowBase(int used_, Point pos_)
|
||||
: CIntObject(used_, pos_)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void WindowBase::close()
|
||||
{
|
||||
if(GH.topInt().get() != this)
|
||||
logGlobal->error("Only top interface must be closed");
|
||||
GH.popInts(1);
|
||||
}
|
||||
|
@ -183,12 +183,9 @@ public:
|
||||
/*
|
||||
* Functions that should be used only by specific GUI elements. Don't use them unless you really know why they are here
|
||||
*/
|
||||
//wrappers for CSDL_Ext methods. This versions use coordinates relative to pos
|
||||
void drawBorderLoc(SDL_Surface * sur, const Rect &r, const int3 &color);
|
||||
|
||||
//functions for printing text. Use CLabel where possible instead
|
||||
void printAtLoc(const std::string & text, int x, int y, EFonts font, SDL_Color color, SDL_Surface * dst);
|
||||
void printToLoc(const std::string & text, int x, int y, EFonts font, SDL_Color color, SDL_Surface * dst);
|
||||
void printAtRightLoc(const std::string & text, int x, int y, EFonts font, SDL_Color color, SDL_Surface * dst);
|
||||
void printAtMiddleLoc(const std::string & text, int x, int y, EFonts font, SDL_Color color, SDL_Surface * dst);
|
||||
void printAtMiddleLoc(const std::string & text, const Point &p, EFonts font, SDL_Color color, SDL_Surface * dst);
|
||||
void printAtMiddleWBLoc(const std::string & text, int x, int y, EFonts font, int charsPerLine, SDL_Color color, SDL_Surface * dst);
|
||||
@ -211,3 +208,11 @@ public:
|
||||
CKeyShortcut(std::set<int> Keys);
|
||||
virtual void keyPressed(const SDL_KeyboardEvent & key) override; //call-in
|
||||
};
|
||||
|
||||
class WindowBase : public CIntObject
|
||||
{
|
||||
public:
|
||||
WindowBase(int used_ = 0, Point pos_ = Point());
|
||||
protected:
|
||||
void close();
|
||||
};
|
||||
|
@ -39,7 +39,7 @@ void SDL_UpdateRect(SDL_Surface *surface, int x, int y, int w, int h)
|
||||
|
||||
SDL_Surface * CSDL_Ext::newSurface(int w, int h, SDL_Surface * mod) //creates new surface, with flags/format same as in surface given
|
||||
{
|
||||
SDL_Surface * ret = SDL_CreateRGBSurface(mod->flags,w,h,mod->format->BitsPerPixel,mod->format->Rmask,mod->format->Gmask,mod->format->Bmask,mod->format->Amask);
|
||||
SDL_Surface * ret = SDL_CreateRGBSurface(0,w,h,mod->format->BitsPerPixel,mod->format->Rmask,mod->format->Gmask,mod->format->Bmask,mod->format->Amask);
|
||||
if (mod->format->palette)
|
||||
{
|
||||
assert(ret->format->palette);
|
||||
@ -65,7 +65,7 @@ SDL_Surface * CSDL_Ext::createSurfaceWithBpp(int width, int height)
|
||||
Channels::px<bpp>::b.set((Uint8*)&bMask, 255);
|
||||
Channels::px<bpp>::a.set((Uint8*)&aMask, 255);
|
||||
|
||||
return SDL_CreateRGBSurface( SDL_SWSURFACE, width, height, bpp * 8, rMask, gMask, bMask, aMask);
|
||||
return SDL_CreateRGBSurface(0, width, height, bpp * 8, rMask, gMask, bMask, aMask);
|
||||
}
|
||||
|
||||
bool isItIn(const SDL_Rect * rect, int x, int y)
|
||||
|
@ -394,14 +394,14 @@ void CBonusSelection::goBack()
|
||||
}
|
||||
else
|
||||
{
|
||||
GH.popIntTotally(this);
|
||||
close();
|
||||
}
|
||||
// TODO: we can actually only pop bonus selection interface for custom campaigns
|
||||
// Though this would require clearing CLobbyScreen::bonusSel pointer when poping this interface
|
||||
/*
|
||||
else
|
||||
{
|
||||
GH.popIntTotally(this);
|
||||
close();
|
||||
CSH->state = EClientState::LOBBY;
|
||||
}
|
||||
*/
|
||||
@ -420,7 +420,7 @@ void CBonusSelection::startMap()
|
||||
const CCampaignScenario & scenario = getCampaign()->camp->scenarios[CSH->campaignMap];
|
||||
if(scenario.prolog.hasPrologEpilog)
|
||||
{
|
||||
GH.pushInt(new CPrologEpilogVideo(scenario.prolog, exitCb));
|
||||
GH.pushIntT<CPrologEpilogVideo>(scenario.prolog, exitCb);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -430,7 +430,7 @@ void CBonusSelection::startMap()
|
||||
|
||||
if(LOCPLINT) // we're currently ingame, so ask for starting new map and end game
|
||||
{
|
||||
GH.popInt(this);
|
||||
close();
|
||||
LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[67], [=]()
|
||||
{
|
||||
showPrologVideo();
|
||||
@ -444,7 +444,7 @@ void CBonusSelection::startMap()
|
||||
|
||||
void CBonusSelection::restartMap()
|
||||
{
|
||||
GH.popInt(this);
|
||||
close();
|
||||
LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[67], [=]()
|
||||
{
|
||||
CSH->startCampaignScenario();
|
||||
|
@ -88,7 +88,11 @@ CLobbyScreen::CLobbyScreen(ESelectionScreen screenType)
|
||||
|
||||
buttonStart->assignedKeys.insert(SDLK_RETURN);
|
||||
|
||||
buttonBack = std::make_shared<CButton>(Point(581, 535), "SCNRBACK.DEF", CGI->generaltexth->zelp[105], [&](){CSH->sendClientDisconnecting(); GH.popIntTotally(this);}, SDLK_ESCAPE);
|
||||
buttonBack = std::make_shared<CButton>(Point(581, 535), "SCNRBACK.DEF", CGI->generaltexth->zelp[105], [&]()
|
||||
{
|
||||
CSH->sendClientDisconnecting();
|
||||
close();
|
||||
}, SDLK_ESCAPE);
|
||||
}
|
||||
|
||||
CLobbyScreen::~CLobbyScreen()
|
||||
@ -138,7 +142,7 @@ void CLobbyScreen::startScenario(bool allowOnlyAI)
|
||||
}
|
||||
catch(ExceptionNoTemplate & e)
|
||||
{
|
||||
GH.pushInt(CInfoWindow::create(CGI->generaltexth->allTexts[751]));
|
||||
CInfoWindow::showInfoDialog(std::ref(CGI->generaltexth->allTexts[751]), CInfoWindow::TCompsInfo(), PlayerColor(1));
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
|
@ -31,5 +31,5 @@ public:
|
||||
const CMapInfo * getMapInfo() override;
|
||||
const StartInfo * getStartInfo() override;
|
||||
|
||||
CBonusSelection * bonusSel;
|
||||
std::shared_ptr<CBonusSelection> bonusSel;
|
||||
};
|
||||
|
@ -80,7 +80,7 @@ void CSavingScreen::saveGame()
|
||||
Settings lastSave = settings.write["general"]["lastSave"];
|
||||
lastSave->String() = path;
|
||||
LOCPLINT->cb->save(path);
|
||||
GH.popIntTotally(this);
|
||||
close();
|
||||
};
|
||||
|
||||
if(CResourceHandler::get("local")->existsResource(ResourceID(path, EResType::CLIENT_SAVEGAME)))
|
||||
|
@ -39,7 +39,7 @@ CScenarioInfoScreen::CScenarioInfoScreen()
|
||||
card->changeSelection();
|
||||
|
||||
card->iconDifficulty->setSelected(getCurrentDifficulty());
|
||||
buttonBack = std::make_shared<CButton>(Point(584, 535), "SCNRBACK.DEF", CGI->generaltexth->zelp[105], std::bind(&CGuiHandler::popIntTotally, &GH, this), SDLK_ESCAPE);
|
||||
buttonBack = std::make_shared<CButton>(Point(584, 535), "SCNRBACK.DEF", CGI->generaltexth->zelp[105], [=](){ close();}, SDLK_ESCAPE);
|
||||
}
|
||||
|
||||
CScenarioInfoScreen::~CScenarioInfoScreen()
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include "CSelectionBase.h"
|
||||
|
||||
/// Scenario information screen shown during the game
|
||||
class CScenarioInfoScreen : public CIntObject, public ISelectionScreenInfo
|
||||
class CScenarioInfoScreen : public WindowBase, public ISelectionScreenInfo
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<CButton> buttonBack;
|
||||
|
@ -86,7 +86,7 @@ CSelectionBase::CSelectionBase(ESelectionScreen type)
|
||||
}
|
||||
pos = background->center();
|
||||
card = std::make_shared<InfoCard>();
|
||||
buttonBack = std::make_shared<CButton>(Point(581, 535), "SCNRBACK.DEF", CGI->generaltexth->zelp[105], std::bind(&CGuiHandler::popIntTotally, &GH, this), SDLK_ESCAPE);
|
||||
buttonBack = std::make_shared<CButton>(Point(581, 535), "SCNRBACK.DEF", CGI->generaltexth->zelp[105], [=](){ close();}, SDLK_ESCAPE);
|
||||
}
|
||||
|
||||
void CSelectionBase::toggleTab(std::shared_ptr<CIntObject> tab)
|
||||
@ -367,7 +367,7 @@ void CFlagBox::recreate()
|
||||
void CFlagBox::clickRight(tribool down, bool previousState)
|
||||
{
|
||||
if(down && SEL->getMapInfo())
|
||||
GH.pushInt(new CFlagBoxTooltipBox(iconsTeamFlags));
|
||||
GH.pushIntT<CFlagBoxTooltipBox>(iconsTeamFlags);
|
||||
}
|
||||
|
||||
CFlagBox::CFlagBoxTooltipBox::CFlagBoxTooltipBox(std::shared_ptr<CAnimation> icons)
|
||||
|
@ -422,7 +422,7 @@ void OptionsTab::SelectedBox::clickRight(tribool down, bool previousState)
|
||||
if(settings.hero == -2 && !SEL->getPlayerInfo(settings.color.getNum()).hasCustomMainHero() && CPlayerSettingsHelper::type == HERO)
|
||||
return;
|
||||
|
||||
GH.pushInt(new CPlayerOptionTooltipBox(*this));
|
||||
GH.pushIntT<CPlayerOptionTooltipBox>(*this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -79,8 +79,7 @@ std::shared_ptr<CButton> CCampaignScreen::createExitButton(const JsonNode & butt
|
||||
if(!button["help"].isNull() && button["help"].Float() > 0)
|
||||
help = CGI->generaltexth->zelp[button["help"].Float()];
|
||||
|
||||
std::function<void()> close = std::bind(&CGuiHandler::popIntTotally, &GH, this);
|
||||
return std::make_shared<CButton>(Point(button["x"].Float(), button["y"].Float()), button["name"].String(), help, close, button["hotkey"].Float());
|
||||
return std::make_shared<CButton>(Point(button["x"].Float(), button["y"].Float()), button["name"].String(), help, [=](){ close();}, button["hotkey"].Float());
|
||||
}
|
||||
|
||||
CCampaignScreen::CCampaignButton::CCampaignButton(const JsonNode & config)
|
||||
|
@ -60,7 +60,7 @@
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
CMainMenu * CMM = nullptr;
|
||||
std::shared_ptr<CMainMenu> CMM;
|
||||
ISelectionScreenInfo * SEL;
|
||||
|
||||
static void do_quit()
|
||||
@ -176,7 +176,7 @@ static std::function<void()> genCommand(CMenuScreen * menu, std::vector<std::str
|
||||
case 0:
|
||||
return std::bind(CMainMenu::openLobby, ESelectionScreen::newGame, true, nullptr, ELoadMode::NONE);
|
||||
case 1:
|
||||
return []() { GH.pushInt(new CMultiMode(ESelectionScreen::newGame)); };
|
||||
return []() { GH.pushIntT<CMultiMode>(ESelectionScreen::newGame); };
|
||||
case 2:
|
||||
return std::bind(CMainMenu::openLobby, ESelectionScreen::campaignList, true, nullptr, ELoadMode::NONE);
|
||||
case 3:
|
||||
@ -191,7 +191,7 @@ static std::function<void()> genCommand(CMenuScreen * menu, std::vector<std::str
|
||||
case 0:
|
||||
return std::bind(CMainMenu::openLobby, ESelectionScreen::loadGame, true, nullptr, ELoadMode::SINGLE);
|
||||
case 1:
|
||||
return []() { GH.pushInt(new CMultiMode(ESelectionScreen::loadGame)); };
|
||||
return []() { GH.pushIntT<CMultiMode>(ESelectionScreen::loadGame); };
|
||||
case 2:
|
||||
return std::bind(CMainMenu::openLobby, ESelectionScreen::loadGame, true, nullptr, ELoadMode::CAMPAIGN);
|
||||
case 3:
|
||||
@ -279,8 +279,7 @@ CMainMenu::CMainMenu()
|
||||
pos.h = screen->h;
|
||||
|
||||
GH.defActionsDef = 63;
|
||||
CMM = this;
|
||||
menu = new CMenuScreen(CMainMenuConfig::get().getConfig()["window"]);
|
||||
menu = std::make_shared<CMenuScreen>(CMainMenuConfig::get().getConfig()["window"]);
|
||||
OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE;
|
||||
backgroundAroundMenu = std::make_shared<CFilledTexture>("DIBOXBCK", pos);
|
||||
}
|
||||
@ -288,8 +287,6 @@ CMainMenu::CMainMenu()
|
||||
CMainMenu::~CMainMenu()
|
||||
{
|
||||
boost::unique_lock<boost::recursive_mutex> lock(*CPlayerInterface::pim);
|
||||
if(CMM == this)
|
||||
CMM = nullptr;
|
||||
|
||||
if(GH.curInt == this)
|
||||
GH.curInt = nullptr;
|
||||
@ -297,12 +294,12 @@ CMainMenu::~CMainMenu()
|
||||
|
||||
void CMainMenu::update()
|
||||
{
|
||||
if(CMM != this) //don't update if you are not a main interface
|
||||
if(CMM != this->shared_from_this()) //don't update if you are not a main interface
|
||||
return;
|
||||
|
||||
if(GH.listInt.empty())
|
||||
{
|
||||
GH.pushInt(this);
|
||||
GH.pushInt(CMM);
|
||||
GH.pushInt(menu);
|
||||
menu->switchToTab(0);
|
||||
}
|
||||
@ -313,7 +310,7 @@ void CMainMenu::update()
|
||||
|
||||
// check for null othervice crash on finishing a campaign
|
||||
// /FIXME: find out why GH.listInt is empty to begin with
|
||||
if(GH.topInt() != nullptr)
|
||||
if(GH.topInt())
|
||||
GH.topInt()->show(screen);
|
||||
}
|
||||
|
||||
@ -323,7 +320,7 @@ void CMainMenu::openLobby(ESelectionScreen screenType, bool host, const std::vec
|
||||
CSH->screenType = screenType;
|
||||
CSH->loadMode = loadMode;
|
||||
|
||||
GH.pushInt(new CSimpleJoinScreen(host));
|
||||
GH.pushIntT<CSimpleJoinScreen>(host);
|
||||
}
|
||||
|
||||
void CMainMenu::openCampaignLobby(const std::string & campaignFileName)
|
||||
@ -337,23 +334,23 @@ void CMainMenu::openCampaignLobby(std::shared_ptr<CCampaignState> campaign)
|
||||
CSH->resetStateForLobby(StartInfo::CAMPAIGN);
|
||||
CSH->screenType = ESelectionScreen::campaignList;
|
||||
CSH->campaignStateToSend = campaign;
|
||||
GH.pushInt(new CSimpleJoinScreen());
|
||||
GH.pushIntT<CSimpleJoinScreen>();
|
||||
}
|
||||
|
||||
void CMainMenu::openCampaignScreen(std::string name)
|
||||
{
|
||||
if(vstd::contains(CMainMenuConfig::get().getCampaigns().Struct(), name))
|
||||
{
|
||||
GH.pushInt(new CCampaignScreen(CMainMenuConfig::get().getCampaigns()[name]));
|
||||
GH.pushIntT<CCampaignScreen>(CMainMenuConfig::get().getCampaigns()[name]);
|
||||
return;
|
||||
}
|
||||
logGlobal->error("Unknown campaign set: %s", name);
|
||||
}
|
||||
|
||||
CMainMenu * CMainMenu::create()
|
||||
std::shared_ptr<CMainMenu> CMainMenu::create()
|
||||
{
|
||||
if(!CMM)
|
||||
CMM = new CMainMenu();
|
||||
CMM = std::shared_ptr<CMainMenu>(new CMainMenu());
|
||||
|
||||
GH.terminate_cond->set(false);
|
||||
return CMM;
|
||||
@ -381,19 +378,21 @@ CMultiMode::CMultiMode(ESelectionScreen ScreenType)
|
||||
buttonHotseat = std::make_shared<CButton>(Point(373, 78), "MUBHOT.DEF", CGI->generaltexth->zelp[266], std::bind(&CMultiMode::hostTCP, this));
|
||||
buttonHost = std::make_shared<CButton>(Point(373, 78 + 57 * 1), "MUBHOST.DEF", CButton::tooltip("Host TCP/IP game", ""), std::bind(&CMultiMode::hostTCP, this));
|
||||
buttonJoin = std::make_shared<CButton>(Point(373, 78 + 57 * 2), "MUBJOIN.DEF", CButton::tooltip("Join TCP/IP game", ""), std::bind(&CMultiMode::joinTCP, this));
|
||||
buttonCancel = std::make_shared<CButton>(Point(373, 424), "MUBCANC.DEF", CGI->generaltexth->zelp[288], [&]() { GH.popIntTotally(this);}, SDLK_ESCAPE);
|
||||
buttonCancel = std::make_shared<CButton>(Point(373, 424), "MUBCANC.DEF", CGI->generaltexth->zelp[288], [=](){ close();}, SDLK_ESCAPE);
|
||||
}
|
||||
|
||||
void CMultiMode::hostTCP()
|
||||
{
|
||||
GH.popIntTotally(this);
|
||||
GH.pushInt(new CMultiPlayers(settings["general"]["playerName"].String(), screenType, true, ELoadMode::MULTI));
|
||||
auto savedScreenType = screenType;
|
||||
close();
|
||||
GH.pushIntT<CMultiPlayers>(settings["general"]["playerName"].String(), savedScreenType, true, ELoadMode::MULTI);
|
||||
}
|
||||
|
||||
void CMultiMode::joinTCP()
|
||||
{
|
||||
GH.popIntTotally(this);
|
||||
GH.pushInt(new CMultiPlayers(settings["general"]["playerName"].String(), screenType, false, ELoadMode::MULTI));
|
||||
auto savedScreenType = screenType;
|
||||
close();
|
||||
GH.pushIntT<CMultiPlayers>(settings["general"]["playerName"].String(), savedScreenType, false, ELoadMode::MULTI);
|
||||
}
|
||||
|
||||
void CMultiMode::onNameChange(std::string newText)
|
||||
@ -420,7 +419,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);
|
||||
buttonCancel = std::make_shared<CButton>(Point(205, 338), "MUBCANC.DEF", CGI->generaltexth->zelp[561], [=](){ close();}, SDLK_ESCAPE);
|
||||
statusBar = std::make_shared<CGStatusBar>(std::make_shared<CPicture>(Rect(7, 381, 348, 18), 0)); //226, 472
|
||||
|
||||
inputNames[0]->setText(firstPlayer, true);
|
||||
@ -497,9 +496,9 @@ void CSimpleJoinScreen::leaveScreen()
|
||||
textTitle->setText("Closing...");
|
||||
CSH->state = EClientState::CONNECTION_CANCELLED;
|
||||
}
|
||||
else if(GH.listInt.size() && GH.listInt.front() == this)
|
||||
else if(GH.listInt.size() && GH.listInt.front().get() == this)
|
||||
{
|
||||
GH.popIntTotally(this);
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@ -516,9 +515,9 @@ void CSimpleJoinScreen::connectThread(const std::string addr, const ui16 port)
|
||||
else
|
||||
CSH->justConnectToServer(addr, port);
|
||||
|
||||
if(GH.listInt.size() && GH.listInt.front() == this)
|
||||
if(GH.listInt.size() && GH.listInt.front().get() == this)
|
||||
{
|
||||
GH.popIntTotally(this);
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,7 @@ public:
|
||||
};
|
||||
|
||||
/// Multiplayer mode
|
||||
class CMultiMode : public CIntObject
|
||||
class CMultiMode : public WindowBase
|
||||
{
|
||||
public:
|
||||
ESelectionScreen screenType;
|
||||
@ -89,7 +89,7 @@ public:
|
||||
};
|
||||
|
||||
/// Hot seat player window
|
||||
class CMultiPlayers : public CIntObject
|
||||
class CMultiPlayers : public WindowBase
|
||||
{
|
||||
bool host;
|
||||
ELoadMode loadMode;
|
||||
@ -124,14 +124,14 @@ private:
|
||||
};
|
||||
|
||||
/// Handles background screen, loads graphics for victory/loss condition and random town or hero selection
|
||||
class CMainMenu : public CIntObject, public IUpdateable
|
||||
class CMainMenu : public CIntObject, public IUpdateable, public std::enable_shared_from_this<CMainMenu>
|
||||
{
|
||||
std::shared_ptr<CFilledTexture> backgroundAroundMenu;
|
||||
|
||||
CMainMenu(); //Use CMainMenu::create
|
||||
|
||||
public:
|
||||
CMenuScreen * menu;
|
||||
std::shared_ptr<CMenuScreen> menu;
|
||||
|
||||
~CMainMenu();
|
||||
void update() override;
|
||||
@ -140,14 +140,14 @@ public:
|
||||
static void openCampaignLobby(std::shared_ptr<CCampaignState> campaign);
|
||||
void openCampaignScreen(std::string name);
|
||||
|
||||
static CMainMenu * create();
|
||||
static std::shared_ptr<CMainMenu> create();
|
||||
|
||||
static std::shared_ptr<CPicture> createPicture(const JsonNode & config);
|
||||
|
||||
};
|
||||
|
||||
/// Simple window to enter the server's address.
|
||||
class CSimpleJoinScreen : public CIntObject
|
||||
class CSimpleJoinScreen : public WindowBase
|
||||
{
|
||||
std::shared_ptr<CPicture> background;
|
||||
std::shared_ptr<CTextBox> textTitle;
|
||||
@ -179,4 +179,4 @@ public:
|
||||
void showAll(SDL_Surface * to) override;
|
||||
};
|
||||
|
||||
extern CMainMenu * CMM;
|
||||
extern std::shared_ptr<CMainMenu> CMM;
|
||||
|
@ -58,7 +58,7 @@ void CPrologEpilogVideo::show(SDL_Surface * to)
|
||||
|
||||
void CPrologEpilogVideo::clickLeft(tribool down, bool previousState)
|
||||
{
|
||||
GH.popInt(this);
|
||||
close();
|
||||
CCS->soundh->stopSound(voiceSoundHandle);
|
||||
exitCb();
|
||||
}
|
||||
|
@ -1250,21 +1250,16 @@ void CAdvMapPanel::addChildToPanel(std::shared_ptr<CIntObject> obj, ui8 actions)
|
||||
CAdvMapWorldViewPanel::CAdvMapWorldViewPanel(std::shared_ptr<CAnimation> _icons, SDL_Surface * bg, Point position, int spaceBottom, const PlayerColor &color)
|
||||
: CAdvMapPanel(bg, position), icons(_icons)
|
||||
{
|
||||
fillerHeight = bg ? spaceBottom - pos.y - pos.h : 0;
|
||||
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
|
||||
int fillerHeight = bg ? spaceBottom - pos.y - pos.h : 0;
|
||||
|
||||
if (fillerHeight > 0)
|
||||
if(fillerHeight > 0)
|
||||
{
|
||||
tmpBackgroundFiller = CMessage::drawDialogBox(pos.w, fillerHeight, color);
|
||||
backgroundFiller = std::make_shared<CFilledTexture>("DIBOXBCK", Rect(0, pos.h, pos.w, fillerHeight));
|
||||
}
|
||||
else
|
||||
tmpBackgroundFiller = nullptr;
|
||||
}
|
||||
|
||||
CAdvMapWorldViewPanel::~CAdvMapWorldViewPanel()
|
||||
{
|
||||
if (tmpBackgroundFiller)
|
||||
SDL_FreeSurface(tmpBackgroundFiller);
|
||||
}
|
||||
CAdvMapWorldViewPanel::~CAdvMapWorldViewPanel() = default;
|
||||
|
||||
void CAdvMapWorldViewPanel::recolorIcons(const PlayerColor & color, int indexOffset)
|
||||
{
|
||||
@ -1275,13 +1270,6 @@ void CAdvMapWorldViewPanel::recolorIcons(const PlayerColor & color, int indexOff
|
||||
const auto & data = iconsData.at(idx);
|
||||
currentIcons[idx]->setFrame(data.first + indexOffset);
|
||||
}
|
||||
|
||||
if(fillerHeight > 0)
|
||||
{
|
||||
if(tmpBackgroundFiller)
|
||||
SDL_FreeSurface(tmpBackgroundFiller);
|
||||
tmpBackgroundFiller = CMessage::drawDialogBox(pos.w, fillerHeight, color);
|
||||
}
|
||||
}
|
||||
|
||||
void CAdvMapWorldViewPanel::addChildIcon(std::pair<int, Point> data, int indexOffset)
|
||||
@ -1290,13 +1278,3 @@ void CAdvMapWorldViewPanel::addChildIcon(std::pair<int, Point> data, int indexOf
|
||||
iconsData.push_back(data);
|
||||
currentIcons.push_back(std::make_shared<CAnimImage>(icons, data.first + indexOffset, 0, data.second.x, data.second.y));
|
||||
}
|
||||
|
||||
void CAdvMapWorldViewPanel::showAll(SDL_Surface * to)
|
||||
{
|
||||
if (tmpBackgroundFiller)
|
||||
{
|
||||
blitAt(tmpBackgroundFiller, pos.x, pos.y + pos.h, to);
|
||||
}
|
||||
|
||||
CAdvMapPanel::showAll(to);
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ class CArmedInstance;
|
||||
class CAnimation;
|
||||
class CAnimImage;
|
||||
class CShowableAnim;
|
||||
class CFilledTexture;
|
||||
class CGGarrison;
|
||||
class CGObjectInstance;
|
||||
class CGHeroInstance;
|
||||
@ -384,9 +385,8 @@ class CAdvMapWorldViewPanel : public CAdvMapPanel
|
||||
std::vector<std::pair<int, Point>> iconsData;
|
||||
/// ptrs to child-pictures constructed from iconsData
|
||||
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;
|
||||
/// surface drawn below world view panel on higher resolutions (won't be needed when world view panel is configured for extraResolutions mod)
|
||||
std::shared_ptr<CFilledTexture> backgroundFiller;
|
||||
std::shared_ptr<CAnimation> icons;
|
||||
public:
|
||||
CAdvMapWorldViewPanel(std::shared_ptr<CAnimation> _icons, SDL_Surface * bg, Point position, int spaceBottom, const PlayerColor &color);
|
||||
@ -395,7 +395,6 @@ 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 showAll(SDL_Surface * to) override;
|
||||
};
|
||||
|
||||
class CInGameConsole : public CIntObject
|
||||
|
@ -126,7 +126,7 @@ void CHeroArtPlace::clickLeft(tribool down, bool previousState)
|
||||
if(ourArt && !down && previousState && !ourOwner->commonInfo->src.AOH)
|
||||
{
|
||||
if(ourArt->artType->id == ArtifactID::SPELLBOOK)
|
||||
GH.pushInt(new CSpellWindow(ourOwner->curHero, LOCPLINT, LOCPLINT->battleInt));
|
||||
GH.pushIntT<CSpellWindow>(ourOwner->curHero, LOCPLINT, LOCPLINT->battleInt);
|
||||
}
|
||||
|
||||
if (!down && previousState)
|
||||
@ -678,14 +678,14 @@ CArtifactsOfHero::~CArtifactsOfHero()
|
||||
|
||||
void CArtifactsOfHero::updateParentWindow()
|
||||
{
|
||||
if (CHeroWindow* chw = dynamic_cast<CHeroWindow*>(GH.topInt()))
|
||||
if (CHeroWindow* chw = dynamic_cast<CHeroWindow*>(GH.topInt().get()))
|
||||
{
|
||||
if(updateState)
|
||||
chw->curHero = curHero;
|
||||
else
|
||||
chw->update(curHero, true);
|
||||
}
|
||||
else if(CExchangeWindow* cew = dynamic_cast<CExchangeWindow*>(GH.topInt()))
|
||||
else if(CExchangeWindow* cew = dynamic_cast<CExchangeWindow*>(GH.topInt().get()))
|
||||
{
|
||||
//use our copy of hero to draw window
|
||||
if(cew->heroInst[0]->id == curHero->id)
|
||||
|
@ -161,7 +161,7 @@ bool CGarrisonSlot::viewInfo()
|
||||
elem->block(true);
|
||||
|
||||
redraw();
|
||||
GH.pushInt(new CStackWindow(myStack, dism, pom, upgr));
|
||||
GH.pushIntT<CStackWindow>(myStack, dism, pom, upgr);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -170,7 +170,7 @@ bool CGarrisonSlot::viewInfo()
|
||||
bool CGarrisonSlot::highlightOrDropArtifact()
|
||||
{
|
||||
bool artSelected = false;
|
||||
if (CWindowWithArtifacts* chw = dynamic_cast<CWindowWithArtifacts*>(GH.topInt())) //dirty solution
|
||||
if (CWindowWithArtifacts* chw = dynamic_cast<CWindowWithArtifacts*>(GH.topInt().get())) //dirty solution
|
||||
{
|
||||
const std::shared_ptr<CArtifactsOfHero::SCommonPart> commonInfo = chw->getCommonPart();
|
||||
const CArtifactInstance * art = nullptr;
|
||||
@ -241,8 +241,8 @@ bool CGarrisonSlot::split()
|
||||
int countLeft = selection->myStack ? selection->myStack->count : 0;
|
||||
int countRight = myStack ? myStack->count : 0;
|
||||
|
||||
GH.pushInt(new CSplitWindow(selection->creature, std::bind(&CGarrisonInt::splitStacks, owner, _1, _2),
|
||||
minLeft, minRight, countLeft, countRight));
|
||||
GH.pushIntT<CSplitWindow>(selection->creature, std::bind(&CGarrisonInt::splitStacks, owner, _1, _2),
|
||||
minLeft, minRight, countLeft, countRight);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -278,7 +278,7 @@ void CGarrisonSlot::clickRight(tribool down, bool previousState)
|
||||
{
|
||||
if(creature && down)
|
||||
{
|
||||
GH.pushInt(new CStackWindow(myStack, true));
|
||||
GH.pushIntT<CStackWindow>(myStack, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -173,7 +173,7 @@ void CPicture::createSimpleRect(const Rect &r, bool screenFormat, ui32 color)
|
||||
if(screenFormat)
|
||||
bg = CSDL_Ext::newSurface(r.w, r.h);
|
||||
else
|
||||
bg = SDL_CreateRGBSurface(SDL_SWSURFACE, r.w, r.h, 8, 0, 0, 0, 0);
|
||||
bg = SDL_CreateRGBSurface(0, r.w, r.h, 8, 0, 0, 0, 0);
|
||||
|
||||
SDL_FillRect(bg, nullptr, color);
|
||||
freeSurf = true;
|
||||
@ -296,7 +296,7 @@ void CAnimImage::playerColored(PlayerColor currPlayer)
|
||||
}
|
||||
|
||||
CShowableAnim::CShowableAnim(int x, int y, std::string name, ui8 Flags, ui32 Delay, size_t Group):
|
||||
anim(new CAnimation(name, Flags & USE_RLE)),
|
||||
anim(std::make_shared<CAnimation>(name)),
|
||||
group(Group),
|
||||
frame(0),
|
||||
first(0),
|
||||
@ -319,7 +319,6 @@ CShowableAnim::CShowableAnim(int x, int y, std::string name, ui8 Flags, ui32 Del
|
||||
CShowableAnim::~CShowableAnim()
|
||||
{
|
||||
anim->unloadGroup(group);
|
||||
delete anim;
|
||||
}
|
||||
|
||||
void CShowableAnim::setAlpha(ui32 alphaValue)
|
||||
@ -410,8 +409,8 @@ void CShowableAnim::blitImage(size_t frame, size_t group, SDL_Surface *to)
|
||||
assert(to);
|
||||
Rect src( xOffset, yOffset, pos.w, pos.h);
|
||||
auto img = anim->getImage(frame, group);
|
||||
if (img)
|
||||
img->draw(to, pos.x-xOffset, pos.y-yOffset, &src, alpha);
|
||||
if(img)
|
||||
img->draw(to, pos.x, pos.y, &src, alpha);
|
||||
}
|
||||
|
||||
void CShowableAnim::rotate(bool on, bool vertical)
|
||||
@ -423,15 +422,11 @@ void CShowableAnim::rotate(bool on, bool vertical)
|
||||
flags &= ~flag;
|
||||
}
|
||||
|
||||
CCreatureAnim::CCreatureAnim(int x, int y, std::string name, Rect picPos, ui8 flags, EAnimType type):
|
||||
CCreatureAnim::CCreatureAnim(int x, int y, std::string name, ui8 flags, EAnimType type):
|
||||
CShowableAnim(x,y,name,flags,4,type)
|
||||
{
|
||||
xOffset = picPos.x;
|
||||
yOffset = picPos.y;
|
||||
if (picPos.w)
|
||||
pos.w = picPos.w;
|
||||
if (picPos.h)
|
||||
pos.h = picPos.h;
|
||||
xOffset = 0;
|
||||
yOffset = 0;
|
||||
}
|
||||
|
||||
void CCreatureAnim::loopPreview(bool warMachine)
|
||||
|
@ -105,12 +105,11 @@ public:
|
||||
BASE=1, //base frame will be blitted before current one
|
||||
HORIZONTAL_FLIP=2, //TODO: will be displayed rotated
|
||||
VERTICAL_FLIP=4, //TODO: will be displayed rotated
|
||||
USE_RLE=8, //RLE-d version, support full alpha-channel for 8-bit images
|
||||
PLAYER_COLORED=16, //TODO: all loaded images will be player-colored
|
||||
PLAY_ONCE=32 //play animation only once and stop at last frame
|
||||
};
|
||||
protected:
|
||||
CAnimation * anim;
|
||||
std::shared_ptr<CAnimation> anim;
|
||||
|
||||
size_t group, frame;//current frame
|
||||
|
||||
@ -227,7 +226,6 @@ public:
|
||||
//clear queue and set animation to this sequence
|
||||
void clearAndSet(EAnimType type);
|
||||
|
||||
CCreatureAnim(int x, int y, std::string name, Rect picPos,
|
||||
ui8 flags= USE_RLE, EAnimType = HOLDING );
|
||||
CCreatureAnim(int x, int y, std::string name, ui8 flags = 0, EAnimType = HOLDING);
|
||||
|
||||
};
|
||||
|
@ -457,7 +457,7 @@ CCreaturePic::CCreaturePic(int x, int y, const CCreature * cre, bool Big, bool A
|
||||
bg = std::make_shared<CPicture>(CGI->townh->factions[faction]->creatureBg130);
|
||||
else
|
||||
bg = std::make_shared<CPicture>(CGI->townh->factions[faction]->creatureBg120);
|
||||
anim = std::make_shared<CCreatureAnim>(0, 0, cre->animDefName, Rect());
|
||||
anim = std::make_shared<CCreatureAnim>(0, 0, cre->animDefName);
|
||||
anim->clipRect(cre->isDoubleWide()?170:150, 155, bg->pos.w, bg->pos.h);
|
||||
anim->startPreview(cre->hasBonusOfType(Bonus::SIEGE_WEAPON));
|
||||
|
||||
|
@ -59,7 +59,7 @@
|
||||
#define ADVOPT (conf.go()->ac)
|
||||
using namespace CSDL_Ext;
|
||||
|
||||
CAdvMapInt *adventureInt;
|
||||
std::shared_ptr<CAdvMapInt> adventureInt;
|
||||
|
||||
static void setScrollingCursor(ui8 direction)
|
||||
{
|
||||
@ -565,7 +565,6 @@ CAdvMapInt::CAdvMapInt():
|
||||
swipeEnabled(settings["general"]["swipe"].Bool()), swipeMovementRequested(false),
|
||||
swipeTargetPosition(int3(-1, -1, -1))
|
||||
{
|
||||
adventureInt = this;
|
||||
pos.x = pos.y = 0;
|
||||
pos.w = screen->w;
|
||||
pos.h = screen->h;
|
||||
@ -723,7 +722,7 @@ CAdvMapInt::~CAdvMapInt()
|
||||
|
||||
void CAdvMapInt::fshowOverview()
|
||||
{
|
||||
GH.pushInt(new CKingdomInterface());
|
||||
GH.pushIntT<CKingdomInterface>();
|
||||
}
|
||||
|
||||
void CAdvMapInt::fworldViewBack()
|
||||
@ -811,17 +810,17 @@ void CAdvMapInt::fshowSpellbok()
|
||||
|
||||
centerOn(selection);
|
||||
|
||||
GH.pushInt(new CSpellWindow(curHero(), LOCPLINT, false));
|
||||
GH.pushIntT<CSpellWindow>(curHero(), LOCPLINT, false);
|
||||
}
|
||||
|
||||
void CAdvMapInt::fadventureOPtions()
|
||||
{
|
||||
GH.pushInt(new CAdventureOptions());
|
||||
GH.pushIntT<CAdventureOptions>();
|
||||
}
|
||||
|
||||
void CAdvMapInt::fsystemOptions()
|
||||
{
|
||||
GH.pushInt(new CSystemOptionsWindow());
|
||||
GH.pushIntT<CSystemOptionsWindow>();
|
||||
}
|
||||
|
||||
void CAdvMapInt::fnextHero()
|
||||
@ -1088,7 +1087,7 @@ void CAdvMapInt::handleMapScrollingUpdate()
|
||||
int scrollSpeed = settings["adventure"]["scrollSpeed"].Float();
|
||||
//if advmap needs updating AND (no dialog is shown OR ctrl is pressed)
|
||||
if((animValHitCount % (4 / scrollSpeed)) == 0
|
||||
&& ((GH.topInt() == this) || isCtrlKeyDown()))
|
||||
&& ((GH.topInt().get() == this) || isCtrlKeyDown()))
|
||||
{
|
||||
if((scrollingDir & LEFT) && (position.x > -CGI->mh->frameW))
|
||||
position.x--;
|
||||
@ -1224,7 +1223,7 @@ void CAdvMapInt::keyPressed(const SDL_KeyboardEvent & key)
|
||||
return;
|
||||
case SDLK_s:
|
||||
if(isActive() && key.type == SDL_KEYUP)
|
||||
GH.pushInt(new CSavingScreen());
|
||||
GH.pushIntT<CSavingScreen>();
|
||||
return;
|
||||
case SDLK_d:
|
||||
{
|
||||
@ -1274,7 +1273,7 @@ void CAdvMapInt::keyPressed(const SDL_KeyboardEvent & key)
|
||||
}
|
||||
case SDLK_ESCAPE:
|
||||
{
|
||||
if(isActive() || GH.topInt() != this || !spellBeingCasted || key.state != SDL_PRESSED)
|
||||
if(isActive() || GH.topInt().get() != this || !spellBeingCasted || key.state != SDL_PRESSED)
|
||||
return;
|
||||
|
||||
leaveCastingMode();
|
||||
@ -1300,7 +1299,7 @@ void CAdvMapInt::keyPressed(const SDL_KeyboardEvent & key)
|
||||
}
|
||||
|
||||
if(townWithMarket) //if any town has marketplace, open window
|
||||
GH.pushInt(new CMarketplaceWindow(townWithMarket));
|
||||
GH.pushIntT<CMarketplaceWindow>(townWithMarket);
|
||||
else //if not - complain
|
||||
LOCPLINT->showInfoDialog("No available marketplace!");
|
||||
}
|
||||
@ -1957,11 +1956,11 @@ void CAdventureOptions::showScenarioInfo()
|
||||
{
|
||||
if(LOCPLINT->cb->getStartInfo()->campState)
|
||||
{
|
||||
GH.pushInt(new CBonusSelection());
|
||||
GH.pushIntT<CBonusSelection>();
|
||||
}
|
||||
else
|
||||
{
|
||||
GH.pushInt(new CScenarioInfoScreen());
|
||||
GH.pushIntT<CScenarioInfoScreen>();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -266,4 +266,4 @@ public:
|
||||
|
||||
};
|
||||
|
||||
extern CAdvMapInt *adventureInt;
|
||||
extern std::shared_ptr<CAdvMapInt> adventureInt;
|
||||
|
@ -41,13 +41,12 @@
|
||||
#include "../../lib/mapObjects/CGTownInstance.h"
|
||||
|
||||
CBuildingRect::CBuildingRect(CCastleBuildings * Par, const CGTownInstance * Town, const CStructure * Str)
|
||||
: CShowableAnim(0, 0, Str->defName, CShowableAnim::BASE | CShowableAnim::USE_RLE),
|
||||
: CShowableAnim(0, 0, Str->defName, CShowableAnim::BASE),
|
||||
parent(Par),
|
||||
town(Town),
|
||||
str(Str),
|
||||
stateCounter(80)
|
||||
{
|
||||
recActions = ACTIVATE | DEACTIVATE | DISPOSE | SHARE_POS;
|
||||
addUsedEvents(LCLICK | RCLICK | HOVER);
|
||||
pos.x += str->pos.x;
|
||||
pos.y += str->pos.y;
|
||||
@ -131,7 +130,7 @@ void CBuildingRect::clickRight(tribool down, bool previousState)
|
||||
else
|
||||
{
|
||||
int level = ( bid - BuildingID::DWELL_FIRST ) % GameConstants::CREATURES_PER_TOWN;
|
||||
GH.pushInt(new CDwellingInfoBox(parent->pos.x+parent->pos.w/2, parent->pos.y+parent->pos.h/2, town, level));
|
||||
GH.pushIntT<CDwellingInfoBox>(parent->pos.x+parent->pos.w/2, parent->pos.y+parent->pos.h/2, town, level);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -421,7 +420,7 @@ void CHeroGSlot::clickLeft(tribool down, bool previousState)
|
||||
{
|
||||
setHighlight(true);
|
||||
owner->garr->selectSlot(nullptr);
|
||||
showAll(screen2);
|
||||
redraw();
|
||||
}
|
||||
|
||||
//refresh statusbar
|
||||
@ -434,7 +433,7 @@ void CHeroGSlot::clickRight(tribool down, bool previousState)
|
||||
{
|
||||
if(hero && down)
|
||||
{
|
||||
GH.pushInt(new CInfoBoxPopup(Point(pos.x + 175, pos.y + 100), hero));
|
||||
GH.pushIntT<CInfoBoxPopup>(Point(pos.x + 175, pos.y + 100), hero);
|
||||
}
|
||||
}
|
||||
|
||||
@ -522,17 +521,26 @@ void HeroSlots::swapArmies()
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
class SORTHELP
|
||||
{
|
||||
public:
|
||||
bool operator() (const std::shared_ptr<T> a, const std::shared_ptr<T> b)
|
||||
bool operator() (const CIntObject * a, const CIntObject * b)
|
||||
{
|
||||
return (*a)<(*b);
|
||||
auto b1 = dynamic_cast<const CBuildingRect *>(a);
|
||||
auto b2 = dynamic_cast<const CBuildingRect *>(b);
|
||||
|
||||
if(!b1 && !b2)
|
||||
return intptr_t(a) < intptr_t(b);
|
||||
if(b1 && !b2)
|
||||
return false;
|
||||
if(!b1 && b2)
|
||||
return true;
|
||||
|
||||
return (*b1)<(*b2);
|
||||
}
|
||||
};
|
||||
|
||||
SORTHELP<CBuildingRect> buildSorter;
|
||||
SORTHELP buildSorter;
|
||||
|
||||
CCastleBuildings::CCastleBuildings(const CGTownInstance* Town):
|
||||
town(Town),
|
||||
@ -552,8 +560,7 @@ CCastleBuildings::~CCastleBuildings() = default;
|
||||
void CCastleBuildings::recreate()
|
||||
{
|
||||
selectedBuilding = nullptr;
|
||||
//TODO: remove show[all] method and try UPDATE+SHOWALL
|
||||
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(ACTIVATE+SHARE_POS);
|
||||
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
|
||||
|
||||
buildings.clear();
|
||||
groups.clear();
|
||||
@ -600,7 +607,8 @@ void CCastleBuildings::recreate()
|
||||
|
||||
buildings.push_back(std::make_shared<CBuildingRect>(this, town, toAdd));
|
||||
}
|
||||
boost::sort(buildings, buildSorter);
|
||||
|
||||
boost::sort(children, buildSorter); //TODO: create building in blit order
|
||||
}
|
||||
|
||||
void CCastleBuildings::addBuilding(BuildingID building)
|
||||
@ -632,20 +640,6 @@ void CCastleBuildings::removeBuilding(BuildingID building)
|
||||
recreate();
|
||||
}
|
||||
|
||||
void CCastleBuildings::show(SDL_Surface * to)
|
||||
{
|
||||
CIntObject::show(to);
|
||||
for(auto str : buildings)
|
||||
str->show(to);
|
||||
}
|
||||
|
||||
void CCastleBuildings::showAll(SDL_Surface * to)
|
||||
{
|
||||
CIntObject::showAll(to);
|
||||
for(auto str : buildings)
|
||||
str->showAll(to);
|
||||
}
|
||||
|
||||
const CGHeroInstance * CCastleBuildings::getHero()
|
||||
{
|
||||
if(town->visitingHero)
|
||||
@ -689,7 +683,7 @@ void CCastleBuildings::buildingClicked(BuildingID building)
|
||||
case BuildingID::FORT:
|
||||
case BuildingID::CITADEL:
|
||||
case BuildingID::CASTLE:
|
||||
GH.pushInt(new CFortScreen(town));
|
||||
GH.pushIntT<CFortScreen>(town);
|
||||
break;
|
||||
|
||||
case BuildingID::VILLAGE_HALL:
|
||||
@ -700,7 +694,7 @@ void CCastleBuildings::buildingClicked(BuildingID building)
|
||||
break;
|
||||
|
||||
case BuildingID::MARKETPLACE:
|
||||
GH.pushInt(new CMarketplaceWindow(town, town->visitingHero));
|
||||
GH.pushIntT<CMarketplaceWindow>(town, town->visitingHero);
|
||||
break;
|
||||
|
||||
case BuildingID::BLACKSMITH:
|
||||
@ -718,7 +712,7 @@ void CCastleBuildings::buildingClicked(BuildingID building)
|
||||
case ETownType::DUNGEON://Artifact Merchant
|
||||
case ETownType::CONFLUX:
|
||||
if(town->visitingHero)
|
||||
GH.pushInt(new CMarketplaceWindow(town, town->visitingHero, EMarketMode::RESOURCE_ARTIFACT));
|
||||
GH.pushIntT<CMarketplaceWindow>(town, town->visitingHero, EMarketMode::RESOURCE_ARTIFACT);
|
||||
else
|
||||
LOCPLINT->showInfoDialog(boost::str(boost::format(CGI->generaltexth->allTexts[273]) % b->Name())); //Only visiting heroes may use the %s.
|
||||
break;
|
||||
@ -742,14 +736,14 @@ void CCastleBuildings::buildingClicked(BuildingID building)
|
||||
|
||||
case ETownType::STRONGHOLD: //Freelancer's Guild
|
||||
if(getHero())
|
||||
GH.pushInt(new CMarketplaceWindow(town, getHero(), EMarketMode::CREATURE_RESOURCE));
|
||||
GH.pushIntT<CMarketplaceWindow>(town, getHero(), EMarketMode::CREATURE_RESOURCE);
|
||||
else
|
||||
LOCPLINT->showInfoDialog(boost::str(boost::format(CGI->generaltexth->allTexts[273]) % b->Name())); //Only visiting heroes may use the %s.
|
||||
break;
|
||||
|
||||
case ETownType::CONFLUX: //Magic University
|
||||
if (getHero())
|
||||
GH.pushInt(new CUniversityWindow(getHero(), town));
|
||||
GH.pushIntT<CUniversityWindow>(getHero(), town);
|
||||
else
|
||||
enterBuilding(building);
|
||||
break;
|
||||
@ -772,7 +766,7 @@ void CCastleBuildings::buildingClicked(BuildingID building)
|
||||
break;
|
||||
|
||||
case ETownType::NECROPOLIS: //Skeleton Transformer
|
||||
GH.pushInt( new CTransformerWindow(getHero(), town) );
|
||||
GH.pushIntT<CTransformerWindow>(getHero(), town);
|
||||
break;
|
||||
|
||||
case ETownType::DUNGEON: //Portal of Summoning
|
||||
@ -810,7 +804,7 @@ void CCastleBuildings::enterBlacksmith(ArtifactID artifactID)
|
||||
int price = CGI->arth->artifacts[artifactID]->price;
|
||||
bool possible = LOCPLINT->cb->getResourceAmount(Res::GOLD) >= price && !hero->hasArt(artifactID);
|
||||
CreatureID cre = artifactID.toArtifact()->warMachine;
|
||||
GH.pushInt(new CBlacksmithDialog(possible, cre, artifactID, hero->id));
|
||||
GH.pushIntT<CBlacksmithDialog>(possible, cre, artifactID, hero->id);
|
||||
}
|
||||
|
||||
void CCastleBuildings::enterBuilding(BuildingID building)
|
||||
@ -838,20 +832,20 @@ void CCastleBuildings::enterCastleGate()
|
||||
}
|
||||
}
|
||||
auto gateIcon = std::make_shared<CAnimImage>(town->town->clientInfo.buildingsIcons, BuildingID::CASTLE_GATE);//will be deleted by selection window
|
||||
GH.pushInt(new CObjectListWindow(availableTowns, gateIcon, CGI->generaltexth->jktexts[40],
|
||||
CGI->generaltexth->jktexts[41], std::bind (&CCastleInterface::castleTeleport, LOCPLINT->castleInt, _1)));
|
||||
GH.pushIntT<CObjectListWindow>(availableTowns, gateIcon, CGI->generaltexth->jktexts[40],
|
||||
CGI->generaltexth->jktexts[41], std::bind (&CCastleInterface::castleTeleport, LOCPLINT->castleInt, _1));
|
||||
}
|
||||
|
||||
void CCastleBuildings::enterDwelling(int level)
|
||||
{
|
||||
assert(level >= 0 && level < town->creatures.size());
|
||||
auto recruitCb = [=](CreatureID id, int count){ LOCPLINT->cb->recruitCreatures(town, town->getUpperArmy(), id, count, level); };
|
||||
GH.pushInt(new CRecruitmentWindow(town, level, town, recruitCb, -87));
|
||||
GH.pushIntT<CRecruitmentWindow>(town, level, town, recruitCb, -87);
|
||||
}
|
||||
|
||||
void CCastleBuildings::enterToTheQuickRecruitmentWindow()
|
||||
{
|
||||
GH.pushInt(new QuickRecruitmentWindow(town, pos));
|
||||
GH.pushIntT<QuickRecruitmentWindow>(town, pos);
|
||||
}
|
||||
|
||||
void CCastleBuildings::enterFountain(BuildingID building)
|
||||
@ -915,7 +909,7 @@ void CCastleBuildings::enterTownHall()
|
||||
else
|
||||
{
|
||||
LOCPLINT->showInfoDialog(CGI->generaltexth->allTexts[673]);
|
||||
dynamic_cast<CInfoWindow*>(GH.topInt())->buttons[0]->addCallback(std::bind(&CCastleBuildings::openTownHall, this));
|
||||
dynamic_cast<CInfoWindow*>(GH.topInt().get())->buttons[0]->addCallback(std::bind(&CCastleBuildings::openTownHall, this));
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -928,12 +922,12 @@ void CCastleBuildings::openMagesGuild()
|
||||
{
|
||||
std::string mageGuildBackground;
|
||||
mageGuildBackground = LOCPLINT->castleInt->town->town->clientInfo.guildBackground;
|
||||
GH.pushInt(new CMageGuildScreen(LOCPLINT->castleInt,mageGuildBackground));
|
||||
GH.pushIntT<CMageGuildScreen>(LOCPLINT->castleInt,mageGuildBackground);
|
||||
}
|
||||
|
||||
void CCastleBuildings::openTownHall()
|
||||
{
|
||||
GH.pushInt(new CHallInterface(town));
|
||||
GH.pushIntT<CHallInterface>(town);
|
||||
}
|
||||
|
||||
CCreaInfo::CCreaInfo(Point position, const CGTownInstance * Town, int Level, bool compact, bool ShowAvailable):
|
||||
@ -1016,7 +1010,7 @@ void CCreaInfo::clickLeft(tribool down, bool previousState)
|
||||
{
|
||||
LOCPLINT->cb->recruitCreatures(town, town->getUpperArmy(), id, count, level);
|
||||
};
|
||||
GH.pushInt(new CRecruitmentWindow(town, level, town, recruitCb, offset));
|
||||
GH.pushIntT<CRecruitmentWindow>(town, level, town, recruitCb, offset);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1036,7 +1030,7 @@ void CCreaInfo::clickRight(tribool down, bool previousState)
|
||||
if(down)
|
||||
{
|
||||
if (showAvailable)
|
||||
GH.pushInt(new CDwellingInfoBox(screen->w/2, screen->h/2, town, level));
|
||||
GH.pushIntT<CDwellingInfoBox>(screen->w/2, screen->h/2, town, level);
|
||||
else
|
||||
CRClickPopup::createAndPush(genGrowthText(), std::make_shared<CComponent>(CComponent::creature, creature->idNumber));
|
||||
}
|
||||
@ -1141,7 +1135,8 @@ CCastleInterface::CCastleInterface(const CGTownInstance * Town, const CGTownInst
|
||||
|
||||
CCastleInterface::~CCastleInterface()
|
||||
{
|
||||
LOCPLINT->castleInt = nullptr;
|
||||
if(LOCPLINT->castleInt == this)
|
||||
LOCPLINT->castleInt = nullptr;
|
||||
}
|
||||
|
||||
void CCastleInterface::updateGarrisons()
|
||||
@ -1170,12 +1165,13 @@ void CCastleInterface::castleTeleport(int where)
|
||||
|
||||
void CCastleInterface::townChange()
|
||||
{
|
||||
//TODO: do not recreate window
|
||||
const CGTownInstance * dest = LOCPLINT->towns[townlist->getSelectedIndex()];
|
||||
const CGTownInstance * town = this->town;// "this" is going to be deleted
|
||||
if ( dest == town )
|
||||
return;
|
||||
close();
|
||||
GH.pushInt(new CCastleInterface(dest, town));
|
||||
GH.pushIntT<CCastleInterface>(dest, town);
|
||||
}
|
||||
|
||||
void CCastleInterface::addBuilding(BuildingID bid)
|
||||
@ -1299,13 +1295,13 @@ void CHallInterface::CBuildingBox::hover(bool on)
|
||||
void CHallInterface::CBuildingBox::clickLeft(tribool down, bool previousState)
|
||||
{
|
||||
if(previousState && (!down))
|
||||
GH.pushInt(new CBuildWindow(town,building,state,0));
|
||||
GH.pushIntT<CBuildWindow>(town,building,state,0);
|
||||
}
|
||||
|
||||
void CHallInterface::CBuildingBox::clickRight(tribool down, bool previousState)
|
||||
{
|
||||
if(down)
|
||||
GH.pushInt(new CBuildWindow(town,building,state,1));
|
||||
GH.pushIntT<CBuildWindow>(town,building,state,1);
|
||||
}
|
||||
|
||||
CHallInterface::CHallInterface(const CGTownInstance * Town):
|
||||
@ -1756,7 +1752,7 @@ CBlacksmithDialog::CBlacksmithDialog(bool possible, CreatureID creMachineID, Art
|
||||
animBG->needRefresh = true;
|
||||
|
||||
const CCreature * creature = CGI->creh->creatures[creMachineID];
|
||||
anim = std::make_shared<CCreatureAnim>(64, 50, creature->animDefName, Rect());
|
||||
anim = std::make_shared<CCreatureAnim>(64, 50, creature->animDefName);
|
||||
anim->clipRect(113,125,200,150);
|
||||
|
||||
title = std::make_shared<CLabel>(165, 28, FONT_BIG, CENTER, Colors::YELLOW,
|
||||
|
@ -156,9 +156,6 @@ public:
|
||||
void buildingClicked(BuildingID building);
|
||||
void addBuilding(BuildingID building);
|
||||
void removeBuilding(BuildingID building);//FIXME: not tested!!!
|
||||
|
||||
void show(SDL_Surface * to) override;
|
||||
void showAll(SDL_Surface * to) override;
|
||||
};
|
||||
|
||||
/// Creature info window
|
||||
|
@ -78,8 +78,8 @@ void CHeroSwitcher::clickLeft(tribool down, bool previousState)
|
||||
owner->update(hero, true);
|
||||
#else
|
||||
const CGHeroInstance * buf = hero;
|
||||
GH.popIntTotally(parent);
|
||||
GH.pushInt(new CHeroWindow(buf));
|
||||
GH.popInts(1);
|
||||
GH.pushIntT<CHeroWindow>(buf);
|
||||
#endif // 0
|
||||
}
|
||||
}
|
||||
@ -297,16 +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(auto isa : GH.listInt)
|
||||
{
|
||||
if(CExchangeWindow * cew = dynamic_cast<CExchangeWindow*>(isa))
|
||||
if(CExchangeWindow * cew = dynamic_cast<CExchangeWindow*>(isa.get()))
|
||||
{
|
||||
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.get()))
|
||||
noDismiss = true;
|
||||
}
|
||||
//if player only have one hero and no towns
|
||||
@ -374,7 +374,7 @@ void CHeroWindow::commanderWindow()
|
||||
}
|
||||
else
|
||||
{
|
||||
GH.pushInt(new CStackWindow(curHero->commander, false));
|
||||
GH.pushIntT<CStackWindow>(curHero->commander, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,8 +40,7 @@ void CQuestLabel::clickLeft(tribool down, bool previousState)
|
||||
|
||||
void CQuestLabel::showAll(SDL_Surface * to)
|
||||
{
|
||||
if (active)
|
||||
CMultiLineLabel::showAll (to);
|
||||
CMultiLineLabel::showAll (to);
|
||||
}
|
||||
|
||||
CQuestIcon::CQuestIcon (const std::string &defname, int index, int x, int y) :
|
||||
@ -204,8 +203,9 @@ void CQuestLog::recreateLabelList()
|
||||
void CQuestLog::showAll(SDL_Surface * to)
|
||||
{
|
||||
CWindowObject::showAll(to);
|
||||
if(labels.size() && labels[questIndex]->active)
|
||||
if(questIndex >= 0 && questIndex < labels.size())
|
||||
{
|
||||
//TODO: use child object to selection rect
|
||||
Rect rect = Rect::around(labels[questIndex]->pos);
|
||||
rect.x -= 2; // Adjustment needed as we want selection box on top of border in graphics
|
||||
rect.w += 2;
|
||||
|
@ -255,7 +255,7 @@ void CSpellWindow::fexitb()
|
||||
(myInt->battleInt ? myInt->spellbookSettings.spellbookLastTabBattle : myInt->spellbookSettings.spellbookLastTabAdvmap) = selectedTab;
|
||||
(myInt->battleInt ? myInt->spellbookSettings.spellbookLastPageBattle : myInt->spellbookSettings.spellbokLastPageAdvmap) = currentPage;
|
||||
|
||||
GH.popIntTotally(this);
|
||||
close();
|
||||
}
|
||||
|
||||
void CSpellWindow::fadvSpellsb()
|
||||
@ -414,13 +414,13 @@ void CSpellWindow::setCurrentPage(int value)
|
||||
void CSpellWindow::turnPageLeft()
|
||||
{
|
||||
if(settings["video"]["spellbookAnimation"].Bool())
|
||||
CCS->videoh->openAndPlayVideo("PGTRNLFT.SMK", pos.x+13, pos.y+15, screen);
|
||||
CCS->videoh->openAndPlayVideo("PGTRNLFT.SMK", pos.x+13, pos.y+15);
|
||||
}
|
||||
|
||||
void CSpellWindow::turnPageRight()
|
||||
{
|
||||
if(settings["video"]["spellbookAnimation"].Bool())
|
||||
CCS->videoh->openAndPlayVideo("PGTRNRGH.SMK", pos.x+13, pos.y+15, screen);
|
||||
CCS->videoh->openAndPlayVideo("PGTRNRGH.SMK", pos.x+13, pos.y+15);
|
||||
}
|
||||
|
||||
void CSpellWindow::keyPressed(const SDL_KeyboardEvent & key)
|
||||
@ -568,7 +568,7 @@ void CSpellWindow::SpellArea::clickLeft(tribool down, bool previousState)
|
||||
else //adventure spell
|
||||
{
|
||||
const CGHeroInstance * h = owner->myHero;
|
||||
GH.popInt(owner);
|
||||
GH.popInts(1);
|
||||
|
||||
auto guard = vstd::makeScopeGuard([this]()
|
||||
{
|
||||
|
@ -605,22 +605,19 @@ void CTradeWindow::setMode(EMarketMode::EMarketMode Mode)
|
||||
{
|
||||
const IMarket *m = market;
|
||||
const CGHeroInstance *h = hero;
|
||||
CTradeWindow *nwindow = nullptr;
|
||||
|
||||
GH.popIntTotally(this);
|
||||
close();
|
||||
|
||||
switch(Mode)
|
||||
{
|
||||
case EMarketMode::CREATURE_EXP:
|
||||
case EMarketMode::ARTIFACT_EXP:
|
||||
nwindow = new CAltarWindow(m, h, Mode);
|
||||
GH.pushIntT<CAltarWindow>(m, h, Mode);
|
||||
break;
|
||||
default:
|
||||
nwindow = new CMarketplaceWindow(m, h, Mode);
|
||||
GH.pushIntT<CMarketplaceWindow>(m, h, Mode);
|
||||
break;
|
||||
}
|
||||
|
||||
GH.pushInt(nwindow);
|
||||
}
|
||||
|
||||
void CTradeWindow::artifactSelected(CHeroArtPlace *slot)
|
||||
|
@ -34,8 +34,7 @@
|
||||
#include "../../lib/CGeneralTextHandler.h" //for Unicode related stuff
|
||||
|
||||
CWindowObject::CWindowObject(int options_, std::string imageName, Point centerAt):
|
||||
CIntObject(getUsedEvents(options_), Point()),
|
||||
shadow(nullptr),
|
||||
WindowBase(getUsedEvents(options_), Point()),
|
||||
options(options_),
|
||||
background(createBg(imageName, options & PLAYER_COLORED))
|
||||
{
|
||||
@ -56,7 +55,7 @@ CWindowObject::CWindowObject(int options_, std::string imageName, Point centerAt
|
||||
}
|
||||
|
||||
CWindowObject::CWindowObject(int options_, std::string imageName):
|
||||
CIntObject(getUsedEvents(options_), Point()),
|
||||
WindowBase(getUsedEvents(options_), Point()),
|
||||
options(options_),
|
||||
background(createBg(imageName, options_ & PLAYER_COLORED))
|
||||
{
|
||||
@ -122,10 +121,10 @@ void CWindowObject::setShadow(bool on)
|
||||
//size of shadow
|
||||
static const int size = 8;
|
||||
|
||||
if(on == bool(shadow))
|
||||
if(on == !shadowParts.empty())
|
||||
return;
|
||||
|
||||
shadow.reset();
|
||||
shadowParts.clear();
|
||||
|
||||
//object too small to cast shadow
|
||||
if(pos.h <= size || pos.w <= size)
|
||||
@ -214,15 +213,11 @@ void CWindowObject::setShadow(bool on)
|
||||
//generate "shadow" object with these 3 pieces in it
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
|
||||
shadow = std::make_shared<CIntObject>();
|
||||
}
|
||||
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255);
|
||||
shadowParts.push_back(std::make_shared<CPicture>(shadowCorner, shadowPos.x, shadowPos.y));
|
||||
shadowParts.push_back(std::make_shared<CPicture>(shadowRight, shadowPos.x, shadowStart.y));
|
||||
shadowParts.push_back(std::make_shared<CPicture>(shadowBottom, shadowStart.x, shadowPos.y));
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -238,11 +233,6 @@ void CWindowObject::showAll(SDL_Surface *to)
|
||||
CMessage::drawBorder(color, to, pos.w+28, pos.h+29, pos.x-14, pos.y-15);
|
||||
}
|
||||
|
||||
void CWindowObject::close()
|
||||
{
|
||||
GH.popIntTotally(this);
|
||||
}
|
||||
|
||||
void CWindowObject::clickRight(tribool down, bool previousState)
|
||||
{
|
||||
close();
|
||||
|
@ -11,13 +11,13 @@
|
||||
|
||||
#include "../gui/CIntObject.h"
|
||||
|
||||
/// Basic class for windows
|
||||
class CWindowObject : public CIntObject
|
||||
class CWindowObject : public WindowBase
|
||||
{
|
||||
std::shared_ptr<CPicture> createBg(std::string imageName, bool playerColored);
|
||||
int getUsedEvents(int options);
|
||||
|
||||
std::shared_ptr<CIntObject> shadow;
|
||||
std::vector<std::shared_ptr<CPicture>> shadowParts;
|
||||
|
||||
void setShadow(bool on);
|
||||
|
||||
int options;
|
||||
@ -25,8 +25,6 @@ class CWindowObject : public CIntObject
|
||||
protected:
|
||||
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
|
||||
|
@ -96,7 +96,7 @@ void CRecruitmentWindow::CCreatureCard::clickLeft(tribool down, bool previousSta
|
||||
void CRecruitmentWindow::CCreatureCard::clickRight(tribool down, bool previousState)
|
||||
{
|
||||
if(down)
|
||||
GH.pushInt(new CStackWindow(creature, true));
|
||||
GH.pushIntT<CStackWindow>(creature, true);
|
||||
}
|
||||
|
||||
void CRecruitmentWindow::CCreatureCard::showAll(SDL_Surface * to)
|
||||
@ -569,8 +569,7 @@ void CSystemOptionsWindow::selectGameRes()
|
||||
items.push_back(resX + 'x' + resY);
|
||||
}
|
||||
|
||||
GH.pushInt(new CObjectListWindow(items, nullptr, texts["label"].String(), texts["help"].String(),
|
||||
std::bind(&CSystemOptionsWindow::setGameRes, this, _1)));
|
||||
GH.pushIntT<CObjectListWindow>(items, nullptr, texts["label"].String(), texts["help"].String(), std::bind(&CSystemOptionsWindow::setGameRes, this, _1));
|
||||
}
|
||||
|
||||
void CSystemOptionsWindow::setGameRes(int index)
|
||||
@ -599,7 +598,7 @@ void CSystemOptionsWindow::bquitf()
|
||||
|
||||
void CSystemOptionsWindow::breturnf()
|
||||
{
|
||||
GH.popIntTotally(this);
|
||||
close();
|
||||
}
|
||||
|
||||
void CSystemOptionsWindow::bmainmenuf()
|
||||
@ -609,14 +608,14 @@ void CSystemOptionsWindow::bmainmenuf()
|
||||
|
||||
void CSystemOptionsWindow::bloadf()
|
||||
{
|
||||
GH.popIntTotally(this);
|
||||
close();
|
||||
LOCPLINT->proposeLoadingGame();
|
||||
}
|
||||
|
||||
void CSystemOptionsWindow::bsavef()
|
||||
{
|
||||
GH.popIntTotally(this);
|
||||
GH.pushInt(new CSavingScreen());
|
||||
close();
|
||||
GH.pushIntT<CSavingScreen>();
|
||||
}
|
||||
|
||||
void CSystemOptionsWindow::brestartf()
|
||||
@ -626,7 +625,7 @@ void CSystemOptionsWindow::brestartf()
|
||||
|
||||
void CSystemOptionsWindow::closeAndPushEvent(int eventType, int code)
|
||||
{
|
||||
GH.popIntTotally(this);
|
||||
close();
|
||||
GH.pushSDLEvent(eventType, code);
|
||||
}
|
||||
|
||||
@ -705,7 +704,7 @@ void CTavernWindow::recruitb()
|
||||
|
||||
void CTavernWindow::thievesguildb()
|
||||
{
|
||||
GH.pushInt( new CThievesGuildWindow(tavernObj) );
|
||||
GH.pushIntT<CThievesGuildWindow>(tavernObj);
|
||||
}
|
||||
|
||||
CTavernWindow::~CTavernWindow()
|
||||
@ -745,9 +744,7 @@ void CTavernWindow::HeroPortrait::clickLeft(tribool down, bool previousState)
|
||||
void CTavernWindow::HeroPortrait::clickRight(tribool down, bool previousState)
|
||||
{
|
||||
if(h && down)
|
||||
{
|
||||
GH.pushInt(new CRClickPopupInt(new CHeroWindow(h), true));
|
||||
}
|
||||
GH.pushIntT<CRClickPopupInt>(std::make_shared<CHeroWindow>(h));
|
||||
}
|
||||
|
||||
CTavernWindow::HeroPortrait::HeroPortrait(int & sel, int id, int x, int y, const CGHeroInstance * H)
|
||||
@ -990,7 +987,7 @@ CShipyardWindow::CShipyardWindow(const std::vector<si32> & cost, int state, int
|
||||
std::string boatFilenames[3] = {"AB01_", "AB02_", "AB03_"};
|
||||
|
||||
Point waterCenter = Point(bgWater->pos.x+bgWater->pos.w/2, bgWater->pos.y+bgWater->pos.h/2);
|
||||
bgShip = std::make_shared<CAnimImage>(boatFilenames[boatType], 0, 7, 120, 96, CShowableAnim::USE_RLE);
|
||||
bgShip = std::make_shared<CAnimImage>(boatFilenames[boatType], 0, 7, 120, 96, 0);
|
||||
bgShip->center(waterCenter);
|
||||
|
||||
// Create resource icons and costs.
|
||||
@ -1110,7 +1107,7 @@ void CTransformerWindow::CItem::clickLeft(tribool down, bool previousState)
|
||||
if(previousState && (!down))
|
||||
{
|
||||
move();
|
||||
parent->showAll(screen2);
|
||||
parent->redraw();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1152,7 +1149,7 @@ void CTransformerWindow::addAll()
|
||||
if(elem->left)
|
||||
elem->move();
|
||||
}
|
||||
showAll(screen2);
|
||||
redraw();
|
||||
}
|
||||
|
||||
void CTransformerWindow::updateGarrisons()
|
||||
@ -1215,10 +1212,7 @@ void CUniversityWindow::CItem::clickLeft(tribool down, bool previousState)
|
||||
if(previousState && (!down))
|
||||
{
|
||||
if(state() == 2)
|
||||
{
|
||||
auto win = new CUnivConfirmWindow(parent, ID, LOCPLINT->cb->getResourceAmount(Res::GOLD) >= 2000);
|
||||
GH.pushInt(win);
|
||||
}
|
||||
GH.pushIntT<CUnivConfirmWindow>(parent, ID, LOCPLINT->cb->getResourceAmount(Res::GOLD) >= 2000);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1813,14 +1807,14 @@ void CObjectListWindow::elementSelected()
|
||||
{
|
||||
std::function<void(int)> toCall = onSelect;//save
|
||||
int where = items[selected].first; //required variables
|
||||
GH.popIntTotally(this);//then destroy window
|
||||
close();//then destroy window
|
||||
toCall(where);//and send selected object
|
||||
}
|
||||
|
||||
void CObjectListWindow::exitPressed()
|
||||
{
|
||||
std::function<void()> toCall = onExit;//save
|
||||
GH.popIntTotally(this);//then destroy window
|
||||
close();//then destroy window
|
||||
if(toCall)
|
||||
toCall();
|
||||
}
|
||||
|
@ -161,7 +161,8 @@ CInfoWindow::CInfoWindow()
|
||||
|
||||
void CInfoWindow::close()
|
||||
{
|
||||
GH.popIntTotally(this);
|
||||
WindowBase::close();
|
||||
|
||||
if(LOCPLINT)
|
||||
LOCPLINT->showingDialog->setn(false);
|
||||
}
|
||||
@ -181,8 +182,7 @@ void CInfoWindow::showAll(SDL_Surface * to)
|
||||
|
||||
void CInfoWindow::showInfoDialog(const std::string &text, const TCompsInfo & components, PlayerColor player)
|
||||
{
|
||||
CInfoWindow * window = CInfoWindow::create(text, player, components);
|
||||
GH.pushInt(window);
|
||||
GH.pushInt(CInfoWindow::create(text, player, components));
|
||||
}
|
||||
|
||||
void CInfoWindow::showYesNoDialog(const std::string & text, const TCompsInfo & components, const CFunctionList<void( ) > &onYes, const CFunctionList<void()> &onNo, PlayerColor player)
|
||||
@ -191,7 +191,7 @@ void CInfoWindow::showYesNoDialog(const std::string & text, const TCompsInfo & c
|
||||
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, pom);
|
||||
std::shared_ptr<CInfoWindow> temp = std::make_shared<CInfoWindow>(text, player, components, pom);
|
||||
|
||||
temp->buttons[0]->addCallback( onYes );
|
||||
temp->buttons[1]->addCallback( onNo );
|
||||
@ -199,22 +199,11 @@ void CInfoWindow::showYesNoDialog(const std::string & text, const TCompsInfo & c
|
||||
GH.pushInt(temp);
|
||||
}
|
||||
|
||||
void CInfoWindow::showOkDialog(const std::string & text, const TCompsInfo & components, const std::function<void()> & onOk, PlayerColor player)
|
||||
std::shared_ptr<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 * 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 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, pom);
|
||||
return ret;
|
||||
return std::make_shared<CInfoWindow>(text, playerID, components, pom);
|
||||
}
|
||||
|
||||
std::string CInfoWindow::genText(std::string title, std::string description)
|
||||
@ -268,7 +257,7 @@ void CInfoPopup::close()
|
||||
{
|
||||
if(free)
|
||||
SDL_FreeSurface(bitmap);
|
||||
GH.popIntTotally(this);
|
||||
WindowBase::close();
|
||||
}
|
||||
|
||||
void CInfoPopup::show(SDL_Surface * to)
|
||||
@ -307,7 +296,7 @@ void CRClickPopup::clickRight(tribool down, bool previousState)
|
||||
|
||||
void CRClickPopup::close()
|
||||
{
|
||||
GH.popIntTotally(this);
|
||||
WindowBase::close();
|
||||
}
|
||||
|
||||
void CRClickPopup::createAndPush(const std::string &txt, const CInfoWindow::TCompsInfo &comps)
|
||||
@ -316,11 +305,11 @@ void CRClickPopup::createAndPush(const std::string &txt, const CInfoWindow::TCom
|
||||
if(settings["session"]["spectate"].Bool())//TODO: there must be better way to implement this
|
||||
player = PlayerColor(1);
|
||||
|
||||
CSimpleWindow * temp = new CInfoWindow(txt, player, comps);
|
||||
auto temp = std::make_shared<CInfoWindow>(txt, player, comps);
|
||||
temp->center(Point(GH.current->motion)); //center on mouse
|
||||
temp->fitToScreen(10);
|
||||
auto rcpi = new CRClickPopupInt(temp,true);
|
||||
GH.pushInt(rcpi);
|
||||
|
||||
GH.pushIntT<CRClickPopupInt>(temp);
|
||||
}
|
||||
|
||||
void CRClickPopup::createAndPush(const std::string & txt, std::shared_ptr<CComponent> component)
|
||||
@ -331,14 +320,16 @@ void CRClickPopup::createAndPush(const std::string & txt, std::shared_ptr<CCompo
|
||||
createAndPush(txt, intComps);
|
||||
}
|
||||
|
||||
void CRClickPopup::createAndPush(const CGObjectInstance *obj, const Point &p, EAlignment alignment)
|
||||
void CRClickPopup::createAndPush(const CGObjectInstance * obj, const Point & p, EAlignment alignment)
|
||||
{
|
||||
CIntObject *iWin = createInfoWin(p, obj); //try get custom infowindow for this obj
|
||||
auto iWin = createInfoWin(p, obj); //try get custom infowindow for this obj
|
||||
if(iWin)
|
||||
{
|
||||
GH.pushInt(iWin);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (adventureInt->curHero())
|
||||
if(adventureInt->curHero())
|
||||
CRClickPopup::createAndPush(obj->getHoverText(adventureInt->curHero()));
|
||||
else
|
||||
CRClickPopup::createAndPush(obj->getHoverText(LOCPLINT->playerID));
|
||||
@ -354,31 +345,20 @@ CRClickPopup::~CRClickPopup()
|
||||
{
|
||||
}
|
||||
|
||||
void CRClickPopupInt::show(SDL_Surface * to)
|
||||
{
|
||||
inner->show(to);
|
||||
}
|
||||
|
||||
CRClickPopupInt::CRClickPopupInt( IShowActivatable *our, bool deleteInt )
|
||||
CRClickPopupInt::CRClickPopupInt(std::shared_ptr<CIntObject> our)
|
||||
{
|
||||
CCS->curh->hide();
|
||||
defActions = SHOWALL | UPDATE;
|
||||
our->recActions = defActions;
|
||||
inner = our;
|
||||
delInner = deleteInt;
|
||||
addChild(our.get(), false);
|
||||
}
|
||||
|
||||
CRClickPopupInt::~CRClickPopupInt()
|
||||
{
|
||||
if(delInner)
|
||||
delete inner;
|
||||
|
||||
CCS->curh->show();
|
||||
}
|
||||
|
||||
void CRClickPopupInt::showAll(SDL_Surface * to)
|
||||
{
|
||||
inner->showAll(to);
|
||||
}
|
||||
|
||||
Point CInfoBoxPopup::toScreen(Point p)
|
||||
{
|
||||
vstd::abetween(p.x, adventureInt->terrain.pos.x + 100, adventureInt->terrain.pos.x + adventureInt->terrain.pos.w - 100);
|
||||
@ -417,7 +397,7 @@ CInfoBoxPopup::CInfoBoxPopup(Point position, const CGGarrison * garr)
|
||||
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
|
||||
std::shared_ptr<WindowBase> CRClickPopup::createInfoWin(Point position, const CGObjectInstance * specific) //specific=0 => draws info about selected town/hero
|
||||
{
|
||||
if(nullptr == specific)
|
||||
specific = adventureInt->selection;
|
||||
@ -431,13 +411,13 @@ CIntObject * CRClickPopup::createInfoWin(Point position, const CGObjectInstance
|
||||
switch(specific->ID)
|
||||
{
|
||||
case Obj::HERO:
|
||||
return new CInfoBoxPopup(position, dynamic_cast<const CGHeroInstance *>(specific));
|
||||
return std::make_shared<CInfoBoxPopup>(position, dynamic_cast<const CGHeroInstance *>(specific));
|
||||
case Obj::TOWN:
|
||||
return new CInfoBoxPopup(position, dynamic_cast<const CGTownInstance *>(specific));
|
||||
return std::make_shared<CInfoBoxPopup>(position, dynamic_cast<const CGTownInstance *>(specific));
|
||||
case Obj::GARRISON:
|
||||
case Obj::GARRISON2:
|
||||
return new CInfoBoxPopup(position, dynamic_cast<const CGGarrison *>(specific));
|
||||
return std::make_shared<CInfoBoxPopup>(position, dynamic_cast<const CGGarrison *>(specific));
|
||||
default:
|
||||
return nullptr;
|
||||
return std::shared_ptr<WindowBase>();
|
||||
}
|
||||
}
|
||||
|
@ -26,11 +26,11 @@ class CSlider;
|
||||
class CArmyTooltip;
|
||||
|
||||
// Window GUI class
|
||||
class CSimpleWindow : public CIntObject
|
||||
class CSimpleWindow : public WindowBase
|
||||
{
|
||||
public:
|
||||
SDL_Surface * bitmap; //background
|
||||
virtual void show(SDL_Surface * to) override;
|
||||
void show(SDL_Surface * to) override;
|
||||
CSimpleWindow():bitmap(nullptr){};
|
||||
virtual ~CSimpleWindow();
|
||||
};
|
||||
@ -58,16 +58,15 @@ public:
|
||||
|
||||
//use only before the game starts! (showYesNoDialog in LOCPLINT must be used then)
|
||||
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());
|
||||
static std::shared_ptr<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);
|
||||
};
|
||||
|
||||
/// popup displayed on R-click
|
||||
class CRClickPopup : public CIntObject
|
||||
class CRClickPopup : public WindowBase
|
||||
{
|
||||
public:
|
||||
virtual void close();
|
||||
@ -76,7 +75,7 @@ public:
|
||||
CRClickPopup();
|
||||
virtual ~CRClickPopup();
|
||||
|
||||
static CIntObject* createInfoWin(Point position, const CGObjectInstance * specific);
|
||||
static std::shared_ptr<WindowBase> 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, std::shared_ptr<CComponent> component);
|
||||
static void createAndPush(const CGObjectInstance * obj, const Point & p, EAlignment alignment = BOTTOMRIGHT);
|
||||
@ -85,13 +84,9 @@ public:
|
||||
/// popup displayed on R-click
|
||||
class CRClickPopupInt : public CRClickPopup
|
||||
{
|
||||
std::shared_ptr<CIntObject> inner;
|
||||
public:
|
||||
IShowActivatable *inner;
|
||||
bool delInner;
|
||||
|
||||
void show(SDL_Surface * to) override;
|
||||
void showAll(SDL_Surface * to) override;
|
||||
CRClickPopupInt(IShowActivatable *our, bool deleteInt);
|
||||
CRClickPopupInt(std::shared_ptr<CIntObject> our);
|
||||
virtual ~CRClickPopupInt();
|
||||
};
|
||||
|
||||
@ -123,11 +118,11 @@ public:
|
||||
|
||||
/// component selection window
|
||||
class CSelWindow : public CInfoWindow
|
||||
{ //warning - this window deletes its components by closing!
|
||||
{
|
||||
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<std::shared_ptr<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);
|
||||
|
||||
//notification - this class inherits important destructor from CInfoWindow
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user