[Scummvm-git-logs] scummvm master -> 58a1e24912158b532296d742cbbf5512e2252083

mduggan mgithub at guarana.org
Thu Jul 30 05:18:42 UTC 2020


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

Summary:
ab72e615e6 ULTIMA8: Add loaders for new gumps
1fa244a662 ULTIMA8: Mark some weapons as 'small' for Crusader
9ad824112f ULTIMA8: Customize Crusader animations per weapon size
bd7fb406aa ULTIMA8: Don't crash when crusader music finishes
deff448929 ULTIMA8: Improve behavior of item selection process
58a1e24912 ULTIMA8: Fix teleport animations in Crusader


Commit: ab72e615e62756b35717d9e371d229bcd987559a
    https://github.com/scummvm/scummvm/commit/ab72e615e62756b35717d9e371d229bcd987559a
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-07-30T13:35:31+09:00

Commit Message:
ULTIMA8: Add loaders for new gumps

Changed paths:
    engines/ultima/ultima8/kernel/object_manager.cpp


diff --git a/engines/ultima/ultima8/kernel/object_manager.cpp b/engines/ultima/ultima8/kernel/object_manager.cpp
index 6190db2557..e753af4c73 100644
--- a/engines/ultima/ultima8/kernel/object_manager.cpp
+++ b/engines/ultima/ultima8/kernel/object_manager.cpp
@@ -46,6 +46,8 @@
 #include "ultima/ultima8/gumps/widgets/sliding_widget.h"
 #include "ultima/ultima8/gumps/mini_stats_gump.h"
 #include "ultima/ultima8/gumps/minimap_gump.h"
+#include "ultima/ultima8/gumps/cru_pickup_gump.h"
+#include "ultima/ultima8/gumps/cru_pickup_area_gump.h"
 
 namespace Ultima {
 namespace Ultima8 {
@@ -369,6 +371,8 @@ void ObjectManager::setupLoaders() {
 	addObjectLoader("SlidingWidget", ObjectLoader<SlidingWidget>::load);
 	addObjectLoader("MiniStatsGump", ObjectLoader<MiniStatsGump>::load);
 	addObjectLoader("MiniMapGump", ObjectLoader<MiniMapGump>::load);
+	addObjectLoader("CruPickupAreaGump", ObjectLoader<CruPickupAreaGump>::load);
+	addObjectLoader("CruPickupGump", ObjectLoader<CruPickupGump>::load);
 }
 
 } // End of namespace Ultima8


Commit: 1fa244a662db733107838a1188fdd5537cbfc58d
    https://github.com/scummvm/scummvm/commit/1fa244a662db733107838a1188fdd5537cbfc58d
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-07-30T13:37:20+09:00

Commit Message:
ULTIMA8: Mark some weapons as 'small' for Crusader

Changed paths:
    devtools/create_ultima/files/ultima8/remorseweapons.ini
    engines/ultima/ultima8/graphics/type_flags.cpp
    engines/ultima/ultima8/world/weapon_info.h


diff --git a/devtools/create_ultima/files/ultima8/remorseweapons.ini b/devtools/create_ultima/files/ultima8/remorseweapons.ini
index 7db78ebf99..5b78bd518d 100644
--- a/devtools/create_ultima/files/ultima8/remorseweapons.ini
+++ b/devtools/create_ultima/files/ultima8/remorseweapons.ini
@@ -8,6 +8,7 @@ display_shape=3
 display_frame=2
 overlay_shape=0x01A1
 overlay=0
+small=1
 
 [BA-41]
 shape=0x032F
@@ -18,6 +19,7 @@ display_shape=3
 display_frame=1
 overlay_shape=0x01A1
 overlay=0
+small=1
 
 [PA-21]
 shape=0x0330
@@ -28,6 +30,7 @@ display_shape=3
 display_frame=7
 overlay_shape=0x036D
 overlay=0
+small=1
 
 [EM-4]
 shape=0x038C
diff --git a/engines/ultima/ultima8/graphics/type_flags.cpp b/engines/ultima/ultima8/graphics/type_flags.cpp
index 40de6b7194..dd0e338919 100644
--- a/engines/ultima/ultima8/graphics/type_flags.cpp
+++ b/engines/ultima/ultima8/graphics/type_flags.cpp
@@ -262,6 +262,11 @@ void TypeFlags::loadWeaponInfo() {
 		else
 			wi->_displayGumpShape = 3;
 
+		if (config->get(k + "/small", val))
+			wi->_small = static_cast<uint8>(val);
+		else
+			wi->_small = 0;
+
 		if (wi->_shape > _shapeInfo.size()) {
 			warning("ignoring weapon info for shape %d beyond size %d.",
 					wi->_shape, _shapeInfo.size());
diff --git a/engines/ultima/ultima8/world/weapon_info.h b/engines/ultima/ultima8/world/weapon_info.h
index 85b2a7287d..6e544272f9 100644
--- a/engines/ultima/ultima8/world/weapon_info.h
+++ b/engines/ultima/ultima8/world/weapon_info.h
@@ -47,6 +47,7 @@ struct WeaponInfo {
 	uint16 _ammoShape;	//!< The shape number for the ammo used
 	uint16 _displayGumpShape; //! The gump shape to use for inventory display (3,4,5)
 	uint16 _displayGumpFrame; //!< The frame to use in the inventory gump
+	uint8 _small;	//! A flag whether or not the weapon is "small" (changes the animations used)
 
 	enum DmgType {
 		DMG_NORMAL = 0x0001,


Commit: 9ad824112f1e90f4bba4450060976c731acaf21a
    https://github.com/scummvm/scummvm/commit/9ad824112f1e90f4bba4450060976c731acaf21a
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-07-30T13:37:56+09:00

Commit Message:
ULTIMA8: Customize Crusader animations per weapon size

Changed paths:
    engines/ultima/ultima8/graphics/anim_dat.cpp
    engines/ultima/ultima8/world/actors/actor.cpp
    engines/ultima/ultima8/world/actors/actor.h
    engines/ultima/ultima8/world/actors/main_actor.cpp
    engines/ultima/ultima8/world/actors/main_actor.h


diff --git a/engines/ultima/ultima8/graphics/anim_dat.cpp b/engines/ultima/ultima8/graphics/anim_dat.cpp
index 9890083fa2..2d00bd44f7 100644
--- a/engines/ultima/ultima8/graphics/anim_dat.cpp
+++ b/engines/ultima/ultima8/graphics/anim_dat.cpp
@@ -28,6 +28,7 @@
 #include "ultima/ultima8/world/actors/actor_anim.h"
 #include "ultima/ultima8/world/actors/anim_action.h"
 #include "ultima/ultima8/world/actors/animation.h"
+#include "ultima/ultima8/world/actors/actor.h"
 #include "ultima/ultima8/kernel/core_app.h"
 #include "ultima/ultima8/games/game_info.h"
 
@@ -62,10 +63,13 @@ uint32 AnimDat::getActionNumberForSequence(Animation::Sequence action, const Act
 	if (GAME_IS_U8) {
 		return static_cast<uint32>(action);
 	} else {
+		bool smallwpn = (actor && actor->activeWeaponIsSmall());
 		// For crusader the actions have different IDs.  Rather than
 		// rewrite everything, we just translate them here for all the ones
 		// we want to use programmatically.  There are more, but they are
 		// called from usecode so don't need translation.
+		//
+		// TODO: Also handle kneeling weapon animations
 		switch (action) {
 		case Animation::stand:
 			return 0;
@@ -78,14 +82,14 @@ uint32 AnimDat::getActionNumberForSequence(Animation::Sequence action, const Act
 		case Animation::run:
 			return 3;
 		case Animation::combatStand:
-			return 4; // TODO: 8, 37 is also a combat stand for other weapons?
+			return (smallwpn ? 4 : 37);
 		// Note: 5, 6, 9, 10 == nothing (for avatar)?
 		case Animation::unreadyWeapon:
-			return 11; // TODO: 16 is also a unready-weapon move, which is right?
+			return (smallwpn ? 11: 16);
 		case Animation::readyWeapon:
-			return 12; // TODO: 7 is also a ready-weapon move, which is right?
+			return (smallwpn ? 7 : 12);
 		case Animation::attack:
-			return 13;
+			return (smallwpn ? 8 : 13);
 		// Note: 14, 17, 21, 22, 29 == nothing for avatar
 		case Animation::fallBackwards:
 			return 18;
diff --git a/engines/ultima/ultima8/world/actors/actor.cpp b/engines/ultima/ultima8/world/actors/actor.cpp
index 277627f0b6..664bd305da 100644
--- a/engines/ultima/ultima8/world/actors/actor.cpp
+++ b/engines/ultima/ultima8/world/actors/actor.cpp
@@ -73,7 +73,7 @@ Actor::Actor() : _strength(0), _dexterity(0), _intelligence(0),
 		_lastAnim(Animation::stand), _animFrame(0), _direction(dir_north),
 		_fallStart(0), _unkByte(0), _actorFlags(0), _combatTactic(0),
 		_homeX(0), _homeY(0), _homeZ(0), _currentActivityNo(0),
-		_lastActivityNo(0) {
+		_lastActivityNo(0), _activeWeapon(0) {
 	_defaultActivity[0] = 0;
 	_defaultActivity[1] = 0;
 	_defaultActivity[2] = 0;
@@ -800,18 +800,25 @@ void Actor::receiveHitCru(uint16 other, Direction dir, int damage, uint16 damage
 		return;
 
 	if (shape != 1 && this != getControlledActor()) {
-		//Actor *controlled = getControlledActor();
+		Actor *controlled = getControlledActor();
 		if (!isInCombat()) {
 			setActivity(getDefaultActivity(2)); // get activity from field 0xA
 			if (!isInCombat()) {
 				setInCombat();
-				// TODO: attack the currently controlled NPC.
+				CombatProcess *combat = getCombatProcess();
+				if (combat && controlled) {
+					combat->setTarget(controlled->getObjId());
+				}
 			}
 		} else {
 			if (getCurrentActivityNo() == 8) {
 				setActivity(5);
 			}
-			// TODO: attack the currently controlled NPC.
+			setInCombat();
+			CombatProcess *combat = getCombatProcess();
+			if (combat && controlled) {
+				combat->setTarget(controlled->getObjId());
+			}
 		}
 
 		// If the attacker is the controlled npc and this actor is not pathfinding
@@ -1342,6 +1349,16 @@ void Actor::notifyNearbyItems() {
 	}*/
 }
 
+bool Actor::activeWeaponIsSmall() const {
+	const Item *wpn = getItem(_activeWeapon);
+	if (wpn) {
+		const WeaponInfo *wi = wpn->getShapeInfo()->_weaponInfo;
+		return wi && (wi->_small != 0);
+	}
+	return false;
+}
+
+
 bool Actor::areEnemiesNear() {
 	UCList uclist(2);
 	LOOPSCRIPT(script, LS_TOKEN_TRUE); // we want all items
@@ -1438,6 +1455,7 @@ void Actor::saveData(Common::WriteStream *ws) {
 		ws->writeUint32LE(_homeZ);
 		ws->writeUint16LE(_currentActivityNo);
 		ws->writeUint16LE(_lastActivityNo);
+		ws->writeUint16LE(_activeWeapon);
 	}
 }
 
@@ -1468,6 +1486,7 @@ bool Actor::loadData(Common::ReadStream *rs, uint32 version) {
 		_homeZ = rs->readUint32LE();
 		_currentActivityNo = rs->readUint16LE();
 		_lastActivityNo = rs->readUint16LE();
+		_activeWeapon = rs->readUint16LE();
 	}
 
 	return true;
diff --git a/engines/ultima/ultima8/world/actors/actor.h b/engines/ultima/ultima8/world/actors/actor.h
index 57a13af098..6a86a33736 100644
--- a/engines/ultima/ultima8/world/actors/actor.h
+++ b/engines/ultima/ultima8/world/actors/actor.h
@@ -268,6 +268,12 @@ public:
 		return 0;
 	}
 
+	uint16 getActiveWeapon() const {
+		return _activeWeapon;
+	}
+
+	bool activeWeaponIsSmall() const;
+
 	ENABLE_RUNTIME_CLASSTYPE()
 
 	INTRINSIC(I_isNPC);
@@ -391,6 +397,9 @@ protected:
 	uint16 _currentActivityNo;
 	uint16 _lastActivityNo;
 
+	//! Active weapon item (only used in Crusader)
+	uint16 _activeWeapon;
+
 	//! starts an activity (Ultima 8 version)
 	//! \return processID of process handling the activity or zero
 	uint16 setActivityU8(int activity);
diff --git a/engines/ultima/ultima8/world/actors/main_actor.cpp b/engines/ultima/ultima8/world/actors/main_actor.cpp
index c7802041a8..98a87c9899 100644
--- a/engines/ultima/ultima8/world/actors/main_actor.cpp
+++ b/engines/ultima/ultima8/world/actors/main_actor.cpp
@@ -59,7 +59,7 @@ DEFINE_RUNTIME_CLASSTYPE_CODE(MainActor)
 
 MainActor::MainActor() : _justTeleported(false), _accumStr(0), _accumDex(0),
 	_accumInt(0), _cruBatteryType(ChemicalBattery), _keycards(0),
-	_activeWeapon(0), _activeInvItem(0), _shieldType(0), _shieldSpriteProc(0) {
+	_activeInvItem(0), _shieldType(0), _shieldSpriteProc(0) {
 }
 
 MainActor::~MainActor() {
@@ -666,7 +666,6 @@ void MainActor::saveData(Common::WriteStream *ws) {
 	if (GAME_IS_CRUSADER) {
 		ws->writeByte(static_cast<byte>(_cruBatteryType));
 		ws->writeUint32LE(_keycards);
-		ws->writeUint16LE(_activeWeapon);
 		ws->writeUint16LE(_activeInvItem);
 		ws->writeUint16LE(_shieldType);
 		ws->writeUint16LE(_shieldSpriteProc);
@@ -690,7 +689,6 @@ bool MainActor::loadData(Common::ReadStream *rs, uint32 version) {
 	if (GAME_IS_CRUSADER) {
 		_cruBatteryType = static_cast<CruBatteryType>(rs->readByte());
 		_keycards = rs->readUint32LE();
-		_activeWeapon = rs->readUint16LE();
 		_activeInvItem = rs->readUint16LE();
 		_shieldType = rs->readUint16LE();
 		_shieldSpriteProc = rs->readUint16LE();
diff --git a/engines/ultima/ultima8/world/actors/main_actor.h b/engines/ultima/ultima8/world/actors/main_actor.h
index e7915f05e7..e152495199 100644
--- a/engines/ultima/ultima8/world/actors/main_actor.h
+++ b/engines/ultima/ultima8/world/actors/main_actor.h
@@ -118,10 +118,6 @@ public:
 		_keycards = 0;
 	}
 
-	uint16 getActiveWeapon() const {
-		return _activeWeapon;
-	}
-
 	uint16 getActiveInvItem() const {
 		return _activeInvItem;
 	}
@@ -168,7 +164,6 @@ protected:
 
 	uint32 _keycards;
 	CruBatteryType _cruBatteryType;
-	uint16 _activeWeapon;
 	uint16 _activeInvItem;
 
 	Std::string _name;


Commit: bd7fb406aa1b975d84b38bd0d4632e817b6fadd2
    https://github.com/scummvm/scummvm/commit/bd7fb406aa1b975d84b38bd0d4632e817b6fadd2
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-07-30T13:42:37+09:00

Commit Message:
ULTIMA8: Don't crash when crusader music finishes

Changed paths:
    engines/ultima/ultima8/audio/remorse_music_process.cpp
    engines/ultima/ultima8/audio/remorse_music_process.h


diff --git a/engines/ultima/ultima8/audio/remorse_music_process.cpp b/engines/ultima/ultima8/audio/remorse_music_process.cpp
index 1c7e88826a..1eea5fd860 100644
--- a/engines/ultima/ultima8/audio/remorse_music_process.cpp
+++ b/engines/ultima/ultima8/audio/remorse_music_process.cpp
@@ -64,17 +64,12 @@ static const char *TRACK_FILE_NAMES[] = {
 // p_dynamic_cast stuff
 DEFINE_RUNTIME_CLASSTYPE_CODE(RemorseMusicProcess)
 
-RemorseMusicProcess::RemorseMusicProcess() : MusicProcess(), _currentTrack(0), _savedTrack(0), _playingStream(nullptr), _combatMusicActive(false) {
+RemorseMusicProcess::RemorseMusicProcess() : MusicProcess(), _currentTrack(0), _savedTrack(0), _combatMusicActive(false) {
 }
 
 RemorseMusicProcess::~RemorseMusicProcess() {
-	if (_playingStream) {
-		Audio::Mixer *mixer = Ultima8Engine::get_instance()->_mixer;
-		assert(mixer);
-		mixer->stopHandle(_soundHandle);
-		// FIXME: Some destruction order problem here..
-		//delete _playingStream;
-	}
+	// We shouldn't need to do anything here - the mixer will
+	// clean up the stream for us.
 }
 
 void RemorseMusicProcess::playMusic(int track) {
@@ -114,19 +109,15 @@ void RemorseMusicProcess::playMusic_internal(int track) {
 		return;
 	}
 
-	if (track == _currentTrack && _playingStream &&
-			!_playingStream->endOfStream())
+	Audio::Mixer *mixer = Ultima8Engine::get_instance()->_mixer;
+	assert(mixer);
+
+	if (track == _currentTrack && mixer->isSoundHandleActive(_soundHandle))
 		// Already playing what we want.
 		return;
 
-	Audio::Mixer *mixer = Ultima8Engine::get_instance()->_mixer;
-	assert(mixer);
 	mixer->stopHandle(_soundHandle);
 	_soundHandle = Audio::SoundHandle();
-	if (_playingStream) {
-		delete _playingStream;
-		_playingStream = nullptr;
-	}
 
 	if (track > 0) {
 		// TODO: It's a bit ugly having this here.  Should be in GameData.
@@ -139,24 +130,22 @@ void RemorseMusicProcess::playMusic_internal(int track) {
 			return;
 		}
 
-		_playingStream = Audio::makeModXmS3mStream(rs, DisposeAfterUse::NO);
-		if (!_playingStream) {
+		Audio::AudioStream *stream = Audio::makeModXmS3mStream(rs, DisposeAfterUse::NO);
+		if (!stream) {
 			error("Couldn't create stream from AMF file: %s", fname.c_str());
 			return;
 		}
-		mixer->playStream(Audio::Mixer::kMusicSoundType, &_soundHandle, _playingStream, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO);
+		mixer->playStream(Audio::Mixer::kMusicSoundType, &_soundHandle, stream, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::YES);
 	}
 }
 
 void RemorseMusicProcess::run() {
-	if (!_playingStream) {
-		return;
-	}
-	if (_playingStream->endOfStream()) {
-		delete _playingStream;
-		_playingStream = nullptr;
+	Audio::Mixer *mixer = Ultima8Engine::get_instance()->_mixer;
+	assert(mixer);
+	if (mixer->isSoundHandleActive(_soundHandle)) {
 		return;
 	}
+
 	// hit end of stream, play it again.
 	// TODO: This doesn't loop to the correct spot, should do something a bit nicer..
 	playMusic_internal(_currentTrack);
diff --git a/engines/ultima/ultima8/audio/remorse_music_process.h b/engines/ultima/ultima8/audio/remorse_music_process.h
index cf4214c290..b7baac08cf 100644
--- a/engines/ultima/ultima8/audio/remorse_music_process.h
+++ b/engines/ultima/ultima8/audio/remorse_music_process.h
@@ -53,7 +53,6 @@ private:
 	int _savedTrack;
 
 	Audio::SoundHandle _soundHandle;
-	Audio::AudioStream *_playingStream;
 
 public:
 	RemorseMusicProcess();


Commit: deff448929a806ddd260a2a2175ef3ab9d910478
    https://github.com/scummvm/scummvm/commit/deff448929a806ddd260a2a2175ef3ab9d910478
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-07-30T14:16:43+09:00

Commit Message:
ULTIMA8: Improve behavior of item selection process

Changed paths:
    engines/ultima/ultima8/world/item_selection_process.cpp
    engines/ultima/ultima8/world/item_selection_process.h


diff --git a/engines/ultima/ultima8/world/item_selection_process.cpp b/engines/ultima/ultima8/world/item_selection_process.cpp
index a30bd2aa7d..079387d371 100644
--- a/engines/ultima/ultima8/world/item_selection_process.cpp
+++ b/engines/ultima/ultima8/world/item_selection_process.cpp
@@ -61,13 +61,12 @@ bool ItemSelectionProcess::selectNextItem() {
 	if (!mainactor || !currentmap)
 		return false;
 
-	int32 x, y, z;
-	mainactor->getCentre(x, y, z);
+	mainactor->getCentre(_ax, _ay, _az);
 
 	UCList uclist(2);
 	LOOPSCRIPT(script, LS_TOKEN_TRUE); // we want all items
 	currentmap->areaSearch(&uclist, script, sizeof(script),
-						   mainactor, 0x100, false);
+						   mainactor, 0x120, false);
 
 	Std::vector<Item *> candidates;
 
@@ -91,7 +90,7 @@ bool ItemSelectionProcess::selectNextItem() {
 
 			int32 cx, cy, cz;
 			item->getCentre(cx, cy, cz);
-			if (abs(cx - x) > 0x100 || abs(cy - y) > 0x100 || abs(cz - z) > 50)
+			if (abs(cx - _ax) > 0x100 || abs(cy - _ay) > 0x100 || abs(cz - _az) > 50)
 				continue;
 
 			candidates.push_back(item);
@@ -112,7 +111,7 @@ bool ItemSelectionProcess::selectNextItem() {
 		int offset = 0;
 		for (Std::vector<Item *>::iterator iter = candidates.begin();
 			 iter != candidates.end();
-			 iter++) {
+			 offset++, iter++) {
 			ObjId num = item->getObjId();
 			if (_selectedItem == num) {
 				offset++;
@@ -136,6 +135,22 @@ void ItemSelectionProcess::useSelectedItem() {
 	clearSelection();
 }
 
+void ItemSelectionProcess::avatarMoved() {
+	if (!_selectedItem)
+		return;
+	Item *item = getItem(_selectedItem);
+	MainActor *mainactor = getMainActor();
+
+	// Only clear if actor has moved a little
+	if (item && mainactor) {
+		int32 ax, ay, az;
+		mainactor->getCentre(ax, ay, az);
+		uint32 range = MAX(abs(ax - _ax), MAX(abs(ay - _ay), abs(az - _az)));
+		if (range > 16)
+			clearSelection();
+	}
+}
+
 void ItemSelectionProcess::clearSelection() {
 	if (!getItemNum())
 		return;
@@ -165,12 +180,18 @@ void ItemSelectionProcess::putItemSelectionOnItem(Item *item) {
 void ItemSelectionProcess::saveData(Common::WriteStream *ws) {
 	Process::saveData(ws);
 	ws->writeUint16LE(_selectedItem);
+	ws->writeSint32LE(_ax);
+	ws->writeSint32LE(_ay);
+	ws->writeSint32LE(_az);
 }
 
 bool ItemSelectionProcess::loadData(Common::ReadStream *rs, uint32 version) {
 	if (!Process::loadData(rs, version)) return false;
 
 	_selectedItem = rs->readUint16LE();
+	_ax = rs->readSint32LE();
+	_ay = rs->readSint32LE();
+	_az = rs->readSint32LE();
 	return true;
 }
 
diff --git a/engines/ultima/ultima8/world/item_selection_process.h b/engines/ultima/ultima8/world/item_selection_process.h
index afd3a86919..11541349f6 100644
--- a/engines/ultima/ultima8/world/item_selection_process.h
+++ b/engines/ultima/ultima8/world/item_selection_process.h
@@ -46,9 +46,12 @@ public:
 	//!< Select the next item
 	bool selectNextItem();
 
-	//!< Avatar moved - clear the selector
+	//!< Clear the selector
 	void clearSelection();
 
+	//!< Avatar moved - clear the selector if needed.
+	void avatarMoved();
+
 	//!< Use the selected item (if any)
 	void useSelectedItem();
 
@@ -67,6 +70,9 @@ private:
 	void putItemSelectionOnItem(Item *item);
 
 	uint16 _selectedItem;
+	int32 _ax;
+	int32 _ay;
+	int32 _az;
 
 	static ItemSelectionProcess *_instance;
 };


Commit: 58a1e24912158b532296d742cbbf5512e2252083
    https://github.com/scummvm/scummvm/commit/58a1e24912158b532296d742cbbf5512e2252083
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-07-30T14:18:08+09:00

Commit Message:
ULTIMA8: Fix teleport animations in Crusader

Changed paths:
    engines/ultima/ultima8/graphics/anim_dat.cpp
    engines/ultima/ultima8/world/actors/actor.cpp
    engines/ultima/ultima8/world/actors/animation.h


diff --git a/engines/ultima/ultima8/graphics/anim_dat.cpp b/engines/ultima/ultima8/graphics/anim_dat.cpp
index 2d00bd44f7..7f87f6763d 100644
--- a/engines/ultima/ultima8/graphics/anim_dat.cpp
+++ b/engines/ultima/ultima8/graphics/anim_dat.cpp
@@ -108,6 +108,10 @@ uint32 AnimDat::getActionNumberForSequence(Animation::Sequence action, const Act
 			return 0;
 		case Animation::lookRight:
 			return 0;
+		case Animation::teleportInReplacement:
+			return Animation::teleportIn;
+		case Animation::teleportOutReplacement:
+			return Animation::teleportOut;
 		default:
 			return static_cast<uint32>(action);;
 		}
diff --git a/engines/ultima/ultima8/world/actors/actor.cpp b/engines/ultima/ultima8/world/actors/actor.cpp
index 664bd305da..fa7ab480ca 100644
--- a/engines/ultima/ultima8/world/actors/actor.cpp
+++ b/engines/ultima/ultima8/world/actors/actor.cpp
@@ -790,8 +790,8 @@ void Actor::receiveHitCru(uint16 other, Direction dir, int damage, uint16 damage
 		// TODO: Finish special case for Vargas.  Should not do any damage
 		// if there is a particular anim process running.  Also, check if the
 		// same special case exists in REGRET.
-		doAnim(static_cast<Animation::Sequence>(0x21), dir_current);
-		doAnim(static_cast<Animation::Sequence>(0x20), dir_current);
+		doAnim(Animation::teleportOutReplacement, dir_current);
+		doAnim(Animation::teleportInReplacement, dir_current);
 		_hitPoints -= damage;
 		return;
 	}
@@ -1319,7 +1319,7 @@ int32 Actor::collideMove(int32 x, int32 y, int32 z, bool teleport, bool force,
 	if (_objId == 1 && GAME_IS_CRUSADER) {
 		notifyNearbyItems();
 		TargetReticleProcess::get_instance()->avatarMoved();
-		ItemSelectionProcess::get_instance()->clearSelection();
+		ItemSelectionProcess::get_instance()->avatarMoved();
 	}
 	return result;
 }
@@ -1527,6 +1527,20 @@ uint32 Actor::I_doAnim(const uint8 *args, unsigned int /*argsize*/) {
 
 	if (!actor) return 0;
 
+	//
+	// HACK: In Crusader, anims 32 and 33 are teleport in/out.  In U8 they are
+	// turn left/right.  We want to remap those numbers in most cases, but when
+	// they come out of usecode we don't want to remap them.  Here we give them
+	// temporary values so we can set them back later.
+	//
+	if (GAME_IS_CRUSADER) {
+		Animation::Sequence seq = static_cast<Animation::Sequence>(anim);
+		if (seq == Animation::teleportIn)
+			anim = static_cast<uint16>(Animation::teleportInReplacement);
+		else if (seq == Animation::teleportOut)
+			anim = static_cast<uint16>(Animation::teleportOutReplacement);
+	}
+
 	return actor->doAnim(static_cast<Animation::Sequence>(anim), Direction_FromUsecodeDir(dir));
 }
 
diff --git a/engines/ultima/ultima8/world/actors/animation.h b/engines/ultima/ultima8/world/actors/animation.h
index d5795e5aa5..b94ff8d736 100644
--- a/engines/ultima/ultima8/world/actors/animation.h
+++ b/engines/ultima/ultima8/world/actors/animation.h
@@ -112,7 +112,9 @@ enum Sequence {
 	kneelAndFire3 = 43,
 	runWithLargeWeapon = 50,
 	surrender = 57,
-	surrenderStand = 60
+	surrenderStand = 60,
+	teleportInReplacement = 0x1020,	//!< See notes in Actor::I_doAnim
+	teleportOutReplacement = 0x1021	//!< See notes in Actor::I_doAnim
 };
 
 enum Result {




More information about the Scummvm-git-logs mailing list