void register_spikes_floor (struct pos *p) { assert (con (p)->fg == SPIKES_FLOOR && spikes_floor_at_pos (p) == NULL); struct spikes_floor s; s.p = *p; s.wait = SPIKES_WAIT; s.murdered_anim = -1; s.activate = false; switch (con (p)->ext.step) { case 0: s.i = 0; s.state = 0; break; case 1: s.i = 1; s.state = 1; break; case 2: s.i = 2; s.state = 2; break; case 3: s.i = 3; s.state = 3; break; case 4: s.i = 4; s.state = 4; break; case 5: s.i = 4; s.state = 5; break; case 6: s.i = 5; s.state = 3; break; case 7: s.i = 6; s.state = 2; break; case 8: s.i = 0; s.state = 1; break; case 9: s.i = 0; s.state = 0; break; } s.inactive = (con (p)->ext.step != 0); spikes_floor = add_to_array (&s, 1, spikes_floor, &spikes_floor_nmemb, spikes_floor_nmemb, sizeof (s)); sort_spikes_floors (); }
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 draw_spikes_floor_right (ALLEGRO_BITMAP *bitmap, struct pos *p, enum em em, enum vm vm) { struct spikes_floor *s = spikes_floor_at_pos (p); if (! s) return; draw_spikes_floor_floor_right (bitmap, p, em, vm); draw_spikes_right (bitmap, p, s, em, vm); }
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 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; }
void draw_spikes_fg (ALLEGRO_BITMAP *bitmap, struct pos *p, enum em em, enum vm vm) { struct spikes_floor *s = spikes_floor_at_pos (p); if (! s) return; switch (s->state) { case 0: break; case 1: draw_spikes_fg_00 (bitmap, p, em, vm); break; case 2: draw_spikes_fg_01 (bitmap, p, em, vm); break; case 3: draw_spikes_fg_02 (bitmap, p, em, vm); break; case 4: draw_spikes_fg_03 (bitmap, p, em, vm); break; case 5: draw_spikes_fg_04 (bitmap, p, em, vm); break; } }
void guard_resurrect (struct anim *g) { g->splash = false; g->invisible = false; if (g->current_lives > 0) return; struct pos pm; survey (_m, pos, &g->f, NULL, &pm, NULL); g->current_lives = g->total_lives; g->death_reason = NO_DEATH; g->action = guard_normal; g->glory_sample = false; place_frame (&g->f, &g->f, get_guard_normal_bitmap (g->type), &pm, g->f.dir == LEFT ? +16 : +22, +14); place_on_the_ground (&g->f, &g->f.c); if (fg (&g->p) == SPIKES_FLOOR) spikes_floor_at_pos (&g->p)->inactive = false; }
static bool physics_in (struct anim *g) { struct coord nc; struct pos np, pbf, pmt, pmtf, pmtb, npmbo, npmbo_nf; struct frame nf; struct frame_offset fo; if (g->i == 0) { next_frame (&g->f, &g->f, &g->fo); int dirf = (g->f.dir == LEFT) ? -1 : +1; int dirb = (g->f.dir == LEFT) ? +1 : -1; survey (_mt, pos, &g->f, &nc, &pmt, &np); prel (&pmt, &pmtf, +0, dirf); prel (&pmt, &pmtb, +0, dirb); if (! is_strictly_traversable (&pmt) || ! is_strictly_traversable (&pmtf) || ! is_strictly_traversable (&pmtb)) place_in_initial_fall (g); } /* fall speed */ if (g->i > 0) g->fo.dx = -g->inertia; if (g->i > 4) { int speed = +21 + 3 * (g->i - 5); g->fo.dy = (speed > 33) ? 33 : speed; } /* land on ground */ struct frameset *frameset = get_guard_fall_frameset (g->type); fo.b = frameset[g->i > 2 ? 2 : g->i].frame; fo.dx = frameset[g->i > 2 ? 2 : g->i].dx; fo.dy = frameset[g->i > 2 ? 2 : g->i].dy; if (g->i > 0) g->fo.dx = -g->inertia; if (g->i > 2) { int speed = +21 + 3 * (g->i - 5); fo.dy = (speed > 33) ? 33 : speed; } fo.dy += 8; survey (_mbo, pos, &g->f, &nc, &np, &npmbo); next_frame (&g->f, &nf, &fo); survey (_mbo, pos, &nf, &nc, &np, &npmbo_nf); if (g->i > 2 && ! is_strictly_traversable (&npmbo) && npmbo.floor != npmbo_nf.floor) { g->inertia = g->cinertia = 0; if (is_colliding (&g->f, &g->fo, +16, false, &g->ci)) { if (g->ci.t != WALL) g->f.c.x += (g->f.dir == LEFT) ? +16 : -16; else g->f.c.x += (g->f.dir == LEFT) ? +8 : -8; } survey (_bf, pos, &g->f, &nc, &pbf, &np); /* pos2view (&pbf, &pbf); */ frameset = get_guard_vigilant_frameset (g->type); g->f.b = frameset[0].frame; place_on_the_ground (&g->f, &g->f.c); shake_loose_floor_row (&pbf); if (g->i >= 8 && ! g->immortal && ! g->fall_immune) { g->hurt = true; g->splash = true; g->current_lives--; if (g->i >= 10) g->current_lives = 0; if (g->current_lives > 0) g->uncouch_slowly = true; } else if (g->i > 3) { play_sample (hit_ground_sample, g->f.c.room); g->hurt = false; } else g->hurt = false; stop_sample (g->sample, scream_sample); survey (_mt, pos, &g->f, &nc, &pmt, &np); g->p = pmt; if (con (&pmt)->fg == SPIKES_FLOOR && ! spikes_floor_at_pos (&pmt)->inactive) guard_die_spiked (g); else if (g->current_lives <= 0) { play_sample (hit_ground_fatal_sample, g->f.c.room); guard_die_suddenly (g); g->death_reason = FALL_DEATH; } else { place_on_the_ground (&g->f, &g->f.c); g->f.c.y++; guard_vigilant (g); } return false; } return true; }