diff --git a/client/CMT.cpp b/client/CMT.cpp index 128fc6843..4f73754e0 100644 --- a/client/CMT.cpp +++ b/client/CMT.cpp @@ -92,7 +92,7 @@ static po::variables_map vm; static bool ermInteractiveMode = false; //structurize when time is right void processCommand(const std::string &message); -static void setScreenRes(int w, int h, int bpp, bool fullscreen, bool resetVideo=true); +static void setScreenRes(int w, int h, int bpp, bool fullscreen, int displayIndex, bool resetVideo=true); void dispose(); void playIntro(); static void mainLoop(); @@ -407,7 +407,7 @@ int main(int argc, char** argv) } } - setScreenRes(res["width"].Float(), res["height"].Float(), video["bitsPerPixel"].Float(), video["fullscreen"].Bool()); + setScreenRes(res["width"].Float(), res["height"].Float(), video["bitsPerPixel"].Float(), video["displayIndex"].Float(), video["fullscreen"].Bool()); logGlobal->infoStream() <<"\tInitializing screen: "<16) bpp = 32; - if(!checkVideoMode(0,w,h)) + if(displayIndex < 0) + { + if (mainWindow != nullptr) + displayIndex = SDL_GetWindowDisplayIndex(mainWindow); + if (displayIndex < 0) + displayIndex = 0; + } + if(!checkVideoMode(displayIndex, w, h)) { logGlobal->errorStream() << "Error: SDL says that " << w << "x" << h << " resolution is not available!"; return false; @@ -1005,12 +1012,12 @@ static bool recreateWindow(int w, int h, int bpp, bool fullscreen) if(fullscreen) { //in full-screen mode always use desktop resolution - mainWindow = SDL_CreateWindow(NAME.c_str(), SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED, 0, 0, SDL_WINDOW_FULLSCREEN_DESKTOP); + 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,SDL_WINDOWPOS_CENTERED, w, h, 0); + mainWindow = SDL_CreateWindow(NAME.c_str(), SDL_WINDOWPOS_CENTERED_DISPLAY(displayIndex),SDL_WINDOWPOS_CENTERED_DISPLAY(displayIndex), w, h, 0); } if(nullptr == mainWindow) @@ -1091,9 +1098,9 @@ static bool recreateWindow(int w, int h, int bpp, bool fullscreen) } //used only once during initialization -static void setScreenRes(int w, int h, int bpp, bool fullscreen, bool resetVideo) +static void setScreenRes(int w, int h, int bpp, bool fullscreen, int displayIndex, bool resetVideo) { - if(!recreateWindow(w,h,bpp,fullscreen)) + if(!recreateWindow(w, h, bpp, fullscreen, displayIndex)) { throw std::runtime_error("Requested screen resolution is not available\n"); } @@ -1111,7 +1118,7 @@ static void fullScreenChanged() auto w = screen->w; auto h = screen->h; - if(!recreateWindow(w,h,bitsPerPixel,toFullscreen)) + if(!recreateWindow(w, h, bitsPerPixel, toFullscreen, -1)) { //will return false and report error if video mode is not supported return; diff --git a/client/CMusicHandler.cpp b/client/CMusicHandler.cpp index e2c8ba291..40efc783b 100644 --- a/client/CMusicHandler.cpp +++ b/client/CMusicHandler.cpp @@ -128,8 +128,8 @@ void CSoundHandler::release() for (auto &chunk : soundChunks) { - if (chunk.second) - Mix_FreeChunk(chunk.second); + if (chunk.second.first) + Mix_FreeChunk(chunk.second.first); } } @@ -142,14 +142,14 @@ Mix_Chunk *CSoundHandler::GetSoundChunk(std::string &sound, bool cache) try { if (cache && soundChunks.find(sound) != soundChunks.end()) - return soundChunks[sound]; + return soundChunks[sound].first; auto data = CResourceHandler::get()->load(ResourceID(std::string("SOUNDS/") + sound, EResType::SOUND))->readAll(); - SDL_RWops *ops = SDL_RWFromMem(data.first.release(), data.second); + SDL_RWops *ops = SDL_RWFromMem(data.first.get(), data.second); Mix_Chunk *chunk = Mix_LoadWAV_RW(ops, 1); // will free ops if (cache) - soundChunks.insert(std::pair(sound, chunk)); + soundChunks.insert(std::pair(sound, std::make_pair (chunk, std::move (data.first)))); return chunk; } diff --git a/client/CMusicHandler.h b/client/CMusicHandler.h index eaafa8bf9..a21e1beb7 100644 --- a/client/CMusicHandler.h +++ b/client/CMusicHandler.h @@ -41,7 +41,8 @@ private: SettingsListener listener; void onVolumeChange(const JsonNode &volumeNode); - std::map soundChunks; + using CachedChunk = std::pair>; + std::map soundChunks; Mix_Chunk *GetSoundChunk(std::string &sound, bool cache); diff --git a/client/CPlayerInterface.cpp b/client/CPlayerInterface.cpp index 3d8f6aedf..a5e6f5534 100644 --- a/client/CPlayerInterface.cpp +++ b/client/CPlayerInterface.cpp @@ -2294,8 +2294,10 @@ void CPlayerInterface::acceptTurn() { adventureInt->select(heroToSelect, centerView); } - else + else if(towns.size()) adventureInt->select(towns.front(), centerView); + else + adventureInt->select(wanderingHeroes.front()); //show new day animation and sound on infobar adventureInt->infoBar.showDate(); diff --git a/client/CPreGame.cpp b/client/CPreGame.cpp index 91a787b5d..1ae57cbf2 100644 --- a/client/CPreGame.cpp +++ b/client/CPreGame.cpp @@ -1146,7 +1146,7 @@ void SelectionTab::parseGames(const std::unordered_set &files, bool // Create the map info object CMapInfo mapInfo; mapInfo.mapHeader = make_unique(); - mapInfo.scenarioOpts = new StartInfo; + mapInfo.scenarioOpts = nullptr;//to be created by serialiser lf >> *(mapInfo.mapHeader.get()) >> mapInfo.scenarioOpts; mapInfo.fileURI = file.getName(); mapInfo.countPlayers(); diff --git a/client/windows/CCastleInterface.cpp b/client/windows/CCastleInterface.cpp index 1af854294..146403098 100644 --- a/client/windows/CCastleInterface.cpp +++ b/client/windows/CCastleInterface.cpp @@ -1378,7 +1378,7 @@ std::string CBuildWindow::getTextForState(int state) }; ret = CGI->generaltexth->allTexts[52]; - ret += "\n" + town->genBuildingRequirements(building->bid, false).toString(toStr); + ret += "\n" + town->genBuildingRequirements(building->bid).toString(toStr); break; } case EBuildingState::MISSING_BASE: diff --git a/config/schemas/settings.json b/config/schemas/settings.json index fccc17f74..78ad824ed 100644 --- a/config/schemas/settings.json +++ b/config/schemas/settings.json @@ -45,7 +45,7 @@ "type" : "object", "additionalProperties" : false, "default": {}, - "required" : [ "screenRes", "bitsPerPixel", "fullscreen", "spellbookAnimation","driver", "showIntro" ], + "required" : [ "screenRes", "bitsPerPixel", "fullscreen", "spellbookAnimation","driver", "showIntro", "displayIndex" ], "properties" : { "screenRes" : { "type" : "object", @@ -77,6 +77,10 @@ "type" : "string", "default" : "opengl", "description" : "preferred graphics backend driver name for SDL2" + }, + "displayIndex" : { + "type" : "number", + "default" : 0 } } }, diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index c58d62828..597a6a0c5 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -3,6 +3,7 @@ cmake_minimum_required(VERSION 2.8.7) include_directories(${CMAKE_HOME_DIRECTORY} ${CMAKE_HOME_DIRECTORY}/include ${CMAKE_CURRENT_SOURCE_DIR}) include_directories(${ZLIB_INCLUDE_DIR} ${Boost_INCLUDE_DIRS} ${Qt5Widgets_INCLUDE_DIRS} ${Qt5Network_INCLUDE_DIRS}) +include_directories(${SDL_INCLUDE_DIR}) set(launcher_modmanager_SRCS modManager/cdownloadmanager_moc.cpp @@ -25,6 +26,7 @@ set(launcher_SRCS mainwindow_moc.cpp launcherdirs.cpp jsonutils.cpp + sdldisplayquery.cpp ) set(launcher_FORMS @@ -60,10 +62,10 @@ endif() if(MSVC) # Fix _WinMain@16 linking error - target_link_libraries(vcmilauncher vcmi ${Qt5Core_QTMAIN_LIBRARIES} ${Qt5Widgets_LIBRARIES} ${Qt5Network_LIBRARIES}) + target_link_libraries(vcmilauncher vcmi ${Qt5Core_QTMAIN_LIBRARIES} ${Qt5Widgets_LIBRARIES} ${Qt5Network_LIBRARIES} ${SDL_LIBRARY}) else() # The Qt5Widgets_LIBRARIES variable also includes QtGui and QtCore - target_link_libraries(vcmilauncher vcmi ${Qt5Widgets_LIBRARIES} ${Qt5Network_LIBRARIES}) + target_link_libraries(vcmilauncher vcmi ${Qt5Widgets_LIBRARIES} ${Qt5Network_LIBRARIES} ${SDL_LIBRARY}) endif() # temporary(?) disabled - generation of PCH takes too much time since cotire is trying to collect all Qt headers diff --git a/launcher/main.cpp b/launcher/main.cpp index e9fd317b5..cb3ed80bb 100644 --- a/launcher/main.cpp +++ b/launcher/main.cpp @@ -1,11 +1,13 @@ #include "StdInc.h" #include "mainwindow_moc.h" #include +#include "sdldisplayquery.h" int main(int argc, char *argv[]) { + auto displayList = getDisplays(); QApplication a(argc, argv); - MainWindow w; + MainWindow w(displayList); w.show(); return a.exec(); diff --git a/launcher/mainwindow_moc.cpp b/launcher/mainwindow_moc.cpp index 3536e925a..1656f94b3 100644 --- a/launcher/mainwindow_moc.cpp +++ b/launcher/mainwindow_moc.cpp @@ -26,7 +26,7 @@ void MainWindow::load() settings.init(); } -MainWindow::MainWindow(QWidget *parent) : +MainWindow::MainWindow(const QStringList& displayList, QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { @@ -34,6 +34,7 @@ MainWindow::MainWindow(QWidget *parent) : ui->setupUi(this); ui->tabListWidget->setCurrentIndex(0); + ui->settingsView->setDisplayList(displayList); connect(ui->tabSelectList, SIGNAL(currentRowChanged(int)), ui->tabListWidget, SLOT(setCurrentIndex(int))); diff --git a/launcher/mainwindow_moc.h b/launcher/mainwindow_moc.h index e1c994c99..1584c9e4e 100644 --- a/launcher/mainwindow_moc.h +++ b/launcher/mainwindow_moc.h @@ -1,5 +1,6 @@ #pragma once #include +#include namespace Ui { class MainWindow; @@ -14,7 +15,7 @@ class MainWindow : public QMainWindow void load(); void startExecutable(QString name); public: - explicit MainWindow(QWidget *parent = 0); + explicit MainWindow(const QStringList& displayList, QWidget *parent = 0); ~MainWindow(); private slots: diff --git a/launcher/mainwindow_moc.ui b/launcher/mainwindow_moc.ui index 2aa753c8b..a63de44a9 100644 --- a/launcher/mainwindow_moc.ui +++ b/launcher/mainwindow_moc.ui @@ -176,7 +176,7 @@ 1 - + diff --git a/launcher/modManager/cmodlistview_moc.cpp b/launcher/modManager/cmodlistview_moc.cpp index a6f3b22db..a85e1002d 100644 --- a/launcher/modManager/cmodlistview_moc.cpp +++ b/launcher/modManager/cmodlistview_moc.cpp @@ -74,6 +74,10 @@ CModListView::CModListView(QWidget *parent) : { loadRepositories(); } + else + { + manager->resetRepositories(); + } } void CModListView::loadRepositories() diff --git a/launcher/sdldisplayquery.cpp b/launcher/sdldisplayquery.cpp new file mode 100644 index 000000000..aaaf24bb1 --- /dev/null +++ b/launcher/sdldisplayquery.cpp @@ -0,0 +1,32 @@ +#include "sdldisplayquery.h" + +#include +#include + +#include +#include + +QStringList getDisplays() +{ + if(SDL_Init(SDL_INIT_VIDEO)) + return QStringList("default display"); + + const int displays = SDL_GetNumVideoDisplays(); + QStringList list; + + for (int display = 0; display < displays; ++display) + { + SDL_Rect rect; + + if (SDL_GetDisplayBounds (display, &rect)) + continue; + + QString string; + QTextStream(&string) << display << " - " << rect.w << "x" << rect.h << " (at " << rect.x << ", " << rect.y << ")"; + + list << string; + } + + SDL_Quit(); + return list; +} diff --git a/launcher/sdldisplayquery.h b/launcher/sdldisplayquery.h new file mode 100644 index 000000000..e2c7dcaa1 --- /dev/null +++ b/launcher/sdldisplayquery.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +QStringList getDisplays(); diff --git a/launcher/settingsView/csettingsview_moc.cpp b/launcher/settingsView/csettingsview_moc.cpp index 6c1722287..bdfc967c3 100644 --- a/launcher/settingsView/csettingsview_moc.cpp +++ b/launcher/settingsView/csettingsview_moc.cpp @@ -20,11 +20,25 @@ static const std::string knownEncodingsList[] = //TODO: remove hardcode "GB2312" // basic set for Simplified Chinese. Separate from GBK to allow proper detection of H3 fonts }; +void CSettingsView::setDisplayList(const QStringList& displayList) +{ + if (displayList.count() < 2) + { + ui->comboBoxDisplayIndex->hide (); + ui->labelDisplayIndex->hide (); + } + else + { + ui->comboBoxDisplayIndex->clear(); + ui->comboBoxDisplayIndex->addItems(displayList); + ui->comboBoxDisplayIndex->setCurrentIndex(settings["video"]["displayIndex"].Float()); + } +} + void CSettingsView::loadSettings() { int resX = settings["video"]["screenRes"]["width"].Float(); int resY = settings["video"]["screenRes"]["height"].Float(); - int resIndex = ui->comboBoxResolution->findText(QString("%1x%2").arg(resX).arg(resY)); ui->comboBoxResolution->setCurrentIndex(resIndex); @@ -92,6 +106,12 @@ void CSettingsView::on_comboBoxAutoCheck_currentIndexChanged(int index) node->Bool() = index; } +void CSettingsView::on_comboBoxDisplayIndex_currentIndexChanged(int index) +{ + Settings node = settings.write["video"]; + node["displayIndex"].Float() = index; +} + void CSettingsView::on_comboBoxPlayerAI_currentIndexChanged(const QString &arg1) { Settings node = settings.write["server"]["playerAI"]; diff --git a/launcher/settingsView/csettingsview_moc.h b/launcher/settingsView/csettingsview_moc.h index 5aca831fe..5ee782c96 100644 --- a/launcher/settingsView/csettingsview_moc.h +++ b/launcher/settingsView/csettingsview_moc.h @@ -15,6 +15,7 @@ public: ~CSettingsView(); void loadSettings(); + void setDisplayList(const QStringList& displayList); private slots: void on_comboBoxResolution_currentIndexChanged(const QString &arg1); @@ -43,6 +44,8 @@ private slots: void on_comboBoxAutoCheck_currentIndexChanged(int index); + void on_comboBoxDisplayIndex_currentIndexChanged(int index); + private: Ui::CSettingsView *ui; }; diff --git a/launcher/settingsView/csettingsview_moc.ui b/launcher/settingsView/csettingsview_moc.ui index 98d431510..bf9d73c65 100644 --- a/launcher/settingsView/csettingsview_moc.ui +++ b/launcher/settingsView/csettingsview_moc.ui @@ -6,8 +6,8 @@ 0 0 - 700 - 420 + 714 + 429 @@ -26,7 +26,7 @@ 0 - + @@ -39,7 +39,7 @@ - + @@ -59,7 +59,7 @@ - + 1024 @@ -99,7 +99,7 @@ - + @@ -192,7 +192,7 @@ - + QPlainTextEdit::NoWrap @@ -222,7 +222,7 @@ - + @@ -250,21 +250,21 @@ - + Neutral AI - + Heroes III character set - + @@ -273,14 +273,14 @@ - + Player AI - + @@ -309,7 +309,7 @@ - + Network port @@ -329,7 +329,7 @@ - + @@ -411,7 +411,7 @@ - + Qt::Vertical @@ -427,7 +427,7 @@ - + Qt::Vertical @@ -472,7 +472,7 @@ - + 1 @@ -489,13 +489,29 @@ - + Check repositories on startup + + + + Display index + + + + + + + + 0 + + + + diff --git a/lib/CGameState.cpp b/lib/CGameState.cpp index 9d5741ba0..b1f2cc034 100644 --- a/lib/CGameState.cpp +++ b/lib/CGameState.cpp @@ -1080,13 +1080,14 @@ void CGameState::initPlayerStates() logGlobal->debug("\tCreating player entries in gs"); for(auto & elem : scenarioOps->playerInfos) { - std::pair ins(elem.first,PlayerState()); - ins.second.color=ins.first; - ins.second.human = elem.second.playerID; - ins.second.team = map->players[ins.first.getNum()].team; - teams[ins.second.team].id = ins.second.team;//init team - teams[ins.second.team].players.insert(ins.first);//add player to team - players.insert(ins); + PlayerState & p = players[elem.first]; + //std::pair ins(elem.first,PlayerState()); + p.color=elem.first; + p.human = elem.second.playerID; + p.team = map->players[elem.first.getNum()].team; + teams[p.team].id = p.team;//init team + teams[p.team].players.insert(elem.first);//add player to team + //players.insert(ins); } } @@ -2936,6 +2937,25 @@ PlayerState::PlayerState() setNodeType(PLAYER); } +PlayerState::PlayerState(PlayerState && other): + CBonusSystemNode(std::move(other)), + color(other.color), + human(other.human), + team(other.team), + resources(other.resources), + enteredWinningCheatCode(other.enteredWinningCheatCode), + enteredLosingCheatCode(other.enteredLosingCheatCode), + status(other.status), + daysWithoutCastle(other.daysWithoutCastle) +{ + std::swap(visitedObjects, other.visitedObjects); + std::swap(heroes, other.heroes); + std::swap(towns, other.towns); + std::swap(availableHeroes, other.availableHeroes); + std::swap(dwellings, other.dwellings); + std::swap(quests, other.quests); +} + std::string PlayerState::nodeName() const { return "Player " + (color.getNum() < VLC->generaltexth->capColors.size() ? VLC->generaltexth->capColors[color.getNum()] : boost::lexical_cast(color)); @@ -3235,6 +3255,15 @@ TeamState::TeamState() setNodeType(TEAM); } +TeamState::TeamState(TeamState && other): + CBonusSystemNode(std::move(other)), + id(other.id) +{ + std::swap(players, other.players); + std::swap(fogOfWarMap, other.fogOfWarMap); +} + + CRandomGenerator & CGameState::getRandomGenerator() { //logGlobal->traceStream() << "Fetching CGameState::rand with seed " << rand.nextInt(); diff --git a/lib/CPlayerState.h b/lib/CPlayerState.h index f676379a3..3469b1304 100644 --- a/lib/CPlayerState.h +++ b/lib/CPlayerState.h @@ -35,6 +35,8 @@ public: boost::optional daysWithoutCastle; PlayerState(); + PlayerState(PlayerState && other); + std::string nodeName() const override; template void serialize(Handler &h, const int version) @@ -56,6 +58,7 @@ public: std::vector > > fogOfWarMap; //true - visible, false - hidden TeamState(); + TeamState(TeamState && other); template void serialize(Handler &h, const int version) { diff --git a/lib/HeroBonus.cpp b/lib/HeroBonus.cpp index b8d0caa4b..9e6f47578 100644 --- a/lib/HeroBonus.cpp +++ b/lib/HeroBonus.cpp @@ -96,6 +96,13 @@ BonusList::BonusList(const BonusList &bonusList) belongsToTree = false; } +BonusList::BonusList(BonusList&& other): + belongsToTree(false) +{ + std::swap(belongsToTree, other.belongsToTree); + std::swap(bonuses, other.bonuses); +} + BonusList& BonusList::operator=(const BonusList &bonusList) { bonuses.resize(bonusList.size()); @@ -104,6 +111,12 @@ BonusList& BonusList::operator=(const BonusList &bonusList) return *this; } +void BonusList::changed() +{ + if(belongsToTree) + CBonusSystemNode::treeHasChanged(); +} + int BonusList::totalValue() const { int base = 0; @@ -257,24 +270,19 @@ void BonusList::eliminateDuplicates() void BonusList::push_back(Bonus* const &x) { bonuses.push_back(x); - - if (belongsToTree) - CBonusSystemNode::treeHasChanged(); + changed(); } std::vector::iterator BonusList::erase(const int position) { - if (belongsToTree) - CBonusSystemNode::treeHasChanged(); + changed(); return bonuses.erase(bonuses.begin() + position); } void BonusList::clear() { bonuses.clear(); - - if (belongsToTree) - CBonusSystemNode::treeHasChanged(); + changed(); } std::vector::size_type BonusList::operator-=(Bonus* const &i) @@ -283,26 +291,20 @@ std::vector::size_type BonusList::operator-=(Bonus* const &i) if(itr == bonuses.end()) return false; bonuses.erase(itr); - - if (belongsToTree) - CBonusSystemNode::treeHasChanged(); + changed(); return true; } void BonusList::resize(std::vector::size_type sz, Bonus* c ) { bonuses.resize(sz, c); - - if (belongsToTree) - CBonusSystemNode::treeHasChanged(); + changed(); } void BonusList::insert(std::vector::iterator position, std::vector::size_type n, Bonus* const &x) { bonuses.insert(position, n, x); - - if (belongsToTree) - CBonusSystemNode::treeHasChanged(); + changed(); } int IBonusBearer::valOfBonuses(Bonus::BonusType type, const CSelector &selector) const @@ -708,6 +710,36 @@ CBonusSystemNode::CBonusSystemNode() : bonuses(true), exportedBonuses(true), nod { } +CBonusSystemNode::CBonusSystemNode(CBonusSystemNode && other): + bonuses(std::move(other.bonuses)), + exportedBonuses(std::move(other.exportedBonuses)), + nodeType(other.nodeType), + description(other.description), + cachedLast(0) +{ + std::swap(parents, other.parents); + std::swap(children, other.children); + + //fixing bonus tree without recalculation + + for(CBonusSystemNode * n : parents) + { + n->children -= &other; + n->children.push_back(this); + } + + for(CBonusSystemNode * n : children) + { + n->parents -= &other; + n->parents.push_back(this); + } + + //cache ignored + + //cachedBonuses + //cachedRequests +} + CBonusSystemNode::~CBonusSystemNode() { detachFromAll(); diff --git a/lib/HeroBonus.h b/lib/HeroBonus.h index db81b354c..cb0087ad3 100644 --- a/lib/HeroBonus.h +++ b/lib/HeroBonus.h @@ -412,7 +412,7 @@ private: TInternalContainer bonuses; bool belongsToTree; - + void changed(); public: typedef TInternalContainer::const_reference const_reference; @@ -423,6 +423,7 @@ public: BonusList(bool BelongsToTree = false); BonusList(const BonusList &bonusList); + BonusList(BonusList && other); BonusList& operator=(const BonusList &bonusList); // wrapper functions of the STL vector container @@ -494,12 +495,8 @@ public: { return bonuses.end(); } - - //friend inline std::vector::iterator range_begin(BonusList & x); - //friend inline std::vector::iterator range_end(BonusList & x); }; - // Extensions for BOOST_FOREACH to enable iterating of BonusList objects // Don't touch/call this functions inline BonusList::iterator range_begin(BonusList & x) @@ -614,7 +611,7 @@ public: const TBonusListPtr getSpellBonuses() const; }; -class DLL_LINKAGE CBonusSystemNode : public IBonusBearer +class DLL_LINKAGE CBonusSystemNode : public IBonusBearer, public boost::noncopyable { public: enum ENodeTypes @@ -647,8 +644,8 @@ private: const TBonusListPtr getAllBonusesWithoutCaching(const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root = nullptr) const; public: - explicit CBonusSystemNode(); + CBonusSystemNode(CBonusSystemNode && other); virtual ~CBonusSystemNode(); void limitBonuses(const BonusList &allBonuses, BonusList &out) const; //out will bo populed with bonuses that are not limited here @@ -1010,23 +1007,5 @@ template void BonusList::insert(const int position, InputIterator first, InputIterator last) { bonuses.insert(bonuses.begin() + position, first, last); - - if (belongsToTree) - CBonusSystemNode::treeHasChanged(); + changed(); } - -// Extensions for BOOST_FOREACH to enable iterating of BonusList objects -/*namespace boost -{ - template<> - struct range_mutable_iterator - { - typedef std::vector::iterator type; - }; - - template<> - struct range_const_iterator - { - typedef std::vector::const_iterator type; - }; -}*/ diff --git a/lib/mapObjects/CGTownInstance.cpp b/lib/mapObjects/CGTownInstance.cpp index a48173fcb..f15707f65 100644 --- a/lib/mapObjects/CGTownInstance.cpp +++ b/lib/mapObjects/CGTownInstance.cpp @@ -1126,7 +1126,7 @@ bool CGTownInstance::hasBuilt(BuildingID buildingID) const return vstd::contains(builtBuildings, buildingID); } -CBuilding::TRequired CGTownInstance::genBuildingRequirements(BuildingID buildID, bool includeUpgrade) const +CBuilding::TRequired CGTownInstance::genBuildingRequirements(BuildingID buildID) const { const CBuilding * building = town->buildings.at(buildID); @@ -1138,10 +1138,14 @@ CBuilding::TRequired CGTownInstance::genBuildingRequirements(BuildingID buildID, if (!hasBuilt(id)) return id; - if (build->upgrade != BuildingID::NONE && !hasBuilt(build->upgrade)) - return build->upgrade; + CBuilding::TRequired::OperatorAll requirements; - return build->requirements.morph(dependTest); + if (build->upgrade != BuildingID::NONE) + requirements.expressions.push_back(dependTest(build->upgrade)); + + requirements.expressions.push_back(build->requirements.morph(dependTest)); + + return requirements; }; CBuilding::TRequired::OperatorAll requirements; @@ -1149,9 +1153,7 @@ CBuilding::TRequired CGTownInstance::genBuildingRequirements(BuildingID buildID, { const CBuilding * upgr = town->buildings.at(building->upgrade); - if (includeUpgrade) - requirements.expressions.push_back(upgr->bid); - requirements.expressions.push_back(upgr->requirements.morph(dependTest)); + requirements.expressions.push_back(dependTest(upgr->bid)); } requirements.expressions.push_back(building->requirements.morph(dependTest)); diff --git a/lib/mapObjects/CGTownInstance.h b/lib/mapObjects/CGTownInstance.h index 34b781e84..620b37794 100644 --- a/lib/mapObjects/CGTownInstance.h +++ b/lib/mapObjects/CGTownInstance.h @@ -238,7 +238,7 @@ public: bool armedGarrison() const; //true if town has creatures in garrison or garrisoned hero int getTownLevel() const; - CBuilding::TRequired genBuildingRequirements(BuildingID build, bool includeUpgrade=true) const; + CBuilding::TRequired genBuildingRequirements(BuildingID build) const; void mergeGarrisonOnSiege() const; // merge garrison into army of visiting hero void removeCapitols (PlayerColor owner) const; diff --git a/lib/mapObjects/CRewardableObject.cpp b/lib/mapObjects/CRewardableObject.cpp index 698633d09..1c8163f4b 100644 --- a/lib/mapObjects/CRewardableObject.cpp +++ b/lib/mapObjects/CRewardableObject.cpp @@ -857,6 +857,7 @@ void CGOnceVisitable::initObj() info[0].reward.bonuses.push_back(bonus); info[1].reward.bonuses.push_back(bonus); info[0].message.addTxt(MetaString::ADVOB_TXT, 162); + info[0].message.addReplacement(VLC->arth->artifacts[info[0].reward.artifacts.back()]->Name()); info[1].message.addTxt(MetaString::ADVOB_TXT, 163); } break; diff --git a/lib/mapObjects/MiscObjects.cpp b/lib/mapObjects/MiscObjects.cpp index b1910f575..fd63509d0 100644 --- a/lib/mapObjects/MiscObjects.cpp +++ b/lib/mapObjects/MiscObjects.cpp @@ -1659,7 +1659,7 @@ std::string CGShrine::getHoverText(PlayerColor player) const std::string CGShrine::getHoverText(const CGHeroInstance * hero) const { std::string hoverName = getHoverText(hero->tempOwner); - if(vstd::contains(hero->spells, spell)) //hero knows that spell + if(wasVisited(hero->tempOwner) && vstd::contains(hero->spells, spell)) //know what spell there is and hero knows that spell hoverName += "\n\n" + VLC->generaltexth->allTexts[354]; // (Already learned) return hoverName; } diff --git a/lib/mapping/CMapInfo.cpp b/lib/mapping/CMapInfo.cpp index 0cd319d79..4fec37fe3 100644 --- a/lib/mapping/CMapInfo.cpp +++ b/lib/mapping/CMapInfo.cpp @@ -35,11 +35,13 @@ CMapInfo::CMapInfo() : scenarioOpts(nullptr), playerAmnt(0), humanPlayers(0), #define STEAL(x) x = std::move(tmp.x) -CMapInfo::CMapInfo(CMapInfo && tmp) +CMapInfo::CMapInfo(CMapInfo && tmp): + scenarioOpts(nullptr), playerAmnt(0), humanPlayers(0), + actualHumanPlayers(0), isRandomMap(false) { + std::swap(scenarioOpts, tmp.scenarioOpts); STEAL(mapHeader); STEAL(campaignHeader); - STEAL(scenarioOpts); STEAL(fileURI); STEAL(date); STEAL(playerAmnt); @@ -48,6 +50,10 @@ CMapInfo::CMapInfo(CMapInfo && tmp) STEAL(isRandomMap); } +CMapInfo::~CMapInfo() +{ + vstd::clear_pointer(scenarioOpts); +} void CMapInfo::mapInit(const std::string & fname) { diff --git a/lib/mapping/CMapInfo.h b/lib/mapping/CMapInfo.h index 2e204e84b..2a71f71ef 100644 --- a/lib/mapping/CMapInfo.h +++ b/lib/mapping/CMapInfo.h @@ -32,6 +32,7 @@ public: CMapInfo(); CMapInfo(CMapInfo && tmp); + virtual ~CMapInfo(); CMapInfo &operator=(CMapInfo &&other);