[Scummvm-git-logs] scummvm master -> f45ee551b8740129e485b81571532f42c9a857c8

mduggan mgithub at guarana.org
Wed Jul 15 08:33:10 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:
3f46b7ed7f ULTIMA8: Small cleanup of crosshair process
36ab8b5587 ULTIMA8: Const correctness for typeflag functions
8ab251a0ec ULTIMA8: Remove duplicate code from target reticle process
f45ee551b8 ULTIMA8: Create process for Crusader item selection


Commit: 3f46b7ed7f4f68257d5c1c5c978812de1a38141a
    https://github.com/scummvm/scummvm/commit/3f46b7ed7f4f68257d5c1c5c978812de1a38141a
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-07-15T14:58:58+09:00

Commit Message:
ULTIMA8: Small cleanup of crosshair process

Changed paths:
    engines/ultima/ultima8/world/crosshair_process.cpp


diff --git a/engines/ultima/ultima8/world/crosshair_process.cpp b/engines/ultima/ultima8/world/crosshair_process.cpp
index 13c6878ce9..e0585c53ad 100644
--- a/engines/ultima/ultima8/world/crosshair_process.cpp
+++ b/engines/ultima/ultima8/world/crosshair_process.cpp
@@ -36,32 +36,33 @@ namespace Ultima8 {
 // p_dynamic_cast stuff
 DEFINE_RUNTIME_CLASSTYPE_CODE(CrosshairProcess)
 
-const uint32 CROSSHAIR_SHAPE = 0x4CC;
-const float CROSSHAIR_DIST = 400.0;
+static const uint32 CROSSHAIR_SHAPE = 0x4CC;
+static const float CROSSHAIR_DIST = 400.0;
 
 CrosshairProcess::CrosshairProcess() : Process() {
 }
 
 void CrosshairProcess::run() {
-	Kernel *kernel = Kernel::get_instance();
-	assert(kernel);
 	MainActor *mainactor = getMainActor();
-	int32 cx, cy, cz, ax, ay, az;
-	mainactor->getCentre(cx, cy, cz);
-	mainactor->getFootpadWorld(ax, ay, az);
-	// TODO: Make a fine adjustment for avatar height (eg, when crouching)
-	// for now just put it at 3/4 avatar height which is about right.
-	cz += az / 4;
-	// TODO: Get the fine angle of the avatar once that is implemented.
-	uint16 dir = (mainactor->getDir() + 2) % 8;
-	// Dir is 0~7, convert to 0~15/8*pi
-	float angle = (3.14 * dir / 4.0);
-	float xoff = CROSSHAIR_DIST * cos(angle);
-	float yoff = CROSSHAIR_DIST * sin(angle);
-	cx -= static_cast<int32>(xoff);
-	cy -= static_cast<int32>(yoff);
-
+	assert(mainactor);
 	if (mainactor->isInCombat()) {
+		Kernel *kernel = Kernel::get_instance();
+		assert(kernel);
+		int32 cx, cy, cz, ax, ay, az;
+		mainactor->getCentre(cx, cy, cz);
+		mainactor->getFootpadWorld(ax, ay, az);
+		// TODO: Make a fine adjustment for avatar height (eg, when crouching)
+		// for now just put it at 3/4 avatar height which is about right.
+		cz += az / 4;
+		// TODO: Get the fine angle of the avatar once that is implemented.
+		uint16 dir = (mainactor->getDir() + 2) % 8;
+		// Dir is 0~7, convert to 0~15/8*pi
+		float angle = (3.14 * dir / 4.0);
+		float xoff = CROSSHAIR_DIST * cos(angle);
+		float yoff = CROSSHAIR_DIST * sin(angle);
+		cx -= static_cast<int32>(xoff);
+		cy -= static_cast<int32>(yoff);
+
 		Item *item;
 		if (_itemNum) {
 			item = getItem(_itemNum);
@@ -81,7 +82,6 @@ void CrosshairProcess::run() {
 			_itemNum = 0;
 		}
 	}
-
 }
 
 void CrosshairProcess::saveData(Common::WriteStream *ws) {


Commit: 36ab8b5587ec4d96d0cd5374a264e6cf5cda7338
    https://github.com/scummvm/scummvm/commit/36ab8b5587ec4d96d0cd5374a264e6cf5cda7338
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-07-15T15:00:00+09:00

Commit Message:
ULTIMA8: Const correctness for typeflag functions

Changed paths:
    engines/ultima/ultima8/graphics/shape_info.cpp
    engines/ultima/ultima8/graphics/shape_info.h


diff --git a/engines/ultima/ultima8/graphics/shape_info.cpp b/engines/ultima/ultima8/graphics/shape_info.cpp
index b2742a4fde..df2c308468 100644
--- a/engines/ultima/ultima8/graphics/shape_info.cpp
+++ b/engines/ultima/ultima8/graphics/shape_info.cpp
@@ -28,7 +28,7 @@
 namespace Ultima {
 namespace Ultima8 {
 
-bool ShapeInfo::getTypeFlag(int typeFlag) {
+bool ShapeInfo::getTypeFlag(int typeFlag) const {
 	if (GAME_IS_U8)
 		return getTypeFlagU8(typeFlag);
 	else if (GAME_IS_CRUSADER)
@@ -37,7 +37,7 @@ bool ShapeInfo::getTypeFlag(int typeFlag) {
 	return false;
 }
 
-bool ShapeInfo::getTypeFlagU8(int typeFlag) {
+bool ShapeInfo::getTypeFlagU8(int typeFlag) const {
 	// This is not nice. The Typeflags in U8 were stored in an 8 byte array
 	// and they could access them with a number from 0 to 63
 	// Problem: We don't store them in an 8 byte array so we can't access
@@ -74,7 +74,7 @@ bool ShapeInfo::getTypeFlagU8(int typeFlag) {
 	return false;
 }
 
-bool ShapeInfo::getTypeFlagCrusader(int typeFlag) {
+bool ShapeInfo::getTypeFlagCrusader(int typeFlag) const {
 	if (typeFlag <= 11) {       // _flags        Byte 0, 1:0-3   Bits  0-11
 		return (_flags >> typeFlag) & 1;
 	} else if (typeFlag <= 16) { // _family       Byte 1:4-7,2:0  Bits 12-16
diff --git a/engines/ultima/ultima8/graphics/shape_info.h b/engines/ultima/ultima8/graphics/shape_info.h
index 3b6c06565e..48b68342b1 100644
--- a/engines/ultima/ultima8/graphics/shape_info.h
+++ b/engines/ultima/ultima8/graphics/shape_info.h
@@ -151,9 +151,9 @@ public:
 		return (_damageInfo && _damageInfo->takesDamage());
 	}
 
-	bool getTypeFlag(int typeFlag);
-	bool getTypeFlagU8(int typeFlag);
-	bool getTypeFlagCrusader(int typeFlag);
+	bool getTypeFlag(int typeFlag) const;
+	bool getTypeFlagU8(int typeFlag) const;
+	bool getTypeFlagCrusader(int typeFlag) const;
 
 	inline void getFootpadWorld(int32 &x, int32 &y, int32 &z, uint16 flipped) const;
 


Commit: 8ab251a0ec2aa067c2f29d240112a05a97d8ff47
    https://github.com/scummvm/scummvm/commit/8ab251a0ec2aa067c2f29d240112a05a97d8ff47
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-07-15T15:00:36+09:00

Commit Message:
ULTIMA8: Remove duplicate code from target reticle process

Changed paths:
    engines/ultima/module.mk
    engines/ultima/ultima8/world/actors/actor.cpp
    engines/ultima/ultima8/world/item.cpp
    engines/ultima/ultima8/world/target_reticle_process.cpp
    engines/ultima/ultima8/world/target_reticle_process.h


diff --git a/engines/ultima/module.mk b/engines/ultima/module.mk
index d419906744..277af7252d 100644
--- a/engines/ultima/module.mk
+++ b/engines/ultima/module.mk
@@ -538,6 +538,7 @@ MODULE_OBJS := \
 	ultima8/world/gravity_process.o \
 	ultima8/world/item.o \
 	ultima8/world/item_factory.o \
+	ultima8/world/item_selection_process.o \
 	ultima8/world/item_sorter.o \
 	ultima8/world/map.o \
 	ultima8/world/map_glob.o \
diff --git a/engines/ultima/ultima8/world/actors/actor.cpp b/engines/ultima/ultima8/world/actors/actor.cpp
index 24e5200cc2..b7875c3494 100644
--- a/engines/ultima/ultima8/world/actors/actor.cpp
+++ b/engines/ultima/ultima8/world/actors/actor.cpp
@@ -1157,7 +1157,7 @@ int32 Actor::collideMove(int32 x, int32 y, int32 z, bool teleport, bool force,
 	int32 result = Item::collideMove(x, y, z, teleport, force, hititem, dirs);
 	if (_objId == 1 && GAME_IS_CRUSADER) {
 		notifyNearbyItems();
-		TargetReticleProcess::getProcess()->avatarMoved();
+		TargetReticleProcess::get_instance()->avatarMoved();
 	}
 	return result;
 }
diff --git a/engines/ultima/ultima8/world/item.cpp b/engines/ultima/ultima8/world/item.cpp
index aca69101f8..6c17c62e3d 100644
--- a/engines/ultima/ultima8/world/item.cpp
+++ b/engines/ultima/ultima8/world/item.cpp
@@ -246,7 +246,7 @@ void Item::move(int32 X, int32 Y, int32 Z) {
 		CameraProcess::GetCameraProcess()->ItemMoved();
 
 	if (_extendedFlags & EXT_TARGET)
-		TargetReticleProcess::getProcess()->itemMoved(this);
+		TargetReticleProcess::get_instance()->itemMoved(this);
 }
 
 bool Item::moveToContainer(Container *container, bool checkwghtvol) {
diff --git a/engines/ultima/ultima8/world/target_reticle_process.cpp b/engines/ultima/ultima8/world/target_reticle_process.cpp
index 96b027dc44..b392c72295 100644
--- a/engines/ultima/ultima8/world/target_reticle_process.cpp
+++ b/engines/ultima/ultima8/world/target_reticle_process.cpp
@@ -36,7 +36,7 @@
 namespace Ultima {
 namespace Ultima8 {
 
-TargetReticleProcess *TargetReticleProcess::_instance;
+TargetReticleProcess *TargetReticleProcess::_instance = nullptr;
 
 // p_dynamic_cast stuff
 DEFINE_RUNTIME_CLASSTYPE_CODE(TargetReticleProcess)
diff --git a/engines/ultima/ultima8/world/target_reticle_process.h b/engines/ultima/ultima8/world/target_reticle_process.h
index b44e1a8ae9..6838579eb1 100644
--- a/engines/ultima/ultima8/world/target_reticle_process.h
+++ b/engines/ultima/ultima8/world/target_reticle_process.h
@@ -53,10 +53,6 @@ public:
 	bool loadData(Common::ReadStream *rs, uint32 version);
 	void saveData(Common::WriteStream *ws) override;
 
-	static TargetReticleProcess *getProcess() {
-		return _instance;
-	}
-
 	void setEnabled(bool val) {
 		_reticleEnabled = val;
 	}


Commit: f45ee551b8740129e485b81571532f42c9a857c8
    https://github.com/scummvm/scummvm/commit/f45ee551b8740129e485b81571532f42c9a857c8
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-07-15T16:13:54+09:00

Commit Message:
ULTIMA8: Create process for Crusader item selection

Changed paths:
  A engines/ultima/ultima8/world/item_selection_process.cpp
  A engines/ultima/ultima8/world/item_selection_process.h
    engines/ultima/ultima8/graphics/shape_info.h
    engines/ultima/ultima8/graphics/type_flags.cpp
    engines/ultima/ultima8/meta_engine.cpp
    engines/ultima/ultima8/meta_engine.h
    engines/ultima/ultima8/misc/debugger.cpp
    engines/ultima/ultima8/misc/debugger.h
    engines/ultima/ultima8/ultima8.cpp
    engines/ultima/ultima8/world/actors/actor.cpp


diff --git a/engines/ultima/ultima8/graphics/shape_info.h b/engines/ultima/ultima8/graphics/shape_info.h
index 48b68342b1..cb1005eef9 100644
--- a/engines/ultima/ultima8/graphics/shape_info.h
+++ b/engines/ultima/ultima8/graphics/shape_info.h
@@ -50,7 +50,7 @@ public:
 		SI_EXPLODE = 0x2000,
 		SI_UNKNOWN46 = 0x4000,
 		SI_UNKNOWN47 = 0x8000,
-		SI_CRUSUNK61 = 0x2000,
+		SI_SELECTABLE= 0x2000,
 		SI_CRUSUNK62 = 0x4000,
 		SI_CRUSUNK63 = 0x8000,
 		SI_TARGETABLE= 0x10000,
diff --git a/engines/ultima/ultima8/graphics/type_flags.cpp b/engines/ultima/ultima8/graphics/type_flags.cpp
index 590553679b..40de6b7194 100644
--- a/engines/ultima/ultima8/graphics/type_flags.cpp
+++ b/engines/ultima/ultima8/graphics/type_flags.cpp
@@ -140,7 +140,7 @@ void TypeFlags::load(Common::SeekableReadStream *rs) {
 			si._weight = data[7];
 
 			if (data[6] & 0x01) si._flags |= ShapeInfo::SI_EDITOR;
-			if (data[6] & 0x02) si._flags |= ShapeInfo::SI_CRUSUNK61;
+			if (data[6] & 0x02) si._flags |= ShapeInfo::SI_SELECTABLE;
 			if (data[6] & 0x04) si._flags |= ShapeInfo::SI_CRUSUNK62;
 			if (data[6] & 0x08) si._flags |= ShapeInfo::SI_CRUSUNK63;
 			if (data[6] & 0x10) si._flags |= ShapeInfo::SI_TARGETABLE;
diff --git a/engines/ultima/ultima8/meta_engine.cpp b/engines/ultima/ultima8/meta_engine.cpp
index 86bc186388..9ab3e72c49 100644
--- a/engines/ultima/ultima8/meta_engine.cpp
+++ b/engines/ultima/ultima8/meta_engine.cpp
@@ -52,8 +52,9 @@ static const KeybindingRecord KEYS[] = {
 	{ ACTION_INVENTORY, "INVENTORY", "Inventory", "MainActor::useInventory", nullptr, "z", "JOY_LEFT_SHOULDER" },
 	{ ACTION_NEXT_WEAPON, "NEXT_WEAPON", "Next Crusader Weapon", "MainActor::nextWeapon", nullptr, "w", nullptr },
 	{ ACTION_USE_INVENTORY, "USE_INVENTORY", "Use Cru. Inventroy Item", "MainActor::useInventoryItem", nullptr, "u", nullptr },
-	{ ACTION_SELECT_ITEMS, "SELECT_ITEM", "Selete Cru. Item", "MainActor::startSelection", nullptr, "s", nullptr },
 	{ ACTION_USE_MEDIKIT, "USE_MEDIKIT", "Use Medical Kit", "MainActor::useMedikit", nullptr, "M", nullptr },
+	{ ACTION_SELECT_ITEMS, "SELECT_ITEM", "Select Cru. Item", "ItemSelectionProcess::startSelection", nullptr, "s", nullptr },
+	{ ACTION_USE_SELECTION, "USE_SELECTION", "Use Cru. Selection", "ItemSelectionProcess::useSelectedItem", nullptr, "RETURN", nullptr },
 	{ ACTION_MENU, "MENU", "Game Menu", "MenuGump::showMenu", nullptr, "ESCAPE", "JOY_Y" },
 	{ ACTION_CLOSE_GUMPS, "CLOSE_GUMPS", "Close Gumps", "GUIApp::closeItemGumps", nullptr, "BACKSPACE", nullptr },
 	{ ACTION_HIGHLIGHT_ITEMS, "HIGHLIGHT_ITEMS", "Show Highlight Items", "GameMapGump::toggleHighlightItems",
diff --git a/engines/ultima/ultima8/meta_engine.h b/engines/ultima/ultima8/meta_engine.h
index b54364ec65..659751457f 100644
--- a/engines/ultima/ultima8/meta_engine.h
+++ b/engines/ultima/ultima8/meta_engine.h
@@ -31,7 +31,7 @@ namespace Ultima8 {
 enum KeybindingAction {
 	ACTION_QUICKSAVE, ACTION_SAVE, ACTION_LOAD, ACTION_BEDROLL, ACTION_COMBAT, ACTION_BACKPACK,
 	ACTION_KEYRING, ACTION_MINIMAP, ACTION_RECALL, ACTION_INVENTORY, ACTION_NEXT_WEAPON,
-	ACTION_USE_INVENTORY, ACTION_USE_MEDIKIT, ACTION_SELECT_ITEMS,
+	ACTION_USE_INVENTORY, ACTION_USE_MEDIKIT, ACTION_SELECT_ITEMS, ACTION_USE_SELECTION,
 	ACTION_MENU, ACTION_CLOSE_GUMPS, ACTION_HIGHLIGHT_ITEMS, ACTION_TOGGLE_TOUCHING,
 	ACTION_JUMP, ACTION_TURN_LEFT, ACTION_TURN_RIGHT, ACTION_MOVE_FORWARD, ACTION_MOVE_BACK,
 	ACTION_MOVE_UP, ACTION_MOVE_DOWN, ACTION_MOVE_LEFT, ACTION_MOVE_RIGHT,
diff --git a/engines/ultima/ultima8/misc/debugger.cpp b/engines/ultima/ultima8/misc/debugger.cpp
index 7bf6315fa8..fa239ad959 100644
--- a/engines/ultima/ultima8/misc/debugger.cpp
+++ b/engines/ultima/ultima8/misc/debugger.cpp
@@ -48,6 +48,7 @@
 #include "ultima/ultima8/world/actors/quick_avatar_mover_process.h"
 #include "ultima/ultima8/world/actors/avatar_mover_process.h"
 #include "ultima/ultima8/world/target_reticle_process.h"
+#include "ultima/ultima8/world/item_selection_process.h"
 #include "ultima/ultima8/world/actors/main_actor.h"
 #include "ultima/ultima8/world/actors/pathfinder.h"
 
@@ -145,6 +146,8 @@ Debugger::Debugger() : Shared::Debugger() {
 	registerCmd("MainActor::useInventoryItem", WRAP_METHOD(Debugger, cmdUseInventoryItem));
 	registerCmd("MainActor::useMedikit", WRAP_METHOD(Debugger, cmdUseMedikit));
 	registerCmd("MainActor::toggleCombat", WRAP_METHOD(Debugger, cmdToggleCombat));
+	registerCmd("ItemSelectionProcess::startSelection", WRAP_METHOD(Debugger, cmdStartSelection));
+	registerCmd("ItemSelectionProcess::useSelectedItem", WRAP_METHOD(Debugger, cmdUseSelection));
 
 	registerCmd("ObjectManager::objectTypes", WRAP_METHOD(Debugger, cmdObjectTypes));
 	registerCmd("ObjectManager::objectInfo", WRAP_METHOD(Debugger, cmdObjectInfo));
@@ -1500,7 +1503,6 @@ bool Debugger::cmdStopMoveStep(int argc, const char **argv) {
 	return false;
 }
 
-
 bool Debugger::cmdToggleCombat(int argc, const char **argv) {
 	if (Ultima8Engine::get_instance()->isAvatarInStasis()) {
 		debugPrintf("Can't toggle combat: avatarInStasis\n");
@@ -1512,6 +1514,30 @@ bool Debugger::cmdToggleCombat(int argc, const char **argv) {
 	return false;
 }
 
+bool Debugger::cmdStartSelection(int argc, const char **argv) {
+	if (Ultima8Engine::get_instance()->isAvatarInStasis()) {
+		debugPrintf("Can't select items: avatarInStasis\n");
+		return false;
+	}
+
+	ItemSelectionProcess *proc = ItemSelectionProcess::get_instance();
+	if (proc)
+		proc->selectNextItem();
+	return false;
+}
+
+bool Debugger::cmdUseSelection(int argc, const char **argv) {
+	if (Ultima8Engine::get_instance()->isAvatarInStasis()) {
+		debugPrintf("Can't use items: avatarInStasis\n");
+		return false;
+	}
+
+	ItemSelectionProcess *proc = ItemSelectionProcess::get_instance();
+	if (proc)
+		proc->useSelectedItem();
+	return false;
+}
+
 bool Debugger::cmdObjectTypes(int argc, const char **argv) {
 	ObjectManager::get_instance()->objectTypes();
 	return true;
diff --git a/engines/ultima/ultima8/misc/debugger.h b/engines/ultima/ultima8/misc/debugger.h
index b7c4e962e4..cb1bf5b72f 100644
--- a/engines/ultima/ultima8/misc/debugger.h
+++ b/engines/ultima/ultima8/misc/debugger.h
@@ -218,6 +218,8 @@ private:
 	bool cmdToggleCombat(int argc, const char **argv);
 	bool cmdUseInventoryItem(int argc, const char **argv);
 	bool cmdUseMedikit(int argc, const char **argv);
+	bool cmdStartSelection(int argc, const char **argv);
+	bool cmdUseSelection(int argc, const char **argv);
 
 	// Object Manager
 	bool cmdObjectTypes(int argc, const char **argv);
diff --git a/engines/ultima/ultima8/ultima8.cpp b/engines/ultima/ultima8/ultima8.cpp
index 2db991d892..248642ad32 100644
--- a/engines/ultima/ultima8/ultima8.cpp
+++ b/engines/ultima/ultima8/ultima8.cpp
@@ -93,6 +93,7 @@
 #include "ultima/ultima8/world/actors/avatar_gravity_process.h"
 #include "ultima/ultima8/world/actors/teleport_to_egg_process.h"
 #include "ultima/ultima8/world/item_factory.h"
+#include "ultima/ultima8/world/item_selection_process.h"
 #include "ultima/ultima8/world/split_item_process.h"
 #include "ultima/ultima8/world/target_reticle_process.h"
 #include "ultima/ultima8/world/snap_process.h"
@@ -295,6 +296,10 @@ void Ultima8Engine::startup() {
 		ProcessLoader<GuardProcess>::load);
 	_kernel->addProcessLoader("SnapProcess",
 		ProcessLoader<SnapProcess>::load);
+	_kernel->addProcessLoader("CrosshairProcess",
+		ProcessLoader<CrosshairProcess>::load);
+	_kernel->addProcessLoader("ItemSelectionProcess",
+		ProcessLoader<ItemSelectionProcess>::load);
 
 	_objectManager = new ObjectManager();
 	_mouse = new Mouse();
@@ -1135,6 +1140,7 @@ bool Ultima8Engine::newGame(int saveSlot) {
 
 	if (GAME_IS_CRUSADER) {
 		_kernel->addProcess(new TargetReticleProcess());
+		_kernel->addProcess(new ItemSelectionProcess());
 		_kernel->addProcess(new CrosshairProcess());
 		_kernel->addProcess(new CycleProcess());
 		_kernel->addProcess(new SnapProcess());
diff --git a/engines/ultima/ultima8/world/actors/actor.cpp b/engines/ultima/ultima8/world/actors/actor.cpp
index b7875c3494..bd9e44f6a9 100644
--- a/engines/ultima/ultima8/world/actors/actor.cpp
+++ b/engines/ultima/ultima8/world/actors/actor.cpp
@@ -51,6 +51,7 @@
 #include "ultima/ultima8/audio/audio_process.h"
 #include "ultima/ultima8/world/sprite_process.h"
 #include "ultima/ultima8/world/target_reticle_process.h"
+#include "ultima/ultima8/world/item_selection_process.h"
 #include "ultima/ultima8/world/actors/main_actor.h"
 #include "ultima/ultima8/audio/music_process.h"
 #include "ultima/ultima8/world/get_object.h"
@@ -1158,6 +1159,7 @@ int32 Actor::collideMove(int32 x, int32 y, int32 z, bool teleport, bool force,
 	if (_objId == 1 && GAME_IS_CRUSADER) {
 		notifyNearbyItems();
 		TargetReticleProcess::get_instance()->avatarMoved();
+		ItemSelectionProcess::get_instance()->clearSelection();
 	}
 	return result;
 }
diff --git a/engines/ultima/ultima8/world/item_selection_process.cpp b/engines/ultima/ultima8/world/item_selection_process.cpp
new file mode 100644
index 0000000000..5319626283
--- /dev/null
+++ b/engines/ultima/ultima8/world/item_selection_process.cpp
@@ -0,0 +1,173 @@
+/* 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/games/game_data.h"
+#include "ultima/ultima8/audio/audio_process.h"
+#include "ultima/ultima8/kernel/kernel.h"
+#include "ultima/ultima8/world/actors/main_actor.h"
+#include "ultima/ultima8/world/item_selection_process.h"
+#include "ultima/ultima8/world/item_factory.h"
+#include "ultima/ultima8/world/item.h"
+#include "ultima/ultima8/world/world.h"
+#include "ultima/ultima8/world/current_map.h"
+#include "ultima/ultima8/world/get_object.h"
+#include "ultima/ultima8/world/loop_script.h"
+#include "ultima/ultima8/graphics/shape_info.h"
+#include "ultima/ultima8/usecode/uc_list.h"
+
+namespace Ultima {
+namespace Ultima8 {
+
+ItemSelectionProcess *ItemSelectionProcess::_instance = nullptr;
+
+static const uint32 SELECTOR_SHAPE = 0x5a3;
+static const uint16 SELECTION_FAILED_SOUND = 0xb0;
+
+// p_dynamic_cast stuff
+DEFINE_RUNTIME_CLASSTYPE_CODE(ItemSelectionProcess)
+
+ItemSelectionProcess::ItemSelectionProcess() : Process(), _selectedItem(0) {
+	_instance = this;
+}
+
+void ItemSelectionProcess::run() {
+}
+
+bool ItemSelectionProcess::selectNextItem() {
+	MainActor *mainactor = getMainActor();
+	CurrentMap *currentmap = World::get_instance()->getCurrentMap();
+
+	if (!mainactor || !currentmap)
+		return false;
+
+	int32 x, y, z;
+	mainactor->getCentre(x, y, z);
+
+	UCList uclist(2);
+	LOOPSCRIPT(script, LS_TOKEN_TRUE); // we want all items
+	currentmap->areaSearch(&uclist, script, sizeof(script),
+						   mainactor, 0x100, false);
+
+	Std::vector<Item *> candidates;
+
+	for (unsigned int i = 0; i < uclist.getSize(); ++i) {
+		ObjId itemid = uclist.getuint16(i);
+		Item *item = getItem(itemid);
+		const ShapeInfo *info = item->getShapeInfo();
+
+		if (!item)
+			continue;
+		// Maybe this can be done with a loopscript,
+		// but this is how the game does it..
+		if (item->hasFlags(Actor::FLG_HANGING))
+			continue;
+		if (item->getShape() == 0x4ed || item->getFamily() == 10 || item->getFamily() == 11 || item->getFamily() == 12 || item->getFamily() == 13 || (info && info->_flags & ShapeInfo::SI_SELECTABLE)) {
+
+			int32 cx, cy, cz;
+			item->getCentre(cx, cy, cz);
+			if (abs(cx - x) > 0x100 || abs(cy - y) > 0x100 || abs(cz - z) > 50)
+				continue;
+
+			candidates.push_back(item);
+		}
+	}
+
+	if (candidates.size() < 1) {
+		AudioProcess *audio = AudioProcess::get_instance();
+		assert(audio);
+		// Play the "beeboop" selection failed sound.
+		audio->playSFX(SELECTION_FAILED_SOUND, 0x10, 0, 1);
+		clearSelection();
+		return false;
+	}
+	Item *item = candidates[0];
+	if (_selectedItem) {
+		// Pick the next item
+		int offset = 0;
+		for (Std::vector<Item *>::iterator iter = candidates.begin();
+			 iter != candidates.end();
+			 iter++) {
+			ObjId num = item->getObjId();
+			if (_selectedItem == num) {
+				offset++;
+				break;
+			}
+		}
+		offset = offset % candidates.size();
+		item = candidates[offset];
+	}
+
+	putItemSelectionOnItem(item);
+	return true;
+}
+
+void ItemSelectionProcess::useSelectedItem() {
+	if (!_selectedItem)
+		return;
+	Item *item = getItem(_selectedItem);
+	if (item)
+		item->callUsecodeEvent_use();
+	clearSelection();
+}
+
+void ItemSelectionProcess::clearSelection() {
+	if (!getItemNum())
+		return;
+	Item *sprite = getItem(getItemNum());
+	if (sprite) {
+		sprite->destroy();
+	}
+	setItemNum(0);
+	_selectedItem = 0;
+}
+
+void ItemSelectionProcess::putItemSelectionOnItem(Item *item) {
+	assert(item);
+	int32 x, y, z;
+
+	clearSelection();
+
+	item->getCentre(x, y, z);
+	_selectedItem = item->getObjId();
+
+	Item *sprite = ItemFactory::createItem(SELECTOR_SHAPE, 0, 0, Item::FLG_DISPOSABLE,
+										   0, 0, Item::EXT_SPRITE, true);
+	sprite->move(x, y, z);
+	setItemNum(sprite->getObjId());
+}
+
+void ItemSelectionProcess::saveData(Common::WriteStream *ws) {
+	Process::saveData(ws);
+	ws->writeUint16LE(_selectedItem);
+}
+
+bool ItemSelectionProcess::loadData(Common::ReadStream *rs, uint32 version) {
+	if (!Process::loadData(rs, version)) return false;
+
+	_selectedItem = rs->readUint16LE();
+	return true;
+}
+
+} // End of namespace Ultima8
+} // End of namespace Ultima
diff --git a/engines/ultima/ultima8/world/item_selection_process.h b/engines/ultima/ultima8/world/item_selection_process.h
new file mode 100644
index 0000000000..8dc47f94b0
--- /dev/null
+++ b/engines/ultima/ultima8/world/item_selection_process.h
@@ -0,0 +1,81 @@
+/* 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 ULTIMA8_WORLD_ITEMSELECTIONPROCESS_H
+#define ULTIMA8_WORLD_ITEMSELECTIONPROCESS_H
+
+#include "ultima/ultima8/kernel/process.h"
+#include "ultima/ultima8/misc/p_dynamic_cast.h"
+
+namespace Ultima {
+namespace Ultima8 {
+
+class Item;
+
+/**
+ * A process to select items for use.
+ */
+class ItemSelectionProcess : public Process {
+public:
+	ItemSelectionProcess();
+
+	// p_dynamic_cast stuff
+	ENABLE_RUNTIME_CLASSTYPE()
+
+	void run() override;
+
+	//!< Select the next item
+	bool selectNextItem();
+
+	//!< Avatar moved - clear the selector
+	void clearSelection();
+
+	//!< Use the selected item (if any)
+	void useSelectedItem();
+
+	bool loadData(Common::ReadStream *rs, uint32 version);
+	void saveData(Common::WriteStream *ws) override;
+
+	static ItemSelectionProcess *get_instance() {
+		return _instance;
+	}
+
+    uint16 getSelectedItem() const {
+        return _selectedItem;
+    }
+
+private:
+	void putItemSelectionOnItem(Item *item);
+
+	uint16 _selectedItem;
+    int32 _ax;
+    int32 _ay;
+    int32 _az;
+    uint16 _adir;
+
+	static ItemSelectionProcess *_instance;
+};
+
+} // End of namespace Ultima8
+} // End of namespace Ultima
+
+#endif




More information about the Scummvm-git-logs mailing list