From ec3d489bda19f8ab2a45fbb19d7259ea3f4ad75b Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Sun, 9 Sep 2012 12:51:08 +0400 Subject: [PATCH] Move curse-affected attribute value getters to the core. --- LUA_API.rst | 9 ++++++ Lua API.html | 8 +++++ library/include/modules/Units.h | 6 ++++ library/modules/Units.cpp | 52 +++++++++++++++++++++++++++++++++ plugins/devel/siege-engine.cpp | 34 ++------------------- 5 files changed, 77 insertions(+), 32 deletions(-) diff --git a/LUA_API.rst b/LUA_API.rst index 48d2c19e6..686b90038 100644 --- a/LUA_API.rst +++ b/LUA_API.rst @@ -868,6 +868,15 @@ Units module Returns the nemesis record of the unit if it has one, or *nil*. +* ``dfhack.units.isHidingCurse(unit)`` + + Checks if the unit hides improved attributes from its curse. + +* ``dfhack.units.getPhysicalAttrValue(unit, attr_type)`` +* ``dfhack.units.getMentalAttrValue(unit, attr_type)`` + + Computes the effective attribute value, including curse effect. + * ``dfhack.units.isCrazed(unit)`` * ``dfhack.units.isOpposedToLife(unit)`` * ``dfhack.units.hasExtravision(unit)`` diff --git a/Lua API.html b/Lua API.html index c302c29f7..12bcf5fa8 100644 --- a/Lua API.html +++ b/Lua API.html @@ -1106,6 +1106,14 @@ a lua list containing them.

  • dfhack.units.getNemesis(unit)

    Returns the nemesis record of the unit if it has one, or nil.

  • +
  • dfhack.units.isHidingCurse(unit)

    +

    Checks if the unit hides improved attributes from its curse.

    +
  • +
  • dfhack.units.getPhysicalAttrValue(unit, attr_type)

    +
  • +
  • dfhack.units.getMentalAttrValue(unit, attr_type)

    +

    Computes the effective attribute value, including curse effect.

    +
  • dfhack.units.isCrazed(unit)

  • dfhack.units.isOpposedToLife(unit)

    diff --git a/library/include/modules/Units.h b/library/include/modules/Units.h index ece151127..3fba5c218 100644 --- a/library/include/modules/Units.h +++ b/library/include/modules/Units.h @@ -33,6 +33,8 @@ distribution. #include "DataDefs.h" #include "df/unit.h" #include "df/misc_trait_type.h" +#include "df/physical_attribute_type.h" +#include "df/mental_attribute_type.h" #include "df/job_skill.h" namespace df @@ -211,6 +213,10 @@ DFHACK_EXPORT df::language_name *getVisibleName(df::unit *unit); DFHACK_EXPORT df::assumed_identity *getIdentity(df::unit *unit); DFHACK_EXPORT df::nemesis_record *getNemesis(df::unit *unit); +DFHACK_EXPORT bool isHidingCurse(df::unit *unit); +DFHACK_EXPORT int getPhysicalAttrValue(df::unit *unit, df::physical_attribute_type attr); +DFHACK_EXPORT int getMentalAttrValue(df::unit *unit, df::mental_attribute_type attr); + DFHACK_EXPORT bool isCrazed(df::unit *unit); DFHACK_EXPORT bool isOpposedToLife(df::unit *unit); DFHACK_EXPORT bool hasExtravision(df::unit *unit); diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp index 6a672b585..1565dbbd3 100644 --- a/library/modules/Units.cpp +++ b/library/modules/Units.cpp @@ -617,6 +617,58 @@ df::nemesis_record *Units::getNemesis(df::unit *unit) return NULL; } + +bool Units::isHidingCurse(df::unit *unit) +{ + if (!unit->job.hunt_target) + { + auto identity = Units::getIdentity(unit); + if (identity && identity->unk_4c == 0) + return true; + } + + return false; +} + +int Units::getPhysicalAttrValue(df::unit *unit, df::physical_attribute_type attr) +{ + auto &aobj = unit->body.physical_attrs[attr]; + int value = std::max(0, aobj.value - aobj.soft_demotion); + + if (auto mod = unit->curse.attr_change) + { + int mvalue = (value * mod->phys_att_perc[attr]) + mod->phys_att_add[attr]; + + if (isHidingCurse(unit)) + value = std::min(value, mvalue); + else + value = mvalue; + } + + return value; +} + +int Units::getMentalAttrValue(df::unit *unit, df::mental_attribute_type attr) +{ + auto soul = unit->status.current_soul; + if (!soul) return 0; + + auto &aobj = soul->mental_attrs[attr]; + int value = std::max(0, aobj.value - aobj.soft_demotion); + + if (auto mod = unit->curse.attr_change) + { + int mvalue = (value * mod->ment_att_perc[attr]) + mod->ment_att_add[attr]; + + if (isHidingCurse(unit)) + value = std::min(value, mvalue); + else + value = mvalue; + } + + return value; +} + static bool casteFlagSet(int race, int caste, df::caste_raw_flags flag) { auto creature = df::creature_raw::find(race); diff --git a/plugins/devel/siege-engine.cpp b/plugins/devel/siege-engine.cpp index 8b5010194..648e4c3b2 100644 --- a/plugins/devel/siege-engine.cpp +++ b/plugins/devel/siege-engine.cpp @@ -501,28 +501,6 @@ static void paintAimScreen(df::building_siegeenginest *bld, df::coord view, df:: * Unit tracking */ -static int getAttrValue(const df::unit_attribute &attr) -{ - return std::max(0, attr.value - attr.soft_demotion); -} - -static int getPhysAttrValue(df::unit *unit, df::physical_attribute_type attr, bool hide_curse) -{ - int value = getAttrValue(unit->body.physical_attrs[attr]); - - if (auto mod = unit->curse.attr_change) - { - int mvalue = (value * mod->phys_att_perc[attr]) + mod->phys_att_add[attr]; - - if (hide_curse) - value = std::min(value, mvalue); - else - value = mvalue; - } - - return value; -} - int getSpeedRating(df::unit *unit) { using namespace df::enums::physical_attribute_type; @@ -635,18 +613,10 @@ int getSpeedRating(df::unit *unit) speed = std::max(speed*3/4, std::min(speed*3/2, int(int64_t(speed)*strength/agility))); // Attributes - bool hide_curse = false; - if (!unit->job.hunt_target) - { - auto identity = Units::getIdentity(unit); - if (identity && identity->unk_4c == 0) - hide_curse = true; - } + int strength_attr = Units::getPhysicalAttrValue(unit, STRENGTH); + int agility_attr = Units::getPhysicalAttrValue(unit, AGILITY); - int strength_attr = getPhysAttrValue(unit, STRENGTH, hide_curse); - int agility_attr = getPhysAttrValue(unit, AGILITY, hide_curse); int total_attr = std::max(200, std::min(3800, strength_attr + agility_attr)); - speed = ((total_attr-200)*(speed*3/2) + (3800-total_attr)*(speed/2))/4800; // ?? if (!unit->flags1.bits.on_ground && unit->status2.able_stand > 2)