1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-06-27 16:36:03 +00:00

Inventory menu (with dragging) improved. Crafting is now handled via a IACTION_CRAFT inventory action.

This commit is contained in:
Kahrl 2012-01-21 21:21:41 +01:00 committed by Perttu Ahola
parent 157a4cf18c
commit 1efdc36b22
9 changed files with 550 additions and 289 deletions

View file

@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "main.h" // for g_settings
#include "settings.h"
#include "utility.h"
#include "craftdef.h"
/*
InventoryLocation
@ -124,6 +125,10 @@ InventoryAction * InventoryAction::deSerialize(std::istream &is)
{
a = new IDropAction(is);
}
else if(type == "Craft")
{
a = new ICraftAction(is);
}
return a;
}
@ -152,7 +157,7 @@ IMoveAction::IMoveAction(std::istream &is)
to_i = stoi(ts);
}
void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player)
void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGameDef *gamedef)
{
Inventory *inv_from = mgr->getInventory(from_inv);
Inventory *inv_to = mgr->getInventory(to_inv);
@ -273,7 +278,7 @@ IDropAction::IDropAction(std::istream &is)
from_i = stoi(ts);
}
void IDropAction::apply(InventoryManager *mgr, ServerActiveObject *player)
void IDropAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGameDef *gamedef)
{
Inventory *inv_from = mgr->getInventory(from_inv);
@ -332,3 +337,120 @@ void IDropAction::apply(InventoryManager *mgr, ServerActiveObject *player)
<<" i="<<from_i
<<std::endl;
}
ICraftAction::ICraftAction(std::istream &is)
{
std::string ts;
std::getline(is, ts, ' ');
count = stoi(ts);
std::getline(is, ts, ' ');
craft_inv.deSerialize(ts);
}
void ICraftAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGameDef *gamedef)
{
Inventory *inv_craft = mgr->getInventory(craft_inv);
if(!inv_craft){
infostream<<"ICraftAction::apply(): FAIL: inventory not found: "
<<"craft_inv=\""<<craft_inv.dump()<<"\""<<std::endl;
return;
}
InventoryList *list_craft = inv_craft->getList("craft");
InventoryList *list_craftresult = inv_craft->getList("craftresult");
/*
If a list doesn't exist or the source item doesn't exist
*/
if(!list_craft){
infostream<<"ICraftAction::apply(): FAIL: craft list not found: "
<<"craft_inv=\""<<craft_inv.dump()<<"\""<<std::endl;
return;
}
if(!list_craftresult){
infostream<<"ICraftAction::apply(): FAIL: craftresult list not found: "
<<"craft_inv=\""<<craft_inv.dump()<<"\""<<std::endl;
return;
}
if(list_craftresult->getSize() < 1){
infostream<<"ICraftAction::apply(): FAIL: craftresult list too short: "
<<"craft_inv=\""<<craft_inv.dump()<<"\""<<std::endl;
return;
}
ItemStack crafted;
int count_remaining = count;
bool found = getCraftingResult(inv_craft, crafted, false, gamedef);
while(found && list_craftresult->itemFits(0, crafted))
{
// Decrement input and add crafting output
getCraftingResult(inv_craft, crafted, true, gamedef);
list_craftresult->addItem(0, crafted);
mgr->setInventoryModified(craft_inv);
actionstream<<player->getDescription()
<<" crafts "
<<crafted.getItemString()
<<std::endl;
// Decrement counter
if(count_remaining == 1)
break;
else if(count_remaining > 1)
count_remaining--;
// Get next crafting result
found = getCraftingResult(inv_craft, crafted, false, gamedef);
}
infostream<<"ICraftAction::apply(): crafted "
<<" craft_inv=\""<<craft_inv.dump()<<"\""
<<std::endl;
}
// Crafting helper
bool getCraftingResult(Inventory *inv, ItemStack& result,
bool decrementInput, IGameDef *gamedef)
{
DSTACK(__FUNCTION_NAME);
result.clear();
// TODO: Allow different sizes of crafting grids
// Get the InventoryList in which we will operate
InventoryList *clist = inv->getList("craft");
if(!clist || clist->getSize() != 9)
return false;
// Mangle crafting grid to an another format
CraftInput ci;
ci.method = CRAFT_METHOD_NORMAL;
ci.width = 3;
for(u16 i=0; i<9; i++)
ci.items.push_back(clist->getItem(i));
// Find out what is crafted and add it to result item slot
CraftOutput co;
bool found = gamedef->getCraftDefManager()->getCraftResult(
ci, co, decrementInput, gamedef);
if(found)
result.deSerialize(co.item, gamedef->getItemDefManager());
if(found && decrementInput)
{
// CraftInput has been changed, apply changes in clist
for(u16 i=0; i<9; i++)
{
clist->changeItem(i, ci.items[i]);
}
}
return found;
}