[Scummvm-git-logs] scummvm master -> 46c913e557b83c552f944e3757ba39be643a92a1
mduggan
mgithub at guarana.org
Sat Apr 3 23:27:17 UTC 2021
This automated email contains information about 12 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
a94d79fecd ULTIMA8: Update intrinsic descriptions
dd29b771b8 ULTIMA8: Comments
e06cad01ce ULTIMA8: Add Crusader switch map intrinsic
f1ec24d5f0 ULTIMA8: Hack to fix Crusader acid death animation
ba69b82f0a ULTIMA8: Prep for Crusdaer robot control
0e6e7851f9 ULTIMA8: Downgrade assert to warning as it can happen..
8080f8d5a0 ULTIMA8: Crusader shield type - set on startup and save with game
776f809c82 ULTIMA8: Check for errors loading soundflex
7db56b2107 ULTIMA8: Add defensive null check for shapes
a66544cf40 ULTIMA8: More prep for Crusader robot control
21d7586c8a ULTIMA8: Implement Crusader robot control
46c913e557 ULTIMA8: Improve anim debug messages
Commit: a94d79fecd84e20aea6ebad330418c50b1126579
https://github.com/scummvm/scummvm/commit/a94d79fecd84e20aea6ebad330418c50b1126579
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2021-04-04T08:25:44+09:00
Commit Message:
ULTIMA8: Update intrinsic descriptions
Changed paths:
engines/ultima/ultima8/convert/crusader/convert_usecode_crusader.h
engines/ultima/ultima8/convert/crusader/convert_usecode_regret.h
diff --git a/engines/ultima/ultima8/convert/crusader/convert_usecode_crusader.h b/engines/ultima/ultima8/convert/crusader/convert_usecode_crusader.h
index 574c304446..95954ecb6e 100644
--- a/engines/ultima/ultima8/convert/crusader/convert_usecode_crusader.h
+++ b/engines/ultima/ultima8/convert/crusader/convert_usecode_crusader.h
@@ -187,7 +187,7 @@ const char* const ConvertUsecodeCrusader::_intrinsics[] = {
"int16 CameraProcess::I_getCameraY(void)",
"void Item::I_setMapArray(Item *, uint16 maparray)", // based on decompile - sets same value as read by getmaparray .. see VALUEBOX:ordinal20
"int16 Item::I_getNpcNum(Item *)", // part of same coff set 067, 06D, 089, 08E, 0AD, 0F8, 100, 102, 105, 107, 109, 10B, 10D, 10F, 111, 115, 11C, 123, 129
- "void Intrinsic08A(12 bytes)", // TODO: No idea here.. something about hurling? look at the usecode.
+ "void Item::I_shoot(Item *, Point3 *, int speed, int gravity)",
"int16 Item::I_enterFastArea(Item *)", // based on disasm, v similar to U8
"void Item::I_setIsBroken(Item *)", // same coff as 119, 12A
"int16 Item::I_hurl(Item *,8 bytes)", // part of same coff set 028, 08D, 0BD, 0C0, 0C2, 0C8, 0F7, 0F9, 118, 11D
@@ -204,12 +204,12 @@ const char* const ConvertUsecodeCrusader::_intrinsics[] = {
"void PaletteFaderProcess:I_jumpToGreyScale(void)",
"void I_resetVargasHealthTo500(void)", // TODO: look how this is used in disasm and usecode .. seems weird.
"void Item::I_andStatus(Item *, uint16 status)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
- "void PaletteFaderProcess::I_stopFadesAndResetToGamePal(void)", // TODO: Implement this.
+ "void PaletteFaderProcess::I_jumpToNormalPalette(void)",
"int16 PaletteFaderProcess::I_fadeFromBlack(nsteps)",
- "int16 PaletteFaderProcess::I_fadeFromBlackWithParam(nsteps, unk)", // TODO: what's the param?
+ "int16 PaletteFaderProcess::I_fadeFromBlackWithParam(nsteps, unk)",
"int16 PaletteFaderProcess::I_fadeToBlack(nsteps)",
- "int16 PaletteFaderProcess::I_fadeToBlackWithParam(nsteps, unk)", // TODO: what's the param?
- "int16 PaletteFaderProcess::I_fadeToColor(r, g, b, nsteps, unk)", // TODO: what's the other param?
+ "int16 PaletteFaderProcess::I_fadeToBlackWithParam(nsteps, unk)",
+ "int16 PaletteFaderProcess::I_fadeToColor(r, g, b, nsteps, unk)",
// 00A0
"void Actor::I_setDead(Actor *)", // part of same coff set 021, 060, 073, 0A0, 0A8, 0D8, 0E7, 135
"int16 Item::I_getQLo(Item *)", // same as 02B based on same coff set 010, 02B, 066, 084, 0A1, 0AE, 0D9, 0EA
@@ -256,7 +256,7 @@ const char* const ConvertUsecodeCrusader::_intrinsics[] = {
"int16 Item::I_hurl(Item *,8 bytes)", // part of same coff set 028, 08D, 0BD, 0C0, 0C2, 0C8, 0F7, 0F9, 118, 11D
"int16 Item::I_getQHi(Item *)", // same as 026 based on same coff set 026, 045, 047, 049, 04B, 04D, 04F, 0AF, 0BE, 0C9, 0F0, 0F3, 0FB, 133
"byte Actor::I_addHp(Actor *, int)",
- "void I_createMapJumpProcess(int16 mapnum)", // TODO: Implement me
+ "void MainActort::I_switchMap(int16 mapnum)",
"byte Actor::I_getInCombat(Actor *)",
"void Actor::I_setActivity(Actor *, int)", // part of same coff set 055, 07D, 0CD, 0DB, 0F2, 131
"int16 Game::I_isReleaseBuild(void)", // whether the string "GAME COMPILE=1" has the 1. Might be interesting to see what this does..
diff --git a/engines/ultima/ultima8/convert/crusader/convert_usecode_regret.h b/engines/ultima/ultima8/convert/crusader/convert_usecode_regret.h
index dfc92e2f6d..6837b10113 100644
--- a/engines/ultima/ultima8/convert/crusader/convert_usecode_regret.h
+++ b/engines/ultima/ultima8/convert/crusader/convert_usecode_regret.h
@@ -208,7 +208,7 @@ const char* const ConvertUsecodeRegret::_intrinsics[] = {
"Actor::I_clrInCombat()",
"PaletteFaderProcess::I_jumpToGreyScale()",
"PaletteFaderProcess::I_jumpToNormalPalette()",
- "Intrinsic009F()",
+ "CruStatusGump::I_showStatusGump()",
// 00A0
"Item::andStatus(void)",
"Item::getUnkEggType(void)",
@@ -219,7 +219,7 @@ const char* const ConvertUsecodeRegret::_intrinsics[] = {
"Item::getQHi(void)",
"Actor::I_getLastAnimSet()",
"Item::getCY(void)",
- "Intrinsic00A9()", // Equivalent to Intrinsic00BB() in Remorse
+ "CurrentMap::I_canExistAt()", // Equivalent to Intrinsic00BB() in Remorse
"Item::isOn(uint16)",
"Actor::isDead(void)",
"Item::hurl(sint16,sint16,sint16,sint16)",
@@ -370,7 +370,7 @@ const char* const ConvertUsecodeRegret::_intrinsics[] = {
"Item::andStatus(void)",
"Camera::getY(void)",
"Camera::getZ(void)",
- "Intrinsic0137()",
+ "CruStatusGump::I_hideStatusGump()",
"Actor::I_clrInCombat()",
"Item::getTypeFlagCrusader(sint16)",
"Item::getNpcNum(void)",
Commit: dd29b771b8969fad7821d31c1bce77983b49f92e
https://github.com/scummvm/scummvm/commit/dd29b771b8969fad7821d31c1bce77983b49f92e
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2021-04-04T08:25:44+09:00
Commit Message:
ULTIMA8: Comments
Changed paths:
engines/ultima/ultima8/games/game_data.cpp
engines/ultima/ultima8/gumps/keypad_gump.cpp
diff --git a/engines/ultima/ultima8/games/game_data.cpp b/engines/ultima/ultima8/games/game_data.cpp
index 9c1aac50a2..7231d3adec 100644
--- a/engines/ultima/ultima8/games/game_data.cpp
+++ b/engines/ultima/ultima8/games/game_data.cpp
@@ -659,10 +659,9 @@ void GameData::loadRemorseData() {
if (!stuffds)
error("Unable to load static/stuff.dat");
- // TODO: What's in this dat file?
+ // Weasel shop data.
// 14 blocks of 323 bytes, references like W01 and I07
- // (presumably weapon and inventory)
- // shop data?
+ // (weapon and inventory)
while (!stuffds->eos()) {
WeaselDat *data = new WeaselDat(stuffds);
_weaselData.push_back(data);
diff --git a/engines/ultima/ultima8/gumps/keypad_gump.cpp b/engines/ultima/ultima8/gumps/keypad_gump.cpp
index 7fe47e4486..4ac9e51668 100644
--- a/engines/ultima/ultima8/gumps/keypad_gump.cpp
+++ b/engines/ultima/ultima8/gumps/keypad_gump.cpp
@@ -232,7 +232,8 @@ void KeypadGump::Close(bool no_del) {
bool KeypadGump::OnTextInput(int unicode) {
if (!(unicode & 0xFF80)) {
//char c = unicode & 0x7F;
- // TODO: Accept numeric keyboard inputs
+ // Could also accept numeric keyboard inputs here.
+ // For now we do it in OnKeyDown.
}
return true;
}
Commit: e06cad01ced106cb2ebd11bf735a121d8569af63
https://github.com/scummvm/scummvm/commit/e06cad01ced106cb2ebd11bf735a121d8569af63
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2021-04-04T08:25:44+09:00
Commit Message:
ULTIMA8: Add Crusader switch map intrinsic
Changed paths:
engines/ultima/ultima8/usecode/remorse_intrinsics.h
engines/ultima/ultima8/world/actors/main_actor.cpp
engines/ultima/ultima8/world/actors/main_actor.h
diff --git a/engines/ultima/ultima8/usecode/remorse_intrinsics.h b/engines/ultima/ultima8/usecode/remorse_intrinsics.h
index d1d54a7e25..72828a379c 100644
--- a/engines/ultima/ultima8/usecode/remorse_intrinsics.h
+++ b/engines/ultima/ultima8/usecode/remorse_intrinsics.h
@@ -148,7 +148,7 @@ Intrinsic RemorseIntrinsics[] = {
Item::I_setNpcNum, // void Item::I_setSomething068(Item *, int16 something) , see VALUEBOX:ordinal20
Item::I_andStatus, // void Intrinsic069(6 bytes)
Item::I_move, // void Intrinsic06A(10 bytes)
- UCMachine::I_true, // TODO: This is actualy "is compiled with VIOLENCE=1" (was set to 0 in germany). For now just always say yes.
+ UCMachine::I_true, // Note: This is actualy "is compiled with VIOLENCE=1" (was set to 0 in germany). For now just always say yes.
Kernel::I_resetRef, // void Intrinsic06C(4 bytes)
Item::I_getNpcNum, // based on same coff as 102 (-> variable name in TRIGGER::ordinal21)
Item::I_andStatus, // void Intrinsic06E(6 bytes)
@@ -250,7 +250,7 @@ Intrinsic RemorseIntrinsics[] = {
Item::I_hurl, // void Intrinsic0C8(12 bytes)
Item::I_getQHi, // based on same coff set as 026
Actor::I_addHp, // int Intrinsic0CA(6 bytes)
- 0, // 0CB void I_createMapJumpProcess(int16 mapnum)", // TODO: Implement me
+ MainActor::I_switchMap, // 0CB
Actor::I_isInCombat, // int Intrinsic0CC(4 bytes)
Actor::I_setActivity, // void Intrinsic0CD(6 bytes)
UCMachine::I_true, // whether the string "GAME COMPILE=1" has the 1. Might be interesting to see how this changes the game.. for now just set to true.
diff --git a/engines/ultima/ultima8/world/actors/main_actor.cpp b/engines/ultima/ultima8/world/actors/main_actor.cpp
index 44c8866a1a..00376f55df 100644
--- a/engines/ultima/ultima8/world/actors/main_actor.cpp
+++ b/engines/ultima/ultima8/world/actors/main_actor.cpp
@@ -876,7 +876,7 @@ uint32 MainActor::I_addItemCru(const uint8 *args,
}
uint32 MainActor::I_getNumberOfCredits(const uint8 *args,
-unsigned int /*argsize*/) {
+ unsigned int /*argsize*/) {
MainActor *av = getMainActor();
if (av) {
Item *item = av->getFirstItemWithShape(0x4ed, true);
@@ -886,6 +886,16 @@ unsigned int /*argsize*/) {
return 0;
}
+uint32 MainActor::I_switchMap(const uint8 *args,
+ unsigned int /*argsize*/) {
+ ARG_UINT16(mapnum);
+ MainActor *av = getMainActor();
+ if (av) {
+ av->teleport(mapnum, 0x1e); // CONSTANT
+ }
+ return 0;
+}
+
void MainActor::useInventoryItem(uint32 shapenum) {
Item *item = getFirstItemWithShape(shapenum, true);
useInventoryItem(item);
diff --git a/engines/ultima/ultima8/world/actors/main_actor.h b/engines/ultima/ultima8/world/actors/main_actor.h
index bf47b02ac9..7855314298 100644
--- a/engines/ultima/ultima8/world/actors/main_actor.h
+++ b/engines/ultima/ultima8/world/actors/main_actor.h
@@ -162,6 +162,7 @@ public:
INTRINSIC(I_clrKeycards);
INTRINSIC(I_addItemCru);
INTRINSIC(I_getNumberOfCredits);
+ INTRINSIC(I_switchMap);
void getWeaponOverlay(const WeaponOverlayFrame *&frame, uint32 &shape);
Commit: f1ec24d5f0e8e8b0d6a241a199a5b8d74d38ecf1
https://github.com/scummvm/scummvm/commit/f1ec24d5f0e8e8b0d6a241a199a5b8d74d38ecf1
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2021-04-04T08:25:44+09:00
Commit Message:
ULTIMA8: Hack to fix Crusader acid death animation
Changed paths:
engines/ultima/ultima8/world/item.cpp
diff --git a/engines/ultima/ultima8/world/item.cpp b/engines/ultima/ultima8/world/item.cpp
index 7fd2df1857..aeff4bf0f9 100644
--- a/engines/ultima/ultima8/world/item.cpp
+++ b/engines/ultima/ultima8/world/item.cpp
@@ -3343,6 +3343,11 @@ uint32 Item::I_popToCoords(const uint8 *args, unsigned int /*argsize*/) {
if (GAME_IS_CRUSADER) {
x *= 2;
y *= 2;
+ // HACK!! DEATHFL::ordinal20 has a hack to add 1 to z for the death
+ // animation (falling into acid), but then our animation tracker
+ // detects a fall and stops animating. Fight hacks with hacks..
+ if (item->_shape == 1408 && z > 0)
+ z -= 1;
}
item->move(x, y, z);
Commit: ba69b82f0af5639624aed0e272729c3181f6be0e
https://github.com/scummvm/scummvm/commit/ba69b82f0af5639624aed0e272729c3181f6be0e
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2021-04-04T08:25:44+09:00
Commit Message:
ULTIMA8: Prep for Crusdaer robot control
Many operations should use the "Controlled" actor rather than "Main" actor. In
U8 these will always be the same so it should be backward-compatible.
Changed paths:
engines/ultima/ultima8/misc/debugger.cpp
engines/ultima/ultima8/world/actors/avatar_mover_process.cpp
engines/ultima/ultima8/world/snap_process.cpp
engines/ultima/ultima8/world/target_reticle_process.cpp
diff --git a/engines/ultima/ultima8/misc/debugger.cpp b/engines/ultima/ultima8/misc/debugger.cpp
index d64dd48cc7..5d5bfb45c2 100644
--- a/engines/ultima/ultima8/misc/debugger.cpp
+++ b/engines/ultima/ultima8/misc/debugger.cpp
@@ -1124,7 +1124,7 @@ bool Debugger::cmdAttack(int argc, const char **argv) {
}
bool Debugger::cmdCameraOnAvatar(int argc, const char **argv) {
- MainActor *actor = getMainActor();
+ Actor *actor = getControlledActor();
if (actor) {
int32 x, y, z;
actor->getLocation(x, y, z);
diff --git a/engines/ultima/ultima8/world/actors/avatar_mover_process.cpp b/engines/ultima/ultima8/world/actors/avatar_mover_process.cpp
index 83e4d7bb66..1505a1292a 100644
--- a/engines/ultima/ultima8/world/actors/avatar_mover_process.cpp
+++ b/engines/ultima/ultima8/world/actors/avatar_mover_process.cpp
@@ -21,7 +21,7 @@
*/
#include "ultima/ultima8/world/actors/avatar_mover_process.h"
-#include "ultima/ultima8/world/actors/main_actor.h"
+#include "ultima/ultima8/world/actors/actor.h"
#include "ultima/ultima8/kernel/kernel.h"
#include "ultima/ultima8/world/actors/targeted_anim_process.h"
#include "ultima/ultima8/world/get_object.h"
@@ -40,7 +40,7 @@ AvatarMoverProcess::~AvatarMoverProcess() {
}
void AvatarMoverProcess::run() {
- MainActor *avatar = getMainActor();
+ Actor *avatar = getControlledActor();
assert(avatar);
// busy, so don't move
@@ -60,6 +60,11 @@ void AvatarMoverProcess::run() {
return;
}
+ // not in fast area, don't move (can happen for some death sequences
+ // in Crusader)
+ if (!avatar->hasFlags(Item::FLG_FASTAREA))
+ return;
+
bool combatRun = avatar->hasActorFlags(Actor::ACT_COMBATRUN);
if (avatar->isInCombat() && !combatRun)
handleCombatMode();
@@ -69,7 +74,7 @@ void AvatarMoverProcess::run() {
bool AvatarMoverProcess::checkTurn(Direction direction, bool moving) {
- MainActor *avatar = getMainActor();
+ Actor *avatar = getControlledActor();
Direction curdir = avatar->getDir();
bool combat = avatar->isInCombat() && !avatar->hasActorFlags(Actor::ACT_COMBATRUN);
@@ -102,14 +107,14 @@ bool AvatarMoverProcess::checkTurn(Direction direction, bool moving) {
}
void AvatarMoverProcess::turnToDirection(Direction direction) {
- MainActor *avatar = getMainActor();
+ Actor *avatar = getControlledActor();
uint16 turnpid = avatar->turnTowardDir(direction);
if (turnpid)
waitFor(turnpid);
}
void AvatarMoverProcess::slowFromRun(Direction direction) {
- MainActor *avatar = getMainActor();
+ Actor *avatar = getControlledActor();
ProcId walkpid = avatar->doAnim(Animation::walk, direction);
ProcId standpid = avatar->doAnim(Animation::stand, direction);
Process *standproc = Kernel::get_instance()->getProcess(standpid);
@@ -118,7 +123,7 @@ void AvatarMoverProcess::slowFromRun(Direction direction) {
}
void AvatarMoverProcess::putAwayWeapon(Direction direction) {
- MainActor *avatar = getMainActor();
+ Actor *avatar = getControlledActor();
ProcId anim1 = avatar->doAnim(Animation::unreadyWeapon, direction);
ProcId anim2 = avatar->doAnim(Animation::stand, direction);
Process *anim2p = Kernel::get_instance()->getProcess(anim2);
@@ -127,7 +132,7 @@ void AvatarMoverProcess::putAwayWeapon(Direction direction) {
}
bool AvatarMoverProcess::standUpIfNeeded(Direction direction) {
- MainActor *avatar = getMainActor();
+ Actor *avatar = getControlledActor();
Animation::Sequence lastanim = avatar->getLastAnim();
bool stasis = Ultima8Engine::get_instance()->isAvatarInStasis();
diff --git a/engines/ultima/ultima8/world/snap_process.cpp b/engines/ultima/ultima8/world/snap_process.cpp
index 9d9ff7146b..5c72f3b397 100644
--- a/engines/ultima/ultima8/world/snap_process.cpp
+++ b/engines/ultima/ultima8/world/snap_process.cpp
@@ -22,7 +22,7 @@
#include "ultima/ultima8/world/snap_process.h"
#include "ultima/ultima8/world/get_object.h"
-#include "ultima/ultima8/world/actors/main_actor.h"
+#include "ultima/ultima8/world/actors/actor.h"
#include "ultima/ultima8/world/camera_process.h"
namespace Ultima {
@@ -59,7 +59,7 @@ void SnapProcess::updateCurrentEgg() {
if (!_currentSnapEgg && !_snapEggs.size())
return;
- const MainActor *a = getMainActor();
+ const Actor *a = getControlledActor();
int32 ax, ay, az, axd, ayd, azd, x, y, z;
a->getLocation(ax, ay, az);
a->getFootpadWorld(axd, ayd, azd);
@@ -100,7 +100,7 @@ bool SnapProcess::isNpcInRangeOfCurrentEgg() const {
if (!_currentSnapEgg)
return false;
- const MainActor *a = getMainActor();
+ const Actor *a = getControlledActor();
Item *currentegg = getItem(_currentSnapEgg);
if (!a || !currentegg)
diff --git a/engines/ultima/ultima8/world/target_reticle_process.cpp b/engines/ultima/ultima8/world/target_reticle_process.cpp
index 7b8e6c88e6..4a4c8ec2d2 100644
--- a/engines/ultima/ultima8/world/target_reticle_process.cpp
+++ b/engines/ultima/ultima8/world/target_reticle_process.cpp
@@ -24,7 +24,7 @@
#include "ultima/ultima8/gumps/message_box_gump.h"
#include "ultima/ultima8/games/game_data.h"
#include "ultima/ultima8/kernel/kernel.h"
-#include "ultima/ultima8/world/actors/main_actor.h"
+#include "ultima/ultima8/world/actors/actor.h"
#include "ultima/ultima8/world/target_reticle_process.h"
#include "ultima/ultima8/world/sprite_process.h"
#include "ultima/ultima8/world/world.h"
@@ -47,7 +47,7 @@ void TargetReticleProcess::run() {
Kernel *kernel = Kernel::get_instance();
assert(kernel);
uint32 frameno = kernel->getFrameNum();
- Actor *mainactor = getMainActor();
+ Actor *mainactor = getControlledActor();
Process *spriteProc = nullptr;
if (_reticleSpriteProcess != 0) {
spriteProc = kernel->getProcess(_reticleSpriteProcess);
@@ -82,7 +82,7 @@ void TargetReticleProcess::run() {
}
bool TargetReticleProcess::findTargetItem() {
- MainActor *mainactor = getMainActor();
+ Actor *mainactor = getControlledActor();
CurrentMap *currentmap = World::get_instance()->getCurrentMap();
bool changed = false;
@@ -152,7 +152,7 @@ void TargetReticleProcess::itemMoved(Item *item) {
int32 x, y, z;
item->getCentre(x, y, z);
- MainActor *mainactor = getMainActor();
+ Actor *mainactor = getControlledActor();
int actordir = -1;
int dirtoitem = -2;
if (mainactor) {
Commit: 0e6e7851f99ccb2dd3e04af7a6c72da8a7cd256f
https://github.com/scummvm/scummvm/commit/0e6e7851f99ccb2dd3e04af7a6c72da8a7cd256f
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2021-04-04T08:25:44+09:00
Commit Message:
ULTIMA8: Downgrade assert to warning as it can happen..
Changed paths:
engines/ultima/ultima8/world/gravity_process.cpp
diff --git a/engines/ultima/ultima8/world/gravity_process.cpp b/engines/ultima/ultima8/world/gravity_process.cpp
index c0df54e6d4..77452a5ef1 100644
--- a/engines/ultima/ultima8/world/gravity_process.cpp
+++ b/engines/ultima/ultima8/world/gravity_process.cpp
@@ -265,7 +265,11 @@ void GravityProcess::terminate() {
//signal item GravityProcess is gone
Item *item = getItem(_itemNum);
if (item) {
- assert(item->getGravityPID() == 0 || item->getGravityPID() == _pid);
+ // This is strange, but not impossible (one terminates
+ // and another starts before terminate() gets called).
+ if (item->getGravityPID() != 0 && item->getGravityPID() != _pid)
+ warning("GravityProcess::terminate %d on item %d which has gravityPID %d",
+ _pid, _itemNum, item->getGravityPID());
item->setGravityPID(0);
// no longer bouncing
Commit: 8080f8d5a018f5ef83bfcc79cba9e666d1868274
https://github.com/scummvm/scummvm/commit/8080f8d5a018f5ef83bfcc79cba9e666d1868274
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2021-04-04T08:25:44+09:00
Commit Message:
ULTIMA8: Crusader shield type - set on startup and save with game
Changed paths:
engines/ultima/ultima8/games/start_crusader_process.cpp
engines/ultima/ultima8/world/actors/actor.cpp
engines/ultima/ultima8/world/actors/actor.h
diff --git a/engines/ultima/ultima8/games/start_crusader_process.cpp b/engines/ultima/ultima8/games/start_crusader_process.cpp
index 24bb6dfcc5..a022f1b0f6 100644
--- a/engines/ultima/ultima8/games/start_crusader_process.cpp
+++ b/engines/ultima/ultima8/games/start_crusader_process.cpp
@@ -88,6 +88,18 @@ void StartCrusaderProcess::run() {
Item *smiley = ItemFactory::createItem(0x598, 0, 0, 0, 0, mapnum, 0, true);
smiley->moveToContainer(avatar);
+ avatar->setShieldType(1);
+
+#if 0
+ // Give the avatar *all the weapons*.. (handy for testing)
+ uint32 wpnshapes[] = {0x032E, 0x032F, 0x0330, 0x038C, 0x0332, 0x0333, 0x0334,
+ 0x038E, 0x0388, 0x038A, 0x038D, 0x038B, 0x0386};
+ for (int i = 0; i < ARRAYSIZE(wpnshapes); i++) {
+ Item *wpn = ItemFactory::createItem(wpnshapes[i], 0, 0, 0, 0, mapnum, 0, true);
+ avatar->addItemCru(wpn, false);
+ }
+#endif
+
avatar->teleport(1, 0x1e);
// The first level 0x1e teleporter in No Remorse goes straight to another
// teleport, so undo the flag that normally stops that.
diff --git a/engines/ultima/ultima8/world/actors/actor.cpp b/engines/ultima/ultima8/world/actors/actor.cpp
index e8a6d60df8..629d16840b 100644
--- a/engines/ultima/ultima8/world/actors/actor.cpp
+++ b/engines/ultima/ultima8/world/actors/actor.cpp
@@ -69,7 +69,8 @@ Actor::Actor() : _strength(0), _dexterity(0), _intelligence(0),
_lastAnim(Animation::stand), _animFrame(0), _direction(dir_north),
_fallStart(0), _unkByte(0), _actorFlags(0), _combatTactic(0),
_homeX(0), _homeY(0), _homeZ(0), _currentActivityNo(0),
- _lastActivityNo(0), _activeWeapon(0), _lastTimeWasHit(0) {
+ _lastActivityNo(0), _activeWeapon(0), _lastTimeWasHit(0),
+ _shieldType(0) {
_defaultActivity[0] = 0;
_defaultActivity[1] = 0;
_defaultActivity[2] = 0;
@@ -1636,6 +1637,7 @@ void Actor::saveData(Common::WriteStream *ws) {
ws->writeUint16LE(_lastActivityNo);
ws->writeUint16LE(_activeWeapon);
ws->writeSint32LE(_lastTimeWasHit);
+ ws->writeByte(_shieldType);
}
}
@@ -1668,6 +1670,7 @@ bool Actor::loadData(Common::ReadStream *rs, uint32 version) {
_lastActivityNo = rs->readUint16LE();
_activeWeapon = rs->readUint16LE();
_lastTimeWasHit = rs->readSint32LE();
+ _shieldType = rs->readByte();
}
return true;
diff --git a/engines/ultima/ultima8/world/actors/actor.h b/engines/ultima/ultima8/world/actors/actor.h
index 2326976b39..328ff581bd 100644
--- a/engines/ultima/ultima8/world/actors/actor.h
+++ b/engines/ultima/ultima8/world/actors/actor.h
@@ -276,8 +276,12 @@ public:
return damage;
}
- virtual uint8 getShieldType() const {
- return 0;
+ uint8 getShieldType() const {
+ return _shieldType;
+ }
+
+ void setShieldType(uint8 type) {
+ _shieldType = type;
}
uint16 getActiveWeapon() const {
@@ -426,6 +430,9 @@ protected:
//! Kernel timer last time NPC was hit (only used in Crusader)
int32 _lastTimeWasHit;
+ //! Type of shield (only used in Crusader)
+ uint8 _shieldType;
+
//! starts an activity (Ultima 8 version)
//! \return processID of process handling the activity or zero
uint16 setActivityU8(int activity);
Commit: 776f809c8208d43c3d55f7a20aaa5c3aff0db2f9
https://github.com/scummvm/scummvm/commit/776f809c8208d43c3d55f7a20aaa5c3aff0db2f9
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2021-04-04T08:25:44+09:00
Commit Message:
ULTIMA8: Check for errors loading soundflex
Changed paths:
engines/ultima/ultima8/audio/sound_flex.cpp
diff --git a/engines/ultima/ultima8/audio/sound_flex.cpp b/engines/ultima/ultima8/audio/sound_flex.cpp
index 7ec1dd6380..6554642fa8 100644
--- a/engines/ultima/ultima8/audio/sound_flex.cpp
+++ b/engines/ultima/ultima8/audio/sound_flex.cpp
@@ -32,9 +32,14 @@ namespace Ultima {
namespace Ultima8 {
SoundFlex::SoundFlex(Common::SeekableReadStream *rs) : Archive(rs), _samples(nullptr) {
- uint32 size;
+ uint32 size = 0;
uint8 *buf = getRawObject(0, &size);
+ if (!size || !buf) {
+ warning("couldn't load sound flex");
+ return;
+ }
+
Common::MemoryReadStream st(buf, size);
_index.push_back(SoundFlexEntry(""));
Commit: 7db56b21071065773fe59fe453078304b5c2960b
https://github.com/scummvm/scummvm/commit/7db56b21071065773fe59fe453078304b5c2960b
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2021-04-04T08:25:44+09:00
Commit Message:
ULTIMA8: Add defensive null check for shapes
Changed paths:
engines/ultima/ultima8/world/item_sorter.cpp
diff --git a/engines/ultima/ultima8/world/item_sorter.cpp b/engines/ultima/ultima8/world/item_sorter.cpp
index dcd618c588..deab2c2507 100644
--- a/engines/ultima/ultima8/world/item_sorter.cpp
+++ b/engines/ultima/ultima8/world/item_sorter.cpp
@@ -643,7 +643,7 @@ void ItemSorter::AddItem(int32 x, int32 y, int32 z, uint32 shapeNum, uint32 fram
si->_shape = _shapes->getShape(shapeNum);
si->_shapeNum = shapeNum;
si->_frame = frame_num;
- const ShapeFrame *_frame = si->_shape->getFrame(si->_frame);
+ const ShapeFrame *_frame = si->_shape ? si->_shape->getFrame(si->_frame) : nullptr;
if (!_frame) {
perr << "Invalid shape: " << si->_shapeNum << "," << si->_frame
<< Std::endl;
Commit: a66544cf40d3ae21dd2f434b032c4307032cde4b
https://github.com/scummvm/scummvm/commit/a66544cf40d3ae21dd2f434b032c4307032cde4b
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2021-04-04T08:25:44+09:00
Commit Message:
ULTIMA8: More prep for Crusader robot control
Refactor function and set crosshair based on controlled actor.
Changed paths:
engines/ultima/ultima8/world/actors/actor.cpp
engines/ultima/ultima8/world/actors/actor.h
engines/ultima/ultima8/world/actors/main_actor.cpp
engines/ultima/ultima8/world/actors/main_actor.h
engines/ultima/ultima8/world/crosshair_process.cpp
diff --git a/engines/ultima/ultima8/world/actors/actor.cpp b/engines/ultima/ultima8/world/actors/actor.cpp
index 629d16840b..6df391604e 100644
--- a/engines/ultima/ultima8/world/actors/actor.cpp
+++ b/engines/ultima/ultima8/world/actors/actor.cpp
@@ -1609,6 +1609,24 @@ void Actor::dumpInfo() const {
<< ConsoleStream::dec << Std::endl;
}
+void Actor::addFireAnimOffsets(int32 &x, int32 &y, int32 &z) {
+ assert(GAME_IS_CRUSADER);
+ Animation::Sequence fireanim = (isKneeling() ? Animation::kneelAndFire : Animation::attack);
+ uint32 actionno = AnimDat::getActionNumberForSequence(fireanim, this);
+ Direction dir = getDir();
+
+ const AnimAction *animaction = GameData::get_instance()->getMainShapes()->getAnim(getShape(), actionno);
+ for (unsigned int i = 0; i < animaction->getSize(); i++) {
+ const AnimFrame &frame = animaction->getFrame(dir, i);
+ if (frame.is_cruattack()) {
+ x += frame.cru_attackx();
+ y += frame.cru_attacky();
+ z += frame.cru_attackz();
+ return;
+ }
+ }
+}
+
void Actor::saveData(Common::WriteStream *ws) {
Container::saveData(ws);
ws->writeUint16LE(_strength);
diff --git a/engines/ultima/ultima8/world/actors/actor.h b/engines/ultima/ultima8/world/actors/actor.h
index 328ff581bd..7eacb9a760 100644
--- a/engines/ultima/ultima8/world/actors/actor.h
+++ b/engines/ultima/ultima8/world/actors/actor.h
@@ -297,6 +297,9 @@ public:
// A cru-specific behavior - mostly make "ugh" noises, or explode for some robots.
void tookHitCru();
+ //! Add the x/y/z fire offsets given the current state of the actor
+ void addFireAnimOffsets(int32 &x, int32 &y, int32 &z);
+
ENABLE_RUNTIME_CLASSTYPE()
INTRINSIC(I_isNPC);
diff --git a/engines/ultima/ultima8/world/actors/main_actor.cpp b/engines/ultima/ultima8/world/actors/main_actor.cpp
index 00376f55df..681ec6179e 100644
--- a/engines/ultima/ultima8/world/actors/main_actor.cpp
+++ b/engines/ultima/ultima8/world/actors/main_actor.cpp
@@ -693,25 +693,6 @@ void MainActor::nextInvItem() {
_activeInvItem = getIdOfNextItemInList(items, _activeInvItem);
}
-void MainActor::addFireAnimOffsets(int32 &x, int32 &y, int32 &z) {
- assert(GAME_IS_CRUSADER);
- Animation::Sequence fireanim = (isKneeling() ? Animation::kneelAndFire : Animation::attack);
- uint32 actionno = AnimDat::getActionNumberForSequence(fireanim, this);
- Direction dir = getDir();
-
- const AnimAction *animaction = GameData::get_instance()->getMainShapes()->getAnim(getShape(), actionno);
- for (unsigned int i = 0; i < animaction->getSize(); i++) {
- const AnimFrame &frame = animaction->getFrame(dir, i);
- if (frame.is_cruattack()) {
- x += frame.cru_attackx();
- y += frame.cru_attacky();
- z += frame.cru_attackz();
- return;
- }
- }
-}
-
-
void MainActor::saveData(Common::WriteStream *ws) {
Actor::saveData(ws);
uint8 jt = _justTeleported ? 1 : 0;
diff --git a/engines/ultima/ultima8/world/actors/main_actor.h b/engines/ultima/ultima8/world/actors/main_actor.h
index 7855314298..a7fbee2014 100644
--- a/engines/ultima/ultima8/world/actors/main_actor.h
+++ b/engines/ultima/ultima8/world/actors/main_actor.h
@@ -142,9 +142,6 @@ public:
//! Detonate used bomb
void detonateBomb();
- //! Add the x/y/z fire offsets given the current state of the actor
- void addFireAnimOffsets(int32 &x, int32 &y, int32 &z);
-
bool loadData(Common::ReadStream *rs, uint32 version);
void saveData(Common::WriteStream *ws) override;
diff --git a/engines/ultima/ultima8/world/crosshair_process.cpp b/engines/ultima/ultima8/world/crosshair_process.cpp
index 373bda1955..7e4cae238b 100644
--- a/engines/ultima/ultima8/world/crosshair_process.cpp
+++ b/engines/ultima/ultima8/world/crosshair_process.cpp
@@ -47,14 +47,14 @@ CrosshairProcess::CrosshairProcess() : Process() {
}
void CrosshairProcess::run() {
- MainActor *mainactor = getMainActor();
- assert(mainactor);
- if (mainactor->isInCombat()) {
+ Actor *actor = getControlledActor();
+ assert(actor);
+ if (actor->isInCombat()) {
Kernel *kernel = Kernel::get_instance();
assert(kernel);
int32 ax, ay, az;
- mainactor->getLocation(ax, ay, az);
- mainactor->addFireAnimOffsets(ax, ay, az);
+ actor->getLocation(ax, ay, az);
+ actor->addFireAnimOffsets(ax, ay, az);
const CruAvatarMoverProcess *mover = dynamic_cast<CruAvatarMoverProcess *>(Ultima8Engine::get_instance()->getAvatarMoverProcess());
if (!mover) {
Commit: 21d7586c8a96af8299b82d225c98a6f1392ad0b8
https://github.com/scummvm/scummvm/commit/21d7586c8a96af8299b82d225c98a6f1392ad0b8
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2021-04-04T08:25:44+09:00
Commit Message:
ULTIMA8: Implement Crusader robot control
Changed paths:
engines/ultima/ultima8/misc/debugger.cpp
engines/ultima/ultima8/world/actors/actor.cpp
engines/ultima/ultima8/world/actors/animation.cpp
engines/ultima/ultima8/world/actors/attack_process.cpp
engines/ultima/ultima8/world/actors/cru_avatar_mover_process.cpp
engines/ultima/ultima8/world/crosshair_process.cpp
engines/ultima/ultima8/world/snap_process.cpp
engines/ultima/ultima8/world/world.cpp
diff --git a/engines/ultima/ultima8/misc/debugger.cpp b/engines/ultima/ultima8/misc/debugger.cpp
index 5d5bfb45c2..de16dfab9d 100644
--- a/engines/ultima/ultima8/misc/debugger.cpp
+++ b/engines/ultima/ultima8/misc/debugger.cpp
@@ -1720,6 +1720,11 @@ bool Debugger::cmdU8ShapeViewer(int argc, const char **argv) {
}
bool Debugger::cmdShowMenu(int argc, const char **argv) {
+ World *world = World::get_instance();
+ if (world && world->getControlledNPCNum() != 1) {
+ world->setControlledNPCNum(1);
+ return false;
+ }
MenuGump::showMenu();
return false;
}
diff --git a/engines/ultima/ultima8/world/actors/actor.cpp b/engines/ultima/ultima8/world/actors/actor.cpp
index 6df391604e..82305140df 100644
--- a/engines/ultima/ultima8/world/actors/actor.cpp
+++ b/engines/ultima/ultima8/world/actors/actor.cpp
@@ -1473,6 +1473,9 @@ void Actor::setInCombatCru(int activity) {
setActorFlag(ACT_INCOMBAT);
+ if (getObjId() == World::get_instance()->getControlledNPCNum())
+ return;
+
AttackProcess *ap = new AttackProcess(this);
Kernel::get_instance()->addProcess(ap);
@@ -1616,6 +1619,9 @@ void Actor::addFireAnimOffsets(int32 &x, int32 &y, int32 &z) {
Direction dir = getDir();
const AnimAction *animaction = GameData::get_instance()->getMainShapes()->getAnim(getShape(), actionno);
+ if (!animaction)
+ return;
+
for (unsigned int i = 0; i < animaction->getSize(); i++) {
const AnimFrame &frame = animaction->getFrame(dir, i);
if (frame.is_cruattack()) {
diff --git a/engines/ultima/ultima8/world/actors/animation.cpp b/engines/ultima/ultima8/world/actors/animation.cpp
index fa5572ce0b..1fa1d90f79 100644
--- a/engines/ultima/ultima8/world/actors/animation.cpp
+++ b/engines/ultima/ultima8/world/actors/animation.cpp
@@ -54,6 +54,7 @@ bool isCombatAnimU8(const Sequence anim) {
bool isCombatAnimCru(const Sequence anim) {
switch (anim) {
case combatStand:
+ case combatStandSmallWeapon:
case readyWeapon:
case advance:
case retreat:
diff --git a/engines/ultima/ultima8/world/actors/attack_process.cpp b/engines/ultima/ultima8/world/actors/attack_process.cpp
index 6ba2905787..29862e9009 100644
--- a/engines/ultima/ultima8/world/actors/attack_process.cpp
+++ b/engines/ultima/ultima8/world/actors/attack_process.cpp
@@ -519,6 +519,12 @@ void AttackProcess::genericAttack() {
return;
}
+ // This should never be running on the controlled npc.
+ if (_itemNum == World::get_instance()->getControlledNPCNum()) {
+ terminate();
+ return;
+ }
+
const Item *wpn = getItem(a->getActiveWeapon());
/*if (!wpn) {
warning("started attack for NPC %d with no weapon", _itemNum);
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 a33223ce2a..b5e57ed9dc 100644
--- a/engines/ultima/ultima8/world/actors/cru_avatar_mover_process.cpp
+++ b/engines/ultima/ultima8/world/actors/cru_avatar_mover_process.cpp
@@ -48,7 +48,10 @@ void CruAvatarMoverProcess::run() {
// we check if the combat angle needs updating - this keeps it smooth.
const Actor *avatar = getControlledActor();
- assert(avatar);
+
+ // Controlled actor may have gone
+ if (!avatar)
+ return;
// When not in combat the angle is kept as -1
if (avatar->isInCombat()) {
@@ -216,8 +219,8 @@ void CruAvatarMoverProcess::handleCombatMode() {
nextanim = Animation::combatRunSmallWeapon;
}
- nextanim = Animation::checkWeapon(nextanim, lastanim);
- step(nextanim, nextdir);
+ Animation::Sequence wpnanim = Animation::checkWeapon(nextanim, lastanim);
+ step(wpnanim, nextdir);
return;
}
diff --git a/engines/ultima/ultima8/world/crosshair_process.cpp b/engines/ultima/ultima8/world/crosshair_process.cpp
index 7e4cae238b..93994e11dc 100644
--- a/engines/ultima/ultima8/world/crosshair_process.cpp
+++ b/engines/ultima/ultima8/world/crosshair_process.cpp
@@ -48,7 +48,9 @@ CrosshairProcess::CrosshairProcess() : Process() {
void CrosshairProcess::run() {
Actor *actor = getControlledActor();
- assert(actor);
+ if (!actor)
+ return;
+
if (actor->isInCombat()) {
Kernel *kernel = Kernel::get_instance();
assert(kernel);
diff --git a/engines/ultima/ultima8/world/snap_process.cpp b/engines/ultima/ultima8/world/snap_process.cpp
index 5c72f3b397..95444bf827 100644
--- a/engines/ultima/ultima8/world/snap_process.cpp
+++ b/engines/ultima/ultima8/world/snap_process.cpp
@@ -60,6 +60,10 @@ void SnapProcess::updateCurrentEgg() {
return;
const Actor *a = getControlledActor();
+
+ if (!a)
+ return;
+
int32 ax, ay, az, axd, ayd, azd, x, y, z;
a->getLocation(ax, ay, az);
a->getFootpadWorld(axd, ayd, azd);
diff --git a/engines/ultima/ultima8/world/world.cpp b/engines/ultima/ultima8/world/world.cpp
index 66ac15aa8a..28e9745e32 100644
--- a/engines/ultima/ultima8/world/world.cpp
+++ b/engines/ultima/ultima8/world/world.cpp
@@ -37,6 +37,7 @@
#include "ultima/ultima8/world/camera_process.h" // for resetting the camera
#include "ultima/ultima8/gumps/gump.h" // For CloseItemDependents notification
#include "ultima/ultima8/world/get_object.h"
+#include "ultima/ultima8/world/target_reticle_process.h"
#include "ultima/ultima8/audio/audio_process.h"
namespace Ultima {
@@ -46,7 +47,7 @@ namespace Ultima8 {
World *World::_world = nullptr;
-World::World() : _currentMap(nullptr), _alertActive(false), _difficulty(1),
+World::World() : _currentMap(nullptr), _alertActive(false), _difficulty(3),
_controlledNPCNum(1) {
debugN(MM_INFO, "Creating World...\n");
@@ -440,9 +441,26 @@ void World::setAlertActive(bool active)
}
void World::setControlledNPCNum(uint16 num) {
- warning("TODO: World::setControlledNPCNum(%d): IMPLEMENT ME", num);
+ uint16 oldnpc = _controlledNPCNum;
+ _controlledNPCNum = num;
+ CameraProcess::SetCameraProcess(new CameraProcess(num));
+ Actor *previous = getActor(oldnpc);
+ if (previous && !previous->isDead() && previous->isInCombat()) {
+ previous->clearInCombat();
+ }
+
+ Actor *controlled = getActor(num);
+ if (controlled && controlled->isInCombat() && num != 1) {
+ controlled->clearInCombat();
+ }
+
+ TargetReticleProcess *t = TargetReticleProcess::get_instance();
+ if (t) {
+ t->avatarMoved();
+ }
}
+
uint32 World::I_getAlertActive(const uint8 * /*args*/,
unsigned int /*argsize*/) {
return get_instance()->_world->isAlertActive() ? 1 : 0;
Commit: 46c913e557b83c552f944e3757ba39be643a92a1
https://github.com/scummvm/scummvm/commit/46c913e557b83c552f944e3757ba39be643a92a1
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2021-04-04T08:26:46+09:00
Commit Message:
ULTIMA8: Improve anim debug messages
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 91b6aca2fe..3e0f89ea0f 100644
--- a/engines/ultima/ultima8/world/actors/actor_anim_process.cpp
+++ b/engines/ultima/ultima8/world/actors/actor_anim_process.cpp
@@ -92,7 +92,8 @@ bool ActorAnimProcess::init() {
//! Or maybe wait until the previous one finishes?
perr << "ActorAnimProcess [" << getPid() << "]: ANIMLOCK set on actor "
- << _itemNum << Std::endl;
+ << _itemNum << ", skipping anim (" << _action << "," << _dir << ")"
+ << Std::endl;
// for now, just don't play this one.
return false;
@@ -115,7 +116,8 @@ bool ActorAnimProcess::init() {
if (_itemNum == watchactor)
pout << "Animation [" << Kernel::get_instance()->getFrameNum()
<< "] ActorAnimProcess " << getPid() << " created ("
- << _action << "," << _dir << ") steps " << _steps << Std::endl;
+ << _itemNum << "," << _action << "," << _dir << ") steps "
+ << _steps << Std::endl;
#endif
return true;
More information about the Scummvm-git-logs
mailing list