Pull a few utility functions into the core and publish to lua.

develop
Alexander Gavrilov 2012-04-07 19:08:30 +04:00
parent e74788cb26
commit 45ae2ed67f
10 changed files with 117 additions and 85 deletions

@ -644,9 +644,17 @@ Job module
Units module
------------
* ``dfhack.units.setNickname(unit,nick)``
Sets the unit's nickname properly.
* ``dfhack.units.getVisibleName(unit)``
Returns the name visible in game, accounting for false identities.
Returns the language_name object visible in game, accounting for false identities.
* ``dfhack.units.getNemesis(unit)``
Returns the nemesis record of the unit if it has one, or *nil*.
* ``dfhack.units.isDead(unit)``

@ -883,8 +883,14 @@ The is_bright boolean actually seems to invert the brightness.</p>
<div class="section" id="units-module">
<h3><a class="toc-backref" href="#id16">Units module</a></h3>
<ul>
<li><p class="first"><tt class="docutils literal">dfhack.units.setNickname(unit,nick)</tt></p>
<p>Sets the unit's nickname properly.</p>
</li>
<li><p class="first"><tt class="docutils literal">dfhack.units.getVisibleName(unit)</tt></p>
<p>Returns the name visible in game, accounting for false identities.</p>
<p>Returns the language_name object visible in game, accounting for false identities.</p>
</li>
<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.isDead(unit)</tt></p>
<p>The unit is completely dead and passive.</p>

@ -55,6 +55,7 @@ distribution.
#include "df/unit.h"
#include "df/item.h"
#include "df/material.h"
#include "df/nemesis_record.h"
#include "df/historical_figure.h"
#include "df/plant_raw.h"
#include "df/creature_raw.h"
@ -555,7 +556,9 @@ static const LuaWrapper::FunctionReg dfhack_job_module[] = {
};
static const LuaWrapper::FunctionReg dfhack_units_module[] = {
WRAPM(Units, setNickname),
WRAPM(Units, getVisibleName),
WRAPM(Units, getNemesis),
WRAPM(Units, isDead),
WRAPM(Units, isAlive),
WRAPM(Units, isSane),

@ -50,6 +50,8 @@ DFHACK_EXPORT bool IsValid ();
DFHACK_EXPORT bool readName(t_name & name, df::language_name * address);
DFHACK_EXPORT bool copyName(df::language_name * address, df::language_name * target);
DFHACK_EXPORT void setNickname(df::language_name *name, std::string nick);
// translate a name using the loaded dictionaries
DFHACK_EXPORT std::string TranslateName (const df::language_name * name, bool inEnglish = true,
bool onlyLastPart = false);

@ -33,6 +33,11 @@ distribution.
#include "DataDefs.h"
#include "df/unit.h"
namespace df
{
struct nemesis_record;
}
/**
* \defgroup grp_units Unit module parts
* @ingroup grp_modules
@ -193,8 +198,11 @@ DFHACK_EXPORT void CopyNameTo(df::unit *creature, df::language_name * target);
DFHACK_EXPORT bool RemoveOwnedItemByIdx(const uint32_t index, int32_t id);
DFHACK_EXPORT bool RemoveOwnedItemByPtr(df::unit * unit, int32_t id);
DFHACK_EXPORT void setNickname(df::unit *unit, std::string nick);
DFHACK_EXPORT df::language_name *getVisibleName(df::unit *unit);
DFHACK_EXPORT df::nemesis_record *getNemesis(df::unit *unit);
DFHACK_EXPORT bool isDead(df::unit *unit);
DFHACK_EXPORT bool isAlive(df::unit *unit);
DFHACK_EXPORT bool isSane(df::unit *unit);

@ -46,6 +46,7 @@ using namespace DFHack;
#include "df/global_objects.h"
#include "df/viewscreen_dwarfmodest.h"
#include "df/viewscreen_dungeonmodest.h"
#include "df/viewscreen_dungeon_monsterstatusst.h"
#include "df/viewscreen_joblistst.h"
#include "df/viewscreen_unitlistst.h"
#include "df/viewscreen_itemst.h"
@ -284,6 +285,9 @@ static df::unit *getAnyUnit(df::viewscreen *top)
if (VIRTUAL_CAST_VAR(screen, df::viewscreen_unitlistst, top))
return vector_get(screen->units[screen->page], screen->cursor_pos[screen->page]);
if (VIRTUAL_CAST_VAR(screen, df::viewscreen_dungeon_monsterstatusst, top))
return screen->unit;
if (VIRTUAL_CAST_VAR(screen, df::viewscreen_itemst, top))
{
df::general_ref *ref = vector_get(screen->entry_ref, screen->cursor_pos);

@ -92,6 +92,21 @@ void addNameWord (string &out, const string &word)
out.append(upper);
}
void Translation::setNickname(df::language_name *name, std::string nick)
{
CHECK_NULL_POINTER(name);
if (!name->has_name)
{
*name = df::language_name();
name->language = 0;
name->has_name = true;
}
name->nickname = nick;
}
string Translation::TranslateName(const df::language_name * name, bool inEnglish, bool onlyLastPart)
{
CHECK_NULL_POINTER(name);

@ -48,6 +48,8 @@ using namespace std;
#include "df/world.h"
#include "df/ui.h"
#include "df/unit_inventory_item.h"
#include "df/unit_soul.h"
#include "df/nemesis_record.h"
#include "df/historical_entity.h"
#include "df/historical_figure.h"
#include "df/historical_figure_info.h"
@ -527,6 +529,47 @@ void Units::CopyNameTo(df::unit * creature, df::language_name * target)
Translation::copyName(&creature->name, target);
}
void Units::setNickname(df::unit *unit, std::string nick)
{
CHECK_NULL_POINTER(unit);
// There are >=3 copies of the name, and the one
// in the unit is not the authoritative one.
// This is the reason why military units often
// lose nicknames set from Dwarf Therapist.
Translation::setNickname(&unit->name, nick);
if (unit->status.current_soul)
Translation::setNickname(&unit->status.current_soul->name, nick);
df::historical_figure *figure = df::historical_figure::find(unit->hist_figure_id);
if (figure)
{
Translation::setNickname(&figure->name, nick);
// v0.34.01: added the vampire's assumed identity
if (figure->info && figure->info->reputation)
{
auto identity = df::assumed_identity::find(figure->info->reputation->cur_identity);
if (identity)
{
auto id_hfig = df::historical_figure::find(identity->histfig_id);
if (id_hfig)
{
// Even DF doesn't do this bit, because it's apparently
// only used for demons masquerading as gods, so you
// can't ever change their nickname in-game.
Translation::setNickname(&id_hfig->name, nick);
}
else
Translation::setNickname(&identity->name, nick);
}
}
}
}
df::language_name *Units::getVisibleName(df::unit *unit)
{
CHECK_NULL_POINTER(unit);
@ -555,6 +598,22 @@ df::language_name *Units::getVisibleName(df::unit *unit)
return &unit->name;
}
df::nemesis_record *Units::getNemesis(df::unit *unit)
{
if (!unit)
return NULL;
for (unsigned i = 0; i < unit->refs.size(); i++)
{
df::nemesis_record *rv = unit->refs[i]->getNemesis();
if (rv && rv->unit == unit)
return rv;
}
return NULL;
}
bool DFHack::Units::isDead(df::unit *unit)
{
CHECK_NULL_POINTER(unit);

@ -8,6 +8,8 @@
#include "modules/Materials.h"
#include "modules/Maps.h"
#include "modules/Items.h"
#include "modules/Gui.h"
#include "modules/Units.h"
#include "DataDefs.h"
#include "df/world.h"
@ -159,31 +161,6 @@ static bool bodyswap_hotkey(df::viewscreen *top)
!!virtual_cast<df::viewscreen_dungeon_monsterstatusst>(top);
}
df::unit *getCurUnit()
{
auto top = Core::getTopViewscreen();
if (VIRTUAL_CAST_VAR(ms, df::viewscreen_dungeon_monsterstatusst, top))
return ms->unit;
return NULL;
}
df::nemesis_record *getNemesis(df::unit *unit)
{
if (!unit)
return NULL;
for (unsigned i = 0; i < unit->refs.size(); i++)
{
df::nemesis_record *rv = unit->refs[i]->getNemesis();
if (rv && rv->unit == unit)
return rv;
}
return NULL;
}
bool bodySwap(color_ostream &out, df::unit *player)
{
if (!player)
@ -219,7 +196,7 @@ df::nemesis_record *getPlayerNemesis(color_ostream &out, bool restore_swap)
if (restore_swap)
{
df::unit *ctl = world->units.other[0][0];
auto ctl_nemesis = getNemesis(ctl);
auto ctl_nemesis = Units::getNemesis(ctl);
if (ctl_nemesis != real_nemesis)
{
@ -672,8 +649,8 @@ command_result adv_bodyswap (color_ostream &out, std::vector <std::string> & par
return CR_FAILURE;
// Get the unit to swap to
auto new_unit = getCurUnit();
auto new_nemesis = getNemesis(new_unit);
auto new_unit = Gui::getSelectedUnit(out, true);
auto new_nemesis = Units::getNemesis(new_unit);
if (!new_nemesis)
{

@ -4,6 +4,8 @@
#include "PluginManager.h"
#include "modules/Gui.h"
#include "modules/Translation.h"
#include "modules/Units.h"
#include "DataDefs.h"
#include "df/ui.h"
@ -59,19 +61,6 @@ DFhackCExport command_result plugin_shutdown ( color_ostream &out )
return CR_OK;
}
static void set_nickname(df::language_name *name, std::string nick)
{
if (!name->has_name)
{
*name = df::language_name();
name->language = 0;
name->has_name = true;
}
name->nickname = nick;
}
static df::squad *getSquadByIndex(unsigned idx)
{
auto entity = df::historical_entity::find(ui->group_id);
@ -84,45 +73,6 @@ static df::squad *getSquadByIndex(unsigned idx)
return df::squad::find(entity->squads[idx]);
}
void setUnitNickname(df::unit *unit, const std::string &nick)
{
// There are >=3 copies of the name, and the one
// in the unit is not the authoritative one.
// This is the reason why military units often
// lose nicknames set from Dwarf Therapist.
set_nickname(&unit->name, nick);
if (unit->status.current_soul)
set_nickname(&unit->status.current_soul->name, nick);
df::historical_figure *figure = df::historical_figure::find(unit->hist_figure_id);
if (figure)
{
set_nickname(&figure->name, nick);
// v0.34.01: added the vampire's assumed identity
if (figure->info && figure->info->reputation)
{
auto identity = df::assumed_identity::find(figure->info->reputation->cur_identity);
if (identity)
{
auto id_hfig = df::historical_figure::find(identity->histfig_id);
if (id_hfig)
{
// Even DF doesn't do this bit, because it's apparently
// only used for demons masquerading as gods, so you
// can't ever change their nickname in-game.
set_nickname(&id_hfig->name, nick);
}
else
set_nickname(&identity->name, nick);
}
}
}
}
static command_result RenameSquad(color_ostream &stream, const RenameSquadIn *in)
{
df::squad *squad = df::squad::find(in->squad_id());
@ -130,7 +80,7 @@ static command_result RenameSquad(color_ostream &stream, const RenameSquadIn *in
return CR_NOT_FOUND;
if (in->has_nickname())
set_nickname(&squad->name, UTF2DF(in->nickname()));
Translation::setNickname(&squad->name, UTF2DF(in->nickname()));
if (in->has_alias())
squad->alias = UTF2DF(in->alias());
@ -144,7 +94,7 @@ static command_result RenameUnit(color_ostream &stream, const RenameUnitIn *in)
return CR_NOT_FOUND;
if (in->has_nickname())
setUnitNickname(unit, UTF2DF(in->nickname()));
Units::setNickname(unit, UTF2DF(in->nickname()));
if (in->has_profession())
unit->custom_profession = UTF2DF(in->profession());
@ -204,7 +154,7 @@ static command_result rename(color_ostream &out, vector <string> &parameters)
if (!unit)
return CR_WRONG_USAGE;
setUnitNickname(unit, parameters[1]);
Units::setNickname(unit, parameters[1]);
}
else if (cmd == "unit-profession")
{