Beispiel #1
0
bool
is_pos_seeing (struct pos *p0, struct anim *k1, enum dir dir)
{
  struct coord m0, m1, mt1, mb1; struct pos p, p1, pk, pke;
  con_m (p0, &m0);

  coord_f cf;
  if (is_kid_climb (&k1->f) || is_anim_fall (&k1->f)) {
    coord2room (_mt (&k1->f, &mt1), m0.room, &mt1);
    coord2room (_m (&k1->f, &m1), m0.room, &m1);
    coord2room (_mbo (&k1->f, &mb1), m0.room, &mb1);

    double dt, dm, db;
    dt = (mt1.room == m0.room) ? dist_coord (&m0, &mt1) : INFINITY;
    dm = (m1.room == m0.room) ? dist_coord (&m0, &m1) : INFINITY;
    db = (mb1.room == m0.room) ? dist_coord (&m0, &mb1) : INFINITY;

    if (dt <= dm && dt <= db)
      cf = (dir == LEFT) ? _tr : _tl;
    else if (db <= dt && db <= dm)
      cf = (dir == LEFT) ? _br : _bl;
    else cf = (dir == LEFT) ? _mr : _ml;
  } else cf = (dir == LEFT) ? _mr : _ml;

  surveyo (cf, -8, +0, pos, &k1->f, &m1, NULL, NULL);

  coord2room (&m0, p0->room, &m0);
  coord2room (&m1, p0->room, &m1);
  pos (&m1, &p1);

  if (dir == LEFT) {
    if (is_opaque_at_left (p0)) return false;
    if (is_opaque_at_right (&p1)) return false;
    if (peqr (&p1, p0, +0, -1)) return true;
    prel (p0, &pk, +0, -1);
    prel (&p1, &pke, +0, +1);
  } else {
    if (is_opaque_at_right (p0)) return false;
    if (is_opaque_at_left (&p1)) return false;
    if (peqr (&p1, p0, +0, +1)) return true;
    prel (p0, &pk, +0, +1);
    prel (&p1, &pke, +0, -1);
  }

  if (peq (p0, &p1)) return true;

  first_confg (&pk, &pke, opaque_cs, &p);

  return p0->room == p1.room
    && m1.room == m0.room
    && p1.floor == p0->floor
    && ! (dir == LEFT && m1.x > m0.x)
    && ! (dir == RIGHT && m1.x < m0.x)
    && p.room == -1;
}
Beispiel #2
0
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);
}
Beispiel #3
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 #4
0
static bool
flow (struct anim *k)
{
  struct pos pmt;

  bool keep_sword = k->key.down;
  bool defense = k->key.up && ! k->key.shift
    && ! k->key.left && ! k->key.right;
  bool attack = k->key.shift && ! k->key.up
    && ! k->key.left && ! k->key.right;
  bool walkf = ((k->f.dir == RIGHT) && k->key.right)
    || ((k->f.dir == LEFT) && k->key.left);
  bool walkb = ((k->f.dir == RIGHT) && k->key.left)
    || ((k->f.dir == LEFT) && k->key.right);

  struct anim *ke = get_anim_by_id (k->enemy_id);
  k->keep_sword_fast = (k->enemy_id != -1
                        && ke->current_lives > 0
                        && ! is_anim_fall (&ke->f));

  if (k->oaction != kid_sword_normal) k->i = -1;

  if (k->oaction == kid_sword_normal
      && k->current_lives <= 0) {
    survey (_mt, pos, &k->f, NULL, &pmt, NULL);
    k->p = pmt;
    kid_die (k);
    return false;
  }

  if (k->oaction == kid_sword_normal) {
    if (keep_sword) {
      /* keep_sword_fast = true; */
      kid_keep_sword (k);
      return false;
    }

    if (defense) {
      kid_sword_defense (k);
      return false;
    }

    if (attack) {
      kid_sword_attack (k);
      return false;
    }

    if (walkf) {
      kid_sword_walkf (k);
      return false;
    }

    if (walkb) {
      kid_sword_walkb (k);
      return false;
    }
  }

  k->fo.b = kid_sword_normal_00;
  k->fo.dx = k->fo.dy = +0;
  select_xframe (&k->xf, sword_frameset, 13);

  if (k->f.b == kid_take_sword_frameset[3].frame) k->fo.dx = -4;
  if (k->f.b == kid_sword_walkf_frameset[1].frame) k->fo.dx = +5;
  if (k->f.b == kid_sword_walkb_frameset[1].frame) k->fo.dx = +2;

  k->i++;

  return true;
}
Beispiel #5
0
bool
is_safe_to_follow (struct anim *k0, struct anim *k1, enum dir dir)
{
  /* not aware of enemy position */
  if (! is_valid_pos (&k0->enemy_pos)) return false;

  struct pos p0, p, p1, pke, pk;
  survey (_m, pos, &k0->f, NULL, &p0, NULL);
  survey ((k0->f.dir == LEFT) ? _mr : _ml,
          pos, &k1->f, NULL, &p1, NULL);

  pos2room (&p1, p0.room, &p1);

  /* not reachable, to start with */
  if (p0.room != p1.room) return false;
  if (p0.floor > p1.floor) return false;

  /* the character went down after the enemy */
  if (p0.floor != k0->enemy_pos.floor) {
    /* enum dir odir = (dir == LEFT) ? RIGHT : LEFT; */
    /* if (is_on_back (k0, k1) && is_seeing (k0, k1, odir) */
    /*     && p0.floor == p1.floor) return true; */
    if (is_anim_seeing (k0, k1, LEFT)
        || is_anim_seeing (k0, k1, RIGHT)) return true;
    return false;
  }

  /* if falling the chasing is inevitable (necessary to prevent
     leave_fight_logic from forgeting enemy based on the facing
     direction of the is_in_range check) */
  if (is_anim_fall (&k0->f)) return true;

  if (dir == LEFT) {
    if (! is_safe_at_left (&p0)) return false;
    if (! is_safe_at_right (&k0->enemy_pos, &k0->f)) return false;
    if (peqr (&k0->enemy_pos, &p0, +0, -1)) return true;
    prel (&p0, &pk, +0, -1);
    prel (&k0->enemy_pos, &pke, +0, +1);
    if (is_collidable_at_right (&pk, &k0->f))
      return false;
  } else {
    if (! is_safe_at_right (&p0, &k0->f)) return false;
    if (! is_safe_at_left (&k0->enemy_pos)) return false;
    if (peqr (&k0->enemy_pos, &p0, +0, +1)) return true;
    prel (&p0, &pk, +0, +1);
    prel (&k0->enemy_pos, &pke, +0, -1);
    if (is_collidable_at_right (&p0, &k0->f))
      return false;
  }

  /* enemy went down */
  if (is_traversable (&k0->enemy_pos)) {
    prel (&k0->enemy_pos, &pke, +1, +0);
    if (is_traversable (&pke) || fg (&pke) == SPIKES_FLOOR)
      return false;
    int d = (dir == LEFT) ? -1 : +1;
    if (peq (&pk, &k0->enemy_pos)) return true;
    prel (&k0->enemy_pos, &pke, +0, -1 * d);
  } else if (peq (&p0, &k0->enemy_pos)
             && ! (is_anim_seeing (k0, k1, LEFT)
                   || is_anim_seeing (k0, k1, RIGHT)))
    return false;

  first_confg (&pk, &pke, dangerous_cs, &p);
  if (is_valid_pos (&p)) return false;

  first_confg (&pk, &pke, door_cs, &p);
  if (! is_valid_pos (&p)) return true;
  else return door_at_pos (&p)->action == OPEN_DOOR
         || ! is_collidable_at_right (&p, &k0->f);
}
Beispiel #6
0
void
draw_room_anim_fg_sub (ALLEGRO_BITMAP *bitmap,
                       enum em em, enum vm vm, struct anim *a)
{
  struct pos pm, ptl, ptr, ptl2, ptr2;

  struct frame *f = &a->f;
  struct coord c; frame2room (f, room_view, &c);

  int w = al_get_bitmap_width (f->b);
  int h = al_get_bitmap_height (f->b);

  survey (_m, posf, f, NULL, &pm, NULL);
  survey (_tl, posf, f, NULL, &ptl, NULL);
  survey (_tr, posf, f, NULL, &ptr, NULL);

  pos2room (&pm, room_view, &pm);
  pos2room (&ptl, room_view, &ptl);
  pos2room (&ptr, room_view, &ptr);

  survey (_tl, pos, f, NULL, &ptl2, NULL);
  survey (_tr, pos, f, NULL, &ptr2, NULL);

  pos2room (&ptl2, room_view, &ptl2);
  pos2room (&ptr2, room_view, &ptr2);

  push_clipping_rectangle (bitmap, c.x, c.y, w, h);

  /* SWORD */
  if (fake (&pm) == CARPET
      && a->f.dir == RIGHT
      && a->xf.b) {
    struct coord c2;
    int w2 = al_get_bitmap_width (a->xf.b);
    int h2 = al_get_bitmap_height (a->xf.b);
    xframe_coord (&a->f, &a->xf, &c2);
    ignore_clipping_rectangle_intersection = true;
    push_clipping_rectangle (bitmap, c2.x, c2.y, w2, h2);
    push_drawn_rectangle (bitmap);
    draw_confg_right (bitmap, &pm, em, vm);
    redraw_drawn_rectangle (pop_drawn_rectangle (), &pm, em, vm);
    pop_clipping_rectangle ();
    ignore_clipping_rectangle_intersection = false;
  }

  /* CLIMBING STAIRS */
  if (is_kid_stairs (f)) draw_level_door_fg (bitmap, &a->p, f, em, vm);

  /* FALLING */
  if (is_anim_fall (f)) {
    push_clipping_rectangle (bitmap,
                             PLACE_WIDTH * ptr2.place,
                             PLACE_HEIGHT * ptr2.floor + 56,
                             PLACE_WIDTH + 12,
                             PLACE_HEIGHT - 53);

    push_drawn_rectangle (bitmap);

    if (! is_strictly_traversable_fake (&ptr2))
      draw_confg (bitmap, &ptr2, em, vm);
    if (! is_strictly_traversable_fake (&ptr))
      draw_confg (bitmap, &ptr, em, vm);

    redraw_drawn_rectangle (pop_drawn_rectangle (), &ptr2, em, vm);

    pop_clipping_rectangle ();
  }

  /* VERTICAL JUMP */
  if (is_kid_vjump_touching_above (f)) {
    push_clipping_rectangle (bitmap,
                             PLACE_WIDTH * ptl2.place,
                             PLACE_HEIGHT * ptl2.floor + 56,
                             2 * PLACE_WIDTH,
                             PLACE_HEIGHT - 56 + 3);

    push_drawn_rectangle (bitmap);

    draw_confg (bitmap, &ptl2, em, vm);
    draw_confg (bitmap, &ptr, em, vm);

    redraw_drawn_rectangle (pop_drawn_rectangle (), &ptl2, em, vm);

    pop_clipping_rectangle ();
  }

  /* HANGING */
  if (is_kid_hang (f)) {
    struct pos p; get_hanged_pos (&a->hang_pos, f->dir, &p);
    struct pos pb; prel (&p, &pb, +0, f->dir == LEFT ? +1 : -1);
    pos2room (&p, room_view, &p);
    pos2room (&pb, room_view, &pb);

    if (f->dir == RIGHT) {
      push_clipping_rectangle (bitmap,
                               PLACE_WIDTH * p.place,
                               PLACE_HEIGHT * p.floor + 56,
                               PLACE_WIDTH,
                               PLACE_HEIGHT - 53);
      push_drawn_rectangle (bitmap);
      draw_confg (bitmap, &p, em, vm);
      redraw_drawn_rectangle (pop_drawn_rectangle (), &p, em, vm);
    } else {
      push_clipping_rectangle (bitmap,
                               PLACE_WIDTH * pb.place,
                               PLACE_HEIGHT * pb.floor + 56,
                               PLACE_WIDTH,
                               PLACE_HEIGHT - 53);
      push_drawn_rectangle (bitmap);
      draw_confg (bitmap, &pb, em, vm);
      redraw_drawn_rectangle (pop_drawn_rectangle (), &pb, em, vm);
    }

    pop_clipping_rectangle ();
  }

  /* CLIMBING FLOOR */
  if (is_kid_climb (f)) {
    struct pos p; get_hanged_pos (&a->hang_pos, f->dir, &p);
    struct pos pb; prel (&p, &pb, +0, f->dir == LEFT ? +1 : -1);
    pos2room (&p, room_view, &p);
    pos2room (&pb, room_view, &pb);

    if (f->dir == RIGHT) {
      int dy, w;

      if (f->b == kid_climb_00
          || f->b == kid_climb_01
          || f->b == kid_climb_02
          || f->b == kid_climb_08
          || f->b == kid_climb_09) {
        dy = 55;
        w = 18;
      } else if (f->b == kid_climb_05
                 || f->b == kid_climb_06) {
        dy = 53;
        w = 22;
      } else if (f->b == kid_climb_03
                 || f->b == kid_climb_07
                 || f->b == kid_climb_04) {
        dy = 53;
        w = 21;
      }

      push_clipping_rectangle (bitmap,
                               PLACE_WIDTH * p.place,
                               PLACE_HEIGHT * p.floor + dy,
                               w,
                               PLACE_HEIGHT - dy + 3);
      push_drawn_rectangle (bitmap);
      draw_confg (bitmap, &p, em, vm);
      redraw_drawn_rectangle (pop_drawn_rectangle (), &p, em, vm);
    } else {
      push_clipping_rectangle (bitmap,
                               PLACE_WIDTH * pb.place,
                               PLACE_HEIGHT * pb.floor + 54,
                               PLACE_WIDTH,
                               PLACE_HEIGHT - 54 + 3);
      push_drawn_rectangle (bitmap);
      draw_confg (bitmap, &pb, em, vm);
      redraw_drawn_rectangle (pop_drawn_rectangle (), &pb, em, vm);
    }

    pop_clipping_rectangle ();
  }

  pop_clipping_rectangle ();

  draw_room_frame_fg (bitmap, em, vm, f);

  /* xframe */
  if (a->xf.b) {
    struct frame xf; xframe_frame (&a->f, &a->xf, &xf);
    draw_room_frame_fg (bitmap, em, vm, &xf);
  }

  /* splash */
  if (a->splash) {
    struct frame sf; splash_frame (&a->f, &sf);
    draw_room_frame_fg (bitmap, em, vm, &sf);
  }
}