/** * \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 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 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(); } } } } }
/** * \brief Notifies this entity that another sprite is overlapping it. * * This function is called by check_collision(MapEntity*, Sprite*) when another entity's * sprite overlaps a sprite of this detector. * * \param other_entity the entity overlapping this detector * \param other_sprite the sprite of other_entity that is overlapping this detector * \param this_sprite the sprite of this detector that is overlapping the other entity's sprite */ void Pickable::notify_collision(MapEntity& other_entity, Sprite& other_sprite, Sprite& this_sprite) { // taking the item with the sword if (other_entity.is_hero() && other_sprite.contains("sword")) { try_give_item_to_player(); } }
/** * \copydoc Detector::notify_collision(MapEntity&, Sprite&, Sprite&) */ void Pickable::notify_collision( MapEntity& other_entity, Sprite& /* this_sprite */, Sprite& other_sprite ) { // taking the item with the sword if (other_entity.is_hero()) { Hero& hero = static_cast<Hero&>(other_entity); if (other_sprite.get_animation_set_id() == hero.get_hero_sprites().get_sword_sprite_id()) { try_give_item_to_player(); } } }