void register_changed_room (int room) { if (has_room_changed (room)) return; changed_room = add_to_array (&room, 1, changed_room, &changed_room_nmemb, changed_room_nmemb, sizeof (room)); qsort (changed_room, changed_room_nmemb, sizeof (room), (m_comparison_fn_t) cint); struct pos p; new_pos (&p, &global_level, room, -1, -1); p.floor = 0; for (p.place = 0; p.place < PLACES; p.place++) register_changed_pos (&p, -1); p.place = 0; for (p.floor = 1; p.floor < FLOORS; p.floor++) register_changed_pos (&p, -1); p.place = 9; for (p.floor = 1; p.floor < FLOORS; p.floor++) register_changed_pos (&p, -1); }
void register_changed_opener_floors (void) { size_t i; for (i = 0; i < opener_floor_nmemb; i++) { struct opener_floor *o = &opener_floor[i]; if (o->prev_pressed != o->pressed) register_changed_pos (&o->p); } }
void register_changed_closer_floors (void) { size_t i; for (i = 0; i < closer_floor_nmemb; i++) if (closer_floor[i].prev_pressed != closer_floor[i].pressed) register_changed_pos (&closer_floor[i].p, CHPOS_UNPRESS_CLOSER_FLOOR); }
void press_closer_floor (struct pos *p) { struct closer_floor *c = closer_floor_at_pos (p); if (! c) return; if (c->broken) return; c->pressed = true; if (! c->prev_pressed) { register_changed_pos (p, CHPOS_PRESS_CLOSER_FLOOR); c->prev_pressed = true; } }
void press_opener_floor (struct pos *p) { struct opener_floor *o = opener_floor_at_pos (p); if (! o) return; if (o->broken) return; o->pressed = true; if (! o->prev_pressed) { register_changed_pos (&o->p); o->prev_pressed = true; o->priority = anim_cycle; } }
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 compute_doors (void) { size_t i; for (i = 0; i < door_nmemb; i++) { struct door *d = &door[i]; switch (d->action) { case OPEN_DOOR: if (d->i == 0 && d->wait == 0) d->action = CLOSE_DOOR; else if (d->i == 0 && d->wait > 0) { if (! d->noise) { play_sample (door_end_sample, &d->p, -1); d->noise = true; } d->wait--; } else if (d->i > 0) { if (d->i % 2 == 0) { if (d->i == DOOR_MAX_STEP - 1) alert_guards (&d->p); play_sample (door_open_sample, &d->p, -1); } d->i--; d->wait = DOOR_WAIT; register_changed_pos (&d->p, CHPOS_OPEN_DOOR); } break; case CLOSE_DOOR: if (d->i < DOOR_MAX_STEP) { if (d->wait++ % 4 == 0) { if (d->i == 0) alert_guards (&d->p); play_sample (door_close_sample, &d->p, -1); d->i++; d->noise = false; register_changed_pos (&d->p, CHPOS_CLOSE_DOOR); } } else if (d->i == DOOR_MAX_STEP) { play_sample (door_end_sample, &d->p, -1); d->action = NO_DOOR_ACTION; d->wait = DOOR_WAIT; d->noise = false; } break; case ABRUPTLY_CLOSE_DOOR: if (d->i < DOOR_MAX_STEP) { int r = 11 - (d->i % 12); d->i += r ? r : 12; register_changed_pos (&d->p, CHPOS_ABRUPTLY_CLOSE_DOOR); if (d->i >= DOOR_MAX_STEP) { d->i = DOOR_MAX_STEP; alert_guards (&d->p); play_sample (door_abruptly_close_sample, &d->p, -1); } } else { d->action = NO_DOOR_ACTION; d->wait = DOOR_WAIT; d->noise = false; } break; default: break; } } }
void compute_spikes_floors (void) { size_t i, j; struct pos pm; for (i = 0; i < spikes_floor_nmemb; i++) { struct spikes_floor *s = &spikes_floor[i]; if (s->inactive) continue; int state = s->state; switch (s->i) { case 0: if (should_spikes_raise (&s->p) || s->activate) { alert_guards (&s->p); play_sample (spikes_sample, &s->p, -1); s->i++; s->wait = 12; s->state = 1; } else if (s->state != 0) s->state = 0; break; case 1: s->i++; s->state = 2; break; case 2: s->i++; s->state = 3; break; case 3: s->i++; s->state = 4; break; case 4: if (! should_spikes_raise (&s->p)) { if (s->wait-- == 0) { s->i++; s->state = 3; } else s->state = 5; } else { s->state = 5; } break; case 5: s->i++; s->state = 2; break; case 6: s->i = 0; s->state = 1; s->activate = false; break; } if (state != s->state) register_changed_pos (&s->p, CHPOS_SPIKES); /* spike kid */ for (j = 0; j < anima_nmemb; j++) { struct anim *a = &anima[j]; if (is_kid_dead (&a->f) || a->immortal || a->spikes_immune) continue; survey (_m, pos, &a->f, NULL, &pm, NULL); if (peq (&pm, &s->p) && (((s->state >= 2 && s->state <= 4) && (is_kid_start_run (&a->f) || is_kid_run (&a->f) || is_kid_run_jump_running (&a->f))) || (is_kid_couch (&a->f) && a->fall && a->i < 3 && ! a->float_timer) || (is_kid_jump_landing (&a->f) && a->i <= 13) || is_kid_run_jump_landing (&a->f))) { a->p = s->p; anim_die_spiked (a); } } } }
void compute_choppers (void) { size_t i, j; for (i = 0; i < chopper_nmemb; i++) { struct chopper *c = &chopper[i]; if (c->inactive) continue; switch (c->i) { case 0: if (! c->alert) c->alert = ! should_chomp (&c->p); if ((c->wait-- <= 0 && should_chomp (&c->p) && (anim_cycle % CHOPPER_WAIT) == prandom_pos (&c->p, CHOPPER_WAIT - 1)) || c->activate) { c->i++; register_changed_pos (&c->p, CHPOS_CHOPPER); } break; case 1: c->i++; if (c->alert) { alert_guards (&c->p); c->alert = false; } play_sample (chopper_sample, &c->p, -1); register_changed_pos (&c->p, CHPOS_CHOPPER); break; case 2: c->i++; register_changed_pos (&c->p, CHPOS_CHOPPER); break; case 3: c->i++; register_changed_pos (&c->p, CHPOS_CHOPPER); break; case 4: c->i = 0; c->wait = CHOPPER_WAIT; c->activate = false; register_changed_pos (&c->p, CHPOS_CHOPPER); break; } if (c->i != 1 && c->i != 2 ) continue; /* chomp kid */ for (j = 0; j < anima_nmemb; j++) { struct anim *a = &anima[j]; if (a->type == MOUSE || is_anim_fall (&a->f) || a->immortal || a->chopper_immune || (a->action == kid_walk && a->walk != -1)) continue; struct pos pbf, pbb; survey (_bf, pos, &a->f, NULL, &pbf, NULL); survey (_bb, pos, &a->f, NULL, &pbb, NULL); pos2room (&pbf, c->p.room, &pbf); pos2room (&pbb, c->p.room, &pbb); if ((((pbf.room == c->p.room && pbf.floor == c->p.floor) || (pbb.room == c->p.room && pbb.floor == c->p.floor)) && ((a->f.dir == LEFT && pbf.place < c->p.place && pbb.place >= c->p.place) || (a->f.dir == RIGHT && pbf.place >= c->p.place && pbb.place < c->p.place))) && (! is_anim_dead (&a->f) || ! is_anim_chopped (&a->f))) { if (a->type != SKELETON) c->blood = true; a->splash = true; a->p = c->p; a->death_reason = CHOPPER_DEATH; if (a->id == current_kid_id) { mr.flicker = 2; mr.color = get_flicker_blood_color (); } if (a->type == SKELETON) play_sample (skeleton_sample, &c->p, -1); else play_sample (chopped_sample, &c->p, -1); anim_die_chopped (a); } } } }
void draw_multi_rooms (void) { int x, y; mr_set_origin (mr.room, mr.x, mr.y); bool mr_full_update = has_mr_view_changed () || mr.full_update; if (mr_full_update) { mr_busy (); force_full_redraw = true; } if (anim_cycle == 0) { generate_wall_colors_for_room (0, room0_wall_color); } if (em == PALACE && vm == VGA && (mr_full_update || em != mr.last.em || vm != mr.last.vm)) generate_wall_colors (); if (mouse_pos.room != mr.last.mouse_pos.room || mouse_pos.floor != mr.last.mouse_pos.floor || mouse_pos.place != mr.last.mouse_pos.place) { if (is_valid_pos (&mouse_pos)) register_changed_pos (&mouse_pos); if (is_valid_pos (&mr.last.mouse_pos)) register_changed_pos (&mr.last.mouse_pos); } if (anim_cycle == 0 || em != mr.last.em || vm != mr.last.vm || hgc != mr.last.hgc || hue != mr.last.hue) { update_room0_cache (em, vm); force_full_redraw = true; } size_t i; if (anim_cycle == 0 || mr_full_update || em != mr.last.em || vm != mr.last.vm || hgc != mr.last.hgc || hue != mr.last.hue || global_level.n != mr.last.level) { update_cache (em, vm); } else { bool depedv = ((em == DUNGEON && vm == VGA) || (em == DUNGEON && vm == EGA) || (em == PALACE && vm == EGA)); /* optmize changed pos list */ optimize_changed_pos (); /* update cache pos */ for (i = 0; i < changed_pos_nmemb; i++) { update_cache_pos (&changed_pos[i], em, vm); struct pos pl; prel (&changed_pos[i], &pl, +0, -1); if (depedv && fake (&pl) == WALL) update_cache_pos (&pl, em, vm); } /* update cache room */ for (i = 0; i < changed_room_nmemb; i++) update_cache_room (changed_room[i], em, vm); /* kept together so update_cache_pos and update_cache_room can access each other's arrays */ destroy_array ((void **) &changed_pos, &changed_pos_nmemb); destroy_array ((void **) &changed_room, &changed_room_nmemb); } for (y = mr.h - 1; y >= 0; y--) for (x = 0; x < mr.w; x++) { clear_bitmap (mr.cell[x][y].screen, (mr.flicker > 0 && mr.flicker % 2) ? mr.color : BLACK); if (! mr.cell[x][y].room) continue; mr.dx = x; mr.dy = y; draw_animated_background (mr.cell[x][y].screen, mr.cell[x][y].room); } if (mr.flicker > 0) mr.flicker--; struct mr_room_list l; mr_get_room_list (&l); int xm, ym; if (! no_room_drawing) for (i = 0; i < l.nmemb; i++) { mr_coord (l.room[i], -1, &xm, &ym); for (y = mr.h - 1; y >= 0; y--) for (x = 0; x < mr.w; x++) if (mr.cell[x][y].room == l.room[i]) draw_bitmap (mr.cell[xm][ym].cache, mr.cell[x][y].screen, 0, 0, 0); } mr_destroy_room_list (&l); for (y = mr.h - 1; y >= 0; y--) for (x = 0; x < mr.w; x++) { if (! mr.cell[x][y].room) continue; mr.dx = x; mr.dy = y; draw_animated_foreground (mr.cell[x][y].screen, mr.cell[x][y].room); } mr_update_last_settings (); }