diff --git a/AI/VCAI/VCAI.cpp b/AI/VCAI/VCAI.cpp index f8de10cb3..3fbfe9fb8 100644 --- a/AI/VCAI/VCAI.cpp +++ b/AI/VCAI/VCAI.cpp @@ -959,13 +959,13 @@ bool VCAI::tryBuildStructure(const CGTownInstance * t, BuildingID building, unsi TResources currentRes = cb->getResourceAmount(); TResources income = estimateIncome(); //TODO: calculate if we have enough resources to build it in maxDays - - for(const auto & buildID : toBuild) - { - const CBuilding *b = t->town->buildings[buildID]; - - EBuildingState::EBuildingState canBuild = cb->canBuildStructure(t, buildID); - if(canBuild == EBuildingState::ALLOWED) + + for(const auto & buildID : toBuild) + { + const CBuilding *b = t->town->buildings.at(buildID); + + EBuildingState::EBuildingState canBuild = cb->canBuildStructure(t, buildID); + if(canBuild == EBuildingState::ALLOWED) { if(!containsSavedRes(b->resources)) { @@ -974,13 +974,13 @@ bool VCAI::tryBuildStructure(const CGTownInstance * t, BuildingID building, unsi return true; } continue; - } - else if(canBuild == EBuildingState::NO_RESOURCES) - { - TResources cost = t->town->buildings[buildID]->resources; - for (int i = 0; i < GameConstants::RESOURCE_QUANTITY; i++) - { - int diff = currentRes[i] - cost[i] + income[i]; + } + else if(canBuild == EBuildingState::NO_RESOURCES) + { + TResources cost = t->town->buildings.at(buildID)->resources; + for (int i = 0; i < GameConstants::RESOURCE_QUANTITY; i++) + { + int diff = currentRes[i] - cost[i] + income[i]; if(diff < 0) saving[i] = 1; } diff --git a/Global.h b/Global.h index 79ef42bc4..adb41f623 100644 --- a/Global.h +++ b/Global.h @@ -222,59 +222,12 @@ template char (&_ArrayCountObj(const T (&)[N]))[N]; // should be used for variables that becomes unused in release builds (e.g. only used for assert checks) #define UNUSED(VAR) ((void)VAR) -/* ---------------------------------------------------------------------------- */ -/* VCMI standard library */ -/* ---------------------------------------------------------------------------- */ -//a normal std::map with a const operator[] for sanity -template -class bmap : public std::map -{ -public: - const ValT & operator[](KeyT key) const - { - return this->find(key)->second; - } - ValT & operator[](KeyT key) - { - return static_cast &>(*this)[key]; - } - template void serialize(Handler &h, const int version) - { - h & static_cast &>(*this); - } - - bmap() - {} - explicit bmap(const typename std::map::key_compare& _Pred) - : std::map(_Pred) - {} - - bmap(const typename std::map::key_compare& _Pred, const typename std::map::allocator_type& _Al) - : std::map(_Pred, _Al) - {} - - template - bmap(_Iter _First, _Iter _Last) - : std::map(_First, _Last) - {} - - template - bmap(_Iter _First, _Iter _Last, - const typename std::map::key_compare& _Pred) - : std::map(_First, _Last, _Pred) - {} - - template - bmap(_Iter _First, _Iter _Last, - const typename std::map::key_compare& _Pred, const typename std::map::allocator_type& _Al) - : std::map(_First, _Last, _Pred, _Al) - {} - -}; - -template -std::ostream &operator<<(std::ostream &out, const boost::optional &opt) -{ +/* ---------------------------------------------------------------------------- */ +/* VCMI standard library */ +/* ---------------------------------------------------------------------------- */ +template +std::ostream &operator<<(std::ostream &out, const boost::optional &opt) +{ if(opt) return out << *opt; else @@ -311,19 +264,12 @@ namespace vstd template bool contains(const std::map & c, const Item2 &i) { - return c.find(i)!=c.end(); - } - - //returns true if bmap c contains item i - template - bool contains(const bmap & c, const Item2 &i) - { - return c.find(i)!=c.end(); - } - - //returns true if unordered set c contains item i - template - bool contains(const std::unordered_set & c, const Item &i) + return c.find(i)!=c.end(); + } + + //returns true if unordered set c contains item i + template + bool contains(const std::unordered_set & c, const Item &i) { return c.find(i)!=c.end(); } @@ -517,13 +463,13 @@ namespace vstd auto tmpItr = itr++; if(pred(*tmpItr)) setContainer.erase(tmpItr); - } - } - - //works for map and bmap, maybe something else - template - void erase_if(std::map &container, Predicate pred) - { + } + } + + //works for map and std::map, maybe something else + template + void erase_if(std::map &container, Predicate pred) + { auto itr = container.begin(); auto endItr = container.end(); while(itr != endItr) diff --git a/client/CCastleInterface.cpp b/client/CCastleInterface.cpp index e29a9d144..942cbde4c 100644 --- a/client/CCastleInterface.cpp +++ b/client/CCastleInterface.cpp @@ -40,13 +40,13 @@ using namespace boost::assign; const CBuilding * CBuildingRect::getBuilding() { if (!str->building) - return nullptr; - - if (str->hiddenUpgrade) // hidden upgrades, e.g. hordes - return base (dwelling for hordes) - return town->town->buildings[str->building->getBase()]; - - return str->building; -} + return nullptr; + + if (str->hiddenUpgrade) // hidden upgrades, e.g. hordes - return base (dwelling for hordes) + return town->town->buildings.at(str->building->getBase()); + + return str->building; +} CBuildingRect::CBuildingRect(CCastleBuildings * Par, const CGTownInstance *Town, const CStructure *Str) :CShowableAnim(0, 0, Str->defName, CShowableAnim::BASE | CShowableAnim::USE_RLE), @@ -114,13 +114,13 @@ void CBuildingRect::clickRight(tribool down, bool previousState) { if((!area) || (!((bool)down)) || (this!=parent->selectedBuilding) || getBuilding() == nullptr) return; - if( !CSDL_Ext::isTransparent(area, GH.current->motion.x-pos.x, GH.current->motion.y-pos.y) ) //inside building image - { - BuildingID bid = getBuilding()->bid; - const CBuilding *bld = town->town->buildings[bid]; - if (bid < BuildingID::DWELL_FIRST) - { - CRClickPopup::createAndPush(CInfoWindow::genText(bld->Name(), bld->Description()), + if( !CSDL_Ext::isTransparent(area, GH.current->motion.x-pos.x, GH.current->motion.y-pos.y) ) //inside building image + { + BuildingID bid = getBuilding()->bid; + const CBuilding *bld = town->town->buildings.at(bid); + if (bid < BuildingID::DWELL_FIRST) + { + CRClickPopup::createAndPush(CInfoWindow::genText(bld->Name(), bld->Description()), new CComponent(CComponent::building, bld->town->faction->index, bld->bid)); } else @@ -209,20 +209,20 @@ std::string CBuildingRect::getSubtitle()//hover text for building if (!getBuilding()) return ""; - int bid = getBuilding()->bid; - - if (bid<30)//non-dwellings - only buiding name - return town->town->buildings[getBuilding()->bid]->Name(); - else//dwellings - recruit %creature% - { - auto & availableCreatures = town->creatures[(bid-30)%GameConstants::CREATURES_PER_TOWN].second; - if(availableCreatures.size()) - { - int creaID = availableCreatures.back();//taking last of available creatures - return CGI->generaltexth->allTexts[16] + " " + CGI->creh->creatures[creaID]->namePl; - } - else - { + int bid = getBuilding()->bid; + + if (bid<30)//non-dwellings - only buiding name + return town->town->buildings.at(getBuilding()->bid)->Name(); + else//dwellings - recruit %creature% + { + auto & availableCreatures = town->creatures[(bid-30)%GameConstants::CREATURES_PER_TOWN].second; + if(availableCreatures.size()) + { + int creaID = availableCreatures.back();//taking last of available creatures + return CGI->generaltexth->allTexts[16] + " " + CGI->creh->creatures.at(creaID)->namePl; + } + else + { logGlobal->warnStream() << "Problem: dwelling with id " << bid << " offers no creatures!"; return "#ERROR#"; } @@ -255,18 +255,18 @@ void CBuildingRect::mouseMoved (const SDL_MouseMotionEvent & sEvent) CDwellingInfoBox::CDwellingInfoBox(int centerX, int centerY, const CGTownInstance *Town, int level): CWindowObject(RCLICK_POPUP | PLAYER_COLORED, "CRTOINFO", Point(centerX, centerY)) -{ - OBJ_CONSTRUCTION_CAPTURING_ALL; - - const CCreature * creature = CGI->creh->creatures[Town->creatures[level].second.back()]; - - title = new CLabel(80, 30, FONT_SMALL, CENTER, Colors::WHITE, creature->namePl); - animation = new CCreaturePic(30, 44, creature, true, true); - - std::string text = boost::lexical_cast(Town->creatures[level].first); - available = new CLabel(80,190, FONT_SMALL, CENTER, Colors::WHITE, CGI->generaltexth->allTexts[217] + text); - costPerTroop = new CLabel(80, 227, FONT_SMALL, CENTER, Colors::WHITE, CGI->generaltexth->allTexts[346]); - +{ + OBJ_CONSTRUCTION_CAPTURING_ALL; + + const CCreature * creature = CGI->creh->creatures.at(Town->creatures.at(level).second.back()); + + title = new CLabel(80, 30, FONT_SMALL, CENTER, Colors::WHITE, creature->namePl); + animation = new CCreaturePic(30, 44, creature, true, true); + + std::string text = boost::lexical_cast(Town->creatures.at(level).first); + available = new CLabel(80,190, FONT_SMALL, CENTER, Colors::WHITE, CGI->generaltexth->allTexts[217] + text); + costPerTroop = new CLabel(80, 227, FONT_SMALL, CENTER, Colors::WHITE, CGI->generaltexth->allTexts[346]); + for(int i = 0; icost[i]) @@ -503,13 +503,13 @@ void CCastleBuildings::recreate() groups[structure->building->getBase()].push_back(structure); } } - - for(auto & entry : groups) - { - const CBuilding * build = town->town->buildings[entry.first]; - - const CStructure * toAdd = *boost::max_element(entry.second, [=](const CStructure * a, const CStructure * b) - { + + for(auto & entry : groups) + { + const CBuilding * build = town->town->buildings.at(entry.first); + + const CStructure * toAdd = *boost::max_element(entry.second, [=](const CStructure * a, const CStructure * b) + { return build->getDistance(a->building->bid) < build->getDistance(b->building->bid); }); @@ -526,17 +526,17 @@ CCastleBuildings::~CCastleBuildings() { } -void CCastleBuildings::addBuilding(BuildingID building) -{ - //FIXME: implement faster method without complete recreation of town - BuildingID base = town->town->buildings[building]->getBase(); - - recreate(); - - auto & structures = groups[base]; - - for(CBuildingRect * rect : buildings) - { +void CCastleBuildings::addBuilding(BuildingID building) +{ + //FIXME: implement faster method without complete recreation of town + BuildingID base = town->town->buildings.at(building)->getBase(); + + recreate(); + + auto & structures = groups.at(base); + + for(CBuildingRect * rect : buildings) + { if (vstd::contains(structures, rect->str)) { //reset animation @@ -1111,13 +1111,13 @@ CTownInfo::CTownInfo(int posX, int posY, const CGTownInstance* Town, bool townHa { buildID = 6 + town->fortLevel(); if (buildID == 6) - return; - picture = new CAnimImage("ITMCL.DEF", town->fortLevel()-1); - } - building = town->town->buildings[BuildingID(buildID)]; - pos = picture->pos; -} - + return; + picture = new CAnimImage("ITMCL.DEF", town->fortLevel()-1); + } + building = town->town->buildings.at(BuildingID(buildID)); + pos = picture->pos; +} + void CTownInfo::hover(bool on) { if(on) @@ -1295,13 +1295,13 @@ CHallInterface::CHallInterface(const CGTownInstance *Town): resdatabar = new CMinorResDataBar; resdatabar->pos.x += pos.x; resdatabar->pos.y += pos.y; - Rect barRect(5, 556, 740, 18); - statusBar = new CGStatusBar(new CPicture(*background, barRect, 5, 556, false)); - - title = new CLabel(399, 12, FONT_MEDIUM, CENTER, Colors::WHITE, town->town->buildings[BuildingID(town->hallLevel()+BuildingID::VILLAGE_HALL)]->Name()); - exit = new CAdventureMapButton(CGI->generaltexth->hcommands[8], "", - boost::bind(&CHallInterface::close,this), 748, 556, "TPMAGE1.DEF", SDLK_RETURN); - exit->assignedKeys.insert(SDLK_ESCAPE); + Rect barRect(5, 556, 740, 18); + statusBar = new CGStatusBar(new CPicture(*background, barRect, 5, 556, false)); + + title = new CLabel(399, 12, FONT_MEDIUM, CENTER, Colors::WHITE, town->town->buildings.at(BuildingID(town->hallLevel()+BuildingID::VILLAGE_HALL))->Name()); + exit = new CAdventureMapButton(CGI->generaltexth->hcommands[8], "", + boost::bind(&CHallInterface::close,this), 748, 556, "TPMAGE1.DEF", SDLK_RETURN); + exit->assignedKeys.insert(SDLK_ESCAPE); auto & boxList = town->town->clientInfo.hallSlots; boxes.resize(boxList.size()); @@ -1310,13 +1310,13 @@ CHallInterface::CHallInterface(const CGTownInstance *Town): for(size_t col=0; coltown->buildings[buildingID]; - - if(!vstd::contains(town->builtBuildings,buildingID)) - break; + for(auto & elem : boxList[row][col])//we are looking for the first not build structure + { + auto buildingID = elem; + building = town->town->buildings.at(buildingID); + + if(!vstd::contains(town->builtBuildings,buildingID)) + break; } int posX = pos.w/2 - boxList[row].size()*154/2 - (boxList[row].size()-1)*20 + 194*col, posY = 35 + 104*row; @@ -1351,13 +1351,13 @@ std::string CBuildWindow::getTextForState(int state) std::set reqs= LOCPLINT->cb->getBuildingRequiments(town, building->bid); for(const auto & i : reqs) - { - if (vstd::contains(town->builtBuildings, i)) - continue;//skipping constructed buildings - ret+= town->town->buildings[i]->Name() + ", "; - } - ret.erase(ret.size()-2); - } + { + if (vstd::contains(town->builtBuildings, i)) + continue;//skipping constructed buildings + ret+= town->town->buildings.at(i)->Name() + ", "; + } + ret.erase(ret.size()-2); + } } return ret; } @@ -1423,13 +1423,13 @@ CFortScreen::CFortScreen(const CGTownInstance * town): { OBJ_CONSTRUCTION_CAPTURING_ALL; ui32 fortSize = town->creatures.size(); - if (fortSize > GameConstants::CREATURES_PER_TOWN && town->creatures.back().second.empty()) - fortSize--; - - const CBuilding *fortBuilding = town->town->buildings[BuildingID(town->fortLevel()+6)]; - title = new CLabel(400, 12, FONT_BIG, CENTER, Colors::WHITE, fortBuilding->Name()); - - std::string text = boost::str(boost::format(CGI->generaltexth->fcommands[6]) % fortBuilding->Name()); + if (fortSize > GameConstants::CREATURES_PER_TOWN && town->creatures.back().second.empty()) + fortSize--; + + const CBuilding *fortBuilding = town->town->buildings.at(BuildingID(town->fortLevel()+6)); + title = new CLabel(400, 12, FONT_BIG, CENTER, Colors::WHITE, fortBuilding->Name()); + + std::string text = boost::str(boost::format(CGI->generaltexth->fcommands[6]) % fortBuilding->Name()); exit = new CAdventureMapButton(text, "", boost::bind(&CFortScreen::close,this) ,748, 556, "TPMAGE1", SDLK_RETURN); exit->assignedKeys.insert(SDLK_ESCAPE); @@ -1555,13 +1555,13 @@ CFortScreen::RecruitArea::RecruitArea(int posX, int posY, const CGTownInstance * sizes.y+=21; values.push_back(new LabeledValue(sizes, CGI->generaltexth->allTexts[193], CGI->generaltexth->fcommands[4], creature->valOfBonuses(Bonus::STACKS_SPEED))); sizes.y+=20; - values.push_back(new LabeledValue(sizes, CGI->generaltexth->allTexts[194], CGI->generaltexth->fcommands[5], town->creatureGrowth(level))); - - creatureName = new CLabel(78, 11, FONT_SMALL, CENTER, Colors::WHITE, creature->namePl); - dwellingName = new CLabel(78, 101, FONT_SMALL, CENTER, Colors::WHITE, town->town->buildings[buildingID]->Name()); - - if (vstd::contains(town->builtBuildings, buildingID)) - { + values.push_back(new LabeledValue(sizes, CGI->generaltexth->allTexts[194], CGI->generaltexth->fcommands[5], town->creatureGrowth(level))); + + creatureName = new CLabel(78, 11, FONT_SMALL, CENTER, Colors::WHITE, creature->namePl); + dwellingName = new CLabel(78, 101, FONT_SMALL, CENTER, Colors::WHITE, town->town->buildings.at(buildingID)->Name()); + + if (vstd::contains(town->builtBuildings, buildingID)) + { ui32 available = town->creatures[level].first; std::string availableText = CGI->generaltexth->allTexts[217]+ boost::lexical_cast(available); availableCount = new CLabel(78, 119, FONT_SMALL, CENTER, Colors::WHITE, availableText); diff --git a/client/NetPacksClient.cpp b/client/NetPacksClient.cpp index 8bb53211a..a4d082f12 100644 --- a/client/NetPacksClient.cpp +++ b/client/NetPacksClient.cpp @@ -409,30 +409,30 @@ void NewStructures::applyCl( CClient *cl ) { CGTownInstance *town = GS(cl)->getTown(tid); for(const auto & id : bid) - { - if(id == BuildingID::CAPITOL) //fort or capitol - { - town->defInfo = const_cast(CGI->dobjinfo->capitols[town->subID].get()); - } - if(id == BuildingID::FORT) - { - town->defInfo = const_cast(CGI->dobjinfo->gobjs[Obj::TOWN][town->subID].get()); - } - if(vstd::contains(cl->playerint,town->tempOwner)) - cl->playerint[town->tempOwner]->buildChanged(town,id,1); + { + if(id == BuildingID::CAPITOL) //fort or capitol + { + town->defInfo = const_cast(CGI->dobjinfo->capitols.at(town->subID).get()); + } + if(id == BuildingID::FORT) + { + town->defInfo = const_cast(CGI->dobjinfo->gobjs.at(Obj::TOWN).at(town->subID).get()); + } + if(vstd::contains(cl->playerint,town->tempOwner)) + cl->playerint[town->tempOwner]->buildChanged(town,id,1); } } void RazeStructures::applyCl (CClient *cl) { CGTownInstance *town = GS(cl)->getTown(tid); for(const auto & id : bid) - { - if (id == BuildingID::CAPITOL) //fort or capitol - { - town->defInfo = const_cast(CGI->dobjinfo->gobjs[Obj::TOWN][town->subID].get()); - } - if(vstd::contains (cl->playerint,town->tempOwner)) - cl->playerint[town->tempOwner]->buildChanged (town,id,2); + { + if (id == BuildingID::CAPITOL) //fort or capitol + { + town->defInfo = const_cast(CGI->dobjinfo->gobjs.at(Obj::TOWN).at(town->subID).get()); + } + if(vstd::contains (cl->playerint,town->tempOwner)) + cl->playerint[town->tempOwner]->buildChanged (town,id,2); } } @@ -532,13 +532,13 @@ void InfoWindow::applyCl( CClient *cl ) comps.push_back(&elem); } std::string str; - text.toString(str); - - if(vstd::contains(cl->playerint,player)) - cl->playerint[player]->showInfoDialog(str,comps,(soundBase::soundID)soundID); - else - logNetwork->warnStream() << "We received InfoWindow for not our player..."; -} + text.toString(str); + + if(vstd::contains(cl->playerint,player)) + cl->playerint.at(player)->showInfoDialog(str,comps,(soundBase::soundID)soundID); + else + logNetwork->warnStream() << "We received InfoWindow for not our player..."; +} void SetObjectProperty::applyCl( CClient *cl ) { @@ -575,26 +575,26 @@ void CommanderLevelUp::applyCl( CClient *cl ) void BlockingDialog::applyCl( CClient *cl ) { std::string str; - text.toString(str); - - if(vstd::contains(cl->playerint,player)) - cl->playerint[player]->showBlockingDialog(str,components,queryID,(soundBase::soundID)soundID,selection(),cancel()); - else - logNetwork->warnStream() << "We received YesNoDialog for not our player..."; -} + text.toString(str); + + if(vstd::contains(cl->playerint,player)) + cl->playerint.at(player)->showBlockingDialog(str,components,queryID,(soundBase::soundID)soundID,selection(),cancel()); + else + logNetwork->warnStream() << "We received YesNoDialog for not our player..."; +} void GarrisonDialog::applyCl(CClient *cl) { const CGHeroInstance *h = cl->getHero(hid); const CArmedInstance *obj = static_cast(cl->getObj(objid)); - if(!vstd::contains(cl->playerint,h->getOwner())) - return; - - cl->playerint[h->getOwner()]->showGarrisonDialog(obj,h,removableUnits,queryID); -} - -void ExchangeDialog::applyCl(CClient *cl) + if(!vstd::contains(cl->playerint,h->getOwner())) + return; + + cl->playerint.at(h->getOwner())->showGarrisonDialog(obj,h,removableUnits,queryID); +} + +void ExchangeDialog::applyCl(CClient *cl) { assert(heroes[0] && heroes[1]); INTERFACE_CALL_IF_PRESENT(heroes[0]->tempOwner, heroExchangeStarted, heroes[0]->id, heroes[1]->id, queryID); @@ -945,13 +945,13 @@ void SetAvailableArtifacts::applyCl(CClient *cl) INTERFACE_CALL_IF_PRESENT(cl->getTile(bm->visitablePos())->visitableObjects.back()->tempOwner, availableArtifactsChanged, bm); } } - -void TradeComponents::applyCl(CClient *cl) -{///Shop handler - switch (CGI->mh->map->objects[objectid]->ID) - { - case Obj::BLACK_MARKET: - break; + +void TradeComponents::applyCl(CClient *cl) +{///Shop handler + switch (CGI->mh->map->objects.at(objectid)->ID) + { + case Obj::BLACK_MARKET: + break; case Obj::TAVERN: break; case Obj::DEN_OF_THIEVES: diff --git a/editor/Editor.cpp b/editor/Editor.cpp index 8987d01f8..822ac1d89 100644 --- a/editor/Editor.cpp +++ b/editor/Editor.cpp @@ -2,7 +2,7 @@ #include "Editor.h" #include "../lib/VCMI_Lib.h" #include "../lib/VCMIDirs.h" -#include "../lib/filesystem/CResourceLoader.h" +#include "../lib/filesystem/Filesystem.h" #include "../lib/CGeneralTextHandler.h" #include "../lib/mapping/CMap.h" #include "../lib/mapping/CMapService.h" @@ -13,7 +13,7 @@ Editor::Editor(QWidget *parent) { // Setup default logging(enough for now) console = new CConsoleHandler; - CBasicLogConfigurator logConfig(VCMIDirs::get().localPath() + "/VCMI_Editor_log.txt", console); + CBasicLogConfigurator logConfig(VCMIDirs::get().userCachePath() + "/VCMI_Editor_log.txt", console); logConfig.configureDefault(); preinitDLL(console); diff --git a/lib/CArtHandler.cpp b/lib/CArtHandler.cpp index 339661e9f..92d9e41c0 100644 --- a/lib/CArtHandler.cpp +++ b/lib/CArtHandler.cpp @@ -686,13 +686,13 @@ void CArtifactInstance::init() id = static_cast(ArtifactID::NONE); //to be randomized setNodeType(ARTIFACT_INSTANCE); } - -ArtifactPosition CArtifactInstance::firstAvailableSlot(const CArtifactSet *h) const -{ - for(auto slot : artType->possibleSlots[h->bearerType()]) - { - if(canBePutAt(h, slot)) //if(artType->fitsAt(h->artifWorn, slot)) - { + +ArtifactPosition CArtifactInstance::firstAvailableSlot(const CArtifactSet *h) const +{ + for(auto slot : artType->possibleSlots.at(h->bearerType())) + { + if(canBePutAt(h, slot)) //if(artType->fitsAt(h->artifWorn, slot)) + { //we've found a free suitable slot. return slot; } @@ -1092,13 +1092,13 @@ bool CArtifactSet::hasArt(ui32 aid, bool onlyWorn /*= false*/) const return getArtPos(aid, onlyWorn) != ArtifactPosition::PRE_FIRST; } -const ArtSlotInfo * CArtifactSet::getSlot(ArtifactPosition pos) const -{ - if(vstd::contains(artifactsWorn, pos)) - return &artifactsWorn[pos]; - if(pos >= ArtifactPosition::AFTER_LAST ) - { - int backpackPos = (int)pos - GameConstants::BACKPACK_START; +const ArtSlotInfo * CArtifactSet::getSlot(ArtifactPosition pos) const +{ + if(vstd::contains(artifactsWorn, pos)) + return &artifactsWorn.at(pos); + if(pos >= ArtifactPosition::AFTER_LAST ) + { + int backpackPos = (int)pos - GameConstants::BACKPACK_START; if(backpackPos < 0 || backpackPos >= artifactsInBackpack.size()) return nullptr; else diff --git a/lib/CArtHandler.h b/lib/CArtHandler.h index 1fdebdf1c..0058d2a5f 100644 --- a/lib/CArtHandler.h +++ b/lib/CArtHandler.h @@ -63,13 +63,13 @@ public: std::string nodeName() const override; void addNewBonus(Bonus *b) override; - virtual void levelUpArtifact (CArtifactInstance * art){}; - - ui32 price; - bmap > possibleSlots; //Bearer Type => ids of slots where artifact can be placed - std::unique_ptr > constituents; // Artifacts IDs a combined artifact consists of, or nullptr. - std::vector constituentOf; // Reverse map of constituents - combined arts that include this art - EartClass aClass; + virtual void levelUpArtifact (CArtifactInstance * art){}; + + ui32 price; + std::map > possibleSlots; //Bearer Type => ids of slots where artifact can be placed + std::unique_ptr > constituents; // Artifacts IDs a combined artifact consists of, or nullptr. + std::vector constituentOf; // Reverse map of constituents - combined arts that include this art + EartClass aClass; ArtifactID id; template void serialize(Handler &h, const int version) @@ -263,13 +263,13 @@ struct DLL_LINKAGE ArtSlotInfo }; class DLL_LINKAGE CArtifactSet -{ -public: - std::vector artifactsInBackpack; //hero's artifacts from bag - bmap artifactsWorn; //map; positions: 0 - head; 1 - shoulders; 2 - neck; 3 - right hand; 4 - left hand; 5 - torso; 6 - right ring; 7 - left ring; 8 - feet; 9 - misc1; 10 - misc2; 11 - misc3; 12 - misc4; 13 - mach1; 14 - mach2; 15 - mach3; 16 - mach4; 17 - spellbook; 18 - misc5 - - ArtSlotInfo &retreiveNewArtSlot(ArtifactPosition slot); - void setNewArtSlot(ArtifactPosition slot, CArtifactInstance *art, bool locked); +{ +public: + std::vector artifactsInBackpack; //hero's artifacts from bag + std::map artifactsWorn; //map; positions: 0 - head; 1 - shoulders; 2 - neck; 3 - right hand; 4 - left hand; 5 - torso; 6 - right ring; 7 - left ring; 8 - feet; 9 - misc1; 10 - misc2; 11 - misc3; 12 - misc4; 13 - mach1; 14 - mach2; 15 - mach3; 16 - mach4; 17 - spellbook; 18 - misc5 + + ArtSlotInfo &retreiveNewArtSlot(ArtifactPosition slot); + void setNewArtSlot(ArtifactPosition slot, CArtifactInstance *art, bool locked); void eraseArtSlot(ArtifactPosition slot); const ArtSlotInfo *getSlot(ArtifactPosition pos) const; diff --git a/lib/CDefObjInfoHandler.h b/lib/CDefObjInfoHandler.h index 1ddfd5645..10d3e6156 100644 --- a/lib/CDefObjInfoHandler.h +++ b/lib/CDefObjInfoHandler.h @@ -46,16 +46,16 @@ public: CGDefInfo(); void fetchInfoFromMSK(); }; -class DLL_LINKAGE CDefObjInfoHandler -{ -public: - bmap > > gobjs; - - bmap > capitols; - bmap > villages; - - CDefObjInfoHandler(); - ~CDefObjInfoHandler(); +class DLL_LINKAGE CDefObjInfoHandler +{ +public: + std::map > > gobjs; + + std::map > capitols; + std::map > villages; + + CDefObjInfoHandler(); + ~CDefObjInfoHandler(); template void serialize(Handler &h, const int version) { diff --git a/lib/CGameState.cpp b/lib/CGameState.cpp index fbeb6d9c3..015d04235 100644 --- a/lib/CGameState.cpp +++ b/lib/CGameState.cpp @@ -375,7 +375,7 @@ static CGObjectInstance * createObject(Obj id, int subid, int3 pos, PlayerColor return nobj; } -CGHeroInstance * CGameState::HeroesPool::pickHeroFor(bool native, PlayerColor player, const CTown *town, bmap > &available, const CHeroClass *bannedClass /*= nullptr*/) const +CGHeroInstance * CGameState::HeroesPool::pickHeroFor(bool native, PlayerColor player, const CTown *town, std::map > &available, const CHeroClass *bannedClass /*= nullptr*/) const { CGHeroInstance *ret = nullptr; @@ -1340,13 +1340,13 @@ void CGameState::init(StartInfo * si) if (vstd::contains(vti->builtBuildings,(-31-i))) //if we have horde for this level { vti->builtBuildings.erase(BuildingID(-31-i));//remove old ID - if (vti->town->hordeLvl[0] == i)//if town first horde is this one + if (vti->town->hordeLvl.at(0) == i)//if town first horde is this one { vti->builtBuildings.insert(BuildingID::HORDE_1);//add it if (vstd::contains(vti->builtBuildings,(BuildingID::DWELL_UP_FIRST+i)))//if we have upgraded dwelling as well vti->builtBuildings.insert(BuildingID::HORDE_1_UPGR);//add it as well } - if (vti->town->hordeLvl[1] == i)//if town second horde is this one + if (vti->town->hordeLvl.at(1) == i)//if town second horde is this one { vti->builtBuildings.insert(BuildingID::HORDE_2); if (vstd::contains(vti->builtBuildings,(BuildingID::DWELL_UP_FIRST+i))) @@ -1357,7 +1357,7 @@ void CGameState::init(StartInfo * si) //Early check for #1444-like problems for(auto building : vti->builtBuildings) { - assert(vti->town->buildings[building]); + assert(vti->town->buildings.at(building) != nullptr); UNUSED(building); } @@ -1368,9 +1368,9 @@ void CGameState::init(StartInfo * si) if (vstd::contains(ev.buildings,(-31-i))) //if we have horde for this level { ev.buildings.erase(BuildingID(-31-i)); - if (vti->town->hordeLvl[0] == i) + if (vti->town->hordeLvl.at(0) == i) ev.buildings.insert(BuildingID::HORDE_1); - if (vti->town->hordeLvl[1] == i) + if (vti->town->hordeLvl.at(1) == i) ev.buildings.insert(BuildingID::HORDE_2); } } @@ -2433,9 +2433,9 @@ int CGameState::lossCheck( PlayerColor player ) const return false; } -bmap > CGameState::unusedHeroesFromPool() +std::map > CGameState::unusedHeroesFromPool() { - bmap > pool = hpool.heroesPool; + std::map > pool = hpool.heroesPool; for ( auto i = players.cbegin() ; i != players.cend();i++) for(auto j = i->second.availableHeroes.cbegin(); j != i->second.availableHeroes.cend(); j++) if(*j) diff --git a/lib/CGameState.h b/lib/CGameState.h index 3f5d7b746..e9b8e1b00 100644 --- a/lib/CGameState.h +++ b/lib/CGameState.h @@ -361,22 +361,22 @@ class DLL_LINKAGE CGameState : public CNonConstInfoCallback public: ConstTransitivePtr scenarioOps, initialOpts; //second one is a copy of settings received from pregame (not randomized) PlayerColor currentPlayer; //ID of player currently having turn - ConstTransitivePtr curB; //current battle - ui32 day; //total number of days in game - ConstTransitivePtr map; - bmap players; - bmap teams; - CBonusSystemNode globalEffects; - - struct DLL_LINKAGE HeroesPool - { - bmap > heroesPool; //[subID] - heroes available to buy; nullptr if not available - bmap pavailable; // [subid] -> which players can recruit hero (binary flags) - - CGHeroInstance * pickHeroFor(bool native, PlayerColor player, const CTown *town, bmap > &available, const CHeroClass *bannedClass = nullptr) const; - - template void serialize(Handler &h, const int version) - { + ConstTransitivePtr curB; //current battle + ui32 day; //total number of days in game + ConstTransitivePtr map; + std::map players; + std::map teams; + CBonusSystemNode globalEffects; + + struct DLL_LINKAGE HeroesPool + { + std::map > heroesPool; //[subID] - heroes available to buy; nullptr if not available + std::map pavailable; // [subid] -> which players can recruit hero (binary flags) + + CGHeroInstance * pickHeroFor(bool native, PlayerColor player, const CTown *town, std::map > &available, const CHeroClass *bannedClass = nullptr) const; + + template void serialize(Handler &h, const int version) + { h & heroesPool & pavailable; } } hpool; //we have here all heroes available on this map that are not hired @@ -406,13 +406,13 @@ public: std::vector guardingCreatures (int3 pos) const; int victoryCheck(PlayerColor player) const; //checks if given player is winner; -1 if std victory, 1 if special victory, 0 else int lossCheck(PlayerColor player) const; //checks if given player is loser; -1 if std loss, 1 if special, 0 else - PlayerColor checkForStandardWin() const; //returns color of player that accomplished standard victory conditions or 255 (NEUTRAL) if no winner - bool checkForStandardLoss(PlayerColor player) const; //checks if given player lost the game - void obtainPlayersStats(SThievesGuildInfo & tgi, int level); //fills tgi with info about other players that is available at given level of thieves' guild - bmap > unusedHeroesFromPool(); //heroes pool without heroes that are available in taverns - BattleInfo * setupBattle(int3 tile, const CArmedInstance *armies[2], const CGHeroInstance * heroes[2], bool creatureBank, const CGTownInstance *town); - - void buildBonusSystemTree(); + PlayerColor checkForStandardWin() const; //returns color of player that accomplished standard victory conditions or 255 (NEUTRAL) if no winner + bool checkForStandardLoss(PlayerColor player) const; //checks if given player lost the game + void obtainPlayersStats(SThievesGuildInfo & tgi, int level); //fills tgi with info about other players that is available at given level of thieves' guild + std::map > unusedHeroesFromPool(); //heroes pool without heroes that are available in taverns + BattleInfo * setupBattle(int3 tile, const CArmedInstance *armies[2], const CGHeroInstance * heroes[2], bool creatureBank, const CGTownInstance *town); + + void buildBonusSystemTree(); void attachArmedObjects(); void buildGlobalTeamPlayerTree(); void deserializationFix(); diff --git a/lib/CObjectHandler.cpp b/lib/CObjectHandler.cpp index 7ebcb7567..ffee95835 100644 --- a/lib/CObjectHandler.cpp +++ b/lib/CObjectHandler.cpp @@ -2112,13 +2112,13 @@ int CGTownInstance::creatureDwellingLevel(int dwelling) const if (!hasBuilt(BuildingID(BuildingID::DWELL_FIRST+dwelling+i*GameConstants::CREATURES_PER_TOWN))) return i-1; } -} -int CGTownInstance::getHordeLevel(const int & HID) const//HID - 0 or 1; returns creature level or -1 if that horde structure is not present -{ - return town->hordeLvl[HID]; -} -int CGTownInstance::creatureGrowth(const int & level) const -{ +} +int CGTownInstance::getHordeLevel(const int & HID) const//HID - 0 or 1; returns creature level or -1 if that horde structure is not present +{ + return town->hordeLvl.at(HID); +} +int CGTownInstance::creatureGrowth(const int & level) const +{ return getGrowthInfo(level).totalGrowth(); } @@ -2139,17 +2139,17 @@ GrowthInfo CGTownInstance::getGrowthInfo(int level) const if (hasBuilt(BuildingID::CASTLE)) ret.entries.push_back(GrowthInfo::Entry(subID, BuildingID::CASTLE, castleBonus = base)); - else if (hasBuilt(BuildingID::CITADEL)) - ret.entries.push_back(GrowthInfo::Entry(subID, BuildingID::CITADEL, castleBonus = base / 2)); - - if(town->hordeLvl[0] == level)//horde 1 - if(hasBuilt(BuildingID::HORDE_1)) - ret.entries.push_back(GrowthInfo::Entry(subID, BuildingID::HORDE_1, creature->hordeGrowth)); - - if(town->hordeLvl[1] == level)//horde 2 - if(hasBuilt(BuildingID::HORDE_2)) - ret.entries.push_back(GrowthInfo::Entry(subID, BuildingID::HORDE_2, creature->hordeGrowth)); - + else if (hasBuilt(BuildingID::CITADEL)) + ret.entries.push_back(GrowthInfo::Entry(subID, BuildingID::CITADEL, castleBonus = base / 2)); + + if(town->hordeLvl.at(0) == level)//horde 1 + if(hasBuilt(BuildingID::HORDE_1)) + ret.entries.push_back(GrowthInfo::Entry(subID, BuildingID::HORDE_1, creature->hordeGrowth)); + + if(town->hordeLvl.at(1) == level)//horde 2 + if(hasBuilt(BuildingID::HORDE_2)) + ret.entries.push_back(GrowthInfo::Entry(subID, BuildingID::HORDE_2, creature->hordeGrowth)); + int dwellingBonus = 0; if(const PlayerState *p = cb->getPlayer(tempOwner, false)) { @@ -2617,13 +2617,13 @@ bool CGTownInstance::addBonusIfBuilt(BuildingID building, Bonus::BonusType type, bool CGTownInstance::addBonusIfBuilt(BuildingID building, Bonus::BonusType type, int val, TPropagatorPtr & prop, int subtype /*= -1*/) { - if(hasBuilt(building)) - { - std::ostringstream descr; - descr << town->buildings[building]->Name() << " "; - if(val > 0) - descr << "+"; - else if(val < 0) + if(hasBuilt(building)) + { + std::ostringstream descr; + descr << town->buildings.at(building)->Name() << " "; + if(val > 0) + descr << "+"; + else if(val < 0) descr << "-"; descr << val; @@ -2692,13 +2692,13 @@ bool CGTownInstance::armedGarrison() const int CGTownInstance::getTownLevel() const { - // count all buildings that are not upgrades - return boost::range::count_if(builtBuildings, [&](const BuildingID & build) - { - return town->buildings[build] && town->buildings[build]->upgrade == -1; - }); -} - + // count all buildings that are not upgrades + return boost::range::count_if(builtBuildings, [&](const BuildingID & build) + { + return town->buildings.at(build) && town->buildings.at(build)->upgrade == -1; + }); +} + CBonusSystemNode * CGTownInstance::whatShouldBeAttached() { return &townAndVis; diff --git a/lib/CTownHandler.h b/lib/CTownHandler.h index c79b3c2be..0f114e44f 100644 --- a/lib/CTownHandler.h +++ b/lib/CTownHandler.h @@ -134,19 +134,19 @@ public: std::vector names; //names of the town instances /// level -> list of creatures on this tier - // TODO: replace with pointers to CCreature - std::vector > creatures; - - bmap > buildings; - - std::vector dwellings; //defs for adventure map dwellings for new towns, [0] means tier 1 creatures etc. - std::vector dwellingNames; - - // should be removed at least from configs in favor of auto-detection - bmap hordeLvl; //[0] - first horde building creature level; [1] - second horde building (-1 if not present) - ui32 mageLevel; //max available mage guild level - ui16 primaryRes; - ArtifactID warMachine; + // TODO: replace with pointers to CCreature + std::vector > creatures; + + std::map > buildings; + + std::vector dwellings; //defs for adventure map dwellings for new towns, [0] means tier 1 creatures etc. + std::vector dwellingNames; + + // should be removed at least from configs in favor of auto-detection + std::map hordeLvl; //[0] - first horde building creature level; [1] - second horde building (-1 if not present) + ui32 mageLevel; //max available mage guild level + ui16 primaryRes; + ArtifactID warMachine; si32 moatDamage; // default chance for hero of specific class to appear in tavern, if field "tavern" was not set // resulting chance = sqrt(town.chance * heroClass.chance) diff --git a/lib/GameConstants.cpp b/lib/GameConstants.cpp index 56189053b..cf28026b4 100644 --- a/lib/GameConstants.cpp +++ b/lib/GameConstants.cpp @@ -73,13 +73,13 @@ ID_LIKE_OPERATORS(SpellID, SpellID::ESpellID) ID_LIKE_OPERATORS(BuildingID, BuildingID::EBuildingID) -ID_LIKE_OPERATORS(BFieldType, BFieldType::EBFieldType) - - -bmap > & Obj::toDefObjInfo() const -{ - return VLC->dobjinfo->gobjs[*this]; -} +ID_LIKE_OPERATORS(BFieldType, BFieldType::EBFieldType) + + +std::map > & Obj::toDefObjInfo() const +{ + return VLC->dobjinfo->gobjs[*this]; +} CArtifact * ArtifactID::toArtifact() const { diff --git a/lib/GameConstants.h b/lib/GameConstants.h index 4bb5180ff..744ca4b74 100644 --- a/lib/GameConstants.h +++ b/lib/GameConstants.h @@ -606,13 +606,13 @@ public: }; Obj(EObj _num = NO_OBJ) : num(_num) {} - - ID_LIKE_CLASS_COMMON(Obj, EObj) - - bmap > & toDefObjInfo() const; - - EObj num; -}; + + ID_LIKE_CLASS_COMMON(Obj, EObj) + + std::map > & toDefObjInfo() const; + + EObj num; +}; ID_LIKE_OPERATORS_DECLS(Obj, Obj::EObj) diff --git a/lib/HeroBonus.cpp b/lib/HeroBonus.cpp index 91d2a8752..cd3526735 100644 --- a/lib/HeroBonus.cpp +++ b/lib/HeroBonus.cpp @@ -55,18 +55,18 @@ const std::map bonusDurationMap = boost::assign::map_list_of const std::map bonusLimitEffect = boost::assign::map_list_of BONUS_ITEM(NO_LIMIT) BONUS_ITEM(ONLY_DISTANCE_FIGHT) - BONUS_ITEM(ONLY_MELEE_FIGHT) - BONUS_ITEM(ONLY_ENEMY_ARMY); - -const bmap bonusLimiterMap = boost::assign::map_list_of - ("SHOOTER_ONLY", make_shared(Bonus::SHOOTER)) - ("DRAGON_NATURE", make_shared(Bonus::DRAGON_NATURE)) - ("IS_UNDEAD", make_shared(Bonus::UNDEAD)); - -const bmap bonusPropagatorMap = boost::assign::map_list_of - ("BATTLE_WIDE", make_shared(CBonusSystemNode::BATTLE)) - ("VISITED_TOWN_AND_VISITOR", make_shared(CBonusSystemNode::TOWN_AND_VISITOR)) - ("PLAYER_PROPAGATOR", make_shared(CBonusSystemNode::PLAYER)) + BONUS_ITEM(ONLY_MELEE_FIGHT) + BONUS_ITEM(ONLY_ENEMY_ARMY); + +const std::map bonusLimiterMap = boost::assign::map_list_of + ("SHOOTER_ONLY", make_shared(Bonus::SHOOTER)) + ("DRAGON_NATURE", make_shared(Bonus::DRAGON_NATURE)) + ("IS_UNDEAD", make_shared(Bonus::UNDEAD)); + +const std::map bonusPropagatorMap = boost::assign::map_list_of + ("BATTLE_WIDE", make_shared(CBonusSystemNode::BATTLE)) + ("VISITED_TOWN_AND_VISITOR", make_shared(CBonusSystemNode::TOWN_AND_VISITOR)) + ("PLAYER_PROPAGATOR", make_shared(CBonusSystemNode::PLAYER)) ("HERO", make_shared(CBonusSystemNode::HERO)); diff --git a/lib/HeroBonus.h b/lib/HeroBonus.h index 1063ab20a..352cb607a 100644 --- a/lib/HeroBonus.h +++ b/lib/HeroBonus.h @@ -964,14 +964,14 @@ namespace Selector extern DLL_LINKAGE const std::map bonusNameMap; extern DLL_LINKAGE const std::map bonusValueMap; -extern DLL_LINKAGE const std::map bonusSourceMap; -extern DLL_LINKAGE const std::map bonusDurationMap; -extern DLL_LINKAGE const std::map bonusLimitEffect; -extern DLL_LINKAGE const bmap bonusLimiterMap; -extern DLL_LINKAGE const bmap bonusPropagatorMap; - - -// BonusList template that requires full interface of CBonusSystemNode +extern DLL_LINKAGE const std::map bonusSourceMap; +extern DLL_LINKAGE const std::map bonusDurationMap; +extern DLL_LINKAGE const std::map bonusLimitEffect; +extern DLL_LINKAGE const std::map bonusLimiterMap; +extern DLL_LINKAGE const std::map bonusPropagatorMap; + + +// BonusList template that requires full interface of CBonusSystemNode template void BonusList::insert(const int position, InputIterator first, InputIterator last) { diff --git a/lib/IGameCallback.cpp b/lib/IGameCallback.cpp index 7929982c8..4e65a81bd 100644 --- a/lib/IGameCallback.cpp +++ b/lib/IGameCallback.cpp @@ -567,13 +567,13 @@ EBuildingState::EBuildingState CGameInfoCallback::canBuildStructure( const CGTow { ERROR_RET_VAL_IF(!canGetFullInfo(t), "Town is not owned!", EBuildingState::TOWN_NOT_OWNED); - if(!t->town->buildings.count(ID)) - return EBuildingState::BUILDING_ERROR; - - const CBuilding * pom = t->town->buildings[ID]; - - - if(t->hasBuilt(ID)) //already built + if(!t->town->buildings.count(ID)) + return EBuildingState::BUILDING_ERROR; + + const CBuilding * pom = t->town->buildings.at(ID); + + + if(t->hasBuilt(ID)) //already built return EBuildingState::ALREADY_PRESENT; //can we build it? @@ -634,24 +634,24 @@ std::set CGameInfoCallback::getBuildingRequiments( const CGTownInsta { ERROR_RET_VAL_IF(!canGetFullInfo(t), "Town is not owned!", std::set()); ERROR_RET_VAL_IF(!t->town->buildings.count(ID), "No such building!", std::set()); - - std::set used; - used.insert(ID); - auto reqs = t->town->buildings[ID]->requirements; - - bool found; - do + + std::set used; + used.insert(ID); + auto reqs = t->town->buildings.at(ID)->requirements; + + bool found; + do { found = false; for(auto i=reqs.begin();i!=reqs.end();i++) { - if(used.find(*i)==used.end()) //we haven't added requirements for this building - { - found = true; - auto & requires = t->town->buildings[*i]->requirements; - - used.insert(*i); - for(auto & require : requires) + if(used.find(*i)==used.end()) //we haven't added requirements for this building + { + found = true; + auto & requires = t->town->buildings.at(*i)->requirements; + + used.insert(*i); + for(auto & require : requires) reqs.insert(require);//creating full list of requirements } } diff --git a/lib/NetPacksLib.cpp b/lib/NetPacksLib.cpp index 552b537ea..7335a565c 100644 --- a/lib/NetPacksLib.cpp +++ b/lib/NetPacksLib.cpp @@ -453,7 +453,7 @@ DLL_LINKAGE void NewStructures::applyGs( CGameState *gs ) CGTownInstance *t = gs->getTown(tid); for(const auto & id : bid) { - assert(t->town->buildings[id]); + assert(t->town->buildings.at(id) != nullptr); t->builtBuildings.insert(id); } t->builded = builded; diff --git a/lib/StartInfo.h b/lib/StartInfo.h index 4da832025..e254a1053 100644 --- a/lib/StartInfo.h +++ b/lib/StartInfo.h @@ -70,13 +70,13 @@ struct StartInfo { enum EMode {NEW_GAME, LOAD_GAME, CAMPAIGN, DUEL, INVALID = 255}; - EMode mode; - ui8 difficulty; //0=easy; 4=impossible - - typedef bmap TPlayerInfos; - TPlayerInfos playerInfos; //color indexed - - ui32 seedToBeUsed; //0 if not sure (client requests server to decide, will be send in reply pack) + EMode mode; + ui8 difficulty; //0=easy; 4=impossible + + typedef std::map TPlayerInfos; + TPlayerInfos playerInfos; //color indexed + + ui32 seedToBeUsed; //0 if not sure (client requests server to decide, will be send in reply pack) ui32 seedPostInit; //so we know that game is correctly synced at the start; 0 if not known yet ui32 mapfileChecksum; //0 if not relevant ui8 turnTime; //in minutes, 0=unlimited diff --git a/lib/mapping/CCampaignHandler.cpp b/lib/mapping/CCampaignHandler.cpp index c21913147..158ff5bd6 100644 --- a/lib/mapping/CCampaignHandler.cpp +++ b/lib/mapping/CCampaignHandler.cpp @@ -453,13 +453,13 @@ const CCampaignScenario & CCampaignState::getCurrentScenario() const { return camp->scenarios[currentMap]; } - -ui8 CCampaignState::currentBonusID() const -{ - return chosenCampaignBonuses[currentMap]; -} - -CCampaignState::CCampaignState() + +ui8 CCampaignState::currentBonusID() const +{ + return chosenCampaignBonuses.at(currentMap); +} + +CCampaignState::CCampaignState() {} CCampaignState::CCampaignState( unique_ptr _camp ) : camp(std::move(_camp)) diff --git a/lib/mapping/CCampaignHandler.h b/lib/mapping/CCampaignHandler.h index 8c60326d1..aea87e6fa 100644 --- a/lib/mapping/CCampaignHandler.h +++ b/lib/mapping/CCampaignHandler.h @@ -148,13 +148,13 @@ class DLL_LINKAGE CCampaignState public: unique_ptr camp; std::string campaignName; - std::vector mapsConquered, mapsRemaining; - ui8 currentMap; - - bmap chosenCampaignBonuses; //used only for mode CAMPAIGN - - //void initNewCampaign(const StartInfo &si); - void mapConquered(const std::vector & heroes); + std::vector mapsConquered, mapsRemaining; + ui8 currentMap; + + std::map chosenCampaignBonuses; //used only for mode CAMPAIGN + + //void initNewCampaign(const StartInfo &si); + void mapConquered(const std::vector & heroes); boost::optional getBonusForCurrentMap() const; const CCampaignScenario &getCurrentScenario() const; ui8 currentBonusID() const; diff --git a/lib/mapping/CMap.h b/lib/mapping/CMap.h index a058e4213..753278122 100644 --- a/lib/mapping/CMap.h +++ b/lib/mapping/CMap.h @@ -375,13 +375,13 @@ public: std::vector< ConstTransitivePtr > allHeroes; //indexed by [hero_type_id]; on map, disposed, prisons, etc. //Helper lists - std::vector< ConstTransitivePtr > heroesOnMap; - - /// associative list to identify which hero/creature id belongs to which object id(index for objects) - bmap questIdentifierToId; - - unique_ptr editManager; - + std::vector< ConstTransitivePtr > heroesOnMap; + + /// associative list to identify which hero/creature id belongs to which object id(index for objects) + std::map questIdentifierToId; + + unique_ptr editManager; + private: TerrainTile*** terrain; diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index 5135de48d..94f2ffdf8 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -99,22 +99,22 @@ static inline double distance(int3 a, int3 b) static void giveExp(BattleResult &r) { r.exp[0] = 0; - r.exp[1] = 0; - for(auto i = r.casualties[!r.winner].begin(); i!=r.casualties[!r.winner].end(); i++) - { - r.exp[r.winner] += VLC->creh->creatures[i->first]->valOfBonuses(Bonus::STACK_HEALTH) * i->second; - } -} - + r.exp[1] = 0; + for(auto i = r.casualties[!r.winner].begin(); i!=r.casualties[!r.winner].end(); i++) + { + r.exp[r.winner] += VLC->creh->creatures.at(i->first)->valOfBonuses(Bonus::STACK_HEALTH) * i->second; + } +} + PlayerStatus PlayerStatuses::operator[](PlayerColor player) { - boost::unique_lock l(mx); - if(players.find(player) != players.end()) - { - return players[player]; - } - else - { + boost::unique_lock l(mx); + if(players.find(player) != players.end()) + { + return players.at(player); + } + else + { throw std::runtime_error("No such player!"); } } @@ -244,13 +244,13 @@ void CGameHandler::levelUpCommander (const CCommanderInstance * c, int skill) { scp.which = SetCommanderProperty::BONUS; - auto difference = [](std::vector< std::vector > skillLevels, std::vector secondarySkills, int skill)->int - { - int s = std::min (skill, (int)ECommander::SPELL_POWER); //spell power level controls also casts and resistance - return skillLevels[skill][secondarySkills[s]] - (secondarySkills[s] ? skillLevels[skill][secondarySkills[s]-1] : 0); - }; - - switch (skill) + auto difference = [](std::vector< std::vector > skillLevels, std::vector secondarySkills, int skill)->int + { + int s = std::min (skill, (int)ECommander::SPELL_POWER); //spell power level controls also casts and resistance + return skillLevels.at(skill).at(secondarySkills.at(s)) - (secondarySkills.at(s) ? skillLevels.at(skill).at(secondarySkills.at(s)-1) : 0); + }; + + switch (skill) { case ECommander::ATTACK: scp.accumulatedBonus.type = Bonus::PRIMARY_SKILL; @@ -288,19 +288,19 @@ void CGameHandler::levelUpCommander (const CCommanderInstance * c, int skill) scp.accumulatedBonus.val = difference (VLC->creh->skillLevels, c->secondarySkills, skill); sendAndApply (&scp); - - scp.which = SetCommanderProperty::SECONDARY_SKILL; - scp.additionalInfo = skill; - scp.amount = c->secondarySkills[skill] + 1; - sendAndApply (&scp); - } - else if (skill >= 100) - { - scp.which = SetCommanderProperty::SPECIAL_SKILL; - scp.accumulatedBonus = *VLC->creh->skillRequirements[skill-100].first; - scp.additionalInfo = skill; //unnormalized - sendAndApply (&scp); - } + + scp.which = SetCommanderProperty::SECONDARY_SKILL; + scp.additionalInfo = skill; + scp.amount = c->secondarySkills.at(skill) + 1; + sendAndApply (&scp); + } + else if (skill >= 100) + { + scp.which = SetCommanderProperty::SPECIAL_SKILL; + scp.accumulatedBonus = *VLC->creh->skillRequirements.at(skill-100).first; + scp.additionalInfo = skill; //unnormalized + sendAndApply (&scp); + } expGiven(hero); } @@ -322,20 +322,20 @@ void CGameHandler::levelUpCommander(const CCommanderInstance * c) } //picking sec. skills for choice - - for (int i = 0; i <= ECommander::SPELL_POWER; ++i) - { - if (c->secondarySkills[i] < ECommander::MAX_SKILL_LEVEL) - clu.skills.push_back(i); - } - int i = 100; - for (auto specialSkill : VLC->creh->skillRequirements) - { - if (c->secondarySkills[specialSkill.second.first] == ECommander::MAX_SKILL_LEVEL - && c->secondarySkills[specialSkill.second.second] == ECommander::MAX_SKILL_LEVEL - && !vstd::contains (c->specialSKills, i)) - clu.skills.push_back (i); - ++i; + + for (int i = 0; i <= ECommander::SPELL_POWER; ++i) + { + if (c->secondarySkills.at(i) < ECommander::MAX_SKILL_LEVEL) + clu.skills.push_back(i); + } + int i = 100; + for (auto specialSkill : VLC->creh->skillRequirements) + { + if (c->secondarySkills.at(specialSkill.second.first) == ECommander::MAX_SKILL_LEVEL + && c->secondarySkills.at(specialSkill.second.second) == ECommander::MAX_SKILL_LEVEL + && !vstd::contains (c->specialSKills, i)) + clu.skills.push_back (i); + ++i; } int skillAmount = clu.skills.size(); @@ -430,14 +430,14 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer if (hero1) battleResult.data->exp[0] = hero1->calculateXp(battleResult.data->exp[0]);//scholar skill - if (hero2) - battleResult.data->exp[1] = hero2->calculateXp(battleResult.data->exp[1]); - - const CArmedInstance *bEndArmy1 = gs->curB->sides[0].armyObject; - const CArmedInstance *bEndArmy2 = gs->curB->sides[1].armyObject; - const BattleResult::EResult result = battleResult.get()->result; - - auto findBattleQuery = [this] () -> shared_ptr + if (hero2) + battleResult.data->exp[1] = hero2->calculateXp(battleResult.data->exp[1]); + + const CArmedInstance *bEndArmy1 = gs->curB->sides.at(0).armyObject; + const CArmedInstance *bEndArmy2 = gs->curB->sides.at(1).armyObject; + const BattleResult::EResult result = battleResult.get()->result; + + auto findBattleQuery = [this] () -> shared_ptr { for(auto &q : queries.allQueries()) { @@ -482,13 +482,13 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer if(finishingBattle->winnerHero) { if(int eagleEyeLevel = finishingBattle->winnerHero->getSecSkillLevel(SecondarySkill::EAGLE_EYE)) - { - int maxLevel = eagleEyeLevel + 1; - double eagleEyeChance = finishingBattle->winnerHero->valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, SecondarySkill::EAGLE_EYE); - for(const CSpell *sp : gs->curB->sides[!battleResult.data->winner].usedSpellsHistory) - if(sp->level <= maxLevel && !vstd::contains(finishingBattle->winnerHero->spells, sp->id) && rand() % 100 < eagleEyeChance) - cs.spells.insert(sp->id); - } + { + int maxLevel = eagleEyeLevel + 1; + double eagleEyeChance = finishingBattle->winnerHero->valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, SecondarySkill::EAGLE_EYE); + for(const CSpell *sp : gs->curB->sides.at(!battleResult.data->winner).usedSpellsHistory) + if(sp->level <= maxLevel && !vstd::contains(finishingBattle->winnerHero->spells, sp->id) && rand() % 100 < eagleEyeChance) + cs.spells.insert(sp->id); + } } @@ -692,16 +692,16 @@ void CGameHandler::battleAfterLevelUp( const BattleResult &result ) SetAvailableHeroes sah; sah.player = finishingBattle->loser; sah.hid[0] = finishingBattle->loserHero->subID; - if(result.result == BattleResult::ESCAPE) //retreat - { - sah.army[0].clear(); - sah.army[0].setCreature(SlotID(0), finishingBattle->loserHero->type->initialArmy[0].creature, 1); - } - - if(const CGHeroInstance *another = getPlayer(finishingBattle->loser)->availableHeroes[1]) - sah.hid[1] = another->subID; - else - sah.hid[1] = -1; + if(result.result == BattleResult::ESCAPE) //retreat + { + sah.army[0].clear(); + sah.army[0].setCreature(SlotID(0), finishingBattle->loserHero->type->initialArmy.at(0).creature, 1); + } + + if(const CGHeroInstance *another = getPlayer(finishingBattle->loser)->availableHeroes.at(1)) + sah.hid[1] = another->subID; + else + sah.hid[1] = -1; sendAndApply(&sah); } @@ -762,13 +762,13 @@ void CGameHandler::prepareAttack(BattleAttack &bat, const CStack *att, const CSt } const Bonus * bonus = att->getBonusLocalFirst(Selector::type(Bonus::SPELL_LIKE_ATTACK)); - if (bonus && (bat.shot())) //TODO: make it work in meele? - { - bat.bsa.front().flags |= BattleStackAttacked::EFFECT; - bat.bsa.front().effect = VLC->spellh->spells[bonus->subtype]->mainEffectAnim; //hopefully it does not interfere with any other effect? - - std::set attackedCreatures = gs->curB->getAffectedCreatures(SpellID(bonus->subtype).toSpell(), bonus->val, att->owner, targetHex); - //TODO: get exact attacked hex for defender + if (bonus && (bat.shot())) //TODO: make it work in meele? + { + bat.bsa.front().flags |= BattleStackAttacked::EFFECT; + bat.bsa.front().effect = VLC->spellh->spells.at(bonus->subtype)->mainEffectAnim; //hopefully it does not interfere with any other effect? + + std::set attackedCreatures = gs->curB->getAffectedCreatures(SpellID(bonus->subtype).toSpell(), bonus->val, att->owner, targetHex); + //TODO: get exact attacked hex for defender for(const CStack * stack : attackedCreatures) { @@ -1066,13 +1066,13 @@ void CGameHandler::setPortalDwelling(const CGTownInstance * town, bool forced=fa if(!p) { logGlobal->warnStream() << "There is no player owner of town " << town->name << " at " << town->pos; - return; - } - - if (forced || town->creatures[GameConstants::CREATURES_PER_TOWN].second.empty())//we need to change creature - { - SetAvailableCreatures ssi; - ssi.tid = town->id; + return; + } + + if (forced || town->creatures.at(GameConstants::CREATURES_PER_TOWN).second.empty())//we need to change creature + { + SetAvailableCreatures ssi; + ssi.tid = town->id; ssi.creatures = town->creatures; ssi.creatures[GameConstants::CREATURES_PER_TOWN].second.clear();//remove old one @@ -1081,19 +1081,19 @@ void CGameHandler::setPortalDwelling(const CGTownInstance * town, bool forced=fa { sendAndApply(&ssi); return; - } - - ui32 dwellpos = rand()%dwellings.size();//take random dwelling - ui32 creapos = rand()%dwellings[dwellpos]->creatures.size();//for multi-creature dwellings like Golem Factory - CreatureID creature = dwellings[dwellpos]->creatures[creapos].second[0]; - - if (clear) - ssi.creatures[GameConstants::CREATURES_PER_TOWN].first = std::max((ui32)1, (VLC->creh->creatures[creature]->growth)/2); - else - ssi.creatures[GameConstants::CREATURES_PER_TOWN].first = VLC->creh->creatures[creature]->growth; - ssi.creatures[GameConstants::CREATURES_PER_TOWN].second.push_back(creature); - sendAndApply(&ssi); - } + } + + ui32 dwellpos = rand()%dwellings.size();//take random dwelling + ui32 creapos = rand()%dwellings.at(dwellpos)->creatures.size();//for multi-creature dwellings like Golem Factory + CreatureID creature = dwellings.at(dwellpos)->creatures.at(creapos).second[0]; + + if (clear) + ssi.creatures[GameConstants::CREATURES_PER_TOWN].first = std::max((ui32)1, (VLC->creh->creatures.at(creature)->growth)/2); + else + ssi.creatures[GameConstants::CREATURES_PER_TOWN].first = VLC->creh->creatures.at(creature)->growth; + ssi.creatures[GameConstants::CREATURES_PER_TOWN].second.push_back(creature); + sendAndApply(&ssi); + } } void CGameHandler::newTurn() @@ -1177,22 +1177,22 @@ void CGameHandler::newTurn() n.creatureid = newMonster.second; } } - } - } - - bmap > pool = gs->hpool.heroesPool; - - for (auto & elem : gs->players) - { + } + } + + std::map > pool = gs->hpool.heroesPool; + + for (auto & elem : gs->players) + { if(elem.first == PlayerColor::NEUTRAL) continue; - else if(elem.first >= PlayerColor::PLAYER_LIMIT) - assert(0); //illegal player number! - - std::pair playerGold(elem.first, elem.second.resources[Res::GOLD]); - hadGold.insert(playerGold); - - if(newWeek) //new heroes in tavern + else if(elem.first >= PlayerColor::PLAYER_LIMIT) + assert(0); //illegal player number! + + std::pair playerGold(elem.first, elem.second.resources.at(Res::GOLD)); + hadGold.insert(playerGold); + + if(newWeek) //new heroes in tavern { SetAvailableHeroes sah; sah.player = elem.first; @@ -1251,39 +1251,39 @@ void CGameHandler::newTurn() { if(t->hasBuilt(BuildingID::PORTAL_OF_SUMMON, ETownType::DUNGEON)) setPortalDwelling(t, true, (n.specialWeek == NewTurn::PLAGUE ? true : false)); //set creatures for Portal of Summoning - - if(!firstTurn) - if (t->hasBuilt(BuildingID::TREASURY, ETownType::RAMPART) && player < PlayerColor::PLAYER_LIMIT) - n.res[player][Res::GOLD] += hadGold[player]/10; //give 10% of starting gold - - if (!vstd::contains(n.cres, t->id)) - { - n.cres[t->id].tid = t->id; - n.cres[t->id].creatures = t->creatures; - } - auto & sac = n.cres[t->id]; - - for (int k=0; k < GameConstants::CREATURES_PER_TOWN; k++) //creature growths - { - if(t->creatureDwellingLevel(k) >= 0)//there is dwelling (k-level) - { - ui32 &availableCount = sac.creatures[k].first; - const CCreature *cre = VLC->creh->creatures[t->creatures[k].second.back()]; - - if (n.specialWeek == NewTurn::PLAGUE) - availableCount = t->creatures[k].first / 2; //halve their number, no growth - else - { - if(firstTurn) //first day of game: use only basic growths + + if(!firstTurn) + if (t->hasBuilt(BuildingID::TREASURY, ETownType::RAMPART) && player < PlayerColor::PLAYER_LIMIT) + n.res[player][Res::GOLD] += hadGold.at(player)/10; //give 10% of starting gold + + if (!vstd::contains(n.cres, t->id)) + { + n.cres[t->id].tid = t->id; + n.cres[t->id].creatures = t->creatures; + } + auto & sac = n.cres.at(t->id); + + for (int k=0; k < GameConstants::CREATURES_PER_TOWN; k++) //creature growths + { + if(t->creatureDwellingLevel(k) >= 0)//there is dwelling (k-level) + { + ui32 &availableCount = sac.creatures.at(k).first; + const CCreature *cre = VLC->creh->creatures.at(t->creatures.at(k).second.back()); + + if (n.specialWeek == NewTurn::PLAGUE) + availableCount = t->creatures.at(k).first / 2; //halve their number, no growth + else + { + if(firstTurn) //first day of game: use only basic growths availableCount = cre->growth; else - availableCount += t->creatureGrowth(k); - - //Deity of fire week - upgrade both imps and upgrades - if (n.specialWeek == NewTurn::DEITYOFFIRE && vstd::contains(t->creatures[k].second, n.creatureid)) - availableCount += 15; - - if( cre->idNumber == n.creatureid ) //bonus week, effect applies only to identical creatures + availableCount += t->creatureGrowth(k); + + //Deity of fire week - upgrade both imps and upgrades + if (n.specialWeek == NewTurn::DEITYOFFIRE && vstd::contains(t->creatures.at(k).second, n.creatureid)) + availableCount += 15; + + if( cre->idNumber == n.creatureid ) //bonus week, effect applies only to identical creatures { if(n.specialWeek == NewTurn::DOUBLE_GROWTH) availableCount *= 2; @@ -1318,17 +1318,17 @@ void CGameHandler::newTurn() if (player != PlayerColor::NEUTRAL) //do not reveal fow for neutral player { FoWChange fw; - fw.mode = 1; - fw.player = player; - // find all hidden tiles - auto & fow = gs->getPlayerTeam(player)->fogOfWarMap; - for (size_t i=0; i