[Scummvm-git-logs] scummvm master -> f13ebb9759416522b20daa7fa22b4e349e5624e8
mduggan
mgithub at guarana.org
Fri Jun 19 02:36:53 UTC 2020
This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
259e4d6589 ULTIMA8: More Crusader intrinsic support
f13ebb9759 ULTIMA8: Add support for Crusader enable/disable alert intrinsics
Commit: 259e4d6589256cef5935b74346e88256eeeb6f6c
https://github.com/scummvm/scummvm/commit/259e4d6589256cef5935b74346e88256eeeb6f6c
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-06-19T11:35:43+09:00
Commit Message:
ULTIMA8: More Crusader intrinsic support
Changed paths:
engines/ultima/ultima8/convert/crusader/convert_usecode_crusader.h
engines/ultima/ultima8/usecode/remorse_intrinsics.h
engines/ultima/ultima8/world/actors/actor.cpp
engines/ultima/ultima8/world/camera_process.cpp
engines/ultima/ultima8/world/current_map.cpp
engines/ultima/ultima8/world/item.cpp
engines/ultima/ultima8/world/item.h
engines/ultima/ultima8/world/sprite_process.cpp
diff --git a/engines/ultima/ultima8/convert/crusader/convert_usecode_crusader.h b/engines/ultima/ultima8/convert/crusader/convert_usecode_crusader.h
index dcb495cd2c..cce60431ee 100644
--- a/engines/ultima/ultima8/convert/crusader/convert_usecode_crusader.h
+++ b/engines/ultima/ultima8/convert/crusader/convert_usecode_crusader.h
@@ -78,10 +78,10 @@ const char* const ConvertUsecodeCrusader::_intrinsics[] = {
"byte Actor::I_isNPC(Item *)", // proably - actually checks is itemno < 256?
"byte Item::I_getZ(Item *)",
"void Item::I_destroy(Item *)", // probably? often called after creating a replacement object and setting it to the same position (eg, LUGGAGE::gotHit)
- "int16 I_GetNPCDataField0x63_00B(Actor *)", // could be getNPCNum? Called from ANDROID::calledFromAnim, goes to NPCDEATH
+ "int16 Actor::I_GetNPCDataField0x63_00B(Actor *)", // could be getNPCNum? Called from ANDROID::calledFromAnim, goes to NPCDEATH
"void I_NPCsetSomething_00C(int)",
"byte Item::I_getDirToItem(Item *, itemno)", // based on disasm
- "int16 I_NPCSomething00E(Actor *, int, int)",
+ "int16 Actor::I_NPCSomething00E(Actor *, int, int)",
"void I_playFlic(void), int16 I_playFlic(Item *, char *name, int16 sizex, int16 sizey)",
// 0010
"int16 Item::I_getQLo(Item *)", // same as 02B based on same coff as 02B, 066, 084, 0A1, 0AE, 0D9, 0EA
@@ -237,7 +237,7 @@ const char* const ConvertUsecodeCrusader::_intrinsics[] = {
"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?
// 00A0
- "void I_SetItemFlag0x8000AndNPCField0x13Flag0_0A0(Actor *)", // part of same coff set 021, 060, 073, 0A0, 0A8, 0D8, 0E7, 135
+ "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
"int16 Item::I_getUnkEggType(Item *)", // based on disassembly, same as U8
"void Egg::I_setEggXRange(Egg *, int)", // based on disasm
@@ -248,7 +248,7 @@ const char* const ConvertUsecodeCrusader::_intrinsics[] = {
"void Actor::I_setDead(Actor *)", // part of same coff set 021, 060, 073, 0A0, 0A8, 0D8, 0E7, 135
"void I_playFlic0A9(char *)", // same coff as 092
"void I_playSFX(2 bytes)", // same coff as 0D4
- "byte I_NPCGetField0x59Flag1_0AB(Actor *)",
+ "byte Actor::I_NPCGetField0x59Flag1_0AB(Actor *)",
"int16 Item::I_getFamilyOfType(Item *)", // per pentagram notes, matches disasm.
"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
"int16 Item::I_getQLo(Item *)", // same as 02B based on same coff set 010, 02B, 066, 084, 0A1, 0AE, 0D9, 0EA
@@ -283,7 +283,7 @@ const char* const ConvertUsecodeCrusader::_intrinsics[] = {
"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 Intrinsic0CB(2 bytes)",
- "byte I_GetNPCDataField0x59Flag3_0CC(Actor *)",
+ "byte Actor::I_GetNPCDataField0x59Flag3_0CC(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..
"void Item::setQAndCallSomething(Item *, int16 q)", // based on disassembly
@@ -301,17 +301,17 @@ const char* const ConvertUsecodeCrusader::_intrinsics[] = {
"void Intrinsic0DA_Fade(void)", // something about fades
"void Actor::I_setActivity(Actor *, int)", // part of same coff set 055, 07D, 0CD, 0DB, 0F2, 131
"byte Item::I_isOn(Item *, itemno)", // part of same coff set 044, 046, 048, 04A, 04C, 04E, 0A5, 0BC, 0C5, 0DC, 0F1, 0FA, 12C
- "int16 I_GetNPCDataField0x4_0DD(Actor *)",
- "void I_SetNPCDataField0x5c_0DE(Actor *, int)",
+ "int16 Actor::I_GetNPCDataField0x4_0DD(Actor *)",
+ "void Actor::I_SetNPCDataField0x5c_0DE(Actor *, int)",
"int16 Actor::I_getEquip(6 bytes)", // based on disasm
// 00E0
"void Actor::I_setEquip(8 bytes)",
- "int16 I_GetNPCDataField0x6_0E1(Actor *)",
- "int16 I_GetNPCDataField0x8_0E2(Actor *)",
- "int16 I_GetNPCDataField0xa_0E3(Actor *)",
+ "int16 Actor::I_GetNPCDataField0x6_0E1(Actor *)",
+ "int16 Actor::I_GetNPCDataField0x8_0E2(Actor *)",
+ "int16 Actor::I_GetNPCDataField0xa_0E3(Actor *)",
"int16 Actor::I_getLastAnimSet(4 bytes)", // part of same coff set 01D, 05A, 0B9, 0D7, 0E4, 124
- "void I_NPCSomething0E5(Actor *, uint16)",
- "void I_SetNPCDataField0x63_0E6(Actor *, int)",
+ "void Actor::I_NPCSomething0E5(Actor *, uint16)",
+ "void Actor::I_SetNPCDataField0x63_0E6(Actor *, int)",
"void Actor::I_setDead(4 bytes)", // part of same coff set 021, 060, 073, 0A0, 0A8, 0D8, 0E7, 135
"int16 Item::I_cast(6 bytes)",
"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
diff --git a/engines/ultima/ultima8/usecode/remorse_intrinsics.h b/engines/ultima/ultima8/usecode/remorse_intrinsics.h
index f43b27379c..6c50688085 100644
--- a/engines/ultima/ultima8/usecode/remorse_intrinsics.h
+++ b/engines/ultima/ultima8/usecode/remorse_intrinsics.h
@@ -142,7 +142,7 @@ Intrinsic RemorseIntrinsics[] = {
0, // void Intrinsic062(void)
Actor::I_teleport, // void Intrinsic063(12 bytes)
Item::I_getFootpadData, // void Intrinsic064(16 bytes)
- 0, // TODO: Item::I_isInNPC
+ Item::I_isInNpc,
Item::I_getQLo, // based on same coff set as 02B
Item::I_getNpcNum, // based on same coff as 102 (-> variable name in TRIGGER::ordinal21)
Item::I_setNpcNum, // void Item::I_setSomething068(Item *, int16 something) , see VALUEBOX:ordinal20
@@ -152,7 +152,7 @@ Intrinsic RemorseIntrinsics[] = {
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)
- 0, // TODO: Item::I_isCompletelyOn int Intrinsic06F(6 bytes)
+ Item::I_isCompletelyOn,
// 0x070
Ultima8Engine::I_getUnkCrusaderFlag, // int Intrinsic070(void)
Ultima8Engine::I_setUnkCrusaderFlag, // void Intrinsic071(void)
diff --git a/engines/ultima/ultima8/world/actors/actor.cpp b/engines/ultima/ultima8/world/actors/actor.cpp
index 7067f382a8..d578e4ce7d 100644
--- a/engines/ultima/ultima8/world/actors/actor.cpp
+++ b/engines/ultima/ultima8/world/actors/actor.cpp
@@ -1589,6 +1589,11 @@ uint32 Actor::I_pathfindToPoint(const uint8 *args, unsigned int /*argsize*/) {
ARG_NULL16(); // unknown. Only one instance of this in U8, value is 5.
if (!actor) return 0;
+ if (GAME_IS_CRUSADER) {
+ x *= 2;
+ y *= 2;
+ }
+
return Kernel::get_instance()->addProcess(
new PathfinderProcess(actor, x, y, z));
}
diff --git a/engines/ultima/ultima8/world/camera_process.cpp b/engines/ultima/ultima8/world/camera_process.cpp
index 2deb55dc24..c24f7a7db0 100644
--- a/engines/ultima/ultima8/world/camera_process.cpp
+++ b/engines/ultima/ultima8/world/camera_process.cpp
@@ -320,6 +320,11 @@ uint32 CameraProcess::I_moveTo(const uint8 *args, unsigned int argsize) {
if (argsize > 6) {
ARG_SINT16(unk);
}
+
+ if (GAME_IS_CRUSADER) {
+ x *= 2;
+ y *= 2;
+ }
CameraProcess::SetCameraProcess(new CameraProcess(x, y, z));
return 0;
}
@@ -337,6 +342,12 @@ uint32 CameraProcess::I_scrollTo(const uint8 *args, unsigned int /*argsize*/) {
ARG_UINT16(y);
ARG_UINT8(z);
ARG_SINT16(unk);
+
+ if (GAME_IS_CRUSADER) {
+ x *= 2;
+ y *= 2;
+ }
+
return CameraProcess::SetCameraProcess(new CameraProcess(x, y, z, 25));
}
diff --git a/engines/ultima/ultima8/world/current_map.cpp b/engines/ultima/ultima8/world/current_map.cpp
index 3a7658b7d8..6a992f9e7e 100644
--- a/engines/ultima/ultima8/world/current_map.cpp
+++ b/engines/ultima/ultima8/world/current_map.cpp
@@ -1207,6 +1207,11 @@ uint32 CurrentMap::I_canExistAt(const uint8 *args, unsigned int /*argsize*/) {
ARG_UINT16(unk2); // looks like it could be an objid
ARG_UINT16(unk3); // always zero
+ if (GAME_IS_CRUSADER) {
+ x *= 2;
+ y *= 2;
+ }
+
const CurrentMap *cm = World::get_instance()->getCurrentMap();
bool valid = cm->isValidPosition(x, y, z, shape, 0, 0, 0);
diff --git a/engines/ultima/ultima8/world/item.cpp b/engines/ultima/ultima8/world/item.cpp
index 1cbe2e7266..1c71243410 100644
--- a/engines/ultima/ultima8/world/item.cpp
+++ b/engines/ultima/ultima8/world/item.cpp
@@ -116,7 +116,7 @@ void Item::dumpInfo() const {
}
Container *Item::getParentAsContainer() const {
- // No _parent, no container
+ // No parent, no container
if (!_parent)
return nullptr;
@@ -529,6 +529,7 @@ 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
int32 x1a, y1a, z1a, x1b, y1b;
int32 x2a, y2a, z2a, x2b, y2b, z2b;
@@ -2475,6 +2476,11 @@ uint32 Item::I_legalCreateAtCoords(const uint8 *args, unsigned int /*argsize*/)
ARG_UINT16(y);
ARG_UINT16(z);
+ if (GAME_IS_CRUSADER) {
+ x *= 2;
+ y *= 2;
+ }
+
// check if item can exist
CurrentMap *cm = World::get_instance()->getCurrentMap();
bool valid = cm->isValidPosition(x, y, z, shape, 0, 0, 0);
@@ -2613,6 +2619,18 @@ uint32 Item::I_isOn(const uint8 *args, unsigned int /*argsize*/) {
return 0;
}
+uint32 Item::I_isCompletelyOn(const uint8 *args, unsigned int /*argsize*/) {
+ ARG_ITEM_FROM_PTR(item);
+ ARG_ITEM_FROM_ID(item2);
+ if (!item) return 0;
+ if (!item2) return 0;
+
+ if (item->isCompletelyOn(*item2))
+ return 1;
+ else
+ return 0;
+}
+
uint32 Item::I_isCentreOn(const uint8 *args, unsigned int /*argsize*/) {
ARG_ITEM_FROM_PTR(item);
ARG_ITEM_FROM_ID(item2);
@@ -2625,6 +2643,21 @@ uint32 Item::I_isCentreOn(const uint8 *args, unsigned int /*argsize*/) {
return 0;
}
+uint32 Item::I_isInNpc(const uint8 *args, unsigned int /*argsize*/) {
+ ARG_ITEM_FROM_PTR(item);
+ if (!item)
+ return 0;
+
+ const Container *container = item->getParentAsContainer();
+ while (container) {
+ const Actor *actor = dynamic_cast<const Actor *>(container);
+ if (actor)
+ return 1;
+ container = container->getParentAsContainer();
+ }
+ return 0;
+}
+
uint32 Item::I_getFamilyOfType(const uint8 *args, unsigned int /*argsize*/) {
ARG_UINT16(shape);
@@ -2641,7 +2674,6 @@ uint32 Item::I_push(const uint8 *args, unsigned int /*argsize*/) {
perr << "Pushing item to ethereal void: " << item->getShape() << "," << item->getFrame() << Std::endl;
#endif
-
item->moveToEtherealVoid();
return 0;
@@ -3112,6 +3144,8 @@ uint32 Item::I_guardianBark(const uint8 *args, unsigned int /*argsize*/) {
ARG_UINT16(num);
if (!item) return 0;
+ assert(GAME_IS_U8);
+
return item->callUsecodeEvent_guardianBark(num);
}
@@ -3176,6 +3210,8 @@ uint32 Item::I_igniteChaos(const uint8 *args, unsigned int /*argsize*/) {
ARG_UINT16(y);
ARG_NULL8();
+ assert(GAME_IS_U8);
+
UCList itemlist(2);
LOOPSCRIPT(script, LS_SHAPE_EQUAL(592)); // all oilflasks (CONSTANT!)
CurrentMap *currentmap = World::get_instance()->getCurrentMap();
diff --git a/engines/ultima/ultima8/world/item.h b/engines/ultima/ultima8/world/item.h
index 033755e907..10186809cf 100644
--- a/engines/ultima/ultima8/world/item.h
+++ b/engines/ultima/ultima8/world/item.h
@@ -499,6 +499,7 @@ public:
INTRINSIC(I_isOn);
INTRINSIC(I_isCompletelyOn);
INTRINSIC(I_isCentreOn);
+ INTRINSIC(I_isInNpc);
INTRINSIC(I_ascend);
INTRINSIC(I_getWeight);
INTRINSIC(I_getWeightIncludingContents);
diff --git a/engines/ultima/ultima8/world/sprite_process.cpp b/engines/ultima/ultima8/world/sprite_process.cpp
index 08da385b83..44246700c5 100644
--- a/engines/ultima/ultima8/world/sprite_process.cpp
+++ b/engines/ultima/ultima8/world/sprite_process.cpp
@@ -26,6 +26,7 @@
#include "ultima/ultima8/world/item.h"
#include "ultima/ultima8/world/current_map.h"
#include "ultima/ultima8/kernel/kernel.h"
+#include "ultima/ultima8/kernel/core_app.h"
#include "ultima/ultima8/world/get_object.h"
namespace Ultima {
@@ -106,6 +107,12 @@ uint32 SpriteProcess::I_createSprite(const uint8 *args, unsigned int argsize) {
ARG_UINT16(x);
ARG_UINT16(y);
ARG_UINT8(z);
+
+ if (GAME_IS_CRUSADER) {
+ x *= 2;
+ y *= 2;
+ }
+
Process *p = new SpriteProcess(shape, frame, lastFrame, repeats, delay, x, y, z);
return Kernel::get_instance()->addProcess(p);
}
Commit: f13ebb9759416522b20daa7fa22b4e349e5624e8
https://github.com/scummvm/scummvm/commit/f13ebb9759416522b20daa7fa22b4e349e5624e8
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-06-19T11:35:57+09:00
Commit Message:
ULTIMA8: Add support for Crusader enable/disable alert intrinsics
Changed paths:
engines/ultima/ultima8/convert/crusader/convert_usecode_crusader.h
engines/ultima/ultima8/usecode/remorse_intrinsics.h
engines/ultima/ultima8/world/map.cpp
engines/ultima/ultima8/world/world.cpp
engines/ultima/ultima8/world/world.h
diff --git a/engines/ultima/ultima8/convert/crusader/convert_usecode_crusader.h b/engines/ultima/ultima8/convert/crusader/convert_usecode_crusader.h
index cce60431ee..973a554734 100644
--- a/engines/ultima/ultima8/convert/crusader/convert_usecode_crusader.h
+++ b/engines/ultima/ultima8/convert/crusader/convert_usecode_crusader.h
@@ -258,9 +258,9 @@ const char* const ConvertUsecodeCrusader::_intrinsics[] = {
"int16 Item::I_spawnUsecodeEvent0x13(Item *, 2 bytes)", // based on disasm - what is event 0x13? "avatar stole something" in U8..
"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
"int32 I_getCurrentTimerTick(void)",
- "void Intrinsic0B4(void)", // set or clear alert? (based on coff)
+ "void Ultima8Engine::I_setAlertActive(void)",
"int16 Item::I_equip(6 bytes)",
- "void Intrinsic0B6(void)", // set or clear alert? (based on coff)
+ "void Ultima8Engine::I_clrAlertActive(void)",
"int16 I_GetNPCGlobal0x7e24_0B7(void)",
"byte Intrinsic0B8(4 bytes)", // same coff as 037
"int16 Actor::I_getLastAnimSet(4 bytes)", // part of same coff set 01D, 05A, 0B9, 0D7, 0E4, 124
diff --git a/engines/ultima/ultima8/usecode/remorse_intrinsics.h b/engines/ultima/ultima8/usecode/remorse_intrinsics.h
index 6c50688085..cc040134ae 100644
--- a/engines/ultima/ultima8/usecode/remorse_intrinsics.h
+++ b/engines/ultima/ultima8/usecode/remorse_intrinsics.h
@@ -35,17 +35,17 @@ namespace Ultima8 {
// Most up-to-date version of unknown functions is in convert_usecode_crusader.h
Intrinsic RemorseIntrinsics[] = {
// 0x000
- Ultima8Engine::I_getAlertActive, // basically confirmed.. see eg, ALARM_NS::enterFastArea - set frame for alert siren based on value.
- Item::I_getFrame, // int Intrinsic001(4 bytes)
- Item::I_setFrame, // basically confirmed..
+ World::I_getAlertActive,
+ Item::I_getFrame, // int Intrinsic001(Item *)
+ Item::I_setFrame, //
Item::I_getMapArray, // See TRIGGER::ordinal21 - stored in a variable 'mapNum'
- Item::I_getStatus, // probably - see usage in GATGUNEW::enterFastArea - always followed by an AND against a single bit
- Item::I_orStatus, // probably - see usage in GATGUNEW::enterFastArea
+ Item::I_getStatus,
+ Item::I_orStatus,
Item::I_equip, // void Intrinsic006(6 bytes)
Item::I_isOnScreen, //
- Actor::I_isNPC, // byte Intrinsic008(Item *) // probably.. disasm checks for < 256
- Item::I_getZ, // byte Intrinsic009(4 bytes) // probably, see PEPSIEW::use() variable names
- Item::I_destroy, // void Intrinsic00A(4 bytes) // probably, often called after creating replacement object in same position eg, LUGGAGE::gotHit
+ Actor::I_isNPC, // byte Intrinsic008(Item *)
+ Item::I_getZ, // byte Intrinsic009(Item *)
+ Item::I_destroy, // void Intrinsic00A(Item *)
0, // something with npcdata void Intrinsic00B(4 bytes)
0, // void Intrinsic00C(2 bytes)
Item::I_getDirToItem, // byte Intrinsic00D(6 bytes)
@@ -55,19 +55,19 @@ Intrinsic RemorseIntrinsics[] = {
Item::I_getQLo, // Based on having same coff as 02B
Actor::I_getMap, // int Intrinsic011(4 bytes)
0, // void Intrinsic012(2 bytes)
- Item::I_getX, //int Intrinsic013(4 bytes) // probably - see FREE::ordinal34
- Item::I_getY, //int Intrinsic014(4 bytes) // probably - see FREE::ordinal34
- AudioProcess::I_playSFXCru, // pretty sure, see SWITCH::ordinal21 which plays various sfx related to access status
- Item::I_getShape, // in STEAMBOX::func0A, is compared to 0x511 (the STEAM2 shape number) to determine direction
+ Item::I_getX, //int Intrinsic013(4 bytes)
+ Item::I_getY, //int Intrinsic014(4 bytes)
+ AudioProcess::I_playSFXCru,
+ Item::I_getShape,
Item::I_explode, // void Intrinsic017(8 bytes)
UCMachine::I_rndRange, // int16 Intrinsic018(4 bytes) // probably.. always called with 2 constants, then result compared to some number between
- Item::I_legalCreateAtCoords, // byte Intrinsic019(14 bytes), probably, see usage in DOOR2::ordinal37
+ Item::I_legalCreateAtCoords, // byte Intrinsic019(14 bytes)
Item::I_andStatus, // void Intrinsic01A(6 bytes)
UCMachine::I_true, // FIXME: get the num of some npc - maybe currently controlled NPC? For now default to 1 (avatar).
Actor::I_getDir, // byte Intrinsic01C(4 bytes)
Actor::I_getLastAnimSet, // int Intrinsic01D(4 bytes)
0, // int Intrinsic01E(16 bytes)
- Item::I_create, // probably - used in MISS1EGG creating keycards and NPCDEATH in creating blood spills
+ Item::I_create,
// 0x020
Item::I_popToCoords, // void Intrinsic020(10 bytes)
Actor::I_setDead, // void Intrinsic021(4 bytes)
@@ -75,12 +75,12 @@ Intrinsic RemorseIntrinsics[] = {
Item::I_getEtherealTop, // int Intrinsic023(void)
Item::I_setShape, // Probably, see PEPSIEW::gotHit
Item::I_touch,
- Item::I_getQHi, // int16 Intrinsic026(Item *), // guess, based on variable name in BOUNCBOX::gotHit
+ Item::I_getQHi, // int16 Intrinsic026(Item *)
Item::I_getClosestDirectionInRange, // int Intrinsic027(14 bytes)
Item::I_hurl, // int Intrinsic028(12 bytes)
UCMachine::I_true, // TODO: This is actually game difficulty level. Make an intrinsic for that once it's implemented (for now return 1, easiest difficulty).
AudioProcess::I_playAmbientSFXCru, // Confirmed!
- Item::I_getQLo, // int16 Intrinsic02B(4 bytes), // guess, based on variable name in BOUNCBOX::gotHit
+ Item::I_getQLo, // int16 Intrinsic02B(4 bytes)
Item::I_inFastArea, // byte Intrinsic02C(4 bytes) // based on disassembly - checks for flag 0x2000
Item::I_setQHi,
Item::I_legalMoveToPoint, // byte Intrinsic02E(12 bytes)
@@ -226,9 +226,9 @@ Intrinsic RemorseIntrinsics[] = {
Item::I_avatarStoleSomething, // void Intrinsic0B1(6 bytes)
Item::I_andStatus, // void Intrinsic0B2(6 bytes)
Ultima8Engine::I_getCurrentTimerTick, // int32 Intrinsic0B3(void), probably, see FREE::ordinal32
- 0, // void Intrinsic0B4(void)
+ World::I_setAlertActive, // void Intrinsic0B4(void)
Item::I_equip, // void Intrinsic0B5(6 bytes)
- 0, // void Intrinsic0B6(void)
+ World::I_clrAlertActive, // void Intrinsic0B6(void)
0, // void Intrinsic0B7(void)
0, // int Intrinsic0B8(4 bytes)
Actor::I_getLastAnimSet, // void Intrinsic0B9(4 bytes)
diff --git a/engines/ultima/ultima8/world/map.cpp b/engines/ultima/ultima8/world/map.cpp
index 95573553a4..deeb884224 100644
--- a/engines/ultima/ultima8/world/map.cpp
+++ b/engines/ultima/ultima8/world/map.cpp
@@ -261,7 +261,11 @@ void Map::loadFixedFormatObjects(Std::list<Item *> &itemlist,
ShapeInfo *info = item->getShapeInfo();
assert(info);
if (info->_family > 10) {
- warning("Created fixed item unknown family %d, shape (%d, %d) at (%d, %d, %d)", info->_family, shape, frame, x, y, z);
+ //warning("Created fixed item unknown family %d, shape (%d, %d) at (%d, %d, %d)", info->_family, shape, frame, x, y, z);
+ }
+ if (shape == 0x90D) {
+ warning("Created MISS1EGG item unknown family %d, shape (%d, %d) at (%d, %d, %d) q:%d", info->_family, shape, frame, x, y, z, quality);
+
}
}
item->setLocation(x, y, z);
diff --git a/engines/ultima/ultima8/world/world.cpp b/engines/ultima/ultima8/world/world.cpp
index 365c6a017f..fb658d960b 100644
--- a/engines/ultima/ultima8/world/world.cpp
+++ b/engines/ultima/ultima8/world/world.cpp
@@ -29,6 +29,8 @@
#include "ultima/ultima8/world/item_factory.h"
#include "ultima/ultima8/world/actors/actor.h"
#include "ultima/ultima8/world/actors/main_actor.h"
+#include "ultima/ultima8/world/loop_script.h"
+#include "ultima/ultima8/usecode/uc_list.h"
#include "ultima/ultima8/misc/id_man.h"
#include "ultima/ultima8/games/game_data.h"
#include "ultima/ultima8/kernel/kernel.h"
@@ -48,7 +50,7 @@ namespace Ultima8 {
World *World::_world = nullptr;
-World::World() : _currentMap(nullptr) {
+World::World() : _currentMap(nullptr), _alertActive(false) {
debugN(MM_INFO, "Creating World...\n");
_world = this;
@@ -337,6 +339,10 @@ void World::save(Common::WriteStream *ws) {
ws->writeUint16LE(_currentMap->_eggHatcher);
+ if (GAME_IS_CRUSADER) {
+ ws->writeByte(_alertActive ? 0 : 1);
+ }
+
uint16 es = static_cast<uint16>(_ethereal.size());
ws->writeUint32LE(es);
@@ -362,6 +368,10 @@ bool World::load(Common::ReadStream *rs, uint32 version) {
_currentMap->_eggHatcher = rs->readUint16LE();
+ if (GAME_IS_CRUSADER) {
+ _alertActive = (rs->readByte() != 0);
+ }
+
uint32 etherealcount = rs->readUint32LE();
for (unsigned int i = 0; i < etherealcount; ++i) {
_ethereal.push_front(rs->readUint16LE());
@@ -377,7 +387,6 @@ void World::saveMaps(Common::WriteStream *ws) {
}
}
-
bool World::loadMaps(Common::ReadStream *rs, uint32 version) {
uint32 mapcount = rs->readUint32LE();
@@ -390,5 +399,62 @@ bool World::loadMaps(Common::ReadStream *rs, uint32 version) {
return true;
}
+void World::setAlertActive(bool active)
+{
+ assert(GAME_IS_CRUSADER);
+ _alertActive = active;
+
+ // Replicate the behavior of the original game.
+ LOOPSCRIPT(script,
+ LS_OR(
+ LS_OR(
+ LS_OR(
+ LS_OR(LS_SHAPE_EQUAL(0x49), LS_SHAPE_EQUAL(0x21)),
+ LS_SHAPE_EQUAL(0x174)),
+ LS_SHAPE_EQUAL(0x271)),
+ LS_SHAPE_EQUAL(0x477))
+ );
+
+ UCList itemlist(2);
+ _world->getCurrentMap()->areaSearch(&itemlist, script, sizeof(script),
+ nullptr, 0x7fff, false);
+ for (uint32 i = 0; i < itemlist.getSize(); i++) {
+ uint16 itemid = itemlist.getuint16(i);
+ Item *item = getItem(itemid);
+ int frame = item->getFrame();
+ if (_alertActive) {
+ if (item->getShape() == 0x477 && frame < 2) {
+ item->setFrame(frame + 2);
+ } else if (frame == 0) {
+ item->setFrame(1);
+ }
+ } else {
+ if (item->getShape() == 0x477 && frame > 1) {
+ item->setFrame(frame + 2);
+ } else if (frame == 1) {
+ item->setFrame(0);
+ }
+ }
+ }
+}
+
+uint32 World::I_getAlertActive(const uint8 * /*args*/,
+ unsigned int /*argsize*/) {
+ return get_instance()->_world->isAlertActive() ? 1 : 0;
+}
+
+uint32 World::I_setAlertActive(const uint8 * /*args*/,
+ unsigned int /*argsize*/) {
+ get_instance()->_world->setAlertActive(true);
+ return 0;
+}
+
+uint32 World::I_clrAlertActive(const uint8 * /*args*/,
+ unsigned int /*argsize*/) {
+ get_instance()->_world->setAlertActive(false);
+ return 0;
+}
+
+
} // End of namespace Ultima8
} // End of namespace Ultima
diff --git a/engines/ultima/ultima8/world/world.h b/engines/ultima/ultima8/world/world.h
index 7ee446d2b9..60a2a48ff4 100644
--- a/engines/ultima/ultima8/world/world.h
+++ b/engines/ultima/ultima8/world/world.h
@@ -57,6 +57,7 @@
// game data need this, actually.)
#include "ultima/ultima8/misc/common_types.h"
+#include "ultima/ultima8/usecode/intrinsics.h"
#include "ultima/shared/std/containers.h"
namespace Ultima {
@@ -138,6 +139,16 @@ public:
//! load World data
bool load(Common::ReadStream *rs, uint32 version);
+ bool isAlertActive() {
+ return _alertActive;
+ }
+
+ void setAlertActive(bool active);
+
+ INTRINSIC(I_getAlertActive); // for Crusader
+ INTRINSIC(I_setAlertActive); // for Crusader
+ INTRINSIC(I_clrAlertActive); // for Crusader
+
private:
static World *_world;
@@ -145,6 +156,9 @@ private:
CurrentMap *_currentMap;
Std::list<ObjId> _ethereal;
+
+ bool _alertActive; //!< is intruder alert active (Crusader)
+
};
} // End of namespace Ultima8
More information about the Scummvm-git-logs
mailing list