|
|
@ -72,6 +72,7 @@ using namespace std;
|
|
|
|
#include "df/unit_misc_trait.h"
|
|
|
|
#include "df/unit_misc_trait.h"
|
|
|
|
#include "df/unit_skill.h"
|
|
|
|
#include "df/unit_skill.h"
|
|
|
|
#include "df/unit_soul.h"
|
|
|
|
#include "df/unit_soul.h"
|
|
|
|
|
|
|
|
#include "df/unit_wound.h"
|
|
|
|
#include "df/world.h"
|
|
|
|
#include "df/world.h"
|
|
|
|
|
|
|
|
|
|
|
|
using namespace DFHack;
|
|
|
|
using namespace DFHack;
|
|
|
@ -1846,3 +1847,120 @@ bool Units::isMarkedForSlaughter(df::unit* unit)
|
|
|
|
CHECK_NULL_POINTER(unit);
|
|
|
|
CHECK_NULL_POINTER(unit);
|
|
|
|
return unit->flags2.bits.slaughter == 1;
|
|
|
|
return unit->flags2.bits.slaughter == 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool Units::isTame(df::unit* unit)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
CHECK_NULL_POINTER(unit);
|
|
|
|
|
|
|
|
bool tame = false;
|
|
|
|
|
|
|
|
if(unit->flags1.bits.tame)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
switch (unit->training_level)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
case df::animal_training_level::SemiWild: //??
|
|
|
|
|
|
|
|
case df::animal_training_level::Trained:
|
|
|
|
|
|
|
|
case df::animal_training_level::WellTrained:
|
|
|
|
|
|
|
|
case df::animal_training_level::SkilfullyTrained:
|
|
|
|
|
|
|
|
case df::animal_training_level::ExpertlyTrained:
|
|
|
|
|
|
|
|
case df::animal_training_level::ExceptionallyTrained:
|
|
|
|
|
|
|
|
case df::animal_training_level::MasterfullyTrained:
|
|
|
|
|
|
|
|
case df::animal_training_level::Domesticated:
|
|
|
|
|
|
|
|
tame=true;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case df::animal_training_level::Unk8: //??
|
|
|
|
|
|
|
|
case df::animal_training_level::WildUntamed:
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
|
|
tame=false;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return tame;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool Units::isTrained(df::unit* unit)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
CHECK_NULL_POINTER(unit);
|
|
|
|
|
|
|
|
// case a: trained for war/hunting (those don't have a training level, strangely)
|
|
|
|
|
|
|
|
if(Units::isWar(unit) || Units::isHunter(unit))
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// case b: tamed and trained wild creature, gets a training level
|
|
|
|
|
|
|
|
bool trained = false;
|
|
|
|
|
|
|
|
switch (unit->training_level)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
case df::animal_training_level::Trained:
|
|
|
|
|
|
|
|
case df::animal_training_level::WellTrained:
|
|
|
|
|
|
|
|
case df::animal_training_level::SkilfullyTrained:
|
|
|
|
|
|
|
|
case df::animal_training_level::ExpertlyTrained:
|
|
|
|
|
|
|
|
case df::animal_training_level::ExceptionallyTrained:
|
|
|
|
|
|
|
|
case df::animal_training_level::MasterfullyTrained:
|
|
|
|
|
|
|
|
//case df::animal_training_level::Domesticated:
|
|
|
|
|
|
|
|
trained = true;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return trained;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool Units::isGay(df::unit* unit)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
CHECK_NULL_POINTER(unit);
|
|
|
|
|
|
|
|
if (!unit->status.current_soul)
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
df::orientation_flags orientation = unit->status.current_soul->orientation_flags;
|
|
|
|
|
|
|
|
return (Units::isFemale(unit) && ! (orientation.whole & (orientation.mask_marry_male | orientation.mask_romance_male)))
|
|
|
|
|
|
|
|
|| (!Units::isFemale(unit) && ! (orientation.whole & (orientation.mask_marry_female | orientation.mask_romance_female)));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool Units::isNaked(df::unit* unit)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
CHECK_NULL_POINTER(unit);
|
|
|
|
|
|
|
|
// TODO(kazimuth): is this correct?
|
|
|
|
|
|
|
|
return (unit->inventory.empty());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool Units::isUndead(df::unit* unit)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
CHECK_NULL_POINTER(unit);
|
|
|
|
|
|
|
|
// ignore vampires, they should be treated like normal dwarves
|
|
|
|
|
|
|
|
return (unit->flags3.bits.ghostly ||
|
|
|
|
|
|
|
|
( (unit->curse.add_tags1.bits.OPPOSED_TO_LIFE || unit->curse.add_tags1.bits.NOT_LIVING)
|
|
|
|
|
|
|
|
&& !unit->curse.add_tags1.bits.BLOODSUCKER ));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool Units::isGelded(df::unit* unit)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
CHECK_NULL_POINTER(unit);
|
|
|
|
|
|
|
|
auto wounds = unit->body.wounds;
|
|
|
|
|
|
|
|
for(auto wound = wounds.begin(); wound != wounds.end(); ++wound)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
auto parts = (*wound)->parts;
|
|
|
|
|
|
|
|
for (auto part = parts.begin(); part != parts.end(); ++part)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if ((*part)->flags2.bits.gelded)
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// check if creature is domesticated
|
|
|
|
|
|
|
|
// seems to be the only way to really tell if it's completely safe to autonestbox it (training can revert)
|
|
|
|
|
|
|
|
bool Units::isDomesticated(df::unit* unit)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
CHECK_NULL_POINTER(unit);
|
|
|
|
|
|
|
|
bool tame = false;
|
|
|
|
|
|
|
|
if(unit->flags1.bits.tame)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
switch (unit->training_level)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
case df::animal_training_level::Domesticated:
|
|
|
|
|
|
|
|
tame=true;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
|
|
tame=false;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return tame;
|
|
|
|
|
|
|
|
}
|
|
|
|