[Scummvm-git-logs] scummvm master -> a8e83a86b0db6885b06ca915662c5dc60cfaa3eb

mduggan mgithub at guarana.org
Fri Jun 11 13:26:12 UTC 2021


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:
a8e83a86b0 ULTIMA8: Call full code for enterFastArea from intrinsic


Commit: a8e83a86b0db6885b06ca915662c5dc60cfaa3eb
    https://github.com/scummvm/scummvm/commit/a8e83a86b0db6885b06ca915662c5dc60cfaa3eb
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2021-06-11T22:12:11+09:00

Commit Message:
ULTIMA8: Call full code for enterFastArea from intrinsic

Previously we just spawned the usecode event, but to be faithful to the
original the intrinsic should do everything in Item::enterFastArea.

This also adds a workaround for a bug that was occasionally triggered when
returning to the rebel base in Crusader: No Remorse, and fixes an original game
bug in the process.

Changed paths:
    engines/ultima/ultima8/world/glob_egg.cpp
    engines/ultima/ultima8/world/glob_egg.h
    engines/ultima/ultima8/world/item.cpp
    engines/ultima/ultima8/world/item.h


diff --git a/engines/ultima/ultima8/world/glob_egg.cpp b/engines/ultima/ultima8/world/glob_egg.cpp
index 007a0bb1d6..df0b45b7d4 100644
--- a/engines/ultima/ultima8/world/glob_egg.cpp
+++ b/engines/ultima/ultima8/world/glob_egg.cpp
@@ -40,7 +40,7 @@ GlobEgg::~GlobEgg() {
 
 
 // Called when an item has entered the fast area
-void GlobEgg::enterFastArea() {
+uint32 GlobEgg::enterFastArea() {
 	uint32 coordmask = ~0x1FFU;
 	unsigned int coordshift = 1;
 	unsigned int offset = 1;
@@ -53,7 +53,7 @@ void GlobEgg::enterFastArea() {
 	// Expand it
 	if (!hasFlags(FLG_FASTAREA)) {
 		const MapGlob *glob = GameData::get_instance()->getGlob(_quality);
-		if (!glob) return;
+		if (!glob) return 0;
 
 		Std::vector<GlobItem>::const_iterator iter;
 		for (iter = glob->_contents.begin(); iter != glob->_contents.end(); ++iter) {
@@ -73,7 +73,7 @@ void GlobEgg::enterFastArea() {
 		}
 	}
 
-	Item::enterFastArea();
+	return Item::enterFastArea();
 }
 
 void GlobEgg::saveData(Common::WriteStream *ws) {
diff --git a/engines/ultima/ultima8/world/glob_egg.h b/engines/ultima/ultima8/world/glob_egg.h
index a14e594502..920b3a341c 100644
--- a/engines/ultima/ultima8/world/glob_egg.h
+++ b/engines/ultima/ultima8/world/glob_egg.h
@@ -39,7 +39,7 @@ public:
 	ENABLE_RUNTIME_CLASSTYPE()
 
 	//! The item has entered the fast area
-	void enterFastArea() override;
+	uint32 enterFastArea() override;
 
 	bool loadData(Common::ReadStream *rs, uint32 version);
 	void saveData(Common::WriteStream *ws) override;
diff --git a/engines/ultima/ultima8/world/item.cpp b/engines/ultima/ultima8/world/item.cpp
index 3d306f8c1b..e6c25a2424 100644
--- a/engines/ultima/ultima8/world/item.cpp
+++ b/engines/ultima/ultima8/world/item.cpp
@@ -1812,10 +1812,11 @@ void Item::animateItem() {
 
 
 // Called when an item has entered the fast area
-void Item::enterFastArea() {
+uint32 Item::enterFastArea() {
+	uint16 retval = 0;
 	//!! HACK to get rid of endless SFX loops
 	if (_shape == 0x2c8 && GAME_IS_U8)
-		return;
+		return 0;
 
 	const ShapeInfo *si = getShapeInfo();
 
@@ -1841,13 +1842,12 @@ void Item::enterFastArea() {
 			// certain global is set.  For now just skip that.
 
 			//
-			// TODO: Check this. The original games only call usecode for actors or
-			// NOISY types.  Calling for all types like this shouldn't cause any issues
-			// as long as all the types which implement event F are NPC or NOISY.
-			// Should confirm if that is the case.
+			// NOTE: Original games only call usecode for actors or NOISY
+			// types.  We call for all types to fix an usecode bug in
+			// Crusader: No Remorse.  See note about it below.
 			//
 			// if (actor || si->_flags & ShapeInfo::SI_NOISY)
-			callUsecodeEvent_enterFastArea();
+			retval = callUsecodeEvent_enterFastArea();
 		}
 	}
 
@@ -1864,6 +1864,25 @@ void Item::enterFastArea() {
 
 	// We're fast!
 	_flags |= FLG_FASTAREA;
+
+	//
+	// WORKAROUND: Crusader: No Remorse usecode has one place (REB_EGG, after
+	// randomly creating 0x34D REB_COUP (rebel couple) at the bar) where this
+	// is called with an "implies" but the enterFastArea event code never
+	// returns.  Every other instance this is "spawn"ed.
+	//
+	// In the original this bug is never triggered as enterFastArea intrinsic
+	// does not call usecode event unless the shape is SI_NOISY (REB_COUP is
+	// not). The result is the rebel couple do not start moving until you move
+	// near them and trigger their event, then enterFastArea function is
+	// spawned directly.
+	//
+	// Work around both problems by always calling event above and return 0.
+	//
+	if (_shape == 0x34D && GAME_IS_REMORSE)
+		return 0;
+
+	return retval;
 }
 
 // Called when an item is leaving the fast area
@@ -3029,7 +3048,7 @@ uint32 Item::I_enterFastArea(const uint8 *args, unsigned int /*argsize*/) {
 	ARG_ITEM_FROM_PTR(item);
 	if (!item) return 0;
 
-	return item->callUsecodeEvent_enterFastArea();
+	return item->enterFastArea();
 }
 
 uint32 Item::I_cast(const uint8 *args, unsigned int /*argsize*/) {
diff --git a/engines/ultima/ultima8/world/item.h b/engines/ultima/ultima8/world/item.h
index 2932828221..56faf6427e 100644
--- a/engines/ultima/ultima8/world/item.h
+++ b/engines/ultima/ultima8/world/item.h
@@ -492,7 +492,7 @@ public:
 	void setupLerp(int32 gametick);
 
 	//! The item has entered the fast area
-	virtual void enterFastArea();
+	virtual uint32 enterFastArea();
 
 	//! The item has left the fast area
 	//! \note This can destroy the object




More information about the Scummvm-git-logs mailing list