summaryrefslogtreecommitdiff
path: root/src/uqm/gravity.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/uqm/gravity.c')
-rw-r--r--src/uqm/gravity.c200
1 files changed, 200 insertions, 0 deletions
diff --git a/src/uqm/gravity.c b/src/uqm/gravity.c
new file mode 100644
index 0000000..5a7899c
--- /dev/null
+++ b/src/uqm/gravity.c
@@ -0,0 +1,200 @@
+//Copyright Paul Reiche, Fred Ford. 1992-2002
+
+/*
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "collide.h"
+#include "races.h"
+#include "units.h"
+#include "libs/log.h"
+
+//#define DEBUG_GRAVITY
+
+BOOLEAN
+CalculateGravity (ELEMENT *ElementPtr)
+{
+ BOOLEAN retval, HasGravity;
+ HELEMENT hTestElement, hSuccElement;
+
+ retval = FALSE;
+ HasGravity = (BOOLEAN)(CollidingElement (ElementPtr)
+ && GRAVITY_MASS (ElementPtr->mass_points + 1));
+ for (hTestElement = GetHeadElement ();
+ hTestElement != 0; hTestElement = hSuccElement)
+ {
+ BOOLEAN TestHasGravity;
+ ELEMENT *TestElementPtr;
+
+ LockElement (hTestElement, &TestElementPtr);
+ if (TestElementPtr != ElementPtr
+ && CollidingElement (TestElementPtr)
+ && (TestHasGravity =
+ GRAVITY_MASS (TestElementPtr->mass_points + 1)) != HasGravity)
+ {
+ COUNT abs_dx, abs_dy;
+ SIZE dx, dy;
+
+ if (!(ElementPtr->state_flags & PRE_PROCESS))
+ {
+ dx = ElementPtr->current.location.x
+ - TestElementPtr->current.location.x;
+ dy = ElementPtr->current.location.y
+ - TestElementPtr->current.location.y;
+ }
+ else
+ {
+ dx = ElementPtr->next.location.x
+ - TestElementPtr->next.location.x;
+ dy = ElementPtr->next.location.y
+ - TestElementPtr->next.location.y;
+ }
+#ifdef DEBUG_GRAVITY
+ if (TestElementPtr->state_flags & PLAYER_SHIP)
+ {
+ log_add (log_Debug, "CalculateGravity:");
+ log_add (log_Debug, "\tdx = %d, dy = %d", dx, dy);
+ }
+#endif /* DEBUG_GRAVITY */
+ dx = WRAP_DELTA_X (dx);
+ dy = WRAP_DELTA_Y (dy);
+#ifdef DEBUG_GRAVITY
+ if (TestElementPtr->state_flags & PLAYER_SHIP)
+ log_add (log_Debug, "\twrap_dx = %d, wrap_dy = %d", dx, dy);
+#endif /* DEBUG_GRAVITY */
+ abs_dx = dx >= 0 ? dx : -dx;
+ abs_dy = dy >= 0 ? dy : -dy;
+ abs_dx = WORLD_TO_DISPLAY (abs_dx);
+ abs_dy = WORLD_TO_DISPLAY (abs_dy);
+#ifdef DEBUG_GRAVITY
+ if (TestElementPtr->state_flags & PLAYER_SHIP)
+ log_add (log_Debug, "\tdisplay_dx = %d, display_dy = %d",
+ abs_dx, abs_dy);
+#endif /* DEBUG_GRAVITY */
+ if (abs_dx <= GRAVITY_THRESHOLD
+ && abs_dy <= GRAVITY_THRESHOLD)
+ {
+ DWORD dist_squared;
+
+ dist_squared = (DWORD)(abs_dx * abs_dx)
+ + (DWORD)(abs_dy * abs_dy);
+ if (dist_squared <= (DWORD)(GRAVITY_THRESHOLD
+ * GRAVITY_THRESHOLD))
+ {
+#ifdef NEVER
+ COUNT magnitude;
+
+#define DIFUSE_GRAVITY 175
+ dist_squared += (DWORD)abs_dx * (DIFUSE_GRAVITY << 1)
+ + (DWORD)abs_dy * (DIFUSE_GRAVITY << 1)
+ + ((DWORD)(DIFUSE_GRAVITY * DIFUSE_GRAVITY) << 1);
+ if ((magnitude = (COUNT)((DWORD)(GRAVITY_THRESHOLD
+ * GRAVITY_THRESHOLD) / dist_squared)) == 0)
+ magnitude = 1;
+
+#define MAX_MAGNITUDE 6
+ else if (magnitude > MAX_MAGNITUDE)
+ magnitude = MAX_MAGNITUDE;
+ log_add (log_Debug, "magnitude = %u", magnitude);
+#endif /* NEVER */
+
+#ifdef DEBUG_GRAVITY
+ if (TestElementPtr->state_flags & PLAYER_SHIP)
+ log_add (log_Debug, "dist_squared = %lu", dist_squared);
+#endif /* DEBUG_GRAVITY */
+ if (TestHasGravity)
+ {
+ retval = TRUE;
+ UnlockElement (hTestElement);
+ break;
+ }
+ else
+ {
+ COUNT angle;
+
+ angle = ARCTAN (dx, dy);
+ DeltaVelocityComponents (&TestElementPtr->velocity,
+ COSINE (angle, WORLD_TO_VELOCITY (1)),
+ SINE (angle, WORLD_TO_VELOCITY (1)));
+ if (TestElementPtr->state_flags & PLAYER_SHIP)
+ {
+ STARSHIP *StarShipPtr;
+
+ GetElementStarShip (TestElementPtr, &StarShipPtr);
+ StarShipPtr->cur_status_flags &= ~SHIP_AT_MAX_SPEED;
+ StarShipPtr->cur_status_flags |= SHIP_IN_GRAVITY_WELL;
+ }
+ }
+ }
+ }
+ }
+
+ hSuccElement = GetSuccElement (TestElementPtr);
+ UnlockElement (hTestElement);
+ }
+
+ return (retval);
+}
+
+BOOLEAN
+TimeSpaceMatterConflict (ELEMENT *ElementPtr)
+{
+ HELEMENT hTestElement, hSuccElement;
+ INTERSECT_CONTROL ElementControl;
+
+ ElementControl.IntersectStamp.origin.x =
+ WORLD_TO_DISPLAY (ElementPtr->current.location.x);
+ ElementControl.IntersectStamp.origin.y =
+ WORLD_TO_DISPLAY (ElementPtr->current.location.y);
+ ElementControl.IntersectStamp.frame =
+ SetEquFrameIndex (ElementPtr->current.image.farray[0],
+ ElementPtr->current.image.frame);
+ ElementControl.EndPoint = ElementControl.IntersectStamp.origin;
+ for (hTestElement = GetHeadElement ();
+ hTestElement != 0; hTestElement = hSuccElement)
+ {
+ ELEMENT *TestElementPtr;
+
+ LockElement (hTestElement, &TestElementPtr);
+ hSuccElement = GetSuccElement (TestElementPtr);
+ if (TestElementPtr != ElementPtr
+ && (CollidingElement (TestElementPtr)
+ /* ship in transition */
+ || (TestElementPtr->state_flags & PLAYER_SHIP)))
+ {
+ INTERSECT_CONTROL TestElementControl;
+
+ TestElementControl.IntersectStamp.origin.x =
+ WORLD_TO_DISPLAY (TestElementPtr->current.location.x);
+ TestElementControl.IntersectStamp.origin.y =
+ WORLD_TO_DISPLAY (TestElementPtr->current.location.y);
+ TestElementControl.IntersectStamp.frame =
+ SetEquFrameIndex (TestElementPtr->current.image.farray[0],
+ TestElementPtr->current.image.frame);
+ TestElementControl.EndPoint = TestElementControl.IntersectStamp.origin;
+ if (DrawablesIntersect (&ElementControl,
+ &TestElementControl, MAX_TIME_VALUE))
+ {
+ UnlockElement (hTestElement);
+
+ break;
+ }
+ }
+ UnlockElement (hTestElement);
+ }
+
+ return (hTestElement != 0 ? TRUE : FALSE);
+}
+