예제 #1
0
void CFerianShipAI::OnObjDestroyedNotify (const SDestroyCtx &Ctx)

//	OnObjDestroyedNotify
//
//	Deal with an object that has been destroyed

	{
	switch (GetCurrentOrder())
		{
		case IShipController::orderMine:
			{
			if (Ctx.pObj == GetCurrentOrderTarget())
				{
				//	Avenge the base

				if (Ctx.pDestroyer && Ctx.pDestroyer->CanAttack() && !m_pShip->IsFriend(Ctx.pDestroyer))
					AddOrder(IShipController::orderDestroyTarget, Ctx.pDestroyer, 0);
				else if (m_State == stateAttackingThreat)
					AddOrder(IShipController::orderDestroyTarget, m_pTarget, 0);

				//	Stop mining

				CancelCurrentOrder();
				}
			break;
			}
		default:
			break;
		}

	//	Reset

	if (m_pBase == Ctx.pObj)
		{
		SetState(stateNone);
		m_pBase = NULL;
		}

	if (m_pTarget == Ctx.pObj)
		{
		SetState(stateNone);
		m_pTarget = NULL;
		}
	}
예제 #2
0
void CZoanthropeAI::BehaviorStart (void)

//	BehaviorStart
//
//	Figure out what to do based on orders

	{
	switch (GetCurrentOrder())
		{
		case IShipController::orderNone:
			{
			if (m_pShip->GetDockedObj() == NULL)
				AddOrder(IShipController::orderGate, NULL, IShipController::SData());
			break;
			}

		case IShipController::orderEscort:
			{
			CSpaceObject *pPrincipal = GetCurrentOrderTarget();
			ASSERT(pPrincipal);

			SetState(stateOnEscortCourse, pPrincipal);
			m_pShip->Communicate(m_pBase, msgEscortReportingIn, m_pShip);
			break;
			}

		case IShipController::orderFollowPlayerThroughGate:
			SetState(stateOnCourseForStargate, m_pShip->GetNearestStargate());
			break;

		case IShipController::orderGate:
			{
			//	Look for the gate

			CSpaceObject *pGate = GetCurrentOrderTarget();
			if (pGate == NULL)
				pGate = m_pShip->GetNearestStargate(true);

			//	Head for the gate

			if (pGate)
				SetState(stateOnCourseForStargate, pGate);

			break;
			}

		case IShipController::orderGuard:
			{
			CSpaceObject *pPrincipal = GetCurrentOrderTarget();
			ASSERT(pPrincipal);

			//	If we're not docked, dock with principal

			if (m_pShip->GetDockedObj() == NULL)
				SetState(stateReturningFromThreat, pPrincipal);

			//	Otherwise, wait for a threat

			else
				SetState(stateWaitingForThreat, pPrincipal);

			break;
			}

		case IShipController::orderPatrol:
			{
			CSpaceObject *pPrincipal = GetCurrentOrderTarget();
			ASSERT(pPrincipal);

			SetState(stateOnPatrolOrbit, pPrincipal);
			break;
			}

		case IShipController::orderWaitForPlayer:
			{
			SetState(stateWaiting);
			break;
			}
		}
	}
예제 #3
0
void CAutonAI::BehaviorStart (void)

//	BehaviorStart
//
//	Initiate behavior state based on orders

	{
	switch (GetCurrentOrder())
		{
		case IShipController::orderNone:
			{
			if (m_pShip->GetDockedObj() == NULL)
				AddOrder(IShipController::orderGate, NULL, IShipController::SData());
			break;
			}

		case IShipController::orderEscort:
			{
			//	If this is a support ship, then we follow. Otherwise we
			//	are an armed escort.

			if (m_AICtx.IsNonCombatant())
				SetState(stateFollowing);
			else
				SetState(stateEscorting);

			m_pDest = GetCurrentOrderTarget();
			ASSERT(m_pDest);

			m_pShip->Communicate(m_pDest, msgEscortReportingIn, m_pShip);
			break;
			}

		case IShipController::orderFollowPlayerThroughGate:
			{
			SetState(stateOnCourseForStargate);
			m_pDest = m_pShip->GetNearestStargate();
			break;
			}

		case IShipController::orderGate:
			{
			//	Look for the gate

			CSpaceObject *pGate = GetCurrentOrderTarget();
			if (pGate == NULL)
				pGate = m_pShip->GetNearestStargate(true);

			//	Head for the gate

			if (pGate)
				{
				SetState(stateOnCourseForStargate);
				m_pDest = pGate;
				}

			break;
			}

		case IShipController::orderWaitForPlayer:
			{
			SetState(stateWaiting);
			break;
			}
		}
	}
예제 #4
0
void CFerianShipAI::BehaviorStart (void)

//	BehaviorStart
//
//	Figure out what to do based on orders

	{
	switch (GetCurrentOrder())
		{
		case IShipController::orderNone:
			{
			if (m_pShip->GetDockedObj() == NULL)
				AddOrder(IShipController::orderGate, NULL, 0);
			break;
			}

		case IShipController::orderDestroyTarget:
			{
			SetState(stateAttackingTarget);
			m_pTarget = GetCurrentOrderTarget();
			ASSERT(m_pTarget);
			ASSERT(m_pTarget->DebugIsValid() && m_pTarget->NotifyOthersWhenDestroyed());
			break;
			}

		case IShipController::orderMine:
			{
			m_pBase = GetCurrentOrderTarget();
			ASSERT(m_pBase);

			SetState(stateOnCourseForMine);
			m_pTarget = FindRandomAsteroid();
			if (m_pTarget == NULL)
				{
				SetState(stateOnCourseForStargate);
				m_pBase = m_pShip->GetNearestStargate(true);
				}
			break;
			}

		case IShipController::orderGate:
			{
			//	Look for the gate

			CSpaceObject *pGate = GetCurrentOrderTarget();
			if (pGate == NULL)
				pGate = m_pShip->GetNearestStargate(true);

			//	Head for the gate

			if (pGate)
				{
				SetState(stateOnCourseForStargate);
				m_pBase = pGate;
				}

			break;
			}

		case IShipController::orderDestroyPlayerOnReturn:
			{
			CSpaceObject *pGate = m_pShip->GetNearestStargate();
			if (pGate)
				{
				SetState(stateWaitForPlayerAtGate);
				m_pBase = pGate;
				}
			break;
			}
		default:
			break;
		}
	}
예제 #5
0
void CFleetShipAI::OnObjDestroyedNotify (const SDestroyCtx &Ctx)

//	OnObjDestroyedNotify
//
//	Deal with an object that has been destroyed

	{
	switch (GetCurrentOrder())
		{
		case IShipController::orderEscort:
			if (Ctx.pObj == GetCurrentOrderTarget())
				{
				CancelCurrentOrder();

				//	Get the orders of the leader

				IShipController::OrderTypes iLeaderOrders = IShipController::orderNone;
				CSpaceObject *pLeaderTarget = NULL;
				if (Ctx.pObj && Ctx.pObj->GetCategory() == CSpaceObject::catShip)
					{
					CShip *pLeader = Ctx.pObj->AsShip();
					if (pLeader)
						iLeaderOrders = pLeader->GetController()->GetCurrentOrderEx(&pLeaderTarget);
					}

				//	Avenge the leader

				int iAvengeChance = (pLeaderTarget ? 40 : 100);
				if (Ctx.pDestroyer 
						&& Ctx.pDestroyer != pLeaderTarget
						&& Ctx.pDestroyer->CanAttack() 
						&& !m_pShip->IsFriend(Ctx.pDestroyer)
						&& mathRandom(1, 100) <= iAvengeChance)
					AddOrder(IShipController::orderDestroyTarget, Ctx.pDestroyer, 0);

				//	Take on leader's orders

				switch (iLeaderOrders)
					{
					case IShipController::orderDestroyTarget:
					case IShipController::orderGuard:
						if (pLeaderTarget)
							AddOrder(iLeaderOrders, pLeaderTarget, 0);
						break;
					default:
						break;
					}

				//	Attack other enemies

				AddOrder(IShipController::orderAttackNearestEnemy, NULL, 0);
				}
			break;

		case IShipController::orderDock:
		case IShipController::orderDestroyTarget:
		case IShipController::orderPatrol:
		case IShipController::orderGuard:
			if (Ctx.pObj == GetCurrentOrderTarget())
				CancelCurrentOrder();
			break;
		default:
			break;
		}

	//	If our target gets destroyed...

	switch (m_State)
		{
		case stateAttackTarget:
		case stateAttackOnPatrol:
			if (Ctx.pObj == m_pTarget)
				SetState(stateNone);
			break;
		default:
			break;
		}

	//	Reset

	if (m_pDest == Ctx.pObj)
		m_pDest = NULL;
	if (m_pTarget == Ctx.pObj)
		m_pTarget = NULL;
	}
예제 #6
0
void CFleetShipAI::BehaviorStart (void)

//	BehaviorStart
//
//	Figure out what to do based on orders

	{
	switch (GetCurrentOrder())
		{
		case IShipController::orderNone:
			{
			if (m_pShip->GetDockedObj() == NULL)
				AddOrder(IShipController::orderGate, NULL, 0);
			break;
			}

		case IShipController::orderAttackNearestEnemy:
			{
			CSpaceObject *pTarget = m_pShip->GetNearestEnemy(ATTACK_AT_WILL_RANGE, true);
			if (pTarget)
				{
				SetState(stateAttackTarget);
				m_pTarget = pTarget;
				m_iCounter = 0;
				}
			else
				CancelCurrentOrder();
			break;
			}

		case IShipController::orderDestroyTarget:
			{
			SetState(stateAttackTarget);
			m_pTarget = GetCurrentOrderTarget();
			m_iCounter = 0;
			ASSERT(m_pTarget);
			break;
			}

		case IShipController::orderDock:
			{
			CSpaceObject *pDest = GetCurrentOrderTarget();
			ASSERT(pDest);

			//	If we're docked with our destination then we're done.

			if (m_pShip->GetDockedObj() == pDest)
				CancelCurrentOrder();

			//	Otherwise, try to dock

			else
				{
				SetState(stateOnCourseForDocking);
				m_pDest = pDest;
				}

			break;
			}

		case IShipController::orderEscort:
			{
			SetState(stateKeepFormation);

			m_pLeader = GetCurrentOrderTarget();
			ASSERT(m_pLeader);

			m_iFormation = (int)HIWORD(GetCurrentOrderData());
			m_iPlace = (int)LOWORD(GetCurrentOrderData());
			ASSERT(m_iFormation < FORMATIONS_COUNT);

			//	If there is no place for this ship in the formation, then
			//	gate-out

			if (m_iFormation >= FORMATIONS_COUNT
					|| m_iPlace >= g_Formations[m_iFormation].iCount)
				{
				CancelCurrentOrder();
				break;
				}

			//	Keep formation

			m_pShip->Communicate(m_pLeader, msgEscortReportingIn, m_pShip);
			break;
			}

		case IShipController::orderFollowPlayerThroughGate:
			{
			SetState(stateOnCourseForStargate);
			m_pDest = m_pShip->GetNearestStargate();
			break;
			}

		case IShipController::orderGate:
			{
			//	Look for the gate

			CSpaceObject *pGate = GetCurrentOrderTarget();
			if (pGate == NULL)
				pGate = m_pShip->GetNearestStargate(true);

			//	Head for the gate

			if (pGate)
				{
				SetState(stateOnCourseForStargate);
				m_pDest = pGate;
				}

			break;
			}

		case IShipController::orderPatrol:
		case IShipController::orderGuard:
			{
			SetState(stateOnPatrolOrbit);
			m_pDest = GetCurrentOrderTarget();
			ASSERT(m_pDest);
			break;
			}
		default:
			break;
		}
	}