Merged 2 branches because they relied on each other.

This one contains these changes from main c55:
* Adds a function to check if there is room for a specific item
* Using that, you can now pick up rats if you have a full inventory and a not full rat stack
* Furnace would cook only 1 item if that item used the last available result slot, now it will continue
* Furnace will say it's overloaded
* Furnace won't wait until the next step to start on the next item
 - This caused small fuels to cook slower than meant to
 - Also caused furnaces to say they were out of fuel after finishing the last fuel item
This commit is contained in:
JacobF 2011-08-25 19:27:50 -04:00
parent efd8dabd91
commit 134e49cc8e
4 changed files with 55 additions and 13 deletions

@ -182,16 +182,24 @@ std::string FurnaceNodeMetadata::infoText()
assert(src_list);
const InventoryItem *src_item = src_list->getItem(0);
if(src_item)
if(src_item) {
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 (";
s += itos(m_fuel_time/m_fuel_totaltime*100);
s += "%)";
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;
}
}
@ -221,9 +229,14 @@ bool FurnaceNodeMetadata::step(float dtime)
assert(src_list);
const 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(dst_list->getFreeSlots() > 0 && src_item && src_item->isCookable())
if(room_available)
{
m_src_totaltime = 3;
}
@ -252,13 +265,18 @@ bool FurnaceNodeMetadata::step(float dtime)
m_src_totaltime = 0;
}
changed = true;
continue;
// Fall through if the fuel item was used up this step
if(m_fuel_time < m_fuel_totaltime)
continue;
}
/*
If there is no source item or source item is not cookable, stop loop.
If there is no source item or source item is not cookable,
or furnace became overloaded, stop loop.
*/
if(src_item == NULL || m_src_totaltime < 0.001)
if((m_fuel_time < m_fuel_totaltime || dst_list->roomForCookedItem(src_item) == false)
&& (src_item == NULL || m_src_totaltime < 0.001))
{
m_step_accumulator = 0;
break;

@ -549,7 +549,7 @@ InventoryItem * InventoryList::addItem(u32 i, InventoryItem *newitem)
}
}
bool InventoryList::itemFits(u32 i, InventoryItem *newitem)
bool InventoryList::itemFits(const u32 i, const InventoryItem *newitem)
{
// If it is an empty position, it's an easy job.
const InventoryItem *to_item = getItem(i);
@ -558,11 +558,11 @@ bool InventoryList::itemFits(u32 i, InventoryItem *newitem)
return true;
}
// If not addable, return the item
// If not addable, fail
if(newitem->addableTo(to_item) == false)
return false;
// If the item fits fully in the slot, add counter and delete it
// If the item fits fully in the slot, pass
if(newitem->getCount() <= to_item->freeSpace())
{
return true;
@ -571,6 +571,24 @@ bool InventoryList::itemFits(u32 i, InventoryItem *newitem)
return false;
}
bool InventoryList::roomForItem(const InventoryItem *item)
{
for(u32 i=0; i<m_items.size(); i++)
if(itemFits(i, item))
return true;
return false;
}
bool InventoryList::roomForCookedItem(const InventoryItem *item)
{
const InventoryItem *cook = item->createCookResult();
if(!cook)
return false;
bool room = roomForItem(cook);
delete cook;
return room;
}
InventoryItem * InventoryList::takeItem(u32 i, u32 count)
{
if(count == 0)

@ -490,7 +490,13 @@ public:
InventoryItem * addItem(u32 i, InventoryItem *newitem);
// Checks whether the item could be added to the given slot
bool itemFits(u32 i, InventoryItem *newitem);
bool itemFits(const u32 i, const InventoryItem *newitem);
// 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
bool roomForCookedItem(const InventoryItem *item);
// Takes some items from a slot.
// If there are not enough, takes as many as it can.

@ -2446,7 +2446,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
if(g_settings.getBool("creative_mode") == false)
{
// Skip if inventory has no free space
if(ilist->getUsedSlots() == ilist->getSize())
if(ilist->roomForItem(item) == false)
{
dout_server<<"Player inventory has no free space"<<std::endl;
return;