Skip to content

Commit

Permalink
feat(enhancements): Missions can define how the distance to the desti…
Browse files Browse the repository at this point in the history
…nation is calculated (#6846)

Missions can take into account the use of wormholes or jump drives when calculating this distance. This influences deadlines and payment multipliers.
  • Loading branch information
warp-core authored Apr 8, 2023
1 parent 2ffadc8 commit 2464a81
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 15 deletions.
7 changes: 3 additions & 4 deletions EndlessSkyLib.cbp
Original file line number Diff line number Diff line change
Expand Up @@ -374,17 +374,18 @@
<Unit filename="source/Weather.cpp" />
<Unit filename="source/Weather.h" />
<Unit filename="source/WeightedList.h" />
<Unit filename="source/comparators/ByGivenOrder.h" />
<Unit filename="source/comparators/ByName.h" />
<Unit filename="source/Wormhole.cpp" />
<Unit filename="source/Wormhole.h" />
<Unit filename="source/WormholeStrategy.h" />
<Unit filename="source/opengl.cpp" />
<Unit filename="source/opengl.h" />
<Unit filename="source/pi.h" />
<Unit filename="source/shift.h" />
<Unit filename="source/comparators/ByGivenOrder.h" />
<Unit filename="source/comparators/ByName.h" />
<Unit filename="source/comparators/BySeriesAndIndex.h" />
<Unit filename="source/ship/ShipAICache.cpp" />
<Unit filename="source/ship/ShipAICache.h" />
<Unit filename="source/text/DisplayText.cpp" />
<Unit filename="source/text/DisplayText.h" />
<Unit filename="source/text/Font.cpp" />
Expand All @@ -402,8 +403,6 @@
<Unit filename="source/text/alignment.hpp" />
<Unit filename="source/text/layout.hpp" />
<Unit filename="source/text/truncate.hpp" />
<Unit filename="source/ship/ShipAICache.cpp" />
<Unit filename="source/ship/ShipAICache.h" />
<Extensions>
<editor_config active="1" use_tabs="1" tab_indents="1" tab_width="4" indent="4" eol_mode="0" />
<lib_finder disable_auto="1" />
Expand Down
7 changes: 4 additions & 3 deletions source/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -328,13 +328,14 @@ target_sources(EndlessSkyLib PRIVATE
WeightedList.h
Wormhole.cpp
Wormhole.h
comparators/ByGivenOrder.h
comparators/ByName.h
comparators/BySeriesAndIndex.h
WormholeStrategy.h
opengl.cpp
opengl.h
pi.h
shift.h
comparators/ByGivenOrder.h
comparators/ByName.h
comparators/BySeriesAndIndex.h
ship/ShipAICache.cpp
ship/ShipAICache.h
text/DisplayText.cpp
Expand Down
18 changes: 15 additions & 3 deletions source/DistanceMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,18 @@ using namespace std;
// it is a limit on how many systems should be returned. If it is below zero
// it specifies the maximum distance away that paths should be found.
DistanceMap::DistanceMap(const System *center, int maxCount, int maxDistance)
: center(center), maxCount(maxCount), maxDistance(maxDistance), useWormholes(false)
: DistanceMap(center, WormholeStrategy::NONE, false, maxCount, maxDistance)
{
}



// Constructor that allows configuring the use of wormholes and jump drive travel.
// Since no ship instance is available, we use the base game's default fuel for jump travel.
DistanceMap::DistanceMap(const System *center, WormholeStrategy wormholeStrategy,
bool useJumpDrive, int maxCount, int maxDistance)
: center(center), wormholeStrategy(wormholeStrategy), maxCount(maxCount),
maxDistance(maxDistance), jumpFuel(useJumpDrive ? 200 : 0), jumpRange(useJumpDrive ? 100. : 0.)
{
Init();
}
Expand Down Expand Up @@ -220,9 +231,10 @@ void DistanceMap::Init(const Ship *ship)

// Check for wormholes (which cost zero fuel). Wormhole travel should
// not be included in Local Maps or mission itineraries.
if(useWormholes)
if(wormholeStrategy != WormholeStrategy::NONE)
for(const StellarObject &object : top.next->Objects())
if(object.HasSprite() && object.HasValidPlanet() && object.GetPlanet()->IsWormhole())
if(object.HasSprite() && object.HasValidPlanet() && object.GetPlanet()->IsWormhole()
&& (object.GetPlanet()->IsUnrestricted() || wormholeStrategy == WormholeStrategy::ALL))
{
// If we're seeking a path toward a "source," travel through
// wormholes in the reverse of the normal direction.
Expand Down
8 changes: 7 additions & 1 deletion source/DistanceMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ this program. If not, see <https://www.gnu.org/licenses/>.
#ifndef DISTANCE_MAP_H_
#define DISTANCE_MAP_H_

#include "WormholeStrategy.h"

#include <map>
#include <queue>
#include <set>
Expand All @@ -37,6 +39,10 @@ class DistanceMap {
// Find paths to the given system. The optional arguments put a limit on how
// many systems will be returned and how far away they are allowed to be.
explicit DistanceMap(const System *center, int maxCount = -1, int maxDistance = -1);
// Find paths to the given system, potentially using wormholes, a jump drive, or both.
// Optional arguments are as above.
explicit DistanceMap(const System *center, WormholeStrategy wormholeStrategy,
bool useJumpDrive, int maxCount = -1, int maxDistance = -1);
// If a player is given, the map will only use hyperspace paths known to the
// player; that is, one end of the path has been visited. Also, if the
// player's flagship has a jump drive, the jumps will be make use of it.
Expand Down Expand Up @@ -106,13 +112,13 @@ class DistanceMap {
const PlayerInfo *player = nullptr;
const System *source = nullptr;
const System *center = nullptr;
WormholeStrategy wormholeStrategy = WormholeStrategy::ALL;
int maxCount = -1;
int maxDistance = -1;
// How much fuel is used for travel. If either value is zero, it means that
// the ship does not have that type of drive.
int hyperspaceFuel = 100;
int jumpFuel = 0;
bool useWormholes = true;
double jumpRange = 0.;
};

Expand Down
40 changes: 36 additions & 4 deletions source/Mission.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ this program. If not, see <https://www.gnu.org/licenses/>.
#include "UI.h"

#include <cmath>
#include <limits>
#include <sstream>

using namespace std;
Expand Down Expand Up @@ -159,6 +160,22 @@ void Mission::Load(const DataNode &node)
if(child.Size() >= 3)
deadlineMultiplier += child.Value(2);
}
else if(child.Token(0) == "distance calculation settings" && child.HasChildren())
{
for(const DataNode &grand : child)
{
if(grand.Token(0) == "no wormholes")
distanceCalcSettings.wormholeStrategy = WormholeStrategy::NONE;
else if(grand.Token(0) == "only unrestricted wormholes")
distanceCalcSettings.wormholeStrategy = WormholeStrategy::ONLY_UNRESTRICTED;
else if(grand.Token(0) == "all wormholes")
distanceCalcSettings.wormholeStrategy = WormholeStrategy::ALL;
else if(grand.Token(0) == "assumes jump drive")
distanceCalcSettings.assumesJumpDrive = true;
else
grand.PrintTrace("Invalid \"distance calculation settings\" child:");
}
}
else if(child.Token(0) == "cargo" && child.Size() >= 3)
{
cargo = child.Token(1);
Expand Down Expand Up @@ -1479,18 +1496,33 @@ int Mission::CalculateJumps(const System *sourceSystem)
while(!destinations.empty())
{
// Find the closest destination to this location.
DistanceMap distance(sourceSystem);
DistanceMap distance(sourceSystem,
distanceCalcSettings.wormholeStrategy,
distanceCalcSettings.assumesJumpDrive);
auto it = destinations.begin();
auto bestIt = it;
int bestDays = distance.Days(*bestIt);
if(bestDays < 0)
bestDays = numeric_limits<int>::max();
for(++it; it != destinations.end(); ++it)
if(distance.Days(*it) < distance.Days(*bestIt))
{
int days = distance.Days(*it);
if(days >= 0 && days < bestDays)
{
bestIt = it;
bestDays = days;
}
}

sourceSystem = *bestIt;
expectedJumps += distance.Days(*bestIt);
// If currently unreachable, this system adds -1 to the deadline, to match previous behavior.
expectedJumps += bestDays == numeric_limits<int>::max() ? -1 : bestDays;
destinations.erase(bestIt);
}
DistanceMap distance(sourceSystem);
DistanceMap distance(sourceSystem,
distanceCalcSettings.wormholeStrategy,
distanceCalcSettings.assumesJumpDrive);
// If currently unreachable, this system adds -1 to the deadline, to match previous behavior.
expectedJumps += distance.Days(destination->GetSystem());

return expectedJumps;
Expand Down
9 changes: 9 additions & 0 deletions source/Mission.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ this program. If not, see <https://www.gnu.org/licenses/>.
#include "MissionAction.h"
#include "NPC.h"
#include "TextReplacements.h"
#include "WormholeStrategy.h"

#include <list>
#include <map>
Expand Down Expand Up @@ -181,6 +182,13 @@ class Mission {
Mission Instantiate(const PlayerInfo &player, const std::shared_ptr<Ship> &boardingShip = nullptr) const;


private:
struct DistanceCalculationSettings {
WormholeStrategy wormholeStrategy = WormholeStrategy::NONE;
bool assumesJumpDrive = false;
};


private:
bool Enter(const System *system, PlayerInfo &player, UI *ui);
// For legacy code, contraband definitions can be placed in two different
Expand All @@ -207,6 +215,7 @@ class Mission {
int expectedJumps = 0;
int deadlineBase = 0;
int deadlineMultiplier = 0;
DistanceCalculationSettings distanceCalcSettings;
std::string clearance;
LocationFilter clearanceFilter;
bool hasFullClearance = true;
Expand Down
35 changes: 35 additions & 0 deletions source/WormholeStrategy.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/* WormholeStrategy.h
Copyright (c) 2022 by warp-core
Endless Sky is free software: you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or (at your option) any later version.
Endless Sky is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <https://www.gnu.org/licenses/>.
*/

#ifndef WORMHOLE_STRATEGY_H_
#define WORMHOLE_STRATEGY_H_

#include <cstdint>



// Strategies that a DistanceMap can use to determine which wormholes to make use of
// when plotting a course to a destination, if any.
enum class WormholeStrategy : int_fast8_t {
// Disallow use of any wormholes.
NONE,
// Disallow use of wormholes which the player cannot access, such as in
// the case of a wormhole that requires an attribute to use.
ONLY_UNRESTRICTED,
// Allow use of all wormholes.
ALL,
};

#endif

0 comments on commit 2464a81

Please sign in to comment.