Torque3D Documentation / _generateds / afxProjectile.cpp

afxProjectile.cpp

Engine/source/afx/ce/afxProjectile.cpp

More...

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