1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #ifndef CL_PROJECTILE_MANAGER_H
21 #define CL_PROJECTILE_MANAGER_H
23 #include "nel/misc/vector.h"
24 #include "nel/3d/u_particle_system_instance.h"
25 #include "game_share/magic_fx.h"
26 #include "animation_fx.h"
27 #include "attack_info.h"
28 #include "attached_fx.h"
36 class UParticleSystemInstance
;
44 /** Target of a projectile
46 class CProjectileTarget
49 uint Slot
; // Slot of the target, if invalid, 'TargetPos' is used instead
50 NLMISC::CVector TargetPos
; // position of the impact (if target slot invalid now, or later)
56 /** describes a single projectile
57 * should be use with a call to CProjectileManager::createProjectileSet
59 class CProjectileBuild
62 CAttackInfo AttackInfo
;
63 MAGICFX::TSpellMode Mode
; // mode of the projectile (trajectory's shape depends on it)
64 const CAnimationFXSet
*CastAspect
; // additionnal cast created when projectile is thrown
65 uint CastPower
; // applies to CastAspect only
66 const CAnimationFXSet
*ProjectileAspect
;
67 const CAnimationFXSet
*ImpactAspect
;
68 CFXStickMode ProjectileAimingPoint
; // the point on target that the projectile will try to reach (not necessarily the point where impact fx is played)
70 CProjectileTarget Target
;
73 bool MagicResist
; // did the target resist to magic attack ?
76 bool LetProjectileStickedOnTarget
;
77 CAttachedFX::CTargeterInfo TargeterInfo
;
79 CProjectileBuild() : CastAspect(NULL
),
80 ProjectileAspect(NULL
),
82 ForcePlayImpact(false)
85 // for insertion in map / set
86 inline bool operator < (const CProjectileBuild
&lhs
, const CProjectileBuild
&rhs
)
88 return lhs
.StartDate
< rhs
.StartDate
;
92 /** Class that manage all projectiles.
94 * \author Nicolas Vizerie
95 * \author Nevrax France
98 class CProjectileManager
101 // get the unique instance of this class
102 static CProjectileManager
&getInstance();
104 /** Add a new projectile in the queue. The 'StartDate' field gives its date of creation
106 void addProjectileToQueue(const CProjectileBuild
&pb
);
108 // tells the manager that a slot has become invalid
109 void entityRemoved(uint slot
);
111 // update all projectiles
114 // reset the manager (this delete all projectiles)
117 // eval position of a fx on an entity for a given stick mode
118 static void evalFXPosition(const CFXStickMode
*stickMode
, CEntityCL
&entity
, NLMISC::CVector
&result
, const NLMISC::CVector
&additionnalOffset
= NLMISC::CVector::Null
);
120 // return a set of 4 fx user param values for a projectile depending on its power
121 static const float *getProjectileFXUserParams(uint power
);
123 //////////////////////////////////////////////////////////////////////////////////////////////////
126 * It targets an entity.
127 * When the entity is reached by the projectile, it creates impact on it (or play the resist effect)
128 * (bomb, chain & spray)
133 enum { MaxNumFX
= CAnimationFXSet::MaxNumFX
};
135 CAttackInfo AttackInfo
;
136 // aspect of projectile & impact
137 const CAnimationFXSet
*ProjectileAspect
;
138 const CAnimationFXSet
*ImpactAspect
;
139 CFXStickMode ProjectileAimingPoint
;
140 bool LocalizedImpact
;
141 // instances of fx that represents the projectile
142 NL3D::UParticleSystemInstance FX
[MaxNumFX
];
143 // mode of the projectile (used to compute trajectory)
144 MAGICFX::TSpellMode Mode
;
146 NLMISC::CVector LastEntityOrientation
; // this matrix is updated when the target is a bone
147 NLMISC::CVector ClippedTargetBoneRelativePos
; // relative position of the target bone to the skeleton when it was last clipped
148 bool TargetBoneVisibleLastFrame
; // Was target bone visible during the previous frame ?
149 float TargetBoneRelativePosBlendFactor
; // Blend factor from target bone relative pos (0.f) to clipped target bone relative pos (1.f)
150 // If the target was clipped and is now visible, its bones may not have been updated for long.
151 // So we blend between the clipped pos and the visible pos to avoid a 'jump' in the trajectory of the projectile
153 CProjectileTarget Target
;
154 sint TargetBoneID
; // cache target bone id (if impact point is sticked to a bone of the target)
156 float ParabolaHeight
; // height of parabola for bomb missiles
160 bool MagicResist
; // did the target resist ? if so gives the power for resist (0-> no resist)
161 bool PlayImpactAnim
; // impact anim is not necessary for curative spells
162 bool ForcePlayImpact
;
163 bool LetProjectileStickedOnTarget
;
165 CAttachedFX::CTargeterInfo TargeterInfo
;
172 // get the target bone (impact point must be sticked to a bone of the target), or NULL if not found
173 sint
getImpactBoneID(CEntityCL
&target
);
174 // update position of the target
175 void updateTargetPos();
176 // set position of all fx in the projectile
177 void setMatrix(const NLMISC::CMatrix
&mat
);
178 /** Shutdown all fxs and add them to the fx manager if entity == NULL (so that their instance is deleted
179 * when there are no particle left)
180 * If entity provided is not NULL, then the entity will take ownership of shuttingdown FX (useful
181 * if there's an effect triggered at impact in the projectile itself, and if that effect is sticked
182 * to some bone of the target)
184 void shutDown(CCharacterCL
*target
);
186 void playImpactAnimOnAddtionnalTargets();
190 // set of projectile to create later
191 std::list
<CProjectile
> _ActiveProjectiles
; // currently active projectiles
192 std::list
<CProjectile
> _ToShutDownProjectiles
; // Projectiles that must be shutdown.
193 // We can't directly shut projectile down at the impact, because
194 // they can create trail -> final position (impact pos) is reached and, then emitters
195 // are shutdown -> the last segment of the particle trail between 'last pos' and 'impact pos'
196 // isn't generated at fx update, simply because emitters are off, and this create the impression
197 // that the projectile at stopped too early, so we delay the shutdown of one frame.
199 std::multiset
<CProjectileBuild
> _ProjectileQueue
; // projectiles that remains to be built (sorted by spawn date)
203 // update projectile queue, creating projectiles that need to be.
204 void updateProjectileQueue();
205 // create a projectile from its description, and add to the list of projectiles
206 void addProjectile(const CProjectileBuild
&pb
);
207 // clear a list of projectile (and delet fx instantlty)
208 static void resetProjList(std::list
<CProjectile
> &projList
);
210 const CAnimationFX
*getResistFX(uint level
);