Skip to content

Commit

Permalink
feat(fleets,hazards): to spawn condition in system fleets and hazar…
Browse files Browse the repository at this point in the history
…ds (endless-sky#8502)

Co-authored-by: warp-core <[email protected]>
Co-authored-by: TomGoodIdea <[email protected]>
Co-authored-by: Peter van der Meer <[email protected]>
  • Loading branch information
4 people authored Dec 22, 2024
1 parent 5bf9bd9 commit d5d3833
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 15 deletions.
15 changes: 9 additions & 6 deletions source/Engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1453,15 +1453,16 @@ void Engine::EnterSystem()
// Place five seconds worth of fleets and weather events. Check for
// undefined fleets by not trying to create anything with no
// government set.
ConditionsStore &conditions = player.Conditions();
for(int i = 0; i < 5; ++i)
{
for(const auto &fleet : system->Fleets())
if(fleet.Get()->GetGovernment() && Random::Int(fleet.Period()) < 60)
if(fleet.Get()->GetGovernment() && Random::Int(fleet.Period()) < 60 && fleet.CanTrigger(conditions))
fleet.Get()->Place(*system, newShips);

auto CreateWeather = [this](const RandomEvent<Hazard> &hazard, Point origin)
auto CreateWeather = [this, conditions](const RandomEvent<Hazard> &hazard, Point origin)
{
if(hazard.Get()->IsValid() && Random::Int(hazard.Period()) < 60)
if(hazard.Get()->IsValid() && Random::Int(hazard.Period()) < 60 && hazard.CanTrigger(conditions))
{
const Hazard *weather = hazard.Get();
int hazardLifetime = weather->RandomDuration();
Expand Down Expand Up @@ -1922,8 +1923,9 @@ void Engine::SpawnFleets()

// Non-mission NPCs spawn at random intervals in neighboring systems,
// or coming from planets in the current one.
ConditionsStore &conditions = player.Conditions();
for(const auto &fleet : player.GetSystem()->Fleets())
if(!Random::Int(fleet.Period()))
if(!Random::Int(fleet.Period()) && fleet.CanTrigger(conditions))
{
const Government *gov = fleet.Get()->GetGovernment();
if(!gov)
Expand Down Expand Up @@ -1996,9 +1998,10 @@ void Engine::SpawnPersons()
// Generate weather from the current system's hazards.
void Engine::GenerateWeather()
{
auto CreateWeather = [this](const RandomEvent<Hazard> &hazard, Point origin)
ConditionsStore &conditions = player.Conditions();
auto CreateWeather = [this, conditions](const RandomEvent<Hazard> &hazard, Point origin)
{
if(hazard.Get()->IsValid() && !Random::Int(hazard.Period()))
if(hazard.Get()->IsValid() && !Random::Int(hazard.Period()) && hazard.CanTrigger(conditions))
{
const Hazard *weather = hazard.Get();
// If a hazard has activated, generate a duration and strength of the
Expand Down
28 changes: 22 additions & 6 deletions source/RandomEvent.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,39 +15,55 @@ this program. If not, see <https://www.gnu.org/licenses/>.

#pragma once

#include "ConditionSet.h"
#include "ConditionsStore.h"
#include "DataNode.h"



// A class representing an event that triggers randomly
// in a given internal, for example fleets or hazards.
template <typename T>
class RandomEvent {
public:
constexpr RandomEvent(const T *event, int period) noexcept;
RandomEvent(const T *event, int period, const DataNode &node) noexcept;

constexpr const T *Get() const noexcept;
constexpr int Period() const noexcept;
const T *Get() const noexcept;
int Period() const noexcept;
bool CanTrigger(const ConditionsStore &tester) const;

private:
const T *event;
int period;
ConditionSet conditions;
};



template <typename T>
constexpr RandomEvent<T>::RandomEvent(const T *event, int period) noexcept
RandomEvent<T>::RandomEvent(const T *event, int period, const DataNode &node) noexcept
: event(event), period(period > 0 ? period : 200)
{
for(const auto &child : node)
if(child.Size() == 2 && child.Token(0) == "to" && child.Token(1) == "spawn")
conditions.Load(child);
// TODO: else with an error-message?
}

template <typename T>
constexpr const T *RandomEvent<T>::Get() const noexcept
const T *RandomEvent<T>::Get() const noexcept
{
return event;
}

template <typename T>
constexpr int RandomEvent<T>::Period() const noexcept
int RandomEvent<T>::Period() const noexcept
{
return period;
}

template <typename T>
bool RandomEvent<T>::CanTrigger(const ConditionsStore &tester) const
{
return conditions.IsEmpty() || conditions.Test(tester);
}
8 changes: 5 additions & 3 deletions source/System.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ void System::Load(const DataNode &node, Set<Planet> &planets)
}
}
else
fleets.emplace_back(fleet, child.Value(valueIndex + 1));
fleets.emplace_back(fleet, child.Value(valueIndex + 1), child);
}
else if(key == "raid")
RaidFleet::Load(raidFleets, child, remove, valueIndex);
Expand All @@ -297,7 +297,9 @@ void System::Load(const DataNode &node, Set<Planet> &planets)
}
}
else
hazards.emplace_back(hazard, child.Value(valueIndex + 1));
{
hazards.emplace_back(hazard, child.Value(valueIndex + 1), child);
}
}
else if(key == "belt")
{
Expand Down Expand Up @@ -1014,7 +1016,7 @@ void System::LoadObject(const DataNode &node, Set<Planet> &planets, int parent)
for(const DataNode &child : node)
{
if(child.Token(0) == "hazard" && child.Size() >= 3)
object.hazards.emplace_back(GameData::Hazards().Get(child.Token(1)), child.Value(2));
object.hazards.emplace_back(GameData::Hazards().Get(child.Token(1)), child.Value(2), child);
else if(child.Token(0) == "object")
LoadObject(child, planets, index);
else
Expand Down

0 comments on commit d5d3833

Please sign in to comment.