mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-21 17:17:06 +02:00
Merge pull request #4852 from IvanSavenko/remove_vlc_entities_serialization
Remove remaining pointers to VLC entities from serializer
This commit is contained in:
commit
e7bea6c3b8
@ -1055,7 +1055,7 @@ void AIGateway::pickBestArtifacts(const CGHeroInstance * h, const CGHeroInstance
|
||||
//FIXME: why are the above possible to be null?
|
||||
|
||||
bool emptySlotFound = false;
|
||||
for(auto slot : artifact->artType->getPossibleSlots().at(target->bearerType()))
|
||||
for(auto slot : artifact->getType()->getPossibleSlots().at(target->bearerType()))
|
||||
{
|
||||
if(target->isPositionFree(slot) && artifact->canBePutAt(target, slot, true)) //combined artifacts are not always allowed to move
|
||||
{
|
||||
@ -1068,7 +1068,7 @@ void AIGateway::pickBestArtifacts(const CGHeroInstance * h, const CGHeroInstance
|
||||
}
|
||||
if(!emptySlotFound) //try to put that atifact in already occupied slot
|
||||
{
|
||||
for(auto slot : artifact->artType->getPossibleSlots().at(target->bearerType()))
|
||||
for(auto slot : artifact->getType()->getPossibleSlots().at(target->bearerType()))
|
||||
{
|
||||
auto otherSlot = target->getSlot(slot);
|
||||
if(otherSlot && otherSlot->artifact) //we need to exchange artifact for better one
|
||||
@ -1079,8 +1079,8 @@ void AIGateway::pickBestArtifacts(const CGHeroInstance * h, const CGHeroInstance
|
||||
{
|
||||
logAi->trace(
|
||||
"Exchange artifacts %s <-> %s",
|
||||
artifact->artType->getNameTranslated(),
|
||||
otherSlot->artifact->artType->getNameTranslated());
|
||||
artifact->getType()->getNameTranslated(),
|
||||
otherSlot->artifact->getType()->getNameTranslated());
|
||||
|
||||
if(!otherSlot->artifact->canBePutAt(artHolder, location.slot, true))
|
||||
{
|
||||
@ -1129,10 +1129,10 @@ void AIGateway::recruitCreatures(const CGDwelling * d, const CArmedInstance * re
|
||||
{
|
||||
for(auto stack : recruiter->Slots())
|
||||
{
|
||||
if(!stack.second->type)
|
||||
if(!stack.second->getType())
|
||||
continue;
|
||||
|
||||
auto duplicatingSlot = recruiter->getSlotFor(stack.second->type);
|
||||
auto duplicatingSlot = recruiter->getSlotFor(stack.second->getCreature());
|
||||
|
||||
if(duplicatingSlot != stack.first)
|
||||
{
|
||||
|
@ -193,7 +193,7 @@ bool canBeEmbarkmentPoint(const TerrainTile * t, bool fromWater)
|
||||
{
|
||||
// TODO: Such information should be provided by pathfinder
|
||||
// Tile must be free or with unoccupied boat
|
||||
if(!t->blocked)
|
||||
if(!t->blocked())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -267,8 +267,8 @@ bool compareArmyStrength(const CArmedInstance * a1, const CArmedInstance * a2)
|
||||
|
||||
bool compareArtifacts(const CArtifactInstance * a1, const CArtifactInstance * a2)
|
||||
{
|
||||
auto art1 = a1->artType;
|
||||
auto art2 = a2->artType;
|
||||
auto art1 = a1->getType();
|
||||
auto art2 = a2->getType();
|
||||
|
||||
if(art1->getPrice() == art2->getPrice())
|
||||
return art1->valOfBonuses(BonusType::PRIMARY_SKILL) > art2->valOfBonuses(BonusType::PRIMARY_SKILL);
|
||||
@ -312,7 +312,7 @@ int getDuplicatingSlots(const CArmedInstance * army)
|
||||
|
||||
for(auto stack : army->Slots())
|
||||
{
|
||||
if(stack.second->type && army->getSlotFor(stack.second->type) != stack.first)
|
||||
if(stack.second->getCreature() && army->getSlotFor(stack.second->getCreature()) != stack.first)
|
||||
duplicatingSlots++;
|
||||
}
|
||||
|
||||
@ -387,7 +387,7 @@ bool shouldVisit(const Nullkiller * ai, const CGHeroInstance * h, const CGObject
|
||||
{
|
||||
for(auto slot : h->Slots())
|
||||
{
|
||||
if(slot.second->type->hasUpgrades())
|
||||
if(slot.second->getType()->hasUpgrades())
|
||||
return true; //TODO: check price?
|
||||
}
|
||||
return false;
|
||||
|
@ -90,7 +90,7 @@ std::vector<SlotInfo> ArmyManager::getSortedSlots(const CCreatureSet * target, c
|
||||
{
|
||||
for(auto & i : armyPtr->Slots())
|
||||
{
|
||||
auto cre = dynamic_cast<const CCreature*>(i.second->type);
|
||||
auto cre = dynamic_cast<const CCreature*>(i.second->getType());
|
||||
auto & slotInfp = creToPower[cre];
|
||||
|
||||
slotInfp.creature = cre;
|
||||
|
@ -155,10 +155,10 @@ uint64_t getCreatureBankArmyReward(const CGObjectInstance * target, const CGHero
|
||||
for (auto c : creatures)
|
||||
{
|
||||
//Only if hero has slot for this creature in the army
|
||||
auto ccre = dynamic_cast<const CCreature*>(c.data.type);
|
||||
auto ccre = dynamic_cast<const CCreature*>(c.data.getType());
|
||||
if (hero->getSlotFor(ccre).validSlot() || duplicatingSlots > 0)
|
||||
{
|
||||
result += (c.data.type->getAIValue() * c.data.count) * c.chance;
|
||||
result += (c.data.getType()->getAIValue() * c.data.count) * c.chance;
|
||||
}
|
||||
/*else
|
||||
{
|
||||
@ -290,7 +290,7 @@ uint64_t RewardEvaluator::getArmyReward(
|
||||
case Obj::CREATURE_GENERATOR4:
|
||||
return getDwellingArmyValue(ai->cb.get(), target, checkGold);
|
||||
case Obj::ARTIFACT:
|
||||
return evaluateArtifactArmyValue(dynamic_cast<const CGArtifact *>(target)->storedArtifact->artType);
|
||||
return evaluateArtifactArmyValue(dynamic_cast<const CGArtifact *>(target)->storedArtifact->getType());
|
||||
case Obj::HERO:
|
||||
return relations == PlayerRelations::ENEMIES
|
||||
? enemyArmyEliminationRewardRatio * dynamic_cast<const CGHeroInstance *>(target)->getArmyStrength()
|
||||
|
@ -130,10 +130,10 @@ void AINodeStorage::initialize(const PathfinderOptions & options, const CGameSta
|
||||
for(pos.y = 0; pos.y < sizes.y; ++pos.y)
|
||||
{
|
||||
const TerrainTile & tile = gs->map->getTile(pos);
|
||||
if (!tile.terType->isPassable())
|
||||
if (!tile.getTerrain()->isPassable())
|
||||
continue;
|
||||
|
||||
if (tile.terType->isWater())
|
||||
if (tile.isWater())
|
||||
{
|
||||
resetTile(pos, ELayer::SAIL, PathfinderUtil::evaluateAccessibility<ELayer::SAIL>(pos, tile, fow, player, gs));
|
||||
if (useFlying)
|
||||
|
@ -186,7 +186,7 @@ bool canBeEmbarkmentPoint(const TerrainTile * t, bool fromWater)
|
||||
{
|
||||
// TODO: Such information should be provided by pathfinder
|
||||
// Tile must be free or with unoccupied boat
|
||||
if(!t->blocked)
|
||||
if(!t->blocked())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -247,8 +247,8 @@ bool compareArmyStrength(const CArmedInstance * a1, const CArmedInstance * a2)
|
||||
|
||||
bool compareArtifacts(const CArtifactInstance * a1, const CArtifactInstance * a2)
|
||||
{
|
||||
auto art1 = a1->artType;
|
||||
auto art2 = a2->artType;
|
||||
auto art1 = a1->getType();
|
||||
auto art2 = a2->getType();
|
||||
|
||||
if(art1->getPrice() == art2->getPrice())
|
||||
return art1->valOfBonuses(BonusType::PRIMARY_SKILL) > art2->valOfBonuses(BonusType::PRIMARY_SKILL);
|
||||
|
@ -36,7 +36,7 @@ std::vector<SlotInfo> ArmyManager::getSortedSlots(const CCreatureSet * target, c
|
||||
{
|
||||
for(auto & i : armyPtr->Slots())
|
||||
{
|
||||
auto cre = dynamic_cast<const CCreature*>(i.second->type);
|
||||
auto cre = dynamic_cast<const CCreature*>(i.second->getType());
|
||||
auto & slotInfp = creToPower[cre];
|
||||
|
||||
slotInfp.creature = cre;
|
||||
|
@ -162,7 +162,7 @@ TGoalVec CompleteQuest::missionArmy() const
|
||||
|
||||
for(auto creature : q.quest->mission.creatures)
|
||||
{
|
||||
solutions.push_back(sptr(GatherTroops(creature.type->getId(), creature.count)));
|
||||
solutions.push_back(sptr(GatherTroops(creature.getId(), creature.count)));
|
||||
}
|
||||
|
||||
return solutions;
|
||||
|
@ -92,7 +92,7 @@ std::optional<int> MapObjectsEvaluator::getObjectValue(const CGObjectInstance *
|
||||
else if(obj->ID == Obj::ARTIFACT)
|
||||
{
|
||||
auto artifactObject = dynamic_cast<const CGArtifact *>(obj);
|
||||
switch(artifactObject->storedArtifact->artType->aClass)
|
||||
switch(artifactObject->storedArtifact->getType()->aClass)
|
||||
{
|
||||
case CArtifact::EartClass::ART_TREASURE:
|
||||
return 2000;
|
||||
|
@ -46,10 +46,10 @@ void AINodeStorage::initialize(const PathfinderOptions & options, const CGameSta
|
||||
for(pos.y=0; pos.y < sizes.y; ++pos.y)
|
||||
{
|
||||
const TerrainTile & tile = gs->map->getTile(pos);
|
||||
if(!tile.terType->isPassable())
|
||||
if(!tile.getTerrain()->isPassable())
|
||||
continue;
|
||||
|
||||
if(tile.terType->isWater())
|
||||
if(tile.getTerrain()->isWater())
|
||||
{
|
||||
resetTile(pos, ELayer::SAIL, PathfinderUtil::evaluateAccessibility<ELayer::SAIL>(pos, tile, fow, player, gs));
|
||||
if(useFlying)
|
||||
|
@ -1180,7 +1180,7 @@ void VCAI::pickBestArtifacts(const CGHeroInstance * h, const CGHeroInstance * ot
|
||||
//FIXME: why are the above possible to be null?
|
||||
|
||||
bool emptySlotFound = false;
|
||||
for(auto slot : artifact->artType->getPossibleSlots().at(target->bearerType()))
|
||||
for(auto slot : artifact->getType()->getPossibleSlots().at(target->bearerType()))
|
||||
{
|
||||
if(target->isPositionFree(slot) && artifact->canBePutAt(target, slot, true)) //combined artifacts are not always allowed to move
|
||||
{
|
||||
@ -1193,7 +1193,7 @@ void VCAI::pickBestArtifacts(const CGHeroInstance * h, const CGHeroInstance * ot
|
||||
}
|
||||
if(!emptySlotFound) //try to put that atifact in already occupied slot
|
||||
{
|
||||
for(auto slot : artifact->artType->getPossibleSlots().at(target->bearerType()))
|
||||
for(auto slot : artifact->getType()->getPossibleSlots().at(target->bearerType()))
|
||||
{
|
||||
auto otherSlot = target->getSlot(slot);
|
||||
if(otherSlot && otherSlot->artifact) //we need to exchange artifact for better one
|
||||
@ -2818,7 +2818,7 @@ bool shouldVisit(HeroPtr h, const CGObjectInstance * obj)
|
||||
{
|
||||
for(auto slot : h->Slots())
|
||||
{
|
||||
if(slot.second->type->hasUpgrades())
|
||||
if(slot.second->getType()->hasUpgrades())
|
||||
return true; //TODO: check price?
|
||||
}
|
||||
return false;
|
||||
|
@ -71,7 +71,7 @@ bool ArtifactsUIController::askToAssemble(const CGHeroInstance * hero, const Art
|
||||
}
|
||||
|
||||
bool assembleConfirmed = false;
|
||||
MetaString message = MetaString::createFromTextID(art->artType->getDescriptionTextID());
|
||||
MetaString message = MetaString::createFromTextID(art->getType()->getDescriptionTextID());
|
||||
message.appendEOL();
|
||||
message.appendEOL();
|
||||
if(combinedArt->isFused())
|
||||
@ -107,10 +107,10 @@ bool ArtifactsUIController::askToDisassemble(const CGHeroInstance * hero, const
|
||||
|
||||
if(art->hasParts())
|
||||
{
|
||||
if(ArtifactUtils::isSlotBackpack(slot) && !ArtifactUtils::isBackpackFreeSlots(hero, art->artType->getConstituents().size() - 1))
|
||||
if(ArtifactUtils::isSlotBackpack(slot) && !ArtifactUtils::isBackpackFreeSlots(hero, art->getType()->getConstituents().size() - 1))
|
||||
return false;
|
||||
|
||||
MetaString message = MetaString::createFromTextID(art->artType->getDescriptionTextID());
|
||||
MetaString message = MetaString::createFromTextID(art->getType()->getDescriptionTextID());
|
||||
message.appendEOL();
|
||||
message.appendEOL();
|
||||
message.appendRawString(CGI->generaltexth->allTexts[733]); // Do you wish to disassemble this artifact?
|
||||
|
@ -291,14 +291,12 @@ AudioPath HeroMovementController::getMovementSoundFor(const CGHeroInstance * her
|
||||
auto prevTile = LOCPLINT->cb->getTile(posPrev);
|
||||
auto nextTile = LOCPLINT->cb->getTile(posNext);
|
||||
|
||||
auto prevRoad = prevTile->roadType;
|
||||
auto nextRoad = nextTile->roadType;
|
||||
bool movingOnRoad = prevRoad->getId() != Road::NO_ROAD && nextRoad->getId() != Road::NO_ROAD;
|
||||
bool movingOnRoad = prevTile->hasRoad() && nextTile->hasRoad();
|
||||
|
||||
if(movingOnRoad)
|
||||
return nextTile->terType->horseSound;
|
||||
return nextTile->getTerrain()->horseSound;
|
||||
else
|
||||
return nextTile->terType->horseSoundPenalty;
|
||||
return nextTile->getTerrain()->horseSoundPenalty;
|
||||
};
|
||||
|
||||
void HeroMovementController::updateMovementSound(const CGHeroInstance * h, int3 posPrev, int3 nextCoord, EPathNodeAction moveType)
|
||||
|
@ -50,10 +50,10 @@ ColorRGBA CMinimapInstance::getTileColor(const int3 & pos) const
|
||||
return graphics->playerColors[player.getNum()];
|
||||
}
|
||||
|
||||
if (tile->blocked && (!tile->visitable))
|
||||
return tile->terType->minimapBlocked;
|
||||
if (tile->blocked() && !tile->visitable())
|
||||
return tile->getTerrain()->minimapBlocked;
|
||||
else
|
||||
return tile->terType->minimapUnblocked;
|
||||
return tile->getTerrain()->minimapUnblocked;
|
||||
}
|
||||
|
||||
void CMinimapInstance::refreshTile(const int3 &tile)
|
||||
|
@ -182,7 +182,7 @@ void MapAudioPlayer::updateMusic()
|
||||
const auto * tile = LOCPLINT->cb->getTile(currentSelection->visitablePos());
|
||||
|
||||
if (tile)
|
||||
CCS->musich->playMusicFromSet("terrain", tile->terType->getJsonKey(), true, false);
|
||||
CCS->musich->playMusicFromSet("terrain", tile->getTerrain()->getJsonKey(), true, false);
|
||||
}
|
||||
|
||||
if(audioPlaying && enemyMakingTurn)
|
||||
|
@ -143,7 +143,7 @@ void MapRendererTerrain::renderTile(IMapRendererContext & context, Canvas & targ
|
||||
{
|
||||
const TerrainTile & mapTile = context.getMapTile(coordinates);
|
||||
|
||||
int32_t terrainIndex = mapTile.terType->getIndex();
|
||||
int32_t terrainIndex = mapTile.getTerrainID();
|
||||
int32_t imageIndex = mapTile.terView;
|
||||
int32_t rotationIndex = mapTile.extTileFlags % 4;
|
||||
|
||||
@ -152,11 +152,11 @@ void MapRendererTerrain::renderTile(IMapRendererContext & context, Canvas & targ
|
||||
assert(image);
|
||||
if (!image)
|
||||
{
|
||||
logGlobal->error("Failed to find image %d for terrain %s on tile %s", imageIndex, mapTile.terType->getNameTranslated(), coordinates.toString());
|
||||
logGlobal->error("Failed to find image %d for terrain %s on tile %s", imageIndex, mapTile.getTerrain()->getNameTranslated(), coordinates.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
for( auto const & element : mapTile.terType->paletteAnimation)
|
||||
for( auto const & element : mapTile.getTerrain()->paletteAnimation)
|
||||
image->shiftPalette(element.start, element.length, context.terrainImageIndex(element.length));
|
||||
|
||||
target.draw(image, Point(0, 0));
|
||||
@ -166,7 +166,7 @@ uint8_t MapRendererTerrain::checksum(IMapRendererContext & context, const int3 &
|
||||
{
|
||||
const TerrainTile & mapTile = context.getMapTile(coordinates);
|
||||
|
||||
if(!mapTile.terType->paletteAnimation.empty())
|
||||
if(!mapTile.getTerrain()->paletteAnimation.empty())
|
||||
return context.terrainImageIndex(250);
|
||||
return 0xff - 1;
|
||||
}
|
||||
@ -184,16 +184,16 @@ void MapRendererRiver::renderTile(IMapRendererContext & context, Canvas & target
|
||||
{
|
||||
const TerrainTile & mapTile = context.getMapTile(coordinates);
|
||||
|
||||
if(mapTile.riverType->getId() == River::NO_RIVER)
|
||||
if(!mapTile.hasRiver())
|
||||
return;
|
||||
|
||||
int32_t terrainIndex = mapTile.riverType->getIndex();
|
||||
int32_t terrainIndex = mapTile.getRiverID();
|
||||
int32_t imageIndex = mapTile.riverDir;
|
||||
int32_t rotationIndex = (mapTile.extTileFlags >> 2) % 4;
|
||||
|
||||
const auto & image = storage.find(terrainIndex, rotationIndex, imageIndex);
|
||||
|
||||
for( auto const & element : mapTile.riverType->paletteAnimation)
|
||||
for( auto const & element : mapTile.getRiver()->paletteAnimation)
|
||||
image->shiftPalette(element.start, element.length, context.terrainImageIndex(element.length));
|
||||
|
||||
target.draw(image, Point(0, 0));
|
||||
@ -203,7 +203,7 @@ uint8_t MapRendererRiver::checksum(IMapRendererContext & context, const int3 & c
|
||||
{
|
||||
const TerrainTile & mapTile = context.getMapTile(coordinates);
|
||||
|
||||
if(!mapTile.riverType->paletteAnimation.empty())
|
||||
if(!mapTile.getRiver()->paletteAnimation.empty())
|
||||
return context.terrainImageIndex(250);
|
||||
return 0xff-1;
|
||||
}
|
||||
@ -224,9 +224,9 @@ void MapRendererRoad::renderTile(IMapRendererContext & context, Canvas & target,
|
||||
if(context.isInMap(coordinatesAbove))
|
||||
{
|
||||
const TerrainTile & mapTileAbove = context.getMapTile(coordinatesAbove);
|
||||
if(mapTileAbove.roadType->getId() != Road::NO_ROAD)
|
||||
if(mapTileAbove.hasRoad())
|
||||
{
|
||||
int32_t terrainIndex = mapTileAbove.roadType->getIndex();
|
||||
int32_t terrainIndex = mapTileAbove.getRoadID();
|
||||
int32_t imageIndex = mapTileAbove.roadDir;
|
||||
int32_t rotationIndex = (mapTileAbove.extTileFlags >> 4) % 4;
|
||||
|
||||
@ -236,9 +236,9 @@ void MapRendererRoad::renderTile(IMapRendererContext & context, Canvas & target,
|
||||
}
|
||||
|
||||
const TerrainTile & mapTile = context.getMapTile(coordinates);
|
||||
if(mapTile.roadType->getId() != Road::NO_ROAD)
|
||||
if(mapTile.hasRoad())
|
||||
{
|
||||
int32_t terrainIndex = mapTile.roadType->getIndex();
|
||||
int32_t terrainIndex = mapTile.getRoadID();
|
||||
int32_t imageIndex = mapTile.roadDir;
|
||||
int32_t rotationIndex = (mapTile.extTileFlags >> 4) % 4;
|
||||
|
||||
|
@ -275,7 +275,7 @@ std::string MapRendererAdventureContext::overlayText(const int3 & coordinates) c
|
||||
|
||||
const auto & tile = getMapTile(coordinates);
|
||||
|
||||
if (!tile.visitable)
|
||||
if (!tile.visitable())
|
||||
return {};
|
||||
|
||||
return tile.visitableObjects.back()->getObjectName();
|
||||
@ -288,7 +288,7 @@ ColorRGBA MapRendererAdventureContext::overlayTextColor(const int3 & coordinates
|
||||
|
||||
const auto & tile = getMapTile(coordinates);
|
||||
|
||||
if (!tile.visitable)
|
||||
if (!tile.visitable())
|
||||
return {};
|
||||
|
||||
const auto * object = tile.visitableObjects.back();
|
||||
|
@ -55,7 +55,7 @@ std::string CMapHandler::getTerrainDescr(const int3 & pos, bool rightClick) cons
|
||||
if(t.hasFavorableWinds())
|
||||
return CGI->objtypeh->getObjectName(Obj::FAVORABLE_WINDS, 0);
|
||||
|
||||
std::string result = t.terType->getNameTranslated();
|
||||
std::string result = t.getTerrain()->getNameTranslated();
|
||||
|
||||
for(const auto & object : map->objects)
|
||||
{
|
||||
|
@ -152,7 +152,7 @@ void CArtifactsOfHeroQuickBackpack::setHero(const CGHeroInstance * hero)
|
||||
std::map<const ArtifactID, const CArtifactInstance*> filteredArts;
|
||||
for(auto & slotInfo : curHero->artifactsInBackpack)
|
||||
if(slotInfo.artifact->getTypeId() != artInSlotId && !slotInfo.artifact->isScroll() &&
|
||||
slotInfo.artifact->artType->canBePutAt(curHero, filterBySlot, true))
|
||||
slotInfo.artifact->getType()->canBePutAt(curHero, filterBySlot, true))
|
||||
{
|
||||
filteredArts.insert(std::pair(slotInfo.artifact->getTypeId(), slotInfo.artifact));
|
||||
}
|
||||
|
@ -273,7 +273,7 @@ void CArtifactsOfHeroBase::setSlotData(ArtPlacePtr artPlace, const ArtifactPosit
|
||||
|
||||
// If the artifact is part of at least one combined artifact, add additional information
|
||||
std::map<const ArtifactID, std::vector<ArtifactID>> arts;
|
||||
for(const auto combinedArt : slotInfo->artifact->artType->getPartOf())
|
||||
for(const auto combinedArt : slotInfo->artifact->getType()->getPartOf())
|
||||
{
|
||||
assert(combinedArt->isCombined());
|
||||
arts.try_emplace(combinedArt->getId());
|
||||
|
@ -32,7 +32,7 @@ void CArtifactsOfHeroMarket::clickPressedArtPlace(CComponentHolder & artPlace, c
|
||||
|
||||
if(const auto art = getArt(ownedPlace->slot))
|
||||
{
|
||||
if(onSelectArtCallback && art->artType->isTradable())
|
||||
if(onSelectArtCallback && art->getType()->isTradable())
|
||||
{
|
||||
unmarkSlots();
|
||||
artPlace.selectSlot(true);
|
||||
|
@ -373,7 +373,7 @@ void CGarrisonSlot::gesture(bool on, const Point & initialPosition, const Point
|
||||
const auto * otherArmy = upg == EGarrisonType::UPPER ? owner->lowerArmy() : owner->upperArmy();
|
||||
|
||||
bool stackExists = myStack != nullptr;
|
||||
bool hasSameUnit = stackExists && !owner->army(upg)->getCreatureSlots(myStack->type, ID).empty();
|
||||
bool hasSameUnit = stackExists && !owner->army(upg)->getCreatureSlots(myStack->getCreature(), ID).empty();
|
||||
bool hasOwnEmptySlots = stackExists && owner->army(upg)->getFreeSlot() != SlotID();
|
||||
bool exchangeMode = stackExists && owner->upperArmy() && owner->lowerArmy();
|
||||
bool hasOtherEmptySlots = exchangeMode && otherArmy->getFreeSlot() != SlotID();
|
||||
@ -398,7 +398,7 @@ void CGarrisonSlot::update()
|
||||
{
|
||||
addUsedEvents(LCLICK | SHOW_POPUP | GESTURE | HOVER);
|
||||
myStack = getObj()->getStackPtr(ID);
|
||||
creature = myStack ? myStack->type : nullptr;
|
||||
creature = myStack ? myStack->getCreature() : nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -426,7 +426,7 @@ CGarrisonSlot::CGarrisonSlot(CGarrisonInt * Owner, int x, int y, SlotID IID, EGa
|
||||
: ID(IID),
|
||||
owner(Owner),
|
||||
myStack(creature_),
|
||||
creature(creature_ ? creature_->type : nullptr),
|
||||
creature(creature_ ? creature_->getCreature() : nullptr),
|
||||
upg(Upg)
|
||||
{
|
||||
OBJECT_CONSTRUCTION;
|
||||
|
@ -280,7 +280,7 @@ void CArmyTooltip::init(const InfoAboutArmy &army)
|
||||
continue;
|
||||
}
|
||||
|
||||
icons.push_back(std::make_shared<CAnimImage>(AnimationPath::builtin("CPRSMALL"), slot.second.type->getIconIndex(), 0, slotsPos[slot.first.getNum()].x, slotsPos[slot.first.getNum()].y));
|
||||
icons.push_back(std::make_shared<CAnimImage>(AnimationPath::builtin("CPRSMALL"), slot.second.getType()->getIconIndex(), 0, slotsPos[slot.first.getNum()].x, slotsPos[slot.first.getNum()].y));
|
||||
|
||||
std::string subtitle;
|
||||
if(army.army.isDetailed)
|
||||
|
@ -201,7 +201,7 @@ void CAltarArtifacts::onSlotClickPressed(const std::shared_ptr<CTradeableItem> &
|
||||
{
|
||||
if(pickedArtInst->canBePutAt(altarArtifactsStorage))
|
||||
{
|
||||
if(pickedArtInst->artType->isTradable())
|
||||
if(pickedArtInst->getType()->isTradable())
|
||||
{
|
||||
if(altarSlot->id == -1)
|
||||
tradeSlotsMap.try_emplace(altarSlot, pickedArtInst);
|
||||
|
@ -90,7 +90,7 @@ public:
|
||||
std::string getName() const
|
||||
{
|
||||
if(commander)
|
||||
return commander->type->getNameSingularTranslated();
|
||||
return commander->getType()->getNameSingularTranslated();
|
||||
else
|
||||
return creature->getNamePluralTranslated();
|
||||
}
|
||||
@ -705,7 +705,7 @@ CStackWindow::CStackWindow(const CStackInstance * stack, bool popup)
|
||||
info(new UnitView())
|
||||
{
|
||||
info->stackNode = stack;
|
||||
info->creature = stack->type;
|
||||
info->creature = stack->getCreature();
|
||||
info->creatureCount = stack->count;
|
||||
info->popupWindow = popup;
|
||||
info->owner = dynamic_cast<const CGHeroInstance *> (stack->armyObj);
|
||||
@ -717,7 +717,7 @@ CStackWindow::CStackWindow(const CStackInstance * stack, std::function<void()> d
|
||||
info(new UnitView())
|
||||
{
|
||||
info->stackNode = stack;
|
||||
info->creature = stack->type;
|
||||
info->creature = stack->getCreature();
|
||||
info->creatureCount = stack->count;
|
||||
|
||||
info->upgradeInfo = std::make_optional(UnitView::StackUpgradeInfo());
|
||||
@ -734,7 +734,7 @@ CStackWindow::CStackWindow(const CCommanderInstance * commander, bool popup)
|
||||
info(new UnitView())
|
||||
{
|
||||
info->stackNode = commander;
|
||||
info->creature = commander->type;
|
||||
info->creature = commander->getCreature();
|
||||
info->commander = commander;
|
||||
info->creatureCount = 1;
|
||||
info->popupWindow = popup;
|
||||
@ -747,7 +747,7 @@ CStackWindow::CStackWindow(const CCommanderInstance * commander, std::vector<ui3
|
||||
info(new UnitView())
|
||||
{
|
||||
info->stackNode = commander;
|
||||
info->creature = commander->type;
|
||||
info->creature = commander->getCreature();
|
||||
info->commander = commander;
|
||||
info->creatureCount = 1;
|
||||
info->levelupInfo = std::make_optional(UnitView::CommanderLevelInfo());
|
||||
@ -879,7 +879,7 @@ std::string CStackWindow::generateStackExpDescription()
|
||||
const CStackInstance * stack = info->stackNode;
|
||||
const CCreature * creature = info->creature;
|
||||
|
||||
int tier = stack->type->getLevel();
|
||||
int tier = stack->getType()->getLevel();
|
||||
int rank = stack->getExpRank();
|
||||
if (!vstd::iswithin(tier, 1, 7))
|
||||
tier = 0;
|
||||
|
@ -67,9 +67,9 @@ Canvas CMapOverviewWidget::createMinimapForLayer(std::unique_ptr<CMap> & map, in
|
||||
{
|
||||
TerrainTile & tile = map->getTile(int3(x, y, layer));
|
||||
|
||||
ColorRGBA color = tile.terType->minimapUnblocked;
|
||||
if (tile.blocked && (!tile.visitable))
|
||||
color = tile.terType->minimapBlocked;
|
||||
ColorRGBA color = tile.getTerrain()->minimapUnblocked;
|
||||
if (tile.blocked() && !tile.visitable())
|
||||
color = tile.getTerrain()->minimapBlocked;
|
||||
|
||||
if(drawPlayerElements)
|
||||
// if object at tile is owned - it will be colored as its owner
|
||||
|
@ -198,7 +198,7 @@ void CWindowWithArtifacts::markPossibleSlots() const
|
||||
continue;
|
||||
|
||||
if(getHeroPickedArtifact() == hero || !std::dynamic_pointer_cast<CArtifactsOfHeroKingdom>(artSet))
|
||||
artSet->markPossibleSlots(pickedArtInst->artType, hero->tempOwner == LOCPLINT->playerID);
|
||||
artSet->markPossibleSlots(pickedArtInst->getType(), hero->tempOwner == LOCPLINT->playerID);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -219,7 +219,7 @@ bool CWindowWithArtifacts::checkSpecialArts(const CArtifactInstance & artInst, c
|
||||
std::vector<std::shared_ptr<CComponent>>(1, std::make_shared<CComponent>(ComponentType::ARTIFACT, ArtifactID(ArtifactID::CATAPULT))));
|
||||
return false;
|
||||
}
|
||||
if(isTrade && !artInst.artType->isTradable())
|
||||
if(isTrade && !artInst.getType()->isTradable())
|
||||
{
|
||||
LOCPLINT->showInfoDialog(CGI->generaltexth->allTexts[21],
|
||||
std::vector<std::shared_ptr<CComponent>>(1, std::make_shared<CComponent>(ComponentType::ARTIFACT, artId)));
|
||||
@ -240,7 +240,7 @@ void CWindowWithArtifacts::setCursorAnimation(const CArtifactInstance & artInst)
|
||||
}
|
||||
else
|
||||
{
|
||||
CCS->curh->dragAndDropCursor(AnimationPath::builtin("artifact"), artInst.artType->getIconIndex());
|
||||
CCS->curh->dragAndDropCursor(AnimationPath::builtin("artifact"), artInst.getType()->getIconIndex());
|
||||
}
|
||||
}
|
||||
|
||||
@ -253,10 +253,10 @@ void CWindowWithArtifacts::putPickedArtifact(const CGHeroInstance & curHero, con
|
||||
|
||||
if(ArtifactUtils::isSlotBackpack(dstLoc.slot))
|
||||
{
|
||||
if(pickedArt->artType->isBig())
|
||||
if(pickedArt->getType()->isBig())
|
||||
{
|
||||
// War machines cannot go to backpack
|
||||
LOCPLINT->showInfoDialog(boost::str(boost::format(CGI->generaltexth->allTexts[153]) % pickedArt->artType->getNameTranslated()));
|
||||
LOCPLINT->showInfoDialog(boost::str(boost::format(CGI->generaltexth->allTexts[153]) % pickedArt->getType()->getNameTranslated()));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1056,7 +1056,7 @@ CGarrisonWindow::CGarrisonWindow(const CArmedInstance * up, const CGHeroInstance
|
||||
if(up->Slots().size() > 0)
|
||||
{
|
||||
titleText = CGI->generaltexth->allTexts[35];
|
||||
boost::algorithm::replace_first(titleText, "%s", up->Slots().begin()->second->type->getNamePluralTranslated());
|
||||
boost::algorithm::replace_first(titleText, "%s", up->Slots().begin()->second->getType()->getNamePluralTranslated());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -732,7 +732,7 @@ ArtifactPosition CArtifactSet::getArtPos(const ArtifactID & aid, bool onlyWorn,
|
||||
for(const auto & artInfo : artifactsInBackpack)
|
||||
{
|
||||
const auto art = artInfo.getArt();
|
||||
if(art && art->artType->getId() == aid)
|
||||
if(art && art->getType()->getId() == aid)
|
||||
return ArtifactPosition(backpackPositionIdx);
|
||||
backpackPositionIdx++;
|
||||
}
|
||||
@ -757,7 +757,7 @@ ArtifactPosition CArtifactSet::getArtPos(const CArtifactInstance * artInst) cons
|
||||
{
|
||||
if(artInst)
|
||||
{
|
||||
for(const auto & slot : artInst->artType->getPossibleSlots().at(bearerType()))
|
||||
for(const auto & slot : artInst->getType()->getPossibleSlots().at(bearerType()))
|
||||
if(getArt(slot) == artInst)
|
||||
return slot;
|
||||
|
||||
@ -805,11 +805,11 @@ CArtifactSet::ArtPlacementMap CArtifactSet::putArtifact(const ArtifactPosition &
|
||||
};
|
||||
|
||||
putToSlot(slot, art, false);
|
||||
if(art->artType->isCombined() && ArtifactUtils::isSlotEquipment(slot))
|
||||
if(art->getType()->isCombined() && ArtifactUtils::isSlotEquipment(slot))
|
||||
{
|
||||
const CArtifactInstance * mainPart = nullptr;
|
||||
for(const auto & part : art->getPartsInfo())
|
||||
if(vstd::contains(part.art->artType->getPossibleSlots().at(bearerType()), slot)
|
||||
if(vstd::contains(part.art->getType()->getPossibleSlots().at(bearerType()), slot)
|
||||
&& (part.slot == ArtifactPosition::PRE_FIRST))
|
||||
{
|
||||
mainPart = part.art;
|
||||
@ -821,7 +821,7 @@ CArtifactSet::ArtPlacementMap CArtifactSet::putArtifact(const ArtifactPosition &
|
||||
if(part.art != mainPart)
|
||||
{
|
||||
auto partSlot = part.slot;
|
||||
if(!part.art->artType->canBePutAt(this, partSlot))
|
||||
if(!part.art->getType()->canBePutAt(this, partSlot))
|
||||
partSlot = ArtifactUtils::getArtAnyPosition(this, part.art->getTypeId());
|
||||
|
||||
assert(ArtifactUtils::isSlotEquipment(partSlot));
|
||||
@ -995,7 +995,7 @@ void CArtifactSet::serializeJsonHero(JsonSerializeFormat & handler)
|
||||
{
|
||||
auto * artifact = ArtifactUtils::createArtifact(artifactID);
|
||||
auto slot = ArtifactPosition::BACKPACK_START + artifactsInBackpack.size();
|
||||
if(artifact->artType->canBePutAt(this, slot))
|
||||
if(artifact->getType()->canBePutAt(this, slot))
|
||||
{
|
||||
auto artsMap = putArtifact(slot, artifact);
|
||||
artifact->addPlacementMap(artsMap);
|
||||
@ -1036,7 +1036,7 @@ void CArtifactSet::serializeJsonSlot(JsonSerializeFormat & handler, const Artifa
|
||||
{
|
||||
auto * artifact = ArtifactUtils::createArtifact(artifactID.toEnum());
|
||||
|
||||
if(artifact->artType->canBePutAt(this, slot))
|
||||
if(artifact->getType()->canBePutAt(this, slot))
|
||||
{
|
||||
auto artsMap = putArtifact(slot, artifact);
|
||||
artifact->addPlacementMap(artsMap);
|
||||
|
@ -20,12 +20,12 @@ VCMI_LIB_NAMESPACE_BEGIN
|
||||
void CCombinedArtifactInstance::addPart(CArtifactInstance * art, const ArtifactPosition & slot)
|
||||
{
|
||||
auto artInst = static_cast<CArtifactInstance*>(this);
|
||||
assert(vstd::contains_if(artInst->artType->getConstituents(),
|
||||
assert(vstd::contains_if(artInst->getType()->getConstituents(),
|
||||
[=](const CArtifact * partType)
|
||||
{
|
||||
return partType->getId() == art->getTypeId();
|
||||
}));
|
||||
assert(art->getParentNodes().size() == 1 && art->getParentNodes().front() == art->artType);
|
||||
assert(art->getParentNodes().size() == 1 && art->getParentNodes().front() == art->getType());
|
||||
partsInfo.emplace_back(art, slot);
|
||||
artInst->attachTo(*art);
|
||||
}
|
||||
@ -77,7 +77,7 @@ void CGrowingArtifactInstance::growingUp()
|
||||
{
|
||||
auto artInst = static_cast<CArtifactInstance*>(this);
|
||||
|
||||
if(artInst->artType->isGrowing())
|
||||
if(artInst->getType()->isGrowing())
|
||||
{
|
||||
|
||||
auto bonus = std::make_shared<Bonus>();
|
||||
@ -86,7 +86,7 @@ void CGrowingArtifactInstance::growingUp()
|
||||
bonus->duration = BonusDuration::COMMANDER_KILLED;
|
||||
artInst->accumulateBonus(bonus);
|
||||
|
||||
for(const auto & bonus : artInst->artType->getBonusesPerLevel())
|
||||
for(const auto & bonus : artInst->getType()->getBonusesPerLevel())
|
||||
{
|
||||
// Every n levels
|
||||
if(artInst->valOfBonuses(BonusType::LEVEL_COUNTER) % bonus.first == 0)
|
||||
@ -94,7 +94,7 @@ void CGrowingArtifactInstance::growingUp()
|
||||
artInst->accumulateBonus(std::make_shared<Bonus>(bonus.second));
|
||||
}
|
||||
}
|
||||
for(const auto & bonus : artInst->artType->getThresholdBonuses())
|
||||
for(const auto & bonus : artInst->getType()->getThresholdBonuses())
|
||||
{
|
||||
// At n level
|
||||
if(artInst->valOfBonuses(BonusType::LEVEL_COUNTER) == bonus.first)
|
||||
@ -125,18 +125,23 @@ CArtifactInstance::CArtifactInstance()
|
||||
|
||||
void CArtifactInstance::setType(const CArtifact * art)
|
||||
{
|
||||
artType = art;
|
||||
artTypeID = art->getId();
|
||||
attachToSource(*art);
|
||||
}
|
||||
|
||||
std::string CArtifactInstance::nodeName() const
|
||||
{
|
||||
return "Artifact instance of " + (artType ? artType->getJsonKey() : std::string("uninitialized")) + " type";
|
||||
return "Artifact instance of " + (getType() ? getType()->getJsonKey() : std::string("uninitialized")) + " type";
|
||||
}
|
||||
|
||||
ArtifactID CArtifactInstance::getTypeId() const
|
||||
{
|
||||
return artType->getId();
|
||||
return artTypeID;
|
||||
}
|
||||
|
||||
const CArtifact * CArtifactInstance::getType() const
|
||||
{
|
||||
return artTypeID.toArtifact();
|
||||
}
|
||||
|
||||
ArtifactInstanceID CArtifactInstance::getId() const
|
||||
@ -151,22 +156,22 @@ void CArtifactInstance::setId(ArtifactInstanceID id)
|
||||
|
||||
bool CArtifactInstance::canBePutAt(const CArtifactSet * artSet, ArtifactPosition slot, bool assumeDestRemoved) const
|
||||
{
|
||||
return artType->canBePutAt(artSet, slot, assumeDestRemoved);
|
||||
return getType()->canBePutAt(artSet, slot, assumeDestRemoved);
|
||||
}
|
||||
|
||||
bool CArtifactInstance::isCombined() const
|
||||
{
|
||||
return artType->isCombined();
|
||||
return getType()->isCombined();
|
||||
}
|
||||
|
||||
bool CArtifactInstance::isScroll() const
|
||||
{
|
||||
return artType->isScroll();
|
||||
return getType()->isScroll();
|
||||
}
|
||||
|
||||
void CArtifactInstance::deserializationFix()
|
||||
{
|
||||
setType(artType);
|
||||
setType(artTypeID.toArtifact());
|
||||
for(PartInfo & part : partsInfo)
|
||||
attachTo(*part.art);
|
||||
}
|
||||
|
@ -73,14 +73,15 @@ protected:
|
||||
void init();
|
||||
|
||||
ArtifactInstanceID id;
|
||||
ArtifactID artTypeID;
|
||||
public:
|
||||
const CArtifact * artType = nullptr;
|
||||
|
||||
CArtifactInstance(const CArtifact * art);
|
||||
CArtifactInstance();
|
||||
void setType(const CArtifact * art);
|
||||
std::string nodeName() const override;
|
||||
ArtifactID getTypeId() const;
|
||||
const CArtifact * getType() const;
|
||||
ArtifactInstanceID getId() const;
|
||||
void setId(ArtifactInstanceID id);
|
||||
|
||||
@ -94,7 +95,17 @@ public:
|
||||
{
|
||||
h & static_cast<CBonusSystemNode&>(*this);
|
||||
h & static_cast<CCombinedArtifactInstance&>(*this);
|
||||
h & artType;
|
||||
if (h.version >= Handler::Version::REMOVE_VLC_POINTERS)
|
||||
{
|
||||
h & artTypeID;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool isNull = false;
|
||||
h & isNull;
|
||||
if (!isNull)
|
||||
h & artTypeID;
|
||||
}
|
||||
h & id;
|
||||
BONUS_TREE_DESERIALIZATION_FIX
|
||||
}
|
||||
|
@ -343,11 +343,6 @@ bool CCreature::isMyUpgrade(const CCreature *anotherCre) const
|
||||
return vstd::contains(upgrades, anotherCre->getId());
|
||||
}
|
||||
|
||||
bool CCreature::valid() const
|
||||
{
|
||||
return this == (*VLC->creh)[idNumber];
|
||||
}
|
||||
|
||||
std::string CCreature::nodeName() const
|
||||
{
|
||||
return "\"" + getNamePluralTextID() + "\"";
|
||||
|
@ -166,8 +166,6 @@ public:
|
||||
static int estimateCreatureCount(ui32 countID); //reverse version of above function, returns middle of range
|
||||
bool isMyUpgrade(const CCreature *anotherCre) const;
|
||||
|
||||
bool valid() const;
|
||||
|
||||
void addBonus(int val, BonusType type);
|
||||
void addBonus(int val, BonusType type, BonusSubtypeID subtype);
|
||||
std::string nodeName() const override;
|
||||
|
@ -48,7 +48,7 @@ const CCreature * CCreatureSet::getCreature(const SlotID & slot) const
|
||||
{
|
||||
auto i = stacks.find(slot);
|
||||
if (i != stacks.end())
|
||||
return i->second->type;
|
||||
return i->second->getCreature();
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
@ -84,11 +84,10 @@ SlotID CCreatureSet::getSlotFor(const CreatureID & creature, ui32 slotsAmount) c
|
||||
|
||||
SlotID CCreatureSet::getSlotFor(const CCreature *c, ui32 slotsAmount) const
|
||||
{
|
||||
assert(c && c->valid());
|
||||
assert(c);
|
||||
for(const auto & elem : stacks)
|
||||
{
|
||||
assert(elem.second->type->valid());
|
||||
if(elem.second->type == c)
|
||||
if(elem.second->getType() == c)
|
||||
{
|
||||
return elem.first; //if there is already such creature we return its slot id
|
||||
}
|
||||
@ -98,18 +97,16 @@ SlotID CCreatureSet::getSlotFor(const CCreature *c, ui32 slotsAmount) const
|
||||
|
||||
bool CCreatureSet::hasCreatureSlots(const CCreature * c, const SlotID & exclude) const
|
||||
{
|
||||
assert(c && c->valid());
|
||||
assert(c);
|
||||
for(const auto & elem : stacks) // elem is const
|
||||
{
|
||||
if(elem.first == exclude) // Check slot
|
||||
continue;
|
||||
|
||||
if(!elem.second || !elem.second->type) // Check creature
|
||||
if(!elem.second || !elem.second->getType()) // Check creature
|
||||
continue;
|
||||
|
||||
assert(elem.second->type->valid());
|
||||
|
||||
if(elem.second->type == c)
|
||||
if(elem.second->getType() == c)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -117,7 +114,7 @@ bool CCreatureSet::hasCreatureSlots(const CCreature * c, const SlotID & exclude)
|
||||
|
||||
std::vector<SlotID> CCreatureSet::getCreatureSlots(const CCreature * c, const SlotID & exclude, TQuantity ignoreAmount) const
|
||||
{
|
||||
assert(c && c->valid());
|
||||
assert(c);
|
||||
std::vector<SlotID> result;
|
||||
|
||||
for(const auto & elem : stacks)
|
||||
@ -125,13 +122,12 @@ std::vector<SlotID> CCreatureSet::getCreatureSlots(const CCreature * c, const Sl
|
||||
if(elem.first == exclude)
|
||||
continue;
|
||||
|
||||
if(!elem.second || !elem.second->type || elem.second->type != c)
|
||||
if(!elem.second || !elem.second->getType() || elem.second->getType() != c)
|
||||
continue;
|
||||
|
||||
if(elem.second->count == ignoreAmount || elem.second->count < 1)
|
||||
continue;
|
||||
|
||||
assert(elem.second->type->valid());
|
||||
result.push_back(elem.first);
|
||||
}
|
||||
return result;
|
||||
@ -139,13 +135,13 @@ std::vector<SlotID> CCreatureSet::getCreatureSlots(const CCreature * c, const Sl
|
||||
|
||||
bool CCreatureSet::isCreatureBalanced(const CCreature * c, TQuantity ignoreAmount) const
|
||||
{
|
||||
assert(c && c->valid());
|
||||
assert(c);
|
||||
TQuantity max = 0;
|
||||
auto min = std::numeric_limits<TQuantity>::max();
|
||||
|
||||
for(const auto & elem : stacks)
|
||||
{
|
||||
if(!elem.second || !elem.second->type || elem.second->type != c)
|
||||
if(!elem.second || !elem.second->getType() || elem.second->getType() != c)
|
||||
continue;
|
||||
|
||||
const auto count = elem.second->count;
|
||||
@ -153,7 +149,6 @@ bool CCreatureSet::isCreatureBalanced(const CCreature * c, TQuantity ignoreAmoun
|
||||
if(count == ignoreAmount || count < 1)
|
||||
continue;
|
||||
|
||||
assert(elem.second->type->valid());
|
||||
|
||||
if(count > max)
|
||||
max = count;
|
||||
@ -214,7 +209,7 @@ TMapCreatureSlot CCreatureSet::getCreatureMap() const
|
||||
// https://www.cplusplus.com/reference/map/map/key_comp/
|
||||
for(const auto & pair : stacks)
|
||||
{
|
||||
const auto * creature = pair.second->type;
|
||||
const auto * creature = pair.second->getCreature();
|
||||
auto slot = pair.first;
|
||||
auto lb = creatureMap.lower_bound(creature);
|
||||
|
||||
@ -234,7 +229,7 @@ TCreatureQueue CCreatureSet::getCreatureQueue(const SlotID & exclude) const
|
||||
{
|
||||
if(pair.first == exclude)
|
||||
continue;
|
||||
creatureQueue.push(std::make_pair(pair.second->type, pair.first));
|
||||
creatureQueue.push(std::make_pair(pair.second->getCreature(), pair.first));
|
||||
}
|
||||
return creatureQueue;
|
||||
}
|
||||
@ -262,10 +257,10 @@ bool CCreatureSet::mergeableStacks(std::pair<SlotID, SlotID> & out, const SlotID
|
||||
//try to match creature to our preferred stack
|
||||
if(preferable.validSlot() && vstd::contains(stacks, preferable))
|
||||
{
|
||||
const CCreature *cr = stacks.find(preferable)->second->type;
|
||||
const CCreature *cr = stacks.find(preferable)->second->getCreature();
|
||||
for(const auto & elem : stacks)
|
||||
{
|
||||
if(cr == elem.second->type && elem.first != preferable)
|
||||
if(cr == elem.second->getType() && elem.first != preferable)
|
||||
{
|
||||
out.first = preferable;
|
||||
out.second = elem.first;
|
||||
@ -278,7 +273,7 @@ bool CCreatureSet::mergeableStacks(std::pair<SlotID, SlotID> & out, const SlotID
|
||||
{
|
||||
for(const auto & elem : stacks)
|
||||
{
|
||||
if(stack.second->type == elem.second->type && stack.first != elem.first)
|
||||
if(stack.second->getType() == elem.second->getType() && stack.first != elem.first)
|
||||
{
|
||||
out.first = stack.first;
|
||||
out.second = elem.first;
|
||||
@ -328,7 +323,7 @@ void CCreatureSet::addToSlot(const SlotID & slot, CStackInstance * stack, bool a
|
||||
{
|
||||
putStack(slot, stack);
|
||||
}
|
||||
else if(allowMerging && stack->type == getCreature(slot))
|
||||
else if(allowMerging && stack->getType() == getCreature(slot))
|
||||
{
|
||||
joinStack(slot, stack);
|
||||
}
|
||||
@ -514,7 +509,7 @@ void CCreatureSet::putStack(const SlotID & slot, CStackInstance * stack)
|
||||
void CCreatureSet::joinStack(const SlotID & slot, CStackInstance * stack)
|
||||
{
|
||||
[[maybe_unused]] const CCreature *c = getCreature(slot);
|
||||
assert(c == stack->type);
|
||||
assert(c == stack->getType());
|
||||
assert(c);
|
||||
|
||||
//TODO move stuff
|
||||
@ -577,9 +572,9 @@ bool CCreatureSet::canBeMergedWith(const CCreatureSet &cs, bool allowMergingStac
|
||||
std::set<const CCreature*> cresToAdd;
|
||||
for(const auto & elem : cs.stacks)
|
||||
{
|
||||
SlotID dest = getSlotFor(elem.second->type);
|
||||
SlotID dest = getSlotFor(elem.second->getCreature());
|
||||
if(!dest.validSlot() || hasStackAtSlot(dest))
|
||||
cresToAdd.insert(elem.second->type);
|
||||
cresToAdd.insert(elem.second->getCreature());
|
||||
}
|
||||
return cresToAdd.size() <= freeSlots;
|
||||
}
|
||||
@ -590,13 +585,13 @@ bool CCreatureSet::canBeMergedWith(const CCreatureSet &cs, bool allowMergingStac
|
||||
|
||||
//get types of creatures that need their own slot
|
||||
for(const auto & elem : cs.stacks)
|
||||
if ((j = cres.getSlotFor(elem.second->type)).validSlot())
|
||||
cres.addToSlot(j, elem.second->type->getId(), 1, true); //merge if possible
|
||||
if ((j = cres.getSlotFor(elem.second->getCreature())).validSlot())
|
||||
cres.addToSlot(j, elem.second->getId(), 1, true); //merge if possible
|
||||
//cres.addToSlot(elem.first, elem.second->type->getId(), 1, true);
|
||||
for(const auto & elem : stacks)
|
||||
{
|
||||
if ((j = cres.getSlotFor(elem.second->type)).validSlot())
|
||||
cres.addToSlot(j, elem.second->type->getId(), 1, true); //merge if possible
|
||||
if ((j = cres.getSlotFor(elem.second->getCreature())).validSlot())
|
||||
cres.addToSlot(j, elem.second->getId(), 1, true); //merge if possible
|
||||
else
|
||||
return false; //no place found
|
||||
}
|
||||
@ -693,7 +688,7 @@ void CStackInstance::init()
|
||||
{
|
||||
experience = 0;
|
||||
count = 0;
|
||||
type = nullptr;
|
||||
setType(nullptr);
|
||||
_armyObj = nullptr;
|
||||
setNodeType(STACK_INSTANCE);
|
||||
}
|
||||
@ -707,7 +702,7 @@ int CStackInstance::getExpRank() const
|
||||
{
|
||||
if (!VLC->engineSettings()->getBoolean(EGameSettings::MODULE_STACK_EXPERIENCE))
|
||||
return 0;
|
||||
int tier = type->getLevel();
|
||||
int tier = getType()->getLevel();
|
||||
if (vstd::iswithin(tier, 1, 7))
|
||||
{
|
||||
for(int i = static_cast<int>(VLC->creh->expRanks[tier].size()) - 2; i > -1; --i) //sic!
|
||||
@ -730,12 +725,12 @@ int CStackInstance::getExpRank() const
|
||||
|
||||
int CStackInstance::getLevel() const
|
||||
{
|
||||
return std::max(1, static_cast<int>(type->getLevel()));
|
||||
return std::max(1, static_cast<int>(getType()->getLevel()));
|
||||
}
|
||||
|
||||
void CStackInstance::giveStackExp(TExpType exp)
|
||||
{
|
||||
int level = type->getLevel();
|
||||
int level = getType()->getLevel();
|
||||
if (!vstd::iswithin(level, 1, 7))
|
||||
level = 0;
|
||||
|
||||
@ -756,17 +751,17 @@ void CStackInstance::setType(const CreatureID & creID)
|
||||
|
||||
void CStackInstance::setType(const CCreature *c)
|
||||
{
|
||||
if(type)
|
||||
if(getCreature())
|
||||
{
|
||||
detachFromSource(*type);
|
||||
if (type->isMyUpgrade(c) && VLC->engineSettings()->getBoolean(EGameSettings::MODULE_STACK_EXPERIENCE))
|
||||
detachFromSource(*getCreature());
|
||||
if (getCreature()->isMyUpgrade(c) && VLC->engineSettings()->getBoolean(EGameSettings::MODULE_STACK_EXPERIENCE))
|
||||
experience = static_cast<TExpType>(experience * VLC->creh->expAfterUpgrade / 100.0);
|
||||
}
|
||||
|
||||
CStackBasicDescriptor::setType(c);
|
||||
|
||||
if(type)
|
||||
attachToSource(*type);
|
||||
if(getCreature())
|
||||
attachToSource(*getCreature());
|
||||
}
|
||||
std::string CStackInstance::bonusToString(const std::shared_ptr<Bonus>& bonus, bool description) const
|
||||
{
|
||||
@ -808,7 +803,7 @@ bool CStackInstance::valid(bool allowUnrandomized) const
|
||||
{
|
||||
if(!randomStack)
|
||||
{
|
||||
return (type && type == type->getId().toEntity(VLC));
|
||||
return (getType() && getType() == getId().toEntity(VLC));
|
||||
}
|
||||
else
|
||||
return allowUnrandomized;
|
||||
@ -818,8 +813,8 @@ std::string CStackInstance::nodeName() const
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "Stack of " << count << " of ";
|
||||
if(type)
|
||||
oss << type->getNamePluralTextID();
|
||||
if(getType())
|
||||
oss << getType()->getNamePluralTextID();
|
||||
else
|
||||
oss << "[UNDEFINED TYPE]";
|
||||
|
||||
@ -841,21 +836,21 @@ void CStackInstance::deserializationFix()
|
||||
|
||||
CreatureID CStackInstance::getCreatureID() const
|
||||
{
|
||||
if(type)
|
||||
return type->getId();
|
||||
if(getType())
|
||||
return getType()->getId();
|
||||
else
|
||||
return CreatureID::NONE;
|
||||
}
|
||||
|
||||
std::string CStackInstance::getName() const
|
||||
{
|
||||
return (count > 1) ? type->getNamePluralTranslated() : type->getNameSingularTranslated();
|
||||
return (count > 1) ? getType()->getNamePluralTranslated() : getType()->getNameSingularTranslated();
|
||||
}
|
||||
|
||||
ui64 CStackInstance::getPower() const
|
||||
{
|
||||
assert(type);
|
||||
return static_cast<ui64>(type->getAIValue()) * count;
|
||||
assert(getType());
|
||||
return static_cast<ui64>(getType()->getAIValue()) * count;
|
||||
}
|
||||
|
||||
ArtBearer::ArtBearer CStackInstance::bearerType() const
|
||||
@ -899,7 +894,7 @@ void CStackInstance::serializeJson(JsonSerializeFormat & handler)
|
||||
else
|
||||
{
|
||||
//type set by CStackBasicDescriptor::serializeJson
|
||||
if(type == nullptr)
|
||||
if(getType() == nullptr)
|
||||
{
|
||||
uint8_t level = 0;
|
||||
uint8_t upgrade = 0;
|
||||
@ -914,8 +909,8 @@ void CStackInstance::serializeJson(JsonSerializeFormat & handler)
|
||||
|
||||
FactionID CStackInstance::getFactionID() const
|
||||
{
|
||||
if(type)
|
||||
return type->getFactionID();
|
||||
if(getType())
|
||||
return getType()->getFactionID();
|
||||
|
||||
return FactionID::NEUTRAL;
|
||||
}
|
||||
@ -943,7 +938,7 @@ void CCommanderInstance::init()
|
||||
experience = 0;
|
||||
level = 1;
|
||||
count = 1;
|
||||
type = nullptr;
|
||||
setType(nullptr);
|
||||
_armyObj = nullptr;
|
||||
setNodeType (CBonusSystemNode::COMMANDER);
|
||||
secondarySkills.resize (ECommander::SPELL_POWER + 1);
|
||||
@ -998,24 +993,29 @@ bool CCommanderInstance::gainsLevel() const
|
||||
CStackBasicDescriptor::CStackBasicDescriptor() = default;
|
||||
|
||||
CStackBasicDescriptor::CStackBasicDescriptor(const CreatureID & id, TQuantity Count):
|
||||
type(id.toCreature()),
|
||||
typeID(id),
|
||||
count(Count)
|
||||
{
|
||||
}
|
||||
|
||||
CStackBasicDescriptor::CStackBasicDescriptor(const CCreature *c, TQuantity Count)
|
||||
: type(c), count(Count)
|
||||
: typeID(c ? c->getId() : CreatureID()), count(Count)
|
||||
{
|
||||
}
|
||||
|
||||
const CCreature * CStackBasicDescriptor::getCreature() const
|
||||
{
|
||||
return typeID.toCreature();
|
||||
}
|
||||
|
||||
const Creature * CStackBasicDescriptor::getType() const
|
||||
{
|
||||
return type;
|
||||
return typeID.toEntity(VLC);
|
||||
}
|
||||
|
||||
CreatureID CStackBasicDescriptor::getId() const
|
||||
{
|
||||
return type->getId();
|
||||
return typeID;
|
||||
}
|
||||
|
||||
TQuantity CStackBasicDescriptor::getCount() const
|
||||
@ -1023,18 +1023,14 @@ TQuantity CStackBasicDescriptor::getCount() const
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
void CStackBasicDescriptor::setType(const CCreature * c)
|
||||
{
|
||||
type = c;
|
||||
typeID = c ? c->getId() : CreatureID();
|
||||
}
|
||||
|
||||
bool operator== (const CStackBasicDescriptor & l, const CStackBasicDescriptor & r)
|
||||
{
|
||||
return (!l.type && !r.type)
|
||||
|| (l.type && r.type
|
||||
&& l.type->getId() == r.type->getId()
|
||||
&& l.count == r.count);
|
||||
return l.typeID == r.typeID && l.count == r.count;
|
||||
}
|
||||
|
||||
void CStackBasicDescriptor::serializeJson(JsonSerializeFormat & handler)
|
||||
@ -1043,9 +1039,9 @@ void CStackBasicDescriptor::serializeJson(JsonSerializeFormat & handler)
|
||||
|
||||
if(handler.saving)
|
||||
{
|
||||
if(type)
|
||||
if(typeID.hasValue())
|
||||
{
|
||||
std::string typeName = type->getJsonKey();
|
||||
std::string typeName = typeID.toEntity(VLC)->getJsonKey();
|
||||
handler.serializeString("type", typeName);
|
||||
}
|
||||
}
|
||||
|
@ -31,8 +31,8 @@ class JsonSerializeFormat;
|
||||
|
||||
class DLL_LINKAGE CStackBasicDescriptor
|
||||
{
|
||||
CreatureID typeID;
|
||||
public:
|
||||
const CCreature *type = nullptr;
|
||||
TQuantity count = -1; //exact quantity or quantity ID from CCreature::getQuantityID when getting info about enemy army
|
||||
|
||||
CStackBasicDescriptor();
|
||||
@ -41,29 +41,20 @@ public:
|
||||
virtual ~CStackBasicDescriptor() = default;
|
||||
|
||||
const Creature * getType() const;
|
||||
const CCreature * getCreature() const;
|
||||
CreatureID getId() const;
|
||||
TQuantity getCount() const;
|
||||
|
||||
virtual void setType(const CCreature * c);
|
||||
|
||||
|
||||
friend bool operator== (const CStackBasicDescriptor & l, const CStackBasicDescriptor & r);
|
||||
|
||||
template <typename Handler> void serialize(Handler &h)
|
||||
{
|
||||
if(h.saving)
|
||||
{
|
||||
auto idNumber = type ? type->getId() : CreatureID(CreatureID::NONE);
|
||||
h & idNumber;
|
||||
}
|
||||
else
|
||||
{
|
||||
CreatureID idNumber;
|
||||
h & idNumber;
|
||||
if(idNumber != CreatureID::NONE)
|
||||
setType(dynamic_cast<const CCreature*>(VLC->creatures()->getById(idNumber)));
|
||||
else
|
||||
type = nullptr;
|
||||
}
|
||||
h & typeID;
|
||||
if(!h.saving)
|
||||
setType(typeID.toCreature());
|
||||
|
||||
h & count;
|
||||
}
|
||||
|
||||
|
@ -345,10 +345,10 @@ bool CGameInfoCallback::getHeroInfo(const CGObjectInstance * hero, InfoAboutHero
|
||||
|
||||
for(auto & elem : info.army)
|
||||
{
|
||||
if(static_cast<int>(elem.second.type->getAIValue()) > maxAIValue)
|
||||
if(static_cast<int>(elem.second.getCreature()->getAIValue()) > maxAIValue)
|
||||
{
|
||||
maxAIValue = elem.second.type->getAIValue();
|
||||
mostStrong = elem.second.type;
|
||||
maxAIValue = elem.second.getCreature()->getAIValue();
|
||||
mostStrong = elem.second.getCreature();
|
||||
}
|
||||
}
|
||||
|
||||
@ -357,7 +357,7 @@ bool CGameInfoCallback::getHeroInfo(const CGObjectInstance * hero, InfoAboutHero
|
||||
else
|
||||
for(auto & elem : info.army)
|
||||
{
|
||||
elem.second.type = mostStrong;
|
||||
elem.second.setType(mostStrong);
|
||||
}
|
||||
};
|
||||
|
||||
@ -390,7 +390,7 @@ bool CGameInfoCallback::getHeroInfo(const CGObjectInstance * hero, InfoAboutHero
|
||||
|
||||
if(nullptr != mostStrong) //possible, faction may have no creatures at all
|
||||
for(auto & elem : info.army)
|
||||
elem.second.type = mostStrong;
|
||||
elem.second.setType(mostStrong);
|
||||
};
|
||||
|
||||
|
||||
@ -630,7 +630,7 @@ EBuildingState CGameInfoCallback::canBuildStructure( const CGTownInstance *t, Bu
|
||||
{
|
||||
const TerrainTile *tile = getTile(t->bestLocation(), false);
|
||||
|
||||
if(!tile || !tile->terType->isWater())
|
||||
if(!tile || !tile->isWater())
|
||||
return EBuildingState::NO_WATER; //lack of water
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@ CStack::CStack(const CStackInstance * Base, const PlayerColor & O, int I, Battle
|
||||
CBonusSystemNode(STACK_BATTLE),
|
||||
base(Base),
|
||||
ID(I),
|
||||
type(Base->type),
|
||||
typeID(Base->getId()),
|
||||
baseAmount(Base->count),
|
||||
owner(O),
|
||||
slot(S),
|
||||
@ -48,7 +48,7 @@ CStack::CStack():
|
||||
CStack::CStack(const CStackBasicDescriptor * stack, const PlayerColor & O, int I, BattleSide Side, const SlotID & S):
|
||||
CBonusSystemNode(STACK_BATTLE),
|
||||
ID(I),
|
||||
type(stack->type),
|
||||
typeID(stack->getId()),
|
||||
baseAmount(stack->count),
|
||||
owner(O),
|
||||
slot(S),
|
||||
@ -60,7 +60,7 @@ CStack::CStack(const CStackBasicDescriptor * stack, const PlayerColor & O, int I
|
||||
void CStack::localInit(BattleInfo * battleInfo)
|
||||
{
|
||||
battle = battleInfo;
|
||||
assert(type);
|
||||
assert(typeID.hasValue());
|
||||
|
||||
exportBonuses();
|
||||
if(base) //stack originating from "real" stack in garrison -> attach to it
|
||||
@ -72,7 +72,7 @@ void CStack::localInit(BattleInfo * battleInfo)
|
||||
CArmedInstance * army = battle->battleGetArmyObject(side);
|
||||
assert(army);
|
||||
attachTo(*army);
|
||||
attachToSource(*type);
|
||||
attachToSource(*typeID.toCreature());
|
||||
}
|
||||
nativeTerrain = getNativeTerrain(); //save nativeTerrain in the variable on the battle start to avoid dead lock
|
||||
CUnitState::localInit(this); //it causes execution of the CStack::isOnNativeTerrain where nativeTerrain will be considered
|
||||
@ -164,8 +164,8 @@ std::string CStack::nodeName() const
|
||||
std::ostringstream oss;
|
||||
oss << owner.toString();
|
||||
oss << " battle stack [" << ID << "]: " << getCount() << " of ";
|
||||
if(type)
|
||||
oss << type->getNamePluralTextID();
|
||||
if(typeID.hasValue())
|
||||
oss << typeID.toEntity(VLC)->getNamePluralTextID();
|
||||
else
|
||||
oss << "[UNDEFINED TYPE]";
|
||||
|
||||
@ -304,7 +304,7 @@ bool CStack::isMeleeAttackPossible(const battle::Unit * attacker, const battle::
|
||||
|
||||
std::string CStack::getName() const
|
||||
{
|
||||
return (getCount() == 1) ? type->getNameSingularTranslated() : type->getNamePluralTranslated(); //War machines can't use base
|
||||
return (getCount() == 1) ? typeID.toEntity(VLC)->getNameSingularTranslated() : typeID.toEntity(VLC)->getNamePluralTranslated(); //War machines can't use base
|
||||
}
|
||||
|
||||
bool CStack::canBeHealed() const
|
||||
@ -326,7 +326,7 @@ bool CStack::isOnTerrain(TerrainId terrain) const
|
||||
|
||||
const CCreature * CStack::unitType() const
|
||||
{
|
||||
return type;
|
||||
return typeID.toCreature();
|
||||
}
|
||||
|
||||
int32_t CStack::unitBaseAmount() const
|
||||
@ -352,7 +352,7 @@ bool CStack::unitHasAmmoCart(const battle::Unit * unit) const
|
||||
const auto * ownerHero = battle->battleGetOwnerHero(unit);
|
||||
if(ownerHero && ownerHero->artifactsWorn.find(ArtifactPosition::MACH2) != ownerHero->artifactsWorn.end())
|
||||
{
|
||||
if(battle->battleGetOwnerHero(unit)->artifactsWorn.at(ArtifactPosition::MACH2).artifact->artType->getId() == ArtifactID::AMMO_CART)
|
||||
if(battle->battleGetOwnerHero(unit)->artifactsWorn.at(ArtifactPosition::MACH2).artifact->getTypeId() == ArtifactID::AMMO_CART)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ class DLL_LINKAGE CStack : public CBonusSystemNode, public battle::CUnitState, p
|
||||
{
|
||||
private:
|
||||
ui32 ID = -1; //unique ID of stack
|
||||
const CCreature * type = nullptr;
|
||||
CreatureID typeID;
|
||||
TerrainId nativeTerrain; //tmp variable to save native terrain value on battle init
|
||||
ui32 baseAmount = -1;
|
||||
|
||||
@ -98,7 +98,7 @@ public:
|
||||
//stackState is not serialized here
|
||||
assert(isIndependentNode());
|
||||
h & static_cast<CBonusSystemNode&>(*this);
|
||||
h & type;
|
||||
h & typeID;
|
||||
h & ID;
|
||||
h & baseAmount;
|
||||
h & owner;
|
||||
@ -133,7 +133,7 @@ public:
|
||||
else if(!army || extSlot == SlotID() || !army->hasStackAtSlot(extSlot))
|
||||
{
|
||||
base = nullptr;
|
||||
logGlobal->warn("%s doesn't have a base stack!", type->getNameSingularTranslated());
|
||||
logGlobal->warn("%s doesn't have a base stack!", typeID.toEntity(VLC)->getNameSingularTranslated());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -72,7 +72,7 @@ void CPrivilegedInfoCallback::getFreeTiles(std::vector<int3> & tiles) const
|
||||
for (int yd = 0; yd < gs->map->height; yd++)
|
||||
{
|
||||
tinfo = getTile(int3 (xd,yd,zd));
|
||||
if (tinfo->terType->isLand() && tinfo->terType->isPassable() && !tinfo->blocked) //land and free
|
||||
if (tinfo->isLand() && tinfo->getTerrain()->isPassable() && !tinfo->blocked()) //land and free
|
||||
tiles.emplace_back(xd, yd, zd);
|
||||
}
|
||||
}
|
||||
@ -149,14 +149,14 @@ void CPrivilegedInfoCallback::getAllTiles(std::unordered_set<int3> & tiles, std:
|
||||
}
|
||||
}
|
||||
|
||||
void CPrivilegedInfoCallback::pickAllowedArtsSet(std::vector<const CArtifact *> & out, vstd::RNG & rand)
|
||||
void CPrivilegedInfoCallback::pickAllowedArtsSet(std::vector<ArtifactID> & out, vstd::RNG & rand)
|
||||
{
|
||||
for (int j = 0; j < 3 ; j++)
|
||||
out.push_back(gameState()->pickRandomArtifact(rand, CArtifact::ART_TREASURE).toArtifact());
|
||||
out.push_back(gameState()->pickRandomArtifact(rand, CArtifact::ART_TREASURE));
|
||||
for (int j = 0; j < 3 ; j++)
|
||||
out.push_back(gameState()->pickRandomArtifact(rand, CArtifact::ART_MINOR).toArtifact());
|
||||
out.push_back(gameState()->pickRandomArtifact(rand, CArtifact::ART_MINOR));
|
||||
|
||||
out.push_back(gameState()->pickRandomArtifact(rand, CArtifact::ART_MAJOR).toArtifact());
|
||||
out.push_back(gameState()->pickRandomArtifact(rand, CArtifact::ART_MAJOR));
|
||||
}
|
||||
|
||||
void CPrivilegedInfoCallback::getAllowedSpells(std::vector<SpellID> & out, std::optional<ui16> level)
|
||||
|
@ -75,7 +75,7 @@ public:
|
||||
void getAllTiles(std::unordered_set<int3> &tiles, std::optional<PlayerColor> player, int level, std::function<bool(const TerrainTile *)> filter) const;
|
||||
|
||||
//gives 3 treasures, 3 minors, 1 major -> used by Black Market and Artifact Merchant
|
||||
void pickAllowedArtsSet(std::vector<const CArtifact *> & out, vstd::RNG & rand);
|
||||
void pickAllowedArtsSet(std::vector<ArtifactID> & out, vstd::RNG & rand);
|
||||
void getAllowedSpells(std::vector<SpellID> &out, std::optional<ui16> level = std::nullopt);
|
||||
|
||||
void saveCommonState(CSaveFile &out) const; //stores GS and VLC
|
||||
|
@ -303,7 +303,7 @@ BattleInfo * BattleInfo::setupBattle(const int3 & tile, TerrainId terrain, const
|
||||
|
||||
if(nullptr != warMachineArt && hex.isValid())
|
||||
{
|
||||
CreatureID cre = warMachineArt->artType->getWarMachine();
|
||||
CreatureID cre = warMachineArt->getType()->getWarMachine();
|
||||
|
||||
if(cre != CreatureID::NONE)
|
||||
currentBattle->generateNewStack(currentBattle->nextUnitId(), CStackBasicDescriptor(cre, 1), side, SlotID::WAR_MACHINES_SLOT, hex);
|
||||
|
@ -75,7 +75,7 @@ static const CCreature * retrieveCreature(const CBonusSystemNode *node)
|
||||
default:
|
||||
const CStackInstance * csi = retrieveStackInstance(node);
|
||||
if(csi)
|
||||
return csi->type;
|
||||
return csi->getCreature();
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
@ -103,25 +103,25 @@ ILimiter::EDecision CCreatureTypeLimiter::limit(const BonusLimitationContext &co
|
||||
if(!c)
|
||||
return ILimiter::EDecision::DISCARD;
|
||||
|
||||
auto accept = c->getId() == creature->getId() || (includeUpgrades && creature->isMyUpgrade(c));
|
||||
auto accept = c->getId() == creatureID || (includeUpgrades && creatureID.toCreature()->isMyUpgrade(c));
|
||||
return accept ? ILimiter::EDecision::ACCEPT : ILimiter::EDecision::DISCARD;
|
||||
//drop bonus if it's not our creature and (we don`t check upgrades or its not our upgrade)
|
||||
}
|
||||
|
||||
CCreatureTypeLimiter::CCreatureTypeLimiter(const CCreature & creature_, bool IncludeUpgrades)
|
||||
: creature(&creature_), includeUpgrades(IncludeUpgrades)
|
||||
: creatureID(creature_.getId()), includeUpgrades(IncludeUpgrades)
|
||||
{
|
||||
}
|
||||
|
||||
void CCreatureTypeLimiter::setCreature(const CreatureID & id)
|
||||
{
|
||||
creature = id.toCreature();
|
||||
creatureID = id;
|
||||
}
|
||||
|
||||
std::string CCreatureTypeLimiter::toString() const
|
||||
{
|
||||
boost::format fmt("CCreatureTypeLimiter(creature=%s, includeUpgrades=%s)");
|
||||
fmt % creature->getJsonKey() % (includeUpgrades ? "true" : "false");
|
||||
fmt % creatureID.toEntity(VLC)->getJsonKey() % (includeUpgrades ? "true" : "false");
|
||||
return fmt.str();
|
||||
}
|
||||
|
||||
@ -130,7 +130,7 @@ JsonNode CCreatureTypeLimiter::toJsonNode() const
|
||||
JsonNode root;
|
||||
|
||||
root["type"].String() = "CREATURE_TYPE_LIMITER";
|
||||
root["parameters"].Vector().emplace_back(creature->getJsonKey());
|
||||
root["parameters"].Vector().emplace_back(creatureID.toEntity(VLC)->getJsonKey());
|
||||
root["parameters"].Vector().emplace_back(includeUpgrades);
|
||||
|
||||
return root;
|
||||
|
@ -94,7 +94,7 @@ public:
|
||||
class DLL_LINKAGE CCreatureTypeLimiter : public ILimiter //affect only stacks of given creature (and optionally it's upgrades)
|
||||
{
|
||||
public:
|
||||
const CCreature * creature = nullptr;
|
||||
CreatureID creatureID;
|
||||
bool includeUpgrades = false;
|
||||
|
||||
CCreatureTypeLimiter() = default;
|
||||
@ -108,7 +108,7 @@ public:
|
||||
template <typename Handler> void serialize(Handler &h)
|
||||
{
|
||||
h & static_cast<ILimiter&>(*this);
|
||||
h & creature;
|
||||
h & creatureID;
|
||||
h & includeUpgrades;
|
||||
}
|
||||
};
|
||||
|
@ -437,10 +437,10 @@ void CGameState::initGrailPosition()
|
||||
for(int y = BORDER_WIDTH; y < map->height - BORDER_WIDTH; y++)
|
||||
{
|
||||
const TerrainTile &t = map->getTile(int3(x, y, z));
|
||||
if(!t.blocked
|
||||
&& !t.visitable
|
||||
&& t.terType->isLand()
|
||||
&& t.terType->isPassable()
|
||||
if(!t.blocked()
|
||||
&& !t.visitable()
|
||||
&& t.isLand()
|
||||
&& t.getTerrain()->isPassable()
|
||||
&& (int)map->grailPos.dist2dSQ(int3(x, y, z)) <= (map->grailRadius * map->grailRadius))
|
||||
allowedPos.emplace_back(x, y, z);
|
||||
}
|
||||
@ -608,7 +608,7 @@ void CGameState::initHeroes()
|
||||
{
|
||||
assert(map->isInTheMap(hero->visitablePos()));
|
||||
const auto & tile = map->getTile(hero->visitablePos());
|
||||
if (tile.terType->isWater())
|
||||
if (tile.isWater())
|
||||
{
|
||||
auto handler = VLC->objtypeh->getHandlerFor(Obj::BOAT, hero->getBoatType().getNum());
|
||||
auto boat = dynamic_cast<CGBoat*>(handler->create(callback, nullptr));
|
||||
@ -1074,10 +1074,10 @@ BattleField CGameState::battleGetBattlefieldType(int3 tile, vstd::RNG & rand)
|
||||
if(map->isCoastalTile(tile)) //coastal tile is always ground
|
||||
return BattleField(*VLC->identifiers()->getIdentifier("core", "battlefield.sand_shore"));
|
||||
|
||||
if (t.terType->battleFields.empty())
|
||||
throw std::runtime_error("Failed to find battlefield for terrain " + t.terType->getJsonKey());
|
||||
if (t.getTerrain()->battleFields.empty())
|
||||
throw std::runtime_error("Failed to find battlefield for terrain " + t.getTerrain()->getJsonKey());
|
||||
|
||||
return BattleField(*RandomGeneratorUtil::nextItem(t.terType->battleFields, rand));
|
||||
return BattleField(*RandomGeneratorUtil::nextItem(t.getTerrain()->battleFields, rand));
|
||||
}
|
||||
|
||||
void CGameState::fillUpgradeInfo(const CArmedInstance *obj, SlotID stackPos, UpgradeInfo &out) const
|
||||
@ -1091,7 +1091,7 @@ void CGameState::fillUpgradeInfo(const CArmedInstance *obj, SlotID stackPos, Upg
|
||||
UpgradeInfo CGameState::fillUpgradeInfo(const CStackInstance &stack) const
|
||||
{
|
||||
UpgradeInfo ret;
|
||||
const CCreature *base = stack.type;
|
||||
const CCreature *base = stack.getCreature();
|
||||
|
||||
if (stack.armyObj->ID == Obj::HERO)
|
||||
{
|
||||
@ -1171,7 +1171,7 @@ std::vector<CGObjectInstance*> CGameState::guardingCreatures (int3 pos) const
|
||||
return guards;
|
||||
|
||||
const TerrainTile &posTile = map->getTile(pos);
|
||||
if (posTile.visitable)
|
||||
if (posTile.visitable())
|
||||
{
|
||||
for (CGObjectInstance* obj : posTile.visitableObjects)
|
||||
{
|
||||
@ -1190,7 +1190,7 @@ std::vector<CGObjectInstance*> CGameState::guardingCreatures (int3 pos) const
|
||||
if (map->isInTheMap(pos))
|
||||
{
|
||||
const auto & tile = map->getTile(pos);
|
||||
if (tile.visitable && (tile.isWater() == posTile.isWater()))
|
||||
if (tile.visitable() && (tile.isWater() == posTile.isWater()))
|
||||
{
|
||||
for (CGObjectInstance* obj : tile.visitableObjects)
|
||||
{
|
||||
@ -1571,7 +1571,7 @@ void CGameState::obtainPlayersStats(SThievesGuildInfo & tgi, int level)
|
||||
{
|
||||
for(const auto & it : elem->Slots())
|
||||
{
|
||||
CreatureID toCmp = it.second->type->getId(); //ID of creature we should compare with the best one
|
||||
CreatureID toCmp = it.second->getId(); //ID of creature we should compare with the best one
|
||||
if(bestCre == CreatureID::NONE || bestCre.toEntity(VLC)->getAIValue() < toCmp.toEntity(VLC)->getAIValue())
|
||||
{
|
||||
bestCre = toCmp;
|
||||
|
@ -137,18 +137,18 @@ void CGameStateCampaign::trimCrossoverHeroesParameters(const CampaignTravel & tr
|
||||
|
||||
ArtifactLocation al(hero.hero->id, artifactPosition);
|
||||
|
||||
bool takeable = travelOptions.artifactsKeptByHero.count(art->artType->getId());
|
||||
bool takeable = travelOptions.artifactsKeptByHero.count(art->getTypeId());
|
||||
bool locked = hero.hero->getSlot(al.slot)->locked;
|
||||
|
||||
if (!locked && takeable)
|
||||
{
|
||||
logGlobal->debug("Artifact %s from slot %d of hero %s will be transferred to next scenario", art->artType->getJsonKey(), al.slot.getNum(), hero.hero->getHeroTypeName());
|
||||
logGlobal->debug("Artifact %s from slot %d of hero %s will be transferred to next scenario", art->getType()->getJsonKey(), al.slot.getNum(), hero.hero->getHeroTypeName());
|
||||
hero.transferrableArtifacts.push_back(artifactPosition);
|
||||
}
|
||||
|
||||
if (!locked && !takeable)
|
||||
{
|
||||
logGlobal->debug("Removing artifact %s from slot %d of hero %s", art->artType->getJsonKey(), al.slot.getNum(), hero.hero->getHeroTypeName());
|
||||
logGlobal->debug("Removing artifact %s from slot %d of hero %s", art->getType()->getJsonKey(), al.slot.getNum(), hero.hero->getHeroTypeName());
|
||||
gameState->map->removeArtifactInstance(*hero.hero, al.slot);
|
||||
return true;
|
||||
}
|
||||
@ -424,12 +424,12 @@ void CGameStateCampaign::transferMissingArtifacts(const CampaignTravel & travelO
|
||||
{
|
||||
auto * artifact = donorHero->getArt(artLocation);
|
||||
|
||||
logGlobal->debug("Removing artifact %s from slot %d of hero %s for transfer", artifact->artType->getJsonKey(), artLocation.getNum(), donorHero->getHeroTypeName());
|
||||
logGlobal->debug("Removing artifact %s from slot %d of hero %s for transfer", artifact->getType()->getJsonKey(), artLocation.getNum(), donorHero->getHeroTypeName());
|
||||
gameState->map->removeArtifactInstance(*donorHero, artLocation);
|
||||
|
||||
if (receiver)
|
||||
{
|
||||
logGlobal->debug("Granting artifact %s to hero %s for transfer", artifact->artType->getJsonKey(), receiver->getHeroTypeName());
|
||||
logGlobal->debug("Granting artifact %s to hero %s for transfer", artifact->getType()->getJsonKey(), receiver->getHeroTypeName());
|
||||
|
||||
const auto slot = ArtifactUtils::getArtAnyPosition(receiver, artifact->getTypeId());
|
||||
if(ArtifactUtils::isSlotEquipment(slot) || ArtifactUtils::isSlotBackpack(slot))
|
||||
|
@ -291,7 +291,7 @@ float Statistic::getMapExploredRatio(const CGameState * gs, PlayerColor player)
|
||||
{
|
||||
TerrainTile tile = gs->map->getTile(int3(x, y, layer));
|
||||
|
||||
if(tile.blocked && (!tile.visitable))
|
||||
if(tile.blocked() && !tile.visitable())
|
||||
continue;
|
||||
|
||||
if(gs->isVisible(int3(x, y, layer), player))
|
||||
|
@ -26,7 +26,7 @@ ArmyDescriptor::ArmyDescriptor(const CArmedInstance *army, bool detailed)
|
||||
if(detailed)
|
||||
(*this)[elem.first] = *elem.second;
|
||||
else
|
||||
(*this)[elem.first] = CStackBasicDescriptor(elem.second->type, (int)elem.second->getQuantityID());
|
||||
(*this)[elem.first] = CStackBasicDescriptor(elem.second->getCreature(), (int)elem.second->getQuantityID());
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,12 +42,12 @@ int ArmyDescriptor::getStrength() const
|
||||
if(isDetailed)
|
||||
{
|
||||
for(const auto & elem : *this)
|
||||
ret += elem.second.type->getAIValue() * elem.second.count;
|
||||
ret += elem.second.getType()->getAIValue() * elem.second.count;
|
||||
}
|
||||
else
|
||||
{
|
||||
for(const auto & elem : *this)
|
||||
ret += elem.second.type->getAIValue() * CCreature::estimateCreatureCount(elem.second.count);
|
||||
ret += elem.second.getType()->getAIValue() * CCreature::estimateCreatureCount(elem.second.count);
|
||||
}
|
||||
return static_cast<int>(ret);
|
||||
}
|
||||
|
@ -485,13 +485,13 @@ VCMI_LIB_NAMESPACE_BEGIN
|
||||
else
|
||||
logMod->warn("Failed to select suitable random creature!");
|
||||
|
||||
stack.type = pickedCreature.toCreature();
|
||||
stack.setType(pickedCreature.toCreature());
|
||||
stack.count = loadValue(value, rng, variables);
|
||||
if (!value["upgradeChance"].isNull() && !stack.type->upgrades.empty())
|
||||
if (!value["upgradeChance"].isNull() && !stack.getCreature()->upgrades.empty())
|
||||
{
|
||||
if (int(value["upgradeChance"].Float()) > rng.nextInt(99)) // select random upgrade
|
||||
{
|
||||
stack.type = RandomGeneratorUtil::nextItem(stack.type->upgrades, rng)->toCreature();
|
||||
stack.setType(RandomGeneratorUtil::nextItem(stack.getCreature()->upgrades, rng)->toCreature());
|
||||
}
|
||||
}
|
||||
return stack;
|
||||
|
@ -101,7 +101,7 @@ void CTownInstanceConstructor::initializeObject(CGTownInstance * obj) const
|
||||
|
||||
void CTownInstanceConstructor::randomizeObject(CGTownInstance * object, vstd::RNG & rng) const
|
||||
{
|
||||
auto templ = getOverride(object->cb->getTile(object->pos)->terType->getId(), object);
|
||||
auto templ = getOverride(object->cb->getTile(object->pos)->getTerrainID(), object);
|
||||
if(templ)
|
||||
object->appearance = templ;
|
||||
}
|
||||
|
@ -102,7 +102,7 @@ void DwellingInstanceConstructor::randomizeObject(CGDwelling * dwelling, vstd::R
|
||||
JsonRandom::Variables emptyVariables;
|
||||
for(auto & stack : randomizer.loadCreatures(guards, rng, emptyVariables))
|
||||
{
|
||||
dwelling->putStack(SlotID(dwelling->stacksCount()), new CStackInstance(stack.type->getId(), stack.count));
|
||||
dwelling->putStack(SlotID(dwelling->stacksCount()), new CStackInstance(stack.getId(), stack.count));
|
||||
}
|
||||
}
|
||||
else //default condition - creatures are of level 5 or higher
|
||||
|
@ -94,7 +94,7 @@ void CBank::setConfig(const BankConfig & config)
|
||||
clearSlots(); // remove all stacks, if any
|
||||
|
||||
for(const auto & stack : config.guards)
|
||||
setCreature (SlotID(stacksCount()), stack.type->getId(), stack.count);
|
||||
setCreature (SlotID(stacksCount()), stack.getId(), stack.count);
|
||||
|
||||
daycounter = 1; //yes, 1 since "today" daycounter won't be incremented
|
||||
}
|
||||
@ -190,8 +190,8 @@ void CBank::doVisit(const CGHeroInstance * hero) const
|
||||
iw.text.appendLocalString(EMetaText::ADVOB_TXT, 34);
|
||||
const auto * strongest = boost::range::max_element(bankConfig->guards, [](const CStackBasicDescriptor & a, const CStackBasicDescriptor & b)
|
||||
{
|
||||
return a.type->getFightValue() < b.type->getFightValue();
|
||||
})->type;
|
||||
return a.getType()->getFightValue() < b.getType()->getFightValue();
|
||||
})->getType();
|
||||
|
||||
iw.text.replaceNamePlural(strongest->getId());
|
||||
iw.text.replaceRawString(loot.buildList());
|
||||
@ -244,7 +244,7 @@ void CBank::doVisit(const CGHeroInstance * hero) const
|
||||
CCreatureSet ourArmy;
|
||||
for(const auto & slot : bankConfig->creatures)
|
||||
{
|
||||
ourArmy.addToSlot(ourArmy.getSlotFor(slot.type->getId()), slot.type->getId(), slot.count);
|
||||
ourArmy.addToSlot(ourArmy.getSlotFor(slot.getId()), slot.getId(), slot.count);
|
||||
}
|
||||
|
||||
for(const auto & elem : ourArmy.Slots())
|
||||
|
@ -359,7 +359,7 @@ int CGCreature::takenAction(const CGHeroInstance *h, bool allowJoin) const
|
||||
for(const auto & elem : h->Slots())
|
||||
{
|
||||
bool isOurUpgrade = vstd::contains(getCreature()->upgrades, elem.second->getCreatureID());
|
||||
bool isOurDowngrade = vstd::contains(elem.second->type->upgrades, getCreatureID());
|
||||
bool isOurDowngrade = vstd::contains(elem.second->getCreature()->upgrades, getCreatureID());
|
||||
|
||||
if(isOurUpgrade || isOurDowngrade)
|
||||
count += elem.second->count;
|
||||
@ -480,7 +480,7 @@ void CGCreature::fight( const CGHeroInstance *h ) const
|
||||
if (containsUpgradedStack()) //upgrade
|
||||
{
|
||||
SlotID slotID = SlotID(static_cast<si32>(std::floor(static_cast<float>(stacks.size()) / 2.0f)));
|
||||
const auto & upgrades = getStack(slotID).type->upgrades;
|
||||
const auto & upgrades = getStack(slotID).getCreature()->upgrades;
|
||||
if(!upgrades.empty())
|
||||
{
|
||||
auto it = RandomGeneratorUtil::nextItem(upgrades, cb->gameState()->getRandomGenerator());
|
||||
@ -521,7 +521,7 @@ void CGCreature::battleFinished(const CGHeroInstance *hero, const BattleResult &
|
||||
const CCreature * cre = getCreature();
|
||||
for(i = stacks.begin(); i != stacks.end(); i++)
|
||||
{
|
||||
if(cre->isMyUpgrade(i->second->type))
|
||||
if(cre->isMyUpgrade(i->second->getCreature()))
|
||||
{
|
||||
cb->changeStackType(StackLocation(this, i->first), cre); //un-upgrade creatures
|
||||
}
|
||||
@ -536,7 +536,7 @@ void CGCreature::battleFinished(const CGHeroInstance *hero, const BattleResult &
|
||||
// TODO it's either overcomplicated (if we assume there'll be only one stack) or buggy (if we allow multiple stacks... but that'll also cause troubles elsewhere)
|
||||
i = stacks.end();
|
||||
i--;
|
||||
SlotID slot = getSlotFor(i->second->type);
|
||||
SlotID slot = getSlotFor(i->second->getCreature());
|
||||
if(slot == i->first) //no reason to move stack to its own slot
|
||||
break;
|
||||
else
|
||||
|
@ -102,16 +102,16 @@ ui32 CGHeroInstance::getTileMovementCost(const TerrainTile & dest, const Terrain
|
||||
int64_t ret = GameConstants::BASE_MOVEMENT_COST;
|
||||
|
||||
//if there is road both on dest and src tiles - use src road movement cost
|
||||
if(dest.roadType->getId() != Road::NO_ROAD && from.roadType->getId() != Road::NO_ROAD)
|
||||
if(dest.hasRoad() && from.hasRoad())
|
||||
{
|
||||
ret = from.roadType->movementCost;
|
||||
ret = from.getRoad()->movementCost;
|
||||
}
|
||||
else if(ti->nativeTerrain != from.terType->getId() &&//the terrain is not native
|
||||
else if(ti->nativeTerrain != from.getTerrainID() &&//the terrain is not native
|
||||
ti->nativeTerrain != ETerrainId::ANY_TERRAIN && //no special creature bonus
|
||||
!ti->hasBonusOfType(BonusType::NO_TERRAIN_PENALTY, BonusSubtypeID(from.terType->getId()))) //no special movement bonus
|
||||
!ti->hasBonusOfType(BonusType::NO_TERRAIN_PENALTY, BonusSubtypeID(from.getTerrainID()))) //no special movement bonus
|
||||
{
|
||||
|
||||
ret = VLC->terrainTypeHandler->getById(from.terType->getId())->moveCost;
|
||||
ret = VLC->terrainTypeHandler->getById(from.getTerrainID())->moveCost;
|
||||
ret -= ti->valOfBonuses(BonusType::ROUGH_TERRAIN_DISCOUNT);
|
||||
if(ret < GameConstants::BASE_MOVEMENT_COST)
|
||||
ret = GameConstants::BASE_MOVEMENT_COST;
|
||||
@ -1806,14 +1806,14 @@ bool CGHeroInstance::isMissionCritical() const
|
||||
|
||||
void CGHeroInstance::fillUpgradeInfo(UpgradeInfo & info, const CStackInstance &stack) const
|
||||
{
|
||||
TConstBonusListPtr lista = getBonuses(Selector::typeSubtype(BonusType::SPECIAL_UPGRADE, BonusSubtypeID(stack.type->getId())));
|
||||
TConstBonusListPtr lista = getBonuses(Selector::typeSubtype(BonusType::SPECIAL_UPGRADE, BonusSubtypeID(stack.getId())));
|
||||
for(const auto & it : *lista)
|
||||
{
|
||||
auto nid = CreatureID(it->additionalInfo[0]);
|
||||
if (nid != stack.type->getId()) //in very specific case the upgrade is available by default (?)
|
||||
if (nid != stack.getId()) //in very specific case the upgrade is available by default (?)
|
||||
{
|
||||
info.newID.push_back(nid);
|
||||
info.cost.push_back(nid.toCreature()->getFullRecruitCost() - stack.type->getFullRecruitCost());
|
||||
info.cost.push_back(nid.toCreature()->getFullRecruitCost() - stack.getType()->getFullRecruitCost());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -359,8 +359,11 @@ public:
|
||||
h & boat;
|
||||
if (h.version < Handler::Version::REMOVE_TOWN_PTR)
|
||||
{
|
||||
CHero * type = nullptr;
|
||||
h & type;
|
||||
HeroTypeID type;
|
||||
bool isNull = false;
|
||||
h & isNull;
|
||||
if(!isNull)
|
||||
h & type;
|
||||
}
|
||||
h & commander;
|
||||
h & visitedObjects;
|
||||
|
@ -88,11 +88,8 @@ std::vector<TradeItemBuy> CGBlackMarket::availableItemsIds(EMarketMode mode) con
|
||||
case EMarketMode::RESOURCE_ARTIFACT:
|
||||
{
|
||||
std::vector<TradeItemBuy> ret;
|
||||
for(const CArtifact *a : artifacts)
|
||||
if(a)
|
||||
ret.push_back(a->getId());
|
||||
else
|
||||
ret.push_back(ArtifactID{});
|
||||
for(const auto & a : artifacts)
|
||||
ret.push_back(a);
|
||||
return ret;
|
||||
}
|
||||
default:
|
||||
|
@ -70,7 +70,7 @@ class DLL_LINKAGE CGBlackMarket : public CGMarket
|
||||
public:
|
||||
using CGMarket::CGMarket;
|
||||
|
||||
std::vector<const CArtifact *> artifacts; //available artifacts
|
||||
std::vector<ArtifactID> artifacts; //available artifacts
|
||||
|
||||
void newTurn(vstd::RNG & rand) const override; //reset artifacts for black market every month
|
||||
std::vector<TradeItemBuy> availableItemsIds(EMarketMode mode) const override;
|
||||
|
@ -128,13 +128,13 @@ void CGObjectInstance::setType(MapObjectID newID, MapObjectSubID newSubID)
|
||||
cb->gameState()->map->removeBlockVisTiles(this, true);
|
||||
auto handler = VLC->objtypeh->getHandlerFor(newID, newSubID);
|
||||
|
||||
if(!handler->getTemplates(tile.terType->getId()).empty())
|
||||
if(!handler->getTemplates(tile.getTerrainID()).empty())
|
||||
{
|
||||
appearance = handler->getTemplates(tile.terType->getId())[0];
|
||||
appearance = handler->getTemplates(tile.getTerrainID())[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
logGlobal->warn("Object %d:%d at %s has no templates suitable for terrain %s", newID, newSubID, visitablePos().toString(), tile.terType->getNameTranslated());
|
||||
logGlobal->warn("Object %d:%d at %s has no templates suitable for terrain %s", newID, newSubID, visitablePos().toString(), tile.getTerrain()->getNameTranslated());
|
||||
appearance = handler->getTemplates()[0]; // get at least some appearance since alternative is crash
|
||||
}
|
||||
|
||||
|
@ -670,11 +670,9 @@ std::vector<TradeItemBuy> CGTownInstance::availableItemsIds(EMarketMode mode) co
|
||||
if(mode == EMarketMode::RESOURCE_ARTIFACT)
|
||||
{
|
||||
std::vector<TradeItemBuy> ret;
|
||||
for(const CArtifact *a : cb->gameState()->map->townMerchantArtifacts)
|
||||
if(a)
|
||||
ret.push_back(a->getId());
|
||||
else
|
||||
ret.push_back(ArtifactID{});
|
||||
for(const ArtifactID a : cb->gameState()->map->townMerchantArtifacts)
|
||||
ret.push_back(a);
|
||||
|
||||
return ret;
|
||||
}
|
||||
else if ( mode == EMarketMode::RESOURCE_SKILL )
|
||||
@ -692,7 +690,7 @@ ObjectInstanceID CGTownInstance::getObjInstanceID() const
|
||||
|
||||
void CGTownInstance::updateAppearance()
|
||||
{
|
||||
auto terrain = cb->gameState()->getTile(visitablePos())->terType->getId();
|
||||
auto terrain = cb->gameState()->getTile(visitablePos())->getTerrainID();
|
||||
//FIXME: not the best way to do this
|
||||
auto app = getObjectHandler()->getOverride(terrain, this);
|
||||
if (app)
|
||||
@ -1227,14 +1225,14 @@ void CGTownInstance::fillUpgradeInfo(UpgradeInfo & info, const CStackInstance &s
|
||||
{
|
||||
for(const CGTownInstance::TCreaturesSet::value_type & dwelling : creatures)
|
||||
{
|
||||
if (vstd::contains(dwelling.second, stack.type->getId())) //Dwelling with our creature
|
||||
if (vstd::contains(dwelling.second, stack.getId())) //Dwelling with our creature
|
||||
{
|
||||
for(const auto & upgrID : dwelling.second)
|
||||
{
|
||||
if(vstd::contains(stack.type->upgrades, upgrID)) //possible upgrade
|
||||
if(vstd::contains(stack.getCreature()->upgrades, upgrID)) //possible upgrade
|
||||
{
|
||||
info.newID.push_back(upgrID);
|
||||
info.cost.push_back(upgrID.toCreature()->getFullRecruitCost() - stack.type->getFullRecruitCost());
|
||||
info.cost.push_back(upgrID.toCreature()->getFullRecruitCost() - stack.getType()->getFullRecruitCost());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -114,19 +114,11 @@ public:
|
||||
|
||||
if (h.version < Handler::Version::REMOVE_TOWN_PTR)
|
||||
{
|
||||
CTown * town = nullptr;
|
||||
|
||||
if (h.saving)
|
||||
{
|
||||
CFaction * faction = town ? town->faction : nullptr;
|
||||
FactionID faction;
|
||||
bool isNull = false;
|
||||
h & isNull;
|
||||
if (!isNull)
|
||||
h & faction;
|
||||
}
|
||||
else
|
||||
{
|
||||
CFaction * faction = nullptr;
|
||||
h & faction;
|
||||
town = faction ? faction->town : nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
h & townAndVis;
|
||||
|
@ -110,7 +110,7 @@ bool CQuest::checkMissionArmy(const CQuest * q, const CCreatureSet * army)
|
||||
{
|
||||
for(count = 0, it = army->Slots().begin(); it != army->Slots().end(); ++it)
|
||||
{
|
||||
if(it->second->type == cre->type)
|
||||
if(it->second->getType() == cre->getType())
|
||||
{
|
||||
count += it->second->count;
|
||||
slotsCount++;
|
||||
|
@ -90,10 +90,10 @@ int3 IBoatGenerator::bestLocation() const
|
||||
if(!tile)
|
||||
continue; // tile not visible / outside the map
|
||||
|
||||
if(!tile->terType->isWater())
|
||||
if(!tile->isWater())
|
||||
continue;
|
||||
|
||||
if (tile->blocked)
|
||||
if (tile->blocked())
|
||||
{
|
||||
bool hasBoat = false;
|
||||
for (auto const * object : tile->blockingObjects)
|
||||
|
@ -775,13 +775,13 @@ void CGArtifact::initObj(vstd::RNG & rand)
|
||||
storedArtifact = ArtifactUtils::createArtifact(ArtifactID());
|
||||
cb->gameState()->map->addNewArtifactInstance(storedArtifact);
|
||||
}
|
||||
if(!storedArtifact->artType)
|
||||
if(!storedArtifact->getType())
|
||||
storedArtifact->setType(getArtifact().toArtifact());
|
||||
}
|
||||
if(ID == Obj::SPELL_SCROLL)
|
||||
subID = 1;
|
||||
|
||||
assert(storedArtifact->artType);
|
||||
assert(storedArtifact->getType());
|
||||
assert(!storedArtifact->getParentNodes().empty());
|
||||
|
||||
//assert(storedArtifact->artType->id == subID); //this does not stop desync
|
||||
@ -825,7 +825,7 @@ void CGArtifact::onHeroVisit(const CGHeroInstance * h) const
|
||||
iw.type = EInfoWindowMode::AUTO;
|
||||
iw.player = h->tempOwner;
|
||||
|
||||
if(storedArtifact->artType->canBePutAt(h))
|
||||
if(storedArtifact->getType()->canBePutAt(h))
|
||||
{
|
||||
switch (ID.toEnum())
|
||||
{
|
||||
@ -1152,7 +1152,7 @@ void CGSirens::onHeroVisit( const CGHeroInstance * h ) const
|
||||
if(drown)
|
||||
{
|
||||
cb->changeStackCount(StackLocation(h, i->first), -drown);
|
||||
xp += drown * i->second->type->getMaxHealth();
|
||||
xp += drown * i->second->getType()->getMaxHealth();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1318,7 +1318,7 @@ void HillFort::onHeroVisit(const CGHeroInstance * h) const
|
||||
|
||||
void HillFort::fillUpgradeInfo(UpgradeInfo & info, const CStackInstance &stack) const
|
||||
{
|
||||
int32_t level = stack.type->getLevel();
|
||||
int32_t level = stack.getType()->getLevel();
|
||||
int32_t index = std::clamp<int32_t>(level - 1, 0, upgradeCostPercentage.size() - 1);
|
||||
|
||||
int costModifier = upgradeCostPercentage[index];
|
||||
@ -1326,10 +1326,10 @@ void HillFort::fillUpgradeInfo(UpgradeInfo & info, const CStackInstance &stack)
|
||||
if (costModifier < 0)
|
||||
return; // upgrade not allowed
|
||||
|
||||
for(const auto & nid : stack.type->upgrades)
|
||||
for(const auto & nid : stack.getCreature()->upgrades)
|
||||
{
|
||||
info.newID.push_back(nid);
|
||||
info.cost.push_back((nid.toCreature()->getFullRecruitCost() - stack.type->getFullRecruitCost()) * costModifier / 100);
|
||||
info.cost.push_back((nid.toCreature()->getFullRecruitCost() - stack.getType()->getFullRecruitCost()) * costModifier / 100);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -344,12 +344,12 @@ std::string CDrawRiversOperation::getLabel() const
|
||||
|
||||
void CDrawRoadsOperation::executeTile(TerrainTile & tile)
|
||||
{
|
||||
tile.roadType = const_cast<RoadType*>(VLC->roadTypeHandler->getByIndex(roadType.getNum()));
|
||||
tile.roadType = roadType;
|
||||
}
|
||||
|
||||
void CDrawRiversOperation::executeTile(TerrainTile & tile)
|
||||
{
|
||||
tile.riverType = const_cast<RiverType*>(VLC->riverTypeHandler->getByIndex(riverType.getNum()));
|
||||
tile.riverType = riverType;
|
||||
}
|
||||
|
||||
bool CDrawRoadsOperation::canApplyPattern(const LinePattern & pattern) const
|
||||
@ -364,22 +364,22 @@ bool CDrawRiversOperation::canApplyPattern(const LinePattern & pattern) const
|
||||
|
||||
bool CDrawRoadsOperation::needUpdateTile(const TerrainTile & tile) const
|
||||
{
|
||||
return tile.roadType->getId() != Road::NO_ROAD;
|
||||
return tile.hasRoad();
|
||||
}
|
||||
|
||||
bool CDrawRiversOperation::needUpdateTile(const TerrainTile & tile) const
|
||||
{
|
||||
return tile.riverType->getId() != River::NO_RIVER;
|
||||
return tile.hasRiver();
|
||||
}
|
||||
|
||||
bool CDrawRoadsOperation::tileHasSomething(const int3& pos) const
|
||||
{
|
||||
return map->getTile(pos).roadType->getId() != Road::NO_ROAD;
|
||||
return map->getTile(pos).hasRoad();
|
||||
}
|
||||
|
||||
bool CDrawRiversOperation::tileHasSomething(const int3& pos) const
|
||||
{
|
||||
return map->getTile(pos).riverType->getId() != River::NO_RIVER;
|
||||
return map->getTile(pos).hasRiver();
|
||||
}
|
||||
|
||||
void CDrawRoadsOperation::updateTile(TerrainTile & tile, const LinePattern & pattern, const int flip)
|
||||
|
@ -131,32 +131,29 @@ void CCastleEvent::serializeJson(JsonSerializeFormat & handler)
|
||||
}
|
||||
|
||||
TerrainTile::TerrainTile():
|
||||
terType(nullptr),
|
||||
riverType(VLC->riverTypeHandler->getById(River::NO_RIVER)),
|
||||
roadType(VLC->roadTypeHandler->getById(Road::NO_ROAD)),
|
||||
riverType(River::NO_RIVER),
|
||||
roadType(Road::NO_ROAD),
|
||||
terView(0),
|
||||
riverDir(0),
|
||||
roadDir(0),
|
||||
extTileFlags(0),
|
||||
visitable(false),
|
||||
blocked(false)
|
||||
extTileFlags(0)
|
||||
{
|
||||
}
|
||||
|
||||
bool TerrainTile::entrableTerrain(const TerrainTile * from) const
|
||||
{
|
||||
return entrableTerrain(from ? from->terType->isLand() : true, from ? from->terType->isWater() : true);
|
||||
return entrableTerrain(from ? from->isLand() : true, from ? from->isWater() : true);
|
||||
}
|
||||
|
||||
bool TerrainTile::entrableTerrain(bool allowLand, bool allowSea) const
|
||||
{
|
||||
return terType->isPassable()
|
||||
&& ((allowSea && terType->isWater()) || (allowLand && terType->isLand()));
|
||||
return getTerrain()->isPassable()
|
||||
&& ((allowSea && isWater()) || (allowLand && isLand()));
|
||||
}
|
||||
|
||||
bool TerrainTile::isClear(const TerrainTile * from) const
|
||||
{
|
||||
return entrableTerrain(from) && !blocked;
|
||||
return entrableTerrain(from) && !blocked();
|
||||
}
|
||||
|
||||
Obj TerrainTile::topVisitableId(bool excludeTop) const
|
||||
@ -177,7 +174,7 @@ CGObjectInstance * TerrainTile::topVisitableObj(bool excludeTop) const
|
||||
|
||||
EDiggingStatus TerrainTile::getDiggingStatus(const bool excludeTop) const
|
||||
{
|
||||
if(terType->isWater() || !terType->isPassable())
|
||||
if(isWater() || !getTerrain()->isPassable())
|
||||
return EDiggingStatus::WRONG_TERRAIN;
|
||||
|
||||
int allowedBlocked = excludeTop ? 1 : 0;
|
||||
@ -194,9 +191,65 @@ bool TerrainTile::hasFavorableWinds() const
|
||||
|
||||
bool TerrainTile::isWater() const
|
||||
{
|
||||
return terType->isWater();
|
||||
return getTerrain()->isWater();
|
||||
}
|
||||
|
||||
bool TerrainTile::isLand() const
|
||||
{
|
||||
return getTerrain()->isLand();
|
||||
}
|
||||
|
||||
bool TerrainTile::visitable() const
|
||||
{
|
||||
return !visitableObjects.empty();
|
||||
}
|
||||
|
||||
bool TerrainTile::blocked() const
|
||||
{
|
||||
return !blockingObjects.empty();
|
||||
}
|
||||
|
||||
bool TerrainTile::hasRiver() const
|
||||
{
|
||||
return getRiverID() != RiverId::NO_RIVER;
|
||||
}
|
||||
|
||||
bool TerrainTile::hasRoad() const
|
||||
{
|
||||
return getRoadID() != RoadId::NO_ROAD;
|
||||
}
|
||||
|
||||
const TerrainType * TerrainTile::getTerrain() const
|
||||
{
|
||||
return terrainType.toEntity(VLC);
|
||||
}
|
||||
|
||||
const RiverType * TerrainTile::getRiver() const
|
||||
{
|
||||
return riverType.toEntity(VLC);
|
||||
}
|
||||
|
||||
const RoadType * TerrainTile::getRoad() const
|
||||
{
|
||||
return roadType.toEntity(VLC);
|
||||
}
|
||||
|
||||
TerrainId TerrainTile::getTerrainID() const
|
||||
{
|
||||
return terrainType;
|
||||
}
|
||||
|
||||
RiverId TerrainTile::getRiverID() const
|
||||
{
|
||||
return riverType;
|
||||
}
|
||||
|
||||
RoadId TerrainTile::getRoadID() const
|
||||
{
|
||||
return roadType;
|
||||
}
|
||||
|
||||
|
||||
CMap::CMap(IGameCallback * cb)
|
||||
: GameCallbackHolder(cb)
|
||||
, checksum(0)
|
||||
@ -243,15 +296,10 @@ void CMap::removeBlockVisTiles(CGObjectInstance * obj, bool total)
|
||||
{
|
||||
TerrainTile & curt = terrain[zVal][xVal][yVal];
|
||||
if(total || obj->visitableAt(int3(xVal, yVal, zVal)))
|
||||
{
|
||||
curt.visitableObjects -= obj;
|
||||
curt.visitable = curt.visitableObjects.size();
|
||||
}
|
||||
|
||||
if(total || obj->blockingAt(int3(xVal, yVal, zVal)))
|
||||
{
|
||||
curt.blockingObjects -= obj;
|
||||
curt.blocked = curt.blockingObjects.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -270,15 +318,10 @@ void CMap::addBlockVisTiles(CGObjectInstance * obj)
|
||||
{
|
||||
TerrainTile & curt = terrain[zVal][xVal][yVal];
|
||||
if(obj->visitableAt(int3(xVal, yVal, zVal)))
|
||||
{
|
||||
curt.visitableObjects.push_back(obj);
|
||||
curt.visitable = true;
|
||||
}
|
||||
|
||||
if(obj->blockingAt(int3(xVal, yVal, zVal)))
|
||||
{
|
||||
curt.blockingObjects.push_back(obj);
|
||||
curt.blocked = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -381,7 +424,7 @@ int3 CMap::guardingCreaturePosition (int3 pos) const
|
||||
if (!isInTheMap(pos))
|
||||
return int3(-1, -1, -1);
|
||||
const TerrainTile &posTile = getTile(pos);
|
||||
if (posTile.visitable)
|
||||
if (posTile.visitable())
|
||||
{
|
||||
for (CGObjectInstance* obj : posTile.visitableObjects)
|
||||
{
|
||||
@ -401,7 +444,7 @@ int3 CMap::guardingCreaturePosition (int3 pos) const
|
||||
if (isInTheMap(pos))
|
||||
{
|
||||
const auto & tile = getTile(pos);
|
||||
if (tile.visitable && (tile.isWater() == water))
|
||||
if (tile.visitable() && (tile.isWater() == water))
|
||||
{
|
||||
for (CGObjectInstance* obj : tile.visitableObjects)
|
||||
{
|
||||
|
@ -180,7 +180,7 @@ public:
|
||||
ui8 obeliskCount = 0; //how many obelisks are on map
|
||||
std::map<TeamID, ui8> obelisksVisited; //map: team_id => how many obelisks has been visited
|
||||
|
||||
std::vector<const CArtifact *> townMerchantArtifacts;
|
||||
std::vector<ArtifactID> townMerchantArtifacts;
|
||||
std::vector<TradeItemBuy> townUniversitySkills;
|
||||
|
||||
void overrideGameSettings(const JsonNode & input);
|
||||
|
@ -104,20 +104,33 @@ struct DLL_LINKAGE TerrainTile
|
||||
Obj topVisitableId(bool excludeTop = false) const;
|
||||
CGObjectInstance * topVisitableObj(bool excludeTop = false) const;
|
||||
bool isWater() const;
|
||||
EDiggingStatus getDiggingStatus(const bool excludeTop = true) const;
|
||||
bool isLand() const;
|
||||
EDiggingStatus getDiggingStatus(bool excludeTop = true) const;
|
||||
bool hasFavorableWinds() const;
|
||||
|
||||
const TerrainType * terType;
|
||||
const RiverType * riverType;
|
||||
const RoadType * roadType;
|
||||
bool visitable() const;
|
||||
bool blocked() const;
|
||||
|
||||
const TerrainType * getTerrain() const;
|
||||
const RiverType * getRiver() const;
|
||||
const RoadType * getRoad() const;
|
||||
|
||||
TerrainId getTerrainID() const;
|
||||
RiverId getRiverID() const;
|
||||
RoadId getRoadID() const;
|
||||
|
||||
bool hasRiver() const;
|
||||
bool hasRoad() const;
|
||||
|
||||
TerrainId terrainType;
|
||||
RiverId riverType;
|
||||
RoadId roadType;
|
||||
ui8 terView;
|
||||
ui8 riverDir;
|
||||
ui8 roadDir;
|
||||
/// first two bits - how to rotate terrain graphic (next two - river graphic, next two - road);
|
||||
/// 7th bit - whether tile is coastal (allows disembarking if land or block movement if water); 8th bit - Favorable Winds effect
|
||||
ui8 extTileFlags;
|
||||
bool visitable;
|
||||
bool blocked;
|
||||
|
||||
std::vector<CGObjectInstance *> visitableObjects;
|
||||
std::vector<CGObjectInstance *> blockingObjects;
|
||||
@ -125,15 +138,50 @@ struct DLL_LINKAGE TerrainTile
|
||||
template <typename Handler>
|
||||
void serialize(Handler & h)
|
||||
{
|
||||
h & terType;
|
||||
if (h.version >= Handler::Version::REMOVE_VLC_POINTERS)
|
||||
{
|
||||
h & terrainType;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool isNull = false;
|
||||
h & isNull;
|
||||
if (isNull)
|
||||
h & terrainType;
|
||||
}
|
||||
h & terrainType;
|
||||
h & terView;
|
||||
h & riverType;
|
||||
if (h.version >= Handler::Version::REMOVE_VLC_POINTERS)
|
||||
{
|
||||
h & riverType;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool isNull = false;
|
||||
h & isNull;
|
||||
if (isNull)
|
||||
h & riverType;
|
||||
}
|
||||
h & riverDir;
|
||||
h & roadType;
|
||||
if (h.version >= Handler::Version::REMOVE_VLC_POINTERS)
|
||||
{
|
||||
h & roadType;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool isNull = false;
|
||||
h & isNull;
|
||||
if (isNull)
|
||||
h & roadType;
|
||||
}
|
||||
h & roadDir;
|
||||
h & extTileFlags;
|
||||
h & visitable;
|
||||
h & blocked;
|
||||
if (h.version < Handler::Version::REMOVE_VLC_POINTERS)
|
||||
{
|
||||
bool unused = false;
|
||||
h & unused;
|
||||
h & unused;
|
||||
}
|
||||
h & visitableObjects;
|
||||
h & blockingObjects;
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ void CDrawTerrainOperation::execute()
|
||||
for(const auto & pos : terrainSel.getSelectedItems())
|
||||
{
|
||||
auto & tile = map->getTile(pos);
|
||||
tile.terType = const_cast<TerrainType*>(VLC->terrainTypeHandler->getById(terType));
|
||||
tile.terrainType = terType;
|
||||
invalidateTerrainViews(pos);
|
||||
}
|
||||
|
||||
@ -137,7 +137,7 @@ void CDrawTerrainOperation::updateTerrainTypes()
|
||||
auto tiles = getInvalidTiles(centerPos);
|
||||
auto updateTerrainType = [&](const int3& pos)
|
||||
{
|
||||
map->getTile(pos).terType = centerTile.terType;
|
||||
map->getTile(pos).terrainType = centerTile.terrainType;
|
||||
positions.insert(pos);
|
||||
invalidateTerrainViews(pos);
|
||||
//logGlobal->debug("Set additional terrain tile at pos '%s' to type '%s'", pos, centerTile.terType);
|
||||
@ -161,10 +161,10 @@ void CDrawTerrainOperation::updateTerrainTypes()
|
||||
rect.forEach([&](const int3& posToTest)
|
||||
{
|
||||
auto & terrainTile = map->getTile(posToTest);
|
||||
if(centerTile.terType->getId() != terrainTile.terType->getId())
|
||||
if(centerTile.getTerrain() != terrainTile.getTerrain())
|
||||
{
|
||||
const auto * formerTerType = terrainTile.terType;
|
||||
terrainTile.terType = centerTile.terType;
|
||||
const auto formerTerType = terrainTile.terrainType;
|
||||
terrainTile.terrainType = centerTile.terrainType;
|
||||
auto testTile = getInvalidTiles(posToTest);
|
||||
|
||||
int nativeTilesCntNorm = testTile.nativeTiles.empty() ? std::numeric_limits<int>::max() : static_cast<int>(testTile.nativeTiles.size());
|
||||
@ -221,7 +221,7 @@ void CDrawTerrainOperation::updateTerrainTypes()
|
||||
suitableTiles.insert(posToTest);
|
||||
}
|
||||
|
||||
terrainTile.terType = formerTerType;
|
||||
terrainTile.terrainType = formerTerType;
|
||||
}
|
||||
});
|
||||
|
||||
@ -264,7 +264,7 @@ void CDrawTerrainOperation::updateTerrainViews()
|
||||
{
|
||||
for(const auto & pos : invalidatedTerViews)
|
||||
{
|
||||
const auto & patterns = VLC->terviewh->getTerrainViewPatterns(map->getTile(pos).terType->getId());
|
||||
const auto & patterns = VLC->terviewh->getTerrainViewPatterns(map->getTile(pos).getTerrainID());
|
||||
|
||||
// Detect a pattern which fits best
|
||||
int bestPattern = -1;
|
||||
@ -340,7 +340,7 @@ CDrawTerrainOperation::ValidationResult CDrawTerrainOperation::validateTerrainVi
|
||||
|
||||
CDrawTerrainOperation::ValidationResult CDrawTerrainOperation::validateTerrainViewInner(const int3& pos, const TerrainViewPattern& pattern, int recDepth) const
|
||||
{
|
||||
const auto * centerTerType = map->getTile(pos).terType;
|
||||
const auto * centerTerType = map->getTile(pos).getTerrain();
|
||||
int totalPoints = 0;
|
||||
std::string transitionReplacement;
|
||||
|
||||
@ -372,24 +372,24 @@ CDrawTerrainOperation::ValidationResult CDrawTerrainOperation::validateTerrainVi
|
||||
}
|
||||
else if(widthTooHigh)
|
||||
{
|
||||
terType = map->getTile(int3(currentPos.x - 1, currentPos.y, currentPos.z)).terType;
|
||||
terType = map->getTile(int3(currentPos.x - 1, currentPos.y, currentPos.z)).getTerrain();
|
||||
}
|
||||
else if(heightTooHigh)
|
||||
{
|
||||
terType = map->getTile(int3(currentPos.x, currentPos.y - 1, currentPos.z)).terType;
|
||||
terType = map->getTile(int3(currentPos.x, currentPos.y - 1, currentPos.z)).getTerrain();
|
||||
}
|
||||
else if(widthTooLess)
|
||||
{
|
||||
terType = map->getTile(int3(currentPos.x + 1, currentPos.y, currentPos.z)).terType;
|
||||
terType = map->getTile(int3(currentPos.x + 1, currentPos.y, currentPos.z)).getTerrain();
|
||||
}
|
||||
else if(heightTooLess)
|
||||
{
|
||||
terType = map->getTile(int3(currentPos.x, currentPos.y + 1, currentPos.z)).terType;
|
||||
terType = map->getTile(int3(currentPos.x, currentPos.y + 1, currentPos.z)).getTerrain();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
terType = map->getTile(currentPos).terType;
|
||||
terType = map->getTile(currentPos).getTerrain();
|
||||
if(terType != centerTerType && (terType->isPassable() || centerTerType->isPassable()))
|
||||
{
|
||||
isAlien = true;
|
||||
@ -509,13 +509,13 @@ CDrawTerrainOperation::InvalidTiles CDrawTerrainOperation::getInvalidTiles(const
|
||||
{
|
||||
//TODO: this is very expensive function for RMG, needs optimization
|
||||
InvalidTiles tiles;
|
||||
const auto * centerTerType = map->getTile(centerPos).terType;
|
||||
const auto * centerTerType = map->getTile(centerPos).getTerrain();
|
||||
auto rect = extendTileAround(centerPos);
|
||||
rect.forEach([&](const int3& pos)
|
||||
{
|
||||
if(map->isInTheMap(pos))
|
||||
{
|
||||
const auto * terType = map->getTile(pos).terType;
|
||||
const auto * terType = map->getTile(pos).getTerrain();
|
||||
auto valid = validateTerrainView(pos, VLC->terviewh->getTerrainTypePatternById("n1")).result;
|
||||
|
||||
// Special validity check for rock & water
|
||||
|
@ -356,7 +356,7 @@ void CTerrainViewPatternUtils::printDebuggingInfoAboutTile(const CMap * map, con
|
||||
{
|
||||
auto debugTile = map->getTile(debugPos);
|
||||
|
||||
std::string terType = debugTile.terType->shortIdentifier;
|
||||
std::string terType = debugTile.getTerrain()->shortIdentifier;
|
||||
line += terType;
|
||||
line.insert(line.end(), PADDED_LENGTH - terType.size(), ' ');
|
||||
}
|
||||
|
@ -988,17 +988,13 @@ void CMapLoaderH3M::readTerrain()
|
||||
for(pos.x = 0; pos.x < map->width; pos.x++)
|
||||
{
|
||||
auto & tile = map->getTile(pos);
|
||||
tile.terType = VLC->terrainTypeHandler->getById(reader->readTerrain());
|
||||
tile.terrainType = reader->readTerrain();
|
||||
tile.terView = reader->readUInt8();
|
||||
tile.riverType = VLC->riverTypeHandler->getById(reader->readRiver());
|
||||
tile.riverType = reader->readRiver();
|
||||
tile.riverDir = reader->readUInt8();
|
||||
tile.roadType = VLC->roadTypeHandler->getById(reader->readRoad());
|
||||
tile.roadType = reader->readRoad();
|
||||
tile.roadDir = reader->readUInt8();
|
||||
tile.extTileFlags = reader->readUInt8();
|
||||
tile.blocked = !tile.terType->isPassable();
|
||||
tile.visitable = false;
|
||||
|
||||
assert(tile.terType->getId() != ETerrainId::NONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2120,7 +2116,7 @@ EQuestMission CMapLoaderH3M::readQuest(IQuestObject * guard, const int3 & positi
|
||||
guard->quest->mission.creatures.resize(typeNumber);
|
||||
for(size_t hh = 0; hh < typeNumber; ++hh)
|
||||
{
|
||||
guard->quest->mission.creatures[hh].type = reader->readCreature().toCreature();
|
||||
guard->quest->mission.creatures[hh].setType(reader->readCreature().toCreature());
|
||||
guard->quest->mission.creatures[hh].count = reader->readUInt16();
|
||||
}
|
||||
break;
|
||||
|
@ -260,34 +260,34 @@ CMapFormatJson::CMapFormatJson():
|
||||
|
||||
}
|
||||
|
||||
TerrainType * CMapFormatJson::getTerrainByCode(const std::string & code)
|
||||
TerrainId CMapFormatJson::getTerrainByCode(const std::string & code)
|
||||
{
|
||||
for(const auto & object : VLC->terrainTypeHandler->objects)
|
||||
{
|
||||
if(object->shortIdentifier == code)
|
||||
return const_cast<TerrainType *>(object.get());
|
||||
return object->getId();
|
||||
}
|
||||
return nullptr;
|
||||
return TerrainId::NONE;
|
||||
}
|
||||
|
||||
RiverType * CMapFormatJson::getRiverByCode(const std::string & code)
|
||||
RiverId CMapFormatJson::getRiverByCode(const std::string & code)
|
||||
{
|
||||
for(const auto & object : VLC->riverTypeHandler->objects)
|
||||
{
|
||||
if (object->shortIdentifier == code)
|
||||
return const_cast<RiverType *>(object.get());
|
||||
return object->getId();
|
||||
}
|
||||
return nullptr;
|
||||
return RiverId::NO_RIVER;
|
||||
}
|
||||
|
||||
RoadType * CMapFormatJson::getRoadByCode(const std::string & code)
|
||||
RoadId CMapFormatJson::getRoadByCode(const std::string & code)
|
||||
{
|
||||
for(const auto & object : VLC->roadTypeHandler->objects)
|
||||
{
|
||||
if (object->shortIdentifier == code)
|
||||
return const_cast<RoadType *>(object.get());
|
||||
return object->getId();
|
||||
}
|
||||
return nullptr;
|
||||
return RoadId::NO_ROAD;
|
||||
}
|
||||
|
||||
void CMapFormatJson::serializeAllowedFactions(JsonSerializeFormat & handler, std::set<FactionID> & value) const
|
||||
@ -890,7 +890,7 @@ void CMapLoaderJson::readTerrainTile(const std::string & src, TerrainTile & tile
|
||||
using namespace TerrainDetail;
|
||||
{//terrain type
|
||||
const std::string typeCode = src.substr(0, 2);
|
||||
tile.terType = getTerrainByCode(typeCode);
|
||||
tile.terrainType = getTerrainByCode(typeCode);
|
||||
}
|
||||
int startPos = 2; //0+typeCode fixed length
|
||||
{//terrain view
|
||||
@ -920,7 +920,7 @@ void CMapLoaderJson::readTerrainTile(const std::string & src, TerrainTile & tile
|
||||
tile.roadType = getRoadByCode(typeCode);
|
||||
if(!tile.roadType) //it's not a road, it's a river
|
||||
{
|
||||
tile.roadType = VLC->roadTypeHandler->getById(Road::NO_ROAD);
|
||||
tile.roadType = Road::NO_ROAD;
|
||||
tile.riverType = getRiverByCode(typeCode);
|
||||
hasRoad = false;
|
||||
if(!tile.riverType)
|
||||
@ -1254,13 +1254,13 @@ std::string CMapSaverJson::writeTerrainTile(const TerrainTile & tile)
|
||||
out.setf(std::ios::dec, std::ios::basefield);
|
||||
out.unsetf(std::ios::showbase);
|
||||
|
||||
out << tile.terType->shortIdentifier << static_cast<int>(tile.terView) << flipCodes[tile.extTileFlags % 4];
|
||||
out << tile.getTerrain()->shortIdentifier << static_cast<int>(tile.terView) << flipCodes[tile.extTileFlags % 4];
|
||||
|
||||
if(tile.roadType->getId() != Road::NO_ROAD)
|
||||
out << tile.roadType->shortIdentifier << static_cast<int>(tile.roadDir) << flipCodes[(tile.extTileFlags >> 4) % 4];
|
||||
if(tile.hasRoad())
|
||||
out << tile.getRoad()->shortIdentifier << static_cast<int>(tile.roadDir) << flipCodes[(tile.extTileFlags >> 4) % 4];
|
||||
|
||||
if(tile.riverType->getId() != River::NO_RIVER)
|
||||
out << tile.riverType->shortIdentifier << static_cast<int>(tile.riverDir) << flipCodes[(tile.extTileFlags >> 2) % 4];
|
||||
if(tile.hasRiver())
|
||||
out << tile.getRiver()->shortIdentifier << static_cast<int>(tile.riverDir) << flipCodes[(tile.extTileFlags >> 2) % 4];
|
||||
|
||||
return out.str();
|
||||
}
|
||||
|
@ -60,9 +60,9 @@ protected:
|
||||
|
||||
CMapFormatJson();
|
||||
|
||||
static TerrainType * getTerrainByCode(const std::string & code);
|
||||
static RiverType * getRiverByCode(const std::string & code);
|
||||
static RoadType * getRoadByCode(const std::string & code);
|
||||
static TerrainId getTerrainByCode(const std::string & code);
|
||||
static RiverId getRiverByCode(const std::string & code);
|
||||
static RoadId getRoadByCode(const std::string & code);
|
||||
|
||||
void serializeAllowedFactions(JsonSerializeFormat & handler, std::set<FactionID> & value) const;
|
||||
|
||||
|
@ -1208,7 +1208,7 @@ void RemoveObject::applyGs(CGameState *gs)
|
||||
beatenHero->tempOwner = PlayerColor::NEUTRAL; //no one owns beaten hero
|
||||
vstd::erase_if(beatenHero->artifactsInBackpack, [](const ArtSlotInfo& asi)
|
||||
{
|
||||
return asi.artifact->artType->getId() == ArtifactID::GRAIL;
|
||||
return asi.artifact->getTypeId() == ArtifactID::GRAIL;
|
||||
});
|
||||
|
||||
if(beatenHero->visitedTown)
|
||||
@ -1733,7 +1733,7 @@ void BulkEraseArtifacts::applyGs(CGameState *gs)
|
||||
const auto slotInfo = artSet->getSlot(slot);
|
||||
if(slotInfo->locked)
|
||||
{
|
||||
logGlobal->debug("Erasing locked artifact: %s", slotInfo->artifact->artType->getNameTranslated());
|
||||
logGlobal->debug("Erasing locked artifact: %s", slotInfo->artifact->getType()->getNameTranslated());
|
||||
DisassembledArtifact dis;
|
||||
dis.al.artHolder = artHolder;
|
||||
|
||||
@ -1747,12 +1747,12 @@ void BulkEraseArtifacts::applyGs(CGameState *gs)
|
||||
}
|
||||
}
|
||||
assert((dis.al.slot != ArtifactPosition::PRE_FIRST) && "Failed to determine the assembly this locked artifact belongs to");
|
||||
logGlobal->debug("Found the corresponding assembly: %s", artSet->getArt(dis.al.slot)->artType->getNameTranslated());
|
||||
logGlobal->debug("Found the corresponding assembly: %s", artSet->getArt(dis.al.slot)->getType()->getNameTranslated());
|
||||
dis.applyGs(gs);
|
||||
}
|
||||
else
|
||||
{
|
||||
logGlobal->debug("Erasing artifact %s", slotInfo->artifact->artType->getNameTranslated());
|
||||
logGlobal->debug("Erasing artifact %s", slotInfo->artifact->getType()->getNameTranslated());
|
||||
}
|
||||
gs->map->removeArtifactInstance(*artSet, slot);
|
||||
}
|
||||
@ -1840,8 +1840,8 @@ void AssembledArtifact::applyGs(CGameState *gs)
|
||||
break;
|
||||
}
|
||||
|
||||
if(!vstd::contains(combinedArt->artType->getPossibleSlots().at(hero->bearerType()), al.slot)
|
||||
&& vstd::contains(combinedArt->artType->getPossibleSlots().at(hero->bearerType()), slot))
|
||||
if(!vstd::contains(combinedArt->getType()->getPossibleSlots().at(hero->bearerType()), al.slot)
|
||||
&& vstd::contains(combinedArt->getType()->getPossibleSlots().at(hero->bearerType()), slot))
|
||||
al.slot = slot;
|
||||
}
|
||||
else
|
||||
@ -1857,7 +1857,7 @@ void AssembledArtifact::applyGs(CGameState *gs)
|
||||
const auto constituentInstance = hero->getArt(slot);
|
||||
gs->map->removeArtifactInstance(*hero, slot);
|
||||
|
||||
if(!combinedArt->artType->isFused())
|
||||
if(!combinedArt->getType()->isFused())
|
||||
{
|
||||
if(ArtifactUtils::isSlotEquipment(al.slot) && slot != al.slot)
|
||||
combinedArt->addPart(constituentInstance, slot);
|
||||
|
@ -819,7 +819,7 @@ struct DLL_LINKAGE SetAvailableArtifacts : public CPackForClient
|
||||
|
||||
//two variants: id < 0: set artifact pool for Artifact Merchants in towns; id >= 0: set pool for adv. map Black Market (id is the id of Black Market instance then)
|
||||
ObjectInstanceID id;
|
||||
std::vector<const CArtifact *> arts;
|
||||
std::vector<ArtifactID> arts;
|
||||
|
||||
void visitTyped(ICPackVisitor & visitor) override;
|
||||
|
||||
|
@ -596,25 +596,19 @@ void CPathfinderHelper::getNeighbours(
|
||||
continue;
|
||||
|
||||
const TerrainTile & destTile = map->getTile(destCoord);
|
||||
if(!destTile.terType->isPassable())
|
||||
if(!destTile.getTerrain()->isPassable())
|
||||
continue;
|
||||
|
||||
// //we cannot visit things from blocked tiles
|
||||
// if(srcTile.blocked && !srcTile.visitable && destTile.visitable && srcTile.blockingObjects.front()->ID != HEROI_TYPE)
|
||||
// {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
/// Following condition let us avoid diagonal movement over coast when sailing
|
||||
if(srcTile.terType->isWater() && limitCoastSailing && destTile.terType->isWater() && dir.x && dir.y) //diagonal move through water
|
||||
if(srcTile.isWater() && limitCoastSailing && destTile.isWater() && dir.x && dir.y) //diagonal move through water
|
||||
{
|
||||
const int3 horizontalNeighbour = srcCoord + int3{dir.x, 0, 0};
|
||||
const int3 verticalNeighbour = srcCoord + int3{0, dir.y, 0};
|
||||
if(map->getTile(horizontalNeighbour).terType->isLand() || map->getTile(verticalNeighbour).terType->isLand())
|
||||
if(map->getTile(horizontalNeighbour).isLand() || map->getTile(verticalNeighbour).isLand())
|
||||
continue;
|
||||
}
|
||||
|
||||
if(indeterminate(onLand) || onLand == destTile.terType->isLand())
|
||||
if(indeterminate(onLand) || onLand == destTile.isLand())
|
||||
{
|
||||
vec.push_back(destCoord);
|
||||
}
|
||||
@ -662,13 +656,13 @@ int CPathfinderHelper::getMovementCost(
|
||||
|
||||
bool isSailLayer;
|
||||
if(indeterminate(isDstSailLayer))
|
||||
isSailLayer = hero->boat && hero->boat->layer == EPathfindingLayer::SAIL && dt->terType->isWater();
|
||||
isSailLayer = hero->boat && hero->boat->layer == EPathfindingLayer::SAIL && dt->isWater();
|
||||
else
|
||||
isSailLayer = static_cast<bool>(isDstSailLayer);
|
||||
|
||||
bool isWaterLayer;
|
||||
if(indeterminate(isDstWaterLayer))
|
||||
isWaterLayer = ((hero->boat && hero->boat->layer == EPathfindingLayer::WATER) || ti->hasBonusOfType(BonusType::WATER_WALKING)) && dt->terType->isWater();
|
||||
isWaterLayer = ((hero->boat && hero->boat->layer == EPathfindingLayer::WATER) || ti->hasBonusOfType(BonusType::WATER_WALKING)) && dt->isWater();
|
||||
else
|
||||
isWaterLayer = static_cast<bool>(isDstWaterLayer);
|
||||
|
||||
@ -703,7 +697,7 @@ int CPathfinderHelper::getMovementCost(
|
||||
{
|
||||
NeighbourTilesVector vec;
|
||||
|
||||
getNeighbours(*dt, dst, vec, ct->terType->isLand(), true);
|
||||
getNeighbours(*dt, dst, vec, ct->isLand(), true);
|
||||
for(const auto & elem : vec)
|
||||
{
|
||||
int fcost = getMovementCost(dst, elem, nullptr, nullptr, left, false);
|
||||
|
@ -41,7 +41,7 @@ void NodeStorage::initialize(const PathfinderOptions & options, const CGameState
|
||||
for(pos.y=0; pos.y < sizes.y; ++pos.y)
|
||||
{
|
||||
const TerrainTile & tile = gs->map->getTile(pos);
|
||||
if(tile.terType->isWater())
|
||||
if(tile.isWater())
|
||||
{
|
||||
resetTile(pos, ELayer::SAIL, PathfinderUtil::evaluateAccessibility<ELayer::SAIL>(pos, tile, fow, player, gs));
|
||||
if(useFlying)
|
||||
@ -49,7 +49,7 @@ void NodeStorage::initialize(const PathfinderOptions & options, const CGameState
|
||||
if(useWaterWalking)
|
||||
resetTile(pos, ELayer::WATER, PathfinderUtil::evaluateAccessibility<ELayer::WATER>(pos, tile, fow, player, gs));
|
||||
}
|
||||
if(tile.terType->isLand())
|
||||
if(tile.isLand())
|
||||
{
|
||||
resetTile(pos, ELayer::LAND, PathfinderUtil::evaluateAccessibility<ELayer::LAND>(pos, tile, fow, player, gs));
|
||||
if(useFlying)
|
||||
|
@ -32,7 +32,7 @@ namespace PathfinderUtil
|
||||
{
|
||||
case ELayer::LAND:
|
||||
case ELayer::SAIL:
|
||||
if(tinfo.visitable)
|
||||
if(tinfo.visitable())
|
||||
{
|
||||
if(tinfo.visitableObjects.front()->ID == Obj::SANCTUARY && tinfo.visitableObjects.back()->ID == Obj::HERO && tinfo.visitableObjects.back()->tempOwner != player) //non-owned hero stands on Sanctuary
|
||||
{
|
||||
@ -51,7 +51,7 @@ namespace PathfinderUtil
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(tinfo.blocked)
|
||||
else if(tinfo.blocked())
|
||||
{
|
||||
return EPathAccessibility::BLOCKED;
|
||||
}
|
||||
@ -64,7 +64,7 @@ namespace PathfinderUtil
|
||||
break;
|
||||
|
||||
case ELayer::WATER:
|
||||
if(tinfo.blocked || tinfo.terType->isLand())
|
||||
if(tinfo.blocked() || tinfo.isLand())
|
||||
return EPathAccessibility::BLOCKED;
|
||||
|
||||
break;
|
||||
|
@ -380,7 +380,7 @@ void LayerTransitionRule::process(
|
||||
|
||||
case EPathfindingLayer::SAIL:
|
||||
// have to disembark first before visiting objects on land
|
||||
if (destination.tile->visitable)
|
||||
if (destination.tile->visitable())
|
||||
destination.blocked = true;
|
||||
|
||||
//can disembark only on accessible tiles or tiles guarded by nearby monster
|
||||
@ -397,7 +397,7 @@ void LayerTransitionRule::process(
|
||||
if (destination.node->accessible == EPathAccessibility::BLOCKVIS)
|
||||
{
|
||||
// Can't visit 'blockvisit' objects on coast if hero will end up on water terrain
|
||||
if (source.tile->blocked || !destination.tile->entrableTerrain(source.tile))
|
||||
if (source.tile->blocked() || !destination.tile->entrableTerrain(source.tile))
|
||||
destination.blocked = true;
|
||||
}
|
||||
}
|
||||
|
@ -63,16 +63,16 @@ void Rewardable::Interface::grantRewardBeforeLevelup(const Rewardable::VisitInfo
|
||||
const auto functor = [&props](const TerrainTile * tile)
|
||||
{
|
||||
int score = 0;
|
||||
if (tile->terType->isSurface())
|
||||
if (tile->getTerrain()->isSurface())
|
||||
score += props.scoreSurface;
|
||||
|
||||
if (tile->terType->isUnderground())
|
||||
if (tile->getTerrain()->isUnderground())
|
||||
score += props.scoreSubterra;
|
||||
|
||||
if (tile->terType->isWater())
|
||||
if (tile->getTerrain()->isWater())
|
||||
score += props.scoreWater;
|
||||
|
||||
if (tile->terType->isRock())
|
||||
if (tile->getTerrain()->isRock())
|
||||
score += props.scoreRock;
|
||||
|
||||
return score > 0;
|
||||
@ -185,7 +185,7 @@ void Rewardable::Interface::grantRewardAfterLevelup(const Rewardable::VisitInfo
|
||||
|
||||
for(const auto & change : info.reward.creaturesChange)
|
||||
{
|
||||
if (heroStack->type->getId() == change.first)
|
||||
if (heroStack->getId() == change.first)
|
||||
{
|
||||
StackLocation location(hero, slot.first);
|
||||
cb->changeStackType(location, change.second.toCreature());
|
||||
@ -199,7 +199,7 @@ void Rewardable::Interface::grantRewardAfterLevelup(const Rewardable::VisitInfo
|
||||
{
|
||||
CCreatureSet creatures;
|
||||
for(const auto & crea : info.reward.creatures)
|
||||
creatures.addToSlot(creatures.getFreeSlot(), new CStackInstance(crea.type, crea.count));
|
||||
creatures.addToSlot(creatures.getFreeSlot(), new CStackInstance(crea.getCreature(), crea.count));
|
||||
|
||||
if(auto * army = dynamic_cast<const CArmedInstance*>(this)) //TODO: to fix that, CArmedInstance must be split on map instance part and interface part
|
||||
cb->giveCreatures(army, hero, creatures, false);
|
||||
|
@ -84,7 +84,7 @@ bool Rewardable::Limiter::heroAllowed(const CGHeroInstance * hero) const
|
||||
for(const auto & slot : hero->Slots())
|
||||
{
|
||||
const CStackInstance * heroStack = slot.second;
|
||||
if (heroStack->type == reqStack.type)
|
||||
if (heroStack->getType() == reqStack.getType())
|
||||
count += heroStack->count;
|
||||
}
|
||||
if (count < reqStack.count) //not enough creatures of this kind
|
||||
@ -233,7 +233,7 @@ void Rewardable::Limiter::loadComponents(std::vector<Component> & comps,
|
||||
comps.emplace_back(ComponentType::SPELL, entry);
|
||||
|
||||
for(const auto & entry : creatures)
|
||||
comps.emplace_back(ComponentType::CREATURE, entry.type->getId(), entry.count);
|
||||
comps.emplace_back(ComponentType::CREATURE, entry.getId(), entry.count);
|
||||
|
||||
for(const auto & entry : players)
|
||||
comps.emplace_back(ComponentType::FLAG, entry);
|
||||
|
@ -121,7 +121,7 @@ void Rewardable::Reward::loadComponents(std::vector<Component> & comps, const CG
|
||||
}
|
||||
|
||||
for(const auto & entry : creatures)
|
||||
comps.emplace_back(ComponentType::CREATURE, entry.type->getId(), entry.count);
|
||||
comps.emplace_back(ComponentType::CREATURE, entry.getId(), entry.count);
|
||||
|
||||
for (size_t i=0; i<resources.size(); i++)
|
||||
{
|
||||
|
@ -484,7 +484,7 @@ void Object::Instance::finalize(RmgMap & map, vstd::RNG & rng)
|
||||
//If no specific template was defined for this object, select any matching
|
||||
if (!dObject.appearance)
|
||||
{
|
||||
const auto * terrainType = map.getTile(getPosition(true)).terType;
|
||||
const auto * terrainType = map.getTile(getPosition(true)).getTerrain();
|
||||
auto templates = dObject.getObjectHandler()->getTemplates(terrainType->getId());
|
||||
if (templates.empty())
|
||||
{
|
||||
|
@ -149,7 +149,7 @@ void RoadPlacer::drawRoads(bool secondary)
|
||||
//Do not draw roads on underground rock or water
|
||||
roads.erase_if([this](const int3& pos) -> bool
|
||||
{
|
||||
const auto* terrain = map.getTile(pos).terType;
|
||||
const auto* terrain = map.getTile(pos).getTerrain();
|
||||
return !terrain->isPassable() || !terrain->isLand();
|
||||
});
|
||||
|
||||
|
@ -72,7 +72,7 @@ void RockFiller::init()
|
||||
|
||||
char RockFiller::dump(const int3 & t)
|
||||
{
|
||||
if(!map.getTile(t).terType->isPassable())
|
||||
if(!map.getTile(t).getTerrain()->isPassable())
|
||||
{
|
||||
return zone.area()->contains(t) ? 'R' : 'E';
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ void RockPlacer::postProcess()
|
||||
//Finally mark rock tiles as occupied, spawn no obstacles there
|
||||
rockArea = zone.area()->getSubarea([this](const int3 & t)
|
||||
{
|
||||
return !map.getTile(t).terType->isPassable();
|
||||
return !map.getTile(t).getTerrain()->isPassable();
|
||||
});
|
||||
|
||||
// Do not place rock on roads
|
||||
@ -96,7 +96,7 @@ void RockPlacer::init()
|
||||
|
||||
char RockPlacer::dump(const int3 & t)
|
||||
{
|
||||
if(!map.getTile(t).terType->isPassable())
|
||||
if(!map.getTile(t).getTerrain()->isPassable())
|
||||
{
|
||||
return zone.area()->contains(t) ? 'R' : 'E';
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ void WaterProxy::process()
|
||||
for([[maybe_unused]] const auto & t : area->getTilesVector())
|
||||
{
|
||||
assert(map.isOnMap(t));
|
||||
assert(map.getTile(t).terType->getId() == zone.getTerrainType());
|
||||
assert(map.getTile(t).getTerrainID() == zone.getTerrainType());
|
||||
}
|
||||
|
||||
// FIXME: Possible deadlock for 2 zones
|
||||
@ -66,7 +66,7 @@ void WaterProxy::process()
|
||||
auto secondAreaPossible = z.second->areaPossible();
|
||||
for(const auto & t : secondArea->getTilesVector())
|
||||
{
|
||||
if(map.getTile(t).terType->getId() == zone.getTerrainType())
|
||||
if(map.getTile(t).getTerrainID() == zone.getTerrainType())
|
||||
{
|
||||
secondArea->erase(t);
|
||||
secondAreaPossible->erase(t);
|
||||
|
@ -235,25 +235,6 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
loadPointerImpl(data);
|
||||
}
|
||||
|
||||
template < typename T, typename std::enable_if_t < std::is_base_of_v<Entity, std::remove_pointer_t<T>>, int > = 0 >
|
||||
void loadPointerImpl(T &data)
|
||||
{
|
||||
using DataType = std::remove_pointer_t<T>;
|
||||
|
||||
typename DataType::IdentifierType index;
|
||||
load(index);
|
||||
|
||||
auto * constEntity = index.toEntity(VLC);
|
||||
auto * constData = dynamic_cast<const DataType *>(constEntity);
|
||||
data = const_cast<DataType *>(constData);
|
||||
}
|
||||
|
||||
template < typename T, typename std::enable_if_t < !std::is_base_of_v<Entity, std::remove_pointer_t<T>>, int > = 0 >
|
||||
void loadPointerImpl(T &data)
|
||||
{
|
||||
if(reader->smartVectorMembersSerialization)
|
||||
{
|
||||
typedef typename std::remove_const_t<typename std::remove_pointer_t<T>> TObjectType; //eg: const CGHeroInstance * => CGHeroInstance
|
||||
|
@ -186,19 +186,6 @@ public:
|
||||
if(data == nullptr)
|
||||
return;
|
||||
|
||||
savePointerImpl(data);
|
||||
}
|
||||
|
||||
template < typename T, typename std::enable_if_t < std::is_base_of_v<Entity, std::remove_pointer_t<T>>, int > = 0 >
|
||||
void savePointerImpl(const T &data)
|
||||
{
|
||||
auto index = data->getId();
|
||||
save(index);
|
||||
}
|
||||
|
||||
template < typename T, typename std::enable_if_t < !std::is_base_of_v<Entity, std::remove_pointer_t<T>>, int > = 0 >
|
||||
void savePointerImpl(const T &data)
|
||||
{
|
||||
typedef typename std::remove_const_t<typename std::remove_pointer_t<T>> TObjectType;
|
||||
|
||||
if(writer->smartVectorMembersSerialization)
|
||||
|
@ -65,6 +65,7 @@ enum class ESerializationVersion : int32_t
|
||||
LOCAL_PLAYER_STATE_DATA, // 866 - player state contains arbitrary client-side data
|
||||
REMOVE_TOWN_PTR, // 867 - removed pointer to CTown from CGTownInstance
|
||||
REMOVE_OBJECT_TYPENAME, // 868 - remove typename from CGObjectInstance
|
||||
REMOVE_VLC_POINTERS, // 869 removed remaining pointers to VLC entities
|
||||
|
||||
CURRENT = REMOVE_OBJECT_TYPENAME
|
||||
CURRENT = REMOVE_VLC_POINTERS
|
||||
};
|
||||
|
@ -374,7 +374,7 @@ bool DimensionDoorMechanics::canBeCastAtImpl(spells::Problem & problem, const CG
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dest->blocked)
|
||||
if (dest->blocked())
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -438,7 +438,7 @@ void MetaString::replaceName(const CreatureID & id, TQuantity count) //adds sing
|
||||
|
||||
void MetaString::replaceName(const CStackBasicDescriptor & stack)
|
||||
{
|
||||
replaceName(stack.type->getId(), stack.count);
|
||||
replaceName(stack.getId(), stack.count);
|
||||
}
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -169,7 +169,7 @@ void QuestWidget::obtainData()
|
||||
}
|
||||
for(auto & i : quest.mission.creatures)
|
||||
{
|
||||
int index = i.type->getIndex();
|
||||
int index = i.getType()->getIndex();
|
||||
ui->lCreatureId->setCurrentIndex(index);
|
||||
ui->lCreatureAmount->setValue(i.count);
|
||||
onCreatureAdd(ui->lCreatures, ui->lCreatureId, ui->lCreatureAmount);
|
||||
|
@ -459,7 +459,7 @@ void RewardsWidget::loadCurrentVisitInfo(int index)
|
||||
}
|
||||
for(auto & i : vinfo.reward.creatures)
|
||||
{
|
||||
int index = i.type->getIndex();
|
||||
int index = i.getType()->getIndex();
|
||||
ui->rCreatureId->setCurrentIndex(index);
|
||||
ui->rCreatureAmount->setValue(i.count);
|
||||
onCreatureAdd(ui->rCreatures, ui->rCreatureId, ui->rCreatureAmount);
|
||||
@ -527,7 +527,7 @@ void RewardsWidget::loadCurrentVisitInfo(int index)
|
||||
}
|
||||
for(auto & i : vinfo.limiter.creatures)
|
||||
{
|
||||
int index = i.type->getIndex();
|
||||
int index = i.getType()->getIndex();
|
||||
ui->lCreatureId->setCurrentIndex(index);
|
||||
ui->lCreatureAmount->setValue(i.count);
|
||||
onCreatureAdd(ui->lCreatures, ui->lCreatureId, ui->lCreatureAmount);
|
||||
|
@ -1123,7 +1123,7 @@ void MainWindow::on_actionUpdate_appearance_triggered()
|
||||
continue;
|
||||
}
|
||||
|
||||
auto * terrain = controller.map()->getTile(obj->visitablePos()).terType;
|
||||
auto * terrain = controller.map()->getTile(obj->visitablePos()).getTerrain();
|
||||
|
||||
if(handler->isStaticObject())
|
||||
{
|
||||
|
@ -429,10 +429,10 @@ void MapController::commitObstacleFill(int level)
|
||||
for(auto & t : selection)
|
||||
{
|
||||
auto tl = _map->getTile(t);
|
||||
if(tl.blocked || tl.visitable)
|
||||
if(tl.blocked() || tl.visitable())
|
||||
continue;
|
||||
|
||||
auto terrain = tl.terType->getId();
|
||||
auto terrain = tl.getTerrainID();
|
||||
_obstaclePainters[terrain]->addBlockedTile(t);
|
||||
}
|
||||
|
||||
|
@ -93,7 +93,7 @@ void MapHandler::drawTerrainTile(QPainter & painter, int x, int y, int z)
|
||||
auto & tinfo = map->getTile(int3(x, y, z));
|
||||
ui8 rotation = tinfo.extTileFlags % 4;
|
||||
|
||||
auto terrainName = tinfo.terType->getJsonKey();
|
||||
auto terrainName = tinfo.getTerrain()->getJsonKey();
|
||||
|
||||
if(terrainImages.at(terrainName).size() <= tinfo.terView)
|
||||
return;
|
||||
@ -110,7 +110,7 @@ void MapHandler::drawRoad(QPainter & painter, int x, int y, int z)
|
||||
|
||||
if(tinfoUpper && tinfoUpper->roadType)
|
||||
{
|
||||
auto roadName = tinfoUpper->roadType->getJsonKey();
|
||||
auto roadName = tinfoUpper->getRoad()->getJsonKey();
|
||||
QRect source(0, tileSize / 2, tileSize, tileSize / 2);
|
||||
ui8 rotation = (tinfoUpper->extTileFlags >> 4) % 4;
|
||||
bool hflip = (rotation == 1 || rotation == 3);
|
||||
@ -123,7 +123,7 @@ void MapHandler::drawRoad(QPainter & painter, int x, int y, int z)
|
||||
|
||||
if(tinfo.roadType) //print road from this tile
|
||||
{
|
||||
auto roadName = tinfo.roadType->getJsonKey();
|
||||
auto roadName = tinfo.getRoad()->getJsonKey();
|
||||
QRect source(0, 0, tileSize, tileSize / 2);
|
||||
ui8 rotation = (tinfo.extTileFlags >> 4) % 4;
|
||||
bool hflip = (rotation == 1 || rotation == 3);
|
||||
@ -139,11 +139,11 @@ void MapHandler::drawRiver(QPainter & painter, int x, int y, int z)
|
||||
{
|
||||
auto & tinfo = map->getTile(int3(x, y, z));
|
||||
|
||||
if(tinfo.riverType->getId() == River::NO_RIVER)
|
||||
if(!tinfo.hasRiver())
|
||||
return;
|
||||
|
||||
//TODO: use ui8 instead of string key
|
||||
auto riverName = tinfo.riverType->getJsonKey();
|
||||
auto riverName = tinfo.getRiver()->getJsonKey();
|
||||
|
||||
if(riverImages.at(riverName).size() <= tinfo.riverDir)
|
||||
return;
|
||||
@ -441,9 +441,9 @@ QRgb MapHandler::getTileColor(int x, int y, int z)
|
||||
|
||||
auto & tile = map->getTile(int3(x, y, z));
|
||||
|
||||
auto color = tile.terType->minimapUnblocked;
|
||||
if (tile.blocked && (!tile.visitable))
|
||||
color = tile.terType->minimapBlocked;
|
||||
auto color = tile.getTerrain()->minimapUnblocked;
|
||||
if (tile.blocked() && (!tile.visitable()))
|
||||
color = tile.getTerrain()->minimapBlocked;
|
||||
|
||||
return qRgb(color.r, color.g, color.b);
|
||||
}
|
||||
|
@ -364,7 +364,7 @@ void MapView::mousePressEvent(QMouseEvent *event)
|
||||
else if(controller->map()->getTile(tile).riverType
|
||||
&& controller->map()->getTile(tile).riverType != controller->map()->getTile(tilen).riverType)
|
||||
continue;
|
||||
else if(controller->map()->getTile(tile).terType != controller->map()->getTile(tilen).terType)
|
||||
else if(controller->map()->getTile(tile).terrainType != controller->map()->getTile(tilen).terrainType)
|
||||
continue;
|
||||
}
|
||||
if(event->button() == Qt::LeftButton && sc->selectionTerrainView.selection().count(tilen))
|
||||
|
@ -101,9 +101,9 @@ void PassabilityLayer::update()
|
||||
for(int i = 0; i < map->width; ++i)
|
||||
{
|
||||
auto tl = map->getTile(int3(i, j, scene->level));
|
||||
if(tl.blocked || tl.visitable)
|
||||
if(tl.blocked() || tl.visitable())
|
||||
{
|
||||
painter.fillRect(i * 32, j * 32, 31, 31, tl.visitable ? QColor(200, 200, 0, 64) : QColor(255, 0, 0, 64));
|
||||
painter.fillRect(i * 32, j * 32, 31, 31, tl.visitable() ? QColor(200, 200, 0, 64) : QColor(255, 0, 0, 64));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -830,9 +830,8 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, EMovementMode moveme
|
||||
|
||||
const bool embarking = !h->boat && objectToVisit && objectToVisit->ID == Obj::BOAT;
|
||||
const bool disembarking = h->boat
|
||||
&& t.terType->isLand()
|
||||
&& (dst == h->pos
|
||||
|| (h->boat->layer == EPathfindingLayer::SAIL && !t.blocked));
|
||||
&& t.isLand()
|
||||
&& (dst == h->pos || (h->boat->layer == EPathfindingLayer::SAIL && !t.blocked()));
|
||||
|
||||
//result structure for start - movement failed, no move points used
|
||||
TryMoveHero tmh;
|
||||
@ -850,9 +849,9 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, EMovementMode moveme
|
||||
const bool canWalkOnSea = pathfinderHelper->hasBonusOfType(BonusType::WATER_WALKING) || (h->boat && h->boat->layer == EPathfindingLayer::WATER);
|
||||
const int cost = pathfinderHelper->getMovementCost(h->visitablePos(), hmpos, nullptr, nullptr, h->movementPointsRemaining());
|
||||
|
||||
const bool movingOntoObstacle = t.blocked && !t.visitable;
|
||||
const bool movingOntoObstacle = t.blocked() && !t.visitable();
|
||||
const bool objectCoastVisitable = objectToVisit && objectToVisit->isCoastVisitable();
|
||||
const bool movingOntoWater = !h->boat && t.terType->isWater() && !objectCoastVisitable;
|
||||
const bool movingOntoWater = !h->boat && t.isWater() && !objectCoastVisitable;
|
||||
|
||||
const auto complainRet = [&](const std::string & message)
|
||||
{
|
||||
@ -876,14 +875,14 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, EMovementMode moveme
|
||||
|
||||
//it's a rock or blocked and not visitable tile
|
||||
//OR hero is on land and dest is water and (there is not present only one object - boat)
|
||||
if (!t.terType->isPassable() || (movingOntoObstacle && !canFly))
|
||||
if (!t.getTerrain()->isPassable() || (movingOntoObstacle && !canFly))
|
||||
return complainRet("Cannot move hero, destination tile is blocked!");
|
||||
|
||||
//hero is not on boat/water walking and dst water tile doesn't contain boat/hero (objs visitable from land) -> we test back cause boat may be on top of another object (#276)
|
||||
if(movingOntoWater && !canFly && !canWalkOnSea)
|
||||
return complainRet("Cannot move hero, destination tile is on water!");
|
||||
|
||||
if(h->boat && h->boat->layer == EPathfindingLayer::SAIL && t.terType->isLand() && t.blocked)
|
||||
if(h->boat && h->boat->layer == EPathfindingLayer::SAIL && t.isLand() && t.blocked())
|
||||
return complainRet("Cannot disembark hero, tile is blocked!");
|
||||
|
||||
if(distance(h->pos, dst) >= 1.5 && movementMode == EMovementMode::STANDARD)
|
||||
@ -895,7 +894,7 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, EMovementMode moveme
|
||||
if(h->movementPointsRemaining() < cost && dst != h->pos && movementMode == EMovementMode::STANDARD)
|
||||
return complainRet("Hero doesn't have any movement points left!");
|
||||
|
||||
if (transit && !canFly && !(canWalkOnSea && t.terType->isWater()) && !CGTeleport::isTeleport(objectToVisit))
|
||||
if (transit && !canFly && !(canWalkOnSea && t.isWater()) && !CGTeleport::isTeleport(objectToVisit))
|
||||
return complainRet("Hero cannot transit over this tile!");
|
||||
|
||||
//several generic blocks of code
|
||||
@ -1017,7 +1016,7 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, EMovementMode moveme
|
||||
if (CGTeleport::isTeleport(objectToVisit))
|
||||
visitDest = DONT_VISIT_DEST;
|
||||
|
||||
if (canFly || (canWalkOnSea && t.terType->isWater()))
|
||||
if (canFly || (canWalkOnSea && t.isWater()))
|
||||
{
|
||||
lookForGuards = IGNORE_GUARDS;
|
||||
visitDest = DONT_VISIT_DEST;
|
||||
@ -1140,7 +1139,7 @@ void CGameHandler::giveCreatures(const CArmedInstance *obj, const CGHeroInstance
|
||||
//first we move creatures to give to make them army of object-source
|
||||
for (auto & elem : creatures.Slots())
|
||||
{
|
||||
addToSlot(StackLocation(obj, obj->getSlotFor(elem.second->type)), elem.second->type, elem.second->count);
|
||||
addToSlot(StackLocation(obj, obj->getSlotFor(elem.second->getCreature())), elem.second->getCreature(), elem.second->count);
|
||||
}
|
||||
|
||||
tryJoiningArmy(obj, h, remove, true);
|
||||
@ -1161,7 +1160,7 @@ void CGameHandler::takeCreatures(ObjectInstanceID objid, const std::vector<CStac
|
||||
bool foundSth = false;
|
||||
for (auto i = obj->Slots().begin(); i != obj->Slots().end(); i++)
|
||||
{
|
||||
if (i->second->type == sbd.type)
|
||||
if (i->second->getType() == sbd.getType())
|
||||
{
|
||||
TQuantity take = std::min(sbd.count - collected, i->second->count); //collect as much cres as we can
|
||||
changeStackCount(StackLocation(obj, i->first), -take, false);
|
||||
@ -2456,7 +2455,7 @@ void CGameHandler::moveArmy(const CArmedInstance *src, const CArmedInstance *dst
|
||||
auto i = src->Slots().begin(); //iterator to stack to move
|
||||
StackLocation sl(src, i->first); //location of stack to move
|
||||
|
||||
SlotID pos = dst->getSlotFor(i->second->type);
|
||||
SlotID pos = dst->getSlotFor(i->second->getCreature());
|
||||
if (!pos.validSlot())
|
||||
{
|
||||
//try to merge two other stacks to make place
|
||||
@ -2601,7 +2600,7 @@ bool CGameHandler::moveArtifact(const PlayerColor & player, const ArtifactLocati
|
||||
if((srcSlotInfo && srcSlotInfo->locked) || (dstSlotInfo && dstSlotInfo->locked))
|
||||
COMPLAIN_RET("Cannot move artifact locks.");
|
||||
|
||||
if(isDstSlotBackpack && srcArtifact->artType->isBig())
|
||||
if(isDstSlotBackpack && srcArtifact->getType()->isBig())
|
||||
COMPLAIN_RET("Cannot put big artifacts in backpack!");
|
||||
if(src.slot == ArtifactPosition::MACH4 || dstSlot == ArtifactPosition::MACH4)
|
||||
COMPLAIN_RET("Cannot move catapult!");
|
||||
@ -2626,7 +2625,7 @@ bool CGameHandler::moveArtifact(const PlayerColor & player, const ArtifactLocati
|
||||
}
|
||||
|
||||
auto hero = getHero(dst.artHolder);
|
||||
if(ArtifactUtils::checkSpellbookIsNeeded(hero, srcArtifact->artType->getId(), dstSlot))
|
||||
if(ArtifactUtils::checkSpellbookIsNeeded(hero, srcArtifact->getTypeId(), dstSlot))
|
||||
giveHeroNewArtifact(hero, ArtifactID::SPELLBOOK, ArtifactPosition::SPELLBOOK);
|
||||
|
||||
ma.artsPack0.push_back(BulkMoveArtifacts::LinkedSlots(src.slot, dstSlot));
|
||||
@ -2772,21 +2771,21 @@ bool CGameHandler::manageBackpackArtifacts(const PlayerColor & player, const Obj
|
||||
{
|
||||
makeSortBackpackRequest([](const ArtSlotInfo & inf) -> int32_t
|
||||
{
|
||||
return inf.getArt()->artType->getPossibleSlots().at(ArtBearer::HERO).front().num;
|
||||
return inf.getArt()->getType()->getPossibleSlots().at(ArtBearer::HERO).front().num;
|
||||
});
|
||||
}
|
||||
else if(sortType == ManageBackpackArtifacts::ManageCmd::SORT_BY_COST)
|
||||
{
|
||||
makeSortBackpackRequest([](const ArtSlotInfo & inf) -> int32_t
|
||||
{
|
||||
return inf.getArt()->artType->getPrice();
|
||||
return inf.getArt()->getType()->getPrice();
|
||||
});
|
||||
}
|
||||
else if(sortType == ManageBackpackArtifacts::ManageCmd::SORT_BY_CLASS)
|
||||
{
|
||||
makeSortBackpackRequest([](const ArtSlotInfo & inf) -> int32_t
|
||||
{
|
||||
return inf.getArt()->artType->aClass;
|
||||
return inf.getArt()->getType()->aClass;
|
||||
});
|
||||
}
|
||||
else
|
||||
@ -2925,7 +2924,7 @@ bool CGameHandler::assembleArtifacts(ObjectInstanceID heroID, ArtifactPosition a
|
||||
COMPLAIN_RET("assembleArtifacts: Artifact being attempted to disassemble is fused combined artifact!");
|
||||
|
||||
if(ArtifactUtils::isSlotBackpack(artifactSlot)
|
||||
&& !ArtifactUtils::isBackpackFreeSlots(hero, destArtifact->artType->getConstituents().size() - 1))
|
||||
&& !ArtifactUtils::isBackpackFreeSlots(hero, destArtifact->getType()->getConstituents().size() - 1))
|
||||
COMPLAIN_RET("assembleArtifacts: Artifact being attempted to disassemble but backpack is full!");
|
||||
|
||||
DisassembledArtifact da;
|
||||
@ -3036,11 +3035,11 @@ bool CGameHandler::buyArtifact(const IMarket *m, const CGHeroInstance *h, GameRe
|
||||
COMPLAIN_RET("Wrong marktet...");
|
||||
|
||||
bool found = false;
|
||||
for (const CArtifact *&art : saa.arts)
|
||||
for (ArtifactID & art : saa.arts)
|
||||
{
|
||||
if (art && art->getId() == aid)
|
||||
if (art == aid)
|
||||
{
|
||||
art = nullptr;
|
||||
art = ArtifactID();
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
@ -3059,11 +3058,11 @@ bool CGameHandler::sellArtifact(const IMarket *m, const CGHeroInstance *h, Artif
|
||||
COMPLAIN_RET_FALSE_IF((!h), "Only hero can sell artifacts!");
|
||||
const CArtifactInstance *art = h->getArtByInstanceId(aid);
|
||||
COMPLAIN_RET_FALSE_IF((!art), "There is no artifact to sell!");
|
||||
COMPLAIN_RET_FALSE_IF((!art->artType->isTradable()), "Cannot sell a war machine or spellbook!");
|
||||
COMPLAIN_RET_FALSE_IF((!art->getType()->isTradable()), "Cannot sell a war machine or spellbook!");
|
||||
|
||||
int resVal = 0;
|
||||
int dump = 1;
|
||||
m->getOffer(art->artType->getId(), rid, dump, resVal, EMarketMode::ARTIFACT_RESOURCE);
|
||||
m->getOffer(art->getType()->getId(), rid, dump, resVal, EMarketMode::ARTIFACT_RESOURCE);
|
||||
|
||||
removeArtifact(ArtifactLocation(h->id, h->getArtPos(art)));
|
||||
giveResource(h->tempOwner, rid, resVal);
|
||||
@ -3138,7 +3137,7 @@ bool CGameHandler::sellCreatures(ui32 count, const IMarket *market, const CGHero
|
||||
|
||||
int b1; //base quantities for trade
|
||||
int b2;
|
||||
market->getOffer(s.type->getId(), resourceID, b1, b2, EMarketMode::CREATURE_RESOURCE);
|
||||
market->getOffer(s.getId(), resourceID, b1, b2, EMarketMode::CREATURE_RESOURCE);
|
||||
int units = count / b1; //how many base quantities we trade
|
||||
|
||||
if (count%b1) //all offered units of resource should be used, if not -> somewhere in calculations must be an error
|
||||
@ -3649,7 +3648,7 @@ bool CGameHandler::sacrificeCreatures(const IMarket * market, const CGHeroInstan
|
||||
COMPLAIN_RET("Cannot sacrifice last creature!");
|
||||
}
|
||||
|
||||
int crid = hero->getStack(slot[i]).type->getId();
|
||||
int crid = hero->getStack(slot[i]).getId();
|
||||
|
||||
changeStackCount(StackLocation(hero, slot[i]), -(TQuantity)count[i]);
|
||||
|
||||
@ -3687,7 +3686,7 @@ bool CGameHandler::sacrificeArtifact(const IMarket * market, const CGHeroInstanc
|
||||
{
|
||||
if(auto art = artSet->getArtByInstanceId(artInstId))
|
||||
{
|
||||
if(art->artType->isTradable())
|
||||
if(art->getType()->isTradable())
|
||||
{
|
||||
int dmp;
|
||||
int expToGive;
|
||||
@ -3802,7 +3801,7 @@ void CGameHandler::tryJoiningArmy(const CArmedInstance *src, const CArmedInstanc
|
||||
{
|
||||
for (auto i = src->stacks.begin(); i != src->stacks.end(); i++)//while there are unmoved creatures
|
||||
{
|
||||
SlotID pos = dst->getSlotFor(i->second->type);
|
||||
SlotID pos = dst->getSlotFor(i->second->getCreature());
|
||||
if (pos.validSlot())
|
||||
{
|
||||
moveStack(StackLocation(src, i->first), StackLocation(dst, pos));
|
||||
@ -3893,7 +3892,7 @@ bool CGameHandler::swapStacks(const StackLocation & sl1, const StackLocation & s
|
||||
bool CGameHandler::putArtifact(const ArtifactLocation & al, const ArtifactInstanceID & id, std::optional<bool> askAssemble)
|
||||
{
|
||||
const auto artInst = getArtInstance(id);
|
||||
assert(artInst && artInst->artType);
|
||||
assert(artInst && artInst->getType());
|
||||
ArtifactLocation dst(al.artHolder, ArtifactPosition::PRE_FIRST);
|
||||
dst.creature = al.creature;
|
||||
auto putTo = getArtSet(al);
|
||||
@ -4212,7 +4211,7 @@ CGObjectInstance * CGameHandler::createNewObject(const int3 & visitablePosition,
|
||||
throw std::runtime_error("Attempt to create object outside map at " + visitablePosition.toString());
|
||||
|
||||
const TerrainTile & t = gs->map->getTile(visitablePosition);
|
||||
terrainType = t.terType->getId();
|
||||
terrainType = t.getTerrainID();
|
||||
|
||||
auto handler = VLC->objtypeh->getHandlerFor(objectID, subID);
|
||||
|
||||
|
@ -157,7 +157,7 @@ void BattleProcessor::startBattle(const CArmedInstance *army1, const CArmedInsta
|
||||
BattleID BattleProcessor::setupBattle(int3 tile, BattleSideArray<const CArmedInstance *> armies, BattleSideArray<const CGHeroInstance *> heroes, const BattleLayout & layout, const CGTownInstance *town)
|
||||
{
|
||||
const auto & t = *gameHandler->getTile(tile);
|
||||
TerrainId terrain = t.terType->getId();
|
||||
TerrainId terrain = t.getTerrainID();
|
||||
if (town)
|
||||
terrain = town->getNativeTerrain();
|
||||
else if (gameHandler->gameState()->map->isCoastalTile(tile)) //coastal tile is always ground
|
||||
|
@ -556,12 +556,12 @@ void BattleResultProcessor::battleAfterLevelUp(const BattleID & battleID, const
|
||||
const CStackBasicDescriptor raisedStack = finishingBattle->winnerHero ? finishingBattle->winnerHero->calculateNecromancy(result) : CStackBasicDescriptor();
|
||||
// Give raised units to winner and show dialog, if any were raised,
|
||||
// units will be given after casualties are taken
|
||||
const SlotID necroSlot = raisedStack.type ? finishingBattle->winnerHero->getSlotFor(raisedStack.type) : SlotID();
|
||||
const SlotID necroSlot = raisedStack.getCreature() ? finishingBattle->winnerHero->getSlotFor(raisedStack.getCreature()) : SlotID();
|
||||
|
||||
if (necroSlot != SlotID() && !finishingBattle->isDraw())
|
||||
{
|
||||
finishingBattle->winnerHero->showNecromancyDialog(raisedStack, gameHandler->getRandomGenerator());
|
||||
gameHandler->addToSlot(StackLocation(finishingBattle->winnerHero, necroSlot), raisedStack.type, raisedStack.count);
|
||||
gameHandler->addToSlot(StackLocation(finishingBattle->winnerHero, necroSlot), raisedStack.getCreature(), raisedStack.count);
|
||||
}
|
||||
|
||||
BattleResultsApplied resultsApplied;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user