/* Minetest-c55 Copyright (C) 2010-2011 celeron55, Perttu Ahola This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "content_nodemeta.h" #include "inventory.h" #include "content_mapnode.h" #include "log.h" /* SignNodeMetadata */ // Prototype SignNodeMetadata proto_SignNodeMetadata(""); SignNodeMetadata::SignNodeMetadata(std::string text): m_text(text) { NodeMetadata::registerType(typeId(), create); } u16 SignNodeMetadata::typeId() const { return CONTENT_SIGN_WALL; } NodeMetadata* SignNodeMetadata::create(std::istream &is) { std::string text = deSerializeString(is); return new SignNodeMetadata(text); } NodeMetadata* SignNodeMetadata::clone() { return new SignNodeMetadata(m_text); } void SignNodeMetadata::serializeBody(std::ostream &os) { os<addList("0", 8*4); } ChestNodeMetadata::~ChestNodeMetadata() { delete m_inventory; } u16 ChestNodeMetadata::typeId() const { return CONTENT_CHEST; } NodeMetadata* ChestNodeMetadata::create(std::istream &is) { ChestNodeMetadata *d = new ChestNodeMetadata(); d->m_inventory->deSerialize(is); return d; } NodeMetadata* ChestNodeMetadata::clone() { ChestNodeMetadata *d = new ChestNodeMetadata(); *d->m_inventory = *m_inventory; return d; } void ChestNodeMetadata::serializeBody(std::ostream &os) { m_inventory->serialize(os); } std::string ChestNodeMetadata::infoText() { return "Chest"; } bool ChestNodeMetadata::nodeRemovalDisabled() { /* Disable removal if chest contains something */ InventoryList *list = m_inventory->getList("0"); if(list == NULL) return false; if(list->getUsedSlots() == 0) return false; return true; } std::string ChestNodeMetadata::getInventoryDrawSpecString() { return "invsize[8,9;]" "list[current_name;0;0,0;8,4;]" "list[current_player;main;0,5;8,4;]"; } /* LockingChestNodeMetadata */ // Prototype LockingChestNodeMetadata proto_LockingChestNodeMetadata; LockingChestNodeMetadata::LockingChestNodeMetadata() { NodeMetadata::registerType(typeId(), create); m_inventory = new Inventory(); m_inventory->addList("0", 8*4); } LockingChestNodeMetadata::~LockingChestNodeMetadata() { delete m_inventory; } u16 LockingChestNodeMetadata::typeId() const { return CONTENT_LOCKABLE_CHEST; } NodeMetadata* LockingChestNodeMetadata::create(std::istream &is) { LockingChestNodeMetadata *d = new LockingChestNodeMetadata(); d->setOwner(deSerializeString(is)); d->m_inventory->deSerialize(is); return d; } NodeMetadata* LockingChestNodeMetadata::clone() { LockingChestNodeMetadata *d = new LockingChestNodeMetadata(); *d->m_inventory = *m_inventory; return d; } void LockingChestNodeMetadata::serializeBody(std::ostream &os) { os<serialize(os); } std::string LockingChestNodeMetadata::infoText() { return "Locking Chest"; } bool LockingChestNodeMetadata::nodeRemovalDisabled() { /* Disable removal if chest contains something */ InventoryList *list = m_inventory->getList("0"); if(list == NULL) return false; if(list->getUsedSlots() == 0) return false; return true; } std::string LockingChestNodeMetadata::getInventoryDrawSpecString() { return "invsize[8,9;]" "list[current_name;0;0,0;8,4;]" "list[current_player;main;0,5;8,4;]"; } /* FurnaceNodeMetadata */ // Prototype FurnaceNodeMetadata proto_FurnaceNodeMetadata; FurnaceNodeMetadata::FurnaceNodeMetadata() { 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; } FurnaceNodeMetadata::~FurnaceNodeMetadata() { delete m_inventory; } u16 FurnaceNodeMetadata::typeId() const { return CONTENT_FURNACE; } NodeMetadata* FurnaceNodeMetadata::clone() { FurnaceNodeMetadata *d = new FurnaceNodeMetadata(); *d->m_inventory = *m_inventory; return d; } NodeMetadata* FurnaceNodeMetadata::create(std::istream &is) { FurnaceNodeMetadata *d = new FurnaceNodeMetadata(); 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 FurnaceNodeMetadata::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->isCookable()) { InventoryList *dst_list = m_inventory->getList("dst"); if(!dst_list->roomForCookedItem(src_item)) return "Furnace is overloaded"; return "Furnace is out of fuel"; } else return "Furnace is inactive"; } else { std::string s = "Furnace is active"; // Do this so it doesn't always show (0%) for weak fuel if(m_fuel_totaltime > 3) { s += " ("; s += itos(m_fuel_time/m_fuel_totaltime*100); s += "%)"; } return s; } } bool FurnaceNodeMetadata::nodeRemovalDisabled() { /* Disable removal if furnace 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 FurnaceNodeMetadata::inventoryModified() { infostream<<"Furnace inventory modification callback"< 60.0) infostream<<"Furnace stepping a long time ("< interval) { m_step_accumulator -= interval; dtime = interval; //infostream<<"Furnace 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->isCookable()) room_available = dst_list->roomForCookedItem(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 cooking, move it to result. */ if(m_fuel_time < m_fuel_totaltime) { //infostream<<"Furnace is active"<= m_src_totaltime && m_src_totaltime > 0.001 && src_item) { InventoryItem *cookresult = src_item->createCookResult(); dst_list->addItem(cookresult); 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 cookable, or the furnace is still cooking, or the furnace became overloaded, stop loop. */ if(src_item == NULL || !room_available || m_fuel_time < m_fuel_totaltime || dst_list->roomForCookedItem(src_item) == false) { m_step_accumulator = 0; break; } //infostream<<"Furnace is out of fuel"<getList("fuel"); assert(fuel_list); const InventoryItem *fuel_item = fuel_list->getItem(0); if(ItemSpec(ITEM_MATERIAL, CONTENT_TREE).checkItem(fuel_item)) { m_fuel_totaltime = 30; m_fuel_time = 0; fuel_list->decrementMaterials(1); changed = true; } else if(ItemSpec(ITEM_MATERIAL, CONTENT_JUNGLETREE).checkItem(fuel_item)) { m_fuel_totaltime = 30; m_fuel_time = 0; fuel_list->decrementMaterials(1); changed = true; } else if(ItemSpec(ITEM_MATERIAL, CONTENT_FENCE).checkItem(fuel_item)) { m_fuel_totaltime = 30/2; m_fuel_time = 0; fuel_list->decrementMaterials(1); changed = true; } else if(ItemSpec(ITEM_MATERIAL, CONTENT_WOOD).checkItem(fuel_item)) { m_fuel_totaltime = 30/4; m_fuel_time = 0; fuel_list->decrementMaterials(1); changed = true; } else if(ItemSpec(ITEM_MATERIAL, CONTENT_BOOKSHELF).checkItem(fuel_item)) { m_fuel_totaltime = 30/4; m_fuel_time = 0; fuel_list->decrementMaterials(1); changed = true; } else if(ItemSpec(ITEM_MATERIAL, CONTENT_LEAVES).checkItem(fuel_item)) { m_fuel_totaltime = 30/16; m_fuel_time = 0; fuel_list->decrementMaterials(1); changed = true; } else if(ItemSpec(ITEM_MATERIAL, CONTENT_PAPYRUS).checkItem(fuel_item)) { m_fuel_totaltime = 30/32; m_fuel_time = 0; fuel_list->decrementMaterials(1); changed = true; } else if(ItemSpec(ITEM_MATERIAL, CONTENT_JUNGLEGRASS).checkItem(fuel_item)) { m_fuel_totaltime = 30/32; m_fuel_time = 0; fuel_list->decrementMaterials(1); changed = true; } else if(ItemSpec(ITEM_MATERIAL, CONTENT_CACTUS).checkItem(fuel_item)) { m_fuel_totaltime = 30/4; m_fuel_time = 0; fuel_list->decrementMaterials(1); changed = true; } else if(ItemSpec(ITEM_CRAFT, "Stick").checkItem(fuel_item)) { m_fuel_totaltime = 30/4/4; m_fuel_time = 0; fuel_list->decrementMaterials(1); changed = true; } else if(ItemSpec(ITEM_CRAFT, "lump_of_coal").checkItem(fuel_item)) { m_fuel_totaltime = 40; m_fuel_time = 0; fuel_list->decrementMaterials(1); changed = true; } else { //infostream<<"No fuel found"<