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; } }
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; } } }
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; } } }
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; } }
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; }
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; } }