[Scummvm-git-logs] scummvm master -> 749214ce61d9f24d1ec2f769ae32d842a4ef41da
mduggan
mgithub at guarana.org
Mon Jul 13 04:19:29 UTC 2020
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:
6e99e85407 ULTIMA8: Play correct SFX when Silencer dies in Crusader
ac0f52b028 ULTIMA8: Make intrinsics behave more correctly in Crusader
c58c235249 ULTIMA8: Remember actor activity numbers in Crusader
754c415016 ULTIMA8: Always have camera follow avatar in quick mover
a037987282 ULTIMA8: Fix typo in comment
c8d1a017f5 ULTIMA8: Add some useful warp points for debugging
bb7638917e ULTIMA8: Fix usecode dump output
427d653683 ULTIMA8: Add loader for Crusader damage flex
749214ce61 ULTIMA8: Correct comment and variable name
Commit: 6e99e85407f6b574b2fcf5c4f6dd233ff2d12994
https://github.com/scummvm/scummvm/commit/6e99e85407f6b574b2fcf5c4f6dd233ff2d12994
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-07-13T12:55:21+09:00
Commit Message:
ULTIMA8: Play correct SFX when Silencer dies in Crusader
Changed paths:
engines/ultima/ultima8/world/actors/avatar_death_process.cpp
diff --git a/engines/ultima/ultima8/world/actors/avatar_death_process.cpp b/engines/ultima/ultima8/world/actors/avatar_death_process.cpp
index 8aec052e22..95b6dfd227 100644
--- a/engines/ultima/ultima8/world/actors/avatar_death_process.cpp
+++ b/engines/ultima/ultima8/world/actors/avatar_death_process.cpp
@@ -28,10 +28,12 @@
#include "ultima/ultima8/games/game_data.h"
#include "ultima/ultima8/kernel/kernel.h"
#include "ultima/ultima8/kernel/core_app.h"
+#include "ultima/ultima8/kernel/delay_process.h"
#include "ultima/ultima8/gumps/main_menu_process.h"
#include "ultima/ultima8/gumps/gump_notify_process.h"
#include "ultima/ultima8/graphics/palette_manager.h"
#include "ultima/ultima8/audio/music_process.h"
+#include "ultima/ultima8/audio/audio_process.h"
#include "ultima/ultima8/world/get_object.h"
namespace Ultima {
@@ -69,13 +71,21 @@ void AvatarDeathProcess::run() {
Kernel::get_instance()->addProcess(menuproc);
if (GAME_IS_U8) {
- // TODO: What should this do in crusader?
+ // Show the avatar gravestone
ReadableGump *gump = new ReadableGump(1, 27, 11,
_TL_("HERE LIES*THE AVATAR*REST IN PEACE"));
gump->InitGump(0);
gump->setRelativePosition(Gump::CENTER);
Process *gumpproc = gump->GetNotifyProcess();
menuproc->waitFor(gumpproc);
+ } else {
+ // Play "Silencer Terminated" audio and wait
+ // a couple of seconds before showing menu
+ AudioProcess *ap = AudioProcess::get_instance();
+ ap->playSFX(9, 0x10, 0, 1);
+ DelayProcess *delayproc = new DelayProcess(60);
+ Kernel::get_instance()->addProcess(delayproc);
+ menuproc->waitFor(delayproc);
}
// done
Commit: ac0f52b02853f7fd6d5e1985c2c8d8ddd047cd22
https://github.com/scummvm/scummvm/commit/ac0f52b02853f7fd6d5e1985c2c8d8ddd047cd22
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-07-13T12:55:21+09:00
Commit Message:
ULTIMA8: Make intrinsics behave more correctly in Crusader
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 84d1c14426..351faadafc 100644
--- a/engines/ultima/ultima8/world/item.cpp
+++ b/engines/ultima/ultima8/world/item.cpp
@@ -538,8 +538,9 @@ bool Item::isOn(const Item &item2) const {
}
bool Item::isCompletelyOn(const Item &item2) const {
- warning("TODO: Properly implement Item::isCompletelyOn");
- // FIXME: this is just a copy of isOn at the moment
+ if (hasFlags(FLG_CONTAINED) || item2.hasFlags(FLG_CONTAINED))
+ return false;
+
int32 x1a, y1a, z1a, x1b, y1b;
int32 x2a, y2a, z2a, x2b, y2b, z2b;
getLocation(x1b, y1b, z1a);
@@ -555,10 +556,9 @@ bool Item::isCompletelyOn(const Item &item2) const {
y2a = y2b - yd;
z2b = z2a + zd;
- if (x1b <= x2a || x2b <= x1a) return false;
- if (y1b <= y2a || y2b <= y1a) return false;
- if (z2b == z1a) return true;
- return false;
+ return ((x1b <= x2b && x2a <= x1a) &&
+ (y1b <= y2b && y2a <= y1a) &&
+ (z2b == z1a));
}
bool Item::isCentreOn(const Item &item2) const {
@@ -1279,11 +1279,13 @@ uint32 Item::use() {
Actor *actor = dynamic_cast<Actor *>(this);
if (actor) {
if (actor->isDead()) {
- // dead actor, so open/close the dead-body-_gump
- if (hasFlags(FLG_GUMP_OPEN)) {
- closeGump();
- } else {
- openGump(12); // CONSTANT!!
+ if (GAME_IS_U8) {
+ // dead actor, so open/close the dead-body-gump
+ if (hasFlags(FLG_GUMP_OPEN)) {
+ closeGump();
+ } else {
+ openGump(12); // CONSTANT!!
+ }
}
return 0;
}
@@ -1457,11 +1459,17 @@ void Item::enterFastArea() {
// Call usecode
if (!(_flags & FLG_FASTAREA)) {
-
Actor *actor = dynamic_cast<Actor *>(this);
- if (actor && actor->isDead()) {
+ // Crusader special-cases a few shapes even when they are dead.
+ bool call_even_if_dead = (_shape == 0x576 || _shape == 0x596 ||
+ _shape == 0x59c || _shape == 0x58f) && GAME_IS_CRUSADER;
+ if (actor && actor->isDead() && !call_even_if_dead) {
// dead actor, don't call the usecode
} else {
+ if (actor && GAME_IS_CRUSADER) {
+ actor->clearLastActivityNo();
+ actor->clearInCombat();
+ }
callUsecodeEvent_enterFastArea();
}
}
Commit: c58c235249536ce6728e2cadfde47bb9cdda0406
https://github.com/scummvm/scummvm/commit/c58c235249536ce6728e2cadfde47bb9cdda0406
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-07-13T12:55:21+09:00
Commit Message:
ULTIMA8: Remember actor activity numbers in Crusader
Changed paths:
engines/ultima/ultima8/usecode/remorse_intrinsics.h
engines/ultima/ultima8/world/actors/actor.cpp
engines/ultima/ultima8/world/actors/actor.h
diff --git a/engines/ultima/ultima8/usecode/remorse_intrinsics.h b/engines/ultima/ultima8/usecode/remorse_intrinsics.h
index ed987f054e..c8b3a81c42 100644
--- a/engines/ultima/ultima8/usecode/remorse_intrinsics.h
+++ b/engines/ultima/ultima8/usecode/remorse_intrinsics.h
@@ -120,7 +120,7 @@ Intrinsic RemorseIntrinsics[] = {
Item::I_isOn,
Item::I_getQHi, // based on same coff set as 026
// 0x050
- 0, // TODO: int16 Actor::I_getCurrentActivityNo // void Intrinsic050(4 bytes)
+ Actor::I_getCurrentActivityNo, // void Intrinsic050(4 bytes)
Actor::I_clrInCombat, // void Intrinsic051(4 bytes)
Actor::I_setDefaultActivity0, // void Intrinsic052(6 bytes)
Actor::I_setDefaultActivity1, // void Intrinsic053(6 bytes)
@@ -269,7 +269,7 @@ Intrinsic RemorseIntrinsics[] = {
0, // TODO: PaletteFaderProcess::I_setPalToAllGrey // sets all colors to 0x3F3F3F
Actor::I_setActivity, // void Intrinsic0DB(6 bytes)
Item::I_isOn,
- 0, // TODO: Actor::I_getLastActivityNo void Intrinsic0DD(4 bytes)
+ Actor::I_getLastActivityNo, // void Intrinsic0DD(4 bytes)
Actor::I_setCombatTactic, // void Intrinsic0DE(6 bytes)
Actor::I_getEquip, // void Intrinsic0DF(6 bytes)
// 0x0E0
diff --git a/engines/ultima/ultima8/world/actors/actor.cpp b/engines/ultima/ultima8/world/actors/actor.cpp
index 0865328c23..9f1eef5240 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),
_hitPoints(0), _mana(0), _alignment(0), _enemyAlignment(0),
_lastAnim(Animation::stand), _animFrame(0), _direction(0),
_fallStart(0), _unkByte(0), _actorFlags(0), _combatTactic(0),
- _homeX(0), _homeY(0), _homeZ(0) {
+ _homeX(0), _homeY(0), _homeZ(0), _currentActivityNo(0),
+ _lastActivityNo(0) {
_defaultActivity[0] = 0;
_defaultActivity[1] = 0;
_defaultActivity[2] = 0;
@@ -573,6 +574,9 @@ uint16 Actor::setActivityCru(int activity) {
if (isDead())
return 0;
+ _lastActivityNo = _currentActivityNo;
+ _currentActivityNo = activity;
+
switch (activity) {
case 1: // stand
return doAnim(Animation::stand, 8);
@@ -1241,6 +1245,8 @@ void Actor::saveData(Common::WriteStream *ws) {
ws->writeUint32LE(_homeX);
ws->writeUint32LE(_homeY);
ws->writeUint32LE(_homeZ);
+ ws->writeUint16LE(_currentActivityNo);
+ ws->writeUint16LE(_lastActivityNo);
}
}
@@ -1269,6 +1275,8 @@ bool Actor::loadData(Common::ReadStream *rs, uint32 version) {
_homeX = rs->readUint32LE();
_homeY = rs->readUint32LE();
_homeZ = rs->readUint32LE();
+ _currentActivityNo = rs->readUint16LE();
+ _lastActivityNo = rs->readUint16LE();
}
return true;
@@ -1959,7 +1967,19 @@ uint32 Actor::I_setCombatTactic(const uint8 *args, unsigned int /*argsize*/) {
return 0;
}
+uint32 Actor::I_getCurrentActivityNo(const uint8 *args, unsigned int /*argsize*/) {
+ ARG_ACTOR_FROM_PTR(actor);
+ if (!actor) return 0;
+
+ return actor->getCurrentActivityNo();
+}
+uint32 Actor::I_getLastActivityNo(const uint8 *args, unsigned int /*argsize*/) {
+ ARG_ACTOR_FROM_PTR(actor);
+ if (!actor) return 0;
+
+ return actor->getLastActivityNo();
+}
} // End of namespace Ultima8
} // End of namespace Ultima
diff --git a/engines/ultima/ultima8/world/actors/actor.h b/engines/ultima/ultima8/world/actors/actor.h
index 1b7a77e7ac..5729f9824b 100644
--- a/engines/ultima/ultima8/world/actors/actor.h
+++ b/engines/ultima/ultima8/world/actors/actor.h
@@ -210,6 +210,18 @@ public:
//! \return processID of process handling the activity or zero
uint16 setActivity(int activity);
+ uint16 getCurrentActivityNo() const {
+ return _currentActivityNo;
+ }
+
+ uint16 getLastActivityNo() const {
+ return _lastActivityNo;
+ }
+
+ void clearLastActivityNo() {
+ _lastActivityNo = 0;
+ }
+
//! run the given animation
//! \return the PID of the ActorAnimProcess
uint16 doAnim(Animation::Sequence anim, int dir, unsigned int steps = 0);
@@ -302,6 +314,8 @@ public:
INTRINSIC(I_setCombatTactic);
INTRINSIC(I_setUnkByte);
INTRINSIC(I_getUnkByte);
+ INTRINSIC(I_getLastActivityNo);
+ INTRINSIC(I_getCurrentActivityNo);
enum ActorFlags {
ACT_INVINCIBLE = 0x000001, // flags from npcdata byte 0x1B
@@ -355,6 +369,10 @@ protected:
int32 _homeY;
int32 _homeZ;
+ //! Current and last activity (only used in Crusader)
+ uint16 _currentActivityNo;
+ uint16 _lastActivityNo;
+
//! starts an activity (Ultima 8 version)
//! \return processID of process handling the activity or zero
uint16 setActivityU8(int activity);
Commit: 754c415016a5e708cf3097bb39e12024941a8621
https://github.com/scummvm/scummvm/commit/754c415016a5e708cf3097bb39e12024941a8621
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-07-13T13:14:36+09:00
Commit Message:
ULTIMA8: Always have camera follow avatar in quick mover
Changed paths:
engines/ultima/ultima8/world/actors/quick_avatar_mover_process.cpp
diff --git a/engines/ultima/ultima8/world/actors/quick_avatar_mover_process.cpp b/engines/ultima/ultima8/world/actors/quick_avatar_mover_process.cpp
index 0320fa2ab9..c3e6007ad2 100644
--- a/engines/ultima/ultima8/world/actors/quick_avatar_mover_process.cpp
+++ b/engines/ultima/ultima8/world/actors/quick_avatar_mover_process.cpp
@@ -26,8 +26,10 @@
#include "ultima/ultima8/world/world.h"
#include "ultima/ultima8/world/current_map.h"
#include "ultima/ultima8/kernel/kernel.h"
+#include "ultima/ultima8/kernel/core_app.h"
#include "ultima/ultima8/ultima8.h"
#include "ultima/ultima8/graphics/shape_info.h"
+#include "ultima/ultima8/world/camera_process.h"
#include "ultima/ultima8/world/get_object.h"
#include "ultima/ultima8/world/actors/avatar_mover_process.h"
@@ -124,6 +126,10 @@ void QuickAvatarMoverProcess::run() {
// Yes, i know, not entirely correct
avatar->collideMove(x + dxv, y + dyv, z + dzv, false, true);
+ if (GAME_IS_CRUSADER) {
+ // Keep the camera on the avatar while we're quick-moving.
+ CameraProcess::SetCameraProcess(new CameraProcess(x + dxv, y + dyv, z + dzv));
+ }
// Prevent avatar from running an idle animation while moving around
Ultima8Engine::get_instance()->getAvatarMoverProcess()->resetIdleTime();
Commit: a0379872822b6ff3474e7e2f294f14f429e5ac16
https://github.com/scummvm/scummvm/commit/a0379872822b6ff3474e7e2f294f14f429e5ac16
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-07-13T13:14:41+09:00
Commit Message:
ULTIMA8: Fix typo in comment
Changed paths:
engines/ultima/ultima8/world/item.h
diff --git a/engines/ultima/ultima8/world/item.h b/engines/ultima/ultima8/world/item.h
index 0f4bf761f6..dec7d85a45 100644
--- a/engines/ultima/ultima8/world/item.h
+++ b/engines/ultima/ultima8/world/item.h
@@ -226,7 +226,7 @@ public:
return _mapNum;
}
- //! Set the 'NpcNum' of this Item. Note that this can represent various
+ //! Set the 'MapNum' of this Item. Note that this can represent various
//! things depending on the family of this Item.
void setMapNum(uint16 mapnum_) {
_mapNum = mapnum_;
Commit: c8d1a017f545fb2bc59e442fd9ab3195d81cb759
https://github.com/scummvm/scummvm/commit/c8d1a017f545fb2bc59e442fd9ab3195d81cb759
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-07-13T13:14:41+09:00
Commit Message:
ULTIMA8: Add some useful warp points for debugging
Changed paths:
engines/ultima/ultima8/games/remorse_game.cpp
diff --git a/engines/ultima/ultima8/games/remorse_game.cpp b/engines/ultima/ultima8/games/remorse_game.cpp
index 9dfd65623c..97ef21150d 100644
--- a/engines/ultima/ultima8/games/remorse_game.cpp
+++ b/engines/ultima/ultima8/games/remorse_game.cpp
@@ -122,7 +122,18 @@ bool RemorseGame::startGame() {
ObjectManager::get_instance()->assignActorObjId(actor, 1);
if (GAME_IS_REMORSE) {
- actor->setLocation(60716, 59400, 16);
+ // Some useful points to warp into for testing..
+ actor->setLocation(60716, 59400, 16); // Map 1 (mission 1)
+ //actor->setLocation(42493, 26621, 16); // Map 2 (mission 1 / level 4)
+ //actor->setLocation(34302, 32254, 16); // Map 3 (mission 2)
+ //actor->setLocation(34813, 33789, 16); // Map 4
+ //actor->setLocation(37373, 30205, 16); // Map 5
+ //actor->setLocation(37373, 30205, 16); // Map 6
+ //actor->setLocation(35070, 26142, 96); // Map 7
+ //actor->setLocation(29693, 32253, 0); // Map 8 - unfinished area?
+ //actor->setLocation(2046, 2046, 0); // Map 9
+ //actor->setLocation(14845, 6141, 0); // Map 22 - debugging map
+ //actor->setLocation(34302, 32254, 16); // Map 40 (Rebel base)
} else {
actor->setLocation(58174, 56606, 16);
}
@@ -165,7 +176,7 @@ ProcId RemorseGame::playEndgameMovie(bool fade) {
}
void RemorseGame::playCredits() {
-
+ warning("TODO: Implement Crusader credits..");
}
void RemorseGame::writeSaveInfo(Common::WriteStream *ws) {
Commit: bb7638917e5095bd07045d15a326b77ad51e5eca
https://github.com/scummvm/scummvm/commit/bb7638917e5095bd07045d15a326b77ad51e5eca
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-07-13T13:14:59+09:00
Commit Message:
ULTIMA8: Fix usecode dump output
Changed paths:
engines/ultima/ultima8/usecode/uc_machine.cpp
diff --git a/engines/ultima/ultima8/usecode/uc_machine.cpp b/engines/ultima/ultima8/usecode/uc_machine.cpp
index 9e3d5bfc2e..cd2cf1c498 100644
--- a/engines/ultima/ultima8/usecode/uc_machine.cpp
+++ b/engines/ultima/ultima8/usecode/uc_machine.cpp
@@ -2027,6 +2027,7 @@ void UCMachine::execProcess(UCProcess *p) {
case 0x5B: {
ui16a = cs.readUint16LE(); // source line number
debug(10, "ignore debug opcode %02X: line offset %d", opcode, ui16a);
+ LOGPF(("line number %d\n", ui16a));
break;
}
case 0x5C: {
@@ -2036,6 +2037,7 @@ void UCMachine::execProcess(UCProcess *p) {
// skip over class name and null terminator
name[x] = cs.readByte();
}
+ LOGPF(("line number %s %d\n", name, ui16a));
debug(10, "ignore debug opcode %02X: %s line offset %d", opcode, name, ui16a);
break;
}
@@ -2454,8 +2456,8 @@ uint32 UCMachine::I_rndRange(const uint8 *args, unsigned int /*argsize*/) {
ARG_SINT16(hi);
// return random integer between lo (incl.) to hi (incl.)
-
- if (hi <= lo) return lo;
+ if (hi <= lo)
+ return lo;
return (lo + (getRandom() % (hi - lo + 1)));
}
Commit: 427d65368310d50f8ae00a619b41ab8feed40a07
https://github.com/scummvm/scummvm/commit/427d65368310d50f8ae00a619b41ab8feed40a07
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-07-13T13:16:10+09:00
Commit Message:
ULTIMA8: Add loader for Crusader damage flex
Changed paths:
A engines/ultima/ultima8/world/damage_info.cpp
A engines/ultima/ultima8/world/damage_info.h
engines/ultima/module.mk
engines/ultima/ultima8/games/game_data.cpp
engines/ultima/ultima8/graphics/main_shape_archive.cpp
engines/ultima/ultima8/graphics/main_shape_archive.h
engines/ultima/ultima8/graphics/shape_info.h
engines/ultima/ultima8/graphics/type_flags.cpp
engines/ultima/ultima8/graphics/type_flags.h
diff --git a/engines/ultima/module.mk b/engines/ultima/module.mk
index 56632f4933..d419906744 100644
--- a/engines/ultima/module.mk
+++ b/engines/ultima/module.mk
@@ -528,6 +528,7 @@ MODULE_OBJS := \
ultima8/world/create_item_process.o \
ultima8/world/crosshair_process.o \
ultima8/world/current_map.o \
+ ultima8/world/damage_info.o \
ultima8/world/destroy_item_process.o \
ultima8/world/egg.o \
ultima8/world/egg_hatcher_process.o \
diff --git a/engines/ultima/ultima8/games/game_data.cpp b/engines/ultima/ultima8/games/game_data.cpp
index e3e307d1e1..6a90cde653 100644
--- a/engines/ultima/ultima8/games/game_data.cpp
+++ b/engines/ultima/ultima8/games/game_data.cpp
@@ -633,11 +633,10 @@ void GameData::loadRemorseData() {
error("Unable to load static/damage.flx");
RawArchive *damageflex = new RawArchive(damageds);
+ if (damageflex->getCount() != 1)
+ error("static/damage.flx appears corrupted");
- // TODO: What's in this flex file?
- // 1 object of 12288 bytes, mostly 0s
- //_damage = new DamageDat();
- //_damage->load(damageflex);
+ _mainShapes->loadDamageDat(damageflex->get_datasource(0));
delete damageflex;
diff --git a/engines/ultima/ultima8/graphics/main_shape_archive.cpp b/engines/ultima/ultima8/graphics/main_shape_archive.cpp
index c79af9dde4..e20ea63dfe 100644
--- a/engines/ultima/ultima8/graphics/main_shape_archive.cpp
+++ b/engines/ultima/ultima8/graphics/main_shape_archive.cpp
@@ -49,6 +49,11 @@ void MainShapeArchive::loadTypeFlags(Common::SeekableReadStream *rs) {
_typeFlags->load(rs);
}
+void MainShapeArchive::loadDamageDat(Common::SeekableReadStream *rs) {
+ assert(_typeFlags);
+ _typeFlags->loadDamageDat(rs);
+}
+
ShapeInfo *MainShapeArchive::getShapeInfo(uint32 shapenum) {
assert(_typeFlags);
diff --git a/engines/ultima/ultima8/graphics/main_shape_archive.h b/engines/ultima/ultima8/graphics/main_shape_archive.h
index 8fa93ede77..73041670c9 100644
--- a/engines/ultima/ultima8/graphics/main_shape_archive.h
+++ b/engines/ultima/ultima8/graphics/main_shape_archive.h
@@ -50,6 +50,7 @@ public:
~MainShapeArchive() override;
void loadTypeFlags(Common::SeekableReadStream *rs);
+ void loadDamageDat(Common::SeekableReadStream *rs);
ShapeInfo *getShapeInfo(uint32 shapenum);
void loadAnimDat(Common::SeekableReadStream *rs);
diff --git a/engines/ultima/ultima8/graphics/shape_info.h b/engines/ultima/ultima8/graphics/shape_info.h
index 3b95765694..3b6c06565e 100644
--- a/engines/ultima/ultima8/graphics/shape_info.h
+++ b/engines/ultima/ultima8/graphics/shape_info.h
@@ -25,6 +25,7 @@
#include "ultima/ultima8/world/weapon_info.h"
#include "ultima/ultima8/world/armour_info.h"
+#include "ultima/ultima8/world/damage_info.h"
#include "ultima/ultima8/world/actors/monster_info.h"
namespace Ultima {
@@ -97,6 +98,7 @@ public:
WeaponInfo *_weaponInfo;
ArmourInfo *_armourInfo;
MonsterInfo *_monsterInfo;
+ DamageInfo *_damageInfo;
inline bool is_fixed() const {
return (_flags & SI_FIXED) != 0;
@@ -145,6 +147,10 @@ public:
return (_family == SF_QUANTITY || _family == SF_REAGENT);
}
+ bool takesDamage() const {
+ return (_damageInfo && _damageInfo->takesDamage());
+ }
+
bool getTypeFlag(int typeFlag);
bool getTypeFlagU8(int typeFlag);
bool getTypeFlagCrusader(int typeFlag);
@@ -156,12 +162,13 @@ public:
_family(0), _equipType(0), _animType(0), _animData(0),
_unknown(0), _weight(0), _volume(0),
_weaponInfo(nullptr), _armourInfo(nullptr),
- _monsterInfo(nullptr) { }
+ _monsterInfo(nullptr), _damageInfo(nullptr) { }
~ShapeInfo() {
delete _weaponInfo;
delete[] _armourInfo;
delete _monsterInfo;
+ delete _damageInfo;
}
};
diff --git a/engines/ultima/ultima8/graphics/type_flags.cpp b/engines/ultima/ultima8/graphics/type_flags.cpp
index 2297a2ddc2..590553679b 100644
--- a/engines/ultima/ultima8/graphics/type_flags.cpp
+++ b/engines/ultima/ultima8/graphics/type_flags.cpp
@@ -51,10 +51,6 @@ ShapeInfo *TypeFlags::getShapeInfo(uint32 shapenum) {
void TypeFlags::load(Common::SeekableReadStream *rs) {
- // TODO: detect U8/crusader format somehow?!
- // (Or probably pass it as parameter)
- // The 'parsing' below is only for U8
-
unsigned int blocksize = 8;
if (GAME_IS_CRUSADER) {
blocksize = 9;
@@ -266,7 +262,12 @@ void TypeFlags::loadWeaponInfo() {
else
wi->_displayGumpShape = 3;
- assert(wi->_shape < _shapeInfo.size());
+ if (wi->_shape > _shapeInfo.size()) {
+ warning("ignoring weapon info for shape %d beyond size %d.",
+ wi->_shape, _shapeInfo.size());
+ delete wi;
+ continue;
+ }
_shapeInfo[wi->_shape]._weaponInfo = wi;
}
}
@@ -416,5 +417,23 @@ void TypeFlags::loadMonsterInfo() {
}
}
+void TypeFlags::loadDamageDat(Common::SeekableReadStream *rs) {
+ uint32 count = rs->size() / 6;
+ if (_shapeInfo.size() < count) {
+ warning("more damage info than shape info");
+ return;
+ }
+ for (uint32 i = 0; i < count; i++) {
+ byte damagedata[6];
+ rs->read(damagedata, 6);
+ if (damagedata[0] == 0)
+ continue;
+
+ DamageInfo *di = new DamageInfo(damagedata);
+ _shapeInfo[i]._damageInfo = di;
+ }
+}
+
+
} // End of namespace Ultima8
} // End of namespace Ultima
diff --git a/engines/ultima/ultima8/graphics/type_flags.h b/engines/ultima/ultima8/graphics/type_flags.h
index d5512de15f..27f1f350df 100644
--- a/engines/ultima/ultima8/graphics/type_flags.h
+++ b/engines/ultima/ultima8/graphics/type_flags.h
@@ -35,6 +35,7 @@ public:
~TypeFlags();
void load(Common::SeekableReadStream *rs);
+ void loadDamageDat(Common::SeekableReadStream *rs);
ShapeInfo *getShapeInfo(uint32 shape);
private:
diff --git a/engines/ultima/ultima8/world/damage_info.cpp b/engines/ultima/ultima8/world/damage_info.cpp
new file mode 100644
index 0000000000..473cb3905f
--- /dev/null
+++ b/engines/ultima/ultima8/world/damage_info.cpp
@@ -0,0 +1,87 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "ultima/ultima8/misc/pent_include.h"
+#include "ultima/ultima8/world/damage_info.h"
+#include "ultima/ultima8/world/item.h"
+#include "ultima/ultima8/world/item_factory.h"
+#include "ultima/ultima8/audio/audio_process.h"
+#include "ultima/ultima8/kernel/kernel.h"
+
+namespace Ultima {
+namespace Ultima8 {
+
+DamageInfo::DamageInfo(uint8 data[6]) {
+ _flags = data[0];
+ _sound = data[1];
+ _data[0] = data[2];
+ _data[1] = data[3];
+ _data[2] = data[4];
+ _data[3] = data[5];
+}
+
+void DamageInfo::applyToItem(Item *item) {
+ if (!item)
+ return;
+ if (explode()) {
+ item->explode(explosionType(), explodeDestroysItem());
+ }
+ if (_sound) {
+ AudioProcess *audio = AudioProcess::get_instance();
+ if (audio) {
+ audio->playSFX(_sound, 0x10, item->getObjId(), 1, true);
+ }
+ }
+ if (replaceItem()) {
+ uint16 q = item->getQuality();
+ int32 x, y, z;
+ item->getLocation(x, y, z);
+ uint16 replacementShape = getReplacementShape();
+ uint8 replacementFrame = getReplacementFrame();
+ Item *newitem = ItemFactory::createItem(replacementShape, replacementFrame, q, 0, 0, 0, 0, true);
+ newitem->setLocation(x, y, z);
+ } else {
+ if (frameDataIsAbsolute()) {
+ int frameval = 1;
+ if (_data[1])
+ frameval++;
+ if (_data[2])
+ frameval++;
+ item->setFrame(_data[getRandom() % frameval]);
+ } else {
+ int frameoff = 0;
+ for (int i = 0; i < 3; i++)
+ if (_data[i])
+ frameoff++;
+ if (!frameoff) {
+ item->destroy();
+ } else {
+ uint32 frame = item->getFrame();
+ item->setFrame(frame + _data[getRandom() % frameoff]);
+ }
+ }
+ }
+}
+
+
+} // End of namespace Ultima8
+} // End of namespace Ultima
diff --git a/engines/ultima/ultima8/world/damage_info.h b/engines/ultima/ultima8/world/damage_info.h
new file mode 100644
index 0000000000..0760699f40
--- /dev/null
+++ b/engines/ultima/ultima8/world/damage_info.h
@@ -0,0 +1,89 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef WORLD_DAMAGE_INFO_H
+#define WORLD_DAMAGE_INFO_H
+
+#include "common/stream.h"
+
+#include "ultima/shared/std/string.h"
+
+namespace Ultima {
+namespace Ultima8 {
+
+class Item;
+
+/**
+ * The damage.dat flex contains data about each shape and how it should be damaged
+ */
+class DamageInfo {
+public:
+ DamageInfo(uint8 data[6]);
+ ~DamageInfo() {};
+
+ void applyToItem(Item *item);
+
+ bool takesDamage() {
+ return _flags != 0;
+ }
+
+protected:
+ bool replaceItem() const {
+ return (_flags & 0x40) != 0;
+ }
+ bool explode() const {
+ return (_flags & 0x06) != 0;
+ }
+ bool explosionType() const{
+ assert(explode());
+ return ((_flags & 0x06) >> 1) - 1;
+ }
+ bool explodeDestroysItem() const {
+ return (_flags >> 5) & 1;
+ }
+ bool explodeWithDamage() const {
+ return (_flags >> 3) & 1;
+ }
+
+ uint16 getReplacementShape() const {
+ assert(replaceItem());
+ return static_cast<uint16>(_data[1]) << 16 | _data[0];
+ }
+
+ uint16 getReplacementFrame() const {
+ assert(replaceItem());
+ return static_cast<uint16>(_data[2]);
+ }
+
+ bool frameDataIsAbsolute() const {
+ return (_flags & 0x80) != 0;
+ }
+
+ uint8 _flags;
+ uint8 _sound;
+ uint8 _data[4];
+};
+
+} // End of namespace Ultima8
+} // End of namespace Ultima
+
+#endif
Commit: 749214ce61d9f24d1ec2f769ae32d842a4ef41da
https://github.com/scummvm/scummvm/commit/749214ce61d9f24d1ec2f769ae32d842a4ef41da
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-07-13T13:16:22+09:00
Commit Message:
ULTIMA8: Correct comment and variable name
Changed paths:
engines/ultima/ultima8/world/actors/main_actor.cpp
diff --git a/engines/ultima/ultima8/world/actors/main_actor.cpp b/engines/ultima/ultima8/world/actors/main_actor.cpp
index 23d0517de3..3327d337d0 100644
--- a/engines/ultima/ultima8/world/actors/main_actor.cpp
+++ b/engines/ultima/ultima8/world/actors/main_actor.cpp
@@ -693,15 +693,15 @@ uint32 MainActor::I_teleportToEgg(const uint8 *args, unsigned int argsize) {
ARG_UINT16(map);
mapnum = map;
} else {
- // TODO: Confirm this works right.
- // Crusader teleport uses main actor map.
+ // Crusader teleport intrinsic 096 uses main actor map.
+ // Intrinsic 079 provides a map argument.
assert(argsize == 8);
MainActor *av = getMainActor();
mapnum = av->getMapNum();
}
ARG_UINT16(teleport_id);
- ARG_UINT16(unknown); // 0/1
+ ARG_UINT16(put_in_stasis); // 0/1
return Kernel::get_instance()->addProcess(
new TeleportToEggProcess(mapnum, teleport_id));
More information about the Scummvm-git-logs
mailing list