Skip to content

Commit

Permalink
feat(enhancement): Allow missions to mark systems of importance (endl…
Browse files Browse the repository at this point in the history
  • Loading branch information
Amazinite authored May 18, 2024
1 parent 954b814 commit a637e1e
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 8 deletions.
24 changes: 24 additions & 0 deletions source/GameAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,10 @@ void GameAction::LoadSingle(const DataNode &child)
music = child.Token(1);
else if(key == "mute")
music = "";
else if(key == "mark" && hasValue)
mark.insert(GameData::Systems().Get(child.Token(1)));
else if(key == "unmark" && hasValue)
unmark.insert(GameData::Systems().Get(child.Token(1)));
else if(key == "fail" && hasValue)
fail.insert(child.Token(1));
else if(key == "fail")
Expand Down Expand Up @@ -268,6 +272,10 @@ void GameAction::Save(DataWriter &out) const
}
for(auto &&it : events)
out.Write("event", it.first->Name(), it.second.first, it.second.second);
for(const System *system : mark)
out.Write("mark", system->Name());
for(const System *system : unmark)
out.Write("unmark", system->Name());
for(const string &name : fail)
out.Write("fail", name);
if(failCaller)
Expand Down Expand Up @@ -305,6 +313,14 @@ string GameAction::Validate() const
if(!outfit.first->IsDefined())
return "gift outfit \"" + outfit.first->TrueName() + "\"";

// Marked and unmarked system must be valid.
for(auto &&system : mark)
if(!system->IsValid())
return "system \"" + system->Name() + "\"";
for(auto &&system : unmark)
if(!system->IsValid())
return "system \"" + system->Name() + "\"";

// It is OK for this action to try to fail a mission that does not exist.
// (E.g. a plugin may be designed for interoperability with other plugins.)

Expand Down Expand Up @@ -395,6 +411,11 @@ void GameAction::Do(PlayerInfo &player, UI *ui, const Mission *caller) const
for(const auto &it : events)
player.AddEvent(*it.first, player.GetDate() + it.second.first);

for(const System *system : mark)
caller->Mark(system);
for(const System *system : unmark)
caller->Unmark(system);

if(!fail.empty())
{
// If this action causes this or any other mission to fail, mark that
Expand Down Expand Up @@ -465,5 +486,8 @@ GameAction GameAction::Instantiate(map<string, string> &subs, int jumps, int pay

result.conditions = conditions;

result.mark = mark;
result.unmark = unmark;

return result;
}
4 changes: 4 additions & 0 deletions source/GameAction.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class Mission;
class Outfit;
class PlayerInfo;
class Ship;
class System;
class UI;


Expand Down Expand Up @@ -101,6 +102,9 @@ class GameAction {

std::optional<std::string> music;

std::set<const System *> mark;
std::set<const System *> unmark;

// When this action is performed, the missions with these names fail.
std::set<std::string> fail;
// When this action is performed, the mission that called this action is failed.
Expand Down
10 changes: 10 additions & 0 deletions source/MapPanel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,14 @@ void MapPanel::DrawMiniMap(const PlayerInfo &player, float alpha, const System *
if(stopover->IsInSystem(&system))
DrawPointer(from, missionCounter, waypointColor, false);
}

for(const System *mark : mission.MarkedSystems())
{
if(missionCounter >= MAX_MISSION_POINTERS_DRAWN)
break;
if(mark == &system)
DrawPointer(from, missionCounter, waypointColor, false);
}
}
}

Expand Down Expand Up @@ -1473,6 +1481,8 @@ void MapPanel::DrawMissions()
DrawPointer(waypoint, missionCount[waypoint].drawn, waypointColor);
for(const Planet *stopover : mission.Stopovers())
DrawPointer(stopover->GetSystem(), missionCount[stopover->GetSystem()].drawn, waypointColor);
for(const System *mark : mission.MarkedSystems())
DrawPointer(mark, missionCount[mark].drawn, waypointColor);
}
// Draw the available and unavailable jobs.
for(auto &&it : missionCount)
Expand Down
65 changes: 58 additions & 7 deletions source/Mission.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,12 @@ void Mission::Load(const DataNode &node)
}
else if(child.Token(0) == "stopover" && child.HasChildren())
stopoverFilters.emplace_back(child);
else if(child.Token(0) == "mark" && child.Size() >= 2)
{
bool unmarked = child.Size() >= 3 && child.Token(2) == "unmarked";
set<const System *> &set = unmarked ? unmarkedSystems : markedSystems;
set.insert(GameData::Systems().Get(child.Token(1)));
}
else if(child.Token(0) == "substitutions" && child.HasChildren())
substitutions.Load(child);
else if(child.Token(0) == "npc")
Expand Down Expand Up @@ -451,6 +457,11 @@ void Mission::Save(DataWriter &out, const string &tag) const
for(const Planet *planet : visitedStopovers)
out.Write("stopover", planet->TrueName(), "visited");

for(const System *system : markedSystems)
out.Write("mark", system->Name());
for(const System *system : unmarkedSystems)
out.Write("mark", system->Name(), "unmarked");

for(const NPC &npc : npcs)
npc.Save(out);

Expand Down Expand Up @@ -535,6 +546,12 @@ bool Mission::IsValid() const
for(auto &&system : VisitedWaypoints())
if(!system->IsValid())
return false;
for(auto &&system : MarkedSystems())
if(!system->IsValid())
return false;
for(auto &&system : UnmarkedSystems())
if(!system->IsValid())
return false;

// Actions triggered when entering a system should reference valid systems.
for(auto &&it : onEnter)
Expand Down Expand Up @@ -629,6 +646,36 @@ const set<const Planet *> &Mission::VisitedStopovers() const



const set<const System *> &Mission::MarkedSystems() const
{
return markedSystems;
}



const set<const System *> &Mission::UnmarkedSystems() const
{
return unmarkedSystems;
}



void Mission::Mark(const System *system) const
{
markedSystems.insert(system);
unmarkedSystems.erase(system);
}



void Mission::Unmark(const System *system) const
{
if(markedSystems.erase(system))
unmarkedSystems.insert(system);
}



const string &Mission::Cargo() const
{
return cargo;
Expand Down Expand Up @@ -1239,6 +1286,7 @@ Mission Mission::Instantiate(const PlayerInfo &player, const shared_ptr<Ship> &b
result.repeat = repeat;
result.name = name;
result.waypoints = waypoints;
result.markedSystems = markedSystems;
// Handle waypoint systems that are chosen randomly.
const System *const sourceSystem = player.GetSystem();
for(const LocationFilter &filter : waypointFilters)
Expand Down Expand Up @@ -1405,20 +1453,23 @@ Mission Mission::Instantiate(const PlayerInfo &player, const shared_ptr<Ship> &b
subs["<stopovers>"] = stopovers;
subs["<planet stopovers>"] = planets;
}
// Waypoints: "<system name>" with "," and "and".
if(!result.waypoints.empty())
{
// Waypoints and marks: "<system name>" with "," and "and".
auto systemsReplacement = [](const set<const System *> &systemsSet) -> string {
string systems;
const System * const *last = &*--result.waypoints.end();
const System * const *last = &*--systemsSet.end();
int count = 0;
for(const System * const &system : result.waypoints)
for(const System * const &system : systemsSet)
{
if(count++)
systems += (&system != last) ? ", " : (count > 2 ? ", and " : " and ");
systems += system->Name();
}
subs["<waypoints>"] = systems;
}
return systems;
};
if(!result.waypoints.empty())
subs["<waypoints>"] = systemsReplacement(result.waypoints);
if(!result.markedSystems.empty())
subs["<marks>"] = systemsReplacement(result.markedSystems);

// Instantiate the NPCs. This also fills in the "<npc>" substitution.
string reason;
Expand Down
8 changes: 8 additions & 0 deletions source/Mission.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ class Mission {
const std::set<const System *> &VisitedWaypoints() const;
const std::set<const Planet *> &Stopovers() const;
const std::set<const Planet *> &VisitedStopovers() const;
const std::set<const System *> &MarkedSystems() const;
const std::set<const System *> &UnmarkedSystems() const;
void Mark(const System *system) const;
void Unmark(const System *system) const;
const std::string &Cargo() const;
int CargoSize() const;
int IllegalCargoFine() const;
Expand Down Expand Up @@ -247,6 +251,10 @@ class Mission {
std::list<LocationFilter> stopoverFilters;
std::set<const Planet *> visitedStopovers;
std::set<const System *> visitedWaypoints;
// Systems that don't need to be visited, but which the mission still
// wants to highlight for the player.
mutable std::set<const System *> markedSystems;
mutable std::set<const System *> unmarkedSystems;

// User-defined text replacements unique to this mission:
TextReplacements substitutions;
Expand Down
14 changes: 13 additions & 1 deletion source/MissionPanel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ namespace {
if(stopover->IsInSystem(system))
return true;

for(const System *mark : mission.MarkedSystems())
if(mark == system)
return true;

return false;
}

Expand Down Expand Up @@ -656,7 +660,7 @@ void MissionPanel::DrawKey() const
"Too little space to accept",
"Active job; go here to complete",
"Has unfinished requirements",
"Waypoint you must visit"
"System of importance"
};
int selected = -1;
if(availableIt != available.end())
Expand All @@ -679,9 +683,11 @@ void MissionPanel::DrawKey() const
void MissionPanel::DrawMissionSystem(const Mission &mission, const Color &color) const
{
auto toVisit = set<const System *>{mission.Waypoints()};
toVisit.insert(mission.MarkedSystems().begin(), mission.MarkedSystems().end());
for(const Planet *planet : mission.Stopovers())
toVisit.insert(planet->GetSystem());
auto hasVisited = set<const System *>{mission.VisitedWaypoints()};
hasVisited.insert(mission.UnmarkedSystems().begin(), mission.UnmarkedSystems().end());
for(const Planet *planet : mission.VisitedStopovers())
hasVisited.insert(planet->GetSystem());

Expand Down Expand Up @@ -1112,6 +1118,12 @@ void MissionPanel::CycleInvolvedSystems(const Mission &mission)
return;
}

for(const System *mark : mission.MarkedSystems())
if(++index == cycleInvolvedIndex)
{
CenterOnSystem(mark);
return;
}

cycleInvolvedIndex = 0;
CenterOnSystem(mission.Destination()->GetSystem());
Expand Down
2 changes: 2 additions & 0 deletions source/PlayerInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2405,6 +2405,8 @@ bool PlayerInfo::HasSeen(const System &system) const
return false;
if(m.Waypoints().count(&system))
return true;
if(m.MarkedSystems().count(&system))
return true;
for(auto &&p : m.Stopovers())
if(p->IsInSystem(&system))
return true;
Expand Down

0 comments on commit a637e1e

Please sign in to comment.