[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