Commit 0302767e authored by AlisterT's avatar AlisterT

Improved bridges and platform events.

parent db07689d
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
* Part of the OpenJazz project * Part of the OpenJazz project
* *
* *
* Copyright (c) 2005-2009 Alister Thomson * Copyright (c) 2005-2010 Alister Thomson
* *
* OpenJazz is distributed under the terms of * OpenJazz is distributed under the terms of
* the GNU General Public License, version 2.0 * the GNU General Public License, version 2.0
...@@ -62,9 +62,9 @@ ...@@ -62,9 +62,9 @@
#define F64 65536 #define F64 65536
#define F100 102400 #define F100 102400
#define F160 163840 #define F160 163840
#define F192 196608
// Files // Files
#define CONFIG_FILE "openjazz.cfg" #define CONFIG_FILE "openjazz.cfg"
#define LOGO_FILE "openjazz.000" #define LOGO_FILE "openjazz.000"
#define LEVEL_FILE "openjazz.tmp" #define LEVEL_FILE "openjazz.tmp"
......
...@@ -33,24 +33,25 @@ ...@@ -33,24 +33,25 @@
Bridge::Bridge (unsigned char gX, unsigned char gY, Event *nextEvent) { Bridge::Bridge (unsigned char gX, unsigned char gY, Event *nextEvent) {
signed char *set;
set = level->getEvent(gX, gY);
x = TTOF(gX); x = TTOF(gX);
y = TTOF(gY + 1); y = TTOF(gY) + ITOF(set[E_YAXIS]) - F8 - F1;
dx = 0; dx = 0;
dy = 0; dy = 0;
next = nextEvent; next = nextEvent;
gridX = gX; gridX = gX;
gridY = gY; gridY = gY;
flashTime = 0;
animType = E_LEFTANIM; animType = E_LEFTANIM;
x -= F2; flashTime = 0;
y += ITOF(getProperty(E_YAXIS)) - F40;
// dx and dy used to store leftmost and rightmost player on bridge // leftDipX and rightDipX used to store leftmost and rightmost player on bridge
// Start with minimum values // Start with minimum values
dx = getProperty(E_MULTIPURPOSE) * F8; leftDipX = set[E_MULTIPURPOSE] * set[E_BRIDGELENGTH] * F4;
dy = 0; rightDipX = 0;
return; return;
...@@ -61,7 +62,7 @@ bool Bridge::step (unsigned int ticks, int msps) { ...@@ -61,7 +62,7 @@ bool Bridge::step (unsigned int ticks, int msps) {
signed char *set; signed char *set;
int count; int count;
fixed offset; fixed bridgeLength, playerDipX, playerDipY;
set = prepareStep(ticks, msps); set = prepareStep(ticks, msps);
...@@ -69,34 +70,35 @@ bool Bridge::step (unsigned int ticks, int msps) { ...@@ -69,34 +70,35 @@ bool Bridge::step (unsigned int ticks, int msps) {
if (!set) return true; if (!set) return true;
bridgeLength = set[E_MULTIPURPOSE] * set[E_BRIDGELENGTH] * F4;
// Gradually stop the bridge sagging // Gradually stop the bridge sagging
if (dx < set[E_MULTIPURPOSE] * F8) dx += 320 * msps; if (leftDipX < bridgeLength) leftDipX += 320 * msps;
if (dx > set[E_MULTIPURPOSE] * F8) dx = set[E_MULTIPURPOSE] * F8; if (leftDipX > bridgeLength) leftDipX = bridgeLength;
if (dy > 0) dy -= 320 * msps; if (rightDipX > 0) rightDipX -= 320 * msps;
if (dy < 0) dy = 0; if (rightDipX < 0) rightDipX = 0;
for (count = 0; count < nPlayers; count++) { for (count = 0; count < nPlayers; count++) {
offset = players[count].getX() + PXO_MID; playerDipX = players[count].getX() + PXO_MID - x;
if (playerDipX < bridgeLength >> 1) playerDipY = playerDipX >> 3;
else playerDipY = (bridgeLength - playerDipX) >> 3;
if (players[count].overlap(x, y, set[E_MULTIPURPOSE] * F8, F8) && if (players[count].overlap(x, y + playerDipY - F4, bridgeLength, F8) &&
!level->checkMaskDown(offset, y - F32)) { !level->checkMaskDown(x + playerDipX, y + playerDipY - F32)) {
// Player is on the bridge // Player is on the bridge
players[count].setEvent(gridX, gridY); players[count].setEvent(gridX, gridY);
offset -= x; if (playerDipX < leftDipX) leftDipX = playerDipX;
if (offset < dx) dx = offset; if (playerDipX > rightDipX) rightDipX = playerDipX;
if ((offset > dy) && (offset < set[E_MULTIPURPOSE] * F8)) dy = offset; players[count].setPosition(players[count].getX(), y + playerDipY);
if (offset < set[E_MULTIPURPOSE] * F4)
players[count].setPosition(players[count].getX(), y + (offset >> 3) - F8);
else
players[count].setPosition(players[count].getX(), y + (set[E_MULTIPURPOSE] * F1) - (offset >> 3) - F8);
} else players[count].clearEvent(gridX, gridY); } else players[count].clearEvent(gridX, gridY);
...@@ -113,7 +115,7 @@ void Bridge::draw (unsigned int ticks, int change) { ...@@ -113,7 +115,7 @@ void Bridge::draw (unsigned int ticks, int change) {
Anim *anim; Anim *anim;
signed char *set; signed char *set;
int count; int count;
fixed bridgeLength, dipA, dipB; fixed bridgeLength, leftDipY, rightDipY;
// Get the event properties // Get the event properties
...@@ -127,12 +129,8 @@ void Bridge::draw (unsigned int ticks, int change) { ...@@ -127,12 +129,8 @@ void Bridge::draw (unsigned int ticks, int change) {
if (!animType || (set[animType] < 0)) return; if (!animType || (set[animType] < 0)) return;
if ((animType == E_LFINISHANIM) || (animType == E_RFINISHANIM)) if (set[E_ANIMSP]) frame = ticks / (set[E_ANIMSP] * 40);
frame = (ticks + T_FINISH - level->getEventTime(gridX, gridY)) / 40; else frame = ticks / 20;
else if (set[E_ANIMSP])
frame = ticks / (set[E_ANIMSP] * 40);
else
frame = ticks / 20;
anim = level->getAnim(set[animType]); anim = level->getAnim(set[animType]);
anim->setFrame(frame + gridX + gridY, true); anim->setFrame(frame + gridX + gridY, true);
...@@ -140,21 +138,21 @@ void Bridge::draw (unsigned int ticks, int change) { ...@@ -140,21 +138,21 @@ void Bridge::draw (unsigned int ticks, int change) {
// Draw the bridge // Draw the bridge
bridgeLength = set[E_MULTIPURPOSE] * F8; bridgeLength = set[E_MULTIPURPOSE] * set[E_BRIDGELENGTH] * F4;
if (dy >= dx) { if (rightDipX >= leftDipX) {
dipA = (dx <= (bridgeLength >> 1)) ? dx >> 3: (bridgeLength - dx) >> 3; leftDipY = (leftDipX <= (bridgeLength >> 1)) ? leftDipX >> 3: (bridgeLength - leftDipX) >> 3;
dipB = (dy <= (bridgeLength >> 1)) ? dy >> 3: (bridgeLength - dy) >> 3; rightDipY = (rightDipX <= (bridgeLength >> 1)) ? rightDipX >> 3: (bridgeLength - rightDipX) >> 3;
for (count = 0; count < bridgeLength; count += F8) { for (count = 0; count < bridgeLength; count += F4 * set[E_BRIDGELENGTH]) {
if (count < dx) if (count < leftDipX)
anim->draw(x + count, y + (count * dipA / dx)); anim->draw(x + count, y + (count * leftDipY / leftDipX));
else if (count < dy) else if (count < dy)
anim->draw(x + count, y + dipA + ((count - dx) * (dipB - dipA) / (dy - dx))); anim->draw(x + count, y + leftDipY + ((count - leftDipX) * (rightDipY - leftDipY) / (rightDipX - leftDipX)));
else else
anim->draw(x + count, y + ((bridgeLength - count) * dipB / (bridgeLength - dy))); anim->draw(x + count, y + ((bridgeLength - count) * rightDipY / (bridgeLength - rightDipX)));
} }
...@@ -162,15 +160,18 @@ void Bridge::draw (unsigned int ticks, int change) { ...@@ -162,15 +160,18 @@ void Bridge::draw (unsigned int ticks, int change) {
// No players on the bridge, de-sagging in progress // No players on the bridge, de-sagging in progress
dipA = (dx + dy) >> 1; // Midpoint
dipB = (dy < bridgeLength - dx) ? dy >> 3: (bridgeLength - dx) >> 3; leftDipY = (leftDipX + rightDipX) >> 1;
// Dip
rightDipY = (rightDipX < bridgeLength - leftDipX) ? rightDipX >> 3: (bridgeLength - leftDipX) >> 3;
for (count = 0; count < bridgeLength; count += F8) { for (count = 0; count < bridgeLength; count += F4 * set[E_BRIDGELENGTH]) {
if (count < dipA) if (count < leftDipY)
anim->draw(x + count, y + (count * dipB / dipA)); anim->draw(x + count, y + (count * rightDipY / leftDipY));
else else
anim->draw(x + count, y + ((bridgeLength - count) * dipB / (bridgeLength - dipA))); anim->draw(x + count, y + ((bridgeLength - count) * rightDipY / (bridgeLength - leftDipY)));
} }
......
...@@ -110,6 +110,10 @@ class Event : public Movable { ...@@ -110,6 +110,10 @@ class Event : public Movable {
class Bridge : public Event { class Bridge : public Event {
private:
fixed leftDipX;
fixed rightDipX;
public: public:
Bridge (unsigned char gX, unsigned char gY, Event *nextEvent); Bridge (unsigned char gX, unsigned char gY, Event *nextEvent);
......
...@@ -60,7 +60,7 @@ signed char * Event::prepareStep (unsigned int ticks, int msps) { ...@@ -60,7 +60,7 @@ signed char * Event::prepareStep (unsigned int ticks, int msps) {
// If the event and its origin are off-screen, the event is not in the // If the event and its origin are off-screen, the event is not in the
// process of self-destruction, remove it // process of self-destruction, remove it
if ((animType != E_LFINISHANIM) && (animType != E_RFINISHANIM) && if ((animType != E_LFINISHANIM) && (animType != E_RFINISHANIM) &&
((x < viewX - F160) || (x > viewX + ITOF(viewW) + F160) || ((x < viewX - F192) || (x > viewX + ITOF(viewW) + F192) ||
(y < viewY - F160) || (y > viewY + ITOF(viewH) + F160)) && (y < viewY - F160) || (y > viewY + ITOF(viewH) + F160)) &&
((gridX < FTOT(viewX) - 1) || ((gridX < FTOT(viewX) - 1) ||
(gridX > ITOT(FTOI(viewX) + viewW) + 1) || (gridX > ITOT(FTOI(viewX) + viewW) + 1) ||
...@@ -879,7 +879,9 @@ bool Event::step (unsigned int ticks, int msps) { ...@@ -879,7 +879,9 @@ bool Event::step (unsigned int ticks, int msps) {
// Player is on a platform // Player is on a platform
players[count].setEvent(gridX, gridY); players[count].setEvent(gridX, gridY);
players[count].setPosition(players[count].getX() + ((dx * msps) >> 10), y - height); players[count].setPosition(
players[count].getX() + ((dx * msps) >> 10),
players[count].getY() + ((dy * msps) >> 10));
} else players[count].clearEvent(gridX, gridY); } else players[count].clearEvent(gridX, gridY);
......
...@@ -663,12 +663,11 @@ bool Player::isOnPlatform () { ...@@ -663,12 +663,11 @@ bool Player::isOnPlatform () {
return return
(event >= 3) || (event >= 3) ||
level->checkMaskDown(x + PXO_ML, y + F2) || level->checkMaskDown(x + PXO_ML, y + 1) ||
level->checkMaskDown(x + PXO_MID, y + F2) || level->checkMaskDown(x + PXO_MID, y + 1) ||
level->checkMaskDown(x + PXO_MR, y + F2) || level->checkMaskDown(x + PXO_MR, y + 1) ||
level->checkMaskDown(x + PXO_ML, y + F8) || ((dx > 0) && level->checkMaskDown(x + PXO_ML, y + F8)) ||
level->checkMaskDown(x + PXO_MID, y + F8) || ((dx < 0) && level->checkMaskDown(x + PXO_MR, y + F8));
level->checkMaskDown(x + PXO_MR, y + F8);
} }
......
...@@ -252,6 +252,9 @@ void Player::control (unsigned int ticks, int msps) { ...@@ -252,6 +252,9 @@ void Player::control (unsigned int ticks, int msps) {
} }
// Don't descend through platforms
if ((dy > 0) && (event >= 3)) dy = 0;
if (platform && !lookTime) { if (platform && !lookTime) {
// If requested, look up or down // If requested, look up or down
...@@ -713,15 +716,18 @@ void Player::draw (unsigned int ticks, int change) { ...@@ -713,15 +716,18 @@ void Player::draw (unsigned int ticks, int change) {
// Uncomment the following to see the area of the player // Uncomment the following to see the area of the player
/*drawRect(FTOI(getDrawX(change) + PXO_L - viewX), /*drawRect(FTOI(drawX + PXO_L - viewX),
FTOI(getDrawY(change) + PYO_TOP - viewY), FTOI(drawY + PYO_TOP - viewY),
FTOI(PXO_R - PXO_L), FTOI(PXO_R - PXO_L),
FTOI(-PYO_TOP), 89); FTOI(-PYO_TOP), 89);
drawRect(FTOI(getDrawX(change) + PXO_ML - viewX), drawRect(FTOI(drawX + PXO_ML - viewX),
FTOI(getDrawY(change) + PYO_TOP - viewY), FTOI(drawY + PYO_TOP - viewY),
FTOI(PXO_MR - PXO_ML), FTOI(PXO_MR - PXO_ML),
FTOI(-PYO_TOP), 88);*/ FTOI(-PYO_TOP), 88);*/
// Uncomment the following to show the player's event tile
// if (event) drawRect(FTOI(TTOF(eventX) - viewX), FTOI(TTOF(eventY) - viewY), 32, 32, 89);
if (reaction == PR_INVINCIBLE) { if (reaction == PR_INVINCIBLE) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment