Merge remote-tracking branch 'q-github/master'

develop
Alexander Gavrilov 2012-01-19 12:07:00 +04:00
commit d75292acc7
13 changed files with 356 additions and 1086 deletions

@ -1094,7 +1094,6 @@ MODULE_GETTER(Maps);
MODULE_GETTER(Gui);
MODULE_GETTER(World);
MODULE_GETTER(Materials);
MODULE_GETTER(Items);
MODULE_GETTER(Translation);
MODULE_GETTER(Vegetation);
MODULE_GETTER(Constructions);

@ -58,7 +58,6 @@ namespace DFHack
class Gui;
class World;
class Materials;
class Items;
class Translation;
class Vegetation;
class Constructions;
@ -111,8 +110,6 @@ namespace DFHack
World * getWorld();
/// get the materials module
Materials * getMaterials();
/// get the items module
Items * getItems();
/// get the translation module
Translation * getTranslation();
/// get the vegetation module
@ -173,7 +170,6 @@ namespace DFHack
Gui * pGui;
World * pWorld;
Materials * pMaterials;
Items * pItems;
Translation * pTranslation;
Vegetation * pVegetation;
Constructions * pConstructions;

@ -35,7 +35,6 @@ namespace DFHack
Module* createGui();
Module* createWorld();
Module* createMaterials();
Module* createItems();
Module* createTranslation();
Module* createVegetation();
Module* createBuildings();

@ -34,7 +34,9 @@ distribution.
#include "MemAccess.h"
#include "DataDefs.h"
#include "df/item.h"
#include "df/item_type.h"
#include "df/general_ref.h"
namespace df
{
@ -90,408 +92,17 @@ class Context;
class DFContextShared;
class Units;
/**
* Item flags. A bit fuzzy.
* Mostly from http://dwarffortresswiki.net/index.php/User:Rick/Memory_research
* \ingroup grp_items
*/
union t_itemflags
{
uint32_t whole; ///< the whole struct. all 32 bits of it, as an integer
struct
{
unsigned int on_ground : 1; ///< 0000 0001 Item on ground
unsigned int in_job : 1; ///< 0000 0002 Item currently being used in a job
unsigned int hostile : 1; ///< 0000 0004 Item owned by hostile
unsigned int in_inventory : 1; ///< 0000 0008 Item in a creature or workshop inventory
unsigned int unk1 : 1; ///< 0000 0010 unknown, lost (artifact)?, unusable, unseen
unsigned int in_building : 1; ///< 0000 0020 Part of a building (including mechanisms, bodies in coffins)
unsigned int unk2 : 1; ///< 0000 0040 unknown, unseen
unsigned int dead_dwarf : 1; ///< 0000 0080 Dwarf's dead body or body part
unsigned int rotten : 1; ///< 0000 0100 Rotten food
unsigned int spider_web : 1; ///< 0000 0200 Thread in spider web
unsigned int construction : 1; ///< 0000 0400 Material used in construction
unsigned int unk3 : 1; ///< 0000 0800 unknown, unseen, unusable
unsigned int unk4 : 1; ///< 0000 1000 unknown, unseen
unsigned int murder : 1; ///< 0000 2000 Implies murder - used in fell moods
unsigned int foreign : 1; ///< 0000 4000 Item is imported
unsigned int trader : 1; ///< 0000 8000 Item ownwed by trader
unsigned int owned : 1; ///< 0001 0000 Item is owned by a dwarf
unsigned int garbage_colect : 1; ///< 0002 0000 Marked for deallocation by DF it seems
unsigned int artifact1 : 1; ///< 0004 0000 Artifact ?
unsigned int forbid : 1; ///< 0008 0000 Forbidden item
unsigned int unk6 : 1; ///< 0010 0000 unknown, unseen
unsigned int dump : 1; ///< 0020 0000 Designated for dumping
unsigned int on_fire: 1; ///< 0040 0000 Indicates if item is on fire, Will Set Item On Fire if Set!
unsigned int melt : 1; ///< 0080 0000 Designated for melting, if applicable
unsigned int hidden : 1; ///< 0100 0000 Hidden item
unsigned int in_chest : 1; ///< 0200 0000 Stored in chest/part of well?
unsigned int unk7 : 1; ///< 0400 0000 unknown, unseen
unsigned int artifact2 : 1; ///< 0800 0000 Artifact ?
unsigned int unk8 : 1; ///< 1000 0000 unknown, unseen, common
unsigned int unk9 : 1; ///< 2000 0000 unknown, set when viewing details
unsigned int unk10 : 1; ///< 4000 0000 unknown, unseen
unsigned int unk11 : 1; ///< 8000 0000 unknown, unseen
};
};
/**
* Describes relationship of an item with other objects
* \ingroup grp_items
*/
struct t_itemref : public t_virtual
{
int32_t value;
};
struct df_contaminant
{
int16_t material;
int32_t mat_index;
int16_t mat_state; // FIXME: enum or document in text
int16_t temperature;
int16_t temperature_fraction; // maybe...
int32_t size; ///< 1-24=spatter, 25-49=smear, 50-* = coating
};
/**
* A partial mirror of a DF base type for items
* \ingroup grp_items
*/
class df_item
{
public:
// 4
int16_t x;
int16_t y;
// 8
int16_t z;
// C
t_itemflags flags;
// 10
uint32_t age;
// 14
uint32_t id;
// 18
std::vector<void *> unk1;
// 24 L, 28 W
std::vector<t_itemref *> itemrefs;
// 30 L, 38 W - these were mostly unset (0xCC with malloc patch)
int16_t mystery_meat[12];
// 48 L, 50 W
int32_t mystery1;
// 4C L, 54 W
int32_t mystery2;
// 50 L, 58 W
int32_t mystery3;
// 54 L, 5C W
int32_t mystery4;
// 58 L, 60 W
int32_t mystery5;
// 5C L, 64 W - pointer to vector of contaminants
std::vector <df_contaminant *> * contaminants;
// 60 L, 6C W - temperature in Urists
int16_t temperature;
// 62 L, 6E W - temperature fraction (maybe, just a guess)
int16_t temperature_fraction;
public:
// 0x0
virtual t_itemType getType();
virtual t_itemSubtype getSubtype();
virtual t_materialType getMaterial();
virtual t_materialIndex getMaterialIndex();
// 0x10
virtual void setSubType(t_itemSubtype);
virtual void setMaterial(t_materialType mat);
virtual void setMaterialIndex (t_materialIndex submat);
virtual t_materialType getMaterial2(); // weird
// 0x20
virtual t_materialIndex getMaterialIndex2(); // weird
virtual void fn9(void);
virtual void fn10(void);
virtual void fn11(void);
// 0x30
virtual void fn12(void);
virtual void fn13(void);
virtual void fn14(void);
virtual void fn15(void);
// 0x40
virtual void fn16(void);
virtual void fn17(void);
virtual void fn18(void);
virtual void fn19(void);
// 0x50
virtual void fn20(void);
virtual void fn21(void);
virtual void fn22(void);
virtual void fn23(void);
// 0x60
virtual void fn24(void);
virtual void fn25(void);
virtual void fn26(void);
virtual void fn27(void);
// 0x70
virtual void fn28(void);
virtual void fn29(void);
virtual void fn30(void);
virtual void fn31(void);
// 0x80
virtual void fn32(void);
virtual void fn33(void);
virtual void fn34(void);
virtual void fn35(void);
// 0x90
virtual void fn36(void);
virtual void fn37(void);
virtual void fn38(void);
virtual void fn39(void);
// 0xA0
virtual void fn40(void);
virtual void fn41(void);
virtual void fn42(void);
virtual void fn43(void);
// 0xB0
virtual void fn44(void);
virtual void fn45(void);
virtual void fn46(void);
virtual void fn47(void);
// 0xC0
virtual void fn48(void);
virtual void fn49(void);
virtual void fn50(void);
virtual int16_t getWear(void); // 0 = normal, 1 = x, 2 = X, 3 = XX
// 0xD0
virtual void setWear(int16_t wear); // also zeroes wear timer?
virtual void fn53(void);
virtual void fn54(void);
virtual void fn55(void);
// 0xE0
virtual void fn56(void);
virtual void fn57(void);
virtual void fn58(void);
virtual void fn59(void);
// 0xF0
virtual void fn60(void);
virtual void fn61(void);
virtual void fn62(void);
virtual void fn63(void);
// 0x100
virtual void fn64(void);
virtual void fn65(void);
virtual void fn66(void);
virtual void fn67(void);
// 0x110
virtual void fn68(void);
virtual void fn69(void);
virtual void fn70(void);
virtual void fn71(void);
// 0x120
virtual void fn72(void);
virtual void fn73(void);
virtual void fn74(void);
virtual void fn75(void);
// 0x130
virtual void fn76(void);
virtual void fn77(void);
virtual void fn78(void);
virtual void fn79(void);
// 0x140
virtual void fn80(void);
virtual void fn81(void);
virtual void fn82(void);
virtual void fn83(void);
// 0x150
virtual void fn84(void);
virtual void fn85(void);
virtual void fn86(void);
virtual void fn87(void);
// 0x160
virtual void fn88(void);
virtual void fn89(void);
virtual void fn90(void);
virtual void fn91(void);
// 0x170
virtual void fn92(void);
virtual void fn93(void);
virtual void fn94(void);
virtual void fn95(void);
// 0x180
virtual void fn96(void);
virtual void fn97(void);
virtual void fn98(void);
virtual void fn99(void);
// 0x190
virtual void fn100(void);
virtual void fn101(void);
virtual void fn102(void);
virtual void fn103(void);
// 0x1A0
virtual void fn104(void);
virtual void fn105(void);
virtual void fn106(void);
virtual void fn107(void);
// 0x1B0
virtual void fn108(void);
virtual void fn109(void);
virtual void fn110(void);
virtual void fn111(void);
// 0x1C0
virtual void fn112(void);
virtual void fn113(void);
virtual void fn114(void);
virtual void fn115(void);
// 0x1D0
virtual void fn116(void);
virtual void fn117(void);
virtual void fn118(void);
virtual void fn119(void);
// 0x1E0
virtual void fn120(void);
virtual void fn121(void);
virtual void fn122(void);
virtual void fn123(void);
// 0x1F0
virtual void fn124(void);
virtual void fn125(void);
virtual void fn126(void);
virtual void fn127(void);
// 0x200
virtual void fn128(void);
virtual void fn129(void);
virtual void fn130(void);
virtual void fn131(void);
// 0x210
virtual void fn132(void);
virtual int32_t getStackSize( void );
virtual void fn134(void);
virtual void fn135(void);
// 0x220
virtual void fn136(void);
virtual void fn137(void);
virtual void fn138(void);
virtual void fn139(void);
// 0x230
virtual void fn140(void);
virtual void fn141(void);
virtual void fn142(void);
virtual void fn143(void);
// 0x240
virtual void fn144(void);
virtual void fn145(void);
virtual void fn146(void);
virtual void fn147(void);
// 0x250
virtual void fn148(void);
virtual void fn149(void);
virtual void fn150(void);
virtual int16_t getQuality( void );
// 0x260
virtual void fn152(void);
virtual void fn153(void);
virtual void fn154(void);
virtual void fn155(void);
// 0x270
virtual void fn156(void);
virtual void fn157(void);
virtual void fn158(void);
virtual void fn159(void);
// 0x280
virtual void fn160(void);
virtual void fn161(void);
virtual void fn162(void);
virtual void fn163(void);
// 0x290
virtual void fn164(void);
virtual void fn165(void);
virtual void fn166(void);
virtual void fn167(void);
// 0x2A0
virtual void fn168(void); // value returned (int) = first param to descriprion construction function
virtual void fn169(void);
virtual void fn170(void);
virtual void fn171(void);
// 0x2B0
virtual void fn172(void);
virtual void fn173(void);
virtual void fn174(void);
virtual void fn175(void);
// 0x2C0
virtual void fn176(void);
virtual void fn177(void);
//virtual std::string *getItemDescription ( std::string * str, int sizes = 0); // 0 = stacked, 1 = singular, 2 = plural
virtual std::string *getItemDescription ( std::string * str, int sizes = 0); // 0 = stacked, 1 = singular, 2 = plural
virtual void fn179(void);
// 0x2D0
virtual void fn180(void);
virtual void fn181(void);
virtual void fn182(void);
virtual void fn183(void);
// 0x2E0
virtual void fn184(void);
virtual void fn185(void);
virtual void fn186(void);
virtual void fn187(void);
// 0x2F0
virtual void fn188(void);
virtual void fn189(void);
virtual void fn190(void);
virtual void fn191(void);
// 0x300
virtual void fn192(void);
virtual void fn193(void);
virtual void fn194(void);
virtual void fn195(void);
// 0x310
virtual void fn196(void);
virtual void fn197(void);
virtual void fn198(void);
virtual void fn199(void);
// 0x320
virtual void fn200(void);
virtual void fn201(void);
virtual void fn202(void);
virtual void fn203(void);
// 0x330
virtual void fn204(void);
virtual void fn205(void);
virtual void fn206(void);
virtual void fn207(void);
// 0x340
virtual void fn208(void);
virtual void fn209(void);
virtual void fn210(void);
virtual void fn211(void);
// 0x350
virtual void fn212(void);
virtual void fn213(void);
virtual void fn214(void);
virtual void fn215(void);
// 0x360
virtual void fn216(void);
virtual void fn217(void);
// and this should be all 218 of them
// fn numbers start with 0
};
/**
* Type for holding an item read from DF
* \ingroup grp_items
*/
struct dfh_item
{
df_item *origin; // where this was read from
df::item *origin; // where this was read from
int16_t x;
int16_t y;
int16_t z;
t_itemflags flags;
df::item_flags flags;
uint32_t age;
uint32_t id;
t_material matdesc;
@ -500,154 +111,37 @@ struct dfh_item
int16_t wear_level;
};
/**
* Type for holding item improvements. broken/unused.
* \ingroup grp_items
*/
struct t_improvement
{
t_material matdesc;
int32_t quality;
};
/**
* The Items module
* \ingroup grp_modules
* \ingroup grp_items
*/
class DFHACK_EXPORT Items : public Module
namespace Simple
{
namespace Items
{
public:
/**
* All the known item types as an enum
* From http://df.magmawiki.com/index.php/DF2010:Item_token
*/
enum item_types
{
BAR, ///< Bars, such as metal, fuel, or soap.
SMALLGEM, ///< Cut gemstones usable in jeweler's workshop
BLOCKS, ///< Blocks of any kind.
ROUGH, ///< Rough gemstones.
BOULDER, ///< or IT_STONE - raw mined stone.
STONE = BOULDER,
WOOD, ///< Wooden logs.
DOOR, ///< Doors.
FLOODGATE, ///< Floodgates.
BED, ///< Beds.
CHAIR, ///< Chairs and thrones.
CHAIN, ///< Restraints.
FLASK, ///< Flasks.
GOBLET, ///< Goblets.
INSTRUMENT, ///< Musical instruments. Subtypes come from item_instrument.txt
TOY, ///< Toys. Subtypes come from item_toy.txt
WINDOW, ///< Glass windows.
CAGE, ///< Cages.
BARREL, ///< Barrels.
BUCKET, ///< Buckets.
ANIMALTRAP, ///< Animal traps.
TABLE, ///< Tables.
COFFIN, ///< Coffins.
STATUE, ///< Statues.
CORPSE, ///< Corpses.
WEAPON, ///< Weapons. Subtypes come from item_weapon.txt
ARMOR, ///< Armor and clothing worn on the upper body. Subtypes come from item_armor.txt
SHOES, ///< Armor and clothing worn on the feet. Subtypes come from item_shoes.txt
SHIELD, ///< Shields and bucklers. Subtypes come from item_shield.txt
HELM, ///< Armor and clothing worn on the head. Subtypes come from item_helm.txt
GLOVES, ///< Armor and clothing worn on the hands. Subtypes come from item_gloves.txt
BOX, ///< Chests (wood), coffers (stone), boxes (glass), and bags (cloth or leather).
BIN, ///< Bins.
ARMORSTAND, ///< Armor stands.
WEAPONRACK, ///< Weapon racks.
CABINET, ///< Cabinets.
FIGURINE, ///< Figurines.
AMULET, ///< Amulets.
SCEPTER, ///< Scepters.
AMMO, ///< Ammunition for hand-held weapons. Subtypes come from item_ammo.txt
CROWN, ///< Crowns.
RING, ///< Rings.
EARRING, ///< Earrings.
BRACELET, ///< Bracelets.
GEM, ///< Large gems.
ANVIL, ///< Anvils.
CORPSEPIECE,///< Body parts.
REMAINS, ///< Dead vermin bodies.
MEAT, ///< Butchered meat.
FISH, ///< Prepared fish.
FISH_RAW, ///< Unprepared fish.
VERMIN, ///< Live vermin.
PET, ///< Tame vermin.
SEEDS, ///< Seeds from plants.
PLANT, ///< Plants.
SKIN_TANNED,///< Tanned skins.
LEAVES, ///< Leaves, usually from quarry bushes.
THREAD, ///< Thread gathered from webs or made at the farmer's workshop.
CLOTH, ///< Cloth made at the loom.
TOTEM, ///< Skull totems.
PANTS, ///< Armor and clothing worn on the legs. Subtypes come from item_pants.txt
BACKPACK, ///< Backpacks.
QUIVER, ///< Quivers.
CATAPULTPARTS, ///< Catapult parts.
BALLISTAPARTS, ///< Ballista parts.
SIEGEAMMO, ///< Siege engine ammunition. Subtypes come from item_siegeammo.txt
BALLISTAARROWHEAD, ///< Ballista arrow heads.
TRAPPARTS, ///< Mechanisms.
TRAPCOMP, ///< Trap components. Subtypes come from item_trapcomp.txt
DRINK, ///< Alcoholic drinks.
POWDER_MISC,///< Powders such as flour, gypsum plaster, dye, or sand.
CHEESE, ///< Pieces of cheese.
FOOD, ///< Prepared meals. Subtypes come from item_food.txt
LIQUID_MISC,///< Liquids such as water, lye, and extracts.
COIN, ///< Coins.
GLOB, ///< Fat, tallow, pastes/pressed objects, and small bits of molten rock/metal.
ROCK, ///< Small rocks (usually sharpened and/or thrown in adventurer mode)
PIPE_SECTION, ///< Pipe sections.
HATCH_COVER, ///< Hatch covers.
GRATE, ///< Grates.
QUERN, ///< Querns.
MILLSTONE, ///< Millstones.
SPLINT, ///< Splints.
CRUTCH, ///< Crutches.
TRACTION_BENCH, ///< Traction benches.
ORTHOPEDIC_CAST, ///< Casts.
TOOL, ///< Tools. Subtypes come from item_tool.txt
SLAB, ///< Slabs.
EGG, ///< Eggs.
};
public:
Items();
~Items();
bool Start();
bool Finish();
/// Read the item vector from DF into a supplied vector
bool readItemVector(std::vector<df_item *> &items);
/// Look for a particular item by ID
df_item * findItemByID(int32_t id);
/// Make a partial copy of a DF item
bool copyItem(df_item * source, dfh_item & target);
/// write copied item back to its origin
bool writeItem(const dfh_item & item);
/// get the class name of an item
std::string getItemClass(const df_item * item);
/// who owns this item we already read?
int32_t getItemOwnerID(const df_item * item);
/// which item is it contained in?
int32_t getItemContainerID(const df_item * item);
/// which items does it contain?
bool getContainedItems(const df_item * item, /*output*/ std::vector<int32_t> &items);
/// wipe out the owner records
bool removeItemOwner(df_item * item, Units *creatures);
/// read item references, filtered by class
bool readItemRefs(const df_item * item, const ClassNameCheck &classname,
/*output*/ std::vector<int32_t> &values);
/// get list of item references that are unknown along with their values
bool unknownRefs(const df_item * item, /*output*/ std::vector<std::pair<std::string, int32_t> >& refs);
private:
class Private;
Private* d;
};
/// Look for a particular item by ID
DFHACK_EXPORT df::item * findItemByID(int32_t id);
/// Make a partial copy of a DF item
DFHACK_EXPORT bool copyItem(df::item * source, dfh_item & target);
/// write copied item back to its origin
DFHACK_EXPORT bool writeItem(const dfh_item & item);
/// get the class name of an item
DFHACK_EXPORT std::string getItemClass(const df::item * item);
/// who owns this item we already read?
DFHACK_EXPORT int32_t getItemOwnerID(const df::item * item);
/// which item is it contained in?
DFHACK_EXPORT int32_t getItemContainerID(const df::item * item);
/// which items does it contain?
DFHACK_EXPORT bool getContainedItems(const df::item * item, /*output*/ std::vector<int32_t> &items);
/// wipe out the owner records
DFHACK_EXPORT bool removeItemOwner(df::item * item, Units *creatures);
/// read item references, filtered by class
DFHACK_EXPORT bool readItemRefs(const df::item * item, const df::general_ref_type type,
/*output*/ std::vector<int32_t> &values);
}
}
}

@ -557,7 +557,7 @@ namespace DFHack
int16_t unk_280;
int32_t unk_284;
std::vector<df_item *> inventory; // 288 - vector of item pointers
std::vector<df::item *> inventory; // 288 - vector of item pointers
std::vector<int32_t> owned_items; // 298 - vector of item IDs
std::vector<uint32_t> unk_2a8;
std::vector<uint32_t> unk_2b8;
@ -777,8 +777,8 @@ namespace DFHack
bool ReadJob(const df_unit * unit, std::vector<t_material> & mat);
bool ReadInventoryByIdx(const uint32_t index, std::vector<df_item *> & item);
bool ReadInventoryByPtr(const df_unit * unit, std::vector<df_item *> & item);
bool ReadInventoryByIdx(const uint32_t index, std::vector<df::item *> & item);
bool ReadInventoryByPtr(const df_unit * unit, std::vector<df::item *> & item);
bool ReadOwnedItemsByIdx(const uint32_t index, std::vector<int32_t> & item);
bool ReadOwnedItemsByPtr(const df_unit * unit, std::vector<int32_t> & item);
@ -807,8 +807,6 @@ namespace DFHack
void CopyNameTo(df_unit *creature, df_name * target);
protected:
friend class Items;
bool RemoveOwnedItemByIdx(const uint32_t index, int32_t id);
bool RemoveOwnedItemByPtr(df_unit * unit, int32_t id);

@ -30,9 +30,9 @@ distribution.
#include "Module.h"
#include "Types.h"
#include "VersionInfo.h"
#include "modules/Materials.h"
#include "modules/Items.h"
#include "Core.h"
#include "modules/Items.h"
/**
* \defgroup grp_kitchen Kitchen settings
* @ingroup grp_modules
@ -40,6 +40,8 @@ distribution.
namespace DFHack
{
namespace Simple
{
namespace Kitchen
{
typedef uint8_t t_exclusionType;
@ -52,45 +54,33 @@ const t_itemSubtype limitSubtype = 0; // used to store limit as an entry in the
const t_exclusionType limitExclusion = 4; // used to store limit as an entry in the exclusion list
/**
* Kitchen exclusions manipulator class. Currently geared towards plants and seeds.
* @ingroup grp_kitchen
* Kitchen exclusions manipulator. Currently geared towards plants and seeds.
* \ingroup grp_modules
* \ingroup grp_kitchen
*/
class DFHACK_EXPORT Exclusions
{
public:
/// ctor
Exclusions(DFHack::Core& core_);
/// dtor
~Exclusions();
/// print the exclusion list, with the material index also translated into its token (for organics) - for debug really
void debug_print() const;
/// remove this material from the exclusion list if it is in it
void allowPlantSeedCookery(t_materialIndex materialIndex);
// print the exclusion list, with the material index also translated into its token (for organics) - for debug really
DFHACK_EXPORT void debug_print(Core &);
/// add this material to the exclusion list, if it is not already in it
void denyPlantSeedCookery(t_materialIndex materialIndex);
// remove this material from the exclusion list if it is in it
DFHACK_EXPORT void allowPlantSeedCookery(t_materialIndex materialIndex);
/// fills a map with info from the limit info storage entries in the exclusion list
void fillWatchMap(std::map<t_materialIndex, unsigned int>& watchMap) const;
// add this material to the exclusion list, if it is not already in it
DFHACK_EXPORT void denyPlantSeedCookery(t_materialIndex materialIndex);
/// removes a limit info storage entry from the exclusion list if it's present
void removeLimit(t_materialIndex materialIndex);
// fills a map with info from the limit info storage entries in the exclusion list
DFHACK_EXPORT void fillWatchMap(std::map<t_materialIndex, unsigned int>& watchMap);
/// add a limit info storage item to the exclusion list, or alters an existing one
void setLimit(t_materialIndex materialIndex, unsigned int limit);
// removes a limit info storage entry from the exclusion list if it's present
DFHACK_EXPORT void removeLimit(t_materialIndex materialIndex);
/// clears all limit info storage items from the exclusion list
void clearLimits();
// add a limit info storage item to the exclusion list, or alters an existing one
DFHACK_EXPORT void setLimit(t_materialIndex materialIndex, unsigned int limit);
/// the size of the exclusions vectors (they are all the same size - if not, there is a problem!)
std::size_t size() const;
private:
class Private;
Private* d;
};
// clears all limit info storage items from the exclusion list
DFHACK_EXPORT void clearLimits();
DFHACK_EXPORT std::size_t size();
}
}
}

@ -1,4 +1,4 @@
/*
/*
https://github.com/peterix/dfhack
Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com)
@ -63,9 +63,12 @@ using namespace std;
#include "df/itemdef_foodst.h"
#include "df/trapcomp_flags.h"
#include "df/job_item.h"
#include "df/general_ref.h"
using namespace DFHack;
using namespace DFHack::Simple;
using namespace df::enums;
using df::global::world;
#define ITEMDEF_VECTORS \
ITEM(WEAPON, weapons, itemdef_weaponst) \
@ -393,153 +396,18 @@ bool ItemTypeInfo::matches(const df::job_item &item, MaterialInfo *mat)
bits_match(item.flags3.whole, item_ok3.whole, item_mask3.whole);
}
Module* DFHack::createItems()
{
return new Items();
}
class Items::Private
{
public:
Process * owner;
std::map<int32_t, df_item *> idLookupTable;
uint32_t refVectorOffset;
uint32_t idFieldOffset;
void * itemVectorAddress;
ClassNameCheck isOwnerRefClass;
ClassNameCheck isContainerRefClass;
ClassNameCheck isContainsRefClass;
// Similar to isOwnerRefClass. Value is unique to each creature, but
// different than the creature's id.
ClassNameCheck isUnitHolderRefClass;
// One of these is present for each creature contained in a cage.
// The value is similar to that for isUnitHolderRefClass, different
// than the creature's ID but unique for each creature.
ClassNameCheck isCagedUnitRefClass;
// ID of bulding containing/holding the item.
ClassNameCheck isBuildingHolderRefClass;
// Building ID of lever/etc which triggers bridge/etc holding
// this mechanism.
ClassNameCheck isTriggeredByRefClass;
// Building ID of bridge/etc which is triggered by lever/etc holding
// this mechanism.
ClassNameCheck isTriggerTargetRefClass;
// Civilization ID of owner of item, for items not owned by the
// fortress.
ClassNameCheck isEntityOwnerRefClass;
// Item has been offered to the caravan. The value is the
// civilization ID of
ClassNameCheck isOfferedRefClass;
// Item is in a depot for trade. Purpose of value is unknown, but is
// different for each item, even in the same depot at the same time.
ClassNameCheck isTradingRefClass;
// Item is flying or falling through the air. The value seems to
// be the ID for a "projectile information" object.
ClassNameCheck isProjectileRefClass;
std::set<std::string> knownItemRefTypes;
};
Items::Items()
{
Core & c = Core::getInstance();
d = new Private;
d->owner = c.p;
DFHack::OffsetGroup* itemGroup = c.vinfo->getGroup("Items");
d->itemVectorAddress = itemGroup->getAddress("items_vector");
d->idFieldOffset = itemGroup->getOffset("id");
d->refVectorOffset = itemGroup->getOffset("item_ref_vector");
d->isOwnerRefClass = ClassNameCheck("general_ref_unit_itemownerst");
d->isContainerRefClass = ClassNameCheck("general_ref_contained_in_itemst");
d->isContainsRefClass = ClassNameCheck("general_ref_contains_itemst");
d->isUnitHolderRefClass = ClassNameCheck("general_ref_unit_holderst");
d->isCagedUnitRefClass = ClassNameCheck("general_ref_contains_unitst");
d->isBuildingHolderRefClass
= ClassNameCheck("general_ref_building_holderst");
d->isTriggeredByRefClass = ClassNameCheck("general_ref_building_triggerst");
d->isTriggerTargetRefClass
= ClassNameCheck("general_ref_building_triggertargetst");
d->isEntityOwnerRefClass = ClassNameCheck("general_ref_entity_itemownerst");
d->isOfferedRefClass = ClassNameCheck("general_ref_entity_offeredst");
d->isTradingRefClass = ClassNameCheck("general_ref_unit_tradebringerst");
d->isProjectileRefClass = ClassNameCheck("general_ref_projectilest");
std::vector<std::string> known_names;
ClassNameCheck::getKnownClassNames(known_names);
for (size_t i = 0; i < known_names.size(); i++)
{
if (known_names[i].find("general_ref_") == 0)
d->knownItemRefTypes.insert(known_names[i]);
}
}
bool Items::Start()
{
d->idLookupTable.clear();
return true;
}
bool Items::Finish()
{
return true;
}
bool Items::readItemVector(std::vector<df_item *> &items)
{
std::vector <df_item *> *p_items = (std::vector <df_item *> *) d->itemVectorAddress;
d->idLookupTable.clear();
items.resize(p_items->size());
for (unsigned i = 0; i < p_items->size(); i++)
{
df_item * ptr = p_items->at(i);
items[i] = ptr;
d->idLookupTable[ptr->id] = ptr;
}
return true;
}
df_item * Items::findItemByID(int32_t id)
df::item * Items::findItemByID(int32_t id)
{
if (id < 0)
return 0;
if (d->idLookupTable.empty())
{
std::vector<df_item *> tmp;
readItemVector(tmp);
}
return d->idLookupTable[id];
}
Items::~Items()
{
Finish();
delete d;
return df::item::find(id);
}
bool Items::copyItem(df_item * itembase, DFHack::dfh_item &item)
bool Items::copyItem(df::item * itembase, DFHack::dfh_item &item)
{
if(!itembase)
return false;
df_item * itreal = (df_item *) itembase;
df::item * itreal = (df::item *) itembase;
item.origin = itembase;
item.x = itreal->x;
item.y = itreal->y;
@ -557,87 +425,72 @@ bool Items::copyItem(df_item * itembase, DFHack::dfh_item &item)
return true;
}
int32_t Items::getItemOwnerID(const DFHack::df_item * item)
int32_t Items::getItemOwnerID(const df::item * item)
{
std::vector<int32_t> vals;
if (readItemRefs(item, d->isOwnerRefClass, vals))
return vals[0];
else
return -1;
for (uint32_t i = 0; i < item->itemrefs.size(); i++)
{
df::general_ref *ref = item->itemrefs[i];
if (ref->getType() == df::general_ref_type::UNIT_ITEMOWNER)
return ref->getID();
}
return -1;
}
int32_t Items::getItemContainerID(const DFHack::df_item * item)
int32_t Items::getItemContainerID(const df::item * item)
{
std::vector<int32_t> vals;
if (readItemRefs(item, d->isContainerRefClass, vals))
return vals[0];
else
return -1;
for (uint32_t i = 0; i < item->itemrefs.size(); i++)
{
df::general_ref *ref = item->itemrefs[i];
if (ref->getType() == df::general_ref_type::CONTAINED_IN_ITEM)
return ref->getID();
}
return -1;
}
bool Items::getContainedItems(const DFHack::df_item * item, std::vector<int32_t> &items)
bool Items::getContainedItems(const df::item * item, std::vector<int32_t> &items)
{
return readItemRefs(item, d->isContainsRefClass, items);
return readItemRefs(item, df::general_ref_type::CONTAINS_ITEM, items);
}
bool Items::readItemRefs(const df_item * item, const ClassNameCheck &classname, std::vector<int32_t> &values)
bool Items::readItemRefs(const df::item * item, df::general_ref_type type, std::vector<int32_t> &values)
{
const std::vector <t_itemref *> &p_refs = item->itemrefs;
values.clear();
for (uint32_t i=0; i<p_refs.size(); i++)
for (uint32_t i = 0; i < item->itemrefs.size(); i++)
{
if (classname(d->owner, p_refs[i]->vptr))
values.push_back(int32_t(p_refs[i]->value));
df::general_ref *ref = item->itemrefs[i];
if (ref->getType() == type)
values.push_back(ref->getID());
}
return !values.empty();
}
bool Items::unknownRefs(const df_item * item, std::vector<std::pair<std::string, int32_t> >& refs)
{
refs.clear();
const std::vector <t_itemref *> &p_refs = item->itemrefs;
for (uint32_t i=0; i<p_refs.size(); i++)
{
std::string name = p_refs[i]->getClassName();
if (d->knownItemRefTypes.find(name) == d->knownItemRefTypes.end())
{
refs.push_back(pair<string, int32_t>(name, p_refs[i]->value));
}
}
return (refs.size() > 0);
}
bool Items::removeItemOwner(df_item * item, Units *creatures)
bool Items::removeItemOwner(df::item * item, Units *creatures)
{
std::vector <t_itemref *> &p_refs = item->itemrefs;
for (uint32_t i=0; i<p_refs.size(); i++)
for (uint32_t i = 0; i < item->itemrefs.size(); i++)
{
if (!d->isOwnerRefClass(d->owner, p_refs[i]->vptr))
df::general_ref *ref = item->itemrefs[i];
if (ref->getType() != df::general_ref_type::UNIT_ITEMOWNER)
continue;
int32_t & oid = p_refs[i]->value;
int32_t ix = creatures->FindIndexById(oid);
df_unit *unit = (df_unit *)ref->getUnit();
if (ix < 0 || !creatures->RemoveOwnedItemByIdx(ix, item->id))
if (unit == NULL || !creatures->RemoveOwnedItemByPtr(unit, item->id))
{
cerr << "RemoveOwnedItemIdx: CREATURE " << ix << " ID " << item->id << " FAILED!" << endl;
cerr << "RemoveOwnedItemIdx: CREATURE " << ref->getID() << " ID " << item->id << " FAILED!" << endl;
return false;
}
p_refs.erase(p_refs.begin() + i--);
delete ref;
item->itemrefs.erase(item->itemrefs.begin() + i--);
}
item->flags.owned = 0;
item->flags.bits.owned = 0;
return true;
}
std::string Items::getItemClass(const df_item * item)
std::string Items::getItemClass(const df::item * item)
{
const t_virtual * virt = (t_virtual *) item;
return virt->getClassName();

@ -549,7 +549,7 @@ bool Creatures::ReadJob(const t_creature * furball, vector<t_material> & mat)
return true;
}
*/
bool Units::ReadInventoryByIdx(const uint32_t index, std::vector<df_item *> & item)
bool Units::ReadInventoryByIdx(const uint32_t index, std::vector<df::item *> & item)
{
if(!d->Started) return false;
if(index >= creatures->size()) return false;
@ -557,7 +557,7 @@ bool Units::ReadInventoryByIdx(const uint32_t index, std::vector<df_item *> & it
return this->ReadInventoryByPtr(temp, item);
}
bool Units::ReadInventoryByPtr(const df_unit * temp, std::vector<df_item *> & items)
bool Units::ReadInventoryByPtr(const df_unit * temp, std::vector<df::item *> & items)
{
if(!d->Started) return false;
items = temp->inventory;

@ -9,225 +9,191 @@
#include <set>
using namespace std;
#include "Types.h"
#include "VersionInfo.h"
#include "MemAccess.h"
#include "modules/Materials.h"
#include "modules/Items.h"
#include "modules/Units.h"
#include "Types.h"
#include "Error.h"
#include "modules/kitchen.h"
#include "ModuleFactory.h"
#include "Core.h"
#include "Virtual.h"
using namespace DFHack;
using namespace DFHack::Simple;
namespace DFHack
{
namespace Kitchen
{
class Exclusions::Private
{
public:
Private (DFHack::Core& core_)
: core(core_)
, itemTypes (*((std::vector<t_itemType >*)(addr(core_,0))))
, itemSubtypes (*((std::vector<t_itemSubtype >*)(addr(core_,1))))
, materialTypes (*((std::vector<t_materialType >*)(addr(core_,2))))
, materialIndices (*((std::vector<t_materialIndex>*)(addr(core_,3))))
, exclusionTypes (*((std::vector<t_exclusionType>*)(addr(core_,4))))
{
};
DFHack::Core& core;
std::vector<t_itemType>& itemTypes; // the item types vector of the kitchen exclusion list
std::vector<t_itemSubtype>& itemSubtypes; // the item subtype vector of the kitchen exclusion list
std::vector<t_materialType>& materialTypes; // the material subindex vector of the kitchen exclusion list
std::vector<t_materialIndex>& materialIndices; // the material index vector of the kitchen exclusion list
std::vector<t_exclusionType>& exclusionTypes; // the exclusion type vector of the kitchen excluions list
#include "DataDefs.h"
#include "df/world.h"
#include "df/ui.h"
#include "df/item_type.h"
#include "df/plant_raw.h"
static void * addr(const DFHack::Core& core, int index)
{
static char * start = core.vinfo->getAddress("kitchen_limits");
return start + sizeof(std::vector<int>) * index;
};
};
using namespace df::enums;
using df::global::world;
using df::global::ui;
Exclusions::Exclusions(Core & c)
void Kitchen::debug_print(Core &core)
{
core.con.print("Kitchen Exclusions\n");
for(std::size_t i = 0; i < size(); ++i)
{
d = new Private(c);
};
core.con.print("%2u: IT:%2i IS:%i MT:%3i MI:%2i ET:%i %s\n",
i,
ui->kitchen.item_types[i],
ui->kitchen.item_subtypes[i],
ui->kitchen.mat_types[i],
ui->kitchen.mat_indices[i],
ui->kitchen.exc_types[i],
(ui->kitchen.mat_types[i] >= 419 && ui->kitchen.mat_types[i] <= 618) ? world->raws.plants.all[ui->kitchen.mat_indices[i]]->id.c_str() : "n/a"
);
}
core.con.print("\n");
}
Exclusions::~Exclusions()
void Kitchen::allowPlantSeedCookery(t_materialIndex materialIndex)
{
bool match = false;
do
{
delete d;
};
match = false;
std::size_t matchIndex = 0;
for(std::size_t i = 0; i < size(); ++i)
{
if(ui->kitchen.mat_indices[i] == materialIndex
&& (ui->kitchen.item_types[i] == df::item_type::SEEDS || ui->kitchen.item_types[i] == df::item_type::PLANT)
&& ui->kitchen.exc_types[i] == cookingExclusion
)
{
match = true;
matchIndex = i;
}
}
if(match)
{
ui->kitchen.item_types.erase(ui->kitchen.item_types.begin() + matchIndex);
ui->kitchen.item_subtypes.erase(ui->kitchen.item_subtypes.begin() + matchIndex);
ui->kitchen.mat_indices.erase(ui->kitchen.mat_indices.begin() + matchIndex);
ui->kitchen.mat_types.erase(ui->kitchen.mat_types.begin() + matchIndex);
ui->kitchen.exc_types.erase(ui->kitchen.exc_types.begin() + matchIndex);
}
} while(match);
};
void Exclusions::debug_print() const
void Kitchen::denyPlantSeedCookery(t_materialIndex materialIndex)
{
df::plant_raw *type = world->raws.plants.all[materialIndex];
bool SeedAlreadyIn = false;
bool PlantAlreadyIn = false;
for(std::size_t i = 0; i < size(); ++i)
{
d->core.con.print("Kitchen Exclusions\n");
Materials& materialsModule= *d->core.getMaterials();
for(std::size_t i = 0; i < size(); ++i)
if(ui->kitchen.mat_indices[i] == materialIndex
&& ui->kitchen.exc_types[i] == cookingExclusion)
{
d->core.con.print("%2u: IT:%2i IS:%i MT:%3i MI:%2i ET:%i %s\n",
i,
d->itemTypes[i],
d->itemSubtypes[i],
d->materialTypes[i],
d->materialIndices[i],
d->exclusionTypes[i],
materialsModule.df_organic->at(d->materialIndices[i])->ID.c_str()
);
if(ui->kitchen.item_types[i] == df::item_type::SEEDS)
SeedAlreadyIn = true;
else if (ui->kitchen.item_types[i] == df::item_type::PLANT)
PlantAlreadyIn = true;
}
d->core.con.print("\n");
}
if(!SeedAlreadyIn)
{
ui->kitchen.item_types.push_back(df::item_type::SEEDS);
ui->kitchen.item_subtypes.push_back(organicSubtype);
ui->kitchen.mat_types.push_back(type->material_defs.type_seed);
ui->kitchen.mat_indices.push_back(materialIndex);
ui->kitchen.exc_types.push_back(cookingExclusion);
}
if(!PlantAlreadyIn)
{
ui->kitchen.item_types.push_back(df::item_type::PLANT);
ui->kitchen.item_subtypes.push_back(organicSubtype);
ui->kitchen.mat_types.push_back(type->material_defs.type_basic_mat);
ui->kitchen.mat_indices.push_back(materialIndex);
ui->kitchen.exc_types.push_back(cookingExclusion);
}
};
void Exclusions::allowPlantSeedCookery(t_materialIndex materialIndex)
void Kitchen::fillWatchMap(std::map<t_materialIndex, unsigned int>& watchMap)
{
watchMap.clear();
for(std::size_t i = 0; i < size(); ++i)
{
bool match = false;
do
if(ui->kitchen.item_subtypes[i] == limitType && ui->kitchen.item_subtypes[i] == limitSubtype && ui->kitchen.exc_types[i] == limitExclusion)
{
match = false;
std::size_t matchIndex = 0;
for(std::size_t i = 0; i < size(); ++i)
{
if(d->materialIndices[i] == materialIndex
&& (d->itemTypes[i] == DFHack::Items::SEEDS || d->itemTypes[i] == DFHack::Items::PLANT)
&& d->exclusionTypes[i] == cookingExclusion
)
{
match = true;
matchIndex = i;
}
}
if(match)
{
d->itemTypes.erase(d->itemTypes.begin() + matchIndex);
d->itemSubtypes.erase(d->itemSubtypes.begin() + matchIndex);
d->materialIndices.erase(d->materialIndices.begin() + matchIndex);
d->materialTypes.erase(d->materialTypes.begin() + matchIndex);
d->exclusionTypes.erase(d->exclusionTypes.begin() + matchIndex);
}
} while(match);
};
watchMap[ui->kitchen.mat_indices[i]] = (unsigned int) ui->kitchen.mat_types[i];
}
}
};
void Exclusions::denyPlantSeedCookery(t_materialIndex materialIndex)
void Kitchen::removeLimit(t_materialIndex materialIndex)
{
bool match = false;
do
{
Materials *mats = d->core.getMaterials();
df_plant_type *type = mats->df_organic->at(materialIndex);
bool SeedAlreadyIn = false;
bool PlantAlreadyIn = false;
match = false;
std::size_t matchIndex = 0;
for(std::size_t i = 0; i < size(); ++i)
{
if(d->materialIndices[i] == materialIndex
&& d->exclusionTypes[i] == cookingExclusion)
if(ui->kitchen.item_types[i] == limitType
&& ui->kitchen.item_subtypes[i] == limitSubtype
&& ui->kitchen.mat_indices[i] == materialIndex
&& ui->kitchen.exc_types[i] == limitExclusion)
{
if(d->itemTypes[i] == DFHack::Items::SEEDS)
SeedAlreadyIn = true;
else if (d->itemTypes[i] == DFHack::Items::PLANT)
PlantAlreadyIn = true;
match = true;
matchIndex = i;
}
}
if(!SeedAlreadyIn)
if(match)
{
d->itemTypes.push_back(DFHack::Items::SEEDS);
d->itemSubtypes.push_back(organicSubtype);
d->materialTypes.push_back(type->material_type_seed);
d->materialIndices.push_back(materialIndex);
d->exclusionTypes.push_back(cookingExclusion);
ui->kitchen.item_types.erase(ui->kitchen.item_types.begin() + matchIndex);
ui->kitchen.item_subtypes.erase(ui->kitchen.item_subtypes.begin() + matchIndex);
ui->kitchen.mat_types.erase(ui->kitchen.mat_types.begin() + matchIndex);
ui->kitchen.mat_indices.erase(ui->kitchen.mat_indices.begin() + matchIndex);
ui->kitchen.exc_types.erase(ui->kitchen.exc_types.begin() + matchIndex);
}
if(!PlantAlreadyIn)
{
d->itemTypes.push_back(DFHack::Items::PLANT);
d->itemSubtypes.push_back(organicSubtype);
d->materialTypes.push_back(type->material_type_basic_mat);
d->materialIndices.push_back(materialIndex);
d->exclusionTypes.push_back(cookingExclusion);
}
};
} while(match);
};
void Exclusions::fillWatchMap(std::map<t_materialIndex, unsigned int>& watchMap) const
void Kitchen::setLimit(t_materialIndex materialIndex, unsigned int limit)
{
removeLimit(materialIndex);
if(limit > seedLimit)
{
watchMap.clear();
for(std::size_t i = 0; i < size(); ++i)
{
if(d->itemTypes[i] == limitType && d->itemSubtypes[i] == limitSubtype && d->exclusionTypes[i] == limitExclusion)
{
watchMap[d->materialIndices[i]] = (unsigned int) d->materialTypes[i];
}
}
};
limit = seedLimit;
}
ui->kitchen.item_types.push_back(limitType);
ui->kitchen.item_subtypes.push_back(limitSubtype);
ui->kitchen.mat_indices.push_back(materialIndex);
ui->kitchen.mat_types.push_back((t_materialType) (limit < seedLimit) ? limit : seedLimit);
ui->kitchen.exc_types.push_back(limitExclusion);
};
void Exclusions::removeLimit(t_materialIndex materialIndex)
void Kitchen::clearLimits()
{
bool match = false;
do
{
bool match = false;
do
match = false;
std::size_t matchIndex;
for(std::size_t i = 0; i < size(); ++i)
{
match = false;
std::size_t matchIndex = 0;
for(std::size_t i = 0; i < size(); ++i)
if(ui->kitchen.item_types[i] == limitType
&& ui->kitchen.item_subtypes[i] == limitSubtype
&& ui->kitchen.exc_types[i] == limitExclusion)
{
if(d->itemTypes[i] == limitType
&& d->itemSubtypes[i] == limitSubtype
&& d->materialIndices[i] == materialIndex
&& d->exclusionTypes[i] == limitExclusion)
{
match = true;
matchIndex = i;
}
match = true;
matchIndex = i;
}
if(match)
{
d->itemTypes.erase(d->itemTypes.begin() + matchIndex);
d->itemSubtypes.erase(d->itemSubtypes.begin() + matchIndex);
d->materialTypes.erase(d->materialTypes.begin() + matchIndex);
d->materialIndices.erase(d->materialIndices.begin() + matchIndex);
d->exclusionTypes.erase(d->exclusionTypes.begin() + matchIndex);
}
} while(match);
};
void Exclusions::setLimit(t_materialIndex materialIndex, unsigned int limit)
{
removeLimit(materialIndex);
if(limit > seedLimit)
}
if(match)
{
limit = seedLimit;
ui->kitchen.item_types.erase(ui->kitchen.item_types.begin() + matchIndex);
ui->kitchen.item_subtypes.erase(ui->kitchen.item_subtypes.begin() + matchIndex);
ui->kitchen.mat_indices.erase(ui->kitchen.mat_indices.begin() + matchIndex);
ui->kitchen.mat_types.erase(ui->kitchen.mat_types.begin() + matchIndex);
ui->kitchen.exc_types.erase(ui->kitchen.exc_types.begin() + matchIndex);
}
d->itemTypes.push_back(limitType);
d->itemSubtypes.push_back(limitSubtype);
d->materialIndices.push_back(materialIndex);
d->materialTypes.push_back((t_materialType) (limit < seedLimit) ? limit : seedLimit);
d->exclusionTypes.push_back(limitExclusion);
};
} while(match);
};
void Exclusions::clearLimits()
{
bool match = false;
do
{
match = false;
std::size_t matchIndex;
for(std::size_t i = 0; i < size(); ++i)
{
if(d->itemTypes[i] == limitType
&& d->itemSubtypes[i] == limitSubtype
&& d->exclusionTypes[i] == limitExclusion)
{
match = true;
matchIndex = i;
}
}
if(match)
{
d->itemTypes.erase(d->itemTypes.begin() + matchIndex);
d->itemSubtypes.erase(d->itemSubtypes.begin() + matchIndex);
d->materialIndices.erase(d->materialIndices.begin() + matchIndex);
d->materialTypes.erase(d->materialTypes.begin() + matchIndex);
d->exclusionTypes.erase(d->exclusionTypes.begin() + matchIndex);
}
} while(match);
};
size_t Exclusions::size() const
{
return d->itemTypes.size();
};
}
};
size_t Kitchen::size()
{
return ui->kitchen.item_types.size();
};

@ -28,6 +28,7 @@ using namespace std;
using namespace DFHack;
using MapExtras::Block;
using MapExtras::MapCache;
using df::global::world;
DFhackCExport command_result df_autodump(Core * c, vector <string> & parameters);
DFhackCExport command_result df_autodump_destroy_here(Core * c, vector <string> & parameters);
@ -95,16 +96,9 @@ static command_result autodump_main(Core * c, vector <string> & parameters)
DFHack::VersionInfo *mem = c->vinfo;
DFHack::Gui * Gui = c->getGui();
DFHack::Items * Items = c->getItems();
DFHack::Maps *Maps = c->getMaps();
vector <df_item*> p_items;
if(!Items->readItemVector(p_items))
{
c->con.printerr("Can't access the item vector.\n");
return CR_FAILURE;
}
std::size_t numItems = p_items.size();
std::size_t numItems = world->items.all.size();
// init the map
if(!Maps->Start())
@ -148,7 +142,7 @@ static command_result autodump_main(Core * c, vector <string> & parameters)
// proceed with the dumpification operation
for(std::size_t i=0; i< numItems; i++)
{
df_item * itm = p_items[i];
df::item * itm = world->items.all[i];
DFCoord pos_item(itm->x, itm->y, itm->z);
// keep track how many items are at places. all items.
@ -165,22 +159,22 @@ static command_result autodump_main(Core * c, vector <string> & parameters)
// iterator is valid here, we use it later to decrement the pile counter if the item is moved
// only dump the stuff marked for dumping and laying on the ground
if ( !itm->flags.dump
|| !itm->flags.on_ground
|| itm->flags.construction
|| itm->flags.hidden
|| itm->flags.in_building
|| itm->flags.in_chest
|| itm->flags.in_inventory
|| itm->flags.artifact1
if ( !itm->flags.bits.dump
|| !itm->flags.bits.on_ground
|| itm->flags.bits.construction
|| itm->flags.bits.hidden
|| itm->flags.bits.in_building
|| itm->flags.bits.in_chest
|| itm->flags.bits.in_inventory
|| itm->flags.bits.artifact1
)
continue;
if(!destroy) // move to cursor
{
// Change flags to indicate the dump was completed, as if by super-dwarfs
itm->flags.dump = false;
itm->flags.forbid = true;
itm->flags.bits.dump = false;
itm->flags.bits.forbid = true;
// Don't move items if they're already at the cursor
if (pos_cursor == pos_item)
@ -221,11 +215,11 @@ static command_result autodump_main(Core * c, vector <string> & parameters)
if (here && pos_item != pos_cursor)
continue;
itm->flags.garbage_colect = true;
itm->flags.bits.garbage_colect = true;
// Cosmetic changes: make them disappear from view instantly
itm->flags.forbid = true;
itm->flags.hidden = true;
itm->flags.bits.forbid = true;
itm->flags.bits.hidden = true;
}
// keeping track of item pile sizes ;)
it->second --;
@ -336,7 +330,7 @@ DFhackCExport command_result df_autodump_destroy_item(Core * c, vector <string>
for (unsigned i = 0; i < item->itemrefs.size(); i++)
{
df::general_ref *ref = item->itemrefs[i];
if (ref->getType() == df::general_ref_type::unit_holder)
if (ref->getType() == df::general_ref_type::UNIT_HOLDER)
{
c->con.printerr("Choosing not to destroy items in unit inventory.\n");
return CR_FAILURE;

@ -20,6 +20,11 @@ using namespace std;
#include "modules/Materials.h"
#include "modules/Translation.h"
using namespace DFHack;
using namespace DFHack::Simple;
#include "DataDefs.h"
#include "df/world.h"
using df::global::world;
DFhackCExport command_result df_cleanowned (Core * c, vector <string> & parameters);
@ -89,7 +94,6 @@ DFhackCExport command_result df_cleanowned (Core * c, vector <string> & paramete
}
c->Suspend();
DFHack::Materials *Materials = c->getMaterials();
DFHack::Items *Items = c->getItems();
DFHack::Units *Creatures = c->getUnits();
DFHack::Translation *Tran = c->getTranslation();
@ -99,25 +103,17 @@ DFhackCExport command_result df_cleanowned (Core * c, vector <string> & paramete
ok &= Creatures->Start(num_creatures);
ok &= Tran->Start();
vector<df_item *> p_items;
ok &= Items->readItemVector(p_items);
if(!ok)
{
c->con.printerr("Can't continue due to offset errors.\n");
c->Resume();
return CR_FAILURE;
}
c->con.print("Found total %d items.\n", p_items.size());
c->con.print("Found total %d items.\n", world->items.all.size());
for (std::size_t i=0; i < p_items.size(); i++)
for (std::size_t i=0; i < world->items.all.size(); i++)
{
df_item * item = p_items[i];
df::item * item = world->items.all[i];
bool confiscate = false;
bool dump = false;
if (!item->flags.owned)
if (!item->flags.bits.owned)
{
int32_t owner = Items->getItemOwnerID(item);
int32_t owner = Items::getItemOwnerID(item);
if (owner >= 0)
{
c->con.print("Fixing a misflagged item: \t");
@ -129,23 +125,21 @@ DFhackCExport command_result df_cleanowned (Core * c, vector <string> & paramete
}
}
std::string name = Items->getItemClass(item);
if (item->flags.rotten)
if (item->flags.bits.rotten)
{
c->con.print("Confiscating a rotten item: \t");
confiscate = true;
}
else if (item->flags.on_ground)
else if (item->flags.bits.on_ground)
{
int32_t type = item->getType();
if(type == Items::MEAT ||
type == Items::FISH ||
type == Items::VERMIN ||
type == Items::PET ||
type == Items::PLANT ||
type == Items::CHEESE ||
type == Items::FOOD
if(type == df::item_type::MEAT ||
type == df::item_type::FISH ||
type == df::item_type::VERMIN ||
type == df::item_type::PET ||
type == df::item_type::PLANT ||
type == df::item_type::CHEESE ||
type == df::item_type::FOOD
)
{
confiscate = true;
@ -189,7 +183,7 @@ DFhackCExport command_result df_cleanowned (Core * c, vector <string> & paramete
item->getWear()
);
int32_t owner = Items->getItemOwnerID(item);
int32_t owner = Items::getItemOwnerID(item);
int32_t owner_index = Creatures->FindIndexById(owner);
std::string info;
@ -206,10 +200,10 @@ DFhackCExport command_result df_cleanowned (Core * c, vector <string> & paramete
if (!dry_run)
{
if (!Items->removeItemOwner(item, Creatures))
if (!Items::removeItemOwner(item, Creatures))
c->con.print("(unsuccessfully) ");
if (dump)
item->flags.dump = 1;
item->flags.bits.dump = 1;
}
c->con.print("\n");
}

@ -8,14 +8,17 @@
#include "Core.h"
#include "Export.h"
#include "PluginManager.h"
#include "modules/Materials.h"
#include "modules/Items.h"
#include "modules/World.h"
#include "modules/kitchen.h"
#include "VersionInfo.h"
#include "df/world.h"
#include "df/plant_raw.h"
#include "df/item_flags.h"
using DFHack::t_materialType;
using DFHack::t_materialIndex;
using namespace DFHack;
using namespace DFHack::Simple;
using df::global::world;
const int buffer = 20; // seed number buffer - 20 is reasonable
bool running = false; // whether seedwatch is counting the seeds or not
@ -23,22 +26,22 @@ bool running = false; // whether seedwatch is counting the seeds or not
// abbreviations for the standard plants
std::map<std::string, std::string> abbreviations;
bool ignoreSeeds(DFHack::t_itemflags& f) // seeds with the following flags should not be counted
bool ignoreSeeds(df::item_flags& f) // seeds with the following flags should not be counted
{
return
f.dump ||
f.forbid ||
f.garbage_colect ||
f.hidden ||
f.hostile ||
f.on_fire ||
f.rotten ||
f.trader ||
f.in_building ||
f.in_job;
f.bits.dump ||
f.bits.forbid ||
f.bits.garbage_colect ||
f.bits.hidden ||
f.bits.hostile ||
f.bits.on_fire ||
f.bits.rotten ||
f.bits.trader ||
f.bits.in_building ||
f.bits.in_job;
};
void printHelp(DFHack::Core& core) // prints help
void printHelp(Core& core) // prints help
{
core.con.print(
"Watches the numbers of seeds available and enables/disables seed and plant cooking.\n"
@ -92,36 +95,32 @@ std::string searchAbbreviations(std::string in)
}
};
DFhackCExport DFHack::command_result df_seedwatch(DFHack::Core* pCore, std::vector<std::string>& parameters)
DFhackCExport command_result df_seedwatch(Core* pCore, std::vector<std::string>& parameters)
{
DFHack::Core& core = *pCore;
Core& core = *pCore;
if(!core.isValid())
{
return DFHack::CR_FAILURE;
return CR_FAILURE;
}
core.Suspend();
DFHack::Materials& materialsModule = *core.getMaterials();
std::vector<DFHack::t_matgloss> organics;
materialsModule.CopyOrganicMaterials(organics);
std::map<std::string, t_materialIndex> materialsReverser;
for(std::size_t i = 0; i < organics.size(); ++i)
for(std::size_t i = 0; i < world->raws.plants.all.size(); ++i)
{
materialsReverser[organics[i].id] = i;
materialsReverser[world->raws.plants.all[i]->id] = i;
}
DFHack::World *w = core.getWorld();
DFHack::t_gamemodes gm;
World *w = core.getWorld();
t_gamemodes gm;
w->ReadGameMode(gm);// FIXME: check return value
// if game mode isn't fortress mode
if(gm.g_mode != DFHack::GAMEMODE_DWARF || gm.g_type != DFHack::GAMETYPE_DWARF_MAIN)
if(gm.g_mode != GAMEMODE_DWARF || gm.g_type != GAMETYPE_DWARF_MAIN)
{
// just print the help
printHelp(core);
core.Resume();
return DFHack::CR_OK;
return CR_OK;
}
std::string par;
@ -147,8 +146,7 @@ DFhackCExport DFHack::command_result df_seedwatch(DFHack::Core* pCore, std::vect
}
else if(par == "clear")
{
DFHack::Kitchen::Exclusions kitchenExclusions(core);
kitchenExclusions.clearLimits();
Kitchen::clearLimits();
core.con.print("seedwatch watchlist cleared\n");
}
else if(par == "info")
@ -162,9 +160,8 @@ DFhackCExport DFHack::command_result df_seedwatch(DFHack::Core* pCore, std::vect
{
core.con.print("seedwatch is not supervising. Use 'seedwatch start' to start supervision.\n");
}
DFHack::Kitchen::Exclusions kitchenExclusions(core);
std::map<t_materialIndex, unsigned int> watchMap;
kitchenExclusions.fillWatchMap(watchMap);
Kitchen::fillWatchMap(watchMap);
if(watchMap.empty())
{
core.con.print("The watch list is empty.\n");
@ -174,16 +171,15 @@ DFhackCExport DFHack::command_result df_seedwatch(DFHack::Core* pCore, std::vect
core.con.print("The watch list is:\n");
for(std::map<t_materialIndex, unsigned int>::const_iterator i = watchMap.begin(); i != watchMap.end(); ++i)
{
core.con.print("%s : %u\n", organics[i->first].id.c_str(), i->second);
core.con.print("%s : %u\n", world->raws.plants.all[i->first]->id.c_str(), i->second);
}
}
}
else if(par == "debug")
{
DFHack::Kitchen::Exclusions kitchenExclusions(core);
std::map<t_materialIndex, unsigned int> watchMap;
kitchenExclusions.fillWatchMap(watchMap);
kitchenExclusions.debug_print();
Kitchen::fillWatchMap(watchMap);
Kitchen::debug_print(core);
}
/*
else if(par == "dumpmaps")
@ -208,8 +204,7 @@ DFhackCExport DFHack::command_result df_seedwatch(DFHack::Core* pCore, std::vect
std::string token = searchAbbreviations(par);
if(materialsReverser.count(token) > 0)
{
DFHack::Kitchen::Exclusions kitchenExclusions(core);
kitchenExclusions.removeLimit(materialsReverser[token]);
Kitchen::removeLimit(materialsReverser[token]);
core.con.print("%s is not being watched\n", token.c_str());
}
else
@ -225,8 +220,7 @@ DFhackCExport DFHack::command_result df_seedwatch(DFHack::Core* pCore, std::vect
{
for(std::map<std::string, std::string>::const_iterator i = abbreviations.begin(); i != abbreviations.end(); ++i)
{
DFHack::Kitchen::Exclusions kitchenExclusions(core);
if(materialsReverser.count(i->second) > 0) kitchenExclusions.setLimit(materialsReverser[i->second], limit);
if(materialsReverser.count(i->second) > 0) Kitchen::setLimit(materialsReverser[i->second], limit);
}
}
else
@ -234,8 +228,7 @@ DFhackCExport DFHack::command_result df_seedwatch(DFHack::Core* pCore, std::vect
std::string token = searchAbbreviations(parameters[0]);
if(materialsReverser.count(token) > 0)
{
DFHack::Kitchen::Exclusions kitchenExclusions(core);
kitchenExclusions.setLimit(materialsReverser[token], limit);
Kitchen::setLimit(materialsReverser[token], limit);
core.con.print("%s is being watched.\n", token.c_str());
}
else
@ -250,7 +243,7 @@ DFhackCExport DFHack::command_result df_seedwatch(DFHack::Core* pCore, std::vect
}
core.Resume();
return DFHack::CR_OK;
return CR_OK;
}
DFhackCExport const char* plugin_name(void)
@ -258,10 +251,10 @@ DFhackCExport const char* plugin_name(void)
return "seedwatch";
}
DFhackCExport DFHack::command_result plugin_init(DFHack::Core* pCore, std::vector<DFHack::PluginCommand>& commands)
DFhackCExport command_result plugin_init(Core* pCore, std::vector<PluginCommand>& commands)
{
commands.clear();
commands.push_back(DFHack::PluginCommand("seedwatch", "Switches cookery based on quantity of seeds, to keep reserves", df_seedwatch));
commands.push_back(PluginCommand("seedwatch", "Switches cookery based on quantity of seeds, to keep reserves", df_seedwatch));
// fill in the abbreviations map, with abbreviations for the standard plants
abbreviations["bs"] = "SLIVER_BARB";
abbreviations["bt"] = "TUBER_BLOATED";
@ -284,14 +277,14 @@ DFhackCExport DFHack::command_result plugin_init(DFHack::Core* pCore, std::vecto
abbreviations["vh"] = "HERB_VALLEY";
abbreviations["ws"] = "BERRIES_STRAW_WILD";
abbreviations["wv"] = "VINE_WHIP";
return DFHack::CR_OK;
return CR_OK;
}
DFhackCExport DFHack::command_result plugin_onstatechange(DFHack::Core* pCore, DFHack::state_change_event event)
DFhackCExport command_result plugin_onstatechange(Core* pCore, state_change_event event)
{
switch (event) {
case DFHack::SC_GAME_LOADED:
case DFHack::SC_GAME_UNLOADED:
case SC_GAME_LOADED:
case SC_GAME_UNLOADED:
if (running)
pCore->con.printerr("seedwatch deactivated due to game load/unload\n");
running = false;
@ -300,73 +293,67 @@ DFhackCExport DFHack::command_result plugin_onstatechange(DFHack::Core* pCore, D
break;
}
return DFHack::CR_OK;
return CR_OK;
}
DFhackCExport DFHack::command_result plugin_onupdate(DFHack::Core* pCore)
DFhackCExport command_result plugin_onupdate(Core* pCore)
{
if (running)
{
// reduce processing rate
static int counter = 0;
if (++counter < 500)
return DFHack::CR_OK;
return CR_OK;
counter = 0;
DFHack::Core& core = *pCore;
DFHack::World *w = core.getWorld();
DFHack::t_gamemodes gm;
Core& core = *pCore;
World *w = core.getWorld();
t_gamemodes gm;
w->ReadGameMode(gm);// FIXME: check return value
// if game mode isn't fortress mode
if(gm.g_mode != DFHack::GAMEMODE_DWARF || gm.g_type != DFHack::GAMETYPE_DWARF_MAIN)
if(gm.g_mode != GAMEMODE_DWARF || gm.g_type != GAMETYPE_DWARF_MAIN)
{
// stop running.
running = false;
core.con.printerr("seedwatch deactivated due to game mode switch\n");
return DFHack::CR_OK;
return CR_OK;
}
// this is dwarf mode, continue
std::map<t_materialIndex, unsigned int> seedCount; // the number of seeds
DFHack::Items& itemsModule = *core.getItems();
itemsModule.Start();
std::vector<DFHack::df_item*> items;
itemsModule.readItemVector(items);
DFHack::df_item * item;
// count all seeds and plants by RAW material
for(std::size_t i = 0; i < items.size(); ++i)
for(std::size_t i = 0; i < world->items.all.size(); ++i)
{
item = items[i];
df::item * item = world->items.all[i];
t_materialIndex materialIndex = item->getMaterialIndex();
switch(item->getType())
{
case DFHack::Items::SEEDS:
case df::item_type::SEEDS:
if(!ignoreSeeds(item->flags)) ++seedCount[materialIndex];
break;
case DFHack::Items::PLANT:
case df::item_type::PLANT:
break;
}
}
itemsModule.Finish();
DFHack::Kitchen::Exclusions kitchenExclusions(core);
std::map<t_materialIndex, unsigned int> watchMap;
kitchenExclusions.fillWatchMap(watchMap);
Kitchen::fillWatchMap(watchMap);
for(auto i = watchMap.begin(); i != watchMap.end(); ++i)
{
if(seedCount[i->first] <= i->second)
{
kitchenExclusions.denyPlantSeedCookery(i->first);
Kitchen::denyPlantSeedCookery(i->first);
}
else if(i->second + buffer < seedCount[i->first])
{
kitchenExclusions.allowPlantSeedCookery(i->first);
Kitchen::allowPlantSeedCookery(i->first);
}
}
}
return DFHack::CR_OK;
return CR_OK;
}
DFhackCExport DFHack::command_result plugin_shutdown(DFHack::Core* pCore)
DFhackCExport command_result plugin_shutdown(Core* pCore)
{
return DFHack::CR_OK;
return CR_OK;
}

@ -984,7 +984,7 @@ static void dryBucket(df::item *item)
for (unsigned i = 0; i < item->itemrefs.size(); i++)
{
df::general_ref *ref = item->itemrefs[i];
if (ref->getType() == df::general_ref_type::contains_item)
if (ref->getType() == df::general_ref_type::CONTAINS_ITEM)
{
df::item *obj = ref->getItem();
@ -1006,20 +1006,20 @@ static bool itemBusy(df::item *item)
for (unsigned i = 0; i < item->itemrefs.size(); i++)
{
df::general_ref *ref = item->itemrefs[i];
if (ref->getType() == df::general_ref_type::contains_item)
if (ref->getType() == df::general_ref_type::CONTAINS_ITEM)
{
df::item *obj = ref->getItem();
if (obj && !obj->flags.bits.garbage_colect)
return true;
}
else if (ref->getType() == df::general_ref_type::contains_unit)
else if (ref->getType() == df::general_ref_type::CONTAINS_UNIT)
return true;
else if (ref->getType() == df::general_ref_type::unit_holder)
else if (ref->getType() == df::general_ref_type::UNIT_HOLDER)
{
if (!item->flags.bits.in_job)
return true;
}
else if (ref->getType() == df::general_ref_type::contained_in_item)
else if (ref->getType() == df::general_ref_type::CONTAINED_IN_ITEM)
{
df::item *obj = ref->getItem();
if (!obj)