From d4626f9751be95e392cf1a0862648bae1e2d0e43 Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Sun, 18 Mar 2012 15:35:38 +0400 Subject: [PATCH] Add unit professions and filtering on status. --- library/RemoteTools.cpp | 28 ++++++++++++++++++++----- library/include/modules/Units.h | 4 ++++ library/modules/Units.cpp | 37 +++++++++++++++++++++++++++++++++ library/proto/Basic.proto | 5 +++++ library/proto/BasicApi.proto | 7 +++++++ 5 files changed, 76 insertions(+), 5 deletions(-) diff --git a/library/RemoteTools.cpp b/library/RemoteTools.cpp index 9323c9363..68f29e4f8 100644 --- a/library/RemoteTools.cpp +++ b/library/RemoteTools.cpp @@ -273,6 +273,7 @@ void DFHack::describeUnit(BasicUnitInfo *info, df::unit *unit, info->set_civ_id(unit->civ_id); if (unit->hist_figure_id >= 0) info->set_histfig_id(unit->hist_figure_id); + if (unit->counters.death_id >= 0) { info->set_death_id(unit->counters.death_id); @@ -280,10 +281,18 @@ void DFHack::describeUnit(BasicUnitInfo *info, df::unit *unit, info->set_death_flags(death->flags.whole); } - if (unit->military.squad_index >= 0) + if (mask && mask->profession()) { - info->set_squad_id(unit->military.squad_index); - info->set_squad_position(unit->military.squad_position); + if (unit->profession >= 0) + info->set_profession(unit->profession); + if (!unit->custom_profession.empty()) + info->set_custom_profession(unit->custom_profession); + + if (unit->military.squad_index >= 0) + { + info->set_squad_id(unit->military.squad_index); + info->set_squad_position(unit->military.squad_position); + } } if (mask && mask->labors()) @@ -429,6 +438,8 @@ static command_result ListEnums(color_ostream &stream, describe_bitfield(out->mutable_death_info_flags()); + ENUM(profession); + #undef ENUM #undef BITFIELD } @@ -505,7 +516,8 @@ static command_result ListUnits(color_ostream &stream, describeUnit(out->add_value(), unit, mask); } } - else + + if (in->scan_all()) { auto &vec = df::unit::get_vector(); @@ -515,7 +527,13 @@ static command_result ListUnits(color_ostream &stream, if (in->has_race() && unit->race != in->race()) continue; - if (in->civ_id() && unit->civ_id != in->civ_id()) + if (in->has_civ_id() && unit->civ_id != in->civ_id()) + continue; + if (in->has_dead() && Units::isDead(unit) != in->dead()) + continue; + if (in->has_alive() && Units::isAlive(unit) != in->alive()) + continue; + if (in->has_sane() && Units::isSane(unit) != in->sane()) continue; describeUnit(out->add_value(), unit, mask); diff --git a/library/include/modules/Units.h b/library/include/modules/Units.h index 6df8b2c19..0fd75bf1f 100644 --- a/library/include/modules/Units.h +++ b/library/include/modules/Units.h @@ -194,6 +194,10 @@ DFHACK_EXPORT bool RemoveOwnedItemByIdx(const uint32_t index, int32_t id); DFHACK_EXPORT bool RemoveOwnedItemByPtr(df::unit * unit, int32_t id); DFHACK_EXPORT df::language_name *GetVisibleName(df::unit *unit); + +DFHACK_EXPORT bool isDead(df::unit *unit); +DFHACK_EXPORT bool isAlive(df::unit *unit); +DFHACK_EXPORT bool isSane(df::unit *unit); } } #endif diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp index 9e97f8e74..f6259bd3b 100644 --- a/library/modules/Units.cpp +++ b/library/modules/Units.cpp @@ -54,6 +54,7 @@ using namespace std; #include "df/assumed_identity.h" using namespace DFHack; +using namespace df::enums; using df::global::world; using df::global::ui; @@ -551,3 +552,39 @@ df::language_name *Units::GetVisibleName(df::unit *unit) return &unit->name; } + +bool DFHack::Units::isDead(df::unit *unit) +{ + return unit->flags1.bits.dead; +} + +bool DFHack::Units::isAlive(df::unit *unit) +{ + return !unit->flags1.bits.dead && + !unit->flags3.bits.ghostly && + !unit->curse.add_tags1.bits.NOT_LIVING; +} + +bool DFHack::Units::isSane(df::unit *unit) +{ + if (unit->flags1.bits.dead || + unit->flags3.bits.ghostly || + unit->curse.add_tags1.bits.OPPOSED_TO_LIFE || + unit->curse.add_tags1.bits.CRAZED) + return false; + + if (unit->flags1.bits.has_mood) + { + switch (unit->mood) + { + case mood_type::Melancholy: + case mood_type::Raving: + case mood_type::Berserk: + return false; + default: + break; + } + } + + return true; +} diff --git a/library/proto/Basic.proto b/library/proto/Basic.proto index 2c11aa67c..ead41cd81 100644 --- a/library/proto/Basic.proto +++ b/library/proto/Basic.proto @@ -123,9 +123,13 @@ message BasicUnitInfo { optional int32 death_id = 17 [default = -1]; optional uint32 death_flags = 18; + // IF mask.profession: optional int32 squad_id = 19 [default = -1]; optional int32 squad_position = 20 [default = -1]; + optional int32 profession = 22 [default = -1]; + optional string custom_profession = 23; + // IF mask.labors: repeated int32 labors = 11; @@ -140,6 +144,7 @@ message BasicUnitInfo { message BasicUnitInfoMask { optional bool labors = 1 [default = false]; optional bool skills = 2 [default = false]; + optional bool profession = 3 [default = false]; }; message BasicSquadInfo { diff --git a/library/proto/BasicApi.proto b/library/proto/BasicApi.proto index cc251a7c6..7b105ee88 100644 --- a/library/proto/BasicApi.proto +++ b/library/proto/BasicApi.proto @@ -42,6 +42,8 @@ message ListEnumsOut { repeated EnumItemName cie_add_tag_mask2 = 9; repeated EnumItemName death_info_flags = 10; + + repeated EnumItemName profession = 11; }; message ListMaterialsIn { @@ -67,8 +69,13 @@ message ListUnitsIn { repeated int32 id_list = 2; // All units matching: + optional bool scan_all = 5; + optional int32 race = 3; optional int32 civ_id = 4; + optional bool dead = 6; // i.e. passive corpse + optional bool alive = 7; // i.e. not dead or undead + optional bool sane = 8; // not dead, ghost, zombie, or insane }; message ListUnitsOut { repeated BasicUnitInfo value = 1;