Retrieve unit noble position info, and use it in getProfessionName.

develop
Alexander Gavrilov 2012-04-26 12:03:56 +04:00
parent 9489c6ed1a
commit 6ab270d129
6 changed files with 145 additions and 9 deletions

@ -728,9 +728,15 @@ Units module
Returns the age of the unit in years as a floating-point value.
If ``true_age`` is true, ignores false identities.
* ``dfhack.units.getProfessionName(unit[,plural])``
* ``dfhack.units.getNoblePositions(unit)``
Retrieves the profession name using custom profession or raws.
Returns a list of tables describing noble position assignments, or *nil*.
Every table has fields ``entity``, ``assignment`` and ``position``.
* ``dfhack.units.getProfessionName(unit[,ignore_noble,plural])``
Retrieves the profession name using custom profession, noble assignments
or raws. The ``ignore_noble`` boolean disables the use of noble positions.
* ``dfhack.units.getCasteProfessionName(race,caste,prof_id[,plural])``

@ -959,8 +959,13 @@ a lua list containing them.</p>
<p>Returns the age of the unit in years as a floating-point value.
If <tt class="docutils literal">true_age</tt> is true, ignores false identities.</p>
</li>
<li><p class="first"><tt class="docutils literal"><span class="pre">dfhack.units.getProfessionName(unit[,plural])</span></tt></p>
<p>Retrieves the profession name using custom profession or raws.</p>
<li><p class="first"><tt class="docutils literal">dfhack.units.getNoblePositions(unit)</tt></p>
<p>Returns a list of tables describing noble position assignments, or <em>nil</em>.
Every table has fields <tt class="docutils literal">entity</tt>, <tt class="docutils literal">assignment</tt> and <tt class="docutils literal">position</tt>.</p>
</li>
<li><p class="first"><tt class="docutils literal"><span class="pre">dfhack.units.getProfessionName(unit[,ignore_noble,plural])</span></tt></p>
<p>Retrieves the profession name using custom profession, noble assignments
or raws. The <tt class="docutils literal">ignore_noble</tt> boolean disables the use of noble positions.</p>
</li>
<li><p class="first"><tt class="docutils literal"><span class="pre">dfhack.units.getCasteProfessionName(race,caste,prof_id[,plural])</span></tt></p>
<p>Retrieves the profession name for the given race/caste using raws.</p>

@ -61,6 +61,10 @@ distribution.
#include "df/assumed_identity.h"
#include "df/nemesis_record.h"
#include "df/historical_figure.h"
#include "df/historical_entity.h"
#include "df/entity_position.h"
#include "df/entity_position_assignment.h"
#include "df/histfig_entity_link_positionst.h"
#include "df/plant_raw.h"
#include "df/creature_raw.h"
#include "df/inorganic_raw.h"
@ -628,8 +632,35 @@ static int units_getPosition(lua_State *state)
return Lua::PushPosXYZ(state, Units::getPosition(Lua::CheckDFObject<df::unit>(state,1)));
}
static int units_getNoblePositions(lua_State *state)
{
std::vector<Units::NoblePosition> np;
if (Units::getNoblePositions(&np, Lua::CheckDFObject<df::unit>(state,1)))
{
lua_createtable(state, np.size(), 0);
for (size_t i = 0; i < np.size(); i++)
{
lua_createtable(state, 0, 3);
Lua::PushDFObject(state, np[i].entity);
lua_setfield(state, -2, "entity");
Lua::PushDFObject(state, np[i].assignment);
lua_setfield(state, -2, "assignment");
Lua::PushDFObject(state, np[i].position);
lua_setfield(state, -2, "position");
lua_rawseti(state, -2, i+1);
}
}
else
lua_pushnil(state);
return 1;
}
static const luaL_Reg dfhack_units_funcs[] = {
{ "getPosition", units_getPosition },
{ "getNoblePositions", units_getNoblePositions },
{ NULL, NULL }
};

@ -38,6 +38,9 @@ namespace df
struct nemesis_record;
struct burrow;
struct assumed_identity;
struct historical_entity;
struct entity_position_assignment;
struct entity_position;
}
/**
@ -218,7 +221,15 @@ DFHACK_EXPORT void setInBurrow(df::unit *unit, df::burrow *burrow, bool enable);
DFHACK_EXPORT double getAge(df::unit *unit, bool true_age = false);
DFHACK_EXPORT std::string getProfessionName(df::unit *unit, bool plural = false);
struct NoblePosition {
df::historical_entity *entity;
df::entity_position_assignment *assignment;
df::entity_position *position;
};
DFHACK_EXPORT bool getNoblePositions(std::vector<NoblePosition> *pvec, df::unit *unit);
DFHACK_EXPORT std::string getProfessionName(df::unit *unit, bool ignore_noble = false, bool plural = false);
DFHACK_EXPORT std::string getCasteProfessionName(int race, int caste, df::profession pid, bool plural = false);
}
}

@ -55,6 +55,9 @@ using namespace std;
#include "df/historical_entity.h"
#include "df/historical_figure.h"
#include "df/historical_figure_info.h"
#include "df/entity_position.h"
#include "df/entity_position_assignment.h"
#include "df/histfig_entity_link_positionst.h"
#include "df/assumed_identity.h"
#include "df/burrow.h"
#include "df/creature_raw.h"
@ -762,14 +765,85 @@ double DFHack::Units::getAge(df::unit *unit, bool true_age)
return cur_time - birth_time;
}
std::string DFHack::Units::getProfessionName(df::unit *unit, bool plural)
static bool noble_pos_compare(const Units::NoblePosition &a, const Units::NoblePosition &b)
{
if (a.position->precedence < b.position->precedence)
return true;
if (a.position->precedence > b.position->precedence)
return false;
return a.position->id < b.position->id;
}
bool DFHack::Units::getNoblePositions(std::vector<NoblePosition> *pvec, df::unit *unit)
{
CHECK_NULL_POINTER(unit);
pvec->clear();
auto histfig = df::historical_figure::find(unit->hist_figure_id);
if (!histfig)
return false;
for (size_t i = 0; i < histfig->entity_links.size(); i++)
{
auto link = histfig->entity_links[i];
auto epos = strict_virtual_cast<df::histfig_entity_link_positionst>(link);
if (!epos)
continue;
NoblePosition pos;
pos.entity = df::historical_entity::find(epos->entity_id);
if (!pos.entity)
continue;
pos.assignment = binsearch_in_vector(pos.entity->positions.assignments, epos->assignment_id);
if (!pos.assignment)
continue;
pos.position = binsearch_in_vector(pos.entity->positions.own, pos.assignment->position_id);
if (!pos.position)
continue;
pvec->push_back(pos);
}
if (pvec->empty())
return false;
std::sort(pvec->begin(), pvec->end(), noble_pos_compare);
return true;
}
std::string DFHack::Units::getProfessionName(df::unit *unit, bool ignore_noble, bool plural)
{
std::string prof = unit->custom_profession;
if (!prof.empty())
return prof;
if (prof.empty())
prof = getCasteProfessionName(unit->race, unit->caste, unit->profession, plural);
std::vector<NoblePosition> np;
if (!ignore_noble && getNoblePositions(&np, unit))
{
switch (unit->sex)
{
case 0:
prof = np[0].position->name_female[plural ? 1 : 0];
break;
case 1:
prof = np[0].position->name_male[plural ? 1 : 0];
break;
default:
break;
}
if (prof.empty())
prof = np[0].position->name[plural ? 1 : 0];
if (!prof.empty())
return prof;
}
return getCasteProfessionName(unit->race, unit->caste, unit->profession, plural);
}
std::string DFHack::Units::getCasteProfessionName(int race, int casteid, df::profession pid, bool plural)

@ -52,6 +52,15 @@ local function findRaceCaste(unit)
return rraw, safe_index(rraw, 'caste', unit.caste)
end
orders.noble = {
key = function(unit)
local info = dfhack.units.getNoblePositions(unit)
if info then
return info[1].position.precedence
end
end
}
orders.profession = {
key = function(unit)
local cp = dfhack.units.getProfessionName(unit)