Skip to content

Commit 34d7188

Browse files
committed
Merge branch 'develop' into job-helpers
2 parents d1f3016 + c2007f0 commit 34d7188

File tree

14 files changed

+124
-52
lines changed

14 files changed

+124
-52
lines changed

.github/workflows/generate-symbols.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ jobs:
134134
+quit
135135
tar xjf dfhack-symbols-linux64-build.tar.bz2 -C DF_steam
136136
xml/symbols_gen_linux.sh ${{ inputs.version == 'auto' && '50.0' || inputs.version }} STEAM DF_steam
137-
if [ "${{ inputs.version }}" = "auto" ]; then
137+
if [ "${{ inputs.version }}" == "auto" ]; then
138138
while pgrep dwarfort; do
139139
echo "waiting for DF to exit"
140140
sleep 0.5

CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ cmake_policy(SET CMP0048 NEW)
66
cmake_policy(SET CMP0074 NEW)
77

88
# set up versioning.
9-
set(DF_VERSION "52.02")
10-
set(DFHACK_RELEASE "r2")
9+
set(DF_VERSION "52.03")
10+
set(DFHACK_RELEASE "r1.1")
1111
set(DFHACK_PRERELEASE FALSE)
1212

1313
set(DFHACK_VERSION "${DF_VERSION}-${DFHACK_RELEASE}")

docs/changelog.txt

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ Template for new versions:
3535
## Documentation
3636

3737
## API
38-
- Added GUI focus strings for new_arena: ``/Loading`` and ``/Mods``
3938

4039
## Lua
4140

@@ -57,6 +56,7 @@ Template for new versions:
5756
## New Features
5857

5958
## Fixes
59+
- ``Units::getReadableName`` will no longer append a comma to the names of histfigs with no profession
6060

6161
## Misc Improvements
6262

@@ -70,6 +70,45 @@ Template for new versions:
7070

7171
## Removed
7272

73+
# 52.03-r1.1
74+
75+
## New Tools
76+
77+
## New Features
78+
79+
## Fixes
80+
- job descriptions of mix dye job will display proper dye names
81+
82+
## Misc Improvements
83+
84+
## Documentation
85+
86+
## API
87+
88+
## Lua
89+
90+
## Removed
91+
92+
# 52.03-r1
93+
94+
## New Tools
95+
96+
## New Features
97+
98+
## Fixes
99+
- `preserve-rooms` will no longer hang on startup in the presence of a cycle in the replacement relationship of noble positions
100+
101+
## Misc Improvements
102+
103+
## Documentation
104+
105+
## API
106+
- Adjusted the logic inside ``Military::removeFromSquad`` to more closely match the game's own behavior
107+
108+
## Lua
109+
110+
## Removed
111+
73112
# 52.02-r2
74113

75114
## New Tools

docs/plugins/orders.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ game does not provide sufficient order conditions. Please enable ``automilk``,
151151
types of jobs.
152152

153153
Note that the jugs are specifically made out of wood. This is so, as long as
154-
you don't may any other "Tools" out of wood, you can have a stockpile just for
154+
you don't make any other "Tools" out of wood, you can have a stockpile just for
155155
jugs by restricting a finished goods stockpile to only take wooden tools.
156156

157157
Armok's additional note: "shleggings? Yes,

library/LuaApi.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,7 @@ void Lua::Push(lua_State *L, const Screen::Pen &info)
629629
return;
630630
}
631631

632-
new (L) Pen(info);
632+
Lua::make_lua_userdata<Pen>(L, info);
633633

634634
lua_rawgetp(L, LUA_REGISTRYINDEX, &DFHACK_PEN_TOKEN);
635635
lua_setmetatable(L, -2);
@@ -1128,7 +1128,7 @@ static int dfhack_random_init(lua_State *L)
11281128

11291129
static int dfhack_random_new(lua_State *L)
11301130
{
1131-
new (L) MersenneRNG();
1131+
Lua::make_lua_userdata<MersenneRNG>(L);
11321132

11331133
lua_rawgetp(L, LUA_REGISTRYINDEX, &DFHACK_RANDOM_TOKEN);
11341134
lua_setmetatable(L, -2);
@@ -1212,19 +1212,19 @@ static int dfhack_random_perlin(lua_State *L)
12121212
switch (size)
12131213
{
12141214
case 1: {
1215-
auto pdata = new (L) PerlinNoise1D<float>();
1215+
auto pdata = Lua::make_lua_userdata<PerlinNoise1D<float>>(L);
12161216
pdata->init(*prng);
12171217
lua_pushcclosure(L, eval_perlin_1, 1);
12181218
break;
12191219
}
12201220
case 2: {
1221-
auto pdata = new (L) PerlinNoise2D<float>();
1221+
auto pdata = Lua::make_lua_userdata<PerlinNoise2D<float>>(L);
12221222
pdata->init(*prng);
12231223
lua_pushcclosure(L, eval_perlin_2, 1);
12241224
break;
12251225
}
12261226
case 3: {
1227-
auto pdata = new (L) PerlinNoise3D<float>();
1227+
auto pdata = Lua::make_lua_userdata<PerlinNoise3D<float>>(L);
12281228
pdata->init(*prng);
12291229
lua_pushcclosure(L, eval_perlin_3, 1);
12301230
break;

library/LuaWrapper.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -168,12 +168,15 @@ static void BuildTypeMetatable(lua_State *state, const type_identity *type);
168168
void LuaWrapper::push_object_ref(lua_State *state, void *ptr)
169169
{
170170
// stack: [metatable]
171-
auto ref = (DFRefHeader*)lua_newuserdata(state, sizeof(DFRefHeader));
172-
ref->ptr = ptr;
173-
ref->field_info = NULL;
174-
ref->tag_ptr = NULL;
175-
ref->tag_identity = NULL;
176-
ref->tag_attr = NULL;
171+
void* stg = lua_newuserdata(state, sizeof(DFRefHeader));
172+
new (stg) DFRefHeader
173+
{
174+
.ptr = ptr,
175+
.field_info = NULL,
176+
.tag_ptr = NULL,
177+
.tag_identity = NULL,
178+
.tag_attr = NULL,
179+
};
177180

178181
lua_swap(state);
179182
lua_setmetatable(state, -2);

library/include/LuaTools.h

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,6 @@ distribution.
4444
#include <lua.h>
4545
#include <lauxlib.h>
4646

47-
/// Allocate a new user data object and push it on the stack
48-
inline void *operator new (std::size_t size, lua_State *L) {
49-
return lua_newuserdata(L, size);
50-
}
51-
5247
namespace DFHack {
5348
class function_identity_base;
5449
struct MaterialInfo;
@@ -67,6 +62,20 @@ namespace DFHack::Lua {
6762
*/
6863
DFHACK_EXPORT lua_State *Open(color_ostream &out, lua_State *state = NULL);
6964

65+
/**
66+
* Allocate a lua userdata and construct a C++ object in that userdata's storage space
67+
* The C++ object must be trivially destructible as lua GC will _not_ call the object's destructor
68+
* be aware that the created userdata is left on the Lua stack as well as returned to the caller
69+
*/
70+
template <typename T, typename... Args>
71+
requires (std::is_trivially_destructible_v<T>)
72+
T* make_lua_userdata(lua_State* L, Args&&... args)
73+
{
74+
void* stg = lua_newuserdata(L, sizeof(T));
75+
T * obj = ::new (stg) T(std::forward<Args>(args)...);
76+
return obj;
77+
}
78+
7079
DFHACK_EXPORT void PushDFHack(lua_State *state);
7180
DFHACK_EXPORT void PushBaseGlobals(lua_State *state);
7281

library/modules/Filesystem.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,8 @@ std::filesystem::path Filesystem::getInstallDir() noexcept
238238
std::filesystem::path Filesystem::getBaseDir() noexcept
239239
{
240240
auto getsavebase = []() {
241-
if (df::global::init->media.flag.is_set(df::enums::init_media_flags::PORTABLE_MODE))
241+
// assume portable mode is _on_ if init is missing
242+
if (!df::global::init || df::global::init->media.flag.is_set(df::enums::init_media_flags::PORTABLE_MODE))
242243
return DFSDL::DFSDL_GetBasePath();
243244
else
244245
return DFSDL::DFSDL_GetPrefPath("Bay 12 Games", "Dwarf Fortress");

library/modules/Job.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,9 @@ std::string Job::getName(df::job *job)
677677
button->matgloss = job->mat_index;
678678
button->specflag = job->specflag;
679679
button->job_item_flag = job->material_category;
680+
button->specdata = job->specdata;
681+
button->art_specifier_id1 = job->art_spec.id;
682+
button->art_specifier_id2 = job->art_spec.subid;
680683

681684
button->text(&desc);
682685
delete button;

library/modules/Military.cpp

Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -477,42 +477,53 @@ bool Military::addToSquad(int32_t unit_id, int32_t squad_id, int32_t squad_pos)
477477

478478
bool Military::removeFromSquad(int32_t unit_id)
479479
{
480+
// based on unitst::remove_squad_info
480481
df::unit *unit = df::unit::find(unit_id);
481482
if (unit == nullptr || unit->military.squad_id == -1 || unit->military.squad_position == -1)
482483
return false;
483484

484-
int32_t squad_id = unit->military.squad_id;
485-
df::squad* squad = df::squad::find(squad_id);
486-
if (squad == nullptr)
487-
return false;
485+
// abort individual training
486+
if (unit->individual_drills.size())
487+
unit->flags3.bits.verify_personal_training = true;
488488

489+
int32_t squad_id = unit->military.squad_id;
489490
int32_t squad_pos = unit->military.squad_position;
490-
df::squad_position* pos = vector_get(squad->positions, squad_pos);
491-
if (pos == nullptr)
492-
return false;
493491

494-
df::historical_figure* hf = df::historical_figure::find(unit->hist_figure_id);
495-
if (hf == nullptr)
496-
return false;
492+
df::squad* squad = df::squad::find(squad_id);
493+
494+
if (squad)
495+
{
496+
df::squad_position* pos = vector_get(squad->positions, squad_pos);
497+
if (pos)
498+
{
499+
// based on unitst::remove_squad_activity_info
500+
FOR_ENUM_ITEMS(squad_event_type, i)
501+
{
502+
auto activity_entry = df::activity_entry::find(pos->activities[i]);
503+
if (activity_entry)
504+
{
505+
auto activity_event = binsearch_in_vector(activity_entry->events, &df::activity_event::event_id, pos->events[i]);
506+
if (activity_event)
507+
{
508+
activity_event->removeParticipant(unit->hist_figure_id, unit->id, false);
509+
pos->activities[i] = -1;
510+
pos->events[i] = -1;
511+
}
512+
}
513+
}
497514

498-
// remove from squad information
499-
pos->occupant = -1;
515+
// remove from squad position
516+
pos->occupant = -1;
517+
}
518+
}
500519
// remove from unit information
501520
unit->military.squad_id = -1;
502521
unit->military.squad_position = -1;
503522

504-
// abort individual training
505-
if (unit->individual_drills.size()) {
506-
unit->flags3.bits.verify_personal_training = true;
507-
}
508-
509-
// remove unit from squad activities
510-
auto activity_entry = binsearch_in_vector(df::global::world->activities.all,&df::activity_entry::id,squad->activity);
511-
if (activity_entry) {
512-
for (auto const activity_event : activity_entry->events) {
513-
activity_event->removeParticipant(unit->hist_figure_id, unit->id, false);
514-
}
515-
}
523+
// remove entity squad link
524+
df::historical_figure* hf = df::historical_figure::find(unit->hist_figure_id);
525+
if (hf == nullptr || squad == nullptr)
526+
return false;
516527

517528
if (squad_pos == 0) // is unit a commander?
518529
remove_officer_entity_link(hf, squad);

0 commit comments

Comments
 (0)