Move a few item functions from autotrade/stocks into DFHack::Items

develop
lethosor 2018-05-12 11:51:36 -04:00
parent a0ea756789
commit a34b34d3cb
9 changed files with 130 additions and 115 deletions

@ -1290,6 +1290,21 @@ Items module
Calculates the Basic Value of an item, as seen in the View Item screen. Calculates the Basic Value of an item, as seen in the View Item screen.
* ``dfhack.items.createItem(item_type, item_subtype, mat_type, mat_index, unit)``
Creates an item, similar to the `createitem` plugin.
* ``dfhack.items.checkMandates(item)``
Returns true if the item is free from mandates, or false if mandates prevent trading the item.
* ``dfhack.items.canTrade(item)``
Checks whether the item can be traded.
* ``dfhack.items.canTradeWithContents(item)``
Checks whether the item and all items it contains, if any, can be traded.
Maps module Maps module
----------- -----------

@ -37,6 +37,12 @@ changelog.txt uses a syntax similar to RST, with a few special sequences:
================================================================================ ================================================================================
# Future # Future
## API
- New functions (all available to Lua as well):
- ``Items::checkMandates()``
- ``Items::canTrade()``
- ``Items::canTradeWithContents()``
# 0.44.10-beta1 # 0.44.10-beta1
## New Scripts ## New Scripts

@ -13,6 +13,7 @@ CHANGELOG_SECTIONS = [
'Fixes', 'Fixes',
'Misc Improvements', 'Misc Improvements',
'Removed', 'Removed',
'API',
'Internals', 'Internals',
'Structures', 'Structures',
'Lua', 'Lua',
@ -23,6 +24,12 @@ REPLACEMENTS = {
'`search`': '`search-plugin`', '`search`': '`search-plugin`',
} }
def to_title_case(word):
if word == word.upper():
# Preserve acronyms
return word
return word[0].upper() + word[1:].lower()
def find_all_indices(string, substr): def find_all_indices(string, substr):
start = 0 start = 0
while True: while True:
@ -54,8 +61,7 @@ class ChangelogEntry(object):
def __init__(self, text, section, stable_version, dev_version): def __init__(self, text, section, stable_version, dev_version):
text = text.lstrip('- ') text = text.lstrip('- ')
# normalize section to title case # normalize section to title case
self.section = ' '.join(word[0].upper() + word[1:].lower() self.section = ' '.join(map(to_title_case, section.strip().split()))
for word in section.strip().split())
self.stable_version = stable_version self.stable_version = stable_version
self.dev_version = dev_version self.dev_version = dev_version
self.dev_only = text.startswith('@') self.dev_only = text.startswith('@')

@ -1755,6 +1755,9 @@ static const LuaWrapper::FunctionReg dfhack_items_module[] = {
WRAPM(Items, getItemBaseValue), WRAPM(Items, getItemBaseValue),
WRAPM(Items, getValue), WRAPM(Items, getValue),
WRAPM(Items, createItem), WRAPM(Items, createItem),
WRAPM(Items, checkMandates),
WRAPM(Items, canTrade),
WRAPM(Items, canTradeWithContents),
WRAPN(moveToGround, items_moveToGround), WRAPN(moveToGround, items_moveToGround),
WRAPN(moveToContainer, items_moveToContainer), WRAPN(moveToContainer, items_moveToContainer),
WRAPN(moveToInventory, items_moveToInventory), WRAPN(moveToInventory, items_moveToInventory),

@ -182,6 +182,14 @@ DFHACK_EXPORT int getItemBaseValue(int16_t item_type, int16_t item_subtype, int1
DFHACK_EXPORT int getValue(df::item *item); DFHACK_EXPORT int getValue(df::item *item);
DFHACK_EXPORT int32_t createItem(df::item_type type, int16_t item_subtype, int16_t mat_type, int32_t mat_index, df::unit* creator); DFHACK_EXPORT int32_t createItem(df::item_type type, int16_t item_subtype, int16_t mat_type, int32_t mat_index, df::unit* creator);
/// Returns true if the item is free from mandates, or false if mandates prevent trading the item
DFHACK_EXPORT bool checkMandates(df::item *item);
/// Checks whether the item can be traded
DFHACK_EXPORT bool canTrade(df::item *item);
/// Checks whether the item and all items it contains, if any, can be traded
DFHACK_EXPORT bool canTradeWithContents(df::item *item);
} }
} }

@ -75,6 +75,7 @@ using namespace std;
#include "df/itemdef_trapcompst.h" #include "df/itemdef_trapcompst.h"
#include "df/itemdef_weaponst.h" #include "df/itemdef_weaponst.h"
#include "df/job_item.h" #include "df/job_item.h"
#include "df/mandate.h"
#include "df/map_block.h" #include "df/map_block.h"
#include "df/proj_itemst.h" #include "df/proj_itemst.h"
#include "df/proj_list_link.h" #include "df/proj_list_link.h"
@ -1401,3 +1402,86 @@ int32_t Items::createItem(df::item_type item_type, int16_t item_subtype, int16_t
return out_items[0]->id; return out_items[0]->id;
} }
/*
* Trade Info
*/
bool Items::checkMandates(df::item *item)
{
CHECK_NULL_POINTER(item);
for (df::mandate *mandate : world->mandates)
{
if (mandate->mode != df::mandate::T_mode::Export)
continue;
if (item->getType() != mandate->item_type ||
(mandate->item_subtype != -1 && item->getSubtype() != mandate->item_subtype))
continue;
if (mandate->mat_type != -1 && item->getMaterial() != mandate->mat_type)
continue;
if (mandate->mat_index != -1 && item->getMaterialIndex() != mandate->mat_index)
continue;
return false;
}
return true;
}
bool Items::canTrade(df::item *item)
{
CHECK_NULL_POINTER(item);
if (item->flags.bits.owned || item->flags.bits.artifact || item->flags.bits.spider_web || item->flags.bits.in_job)
return false;
for (df::general_ref *ref : item->general_refs)
{
switch (ref->getType())
{
case general_ref_type::UNIT_HOLDER:
return false;
case general_ref_type::BUILDING_HOLDER:
return false;
default:
break;
}
}
for (df::specific_ref *ref : item->specific_refs)
{
if (ref->type == specific_ref_type::JOB)
{
// Ignore any items assigned to a job
return false;
}
}
return checkMandates(item);
}
bool Items::canTradeWithContents(df::item *item)
{
CHECK_NULL_POINTER(item);
if (item->flags.bits.in_inventory)
return false;
if (!canTrade(item))
return false;
vector<df::item*> contained_items;
getContainedItems(item, &contained_items);
for (df::item *cit : contained_items)
{
if (!canTrade(cit))
return false;
}
return true;
}

@ -1 +1 @@
Subproject commit 03eedecfb3bb0eb3d71986e7e897770d9be0fad6 Subproject commit 6c4020d5a0ebca365fe3074087110cc8b0f12168

@ -134,33 +134,9 @@ static TradeDepotInfo depot_info;
* Item Manipulation * Item Manipulation
*/ */
static bool check_mandates(df::item *item)
{
for (auto it = world->mandates.begin(); it != world->mandates.end(); it++)
{
auto mandate = *it;
if (mandate->mode != 0)
continue;
if (item->getType() != mandate->item_type ||
(mandate->item_subtype != -1 && item->getSubtype() != mandate->item_subtype))
continue;
if (mandate->mat_type != -1 && item->getMaterial() != mandate->mat_type)
continue;
if (mandate->mat_index != -1 && item->getMaterialIndex() != mandate->mat_index)
continue;
return false;
}
return true;
}
static bool is_valid_item(df::item *item) static bool is_valid_item(df::item *item)
{ {
// Similar to Items::canTrade() with a few checks changed
for (size_t i = 0; i < item->general_refs.size(); i++) for (size_t i = 0; i < item->general_refs.size(); i++)
{ {
df::general_ref *ref = item->general_refs[i]; df::general_ref *ref = item->general_refs[i];
@ -192,7 +168,7 @@ static bool is_valid_item(df::item *item)
} }
} }
if (!check_mandates(item)) if (!Items::checkMandates(item))
return false; return false;
return true; return true;
@ -236,9 +212,9 @@ static void mark_all_in_stockpiles(vector<PersistentStockpileInfo> &stockpiles)
bool mandates_ok = true; bool mandates_ok = true;
vector<df::item*> contained_items; vector<df::item*> contained_items;
Items::getContainedItems(item, &contained_items); Items::getContainedItems(item, &contained_items);
for (auto cit = contained_items.begin(); cit != contained_items.end(); cit++) for (df::item *cit : contained_items)
{ {
if (!check_mandates(*cit)) if (!Items::checkMandates(cit))
{ {
mandates_ok = false; mandates_ok = false;
break; break;

@ -72,89 +72,6 @@ static df::item *get_container_of(df::unit *unit)
* Trade Info * Trade Info
*/ */
static bool check_mandates(df::item *item)
{
for (auto it = world->mandates.begin(); it != world->mandates.end(); it++)
{
auto mandate = *it;
if (mandate->mode != 0)
continue;
if (item->getType() != mandate->item_type ||
(mandate->item_subtype != -1 && item->getSubtype() != mandate->item_subtype))
continue;
if (mandate->mat_type != -1 && item->getMaterial() != mandate->mat_type)
continue;
if (mandate->mat_index != -1 && item->getMaterialIndex() != mandate->mat_index)
continue;
return false;
}
return true;
}
static bool can_trade_item(df::item *item)
{
if (item->flags.bits.owned || item->flags.bits.artifact || item->flags.bits.spider_web || item->flags.bits.in_job)
return false;
for (size_t i = 0; i < item->general_refs.size(); i++)
{
df::general_ref *ref = item->general_refs[i];
switch (ref->getType())
{
case general_ref_type::UNIT_HOLDER:
return false;
case general_ref_type::BUILDING_HOLDER:
return false;
default:
break;
}
}
for (size_t i = 0; i < item->specific_refs.size(); i++)
{
df::specific_ref *ref = item->specific_refs[i];
if (ref->type == specific_ref_type::JOB)
{
// Ignore any items assigned to a job
return false;
}
}
return check_mandates(item);
}
static bool can_trade_item_and_container(df::item *item)
{
item = get_container_of(item);
if (item->flags.bits.in_inventory)
return false;
if (!can_trade_item(item))
return false;
vector<df::item*> contained_items;
Items::getContainedItems(item, &contained_items);
for (auto cit = contained_items.begin(); cit != contained_items.end(); cit++)
{
if (!can_trade_item(*cit))
return false;
}
return true;
}
class TradeDepotInfo class TradeDepotInfo
{ {
public: public:
@ -185,7 +102,7 @@ public:
{ {
auto item = *it; auto item = *it;
item = get_container_of(item); item = get_container_of(item);
if (!can_trade_item_and_container(item)) if (!Items::canTradeWithContents(item))
return false; return false;
auto href = df::allocate<df::general_ref_building_holderst>(); auto href = df::allocate<df::general_ref_building_holderst>();