diff options
| author | Alexander Gavrilov | 2012-05-22 12:31:37 +0400 |
|---|---|---|
| committer | Alexander Gavrilov | 2012-05-22 12:31:37 +0400 |
| commit | 9adf310d7f162ba58da764bed2c918487c692f6b (patch) | |
| tree | d253f45cf76c8bae4f4926eb0f841eebf3dc5deb | |
| parent | 20794ebf191d21d5acce274d70bdad4012deaa44 (diff) | |
| download | dfhack-9adf310d7f162ba58da764bed2c918487c692f6b.tar.gz dfhack-9adf310d7f162ba58da764bed2c918487c692f6b.tar.bz2 dfhack-9adf310d7f162ba58da764bed2c918487c692f6b.tar.xz | |
Update Units::isCitizen after looking at game-over detection code.
| -rw-r--r-- | LUA_API.rst | 13 | ||||
| -rw-r--r-- | Lua API.html | 11 | ||||
| -rw-r--r-- | library/LuaApi.cpp | 2 | ||||
| -rw-r--r-- | library/modules/Units.cpp | 71 | ||||
| m--------- | library/xml | 0 |
5 files changed, 85 insertions, 12 deletions
diff --git a/LUA_API.rst b/LUA_API.rst index b0f1a9f3..9fb37375 100644 --- a/LUA_API.rst +++ b/LUA_API.rst @@ -726,7 +726,7 @@ Units module * ``dfhack.units.isDead(unit)`` - The unit is completely dead and passive. + The unit is completely dead and passive, or a ghost. * ``dfhack.units.isAlive(unit)`` @@ -734,7 +734,16 @@ Units module * ``dfhack.units.isSane(unit)`` - The unit is capable of rational action, i.e. not dead, insane or zombie. + The unit is capable of rational action, i.e. not dead, insane, zombie, or active werewolf. + +* ``dfhack.units.isDwarf(unit)`` + + The unit is of the correct race of the fortress. + +* ``dfhack.units.isCitizen(unit)`` + + The unit is an alive sane citizen of the fortress; wraps the + same checks the game uses to decide game-over by extinction. * ``dfhack.units.getAge(unit[,true_age])`` diff --git a/Lua API.html b/Lua API.html index 4b763af2..1576652d 100644 --- a/Lua API.html +++ b/Lua API.html @@ -960,13 +960,20 @@ a lua list containing them.</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> +<p>The unit is completely dead and passive, or a ghost.</p> </li> <li><p class="first"><tt class="docutils literal">dfhack.units.isAlive(unit)</tt></p> <p>The unit isn't dead or undead.</p> </li> <li><p class="first"><tt class="docutils literal">dfhack.units.isSane(unit)</tt></p> -<p>The unit is capable of rational action, i.e. not dead, insane or zombie.</p> +<p>The unit is capable of rational action, i.e. not dead, insane, zombie, or active werewolf.</p> +</li> +<li><p class="first"><tt class="docutils literal">dfhack.units.isDwarf(unit)</tt></p> +<p>The unit is of the correct race of the fortress.</p> +</li> +<li><p class="first"><tt class="docutils literal">dfhack.units.isCitizen(unit)</tt></p> +<p>The unit is an alive sane citizen of the fortress; wraps the +same checks the game uses to decide game-over by extinction.</p> </li> <li><p class="first"><tt class="docutils literal"><span class="pre">dfhack.units.getAge(unit[,true_age])</span></tt></p> <p>Returns the age of the unit in years as a floating-point value. diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index 6a550db8..8e8a3c4e 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -715,6 +715,8 @@ static const LuaWrapper::FunctionReg dfhack_units_module[] = { WRAPM(Units, isDead), WRAPM(Units, isAlive), WRAPM(Units, isSane), + WRAPM(Units, isDwarf), + WRAPM(Units, isCitizen), WRAPM(Units, getAge), WRAPM(Units, getProfessionName), WRAPM(Units, getCasteProfessionName), diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp index dd26109e..ee383cc0 100644 --- a/library/modules/Units.cpp +++ b/library/modules/Units.cpp @@ -613,12 +613,45 @@ df::nemesis_record *Units::getNemesis(df::unit *unit) return NULL; } +static bool casteFlagSet(int race, int caste, df::caste_raw_flags flag) +{ + auto creature = df::creature_raw::find(race); + if (!creature) + return false; + + auto craw = vector_get(creature->caste, caste); + if (!craw) + return false; + + return craw->flags.is_set(flag); +} + +static bool isCrazed(df::unit *unit) +{ + if (unit->flags3.bits.scuttle) + return false; + if (unit->curse.rem_tags1.bits.CRAZED) + return false; + if (unit->curse.add_tags1.bits.CRAZED) + return true; + return casteFlagSet(unit->race, unit->caste, caste_raw_flags::CRAZED); +} + +static bool isOpposedToLife(df::unit *unit) +{ + if (unit->curse.rem_tags1.bits.OPPOSED_TO_LIFE) + return false; + if (unit->curse.add_tags1.bits.OPPOSED_TO_LIFE) + return true; + return casteFlagSet(unit->race, unit->caste, caste_raw_flags::CANNOT_UNDEAD); +} bool DFHack::Units::isDead(df::unit *unit) { CHECK_NULL_POINTER(unit); - return unit->flags1.bits.dead; + return unit->flags1.bits.dead || + unit->flags3.bits.ghostly; } bool DFHack::Units::isAlive(df::unit *unit) @@ -636,8 +669,11 @@ bool DFHack::Units::isSane(df::unit *unit) if (unit->flags1.bits.dead || unit->flags3.bits.ghostly || - unit->curse.add_tags1.bits.OPPOSED_TO_LIFE || - unit->curse.add_tags1.bits.CRAZED) + isOpposedToLife(unit) || + unit->unknown8.unk2) + return false; + + if (unit->unknown8.normal_race == unit->unknown8.were_race && isCrazed(unit)) return false; switch (unit->mood) @@ -657,19 +693,38 @@ bool DFHack::Units::isCitizen(df::unit *unit) { CHECK_NULL_POINTER(unit); + // Copied from the conditions used to decide game over, + // except that the game appears to let melancholy/raving + // dwarves count as citizens. + + if (!isDwarf(unit) || !isSane(unit)) + return false; + + if (unit->flags1.bits.marauder || + unit->flags1.bits.invader_origin || + unit->flags1.bits.active_invader || + unit->flags1.bits.forest || + unit->flags1.bits.merchant || + unit->flags1.bits.diplomat) + return false; + + if (unit->flags1.bits.tame) + return true; + return unit->civ_id == ui->civ_id && - !unit->flags1.bits.merchant && - !unit->flags1.bits.diplomat && + unit->civ_id != -1 && + !unit->flags2.bits.underworld && !unit->flags2.bits.resident && - !unit->flags1.bits.dead && - !unit->flags3.bits.ghostly; + !unit->flags2.bits.visitor_uninvited && + !unit->flags2.bits.visitor; } bool DFHack::Units::isDwarf(df::unit *unit) { CHECK_NULL_POINTER(unit); - return unit->race == ui->race_id; + return unit->race == ui->race_id || + unit->unknown8.normal_race == ui->race_id; } double DFHack::Units::getAge(df::unit *unit, bool true_age) diff --git a/library/xml b/library/xml -Subproject 234d0f57a927f306f2052fc2f45d38b3201ddee +Subproject d991d47b0f6709205c4e333bb86edb3dcf65642 |
