@@ -301,6 +301,7 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
301
301
if (!list_to->getItem (dest_i).empty ()) {
302
302
to_i = dest_i;
303
303
apply (mgr, player, gamedef);
304
+ assert (move_count <= count);
304
305
count -= move_count;
305
306
}
306
307
}
@@ -352,10 +353,12 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
352
353
bool allow_swap = !list_to->itemFits (to_i, src_item, &restitem)
353
354
&& restitem.count == src_item.count
354
355
&& !caused_by_move_somewhere;
356
+ move_count = src_item.count - restitem.count ;
355
357
356
358
// Shift-click: Cannot fill this stack, proceed with next slot
357
- if (caused_by_move_somewhere && restitem. count == src_item. count )
359
+ if (caused_by_move_somewhere && move_count == 0 ) {
358
360
return ;
361
+ }
359
362
360
363
if (allow_swap) {
361
364
// Swap will affect the entire stack if it can performed.
@@ -384,9 +387,16 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
384
387
src_can_take_count = dst_can_put_count = 0 ;
385
388
} else {
386
389
// Take from one inventory, put into another
390
+ int src_item_count = src_item.count ;
391
+ if (caused_by_move_somewhere)
392
+ // When moving somewhere: temporarily use the actual movable stack
393
+ // size to ensure correct callback execution.
394
+ src_item.count = move_count;
387
395
dst_can_put_count = allowPut (src_item, player);
388
396
src_can_take_count = allowTake (src_item, player);
389
-
397
+ if (caused_by_move_somewhere)
398
+ // Reset source item count
399
+ src_item.count = src_item_count;
390
400
bool swap_expected = allow_swap;
391
401
allow_swap = allow_swap
392
402
&& (src_can_take_count == -1 || src_can_take_count >= src_item.count )
@@ -416,12 +426,17 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
416
426
count = src_can_take_count;
417
427
if (dst_can_put_count != -1 && count > dst_can_put_count)
418
428
count = dst_can_put_count;
429
+
419
430
/* Limit according to source item count */
420
431
if (count > list_from->getItem (from_i).count )
421
432
count = list_from->getItem (from_i).count ;
422
433
423
434
/* If no items will be moved, don't go further */
424
435
if (count == 0 ) {
436
+ if (caused_by_move_somewhere)
437
+ // Set move count to zero, as no items have been moved
438
+ move_count = 0 ;
439
+
425
440
// Undo client prediction. See 'clientApply'
426
441
if (from_inv.type == InventoryLocation::PLAYER)
427
442
list_from->setModified ();
@@ -438,6 +453,7 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
438
453
<<" list=\" " <<to_list<<" \" "
439
454
<<" i=" <<to_i
440
455
<<std::endl;
456
+
441
457
return ;
442
458
}
443
459
@@ -455,6 +471,8 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
455
471
bool did_swap = false ;
456
472
move_count = list_from->moveItem (from_i,
457
473
list_to, to_i, count, allow_swap, &did_swap);
474
+ if (caused_by_move_somewhere)
475
+ count = old_count;
458
476
assert (allow_swap == did_swap);
459
477
460
478
// If source is infinite, reset it's stack
@@ -503,8 +521,7 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
503
521
<< std::endl;
504
522
505
523
// If we are inside the move somewhere loop, we don't need to report
506
- // anything if nothing happened (perhaps we don't need to report
507
- // anything for caused_by_move_somewhere == true, but this way its safer)
524
+ // anything if nothing happened
508
525
if (caused_by_move_somewhere && move_count == 0 )
509
526
return ;
510
527
@@ -558,7 +575,15 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
558
575
}
559
576
mgr->setInventoryModified (from_inv);
560
577
} else {
578
+ int src_item_count = src_item.count ;
579
+ if (caused_by_move_somewhere)
580
+ // When moving somewhere: temporarily use the actual movable stack
581
+ // size to ensure correct callback execution.
582
+ src_item.count = move_count;
561
583
onPutAndOnTake (src_item, player);
584
+ if (caused_by_move_somewhere)
585
+ // Reset source item count
586
+ src_item.count = src_item_count;
562
587
if (did_swap) {
563
588
// Item is now placed in source list
564
589
src_item = list_from->getItem (from_i);
0 commit comments