Spieler splodiert.
[hackover2013-badge-firmware.git] / badge / jumpnrun / enemies.c
index 61859a8..fab1526 100644 (file)
@@ -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);
@@ -180,7 +198,7 @@ void enemy_collision_tiles_bounce_horiz(jumpnrun_enemy            *self,
                                           &inertia_mod);
 
   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 +210,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 +220,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 +240,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 +249,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 +503,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,
This page took 0.023557 seconds and 4 git commands to generate.