diff options
Diffstat (limited to 'library/modules/Units.cpp')
| -rw-r--r-- | library/modules/Units.cpp | 71 |
1 files changed, 63 insertions, 8 deletions
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) |
