Merge pull request #3688 from myk002/myk_training

[autobutcher] don't slaughter animals marked for training
develop
Myk 2023-08-20 22:57:02 -07:00 committed by GitHub
commit 85de598775
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 51 additions and 7 deletions

@ -64,6 +64,7 @@ Template for new versions:
## Misc Improvements ## Misc Improvements
- Surround DFHack-specific UI elements with square brackets instead of red-yellow blocks for better readability - Surround DFHack-specific UI elements with square brackets instead of red-yellow blocks for better readability
- `autobutcher`: don't mark animals for butchering if they are already marked for some kind of training (war, hunt)
- `hotkeys`: don't display DFHack logo in legends mode since it covers up important interface elements. the Ctrl-Shift-C hotkey to bring up the menu and the mouseover hotspot still function, though. - `hotkeys`: don't display DFHack logo in legends mode since it covers up important interface elements. the Ctrl-Shift-C hotkey to bring up the menu and the mouseover hotspot still function, though.
- `sort`: animals are now sortable by race on the assignment screens - `sort`: animals are now sortable by race on the assignment screens
@ -72,6 +73,7 @@ Template for new versions:
## API ## API
- ``Items::getValue()``: remove ``caravan_buying`` parameter since the identity of the selling party doesn't actually affect the item value - ``Items::getValue()``: remove ``caravan_buying`` parameter since the identity of the selling party doesn't actually affect the item value
- `RemoteFortressReader`: add a ``force_reload`` option to the GetBlockList RPC API to return blocks regardless of whether they have changed since the last request - `RemoteFortressReader`: add a ``force_reload`` option to the GetBlockList RPC API to return blocks regardless of whether they have changed since the last request
- ``Units``: new animal propery check functions ``isMarkedForTraining(unit)``, ``isMarkedForTaming(unit)``, ``isMarkedForWarTraining(unit)``, and ``isMarkedForHuntTraining(unit)``
## Lua ## Lua
- ``new()``: improved error handling so that certain errors that were previously uncatchable (creating objects with members with unknown vtables) are now catchable with ``pcall()`` - ``new()``: improved error handling so that certain errors that were previously uncatchable (creating objects with members with unknown vtables) are now catchable with ``pcall()``
@ -79,6 +81,7 @@ Template for new versions:
- ``widgets.BannerPanel``: panel with distinctive border for marking DFHack UI elements on otherwise vanilla screens - ``widgets.BannerPanel``: panel with distinctive border for marking DFHack UI elements on otherwise vanilla screens
- ``widgets.Panel``: new functions to override instead of setting corresponding properties (useful when subclassing instead of just setting attributes): ``onDragBegin``, ``onDragEnd``, ``onResizeBegin``, ``onResizeEnd`` - ``widgets.Panel``: new functions to override instead of setting corresponding properties (useful when subclassing instead of just setting attributes): ``onDragBegin``, ``onDragEnd``, ``onResizeBegin``, ``onResizeEnd``
- ``dfhack.screen.readTile()``: now populates extended tile property fields (like ``top_of_text``) in the returned ``Pen`` object - ``dfhack.screen.readTile()``: now populates extended tile property fields (like ``top_of_text``) in the returned ``Pen`` object
- ``dfhack.units``: new animal propery check functions ``isMarkedForTraining(unit)``, ``isMarkedForTaming(unit)``, ``isMarkedForWarTraining(unit)``, and ``isMarkedForHuntTraining(unit)``
## Removed ## Removed

@ -1380,6 +1380,10 @@ Units module
* ``dfhack.units.isTame(unit)`` * ``dfhack.units.isTame(unit)``
* ``dfhack.units.isTamable(unit)`` * ``dfhack.units.isTamable(unit)``
* ``dfhack.units.isDomesticated(unit)`` * ``dfhack.units.isDomesticated(unit)``
* ``dfhack.units.isMarkedForTraining(unit)``
* ``dfhack.units.isMarkedForTaming(unit)``
* ``dfhack.units.isMarkedForWarTraining(unit)``
* ``dfhack.units.isMarkedForHuntTraining(unit)``
* ``dfhack.units.isMarkedForSlaughter(unit)`` * ``dfhack.units.isMarkedForSlaughter(unit)``
* ``dfhack.units.isMarkedForGelding(unit)`` * ``dfhack.units.isMarkedForGelding(unit)``
* ``dfhack.units.isGeldable(unit)`` * ``dfhack.units.isGeldable(unit)``

@ -1777,6 +1777,10 @@ static const LuaWrapper::FunctionReg dfhack_units_module[] = {
WRAPM(Units, isTame), WRAPM(Units, isTame),
WRAPM(Units, isTamable), WRAPM(Units, isTamable),
WRAPM(Units, isDomesticated), WRAPM(Units, isDomesticated),
WRAPM(Units, isMarkedForTraining),
WRAPM(Units, isMarkedForTaming),
WRAPM(Units, isMarkedForWarTraining),
WRAPM(Units, isMarkedForHuntTraining),
WRAPM(Units, isMarkedForSlaughter), WRAPM(Units, isMarkedForSlaughter),
WRAPM(Units, isMarkedForGelding), WRAPM(Units, isMarkedForGelding),
WRAPM(Units, isGeldable), WRAPM(Units, isGeldable),

@ -109,6 +109,10 @@ DFHACK_EXPORT bool isWar(df::unit* unit);
DFHACK_EXPORT bool isTame(df::unit* unit); DFHACK_EXPORT bool isTame(df::unit* unit);
DFHACK_EXPORT bool isTamable(df::unit* unit); DFHACK_EXPORT bool isTamable(df::unit* unit);
DFHACK_EXPORT bool isDomesticated(df::unit* unit); DFHACK_EXPORT bool isDomesticated(df::unit* unit);
DFHACK_EXPORT bool isMarkedForTraining(df::unit* unit);
DFHACK_EXPORT bool isMarkedForTaming(df::unit* unit);
DFHACK_EXPORT bool isMarkedForWarTraining(df::unit* unit);
DFHACK_EXPORT bool isMarkedForHuntTraining(df::unit* unit);
DFHACK_EXPORT bool isMarkedForSlaughter(df::unit* unit); DFHACK_EXPORT bool isMarkedForSlaughter(df::unit* unit);
DFHACK_EXPORT bool isMarkedForGelding(df::unit* unit); DFHACK_EXPORT bool isMarkedForGelding(df::unit* unit);
DFHACK_EXPORT bool isGeldable(df::unit* unit); DFHACK_EXPORT bool isGeldable(df::unit* unit);

@ -76,6 +76,7 @@ using namespace std;
#include "df/tile_occupancy.h" #include "df/tile_occupancy.h"
#include "df/plotinfost.h" #include "df/plotinfost.h"
#include "df/syndrome.h" #include "df/syndrome.h"
#include "df/training_assignment.h"
#include "df/unit_inventory_item.h" #include "df/unit_inventory_item.h"
#include "df/unit_misc_trait.h" #include "df/unit_misc_trait.h"
#include "df/unit_relationship_type.h" #include "df/unit_relationship_type.h"
@ -510,6 +511,38 @@ bool Units::isDomesticated(df::unit* unit)
return tame; return tame;
} }
static df::training_assignment * get_training_assignment(df::unit* unit) {
return binsearch_in_vector(df::global::plotinfo->equipment.training_assignments,
&df::training_assignment::animal_id, unit->id);
}
bool Units::isMarkedForTraining(df::unit* unit)
{
CHECK_NULL_POINTER(unit);
return !!get_training_assignment(unit);
}
bool Units::isMarkedForTaming(df::unit* unit)
{
CHECK_NULL_POINTER(unit);
auto assignment = get_training_assignment(unit);
return assignment && !assignment->flags.bits.train_war && !assignment->flags.bits.train_hunt;
}
bool Units::isMarkedForWarTraining(df::unit* unit)
{
CHECK_NULL_POINTER(unit);
auto assignment = get_training_assignment(unit);
return assignment && assignment->flags.bits.train_war;
}
bool Units::isMarkedForHuntTraining(df::unit* unit)
{
CHECK_NULL_POINTER(unit);
auto assignment = get_training_assignment(unit);
return assignment && assignment->flags.bits.train_hunt;
}
bool Units::isMarkedForSlaughter(df::unit* unit) bool Units::isMarkedForSlaughter(df::unit* unit)
{ {
CHECK_NULL_POINTER(unit); CHECK_NULL_POINTER(unit);

@ -746,6 +746,7 @@ static bool isInappropriateUnit(df::unit *unit) {
static bool isProtectedUnit(df::unit *unit) { static bool isProtectedUnit(df::unit *unit) {
return Units::isWar(unit) // ignore war dogs etc return Units::isWar(unit) // ignore war dogs etc
|| Units::isHunter(unit) // ignore hunting dogs etc || Units::isHunter(unit) // ignore hunting dogs etc
|| Units::isMarkedForTraining(unit) // ignore units marked for any kind of training
// ignore creatures in built cages which are defined as rooms to leave zoos alone // ignore creatures in built cages which are defined as rooms to leave zoos alone
// (TODO: better solution would be to allow some kind of slaughter cages which you can place near the butcher) // (TODO: better solution would be to allow some kind of slaughter cages which you can place near the butcher)
|| (isContainedInItem(unit) && isInBuiltCageRoom(unit)) // !!! see comments in isBuiltCageRoom() || (isContainedInItem(unit) && isInBuiltCageRoom(unit)) // !!! see comments in isBuiltCageRoom()

@ -392,14 +392,14 @@ public:
bool is_designated(color_ostream& out, df::item* item) override { bool is_designated(color_ostream& out, df::item* item) override {
auto unit = get_caged_unit(item); auto unit = get_caged_unit(item);
return unit && has_training_assignment(unit); return unit && Units::isMarkedForTraining(unit);
} }
bool can_designate(color_ostream& out, df::item* item) override { bool can_designate(color_ostream& out, df::item* item) override {
auto unit = get_caged_unit(item); auto unit = get_caged_unit(item);
return unit && !Units::isInvader(unit) && return unit && !Units::isInvader(unit) &&
Units::isTamable(unit) && !Units::isTame(unit) && Units::isTamable(unit) && !Units::isTame(unit) &&
!has_training_assignment(unit); !Units::isMarkedForTraining(unit);
} }
bool designate(color_ostream& out, df::item* item) override { bool designate(color_ostream& out, df::item* item) override {
@ -424,11 +424,6 @@ private:
return NULL; return NULL;
return gref->getUnit(); return gref->getUnit();
} }
static bool has_training_assignment(df::unit* unit) {
return binsearch_index(df::global::plotinfo->equipment.training_assignments,
&df::training_assignment::animal_id, unit->id) > -1;
}
}; };
static const struct BadFlags { static const struct BadFlags {