Beispiel #1
0
void
register_changed_room (int room)
{
  if (has_room_changed (room)) return;

  changed_room =
    add_to_array (&room, 1, changed_room, &changed_room_nmemb,
                  changed_room_nmemb, sizeof (room));

  qsort (changed_room, changed_room_nmemb, sizeof (room), (m_comparison_fn_t) cint);

  struct pos p;
  new_pos (&p, &global_level, room, -1, -1);

  p.floor = 0;
  for (p.place = 0; p.place < PLACES; p.place++)
    register_changed_pos (&p, -1);

  p.place = 0;
  for (p.floor = 1; p.floor < FLOORS; p.floor++)
    register_changed_pos (&p, -1);

  p.place = 9;
  for (p.floor = 1; p.floor < FLOORS; p.floor++)
    register_changed_pos (&p, -1);
}
Beispiel #2
0
void
register_changed_opener_floors (void)
{
    size_t i;
    for (i = 0; i < opener_floor_nmemb; i++) {
        struct opener_floor *o = &opener_floor[i];
        if (o->prev_pressed != o->pressed)
            register_changed_pos (&o->p);
    }
}
Beispiel #3
0
void
register_changed_closer_floors (void)
{
  size_t i;
  for (i = 0; i < closer_floor_nmemb; i++)
    if (closer_floor[i].prev_pressed !=
        closer_floor[i].pressed)
      register_changed_pos (&closer_floor[i].p,
                            CHPOS_UNPRESS_CLOSER_FLOOR);
}
Beispiel #4
0
void
press_closer_floor (struct pos *p)
{
  struct closer_floor *c = closer_floor_at_pos (p);
  if (! c) return;
  if (c->broken) return;
  c->pressed = true;

  if (! c->prev_pressed) {
    register_changed_pos (p, CHPOS_PRESS_CLOSER_FLOOR);
    c->prev_pressed = true;
  }
}
Beispiel #5
0
void
press_opener_floor (struct pos *p)
{
    struct opener_floor *o = opener_floor_at_pos (p);
    if (! o) return;
    if (o->broken) return;
    o->pressed = true;

    if (! o->prev_pressed) {
        register_changed_pos (&o->p);
        o->prev_pressed = true;
        o->priority = anim_cycle;
    }
}
Beispiel #6
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 #7
0
void
compute_doors (void)
{
  size_t i;

  for (i = 0; i < door_nmemb; i++) {
    struct door *d = &door[i];
    switch (d->action) {
    case OPEN_DOOR:
      if (d->i == 0 && d->wait == 0) d->action = CLOSE_DOOR;
      else if (d->i == 0 && d->wait > 0) {
        if (! d->noise) {
          play_sample (door_end_sample, &d->p, -1);
          d->noise = true;
        }

        d->wait--;
      }
      else if (d->i > 0) {
        if (d->i % 2 == 0) {
          if (d->i == DOOR_MAX_STEP - 1) alert_guards (&d->p);
          play_sample (door_open_sample, &d->p, -1);
        }
        d->i--;
        d->wait = DOOR_WAIT;
        register_changed_pos (&d->p, CHPOS_OPEN_DOOR);
      }
      break;
    case CLOSE_DOOR:
      if (d->i < DOOR_MAX_STEP) {
        if (d->wait++ % 4 == 0) {
          if (d->i == 0) alert_guards (&d->p);
          play_sample (door_close_sample, &d->p, -1);
          d->i++;
          d->noise = false;
          register_changed_pos (&d->p, CHPOS_CLOSE_DOOR);
        }
      } else if (d->i == DOOR_MAX_STEP) {
        play_sample (door_end_sample, &d->p, -1);
        d->action = NO_DOOR_ACTION;
        d->wait = DOOR_WAIT;
        d->noise = false;
      }
      break;
    case ABRUPTLY_CLOSE_DOOR:
      if (d->i < DOOR_MAX_STEP) {
        int r = 11 - (d->i % 12);
        d->i += r ? r : 12;
        register_changed_pos (&d->p, CHPOS_ABRUPTLY_CLOSE_DOOR);
        if (d->i >= DOOR_MAX_STEP) {
          d->i = DOOR_MAX_STEP;
          alert_guards (&d->p);
          play_sample (door_abruptly_close_sample, &d->p, -1);
        }
      } else {
        d->action = NO_DOOR_ACTION;
        d->wait = DOOR_WAIT;
        d->noise = false;
      }
      break;
    default:
      break;
    }
  }
}
Beispiel #8
0
void
compute_spikes_floors (void)
{
  size_t i, j;
  struct pos pm;

  for (i = 0; i < spikes_floor_nmemb; i++) {
    struct spikes_floor *s = &spikes_floor[i];

    if (s->inactive) continue;

    int state = s->state;

    switch (s->i) {
    case 0: if (should_spikes_raise (&s->p) || s->activate) {
        alert_guards (&s->p);
        play_sample (spikes_sample, &s->p, -1);
        s->i++;
        s->wait = 12;
        s->state = 1;
      } else if (s->state != 0) s->state = 0;
      break;
    case 1:
      s->i++;
      s->state = 2;
      break;
    case 2:
      s->i++;
      s->state = 3;
      break;
    case 3:
      s->i++;
      s->state = 4;
      break;
    case 4: if (! should_spikes_raise (&s->p)) {
        if (s->wait-- == 0) {
          s->i++;
          s->state = 3;
        } else s->state = 5;
      } else {
        s->state = 5;
      }
      break;
    case 5:
      s->i++;
      s->state = 2;
      break;
    case 6:
      s->i = 0;
      s->state = 1;
      s->activate = false;
      break;
    }

    if (state != s->state)
      register_changed_pos (&s->p, CHPOS_SPIKES);

    /* spike kid */
    for (j = 0; j < anima_nmemb; j++) {
      struct anim *a = &anima[j];
      if (is_kid_dead (&a->f)
          || a->immortal
          || a->spikes_immune) continue;
      survey (_m, pos, &a->f, NULL, &pm, NULL);
      if (peq (&pm, &s->p)
          && (((s->state >= 2 && s->state <= 4)
               && (is_kid_start_run (&a->f)
                   || is_kid_run (&a->f)
                   || is_kid_run_jump_running (&a->f)))
              || (is_kid_couch (&a->f) && a->fall && a->i < 3
                  && ! a->float_timer)
              || (is_kid_jump_landing (&a->f) && a->i <= 13)
              || is_kid_run_jump_landing (&a->f))) {
        a->p = s->p;
        anim_die_spiked (a);
      }
    }
  }
}
Beispiel #9
0
void
compute_choppers (void)
{
  size_t i, j;

  for (i = 0; i < chopper_nmemb; i++) {
    struct chopper *c = &chopper[i];

    if (c->inactive) continue;

    switch (c->i) {
    case 0:
      if (! c->alert) c->alert = ! should_chomp (&c->p);
      if ((c->wait-- <= 0 && should_chomp (&c->p)
           && (anim_cycle % CHOPPER_WAIT) ==
           prandom_pos (&c->p, CHOPPER_WAIT - 1))
          || c->activate) {
        c->i++;
        register_changed_pos (&c->p, CHPOS_CHOPPER);
      }
      break;
    case 1: c->i++;
      if (c->alert) {
        alert_guards (&c->p);
        c->alert = false;
      }
      play_sample (chopper_sample, &c->p, -1);
      register_changed_pos (&c->p, CHPOS_CHOPPER);
      break;
    case 2:
      c->i++;
      register_changed_pos (&c->p, CHPOS_CHOPPER);
      break;
    case 3:
      c->i++;
      register_changed_pos (&c->p, CHPOS_CHOPPER);
      break;
    case 4: c->i = 0; c->wait = CHOPPER_WAIT; c->activate = false;
      register_changed_pos (&c->p, CHPOS_CHOPPER);
      break;
    }

    if (c->i != 1 && c->i != 2 ) continue;

    /* chomp kid */
    for (j = 0; j < anima_nmemb; j++) {
      struct anim *a = &anima[j];
      if (a->type == MOUSE
          || is_anim_fall (&a->f)
          || a->immortal
          || a->chopper_immune
          || (a->action == kid_walk && a->walk != -1))
        continue;
      struct pos pbf, pbb;
      survey (_bf, pos, &a->f, NULL, &pbf, NULL);
      survey (_bb, pos, &a->f, NULL, &pbb, NULL);
      pos2room (&pbf, c->p.room, &pbf);
      pos2room (&pbb, c->p.room, &pbb);
      if ((((pbf.room == c->p.room
             && pbf.floor == c->p.floor)
            || (pbb.room == c->p.room
                && pbb.floor == c->p.floor))
           && ((a->f.dir == LEFT && pbf.place < c->p.place
                && pbb.place >= c->p.place)
               || (a->f.dir == RIGHT && pbf.place >= c->p.place
                   && pbb.place < c->p.place)))
          && (! is_anim_dead (&a->f) || ! is_anim_chopped (&a->f))) {
        if (a->type != SKELETON) c->blood = true;
        a->splash = true;
        a->p = c->p;
        a->death_reason = CHOPPER_DEATH;
        if (a->id == current_kid_id) {
          mr.flicker = 2;
          mr.color = get_flicker_blood_color ();
        }
        if (a->type == SKELETON)
          play_sample (skeleton_sample, &c->p, -1);
        else play_sample (chopped_sample, &c->p, -1);
        anim_die_chopped (a);
      }
    }
  }
}
Beispiel #10
0
void
draw_multi_rooms (void)
{
  int x, y;

  mr_set_origin (mr.room, mr.x, mr.y);

  bool mr_full_update = has_mr_view_changed ()
    || mr.full_update;

  if (mr_full_update) {
    mr_busy ();
    force_full_redraw = true;
  }

  if (anim_cycle == 0) {
    generate_wall_colors_for_room (0, room0_wall_color);
  }

  if (em == PALACE && vm == VGA
      && (mr_full_update
          || em != mr.last.em
          || vm != mr.last.vm))
    generate_wall_colors ();

  if (mouse_pos.room != mr.last.mouse_pos.room
      || mouse_pos.floor != mr.last.mouse_pos.floor
      || mouse_pos.place != mr.last.mouse_pos.place) {
    if (is_valid_pos (&mouse_pos))
      register_changed_pos (&mouse_pos);

    if (is_valid_pos (&mr.last.mouse_pos))
      register_changed_pos (&mr.last.mouse_pos);
  }

  if (anim_cycle == 0
      || em != mr.last.em
      || vm != mr.last.vm
      || hgc != mr.last.hgc
      || hue != mr.last.hue) {
    update_room0_cache (em, vm);
    force_full_redraw = true;
  }

  size_t i;

  if (anim_cycle == 0
      || mr_full_update
      || em != mr.last.em
      || vm != mr.last.vm
      || hgc != mr.last.hgc
      || hue != mr.last.hue
      || global_level.n != mr.last.level) {
    update_cache (em, vm);
  } else {
    bool depedv =
      ((em == DUNGEON && vm == VGA)
       || (em == DUNGEON && vm == EGA)
       || (em == PALACE && vm == EGA));

    /* optmize changed pos list */
    optimize_changed_pos ();

    /* update cache pos */
    for (i = 0; i < changed_pos_nmemb; i++) {
      update_cache_pos (&changed_pos[i], em, vm);
      struct pos pl; prel (&changed_pos[i], &pl, +0, -1);
      if (depedv && fake (&pl) == WALL)
        update_cache_pos (&pl, em, vm);
    }

    /* update cache room */
    for (i = 0; i < changed_room_nmemb; i++)
      update_cache_room (changed_room[i], em, vm);

    /* kept together so update_cache_pos and update_cache_room can
       access each other's arrays */
    destroy_array ((void **) &changed_pos, &changed_pos_nmemb);
    destroy_array ((void **) &changed_room, &changed_room_nmemb);
  }

  for (y = mr.h - 1; y >= 0; y--)
    for (x = 0; x < mr.w; x++) {
      clear_bitmap (mr.cell[x][y].screen, (mr.flicker > 0 && mr.flicker % 2)
                    ? mr.color : BLACK);

      if (! mr.cell[x][y].room) continue;
      mr.dx = x;
      mr.dy = y;
      draw_animated_background (mr.cell[x][y].screen,
                                mr.cell[x][y].room);
    }

  if (mr.flicker > 0) mr.flicker--;

  struct mr_room_list l;
  mr_get_room_list (&l);

  int xm, ym;
  if (! no_room_drawing)
    for (i = 0; i < l.nmemb; i++) {
      mr_coord (l.room[i], -1, &xm, &ym);
      for (y = mr.h - 1; y >= 0; y--)
        for (x = 0; x < mr.w; x++)
          if (mr.cell[x][y].room == l.room[i])
            draw_bitmap (mr.cell[xm][ym].cache,
                         mr.cell[x][y].screen, 0, 0, 0);
    }

  mr_destroy_room_list (&l);

  for (y = mr.h - 1; y >= 0; y--)
    for (x = 0; x < mr.w; x++) {
      if (! mr.cell[x][y].room) continue;
      mr.dx = x;
      mr.dy = y;
      draw_animated_foreground (mr.cell[x][y].screen, mr.cell[x][y].room);
    }

  mr_update_last_settings ();
}