addition - crusher

This commit is contained in:
Capricornus 2017-07-03 22:09:59 +02:00 committed by darkrose
parent 7517420b5a
commit c9b31e8826
19 changed files with 959 additions and 3 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 606 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 513 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 513 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 654 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 516 B

View File

@ -60,6 +60,8 @@ void content_craftitem_init()
g_content_craftitem_features[k].description = (char*)"";
g_content_craftitem_features[k].cook_result = CONTENT_IGNORE;
g_content_craftitem_features[k].cook_type = COOK_ANY;
g_content_craftitem_features[k].crush_result = CONTENT_IGNORE;
g_content_craftitem_features[k].crush_type = CRUSH_ANY;
g_content_craftitem_features[k].fuel_time = 0.0;
g_content_craftitem_features[k].stackable = true;
g_content_craftitem_features[k].consumable = false;

View File

@ -41,6 +41,10 @@ struct CraftItemFeatures {
content_t cook_result;
// what type of cooking device this item needs
CookType cook_type;
// the result of crushing this item
content_t crush_result;
// what type of crushing device this item needs
CrushType crush_type;
// the fuel value of this item
float fuel_time;
// whether the item can be stacked in inventory

View File

@ -223,6 +223,8 @@ void content_mapnode_init(bool repeat)
f->is_ground_content = true;
f->often_contains_mineral = true;
f->dug_item = std::string("MaterialItem2 ")+itos(CONTENT_ROUGHSTONE)+" 1";
f->crush_result = std::string("MaterialItem2 ")+itos(CONTENT_COBBLE)+" 1";
f->crush_type = CRUSH_CRUSHER;
f->type = CMT_STONE;
f->dig_time = 1.0;
content_list_add("creative",i,1,0);
@ -242,6 +244,8 @@ void content_mapnode_init(bool repeat)
f->cook_type = COOK_FURNACE;
f->type = CMT_STONE;
f->dig_time = 0.6;
f->crush_result = std::string("MaterialItem2 ")+itos(CONTENT_COBBLE)+" 1";
f->crush_type = CRUSH_CRUSHER;
content_list_add("creative",i,1,0);
content_list_add("cooking",i,1,0);
content_list_add("decrafting",i,1,0);
@ -602,6 +606,8 @@ void content_mapnode_init(bool repeat)
f->extra_dug_item_min_level = 1;
f->type = CMT_DIRT;
f->dig_time = 1.75;
f->crush_result = std::string("MaterialItem2 ")+itos(CONTENT_SAND)+" 1";
f->crush_type = CRUSH_CRUSHER;
content_list_add("creative",i,1,0);
content_list_add("decrafting",i,1,0);
@ -2306,6 +2312,8 @@ void content_mapnode_init(bool repeat)
f->cook_type = COOK_FURNACE;
f->type = CMT_STONE;
f->dig_time = 0.9;
f->crush_result = std::string("MaterialItem2 ")+itos(CONTENT_COBBLE)+" 1";
f->crush_type = CRUSH_CRUSHER;
crafting::setBlockRecipe(CONTENT_COBBLE,CONTENT_ROUGHSTONE);
content_list_add("craftguide",i,1,0);
content_list_add("creative",i,1,0);
@ -2322,6 +2330,8 @@ void content_mapnode_init(bool repeat)
f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
f->type = CMT_STONE;
f->dig_time = 0.9;
f->crush_result = std::string("MaterialItem2 ")+itos(CONTENT_GRAVEL)+" 1";
f->crush_type = CRUSH_CRUSHER;
crafting::set5Recipe(CONTENT_ROUGHSTONE,CONTENT_COBBLE);
crafting::setHardBlockRecipe(CONTENT_ROCK,CONTENT_COBBLE);
content_list_add("craftguide",i,1,0);
@ -2338,6 +2348,8 @@ void content_mapnode_init(bool repeat)
f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
f->type = CMT_STONE;
f->dig_time = 0.8;
f->crush_result = std::string("MaterialItem2 ")+itos(CONTENT_GRAVEL)+" 1";
f->crush_type = CRUSH_CRUSHER;
content_list_add("creative",i,1,0);
i = CONTENT_STEEL;
@ -2818,7 +2830,7 @@ void content_mapnode_init(bool repeat)
content_list_add("cooking",i,1,0);
content_list_add("craftguide",i,1,0);
content_list_add("creative",i,1,0);
i = CONTENT_APPLEWOOD_COLUMN_SQUARE_BASE;
f = &content_features(i);
f->setAllTextures("applewood.png");

View File

@ -291,7 +291,11 @@ MapNode mapnode_translate_to_internal(MapNode n_from, u8 version);
#define CONTENT_COUCH_OUTER_BLACK 0x864
#define CONTENT_COUCH_CHAIR_BLACK 0x865
#define CONTENT_CAULDRON 0x866
// FREE 867-86F
#define CONTENT_CRUSHER 0x867
#define CONTENT_CRUSHER_ACTIVE 0x868
#define CONTENT_LOCKABLE_CRUSHER 0x869
#define CONTENT_LOCKABLE_CRUSHER_ACTIVE 0x86A
// FREE 86B-86F
#define CONTENT_FLAG 0x870
#define CONTENT_FLAG_BLUE 0x871
#define CONTENT_FLAG_GREEN 0x872

View File

@ -1515,7 +1515,90 @@ void content_mapnode_special(bool repeat)
content_list_add("craftguide",i,1,0);
content_list_add("creative",i,1,0);
i = CONTENT_CRUSHER;
f = &content_features(i);
f->description = gettext("Crusher");
f->param_type = CPT_FACEDIR_SIMPLE;
f->draw_type = CDT_NODEBOX_META;
f->setAllTextures("crusher_side.png");
f->setTexture(0, "crusher_top.png");
f->setTexture(1, "crusher_top.png^[transformFY");
f->setTexture(2, "crusher_side.png^[transformFX");
f->setTexture(4, "crusher_back.png");
f->setTexture(5, "crusher_front.png"); // Z-
content_nodebox_crusher(f);
f->setInventoryTextureNodeBox(i,"crusher_top.png^[transformR90", "crusher_front.png", "crusher_side.png^[transformFX");
f->rotate_tile_with_nodebox = true;
f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
if(f->initial_metadata == NULL)
f->initial_metadata = new CrusherNodeMetadata();
f->type = CMT_STONE;
f->dig_time = 3.0;
f->pressure_type = CST_SOLID;
f->alternate_lockstate_node = CONTENT_LOCKABLE_CRUSHER;
crafting::setFilledRoundRecipe(CONTENT_CRAFTITEM_STEEL_INGOT,CONTENT_CRAFTITEM_TIN_INGOT,CONTENT_CRUSHER);
content_list_add("craftguide",i,1,0);
content_list_add("creative",i,1,0);
i = CONTENT_CRUSHER_ACTIVE;
f = &content_features(i);
f->description = gettext("Crusher");
f->param_type = CPT_FACEDIR_SIMPLE;
f->draw_type = CDT_CUBELIKE;
f->setAllTextures("crusher_side.png");
f->setTexture(0, "crusher_top.png");
f->setTexture(1, "crusher_top.png");
f->setTexture(5, "crusher_front.png"); // Z-
content_nodebox_activecrusher(f);
f->dug_item = std::string("MaterialItem2 ")+itos(CONTENT_CRUSHER)+" 1";
if(f->initial_metadata == NULL)
f->initial_metadata = new CrusherNodeMetadata();
f->type = CMT_STONE;
f->dig_time = 3.0;
f->pressure_type = CST_SOLID;
i = CONTENT_LOCKABLE_CRUSHER;
f = &content_features(i);
f->description = gettext("Locking Crusher");
f->param_type = CPT_FACEDIR_SIMPLE;
f->draw_type = CDT_NODEBOX_META;
f->setAllTextures("crusher_side.png");
f->setTexture(0, "crusher_top.png");
f->setTexture(1, "crusher_top.png^[transformFY");
f->setTexture(2, "crusher_side.png^[transformFX");
f->setTexture(4, "crusher_back.png");
f->setTexture(5, "crusher_lock.png"); // Z-
content_nodebox_lockedcrusher(f);
f->setInventoryTextureNodeBox(i,"crusher_top.png^[transformR90", "crusher_lock.png", "crusher_side.png^[transformFX");
f->rotate_tile_with_nodebox = true;
f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
if(f->initial_metadata == NULL)
f->initial_metadata = new LockingCrusherNodeMetadata();
f->type = CMT_STONE;
f->dig_time = 3.0;
f->pressure_type = CST_SOLID;
f->alternate_lockstate_node = CONTENT_CRUSHER;
crafting::set1Any2Recipe(CONTENT_CRUSHER,CONTENT_CRAFTITEM_STEEL_INGOT,CONTENT_LOCKABLE_CRUSHER);
content_list_add("craftguide",i,1,0);
content_list_add("creative",i,1,0);
i = CONTENT_LOCKABLE_CRUSHER_ACTIVE;
f = &content_features(i);
f->description = gettext("Locking Crusher");
f->param_type = CPT_FACEDIR_SIMPLE;
f->draw_type = CDT_CUBELIKE;
f->light_source = 9;
f->setAllTextures("crusher_side.png");
f->setTexture(0, "crusher_top.png");
f->setTexture(1, "crusher_top.png");
f->setTexture(5, "crusher_lock_active.png"); // Z-
content_nodebox_activelockedcrusher(f);
f->dug_item = std::string("MaterialItem2 ")+itos(CONTENT_LOCKABLE_CRUSHER)+" 1";
if(f->initial_metadata == NULL)
f->initial_metadata = new LockingCrusherNodeMetadata();
f->type = CMT_STONE;
f->dig_time = 3.0;
f->pressure_type = CST_SOLID;
i = CONTENT_NC;
f = &content_features(i);

View File

@ -2077,3 +2077,143 @@ void content_nodebox_scaffolding(ContentFeatures *f)
0.406250*BS,-0.500000*BS,-0.406250*BS,0.500000*BS,-0.406250*BS,0.406250*BS
));
}
void content_nodebox_crusher(ContentFeatures *f)
{
f->setNodeBox(NodeBox(
-0.5*BS,-0.5*BS,-0.5*BS,0.5*BS,-0.3125*BS,0.5*BS
));
f->addNodeBox(NodeBox(
-0.5*BS,-0.3125*BS,-0.5*BS,-0.375*BS,0.5*BS,0.5*BS
));
f->addNodeBox(NodeBox(
0.375*BS,-0.3125*BS,-0.5*BS,0.5*BS,0.5*BS,0.5*BS
));
f->addNodeBox(NodeBox(
-0.375*BS,-0.3125*BS,-0.5*BS,0.375*BS,0.5*BS,-0.375*BS
));
f->addNodeBox(NodeBox(
-0.375*BS,-0.3125*BS,0.375*BS,0.375*BS,0.5*BS,0.5*BS
));
f->addNodeBox(NodeBox(
0.1875*BS,-0.3125*BS,-0.5*BS,0.25*BS,0.5*BS,0.5*BS
));
f->addNodeBox(NodeBox(
-0.25*BS,-0.3125*BS,-0.5*BS,-0.1875*BS,0.5*BS,0.5*BS
));
f->addNodeBox(NodeBox(
0.25*BS,-0.0625*BS,-0.0625*BS,0.375*BS,0.0625*BS,0.0625*BS
));
f->addNodeBox(NodeBox(
-0.375*BS,-0.0625*BS,-0.0625*BS,-0.25*BS,0.0625*BS,0.0625*BS
));
}
void content_nodebox_activecrusher(ContentFeatures *f)
{
f->setNodeBox(NodeBox(
-0.5*BS,-0.5*BS,-0.5*BS,0.5*BS,-0.3125*BS,0.5*BS
));
f->addNodeBox(NodeBox(
-0.5*BS,-0.3125*BS,-0.5*BS,-0.375*BS,0.5*BS,0.5*BS
));
f->addNodeBox(NodeBox(
0.375*BS,-0.3125*BS,-0.5*BS,0.5*BS,0.5*BS,0.5*BS
));
f->addNodeBox(NodeBox(
-0.375*BS,-0.3125*BS,-0.5*BS,0.375*BS,0.5*BS,-0.375*BS
));
f->addNodeBox(NodeBox(
-0.375*BS,-0.3125*BS,0.375*BS,0.375*BS,0.5*BS,0.5*BS
));
f->addNodeBox(NodeBox(
-0.0625*BS,-0.3125*BS,-0.5*BS,0.0625*BS,0.5*BS,0.5*BS
));
f->addNodeBox(NodeBox(
-0.375*BS,-0.0625*BS,-0.0625*BS,0.375*BS,0.0625*BS,0.0625*BS
));
}
void content_nodebox_lockedcrusher(ContentFeatures *f)
{
f->setNodeBox(NodeBox(
-0.5*BS,-0.5*BS,-0.5*BS,0.5*BS,-0.3125*BS,0.5*BS
));
f->addNodeBox(NodeBox(
-0.5*BS,-0.3125*BS,-0.5*BS,-0.375*BS,0.5*BS,0.5*BS
));
f->addNodeBox(NodeBox(
0.375*BS,-0.3125*BS,-0.5*BS,0.5*BS,0.5*BS,0.5*BS
));
f->addNodeBox(NodeBox(
-0.375*BS,-0.3125*BS,-0.5*BS,0.375*BS,0.5*BS,-0.375*BS
));
f->addNodeBox(NodeBox(
-0.375*BS,-0.3125*BS,0.375*BS,0.375*BS,0.5*BS,0.5*BS
));
f->addNodeBox(NodeBox(
0.1875*BS,-0.3125*BS,-0.5*BS,0.25*BS,0.5*BS,0.5*BS
));
f->addNodeBox(NodeBox(
-0.25*BS,-0.3125*BS,-0.5*BS,-0.1875*BS,0.5*BS,0.5*BS
));
f->addNodeBox(NodeBox(
0.25*BS,-0.0625*BS,-0.0625*BS,0.375*BS,0.0625*BS,0.0625*BS
));
f->addNodeBox(NodeBox(
-0.375*BS,-0.0625*BS,-0.0625*BS,-0.25*BS,0.0625*BS,0.0625*BS
));
}
void content_nodebox_activelockedcrusher(ContentFeatures *f)
{
f->setNodeBox(NodeBox(
-0.5*BS,-0.5*BS,-0.5*BS,0.5*BS,-0.3125*BS,0.5*BS
));
f->addNodeBox(NodeBox(
-0.5*BS,-0.3125*BS,-0.5*BS,-0.375*BS,0.5*BS,0.5*BS
));
f->addNodeBox(NodeBox(
0.375*BS,-0.3125*BS,-0.5*BS,0.5*BS,0.5*BS,0.5*BS
));
f->addNodeBox(NodeBox(
-0.375*BS,-0.3125*BS,-0.5*BS,0.375*BS,0.5*BS,-0.375*BS
));
f->addNodeBox(NodeBox(
-0.375*BS,-0.3125*BS,0.375*BS,0.375*BS,0.5*BS,0.5*BS
));
f->addNodeBox(NodeBox(
-0.0625*BS,-0.3125*BS,-0.5*BS,0.0625*BS,0.5*BS,0.5*BS
));
f->addNodeBox(NodeBox(
-0.375*BS,-0.0625*BS,-0.0625*BS,0.375*BS,0.0625*BS,0.0625*BS
));
}

View File

@ -90,5 +90,9 @@ void content_nodebox_column_cross(ContentFeatures *f);
void content_nodebox_column_cross_base(ContentFeatures *f);
void content_nodebox_column_cross_top(ContentFeatures *f);
void content_nodebox_scaffolding(ContentFeatures *f);
void content_nodebox_crusher(ContentFeatures *f);
void content_nodebox_activecrusher(ContentFeatures *f);
void content_nodebox_lockedcrusher(ContentFeatures *f);
void content_nodebox_activelockedcrusher(ContentFeatures *f);
#endif

View File

@ -374,6 +374,72 @@ private:
float m_src_time;
};
class CrusherNodeMetadata : public NodeMetadata
{
public:
CrusherNodeMetadata();
~CrusherNodeMetadata();
virtual u16 typeId() const;
virtual NodeMetadata* clone();
static NodeMetadata* create(std::istream &is);
virtual void serializeBody(std::ostream &os);
virtual std::wstring infoText();
virtual Inventory* getInventory() {return m_inventory;}
virtual void inventoryModified();
virtual bool step(float dtime, v3s16 pos, ServerEnvironment *env);
virtual bool nodeRemovalDisabled();
virtual std::string getDrawSpecString(Player *player);
virtual std::vector<NodeBox> getNodeBoxes(MapNode &n);
virtual bool import(NodeMetadata *meta);
private:
Inventory *m_inventory;
float m_step_accumulator;
float m_fuel_totaltime;
float m_fuel_time;
float m_src_totaltime;
float m_src_time;
};
class LockingCrusherNodeMetadata : public NodeMetadata
{
public:
LockingCrusherNodeMetadata();
~LockingCrusherNodeMetadata();
virtual u16 typeId() const;
virtual NodeMetadata* clone();
static NodeMetadata* create(std::istream &is);
virtual void serializeBody(std::ostream &os);
virtual std::wstring infoText();
virtual Inventory* getInventory() {return m_inventory;}
virtual void inventoryModified();
virtual bool step(float dtime, v3s16 pos, ServerEnvironment *env);
virtual bool nodeRemovalDisabled();
virtual std::string getDrawSpecString(Player *player);
virtual std::vector<NodeBox> getNodeBoxes(MapNode &n);
virtual bool import(NodeMetadata *meta);
virtual std::string getOwner(){ return m_owner; }
virtual void setOwner(std::string t){ m_owner = t; }
virtual std::string getInventoryOwner(){ return m_inv_owner; }
virtual void setInventoryOwner(std::string t){ m_inv_owner = t; }
private:
Inventory *m_inventory;
float m_step_accumulator;
float m_fuel_totaltime;
float m_fuel_time;
float m_src_totaltime;
float m_src_time;
std::string m_owner;
std::string m_inv_owner;
float m_lock;
};
class LockingFurnaceNodeMetadata : public NodeMetadata
{
public:

View File

@ -36,6 +36,10 @@ struct ToolItemFeatures {
// what type of cooking device this item needs
CookType cook_type;
// the fuel value of this item
std::string crush_result;
// what type of crushing device this item needs
CrushType crush_type;
// the crush value of this item
float fuel_time;
// 0 if inedible, otherwise the value it improves hp by
s16 edible;
@ -73,6 +77,8 @@ struct ToolItemFeatures {
name(""),
cook_result(""),
cook_type(COOK_ANY),
crush_result(""),
crush_type(CRUSH_ANY),
fuel_time(0.0),
edible(0),
drop_count(-1),

View File

@ -281,6 +281,24 @@ InventoryItem *MaterialItem::createCookResult() const
return InventoryItem::deSerialize(is);
}
bool MaterialItem::isCrushable(CrushType type) const
{
ContentFeatures *f = &content_features(m_content);
if (!f)
return false;
if (type != f->crush_type && f->crush_type != CRUSH_ANY)
return false;
if (f->crush_result == "")
return false;
return true;
}
InventoryItem *MaterialItem::createCrushResult() const
{
std::istringstream is(content_features(m_content).crush_result, std::ios::binary);
return InventoryItem::deSerialize(is);
}
bool MaterialItem::isFuel() const
{
return (content_features(m_content).fuel_time != 0.0);
@ -449,6 +467,23 @@ InventoryItem *CraftItem::createCookResult() const
return InventoryItem::create(content_craftitem_features(m_content)->cook_result,1,1,0);
}
bool CraftItem::isCrushable(CrushType type) const
{
CraftItemFeatures *f = content_craftitem_features(m_content);
if (!f)
return false;
if (type != f->crush_type && f->crush_type != CRUSH_ANY)
return false;
if (f->crush_result == CONTENT_IGNORE)
return false;
return true;
}
InventoryItem *CraftItem::createCrushResult() const
{
return InventoryItem::create(content_craftitem_features(m_content)->crush_result,1,1,0);
}
bool CraftItem::isFuel() const
{
return (content_craftitem_features(m_content)->fuel_time != 0.0);
@ -614,6 +649,24 @@ InventoryItem *ToolItem::createCookResult() const
return InventoryItem::deSerialize(is);
}
bool ToolItem::isCrushable(CrushType type) const
{
ToolItemFeatures *f = &content_toolitem_features(m_content);
if (!f)
return false;
if (type != f->crush_type && f->crush_type != CRUSH_ANY)
return false;
if (f->crush_result == "")
return false;
return true;
}
InventoryItem *ToolItem::createCrushResult() const
{
std::istringstream is(content_toolitem_features(m_content).crush_result, std::ios::binary);
return InventoryItem::deSerialize(is);
}
bool ToolItem::isFuel() const
{
return (content_toolitem_features(m_content).fuel_time != 0.0);
@ -1156,6 +1209,18 @@ bool InventoryList::roomForCookedItem(const InventoryItem *item)
return room;
}
bool InventoryList::roomForCrushedItem(const InventoryItem *item)
{
if (!item)
return false;
const InventoryItem *cook = item->createCrushResult();
if (!cook)
return false;
bool room = roomForItem(cook);
delete cook;
return room;
}
InventoryItem * InventoryList::takeItem(u32 i, u32 count)
{
if (count == 0)

View File

@ -135,10 +135,14 @@ public:
// Whether it can be cooked
virtual bool isCookable(CookType type=COOK_ANY) const {return false;}
// Whether it can be crushed
virtual bool isCrushable(CrushType type=CRUSH_ANY) const {return false;}
// Time of cooking
virtual float getCookTime() const {return 3.0;}
// Result of cooking (can randomize)
virtual InventoryItem *createCookResult() const {return NULL;}
// Result of crushing (can randomize)
virtual InventoryItem *createCrushResult() const {return NULL;}
// Whether it can be used as fuel
virtual bool isFuel() const {return false;}
// the fuel time value
@ -223,6 +227,8 @@ public:
*/
bool isCookable(CookType type) const;
InventoryItem *createCookResult() const;
bool isCrushable(CrushType type) const;
InventoryItem *createCrushResult() const;
virtual bool isFuel() const;
virtual float getFuelTime() const;
@ -314,6 +320,8 @@ public:
bool isCookable(CookType type) const;
InventoryItem *createCookResult() const;
bool isCrushable(CrushType type) const;
InventoryItem *createCrushResult() const;
bool isFuel() const;
float getFuelTime() const;
@ -385,6 +393,8 @@ public:
bool isCookable(CookType type) const;
InventoryItem *createCookResult() const;
bool isCrushable(CrushType type) const;
InventoryItem *createCrushResult() const;
bool isFuel() const;
float getFuelTime() const;
/*
@ -632,9 +642,12 @@ public:
// Checks whether there is room for a given item
bool roomForItem(const InventoryItem *item);
// Checks whether there is room for a given item aftr it has been cooked
// Checks whether there is room for a given item after it has been cooked
bool roomForCookedItem(const InventoryItem *item);
// Checks whether there is room for a given item aftr it has been crushed
bool roomForCrushedItem(const InventoryItem *item);
// Takes some items from a slot.
// If there are not enough, takes as many as it can.
// Returns NULL if couldn't take any.

View File

@ -162,6 +162,12 @@ enum CookType
COOK_FURNACE
};
enum CrushType
{
CRUSH_ANY,
CRUSH_CRUSHER
};
/*
Material Type
*/
@ -457,6 +463,11 @@ struct ContentFeatures
// the fuel value of this node
float fuel_time;
// the result of crushing this node
std::string crush_result;
// what type of crushing device this node needs
CrushType crush_type;
// maximum height a plant can grow to
s16 plantgrowth_max_height;
// when CPT_PLANTGROWTH < 8 digging gives this
@ -599,6 +610,8 @@ struct ContentFeatures
unpowered_node = CONTENT_IGNORE;
cook_result = "";
cook_type = COOK_ANY;
crush_result = "";
crush_type = CRUSH_ANY;
fuel_time = 0.0;
plantgrowth_max_height = 1;
plantgrowth_small_dug_node = CONTENT_IGNORE;

View File

@ -821,3 +821,541 @@ bool CampFireNodeMetadata::isActive()
return false;
return true;
}
/*
CrusherNodeMetadata
*/
// Prototype
CrusherNodeMetadata proto_CrusherNodeMetadata;
CrusherNodeMetadata::CrusherNodeMetadata()
{
NodeMetadata::registerType(typeId(), create);
m_inventory = new Inventory();
m_inventory->addList("fuel", 1);
m_inventory->addList("src", 1);
m_inventory->addList("dst", 4);
m_step_accumulator = 0;
m_fuel_totaltime = 0;
m_fuel_time = 0;
m_src_totaltime = 0;
m_src_time = 0;
}
CrusherNodeMetadata::~CrusherNodeMetadata()
{
delete m_inventory;
}
u16 CrusherNodeMetadata::typeId() const
{
return CONTENT_CRUSHER;
}
NodeMetadata* CrusherNodeMetadata::clone()
{
CrusherNodeMetadata *d = new CrusherNodeMetadata();
*d->m_inventory = *m_inventory;
d->m_fuel_totaltime = m_fuel_totaltime;
d->m_fuel_time = m_fuel_time;
d->m_src_totaltime = m_src_totaltime;
d->m_src_time = m_src_time;
return d;
}
NodeMetadata* CrusherNodeMetadata::create(std::istream &is)
{
CrusherNodeMetadata *d = new CrusherNodeMetadata();
d->m_inventory->deSerialize(is);
int temp;
is>>temp;
d->m_fuel_totaltime = (float)temp/10;
is>>temp;
d->m_fuel_time = (float)temp/10;
return d;
}
void CrusherNodeMetadata::serializeBody(std::ostream &os)
{
m_inventory->serialize(os);
os<<itos(m_fuel_totaltime*10)<<" ";
os<<itos(m_fuel_time*10)<<" ";
}
std::wstring CrusherNodeMetadata::infoText()
{
//return "Crusher";
if (m_fuel_time >= m_fuel_totaltime) {
const InventoryList *src_list = m_inventory->getList("src");
assert(src_list);
const InventoryItem *src_item = src_list->getItem(0);
if (src_item && src_item->isCrushable(CRUSH_CRUSHER)) {
InventoryList *dst_list = m_inventory->getList("dst");
if(!dst_list->roomForCrushedItem(src_item))
return narrow_to_wide(gettext("Crusher is overloaded"));
return narrow_to_wide(gettext("Crusher is out of fuel"));
}else{
return narrow_to_wide(gettext("Crusher is inactive"));
}
}else{
std::wstring s = narrow_to_wide(gettext("Crusher is active"));
// Do this so it doesn't always show (0%) for weak fuel
if (m_fuel_totaltime > 3) {
s += L" (";
s += itows(m_fuel_time/m_fuel_totaltime*100);
s += L"%)";
}
return s;
}
}
bool CrusherNodeMetadata::nodeRemovalDisabled()
{
/*
Disable removal if crusher is not empty
*/
InventoryList *list[3] = {m_inventory->getList("src"),
m_inventory->getList("dst"), m_inventory->getList("fuel")};
for (int i = 0; i < 3; i++) {
if (list[i] == NULL)
continue;
if (list[i]->getUsedSlots() == 0)
continue;
return true;
}
return false;
}
void CrusherNodeMetadata::inventoryModified()
{
vlprintf(CN_INFO,"Crusher inventory modification callback");
}
bool CrusherNodeMetadata::step(float dtime, v3s16 pos, ServerEnvironment *env)
{
{
MapNode n = env->getMap().getNodeNoEx(pos).getContent();
if (n.getContent() == CONTENT_CRUSHER_ACTIVE) {
n.param1 = n.param2;
n.setContent(CONTENT_CRUSHER);
env->setPostStepNodeSwap(pos,n);
}
}
if (dtime > 60.0)
vlprintf(CN_INFO,"Crusher stepping a long time (%f)",dtime);
// Update at a fixed frequency
const float interval = 2.0;
m_step_accumulator += dtime;
bool changed = false;
while (m_step_accumulator > interval) {
m_step_accumulator -= interval;
dtime = interval;
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);
bool room_available = false;
if (src_item && src_item->isCrushable(CRUSH_CRUSHER))
room_available = dst_list->roomForCrushedItem(src_item);
// Start only if there are free slots in dst, so that it can
// accomodate any result item
if (room_available) {
m_src_totaltime = 3;
}else{
m_src_time = 0;
m_src_totaltime = 0;
}
/*
If fuel is burning, increment the burn counters.
If item finishes crushing, move it to result.
*/
if (m_fuel_time < m_fuel_totaltime) {
m_fuel_time += dtime;
m_src_time += dtime;
if (m_src_time >= m_src_totaltime && m_src_totaltime > 0.001 && src_item) {
InventoryItem *crushresult = src_item->createCrushResult();
dst_list->addItem(crushresult);
src_list->decrementMaterials(1);
m_src_time = 0;
m_src_totaltime = 0;
}
changed = true;
// If the fuel was not used up this step, just keep burning it
if (m_fuel_time < m_fuel_totaltime)
continue;
}
/*
Get the source again in case it has all burned
*/
src_item = src_list->getItem(0);
/*
If there is no source item, or the source item is not crushable,
or the crusher is still cooking, or the crusher became overloaded, stop loop.
*/
if (
src_item == NULL
|| !room_available
|| m_fuel_time < m_fuel_totaltime
|| dst_list->roomForCrushedItem(src_item) == false
) {
m_step_accumulator = 0;
break;
}
//vlprintf(CN_INFO,"Crusher is out of fuel");
InventoryList *fuel_list = m_inventory->getList("fuel");
assert(fuel_list);
InventoryItem *fuel_item = fuel_list->getItem(0);
if (fuel_item && fuel_item->isFuel()) {
if ((fuel_item->getContent()&CONTENT_CRAFTITEM_MASK) == CONTENT_CRAFTITEM_MASK) {
m_fuel_totaltime = ((CraftItem*)fuel_item)->getFuelTime();
}else if ((fuel_item->getContent()&CONTENT_TOOLITEM_MASK) == CONTENT_TOOLITEM_MASK) {
m_fuel_totaltime = ((ToolItem*)fuel_item)->getFuelTime();
}else{
m_fuel_totaltime = ((MaterialItem*)fuel_item)->getFuelTime();
}
m_fuel_time = 0;
content_t c = fuel_item->getContent();
fuel_list->decrementMaterials(1);
if (c == CONTENT_TOOLITEM_STEELBUCKET_LAVA) {
fuel_list->addItem(0,new ToolItem(CONTENT_TOOLITEM_STEELBUCKET,0,0));
}
changed = true;
}else{
m_step_accumulator = 0;
}
}
return changed;
}
std::string CrusherNodeMetadata::getDrawSpecString(Player *player)
{
std::string spec("size[8,9]");
spec += "list[current_name;fuel;2,3;1,1;]";
spec += "ring[2,3;1;#FF0000;";
float v = 0;
if (m_fuel_totaltime > 0.0)
v = 100.0-((100.0/m_fuel_totaltime)*m_fuel_time);
spec += itos((int)v);
spec += "]";
spec += "list[current_name;src;2,1;1,1;]";
spec += "list[current_name;dst;5,1;2,2;]";
spec += "list[current_player;main;0,5;8,4;]";
return spec;
}
std::vector<NodeBox> CrusherNodeMetadata::getNodeBoxes(MapNode &n)
{
std::vector<NodeBox> boxes;
boxes.clear();
if (m_fuel_time < m_fuel_totaltime) {
boxes.push_back(NodeBox(
-0.3125*BS,-0.25*BS,-0.4*BS,0.3125*BS,0.125*BS,-0.3*BS
));
}
return transformNodeBox(n,boxes);
}
bool CrusherNodeMetadata::import(NodeMetadata *meta)
{
if (meta->typeId() != CONTENT_LOCKABLE_CRUSHER)
return false;
LockingCrusherNodeMetadata *l = (LockingCrusherNodeMetadata*)meta;
*m_inventory = *l->getInventory();
return true;
}
/*
LockingCrusherNodeMetadata
*/
// Prototype
LockingCrusherNodeMetadata proto_LockingCrusherNodeMetadata;
LockingCrusherNodeMetadata::LockingCrusherNodeMetadata()
{
NodeMetadata::registerType(typeId(), create);
m_inventory = new Inventory();
m_inventory->addList("fuel", 1);
m_inventory->addList("src", 1);
m_inventory->addList("dst", 4);
m_step_accumulator = 0;
m_fuel_totaltime = 0;
m_fuel_time = 0;
m_src_totaltime = 0;
m_src_time = 0;
m_lock = 0;
}
LockingCrusherNodeMetadata::~LockingCrusherNodeMetadata()
{
delete m_inventory;
}
u16 LockingCrusherNodeMetadata::typeId() const
{
return CONTENT_LOCKABLE_CRUSHER;
}
NodeMetadata* LockingCrusherNodeMetadata::clone()
{
LockingCrusherNodeMetadata *d = new LockingCrusherNodeMetadata();
*d->m_inventory = *m_inventory;
d->m_fuel_totaltime = m_fuel_totaltime;
d->m_fuel_time = m_fuel_time;
d->m_src_totaltime = m_src_totaltime;
d->m_src_time = m_src_time;
return d;
}
NodeMetadata* LockingCrusherNodeMetadata::create(std::istream &is)
{
LockingCrusherNodeMetadata *d = new LockingCrusherNodeMetadata();
d->m_inventory->deSerialize(is);
d->setOwner(deSerializeString(is));
d->setInventoryOwner(deSerializeString(is));
int temp;
is>>temp;
d->m_fuel_totaltime = (float)temp/10;
is>>temp;
d->m_fuel_time = (float)temp/10;
is>>temp;
d->m_lock = (float)temp/10;
return d;
}
void LockingCrusherNodeMetadata::serializeBody(std::ostream &os)
{
m_inventory->serialize(os);
os<<serializeString(m_owner);
os<<serializeString(m_inv_owner);
os<<itos(m_fuel_totaltime*10)<<" ";
os<<itos(m_fuel_time*10)<<" ";
os<<itos(m_lock*10)<<" ";
}
std::wstring LockingCrusherNodeMetadata::infoText()
{
char buff[256];
char* s;
char e[128];
std::string ostr = m_owner;
e[0] = 0;
if (m_inv_owner != "")
ostr += ","+m_inv_owner;
if (m_fuel_time >= m_fuel_totaltime) {
const InventoryList *src_list = m_inventory->getList("src");
assert(src_list);
const InventoryItem *src_item = src_list->getItem(0);
if(src_item && src_item->isCrushable(CRUSH_CRUSHER)) {
InventoryList *dst_list = m_inventory->getList("dst");
if (!dst_list->roomForCrushedItem(src_item)) {
s = gettext("Locking Crusher is overloaded");
}else{
s = gettext("Locking Crusher is out of fuel");
}
}else{
s = gettext("Locking Crusher is inactive");
}
}else{
s = gettext("Locking Crusher is active");
// Do this so it doesn't always show (0%) for weak fuel
if (m_fuel_totaltime > 3) {
uint32_t tt = m_fuel_time/m_fuel_totaltime*100;
snprintf(e,128, " (%d%%)",tt);
}
}
snprintf(buff,256,"%s (%s)%s",s,ostr.c_str(),e);
return narrow_to_wide(buff);
}
bool LockingCrusherNodeMetadata::nodeRemovalDisabled()
{
/*
Disable removal if crusher is not empty
*/
InventoryList *list[3] = {m_inventory->getList("src"),
m_inventory->getList("dst"), m_inventory->getList("fuel")};
for(int i = 0; i < 3; i++) {
if(list[i] == NULL)
continue;
if(list[i]->getUsedSlots() == 0)
continue;
return true;
}
return false;
}
void LockingCrusherNodeMetadata::inventoryModified()
{
vlprintf(CN_INFO,"LockingCrusher inventory modification callback");
}
bool LockingCrusherNodeMetadata::step(float dtime, v3s16 pos, ServerEnvironment *env)
{
{
MapNode n = env->getMap().getNodeNoEx(pos);
if (n.getContent() == CONTENT_LOCKABLE_CRUSHER_ACTIVE) {
n.param1 = n.param2;
n.setContent(CONTENT_LOCKABLE_CRUSHER);
env->setPostStepNodeSwap(pos,n);
}
}
if (dtime > 60.0)
vlprintf(CN_INFO,"LockingCrusher stepping a long time (%f)",dtime);
// Update at a fixed frequency
const float interval = 2.0;
m_step_accumulator += dtime;
bool changed = false;
while(m_step_accumulator > interval) {
m_step_accumulator -= interval;
dtime = interval;
//infostream<<"Crusher 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);
bool room_available = false;
if (src_item && src_item->isCrushable(CRUSH_CRUSHER)) {
room_available = dst_list->roomForCrushedItem(src_item);
m_lock = 300.0;
changed = true;
}else if (m_lock < 0.0) {
setInventoryOwner("");
changed = true;
}else{
m_lock -= dtime;
changed = true;
}
// Start only if there are free slots in dst, so that it can
// accomodate any result item
if (room_available) {
m_src_totaltime = 3;
}else{
m_src_time = 0;
m_src_totaltime = 0;
}
/*
If fuel is burning, increment the burn counters.
If item finishes cooking, move it to result.
*/
if (m_fuel_time < m_fuel_totaltime) {
m_fuel_time += dtime;
m_src_time += dtime;
if (m_src_time >= m_src_totaltime && m_src_totaltime > 0.001 && src_item) {
InventoryItem *crushresult = src_item->createCrushResult();
dst_list->addItem(crushresult);
src_list->decrementMaterials(1);
m_src_time = 0;
m_src_totaltime = 0;
}
changed = true;
// If the fuel was not used up this step, just keep burning it
if (m_fuel_time < m_fuel_totaltime)
continue;
}
/*
Get the source again in case it has all burned
*/
src_item = src_list->getItem(0);
/*
If there is no source item, or the source item is not crushable,
or the crusher is still cooking, or the crusher became overloaded, stop loop.
*/
if (
src_item == NULL
|| !room_available ||
m_fuel_time < m_fuel_totaltime
|| dst_list->roomForCrushedItem(src_item) == false
) {
m_step_accumulator = 0;
break;
}
//vlprintf(CN_INFO,"Crusher is out of fuel");
InventoryList *fuel_list = m_inventory->getList("fuel");
assert(fuel_list);
InventoryItem *fuel_item = fuel_list->getItem(0);
if (fuel_item && fuel_item->isFuel()) {
if ((fuel_item->getContent()&CONTENT_CRAFTITEM_MASK) == CONTENT_CRAFTITEM_MASK) {
m_fuel_totaltime = ((CraftItem*)fuel_item)->getFuelTime();
}else if ((fuel_item->getContent()&CONTENT_TOOLITEM_MASK) == CONTENT_TOOLITEM_MASK) {
m_fuel_totaltime = ((ToolItem*)fuel_item)->getFuelTime();
}else{
m_fuel_totaltime = ((MaterialItem*)fuel_item)->getFuelTime();
}
m_fuel_time = 0;
content_t c = fuel_item->getContent();
fuel_list->decrementMaterials(1);
if (c == CONTENT_TOOLITEM_STEELBUCKET_LAVA) {
fuel_list->addItem(0,new ToolItem(CONTENT_TOOLITEM_STEELBUCKET,0,0));
}
changed = true;
}else{
m_step_accumulator = 0;
}
}
return changed;
}
std::string LockingCrusherNodeMetadata::getDrawSpecString(Player *player)
{
std::string spec("size[8,9]");
spec += "list[current_name;fuel;2,3;1,1;]";
spec += "ring[2,3;1;#FF0000;";
float v = 0;
if (m_fuel_totaltime > 0.0)
v = 100.0-((100.0/m_fuel_totaltime)*m_fuel_time);
spec += itos((int)v);
spec += "]";
spec += "list[current_name;src;2,1;1,1;]";
spec += "list[current_name;dst;5,1;2,2;]";
spec += "list[current_player;main;0,5;8,4;]";
return spec;
}
std::vector<NodeBox> LockingCrusherNodeMetadata::getNodeBoxes(MapNode &n)
{
std::vector<NodeBox> boxes;
boxes.clear();
if (m_fuel_time < m_fuel_totaltime) {
boxes.push_back(NodeBox(
-0.3125*BS,-0.25*BS,-0.4*BS,0.3125*BS,0.125*BS,-0.3*BS
));
}
return transformNodeBox(n,boxes);
}
bool LockingCrusherNodeMetadata::import(NodeMetadata *meta)
{
if (meta->typeId() != CONTENT_CRUSHER)
return false;
CrusherNodeMetadata *l = (CrusherNodeMetadata*)meta;
*m_inventory = *l->getInventory();
return true;
}

View File

@ -3084,6 +3084,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|| meta->typeId() == CONTENT_LOCKABLE_SIGN_WALL
|| meta->typeId() == CONTENT_LOCKABLE_SIGN_UD
|| meta->typeId() == CONTENT_LOCKABLE_FURNACE
|| meta->typeId() == CONTENT_LOCKABLE_CRUSHER
|| meta->typeId() == CONTENT_FLAG
|| meta->typeId() == CONTENT_FLAG_BLUE
|| meta->typeId() == CONTENT_FLAG_GREEN
@ -4403,6 +4404,11 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
std::string name = lfm->getInventoryOwner();
if (name != "" && name != player->getName() && lfm->getOwner() != player->getName())
return;
}else if (meta->typeId() == CONTENT_LOCKABLE_CRUSHER) {
LockingCrusherNodeMetadata *lfm = (LockingCrusherNodeMetadata*)meta;
std::string name = lfm->getInventoryOwner();
if (name != "" && name != player->getName() && lfm->getOwner() != player->getName())
return;
}else if (meta->typeId() == CONTENT_SAFE) {
SafeNodeMetadata *sm = (SafeNodeMetadata*)meta;
std::string name = sm->getInventoryOwner();