/** * \brief This function is called by the engine when an entity overlaps the pickable item. * * If the entity is the player, we give him the item, and the map is notified * to destroy it. * \param entity_overlapping the entity overlapping the detector * \param collision_mode the collision mode that detected the collision */ void Pickable::notify_collision(MapEntity& entity_overlapping, CollisionMode collision_mode) { if (entity_overlapping.is_hero()) { try_give_item_to_player(); } else if (entity_followed == NULL) { if (entity_overlapping.get_type() == ENTITY_BOOMERANG) { Boomerang& boomerang = static_cast<Boomerang&>(entity_overlapping); if (!boomerang.is_going_back()) { boomerang.go_back(); } entity_followed = &boomerang; } else if (entity_overlapping.get_type() == ENTITY_HOOKSHOT) { Hookshot& hookshot = static_cast<Hookshot&>(entity_overlapping); if (!hookshot.is_going_back()) { hookshot.go_back(); } entity_followed = &hookshot; } if (entity_followed != NULL) { clear_movement(); set_movement(new FollowMovement(entity_followed, 0, 0, true)); falling_height = FALLING_NONE; set_blinking(false); } } }
/** * \brief This function is called by the engine when an entity overlaps the pickable item. * * If the entity is the player, we give him the item, and the map is notified * to destroy it. * \param entity_overlapping the entity overlapping the detector * \param collision_mode the collision mode that detected the collision */ void Pickable::notify_collision(MapEntity& entity_overlapping, CollisionMode /* collision_mode */) { if (entity_overlapping.is_hero()) { try_give_item_to_player(); } else if (entity_followed == nullptr) { MapEntityPtr shared_entity_overlapping = std::static_pointer_cast<MapEntity>(entity_overlapping.shared_from_this()); if (entity_overlapping.get_type() == ENTITY_BOOMERANG) { Boomerang& boomerang = static_cast<Boomerang&>(entity_overlapping); if (!boomerang.is_going_back()) { boomerang.go_back(); } entity_followed = shared_entity_overlapping; } else if (entity_overlapping.get_type() == ENTITY_HOOKSHOT) { Hookshot& hookshot = static_cast<Hookshot&>(entity_overlapping); if (!hookshot.is_going_back()) { hookshot.go_back(); } entity_followed = shared_entity_overlapping; } if (entity_followed != nullptr) { clear_movement(); set_movement(std::make_shared<FollowMovement>( entity_followed, 0, 0, true )); falling_height = FALLING_NONE; set_blinking(false); } } }
/** * \brief Updates the pickable item. * * This function is called repeatedly by the map. * This is a redefinition of Entity::update() to make * the item blink and then disappear after an amount of time. */ void Pickable::update() { // update the animations and the movement Detector::update(); // update the shadow if (shadow_sprite != nullptr) { shadow_sprite->update(); } shadow_xy.x = get_x(); if (!is_falling()) { shadow_xy.y = get_y(); } if (entity_followed != nullptr && entity_followed->is_being_removed()) { if (entity_followed->get_type() == EntityType::BOOMERANG || entity_followed->get_type() == EntityType::HOOKSHOT) { // The pickable may have been dropped by the boomerang/hookshot // not exactly on the hero so let's fix this. if (get_distance(get_hero()) < 16) { try_give_item_to_player(); } } entity_followed = nullptr; } check_bad_ground(); if (!is_suspended()) { // check the timer uint32_t now = System::now(); // wait 0.7 second before allowing the hero to take the item if (!can_be_picked && now >= allow_pick_date) { can_be_picked = true; falling_height = FALLING_NONE; get_hero().check_collision_with_detectors(); } else { // make the item blink and then disappear if (will_disappear) { if (now >= blink_date && !get_sprite().is_blinking() && entity_followed == nullptr) { set_blinking(true); } if (now >= disappear_date) { remove_from_map(); } } } } }