summaryrefslogtreecommitdiff
path: root/src/inventorymanager.cpp
diff options
context:
space:
mode:
authorest31 <MTest31@outlook.com>2015-06-20 12:55:48 +0200
committerest31 <MTest31@outlook.com>2015-06-23 20:18:41 +0200
commit2c1fd29884adec17564d39c0f7792633cbc55f9a (patch)
tree73bdee04a50963ac5990f08b96ee30f069aa8ce7 /src/inventorymanager.cpp
parentbc55ef337cc83a5c31d4fdafba352a7a26921900 (diff)
downloadminetest-2c1fd29884adec17564d39c0f7792633cbc55f9a.tar.gz
minetest-2c1fd29884adec17564d39c0f7792633cbc55f9a.tar.bz2
minetest-2c1fd29884adec17564d39c0f7792633cbc55f9a.zip
Add MoveSomewhere inventory action
Improve shift+click experience
Diffstat (limited to 'src/inventorymanager.cpp')
-rw-r--r--src/inventorymanager.cpp96
1 files changed, 73 insertions, 23 deletions
diff --git a/src/inventorymanager.cpp b/src/inventorymanager.cpp
index 640e3395b..96ce48086 100644
--- a/src/inventorymanager.cpp
+++ b/src/inventorymanager.cpp
@@ -121,16 +121,13 @@ InventoryAction * InventoryAction::deSerialize(std::istream &is)
InventoryAction *a = NULL;
- if(type == "Move")
- {
- a = new IMoveAction(is);
- }
- else if(type == "Drop")
- {
+ if (type == "Move") {
+ a = new IMoveAction(is, false);
+ } else if (type == "MoveSomewhere") {
+ a = new IMoveAction(is, true);
+ } else if (type == "Drop") {
a = new IDropAction(is);
- }
- else if(type == "Craft")
- {
+ } else if(type == "Craft") {
a = new ICraftAction(is);
}
@@ -141,9 +138,12 @@ InventoryAction * InventoryAction::deSerialize(std::istream &is)
IMoveAction
*/
-IMoveAction::IMoveAction(std::istream &is)
+IMoveAction::IMoveAction(std::istream &is, bool somewhere)
{
std::string ts;
+ move_somewhere = somewhere;
+ caused_by_move_somewhere = false;
+ move_count = 0;
std::getline(is, ts, ' ');
count = stoi(ts);
@@ -161,8 +161,10 @@ IMoveAction::IMoveAction(std::istream &is)
std::getline(is, to_list, ' ');
- std::getline(is, ts, ' ');
- to_i = stoi(ts);
+ if (!somewhere) {
+ std::getline(is, ts, ' ');
+ to_i = stoi(ts);
+ }
}
void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGameDef *gamedef)
@@ -202,6 +204,48 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
return;
}
+ if (move_somewhere) {
+ s16 old_to_i = to_i;
+ u16 old_count = count;
+ caused_by_move_somewhere = true;
+ move_somewhere = false;
+
+ infostream << "IMoveAction::apply(): moving item somewhere"
+ << " msom=" << move_somewhere
+ << " count=" << count
+ << " from inv=\"" << from_inv.dump() << "\""
+ << " list=\"" << from_list << "\""
+ << " i=" << from_i
+ << " to inv=\"" << to_inv.dump() << "\""
+ << " list=\"" << to_list << "\""
+ << std::endl;
+
+ // Try to add the item to destination list
+ s16 dest_size = list_to->getSize();
+ // First try all the non-empty slots
+ for (s16 dest_i = 0; dest_i < dest_size && count > 0; dest_i++) {
+ if (!list_to->getItem(dest_i).empty()) {
+ to_i = dest_i;
+ apply(mgr, player, gamedef);
+ count -= move_count;
+ }
+ }
+
+ // Then try all the empty ones
+ for (s16 dest_i = 0; dest_i < dest_size && count > 0; dest_i++) {
+ if (list_to->getItem(dest_i).empty()) {
+ to_i = dest_i;
+ apply(mgr, player, gamedef);
+ count -= move_count;
+ }
+ }
+
+ to_i = old_to_i;
+ count = old_count;
+ caused_by_move_somewhere = false;
+ move_somewhere = true;
+ return;
+ }
/*
Do not handle rollback if both inventories are that of the same player
*/
@@ -324,7 +368,8 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
If something is wrong (source item is empty, destination is the
same as source), nothing happens
*/
- list_from->moveItem(from_i, list_to, to_i, count);
+ move_count = list_from->moveItem(from_i,
+ list_to, to_i, count, !caused_by_move_somewhere);
// If source is infinite, reset it's stack
if(src_can_take_count == -1){
@@ -352,15 +397,17 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
list_from->takeItem(from_i, count);
}
- infostream<<"IMoveAction::apply(): moved"
- <<" count="<<count
- <<" from inv=\""<<from_inv.dump()<<"\""
- <<" list=\""<<from_list<<"\""
- <<" i="<<from_i
- <<" to inv=\""<<to_inv.dump()<<"\""
- <<" list=\""<<to_list<<"\""
- <<" i="<<to_i
- <<std::endl;
+ infostream << "IMoveAction::apply(): moved"
+ << " msom=" << move_somewhere
+ << " caused=" << caused_by_move_somewhere
+ << " count=" << count
+ << " from inv=\"" << from_inv.dump() << "\""
+ << " list=\"" << from_list << "\""
+ << " i=" << from_i
+ << " to inv=\"" << to_inv.dump() << "\""
+ << " list=\"" << to_list << "\""
+ << " i=" << to_i
+ << std::endl;
/*
Record rollback information
@@ -480,7 +527,10 @@ void IMoveAction::clientApply(InventoryManager *mgr, IGameDef *gamedef)
if(!list_from || !list_to)
return;
- list_from->moveItem(from_i, list_to, to_i, count);
+ if (!move_somewhere)
+ list_from->moveItem(from_i, list_to, to_i, count);
+ else
+ list_from->moveItemSomewhere(from_i, list_to, count);
mgr->setInventoryModified(from_inv);
if(inv_from != inv_to)