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)
|
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)
|
switch(obj->ID)
|
||||||
{
|
{
|
||||||
case Obj::TOWN:
|
case Obj::TOWN:
|
||||||
@ -1455,7 +1455,7 @@ bool AIGateway::moveHeroToTile(int3 dst, HeroPtr h)
|
|||||||
void AIGateway::buildStructure(const CGTownInstance * t, BuildingID building)
|
void AIGateway::buildStructure(const CGTownInstance * t, BuildingID building)
|
||||||
{
|
{
|
||||||
auto name = t->town->buildings.at(building)->getNameTranslated();
|
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;
|
cb->buildBuilding(t, building); //just do this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ void BuildThis::accept(AIGateway * ai)
|
|||||||
if(cb->canBuildStructure(town, b) == EBuildingState::ALLOWED)
|
if(cb->canBuildStructure(town, b) == EBuildingState::ALLOWED)
|
||||||
{
|
{
|
||||||
logAi->debug("Player %d will build %s in town of %s at %s",
|
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);
|
cb->buildBuilding(town, b);
|
||||||
|
|
||||||
return;
|
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()));
|
return sptr(VisitObj(o->id.getNum()));
|
||||||
else
|
else
|
||||||
return sptr(Explore());
|
return sptr(Explore());
|
||||||
|
@ -1032,7 +1032,7 @@ void VCAI::mainLoop()
|
|||||||
|
|
||||||
void VCAI::performObjectInteraction(const CGObjectInstance * obj, HeroPtr h)
|
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)
|
switch(obj->ID)
|
||||||
{
|
{
|
||||||
case Obj::TOWN:
|
case Obj::TOWN:
|
||||||
@ -1417,11 +1417,11 @@ void VCAI::wander(HeroPtr h)
|
|||||||
//TODO pick the truly best
|
//TODO pick the truly best
|
||||||
const CGTownInstance * t = *boost::max_element(townsNotReachable, compareReinforcements);
|
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());
|
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
|
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 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))
|
if(canRecruitAnyHero(t))
|
||||||
recruitHero(t);
|
recruitHero(t);
|
||||||
@ -1471,7 +1471,7 @@ void VCAI::wander(HeroPtr h)
|
|||||||
{
|
{
|
||||||
auto chosenObject = cb->getObjInstance(ObjectInstanceID(bestObjectGoal->objid));
|
auto chosenObject = cb->getObjInstance(ObjectInstanceID(bestObjectGoal->objid));
|
||||||
if(chosenObject != nullptr)
|
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
|
else
|
||||||
logAi->debug("Trying to realize goal of type %s as part of wandering.", bestObjectGoal->name());
|
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)
|
void VCAI::buildStructure(const CGTownInstance * t, BuildingID building)
|
||||||
{
|
{
|
||||||
auto name = t->town->buildings.at(building)->getNameTranslated();
|
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;
|
cb->buildBuilding(t, building); //just do this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2081,7 +2081,7 @@ void VCAI::tryRealize(Goals::BuildThis & g)
|
|||||||
if (cb->canBuildStructure(t, b) == EBuildingState::ALLOWED)
|
if (cb->canBuildStructure(t, b) == EBuildingState::ALLOWED)
|
||||||
{
|
{
|
||||||
logAi->debug("Player %d will build %s in town of %s at %s",
|
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);
|
cb->buildBuilding(t, b);
|
||||||
throw goalFulfilledException(sptr(g));
|
throw goalFulfilledException(sptr(g));
|
||||||
}
|
}
|
||||||
|
@ -375,7 +375,7 @@ void HeroMovementController::sendMovementRequest(const CGHeroInstance * h, const
|
|||||||
{
|
{
|
||||||
updateMovementSound(h, currNode.coord, nextNode.coord, nextNode.action);
|
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());
|
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)
|
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);
|
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)
|
for(const auto & tile : tiles)
|
||||||
{
|
{
|
||||||
int3 currTile = obj->pos + tile;
|
int3 currTile = obj->anchorPos() + tile;
|
||||||
|
|
||||||
if(LOCPLINT->cb->isInTheMap(currTile))
|
if(LOCPLINT->cb->isInTheMap(currTile))
|
||||||
objects[currTile.z][currTile.x][currTile.y].push_back(obj->id);
|
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))
|
if(context.objectTransparency(objectID, coordinates) > 0 && !context.isActiveHero(object))
|
||||||
{
|
{
|
||||||
visitable |= object->visitableAt(coordinates.x, coordinates.y);
|
visitable |= object->visitableAt(coordinates);
|
||||||
blocking |= object->blockingAt(coordinates.x, coordinates.y);
|
blocking |= object->blockingAt(coordinates);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,7 +120,7 @@ size_t MapRendererBaseContext::objectGroupIndex(ObjectInstanceID objectID) const
|
|||||||
Point MapRendererBaseContext::objectImageOffset(ObjectInstanceID objectID, const int3 & coordinates) const
|
Point MapRendererBaseContext::objectImageOffset(ObjectInstanceID objectID, const int3 & coordinates) const
|
||||||
{
|
{
|
||||||
const CGObjectInstance * object = getObject(objectID);
|
const CGObjectInstance * object = getObject(objectID);
|
||||||
int3 offsetTiles(object->getPosition() - coordinates);
|
int3 offsetTiles(object->anchorPos() - coordinates);
|
||||||
return Point(offsetTiles) * Point(32, 32);
|
return Point(offsetTiles) * Point(32, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -498,7 +498,7 @@ size_t MapRendererWorldViewContext::overlayImageIndex(const int3 & coordinates)
|
|||||||
{
|
{
|
||||||
const auto * object = getObject(objectID);
|
const auto * object = getObject(objectID);
|
||||||
|
|
||||||
if(!object->visitableAt(coordinates.x, coordinates.y))
|
if(!object->visitableAt(coordinates))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ObjectPosInfo info(object);
|
ObjectPosInfo info(object);
|
||||||
|
@ -49,9 +49,9 @@ void MapRendererContextState::addObject(const CGObjectInstance * obj)
|
|||||||
{
|
{
|
||||||
for(int fy = 0; fy < obj->getHeight(); ++fy)
|
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];
|
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)
|
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))
|
if(LOCPLINT->cb->isInTheMap(currTile))
|
||||||
{
|
{
|
||||||
|
@ -317,7 +317,7 @@ bool MapViewController::isEventVisible(const CGObjectInstance * obj, const Playe
|
|||||||
if(obj->isVisitable())
|
if(obj->isVisitable())
|
||||||
return context->isVisible(obj->visitablePos());
|
return context->isVisible(obj->visitablePos());
|
||||||
else
|
else
|
||||||
return context->isVisible(obj->pos);
|
return context->isVisible(obj->anchorPos());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MapViewController::isEventVisible(const CGHeroInstance * obj, const int3 & from, const int3 & dest)
|
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)
|
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();
|
result = object->getObjectName();
|
||||||
break;
|
break;
|
||||||
@ -103,15 +103,15 @@ bool CMapHandler::compareObjectBlitOrder(const CGObjectInstance * a, const CGObj
|
|||||||
|
|
||||||
for(const auto & aOffset : a->getBlockedOffsets())
|
for(const auto & aOffset : a->getBlockedOffsets())
|
||||||
{
|
{
|
||||||
int3 testTarget = a->pos + aOffset + int3(0, 1, 0);
|
int3 testTarget = a->anchorPos() + aOffset + int3(0, 1, 0);
|
||||||
if(b->blockingAt(testTarget.x, testTarget.y))
|
if(b->blockingAt(testTarget))
|
||||||
bBlocksA += 1;
|
bBlocksA += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(const auto & bOffset : b->getBlockedOffsets())
|
for(const auto & bOffset : b->getBlockedOffsets())
|
||||||
{
|
{
|
||||||
int3 testTarget = b->pos + bOffset + int3(0, 1, 0);
|
int3 testTarget = b->anchorPos() + bOffset + int3(0, 1, 0);
|
||||||
if(a->blockingAt(testTarget.x, testTarget.y))
|
if(a->blockingAt(testTarget))
|
||||||
aBlocksB += 1;
|
aBlocksB += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,8 +126,8 @@ bool CMapHandler::compareObjectBlitOrder(const CGObjectInstance * a, const CGObj
|
|||||||
return aBlocksB < bBlocksA;
|
return aBlocksB < bBlocksA;
|
||||||
|
|
||||||
// object that don't have clear priority via tile blocking will appear based on their row
|
// object that don't have clear priority via tile blocking will appear based on their row
|
||||||
if(a->pos.y != b->pos.y)
|
if(a->anchorPos().y != b->anchorPos().y)
|
||||||
return a->pos.y < b->pos.y;
|
return a->anchorPos().y < b->anchorPos().y;
|
||||||
|
|
||||||
// heroes should appear on top of objects on the same tile
|
// heroes should appear on top of objects on the same tile
|
||||||
if(b->ID==Obj::HERO && a->ID!=Obj::HERO)
|
if(b->ID==Obj::HERO && a->ID!=Obj::HERO)
|
||||||
|
@ -78,7 +78,7 @@ void CQuestMinimap::addQuestMarks (const QuestInfo * q)
|
|||||||
|
|
||||||
int3 tile;
|
int3 tile;
|
||||||
if (q->obj)
|
if (q->obj)
|
||||||
tile = q->obj->pos;
|
tile = q->obj->visitablePos();
|
||||||
else
|
else
|
||||||
tile = q->tile;
|
tile = q->tile;
|
||||||
|
|
||||||
@ -104,7 +104,7 @@ void CQuestMinimap::update()
|
|||||||
void CQuestMinimap::iconClicked()
|
void CQuestMinimap::iconClicked()
|
||||||
{
|
{
|
||||||
if(currentQuest->obj)
|
if(currentQuest->obj)
|
||||||
adventureInt->centerOnTile(currentQuest->obj->pos);
|
adventureInt->centerOnTile(currentQuest->obj->visitablePos());
|
||||||
//moveAdvMapSelection();
|
//moveAdvMapSelection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -539,7 +539,7 @@ EDiggingStatus CGameInfoCallback::getTileDigStatus(int3 tile, bool verbose) cons
|
|||||||
|
|
||||||
for(const auto & object : gs->map->objects)
|
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 EDiggingStatus::TILE_OCCUPIED;
|
||||||
}
|
}
|
||||||
return getTile(tile)->getDiggingStatus();
|
return getTile(tile)->getDiggingStatus();
|
||||||
|
@ -449,7 +449,7 @@ void CGameState::initGrailPosition()
|
|||||||
//remove tiles with holes
|
//remove tiles with holes
|
||||||
for(auto & elem : map->objects)
|
for(auto & elem : map->objects)
|
||||||
if(elem && elem->ID == Obj::HOLE)
|
if(elem && elem->ID == Obj::HOLE)
|
||||||
allowedPos -= elem->pos;
|
allowedPos -= elem->anchorPos();
|
||||||
|
|
||||||
if(!allowedPos.empty())
|
if(!allowedPos.empty())
|
||||||
{
|
{
|
||||||
@ -495,7 +495,7 @@ void CGameState::randomizeMapObjects()
|
|||||||
{
|
{
|
||||||
for (int j = 0; j < object->getHeight() ; j++)
|
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;
|
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)
|
for(auto town : map->towns)
|
||||||
{
|
{
|
||||||
if(town->getPosition() == townPos)
|
if(town->anchorPos() == townPos)
|
||||||
{
|
{
|
||||||
townPos = town->visitablePos();
|
townPos = town->visitablePos();
|
||||||
break;
|
break;
|
||||||
@ -545,8 +545,7 @@ void CGameState::placeStartingHero(const PlayerColor & playerColor, const HeroTy
|
|||||||
hero->setHeroType(heroTypeId);
|
hero->setHeroType(heroTypeId);
|
||||||
hero->tempOwner = playerColor;
|
hero->tempOwner = playerColor;
|
||||||
|
|
||||||
hero->pos = townPos;
|
hero->setAnchorPos(townPos + hero->getVisitableOffset());
|
||||||
hero->pos += hero->getVisitableOffset();
|
|
||||||
map->getEditManager()->insertObject(hero);
|
map->getEditManager()->insertObject(hero);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -614,7 +613,7 @@ void CGameState::initHeroes()
|
|||||||
auto boat = dynamic_cast<CGBoat*>(handler->create(callback, nullptr));
|
auto boat = dynamic_cast<CGBoat*>(handler->create(callback, nullptr));
|
||||||
handler->configureObject(boat, gs->getRandomGenerator());
|
handler->configureObject(boat, gs->getRandomGenerator());
|
||||||
|
|
||||||
boat->pos = hero->pos;
|
boat->setAnchorPos(hero->anchorPos());
|
||||||
boat->appearance = handler->getTemplates().front();
|
boat->appearance = handler->getTemplates().front();
|
||||||
boat->id = ObjectInstanceID(static_cast<si32>(gs->map->objects.size()));
|
boat->id = ObjectInstanceID(static_cast<si32>(gs->map->objects.size()));
|
||||||
|
|
||||||
@ -964,22 +963,18 @@ void CGameState::placeHeroesInTowns()
|
|||||||
{
|
{
|
||||||
for(CGTownInstance * t : player.second.getTowns())
|
for(CGTownInstance * t : player.second.getTowns())
|
||||||
{
|
{
|
||||||
if(h->visitablePos().z != t->visitablePos().z)
|
bool heroOnTownBlockableTile = t->blockingAt(h->visitablePos());
|
||||||
continue;
|
|
||||||
|
|
||||||
bool heroOnTownBlockableTile = t->blockingAt(h->visitablePos().x, h->visitablePos().y);
|
|
||||||
|
|
||||||
// current hero position is at one of blocking tiles of current town
|
// 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
|
// assume that this hero should be visiting the town (H3M format quirk) and move hero to correct position
|
||||||
if (heroOnTownBlockableTile)
|
if (heroOnTownBlockableTile)
|
||||||
{
|
{
|
||||||
int3 correctedPos = h->convertFromVisitablePos(t->visitablePos());
|
|
||||||
|
|
||||||
map->removeBlockVisTiles(h);
|
map->removeBlockVisTiles(h);
|
||||||
h->pos = correctedPos;
|
int3 correctedPos = h->convertFromVisitablePos(t->visitablePos());
|
||||||
|
h->setAnchorPos(correctedPos);
|
||||||
map->addBlockVisTiles(h);
|
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)
|
if(h->visitablePos().z != t->visitablePos().z)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (t->visitableAt(h->visitablePos().x, h->visitablePos().y))
|
if (t->visitableAt(h->visitablePos()))
|
||||||
{
|
{
|
||||||
assert(t->visitingHero == nullptr);
|
assert(t->visitingHero == nullptr);
|
||||||
t->setVisitingHero(h);
|
t->setVisitingHero(h);
|
||||||
@ -1066,7 +1061,7 @@ BattleField CGameState::battleGetBattlefieldType(int3 tile, vstd::RNG & rand)
|
|||||||
for(auto &obj : map->objects)
|
for(auto &obj : map->objects)
|
||||||
{
|
{
|
||||||
//look only for objects covering given tile
|
//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;
|
continue;
|
||||||
|
|
||||||
auto customBattlefield = obj->getBattlefield();
|
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)
|
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) &&
|
if ( map->isInTheMap(pos) &&
|
||||||
obj->coveringAt(pos.x, pos.y) &&
|
obj->coveringAt(pos) &&
|
||||||
isVisible(pos, *player))
|
isVisible(pos, *player))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -368,7 +368,7 @@ void CGameStateCampaign::replaceHeroesPlaceholders()
|
|||||||
heroToPlace->id = campaignHeroReplacement.heroPlaceholderId;
|
heroToPlace->id = campaignHeroReplacement.heroPlaceholderId;
|
||||||
if(heroPlaceholder->tempOwner.isValidPlayer())
|
if(heroPlaceholder->tempOwner.isValidPlayer())
|
||||||
heroToPlace->tempOwner = heroPlaceholder->tempOwner;
|
heroToPlace->tempOwner = heroPlaceholder->tempOwner;
|
||||||
heroToPlace->pos = heroPlaceholder->pos;
|
heroToPlace->setAnchorPos(heroPlaceholder->anchorPos());
|
||||||
heroToPlace->type = heroToPlace->getHeroType().toHeroType();
|
heroToPlace->type = heroToPlace->getHeroType().toHeroType();
|
||||||
heroToPlace->appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, heroToPlace->type->heroClass->getIndex())->getTemplates().front();
|
heroToPlace->appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, heroToPlace->type->heroClass->getIndex())->getTemplates().front();
|
||||||
|
|
||||||
@ -655,7 +655,7 @@ void CGameStateCampaign::initTowns()
|
|||||||
if (!owner->human)
|
if (!owner->human)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (town->pos != pi.posOfMainTown)
|
if (town->anchorPos() != pi.posOfMainTown)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
BuildingID newBuilding;
|
BuildingID newBuilding;
|
||||||
|
@ -33,7 +33,7 @@ std::string CGCreature::getHoverText(PlayerColor player) const
|
|||||||
if(stacks.empty())
|
if(stacks.empty())
|
||||||
{
|
{
|
||||||
//should not happen...
|
//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";
|
return "INVALID_STACK";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -562,7 +562,7 @@ bool CGCreature::containsUpgradedStack() const
|
|||||||
float c = 5325.181015f;
|
float c = 5325.181015f;
|
||||||
float d = 32788.727920f;
|
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;
|
return ((val % 32768) % 100) < 50;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -591,7 +591,7 @@ int CGCreature::getNumberOfStacks(const CGHeroInstance *hero) const
|
|||||||
ui32 c = 1943276003u;
|
ui32 c = 1943276003u;
|
||||||
ui32 d = 3174620878u;
|
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;
|
ui32 R2 = (R1 >> 16) & 0x7fff;
|
||||||
|
|
||||||
int R4 = R2 % 100 + 1;
|
int R4 = R2 % 100 + 1;
|
||||||
|
@ -1514,11 +1514,11 @@ bool CGHeroInstance::hasVisions(const CGObjectInstance * target, BonusSubtypeID
|
|||||||
if (visionsMultiplier > 0)
|
if (visionsMultiplier > 0)
|
||||||
vstd::amax(visionsRange, 3); //minimum range is 3 tiles, but only if VISIONS bonus present
|
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));
|
//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
|
std::string CGHeroInstance::getHeroTypeName() const
|
||||||
|
@ -54,14 +54,14 @@ MapObjectSubID CGObjectInstance::getObjTypeIndex() const
|
|||||||
return subID;
|
return subID;
|
||||||
}
|
}
|
||||||
|
|
||||||
int3 CGObjectInstance::getPosition() const
|
int3 CGObjectInstance::anchorPos() const
|
||||||
{
|
{
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
int3 CGObjectInstance::getTopVisiblePos() const
|
int3 CGObjectInstance::getTopVisiblePos() const
|
||||||
{
|
{
|
||||||
return pos - appearance->getTopVisibleOffset();
|
return anchorPos() - appearance->getTopVisibleOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGObjectInstance::setOwner(const PlayerColor & ow)
|
void CGObjectInstance::setOwner(const PlayerColor & ow)
|
||||||
@ -69,6 +69,11 @@ void CGObjectInstance::setOwner(const PlayerColor & ow)
|
|||||||
tempOwner = ow;
|
tempOwner = ow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CGObjectInstance::setAnchorPos(int3 newPos)
|
||||||
|
{
|
||||||
|
pos = newPos;
|
||||||
|
}
|
||||||
|
|
||||||
int CGObjectInstance::getWidth() const
|
int CGObjectInstance::getWidth() const
|
||||||
{
|
{
|
||||||
return appearance->getWidth();
|
return appearance->getWidth();
|
||||||
@ -79,32 +84,19 @@ int CGObjectInstance::getHeight() const
|
|||||||
return appearance->getHeight();
|
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
|
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
|
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
|
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
|
std::set<int3> CGObjectInstance::getBlockedPos() const
|
||||||
@ -115,7 +107,7 @@ std::set<int3> CGObjectInstance::getBlockedPos() const
|
|||||||
for(int h=0; h<getHeight(); ++h)
|
for(int h=0; h<getHeight(); ++h)
|
||||||
{
|
{
|
||||||
if(appearance->isBlockedAt(w, 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;
|
return ret;
|
||||||
@ -215,6 +207,8 @@ int CGObjectInstance::getSightRadius() const
|
|||||||
|
|
||||||
int3 CGObjectInstance::getVisitableOffset() const
|
int3 CGObjectInstance::getVisitableOffset() const
|
||||||
{
|
{
|
||||||
|
if (!isVisitable())
|
||||||
|
throw std::runtime_error("Attempt to access visitable offset of a non-visitable object!");
|
||||||
return appearance->getVisitableOffset();
|
return appearance->getVisitableOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -313,6 +307,9 @@ void CGObjectInstance::onHeroVisit( const CGHeroInstance * h ) const
|
|||||||
|
|
||||||
int3 CGObjectInstance::visitablePos() const
|
int3 CGObjectInstance::visitablePos() const
|
||||||
{
|
{
|
||||||
|
if (!isVisitable())
|
||||||
|
throw std::runtime_error("Attempt to access visitable position on a non-visitable object!");
|
||||||
|
|
||||||
return pos - getVisitableOffset();
|
return pos - getVisitableOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,8 +28,6 @@ using TObjectTypeHandler = std::shared_ptr<AObjectTypeHandler>;
|
|||||||
class DLL_LINKAGE CGObjectInstance : public IObjectInterface
|
class DLL_LINKAGE CGObjectInstance : public IObjectInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// Position of bottom-right corner of object on map
|
|
||||||
int3 pos;
|
|
||||||
/// Type of object, e.g. town, hero, creature.
|
/// Type of object, e.g. town, hero, creature.
|
||||||
MapObjectID ID;
|
MapObjectID ID;
|
||||||
/// Subtype of object, depends on type
|
/// Subtype of object, depends on type
|
||||||
@ -41,6 +39,9 @@ public:
|
|||||||
/// Defines appearance of object on map (animation, blocked tiles, blit order, etc)
|
/// Defines appearance of object on map (animation, blocked tiles, blit order, etc)
|
||||||
std::shared_ptr<const ObjectTemplate> appearance;
|
std::shared_ptr<const ObjectTemplate> appearance;
|
||||||
|
|
||||||
|
/// Position of bottom-right corner of object on map
|
||||||
|
int3 pos;
|
||||||
|
|
||||||
std::string instanceName;
|
std::string instanceName;
|
||||||
std::string typeName;
|
std::string typeName;
|
||||||
std::string subTypeName;
|
std::string subTypeName;
|
||||||
@ -62,21 +63,19 @@ public:
|
|||||||
return this->tempOwner;
|
return this->tempOwner;
|
||||||
}
|
}
|
||||||
void setOwner(const PlayerColor & ow);
|
void setOwner(const PlayerColor & ow);
|
||||||
|
void setAnchorPos(int3 pos);
|
||||||
|
|
||||||
/** APPEARANCE ACCESSORS **/
|
/** APPEARANCE ACCESSORS **/
|
||||||
|
|
||||||
int getWidth() const; //returns width of object graphic in tiles
|
int getWidth() const; //returns width of object graphic in tiles
|
||||||
int getHeight() const; //returns height of object graphic in tiles
|
int getHeight() const; //returns height of object graphic in tiles
|
||||||
int3 visitablePos() const override;
|
int3 visitablePos() const override;
|
||||||
int3 getPosition() const override;
|
int3 anchorPos() const override;
|
||||||
int3 getTopVisiblePos() const;
|
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 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 (x, y) (h3m pos)
|
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 (x, y) (h3m pos)
|
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
|
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
|
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;
|
return town->buildings.at(buildingID)->resources;
|
||||||
else
|
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();
|
return TResources();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,8 +56,6 @@ class DLL_LINKAGE CGTownInstance : public CGDwelling, public IShipyard, public I
|
|||||||
std::set<BuildingID> builtBuildings;
|
std::set<BuildingID> builtBuildings;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using CGDwelling::getPosition;
|
|
||||||
|
|
||||||
enum EFortLevel {NONE = 0, FORT = 1, CITADEL = 2, CASTLE = 3};
|
enum EFortLevel {NONE = 0, FORT = 1, CITADEL = 2, CASTLE = 3};
|
||||||
|
|
||||||
CTownAndVisitingHero townAndVis;
|
CTownAndVisitingHero townAndVis;
|
||||||
|
@ -614,7 +614,7 @@ void CGSeerHut::onHeroVisit(const CGHeroInstance * h) const
|
|||||||
|
|
||||||
int CGSeerHut::checkDirection() 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.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
|
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);
|
out.appendLocalString(EMetaText::ADVOB_TXT, 189);
|
||||||
break;
|
break;
|
||||||
case NO_WATER:
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ public:
|
|||||||
|
|
||||||
virtual PlayerColor getOwner() const = 0;
|
virtual PlayerColor getOwner() const = 0;
|
||||||
virtual int3 visitablePos() 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 onHeroVisit(const CGHeroInstance * h) const;
|
||||||
virtual void onHeroLeave(const CGHeroInstance * h) const;
|
virtual void onHeroLeave(const CGHeroInstance * h) const;
|
||||||
|
@ -111,7 +111,7 @@ void CGMine::initObj(vstd::RNG & rand)
|
|||||||
}
|
}
|
||||||
else
|
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;
|
producedResource = GameResID::GOLD;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -510,11 +510,11 @@ void CGMonolith::onHeroVisit( const CGHeroInstance * h ) const
|
|||||||
|
|
||||||
if(cb->isTeleportChannelImpassable(channel))
|
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;
|
td.impassable = true;
|
||||||
}
|
}
|
||||||
else if(getRandomExit(h) == ObjectInstanceID())
|
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
|
else
|
||||||
h->showInfoDialog(70);
|
h->showInfoDialog(70);
|
||||||
@ -574,7 +574,7 @@ void CGSubterraneanGate::onHeroVisit( const CGHeroInstance * h ) const
|
|||||||
if(cb->isTeleportChannelImpassable(channel))
|
if(cb->isTeleportChannelImpassable(channel))
|
||||||
{
|
{
|
||||||
h->showInfoDialog(153);//Just inside the entrance you find a large pile of rubble blocking the tunnel. You leave discouraged.
|
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;
|
td.impassable = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -602,13 +602,13 @@ void CGSubterraneanGate::postInit(IGameCallback * cb) //matches subterranean gat
|
|||||||
|
|
||||||
auto * hlp = dynamic_cast<CGSubterraneanGate *>(cb->gameState()->getObjInstance(obj->id));
|
auto * hlp = dynamic_cast<CGSubterraneanGate *>(cb->gameState()->getObjInstance(obj->id));
|
||||||
if(hlp)
|
if(hlp)
|
||||||
gatesSplit[hlp->pos.z].push_back(hlp);
|
gatesSplit[hlp->visitablePos().z].push_back(hlp);
|
||||||
}
|
}
|
||||||
|
|
||||||
//sort by position
|
//sort by position
|
||||||
std::sort(gatesSplit[0].begin(), gatesSplit[0].end(), [](const CGObjectInstance * a, const CGObjectInstance * b)
|
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)
|
auto assignToChannel = [&](CGSubterraneanGate * obj)
|
||||||
@ -631,7 +631,7 @@ void CGSubterraneanGate::postInit(IGameCallback * cb) //matches subterranean gat
|
|||||||
CGSubterraneanGate *checked = gatesSplit[1][j];
|
CGSubterraneanGate *checked = gatesSplit[1][j];
|
||||||
if(checked->channel != TeleportChannelID())
|
if(checked->channel != TeleportChannelID())
|
||||||
continue;
|
continue;
|
||||||
si32 hlp = checked->pos.dist2dSQ(objCurrent->pos);
|
si32 hlp = checked->visitablePos().dist2dSQ(objCurrent->visitablePos());
|
||||||
if(hlp < best.second)
|
if(hlp < best.second)
|
||||||
{
|
{
|
||||||
best.first = j;
|
best.first = j;
|
||||||
@ -657,11 +657,11 @@ void CGWhirlpool::onHeroVisit( const CGHeroInstance * h ) const
|
|||||||
TeleportDialog td(h->id, channel);
|
TeleportDialog td(h->id, channel);
|
||||||
if(cb->isTeleportChannelImpassable(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;
|
td.impassable = true;
|
||||||
}
|
}
|
||||||
else if(getRandomExit(h) == ObjectInstanceID())
|
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))
|
if(!isProtected(h))
|
||||||
{
|
{
|
||||||
@ -1086,9 +1086,9 @@ void CGMagi::onHeroVisit(const CGHeroInstance * h) const
|
|||||||
|
|
||||||
for(const auto & eye : eyes)
|
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);
|
cb->sendAndApply(fw);
|
||||||
cv.pos = eye->pos;
|
cv.pos = eye->visitablePos();
|
||||||
|
|
||||||
cb->sendAndApply(cv);
|
cb->sendAndApply(cv);
|
||||||
}
|
}
|
||||||
|
@ -56,9 +56,9 @@ int3 TownBuildingInstance::visitablePos() const
|
|||||||
return town->visitablePos();
|
return town->visitablePos();
|
||||||
}
|
}
|
||||||
|
|
||||||
int3 TownBuildingInstance::getPosition() const
|
int3 TownBuildingInstance::anchorPos() const
|
||||||
{
|
{
|
||||||
return town->getPosition();
|
return town->anchorPos();
|
||||||
}
|
}
|
||||||
|
|
||||||
TownRewardableBuildingInstance::TownRewardableBuildingInstance(IGameCallback *cb)
|
TownRewardableBuildingInstance::TownRewardableBuildingInstance(IGameCallback *cb)
|
||||||
|
@ -38,7 +38,7 @@ public:
|
|||||||
const IOwnableObject * asOwnable() const override;
|
const IOwnableObject * asOwnable() const override;
|
||||||
|
|
||||||
int3 visitablePos() const override;
|
int3 visitablePos() const override;
|
||||||
int3 getPosition() const override;
|
int3 anchorPos() const override;
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h)
|
template <typename Handler> void serialize(Handler &h)
|
||||||
{
|
{
|
||||||
|
@ -232,22 +232,22 @@ CMap::~CMap()
|
|||||||
|
|
||||||
void CMap::removeBlockVisTiles(CGObjectInstance * obj, bool total)
|
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)
|
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)
|
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)
|
if(xVal>=0 && xVal < width && yVal>=0 && yVal < height)
|
||||||
{
|
{
|
||||||
TerrainTile & curt = terrain[zVal][xVal][yVal];
|
TerrainTile & curt = terrain[zVal][xVal][yVal];
|
||||||
if(total || obj->visitableAt(xVal, yVal))
|
if(total || obj->visitableAt(int3(xVal, yVal, zVal)))
|
||||||
{
|
{
|
||||||
curt.visitableObjects -= obj;
|
curt.visitableObjects -= obj;
|
||||||
curt.visitable = curt.visitableObjects.size();
|
curt.visitable = curt.visitableObjects.size();
|
||||||
}
|
}
|
||||||
if(total || obj->blockingAt(xVal, yVal))
|
if(total || obj->blockingAt(int3(xVal, yVal, zVal)))
|
||||||
{
|
{
|
||||||
curt.blockingObjects -= obj;
|
curt.blockingObjects -= obj;
|
||||||
curt.blocked = curt.blockingObjects.size();
|
curt.blocked = curt.blockingObjects.size();
|
||||||
@ -259,22 +259,22 @@ void CMap::removeBlockVisTiles(CGObjectInstance * obj, bool total)
|
|||||||
|
|
||||||
void CMap::addBlockVisTiles(CGObjectInstance * obj)
|
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)
|
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)
|
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)
|
if(xVal>=0 && xVal < width && yVal >= 0 && yVal < height)
|
||||||
{
|
{
|
||||||
TerrainTile & curt = terrain[zVal][xVal][yVal];
|
TerrainTile & curt = terrain[zVal][xVal][yVal];
|
||||||
if(obj->visitableAt(xVal, yVal))
|
if(obj->visitableAt(int3(xVal, yVal, zVal)))
|
||||||
{
|
{
|
||||||
curt.visitableObjects.push_back(obj);
|
curt.visitableObjects.push_back(obj);
|
||||||
curt.visitable = true;
|
curt.visitable = true;
|
||||||
}
|
}
|
||||||
if(obj->blockingAt(xVal, yVal))
|
if(obj->blockingAt(int3(xVal, yVal, zVal)))
|
||||||
{
|
{
|
||||||
curt.blockingObjects.push_back(obj);
|
curt.blockingObjects.push_back(obj);
|
||||||
curt.blocked = true;
|
curt.blocked = true;
|
||||||
@ -444,14 +444,14 @@ const CGObjectInstance * CMap::getObjectiveObjectFrom(const int3 & pos, Obj type
|
|||||||
bestMatch = object;
|
bestMatch = object;
|
||||||
else
|
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
|
bestMatch = object;// closer than one we already found
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert(bestMatch != nullptr); // if this happens - victory conditions or map itself is very, very broken
|
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;
|
return bestMatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -635,7 +635,7 @@ void CMap::addNewObject(CGObjectInstance * obj)
|
|||||||
void CMap::moveObject(CGObjectInstance * obj, const int3 & pos)
|
void CMap::moveObject(CGObjectInstance * obj, const int3 & pos)
|
||||||
{
|
{
|
||||||
removeBlockVisTiles(obj);
|
removeBlockVisTiles(obj);
|
||||||
obj->pos = pos;
|
obj->setAnchorPos(pos);
|
||||||
addBlockVisTiles(obj);
|
addBlockVisTiles(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -803,7 +803,7 @@ void CMap::reindexObjects()
|
|||||||
if (lhs->isRemovable() && !rhs->isRemovable())
|
if (lhs->isRemovable() && !rhs->isRemovable())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return lhs->pos.y < rhs->pos.y;
|
return lhs->anchorPos().y < rhs->anchorPos().y;
|
||||||
});
|
});
|
||||||
|
|
||||||
// instanceNames don't change
|
// instanceNames don't change
|
||||||
|
@ -615,7 +615,7 @@ std::string CInsertObjectOperation::getLabel() const
|
|||||||
CMoveObjectOperation::CMoveObjectOperation(CMap* map, CGObjectInstance* obj, const int3& targetPosition)
|
CMoveObjectOperation::CMoveObjectOperation(CMap* map, CGObjectInstance* obj, const int3& targetPosition)
|
||||||
: CMapOperation(map),
|
: CMapOperation(map),
|
||||||
obj(obj),
|
obj(obj),
|
||||||
initialPos(obj->pos),
|
initialPos(obj->anchorPos()),
|
||||||
targetPos(targetPosition)
|
targetPos(targetPosition)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -913,7 +913,7 @@ void CMapLoaderH3M::loadArtifactsOfHero(CGHeroInstance * hero)
|
|||||||
|
|
||||||
if(!hero->artifactsWorn.empty() || !hero->artifactsInBackpack.empty())
|
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();
|
hero->artifactsInBackpack.clear();
|
||||||
while(!hero->artifactsWorn.empty())
|
while(!hero->artifactsWorn.empty())
|
||||||
@ -1651,7 +1651,7 @@ void CMapLoaderH3M::readObjects()
|
|||||||
if(!newObject)
|
if(!newObject)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
newObject->pos = mapPosition;
|
newObject->setAnchorPos(mapPosition);
|
||||||
newObject->ID = objectTemplate->id;
|
newObject->ID = objectTemplate->id;
|
||||||
newObject->id = objectInstanceID;
|
newObject->id = objectInstanceID;
|
||||||
if(newObject->ID != Obj::HERO && newObject->ID != Obj::HERO_PLACEHOLDER && newObject->ID != Obj::PRISON)
|
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->id = ObjectInstanceID(static_cast<si32>(owner->map->objects.size()));
|
||||||
instance->instanceName = jsonKey;
|
instance->instanceName = jsonKey;
|
||||||
instance->pos = pos;
|
instance->setAnchorPos(pos);
|
||||||
owner->map->addNewObject(instance);
|
owner->map->addNewObject(instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1047,7 +1047,7 @@ void ChangeObjPos::applyGs(CGameState *gs)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
gs->map->removeBlockVisTiles(obj);
|
gs->map->removeBlockVisTiles(obj);
|
||||||
obj->pos = nPos + obj->getVisitableOffset();
|
obj->setAnchorPos(nPos + obj->getVisitableOffset());
|
||||||
gs->map->addBlockVisTiles(obj);
|
gs->map->addBlockVisTiles(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1467,7 +1467,7 @@ void GiveHero::applyGs(CGameState *gs)
|
|||||||
|
|
||||||
h->setOwner(player);
|
h->setOwner(player);
|
||||||
h->setMovementPoints(h->movementPointsLimit(true));
|
h->setMovementPoints(h->movementPointsLimit(true));
|
||||||
h->pos = h->convertFromVisitablePos(oldVisitablePos);
|
h->setAnchorPos(h->convertFromVisitablePos(oldVisitablePos));
|
||||||
gs->map->heroesOnMap.emplace_back(h);
|
gs->map->heroesOnMap.emplace_back(h);
|
||||||
gs->getPlayerState(h->getOwner())->addOwnedObject(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)
|
void Object::Instance::setPosition(const int3 & position)
|
||||||
{
|
{
|
||||||
dPosition = position;
|
dPosition = position;
|
||||||
dObject.pos = dPosition + dParent.getPosition();
|
dObject.setAnchorPos(dPosition + dParent.getPosition());
|
||||||
|
|
||||||
dBlockedAreaCache.clear();
|
dBlockedAreaCache.clear();
|
||||||
dAccessibleAreaCache.clear();
|
dAccessibleAreaCache.clear();
|
||||||
@ -96,21 +96,21 @@ void Object::Instance::setPosition(const int3 & position)
|
|||||||
|
|
||||||
void Object::Instance::setPositionRaw(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();
|
dBlockedAreaCache.clear();
|
||||||
dAccessibleAreaCache.clear();
|
dAccessibleAreaCache.clear();
|
||||||
dParent.clearCachedArea();
|
dParent.clearCachedArea();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto shift = position + dParent.getPosition() - dObject.pos;
|
auto shift = position + dParent.getPosition() - dObject.anchorPos();
|
||||||
|
|
||||||
dAccessibleAreaCache.translate(shift);
|
dAccessibleAreaCache.translate(shift);
|
||||||
dBlockedAreaCache.translate(shift);
|
dBlockedAreaCache.translate(shift);
|
||||||
|
|
||||||
dPosition = position;
|
dPosition = position;
|
||||||
dObject.pos = dPosition + dParent.getPosition();
|
dObject.setAnchorPos(dPosition + dParent.getPosition());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Object::Instance::setAnyTemplate(vstd::RNG & rng)
|
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()))
|
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())
|
for(const auto & tile : dObject.getBlockedPos())
|
||||||
{
|
{
|
||||||
if(!map.isOnMap(tile))
|
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())
|
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",
|
logGlobal->trace("Replacing %s at %s with the quest artifact %s",
|
||||||
objectToReplace->getObjectName(),
|
objectToReplace->getObjectName(),
|
||||||
objectToReplace->getPosition().toString(),
|
objectToReplace->anchorPos().toString(),
|
||||||
VLC->artifacts()->getById(artifactToPlace)->getNameTranslated());
|
VLC->artifacts()->getById(artifactToPlace)->getNameTranslated());
|
||||||
|
|
||||||
//Update appearance. Terrain is irrelevant.
|
//Update appearance. Terrain is irrelevant.
|
||||||
@ -121,7 +121,7 @@ void QuestArtifactPlacer::placeQuestArtifacts(vstd::RNG & rand)
|
|||||||
auto templates = handler->getTemplates();
|
auto templates = handler->getTemplates();
|
||||||
//artifactToReplace->appearance = templates.front();
|
//artifactToReplace->appearance = templates.front();
|
||||||
newObj->appearance = templates.front();
|
newObj->appearance = templates.front();
|
||||||
newObj->pos = objectToReplace->pos;
|
newObj->setAnchorPos(objectToReplace->anchorPos());
|
||||||
mapProxy->insertObject(newObj);
|
mapProxy->insertObject(newObj);
|
||||||
mapProxy->removeObject(objectToReplace);
|
mapProxy->removeObject(objectToReplace);
|
||||||
break;
|
break;
|
||||||
|
@ -209,7 +209,7 @@ ESpellCastResult SummonBoatMechanics::applyAdventureEffects(SpellCastEnvironment
|
|||||||
if(b->hero || b->layer != EPathfindingLayer::SAIL)
|
if(b->hero || b->layer != EPathfindingLayer::SAIL)
|
||||||
continue; //we're looking for unoccupied boat
|
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
|
if(!nearest || nDist < dist) //it's first boat or closer than previous
|
||||||
{
|
{
|
||||||
nearest = b;
|
nearest = b;
|
||||||
@ -669,11 +669,11 @@ const CGTownInstance * TownPortalMechanics::findNearestTown(SpellCastEnvironment
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
auto nearest = pool.cbegin(); //nearest town's iterator
|
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)
|
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)
|
if(curDist < dist)
|
||||||
{
|
{
|
||||||
|
@ -379,7 +379,7 @@ void MapHandler::drawObjects(QPainter & painter, int x, int y, int z, const std:
|
|||||||
|
|
||||||
if(objData.objBitmap)
|
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);
|
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;
|
std::string name;
|
||||||
if(auto monster = dynamic_cast<const CGCreature*>(map.objects[objectIdx].get()))
|
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;
|
return name;
|
||||||
}
|
}
|
||||||
|
@ -425,7 +425,7 @@ void ObjectsLayer::setDirty(const CGObjectInstance * object)
|
|||||||
{
|
{
|
||||||
for(int i = 0; i < object->getWidth(); ++i)
|
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)
|
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())
|
for(auto & t : obj->getBlockedPos())
|
||||||
{
|
{
|
||||||
QPoint topLeft(std::min(t.x, bbox.topLeft().x()), std::min(t.y, bbox.topLeft().y()));
|
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()))
|
if(selectionMode == SelectionMode::MOVEMENT && (shift.x() || shift.y()))
|
||||||
{
|
{
|
||||||
painter.setOpacity(0.7);
|
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());
|
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))
|
if(!object.obj || object.obj == ignore || lockedObjects.count(object.obj))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(object.obj->visitableAt(x, y))
|
if(object.obj->visitableAt(int3(x, y, scene->level)))
|
||||||
{
|
{
|
||||||
return const_cast<CGObjectInstance*>(object.obj);
|
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))
|
if(!object.obj || object.obj == ignore || lockedObjects.count(object.obj))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(object.obj->blockingAt(x, y))
|
if(object.obj->blockingAt(int3(x, y, scene->level)))
|
||||||
{
|
{
|
||||||
return const_cast<CGObjectInstance*>(object.obj);
|
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))
|
if(!object.obj || object.obj == ignore || lockedObjects.count(object.obj))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(object.obj->coveringAt(x, y))
|
if(object.obj->coveringAt(int3(x, y, scene->level)))
|
||||||
{
|
{
|
||||||
return const_cast<CGObjectInstance*>(object.obj);
|
return const_cast<CGObjectInstance*>(object.obj);
|
||||||
}
|
}
|
||||||
|
@ -804,7 +804,7 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, EMovementMode moveme
|
|||||||
return false;
|
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);
|
const int3 hmpos = h->convertToVisitablePos(dst);
|
||||||
|
|
||||||
if (!gs->map->isInTheMap(hmpos))
|
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
|
// should be called if hero changes tile but before applying TryMoveHero package
|
||||||
auto leaveTile = [&]()
|
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);
|
obj->onHeroLeave(h);
|
||||||
}
|
}
|
||||||
@ -4223,8 +4223,11 @@ CGObjectInstance * CGameHandler::createNewObject(const int3 & visitablePosition,
|
|||||||
else
|
else
|
||||||
o->appearance = handler->getTemplates().front();
|
o->appearance = handler->getTemplates().front();
|
||||||
|
|
||||||
|
if (o->isVisitable())
|
||||||
|
o->setAnchorPos(visitablePosition + o->getVisitableOffset());
|
||||||
|
else
|
||||||
|
o->setAnchorPos(visitablePosition);
|
||||||
|
|
||||||
o->pos = visitablePosition + o->getVisitableOffset();
|
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,7 +283,7 @@ void ApplyGhNetPackVisitor::visitTradeOnMarketplace(TradeOnMarketplace & pack)
|
|||||||
gh.throwAndComplain(&pack, "Can not trade - no hero!");
|
gh.throwAndComplain(&pack, "Can not trade - no hero!");
|
||||||
|
|
||||||
// TODO: check that object is actually being visited (e.g. Query exists)
|
// 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!");
|
gh.throwAndComplain(&pack, "Can not trade - object not visited!");
|
||||||
|
|
||||||
if (object->getOwner().isValidPlayer() && gh.getPlayerRelations(object->getOwner(), hero->getOwner()) == PlayerRelations::ENEMIES)
|
if (object->getOwner().isValidPlayer() && gh.getPlayerRelations(object->getOwner(), hero->getOwner()) == PlayerRelations::ENEMIES)
|
||||||
|
Loading…
Reference in New Issue
Block a user