#include #include #include "vga.h" #include "sound.h" #include "entities.h" #include "map.h" #include "game.h" #include "player.h" #include "effect.h" #include "pickup.h" #define MAX_FRAME 3 #define MAX_BONUS_FRAME 4 #define MAX_TTL ((uint16_t)800) typedef enum { PICKUP_TIME = 0, PICKUP_BONUS, PICKUP_PICKAXE, PICKUP_GOLDKEY, PICKUP_SILVERKEY, } PickupType; static const Rect frames_in[2 * 4] = { { 96, 16, 144, 144 }, { 128, 16, 144, 144 }, { 112, 16, 144, 144 }, /* not used */ { 0, 0, 144, 144 }, { 0, 0, 144, 144 }, { 0, 0, 144, 144 }, { 0, 0, 144, 144 }, { 0, 0, 144, 144 } }; static const Rect frames[2 * 4] = { /* time */ { 80, 16, 144, 144 }, /* pickaxe */ { 64, 16, 144, 144 }, /* gold key */ { 32, 16, 144, 144 }, /* siver key */ { 48, 16, 144, 144 }, /* not used */ { 0, 0, 144, 144 }, { 0, 0, 144, 144 }, { 0, 0, 144, 144 }, { 0, 0, 144, 144 } }; static const Rect frames_bonus0[2 * 4] = { { 0, 48, 144, 144 }, { 16, 48, 144, 144 }, { 32, 48, 144, 144 }, { 48, 48, 144, 144 }, /* not used */ { 0, 0, 144, 144 }, { 0, 0, 144, 144 }, { 0, 0, 144, 144 }, { 0, 0, 144, 144 } }; static const Rect frames_bonus1[2 * 4] = { { 0, 64, 144, 144 }, { 16, 64, 144, 144 }, { 32, 64, 144, 144 }, { 48, 64, 144, 144 }, /* not used */ { 0, 0, 144, 144 }, { 0, 0, 144, 144 }, { 0, 0, 144, 144 }, { 0, 0, 144, 144 } }; static const Rect frames_bonus2[2 * 4] = { { 64, 64, 144, 144 }, { 80, 64, 144, 144 }, { 96, 64, 144, 144 }, { 112, 64, 144, 144 }, /* not used */ { 0, 0, 144, 144 }, { 0, 0, 144, 144 }, { 0, 0, 144, 144 }, { 0, 0, 144, 144 } }; static const Rect *frames_bonuses[] = { frames_bonus0, frames_bonus1, frames_bonus2 }; void pickup_time_init(Entity *e) { e->used = USED_BG; e->frames = (const Rect *)frames_in; e->flags = PICKUP_TIME; e->counter = MAX_TTL * 2 + (rand() % MAX_TTL); e->update = pickup_wait_update; } void pickup_bonus_init(Entity *e) { e->used = USED_BG; e->frames = (const Rect *)frames_in; e->flags = PICKUP_BONUS; e->counter = MAX_TTL + (rand() % MAX_TTL); e->update = pickup_wait_update; } void pickup_pickaxe_init(Entity *e) { e->used = USED_BG; e->frames = (const Rect *)frames_in; e->flags = PICKUP_PICKAXE; e->counter = MAX_TTL / 2 + (rand() % MAX_TTL); e->update = pickup_wait_update; } void pickup_goldkey_init(Entity *e) { e->used = USED_BG; e->frames = (const Rect *)frames_in; e->flags = PICKUP_GOLDKEY; e->counter = 2 + (rand() % MAX_TTL); e->update = pickup_wait_update; } void pickup_silverkey_init(Entity *e) { e->used = USED_BG; e->frames = (const Rect *)frames_in; e->flags = PICKUP_SILVERKEY; e->counter = 2 + (rand() % MAX_TTL); e->update = pickup_wait_update; } void pickup_wait_update(Entity *e) { if (e->counter-- == 0) { e->update = pickup_in_update; sound_play_efx(EFX_WARP); } } void pickup_in_update(Entity *e) { if (e->delay++ == WALK_DELAY - 2) { e->delay = 0; e->frame++; if (e->frame == MAX_FRAME) { switch (e->flags) { case PICKUP_TIME: e->frames = (const Rect *)frames; e->frame = 0; break; case PICKUP_BONUS: e->frames = (const Rect *)frames_bonuses[rand() % 3]; e->frame = 0; break; case PICKUP_PICKAXE: e->frames = (const Rect *)frames; e->frame = 1; break; case PICKUP_GOLDKEY: e->frames = (const Rect *)frames; e->frame = 2; break; case PICKUP_SILVERKEY: e->frames = (const Rect *)frames; e->frame = 3; break; } e->counter = 0; e->update = pickup_update; } } } void pickup_update(Entity *e) { /* the keys NEVER disappear */ if (e->flags != PICKUP_GOLDKEY && e->flags != PICKUP_SILVERKEY && e->counter++ == MAX_TTL) { effect_out_init(e); sound_play_efx(EFX_WARP); return; } /* the bonuses have an animation */ if (e->flags == PICKUP_BONUS) { e->delay++; /* first frame lasts longer */ if ((e->frame == 0 && e->delay == WALK_DELAY * 4) || (e->frame != 0 && e->delay == WALK_DELAY - 2)) { e->delay = 0; e->frame++; if (e->frame == MAX_BONUS_FRAME) e->frame = 0; } } if (player_collision_pickup(e)) { switch (e->flags) { case PICKUP_TIME: reset_time(); sound_play_efx(EFX_PICKUP); break; case PICKUP_BONUS: add_score(250); sound_play_efx(EFX_PICKUP); break; case PICKUP_PICKAXE: add_pickaxe(); sound_play_efx(EFX_PICKUP); break; case PICKUP_GOLDKEY: map_open_goldkey(); sound_play_efx(EFX_WARP); break; case PICKUP_SILVERKEY: map_open_silverkey(); sound_play_efx(EFX_WARP); break; } e->used = USED_FREE; } }