[Scummvm-git-logs] scummvm master -> 5ce24939d08982612f08c1d3a92a99ae6f69b3a2

mduggan mgithub at guarana.org
Tue Jul 28 01:52:28 UTC 2020


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

Summary:
3e85a3038d ULTIMA: Split some keybindings for U8 and Crusader games
19b3103462 ULTIMA8: Only play combat music for U8
584abe0906 ULTIMA8: Only do 'actor specials' for U8
8a63328011 ULTIMA8: Add z key to centre camera in Crusader
5ce24939d0 ULTIMA8: Small fixes to make firing gun work in Crusader


Commit: 3e85a3038dd53f4f2556cd12b622c1f83992d028
    https://github.com/scummvm/scummvm/commit/3e85a3038dd53f4f2556cd12b622c1f83992d028
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-07-28T10:03:39+09:00

Commit Message:
ULTIMA: Split some keybindings for U8 and Crusader games

Changed paths:
    engines/ultima/detection.cpp
    engines/ultima/ultima8/meta_engine.cpp
    engines/ultima/ultima8/meta_engine.h
    engines/ultima/ultima8/misc/debugger.cpp
    engines/ultima/ultima8/misc/debugger.h
    engines/ultima/ultima8/world/actors/avatar_mover_process.cpp
    engines/ultima/ultima8/world/actors/avatar_mover_process.h


diff --git a/engines/ultima/detection.cpp b/engines/ultima/detection.cpp
index ef93ea7fbc..0b85faf031 100644
--- a/engines/ultima/detection.cpp
+++ b/engines/ultima/detection.cpp
@@ -123,11 +123,11 @@ SaveStateList UltimaMetaEngine::listSaves(const char *target) const {
 }
 
 Common::KeymapArray UltimaMetaEngine::initKeymaps(const char *target) const {
-	Common::String gameId = getGameId(target);
+	const Common::String gameId = getGameId(target);
 	if (gameId == "ultima4" || gameId == "ultima4_enh")
 		return Ultima::Ultima4::MetaEngine::initKeymaps();
 	if (gameId == "ultima8" || gameId == "remorse" || gameId == "regret")
-		return Ultima::Ultima8::MetaEngine::initKeymaps();
+		return Ultima::Ultima8::MetaEngine::initKeymaps(gameId);
 
 	return Common::KeymapArray();
 }
diff --git a/engines/ultima/ultima8/meta_engine.cpp b/engines/ultima/ultima8/meta_engine.cpp
index 9ab3e72c49..90d2e52398 100644
--- a/engines/ultima/ultima8/meta_engine.cpp
+++ b/engines/ultima/ultima8/meta_engine.cpp
@@ -39,28 +39,15 @@ struct KeybindingRecord {
 	const char *_joy;
 };
 
-static const KeybindingRecord KEYS[] = {
+static const KeybindingRecord COMMON_KEYS[] = {
 	{ ACTION_QUICKSAVE, "QUICKSAVE", "Quick Save", "GUIApp::saveGame QuickSave", nullptr, "F1", nullptr },
 	{ ACTION_SAVE, "SAVE", "Save Game", "GUIApp::saveGame", nullptr, "F5", nullptr },
 	{ ACTION_LOAD, "LOAD", "Load Game", "GUIApp::loadGame", nullptr, "F7", nullptr },
-	{ ACTION_BEDROLL, "BEDROLL", "Bedroll", "MainActor::useBedroll", nullptr, "b", nullptr },
 	{ ACTION_COMBAT, "COMBAT", "Combat", "MainActor::toggleCombat", nullptr, "c", "JOY_X" },
-	{ ACTION_BACKPACK, "BACKPACK", "Use Backpack", "MainActor::useBackpack", nullptr, "i", nullptr },
-	{ ACTION_KEYRING, "KEYRING", "Keyring", "MainActor::useKeyring", nullptr, "k", nullptr },
-	{ ACTION_MINIMAP, "MINIMAP", "Toggle Minimap", "MiniMapGump::toggle", nullptr, "m", "JOY_LEFT_TRIGGER" },
-	{ ACTION_RECALL, "RECALL", "Use Recall", "MainActor::useRecall", nullptr, "r", nullptr },
-	{ ACTION_INVENTORY, "INVENTORY", "Inventory", "MainActor::useInventory", nullptr, "z", "JOY_LEFT_SHOULDER" },
-	{ ACTION_NEXT_WEAPON, "NEXT_WEAPON", "Next Crusader Weapon", "MainActor::nextWeapon", nullptr, "w", nullptr },
-	{ ACTION_USE_INVENTORY, "USE_INVENTORY", "Use Cru. Inventroy Item", "MainActor::useInventoryItem", nullptr, "u", nullptr },
-	{ ACTION_USE_MEDIKIT, "USE_MEDIKIT", "Use Medical Kit", "MainActor::useMedikit", nullptr, "M", nullptr },
-	{ ACTION_SELECT_ITEMS, "SELECT_ITEM", "Select Cru. Item", "ItemSelectionProcess::startSelection", nullptr, "s", nullptr },
-	{ ACTION_USE_SELECTION, "USE_SELECTION", "Use Cru. Selection", "ItemSelectionProcess::useSelectedItem", nullptr, "RETURN", nullptr },
 	{ ACTION_MENU, "MENU", "Game Menu", "MenuGump::showMenu", nullptr, "ESCAPE", "JOY_Y" },
-	{ ACTION_CLOSE_GUMPS, "CLOSE_GUMPS", "Close Gumps", "GUIApp::closeItemGumps", nullptr, "BACKSPACE", nullptr },
 	{ ACTION_HIGHLIGHT_ITEMS, "HIGHLIGHT_ITEMS", "Show Highlight Items", "GameMapGump::toggleHighlightItems",
 		"GameMapGump::toggleHighlightItems", "TAB", nullptr },
 	{ ACTION_TOGGLE_TOUCHING, "TOUCHING", "Show Touching Items", "GUIApp::toggleShowTouchingItems", nullptr, "h", nullptr },
-	{ ACTION_JUMP, "JUMP", "Jump (fake both-button-click)", "AvatarMoverProcess::startJump", "AvatarMoverProcess::stopJump", "SPACE", nullptr },
 	{ ACTION_TURN_LEFT, "TURN_LEFT", "Turn Left", "AvatarMoverProcess::startTurnLeft", "AvatarMoverProcess::stopTurnLeft", "LEFT", nullptr },
 	{ ACTION_TURN_RIGHT, "TURN_RIGHT", "Turn Right", "AvatarMoverProcess::startTurnRight", "AvatarMoverProcess::stopTurnRight", "RIGHT", nullptr },
 	{ ACTION_MOVE_FORWARD, "MOVE_FORWARD", "Move Forward", "AvatarMoverProcess::startMoveForward", "AvatarMoverProcess::stopMoveForward", "UP", nullptr },
@@ -75,6 +62,29 @@ static const KeybindingRecord KEYS[] = {
 	{ ACTION_NONE, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }
 };
 
+static const KeybindingRecord U8_KEYS[] = {
+	{ ACTION_BEDROLL, "BEDROLL", "Bedroll", "MainActor::useBedroll", nullptr, "b", nullptr },
+	{ ACTION_BACKPACK, "BACKPACK", "Use Backpack", "MainActor::useBackpack", nullptr, "i", nullptr },
+	{ ACTION_KEYRING, "KEYRING", "Keyring", "MainActor::useKeyring", nullptr, "k", nullptr },
+	{ ACTION_MINIMAP, "MINIMAP", "Toggle Minimap", "MiniMapGump::toggle", nullptr, "m", "JOY_LEFT_TRIGGER" },
+	{ ACTION_RECALL, "RECALL", "Use Recall", "MainActor::useRecall", nullptr, "r", nullptr },
+	{ ACTION_INVENTORY, "INVENTORY", "Inventory", "MainActor::useInventory", nullptr, "z", "JOY_LEFT_SHOULDER" },
+	{ ACTION_CLOSE_GUMPS, "CLOSE_GUMPS", "Close Gumps", "GUIApp::closeItemGumps", nullptr, "BACKSPACE", nullptr },
+	{ ACTION_JUMP, "JUMP", "Jump (fake both-button-click)", "AvatarMoverProcess::startJump", "AvatarMoverProcess::stopJump", "SPACE", nullptr },
+	{ ACTION_NONE, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }
+};
+
+static const KeybindingRecord CRUSADER_KEYS[] = {
+	{ ACTION_NEXT_WEAPON, "NEXT_WEAPON", "Next Weapon", "MainActor::nextWeapon", nullptr, "w", nullptr },
+	{ ACTION_NEXT_INVENTORY, "NEXT_INVENTORY", "Next Inventory Item", "MainActor::nextInvItem", nullptr, "i", nullptr },
+	{ ACTION_USE_INVENTORY, "USE_INVENTORY", "Use Inventroy Item", "MainActor::useInventoryItem", nullptr, "u", nullptr },
+	{ ACTION_USE_MEDIKIT, "USE_MEDIKIT", "Use Medical Kit", "MainActor::useMedikit", nullptr, "M", nullptr },
+	{ ACTION_SELECT_ITEMS, "SELECT_ITEM", "Select Item", "ItemSelectionProcess::startSelection", nullptr, "s", nullptr },
+	{ ACTION_USE_SELECTION, "USE_SELECTION", "Use Selection", "ItemSelectionProcess::useSelectedItem", nullptr, "RETURN", nullptr },
+	{ ACTION_ATTACK, "ATTACK", "Attack", "AvatarMoverProcess::tryAttack", nullptr, "SPACE", nullptr },
+	{ ACTION_NONE, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }
+};
+
 static const KeybindingRecord CHEAT_KEYS[] = {
 	{ ACTION_CHEAT_MODE, "CHEAT_MODE", "Toggle Cheat Mode", "Cheat::toggle", nullptr, "BACKQUOTE", nullptr },
 	{ ACTION_CLIPPING, "CLIPPING", "Toggle Clipping", "QuickAvatarMoverProcess::toggleClipping", nullptr, "INSERT", nullptr },
@@ -104,11 +114,13 @@ static const KeybindingRecord DEBUG_KEYS[] = {
 #endif
 
 
-Common::KeymapArray MetaEngine::initKeymaps(bool isMenuActive) {
+Common::KeymapArray MetaEngine::initKeymaps(const Common::String &gameId, bool isMenuActive) {
 	Common::KeymapArray keymapArray;
 
 	// Core keymaps
-	Common::Keymap *keyMap = new Common::Keymap(Common::Keymap::kKeymapTypeGame, "ultima8", _("Ultima VIII"));
+	const char *desc = (gameId == "ultima8" ? _("Ultima VIII") : _("Crusader"));
+
+	Common::Keymap *keyMap = new Common::Keymap(Common::Keymap::kKeymapTypeGame, gameId, desc);
 	keymapArray.push_back(keyMap);
 
 	Common::Action *act;
@@ -125,7 +137,7 @@ Common::KeymapArray MetaEngine::initKeymaps(bool isMenuActive) {
 	act->addDefaultInputMapping("JOY_B");
 	keyMap->addAction(act);
 
-	for (const KeybindingRecord *r = KEYS; r->_id; ++r) {
+	for (const KeybindingRecord *r = COMMON_KEYS; r->_id; ++r) {
 		if (!isMenuActive || !strcmp(r->_id, "MENU")) {
 			act = new Common::Action(r->_id, _(r->_desc));
 			act->setCustomEngineActionEvent(r->_action);
@@ -138,6 +150,19 @@ Common::KeymapArray MetaEngine::initKeymaps(bool isMenuActive) {
 	}
 
 	if (!isMenuActive) {
+		// Game specific keymaps
+		const KeybindingRecord *game_keys = (gameId.equals("ultima8") ? U8_KEYS : CRUSADER_KEYS);
+		for (const KeybindingRecord *r = game_keys; r->_id; ++r) {
+			act = new Common::Action(r->_id, _(r->_desc));
+			act->setCustomEngineActionEvent(r->_action);
+			if (r->_key)
+				act->addDefaultInputMapping(r->_key);
+			if (r->_joy)
+				act->addDefaultInputMapping(r->_joy);
+			keyMap->addAction(act);
+		}
+
+
 		// Cheat keymaps
 		keyMap = new Common::Keymap(Common::Keymap::kKeymapTypeGame, "ultima8_cheats", _("Ultima VIII Cheats"));
 		keymapArray.push_back(keyMap);
@@ -176,7 +201,9 @@ void MetaEngine::setGameMenuActive(bool isActive) {
 	Common::Keymapper *const mapper = g_engine->getEventManager()->getKeymapper();
 	mapper->cleanupGameKeymaps();
 
-	Common::KeymapArray arr = initKeymaps(isActive);
+	const Common::String gameId = CoreApp::get_instance()->getGameInfo()->_name;
+
+	Common::KeymapArray arr = initKeymaps(gameId, isActive);
 
 	for (uint idx = 0; idx < arr.size(); ++idx)
 		mapper->addGameKeymap(arr[idx]);
@@ -197,9 +224,9 @@ void MetaEngine::releaseAction(KeybindingAction keyAction) {
 
 Common::String MetaEngine::getMethod(KeybindingAction keyAction, bool isPress) {
 #ifdef RELEASE_BUILD
-	const KeybindingRecord *KEY_ARRAYS[] = { KEYS, CHEAT_KEYS, nullptr };
+	const KeybindingRecord *KEY_ARRAYS[] = { COMMON_KEYS, U8_KEYS, CRUSADER_KEYS, CHEAT_KEYS, nullptr };
 #else
-	const KeybindingRecord *KEY_ARRAYS[] = { KEYS, CHEAT_KEYS, DEBUG_KEYS, nullptr };
+	const KeybindingRecord *KEY_ARRAYS[] = { COMMON_KEYS, U8_KEYS, CRUSADER_KEYS, CHEAT_KEYS, DEBUG_KEYS, nullptr };
 #endif
 
 	for (const KeybindingRecord **arr = KEY_ARRAYS; *arr; ++arr) {
diff --git a/engines/ultima/ultima8/meta_engine.h b/engines/ultima/ultima8/meta_engine.h
index 659751457f..fedf6bfa0b 100644
--- a/engines/ultima/ultima8/meta_engine.h
+++ b/engines/ultima/ultima8/meta_engine.h
@@ -31,11 +31,11 @@ namespace Ultima8 {
 enum KeybindingAction {
 	ACTION_QUICKSAVE, ACTION_SAVE, ACTION_LOAD, ACTION_BEDROLL, ACTION_COMBAT, ACTION_BACKPACK,
 	ACTION_KEYRING, ACTION_MINIMAP, ACTION_RECALL, ACTION_INVENTORY, ACTION_NEXT_WEAPON,
-	ACTION_USE_INVENTORY, ACTION_USE_MEDIKIT, ACTION_SELECT_ITEMS, ACTION_USE_SELECTION,
-	ACTION_MENU, ACTION_CLOSE_GUMPS, ACTION_HIGHLIGHT_ITEMS, ACTION_TOGGLE_TOUCHING,
-	ACTION_JUMP, ACTION_TURN_LEFT, ACTION_TURN_RIGHT, ACTION_MOVE_FORWARD, ACTION_MOVE_BACK,
-	ACTION_MOVE_UP, ACTION_MOVE_DOWN, ACTION_MOVE_LEFT, ACTION_MOVE_RIGHT,
-	ACTION_MOVE_RUN, ACTION_MOVE_STEP,
+	ACTION_NEXT_INVENTORY, ACTION_USE_INVENTORY, ACTION_USE_MEDIKIT, ACTION_SELECT_ITEMS,
+	ACTION_USE_SELECTION, ACTION_MENU, ACTION_CLOSE_GUMPS, ACTION_HIGHLIGHT_ITEMS,
+	ACTION_TOGGLE_TOUCHING, ACTION_JUMP, ACTION_TURN_LEFT, ACTION_TURN_RIGHT,
+	ACTION_MOVE_FORWARD, ACTION_MOVE_BACK, ACTION_MOVE_UP, ACTION_MOVE_DOWN, ACTION_MOVE_LEFT,
+	ACTION_MOVE_RIGHT, ACTION_MOVE_RUN, ACTION_MOVE_STEP, ACTION_ATTACK,
 
 	ACTION_CHEAT_MODE, ACTION_CLIPPING, ACTION_DEC_SORT_ORDER, ACTION_INC_SORT_ORDER,
 	ACTION_QUICK_MOVE_ASCEND, ACTION_QUICK_MOVE_DESCEND,
@@ -55,11 +55,12 @@ private:
 	 * Get the method to execute
 	 */
 	static Common::String getMethod(KeybindingAction keyAction, bool isPress);
+
 public:
 	/**
 	 * Initialize keymaps
 	 */
-	static Common::KeymapArray initKeymaps(bool isMenuActive = false);
+	static Common::KeymapArray initKeymaps(const Common::String &gameId, bool isMenuActive = false);
 
 	/**
 	 * Execute an engine keymap press action
diff --git a/engines/ultima/ultima8/misc/debugger.cpp b/engines/ultima/ultima8/misc/debugger.cpp
index fa239ad959..0ecce3b594 100644
--- a/engines/ultima/ultima8/misc/debugger.cpp
+++ b/engines/ultima/ultima8/misc/debugger.cpp
@@ -109,6 +109,7 @@ Debugger::Debugger() : Shared::Debugger() {
 	registerCmd("AvatarMoverProcess::stopMoveRun", WRAP_METHOD(Debugger, cmdStopMoveRun));
 	registerCmd("AvatarMoverProcess::startMoveStep", WRAP_METHOD(Debugger, cmdStartMoveStep));
 	registerCmd("AvatarMoverProcess::stopMoveStep", WRAP_METHOD(Debugger, cmdStopMoveStep));
+	registerCmd("AvatarMoverProcess::tryAttack", WRAP_METHOD(Debugger, cmdAttack));
 
 	registerCmd("AudioProcess::listSFX", WRAP_METHOD(Debugger, cmdListSFX));
 	registerCmd("AudioProcess::playSFX", WRAP_METHOD(Debugger, cmdPlaySFX));
@@ -143,6 +144,7 @@ Debugger::Debugger() : Shared::Debugger() {
 	registerCmd("MainActor::useBedroll", WRAP_METHOD(Debugger, cmdUseBedroll));
 	registerCmd("MainActor::useKeyring", WRAP_METHOD(Debugger, cmdUseKeyring));
 	registerCmd("MainActor::nextWeapon", WRAP_METHOD(Debugger, cmdNextWeapon));
+	registerCmd("MainActor::nextInvItem", WRAP_METHOD(Debugger, cmdNextInventory));
 	registerCmd("MainActor::useInventoryItem", WRAP_METHOD(Debugger, cmdUseInventoryItem));
 	registerCmd("MainActor::useMedikit", WRAP_METHOD(Debugger, cmdUseMedikit));
 	registerCmd("MainActor::toggleCombat", WRAP_METHOD(Debugger, cmdToggleCombat));
@@ -1091,13 +1093,19 @@ bool Debugger::cmdUseBackpack(int argc, const char **argv) {
 		return false;
 	}
 	MainActor *av = getMainActor();
-	if (GAME_IS_U8) {
-		Item *backpack = getItem(av->getEquip(7));
-		if (backpack)
-			backpack->callUsecodeEvent_use();
-	} else {
-		av->nextInvItem();
+	Item *backpack = getItem(av->getEquip(7));
+	if (backpack)
+		backpack->callUsecodeEvent_use();
+	return false;
+}
+
+bool Debugger::cmdNextInventory(int argc, const char **argv) {
+	if (Ultima8Engine::get_instance()->isAvatarInStasis()) {
+		debugPrintf("Can't use inventory: avatarInStasis\n");
+		return false;
 	}
+	MainActor *av = getMainActor();
+	av->nextInvItem();
 	return false;
 }
 
@@ -1172,6 +1180,19 @@ bool Debugger::cmdUseKeyring(int argc, const char **argv) {
 	return false;
 }
 
+bool Debugger::cmdAttack(int argc, const char **argv) {
+	Ultima8Engine *engine = Ultima8Engine::get_instance();
+	if (engine->isAvatarInStasis()) {
+		debugPrintf("Can't attack: avatarInStasis\n");
+		return false;
+	}
+	AvatarMoverProcess *proc = engine->getAvatarMoverProcess();
+	if (proc) {
+		proc->tryAttack();
+	}
+	return false;
+}
+
 bool Debugger::cmdStartJump(int argc, const char **argv) {
 	Ultima8Engine *engine = Ultima8Engine::get_instance();
 	engine->moveKeyEvent();
diff --git a/engines/ultima/ultima8/misc/debugger.h b/engines/ultima/ultima8/misc/debugger.h
index cb1bf5b72f..a64e189166 100644
--- a/engines/ultima/ultima8/misc/debugger.h
+++ b/engines/ultima/ultima8/misc/debugger.h
@@ -176,6 +176,7 @@ private:
 	bool cmdStopMoveRun(int argc, const char **argv);
 	bool cmdStartMoveStep(int argc, const char **argv);
 	bool cmdStopMoveStep(int argc, const char **argv);
+	bool cmdAttack(int argc, const char **argv);
 
 	// Audio Process
 	bool cmdListSFX(int argc, const char **argv);
@@ -214,6 +215,7 @@ private:
 	bool cmdUseRecall(int argc, const char **argv);
 	bool cmdUseBedroll(int argc, const char **argv);
 	bool cmdUseKeyring(int argc, const char **argv);
+	bool cmdNextInventory(int argc, const char **argv);
 	bool cmdNextWeapon(int argc, const char **argv);
 	bool cmdToggleCombat(int argc, const char **argv);
 	bool cmdUseInventoryItem(int argc, const char **argv);
diff --git a/engines/ultima/ultima8/world/actors/avatar_mover_process.cpp b/engines/ultima/ultima8/world/actors/avatar_mover_process.cpp
index abe958e9a0..ef0e573664 100644
--- a/engines/ultima/ultima8/world/actors/avatar_mover_process.cpp
+++ b/engines/ultima/ultima8/world/actors/avatar_mover_process.cpp
@@ -931,9 +931,28 @@ bool AvatarMoverProcess::checkTurn(int direction, bool moving) {
 
 bool AvatarMoverProcess::canAttack() {
 	MainActor *avatar = getMainActor();
+	if (GAME_IS_CRUSADER)
+		return avatar->isInCombat();
 	return (_lastFrame > _lastAttack + (25 - avatar->getDex()));
 }
 
+void AvatarMoverProcess::tryAttack() {
+	MainActor *avatar = getMainActor();
+	uint16 dir = avatar->getDir();
+	if (!avatar->isInCombat()) {
+		avatar->setInCombat();
+		waitFor(avatar->doAnim(Animation::readyWeapon, dir));
+	} else {
+		if (canAttack()) {
+			waitFor(avatar->doAnim(Animation::attack, dir));
+			if (GAME_IS_CRUSADER) {
+				// FIXME: put some real values in here.
+				avatar->fireWeapon(0, 0, 16, dir, 1, 1);
+			}
+		}
+	}
+}
+
 void AvatarMoverProcess::onMouseDown(int button, int32 mx, int32 my) {
 	int bid = 0;
 
diff --git a/engines/ultima/ultima8/world/actors/avatar_mover_process.h b/engines/ultima/ultima8/world/actors/avatar_mover_process.h
index f55fcd5dda..681b3e1b95 100644
--- a/engines/ultima/ultima8/world/actors/avatar_mover_process.h
+++ b/engines/ultima/ultima8/world/actors/avatar_mover_process.h
@@ -60,6 +60,8 @@ public:
 		_movementFlags &= ~mask;
 	}
 
+	void tryAttack();
+
 	enum MovementFlags {
 		MOVE_MOUSE_DIRECTION = 0x001,
 		MOVE_RUN = 0x002,


Commit: 19b310346214da4f1ee9bb2cbb0bda715a17d636
    https://github.com/scummvm/scummvm/commit/19b310346214da4f1ee9bb2cbb0bda715a17d636
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-07-28T10:03:39+09:00

Commit Message:
ULTIMA8: Only play combat music for U8

Changed paths:
    engines/ultima/ultima8/world/actors/main_actor.cpp


diff --git a/engines/ultima/ultima8/world/actors/main_actor.cpp b/engines/ultima/ultima8/world/actors/main_actor.cpp
index 6b82a1ae4f..19fa077753 100644
--- a/engines/ultima/ultima8/world/actors/main_actor.cpp
+++ b/engines/ultima/ultima8/world/actors/main_actor.cpp
@@ -479,12 +479,14 @@ int MainActor::getDamageAmount() const {
 
 void MainActor::setInCombat() {
 	setActorFlag(ACT_INCOMBAT);
-	MusicProcess::get_instance()->playCombatMusic(98); // CONSTANT!
+	if (GAME_IS_U8)
+		MusicProcess::get_instance()->playCombatMusic(98); // CONSTANT!
 }
 
 void MainActor::clearInCombat() {
 	clearActorFlag(ACT_INCOMBAT);
-	MusicProcess::get_instance()->restoreMusic();
+	if (GAME_IS_U8)
+		MusicProcess::get_instance()->restoreMusic();
 }
 
 ProcId MainActor::die(uint16 damageType) {


Commit: 584abe0906af3308fa6de83ac740b46384485662
    https://github.com/scummvm/scummvm/commit/584abe0906af3308fa6de83ac740b46384485662
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-07-28T10:03:39+09:00

Commit Message:
ULTIMA8: Only do 'actor specials' for U8

Changed paths:
    engines/ultima/ultima8/world/actors/actor_anim_process.cpp


diff --git a/engines/ultima/ultima8/world/actors/actor_anim_process.cpp b/engines/ultima/ultima8/world/actors/actor_anim_process.cpp
index fbb28d596c..c1cbb5d6c8 100644
--- a/engines/ultima/ultima8/world/actors/actor_anim_process.cpp
+++ b/engines/ultima/ultima8/world/actors/actor_anim_process.cpp
@@ -357,6 +357,10 @@ void ActorAnimProcess::doSpecial() {
 	Actor *a = getActor(_itemNum);
 	assert(a);
 
+	// All this stuff is U8 specific.
+	if (!GAME_IS_U8)
+		return;
+
 	// play SFX when Avatar draws/sheathes weapon
 	if (_itemNum == 1 && (_action == Animation::readyWeapon ||
 	                      _action == Animation::unreadyWeapon) &&
@@ -417,7 +421,7 @@ void ActorAnimProcess::doSpecial() {
 	}
 
 	// ghost's fireball
-	if (a->getShape() == 0x19d && GAME_IS_U8) {
+	if (a->getShape() == 0x19d) {
 		Actor *av = getMainActor();
 		if (a->getRange(*av) < 96) {
 			a->setActorFlag(Actor::ACT_DEAD);


Commit: 8a63328011cb9d260d9b71dca047bb7f152c12f0
    https://github.com/scummvm/scummvm/commit/8a63328011cb9d260d9b71dca047bb7f152c12f0
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-07-28T10:03:39+09:00

Commit Message:
ULTIMA8: Add z key to centre camera in Crusader

Changed paths:
    engines/ultima/ultima8/meta_engine.cpp
    engines/ultima/ultima8/meta_engine.h
    engines/ultima/ultima8/misc/debugger.cpp
    engines/ultima/ultima8/misc/debugger.h


diff --git a/engines/ultima/ultima8/meta_engine.cpp b/engines/ultima/ultima8/meta_engine.cpp
index 90d2e52398..03026e36d7 100644
--- a/engines/ultima/ultima8/meta_engine.cpp
+++ b/engines/ultima/ultima8/meta_engine.cpp
@@ -82,6 +82,7 @@ static const KeybindingRecord CRUSADER_KEYS[] = {
 	{ ACTION_SELECT_ITEMS, "SELECT_ITEM", "Select Item", "ItemSelectionProcess::startSelection", nullptr, "s", nullptr },
 	{ ACTION_USE_SELECTION, "USE_SELECTION", "Use Selection", "ItemSelectionProcess::useSelectedItem", nullptr, "RETURN", nullptr },
 	{ ACTION_ATTACK, "ATTACK", "Attack", "AvatarMoverProcess::tryAttack", nullptr, "SPACE", nullptr },
+	{ ACTION_CAMERA_AVATAR, "CAMERA_AVATAR", "Focus Camera on Silencer", "CameraProcess::moveToAvatar", nullptr, "z", nullptr },
 	{ ACTION_NONE, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }
 };
 
diff --git a/engines/ultima/ultima8/meta_engine.h b/engines/ultima/ultima8/meta_engine.h
index fedf6bfa0b..9f0054a54a 100644
--- a/engines/ultima/ultima8/meta_engine.h
+++ b/engines/ultima/ultima8/meta_engine.h
@@ -35,7 +35,7 @@ enum KeybindingAction {
 	ACTION_USE_SELECTION, ACTION_MENU, ACTION_CLOSE_GUMPS, ACTION_HIGHLIGHT_ITEMS,
 	ACTION_TOGGLE_TOUCHING, ACTION_JUMP, ACTION_TURN_LEFT, ACTION_TURN_RIGHT,
 	ACTION_MOVE_FORWARD, ACTION_MOVE_BACK, ACTION_MOVE_UP, ACTION_MOVE_DOWN, ACTION_MOVE_LEFT,
-	ACTION_MOVE_RIGHT, ACTION_MOVE_RUN, ACTION_MOVE_STEP, ACTION_ATTACK,
+	ACTION_MOVE_RIGHT, ACTION_MOVE_RUN, ACTION_MOVE_STEP, ACTION_ATTACK, ACTION_CAMERA_AVATAR,
 
 	ACTION_CHEAT_MODE, ACTION_CLIPPING, ACTION_DEC_SORT_ORDER, ACTION_INC_SORT_ORDER,
 	ACTION_QUICK_MOVE_ASCEND, ACTION_QUICK_MOVE_DESCEND,
diff --git a/engines/ultima/ultima8/misc/debugger.cpp b/engines/ultima/ultima8/misc/debugger.cpp
index 0ecce3b594..0c4f611105 100644
--- a/engines/ultima/ultima8/misc/debugger.cpp
+++ b/engines/ultima/ultima8/misc/debugger.cpp
@@ -43,6 +43,7 @@
 #include "ultima/ultima8/usecode/uc_machine.h"
 #include "ultima/ultima8/usecode/bit_set.h"
 #include "ultima/ultima8/world/world.h"
+#include "ultima/ultima8/world/camera_process.h"
 #include "ultima/ultima8/world/get_object.h"
 #include "ultima/ultima8/world/item_factory.h"
 #include "ultima/ultima8/world/actors/quick_avatar_mover_process.h"
@@ -111,6 +112,8 @@ Debugger::Debugger() : Shared::Debugger() {
 	registerCmd("AvatarMoverProcess::stopMoveStep", WRAP_METHOD(Debugger, cmdStopMoveStep));
 	registerCmd("AvatarMoverProcess::tryAttack", WRAP_METHOD(Debugger, cmdAttack));
 
+	registerCmd("CameraProcess::moveToAvatar", WRAP_METHOD(Debugger, cmdCameraOnAvatar));
+
 	registerCmd("AudioProcess::listSFX", WRAP_METHOD(Debugger, cmdListSFX));
 	registerCmd("AudioProcess::playSFX", WRAP_METHOD(Debugger, cmdPlaySFX));
 	registerCmd("AudioProcess::stopSFX", WRAP_METHOD(Debugger, cmdStopSFX));
@@ -1193,6 +1196,16 @@ bool Debugger::cmdAttack(int argc, const char **argv) {
 	return false;
 }
 
+bool Debugger::cmdCameraOnAvatar(int argc, const char **argv) {
+	MainActor *actor = getMainActor();
+	if (actor) {
+		int32 x, y, z;
+		actor->getLocation(x, y, z);
+		CameraProcess::SetCameraProcess(new CameraProcess(x, y, z));
+	}
+	return false;
+}
+
 bool Debugger::cmdStartJump(int argc, const char **argv) {
 	Ultima8Engine *engine = Ultima8Engine::get_instance();
 	engine->moveKeyEvent();
diff --git a/engines/ultima/ultima8/misc/debugger.h b/engines/ultima/ultima8/misc/debugger.h
index a64e189166..325c956dbb 100644
--- a/engines/ultima/ultima8/misc/debugger.h
+++ b/engines/ultima/ultima8/misc/debugger.h
@@ -178,6 +178,8 @@ private:
 	bool cmdStopMoveStep(int argc, const char **argv);
 	bool cmdAttack(int argc, const char **argv);
 
+	bool cmdCameraOnAvatar(int argc, const char **argv);
+
 	// Audio Process
 	bool cmdListSFX(int argc, const char **argv);
 	bool cmdStopSFX(int argc, const char **argv);


Commit: 5ce24939d08982612f08c1d3a92a99ae6f69b3a2
    https://github.com/scummvm/scummvm/commit/5ce24939d08982612f08c1d3a92a99ae6f69b3a2
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-07-28T10:51:59+09:00

Commit Message:
ULTIMA8: Small fixes to make firing gun work in Crusader

Changed paths:
    engines/ultima/ultima8/world/actors/avatar_mover_process.cpp
    engines/ultima/ultima8/world/damage_info.cpp
    engines/ultima/ultima8/world/damage_info.h
    engines/ultima/ultima8/world/item.cpp
    engines/ultima/ultima8/world/item.h
    engines/ultima/ultima8/world/super_sprite_process.cpp
    engines/ultima/ultima8/world/target_reticle_process.cpp


diff --git a/engines/ultima/ultima8/world/actors/avatar_mover_process.cpp b/engines/ultima/ultima8/world/actors/avatar_mover_process.cpp
index ef0e573664..3c6a28c36e 100644
--- a/engines/ultima/ultima8/world/actors/avatar_mover_process.cpp
+++ b/engines/ultima/ultima8/world/actors/avatar_mover_process.cpp
@@ -947,7 +947,9 @@ void AvatarMoverProcess::tryAttack() {
 			waitFor(avatar->doAnim(Animation::attack, dir));
 			if (GAME_IS_CRUSADER) {
 				// FIXME: put some real values in here.
-				avatar->fireWeapon(0, 0, 16, dir, 1, 1);
+				int32 xs, ys, zs;
+				avatar->getFootpadWorld(xs, ys, zs);
+				avatar->fireWeapon(xs / 2, ys / 2, zs / 2, dir, 1, 1);
 			}
 		}
 	}
diff --git a/engines/ultima/ultima8/world/damage_info.cpp b/engines/ultima/ultima8/world/damage_info.cpp
index fbbc394473..cd8f4efae8 100644
--- a/engines/ultima/ultima8/world/damage_info.cpp
+++ b/engines/ultima/ultima8/world/damage_info.cpp
@@ -56,8 +56,15 @@ bool DamageInfo::applyToItem(Item *item, uint16 points) const {
 	item->setDamagePoints(0);
 	item->setFlag(Item::FLG_GUMP_OPEN | Item::FLG_BROKEN);
 
+	// Get some data out of the item before we potentially delete
+	// it by explosion
+	uint16 q = item->getQuality();
+	int32 x, y , z;
+	item->getLocation(x, y, z);
+	int32 mapnum = item->getMapNum();
+
 	if (explode()) {
-		item->explode(explosionType(), explodeDestroysItem());
+		item->explode(explosionType(), explodeDestroysItem(), explodeWithDamage());
 	}
 	if (_sound) {
 		AudioProcess *audio = AudioProcess::get_instance();
@@ -66,14 +73,12 @@ bool DamageInfo::applyToItem(Item *item, uint16 points) const {
 		}
 	}
 	if (replaceItem()) {
-		uint16 q = item->getQuality();
-		int32 x, y, z;
-		item->getLocation(x, y, z);
 		uint16 replacementShape = getReplacementShape();
 		uint8 replacementFrame = getReplacementFrame();
-		Item *newitem = ItemFactory::createItem(replacementShape, replacementFrame, q, 0, 0, 0, 0, true);
-		newitem->setLocation(x, y, z);
-	} else {
+		Item *newitem = ItemFactory::createItem(replacementShape, replacementFrame, q, 0, 0, mapnum, 0, true);
+		newitem->move(x, y, z);
+	} else if (!explodeDestroysItem()) {
+		assert(!explodeDestroysItem());
 		if (frameDataIsAbsolute()) {
 			int frameval = 1;
 			if (_data[1])
diff --git a/engines/ultima/ultima8/world/damage_info.h b/engines/ultima/ultima8/world/damage_info.h
index aaa72c590e..62bb68501f 100644
--- a/engines/ultima/ultima8/world/damage_info.h
+++ b/engines/ultima/ultima8/world/damage_info.h
@@ -46,11 +46,11 @@ public:
 	bool frameDataIsAbsolute() const {
 		return (_flags >> 7) & 1;
 	}
-	bool explodeDestroysItem() const {
+	bool replaceItem() const {
 		return (_flags >> 6) & 1;
 	}
-	bool replaceItem() const {
-		return (_flags >> 4) & 1;
+	bool explodeDestroysItem() const {
+		return (_flags >> 5) & 1;
 	}
 	bool explodeWithDamage() const {
 		return (_flags >> 3) & 1;
@@ -83,10 +83,10 @@ protected:
 	}
 
 
-	// Flags are ABxCDEEF
+	// Flags are ABCxDEEF
 	// A = frame data is absolute (not relative to current)
-	// B = item destroyed after explosion
-	// C = item is replaced when destroyed
+	// B = item is replaced when destroyed
+	// C = item destroyed after explosion
 	// D = explosion damages surrounding items
 	// EE = 2 bits for explosion type
 	// F = item takes damage
diff --git a/engines/ultima/ultima8/world/item.cpp b/engines/ultima/ultima8/world/item.cpp
index 8c8a29fe84..b6c7a12ae1 100644
--- a/engines/ultima/ultima8/world/item.cpp
+++ b/engines/ultima/ultima8/world/item.cpp
@@ -1216,14 +1216,18 @@ uint16 Item::fireWeapon(int32 x, int32 y, int32 z, int dir, int firetype, char s
 			// animation here (lines 185~208 of disasm)
 		}
 
-		Item *target;
+		Item *target = nullptr;
 		if (someflag) {
-			target = getControlledActor();
-		} else {
-			target = currentmap->findBestTargetItem(x, y, dir);
+			if (this != getControlledActor()) {
+				target = getControlledActor();
+			} else {
+				target = currentmap->findBestTargetItem(ix, iy, dir);
+			}
 		}
 
-		int32 tx, ty, tz;
+		int32 tx = -1;
+		int32 ty = 0;
+		int32 tz = 0;
 		if (target) {
 			int32 tsx, tsy, tsz;
 			target->getCentre(tx, ty, tz);
@@ -1248,8 +1252,6 @@ uint16 Item::fireWeapon(int32 x, int32 y, int32 z, int dir, int firetype, char s
 					}
 				}
 			}
-		} else {
-			tx = -1;
 		}
 
 		// TODO: check if we need the equivalent of FUN_1130_0299 here..
@@ -1271,6 +1273,7 @@ uint16 Item::fireWeapon(int32 x, int32 y, int32 z, int dir, int firetype, char s
 			} else if (this == getControlledActor() && crosshair) {
 				// Shoot toward the crosshair
 				crosshair->getLocation(ssx, ssy, ssz);
+				ssz = iz;
 			} else {
 				// Just send the projectile off into the distance
 				// CHECKME: This is not how the game does it - it has different
@@ -1280,9 +1283,10 @@ uint16 Item::fireWeapon(int32 x, int32 y, int32 z, int dir, int firetype, char s
 				ssz = iz;
 			}
 
+			uint16 targetid = (target ? target->getObjId() : 0);
 			ssp = new SuperSpriteProcess(BULLET_SPLASH_SHAPE, spriteframe,
 										 ix, iy, iz, ssx, ssy, ssz, firetype,
-										 damage, _objId, target->getObjId(), someflag);
+										 damage, _objId, targetid, someflag);
 			Kernel::get_instance()->addProcess(ssp);
 		}
 	}
@@ -1647,7 +1651,7 @@ void Item::leaveFastArea() {
 	        (_flags & FLG_FASTAREA))
 		callUsecodeEvent_leaveFastArea();
 
-	// If we have a _gump open, close it (unless we're in a container)
+	// If we have a gump open, close it (unless we're in a container)
 	if (!_parent && (_flags & FLG_GUMP_OPEN)) {
 		Gump *g = Ultima8Engine::get_instance()->getGump(_gump);
 		if (g) g->Close();
@@ -1719,10 +1723,10 @@ void Item::closeGump() {
 	if (!(_flags & FLG_GUMP_OPEN)) return;
 
 	Gump *g = Ultima8Engine::get_instance()->getGump(_gump);
-	assert(g);
-	g->Close();
+	if (g)
+		g->Close();
 
-	// can we already clear _gump here, or do we need to wait for the _gump
+	// can we already clear gump here, or do we need to wait for the gump
 	// to really close??
 	clearGump();
 }
@@ -1846,14 +1850,14 @@ void Item::hurl(int xs, int ys, int zs, int grav) {
 }
 
 
-void Item::explode(int explosion_type, bool destroy_item) {
+void Item::explode(int explosion_type, bool destroy_item, bool cause_damage) {
 	Process *p;
 
 	if (GAME_IS_CRUSADER) {
 		setFlag(FLG_BROKEN);
 		// TODO: original game puts them at cx/cy/cz, but that looks wrong..
-		//int32 cx, cy, cz;
-		//getCentre(cx, cy, cz);
+		int32 cx, cy, cz;
+		getCentre(cx, cy, cz);
 		static const int expshapes[] = {0x31C, 0x31F, 0x326, 0x320, 0x321, 0x324, 0x323, 0x325};
 		int rnd = getRandom();
 		int spriteno;
@@ -1872,7 +1876,7 @@ void Item::explode(int explosion_type, bool destroy_item) {
 			break;
 		}
 		p = new SpriteProcess(spriteno, 0, 39, 1, 1, //!! constants
-	                               _x, _y, _z);
+	                               _x, _y, cz);
 	} else {
 		p = new SpriteProcess(578, 20, 34, 1, 1, //!! constants
 	                               _x, _y, _z);
@@ -1899,6 +1903,9 @@ void Item::explode(int explosion_type, bool destroy_item) {
 		// WARNING: we are deleted at this point
 	}
 
+	if (!cause_damage)
+		return;
+
 	UCList itemlist(2);
 	LOOPSCRIPT(script, LS_TOKEN_TRUE); // we want all items
 	CurrentMap *currentmap = World::get_instance()->getCurrentMap();
diff --git a/engines/ultima/ultima8/world/item.h b/engines/ultima/ultima8/world/item.h
index 58935aac91..eb65793009 100644
--- a/engines/ultima/ultima8/world/item.h
+++ b/engines/ultima/ultima8/world/item.h
@@ -372,8 +372,9 @@ public:
 	//! Get the volume this item takes up in a container
 	virtual uint32 getVolume() const;
 
-	//! explode with explosion type (0,1,2) and flag of whether to destroy the item.
-	void explode(int explosion_type, bool destroy_item);
+	//! explode with explosion type (0,1,2), whether to destroy the item,
+	//! and whether to cause splash damage.
+	void explode(int explosion_type, bool destroy_item, bool cause_damage = true);
 
 	//! get the damage type this object does when hitting something
 	virtual uint16 getDamageType() const;
diff --git a/engines/ultima/ultima8/world/super_sprite_process.cpp b/engines/ultima/ultima8/world/super_sprite_process.cpp
index 7631a1ff76..ae49b3ef5b 100644
--- a/engines/ultima/ultima8/world/super_sprite_process.cpp
+++ b/engines/ultima/ultima8/world/super_sprite_process.cpp
@@ -107,7 +107,8 @@ SuperSpriteProcess::SuperSpriteProcess(int shape, int frame, int sx, int sy, int
 	}
 
 	float travel = _destpt.maxDistXYZ(_nextpt);
-	float speed = firetypedat->getCellsPerRound() * 32.0f;
+	// FIXME: how to get this scaled correctly?
+	float speed = firetypedat->getCellsPerRound() * 128.0f;
 	float rounds = travel / speed;
 	if (rounds < 1)
 		rounds = 1;
@@ -288,7 +289,11 @@ void SuperSpriteProcess::hitAndFinish() {
 									_source, true, &hits);
 
 	if (collision && hits.size()) {
-		_item0x77 = hits.front()._item;
+		const CurrentMap::SweepItem &firsthit = hits.front();
+		_item0x77 = firsthit._item;
+		int32 hitpt[3] = {pt.x, pt.y, pt.z};
+		firsthit.GetInterpolatedCoords(hitpt, start, end);
+		pt = Point3(hitpt[0], hitpt[1], hitpt[2]);
 	}
 
 	Item *item = getItem(_item0x77);
diff --git a/engines/ultima/ultima8/world/target_reticle_process.cpp b/engines/ultima/ultima8/world/target_reticle_process.cpp
index b392c72295..3badaf9bd2 100644
--- a/engines/ultima/ultima8/world/target_reticle_process.cpp
+++ b/engines/ultima/ultima8/world/target_reticle_process.cpp
@@ -119,8 +119,10 @@ void TargetReticleProcess::putTargetReticleOnItem(Item *item) {
 	int32 x, y, z;
 
 	// TODO: the game does a bunch of other maths here to pick the right location.
-	// This is an over-simplification.
+	// This is an over-simplification and is usually too high so it's
+	// hacked a little lower.
 	item->getCentre(x, y, z);
+	z -= 8;
 
 	Process *p = new SpriteProcess(0x59a, 0, 5, 1, 10, x, y, z, false);
 




More information about the Scummvm-git-logs mailing list