Fix seedwatch some more.

develop
Petr Mrázek 2011-10-30 02:52:25 +01:00
parent 13ca2e608f
commit a3a1629521
5 changed files with 381 additions and 282 deletions

@ -758,8 +758,8 @@
<class name="building_hivest" />
</VTable>
<Offsets>
<Address name="WORLD" description="A huge object that many things in DF are part of. Contains the whole game and can be used as a base
for many of the addresses." />
<Address name="WORLD" description="A huge object that many things in DF are part of. Contains the whole game and can be used as a base for many of the addresses." />
<Address name="kitchen_limits" description="five vectors describing plants/items that can't be cooked/brewed" />
<Group name="vector" description="An STL vector.">
<HexValue name="sizeof" description="The total size in bytes." />
<Offset name="start" description="The offset where the actual start/end/alloc_end triplet is." />
@ -2258,6 +2258,7 @@
<PETimeStamp value="0x4D90764F" />
<MD5 value="6ada05fc94785b53efe6aa5728b3756b" />
<Offsets>
<Address name="kitchen_limits" value="0x014F0BB4"/>
<Group name="GUI">
<Address name="hotkeys" value="0x14f5cc8" />
<Address name="interface" value="0x14f6070" />
@ -3071,7 +3072,7 @@
<MD5 value="fc15065c4d1977ca019c6dad220413d1" />
<Offsets>
WORLD: 0x93f77a0
<Address name="kitchen_limits" value="0x93f2b00"/>
<Group name="GUI">
<Address name="hotkeys" value="0x93f740c" />
<Address name="interface" value="0x8C3E900" />

@ -157,10 +157,10 @@ public:
int16_t temperature_fraction;
public:
// 0x0
virtual int32_t getType();
virtual int16_t getSubtype();
virtual int16_t getMaterial();
virtual int32_t getMaterialIndex();
virtual t_itemType getType();
virtual t_itemSubtype getSubtype();
virtual t_materialType getMaterial();
virtual t_materialIndex getMaterialIndex();
// 0x10
/*
hm, [4] looks complicated *
@ -170,13 +170,13 @@ public:
(0.31.25 Windows SDL)
*/
virtual void fn4(void);
virtual void setMaterial(int16_t mat);
virtual void setMaterialIndex (int32_t submat);
virtual void setMaterial(t_materialType mat);
virtual void setMaterialIndex (t_materialIndex submat);
// another one? really?
virtual int16_t getMaterial2();
virtual t_materialType getMaterial2();
// 0x20
// more of the same?
virtual int32_t getMaterialIndex2();
virtual t_materialIndex getMaterialIndex2();
virtual void fn9(void);
virtual void fn10(void);
virtual void fn11(void);

@ -501,16 +501,16 @@ namespace DFHack
std::vector<std::string *> prefstring;
std::vector<df_material *> materials;
// materials and material indexes - only valid when appropriate flags in the BitArray are set
int16_t material_basic_mat;
int16_t material_tree;
int16_t material_drink;
int16_t material_seed;
int16_t material_thread;
int16_t material_mill;
int16_t material_extract_vial;
int16_t material_extract_barrel;
int16_t material_extract_still_vial;
int16_t material_leaves;
int16_t material_type_basic_mat;
int16_t material_type_tree;
int16_t material_type_drink;
int16_t material_type_seed;
int16_t material_type_thread;
int16_t material_type_mill;
int16_t material_type_extract_vial;
int16_t material_type_extract_barrel;
int16_t material_type_extract_still_vial;
int16_t material_type_leaves;
int32_t material_idx_basic_mat;
int32_t material_idx_tree;
int32_t material_idx_drink;
@ -641,16 +641,19 @@ namespace DFHack
} tilecolor;
};
typedef int32_t t_materialIndex;
typedef int16_t t_materialType, t_itemType, t_itemSubtype;
/**
* this structure describes what are things made of in the DF world
* \ingroup grp_materials
*/
struct t_material
{
int16_t itemType;
int16_t subType;
int16_t material;
int32_t index;
t_itemType itemType;
t_itemSubtype subType;
t_materialType material;
t_materialIndex index;
uint32_t flags;
};
/**

@ -0,0 +1,261 @@
/*
https://github.com/peterix/dfhack
Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com)
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#pragma once
/*
* kitchen settings
*/
#include "dfhack/Export.h"
#include "dfhack/Module.h"
#include "dfhack/Types.h"
#include "dfhack/VersionInfo.h"
#include "dfhack/modules/Materials.h"
#include "dfhack/modules/Items.h"
#include <dfhack/Core.h>
/**
* \defgroup grp_kitchen Kitchen settings
* @ingroup grp_modules
*/
namespace DFHack
{
namespace Kitchen
{
typedef uint8_t t_exclusionType;
const unsigned int seedLimit = 400; // a limit on the limits which can be placed on seeds
const t_itemSubtype organicSubtype = -1; // seems to fixed
const t_exclusionType cookingExclusion = 1; // seems to be fixed
const t_itemType limitType = 0; // used to store limit as an entry in the exclusion list. 0 = BAR
const t_itemSubtype limitSubtype = 0; // used to store limit as an entry in the exclusion list
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
*/
class Exclusions
{
public:
/// ctor
Exclusions(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))))
{
};
/// print the exclusion list, with the material index also translated into its token (for organics) - for debug really
void debug_print()
{
core.con.print("Kitchen Exclusions\n");
DFHack::Materials& materialsModule= *core.getMaterials();
for(std::size_t i = 0; i < size(); ++i)
{
core.con.print("%2u: IT:%2i IS:%i MT:%3i MI:%2i ET:%i %s\n",
i,
itemTypes[i],
itemSubtypes[i],
materialTypes[i],
materialIndices[i],
exclusionTypes[i],
materialsModule.df_organic->at(materialIndices[i])->ID.c_str()
);
}
core.con.print("\n");
};
/// remove this material from the exclusion list if it is in it
void allowPlantSeedCookery(t_materialIndex materialIndex)
{
bool match = false;
do
{
match = false;
std::size_t matchIndex = 0;
for(std::size_t i = 0; i < size(); ++i)
{
if(materialIndices[i] == materialIndex
&& (itemTypes[i] == DFHack::Items::SEEDS || itemTypes[i] == DFHack::Items::PLANT)
&& exclusionTypes[i] == cookingExclusion
)
{
match = true;
matchIndex = i;
}
}
if(match)
{
itemTypes.erase(itemTypes.begin() + matchIndex);
itemSubtypes.erase(itemSubtypes.begin() + matchIndex);
materialIndices.erase(materialIndices.begin() + matchIndex);
materialTypes.erase( materialTypes.begin() + matchIndex);
exclusionTypes.erase(exclusionTypes.begin() + matchIndex);
}
} while(match);
};
/// add this material to the exclusion list, if it is not already in it
void denyPlantSeedCookery(t_materialIndex materialIndex)
{
Materials *mats = core.getMaterials();
df_plant_type *type = mats->df_organic->at(materialIndex);
bool SeedAlreadyIn = false;
bool PlantAlreadyIn = false;
for(std::size_t i = 0; i < size(); ++i)
{
if(materialIndices[i] == materialIndex
&& exclusionTypes[i] == cookingExclusion)
{
if(itemTypes[i] == DFHack::Items::SEEDS)
SeedAlreadyIn = true;
else if (itemTypes[i] == DFHack::Items::PLANT)
PlantAlreadyIn = true;
}
}
if(!SeedAlreadyIn)
{
itemTypes.push_back(DFHack::Items::SEEDS);
itemSubtypes.push_back(organicSubtype);
materialTypes.push_back(type->material_type_seed);
materialIndices.push_back(materialIndex);
exclusionTypes.push_back(cookingExclusion);
}
if(!PlantAlreadyIn)
{
itemTypes.push_back(DFHack::Items::PLANT);
itemSubtypes.push_back(organicSubtype);
materialTypes.push_back(type->material_type_basic_mat);
materialIndices.push_back(materialIndex);
exclusionTypes.push_back(cookingExclusion);
}
};
/// fills a map with info from the limit info storage entries in the exclusion list
void fillWatchMap(std::map<t_materialIndex, unsigned int>& watchMap)
{
watchMap.clear();
for(std::size_t i = 0; i < size(); ++i)
{
if(itemTypes[i] == limitType && itemSubtypes[i] == limitSubtype && exclusionTypes[i] == limitExclusion)
{
watchMap[materialIndices[i]] = (unsigned int) materialTypes[i];
}
}
};
/// removes a limit info storage entry from the exclusion list if it's present
void removeLimit(t_materialIndex materialIndex)
{
bool match = false;
do
{
match = false;
std::size_t matchIndex = 0;
for(std::size_t i = 0; i < size(); ++i)
{
if(itemTypes[i] == limitType
&& itemSubtypes[i] == limitSubtype
&& materialIndices[i] == materialIndex
&& exclusionTypes[i] == limitExclusion)
{
match = true;
matchIndex = i;
}
}
if(match)
{
itemTypes.erase(itemTypes.begin() + matchIndex);
itemSubtypes.erase(itemSubtypes.begin() + matchIndex);
materialTypes.erase( materialTypes.begin() + matchIndex);
materialIndices.erase(materialIndices.begin() + matchIndex);
exclusionTypes.erase(exclusionTypes.begin() + matchIndex);
}
} while(match);
};
/// add a limit info storage item to the exclusion list, or alters an existing one
void setLimit(t_materialIndex materialIndex, unsigned int limit)
{
removeLimit(materialIndex);
if(limit > seedLimit) limit = seedLimit;
itemTypes.push_back(limitType);
itemSubtypes.push_back(limitSubtype);
materialIndices.push_back(materialIndex);
materialTypes.push_back((t_materialType) (limit < seedLimit) ? limit : seedLimit);
exclusionTypes.push_back(limitExclusion);
};
/// clears all limit info storage items from the exclusion list
void clearLimits()
{
bool match = false;
do
{
match = false;
std::size_t matchIndex;
for(std::size_t i = 0; i < size(); ++i)
{
if(itemTypes[i] == limitType
&& itemSubtypes[i] == limitSubtype
&& exclusionTypes[i] == limitExclusion)
{
match = true;
matchIndex = i;
}
}
if(match)
{
itemTypes.erase(itemTypes.begin() + matchIndex);
itemSubtypes.erase(itemSubtypes.begin() + matchIndex);
materialIndices.erase(materialIndices.begin() + matchIndex);
materialTypes.erase( materialTypes.begin() + matchIndex);
exclusionTypes.erase(exclusionTypes.begin() + matchIndex);
}
} while(match);
};
private:
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
std::size_t size() // the size of the exclusions vectors (they are all the same size - if not, there is a problem!)
{
return itemTypes.size();
};
static uint32_t addr(const DFHack::Core& core, int index)
{
static uint32_t start = core.vinfo->getAddress("kitchen_limits");
return start + sizeof(std::vector<int>) * index;
};
};
}
}

@ -9,23 +9,20 @@
#include "dfhack/Export.h"
#include "dfhack/PluginManager.h"
#include "dfhack/Process.h"
#include "dfhack/modules/Items.h"
#include "dfhack/modules/Materials.h"
#include "dfhack/modules/Items.h"
#include "dfhack/modules/World.h"
#include "dfhack/modules/kitchen.h"
#include <dfhack/VersionInfo.h>
typedef int32_t t_materialIndex;
typedef int16_t t_material, t_itemType, t_itemSubtype;
typedef int8_t t_exclusionType;
using DFHack::t_materialType;
using DFHack::t_materialIndex;
const unsigned int seedLimit = 400; // a limit on the limits which can be placed on seeds
const t_itemSubtype organicSubtype = -1; // seems to fixed
const t_exclusionType cookingExclusion = 1; // seems to be fixed
const t_itemType limitType = 0; // used to store limit as an entry in the exclusion list. 0 = BAR
const t_itemSubtype limitSubtype = 0; // used to store limit as an entry in the exclusion list
const t_exclusionType limitExclusion = 4; // used to store limit as an entry in the exclusion list
const int buffer = 20; // seed number buffer - 20 is reasonable
bool running = false; // whether seedwatch is counting the seeds or not
std::map<std::string, std::string> abbreviations; // abbreviations for the standard plants
// 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
{
@ -41,47 +38,26 @@ bool ignoreSeeds(DFHack::t_itemflags& f) // seeds with the following flags shoul
f.in_building ||
f.in_job;
};
void updateCountAndSubindices(DFHack::Core& core, std::map<t_materialIndex, unsigned int>& seedCount, std::map<t_materialIndex, t_material>& seedSubindices, std::map<t_materialIndex, t_material>& plantSubindices) // fills seedCount, seedSubindices and plantSubindices
{
DFHack::Items& itemsModule = *core.getItems();
itemsModule.Start();
std::vector<DFHack::df_item*> items;
itemsModule.readItemVector(items);
DFHack::df_item * item;
std::size_t size = items.size();
for(std::size_t i = 0; i < size; ++i)
{
item = items[i];
t_materialIndex materialIndex = item->getMaterialIndex();
switch(item->getType())
{
case DFHack::Items::SEEDS:
seedSubindices[materialIndex] = item->getMaterial();
if(!ignoreSeeds(item->flags)) ++seedCount[materialIndex];
break;
case DFHack::Items::PLANT:
plantSubindices[materialIndex] = item->getMaterial();
break;
}
}
itemsModule.Finish();
};
void printHelp(DFHack::Core& core) // prints help
{
core.con.print(
"Watches the numbers of plants and seeds available and enables/disables cooking automatically.\n"
"Watches the numbers of seeds available and enables/disables seed and plant cooking.\n"
"Each plant type can be assigned a limit. If their number falls below,\n"
"the plants and seeds of that type will be excluded from cookery.\n"
"If the number rises above the limit + %i, then cooking will be allowed.\n"
"If the number rises above the limit + %i, then cooking will be allowed.\n", buffer
);
core.con.printerr(
"The plugin needs a fortress to be loaded and will deactivate automatically otherwise.\n"
"You have to reactivate with 'seedwatch start' after you load the game.\n"
);
core.con.print(
"Options:\n"
"seedwatch all - Adds all plants from the abbreviation list to the watch list.\n"
"seedwatch start - Start watching.\n"
"seedwatch stop - Stop watching.\n"
"seedwatch info - Display whether seedwatch is watching, and the watch list.\n"
"seedwatch clear - Clears the watch list.\n\n"
, buffer
);
if(!abbreviations.empty())
{
@ -117,209 +93,6 @@ std::string searchAbbreviations(std::string in)
}
};
// helps to organise access to the cooking exclusions
class t_kitchenExclusions
{
public:
t_kitchenExclusions(DFHack::Core& core_) // constructor
: core(core_)
, itemTypes (*((std::vector<t_itemType >*)(addr(core_,0))))
, itemSubtypes (*((std::vector<t_itemSubtype >*)(addr(core_,1))))
, materials (*((std::vector<t_material >*)(addr(core_,2))))
, materialIndices (*((std::vector<t_materialIndex>*)(addr(core_,3))))
, exclusionTypes (*((std::vector<t_exclusionType>*)(addr(core_,4))))
{
};
void print() // print the exclusion list, with the material index also translated into its token (for organics) - for debug really
{
core.con.print("Kitchen Exclusions\n");
DFHack::Materials& materialsModule= *core.getMaterials();
materialsModule.ReadOrganicMaterials();
for(std::size_t i = 0; i < size(); ++i)
{
core.con.print("%2u: IT:%2i IS:%i MI:%2i MS:%3i ET:%i %s\n", i, itemTypes[i], itemSubtypes[i], materialIndices[i], materials[i], exclusionTypes[i], materialsModule.organic[materialIndices[i]].id.c_str());
}
core.con.print("\n");
};
void allowCookery(t_materialIndex materialIndex) // remove this material from the exclusion list if it is in it
{
bool match = false;
do
{
match = false;
std::size_t matchIndex = 0;
for(std::size_t i = 0; i < size(); ++i)
{
if(materialIndices[i] == materialIndex
&& (itemTypes[i] == DFHack::Items::SEEDS || itemTypes[i] == DFHack::Items::PLANT)
&& exclusionTypes[i] == cookingExclusion
)
{
match = true;
matchIndex = i;
}
}
if(match)
{
itemTypes.erase(itemTypes.begin() + matchIndex);
itemSubtypes.erase(itemSubtypes.begin() + matchIndex);
materialIndices.erase(materialIndices.begin() + matchIndex);
materials.erase( materials.begin() + matchIndex);
exclusionTypes.erase(exclusionTypes.begin() + matchIndex);
}
} while(match);
};
// add this material to the exclusion list, if it is not already in it
void denyCookery(t_materialIndex materialIndex, std::map<t_materialIndex, t_material>& seedMaterials, std::map<t_materialIndex, t_material>& plantMaterials)
{
if( seedMaterials.count(materialIndex) > 0)
{
bool alreadyIn = false;
for(std::size_t i = 0; i < size(); ++i)
{
if(materialIndices[i] == materialIndex
&& itemTypes[i] == DFHack::Items::SEEDS
&& exclusionTypes[i] == cookingExclusion)
{
alreadyIn = true;
}
}
if(!alreadyIn)
{
itemTypes.push_back(DFHack::Items::SEEDS);
itemSubtypes.push_back(organicSubtype);
materials.push_back( seedMaterials[materialIndex]);
materialIndices.push_back(materialIndex);
exclusionTypes.push_back(cookingExclusion);
}
}
if( plantMaterials.count(materialIndex) > 0)
{
bool alreadyIn = false;
for(std::size_t i = 0; i < size(); ++i)
{
if(materialIndices[i] == materialIndex
&& itemTypes[i] == DFHack::Items::PLANT
&& exclusionTypes[i] == cookingExclusion)
{
alreadyIn = true;
}
}
if(!alreadyIn)
{
itemTypes.push_back(DFHack::Items::PLANT);
itemSubtypes.push_back(organicSubtype);
materials.push_back(plantMaterials[materialIndex]);
materialIndices.push_back(materialIndex);
exclusionTypes.push_back(cookingExclusion);
}
}
};
// fills a map with info from the limit info storage entries in the exclusion list
void fillWatchMap(std::map<t_materialIndex, unsigned int>& watchMap)
{
watchMap.clear();
for(std::size_t i = 0; i < size(); ++i)
{
if(itemTypes[i] == limitType && itemSubtypes[i] == limitSubtype && exclusionTypes[i] == limitExclusion)
{
watchMap[materialIndices[i]] = (unsigned int) materials[i];
}
}
};
// removes a limit info storage entry from the exclusion list if it is in it
void removeLimit(t_materialIndex materialIndex)
{
bool match = false;
do
{
match = false;
std::size_t matchIndex = 0;
for(std::size_t i = 0; i < size(); ++i)
{
if(itemTypes[i] == limitType
&& itemSubtypes[i] == limitSubtype
&& materialIndices[i] == materialIndex
&& exclusionTypes[i] == limitExclusion)
{
match = true;
matchIndex = i;
}
}
if(match)
{
itemTypes.erase(itemTypes.begin() + matchIndex);
itemSubtypes.erase(itemSubtypes.begin() + matchIndex);
materials.erase(materials.begin() + matchIndex);
materialIndices.erase(materialIndices.begin() + matchIndex);
exclusionTypes.erase(exclusionTypes.begin() + matchIndex);
}
} while(match);
};
// add a limit info storage item to the exclusion list, or alters an existing one
void setLimit(t_materialIndex materialIndex, unsigned int limit)
{
removeLimit(materialIndex);
if(limit > seedLimit) limit = seedLimit;
itemTypes.push_back(limitType);
itemSubtypes.push_back(limitSubtype);
materialIndices.push_back(materialIndex);
materials.push_back((t_material) (limit < seedLimit) ? limit : seedLimit);
exclusionTypes.push_back(limitExclusion);
};
void clearLimits() // clears all limit info storage items from the exclusion list
{
bool match = false;
do
{
match = false;
std::size_t matchIndex;
for(std::size_t i = 0; i < size(); ++i)
{
if(itemTypes[i] == limitType
&& itemSubtypes[i] == limitSubtype
&& exclusionTypes[i] == limitExclusion)
{
match = true;
matchIndex = i;
}
}
if(match)
{
itemTypes.erase(itemTypes.begin() + matchIndex);
itemSubtypes.erase(itemSubtypes.begin() + matchIndex);
materialIndices.erase(materialIndices.begin() + matchIndex);
materials.erase( materials.begin() + matchIndex);
exclusionTypes.erase(exclusionTypes.begin() + matchIndex);
}
} while(match);
};
private:
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_material>& materials; // 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
std::size_t size() // the size of the exclusions vectors (they are all the same size - if not, there is a problem!)
{
return itemTypes.size();
};
//FIXME: ugly, ugly hack. Use memory.xml instead.
static uint32_t addr(const DFHack::Core& core, int index)
{
#ifdef LINUX_BUILD
return 0x93f2b00 + 0xC * index;
#else
return core.p->getBase() + 0x014F0BB4 - 0x400000 + 0x10 * index;
#endif
};
};
DFhackCExport DFHack::command_result df_seedwatch(DFHack::Core* pCore, std::vector<std::string>& parameters)
{
DFHack::Core& core = *pCore;
@ -339,6 +112,19 @@ DFhackCExport DFHack::command_result df_seedwatch(DFHack::Core* pCore, std::vect
materialsReverser[organics[i].id] = i;
}
DFHack::World *w = core.getWorld();
DFHack::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)
{
// just print the help
printHelp(core);
core.Resume();
return DFHack::CR_OK;
}
std::string par;
int limit;
switch(parameters.size())
@ -362,7 +148,7 @@ DFhackCExport DFHack::command_result df_seedwatch(DFHack::Core* pCore, std::vect
}
else if(par == "clear")
{
t_kitchenExclusions kitchenExclusions(core);
DFHack::Kitchen::Exclusions kitchenExclusions(core);
kitchenExclusions.clearLimits();
core.con.print("seedwatch watchlist cleared\n");
}
@ -377,7 +163,7 @@ 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");
}
t_kitchenExclusions kitchenExclusions(core);
DFHack::Kitchen::Exclusions kitchenExclusions(core);
std::map<t_materialIndex, unsigned int> watchMap;
kitchenExclusions.fillWatchMap(watchMap);
if(watchMap.empty())
@ -395,17 +181,35 @@ DFhackCExport DFHack::command_result df_seedwatch(DFHack::Core* pCore, std::vect
}
else if(par == "debug")
{
t_kitchenExclusions kitchenExclusions(core);
DFHack::Kitchen::Exclusions kitchenExclusions(core);
std::map<t_materialIndex, unsigned int> watchMap;
kitchenExclusions.fillWatchMap(watchMap);
kitchenExclusions.print();
kitchenExclusions.debug_print();
}
/*
else if(par == "dumpmaps")
{
core.con.print("Plants:\n");
for(auto i = plantMaterialTypes.begin(); i != plantMaterialTypes.end(); i++)
{
auto t = materialsModule.df_organic->at(i->first);
core.con.print("%s : %u %u\n", organics[i->first].id.c_str(), i->second, t->material_basic_mat);
}
core.con.print("Seeds:\n");
for(auto i = seedMaterialTypes.begin(); i != seedMaterialTypes.end(); i++)
{
auto t = materialsModule.df_organic->at(i->first);
core.con.print("%s : %u %u\n", organics[i->first].id.c_str(), i->second, t->material_seed);
}
}
*/
else
{
std::string token = searchAbbreviations(par);
if(materialsReverser.count(token) > 0)
{
t_kitchenExclusions kitchenExclusions(core);
DFHack::Kitchen::Exclusions kitchenExclusions(core);
kitchenExclusions.removeLimit(materialsReverser[token]);
core.con.print("%s is not being watched\n", token.c_str());
}
@ -422,7 +226,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)
{
t_kitchenExclusions kitchenExclusions(core);
DFHack::Kitchen::Exclusions kitchenExclusions(core);
if(materialsReverser.count(i->second) > 0) kitchenExclusions.setLimit(materialsReverser[i->second], limit);
}
}
@ -431,7 +235,7 @@ DFhackCExport DFHack::command_result df_seedwatch(DFHack::Core* pCore, std::vect
std::string token = searchAbbreviations(parameters[0]);
if(materialsReverser.count(token) > 0)
{
t_kitchenExclusions kitchenExclusions(core);
DFHack::Kitchen::Exclusions kitchenExclusions(core);
kitchenExclusions.setLimit(materialsReverser[token], limit);
core.con.print("%s is being watched.\n", token.c_str());
}
@ -489,22 +293,52 @@ DFhackCExport DFHack::command_result plugin_onupdate(DFHack::Core* pCore)
if(running)
{
DFHack::Core& core = *pCore;
DFHack::World *w = core.getWorld();
DFHack::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)
{
// stop running.
running = false;
core.con.printerr("seedwatch deactivated due to game mode switch\n");
return DFHack::CR_OK;
}
// this is dwarf mode, continue
std::map<t_materialIndex, unsigned int> seedCount; // the number of seeds
std::map<t_materialIndex, t_material> seedSubindices; // holds information needed to add entries to the cooking exclusions
std::map<t_materialIndex, t_material> plantSubindices; // holds information need to add entries to the cooking exclusions
updateCountAndSubindices(core, seedCount, seedSubindices, plantSubindices);
t_kitchenExclusions kitchenExclusions(core);
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)
{
item = items[i];
t_materialIndex materialIndex = item->getMaterialIndex();
switch(item->getType())
{
case DFHack::Items::SEEDS:
if(!ignoreSeeds(item->flags)) ++seedCount[materialIndex];
break;
case DFHack::Items::PLANT:
break;
}
}
itemsModule.Finish();
DFHack::Kitchen::Exclusions kitchenExclusions(core);
std::map<t_materialIndex, unsigned int> watchMap;
kitchenExclusions.fillWatchMap(watchMap);
for(std::map<t_materialIndex, unsigned int>::const_iterator i = watchMap.begin(); i != watchMap.end(); ++i)
for(auto i = watchMap.begin(); i != watchMap.end(); ++i)
{
if(seedCount[i->first] <= i->second)
{
kitchenExclusions.denyCookery(i->first, seedSubindices, plantSubindices);
kitchenExclusions.denyPlantSeedCookery(i->first);
}
else if(i->second + buffer < seedCount[i->first])
{
kitchenExclusions.allowCookery(i->first);
kitchenExclusions.allowPlantSeedCookery(i->first);
}
}
}