Esempio n. 1
0
void
guard_die_properly (struct anim *g)
{
  switch (con (&g->p)->fg) {
  case SPIKES_FLOOR: guard_die_spiked (g); break;
  case CHOPPER: guard_die_chopped (g); break;
  default: guard_die_suddenly (g); break;
  }
}
Esempio n. 2
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;
}