mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-14 16:07:39 +00:00
ULTIMA8: Call full code for enterFastArea from intrinsic
Previously we just spawned the usecode event, but to be faithful to the original the intrinsic should do everything in Item::enterFastArea. This also adds a workaround for a bug that was occasionally triggered when returning to the rebel base in Crusader: No Remorse, and fixes an original game bug in the process.
This commit is contained in:
parent
96c5f721db
commit
a8e83a86b0
@ -40,7 +40,7 @@ GlobEgg::~GlobEgg() {
|
||||
|
||||
|
||||
// Called when an item has entered the fast area
|
||||
void GlobEgg::enterFastArea() {
|
||||
uint32 GlobEgg::enterFastArea() {
|
||||
uint32 coordmask = ~0x1FFU;
|
||||
unsigned int coordshift = 1;
|
||||
unsigned int offset = 1;
|
||||
@ -53,7 +53,7 @@ void GlobEgg::enterFastArea() {
|
||||
// Expand it
|
||||
if (!hasFlags(FLG_FASTAREA)) {
|
||||
const MapGlob *glob = GameData::get_instance()->getGlob(_quality);
|
||||
if (!glob) return;
|
||||
if (!glob) return 0;
|
||||
|
||||
Std::vector<GlobItem>::const_iterator iter;
|
||||
for (iter = glob->_contents.begin(); iter != glob->_contents.end(); ++iter) {
|
||||
@ -73,7 +73,7 @@ void GlobEgg::enterFastArea() {
|
||||
}
|
||||
}
|
||||
|
||||
Item::enterFastArea();
|
||||
return Item::enterFastArea();
|
||||
}
|
||||
|
||||
void GlobEgg::saveData(Common::WriteStream *ws) {
|
||||
|
@ -39,7 +39,7 @@ public:
|
||||
ENABLE_RUNTIME_CLASSTYPE()
|
||||
|
||||
//! The item has entered the fast area
|
||||
void enterFastArea() override;
|
||||
uint32 enterFastArea() override;
|
||||
|
||||
bool loadData(Common::ReadStream *rs, uint32 version);
|
||||
void saveData(Common::WriteStream *ws) override;
|
||||
|
@ -1812,10 +1812,11 @@ void Item::animateItem() {
|
||||
|
||||
|
||||
// Called when an item has entered the fast area
|
||||
void Item::enterFastArea() {
|
||||
uint32 Item::enterFastArea() {
|
||||
uint16 retval = 0;
|
||||
//!! HACK to get rid of endless SFX loops
|
||||
if (_shape == 0x2c8 && GAME_IS_U8)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
const ShapeInfo *si = getShapeInfo();
|
||||
|
||||
@ -1841,13 +1842,12 @@ void Item::enterFastArea() {
|
||||
// certain global is set. For now just skip that.
|
||||
|
||||
//
|
||||
// TODO: Check this. The original games only call usecode for actors or
|
||||
// NOISY types. Calling for all types like this shouldn't cause any issues
|
||||
// as long as all the types which implement event F are NPC or NOISY.
|
||||
// Should confirm if that is the case.
|
||||
// NOTE: Original games only call usecode for actors or NOISY
|
||||
// types. We call for all types to fix an usecode bug in
|
||||
// Crusader: No Remorse. See note about it below.
|
||||
//
|
||||
// if (actor || si->_flags & ShapeInfo::SI_NOISY)
|
||||
callUsecodeEvent_enterFastArea();
|
||||
retval = callUsecodeEvent_enterFastArea();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1864,6 +1864,25 @@ void Item::enterFastArea() {
|
||||
|
||||
// We're fast!
|
||||
_flags |= FLG_FASTAREA;
|
||||
|
||||
//
|
||||
// WORKAROUND: Crusader: No Remorse usecode has one place (REB_EGG, after
|
||||
// randomly creating 0x34D REB_COUP (rebel couple) at the bar) where this
|
||||
// is called with an "implies" but the enterFastArea event code never
|
||||
// returns. Every other instance this is "spawn"ed.
|
||||
//
|
||||
// In the original this bug is never triggered as enterFastArea intrinsic
|
||||
// does not call usecode event unless the shape is SI_NOISY (REB_COUP is
|
||||
// not). The result is the rebel couple do not start moving until you move
|
||||
// near them and trigger their event, then enterFastArea function is
|
||||
// spawned directly.
|
||||
//
|
||||
// Work around both problems by always calling event above and return 0.
|
||||
//
|
||||
if (_shape == 0x34D && GAME_IS_REMORSE)
|
||||
return 0;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
// Called when an item is leaving the fast area
|
||||
@ -3029,7 +3048,7 @@ uint32 Item::I_enterFastArea(const uint8 *args, unsigned int /*argsize*/) {
|
||||
ARG_ITEM_FROM_PTR(item);
|
||||
if (!item) return 0;
|
||||
|
||||
return item->callUsecodeEvent_enterFastArea();
|
||||
return item->enterFastArea();
|
||||
}
|
||||
|
||||
uint32 Item::I_cast(const uint8 *args, unsigned int /*argsize*/) {
|
||||
|
@ -492,7 +492,7 @@ public:
|
||||
void setupLerp(int32 gametick);
|
||||
|
||||
//! The item has entered the fast area
|
||||
virtual void enterFastArea();
|
||||
virtual uint32 enterFastArea();
|
||||
|
||||
//! The item has left the fast area
|
||||
//! \note This can destroy the object
|
||||
|
Loading…
x
Reference in New Issue
Block a user