コード例 #1
0
ファイル: guard-die.c プロジェクト: allisson128/mininim
void
guard_die_suddenly (struct anim *g)
{
  if (con (&g->p)->fg == SPIKES_FLOOR
      || con (&g->p)->fg == CHOPPER) {
    guard_die_properly (g);
    return;
  }

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

  struct frameset *frameset = get_guard_die_frameset (g->type);

  int dy = (g->type == SKELETON) ? +44 : +47;

  place_frame (&g->f, &g->f, frameset[5].frame,
               &g->p, (g->f.dir == LEFT)
               ? +9 : +4, dy);

  if (g->oaction != guard_die_suddenly) {
    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;
  g->xf.b = NULL;

  g->hit_by_loose_floor = false;

  /* fall */
  struct pos pm;
  survey (_m, pos, &g->f, NULL, &pm, NULL);
  if (is_strictly_traversable (&pm)) {
    guard_fall (g);
    return;
  }

  /* depressible floors */
  update_depressible_floor (g, -12, -28);
}
コード例 #2
0
ファイル: guard-die.c プロジェクト: allisson128/mininim
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;
}
コード例 #3
0
ファイル: spikes-floor.c プロジェクト: allisson128/mininim
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);
}
コード例 #4
0
ファイル: guard-die.c プロジェクト: allisson128/mininim
void
guard_die_chopped (struct anim *g)
{
  if (con (&g->p)->fg != CHOPPER) {
    guard_die_properly (g);
    return;
  }

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

  int dx, dy;

  if (g->type == SHADOW) {
    dx = (g->f.dir == LEFT) ? -8 : -7;
    dy = +47;
  } else {
    dx = (g->f.dir == LEFT) ? -10 : -13;
    dy = (g->type == SKELETON) ? +45 : +43;
  }

  ALLEGRO_BITMAP *bitmap = get_guard_die_chopped_bitmap (g->type);
  place_frame (&g->f, &g->f, bitmap, &g->p, dx, dy);

  if (g->oaction != guard_die_chopped) {
    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;
  g->xf.b = NULL;
}
コード例 #5
0
ファイル: fight.c プロジェクト: oitofelix/mininim
void
fight_turn_controllable (struct anim *k)
{
  int d = INT_MAX;
  int t; /* threshold */
  struct anim *ke = NULL;
  struct anim *ke0 = get_anim_by_id (k->enemy_id);

  /* make the kid target the nearest enemy targeting him */
  int i;
  for (i = 0; i < anima_nmemb; i++) {
    struct anim *a = &anima[i];
    if (a->enemy_id != k->id || ! is_fightable_anim (a))
      continue;
    int de = dist_enemy (a);
    if (de < d) {
      d = de;
      ke = a;
    }
  }

  if (ke && ke0 && ke->f.dir != ke0->f.dir) t = 20;
  else t = -1;

  if (ke && abs (dist_enemy (k) - d) > t)
    consider_enemy (k, ke);

  ke = get_anim_by_id (k->enemy_id);
  if (ke) {
    struct pos p, pe;
    survey (_m, pos, &k->f, NULL, &p, NULL);
    survey (_m, pos, &ke->f, NULL, &pe, NULL);
    pos2room (&pe, p.room, &pe);
    if (is_on_back (k, ke)
        && ! is_in_range (k, ke, INVERSION_RANGE)
        && is_in_fight_mode (k)
        && is_in_fight_mode (ke)
        && p.room == pe.room
        && p.floor == pe.floor)
      fight_turn (k);
  }
}
コード例 #6
0
ファイル: guard-die.c プロジェクト: allisson128/mininim
static bool
flow (struct anim *g)
{
  if (g->oaction != guard_die) {
    place_frame (&g->f, &g->f, guard_die_frameset[0].frame,
                 &g->p, (g->f.dir == LEFT)
                 ? +13 : +21, (g->type == SHADOW) ? +18 : +17);
    g->i = -1, g->j = 0;
    if (g->type == SKELETON)
      play_sample (skeleton_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->xf.b = NULL;
  }

  g->current_lives = 0;

  g->i = g->i < 5 ? g->i + 1 : 5;

  struct frameset *frameset = get_guard_die_frameset (g->type);
  select_frame (g, frameset, g->i);

  if (g->j >= 1) g->fo.dx = g->fo.dy = 0;
  if (g->i == 5) g->j = 1;
  if (g->j == 1) g->j++;

  return true;
}
コード例 #7
0
ファイル: fight.c プロジェクト: oitofelix/mininim
int
dist_enemy (struct anim *k)
{
  struct anim *k1 = get_anim_by_id (k->enemy_id);

  if (! k1) return INT_MAX;

  struct frame f1 = k1->f;
  frame2room (&f1, k->f.c.room, &f1.c);

  struct coord m0, m1;
  _m (&k->f, &m0);
  _m (&f1, &m1);

  if (m0.room != m1.room) return INT_MAX;

  return abs (m1.x - m0.x);
}
コード例 #8
0
static bool
flow (struct anim *k)
{
  if (k->oaction != kid_sword_defense) k->i = -1;

  struct anim *ke = get_anim_by_id (k->enemy_id);
  if (k->i == 2) {
    kid_sword_attack (k);
    return false;
  } else if (k->i == 1 && ke && ke->attack_defended == 2
           && ke->counter_attacked != 2) {
    kid_sword_walkb (k);
    return false;
  } else if (k->i == 1 && ! (ke && ke->attack_defended == 2)) {
    kid_sword_normal (k);
    return false;
  }

  if (k->oaction == kid_sword_attack) {
    select_frame (k, kid_sword_walkb_frameset, 0);
    k->j = 10;
  } else if (k->f.b == kid_sword_walkb_frameset[0].frame) {
    select_frame (k, kid_sword_defense_frameset, 1);
    k->fo.dx += 7;
    k->j = 14;
  } else {
    select_frame (k, kid_sword_defense_frameset, k->i + 1);

    if (k->i == 0) k->j = 28;
    if (k->i == 1) k->j = 14;
    if (k->i == 2) k->j = 15;
  }

  select_xframe (&k->xf, sword_frameset, k->j);

  if (k->oaction == kid_sword_attack) k->fo.dx += +2;

  /* if (k->id == 0) */
  /*   printf ("kid_sword_defense: k->i = %i, k->fo.dx = %i\n", */
  /*           k->i, k->fo.dx); */

  return true;
}
コード例 #9
0
ファイル: fight.c プロジェクト: oitofelix/mininim
void
put_at_defense_frame (struct anim *k)
{
  struct frameset *frameset;
  play_audio (&sword_defense_audio, NULL, k->id);

  switch (k->type) {
  case NO_ANIM: default: break;
  case KID:
    select_frame (k, kid_sword_defense_frameset, 0);
    next_frame (&k->f, &k->f, &k->fo);

    select_frame (k, kid_sword_defense_frameset, 1);

    struct anim *ke = get_anim_by_id (k->enemy_id);
    if (ke->type == KID) {
      select_xframe (&k->xf, sword_frameset, 11);
      k->xf.dx = -13;
      k->xf.dy = +5;
    } else select_xframe (&k->xf, sword_frameset, 14);

    k->action = kid_sword_defense;
    uncollide_back_fight (k);
    next_frame (&k->f, &k->f, &k->fo);
    break;
  case GUARD:
  case FAT_GUARD:
  case VIZIER:
  case SKELETON:
  case SHADOW:
    frameset = get_guard_defense_frameset (k->type);
    select_frame (k, frameset, 0);
    select_xframe (&k->xf, sword_frameset, 11);
    k->action = guard_defense;
    uncollide_back_fight (k);
    next_frame (&k->f, &k->f, &k->fo);
    break;
  }

  /* if (k->id == 0) */
  /*   printf ("%s: k->i = %i, k->fo.dx = %i\n", */
  /*           __func__, k->i, k->fo.dx); */
}
コード例 #10
0
ファイル: guard-defense.c プロジェクト: allisson128/mininim
static bool
flow (struct anim *g)
{
  if (g->oaction != guard_defense) g->i = -1;

  struct anim *ke = get_anim_by_id (g->enemy_id);
  if (g->i == 1) {
    guard_attack (g);
    return false;
  } else if (g->i == 0 && ke && ke->attack_defended == 2
           && ke->counter_attacked != 2) {
    guard_walkb (g);
    return false;
  } else if (g->i == 0 && ! (ke && ke->attack_defended == 2)) {
    guard_vigilant (g);
    return false;
  }

  struct frameset *frameset = get_guard_defense_frameset (g->type);
  select_frame (g, frameset, g->i + 1);

  if (g->i == 0) g->j = 11;

  select_xframe (&g->xf, sword_frameset, g->j);

  if (g->i == 1) g->xf.b = NULL;

  if (g->oaction == guard_attack) g->fo.dx += +2;

  if (g->type == SKELETON) g->xf.dy += -3;
  if (g->type == SHADOW) g->xf.dy += -2;

  /* if (g->id == 0) */
  /*   printf ("guard_defense: g->i = %i, g->fo.dx = %i\n", */
  /*           g->i, g->fo.dx); */

  return true;
}
コード例 #11
0
ファイル: mirror.c プロジェクト: oitofelix/mininim
void
draw_mirror_fg (ALLEGRO_BITMAP *bitmap, struct pos *p, struct frame *f,
                enum em em, enum vm vm)
{
  ALLEGRO_BITMAP *mirror = NULL;

  switch (em) {
  case DUNGEON:
    switch (vm) {
    case CGA: mirror = dc_mirror; break;
    case EGA: mirror = de_mirror; break;
    case VGA: mirror = dv_mirror; break;
    }
    break;
  case PALACE:
    switch (vm) {
    case CGA: mirror = pc_mirror; break;
    case EGA: mirror = pe_mirror; break;
    case VGA: mirror = pv_mirror; break;
    }
    break;
  }

  /* make mirror black */
  struct rect r;
  new_rect (&r, p->room, PLACE_WIDTH * p->place + 2,
            PLACE_HEIGHT * p->floor + 3,
            13, PLACE_HEIGHT - 16);
  draw_filled_rect (bitmap, &r, BLACK);

  /* draw floor reflex */
  draw_floor_reflex (bitmap, p, em, vm);

  ignore_clipping_rectangle_intersection = true;
  /* draw anim */
  if (f) {
    push_clipping_rectangle (bitmap, PLACE_WIDTH * p->place + 2,
                             PLACE_HEIGHT * p->floor + 3,
                             16, PLACE_HEIGHT - 9);
    struct anim *a = get_anim_by_id (f->parent_id);
    struct anim a0 = *a;
    invert_frame_dir (&a0.f, &a0.f);
    a0.f.c.x = (2 * PLACE_WIDTH * p->place + 36)
      - (a->f.c.x + al_get_bitmap_width (a->f.b));
    draw_anim_frame (bitmap, &a0, vm);
    pop_clipping_rectangle ();
  }

  /* draw mirror properly */
  if (vm == VGA) mirror = apply_hue_palette (mirror);
  if (hgc) mirror = apply_palette (mirror, hgc_palette);
  if (peq (p, &mouse_pos))
    mirror = apply_palette (mirror, selection_palette);

  struct coord c;
  int h = al_get_bitmap_height (mirror);
  push_reset_clipping_rectangle (bitmap);
  draw_bitmap_regionc (mirror, bitmap, 0, 0, 22, h, mirror_coord (p, &c), 0);
  pop_clipping_rectangle ();

  ignore_clipping_rectangle_intersection = false;
}
コード例 #12
0
ファイル: fight.c プロジェクト: oitofelix/mininim
void
leave_fight_logic (struct anim *k)
{
  /* dead character doesn't fight */
  if (k->current_lives <= 0) {
    k->enemy_refraction = 0;
    forget_enemy (k);
    return;
  }

  /* non-fightable characters don't fight */
  if (! is_fightable_anim (k)) return;

  /* no enemy, no need to forget */
  if (k->enemy_id == -1) return;

  /* non-fighter doesn't fight */
  if (! k->fight) return;

  /* character that went upstairs doesn't fight */
  if (is_kid_stairs (&k->f)) {
    k->enemy_refraction = 0;
    forget_enemy (k);
    return;
  }

  /* who's the enemy? */
  struct anim *ke = get_anim_by_id (k->enemy_id);

  /* if the enemy doesn't exist, forget about it */
  if (! ke) {
    k->enemy_refraction = 0;
    forget_enemy (k);
    return;
  }

  /* if the enemy is dead no need to worry about him */
  if (ke->current_lives <= 0) {
    k->enemy_refraction = 0;
    forget_enemy (k);
    return;
  }

  /* if the enemy went up stairs, forget about him */
  if (is_kid_stairs (&ke->f)) {
    k->enemy_refraction = 0;
    forget_enemy (k);
    return;
  }

  /* if the enemy is not reachable, forget about him */
  enum dir odir = (k->f.dir == LEFT) ? RIGHT : LEFT;
  struct pos p, pe;
  survey (_m, pos, &k->f, NULL, &p, NULL);
  survey (_m, pos, &ke->f, NULL, &pe, NULL);
  pos2room (&pe, p.room, &pe);
  if (! is_anim_seeing (k, ke, k->f.dir)
      && ! is_near (k, ke)
      && ! is_safe_to_follow (k, ke, k->f.dir)
      && ! (is_on_back (k, ke) && is_anim_seeing (k, ke, odir)
            && p.floor == pe.floor)) {
    forget_enemy (k);
    return;
  }
}
コード例 #13
0
ファイル: fight.c プロジェクト: oitofelix/mininim
void
fight_mechanics (struct anim *k)
{
  if (k->sword_immune > 0) k->sword_immune--;

  /* 'ke' is the attacking part */
  struct anim *ke = get_anim_by_id (k->enemy_id);

  if (! ke || ke->enemy_id != k->id) return;

  fight_inversion_mechanics (k, ke);

  if (! is_attacking (ke) || is_sword_hit (k)) return;

  if (! ke->attack_range_far)
    ke->attack_range_far =
      (is_in_range (k, ke, ATTACK_RANGE + 16) && ke->i == 0);

  if (! ke->attack_range_near)
    ke->attack_range_near =
      (is_in_range (k, ke, ATTACK_RANGE) && ke->i == 0);

  if (! ke->enemy_defended_my_attack)
    ke->enemy_defended_my_attack =
      (ke->i < 4 && k->key.up && ke->attack_range_far)
      || (ke->attack_range_far && ! ke->attack_range_near);

  if (is_walkingf (k) || is_attacking (k) || ! is_in_fight_mode (k))
    ke->enemy_defended_my_attack = 0;

  bool walkb = ((k->f.dir == RIGHT) && k->key.left)
    || ((k->f.dir == LEFT) && k->key.right);

  if (! ke->enemy_counter_attacked_myself)
    ke->enemy_counter_attacked_myself =
      (ke->enemy_defended_my_attack && k->key.shift
       && prandom (99) <= k->skill.counter_attack_prob
       && (ke->attack_range_near || k->attack_range_near)
       && ! walkb);

  if (! ke->i_counter_defended)
    ke->i_counter_defended =
      (ke->enemy_counter_attacked_myself && ke->key.up
       && prandom (99) <= ke->skill.counter_defense_prob);

  if (! k->hurt_enemy_in_counter_attack)
    k->hurt_enemy_in_counter_attack =
      (ke->enemy_counter_attacked_myself && ! ke->i_counter_defended);

  /* printf ("ke->attack_range_near: %i\n", ke->attack_range_near); */

  /* printf ("ke->enemy_defended_my_attack = %i, ke->i = %i, k->key.up = %i\n", */
  /*         ke->enemy_defended_my_attack, ke->i, k->key.up); */

  if (! ke->enemy_defended_my_attack && is_at_hit_frame (ke)
      && ! is_on_back (ke, k)
      && (ke->attack_range_far || ! is_in_fight_mode (k))
      && ((is_in_range (k, ke, HIT_RANGE + 4) && is_in_fight_mode (k))
          || (is_in_range (k, ke, ATTACK_RANGE) && ! is_in_fight_mode (k))))
    fight_hit (k, ke);
  else if (ke->hurt_enemy_in_counter_attack
           && is_at_hit_frame (ke)
           && ! is_on_back (ke, k)) fight_hit (k, ke);
  else if (ke->enemy_defended_my_attack == 1
           && is_at_defendable_attack_frame (ke)) {
    if (is_in_range (k, ke, HIT_RANGE + 8)
        || is_defending (k)) {
      backoff_from_range (ke, k, ATTACK_RANGE - 20, false, false);
      get_in_range (ke, k, ATTACK_RANGE - 6, false, false);
      put_at_attack_frame (ke);
      put_at_defense_frame (k);
    } else ke->enemy_defended_my_attack = false;
  }

/*   printf ("id: %i, ad: %i, ca: %i, cd: %i, i: %i, hurt: %i\n\ */
/* id: %i, ad: %i, ca: %i, cd: %i, i: %i, hurt: %i\n\ */
/* -------------------------------\n", */
/*           k->id, k->enemy_defended_my_attack, k->enemy_counter_attacked_myself, k->i_counter_defended, k->i, k->hurt, */
/*           ke->id, ke->enemy_defended_my_attack, ke->enemy_counter_attacked_myself, ke->i_counter_defended, ke->i, ke->hurt); */
}
コード例 #14
0
ファイル: fight.c プロジェクト: oitofelix/mininim
void
fight_ai (struct anim *k)
{
  /* non-fightable characters don't fight */
  if (! is_fightable_anim (k)) return;

  /* controllables and non-fighters doesn't need AI to fight */
  if (k->controllable || ! k->fight) return;

  /* if forgetting about an enemy, no need to fight */
  if (k->enemy_refraction > 0) return;

  /* without an enemy or awareness, no need to fight */
  if (k->enemy_id == -1) {
    if (is_in_fight_mode (k)) leave_fight_mode (k);
    return;
  }

  /* first thing, enter in fight mode */
  if (! is_in_fight_mode (k)) {
    enter_fight_mode (k);
    return;
  }

  /* who's the enemy? */
  struct anim *ke = get_anim_by_id (k->enemy_id);

  /* what's the facing opposite direction? */
  enum dir odir = (k->f.dir == LEFT) ? RIGHT : LEFT;

  /* get positions */
  struct pos p, pe;
  survey (_m, pos, &k->f, NULL, &p, NULL);
  survey ((k->f.dir != ke->f.dir) ? _m : _mba,
          pos, &ke->f, NULL, &pe, NULL);
  pos2room (&pe, p.room, &pe);

  /* remember the place the enemy was last seen */
  if (pe.room == p.room && pe.floor == p.floor)
    k->enemy_pos = pe;
  else if (pe.floor > p.floor && is_valid_pos (&k->enemy_pos)
           && ! is_strictly_traversable (&k->enemy_pos))
    k->enemy_pos.place = pe.place;

  if (is_valid_pos (&k->enemy_pos)
      && is_strictly_traversable (&k->enemy_pos)) {
    struct pos pp;
    int d = (p.place < k->enemy_pos.place) ? -1 : +1;
    while (is_strictly_traversable (prel (&k->enemy_pos, &pp, +0, d)))
      k->enemy_pos = pp;
  }

  /* prevent enemy from passing through */
  if (ke->type == KID
      && is_in_range (k, ke, ATTACK_RANGE)
      && ! is_in_fight_mode (ke)
      && ! ke->immortal
      && ! (is_kid_climb (&ke->f) && ke->i <= 7)
      && ke->f.dir != k->f.dir
      && ke->current_lives > 0
      && ke->has_sword
      && ! is_kid_fall (&ke->f)
      && ! is_kid_hang (&ke->f)
      && ! is_kid_jump_air (&ke->f)
      && ! is_kid_run_jump_air (&ke->f)
      && is_safe_to_attack (ke)) {
    place_on_the_ground (&ke->f, &ke->f.c);
    kid_take_sword (ke);
    ke->auto_taken_sword = true;
  }

  /* prevent enemy from hiding near */
  if (ke->type == KID
      && is_in_range (k, ke, INVERSION_RANGE)
      && ! is_in_fight_mode (ke)
      && ke->current_lives > 0) {
    if (is_safe_to_walkb (k)) fight_walkb (k);
    else if (is_safe_to_turn (k)) fight_turn (k);
    return;
  }

  /* if the enemy is on the back, turn */
  if (is_on_back (k, ke) && is_anim_seeing (k, ke, odir)
      && p.floor == pe.floor
      && ! is_in_range (k, ke, INVERSION_RANGE)) {
    if (is_safe_to_turn (k)) fight_turn (k);
    else if (is_safe_to_walkb (k)) fight_walkb (k);
    return;
  }

  /* if too near to a wall, back off to have room for an attack */
  if (fight_crel (k, +0, +1) == WALL
      && is_safe_to_walkb (k)) {
    fight_walkb (k);
    return;
  }

  /* /\* if the enemy can be followed in the opposite direction, turn *\/ */
  /* if (! is_safe_to_follow (k, ke, k->f.dir) */
  /*     && is_safe_to_follow (k, ke, odir)) { */
  /*   fight_turn (k); */
  /*   return; */
  /* } */

  /* if the enemy is trying to bypass, attack him */
  if (! is_in_fight_mode (ke)
      && ! ke->has_sword
      && ! is_kid_stairs (&ke->f)
      && ke->f.dir != k->f.dir
      && ke->current_lives > 0
      && ! is_on_back (k, ke)
      && ((is_kid_run (&ke->f)
           && is_in_range (k, ke, 3 * PLACE_WIDTH - 4))
          || (is_kid_run_jump (&ke->f)
              && is_in_range (k, ke, 4 * PLACE_WIDTH - 4))
          || (is_kid_jump_air (&ke->f) && ke->i < 9
              && is_in_range (k, ke, 4 * PLACE_WIDTH)))) {
    if (is_safe_to_attack (k)) fight_attack (k);
    else if (is_safe_to_walkb (k)) fight_walkb (k);
    return;
  }

  /* stays at least in the fight range.  Advance, unless the enemy is
     not running towards you */
  if (! is_in_range (k, ke, FIGHT_RANGE + 10)
      && ! is_kid_stairs (&ke->f)
      && (ke->f.dir == k->f.dir
          || p.room != pe.room
          || p.floor != pe.floor
          || ! (is_kid_run (&ke->f)
                || is_kid_run_jump (&ke->f)
                || is_kid_jump (&ke->f)))
      && is_safe_to_follow (k, ke, k->f.dir)) {
    fight_walkf (k);
    return;
  }

  /* if the enemy is not targeting you, do nothing more */
  if (ke->enemy_id != -1 && ke->enemy_id != k->id) return;

  /* in fight range, if the enemy is not attacking, go towards attack
     range (with probability, unless the enemy is not in fight mode,
     then go immediately) */
  if (is_in_range (k, ke, FIGHT_RANGE + 10)
      && ! is_in_range (k, ke, ATTACK_RANGE)
      && ! is_kid_stairs (&ke->f)
      && is_safe_to_follow (k, ke, k->f.dir)
      && (prandom (99) <= k->skill.advance_prob
          || ! is_in_fight_mode (ke))
      && ! is_attacking (ke)
      && (! is_in_fight_mode (ke)
          || is_walking (ke)
          || ke->i >= 6 + prandom (24))) {
    fight_walkf (k);
    return;
  }

  /* in attack range, if being attacked, defend yourself (with
     probability) and counter attack (with probability handled
     elsewhere) */
  if (is_in_range (k, ke, ATTACK_RANGE + 16)
      && ! is_on_back (k, ke)
      && (is_attacking (ke) && ke->i == 0)
      && (prandom (99) <= k->skill.defense_prob
          || k->refraction > 0)
      && ke->current_lives > 0) {
    fight_defense (k);
    fight_attack (k);
    return;
  }

  /* if attacking, counter defend
     (with probability handled elsewhere) */
  if (is_in_range (k, ke, ATTACK_RANGE + 16)
      && is_attacking (k)) {
    fight_defense (k);
    fight_attack (k);
    return;
  }

  /* in attack range, if not being attacked, attack (with probability,
     unless the enemy is not in fight mode, then attack immediately) */
  if (is_in_range (k, ke, ATTACK_RANGE)
      && ! is_attacking (ke)
      && ! is_on_back (k, ke)
      && ! is_kid_stairs (&ke->f)
      && ! ((is_kid_climb (&ke->f)
             || is_kid_successfully_climbing (&ke->f))
            && ke->i >= 1)
      && ke->current_lives > 0
      && (prandom (99) <= k->skill.attack_prob
          || ! is_in_fight_mode (ke))) {
    if (is_safe_to_attack (k)) fight_attack (k);
    else if (is_safe_to_walkb (k)) fight_walkb (k);
    return;
  }

  /* in hit range, back off (with probability) */
  if (is_in_range (k, ke, HIT_RANGE - 10)
      && is_safe_to_walkb (k)
      && ! k->refraction
      && ! is_walkingb (ke)
      && prandom (99) <= k->skill.return_prob) {
    fight_walkb (k);
    return;
  }
}
コード例 #15
0
ファイル: kid-normal.c プロジェクト: oitofelix/mininim
static bool
flow (struct anim *k)
{
  struct pos pbf, pmt;
  survey (_bf, pos, &k->f, NULL, &pbf, NULL);

  k->collision = false;
  k->hit_by_loose_floor = false;

  bool turn = ((k->f.dir == RIGHT) && k->key.left)
    || ((k->f.dir == LEFT) && k->key.right);
  bool walk = ((k->f.dir == RIGHT) && k->key.right && k->key.shift)
    || ((k->f.dir == LEFT) && k->key.left && k->key.shift);
  bool run = (((k->f.dir == RIGHT) && k->key.right)
              || ((k->f.dir == LEFT) && k->key.left)) && ! walk;
  bool jump = ((k->f.dir == RIGHT) && k->key.right && k->key.up)
    || ((k->f.dir == LEFT) && k->key.left && k->key.up);
  bool couch = k->key.down;
  bool vjump = k->key.up;
  bool drink = is_potion (&pbf) && k->key.shift;
  bool raise_sword = is_sword (&pbf) && k->key.shift;
  bool take_sword = k->key.enter && k->has_sword;

  survey (_mt, pos, &k->f, NULL, &pmt, NULL);
  bool stairs = k->key.up && ! k->key.left && ! k->key.right
    && fg (&pmt) == LEVEL_DOOR
    && level_door_at_pos (&pmt)->i == 0
    && k == get_anim_by_id (0);

  if (k->oaction == kid_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_normal) {
    if (stairs) {
      k->p = pmt;
      kid_stairs (k);
      return false;
    }

    if (couch) {
      kid_couch (k);
      return false;
    }

    if (jump) {
      kid_jump (k);
      return false;
    }

    if (turn) {
      kid_turn (k);
      return false;
    }

    if (vjump) {
      kid_vjump (k);
      return false;
    }
    if (walk) {
      kid_walk (k);
      return false;
    }

    if (run) {
      if (dist_collision (&k->f, _bf, -4, -4, &k->ci) < 29)
        kid_walk (k);
      else kid_start_run (k);
      return false;
    }

    if (drink) {
      k->item_pos = pbf;
      place_frame (&k->f, &k->f, kid_couch_frameset[0].frame,
                   &k->item_pos, (k->f.dir == LEFT)
                   ? PLACE_WIDTH + 3 : +9, +27);
      kid_couch (k);
      return false;
    }

    if (raise_sword) {
      k->item_pos = pbf;
      kid_couch (k);
      return false;
    }

    if (take_sword) {
      kid_take_sword (k);
      return false;
    }
  }

  k->fo.b = kid_normal_00;
  k->fo.dx = k->fo.dy = +0;

  if (k->f.b == kid_stabilize_frameset[3].frame) k->fo.dx = +2;
  if (k->f.b == kid_walk_frameset[11].frame) k->fo.dx = -1;
  if (k->f.b == kid_jump_frameset[17].frame) k->fo.dx = -2;
  if (k->f.b == kid_couch_frameset[12].frame) k->fo.dx = -2;
  if (k->f.b == kid_vjump_frameset[17].frame) k->fo.dx = +2;
  if (k->f.b == kid_drink_frameset[7].frame) k->fo.dx = +0;
  if (k->f.b == kid_keep_sword_frameset[9].frame) k->fo.dx = +2;

  k->xf.b = NULL;

  return true;
}
コード例 #16
0
ファイル: multi-room.c プロジェクト: NoSuchProcess/mininim
bool
is_kid_visible (void)
{
  struct anim *k = get_anim_by_id (current_kid_id);
  return is_room_visible (k->f.c.room);
}
コード例 #17
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;
}