void release_loose_floor (struct pos *p) { struct loose_floor *l = loose_floor_at_pos (p); if (l->action != RELEASE_LOOSE_FLOOR && l->action != FALL_LOOSE_FLOOR && ! l->cant_fall) { l->action = RELEASE_LOOSE_FLOOR; l->i = 0; } }
void draw_loose_floor_right (ALLEGRO_BITMAP *bitmap, struct pos *p, enum em em, enum vm vm) { struct loose_floor *l = loose_floor_at_pos (p); if (! l) return; switch (l->state) { case 0: draw_floor_right (bitmap, p, em, vm); break; case 1: draw_loose_floor_00_right (bitmap, p, em, vm); break; case 2: draw_loose_floor_01_right (bitmap, p, em, vm); break; } }
void shake_loose_floor_row (struct pos *p) { struct pos _p = *p; struct loose_floor *l; for (_p.place = PLACES - 1; _p.place >= -1; _p.place--) if (con (&_p)->fg == LOOSE_FLOOR) { l = loose_floor_at_pos (&_p); if (l->action == NO_LOOSE_FLOOR_ACTION) { l->action = SHAKE_LOOSE_FLOOR; l->i = 0; } } }
void draw_loose_floor (ALLEGRO_BITMAP *bitmap, struct pos *p, enum em em, enum vm vm) { struct loose_floor *l = loose_floor_at_pos (p); if (! l) return; if (l->action == FALL_LOOSE_FLOOR) return; else { switch (l->state) { case 0: draw_floor (bitmap, p, em, vm); break; case 1: draw_loose_floor_00 (bitmap, p, em, vm); break; case 2: draw_loose_floor_01 (bitmap, p, em, vm); break; } } }
static bool physics_in (struct anim *k) { struct coord nc; struct pos np, pm; enum confg cm; /* collision */ if (is_colliding (&k->f, &k->fo, +0, false, &k->ci) && k->ci.t != MIRROR) { if (k->i <= 2 && k->fall) uncollide (&k->f, &k->fo, &k->fo, +0, false, &k->ci); else { kid_stabilize_collision (k); return false; } } else if (is_colliding (&k->f, &k->fo, +2, false, &k->ci) && k->ci.t == MIRROR) { if (k->i <= 2) k->f.c.x += (k->f.dir == LEFT) ? +4 : -4; else { kid_stabilize_collision (k); return false; } } if (! k->fall && kid_door_split_collision (k)) return false; /* fall */ cm = survey (_m, pos, &k->f, &nc, &pm, &np)->fg; struct loose_floor *l = loose_floor_at_pos (prel (&pm, &np, -1, +0)); if ((is_strictly_traversable (&pm) || (l && l->action == FALL_LOOSE_FLOOR && cm == LOOSE_FLOOR)) && ! (k->fall && k->i == 0)) { kid_fall (k); return false; } return true; }
void draw_falling_loose_floor (ALLEGRO_BITMAP *bitmap, struct pos *p, enum em em, enum vm vm) { struct loose_floor *l = loose_floor_at_pos (p); if (! l) return; if (l->action == FALL_LOOSE_FLOOR) { struct coord tr, br; struct pos fptr, nfptr, fpbr, nfpbr; frame2room (&l->f, room_view, &l->f.c); survey (_tr, posf, &l->f, &tr, &fptr, &nfptr); survey (_br, posf, &l->f, &br, &fpbr, &nfpbr); l->f.b = get_correct_falling_loose_floor_bitmap (l->f.b); struct frame f = l->f; if (hgc) f.b = apply_palette (f.b, hgc_palette); draw_frame (bitmap, &f); draw_confg_base (bitmap, &fptr, em, vm); draw_confg_left (bitmap, &fptr, em, vm, true); draw_confg_base (bitmap, &fpbr, em, vm); draw_confg_left (bitmap, &fpbr, em, vm, true); } else return; }
void compute_loose_floor_fall (struct loose_floor *l) { int speed = 3 * ++l->i; if (speed > 29) speed = 29; struct frame nf; struct frame_offset fo; fo.b = l->f.b; fo.dx = 0; fo.dy = speed; next_frame (&l->f, &nf, &fo); struct coord mbo_f, mbo_nf; struct pos fpmbo_f, nfpmbo_f, fpmbo_nf, nfpmbo_nf; enum confg fcmbo_f; fcmbo_f = survey (_mbo, posf, &l->f, &mbo_f, &fpmbo_f, &nfpmbo_f)->fg; survey (_mbo, posf, &nf, &mbo_nf, &fpmbo_nf, &nfpmbo_nf); struct pos p; /* hit kid */ int i; for (i = 0; i < anima_nmemb; i++) { struct coord kmt, ambo_f, ambo_nf; struct pos np, kpmt; struct anim *a = &anima[i]; if (is_anim_dead (&a->f) || a->immortal || a->loose_floor_immune) continue; survey (_mt, pos, &a->f, &kmt, &kpmt, &np); coord2room (&mbo_f, kpmt.room, &ambo_f); coord2room (&mbo_nf, kpmt.room, &ambo_nf); if (peq (&nfpmbo_f, &kpmt) && ambo_f.y <= kmt.y && ambo_nf.y >= kmt.y && ! a->hit_by_loose_floor && ! is_kid_hang_or_climb (&a->f) && ! is_kid_fall (&a->f)) { a->hit_by_loose_floor = true; a->splash = true; a->current_lives--; a->uncouch_slowly = true; /* ensure kid doesn't couch in thin air (might occur when hit while jumping, for example) */ place_on_the_ground (&a->f, &a->f.c); play_sample (hit_wall_sample, kpmt.room); alert_guards (&kpmt); if (a->id == current_kid_id) { video_effect.color = get_flicker_blood_color (); start_video_effect (VIDEO_FLICKERING, SECS_TO_VCYCLES (0.1)); } if (a->current_lives <= 0) { a->p = kpmt; anim_die_suddenly (a); a->death_reason = LOOSE_FLOOR_DEATH; } else if (a->type == KID) kid_couch (a); } } /* fall */ if (is_strictly_traversable (&fpmbo_f) || peq (&fpmbo_f, &fpmbo_nf)) { /* the floor hit a rigid structure */ if (is_rigid_con (&fpmbo_nf)) prel (&fpmbo_nf, &p, -1, 0); /* the floor continue to fall */ else { l->f = nf; if (is_strictly_traversable (&fpmbo_nf)) l->p = fpmbo_nf; must_sort = true; return; } /* the floor hit the ground */ } else { struct loose_floor *m; p = fpmbo_f; switch (fcmbo_f) { case LOOSE_FLOOR: /* loose floor isn't ground */ m = loose_floor_at_pos (&fpmbo_f); if (m) m->p.room = -1; must_remove = true; l->f = nf; l->f.b = get_correct_falling_loose_floor_bitmap (dv_broken_floor); l->p = fpmbo_f; l->i = 0; con (&fpmbo_f)->fg = NO_FLOOR; must_sort = true; play_sample (broken_floor_sample, p.room); alert_guards (&p); return; case OPENER_FLOOR: break_opener_floor (&fpmbo_f); break; case CLOSER_FLOOR: break_closer_floor (&fpmbo_f); break; case SPIKES_FLOOR: break_spikes_floor (&fpmbo_f); break; case LEVEL_DOOR: break_level_door (&fpmbo_f); break; default: break; } } /* reach here only if the floor hit a rigid structure or the ground */ if (con (&p)->fg != LEVEL_DOOR) con (&p)->fg = BROKEN_FLOOR; shake_loose_floor_row (&p); l->p.room = -1; must_remove = true; must_sort = true; play_sample (broken_floor_sample, p.room); alert_guards (&p); }