Beispiel #1
0
void
register_spikes_floor (struct pos *p)
{
  assert (con (p)->fg == SPIKES_FLOOR
          && spikes_floor_at_pos (p) == NULL);

  struct spikes_floor s;

  s.p = *p;
  s.wait = SPIKES_WAIT;
  s.murdered_anim = -1;
  s.activate = false;

  switch (con (p)->ext.step) {
  case 0: s.i = 0; s.state = 0; break;
  case 1: s.i = 1; s.state = 1; break;
  case 2: s.i = 2; s.state = 2; break;
  case 3: s.i = 3; s.state = 3; break;
  case 4: s.i = 4; s.state = 4; break;
  case 5: s.i = 4; s.state = 5; break;
  case 6: s.i = 5; s.state = 3; break;
  case 7: s.i = 6; s.state = 2; break;
  case 8: s.i = 0; s.state = 1; break;
  case 9: s.i = 0; s.state = 0; break;
  }

  s.inactive = (con (p)->ext.step != 0);

  spikes_floor =
    add_to_array (&s, 1, spikes_floor, &spikes_floor_nmemb,
                  spikes_floor_nmemb, sizeof (s));

  sort_spikes_floors ();
}
Beispiel #2
0
void
break_spikes_floor (struct pos *p)
{
  struct spikes_floor *s = spikes_floor_at_pos (p);
  if (! s) return;
  if (s->murdered_anim != -1)
    anim_die_suddenly (get_anim_by_id (s->murdered_anim));
  remove_spikes_floor (s);
}
Beispiel #3
0
void
draw_spikes_floor_right (ALLEGRO_BITMAP *bitmap, struct pos *p,
                         enum em em, enum vm vm)
{
  struct spikes_floor *s = spikes_floor_at_pos (p);
  if (! s) return;

  draw_spikes_floor_floor_right (bitmap, p, em, vm);
  draw_spikes_right (bitmap, p, s, em, vm);
}
Beispiel #4
0
void
guard_die_spiked (struct anim *g)
{
  if (con (&g->p)->fg != SPIKES_FLOOR) {
    guard_die_properly (g);
    return;
  }

  g->oaction = g->action;
  g->action = guard_die_spiked;
  g->f.flip = (g->f.dir == RIGHT) ? ALLEGRO_FLIP_HORIZONTAL : 0;

  if (g->oaction != guard_die_spiked) {
    g->splash = true;
    g->death_reason = SPIKES_DEATH;

    assert (con (&g->p)->fg == SPIKES_FLOOR);
    struct spikes_floor *s = spikes_floor_at_pos (&g->p);
    s->i = 4;
    s->state = 5;
    s->inactive = true;
    s->murdered_anim = g->id;

    if (g->type == SKELETON)
      play_sample (skeleton_sample, NULL, g->id);
    else play_sample (spiked_sample, NULL, g->id);

    struct anim *ke = get_anim_by_id (g->enemy_id);
    if (! ke) ke = get_anim_by_id (g->oenemy_id);
    if (ke && ke->id == current_kid_id
        && ! g->glory_sample
        && g->death_reason != SHADOW_FIGHT_DEATH) {
      play_sample (glory_sample, NULL, ke->id);
      g->glory_sample = true;
    }
    g->oenemy_id = -1;

    if (ke) upgrade_skill (&ke->skill, &g->skill);
  }

  g->current_lives = 0;

  int dy;
  if (g->type == SKELETON) dy = +45;
  else dy = (g->f.dir == LEFT) ? +32 : +31;

  ALLEGRO_BITMAP *bitmap = get_guard_die_spiked_bitmap (g->type);
  place_frame (&g->f, &g->f, bitmap,
               &g->p, (g->f.dir == LEFT) ? +8 : +9, dy);

  g->xf.b = NULL;
}
Beispiel #5
0
void
guard_die_spiked (struct anim *g)
{
  if (fg (&g->p) != SPIKES_FLOOR) {
    guard_die_properly (g);
    return;
  }

  g->oaction = g->action;
  g->action = guard_die_spiked;
  g->f.flip = (g->f.dir == RIGHT) ? ALLEGRO_FLIP_HORIZONTAL : 0;

  assert (fg (&g->p) == SPIKES_FLOOR);
  struct spikes_floor *s = spikes_floor_at_pos (&g->p);

  if (s->i != 4 || s->state != 5 || ! s->inactive) {
    s->i = 4;
    s->state = 5;
    s->inactive = true;
    register_changed_pos (&g->p);
  }

  if (g->oaction != guard_die_spiked) {
    g->splash = true;
    g->death_reason = SPIKES_DEATH;

    if (g->type == SKELETON)
      play_audio (&skeleton_audio, NULL, g->id);
    else play_audio (&spiked_audio, NULL, g->id);

    if (! g->glory_sample) {
      play_audio (&glory_audio, NULL, g->id);
      g->glory_sample = true;
    }
  }

  g->current_lives = 0;

  int dy;
  if (g->type == SKELETON) dy = +45;
  else dy = (g->f.dir == LEFT) ? +32 : +31;

  ALLEGRO_BITMAP *bitmap = get_guard_die_spiked_bitmap (g->type);
  place_frame (&g->f, &g->f, bitmap,
               &g->p, (g->f.dir == LEFT) ? +8 : +9, dy);

  g->xf.b = NULL;
}
Beispiel #6
0
void
draw_spikes_fg (ALLEGRO_BITMAP *bitmap, struct pos *p,
                enum em em, enum vm vm)
{
  struct spikes_floor *s = spikes_floor_at_pos (p);
  if (! s) return;

  switch (s->state) {
  case 0: break;
  case 1: draw_spikes_fg_00 (bitmap, p, em, vm); break;
  case 2: draw_spikes_fg_01 (bitmap, p, em, vm); break;
  case 3: draw_spikes_fg_02 (bitmap, p, em, vm); break;
  case 4: draw_spikes_fg_03 (bitmap, p, em, vm); break;
  case 5: draw_spikes_fg_04 (bitmap, p, em, vm); break;
  }
}
Beispiel #7
0
void
guard_resurrect (struct anim *g)
{
  g->splash = false;
  g->invisible = false;
  if (g->current_lives > 0) return;
  struct pos pm;
  survey (_m, pos, &g->f, NULL, &pm, NULL);
  g->current_lives = g->total_lives;
  g->death_reason = NO_DEATH;
  g->action = guard_normal;
  g->glory_sample = false;
  place_frame (&g->f, &g->f, get_guard_normal_bitmap (g->type),
               &pm, g->f.dir == LEFT ? +16 : +22, +14);
  place_on_the_ground (&g->f, &g->f.c);
  if (fg (&g->p) == SPIKES_FLOOR)
    spikes_floor_at_pos (&g->p)->inactive = false;
}
Beispiel #8
0
static bool
physics_in (struct anim *g)
{
  struct coord nc;
  struct pos np, pbf, pmt, pmtf, pmtb,
    npmbo, npmbo_nf;
  struct frame nf;
  struct frame_offset fo;

  if (g->i == 0) {
    next_frame (&g->f, &g->f, &g->fo);

    int dirf = (g->f.dir == LEFT) ? -1 : +1;
    int dirb = (g->f.dir == LEFT) ? +1 : -1;
    survey (_mt, pos, &g->f, &nc, &pmt, &np);
    prel (&pmt, &pmtf, +0, dirf);
    prel (&pmt, &pmtb, +0, dirb);

    if (! is_strictly_traversable (&pmt)
        || ! is_strictly_traversable (&pmtf)
        || ! is_strictly_traversable (&pmtb))
      place_in_initial_fall (g);
  }

  /* fall speed */
  if (g->i > 0)
    g->fo.dx = -g->inertia;
  if (g->i > 4) {
    int speed = +21 + 3 * (g->i - 5);
    g->fo.dy = (speed > 33) ? 33 : speed;
  }

  /* land on ground */
  struct frameset *frameset = get_guard_fall_frameset (g->type);
  fo.b = frameset[g->i > 2 ? 2 : g->i].frame;
  fo.dx = frameset[g->i > 2 ? 2 : g->i].dx;
  fo.dy = frameset[g->i > 2 ? 2 : g->i].dy;

  if (g->i > 0) g->fo.dx = -g->inertia;
  if (g->i > 2) {
    int speed = +21 + 3 * (g->i - 5);
    fo.dy = (speed > 33) ? 33 : speed;
  }
  fo.dy += 8;

  survey (_mbo, pos, &g->f, &nc, &np, &npmbo);
  next_frame (&g->f, &nf, &fo);
  survey (_mbo, pos, &nf, &nc, &np, &npmbo_nf);

  if (g->i > 2
      && ! is_strictly_traversable (&npmbo)
      && npmbo.floor != npmbo_nf.floor) {
    g->inertia = g->cinertia = 0;

    if (is_colliding (&g->f, &g->fo, +16, false, &g->ci)) {
      if (g->ci.t != WALL)
        g->f.c.x += (g->f.dir == LEFT) ? +16 : -16;
      else
        g->f.c.x += (g->f.dir == LEFT) ? +8 : -8;
    }

    survey (_bf, pos, &g->f, &nc, &pbf, &np);
    /* pos2view (&pbf, &pbf); */
    frameset = get_guard_vigilant_frameset (g->type);
    g->f.b = frameset[0].frame;
    place_on_the_ground (&g->f, &g->f.c);

    shake_loose_floor_row (&pbf);

    if (g->i >= 8 && ! g->immortal
        && ! g->fall_immune) {
      g->hurt = true;
      g->splash = true;
      g->current_lives--;

      if (g->i >= 10) g->current_lives = 0;

      if (g->current_lives > 0) g->uncouch_slowly = true;
    } else if (g->i > 3) {
      play_sample (hit_ground_sample, g->f.c.room);
      g->hurt = false;
    } else g->hurt = false;

    stop_sample (g->sample, scream_sample);

    survey (_mt, pos, &g->f, &nc, &pmt, &np);
    g->p = pmt;

    if (con (&pmt)->fg == SPIKES_FLOOR
        && ! spikes_floor_at_pos (&pmt)->inactive)
      guard_die_spiked (g);
    else if (g->current_lives <= 0) {
      play_sample (hit_ground_fatal_sample, g->f.c.room);
      guard_die_suddenly (g);
      g->death_reason = FALL_DEATH;
    } else {
      place_on_the_ground (&g->f, &g->f.c);
      g->f.c.y++;
      guard_vigilant (g);
    }

    return false;
  }

  return true;
}