[Scummvm-git-logs] scummvm master -> 881c9a1c0b175e7f0ca4e6e45887d9fe81142983

OMGPizzaGuy noreply at scummvm.org
Sun May 12 00:59:45 UTC 2024


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
881c9a1c0b ULTIMA8: Allow item spliting & merging on game map.


Commit: 881c9a1c0b175e7f0ca4e6e45887d9fe81142983
    https://github.com/scummvm/scummvm/commit/881c9a1c0b175e7f0ca4e6e45887d9fe81142983
Author: Matthew Jimenez (matthew.jimenez at outlook.com)
Date: 2024-05-11T19:59:14-05:00

Commit Message:
ULTIMA8: Allow item spliting & merging on game map.
Fixes #14045

Changed paths:
    engines/ultima/ultima8/gumps/game_map_gump.cpp


diff --git a/engines/ultima/ultima8/gumps/game_map_gump.cpp b/engines/ultima/ultima8/gumps/game_map_gump.cpp
index 6fd3b4837de..eb54a023e42 100644
--- a/engines/ultima/ultima8/gumps/game_map_gump.cpp
+++ b/engines/ultima/ultima8/gumps/game_map_gump.cpp
@@ -21,16 +21,20 @@
 
 #include "ultima/ultima.h"
 #include "ultima/ultima8/gumps/game_map_gump.h"
+#include "ultima/ultima8/gumps/gump_notify_process.h"
+#include "ultima/ultima8/gumps/slider_gump.h"
 #include "ultima/ultima8/kernel/kernel.h"
 #include "ultima/ultima8/world/world.h"
 #include "ultima/ultima8/world/current_map.h"
 #include "ultima/ultima8/world/actors/main_actor.h"
+#include "ultima/ultima8/world/item_factory.h"
 #include "ultima/ultima8/world/item_sorter.h"
 #include "ultima/ultima8/world/camera_process.h"
 #include "ultima/ultima8/ultima8.h"
 #include "ultima/ultima8/world/get_object.h"
 #include "ultima/ultima8/world/actors/avatar_mover_process.h"
 #include "ultima/ultima8/world/missile_tracker.h"
+#include "ultima/ultima8/world/split_item_process.h"
 
 #include "ultima/ultima8/world/actors/pathfinder_process.h"
 
@@ -473,6 +477,64 @@ void GameMapGump::DropItem(Item *item, int mx, int my) {
 	Actor *avatar = getMainActor();
 
 	ObjId trace = TraceCoordinates(mx, my, _draggingPos, dox, doy, item);
+	Item *targetitem = getItem(trace);
+	bool canReach = avatar->canReach(item, 128, // CONSTANT!
+									_draggingPos[0], _draggingPos[1], _draggingPos[2]);
+
+	if (item->getShapeInfo()->hasQuantity()) {
+		if (item->getQuality() > 1) {
+			// more than one, so see if we should ask if we should split it up
+			Item *splittarget = nullptr;
+
+			// also try to combine
+			if (canReach && targetitem && item->canMergeWith(targetitem)) {
+				splittarget = targetitem;
+			}
+
+			if (!splittarget) {
+				// create new item
+				splittarget = ItemFactory::createItem(
+					item->getShape(), item->getFrame(), 0,
+					item->getFlags() & (Item::FLG_DISPOSABLE | Item::FLG_OWNED | Item::FLG_INVISIBLE | Item::FLG_FLIPPED | Item::FLG_FAST_ONLY | Item::FLG_LOW_FRICTION), item->getNpcNum(), item->getMapNum(),
+					item->getExtFlags() & (Item::EXT_SPRITE | Item::EXT_HIGHLIGHT | Item::EXT_TRANSPARENT), true);
+				if (!splittarget) {
+					warning("ContainerGump failed to create item (%u,%u) while splitting",
+							item->getShape(), item->getFrame());
+					return;
+				}
+			}
+
+			SliderGump *slidergump = new SliderGump(100, 100,
+													0, item->getQuality(),
+													item->getQuality());
+			slidergump->InitGump(0);
+			slidergump->CreateNotifier(); // manually create notifier
+			Process *notifier = slidergump->GetNotifyProcess();
+			SplitItemProcess *splitproc = new SplitItemProcess(item, splittarget);
+			Kernel::get_instance()->addProcess(splitproc);
+			splitproc->waitFor(notifier);
+			item = splittarget;
+		} else {
+			// try to combine items
+			if (canReach && targetitem && item->canMergeWith(targetitem)) {
+				uint16 newquant = targetitem->getQuality() + item->getQuality();
+				// easter egg as in original: items stack to max quantity of 666
+				if (newquant > 666) {
+					item->setQuality(newquant - 666);
+					targetitem->setQuality(666);
+					// maybe this isn't needed? original doesn't do it here..
+					targetitem->callUsecodeEvent_combine();
+				} else {
+					targetitem->setQuality(newquant);
+					targetitem->callUsecodeEvent_combine();
+					// combined, so delete other
+					item->destroy();
+				}
+				return;
+			}
+		}
+	}
+
 	if (trace == 1) { // dropping on self
 		ObjId bp = avatar->getEquip(ShapeInfo::SE_BACKPACK);
 		Container *backpack = getContainer(bp);
@@ -483,8 +545,7 @@ void GameMapGump::DropItem(Item *item, int mx, int my) {
 		}
 	}
 
-	if (!avatar->canReach(item, 128, // CONSTANT!
-	                      _draggingPos[0], _draggingPos[1], _draggingPos[2])) {
+	if (!canReach) {
 		// can't reach, so throw
 		debugC(kDebugObject, "Throwing item to (%d, %d, %d)",
 			   _draggingPos[0], _draggingPos[1], _draggingPos[2]);




More information about the Scummvm-git-logs mailing list