/** * \brief Returns whether this enemy is in a normal state. * * The enemy is considered to be in its normal state if * it is not disabled, dying, being hurt or immobilized. * When this method returns false, the subclasses of Enemy * should not change the enemy properties. * * \return true if this enemy is in a normal state */ bool Enemy::is_in_normal_state() const { return is_enabled() && !is_being_hurt() && get_life() > 0 && !is_immobilized() && !is_being_removed(); }
/** * @brief This function is called when the movement of the entity is finished. */ void CustomEnemy::notify_movement_finished() { Enemy::notify_movement_finished(); if (!is_being_hurt()) { script->event_movement_finished(*get_movement()); } }
/** * @brief This function is called when the layer of this entity has just changed. * * Redefine it if you need to be notified. */ void CustomEnemy::notify_layer_changed() { Enemy::notify_layer_changed(); if (!is_being_hurt()) { script->event_layer_changed(get_layer()); } }
/** * @brief This function is called when the entity has just moved. */ void CustomEnemy::notify_position_changed() { Enemy::notify_position_changed(); if (!is_being_hurt()) { script->event_position_changed(get_xy()); } }
/** * @brief Notifies this entity that it has just failed to change its position * because of obstacles. */ void CustomEnemy::notify_obstacle_reached() { Enemy::notify_obstacle_reached(); if (!is_being_hurt()) { script->event_obstacle_reached(); } }
/** * \brief Returns whether lava is currently considered as obstacle by this entity. * \return true if lava is currently obstacle for this entity */ bool Enemy::is_lava_obstacle() const { if (obstacle_behavior == OBSTACLE_BEHAVIOR_FLYING) { return false; } if (is_being_hurt()) { return false; } const Layer layer = get_layer(); const int x = get_top_left_x(); const int y = get_top_left_y(); if (get_map().get_ground(layer, x, y) == GROUND_LAVA || get_map().get_ground(layer, x + get_width() - 1, y) == GROUND_LAVA || get_map().get_ground(layer, x, y + get_height() - 1) == GROUND_LAVA || get_map().get_ground(layer, x + get_width() - 1, y + get_height() - 1) == GROUND_LAVA) { return false; } return true; }
/** * \brief Updates the enemy. */ void Enemy::update() { MapEntity::update(); if (is_suspended() || !is_enabled()) { return; } uint32_t now = System::now(); if (being_hurt) { // see if we should stop the animation "hurt" if (now >= stop_hurt_date) { being_hurt = false; set_movement_events_enabled(true); if (life <= 0) { kill(); } else if (is_immobilized()) { clear_movement(); set_animation("immobilized"); notify_immobilized(); } else { clear_movement(); restart(); } } } if (life > 0 && invulnerable && now >= vulnerable_again_date && !being_hurt) { invulnerable = false; } if (life > 0 && !can_attack && !is_immobilized() && can_attack_again_date != 0 && now >= can_attack_again_date) { can_attack = true; } if (is_immobilized() && !is_killed() && now >= end_shaking_date && get_sprite().get_current_animation() == "shaking") { restart(); } if (is_immobilized() && !is_killed() && !is_being_hurt() && now >= start_shaking_date && get_sprite().get_current_animation() != "shaking") { end_shaking_date = now + 2000; set_animation("shaking"); } if (exploding) { uint32_t now = System::now(); if (now >= next_explosion_date) { // create an explosion Rectangle xy; xy.set_x(get_top_left_x() + Random::get_number(get_width())); xy.set_y(get_top_left_y() + Random::get_number(get_height())); get_entities().add_entity(new Explosion("", LAYER_HIGH, xy, false)); Sound::play("explosion"); next_explosion_date = now + 200; nb_explosions++; if (nb_explosions >= 15) { exploding = false; } } } if (is_killed() && is_dying_animation_finished()) { // Create the pickable treasure if any. get_entities().add_entity(Pickable::create(get_game(), "", get_layer(), get_x(), get_y(), treasure, FALLING_HIGH, false)); // Remove the enemy. remove_from_map(); // Notify Lua that this enemy is dead. // We need to do this after remove_from_map() so that this enemy is // considered dead in functions like map:has_entities(prefix). notify_dead(); } get_lua_context().enemy_on_update(*this); }