1 #ifndef OPENMW_MWWORLD_PROJECTILEMANAGER_H 2 #define OPENMW_MWWORLD_PROJECTILEMANAGER_H 3 4 #include <string> 5 6 #include <osg/ref_ptr> 7 #include <osg/PositionAttitudeTransform> 8 9 #include <components/esm/effectlist.hpp> 10 11 #include "../mwbase/soundmanager.hpp" 12 13 #include "ptr.hpp" 14 15 namespace MWPhysics 16 { 17 class PhysicsSystem; 18 } 19 20 namespace Loading 21 { 22 class Listener; 23 } 24 25 namespace osg 26 { 27 class Group; 28 class Quat; 29 } 30 31 namespace Resource 32 { 33 class ResourceSystem; 34 } 35 36 namespace MWRender 37 { 38 class EffectAnimationTime; 39 class RenderingManager; 40 } 41 42 namespace MWWorld 43 { 44 45 class ProjectileManager 46 { 47 public: 48 ProjectileManager (osg::Group* parent, Resource::ResourceSystem* resourceSystem, 49 MWRender::RenderingManager* rendering, MWPhysics::PhysicsSystem* physics); 50 51 /// If caster is an actor, the actor's facing orientation is used. Otherwise fallbackDirection is used. 52 void launchMagicBolt (const std::string &spellId, const MWWorld::Ptr& caster, const osg::Vec3f& fallbackDirection); 53 54 void launchProjectile (MWWorld::Ptr actor, MWWorld::ConstPtr projectile, 55 const osg::Vec3f& pos, const osg::Quat& orient, MWWorld::Ptr bow, float speed, float attackStrength); 56 57 void updateCasters(); 58 59 void update(float dt); 60 61 void processHits(); 62 63 /// Removes all current projectiles. Should be called when switching to a new worldspace. 64 void clear(); 65 66 void write (ESM::ESMWriter& writer, Loading::Listener& progress) const; 67 bool readRecord (ESM::ESMReader& reader, uint32_t type); 68 int countSavedGameRecords() const; 69 70 private: 71 osg::ref_ptr<osg::Group> mParent; 72 Resource::ResourceSystem* mResourceSystem; 73 MWRender::RenderingManager* mRendering; 74 MWPhysics::PhysicsSystem* mPhysics; 75 float mCleanupTimer; 76 77 struct State 78 { 79 osg::ref_ptr<osg::PositionAttitudeTransform> mNode; 80 std::shared_ptr<MWRender::EffectAnimationTime> mEffectAnimationTime; 81 82 int mActorId; 83 int mProjectileId; 84 85 // TODO: this will break when the game is saved and reloaded, since there is currently 86 // no way to write identifiers for non-actors to a savegame. 87 MWWorld::Ptr mCasterHandle; 88 89 MWWorld::Ptr getCaster(); 90 91 // MW-ids of a magic projectile 92 std::vector<std::string> mIdMagic; 93 94 // MW-id of an arrow projectile 95 std::string mIdArrow; 96 97 bool mToDelete; 98 }; 99 100 struct MagicBoltState : public State 101 { 102 std::string mSpellId; 103 104 // Name of item to display as effect source in magic menu (in case we casted an enchantment) 105 std::string mSourceName; 106 107 ESM::EffectList mEffects; 108 109 float mSpeed; 110 111 std::vector<MWBase::Sound*> mSounds; 112 std::set<std::string> mSoundIds; 113 }; 114 115 struct ProjectileState : public State 116 { 117 // RefID of the bow or crossbow the actor was using when this projectile was fired (may be empty) 118 std::string mBowId; 119 120 osg::Vec3f mVelocity; 121 float mAttackStrength; 122 bool mThrown; 123 }; 124 125 std::vector<MagicBoltState> mMagicBolts; 126 std::vector<ProjectileState> mProjectiles; 127 128 void cleanupProjectile(ProjectileState& state); 129 void cleanupMagicBolt(MagicBoltState& state); 130 void periodicCleanup(float dt); 131 132 void moveProjectiles(float dt); 133 void moveMagicBolts(float dt); 134 135 void createModel (State& state, const std::string& model, const osg::Vec3f& pos, const osg::Quat& orient, 136 bool rotate, bool createLight, osg::Vec4 lightDiffuseColor, std::string texture = ""); 137 void update (State& state, float duration); 138 139 void operator=(const ProjectileManager&); 140 ProjectileManager(const ProjectileManager&); 141 }; 142 143 } 144 145 #endif 146