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

dreammaster paulfgilbert at gmail.com
Sat May 2 03:36:51 UTC 2020


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

Summary:
e403c7c6f5 ULTIMA4: Switch combat to use the normal keybindings action
fc3dbbe426 ULTIMA4: Attack for combat controller


Commit: e403c7c6f51b2ed5758078ff4d528a2bb3317dcf
    https://github.com/scummvm/scummvm/commit/e403c7c6f51b2ed5758078ff4d528a2bb3317dcf
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-05-01T18:47:18-07:00

Commit Message:
ULTIMA4: Switch combat to use the normal keybindings action

I'll want to still accept keys that are disallowed during combat,
so they'll funneled through to action execution and give a proper
'Not Here' response, rather than being completely ignored

Changed paths:
    engines/ultima/ultima4/meta_engine.cpp


diff --git a/engines/ultima/ultima4/meta_engine.cpp b/engines/ultima/ultima4/meta_engine.cpp
index 20bdb80bd8..1312a5e059 100644
--- a/engines/ultima/ultima4/meta_engine.cpp
+++ b/engines/ultima/ultima4/meta_engine.cpp
@@ -170,16 +170,8 @@ static const KeysRecord DIRECTION_RECORDS[] = {
 	{ nullptr, nullptr, nullptr }
 };
 
-static const KeysRecord COMBAT_RECORDS[] = {
-	{ "ultima4", "Ultima IV", COMBAT_KEYS },
-	{ "ultima4_config", "Ultima IV - Configuration", CONFIG_KEYS },
-	{ "ultima4_party", "Ultima IV - Party", PARTY_KEYS },
-	{ "ultima4_cheats", "Ultima IV - Cheats", CHEAT_KEYS },
-	{ nullptr, nullptr, nullptr }
-};
-
 static const KeysRecord *MODE_RECORDS[5] = {
-	NORMAL_RECORDS, INPUT_RECORDS, DIRECTION_RECORDS, COMBAT_RECORDS
+	NORMAL_RECORDS, INPUT_RECORDS, DIRECTION_RECORDS, NORMAL_RECORDS
 };
 
 Common::KeymapArray MetaEngine::initKeymaps(KeybindingMode mode) {


Commit: fc3dbbe4262cfbd08a077742876199746a01a197
    https://github.com/scummvm/scummvm/commit/fc3dbbe4262cfbd08a077742876199746a01a197
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-05-01T20:36:39-07:00

Commit Message:
ULTIMA4: Attack for combat controller

Changed paths:
    engines/ultima/ultima4/controllers/combat_controller.cpp
    engines/ultima/ultima4/controllers/combat_controller.h
    engines/ultima/ultima4/controllers/game_controller.cpp
    engines/ultima/ultima4/controllers/game_controller.h
    engines/ultima/ultima4/core/debugger.cpp
    engines/ultima/ultima4/core/debugger_actions.cpp
    engines/ultima/ultima4/core/debugger_actions.h


diff --git a/engines/ultima/ultima4/controllers/combat_controller.cpp b/engines/ultima/ultima4/controllers/combat_controller.cpp
index 9fedb0125a..b387fc2b12 100644
--- a/engines/ultima/ultima4/controllers/combat_controller.cpp
+++ b/engines/ultima/ultima4/controllers/combat_controller.cpp
@@ -871,10 +871,6 @@ bool CombatController::keyPressed(int key) {
 		break;
 	}
 
-	case 'a':
-		attack();
-		break;
-
 	case 'c':
 		g_screen->screenMessage("Cast Spell!\n");
 		g_debugger->castSpell(_focus);
@@ -1008,17 +1004,19 @@ bool CombatController::keyPressed(int key) {
 	return valid;
 }
 
-void CombatController::attack() {
+void CombatController::attack(Direction dir, int distance) {
 	g_screen->screenMessage("Dir: ");
 
 	ReadDirController dirController;
 #ifdef IOS_ULTIMA4
 	U4IOS::IOSDirectionHelper directionPopup;
 #endif
-	eventHandler->pushController(&dirController);
-	Direction dir = dirController.waitFor();
-	if (dir == DIR_NONE)
-		return;
+	if (dir == DIR_NONE) {
+		eventHandler->pushController(&dirController);
+		dir = dirController.waitFor();
+		if (dir == DIR_NONE)
+			return;
+	}
 	g_screen->screenMessage("%s\n", getDirectionName(dir));
 
 	PartyMember *attacker = getCurrentPlayer();
@@ -1027,9 +1025,14 @@ void CombatController::attack() {
 	int range = weapon->getRange();
 	if (weapon->canChooseDistance()) {
 		g_screen->screenMessage("Range: ");
-		int choice = ReadChoiceController::get("123456789");
-		if ((choice - '0') >= 1 && (choice - '0') <= weapon->getRange()) {
-			range = choice - '0';
+
+		if (distance == -1) {
+			int choice = ReadChoiceController::get("123456789");
+			distance = choice - '0';
+		}
+
+		if (distance >= 1 && distance <= weapon->getRange()) {
+			range = distance;
 			g_screen->screenMessage("%d\n", range);
 		} else {
 			return;
@@ -1052,7 +1055,7 @@ void CombatController::attack() {
 	if (path.size() > 0)
 		targetCoords = path.back();
 
-	int distance = 1;
+	distance = 1;
 	for (Std::vector<Coords>::iterator i = path.begin(); i != path.end(); i++) {
 		if (attackAt(*i, attacker, MASK_DIR(dir), range, distance)) {
 			foundTarget = true;
diff --git a/engines/ultima/ultima4/controllers/combat_controller.h b/engines/ultima/ultima4/controllers/combat_controller.h
index fe5acf1e56..74372133d1 100644
--- a/engines/ultima/ultima4/controllers/combat_controller.h
+++ b/engines/ultima/ultima4/controllers/combat_controller.h
@@ -157,10 +157,7 @@ public:
 	virtual void awardLoot();
 
 	// attack functions
-	/**
-	 * Key handler for choosing an attack direction
-	 */
-	void attack();
+	void attack(Direction dir = DIR_NONE, int distance = 0);
 	bool attackAt(const Coords &coords, PartyMember *attacker, int dir, int range, int distance);
 	bool rangedAttack(const Coords &coords, Creature *attacker);
 	void rangedMiss(const Coords &coords, Creature *attacker);
diff --git a/engines/ultima/ultima4/controllers/game_controller.cpp b/engines/ultima/ultima4/controllers/game_controller.cpp
index 26395d503f..0a8a1581cf 100644
--- a/engines/ultima/ultima4/controllers/game_controller.cpp
+++ b/engines/ultima/ultima4/controllers/game_controller.cpp
@@ -776,5 +776,68 @@ bool GameController::createBalloon(Map *map) {
 	return true;
 }
 
+void GameController::attack(Direction dir) {
+	g_screen->screenMessage("Attack: ");
+	if (g_context->_party->isFlying()) {
+		g_screen->screenMessage("\n%cDrift only!%c\n", FG_GREY, FG_WHITE);
+		return;
+	}
+
+	if (dir == DIR_NONE)
+		dir = gameGetDirection();
+
+	if (dir == DIR_NONE) {
+		g_screen->screenMessage("\n");
+		return;
+	}
+
+	Std::vector<Coords> path = gameGetDirectionalActionPath(
+		MASK_DIR(dir), MASK_DIR_ALL, g_context->_location->_coords,
+		1, 1, nullptr, true);
+	for (Std::vector<Coords>::iterator i = path.begin(); i != path.end(); i++) {
+		if (attackAt(*i))
+			return;
+	}
+
+	g_screen->screenMessage("%cNothing to Attack!%c\n", FG_GREY, FG_WHITE);
+}
+
+bool GameController::attackAt(const Coords &coords) {
+	Object *under;
+	const Tile *ground;
+	Creature *m;
+
+	m = dynamic_cast<Creature *>(g_context->_location->_map->objectAt(coords));
+	// Nothing attackable: move on to next tile
+	if (m == nullptr || !m->isAttackable())
+		return false;
+
+	// Attack successful
+	/// TODO: CHEST: Make a user option to not make chests change battlefield
+	/// map (1 of 2)
+	ground = g_context->_location->_map->tileTypeAt(g_context->_location->_coords, WITH_GROUND_OBJECTS);
+	if (!ground->isChest()) {
+		ground = g_context->_location->_map->tileTypeAt(g_context->_location->_coords, WITHOUT_OBJECTS);
+		if ((under = g_context->_location->_map->objectAt(g_context->_location->_coords)) &&
+			under->getTile().getTileType()->isShip())
+			ground = under->getTile().getTileType();
+	}
+
+	// You're attacking a townsperson!  Alert the guards!
+	if ((m->getType() == Object::PERSON) && (m->getMovementBehavior() != MOVEMENT_ATTACK_AVATAR))
+		g_context->_location->_map->alertGuards();
+
+	// Not good karma to be killing the innocent.  Bad avatar!
+	if (m->isGood() || /* attacking a good creature */
+			/* attacking a docile (although possibly evil) person in town */
+		((m->getType() == Object::PERSON) && (m->getMovementBehavior() != MOVEMENT_ATTACK_AVATAR)))
+		g_context->_party->adjustKarma(KA_ATTACKED_GOOD);
+
+	CombatController *cc = new CombatController(CombatMap::mapForTile(ground, g_context->_party->getTransport().getTileType(), m));
+	cc->init(m);
+	cc->begin();
+	return false;
+}
+
 } // End of namespace Ultima4
 } // End of namespace Ultima
diff --git a/engines/ultima/ultima4/controllers/game_controller.h b/engines/ultima/ultima4/controllers/game_controller.h
index d69d5da2bb..afc0571a13 100644
--- a/engines/ultima/ultima4/controllers/game_controller.h
+++ b/engines/ultima/ultima4/controllers/game_controller.h
@@ -44,6 +44,68 @@ namespace Ultima4 {
  */
 class GameController : public Controller, public Observer<Party *, PartyEvent &>, public Observer<Location *, MoveEvent &>,
 	public TurnCompleter {
+private:
+	/**
+	 * Handles feedback after avatar moved during normal 3rd-person view.
+	 */
+	void avatarMoved(MoveEvent &event);
+
+	/**
+	 * Handles feedback after moving the avatar in the 3-d dungeon view.
+	 */
+	void avatarMovedInDungeon(MoveEvent &event);
+
+	/**
+	 * Removes creatures from the current map if they are too far away from the avatar
+	 */
+	void creatureCleanup();
+
+	/**
+	 * Handles trolls under bridges
+	 */
+	void checkBridgeTrolls();
+
+	/**
+	 * Checks creature conditions and spawns new creatures if necessary
+	 */
+	void checkRandomCreatures();
+
+	/**
+	 * Checks for valid conditions and handles
+	 * special creatures guarding the entrance to the
+	 * abyss and to the shrine of spirituality
+	 */
+	void checkSpecialCreatures(Direction dir);
+
+	/**
+	 * Checks for and handles when the avatar steps on a moongate
+	 */
+	bool checkMoongates();
+
+	/**
+	 * Creates the balloon near Hythloth, but only if the balloon doesn't already exists somewhere
+	 */
+	bool createBalloon(Map *map);
+
+	/**
+	 * Attempts to attack a creature at map coordinates x,y.  If no
+	 * creature is present at that point, zero is returned.
+	 */
+	bool attackAt(const Coords &coords);
+public:
+	/**
+	 * Show an attack flash at x, y on the current map.
+	 * This is used for 'being hit' or 'being missed'
+	 * by weapons, cannon fire, spells, etc.
+	 */
+	static void flashTile(const Coords &coords, MapTile tile, int timeFactor);
+
+	static void flashTile(const Coords &coords, const Common::String &tilename, int timeFactor);
+	static void doScreenAnimationsWhilePausing(int timeFactor);
+public:
+	TileView _mapArea;
+	bool _paused;
+	int _pausedTimer;
 public:
 	GameController();
 
@@ -113,62 +175,7 @@ public:
 	 */
 	void updateMoons(bool showmoongates);
 
-	/**
-	 * Show an attack flash at x, y on the current map.
-	 * This is used for 'being hit' or 'being missed'
-	 * by weapons, cannon fire, spells, etc.
-	 */
-	static void flashTile(const Coords &coords, MapTile tile, int timeFactor);
-
-	static void flashTile(const Coords &coords, const Common::String &tilename, int timeFactor);
-	static void doScreenAnimationsWhilePausing(int timeFactor);
-
-	TileView _mapArea;
-	bool _paused;
-	int _pausedTimer;
-
-private:
-	/**
-	 * Handles feedback after avatar moved during normal 3rd-person view.
-	 */
-	void avatarMoved(MoveEvent &event);
-
-	/**
-	 * Handles feedback after moving the avatar in the 3-d dungeon view.
-	 */
-	void avatarMovedInDungeon(MoveEvent &event);
-
-	/**
-	 * Removes creatures from the current map if they are too far away from the avatar
-	 */
-	void creatureCleanup();
-
-	/**
-	 * Handles trolls under bridges
-	 */
-	void checkBridgeTrolls();
-
-	/**
-	 * Checks creature conditions and spawns new creatures if necessary
-	 */
-	void checkRandomCreatures();
-
-	/**
-	 * Checks for valid conditions and handles
-	 * special creatures guarding the entrance to the
-	 * abyss and to the shrine of spirituality
-	 */
-	void checkSpecialCreatures(Direction dir);
-
-	/**
-	 * Checks for and handles when the avatar steps on a moongate
-	 */
-	bool checkMoongates();
-
-	/**
-	 * Creates the balloon near Hythloth, but only if the balloon doesn't already exists somewhere
-	 */
-	bool createBalloon(Map *map);
+	void attack(Direction dir = DIR_NONE);
 };
 
 extern GameController *g_game;
diff --git a/engines/ultima/ultima4/core/debugger.cpp b/engines/ultima/ultima4/core/debugger.cpp
index 2e8ddbe1ac..3d9a9c8cf1 100644
--- a/engines/ultima/ultima4/core/debugger.cpp
+++ b/engines/ultima/ultima4/core/debugger.cpp
@@ -253,40 +253,22 @@ bool Debugger::cmdMove(int argc, const char **argv) {
 }
 
 bool Debugger::cmdAttack(int argc, const char **argv) {
-	Direction dir;
-
-	if (argc != 2 && isDebuggerActive()) {
-		print("attack <direction>");
+	if (argc < 2 && isDebuggerActive()) {
+		print("attack <direction> [distance]");
 		return true;
 	}
 
-	printN("Attack: ");
-	if (g_context->_party->isFlying()) {
-		print("\n%cDrift only!%c", FG_GREY, FG_WHITE);
-		return isDebuggerActive();
-	}
+	Direction dir = (argc >= 2) ? directionFromName(argv[1]) : DIR_NONE;
+	int range = (argc >= 3) ? strToInt(argv[2]) : -1;
 
-	if (argc == 2) {
-		dir = directionFromName(argv[1]);
-	} else {
-		dir = gameGetDirection();
-	}
+	CombatController *cc = dynamic_cast<CombatController *>(eventHandler->getController());
+	GameController *gc = dynamic_cast<GameController *>(eventHandler->getController());
 
-	if (dir == DIR_NONE) {
-		if (isDebuggerActive())
-			print("");
-		return isDebuggerActive();
-	}
-
-	Std::vector<Coords> path = gameGetDirectionalActionPath(
-		MASK_DIR(dir), MASK_DIR_ALL, g_context->_location->_coords,
-		1, 1, nullptr, true);
-	for (Std::vector<Coords>::iterator i = path.begin(); i != path.end(); i++) {
-		if (attackAt(*i))
-			return isDebuggerActive();
-	}
+	if (cc)
+		cc->attack(dir, range);
+	else if (gc)
+		gc->attack(dir);
 
-	print("%cNothing to Attack!%c", FG_GREY, FG_WHITE);
 	return isDebuggerActive();
 }
 
diff --git a/engines/ultima/ultima4/core/debugger_actions.cpp b/engines/ultima/ultima4/core/debugger_actions.cpp
index 5e8a914270..299d4bfb38 100644
--- a/engines/ultima/ultima4/core/debugger_actions.cpp
+++ b/engines/ultima/ultima4/core/debugger_actions.cpp
@@ -107,43 +107,6 @@ bool DebuggerActions::destroyAt(const Coords &coords) {
 	return false;
 }
 
-bool DebuggerActions::attackAt(const Coords &coords) {
-	Object *under;
-	const Tile *ground;
-	Creature *m;
-
-	m = dynamic_cast<Creature *>(g_context->_location->_map->objectAt(coords));
-	/* nothing attackable: move on to next tile */
-	if (m == nullptr || !m->isAttackable())
-		return false;
-
-	/* attack successful */
-	/// TODO: CHEST: Make a user option to not make chests change battlefield
-	/// map (1 of 2)
-	ground = g_context->_location->_map->tileTypeAt(g_context->_location->_coords, WITH_GROUND_OBJECTS);
-	if (!ground->isChest()) {
-		ground = g_context->_location->_map->tileTypeAt(g_context->_location->_coords, WITHOUT_OBJECTS);
-		if ((under = g_context->_location->_map->objectAt(g_context->_location->_coords)) &&
-			under->getTile().getTileType()->isShip())
-			ground = under->getTile().getTileType();
-	}
-
-	/* You're attacking a townsperson!  Alert the guards! */
-	if ((m->getType() == Object::PERSON) && (m->getMovementBehavior() != MOVEMENT_ATTACK_AVATAR))
-		g_context->_location->_map->alertGuards();
-
-	/* not good karma to be killing the innocent.  Bad avatar! */
-	if (m->isGood() || /* attacking a good creature */
-			/* attacking a docile (although possibly evil) person in town */
-		((m->getType() == Object::PERSON) && (m->getMovementBehavior() != MOVEMENT_ATTACK_AVATAR)))
-		g_context->_party->adjustKarma(KA_ATTACKED_GOOD);
-
-	CombatController *cc = new CombatController(CombatMap::mapForTile(ground, g_context->_party->getTransport().getTileType(), m));
-	cc->init(m);
-	cc->begin();
-	return false;
-}
-
 bool DebuggerActions::getChestTrapHandler(int player) {
 	TileEffect trapType;
 	int randNum = xu4_random(4);
diff --git a/engines/ultima/ultima4/core/debugger_actions.h b/engines/ultima/ultima4/core/debugger_actions.h
index 88bdb422ea..a1bf8bf6c4 100644
--- a/engines/ultima/ultima4/core/debugger_actions.h
+++ b/engines/ultima/ultima4/core/debugger_actions.h
@@ -84,12 +84,6 @@ public:
 	 */
 	Direction directionFromName(const Common::String &dirStr);
 
-	/**
-	 * Attempts to attack a creature at map coordinates x,y.  If no
-	 * creature is present at that point, zero is returned.
-	 */
-	bool attackAt(const Coords &coords);
-
 	/**
 	 * Called by getChest() to handle possible traps on chests
 	 **/




More information about the Scummvm-git-logs mailing list