From 28b086fdc400433c80c3fdb8ca90ece14146b631 Mon Sep 17 00:00:00 2001 From: Felix Ableitner Date: Sun, 18 Aug 2013 13:13:49 +0200 Subject: [PATCH] Changed World::getNearestItem to getNearbySprites for better reusability. --- source/World.cpp | 23 +++++++--------- source/World.h | 3 ++- source/abstract/Character.cpp | 49 +++++++++++++++++++++-------------- source/abstract/Character.h | 2 +- 4 files changed, 42 insertions(+), 35 deletions(-) diff --git a/source/World.cpp b/source/World.cpp index f4b5150..b1e93ef 100755 --- a/source/World.cpp +++ b/source/World.cpp @@ -193,19 +193,14 @@ World::raycast(const Vector2f& lineStart, } /** - * Returns the item closest to position after linear search. + * Returns all sprites that are at most distance pixels away from position. */ -std::shared_ptr -World::getNearestItem(const Vector2f& position) const { - std::shared_ptr closest; - float distance = std::numeric_limits::max(); - for (const auto& v : mDrawables) { - for (const auto& d : v.second) { - std::shared_ptr converted = std::dynamic_pointer_cast(d); - if (converted.get() != nullptr && - thor::squaredLength(converted->getPosition() - position) < distance) - closest = converted; - } - } - return closest; +std::vector > +World::getNearbySprites(const Vector2f& position, float distance) const { + std::vector > ret; + for (const auto& v : mDrawables) + for (const auto& d : v.second) + if (thor::squaredLength(d->getPosition() - position) <= distance * distance) + ret.push_back(d); + return ret; } diff --git a/source/World.h b/source/World.h index 2587239..e39c148 100755 --- a/source/World.h +++ b/source/World.h @@ -31,7 +31,8 @@ public: getCharacters(const Vector2f& position, float maxDistance) const; bool raycast(const Vector2f& lineStart, const Vector2f& lineEnd) const; - std::shared_ptr getNearestItem(const Vector2f& position) const; + std::vector > getNearbySprites( + const Vector2f& position, float radius) const; private: diff --git a/source/abstract/Character.cpp b/source/abstract/Character.cpp index 3017b9b..f027e9e 100644 --- a/source/abstract/Character.cpp +++ b/source/abstract/Character.cpp @@ -18,7 +18,7 @@ const float Character::VISION_DISTANCE = 500.0f; const float Character::POINT_REACHED_DISTANCE = 1.0f; -const float Character::ITEM_PICKUP_MAX_DISTANCE_SQUARED = 2500.0f; +const float Character::ITEM_PICKUP_MAX_DISTANCE = 50.0f; /** * Saves pointer to this instance in static var for think(). @@ -267,26 +267,37 @@ Character::getRightGadgetName() const { */ void Character::pickUpItem() { - std::shared_ptr item = mWorld.getNearestItem(getPosition()); - if (item != nullptr && thor::squaredLength(item->getPosition() - getPosition()) <= - ITEM_PICKUP_MAX_DISTANCE_SQUARED) { - std::shared_ptr weapon = std::dynamic_pointer_cast(item); - if (weapon != nullptr) { - mWorld.insert(mActiveWeapon); - mActiveWeapon->drop(getPosition()); - mActiveWeapon = weapon; - mActiveWeapon->setHolder(*this); + auto sprites = mWorld.getNearbySprites(getPosition(), + ITEM_PICKUP_MAX_DISTANCE); + float distance = std::numeric_limits::max(); + std::shared_ptr closest; + for (auto& s : sprites) { + std::shared_ptr converted = std::dynamic_pointer_cast(s); + if (converted.get() != nullptr && + thor::squaredLength(getPosition() - converted->getPosition()) < distance) { + closest = converted; + distance = thor::squaredLength(getPosition() - converted->getPosition()); } - std::shared_ptr gadget = std::dynamic_pointer_cast(item); - if (gadget != nullptr) { - mWorld.insert(mRightGadget); - mRightGadget->drop(getPosition()); - mRightGadget = mLeftGadget; - mLeftGadget = gadget; - } - mWorld.remove(item); } - else { + + if (closest == nullptr) { std::swap(mLeftGadget, mRightGadget); + return; } + + std::shared_ptr weapon = std::dynamic_pointer_cast(closest); + if (weapon != nullptr) { + mWorld.insert(mActiveWeapon); + mActiveWeapon->drop(getPosition()); + mActiveWeapon = weapon; + mActiveWeapon->setHolder(*this); + } + std::shared_ptr gadget = std::dynamic_pointer_cast(closest); + if (gadget != nullptr) { + mWorld.insert(mRightGadget); + mRightGadget->drop(getPosition()); + mRightGadget = mLeftGadget; + mLeftGadget = gadget; + } + mWorld.remove(closest); } diff --git a/source/abstract/Character.h b/source/abstract/Character.h index b3cc7be..3ffa635 100644 --- a/source/abstract/Character.h +++ b/source/abstract/Character.h @@ -77,7 +77,7 @@ private: /// avoid floating point equality check). static const float POINT_REACHED_DISTANCE; /// Maximum distance from character where an item can be picked up. - static const float ITEM_PICKUP_MAX_DISTANCE_SQUARED; + static const float ITEM_PICKUP_MAX_DISTANCE; friend class World; World& mWorld; Pathfinder& mPathfinder;