From 0f8ce360ac2e16541c6cdd47f9b162a6b6f8a2a4 Mon Sep 17 00:00:00 2001 From: Tachytaenius Date: Mon, 7 Nov 2022 23:01:00 +0000 Subject: [PATCH 01/25] Make first pass of action timer API --- docs/api/Units.rst | 0 library/LuaApi.cpp | 6 + library/include/modules/Units.h | 8 ++ library/modules/Units.cpp | 190 ++++++++++++++++++++++++++++++++ plugins/fastdwarf.cpp | 69 +----------- 5 files changed, 205 insertions(+), 68 deletions(-) create mode 100644 docs/api/Units.rst diff --git a/docs/api/Units.rst b/docs/api/Units.rst new file mode 100644 index 000000000..e69de29bb diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index 36d132124..c918cdedb 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -1779,6 +1779,12 @@ static const LuaWrapper::FunctionReg dfhack_units_module[] = { WRAPM(Units, getMainSocialEvent), WRAPM(Units, getStressCategory), WRAPM(Units, getStressCategoryRaw), + WRAPM(Units, subtractActionTimer), + WRAPM(Units, subtractActionTimerCategory), + WRAPM(Units, multiplyActionTimer), + WRAPM(Units, multiplyActionTimerCategory), + WRAPM(Units, setActionTimer), + WRAPM(Units, setActionTimerCategory), { NULL, NULL } }; diff --git a/library/include/modules/Units.h b/library/include/modules/Units.h index be630b802..ffbeaac67 100644 --- a/library/include/modules/Units.h +++ b/library/include/modules/Units.h @@ -224,5 +224,13 @@ DFHACK_EXPORT extern const std::vector stress_cutoffs; DFHACK_EXPORT int getStressCategory(df::unit *unit); DFHACK_EXPORT int getStressCategoryRaw(int32_t stress_level); +enum ActionTypeGroup {All, Movement, MovementFeet, Offensive, Work}; +DFHACK_EXPORT void subtractActionTimer(df::unit *unit, int amount, int affectedActionType); +DFHACK_EXPORT void subtractActionTimerCategory(df::unit *unit, int amount, int affectedActionTypes); +DFHACK_EXPORT void multiplyActionTimer(df::unit *unit, float amount, int affectedActionType); +DFHACK_EXPORT void multiplyActionTimerCategory(df::unit *unit, float amount, int affectedActionTypes); +DFHACK_EXPORT void setActionTimer(df::unit *unit, int amount, int affectedActionType); +DFHACK_EXPORT void setActionTimerCategory(df::unit *unit, int amount, int affectedActionTypes); + } } diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp index 777c3239b..468c0dc40 100644 --- a/library/modules/Units.cpp +++ b/library/modules/Units.cpp @@ -80,6 +80,7 @@ using namespace std; #include "df/unit_soul.h" #include "df/unit_wound.h" #include "df/world.h" +#include "df/unit_action.h" using namespace DFHack; using namespace df::enums; @@ -1949,3 +1950,192 @@ int Units::getStressCategoryRaw(int32_t stress_level) } return level; } + +struct AffectedActionTypesGroupContainer +{ + std::vector> groups; + + AffectedActionTypesGroupContainer() + { + // "All" category + std::vector & allVector = groups[Units::ActionTypeGroup::All]; + // reinitialise allVector to the length of the df::unit_action_type enum + allVector[df::unit_action_type::Move] = true; + allVector[df::unit_action_type::Attack] = true; + allVector[df::unit_action_type::HoldTerrain] = true; + allVector[df::unit_action_type::Climb] = true; + allVector[df::unit_action_type::Job] = true; + allVector[df::unit_action_type::Talk] = true; + allVector[df::unit_action_type::Unsteady] = true; + allVector[df::unit_action_type::Dodge] = true; + allVector[df::unit_action_type::Recover] = true; + allVector[df::unit_action_type::StandUp] = true; + allVector[df::unit_action_type::LieDown] = true; + allVector[df::unit_action_type::Job2] = true; + allVector[df::unit_action_type::PushObject] = true; + allVector[df::unit_action_type::SuckBlood] = true; + + // "Movement" category + std::vector & movementVector = groups[Units::ActionTypeGroup::Movement]; + // reinitialise movementVector to falses with the length of the df::unit_action_type enum + movementVector[df::unit_action_type::Move] = true; + movementVector[df::unit_action_type::HoldTerrain] = true; + movementVector[df::unit_action_type::Climb] = true; + // Include Unsteady? + movementVector[df::unit_action_type::Dodge] = true; + movementVector[df::unit_action_type::Recover] = true; + movementVector[df::unit_action_type::StandUp] = true; + movementVector[df::unit_action_type::LieDown] = true; + movementVector[df::unit_action_type::PushObject] = true; + + // "MovementFeet" category + std::vector & movementFeetVector = groups[Units::ActionTypeGroup::MovementFeet]; + // reinitialise movementFeetVector to falses with the length of the df::unit_action_type enum + movementFeetVector[df::unit_action_type::Move] = true; + // Include Unsteady? + movementFeetVector[df::unit_action_type::Dodge] = true; + movementFeetVector[df::unit_action_type::Recover] = true; + movementFeetVector[df::unit_action_type::PushObject] = true; + + // "Offensive" category + std::vector & offensiveVector = groups[Units::ActionTypeGroup::Offensive]; + // reinitialise offensiveVector to falses with the length of the df::unit_action_type enum + offensiveVector[df::unit_action_type::Attack] = true; + offensiveVector[df::unit_action_type::SuckBlood] = true; + + // "Work" category + std::vector & workVector = groups[Units::ActionTypeGroup::Work]; + // reinitialise workVector to falses with the length of the df::unit_action_type enum + workVector[df::unit_action_type::Job] = true; + workVector[df::unit_action_type::Job2] = true; + workVector[df::unit_action_type::PushObject] = true; + } +}; + +int *getActionTimerPointer(df::unit_action *action) { + switch (action->type) + { + case unit_action_type::None: + break; + case unit_action_type::Move: + return &action->data.move.timer; + case unit_action_type::Attack: + if (action->data.attack.timer1 != 0) { + // Wind-up timer is still active, work on it + return &action->data.attack.timer1; + } else { + // Wind-up timer is finished, work on recovery timer + return &action->data.attack.timer2; + } + case unit_action_type::HoldTerrain: + return &action->data.holdterrain.timer; + case unit_action_type::Climb: + return &action->data.climb.timer; + case unit_action_type::Job: + return &action->data.job.timer; + // could also patch the unit->job.current_job->completion_timer + case unit_action_type::Talk: + return &action->data.talk.timer; + case unit_action_type::Unsteady: + return &action->data.unsteady.timer; + case unit_action_type::Dodge: + return &action->data.dodge.timer; + case unit_action_type::Recover: + return &action->data.recover.timer; + case unit_action_type::StandUp: + return &action->data.standup.timer; + case unit_action_type::LieDown: + return &action->data.liedown.timer; + case unit_action_type::Job2: + return &action->data.job2.timer; + // could also patch the unit->job.current_job->completion_timer + case unit_action_type::PushObject: + return &action->data.pushobject.timer; + case unit_action_type::SuckBlood: + return &action->data.suckblood.timer; + case unit_action_type::Jump: + case unit_action_type::ReleaseTerrain: + case unit_action_type::Parry: + case unit_action_type::Block: + case unit_action_type::HoldItem: + case unit_action_type::ReleaseItem: + default: + break; + } + return nullptr; +} + +void Units::subtractActionTimer(df::unit *unit, int amount, int affectedActionType) +{ + CHECK_NULL_POINTER(unit); + for (auto action : unit->actions) { + if (affectedActionType != action->type) continue; + int *timer = getActionTimerPointer(action); + if (timer != nullptr && *timer != 0) { + *timer = max(*timer - amount, 1); + } + } +} + +void Units::subtractActionTimerCategory(df::unit *unit, int amount, int affectedActionTypes) +{ + CHECK_NULL_POINTER(unit); + static AffectedActionTypesGroupContainer groupContainer; + for (auto action : unit->actions) { + if (!groupContainer.groups[affectedActionTypes][action->type]) continue; + int *timer = getActionTimerPointer(action); + if (timer != nullptr && *timer != 0) { + *timer = max(*timer - amount, 1); + } + } +} + +void Units::multiplyActionTimer(df::unit *unit, float amount, int affectedActionType) +{ + CHECK_NULL_POINTER(unit); + for (auto action : unit->actions) { + if (affectedActionType != action->type) continue; + int *timer = getActionTimerPointer(action); + if (timer != nullptr && *timer != 0) { + *timer = max(int(*timer * amount), 1); + } + } +} + +void Units::multiplyActionTimerCategory(df::unit *unit, float amount, int affectedActionTypes) +{ + CHECK_NULL_POINTER(unit); + static AffectedActionTypesGroupContainer groupContainer; + for (auto action : unit->actions) { + if (!groupContainer.groups[affectedActionTypes][action->type]) continue; + int *timer = getActionTimerPointer(action); + if (timer != nullptr && *timer != 0) { + *timer = max(int(*timer * amount), 1); + } + } +} + +void Units::setActionTimer(df::unit *unit, int amount, int affectedActionType) +{ + CHECK_NULL_POINTER(unit); + for (auto action : unit->actions) { + if (affectedActionType != action->type) continue; + int *timer = getActionTimerPointer(action); + if (timer != nullptr && *timer != 0) { + *timer = amount; + } + } +} + +void Units::setActionTimerCategory(df::unit *unit, int amount, int affectedActionTypes) +{ + CHECK_NULL_POINTER(unit); + static AffectedActionTypesGroupContainer groupContainer; + for (auto action : unit->actions) { + if (!groupContainer.groups[affectedActionTypes][action->type]) continue; + int *timer = getActionTimerPointer(action); + if (timer != nullptr && *timer != 0) { + *timer = amount; + } + } +} diff --git a/plugins/fastdwarf.cpp b/plugins/fastdwarf.cpp index 787f85c5d..cb6a3e310 100644 --- a/plugins/fastdwarf.cpp +++ b/plugins/fastdwarf.cpp @@ -82,74 +82,7 @@ DFhackCExport command_result plugin_onupdate ( color_ostream &out ) if (enable_fastdwarf) { - for (size_t i = 0; i < unit->actions.size(); i++) - { - df::unit_action *action = unit->actions[i]; - switch (action->type) - { - case unit_action_type::None: - break; - case unit_action_type::Move: - action->data.move.timer = 1; - break; - case unit_action_type::Attack: - // Attacks are executed when timer1 reaches zero, which will be - // on the following tick. - if (action->data.attack.timer1 > 1) - action->data.attack.timer1 = 1; - // Attack actions are completed, and new ones generated, when - // timer2 reaches zero. - if (action->data.attack.timer2 > 1) - action->data.attack.timer2 = 1; - break; - case unit_action_type::HoldTerrain: - action->data.holdterrain.timer = 1; - break; - case unit_action_type::Climb: - action->data.climb.timer = 1; - break; - case unit_action_type::Job: - action->data.job.timer = 1; - // could also patch the unit->job.current_job->completion_timer - break; - case unit_action_type::Talk: - action->data.talk.timer = 1; - break; - case unit_action_type::Unsteady: - action->data.unsteady.timer = 1; - break; - case unit_action_type::Dodge: - action->data.dodge.timer = 1; - break; - case unit_action_type::Recover: - action->data.recover.timer = 1; - break; - case unit_action_type::StandUp: - action->data.standup.timer = 1; - break; - case unit_action_type::LieDown: - action->data.liedown.timer = 1; - break; - case unit_action_type::Job2: - action->data.job2.timer = 1; - // could also patch the unit->job.current_job->completion_timer - break; - case unit_action_type::PushObject: - action->data.pushobject.timer = 1; - break; - case unit_action_type::SuckBlood: - action->data.suckblood.timer = 1; - break; - case unit_action_type::Jump: - case unit_action_type::ReleaseTerrain: - case unit_action_type::Parry: - case unit_action_type::Block: - case unit_action_type::HoldItem: - case unit_action_type::ReleaseItem: - default: - break; - } - } + Units::setActionTimerCategory(unit, 1, Units::ActionTypeGroup::All); } } return CR_OK; From fa589b57645985b6abbdffb0f96714d31a401a41 Mon Sep 17 00:00:00 2001 From: Tachytaenius Date: Wed, 9 Nov 2022 19:08:06 +0000 Subject: [PATCH 02/25] Make progress with action timer API --- library/include/modules/Units.h | 15 +++++++------- library/modules/Units.cpp | 36 ++++++++++++++++++--------------- plugins/fastdwarf.cpp | 3 ++- 3 files changed, 30 insertions(+), 24 deletions(-) diff --git a/library/include/modules/Units.h b/library/include/modules/Units.h index ffbeaac67..ba71215f5 100644 --- a/library/include/modules/Units.h +++ b/library/include/modules/Units.h @@ -38,6 +38,8 @@ distribution. #include "df/misc_trait_type.h" #include "df/physical_attribute_type.h" #include "df/unit.h" +#include "df/unit_action.h" +#include "df/action_type_group.h" namespace df { @@ -224,13 +226,12 @@ DFHACK_EXPORT extern const std::vector stress_cutoffs; DFHACK_EXPORT int getStressCategory(df::unit *unit); DFHACK_EXPORT int getStressCategoryRaw(int32_t stress_level); -enum ActionTypeGroup {All, Movement, MovementFeet, Offensive, Work}; -DFHACK_EXPORT void subtractActionTimer(df::unit *unit, int amount, int affectedActionType); -DFHACK_EXPORT void subtractActionTimerCategory(df::unit *unit, int amount, int affectedActionTypes); -DFHACK_EXPORT void multiplyActionTimer(df::unit *unit, float amount, int affectedActionType); -DFHACK_EXPORT void multiplyActionTimerCategory(df::unit *unit, float amount, int affectedActionTypes); -DFHACK_EXPORT void setActionTimer(df::unit *unit, int amount, int affectedActionType); -DFHACK_EXPORT void setActionTimerCategory(df::unit *unit, int amount, int affectedActionTypes); +DFHACK_EXPORT void subtractActionTimer(df::unit *unit, int amount, df::unit_action_type affectedActionType); +DFHACK_EXPORT void subtractActionTimerCategory(df::unit *unit, int amount, df::action_type_group affectedActionTypes); +DFHACK_EXPORT void multiplyActionTimer(df::unit *unit, float amount, df::unit_action_type affectedActionType); +DFHACK_EXPORT void multiplyActionTimerCategory(df::unit *unit, float amount, df::action_type_group affectedActionTypes); +DFHACK_EXPORT void setActionTimer(df::unit *unit, int amount, df::unit_action_type affectedActionType); +DFHACK_EXPORT void setActionTimerCategory(df::unit *unit, int amount, df::action_type_group affectedActionTypes); } } diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp index 468c0dc40..fe9a79fa7 100644 --- a/library/modules/Units.cpp +++ b/library/modules/Units.cpp @@ -81,6 +81,7 @@ using namespace std; #include "df/unit_wound.h" #include "df/world.h" #include "df/unit_action.h" +#include "df/action_type_group.h" using namespace DFHack; using namespace df::enums; @@ -1957,9 +1958,16 @@ struct AffectedActionTypesGroupContainer AffectedActionTypesGroupContainer() { + const int NUM_ACTION_TYPES = ENUM_LAST_ITEM(unit_action_type) - ENUM_FIRST_ITEM(unit_action_type) + 1; + // Length of df::unit_action_type, including unknowns + const int NUM_ACTION_TYPE_GROUPS = ENUM_LAST_ITEM(action_type_group) - ENUM_FIRST_ITEM(action_type_group) + 1; + // Length of df::action_type_group + groups = std::vector>(NUM_ACTION_TYPE_GROUPS, std::vector(NUM_ACTION_TYPES, false)); + + // "None" category can be left alone + // "All" category - std::vector & allVector = groups[Units::ActionTypeGroup::All]; - // reinitialise allVector to the length of the df::unit_action_type enum + std::vector & allVector = groups[df::action_type_group::All]; allVector[df::unit_action_type::Move] = true; allVector[df::unit_action_type::Attack] = true; allVector[df::unit_action_type::HoldTerrain] = true; @@ -1976,8 +1984,7 @@ struct AffectedActionTypesGroupContainer allVector[df::unit_action_type::SuckBlood] = true; // "Movement" category - std::vector & movementVector = groups[Units::ActionTypeGroup::Movement]; - // reinitialise movementVector to falses with the length of the df::unit_action_type enum + std::vector & movementVector = groups[df::action_type_group::Movement]; movementVector[df::unit_action_type::Move] = true; movementVector[df::unit_action_type::HoldTerrain] = true; movementVector[df::unit_action_type::Climb] = true; @@ -1989,8 +1996,7 @@ struct AffectedActionTypesGroupContainer movementVector[df::unit_action_type::PushObject] = true; // "MovementFeet" category - std::vector & movementFeetVector = groups[Units::ActionTypeGroup::MovementFeet]; - // reinitialise movementFeetVector to falses with the length of the df::unit_action_type enum + std::vector & movementFeetVector = groups[df::action_type_group::MovementFeet]; movementFeetVector[df::unit_action_type::Move] = true; // Include Unsteady? movementFeetVector[df::unit_action_type::Dodge] = true; @@ -1998,14 +2004,12 @@ struct AffectedActionTypesGroupContainer movementFeetVector[df::unit_action_type::PushObject] = true; // "Offensive" category - std::vector & offensiveVector = groups[Units::ActionTypeGroup::Offensive]; - // reinitialise offensiveVector to falses with the length of the df::unit_action_type enum + std::vector & offensiveVector = groups[df::action_type_group::Offensive]; offensiveVector[df::unit_action_type::Attack] = true; offensiveVector[df::unit_action_type::SuckBlood] = true; // "Work" category - std::vector & workVector = groups[Units::ActionTypeGroup::Work]; - // reinitialise workVector to falses with the length of the df::unit_action_type enum + std::vector & workVector = groups[df::action_type_group::Work]; workVector[df::unit_action_type::Job] = true; workVector[df::unit_action_type::Job2] = true; workVector[df::unit_action_type::PushObject] = true; @@ -2065,7 +2069,7 @@ int *getActionTimerPointer(df::unit_action *action) { return nullptr; } -void Units::subtractActionTimer(df::unit *unit, int amount, int affectedActionType) +void Units::subtractActionTimer(df::unit *unit, int amount, df::unit_action_type affectedActionType) { CHECK_NULL_POINTER(unit); for (auto action : unit->actions) { @@ -2077,7 +2081,7 @@ void Units::subtractActionTimer(df::unit *unit, int amount, int affectedActionTy } } -void Units::subtractActionTimerCategory(df::unit *unit, int amount, int affectedActionTypes) +void Units::subtractActionTimerCategory(df::unit *unit, int amount, df::action_type_group affectedActionTypes) { CHECK_NULL_POINTER(unit); static AffectedActionTypesGroupContainer groupContainer; @@ -2090,7 +2094,7 @@ void Units::subtractActionTimerCategory(df::unit *unit, int amount, int affected } } -void Units::multiplyActionTimer(df::unit *unit, float amount, int affectedActionType) +void Units::multiplyActionTimer(df::unit *unit, float amount, df::unit_action_type affectedActionType) { CHECK_NULL_POINTER(unit); for (auto action : unit->actions) { @@ -2102,7 +2106,7 @@ void Units::multiplyActionTimer(df::unit *unit, float amount, int affectedAction } } -void Units::multiplyActionTimerCategory(df::unit *unit, float amount, int affectedActionTypes) +void Units::multiplyActionTimerCategory(df::unit *unit, float amount, df::action_type_group affectedActionTypes) { CHECK_NULL_POINTER(unit); static AffectedActionTypesGroupContainer groupContainer; @@ -2115,7 +2119,7 @@ void Units::multiplyActionTimerCategory(df::unit *unit, float amount, int affect } } -void Units::setActionTimer(df::unit *unit, int amount, int affectedActionType) +void Units::setActionTimer(df::unit *unit, int amount, df::unit_action_type affectedActionType) { CHECK_NULL_POINTER(unit); for (auto action : unit->actions) { @@ -2127,7 +2131,7 @@ void Units::setActionTimer(df::unit *unit, int amount, int affectedActionType) } } -void Units::setActionTimerCategory(df::unit *unit, int amount, int affectedActionTypes) +void Units::setActionTimerCategory(df::unit *unit, int amount, df::action_type_group affectedActionTypes) { CHECK_NULL_POINTER(unit); static AffectedActionTypesGroupContainer groupContainer; diff --git a/plugins/fastdwarf.cpp b/plugins/fastdwarf.cpp index cb6a3e310..ad4d6069d 100644 --- a/plugins/fastdwarf.cpp +++ b/plugins/fastdwarf.cpp @@ -12,6 +12,7 @@ #include "df/unit_relationship_type.h" #include "df/units_other_id.h" #include "df/world.h" +#include "df/action_type_group.h" using std::string; using std::vector; @@ -82,7 +83,7 @@ DFhackCExport command_result plugin_onupdate ( color_ostream &out ) if (enable_fastdwarf) { - Units::setActionTimerCategory(unit, 1, Units::ActionTypeGroup::All); + Units::setActionTimerCategory(unit, 1, df::action_type_group::All); } } return CR_OK; From 2cbbed6750f3d441335af14f368f55dadbbe5dae Mon Sep 17 00:00:00 2001 From: Tachytaenius Date: Wed, 9 Nov 2022 21:13:23 +0000 Subject: [PATCH 03/25] Use df-structures XML enums for action timer API --- library/modules/Units.cpp | 106 ++++++++++---------------------------- 1 file changed, 27 insertions(+), 79 deletions(-) diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp index fe9a79fa7..58d70d01f 100644 --- a/library/modules/Units.cpp +++ b/library/modules/Units.cpp @@ -1952,70 +1952,6 @@ int Units::getStressCategoryRaw(int32_t stress_level) return level; } -struct AffectedActionTypesGroupContainer -{ - std::vector> groups; - - AffectedActionTypesGroupContainer() - { - const int NUM_ACTION_TYPES = ENUM_LAST_ITEM(unit_action_type) - ENUM_FIRST_ITEM(unit_action_type) + 1; - // Length of df::unit_action_type, including unknowns - const int NUM_ACTION_TYPE_GROUPS = ENUM_LAST_ITEM(action_type_group) - ENUM_FIRST_ITEM(action_type_group) + 1; - // Length of df::action_type_group - groups = std::vector>(NUM_ACTION_TYPE_GROUPS, std::vector(NUM_ACTION_TYPES, false)); - - // "None" category can be left alone - - // "All" category - std::vector & allVector = groups[df::action_type_group::All]; - allVector[df::unit_action_type::Move] = true; - allVector[df::unit_action_type::Attack] = true; - allVector[df::unit_action_type::HoldTerrain] = true; - allVector[df::unit_action_type::Climb] = true; - allVector[df::unit_action_type::Job] = true; - allVector[df::unit_action_type::Talk] = true; - allVector[df::unit_action_type::Unsteady] = true; - allVector[df::unit_action_type::Dodge] = true; - allVector[df::unit_action_type::Recover] = true; - allVector[df::unit_action_type::StandUp] = true; - allVector[df::unit_action_type::LieDown] = true; - allVector[df::unit_action_type::Job2] = true; - allVector[df::unit_action_type::PushObject] = true; - allVector[df::unit_action_type::SuckBlood] = true; - - // "Movement" category - std::vector & movementVector = groups[df::action_type_group::Movement]; - movementVector[df::unit_action_type::Move] = true; - movementVector[df::unit_action_type::HoldTerrain] = true; - movementVector[df::unit_action_type::Climb] = true; - // Include Unsteady? - movementVector[df::unit_action_type::Dodge] = true; - movementVector[df::unit_action_type::Recover] = true; - movementVector[df::unit_action_type::StandUp] = true; - movementVector[df::unit_action_type::LieDown] = true; - movementVector[df::unit_action_type::PushObject] = true; - - // "MovementFeet" category - std::vector & movementFeetVector = groups[df::action_type_group::MovementFeet]; - movementFeetVector[df::unit_action_type::Move] = true; - // Include Unsteady? - movementFeetVector[df::unit_action_type::Dodge] = true; - movementFeetVector[df::unit_action_type::Recover] = true; - movementFeetVector[df::unit_action_type::PushObject] = true; - - // "Offensive" category - std::vector & offensiveVector = groups[df::action_type_group::Offensive]; - offensiveVector[df::unit_action_type::Attack] = true; - offensiveVector[df::unit_action_type::SuckBlood] = true; - - // "Work" category - std::vector & workVector = groups[df::action_type_group::Work]; - workVector[df::unit_action_type::Job] = true; - workVector[df::unit_action_type::Job2] = true; - workVector[df::unit_action_type::PushObject] = true; - } -}; - int *getActionTimerPointer(df::unit_action *action) { switch (action->type) { @@ -2084,12 +2020,16 @@ void Units::subtractActionTimer(df::unit *unit, int amount, df::unit_action_type void Units::subtractActionTimerCategory(df::unit *unit, int amount, df::action_type_group affectedActionTypes) { CHECK_NULL_POINTER(unit); - static AffectedActionTypesGroupContainer groupContainer; for (auto action : unit->actions) { - if (!groupContainer.groups[affectedActionTypes][action->type]) continue; - int *timer = getActionTimerPointer(action); - if (timer != nullptr && *timer != 0) { - *timer = max(*timer - amount, 1); + auto list = ENUM_ATTR(unit_action_type, group, action->type); + for (size_t i = 0; i < list.size; i++) { + if (list.items[i] == affectedActionTypes) { + int *timer = getActionTimerPointer(action); + if (timer != nullptr && *timer != 0) { + *timer = max(*timer - amount, 1); + } + break; + } } } } @@ -2109,12 +2049,16 @@ void Units::multiplyActionTimer(df::unit *unit, float amount, df::unit_action_ty void Units::multiplyActionTimerCategory(df::unit *unit, float amount, df::action_type_group affectedActionTypes) { CHECK_NULL_POINTER(unit); - static AffectedActionTypesGroupContainer groupContainer; for (auto action : unit->actions) { - if (!groupContainer.groups[affectedActionTypes][action->type]) continue; - int *timer = getActionTimerPointer(action); - if (timer != nullptr && *timer != 0) { - *timer = max(int(*timer * amount), 1); + auto list = ENUM_ATTR(unit_action_type, group, action->type); + for (size_t i = 0; i < list.size; i++) { + if (list.items[i] == affectedActionTypes) { + int *timer = getActionTimerPointer(action); + if (timer != nullptr && *timer != 0) { + *timer = max(int(*timer * amount), 1); + } + break; + } } } } @@ -2134,12 +2078,16 @@ void Units::setActionTimer(df::unit *unit, int amount, df::unit_action_type affe void Units::setActionTimerCategory(df::unit *unit, int amount, df::action_type_group affectedActionTypes) { CHECK_NULL_POINTER(unit); - static AffectedActionTypesGroupContainer groupContainer; for (auto action : unit->actions) { - if (!groupContainer.groups[affectedActionTypes][action->type]) continue; - int *timer = getActionTimerPointer(action); - if (timer != nullptr && *timer != 0) { - *timer = amount; + auto list = ENUM_ATTR(unit_action_type, group, action->type); + for (size_t i = 0; i < list.size; i++) { + if (list.items[i] == affectedActionTypes) { + int *timer = getActionTimerPointer(action); + if (timer != nullptr && *timer != 0) { + *timer = amount; + } + break; + } } } } From 16ef4f83133ac1dcd5e528220a60ac70df7c13ce Mon Sep 17 00:00:00 2001 From: Tachytaenius Date: Wed, 9 Nov 2022 21:42:18 +0000 Subject: [PATCH 04/25] Rename action_type_group to unit_timer_action_type_group --- library/include/modules/Units.h | 8 ++++---- library/modules/Units.cpp | 8 ++++---- plugins/fastdwarf.cpp | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/library/include/modules/Units.h b/library/include/modules/Units.h index ba71215f5..ea0d109f5 100644 --- a/library/include/modules/Units.h +++ b/library/include/modules/Units.h @@ -39,7 +39,7 @@ distribution. #include "df/physical_attribute_type.h" #include "df/unit.h" #include "df/unit_action.h" -#include "df/action_type_group.h" +#include "df/unit_action_timer_type_group.h" namespace df { @@ -227,11 +227,11 @@ DFHACK_EXPORT int getStressCategory(df::unit *unit); DFHACK_EXPORT int getStressCategoryRaw(int32_t stress_level); DFHACK_EXPORT void subtractActionTimer(df::unit *unit, int amount, df::unit_action_type affectedActionType); -DFHACK_EXPORT void subtractActionTimerCategory(df::unit *unit, int amount, df::action_type_group affectedActionTypes); +DFHACK_EXPORT void subtractActionTimerCategory(df::unit *unit, int amount, df::unit_action_timer_type_group affectedActionTypes); DFHACK_EXPORT void multiplyActionTimer(df::unit *unit, float amount, df::unit_action_type affectedActionType); -DFHACK_EXPORT void multiplyActionTimerCategory(df::unit *unit, float amount, df::action_type_group affectedActionTypes); +DFHACK_EXPORT void multiplyActionTimerCategory(df::unit *unit, float amount, df::unit_action_timer_type_group affectedActionTypes); DFHACK_EXPORT void setActionTimer(df::unit *unit, int amount, df::unit_action_type affectedActionType); -DFHACK_EXPORT void setActionTimerCategory(df::unit *unit, int amount, df::action_type_group affectedActionTypes); +DFHACK_EXPORT void setActionTimerCategory(df::unit *unit, int amount, df::unit_action_timer_type_group affectedActionTypes); } } diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp index 58d70d01f..d4bb800af 100644 --- a/library/modules/Units.cpp +++ b/library/modules/Units.cpp @@ -81,7 +81,7 @@ using namespace std; #include "df/unit_wound.h" #include "df/world.h" #include "df/unit_action.h" -#include "df/action_type_group.h" +#include "df/unit_action_timer_type_group.h" using namespace DFHack; using namespace df::enums; @@ -2017,7 +2017,7 @@ void Units::subtractActionTimer(df::unit *unit, int amount, df::unit_action_type } } -void Units::subtractActionTimerCategory(df::unit *unit, int amount, df::action_type_group affectedActionTypes) +void Units::subtractActionTimerCategory(df::unit *unit, int amount, df::unit_action_timer_type_group affectedActionTypes) { CHECK_NULL_POINTER(unit); for (auto action : unit->actions) { @@ -2046,7 +2046,7 @@ void Units::multiplyActionTimer(df::unit *unit, float amount, df::unit_action_ty } } -void Units::multiplyActionTimerCategory(df::unit *unit, float amount, df::action_type_group affectedActionTypes) +void Units::multiplyActionTimerCategory(df::unit *unit, float amount, df::unit_action_timer_type_group affectedActionTypes) { CHECK_NULL_POINTER(unit); for (auto action : unit->actions) { @@ -2075,7 +2075,7 @@ void Units::setActionTimer(df::unit *unit, int amount, df::unit_action_type affe } } -void Units::setActionTimerCategory(df::unit *unit, int amount, df::action_type_group affectedActionTypes) +void Units::setActionTimerCategory(df::unit *unit, int amount, df::unit_action_timer_type_group affectedActionTypes) { CHECK_NULL_POINTER(unit); for (auto action : unit->actions) { diff --git a/plugins/fastdwarf.cpp b/plugins/fastdwarf.cpp index ad4d6069d..073e8758f 100644 --- a/plugins/fastdwarf.cpp +++ b/plugins/fastdwarf.cpp @@ -12,7 +12,7 @@ #include "df/unit_relationship_type.h" #include "df/units_other_id.h" #include "df/world.h" -#include "df/action_type_group.h" +#include "df/unit_action_timer_type_group.h" using std::string; using std::vector; @@ -83,7 +83,7 @@ DFhackCExport command_result plugin_onupdate ( color_ostream &out ) if (enable_fastdwarf) { - Units::setActionTimerCategory(unit, 1, df::action_type_group::All); + Units::setActionTimerCategory(unit, 1, df::unit_action_timer_type_group::All); } } return CR_OK; From 7f54a77ed9979dcaba4ee78bb2eb76538c32d743 Mon Sep 17 00:00:00 2001 From: Tachytaenius Date: Fri, 18 Nov 2022 22:10:14 +0000 Subject: [PATCH 05/25] Continue work on unit action timer API --- library/LuaApi.cpp | 6 +++--- library/include/modules/Units.h | 8 ++++---- library/modules/Units.cpp | 8 ++++---- plugins/fastdwarf.cpp | 4 ++-- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index c918cdedb..773e9f7b3 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -1780,11 +1780,11 @@ static const LuaWrapper::FunctionReg dfhack_units_module[] = { WRAPM(Units, getStressCategory), WRAPM(Units, getStressCategoryRaw), WRAPM(Units, subtractActionTimer), - WRAPM(Units, subtractActionTimerCategory), + WRAPM(Units, subtractCategoryActionTimers), WRAPM(Units, multiplyActionTimer), - WRAPM(Units, multiplyActionTimerCategory), + WRAPM(Units, multiplyCategoryActionTimers), WRAPM(Units, setActionTimer), - WRAPM(Units, setActionTimerCategory), + WRAPM(Units, setCategoryActionTimers), { NULL, NULL } }; diff --git a/library/include/modules/Units.h b/library/include/modules/Units.h index ea0d109f5..559fe0af7 100644 --- a/library/include/modules/Units.h +++ b/library/include/modules/Units.h @@ -39,7 +39,7 @@ distribution. #include "df/physical_attribute_type.h" #include "df/unit.h" #include "df/unit_action.h" -#include "df/unit_action_timer_type_group.h" +#include "df/unit_action_type_group.h" namespace df { @@ -227,11 +227,11 @@ DFHACK_EXPORT int getStressCategory(df::unit *unit); DFHACK_EXPORT int getStressCategoryRaw(int32_t stress_level); DFHACK_EXPORT void subtractActionTimer(df::unit *unit, int amount, df::unit_action_type affectedActionType); -DFHACK_EXPORT void subtractActionTimerCategory(df::unit *unit, int amount, df::unit_action_timer_type_group affectedActionTypes); +DFHACK_EXPORT void subtractCategoryActionTimers(df::unit *unit, int amount, df::unit_action_type_group affectedActionTypes); DFHACK_EXPORT void multiplyActionTimer(df::unit *unit, float amount, df::unit_action_type affectedActionType); -DFHACK_EXPORT void multiplyActionTimerCategory(df::unit *unit, float amount, df::unit_action_timer_type_group affectedActionTypes); +DFHACK_EXPORT void multiplyCategoryActionTimers(df::unit *unit, float amount, df::unit_action_type_group affectedActionTypes); DFHACK_EXPORT void setActionTimer(df::unit *unit, int amount, df::unit_action_type affectedActionType); -DFHACK_EXPORT void setActionTimerCategory(df::unit *unit, int amount, df::unit_action_timer_type_group affectedActionTypes); +DFHACK_EXPORT void setCategoryActionTimers(df::unit *unit, int amount, df::unit_action_type_group affectedActionTypes); } } diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp index d4bb800af..e559126dc 100644 --- a/library/modules/Units.cpp +++ b/library/modules/Units.cpp @@ -81,7 +81,7 @@ using namespace std; #include "df/unit_wound.h" #include "df/world.h" #include "df/unit_action.h" -#include "df/unit_action_timer_type_group.h" +#include "df/unit_action_type_group.h" using namespace DFHack; using namespace df::enums; @@ -2017,7 +2017,7 @@ void Units::subtractActionTimer(df::unit *unit, int amount, df::unit_action_type } } -void Units::subtractActionTimerCategory(df::unit *unit, int amount, df::unit_action_timer_type_group affectedActionTypes) +void Units::subtractCategoryActionTimers(df::unit *unit, int amount, df::unit_action_type_group affectedActionTypes) { CHECK_NULL_POINTER(unit); for (auto action : unit->actions) { @@ -2046,7 +2046,7 @@ void Units::multiplyActionTimer(df::unit *unit, float amount, df::unit_action_ty } } -void Units::multiplyActionTimerCategory(df::unit *unit, float amount, df::unit_action_timer_type_group affectedActionTypes) +void Units::multiplyCategoryActionTimers(df::unit *unit, float amount, df::unit_action_type_group affectedActionTypes) { CHECK_NULL_POINTER(unit); for (auto action : unit->actions) { @@ -2075,7 +2075,7 @@ void Units::setActionTimer(df::unit *unit, int amount, df::unit_action_type affe } } -void Units::setActionTimerCategory(df::unit *unit, int amount, df::unit_action_timer_type_group affectedActionTypes) +void Units::setCategoryActionTimers(df::unit *unit, int amount, df::unit_action_type_group affectedActionTypes) { CHECK_NULL_POINTER(unit); for (auto action : unit->actions) { diff --git a/plugins/fastdwarf.cpp b/plugins/fastdwarf.cpp index 073e8758f..2a8f535ea 100644 --- a/plugins/fastdwarf.cpp +++ b/plugins/fastdwarf.cpp @@ -12,7 +12,7 @@ #include "df/unit_relationship_type.h" #include "df/units_other_id.h" #include "df/world.h" -#include "df/unit_action_timer_type_group.h" +#include "df/unit_action_type_group.h" using std::string; using std::vector; @@ -83,7 +83,7 @@ DFhackCExport command_result plugin_onupdate ( color_ostream &out ) if (enable_fastdwarf) { - Units::setActionTimerCategory(unit, 1, df::unit_action_timer_type_group::All); + Units::setCategoryActionTimers(unit, 1, df::unit_action_type_group::All); } } return CR_OK; From a3b1125c2842007ad989c617d4b620f3764bcd97 Mon Sep 17 00:00:00 2001 From: Tachytaenius Date: Tue, 22 Nov 2022 16:56:37 +0000 Subject: [PATCH 06/25] Progress on action timer API --- library/modules/Units.cpp | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp index e559126dc..a007db41d 100644 --- a/library/modules/Units.cpp +++ b/library/modules/Units.cpp @@ -1952,7 +1952,7 @@ int Units::getStressCategoryRaw(int32_t stress_level) return level; } -int *getActionTimerPointer(df::unit_action *action) { +int32_t *getActionTimerPointer(df::unit_action *action) { switch (action->type) { case unit_action_type::None: @@ -2010,7 +2010,7 @@ void Units::subtractActionTimer(df::unit *unit, int amount, df::unit_action_type CHECK_NULL_POINTER(unit); for (auto action : unit->actions) { if (affectedActionType != action->type) continue; - int *timer = getActionTimerPointer(action); + int32_t *timer = getActionTimerPointer(action); if (timer != nullptr && *timer != 0) { *timer = max(*timer - amount, 1); } @@ -2024,7 +2024,7 @@ void Units::subtractCategoryActionTimers(df::unit *unit, int amount, df::unit_ac auto list = ENUM_ATTR(unit_action_type, group, action->type); for (size_t i = 0; i < list.size; i++) { if (list.items[i] == affectedActionTypes) { - int *timer = getActionTimerPointer(action); + int32_t *timer = getActionTimerPointer(action); if (timer != nullptr && *timer != 0) { *timer = max(*timer - amount, 1); } @@ -2039,9 +2039,14 @@ void Units::multiplyActionTimer(df::unit *unit, float amount, df::unit_action_ty CHECK_NULL_POINTER(unit); for (auto action : unit->actions) { if (affectedActionType != action->type) continue; - int *timer = getActionTimerPointer(action); + int32_t *timer = getActionTimerPointer(action); if (timer != nullptr && *timer != 0) { - *timer = max(int(*timer * amount), 1); + double value = *timer; + value = max(value * amount, 1.0); + if (value > INT32_MAX) { + value = INT32_MAX; + } + *timer = value; } } } @@ -2053,9 +2058,14 @@ void Units::multiplyCategoryActionTimers(df::unit *unit, float amount, df::unit_ auto list = ENUM_ATTR(unit_action_type, group, action->type); for (size_t i = 0; i < list.size; i++) { if (list.items[i] == affectedActionTypes) { - int *timer = getActionTimerPointer(action); + int32_t *timer = getActionTimerPointer(action); if (timer != nullptr && *timer != 0) { - *timer = max(int(*timer * amount), 1); + double value = *timer; + value = max(value * amount, 1.0); + if (value > INT32_MAX) { + value = INT32_MAX; + } + *timer = value; } break; } @@ -2068,7 +2078,7 @@ void Units::setActionTimer(df::unit *unit, int amount, df::unit_action_type affe CHECK_NULL_POINTER(unit); for (auto action : unit->actions) { if (affectedActionType != action->type) continue; - int *timer = getActionTimerPointer(action); + int32_t *timer = getActionTimerPointer(action); if (timer != nullptr && *timer != 0) { *timer = amount; } @@ -2082,7 +2092,7 @@ void Units::setCategoryActionTimers(df::unit *unit, int amount, df::unit_action_ auto list = ENUM_ATTR(unit_action_type, group, action->type); for (size_t i = 0; i < list.size; i++) { if (list.items[i] == affectedActionTypes) { - int *timer = getActionTimerPointer(action); + int32_t *timer = getActionTimerPointer(action); if (timer != nullptr && *timer != 0) { *timer = amount; } From 4b33097e57a86a90f299e4f950be68a0a9ecca3e Mon Sep 17 00:00:00 2001 From: Tachytaenius Date: Wed, 23 Nov 2022 12:47:27 +0000 Subject: [PATCH 07/25] Remove default in action timer API switch case --- library/modules/Units.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp index a007db41d..d7d7ca680 100644 --- a/library/modules/Units.cpp +++ b/library/modules/Units.cpp @@ -1999,7 +1999,10 @@ int32_t *getActionTimerPointer(df::unit_action *action) { case unit_action_type::Block: case unit_action_type::HoldItem: case unit_action_type::ReleaseItem: - default: + case unit_action_type::Unk20: + case unit_action_type::Unk21: + case unit_action_type::Unk22: + case unit_action_type::Unk23: break; } return nullptr; From 8f0b7663d9a0f288c9049b4efc127274768cc196 Mon Sep 17 00:00:00 2001 From: Tachytaenius Date: Wed, 23 Nov 2022 12:54:58 +0000 Subject: [PATCH 08/25] Change ints in action timer API function signatures to int32_ts --- library/include/modules/Units.h | 8 ++++---- library/modules/Units.cpp | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/library/include/modules/Units.h b/library/include/modules/Units.h index 559fe0af7..2718f357f 100644 --- a/library/include/modules/Units.h +++ b/library/include/modules/Units.h @@ -226,12 +226,12 @@ DFHACK_EXPORT extern const std::vector stress_cutoffs; DFHACK_EXPORT int getStressCategory(df::unit *unit); DFHACK_EXPORT int getStressCategoryRaw(int32_t stress_level); -DFHACK_EXPORT void subtractActionTimer(df::unit *unit, int amount, df::unit_action_type affectedActionType); -DFHACK_EXPORT void subtractCategoryActionTimers(df::unit *unit, int amount, df::unit_action_type_group affectedActionTypes); +DFHACK_EXPORT void subtractActionTimer(df::unit *unit, int32_t amount, df::unit_action_type affectedActionType); +DFHACK_EXPORT void subtractCategoryActionTimers(df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionTypes); DFHACK_EXPORT void multiplyActionTimer(df::unit *unit, float amount, df::unit_action_type affectedActionType); DFHACK_EXPORT void multiplyCategoryActionTimers(df::unit *unit, float amount, df::unit_action_type_group affectedActionTypes); -DFHACK_EXPORT void setActionTimer(df::unit *unit, int amount, df::unit_action_type affectedActionType); -DFHACK_EXPORT void setCategoryActionTimers(df::unit *unit, int amount, df::unit_action_type_group affectedActionTypes); +DFHACK_EXPORT void setActionTimer(df::unit *unit, int32_t amount, df::unit_action_type affectedActionType); +DFHACK_EXPORT void setCategoryActionTimers(df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionTypes); } } diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp index d7d7ca680..6103ea8e9 100644 --- a/library/modules/Units.cpp +++ b/library/modules/Units.cpp @@ -2008,7 +2008,7 @@ int32_t *getActionTimerPointer(df::unit_action *action) { return nullptr; } -void Units::subtractActionTimer(df::unit *unit, int amount, df::unit_action_type affectedActionType) +void Units::subtractActionTimer(df::unit *unit, int32_t amount, df::unit_action_type affectedActionType) { CHECK_NULL_POINTER(unit); for (auto action : unit->actions) { @@ -2020,7 +2020,7 @@ void Units::subtractActionTimer(df::unit *unit, int amount, df::unit_action_type } } -void Units::subtractCategoryActionTimers(df::unit *unit, int amount, df::unit_action_type_group affectedActionTypes) +void Units::subtractCategoryActionTimers(df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionTypes) { CHECK_NULL_POINTER(unit); for (auto action : unit->actions) { @@ -2076,7 +2076,7 @@ void Units::multiplyCategoryActionTimers(df::unit *unit, float amount, df::unit_ } } -void Units::setActionTimer(df::unit *unit, int amount, df::unit_action_type affectedActionType) +void Units::setActionTimer(df::unit *unit, int32_t amount, df::unit_action_type affectedActionType) { CHECK_NULL_POINTER(unit); for (auto action : unit->actions) { @@ -2088,7 +2088,7 @@ void Units::setActionTimer(df::unit *unit, int amount, df::unit_action_type affe } } -void Units::setCategoryActionTimers(df::unit *unit, int amount, df::unit_action_type_group affectedActionTypes) +void Units::setCategoryActionTimers(df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionTypes) { CHECK_NULL_POINTER(unit); for (auto action : unit->actions) { From 357b871b4fe169b2e54fceda38182b119313accc Mon Sep 17 00:00:00 2001 From: Tachytaenius Date: Wed, 23 Nov 2022 13:04:23 +0000 Subject: [PATCH 09/25] Factor out shared unit action timer multiplication code into its own function --- library/modules/Units.cpp | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp index 6103ea8e9..387209ab4 100644 --- a/library/modules/Units.cpp +++ b/library/modules/Units.cpp @@ -2037,20 +2037,25 @@ void Units::subtractCategoryActionTimers(df::unit *unit, int32_t amount, df::uni } } +void multiplyActionTimerCore(df::unit_action *action, float amount) +{ + int32_t *timer = getActionTimerPointer(action); + if (timer != nullptr && *timer != 0) { + double value = *timer; + value = max(value * amount, 1.0); + if (value > INT32_MAX) { + value = INT32_MAX; + } + *timer = value; + } +} + void Units::multiplyActionTimer(df::unit *unit, float amount, df::unit_action_type affectedActionType) { CHECK_NULL_POINTER(unit); for (auto action : unit->actions) { if (affectedActionType != action->type) continue; - int32_t *timer = getActionTimerPointer(action); - if (timer != nullptr && *timer != 0) { - double value = *timer; - value = max(value * amount, 1.0); - if (value > INT32_MAX) { - value = INT32_MAX; - } - *timer = value; - } + multiplyActionTimerCore(action, amount); } } @@ -2061,15 +2066,7 @@ void Units::multiplyCategoryActionTimers(df::unit *unit, float amount, df::unit_ auto list = ENUM_ATTR(unit_action_type, group, action->type); for (size_t i = 0; i < list.size; i++) { if (list.items[i] == affectedActionTypes) { - int32_t *timer = getActionTimerPointer(action); - if (timer != nullptr && *timer != 0) { - double value = *timer; - value = max(value * amount, 1.0); - if (value > INT32_MAX) { - value = INT32_MAX; - } - *timer = value; - } + multiplyActionTimerCore(action, amount); break; } } From e93d7eefb3a891d9ba8f1b7d41495454daf58722 Mon Sep 17 00:00:00 2001 From: Tachytaenius Date: Wed, 23 Nov 2022 13:17:32 +0000 Subject: [PATCH 10/25] Factor out set and add shared action timer code into own functions --- library/modules/Units.cpp | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp index 387209ab4..f068936c5 100644 --- a/library/modules/Units.cpp +++ b/library/modules/Units.cpp @@ -2008,15 +2008,20 @@ int32_t *getActionTimerPointer(df::unit_action *action) { return nullptr; } +void subtractActionTimerCore(df::unit_action *action, int32_t amount) +{ + int32_t *timer = getActionTimerPointer(action); + if (timer != nullptr && *timer != 0) { + *timer = max(*timer - amount, 1); + } +} + void Units::subtractActionTimer(df::unit *unit, int32_t amount, df::unit_action_type affectedActionType) { CHECK_NULL_POINTER(unit); for (auto action : unit->actions) { if (affectedActionType != action->type) continue; - int32_t *timer = getActionTimerPointer(action); - if (timer != nullptr && *timer != 0) { - *timer = max(*timer - amount, 1); - } + subtractActionTimerCore(action, amount); } } @@ -2027,10 +2032,7 @@ void Units::subtractCategoryActionTimers(df::unit *unit, int32_t amount, df::uni auto list = ENUM_ATTR(unit_action_type, group, action->type); for (size_t i = 0; i < list.size; i++) { if (list.items[i] == affectedActionTypes) { - int32_t *timer = getActionTimerPointer(action); - if (timer != nullptr && *timer != 0) { - *timer = max(*timer - amount, 1); - } + subtractActionTimerCore(action, amount); break; } } @@ -2073,15 +2075,19 @@ void Units::multiplyCategoryActionTimers(df::unit *unit, float amount, df::unit_ } } +void setActionTimerCore(df::unit_action *action, int32_t amount) { + int32_t *timer = getActionTimerPointer(action); + if (timer != nullptr && *timer != 0) { + *timer = amount; + } +} + void Units::setActionTimer(df::unit *unit, int32_t amount, df::unit_action_type affectedActionType) { CHECK_NULL_POINTER(unit); for (auto action : unit->actions) { if (affectedActionType != action->type) continue; - int32_t *timer = getActionTimerPointer(action); - if (timer != nullptr && *timer != 0) { - *timer = amount; - } + setActionTimerCore(action, amount); } } @@ -2092,10 +2098,7 @@ void Units::setCategoryActionTimers(df::unit *unit, int32_t amount, df::unit_act auto list = ENUM_ATTR(unit_action_type, group, action->type); for (size_t i = 0; i < list.size; i++) { if (list.items[i] == affectedActionTypes) { - int32_t *timer = getActionTimerPointer(action); - if (timer != nullptr && *timer != 0) { - *timer = amount; - } + setActionTimerCore(action, amount); break; } } From 5e0c0d22cb3def800acdc17692b95f07f6c0a3c0 Mon Sep 17 00:00:00 2001 From: Tachytaenius Date: Wed, 23 Nov 2022 13:20:22 +0000 Subject: [PATCH 11/25] Group action timer API internal functions together --- library/modules/Units.cpp | 40 +++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp index f068936c5..ba3f7696f 100644 --- a/library/modules/Units.cpp +++ b/library/modules/Units.cpp @@ -2016,6 +2016,26 @@ void subtractActionTimerCore(df::unit_action *action, int32_t amount) } } +void multiplyActionTimerCore(df::unit_action *action, float amount) +{ + int32_t *timer = getActionTimerPointer(action); + if (timer != nullptr && *timer != 0) { + double value = *timer; + value = max(value * amount, 1.0); + if (value > INT32_MAX) { + value = INT32_MAX; + } + *timer = value; + } +} + +void setActionTimerCore(df::unit_action *action, int32_t amount) { + int32_t *timer = getActionTimerPointer(action); + if (timer != nullptr && *timer != 0) { + *timer = amount; + } +} + void Units::subtractActionTimer(df::unit *unit, int32_t amount, df::unit_action_type affectedActionType) { CHECK_NULL_POINTER(unit); @@ -2039,19 +2059,6 @@ void Units::subtractCategoryActionTimers(df::unit *unit, int32_t amount, df::uni } } -void multiplyActionTimerCore(df::unit_action *action, float amount) -{ - int32_t *timer = getActionTimerPointer(action); - if (timer != nullptr && *timer != 0) { - double value = *timer; - value = max(value * amount, 1.0); - if (value > INT32_MAX) { - value = INT32_MAX; - } - *timer = value; - } -} - void Units::multiplyActionTimer(df::unit *unit, float amount, df::unit_action_type affectedActionType) { CHECK_NULL_POINTER(unit); @@ -2075,13 +2082,6 @@ void Units::multiplyCategoryActionTimers(df::unit *unit, float amount, df::unit_ } } -void setActionTimerCore(df::unit_action *action, int32_t amount) { - int32_t *timer = getActionTimerPointer(action); - if (timer != nullptr && *timer != 0) { - *timer = amount; - } -} - void Units::setActionTimer(df::unit *unit, int32_t amount, df::unit_action_type affectedActionType) { CHECK_NULL_POINTER(unit); From 6148307e9b60b24609a9dcea214a3fdc7868597e Mon Sep 17 00:00:00 2001 From: Tachytaenius Date: Wed, 23 Nov 2022 13:31:16 +0000 Subject: [PATCH 12/25] Change != 0 to > 0 in action timer API core functions --- library/modules/Units.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp index ba3f7696f..ed47af271 100644 --- a/library/modules/Units.cpp +++ b/library/modules/Units.cpp @@ -2011,7 +2011,7 @@ int32_t *getActionTimerPointer(df::unit_action *action) { void subtractActionTimerCore(df::unit_action *action, int32_t amount) { int32_t *timer = getActionTimerPointer(action); - if (timer != nullptr && *timer != 0) { + if (timer != nullptr && *timer > 0) { *timer = max(*timer - amount, 1); } } @@ -2019,7 +2019,7 @@ void subtractActionTimerCore(df::unit_action *action, int32_t amount) void multiplyActionTimerCore(df::unit_action *action, float amount) { int32_t *timer = getActionTimerPointer(action); - if (timer != nullptr && *timer != 0) { + if (timer != nullptr && *timer > 0) { double value = *timer; value = max(value * amount, 1.0); if (value > INT32_MAX) { @@ -2031,7 +2031,7 @@ void multiplyActionTimerCore(df::unit_action *action, float amount) void setActionTimerCore(df::unit_action *action, int32_t amount) { int32_t *timer = getActionTimerPointer(action); - if (timer != nullptr && *timer != 0) { + if (timer != nullptr && *timer > 0) { *timer = amount; } } From cc40b804567d9761d7eadbe6bac56d4fb7fed051 Mon Sep 17 00:00:00 2001 From: Tachytaenius Date: Wed, 23 Nov 2022 14:06:26 +0000 Subject: [PATCH 13/25] Protect against integer overflow when subtracting with action timer API --- library/modules/Units.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp index ed47af271..29afd00e9 100644 --- a/library/modules/Units.cpp +++ b/library/modules/Units.cpp @@ -2012,7 +2012,12 @@ void subtractActionTimerCore(df::unit_action *action, int32_t amount) { int32_t *timer = getActionTimerPointer(action); if (timer != nullptr && *timer > 0) { - *timer = max(*timer - amount, 1); + double value = *timer; + value = max(value - amount, 1.0); + if (value > INT32_MAX) { + value = INT32_MAX; + } + *timer = value; } } From f863b9807a05d99bc407a7ab7025436d789f8450 Mon Sep 17 00:00:00 2001 From: Tachytaenius Date: Sat, 26 Nov 2022 22:45:01 +0000 Subject: [PATCH 14/25] Add action timer API input validation --- library/include/modules/Units.h | 12 +++++------ library/modules/Units.cpp | 36 +++++++++++++++++++++++++++------ plugins/fastdwarf.cpp | 2 +- 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/library/include/modules/Units.h b/library/include/modules/Units.h index 2718f357f..5578dc521 100644 --- a/library/include/modules/Units.h +++ b/library/include/modules/Units.h @@ -226,12 +226,12 @@ DFHACK_EXPORT extern const std::vector stress_cutoffs; DFHACK_EXPORT int getStressCategory(df::unit *unit); DFHACK_EXPORT int getStressCategoryRaw(int32_t stress_level); -DFHACK_EXPORT void subtractActionTimer(df::unit *unit, int32_t amount, df::unit_action_type affectedActionType); -DFHACK_EXPORT void subtractCategoryActionTimers(df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionTypes); -DFHACK_EXPORT void multiplyActionTimer(df::unit *unit, float amount, df::unit_action_type affectedActionType); -DFHACK_EXPORT void multiplyCategoryActionTimers(df::unit *unit, float amount, df::unit_action_type_group affectedActionTypes); -DFHACK_EXPORT void setActionTimer(df::unit *unit, int32_t amount, df::unit_action_type affectedActionType); -DFHACK_EXPORT void setCategoryActionTimers(df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionTypes); +DFHACK_EXPORT void subtractActionTimer(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type affectedActionType); +DFHACK_EXPORT void subtractCategoryActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionTypes); +DFHACK_EXPORT void multiplyActionTimer(color_ostream &out, df::unit *unit, float amount, df::unit_action_type affectedActionType); +DFHACK_EXPORT void multiplyCategoryActionTimers(color_ostream &out, df::unit *unit, float amount, df::unit_action_type_group affectedActionTypes); +DFHACK_EXPORT void setActionTimer(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type affectedActionType); +DFHACK_EXPORT void setCategoryActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionTypes); } } diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp index 29afd00e9..eee359254 100644 --- a/library/modules/Units.cpp +++ b/library/modules/Units.cpp @@ -2041,7 +2041,7 @@ void setActionTimerCore(df::unit_action *action, int32_t amount) { } } -void Units::subtractActionTimer(df::unit *unit, int32_t amount, df::unit_action_type affectedActionType) +void Units::subtractActionTimer(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type affectedActionType) { CHECK_NULL_POINTER(unit); for (auto action : unit->actions) { @@ -2050,7 +2050,7 @@ void Units::subtractActionTimer(df::unit *unit, int32_t amount, df::unit_action_ } } -void Units::subtractCategoryActionTimers(df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionTypes) +void Units::subtractCategoryActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionTypes) { CHECK_NULL_POINTER(unit); for (auto action : unit->actions) { @@ -2064,18 +2064,30 @@ void Units::subtractCategoryActionTimers(df::unit *unit, int32_t amount, df::uni } } -void Units::multiplyActionTimer(df::unit *unit, float amount, df::unit_action_type affectedActionType) +bool validateMultiplyActionTimerAmount(color_ostream &out, float amount) { + if (amount < 0) { + out.printerr("Can't multiply action timer(s) by negative amount.\n"); + return false; + } + return true; +} + +void Units::multiplyActionTimer(color_ostream &out, df::unit *unit, float amount, df::unit_action_type affectedActionType) { CHECK_NULL_POINTER(unit); + if (!validateMultiplyActionTimerAmount(out, amount)) + return; for (auto action : unit->actions) { if (affectedActionType != action->type) continue; multiplyActionTimerCore(action, amount); } } -void Units::multiplyCategoryActionTimers(df::unit *unit, float amount, df::unit_action_type_group affectedActionTypes) +void Units::multiplyCategoryActionTimers(color_ostream &out, df::unit *unit, float amount, df::unit_action_type_group affectedActionTypes) { CHECK_NULL_POINTER(unit); + if (!validateMultiplyActionTimerAmount(out, amount)) + return; for (auto action : unit->actions) { auto list = ENUM_ATTR(unit_action_type, group, action->type); for (size_t i = 0; i < list.size; i++) { @@ -2087,18 +2099,30 @@ void Units::multiplyCategoryActionTimers(df::unit *unit, float amount, df::unit_ } } -void Units::setActionTimer(df::unit *unit, int32_t amount, df::unit_action_type affectedActionType) +bool validateSetActionTimerAmount(color_ostream &out, int32_t amount) { + if (amount <= 0) { + out.printerr("Can't set action timer(s) to non-positive amount.\n"); + return false; + } + return true; +} + +void Units::setActionTimer(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type affectedActionType) { CHECK_NULL_POINTER(unit); + if (!validateSetActionTimerAmount(out, amount)) + return; for (auto action : unit->actions) { if (affectedActionType != action->type) continue; setActionTimerCore(action, amount); } } -void Units::setCategoryActionTimers(df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionTypes) +void Units::setCategoryActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionTypes) { CHECK_NULL_POINTER(unit); + if (!validateSetActionTimerAmount(out, amount)) + return; for (auto action : unit->actions) { auto list = ENUM_ATTR(unit_action_type, group, action->type); for (size_t i = 0; i < list.size; i++) { diff --git a/plugins/fastdwarf.cpp b/plugins/fastdwarf.cpp index 2a8f535ea..ea18437d6 100644 --- a/plugins/fastdwarf.cpp +++ b/plugins/fastdwarf.cpp @@ -83,7 +83,7 @@ DFhackCExport command_result plugin_onupdate ( color_ostream &out ) if (enable_fastdwarf) { - Units::setCategoryActionTimers(unit, 1, df::unit_action_type_group::All); + Units::setCategoryActionTimers(out, unit, 1, df::unit_action_type_group::All); } } return CR_OK; From a925c3441374c46164d4c492ebac918d5fbdfb1c Mon Sep 17 00:00:00 2001 From: Tachytaenius Date: Sun, 27 Nov 2022 17:07:47 +0000 Subject: [PATCH 15/25] Rename [xyz]ActionTimer functions to [xyz]ActionTimers --- library/LuaApi.cpp | 6 +++--- library/include/modules/Units.h | 6 +++--- library/modules/Units.cpp | 24 ++++++++++++------------ 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index 773e9f7b3..453a368f3 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -1779,11 +1779,11 @@ static const LuaWrapper::FunctionReg dfhack_units_module[] = { WRAPM(Units, getMainSocialEvent), WRAPM(Units, getStressCategory), WRAPM(Units, getStressCategoryRaw), - WRAPM(Units, subtractActionTimer), + WRAPM(Units, subtractActionTimers), WRAPM(Units, subtractCategoryActionTimers), - WRAPM(Units, multiplyActionTimer), + WRAPM(Units, multiplyActionTimers), WRAPM(Units, multiplyCategoryActionTimers), - WRAPM(Units, setActionTimer), + WRAPM(Units, setActionTimers), WRAPM(Units, setCategoryActionTimers), { NULL, NULL } }; diff --git a/library/include/modules/Units.h b/library/include/modules/Units.h index 5578dc521..5afd402e6 100644 --- a/library/include/modules/Units.h +++ b/library/include/modules/Units.h @@ -226,11 +226,11 @@ DFHACK_EXPORT extern const std::vector stress_cutoffs; DFHACK_EXPORT int getStressCategory(df::unit *unit); DFHACK_EXPORT int getStressCategoryRaw(int32_t stress_level); -DFHACK_EXPORT void subtractActionTimer(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type affectedActionType); +DFHACK_EXPORT void subtractActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type affectedActionType); DFHACK_EXPORT void subtractCategoryActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionTypes); -DFHACK_EXPORT void multiplyActionTimer(color_ostream &out, df::unit *unit, float amount, df::unit_action_type affectedActionType); +DFHACK_EXPORT void multiplyActionTimers(color_ostream &out, df::unit *unit, float amount, df::unit_action_type affectedActionType); DFHACK_EXPORT void multiplyCategoryActionTimers(color_ostream &out, df::unit *unit, float amount, df::unit_action_type_group affectedActionTypes); -DFHACK_EXPORT void setActionTimer(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type affectedActionType); +DFHACK_EXPORT void setActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type affectedActionType); DFHACK_EXPORT void setCategoryActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionTypes); } diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp index eee359254..988624a3f 100644 --- a/library/modules/Units.cpp +++ b/library/modules/Units.cpp @@ -2008,7 +2008,7 @@ int32_t *getActionTimerPointer(df::unit_action *action) { return nullptr; } -void subtractActionTimerCore(df::unit_action *action, int32_t amount) +void subtractActionTimersCore(df::unit_action *action, int32_t amount) { int32_t *timer = getActionTimerPointer(action); if (timer != nullptr && *timer > 0) { @@ -2021,7 +2021,7 @@ void subtractActionTimerCore(df::unit_action *action, int32_t amount) } } -void multiplyActionTimerCore(df::unit_action *action, float amount) +void multiplyActionTimersCore(df::unit_action *action, float amount) { int32_t *timer = getActionTimerPointer(action); if (timer != nullptr && *timer > 0) { @@ -2034,19 +2034,19 @@ void multiplyActionTimerCore(df::unit_action *action, float amount) } } -void setActionTimerCore(df::unit_action *action, int32_t amount) { +void setActionTimersCore(df::unit_action *action, int32_t amount) { int32_t *timer = getActionTimerPointer(action); if (timer != nullptr && *timer > 0) { *timer = amount; } } -void Units::subtractActionTimer(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type affectedActionType) +void Units::subtractActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type affectedActionType) { CHECK_NULL_POINTER(unit); for (auto action : unit->actions) { if (affectedActionType != action->type) continue; - subtractActionTimerCore(action, amount); + subtractActionTimersCore(action, amount); } } @@ -2057,7 +2057,7 @@ void Units::subtractCategoryActionTimers(color_ostream &out, df::unit *unit, int auto list = ENUM_ATTR(unit_action_type, group, action->type); for (size_t i = 0; i < list.size; i++) { if (list.items[i] == affectedActionTypes) { - subtractActionTimerCore(action, amount); + subtractActionTimersCore(action, amount); break; } } @@ -2072,14 +2072,14 @@ bool validateMultiplyActionTimerAmount(color_ostream &out, float amount) { return true; } -void Units::multiplyActionTimer(color_ostream &out, df::unit *unit, float amount, df::unit_action_type affectedActionType) +void Units::multiplyActionTimers(color_ostream &out, df::unit *unit, float amount, df::unit_action_type affectedActionType) { CHECK_NULL_POINTER(unit); if (!validateMultiplyActionTimerAmount(out, amount)) return; for (auto action : unit->actions) { if (affectedActionType != action->type) continue; - multiplyActionTimerCore(action, amount); + multiplyActionTimersCore(action, amount); } } @@ -2092,7 +2092,7 @@ void Units::multiplyCategoryActionTimers(color_ostream &out, df::unit *unit, flo auto list = ENUM_ATTR(unit_action_type, group, action->type); for (size_t i = 0; i < list.size; i++) { if (list.items[i] == affectedActionTypes) { - multiplyActionTimerCore(action, amount); + multiplyActionTimersCore(action, amount); break; } } @@ -2107,14 +2107,14 @@ bool validateSetActionTimerAmount(color_ostream &out, int32_t amount) { return true; } -void Units::setActionTimer(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type affectedActionType) +void Units::setActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type affectedActionType) { CHECK_NULL_POINTER(unit); if (!validateSetActionTimerAmount(out, amount)) return; for (auto action : unit->actions) { if (affectedActionType != action->type) continue; - setActionTimerCore(action, amount); + setActionTimersCore(action, amount); } } @@ -2127,7 +2127,7 @@ void Units::setCategoryActionTimers(color_ostream &out, df::unit *unit, int32_t auto list = ENUM_ATTR(unit_action_type, group, action->type); for (size_t i = 0; i < list.size; i++) { if (list.items[i] == affectedActionTypes) { - setActionTimerCore(action, amount); + setActionTimersCore(action, amount); break; } } From aa2cf44c4bc2b2787dd0d9ebaf046632ead30877 Mon Sep 17 00:00:00 2001 From: Tachytaenius Date: Sun, 27 Nov 2022 17:49:40 +0000 Subject: [PATCH 16/25] Use lambdas to violate DRY less in action timer API --- library/modules/Units.cpp | 40 +++++++++++---------------------------- 1 file changed, 11 insertions(+), 29 deletions(-) diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp index 988624a3f..c2ed25b23 100644 --- a/library/modules/Units.cpp +++ b/library/modules/Units.cpp @@ -32,6 +32,7 @@ distribution. #include #include #include +#include using namespace std; #include "VersionInfo.h" @@ -2008,45 +2009,26 @@ int32_t *getActionTimerPointer(df::unit_action *action) { return nullptr; } -void subtractActionTimersCore(df::unit_action *action, int32_t amount) -{ +void mutateActionTimerCore(df::unit_action *action, std::function mutator) { int32_t *timer = getActionTimerPointer(action); if (timer != nullptr && *timer > 0) { double value = *timer; - value = max(value - amount, 1.0); + value = mutator(value); if (value > INT32_MAX) { value = INT32_MAX; + } else if (value < INT32_MIN) { + value = INT32_MIN; } *timer = value; } } -void multiplyActionTimersCore(df::unit_action *action, float amount) -{ - int32_t *timer = getActionTimerPointer(action); - if (timer != nullptr && *timer > 0) { - double value = *timer; - value = max(value * amount, 1.0); - if (value > INT32_MAX) { - value = INT32_MAX; - } - *timer = value; - } -} - -void setActionTimersCore(df::unit_action *action, int32_t amount) { - int32_t *timer = getActionTimerPointer(action); - if (timer != nullptr && *timer > 0) { - *timer = amount; - } -} - void Units::subtractActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type affectedActionType) { CHECK_NULL_POINTER(unit); for (auto action : unit->actions) { if (affectedActionType != action->type) continue; - subtractActionTimersCore(action, amount); + mutateActionTimerCore(action, [=](double timerValue){return max(timerValue - amount, 1.0);}); } } @@ -2057,7 +2039,7 @@ void Units::subtractCategoryActionTimers(color_ostream &out, df::unit *unit, int auto list = ENUM_ATTR(unit_action_type, group, action->type); for (size_t i = 0; i < list.size; i++) { if (list.items[i] == affectedActionTypes) { - subtractActionTimersCore(action, amount); + mutateActionTimerCore(action, [=](double timerValue){return max(timerValue - amount, 1.0);}); break; } } @@ -2079,7 +2061,7 @@ void Units::multiplyActionTimers(color_ostream &out, df::unit *unit, float amoun return; for (auto action : unit->actions) { if (affectedActionType != action->type) continue; - multiplyActionTimersCore(action, amount); + mutateActionTimerCore(action, [=](double timerValue){return max(timerValue * amount, 1.0);}); } } @@ -2092,7 +2074,7 @@ void Units::multiplyCategoryActionTimers(color_ostream &out, df::unit *unit, flo auto list = ENUM_ATTR(unit_action_type, group, action->type); for (size_t i = 0; i < list.size; i++) { if (list.items[i] == affectedActionTypes) { - multiplyActionTimersCore(action, amount); + mutateActionTimerCore(action, [=](double timerValue){return max(timerValue * amount, 1.0);}); break; } } @@ -2114,7 +2096,7 @@ void Units::setActionTimers(color_ostream &out, df::unit *unit, int32_t amount, return; for (auto action : unit->actions) { if (affectedActionType != action->type) continue; - setActionTimersCore(action, amount); + mutateActionTimerCore(action, [=](double timerValue){return amount;}); } } @@ -2127,7 +2109,7 @@ void Units::setCategoryActionTimers(color_ostream &out, df::unit *unit, int32_t auto list = ENUM_ATTR(unit_action_type, group, action->type); for (size_t i = 0; i < list.size; i++) { if (list.items[i] == affectedActionTypes) { - setActionTimersCore(action, amount); + mutateActionTimerCore(action, [=](double timerValue){return amount;}); break; } } From 2256bfd6f74a9cc620d667475c384b67e55ade45 Mon Sep 17 00:00:00 2001 From: Tachytaenius Date: Thu, 1 Dec 2022 21:08:57 +0000 Subject: [PATCH 17/25] Delete Units.rst --- docs/api/Units.rst | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 docs/api/Units.rst diff --git a/docs/api/Units.rst b/docs/api/Units.rst deleted file mode 100644 index e69de29bb..000000000 From f06f17b59c8321162ab8777155e2cfc648f7bf06 Mon Sep 17 00:00:00 2001 From: Tachytaenius Date: Thu, 1 Dec 2022 23:17:57 +0000 Subject: [PATCH 18/25] Rename affectedActionTypes to affectedActionCategory in action timer API --- library/include/modules/Units.h | 6 +++--- library/modules/Units.cpp | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/library/include/modules/Units.h b/library/include/modules/Units.h index 5afd402e6..004c0bcbf 100644 --- a/library/include/modules/Units.h +++ b/library/include/modules/Units.h @@ -227,11 +227,11 @@ DFHACK_EXPORT int getStressCategory(df::unit *unit); DFHACK_EXPORT int getStressCategoryRaw(int32_t stress_level); DFHACK_EXPORT void subtractActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type affectedActionType); -DFHACK_EXPORT void subtractCategoryActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionTypes); +DFHACK_EXPORT void subtractCategoryActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionCategory); DFHACK_EXPORT void multiplyActionTimers(color_ostream &out, df::unit *unit, float amount, df::unit_action_type affectedActionType); -DFHACK_EXPORT void multiplyCategoryActionTimers(color_ostream &out, df::unit *unit, float amount, df::unit_action_type_group affectedActionTypes); +DFHACK_EXPORT void multiplyCategoryActionTimers(color_ostream &out, df::unit *unit, float amount, df::unit_action_type_group affectedActionCategory); DFHACK_EXPORT void setActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type affectedActionType); -DFHACK_EXPORT void setCategoryActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionTypes); +DFHACK_EXPORT void setCategoryActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionCategory); } } diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp index c2ed25b23..b663965f8 100644 --- a/library/modules/Units.cpp +++ b/library/modules/Units.cpp @@ -2032,13 +2032,13 @@ void Units::subtractActionTimers(color_ostream &out, df::unit *unit, int32_t amo } } -void Units::subtractCategoryActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionTypes) +void Units::subtractCategoryActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionCategory) { CHECK_NULL_POINTER(unit); for (auto action : unit->actions) { auto list = ENUM_ATTR(unit_action_type, group, action->type); for (size_t i = 0; i < list.size; i++) { - if (list.items[i] == affectedActionTypes) { + if (list.items[i] == affectedActionCategory) { mutateActionTimerCore(action, [=](double timerValue){return max(timerValue - amount, 1.0);}); break; } @@ -2065,7 +2065,7 @@ void Units::multiplyActionTimers(color_ostream &out, df::unit *unit, float amoun } } -void Units::multiplyCategoryActionTimers(color_ostream &out, df::unit *unit, float amount, df::unit_action_type_group affectedActionTypes) +void Units::multiplyCategoryActionTimers(color_ostream &out, df::unit *unit, float amount, df::unit_action_type_group affectedActionCategory) { CHECK_NULL_POINTER(unit); if (!validateMultiplyActionTimerAmount(out, amount)) @@ -2073,7 +2073,7 @@ void Units::multiplyCategoryActionTimers(color_ostream &out, df::unit *unit, flo for (auto action : unit->actions) { auto list = ENUM_ATTR(unit_action_type, group, action->type); for (size_t i = 0; i < list.size; i++) { - if (list.items[i] == affectedActionTypes) { + if (list.items[i] == affectedActionCategory) { mutateActionTimerCore(action, [=](double timerValue){return max(timerValue * amount, 1.0);}); break; } @@ -2100,7 +2100,7 @@ void Units::setActionTimers(color_ostream &out, df::unit *unit, int32_t amount, } } -void Units::setCategoryActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionTypes) +void Units::setCategoryActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionCategory) { CHECK_NULL_POINTER(unit); if (!validateSetActionTimerAmount(out, amount)) @@ -2108,7 +2108,7 @@ void Units::setCategoryActionTimers(color_ostream &out, df::unit *unit, int32_t for (auto action : unit->actions) { auto list = ENUM_ATTR(unit_action_type, group, action->type); for (size_t i = 0; i < list.size; i++) { - if (list.items[i] == affectedActionTypes) { + if (list.items[i] == affectedActionCategory) { mutateActionTimerCore(action, [=](double timerValue){return amount;}); break; } From 76cdbfbc5cd66651a85b9b9354c0e6cc3386aab6 Mon Sep 17 00:00:00 2001 From: Tachytaenius Date: Thu, 1 Dec 2022 23:19:10 +0000 Subject: [PATCH 19/25] Rename affectedActionCategory to affectedActionTypeCategory in action timer API --- library/include/modules/Units.h | 6 +++--- library/modules/Units.cpp | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/library/include/modules/Units.h b/library/include/modules/Units.h index 004c0bcbf..4c8513e27 100644 --- a/library/include/modules/Units.h +++ b/library/include/modules/Units.h @@ -227,11 +227,11 @@ DFHACK_EXPORT int getStressCategory(df::unit *unit); DFHACK_EXPORT int getStressCategoryRaw(int32_t stress_level); DFHACK_EXPORT void subtractActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type affectedActionType); -DFHACK_EXPORT void subtractCategoryActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionCategory); +DFHACK_EXPORT void subtractCategoryActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionTypeCategory); DFHACK_EXPORT void multiplyActionTimers(color_ostream &out, df::unit *unit, float amount, df::unit_action_type affectedActionType); -DFHACK_EXPORT void multiplyCategoryActionTimers(color_ostream &out, df::unit *unit, float amount, df::unit_action_type_group affectedActionCategory); +DFHACK_EXPORT void multiplyCategoryActionTimers(color_ostream &out, df::unit *unit, float amount, df::unit_action_type_group affectedActionTypeCategory); DFHACK_EXPORT void setActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type affectedActionType); -DFHACK_EXPORT void setCategoryActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionCategory); +DFHACK_EXPORT void setCategoryActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionTypeCategory); } } diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp index b663965f8..9656c75e6 100644 --- a/library/modules/Units.cpp +++ b/library/modules/Units.cpp @@ -2032,13 +2032,13 @@ void Units::subtractActionTimers(color_ostream &out, df::unit *unit, int32_t amo } } -void Units::subtractCategoryActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionCategory) +void Units::subtractCategoryActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionTypeCategory) { CHECK_NULL_POINTER(unit); for (auto action : unit->actions) { auto list = ENUM_ATTR(unit_action_type, group, action->type); for (size_t i = 0; i < list.size; i++) { - if (list.items[i] == affectedActionCategory) { + if (list.items[i] == affectedActionTypeCategory) { mutateActionTimerCore(action, [=](double timerValue){return max(timerValue - amount, 1.0);}); break; } @@ -2065,7 +2065,7 @@ void Units::multiplyActionTimers(color_ostream &out, df::unit *unit, float amoun } } -void Units::multiplyCategoryActionTimers(color_ostream &out, df::unit *unit, float amount, df::unit_action_type_group affectedActionCategory) +void Units::multiplyCategoryActionTimers(color_ostream &out, df::unit *unit, float amount, df::unit_action_type_group affectedActionTypeCategory) { CHECK_NULL_POINTER(unit); if (!validateMultiplyActionTimerAmount(out, amount)) @@ -2073,7 +2073,7 @@ void Units::multiplyCategoryActionTimers(color_ostream &out, df::unit *unit, flo for (auto action : unit->actions) { auto list = ENUM_ATTR(unit_action_type, group, action->type); for (size_t i = 0; i < list.size; i++) { - if (list.items[i] == affectedActionCategory) { + if (list.items[i] == affectedActionTypeCategory) { mutateActionTimerCore(action, [=](double timerValue){return max(timerValue * amount, 1.0);}); break; } @@ -2100,7 +2100,7 @@ void Units::setActionTimers(color_ostream &out, df::unit *unit, int32_t amount, } } -void Units::setCategoryActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionCategory) +void Units::setCategoryActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionTypeCategory) { CHECK_NULL_POINTER(unit); if (!validateSetActionTimerAmount(out, amount)) @@ -2108,7 +2108,7 @@ void Units::setCategoryActionTimers(color_ostream &out, df::unit *unit, int32_t for (auto action : unit->actions) { auto list = ENUM_ATTR(unit_action_type, group, action->type); for (size_t i = 0; i < list.size; i++) { - if (list.items[i] == affectedActionCategory) { + if (list.items[i] == affectedActionTypeCategory) { mutateActionTimerCore(action, [=](double timerValue){return amount;}); break; } From ae532e14528214b8ff3e24c827172911a87e2caf Mon Sep 17 00:00:00 2001 From: Tachytaenius Date: Thu, 1 Dec 2022 23:22:02 +0000 Subject: [PATCH 20/25] Rename affectedActionTypeCategory to affectedActionTypeGroup in action timer API --- library/include/modules/Units.h | 6 +++--- library/modules/Units.cpp | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/library/include/modules/Units.h b/library/include/modules/Units.h index 4c8513e27..158f22f54 100644 --- a/library/include/modules/Units.h +++ b/library/include/modules/Units.h @@ -227,11 +227,11 @@ DFHACK_EXPORT int getStressCategory(df::unit *unit); DFHACK_EXPORT int getStressCategoryRaw(int32_t stress_level); DFHACK_EXPORT void subtractActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type affectedActionType); -DFHACK_EXPORT void subtractCategoryActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionTypeCategory); +DFHACK_EXPORT void subtractCategoryActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionTypeGroup); DFHACK_EXPORT void multiplyActionTimers(color_ostream &out, df::unit *unit, float amount, df::unit_action_type affectedActionType); -DFHACK_EXPORT void multiplyCategoryActionTimers(color_ostream &out, df::unit *unit, float amount, df::unit_action_type_group affectedActionTypeCategory); +DFHACK_EXPORT void multiplyCategoryActionTimers(color_ostream &out, df::unit *unit, float amount, df::unit_action_type_group affectedActionTypeGroup); DFHACK_EXPORT void setActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type affectedActionType); -DFHACK_EXPORT void setCategoryActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionTypeCategory); +DFHACK_EXPORT void setCategoryActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionTypeGroup); } } diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp index 9656c75e6..3b2b285a4 100644 --- a/library/modules/Units.cpp +++ b/library/modules/Units.cpp @@ -2032,13 +2032,13 @@ void Units::subtractActionTimers(color_ostream &out, df::unit *unit, int32_t amo } } -void Units::subtractCategoryActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionTypeCategory) +void Units::subtractCategoryActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionTypeGroup) { CHECK_NULL_POINTER(unit); for (auto action : unit->actions) { auto list = ENUM_ATTR(unit_action_type, group, action->type); for (size_t i = 0; i < list.size; i++) { - if (list.items[i] == affectedActionTypeCategory) { + if (list.items[i] == affectedActionTypeGroup) { mutateActionTimerCore(action, [=](double timerValue){return max(timerValue - amount, 1.0);}); break; } @@ -2065,7 +2065,7 @@ void Units::multiplyActionTimers(color_ostream &out, df::unit *unit, float amoun } } -void Units::multiplyCategoryActionTimers(color_ostream &out, df::unit *unit, float amount, df::unit_action_type_group affectedActionTypeCategory) +void Units::multiplyCategoryActionTimers(color_ostream &out, df::unit *unit, float amount, df::unit_action_type_group affectedActionTypeGroup) { CHECK_NULL_POINTER(unit); if (!validateMultiplyActionTimerAmount(out, amount)) @@ -2073,7 +2073,7 @@ void Units::multiplyCategoryActionTimers(color_ostream &out, df::unit *unit, flo for (auto action : unit->actions) { auto list = ENUM_ATTR(unit_action_type, group, action->type); for (size_t i = 0; i < list.size; i++) { - if (list.items[i] == affectedActionTypeCategory) { + if (list.items[i] == affectedActionTypeGroup) { mutateActionTimerCore(action, [=](double timerValue){return max(timerValue * amount, 1.0);}); break; } @@ -2100,7 +2100,7 @@ void Units::setActionTimers(color_ostream &out, df::unit *unit, int32_t amount, } } -void Units::setCategoryActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionTypeCategory) +void Units::setCategoryActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionTypeGroup) { CHECK_NULL_POINTER(unit); if (!validateSetActionTimerAmount(out, amount)) @@ -2108,7 +2108,7 @@ void Units::setCategoryActionTimers(color_ostream &out, df::unit *unit, int32_t for (auto action : unit->actions) { auto list = ENUM_ATTR(unit_action_type, group, action->type); for (size_t i = 0; i < list.size; i++) { - if (list.items[i] == affectedActionTypeCategory) { + if (list.items[i] == affectedActionTypeGroup) { mutateActionTimerCore(action, [=](double timerValue){return amount;}); break; } From 083696200799b6fd6cccf034fb848ac4a0968bc5 Mon Sep 17 00:00:00 2001 From: Tachytaenius Date: Thu, 1 Dec 2022 23:24:04 +0000 Subject: [PATCH 21/25] Rename [xyz]CategoryActionTimers to [xyz]GroupActionTimers in action timer API --- library/LuaApi.cpp | 6 +++--- library/include/modules/Units.h | 6 +++--- library/modules/Units.cpp | 6 +++--- plugins/fastdwarf.cpp | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index 453a368f3..ef0b5c3dd 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -1780,11 +1780,11 @@ static const LuaWrapper::FunctionReg dfhack_units_module[] = { WRAPM(Units, getStressCategory), WRAPM(Units, getStressCategoryRaw), WRAPM(Units, subtractActionTimers), - WRAPM(Units, subtractCategoryActionTimers), + WRAPM(Units, subtractGroupActionTimers), WRAPM(Units, multiplyActionTimers), - WRAPM(Units, multiplyCategoryActionTimers), + WRAPM(Units, multiplyGroupActionTimers), WRAPM(Units, setActionTimers), - WRAPM(Units, setCategoryActionTimers), + WRAPM(Units, setGroupActionTimers), { NULL, NULL } }; diff --git a/library/include/modules/Units.h b/library/include/modules/Units.h index 158f22f54..effa7cd1a 100644 --- a/library/include/modules/Units.h +++ b/library/include/modules/Units.h @@ -227,11 +227,11 @@ DFHACK_EXPORT int getStressCategory(df::unit *unit); DFHACK_EXPORT int getStressCategoryRaw(int32_t stress_level); DFHACK_EXPORT void subtractActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type affectedActionType); -DFHACK_EXPORT void subtractCategoryActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionTypeGroup); +DFHACK_EXPORT void subtractGroupActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionTypeGroup); DFHACK_EXPORT void multiplyActionTimers(color_ostream &out, df::unit *unit, float amount, df::unit_action_type affectedActionType); -DFHACK_EXPORT void multiplyCategoryActionTimers(color_ostream &out, df::unit *unit, float amount, df::unit_action_type_group affectedActionTypeGroup); +DFHACK_EXPORT void multiplyGroupActionTimers(color_ostream &out, df::unit *unit, float amount, df::unit_action_type_group affectedActionTypeGroup); DFHACK_EXPORT void setActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type affectedActionType); -DFHACK_EXPORT void setCategoryActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionTypeGroup); +DFHACK_EXPORT void setGroupActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionTypeGroup); } } diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp index 3b2b285a4..20badb1b5 100644 --- a/library/modules/Units.cpp +++ b/library/modules/Units.cpp @@ -2032,7 +2032,7 @@ void Units::subtractActionTimers(color_ostream &out, df::unit *unit, int32_t amo } } -void Units::subtractCategoryActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionTypeGroup) +void Units::subtractGroupActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionTypeGroup) { CHECK_NULL_POINTER(unit); for (auto action : unit->actions) { @@ -2065,7 +2065,7 @@ void Units::multiplyActionTimers(color_ostream &out, df::unit *unit, float amoun } } -void Units::multiplyCategoryActionTimers(color_ostream &out, df::unit *unit, float amount, df::unit_action_type_group affectedActionTypeGroup) +void Units::multiplyGroupActionTimers(color_ostream &out, df::unit *unit, float amount, df::unit_action_type_group affectedActionTypeGroup) { CHECK_NULL_POINTER(unit); if (!validateMultiplyActionTimerAmount(out, amount)) @@ -2100,7 +2100,7 @@ void Units::setActionTimers(color_ostream &out, df::unit *unit, int32_t amount, } } -void Units::setCategoryActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionTypeGroup) +void Units::setGroupActionTimers(color_ostream &out, df::unit *unit, int32_t amount, df::unit_action_type_group affectedActionTypeGroup) { CHECK_NULL_POINTER(unit); if (!validateSetActionTimerAmount(out, amount)) diff --git a/plugins/fastdwarf.cpp b/plugins/fastdwarf.cpp index ea18437d6..fe0b90be5 100644 --- a/plugins/fastdwarf.cpp +++ b/plugins/fastdwarf.cpp @@ -83,7 +83,7 @@ DFhackCExport command_result plugin_onupdate ( color_ostream &out ) if (enable_fastdwarf) { - Units::setCategoryActionTimers(out, unit, 1, df::unit_action_type_group::All); + Units::setGroupActionTimers(out, unit, 1, df::unit_action_type_group::All); } } return CR_OK; From 370ffe274f46175048c750991e569a259d6ebc34 Mon Sep 17 00:00:00 2001 From: Tachytaenius Date: Thu, 1 Dec 2022 23:25:01 +0000 Subject: [PATCH 22/25] Add Lua API docs for action timer API --- docs/dev/Lua API.rst | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/docs/dev/Lua API.rst b/docs/dev/Lua API.rst index 37865394e..bbc56b03b 100644 --- a/docs/dev/Lua API.rst +++ b/docs/dev/Lua API.rst @@ -1548,6 +1548,49 @@ Units module Returns a table of the cutoffs used by the above stress level functions. +Action Timer API +~~~~~~~~~~~~~~~~ + +This is an API to allow manipulation of unit action timers, to speed them up or slow them down. +All functions in this API have overflow/underflow protection when modifying action timers (the value will cap out). +``affectedActionType`` parameters are integers from the DF enum ``unit_action_type``. E.g. ``df.unit_action_type.Move``. +``affectedActionTypeGroup`` parameters are integers from the (custom) DF enum ``unit_action_type_group``. They are as follows: + + * ``All`` (does not include unknown unit action types) + * ``Movement`` + * ``MovementFeet`` (check if the unit is not on ground before using this one?) + * ``Combat`` (includes bloodsucking) + * ``Work`` + +API functions: + +* ``subtractActionTimers(unit, amount, affectedActionType)`` + + Subtract ``amount`` (32-bit integer) from the timers of any actions the unit is performing of ``affectedActionType`` + (usually one or zero actions in normal gameplay). + +* ``subtractGroupActionTimers(unit, amount, affectedActionTypeGroup)`` + + Subtract ``amount`` (32-bit integer) from the timers of any actions the unit is performing that match the ``affectedActionTypeGroup`` category. + +* ``multiplyActionTimers(unit, amount, affectedActionType)`` + + Multiply the timers of any actions of ``affectedActionType`` the unit is performing by ``amount`` (float) + (usually one or zero actions in normal gameplay). + +* ``multiplyGroupActionTimers(unit, amount, affectedActionTypeGroup)`` + + Multiply the timers of any actions that match the ``affectedActionTypeGroup`` category the unit is performing by ``amount`` (float). + +* ``setActionTimers(unit, amount, affectedActionType)`` + + Set the timers of any action the unit is performing of ``affectedActionType`` to ``amount`` (32-bit integer) + (usually one or zero actions in normal gameplay). + +* ``setGroupActionTimers(unit, amount, affectedActionTypeGroup)`` + + Set the timers of any action the unit is performing that match the ``affectedActionTypeGroup`` category to ``amount`` (32-bit integer). + Items module ------------ From cd5ee666cf7f7e5dbc9e1b5930dc628bbcd7b93f Mon Sep 17 00:00:00 2001 From: Tachytaenius Date: Thu, 1 Dec 2022 23:52:00 +0000 Subject: [PATCH 23/25] Update modding guide to reflect new action timer API --- docs/guides/modding-guide.rst | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/guides/modding-guide.rst b/docs/guides/modding-guide.rst index da33a5a9d..e602e632d 100644 --- a/docs/guides/modding-guide.rst +++ b/docs/guides/modding-guide.rst @@ -316,7 +316,7 @@ item in the raws:: [METAL] [LEATHER] [HARD] - [PEGASUS_BOOTS_MOD_MOVEMENT_TIMER_REDUCTION_PER_TICK:5] custom raw token + [PEGASUS_BOOTS_MOD_FOOT_MOVEMENT_TIMER_REDUCTION_PER_TICK:2] custom raw token (you don't have to comment the custom token every time, but it does clarify what it is) @@ -327,8 +327,7 @@ Then, let's make a ``repeat-util`` callback for once a tick:: repeatUtil.scheduleEvery(modId, 1, "ticks", function() Let's iterate over every active unit, and for every unit, iterate over their -worn items to calculate how much we are going to take from their movement -timer:: +worn items to calculate how much we are going to take from their on-foot movement timers:: for _, unit in ipairs(df.global.world.units.active) do local amount = 0 @@ -336,15 +335,16 @@ timer:: if entry.mode == df.unit_inventory_item.T_mode.Worn then local reduction = customRawTokens.getToken( entry.item, - 'PEGASUS_BOOTS_MOD_MOVEMENT_TIMER_REDUCTION_PER_TICK') + 'PEGASUS_BOOTS_MOD_FOOT_MOVEMENT_TIMER_REDUCTION_PER_TICK') amount = amount + (tonumber(reduction) or 0) end end + -- Subtract amount from on-foot movement timers if not on ground + if not unit.flags1.on_ground then + dfhack.units.subtractActionTimers(unit, amount, df.unit_action_type_group.MovementFeet) + end end - -- Subtract amount from movement timer if currently moving - dfhack.units.addMoveTimer(-amount) - The structure of a full mod --------------------------- From 0b0bd71a0c96bb7b81b2ccbd0813a1b318c31ea1 Mon Sep 17 00:00:00 2001 From: Tachytaenius Date: Fri, 2 Dec 2022 12:51:49 +0000 Subject: [PATCH 24/25] Adjust action timer API Lua API docs --- docs/dev/Lua API.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/dev/Lua API.rst b/docs/dev/Lua API.rst index bbc56b03b..8eb5e2c74 100644 --- a/docs/dev/Lua API.rst +++ b/docs/dev/Lua API.rst @@ -1553,12 +1553,14 @@ Action Timer API This is an API to allow manipulation of unit action timers, to speed them up or slow them down. All functions in this API have overflow/underflow protection when modifying action timers (the value will cap out). +Actions with a timer of 0 (or less) will not be modified as they are completed (or invalid in the case of negatives). +Timers will be capped to go no lower than 1. ``affectedActionType`` parameters are integers from the DF enum ``unit_action_type``. E.g. ``df.unit_action_type.Move``. ``affectedActionTypeGroup`` parameters are integers from the (custom) DF enum ``unit_action_type_group``. They are as follows: * ``All`` (does not include unknown unit action types) * ``Movement`` - * ``MovementFeet`` (check if the unit is not on ground before using this one?) + * ``MovementFeet`` (intended to only be used when the unit is standing, such as with pegasus boots from the modding guide) * ``Combat`` (includes bloodsucking) * ``Work`` From c7d1baacb32960ebaa47a510fb5ecf7a7c44d4c3 Mon Sep 17 00:00:00 2001 From: Tachytaenius Date: Fri, 2 Dec 2022 17:03:04 +0000 Subject: [PATCH 25/25] Update docs/dev/Lua API.rst Co-authored-by: Myk --- docs/dev/Lua API.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dev/Lua API.rst b/docs/dev/Lua API.rst index 8eb5e2c74..b8a94f59c 100644 --- a/docs/dev/Lua API.rst +++ b/docs/dev/Lua API.rst @@ -1560,7 +1560,7 @@ Timers will be capped to go no lower than 1. * ``All`` (does not include unknown unit action types) * ``Movement`` - * ``MovementFeet`` (intended to only be used when the unit is standing, such as with pegasus boots from the modding guide) + * ``MovementFeet`` (for walking speed, such as with pegasus boots from the `modding-guide`) * ``Combat`` (includes bloodsucking) * ``Work``