Skip to content

Commit

Permalink
feat(UI): Improve landing target selection when above a star (endless…
Browse files Browse the repository at this point in the history
…-sky#9444)

This PR adds a couple of improvements to the landing logic when hovering above star:
* If you're hovering above a planet as well, target the planet instead.
* Don't emit the fail sound if the player already has a target selected.
  • Loading branch information
quyykk authored Oct 22, 2023
1 parent e95fe17 commit 39acece
Showing 1 changed file with 28 additions and 10 deletions.
38 changes: 28 additions & 10 deletions source/AI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3994,29 +3994,47 @@ void AI::MovePlayer(Ship &ship, const PlayerInfo &player, Command &activeCommand
// Track all possible landable objects in the current system.
auto landables = vector<const StellarObject *>{};

// If the player is moving slowly over an uninhabited or inaccessible planet,
// display the default message explaining why they cannot land there.
string message;
const bool isMovingSlowly = (ship.Velocity().Length() < (MIN_LANDING_VELOCITY / 60.));
const StellarObject *potentialTarget = nullptr;
for(const StellarObject &object : ship.GetSystem()->Objects())
{
if(object.HasSprite() && object.HasValidPlanet() && object.GetPlanet()->IsAccessible(&ship))
landables.emplace_back(&object);
else if(object.HasSprite())
if(!object.HasSprite())
continue;

// If the player is moving slowly over an object, then the player is considering landing there.
// The target object might not be able to be landed on, for example an enemy planet or a star.
const bool isTryingLanding = (ship.Position().Distance(object.Position()) < object.Radius() && isMovingSlowly);
if(object.HasValidPlanet() && object.GetPlanet()->IsAccessible(&ship))
{
double distance = ship.Position().Distance(object.Position());
if(distance < object.Radius() && ship.Velocity().Length() < (MIN_LANDING_VELOCITY / 60.))
message = object.LandingMessage();
landables.emplace_back(&object);
if(isTryingLanding)
potentialTarget = &object;
}
else if(isTryingLanding)
message = object.LandingMessage();
}
if(!message.empty())
Audio::Play(Audio::Get("fail"));

const StellarObject *target = ship.GetTargetStellar();
// Require that the player's planetary target is one of the current system's planets.
auto landIt = find(landables.cbegin(), landables.cend(), target);
if(landIt == landables.cend())
target = nullptr;

// Consider the potential target as a landing target first.
if(!target && potentialTarget)
{
target = potentialTarget;
ship.SetTargetStellar(potentialTarget);
}

// If the player has a target in mind already, don't emit an error if the player
// is hovering above a star or inaccessible planet.
if(target)
message.clear();
else if(!message.empty())
Audio::Play(Audio::Get("fail"));

Messages::Importance messageImportance = Messages::Importance::High;

if(target && (ship.Zoom() < 1. || ship.Position().Distance(target->Position()) < target->Radius()))
Expand Down

0 comments on commit 39acece

Please sign in to comment.