afxProjectile.cpp
Engine/source/afx/ce/afxProjectile.cpp
Classes:
Public Defines
define
myOffset(field) (field, )
Public Variables
Public Functions
ConsoleDocClass(afxProjectile , "@brief A <a href="/coding/class/classprojectile/">Projectile</a> effect as defined by an <a href="/coding/class/classafxprojectiledata/">afxProjectileData</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">datablock.\n\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">afxEffects\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">AFX\n</a>" )
ConsoleDocClass(afxProjectileData , "@brief A datablock that specifies <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/class/classprojectile/">Projectile</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">effect.\n\n</a>" "<a href="/coding/class/classafxprojectiledata/">afxProjectileData</a> inherits from <a href="/coding/class/classprojectiledata/">ProjectileData</a> and adds some AFX specific fields." "\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">afxEffects\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">AFX\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Datablocks\n</a>" )
ImplementEnumType(afxProjectile_LaunchDirType , "Possible projectile launch direction <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">types.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">afxProjectile\n\n</a>" )
Detailed Description
Public Defines
myOffset(field) (field, )
Public Variables
EndImplementEnumType
Public Functions
ConsoleDocClass(afxProjectile , "@brief A <a href="/coding/class/classprojectile/">Projectile</a> effect as defined by an <a href="/coding/class/classafxprojectiledata/">afxProjectileData</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">datablock.\n\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">afxEffects\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">AFX\n</a>" )
ConsoleDocClass(afxProjectileData , "@brief A datablock that specifies <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/class/classprojectile/">Projectile</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">effect.\n\n</a>" "<a href="/coding/class/classafxprojectiledata/">afxProjectileData</a> inherits from <a href="/coding/class/classprojectiledata/">ProjectileData</a> and adds some AFX specific fields." "\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">afxEffects\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">AFX\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Datablocks\n</a>" )
IMPLEMENT_CO_DATABLOCK_V1(afxProjectileData )
IMPLEMENT_CO_NETOBJECT_V1(afxProjectile )
ImplementEnumType(afxProjectile_LaunchDirType , "Possible projectile launch direction <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">types.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">afxProjectile\n\n</a>" )
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#include "afx/arcaneFX.h" 28 29#include "T3D/shapeBase.h" 30 31#include "afx/ce/afxProjectile.h" 32#include "afx/afxChoreographer.h" 33 34//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 35//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 36// afxProjectileData 37 38IMPLEMENT_CO_DATABLOCK_V1(afxProjectileData); 39 40ConsoleDocClass( afxProjectileData, 41 "@brief A datablock that specifies a Projectile effect.\n\n" 42 43 "afxProjectileData inherits from ProjectileData and adds some AFX specific fields." 44 "\n\n" 45 46 "@ingroup afxEffects\n" 47 "@ingroup AFX\n" 48 "@ingroup Datablocks\n" 49); 50 51afxProjectileData::afxProjectileData() 52{ 53 networking = GHOSTABLE; 54 launch_pos_spec = ST_NULLSTRING; 55 launch_dir_bias.zero(); 56 ignore_src_timeout = false; 57 dynamicCollisionMask = 0; 58 staticCollisionMask = 0; 59 override_collision_masks = false; 60 launch_dir_method = TowardPos2Constraint; 61} 62 63afxProjectileData::afxProjectileData(const afxProjectileData& other, bool temp_clone) : ProjectileData(other, temp_clone) 64{ 65 networking = other.networking; 66 launch_pos_spec = other.launch_pos_spec; 67 launch_pos_def = other.launch_pos_def; 68 launch_dir_bias = other.launch_dir_bias; 69 ignore_src_timeout = other.ignore_src_timeout; 70 dynamicCollisionMask = other.dynamicCollisionMask; 71 staticCollisionMask = other.staticCollisionMask; 72 override_collision_masks = other.override_collision_masks; 73 launch_dir_method = other.launch_dir_method; 74} 75 76ImplementEnumType( afxProjectile_LaunchDirType, "Possible projectile launch direction types.\n" "@ingroup afxProjectile\n\n" ) 77 { afxProjectileData::TowardPos2Constraint, "towardPos2Constraint", "..." }, 78 { afxProjectileData::OrientConstraint, "orientConstraint", "..." }, 79 { afxProjectileData::LaunchDirField, "launchDirField", "..." }, 80EndImplementEnumType; 81 82#define myOffset(field) Offset(field, afxProjectileData) 83 84void afxProjectileData::initPersistFields() 85{ 86 addField("networking", TypeS8, myOffset(networking), 87 "..."); 88 addField("launchPosSpec", TypeString, myOffset(launch_pos_spec), 89 "..."); 90 addField("launchDirBias", TypePoint3F, myOffset(launch_dir_bias), 91 "..."); 92 addField("ignoreSourceTimeout", TypeBool, myOffset(ignore_src_timeout), 93 "..."); 94 addField("dynamicCollisionMask", TypeS32, myOffset(dynamicCollisionMask), 95 "..."); 96 addField("staticCollisionMask", TypeS32, myOffset(staticCollisionMask), 97 "..."); 98 addField("overrideCollisionMasks", TypeBool, myOffset(override_collision_masks), 99 "..."); 100 101 addField("launchDirMethod", TYPEID<afxProjectileData::LaunchDirType>(), myOffset(launch_dir_method), 102 "Possible values: towardPos2Constraint, orientConstraint, or launchDirField."); 103 104 Parent::initPersistFields(); 105} 106 107bool afxProjectileData::onAdd() 108{ 109 if (Parent::onAdd() == false) 110 return false; 111 112 bool runs_on_s = ((networking & (SERVER_ONLY | SERVER_AND_CLIENT)) != 0); 113 bool runs_on_c = ((networking & (CLIENT_ONLY | SERVER_AND_CLIENT)) != 0); 114 launch_pos_def.parseSpec(launch_pos_spec, runs_on_s, runs_on_c); 115 116 return true; 117} 118 119void afxProjectileData::packData(BitStream* stream) 120{ 121 Parent::packData(stream); 122 123 stream->write(networking); 124 stream->writeString(launch_pos_spec); 125 if (stream->writeFlag(!launch_dir_bias.isZero())) 126 { 127 stream->write(launch_dir_bias.x); 128 stream->write(launch_dir_bias.y); 129 stream->write(launch_dir_bias.z); 130 } 131 stream->writeFlag(ignore_src_timeout); 132 if (stream->writeFlag(override_collision_masks)) 133 { 134 stream->write(dynamicCollisionMask); 135 stream->write(staticCollisionMask); 136 } 137 138 stream->writeInt(launch_dir_method, 2); 139} 140 141void afxProjectileData::unpackData(BitStream* stream) 142{ 143 Parent::unpackData(stream); 144 145 stream->read(&networking); 146 launch_pos_spec = stream->readSTString(); 147 if (stream->readFlag()) 148 { 149 stream->read(&launch_dir_bias.x); 150 stream->read(&launch_dir_bias.y); 151 stream->read(&launch_dir_bias.z); 152 } 153 else 154 launch_dir_bias.zero(); 155 ignore_src_timeout = stream->readFlag(); 156 if ((override_collision_masks = stream->readFlag()) == true) 157 { 158 stream->read(&dynamicCollisionMask); 159 stream->read(&staticCollisionMask); 160 } 161 else 162 { 163 dynamicCollisionMask = 0; 164 staticCollisionMask = 0; 165 } 166 167 launch_dir_method = (U32) stream->readInt(2); 168} 169 170void afxProjectileData::gather_cons_defs(Vector<afxConstraintDef>& defs) 171{ 172 if (launch_pos_def.isDefined()) 173 defs.push_back(launch_pos_def); 174}; 175 176//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 177//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 178// afxProjectile 179 180IMPLEMENT_CO_NETOBJECT_V1(afxProjectile); 181 182ConsoleDocClass( afxProjectile, 183 "@brief A Projectile effect as defined by an afxProjectileData datablock.\n\n" 184 185 "@ingroup afxEffects\n" 186 "@ingroup AFX\n" 187); 188 189afxProjectile::afxProjectile() 190{ 191 chor_id = 0; 192 hookup_with_chor = false; 193 ghost_cons_name = ST_NULLSTRING; 194 client_only = false; 195} 196 197afxProjectile::afxProjectile(U32 networking, U32 chor_id, StringTableEntry cons_name) 198{ 199 if (networking & SCOPE_ALWAYS) 200 { 201 mNetFlags.clear(); 202 mNetFlags.set(Ghostable | ScopeAlways); 203 client_only = false; 204 } 205 else if (networking & GHOSTABLE) 206 { 207 mNetFlags.clear(); 208 mNetFlags.set(Ghostable); 209 client_only = false; 210 } 211 else if (networking & SERVER_ONLY) 212 { 213 mNetFlags.clear(); 214 client_only = false; 215 } 216 else // if (networking & CLIENT_ONLY) 217 { 218 mNetFlags.clear(); 219 mNetFlags.set(IsGhost); 220 client_only = true; 221 } 222 223 this->chor_id = chor_id; 224 hookup_with_chor = false; 225 this->ghost_cons_name = cons_name; 226} 227 228afxProjectile::~afxProjectile() 229{ 230} 231 232void afxProjectile::init(Point3F& pos, Point3F& vel, ShapeBase* src_obj) 233{ 234 mCurrPosition = pos; 235 mCurrVelocity = vel; 236 if (src_obj) 237 { 238 mSourceObject = src_obj; 239 mSourceObjectId = src_obj->getId(); 240 mSourceObjectSlot = 0; 241 } 242 243 setPosition(mCurrPosition); 244} 245 246//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~// 247 248bool afxProjectile::onNewDataBlock(GameBaseData* dptr, bool reload) 249{ 250 return Parent::onNewDataBlock(dptr, reload); 251} 252 253void afxProjectile::processTick(const Move* move) 254{ 255 // note: this deletion test must occur before calling to the parent's 256 // processTick() because if this is a server projectile, the parent 257 // might decide to delete it and then client_only will no longer be 258 // valid after the return. 259 bool do_delete = (client_only && mCurrTick >= mDataBlock->lifetime); 260 261 Parent::processTick(move); 262 263 if (do_delete) 264 deleteObject(); 265} 266 267void afxProjectile::interpolateTick(F32 delta) 268{ 269 if (client_only) 270 return; 271 272 Parent::interpolateTick(delta); 273} 274 275void afxProjectile::advanceTime(F32 dt) 276{ 277 Parent::advanceTime(dt); 278 279 if (hookup_with_chor) 280 { 281 afxChoreographer* chor = arcaneFX::findClientChoreographer(chor_id); 282 if (chor) 283 { 284 chor->setGhostConstraintObject(this, ghost_cons_name); 285 hookup_with_chor = false; 286 } 287 } 288} 289 290bool afxProjectile::onAdd() 291{ 292 if(!Parent::onAdd()) 293 return false; 294 295 if (isClientObject()) 296 { 297 // add to client side mission cleanup 298 SimGroup *cleanup = dynamic_cast<SimGroup *>( Sim::findObject( "ClientMissionCleanup") ); 299 if( cleanup != NULL ) 300 { 301 cleanup->addObject( this ); 302 } 303 else 304 { 305 AssertFatal( false, "Error, could not find ClientMissionCleanup group" ); 306 return false; 307 } 308 } 309 310 return true; 311} 312 313void afxProjectile::onRemove() 314{ 315 Parent::onRemove(); 316} 317 318//~~~~~~~~~~~~~~~~~~~~ 319 320U32 afxProjectile::packUpdate(NetConnection* conn, U32 mask, BitStream* stream) 321{ 322 U32 retMask = Parent::packUpdate(conn, mask, stream); 323 324 // InitialUpdate 325 if (stream->writeFlag(mask & InitialUpdateMask)) 326 { 327 stream->write(chor_id); 328 stream->writeString(ghost_cons_name); 329 } 330 331 return retMask; 332} 333 334//~~~~~~~~~~~~~~~~~~~~// 335 336void afxProjectile::unpackUpdate(NetConnection * conn, BitStream * stream) 337{ 338 Parent::unpackUpdate(conn, stream); 339 340 // InitialUpdate 341 if (stream->readFlag()) 342 { 343 stream->read(&chor_id); 344 ghost_cons_name = stream->readSTString(); 345 346 if (chor_id != 0 && ghost_cons_name != ST_NULLSTRING) 347 hookup_with_chor = true; 348 } 349} 350 351class afxProjectileDeleteEvent : public SimEvent 352{ 353public: 354 void process(SimObject *object) 355 { 356 object->deleteObject(); 357 } 358}; 359 360void afxProjectile::explode(const Point3F& p, const Point3F& n, const U32 collideType) 361{ 362 // Make sure we don't explode twice... 363 if ( isHidden() ) 364 return; 365 366 Parent::explode(p, n, collideType); 367 368 if (isClientObject() && client_only) 369 Sim::postEvent(this, new afxProjectileDeleteEvent, Sim::getCurrentTime() + DeleteWaitTime); 370} 371 372//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 373