mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-22 22:13:35 +02:00
Merge pull request #4735 from IvanSavenko/private_pos
Reduce usages of ambiguos CGObjectInstance::pos
This commit is contained in:
commit
5aebf287b9
@ -864,7 +864,7 @@ void AIGateway::makeTurn()
|
||||
|
||||
void AIGateway::performObjectInteraction(const CGObjectInstance * obj, HeroPtr h)
|
||||
{
|
||||
LOG_TRACE_PARAMS(logAi, "Hero %s and object %s at %s", h->getNameTranslated() % obj->getObjectName() % obj->pos.toString());
|
||||
LOG_TRACE_PARAMS(logAi, "Hero %s and object %s at %s", h->getNameTranslated() % obj->getObjectName() % obj->anchorPos().toString());
|
||||
switch(obj->ID)
|
||||
{
|
||||
case Obj::TOWN:
|
||||
@ -1455,7 +1455,7 @@ bool AIGateway::moveHeroToTile(int3 dst, HeroPtr h)
|
||||
void AIGateway::buildStructure(const CGTownInstance * t, BuildingID building)
|
||||
{
|
||||
auto name = t->town->buildings.at(building)->getNameTranslated();
|
||||
logAi->debug("Player %d will build %s in town of %s at %s", ai->playerID, name, t->getNameTranslated(), t->pos.toString());
|
||||
logAi->debug("Player %d will build %s in town of %s at %s", ai->playerID, name, t->getNameTranslated(), t->anchorPos().toString());
|
||||
cb->buildBuilding(t, building); //just do this;
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ void BuildThis::accept(AIGateway * ai)
|
||||
if(cb->canBuildStructure(town, b) == EBuildingState::ALLOWED)
|
||||
{
|
||||
logAi->debug("Player %d will build %s in town of %s at %s",
|
||||
ai->playerID, town->town->buildings.at(b)->getNameTranslated(), town->getNameTranslated(), town->pos.toString());
|
||||
ai->playerID, town->town->buildings.at(b)->getNameTranslated(), town->getNameTranslated(), town->anchorPos().toString());
|
||||
cb->buildBuilding(town, b);
|
||||
|
||||
return;
|
||||
|
@ -46,7 +46,7 @@ TSubgoal FindObj::whatToDoToAchieve()
|
||||
}
|
||||
}
|
||||
}
|
||||
if(o && ai->isAccessible(o->pos)) //we don't use isAccessibleForHero as we don't know which hero it is
|
||||
if(o && ai->isAccessible(o->visitablePos())) //we don't use isAccessibleForHero as we don't know which hero it is
|
||||
return sptr(VisitObj(o->id.getNum()));
|
||||
else
|
||||
return sptr(Explore());
|
||||
|
@ -1032,7 +1032,7 @@ void VCAI::mainLoop()
|
||||
|
||||
void VCAI::performObjectInteraction(const CGObjectInstance * obj, HeroPtr h)
|
||||
{
|
||||
LOG_TRACE_PARAMS(logAi, "Hero %s and object %s at %s", h->getNameTranslated() % obj->getObjectName() % obj->pos.toString());
|
||||
LOG_TRACE_PARAMS(logAi, "Hero %s and object %s at %s", h->getNameTranslated() % obj->getObjectName() % obj->anchorPos().toString());
|
||||
switch(obj->ID)
|
||||
{
|
||||
case Obj::TOWN:
|
||||
@ -1417,11 +1417,11 @@ void VCAI::wander(HeroPtr h)
|
||||
//TODO pick the truly best
|
||||
const CGTownInstance * t = *boost::max_element(townsNotReachable, compareReinforcements);
|
||||
logAi->debug("%s can't reach any town, we'll try to make our way to %s at %s", h->getNameTranslated(), t->getNameTranslated(), t->visitablePos().toString());
|
||||
int3 pos1 = h->pos;
|
||||
int3 posBefore = h->visitablePos();
|
||||
striveToGoal(sptr(Goals::ClearWayTo(t->visitablePos()).sethero(h))); //TODO: drop "strive", add to mainLoop
|
||||
//if out hero is stuck, we may need to request another hero to clear the way we see
|
||||
|
||||
if(pos1 == h->pos && h == primaryHero()) //hero can't move
|
||||
if(posBefore == h->visitablePos() && h == primaryHero()) //hero can't move
|
||||
{
|
||||
if(canRecruitAnyHero(t))
|
||||
recruitHero(t);
|
||||
@ -1471,7 +1471,7 @@ void VCAI::wander(HeroPtr h)
|
||||
{
|
||||
auto chosenObject = cb->getObjInstance(ObjectInstanceID(bestObjectGoal->objid));
|
||||
if(chosenObject != nullptr)
|
||||
logAi->debug("Of all %d destinations, object %s at pos=%s seems nice", dests.size(), chosenObject->getObjectName(), chosenObject->pos.toString());
|
||||
logAi->debug("Of all %d destinations, object %s at pos=%s seems nice", dests.size(), chosenObject->getObjectName(), chosenObject->anchorPos().toString());
|
||||
}
|
||||
else
|
||||
logAi->debug("Trying to realize goal of type %s as part of wandering.", bestObjectGoal->name());
|
||||
@ -1995,7 +1995,7 @@ bool VCAI::moveHeroToTile(int3 dst, HeroPtr h)
|
||||
void VCAI::buildStructure(const CGTownInstance * t, BuildingID building)
|
||||
{
|
||||
auto name = t->town->buildings.at(building)->getNameTranslated();
|
||||
logAi->debug("Player %d will build %s in town of %s at %s", ai->playerID, name, t->getNameTranslated(), t->pos.toString());
|
||||
logAi->debug("Player %d will build %s in town of %s at %s", ai->playerID, name, t->getNameTranslated(), t->anchorPos().toString());
|
||||
cb->buildBuilding(t, building); //just do this;
|
||||
}
|
||||
|
||||
@ -2081,7 +2081,7 @@ void VCAI::tryRealize(Goals::BuildThis & g)
|
||||
if (cb->canBuildStructure(t, b) == EBuildingState::ALLOWED)
|
||||
{
|
||||
logAi->debug("Player %d will build %s in town of %s at %s",
|
||||
playerID, t->town->buildings.at(b)->getNameTranslated(), t->getNameTranslated(), t->pos.toString());
|
||||
playerID, t->town->buildings.at(b)->getNameTranslated(), t->getNameTranslated(), t->anchorPos().toString());
|
||||
cb->buildBuilding(t, b);
|
||||
throw goalFulfilledException(sptr(g));
|
||||
}
|
||||
|
@ -375,7 +375,7 @@ void HeroMovementController::sendMovementRequest(const CGHeroInstance * h, const
|
||||
{
|
||||
updateMovementSound(h, currNode.coord, nextNode.coord, nextNode.action);
|
||||
|
||||
assert(h->pos.z == nextNode.coord.z); // Z should change only if it's movement via teleporter and in this case this code shouldn't be executed at all
|
||||
assert(h->anchorPos().z == nextNode.coord.z); // Z should change only if it's movement via teleporter and in this case this code shouldn't be executed at all
|
||||
|
||||
logGlobal->trace("Requesting hero movement to %s", nextNode.coord.toString());
|
||||
|
||||
|
@ -81,9 +81,9 @@ void MapAudioPlayer::addObject(const CGObjectInstance * obj)
|
||||
{
|
||||
for(int fy = 0; fy < obj->getHeight(); ++fy)
|
||||
{
|
||||
int3 currTile(obj->pos.x - fx, obj->pos.y - fy, obj->pos.z);
|
||||
int3 currTile(obj->anchorPos().x - fx, obj->anchorPos().y - fy, obj->anchorPos().z);
|
||||
|
||||
if(LOCPLINT->cb->isInTheMap(currTile) && obj->coveringAt(currTile.x, currTile.y))
|
||||
if(LOCPLINT->cb->isInTheMap(currTile) && obj->coveringAt(currTile))
|
||||
objects[currTile.z][currTile.x][currTile.y].push_back(obj->id);
|
||||
}
|
||||
}
|
||||
@ -108,7 +108,7 @@ void MapAudioPlayer::addObject(const CGObjectInstance * obj)
|
||||
|
||||
for(const auto & tile : tiles)
|
||||
{
|
||||
int3 currTile = obj->pos + tile;
|
||||
int3 currTile = obj->anchorPos() + tile;
|
||||
|
||||
if(LOCPLINT->cb->isInTheMap(currTile))
|
||||
objects[currTile.z][currTile.x][currTile.y].push_back(obj->id);
|
||||
|
@ -591,8 +591,8 @@ void MapRendererOverlay::renderTile(IMapRendererContext & context, Canvas & targ
|
||||
|
||||
if(context.objectTransparency(objectID, coordinates) > 0 && !context.isActiveHero(object))
|
||||
{
|
||||
visitable |= object->visitableAt(coordinates.x, coordinates.y);
|
||||
blocking |= object->blockingAt(coordinates.x, coordinates.y);
|
||||
visitable |= object->visitableAt(coordinates);
|
||||
blocking |= object->blockingAt(coordinates);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -120,7 +120,7 @@ size_t MapRendererBaseContext::objectGroupIndex(ObjectInstanceID objectID) const
|
||||
Point MapRendererBaseContext::objectImageOffset(ObjectInstanceID objectID, const int3 & coordinates) const
|
||||
{
|
||||
const CGObjectInstance * object = getObject(objectID);
|
||||
int3 offsetTiles(object->getPosition() - coordinates);
|
||||
int3 offsetTiles(object->anchorPos() - coordinates);
|
||||
return Point(offsetTiles) * Point(32, 32);
|
||||
}
|
||||
|
||||
@ -498,7 +498,7 @@ size_t MapRendererWorldViewContext::overlayImageIndex(const int3 & coordinates)
|
||||
{
|
||||
const auto * object = getObject(objectID);
|
||||
|
||||
if(!object->visitableAt(coordinates.x, coordinates.y))
|
||||
if(!object->visitableAt(coordinates))
|
||||
continue;
|
||||
|
||||
ObjectPosInfo info(object);
|
||||
|
@ -49,9 +49,9 @@ void MapRendererContextState::addObject(const CGObjectInstance * obj)
|
||||
{
|
||||
for(int fy = 0; fy < obj->getHeight(); ++fy)
|
||||
{
|
||||
int3 currTile(obj->pos.x - fx, obj->pos.y - fy, obj->pos.z);
|
||||
int3 currTile(obj->anchorPos().x - fx, obj->anchorPos().y - fy, obj->anchorPos().z);
|
||||
|
||||
if(LOCPLINT->cb->isInTheMap(currTile) && obj->coveringAt(currTile.x, currTile.y))
|
||||
if(LOCPLINT->cb->isInTheMap(currTile) && obj->coveringAt(currTile))
|
||||
{
|
||||
auto & container = objects[currTile.z][currTile.x][currTile.y];
|
||||
|
||||
@ -73,7 +73,7 @@ void MapRendererContextState::addMovingObject(const CGObjectInstance * object, c
|
||||
{
|
||||
for(int y = yFrom; y <= yDest; ++y)
|
||||
{
|
||||
int3 currTile(x, y, object->pos.z);
|
||||
int3 currTile(x, y, object->anchorPos().z);
|
||||
|
||||
if(LOCPLINT->cb->isInTheMap(currTile))
|
||||
{
|
||||
|
@ -317,7 +317,7 @@ bool MapViewController::isEventVisible(const CGObjectInstance * obj, const Playe
|
||||
if(obj->isVisitable())
|
||||
return context->isVisible(obj->visitablePos());
|
||||
else
|
||||
return context->isVisible(obj->pos);
|
||||
return context->isVisible(obj->anchorPos());
|
||||
}
|
||||
|
||||
bool MapViewController::isEventVisible(const CGHeroInstance * obj, const int3 & from, const int3 & dest)
|
||||
|
@ -59,7 +59,7 @@ std::string CMapHandler::getTerrainDescr(const int3 & pos, bool rightClick) cons
|
||||
|
||||
for(const auto & object : map->objects)
|
||||
{
|
||||
if(object && object->coveringAt(pos.x, pos.y) && object->pos.z == pos.z && object->isTile2Terrain())
|
||||
if(object && object->coveringAt(pos) && object->isTile2Terrain())
|
||||
{
|
||||
result = object->getObjectName();
|
||||
break;
|
||||
@ -103,15 +103,15 @@ bool CMapHandler::compareObjectBlitOrder(const CGObjectInstance * a, const CGObj
|
||||
|
||||
for(const auto & aOffset : a->getBlockedOffsets())
|
||||
{
|
||||
int3 testTarget = a->pos + aOffset + int3(0, 1, 0);
|
||||
if(b->blockingAt(testTarget.x, testTarget.y))
|
||||
int3 testTarget = a->anchorPos() + aOffset + int3(0, 1, 0);
|
||||
if(b->blockingAt(testTarget))
|
||||
bBlocksA += 1;
|
||||
}
|
||||
|
||||
for(const auto & bOffset : b->getBlockedOffsets())
|
||||
{
|
||||
int3 testTarget = b->pos + bOffset + int3(0, 1, 0);
|
||||
if(a->blockingAt(testTarget.x, testTarget.y))
|
||||
int3 testTarget = b->anchorPos() + bOffset + int3(0, 1, 0);
|
||||
if(a->blockingAt(testTarget))
|
||||
aBlocksB += 1;
|
||||
}
|
||||
|
||||
@ -126,8 +126,8 @@ bool CMapHandler::compareObjectBlitOrder(const CGObjectInstance * a, const CGObj
|
||||
return aBlocksB < bBlocksA;
|
||||
|
||||
// object that don't have clear priority via tile blocking will appear based on their row
|
||||
if(a->pos.y != b->pos.y)
|
||||
return a->pos.y < b->pos.y;
|
||||
if(a->anchorPos().y != b->anchorPos().y)
|
||||
return a->anchorPos().y < b->anchorPos().y;
|
||||
|
||||
// heroes should appear on top of objects on the same tile
|
||||
if(b->ID==Obj::HERO && a->ID!=Obj::HERO)
|
||||
|
@ -78,7 +78,7 @@ void CQuestMinimap::addQuestMarks (const QuestInfo * q)
|
||||
|
||||
int3 tile;
|
||||
if (q->obj)
|
||||
tile = q->obj->pos;
|
||||
tile = q->obj->visitablePos();
|
||||
else
|
||||
tile = q->tile;
|
||||
|
||||
@ -104,7 +104,7 @@ void CQuestMinimap::update()
|
||||
void CQuestMinimap::iconClicked()
|
||||
{
|
||||
if(currentQuest->obj)
|
||||
adventureInt->centerOnTile(currentQuest->obj->pos);
|
||||
adventureInt->centerOnTile(currentQuest->obj->visitablePos());
|
||||
//moveAdvMapSelection();
|
||||
}
|
||||
|
||||
|
@ -539,7 +539,7 @@ EDiggingStatus CGameInfoCallback::getTileDigStatus(int3 tile, bool verbose) cons
|
||||
|
||||
for(const auto & object : gs->map->objects)
|
||||
{
|
||||
if(object && object->ID == Obj::HOLE && object->pos == tile)
|
||||
if(object && object->ID == Obj::HOLE && object->anchorPos() == tile)
|
||||
return EDiggingStatus::TILE_OCCUPIED;
|
||||
}
|
||||
return getTile(tile)->getDiggingStatus();
|
||||
|
@ -449,7 +449,7 @@ void CGameState::initGrailPosition()
|
||||
//remove tiles with holes
|
||||
for(auto & elem : map->objects)
|
||||
if(elem && elem->ID == Obj::HOLE)
|
||||
allowedPos -= elem->pos;
|
||||
allowedPos -= elem->anchorPos();
|
||||
|
||||
if(!allowedPos.empty())
|
||||
{
|
||||
@ -495,7 +495,7 @@ void CGameState::randomizeMapObjects()
|
||||
{
|
||||
for (int j = 0; j < object->getHeight() ; j++)
|
||||
{
|
||||
int3 pos = object->pos - int3(i,j,0);
|
||||
int3 pos = object->anchorPos() - int3(i,j,0);
|
||||
if(map->isInTheMap(pos)) map->getTile(pos).extTileFlags |= 128;
|
||||
}
|
||||
}
|
||||
@ -530,7 +530,7 @@ void CGameState::placeStartingHero(const PlayerColor & playerColor, const HeroTy
|
||||
{
|
||||
for(auto town : map->towns)
|
||||
{
|
||||
if(town->getPosition() == townPos)
|
||||
if(town->anchorPos() == townPos)
|
||||
{
|
||||
townPos = town->visitablePos();
|
||||
break;
|
||||
@ -545,8 +545,7 @@ void CGameState::placeStartingHero(const PlayerColor & playerColor, const HeroTy
|
||||
hero->setHeroType(heroTypeId);
|
||||
hero->tempOwner = playerColor;
|
||||
|
||||
hero->pos = townPos;
|
||||
hero->pos += hero->getVisitableOffset();
|
||||
hero->setAnchorPos(townPos + hero->getVisitableOffset());
|
||||
map->getEditManager()->insertObject(hero);
|
||||
}
|
||||
|
||||
@ -614,7 +613,7 @@ void CGameState::initHeroes()
|
||||
auto boat = dynamic_cast<CGBoat*>(handler->create(callback, nullptr));
|
||||
handler->configureObject(boat, gs->getRandomGenerator());
|
||||
|
||||
boat->pos = hero->pos;
|
||||
boat->setAnchorPos(hero->anchorPos());
|
||||
boat->appearance = handler->getTemplates().front();
|
||||
boat->id = ObjectInstanceID(static_cast<si32>(gs->map->objects.size()));
|
||||
|
||||
@ -964,22 +963,18 @@ void CGameState::placeHeroesInTowns()
|
||||
{
|
||||
for(CGTownInstance * t : player.second.getTowns())
|
||||
{
|
||||
if(h->visitablePos().z != t->visitablePos().z)
|
||||
continue;
|
||||
|
||||
bool heroOnTownBlockableTile = t->blockingAt(h->visitablePos().x, h->visitablePos().y);
|
||||
bool heroOnTownBlockableTile = t->blockingAt(h->visitablePos());
|
||||
|
||||
// current hero position is at one of blocking tiles of current town
|
||||
// assume that this hero should be visiting the town (H3M format quirk) and move hero to correct position
|
||||
if (heroOnTownBlockableTile)
|
||||
{
|
||||
int3 correctedPos = h->convertFromVisitablePos(t->visitablePos());
|
||||
|
||||
map->removeBlockVisTiles(h);
|
||||
h->pos = correctedPos;
|
||||
int3 correctedPos = h->convertFromVisitablePos(t->visitablePos());
|
||||
h->setAnchorPos(correctedPos);
|
||||
map->addBlockVisTiles(h);
|
||||
|
||||
assert(t->visitableAt(h->visitablePos().x, h->visitablePos().y));
|
||||
assert(t->visitableAt(h->visitablePos()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1001,7 +996,7 @@ void CGameState::initVisitingAndGarrisonedHeroes()
|
||||
if(h->visitablePos().z != t->visitablePos().z)
|
||||
continue;
|
||||
|
||||
if (t->visitableAt(h->visitablePos().x, h->visitablePos().y))
|
||||
if (t->visitableAt(h->visitablePos()))
|
||||
{
|
||||
assert(t->visitingHero == nullptr);
|
||||
t->setVisitingHero(h);
|
||||
@ -1066,7 +1061,7 @@ BattleField CGameState::battleGetBattlefieldType(int3 tile, vstd::RNG & rand)
|
||||
for(auto &obj : map->objects)
|
||||
{
|
||||
//look only for objects covering given tile
|
||||
if( !obj || obj->pos.z != tile.z || !obj->coveringAt(tile.x, tile.y))
|
||||
if( !obj || !obj->coveringAt(tile))
|
||||
continue;
|
||||
|
||||
auto customBattlefield = obj->getBattlefield();
|
||||
@ -1250,10 +1245,10 @@ bool CGameState::isVisible(const CGObjectInstance * obj, const std::optional<Pla
|
||||
{
|
||||
for(int fx=0; fx < obj->getWidth(); ++fx)
|
||||
{
|
||||
int3 pos = obj->pos + int3(-fx, -fy, 0);
|
||||
int3 pos = obj->anchorPos() + int3(-fx, -fy, 0);
|
||||
|
||||
if ( map->isInTheMap(pos) &&
|
||||
obj->coveringAt(pos.x, pos.y) &&
|
||||
obj->coveringAt(pos) &&
|
||||
isVisible(pos, *player))
|
||||
return true;
|
||||
}
|
||||
|
@ -368,7 +368,7 @@ void CGameStateCampaign::replaceHeroesPlaceholders()
|
||||
heroToPlace->id = campaignHeroReplacement.heroPlaceholderId;
|
||||
if(heroPlaceholder->tempOwner.isValidPlayer())
|
||||
heroToPlace->tempOwner = heroPlaceholder->tempOwner;
|
||||
heroToPlace->pos = heroPlaceholder->pos;
|
||||
heroToPlace->setAnchorPos(heroPlaceholder->anchorPos());
|
||||
heroToPlace->type = heroToPlace->getHeroType().toHeroType();
|
||||
heroToPlace->appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, heroToPlace->type->heroClass->getIndex())->getTemplates().front();
|
||||
|
||||
@ -655,7 +655,7 @@ void CGameStateCampaign::initTowns()
|
||||
if (!owner->human)
|
||||
continue;
|
||||
|
||||
if (town->pos != pi.posOfMainTown)
|
||||
if (town->anchorPos() != pi.posOfMainTown)
|
||||
continue;
|
||||
|
||||
BuildingID newBuilding;
|
||||
|
@ -33,7 +33,7 @@ std::string CGCreature::getHoverText(PlayerColor player) const
|
||||
if(stacks.empty())
|
||||
{
|
||||
//should not happen...
|
||||
logGlobal->error("Invalid stack at tile %s: subID=%d; id=%d", pos.toString(), getCreature(), id.getNum());
|
||||
logGlobal->error("Invalid stack at tile %s: subID=%d; id=%d", anchorPos().toString(), getCreature(), id.getNum());
|
||||
return "INVALID_STACK";
|
||||
}
|
||||
|
||||
@ -562,7 +562,7 @@ bool CGCreature::containsUpgradedStack() const
|
||||
float c = 5325.181015f;
|
||||
float d = 32788.727920f;
|
||||
|
||||
int val = static_cast<int>(std::floor(a * pos.x + b * pos.y + c * pos.z + d));
|
||||
int val = static_cast<int>(std::floor(a * visitablePos().x + b * visitablePos().y + c * visitablePos().z + d));
|
||||
return ((val % 32768) % 100) < 50;
|
||||
}
|
||||
|
||||
@ -591,7 +591,7 @@ int CGCreature::getNumberOfStacks(const CGHeroInstance *hero) const
|
||||
ui32 c = 1943276003u;
|
||||
ui32 d = 3174620878u;
|
||||
|
||||
ui32 R1 = a * static_cast<ui32>(pos.x) + b * static_cast<ui32>(pos.y) + c * static_cast<ui32>(pos.z) + d;
|
||||
ui32 R1 = a * static_cast<ui32>(visitablePos().x) + b * static_cast<ui32>(visitablePos().y) + c * static_cast<ui32>(visitablePos().z) + d;
|
||||
ui32 R2 = (R1 >> 16) & 0x7fff;
|
||||
|
||||
int R4 = R2 % 100 + 1;
|
||||
|
@ -1514,11 +1514,11 @@ bool CGHeroInstance::hasVisions(const CGObjectInstance * target, BonusSubtypeID
|
||||
if (visionsMultiplier > 0)
|
||||
vstd::amax(visionsRange, 3); //minimum range is 3 tiles, but only if VISIONS bonus present
|
||||
|
||||
const int distance = static_cast<int>(target->pos.dist2d(visitablePos()));
|
||||
const int distance = static_cast<int>(target->anchorPos().dist2d(visitablePos()));
|
||||
|
||||
//logGlobal->debug(boost::str(boost::format("Visions: dist %d, mult %d, range %d") % distance % visionsMultiplier % visionsRange));
|
||||
|
||||
return (distance < visionsRange) && (target->pos.z == pos.z);
|
||||
return (distance < visionsRange) && (target->anchorPos().z == anchorPos().z);
|
||||
}
|
||||
|
||||
std::string CGHeroInstance::getHeroTypeName() const
|
||||
|
@ -54,14 +54,14 @@ MapObjectSubID CGObjectInstance::getObjTypeIndex() const
|
||||
return subID;
|
||||
}
|
||||
|
||||
int3 CGObjectInstance::getPosition() const
|
||||
int3 CGObjectInstance::anchorPos() const
|
||||
{
|
||||
return pos;
|
||||
}
|
||||
|
||||
int3 CGObjectInstance::getTopVisiblePos() const
|
||||
{
|
||||
return pos - appearance->getTopVisibleOffset();
|
||||
return anchorPos() - appearance->getTopVisibleOffset();
|
||||
}
|
||||
|
||||
void CGObjectInstance::setOwner(const PlayerColor & ow)
|
||||
@ -69,6 +69,11 @@ void CGObjectInstance::setOwner(const PlayerColor & ow)
|
||||
tempOwner = ow;
|
||||
}
|
||||
|
||||
void CGObjectInstance::setAnchorPos(int3 newPos)
|
||||
{
|
||||
pos = newPos;
|
||||
}
|
||||
|
||||
int CGObjectInstance::getWidth() const
|
||||
{
|
||||
return appearance->getWidth();
|
||||
@ -79,32 +84,19 @@ int CGObjectInstance::getHeight() const
|
||||
return appearance->getHeight();
|
||||
}
|
||||
|
||||
bool CGObjectInstance::visitableAt(int x, int y) const
|
||||
{
|
||||
return appearance->isVisitableAt(pos.x - x, pos.y - y);
|
||||
}
|
||||
bool CGObjectInstance::blockingAt(int x, int y) const
|
||||
{
|
||||
return appearance->isBlockedAt(pos.x - x, pos.y - y);
|
||||
}
|
||||
|
||||
bool CGObjectInstance::coveringAt(int x, int y) const
|
||||
{
|
||||
return appearance->isVisibleAt(pos.x - x, pos.y - y);
|
||||
}
|
||||
|
||||
bool CGObjectInstance::visitableAt(const int3 & testPos) const
|
||||
{
|
||||
return pos.z == testPos.z && appearance->isVisitableAt(pos.x - testPos.x, pos.y - testPos.y);
|
||||
return anchorPos().z == testPos.z && appearance->isVisitableAt(anchorPos().x - testPos.x, anchorPos().y - testPos.y);
|
||||
}
|
||||
|
||||
bool CGObjectInstance::blockingAt(const int3 & testPos) const
|
||||
{
|
||||
return pos.z == testPos.z && appearance->isBlockedAt(pos.x - testPos.x, pos.y - testPos.y);
|
||||
return anchorPos().z == testPos.z && appearance->isBlockedAt(anchorPos().x - testPos.x, anchorPos().y - testPos.y);
|
||||
}
|
||||
|
||||
bool CGObjectInstance::coveringAt(const int3 & testPos) const
|
||||
{
|
||||
return pos.z == testPos.z && appearance->isVisibleAt(pos.x - testPos.x, pos.y - testPos.y);
|
||||
return anchorPos().z == testPos.z && appearance->isVisibleAt(anchorPos().x - testPos.x, anchorPos().y - testPos.y);
|
||||
}
|
||||
|
||||
std::set<int3> CGObjectInstance::getBlockedPos() const
|
||||
@ -115,7 +107,7 @@ std::set<int3> CGObjectInstance::getBlockedPos() const
|
||||
for(int h=0; h<getHeight(); ++h)
|
||||
{
|
||||
if(appearance->isBlockedAt(w, h))
|
||||
ret.insert(int3(pos.x - w, pos.y - h, pos.z));
|
||||
ret.insert(int3(anchorPos().x - w, anchorPos().y - h, anchorPos().z));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
@ -215,6 +207,8 @@ int CGObjectInstance::getSightRadius() const
|
||||
|
||||
int3 CGObjectInstance::getVisitableOffset() const
|
||||
{
|
||||
if (!isVisitable())
|
||||
throw std::runtime_error("Attempt to access visitable offset of a non-visitable object!");
|
||||
return appearance->getVisitableOffset();
|
||||
}
|
||||
|
||||
@ -313,6 +307,9 @@ void CGObjectInstance::onHeroVisit( const CGHeroInstance * h ) const
|
||||
|
||||
int3 CGObjectInstance::visitablePos() const
|
||||
{
|
||||
if (!isVisitable())
|
||||
throw std::runtime_error("Attempt to access visitable position on a non-visitable object!");
|
||||
|
||||
return pos - getVisitableOffset();
|
||||
}
|
||||
|
||||
|
@ -28,8 +28,6 @@ using TObjectTypeHandler = std::shared_ptr<AObjectTypeHandler>;
|
||||
class DLL_LINKAGE CGObjectInstance : public IObjectInterface
|
||||
{
|
||||
public:
|
||||
/// Position of bottom-right corner of object on map
|
||||
int3 pos;
|
||||
/// Type of object, e.g. town, hero, creature.
|
||||
MapObjectID ID;
|
||||
/// Subtype of object, depends on type
|
||||
@ -41,6 +39,9 @@ public:
|
||||
/// Defines appearance of object on map (animation, blocked tiles, blit order, etc)
|
||||
std::shared_ptr<const ObjectTemplate> appearance;
|
||||
|
||||
/// Position of bottom-right corner of object on map
|
||||
int3 pos;
|
||||
|
||||
std::string instanceName;
|
||||
std::string typeName;
|
||||
std::string subTypeName;
|
||||
@ -62,21 +63,19 @@ public:
|
||||
return this->tempOwner;
|
||||
}
|
||||
void setOwner(const PlayerColor & ow);
|
||||
void setAnchorPos(int3 pos);
|
||||
|
||||
/** APPEARANCE ACCESSORS **/
|
||||
|
||||
int getWidth() const; //returns width of object graphic in tiles
|
||||
int getHeight() const; //returns height of object graphic in tiles
|
||||
int3 visitablePos() const override;
|
||||
int3 getPosition() const override;
|
||||
int3 anchorPos() const override;
|
||||
int3 getTopVisiblePos() const;
|
||||
bool visitableAt(int x, int y) const; //returns true if object is visitable at location (x, y) (h3m pos)
|
||||
bool blockingAt(int x, int y) const; //returns true if object is blocking location (x, y) (h3m pos)
|
||||
bool coveringAt(int x, int y) const; //returns true if object covers with picture location (x, y) (h3m pos)
|
||||
|
||||
bool visitableAt(const int3 & pos) const; //returns true if object is visitable at location (x, y) (h3m pos)
|
||||
bool blockingAt (const int3 & pos) const; //returns true if object is blocking location (x, y) (h3m pos)
|
||||
bool coveringAt (const int3 & pos) const; //returns true if object covers with picture location (x, y) (h3m pos)
|
||||
bool visitableAt(const int3 & pos) const; //returns true if object is visitable at location
|
||||
bool blockingAt (const int3 & pos) const; //returns true if object is blocking location
|
||||
bool coveringAt (const int3 & pos) const; //returns true if object covers with picture location
|
||||
|
||||
std::set<int3> getBlockedPos() const; //returns set of positions blocked by this object
|
||||
const std::set<int3> & getBlockedOffsets() const; //returns set of relative positions blocked by this object
|
||||
|
@ -954,7 +954,7 @@ TResources CGTownInstance::getBuildingCost(const BuildingID & buildingID) const
|
||||
return town->buildings.at(buildingID)->resources;
|
||||
else
|
||||
{
|
||||
logGlobal->error("Town %s at %s has no possible building %d!", getNameTranslated(), pos.toString(), buildingID.toEnum());
|
||||
logGlobal->error("Town %s at %s has no possible building %d!", getNameTranslated(), anchorPos().toString(), buildingID.toEnum());
|
||||
return TResources();
|
||||
}
|
||||
|
||||
|
@ -56,8 +56,6 @@ class DLL_LINKAGE CGTownInstance : public CGDwelling, public IShipyard, public I
|
||||
std::set<BuildingID> builtBuildings;
|
||||
|
||||
public:
|
||||
using CGDwelling::getPosition;
|
||||
|
||||
enum EFortLevel {NONE = 0, FORT = 1, CITADEL = 2, CASTLE = 3};
|
||||
|
||||
CTownAndVisitingHero townAndVis;
|
||||
|
@ -614,7 +614,7 @@ void CGSeerHut::onHeroVisit(const CGHeroInstance * h) const
|
||||
|
||||
int CGSeerHut::checkDirection() const
|
||||
{
|
||||
int3 cord = getCreatureToKill(false)->pos;
|
||||
int3 cord = getCreatureToKill(false)->visitablePos();
|
||||
if(static_cast<double>(cord.x) / static_cast<double>(cb->getMapSize().x) < 0.34) //north
|
||||
{
|
||||
if(static_cast<double>(cord.y) / static_cast<double>(cb->getMapSize().y) < 0.34) //northwest
|
||||
|
@ -145,7 +145,7 @@ void IBoatGenerator::getProblemText(MetaString &out, const CGHeroInstance *visit
|
||||
out.appendLocalString(EMetaText::ADVOB_TXT, 189);
|
||||
break;
|
||||
case NO_WATER:
|
||||
logGlobal->error("Shipyard without water at tile %s! ", getObject()->getPosition().toString());
|
||||
logGlobal->error("Shipyard without water at tile %s! ", getObject()->anchorPos().toString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ public:
|
||||
|
||||
virtual PlayerColor getOwner() const = 0;
|
||||
virtual int3 visitablePos() const = 0;
|
||||
virtual int3 getPosition() const = 0;
|
||||
virtual int3 anchorPos() const = 0;
|
||||
|
||||
virtual void onHeroVisit(const CGHeroInstance * h) const;
|
||||
virtual void onHeroLeave(const CGHeroInstance * h) const;
|
||||
|
@ -111,7 +111,7 @@ void CGMine::initObj(vstd::RNG & rand)
|
||||
}
|
||||
else
|
||||
{
|
||||
logGlobal->error("Abandoned mine at (%s) has no valid resource candidates!", pos.toString());
|
||||
logGlobal->error("Abandoned mine at (%s) has no valid resource candidates!", anchorPos().toString());
|
||||
producedResource = GameResID::GOLD;
|
||||
}
|
||||
}
|
||||
@ -510,11 +510,11 @@ void CGMonolith::onHeroVisit( const CGHeroInstance * h ) const
|
||||
|
||||
if(cb->isTeleportChannelImpassable(channel))
|
||||
{
|
||||
logGlobal->debug("Cannot find corresponding exit monolith for %d at %s", id.getNum(), pos.toString());
|
||||
logGlobal->debug("Cannot find corresponding exit monolith for %d at %s", id.getNum(), anchorPos().toString());
|
||||
td.impassable = true;
|
||||
}
|
||||
else if(getRandomExit(h) == ObjectInstanceID())
|
||||
logGlobal->debug("All exits blocked for monolith %d at %s", id.getNum(), pos.toString());
|
||||
logGlobal->debug("All exits blocked for monolith %d at %s", id.getNum(), anchorPos().toString());
|
||||
}
|
||||
else
|
||||
h->showInfoDialog(70);
|
||||
@ -574,7 +574,7 @@ void CGSubterraneanGate::onHeroVisit( const CGHeroInstance * h ) const
|
||||
if(cb->isTeleportChannelImpassable(channel))
|
||||
{
|
||||
h->showInfoDialog(153);//Just inside the entrance you find a large pile of rubble blocking the tunnel. You leave discouraged.
|
||||
logGlobal->debug("Cannot find exit subterranean gate for %d at %s", id.getNum(), pos.toString());
|
||||
logGlobal->debug("Cannot find exit subterranean gate for %d at %s", id.getNum(), anchorPos().toString());
|
||||
td.impassable = true;
|
||||
}
|
||||
else
|
||||
@ -602,13 +602,13 @@ void CGSubterraneanGate::postInit(IGameCallback * cb) //matches subterranean gat
|
||||
|
||||
auto * hlp = dynamic_cast<CGSubterraneanGate *>(cb->gameState()->getObjInstance(obj->id));
|
||||
if(hlp)
|
||||
gatesSplit[hlp->pos.z].push_back(hlp);
|
||||
gatesSplit[hlp->visitablePos().z].push_back(hlp);
|
||||
}
|
||||
|
||||
//sort by position
|
||||
std::sort(gatesSplit[0].begin(), gatesSplit[0].end(), [](const CGObjectInstance * a, const CGObjectInstance * b)
|
||||
{
|
||||
return a->pos < b->pos;
|
||||
return a->visitablePos() < b->visitablePos();
|
||||
});
|
||||
|
||||
auto assignToChannel = [&](CGSubterraneanGate * obj)
|
||||
@ -631,7 +631,7 @@ void CGSubterraneanGate::postInit(IGameCallback * cb) //matches subterranean gat
|
||||
CGSubterraneanGate *checked = gatesSplit[1][j];
|
||||
if(checked->channel != TeleportChannelID())
|
||||
continue;
|
||||
si32 hlp = checked->pos.dist2dSQ(objCurrent->pos);
|
||||
si32 hlp = checked->visitablePos().dist2dSQ(objCurrent->visitablePos());
|
||||
if(hlp < best.second)
|
||||
{
|
||||
best.first = j;
|
||||
@ -657,11 +657,11 @@ void CGWhirlpool::onHeroVisit( const CGHeroInstance * h ) const
|
||||
TeleportDialog td(h->id, channel);
|
||||
if(cb->isTeleportChannelImpassable(channel))
|
||||
{
|
||||
logGlobal->debug("Cannot find exit whirlpool for %d at %s", id.getNum(), pos.toString());
|
||||
logGlobal->debug("Cannot find exit whirlpool for %d at %s", id.getNum(), anchorPos().toString());
|
||||
td.impassable = true;
|
||||
}
|
||||
else if(getRandomExit(h) == ObjectInstanceID())
|
||||
logGlobal->debug("All exits are blocked for whirlpool %d at %s", id.getNum(), pos.toString());
|
||||
logGlobal->debug("All exits are blocked for whirlpool %d at %s", id.getNum(), anchorPos().toString());
|
||||
|
||||
if(!isProtected(h))
|
||||
{
|
||||
@ -1086,9 +1086,9 @@ void CGMagi::onHeroVisit(const CGHeroInstance * h) const
|
||||
|
||||
for(const auto & eye : eyes)
|
||||
{
|
||||
cb->getTilesInRange (fw.tiles, eye->pos, 10, ETileVisibility::HIDDEN, h->tempOwner);
|
||||
cb->getTilesInRange (fw.tiles, eye->visitablePos(), 10, ETileVisibility::HIDDEN, h->tempOwner);
|
||||
cb->sendAndApply(fw);
|
||||
cv.pos = eye->pos;
|
||||
cv.pos = eye->visitablePos();
|
||||
|
||||
cb->sendAndApply(cv);
|
||||
}
|
||||
|
@ -56,9 +56,9 @@ int3 TownBuildingInstance::visitablePos() const
|
||||
return town->visitablePos();
|
||||
}
|
||||
|
||||
int3 TownBuildingInstance::getPosition() const
|
||||
int3 TownBuildingInstance::anchorPos() const
|
||||
{
|
||||
return town->getPosition();
|
||||
return town->anchorPos();
|
||||
}
|
||||
|
||||
TownRewardableBuildingInstance::TownRewardableBuildingInstance(IGameCallback *cb)
|
||||
|
@ -38,7 +38,7 @@ public:
|
||||
const IOwnableObject * asOwnable() const override;
|
||||
|
||||
int3 visitablePos() const override;
|
||||
int3 getPosition() const override;
|
||||
int3 anchorPos() const override;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h)
|
||||
{
|
||||
|
@ -232,22 +232,22 @@ CMap::~CMap()
|
||||
|
||||
void CMap::removeBlockVisTiles(CGObjectInstance * obj, bool total)
|
||||
{
|
||||
const int zVal = obj->pos.z;
|
||||
const int zVal = obj->anchorPos().z;
|
||||
for(int fx = 0; fx < obj->getWidth(); ++fx)
|
||||
{
|
||||
int xVal = obj->pos.x - fx;
|
||||
int xVal = obj->anchorPos().x - fx;
|
||||
for(int fy = 0; fy < obj->getHeight(); ++fy)
|
||||
{
|
||||
int yVal = obj->pos.y - fy;
|
||||
int yVal = obj->anchorPos().y - fy;
|
||||
if(xVal>=0 && xVal < width && yVal>=0 && yVal < height)
|
||||
{
|
||||
TerrainTile & curt = terrain[zVal][xVal][yVal];
|
||||
if(total || obj->visitableAt(xVal, yVal))
|
||||
if(total || obj->visitableAt(int3(xVal, yVal, zVal)))
|
||||
{
|
||||
curt.visitableObjects -= obj;
|
||||
curt.visitable = curt.visitableObjects.size();
|
||||
}
|
||||
if(total || obj->blockingAt(xVal, yVal))
|
||||
if(total || obj->blockingAt(int3(xVal, yVal, zVal)))
|
||||
{
|
||||
curt.blockingObjects -= obj;
|
||||
curt.blocked = curt.blockingObjects.size();
|
||||
@ -259,22 +259,22 @@ void CMap::removeBlockVisTiles(CGObjectInstance * obj, bool total)
|
||||
|
||||
void CMap::addBlockVisTiles(CGObjectInstance * obj)
|
||||
{
|
||||
const int zVal = obj->pos.z;
|
||||
const int zVal = obj->anchorPos().z;
|
||||
for(int fx = 0; fx < obj->getWidth(); ++fx)
|
||||
{
|
||||
int xVal = obj->pos.x - fx;
|
||||
int xVal = obj->anchorPos().x - fx;
|
||||
for(int fy = 0; fy < obj->getHeight(); ++fy)
|
||||
{
|
||||
int yVal = obj->pos.y - fy;
|
||||
int yVal = obj->anchorPos().y - fy;
|
||||
if(xVal>=0 && xVal < width && yVal >= 0 && yVal < height)
|
||||
{
|
||||
TerrainTile & curt = terrain[zVal][xVal][yVal];
|
||||
if(obj->visitableAt(xVal, yVal))
|
||||
if(obj->visitableAt(int3(xVal, yVal, zVal)))
|
||||
{
|
||||
curt.visitableObjects.push_back(obj);
|
||||
curt.visitable = true;
|
||||
}
|
||||
if(obj->blockingAt(xVal, yVal))
|
||||
if(obj->blockingAt(int3(xVal, yVal, zVal)))
|
||||
{
|
||||
curt.blockingObjects.push_back(obj);
|
||||
curt.blocked = true;
|
||||
@ -444,14 +444,14 @@ const CGObjectInstance * CMap::getObjectiveObjectFrom(const int3 & pos, Obj type
|
||||
bestMatch = object;
|
||||
else
|
||||
{
|
||||
if (object->pos.dist2dSQ(pos) < bestMatch->pos.dist2dSQ(pos))
|
||||
if (object->anchorPos().dist2dSQ(pos) < bestMatch->anchorPos().dist2dSQ(pos))
|
||||
bestMatch = object;// closer than one we already found
|
||||
}
|
||||
}
|
||||
}
|
||||
assert(bestMatch != nullptr); // if this happens - victory conditions or map itself is very, very broken
|
||||
|
||||
logGlobal->error("Will use %s from %s", bestMatch->getObjectName(), bestMatch->pos.toString());
|
||||
logGlobal->error("Will use %s from %s", bestMatch->getObjectName(), bestMatch->anchorPos().toString());
|
||||
return bestMatch;
|
||||
}
|
||||
|
||||
@ -635,7 +635,7 @@ void CMap::addNewObject(CGObjectInstance * obj)
|
||||
void CMap::moveObject(CGObjectInstance * obj, const int3 & pos)
|
||||
{
|
||||
removeBlockVisTiles(obj);
|
||||
obj->pos = pos;
|
||||
obj->setAnchorPos(pos);
|
||||
addBlockVisTiles(obj);
|
||||
}
|
||||
|
||||
@ -803,7 +803,7 @@ void CMap::reindexObjects()
|
||||
if (lhs->isRemovable() && !rhs->isRemovable())
|
||||
return false;
|
||||
|
||||
return lhs->pos.y < rhs->pos.y;
|
||||
return lhs->anchorPos().y < rhs->anchorPos().y;
|
||||
});
|
||||
|
||||
// instanceNames don't change
|
||||
|
@ -615,7 +615,7 @@ std::string CInsertObjectOperation::getLabel() const
|
||||
CMoveObjectOperation::CMoveObjectOperation(CMap* map, CGObjectInstance* obj, const int3& targetPosition)
|
||||
: CMapOperation(map),
|
||||
obj(obj),
|
||||
initialPos(obj->pos),
|
||||
initialPos(obj->anchorPos()),
|
||||
targetPos(targetPosition)
|
||||
{
|
||||
}
|
||||
|
@ -913,7 +913,7 @@ void CMapLoaderH3M::loadArtifactsOfHero(CGHeroInstance * hero)
|
||||
|
||||
if(!hero->artifactsWorn.empty() || !hero->artifactsInBackpack.empty())
|
||||
{
|
||||
logGlobal->debug("Hero %d at %s has set artifacts twice (in map properties and on adventure map instance). Using the latter set...", hero->getHeroType().getNum(), hero->pos.toString());
|
||||
logGlobal->debug("Hero %d at %s has set artifacts twice (in map properties and on adventure map instance). Using the latter set...", hero->getHeroType().getNum(), hero->anchorPos().toString());
|
||||
|
||||
hero->artifactsInBackpack.clear();
|
||||
while(!hero->artifactsWorn.empty())
|
||||
@ -1651,7 +1651,7 @@ void CMapLoaderH3M::readObjects()
|
||||
if(!newObject)
|
||||
continue;
|
||||
|
||||
newObject->pos = mapPosition;
|
||||
newObject->setAnchorPos(mapPosition);
|
||||
newObject->ID = objectTemplate->id;
|
||||
newObject->id = objectInstanceID;
|
||||
if(newObject->ID != Obj::HERO && newObject->ID != Obj::HERO_PLACEHOLDER && newObject->ID != Obj::PRISON)
|
||||
|
@ -1072,7 +1072,7 @@ void CMapLoaderJson::MapObjectLoader::construct()
|
||||
|
||||
instance->id = ObjectInstanceID(static_cast<si32>(owner->map->objects.size()));
|
||||
instance->instanceName = jsonKey;
|
||||
instance->pos = pos;
|
||||
instance->setAnchorPos(pos);
|
||||
owner->map->addNewObject(instance);
|
||||
}
|
||||
|
||||
|
@ -1047,7 +1047,7 @@ void ChangeObjPos::applyGs(CGameState *gs)
|
||||
return;
|
||||
}
|
||||
gs->map->removeBlockVisTiles(obj);
|
||||
obj->pos = nPos + obj->getVisitableOffset();
|
||||
obj->setAnchorPos(nPos + obj->getVisitableOffset());
|
||||
gs->map->addBlockVisTiles(obj);
|
||||
}
|
||||
|
||||
@ -1467,7 +1467,7 @@ void GiveHero::applyGs(CGameState *gs)
|
||||
|
||||
h->setOwner(player);
|
||||
h->setMovementPoints(h->movementPointsLimit(true));
|
||||
h->pos = h->convertFromVisitablePos(oldVisitablePos);
|
||||
h->setAnchorPos(h->convertFromVisitablePos(oldVisitablePos));
|
||||
gs->map->heroesOnMap.emplace_back(h);
|
||||
gs->getPlayerState(h->getOwner())->addOwnedObject(h);
|
||||
|
||||
|
@ -87,7 +87,7 @@ const rmg::Area & Object::Instance::getAccessibleArea() const
|
||||
void Object::Instance::setPosition(const int3 & position)
|
||||
{
|
||||
dPosition = position;
|
||||
dObject.pos = dPosition + dParent.getPosition();
|
||||
dObject.setAnchorPos(dPosition + dParent.getPosition());
|
||||
|
||||
dBlockedAreaCache.clear();
|
||||
dAccessibleAreaCache.clear();
|
||||
@ -96,21 +96,21 @@ void Object::Instance::setPosition(const int3 & position)
|
||||
|
||||
void Object::Instance::setPositionRaw(const int3 & position)
|
||||
{
|
||||
if(!dObject.pos.valid())
|
||||
if(!dObject.anchorPos().valid())
|
||||
{
|
||||
dObject.pos = dPosition + dParent.getPosition();
|
||||
dObject.setAnchorPos(dPosition + dParent.getPosition());
|
||||
dBlockedAreaCache.clear();
|
||||
dAccessibleAreaCache.clear();
|
||||
dParent.clearCachedArea();
|
||||
}
|
||||
|
||||
auto shift = position + dParent.getPosition() - dObject.pos;
|
||||
auto shift = position + dParent.getPosition() - dObject.anchorPos();
|
||||
|
||||
dAccessibleAreaCache.translate(shift);
|
||||
dBlockedAreaCache.translate(shift);
|
||||
|
||||
dPosition = position;
|
||||
dObject.pos = dPosition + dParent.getPosition();
|
||||
dObject.setAnchorPos(dPosition + dParent.getPosition());
|
||||
}
|
||||
|
||||
void Object::Instance::setAnyTemplate(vstd::RNG & rng)
|
||||
@ -497,12 +497,12 @@ void Object::Instance::finalize(RmgMap & map, vstd::RNG & rng)
|
||||
}
|
||||
|
||||
if (dObject.isVisitable() && !map.isOnMap(dObject.visitablePos()))
|
||||
throw rmgException(boost::str(boost::format("Visitable tile %s of object %d at %s is outside the map") % dObject.visitablePos().toString() % dObject.id % dObject.pos.toString()));
|
||||
throw rmgException(boost::str(boost::format("Visitable tile %s of object %d at %s is outside the map") % dObject.visitablePos().toString() % dObject.id % dObject.anchorPos().toString()));
|
||||
|
||||
for(const auto & tile : dObject.getBlockedPos())
|
||||
{
|
||||
if(!map.isOnMap(tile))
|
||||
throw rmgException(boost::str(boost::format("Tile %s of object %d at %s is outside the map") % tile.toString() % dObject.id % dObject.pos.toString()));
|
||||
throw rmgException(boost::str(boost::format("Tile %s of object %d at %s is outside the map") % tile.toString() % dObject.id % dObject.anchorPos().toString()));
|
||||
}
|
||||
|
||||
for(const auto & tile : getBlockedArea().getTilesVector())
|
||||
|
@ -112,7 +112,7 @@ void QuestArtifactPlacer::placeQuestArtifacts(vstd::RNG & rand)
|
||||
|
||||
logGlobal->trace("Replacing %s at %s with the quest artifact %s",
|
||||
objectToReplace->getObjectName(),
|
||||
objectToReplace->getPosition().toString(),
|
||||
objectToReplace->anchorPos().toString(),
|
||||
VLC->artifacts()->getById(artifactToPlace)->getNameTranslated());
|
||||
|
||||
//Update appearance. Terrain is irrelevant.
|
||||
@ -121,7 +121,7 @@ void QuestArtifactPlacer::placeQuestArtifacts(vstd::RNG & rand)
|
||||
auto templates = handler->getTemplates();
|
||||
//artifactToReplace->appearance = templates.front();
|
||||
newObj->appearance = templates.front();
|
||||
newObj->pos = objectToReplace->pos;
|
||||
newObj->setAnchorPos(objectToReplace->anchorPos());
|
||||
mapProxy->insertObject(newObj);
|
||||
mapProxy->removeObject(objectToReplace);
|
||||
break;
|
||||
|
@ -209,7 +209,7 @@ ESpellCastResult SummonBoatMechanics::applyAdventureEffects(SpellCastEnvironment
|
||||
if(b->hero || b->layer != EPathfindingLayer::SAIL)
|
||||
continue; //we're looking for unoccupied boat
|
||||
|
||||
double nDist = b->pos.dist2d(parameters.caster->getHeroCaster()->visitablePos());
|
||||
double nDist = b->visitablePos().dist2d(parameters.caster->getHeroCaster()->visitablePos());
|
||||
if(!nearest || nDist < dist) //it's first boat or closer than previous
|
||||
{
|
||||
nearest = b;
|
||||
@ -669,11 +669,11 @@ const CGTownInstance * TownPortalMechanics::findNearestTown(SpellCastEnvironment
|
||||
return nullptr;
|
||||
|
||||
auto nearest = pool.cbegin(); //nearest town's iterator
|
||||
si32 dist = (*nearest)->pos.dist2dSQ(parameters.caster->getHeroCaster()->pos);
|
||||
si32 dist = (*nearest)->visitablePos().dist2dSQ(parameters.caster->getHeroCaster()->visitablePos());
|
||||
|
||||
for(auto i = nearest + 1; i != pool.cend(); ++i)
|
||||
{
|
||||
si32 curDist = (*i)->pos.dist2dSQ(parameters.caster->getHeroCaster()->pos);
|
||||
si32 curDist = (*i)->visitablePos().dist2dSQ(parameters.caster->getHeroCaster()->visitablePos());
|
||||
|
||||
if(curDist < dist)
|
||||
{
|
||||
|
@ -379,7 +379,7 @@ void MapHandler::drawObjects(QPainter & painter, int x, int y, int z, const std:
|
||||
|
||||
if(objData.objBitmap)
|
||||
{
|
||||
auto pos = obj->getPosition();
|
||||
auto pos = obj->anchorPos();
|
||||
|
||||
painter.drawImage(QPoint(x * tileSize, y * tileSize), *objData.objBitmap, object.rect, Qt::AutoColor | Qt::NoOpaqueDetection);
|
||||
|
||||
|
@ -115,7 +115,7 @@ std::string AbstractSettings::getMonsterName(const CMap & map, int objectIdx)
|
||||
std::string name;
|
||||
if(auto monster = dynamic_cast<const CGCreature*>(map.objects[objectIdx].get()))
|
||||
{
|
||||
name = boost::str(boost::format("%1% at %2%") % monster->getObjectName() % monster->getPosition().toString());
|
||||
name = boost::str(boost::format("%1% at %2%") % monster->getObjectName() % monster->anchorPos().toString());
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
@ -425,7 +425,7 @@ void ObjectsLayer::setDirty(const CGObjectInstance * object)
|
||||
{
|
||||
for(int i = 0; i < object->getWidth(); ++i)
|
||||
{
|
||||
setDirty(object->getPosition().x - i, object->getPosition().y - j);
|
||||
setDirty(object->anchorPos().x - i, object->anchorPos().y - j);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -479,7 +479,7 @@ void SelectionObjectsLayer::draw()
|
||||
{
|
||||
if(obj != newObject)
|
||||
{
|
||||
QRect bbox(obj->getPosition().x, obj->getPosition().y, 1, 1);
|
||||
QRect bbox(obj->anchorPos().x, obj->anchorPos().y, 1, 1);
|
||||
for(auto & t : obj->getBlockedPos())
|
||||
{
|
||||
QPoint topLeft(std::min(t.x, bbox.topLeft().x()), std::min(t.y, bbox.topLeft().y()));
|
||||
@ -496,7 +496,7 @@ void SelectionObjectsLayer::draw()
|
||||
if(selectionMode == SelectionMode::MOVEMENT && (shift.x() || shift.y()))
|
||||
{
|
||||
painter.setOpacity(0.7);
|
||||
auto newPos = QPoint(obj->getPosition().x, obj->getPosition().y) + shift;
|
||||
auto newPos = QPoint(obj->anchorPos().x, obj->anchorPos().y) + shift;
|
||||
handler->drawObjectAt(painter, obj, newPos.x(), newPos.y());
|
||||
}
|
||||
}
|
||||
@ -517,7 +517,7 @@ CGObjectInstance * SelectionObjectsLayer::selectObjectAt(int x, int y, const CGO
|
||||
if(!object.obj || object.obj == ignore || lockedObjects.count(object.obj))
|
||||
continue;
|
||||
|
||||
if(object.obj->visitableAt(x, y))
|
||||
if(object.obj->visitableAt(int3(x, y, scene->level)))
|
||||
{
|
||||
return const_cast<CGObjectInstance*>(object.obj);
|
||||
}
|
||||
@ -529,7 +529,7 @@ CGObjectInstance * SelectionObjectsLayer::selectObjectAt(int x, int y, const CGO
|
||||
if(!object.obj || object.obj == ignore || lockedObjects.count(object.obj))
|
||||
continue;
|
||||
|
||||
if(object.obj->blockingAt(x, y))
|
||||
if(object.obj->blockingAt(int3(x, y, scene->level)))
|
||||
{
|
||||
return const_cast<CGObjectInstance*>(object.obj);
|
||||
}
|
||||
@ -541,7 +541,7 @@ CGObjectInstance * SelectionObjectsLayer::selectObjectAt(int x, int y, const CGO
|
||||
if(!object.obj || object.obj == ignore || lockedObjects.count(object.obj))
|
||||
continue;
|
||||
|
||||
if(object.obj->coveringAt(x, y))
|
||||
if(object.obj->coveringAt(int3(x, y, scene->level)))
|
||||
{
|
||||
return const_cast<CGObjectInstance*>(object.obj);
|
||||
}
|
||||
|
@ -804,7 +804,7 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, EMovementMode moveme
|
||||
return false;
|
||||
}
|
||||
|
||||
logGlobal->trace("Player %d (%s) wants to move hero %d from %s to %s", asker, asker.toString(), hid.getNum(), h->pos.toString(), dst.toString());
|
||||
logGlobal->trace("Player %d (%s) wants to move hero %d from %s to %s", asker, asker.toString(), hid.getNum(), h->anchorPos().toString(), dst.toString());
|
||||
const int3 hmpos = h->convertToVisitablePos(dst);
|
||||
|
||||
if (!gs->map->isInTheMap(hmpos))
|
||||
@ -903,7 +903,7 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, EMovementMode moveme
|
||||
// should be called if hero changes tile but before applying TryMoveHero package
|
||||
auto leaveTile = [&]()
|
||||
{
|
||||
for (CGObjectInstance *obj : gs->map->getTile(int3(h->pos.x-1, h->pos.y, h->pos.z)).visitableObjects)
|
||||
for (CGObjectInstance *obj : gs->map->getTile(h->visitablePos()).visitableObjects)
|
||||
{
|
||||
obj->onHeroLeave(h);
|
||||
}
|
||||
@ -4223,8 +4223,11 @@ CGObjectInstance * CGameHandler::createNewObject(const int3 & visitablePosition,
|
||||
else
|
||||
o->appearance = handler->getTemplates().front();
|
||||
|
||||
if (o->isVisitable())
|
||||
o->setAnchorPos(visitablePosition + o->getVisitableOffset());
|
||||
else
|
||||
o->setAnchorPos(visitablePosition);
|
||||
|
||||
o->pos = visitablePosition + o->getVisitableOffset();
|
||||
return o;
|
||||
}
|
||||
|
||||
|
@ -283,7 +283,7 @@ void ApplyGhNetPackVisitor::visitTradeOnMarketplace(TradeOnMarketplace & pack)
|
||||
gh.throwAndComplain(&pack, "Can not trade - no hero!");
|
||||
|
||||
// TODO: check that object is actually being visited (e.g. Query exists)
|
||||
if (!object->visitableAt(hero->visitablePos().x, hero->visitablePos().y))
|
||||
if (!object->visitableAt(hero->visitablePos()))
|
||||
gh.throwAndComplain(&pack, "Can not trade - object not visited!");
|
||||
|
||||
if (object->getOwner().isValidPlayer() && gh.getPlayerRelations(object->getOwner(), hero->getOwner()) == PlayerRelations::ENEMIES)
|
||||
|
Loading…
Reference in New Issue
Block a user