mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
- fixed #1643 -> hero placeholder handling
- fixed bug when loading victory/loss conditions of the 3rd scenario in the first ROE campaign - fixed bug when loading artifacts to hero of the 3rd scenario in the first ROE campaign (due to corrupt H3M map) - implemented function object to quickly find a object by it's sub ID in a list - added netbackbase.h to header list in CMake - removed false message which said that the server loaded the map successfully
This commit is contained in:
parent
27be6a8f13
commit
d4fd361d4b
@ -326,10 +326,7 @@ void CClient::newGame( CConnection *con, StartInfo *si )
|
||||
c << ui8(2) << ui8(1); //new game; one client
|
||||
c << *si;
|
||||
c >> pom8;
|
||||
if(pom8)
|
||||
throw std::runtime_error("Server cannot open the map!");
|
||||
else
|
||||
logNetwork->infoStream() << "Server opened map properly.";
|
||||
if(pom8) throw std::runtime_error("Server cannot open the map!");
|
||||
}
|
||||
|
||||
c >> si;
|
||||
|
@ -432,6 +432,23 @@ CGHeroInstance * CGameState::HeroesPool::pickHeroFor(bool native, PlayerColor pl
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CGameState::CrossoverHeroesList::addHeroToBothLists(CGHeroInstance * hero)
|
||||
{
|
||||
heroesFromPreviousScenario.push_back(hero);
|
||||
heroesFromAnyPreviousScenarios.push_back(hero);
|
||||
}
|
||||
|
||||
void CGameState::CrossoverHeroesList::removeHeroFromBothLists(CGHeroInstance * hero)
|
||||
{
|
||||
heroesFromPreviousScenario -= hero;
|
||||
heroesFromAnyPreviousScenarios -= hero;
|
||||
}
|
||||
|
||||
CGameState::CampaignHeroReplacement::CampaignHeroReplacement(CGHeroInstance * hero, ObjectInstanceID heroPlaceholderId) : hero(hero), heroPlaceholderId(heroPlaceholderId)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int CGameState::pickNextHeroType(PlayerColor owner) const
|
||||
{
|
||||
const PlayerSettings &ps = scenarioOps->getIthPlayersSettings(owner);
|
||||
@ -1104,15 +1121,15 @@ void CGameState::placeCampaignHeroes()
|
||||
}
|
||||
|
||||
// replace heroes placeholders
|
||||
auto sourceCrossoverHeroes = getCrossoverHeroesFromPreviousScenario();
|
||||
auto crossoverHeroes = getCrossoverHeroesFromPreviousScenarios();
|
||||
|
||||
if(!sourceCrossoverHeroes.empty())
|
||||
if(!crossoverHeroes.heroesFromAnyPreviousScenarios.empty())
|
||||
{
|
||||
logGlobal->debugStream() << "\tPrepare crossover heroes";
|
||||
auto crossoverHeroes = prepareCrossoverHeroes(sourceCrossoverHeroes, scenarioOps->campState->getCurrentScenario().travelOptions);
|
||||
|
||||
logGlobal->debugStream() << "\tGenerate list of hero placeholders";
|
||||
const auto campaignHeroReplacements = generateCampaignHeroesToReplace(crossoverHeroes);
|
||||
auto campaignHeroReplacements = generateCampaignHeroesToReplace(crossoverHeroes);
|
||||
|
||||
logGlobal->debugStream() << "\tPrepare crossover heroes";
|
||||
prepareCrossoverHeroes(campaignHeroReplacements, scenarioOps->campState->getCurrentScenario().travelOptions);
|
||||
|
||||
// remove same heroes on the map which will be added through crossover heroes
|
||||
// INFO: we will remove heroes because later it may be possible that the API doesn't allow having heroes
|
||||
@ -1121,7 +1138,7 @@ void CGameState::placeCampaignHeroes()
|
||||
|
||||
for(auto & campaignHeroReplacement : campaignHeroReplacements)
|
||||
{
|
||||
auto hero = getUsedHero(HeroTypeID(campaignHeroReplacement.first->subID));
|
||||
auto hero = getUsedHero(HeroTypeID(campaignHeroReplacement.hero->subID));
|
||||
if(hero)
|
||||
{
|
||||
removedHeroes.push_back(hero);
|
||||
@ -1176,30 +1193,58 @@ void CGameState::placeStartingHero(PlayerColor playerColor, HeroTypeID heroTypeI
|
||||
map->getEditManager()->insertObject(hero, townPos);
|
||||
}
|
||||
|
||||
std::vector<CGHeroInstance *> CGameState::getCrossoverHeroesFromPreviousScenario() const
|
||||
CGameState::CrossoverHeroesList CGameState::getCrossoverHeroesFromPreviousScenarios() const
|
||||
{
|
||||
std::vector<CGHeroInstance *> crossoverHeroes;
|
||||
CrossoverHeroesList crossoverHeroes;
|
||||
|
||||
auto campaignState = scenarioOps->campState;
|
||||
auto bonus = campaignState->getBonusForCurrentMap();
|
||||
if (bonus->type == CScenarioTravel::STravelBonus::HEROES_FROM_PREVIOUS_SCENARIO)
|
||||
{
|
||||
crossoverHeroes = campaignState->camp->scenarios[bonus->info2].crossoverHeroes;
|
||||
crossoverHeroes.heroesFromAnyPreviousScenarios = crossoverHeroes.heroesFromPreviousScenario = campaignState->camp->scenarios[bonus->info2].crossoverHeroes;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!campaignState->mapsConquered.empty())
|
||||
{
|
||||
crossoverHeroes = campaignState->camp->scenarios[campaignState->mapsConquered.back()].crossoverHeroes;
|
||||
crossoverHeroes.heroesFromPreviousScenario = campaignState->camp->scenarios[campaignState->mapsConquered.back()].crossoverHeroes;
|
||||
|
||||
for(auto mapNr : campaignState->mapsConquered)
|
||||
{
|
||||
// create a list of deleted heroes
|
||||
auto & scenario = campaignState->camp->scenarios[mapNr];
|
||||
auto lostCrossoverHeroes = scenario.getLostCrossoverHeroes();
|
||||
|
||||
// remove heroes which didn't reached the end of the scenario, but were available at the start
|
||||
for(auto hero : lostCrossoverHeroes)
|
||||
{
|
||||
range::remove_if(crossoverHeroes.heroesFromAnyPreviousScenarios, CGObjectInstanceBySubIdFinder(hero));
|
||||
}
|
||||
|
||||
// now add heroes which completed the scenario
|
||||
for(auto hero : scenario.crossoverHeroes)
|
||||
{
|
||||
// add new heroes and replace old heroes with newer ones
|
||||
range::remove_if(crossoverHeroes.heroesFromAnyPreviousScenarios, CGObjectInstanceBySubIdFinder(hero));
|
||||
crossoverHeroes.heroesFromAnyPreviousScenarios.push_back(hero);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return std::move(crossoverHeroes);
|
||||
}
|
||||
|
||||
std::vector<CGHeroInstance *> CGameState::prepareCrossoverHeroes(const std::vector<CGHeroInstance *> & sourceCrossoverHeroes, const CScenarioTravel & travelOptions)
|
||||
void CGameState::prepareCrossoverHeroes(std::vector<CGameState::CampaignHeroReplacement> & campaignHeroReplacements, const CScenarioTravel & travelOptions) const
|
||||
{
|
||||
auto crossoverHeroes = sourceCrossoverHeroes; //TODO deep copy hero instances
|
||||
//TODO deep copy hero instances
|
||||
|
||||
// create heroes list for convenience iterating
|
||||
std::vector<CGHeroInstance *> crossoverHeroes;
|
||||
for(auto & campaignHeroReplacement : campaignHeroReplacements)
|
||||
{
|
||||
crossoverHeroes.push_back(campaignHeroReplacement.hero);
|
||||
}
|
||||
|
||||
if(!(travelOptions.whatHeroKeeps & 1))
|
||||
{
|
||||
@ -1280,8 +1325,6 @@ std::vector<CGHeroInstance *> CGameState::prepareCrossoverHeroes(const std::vect
|
||||
return !(travelOptions.monstersKeptByHero[crid / 8] & (1 << (crid % 8)) );
|
||||
});
|
||||
}
|
||||
|
||||
return std::move(crossoverHeroes);
|
||||
}
|
||||
|
||||
void CGameState::placeStartingHeroes()
|
||||
@ -2696,9 +2739,9 @@ std::set<HeroTypeID> CGameState::getUnusedAllowedHeroes(bool alsoIncludeNotAllow
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<std::pair<CGHeroInstance*, ObjectInstanceID> > CGameState::generateCampaignHeroesToReplace(std::vector<CGHeroInstance *> & crossoverHeroes)
|
||||
std::vector<CGameState::CampaignHeroReplacement> CGameState::generateCampaignHeroesToReplace(CrossoverHeroesList & crossoverHeroes)
|
||||
{
|
||||
std::vector<std::pair<CGHeroInstance*, ObjectInstanceID> > campaignHeroReplacements;
|
||||
std::vector<CampaignHeroReplacement> campaignHeroReplacements;
|
||||
|
||||
auto removeHeroPlaceholder = [this](CGHeroPlaceholder * heroPlaceholder)
|
||||
{
|
||||
@ -2708,56 +2751,50 @@ std::vector<std::pair<CGHeroInstance*, ObjectInstanceID> > CGameState::generateC
|
||||
};
|
||||
|
||||
//selecting heroes by type
|
||||
for(int g = 0; g < map->objects.size(); ++g)
|
||||
for(auto obj : map->objects)
|
||||
{
|
||||
CGObjectInstance * obj = map->objects[g];
|
||||
if(obj && obj->ID == Obj::HERO_PLACEHOLDER)
|
||||
{
|
||||
CGHeroPlaceholder * hp = static_cast<CGHeroPlaceholder*>(obj);
|
||||
|
||||
const ObjectInstanceID gid = ObjectInstanceID(g);
|
||||
if(hp->subID != 0xFF) //select by type
|
||||
auto heroPlaceholder = dynamic_cast<CGHeroPlaceholder *>(obj.get());
|
||||
if(heroPlaceholder->subID != 0xFF) //select by type
|
||||
{
|
||||
bool found = false;
|
||||
for(auto ghi : crossoverHeroes)
|
||||
auto it = range::find_if(crossoverHeroes.heroesFromAnyPreviousScenarios, [heroPlaceholder](CGHeroInstance * hero)
|
||||
{
|
||||
if (ghi->subID == hp->subID)
|
||||
return hero->subID == heroPlaceholder->subID;
|
||||
});
|
||||
if(it == crossoverHeroes.heroesFromAnyPreviousScenarios.end())
|
||||
{
|
||||
found = true;
|
||||
campaignHeroReplacements.push_back(std::make_pair(ghi, gid));
|
||||
crossoverHeroes -= ghi;
|
||||
break;
|
||||
removeHeroPlaceholder(heroPlaceholder);
|
||||
}
|
||||
}
|
||||
if(!found)
|
||||
else
|
||||
{
|
||||
removeHeroPlaceholder(hp);
|
||||
campaignHeroReplacements.push_back(CampaignHeroReplacement(*it, obj->id));
|
||||
crossoverHeroes.removeHeroFromBothLists(*it);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//selecting heroes by power
|
||||
std::sort(crossoverHeroes.begin(), crossoverHeroes.end(), [](const CGHeroInstance * a, const CGHeroInstance * b)
|
||||
range::sort(crossoverHeroes.heroesFromPreviousScenario, [](const CGHeroInstance * a, const CGHeroInstance * b)
|
||||
{
|
||||
return a->getHeroStrength() > b->getHeroStrength();
|
||||
}); //sort, descending strength
|
||||
|
||||
// sort hero placeholders descending power
|
||||
std::vector<CGHeroPlaceholder *> heroPlaceholders;
|
||||
for(int g = 0; g < map->objects.size(); ++g)
|
||||
for(auto obj : map->objects)
|
||||
{
|
||||
CGObjectInstance * obj = map->objects[g];
|
||||
if(obj && obj->ID == Obj::HERO_PLACEHOLDER)
|
||||
{
|
||||
CGHeroPlaceholder * hp = dynamic_cast<CGHeroPlaceholder*>(obj);
|
||||
if(hp->subID == 0xFF) //select by power
|
||||
auto heroPlaceholder = dynamic_cast<CGHeroPlaceholder *>(obj.get());
|
||||
if(heroPlaceholder->subID == 0xFF) //select by power
|
||||
{
|
||||
heroPlaceholders.push_back(hp);
|
||||
heroPlaceholders.push_back(heroPlaceholder);
|
||||
}
|
||||
}
|
||||
}
|
||||
std::sort(heroPlaceholders.begin(), heroPlaceholders.end(), [](const CGHeroPlaceholder * a, const CGHeroPlaceholder * b)
|
||||
range::sort(heroPlaceholders, [](const CGHeroPlaceholder * a, const CGHeroPlaceholder * b)
|
||||
{
|
||||
return a->power > b->power;
|
||||
});
|
||||
@ -2765,9 +2802,9 @@ std::vector<std::pair<CGHeroInstance*, ObjectInstanceID> > CGameState::generateC
|
||||
for(int i = 0; i < heroPlaceholders.size(); ++i)
|
||||
{
|
||||
auto heroPlaceholder = heroPlaceholders[i];
|
||||
if(crossoverHeroes.size() > i)
|
||||
if(crossoverHeroes.heroesFromPreviousScenario.size() > i)
|
||||
{
|
||||
campaignHeroReplacements.push_back(std::make_pair(crossoverHeroes[i], heroPlaceholder->id));
|
||||
campaignHeroReplacements.push_back(CampaignHeroReplacement(crossoverHeroes.heroesFromPreviousScenario[i], heroPlaceholder->id));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2778,16 +2815,16 @@ std::vector<std::pair<CGHeroInstance*, ObjectInstanceID> > CGameState::generateC
|
||||
return campaignHeroReplacements;
|
||||
}
|
||||
|
||||
void CGameState::replaceHeroesPlaceholders(const std::vector<std::pair<CGHeroInstance*, ObjectInstanceID> > &campHeroReplacements)
|
||||
void CGameState::replaceHeroesPlaceholders(const std::vector<CGameState::CampaignHeroReplacement> & campaignHeroReplacements)
|
||||
{
|
||||
for(auto obj : campHeroReplacements)
|
||||
for(auto campaignHeroReplacement : campaignHeroReplacements)
|
||||
{
|
||||
CGHeroPlaceholder *placeholder = dynamic_cast<CGHeroPlaceholder*>(getObjInstance(obj.second));
|
||||
auto heroPlaceholder = dynamic_cast<CGHeroPlaceholder*>(getObjInstance(campaignHeroReplacement.heroPlaceholderId));
|
||||
|
||||
CGHeroInstance *heroToPlace = obj.first;
|
||||
heroToPlace->id = obj.second;
|
||||
heroToPlace->tempOwner = placeholder->tempOwner;
|
||||
heroToPlace->pos = placeholder->pos;
|
||||
CGHeroInstance *heroToPlace = campaignHeroReplacement.hero;
|
||||
heroToPlace->id = campaignHeroReplacement.heroPlaceholderId;
|
||||
heroToPlace->tempOwner = heroPlaceholder->tempOwner;
|
||||
heroToPlace->pos = heroPlaceholder->pos;
|
||||
heroToPlace->type = VLC->heroh->heroes[heroToPlace->subID];
|
||||
|
||||
for(auto &&i : heroToPlace->stacks)
|
||||
@ -2808,6 +2845,8 @@ void CGameState::replaceHeroesPlaceholders(const std::vector<std::pair<CGHeroIns
|
||||
map->heroesOnMap.push_back(heroToPlace);
|
||||
map->objects[heroToPlace->id.getNum()] = heroToPlace;
|
||||
map->addBlockVisTiles(heroToPlace);
|
||||
|
||||
scenarioOps->campState->getCurrentScenario().placedCrossoverHeroes.push_back(heroToPlace);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -460,6 +460,20 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
struct CrossoverHeroesList
|
||||
{
|
||||
std::vector<CGHeroInstance *> heroesFromPreviousScenario, heroesFromAnyPreviousScenarios;
|
||||
void addHeroToBothLists(CGHeroInstance * hero);
|
||||
void removeHeroFromBothLists(CGHeroInstance * hero);
|
||||
};
|
||||
|
||||
struct CampaignHeroReplacement
|
||||
{
|
||||
CampaignHeroReplacement(CGHeroInstance * hero, ObjectInstanceID heroPlaceholderId);
|
||||
CGHeroInstance * hero;
|
||||
ObjectInstanceID heroPlaceholderId;
|
||||
};
|
||||
|
||||
// ----- initialization -----
|
||||
|
||||
void initNewGame();
|
||||
@ -472,15 +486,15 @@ private:
|
||||
void randomizeObject(CGObjectInstance *cur);
|
||||
void initPlayerStates();
|
||||
void placeCampaignHeroes();
|
||||
std::vector<CGHeroInstance *> getCrossoverHeroesFromPreviousScenario() const;
|
||||
|
||||
/// gets prepared and copied hero instances with crossover heroes from prev. scenario and travel options from current scenario
|
||||
std::vector<CGHeroInstance *> prepareCrossoverHeroes(const std::vector<CGHeroInstance *> & sourceCrossoverHeroes, const CScenarioTravel & travelOptions);
|
||||
CrossoverHeroesList getCrossoverHeroesFromPreviousScenarios() const;
|
||||
|
||||
/// returns heroes and placeholders in where heroes will be put
|
||||
std::vector<std::pair<CGHeroInstance*, ObjectInstanceID> > generateCampaignHeroesToReplace(std::vector<CGHeroInstance *> & crossoverHeroes);
|
||||
std::vector<CampaignHeroReplacement> generateCampaignHeroesToReplace(CrossoverHeroesList & crossoverHeroes);
|
||||
|
||||
void replaceHeroesPlaceholders(const std::vector<std::pair<CGHeroInstance*, ObjectInstanceID> > &campHeroReplacements);
|
||||
/// gets prepared and copied hero instances with crossover heroes from prev. scenario and travel options from current scenario
|
||||
void prepareCrossoverHeroes(std::vector<CampaignHeroReplacement> & campaignHeroReplacements, const CScenarioTravel & travelOptions) const;
|
||||
|
||||
void replaceHeroesPlaceholders(const std::vector<CampaignHeroReplacement> & campaignHeroReplacements);
|
||||
void placeStartingHeroes();
|
||||
void placeStartingHero(PlayerColor playerColor, HeroTypeID heroTypeId, int3 townPos);
|
||||
void initStartingResources();
|
||||
|
@ -94,6 +94,7 @@ set(lib_HEADERS
|
||||
int3.h
|
||||
Interprocess.h
|
||||
NetPacks.h
|
||||
NetPacksBase.h
|
||||
RegisterTypes.h
|
||||
StartInfo.h
|
||||
UnlockGuard.h
|
||||
|
@ -519,6 +519,16 @@ bool CGObjectInstance::passableFor(PlayerColor color) const
|
||||
return getPassableness() & 1<<color.getNum();
|
||||
}
|
||||
|
||||
CGObjectInstanceBySubIdFinder::CGObjectInstanceBySubIdFinder(CGObjectInstance * obj) : obj(obj)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool CGObjectInstanceBySubIdFinder::operator()(CGObjectInstance * obj) const
|
||||
{
|
||||
return this->obj->subID == obj->subID;
|
||||
}
|
||||
|
||||
static int lowestSpeed(const CGHeroInstance * chi)
|
||||
{
|
||||
if(!chi->Slots().size())
|
||||
|
@ -228,6 +228,18 @@ protected:
|
||||
void getNameVis(std::string &hname) const;
|
||||
void giveDummyBonus(ObjectInstanceID heroID, ui8 duration = Bonus::ONE_DAY) const;
|
||||
};
|
||||
|
||||
/// function object which can be used to find an object with an specific sub ID
|
||||
class CGObjectInstanceBySubIdFinder
|
||||
{
|
||||
public:
|
||||
CGObjectInstanceBySubIdFinder(CGObjectInstance * obj);
|
||||
bool operator()(CGObjectInstance * obj) const;
|
||||
|
||||
private:
|
||||
CGObjectInstance * obj;
|
||||
};
|
||||
|
||||
class CGHeroPlaceholder : public CGObjectInstance
|
||||
{
|
||||
public:
|
||||
|
@ -337,6 +337,23 @@ const CGHeroInstance * CCampaignScenario::strongestHero( PlayerColor owner ) con
|
||||
return i == ownedHeroes.end() ? nullptr : *i;
|
||||
}
|
||||
|
||||
std::vector<CGHeroInstance *> CCampaignScenario::getLostCrossoverHeroes() const
|
||||
{
|
||||
std::vector<CGHeroInstance *> lostCrossoverHeroes;
|
||||
if(conquered)
|
||||
{
|
||||
for(auto hero : placedCrossoverHeroes)
|
||||
{
|
||||
auto it = range::find_if(crossoverHeroes, CGObjectInstanceBySubIdFinder(hero));
|
||||
if(it == crossoverHeroes.end())
|
||||
{
|
||||
lostCrossoverHeroes.push_back(hero);
|
||||
}
|
||||
}
|
||||
}
|
||||
return std::move(lostCrossoverHeroes);
|
||||
}
|
||||
|
||||
bool CScenarioTravel::STravelBonus::isBonusForHero() const
|
||||
{
|
||||
return type == SPELL || type == MONSTER || type == ARTIFACT || type == SPELL_SCROLL || type == PRIMARY_SKILL
|
||||
@ -376,6 +393,11 @@ const CCampaignScenario & CCampaignState::getCurrentScenario() const
|
||||
return camp->scenarios[*currentMap];
|
||||
}
|
||||
|
||||
CCampaignScenario & CCampaignState::getCurrentScenario()
|
||||
{
|
||||
return camp->scenarios[*currentMap];
|
||||
}
|
||||
|
||||
ui8 CCampaignState::currentBonusID() const
|
||||
{
|
||||
return chosenCampaignBonuses.at(*currentMap);
|
||||
|
@ -109,15 +109,17 @@ public:
|
||||
|
||||
CScenarioTravel travelOptions;
|
||||
std::vector<CGHeroInstance *> crossoverHeroes; // contains all heroes with the same state when the campaign scenario was finished
|
||||
std::vector<CGHeroInstance *> placedCrossoverHeroes; // contains all placed crossover heroes defined by hero placeholders when the scenario was started
|
||||
|
||||
const CGHeroInstance * strongestHero(PlayerColor owner) const;
|
||||
void loadPreconditionRegions(ui32 regions);
|
||||
bool isNotVoid() const;
|
||||
std::vector<CGHeroInstance *> getLostCrossoverHeroes() const; /// returns a list of crossover heroes which started the scenario, but didn't complete it
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int formatVersion)
|
||||
{
|
||||
h & mapName & scenarioName & packedMapSize & preconditionRegions & regionColor & difficulty & conquered & regionText &
|
||||
prolog & epilog & travelOptions & crossoverHeroes;
|
||||
prolog & epilog & travelOptions & crossoverHeroes & placedCrossoverHeroes;
|
||||
}
|
||||
};
|
||||
|
||||
@ -152,6 +154,7 @@ public:
|
||||
void setCurrentMapAsConquered(const std::vector<CGHeroInstance*> & heroes);
|
||||
boost::optional<CScenarioTravel::STravelBonus> getBonusForCurrentMap() const;
|
||||
const CCampaignScenario & getCurrentScenario() const;
|
||||
CCampaignScenario & getCurrentScenario();
|
||||
ui8 currentBonusID() const;
|
||||
|
||||
CCampaignState();
|
||||
|
@ -9,23 +9,21 @@
|
||||
*/
|
||||
|
||||
#include "StdInc.h"
|
||||
#include "MapFormatH3M.h"
|
||||
|
||||
#include <boost/crc.hpp>
|
||||
|
||||
#include "../CStopWatch.h"
|
||||
|
||||
#include "../filesystem/Filesystem.h"
|
||||
#include "MapFormatH3M.h"
|
||||
#include "CMap.h"
|
||||
|
||||
#include "../CStopWatch.h"
|
||||
#include "../filesystem/Filesystem.h"
|
||||
#include "../CSpellHandler.h"
|
||||
#include "../CCreatureHandler.h"
|
||||
#include "../CGeneralTextHandler.h"
|
||||
#include "../CHeroHandler.h"
|
||||
#include "../CObjectHandler.h"
|
||||
#include "../CDefObjInfoHandler.h"
|
||||
|
||||
#include "../VCMI_Lib.h"
|
||||
#include "../NetPacksBase.h"
|
||||
|
||||
|
||||
const bool CMapLoaderH3M::IS_PROFILING_ENABLED = false;
|
||||
@ -442,7 +440,6 @@ void CMapLoaderH3M::readVictoryLossConditions()
|
||||
{
|
||||
EventCondition cond(EventCondition::CONTROL);
|
||||
cond.objectType = Obj::CREATURE_GENERATOR1; // FIXME: generators 2-4?
|
||||
cond.position = readInt3();
|
||||
|
||||
specialVictory.effect.toOtherMessage = VLC->generaltexth->allTexts[289];
|
||||
specialVictory.onFulfill = VLC->generaltexth->allTexts[288];
|
||||
@ -473,7 +470,7 @@ void CMapLoaderH3M::readVictoryLossConditions()
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
//bool allowNormalVictory = reader.readBool();
|
||||
|
||||
// if condition is human-only turn it into following construction: AllOf(human, condition)
|
||||
if (!appliesToAI)
|
||||
{
|
||||
@ -869,7 +866,17 @@ bool CMapLoaderH3M::loadArtifactToSlot(CGHeroInstance * hero, int slot)
|
||||
slot = ArtifactPosition::SPELLBOOK;
|
||||
}
|
||||
|
||||
hero->putArtifact(ArtifactPosition(slot), createArtifact(aid));
|
||||
// this is needed, because some H3M maps (last scenario of ROE map) contain invalid data like misplaced artifacts
|
||||
auto artifact = createArtifact(aid);
|
||||
auto artifactPos = ArtifactPosition(slot);
|
||||
if (artifact->canBePutAt(ArtifactLocation(hero, artifactPos)))
|
||||
{
|
||||
hero->putArtifact(artifactPos, artifact);
|
||||
}
|
||||
else
|
||||
{
|
||||
logGlobal->debugStream() << "Artifact can't be put at the specified location."; //TODO add more debugging information
|
||||
}
|
||||
}
|
||||
|
||||
return isArt;
|
||||
|
Loading…
Reference in New Issue
Block a user