From 0df09f914a638768b6033f5e8ddef8e5dd207646 Mon Sep 17 00:00:00 2001 From: Steve Date: Thu, 1 Feb 2018 21:51:43 +0000 Subject: [PATCH] Particles processing, Bob, and entity actions. --- src/combat/weapons.c | 19 +- src/defs.h | 5 +- src/entities/blobs/bob.c | 572 ++++++++++++++++++++++++++++++++++- src/entities/blobs/bob.h | 25 ++ src/entities/boss/blobBoss.c | 4 +- src/entities/entity.c | 48 +-- src/entities/entity.h | 2 - src/entities/items/cherry.c | 2 +- src/structs.h | 12 +- src/test/atlasTest.c | 4 + src/test/atlasTest.h | 2 + src/world/entities.c | 55 ++++ src/world/entities.h | 1 + src/world/particles.c | 78 ++--- src/world/player.c | 4 - src/world/worldLoader.c | 1 + 16 files changed, 728 insertions(+), 106 deletions(-) diff --git a/src/combat/weapons.c b/src/combat/weapons.c index 0c687a0..5ac41cd 100644 --- a/src/combat/weapons.c +++ b/src/combat/weapons.c @@ -61,19 +61,20 @@ void initWeapons(void) missileSprite[1] = getSprite("MissileLeft"); } -void firePistol(Unit *owner) +/* only used by Bob */ +void firePistol(void) { Bullet *bullet; - bullet = createBaseBullet(owner); + bullet = createBaseBullet((Unit*)world.bob); bullet->weaponType = WPN_PISTOL; - bullet->facing = owner->facing; + bullet->facing = world.bob->facing; bullet->sprite[0] = bulletSprite[0]; 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) @@ -124,7 +125,7 @@ void firePlasma(Unit *owner) 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) @@ -148,7 +149,7 @@ void fireSpread(Unit *owner, int numberOfShots) 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) @@ -167,7 +168,7 @@ void fireLaser(Unit *owner) 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) @@ -187,7 +188,7 @@ void fireGrenade(Unit *owner) 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) diff --git a/src/defs.h b/src/defs.h index bf16c24..759b403 100644 --- a/src/defs.h +++ b/src/defs.h @@ -209,7 +209,8 @@ enum enum { WS_IN_PROGRESS, - WS_COMPLETE + WS_COMPLETE, + WS_GAME_OVER }; enum @@ -289,7 +290,7 @@ enum enum { CH_ANY = -1, - CH_PLAYER, + CH_BOB, CH_EXPLODE, CH_WEAPON, CH_DEATH, diff --git a/src/entities/blobs/bob.c b/src/entities/blobs/bob.c index 88d16f2..c31aa55 100644 --- a/src/entities/blobs/bob.c +++ b/src/entities/blobs/bob.c @@ -23,8 +23,29 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. static SDL_Rect *getCurrentSprite(void); static void (*superAnimate)(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 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) { @@ -34,18 +55,563 @@ void initBob(void) u->type = ET_BOB; - u->sprite[FACING_LEFT] = getSprite("BobLeft"); - u->sprite[FACING_RIGHT] = getSprite("BobRight"); - u->sprite[FACING_DIE] = getSprite("BobSpin"); + memset(&world.bob->itemHead, 0, sizeof(Item)); + world.bob->itemTail = &world.bob->itemHead; + + 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; + world.bob->tick = tick; u->getCurrentSprite = getCurrentSprite; u->animate = animate; + u->activate = activate; + u->changeEnvironment = changeEnvironment; u->load = load; 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) { diff --git a/src/entities/blobs/bob.h b/src/entities/blobs/bob.h index df44bb7..7df090b 100644 --- a/src/entities/blobs/bob.h +++ b/src/entities/blobs/bob.h @@ -21,9 +21,34 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "../../common.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 Sprite *getSprite(char *name); extern char *getLookupName(const char *prefix, long num); 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; diff --git a/src/entities/boss/blobBoss.c b/src/entities/boss/blobBoss.c index d371b50..c4cce7e 100644 --- a/src/entities/boss/blobBoss.c +++ b/src/entities/boss/blobBoss.c @@ -326,8 +326,8 @@ void reappear(void) do { r = (int) (rand() % MAX_CHECKPOINTS); - self->x = world.checkpoints[r].x; - self->y = world.checkpoints[r].y; + self->x = world.bob->checkpoints[r].x; + self->y = world.bob->checkpoints[r].y; valid = (self->x != 0 && self->y != 0); } while (!valid); diff --git a/src/entities/entity.c b/src/entities/entity.c index 4fe343f..6d48daf 100644 --- a/src/entities/entity.c +++ b/src/entities/entity.c @@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. static void init(void); static void reset(void); +static void action(void); static void applyDamage(int damage); static float bounce(float x); static SDL_Rect *getBounds(void); @@ -54,6 +55,7 @@ void initEntity(Entity *e) e->init = init; e->reset = reset; + e->action = action; e->animate = animate; e->tick = tick; 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); } +static void action(void) +{ +} + static SDL_Rect *getBounds(void) { self->bounds.x = self->x; @@ -141,24 +147,6 @@ static float bounce(float 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) { @@ -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); 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; - } -} diff --git a/src/entities/entity.h b/src/entities/entity.h index 484169b..3377cd3 100644 --- a/src/entities/entity.h +++ b/src/entities/entity.h @@ -20,7 +20,5 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "../common.h" -extern void addTeleportStars(Entity *e); - extern Entity *self; extern World world; diff --git a/src/entities/items/cherry.c b/src/entities/items/cherry.c index 1941dce..09d57fe 100644 --- a/src/entities/items/cherry.c +++ b/src/entities/items/cherry.c @@ -43,6 +43,6 @@ static void touch(Entity *other) pickupItem(); - playSound(SND_CHERRY, CH_PLAYER); + playSound(SND_CHERRY, CH_BOB); } } diff --git a/src/structs.h b/src/structs.h index 57397cc..32919d7 100644 --- a/src/structs.h +++ b/src/structs.h @@ -157,6 +157,7 @@ struct EntityExt { struct Entity; char spriteName[MAX_NAME_LENGTH]; Item *carriedItem; + Entity *riding; }; struct Unit { @@ -205,8 +206,14 @@ struct Item { struct Bob { struct Unit; + int checkpointTimer; + int outTimer; int stunTimer; + int immuneTimer; int power, powerMax; + int jpEffectTimer; + PointF checkpoints[MAX_CHECKPOINTS]; + Item itemHead, *itemTail; }; struct Structure { @@ -322,12 +329,12 @@ typedef struct { int awaitingWidgetInput; int lastKeyPressed; int lastButtonPressed; - int keyControls[CONTROL_MAX]; } App; typedef struct { int sound; int music; + int control[CONTROL_MAX]; } Config; typedef struct { @@ -435,12 +442,13 @@ typedef struct { int allObjectivesComplete; int frameCounter; int currentStatus; + int isTrainingMission; int isBossMission; int isBossActive; int isOutpostMission; int isReturnVisit; int missionCompleteTimer; - PointF checkpoints[MAX_CHECKPOINTS]; + int betweenTimer; Quadtree quadtree; Entity entityHead, *entityTail; Particle particleHead, *particleTail; diff --git a/src/test/atlasTest.c b/src/test/atlasTest.c index ee4ecc6..93096a1 100644 --- a/src/test/atlasTest.c +++ b/src/test/atlasTest.c @@ -49,6 +49,10 @@ void initAtlasTest(void) static void logic(void) { + doEntities(); + + doParticles(); + if (--timeout <= 0) { trackRandomEntity(); diff --git a/src/test/atlasTest.h b/src/test/atlasTest.h index c4a69f5..a06c9c7 100644 --- a/src/test/atlasTest.h +++ b/src/test/atlasTest.h @@ -32,6 +32,8 @@ extern void loadWorld(char *filename); extern void drawMap(void); extern void drawEntities(void); extern void cameraTrack(Entity *e); +extern void doEntities(void); +extern void doParticles(void); extern App app; extern World world; diff --git a/src/world/entities.c b/src/world/entities.c index fee3733..5752077 100644 --- a/src/world/entities.c +++ b/src/world/entities.c @@ -27,6 +27,19 @@ void initEntities(void) 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) { int x, y; @@ -39,3 +52,45 @@ void drawEntities(void) 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); +} diff --git a/src/world/entities.h b/src/world/entities.h index 9187443..9d4a617 100644 --- a/src/world/entities.h +++ b/src/world/entities.h @@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. extern Texture *getTexture(const char *filename); extern void blitRect(SDL_Texture *texture, int x, int y, SDL_Rect *srcRect, int center); +extern void addTeleportStars(Entity *e); extern Entity *self; extern Camera camera; diff --git a/src/world/particles.c b/src/world/particles.c index d990385..5fd94fd 100644 --- a/src/world/particles.c +++ b/src/world/particles.c @@ -44,6 +44,45 @@ void initParticles(void) 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) { Particle *p; @@ -198,45 +237,6 @@ void addTeleporterEffect(float x, float y) 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) { diff --git a/src/world/player.c b/src/world/player.c index 8e84232..7849b3c 100644 --- a/src/world/player.c +++ b/src/world/player.c @@ -19,7 +19,3 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "player.h" - -void stunBob(void) -{ -} diff --git a/src/world/worldLoader.c b/src/world/worldLoader.c index 86af40c..b111e9e 100644 --- a/src/world/worldLoader.c +++ b/src/world/worldLoader.c @@ -37,6 +37,7 @@ void loadWorld(char *filename) world.entityTail = &world.entityHead; world.triggerTail = &world.triggerHead; world.objectiveTail = &world.objectiveHead; + world.particleTail = &world.particleHead; text = readFile(filename);