[Scummvm-git-logs] scummvm master -> cf7ae464756ca9f9e994b111d219058a46180695
mduggan
mgithub at guarana.org
Sun May 9 04:11:28 UTC 2021
This automated email contains information about 9 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
531ed6865b ULTIMA8: Add comment about iteration order
f5c4374888 ULTIMA8: Refactor so all Crusader movies get subtitles
d83ccb7e9b ULTIMA8: Default to no mouse cursor in Crusader
cf085788c2 ULTIMA8: Add Crusader key for using energy cube
137fa8ea29 ULTIMA8: Implement 'grab' operation for Crusader games
bda1466e0a ULTIMA8: Fix Crusader items reappearing after exploding
26f936510f ULTIMA8: Implement "cruStasis", stops some key events
6f5538ab4d ULTIMA8: Fix actor anim speed in Crusader
cf7ae46475 ULTIMA8: Adjust Crusader step tests to match original
Commit: 531ed6865b6d73da53791a5a70b3cb4720659153
https://github.com/scummvm/scummvm/commit/531ed6865b6d73da53791a5a70b3cb4720659153
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2021-05-09T07:31:43+09:00
Commit Message:
ULTIMA8: Add comment about iteration order
This function looks tempting to "optimize", by changing the order, so add a
warning for new adventurers.
Changed paths:
engines/ultima/ultima8/world/current_map.cpp
diff --git a/engines/ultima/ultima8/world/current_map.cpp b/engines/ultima/ultima8/world/current_map.cpp
index 20bcc75a6f..3c2a3a2afd 100644
--- a/engines/ultima/ultima8/world/current_map.cpp
+++ b/engines/ultima/ultima8/world/current_map.cpp
@@ -572,6 +572,15 @@ void CurrentMap::areaSearch(UCList *itemlist, const uint8 *loopscript,
int maxy = ((y + range) / _mapChunkSize) + 1;
clipMapChunks(minx, maxx, miny, maxy);
+ //
+ // NOTE: Iteration order of chunks here is important for
+ // usecode compatibility!
+ //
+ // eg, No Remorse Mission 2 has a camera which searches for
+ // trigger with qlo = 5, but there are 2 of those on the map.
+ // We need to return in the correct order or it triggers
+ // the wrong one and breaks the game.
+ //
for (int cy = miny; cy <= maxy; cy++) {
for (int cx = minx; cx <= maxx; cx++) {
item_list::const_iterator iter;
Commit: f5c43748889c08015bfd03b060c09babb5b03e85
https://github.com/scummvm/scummvm/commit/f5c43748889c08015bfd03b060c09babb5b03e85
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2021-05-09T07:31:43+09:00
Commit Message:
ULTIMA8: Refactor so all Crusader movies get subtitles
Previously there was a bit of duplication, and Weasel and the intro movies
didn't get subtitles. Cleaned up the code a bit and now all are treated
consistently.
Changed paths:
engines/ultima/ultima8/games/remorse_game.cpp
engines/ultima/ultima8/gumps/movie_gump.cpp
engines/ultima/ultima8/gumps/movie_gump.h
engines/ultima/ultima8/gumps/weasel_gump.cpp
diff --git a/engines/ultima/ultima8/games/remorse_game.cpp b/engines/ultima/ultima8/games/remorse_game.cpp
index f9028447f5..676f67f2b8 100644
--- a/engines/ultima/ultima8/games/remorse_game.cpp
+++ b/engines/ultima/ultima8/games/remorse_game.cpp
@@ -28,6 +28,7 @@
#include "ultima/ultima8/filesys/file_system.h"
#include "ultima/ultima8/graphics/palette_manager.h"
#include "ultima/ultima8/gumps/movie_gump.h"
+#include "ultima/ultima8/gumps/gump_notify_process.h"
#include "ultima/ultima8/kernel/object_manager.h"
#include "ultima/ultima8/kernel/kernel.h"
#include "ultima/ultima8/world/world.h"
@@ -149,15 +150,13 @@ bool RemorseGame::startInitialUsecode(int saveSlot) {
static ProcId playMovie(const char *movieID, bool fade, bool noScale) {
- const Std::string filename = Std::string::format("flics/%s.avi", movieID);
- FileSystem *filesys = FileSystem::get_instance();
- Common::SeekableReadStream *rs = filesys->ReadFile(filename);
- if (!rs) {
- pout << "RemorseGame::playIntro: movie not found." << Std::endl;
+ MovieGump *gump = MovieGump::CruMovieViewer(movieID, 640, 480, nullptr, nullptr);
+ if (!gump) {
+ pout << "RemorseGame::playIntro: movie " << movieID << " not found." << Std::endl;
return 0;
}
- // TODO: Add support for subtitles (.txt file). The format is very simple.
- return MovieGump::U8MovieViewer(rs, fade, false, noScale);
+ gump->CreateNotifier();
+ return gump->GetNotifyProcess()->getPid();
}
ProcId RemorseGame::playIntroMovie(bool fade) {
diff --git a/engines/ultima/ultima8/gumps/movie_gump.cpp b/engines/ultima/ultima8/gumps/movie_gump.cpp
index 0b2cd77246..be5e869d51 100644
--- a/engines/ultima/ultima8/gumps/movie_gump.cpp
+++ b/engines/ultima/ultima8/gumps/movie_gump.cpp
@@ -40,6 +40,60 @@
namespace Ultima {
namespace Ultima8 {
+static Std::string _fixCrusaderMovieName(const Std::string &s) {
+ /*
+ HACK! The game comes with movies MVA01.AVI etc, but the usecode mentions both
+ MVA01 and MVA1. We do a translation here. These are the strings we need to fix:
+ 008E: 0D push string "mva1"
+ 036D: 0D push string "mva3a"
+ 04E3: 0D push string "mva4"
+ 0656: 0D push string "mva5a"
+ 07BD: 0D push string "mva6"
+ 0944: 0D push string "mva7"
+ 0A68: 0D push string "mva8"
+ 0B52: 0D push string "mva9"
+ */
+ if (s.size() == 4)
+ return Std::string::format("mva0%c", s[3]);
+ else if (s.equals("mva3a"))
+ return "mva03a";
+ else if (s.equals("mva5a"))
+ return "mva05a";
+
+ return s;
+}
+
+static Common::SeekableReadStream *_tryLoadCruMovieFile(const Std::string &filename, const char *extn) {
+ const Std::string path = Std::string::format("flics/%s.%s", filename.c_str(), extn);
+ FileSystem *filesys = FileSystem::get_instance();
+ Common::SeekableReadStream *rs = filesys->ReadFile(path);
+ if (!rs) {
+ // Try with a "0" in the name
+ const Std::string adjustedfn = Std::string::format("flics/0%s.%s", filename.c_str(), extn);
+ rs = filesys->ReadFile(adjustedfn);
+ if (!rs)
+ return nullptr;
+ }
+ return rs;
+}
+
+static Common::SeekableReadStream *_tryLoadCruAVI(const Std::string &filename) {
+ Common::SeekableReadStream *rs = _tryLoadCruMovieFile(filename, "avi");
+ if (!rs)
+ warning("movie %s not found", filename.c_str());
+ return rs;
+}
+
+// Convenience function that tries to open both TXT (No Remorse)
+// and IFF (No Regret) subtitle formats.
+static Common::SeekableReadStream *_tryLoadCruSubtitle(const Std::string &filename) {
+ Common::SeekableReadStream *txtfile = _tryLoadCruMovieFile(filename, "txt");
+ if (txtfile)
+ return txtfile;
+ return _tryLoadCruMovieFile(filename, "iff");
+}
+
+
DEFINE_RUNTIME_CLASSTYPE_CODE(MovieGump)
MovieGump::MovieGump() : ModalGump(), _player(nullptr) {
@@ -134,7 +188,7 @@ bool MovieGump::OnKeyDown(int key, int mod) {
return true;
}
-//static
+/*static*/
ProcId MovieGump::U8MovieViewer(Common::SeekableReadStream *rs, bool fade, bool introMusicHack, bool noScale) {
ModalGump *gump;
if (GAME_IS_U8)
@@ -156,6 +210,18 @@ ProcId MovieGump::U8MovieViewer(Common::SeekableReadStream *rs, bool fade, bool
}
}
+/*static*/ MovieGump *MovieGump::CruMovieViewer(const Std::string fname, int x, int y, const byte *pal, Gump *parent) {
+ Common::SeekableReadStream *rs = _tryLoadCruAVI(fname);
+ if (!rs)
+ return nullptr;
+
+ MovieGump *gump = new MovieGump(x, y, rs, false, false, pal);
+ gump->InitGump(parent, true);
+ gump->setRelativePosition(CENTER);
+ gump->loadSubtitles(_tryLoadCruSubtitle(fname));
+ return gump;
+}
+
void MovieGump::loadSubtitles(Common::SeekableReadStream *rs) {
if (!rs)
return;
@@ -197,59 +263,6 @@ void MovieGump::saveData(Common::WriteStream *ws) {
}
-static Std::string _fixCrusaderMovieName(const Std::string &s) {
- /*
- HACK! The game comes with movies MVA01.AVI etc, but the usecode mentions both
- MVA01 and MVA1. We do a translation here. These are the strings we need to fix:
- 008E: 0D push string "mva1"
- 036D: 0D push string "mva3a"
- 04E3: 0D push string "mva4"
- 0656: 0D push string "mva5a"
- 07BD: 0D push string "mva6"
- 0944: 0D push string "mva7"
- 0A68: 0D push string "mva8"
- 0B52: 0D push string "mva9"
- */
- if (s.size() == 4)
- return Std::string::format("mva0%c", s[3]);
- else if (s.equals("mva3a"))
- return "mva03a";
- else if (s.equals("mva5a"))
- return "mva05a";
-
- return s;
-}
-
-static Common::SeekableReadStream *_tryLoadCruMovieFile(const Std::string &filename, const char *extn) {
- const Std::string path = Std::string::format("flics/%s.%s", filename.c_str(), extn);
- FileSystem *filesys = FileSystem::get_instance();
- Common::SeekableReadStream *rs = filesys->ReadFile(path);
- if (!rs) {
- // Try with a "0" in the name
- const Std::string adjustedfn = Std::string::format("flics/0%s.%s", filename.c_str(), extn);
- rs = filesys->ReadFile(adjustedfn);
- if (!rs)
- return nullptr;
- }
- return rs;
-}
-
-static Common::SeekableReadStream *_tryLoadCruAVI(const Std::string &filename) {
- Common::SeekableReadStream *rs = _tryLoadCruMovieFile(filename, "avi");
- if (!rs)
- warning("movie %s not found", filename.c_str());
- return rs;
-}
-
-// Convenience function that tries to open both TXT (No Remorse)
-// and IFF (No Regret) subtitle formats.
-static Common::SeekableReadStream *_tryLoadCruSubtitle(const Std::string &filename) {
- Common::SeekableReadStream *txtfile = _tryLoadCruMovieFile(filename, "txt");
- if (txtfile)
- return txtfile;
- return _tryLoadCruMovieFile(filename, "iff");
-}
-
uint32 MovieGump::I_playMovieOverlay(const uint8 *args,
unsigned int /*argsize*/) {
ARG_ITEM_FROM_PTR(item);
@@ -267,13 +280,7 @@ uint32 MovieGump::I_playMovieOverlay(const uint8 *args,
const Palette *pal = palman->getPalette(PaletteManager::Pal_Game);
assert(pal);
- Common::SeekableReadStream *rs = _tryLoadCruAVI(name);
- if (rs) {
- MovieGump *gump = new MovieGump(x, y, rs, false, false, pal->_palette);
- gump->InitGump(nullptr, true);
- gump->setRelativePosition(CENTER);
- gump->loadSubtitles(_tryLoadCruSubtitle(name));
- }
+ CruMovieViewer(name, x, y, pal->_palette, nullptr);
}
return 0;
@@ -286,13 +293,7 @@ uint32 MovieGump::I_playMovieCutscene(const uint8 *args, unsigned int /*argsize*
ARG_UINT16(y);
if (item) {
- Common::SeekableReadStream *rs = _tryLoadCruAVI(name);
- if (rs) {
- MovieGump *gump = new MovieGump(x * 3, y * 3, rs, false, false);
- gump->InitGump(nullptr, true);
- gump->setRelativePosition(CENTER);
- gump->loadSubtitles(_tryLoadCruSubtitle(name));
- }
+ CruMovieViewer(name, x * 3, y * 3, nullptr, nullptr);
}
return 0;
@@ -312,13 +313,7 @@ uint32 MovieGump::I_playMovieCutsceneAlt(const uint8 *args, unsigned int /*argsi
warning("MovieGump::I_playMovieCutsceneAlt: TODO: This intrinsic should pause and fade the background to grey");
if (item) {
- Common::SeekableReadStream *rs = _tryLoadCruAVI(name);
- if (rs) {
- MovieGump *gump = new MovieGump(x * 3, y * 3, rs, false, false);
- gump->InitGump(nullptr, true);
- gump->setRelativePosition(CENTER);
- gump->loadSubtitles(_tryLoadCruSubtitle(name));
- }
+ CruMovieViewer(name, x * 3, y * 3, nullptr, nullptr);
}
return 0;
@@ -330,13 +325,7 @@ uint32 MovieGump::I_playMovieCutsceneRegret(const uint8 *args, unsigned int /*ar
warning("MovieGump::I_playMovieCutsceneRegret: TODO: use fade argument %d", fade);
- Common::SeekableReadStream *rs = _tryLoadCruAVI(name);
- if (rs) {
- MovieGump *gump = new MovieGump(640, 480, rs, false, false);
- gump->InitGump(nullptr, true);
- gump->setRelativePosition(CENTER);
- gump->loadSubtitles(_tryLoadCruSubtitle(name));
- }
+ CruMovieViewer(name, 640, 480, nullptr, nullptr);
return 0;
}
diff --git a/engines/ultima/ultima8/gumps/movie_gump.h b/engines/ultima/ultima8/gumps/movie_gump.h
index 34399ee48a..bcc8af0596 100644
--- a/engines/ultima/ultima8/gumps/movie_gump.h
+++ b/engines/ultima/ultima8/gumps/movie_gump.h
@@ -56,6 +56,7 @@ public:
bool OnKeyDown(int key, int mod) override;
static ProcId U8MovieViewer(Common::SeekableReadStream *rs, bool fade, bool introMusicHack, bool noScale);
+ static MovieGump *CruMovieViewer(const Std::string fname, int x, int y, const byte *pal, Gump *parent);
bool loadData(Common::ReadStream *rs);
void saveData(Common::WriteStream *ws) override;
diff --git a/engines/ultima/ultima8/gumps/weasel_gump.cpp b/engines/ultima/ultima8/gumps/weasel_gump.cpp
index 30fe67d4db..17b3de40e6 100644
--- a/engines/ultima/ultima8/gumps/weasel_gump.cpp
+++ b/engines/ultima/ultima8/gumps/weasel_gump.cpp
@@ -196,16 +196,11 @@ void WeaselGump::InitGump(Gump *newparent, bool take_focus) {
}
Gump *WeaselGump::playMovie(const Std::string &filename) {
- const Std::string path = Std::string::format("flics/%s.avi", filename.c_str());
- FileSystem *filesys = FileSystem::get_instance();
- Common::SeekableReadStream *rs = filesys->ReadFile(path);
- if (!rs) {
+ MovieGump *gump = MovieGump::CruMovieViewer(filename, 600, 450, nullptr, this);
+ if (!gump) {
warning("Couldn't load flic %s", filename.c_str());
return nullptr;
}
- Gump *gump = new MovieGump(600, 450, rs, false, false);
- gump->InitGump(this, true);
- gump->setRelativePosition(CENTER);
gump->CreateNotifier();
return gump;
}
Commit: d83ccb7e9b8cababdf8131f71eddf2395b12b6a6
https://github.com/scummvm/scummvm/commit/d83ccb7e9b8cababdf8131f71eddf2395b12b6a6
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2021-05-09T07:31:43+09:00
Commit Message:
ULTIMA8: Default to no mouse cursor in Crusader
Changed paths:
engines/ultima/ultima8/kernel/mouse.cpp
diff --git a/engines/ultima/ultima8/kernel/mouse.cpp b/engines/ultima/ultima8/kernel/mouse.cpp
index 2877a3054c..ea93c3d624 100644
--- a/engines/ultima/ultima8/kernel/mouse.cpp
+++ b/engines/ultima/ultima8/kernel/mouse.cpp
@@ -203,8 +203,11 @@ int Mouse::getMouseFrame() {
switch (cursor) {
case MOUSE_NORMAL: {
+ if (GAME_IS_CRUSADER)
+ return -1;
+
bool combat = false;
- MainActor *av = getMainActor();
+ const MainActor *av = getMainActor();
if (av) {
combat = av->isInCombat();
}
Commit: cf085788c2665665eac6bac23057488aaf670f61
https://github.com/scummvm/scummvm/commit/cf085788c2665665eac6bac23057488aaf670f61
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2021-05-09T07:31:43+09:00
Commit Message:
ULTIMA8: Add Crusader key for using energy cube
Had to reassign the "paint editor items" debug key because it was using 'e',
which we need.
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 dbab7b78d5..2854fb2b7d 100644
--- a/engines/ultima/ultima8/meta_engine.cpp
+++ b/engines/ultima/ultima8/meta_engine.cpp
@@ -85,6 +85,7 @@ static const KeybindingRecord CRUSADER_KEYS[] = {
{ ACTION_NEXT_INVENTORY, "NEXT_INVENTORY", "Next Inventory Item", "MainActor::nextInvItem", nullptr, "i", nullptr, 0 },
{ ACTION_USE_INVENTORY, "USE_INVENTORY", "Use Inventroy Item", "MainActor::useInventoryItem", nullptr, "u", nullptr, 0 },
{ ACTION_USE_MEDIKIT, "USE_MEDIKIT", "Use Medical Kit", "MainActor::useMedikit", nullptr, "m", nullptr, 0 },
+ { ACTION_USE_ENERGYCUBE, "USE_ENERGYCUBE", "Use Energy Cube", "MainActor::useEnergyCube", nullptr, "e", nullptr, 0 },
{ ACTION_DETONATE_BOMB, "DETONATE_BOMB", "Detonate Bomb", "MainActor::detonateBomb", nullptr, "b", nullptr, 0 },
{ ACTION_SELECT_ITEMS, "SELECT_ITEM", "Select Item", "ItemSelectionProcess::startSelection", nullptr, "s", nullptr, 0 },
{ ACTION_USE_SELECTION, "USE_SELECTION", "Use Selection", "ItemSelectionProcess::useSelectedItem", nullptr, "RETURN", nullptr, 0 },
@@ -109,7 +110,7 @@ static const KeybindingRecord CHEAT_KEYS[] = {
#ifndef RELEASE_BUILD
static const KeybindingRecord DEBUG_KEYS[] = {
- { ACTION_TOGGLE_PAINT, "TOGGLE_PAINT", "Toggle Paint Editor Items", "GUIApp::togglePaintEditorItems", nullptr, "e", nullptr, 0 },
+ { ACTION_TOGGLE_PAINT, "TOGGLE_PAINT", "Toggle Paint Editor Items", "GUIApp::togglePaintEditorItems", nullptr, "F9", nullptr, 0 },
{ ACTION_DEC_SORT_ORDER, "DEC_SORT_ORDER", "Decrement Map Sort Order", "GameMapGump::decrementSortOrder", nullptr, "LEFTBRACKET", nullptr, 0 },
{ ACTION_INC_SORT_ORDER, "INC_SORT_ORDER", "Increment Map Sort Order", "GameMapGump::incrementSortOrder", nullptr, "RIGHTBRACKET", nullptr, 0 },
{ ACTION_ENGINE_STATS, "STATS", "List engine stats", "GUIApp::engineStats", nullptr, "t", nullptr, 0 },
diff --git a/engines/ultima/ultima8/meta_engine.h b/engines/ultima/ultima8/meta_engine.h
index b1e9564484..a67a33ad09 100644
--- a/engines/ultima/ultima8/meta_engine.h
+++ b/engines/ultima/ultima8/meta_engine.h
@@ -33,8 +33,8 @@ 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_NEXT_INVENTORY,
- ACTION_USE_INVENTORY, ACTION_USE_MEDIKIT, ACTION_SELECT_ITEMS,
- ACTION_DETONATE_BOMB, ACTION_USE_SELECTION, ACTION_MENU,
+ ACTION_USE_INVENTORY, ACTION_USE_MEDIKIT, ACTION_USE_ENERGYCUBE,
+ ACTION_SELECT_ITEMS, ACTION_DETONATE_BOMB, 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,
diff --git a/engines/ultima/ultima8/misc/debugger.cpp b/engines/ultima/ultima8/misc/debugger.cpp
index 85d2036e16..a567d593a5 100644
--- a/engines/ultima/ultima8/misc/debugger.cpp
+++ b/engines/ultima/ultima8/misc/debugger.cpp
@@ -154,6 +154,7 @@ Debugger::Debugger() : Shared::Debugger() {
registerCmd("MainActor::nextInvItem", WRAP_METHOD(Debugger, cmdNextInventory));
registerCmd("MainActor::useInventoryItem", WRAP_METHOD(Debugger, cmdUseInventoryItem));
registerCmd("MainActor::useMedikit", WRAP_METHOD(Debugger, cmdUseMedikit));
+ registerCmd("MainActor::useEnergyCube", WRAP_METHOD(Debugger, cmdUseEnergyCube));
registerCmd("MainActor::detonateBomb", WRAP_METHOD(Debugger, cmdDetonateBomb));
registerCmd("MainActor::toggleCombat", WRAP_METHOD(Debugger, cmdToggleCombat));
registerCmd("ItemSelectionProcess::startSelection", WRAP_METHOD(Debugger, cmdStartSelection));
@@ -1096,6 +1097,22 @@ bool Debugger::cmdUseMedikit(int argc, const char **argv) {
return false;
}
+bool Debugger::cmdUseEnergyCube(int argc, const char **argv) {
+ if (Ultima8Engine::get_instance()->isAvatarInStasis()) {
+ debugPrintf("Can't use energy cube: avatarInStasis\n");
+ return false;
+ }
+
+ // Only if controlling avatar.
+ if (!_isAvatarControlled()) {
+ return false;
+ }
+
+ MainActor *av = getMainActor();
+ av->useInventoryItem(0x582);
+ return false;
+}
+
bool Debugger::cmdDetonateBomb(int argc, const char **argv) {
if (Ultima8Engine::get_instance()->isAvatarInStasis()) {
debugPrintf("Can't detonate bomb: avatarInStasis\n");
diff --git a/engines/ultima/ultima8/misc/debugger.h b/engines/ultima/ultima8/misc/debugger.h
index 7ae8c902ac..95145920aa 100644
--- a/engines/ultima/ultima8/misc/debugger.h
+++ b/engines/ultima/ultima8/misc/debugger.h
@@ -222,6 +222,7 @@ private:
bool cmdToggleCombat(int argc, const char **argv);
bool cmdUseInventoryItem(int argc, const char **argv);
bool cmdUseMedikit(int argc, const char **argv);
+ bool cmdUseEnergyCube(int argc, const char **argv);
bool cmdDetonateBomb(int argc, const char **argv);
bool cmdStartSelection(int argc, const char **argv);
bool cmdUseSelection(int argc, const char **argv);
Commit: 137fa8ea290c31aa061830e9158e4ddc407b45b7
https://github.com/scummvm/scummvm/commit/137fa8ea290c31aa061830e9158e4ddc407b45b7
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2021-05-09T07:48:26+09:00
Commit Message:
ULTIMA8: Implement 'grab' operation for Crusader games
Since it only works on loose items and not for searching boxes etc, it's
actually not so useful, but implemented for completeness.
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
engines/ultima/ultima8/world/item_selection_process.cpp
engines/ultima/ultima8/world/item_selection_process.h
diff --git a/engines/ultima/ultima8/meta_engine.cpp b/engines/ultima/ultima8/meta_engine.cpp
index 2854fb2b7d..bd3abdfaa8 100644
--- a/engines/ultima/ultima8/meta_engine.cpp
+++ b/engines/ultima/ultima8/meta_engine.cpp
@@ -89,6 +89,7 @@ static const KeybindingRecord CRUSADER_KEYS[] = {
{ ACTION_DETONATE_BOMB, "DETONATE_BOMB", "Detonate Bomb", "MainActor::detonateBomb", nullptr, "b", nullptr, 0 },
{ ACTION_SELECT_ITEMS, "SELECT_ITEM", "Select Item", "ItemSelectionProcess::startSelection", nullptr, "s", nullptr, 0 },
{ ACTION_USE_SELECTION, "USE_SELECTION", "Use Selection", "ItemSelectionProcess::useSelectedItem", nullptr, "RETURN", nullptr, 0 },
+ { ACTION_GRAB_ITEMS, "GRAB_ITEM", "Grab Items", "ItemSelectionProcess::grabItems", nullptr, "g", nullptr, 0 },
{ ACTION_ATTACK, "ATTACK", "Attack", "AvatarMoverProcess::tryAttack", nullptr, "SPACE", nullptr, 0 },
{ ACTION_CAMERA_AVATAR, "CAMERA_AVATAR", "Focus Camera on Silencer", "CameraProcess::moveToAvatar", nullptr, "z", nullptr, 0 },
{ ACTION_JUMP, "JUMP", "Jump / Roll / Crouch", "AvatarMoverProcess::startJump", "AvatarMoverProcess::stopJump", "LCTRL", nullptr, FLAG_MENU_ENABLED },
diff --git a/engines/ultima/ultima8/meta_engine.h b/engines/ultima/ultima8/meta_engine.h
index a67a33ad09..c1b435fb2a 100644
--- a/engines/ultima/ultima8/meta_engine.h
+++ b/engines/ultima/ultima8/meta_engine.h
@@ -34,12 +34,12 @@ enum KeybindingAction {
ACTION_BACKPACK, ACTION_KEYRING, ACTION_MINIMAP, ACTION_RECALL,
ACTION_INVENTORY, ACTION_NEXT_WEAPON, ACTION_NEXT_INVENTORY,
ACTION_USE_INVENTORY, ACTION_USE_MEDIKIT, ACTION_USE_ENERGYCUBE,
- ACTION_SELECT_ITEMS, ACTION_DETONATE_BOMB, 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_CAMERA_AVATAR,
+ ACTION_SELECT_ITEMS, ACTION_DETONATE_BOMB, ACTION_USE_SELECTION,
+ ACTION_GRAB_ITEMS, 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_CAMERA_AVATAR,
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 a567d593a5..cd1734b99d 100644
--- a/engines/ultima/ultima8/misc/debugger.cpp
+++ b/engines/ultima/ultima8/misc/debugger.cpp
@@ -159,6 +159,7 @@ Debugger::Debugger() : Shared::Debugger() {
registerCmd("MainActor::toggleCombat", WRAP_METHOD(Debugger, cmdToggleCombat));
registerCmd("ItemSelectionProcess::startSelection", WRAP_METHOD(Debugger, cmdStartSelection));
registerCmd("ItemSelectionProcess::useSelectedItem", WRAP_METHOD(Debugger, cmdUseSelection));
+ registerCmd("ItemSelectionProcess::grabItems", WRAP_METHOD(Debugger, cmdGrabItems));
registerCmd("ObjectManager::objectTypes", WRAP_METHOD(Debugger, cmdObjectTypes));
registerCmd("ObjectManager::objectInfo", WRAP_METHOD(Debugger, cmdObjectInfo));
@@ -1498,7 +1499,7 @@ bool Debugger::cmdStartSelection(int argc, const char **argv) {
ItemSelectionProcess *proc = ItemSelectionProcess::get_instance();
if (proc)
- proc->selectNextItem();
+ proc->selectNextItem(false);
return false;
}
@@ -1519,6 +1520,23 @@ bool Debugger::cmdUseSelection(int argc, const char **argv) {
return false;
}
+bool Debugger::cmdGrabItems(int argc, const char **argv) {
+ if (Ultima8Engine::get_instance()->isAvatarInStasis()) {
+ debugPrintf("Can't grab items: avatarInStasis\n");
+ return false;
+ }
+
+ // Only if controlling avatar.
+ if (!_isAvatarControlled()) {
+ return false;
+ }
+
+ ItemSelectionProcess *proc = ItemSelectionProcess::get_instance();
+ if (proc)
+ proc->selectNextItem(true);
+ return false;
+}
+
bool Debugger::cmdObjectTypes(int argc, const char **argv) {
ObjectManager::get_instance()->objectTypes();
return true;
diff --git a/engines/ultima/ultima8/misc/debugger.h b/engines/ultima/ultima8/misc/debugger.h
index 95145920aa..bdd7b74adb 100644
--- a/engines/ultima/ultima8/misc/debugger.h
+++ b/engines/ultima/ultima8/misc/debugger.h
@@ -226,6 +226,7 @@ private:
bool cmdDetonateBomb(int argc, const char **argv);
bool cmdStartSelection(int argc, const char **argv);
bool cmdUseSelection(int argc, const char **argv);
+ bool cmdGrabItems(int argc, const char **argv);
// Object Manager
bool cmdObjectTypes(int argc, const char **argv);
diff --git a/engines/ultima/ultima8/world/item_selection_process.cpp b/engines/ultima/ultima8/world/item_selection_process.cpp
index f0c45a7476..2e9e6bcf80 100644
--- a/engines/ultima/ultima8/world/item_selection_process.cpp
+++ b/engines/ultima/ultima8/world/item_selection_process.cpp
@@ -51,7 +51,7 @@ _ax(0), _ay(0), _az(0) {
void ItemSelectionProcess::run() {
}
-bool ItemSelectionProcess::selectNextItem() {
+bool ItemSelectionProcess::selectNextItem(bool grab) {
MainActor *mainactor = getMainActor();
CurrentMap *currentmap = World::get_instance()->getCurrentMap();
@@ -94,9 +94,22 @@ bool ItemSelectionProcess::selectNextItem() {
continue;
candidates.push_back(item);
+ if (grab) {
+ const ShapeInfo *info = item->getShapeInfo();
+ if (!info || !(info->_flags & ShapeInfo::SI_CRU_SELECTABLE)) {
+ MainActor *actor = getMainActor();
+ if (actor)
+ actor->addItemCru(item, true);
+ }
+ }
}
}
+ if (grab) {
+ clearSelection();
+ return false;
+ }
+
if (candidates.size() < 1) {
AudioProcess *audio = AudioProcess::get_instance();
assert(audio);
diff --git a/engines/ultima/ultima8/world/item_selection_process.h b/engines/ultima/ultima8/world/item_selection_process.h
index f544804707..509e2256bb 100644
--- a/engines/ultima/ultima8/world/item_selection_process.h
+++ b/engines/ultima/ultima8/world/item_selection_process.h
@@ -42,16 +42,16 @@ public:
void run() override;
- //!< Select the next item
- bool selectNextItem();
+ //! Select the next item. If grab is true, pick up loose items now.
+ bool selectNextItem(bool grab);
- //!< Clear the selector
+ //! Clear the selector sprite
void clearSelection();
- //!< Avatar moved - clear the selector if needed.
+ //! Avatar moved - clear the selector if needed.
void avatarMoved();
- //!< Use the selected item (if any)
+ //! Use the selected item (if any)
void useSelectedItem();
bool loadData(Common::ReadStream *rs, uint32 version);
Commit: bda1466e0a1326bcaa8ee240722d01f97c22e341
https://github.com/scummvm/scummvm/commit/bda1466e0a1326bcaa8ee240722d01f97c22e341
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2021-05-09T08:17:01+09:00
Commit Message:
ULTIMA8: Fix Crusader items reappearing after exploding
Changed paths:
engines/ultima/ultima8/world/damage_info.cpp
diff --git a/engines/ultima/ultima8/world/damage_info.cpp b/engines/ultima/ultima8/world/damage_info.cpp
index bc59f45f5c..a849103af3 100644
--- a/engines/ultima/ultima8/world/damage_info.cpp
+++ b/engines/ultima/ultima8/world/damage_info.cpp
@@ -63,6 +63,8 @@ bool DamageInfo::applyToItem(Item *item, uint16 points) const {
if (explode()) {
item->explode(explosionType(), explodeDestroysItem(), explodeWithDamage());
+ if (explodeDestroysItem())
+ item = nullptr;
}
if (_sound) {
AudioProcess *audio = AudioProcess::get_instance();
@@ -75,8 +77,9 @@ bool DamageInfo::applyToItem(Item *item, uint16 points) const {
uint8 replacementFrame = getReplacementFrame();
Item *newitem = ItemFactory::createItem(replacementShape, replacementFrame, q, 0, 0, mapnum, 0, true);
newitem->move(x, y, z);
+ if (item)
+ item->destroy();
} else if (!explodeDestroysItem()) {
- assert(!explodeDestroysItem());
if (frameDataIsAbsolute()) {
int frameval = 1;
if (_data[1])
Commit: 26f936510f54fbf8b16ff26cefe8fc6330d2b54f
https://github.com/scummvm/scummvm/commit/26f936510f54fbf8b16ff26cefe8fc6330d2b54f
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2021-05-09T09:08:31+09:00
Commit Message:
ULTIMA8: Implement "cruStasis", stops some key events
The main bugs that this fixes are when using a remote camera:
* Z should not recenter camera on avatar
* Escape should close remote viewing, not open menu
Changed paths:
engines/ultima/ultima8/misc/debugger.cpp
engines/ultima/ultima8/ultima8.cpp
engines/ultima/ultima8/ultima8.h
diff --git a/engines/ultima/ultima8/misc/debugger.cpp b/engines/ultima/ultima8/misc/debugger.cpp
index cd1734b99d..856865a0c2 100644
--- a/engines/ultima/ultima8/misc/debugger.cpp
+++ b/engines/ultima/ultima8/misc/debugger.cpp
@@ -1179,6 +1179,10 @@ bool Debugger::cmdAttack(int argc, const char **argv) {
}
bool Debugger::cmdCameraOnAvatar(int argc, const char **argv) {
+ if (Ultima8Engine::get_instance()->isCruStasis()) {
+ debugPrintf("Can't move camera: cruStasis\n");
+ return false;
+ }
Actor *actor = getControlledActor();
if (actor) {
int32 x, y, z;
@@ -1803,10 +1807,16 @@ bool Debugger::cmdU8ShapeViewer(int argc, const char **argv) {
bool Debugger::cmdShowMenu(int argc, const char **argv) {
World *world = World::get_instance();
+ // In Crusader escape is also used to stop controlling another NPC
if (world && world->getControlledNPCNum() != 1) {
world->setControlledNPCNum(1);
return false;
}
+ if (Ultima8Engine::get_instance()->isCruStasis()) {
+ Ultima8Engine::get_instance()->moveKeyEvent();
+ debugPrintf("Not opening menu: cruStasis\n");
+ return false;
+ }
MenuGump::showMenu();
return false;
}
diff --git a/engines/ultima/ultima8/ultima8.cpp b/engines/ultima/ultima8/ultima8.cpp
index 460d1906a3..15a16a2a89 100644
--- a/engines/ultima/ultima8/ultima8.cpp
+++ b/engines/ultima/ultima8/ultima8.cpp
@@ -125,7 +125,7 @@ Ultima8Engine::Ultima8Engine(OSystem *syst, const Ultima::UltimaGameDescription
_screen(nullptr), _fontManager(nullptr), _paletteManager(nullptr), _gameData(nullptr),
_world(nullptr), _desktopGump(nullptr), _gameMapGump(nullptr), _avatarMoverProcess(nullptr),
_frameSkip(false), _frameLimit(true), _interpolate(true), _animationRate(100),
- _avatarInStasis(false), _paintEditorItems(false), _inversion(0),
+ _avatarInStasis(false), _cruStasis(false), _paintEditorItems(false), _inversion(0),
_showTouching(false), _timeOffset(0), _hasCheated(false), _cheatsEnabled(false),
_fontOverride(false), _fontAntialiasing(false), _audioMixer(0), _inverterGump(nullptr),
_lerpFactor(256), _inBetweenFrame(false), _unkCrusaderFlag(false), _moveKeyFrame(0) {
@@ -864,7 +864,7 @@ void Ultima8Engine::writeSaveInfo(Common::WriteStream *ws) {
bool Ultima8Engine::canSaveGameStateCurrently(bool isAutosave) {
// Can't save when avatar in stasis during cutscenes
- if (_avatarInStasis)
+ if (_avatarInStasis || _cruStasis)
return false;
// Check for gumps that prevent saving
@@ -1507,13 +1507,12 @@ uint32 Ultima8Engine::I_getAvatarInStasis(const uint8 * /*args*/, unsigned int /
}
uint32 Ultima8Engine::I_setCruStasis(const uint8 *args, unsigned int argsize) {
- // This is like avatar stasis, but stops a lot of other keyboard inputs too.
- warning("I_setCruStasis: TODO: implement me");
+ get_instance()->setCruStasis(true);
return 0;
}
uint32 Ultima8Engine::I_clrCruStasis(const uint8 *args, unsigned int argsize) {
- warning("I_clrCruStasis: TODO: implement me");
+ get_instance()->setCruStasis(false);
return 0;
}
diff --git a/engines/ultima/ultima8/ultima8.h b/engines/ultima/ultima8/ultima8.h
index b72dec55ae..8a915f453e 100644
--- a/engines/ultima/ultima8/ultima8.h
+++ b/engines/ultima/ultima8/ultima8.h
@@ -123,6 +123,7 @@ private:
unsigned int _inversion;
bool _unkCrusaderFlag; //!< not sure what this is but it's only used in usecode for crusader, so just keep track of it..
uint32 _moveKeyFrame; //!< An imperfect way for the Crusader usecode to stop remote camera viewing.
+ bool _cruStasis; //!< A slightly different kind of stasis for Crusader that stops some keyboard events
private:
/**
* Does engine deinitialization
@@ -260,6 +261,12 @@ public:
void setUnkCrusaderFlag(bool flag) {
_unkCrusaderFlag = flag;
}
+ void setCruStasis(bool flag) {
+ _cruStasis = flag;
+ }
+ bool isCruStasis() const {
+ return _cruStasis;
+ }
void moveKeyEvent();
bool moveKeyDownRecently();
Commit: 6f5538ab4dac77cb2f46f4ddff73c8a28f8dd55f
https://github.com/scummvm/scummvm/commit/6f5538ab4dac77cb2f46f4ddff73c8a28f8dd55f
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2021-05-09T12:04:25+09:00
Commit Message:
ULTIMA8: Fix actor anim speed in Crusader
Changed paths:
engines/ultima/ultima8/graphics/anim_dat.cpp
diff --git a/engines/ultima/ultima8/graphics/anim_dat.cpp b/engines/ultima/ultima8/graphics/anim_dat.cpp
index 9f3bf1373c..f21e0b5e62 100644
--- a/engines/ultima/ultima8/graphics/anim_dat.cpp
+++ b/engines/ultima/ultima8/graphics/anim_dat.cpp
@@ -199,6 +199,13 @@ void AnimDat::load(Common::SeekableReadStream *rs) {
if (GAME_IS_U8 && (repeatAndRotateFlag & 0xf0)) {
// This should never happen..
error("Anim data: frame repeat byte should never be > 0xf");
+ } else if (GAME_IS_CRUSADER) {
+ // WORKAROUND: In Crusader, the process wait semantics changed so
+ // wait of 1 frame was the same as no wait. The frame repeat
+ // is implemented as a process wait, so this effectively reduced
+ // all frame repeats by 1.
+ if (a->_actions[action]->_frameRepeat)
+ a->_actions[action]->_frameRepeat--;
}
// byte 3: flags high byte
rawflags |= rs->readByte() << 8;
Commit: cf7ae464756ca9f9e994b111d219058a46180695
https://github.com/scummvm/scummvm/commit/cf7ae464756ca9f9e994b111d219058a46180695
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2021-05-09T13:09:08+09:00
Commit Message:
ULTIMA8: Adjust Crusader step tests to match original
Changed paths:
engines/ultima/ultima8/world/actors/cru_avatar_mover_process.cpp
diff --git a/engines/ultima/ultima8/world/actors/cru_avatar_mover_process.cpp b/engines/ultima/ultima8/world/actors/cru_avatar_mover_process.cpp
index 95648f774a..b413d933d1 100644
--- a/engines/ultima/ultima8/world/actors/cru_avatar_mover_process.cpp
+++ b/engines/ultima/ultima8/world/actors/cru_avatar_mover_process.cpp
@@ -380,8 +380,9 @@ void CruAvatarMoverProcess::step(Animation::Sequence action, Direction direction
Direction dir_left = Direction_TurnByDelta(direction, -4, dirmode_16dirs);
Point3 origpt;
avatar->getLocation(origpt);
- static const int ADJUSTMENTS[] = {0x10, 0x10, 0x20, 0x20, 0x30, 0x30,
- 0x40, 0x40, 0x50, 0x50};
+ // Double the values in original to match our coordinate space
+ static const int ADJUSTMENTS[] = {0x20, 0x20, 0x40, 0x40, 0x60, 0x60,
+ 0x80, 0x80, 0xA0, 0xA0};
for (int i = 0; i < ARRAYSIZE(ADJUSTMENTS); i++) {
Direction testdir = (i % 2 ? dir_left : dir_right);
More information about the Scummvm-git-logs
mailing list