Skip to content

Commit

Permalink
Merge branch 'develop' into wagonpathfix
Browse files Browse the repository at this point in the history
  • Loading branch information
dhthwy authored Dec 7, 2024
2 parents 2a1a734 + 1b861af commit d11dd6d
Show file tree
Hide file tree
Showing 12 changed files with 97 additions and 14 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ repos:
args: ['--fix=lf']
- id: trailing-whitespace
- repo: https://github.com/python-jsonschema/check-jsonschema
rev: 0.29.4
rev: 0.30.0
hooks:
- id: check-github-workflows
- repo: https://github.com/Lucas-C/pre-commit-hooks
Expand Down
2 changes: 2 additions & 0 deletions depends/lua/include/dfhack_llimits.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,10 @@ struct lua_extra_state {
#define luai_userstateopen(L) do { \
luai_mutex(L) = (mutex_t*)malloc(sizeof(mutex_t)); \
pthread_mutexattr_t attr; \
pthread_mutexattr_init(&attr); \
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); \
pthread_mutex_init(luai_mutex(L), &attr); \
pthread_mutexattr_destroy(&attr); \
} while (0)
#define luai_userstateclose(L) do { \
lua_unlock(L); \
Expand Down
10 changes: 6 additions & 4 deletions docs/changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,11 @@ Template for new versions:
- `tweak`: ``realistic-melting``: change melting return for inorganic armor parts, shields, weapons, trap components and tools to stop smelters from creating metal, bring melt return for adamantine in line with other metals to ~95% of forging cost. wear reduces melt return by 10% per level

## Fixes
- Fix mouse clicks bleeding through DFHack windows when clicking in the space between the frame and the window content in resizable windows
- Fix mouse clicks bleeding through resizable DFHack windows when clicking in the space between the frame and the window content
- `autobutcher`: don't run a scanning and marking cycle on the first tick of a fortress to allow for all custom configuration to be set first
- `nestboxes`: don't consider eggs to be infertile just because the mother has left the nest; eggs can still hatch in this situation
- `timestream`: adjust the incubation counter on fertile eggs so they hatch at the expected time
- `timestream`: adjust the timeout on traps so they can be re-triggered at normal rates
- `logistics`: don't ignore rotten items when applying stockpile logistics operations (e.g. autodump, autoclaim, etc.)

## Misc Improvements
Expand All @@ -74,12 +75,13 @@ Template for new versions:
- Quickfort blueprint library: ``aquifer_tap`` blueprint now designated at priority 3 and marks the stairway tile below the tap in "blueprint" mode to prevent drips while the drainage pipe is being prepared
- `preserve-rooms`: automatically release room reservations for captured squad members. we were kidding ourselves with our optimistic kept reservations. they're unlikely to come back : ((
- `buildingplan`: add value info to item selection dialog (effectively ungrouping items with different values) and add sorting by value
- `timestream`: reduce CPU utilization
- `fix/occupancy`: additionally handle the case where tile occupancy doesn't reflect the actual existence of a building
- `timestream`: improve FPS by a further 10%
- `fix/occupancy`: additionally handle the case where tile building occupancy needs to be set instead of cleared
- `orders`: ``orders sort`` now moves orders that are tied to a specific workshop to the top of the list in the overall manager orders screen

## Documentation
- Dreamfort: add link to Dreamfort tutorial youtube series: https://www.youtube.com/playlist?list=PLzXx9JcB9oXxmrtkO1y8ZXzBCFEZrKxve
- The error message that comes up if there is a version mismatch between DF and the installed DFHack now informs you which DF versions are supported by the installed version of DFHack
- The error message that comes up if there is a version mismatch between DF and DFHack now informs you which DF versions are supported by the installed version of DFHack

## API
- ``DFHack::Units``: new function ``setPathGoal``
Expand Down
5 changes: 4 additions & 1 deletion library/Core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,10 @@ void get_commands(color_ostream &con, std::vector<std::string> &commands) {
static bool try_autocomplete(color_ostream &con, const std::string &first, std::string &completed)
{
std::vector<std::string> commands, possible;
get_commands(con, commands);

// restore call to get_commands once we have updated the core lock to a deferred lock
// so calling Lua from the console thread won't deadlock if Lua is currently busy
//get_commands(con, commands);
for (auto &command : commands)
if (command.substr(0, first.size()) == first)
possible.push_back(command);
Expand Down
7 changes: 4 additions & 3 deletions library/modules/Units.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -642,13 +642,14 @@ bool Units::isDanger(df::unit *unit) {
if (isTame(unit) || isOwnGroup(unit))
return false;

// NOTE: demons from hell have visitor/visitor_unvited set to false
// other demons may visit as a diplomat
return isCrazed(unit)
|| isInvader(unit)
|| isOpposedToLife(unit)
|| isAgitated(unit)
|| isSemiMegabeast(unit)
|| isNightCreature(unit)
|| isGreatDanger(unit);
|| unit->flags2.bits.visitor_uninvited
|| ((isGreatDanger(unit) || isNightCreature(unit)) && !unit->flags2.bits.visitor);
}

bool Units::isGreatDanger(df::unit *unit) {
Expand Down
2 changes: 1 addition & 1 deletion library/xml
Submodule xml updated 1 files
+1 −1 .pre-commit-config.yaml
10 changes: 7 additions & 3 deletions plugins/orders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1011,8 +1011,12 @@ static command_result orders_clear_command(color_ostream & out)
return CR_OK;
}

static bool compare_freq(df::manager_order *a, df::manager_order *b)
static bool orders_compare(df::manager_order *a, df::manager_order *b)
{
if (a->workshop_id != b->workshop_id) {
return a->workshop_id >= 0;
}

if (a->frequency == df::manager_order::T_frequency::OneTime
|| b->frequency == df::manager_order::T_frequency::OneTime)
return a->frequency < b->frequency;
Expand All @@ -1025,11 +1029,11 @@ static command_result orders_sort_command(color_ostream & out)

if (!std::is_sorted(world->manager_orders.all.begin(),
world->manager_orders.all.end(),
compare_freq))
orders_compare))
{
std::stable_sort(world->manager_orders.all.begin(),
world->manager_orders.all.end(),
compare_freq);
orders_compare);
out << "Fixed priority of manager orders." << std::endl;
}

Expand Down
5 changes: 5 additions & 0 deletions plugins/preserve-rooms.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,11 @@ static void process_rooms(color_ostream &out,
auto it = last_known.begin();
auto it_end = last_known.end();
for (auto zone : vec) {
auto idx = linear_index(df::global::world->buildings.all, (df::building*)(zone));
if (idx == -1) {
WARN(cycle, out).print("invalid building pointer %p in building vector\n", zone);
continue;
}
if (!zone->assigned_unit) {
handle_missing_assignments(out, active_unit_ids, &it, it_end, share_with_spouse, zone->id);
continue;
Expand Down
17 changes: 17 additions & 0 deletions plugins/timestream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "df/activity_event_writest.h"
#include "df/activity_event_worshipst.h"
#include "df/building_nest_boxst.h"
#include "df/building_trapst.h"
#include "df/init.h"
#include "df/item_eggst.h"
#include "df/unit.h"
Expand Down Expand Up @@ -579,6 +580,21 @@ static void adjust_activities(color_ostream &out, int32_t timeskip) {
}
}

static void adjust_buildings(color_ostream &out, int32_t timeskip) {
// decrement trap timers
for (df::building_trapst *tr : world->buildings.other.TRAP) {
decrement_counter(tr, &df::building_trapst::ready_timeout, timeskip);
// used by pressure plates to delay until the plate is triggerable again
// other trap types never set this to a value higher than 1 so it is safe to decrement here
decrement_counter(tr, &df::building_trapst::state, timeskip);
}

for (df::building *bld : world->buildings.all) {
// assumes age > 0, but that will become true very quickly for all new buildings
increment_counter(bld, &df::building::age, timeskip);
}
}

static void adjust_items(color_ostream &out, int32_t timeskip) {
// increment incubation counters for fertile eggs in non-forbidden nestboxes
for (df::building_nest_boxst *nb : world->buildings.other.NEST_BOX) {
Expand Down Expand Up @@ -636,6 +652,7 @@ static void do_cycle(color_ostream &out) {

adjust_units(out, timeskip);
adjust_activities(out, timeskip);
adjust_buildings(out, timeskip);
adjust_items(out, timeskip);
}

Expand Down
2 changes: 1 addition & 1 deletion scripts
27 changes: 27 additions & 0 deletions test/modules/job.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
local utils = require('utils')

config.target = 'core'
config.mode = 'title' -- alters world state, not safe when a world is loaded

Expand All @@ -17,3 +19,28 @@ function test.removeJob()
expect.true_(dfhack.job.removeJob(job))
expect.nil_(df.global.world.jobs.list.next, 'job list is not empty after removeJob()')
end

-- EventManager job completion handling expects sorted order
function test.jobIDsAreSortedAfterAdd()
local job1 = df.job:new()
dfhack.job.linkIntoWorld(job1)

local job2 = df.job:new()
dfhack.job.linkIntoWorld(job2)

local is_sorted = true
local prev_id = nil

for _, job in utils.listpairs(df.global.world.jobs.list) do
if prev_id and job.id < prev_id then
is_sorted = false
break
end
prev_id = job.id
end

dfhack.job.removeJob(job1)
dfhack.job.removeJob(job2)

expect.true_(is_sorted)
end
22 changes: 22 additions & 0 deletions test/modules/job_fortress.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
local utils = require('utils')

config.target = 'core'
config.mode = 'fortress'

-- EventManager job completion handling expects sorted order
function test.jobIDsAreSorted()
local is_sorted = true
local prev_id = nil

-- assumes there are at least some "naturally added" jobs currently in the list
-- but this should always be true for CI test saves
for _, job in utils.listpairs(df.global.world.jobs.list) do
if prev_id and job.id < prev_id then
is_sorted = false
break
end
prev_id = job.id
end

expect.true_(is_sorted)
end

0 comments on commit d11dd6d

Please sign in to comment.