Control *findControl(const char *name)
{
   SimManager *manager = SimGame::get()->getManager(SimGame::CLIENT);
   int tag = atoi(name);
   if(tag)
   {
      SimSet *s = (SimSet *) manager->findObject(TaggedGuiSetId);
      SimSet::iterator i;
      for(i = s->begin(); i != s->end(); i++)
      {
         Control *c = dynamic_cast<Control *>(*i);
         if(c && c->getTag() == DWORD(tag))
            return c;
      }
      return NULL;   
   }
   else
   {
      StringTableEntry n = stringTable.insert(name);
      SimSet *s = (SimSet *) manager->findObject(NamedGuiSetId);
      SimSet::iterator i;
      for(i = s->begin(); i != s->end(); i++)
      {
         Control *c = dynamic_cast<Control *>(*i);
         if(c && c->getName() == n)
            return c;
      }
      return NULL;   
   }
}
Example #2
0
void SimFire::createOnClients(SimFire * fire, SimManager * mgr)
{
   SimSet * packetStreams = static_cast<SimSet*>(mgr->findObject(PacketStreamSetId));
   if (packetStreams)
   {
      for (SimSet::iterator itr = packetStreams->begin(); itr != packetStreams->end(); itr++)
      {
         Net::PacketStream * pStream = dynamic_cast<Net::PacketStream *>(*itr);
         if (pStream && pStream->getGhostManager()->getCurrentMode() ==
                        Net::GhostManager::GhostNormalMode)
         {
            Net::RemoteCreateEvent * addEvent = new Net::RemoteCreateEvent;
            SimFire *fireCopy = new SimFire(*fire);
            addEvent->newRemoteObject = fireCopy;
            // if attached to an object, see if it is in scope...
            if (fire->onObj)
            {
               int gidx = pStream->getGhostManager()->getGhostIndex(static_cast<SimNetObject*>(fire->onObj));
               if (gidx==-1)
                  continue; // object must be out of scope
            }
            pStream->getEventManager()->postRemoteEvent(addEvent);
         }
      }
   }
   if (!fire->manager)
      // this was a temporary object
      delete fire;
}
bool Material::onAdd()
{
   if (Parent::onAdd() == false)
      return false;

   mCubemapData = dynamic_cast<CubemapData*>(Sim::findObject( mCubemapName ) );

   if( mTranslucentBlendOp >= NumBlendTypes || mTranslucentBlendOp < 0 )
   {
      Con::errorf( "Invalid blend op in material: %s", getName() );
      mTranslucentBlendOp = LerpAlpha;
   }

   SimSet *matSet = MATMGR->getMaterialSet();
   if( matSet )
      matSet->addObject( (SimObject*)this );

   // save the current script path for texture lookup later
   const String  scriptFile = Con::getVariable("$Con::File");  // current script file - local materials.cs

   String::SizeType  slash = scriptFile.find( '/', scriptFile.length(), String::Right );
   if ( slash != String::NPos )
      mPath = scriptFile.substr( 0, slash + 1 );

   _mapMaterial();

   return true;
}
Example #4
0
SimObject* SimSet::findObjectByLineNumber(const char* fileName, S32 declarationLine, bool searchChildren)
{
   if (!fileName)
      return NULL;

   if (declarationLine < 0)
      return NULL;

   StringTableEntry fileEntry = StringTable->insert(fileName);

   for (iterator i = begin(); i != end(); i++)
   {
      SimObject *childObj = static_cast<SimObject*>(*i);

      if(childObj->getFilename() == fileEntry && childObj->getDeclarationLine() == declarationLine)
         return childObj;
      else if (searchChildren)
      {
         SimSet* childSet = dynamic_cast<SimSet*>(*i);

         if (childSet)
         {
            SimObject* found = childSet->findObjectByLineNumber(fileName, declarationLine, searchChildren);
            if (found)
               return found;
         }
      }
   }

   return NULL;
}
bool SimTreeView::handleItemRemoveFromFolder( HTREEITEM hFolder, HTREEITEM hItem )
{
	lockManager();
   SimSet *parent = (SimSet*)getObject( hFolder );
   SimObject *obj = getObject(hItem);
   parent->removeObject( obj );
   state.set(STV_MODIFIED);
	unlockManager();
   return ( true );  // true indicates we want item removed from TreeList
}   
bool SimTreeView::hasChildren( TV_ITEM *tvi )
{
   SimSet *set;
	lockManager();
   SimObject *obj = targetManager->findObject( tvi->lParam );
	unlockManager();

   if ( obj && (( set = dynamic_cast<SimSet*>(obj)) != 0) )
      return ( set->size() != 0 );
   else
      return false;
}
Example #7
0
TerrainBlock* EditTSCtrl::getActiveTerrain()
{
   // Find a terrain block
   SimSet* scopeAlwaysSet = Sim::getGhostAlwaysSet();
   for(SimSet::iterator itr = scopeAlwaysSet->begin(); itr != scopeAlwaysSet->end(); itr++)
   {
      TerrainBlock* block = dynamic_cast<TerrainBlock*>(*itr);
      if( block )
         return block;
   }

   return NULL;
}
Example #8
0
U32 SimSet::sizeRecursive()
{
   U32 count = 0;

   for ( iterator i = begin(); i != end(); i++ )
   {
      count++;

      SimSet* childSet = dynamic_cast<SimSet*>(*i);
      if ( childSet )
         count += childSet->sizeRecursive();
   }

   return count;
}
// lock/unlock object(s)
bool SimTreeView::lockObject( SimObject * obj, bool lock )
{
   if( !obj )
      return( false );
      
   SimSet   *ss;
   
   // recurse into children
   if( ( ss = dynamic_cast<SimSet*>( obj ) ) != NULL )
      for( SimSet::iterator itr = ss->begin(); itr != ss->end(); itr++ )
         lockObject( (*itr), lock );
   else
      obj->setLocked( lock );
   
   return( true );   
}
SimObject* SimSetIterator::operator++()
{
	SimSet* set;
	if ((set = dynamic_cast<SimSet*>(*stack.last().itr)) != 0) {
		if (!set->empty()) {
		   stack.push_back(set);
			return *stack.last().itr;
		}
	}

	while (++stack.last().itr == stack.last().set->end()) {
		stack.pop_back();
		if (stack.empty())
			return 0;
	}
	return *stack.last().itr;
}	
Example #11
0
TerrainMaterial* TerrainMaterial::findOrCreate( const char *nameOrPath )
{
   SimSet *set = Sim::getTerrainMaterialSet();
   
   if ( !nameOrPath || !nameOrPath[0] )
      nameOrPath = "warning_material";

   // See if we can just find it.
   TerrainMaterial *mat = dynamic_cast<TerrainMaterial*>( set->findObjectByInternalName( StringTable->insert( nameOrPath ) ) );
   if ( mat )
      return mat;

   // We didn't find it... so see if its a path to a
   // file.  If it is lets assume its the texture.
   if ( GBitmap::sFindFiles( nameOrPath, NULL ) )
   {
      mat = new TerrainMaterial();
      mat->setInternalName( nameOrPath );
      mat->mDiffuseMap = nameOrPath;
      mat->registerObject();
      Sim::getRootGroup()->addObject( mat );
      return mat;
   }

   // Ok... return a debug material then.
   mat = dynamic_cast<TerrainMaterial*>( set->findObjectByInternalName( StringTable->insert( "warning_material" ) ) );
   if ( !mat )
   {
      // This shouldn't happen.... the warning_texture should
      // have already been defined in script, but we put this
      // fallback here just in case it gets "lost".
      mat = new TerrainMaterial();
      mat->setInternalName( "warning_material" );
      mat->mDiffuseMap = GFXTextureManager::getWarningTexturePath();
      mat->mDiffuseSize = 500;
      mat->mDetailMap = GFXTextureManager::getWarningTexturePath();
      mat->mDetailSize = 5;
	  mat->mMacroMap = GFXTextureManager::getWarningTexturePath();
	  mat->mMacroSize = 200;
      mat->registerObject();
      
      Sim::getRootGroup()->addObject( mat );
   }

   return mat;
}
void SimTreeView::handleItemExpansion( HTREEITEM /*hParent*/, HTREEITEM hItem )
{
   SimSet *set;
	lockManager();
   TV_ITEM *tvi = treeList.getItemInfo( hItem );
   SimObject *obj = getObject( hItem );
   if ( (set = dynamic_cast<SimSet*>(obj)) != 0 )
   {
      TreeView_Expand( treeList.getHandle(), hItem, TVE_COLLAPSE|TVE_COLLAPSERESET );
      tvi->mask = TVIF_IMAGE;
      tvi->iImage = handleGetBitmapIndex( hItem, true );
      TreeView_SetItem( treeList.getHandle(), tvi );
      for ( SimObjectList::iterator iter=set->begin(); iter!=set->end(); iter++ )
         addSet( *iter, hItem );
   }
	unlockManager();
}   
Example #13
0
bool tripod::onAdd()
{
	if (!ObjParent::onAdd())
		return false;

	// Post by sending an event
   addToSet(SimTimerSetId);
   SimSet *grp;

   grp = (SimSet*)manager->findObject( SimCameraSetId );
  
   if ( grp )
      grp->addObject( this );

   setEventMap();      
      
    return true;
}
Example #14
0
SimSet* SimSet::clone()
{
   // Clone the set object.
   
   SimObject* object = Parent::clone();
   SimSet* set = dynamic_cast< SimSet* >( object );
   if( !set )
   {
      object->deleteObject();
      return NULL;
   }
   
   // Add all object in the set.
   
   for( iterator iter = begin(); iter != end(); ++ iter )
      set->addObject( *iter );
   
   return set;
}
Example #15
0
bool TerrainMaterial::onAdd()
{
   if ( !Parent::onAdd() )
      return false;

   SimSet *set = Sim::getTerrainMaterialSet();

   // Make sure we have an internal name set.
   if ( !mInternalName || !mInternalName[0] )
      Con::warnf( "TerrainMaterial::onAdd() - No internal name set!" );
   else
   {
      SimObject *object = set->findObjectByInternalName( mInternalName );
      if ( object )
         Con::warnf( "TerrainMaterial::onAdd() - Internal name collision; '%s' already exists!", mInternalName );
   }

   set->addObject( this );

   return true;
}
Example #16
0
SimObject* SimSet::findObjectByInternalName(StringTableEntry internalName, bool searchChildren)
{
   iterator i;
   for (i = begin(); i != end(); i++)
   {
      SimObject *childObj = static_cast<SimObject*>(*i);
      if(childObj->getInternalName() == internalName)
         return childObj;
      else if (searchChildren)
      {
         SimSet* childSet = dynamic_cast<SimSet*>(*i);
         if (childSet)
         {
            SimObject* found = childSet->findObjectByInternalName(internalName, searchChildren);
            if (found) return found;
         }
      }
   }

   return NULL;
}
void SimExplosionCloud::createOnClients(SimExplosionCloud * cloud, SimManager * mgr)
{
   SimSet * packetStreams = static_cast<SimSet*>(mgr->findObject(PacketStreamSetId));
   if (packetStreams)
   {
      for (SimSet::iterator itr = packetStreams->begin(); itr != packetStreams->end(); itr++)
      {
         Net::PacketStream * pStream = dynamic_cast<Net::PacketStream *>(*itr);
         if (pStream && pStream->getGhostManager()->getCurrentMode() ==
                        Net::GhostManager::GhostNormalMode)
         {
            Net::RemoteCreateEvent * addEvent = new Net::RemoteCreateEvent;
            SimExplosionCloud *cloudCopy = new SimExplosionCloud(*cloud);
            addEvent->newRemoteObject = cloudCopy;
            pStream->getEventManager()->postRemoteEvent(addEvent);
         }
      }
   }
   if (!cloud->manager)
      // this was a temporary object
      delete cloud;
}
bool GhostManager::onAdd()
{
   if(!Parent::onAdd())
      return false;

	if (!getId())
		manager->assignId(this);

   // iterate through the ghost always objects and InScope them...
   SimSet *ghostAlwaysSet = (SimSet *) manager->findObject(SimGhostAlwaysSetId);

   SimSet::iterator i;
   for(i = ghostAlwaysSet->begin(); i != ghostAlwaysSet->end(); i++)
   {
      AssertFatal(dynamic_cast<SimNetObject *>(*i) != NULL, "Non SimNetObject in GhostAlwaysSet");
      SimNetObject *obj = (SimNetObject *)(*i);
      if(obj->netFlags.test(SimNetObject::Ghostable))
         objectInScope(obj);
   }
   // add to the ghostManager set
   addToSet(GhostManagerSetId);
   return true;
}
bool SimTreeView::handleItemDroppedOnItem( HTREEITEM hTarget, HTREEITEM hDropItem )
{
   bool removeFromSource=false;
	lockManager();

   HTREEITEM hParent = getParent( hTarget );
   SimSet *pTarget = (SimSet*)getObject( hParent );
   SimObject *obj = getObject(hDragItem);
   SimObject *pParent = getObject( getParent(hDropItem) );

   if ( pTarget != obj )
   {
      state.set(STV_MODIFIED);
      if ( pTarget->find(pTarget->begin(), pTarget->end(), obj) != pTarget->end() )
      {
         if ( pTarget->reOrder( obj, getObject(hTarget) ) )
            refresh( hParent );
      }
      else
      {
         if ( !dynamic_cast<SimGroup*>(pTarget) )
         {
            if ( dynamic_cast<SimGroup*>(pParent) )
               removeFromSource = false;    // Group->Set, copy
            else if ( (GetKeyState( VK_SHIFT ) & 0x80000000) == 0 )
               removeFromSource = true;     // Set->Set, but pressing shift key, copy
            else
               removeFromSource = true;     // Set->Set, copying set by menu
         }
         else if ( !dynamic_cast<SimGroup*>(pParent) )
         {
         	unlockManager();
            return false;                    // set->Group is not allowed
         }
         else
         {
            state.clear(GWTV_COPYING);       // Group->Group, moving
            removeFromSource =  true;
         }
      	pTarget->addObject(obj);
         pTarget->reOrder( obj, getObject(hTarget) );
         WinParent::handleItemDroppedOnItem( hTarget, hDropItem );
      }
   }
	unlockManager();
   return removeFromSource;  // don't modify list after return
}
Example #20
0
void SimSet::callOnChildren( const String &method, S32 argc, ConsoleValueRef argv[], bool executeOnChildGroups )
{
   // Prep the arguments for the console exec...
   // Make sure and leave args[1] empty.
   ConsoleValueRef args[21];
   args[0] = method.c_str();
   for (S32 i = 0; i < argc; i++)
      args[i + 2] = argv[i];

   for( iterator i = begin(); i != end(); i++ )
   {
      SimObject *childObj = static_cast<SimObject*>(*i);

      if( childObj->isMethod( method.c_str() ) )
         Con::execute(childObj, argc + 2, args);

      if( executeOnChildGroups )
      {
         SimSet* childSet = dynamic_cast<SimSet*>(*i);
         if ( childSet )
            childSet->callOnChildren( method, argc, argv, executeOnChildGroups );
      }
   }
}
void SimTreeView::onCommand( int id, HWND hwndCtl, UINT codeNotify )
{
   hwndCtl, codeNotify;
   SimObject   *obj;
   SimSet    *prnt;
	lockManager();

   switch( id )
   {
      case IDM_EXIT:
         destroyWindow();
         break;

      case IDM_CUT:
         if ( (obj = getSelectedObject()) !=  NULL )
         {
            // persist selected object
            obj->fileStore( "temp\\clip.tmp" );

            // remove it from parent
            obj->deleteObject();
            delItem( getSelection() );
            state.set(STV_MODIFIED);
         }
         break;

      case IDM_COPY:
         if ( (obj = getSelectedObject()) !=  NULL )
            obj->fileStore( "temp\\clip.tmp" );
         break;

      case IDM_PASTE:
         {
            // unpersist object to get a duplicate
            Persistent::Base::Error err;
            obj = (SimObject*)Persistent::Base::fileLoad( "temp\\clip.tmp", &err );
            if ( err != Ok )
               return;

            // add to simTree
            HTREEITEM hParent = getSelection();
            if ( !isItemFolder(hParent) )
               hParent = getParent( hParent );

            prnt = (SimSet*)getObject( hParent );
            prnt->getManager()->addObject( obj );
				prnt->addObject(obj);
            HTREEITEM hItem = addSet( obj, hParent );
            selectItem( hItem );
            state.set(STV_MODIFIED);
         }
         break;

      case IDM_DELETE:
         obj = getSelectedObject();
         if ( obj )
         {
            obj->deleteObject();
            delItem( getSelection() );
            state.set(STV_MODIFIED);
         }
         break;

      case IDM_REMOVE:
         obj = getSelectedObject();
         if ( obj )
         {
            prnt = getSelectedParent();
				prnt->removeObject(obj);
            delItem( getSelection() );
            state.set(STV_MODIFIED);
         }
         break;

      case IDM_DUPLICATE:
         {
            obj = getSelectedObject();
            
            // persist object to get a duplicate
            if ( obj->fileStore( "temp\\clip.tmp" ) != Ok )
            {
					unlockManager();
               return;
            }

            Persistent::Base::Error err;
            obj = (SimObject*)Persistent::Base::fileLoad( "temp\\clip.tmp", &err );
            if ( err != Ok )
            {
					unlockManager();
               return;
            }
            // perhaps delete clip.tmp to clean up directory

            HTREEITEM hParent = getSelection();
            if ( !isItemFolder(hParent) )
               hParent = getParent( hParent );

            prnt = (SimSet*)getObject( hParent );
            prnt->getManager()->addObject( obj );
            prnt->addObject( obj );
            HTREEITEM hItem = addSet( obj, getParent(getSelection()) );
            selectItem( hItem );
            state.set(STV_MODIFIED);
         }
         break;

      case IDM_EDIT:
         inspectObject( getSelectedObject() );
         state.set(STV_MODIFIED);
         break;

      case IDM_LOCK:
         lockObject( getSelectedObject(), true );
         state.set( STV_MODIFIED );
         break;
         
      case IDM_UNLOCK:
         lockObject( getSelectedObject(), false );
         state.set( STV_MODIFIED );
         break;
         
      default:
         if ( (id>=IDM_SCRIPT_START) && (id<=scriptMenu_IDM) )
         {
            int scriptIndex = id-IDM_SCRIPT_START;
            CMDConsole::getLocked()->evaluate( script[scriptIndex], false );
         }
         // let parent handle its default menu items
         WinParent::handleContextMenuItemSelection( id );
   }
   checkMenu( hMainMenu );
	unlockManager();
}
Example #22
0
void Turret::shoot (bool playerControlled, Player* targetPlayer)
{
   if (data && data->isSustained == false) {
	   if (data && data->projectile.type == -1)
	   	{
	   		if (!isGhost())
	   			if (const char* script = scriptName("onFire"))
	   				Console->executef(2, script, scriptThis());
	   	}
	   else
	   	{
	   		float energy = getEnergy();
	   		if (waitTime <= manager->getCurrentTime() && data && energy >= data->minGunEnergy && data->projectile.type != -1)
	   			{
                  TMat3F muzzleTransform;
	   				getMuzzleTransform(0, &muzzleTransform);
	   				Projectile* bullet = createProjectile(data->projectile);

	   				if (!playerControlled && data->deflection)
	   					{
	   						static Random random;
	   						EulerF angles;
	   					   muzzleTransform.angles (&angles);
	   						angles.x += (random.getFloat() - 0.5) * M_2PI * data->deflection;
	   						angles.z += (random.getFloat() - 0.5) * M_2PI * data->deflection;
	   						muzzleTransform.set (angles, muzzleTransform.p);
	   					}
	   				else
	   					if (playerControlled)
	   						{
	   							Point3F start = muzzleTransform.p;
	   							muzzleTransform = getEyeTransform ();
	   							aimedTransform (&muzzleTransform, start);
	   							muzzleTransform.p = start;
	   						}

	   				bullet->initProjectile (muzzleTransform, Point3F (0, 0, 0), getId());

	   	         if (bullet->isTargetable() == true) {
	   	            if (targetPlayer != NULL) {
	   						if (GameBase* mo = targetPlayer->getMountObject())
	   		               bullet->setTarget(static_cast<ShapeBase*>(mo));
	   						else
	   		               bullet->setTarget(targetPlayer);
                     } else if (playerControlled) {
                        ShapeBase* pClosest   = NULL;
                        Point3F    closeHisPos;
                        float      closestVal = -2.0f;
                        SimSet::iterator itr;
                     
                        Point3F lookDir;
                        getEyeTransform().getRow(1, &lookDir);
                        lookDir.normalize();

                        SimContainerQuery collisionQuery;
                        SimCollisionInfo  info;
                        collisionQuery.id     = getId();
                        collisionQuery.type   = -1;
                        collisionQuery.mask   = Projectile::csm_collisionMask;
                        collisionQuery.detail = SimContainerQuery::DefaultDetail;
                        collisionQuery.box.fMin = getEyeTransform().p;
                        SimContainer* pRoot = (SimContainer*)manager->findObject(SimRootContainerId);

                        SimSet* pSet = dynamic_cast<SimSet*>(manager->findObject(PlayerSetId));
                        AssertFatal(pSet != NULL, "No player set?");
                        for (itr = pSet->begin(); itr != pSet->end(); itr++) {
                           Player* pPlayer = dynamic_cast<Player*>(*itr);

                           if (!pPlayer || pPlayer->getVisibleToTeam(getTeam()) == false)
                              continue;

                           collisionQuery.box.fMax = pPlayer->getBoxCenter();
                           if (pRoot->findLOS(collisionQuery, &info, SimCollisionImageQuery::High) == true) {
                              if (info.object != (SimObject*)pPlayer)
                                 continue;
                           }

                           Point3F hisPos = pPlayer->getBoxCenter();
                           hisPos -= getLinearPosition();
                           hisPos.normalize();

                           float prod = m_dot(hisPos, lookDir);
                           if (prod > 0.0f && prod > closestVal) {
                              closestVal = prod;
                              pClosest   = pPlayer;
                              closeHisPos = hisPos;
                           }
                        }

                        pSet = dynamic_cast<SimSet*>(manager->findObject(MoveableSetId));
                        AssertFatal(pSet != NULL, "No moveable set?");
                        for (itr = pSet->begin(); itr != pSet->end(); itr++) {
                           if (((*itr)->getType() & VehicleObjectType) == 0)
                              continue;

                           ShapeBase* pObject = dynamic_cast<ShapeBase*>(*itr);
                           
                           if (pObject->getVisibleToTeam(getTeam()) == false)
                              continue;

                           collisionQuery.box.fMax = pObject->getBoxCenter();
                           if (pRoot->findLOS(collisionQuery, &info, SimCollisionImageQuery::High) == true) {
                              if (info.object != (SimObject*)pObject)
                                 continue;
                           }

                           Point3F hisPos = pObject->getBoxCenter();
                           hisPos -= getLinearPosition();
                           hisPos.normalize();

                           float prod = m_dot(hisPos, lookDir);
                           if (prod > 0.0f && prod > closestVal) {
                              closestVal = prod;
                              closeHisPos = hisPos;
                              pClosest   = pObject;
                           }
                        }

                        // We need to find the current FOV, and take the percentage of
                        //  it specified in the .dat file for this turret.  Only if the
                        //  do product is greater than this, do we allow the target to
                        //  be set...
                        //
                        float myFov   = (fov / 2.0) * data->targetableFovRatio;
                        float compCos = cos(myFov);
                        if (compCos > 0.996f)   // hack for single precision math.  It's very
                           compCos = 0.996;     // hard to get more precise answers from the dot prod.

                        if (pClosest != NULL && closestVal > compCos)
                           bullet->setTarget(pClosest);
                     }
                  }

	   				if (data->maxGunEnergy)
	   					{
	   						float e;
	   						e = energy > data->maxGunEnergy ? data->maxGunEnergy : energy;

                        float pofm = e / float(data->maxGunEnergy);

	   						bullet->setEnergy (e, pofm);

	   						energy -= e;
	   						setEnergy (energy);
	   					}

                  SimGroup *grp = NULL;
                  if(SimObject *obj = manager->findObject("MissionCleanup"))
                     grp = dynamic_cast<SimGroup*>(obj);
                  if(!manager->registerObject(bullet))
                     delete bullet;
                  else
                  {
                     if(grp)
                        grp->addObject(bullet);
                     else
                        manager->addObject(bullet);
                  }

	   				waitTime = manager->getCurrentTime() + data->reloadDelay;

	   				if (animThread)
	   					{
	   						setFireThread ();
	   						animThread->SetPosition (0.0);
	   					}
	   				
	   				fireCount++;
	   				setMaskBits (ShootingMask);
	   			}
	   	}
   } else {
      if (data && data->projectile.type == -1) {
         if (!isGhost())
            if (const char* script = scriptName("onFire"))
               Console->executef(2, script, scriptThis());
      }
      else {
         float energy = getEnergy();
         if (waitTime <= manager->getCurrentTime() && data && energy >= data->minGunEnergy && data->projectile.type != -1) {
            TMat3F muzzleTransform;
            getMuzzleTransform(0, &muzzleTransform);
            Projectile* bullet = createProjectile(data->projectile);

            if (!playerControlled && data->deflection) {
               static Random random;
               EulerF angles;
               muzzleTransform.angles (&angles);
               angles.x += (random.getFloat() - 0.5) * M_2PI * data->deflection;
               angles.z += (random.getFloat() - 0.5) * M_2PI * data->deflection;
               muzzleTransform.set (angles, muzzleTransform.p);
            } else if (playerControlled) {
               Point3F start = muzzleTransform.p;
               muzzleTransform = getEyeTransform ();
               aimedTransform (&muzzleTransform, start);
               muzzleTransform.p = start;
            }

            bullet->initProjectile (muzzleTransform, Point3F (0, 0, 0), getId());
            AssertFatal(bullet->isSustained() == true, "Error, must be sustained bullet");
            SimGroup *grp = NULL;
            if(SimObject *obj = manager->findObject("MissionCleanup"))
               grp = dynamic_cast<SimGroup*>(obj);
            if(!manager->registerObject(bullet))
               delete bullet;
            else
            {
               if(grp)
                  grp->addObject(bullet);
               else
                  manager->addObject(bullet);
            }

            if (animThread) {
               setFireThread ();
               animThread->SetPosition (0.0);
            }
            
            fireCount++;
            setMaskBits (ShootingMask);

            m_fireState  = Firing;
            m_beganState = wg->currentTime;

            m_pProjectile = bullet;
            m_pTarget     = targetPlayer;
            
            if (m_pTarget)
               deleteNotify(m_pTarget);
         }
      }
   }
}