[Scummvm-git-logs] scummvm master -> 47ac672ff82cc88079338ba0e4f88fbf2140726a

mduggan mgithub at guarana.org
Fri Jul 10 03:26:47 UTC 2020


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
47ac672ff8 ULTIMA8: Add camera snap to Crusader


Commit: 47ac672ff82cc88079338ba0e4f88fbf2140726a
    https://github.com/scummvm/scummvm/commit/47ac672ff82cc88079338ba0e4f88fbf2140726a
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-07-10T12:26:09+09:00

Commit Message:
ULTIMA8: Add camera snap to Crusader

Changed paths:
  A engines/ultima/ultima8/world/snap_process.cpp
  A engines/ultima/ultima8/world/snap_process.h
    engines/ultima/module.mk
    engines/ultima/ultima8/ultima8.cpp
    engines/ultima/ultima8/world/item.cpp


diff --git a/engines/ultima/module.mk b/engines/ultima/module.mk
index a262910e97..56632f4933 100644
--- a/engines/ultima/module.mk
+++ b/engines/ultima/module.mk
@@ -542,6 +542,7 @@ MODULE_OBJS := \
 	ultima8/world/map_glob.o \
 	ultima8/world/missile_tracker.o \
 	ultima8/world/monster_egg.o \
+	ultima8/world/snap_process.o \
 	ultima8/world/split_item_process.o \
 	ultima8/world/sprite_process.o \
 	ultima8/world/target_reticle_process.o \
diff --git a/engines/ultima/ultima8/ultima8.cpp b/engines/ultima/ultima8/ultima8.cpp
index 1ec9fb3a88..83f15645e9 100644
--- a/engines/ultima/ultima8/ultima8.cpp
+++ b/engines/ultima/ultima8/ultima8.cpp
@@ -93,6 +93,7 @@
 #include "ultima/ultima8/world/item_factory.h"
 #include "ultima/ultima8/world/split_item_process.h"
 #include "ultima/ultima8/world/target_reticle_process.h"
+#include "ultima/ultima8/world/snap_process.h"
 #include "ultima/ultima8/world/crosshair_process.h"
 #include "ultima/ultima8/world/actors/pathfinder_process.h"
 #include "ultima/ultima8/world/actors/avatar_mover_process.h"
@@ -104,6 +105,7 @@
 #include "ultima/ultima8/world/actors/cru_healer_process.h"
 #include "ultima/ultima8/world/actors/surrender_process.h"
 #include "ultima/ultima8/world/actors/combat_process.h"
+#include "ultima/ultima8/world/actors/guard_process.h"
 #include "ultima/ultima8/world/fireball_process.h"
 #include "ultima/ultima8/world/destroy_item_process.h"
 #include "ultima/ultima8/world/actors/ambush_process.h"
@@ -288,6 +290,10 @@ void Ultima8Engine::startup() {
 		ProcessLoader<BatteryChargerProcess>::load);
 	_kernel->addProcessLoader("CycleProcess",
 		ProcessLoader<CycleProcess>::load);
+	_kernel->addProcessLoader("GuardProcess",
+		ProcessLoader<GuardProcess>::load);
+	_kernel->addProcessLoader("SnapProcess",
+		ProcessLoader<SnapProcess>::load);
 
 	_objectManager = new ObjectManager();
 	_mouse = new Mouse();
@@ -1042,7 +1048,7 @@ void Ultima8Engine::resetEngine() {
 }
 
 void Ultima8Engine::setupCoreGumps() {
-	debugN(MM_INFO, "Setting up core _game gumps...\n");
+	debugN(MM_INFO, "Setting up core game gumps...\n");
 
 	Rect dims;
 	_screen->GetSurfaceDims(dims);
@@ -1053,7 +1059,7 @@ void Ultima8Engine::setupCoreGumps() {
 	_desktopGump->MakeFocus();
 
 	if (GAME_IS_U8) {
-		debugN(MM_INFO, "Creating _scalerGump...\n");
+		debugN(MM_INFO, "Creating ScalerGump...\n");
 		_scalerGump = new ScalerGump(0, 0, dims.w, dims.h);
 		_scalerGump->InitGump(0);
 
@@ -1130,6 +1136,7 @@ bool Ultima8Engine::newGame(int saveSlot) {
 		_kernel->addProcess(new TargetReticleProcess());
 		_kernel->addProcess(new CrosshairProcess());
 		_kernel->addProcess(new CycleProcess());
+		_kernel->addProcess(new SnapProcess());
 	}
 
 	if (saveSlot == -1)
diff --git a/engines/ultima/ultima8/world/item.cpp b/engines/ultima/ultima8/world/item.cpp
index c9d29dc17c..84d1c14426 100644
--- a/engines/ultima/ultima8/world/item.cpp
+++ b/engines/ultima/ultima8/world/item.cpp
@@ -58,6 +58,7 @@
 #include "ultima/ultima8/usecode/uc_process.h"
 #include "ultima/ultima8/world/destroy_item_process.h"
 #include "ultima/ultima8/world/target_reticle_process.h"
+#include "ultima/ultima8/world/snap_process.h"
 #include "ultima/ultima8/audio/audio_process.h"
 #include "ultima/ultima8/games/game_info.h"
 #include "ultima/ultima8/world/actors/main_actor.h"
@@ -66,6 +67,8 @@
 namespace Ultima {
 namespace Ultima8 {
 
+static const uint32 SNAP_EGG_SHAPE = 0x4fe;
+
 // p_dynamic_cast stuff
 DEFINE_RUNTIME_CLASSTYPE_CODE(Item)
 
@@ -1308,6 +1311,11 @@ void Item::destroy(bool delnow) {
 		AudioProcess *audio = AudioProcess::get_instance();
 		if (audio)
 			audio->stopSFX(-1, _objId);
+		if (_shape == SNAP_EGG_SHAPE) {
+			SnapProcess *snap = SnapProcess::get_instance();
+			if (snap)
+				snap->removeEgg(this);
+		}
 	}
 
 	if (_extendedFlags & Item::EXT_CAMERA)
@@ -1463,6 +1471,11 @@ void Item::enterFastArea() {
 		if ((si->_flags & ShapeInfo::SI_TARGETABLE) || (si->_flags & ShapeInfo::SI_OCCL)) {
 			World::get_instance()->getCurrentMap()->addTargetItem(this);
 		}
+		if (_shape == SNAP_EGG_SHAPE) {
+			SnapProcess *snap = SnapProcess::get_instance();
+			if (snap)
+				snap->addEgg(this);
+		}
 	}
 
 	// We're fast!
@@ -1487,6 +1500,11 @@ void Item::leaveFastArea() {
 
 	if (!hasFlags(FLG_BROKEN) && GAME_IS_CRUSADER) {
 		World::get_instance()->getCurrentMap()->removeTargetItem(this);
+		if (_shape == SNAP_EGG_SHAPE) {
+			SnapProcess *snap = SnapProcess::get_instance();
+			if (snap)
+				snap->removeEgg(this);
+		}
 	}
 
 	// CHECKME: what do we need to do exactly?
@@ -2937,6 +2955,8 @@ uint32 Item::I_legalMoveToPoint(const uint8 *args, unsigned int argsize) {
 		point.setY(point.getY() * 2);
 	}
 
+	if (!item)
+		return 0;
 	//! What should this do to ethereal items?
 
 //	if (item->canExistAt(point.getX(), point.getY(), point.getZ())) {
diff --git a/engines/ultima/ultima8/world/snap_process.cpp b/engines/ultima/ultima8/world/snap_process.cpp
new file mode 100644
index 0000000000..e368d11e7b
--- /dev/null
+++ b/engines/ultima/ultima8/world/snap_process.cpp
@@ -0,0 +1,174 @@
+/* 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/snap_process.h"
+#include "ultima/ultima8/world/item.h"
+#include "ultima/ultima8/world/get_object.h"
+#include "ultima/ultima8/world/actors/main_actor.h"
+#include "ultima/ultima8/world/camera_process.h"
+
+namespace Ultima {
+namespace Ultima8 {
+
+
+SnapProcess *SnapProcess::_instance = nullptr;
+
+// p_dynamic_cast stuff
+DEFINE_RUNTIME_CLASSTYPE_CODE(SnapProcess)
+
+SnapProcess::SnapProcess() : Process(), _currentSnapEgg() {
+	_instance = this;
+}
+
+void SnapProcess::run() {
+	if (!_currentSnapEgg || !isNpcInRangeOfCurrentEgg()) {
+		updateCurrentEgg();
+	}
+}
+
+void SnapProcess::addEgg(Item *item) {
+	assert(item);
+	ObjId id = item->getObjId();
+	for (Std::list<ObjId>::const_iterator iter = _snapEggs.begin();
+		 iter != _snapEggs.end(); iter++) {
+		if (*iter == id)
+			return;
+	}
+	_snapEggs.push_back(id);
+}
+
+void SnapProcess::updateCurrentEgg() {
+	// Check that we have something to snap to..
+	if (!_currentSnapEgg && !_snapEggs.size())
+		return;
+
+	const MainActor *a = getMainActor();
+	int32 ax, ay, az, axd, ayd, azd, x, y, z;
+	a->getLocation(ax, ay, az);
+	a->getFootpadWorld(axd, ayd, azd);
+	Rect arect(ax, ay, axd, ayd);
+
+	for (Std::list<ObjId>::const_iterator iter = _snapEggs.begin();
+		 iter != _snapEggs.end(); iter++) {
+		Item *egg = getItem(*iter);
+		if (!egg)
+			continue;
+		Rect r;
+		egg->getLocation(x, y, z);
+		getSnapEggRange(egg, r);
+		if (r.Overlaps(arect) && (az < z + 0x30 && az > z - 0x30)) {
+			_currentSnapEgg = *iter;
+			_currentSnapEggRange = r;
+			CameraProcess::SetCameraProcess(new CameraProcess(_currentSnapEgg));
+		}
+	}
+}
+
+void SnapProcess::removeEgg(Item *item) {
+	assert(item);
+	ObjId id = item->getObjId();
+	for (Std::list<ObjId>::iterator iter = _snapEggs.begin();
+		 iter != _snapEggs.end(); iter++) {
+		if (*iter == id) {
+			iter = _snapEggs.erase(iter);
+		}
+	}
+	if (id == _currentSnapEgg) {
+		_currentSnapEgg = 0;
+		_currentSnapEggRange = Rect();
+	}
+}
+
+bool SnapProcess::isNpcInRangeOfCurrentEgg() const {
+	if (!_currentSnapEgg)
+		return false;
+
+	const MainActor *a = getMainActor();
+	Item *currentegg = getItem(_currentSnapEgg);
+
+	if (!a || !currentegg)
+		return false;
+
+	int32 ax, ay, az, axd, ayd, azd, x, y, z;
+	a->getLocation(ax, ay, az);
+	a->getFootpadWorld(axd, ayd, azd);
+	currentegg->getLocation(x, y, z);
+
+	Rect arect(ax, ay, axd, ayd);
+
+	if (!_currentSnapEggRange.Overlaps(arect))
+		return false;
+	if (az > z + 0x30 || az < z - 0x30)
+		return false;
+
+	return true;
+}
+
+void SnapProcess::getSnapEggRange(const Item *item, Rect &rect) const {
+	assert(item);
+	uint16 qhi = ((item->getQuality() >> 8) & 0xff);
+	// Interpreting the values as *signed* char here is deliberate.
+	int32 xoff = static_cast<int8>(item->getMapNum()) * 0x0020;
+	int32 yoff = static_cast<int8>(item->getNpcNum()) * 0x0020;
+	int32 xrange = (qhi >> 4) * 0x20;
+	int32 yrange = (qhi & 0xf) * 0x20;
+
+	int32 x, y, z;
+	item->getLocation(x, y, z);
+
+	rect.x = x - xrange + xoff;
+	rect.y = y - yrange + yoff;
+	rect.w = xrange * 2;
+	rect.h = yrange * 2;
+}
+
+void SnapProcess::saveData(Common::WriteStream *ws) {
+	Process::saveData(ws);
+
+	ws->writeUint16LE(_currentSnapEgg);
+	ws->writeUint16LE(_snapEggs.size());
+	for (Std::list<ObjId>::const_iterator iter = _snapEggs.begin();
+		 iter != _snapEggs.end(); iter++) {
+		ws->writeUint16LE(*iter);
+	}
+}
+
+bool SnapProcess::loadData(Common::ReadStream *rs, uint32 version) {
+	if (!Process::loadData(rs, version)) return false;
+
+	_currentSnapEgg = rs->readUint16LE();
+	uint16 numeggs = rs->readUint16LE();
+	for (int i = 0; i < numeggs; i++) {
+		_snapEggs.push_back(rs->readUint16LE());
+	}
+
+	return true;
+}
+
+SnapProcess *SnapProcess::get_instance() {
+	return _instance;
+}
+
+
+} // End of namespace Ultima8
+} // End of namespace Ultima
diff --git a/engines/ultima/ultima8/world/snap_process.h b/engines/ultima/ultima8/world/snap_process.h
new file mode 100644
index 0000000000..c6ee38b9ec
--- /dev/null
+++ b/engines/ultima/ultima8/world/snap_process.h
@@ -0,0 +1,66 @@
+/* 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_SNAPPROCESS_H
+#define ULTIMA8_WORLD_SNAPPROCESS_H
+
+#include "ultima/ultima8/kernel/process.h"
+#include "ultima/ultima8/misc/rect.h"
+
+namespace Ultima {
+namespace Ultima8 {
+
+class Item;
+
+class SnapProcess : public Process {
+public:
+	SnapProcess();
+
+	// p_dynamic_cast stuff
+	ENABLE_RUNTIME_CLASSTYPE()
+
+	void run() override;
+
+	bool loadData(Common::ReadStream *rs, uint32 version);
+	void saveData(Common::WriteStream *ws) override;
+
+	void addEgg(Item *item);
+	void removeEgg(Item *item);
+
+	static SnapProcess *get_instance();
+
+protected:
+	static SnapProcess *_instance;
+
+	void getSnapEggRange(const Item *egg, Rect &rect) const;
+	void updateCurrentEgg();
+	bool isNpcInRangeOfCurrentEgg() const;
+
+	ObjId   _currentSnapEgg;
+	Rect	_currentSnapEggRange;
+	Std::list<ObjId> _snapEggs;
+};
+
+} // End of namespace Ultima8
+} // End of namespace Ultima
+
+#endif




More information about the Scummvm-git-logs mailing list