GliderPRO/Sources/RubberBands.c

1 line
7.8 KiB
C
Executable File

//============================================================================
//----------------------------------------------------------------------------
// RubberBands.c
//----------------------------------------------------------------------------
//============================================================================
#include "Externs.h"
#include "RectUtils.h"
#define kRubberBandVelocity 20
#define kBandFallCount 4
#define kKillBandMode -1
void CheckBandCollision (short);
void KillBand (short);
bandPtr bands;
Rect bandsSrcRect;
Rect bandRects[3];
GWorldPtr bandsSrcMap;
GWorldPtr bandsMaskMap;
short numBands, bandHitLast;
extern hotPtr hotSpots;
extern long gameFrame;
extern short nHotSpots, leftThresh, rightThresh;
extern Boolean twoPlayerGame, onePlayerLeft, playerDead;
//============================================================== Functions
//-------------------------------------------------------------- CheckBandCollision
void CheckBandCollision (short who)
{
short i, action, whoLinked;
Boolean collided, nothingCollided;
nothingCollided = true;
if ((leftThresh == kLeftWallLimit) && (bands[who].dest.left < kLeftWallLimit))
{
if (bands[who].hVel < 0)
bands[who].hVel = -bands[who].hVel;
bands[who].dest.left = kLeftWallLimit;
bands[who].dest.right = bands[who].dest.left + 16;
PlayPrioritySound(kBandReboundSound, kBandReboundPriority);
collided = true;
}
else if ((rightThresh == kRightWallLimit) && (bands[who].dest.right > kRightWallLimit))
{
if (bands[who].hVel > 0)
bands[who].hVel = -bands[who].hVel;
bands[who].dest.right = kRightWallLimit;
bands[who].dest.left = bands[who].dest.right - 16;
PlayPrioritySound(kBandReboundSound, kBandReboundPriority);
collided = true;
}
for (i = 0; i < nHotSpots; i++)
{
if (hotSpots[i].isOn)
{
action = hotSpots[i].action;
if ((action == kDissolveIt) || (action == kRewardIt) ||
(action == kSwitchIt) || (action == kTriggerIt) ||
(action == kBounceIt))
{
if (bands[who].dest.bottom < hotSpots[i].bounds.top)
collided = false;
else if (bands[who].dest.top > hotSpots[i].bounds.bottom)
collided = false;
else if (bands[who].dest.right < hotSpots[i].bounds.left)
collided = false;
else if (bands[who].dest.left > hotSpots[i].bounds.right)
collided = false;
else
collided = true;
if (collided)
{
nothingCollided = false; // we have detected a collision
if (bandHitLast != i) // don't count it if same as last frame
{ // we don't want rapid on/off toggles
bandHitLast = i; // note who so we don't double-toggle it
if ((action == kDissolveIt) || (action == kBounceIt))
{
if (bands[who].hVel > 0)
{
if ((bands[who].dest.right - bands[who].hVel) <
hotSpots[i].bounds.left)
{
bands[who].hVel = -bands[who].hVel;
bands[who].dest.right = hotSpots[i].bounds.left;
bands[who].dest.left = bands[who].dest.right - 16;
}
else
bands[who].mode = kKillBandMode;
}
else
{
if ((bands[who].dest.left - bands[who].hVel) >
hotSpots[i].bounds.right)
{
bands[who].hVel = -bands[who].hVel;
bands[who].dest.left = hotSpots[i].bounds.right;
bands[who].dest.right = bands[who].dest.left + 16;
}
else
bands[who].mode = kKillBandMode;
}
PlayPrioritySound(kBandReboundSound, kBandReboundPriority);
break;
}
else if (action == kRewardIt)
{
whoLinked = hotSpots[i].who;
if ((masterObjects[whoLinked].theObject.what == kGreaseRt) ||
(masterObjects[whoLinked].theObject.what == kGreaseLf))
{
if (SetObjectState(thisRoomNumber,
masterObjects[whoLinked].objectNum, 0, whoLinked))
SpillGrease(masterObjects[whoLinked].dynaNum,
masterObjects[whoLinked].hotNum);
hotSpots[i].isOn = false;
}
}
else if (action == kSwitchIt)
{
HandleSwitches(&hotSpots[i]);
}
else if (action == kTriggerIt)
{
ArmTrigger(&hotSpots[i]);
}
}
}
}
}
}
if (nothingCollided) // the rubberband has hit nothing
bandHitLast = -1; // so make note of that for the next time
if (bands[who].hVel != 0)
{
if (bands[who].dest.bottom < theGlider.dest.top)
collided = false;
else if (bands[who].dest.top > theGlider.dest.bottom)
collided = false;
else if (bands[who].dest.right < theGlider.dest.left)
collided = false;
else if (bands[who].dest.left > theGlider.dest.right)
collided = false;
else
collided = true;
if (collided)
{
if ((!twoPlayerGame) || (!onePlayerLeft) || (playerDead == kPlayer2))
{
theGlider.hVel += (bands[who].hVel / 2);
bands[who].hVel = 0;
PlayPrioritySound(kHitWallSound, kHitWallPriority);
}
}
if (twoPlayerGame)
{
if (bands[who].dest.bottom < theGlider2.dest.top)
collided = false;
else if (bands[who].dest.top > theGlider2.dest.bottom)
collided = false;
else if (bands[who].dest.right < theGlider2.dest.left)
collided = false;
else if (bands[who].dest.left > theGlider2.dest.right)
collided = false;
else
collided = true;
if (collided)
{
if ((!onePlayerLeft) || (playerDead == kPlayer1))
{
theGlider2.hVel += (bands[who].hVel / 2);
bands[who].hVel = 0;
PlayPrioritySound(kHitWallSound, kHitWallPriority);
}
}
}
}
if ((bands[who].dest.left < kLeftWallLimit) ||
(bands[who].dest.right > kRightWallLimit))
{
bands[who].mode = kKillBandMode;
}
else if (bands[who].dest.bottom > kFloorLimit)
{
bands[who].mode = kKillBandMode;
}
}
//-------------------------------------------------------------- HandleBands
void HandleBands (void)
{
Rect dest;
short i, count;
if (numBands == 0)
return;
for (i = 0; i < numBands; i++)
{
bands[i].mode++;
if (bands[i].mode > 2)
bands[i].mode = 0;
bands[i].count++;
if (bands[i].count >= kBandFallCount)
{
bands[i].vVel++;
bands[i].count = 0;
}
dest = bands[i].dest;
QOffsetRect(&dest, playOriginH, playOriginV);
AddRectToWorkRects(&dest);
bands[i].dest.left += bands[i].hVel;
bands[i].dest.right += bands[i].hVel;
bands[i].dest.top += bands[i].vVel;
bands[i].dest.bottom += bands[i].vVel;
CheckBandCollision(i);
}
count = 0;
do
{
while (bands[count].mode == kKillBandMode)
{
bands[count].mode = 0;
KillBand(count);
}
count++;
}
while (count < numBands);
}
//-------------------------------------------------------------- AddBand
Boolean AddBand (gliderPtr thisGlider, short h, short v, Boolean direction)
{
if (numBands >= kMaxRubberBands)
return (false);
bands[numBands].mode = 0;
bands[numBands].count = 0;
if (thisGlider->tipped)
bands[numBands].vVel = -2;
else
bands[numBands].vVel = 0;
bands[numBands].dest.left = h - 8;
bands[numBands].dest.right = h + 8;
bands[numBands].dest.top = v - 3;
bands[numBands].dest.bottom = v + 3;
if (direction == kFaceLeft)
{
bands[numBands].dest.left -= 32;
bands[numBands].dest.right -= 32;
bands[numBands].hVel = -kRubberBandVelocity;
}
else
{
bands[numBands].dest.left += 32;
bands[numBands].dest.right += 32;
bands[numBands].hVel = kRubberBandVelocity;
}
thisGlider->hVel -= (bands[numBands].hVel / 2);
numBands++;
PlayPrioritySound(kFireBandSound, kFireBandPriority);
return (true);
}
//-------------------------------------------------------------- KillBand
void KillBand (short which)
{
short lastBand;
lastBand = numBands - 1;
if (which != lastBand)
bands[which] = bands[lastBand];
numBands--;
}
//-------------------------------------------------------------- KillAllBands
void KillAllBands (void)
{
short i;
for (i = 0; i < kMaxRubberBands; i++)
{
bands[i].mode = 0;
}
numBands = 0;
}