X-Git-Url: https://git.rohieb.name/hackover2013-badge-firmware.git/blobdiff_plain/01d395b92b5ba972a6e1c3d8f2bf4803f155a3cb..05db94c84b6f7e4ee91fd67d6e1a8d97a2b97f2e:/badge/jumpnrun/enemies.c?ds=sidebyside diff --git a/badge/jumpnrun/enemies.c b/badge/jumpnrun/enemies.c index 61859a8..0ca8ad0 100644 --- a/badge/jumpnrun/enemies.c +++ b/badge/jumpnrun/enemies.c @@ -99,9 +99,14 @@ static void enemy_spawn(jumpnrun_enemy *self) { self->base.jumpable_frames = 0; } +static void jumpnrun_enemy_kill(jumpnrun_enemy *self) { + self->base.flags |= JUMPNRUN_MOVEABLE_DYING; + self->base.tick_minor = 0; +} + void jumpnrun_enemy_despawn(jumpnrun_enemy *self) { // Despawned enemies are reset to their spawn position, so enemy_in_spawn_area will determine whether the spawn point is in the spawn area. - self->base.flags &= ~JUMPNRUN_ENEMY_SPAWNED; + self->base.flags &= ~(JUMPNRUN_ENEMY_SPAWNED | JUMPNRUN_ENEMY_MOVING | JUMPNRUN_MOVEABLE_DYING); self->base.hitbox = rectangle_new(self->spawn_pos, self->type->hitbox.extent); self->base.inertia = self->type->spawn_inertia; } @@ -130,7 +135,7 @@ static inline bool enemy_in_area(jumpnrun_enemy const *self, jumpnrun_game_state } static inline bool enemy_on_screen(jumpnrun_enemy const *self, jumpnrun_game_state *state) { - return enemy_in_area(self, state, 0); + return enemy_in_area(self, state, self->type->animation_frames[self->base.anim_frame].width); } static inline bool enemy_in_spawn_area(jumpnrun_enemy const *self, jumpnrun_game_state *state) { @@ -147,11 +152,24 @@ void jumpnrun_process_enemy(jumpnrun_enemy *self, if(self->base.flags & JUMPNRUN_ENEMY_SPAWNED) { if(!enemy_in_spawn_area(self, state) || fixed_point_gt(rectangle_top (enemy_hitbox(self)), FIXED_INT(BADGE_DISPLAY_HEIGHT))) { jumpnrun_enemy_despawn(self); + } else if(jumpnrun_moveable_dying(&self->base)) { + if(jumpnrun_moveable_finished_dying(&self->base)) { + jumpnrun_enemy_despawn(self); + } else { + if(fb) { + jumpnrun_render_splosion(fb, state, &self->base); + } + ++self->base.tick_minor; + } } else { - self->type->move_tick(self, state, lv, visible_tiles, player_inertia_mod); - self->type->collision_shots(self, state); - if (fixed_point_lt(self->base.inertia.x, FIXED_INT(0))) { self->base.flags &= ~JUMPNRUN_MOVEABLE_MIRRORED; } - else if(fixed_point_ne(self->base.inertia.x, FIXED_INT(0))) { self->base.flags |= JUMPNRUN_MOVEABLE_MIRRORED; } + if((self->base.flags & JUMPNRUN_ENEMY_MOVING) || enemy_on_screen(self, state)) { + self->base.flags |= JUMPNRUN_ENEMY_MOVING; + + self->type->move_tick(self, state, lv, visible_tiles, player_inertia_mod); + self->type->collision_shots(self, state); + if (fixed_point_lt(self->base.inertia.x, FIXED_INT(0))) { self->base.flags &= ~JUMPNRUN_MOVEABLE_MIRRORED; } + else if(fixed_point_ne(self->base.inertia.x, FIXED_INT(0))) { self->base.flags |= JUMPNRUN_MOVEABLE_MIRRORED; } + } if(fb) { jumpnrun_render_enemy(fb, state, self); @@ -178,9 +196,10 @@ void enemy_collision_tiles_bounce_horiz(jumpnrun_enemy *self, lv, visible_tiles, &inertia_mod); + self->base.inertia.y = inertia_mod.y; if(killed) { - jumpnrun_enemy_despawn(self); + jumpnrun_enemy_kill(self); } else if(fixed_point_ne(inertia_mod.x, self->base.inertia.x)) { enemy_bounce(self); } @@ -192,7 +211,7 @@ void enemy_collision_player_deadly(struct jumpnrun_enemy *self, (void) player_inertia_mod; if(rectangle_intersect(enemy_hitbox(self), &state->player.base.hitbox)) { - state->player.base.flags |= JUMPNRUN_PLAYER_DEAD; + jumpnrun_player_kill(&state->player); } } @@ -202,13 +221,14 @@ void enemy_collision_player_jumpable(jumpnrun_enemy *self, { if(rectangle_intersect(enemy_hitbox(self), &state->player.base.hitbox)) { if(fixed_point_lt(rectangle_top(&state->player.base.hitbox), rectangle_top(enemy_hitbox(self))) && - fixed_point_gt(state->player.base.inertia.y, FIXED_INT(0))) + fixed_point_gt(state->player.base.inertia.y, FIXED_INT(0)) && + jumpnrun_player_alive(&state->player)) { - jumpnrun_enemy_despawn(self); + jumpnrun_enemy_kill(self); player_inertia_mod->y = FIXED_POINT(0, -250); state->player.base.jumpable_frames = 12; } else { - state->player.base.flags |= JUMPNRUN_PLAYER_DEAD; + jumpnrun_player_kill(&state->player); } } } @@ -221,7 +241,6 @@ void enemy_collision_tiles_pass_through(struct jumpnrun_enemy *self, (void) desired_position; (void) lv; (void) visible_tiles; - return; } void enemy_collision_shots_die(struct jumpnrun_enemy *self, @@ -231,7 +250,7 @@ void enemy_collision_shots_die(struct jumpnrun_enemy *self, if(jumpnrun_shot_spawned(shot)) { if(rectangle_intersect(enemy_hitbox(self), &shot->current_box)) { - self->base.flags &= ~JUMPNRUN_ENEMY_SPAWNED; + jumpnrun_enemy_kill(self); jumpnrun_shot_despawn(shot); } } @@ -485,7 +504,7 @@ jumpnrun_enemy_type const jumpnrun_enemy_type_data[JUMPNRUN_ENEMY_TYPE_COUNT] = .animation_length = ARRAY_SIZE(anim_mushroom), .animation_frames = anim_mushroom, .hitbox = { { FIXED_INT_I(1), FIXED_INT_I(1) }, - { FIXED_INT_I(5), FIXED_INT_I(4) } }, + { FIXED_INT_I(5), FIXED_INT_I(6) } }, .spawn_inertia = { FIXED_POINT_I(0, -80), FIXED_INT_I(0) }, .collision_tiles = enemy_collision_tiles_bounce_horiz, .collision_player = enemy_collision_player_jumpable,