diff --git a/NEWS b/NEWS index d0ea094c8..67da3563b 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,7 @@ DFHack Future Fixed numerous (mostly Lua-related) crashes on OS X by including a more up-to-date libstdc++ Alt should no longer get stuck on Windows (and perhaps other platforms as well) advfort works again + autobutcher takes sexualities into account devel/export-dt-ini: Updated for 0.40.20+ digfort: now checks file type and existence exportlegends: Fixed map export @@ -13,6 +14,7 @@ DFHack Future mousequery: Changed box-select key to Alt+M plugins/dwarfmonitor: correct date display (month index, separator) scripts/putontable: added to the readme + siren should work again stderr.log: removed excessive debug output on OS X trackstop: No longer prevents cancelling the removal of a track stop or roller. Fixed a display issue with PRINT_MODE:TEXT diff --git a/plugins/zone.cpp b/plugins/zone.cpp index 386200d41..f6a525581 100644 --- a/plugins/zone.cpp +++ b/plugins/zone.cpp @@ -67,6 +67,7 @@ using namespace std; #include "df/general_ref_building_civzone_assignedst.h" #include #include +#include "df/unit_soul.h" #include "df/viewscreen_dwarfmodest.h" #include "modules/Translation.h" @@ -345,6 +346,7 @@ bool isHunter(df::unit* unit); bool isOwnCiv(df::unit* unit); bool isMerchant(df::unit* unit); bool isForest(df::unit* unit); +bool isGay(df::unit* unit); bool isActivityZone(df::building * building); bool isPenPasture(df::building * building); @@ -705,6 +707,13 @@ int getUnitIndexFromId(df::unit* unit_) return -1; } +bool isGay(df::unit* unit) +{ + df::orientation_flags orientation = unit->status.current_soul->orientation_flags; + return isFemale(unit) && ! (orientation.whole & (orientation.mask_marry_male | orientation.mask_romance_male)) + || ! isFemale(unit) && ! (orientation.whole & (orientation.mask_marry_female | orientation.mask_romance_female)); +} + // dump some unit info void unitInfo(color_ostream & out, df::unit* unit, bool verbose = false) { @@ -2796,13 +2805,18 @@ public: int mk_prot; int ma_prot; - // bah, this should better be an array of 4 vectors - // that way there's no need for the 4 ugly process methods + // butcherable units vector fk_ptr; vector mk_ptr; vector fa_ptr; vector ma_ptr; + // priority butcherable units + vector fk_pri_ptr; + vector mk_pri_ptr; + vector fa_pri_ptr; + vector ma_pri_ptr; + WatchedRace(bool watch, int id, int _fk, int _mk, int _fa, int _ma) { isWatched = watch; @@ -2856,6 +2870,10 @@ public: sort(mk_ptr.begin(), mk_ptr.end(), compareUnitAgesOlder); sort(fa_ptr.begin(), fa_ptr.end(), compareUnitAgesYounger); sort(ma_ptr.begin(), ma_ptr.end(), compareUnitAgesYounger); + sort(fk_pri_ptr.begin(), fk_pri_ptr.end(), compareUnitAgesOlder); + sort(mk_pri_ptr.begin(), mk_pri_ptr.end(), compareUnitAgesOlder); + sort(fa_pri_ptr.begin(), fa_pri_ptr.end(), compareUnitAgesYounger); + sort(ma_pri_ptr.begin(), ma_pri_ptr.end(), compareUnitAgesYounger); } void PushUnit(df::unit * unit) @@ -2876,6 +2894,24 @@ public: } } + void PushPriorityUnit(df::unit * unit) + { + if(isFemale(unit)) + { + if(isBaby(unit) || isChild(unit)) + fk_pri_ptr.push_back(unit); + else + fa_pri_ptr.push_back(unit); + } + else + { + if(isBaby(unit) || isChild(unit)) + mk_pri_ptr.push_back(unit); + else + ma_pri_ptr.push_back(unit); + } + } + void PushProtectedUnit(df::unit * unit) { if(isFemale(unit)) @@ -2901,55 +2937,27 @@ public: mk_ptr.clear(); fa_ptr.clear(); ma_ptr.clear(); + fk_pri_ptr.clear(); + mk_pri_ptr.clear(); + fa_pri_ptr.clear(); + ma_pri_ptr.clear(); } - int ProcessUnits_fk() - { - int subcount = 0; - while(fk_ptr.size() && (fk_ptr.size() + fk_prot > fk) ) - { - df::unit* unit = fk_ptr.back(); - doMarkForSlaughter(unit); - fk_ptr.pop_back(); - subcount++; - } - return subcount; - } - - int ProcessUnits_mk() - { - int subcount = 0; - while(mk_ptr.size() && (mk_ptr.size() + mk_prot > mk) ) - { - df::unit* unit = mk_ptr.back(); - doMarkForSlaughter(unit); - mk_ptr.pop_back(); - subcount++; - } - return subcount; - } - - int ProcessUnits_fa() + int ProcessUnits(vector& unit_ptr, vector& unit_pri_ptr, int prot, int goal) { int subcount = 0; - while(fa_ptr.size() && (fa_ptr.size() + fa_prot > fa) ) + while(unit_pri_ptr.size() && (unit_ptr.size() + unit_pri_ptr.size() + prot > goal) ) { - df::unit* unit = fa_ptr.back(); + df::unit* unit = unit_pri_ptr.back(); doMarkForSlaughter(unit); - fa_ptr.pop_back(); + unit_pri_ptr.pop_back(); subcount++; } - return subcount; - } - - int ProcessUnits_ma() - { - int subcount = 0; - while(ma_ptr.size() && (ma_ptr.size() + ma_prot > ma) ) + while(unit_ptr.size() && (unit_ptr.size() + prot > goal) ) { - df::unit* unit = ma_ptr.back(); + df::unit* unit = unit_ptr.back(); doMarkForSlaughter(unit); - ma_ptr.pop_back(); + unit_ptr.pop_back(); subcount++; } return subcount; @@ -2959,10 +2967,10 @@ public: { SortUnitsByAge(); int slaughter_count = 0; - slaughter_count += ProcessUnits_fk(); - slaughter_count += ProcessUnits_mk(); - slaughter_count += ProcessUnits_fa(); - slaughter_count += ProcessUnits_ma(); + slaughter_count += ProcessUnits(fk_ptr, fk_pri_ptr, fk_prot, fk); + slaughter_count += ProcessUnits(mk_ptr, mk_pri_ptr, mk_prot, mk); + slaughter_count += ProcessUnits(fa_ptr, fa_pri_ptr, fa_prot, fa); + slaughter_count += ProcessUnits(ma_ptr, ma_pri_ptr, ma_prot, ma); ClearUnits(); return slaughter_count; } @@ -3473,6 +3481,8 @@ command_result autoButcher( color_ostream &out, bool verbose = false ) || isAvailableForAdoption(unit) || unit->name.has_name ) w->PushProtectedUnit(unit); + else if (isGay(unit)) + w->PushPriorityUnit(unit); else w->PushUnit(unit); } diff --git a/scripts/siren.lua b/scripts/siren.lua index 4fc574ed0..3a799c3e2 100644 --- a/scripts/siren.lua +++ b/scripts/siren.lua @@ -32,15 +32,18 @@ function is_in_burrows(pos) end end -function add_thought(unit, code) - for _,v in ipairs(unit.status.recent_events) do - if v.type == code then - v.age = 0 - return - end - end - - unit.status.recent_events:insert('#', { new = true, type = code }) +function add_thought(unit, emotion, thought) + unit.status.current_soul.personality.emotions:insert('#', { new = true, + type = emotion, + unk2=1, + strength=1, + thought=thought, + subthought=0, + severity=0, + flags=0, + unk7=0, + year=df.global.cur_year, + year_tick=df.global.cur_year_tick}) end function wake_unit(unit) @@ -51,9 +54,9 @@ function wake_unit(unit) if job.completion_timer > 0 then unit.counters.unconscious = 0 - add_thought(unit, df.unit_thought_type.SleepNoiseWake) + add_thought(unit, df.emotion_type.Grouchiness, df.unit_thought_type.Drowsy) elseif job.completion_timer < 0 then - add_thought(unit, df.unit_thought_type.Tired) + add_thought(unit, df.emotion_type.Grumpiness, df.unit_thought_type.Drowsy) end job.pos:assign(unit.pos) @@ -73,7 +76,7 @@ function stop_break(unit) if counter then counter.id = df.misc_trait_type.TimeSinceBreak counter.value = 100800 - 30*1200 - add_thought(unit, df.unit_thought_type.Tired) + add_thought(unit, df.emotion_type.Grumpiness, df.unit_thought_type.Drowsy) end end @@ -90,7 +93,7 @@ for _,v in ipairs(df.global.world.units.active) do local x,y,z = dfhack.units.getPosition(v) if x and dfhack.units.isCitizen(v) and is_in_burrows(xyz2pos(x,y,z)) then if not in_siege and v.military.squad_id < 0 then - add_thought(v, df.unit_thought_type.LackProtection) + add_thought(v, df.emotion_type.Nervousness, df.unit_thought_type.LackProtection) end wake_unit(v) stop_break(v) @@ -103,7 +106,7 @@ for _,v in ipairs(df.global.ui.parties) do if is_in_burrows(pos) then v.timer = 0 for _, u in ipairs(v.units) do - add_thought(unit, df.unit_thought_type.Tired) + add_thought(unit, df.emotion_type.Grumpiness, df.unit_thought_type.Drowsy) end end end