mirror of
https://github.com/vcmi/vcmi.git
synced 2025-02-05 13:04:54 +02:00
Refactored loadObject() monstrocity into set of smaller methods.
This commit is contained in:
parent
c0e9eb6eb1
commit
3790661fa6
@ -936,192 +936,153 @@ void CMapLoaderH3M::readDefInfo()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMapLoaderH3M::readObjects()
|
CGObjectInstance * CMapLoaderH3M::readEvent(const int3 & objPos)
|
||||||
{
|
{
|
||||||
uint32_t howManyObjs = reader->readUInt32();
|
auto * object = new CGEvent();
|
||||||
|
|
||||||
for(uint32_t ww = 0; ww < howManyObjs; ++ww)
|
readBoxContent(object, objPos);
|
||||||
{
|
|
||||||
CGObjectInstance * nobj = nullptr;
|
|
||||||
|
|
||||||
int3 objPos = reader->readInt3();
|
object->availableFor = reader->readUInt8();
|
||||||
|
object->computerActivate = reader->readBool();
|
||||||
uint32_t defnum = reader->readUInt32();
|
object->removeAfterVisit = reader->readBool();
|
||||||
ObjectInstanceID idToBeGiven = ObjectInstanceID(static_cast<si32>(map->objects.size()));
|
object->humanActivate = true;
|
||||||
|
|
||||||
std::shared_ptr<const ObjectTemplate> objTempl = templates.at(defnum);
|
|
||||||
reader->skipZero(5);
|
|
||||||
|
|
||||||
switch(objTempl->id)
|
|
||||||
{
|
|
||||||
case Obj::EVENT:
|
|
||||||
{
|
|
||||||
auto * evnt = new CGEvent();
|
|
||||||
nobj = evnt;
|
|
||||||
|
|
||||||
readMessageAndGuards(evnt->message, evnt, objPos);
|
|
||||||
|
|
||||||
evnt->gainedExp = reader->readUInt32();
|
|
||||||
evnt->manaDiff = reader->readInt32();
|
|
||||||
evnt->moraleDiff = reader->readInt8();
|
|
||||||
evnt->luckDiff = reader->readInt8();
|
|
||||||
|
|
||||||
reader->readResourses(evnt->resources);
|
|
||||||
|
|
||||||
evnt->primskills.resize(GameConstants::PRIMARY_SKILLS);
|
|
||||||
for(int x = 0; x < 4; ++x)
|
|
||||||
{
|
|
||||||
evnt->primskills[x] = static_cast<PrimarySkill::PrimarySkill>(reader->readUInt8());
|
|
||||||
}
|
|
||||||
|
|
||||||
int gabn = reader->readUInt8(); // Number of gained abilities
|
|
||||||
for(int oo = 0; oo < gabn; ++oo)
|
|
||||||
{
|
|
||||||
evnt->abilities.emplace_back(reader->readSkill());
|
|
||||||
evnt->abilityLevels.push_back(reader->readUInt8());
|
|
||||||
}
|
|
||||||
|
|
||||||
int gart = reader->readUInt8(); // Number of gained artifacts
|
|
||||||
for(int oo = 0; oo < gart; ++oo)
|
|
||||||
evnt->artifacts.emplace_back(reader->readArtifact());
|
|
||||||
|
|
||||||
int gspel = reader->readUInt8(); // Number of gained spells
|
|
||||||
for(int oo = 0; oo < gspel; ++oo)
|
|
||||||
{
|
|
||||||
evnt->spells.emplace_back(reader->readSpell());
|
|
||||||
}
|
|
||||||
|
|
||||||
int gcre = reader->readUInt8(); //number of gained creatures
|
|
||||||
readCreatureSet(&evnt->creatures, gcre);
|
|
||||||
|
|
||||||
reader->skipZero(8);
|
|
||||||
evnt->availableFor = reader->readUInt8();
|
|
||||||
evnt->computerActivate = reader->readBool();
|
|
||||||
evnt->removeAfterVisit = reader->readBool();
|
|
||||||
evnt->humanActivate = true;
|
|
||||||
|
|
||||||
reader->skipZero(4);
|
reader->skipZero(4);
|
||||||
break;
|
return object;
|
||||||
}
|
}
|
||||||
case Obj::HERO:
|
|
||||||
case Obj::RANDOM_HERO:
|
CGObjectInstance * CMapLoaderH3M::readPandora(const int3 & position)
|
||||||
case Obj::PRISON:
|
{
|
||||||
|
auto * object = new CGPandoraBox();
|
||||||
|
readBoxContent(object, position);
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMapLoaderH3M::readBoxContent(CGPandoraBox * object, const int3 & position)
|
||||||
|
{
|
||||||
|
readMessageAndGuards(object->message, object, position);
|
||||||
|
|
||||||
|
object->gainedExp = reader->readUInt32();
|
||||||
|
object->manaDiff = reader->readInt32();
|
||||||
|
object->moraleDiff = reader->readInt8();
|
||||||
|
object->luckDiff = reader->readInt8();
|
||||||
|
|
||||||
|
reader->readResourses(object->resources);
|
||||||
|
|
||||||
|
object->primskills.resize(GameConstants::PRIMARY_SKILLS);
|
||||||
|
for(int x = 0; x < GameConstants::PRIMARY_SKILLS; ++x)
|
||||||
|
object->primskills[x] = static_cast<PrimarySkill::PrimarySkill>(reader->readUInt8());
|
||||||
|
|
||||||
|
int gabn = reader->readUInt8();//number of gained abilities
|
||||||
|
for(int oo = 0; oo < gabn; ++oo)
|
||||||
{
|
{
|
||||||
nobj = readHero(idToBeGiven, objPos);
|
object->abilities.emplace_back(reader->readSkill());
|
||||||
break;
|
object->abilityLevels.push_back(reader->readUInt8());
|
||||||
}
|
}
|
||||||
case Obj::MONSTER: //Monster
|
int gart = reader->readUInt8(); //number of gained artifacts
|
||||||
case Obj::RANDOM_MONSTER:
|
for(int oo = 0; oo < gart; ++oo)
|
||||||
case Obj::RANDOM_MONSTER_L1:
|
object->artifacts.emplace_back(reader->readArtifact());
|
||||||
case Obj::RANDOM_MONSTER_L2:
|
|
||||||
case Obj::RANDOM_MONSTER_L3:
|
int gspel = reader->readUInt8(); //number of gained spells
|
||||||
case Obj::RANDOM_MONSTER_L4:
|
for(int oo = 0; oo < gspel; ++oo)
|
||||||
case Obj::RANDOM_MONSTER_L5:
|
object->spells.emplace_back(reader->readSpell());
|
||||||
case Obj::RANDOM_MONSTER_L6:
|
|
||||||
case Obj::RANDOM_MONSTER_L7:
|
int gcre = reader->readUInt8(); //number of gained creatures
|
||||||
{
|
readCreatureSet(&object->creatures, gcre);
|
||||||
auto * cre = new CGCreature();
|
reader->skipZero(8);
|
||||||
nobj = cre;
|
}
|
||||||
|
|
||||||
|
CGObjectInstance * CMapLoaderH3M::readMonster(const int3 & objPos, const ObjectInstanceID & idToBeGiven)
|
||||||
|
{
|
||||||
|
auto * object = new CGCreature();
|
||||||
|
|
||||||
if(features.levelAB)
|
if(features.levelAB)
|
||||||
{
|
{
|
||||||
cre->identifier = reader->readUInt32();
|
object->identifier = reader->readUInt32();
|
||||||
map->questIdentifierToId[cre->identifier] = idToBeGiven;
|
map->questIdentifierToId[object->identifier] = idToBeGiven;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto * hlp = new CStackInstance();
|
auto * hlp = new CStackInstance();
|
||||||
hlp->count = reader->readUInt16();
|
hlp->count = reader->readUInt16();
|
||||||
|
|
||||||
//type will be set during initialization
|
//type will be set during initialization
|
||||||
cre->putStack(SlotID(0), hlp);
|
object->putStack(SlotID(0), hlp);
|
||||||
|
|
||||||
cre->character = reader->readInt8();
|
object->character = reader->readInt8();
|
||||||
|
|
||||||
bool hasMessage = reader->readBool();
|
bool hasMessage = reader->readBool();
|
||||||
if(hasMessage)
|
if(hasMessage)
|
||||||
{
|
{
|
||||||
cre->message = readLocalizedString(TextIdentifier("monster", objPos.x, objPos.y, objPos.z, "message"));
|
object->message = readLocalizedString(TextIdentifier("monster", objPos.x, objPos.y, objPos.z, "message"));
|
||||||
reader->readResourses(cre->resources);
|
reader->readResourses(object->resources);
|
||||||
cre->gainedArtifact = reader->readArtifact();
|
object->gainedArtifact = reader->readArtifact();
|
||||||
}
|
}
|
||||||
cre->neverFlees = reader->readBool();
|
object->neverFlees = reader->readBool();
|
||||||
cre->notGrowingTeam = reader->readBool();
|
object->notGrowingTeam = reader->readBool();
|
||||||
reader->skipZero(2);
|
reader->skipZero(2);
|
||||||
break;
|
return object;
|
||||||
}
|
}
|
||||||
case Obj::OCEAN_BOTTLE:
|
|
||||||
case Obj::SIGN:
|
CGObjectInstance * CMapLoaderH3M::readSign(const int3 & objPos)
|
||||||
{
|
{
|
||||||
auto * sb = new CGSignBottle();
|
auto * object = new CGSignBottle();
|
||||||
nobj = sb;
|
object->message = readLocalizedString(TextIdentifier("sign", objPos.x, objPos.y, objPos.z, "message"));
|
||||||
sb->message = readLocalizedString(TextIdentifier("sign", objPos.x, objPos.y, objPos.z, "message"));
|
|
||||||
reader->skipZero(4);
|
reader->skipZero(4);
|
||||||
break;
|
return object;
|
||||||
}
|
}
|
||||||
case Obj::SEER_HUT:
|
|
||||||
{
|
CGObjectInstance * CMapLoaderH3M::readWitchHut(const int3 & position)
|
||||||
nobj = readSeerHut(objPos);
|
{
|
||||||
break;
|
auto * object = new CGWitchHut();
|
||||||
}
|
|
||||||
case Obj::WITCH_HUT:
|
|
||||||
{
|
|
||||||
auto * wh = new CGWitchHut();
|
|
||||||
nobj = wh;
|
|
||||||
|
|
||||||
// AB and later maps have allowed abilities defined in H3M
|
// AB and later maps have allowed abilities defined in H3M
|
||||||
if(features.levelAB)
|
if(features.levelAB)
|
||||||
{
|
{
|
||||||
reader->readBitmask(wh->allowedAbilities, features.skillsBytes, features.skillsCount, false);
|
reader->readBitmask(object->allowedAbilities, features.skillsBytes, features.skillsCount, false);
|
||||||
|
|
||||||
if(wh->allowedAbilities.size() != 1)
|
if(object->allowedAbilities.size() != 1)
|
||||||
{
|
{
|
||||||
auto defaultAllowed = VLC->skillh->getDefaultAllowed();
|
auto defaultAllowed = VLC->skillh->getDefaultAllowed();
|
||||||
|
|
||||||
for(int skillID = 0; skillID < VLC->skillh->size(); ++skillID)
|
for(int skillID = 0; skillID < VLC->skillh->size(); ++skillID)
|
||||||
if (defaultAllowed[skillID])
|
if (defaultAllowed[skillID])
|
||||||
wh->allowedAbilities.insert(skillID);
|
object->allowedAbilities.insert(skillID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
return object;
|
||||||
}
|
}
|
||||||
case Obj::SCHOLAR:
|
|
||||||
{
|
CGObjectInstance * CMapLoaderH3M::readScholar(const int3 & position)
|
||||||
auto * sch = new CGScholar();
|
{
|
||||||
nobj = sch;
|
auto * object = new CGScholar();
|
||||||
sch->bonusType = static_cast<CGScholar::EBonusType>(reader->readUInt8());
|
object->bonusType = static_cast<CGScholar::EBonusType>(reader->readUInt8());
|
||||||
sch->bonusID = reader->readUInt8();
|
object->bonusID = reader->readUInt8();
|
||||||
reader->skipZero(6);
|
reader->skipZero(6);
|
||||||
break;
|
return object;
|
||||||
}
|
}
|
||||||
case Obj::GARRISON:
|
|
||||||
case Obj::GARRISON2:
|
CGObjectInstance * CMapLoaderH3M::readGarrison(const int3 & position)
|
||||||
{
|
{
|
||||||
auto * gar = new CGGarrison();
|
auto * object = new CGGarrison();
|
||||||
nobj = gar;
|
|
||||||
nobj->setOwner(reader->readPlayer32());
|
object->setOwner(reader->readPlayer32());
|
||||||
readCreatureSet(gar, 7);
|
readCreatureSet(object, 7);
|
||||||
if(features.levelAB)
|
if(features.levelAB)
|
||||||
gar->removableUnits = reader->readBool();
|
object->removableUnits = reader->readBool();
|
||||||
else
|
else
|
||||||
gar->removableUnits = true;
|
object->removableUnits = true;
|
||||||
|
|
||||||
reader->skipZero(8);
|
reader->skipZero(8);
|
||||||
break;
|
return object;
|
||||||
}
|
}
|
||||||
case Obj::ARTIFACT:
|
|
||||||
case Obj::RANDOM_ART:
|
CGObjectInstance * CMapLoaderH3M::readArtifact(const int3 & objPos, std::shared_ptr<const ObjectTemplate> objTempl)
|
||||||
case Obj::RANDOM_TREASURE_ART:
|
{
|
||||||
case Obj::RANDOM_MINOR_ART:
|
|
||||||
case Obj::RANDOM_MAJOR_ART:
|
|
||||||
case Obj::RANDOM_RELIC_ART:
|
|
||||||
case Obj::SPELL_SCROLL:
|
|
||||||
{
|
|
||||||
auto artID = ArtifactID::NONE; //random, set later
|
auto artID = ArtifactID::NONE; //random, set later
|
||||||
int spellID = -1;
|
int spellID = -1;
|
||||||
auto * art = new CGArtifact();
|
auto * object = new CGArtifact();
|
||||||
nobj = art;
|
|
||||||
|
|
||||||
readMessageAndGuards(art->message, art, objPos);
|
readMessageAndGuards(object->message, object, objPos);
|
||||||
|
|
||||||
if(objTempl->id == Obj::SPELL_SCROLL)
|
if(objTempl->id == Obj::SPELL_SCROLL)
|
||||||
{
|
{
|
||||||
@ -1134,116 +1095,52 @@ void CMapLoaderH3M::readObjects()
|
|||||||
artID = ArtifactID(objTempl->subid);
|
artID = ArtifactID(objTempl->subid);
|
||||||
}
|
}
|
||||||
|
|
||||||
art->storedArtifact = CArtifactInstance::createArtifact(map, artID, spellID);
|
object->storedArtifact = CArtifactInstance::createArtifact(map, artID, spellID);
|
||||||
break;
|
return object;
|
||||||
}
|
}
|
||||||
case Obj::RANDOM_RESOURCE:
|
|
||||||
case Obj::RESOURCE:
|
|
||||||
{
|
|
||||||
auto * res = new CGResource();
|
|
||||||
nobj = res;
|
|
||||||
|
|
||||||
readMessageAndGuards(res->message, res, objPos);
|
CGObjectInstance * CMapLoaderH3M::readResource(const int3 & position, std::shared_ptr<const ObjectTemplate> objTempl)
|
||||||
|
{
|
||||||
|
auto * object = new CGResource();
|
||||||
|
|
||||||
res->amount = reader->readUInt32();
|
readMessageAndGuards(object->message, object, position);
|
||||||
|
|
||||||
|
object->amount = reader->readUInt32();
|
||||||
if(objTempl->subid == GameResID(EGameResID::GOLD))
|
if(objTempl->subid == GameResID(EGameResID::GOLD))
|
||||||
{
|
{
|
||||||
// Gold is multiplied by 100.
|
// Gold is multiplied by 100.
|
||||||
res->amount *= 100;
|
object->amount *= 100;
|
||||||
}
|
}
|
||||||
reader->skipZero(4);
|
reader->skipZero(4);
|
||||||
break;
|
return object;
|
||||||
}
|
}
|
||||||
case Obj::RANDOM_TOWN:
|
|
||||||
case Obj::TOWN:
|
CGObjectInstance * CMapLoaderH3M::readMine(const int3 & position, std::shared_ptr<const ObjectTemplate> objTempl)
|
||||||
{
|
{
|
||||||
nobj = readTown(objTempl->subid, objPos);
|
auto * object = new CGMine();
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Obj::MINE:
|
|
||||||
case Obj::ABANDONED_MINE:
|
|
||||||
{
|
|
||||||
auto * mine = new CGMine();
|
|
||||||
nobj = mine;
|
|
||||||
if (objTempl->subid < 7 )
|
if (objTempl->subid < 7 )
|
||||||
{
|
{
|
||||||
mine->setOwner(reader->readPlayer32());
|
object->setOwner(reader->readPlayer32());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mine->setOwner(PlayerColor::NEUTRAL);
|
object->setOwner(PlayerColor::NEUTRAL);
|
||||||
reader->readBitmask(mine->abandonedMineResources, features.resourcesBytes, features.resourcesCount, false);
|
reader->readBitmask(object->abandonedMineResources, features.resourcesBytes, features.resourcesCount, false);
|
||||||
}
|
}
|
||||||
break;
|
return object;
|
||||||
}
|
}
|
||||||
case Obj::CREATURE_GENERATOR1:
|
|
||||||
case Obj::CREATURE_GENERATOR2:
|
|
||||||
case Obj::CREATURE_GENERATOR3:
|
|
||||||
case Obj::CREATURE_GENERATOR4:
|
|
||||||
{
|
|
||||||
nobj = new CGDwelling();
|
|
||||||
nobj->setOwner(reader->readPlayer32());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Obj::SHRINE_OF_MAGIC_INCANTATION:
|
|
||||||
case Obj::SHRINE_OF_MAGIC_GESTURE:
|
|
||||||
case Obj::SHRINE_OF_MAGIC_THOUGHT:
|
|
||||||
{
|
|
||||||
auto * shr = new CGShrine();
|
|
||||||
nobj = shr;
|
|
||||||
shr->spell = reader->readSpell32();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Obj::PANDORAS_BOX:
|
|
||||||
{
|
|
||||||
auto * box = new CGPandoraBox();
|
|
||||||
nobj = box;
|
|
||||||
readMessageAndGuards(box->message, box, objPos);
|
|
||||||
|
|
||||||
box->gainedExp = reader->readUInt32();
|
CGObjectInstance * CMapLoaderH3M::readDwelling(const int3 & position)
|
||||||
box->manaDiff = reader->readInt32();
|
{
|
||||||
box->moraleDiff = reader->readInt8();
|
auto * object = new CGDwelling();
|
||||||
box->luckDiff = reader->readInt8();
|
object->setOwner(reader->readPlayer32());
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
reader->readResourses(box->resources);
|
CGObjectInstance * CMapLoaderH3M::readDwellingRandom(const int3 & position, std::shared_ptr<const ObjectTemplate> objTempl )
|
||||||
|
{
|
||||||
|
auto * object = new CGDwelling();
|
||||||
|
|
||||||
box->primskills.resize(GameConstants::PRIMARY_SKILLS);
|
|
||||||
for(int x = 0; x < GameConstants::PRIMARY_SKILLS; ++x)
|
|
||||||
{
|
|
||||||
box->primskills[x] = static_cast<PrimarySkill::PrimarySkill>(reader->readUInt8());
|
|
||||||
}
|
|
||||||
|
|
||||||
int gabn = reader->readUInt8();//number of gained abilities
|
|
||||||
for(int oo = 0; oo < gabn; ++oo)
|
|
||||||
{
|
|
||||||
box->abilities.emplace_back(reader->readSkill());
|
|
||||||
box->abilityLevels.push_back(reader->readUInt8());
|
|
||||||
}
|
|
||||||
int gart = reader->readUInt8(); //number of gained artifacts
|
|
||||||
for(int oo = 0; oo < gart; ++oo)
|
|
||||||
box->artifacts.emplace_back(reader->readArtifact());
|
|
||||||
|
|
||||||
int gspel = reader->readUInt8(); //number of gained spells
|
|
||||||
for(int oo = 0; oo < gspel; ++oo)
|
|
||||||
box->spells.emplace_back(reader->readSpell());
|
|
||||||
|
|
||||||
int gcre = reader->readUInt8(); //number of gained creatures
|
|
||||||
readCreatureSet(&box->creatures, gcre);
|
|
||||||
reader->skipZero(8);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Obj::GRAIL:
|
|
||||||
{
|
|
||||||
map->grailPos = objPos;
|
|
||||||
map->grailRadius = reader->readInt32();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
case Obj::RANDOM_DWELLING: //same as castle + level range
|
|
||||||
case Obj::RANDOM_DWELLING_LVL: //same as castle, fixed level
|
|
||||||
case Obj::RANDOM_DWELLING_FACTION: //level range, fixed faction
|
|
||||||
{
|
|
||||||
auto * dwelling = new CGDwelling();
|
|
||||||
nobj = dwelling;
|
|
||||||
CSpecObjInfo * spec = nullptr;
|
CSpecObjInfo * spec = nullptr;
|
||||||
switch(objTempl->id)
|
switch(objTempl->id)
|
||||||
{
|
{
|
||||||
@ -1259,9 +1156,9 @@ void CMapLoaderH3M::readObjects()
|
|||||||
default:
|
default:
|
||||||
throw std::runtime_error("Invalid random dwelling format");
|
throw std::runtime_error("Invalid random dwelling format");
|
||||||
}
|
}
|
||||||
spec->owner = dwelling;
|
spec->owner = object;
|
||||||
|
|
||||||
nobj->setOwner(reader->readPlayer32());
|
object->setOwner(reader->readPlayer32());
|
||||||
|
|
||||||
//216 and 217
|
//216 and 217
|
||||||
if(auto * castleSpec = dynamic_cast<CCreGenAsCastleInfo *>(spec))
|
if(auto * castleSpec = dynamic_cast<CCreGenAsCastleInfo *>(spec))
|
||||||
@ -1297,89 +1194,220 @@ void CMapLoaderH3M::readObjects()
|
|||||||
lvlSpec->minLevel = std::max(reader->readUInt8(), static_cast<ui8>(1));
|
lvlSpec->minLevel = std::max(reader->readUInt8(), static_cast<ui8>(1));
|
||||||
lvlSpec->maxLevel = std::min(reader->readUInt8(), static_cast<ui8>(7));
|
lvlSpec->maxLevel = std::min(reader->readUInt8(), static_cast<ui8>(7));
|
||||||
}
|
}
|
||||||
dwelling->info = spec;
|
object->info = spec;
|
||||||
break;
|
return object;
|
||||||
}
|
}
|
||||||
case Obj::QUEST_GUARD:
|
|
||||||
{
|
|
||||||
auto * guard = new CGQuestGuard();
|
|
||||||
readQuest(guard, objPos);
|
|
||||||
nobj = guard;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Obj::SHIPYARD:
|
|
||||||
{
|
|
||||||
nobj = new CGShipyard();
|
|
||||||
nobj->setOwner(reader->readPlayer32());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Obj::HERO_PLACEHOLDER: //hero placeholder
|
|
||||||
{
|
|
||||||
auto * hp = new CGHeroPlaceholder();
|
|
||||||
nobj = hp;
|
|
||||||
|
|
||||||
hp->setOwner(reader->readPlayer());
|
CGObjectInstance * CMapLoaderH3M::readShrine(const int3 & position)
|
||||||
|
{
|
||||||
|
auto * object = new CGShrine();
|
||||||
|
object->spell = reader->readSpell32();
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
CGObjectInstance * CMapLoaderH3M::readHeroPlaceholder(const int3 & position)
|
||||||
|
{
|
||||||
|
auto * object = new CGHeroPlaceholder();
|
||||||
|
|
||||||
|
object->setOwner(reader->readPlayer());
|
||||||
|
|
||||||
HeroTypeID htid = reader->readHero(); //hero type id
|
HeroTypeID htid = reader->readHero(); //hero type id
|
||||||
nobj->subID = htid.getNum();
|
object->subID = htid.getNum();
|
||||||
|
|
||||||
if(htid.getNum() == -1)
|
if(htid.getNum() == -1)
|
||||||
{
|
{
|
||||||
hp->power = reader->readUInt8();
|
object->power = reader->readUInt8();
|
||||||
logGlobal->debug("Hero placeholder: by power at %s", objPos.toString());
|
logGlobal->debug("Hero placeholder: by power at %s", position.toString());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
logGlobal->debug("Hero placeholder: %s at %s", VLC->heroh->getById(htid)->getNameTranslated(), objPos.toString());
|
object->power = 0;
|
||||||
hp->power = 0;
|
logGlobal->debug("Hero placeholder: %s at %s", VLC->heroh->getById(htid)->getNameTranslated(), position.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
return object;
|
||||||
}
|
}
|
||||||
case Obj::BORDERGUARD:
|
|
||||||
{
|
CGObjectInstance * CMapLoaderH3M::readGrail(const int3 & position)
|
||||||
nobj = new CGBorderGuard();
|
{
|
||||||
break;
|
map->grailPos = position;
|
||||||
}
|
map->grailRadius = reader->readInt32();
|
||||||
case Obj::BORDER_GATE:
|
return nullptr;
|
||||||
{
|
}
|
||||||
nobj = new CGBorderGate();
|
|
||||||
break;
|
CGObjectInstance * CMapLoaderH3M::readBlank(const int3 & position, std::shared_ptr<const ObjectTemplate> objTempl)
|
||||||
}
|
{
|
||||||
case Obj::PYRAMID: //Pyramid of WoG object
|
|
||||||
{
|
|
||||||
if(objTempl->subid == 0)
|
|
||||||
{
|
|
||||||
nobj = new CBank();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//WoG object
|
|
||||||
//TODO: possible special handling
|
|
||||||
nobj = new CGObjectInstance();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Obj::LIGHTHOUSE: //Lighthouse
|
|
||||||
{
|
|
||||||
nobj = new CGLighthouse();
|
|
||||||
nobj->tempOwner = reader->readPlayer32();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: //any other object
|
|
||||||
{
|
|
||||||
if (VLC->objtypeh->knownSubObjects(objTempl->id).count(objTempl->subid))
|
if (VLC->objtypeh->knownSubObjects(objTempl->id).count(objTempl->subid))
|
||||||
|
return VLC->objtypeh->getHandlerFor(objTempl->id, objTempl->subid)->create(objTempl);
|
||||||
|
|
||||||
|
logGlobal->warn("Unrecognized object: %d:%d ('%s') at %s on map '%s'", objTempl->id.toEnum(), objTempl->subid, objTempl->animationFile, position.toString(), map->name);
|
||||||
|
return new CGObjectInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
CGObjectInstance * CMapLoaderH3M::readPyramid(const int3 & position, std::shared_ptr<const ObjectTemplate> objTempl)
|
||||||
|
{
|
||||||
|
if(objTempl->subid == 0)
|
||||||
|
return new CBank();
|
||||||
|
|
||||||
|
return new CGObjectInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
CGObjectInstance * CMapLoaderH3M::readQuestGuard(const int3 & position)
|
||||||
|
{
|
||||||
|
auto * guard = new CGQuestGuard();
|
||||||
|
readQuest(guard, position);
|
||||||
|
return guard;
|
||||||
|
}
|
||||||
|
|
||||||
|
CGObjectInstance * CMapLoaderH3M::readShipyard(const int3 & position)
|
||||||
|
{
|
||||||
|
auto * object = new CGShipyard();
|
||||||
|
object->setOwner(reader->readPlayer32());
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
CGObjectInstance * CMapLoaderH3M::readBorderGuard(const int3 & position)
|
||||||
|
{
|
||||||
|
return new CGBorderGuard();
|
||||||
|
}
|
||||||
|
|
||||||
|
CGObjectInstance * CMapLoaderH3M::readBorderGate(const int3 & position)
|
||||||
|
{
|
||||||
|
return new CGBorderGate();
|
||||||
|
}
|
||||||
|
|
||||||
|
CGObjectInstance * CMapLoaderH3M::readLighthouse(const int3 & position)
|
||||||
|
{
|
||||||
|
auto * object = new CGLighthouse();
|
||||||
|
object->tempOwner = reader->readPlayer32();
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
CGObjectInstance * CMapLoaderH3M::readObject(std::shared_ptr<const ObjectTemplate> objectTemplate, const int3 & objectPosition, const ObjectInstanceID & idToBeGiven)
|
||||||
|
{
|
||||||
|
switch(objectTemplate->id)
|
||||||
{
|
{
|
||||||
nobj = VLC->objtypeh->getHandlerFor(objTempl->id, objTempl->subid)->create(objTempl);
|
case Obj::EVENT:
|
||||||
|
return readEvent(objectPosition);
|
||||||
|
|
||||||
|
case Obj::HERO:
|
||||||
|
case Obj::RANDOM_HERO:
|
||||||
|
case Obj::PRISON:
|
||||||
|
return readHero(objectPosition, idToBeGiven);
|
||||||
|
|
||||||
|
case Obj::MONSTER:
|
||||||
|
case Obj::RANDOM_MONSTER:
|
||||||
|
case Obj::RANDOM_MONSTER_L1:
|
||||||
|
case Obj::RANDOM_MONSTER_L2:
|
||||||
|
case Obj::RANDOM_MONSTER_L3:
|
||||||
|
case Obj::RANDOM_MONSTER_L4:
|
||||||
|
case Obj::RANDOM_MONSTER_L5:
|
||||||
|
case Obj::RANDOM_MONSTER_L6:
|
||||||
|
case Obj::RANDOM_MONSTER_L7:
|
||||||
|
return readMonster(objectPosition, idToBeGiven);
|
||||||
|
|
||||||
|
case Obj::OCEAN_BOTTLE:
|
||||||
|
case Obj::SIGN:
|
||||||
|
return readSign(objectPosition);
|
||||||
|
|
||||||
|
case Obj::SEER_HUT:
|
||||||
|
return readSeerHut(objectPosition);
|
||||||
|
|
||||||
|
case Obj::WITCH_HUT:
|
||||||
|
return readWitchHut(objectPosition);
|
||||||
|
case Obj::SCHOLAR:
|
||||||
|
return readScholar(objectPosition);
|
||||||
|
|
||||||
|
case Obj::GARRISON:
|
||||||
|
case Obj::GARRISON2:
|
||||||
|
return readGarrison(objectPosition);
|
||||||
|
|
||||||
|
case Obj::ARTIFACT:
|
||||||
|
case Obj::RANDOM_ART:
|
||||||
|
case Obj::RANDOM_TREASURE_ART:
|
||||||
|
case Obj::RANDOM_MINOR_ART:
|
||||||
|
case Obj::RANDOM_MAJOR_ART:
|
||||||
|
case Obj::RANDOM_RELIC_ART:
|
||||||
|
case Obj::SPELL_SCROLL:
|
||||||
|
return readArtifact(objectPosition, objectTemplate);
|
||||||
|
|
||||||
|
case Obj::RANDOM_RESOURCE:
|
||||||
|
case Obj::RESOURCE:
|
||||||
|
return readResource(objectPosition, objectTemplate);
|
||||||
|
case Obj::RANDOM_TOWN:
|
||||||
|
case Obj::TOWN:
|
||||||
|
return readTown(objectPosition, objectTemplate);
|
||||||
|
|
||||||
|
case Obj::MINE:
|
||||||
|
case Obj::ABANDONED_MINE:
|
||||||
|
return readMine(objectPosition, objectTemplate);
|
||||||
|
|
||||||
|
case Obj::CREATURE_GENERATOR1:
|
||||||
|
case Obj::CREATURE_GENERATOR2:
|
||||||
|
case Obj::CREATURE_GENERATOR3:
|
||||||
|
case Obj::CREATURE_GENERATOR4:
|
||||||
|
return readDwelling(objectPosition);
|
||||||
|
|
||||||
|
case Obj::SHRINE_OF_MAGIC_INCANTATION:
|
||||||
|
case Obj::SHRINE_OF_MAGIC_GESTURE:
|
||||||
|
case Obj::SHRINE_OF_MAGIC_THOUGHT:
|
||||||
|
return readShrine(objectPosition);
|
||||||
|
|
||||||
|
case Obj::PANDORAS_BOX:
|
||||||
|
return readPandora(objectPosition);
|
||||||
|
|
||||||
|
case Obj::GRAIL:
|
||||||
|
return readGrail(objectPosition);
|
||||||
|
|
||||||
|
case Obj::RANDOM_DWELLING:
|
||||||
|
case Obj::RANDOM_DWELLING_LVL:
|
||||||
|
case Obj::RANDOM_DWELLING_FACTION:
|
||||||
|
return readDwellingRandom(objectPosition, objectTemplate);
|
||||||
|
|
||||||
|
case Obj::QUEST_GUARD:
|
||||||
|
return readQuestGuard(objectPosition);
|
||||||
|
|
||||||
|
case Obj::SHIPYARD:
|
||||||
|
return readShipyard(objectPosition);
|
||||||
|
|
||||||
|
case Obj::HERO_PLACEHOLDER:
|
||||||
|
return readHeroPlaceholder(objectPosition);
|
||||||
|
|
||||||
|
case Obj::BORDERGUARD:
|
||||||
|
return readBorderGuard(objectPosition);
|
||||||
|
|
||||||
|
case Obj::BORDER_GATE:
|
||||||
|
return readBorderGate(objectPosition);
|
||||||
|
|
||||||
|
case Obj::PYRAMID:
|
||||||
|
return readPyramid(objectPosition, objectTemplate);
|
||||||
|
|
||||||
|
case Obj::LIGHTHOUSE:
|
||||||
|
return readLighthouse(objectPosition);
|
||||||
|
|
||||||
|
default: //any other object
|
||||||
|
return readBlank(objectPosition, objectTemplate);
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
|
||||||
|
void CMapLoaderH3M::readObjects()
|
||||||
|
{
|
||||||
|
uint32_t howManyObjs = reader->readUInt32();
|
||||||
|
|
||||||
|
for(uint32_t ww = 0; ww < howManyObjs; ++ww)
|
||||||
{
|
{
|
||||||
logGlobal->warn("Unrecognized object: %d:%d ('%s') at %s on map '%s'", objTempl->id.toEnum(), objTempl->subid, objTempl->animationFile, objPos.toString(), map->name);
|
int3 objPos = reader->readInt3();
|
||||||
nobj = new CGObjectInstance();
|
|
||||||
}
|
uint32_t defnum = reader->readUInt32();
|
||||||
break;
|
ObjectInstanceID idToBeGiven = ObjectInstanceID(static_cast<si32>(map->objects.size()));
|
||||||
}
|
|
||||||
}
|
std::shared_ptr<const ObjectTemplate> objTempl = templates.at(defnum);
|
||||||
|
reader->skipZero(5);
|
||||||
|
|
||||||
|
CGObjectInstance * nobj = readObject(objTempl, objPos, idToBeGiven);
|
||||||
|
|
||||||
|
if (!nobj)
|
||||||
|
continue;
|
||||||
|
|
||||||
nobj->pos = objPos;
|
nobj->pos = objPos;
|
||||||
nobj->ID = objTempl->id;
|
nobj->ID = objTempl->id;
|
||||||
@ -1443,7 +1471,7 @@ void CMapLoaderH3M::readCreatureSet(CCreatureSet * out, int number)
|
|||||||
out->validTypes(true);
|
out->validTypes(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
CGObjectInstance * CMapLoaderH3M::readHero(const ObjectInstanceID & idToBeGiven, const int3 & initialPos)
|
CGObjectInstance * CMapLoaderH3M::readHero(const int3 & initialPos, const ObjectInstanceID & idToBeGiven)
|
||||||
{
|
{
|
||||||
auto * nhi = new CGHeroInstance();
|
auto * nhi = new CGHeroInstance();
|
||||||
|
|
||||||
@ -1601,7 +1629,7 @@ CGObjectInstance * CMapLoaderH3M::readHero(const ObjectInstanceID & idToBeGiven,
|
|||||||
return nhi;
|
return nhi;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGSeerHut * CMapLoaderH3M::readSeerHut(const int3 & position)
|
CGObjectInstance * CMapLoaderH3M::readSeerHut(const int3 & position)
|
||||||
{
|
{
|
||||||
auto * hut = new CGSeerHut();
|
auto * hut = new CGSeerHut();
|
||||||
|
|
||||||
@ -1791,7 +1819,7 @@ void CMapLoaderH3M::readQuest(IQuestObject * guard, const int3 & position)
|
|||||||
guard->quest->isCustomComplete = !guard->quest->completedText.empty();
|
guard->quest->isCustomComplete = !guard->quest->completedText.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
CGTownInstance * CMapLoaderH3M::readTown(int castleID, const int3 & position)
|
CGObjectInstance * CMapLoaderH3M::readTown(const int3 & position, std::shared_ptr<const ObjectTemplate> objTempl)
|
||||||
{
|
{
|
||||||
auto * nt = new CGTownInstance();
|
auto * nt = new CGTownInstance();
|
||||||
if(features.levelAB)
|
if(features.levelAB)
|
||||||
@ -1815,8 +1843,8 @@ CGTownInstance * CMapLoaderH3M::readTown(int castleID, const int3 & position)
|
|||||||
reader->readBitmask(nt->builtBuildings, features.buildingsBytes,features.buildingsCount,false);
|
reader->readBitmask(nt->builtBuildings, features.buildingsBytes,features.buildingsCount,false);
|
||||||
reader->readBitmask(nt->forbiddenBuildings,features.buildingsBytes,features.buildingsCount,false);
|
reader->readBitmask(nt->forbiddenBuildings,features.buildingsBytes,features.buildingsCount,false);
|
||||||
|
|
||||||
nt->builtBuildings = convertBuildings(nt->builtBuildings, castleID);
|
nt->builtBuildings = convertBuildings(nt->builtBuildings, objTempl->subid);
|
||||||
nt->forbiddenBuildings = convertBuildings(nt->forbiddenBuildings, castleID);
|
nt->forbiddenBuildings = convertBuildings(nt->forbiddenBuildings, objTempl->subid);
|
||||||
}
|
}
|
||||||
// Standard buildings
|
// Standard buildings
|
||||||
else
|
else
|
||||||
@ -1879,7 +1907,7 @@ CGTownInstance * CMapLoaderH3M::readTown(int castleID, const int3 & position)
|
|||||||
|
|
||||||
reader->readBitmask(nce.buildings, features.buildingsBytes, features.buildingsCount, false);
|
reader->readBitmask(nce.buildings, features.buildingsBytes, features.buildingsCount, false);
|
||||||
|
|
||||||
nce.buildings = convertBuildings(nce.buildings, castleID, false);
|
nce.buildings = convertBuildings(nce.buildings, objTempl->subid, false);
|
||||||
|
|
||||||
nce.creatures.resize(7);
|
nce.creatures.resize(7);
|
||||||
for(int vv = 0; vv < 7; ++vv)
|
for(int vv = 0; vv < 7; ++vv)
|
||||||
|
@ -25,6 +25,7 @@ class CGTownInstance;
|
|||||||
class CCreatureSet;
|
class CCreatureSet;
|
||||||
class CInputStream;
|
class CInputStream;
|
||||||
class TextIdentifier;
|
class TextIdentifier;
|
||||||
|
class CGPandoraBox;
|
||||||
|
|
||||||
class ObjectInstanceID;
|
class ObjectInstanceID;
|
||||||
class BuildingID;
|
class BuildingID;
|
||||||
@ -153,6 +154,35 @@ private:
|
|||||||
*/
|
*/
|
||||||
void readObjects();
|
void readObjects();
|
||||||
|
|
||||||
|
/// Reads single object from input stream based on template
|
||||||
|
CGObjectInstance * readObject(std::shared_ptr<const ObjectTemplate> objectTemplate, const int3 & objectPosition, const ObjectInstanceID & idToBeGiven);
|
||||||
|
|
||||||
|
CGObjectInstance * readEvent(const int3 & objectPosition);
|
||||||
|
CGObjectInstance * readMonster(const int3 & objectPosition, const ObjectInstanceID & idToBeGiven);
|
||||||
|
CGObjectInstance * readHero(const int3 & initialPos, const ObjectInstanceID & idToBeGiven);
|
||||||
|
CGObjectInstance * readSeerHut(const int3 & initialPos);
|
||||||
|
CGObjectInstance * readTown(const int3 & position, std::shared_ptr<const ObjectTemplate> objTempl);
|
||||||
|
CGObjectInstance * readSign(const int3 & position);
|
||||||
|
CGObjectInstance * readWitchHut(const int3 & position);
|
||||||
|
CGObjectInstance * readScholar(const int3 & position);
|
||||||
|
CGObjectInstance * readGarrison(const int3 & position);
|
||||||
|
CGObjectInstance * readArtifact(const int3 & position, std::shared_ptr<const ObjectTemplate> objTempl);
|
||||||
|
CGObjectInstance * readResource(const int3 & position, std::shared_ptr<const ObjectTemplate> objTempl);
|
||||||
|
CGObjectInstance * readMine(const int3 & position, std::shared_ptr<const ObjectTemplate> objTempl);
|
||||||
|
CGObjectInstance * readPandora(const int3 & position);
|
||||||
|
CGObjectInstance * readDwelling(const int3 & position);
|
||||||
|
CGObjectInstance * readDwellingRandom(const int3 & position, std::shared_ptr<const ObjectTemplate> objTempl);
|
||||||
|
CGObjectInstance * readShrine(const int3 & position);
|
||||||
|
CGObjectInstance * readHeroPlaceholder(const int3 & position);
|
||||||
|
CGObjectInstance * readGrail(const int3 & position);
|
||||||
|
CGObjectInstance * readPyramid(const int3 & position, std::shared_ptr<const ObjectTemplate> objTempl);
|
||||||
|
CGObjectInstance * readBorderGuard(const int3 & position);
|
||||||
|
CGObjectInstance * readBorderGate(const int3 & position);
|
||||||
|
CGObjectInstance * readQuestGuard(const int3 & position);
|
||||||
|
CGObjectInstance * readShipyard(const int3 & position);
|
||||||
|
CGObjectInstance * readLighthouse(const int3 & position);
|
||||||
|
CGObjectInstance * readBlank(const int3 & position, std::shared_ptr<const ObjectTemplate> objectTemplate);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads a creature set.
|
* Reads a creature set.
|
||||||
*
|
*
|
||||||
@ -162,19 +192,11 @@ private:
|
|||||||
void readCreatureSet(CCreatureSet * out, int number);
|
void readCreatureSet(CCreatureSet * out, int number);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads a hero.
|
* Reads a quest for the given quest guard.
|
||||||
*
|
*
|
||||||
* @param idToBeGiven the object id which should be set for the hero
|
* @param guard the quest guard where that quest should be applied to
|
||||||
* @return a object instance
|
|
||||||
*/
|
*/
|
||||||
CGObjectInstance * readHero(const ObjectInstanceID & idToBeGiven, const int3 & initialPos);
|
void readBoxContent(CGPandoraBox * object, const int3 & position);
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads a seer hut.
|
|
||||||
*
|
|
||||||
* @return the initialized seer hut object
|
|
||||||
*/
|
|
||||||
CGSeerHut * readSeerHut(const int3 & position);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads a quest for the given quest guard.
|
* Reads a quest for the given quest guard.
|
||||||
@ -183,14 +205,6 @@ private:
|
|||||||
*/
|
*/
|
||||||
void readQuest(IQuestObject * guard, const int3 & position);
|
void readQuest(IQuestObject * guard, const int3 & position);
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads a town.
|
|
||||||
*
|
|
||||||
* @param castleID the id of the castle type
|
|
||||||
* @return the loaded town object
|
|
||||||
*/
|
|
||||||
CGTownInstance * readTown(int castleID, const int3 & position);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts buildings to the specified castle id.
|
* Converts buildings to the specified castle id.
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user