mirror of
https://github.com/vcmi/vcmi.git
synced 2025-04-11 11:31:52 +02:00
Clicking on blocked tile of a visitable object now builds a path to it
Suggestion from Discord. If player has hero selected, clicking on a blocked tile of a visitable, reachable object will now build a path to its visitable position (or move hero to it, in case of second click / tap). Objects that have interaction on left click (allied town and shipyards) are excluded from this change and work as before
This commit is contained in:
parent
2beb4c6aa4
commit
7803f7a972
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -719,6 +719,7 @@
|
||||
"skipBattleIntroMusic",
|
||||
"infoBarCreatureManagement",
|
||||
"enableLargeSpellbook",
|
||||
"simpleObjectSelection",
|
||||
"skipAdventureMapAnimations"
|
||||
],
|
||||
"properties" : {
|
||||
@ -758,6 +759,10 @@
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"simpleObjectSelection" : {
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"skipAdventureMapAnimations": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
|
Loading…
x
Reference in New Issue
Block a user