SFML community forums

Help => General => Topic started by: KagonKhan on September 08, 2021, 05:41:21 am

Title: Game Design / Programming Design help
Post by: KagonKhan on September 08, 2021, 05:41:21 am
TL;DR
Is there a way to concatenate vectors of unique pointers, without breaking any Geneva Conventions:
class Weapon{
   std::vector<std::unique_ptr<Ammo>> m_Ammo;
}
class Ship{
   std::vector<std::unique_ptr<Weapon>> m_Weapons;
}
class Game{
   std::vector<std::unique_ptr<Ship>> m_Ships
}
// i want to have access to every Ammo object from class Game
 


I've found myself in a pickle. I'm writing a game and my issue is with bullet collisions. The way I designed weapon system got me stuck.


*Problem*
My idea was to gather all of the bullets in some container in actual game class, but I'm having difficulties with smart pointers (A weapon would return it's vector of bullets into a ship, then ship would concatenate and return into gamestate class).
std::vector<std::unique_ptr<Ammunition>>& Weapon::getShots()
{
        return m_Shots;
}

// m_Shots is a private variable
std::vector<std::unique_ptr<Ammunition>>& Ship::getShots() //-> ErrorC2783
{
        for (auto&& weapon : m_Weapons)
                m_Shots.insert(m_Shots.end(), weapon->getShots().begin(), weapon->getShots().end());

        return m_Shots;
}
/* ErrorC2783
Error   C2783   '_Ty *std::construct_at(_Ty *const ,_Types &&...) noexcept(<expr>)': could not deduce template argument for '<unnamed-symbol>'*/


 

How should I go about that merge, so as to not brick everything.
And if that is not feasible, what would you suggest?

I've thought of
 - Weapon has world reference and creates bullets directly in there
 - SFML game dev book mentioned scene graphs, maybe I could follow that design pattern, although preferably as a last
   resort

Title: Re: Game Design / Programming Design help
Post by: KagonKhan on September 08, 2021, 06:25:32 am
UPDATE
Got a version working, but since I'm inexperienced with smart pointers I'd appreciate input on my new-found solution.

std::vector<Ammunition*>& Weapon::getShots() {
   ghostPTR.clear();
   for (auto&& ammo : m_Shots)
      ghostPTR.push_back(ammo.get());

   return ghostPTR;
}
std::vector<Ammunition*>& Ship::getShots() {
   ghostPTR.clear();
   for (auto&& weapon : m_Weapons)
      for (auto&& ammo : weapon->getShots())
          ghostPTR.push_back(ammo);

   return ghostPTR;
}
// And lastly the game class
void Level::update(const sf::Time& deltaTime) {
   std::vector<Ammunition*> ammunition;
   for (auto&& entity : m_Entities)
       if (Ship* ptr = dynamic_cast<Ship*>(entity.get()); ptr)
           ammunition.insert(ammunition.begin(), ptr->getShots().begin(),ptr->getShots().end());

}