Particles processing, Bob, and entity actions.

This commit is contained in:
Steve 2018-02-01 21:51:43 +00:00
parent 7cd5fe999a
commit 0df09f914a
16 changed files with 728 additions and 106 deletions

View File

@ -61,19 +61,20 @@ void initWeapons(void)
missileSprite[1] = getSprite("MissileLeft"); missileSprite[1] = getSprite("MissileLeft");
} }
void firePistol(Unit *owner) /* only used by Bob */
void firePistol(void)
{ {
Bullet *bullet; Bullet *bullet;
bullet = createBaseBullet(owner); bullet = createBaseBullet((Unit*)world.bob);
bullet->weaponType = WPN_PISTOL; bullet->weaponType = WPN_PISTOL;
bullet->facing = owner->facing; bullet->facing = world.bob->facing;
bullet->sprite[0] = bulletSprite[0]; bullet->sprite[0] = bulletSprite[0];
bullet->sprite[1] = bulletSprite[1]; bullet->sprite[1] = bulletSprite[1];
owner->reload = 20; world.bob->reload = 20;
playSound(SND_PISTOL, CH_PLAYER); playSound(SND_PISTOL, CH_BOB);
} }
void fireAimedShot(Unit *owner) void fireAimedShot(Unit *owner)
@ -124,7 +125,7 @@ void firePlasma(Unit *owner)
owner->reload = owner->type == ET_BOB ? 4 : 8; owner->reload = owner->type == ET_BOB ? 4 : 8;
playSound(SND_PLASMA, owner->type == ET_BOB ? CH_PLAYER : CH_WEAPON); playSound(SND_PLASMA, owner->type == ET_BOB ? CH_BOB : CH_WEAPON);
} }
void fireSpread(Unit *owner, int numberOfShots) void fireSpread(Unit *owner, int numberOfShots)
@ -148,7 +149,7 @@ void fireSpread(Unit *owner, int numberOfShots)
owner->reload = 16; owner->reload = 16;
} }
playSound(SND_SPREAD, owner->type == ET_BOB ? CH_PLAYER : CH_WEAPON); playSound(SND_SPREAD, owner->type == ET_BOB ? CH_BOB : CH_WEAPON);
} }
void fireLaser(Unit *owner) void fireLaser(Unit *owner)
@ -167,7 +168,7 @@ void fireLaser(Unit *owner)
owner->reload = owner->type == ET_BOB ? FPS / 2 : FPS; owner->reload = owner->type == ET_BOB ? FPS / 2 : FPS;
playSound(SND_LASER, owner->type == ET_BOB ? CH_PLAYER : CH_WEAPON); playSound(SND_LASER, owner->type == ET_BOB ? CH_BOB : CH_WEAPON);
} }
void fireGrenade(Unit *owner) void fireGrenade(Unit *owner)
@ -187,7 +188,7 @@ void fireGrenade(Unit *owner)
owner->reload = FPS / 2; owner->reload = FPS / 2;
playSound(SND_THROW, owner->type == ET_BOB ? CH_PLAYER : CH_WEAPON); playSound(SND_THROW, owner->type == ET_BOB ? CH_BOB : CH_WEAPON);
} }
void fireShotgun(Unit *owner) void fireShotgun(Unit *owner)

View File

@ -209,7 +209,8 @@ enum
enum enum
{ {
WS_IN_PROGRESS, WS_IN_PROGRESS,
WS_COMPLETE WS_COMPLETE,
WS_GAME_OVER
}; };
enum enum
@ -289,7 +290,7 @@ enum
enum enum
{ {
CH_ANY = -1, CH_ANY = -1,
CH_PLAYER, CH_BOB,
CH_EXPLODE, CH_EXPLODE,
CH_WEAPON, CH_WEAPON,
CH_DEATH, CH_DEATH,

View File

@ -23,8 +23,29 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
static SDL_Rect *getCurrentSprite(void); static SDL_Rect *getCurrentSprite(void);
static void (*superAnimate)(void); static void (*superAnimate)(void);
static void animate(void); static void animate(void);
static void tick(void);
static void doAlive(void);
static void doDying(void);
static void doBobInWater(void);
static void doBobInAir(void);
static void handeImmunity(void);
static void changeSprite(Sprite **sprite);
static void load(cJSON *root); static void load(cJSON *root);
static void save(cJSON *root); static void save(cJSON *root);
static int completelyOnGround(void);
void resetAtCheckpoint(void);
void terminateJetpack(void);
static void bobFly(void);
static void bobWalk(void);
static void bobSwim(void);
static void fireWeapon(void);
static void activate(int activate);
static void changeEnvironment(void);
static Sprite *walkSprite[3];
static Sprite *swimSprite[3];
static Sprite *flySprite[3];
static int checkpointTimer;
void initBob(void) void initBob(void)
{ {
@ -34,18 +55,563 @@ void initBob(void)
u->type = ET_BOB; u->type = ET_BOB;
u->sprite[FACING_LEFT] = getSprite("BobLeft"); memset(&world.bob->itemHead, 0, sizeof(Item));
u->sprite[FACING_RIGHT] = getSprite("BobRight"); world.bob->itemTail = &world.bob->itemHead;
u->sprite[FACING_DIE] = getSprite("BobSpin");
walkSprite[FACING_LEFT] = getSprite("BobLeft");
walkSprite[FACING_RIGHT] = getSprite("BobRight");
walkSprite[FACING_DIE] = getSprite("BobSpin");
swimSprite[FACING_LEFT] = getSprite("BobAquaLeft");
swimSprite[FACING_RIGHT] = getSprite("BobAquaRight");
swimSprite[FACING_DIE] = getSprite("BobAquaSpin");
flySprite[FACING_LEFT] = getSprite("BobJPLeft");
flySprite[FACING_RIGHT] = getSprite("BobJPRight");
flySprite[FACING_DIE] = getSprite("BobSpin");
changeSprite(walkSprite);
world.bob->health = world.bob->healthMax = game.hearts;
world.bob->power = world.bob->powerMax = game.cells;
world.bob->weaponType = WPN_PISTOL;
world.bob->reload = 0;
world.bob->flags |= EF_SWIMS | EF_BOMB_SHIELD;
superAnimate = u->animate; superAnimate = u->animate;
world.bob->tick = tick;
u->getCurrentSprite = getCurrentSprite; u->getCurrentSprite = getCurrentSprite;
u->animate = animate; u->animate = animate;
u->activate = activate;
u->changeEnvironment = changeEnvironment;
u->load = load; u->load = load;
u->save = save; u->save = save;
} }
static void tick(void)
{
if (world.isTrainingMission || dev.cheatHealth)
{
world.bob->alive = ALIVE_ALIVE;
world.bob->health = world.bob->healthMax;
}
if (world.isTrainingMission)
{
world.bob->power = MIN(world.bob->power + 0.01, world.bob->powerMax);
}
else
{
world.bob->power = MIN(world.bob->power + 0.00065, world.bob->powerMax);
}
if (dev.cheatPower)
{
world.bob->power = world.bob->powerMax;
}
if (dev.cheatReload && world.bob->reload > 4)
{
world.bob->reload = 4;
}
switch (world.bob->alive)
{
case ALIVE_ALIVE:
doAlive();
break;
case ALIVE_DYING:
doDying();
break;
default:
break;
}
}
static void doAlive(void)
{
handeImmunity();
world.bob->checkpointTimer = MAX(world.bob->checkpointTimer - 1, 0);
world.bob->reload = limit(world.bob->reload - 1, 0, FPS);
switch (world.bob->environment)
{
case ENV_AIR:
doBobInAir();
break;
case ENV_WATER:
doBobInWater();
break;
case ENV_SLIME:
if (world.bob->alive == ALIVE_ALIVE && world.bob->outTimer == 0)
{
world.bob->outTimer = FPS * 3;
world.bob->stunTimer = 1;
if (world.bob->flags & EF_IMMUNE)
{
world.bob->health--;
}
}
break;
case ENV_LAVA:
if (world.bob->alive == ALIVE_ALIVE && world.bob->outTimer == 0)
{
world.bob->outTimer = FPS * 3;
world.bob->stunTimer = 1;
if (world.bob->flags & EF_IMMUNE)
{
world.bob->health -= 2;
}
}
break;
}
}
static void handeImmunity(void)
{
int i;
if (world.bob->outTimer > 0)
{
world.bob->outTimer--;
if (world.bob->outTimer <= 0)
{
world.betweenTimer = FPS / 2;
resetAtCheckpoint();
}
}
else if (world.bob->stunTimer > 0)
{
world.bob->stunTimer--;
if (world.bob->stunTimer <= 0)
{
if (!world.bob->isOnGround && world.bob->environment != ENV_WATER)
{
world.bob->stunTimer = 1;
}
else
{
world.bob->spriteFrame = 0;
world.bob->spriteTime = 0;
world.bob->dy = 0;
world.bob->flags &= ~EF_BOUNCES;
world.bob->flags |= EF_FLICKER;
}
}
}
else if (world.bob->immuneTimer > 0)
{
world.bob->immuneTimer--;
if (world.bob->immuneTimer <= 0)
{
world.bob->flags &= ~(EF_FLICKER | EF_IMMUNE);
}
}
else if (world.bob->checkpointTimer == 0 && world.bob->isOnGround && completelyOnGround() && world.bob->environment == ENV_AIR && world.bob->riding == NULL)
{
for (i = MAX_CHECKPOINTS - 1 ; i > 0 ; i--)
{
world.bob->checkpoints[i].x = world.bob->checkpoints[i - 1].x;
world.bob->checkpoints[i].y = world.bob->checkpoints[i - 1].y;
}
world.bob->checkpoints[0].x = world.bob->x;
world.bob->checkpoints[0].y = world.bob->y;
checkpointTimer = FPS;
}
}
static int completelyOnGround(void)
{
int x1, x2, y;
x1 = (world.bob->x / MAP_TILE_SIZE);
x2 = ((world.bob->x + world.bob->w) / MAP_TILE_SIZE);
y = ((world.bob->y + world.bob->h + 8) / MAP_TILE_SIZE);
return isSolid(x1, y) && isSolid(x2, y);
}
static void activate(int activate)
{
if (world.bob->stunTimer <= 0)
{
if (world.bob->flags & (EF_WATER_BREATHING | EF_WEIGHTLESS))
{
world.bob->flags &= ~(EF_WATER_BREATHING | EF_WEIGHTLESS);
changeSprite(walkSprite);
}
else if (world.bob->power > 0)
{
if (world.bob->environment == ENV_AIR)
{
world.bob->flags |= EF_WEIGHTLESS;
changeSprite(flySprite);
}
else if (world.bob->environment == ENV_WATER)
{
world.bob->flags |= EF_WATER_BREATHING;
changeSprite(swimSprite);
}
world.bob->dy = 0;
}
else
{
if (world.bob->environment == ENV_AIR)
{
setGameplayMessage(MSG_STANDARD, _("Not enough power for jetpack"));
}
else
{
setGameplayMessage(MSG_STANDARD, _("Not enough power for aqualung"));
}
}
}
}
static void doBobInAir(void)
{
world.bob->oxygen = limit(world.bob->oxygen + 4, 0, MAX_OXYGEN);
if (world.bob->flags & EF_WEIGHTLESS)
{
if (!dev.cheatPower)
{
world.bob->power = limit(world.bob->power - (1.0 / FPS), 0, world.bob->powerMax);
}
if (--world.bob->jpEffectTimer <= 0)
{
addFlameParticles(world.bob->x + (world.bob->facing * 25) + rrnd(-1, 1), world.bob->y + 25 + rrnd(-1, 1));
world.bob->jpEffectTimer = 1;
}
if (world.bob->power == 0)
{
terminateJetpack();
}
}
}
void terminateJetpack(void)
{
changeSprite(walkSprite);
world.bob->flags &= ~EF_WEIGHTLESS;
}
static void doBobInWater(void)
{
if (world.bob->flags & EF_WATER_BREATHING)
{
if (!dev.cheatPower)
{
world.bob->power = limit(world.bob->power - (1.0 / FPS), 0, world.bob->powerMax);
}
if (world.bob->power == 0)
{
world.bob->flags &= ~EF_WATER_BREATHING;
changeSprite(walkSprite);
}
}
else
{
world.bob->oxygen = limit(--world.bob->oxygen, 0, MAX_OXYGEN);
if (world.bob->oxygen == 0 && (world.frameCounter % 30) == 0)
{
world.bob->health--;
playSound(SND_DROWN, CH_BOB);
}
}
}
static void doDying(void)
{
world.bob->health--;
if (world.bob->health <= -(FPS * 2))
{
world.bob->alive = ALIVE_DEAD;
throwFleshChunks(world.bob->x + world.bob->w / 2, world.bob->y + world.bob->h / 2, rrnd(3, 6));
world.state = WS_GAME_OVER;
playSound(SND_SPLAT, CH_BOB);
game.deaths++;
}
}
void stunBob(void)
{
terminateJetpack();
world.bob->stunTimer = FPS;
world.bob->immuneTimer = FPS * 2;
world.bob->spriteFrame = 0;
world.bob->spriteTime = 0;
world.bob->flags &= ~EF_FLICKER;
world.bob->flags |= (EF_BOUNCES | EF_IMMUNE);
}
void applyDamage(int damage)
{
if (!(world.bob->flags & EF_IMMUNE) && !world.isTrainingMission && !dev.cheatHealth && world.bob->alive != ALIVE_DEAD)
{
if (world.bob->health < 0)
{
world.bob->health = 0;
world.bob->alive = ALIVE_ALIVE;
}
world.bob->health -= damage;
if (world.bob->health > 0)
{
world.bob->immuneTimer = FPS * 2;
world.bob->flags |= EF_FLICKER | EF_IMMUNE;
}
}
}
void doBob(void)
{
if (world.bob->stunTimer <= 0 && world.bob->health > 0)
{
if (world.bob->flags & EF_WEIGHTLESS)
{
bobFly();
}
else if (world.bob->environment == ENV_AIR)
{
bobWalk();
}
else if (world.bob->environment == ENV_WATER)
{
bobSwim();
}
}
}
static void bobWalk(void)
{
world.bob->dx = 0;
if (game.config.control[CONTROL_LEFT])
{
world.bob->dx = -WALK_SPEED;
world.bob->facing = FACING_LEFT;
}
if (game.config.control[CONTROL_RIGHT])
{
world.bob->dx = WALK_SPEED;
world.bob->facing = FACING_RIGHT;
}
if (game.config.control[CONTROL_JUMP] && world.bob->isOnGround)
{
world.bob->dy = JUMP_POWER;
}
if (game.config.control[CONTROL_FIRE] && world.bob->reload == 0)
{
fireWeapon();
}
}
static void bobSwim(void)
{
world.bob->dx = 0;
world.bob->dy = 0.5f;
if (game.config.control[CONTROL_LEFT])
{
world.bob->dx = -SWIM_SPEED;
world.bob->facing = FACING_LEFT;
}
if (game.config.control[CONTROL_RIGHT])
{
world.bob->dx = SWIM_SPEED;
world.bob->facing = FACING_RIGHT;
}
if (game.config.control[CONTROL_JUMP] || game.config.control[CONTROL_UP])
{
world.bob->dy = -SWIM_SPEED;
}
if (game.config.control[CONTROL_DOWN])
{
world.bob->dy = SWIM_SPEED;
}
if (game.config.control[CONTROL_FIRE] && world.bob->reload == 0 && world.bob->weaponType == WPN_PISTOL)
{
firePistol();
}
}
static void bobFly(void)
{
if (game.config.control[CONTROL_LEFT])
{
world.bob->dx -= FLY_ACCEL;
world.bob->facing = FACING_LEFT;
}
if (game.config.control[CONTROL_RIGHT])
{
world.bob->dx += FLY_ACCEL;
world.bob->facing = FACING_RIGHT;
}
if (game.config.control[CONTROL_UP])
{
world.bob->dy -= FLY_ACCEL;
}
if (game.config.control[CONTROL_DOWN])
{
world.bob->dy += FLY_ACCEL;
}
if (game.config.control[CONTROL_FIRE] && world.bob->reload == 0)
{
fireWeapon();
}
world.bob->dx = MIN(FLY_SPEED, MAX(world.bob->dx, -FLY_SPEED));
world.bob->dy = MIN(FLY_SPEED, MAX(world.bob->dy, -FLY_SPEED));
}
static void fireWeapon(void)
{
switch (world.bob->weaponType)
{
case WPN_PISTOL:
firePistol();
break;
case WPN_PLASMA:
firePlasma((Entity*)world.bob);
break;
case WPN_SPREAD:
fireSpread((Entity*)world.bob, 3);
game.statShotsFired[WPN_SPREAD] += 2;
break;
case WPN_LASER:
fireLaser((Entity*)world.bob);
break;
case WPN_GRENADES:
fireGrenade((Entity*)world.bob);
break;
default:
break;
}
game.statShotsFired[world.bob->weaponType]++;
}
static void changeEnvironment(void)
{
switch (world.bob->environment)
{
case ENV_AIR:
case ENV_LAVA:
case ENV_SLIME:
world.bob->flags &= ~EF_WATER_BREATHING;
changeSprite(walkSprite);
break;
case ENV_WATER:
terminateJetpack();
break;
}
}
static void changeSprite(Sprite **sprite)
{
world.bob->sprite[0] = sprite[0];
world.bob->sprite[1] = sprite[1];
world.bob->sprite[2] = sprite[2];
world.bob->spriteFrame = 0;
world.bob->spriteTime = 0;
}
void setCheckpoint(void)
{
world.bob->checkpoints[0].x = world.bob->x;
world.bob->checkpoints[0].y = world.bob->y;
}
void resetAtCheckpoint(void)
{
world.bob->x = world.bob->checkpoints[0].x;
world.bob->y = world.bob->checkpoints[0].y;
world.bob->outTimer = 0;
world.bob->flags |= EF_FLICKER;
world.bob->flags &= ~EF_WEIGHTLESS;
changeSprite(walkSprite);
world.bob->environment = ENV_AIR;
if (!game.isResumingMission)
{
world.bob->immuneTimer = FPS * 2;
addTeleportStars((Entity*)world.bob);
if (world.state == WS_IN_PROGRESS)
{
playSound(SND_APPEAR, CH_ANY);
}
}
}
void die(void)
{
world.bob->flags &= ~EF_WEIGHTLESS;
world.bob->flags |= EF_BOUNCES;
if (world.bob->environment == ENV_AIR)
{
world.bob->dy = -9;
}
world.bob->dx = (randF() - randF()) * 5;
switch (rand() % 3)
{
case 0:
playSound(SND_DEATH_1, CH_DEATH);
break;
case 1:
playSound(SND_DEATH_2, CH_DEATH);
break;
case 2:
playSound(SND_DEATH_3, CH_DEATH);
break;
}
}
void addBobItem(Item *i) void addBobItem(Item *i)
{ {

View File

@ -21,9 +21,34 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "../../common.h" #include "../../common.h"
#include "../../json/cJSON.h" #include "../../json/cJSON.h"
#define WALK_SPEED 5
#define SWIM_SPEED 3
#define FLY_ACCEL 0.1
#define FLY_SPEED 8
extern Unit *createUnit(void); extern Unit *createUnit(void);
extern Sprite *getSprite(char *name); extern Sprite *getSprite(char *name);
extern char *getLookupName(const char *prefix, long num); extern char *getLookupName(const char *prefix, long num);
extern long lookup(const char *name); extern long lookup(const char *name);
extern double randF(void);
extern int rrnd(int low, int high);
extern float limit(float i, float a, float b);
extern int isSolid(int x, int y);
extern void setGameplayMessage(int type, char *format, ...);
extern void playSound(int snd, int ch);
extern void addFlameParticles(float x, float y);
extern void throwFleshChunks(float x, float y, int amount);
extern void firePistol(void);
extern void fireAimedShot(Entity *e);
extern void fireMachineGun(Entity *e);
extern void fireGrenade(Entity *e);
extern void firePlasma(Entity *e);
extern void fireSpread(Entity *e, int n);
extern void fireLaser(Entity *e);
extern void fireShotgun(Entity *e);
extern void fireMissile(Entity *e);
extern void addTeleportStars(Entity *e);
extern Dev dev;
extern Game game;
extern World world; extern World world;

View File

@ -326,8 +326,8 @@ void reappear(void)
do do
{ {
r = (int) (rand() % MAX_CHECKPOINTS); r = (int) (rand() % MAX_CHECKPOINTS);
self->x = world.checkpoints[r].x; self->x = world.bob->checkpoints[r].x;
self->y = world.checkpoints[r].y; self->y = world.bob->checkpoints[r].y;
valid = (self->x != 0 && self->y != 0); valid = (self->x != 0 && self->y != 0);
} }
while (!valid); while (!valid);

View File

@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
static void init(void); static void init(void);
static void reset(void); static void reset(void);
static void action(void);
static void applyDamage(int damage); static void applyDamage(int damage);
static float bounce(float x); static float bounce(float x);
static SDL_Rect *getBounds(void); static SDL_Rect *getBounds(void);
@ -54,6 +55,7 @@ void initEntity(Entity *e)
e->init = init; e->init = init;
e->reset = reset; e->reset = reset;
e->action = action;
e->animate = animate; e->animate = animate;
e->tick = tick; e->tick = tick;
e->touch = touch; e->touch = touch;
@ -79,6 +81,10 @@ static void reset(void)
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_WARN, "Cannot reset() entity [name=%s, type=%d, x=%d, y=%d]", self->name, self->type, (int)self->x, (int)self->y); SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_WARN, "Cannot reset() entity [name=%s, type=%d, x=%d, y=%d]", self->name, self->type, (int)self->x, (int)self->y);
} }
static void action(void)
{
}
static SDL_Rect *getBounds(void) static SDL_Rect *getBounds(void)
{ {
self->bounds.x = self->x; self->bounds.x = self->x;
@ -141,24 +147,6 @@ static float bounce(float x)
return x; return x;
} }
void teleport(Entity *e, float tx, float ty)
{
e->tx = tx;
e->ty = ty;
e->flags |= EF_TELEPORTING;
addTeleportStars(e);
}
void activateEntities(char *names, int activate)
{
}
void teleportEntity(Entity *e, float tx, float ty)
{
}
static void applyDamage(int damage) static void applyDamage(int damage)
{ {
@ -188,27 +176,3 @@ static void save(cJSON *root)
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_ERROR, "Entity [name=%s, type=%d, x=%d, y=%d] cannot be saved", self->name, self->type, (int)self->x, (int)self->y); SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_ERROR, "Entity [name=%s, type=%d, x=%d, y=%d] cannot be saved", self->name, self->type, (int)self->x, (int)self->y);
exit(1); exit(1);
} }
void dropCarriedItem(void)
{
EntityExt *e;
Item *i;
e = (EntityExt*)self;
if (e->carriedItem != NULL)
{
i = e->carriedItem;
i->x = (e->x + e->w / 2) - i->w / 2;
i->y = e->y;
i->dx = i->dy = 0;
world.entityTail->next = (Entity*)i;
world.entityTail = (Entity*)i;
world.entityTail->next = NULL;
e->carriedItem = NULL;
}
}

View File

@ -20,7 +20,5 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "../common.h" #include "../common.h"
extern void addTeleportStars(Entity *e);
extern Entity *self; extern Entity *self;
extern World world; extern World world;

View File

@ -43,6 +43,6 @@ static void touch(Entity *other)
pickupItem(); pickupItem();
playSound(SND_CHERRY, CH_PLAYER); playSound(SND_CHERRY, CH_BOB);
} }
} }

View File

@ -157,6 +157,7 @@ struct EntityExt {
struct Entity; struct Entity;
char spriteName[MAX_NAME_LENGTH]; char spriteName[MAX_NAME_LENGTH];
Item *carriedItem; Item *carriedItem;
Entity *riding;
}; };
struct Unit { struct Unit {
@ -205,8 +206,14 @@ struct Item {
struct Bob { struct Bob {
struct Unit; struct Unit;
int checkpointTimer;
int outTimer;
int stunTimer; int stunTimer;
int immuneTimer;
int power, powerMax; int power, powerMax;
int jpEffectTimer;
PointF checkpoints[MAX_CHECKPOINTS];
Item itemHead, *itemTail;
}; };
struct Structure { struct Structure {
@ -322,12 +329,12 @@ typedef struct {
int awaitingWidgetInput; int awaitingWidgetInput;
int lastKeyPressed; int lastKeyPressed;
int lastButtonPressed; int lastButtonPressed;
int keyControls[CONTROL_MAX];
} App; } App;
typedef struct { typedef struct {
int sound; int sound;
int music; int music;
int control[CONTROL_MAX];
} Config; } Config;
typedef struct { typedef struct {
@ -435,12 +442,13 @@ typedef struct {
int allObjectivesComplete; int allObjectivesComplete;
int frameCounter; int frameCounter;
int currentStatus; int currentStatus;
int isTrainingMission;
int isBossMission; int isBossMission;
int isBossActive; int isBossActive;
int isOutpostMission; int isOutpostMission;
int isReturnVisit; int isReturnVisit;
int missionCompleteTimer; int missionCompleteTimer;
PointF checkpoints[MAX_CHECKPOINTS]; int betweenTimer;
Quadtree quadtree; Quadtree quadtree;
Entity entityHead, *entityTail; Entity entityHead, *entityTail;
Particle particleHead, *particleTail; Particle particleHead, *particleTail;

View File

@ -49,6 +49,10 @@ void initAtlasTest(void)
static void logic(void) static void logic(void)
{ {
doEntities();
doParticles();
if (--timeout <= 0) if (--timeout <= 0)
{ {
trackRandomEntity(); trackRandomEntity();

View File

@ -32,6 +32,8 @@ extern void loadWorld(char *filename);
extern void drawMap(void); extern void drawMap(void);
extern void drawEntities(void); extern void drawEntities(void);
extern void cameraTrack(Entity *e); extern void cameraTrack(Entity *e);
extern void doEntities(void);
extern void doParticles(void);
extern App app; extern App app;
extern World world; extern World world;

View File

@ -27,6 +27,19 @@ void initEntities(void)
atlasTexture = getTexture("gfx/atlas/atlas.png"); atlasTexture = getTexture("gfx/atlas/atlas.png");
} }
void doEntities(void)
{
for (self = world.entityHead.next ; self != NULL ; self = self->next)
{
self->tick();
if (--self->thinkTime <= 0)
{
self->action();
}
}
}
void drawEntities(void) void drawEntities(void)
{ {
int x, y; int x, y;
@ -39,3 +52,45 @@ void drawEntities(void)
blitRect(atlasTexture->texture, x, y, self->getCurrentSprite(), 0); blitRect(atlasTexture->texture, x, y, self->getCurrentSprite(), 0);
} }
} }
void activateEntities(char *names, int activate)
{
}
void teleportEntity(Entity *e, float tx, float ty)
{
}
void dropCarriedItem(void)
{
EntityExt *e;
Item *i;
e = (EntityExt*)self;
if (e->carriedItem != NULL)
{
i = e->carriedItem;
i->x = (e->x + e->w / 2) - i->w / 2;
i->y = e->y;
i->dx = i->dy = 0;
world.entityTail->next = (Entity*)i;
world.entityTail = (Entity*)i;
world.entityTail->next = NULL;
e->carriedItem = NULL;
}
}
void teleport(Entity *e, float tx, float ty)
{
e->tx = tx;
e->ty = ty;
e->flags |= EF_TELEPORTING;
addTeleportStars(e);
}

View File

@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
extern Texture *getTexture(const char *filename); extern Texture *getTexture(const char *filename);
extern void blitRect(SDL_Texture *texture, int x, int y, SDL_Rect *srcRect, int center); extern void blitRect(SDL_Texture *texture, int x, int y, SDL_Rect *srcRect, int center);
extern void addTeleportStars(Entity *e);
extern Entity *self; extern Entity *self;
extern Camera camera; extern Camera camera;

View File

@ -44,6 +44,45 @@ void initParticles(void)
teleportStarSprite = getSprite("TeleportStar"); teleportStarSprite = getSprite("TeleportStar");
} }
void doParticles(void)
{
Particle *p, *prev;
int camMidX, camMidY;
camMidX = camera.x + (SCREEN_WIDTH / 2);
camMidY = camera.y + (SCREEN_HEIGHT / 2);
prev = &world.particleHead;
for (p = world.particleHead.next ; p != NULL ; p = p->next)
{
animate(p);
p->x += p->dx;
p->y += p->dy;
p->onScreen = 0;
if (--p->health <= 0 || (p->destroyAfterAnim && p->spriteTime == -1))
{
if (p == world.particleTail)
{
world.particleTail = prev;
}
prev->next = p->next;
free(p);
p = prev;
}
else if (getDistance(camMidX, camMidY, p->x, p->y) < SCREEN_WIDTH)
{
p->onScreen = 1;
}
prev = p;
}
}
void addBlood(float x, float y) void addBlood(float x, float y)
{ {
Particle *p; Particle *p;
@ -198,45 +237,6 @@ void addTeleporterEffect(float x, float y)
p->spriteFrame = (rand() % 12); p->spriteFrame = (rand() % 12);
} }
void doParticles(void)
{
Particle *p, *prev;
int camMidX, camMidY;
camMidX = camera.x + (SCREEN_WIDTH / 2);
camMidY = camera.y + (SCREEN_HEIGHT / 2);
prev = &world.particleHead;
for (p = world.particleHead.next ; p != NULL ; p = p->next)
{
animate(p);
p->x += p->dx;
p->y += p->dy;
p->onScreen = 0;
if (--p->health <= 0 || (p->destroyAfterAnim && p->spriteTime == -1))
{
if (p == world.particleTail)
{
world.particleTail = prev;
}
prev->next = p->next;
free(p);
p = prev;
}
else if (getDistance(camMidX, camMidY, p->x, p->y) < SCREEN_WIDTH)
{
p->onScreen = 1;
}
prev = p;
}
}
static void animate(Particle *p) static void animate(Particle *p)
{ {

View File

@ -19,7 +19,3 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#include "player.h" #include "player.h"
void stunBob(void)
{
}

View File

@ -37,6 +37,7 @@ void loadWorld(char *filename)
world.entityTail = &world.entityHead; world.entityTail = &world.entityHead;
world.triggerTail = &world.triggerHead; world.triggerTail = &world.triggerHead;
world.objectiveTail = &world.objectiveHead; world.objectiveTail = &world.objectiveHead;
world.particleTail = &world.particleHead;
text = readFile(filename); text = readFile(filename);