From 93ed45d6e73efd5fa83a803ba868c8f80fc77231 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sat, 12 Aug 2023 23:29:45 -0700 Subject: [PATCH 1/3] handle small pets, similar to vermin --- plugins/lua/zone.lua | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/plugins/lua/zone.lua b/plugins/lua/zone.lua index 4637f1b3f..b30ba3a5c 100644 --- a/plugins/lua/zone.lua +++ b/plugins/lua/zone.lua @@ -466,7 +466,7 @@ local function get_unit_disposition(unit) return disposition.value end -local function get_vermin_disposition(vermin) +local function get_item_disposition(item) -- TODO return DISPOSITION.TAME.value end @@ -479,8 +479,8 @@ local function is_assignable_unit(unit) not dfhack.units.isForest(unit) end -local function is_assignable_vermin(vermin) - -- TODO are there unassignable vermin? +local function is_assignable_item(item) + -- TODO are there unassignable vermin/small pets? return true end @@ -489,6 +489,11 @@ local function get_vermin_desc(vermin, raw) return ('%s [%d]'):format(raw.name[1], vermin.stack_size) end +local function get_small_pet_desc(raw) + if not raw then return 'Unknown small pet' end + return ('tame %s'):format(raw.name[0]) +end + function AssignAnimal:cache_choices() if self.choices then return self.choices end @@ -516,7 +521,7 @@ function AssignAnimal:cache_choices() ::continue:: end for _, vermin in ipairs(df.global.world.items.other.VERMIN) do - if not is_assignable_vermin(vermin) then goto continue end + if not is_assignable_item(vermin) then goto continue end local raw = df.creature_raw.find(vermin.race) local data = { vermin=vermin, @@ -524,7 +529,26 @@ function AssignAnimal:cache_choices() gender=df.pronoun_type.it, race=raw and raw.creature_id or -1, status=self.get_status(vermin, bld_assignments), - disposition=get_vermin_disposition(vermin), + disposition=get_item_disposition(vermin), + } + local choice = { + search_key=make_search_key(data.desc), + data=data, + text=self:make_choice_text(data), + } + table.insert(choices, choice) + ::continue:: + end + for _, small_pet in ipairs(df.global.world.items.other.PET) do + if not is_assignable_item(small_pet) then goto continue end + local raw = df.creature_raw.find(small_pet.race) + local data = { + vermin=small_pet, + desc=get_small_pet_desc(raw), + gender=df.pronoun_type.it, + race=raw and raw.creature_id or -1, + status=self.get_status(small_pet, bld_assignments), + disposition=get_item_disposition(small_pet), } local choice = { search_key=make_search_key(data.desc), From 296a34834c986290ff9ba435e9bf48f15821de82 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sun, 13 Aug 2023 00:20:08 -0700 Subject: [PATCH 2/3] expose and use casteFlagSet --- docs/dev/Lua API.rst | 5 +++++ library/LuaApi.cpp | 1 + plugins/lua/zone.lua | 23 ++++++++++++++++++----- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/docs/dev/Lua API.rst b/docs/dev/Lua API.rst index 08b20e1b3..f29df78c6 100644 --- a/docs/dev/Lua API.rst +++ b/docs/dev/Lua API.rst @@ -1525,6 +1525,11 @@ Units module Computes the effective attribute value, including curse effect. +* ``dfhack.units.casteFlagSet(race, caste, flag)`` + + Returns whether the given ``df.caste_raw_flags`` flag is set for the given + race and caste. + * ``dfhack.units.getMiscTrait(unit, type[, create])`` Finds (or creates if requested) a misc trait object with the given id. diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index 9dc86b526..beaf50579 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -1816,6 +1816,7 @@ static const LuaWrapper::FunctionReg dfhack_units_module[] = { WRAPM(Units, getNemesis), WRAPM(Units, getPhysicalAttrValue), WRAPM(Units, getMentalAttrValue), + WRAPM(Units, casteFlagSet), WRAPM(Units, getMiscTrait), WRAPM(Units, getAge), WRAPM(Units, getKillCount), diff --git a/plugins/lua/zone.lua b/plugins/lua/zone.lua index b30ba3a5c..29859e419 100644 --- a/plugins/lua/zone.lua +++ b/plugins/lua/zone.lua @@ -450,7 +450,9 @@ end local function get_unit_disposition(unit) local disposition = DISPOSITION.NONE - if dfhack.units.isPet(unit) then + if dfhack.units.isInvader(unit) or dfhack.units.isOpposedToLife(unit) then + disposition = DISPOSITION.HOSTILE + elseif dfhack.units.isPet(unit) then disposition = DISPOSITION.PET elseif dfhack.units.isDomesticated(unit) then disposition = DISPOSITION.TAME @@ -458,8 +460,6 @@ local function get_unit_disposition(unit) disposition = DISPOSITION.TRAINED elseif dfhack.units.isTamable(unit) then disposition = DISPOSITION.WILD_TRAINABLE - elseif dfhack.units.isInvader(unit) or dfhack.units.isOpposedToLife(unit) then - disposition = DISPOSITION.HOSTILE else disposition = DISPOSITION.WILD_UNTRAINABLE end @@ -467,8 +467,21 @@ local function get_unit_disposition(unit) end local function get_item_disposition(item) - -- TODO - return DISPOSITION.TAME.value + local disposition = DISPOSITION.NONE + if dfhack.units.casteFlagSet(item.race, item.caste, df.caste_raw_flags.OPPOSED_TO_LIFE) then + disposition = DISPOSITION.HOSTILE + -- elseif dfhack.units.isPet(unit) then + -- disposition = DISPOSITION.PET + -- elseif dfhack.units.isDomesticated(unit) then + -- disposition = DISPOSITION.TAME + elseif dfhack.units.casteFlagSet(item.race, item.caste, df.caste_raw_flags.PET) or + dfhack.units.casteFlagSet(item.race, item.caste, df.caste_raw_flags.PET_EXOTIC) + then + disposition = DISPOSITION.WILD_TRAINABLE + else + disposition = DISPOSITION.WILD_UNTRAINABLE + end + return disposition.value end local function is_assignable_unit(unit) From 463a8647e6c5fcf7d13f9dd39e1a9b252a249205 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sun, 13 Aug 2023 02:45:04 -0700 Subject: [PATCH 3/3] complete vermin and small animal support --- plugins/lua/zone.lua | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/plugins/lua/zone.lua b/plugins/lua/zone.lua index 29859e419..ef28a91b3 100644 --- a/plugins/lua/zone.lua +++ b/plugins/lua/zone.lua @@ -467,21 +467,23 @@ local function get_unit_disposition(unit) end local function get_item_disposition(item) - local disposition = DISPOSITION.NONE if dfhack.units.casteFlagSet(item.race, item.caste, df.caste_raw_flags.OPPOSED_TO_LIFE) then - disposition = DISPOSITION.HOSTILE - -- elseif dfhack.units.isPet(unit) then - -- disposition = DISPOSITION.PET - -- elseif dfhack.units.isDomesticated(unit) then - -- disposition = DISPOSITION.TAME - elseif dfhack.units.casteFlagSet(item.race, item.caste, df.caste_raw_flags.PET) or + return DISPOSITION.HOSTILE.value + end + + if df.item_petst:is_instance(item) then + if item.owner_id > -1 then + return DISPOSITION.PET.value + end + return DISPOSITION.TAME.value + end + + if dfhack.units.casteFlagSet(item.race, item.caste, df.caste_raw_flags.PET) or dfhack.units.casteFlagSet(item.race, item.caste, df.caste_raw_flags.PET_EXOTIC) then - disposition = DISPOSITION.WILD_TRAINABLE - else - disposition = DISPOSITION.WILD_UNTRAINABLE + return DISPOSITION.WILD_TRAINABLE.value end - return disposition.value + return DISPOSITION.WILD_UNTRAINABLE.value end local function is_assignable_unit(unit) @@ -493,13 +495,16 @@ local function is_assignable_unit(unit) end local function is_assignable_item(item) - -- TODO are there unassignable vermin/small pets? + -- all vermin/small pets are assignable return true end local function get_vermin_desc(vermin, raw) if not raw then return 'Unknown vermin' end - return ('%s [%d]'):format(raw.name[1], vermin.stack_size) + if vermin.stack_size > 1 then + return ('%s [%d]'):format(raw.name[1], vermin.stack_size) + end + return ('%s'):format(raw.name[0]) end local function get_small_pet_desc(raw) @@ -519,7 +524,7 @@ function AssignAnimal:cache_choices() unit=unit, desc=dfhack.units.getReadableName(unit), gender=unit.sex, - race=raw and raw.creature_id or -1, + race=raw and raw.creature_id or '', status=self.get_status(unit, bld_assignments), disposition=get_unit_disposition(unit), egg=dfhack.units.isEggLayerRace(unit), @@ -540,7 +545,7 @@ function AssignAnimal:cache_choices() vermin=vermin, desc=get_vermin_desc(vermin, raw), gender=df.pronoun_type.it, - race=raw and raw.creature_id or -1, + race=raw and raw.creature_id or '', status=self.get_status(vermin, bld_assignments), disposition=get_item_disposition(vermin), } @@ -559,7 +564,7 @@ function AssignAnimal:cache_choices() vermin=small_pet, desc=get_small_pet_desc(raw), gender=df.pronoun_type.it, - race=raw and raw.creature_id or -1, + race=raw and raw.creature_id or '', status=self.get_status(small_pet, bld_assignments), disposition=get_item_disposition(small_pet), }