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