201 lines
5.9 KiB
C
201 lines
5.9 KiB
C
//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);
|
|
}
|
|
|