/* * DESCRIPTION: * AI for the "Crumbler" enemy. */ #include "crumbler.h" static s32 crumbler_health_get(Enemy* _e, List* _l, Play* _p); static s32 crumbler_attack_timer_max_get(Enemy* _e, List* _l, Play* _p); /* Gets the Crumbler health. */ static s32 crumbler_health_get(Enemy* _e, List* _l, Play* _p) { s32 health; health = CRUMBLER_HEALTH_BASE + ((_p->game - 1) * CRUMBLER_HEALTH_GAME_MULTIPLIER); health = CEIL(health, CRUMBLER_HEALTH_MAX); return health; } /* Gets the Crumbler attack timer max. */ static s32 crumbler_attack_timer_max_get(Enemy* _e, List* _l, Play* _p) { s32 attackTimerMax; attackTimerMax = CRUMBLER_ATTACK_TIMER_MAX_BASE - ((_p->game - 1) * CRUMBLER_ATTACK_TIMER_MAX_GAME_MULTIPLIER); attackTimerMax = FLOOR(attackTimerMax, CRUMBLER_ATTACK_TIMER_MAX_MIN); return attackTimerMax; } /* Initializes the Crumbler. */ void crumbler_init(Enemy* _e, List* _l, Play* _p) { Atlas atlas; atlas_init ( &atlas, _p->g->textures[TEXTURE_ENEMY_CRUMBLER], CRUMBLER_ROWS, CRUMBLER_COLUMNS, CRUMBLER_WIDTH, CRUMBLER_HEIGHT ); sprite_atlas_init ( &_e->sprite, &atlas, ORIGIN_MIDDLE, CRUMBLER_WIDTH, CRUMBLER_HEIGHT ); _e->shadow.r = 0; _e->sprite.frame = 1; } /* Sets the Crumbler. */ void crumbler_set(Enemy* _e, List* _l, f64 _x, f64 _y, Play* _p) { _e->shadow.x = _x + CRUMBLER_SHADOW_OFFSET_X; _e->shadow.y = _y + CRUMBLER_SHADOW_OFFSET_Y; _e->sprite.x = _e->shadow.x; _e->sprite.y = _e->shadow.y - (CRUMBLER_ATTACK_OFFSET_Y + CRUMBLER_SHADOW_OFFSET_Y); _e->isActive = FALSE; _e->isActing = TRUE; _e->attackTimer = crumbler_attack_timer_max_get(_e, _l, _p); _e->health = crumbler_health_get(_e, _l, _p); } /* * Updates Crumbler. * Falls into the arena and then remains stationary. */ void crumbler_update(Enemy* _e, List* _l, Play* _p) { if (_e->isActing) { f64 progress; _e->attackTimer--; progress = 1 - ((f64)_e->attackTimer / crumbler_attack_timer_max_get(_e, _l, _p)); _e->shadow.r = CRUMBLER_SHADOW_RADIUS * progress; _e->sprite.y = _e->shadow.y - CRUMBLER_SHADOW_OFFSET_Y - (CRUMBLER_ATTACK_OFFSET_Y * (1 - progress)); if (_e->attackTimer <= 0) { _e->isActing = FALSE; _e->isActive = TRUE; _e->shadow.r = CRUMBLER_SHADOW_RADIUS; _e->sprite.frame = 0; sound_play(_p->g->sounds[SOUND_RUMBLE], -1); } } else { f64 progress; _e->animationTimer--; progress = 1 - ((f64)_e->animationTimer / CRUMBLER_ANIMATION_TIMER_MAX); _e->sprite.squash = (SPRITE_SQUASH_DEFAULT + cos((ROTATION_MAX_RAD * progress)) * CRUMBLER_SQUASH_MULTIPLIER); _e->sprite.stretch = (SPRITE_STRETCH_DEFAULT + cos((ROTATION_MAX_RAD * progress)) * CRUMBLER_STRETCH_MULTIPLIER); if (_e->animationTimer <= 0) _e->animationTimer = CRUMBLER_ANIMATION_TIMER_MAX; } }