forked from oerkki/voxelands
addition - crusher
This commit is contained in:
parent
7517420b5a
commit
c9b31e8826
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 |
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
));
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue