/** * @brief Updates the entity. */ void Door::update() { Detector::update(); if (!initialized) { update_dynamic_tiles(); initialized = true; } if (is_closed() && get_opening_method() == OPENING_BY_EXPLOSION && get_equipment().has_ability("detect_weak_walls") && Geometry::get_distance(get_center_point(), get_hero().get_center_point()) < 40 && !is_suspended() && System::now() >= next_hint_sound_date) { Sound::play("cane"); next_hint_sound_date = System::now() + 500; } if (is_changing() && get_sprite().is_animation_finished()) { // Toggle door_open when the changing animation finishes. set_open(is_opening()); } if (is_saved() && !is_changing()) { bool open_in_savegame = get_savegame().get_boolean(savegame_variable); if (open_in_savegame && is_closed()) { set_opening(); } else if (!open_in_savegame && is_open()) { set_closing(); } } }
/** * @brief Starts opening the door and plays the corresponding animations. * * Nothing is done if the door is already in the process of being open. */ void Door::open() { if (is_open() || is_opening()) { // The door is already open or being open: nothing to do. return; } set_opening(); if (is_saved()) { get_savegame().set_boolean(savegame_variable, true); } }
/** * @brief Enables or disables the dynamic tiles related to this door. * * The dynamic tiles impacted by this function are the ones whose prefix is the door's name * followed by "_closed" or "_open", depending on the door state. */ void Door::update_dynamic_tiles() { std::list<MapEntity*> tiles = get_entities().get_entities_with_prefix(DYNAMIC_TILE, get_name() + "_closed"); std::list<MapEntity*>::iterator it; for (it = tiles.begin(); it != tiles.end(); it++) { DynamicTile* tile = static_cast<DynamicTile*>(*it); tile->set_enabled(is_closed() || is_opening()); } tiles = get_entities().get_entities_with_prefix(DYNAMIC_TILE, get_name() + "_open"); for (it = tiles.begin(); it != tiles.end(); it++) { DynamicTile* tile = static_cast<DynamicTile*>(*it); tile->set_enabled(is_open() || is_closing()); } }
/* https://stackoverflow.com/a/2718114/6049386 , MIT, Feb 2018 */ static const char *match(const char *str) { if (*str == '\0' || is_closing(*str)) return str; if (is_opening(*str)) { const char *closer = match(str + 1); if (is_matching(*str, *closer)) return match(closer + 1); return str; } return match(++str); }