initial workings of the furnace
This commit is contained in:
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)
|
InventoryItem * InventoryList::takeItem(u32 i, u32 count)
|
||||||
{
|
{
|
||||||
if(count == 0)
|
if(count == 0)
|
||||||
|
@ -699,4 +721,131 @@ void IMoveAction::apply(InventoryContext *c, InventoryManager *mgr)
|
||||||
#endif
|
#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
|
//END
|
||||||
|
|
|
@ -435,6 +435,7 @@ public:
|
||||||
InventoryItem * changeItem(u32 i, InventoryItem *newitem);
|
InventoryItem * changeItem(u32 i, InventoryItem *newitem);
|
||||||
// Delete item
|
// Delete item
|
||||||
void deleteItem(u32 i);
|
void deleteItem(u32 i);
|
||||||
|
|
||||||
// Adds an item to a suitable place. Returns leftover item.
|
// Adds an item to a suitable place. Returns leftover item.
|
||||||
// If all went into the list, returns NULL.
|
// If all went into the list, returns NULL.
|
||||||
InventoryItem * addItem(InventoryItem *newitem);
|
InventoryItem * addItem(InventoryItem *newitem);
|
||||||
|
@ -445,6 +446,9 @@ public:
|
||||||
// If can be added fully, NULL is returned.
|
// If can be added fully, NULL is returned.
|
||||||
InventoryItem * addItem(u32 i, InventoryItem *newitem);
|
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.
|
// Takes some items from a slot.
|
||||||
// If there are not enough, takes as many as it can.
|
// If there are not enough, takes as many as it can.
|
||||||
// Returns NULL if couldn't take any.
|
// Returns NULL if couldn't take any.
|
||||||
|
@ -522,7 +526,7 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual Inventory* getInventory(InventoryContext *c, std::string id)
|
virtual Inventory* getInventory(InventoryContext *c, std::string id)
|
||||||
{return NULL;}
|
{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)
|
virtual void inventoryModified(InventoryContext *c, std::string id)
|
||||||
{}
|
{}
|
||||||
// Used on the client
|
// Used on the client
|
||||||
|
@ -600,5 +604,51 @@ struct IMoveAction : public InventoryAction
|
||||||
void apply(InventoryContext *c, InventoryManager *mgr);
|
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
|
#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);
|
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
|
ServerMap
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -285,6 +285,8 @@ public:
|
||||||
NodeMetadata* getNodeMetadata(v3s16 p);
|
NodeMetadata* getNodeMetadata(v3s16 p);
|
||||||
void setNodeMetadata(v3s16 p, NodeMetadata *meta);
|
void setNodeMetadata(v3s16 p, NodeMetadata *meta);
|
||||||
void removeNodeMetadata(v3s16 p);
|
void removeNodeMetadata(v3s16 p);
|
||||||
|
void nodeMetadataStep(float dtime,
|
||||||
|
core::map<v3s16, MapBlock*> &changed_blocks);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Variables
|
Variables
|
||||||
|
|
|
@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "mineral.h"
|
#include "mineral.h"
|
||||||
// For g_settings
|
// For g_settings
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
#include "nodemetadata.h"
|
||||||
|
|
||||||
ContentFeatures::~ContentFeatures()
|
ContentFeatures::~ContentFeatures()
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,7 +28,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "serialization.h"
|
#include "serialization.h"
|
||||||
#include "tile.h"
|
#include "tile.h"
|
||||||
#include "iirrlichtwrapper.h"
|
#include "iirrlichtwrapper.h"
|
||||||
#include "nodemetadata.h"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Initializes all kind of stuff in here.
|
Initializes all kind of stuff in here.
|
||||||
|
@ -121,6 +120,7 @@ enum LiquidType
|
||||||
};
|
};
|
||||||
|
|
||||||
class MapNode;
|
class MapNode;
|
||||||
|
class NodeMetadata;
|
||||||
|
|
||||||
struct ContentFeatures
|
struct ContentFeatures
|
||||||
{
|
{
|
||||||
|
|
|
@ -178,6 +178,12 @@ FurnaceNodeMetadata::FurnaceNodeMetadata()
|
||||||
m_inventory->addList("fuel", 1);
|
m_inventory->addList("fuel", 1);
|
||||||
m_inventory->addList("src", 1);
|
m_inventory->addList("src", 1);
|
||||||
m_inventory->addList("dst", 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()
|
FurnaceNodeMetadata::~FurnaceNodeMetadata()
|
||||||
{
|
{
|
||||||
|
@ -197,24 +203,134 @@ NodeMetadata* FurnaceNodeMetadata::create(std::istream &is)
|
||||||
{
|
{
|
||||||
FurnaceNodeMetadata *d = new FurnaceNodeMetadata();
|
FurnaceNodeMetadata *d = new FurnaceNodeMetadata();
|
||||||
d->m_inventory->deSerialize(is);
|
d->m_inventory->deSerialize(is);
|
||||||
/*std::string params;
|
int temp;
|
||||||
std::getline(is, params, '\n');*/
|
is>>temp;
|
||||||
|
d->m_fuel_totaltime = (float)temp/10;
|
||||||
|
is>>temp;
|
||||||
|
d->m_fuel_time = (float)temp/10;
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
void FurnaceNodeMetadata::serializeBody(std::ostream &os)
|
void FurnaceNodeMetadata::serializeBody(std::ostream &os)
|
||||||
{
|
{
|
||||||
m_inventory->serialize(os);
|
m_inventory->serialize(os);
|
||||||
// This line will contain the other parameters
|
os<<itos(m_fuel_totaltime*10)<<" ";
|
||||||
//os<<"\n";
|
os<<itos(m_fuel_time*10)<<" ";
|
||||||
}
|
}
|
||||||
std::string FurnaceNodeMetadata::infoText()
|
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()
|
void FurnaceNodeMetadata::inventoryModified()
|
||||||
{
|
{
|
||||||
dstream<<"Furnace inventory modification callback"<<std::endl;
|
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
|
NodeMetadatalist
|
||||||
|
@ -318,3 +434,32 @@ void NodeMetadataList::set(v3s16 p, NodeMetadata *d)
|
||||||
m_data.insert(p, 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
|
// This is called always after the inventory is modified, before
|
||||||
// the changes are copied elsewhere
|
// the changes are copied elsewhere
|
||||||
virtual void inventoryModified(){}
|
virtual void inventoryModified(){}
|
||||||
|
// A step in time. Returns true if metadata changed.
|
||||||
|
virtual bool step(float dtime) {return false;}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void registerType(u16 id, Factory f);
|
static void registerType(u16 id, Factory f);
|
||||||
|
@ -115,15 +117,23 @@ public:
|
||||||
virtual std::string infoText();
|
virtual std::string infoText();
|
||||||
virtual Inventory* getInventory() {return m_inventory;}
|
virtual Inventory* getInventory() {return m_inventory;}
|
||||||
virtual void inventoryModified();
|
virtual void inventoryModified();
|
||||||
|
virtual bool step(float dtime);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Inventory *m_inventory;
|
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
|
List of metadata of all the nodes of a block
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
class InventoryManager;
|
||||||
|
|
||||||
class NodeMetadataList
|
class NodeMetadataList
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -138,6 +148,10 @@ public:
|
||||||
void remove(v3s16 p);
|
void remove(v3s16 p);
|
||||||
// Deletes old data and sets a new one
|
// Deletes old data and sets a new one
|
||||||
void set(v3s16 p, NodeMetadata *d);
|
void set(v3s16 p, NodeMetadata *d);
|
||||||
|
|
||||||
|
// A step in time. Returns true if something changed.
|
||||||
|
bool step(float dtime);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
core::map<v3s16, NodeMetadata*> m_data;
|
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
|
Trigger emergethread (it somehow gets to a non-triggered but
|
||||||
bysy state sometimes)
|
bysy state sometimes)
|
||||||
|
@ -2740,7 +2766,6 @@ void Server::inventoryModified(InventoryContext *c, std::string id)
|
||||||
p.X = stoi(fn.next(","));
|
p.X = stoi(fn.next(","));
|
||||||
p.Y = stoi(fn.next(","));
|
p.Y = stoi(fn.next(","));
|
||||||
p.Z = stoi(fn.next(","));
|
p.Z = stoi(fn.next(","));
|
||||||
assert(c->current_player);
|
|
||||||
v3s16 blockpos = getNodeBlockPos(p);
|
v3s16 blockpos = getNodeBlockPos(p);
|
||||||
|
|
||||||
NodeMetadata *meta = m_env.getMap().getNodeMetadata(p);
|
NodeMetadata *meta = m_env.getMap().getNodeMetadata(p);
|
||||||
|
@ -2888,163 +2913,6 @@ void Server::SendPlayerInfos()
|
||||||
m_con.SendToAll(0, data, true);
|
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)
|
void Server::SendInventory(u16 peer_id)
|
||||||
{
|
{
|
||||||
DSTACK(__FUNCTION_NAME);
|
DSTACK(__FUNCTION_NAME);
|
||||||
|
|
Loading…
Reference in New Issue