void guard_die_properly (struct anim *g) { switch (con (&g->p)->fg) { case SPIKES_FLOOR: guard_die_spiked (g); break; case CHOPPER: guard_die_chopped (g); break; default: guard_die_suddenly (g); break; } }
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; }