diff --git a/src/content_mapnode.h b/src/content_mapnode.h index 5ec5939..ae96edc 100644 --- a/src/content_mapnode.h +++ b/src/content_mapnode.h @@ -292,10 +292,7 @@ MapNode mapnode_translate_to_internal(MapNode n_from, u8 version); #define CONTENT_COUCH_CHAIR_BLACK 0x865 #define CONTENT_CAULDRON 0x866 #define CONTENT_CRUSHER 0x867 -#define CONTENT_CRUSHER_ACTIVE 0x868 -#define CONTENT_LOCKABLE_CRUSHER 0x869 -#define CONTENT_LOCKABLE_CRUSHER_ACTIVE 0x86A -// FREE 86B-86F +// FREE 868-86F #define CONTENT_FLAG 0x870 #define CONTENT_FLAG_BLUE 0x871 #define CONTENT_FLAG_GREEN 0x872 diff --git a/src/content_mapnode_special.cpp b/src/content_mapnode_special.cpp index 8fdc440..995fb9a 100644 --- a/src/content_mapnode_special.cpp +++ b/src/content_mapnode_special.cpp @@ -1457,71 +1457,10 @@ void content_mapnode_special(bool repeat) 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); f->description = gettext("Nyan Cat"); diff --git a/src/content_nodemeta.h b/src/content_nodemeta.h index e2e97cf..66b38d0 100644 --- a/src/content_nodemeta.h +++ b/src/content_nodemeta.h @@ -392,52 +392,24 @@ public: virtual std::string getDrawSpecString(Player *player); virtual std::vector 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 getNodeBoxes(MapNode &n); - - virtual bool import(NodeMetadata *meta); - - virtual std::string getOwner(){ return m_owner; } + virtual std::string getOwner(); 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; } + virtual std::string getInventoryOwner(); + virtual void setInventoryOwner(std::string t){ m_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; + float m_active_timer; + float m_burn_counter; + float m_cook_timer; + float m_step_interval; std::string m_owner; - std::string m_inv_owner; - float m_lock; + bool m_is_locked; + bool m_is_expanded; + bool m_is_exo; + float m_cook_upgrade; + float m_burn_upgrade; + uint16_t m_expanded_slot_id; }; class LockingFurnaceNodeMetadata : public NodeMetadata diff --git a/src/nodemeta/content_nodemeta_cooking.cpp b/src/nodemeta/content_nodemeta_cooking.cpp index 74939df..a865921 100644 --- a/src/nodemeta/content_nodemeta_cooking.cpp +++ b/src/nodemeta/content_nodemeta_cooking.cpp @@ -836,13 +836,21 @@ CrusherNodeMetadata::CrusherNodeMetadata() m_inventory = new Inventory(); m_inventory->addList("fuel", 1); m_inventory->addList("src", 1); - m_inventory->addList("dst", 4); + m_inventory->addList("main", 4); + m_inventory->addList("upgrades", 2); - m_step_accumulator = 0; - m_fuel_totaltime = 0; - m_fuel_time = 0; - m_src_totaltime = 0; - m_src_time = 0; + m_active_timer = 0.0; + m_burn_counter = 0; + m_cook_timer = 0.0; + m_step_interval = 1.0; + m_is_locked = false; + m_is_expanded = false; + m_is_exo = false; + m_cook_upgrade = 1.0; + m_burn_upgrade = 1.0; + m_expanded_slot_id = 0; + + inventoryModified(); } CrusherNodeMetadata::~CrusherNodeMetadata() { @@ -856,66 +864,107 @@ 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; + + d->m_active_timer = m_active_timer; + d->m_burn_counter = m_burn_counter; + d->m_cook_timer = m_cook_timer; + d->m_step_interval = m_step_interval; + d->m_is_locked = m_is_locked; + d->m_is_expanded = m_is_expanded; + d->m_is_exo = m_is_exo; + d->m_cook_upgrade = m_cook_upgrade; + d->m_burn_upgrade = m_burn_upgrade; + d->m_expanded_slot_id = m_expanded_slot_id; + return d; } NodeMetadata* CrusherNodeMetadata::create(std::istream &is) { + std::string s; CrusherNodeMetadata *d = new CrusherNodeMetadata(); - d->m_inventory->deSerialize(is); + d->setOwner(deSerializeString(is)); - int temp; - is>>temp; - d->m_fuel_totaltime = (float)temp/10; - is>>temp; - d->m_fuel_time = (float)temp/10; + s = deSerializeString(is); + d->m_active_timer = mystof(s); + + s = deSerializeString(is); + d->m_burn_counter = mystoi(s); + + s = deSerializeString(is); + d->m_cook_timer = mystof(s); + + s = deSerializeString(is); + d->m_step_interval = mystof(s); + + s = deSerializeString(is); + d->m_is_locked = !!mystoi(s); + + s = deSerializeString(is); + d->m_is_expanded = !!mystoi(s); + + s = deSerializeString(is); + d->m_is_exo = !!mystoi(s); + + s = deSerializeString(is); + d->m_cook_upgrade = mystof(s); + + s = deSerializeString(is); + d->m_burn_upgrade = mystof(s); + + s = deSerializeString(is); + d->m_expanded_slot_id = mystoi(s); + + if (d->m_is_expanded) { + delete d->m_inventory; + d->m_inventory = new Inventory(); + d->m_inventory->addList("fuel", 1); + d->m_inventory->addList("src", 1); + d->m_inventory->addList("main", 18); + d->m_inventory->addList("upgrades", 2); + } + d->m_inventory->deSerialize(is); + d->inventoryModified(); return d; } void CrusherNodeMetadata::serializeBody(std::ostream &os) { + os<serialize(os); - os<= 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")); - } + char buff[256]; + if (m_is_locked) { + snprintf(buff, 256, gettext("Locked Crusher owned by '%s'"), m_owner.c_str()); + }else if (m_is_exo) { + snprintf(buff, 256, gettext("Exo Crusher")); }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; + snprintf(buff, 256, gettext("Crusher")); } + return narrow_to_wide(buff); } 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")}; + InventoryList *list[3] = { + m_inventory->getList("src"), + m_inventory->getList("main"), + m_inventory->getList("fuel") + }; for (int i = 0; i < 3; i++) { if (list[i] == NULL) @@ -929,124 +978,267 @@ bool CrusherNodeMetadata::nodeRemovalDisabled() } void CrusherNodeMetadata::inventoryModified() { - vlprintf(CN_INFO,"Crusher inventory modification callback"); + int i; + int k; + int a[3] = {1,1,1}; + int b[3] = {0,0,0}; + Inventory *inv; + InventoryList *il; + InventoryList *im; + InventoryItem *itm; + InventoryList *l = m_inventory->getList("upgrades"); + InventoryList *m = m_inventory->getList("main"); + if (!l || !m) + return; + + for (i=0; i<2; i++) { + itm = l->getItem(i); + if (!itm) + continue; + if (itm->getContent() == CONTENT_CHEST) { + if (m_is_expanded) { + b[0] = 1; + continue; + } + if (m_is_exo) + continue; + inv = new Inventory(); + inv->addList("upgrades", 2); + inv->addList("main", 36); + il = inv->getList("upgrades"); + im = inv->getList("main"); + if (!il || !im) { + delete inv; + continue; + } + for (k=0; k<2; k++) { + itm = l->changeItem(k,NULL); + if (itm) + il->addItem(k,itm); + } + for (k=0; k<18; k++) { + itm = m->changeItem(k,NULL); + if (itm) + im->addItem(k,itm); + } + delete m_inventory; + m_inventory = inv; + l = il; + m = im; + a[2] = 0; + b[0] = 1; + m_is_expanded = true; + m_expanded_slot_id = i; + }else if (itm->getContent() == CONTENT_CRAFTITEM_PADLOCK) { + if (m_is_exo) + continue; + a[2] = 0; + b[1] = 1; + m_is_locked = true; + }else if (itm->getContent() == CONTENT_CRAFTITEM_OERKKI_DUST) { + if (m_is_exo) { + b[2] = 1; + continue; + } + if (m->getUsedSlots() != 0) + continue; + if (l->getUsedSlots() != 1) + continue; + if (m_is_locked) + continue; + if (m_is_expanded) + continue; + m_is_exo = true; + a[0] = 0; + a[1] = 0; + b[2] = 1; + } + } + + if (m_is_expanded && !b[0]) { + inv = new Inventory(); + inv->addList("upgrades", 2); + inv->addList("main", 18); + il = inv->getList("upgrades"); + im = inv->getList("main"); + if (!il || !im) { + delete inv; + }else{ + for (k=0; k<2; k++) { + itm = l->changeItem(k,NULL); + if (itm) + il->addItem(k,itm); + } + for (k=0; k<36; k++) { + itm = m->changeItem(k,NULL); + if (itm) { + if (k > 17) { + im->addItem(itm); + }else{ + im->addItem(k,itm); + } + } + } + delete m_inventory; + m_inventory = inv; + l = il; + m = im; + m_is_expanded = false; + } + } + + if (m_is_locked && !b[1]) + m_is_locked = false; + + if (m_is_exo && !b[2]) + m_is_exo = false; + + if (m_is_expanded || m_is_locked || m->getUsedSlots() != 0) + a[2] = 0; + + l->clearAllowed(); + if (a[0]) + l->addAllowed(CONTENT_CHEST); + if (a[1]) + l->addAllowed(CONTENT_CRAFTITEM_PADLOCK); + if (a[2]) + l->addAllowed(CONTENT_CRAFTITEM_OERKKI_DUST); } 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); - } - } + float cook_time; + bool changed = false; + bool is_cooking; + bool cook_ongoing; + bool room_available; + InventoryList *dst_list; + InventoryList *src_list; + InventoryItem *src_item; + InventoryList *fuel_list; + InventoryItem *fuel_item; 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); + if (m_is_exo) { + Player *p = env->getPlayer(m_owner.c_str()); + if (!p) + return false; + dst_list = p->inventory.getList("exo"); + }else{ + dst_list = m_inventory->getList("dst"); + } + if (!dst_list) + return false; - InventoryList *src_list = m_inventory->getList("src"); - assert(src_list); - InventoryItem *src_item = src_list->getItem(0); + src_list = m_inventory->getList("src"); + if (!src_list) + return false; - bool room_available = false; + m_active_timer += dtime; - if (src_item && src_item->isCrushable(CRUSH_CRUSHER)) - room_available = dst_list->roomForCrushedItem(src_item); + if (m_cook_upgrade < 1.0) + m_cook_upgrade = 1.0; + if (m_burn_upgrade < 1.0) + m_burn_upgrade = 1.0; - // 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; - } + /* cook_upgrade/cook_time determines time to cook one item */ + /* burn_upgrade/burn_time determines number of items that fuel can cook */ - /* - 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; + cook_time = 4.0/m_cook_upgrade; + if (cook_time < 0.1) + cook_time = 0.1; - // If the fuel was not used up this step, just keep burning it - if (m_fuel_time < m_fuel_totaltime) - continue; - } + if (cook_time < m_step_interval) + m_step_interval = cook_time; + + while (m_active_timer > m_step_interval) { + m_active_timer -= m_step_interval; + + is_cooking = false; + cook_ongoing = false; + room_available = false; - /* - Get the source again in case it has all burned - */ src_item = src_list->getItem(0); + if (src_item && src_item->isCrushable(CRUSH_CRUSHER)) { + is_cooking = true; + room_available = dst_list->roomForCrushedItem(src_item); + if (room_available && src_item->getCount() > 1) + cook_ongoing = true; + }else{ + m_cook_timer = 0.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; + if (m_cook_timer > cook_time) + m_cook_timer = cook_time; + + if (m_burn_counter <= 0.0 && cook_ongoing) { + fuel_list = m_inventory->getList("fuel"); + if (!fuel_list) + break; + fuel_item = fuel_list->getItem(0); + if (fuel_item && fuel_item->isFuel()) { + content_t c = fuel_item->getContent(); + if ((c&CONTENT_CRAFTITEM_MASK) == CONTENT_CRAFTITEM_MASK) { + m_burn_counter = ((CraftItem*)fuel_item)->getFuelTime(); + }else if ((c&CONTENT_TOOLITEM_MASK) == CONTENT_TOOLITEM_MASK) { + m_burn_counter = ((ToolItem*)fuel_item)->getFuelTime(); + }else{ + m_burn_counter = ((MaterialItem*)fuel_item)->getFuelTime(); + } + fuel_list->decrementMaterials(1); + if (c == CONTENT_TOOLITEM_STEELBUCKET_LAVA) { + fuel_list->addItem(0,new ToolItem(CONTENT_TOOLITEM_STEELBUCKET,0,0)); + } + m_burn_counter *= m_burn_upgrade; + changed = true; + } + } + + if (m_burn_counter <= 0.0) { + m_active_timer = 0.0; + m_burn_counter = 0.0; break; } - //vlprintf(CN_INFO,"Crusher is out of fuel"); + m_burn_counter -= m_step_interval; - 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(); + if (!is_cooking) { + m_cook_timer = 0.0; + continue; + } + + m_cook_timer += m_step_interval; + + if (m_cook_timer >= cook_time) { + m_cook_timer -= cook_time; + if (src_item && src_item->isCrushable(CRUSH_CRUSHER)) { + InventoryItem *crushresult = src_item->createCrushResult(); + dst_list->addItem(crushresult); + src_list->decrementMaterials(1); + changed = true; } - 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) { + float cook_time; + + if (m_cook_upgrade < 1.0) + m_cook_upgrade = 1.0; + cook_time = 4.0/m_cook_upgrade; + if (cook_time < 0.1) + cook_time = 0.1; + 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); + if (m_burn_counter > 0.0 && m_cook_timer > 0.0) + v = 100.0-((100.0/cook_time)*m_cook_timer); spec += itos((int)v); spec += "]"; spec += "list[current_name;src;2,1;1,1;]"; @@ -1059,7 +1251,7 @@ std::vector CrusherNodeMetadata::getNodeBoxes(MapNode &n) std::vector boxes; boxes.clear(); - if (m_fuel_time < m_fuel_totaltime) { + if (m_burn_counter > 0.0) { boxes.push_back(NodeBox( -0.3125*BS,-0.25*BS,-0.4*BS,0.3125*BS,0.125*BS,-0.3*BS )); @@ -1067,295 +1259,15 @@ std::vector CrusherNodeMetadata::getNodeBoxes(MapNode &n) return transformNodeBox(n,boxes); } -bool CrusherNodeMetadata::import(NodeMetadata *meta) +std::string CrusherNodeMetadata::getOwner() { - if (meta->typeId() != CONTENT_LOCKABLE_CRUSHER) - return false; - LockingCrusherNodeMetadata *l = (LockingCrusherNodeMetadata*)meta; - *m_inventory = *l->getInventory(); - return true; + if (m_is_locked) + return m_owner; + return ""; } - -/* - LockingCrusherNodeMetadata -*/ - -// Prototype -LockingCrusherNodeMetadata proto_LockingCrusherNodeMetadata; - -LockingCrusherNodeMetadata::LockingCrusherNodeMetadata() +std::string CrusherNodeMetadata::getInventoryOwner() { - 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<= 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="<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 LockingCrusherNodeMetadata::getNodeBoxes(MapNode &n) -{ - std::vector 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; + if (m_is_locked) + return m_owner; + return ""; } diff --git a/src/server.cpp b/src/server.cpp index ddabff4..083be51 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -3087,7 +3087,6 @@ 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 @@ -3098,6 +3097,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) || meta->typeId() == CONTENT_FLAG_BLACK || meta->typeId() == CONTENT_SAFE ) + && meta->getOwner() != "" && meta->getOwner() != player->getName() ) { infostream<<"Player "<getName()<<" cannot remove node: not node owner"<typeId() == CONTENT_LOCKABLE_CHEST_DEPRECATED) { + if (meta->typeId() == CONTENT_CHEST) { + ChestNodeMetadata *lcm = (ChestNodeMetadata*)meta; + if (lcm->getInventoryOwner() != "" && lcm->getInventoryOwner() != player->getName()) + return; + }else if (meta->typeId() == CONTENT_CRUSHER) { + CrusherNodeMetadata *lcm = (CrusherNodeMetadata*)meta; + if (lcm->getInventoryOwner() != "" && lcm->getInventoryOwner() != player->getName()) + return; + }else if (meta->typeId() == CONTENT_LOCKABLE_CHEST_DEPRECATED) { LockingDeprecatedChestNodeMetadata *lcm = (LockingDeprecatedChestNodeMetadata*)meta; if (lcm->getInventoryOwner() != player->getName()) return; @@ -4407,11 +4415,6 @@ 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();