1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-02-03 13:01:33 +02:00

Added hacks fot spell scroll support.

This commit is contained in:
AlexVinS 2016-02-13 19:43:05 +03:00
parent 7106c5d1af
commit e0af4a665a
8 changed files with 85 additions and 48 deletions

View File

@ -23,6 +23,7 @@
#include "CRandomGenerator.h"
#include "mapObjects/CObjectClassesHandler.h"
#include "mapping/CMap.h"
// Note: list must match entries in ArtTraits.txt
#define ART_POS_LIST \
@ -963,6 +964,40 @@ CArtifactInstance * CArtifactInstance::createNewArtifactInstance(int aid)
return createNewArtifactInstance(VLC->arth->artifacts[aid]);
}
CArtifactInstance * CArtifactInstance::createArtifact(CMap * map, int aid, int spellID)
{
CArtifactInstance * a = nullptr;
if(aid >= 0)
{
if(spellID < 0)
{
a = CArtifactInstance::createNewArtifactInstance(aid);
}
else
{
a = CArtifactInstance::createScroll(SpellID(spellID).toSpell());
}
}
else //FIXME: create combined artifact instance for random combined artifacts, just in case
{
a = new CArtifactInstance(); //random, empty
}
map->addNewArtifactInstance(a);
//TODO make it nicer
if(a->artType && (!!a->artType->constituents))
{
CCombinedArtifactInstance * comb = dynamic_cast<CCombinedArtifactInstance *>(a);
for(CCombinedArtifactInstance::ConstituentInfo & ci : comb->constituentsInfo)
{
map->addNewArtifactInstance(ci.art);
}
}
return a;
}
void CArtifactInstance::deserializationFix()
{
setType(artType);

View File

@ -25,6 +25,7 @@ struct ArtifactLocation;
class CArtifactSet;
class CArtifactInstance;
class CRandomGenerator;
class CMap;
#define ART_BEARER_LIST \
ART_BEARER(HERO)\
@ -152,6 +153,15 @@ public:
static CArtifactInstance *createScroll(SpellID sid);
static CArtifactInstance *createNewArtifactInstance(CArtifact *Art);
static CArtifactInstance *createNewArtifactInstance(int aid);
/**
* Creates an artifact instance.
*
* @param aid the id of the artifact
* @param spellID optional. the id of a spell if a spell scroll object should be created
* @return the created artifact instance
*/
static CArtifactInstance * createArtifact(CMap * map, int aid, int spellID = -1);
};
class DLL_LINKAGE CCombinedArtifactInstance : public CArtifactInstance

View File

@ -1443,6 +1443,13 @@ void CGArtifact::writeJsonOptions(JsonNode& json) const
{
CCreatureSet::writeJson(json["guards"]);
json["guardMessage"].String() = message;
if(ID == Obj::SPELL_SCROLL)
{
const Bonus * b = storedArtifact->getBonusLocalFirst(Selector::type(Bonus::SPELL));
SpellID spellId(b->subtype);
json["spell"].String() = SpellID(b->subtype).toSpell()->identifier;
}
}
void CGArtifact::readJsonOptions(const JsonNode& json)

View File

@ -14,6 +14,8 @@
*
*/
class CMap;
class DLL_LINKAGE CPlayersVisited: public CGObjectInstance
{
public:

View File

@ -5,6 +5,7 @@
#include "../filesystem/CBinaryReader.h"
#include "../filesystem/CCompressedStream.h"
#include "../filesystem/CMemoryStream.h"
#include "CMap.h"
#include "MapFormatH3M.h"

View File

@ -828,7 +828,7 @@ void CMapLoaderH3M::loadArtifactsOfHero(CGHeroInstance * hero)
{
// catapult by default
assert(!hero->getArt(ArtifactPosition::MACH4));
hero->putArtifact(ArtifactPosition::MACH4, createArtifact(ArtifactID::CATAPULT));
hero->putArtifact(ArtifactPosition::MACH4, CArtifactInstance::createArtifact(map, ArtifactID::CATAPULT));
}
}
@ -885,7 +885,7 @@ bool CMapLoaderH3M::loadArtifactToSlot(CGHeroInstance * hero, int slot)
}
// this is needed, because some H3M maps (last scenario of ROE map) contain invalid data like misplaced artifacts
auto artifact = createArtifact(aid);
auto artifact = CArtifactInstance::createArtifact(map, aid);
auto artifactPos = ArtifactPosition(slot);
if (artifact->canBePutAt(ArtifactLocation(hero, artifactPos)))
{
@ -900,40 +900,6 @@ bool CMapLoaderH3M::loadArtifactToSlot(CGHeroInstance * hero, int slot)
return isArt;
}
CArtifactInstance * CMapLoaderH3M::createArtifact(int aid, int spellID /*= -1*/)
{
CArtifactInstance * a = nullptr;
if(aid >= 0)
{
if(spellID < 0)
{
a = CArtifactInstance::createNewArtifactInstance(aid);
}
else
{
a = CArtifactInstance::createScroll(SpellID(spellID).toSpell());
}
}
else //FIXME: create combined artifact instance for random combined artifacts, just in case
{
a = new CArtifactInstance(); //random, empty
}
map->addNewArtifactInstance(a);
//TODO make it nicer
if(a->artType && (!!a->artType->constituents))
{
CCombinedArtifactInstance * comb = dynamic_cast<CCombinedArtifactInstance *>(a);
for(CCombinedArtifactInstance::ConstituentInfo & ci : comb->constituentsInfo)
{
map->addNewArtifactInstance(ci.art);
}
}
return a;
}
void CMapLoaderH3M::readTerrain()
{
map->initTerrain();
@ -1236,7 +1202,7 @@ void CMapLoaderH3M::readObjects()
artID = objTempl.subid;
}
art->storedArtifact = createArtifact(artID, spellID);
art->storedArtifact = CArtifactInstance::createArtifact(map, artID, spellID);
break;
}
case Obj::RANDOM_RESOURCE:
@ -1998,7 +1964,7 @@ CGTownInstance * CMapLoaderH3M::readTown(int castleID)
ui8 c = reader.readUInt8();
for(int yy = 0; yy < 8; ++yy)
{
int spellid = i * 8 + yy;
int spellid = i * 8 + yy;
if(spellid < GameConstants::SPELLS_QUANTITY)
{
if(c != (c | static_cast<ui8>(std::pow(2., yy))) && map->allowedSpell[spellid]) //add random spell only if it's allowed on entire map

View File

@ -124,15 +124,6 @@ private:
*/
bool loadArtifactToSlot(CGHeroInstance * hero, int slot);
/**
* Creates an artifact instance.
*
* @param aid the id of the artifact
* @param spellID optional. the id of a spell if a spell scroll object should be created
* @return the created artifact instance
*/
CArtifactInstance * createArtifact(int aid, int spellID = -1);
/**
* Read rumors.
*/

View File

@ -657,11 +657,36 @@ void CMapLoaderJson::MapObjectLoader::configure()
{
owner->map->towns.push_back(static_cast<CGTownInstance *>(instance));
}
if(instance->ID == Obj::HERO)
else if(instance->ID == Obj::HERO)
{
logGlobal->debugStream() << "Hero: " << VLC->heroh->heroes[instance->subID]->name << " at " << instance->pos;
owner->map->heroesOnMap.push_back(static_cast<CGHeroInstance *>(instance));
}
else if(auto art = dynamic_cast<CGArtifact *>(instance))
{
//todo: find better place for this code
int artID = ArtifactID::NONE;
int spellID = -1;
if(art->ID == Obj::SPELL_SCROLL)
{
auto spellIdentifier = configuration["options"]["spell"].String();
auto rawId = VLC->modh->identifiers.getIdentifier("core", "spell", spellIdentifier);
if(rawId)
spellID = rawId.get();
else
spellID = 0;
artID = ArtifactID::SPELL_SCROLL;
}
else if(art->ID == Obj::ARTIFACT)
{
//specific artifact
artID = art->subID;
}
art->storedArtifact = CArtifactInstance::createArtifact(owner->map, artID, spellID);
}
}
void CMapLoaderJson::readObjects()