/*---------------------------------------------------------------------------- * Check state for all dynamic circuits. These may activate and deactivate * moving blocks. *----------------------------------------------------------------------------*/ void update_dynamic_circuit(struct dynamic_circuit *d) { if (calculate(d->tree, 0)) { switch (d->obj->type) { case MOVING_0: if (object_try_move(d->obj, DIR_DN)) { MAP[idx_dn(d->obj->idx)] = MOVING_1; d->obj->type = MOVING_1; if (media.enable_audio) Mix_PlayChannel(CHANNEL_OPEN, media.chunk_open, 0); } break; } } else { switch (d->obj->type) { case MOVING_1: if (levitate(d->obj)) { MAP[idx_up(d->obj->idx)] = MOVING_0; d->obj->type = MOVING_0; if (media.enable_audio) Mix_PlayChannel(CHANNEL_OPEN, media.chunk_open, 0); } break; } } }
/*---------------------------------------------------------------------------- * Move an object up, pushing every other object on its way if possible. *----------------------------------------------------------------------------*/ int levitate(struct object *o) { struct object *tmp; if (idx_y(o->idx) == MAX) return 0; if ((tmp = OBJ[idx_up(o->idx)]) && tmp->dir == STILL) { if (levitate(tmp)) { object_move(o, DIR_UP); return DIR_UP; } return STILL; } return object_try_move(o, DIR_UP); }
/*---------------------------------------------------------------------------- * Heavy objects are subject to forces. Depending on the value of the space in * the forces map, they can go either up, down or nowhere, but if they ought to * go up and are unable to do so or the space has no force they might be * affected by a conveyor belt. For these checks we must iterate on the object * map because order matters: objects in higher layers have priority. *----------------------------------------------------------------------------*/ void update_heavy_object(struct object *o) { if (o->dir != STILL) return; switch (FRC[o->idx]) { case DIR_DN: if (idx_y(o->idx) > MIN && object_try_move(o, DIR_DN)) return; break; case DIR_UP: if (levitate(o)) return; break; } switch (MAP[idx_dn(o->idx)]) { case BELT_LF_1: if (idx_x(o->idx) > MIN) object_try_move(o, DIR_LF); break; case BELT_RT_1: if (idx_x(o->idx) < MAX) object_try_move(o, DIR_RT); break; case BELT_BK_1: if (idx_z(o->idx) > MIN) object_try_move(o, DIR_BK); break; case BELT_FT_1: if (idx_z(o->idx) < MAX) object_try_move(o, DIR_FT); break; } }
void s_levitate(void) { levitate(0); }
void i_levitate(pob o) { if (o->known < 1) o->known = 1; Objects[o->id].known = 1; levitate(o->blessing); }