initial workings of the furnace
parent
281f76b6a0
commit
d1d57cf5c3
|
@ -403,6 +403,28 @@ InventoryItem * InventoryList::addItem(u32 i, InventoryItem *newitem)
|
|||
}
|
||||
}
|
||||
|
||||
bool InventoryList::itemFits(u32 i, InventoryItem *newitem)
|
||||
{
|
||||
// If it is an empty position, it's an easy job.
|
||||
InventoryItem *to_item = m_items[i];
|
||||
if(to_item == NULL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// If not addable, return the item
|
||||
if(newitem->addableTo(to_item) == false)
|
||||
return false;
|
||||
|
||||
// If the item fits fully in the slot, add counter and delete it
|
||||
if(newitem->getCount() <= to_item->freeSpace())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
InventoryItem * InventoryList::takeItem(u32 i, u32 count)
|
||||
{
|
||||
if(count == 0)
|
||||
|
@ -698,5 +720,132 @@ void IMoveAction::apply(InventoryContext *c, InventoryManager *mgr)
|
|||
mgr->inventoryModified(c, to_inv);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
Craft checking system
|
||||
*/
|
||||
|
||||
bool ItemSpec::checkItem(InventoryItem *item)
|
||||
{
|
||||
if(type == ITEM_NONE)
|
||||
{
|
||||
// Has to be no item
|
||||
if(item != NULL)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// There should be an item
|
||||
if(item == NULL)
|
||||
return false;
|
||||
|
||||
std::string itemname = item->getName();
|
||||
|
||||
if(type == ITEM_MATERIAL)
|
||||
{
|
||||
if(itemname != "MaterialItem")
|
||||
return false;
|
||||
MaterialItem *mitem = (MaterialItem*)item;
|
||||
if(mitem->getMaterial() != num)
|
||||
return false;
|
||||
}
|
||||
else if(type == ITEM_CRAFT)
|
||||
{
|
||||
if(itemname != "CraftItem")
|
||||
return false;
|
||||
CraftItem *mitem = (CraftItem*)item;
|
||||
if(mitem->getSubName() != name)
|
||||
return false;
|
||||
}
|
||||
else if(type == ITEM_TOOL)
|
||||
{
|
||||
// Not supported yet
|
||||
assert(0);
|
||||
}
|
||||
else if(type == ITEM_MBO)
|
||||
{
|
||||
// Not supported yet
|
||||
assert(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not supported yet
|
||||
assert(0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool checkItemCombination(InventoryItem **items, ItemSpec *specs)
|
||||
{
|
||||
u16 items_min_x = 100;
|
||||
u16 items_max_x = 100;
|
||||
u16 items_min_y = 100;
|
||||
u16 items_max_y = 100;
|
||||
for(u16 y=0; y<3; y++)
|
||||
for(u16 x=0; x<3; x++)
|
||||
{
|
||||
if(items[y*3 + x] == NULL)
|
||||
continue;
|
||||
if(items_min_x == 100 || x < items_min_x)
|
||||
items_min_x = x;
|
||||
if(items_min_y == 100 || y < items_min_y)
|
||||
items_min_y = y;
|
||||
if(items_max_x == 100 || x > items_max_x)
|
||||
items_max_x = x;
|
||||
if(items_max_y == 100 || y > items_max_y)
|
||||
items_max_y = y;
|
||||
}
|
||||
// No items at all, just return false
|
||||
if(items_min_x == 100)
|
||||
return false;
|
||||
|
||||
u16 items_w = items_max_x - items_min_x + 1;
|
||||
u16 items_h = items_max_y - items_min_y + 1;
|
||||
|
||||
u16 specs_min_x = 100;
|
||||
u16 specs_max_x = 100;
|
||||
u16 specs_min_y = 100;
|
||||
u16 specs_max_y = 100;
|
||||
for(u16 y=0; y<3; y++)
|
||||
for(u16 x=0; x<3; x++)
|
||||
{
|
||||
if(specs[y*3 + x].type == ITEM_NONE)
|
||||
continue;
|
||||
if(specs_min_x == 100 || x < specs_min_x)
|
||||
specs_min_x = x;
|
||||
if(specs_min_y == 100 || y < specs_min_y)
|
||||
specs_min_y = y;
|
||||
if(specs_max_x == 100 || x > specs_max_x)
|
||||
specs_max_x = x;
|
||||
if(specs_max_y == 100 || y > specs_max_y)
|
||||
specs_max_y = y;
|
||||
}
|
||||
// No specs at all, just return false
|
||||
if(specs_min_x == 100)
|
||||
return false;
|
||||
|
||||
u16 specs_w = specs_max_x - specs_min_x + 1;
|
||||
u16 specs_h = specs_max_y - specs_min_y + 1;
|
||||
|
||||
// Different sizes
|
||||
if(items_w != specs_w || items_h != specs_h)
|
||||
return false;
|
||||
|
||||
for(u16 y=0; y<specs_h; y++)
|
||||
for(u16 x=0; x<specs_w; x++)
|
||||
{
|
||||
u16 items_x = items_min_x + x;
|
||||
u16 items_y = items_min_y + y;
|
||||
u16 specs_x = specs_min_x + x;
|
||||
u16 specs_y = specs_min_y + y;
|
||||
InventoryItem *item = items[items_y * 3 + items_x];
|
||||
ItemSpec &spec = specs[specs_y * 3 + specs_x];
|
||||
|
||||
if(spec.checkItem(item) == false)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//END
|
||||
|
|
|
@ -435,6 +435,7 @@ public:
|
|||
InventoryItem * changeItem(u32 i, InventoryItem *newitem);
|
||||
// Delete item
|
||||
void deleteItem(u32 i);
|
||||
|
||||
// Adds an item to a suitable place. Returns leftover item.
|
||||
// If all went into the list, returns NULL.
|
||||
InventoryItem * addItem(InventoryItem *newitem);
|
||||
|
@ -445,6 +446,9 @@ public:
|
|||
// If can be added fully, NULL is returned.
|
||||
InventoryItem * addItem(u32 i, InventoryItem *newitem);
|
||||
|
||||
// Checks whether the item could be added to the given slot
|
||||
bool itemFits(u32 i, InventoryItem *newitem);
|
||||
|
||||
// Takes some items from a slot.
|
||||
// If there are not enough, takes as many as it can.
|
||||
// Returns NULL if couldn't take any.
|
||||
|
@ -522,7 +526,7 @@ public:
|
|||
*/
|
||||
virtual Inventory* getInventory(InventoryContext *c, std::string id)
|
||||
{return NULL;}
|
||||
// Used on the server by InventoryAction::apply
|
||||
// Used on the server by InventoryAction::apply and other stuff
|
||||
virtual void inventoryModified(InventoryContext *c, std::string id)
|
||||
{}
|
||||
// Used on the client
|
||||
|
@ -600,5 +604,51 @@ struct IMoveAction : public InventoryAction
|
|||
void apply(InventoryContext *c, InventoryManager *mgr);
|
||||
};
|
||||
|
||||
/*
|
||||
Craft checking system
|
||||
*/
|
||||
|
||||
enum ItemSpecType
|
||||
{
|
||||
ITEM_NONE,
|
||||
ITEM_MATERIAL,
|
||||
ITEM_CRAFT,
|
||||
ITEM_TOOL,
|
||||
ITEM_MBO
|
||||
};
|
||||
|
||||
struct ItemSpec
|
||||
{
|
||||
enum ItemSpecType type;
|
||||
// Only other one of these is used
|
||||
std::string name;
|
||||
u16 num;
|
||||
|
||||
ItemSpec():
|
||||
type(ITEM_NONE)
|
||||
{
|
||||
}
|
||||
ItemSpec(enum ItemSpecType a_type, std::string a_name):
|
||||
type(a_type),
|
||||
name(a_name),
|
||||
num(65535)
|
||||
{
|
||||
}
|
||||
ItemSpec(enum ItemSpecType a_type, u16 a_num):
|
||||
type(a_type),
|
||||
name(""),
|
||||
num(a_num)
|
||||
{
|
||||
}
|
||||
|
||||
bool checkItem(InventoryItem *item);
|
||||
};
|
||||
|
||||
/*
|
||||
items: a pointer to an array of 9 pointers to items
|
||||
specs: a pointer to an array of 9 ItemSpecs
|
||||
*/
|
||||
bool checkItemCombination(InventoryItem **items, ItemSpec *specs);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
29
src/map.cpp
29
src/map.cpp
|
@ -1756,6 +1756,35 @@ void Map::removeNodeMetadata(v3s16 p)
|
|||
block->m_node_metadata.remove(p_rel);
|
||||
}
|
||||
|
||||
void Map::nodeMetadataStep(float dtime,
|
||||
core::map<v3s16, MapBlock*> &changed_blocks)
|
||||
{
|
||||
/*
|
||||
NOTE:
|
||||
Currently there is no way to ensure that all the necessary
|
||||
blocks are loaded when this is run. (They might get unloaded)
|
||||
NOTE: ^- Actually, that might not be so. In a quick test it
|
||||
reloaded a block with a furnace when I walked back to it from
|
||||
a distance.
|
||||
*/
|
||||
core::map<v2s16, MapSector*>::Iterator si;
|
||||
si = m_sectors.getIterator();
|
||||
for(; si.atEnd() == false; si++)
|
||||
{
|
||||
MapSector *sector = si.getNode()->getValue();
|
||||
core::list< MapBlock * > sectorblocks;
|
||||
sector->getBlocks(sectorblocks);
|
||||
core::list< MapBlock * >::Iterator i;
|
||||
for(i=sectorblocks.begin(); i!=sectorblocks.end(); i++)
|
||||
{
|
||||
MapBlock *block = *i;
|
||||
bool changed = block->m_node_metadata.step(dtime);
|
||||
if(changed)
|
||||
changed_blocks[block->getPos()] = block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
ServerMap
|
||||
*/
|
||||
|
|
|
@ -285,6 +285,8 @@ public:
|
|||
NodeMetadata* getNodeMetadata(v3s16 p);
|
||||
void setNodeMetadata(v3s16 p, NodeMetadata *meta);
|
||||
void removeNodeMetadata(v3s16 p);
|
||||
void nodeMetadataStep(float dtime,
|
||||
core::map<v3s16, MapBlock*> &changed_blocks);
|
||||
|
||||
/*
|
||||
Variables
|
||||
|
|
|
@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "mineral.h"
|
||||
// For g_settings
|
||||
#include "main.h"
|
||||
#include "nodemetadata.h"
|
||||
|
||||
ContentFeatures::~ContentFeatures()
|
||||
{
|
||||
|
|
|
@ -28,7 +28,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "serialization.h"
|
||||
#include "tile.h"
|
||||
#include "iirrlichtwrapper.h"
|
||||
#include "nodemetadata.h"
|
||||
|
||||
/*
|
||||
Initializes all kind of stuff in here.
|
||||
|
@ -121,6 +120,7 @@ enum LiquidType
|
|||
};
|
||||
|
||||
class MapNode;
|
||||
class NodeMetadata;
|
||||
|
||||
struct ContentFeatures
|
||||
{
|
||||
|
|
|
@ -178,6 +178,12 @@ FurnaceNodeMetadata::FurnaceNodeMetadata()
|
|||
m_inventory->addList("fuel", 1);
|
||||
m_inventory->addList("src", 1);
|
||||
m_inventory->addList("dst", 1);
|
||||
|
||||
m_step_accumulator = 0;
|
||||
m_fuel_totaltime = 0;
|
||||
m_fuel_time = 0;
|
||||
m_src_totaltime = 0;
|
||||
m_src_time = 0;
|
||||
}
|
||||
FurnaceNodeMetadata::~FurnaceNodeMetadata()
|
||||
{
|
||||
|
@ -197,24 +203,134 @@ NodeMetadata* FurnaceNodeMetadata::create(std::istream &is)
|
|||
{
|
||||
FurnaceNodeMetadata *d = new FurnaceNodeMetadata();
|
||||
d->m_inventory->deSerialize(is);
|
||||
/*std::string params;
|
||||
std::getline(is, params, '\n');*/
|
||||
int temp;
|
||||
is>>temp;
|
||||
d->m_fuel_totaltime = (float)temp/10;
|
||||
is>>temp;
|
||||
d->m_fuel_time = (float)temp/10;
|
||||
return d;
|
||||
}
|
||||
void FurnaceNodeMetadata::serializeBody(std::ostream &os)
|
||||
{
|
||||
m_inventory->serialize(os);
|
||||
// This line will contain the other parameters
|
||||
//os<<"\n";
|
||||
os<<itos(m_fuel_totaltime*10)<<" ";
|
||||
os<<itos(m_fuel_time*10)<<" ";
|
||||
}
|
||||
std::string FurnaceNodeMetadata::infoText()
|
||||
{
|
||||
return "Furnace";
|
||||
//return "Furnace";
|
||||
if(m_fuel_time >= m_fuel_totaltime)
|
||||
{
|
||||
InventoryList *src_list = m_inventory->getList("src");
|
||||
assert(src_list);
|
||||
InventoryItem *src_item = src_list->getItem(0);
|
||||
|
||||
if(src_item)
|
||||
return "Furnace is out of fuel";
|
||||
else
|
||||
return "Furnace is inactive";
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string s = "Furnace is active (";
|
||||
s += itos(m_fuel_time/m_fuel_totaltime*100);
|
||||
s += "%)";
|
||||
return s;
|
||||
}
|
||||
}
|
||||
void FurnaceNodeMetadata::inventoryModified()
|
||||
{
|
||||
dstream<<"Furnace inventory modification callback"<<std::endl;
|
||||
}
|
||||
bool FurnaceNodeMetadata::step(float dtime)
|
||||
{
|
||||
// Update at a fixed frequency
|
||||
const float interval = 0.5;
|
||||
m_step_accumulator += dtime;
|
||||
if(m_step_accumulator < interval)
|
||||
return false;
|
||||
m_step_accumulator -= interval;
|
||||
dtime = interval;
|
||||
|
||||
//dstream<<"Furnace step dtime="<<dtime<<std::endl;
|
||||
|
||||
InventoryList *dst_list = m_inventory->getList("dst");
|
||||
assert(dst_list);
|
||||
|
||||
InventoryList *src_list = m_inventory->getList("src");
|
||||
assert(src_list);
|
||||
InventoryItem *src_item = src_list->getItem(0);
|
||||
|
||||
if(ItemSpec(ITEM_MATERIAL, CONTENT_TREE).checkItem(src_item)
|
||||
&& dst_list->itemFits(0, new CraftItem("lump_of_coal", 1)))
|
||||
{
|
||||
m_src_totaltime = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_src_time = 0;
|
||||
m_src_totaltime = 0;
|
||||
}
|
||||
|
||||
if(m_fuel_time < m_fuel_totaltime)
|
||||
{
|
||||
//dstream<<"Furnace is active"<<std::endl;
|
||||
m_fuel_time += dtime;
|
||||
m_src_time += dtime;
|
||||
if(m_src_time >= m_src_totaltime && m_src_totaltime > 0.001)
|
||||
{
|
||||
if(ItemSpec(ITEM_MATERIAL, CONTENT_TREE).checkItem(src_item))
|
||||
{
|
||||
src_list->decrementMaterials(1);
|
||||
dst_list->addItem(0, new CraftItem("lump_of_coal", 1));
|
||||
m_src_time = 0;
|
||||
m_src_totaltime = 0;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if(src_item == NULL || m_src_totaltime < 0.001)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool changed = false;
|
||||
|
||||
//dstream<<"Furnace is out of fuel"<<std::endl;
|
||||
|
||||
InventoryList *fuel_list = m_inventory->getList("fuel");
|
||||
assert(fuel_list);
|
||||
InventoryItem *fuel_item = fuel_list->getItem(0);
|
||||
|
||||
if(ItemSpec(ITEM_MATERIAL, CONTENT_TREE).checkItem(fuel_item))
|
||||
{
|
||||
m_fuel_totaltime = 10;
|
||||
m_fuel_time = 0;
|
||||
fuel_list->decrementMaterials(1);
|
||||
changed = true;
|
||||
}
|
||||
else if(ItemSpec(ITEM_MATERIAL, CONTENT_WOOD).checkItem(fuel_item))
|
||||
{
|
||||
m_fuel_totaltime = 5;
|
||||
m_fuel_time = 0;
|
||||
fuel_list->decrementMaterials(1);
|
||||
changed = true;
|
||||
}
|
||||
else if(ItemSpec(ITEM_CRAFT, "lump_of_coal").checkItem(fuel_item))
|
||||
{
|
||||
m_fuel_totaltime = 10;
|
||||
m_fuel_time = 0;
|
||||
fuel_list->decrementMaterials(1);
|
||||
changed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
//dstream<<"No fuel found"<<std::endl;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
/*
|
||||
NodeMetadatalist
|
||||
|
@ -318,3 +434,32 @@ void NodeMetadataList::set(v3s16 p, NodeMetadata *d)
|
|||
m_data.insert(p, d);
|
||||
}
|
||||
|
||||
bool NodeMetadataList::step(float dtime)
|
||||
{
|
||||
bool something_changed = false;
|
||||
for(core::map<v3s16, NodeMetadata*>::Iterator
|
||||
i = m_data.getIterator();
|
||||
i.atEnd()==false; i++)
|
||||
{
|
||||
v3s16 p = i.getNode()->getKey();
|
||||
NodeMetadata *meta = i.getNode()->getValue();
|
||||
bool changed = meta->step(dtime);
|
||||
if(changed)
|
||||
something_changed = true;
|
||||
/*if(res.inventory_changed)
|
||||
{
|
||||
std::string inv_id;
|
||||
inv_id += "nodemeta:";
|
||||
inv_id += itos(p.X);
|
||||
inv_id += ",";
|
||||
inv_id += itos(p.Y);
|
||||
inv_id += ",";
|
||||
inv_id += itos(p.Z);
|
||||
InventoryContext c;
|
||||
c.current_player = NULL;
|
||||
inv_mgr->inventoryModified(&c, inv_id);
|
||||
}*/
|
||||
}
|
||||
return something_changed;
|
||||
}
|
||||
|
||||
|
|
|
@ -59,6 +59,8 @@ public:
|
|||
// This is called always after the inventory is modified, before
|
||||
// the changes are copied elsewhere
|
||||
virtual void inventoryModified(){}
|
||||
// A step in time. Returns true if metadata changed.
|
||||
virtual bool step(float dtime) {return false;}
|
||||
|
||||
protected:
|
||||
static void registerType(u16 id, Factory f);
|
||||
|
@ -115,15 +117,23 @@ public:
|
|||
virtual std::string infoText();
|
||||
virtual Inventory* getInventory() {return m_inventory;}
|
||||
virtual void inventoryModified();
|
||||
virtual bool step(float dtime);
|
||||
|
||||
private:
|
||||
Inventory *m_inventory;
|
||||
float m_step_accumulator;
|
||||
float m_fuel_totaltime;
|
||||
float m_fuel_time;
|
||||
float m_src_totaltime;
|
||||
float m_src_time;
|
||||
};
|
||||
|
||||
/*
|
||||
List of metadata of all the nodes of a block
|
||||
*/
|
||||
|
||||
class InventoryManager;
|
||||
|
||||
class NodeMetadataList
|
||||
{
|
||||
public:
|
||||
|
@ -138,6 +148,10 @@ public:
|
|||
void remove(v3s16 p);
|
||||
// Deletes old data and sets a new one
|
||||
void set(v3s16 p, NodeMetadata *d);
|
||||
|
||||
// A step in time. Returns true if something changed.
|
||||
bool step(float dtime);
|
||||
|
||||
private:
|
||||
core::map<v3s16, NodeMetadata*> m_data;
|
||||
};
|
||||
|
|
184
src/server.cpp
184
src/server.cpp
|
@ -1503,6 +1503,32 @@ void Server::AsyncRunStep()
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Step node metadata
|
||||
*/
|
||||
{
|
||||
JMutexAutoLock envlock(m_env_mutex);
|
||||
JMutexAutoLock conlock(m_con_mutex);
|
||||
|
||||
core::map<v3s16, MapBlock*> changed_blocks;
|
||||
m_env.getMap().nodeMetadataStep(dtime, changed_blocks);
|
||||
|
||||
for(core::map<v3s16, MapBlock*>::Iterator
|
||||
i = changed_blocks.getIterator();
|
||||
i.atEnd() == false; i++)
|
||||
{
|
||||
MapBlock *block = i.getNode()->getValue();
|
||||
|
||||
for(core::map<u16, RemoteClient*>::Iterator
|
||||
i = m_clients.getIterator();
|
||||
i.atEnd()==false; i++)
|
||||
{
|
||||
RemoteClient *client = i.getNode()->getValue();
|
||||
client->SetBlockNotSent(block->getPos());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Trigger emergethread (it somehow gets to a non-triggered but
|
||||
bysy state sometimes)
|
||||
|
@ -2740,7 +2766,6 @@ void Server::inventoryModified(InventoryContext *c, std::string id)
|
|||
p.X = stoi(fn.next(","));
|
||||
p.Y = stoi(fn.next(","));
|
||||
p.Z = stoi(fn.next(","));
|
||||
assert(c->current_player);
|
||||
v3s16 blockpos = getNodeBlockPos(p);
|
||||
|
||||
NodeMetadata *meta = m_env.getMap().getNodeMetadata(p);
|
||||
|
@ -2888,163 +2913,6 @@ void Server::SendPlayerInfos()
|
|||
m_con.SendToAll(0, data, true);
|
||||
}
|
||||
|
||||
/*
|
||||
Craft checking system
|
||||
*/
|
||||
|
||||
enum ItemSpecType
|
||||
{
|
||||
ITEM_NONE,
|
||||
ITEM_MATERIAL,
|
||||
ITEM_CRAFT,
|
||||
ITEM_TOOL,
|
||||
ITEM_MBO
|
||||
};
|
||||
|
||||
struct ItemSpec
|
||||
{
|
||||
ItemSpec():
|
||||
type(ITEM_NONE)
|
||||
{
|
||||
}
|
||||
ItemSpec(enum ItemSpecType a_type, std::string a_name):
|
||||
type(a_type),
|
||||
name(a_name),
|
||||
num(65535)
|
||||
{
|
||||
}
|
||||
ItemSpec(enum ItemSpecType a_type, u16 a_num):
|
||||
type(a_type),
|
||||
name(""),
|
||||
num(a_num)
|
||||
{
|
||||
}
|
||||
enum ItemSpecType type;
|
||||
// Only other one of these is used
|
||||
std::string name;
|
||||
u16 num;
|
||||
};
|
||||
|
||||
/*
|
||||
items: a pointer to an array of 9 pointers to items
|
||||
specs: a pointer to an array of 9 ItemSpecs
|
||||
*/
|
||||
bool checkItemCombination(InventoryItem **items, ItemSpec *specs)
|
||||
{
|
||||
u16 items_min_x = 100;
|
||||
u16 items_max_x = 100;
|
||||
u16 items_min_y = 100;
|
||||
u16 items_max_y = 100;
|
||||
for(u16 y=0; y<3; y++)
|
||||
for(u16 x=0; x<3; x++)
|
||||
{
|
||||
if(items[y*3 + x] == NULL)
|
||||
continue;
|
||||
if(items_min_x == 100 || x < items_min_x)
|
||||
items_min_x = x;
|
||||
if(items_min_y == 100 || y < items_min_y)
|
||||
items_min_y = y;
|
||||
if(items_max_x == 100 || x > items_max_x)
|
||||
items_max_x = x;
|
||||
if(items_max_y == 100 || y > items_max_y)
|
||||
items_max_y = y;
|
||||
}
|
||||
// No items at all, just return false
|
||||
if(items_min_x == 100)
|
||||
return false;
|
||||
|
||||
u16 items_w = items_max_x - items_min_x + 1;
|
||||
u16 items_h = items_max_y - items_min_y + 1;
|
||||
|
||||
u16 specs_min_x = 100;
|
||||
u16 specs_max_x = 100;
|
||||
u16 specs_min_y = 100;
|
||||
u16 specs_max_y = 100;
|
||||
for(u16 y=0; y<3; y++)
|
||||
for(u16 x=0; x<3; x++)
|
||||
{
|
||||
if(specs[y*3 + x].type == ITEM_NONE)
|
||||
continue;
|
||||
if(specs_min_x == 100 || x < specs_min_x)
|
||||
specs_min_x = x;
|
||||
if(specs_min_y == 100 || y < specs_min_y)
|
||||
specs_min_y = y;
|
||||
if(specs_max_x == 100 || x > specs_max_x)
|
||||
specs_max_x = x;
|
||||
if(specs_max_y == 100 || y > specs_max_y)
|
||||
specs_max_y = y;
|
||||
}
|
||||
// No specs at all, just return false
|
||||
if(specs_min_x == 100)
|
||||
return false;
|
||||
|
||||
u16 specs_w = specs_max_x - specs_min_x + 1;
|
||||
u16 specs_h = specs_max_y - specs_min_y + 1;
|
||||
|
||||
// Different sizes
|
||||
if(items_w != specs_w || items_h != specs_h)
|
||||
return false;
|
||||
|
||||
for(u16 y=0; y<specs_h; y++)
|
||||
for(u16 x=0; x<specs_w; x++)
|
||||
{
|
||||
u16 items_x = items_min_x + x;
|
||||
u16 items_y = items_min_y + y;
|
||||
u16 specs_x = specs_min_x + x;
|
||||
u16 specs_y = specs_min_y + y;
|
||||
InventoryItem *item = items[items_y * 3 + items_x];
|
||||
ItemSpec &spec = specs[specs_y * 3 + specs_x];
|
||||
|
||||
if(spec.type == ITEM_NONE)
|
||||
{
|
||||
// Has to be no item
|
||||
if(item != NULL)
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
|
||||
// There should be an item
|
||||
if(item == NULL)
|
||||
return false;
|
||||
|
||||
std::string itemname = item->getName();
|
||||
|
||||
if(spec.type == ITEM_MATERIAL)
|
||||
{
|
||||
if(itemname != "MaterialItem")
|
||||
return false;
|
||||
MaterialItem *mitem = (MaterialItem*)item;
|
||||
if(mitem->getMaterial() != spec.num)
|
||||
return false;
|
||||
}
|
||||
else if(spec.type == ITEM_CRAFT)
|
||||
{
|
||||
if(itemname != "CraftItem")
|
||||
return false;
|
||||
CraftItem *mitem = (CraftItem*)item;
|
||||
if(mitem->getSubName() != spec.name)
|
||||
return false;
|
||||
}
|
||||
else if(spec.type == ITEM_TOOL)
|
||||
{
|
||||
// Not supported yet
|
||||
assert(0);
|
||||
}
|
||||
else if(spec.type == ITEM_MBO)
|
||||
{
|
||||
// Not supported yet
|
||||
assert(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not supported yet
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Server::SendInventory(u16 peer_id)
|
||||
{
|
||||
DSTACK(__FUNCTION_NAME);
|
||||
|
|
Loading…
Reference in New Issue