Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ Template for new versions:
## New Features

## Fixes

- Fix broken weather lookup in ``World::ReadCurrentWeather``
- `timestream`: deal properly with units who have breathing difficulties

## Misc Improvements
- Added ``Coord2d`` and ``Coord3d`` C++ templates, providing a standard set operations for 2-tuples and 3-tuples of any numeric type
Expand Down
18 changes: 13 additions & 5 deletions plugins/timestream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -397,12 +397,21 @@ static bool detect_caravans()
});
}

static bool breathing_difficulties()
{
auto& units = df::global::world->units.all;
return std::any_of(units.begin(), units.end(), [] (auto u) { return Units::getBreathingState(u) != Units::breathing_state::FINE; });
}

static int32_t clamp_timeskip(int32_t timeskip) {
if (timeskip <= 0)
return 0;
// timeskip cannot be applied when caravans are loading/unloading because we don't know how to jog that timer
if (detect_caravans())
return 0;
// timeskip cannot be applied when any unit has breathing difficulties
if (breathing_difficulties())
return 0;
int32_t next_tick = *cur_year_tick + 1;
timeskip = std::min(timeskip, get_next_trigger_year_tick(next_tick) - next_tick);
timeskip = std::min(timeskip, get_next_birthday(next_tick) - next_tick);
Expand All @@ -418,22 +427,21 @@ static void increment_counter(T *obj, FT T::*field, int32_t timeskip) {
}

template <typename FT, typename T>
static void decrement_counter(T *obj, FT T::*field, int32_t timeskip) {
static void decrement_counter(T *obj, FT T::*field, int32_t timeskip, int32_t floor = 1) {
if (obj->*field <= 0)
return;
// TODO: check for overflow/underflow
int32_t cur_val = static_cast<int32_t>(obj->*field);
obj->*field = static_cast<FT>(std::max(1, cur_val - timeskip));
obj->*field = static_cast<FT>(std::max(floor, cur_val - timeskip));
}

static void adjust_unit_counters(df::unit * unit, int32_t timeskip) {
auto * c1 = &unit->counters;

decrement_counter(c1, &df::unit::T_counters::job_counter, timeskip);
decrement_counter(c1, &df::unit::T_counters::swap_counter, timeskip);
decrement_counter(c1, &df::unit::T_counters::winded, timeskip);
decrement_counter(c1, &df::unit::T_counters::stunned, timeskip);
decrement_counter(c1, &df::unit::T_counters::unconscious, timeskip);
decrement_counter(c1, &df::unit::T_counters::suffocation, timeskip);
decrement_counter(c1, &df::unit::T_counters::unconscious, timeskip, 2);
decrement_counter(c1, &df::unit::T_counters::webbed, timeskip);
decrement_counter(c1, &df::unit::T_counters::soldier_mood_countdown, timeskip);
decrement_counter(c1, &df::unit::T_counters::pain, timeskip);
Expand Down
Loading