1
0
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:
Ivan Savenko 2024-11-06 22:01:11 +02:00 committed by GitHub
commit e7bea6c3b8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
104 changed files with 561 additions and 531 deletions

View File

@ -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)
{

View File

@ -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;

View File

@ -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;

View File

@ -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()

View File

@ -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)

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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;

View File

@ -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?

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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;

View File

@ -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();

View File

@ -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)
{

View File

@ -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));
}

View File

@ -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());

View File

@ -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);

View File

@ -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;

View File

@ -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)

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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
{

View File

@ -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
{

View File

@ -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);

View File

@ -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);
}

View File

@ -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
}

View File

@ -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() + "\"";

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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
}

View File

@ -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;
}

View File

@ -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
{

View File

@ -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)

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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;
}
};

View File

@ -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;

View File

@ -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))

View File

@ -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))

View File

@ -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);
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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())

View File

@ -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

View File

@ -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());
}
}
}

View File

@ -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;

View File

@ -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:

View File

@ -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;

View File

@ -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
}

View File

@ -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());
}
}
}

View File

@ -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;

View File

@ -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++;

View File

@ -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)

View File

@ -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);
}
}

View File

@ -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)

View File

@ -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)
{

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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(), ' ');
}

View File

@ -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;

View File

@ -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();
}

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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)

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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);

View File

@ -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++)
{

View File

@ -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())
{

View File

@ -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();
});

View File

@ -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';
}

View File

@ -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';
}

View File

@ -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);

View File

@ -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

View File

@ -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)

View File

@ -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
};

View File

@ -374,7 +374,7 @@ bool DimensionDoorMechanics::canBeCastAtImpl(spells::Problem & problem, const CG
}
else
{
if (dest->blocked)
if (dest->blocked())
return false;
}

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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())
{

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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))

View File

@ -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));
}
}
}

View File

@ -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);

View File

@ -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

View File

@ -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