|
|
@ -75,6 +75,8 @@ using namespace std;
|
|
|
|
using std::vector;
|
|
|
|
using std::vector;
|
|
|
|
using std::string;
|
|
|
|
using std::string;
|
|
|
|
using namespace DFHack;
|
|
|
|
using namespace DFHack;
|
|
|
|
|
|
|
|
using namespace DFHack::Units;
|
|
|
|
|
|
|
|
using namespace DFHack::Buildings;
|
|
|
|
using namespace df::enums;
|
|
|
|
using namespace df::enums;
|
|
|
|
|
|
|
|
|
|
|
|
DFHACK_PLUGIN("zone");
|
|
|
|
DFHACK_PLUGIN("zone");
|
|
|
@ -339,26 +341,12 @@ DFhackCExport command_result plugin_onupdate ( color_ostream &out )
|
|
|
|
// Various small tool functions
|
|
|
|
// Various small tool functions
|
|
|
|
// probably many of these should be moved to Unit.h and Building.h sometime later...
|
|
|
|
// probably many of these should be moved to Unit.h and Building.h sometime later...
|
|
|
|
|
|
|
|
|
|
|
|
int32_t getUnitAge(df::unit* unit);
|
|
|
|
|
|
|
|
bool isTame(df::unit* unit);
|
|
|
|
bool isTame(df::unit* unit);
|
|
|
|
bool isTrained(df::unit* unit);
|
|
|
|
bool isTrained(df::unit* unit);
|
|
|
|
bool isWar(df::unit* unit);
|
|
|
|
|
|
|
|
bool isHunter(df::unit* unit);
|
|
|
|
|
|
|
|
bool isOwnCiv(df::unit* unit);
|
|
|
|
|
|
|
|
bool isMerchant(df::unit* unit);
|
|
|
|
|
|
|
|
bool isForest(df::unit* unit);
|
|
|
|
|
|
|
|
bool isGay(df::unit* unit);
|
|
|
|
bool isGay(df::unit* unit);
|
|
|
|
bool isGelded(df::unit* unit);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool isActivityZone(df::building * building);
|
|
|
|
df::building* findCageAtCursor();
|
|
|
|
bool isPenPasture(df::building * building);
|
|
|
|
df::building* findChainAtCursor();
|
|
|
|
bool isPitPond(df::building * building);
|
|
|
|
|
|
|
|
bool isActive(df::building * building);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int32_t findBuildingIndexById(int32_t id);
|
|
|
|
|
|
|
|
int32_t findPenPitAtCursor();
|
|
|
|
|
|
|
|
int32_t findCageAtCursor();
|
|
|
|
|
|
|
|
int32_t findChainAtCursor();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
df::general_ref_building_civzone_assignedst * createCivzoneRef();
|
|
|
|
df::general_ref_building_civzone_assignedst * createCivzoneRef();
|
|
|
|
bool unassignUnitFromBuilding(df::unit* unit);
|
|
|
|
bool unassignUnitFromBuilding(df::unit* unit);
|
|
|
@ -370,22 +358,6 @@ void chainInfo(color_ostream & out, df::building* building, bool verbose);
|
|
|
|
bool isBuiltCageAtPos(df::coord pos);
|
|
|
|
bool isBuiltCageAtPos(df::coord pos);
|
|
|
|
bool isInBuiltCageRoom(df::unit*);
|
|
|
|
bool isInBuiltCageRoom(df::unit*);
|
|
|
|
bool isNaked(df::unit *);
|
|
|
|
bool isNaked(df::unit *);
|
|
|
|
bool isTamable(df::unit *);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int32_t getUnitAge(df::unit* unit)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// If the birthday this year has not yet passed, subtract one year.
|
|
|
|
|
|
|
|
// ASSUMPTION: birth_time is on the same scale as cur_year_tick
|
|
|
|
|
|
|
|
int32_t yearDifference = *cur_year - unit->relations.birth_year;
|
|
|
|
|
|
|
|
if (unit->relations.birth_time >= *cur_year_tick)
|
|
|
|
|
|
|
|
yearDifference--;
|
|
|
|
|
|
|
|
return yearDifference;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool isDead(df::unit* unit)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return unit->flags1.bits.dead;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ignore vampires, they should be treated like normal dwarves
|
|
|
|
// ignore vampires, they should be treated like normal dwarves
|
|
|
|
bool isUndead(df::unit* unit)
|
|
|
|
bool isUndead(df::unit* unit)
|
|
|
@ -395,21 +367,6 @@ bool isUndead(df::unit* unit)
|
|
|
|
&& !unit->curse.add_tags1.bits.BLOODSUCKER ));
|
|
|
|
&& !unit->curse.add_tags1.bits.BLOODSUCKER ));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool isMerchant(df::unit* unit)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return unit->flags1.bits.merchant;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool isForest(df::unit* unit)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return unit->flags1.bits.forest;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool isMarkedForSlaughter(df::unit* unit)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return unit->flags2.bits.slaughter;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void doMarkForSlaughter(df::unit* unit)
|
|
|
|
void doMarkForSlaughter(df::unit* unit)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
unit->flags2.bits.slaughter = 1;
|
|
|
|
unit->flags2.bits.slaughter = 1;
|
|
|
@ -489,195 +446,6 @@ bool isTrained(df::unit* unit)
|
|
|
|
return trained;
|
|
|
|
return trained;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// check for profession "war creature"
|
|
|
|
|
|
|
|
bool isWar(df::unit* unit)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if( unit->profession == df::profession::TRAINED_WAR
|
|
|
|
|
|
|
|
|| unit->profession2 == df::profession::TRAINED_WAR)
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// check for profession "hunting creature"
|
|
|
|
|
|
|
|
bool isHunter(df::unit* unit)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if( unit->profession == df::profession::TRAINED_HUNTER
|
|
|
|
|
|
|
|
|| unit->profession2 == df::profession::TRAINED_HUNTER)
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// check if unit is marked as available for adoption
|
|
|
|
|
|
|
|
bool isAvailableForAdoption(df::unit* unit)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
auto refs = unit->specific_refs;
|
|
|
|
|
|
|
|
for(int i=0; i<refs.size(); i++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
auto ref = refs[i];
|
|
|
|
|
|
|
|
auto reftype = ref->type;
|
|
|
|
|
|
|
|
if( reftype == df::specific_ref_type::PETINFO_PET )
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
//df::pet_info* pet = ref->pet;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// check if creature belongs to the player's civilization
|
|
|
|
|
|
|
|
// (don't try to pasture/slaughter random untame animals)
|
|
|
|
|
|
|
|
bool isOwnCiv(df::unit* unit)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return unit->civ_id == ui->civ_id;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// check if creature belongs to the player's race
|
|
|
|
|
|
|
|
// (in combination with check for civ helps to filter out own dwarves)
|
|
|
|
|
|
|
|
bool isOwnRace(df::unit* unit)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return unit->race == ui->race_id;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// get race name by id or unit pointer
|
|
|
|
|
|
|
|
// todo: rename these two functions to "getRaceToken" since the output is more of a token
|
|
|
|
|
|
|
|
string getRaceName(int32_t id)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
df::creature_raw *raw = world->raws.creatures.all[id];
|
|
|
|
|
|
|
|
return raw->creature_id;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
string getRaceName(df::unit* unit)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
df::creature_raw *raw = world->raws.creatures.all[unit->race];
|
|
|
|
|
|
|
|
return raw->creature_id;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// get plural of race name (used for display in autobutcher UI and for sorting the watchlist)
|
|
|
|
|
|
|
|
string getRaceNamePlural(int32_t id)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
//WatchedRace * w = watched_races[idx];
|
|
|
|
|
|
|
|
df::creature_raw *raw = world->raws.creatures.all[id];
|
|
|
|
|
|
|
|
return raw->name[1]; // second field is plural of race name
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
string getRaceBabyName(df::unit* unit)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
df::creature_raw *raw = world->raws.creatures.all[unit->race];
|
|
|
|
|
|
|
|
return raw->general_baby_name[0];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
string getRaceChildName(df::unit* unit)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
df::creature_raw *raw = world->raws.creatures.all[unit->race];
|
|
|
|
|
|
|
|
return raw->general_child_name[0];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool isBaby(df::unit* unit)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return unit->profession == df::profession::BABY;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool isChild(df::unit* unit)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return unit->profession == df::profession::CHILD;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool isAdult(df::unit* unit)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return !isBaby(unit) && !isChild(unit);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool isEggLayer(df::unit* unit)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
df::creature_raw *raw = world->raws.creatures.all[unit->race];
|
|
|
|
|
|
|
|
size_t sizecas = raw->caste.size();
|
|
|
|
|
|
|
|
for (size_t j = 0; j < sizecas;j++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
df::caste_raw *caste = raw->caste[j];
|
|
|
|
|
|
|
|
if( caste->flags.is_set(caste_raw_flags::LAYS_EGGS)
|
|
|
|
|
|
|
|
|| caste->flags.is_set(caste_raw_flags::LAYS_UNUSUAL_EGGS))
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool isGrazer(df::unit* unit)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
df::creature_raw *raw = world->raws.creatures.all[unit->race];
|
|
|
|
|
|
|
|
size_t sizecas = raw->caste.size();
|
|
|
|
|
|
|
|
for (size_t j = 0; j < sizecas;j++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
df::caste_raw *caste = raw->caste[j];
|
|
|
|
|
|
|
|
if(caste->flags.is_set(caste_raw_flags::GRAZER))
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool isMilkable(df::unit* unit)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
df::creature_raw *raw = world->raws.creatures.all[unit->race];
|
|
|
|
|
|
|
|
size_t sizecas = raw->caste.size();
|
|
|
|
|
|
|
|
for (size_t j = 0; j < sizecas;j++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
df::caste_raw *caste = raw->caste[j];
|
|
|
|
|
|
|
|
if(caste->flags.is_set(caste_raw_flags::MILKABLE))
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool isTrainableWar(df::unit* unit)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
df::creature_raw *raw = world->raws.creatures.all[unit->race];
|
|
|
|
|
|
|
|
size_t sizecas = raw->caste.size();
|
|
|
|
|
|
|
|
for (size_t j = 0; j < sizecas;j++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
df::caste_raw *caste = raw->caste[j];
|
|
|
|
|
|
|
|
if(caste->flags.is_set(caste_raw_flags::TRAINABLE_WAR))
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool isTrainableHunting(df::unit* unit)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
df::creature_raw *raw = world->raws.creatures.all[unit->race];
|
|
|
|
|
|
|
|
size_t sizecas = raw->caste.size();
|
|
|
|
|
|
|
|
for (size_t j = 0; j < sizecas;j++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
df::caste_raw *caste = raw->caste[j];
|
|
|
|
|
|
|
|
if(caste->flags.is_set(caste_raw_flags::TRAINABLE_HUNTING))
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool isTamable(df::unit* unit)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
df::creature_raw *raw = world->raws.creatures.all[unit->race];
|
|
|
|
|
|
|
|
size_t sizecas = raw->caste.size();
|
|
|
|
|
|
|
|
for (size_t j = 0; j < sizecas;j++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
df::caste_raw *caste = raw->caste[j];
|
|
|
|
|
|
|
|
if(caste->flags.is_set(caste_raw_flags::PET) ||
|
|
|
|
|
|
|
|
caste->flags.is_set(caste_raw_flags::PET_EXOTIC))
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool isMale(df::unit* unit)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return unit->sex == 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool isFemale(df::unit* unit)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return unit->sex == 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// found a unit with weird position values on one of my maps (negative and in the thousands)
|
|
|
|
// found a unit with weird position values on one of my maps (negative and in the thousands)
|
|
|
|
// it didn't appear in the animal stocks screen, but looked completely fine otherwise (alive, tame, own, etc)
|
|
|
|
// it didn't appear in the animal stocks screen, but looked completely fine otherwise (alive, tame, own, etc)
|
|
|
|
// maybe a rare bug, but better avoid assigning such units to zones or slaughter etc.
|
|
|
|
// maybe a rare bug, but better avoid assigning such units to zones or slaughter etc.
|
|
|
@ -697,23 +465,11 @@ bool isNaked(df::unit* unit)
|
|
|
|
return (unit->inventory.empty());
|
|
|
|
return (unit->inventory.empty());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int getUnitIndexFromId(df::unit* unit_)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
for (size_t i=0; i < world->units.all.size(); i++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
df::unit* unit = world->units.all[i];
|
|
|
|
|
|
|
|
if(unit->id == unit_->id)
|
|
|
|
|
|
|
|
return i;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool isGay(df::unit* unit)
|
|
|
|
bool isGay(df::unit* unit)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
df::orientation_flags orientation = unit->status.current_soul->orientation_flags;
|
|
|
|
df::orientation_flags orientation = unit->status.current_soul->orientation_flags;
|
|
|
|
return isFemale(unit) && ! (orientation.whole & (orientation.mask_marry_male | orientation.mask_romance_male))
|
|
|
|
return (isFemale(unit) && ! (orientation.whole & (orientation.mask_marry_male | orientation.mask_romance_male)))
|
|
|
|
|| ! isFemale(unit) && ! (orientation.whole & (orientation.mask_marry_female | orientation.mask_romance_female));
|
|
|
|
|| (! isFemale(unit) && ! (orientation.whole & (orientation.mask_marry_female | orientation.mask_romance_female)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool isGelded(df::unit* unit)
|
|
|
|
bool isGelded(df::unit* unit)
|
|
|
@ -776,7 +532,7 @@ void unitInfo(color_ostream & out, df::unit* unit, bool verbose = false)
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
out << ")";
|
|
|
|
out << ")";
|
|
|
|
out << ", age: " << getUnitAge(unit);
|
|
|
|
out << ", age: " << getAge(unit, true);
|
|
|
|
|
|
|
|
|
|
|
|
if(isTame(unit))
|
|
|
|
if(isTame(unit))
|
|
|
|
out << ", tame";
|
|
|
|
out << ", tame";
|
|
|
@ -800,7 +556,7 @@ void unitInfo(color_ostream & out, df::unit* unit, bool verbose = false)
|
|
|
|
if(verbose)
|
|
|
|
if(verbose)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
out << ". Pos: ("<<unit->pos.x << "/"<< unit->pos.y << "/" << unit->pos.z << ") " << endl;
|
|
|
|
out << ". Pos: ("<<unit->pos.x << "/"<< unit->pos.y << "/" << unit->pos.z << ") " << endl;
|
|
|
|
out << "index in units vector: " << getUnitIndexFromId(unit) << endl;
|
|
|
|
out << "index in units vector: " << FindIndexById(unit->id) << endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
out << endl;
|
|
|
|
out << endl;
|
|
|
|
|
|
|
|
|
|
|
@ -843,41 +599,6 @@ void unitInfo(color_ostream & out, df::unit* unit, bool verbose = false)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool isActivityZone(df::building * building)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if( building->getType() == building_type::Civzone
|
|
|
|
|
|
|
|
&& building->getSubtype() == (short)civzone_type::ActivityZone)
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool isPenPasture(df::building * building)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if(!isActivityZone(building))
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
df::building_civzonest * civ = (df::building_civzonest *) building;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(civ->zone_flags.bits.pen_pasture)
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool isPitPond(df::building * building)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if(!isActivityZone(building))
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
df::building_civzonest * civ = (df::building_civzonest *) building;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(civ->zone_flags.bits.pit_pond) // && civ->pit_flags==0)
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool isCage(df::building * building)
|
|
|
|
bool isCage(df::building * building)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return building->getType() == building_type::Cage;
|
|
|
|
return building->getType() == building_type::Cage;
|
|
|
@ -888,128 +609,21 @@ bool isChain(df::building * building)
|
|
|
|
return building->getType() == building_type::Chain;
|
|
|
|
return building->getType() == building_type::Chain;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool isActive(df::building * building)
|
|
|
|
// returns building of cage at cursor position (NULL if nothing found)
|
|
|
|
{
|
|
|
|
df::building* findCageAtCursor()
|
|
|
|
if(!isActivityZone(building))
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
df::building_civzonest * civ = (df::building_civzonest *) building;
|
|
|
|
|
|
|
|
if(civ->zone_flags.bits.active)
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int32_t findBuildingIndexById(int32_t id)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
for (size_t b = 0; b < world->buildings.all.size(); b++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if(world->buildings.all.at(b)->id == id)
|
|
|
|
|
|
|
|
return b;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int32_t findUnitIndexById(int32_t id)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
for (size_t i = 0; i < world->units.all.size(); i++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if(world->units.all.at(i)->id == id)
|
|
|
|
|
|
|
|
return i;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
df::unit* findUnitById(int32_t id)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
int32_t index = findUnitIndexById(id);
|
|
|
|
|
|
|
|
if(index != -1)
|
|
|
|
|
|
|
|
return world->units.all[index];
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// returns id of pen/pit at cursor position (-1 if nothing found)
|
|
|
|
|
|
|
|
int32_t findPenPitAtCursor()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
int32_t foundID = -1;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(cursor->x == -30000)
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (size_t b = 0; b < world->buildings.all.size(); b++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
df::building* building = world->buildings.all[b];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// find zone under cursor
|
|
|
|
|
|
|
|
if (!(building->x1 <= cursor->x && cursor->x <= building->x2 &&
|
|
|
|
|
|
|
|
building->y1 <= cursor->y && cursor->y <= building->y2 &&
|
|
|
|
|
|
|
|
building->z == cursor->z))
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(isPenPasture(building) || isPitPond(building))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
foundID = building->id;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return foundID;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// returns id of cage at cursor position (-1 if nothing found)
|
|
|
|
|
|
|
|
int32_t findCageAtCursor()
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
int32_t foundID = -1;
|
|
|
|
df::building* building = Buildings::findAtTile(Gui::getCursorPos());
|
|
|
|
|
|
|
|
|
|
|
|
if(cursor->x == -30000)
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (size_t b = 0; b < world->buildings.all.size(); b++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
df::building* building = world->buildings.all[b];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!(building->x1 <= cursor->x && cursor->x <= building->x2 &&
|
|
|
|
|
|
|
|
building->y1 <= cursor->y && cursor->y <= building->y2 &&
|
|
|
|
|
|
|
|
building->z == cursor->z))
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// don't set id if cage is not constructed yet
|
|
|
|
|
|
|
|
if(building->getBuildStage()!=building->getMaxBuildStage())
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (isCage(building))
|
|
|
|
if (isCage(building))
|
|
|
|
{
|
|
|
|
return building;
|
|
|
|
foundID = building->id;
|
|
|
|
return NULL;
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return foundID;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int32_t findChainAtCursor()
|
|
|
|
df::building* findChainAtCursor()
|
|
|
|
{
|
|
|
|
|
|
|
|
int32_t foundID = -1;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(cursor->x == -30000)
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (size_t b = 0; b < world->buildings.all.size(); b++)
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
df::building* building = world->buildings.all[b];
|
|
|
|
df::building* building = Buildings::findAtTile(Gui::getCursorPos());
|
|
|
|
|
|
|
|
|
|
|
|
// find zone under cursor
|
|
|
|
|
|
|
|
if (!(building->x1 <= cursor->x && cursor->x <= building->x2 &&
|
|
|
|
|
|
|
|
building->y1 <= cursor->y && cursor->y <= building->y2 &&
|
|
|
|
|
|
|
|
building->z == cursor->z))
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (isChain(building))
|
|
|
|
if (isChain(building))
|
|
|
|
{
|
|
|
|
return building;
|
|
|
|
foundID = building->id;
|
|
|
|
return NULL;
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return foundID;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
df::general_ref_building_civzone_assignedst * createCivzoneRef()
|
|
|
|
df::general_ref_building_civzone_assignedst * createCivzoneRef()
|
|
|
@ -1283,7 +897,6 @@ bool isEmptyPasture(df::building* building)
|
|
|
|
df::building* findFreeNestboxZone()
|
|
|
|
df::building* findFreeNestboxZone()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
df::building * free_building = NULL;
|
|
|
|
df::building * free_building = NULL;
|
|
|
|
bool cage = false;
|
|
|
|
|
|
|
|
for (size_t b=0; b < world->buildings.all.size(); b++)
|
|
|
|
for (size_t b=0; b < world->buildings.all.size(); b++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
df::building* building = world->buildings.all[b];
|
|
|
|
df::building* building = world->buildings.all[b];
|
|
|
@ -1544,8 +1157,6 @@ command_result assignUnitToBuilding(color_ostream& out, df::unit* unit, df::buil
|
|
|
|
|
|
|
|
|
|
|
|
command_result assignUnitsToCagezone(color_ostream& out, vector<df::unit*> units, df::building* building, bool verbose)
|
|
|
|
command_result assignUnitsToCagezone(color_ostream& out, vector<df::unit*> units, df::building* building, bool verbose)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
command_result result = CR_WRONG_USAGE;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(!isPenPasture(building))
|
|
|
|
if(!isPenPasture(building))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
out << "A cage zone needs to be a pen/pasture containing at least one cage!" << endl;
|
|
|
|
out << "A cage zone needs to be a pen/pasture containing at least one cage!" << endl;
|
|
|
@ -1615,7 +1226,7 @@ command_result nickUnitsInZone(color_ostream& out, df::building* building, strin
|
|
|
|
df::building_civzonest * civz = (df::building_civzonest *) building;
|
|
|
|
df::building_civzonest * civz = (df::building_civzonest *) building;
|
|
|
|
for(size_t i = 0; i < civz->assigned_units.size(); i++)
|
|
|
|
for(size_t i = 0; i < civz->assigned_units.size(); i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
df::unit* unit = findUnitById(civz->assigned_units[i]);
|
|
|
|
df::unit* unit = df::unit::find(civz->assigned_units[i]);
|
|
|
|
if(unit)
|
|
|
|
if(unit)
|
|
|
|
Units::setNickname(unit, nick);
|
|
|
|
Units::setNickname(unit, nick);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -1635,7 +1246,7 @@ command_result nickUnitsInCage(color_ostream& out, df::building* building, strin
|
|
|
|
df::building_cagest* cage = (df::building_cagest*) building;
|
|
|
|
df::building_cagest* cage = (df::building_cagest*) building;
|
|
|
|
for(size_t i=0; i<cage->assigned_units.size(); i++)
|
|
|
|
for(size_t i=0; i<cage->assigned_units.size(); i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
df::unit* unit = findUnitById(cage->assigned_units[i]);
|
|
|
|
df::unit* unit = df::unit::find(cage->assigned_units[i]);
|
|
|
|
if(unit)
|
|
|
|
if(unit)
|
|
|
|
Units::setNickname(unit, nick);
|
|
|
|
Units::setNickname(unit, nick);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -1670,10 +1281,7 @@ command_result nickUnitsInBuilding(color_ostream& out, df::building* building, s
|
|
|
|
// dump some zone info
|
|
|
|
// dump some zone info
|
|
|
|
void zoneInfo(color_ostream & out, df::building* building, bool verbose)
|
|
|
|
void zoneInfo(color_ostream & out, df::building* building, bool verbose)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if(building->getType()!= building_type::Civzone)
|
|
|
|
if(!isActivityZone(building))
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(building->getSubtype() != (short)civzone_type::ActivityZone)
|
|
|
|
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
string name;
|
|
|
|
string name;
|
|
|
@ -1689,7 +1297,7 @@ void zoneInfo(color_ostream & out, df::building* building, bool verbose)
|
|
|
|
out.print("\n");
|
|
|
|
out.print("\n");
|
|
|
|
|
|
|
|
|
|
|
|
df::building_civzonest * civ = (df::building_civzonest *) building;
|
|
|
|
df::building_civzonest * civ = (df::building_civzonest *) building;
|
|
|
|
if(civ->zone_flags.bits.active)
|
|
|
|
if(isActive(civ))
|
|
|
|
out << "active";
|
|
|
|
out << "active";
|
|
|
|
else
|
|
|
|
else
|
|
|
|
out << "not active";
|
|
|
|
out << "not active";
|
|
|
@ -1712,7 +1320,7 @@ void zoneInfo(color_ostream & out, df::building* building, bool verbose)
|
|
|
|
<< " z:" <<building->z
|
|
|
|
<< " z:" <<building->z
|
|
|
|
<< endl;
|
|
|
|
<< endl;
|
|
|
|
|
|
|
|
|
|
|
|
int32_t creaturecount = civ->assigned_units.size();
|
|
|
|
size_t creaturecount = civ->assigned_units.size();
|
|
|
|
out << "Creatures in this zone: " << creaturecount << endl;
|
|
|
|
out << "Creatures in this zone: " << creaturecount << endl;
|
|
|
|
for(size_t c = 0; c < creaturecount; c++)
|
|
|
|
for(size_t c = 0; c < creaturecount; c++)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -1752,7 +1360,7 @@ void cageInfo(color_ostream & out, df::building* building, bool verbose)
|
|
|
|
|
|
|
|
|
|
|
|
df::building_cagest * cage = (df::building_cagest*) building;
|
|
|
|
df::building_cagest * cage = (df::building_cagest*) building;
|
|
|
|
|
|
|
|
|
|
|
|
int32_t creaturecount = cage->assigned_units.size();
|
|
|
|
size_t creaturecount = cage->assigned_units.size();
|
|
|
|
out << "Creatures in this cage: " << creaturecount << endl;
|
|
|
|
out << "Creatures in this cage: " << creaturecount << endl;
|
|
|
|
for(size_t c = 0; c < creaturecount; c++)
|
|
|
|
for(size_t c = 0; c < creaturecount; c++)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -1827,7 +1435,6 @@ command_result df_zone (color_ostream &out, vector <string> & parameters)
|
|
|
|
bool find_tame = false;
|
|
|
|
bool find_tame = false;
|
|
|
|
bool find_not_tame = false;
|
|
|
|
bool find_not_tame = false;
|
|
|
|
bool find_merchant = false;
|
|
|
|
bool find_merchant = false;
|
|
|
|
bool find_not_merchant = false;
|
|
|
|
|
|
|
|
bool find_male = false;
|
|
|
|
bool find_male = false;
|
|
|
|
bool find_not_male = false;
|
|
|
|
bool find_not_male = false;
|
|
|
|
bool find_female = false;
|
|
|
|
bool find_female = false;
|
|
|
@ -1864,7 +1471,7 @@ command_result df_zone (color_ostream &out, vector <string> & parameters)
|
|
|
|
bool verbose = false;
|
|
|
|
bool verbose = false;
|
|
|
|
bool all = false;
|
|
|
|
bool all = false;
|
|
|
|
bool unit_slaughter = false;
|
|
|
|
bool unit_slaughter = false;
|
|
|
|
static int target_building = -1;
|
|
|
|
static df::building* target_building = NULL;
|
|
|
|
bool nick_set = false;
|
|
|
|
bool nick_set = false;
|
|
|
|
string target_nick = "";
|
|
|
|
string target_nick = "";
|
|
|
|
|
|
|
|
|
|
|
@ -1935,19 +1542,19 @@ command_result df_zone (color_ostream &out, vector <string> & parameters)
|
|
|
|
if(new_building != -1)
|
|
|
|
if(new_building != -1)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
i++;
|
|
|
|
i++;
|
|
|
|
target_building = new_building;
|
|
|
|
target_building = df::building::find(new_building);
|
|
|
|
out << "Assign selected unit(s) to building #" << target_building <<std::endl;
|
|
|
|
out << "Assign selected unit(s) to building #" << new_building <<std::endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(target_building == -1)
|
|
|
|
if(!target_building)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
out.printerr("No building id specified and current one is invalid!\n");
|
|
|
|
out.printerr("No building id specified and current one is invalid!\n");
|
|
|
|
return CR_WRONG_USAGE;
|
|
|
|
return CR_WRONG_USAGE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
out << "No buiding id specified. Will try to use #" << target_building << endl;
|
|
|
|
out << "No buiding id specified. Will try to use #" << target_building->id << endl;
|
|
|
|
building_assign = true;
|
|
|
|
building_assign = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -1968,18 +1575,18 @@ command_result df_zone (color_ostream &out, vector <string> & parameters)
|
|
|
|
if(new_building != -1)
|
|
|
|
if(new_building != -1)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
i++;
|
|
|
|
i++;
|
|
|
|
target_building = new_building;
|
|
|
|
target_building = df::building::find(new_building);
|
|
|
|
out << "Assign selected unit(s) to cagezone #" << target_building <<std::endl;
|
|
|
|
out << "Assign selected unit(s) to cagezone #" << new_building <<std::endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(target_building == -1)
|
|
|
|
if(!target_building)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
out.printerr("No building id specified and current one is invalid!\n");
|
|
|
|
out.printerr("No building id specified and current one is invalid!\n");
|
|
|
|
return CR_WRONG_USAGE;
|
|
|
|
return CR_WRONG_USAGE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
out << "No buiding id specified. Will try to use #" << target_building << endl;
|
|
|
|
out << "No buiding id specified. Will try to use #" << target_building->id << endl;
|
|
|
|
cagezone_assign = true;
|
|
|
|
cagezone_assign = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -2260,7 +1867,6 @@ command_result df_zone (color_ostream &out, vector <string> & parameters)
|
|
|
|
else if(p == "merchant" && invert_filter)
|
|
|
|
else if(p == "merchant" && invert_filter)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// actually 'not merchant' is pointless since merchant units are ignored by default
|
|
|
|
// actually 'not merchant' is pointless since merchant units are ignored by default
|
|
|
|
find_not_merchant = true;
|
|
|
|
|
|
|
|
invert_filter=false;
|
|
|
|
invert_filter=false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(p == "milkable" && !invert_filter)
|
|
|
|
else if(p == "milkable" && !invert_filter)
|
|
|
@ -2382,21 +1988,13 @@ command_result df_zone (color_ostream &out, vector <string> & parameters)
|
|
|
|
// (doesn't use the findXyzAtCursor() methods because zones might overlap and contain a cage or chain)
|
|
|
|
// (doesn't use the findXyzAtCursor() methods because zones might overlap and contain a cage or chain)
|
|
|
|
if(zone_info) // || chain_info || cage_info)
|
|
|
|
if(zone_info) // || chain_info || cage_info)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for (size_t b = 0; b < world->buildings.all.size(); b++)
|
|
|
|
vector<df::building_civzonest*> zones;
|
|
|
|
{
|
|
|
|
Buildings::findCivzonesAt(&zones, Gui::getCursorPos());
|
|
|
|
df::building * building = world->buildings.all[b];
|
|
|
|
for (auto zone = zones.begin(); zone != zones.end(); ++zone)
|
|
|
|
|
|
|
|
zoneInfo(out, *zone, verbose);
|
|
|
|
// find building under cursor
|
|
|
|
df::building* building = Buildings::findAtTile(Gui::getCursorPos());
|
|
|
|
if (!all &&
|
|
|
|
|
|
|
|
!(building->x1 <= cursor->x && cursor->x <= building->x2 &&
|
|
|
|
|
|
|
|
building->y1 <= cursor->y && cursor->y <= building->y2 &&
|
|
|
|
|
|
|
|
building->z == cursor->z))
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
zoneInfo(out, building, verbose);
|
|
|
|
|
|
|
|
chainInfo(out, building, verbose);
|
|
|
|
chainInfo(out, building, verbose);
|
|
|
|
cageInfo(out, building, verbose);
|
|
|
|
cageInfo(out, building, verbose);
|
|
|
|
}
|
|
|
|
|
|
|
|
return CR_OK;
|
|
|
|
return CR_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -2406,14 +2004,14 @@ command_result df_zone (color_ostream &out, vector <string> & parameters)
|
|
|
|
// cagezone wants a pen/pit as starting point
|
|
|
|
// cagezone wants a pen/pit as starting point
|
|
|
|
if(!cagezone_assign)
|
|
|
|
if(!cagezone_assign)
|
|
|
|
target_building = findCageAtCursor();
|
|
|
|
target_building = findCageAtCursor();
|
|
|
|
if(target_building != -1)
|
|
|
|
if(!target_building)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
out << "Target building type: cage." << endl;
|
|
|
|
out << "Target building type: cage." << endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
target_building = findPenPitAtCursor();
|
|
|
|
target_building = findPenPitAt(Gui::getCursorPos());
|
|
|
|
if(target_building == -1)
|
|
|
|
if(!target_building)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
out << "No pen/pasture or pit under cursor!" << endl;
|
|
|
|
out << "No pen/pasture or pit under cursor!" << endl;
|
|
|
|
return CR_WRONG_USAGE;
|
|
|
|
return CR_WRONG_USAGE;
|
|
|
@ -2423,29 +2021,23 @@ command_result df_zone (color_ostream &out, vector <string> & parameters)
|
|
|
|
out << "Target building type: pen/pasture or pit." << endl;
|
|
|
|
out << "Target building type: pen/pasture or pit." << endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
out << "Current building set to #" << target_building << endl;
|
|
|
|
out << "Current building set to #" << target_building->id << endl;
|
|
|
|
return CR_OK;
|
|
|
|
return CR_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(building_assign || cagezone_assign || unit_info || unit_slaughter || nick_set)
|
|
|
|
if(building_assign || cagezone_assign || unit_info || unit_slaughter || nick_set)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
df::building * building;
|
|
|
|
|
|
|
|
if(building_assign || cagezone_assign || (nick_set && !all && !find_count))
|
|
|
|
if(building_assign || cagezone_assign || (nick_set && !all && !find_count))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// try to get building index from the id
|
|
|
|
if (!target_building)
|
|
|
|
int32_t index = findBuildingIndexById(target_building);
|
|
|
|
|
|
|
|
if(index == -1)
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
out << "Invalid building id." << endl;
|
|
|
|
out << "Invalid building id." << endl;
|
|
|
|
target_building = -1;
|
|
|
|
|
|
|
|
return CR_WRONG_USAGE;
|
|
|
|
return CR_WRONG_USAGE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
building = world->buildings.all.at(index);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(nick_set && !building_assign)
|
|
|
|
if(nick_set && !building_assign)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
out << "Renaming all units in target building." << endl;
|
|
|
|
out << "Renaming all units in target building." << endl;
|
|
|
|
return nickUnitsInBuilding(out, building, target_nick);
|
|
|
|
return nickUnitsInBuilding(out, target_building, target_nick);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -2497,8 +2089,8 @@ command_result df_zone (color_ostream &out, vector <string> & parameters)
|
|
|
|
|| (find_not_war && isWar(unit))
|
|
|
|
|| (find_not_war && isWar(unit))
|
|
|
|
|| (find_hunter && !isHunter(unit))
|
|
|
|
|| (find_hunter && !isHunter(unit))
|
|
|
|
|| (find_not_hunter && isHunter(unit))
|
|
|
|
|| (find_not_hunter && isHunter(unit))
|
|
|
|
|| (find_agemin && getUnitAge(unit)<target_agemin)
|
|
|
|
|| (find_agemin && (int) getAge(unit, true)<target_agemin)
|
|
|
|
|| (find_agemax && getUnitAge(unit)>target_agemax)
|
|
|
|
|| (find_agemax && (int) getAge(unit, true)>target_agemax)
|
|
|
|
|| (find_grazer && !isGrazer(unit))
|
|
|
|
|| (find_grazer && !isGrazer(unit))
|
|
|
|
|| (find_not_grazer && isGrazer(unit))
|
|
|
|
|| (find_not_grazer && isGrazer(unit))
|
|
|
|
|| (find_egglayer && !isEggLayer(unit))
|
|
|
|
|| (find_egglayer && !isEggLayer(unit))
|
|
|
@ -2553,7 +2145,7 @@ command_result df_zone (color_ostream &out, vector <string> & parameters)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(building_assign)
|
|
|
|
else if(building_assign)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
command_result result = assignUnitToBuilding(out, unit, building, verbose);
|
|
|
|
command_result result = assignUnitToBuilding(out, unit, target_building, verbose);
|
|
|
|
if(result != CR_OK)
|
|
|
|
if(result != CR_OK)
|
|
|
|
return result;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -2571,7 +2163,7 @@ command_result df_zone (color_ostream &out, vector <string> & parameters)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(cagezone_assign)
|
|
|
|
if(cagezone_assign)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
command_result result = assignUnitsToCagezone(out, units_for_cagezone, building, verbose);
|
|
|
|
command_result result = assignUnitsToCagezone(out, units_for_cagezone, target_building, verbose);
|
|
|
|
if(result != CR_OK)
|
|
|
|
if(result != CR_OK)
|
|
|
|
return result;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -2592,7 +2184,7 @@ command_result df_zone (color_ostream &out, vector <string> & parameters)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(building_assign)
|
|
|
|
else if(building_assign)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return assignUnitToBuilding(out, unit, building, verbose);
|
|
|
|
return assignUnitToBuilding(out, unit, target_building, verbose);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(unit_slaughter)
|
|
|
|
else if(unit_slaughter)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -2771,8 +2363,8 @@ command_result autoNestbox( color_ostream &out, bool verbose = false )
|
|
|
|
// (assuming that the value from there indicates in which tick of the current year the unit was born)
|
|
|
|
// (assuming that the value from there indicates in which tick of the current year the unit was born)
|
|
|
|
bool compareUnitAgesYounger(df::unit* i, df::unit* j)
|
|
|
|
bool compareUnitAgesYounger(df::unit* i, df::unit* j)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
int32_t age_i = getUnitAge(i);
|
|
|
|
int32_t age_i = (int32_t) getAge(i, true);
|
|
|
|
int32_t age_j = getUnitAge(j);
|
|
|
|
int32_t age_j = (int32_t) getAge(j, true);
|
|
|
|
if(age_i == 0 && age_j == 0)
|
|
|
|
if(age_i == 0 && age_j == 0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
age_i = i->relations.birth_time;
|
|
|
|
age_i = i->relations.birth_time;
|
|
|
@ -2782,8 +2374,8 @@ bool compareUnitAgesYounger(df::unit* i, df::unit* j)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bool compareUnitAgesOlder(df::unit* i, df::unit* j)
|
|
|
|
bool compareUnitAgesOlder(df::unit* i, df::unit* j)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
int32_t age_i = getUnitAge(i);
|
|
|
|
int32_t age_i = (int32_t) getAge(i, true);
|
|
|
|
int32_t age_j = getUnitAge(j);
|
|
|
|
int32_t age_j = (int32_t) getAge(j, true);
|
|
|
|
if(age_i == 0 && age_j == 0)
|
|
|
|
if(age_i == 0 && age_j == 0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
age_i = i->relations.birth_time;
|
|
|
|
age_i = i->relations.birth_time;
|
|
|
@ -2811,30 +2403,32 @@ public:
|
|
|
|
int raceId;
|
|
|
|
int raceId;
|
|
|
|
|
|
|
|
|
|
|
|
// target amounts
|
|
|
|
// target amounts
|
|
|
|
int fk; // max female kids
|
|
|
|
unsigned fk; // max female kids
|
|
|
|
int mk; // max male kids
|
|
|
|
unsigned mk; // max male kids
|
|
|
|
int fa; // max female adults
|
|
|
|
unsigned fa; // max female adults
|
|
|
|
int ma; // max male adults
|
|
|
|
unsigned ma; // max male adults
|
|
|
|
|
|
|
|
|
|
|
|
// amounts of protected (not butcherable) units
|
|
|
|
// amounts of protected (not butcherable) units
|
|
|
|
int fk_prot;
|
|
|
|
unsigned fk_prot;
|
|
|
|
int fa_prot;
|
|
|
|
unsigned fa_prot;
|
|
|
|
int mk_prot;
|
|
|
|
unsigned mk_prot;
|
|
|
|
int ma_prot;
|
|
|
|
unsigned ma_prot;
|
|
|
|
|
|
|
|
|
|
|
|
// butcherable units
|
|
|
|
// butcherable units
|
|
|
|
vector <df::unit*> fk_ptr;
|
|
|
|
vector <df::unit*> unit_ptr[4];
|
|
|
|
vector <df::unit*> mk_ptr;
|
|
|
|
vector <df::unit*> fk_ptr = unit_ptr[0];
|
|
|
|
vector <df::unit*> fa_ptr;
|
|
|
|
vector <df::unit*> mk_ptr = unit_ptr[1];
|
|
|
|
vector <df::unit*> ma_ptr;
|
|
|
|
vector <df::unit*> fa_ptr = unit_ptr[2];
|
|
|
|
|
|
|
|
vector <df::unit*> ma_ptr = unit_ptr[3];
|
|
|
|
|
|
|
|
|
|
|
|
// priority butcherable units
|
|
|
|
// priority butcherable units
|
|
|
|
vector <df::unit*> fk_pri_ptr;
|
|
|
|
vector <df::unit*> prot_ptr[4];
|
|
|
|
vector <df::unit*> mk_pri_ptr;
|
|
|
|
vector <df::unit*> fk_pri_ptr = prot_ptr[0];
|
|
|
|
vector <df::unit*> fa_pri_ptr;
|
|
|
|
vector <df::unit*> mk_pri_ptr = prot_ptr[1];
|
|
|
|
vector <df::unit*> ma_pri_ptr;
|
|
|
|
vector <df::unit*> fa_pri_ptr = prot_ptr[2];
|
|
|
|
|
|
|
|
vector <df::unit*> ma_pri_ptr = prot_ptr[3];
|
|
|
|
|
|
|
|
|
|
|
|
WatchedRace(bool watch, int id, int _fk, int _mk, int _fa, int _ma)
|
|
|
|
WatchedRace(bool watch, int id, unsigned _fk, unsigned _mk, unsigned _fa, unsigned _ma)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
isWatched = watch;
|
|
|
|
isWatched = watch;
|
|
|
|
raceId = id;
|
|
|
|
raceId = id;
|
|
|
@ -2854,7 +2448,7 @@ public:
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if(!rconfig.isValid())
|
|
|
|
if(!rconfig.isValid())
|
|
|
|
{
|
|
|
|
{
|
|
|
|
string keyname = "autobutcher/watchlist/" + getRaceName(raceId);
|
|
|
|
string keyname = "autobutcher/watchlist/" + getRaceNameById(raceId);
|
|
|
|
rconfig = World::GetPersistentData(keyname, NULL);
|
|
|
|
rconfig = World::GetPersistentData(keyname, NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(rconfig.isValid())
|
|
|
|
if(rconfig.isValid())
|
|
|
@ -2869,7 +2463,7 @@ public:
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// this should never happen
|
|
|
|
// this should never happen
|
|
|
|
string keyname = "autobutcher/watchlist/" + getRaceName(raceId);
|
|
|
|
string keyname = "autobutcher/watchlist/" + getRaceNameById(raceId);
|
|
|
|
out << "Something failed, could not find/create config key " << keyname << "!" << endl;
|
|
|
|
out << "Something failed, could not find/create config key " << keyname << "!" << endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -2950,17 +2544,14 @@ public:
|
|
|
|
void ClearUnits()
|
|
|
|
void ClearUnits()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
fk_prot = fa_prot = mk_prot = ma_prot = 0;
|
|
|
|
fk_prot = fa_prot = mk_prot = ma_prot = 0;
|
|
|
|
fk_ptr.clear();
|
|
|
|
for (size_t i = 0; i < 4; i++)
|
|
|
|
mk_ptr.clear();
|
|
|
|
{
|
|
|
|
fa_ptr.clear();
|
|
|
|
unit_ptr[i].clear();
|
|
|
|
ma_ptr.clear();
|
|
|
|
prot_ptr[i].clear();
|
|
|
|
fk_pri_ptr.clear();
|
|
|
|
}
|
|
|
|
mk_pri_ptr.clear();
|
|
|
|
|
|
|
|
fa_pri_ptr.clear();
|
|
|
|
|
|
|
|
ma_pri_ptr.clear();
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int ProcessUnits(vector<df::unit*>& unit_ptr, vector<df::unit*>& unit_pri_ptr, int prot, int goal)
|
|
|
|
int ProcessUnits(vector<df::unit*>& unit_ptr, vector<df::unit*>& unit_pri_ptr, unsigned prot, unsigned goal)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
int subcount = 0;
|
|
|
|
int subcount = 0;
|
|
|
|
while(unit_pri_ptr.size() && (unit_ptr.size() + unit_pri_ptr.size() + prot > goal) )
|
|
|
|
while(unit_pri_ptr.size() && (unit_ptr.size() + unit_pri_ptr.size() + prot > goal) )
|
|
|
@ -3000,8 +2591,8 @@ std::vector<WatchedRace*> watched_races;
|
|
|
|
// helper for sorting the watchlist alphabetically
|
|
|
|
// helper for sorting the watchlist alphabetically
|
|
|
|
bool compareRaceNames(WatchedRace* i, WatchedRace* j)
|
|
|
|
bool compareRaceNames(WatchedRace* i, WatchedRace* j)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
string name_i = getRaceNamePlural(i->raceId);
|
|
|
|
string name_i = getRaceNamePluralById(i->raceId);
|
|
|
|
string name_j = getRaceNamePlural(j->raceId);
|
|
|
|
string name_j = getRaceNamePluralById(j->raceId);
|
|
|
|
|
|
|
|
|
|
|
|
return (name_i < name_j);
|
|
|
|
return (name_i < name_j);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -3009,10 +2600,10 @@ bool compareRaceNames(WatchedRace* i, WatchedRace* j)
|
|
|
|
static void autobutcher_sortWatchList(color_ostream &out);
|
|
|
|
static void autobutcher_sortWatchList(color_ostream &out);
|
|
|
|
|
|
|
|
|
|
|
|
// default target values for autobutcher
|
|
|
|
// default target values for autobutcher
|
|
|
|
static int default_fk = 5;
|
|
|
|
static unsigned default_fk = 5;
|
|
|
|
static int default_mk = 1;
|
|
|
|
static unsigned default_mk = 1;
|
|
|
|
static int default_fa = 5;
|
|
|
|
static unsigned default_fa = 5;
|
|
|
|
static int default_ma = 1;
|
|
|
|
static unsigned default_ma = 1;
|
|
|
|
|
|
|
|
|
|
|
|
command_result df_autobutcher(color_ostream &out, vector <string> & parameters)
|
|
|
|
command_result df_autobutcher(color_ostream &out, vector <string> & parameters)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -3028,12 +2619,10 @@ command_result df_autobutcher(color_ostream &out, vector <string> & parameters)
|
|
|
|
vector <string> target_racenames;
|
|
|
|
vector <string> target_racenames;
|
|
|
|
vector <int> target_raceids;
|
|
|
|
vector <int> target_raceids;
|
|
|
|
|
|
|
|
|
|
|
|
int target_fk = default_fk;
|
|
|
|
unsigned target_fk = default_fk;
|
|
|
|
int target_mk = default_mk;
|
|
|
|
unsigned target_mk = default_mk;
|
|
|
|
int target_fa = default_fa;
|
|
|
|
unsigned target_fa = default_fa;
|
|
|
|
int target_ma = default_ma;
|
|
|
|
unsigned target_ma = default_ma;
|
|
|
|
|
|
|
|
|
|
|
|
int32_t target_raceid = -1;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(!parameters.size())
|
|
|
|
if(!parameters.size())
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -3343,7 +2932,7 @@ command_result df_autobutcher(color_ostream &out, vector <string> & parameters)
|
|
|
|
bool found_race = false;
|
|
|
|
bool found_race = false;
|
|
|
|
for(size_t i=0; i<num_races; i++)
|
|
|
|
for(size_t i=0; i<num_races; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if(getRaceName(i) == target_racenames.back())
|
|
|
|
if(getRaceNameById(i) == target_racenames.back())
|
|
|
|
{
|
|
|
|
{
|
|
|
|
target_raceids.push_back(i);
|
|
|
|
target_raceids.push_back(i);
|
|
|
|
target_racenames.pop_back();
|
|
|
|
target_racenames.pop_back();
|
|
|
@ -3480,7 +3069,7 @@ command_result autoButcher( color_ostream &out, bool verbose = false )
|
|
|
|
watched_races.push_back(w);
|
|
|
|
watched_races.push_back(w);
|
|
|
|
|
|
|
|
|
|
|
|
string announce;
|
|
|
|
string announce;
|
|
|
|
announce = "New race added to autobutcher watchlist: " + getRaceNamePlural(w->raceId);
|
|
|
|
announce = "New race added to autobutcher watchlist: " + getRaceNamePluralById(w->raceId);
|
|
|
|
Gui::showAnnouncement(announce, 2, false);
|
|
|
|
Gui::showAnnouncement(announce, 2, false);
|
|
|
|
autobutcher_sortWatchList(out);
|
|
|
|
autobutcher_sortWatchList(out);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -3517,7 +3106,7 @@ command_result autoButcher( color_ostream &out, bool verbose = false )
|
|
|
|
stringstream ss;
|
|
|
|
stringstream ss;
|
|
|
|
ss << slaughter_subcount;
|
|
|
|
ss << slaughter_subcount;
|
|
|
|
string announce;
|
|
|
|
string announce;
|
|
|
|
announce = getRaceNamePlural(w->raceId) + " marked for slaughter: " + ss.str();
|
|
|
|
announce = getRaceNamePluralById(w->raceId) + " marked for slaughter: " + ss.str();
|
|
|
|
Gui::showAnnouncement(announce, 2, false);
|
|
|
|
Gui::showAnnouncement(announce, 2, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -3845,7 +3434,7 @@ void butcherRace(int race)
|
|
|
|
if(!isContainedInItem(unit) && !hasValidMapPos(unit))
|
|
|
|
if(!isContainedInItem(unit) && !hasValidMapPos(unit))
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
unit->flags2.bits.slaughter = true;
|
|
|
|
doMarkForSlaughter(unit);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -3868,7 +3457,7 @@ void unbutcherRace(int race)
|
|
|
|
if(!isContainedInItem(unit) && !hasValidMapPos(unit))
|
|
|
|
if(!isContainedInItem(unit) && !hasValidMapPos(unit))
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
unit->flags2.bits.slaughter = false;
|
|
|
|
unit->flags2.bits.slaughter = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -3954,7 +3543,7 @@ static void autobutcher_setWatchListRace(color_ostream &out, unsigned id, unsign
|
|
|
|
watched_races.push_back(w);
|
|
|
|
watched_races.push_back(w);
|
|
|
|
|
|
|
|
|
|
|
|
string announce;
|
|
|
|
string announce;
|
|
|
|
announce = "New race added to autobutcher watchlist: " + getRaceNamePlural(w->raceId);
|
|
|
|
announce = "New race added to autobutcher watchlist: " + getRaceNamePluralById(w->raceId);
|
|
|
|
Gui::showAnnouncement(announce, 2, false);
|
|
|
|
Gui::showAnnouncement(announce, 2, false);
|
|
|
|
autobutcher_sortWatchList(out);
|
|
|
|
autobutcher_sortWatchList(out);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -4049,7 +3638,7 @@ static int autobutcher_getWatchList(lua_State *L)
|
|
|
|
WatchedRace * w = watched_races[i];
|
|
|
|
WatchedRace * w = watched_races[i];
|
|
|
|
Lua::SetField(L, w->raceId, ctable, "id");
|
|
|
|
Lua::SetField(L, w->raceId, ctable, "id");
|
|
|
|
Lua::SetField(L, w->isWatched, ctable, "watched");
|
|
|
|
Lua::SetField(L, w->isWatched, ctable, "watched");
|
|
|
|
Lua::SetField(L, getRaceNamePlural(w->raceId), ctable, "name");
|
|
|
|
Lua::SetField(L, getRaceNamePluralById(w->raceId), ctable, "name");
|
|
|
|
Lua::SetField(L, w->fk, ctable, "fk");
|
|
|
|
Lua::SetField(L, w->fk, ctable, "fk");
|
|
|
|
Lua::SetField(L, w->mk, ctable, "mk");
|
|
|
|
Lua::SetField(L, w->mk, ctable, "mk");
|
|
|
|
Lua::SetField(L, w->fa, ctable, "fa");
|
|
|
|
Lua::SetField(L, w->fa, ctable, "fa");
|
|
|
@ -4178,7 +3767,7 @@ public:
|
|
|
|
int adjusted_item_index = i;
|
|
|
|
int adjusted_item_index = i;
|
|
|
|
if (list_has_been_sorted)
|
|
|
|
if (list_has_been_sorted)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for (int j = 0; j < ui_building_assign_units->size(); j++)
|
|
|
|
for (size_t j = 0; j < ui_building_assign_units->size(); j++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (ui_building_assign_units->at(j) == reference_list[i])
|
|
|
|
if (ui_building_assign_units->at(j) == reference_list[i])
|
|
|
|
{
|
|
|
|
{
|
|
|
|