Commit 9f852ec3 authored by alistert's avatar alistert

Split Player class into three.

parent 49cf32fa
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include "io/sound.h" #include "io/sound.h"
#include "menu/menu.h" #include "menu/menu.h"
#include "player/player.h" #include "player/player.h"
#include "player/bonusplayer.h"
#include "loop.h" #include "loop.h"
#include "util.h" #include "util.h"
...@@ -276,7 +277,7 @@ Bonus::Bonus (char * fileName, unsigned char diff) { ...@@ -276,7 +277,7 @@ Bonus::Bonus (char * fileName, unsigned char diff) {
for (count = 0; count < PANIMS; count++) string[count] = count & 31; for (count = 0; count < PANIMS; count++) string[count] = count & 31;
for (count = 0; count < nPlayers; count++) players[count].setAnims(string); for (count = 0; count < nPlayers; count++) players[count].getBonusPlayer()->setAnims(string);
delete[] string; delete[] string;
...@@ -347,7 +348,7 @@ Bonus::Bonus (char * fileName, unsigned char diff) { ...@@ -347,7 +348,7 @@ Bonus::Bonus (char * fileName, unsigned char diff) {
} else { } else {
localPlayer->reset(); localPlayer->reset();
localPlayer->setPosition(TTOF(x) + F16, TTOF(y) + F16); localPlayer->getBonusPlayer()->setPosition(TTOF(x), TTOF(y));
} }
...@@ -415,6 +416,7 @@ bool Bonus::checkMask (fixed x, fixed y) { ...@@ -415,6 +416,7 @@ bool Bonus::checkMask (fixed x, fixed y) {
int Bonus::step () { int Bonus::step () {
BonusPlayer* bonusPlayer;
fixed playerX, playerY; fixed playerX, playerY;
int gridX, gridY; int gridX, gridY;
int msps; int msps;
...@@ -436,10 +438,12 @@ int Bonus::step () { ...@@ -436,10 +438,12 @@ int Bonus::step () {
// Process players // Process players
for (count = 0; count < nPlayers; count++) { for (count = 0; count < nPlayers; count++) {
playerX = players[count].getX(); bonusPlayer = players[count].getBonusPlayer();
playerY = players[count].getY();
players[count].bonusStep(ticks, msps, this); playerX = bonusPlayer->getX();
playerY = bonusPlayer->getY();
bonusPlayer->step(ticks, msps, this);
if (isEvent(playerX, playerY)) { if (isEvent(playerX, playerY)) {
...@@ -457,10 +461,10 @@ int Bonus::step () { ...@@ -457,10 +461,10 @@ int Bonus::step () {
case 2: // Gem case 2: // Gem
players[count].addItem(); bonusPlayer->addGem();
grid[gridY][gridX].event = 0; grid[gridY][gridX].event = 0;
if (players[count].getItems() >= items) { if (bonusPlayer->getGems() >= items) {
players[count].addLife(); players[count].addLife();
...@@ -486,7 +490,7 @@ int Bonus::step () { ...@@ -486,7 +490,7 @@ int Bonus::step () {
} }
direction = localPlayer->getDirection(); direction = localPlayer->getBonusPlayer()->getDirection();
return E_NONE; return E_NONE;
...@@ -495,8 +499,8 @@ int Bonus::step () { ...@@ -495,8 +499,8 @@ int Bonus::step () {
void Bonus::draw () { void Bonus::draw () {
BonusPlayer *bonusPlayer;
unsigned char* row; unsigned char* row;
Anim* anim;
Sprite* sprite; Sprite* sprite;
SDL_Rect dst; SDL_Rect dst;
fixed playerX, playerY, playerSin, playerCos; fixed playerX, playerY, playerSin, playerCos;
...@@ -522,10 +526,13 @@ void Bonus::draw () { ...@@ -522,10 +526,13 @@ void Bonus::draw () {
if (y > 0) drawRect(0, 0, canvasW, y + 1, 128); if (y > 0) drawRect(0, 0, canvasW, y + 1, 128);
bonusPlayer = localPlayer->getBonusPlayer();
// Draw the ground // Draw the ground
playerX = localPlayer->getX(); playerX = bonusPlayer->getX();
playerY = localPlayer->getY(); playerY = bonusPlayer->getY();
playerSin = fSin(direction); playerSin = fSin(direction);
playerCos = fCos(direction); playerCos = fCos(direction);
...@@ -630,16 +637,13 @@ void Bonus::draw () { ...@@ -630,16 +637,13 @@ void Bonus::draw () {
// Show the player // Show the player
anim = animSet + localPlayer->getAnim(); bonusPlayer->draw(ticks, animSet);
anim->disableDefaultOffset();
anim->setFrame(ticks / 75, true);
anim->draw(ITOF((canvasW - anim->getWidth()) >> 1), ITOF(canvasH - anim->getHeight() - 28));
// Show gem count // Show gem count
font->showString("*", 0, 0); font->showString("*", 0, 0);
font->showNumber(localPlayer->getItems() / 10, 50, 0); font->showNumber(bonusPlayer->getGems() / 10, 50, 0);
font->showNumber(localPlayer->getItems() % 10, 68, 0); font->showNumber(bonusPlayer->getGems() % 10, 68, 0);
font->showString("/", 65, 0); font->showString("/", 65, 0);
font->showNumber(items, 124, 0); font->showNumber(items, 124, 0);
...@@ -749,9 +753,9 @@ int Bonus::play () { ...@@ -749,9 +753,9 @@ int Bonus::play () {
// Check if level has been won // Check if level has been won
if (returnTime && (ticks > returnTime)) { if (returnTime && (ticks > returnTime)) {
if (localPlayer->getItems() >= items) { if (localPlayer->getBonusPlayer()->getGems() >= items) {
if (playScene(F_BONUS_0SC) == E_QUIT) return E_QUIT; //if (playScene(F_BONUS_0SC) == E_QUIT) return E_QUIT;
return WON; return WON;
......
...@@ -33,7 +33,8 @@ ...@@ -33,7 +33,8 @@
#include "io/sound.h" #include "io/sound.h"
#include "level/level.h" #include "level/level.h"
#include "planet/planet.h" #include "planet/planet.h"
#include "player/player.h" #include "player/bonusplayer.h"
#include "player/levelplayer.h"
#include "util.h" #include "util.h"
#include <string.h> #include <string.h>
...@@ -286,7 +287,9 @@ void Game::setCheckpoint (unsigned char gridX, unsigned char gridY) { ...@@ -286,7 +287,9 @@ void Game::setCheckpoint (unsigned char gridX, unsigned char gridY) {
void Game::resetPlayer (Player *player, bool bonus) { void Game::resetPlayer (Player *player, bool bonus) {
player->reset(); player->reset();
player->setPosition(TTOF(checkX) + (bonus? F16: 0), TTOF(checkY) + (bonus? F16: 0));
if (bonus) player->getBonusPlayer()->setPosition(TTOF(checkX), TTOF(checkY));
else player->getLevelPlayer()->setPosition(TTOF(checkX), TTOF(checkY));
return; return;
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
#include "video.h" #include "video.h"
#include "level/level.h" #include "level/level.h"
#include "player/player.h" #include "player/levelplayer.h"
#include <string.h> #include <string.h>
...@@ -527,7 +527,7 @@ void WaterPaletteEffect::apply (SDL_Color* shownPalette, bool direct, int mspf) ...@@ -527,7 +527,7 @@ void WaterPaletteEffect::apply (SDL_Color* shownPalette, bool direct, int mspf)
currentPalette = video.getPalette(); currentPalette = video.getPalette();
position = localPlayer->getY() - level->getWaterLevel(); position = localPlayer->getLevelPlayer()->getY() - level->getWaterLevel();
if (position <= 0) return; if (position <= 0) return;
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
#include "io/gfx/sprite.h" #include "io/gfx/sprite.h"
#include "io/gfx/video.h" #include "io/gfx/video.h"
#include "player/bird.h" #include "player/bird.h"
#include "player/player.h" #include "player/levelplayer.h"
Bullet::Bullet (Player* sourcePlayer, bool lower, unsigned int ticks) { Bullet::Bullet (Player* sourcePlayer, bool lower, unsigned int ticks) {
...@@ -52,7 +52,7 @@ Bullet::Bullet (Player* sourcePlayer, bool lower, unsigned int ticks) { ...@@ -52,7 +52,7 @@ Bullet::Bullet (Player* sourcePlayer, bool lower, unsigned int ticks) {
} }
direction = source->getFacing()? 1: 0; direction = source->getLevelPlayer()->getFacing()? 1: 0;
direction |= lower? 2: 0; direction |= lower? 2: 0;
if (type == 4) { if (type == 4) {
...@@ -79,9 +79,9 @@ Bullet::Bullet (Player* sourcePlayer, bool lower, unsigned int ticks) { ...@@ -79,9 +79,9 @@ Bullet::Bullet (Player* sourcePlayer, bool lower, unsigned int ticks) {
} }
anim = level->getAnim(source->getAnim()); anim = level->getAnim(source->getLevelPlayer()->getAnim());
x = source->getX() + anim->getShootX() + PXO_MID - F4; x = source->getLevelPlayer()->getX() + anim->getShootX() + PXO_MID - F4;
y = source->getY() + anim->getShootY() - F4; y = source->getLevelPlayer()->getY() + anim->getShootY() - F4;
return; return;
...@@ -132,10 +132,10 @@ Bullet::Bullet (Bird* sourceBird, bool lower, unsigned int ticks) { ...@@ -132,10 +132,10 @@ Bullet::Bullet (Bird* sourceBird, bool lower, unsigned int ticks) {
} }
type = 30; type = 30;
direction = source->getFacing()? 1: 0; direction = source->getLevelPlayer()->getFacing()? 1: 0;
direction |= lower? 2: 0; direction |= lower? 2: 0;
sprite = level->getSprite(((unsigned char *)level->getBullet(type))[B_SPRITE + direction]); sprite = level->getSprite(((unsigned char *)level->getBullet(type))[B_SPRITE + direction]);
x = sourceBird->getX() + (source->getFacing()? PXO_R: PXO_L); x = sourceBird->getX() + (source->getLevelPlayer()->getFacing()? PXO_R: PXO_L);
y = sourceBird->getY(); y = sourceBird->getY();
dx = level->getBullet(type)[B_XSPEED + direction] * 500 * F1; dx = level->getBullet(type)[B_XSPEED + direction] * 500 * F1;
dy = level->getBullet(type)[B_YSPEED + direction] * 250 * F1; dy = level->getBullet(type)[B_YSPEED + direction] * 250 * F1;
...@@ -227,11 +227,11 @@ Bullet* Bullet::step (unsigned int ticks, int msps) { ...@@ -227,11 +227,11 @@ Bullet* Bullet::step (unsigned int ticks, int msps) {
// Check if a player has been hit // Check if a player has been hit
for (count = 0; count < nPlayers; count++) { for (count = 0; count < nPlayers; count++) {
if (players[count].overlap(x, y, if (players[count].getLevelPlayer()->overlap(x, y,
ITOF(sprite->getWidth()), ITOF(sprite->getHeight()))) { ITOF(sprite->getWidth()), ITOF(sprite->getHeight()))) {
// If the hit was successful, destroy the bullet // If the hit was successful, destroy the bullet
if (players[count].hit(source, ticks)) return remove(); if (players[count].getLevelPlayer()->hit(source, ticks)) return remove();
} }
......
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
#include "io/file.h" #include "io/file.h"
#include "io/gfx/font.h" #include "io/gfx/font.h"
#include "io/gfx/video.h" #include "io/gfx/video.h"
#include "player/player.h" #include "player/levelplayer.h"
#include "loop.h" #include "loop.h"
#include "util.h" #include "util.h"
...@@ -166,7 +166,7 @@ int DemoLevel::play () { ...@@ -166,7 +166,7 @@ int DemoLevel::play () {
// Handle player reactions // Handle player reactions
if (localPlayer->reacted(ticks) == PR_KILLED) return LOST; if (localPlayer->getLevelPlayer()->reacted(ticks) == PR_KILLED) return LOST;
// Draw the graphics // Draw the graphics
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
#include "../level.h" #include "../level.h"
#include "event.h" #include "event.h"
#include "player/player.h" #include "player/levelplayer.h"
Bridge::Bridge (unsigned char gX, unsigned char gY) { Bridge::Bridge (unsigned char gX, unsigned char gY) {
...@@ -63,6 +63,7 @@ Bridge::Bridge (unsigned char gX, unsigned char gY) { ...@@ -63,6 +63,7 @@ Bridge::Bridge (unsigned char gX, unsigned char gY) {
Event* Bridge::step (unsigned int ticks, int msps) { Event* Bridge::step (unsigned int ticks, int msps) {
LevelPlayer* levelPlayer;
signed char* set; signed char* set;
int count; int count;
fixed bridgeLength, playerDipX, playerDipY; fixed bridgeLength, playerDipX, playerDipY;
...@@ -85,25 +86,27 @@ Event* Bridge::step (unsigned int ticks, int msps) { ...@@ -85,25 +86,27 @@ Event* Bridge::step (unsigned int ticks, int msps) {
for (count = 0; count < nPlayers; count++) { for (count = 0; count < nPlayers; count++) {
playerDipX = players[count].getX() + PXO_MID - x; levelPlayer = players[count].getLevelPlayer();
playerDipX = levelPlayer->getX() + PXO_MID - x;
if (playerDipX < bridgeLength >> 1) playerDipY = playerDipX >> 3; if (playerDipX < bridgeLength >> 1) playerDipY = playerDipX >> 3;
else playerDipY = (bridgeLength - playerDipX) >> 3; else playerDipY = (bridgeLength - playerDipX) >> 3;
if (players[count].overlap(x, y + playerDipY - F4, bridgeLength, F8) && if (levelPlayer->overlap(x, y + playerDipY - F4, bridgeLength, F8) &&
!level->checkMaskDown(x + playerDipX, y + playerDipY - F32)) { !level->checkMaskDown(x + playerDipX, y + playerDipY - F32)) {
// Player is on the bridge // Player is on the bridge
players[count].setEvent(gridX, gridY); levelPlayer->setEvent(gridX, gridY);
if (playerDipX < leftDipX) leftDipX = playerDipX; if (playerDipX < leftDipX) leftDipX = playerDipX;
if (playerDipX > rightDipX) rightDipX = playerDipX; if (playerDipX > rightDipX) rightDipX = playerDipX;
players[count].setPosition(players[count].getX(), y + playerDipY); levelPlayer->setPosition(levelPlayer->getX(), y + playerDipY);
} else players[count].clearEvent(gridX, gridY); } else levelPlayer->clearEvent(gridX, gridY);
} }
......
...@@ -28,7 +28,8 @@ ...@@ -28,7 +28,8 @@
#define _EVENT_H #define _EVENT_H
#include "movable.h" #include "../movable.h"
#include "OpenJazz.h" #include "OpenJazz.h"
#include "../../io/gfx/anim.h" #include "../../io/gfx/anim.h"
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
#include "io/gfx/video.h" #include "io/gfx/video.h"
#include "io/sound.h" #include "io/sound.h"
#include "player/player.h" #include "player/levelplayer.h"
#include "util.h" #include "util.h"
#include <stdlib.h> #include <stdlib.h>
...@@ -84,6 +84,7 @@ signed char* Event::prepareStep (unsigned int ticks, int msps) { ...@@ -84,6 +84,7 @@ signed char* Event::prepareStep (unsigned int ticks, int msps) {
Event* Event::step (unsigned int ticks, int msps) { Event* Event::step (unsigned int ticks, int msps) {
LevelPlayer* levelPlayer;
fixed width, height; fixed width, height;
signed char* set; signed char* set;
int count; int count;
...@@ -96,6 +97,8 @@ Event* Event::step (unsigned int ticks, int msps) { ...@@ -96,6 +97,8 @@ Event* Event::step (unsigned int ticks, int msps) {
if (!set) return remove(); if (!set) return remove();
levelPlayer = localPlayer->getLevelPlayer();
// Find dimensions // Find dimensions
width = getWidth(); width = getWidth();
height = getHeight(); height = getHeight();
...@@ -124,8 +127,8 @@ Event* Event::step (unsigned int ticks, int msps) { ...@@ -124,8 +127,8 @@ Event* Event::step (unsigned int ticks, int msps) {
case 3: case 3:
// Seek jazz // Seek jazz
if (localPlayer->getX() + PXO_R < x) dx = -ES_FAST; if (levelPlayer->getX() + PXO_R < x) dx = -ES_FAST;
else if (localPlayer->getX() + PXO_L > x + width) dx = ES_FAST; else if (levelPlayer->getX() + PXO_L > x + width) dx = ES_FAST;
else dx = 0; else dx = 0;
break; break;
...@@ -350,20 +353,20 @@ Event* Event::step (unsigned int ticks, int msps) { ...@@ -350,20 +353,20 @@ Event* Event::step (unsigned int ticks, int msps) {
// Sparks-esque following // Sparks-esque following
if (localPlayer->getFacing() && (x + width < localPlayer->getX())) { if (levelPlayer->getFacing() && (x + width < levelPlayer->getX())) {
dx = ES_FAST; dx = ES_FAST;
if (y + height < localPlayer->getY() + PYO_TOP) dy = ES_SLOW; if (y + height < levelPlayer->getY() + PYO_TOP) dy = ES_SLOW;
else if (y > localPlayer->getY()) dy = -ES_SLOW; else if (y > levelPlayer->getY()) dy = -ES_SLOW;
else dy = 0; else dy = 0;
} else if (!localPlayer->getFacing() && (x > localPlayer->getX() + F32)) { } else if (!levelPlayer->getFacing() && (x > levelPlayer->getX() + F32)) {
dx = -ES_FAST; dx = -ES_FAST;
if (y + height < localPlayer->getY() + PYO_TOP) dy = ES_SLOW; if (y + height < levelPlayer->getY() + PYO_TOP) dy = ES_SLOW;
else if (y > localPlayer->getY()) dy = -ES_SLOW; else if (y > levelPlayer->getY()) dy = -ES_SLOW;
else dy = 0; else dy = 0;
} else { } else {
...@@ -399,7 +402,7 @@ Event* Event::step (unsigned int ticks, int msps) { ...@@ -399,7 +402,7 @@ Event* Event::step (unsigned int ticks, int msps) {
// Non-floating Sparks-esque following // Non-floating Sparks-esque following
if (localPlayer->getFacing() && (x + width < localPlayer->getX() + PXO_L - F4)) { if (levelPlayer->getFacing() && (x + width < levelPlayer->getX() + PXO_L - F4)) {
if (level->checkMaskDown(x + width, y + F4) && if (level->checkMaskDown(x + width, y + F4) &&
!level->checkMaskDown(x + width + F4, y - (height >> 1))) !level->checkMaskDown(x + width + F4, y - (height >> 1)))
...@@ -407,7 +410,7 @@ Event* Event::step (unsigned int ticks, int msps) { ...@@ -407,7 +410,7 @@ Event* Event::step (unsigned int ticks, int msps) {
else else
dx = 0; dx = 0;
} else if (!localPlayer->getFacing() && (x > localPlayer->getX() + PXO_R + F4)) { } else if (!levelPlayer->getFacing() && (x > levelPlayer->getX() + PXO_R + F4)) {
if (level->checkMaskDown(x, y + F4) && if (level->checkMaskDown(x, y + F4) &&
!level->checkMaskDown(x - F4, y - (height >> 1))) !level->checkMaskDown(x - F4, y - (height >> 1)))
...@@ -449,10 +452,10 @@ Event* Event::step (unsigned int ticks, int msps) { ...@@ -449,10 +452,10 @@ Event* Event::step (unsigned int ticks, int msps) {
for (count = 0; count < nPlayers; count++) { for (count = 0; count < nPlayers; count++) {
if (players[count].overlap(x + F8, y + F4 - height, width - F16, if (players[count].getLevelPlayer()->overlap(x + F8, y + F4 - height, width - F16,
height - F8)) { height - F8)) {
players[count].setSpeed(set[E_YAXIS]? set[E_MAGNITUDE] * F4: set[E_MAGNITUDE] * F40, players[count].getLevelPlayer()->setSpeed(set[E_YAXIS]? set[E_MAGNITUDE] * F4: set[E_MAGNITUDE] * F40,
set[E_YAXIS]? set[E_MULTIPURPOSE] * -F20: 0); set[E_YAXIS]? set[E_MULTIPURPOSE] * -F20: 0);
} }
...@@ -569,9 +572,9 @@ Event* Event::step (unsigned int ticks, int msps) { ...@@ -569,9 +572,9 @@ Event* Event::step (unsigned int ticks, int msps) {
case 3: case 3:
// Seek jazz // Seek jazz
if (localPlayer->getX() + PXO_R < x) if (levelPlayer->getX() + PXO_R < x)
animType = E_LEFTANIM; animType = E_LEFTANIM;
else if (localPlayer->getX() + PXO_L > x + width) else if (levelPlayer->getX() + PXO_L > x + width)
animType = E_RIGHTANIM; animType = E_RIGHTANIM;
break; break;
...@@ -670,7 +673,7 @@ Event* Event::step (unsigned int ticks, int msps) { ...@@ -670,7 +673,7 @@ Event* Event::step (unsigned int ticks, int msps) {
// Flip animation // Flip animation
if (localPlayer->overlap(x, y - height, width, height)) if (levelPlayer->overlap(x, y - height, width, height))
animType = E_LEFTANIM; animType = E_LEFTANIM;
else else
animType = E_RIGHTANIM; animType = E_RIGHTANIM;
...@@ -710,13 +713,13 @@ Event* Event::step (unsigned int ticks, int msps) { ...@@ -710,13 +713,13 @@ Event* Event::step (unsigned int ticks, int msps) {
// Sparks-esque following // Sparks-esque following
if (localPlayer->getFacing() && if (levelPlayer->getFacing() &&
(x + width < localPlayer->getX())) { (x + width < levelPlayer->getX())) {
animType = E_RIGHTANIM; animType = E_RIGHTANIM;
} else if (!localPlayer->getFacing() && } else if (!levelPlayer->getFacing() &&
(x > localPlayer->getX() + F32)) { (x > levelPlayer->getX() + F32)) {
animType = E_LEFTANIM; animType = E_LEFTANIM;
...@@ -792,7 +795,7 @@ Event* Event::step (unsigned int ticks, int msps) { ...@@ -792,7 +795,7 @@ Event* Event::step (unsigned int ticks, int msps) {
default: default:
if (localPlayer->getX() + PXO_MID < x + (width >> 1)) if (levelPlayer->getX() + PXO_MID < x + (width >> 1))
animType = E_LEFTANIM; animType = E_LEFTANIM;
else else
animType = E_RIGHTANIM; animType = E_RIGHTANIM;
...@@ -877,31 +880,31 @@ Event* Event::step (unsigned int ticks, int msps) { ...@@ -877,31 +880,31 @@ Event* Event::step (unsigned int ticks, int msps) {
for (count = 0; count < nPlayers; count++) { for (count = 0; count < nPlayers; count++) {
levelPlayer = players[count].getLevelPlayer();
// Check if the player is touching the event // Check if the player is touching the event
if (set[E_MODIFIER] == 6) { if (set[E_MODIFIER] == 6) {
if (width && height && if (width && height &&
players[count].overlap(x, y + extraOffset - height, width - F8, F8) && levelPlayer->overlap(x, y + extraOffset - height, width - F8, F8) &&
(players[count].getY() <= F8 + ((PYS_FALL * msps) >> 10) + y - height) && (levelPlayer->getY() <= F8 + ((PYS_FALL * msps) >> 10) + y - height) &&
!level->checkMaskDown(players[count].getX() + PXO_MID, PYO_TOP + y - height)) { !level->checkMaskDown(levelPlayer->getX() + PXO_MID, PYO_TOP + y - height)) {
// Player is on a platform // Player is on a platform
players[count].setEvent(gridX, gridY); levelPlayer->setEvent(gridX, gridY);
players[count].setPosition( levelPlayer->setPosition(levelPlayer->getX() + ((dx * msps) >> 10), F4 + y - height);
players[count].getX() + ((dx * msps) >> 10),
F4 + y - height);
} else players[count].clearEvent(gridX, gridY); } else levelPlayer->clearEvent(gridX, gridY);
} else { } else {
// Check if the player is touching the event // Check if the player is touching the event
if (width && height && if (width && height &&
players[count].overlap(x, y + extraOffset - height, width, height)) { levelPlayer->overlap(x, y + extraOffset - height, width, height)) {
// If the player picks up the event, destroy it // If the player picks up the event, destroy it
if (players[count].touchEvent(gridX, gridY, ticks, msps)) if (levelPlayer->touchEvent(gridX, gridY, ticks, msps))
destroy(ticks); destroy(ticks);
} }
......
...@@ -51,7 +51,7 @@ ...@@ -51,7 +51,7 @@
#include "io/gfx/video.h" #include "io/gfx/video.h"
#include "io/sound.h" #include "io/sound.h"
#include "menu/menu.h" #include "menu/menu.h"
#include "player/player.h" #include "player/levelplayer.h"
#include "scene/scene.h" #include "scene/scene.h"
#include "loop.h" #include "loop.h"
#include "util.h" #include "util.h"
...@@ -286,7 +286,7 @@ int Level::hitEvent (unsigned char gridX, unsigned char gridY, Player* source) { ...@@ -286,7 +286,7 @@ int Level::hitEvent (unsigned char gridX, unsigned char gridY, Player* source) {
// Notify the player that shot the bullet // Notify the player that shot the bullet
// If this returns false, ignore the hit // If this returns false, ignore the hit
if (!source->takeEvent(gridX, gridY, ticks)) { if (!source->getLevelPlayer()->takeEvent(gridX, gridY, ticks)) {
ge->hits--; ge->hits--;
...@@ -436,7 +436,7 @@ int Level::playBonus () { ...@@ -436,7 +436,7 @@ int Level::playBonus () {
char *bonusFile; char *bonusFile;
int ret; int ret;
if (!localPlayer->hasGem()) return E_NONE; if (!localPlayer->getLevelPlayer()->hasGem()) return E_NONE;
delete paletteEffects; delete paletteEffects;
paletteEffects = NULL; paletteEffects = NULL;
...@@ -517,6 +517,7 @@ void Level::receive (unsigned char* buffer) { ...@@ -517,6 +517,7 @@ void Level::receive (unsigned char* buffer) {
int Level::play () { int Level::play () {
LevelPlayer* levelPlayer;
const char* options[5] = const char* options[5] =
{"continue game", "save game", "load game", "setup options", "quit game"}; {"continue game", "save game", "load game", "setup options", "quit game"};
char *string; char *string;
...@@ -529,6 +530,8 @@ int Level::play () { ...@@ -529,6 +530,8 @@ int Level::play () {
int count; int count;
levelPlayer = localPlayer->getLevelPlayer();
tickOffset = globalTicks; tickOffset = globalTicks;
ticks = 16; ticks = 16;
prevStepTicks = 0; prevStepTicks = 0;
...@@ -700,8 +703,8 @@ int Level::play () { ...@@ -700,8 +703,8 @@ int Level::play () {
if (timeBonus < 0) timeBonus = 0; if (timeBonus < 0) timeBonus = 0;
if ((localPlayer->getEnemies() == enemies) && if ((levelPlayer->getEnemies() == enemies) &&
(localPlayer->getItems() == items)) perfect = 100; (levelPlayer->getItems() == items)) perfect = 100;
} else if (timeBonus - count >= 0) { } else if (timeBonus - count >= 0) {
...@@ -734,7 +737,7 @@ int Level::play () { ...@@ -734,7 +737,7 @@ int Level::play () {
font->showString("enemies", (canvasW >> 1) - 152, (canvasH >> 1) - 40); font->showString("enemies", (canvasW >> 1) - 152, (canvasH >> 1) - 40);
if (enemies) if (enemies)
font->showNumber((localPlayer->getEnemies() * 100) / enemies, (canvasW >> 1) + 124, (canvasH >> 1) - 40); font->showNumber((levelPlayer->getEnemies() * 100) / enemies, (canvasW >> 1) + 124, (canvasH >> 1) - 40);
else else
font->showNumber(0, (canvasW >> 1) + 124, (canvasH >> 1) - 40); font->showNumber(0, (canvasW >> 1) + 124, (canvasH >> 1) - 40);
font->showString("%", (canvasW >> 1) + 124, (canvasH >> 1) - 40); font->showString("%", (canvasW >> 1) + 124, (canvasH >> 1) - 40);
...@@ -742,7 +745,7 @@ int Level::play () { ...@@ -742,7 +745,7 @@ int Level::play () {
font->showString("items", (canvasW >> 1) - 152, (canvasH >> 1) - 20); font->showString("items", (canvasW >> 1) - 152, (canvasH >> 1) - 20);
if (items) if (items)
font->showNumber((localPlayer->getItems() * 100) / items, (canvasW >> 1) + 124, (canvasH >> 1) - 20); font->showNumber((levelPlayer->getItems() * 100) / items, (canvasW >> 1) + 124, (canvasH >> 1) - 20);
else else
font->showNumber(0, (canvasW >> 1) + 124, (canvasH >> 1) - 20); font->showNumber(0, (canvasW >> 1) + 124, (canvasH >> 1) - 20);
font->showString("%", (canvasW >> 1) + 124, (canvasH >> 1) - 20); font->showString("%", (canvasW >> 1) + 124, (canvasH >> 1) - 20);
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
#include "io/controls.h" #include "io/controls.h"
#include "io/gfx/font.h" #include "io/gfx/font.h"
#include "io/gfx/video.h" #include "io/gfx/video.h"
#include "player/player.h" #include "player/levelplayer.h"
#include "util.h" #include "util.h"
...@@ -108,7 +108,7 @@ int Level::step () { ...@@ -108,7 +108,7 @@ int Level::step () {
// Determine the players' trajectories // Determine the players' trajectories
for (x = 0; x < nPlayers; x++) players[x].control(ticks, msps); for (x = 0; x < nPlayers; x++) players[x].getLevelPlayer()->control(ticks, msps);
// Process active events // Process active events
...@@ -125,7 +125,7 @@ int Level::step () { ...@@ -125,7 +125,7 @@ int Level::step () {
// Apply as much of those trajectories as possible, without going into the // Apply as much of those trajectories as possible, without going into the
// scenery // scenery
for (x = 0; x < nPlayers; x++) players[x].move(ticks, msps); for (x = 0; x < nPlayers; x++) players[x].getLevelPlayer()->move(ticks, msps);
...@@ -135,7 +135,7 @@ int Level::step () { ...@@ -135,7 +135,7 @@ int Level::step () {
if (!gameMode) { if (!gameMode) {
if ((difficulty >= 2) && (stage == LS_NORMAL)) if ((difficulty >= 2) && (stage == LS_NORMAL))
localPlayer->kill(NULL, endTime); localPlayer->getLevelPlayer()->kill(NULL, endTime);
} else gameMode->outOfTime(); } else gameMode->outOfTime();
...@@ -153,7 +153,7 @@ int Level::step () { ...@@ -153,7 +153,7 @@ int Level::step () {
// Handle player reactions // Handle player reactions
for (x = 0; x < nPlayers; x++) { for (x = 0; x < nPlayers; x++) {
if (players[x].reacted(ticks) == PR_KILLED) { if (players[x].getLevelPlayer()->reacted(ticks) == PR_KILLED) {
if (!gameMode) return LOST; if (!gameMode) return LOST;
...@@ -181,7 +181,7 @@ void Level::draw () { ...@@ -181,7 +181,7 @@ void Level::draw () {
// Calculate viewport // Calculate viewport
if (game && (stage == LS_END)) game->view(paused? 0: ((ticks - prevTicks) * 160)); if (game && (stage == LS_END)) game->view(paused? 0: ((ticks - prevTicks) * 160));
else localPlayer->view(ticks, paused? 0: (ticks - prevTicks)); else localPlayer->getLevelPlayer()->view(ticks, paused? 0: (ticks - prevTicks));
// Ensure the new viewport is within the level // Ensure the new viewport is within the level
if (viewX < 0) viewX = 0; if (viewX < 0) viewX = 0;
...@@ -276,8 +276,7 @@ void Level::draw () { ...@@ -276,8 +276,7 @@ void Level::draw () {
// Show the players // Show the players
for (x = 0; x < nPlayers; x++) for (x = 0; x < nPlayers; x++) players[x].getLevelPlayer()->draw(ticks, change);
players[x].draw(ticks, change);
// Show bullets // Show bullets
...@@ -390,7 +389,7 @@ void Level::draw () { ...@@ -390,7 +389,7 @@ void Level::draw () {
// Draw the health bar // Draw the health bar
dst.x = 20; dst.x = 20;
x = localPlayer->getEnergy(); x = localPlayer->getLevelPlayer()->getEnergy();
y = (ticks - prevTicks) * 40; y = (ticks - prevTicks) * 40;
if (FTOI(energyBar) < (x << 4)) { if (FTOI(energyBar) < (x << 4)) {
......
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
#include "io/gfx/video.h" #include "io/gfx/video.h"
#include "io/sound.h" #include "io/sound.h"
#include "menu/menu.h" #include "menu/menu.h"
#include "player/player.h" #include "player/levelplayer.h"
#include "loop.h" #include "loop.h"
#include "util.h" #include "util.h"
...@@ -759,7 +759,7 @@ int Level::load (char *fileName, unsigned char diff, bool checkpoint) { ...@@ -759,7 +759,7 @@ int Level::load (char *fileName, unsigned char diff, bool checkpoint) {
} else { } else {
localPlayer->reset(); localPlayer->reset();
localPlayer->setPosition(TTOF(x), TTOF(y)); localPlayer->getLevelPlayer()->setPosition(TTOF(x), TTOF(y));
} }
...@@ -791,7 +791,7 @@ int Level::load (char *fileName, unsigned char diff, bool checkpoint) { ...@@ -791,7 +791,7 @@ int Level::load (char *fileName, unsigned char diff, bool checkpoint) {
for (x = 0; x < PANIMS; x++) string[x + 3] = buffer[x << 1]; for (x = 0; x < PANIMS; x++) string[x + 3] = buffer[x << 1];
for (x = 0; x < nPlayers; x++) players[x].setAnims(string + 3); for (x = 0; x < nPlayers; x++) players[x].getLevelPlayer()->setAnims(string + 3);
if (gameMode) { if (gameMode) {
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
#include "bird.h" #include "bird.h"
#include "player.h" #include "levelplayer.h"
#include "io/gfx/video.h" #include "io/gfx/video.h"
#include "level/bullet.h" #include "level/bullet.h"
...@@ -53,8 +53,8 @@ Bird::~Bird () { ...@@ -53,8 +53,8 @@ Bird::~Bird () {
void Bird::reset () { void Bird::reset () {
x = player->getX(); x = player->getLevelPlayer()->getX();
y = player->getY() - F64; y = player->getLevelPlayer()->getY() - F64;
fireTime = 0; fireTime = 0;
return; return;
...@@ -80,7 +80,8 @@ void Bird::hit () { ...@@ -80,7 +80,8 @@ void Bird::hit () {
bool Bird::step (unsigned int ticks, int msps) { bool Bird::step (unsigned int ticks, int msps) {
Event *event; LevelPlayer* levelPlayer;
Event* event;
bool target; bool target;
if (fleeing) { if (fleeing) {
...@@ -96,14 +97,16 @@ bool Bird::step (unsigned int ticks, int msps) { ...@@ -96,14 +97,16 @@ bool Bird::step (unsigned int ticks, int msps) {
// Trajectory for flying towards the player // Trajectory for flying towards the player
if ((x < player->getX() - F160) || (x > player->getX() + F160)) { levelPlayer = player->getLevelPlayer();
if ((x < levelPlayer->getX() - F160) || (x > levelPlayer->getX() + F160)) {
// Far away from the player // Far away from the player
// Approach the player at a speed proportional to the distance // Approach the player at a speed proportional to the distance
dx = player->getX() - x; dx = levelPlayer->getX() - x;
} else if (x < player->getX()) { } else if (x < levelPlayer->getX()) {
// To the left of the player, so move right // To the left of the player, so move right
...@@ -126,14 +129,14 @@ bool Bird::step (unsigned int ticks, int msps) { ...@@ -126,14 +129,14 @@ bool Bird::step (unsigned int ticks, int msps) {
} else { } else {
if ((y < player->getY() - F100) || (y > player->getY() + F100)) { if ((y < levelPlayer->getY() - F100) || (y > levelPlayer->getY() + F100)) {
// Far away from the player // Far away from the player
// Approach the player at a speed proportional to the distance // Approach the player at a speed proportional to the distance
dy = (player->getY() - F64) - y; dy = (levelPlayer->getY() - F64) - y;
} else if (y < player->getY() - F64) { } else if (y < levelPlayer->getY() - F64) {
// Above the player, so move downwards // Above the player, so move downwards
...@@ -158,7 +161,7 @@ bool Bird::step (unsigned int ticks, int msps) { ...@@ -158,7 +161,7 @@ bool Bird::step (unsigned int ticks, int msps) {
target = false; target = false;
event = level->events; event = level->events;
if (player->getFacing()) { if (levelPlayer->getFacing()) {
while (event && !target) { while (event && !target) {
...@@ -206,8 +209,7 @@ void Bird::draw (unsigned int ticks, int change) { ...@@ -206,8 +209,7 @@ void Bird::draw (unsigned int ticks, int change) {
Anim *anim; Anim *anim;
anim = level->getAnim((player->getFacing() || fleeing)? BIRD_RIGHTANIM: anim = level->getAnim((player->getLevelPlayer()->getFacing() || fleeing)? BIRD_RIGHTANIM: BIRD_LEFTANIM);
BIRD_LEFTANIM);
anim->setFrame(ticks / 80, true); anim->setFrame(ticks / 80, true);
anim->draw(getDrawX(change), getDrawY(change)); anim->draw(getDrawX(change), getDrawY(change));
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
#define _BIRD_H #define _BIRD_H
#include "movable.h" #include "level/movable.h"
#include "OpenJazz.h" #include "OpenJazz.h"
......
/*
*
* bonusplayer.cpp
*
* 24th June 2010: Created bonusplayer.cpp from parts of player.cpp and
* playerframe.cpp
*
* Part of the OpenJazz project
*
*
* Copyright (c) 2005-2010 Alister Thomson
*
* OpenJazz is distributed under the terms of
* the GNU General Public License, version 2.0
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
/*
* Deals with players in bonus levels.
*
*/
#include "bonusplayer.h"
#include "bonus/bonus.h"
#include "io/controls.h"
#include "io/gfx/sprite.h"
#include "io/gfx/video.h"
#include "util.h"
#include <string.h>
BonusPlayer::BonusPlayer (Player* parent) {
player = parent;
return;
}
BonusPlayer::~BonusPlayer () {
return;
}
void BonusPlayer::reset () {
direction = FQ;
dr = 0;
gems = 0;
return;
}
void BonusPlayer::addGem () {
gems++;
return;
}
fixed BonusPlayer::getDirection () {
return direction;
}
int BonusPlayer::getGems () {
return gems;
}
fixed BonusPlayer::getX () {
return x;
}
fixed BonusPlayer::getY () {
return y;
}
void BonusPlayer::setAnims (char *newAnims) {
memcpy(anims, newAnims, PANIMS);
return;
}
void BonusPlayer::setPosition (fixed newX, fixed newY) {
x = newX + F16;
y = newY + F16;
return;
}
void BonusPlayer::step (unsigned int ticks, int msps, Bonus* bonus) {
fixed cdx, cdy;
// Bonus stages use polar coordinates for movement (but not position)
if (player->getControl(C_UP)) {
// Walk/run forwards
if (dr < 0) dr += PRA_REVERSE * msps;
else if (dr < PRS_RUN) dr += PRA_RUN * msps;
animType = PA_WALK;
} else if (player->getControl(C_DOWN)) {
// Walk/run back
if (dr > 0) dr -= PRA_REVERSE * msps;
else if (dr > PRS_REVERSE) dr -= PRA_RUN * msps;
animType = PA_WALK;
} else {
// Slow down
if (dr > 0) {
if (dr < PRA_STOP * msps) dr = 0;
else dr -= PRA_STOP * msps;
}
if (dr < 0) {
if (dr > -PRA_STOP * msps) dr = 0;
else dr += PRA_STOP * msps;
}
animType = PA_OTHER;
}
if (player->getControl(C_LEFT)) {
direction -= msps >> 2;
animType = PA_LEFT;
}
if (player->getControl(C_RIGHT)) {
direction += msps >> 2;
animType = PA_RIGHT;
}
// Apply trajectory
cdx = (MUL(fSin(direction), dr) * msps) >> 10;
cdy = (MUL(-fCos(direction), dr) * msps) >> 10;
if (!bonus->checkMask(x + cdx, y)) x += cdx;
if (!bonus->checkMask(x, y + cdy)) y += cdy;
return;
}
void BonusPlayer::draw (unsigned int ticks, Anim* animSet) {
Anim* anim;
anim = animSet + anims[animType];
anim->disableDefaultOffset();
anim->setFrame(ticks / 75, true);
anim->draw(ITOF((canvasW - anim->getWidth()) >> 1), ITOF(canvasH - anim->getHeight() - 28));
return;
}
/*
*
* bonusplayer.h
*
* 24th June 2010: Created bonusplayer.h from parts of player.h
*
* Part of the OpenJazz project
*
*
* Copyright (c) 2005-2010 Alister Thomson
*
* OpenJazz is distributed under the terms of
* the GNU General Public License, version 2.0
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef _BONUSPLAYER_H
#define _BONUSPLAYER_H
#include "player.h"
#include "OpenJazz.h"
#include <SDL/SDL.h>
// Constants
// Bonus level animations
#define PA_WALK 0
#define PA_LEFT 1
#define PA_RIGHT 2
#define PA_USER 3
#define PA_JUMP 4
#define PA_CRASH 5
#define PA_OTHER 6
// Player speeds
#define PRS_REVERSE ITOF(-32)
#define PRS_RUN ITOF(64)
#define PRS_ROLL ITOF(96)
// Player accelerations
#define PRA_REVERSE 450
#define PRA_STOP 500
#define PRA_RUN 100
// Classes
class Anim;
class Bonus;
class BonusPlayer {
private:
char anims[PANIMS];
fixed x, y, direction, dr;
unsigned char animType;
int gems;
public:
Player* player;
BonusPlayer (Player* parent);
~BonusPlayer ();
void reset ();
void addGem ();
fixed getDirection ();
int getGems ();
fixed getX ();
fixed getY ();
void setAnims (char* newAnims);
void setPosition (fixed newX, fixed newY);
void step (unsigned int ticks, int msps, Bonus* bonus);
void draw (unsigned int ticks, Anim* animSet);
};
#endif
/*
*
* levelplayer.cpp
*
* 24th June 2010: Created levelplayer.cpp from parts of player.cpp
*
* Part of the OpenJazz project
*
*
* Copyright (c) 2005-2010 Alister Thomson
*
* OpenJazz is distributed under the terms of
* the GNU General Public License, version 2.0
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
/*
* Deals with the creation and destruction of players in levels, and their
* interactions with other level objects.
*
*/
#include "bird.h"
#include "levelplayer.h"
#include "game/game.h"
#include "game/gamemode.h"
#include "io/sound.h"
#include "level/event/event.h"
#include "level/level.h"
#include <string.h>
LevelPlayer::LevelPlayer (Player* parent) {
player = parent;
return;
}
LevelPlayer::~LevelPlayer () {
return;
}
void LevelPlayer::reset () {
event = 0;
energy = 4;
shield = 0;
floating = false;
facing = true;
reaction = PR_NONE;
reactionTime = 0;
jumpHeight = ITOF(92);
jumpY = TTOF(LH);
fastFeetTime = 0;
warpTime = 0;
dx = 0;
dy = 0;
enemies = items = 0;
gem = false;
return;
}
void LevelPlayer::addItem () {
items++;
return;
}
void LevelPlayer::clearEvent (unsigned char gridX, unsigned char gridY) {
// If the location matches, clear the event
if ((gridX == eventX) && (gridY == eventY)) event = 0;
return;
}
unsigned char LevelPlayer::getAnim () {
return anims[animType];
}
int LevelPlayer::getEnemies () {
return enemies;
}
int LevelPlayer::getEnergy () {
return energy;
}
bool LevelPlayer::getFacing () {
return facing;
}
int LevelPlayer::getItems () {
return items;
}
bool LevelPlayer::hasGem () {
return gem;
}
bool LevelPlayer::hit (Player *source, unsigned int ticks) {
// Invulnerable if reacting to e.g. having been hit
if (reaction != PR_NONE) return false;
// Hits from the same team have no effect
if (source && (source->getTeam() == player->team)) return false;
if (shield == 3) shield = 0;
else if (shield) shield--;
else if (!gameMode || gameMode->hit(source, player)) {
energy--;
if (player->bird) player->bird->hit();
playSound(S_OW);
}
if (energy) {
reaction = PR_HURT;
reactionTime = ticks + PRT_HURT;
if (dx < 0) {
dx = PXS_RUN;
dy = PYS_JUMP;
} else {
dx = -PXS_RUN;
dy = PYS_JUMP;
}
} else {
kill(source, ticks);
}
return true;
}
void LevelPlayer::kill (Player *source, unsigned int ticks) {
if (reaction != PR_NONE) return;
if (!gameMode || gameMode->kill(source, player)) {
energy = 0;
player->lives--;
reaction = PR_KILLED;
reactionTime = ticks + PRT_KILLED;
}
if (!gameMode) level->flash(0, 0, 0, T_END << 1);
return;
}
bool LevelPlayer::overlap (fixed left, fixed top, fixed width, fixed height) {
return (x + PXO_R >= left) && (x + PXO_L < left + width) &&
(y >= top) && (y + PYO_TOP < top + height);
}
PlayerReaction LevelPlayer::reacted (unsigned int ticks) {
PlayerReaction oldReaction;
if ((reaction != PR_NONE) && (reactionTime < ticks)) {
oldReaction = reaction;
reaction = PR_NONE;
return oldReaction;
}
return PR_NONE;
}
void LevelPlayer::setAnims (char *newAnims) {
memcpy(anims, newAnims, PANIMS);
return;
}
void LevelPlayer::setEvent (unsigned char gridX, unsigned char gridY) {
signed char *set;
set = level->getEvent(gridX, gridY);
if (set[E_MODIFIER] == 29) {
// Upwards spring
jumpY = y + (set[E_MAGNITUDE] * (F20 + F1));
event = 1;
} else if (set[E_MODIFIER] == 6) event = 3;
else if (set[E_BEHAVIOUR] == 28) event = 4;
else return;
eventX = gridX;
eventY = gridY;
return;
}
void LevelPlayer::setPosition (fixed newX, fixed newY) {
x = newX;
y = newY;
return;
}
void LevelPlayer::setSpeed (fixed newDx, fixed newDy) {
dx = newDx;
if (newDy) dy = newDy;
return;
}
bool LevelPlayer::takeEvent (unsigned char gridX, unsigned char gridY, unsigned int ticks) {
signed char *set;
set = level->getEvent(gridX, gridY);
switch (set[E_MODIFIER]) {
case 41: // Bonus level
if (energy) level->setNext(set[E_MULTIPURPOSE], set[E_YAXIS]);
// The lack of a break statement is intentional
case 8: // Boss
case 27: // End of level
if (!getEnergy()) return false;
if (!gameMode) {
if (game) game->setCheckpoint(gridX, gridY);
level->setStage(LS_END);
} else if (!(gameMode->endOfLevel(player, gridX, gridY))) return false;
break;
case 0: // Enemy
break;
case 1: // Invincibility
if (!getEnergy()) return false;
reaction = PR_INVINCIBLE;
reactionTime = ticks + PRT_INVINCIBLE;
break;
case 2:
case 3: // Health
if (energy < 4) energy++;
break;
case 4: // Extra life
player->addLife();
break;
case 5: // High-jump feet
jumpHeight += F16;
break;
case 7: // Used with destructible blocks
break;
case 9: // Sand timer
level->addTimer();
break;
case 10: // Checkpoint
if (game) game->setCheckpoint(gridX, gridY);
break;
case 11: // Item
break;
case 12: // Rapid fire
player->fireSpeed++;
break;
case 15: // Ammo
player->addAmmo(0, 15);
break;
case 16: // Ammo
player->addAmmo(1, 15);
break;
case 17: // Ammo
player->addAmmo(2, 15);
break;
case 18: // Ammo
player->addAmmo(0, 2);
break;
case 19: // Ammo
player->addAmmo(1, 2);
break;
case 20: // Ammo
player->addAmmo(2, 2);
break;
case 26: // Fast feet box
fastFeetTime = ticks + T_FASTFEET;
break;
case 30: // TNT
player->addAmmo(3, 1);
break;
case 31: // Water level
level->setWaterLevel(gridY);
break;
case 33: // 2-hit shield
if (shield < 2) shield = 2;
break;
case 34: // Bird
if (!player->bird) player->bird = new Bird(player, gridX, gridY);
break;
case 35: // Airboard, etc.
floating = true;
break;
case 36: // 4-hit shield
shield = 6;
break;
case 37: // Diamond
gem = true;
// Yellow flash
level->flash(255, 255, 0, 320);
break;
default:
return false;
}
player->addScore(set[E_ADDEDSCORE]);
// Add to player's enemy/item tally
// If the event hurts and can be killed, it is an enemy
// Anything else that scores is an item
if ((set[E_MODIFIER] == 0) && set[E_HITSTOKILL]) enemies++;
else if (set[E_ADDEDSCORE]) items++;
return true;
}
bool LevelPlayer::touchEvent (unsigned char gridX, unsigned char gridY, unsigned int ticks, int msps) {
signed char *set;
set = level->getEvent(gridX, gridY);
switch (set[E_MODIFIER]) {
case 0: // Hurt
case 8: // Boss
if ((set[E_BEHAVIOUR] < 37) || (set[E_BEHAVIOUR] > 44)) hit(NULL, ticks);
break;
case 7: // Used with destructible blocks, but should not destroy on contact
break;
case 13: // Warp
if (!warpTime) {
warpX = set[E_MULTIPURPOSE];
warpY = set[E_YAXIS];
warpTime = ticks + T_WARP;
// White flash
level->flash(255, 255, 255, T_WARP);
}
break;
case 28: // Belt
x += set[E_MAGNITUDE] * 4 * msps;
break;
case 29: // Upwards spring
setEvent(gridX, gridY);
level->playSound(set[E_SOUND]);
break;
case 31: // Water level
level->setWaterLevel(gridY);
break;
case 32: // Float up / sideways
if (set[E_YAXIS]) {
eventX = gridX;
eventY = gridY;
event = 2;
if (dy > set[E_MULTIPURPOSE] * -F20)
dy -= set[E_MULTIPURPOSE] * 320 * msps;
jumpY = y - (8 * F16);
} else if (set[E_MAGNITUDE] < 0) {
if (!level->checkMaskDown(x + PXO_L + (set[E_MAGNITUDE] * 20 * msps), y + PYO_MID))
x += set[E_MAGNITUDE] * 20 * msps;
} else {
if (!level->checkMaskDown(x + PXO_R + (set[E_MAGNITUDE] * 20 * msps), y + PYO_MID))
x += set[E_MAGNITUDE] * 20 * msps;
}
break;
case 38: // Airboard, etc. off
floating = false;
break;
default:
if (!set[E_HITSTOKILL]) return takeEvent(gridX, gridY, ticks);
break;
}
return false;
}
void LevelPlayer::send (unsigned char *buffer) {
// Copy data to be sent to clients/server
buffer[23] = energy;
buffer[25] = shield;
buffer[26] = floating;
buffer[27] = getFacing();
buffer[29] = jumpHeight >> 24;
buffer[30] = (jumpHeight >> 16) & 255;
buffer[31] = (jumpHeight >> 8) & 255;
buffer[32] = jumpHeight & 255;
buffer[33] = jumpY >> 24;
buffer[34] = (jumpY >> 16) & 255;
buffer[35] = (jumpY >> 8) & 255;
buffer[36] = jumpY & 255;
buffer[37] = x >> 24;
buffer[38] = (x >> 16) & 255;
buffer[39] = (x >> 8) & 255;
buffer[40] = x & 255;
buffer[41] = y >> 24;
buffer[42] = (y >> 16) & 255;
buffer[43] = (y >> 8) & 255;
buffer[44] = y & 255;
return;
}
void LevelPlayer::receive (unsigned char *buffer) {
// Interpret data received from client/server
switch (buffer[1]) {
case MT_P_ANIMS:
setAnims((char *)buffer + 3);
break;
case MT_P_TEMP:
energy = buffer[23];
shield = buffer[25];
floating = buffer[26];
facing = buffer[27];
jumpHeight = (buffer[29] << 24) + (buffer[30] << 16) + (buffer[31] << 8) + buffer[32];
jumpY = (buffer[33] << 24) + (buffer[34] << 16) + (buffer[35] << 8) + buffer[36];
x = (buffer[37] << 24) + (buffer[38] << 16) + (buffer[39] << 8) + buffer[40];
y = (buffer[41] << 24) + (buffer[42] << 16) + (buffer[43] << 8) + buffer[44];
break;
}
return;
}
/*
*
* levelplayer.h
*
* 24th June 2010: Created levelplayer.h from parts of player.h
*
* Part of the OpenJazz project
*
*
* Copyright (c) 2005-2010 Alister Thomson
*
* OpenJazz is distributed under the terms of
* the GNU General Public License, version 2.0
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
/* "Tile" is a flexible term. Here it is used to refer specifically to the
individual elements of the tile set.
"Tiles" in the context of level units are referred to as grid elements. */
#ifndef _LEVELPLAYER_H
#define _LEVELPLAYER_H
#include "player.h"
#include "level/movable.h"
#include "OpenJazz.h"
#include <SDL/SDL.h>
// Constants
// Animations
#define PA_LWALK 0
#define PA_RWALK 1
#define PA_LJUMP 2
#define PA_RJUMP 3
#define PA_LSPIN 4
#define PA_RSPIN 5
#define PA_LSHOOT 6
#define PA_RSHOOT 7
#define PA_LCROUCH 8
#define PA_RCROUCH 9
#define PA_LFALL 10
#define PA_RFALL 11
#define PA_LHURT 12
#define PA_RHURT 13
#define PA_LLEAN 14
#define PA_RLEAN 15
#define PA_LBOARD 16
#define PA_RBOARD 17
#define PA_LSTAND 18
#define PA_RSTAND 19
#define PA_LEAT 20
#define PA_REAT 21
#define PA_LEDGE 22
#define PA_REDGE 23
#define PA_LOOKUP 24
#define PA_LOOKDOWN 25
#define PA_LSWIM 26
#define PA_RSWIM 27
#define PA_LRUN 28
#define PA_RRUN 29
#define PA_LDIE 30
#define PA_RDIE 31
#define PA_LSTOP 32
#define PA_RSTOP 33
#define PA_LHALT 34 /* Yeah, I was wondering the same thing... */
#define PA_RHALT 35
#define PA_RSPRING 36
#define PA_LSPRING 37 /* Surely these are the wrong way round? */
// Player reaction times
#define PRT_HURT 1000
#define PRT_HURTANIM 200
#define PRT_KILLED 2000
#define PRT_INVINCIBLE 10000
// Other time periods
#define T_FASTFEET 25000
#define T_WARP 1000
// Player offsets
#define PXO_MID F16
#define PXO_L (PXO_MID - F10)
#define PXO_ML (PXO_MID - F4)
#define PXO_MR (PXO_MID + F4)
#define PXO_R (PXO_MID + F10)
#define PYO_TOP (-F20)
#define PYO_MID (-F10)
// Player speeds
#define PXS_WALK ITOF(300)
#define PXS_RUN ITOF(325)
#define PXS_FFRUN ITOF(500)
#define PYS_FALL ITOF(350)
#define PYS_SINK ITOF(150)
#define PYS_JUMP ITOF(-350)
// Player accelerations
#define PXA_REVERSE 900
#define PXA_STOP 1000
#define PXA_WALK 500
#define PXA_RUN 200
#define PXA_FFRUN 200
#define PYA_GRAVITY 2750
#define PYA_SINK 1000
// Enum
enum PlayerReaction {
PR_NONE, PR_HURT, PR_KILLED, PR_INVINCIBLE
};
// Classes
class Anim;
class LevelPlayer : public Movable {
private:
char anims[PANIMS];
int energy;
int shield; /* 0 = none, 1 = 1 yellow, 2 = 2 yellow, 3 = 1 orange, 4 = 2 orange, 5 = 3 orange, 6 = 4 orange */
bool floating; /* false = normal, true = boarding/bird/etc. */
bool facing;
unsigned char animType;
unsigned char eventX;
unsigned char eventY; /* Position of an event (spring, platform, bridge) */
int event; /* 0 = none, 1 = spring, 2 = float up, 3 = platform, 4 = bridge */
int lookTime; /* Negative if looking up, positive if looking down, 0 if neither */
PlayerReaction reaction;
unsigned int reactionTime;
unsigned int fireTime;
fixed jumpHeight;
fixed jumpY;
unsigned int fastFeetTime;
unsigned char warpX, warpY;
unsigned int warpTime;
int enemies, items;
bool gem;
public:
Player* player;
LevelPlayer (Player* parent);
~LevelPlayer ();
void reset ();
void addItem ();
void clearEvent (unsigned char gridX, unsigned char gridY);
unsigned char getAnim ();
int getEnemies ();
int getEnergy ();
bool getFacing ();
int getItems ();
bool hasGem ();
bool hit (Player* source, unsigned int ticks);
void kill (Player* source, unsigned int ticks);
bool overlap (fixed left, fixed top, fixed width, fixed height);
PlayerReaction reacted (unsigned int ticks);
void setAnims (char* newAnims);
void setEvent (unsigned char gridX, unsigned char gridY);
void setPosition (fixed newX, fixed newY);
void setSpeed (fixed newDx, fixed newDy);
bool takeEvent (unsigned char gridX, unsigned char gridY, unsigned int ticks);
bool touchEvent (unsigned char gridX, unsigned char gridY, unsigned int ticks, int msps);
void send (unsigned char* buffer);
void receive (unsigned char* buffer);
void control (unsigned int ticks, int msps);
void move (unsigned int ticks, int msps);
void view (unsigned int ticks, int mspf);
void draw (unsigned int ticks, int change);
};
#endif
/* /*
* *
* playerframe.cpp * levelplayerframe.cpp
* *
* 18th July 2009: Created playerframe.cpp from parts of player.cpp * 18th July 2009: Created playerframe.cpp from parts of player.cpp
* 24th June 2010: Renamed playerframe.cpp to levelplayerframe.cpp
* *
* Part of the OpenJazz project * Part of the OpenJazz project
* *
...@@ -20,13 +21,13 @@ ...@@ -20,13 +21,13 @@
*/ */
/* /*
* Provides the once-per-frame functions of players. * Provides the once-per-frame functions of players in levels.
* *
*/ */
#include "bird.h" #include "bird.h"
#include "player.h" #include "levelplayer.h"
#include "bonus/bonus.h" #include "bonus/bonus.h"
#include "game/gamemode.h" #include "game/gamemode.h"
...@@ -40,7 +41,7 @@ ...@@ -40,7 +41,7 @@
#include "util.h" #include "util.h"
void Player::control (unsigned int ticks, int msps) { void LevelPlayer::control (unsigned int ticks, int msps) {
int speed; int speed;
bool platform; bool platform;
...@@ -66,7 +67,7 @@ void Player::control (unsigned int ticks, int msps) { ...@@ -66,7 +67,7 @@ void Player::control (unsigned int ticks, int msps) {
} }
if (pcontrols[C_RIGHT]) { if (player->pcontrols[C_RIGHT]) {
// Walk/run right // Walk/run right
...@@ -76,7 +77,7 @@ void Player::control (unsigned int ticks, int msps) { ...@@ -76,7 +77,7 @@ void Player::control (unsigned int ticks, int msps) {
facing = true; facing = true;
} else if (pcontrols[C_LEFT]) { } else if (player->pcontrols[C_LEFT]) {
// Walk/run left // Walk/run left
...@@ -121,7 +122,7 @@ void Player::control (unsigned int ticks, int msps) { ...@@ -121,7 +122,7 @@ void Player::control (unsigned int ticks, int msps) {
if (floating) { if (floating) {
if (pcontrols[C_UP]) { if (player->pcontrols[C_UP]) {
// Fly upwards // Fly upwards
...@@ -129,7 +130,7 @@ void Player::control (unsigned int ticks, int msps) { ...@@ -129,7 +130,7 @@ void Player::control (unsigned int ticks, int msps) {
else if (dy > -PXS_WALK) dy -= PXA_WALK * msps; else if (dy > -PXS_WALK) dy -= PXA_WALK * msps;
else if (dy > -PXS_RUN) dy -= PXA_RUN * msps; else if (dy > -PXS_RUN) dy -= PXA_RUN * msps;
} else if (pcontrols[C_DOWN]) { } else if (player->pcontrols[C_DOWN]) {
// Fly downwards // Fly downwards
...@@ -169,7 +170,7 @@ void Player::control (unsigned int ticks, int msps) { ...@@ -169,7 +170,7 @@ void Player::control (unsigned int ticks, int msps) {
} else if (y + PYO_MID > level->getWaterLevel()) { } else if (y + PYO_MID > level->getWaterLevel()) {
if (pcontrols[C_SWIM]) { if (player->pcontrols[C_SWIM]) {
// Swim upwards // Swim upwards
...@@ -190,7 +191,7 @@ void Player::control (unsigned int ticks, int msps) { ...@@ -190,7 +191,7 @@ void Player::control (unsigned int ticks, int msps) {
} }
} else if (pcontrols[C_DOWN]) { } else if (player->pcontrols[C_DOWN]) {
// Swim downwards // Swim downwards
...@@ -212,7 +213,7 @@ void Player::control (unsigned int ticks, int msps) { ...@@ -212,7 +213,7 @@ void Player::control (unsigned int ticks, int msps) {
} else { } else {
if (platform && pcontrols[C_JUMP] && if (platform && player->pcontrols[C_JUMP] &&
!level->checkMaskUp(x + PXO_MID, y - F36)) { !level->checkMaskUp(x + PXO_MID, y - F36)) {
// Jump // Jump
...@@ -230,7 +231,7 @@ void Player::control (unsigned int ticks, int msps) { ...@@ -230,7 +231,7 @@ void Player::control (unsigned int ticks, int msps) {
} }
// Stop jumping // Stop jumping
if (!pcontrols[C_JUMP] && (event != 1) && (event != 2)) if (!player->pcontrols[C_JUMP] && (event != 1) && (event != 2))
jumpY = TTOF(LH); jumpY = TTOF(LH);
if (y >= jumpY) { if (y >= jumpY) {
...@@ -267,15 +268,15 @@ void Player::control (unsigned int ticks, int msps) { ...@@ -267,15 +268,15 @@ void Player::control (unsigned int ticks, int msps) {
if (platform && !lookTime) { if (platform && !lookTime) {
// If requested, look up or down // If requested, look up or down
if (pcontrols[C_UP]) lookTime = -ticks; if (player->pcontrols[C_UP]) lookTime = -ticks;
else if (pcontrols[C_DOWN]) lookTime = ticks; else if (player->pcontrols[C_DOWN]) lookTime = ticks;
} }
// Stop looking if there is no platform or the control has been released // Stop looking if there is no platform or the control has been released
if (!platform || if (!platform ||
(!pcontrols[C_UP] && (lookTime < 0)) || (!player->pcontrols[C_UP] && (lookTime < 0)) ||
(!pcontrols[C_DOWN] && (lookTime > 0))) lookTime = 0; (!player->pcontrols[C_DOWN] && (lookTime > 0))) lookTime = 0;
} }
...@@ -301,26 +302,26 @@ void Player::control (unsigned int ticks, int msps) { ...@@ -301,26 +302,26 @@ void Player::control (unsigned int ticks, int msps) {
// Handle firing // Handle firing
if (pcontrols[C_FIRE]) { if (player->pcontrols[C_FIRE]) {
if ((ticks > fireTime) && (level->getBullet(ammoType + 1)[B_SPRITE] != 0)) { if ((ticks > fireTime) && (level->getBullet(player->ammoType + 1)[B_SPRITE] != 0)) {
// Make sure bullet position is taken from correct animation // Make sure bullet position is taken from correct animation
if (platform) animType = facing? PA_RSHOOT: PA_LSHOOT; if (platform) animType = facing? PA_RSHOOT: PA_LSHOOT;
// Create new bullet // Create new bullet
level->bullets = new Bullet(this, false, ticks); level->bullets = new Bullet(player, false, ticks);
// Set when the next bullet can be fired // Set when the next bullet can be fired
if (fireSpeed) fireTime = ticks + (1000 / fireSpeed); if (player->fireSpeed) fireTime = ticks + (1000 / player->fireSpeed);
else fireTime = 0x7FFFFFFF; else fireTime = 0x7FFFFFFF;
// Remove the bullet from the arsenal // Remove the bullet from the arsenal
if (ammoType != -1) ammo[ammoType]--; if (player->ammoType != -1) player->ammo[player->ammoType]--;
/* If the current ammo type has been exhausted or TNT has been used, /* If the current ammo type has been exhausted or TNT has been used,
use the previous non-exhausted ammo type */ use the previous non-exhausted ammo type */
while (((ammoType > -1) && !ammo[ammoType]) || (ammoType == 3)) ammoType--; while (((player->ammoType > -1) && !player->ammo[player->ammoType]) || (player->ammoType == 3)) player->ammoType--;
} }
...@@ -328,27 +329,27 @@ void Player::control (unsigned int ticks, int msps) { ...@@ -328,27 +329,27 @@ void Player::control (unsigned int ticks, int msps) {
// Check for a change in ammo // Check for a change in ammo
if (pcontrols[C_CHANGE]) { if (player->pcontrols[C_CHANGE]) {
if (this == localPlayer) controls.release(C_CHANGE); if (player == localPlayer) controls.release(C_CHANGE);
ammoType = ((ammoType + 2) % 5) - 1; player->ammoType = ((player->ammoType + 2) % 5) - 1;
// If there is no ammo of this type, go to the next type that has ammo // If there is no ammo of this type, go to the next type that has ammo
while ((ammoType > -1) && !ammo[ammoType]) while ((player->ammoType > -1) && !player->ammo[player->ammoType])
ammoType = ((ammoType + 2) % 5) - 1; player->ammoType = ((player->ammoType + 2) % 5) - 1;
} }
// Deal with the bird // Deal with the bird
if (bird) { if (player->bird) {
if (bird->step(ticks, msps)) { if (player->bird->step(ticks, msps)) {
delete bird; delete player->bird;
bird = NULL; player->bird = NULL;
} }
...@@ -400,7 +401,7 @@ void Player::control (unsigned int ticks, int msps) { ...@@ -400,7 +401,7 @@ void Player::control (unsigned int ticks, int msps) {
} }
else if (pcontrols[C_FIRE]) else if (player->pcontrols[C_FIRE])
animType = facing? PA_RSHOOT: PA_LSHOOT; animType = facing? PA_RSHOOT: PA_LSHOOT;
else else
...@@ -414,7 +415,7 @@ void Player::control (unsigned int ticks, int msps) { ...@@ -414,7 +415,7 @@ void Player::control (unsigned int ticks, int msps) {
} }
void Player::move (unsigned int ticks, int msps) { void LevelPlayer::move (unsigned int ticks, int msps) {
fixed pdx, pdy; fixed pdx, pdy;
int count; int count;
...@@ -621,81 +622,7 @@ void Player::move (unsigned int ticks, int msps) { ...@@ -621,81 +622,7 @@ void Player::move (unsigned int ticks, int msps) {
} }
void Player::bonusStep (unsigned int ticks, int msps, Bonus* bonus) { void LevelPlayer::view (unsigned int ticks, int mspf) {
fixed cdx, cdy;
// Bonus stages use polar coordinates for movement (but not position)
// Treat dx as change in radius
if (pcontrols[C_UP]) {
// Walk/run forwards
if (dx < 0) dx += PRA_REVERSE * msps;
else if (dx < PRS_RUN) dx += PRA_RUN * msps;
animType = PA_WALK;
} else if (pcontrols[C_DOWN]) {
// Walk/run back
if (dx > 0) dx -= PRA_REVERSE * msps;
else if (dx > PRS_REVERSE) dx -= PRA_RUN * msps;
animType = PA_WALK;
} else {
// Slow down
if (dx > 0) {
if (dx < PRA_STOP * msps) dx = 0;
else dx -= PRA_STOP * msps;
}
if (dx < 0) {
if (dx > -PRA_STOP * msps) dx = 0;
else dx += PRA_STOP * msps;
}
animType = PA_OTHER;
}
if (pcontrols[C_LEFT]) {
direction -= msps >> 2;
animType = PA_LEFT;
}
if (pcontrols[C_RIGHT]) {
direction += msps >> 2;
animType = PA_RIGHT;
}
// Apply trajectory
cdx = (MUL(fSin(direction), dx) * msps) >> 10;
cdy = (MUL(-fCos(direction), dx) * msps) >> 10;
if (!bonus->checkMask(x + cdx, y)) x += cdx;
if (!bonus->checkMask(x, y + cdy)) y += cdy;
return;
}
void Player::view (unsigned int ticks, int mspf) {
int oldViewX, oldViewY, speed; int oldViewX, oldViewY, speed;
...@@ -744,7 +671,7 @@ void Player::view (unsigned int ticks, int mspf) { ...@@ -744,7 +671,7 @@ void Player::view (unsigned int ticks, int mspf) {
} }
void Player::draw (unsigned int ticks, int change) { void LevelPlayer::draw (unsigned int ticks, int change) {
Anim *an; Anim *an;
int frame; int frame;
...@@ -776,8 +703,8 @@ void Player::draw (unsigned int ticks, int change) { ...@@ -776,8 +703,8 @@ void Player::draw (unsigned int ticks, int change) {
else { else {
an->setPalette(palette, 23, 41); an->setPalette(player->palette, 23, 41);
an->setPalette(palette, 88, 8); an->setPalette(player->palette, 88, 8);
} }
...@@ -863,13 +790,13 @@ void Player::draw (unsigned int ticks, int change) { ...@@ -863,13 +790,13 @@ void Player::draw (unsigned int ticks, int change) {
// Show the bird // Show the bird
if (bird) bird->draw(ticks, change); if (player->bird) player->bird->draw(ticks, change);
// Show the player's name // Show the player's name
if (gameMode) if (gameMode)
panelBigFont->showString(name, panelBigFont->showString(player->name,
FTOI(drawX + PXO_MID - viewX) - (panelBigFont->getStringWidth(name) >> 1), FTOI(drawX + PXO_MID - viewX) - (panelBigFont->getStringWidth(player->name) >> 1),
FTOI(drawY - F32 - F16 - viewY)); FTOI(drawY - F32 - F16 - viewY));
return; return;
......
...@@ -30,17 +30,15 @@ ...@@ -30,17 +30,15 @@
#include "bird.h" #include "bird.h"
#include "player.h" #include "bonusplayer.h"
#include "levelplayer.h"
#include "baselevel.h"
#include "game/game.h" #include "game/game.h"
#include "game/gamemode.h"
#include "io/controls.h" #include "io/controls.h"
#include "io/gfx/font.h" #include "io/gfx/font.h"
#include "io/gfx/paletteeffects.h" #include "io/gfx/paletteeffects.h"
#include "io/gfx/video.h" #include "io/gfx/video.h"
#include "io/sound.h"
#include "level/event/event.h"
#include "level/level.h"
#include "util.h" #include "util.h"
#include <string.h> #include <string.h>
...@@ -48,6 +46,9 @@ ...@@ -48,6 +46,9 @@
Player::Player () { Player::Player () {
levelPlayer = new LevelPlayer(this);
bonusPlayer = new BonusPlayer(this);
bird = NULL; bird = NULL;
name = NULL; name = NULL;
...@@ -61,6 +62,9 @@ Player::~Player () { ...@@ -61,6 +62,9 @@ Player::~Player () {
deinit(); deinit();
delete levelPlayer;
delete bonusPlayer;
return; return;
} }
...@@ -175,438 +179,62 @@ void Player::deinit () { ...@@ -175,438 +179,62 @@ void Player::deinit () {
} }
void Player::setAnims (char *newAnims) {
memcpy(anims, newAnims, PANIMS);
return;
}
char * Player::getName () {
return name;
}
unsigned char * Player::getCols () {
return cols;
}
void Player::reset () { void Player::reset () {
int count; int count;
if (bird) bird->reset(); levelPlayer->reset();
bonusPlayer->reset();
event = 0; if (bird) bird->reset();
for (count = 0; count < PCONTROLS; count++) pcontrols[count] = false; for (count = 0; count < PCONTROLS; count++) pcontrols[count] = false;
energy = 4;
shield = 0;
floating = false;
facing = true;
direction = FQ;
reaction = PR_NONE;
reactionTime = 0;
jumpHeight = ITOF(92);
jumpY = TTOF(LH);
fastFeetTime = 0;
warpTime = 0;
dx = 0;
dy = 0;
enemies = items = 0;
gem = false;
return; return;
} }
void Player::setControl (int control, bool state) { BonusPlayer* Player::getBonusPlayer () {
pcontrols[control] = state;
return; return bonusPlayer;
} }
bool Player::takeEvent (unsigned char gridX, unsigned char gridY, unsigned int ticks) { unsigned char * Player::getCols () {
signed char *set;
set = level->getEvent(gridX, gridY);
switch (set[E_MODIFIER]) {
case 41: // Bonus level
if (getEnergy()) level->setNext(set[E_MULTIPURPOSE], set[E_YAXIS]);
// The lack of a break statement is intentional
case 8: // Boss
case 27: // End of level
if (!getEnergy()) return false;
if (!gameMode) {
if (game) game->setCheckpoint(gridX, gridY);
level->setStage(LS_END);
} else if (!(gameMode->endOfLevel(this, gridX, gridY))) return false;
break;
case 0: // Enemy
break;
case 1: // Invincibility
if (!getEnergy()) return false;
reaction = PR_INVINCIBLE;
reactionTime = ticks + PRT_INVINCIBLE;
break;
case 2:
case 3: // Health
if (energy < 4) energy++;
break;
case 4: // Extra life
addLife();
break;
case 5: // High-jump feet
jumpHeight += F16;
break;
case 7: // Used with destructible blocks
break;
case 9: // Sand timer
level->addTimer();
break;
case 10: // Checkpoint
if (game) game->setCheckpoint(gridX, gridY);
break;
case 11: // Item
break;
case 12: // Rapid fire
fireSpeed++;
break;
case 15: // Ammo
addAmmo(0, 15);
break;
case 16: // Ammo
addAmmo(1, 15);
break;
case 17: // Ammo
addAmmo(2, 15);
break;
case 18: // Ammo
addAmmo(0, 2);
break;
case 19: // Ammo
addAmmo(1, 2);
break;
case 20: // Ammo
addAmmo(2, 2);
break;
case 26: // Fast feet box
fastFeetTime = ticks + T_FASTFEET;
break;
case 30: // TNT
addAmmo(3, 1);
break;
case 31: // Water level
level->setWaterLevel(gridY);
break;
case 33: // 2-hit shield
if (shield < 2) shield = 2;
break;
case 34: // Bird
if (!bird) bird = new Bird(this, gridX, gridY);
break;
case 35: // Airboard, etc.
floating = true;
break;
case 36: // 4-hit shield
shield = 6;
break;
case 37: // Diamond
gem = true;
// Yellow flash
level->flash(255, 255, 0, 320);
break;
default:
return false;
}
addScore(set[E_ADDEDSCORE]);
// Add to player's enemy/item tally
// If the event hurts and can be killed, it is an enemy
// Anything else that scores is an item
if ((set[E_MODIFIER] == 0) && set[E_HITSTOKILL]) enemies++;
else if (set[E_ADDEDSCORE]) items++;
return true; return cols;
} }
bool Player::touchEvent (unsigned char gridX, unsigned char gridY, unsigned int ticks, int msps) { char * Player::getName () {
signed char *set;
set = level->getEvent(gridX, gridY);
switch (set[E_MODIFIER]) {
case 0: // Hurt
case 8: // Boss
if ((set[E_BEHAVIOUR] < 37) || (set[E_BEHAVIOUR] > 44))
hit(NULL, ticks);
break;
case 7: // Used with destructible blocks, but should not destroy on contact
break;
case 13: // Warp
if (!warpTime) {
warpX = set[E_MULTIPURPOSE];
warpY = set[E_YAXIS];
warpTime = ticks + T_WARP;
// White flash
level->flash(255, 255, 255, T_WARP);
}
break;
case 28: // Belt
x += set[E_MAGNITUDE] * 4 * msps;
break;
case 29: // Upwards spring
setEvent(gridX, gridY);
level->playSound(set[E_SOUND]);
break;
case 31: // Water level
level->setWaterLevel(gridY);
break;
case 32: // Float up / sideways
if (set[E_YAXIS]) {
eventX = gridX;
eventY = gridY;
event = 2;
if (dy > set[E_MULTIPURPOSE] * -F20)
dy -= set[E_MULTIPURPOSE] * 320 * msps;
jumpY = y - (8 * F16);
} else if (set[E_MAGNITUDE] < 0) {
if (!level->checkMaskDown(x + PXO_L + (set[E_MAGNITUDE] * 20 * msps), y + PYO_MID))
x += set[E_MAGNITUDE] * 20 * msps;
} else {
if (!level->checkMaskDown(x + PXO_R + (set[E_MAGNITUDE] * 20 * msps), y + PYO_MID))
x += set[E_MAGNITUDE] * 20 * msps;
}
break;
case 38: // Airboard, etc. off
floating = false;
break;
default:
if (!set[E_HITSTOKILL]) return takeEvent(gridX, gridY, ticks);
break;
}
return false; return name;
} }
bool Player::hit (Player *source, unsigned int ticks) { LevelPlayer* Player::getLevelPlayer () {
// Invulnerable if reacting to e.g. having been hit
if (reaction != PR_NONE) return false;
// Hits from the same team have no effect
if (source && (source->getTeam() == team)) return false;
if (shield == 3) shield = 0;
else if (shield) shield--;
else if (!gameMode || gameMode->hit(source, this)) {
energy--;
if (bird) bird->hit();
playSound(S_OW);
}
if (energy) {
reaction = PR_HURT;
reactionTime = ticks + PRT_HURT;
if (dx < 0) {
dx = PXS_RUN;
dy = PYS_JUMP;
} else {
dx = -PXS_RUN; return levelPlayer;
dy = PYS_JUMP;
}
} else {
kill(source, ticks);
}
return true;
} }
void Player::kill (Player *source, unsigned int ticks) { void Player::setControl (int control, bool state) {
if (reaction != PR_NONE) return;
if (!gameMode || gameMode->kill(source, this)) {
energy = 0;
lives--;
reaction = PR_KILLED;
reactionTime = ticks + PRT_KILLED;
}
if (!gameMode) level->flash(0, 0, 0, T_END << 1); pcontrols[control] = state;
return; return;
} }
void Player::addItem () { bool Player::getControl (int control) {
items++;
return; return pcontrols[control];
} }
...@@ -626,13 +254,6 @@ int Player::getScore () { ...@@ -626,13 +254,6 @@ int Player::getScore () {
} }
int Player::getEnergy () {
return energy;
}
void Player::addLife () { void Player::addLife () {
if (lives < 99) lives++; if (lives < 99) lives++;
...@@ -666,69 +287,6 @@ int Player::getAmmo (bool amount) { ...@@ -666,69 +287,6 @@ int Player::getAmmo (bool amount) {
} }
int Player::getEnemies () {
return enemies;
}
int Player::getItems () {
return items;
}
bool Player::overlap (fixed left, fixed top, fixed width, fixed height) {
return (x + PXO_R >= left) && (x + PXO_L < left + width) &&
(y >= top) && (y + PYO_TOP < top + height);
}
void Player::setPosition (fixed newX, fixed newY) {
x = newX;
y = newY;
return;
}
void Player::setSpeed (fixed newDx, fixed newDy) {
dx = newDx;
if (newDy) dy = newDy;
return;
}
bool Player::getFacing () {
return facing;
}
fixed Player::getDirection () {
return direction;
}
unsigned char Player::getAnim () {
return anims[animType];
}
unsigned char Player::getTeam () { unsigned char Player::getTeam () {
return team; return team;
...@@ -736,95 +294,35 @@ unsigned char Player::getTeam () { ...@@ -736,95 +294,35 @@ unsigned char Player::getTeam () {
} }
bool Player::hasGem () { void Player::send (unsigned char *buffer) {
return gem;
}
void Player::setEvent (unsigned char gridX, unsigned char gridY) {
signed char *set;
set = level->getEvent(gridX, gridY);
if (set[E_MODIFIER] == 29) {
// Upwards spring
jumpY = y + (set[E_MAGNITUDE] * (F20 + F1));
event = 1;
} else if (set[E_MODIFIER] == 6) event = 3;
else if (set[E_BEHAVIOUR] == 28) event = 4;
else return;
eventX = gridX;
eventY = gridY;
return;
}
void Player::clearEvent (unsigned char gridX, unsigned char gridY) {
// If the location matches, clear the event
if ((gridX == eventX) && (gridY == eventY)) event = 0;
return;
}
void Player::send (unsigned char *data) {
// Copy data to be sent to clients/server // Copy data to be sent to clients/server
data[3] = pcontrols[C_UP]; buffer[3] = pcontrols[C_UP];
data[4] = pcontrols[C_DOWN]; buffer[4] = pcontrols[C_DOWN];
data[5] = pcontrols[C_LEFT]; buffer[5] = pcontrols[C_LEFT];
data[6] = pcontrols[C_RIGHT]; buffer[6] = pcontrols[C_RIGHT];
data[7] = pcontrols[C_JUMP]; buffer[7] = pcontrols[C_JUMP];
data[8] = pcontrols[C_FIRE]; buffer[8] = pcontrols[C_FIRE];
data[9] = bird? 1: 0; buffer[9] = bird? 1: 0;
data[10] = ammo[0] >> 8; buffer[10] = ammo[0] >> 8;
data[11] = ammo[0] & 255; buffer[11] = ammo[0] & 255;
data[12] = ammo[1] >> 8; buffer[12] = ammo[1] >> 8;
data[13] = ammo[1] & 255; buffer[13] = ammo[1] & 255;
data[14] = ammo[2] >> 8; buffer[14] = ammo[2] >> 8;
data[15] = ammo[2] & 255; buffer[15] = ammo[2] & 255;
data[16] = ammo[3] >> 8; buffer[16] = ammo[3] >> 8;
data[17] = ammo[3] & 255; buffer[17] = ammo[3] & 255;
data[18] = ammoType + 1; buffer[18] = ammoType + 1;
data[19] = score >> 24; buffer[19] = score >> 24;
data[20] = (score >> 16) & 255; buffer[20] = (score >> 16) & 255;
data[21] = (score >> 8) & 255; buffer[21] = (score >> 8) & 255;
data[22] = score & 255; buffer[22] = score & 255;
data[23] = energy; buffer[24] = lives;
data[24] = lives; buffer[28] = fireSpeed;
data[25] = shield; buffer[45] = pcontrols[C_SWIM];
data[26] = floating;
data[27] = facing; levelPlayer->send(buffer);
data[28] = fireSpeed;
data[29] = jumpHeight >> 24;
data[30] = (jumpHeight >> 16) & 255;
data[31] = (jumpHeight >> 8) & 255;
data[32] = jumpHeight & 255;
data[33] = jumpY >> 24;
data[34] = (jumpY >> 16) & 255;
data[35] = (jumpY >> 8) & 255;
data[36] = jumpY & 255;
data[37] = x >> 24;
data[38] = (x >> 16) & 255;
data[39] = (x >> 8) & 255;
data[40] = x & 255;
data[41] = y >> 24;
data[42] = (y >> 16) & 255;
data[43] = (y >> 8) & 255;
data[44] = y & 255;
data[45] = pcontrols[C_SWIM];
return; return;
...@@ -835,15 +333,7 @@ void Player::receive (unsigned char *buffer) { ...@@ -835,15 +333,7 @@ void Player::receive (unsigned char *buffer) {
// Interpret data received from client/server // Interpret data received from client/server
switch (buffer[1]) { if (buffer[1] == MT_P_TEMP) {
case MT_P_ANIMS:
setAnims((char *)buffer + 3);
break;
case MT_P_TEMP:
pcontrols[C_UP] = buffer[3]; pcontrols[C_UP] = buffer[3];
pcontrols[C_DOWN] = buffer[4]; pcontrols[C_DOWN] = buffer[4];
...@@ -855,7 +345,7 @@ void Player::receive (unsigned char *buffer) { ...@@ -855,7 +345,7 @@ void Player::receive (unsigned char *buffer) {
pcontrols[C_CHANGE] = false; pcontrols[C_CHANGE] = false;
if ((buffer[9] & 1) && !bird) if ((buffer[9] & 1) && !bird)
bird = new Bird(this, FTOT(x), FTOT(y)); bird = new Bird(this, FTOT(levelPlayer->getX()), FTOT(levelPlayer->getY()));
if (!(buffer[9] & 1) && bird) { if (!(buffer[9] & 1) && bird) {
...@@ -869,47 +359,15 @@ void Player::receive (unsigned char *buffer) { ...@@ -869,47 +359,15 @@ void Player::receive (unsigned char *buffer) {
ammo[2] = (buffer[14] << 8) + buffer[15]; ammo[2] = (buffer[14] << 8) + buffer[15];
ammo[3] = (buffer[16] << 8) + buffer[17]; ammo[3] = (buffer[16] << 8) + buffer[17];
ammoType = buffer[18] - 1; ammoType = buffer[18] - 1;
score = (buffer[19] << 24) + (buffer[20] << 16) + score = (buffer[19] << 24) + (buffer[20] << 16) + (buffer[21] << 8) + buffer[22];
(buffer[21] << 8) + buffer[22];
energy = buffer[23];
lives = buffer[24]; lives = buffer[24];
shield = buffer[25];
floating = buffer[26];
facing = buffer[27];
fireSpeed = buffer[28]; fireSpeed = buffer[28];
jumpHeight = (buffer[29] << 24) + (buffer[30] << 16) +
(buffer[31] << 8) + buffer[32];
jumpY = (buffer[33] << 24) + (buffer[34] << 16) +
(buffer[35] << 8) + buffer[36];
x = (buffer[37] << 24) + (buffer[38] << 16) + (buffer[39] << 8) +
buffer[40];
y = (buffer[41] << 24) + (buffer[42] << 16) + (buffer[43] << 8) +
buffer[44];
break;
} }
return; levelPlayer->receive(buffer);
}
PlayerReaction Player::reacted (unsigned int ticks) { return;
PlayerReaction oldReaction;
if ((reaction != PR_NONE) && (reactionTime < ticks)) {
oldReaction = reaction;
reaction = PR_NONE;
return oldReaction;
}
return PR_NONE;
} }
...@@ -29,7 +29,6 @@ ...@@ -29,7 +29,6 @@
#define _PLAYER_H #define _PLAYER_H
#include "movable.h"
#include "OpenJazz.h" #include "OpenJazz.h"
#include <SDL/SDL.h> #include <SDL/SDL.h>
...@@ -37,99 +36,6 @@ ...@@ -37,99 +36,6 @@
// Constants // Constants
// Level animations
#define PA_LWALK 0
#define PA_RWALK 1
#define PA_LJUMP 2
#define PA_RJUMP 3
#define PA_LSPIN 4
#define PA_RSPIN 5
#define PA_LSHOOT 6
#define PA_RSHOOT 7
#define PA_LCROUCH 8
#define PA_RCROUCH 9
#define PA_LFALL 10
#define PA_RFALL 11
#define PA_LHURT 12
#define PA_RHURT 13
#define PA_LLEAN 14
#define PA_RLEAN 15
#define PA_LBOARD 16
#define PA_RBOARD 17
#define PA_LSTAND 18
#define PA_RSTAND 19
#define PA_LEAT 20
#define PA_REAT 21
#define PA_LEDGE 22
#define PA_REDGE 23
#define PA_LOOKUP 24
#define PA_LOOKDOWN 25
#define PA_LSWIM 26
#define PA_RSWIM 27
#define PA_LRUN 28
#define PA_RRUN 29
#define PA_LDIE 30
#define PA_RDIE 31
#define PA_LSTOP 32
#define PA_RSTOP 33
#define PA_LHALT 34 /* Yeah, I was wondering the same thing... */
#define PA_RHALT 35
#define PA_RSPRING 36
#define PA_LSPRING 37 /* Surely these are the wrong way round? */
// Bonus level animations
#define PA_WALK 0
#define PA_LEFT 1
#define PA_RIGHT 2
#define PA_USER 3
#define PA_JUMP 4
#define PA_CRASH 5
#define PA_OTHER 6
// Player reaction times
#define PRT_HURT 1000
#define PRT_HURTANIM 200
#define PRT_KILLED 2000
#define PRT_INVINCIBLE 10000
// Other time periods
#define T_FASTFEET 25000
#define T_WARP 1000
// Player offsets
#define PXO_MID F16
#define PXO_L (PXO_MID - F10)
#define PXO_ML (PXO_MID - F4)
#define PXO_MR (PXO_MID + F4)
#define PXO_R (PXO_MID + F10)
#define PYO_TOP (-F20)
#define PYO_MID (-F10)
// Player speeds
#define PXS_WALK ITOF(300)
#define PXS_RUN ITOF(325)
#define PXS_FFRUN ITOF(500)
#define PYS_FALL ITOF(350)
#define PYS_SINK ITOF(150)
#define PYS_JUMP ITOF(-350)
#define PRS_REVERSE ITOF(-32)
#define PRS_RUN ITOF(64)
#define PRS_ROLL ITOF(96)
// Player accelerations
#define PXA_REVERSE 900
#define PXA_STOP 1000
#define PXA_WALK 500
#define PXA_RUN 200
#define PXA_FFRUN 200
#define PYA_GRAVITY 2750
#define PYA_SINK 1000
#define PRA_REVERSE 450
#define PRA_STOP 500
#define PRA_RUN 100
// Player colours // Player colours
#define PC_WHITE 0 #define PC_WHITE 0
#define PC_SGREEN 16 #define PC_SGREEN 16
...@@ -158,56 +64,28 @@ ...@@ -158,56 +64,28 @@
#define PCONTROLS 8 /* Number of player controls. */ #define PCONTROLS 8 /* Number of player controls. */
// Enum
enum PlayerReaction {
PR_NONE, PR_HURT, PR_KILLED, PR_INVINCIBLE
};
// Classes // Classes
class Anim;
class Bird; class Bird;
class Bonus; class BonusPlayer;
class LevelPlayer;
class Player : public Movable { class Player {
private: private:
LevelPlayer* levelPlayer;
BonusPlayer* bonusPlayer;
Bird* bird; Bird* bird;
char* name; char* name;
char anims[PANIMS];
bool pcontrols[PCONTROLS]; bool pcontrols[PCONTROLS];
SDL_Color palette[256]; SDL_Color palette[256];
unsigned char cols[4]; unsigned char cols[4];
int ammo[4]; int ammo[4];
int ammoType; /* -1 = blaster, 0 = toaster, 1 = missiles, 2 = bouncer 3 = TNT */ int ammoType; /* -1 = blaster, 0 = toaster, 1 = missiles, 2 = bouncer 3 = TNT */
int score; int score;
int energy;
int lives; int lives;
int shield; /* 0 = none, 1 = 1 yellow, 2 = 2 yellow, 3 = 1 orange, 4 = 2 orange, 5 = 3 orange, 6 = 4 orange */
bool floating; /* false = normal, true = boarding/bird/etc. */
bool facing;
fixed direction;
unsigned char animType;
unsigned char eventX;
unsigned char eventY; /* Position of an event (spring, platform, bridge) */
int event; /* 0 = none, 1 = spring, 2 = float up, 3 = platform, 4 = bridge */
int lookTime; /* Negative if looking up, positive if looking down, 0 if neither */
PlayerReaction reaction;
unsigned int reactionTime;
int fireSpeed; int fireSpeed;
unsigned int fireTime;
fixed jumpHeight;
fixed jumpY;
unsigned int fastFeetTime;
unsigned char warpX, warpY;
unsigned int warpTime;
int enemies, items;
unsigned char team; unsigned char team;
bool gem;
void addAmmo (int type, int amount); void addAmmo (int type, int amount);
...@@ -219,42 +97,25 @@ class Player : public Movable { ...@@ -219,42 +97,25 @@ class Player : public Movable {
void init (char* playerName, unsigned char* cols, unsigned char newTeam); void init (char* playerName, unsigned char* cols, unsigned char newTeam);
void deinit (); void deinit ();
void setAnims (char* newAnims);
char* getName ();
unsigned char* getCols ();
void reset (); void reset ();
void setControl (int control, bool state);
bool takeEvent (unsigned char gridX, unsigned char gridY, unsigned int ticks);
bool touchEvent (unsigned char gridX, unsigned char gridY, unsigned int ticks, int msps);
void setEvent (unsigned char gridX, unsigned char gridY);
void clearEvent (unsigned char gridX, unsigned char gridY);
bool hit (Player* source, unsigned int ticks);
void kill (Player* source, unsigned int ticks);
void addItem ();
void addLife (); void addLife ();
void addScore (int addedScore); void addScore (int addedScore);
int getScore ();
int getEnergy ();
int getLives ();
int getAmmo (bool amount); int getAmmo (bool amount);
int getEnemies (); BonusPlayer* getBonusPlayer ();
int getItems (); unsigned char* getCols ();
bool overlap (fixed left, fixed top, fixed width, fixed height); bool getControl (int control);
void setPosition (fixed newX, fixed newY); LevelPlayer* getLevelPlayer ();
void setSpeed (fixed newDx, fixed newDy); int getLives ();
bool getFacing (); char* getName ();
fixed getDirection (); int getScore ();
unsigned char getAnim ();
unsigned char getTeam (); unsigned char getTeam ();
bool hasGem (); void setControl (int control, bool state);
void send (unsigned char* data);
void send (unsigned char* buffer);
void receive (unsigned char* buffer); void receive (unsigned char* buffer);
void control (unsigned int ticks, int msps);
void move (unsigned int ticks, int msps); friend class LevelPlayer;
void bonusStep (unsigned int ticks, int msps, Bonus* bonus);
void view (unsigned int ticks, int mspf);
void draw (unsigned int ticks, int change);
PlayerReaction reacted (unsigned int ticks);
}; };
......
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