示例#1
0
文件: fight.c 项目: oitofelix/mininim
void
fight_hit (struct anim *k, struct anim *ke)
{
  if (k->immortal || k->sword_immune) return;
  if (k->current_lives <= 0) return;
  if (is_anim_fall (&k->f) || is_kid_stairs (&k->f))
    return;

  place_on_the_ground (&k->f, &k->f.c);
  k->xf.b = NULL;

  if (! is_in_fight_mode (k)) k->current_lives = 0;
  else k->current_lives--;

  if (! is_guard (ke))
    upgrade_skill (&ke->skill, &k->skill, k->total_lives);

  int d = (k->f.dir == LEFT) ? +1 : -1;
  struct pos pb;
  survey (_m, pos, &k->f, NULL, &k->p, NULL);
  prel (&k->p, &pb, 0, d);

  if (k->current_lives <= 0 && ! is_strictly_traversable (&pb)) {
    k->current_lives = 0;
    k->death_reason = FIGHT_DEATH;
    ke->alert_cycle = anim_cycle;
    anim_die (k);
  } else anim_sword_hit (k);

  if (is_in_fight_mode (k)) {
    backoff_from_range (ke, k, ATTACK_RANGE - 20, true, false);
    get_in_range (ke, k, ATTACK_RANGE - 10, false, false);
  }

  k->splash = true;

  if (k->id == current_kid_id) {
    mr.flicker = 2;
    mr.color = get_flicker_blood_color ();
    play_audio (&harm_audio, NULL, k->id);
  } else play_audio (&guard_hit_audio, NULL, k->id);
}
示例#2
0
static bool
flow (struct anim *k)
{
  struct pos p;

  if (k->oaction != kid_drink)
    k->i = -1, k->wait = 4, k->reverse = false;

  if (k->i < 14 && ! k->reverse) k->i++;
  else if (k->wait > 0) k->wait--;
  else if (k->i == 14 && k->wait == 0) k->reverse = true, k->i = 10;
  else if (k->i == 10 && k->reverse) k->i = 7;
  else {
    kid_normal (k);
    invalid_pos (&k->item_pos);
    return false;
  }

  if (k->i == 14 && k->wait == 1)
    switch (k->item) {
    case EMPTY_POTION: break;
    case SMALL_LIFE_POTION: increase_kid_current_lives (k); break;
    case BIG_LIFE_POTION: increase_kid_total_lives (k); break;
    case SMALL_POISON_POTION:
      if (k->immortal
          || k->poison_immune) break;
      k->current_lives--;
      k->splash = true;
      if (k->current_lives == 0) k->death_reason = POTION_DEATH;
      play_sample (harm_sample, NULL, k->id);
      if (k->id == current_kid_id) {
        mr.flicker = 2;
        mr.color = get_flicker_blood_color ();
      }
      break;
    case BIG_POISON_POTION:
      if (k->immortal
          || k->poison_immune) break;
      k->current_lives = 0;
      k->splash = true;
      k->death_reason = POTION_DEATH;
      play_sample (harm_sample, NULL, k->id);
      if (k->id == current_kid_id) {
        mr.flicker = 2;
        mr.color = get_flicker_blood_color ();
      }
      break;
    case FLOAT_POTION: float_kid (k); break;
    case FLIP_POTION:
      if (screen_flags) screen_flags = 0;
      else {
        switch (prandom_pos (&k->item_pos, 2)) {
        case 0: screen_flags ^= ALLEGRO_FLIP_VERTICAL; break;
        case 1: screen_flags ^= ALLEGRO_FLIP_HORIZONTAL; break;
        case 2: screen_flags ^= ALLEGRO_FLIP_VERTICAL | ALLEGRO_FLIP_HORIZONTAL; break;
        }
      }
      break;
    case ACTIVATION_POTION: p.room = 8, p.floor = p.place = 0;
      activate_con (&p); break;
    default: break;
    }

  select_frame (k, kid_drink_frameset, k->i);

  if (k->i == 14 && k->wait < 4) k->fo.dx = 0;
  if (k->i == 10 && k->reverse) k->fo.dx = -2, k->fo.dy = +1;
  if (k->i == 7 && k->reverse) k->fo.dx = +1;

  return true;
}
示例#3
0
void
compute_loose_floor_fall (struct loose_floor *l)
{
  int speed = 3 * ++l->i;
  if (speed > 29) speed = 29;

  struct frame nf;
  struct frame_offset fo;
  fo.b = l->f.b;
  fo.dx = 0;
  fo.dy = speed;
  next_frame (&l->f, &nf, &fo);
  struct coord mbo_f, mbo_nf;
  struct pos fpmbo_f, nfpmbo_f, fpmbo_nf, nfpmbo_nf;
  enum confg fcmbo_f;
  fcmbo_f = survey (_mbo, posf, &l->f, &mbo_f, &fpmbo_f, &nfpmbo_f)->fg;
  survey (_mbo, posf, &nf, &mbo_nf, &fpmbo_nf, &nfpmbo_nf);

  struct pos p;

  /* hit kid */
  int i;
  for (i = 0; i < anima_nmemb; i++) {
    struct coord kmt, ambo_f, ambo_nf; struct pos np, kpmt;
    struct anim *a = &anima[i];
    if (is_anim_dead (&a->f)
        || a->immortal
        || a->loose_floor_immune)
      continue;
    survey (_mt, pos, &a->f, &kmt, &kpmt, &np);
    coord2room (&mbo_f, kpmt.room, &ambo_f);
    coord2room (&mbo_nf, kpmt.room, &ambo_nf);
    if (peq (&nfpmbo_f, &kpmt)
        && ambo_f.y <= kmt.y
        && ambo_nf.y >= kmt.y
        && ! a->hit_by_loose_floor
        && ! is_kid_hang_or_climb (&a->f)
        && ! is_kid_fall (&a->f)) {
      a->hit_by_loose_floor = true;
      a->splash = true;
      a->current_lives--;
      a->uncouch_slowly = true;
      /* ensure kid doesn't couch in thin air (might occur when hit
         while jumping, for example) */
      place_on_the_ground (&a->f, &a->f.c);
      play_sample (hit_wall_sample, kpmt.room);
      alert_guards (&kpmt);
      if (a->id == current_kid_id) {
        video_effect.color = get_flicker_blood_color ();
        start_video_effect (VIDEO_FLICKERING, SECS_TO_VCYCLES (0.1));
      }
      if (a->current_lives <= 0) {
        a->p = kpmt;
        anim_die_suddenly (a);
        a->death_reason = LOOSE_FLOOR_DEATH;
      }
      else if (a->type == KID) kid_couch (a);
    }
  }

  /* fall */
  if (is_strictly_traversable (&fpmbo_f)
      || peq (&fpmbo_f, &fpmbo_nf)) {
    /* the floor hit a rigid structure */
    if (is_rigid_con (&fpmbo_nf)) prel (&fpmbo_nf, &p, -1, 0);
    /* the floor continue to fall */
    else {
      l->f = nf;
      if (is_strictly_traversable (&fpmbo_nf)) l->p = fpmbo_nf;
      must_sort = true;
      return;
    }
    /* the floor hit the ground */
  } else {
    struct loose_floor *m;
    p = fpmbo_f;
    switch (fcmbo_f) {
    case LOOSE_FLOOR: /* loose floor isn't ground */
      m = loose_floor_at_pos (&fpmbo_f);
      if (m) m->p.room = -1;
      must_remove = true;
      l->f = nf;
      l->f.b = get_correct_falling_loose_floor_bitmap (dv_broken_floor);
      l->p = fpmbo_f;
      l->i = 0;
      con (&fpmbo_f)->fg = NO_FLOOR;
      must_sort = true;
      play_sample (broken_floor_sample, p.room);
      alert_guards (&p);
      return;
    case OPENER_FLOOR: break_opener_floor (&fpmbo_f); break;
    case CLOSER_FLOOR: break_closer_floor (&fpmbo_f); break;
    case SPIKES_FLOOR: break_spikes_floor (&fpmbo_f); break;
    case LEVEL_DOOR: break_level_door (&fpmbo_f); break;
    default: break;
    }
  }

  /* reach here only if the floor hit a rigid structure or the
     ground */
  if (con (&p)->fg != LEVEL_DOOR) con (&p)->fg = BROKEN_FLOOR;
  shake_loose_floor_row (&p);
  l->p.room = -1;
  must_remove = true;
  must_sort = true;
  play_sample (broken_floor_sample, p.room);
  alert_guards (&p);
}
示例#4
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);
      }
    }
  }
}