[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