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); }
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; }
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); }
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; }
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); } }
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; }
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); }
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; }
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); */ }
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; }
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; }
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; } }
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); */ }
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; } }
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; }
bool is_kid_visible (void) { struct anim *k = get_anim_by_id (current_kid_id); return is_room_visible (k->f.c.room); }
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; }