[Scummvm-git-logs] scummvm master -> 4af3e8ee79508a2e74d49f73da4e5b07d0c0e4c0

neuromancer noreply at scummvm.org
Sun Nov 13 23:07:20 UTC 2022


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:
4af3e8ee79 FREESCAPE: check collision now executes the conditions in each object collided, instead of the smaller one


Commit: 4af3e8ee79508a2e74d49f73da4e5b07d0c0e4c0
    https://github.com/scummvm/scummvm/commit/4af3e8ee79508a2e74d49f73da4e5b07d0c0e4c0
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-14T00:06:31+01:00

Commit Message:
FREESCAPE: check collision now executes the conditions in each object collided, instead of the smaller one

Changed paths:
    engines/freescape/area.cpp
    engines/freescape/area.h
    engines/freescape/games/driller.cpp
    engines/freescape/movement.cpp


diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 100db3d1320..6642e68b129 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -178,16 +178,13 @@ Object *Area::shootRay(const Math::Ray &ray) {
 	return collided;
 }
 
-Object *Area::checkCollisions(const Math::AABB &boundingBox) {
-	float size = 3.0 * 8192.0 * 8192.0; // TODO: check if this is max size
-	Object *collided = nullptr;
+ObjectArray Area::checkCollisions(const Math::AABB &boundingBox) {
+	ObjectArray collided;
 	for (auto &obj : _drawableObjects) {
 		if (!obj->isDestroyed() && !obj->isInvisible()) {
 			GeometricObject *gobj = (GeometricObject *)obj;
-			float objSize = gobj->getSize().length();
-			if (gobj->collides(boundingBox) && size > objSize) {
-				collided = gobj;
-				size = objSize;
+			if (gobj->collides(boundingBox)) {
+				collided.push_back(gobj);
 			}
 		}
 	}
diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index 3053736bb45..d4af67b095d 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -34,7 +34,7 @@
 namespace Freescape {
 
 typedef Common::HashMap<uint16, Object *> ObjectMap;
-
+typedef Common::Array<Object *> ObjectArray;
 class Area {
 public:
 	Area(uint16 areaID, uint16 areaFlags, ObjectMap *objectsByID, ObjectMap *entrancesByID);
@@ -50,7 +50,7 @@ public:
 	void show();
 
 	Object *shootRay(const Math::Ray &ray);
-	Object *checkCollisions(const Math::AABB &boundingBox);
+	ObjectArray checkCollisions(const Math::AABB &boundingBox);
 	void addObjectFromArea(int16 id, Area *global);
 	void addObject(Object *obj);
 	void addStructure(Area *global);
@@ -76,7 +76,7 @@ private:
 	uint16 _areaFlags;
 	ObjectMap *_objectsByID;
 	ObjectMap *_entrancesByID;
-	Common::Array<Object *> _drawableObjects;
+	ObjectArray _drawableObjects;
 	ObjectMap _addedObjects;
 	Object *objectWithIDFromMap(ObjectMap *map, uint16 objectID);
 };
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 2c6ddb9e37b..194f806befe 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -551,7 +551,7 @@ bool DrillerEngine::checkDrill(const Math::Vector3d position) {
 
 	obj = (GeometricObject *)obj->duplicate();
 	obj->setOrigin(origin);
-	if (_currentArea->checkCollisions(obj->_boundingBox))
+	if (!_currentArea->checkCollisions(obj->_boundingBox).empty())
 		return false;
 
 	// Undo offset
@@ -571,7 +571,7 @@ bool DrillerEngine::checkDrill(const Math::Vector3d position) {
 	origin.setValue(2, origin.z() + obj->getSize().z() / 5);
 
 	obj->setOrigin(origin);
-	if (_currentArea->checkCollisions(obj->_boundingBox))
+	if (!_currentArea->checkCollisions(obj->_boundingBox).empty())
 		return false;
 
 	// Undo offset
@@ -589,7 +589,7 @@ bool DrillerEngine::checkDrill(const Math::Vector3d position) {
 	obj->setOrigin(origin);
 	assert(obj);
 
-	if (_currentArea->checkCollisions(obj->_boundingBox))
+	if (!_currentArea->checkCollisions(obj->_boundingBox).empty())
 		return false;
 
 	delete obj;
diff --git a/engines/freescape/movement.cpp b/engines/freescape/movement.cpp
index 3753991e539..6338c4770f3 100644
--- a/engines/freescape/movement.cpp
+++ b/engines/freescape/movement.cpp
@@ -290,23 +290,34 @@ bool FreescapeEngine::checkCollisions(bool executeCode) {
 		return false;
 	Math::AABB boundingBox(_lastPosition, _lastPosition);
 
-	Math::Vector3d v1(_position.x() - 1, _position.y() - _playerHeight, _position.z() - 1);
-	Math::Vector3d v2(_position.x() + 1, _position.y() + 1, _position.z() + 1);
+	Math::Vector3d v1(_position.x() + 1, _position.y() + 1, _position.z() + 1);
+	Math::Vector3d v2(_position.x() - 1, _position.y() - _playerHeight, _position.z() - 1);
 
 	boundingBox.expand(v1);
 	boundingBox.expand(v2);
-	Object *obj = _currentArea->checkCollisions(boundingBox);
+	ObjectArray objs = _currentArea->checkCollisions(boundingBox);
+	bool collided = !objs.empty();
 
-	if (obj != nullptr) {
-		debugC(1, kFreescapeDebugMove, "Collided with object id %d of size %f %f %f", obj->getObjectID(), obj->getSize().x(), obj->getSize().y(), obj->getSize().z());
-		GeometricObject *gobj = (GeometricObject *)obj;
-		if (!executeCode) // Avoid executing code
-			return true;
+	// If we don't need to execute code, we can finish here
+	if (!executeCode) {
+		return collided;
+	}
+
+	// If we need to execute code, we need to make sure the bounding box touches the floor
+	// so we will expand it and re-run the collision checking
+	uint tolerance = 1;
+	Math::Vector3d v3(_position.x() - 1, _position.y() - _playerHeight - tolerance, _position.z() - 1);
+	boundingBox.expand(v3);
 
+	objs = _currentArea->checkCollisions(boundingBox);
+	for (auto &obj : objs) {
+		GeometricObject *gobj = (GeometricObject *)obj;
+		debugC(1, kFreescapeDebugMove, "Collided with object id %d of size %f %f %f", gobj->getObjectID(), gobj->getSize().x(), gobj->getSize().y(), gobj->getSize().z());
 		executeObjectConditions(gobj, false, true);
-		return true;
 	}
-	return false;
+	// We still need to return the original result, not the collision using the expanded bounding box
+	// This will avoid detecting the floor constantly
+	return collided;
 }
 
 } // namespace Freescape




More information about the Scummvm-git-logs mailing list