1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-08-10 22:31:40 +02:00

Merge pull request #5385 from IvanSavenko/advmap_select

[1.6.6] Clicking on blocked tile of a visitable object now builds a path to it
This commit is contained in:
Ivan Savenko
2025-02-09 19:16:12 +02:00
committed by GitHub
3 changed files with 44 additions and 41 deletions

View File

@@ -531,7 +531,6 @@ void AdventureMapInterface::onTileLeftClicked(const int3 &targetPosition)
bool canSelect = topBlocking && topBlocking->ID == Obj::HERO && topBlocking->tempOwner == LOCPLINT->playerID;
canSelect |= topBlocking && topBlocking->ID == Obj::TOWN && LOCPLINT->cb->getPlayerRelations(LOCPLINT->playerID, topBlocking->tempOwner) != PlayerRelations::ENEMIES;
bool isHero = false;
if(LOCPLINT->localState->getCurrentArmy()->ID != Obj::HERO) //hero is not selected (presumably town)
{
if(LOCPLINT->localState->getCurrentArmy() == topBlocking) //selected town clicked
@@ -541,9 +540,10 @@ void AdventureMapInterface::onTileLeftClicked(const int3 &targetPosition)
}
else if(const CGHeroInstance * currentHero = LOCPLINT->localState->getCurrentHero()) //hero is selected
{
isHero = true;
const CGPathNode *pn = LOCPLINT->getPathsInfo(currentHero)->getPathInfo(targetPosition);
const auto shipyard = dynamic_cast<const IShipyard *>(topBlocking);
if(currentHero == topBlocking) //clicked selected hero
{
LOCPLINT->openHeroWindow(currentHero);
@@ -554,10 +554,19 @@ void AdventureMapInterface::onTileLeftClicked(const int3 &targetPosition)
LOCPLINT->localState->setSelection(static_cast<const CArmedInstance*>(topBlocking));
return;
}
else if(shipyard != nullptr && pn->turns == 255 && LOCPLINT->cb->getPlayerRelations(LOCPLINT->playerID, topBlocking->tempOwner) != PlayerRelations::ENEMIES)
{
LOCPLINT->showShipyardDialogOrProblemPopup(shipyard);
}
else //still here? we need to move hero if we clicked end of already selected path or calculate a new path otherwise
{
int3 destinationTile = targetPosition;
if(topBlocking && topBlocking->isVisitable() && !topBlocking->visitableAt(destinationTile) && settings["gameTweaks"]["simpleObjectSelection"].Bool())
destinationTile = topBlocking->visitablePos();
if(LOCPLINT->localState->hasPath(currentHero) &&
LOCPLINT->localState->getPath(currentHero).endPos() == targetPosition &&
LOCPLINT->localState->getPath(currentHero).endPos() == destinationTile &&
!GH.isKeyboardShiftDown())//we'll be moving
{
assert(!CGI->mh->hasOngoingAnimations());
@@ -574,7 +583,7 @@ void AdventureMapInterface::onTileLeftClicked(const int3 &targetPosition)
}
else //remove old path and find a new one if we clicked on accessible tile
{
LOCPLINT->localState->setPath(currentHero, targetPosition);
LOCPLINT->localState->setPath(currentHero, destinationTile);
onHeroChanged(currentHero);
}
}
@@ -584,12 +593,6 @@ void AdventureMapInterface::onTileLeftClicked(const int3 &targetPosition)
{
throw std::runtime_error("Nothing is selected...");
}
const auto shipyard = ourInaccessibleShipyard(topBlocking);
if(isHero && shipyard != nullptr)
{
LOCPLINT->showShipyardDialogOrProblemPopup(shipyard);
}
}
void AdventureMapInterface::onTileHovered(const int3 &targetPosition)
@@ -690,6 +693,28 @@ void AdventureMapInterface::onTileHovered(const int3 &targetPosition)
showMoveDetailsInStatusbar(*hero, *pathNode);
}
if (objAtTile && pathNode->action == EPathNodeAction::UNKNOWN)
{
if(objAtTile->ID == Obj::TOWN && objRelations != PlayerRelations::ENEMIES)
{
CCS->curh->set(Cursor::Map::TOWN);
return;
}
else if(objAtTile->ID == Obj::HERO && objRelations == PlayerRelations::SAME_PLAYER)
{
CCS->curh->set(Cursor::Map::HERO);
return;
}
else if (objAtTile->ID == Obj::SHIPYARD && objRelations != PlayerRelations::ENEMIES)
{
CCS->curh->set(Cursor::Map::T1_SAIL);
return;
}
if(objAtTile->isVisitable() && !objAtTile->visitableAt(targetPosition) && settings["gameTweaks"]["simpleObjectSelection"].Bool())
pathNode = LOCPLINT->getPathsInfo(hero)->getPathInfo(objAtTile->visitablePos());
}
int turns = pathNode->turns;
vstd::amin(turns, 3);
switch(pathNode->action)
@@ -741,25 +766,10 @@ void AdventureMapInterface::onTileHovered(const int3 &targetPosition)
break;
default:
if(objAtTile && objRelations != PlayerRelations::ENEMIES)
{
if(objAtTile->ID == Obj::TOWN)
CCS->curh->set(Cursor::Map::TOWN);
else if(objAtTile->ID == Obj::HERO && objRelations == PlayerRelations::SAME_PLAYER)
CCS->curh->set(Cursor::Map::HERO);
else
CCS->curh->set(Cursor::Map::POINTER);
}
else
CCS->curh->set(Cursor::Map::POINTER);
break;
}
}
if(ourInaccessibleShipyard(objAtTile))
{
CCS->curh->set(Cursor::Map::T1_SAIL);
}
}
void AdventureMapInterface::showMoveDetailsInStatusbar(const CGHeroInstance & hero, const CGPathNode & pathNode)
@@ -848,18 +858,6 @@ Rect AdventureMapInterface::terrainAreaPixels() const
return widget->getMapView()->pos;
}
const IShipyard * AdventureMapInterface::ourInaccessibleShipyard(const CGObjectInstance *obj) const
{
const auto *ret = dynamic_cast<const IShipyard *>(obj);
if(!ret ||
obj->tempOwner != currentPlayerID ||
(CCS->curh->get<Cursor::Map>() != Cursor::Map::T1_SAIL && CCS->curh->get<Cursor::Map>() != Cursor::Map::POINTER))
return nullptr;
return ret;
}
void AdventureMapInterface::hotkeyExitWorldView()
{
setState(EAdventureState::MAKING_TURN);

View File

@@ -75,9 +75,6 @@ private:
/// updates active state of game window whenever game state changes
void adjustActiveness();
/// checks if obj is our ashipyard and cursor is 0,0 -> returns shipyard or nullptr else
const IShipyard * ourInaccessibleShipyard(const CGObjectInstance *obj) const;
/// check and if necessary reacts on scrolling by moving cursor to screen edge
void handleMapScrollingUpdate(uint32_t msPassed);

View File

@@ -719,6 +719,7 @@
"skipBattleIntroMusic",
"infoBarCreatureManagement",
"enableLargeSpellbook",
"simpleObjectSelection",
"skipAdventureMapAnimations"
],
"properties" : {
@@ -758,6 +759,13 @@
"type": "boolean",
"default": true
},
"simpleObjectSelection" : {
"type": "boolean",
"default": true,
"defaultIOS": true,
"defaultAndroid": true,
"defaultDesktop" : false
},
"skipAdventureMapAnimations": {
"type": "boolean",
"default": false