diff --git a/lib/GameConstants.h b/lib/GameConstants.h index 2c11cb431..11ec82534 100644 --- a/lib/GameConstants.h +++ b/lib/GameConstants.h @@ -1223,6 +1223,7 @@ class SpellID public: enum ESpellID { + SPELLBOOK_PRESET = -3, PRESET = -2, NONE = -1, SUMMON_BOAT=0, SCUTTLE_BOAT=1, VISIONS=2, VIEW_EARTH=3, DISGUISE=4, VIEW_AIR=5, diff --git a/lib/mapObjects/CGHeroInstance.cpp b/lib/mapObjects/CGHeroInstance.cpp index 8fb292b50..dfbe598b3 100644 --- a/lib/mapObjects/CGHeroInstance.cpp +++ b/lib/mapObjects/CGHeroInstance.cpp @@ -287,16 +287,23 @@ void CGHeroInstance::initHero(CRandomGenerator & rand) if (ID == Obj::HERO) appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, type->heroClass->getIndex())->getTemplates().front(); - if(!vstd::contains(spells, SpellID::PRESET)) //hero starts with a spell + if(!vstd::contains(spells, SpellID::PRESET)) { + // hero starts with default spells for(const auto & spellID : type->spells) spells.insert(spellID); } else //remove placeholder spells -= SpellID::PRESET; - if(!getArt(ArtifactPosition::MACH4) && !getArt(ArtifactPosition::SPELLBOOK) && type->haveSpellBook) //no catapult means we haven't read pre-existent set -> use default rules for spellbook - putArtifact(ArtifactPosition::SPELLBOOK, ArtifactUtils::createNewArtifactInstance(ArtifactID::SPELLBOOK)); + if(!vstd::contains(spells, SpellID::SPELLBOOK_PRESET)) + { + // hero starts with default spellbook presence status + if(!getArt(ArtifactPosition::SPELLBOOK) && type->haveSpellBook) + putArtifact(ArtifactPosition::SPELLBOOK, ArtifactUtils::createNewArtifactInstance(ArtifactID::SPELLBOOK)); + } + else + spells -= SpellID::SPELLBOOK_PRESET; if(!getArt(ArtifactPosition::MACH4)) putArtifact(ArtifactPosition::MACH4, ArtifactUtils::createNewArtifactInstance(ArtifactID::CATAPULT)); //everyone has a catapult diff --git a/lib/mapping/MapFormatH3M.cpp b/lib/mapping/MapFormatH3M.cpp index 553763eb4..665e38339 100644 --- a/lib/mapping/MapFormatH3M.cpp +++ b/lib/mapping/MapFormatH3M.cpp @@ -878,6 +878,9 @@ void CMapLoaderH3M::loadArtifactsOfHero(CGHeroInstance * hero) if(!hasArtSet) return; + // Workaround - if hero has customized artifacts game should not attempt to add spellbook based on hero type + hero->spells.insert(SpellID::SPELLBOOK_PRESET); + if(!hero->artifactsWorn.empty() || !hero->artifactsInBackpack.empty()) { logGlobal->warn("Hero %s at %s has set artifacts twice (in map properties and on adventure map instance). Using the latter set...", hero->getNameTranslated(), hero->pos.toString());