Beispiel #1
0
EntityId EntityFactory::create(EntitySpecs specs)
{
  EntityId new_id = EntityId(m_nextEntityId);
  ++m_nextEntityId;
  json& data = Config::bible().categoryData(specs.category);

  auto& jsonComponents = data["components"];
  m_gameState.components().populate(new_id, jsonComponents);

  auto material = specs.material;
  if (material.empty() && jsonComponents.count("materials") != 0)
  {
    auto& jsonMaterials = jsonComponents["materials"];

    if (jsonMaterials.is_array() && jsonMaterials.size() > 0)
    {
      /// @todo Choose one material randomly.
      ///       Right now, we just use the first one.
      material = StringTransforms::squishWhitespace(jsonMaterials[0].get<std::string>());
    }
  }

  if (!material.empty())
  {
    json& materialData = Config::bible().categoryData("material." + material);
    m_gameState.components().populate(new_id, materialData["components"]);
  }

  if (m_initialized)
  {
    GAME.lua().callEntityFunction("on_create", new_id, {}, true);
  }

  return EntityId(new_id);
}
int CampDirtyData::Process(uchar autodisp)
{
	FalconEntity
		*ent;

	unsigned char
		*data;

	int
		size;
	
	ent = (FalconEntity*) vuDatabase->Find (EntityId ());

	if (!ent || autodisp)
		return 0;

	data = dataBlock.data;

	// Only accept data if this is a remote entity
	if (!ent->IsLocal())
	{
		size = ent->DecodeDirty (&data);

		assert (size == dataBlock.size);
	}

	return 0;
}
Beispiel #3
0
bool CFunctionHandler::GetParam(int nIdx, EntityId& entityId)	const
{
    BEHAVIAC_ASSERT(nIdx <= GetParamCount() && "CFunctionHandler::GetParam - (CODE/ERROR) Index out of range");
    const char* entityIdStr = (const char*)lua_tostring(m_pLS, nIdx + 1);
    EntityId::IdType id;
    sscanf(entityIdStr, "%llu", &id);
    entityId = EntityId(id);
    return entityId.IsValid();
}
Beispiel #4
0
EntityId EntityFactory::createTileEntity(MapTile* mapTile, EntitySpecs specs)
{
  EntityId new_id = create(specs);

  MapID map = mapTile->map();
  IntVec2 position = mapTile->getCoords();
  m_gameState.components().position[new_id].set(map, position);

  return EntityId(new_id);
}
bool CCheckpointSystem::ReadMetaData(XmlNodeRef parentNode, SCheckpointData &metaData, bool bRepairId /*=true*/)
{
	XmlNodeRef data = parentNode->findChild(META_DATA_SECTION);
	if(!data)
		return false;

	metaData.m_versionNumber = 0;
	metaData.m_levelName.clear();
	metaData.m_saveTime.clear();
	metaData.m_checkPointId = 0;

	//read meta data
	int numAttribs = data->getNumAttributes();
	const char *key, *value;
	const char *checkpointName = NULL;
	for(int i = 0; i < numAttribs; ++i)
	{
		data->getAttributeByIndex(i, &key, &value);

		if(!stricmp("Version", key))
		{
			metaData.m_versionNumber = atoi(value);
		}
		else if(!stricmp("CheckpointId", key))
		{
			metaData.m_checkPointId = EntityId(atoi(value));
		}
		else if(!stricmp("CheckpointName", key))
		{
			checkpointName = value;
		}
		else if(!stricmp("LevelName", key))
		{
			metaData.m_levelName = value;
		}
		else if(!stricmp("Timestamp", key))
		{
			metaData.m_saveTime = value;
		}
	}

	//EntityId's may change on level export -> fix id
	if(checkpointName && bRepairId)
	{
		if(!RepairEntityId(metaData.m_checkPointId, checkpointName))
			CryWarning(VALIDATOR_MODULE_GAME, VALIDATOR_ERROR, "Failed finding checkpoint entity during loading, flowgraph might be broken.");
	}

	//check all values have been read
	CRY_ASSERT(metaData.m_levelName.size() > 0);
	CRY_ASSERT(metaData.m_saveTime.size() > 0);
	//CRY_ASSERT(metaData.m_checkPointId);

	return true;
}
Beispiel #6
0
EntityId EntityFactory::clone(EntityId original)
{
  auto& components = m_gameState.components();
  if (!components.category.existsFor(original))  return EntityId::Void;

  EntityId newId = EntityId(m_nextEntityId);
  ++m_nextEntityId;

  components.clone(original, newId);

  return newId;
}
int FalconDivertMessage::Process(uchar autodisp)
{
    Flight		flight = (Flight)FindUnit(EntityId());
    CampEntity	target = NULL;

    if (autodisp || !flight || !TheCampaign.IsLoaded())
        return 0;

    if (dataBlock.mission > 0)
    {
        // Check for target viability
        target = (CampEntity)vuDatabase->Find(dataBlock.targetID);
        if (target && target->IsUnit() && ((Unit)target)->Father())
            target = ((Unit)target)->GetFirstUnitElement();
        if ((!target || (target->IsUnit() && ((UnitClass*)target)->IsDead())) && dataBlock.mission > 0)
            return 0;
        // Set with new element's ID
        dataBlock.targetID = target->Id();

        // Make radio call
        PlayDivertRadioCalls(target,dataBlock.mission,flight, 0);

        // Return receipt
        if (flight->IsLocal() && (dataBlock.flags & REQF_NEEDRESPONSE))
        {
            CampEntity	e = (CampEntity) vuDatabase->Find(dataBlock.requesterID);
            if (e->IsUnit())
                ((Unit)e)->SendUnitMessage(dataBlock.targetID,FalconUnitMessage::unitRequestMet,dataBlock.mission,flight->GetTeam(),0);
        }

        // KCK: This is kinda hackish - Basically, for player leads, keep reposting this message
        // (every few seconds) until the player replies.
        if (flight->GetComponentLead() == FalconLocalSession->GetPlayerEntity() && flight == FalconLocalSession->GetPlayerFlight())
        {
            // Trying to track down a potential bug here.. It's hard enough to
            // get diverts I figure I'll let QA do the testing..
            // ShiAssert (!"Show this to Kevin K.");
            memcpy(&sLastDivert.dataBlock,&dataBlock,sizeof(dataBlock));
            sDivertFlight = flight->Id();
            sLastReply = DIVERT_WAIT_FOR_REPLY;
            sNextRepost = vuxGameTime + RESEND_DIVERT_TIME * CampaignSeconds;
            flight->SetDiverted(1);		// Set diverted to prevent additional calls
            return 0;
        }

        // Apply the divert
        ApplyDivert (flight, this);
    }
    else
        PlayDivertRadioCalls(NULL,DIVERT_DENIGNED,flight,0);

    return 1;
}
  virtual void ProcessEvent( EFlowEvent event, SActivationInfo *pActInfo )
  {
    switch (event)
    {    
    case eFE_Activate:
      {
        IActor* pActor = GetAIActor(pActInfo);
        if (!pActor)
          break;
        
        IEntity* pEnt = pActor->GetEntity();
        if (!pEnt)
          break;
        
        HSCRIPTFUNCTION func = 0;
        int ret = 0;
        IScriptTable* pTable = pEnt->GetScriptTable();
        if (!pTable)
          break;

        if (IsPortActive(pActInfo, 1) && pTable->GetValue("GrabObject", func))
        {                   
          IEntity* pObj = gEnv->pEntitySystem->GetEntity( GetPortEntityId(pActInfo, 0) );
          if (pObj)
          {
            IScriptTable* pObjTable = pObj->GetScriptTable();
            Script::CallReturn(gEnv->pScriptSystem, func, pTable, pObjTable, ret);
          }
          ActivateOutput(pActInfo, 0, ret);
        }  
        else if (IsPortActive(pActInfo, 2) && pTable->GetValue("DropObject", func))
        {
          bool bThrow = GetPortBool(pActInfo, 3);
          Script::CallReturn(gEnv->pScriptSystem, func, pTable, bThrow, ret);
          ActivateOutput(pActInfo, 0, ret);
        }
        
        if (pTable->GetValue("GetGrabbedObject", func))
        {          
          ScriptHandle sH(0);
          Script::CallReturn(gEnv->pScriptSystem, func, pTable, sH);
          ActivateOutput(pActInfo, 1, EntityId(sH.n));
        }
        
				if(func)
					gEnv->pScriptSystem->ReleaseFunc(func);

        break;
      }
    }
  }
Beispiel #9
0
ComponentId TransformSystem::createComponent(EntityId entityId)
{
    ComponentId ret = System::createComponent(entityId);
    
    glm::mat4 zero;
    _localPos.add(zero);
    _globalPos.add(zero);
    
    _heights.add(0);
    _parents.add(EntityId(-1, -1));
    _debugSort.add(ret.index);
    
    return ret;
}
void CFlowNode_AISequenceAction_WeaponDrawFromInventory::HandleSequenceEvent(AIActionSequence::SequenceEvent sequenceEvent)
{
	switch(sequenceEvent)
	{
	case AIActionSequence::StartAction:
		{
			CRY_ASSERT_MESSAGE(m_actInfo.pEntity, "entity has magically gone");
			if (!m_actInfo.pEntity)
			{
				// the entity has gone for some reason, at least make sure the action gets finished properly and the FG continues
				CancelSequenceAndActivateOutputPort(OutputPort_Done);
				return;
			}

			assert(gEnv && gEnv->pGame && gEnv->pGame->GetIGameFramework() && gEnv->pGame->GetIGameFramework()->GetIActorSystem());
			IActor* pActor = gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_actInfo.pEntity->GetId());
			if (!pActor)
			{
				CRY_ASSERT_MESSAGE(0, "Provided entity must be an IActor");
				CryWarning(VALIDATOR_MODULE_AI, VALIDATOR_WARNING, "Provided entity %s must be an IActor", m_actInfo.pEntity->GetName());
				CancelSequenceAndActivateOutputPort(OutputPort_Done);
				return;
			}

			assert(gEnv && gEnv->pGame && gEnv->pGame->GetIGameFramework() && gEnv->pGame->GetIGameFramework()->GetIItemSystem());
			IItemSystem* pItemSystem = gEnv->pGame->GetIGameFramework()->GetIItemSystem();

			IInventory* pInventory = pActor->GetInventory();
			if (!pInventory)
			{
				CRY_ASSERT_MESSAGE(0, "Actor has no inventory");
				CryWarning(VALIDATOR_MODULE_AI, VALIDATOR_WARNING, "Actor %s has no inventory", m_actInfo.pEntity->GetName());
				CancelSequenceAndActivateOutputPort(OutputPort_Done);
				return;
			}

			pInventory->SetHolsteredItem(EntityId(0));	// otherwise trying to holster the new weapon later on will not work (i. e. will do nothing)

			// draw the weapon
			const string& weaponName = GetPortString(&m_actInfo, InputPort_WeaponName);
			pItemSystem->SetActorItem(pActor, weaponName.c_str(), false);

			FinishSequenceActionAndActivateOutputPort(OutputPort_Done);
		}
		break;
	}
}
int FalconDLinkMessage::Process(uchar autodisp){
	SimBaseClass* theEntity;
	theEntity = (SimBaseClass*)(vuDatabase->Find (EntityId()));
	if (
		theEntity && theEntity->IsLocal() && 
		theEntity == (void*)SimDriver.GetPlayerEntity()
	){
		gNavigationSys->SetDataLinks(
			dataBlock.numPoints,
			dataBlock.targetType,
			dataBlock.threatType,
			(FalconDLinkMessage::DLinkPointType *) dataBlock.ptype,
			dataBlock.px,
			dataBlock.py,
			dataBlock.pz,
			dataBlock.arrivalTime
		);
		OTWDriver.pCockpitManager->mpIcp->SetICPUpdateFlag(DLINK_UPDATE);
	}
	return 0;
}
Beispiel #12
0
void CGameStats::ProcessPlayerStat(IEntity* pEntity, const GameplayEvent &event)
{
	if(CCryActionCVars::Get().g_statisticsMode != 1)
		return;

	SGetTime time(m_roundStart);

	const int e_id = pEntity->GetId(); 
	PlayerStatsMap::iterator it = m_playerMap.find(e_id);
	if(it == m_playerMap.end())
		return;
	SPlayerStats& plr = *(it->second.stats.back());
	if(gEnv->bServer)
	{
		switch(event.event)
		{
		case eGE_Kill:
			plr.m_kills++;
			{
				EntityId* params = (EntityId*)event.extra;
				IEntity *weapon = gEnv->pEntitySystem->GetEntity(params[0]);
				string wname = event.description?event.description:"";
				if(weapon)
					wname = weapon->GetClass()->GetName();
				plr.PlayerEvent(time, "kill", wname, params[1], pEntity->GetWorldPos());
			}
			break;
		case eGE_Death:
			plr.m_deaths++;
			plr.m_inVehicle = false;
			plr.PlayerEvent(time, "death", "", 0, pEntity->GetWorldPos());
			break;
		case eGE_Revive:
			plr.m_revives++;
			plr.PlayerEvent(time, "spawn", "", int(event.value), pEntity->GetWorldPos());
			CreateNewLifeStats(e_id);
			break;
		case eGE_WeaponMelee:
			{
				plr.m_melee++;
				plr.PlayerEvent(time, "weapon_melee" );
			}
			break;
		case eGE_EnteredVehicle:
			plr.m_inVehicle = true;
			break;
		case eGE_LeftVehicle:
			plr.m_inVehicle = false;
			break;
		}
	}

	static string vehicle_name;

	switch(event.event)
	{
	case eGE_WeaponShot:
		if(!plr.m_inVehicle)
		{
			if(event.description == NULL)
				break;

			if(strstr(event.description, "bullet")!=0 || strcmp(event.description,"shotgunshell")==0 || strcmp(event.description,"alienmount_acmo")==0)//only counting these
				plr.m_shots += int(event.value);
		}
		plr.WeaponShot(int(event.value), time, pEntity->GetWorldPos());
		break;
	/*case eGE_Damage:
		{
			float dmgVal = event.value;
			const char* weaponName = event.description;
			plr.WeaponDamage(weaponName, dmgVal);

		}break;*/
	case eGE_WeaponHit:
		if(!plr.m_inVehicle)
		{
			float dmgVal = event.value;
			const char* weaponName = event.description;
			uint32 targetId = (uint32)reinterpret_cast<TRUNCATE_PTR>(event.extra);
			const Vec3 fakePos(0,0,0);
			const char* bodyPart = event.strData;
			
			plr.WeaponHit(weaponName);
			plr.WeaponDamage(weaponName, dmgVal);
			plr.PlayerEvent(time, "hit", weaponName, targetId, fakePos, dmgVal, bodyPart );
			
		}	
		break;
	case eGE_Kill:
		{
			plr.ClientKill(event.description, time);			
			
			EntityId* params = (EntityId*)event.extra;
			IEntity* pWeapon = 0;
			if (params)
				gEnv->pEntitySystem->GetEntity(params[0]);
			plr.WeaponKill(pWeapon?pWeapon->GetClass()->GetName():0);
		}
		break;
	case eGE_Death:
		plr.ClientDeath(time);
		break;
	case eGE_Revive:
		plr.ClientRevive(time);
		break;
	case eGE_SuitModeChanged:
		plr.SelectSuitMode(int(event.value), time);
		break;
	case eGE_EnteredVehicle:
		{
			if( IVehicle* pV = CCryAction::GetCryAction()->GetIVehicleSystem()->GetVehicle((EntityId)(TRUNCATE_PTR)event.extra))
			{
				vehicle_name.Format("%s_%s", pV->GetEntity()->GetClass()->GetName(), pV->GetModification());
				plr.EnterVehicle(vehicle_name, time);
			}
		}
		break;
	case eGE_LeftVehicle:
		{
			if( IVehicle* pV = CCryAction::GetCryAction()->GetIVehicleSystem()->GetVehicle((EntityId)(TRUNCATE_PTR)event.extra))
			{
				vehicle_name.Format("%s_%s", pV->GetEntity()->GetClass()->GetName(), pV->GetModification());
				plr.LeaveVehicle(vehicle_name, time);
			}
		}
		break;
	case eGE_ItemSelected:
		{
			if( IEntity* pI = gEnv->pEntitySystem->GetEntity(EntityId((TRUNCATE_PTR)event.extra)) )
				plr.SelectWeapon(pI->GetClass()->GetName(), time);
		}			
		break;
	case eGE_WeaponReload:
		{
			plr.Reload(time, pEntity->GetWorldPos());
			break;
		}	
	case eGE_Spectator:
		plr.Spectator(event.value != 0, time);
		break;
	case eGE_WeaponFireModeChanged:
		{
			plr.FiremodeChanged(time, pEntity->GetWorldPos(), event.description);
			break;
		}
	case eGE_ZoomedIn:
		{
			plr.ZoomIn(time, pEntity->GetWorldPos());
			break;
		}
	case eGE_ZoomedOut:
		{
			plr.ZoomOut(time, pEntity->GetWorldPos());
			break;
		}
	}
}
int FalconSimCampMessage::Process(uchar autodisp)
{
	CampEntity				ent = (CampEntity)vuDatabase->Find(EntityId());
	FalconSessionEntity		*session = (FalconSessionEntity*) vuDatabase->Find(dataBlock.from);
	
	if(autodisp || !ent || !session || !FalconLocalGame)
		return 0;
	
	CampEnterCriticalSection();
	switch (dataBlock.message)
	{
	case simcampReaggregate:
		if (check_bandwidth (150))
		{
			ent->Reaggregate(session);
			//MonoPrint ("Reag   %d\n", ent->Id().num_);
		}
		break;

	case simcampDeaggregate:

// OW: me123 MP Fix
#if 0
		if (check_bandwidth (150))
		{
#else
		if (check_bandwidth (150)|| ent->IsSetFalcFlag(FEC_PLAYER_ENTERING|FEC_HASPLAYERS))//me123
		{//me123 addet the player check
			//me123 send player deags so they can go past pie 2 fast
#endif
			//MonoPrint ("Deag   %d\n", ent->Id().num_);
			ent->Deaggregate(session);
		}
		else
		{
			//MonoPrint ("NoDeag %d\n", ent->Id().num_)
		}
		break;

	case simcampChangeOwner:
		//			MonoPrint ("Sim Camp Change Owner %08x %08x%08x\n", ent, session->Id ());
		ent->RecordCurrentState (session, FALSE);
		ent->SetDeagOwner (session->Id ());
		break;
		
	case simcampRequestDeagData:
		// MonoPrint ("Request Deag Data\n");
		ent->SendDeaggregateData(FalconLocalGame);
		break;

	case simcampReaggregateFromData:
		ent->ReaggregateFromData(dataBlock.size,dataBlock.data);
		break;

	case simcampDeaggregateFromData:
		ent->DeaggregateFromData(dataBlock.size,dataBlock.data);
		break;

	case simcampChangeOwnerFromData:
		break;

	case simcampRequestAllDeagData:
		{
			SetTimeCompression(1);//me123 if a client is callign this he's in the pie
			//let's set the compresion to 1 on the host so we don'e f**k up the realtime
			//becourse the clients stops transmitting timecompresion and we go to 64 again for awhile.
			int count = 0;
			VuListIterator	deag_it(DeaggregateList);
			CampEntity c;
			c = (CampEntity) deag_it.GetFirst();
			while (c)
			{
				if ((!c->IsAggregate()) && (c->IsLocal()))
				{
					c->SendDeaggregateData(FalconLocalGame);
					count ++;
				}
				c = (CampEntity) deag_it.GetNext();
			}
			
			//			MonoPrint ("Request All Deag Data = %d\n", count);
			break;
		}
	}
	CampLeaveCriticalSection();
	
	return 0;
}
int FalconCampWeaponsFire::Process(uchar autodisp)
	{
	CampEntity	target = (CampEntity)vuDatabase->Find(EntityId());
	CampEntity	shooter = (CampEntity)vuDatabase->Find(dataBlock.shooterID);
	int			losses,shooterAc=255,i;
	FalconDeathMessage	*dtm = NULL;

	if (autodisp || !shooter || !target || !shooter->IsUnit())
		return -1;

	if (!target->IsAggregate())
		{
		// Whoops, this thing deaggregated out from under us.
		// If we're the host, actually start firing the stuff.
		if (shooter->IsLocal())
			FireOnSimEntity(shooter, target, dataBlock.weapon, dataBlock.shots, dataBlock.dPilotId);
		return 0;
		}

	shooter->ReturnToSearch();

	if (shooter->IsFlight()) {
	// Pick a pilot to get the kill
	if (dataBlock.fPilotId == 255)
		shooterAc = dataBlock.fPilotId = (uchar)((Flight)shooter)->PickRandomPilot(target->Id().num_);
	if (dataBlock.fPilotId >= PILOTS_PER_FLIGHT)
		shooterAc = ((Flight)shooter)->GetAdjustedPlayerSlot(dataBlock.fPilotId);
	else
		shooterAc = dataBlock.fPilotId;
	}
	else {
	    shooterAc = 0; // something
	}

	if (shooter->IsAggregate())
		{
		// Send a radio chatter message to LOCAL MACHINE if shooter is a flight
		if (shooter->IsFlight() && !SimDriver.InSim() && !(rand() % 20) )
			{
			// Send the chatter message;
			FalconRadioChatterMessage *msg = new FalconRadioChatterMessage(shooter->Id(), FalconLocalSession);
			msg->dataBlock.from = shooter->Id();
			msg->dataBlock.to = MESSAGE_FOR_TEAM;
			msg->dataBlock.voice_id = (uchar)((Flight)shooter)->GetPilotVoiceID(shooterAc);
			if (target->IsFlight())
				{
				msg->dataBlock.message = rcFIRING;
				// JWFU: Need callsign data stuff
				msg->dataBlock.edata[0] = WeaponDataTable[dataBlock.weapon[0]].Index;
				}
			else
				{
				msg->dataBlock.message = rcATTACKINGA;
				msg->dataBlock.edata[0] = ((Flight)shooter)->callsign_id;
				msg->dataBlock.edata[1] = (short)((Flight)shooter)->GetPilotCallNumber(shooterAc);
				target->GetLocation(&msg->dataBlock.edata[2],&msg->dataBlock.edata[3]);
				}
			FalconSendMessage(msg, FALSE);
			}

		// Synthisize a shot message for flight shooters in our package
		if (shooter->IsFlight() && (shooter->InPackage()||g_bLogEvents))
			{
			FalconWeaponsFire	wfm(FalconNullId,FalconLocalSession);
			wfm.dataBlock.fCampID = shooter->GetCampID();
			wfm.dataBlock.fPilotID = dataBlock.fPilotId;
			wfm.dataBlock.fIndex = (unsigned short)(((Unit)shooter)->GetVehicleID(0) + VU_LAST_ENTITY_TYPE);
			wfm.dataBlock.fSide = (unsigned char)shooter->GetOwner();
			wfm.dataBlock.fWeaponID = (unsigned short)(WeaponDataTable[dataBlock.weapon[0]].Index + VU_LAST_ENTITY_TYPE);
			// KCK: Since we don't really have a real weapon, use the current time for matching
			wfm.dataBlock.fWeaponUID.num_ = dataBlock.fWeaponUID.num_ = TheCampaign.CurrentTime;
			TheCampaign.MissionEvaluator->RegisterShot(&wfm);
			}

		// Do visual Effects (Aggregate shooters only)
		if (InterestingSFX(target->XPos(), target->YPos()))
			{
			for (i=0; i<MAX_TYPES_PER_CAMP_FIRE_MESSAGE && dataBlock.weapon[i] && dataBlock.shots[i]; i++)
				DoDistanceVisualEffects (shooter, target, dataBlock.weapon[i], dataBlock.shots[i]);
			}
		}

	// Synthisize a death message if either shooter or target is in our package
	if (shooter->InPackage() || target->InPackage())
		{
		dtm = new FalconDeathMessage(FalconNullId,FalconLocalSession);
		dtm->dataBlock.damageType = 0;
		if (target->IsFlight())
			dtm->dataBlock.dPilotID = (uchar)((Flight)target)->PickRandomPilot(target->GetCampID());
		dtm->dataBlock.dCampID = target->GetCampID();
		dtm->dataBlock.dSide = target->GetOwner();
		dtm->dataBlock.fCampID = shooter->GetCampID();
		dtm->dataBlock.fPilotID = dataBlock.fPilotId;
		dtm->dataBlock.fIndex = (unsigned short)(((Unit)shooter)->GetVehicleID(0) + VU_LAST_ENTITY_TYPE);
		dtm->dataBlock.fSide = shooter->GetOwner();
		dtm->dataBlock.fWeaponID = (unsigned short)(WeaponDataTable[dataBlock.weapon[0]].Index + VU_LAST_ENTITY_TYPE);
		dtm->dataBlock.fWeaponUID = dataBlock.fWeaponUID;
		}

	// Apply the damage data
	losses = target->DecodeDamageData(dataBlock.data, (Unit)shooter, dtm);

	// add some additional fire effects if losses were taken, the target is
	// a battalion and the target is in the sim lists
	if ( losses &&
		 target->InSimLists() &&
		 OTWDriver.IsActive() )
	{
		int i;
		Tpoint pos;

		// ground losses
		if ( target->IsBattalion() || target->IsObjective() )
		{
			pos.z = 40.0f;
	
			for ( i = 0; i < losses; i++ )
			{
				pos.x = target->XPos() + 800.0f * PRANDFloat();
				pos.y = target->YPos() + 800.0f * PRANDFloat();
				OTWDriver.AddSfxRequest( new SfxClass( SFX_CAMP_FIRE,
					 &pos,
					 60.0f,
					 90.0f ) );

				pos.x = target->XPos() + 800.0f * PRANDFloat();
				pos.y = target->YPos() + 800.0f * PRANDFloat();
				OTWDriver.AddSfxRequest( new SfxClass( SFX_CAMP_HIT_EXPLOSION_DEBRISTRAIL,
					 &pos,
					 2.0f,
					 200.0f ) );
			}
		}
		// air losses
		else
		{
	
			for ( i = 0; i < losses; i++ )
			{
				pos.x = target->XPos() + 800.0f * PRANDFloat();
				pos.y = target->YPos() + 800.0f * PRANDFloat();
				pos.z = target->ZPos() + 300.0f * PRANDFloat();
				OTWDriver.AddSfxRequest( new SfxClass( SFX_CAMP_HIT_EXPLOSION_DEBRISTRAIL,
					 &pos,
					 2.0f,
					 200.0f ) );
			}
		}

	}

	if (dtm)
		delete dtm;

	// Send a RadioChatter message to LOCAL MACHINE if shooter is a flight and scored a kill
	if (losses && shooter->IsFlight())
		{
		FalconRadioChatterMessage *msg = new FalconRadioChatterMessage(target->Id(), FalconLocalSession);
		msg->dataBlock.from = shooter->Id();
		msg->dataBlock.to = MESSAGE_FOR_TEAM;
		msg->dataBlock.voice_id = (uchar)((Flight)shooter)->GetPilotVoiceID(shooterAc);
		if (target->IsFlight())
			{
			msg->dataBlock.message = rcAIRBDA;
			msg->dataBlock.edata[0] = ((Flight)shooter)->callsign_id;
			msg->dataBlock.edata[1] = (short)((Flight)shooter)->GetPilotCallNumber(shooterAc);
			//MI uncommented the line below and outcommented the lines 
			//M.N. changed to 32767 which flexibly uses randomized values of available eval indexes
			msg->dataBlock.edata[2] = 32767; // couldn't stand the Hollywood kill calls
			/*if(rand()%2)
				  msg->dataBlock.edata[2] = 1;
			  else
				  msg->dataBlock.edata[2] = 9;*/
			}
		else if (target->IsTaskForce())
			{
			msg->dataBlock.message = rcMOVERBDA;
			msg->dataBlock.edata[0] = 32767;
			}
		else
			{
			if (target->IsUnit())
				{
				msg->dataBlock.message = rcMOVERBDA;
				msg->dataBlock.edata[0] = 32767;
				}
			else
				{
				msg->dataBlock.message = rcSTATICBDA;
				msg->dataBlock.edata[0] = ((Flight)shooter)->callsign_id;
				msg->dataBlock.edata[1] = (short)((Flight)shooter)->GetPilotCallNumber(shooterAc);
				msg->dataBlock.edata[2] = 32767;
				}
			}
		FalconSendMessage(msg, FALSE);
		}

	// Send a CampEvent message for weapon fire to the LOCAL MACHINE
	FalconCampEventMessage	*newEvent = new FalconCampEventMessage(shooter->Id(),FalconLocalSession);
	newEvent->dataBlock.flags = 0;
	newEvent->dataBlock.team = shooter->GetTeam();
	if (shooter->GetDomain() == DOMAIN_AIR)
		{
		if (target->IsObjective())
			newEvent->dataBlock.eventType = FalconCampEventMessage::campStrike;
		else if (target->GetDomain() == DOMAIN_AIR)
			newEvent->dataBlock.eventType = FalconCampEventMessage::campAirCombat;
		else if (target->GetDomain() == DOMAIN_LAND)
			newEvent->dataBlock.eventType = FalconCampEventMessage::campGroundAttack;
		else
			newEvent->dataBlock.eventType = FalconCampEventMessage::campCombat;
		}
	else
		newEvent->dataBlock.eventType = FalconCampEventMessage::campCombat;
	newEvent->dataBlock.data.vuIds[0] = shooter->Id();
	newEvent->dataBlock.data.vuIds[1] = target->Id();
	newEvent->dataBlock.data.owners[0] = shooter->GetOwner();
	newEvent->dataBlock.data.owners[1] = target->GetOwner();
	target->GetLocation(&newEvent->dataBlock.data.xLoc,&newEvent->dataBlock.data.yLoc);
	if (shooter->GetDomain() == DOMAIN_AIR)
		{
		// 2002-02-21 ADDED BY S.G. If it's not spotted and it's NOT the player, use the 'Bandit' vehicle so we don't warn the player on the identity of the shooter
		if (!shooter->GetIdentified(target->GetTeam()) && FalconLocalSession->GetTeam() != shooter->GetTeam())
			newEvent->dataBlock.data.textIds[0] = (short)(-1 * BANDIT_VEH);
		else
		// END OF ADDED SECTION 2002-02-21
			newEvent->dataBlock.data.textIds[0] = (short)(-1 * ((Unit)shooter)->GetVehicleID(0));

		if (target->IsObjective())
			{
			// Air Strikes
			newEvent->dataBlock.data.formatId = 1804;
			}
		else if (target->GetDomain() == DOMAIN_AIR)
			{
			// Air to air combat
			newEvent->dataBlock.data.formatId = 1805;
			// 2002-02-21 ADDED BY S.G. If it's not spotted and it's NOT the player, use the 'Bandit' vehicle so we don't warn the player on the identity of the shooter
			if (!target->GetIdentified(shooter->GetTeam()) && FalconLocalSession->GetTeam() != target->GetTeam())
				newEvent->dataBlock.data.textIds[1] = (short)(-1 * BANDIT_VEH);
			else
			// END OF ADDED SECTION 2002-02-21
				newEvent->dataBlock.data.textIds[1] = (short)(-1 * ((Unit)target)->GetVehicleID(0));
			}
		else
			{
			// Air attack
			newEvent->dataBlock.data.formatId = 1803;
			}
		}
	else if (shooter->GetDomain() == DOMAIN_SEA)
		{
		// Naval engagement
		newEvent->dataBlock.data.formatId = 1802;
		}
	else
		{
		if (target->IsObjective())
			{
			// Ground assault
			newEvent->dataBlock.data.formatId = 1806;
			}
		else if (target->GetDomain() == DOMAIN_AIR)
			{
			// Air defenses firing
			newEvent->dataBlock.data.formatId = 1801;
			}
		else
			{
			// Ground engagement (artillery or regular)
			if (shooter->GetSType() == STYPE_UNIT_ROCKET || shooter->GetSType() == STYPE_UNIT_SP_ARTILLERY || shooter->GetSType() == STYPE_UNIT_TOWED_ARTILLERY)
				newEvent->dataBlock.data.formatId = 1807;
			else
				newEvent->dataBlock.data.formatId = 1800;
			}
		}
	SendCampUIMessage(newEvent);

	// Send a CampEvent message for losses to the LOCAL MACHINE
	if (target->IsFlight() && losses)
		{
		FalconCampEventMessage	*newEvent = new FalconCampEventMessage(target->Id(),FalconLocalGame);
		newEvent->dataBlock.team = GetEnemyTeam(target->GetTeam());
		newEvent->dataBlock.eventType = FalconCampEventMessage::campLosses;
		target->GetLocation(&newEvent->dataBlock.data.xLoc,&newEvent->dataBlock.data.yLoc);
		newEvent->dataBlock.data.formatId = 1825;
		// 2002-02-21 ADDED BY S.G. If it's not spotted and it's NOT the player, use the 'Bandit' vehicle so we don't warn the player on the identity of the shooter
		if (!target->GetIdentified(shooter->GetTeam()) && FalconLocalSession->GetTeam() != target->GetTeam())
			newEvent->dataBlock.data.textIds[0] = (short)(-1 * BANDIT_VEH);
		else
		// END OF ADDED SECTION 2002-02-21
			newEvent->dataBlock.data.textIds[0] = (short)(-1 * ((Unit)target)->GetVehicleID(0));
		newEvent->dataBlock.data.owners[0] = target->GetOwner();
		SendCampUIMessage(newEvent);
		}

	if(gMainHandler && FalconLocalSession->GetPlayerSquadron() && target->Id() == FalconLocalSession->GetPlayerSquadron()->GetUnitAirbaseID())
		PostMessage(FalconDisplay.appWin,FM_AIRBASE_ATTACK,0,0);

	return 0;
	}
Beispiel #15
0
void CGameStateRecorder::OnGameplayEvent(IEntity *pEntity, const GameplayEvent &event)
{
	EntityId id;
	if(!pEntity || !(id = pEntity->GetId()))
	{
		GameWarning("TimeDemo:GameState::OnGamePlayEvent: Entity not found");
		return;
	}
	CActor *pActor = (CActor*)(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id));
	if(!pActor)
	{
		GameWarning("TimeDemo:GameState::OnGamePlayEvent: Entity %s has no actor", pEntity->GetName());
		return;
	}

	GameplayEvent  event2 = event;
	event2.extra = 0;// event2 is the forwarded event, extra either will be not used by the listener or re-set as a string
	uint8 eType = event.event;

	bool bPlayer = (pActor->IsPlayer() && m_mode);
	if(bPlayer || m_mode==GPM_AllActors)
	{
		//items
		switch(eType)
		{
			case eGE_ItemPickedUp:
				{
					CheckInventory(pActor,0);//,*m_pRecordGameEventFtor);
				}
				break;

			case eGE_ItemDropped:
				{
					TItemName itemName = GetItemName(EntityId(event.extra));
					if(!itemName ) //if(itemIdx < 0)
						break;
					event2.description = itemName;
					SendGamePlayEvent(pEntity,event2);
					IEntity* pItemEntity = gEnv->pEntitySystem->FindEntityByName(itemName);
					if(!pItemEntity)
						break;
					IItem* pItem = g_pGame->GetIGameFramework()->GetIItemSystem()->GetItem(pItemEntity->GetId());
					if(!pItem)
						break;

					IEntityClass* pItemClass = pItem->GetEntity()->GetClass();
					if(pItemClass && !strcmpi(pItemClass->GetName(),"SOCOM"))
					{
						IItem* pCurrentItem = pActor->GetCurrentItem();
						if(pCurrentItem)
						{
							IEntityClass* pCurrentItemClass = pCurrentItem->GetEntity()->GetClass();
							if(pCurrentItemClass && !strcmpi(pCurrentItemClass->GetName(),"SOCOM"))
							{
								GameplayEvent event3;
								event3.event = eGE_ItemSelected;
								TItemName itemName = GetItemName(pCurrentItem->GetEntity()->GetId());
								if(!itemName)
									break;
								event3.value = 0;
								event3.description = (const char*)itemName;
								SendGamePlayEvent(pEntity,event3);
							}
						}
					}
				}
				break;

			case eGE_WeaponFireModeChanged:
				{
					TItemName itemIdx = GetItemName(EntityId(event.extra));
					if(!itemIdx)//if(itemIdx < 0)
						break;
					event2.description = (const char*)itemIdx;
					SendGamePlayEvent(pEntity,event2);
				}
				break;

			case eGE_ItemSelected:
				{
					EntityId itemId = EntityId(event.extra);
					TItemName itemIdx = GetItemName(itemId);
					if(itemId && !itemIdx)
						break;
					event2.value = 0;
					event2.description = (const char*)itemIdx;
					SendGamePlayEvent(pEntity,event2);
				}
				break;

			case eGE_AttachedAccessory:
				{
					if(!IsGrenade(event.description)) // NOT OffHandGrenade
						SendGamePlayEvent(pEntity,event2);
				}
				break;

			case eGE_AmmoCount:
				{
					const char* itemIdx = event.description;
					if(!itemIdx)
						break;

					TGameStates::iterator itGS;
					/*if(pActor->IsPlayer())
						itGS = m_itSingleActorGameState;
					else */if(pActor->GetEntity())
						itGS = m_GameStates.find(pActor->GetEntity()->GetId());
					else
						break;

					if(itGS == m_GameStates.end())
						break;

					SActorGameState& gstate = itGS->second;

					IEntity* pItemEntity = gEnv->pEntitySystem->FindEntityByName(itemIdx);
					if(!pItemEntity)
						break;
					IItem* pItem = g_pGame->GetIGameFramework()->GetIItemSystem()->GetItem(pItemEntity->GetId());
					if(!pItem)
						break;

					CWeapon* pWeapon = (CWeapon*)(pItem->GetIWeapon());
					if(pWeapon && pWeapon->GetEntity())
					{
						TItemContainer::iterator it = gstate.Items.find(itemIdx);
						if(it==gstate.Items.end())
							break;
						SItemProperties& recItem = it->second;
						
						SWeaponAmmo weaponAmmo = pWeapon->GetFirstAmmo();
						bool bGrenade = false;
						if(!weaponAmmo.pAmmoClass)
						{
							// special case for grenades
							if(IsAmmoGrenade((const char*)(event.extra)))
							{
								weaponAmmo.pAmmoClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass((const char*)event.extra);
								weaponAmmo.count = (int)event.value;
								bGrenade = true;
							}
						}
						
						for(; weaponAmmo.pAmmoClass ; weaponAmmo = pWeapon->GetNextAmmo())
						{
							int ammoCount = weaponAmmo.count;
							const char* ammoClass;
							if(weaponAmmo.pAmmoClass && (ammoClass = weaponAmmo.pAmmoClass->GetName()))
							{
								TAmmoContainer& recAmmo = bGrenade? gstate.AmmoMags : recItem.Ammo;
								if(recAmmo.find(ammoClass) == recAmmo.end())
									recAmmo.insert(std::make_pair(ammoClass,0));
								if(ammoCount != recAmmo[ammoClass])
								{
									event2.event = eGE_AmmoCount;
									event2.value = (float)ammoCount;
									if(event2.value < 0)
										event2.value = 0;
									event2.extra = (void*)ammoClass;
									event2.description = (const char*)itemIdx;
									SendGamePlayEvent(pEntity,event2);
								}
							}
						}
					}

				}
				break;

			case eGE_EntityGrabbed:
				{
					EntityId entityId = EntityId(event.extra);
					IEntity * pGrabbedEntity = gEnv->pEntitySystem->GetEntity(entityId);
					if(pGrabbedEntity)
					{
						event2.description = pGrabbedEntity->GetName();
						SendGamePlayEvent(pEntity,event2);
					}
				}
				break;

			case eGE_WeaponReload:
			case eGE_ZoomedIn:
			case eGE_ZoomedOut:			
			case eGE_HealthChanged:
			case eGE_ItemExchanged:
				SendGamePlayEvent(pEntity,event2);
				break;

			default:
				break;
		}

	}
}
int FalconATCMessage::Process(uchar autodisp)
{
	AircraftClass *aircraft = (AircraftClass*)vuDatabase->Find(dataBlock.from );
	ObjectiveClass *atc = (ObjectiveClass*)vuDatabase->Find(EntityId());
	runwayQueueStruct *info = NULL;
	FalconRadioChatterMessage *radioMessage = NULL;
	
	if (autodisp)
		return 0;

	float cosAngle=0.0F, dx=0.0F, dy=0.0F, finalHdg=0.0F;
	float finalX=0.0F, finalY=0.0F, baseX=0.0F, baseY=0.0F, x=0.0F ,y=0.0F,z=0.0F, dist=0.0F;
	int	taxiPoint=0, tod=0, time_in_minutes=0;
	int delay = 7 * CampaignSeconds;
	if (!PlayerOptions.PlayerRadioVoice)
	    delay = 500;

	if (aircraft && aircraft->IsAirplane())
	{      
		DigitalBrain *acBrain = aircraft->DBrain();
		ATCBrain*	atcBrain = NULL;

		if(atc)
		{
			atcBrain = atc->brain;
			dx = aircraft->XPos() - atc->XPos();
			dy = aircraft->YPos() - atc->YPos();
			dist = dx*dx + dy*dy;
		}

		switch (dataBlock.type)
		{
		case ContactApproach:
        case RequestClearance:
			if(!aircraft->IsPlayer() || !aircraft->IsLocal())
			{
				if(aircraft->pctStrength < STRENGTH_PCT_FOR_EMERG_LDG)
					SendCallToATC(aircraft, EntityId(), rcLANDCLEAREMERGENCY, FalconLocalSession);
				else
					SendCallToATC(aircraft, EntityId(), rcLANDCLEARANCE, FalconLocalSession);
			}
			
			if(atcBrain && atc->IsLocal())
			{
				info = atcBrain->InList(aircraft->Id());
				if( info )
				{
					cosAngle = atcBrain->DetermineAngle(aircraft, acBrain->Runway(), lOnFinal);

					//if(info->status >= tReqTaxi)
					//if(info->status < tReqTaxi) // JB 010802 RTBing AI aircraft won't land. This compare was messed up.  Right? I hope so.
					if(info->status >= tReqTaxi) // JB It appears to work but this was called a bit much for my comfort level. We'll try another approach.
					{
						if(!aircraft->OnGround())
						{
							if(dist < (TOWER_RANGE + 100) * NM_TO_FT * NM_TO_FT)
							{
								if(!aircraft->IsPlayer() && aircraft->pctStrength < STRENGTH_PCT_FOR_EMERG_LDG)
									atcBrain->RequestEmerClearance(aircraft);
								else
									atcBrain->RequestClearance(aircraft);
							}
							else if(dist < APPROACH_RANGE * NM_TO_FT * NM_TO_FT && dist >= (TOWER_RANGE + 100) * NM_TO_FT * NM_TO_FT)
							{
								if(!aircraft->IsPlayer() && aircraft->GetCampaignObject()->GetComponentLead() == aircraft)
									HandleInboundFlight( atc, (Flight)aircraft->GetCampaignObject());
								else
									HandleInbound(atc, aircraft);			
							}
							else
							{
								//note this comm should be rcOUTSIDEAIRSPACE, but Joe misnamed it
								radioMessage = CreateCallFromATC(atc, aircraft, rcOUTSIDEAIRSPEED, FalconLocalGame);
								radioMessage->dataBlock.edata[4]	= (short)(rand()%2);
								radioMessage->dataBlock.time_to_play= delay;
								atcBrain->RemoveTraffic(aircraft->Id(), PtHeaderDataTable[info->rwindex].runwayNum);
							}
							info->lastContacted = SimLibElapsedTime;
						}
						break;
					}
					else if(info->rwindex)
					{
						switch(info->status)
						{
						case noATC:

						case lReqClearance:
						case lReqEmerClearance:

						case lIngressing:
						case lTakingPosition:
							ShiWarning("This should never happen!");
							radioMessage = CreateCallFromATC(atc, aircraft, rcCONTINUEINBOUND1, FalconLocalGame);
							//M.N. changed to 32767 -> flexibly use randomized value of max available eval indexes
							radioMessage->dataBlock.edata[4]	= 32767;
							radioMessage->dataBlock.edata[5]	= (short)atcBrain->GetRunwayName(atcBrain->GetOppositeRunway(info->rwindex));
							if(rand()%2)
								radioMessage->dataBlock.edata[6]	= 4;
							else
								radioMessage->dataBlock.edata[6]	= -1;
							break;

						case lAborted:
							atcBrain->FindAbortPt(aircraft, &x, &y, &z);
							radioMessage = CreateCallFromATC (atc, aircraft, rcATCGOAROUND, FalconLocalSession);
					
							atcBrain->CalculateStandRateTurnToPt(aircraft, x, y, &finalHdg);
							radioMessage->dataBlock.edata[3] = (short)FloatToInt32(finalHdg);
							//M.N. changed to 32767 -> flexibly use randomized value of max available eval indexes
							radioMessage->dataBlock.edata[4] = 32767;
							break;

						case lEmerHold:
						case lHolding:
							radioMessage = CreateCallFromATC (atc, aircraft, rcATCORBIT2, FalconLocalGame);
							radioMessage->dataBlock.edata[2] = -1; //altitude in thousands
							radioMessage->dataBlock.edata[3] = -1; //altitude in thousands
							break;

						case lFirstLeg:
						case lToBase:
						case lToFinal:
							radioMessage = CreateCallFromATC(atc, aircraft, rcATCLANDSEQUENCE, FalconLocalGame);
							radioMessage->dataBlock.edata[4] = (short)atcBrain->GetLandingNumber(info);
							//atcBrain->SendCmdMessage(aircraft, info);
							break;

						case lOnFinal:
						case lClearToLand:
							if(aircraft->DBrain()->IsSetATC(DigitalBrain::ClearToLand))
							{
								radioMessage = CreateCallFromATC (atc, aircraft, rcCLEAREDLAND, FalconLocalGame);
								radioMessage->dataBlock.edata[4] = (short)atcBrain->GetRunwayName(atcBrain->GetOppositeRunway(acBrain->Runway()));
							}
							else
							{
								radioMessage = CreateCallFromATC(atc, aircraft, rcATCLANDSEQUENCE, FalconLocalGame);
								radioMessage->dataBlock.edata[4] = (short)atcBrain->GetLandingNumber(info);
							}
							break;

						case lLanded:
							radioMessage = CreateCallFromATC (atc, aircraft, rcTAXICLEAR, FalconLocalGame);
							break;

						case lTaxiOff:
							//there isn't anything better to say, oh well :)
							radioMessage = CreateCallFromATC (atc, aircraft, rcTAXICLEAR, FalconLocalGame);
							break;

						case lEmergencyToBase:
						case lEmergencyToFinal:
						case lEmergencyOnFinal:
							atcBrain->RequestClearance(aircraft);
							return 1;
							break;

						case lCrashed:
							radioMessage = CreateCallFromATC (atc, aircraft, rcCLEAREDEMERGLAND, FalconLocalGame);
							radioMessage->dataBlock.edata[3] = -1;

							radioMessage->dataBlock.edata[4] = -1;
							//M.N. changed to 32767 -> flexibly use randomized value of max available eval indexes
							radioMessage->dataBlock.edata[5] = 32767;
							break;
						}
					}
					else
					{
						radioMessage = CreateCallFromATC(atc, aircraft, rcCONTINUEINBOUND2, FalconLocalGame);

						if(rand()%2)
						{
							radioMessage->dataBlock.edata[3]	= (short)(rand()%3);
						}
						else
						{
							time_in_minutes =  TheCampaign.GetMinutesSinceMidnight();
							if (time_in_minutes < 180)//3am
								tod = 1;
							else if(time_in_minutes < 720 )//noon
								tod = 0;
							else if(time_in_minutes < 1020 ) //5pm
								tod = 2;
							else
								tod = 1;

							radioMessage->dataBlock.edata[3]	= (short)(3 + tod + (rand()%3)*3);
						}

						if(rand()%2)
							radioMessage->dataBlock.edata[4]	= 4;
						else
							radioMessage->dataBlock.edata[4]	= -1;

						atcBrain->SendCmdMessage(aircraft, info);
					}
					if (radioMessage)
					{
						info->lastContacted = SimLibElapsedTime;
						if (PlayerOptions.PlayerRadioVoice)
						    radioMessage->dataBlock.time_to_play= 2 * CampaignSeconds;
						else 
						    radioMessage->dataBlock.time_to_play= delay;
						FalconSendMessage(radioMessage, TRUE);
					}
				}
				else
				{
					if(dist <= (TOWER_RANGE + 100) * NM_TO_FT * NM_TO_FT)
					{
						if(aircraft->GetCampaignObject()->GetComponentLead() == aircraft)
						{
							AircraftClass *element = NULL;
							Flight flight = (Flight)aircraft->GetCampaignObject();
							VuListIterator	flightIter(flight->GetComponents());

							element = (AircraftClass*) flightIter.GetFirst();
							while(element)
							{
								runwayQueueStruct *tempinfo = atcBrain->InList(element->Id());
								if(!tempinfo)
								{
									if( !element->IsPlayer() && element->pctStrength < STRENGTH_PCT_FOR_EMERG_LDG)
									{
										SendCallToATC(element, EntityId(), rcLANDCLEAREMERGENCY, FalconLocalGame);
										atcBrain->RequestEmerClearance(element);
									}
									else
										atcBrain->RequestClearance(element);
								}
								element = (AircraftClass*) flightIter.GetNext();
							}
						}
						else
						{
							if(!aircraft->IsPlayer() && aircraft->pctStrength < STRENGTH_PCT_FOR_EMERG_LDG)
							{
								SendCallToATC(aircraft, EntityId(), rcLANDCLEAREMERGENCY, FalconLocalGame);
								atcBrain->RequestEmerClearance(aircraft);
							}
							else
								atcBrain->RequestClearance(aircraft);
						}
					}
					else if(dist < APPROACH_RANGE * NM_TO_FT * NM_TO_FT && dist > (TOWER_RANGE + 100) * NM_TO_FT * NM_TO_FT)
					{
						if(aircraft->GetCampaignObject()->GetComponentLead() == aircraft)
							HandleInboundFlight( atc, (Flight)aircraft->GetCampaignObject());
						else
							HandleInbound(atc, aircraft);						
					}
					else
					{
						//note this comm should be rcOUTSIDEAIRSPACE, but Joe misnamed it
						radioMessage = CreateCallFromATC(atc, aircraft, rcOUTSIDEAIRSPEED, FalconLocalGame);
						radioMessage->dataBlock.edata[4]	= (short)(rand()%2);
						radioMessage->dataBlock.time_to_play= delay;
						FalconSendMessage(radioMessage, TRUE);
					}
				}
			}
			break;
			
        case RequestEmerClearance:
			if(!aircraft->IsPlayer() || !aircraft->IsLocal())
				SendCallToATC(aircraft, EntityId(), rcLANDCLEAREMERGENCY, FalconLocalSession);
			if(atcBrain && atc->IsLocal())
				atcBrain->RequestEmerClearance(aircraft);			
			break;
		
        case RequestTakeoff:
			if(!aircraft->IsPlayer() || !aircraft->IsLocal())
				SendCallToATC(aircraft, EntityId(), rcREADYFORDERARTURE, FalconLocalSession);
			if(atcBrain && atc->IsLocal())
				atcBrain->RequestTakeoff(aircraft);
			break;
			
        case RequestTaxi:
			if(!aircraft->IsPlayer() || !aircraft->IsLocal())
				SendCallToATC(aircraft, EntityId(), rcREADYFORDERARTURE, FalconLocalSession);
			if(atcBrain && atc->IsLocal())
				atcBrain->RequestTaxi(aircraft);
			break;
// M.N. 2001-12-20
		case AbortApproach:
			if(!aircraft->IsPlayer() || !aircraft->IsLocal())
				SendCallToATC(aircraft, EntityId(), rcABORTAPPROACH, FalconLocalSession);
				atcBrain->AbortApproach(aircraft);//Cobra
			if (atcBrain && atc->IsLocal())
				atcBrain->AbortApproach(aircraft);
			break;

// RAS - 22Jan04 - Set flag for traffic in sight call 
		case TrafficInSight:
			if(!aircraft->IsPlayer() || !aircraft->IsLocal())
				SendCallToATC(aircraft, EntityId(), rcCOPY, FalconLocalSession);
			if (atcBrain && atc->IsLocal())
				atcBrain->trafficInSightFlag = TRUE;
			break;
// TJL 08/16/04 - Set flag for Hotpit Refueling //Cobra 10/31/04 TJL
 		case RequestHotpitRefuel:
			if(!aircraft->IsPlayer() || !aircraft->IsLocal())
 				SendCallToATC(aircraft, EntityId(), rcCOPY, FalconLocalSession);
				aircraft->requestHotpitRefuel = TRUE; //Cobra 11/13/04 TJL will this make online work?
 			if (atcBrain && atc->IsLocal())
 				aircraft->requestHotpitRefuel = TRUE;
 			break;


		case UpdateStatus:
			if(atcBrain)
			{
				if(atc->IsLocal())
				{
					info = atcBrain->InList(aircraft->Id());
					if(info)
					{
						switch(dataBlock.status)
						{
						case noATC:
							if(info->rwindex)
								atcBrain->RemoveTraffic(aircraft->Id(), PtHeaderDataTable[info->rwindex].runwayNum);
							else
								atcBrain->RemoveInbound(info);
							break;
						case lReqClearance:
						case lReqEmerClearance:
						case tReqTaxi:
						case tReqTakeoff:
						case lIngressing:
						case lTakingPosition:
							break;
						case tFlyOut:
							info->lastContacted = SimLibElapsedTime;
							info->status = noATC;
							break;
						case lCrashed:
							info->lastContacted = SimLibElapsedTime;
							info->status = lCrashed;
							{
								atcBrain->RemoveFromAllOtherATCs(aircraft);
								int Runway = atcBrain->IsOverRunway(aircraft);
								if(GetQueue(Runway) != GetQueue(info->rwindex))
								{
									atcBrain->RemoveTraffic(aircraft->Id(), GetQueue(info->rwindex));
									atcBrain->AddTraffic(aircraft->Id(), lCrashed, Runway, SimLibElapsedTime);
								}
								atcBrain->FindNextEmergency(GetQueue(Runway));
								atcBrain->SetEmergency(GetQueue(Runway));
							}
							break;
						default:
							info->lastContacted = SimLibElapsedTime;
							info->status = (AtcStatusEnum)dataBlock.status;
							break;
						}
					}
					else
					{
						//he thinks we already know about him, orig owner of atc must have dropped
						//offline, so we need to put him into the appropriate list
						switch(dataBlock.status)
						{
							case lIngressing:
								break;
							case lTakingPosition:
							case lAborted:
							case lEmerHold:
							case lHolding:
							case lFirstLeg:
							case lToBase:
							case lToFinal:
							case lOnFinal:
							case lLanded:
							case lTaxiOff:
							case lEmergencyToBase:
							case lEmergencyToFinal:
							case lEmergencyOnFinal:
							case lClearToLand:
								atcBrain->RequestClearance(aircraft);			
								break;
							case lCrashed:
								{
									atcBrain->RemoveFromAllOtherATCs(aircraft);
									int Runway = atcBrain->IsOverRunway(aircraft);
									atcBrain->AddTraffic(aircraft->Id(), lCrashed, Runway, SimLibElapsedTime);
									atcBrain->FindNextEmergency(GetQueue(Runway));
									atcBrain->SetEmergency(GetQueue(Runway));
								}
								break;
							case tEmerStop:
							case tTaxi:
							case tHoldShort:
							case tPrepToTakeRunway:
							case tTakeRunway:
							case tTakeoff:
								atcBrain->RequestTaxi(aircraft);
								break;
							case tFlyOut:
								break;
							default:
								break;
						}
					}
				}

				//update track point, taxi point, timer, status, etc...
				switch(dataBlock.status)
				{
				case noATC:
					break;
				case lClearToLand:
					break;
				case lIngressing:
				case lTakingPosition:
					atcBrain->FindFinalPt(aircraft, acBrain->Runway(), &x, &y);
					acBrain->SetTrackPoint(x, y, atcBrain->GetAltitude(aircraft, lTakingPosition));
					break;
				case lEmerHold:
				case lHolding:
					acBrain->SetTrackPoint(aircraft->XPos(), aircraft->YPos(), atcBrain->GetAltitude(aircraft, lHolding));
					break;

				case lFirstLeg:				
					if(acBrain->ATCStatus() != lFirstLeg && acBrain->ATCStatus() <= lOnFinal)
					{
						atcBrain->FindFinalPt(aircraft, acBrain->Runway(), &finalX, &finalY);
						cosAngle = atcBrain->DetermineAngle(aircraft, acBrain->Runway(), lFirstLeg);
						if(cosAngle < 0.0F)
						{
							atcBrain->FindBasePt(aircraft, acBrain->Runway(), finalX, finalY, &baseX, &baseY);
							atcBrain->FindFirstLegPt(aircraft, acBrain->Runway(), acBrain->RwTime(), baseX, baseY, TRUE, &x, &y);
						}
						else
						{
							atcBrain->FindFirstLegPt(aircraft, acBrain->Runway(), acBrain->RwTime(), finalX, finalY, FALSE, &x, &y);
						}

						acBrain->SetATCStatus(lFirstLeg);
						acBrain->SetTrackPoint(x, y, atcBrain->GetAltitude(aircraft, lFirstLeg));
						acBrain->CalculateNextTurnDistance();
					}

					if( !aircraft->IsPlayer() )
					{
						atcBrain->MakeVectorCall(aircraft, FalconLocalSession);
					}
					break;

				case lToBase:
					if(acBrain->ATCStatus() != lToBase && acBrain->ATCStatus() <= lOnFinal)
					{
						atcBrain->FindFinalPt(aircraft, acBrain->Runway(), &finalX, &finalY);
						atcBrain->FindBasePt(aircraft, acBrain->Runway(), finalX, finalY, &baseX, &baseY);
						acBrain->SetATCStatus(lToBase);
						acBrain->SetTrackPoint(baseX, baseY, atcBrain->GetAltitude(aircraft, lToBase));
						acBrain->CalculateNextTurnDistance();
					}

					if( !aircraft->IsPlayer() )
					{
						atcBrain->MakeVectorCall(aircraft, FalconLocalSession);
					}
					break;

				case lToFinal:
					if(acBrain->ATCStatus() != lToFinal && acBrain->ATCStatus() <= lOnFinal)
					{
						atcBrain->FindFinalPt(aircraft, acBrain->Runway(), &finalX, &finalY);
						acBrain->SetATCStatus(lToFinal);
						acBrain->SetTrackPoint(finalX, finalY, atcBrain->GetAltitude(aircraft, lToFinal));
						acBrain->CalculateNextTurnDistance();
					}

					if( !aircraft->IsPlayer() )
					{
						atcBrain->MakeVectorCall(aircraft, FalconLocalSession);
					}
					break;

				case lOnFinal:
					TranslatePointData (atc, GetFirstPt(acBrain->Runway()), &x, &y);
					//if we sent the message we already know this				
					if(acBrain->ATCStatus() != lOnFinal && acBrain->ATCStatus() <= lOnFinal)
					{						
						acBrain->SetATCStatus(lOnFinal);
						acBrain->SetTrackPoint(x, y, atcBrain->GetAltitude(aircraft, lOnFinal));
						acBrain->CalculateNextTurnDistance();
					}

					if( !aircraft->IsPlayer() )
					{
						radioMessage = CreateCallFromATC (atc, aircraft, rcTURNTOFINAL, FalconLocalSession);
#if 0
						//MI Turn final for AI fix
						if(atcBrain->CalculateStandRateTurnToPt(aircraft, x, y, &finalHdg) > 0)
							radioMessage->dataBlock.edata[2] = 1;
						else
							radioMessage->dataBlock.edata[2] = 0;
#else
						if(atcBrain->CalculateStandRateTurnToPt(aircraft, x, y, &finalHdg) > 0)
							radioMessage->dataBlock.edata[2] = 0;
						else
							radioMessage->dataBlock.edata[2] = 1;
#endif	
						finalHdg = PtHeaderDataTable[acBrain->Runway()].data + 180.0F;
						if(finalHdg > 360)
							finalHdg -= 360;

						radioMessage->dataBlock.edata[3] = (short)FloatToInt32(finalHdg);
						//M.N. changed to 32767 -> flexibly use randomized value of max available eval indexes
						radioMessage->dataBlock.edata[4] = 32767; //vector type
						FalconSendMessage(radioMessage, TRUE);
					}
					break;


				case lLanded:
					//if we sent the message we already know this	
					if(acBrain->ATCStatus() != lLanded)
					{
						acBrain->SetATCStatus(lLanded);
						taxiPoint = GetFirstPt(acBrain->Runway());
						TranslatePointData (atc,GetNextPt(taxiPoint) , &x, &y);
						acBrain->SetTrackPoint(x, y, atcBrain->GetAltitude(aircraft, lLanded));
					}
					break;

				case lTaxiOff:
					break;

				case lAborted:					
					if(acBrain->ATCStatus() != lAborted)
					{
						atcBrain->FindAbortPt(aircraft, &x, &y, &z);
						acBrain->SetATCStatus(lAborted);					
						acBrain->SetTrackPoint(x, y, z);
					}

					if(atc->IsLocal())
					{
						atcBrain->RemoveTraffic(aircraft->Id(), PtHeaderDataTable[acBrain->Runway()].runwayNum);
					}
					break;

				case lEmergencyToBase:
					if(acBrain->ATCStatus() != lEmergencyToBase)
					{
						atcBrain->FindFinalPt(aircraft, acBrain->Runway(), &finalX, &finalY);
						atcBrain->FindBasePt(aircraft, acBrain->Runway(), finalX, finalY, &baseX, &baseY);
						acBrain->SetATCStatus(lEmergencyToBase);
						acBrain->SetTrackPoint(baseX, baseY, atcBrain->GetAltitude(aircraft, lEmergencyToBase));
					}
					break;

				case lEmergencyToFinal:
					if(acBrain->ATCStatus() != lEmergencyToFinal)
					{
						atcBrain->FindFinalPt(aircraft, acBrain->Runway(), &finalX, &finalY);
						acBrain->SetATCStatus(lEmergencyToFinal);
						acBrain->SetTrackPoint(finalX, finalY, atcBrain->GetAltitude(aircraft, lEmergencyToFinal));
					}
					break;

				case lEmergencyOnFinal:
					if(acBrain->ATCStatus() != lEmergencyOnFinal)
					{
						TranslatePointData (atc, GetFirstPt(acBrain->Runway()), &x, &y);
						acBrain->SetATCStatus(lEmergencyOnFinal);
						acBrain->SetTrackPoint(x, y, atcBrain->GetAltitude(aircraft, lEmergencyOnFinal));
					}
					break;

				case lCrashed:
					acBrain->SetATCStatus(lCrashed);
					break;

				case tEmerStop:
					acBrain->SetATCStatus(tEmerStop);
					break;

				case tTaxi:
					if(acBrain->ATCStatus() != tTaxi)
					{
						acBrain->SetATCStatus(tTaxi);
						TranslatePointData (atc,acBrain->GetTaxiPoint() , &x, &y);
						acBrain->SetTrackPoint(x, y, atcBrain->GetAltitude(aircraft, tTaxi));
					}
					break;

				case tHoldShort:
					acBrain->ClearATCFlag(DigitalBrain::PermitRunway);
					acBrain->ClearATCFlag(DigitalBrain::PermitTakeoff);

					if(acBrain->ATCStatus() != tHoldShort)
					{
						acBrain->SetATCStatus(tHoldShort);
						taxiPoint = GetFirstPt(acBrain->Runway());
						taxiPoint = GetNextPt(taxiPoint);
						TranslatePointData (atc,taxiPoint , &x, &y);
						acBrain->SetTrackPoint(x, y, atcBrain->GetAltitude(aircraft, tHoldShort));
					}
					break;

				case tPrepToTakeRunway:
					acBrain->SetATCFlag(DigitalBrain::PermitTakeRunway);
					if(acBrain->ATCStatus() != tTaxi)
					{
						acBrain->SetATCStatus(tTaxi);
						if(PtDataTable[acBrain->GetTaxiPoint()].type == TakeoffPt)
							atcBrain->FindTakeoffPt((Flight)aircraft->GetCampaignObject(), aircraft->vehicleInUnit, acBrain->Runway(), &x, &y);
						else
							TranslatePointData (atc,acBrain->GetTaxiPoint() , &x, &y);
						acBrain->SetTrackPoint(x, y, atcBrain->GetAltitude(aircraft, tTaxi));
					}
					break;

				case tTakeRunway:
					if(acBrain->ATCStatus() != tTakeRunway)
					{
						acBrain->SetATCFlag(DigitalBrain::PermitTakeRunway);
						acBrain->SetATCStatus(tTakeRunway);
						atcBrain->FindTakeoffPt((Flight)aircraft->GetCampaignObject(), aircraft->vehicleInUnit, acBrain->Runway(), &x, &y);
						acBrain->SetTrackPoint(x, y, atcBrain->GetAltitude(aircraft, tTakeRunway));
					}
					break;

				case tTakeoff:
					if(acBrain->ATCStatus() != tTakeoff)
					{
						acBrain->SetATCFlag(DigitalBrain::PermitRunway);
						acBrain->SetATCFlag(DigitalBrain::PermitTakeoff);
						acBrain->SetATCStatus(tTakeRunway);
						atcBrain->FindRunwayPt((Flight)aircraft->GetCampaignObject(), aircraft->vehicleInUnit, acBrain->Runway(), &x, &y);
						acBrain->SetTrackPoint(x, y, atcBrain->GetAltitude(aircraft, tTakeRunway));
					}
					break;

				case tTaxiBack:
					if(acBrain->ATCStatus() != tTaxiBack)
					{
						acBrain->SetATCStatus(tTaxiBack);
					}
					break;

				case tFlyOut:
					if(acBrain->ATCStatus() != tFlyOut)
					{
						acBrain->ResetATC();
					}
				default:
					break;
				}
			}
			break;
		}
	}
	return 1;
}
int FalconFACMessage::Process(uchar autodisp)
{
SimVehicleClass* theEntity;
SimVehicleClass* theFighter;

	if (autodisp)
		return 0;

   theEntity = (SimVehicleClass*)Entity();
   if (!theEntity)
      theEntity = (SimVehicleClass*)(vuDatabase->Find (EntityId()));
   theFighter = (SimVehicleClass*)(vuDatabase->Find (dataBlock.caller));

   if(!theFighter) // PJW: E3 Hack... make sure (theFighter) is valid
	   return 0;

   switch (dataBlock.type)
   {
      case CheckIn:
         if (theEntity && theEntity->IsLocal())
            ((FACBrain*)theEntity->Brain())->AddToQ(theFighter);

         // Play message here
         if (theFighter != SimDriver.playerEntity)
         {
         }
      break;

      case Wilco:
         // Play message here
         if (theFighter != SimDriver.playerEntity)
         {
         }
      break;

      case Unable:
         // Play message here
         if (theFighter != SimDriver.playerEntity)
         {
         }
      break;

      case In:
         // Play message here
         if (theFighter != SimDriver.playerEntity)
         {
         }
      break;

      case Out:
         // Play message here
         if (theFighter != SimDriver.playerEntity)
         {
         }
      break;

      case RequestMark:
      break;

      case RequestTarget:
         if (theEntity && theFighter && theEntity->IsLocal())
            ((FACBrain*)theEntity->Brain())->RequestTarget(theFighter);
      break; 

      case RequestBDA:
         if (theEntity && theFighter && theEntity->IsLocal())
            ((FACBrain*)theEntity->Brain())->RequestBDA(theFighter);
      break;

      case RequestLocation:
         if (theEntity && theEntity->IsLocal())
            ((FACBrain*)theEntity->Brain())->RequestLocation();
      break;

      case RequestTACAN:
         if (theEntity && theEntity->IsLocal())
            ((FACBrain*)theEntity->Brain())->RequestTACAN();
      break;

      case HoldAtCP:
      break;

      case FacSit:
      break;

      case Mark:
      break;

      case NoTargets:
      break;

      case GroundTargetBr:
      break;

      case BDA:
      break;

      case NoBDA:
      break;

      case ReattackQuery:
         if (theFighter && theFighter->IsLocal())
         {
         }
      break;

      case HartsTarget:
      break;

      case HartsOpen:
         if (theFighter && theFighter->IsLocal())
         {
         }
      break;

      case ScudLaunch:
      break;

      case SanitizeLZ:
      break;

      case AttackMyTarget:
         if (theFighter && theFighter->IsLocal())
         {
         }
      break;

      case SendChoppers:
      break;
   };

   return 0;
}