[Scummvm-git-logs] scummvm master -> 2cf53816ccbe720777e49cd273a7d074dc734fcd

mduggan mgithub at guarana.org
Sat Jul 31 03:57:40 UTC 2021


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:
2cf53816cc ULTIMA8: Alert nearby NPCs when Crusader weapons fires


Commit: 2cf53816ccbe720777e49cd273a7d074dc734fcd
    https://github.com/scummvm/scummvm/commit/2cf53816ccbe720777e49cd273a7d074dc734fcd
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2021-07-31T12:56:24+09:00

Commit Message:
ULTIMA8: Alert nearby NPCs when Crusader weapons fires

This is a feature from the original that somehow I missed.  Finally
non-soldiers will properly surrender when you fire your weapon near them.

Changed paths:
    engines/ultima/ultima8/world/actors/cru_avatar_mover_process.cpp
    engines/ultima/ultima8/world/actors/cru_avatar_mover_process.h


diff --git a/engines/ultima/ultima8/world/actors/cru_avatar_mover_process.cpp b/engines/ultima/ultima8/world/actors/cru_avatar_mover_process.cpp
index f4c51a95f2..5041d205c3 100644
--- a/engines/ultima/ultima8/world/actors/cru_avatar_mover_process.cpp
+++ b/engines/ultima/ultima8/world/actors/cru_avatar_mover_process.cpp
@@ -39,7 +39,7 @@ DEFINE_RUNTIME_CLASSTYPE_CODE(CruAvatarMoverProcess)
 static const int REBEL_BASE_MAP = 40;
 
 CruAvatarMoverProcess::CruAvatarMoverProcess() : AvatarMoverProcess(),
-_avatarAngle(-1), _SGA1Loaded(false), _nextFireTick(0) {
+_avatarAngle(-1), _SGA1Loaded(false), _nextFireTick(0), _lastNPCAlertTick(0) {
 }
 
 
@@ -592,6 +592,9 @@ void CruAvatarMoverProcess::tryAttack() {
 				avatar->setMana(avatar->getMana() - wpninfo->_energyUse);
 			}
 
+			// Check if we should alert nearby NPCs
+			checkForAlertingNPCs();
+
 			if (wpninfo->_shotDelay) {
 				_nextFireTick = kernel->getTickNum() + wpninfo->_shotDelay;
 			} else {
@@ -601,10 +604,59 @@ void CruAvatarMoverProcess::tryAttack() {
 	}
 }
 
+void CruAvatarMoverProcess::checkForAlertingNPCs() {
+	uint32 nowtick = Kernel::get_instance()->getTickNum();
+	if (nowtick - _lastNPCAlertTick < 240)
+		return;
+
+	_lastNPCAlertTick = nowtick;
+	uint16 controllednpc = World::get_instance()->getControlledNPCNum();
+	for (int i = 2; i < 256; i++) {
+		if (i == controllednpc)
+			continue;
+
+		Actor *a = getActor(i);
+		if (!a || a->isDead() || !a->isOnScreen())
+			continue;
+
+		if (!a->isInCombat()) {
+			uint16 currentactivity = a->getCurrentActivityNo();
+			uint16 activity2 = a->getDefaultActivity(2);
+			if (currentactivity == activity2) {
+				// note: original game also seems to check surrendering flag here?
+				if (currentactivity == 8) {
+					// Was guarding, attack!
+					a->setActivity(5);
+				}
+			} else {
+				uint16 range = 0;
+				uint32 npcshape = a->getShape();
+				if (npcshape == 0x2f5 || npcshape == 0x2f6 || npcshape == 0x2f7 ||
+					npcshape == 0x595 || npcshape == 0x597) {
+					Actor *c = getActor(controllednpc);
+					if (c)
+						range = a->getRangeIfVisible(*c);
+				} else {
+					range = 1;
+				}
+				if (range) {
+					a->setActivity(a->getDefaultActivity(2));
+				}
+			}
+		} else {
+			// Was guarding, attack!
+			a->setActivity(5);
+		}
+	}
+}
+
 void CruAvatarMoverProcess::saveData(Common::WriteStream *ws) {
 	AvatarMoverProcess::saveData(ws);
 	ws->writeSint32LE(_avatarAngle);
 	ws->writeByte(_SGA1Loaded ? 1 : 0);
+
+	// We don't bother saving _lastNPCAlertTick or _nextFireTick, they both
+	// will get reset to 0 which will behave almost identically in practice.
 }
 
 bool CruAvatarMoverProcess::loadData(Common::ReadStream *rs, uint32 version) {
diff --git a/engines/ultima/ultima8/world/actors/cru_avatar_mover_process.h b/engines/ultima/ultima8/world/actors/cru_avatar_mover_process.h
index 9fab0688a7..1df6579db5 100644
--- a/engines/ultima/ultima8/world/actors/cru_avatar_mover_process.h
+++ b/engines/ultima/ultima8/world/actors/cru_avatar_mover_process.h
@@ -54,6 +54,9 @@ private:
 	/** Try readying or firing weapon. */
 	void tryAttack();
 
+	/** Check if we need to alert NPCs after firing. */
+	void checkForAlertingNPCs();
+
 	/**
 	* Angle of avatar in centidegrees (1/100deg).  The original game runs the keyboard
 	* process 45 times per second and rotates the crosshair by 2 (regular) or
@@ -72,6 +75,11 @@ private:
 	 */
 	uint32 _nextFireTick;
 
+	/**
+	 * Last time we alerted NPCs on a shot.
+	 */
+	uint32 _lastNPCAlertTick;
+
 	void handleHangingMode() override;
 	void handleCombatMode() override;
 	void handleNormalMode() override;




More information about the Scummvm-git-logs mailing list