[Scummvm-git-logs] scummvm master -> 21059fef5d1e2a91126af45c9ac2f2c90b114080
mduggan
mgithub at guarana.org
Tue Jun 30 04:46:42 UTC 2020
This automated email contains information about 4 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
53ed6e242d ULTIMA8: Fixes for keypad gump
fcfe483914 ULTIMA8: Byte 7 is the item weight in crusader
1c7dc91f12 ULTIMA8: put avatar in stasis while healing
21059fef5d ULTIMA8: Load crusader combat tactics
Commit: 53ed6e242d2672f7f2bd2212349999ccaa2f49bf
https://github.com/scummvm/scummvm/commit/53ed6e242d2672f7f2bd2212349999ccaa2f49bf
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-06-30T13:46:23+09:00
Commit Message:
ULTIMA8: Fixes for keypad gump
Changed paths:
engines/ultima/ultima8/gumps/keypad_gump.cpp
diff --git a/engines/ultima/ultima8/gumps/keypad_gump.cpp b/engines/ultima/ultima8/gumps/keypad_gump.cpp
index 2a716af8b9..b212ce6371 100644
--- a/engines/ultima/ultima8/gumps/keypad_gump.cpp
+++ b/engines/ultima/ultima8/gumps/keypad_gump.cpp
@@ -59,7 +59,7 @@ void KeypadGump::InitGump(Gump *newparent, bool take_focus) {
UpdateDimsFromShape();
static const int buttonShapeNum = 11;
- static const uint16 xoffs[] = {0x31, 0x49, 0x61};
+ static const uint16 xoffs[] = {0xc, 0x27, 0x42};
static const uint16 yoffs[] = {0x19, 0x32, 0x4a, 0x62};
for (int y = 0; y < 4; y++) {
@@ -97,7 +97,7 @@ void KeypadGump::ChildNotify(Gump *child, uint32 message) {
//ObjId cid = child->getObjId();
if (message == ButtonWidget::BUTTON_CLICK) {
int buttonNo = child->GetIndex();
- if (buttonNo < 10) {
+ if (buttonNo < 9) {
_value *= 10;
_value += buttonNo + 1;
} else if (buttonNo == 10) {
@@ -112,8 +112,10 @@ void KeypadGump::ChildNotify(Gump *child, uint32 message) {
audio->playSFX(0x32, 0x10, _objId, 1);
Close();
} else {
+ // wrong.
if (audio)
audio->playSFX(0x31, 0x10, _objId, 1);
+ _value = 0;
}
}
}
@@ -133,6 +135,7 @@ uint32 KeypadGump::I_showKeypad(const uint8 *args, unsigned int /*argsize*/) {
ModalGump *gump = new KeypadGump(target);
gump->InitGump(0);
gump->setRelativePosition(CENTER);
+ gump->CreateNotifier();
return gump->GetNotifyProcess()->getPid();
}
Commit: fcfe483914fdb444dd189166133710810d315aac
https://github.com/scummvm/scummvm/commit/fcfe483914fdb444dd189166133710810d315aac
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-06-30T13:46:23+09:00
Commit Message:
ULTIMA8: Byte 7 is the item weight in crusader
Changed paths:
engines/ultima/ultima8/graphics/type_flags.cpp
diff --git a/engines/ultima/ultima8/graphics/type_flags.cpp b/engines/ultima/ultima8/graphics/type_flags.cpp
index c763d838d7..871a0df873 100644
--- a/engines/ultima/ultima8/graphics/type_flags.cpp
+++ b/engines/ultima/ultima8/graphics/type_flags.cpp
@@ -136,7 +136,10 @@ void TypeFlags::load(Common::SeekableReadStream *rs) {
si._y = (data[3] >> 2) & 0x1F;
si._z = ((data[4] << 1) | (data[3] >> 7)) & 0x1F;
- si._unknown = ((data[4] & 0xF0) << 24) | (data[5] << 16) | (data[7] << 8) | data[8];
+ si._unknown = ((data[4] & 0xF0) << 16) | (data[5] << 8) | data[8];
+
+ // This seems to be how it's used..
+ si._weight = data[7];
if (data[6] & 0x01) si._flags |= ShapeInfo::SI_EDITOR;
if (data[6] & 0x02) si._flags |= ShapeInfo::SI_CRUSUNK61;
Commit: 1c7dc91f12b89866b8177d376b26224d2ab1e3dd
https://github.com/scummvm/scummvm/commit/1c7dc91f12b89866b8177d376b26224d2ab1e3dd
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-06-30T13:46:23+09:00
Commit Message:
ULTIMA8: put avatar in stasis while healing
Changed paths:
engines/ultima/ultima8/world/actors/cru_healer_process.cpp
diff --git a/engines/ultima/ultima8/world/actors/cru_healer_process.cpp b/engines/ultima/ultima8/world/actors/cru_healer_process.cpp
index 8937b3d7cd..0649779990 100644
--- a/engines/ultima/ultima8/world/actors/cru_healer_process.cpp
+++ b/engines/ultima/ultima8/world/actors/cru_healer_process.cpp
@@ -25,6 +25,7 @@
#include "ultima/ultima8/world/actors/main_actor.h"
#include "ultima/ultima8/kernel/kernel.h"
#include "ultima/ultima8/world/get_object.h"
+#include "ultima/ultima8/ultima8.h"
#include "ultima/ultima8/audio/audio_process.h"
#include "common/util.h"
@@ -49,6 +50,7 @@ CruHealerProcess::CruHealerProcess() : Process() {
audio->playSFX(0xdb, 0x80, _itemNum, 1, false);
}
}
+ Ultima8Engine::get_instance()->setAvatarInStasis(true);
_type = 0x254; // CONSTANT!
}
@@ -58,6 +60,9 @@ void CruHealerProcess::run() {
AudioProcess *audio = AudioProcess::get_instance();
if (!avatar || avatar->isDead() || avatar->getHP() >= _targetMaxHP) {
+ if (avatar->getHP() >= _targetMaxHP) {
+ Ultima8Engine::get_instance()->setAvatarInStasis(false);
+ }
// dead or finished healing
if (audio)
audio->stopSFX(0xdb, _itemNum);
Commit: 21059fef5d1e2a91126af45c9ac2f2c90b114080
https://github.com/scummvm/scummvm/commit/21059fef5d1e2a91126af45c9ac2f2c90b114080
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-06-30T13:46:23+09:00
Commit Message:
ULTIMA8: Load crusader combat tactics
Changed paths:
A engines/ultima/ultima8/world/actors/combat_dat.cpp
A engines/ultima/ultima8/world/actors/combat_dat.h
engines/ultima/module.mk
engines/ultima/ultima8/convert/crusader/convert_usecode_crusader.h
engines/ultima/ultima8/games/game_data.cpp
engines/ultima/ultima8/games/game_data.h
engines/ultima/ultima8/ultima8.cpp
engines/ultima/ultima8/ultima8.h
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/module.mk b/engines/ultima/module.mk
index 88a8abea58..60eb24c8ba 100644
--- a/engines/ultima/module.mk
+++ b/engines/ultima/module.mk
@@ -554,6 +554,7 @@ MODULE_OBJS := \
ultima8/world/actors/battery_charger_process.o \
ultima8/world/actors/clear_feign_death_process.o \
ultima8/world/actors/cru_healer_process.o \
+ ultima8/world/actors/combat_dat.o \
ultima8/world/actors/combat_process.o \
ultima8/world/actors/grant_peace_process.o \
ultima8/world/actors/heal_process.o \
diff --git a/engines/ultima/ultima8/convert/crusader/convert_usecode_crusader.h b/engines/ultima/ultima8/convert/crusader/convert_usecode_crusader.h
index 328fbdcd00..a6494e307c 100644
--- a/engines/ultima/ultima8/convert/crusader/convert_usecode_crusader.h
+++ b/engines/ultima/ultima8/convert/crusader/convert_usecode_crusader.h
@@ -79,7 +79,7 @@ const char* const ConvertUsecodeCrusader::_intrinsics[] = {
"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 Actor::I_GetNPCDataField0x63_00B(Actor *)", // Maybe get HP? Called from ANDROID::calledFromAnim, goes to NPCDEATH
- "void I_NPCsetSomething_00C(int)",
+ "void Ultima8Engine::I_setAvatarInStasis(int)",
"byte Item::I_getDirToItem(Item *, itemno)", // based on disasm
"int16 Actor::I_turnToward(Actor *, direction, unk)", // TODO: work out what unk is
"void I_playFlic(void), int16 I_playFlic(Item *, char *name, int16 sizex, int16 sizey)",
@@ -153,14 +153,14 @@ 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
// 0050
"int16 I_GetNPCDataField0x2_050(Actor *)",
- "void I_NPCSomething_051(Actor *)", // TODO: check usecode to understand this.
+ "void Actor::I_clrInCombat(Actor *)", // probably, based on disasm.
"void Actor::I_setDefaultActivity0(Actor *, int)",
"void Actor::I_setDefaultActivity1(Actor *, int)",
"void Actor::I_setDefaultActivity2(Actor *, int)",
"void Actor::I_setActivity(Actor *, int)", // part of same coff set 055, 07D, 0CD, 0DB, 0F2, 131
"void Intrinsic056(int itemno)", // Maybe set new target? TODO: check usecode to understand this.
- "int16 Item::I_getSOMETHING_57(Item *)",
- "byte Item::Item::I_isCentreOn(Item *, uint16 other)",
+ "int16 Item::I_getSurfaceWeight(Item *)",
+ "byte Item::I_isCentreOn(Item *, uint16 other)",
"void Item::I_setFrame(Item *, frame)", // based on same coff as 002
"int16 Actor::I_getLastAnimSet(4 bytes)", // part of same coff set 01D, 05A, 0B9, 0D7, 0E4, 124
"byte Item::I_legalCreateAtPoint(Item *, int16 shape, int16 frame, Point *)", // see PEPSIEW::use
@@ -188,10 +188,10 @@ const char* const ConvertUsecodeCrusader::_intrinsics[] = {
// 0070
"byte Ultima8Engine::I_getUnkCrusaderFlag(void)",
"void Ultima8Engine::I_setUnkCrusaderFlag(void)",
- "void Ultima8Engine::I_setAvatarInStasis(void)",
+ "void Ultima8Engine::I_setCruStasis(void)",
"void Actor::I_setDead(4 bytes)", // part of same coff set 021, 060, 073, 0A0, 0A8, 0D8, 0E7, 135
"void Ultima8Engine::I_clrUnkCrusaderFlag(void)",
- "void Ultima8Engine::I_clrAvatarInStasis(void)",
+ "void Ultima8Engine::I_clrCruStasis(void)",
"void AudioProcess::I_stopSFX(Item *)",
"int16 PaletteFaderProcess::I_fadeToBlack(void)", // fade to black, no args (40 frames)
"void MainActor::I_clrKeycards(void)",
@@ -261,7 +261,7 @@ const char* const ConvertUsecodeCrusader::_intrinsics[] = {
"void Ultima8Engine::I_setAlertActive(void)",
"int16 Item::I_equip(6 bytes)",
"void Ultima8Engine::I_clrAlertActive(void)",
- "int16 I_GetNPCGlobal0x7e24_0B7(void)",
+ "int16 Ultima8Engine::I_getAvatarInStasis(void)",
"byte I_probablyPickUpItem_0B8(4 bytes)", // same coff as 037
"int16 Actor::I_getLastAnimSet(4 bytes)", // part of same coff set 01D, 05A, 0B9, 0D7, 0E4, 124
"void Item::I_setQuality(Item *, int)", // same coff as 07F, 125
@@ -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 I_createMapJumpProcess(int16 mapnum)", // TODO: Implement me
- "byte Actor::I_GetNPCDataField0x59Flag3_0CC(Actor *)",
+ "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..
"void Item::I_setQAndCombine(Item *, int16 q)", // based on disassembly
@@ -302,7 +302,7 @@ const char* const ConvertUsecodeCrusader::_intrinsics[] = {
"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 Actor::I_GetNPCDataField0x4_0DD(Actor *)",
- "void Actor::I_SetNPCDataField0x5c_0DE(Actor *, int)",
+ "void Actor::I_setCombatTactic(Actor *, int)",
"int16 Actor::I_getEquip(6 bytes)", // based on disasm
// 00E0
"void Actor::I_setEquip(8 bytes)",
@@ -310,7 +310,7 @@ const char* const ConvertUsecodeCrusader::_intrinsics[] = {
"int16 Actor::I_getDefaultActivity1(Actor *)",
"int16 Actor::I_getDefaultActivity2(Actor *)",
"int16 Actor::I_getLastAnimSet(4 bytes)", // part of same coff set 01D, 05A, 0B9, 0D7, 0E4, 124
- "void Actor::I_attackProbably(Actor *, uint16 target)", // TODO: game checks 0x59 flag 3 first.. what is that?
+ "void Actor::I_attack(Actor *, uint16 target)",
"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)",
diff --git a/engines/ultima/ultima8/games/game_data.cpp b/engines/ultima/ultima8/games/game_data.cpp
index 0ff5a83e6a..2e7cdbfc9f 100644
--- a/engines/ultima/ultima8/games/game_data.cpp
+++ b/engines/ultima/ultima8/games/game_data.cpp
@@ -32,6 +32,7 @@
#include "ultima/ultima8/graphics/gump_shape_archive.h"
#include "ultima/ultima8/world/map_glob.h"
#include "ultima/ultima8/world/actors/npc_dat.h"
+#include "ultima/ultima8/world/actors/combat_dat.h"
#include "ultima/ultima8/graphics/palette_manager.h"
#include "ultima/ultima8/graphics/shape.h"
#include "ultima/ultima8/graphics/wpn_ovlay_dat.h"
@@ -495,6 +496,13 @@ const NPCDat *GameData::getNPCDataForShape(uint16 shapeno) const {
return nullptr;
}
+const CombatDat *GameData::getCombatDat(uint16 entry) const {
+ if (entry < _combatData.size()) {
+ return _combatData[entry];
+ }
+ return nullptr;
+}
+
void GameData::loadRemorseData() {
FileSystem *filesystem = FileSystem::get_instance();
@@ -638,7 +646,16 @@ void GameData::loadRemorseData() {
error("Unable to load static/combat.dat");
RawArchive *combatflex = new RawArchive(combatds);
+ _combatData.clear();
+ _combatData.resize(combatflex->getCount());
+ for (uint32 i = 0; i < combatflex->getCount(); i++) {
+ Common::SeekableReadStream *combatflexrs = combatflex->get_datasource(i);
+ if (combatflexrs && combatflexrs->size() > 20) {
+ _combatData[i] = new CombatDat(*combatflexrs);
+ }
+ delete combatflexrs;
+ }
// TODO: What's in this flex file? Descriptions of combat tactics?
// 14 objects with contents:
// [ 16 Byte Name ]
diff --git a/engines/ultima/ultima8/games/game_data.h b/engines/ultima/ultima8/games/game_data.h
index 052170f6e5..3a8d11d514 100644
--- a/engines/ultima/ultima8/games/game_data.h
+++ b/engines/ultima/ultima8/games/game_data.h
@@ -40,6 +40,7 @@ class Shape;
class MusicFlex;
class WpnOvlayDat;
class NPCDat;
+class CombatDat;
class ShapeFrame;
class SoundFlex;
class SpeechFlex;
@@ -95,6 +96,8 @@ public:
const NPCDat *getNPCData(uint16 entry) const;
const NPCDat *getNPCDataForShape(uint16 shapeno) const;
+ const CombatDat *getCombatDat(uint16 entry) const;
+
Std::string translate(const Std::string &text);
FrameID translate(FrameID frame);
@@ -118,6 +121,7 @@ private:
MusicFlex *_music;
WpnOvlayDat *_weaponOverlay;
Std::vector<NPCDat *> _npcTable;
+ Std::vector<CombatDat *> _combatData;
SoundFlex *_soundFlex;
Std::vector<SpeechFlex **> _speech;
diff --git a/engines/ultima/ultima8/ultima8.cpp b/engines/ultima/ultima8/ultima8.cpp
index 059ed77cc9..7337b61e45 100644
--- a/engines/ultima/ultima8/ultima8.cpp
+++ b/engines/ultima/ultima8/ultima8.cpp
@@ -1385,18 +1385,8 @@ uint32 Ultima8Engine::I_getCurrentTimerTick(const uint8 * /*args*/,
}
uint32 Ultima8Engine::I_setAvatarInStasis(const uint8 *args, unsigned int argsize) {
- if (argsize) {
- ARG_SINT16(stasis);
- get_instance()->setAvatarInStasis(stasis != 0);
- } else {
- // TODO: this is for crusader - does it have the same meaning?
- get_instance()->setAvatarInStasis(true);
- }
- return 0;
-}
-
-uint32 Ultima8Engine::I_clrAvatarInStasis(const uint8 *args, unsigned int argsize) {
- get_instance()->setAvatarInStasis(false);
+ ARG_SINT16(stasis);
+ get_instance()->setAvatarInStasis(stasis != 0);
return 0;
}
@@ -1407,6 +1397,17 @@ uint32 Ultima8Engine::I_getAvatarInStasis(const uint8 * /*args*/, unsigned int /
return 0;
}
+uint32 Ultima8Engine::I_setCruStasis(const uint8 *args, unsigned int argsize) {
+ // This is like avatar stasis, but stops a lot of other keyboard inputs too.
+ warning("I_setCruStasis: TODO: implement me");
+ return 0;
+}
+
+uint32 Ultima8Engine::I_clrCruStasis(const uint8 *args, unsigned int argsize) {
+ warning("I_clrCruStasis: TODO: implement me");
+ return 0;
+}
+
uint32 Ultima8Engine::I_getTimeInGameHours(const uint8 * /*args*/,
unsigned int /*argsize*/) {
// 900 seconds per _game hour
diff --git a/engines/ultima/ultima8/ultima8.h b/engines/ultima/ultima8/ultima8.h
index 5f0b6008c8..21c2e1a5df 100644
--- a/engines/ultima/ultima8/ultima8.h
+++ b/engines/ultima/ultima8/ultima8.h
@@ -213,7 +213,6 @@ public:
INTRINSIC(I_getCurrentTimerTick);
INTRINSIC(I_setAvatarInStasis);
- INTRINSIC(I_clrAvatarInStasis);
INTRINSIC(I_getAvatarInStasis);
INTRINSIC(I_getTimeInGameHours);
INTRINSIC(I_getTimeInMinutes);
@@ -225,6 +224,8 @@ public:
INTRINSIC(I_clrUnkCrusaderFlag);
INTRINSIC(I_makeAvatarACheater);
INTRINSIC(I_closeItemGumps);
+ INTRINSIC(I_setCruStasis);
+ INTRINSIC(I_clrCruStasis);
void setAvatarInStasis(bool stat) {
_avatarInStasis = stat;
diff --git a/engines/ultima/ultima8/usecode/remorse_intrinsics.h b/engines/ultima/ultima8/usecode/remorse_intrinsics.h
index f2c086b42e..40f493d535 100644
--- a/engines/ultima/ultima8/usecode/remorse_intrinsics.h
+++ b/engines/ultima/ultima8/usecode/remorse_intrinsics.h
@@ -47,10 +47,10 @@ Intrinsic RemorseIntrinsics[] = {
Item::I_getZ, // byte Intrinsic009(Item *)
Item::I_destroy, // void Intrinsic00A(Item *)
0, // get something npcdata, maybe HP void Intrinsic00B(4 bytes)
- 0, // void Intrinsic00C(2 bytes)
+ Ultima8Engine::I_setAvatarInStasis, // void Intrinsic00C(2 bytes)
Item::I_getDirToItem, // byte Intrinsic00D(6 bytes)
- 0, // int Intrinsic00E(8 bytes)
- 0, // TODO: I_playVideo(item, vidname, int16 sizex, int16 sizey)
+ 0, // TODO: Actor::I_turnToward(Actor *, direction, unk)
+ 0, // TODO: VideoGump::I_playVideo(item, vidname, int16 sizex, int16 sizey)
// 0x010
Item::I_getQLo, // Based on having same coff as 02B
Actor::I_getMap, // int Intrinsic011(4 bytes)
@@ -121,13 +121,13 @@ Intrinsic RemorseIntrinsics[] = {
Item::I_getQHi, // based on same coff set as 026
// 0x050
0, // void Intrinsic050(4 bytes)
- 0, // void Intrinsic051(4 bytes)
+ Actor::I_clrInCombat, // void Intrinsic051(4 bytes)
Actor::I_setDefaultActivity0, // void Intrinsic052(6 bytes)
Actor::I_setDefaultActivity1, // void Intrinsic053(6 bytes)
Actor::I_setDefaultActivity2, // void Intrinsic054(6 bytes)
Actor::I_setActivity, // void Intrinsic055(6 bytes)
0, // void Intrinsic056(2 bytes)
- 0, // void Intrinsic057(4 bytes)
+ Item::I_getSurfaceWeight, // void Intrinsic057(4 bytes)
Item::I_isCentreOn, // int Intrinsic058(6 bytes)
Item::I_setFrame, // based on same coff as 002
Actor::I_getLastAnimSet, // void Intrinsic05A(4 bytes)
@@ -156,10 +156,10 @@ Intrinsic RemorseIntrinsics[] = {
// 0x070
Ultima8Engine::I_getUnkCrusaderFlag, // int Intrinsic070(void)
Ultima8Engine::I_setUnkCrusaderFlag, // void Intrinsic071(void)
- Ultima8Engine::I_setAvatarInStasis,
+ Ultima8Engine::I_setCruStasis,
Actor::I_setDead,
Ultima8Engine::I_clrUnkCrusaderFlag, // void Intrinsic074(void)
- Ultima8Engine::I_clrAvatarInStasis,
+ Ultima8Engine::I_clrCruStasis,
AudioProcess::I_stopSFXCru, // takes Item *, from disasm
PaletteFaderProcess::I_fadeToBlack, // void Intrinsic077(void)
MainActor::I_clrKeycards, // void Intrinsic078(void)
@@ -229,7 +229,7 @@ Intrinsic RemorseIntrinsics[] = {
World::I_setAlertActive, // void Intrinsic0B4(void)
Item::I_equip, // void Intrinsic0B5(6 bytes)
World::I_clrAlertActive, // void Intrinsic0B6(void)
- 0, // void Intrinsic0B7(void)
+ Ultima8Engine::I_getAvatarInStasis, // void Intrinsic0B7(void)
0, // int Intrinsic0B8(4 bytes)
Actor::I_getLastAnimSet, // void Intrinsic0B9(4 bytes)
Item::I_setQuality,
@@ -251,7 +251,7 @@ Intrinsic RemorseIntrinsics[] = {
Item::I_getQHi, // based on same coff set as 026
Actor::I_setHp, // int Intrinsic0CA(6 bytes)
0, // 0CB void I_createMapJumpProcess(int16 mapnum)", // TODO: Implement me
- 0, // int Intrinsic0CC(4 bytes)
+ 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.
Item::I_setQAndCombine, // void Intrinsic0CF(6 bytes)
@@ -270,7 +270,7 @@ Intrinsic RemorseIntrinsics[] = {
Actor::I_setActivity, // void Intrinsic0DB(6 bytes)
Item::I_isOn,
0, // void Intrinsic0DD(4 bytes)
- 0, // void Intrinsic0DE(6 bytes)
+ Actor::I_setCombatTactic, // void Intrinsic0DE(6 bytes)
Actor::I_getEquip, // void Intrinsic0DF(6 bytes)
// 0x0E0
Actor::I_setEquip, // void Intrinsic0E0(8 bytes)
@@ -278,7 +278,7 @@ Intrinsic RemorseIntrinsics[] = {
Actor::I_getDefaultActivity1, // void Intrinsic0E2(4 bytes)
Actor::I_getDefaultActivity2, // void Intrinsic0E3(4 bytes)
Actor::I_getLastAnimSet, // void Intrinsic0E4(4 bytes)
- 0, // void Intrinsic0E5(6 bytes)
+ 0, // TODO: Actor::I_attack(Actor *, uint16 target) (implement me)
0, // void Intrinsic0E6(6 bytes)
Actor::I_setDead,
Item::I_cast, // void Intrinsic0E8(6 bytes)
diff --git a/engines/ultima/ultima8/world/actors/actor.cpp b/engines/ultima/ultima8/world/actors/actor.cpp
index 88ae4ae711..68ddaa06ec 100644
--- a/engines/ultima/ultima8/world/actors/actor.cpp
+++ b/engines/ultima/ultima8/world/actors/actor.cpp
@@ -67,7 +67,7 @@ DEFINE_RUNTIME_CLASSTYPE_CODE(Actor)
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), _unk0C(0), _actorFlags(0) {
+ _fallStart(0), _unk0C(0), _actorFlags(0), _combatTactic(0) {
_defaultActivity[0] = 0;
_defaultActivity[1] = 0;
_defaultActivity[2] = 0;
@@ -1207,6 +1207,13 @@ void Actor::saveData(Common::WriteStream *ws) {
ws->writeUint32LE(_fallStart);
ws->writeUint32LE(_actorFlags);
ws->writeByte(_unk0C);
+
+ if (GAME_IS_CRUSADER) {
+ ws->writeUint16LE(_defaultActivity[0]);
+ ws->writeUint16LE(_defaultActivity[1]);
+ ws->writeUint16LE(_defaultActivity[2]);
+ ws->writeUint16LE(_combatTactic);
+ }
}
bool Actor::loadData(Common::ReadStream *rs, uint32 version) {
@@ -1226,6 +1233,13 @@ bool Actor::loadData(Common::ReadStream *rs, uint32 version) {
_actorFlags = rs->readUint32LE();
_unk0C = rs->readByte();
+ if (GAME_IS_CRUSADER) {
+ _defaultActivity[0] = rs->readUint16LE();
+ _defaultActivity[1] = rs->readUint16LE();
+ _defaultActivity[2] = rs->readUint16LE();
+ _combatTactic = rs->readUint16LE();
+ }
+
return true;
}
@@ -1881,6 +1895,16 @@ uint32 Actor::I_getDefaultActivity2(const uint8 *args, unsigned int /*argsize*/)
return actor->getDefaultActivity(2);
}
+uint32 Actor::I_setCombatTactic(const uint8 *args, unsigned int /*argsize*/) {
+ ARG_ACTOR_FROM_PTR(actor);
+ if (!actor) return 0;
+ ARG_UINT16(tactic);
+
+ actor->setCombatTactic(tactic);
+ return 0;
+}
+
+
} // 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 f8a54d6cb5..9f196545fc 100644
--- a/engines/ultima/ultima8/world/actors/actor.h
+++ b/engines/ultima/ultima8/world/actors/actor.h
@@ -136,6 +136,10 @@ public:
_actorFlags &= ~mask;
}
+ void setCombatTactic(int no) {
+ _combatTactic = no;
+ }
+
//! set stats from MonsterInfo (hp, dex, alignment, enemyAlignment)
//! in Crusader this comes from the NPC Data
//! \return true if info was found, false otherwise
@@ -289,6 +293,7 @@ public:
INTRINSIC(I_getDefaultActivity0);
INTRINSIC(I_getDefaultActivity1);
INTRINSIC(I_getDefaultActivity2);
+ INTRINSIC(I_setCombatTactic);
enum ActorFlags {
ACT_INVINCIBLE = 0x000001, // flags from npcdata byte 0x1B
@@ -326,6 +331,9 @@ protected:
int32 _fallStart;
uint8 _unk0C; // unknown byte 0x0C from npcdata.dat
+ //! tactic being used in combat (for Crusader), the entry in the combat.dat flex.
+ uint16 _combatTactic;
+
uint32 _actorFlags;
//! the 3 default NPC activities from Crusader
diff --git a/engines/ultima/ultima8/world/actors/combat_dat.cpp b/engines/ultima/ultima8/world/actors/combat_dat.cpp
new file mode 100644
index 0000000000..6561892de2
--- /dev/null
+++ b/engines/ultima/ultima8/world/actors/combat_dat.cpp
@@ -0,0 +1,55 @@
+/* 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/actors/combat_dat.h"
+
+namespace Ultima {
+namespace Ultima8 {
+
+CombatDat::CombatDat(Common::SeekableReadStream &rs) {
+ char namebuf[17] = {0};
+ rs.read(namebuf, 16);
+ _name.assign(namebuf);
+
+ uint16 offset1 = rs.readUint16LE();
+ uint16 offset2 = rs.readUint16LE();
+
+ int data1size = offset2 - offset1;
+ int data2size = rs.size() - offset2;
+ _sequence1 = new uint8[data1size];
+ _sequence2 = new uint8[data2size];
+
+ rs.seek(offset1);
+ _sequence1len = rs.read(_sequence1, data1size);
+
+ rs.seek(offset2);
+ _sequence2len = rs.read(_sequence2, data2size);
+}
+
+CombatDat::~CombatDat() {
+ delete [] _sequence1;
+ delete [] _sequence2;
+}
+
+} // End of namespace Ultima8
+} // End of namespace Ultima
diff --git a/engines/ultima/ultima8/world/actors/combat_dat.h b/engines/ultima/ultima8/world/actors/combat_dat.h
new file mode 100644
index 0000000000..0636202e43
--- /dev/null
+++ b/engines/ultima/ultima8/world/actors/combat_dat.h
@@ -0,0 +1,80 @@
+/* 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_ACTORS_COMBAT_DAT_H
+#define WORLD_ACTORS_COMBAT_DAT_H
+
+#include "common/stream.h"
+
+#include "ultima/shared/std/string.h"
+
+namespace Ultima {
+namespace Ultima8 {
+
+/**
+ * A single entry in the Crusader combat.dat flex. The files consist of 3 parts:
+ * 1. human-readable name (zero-padded 16 bytes)
+ * 2. offset table (10x2-byte offsets, in practice only the first 2 offsets are ever used)
+ * 3. tactic blocks starting at the offsets given in the offset (in practice only 2 blocks are used)
+ *
+ * The tactic blocks are a sequence of opcodes of things the NPC should
+ * do - eg, turn towards direction X.
+ */
+class CombatDat {
+public:
+ CombatDat(Common::SeekableReadStream &rs);
+
+ ~CombatDat();
+
+ const Std::string &getName() const {
+ return _name;
+ };
+
+ const uint8 *getSequence1() const {
+ return _sequence1;
+ }
+
+ const uint8 *getSequence2() const {
+ return _sequence2;
+ }
+
+ uint16 getSequence1Len() const {
+ return _sequence1len;
+ }
+
+ uint16 getSequence2Len() const {
+ return _sequence2len;
+ }
+
+private:
+ Std::string _name;
+
+ uint16 _sequence1len;
+ uint16 _sequence2len;
+ uint8 *_sequence1;
+ uint8 *_sequence2;
+};
+
+} // End of namespace Ultima8
+} // End of namespace Ultima
+
+#endif
More information about the Scummvm-git-logs
mailing list