//////////////////////////////////////////////////////////////////////////////
//
// AVP_ServerEntity_Team_Marine.cpp
//
// Copyright (C) 2007 Rebellion. All Rights Reserved.
//
//////////////////////////////////////////////////////////////////////////////

// I N C L U D E S ///////////////////////////////////////////////////////////

// core
#include "Core/Asura.h"

// header
#include "Entity/Controller/AVP_ServerEntity_Team_Marine.h"

// asura
#include "Blueprint/Asura_Blueprint.h"
#include "Blueprint/Asura_Blueprint_System.h"
#include "ChunkSystem/Asura_Chunk_Stream.h"
#include "Core/Asura_Timers.h"
#include "Network/Asura_Message.h"

// avp
#include "Entity/AVP_Entity_Classification.h"
#include "Entity/AVP_Messages.h"
#include "Entity/Controller/AVP_Controller_Messages.h"
#include "Entity/Controller/AVP_ServerEntity_Squad_Marine.h"
#include "Entity/GamePlayVolume/AVP_ServerEntity_GamePlayVolume.h"
#include "Entity/PhysicalObject/Actor/AVP_ServerEntity_Actor.h"
#include "Entity/PlayerInfo/AVP_ServerEntity_PlayerInfo.h"
#include "Entity/Spawners/Human/AVP_ServerEntity_HumanSpawnPoint.h"
#include "Entity/PhysicalObject/Actor/Vertebrates/Human/Android/AVP_ServerActor_Android.h"
#include "Entity/PhysicalObject/Actor/Vertebrates/Human/Civilian/AVP_ServerActor_Civilian.h"
#include "Entity/PhysicalObject/Actor/Vertebrates/Human/Marine/AVP_ServerActor_Marine.h"

// axon
#include "Core/BrainTypes/AVP_Brain_Actor_Civilian.h"
#include "Core/BrainTypes/AVP_Brain_Actor_Marine.h"
#include "Core/BrainTypes/AVP_Brain_Team_Marine.h"
#include "Knowledge/AVP_Knowledge_System_Actor.h"
#include "Knowledge/SenseTypes/AVP_Sense_Vision_Actor.h"

//////////////////////////////////////////////////////////////////////////////
//
// AVP_ServerEntity_Team_Marine
//
//////////////////////////////////////////////////////////////////////////////

AVP_ServerEntity_Team_Marine* AVP_ServerEntity_Team_Marine::s_pxMarineTeam = NULL;


//--------------------------------------------------------------------------------------
//	Function	:	AVP_ServerEntity_Team_Marine :: Constructor
//--------------------------------------------------------------------------------------
AVP_ServerEntity_Team_Marine::AVP_ServerEntity_Team_Marine( Asura_Guid uGuid )
: PARENT( uGuid )
, m_pxCurrentSpawnRecord(NULL)
, m_fTimeSinceLastSpawn(0.0f)
, m_uMarineKnowledgeBpHash( 0xed4b34fc /*"MarineKnowledge"*/ )
, m_uAndroidKnowledgeBpHash( 0xb66dfeef /*"AndroidKnowledge"*/ )
, m_uCivilianKnowledgeBpHash( 0x4b5ad85b /*"CivilianKnowledge"*/ )
{
	Classification = AVP_ENTITYCLASS_MARINETEAM;

	SetNeverUpdateClient();

	// Create the objective list
	m_pxSpawnRecordList = new Asura_List<SpawnRecord>;
	m_pxSpawnRecordList->ClearList();

	Asura_Assert( !s_pxMarineTeam, "AVP_ServerEntity_Team_Marine::AVP_ServerEntity_Team_Marine - there should only ever be one of these" );
	s_pxMarineTeam = this;
}

//--------------------------------------------------------------------------------------
//	Function	:	AVP_ServerEntity_Team_Marine :: Destructor
//--------------------------------------------------------------------------------------
AVP_ServerEntity_Team_Marine::~AVP_ServerEntity_Team_Marine()
{
	// deleted the objective list
	if (m_pxSpawnRecordList)
	{
		Asura_List_It <SpawnRecord> xSpawnRecordListIter (m_pxSpawnRecordList);

		while (!xSpawnRecordListIter.Done())
		{
			SpawnRecord* pxSpawnRecord = xSpawnRecordListIter.GetCurrent();
			xSpawnRecordListIter.DeleteCurrent();
			delete (pxSpawnRecord);
		}

		m_pxSpawnRecordList->ClearList();
		delete (m_pxSpawnRecordList);
		m_pxSpawnRecordList = NULL;
	}

	if (m_pxCurrentSpawnRecord != NULL)
	{
		delete (m_pxCurrentSpawnRecord);
	}

	s_pxMarineTeam = NULL;
}

//--------------------------------------------------------------------------------------
//	Function	:	AVP_ServerEntity_Team_Marine :: ReadFromChunkStream
//--------------------------------------------------------------------------------------
void AVP_ServerEntity_Team_Marine::ReadFromChunkStream(Asura_Chunk_Stream& xStream)
{
    int iVersion;
    xStream >> iVersion;

    PARENT::ReadFromChunkStream(xStream);

	if ( iVersion == CURRENT_CHUNK_VERSION )
	{
		xStream >> m_fSpawningDelay;
		xStream >> m_uMarineKnowledgeBpHash;
		xStream >> m_uAndroidKnowledgeBpHash;
		xStream >> m_uCivilianKnowledgeBpHash;
	}
	else if ( iVersion == 0 )
	{
		m_fSpawningDelay = 1.0f;
	}
    else if ( iVersion == 1 )
    {
		xStream >> m_fSpawningDelay;
    }
    else
    {
        Asura_Assertf(false, ("AVP_ServerEntity_Team_Marine::ReadFromChunkStream - unhandled version (%d)", iVersion));
    }
}

//--------------------------------------------------------------------------------------
//	Function	:	AVP_ServerEntity_Team_Marine :: WriteToChunkStream
//--------------------------------------------------------------------------------------
void AVP_ServerEntity_Team_Marine::WriteToChunkStream(Asura_Chunk_Stream& xStream) const
{
    xStream << CURRENT_CHUNK_VERSION;

    PARENT::WriteToChunkStream(xStream);

	xStream << m_fSpawningDelay;
	xStream << m_uMarineKnowledgeBpHash;
	xStream << m_uAndroidKnowledgeBpHash;
	xStream << m_uCivilianKnowledgeBpHash;
}

//--------------------------------------------------------------------------------------
//	Function	:	AVP_ServerEntity_Team_Marine :: HandleChangeKnowledgeSettingsMessage
//--------------------------------------------------------------------------------------
void AVP_ServerEntity_Team_Marine::HandleChangeKnowledgeSettingsMessage( const Asura_Message* pxMessage )
{
	const AVP_Message_ChangeHumanoidKnowledgeSettings* pxMsgData = static_cast<const AVP_Message_ChangeHumanoidKnowledgeSettings*>( pxMessage->GetData() );

	if ( pxMsgData )
	{
		KnowledgeSettings	xKnowledgeSettings;
		Asura_Blueprint*	pxBlueprint	= Asura_Blueprint_System::GetBlueprintByHashID(0x7ad7bd1b /*"AI Settings"*/, pxMsgData->m_uBluepprintHashID );

		if (pxBlueprint)
		{
			Asura_Value xValue;

			if (pxBlueprint->GetParameterValueByHashID(0x5739C427, xValue))	// 0x5739c427; //"PassiveSightRange"
				xKnowledgeSettings.m_fPassiveRange = xValue.GetFloatValue();

			if (pxBlueprint->GetParameterValueByHashID(0x510FC946, xValue))	// 0x510fc946; //"ActiveSightRange"
				xKnowledgeSettings.m_fActiveRange = xValue.GetFloatValue();

			if (pxBlueprint->GetParameterValueByHashID(0x196680C4, xValue))	// 0x196680c4; //"AggressiveSightRange"
				xKnowledgeSettings.m_fAggressiveRange = xValue.GetFloatValue();

			if (pxBlueprint->GetParameterValueByHashID(0x4c3ad6f7, xValue))	// 0x4c3ad6f7; //"PassiveThresholdToAcknowledgeThreat"
				xKnowledgeSettings.m_fPassiveThreshold = xValue.GetFloatValue();

			if (pxBlueprint->GetParameterValueByHashID(0xf81b7256, xValue))	// 0xf81b7256; //"ActiveThresholdToAcknowledgeThreat"
				xKnowledgeSettings.m_fActiveThreshold = xValue.GetFloatValue();

			if (pxBlueprint->GetParameterValueByHashID(0x9cae8654, xValue))	// 0x9cae8654; //"AggressiveThresholdToAcknowledgeThreat"
				xKnowledgeSettings.m_fAggressiveThreshold = xValue.GetFloatValue();

			if (pxBlueprint->GetParameterValueByHashID(0x18c61f5f, xValue))	// 0x18c61f5f; //"VisionKnowledgeLifeTime"
				xKnowledgeSettings.m_fKnowledgeLifetime = xValue.GetFloatValue();

			if (pxBlueprint->GetParameterValueByHashID(0xb1a0c5fa, xValue))	// 0xb1a0c5fa; //"CloakedVisibleRange"
			{
				xKnowledgeSettings.m_fCloakedVisibleRangeSq = xValue.GetFloatValue() * xValue.GetFloatValue();
			}

			if (pxBlueprint->GetParameterValueByHashID(0xc5ee14f1, xValue))	// 0xc5ee14f1; //"VisionalwaysSeeDistance"
				xKnowledgeSettings.m_fVisionCutOffDistanceSq = xValue.GetFloatValue() * xValue.GetFloatValue();

			if (pxBlueprint->GetParameterValueByHashID(0x2f076c3e, xValue)) // 0x2f076c3e; //"DarknessThreshold"
				xKnowledgeSettings.m_fDarknessLightThreshold = xValue.GetFloatValue();

			if (pxBlueprint->GetParameterValueByHashID(0x379e5b32, xValue)) // 0x379e5b32; //"DarkLightScore"
				xKnowledgeSettings.m_fDarknessLightScore = xValue.GetFloatValue();

			if (pxBlueprint->GetParameterValueByHashID(0xbe2e033a, xValue)) // 0xbe2e033a; //"BrightnessThreshold"
				xKnowledgeSettings.m_fBrightnessLightThreshold = xValue.GetFloatValue();

			if (pxBlueprint->GetParameterValueByHashID(0x84ab85b6, xValue)) // 0x84ab85b6; //"BrightLightScore"
				xKnowledgeSettings.m_fBrightnessLightScore = xValue.GetFloatValue();

			if (pxBlueprint->GetParameterValueByHashID(0xf7189843, xValue)) // 0xf7189843; //"NeutralLightScore"
				xKnowledgeSettings.m_fNeutralLightScore = xValue.GetFloatValue();

			if (pxBlueprint->GetParameterValueByHashID(0xCA663280, xValue)) //0xCA663280 //"PassiveCloakingThresholdToSeeThreat"
				xKnowledgeSettings.m_fPassiveCloakingThreshold = xValue.GetFloatValue();

			if (pxBlueprint->GetParameterValueByHashID(0x7646CDDF, xValue)) //0x7646CDDF //"ActiveCloakingThresholdToSeeThreat""
				xKnowledgeSettings.m_fActiveCloakingThreshold = xValue.GetFloatValue();

			if (pxBlueprint->GetParameterValueByHashID(0x1AD9E1DD, xValue)) //0x1AD9E1DD //"AggressiveCloakingThresholdToSeeThreat"
				xKnowledgeSettings.m_fAggressiveCloakingThreshold = xValue.GetFloatValue();

			switch ( pxMsgData->m_uHumanoidType )
			{
				case AVP_ENTITYCLASS_ANDROID:
				{
					for (Asura_Hashed_List_It<AVP_ServerActor_Android> it(AVP_ServerActor_Android::GetList()); !it.Done(); it.Next())
					{
						AVP_ServerActor_Android* pxEntity = it.GetCurrent();

						if (pxEntity && !pxEntity->IsPlayer() && !pxEntity->IsDead())
						{
							AVP_Brain_Actor_Marine* pxAndroidBrain = static_cast<AVP_Brain_Actor_Marine*>( pxEntity->GetActorBrain() );

							if ( pxAndroidBrain )
							{
								pxAndroidBrain->GetKnowledgeSystem()->UpdateKnowledgeSettings( &xKnowledgeSettings );
							}
						}
					}
					break;
				}

				case AVP_ENTITYCLASS_CIVILIAN:
				{
					for (Asura_Hashed_List_It<AVP_ServerActor_Civilian> it(AVP_ServerActor_Civilian::GetList()); !it.Done(); it.Next())
					{
						AVP_ServerActor_Civilian* pxEntity = it.GetCurrent();

						if (pxEntity && !pxEntity->IsPlayer() && !pxEntity->IsDead())
						{
							AVP_Brain_Actor_Civilian* pxAndroidBrain = static_cast<AVP_Brain_Actor_Civilian*>( pxEntity->GetActorBrain() );

							if ( pxAndroidBrain )
							{
								pxAndroidBrain->GetKnowledgeSystem()->UpdateKnowledgeSettings( &xKnowledgeSettings );
							}
						}
					}
					break;
				}

				case AVP_ENTITYCLASS_MARINE:
				{
					for (Asura_Hashed_List_It<AVP_ServerActor_Marine> it(AVP_ServerActor_Marine::GetList()); !it.Done(); it.Next())
					{
						AVP_ServerActor_Marine* pxEntity = it.GetCurrent();

						if (pxEntity && !pxEntity->IsPlayer() && !pxEntity->IsDead())
						{
							AVP_Brain_Actor_Marine* pxMarineBrain = static_cast<AVP_Brain_Actor_Marine*>( pxEntity->GetActorBrain() );

							if ( pxMarineBrain )
							{
								pxMarineBrain->GetKnowledgeSystem()->UpdateKnowledgeSettings( &xKnowledgeSettings );
							}
						}
					}
					break;
				}
			}
		}
	}
}

//--------------------------------------------------------------------------------------
//	Function	:	AVP_ServerEntity_Team_Marine :: handleMessage
//--------------------------------------------------------------------------------------
bool AVP_ServerEntity_Team_Marine::HandleMessage(const Asura_Message* pxMessage)
{
	switch (pxMessage->GetMsgID())
	{
		case AVP_MSGID_CHANGE_HUMANOID_KNOWLEDGE_SETTINGS:
		{
			HandleChangeKnowledgeSettingsMessage( pxMessage );
			return true;

		}
		case AVP_MSGID_SPAWN_HUMANOIDS:
		{
			const AVP_Message_SpawnHumanoids* pxMsgData = static_cast<const AVP_Message_SpawnHumanoids*>(pxMessage->GetData());

			if (pxMsgData)
			{
				AddSpawnRecord(pxMsgData);
			}

			return true;
		}

		case AVP_MSGID_CHANGE_HUMANOID_SPAWN_SETTINGS:
		{
			const AVP_Message_ChangeHumanoidSpawnSettings* pxMsgData = static_cast<const AVP_Message_ChangeHumanoidSpawnSettings*>(pxMessage->GetData());

			if (pxMsgData)
			{
				SetSpawnDelay(pxMsgData->GetSpawnDealy());
			}

			return true;
		}

		case AVP_MSGID_SET_AI_TARGET_PRIORITIES:
		case AVP_MSGID_RESET_AI_TARGET_PRIORITIES:
		{
			for ( Asura_Hashed_List_It< AVP_ServerEntity_Squad_Marine > xMSIt( AVP_ServerEntity_Squad_Marine::GetList() ); !xMSIt.Done(); xMSIt.Next() )
			{
				AVP_ServerEntity_Squad_Marine* pxMS = xMSIt.GetCurrent();
				pxMS->HandleMessage( pxMessage );
			}
			
			return true;
		}

		case AVP_MSGID_DISTRACT_AI:
		{
			// TODO - Gaz needs to fill in what marines need to do with this.
			return true;
		}

		default:
		{
			return PARENT::HandleMessage(pxMessage);
		}
	}
}

//--------------------------------------------------------------------------------------
//	Function	:	AVP_ServerEntity_Team_Marine :: update
//--------------------------------------------------------------------------------------
void AVP_ServerEntity_Team_Marine::Update(void)
{
	PARENT::Update();

	HandleSpawning();
}

//--------------------------------------------------------------------------------------
//	Function	:	AVP_ServerEntity_Team_Marine :: update
//--------------------------------------------------------------------------------------
void AVP_ServerEntity_Team_Marine::HandleSpawning(void)
{
	// if we have no current spawn record and we have no queued up spawn records then just return
	if ((GetCurrentSpawnRecord() == NULL) && (m_pxSpawnRecordList->GetNumEntries() <= 0))
	{
		return;
	}
	// Check if the current Spawn record is NULL and if we have any spawn records at all
	if ((GetCurrentSpawnRecord() == NULL) && (m_pxSpawnRecordList->GetNumEntries() > 0))
	{
		SetCurrentSpawnRecord(m_pxSpawnRecordList->PopHeadObject());
	}
	// ok we have some spawning to do!
	else
	{
		if (GetNumToSpawn() > 0)
		{
			if (!IsSpawnRecordValid())
			{
				if (GetCurrentSpawnRecord())
				{
					delete GetCurrentSpawnRecord();
					SetCurrentSpawnRecord(NULL);
					return;
				}
			}

			// Time scale is taken into account!
			IncreaseTimeSinceLastSpawn(Asura_Timers::GetFrameTime() * Asura_Timers::GetGameTimeScale());

			if (GetTimeSinceLastSpawn() > GetSpawnDelay())
			{
				bool bSuccess = false;

				// do the different types of spawning
				switch (GetSpawnMethod())
				{
					//----------------------------------------------
					case SPAWN_METHOD_SPECIFIC_SPAWN_POINT:
					{
						bSuccess = HandleSpawningFromSpawnPoint();
					}break;
					//----------------------------------------------
					case SPAWN_METHOD_SPECIFIC_GAME_PLAY_VOLUME:
					{
						bSuccess = HandleSpawningInsideGamePlayVolume();
					}break;
					//----------------------------------------------
					case SPAWN_METHOD_TEAM_CONTROLLED:
					default:
					{
						bSuccess = HandleTeamSpawning();
					}break;
					//----------------------------------------------
				}

				if (bSuccess)
				{
					// Decrease the number left to spawn
					SpawnSuccess();
					// Reset Our Spawn Timer
					ResetTimeSinceLastSpawn();
				}
			}
		}

		// None to spawn so delete the record ready for next frame
		if (GetNumToSpawn() <= 0)
		{
			if (GetCurrentSpawnRecord())
			{
				delete GetCurrentSpawnRecord();
				SetCurrentSpawnRecord(NULL);
			}
		}
	}
}

//--------------------------------------------------------------------------------------
//	Function	:	AVP_ServerEntity_Team_Marine :: GetHumanoidToSpawnClassification
//--------------------------------------------------------------------------------------
bool AVP_ServerEntity_Team_Marine::IsSpawnRecordValid(void)
{
	switch (GetSpawnMethod())
	{
		//----------------------------------------------
		case SPAWN_METHOD_SPECIFIC_SPAWN_POINT:
		{
			AVP_ServerEntity_HumanSpawnPoint* pxHumanoidSpawner = AVP_ServerEntity_HumanSpawnPoint::FindEntity(GetSpawnPointGuid());

			if (pxHumanoidSpawner)
			{
				if (!pxHumanoidSpawner->IsEntityActive())
				{
					return false;
				}
			}
			else
			{
				return false;
			}
		}break;
		//----------------------------------------------
		case SPAWN_METHOD_SPECIFIC_GAME_PLAY_VOLUME:
		{
			AVP_ServerEntity_GamePlayVolume* pxGamePlayVolume = AVP_ServerEntity_GamePlayVolume::FindEntity(GetSpawningGamePlayVolumeGuid());
			
			if (pxGamePlayVolume)
			{
				u_int uNumActive = 0;

				for (u_int u = 0; u < pxGamePlayVolume->GetNumHumanoidSpawnerGuids(); ++u)
				{
					AVP_ServerEntity_HumanSpawnPoint* pxHumanoidSpawner = AVP_ServerEntity_HumanSpawnPoint::FindEntity(pxGamePlayVolume->GetHumanoidSpawnerGuid(u));

					if (pxHumanoidSpawner && pxHumanoidSpawner->IsEntityActive())
					{
						++uNumActive;
					}
				}

				if (uNumActive == 0)
				{
					return false;
				}
			}
			else
			{
				return false;
			}

		}break;
		//----------------------------------------------
		case SPAWN_METHOD_TEAM_CONTROLLED:
		default:
		{
			return true;
		}
		//----------------------------------------------
	}

	return true;
}

//--------------------------------------------------------------------------------------
//	Function	:	AVP_ServerEntity_Team_Marine :: GetHumanoidToSpawnClassification
//--------------------------------------------------------------------------------------
u_int AVP_ServerEntity_Team_Marine::GetHumanoidToSpawnClassification(int iHumanoidType)
{
	switch (iHumanoidType)
	{
		case AVP_Message_SpawnHumanoids::SPAWN_HUMANOID_ANDROID:	
		{
			return AVP_ENTITYCLASS_ANDROID;

		}

		case AVP_Message_SpawnHumanoids::SPAWN_HUMANOID_CIVILIAN:	
		{
			return AVP_ENTITYCLASS_CIVILIAN;

		}

		case AVP_Message_SpawnHumanoids::SPAWN_HUMANOID_MARINE:
		{
			return AVP_ENTITYCLASS_MARINE;

		}
		default:
		{
			Asura_Assert(false, "AVP_ServerEntity_Team_Marine::GetHumanoidToSpawnClassification - Invalid Humanoid Type, Please Check that the Humanoid Spawn Message has the correct humanoid type selected.");
			return AsuraEntityClass_NotSet;
		}
	}
}

//--------------------------------------------------------------------------------------
//	Function	:	AVP_ServerEntity_Team_Marine :: Create
//--------------------------------------------------------------------------------------
void AVP_ServerEntity_Team_Marine::AddSpawnRecord(const AVP_Message_SpawnHumanoids* pxData)
{
	// pxData has already been verified.
	u_int			uClassification			= GetHumanoidToSpawnClassification(pxData->GetHumanoidTypeToSpawn());
	Asura_Guid		uSquadGuid				= pxData->GetSquadGuid();

	// Entity class is wrong just return (we have already asserted).
	if (uClassification == AsuraEntityClass_NotSet)
		return;

	// Civilians don't go in squads, so clear out the squad Guid.
	if (uClassification == AVP_ENTITYCLASS_CIVILIAN)
		uSquadGuid = ASURA_GUID_UNREGISTERED;

	SpawnRecord* pxSpawnRecord = new SpawnRecord;

	pxSpawnRecord->m_uHumanoidType			= uClassification;
	pxSpawnRecord->m_uNumToSpawn			= (u_int)pxData->GetNumberToSpawn();
	pxSpawnRecord->m_uSpawnMethod			= pxData->GetSpawnMethod();
	pxSpawnRecord->m_uBlueprintHashID		= pxData->GetBlueprintHashID();
	pxSpawnRecord->m_uBlueprintTypeHashID	= pxData->GetBlueprintTypeHashID();

	// Civilians don't go in squads
	if (uClassification == AVP_ENTITYCLASS_CIVILIAN)
		pxSpawnRecord->m_uSquadGuid = ASURA_GUID_UNREGISTERED;
	else
		pxSpawnRecord->m_uSquadGuid = pxData->GetSquadGuid();

	// If we are spawning into a squad check its not full
	if (pxSpawnRecord->m_uSquadGuid != ASURA_GUID_UNREGISTERED)
	{
		if (SquadIsFull(pxSpawnRecord->m_uSquadGuid))
		{
			Asura_Assert(false, "AVP_ServerEntity_Team_Marine::AddSpawnRecord - Trying to spawn into a squad that is full, no Humanoid will be spawned");
			delete pxSpawnRecord;
			return;
		}
	}

	// Add the specific data depending on the spawn method.
	switch (pxData->GetSpawnMethod())
	{
		//---------------------------------------------------------------------
		case SPAWN_METHOD_SPECIFIC_SPAWN_POINT:
		{
			pxSpawnRecord->m_uGamePlayVolumeGuid	= ASURA_GUID_UNREGISTERED;
			pxSpawnRecord->m_uSpawnPointGuid		= pxData->GetHumanoidSpawnGuid();

		}break;
		//---------------------------------------------------------------------
		case SPAWN_METHOD_SPECIFIC_GAME_PLAY_VOLUME:
		{
			pxSpawnRecord->m_uGamePlayVolumeGuid	= pxData->GetGamePlayVolumeGuid();
			pxSpawnRecord->m_uSpawnPointGuid		= ASURA_GUID_UNREGISTERED;

		}break;
		//---------------------------------------------------------------------
		case SPAWN_METHOD_TEAM_CONTROLLED:
		default:
		{
			pxSpawnRecord->m_uGamePlayVolumeGuid	= ASURA_GUID_UNREGISTERED;
			pxSpawnRecord->m_uSpawnPointGuid		= ASURA_GUID_UNREGISTERED;

		}break;
		//---------------------------------------------------------------------
	}

	m_pxSpawnRecordList->AddToList(pxSpawnRecord);
}

//--------------------------------------------------------------------------------------
//	Function	:	AVP_ServerEntity_Team_Marine :: SquadIsFull
//--------------------------------------------------------------------------------------
bool AVP_ServerEntity_Team_Marine::SquadIsFull(Asura_Guid uSquadGuid)
{
	AVP_ServerEntity_Squad_Marine* pxSquad = AVP_ServerEntity_Squad_Marine::FindEntity(uSquadGuid);

	if (pxSquad)
	{
		// Add an extra one for the squad leader
		if ((pxSquad->GetNumSquadMembers() + 1) < AVP_ServerEntity_Squad_Marine::MAX_SQUAD_MEMBERS)
		{
			return false;
		}
	}

	return true;
}

//--------------------------------------------------------------------------------------
//	Function	:	AVP_ServerEntity_Team_Marine :: HandleSpawningFromSpawnPoint
//--------------------------------------------------------------------------------------
bool AVP_ServerEntity_Team_Marine::HandleSpawningFromSpawnPoint(void)
{
	if (GetSpawnPointGuid() != ASURA_GUID_UNREGISTERED)
	{
		AVP_ServerEntity_HumanSpawnPoint* pxHumanoidSpawner = AVP_ServerEntity_HumanSpawnPoint::FindEntity(GetSpawnPointGuid());

		if (pxHumanoidSpawner)
		{
			AVP_ServerActor_Human* pxSpawnedHumanoid = pxHumanoidSpawner->Spawn(GetSpawningBlueprintTypeHashID(), GetSpawningBlueprintHashID(), GetSpawningHumanoidType(), GetSpawningSquadGuid());

			if (pxSpawnedHumanoid)
			{
				return true;
			}
		}
	}

	return false;
}

//--------------------------------------------------------------------------------------
//	Function	:	AVP_ServerEntity_Team_Marine :: HandleSpawningInsideGamePlayVolume
//--------------------------------------------------------------------------------------
bool AVP_ServerEntity_Team_Marine::HandleSpawningInsideGamePlayVolume(void)
{
	if (GetSpawningGamePlayVolumeGuid() != ASURA_GUID_UNREGISTERED)
	{
		AVP_ServerEntity_GamePlayVolume* pxGamePlayVolume = AVP_ServerEntity_GamePlayVolume::FindEntity(GetSpawningGamePlayVolumeGuid());

		if (pxGamePlayVolume)
		{
			Asura_Guid uChosenSpawner = ASURA_GUID_UNREGISTERED;

			while (uChosenSpawner == ASURA_GUID_UNREGISTERED)
			{
				if (pxGamePlayVolume->GetNumHumanoidSpawnerGuids() == 0)
				{
					return false;
				}
				else
				{
					uChosenSpawner = pxGamePlayVolume->GetHumanoidSpawnerGuid(Asura_Random::GetIntU(0, pxGamePlayVolume->GetNumHumanoidSpawnerGuids() - 1));
				}
			}

			AVP_ServerEntity_HumanSpawnPoint* pxHumanoidSpawner = AVP_ServerEntity_HumanSpawnPoint::FindEntity(uChosenSpawner);

			if (pxHumanoidSpawner)
			{
				AVP_ServerActor_Human* pxSpawnedHumanoid = pxHumanoidSpawner->Spawn(GetSpawningBlueprintTypeHashID(), GetSpawningBlueprintHashID(), GetSpawningHumanoidType(), GetSpawningSquadGuid());

				if (pxSpawnedHumanoid)
				{
					return true;
				}
			}
		}
	}

	return false;
}

//--------------------------------------------------------------------------------------
//	Function	:	AVP_ServerEntity_Team_Marine :: HandleTeamSpawning
//--------------------------------------------------------------------------------------
bool AVP_ServerEntity_Team_Marine::HandleTeamSpawning(void)
{
	AVP_ServerEntity_PlayerInfo* pxPlayerInfo = AVP_ServerEntity_PlayerInfo::FindEntity(1000);

	if (pxPlayerInfo)
	{
		AVP_ServerEntity_Actor* pxPlayerActor = AVP_ServerEntity_Actor::FindEntity(pxPlayerInfo->GetPuppetGuid());

		if (pxPlayerActor)
		{
			AVP_ServerEntity_GamePlayVolume* pxGamePlayVolume = AVP_ServerEntity_GamePlayVolume::GetVolumeThatContainsPosition(pxPlayerActor->GetPosition());

			if (pxGamePlayVolume)
			{
				if (pxGamePlayVolume->GetNumHumanoidSpawnerGuids() > 0)
				{
					Asura_Guid uChosenSpawner = ASURA_GUID_UNREGISTERED;

					while (uChosenSpawner == ASURA_GUID_UNREGISTERED)
					{
						uChosenSpawner = pxGamePlayVolume->GetHumanoidSpawnerGuid(Asura_Random::GetIntU(0, pxGamePlayVolume->GetNumHumanoidSpawnerGuids() - 1));
					}

					AVP_ServerEntity_HumanSpawnPoint* pxHumanoidSpawner = AVP_ServerEntity_HumanSpawnPoint::FindEntity(uChosenSpawner);

					if (pxHumanoidSpawner)
					{
						AVP_ServerActor_Human* pxSpawnedHumanoid = pxHumanoidSpawner->Spawn(GetSpawningBlueprintTypeHashID(), GetSpawningBlueprintHashID(), GetSpawningHumanoidType(), GetSpawningSquadGuid());

						if (pxSpawnedHumanoid)
						{
							return true;
						}
					}
				}
			}
		}
	}

	return true;
}

//--------------------------------------------------------------------------------------
//	Function	:	AVP_ServerEntity_Team_Marine :: Create
//--------------------------------------------------------------------------------------
AVP_ServerEntity_Team_Marine* AVP_ServerEntity_Team_Marine::Create( const Asura_Guid uGuid )
{
    return new AVP_ServerEntity_Team_Marine( uGuid );
}

//--------------------------------------------------------------------------------------
//	Function	:	AVP_ServerEntity_Team_Marine :: FindEntity
//--------------------------------------------------------------------------------------
AVP_ServerEntity_Team_Marine* AVP_ServerEntity_Team_Marine::FindEntity( const Asura_Guid uGuid )
{
    if (s_pxMarineTeam && uGuid == s_pxMarineTeam->GetGuid())
    {
        return s_pxMarineTeam;
    }
    else
    {
        return NULL;
    }
}

//--------------------------------------------------------------------------------------
//	Function	:	AVP_ServerEntity_Team_Marine :: GetMarineTeamBrain
//--------------------------------------------------------------------------------------
AVP_Brain_Team_Marine* AVP_ServerEntity_Team_Marine::GetMarineTeamBrain() const
{
    return static_cast< AVP_Brain_Team_Marine* >( GetTeamBrain() );
}

//////////////////////////////////////////////////////////////////////////////
//
// 
//
//////////////////////////////////////////////////////////////////////////////
