[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