Move curse-affected attribute value getters to the core.

develop
Alexander Gavrilov 2012-09-09 12:51:08 +04:00
parent a36fe25e72
commit ec3d489bda
5 changed files with 77 additions and 32 deletions

@ -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)``

@ -1106,6 +1106,14 @@ a lua list containing them.</p>
<li><p class="first"><tt class="docutils literal">dfhack.units.getNemesis(unit)</tt></p>
<p>Returns the nemesis record of the unit if it has one, or <em>nil</em>.</p>
</li>
<li><p class="first"><tt class="docutils literal">dfhack.units.isHidingCurse(unit)</tt></p>
<p>Checks if the unit hides improved attributes from its curse.</p>
</li>
<li><p class="first"><tt class="docutils literal">dfhack.units.getPhysicalAttrValue(unit, attr_type)</tt></p>
</li>
<li><p class="first"><tt class="docutils literal">dfhack.units.getMentalAttrValue(unit, attr_type)</tt></p>
<p>Computes the effective attribute value, including curse effect.</p>
</li>
<li><p class="first"><tt class="docutils literal">dfhack.units.isCrazed(unit)</tt></p>
</li>
<li><p class="first"><tt class="docutils literal">dfhack.units.isOpposedToLife(unit)</tt></p>

@ -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);

@ -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);

@ -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)