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

Add MoveSomewhere inventory action

Improve shift+click experience
This commit is contained in:
est31 2015-06-20 12:55:48 +02:00
parent bc55ef337c
commit 2c1fd29884
6 changed files with 180 additions and 60 deletions

View file

@ -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)