afxMagicSpell.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
  2. // Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
  3. // Copyright (C) 2015 Faust Logic, Inc.
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to
  7. // deal in the Software without restriction, including without limitation the
  8. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9. // sell copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  21. // IN THE SOFTWARE.
  22. //
  23. //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
  24. #ifndef _AFX_MAGIC_SPELL_H_
  25. #define _AFX_MAGIC_SPELL_H_
  26. //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
  27. #include "core/util/tVector.h"
  28. #include "console/typeValidators.h"
  29. #include "afxChoreographer.h"
  30. #include "afxEffectDefs.h"
  31. #include "afxEffectWrapper.h"
  32. #include "afxMagicMissile.h"
  33. class afxChoreographerData;
  34. class afxMagicMissileData;
  35. class afxEffectWrapperData;
  36. class SceneObject;
  37. class afxMagicSpell;
  38. class afxMagicSpellDefs
  39. {
  40. public:
  41. enum
  42. {
  43. CASTING_PHRASE,
  44. LAUNCH_PHRASE,
  45. DELIVERY_PHRASE,
  46. IMPACT_PHRASE,
  47. LINGER_PHRASE,
  48. NUM_PHRASES
  49. };
  50. };
  51. class afxMagicSpellData : public afxChoreographerData, public afxMagicSpellDefs
  52. {
  53. typedef afxChoreographerData Parent;
  54. class ewValidator : public TypeValidator
  55. {
  56. U32 id;
  57. public:
  58. ewValidator(U32 id) { this->id = id; }
  59. void validateType(SimObject *object, void *typePtr);
  60. };
  61. bool mDo_id_convert;
  62. public:
  63. F32 mCasting_dur;
  64. F32 mDelivery_dur;
  65. F32 mLinger_dur;
  66. //
  67. S32 mNum_casting_loops;
  68. S32 mNum_delivery_loops;
  69. S32 mNum_linger_loops;
  70. //
  71. F32 mExtra_casting_time;
  72. F32 mExtra_delivery_time;
  73. F32 mExtra_linger_time;
  74. //
  75. bool mDo_move_interrupts;
  76. F32 mMove_interrupt_speed;
  77. //
  78. afxMagicMissileData* mMissile_db;
  79. bool mLaunch_on_server_signal;
  80. U32 mPrimary_target_types;
  81. //
  82. afxEffectWrapperData* mDummy_fx_entry;
  83. // various effects lists
  84. afxEffectList mCasting_fx_list;
  85. afxEffectList mLaunch_fx_list;
  86. afxEffectList mDelivery_fx_list;
  87. afxEffectList mImpact_fx_list;
  88. afxEffectList mLinger_fx_list;
  89. void pack_fx(BitStream* stream, const afxEffectList& fx, bool packed);
  90. void unpack_fx(BitStream* stream, afxEffectList& fx);
  91. public:
  92. /*C*/ afxMagicSpellData();
  93. /*C*/ afxMagicSpellData(const afxMagicSpellData&, bool = false);
  94. virtual void reloadReset();
  95. virtual bool onAdd();
  96. virtual void packData(BitStream*);
  97. virtual void unpackData(BitStream*);
  98. virtual bool writeField(StringTableEntry fieldname, const char* value);
  99. bool preload(bool server, String &errorStr);
  100. void gatherConstraintDefs(Vector<afxConstraintDef>&);
  101. virtual bool allowSubstitutions() const { return true; }
  102. static void initPersistFields();
  103. DECLARE_CONOBJECT(afxMagicSpellData);
  104. DECLARE_CATEGORY("AFX");
  105. /// @name Callbacks
  106. /// @{
  107. DECLARE_CALLBACK( void, onDamage, (afxMagicSpell* spell, const char* label, const char* flaver, U32 target_id, F32 amount, U8 n, Point3F pos, F32 ad_amount, F32 radius, F32 impulse) );
  108. DECLARE_CALLBACK( void, onDeactivate, (afxMagicSpell* spell) );
  109. DECLARE_CALLBACK( void, onInterrupt, (afxMagicSpell* spell, ShapeBase* caster) );
  110. DECLARE_CALLBACK( void, onLaunch, (afxMagicSpell* spell, ShapeBase* caster, SceneObject* target, afxMagicMissile* missile) );
  111. DECLARE_CALLBACK( void, onImpact, (afxMagicSpell* spell, ShapeBase* caster, SceneObject* impacted, Point3F pos, Point3F normal) );
  112. DECLARE_CALLBACK( bool, onPreactivate, (SimObject* param_holder, ShapeBase* caster, SceneObject* target, SimObject* extra) );
  113. DECLARE_CALLBACK( void, onActivate, (afxMagicSpell* spell, ShapeBase* caster, SceneObject* target) );
  114. /// @}
  115. };
  116. //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
  117. // afxMagicSpell
  118. class ShapeBase;
  119. class GameConnection;
  120. class afxEffectVector;
  121. class afxConstraint;
  122. class afxConstraintMgr;
  123. class afxMagicMissile;
  124. class afxChoreographer;
  125. class afxPhrase;
  126. class afxMagicSpell : public afxChoreographer, public afxMagicSpellDefs
  127. {
  128. typedef afxChoreographer Parent;
  129. friend class afxMagicMissile;
  130. enum MaskBits
  131. {
  132. MagicMissileMask = Parent::NextFreeMask << 0,
  133. StateEventMask = Parent::NextFreeMask << 1,
  134. LaunchEventMask = Parent::NextFreeMask << 2,
  135. ImpactEventMask = Parent::NextFreeMask << 3,
  136. SyncEventMask = Parent::NextFreeMask << 4,
  137. RemapConstraintMask = Parent::NextFreeMask << 5, // CONSTRAINT REMAPPING
  138. NextFreeMask = Parent::NextFreeMask << 6
  139. };
  140. public:
  141. enum
  142. {
  143. NULL_EVENT,
  144. ACTIVATE_EVENT,
  145. LAUNCH_EVENT,
  146. IMPACT_EVENT,
  147. SHUTDOWN_EVENT,
  148. DEACTIVATE_EVENT,
  149. INTERRUPT_PHASE_EVENT,
  150. INTERRUPT_SPELL_EVENT
  151. };
  152. enum
  153. {
  154. INACTIVE_STATE,
  155. CASTING_STATE,
  156. DELIVERY_STATE,
  157. LINGER_STATE,
  158. CLEANUP_STATE,
  159. DONE_STATE,
  160. LATE_STATE
  161. };
  162. enum {
  163. MARK_ACTIVATE = BIT(0),
  164. MARK_LAUNCH = BIT(1),
  165. MARK_IMPACT = BIT(2),
  166. MARK_SHUTDOWN = BIT(3),
  167. MARK_DEACTIVATE = BIT(4),
  168. MARK_END_CASTING = BIT(5),
  169. MARK_END_DELIVERY = BIT(6),
  170. MARK_END_LINGER = BIT(7),
  171. MARK_INTERRUPT_CASTING = BIT(8),
  172. MARK_INTERRUPT_DELIVERY = BIT(9),
  173. MARK_INTERRUPT_LINGER = BIT(10),
  174. MARK_INTERRUPT_CLEANUP = BIT(11),
  175. //
  176. MARK_ENDINGS = MARK_END_CASTING | MARK_END_DELIVERY | MARK_END_LINGER,
  177. MARK_INTERRUPTS = MARK_INTERRUPT_CASTING | MARK_INTERRUPT_DELIVERY | MARK_INTERRUPT_LINGER | MARK_INTERRUPT_CLEANUP
  178. };
  179. class ObjectDeleteEvent : public SimEvent
  180. {
  181. public:
  182. void process(SimObject *obj) { if (obj) obj->deleteObject(); }
  183. };
  184. private:
  185. static StringTableEntry CASTER_CONS;
  186. static StringTableEntry TARGET_CONS;
  187. static StringTableEntry MISSILE_CONS;
  188. static StringTableEntry CAMERA_CONS;
  189. static StringTableEntry LISTENER_CONS;
  190. static StringTableEntry IMPACT_POINT_CONS;
  191. static StringTableEntry IMPACTED_OBJECT_CONS;
  192. private:
  193. afxMagicSpellData* mDatablock;
  194. SimObject* mExeblock;
  195. afxMagicMissileData* mMissile_db;
  196. ShapeBase* mCaster;
  197. SceneObject* mTarget;
  198. SimObject* mCaster_field;
  199. SimObject* mTarget_field;
  200. U16 mCaster_scope_id;
  201. U16 mTarget_scope_id;
  202. bool mTarget_is_shape;
  203. bool mConstraints_initialized;
  204. bool mScoping_initialized;
  205. U8 mSpell_state;
  206. F32 mSpell_elapsed;
  207. afxConstraintID mListener_cons_id;
  208. afxConstraintID mCaster_cons_id;
  209. afxConstraintID mTarget_cons_id;
  210. afxConstraintID mImpacted_cons_id;
  211. afxConstraintID mCamera_cons_id;
  212. SceneObject* mCamera_cons_obj;
  213. afxPhrase* mPhrases[NUM_PHRASES];
  214. F32 mTfactors[NUM_PHRASES];
  215. bool mNotify_castbar;
  216. F32 mOverall_time_factor;
  217. U16 mMarks_mask;
  218. private:
  219. void init();
  220. bool state_expired();
  221. F32 state_elapsed();
  222. void init_constraints();
  223. void init_scoping();
  224. void setup_casting_fx();
  225. void setup_launch_fx();
  226. void setup_delivery_fx();
  227. void setup_impact_fx();
  228. void setup_linger_fx();
  229. bool cleanup_over();
  230. bool is_caster_moving();
  231. bool is_caster_client(ShapeBase* caster, GameConnection* conn);
  232. bool is_impact_in_water(SceneObject* obj, const Point3F& p);
  233. protected:
  234. virtual bool remap_builtin_constraint(SceneObject*, const char* cons_name); // CONSTRAINT REMAPPING
  235. virtual void pack_constraint_info(NetConnection* conn, BitStream* stream);
  236. virtual void unpack_constraint_info(NetConnection* conn, BitStream* stream);
  237. private:
  238. afxMagicMissile* mMissile;
  239. bool mMissile_is_armed;
  240. SceneObject* mImpacted_obj;
  241. Point3F mImpact_pos;
  242. Point3F mImpact_norm;
  243. U16 mImpacted_scope_id;
  244. bool mImpacted_is_shape;
  245. void init_missile_s(afxMagicMissileData* mm);
  246. void launch_missile_s();
  247. void init_missile_c(afxMagicMissileData* mm);
  248. void launch_missile_c();
  249. public:
  250. virtual void impactNotify(const Point3F& p, const Point3F& n, SceneObject*);
  251. virtual void executeScriptEvent(const char* method, afxConstraint*,
  252. const MatrixF& pos, const char* data);
  253. virtual void inflictDamage(const char * label, const char* flavor, SimObjectId target,
  254. F32 amt, U8 count, F32 ad_amt, F32 rad, Point3F pos, F32 imp);
  255. public:
  256. /*C*/ afxMagicSpell();
  257. /*C*/ afxMagicSpell(ShapeBase* caster, SceneObject* target);
  258. /*D*/ ~afxMagicSpell();
  259. // STANDARD OVERLOADED METHODS //
  260. virtual bool onNewDataBlock(GameBaseData* dptr, bool reload);
  261. virtual void processTick(const Move*);
  262. virtual void advanceTime(F32 dt);
  263. virtual bool onAdd();
  264. virtual void onRemove();
  265. virtual void onDeleteNotify(SimObject*);
  266. virtual U32 packUpdate(NetConnection*, U32, BitStream*);
  267. virtual void unpackUpdate(NetConnection*, BitStream*);
  268. virtual void sync_with_clients();
  269. void finish_startup();
  270. static void initPersistFields();
  271. DECLARE_CONOBJECT(afxMagicSpell);
  272. DECLARE_CATEGORY("AFX");
  273. private:
  274. void process_server();
  275. //
  276. void change_state_s(U8 pending_state);
  277. //
  278. void enter_casting_state_s();
  279. void leave_casting_state_s();
  280. void enter_delivery_state_s();
  281. void leave_delivery_state_s();
  282. void enter_linger_state_s();
  283. void leave_linger_state_s();
  284. void enter_done_state_s();
  285. private:
  286. void process_client(F32 dt);
  287. //
  288. void change_state_c(U8 pending_state);
  289. //
  290. void enter_casting_state_c(F32 starttime);
  291. void leave_casting_state_c();
  292. void enter_delivery_state_c(F32 starttime);
  293. void leave_delivery_state_c();
  294. void enter_linger_state_c(F32 starttime);
  295. void leave_linger_state_c();
  296. //
  297. void sync_client(U16 marks, U8 state, F32 state_elapsed, F32 spell_elapsed);
  298. public:
  299. void postSpellEvent(U8 event);
  300. void resolveTimeFactors();
  301. void setTimeFactor(F32 f) { mOverall_time_factor = (f > 0) ? f : 1.0f; }
  302. F32 getTimeFactor() { return mOverall_time_factor; }
  303. void setTimeFactor(U8 phase, F32 f) { mTfactors[phase] = (f > 0) ? f : 1.0f; }
  304. F32 getTimeFactor(U8 phase) { return mTfactors[phase]; }
  305. ShapeBase* getCaster() const { return mCaster; }
  306. SceneObject* getTarget() const { return mTarget; }
  307. afxMagicMissile* getMissile() const { return mMissile; }
  308. SceneObject* getImpactedObject() const { return mImpacted_obj; }
  309. virtual void restoreObject(SceneObject*);
  310. bool activationCallInit(bool postponed=false);
  311. void activate();
  312. public:
  313. static afxMagicSpell* cast_spell(afxMagicSpellData*, ShapeBase* caster, SceneObject* target, SimObject* extra);
  314. static void displayScreenMessage(ShapeBase* caster, const char* msg);
  315. static Point3F getShapeImpactPos(SceneObject*);
  316. };
  317. inline bool afxMagicSpell::is_caster_moving()
  318. {
  319. return (mCaster) ? (mCaster->getVelocity().len() > mDatablock->mMove_interrupt_speed) : false;
  320. }
  321. inline bool afxMagicSpell::is_caster_client(ShapeBase* caster, GameConnection* conn)
  322. {
  323. return (caster) ? (caster->getControllingClient() == conn) : false;
  324. }
  325. //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
  326. #endif // _AFX_MAGIC_SPELL_H_