void CAIWeaponAbstract::Load(ILTMessage_Read *pMsg) { HOBJECT hOwner = NULL; HWEAPON hWeapon = NULL; LOAD_HOBJECT(hOwner); LOAD_HRECORD( hWeapon, g_pWeaponDB->GetWeaponsCategory() ); LOAD_STDSTRING(m_szFireSocketName); LOAD_INT_CAST(m_eFiringState, ENUM_AIFiringState); LOAD_DWORD(m_iAnimRandomSeed); LOAD_TIME(m_fRandomSeedSelectionTime); LOAD_FLOAT(m_flWeaponContextInaccuracyScalar); LOAD_DWORD(m_hWeaponSocket); LOAD_bool(m_bCanDropWeapon); ASSERT(IsAI(hOwner)); CAI* pAI = (CAI*)g_pLTServer->HandleToObject(hOwner); ASSERT(pAI->GetArsenal()); if (pAI) { ASSERT(pAI->GetArsenal()); if (CArsenal* pArsenal = pAI->GetArsenal()) { m_pWeapon = pArsenal->GetWeapon(hWeapon); } } if( m_pWeapon ) { m_pAIWeaponRecord = AIWeaponUtils::GetAIWeaponRecord( m_pWeapon->GetWeaponRecord(), pAI->GetAIBlackBoard()->GetBBAIWeaponOverrideSet() ); } }
void CAIActivityAbstract::InitActivity() { // Find squad members who could be potential participants of this activity. LTObjRef* pSquadMembers = m_pSquad->GetSquadMembers(); int cSquadMembers = m_pSquad->GetNumSquadMembers(); CAI* pCurAI; m_cPotentialParticipants = 0; for( int iMember=0; iMember < cSquadMembers; ++iMember ) { pCurAI = (CAI*)g_pLTServer->HandleToObject( pSquadMembers[iMember] ); if( !pCurAI ) { continue; } // Add AI to list if he has this activity in his activity set. ENUM_AIActivitySet eActivitySet = pCurAI->GetAIBlackBoard()->GetBBAIActivitySet(); if( g_pAICoordinator->IsActivityInAIActivitySet( eActivitySet, GetActivityClassType() ) ) { m_aPotentialParticipants[m_cPotentialParticipants] = pCurAI->m_hObject; ++m_cPotentialParticipants; } } }
void CAIActivityAbstract::CalcActivityAABB( LTRect3f* pAABB ) { // Sanity check. if( !pAABB ) { return; } CAI* pAI; uint32 iParticipant; bool bFirst = true; for( iParticipant=0; iParticipant < m_cPotentialParticipants; ++iParticipant ) { pAI = (CAI*)g_pLTServer->HandleToObject( m_aPotentialParticipants[iParticipant] ); if( !pAI ) { continue; } if( bFirst ) { pAABB->Init( pAI->GetPosition(), pAI->GetPosition() ); bFirst = false; continue; } pAABB->Merge( pAI->GetPosition() ); } }
bool CGenerator_AI::generate(SDL_Event& e) { checkMoveKeys(e); if (e.button.type == SDL_MOUSEBUTTONDOWN && e.button.button == SDL_BUTTON_RIGHT && (m_pSpawnTimer->getTime() - m_prevTimeSpawn) > m_spawnTime_MS) { int w = 10; int h = 10; int x = e.button.x; int y = e.button.y; SCoords2<int> spawnCoords; spawnCoords.setCoords(x, y); SCoords2<int> topLeft, topRight, bottomLeft, bottomRight; topLeft.setCoords(x, y); topRight.setCoords(x + w, y); bottomRight.setCoords(x + w, y + h); bottomLeft.setCoords(x, y + h); if (m_pRoom_collision->size() == 0) { return false; } bool isWithinARoom = false; CRoom* pSpawnRoom = NULL; for (int i = 0; i < m_pRoom_collision->size(); ++i) { pSpawnRoom = m_pRoom_collision->at(i); // want to spawn AI within rooms if (pSpawnRoom->collision(&topLeft) == true && pSpawnRoom->collision(&topRight) == true && pSpawnRoom->collision(&bottomLeft) == true && pSpawnRoom->collision(&bottomRight) == true) { isWithinARoom = true; break; } } if (isWithinARoom == false) { return false; } CAI* pAI = new CAI(m_pWindow, m_pCollisionMap, m_pRoom_collision, spawnCoords, "Resource Files/AI/debug AI.png", w, h, 1, 1); pAI->setCurrentRoom(pSpawnRoom); m_aiVector.push_back(pAI); return true; } return false; }
static bool AllPlayersTargeted( CAI* pIgnoreThisAI ) { CPlayerObj::PlayerObjList::const_iterator itEachPlayer = CPlayerObj::GetPlayerObjList().begin(); CPlayerObj::PlayerObjList::const_iterator itEndPlayer = CPlayerObj::GetPlayerObjList().end(); for ( ; itEachPlayer != itEndPlayer; ++itEachPlayer ) { // Ignore this player if they are not valid or if they are not alive. CCharacter* pPlayer = *itEachPlayer; if ( NULL == pPlayer || IsDeadCharacter( pPlayer->GetHOBJECT() ) ) { continue; } HOBJECT hPlayer = pPlayer->GetHOBJECT(); // See if any AIs are targeting the player. bool bPlayerTargeted = false; CAI::AIList::const_iterator itEachAI = CAI::GetAIList().begin(); CAI::AIList::const_iterator itEndAI = CAI::GetAIList().end(); for ( ; itEachAI != itEndAI; ++itEachAI ) { CAI* pCurrentAI = *itEachAI; if ( NULL == pCurrentAI ) { continue; } if ( pCurrentAI == pIgnoreThisAI ) { continue; } if ( pCurrentAI->GetAIBlackBoard()->GetBBTargetObject() != hPlayer ) { continue; } bPlayerTargeted = true; break; } if ( false == bPlayerTargeted ) { // Found an untargeted player. Not all players are targeted. return false; } } // All players are targeted. return true; }
bool CAITargetSelectCharacterSquad::ValidatePreconditions( CAI* pAI ) { // Sanity check. if( !pAI ) { return false; } // AI is already targeting a character. if( pAI->HasTarget( kTarget_Character ) ) { return false; } // AI is not in a squad. ENUM_AI_SQUAD_ID eSquad = g_pAICoordinator->GetSquadID( pAI->m_hObject ); CAISquad* pSquad = g_pAICoordinator->FindSquad( eSquad ); if( !pSquad ) { return false; } // Find a squad member targeting a character. CAI* pMember = NULL; bool bTargetingCharacter = false; uint32 cMembers = pSquad->GetNumSquadMembers(); LTObjRef* pMembers = pSquad->GetSquadMembers(); if( pMembers ) { for( uint32 iMember=0; iMember < cMembers; ++iMember ) { pMember = (CAI*)g_pLTServer->HandleToObject( pMembers[iMember] ); if( pMember && pMember->HasTarget( kTarget_Character ) ) { bTargetingCharacter = true; break; } } } // Preconditions are met if the squad is targeting someone. return bTargetingCharacter; }
void AI_Helicopter::InitAttachments() { CAIVehicle::InitAttachments(); for ( int iObject = 0 ; iObject < m_cObjects ; iObject++ ) { BaseClass* pObject = m_apObjects[iObject]; if (pObject) { if ( IsKindOf(pObject->m_hObject, "ControlledSearchLight") ) { m_iObjectSearchLight = iObject; ControlledSearchLight* pSearchLight = ((ControlledSearchLight*)pObject); pSearchLight->SetController(m_hObject); HATTACHMENT hAttachment; if ( LT_OK == g_pLTServer->FindAttachment(m_hObject, pSearchLight->m_hObject, &hAttachment) ) { LTransform transform; g_pLTServer->Common()->GetAttachmentTransform(hAttachment, transform, LTTRUE); g_pTransLT->Get(transform, m_vPosSearchlight, m_rRotSearchlight); } } else if ( IsKindOf(pObject->m_hObject, "CAI") ) { Link(pObject->m_hObject); m_iObjectGunner = iObject; CAI* pGunner = ((CAI*)pObject); HATTACHMENT hAttachment; if ( LT_OK == g_pLTServer->FindAttachment(m_hObject, pGunner->m_hObject, &hAttachment) ) { LTransform transform; g_pLTServer->Common()->GetAttachmentTransform(hAttachment, transform, LTTRUE); g_pTransLT->Get(transform, m_vPosGunner, m_rRotGunner); } char szMessage[128]; sprintf(szMessage, "HELIATTACK HELI=%s", g_pLTServer->GetObjectName(m_hObject)); SendTriggerMsgToObject(this, pGunner->GetObject(), LTFALSE, szMessage); } } } }
void CGenerator_AI::update() { for (int i = 0; i < m_aiVector.size(); ++i) { CAI* pAI = m_aiVector.at(i); // delete a room if it is marked as needed to be deleted if (pAI->isToBeDeleted == true) { auto itr = m_aiVector.begin() + i; m_aiVector.erase(itr); continue; } pAI->setMove(isUpPressed, isDownPressed, isLeftPressed, isRightPressed); pAI->update(); } }
void CAIMgr::CollectGarbage() { // Central memory garbage collection. m_pAICentralMemory->CollectGarbage(); // Individual AI working memory garbage collection. CAI::AIList::const_iterator it = CAI::GetAIList().begin(); for (; it != CAI::GetAIList().end(); ++it) { CAI* pAI = *it; if (pAI) { pAI->GetAIWorkingMemory()->CollectGarbage(); } } }
HOBJECT CAITargetSelectDisturbanceBeyondGuard::SelectDisturbanceSource( CAI* pAI, CAIWMFact* pFact ) { // Sanity check. if( !( pAI && pFact ) ) { return NULL; } // Disturbance is not from an AI. if( !IsAI( pFact->GetTargetObject() ) ) { return pFact->GetTargetObject(); } // AI is not an ally. CAI* pOther = (CAI*)g_pLTServer->HandleToObject( pFact->GetTargetObject() ); EnumCharacterStance eStance = g_pCharacterDB->GetStance( pAI->GetAlignment(), pOther->GetAlignment() ); if( eStance != kCharStance_Like ) { return pFact->GetTargetObject(); } // Ally is not targeting a character. if( pOther->GetAIBlackBoard()->GetBBTargetType() != kTarget_Character ) { return pFact->GetTargetObject(); } // Return the Ally's target object. return pOther->GetAIBlackBoard()->GetBBTargetObject(); }
void CAIGoalAbstractStimulated::ActivateGoal() { super::ActivateGoal(); // Only set a new response index if the AI is witnessing a new stimulus, // rather than seeing an ally who is disturbed. if( ( m_eSenseType != kSense_SeeAllyDisturbance ) && ( m_eSenseType != kSense_HearAllyDisturbance ) ) { m_pAI->SetLastStimulusTime( m_fStimulusTime ); } // Copy an ally's stimulus time. else if( m_hStimulusSource && IsAI( m_hStimulusSource ) ) { CAI* pAlly = (CAI*)( g_pLTServer->HandleToObject( m_hStimulusSource ) ); if( pAlly ) { m_pAI->SetLastStimulusTime( pAlly->GetLastStimulusTime() ); } } }
int main() { CAI aCAI; aCAI.StartTest(); return 0; }
void CAIMgr::UpdateAISensors() { CTList<CCharacter*>* plstChars = g_pCharacterMgr->GetCharacterList( CCharacterMgr::kList_AIs ); CCharacter** pNext; CAI* pCurAI; // No AI exist. if( plstChars->GetLength() == 0 ) { return; } // Find the next AI to update. // AI update round robin, so everyone gets the opportunity to // do a distributed update. pNext = plstChars->GetItem( TLIT_FIRST ); while( m_hNextAI && ( (*pNext)->m_hObject != m_hNextAI ) ) { pNext = plstChars->GetItem( TLIT_NEXT ); } if( !pNext ) { pNext = plstChars->GetItem( TLIT_FIRST ); } HOBJECT hFirstToUpdate = (*pNext)->m_hObject; // Iterate over all existing AI. bool bWrapped = false; bool bUpdateDistributedSensors = true; while( true ) { // Bail once we have updated everyone. if( bWrapped ) { break; } // Look ahead at the next AI to update, and flag if we've wrapped. pCurAI = (CAI*)*pNext; pNext = plstChars->GetItem( TLIT_NEXT ); if( !pNext ) { pNext = plstChars->GetItem( TLIT_FIRST ); } if( (*pNext)->m_hObject == hFirstToUpdate ) { bWrapped = true; } // Do not update sensors of dead AI. if( pCurAI->GetDestructible()->IsDead() ) { continue; } // Update all AI's sensors. // Stop updating distributed sensors once someone has performed // an expensive update. if( pCurAI->GetAISensorMgr()->UpdateSensors( bUpdateDistributedSensors ) ) { #if DISTRIBUTE_SENSORS m_hNextAI = (*pNext)->m_hObject; bUpdateDistributedSensors = false; #endif } } }
bool AINodeValidatorLockedByOther::Evaluate( uint32 dwFilteredStatusFlags, CAI* pAI, EnumAINodeClusterID eNodeClusterID, HOBJECT hLockingAI, HOBJECT hDependency, bool* pbOutCoverBehindAlly ) const { if( dwFilteredStatusFlags & kNodeStatus_LockedByOther ) { if( pAI ) { if( hLockingAI && ( hLockingAI != pAI->m_hObject ) ) { return false; } // Node has a dependency. if( hDependency ) { AINodeSmartObject* pNodeSmartObject = AINodeSmartObject::DynamicCast( hDependency ); if( pNodeSmartObject ) { AIDB_SmartObjectRecord* pRecord = pNodeSmartObject->GetSmartObject(); if( pRecord ) { // Destination dependency is locked by someone else. if( ( pRecord->eDependencyType == kDependency_Destination ) && ( pNodeSmartObject->IsNodeLocked() ) && ( pNodeSmartObject->GetLockingAI() != pAI->m_hObject ) ) { return false; } // Occupation dependency is not occupied by someone else. if( pRecord->eDependencyType == kDependency_Occupied ) { // AI is taking cover behind someone. if ( pbOutCoverBehindAlly ) *pbOutCoverBehindAlly = true; // Node is unusable if dependency is disabled. if( pNodeSmartObject->IsNodeDisabled() ) { return false; } // Node is unusable if locking AI does not exist. HOBJECT hLockingAI = pNodeSmartObject->GetLockingAI(); CAI* pLockingAI = (CAI*)g_pLTServer->HandleToObject( hLockingAI ); if( !pLockingAI ) { return false; } // Node is not occupied if the locking AI is not at the node. SAIWORLDSTATE_PROP* pAtProp = pLockingAI->GetAIWorldState()->GetWSProp( kWSK_AtNode, pLockingAI->m_hObject ); if( !( pAtProp && pAtProp->hWSValue == hDependency ) ) { return false; } } } } } // Node has a cluster that is locked by someone else. if( eNodeClusterID != kNodeCluster_Invalid ) { CAINodeCluster* pCluster = g_pAINodeMgr->GetNodeCluster( eNodeClusterID ); if( pCluster && pCluster->IsClusterLocked() && ( pCluster->GetLockingAI() != pAI->m_hObject ) ) { return false; } } } } return true; }
void CAIGoalCircleFlamePot::DeactivateGoal() { super::DeactivateGoal(); // If: // 1) The player is an enemy. // 2) There is another AI very close by // 3) That AI does not have a blitz task // ...this AI should blitz the player. This is an anti-clumping measure. HOBJECT hTarget = m_pAI->GetAIBlackBoard()->GetBBTargetObject(); bool bShouldBlitz = false; if ( m_pAI->HasTarget( kTarget_Character ) && IsPlayer( hTarget ) ) { CAI::AIList::const_iterator itEachAI = CAI::GetAIList().begin(); CAI::AIList::const_iterator itLastAI = CAI::GetAIList().end(); for ( ; itEachAI != itLastAI; ++itEachAI ) { CAI* pCurrentAI = *itEachAI; // Ignore NULL, self and dead AI. if ( NULL == pCurrentAI || pCurrentAI == m_pAI || IsDeadAI( pCurrentAI->GetHOBJECT() ) ) { continue; } // Ignore AIs who are far away in 2D (false positives are okay). LTVector vDelta2D = ( pCurrentAI->GetPosition() - m_pAI->GetPosition() ); vDelta2D.y = 0.0f; if ( vDelta2D.MagSqr() > g_flTooCloseToEnemySqr ) { continue; } // Ignore AI who are already blitzing. CAIWMFact factQuery; factQuery.SetFactType( kFact_Task ); factQuery.SetTaskType( kTask_BlitzCharacter ); if ( pCurrentAI->GetAIWorkingMemory()->FindWMFact( factQuery ) ) { continue; } // AI should blitz. bShouldBlitz = true; break; } } if ( bShouldBlitz || ( 0 == GetRandom( 0, 2 ) ) ) { CAIWMFact factQuery; factQuery.SetFactType( kFact_Task ); factQuery.SetTaskType( kTask_BlitzCharacter ); CAIWMFact* pFact = m_pAI->GetAIWorkingMemory()->CreateWMFact( kFact_Task ); if ( pFact ) { pFact->SetTaskType( kTask_BlitzCharacter ); pFact->SetTargetObject( hTarget ); pFact->SetIndex( kContext_None ); pFact->SetFactFlags( kFactFlag_Scripted, 1.f ); } } }
int main(){ CAI c; c.startTest(); return 0; }
LTBOOL DoVectorFilterFn(HOBJECT hObj, void *pUserData) { // We're not attacking our self... if (SpecificObjectFilterFn(hObj, pUserData)) { // CharacterHitBox objects are used for vector impacts, don't // impact on the character/body prop object itself.... if (IsCharacter(hObj) || IsBody(hObj) || IsKindOf(hObj, "Intelligence")) { return LTFALSE; } // Check special character hit box cases... if (IsCharacterHitBox(hObj)) { CCharacterHitBox *pCharHitBox = (CCharacterHitBox*) g_pLTServer->HandleToObject(hObj); if (pCharHitBox) { // Make sure we don't hit ourself... HOBJECT hUs = (HOBJECT)pUserData; HOBJECT hTestObj = pCharHitBox->GetModelObject(); if (!hTestObj) return LTFALSE; if (hTestObj == hUs) { return LTFALSE; } // Do special AI hitting AI case... if (IsAI(hUs) && IsAI(hTestObj)) { CAI *pAI = (CAI*) g_pLTServer->HandleToObject(hUs); if (!pAI) return LTFALSE; // We can't hit guys we like, unless they're NEUTRAL CCharacter* pB = (CCharacter*)g_pLTServer->HandleToObject(hTestObj); if (!pB) return LTFALSE; CharacterClass cc = pB->GetCharacterClass(); if (cc != NEUTRAL) { return LIKE != GetAlignement(pAI->GetCharacterClass(), cc); } } // Check for friendly fire if (g_pGameServerShell->GetGameType() == COOPERATIVE_ASSAULT && g_vtNetFriendlyFire.GetFloat() < 1.0f) { // We can't hit guys on our team unless friendly fire is turned on if (IsPlayer(hUs) && IsPlayer(hTestObj)) { CPlayerObj* pUs = (CPlayerObj*) g_pLTServer->HandleToObject(hUs); if (!pUs) return LTFALSE; CPlayerObj* pThem = (CPlayerObj*) g_pLTServer->HandleToObject(hTestObj); if (!pThem) return LTFALSE; if (pUs->GetTeamID() == pThem->GetTeamID()) return LTFALSE; } } } } return LTTRUE; } return LTFALSE; }
void CinematicTrigger::HandleOff() { if (!m_bOn) return; for ( uint32 iWho = 0 ; iWho < MAX_CT_MESSAGES; iWho++ ) { if ( m_hstrWhoPlaysDialogue[iWho] ) { HOBJECT hWho; if ( LT_OK == FindNamedObject(m_hstrWhoPlaysDialogue[iWho], hWho) ) { if ( IsKindOf(hWho, "CAI") ) { CAI* pAI = (CAI*)g_pLTServer->HandleToObject(hWho); pAI->UnlinkCinematicTrigger(m_hObject); } } } } m_bOn = LTFALSE; // If we have a current speaker, make sure he is done talking... if (m_hCurSpeaker) { CCharacter* pChar = (CCharacter*)g_pLTServer->HandleToObject(m_hCurSpeaker); if (pChar) { pChar->StopDialogue(); } // Clear our speaker... g_pLTServer->BreakInterObjectLink(m_hObject, m_hCurSpeaker); m_hCurSpeaker = LTNULL; } // Clear out our last speaker if (m_hLastSpeaker) { CCharacter* pChar = (CCharacter*)g_pLTServer->HandleToObject(m_hLastSpeaker); if (pChar) { pChar->StopDialogue(TRUE); } g_pLTServer->BreakInterObjectLink(m_hObject, m_hLastSpeaker); m_hLastSpeaker = LTNULL; } // Send the clean up trigger message... if (m_hstrCleanUpTriggerTarget && m_hstrCleanUpTriggerMsg) { SendTriggerMsgToObjects(this, g_pLTServer->GetStringData( m_hstrCleanUpTriggerTarget ), g_pLTServer->GetStringData( m_hstrCleanUpTriggerMsg )); } // Turn off the camera... if (m_hCamera && !m_bLeaveCameraOn) { SendTriggerMsgToObject(this, m_hCamera, FALSE, "OFF"); } // Turn off the keyframer... if (m_hKeyFramer) { SendTriggerMsgToObject(this, m_hKeyFramer, FALSE, "OFF"); } SetNextUpdate(m_hObject, 0.0f); if (m_bOneTimeOnly) { // Can't get rid of object if we're leaving the camera on ;)... if (!m_hCamera || !m_bLeaveCameraOn) { g_pLTServer->RemoveObject(m_hObject); } } }
LTBOOL CinematicTrigger::UpdateDialogue() { if (!g_pLTServer) return LTFALSE; // If we haven't yet done so, let all the cinematic participants know // they're under CinematicTrigger control if ( !m_bNotified ) { for ( uint32 iWho = 0 ; iWho < MAX_CT_MESSAGES; iWho++ ) { if ( m_hstrWhoPlaysDialogue[iWho] ) { HOBJECT hWho; if ( LT_OK == FindNamedObject(m_hstrWhoPlaysDialogue[iWho], hWho) ) { if ( IsKindOf(hWho, "CAI") ) { CAI* pAI = (CAI*)g_pLTServer->HandleToObject(hWho); pAI->LinkCinematicTrigger(m_hObject); } } } } m_bNotified = LTTRUE; } // Now update... LTFLOAT fTime = g_pLTServer->GetTime(); // See if we are playing a dialogue... BOOL bDone = FALSE; if (m_hCurSpeaker) { // If sound is done, stop it and wait for new sound... CCharacter* pChar = (CCharacter*)g_pLTServer->HandleToObject(m_hCurSpeaker); if (pChar) { bDone = !pChar->IsPlayingDialogue(); } } if (bDone) { // Send message for our last reply (since the dialog is now done)... if (m_byLastReply) { SendReplyMessage(m_byLastReply); } m_byLastReply = m_byDecision; m_byDecision = 0; // Clear our speaker... g_pLTServer->BreakInterObjectLink(m_hObject, m_hCurSpeaker); m_hCurSpeaker = LTNULL; if(m_byLastReply) { return StartDialogue(m_byLastReply); } m_nCurMessage++; if (m_nCurMessage < MAX_CT_MESSAGES) { m_fNextDialogueStart = fTime + m_fDelay[m_nCurMessage]; } else { return LTFALSE; } } if (!m_hCurSpeaker) { // See if we're done... if (m_nCurMessage >= MAX_CT_MESSAGES || !m_hstrDialogue[m_nCurMessage]) { return LTFALSE; } // Start next sound... if (m_fNextDialogueStart >= 0.0f && m_fNextDialogueStart <= fTime) { return StartDialogue(); } } return LTTRUE; }
void CAITargetSelectCharacterSquad::Activate( CAI* pAI ) { super::Activate( pAI ); // Sanity check. if( !pAI ) { return; } // Bail if AI is not in a squad. ENUM_AI_SQUAD_ID eSquad = g_pAICoordinator->GetSquadID( pAI->m_hObject ); CAISquad* pSquad = g_pAICoordinator->FindSquad( eSquad ); if( !pSquad ) { return; } // Find a squad member targeting a character. CAI* pMember = NULL; bool bTargetingCharacter = false; uint32 cMembers = pSquad->GetNumSquadMembers(); LTObjRef* pMembers = pSquad->GetSquadMembers(); if( pMembers ) { for( uint32 iMember=0; iMember < cMembers; ++iMember ) { pMember = (CAI*)g_pLTServer->HandleToObject( pMembers[iMember] ); if( pMember && pMember->HasTarget( kTarget_Character ) ) { break; } } } // Bail if we failed to find a squad member. if( !pMember ) { return; } // Bail if squad member is not targeting a character. if( !pMember->HasTarget( kTarget_Character ) ) { return; } HOBJECT hTarget = pMember->GetAIBlackBoard()->GetBBTargetObject(); // Bail if squad member has no memory of the character. CAIWMFact factQuery; factQuery.SetFactType( kFact_Character ); factQuery.SetTargetObject( hTarget ); CAIWMFact* pFact = pMember->GetAIWorkingMemory()->FindWMFact( factQuery ); if( !pFact ) { return; } // Create a memory for this character. CAIWMFact* pTargetFact; pTargetFact = pAI->GetAIWorkingMemory()->CreateWMFact( kFact_Character ); pTargetFact->SetTargetObject( hTarget, 1.f ); EnumAIStimulusID eStimulusID; EnumAIStimulusType eStimulusType; pFact->GetStimulus( &eStimulusType, &eStimulusID ); pTargetFact->SetStimulus( eStimulusType, eStimulusID, 0.f ); pTargetFact->SetPos( pFact->GetPos(), 1.f ); pTargetFact->SetRadius( 0.f, 1.f ); // Target the character. TargetCharacter( pAI, pTargetFact ); }
void CAIGoalDrawWeapon::ActivateGoal() { super::ActivateGoal(); // Bail if no holstered weapon, or already have a weapon armed. if( ( !m_pAI->HasHolsterString() ) || ( m_pAI->GetPrimaryWeapon() ) ) { m_fCurImportance = 0.f; return; } // ASSERT(m_hStimulusSource != LTNULL); // Ignore senses other than see enemy. m_pAI->SetCurSenseFlags( kSense_SeeEnemy | kSense_SeeDangerousProjectile | kSense_SeeCatchableProjectile ); m_pGoalMgr->LockGoal( this ); // Set Draw state. m_pAI->SetState( kState_HumanDraw ); if( m_pAI->GetAlarmLevel() >= m_pAI->GetBrain()->GetMajorAlarmThreshold() ) { m_pAI->SetAwareness( kAware_Alert ); } // If stimulated by an AI, target whatever he is targeting. if( IsAI( m_hStimulusSource ) ) { CAI* pAI = (CAI*)g_pLTServer->HandleToObject( m_hStimulusSource ); if( pAI ) { if( pAI->HasTarget() ) { m_pAI->Target( pAI->GetTarget()->GetObject() ); } } } else if( IsCharacter( m_hStimulusSource ) ) { // Only set a target to turn towards for specified senses. switch( m_eSenseType ) { case kSense_SeeEnemy: case kSense_SeeEnemyLean: case kSense_HearEnemyWeaponFire: case kSense_HearEnemyFootstep: { // Only target hated characters. CCharacter *pChar = (CCharacter*)g_pLTServer->HandleToObject( m_hStimulusSource ); if( pChar ) { CharacterAlignment eAlignment = GetAlignment( pChar->GetRelationSet(), m_pAI->GetRelationData() ); if( eAlignment == HATE ) { m_pAI->Target( m_hStimulusSource ); CAIHumanStateDraw* pStateDraw = (CAIHumanStateDraw*)m_pAI->GetState(); pStateDraw->SetFaceTarget( LTTRUE ); } } } break; } } }
int main(int argc, char* argv[]) { CAI c; //Create CAI object c.startTest();// Start the test return 0; }
void CAITargetSelectDisturbance::TargetDisturbance( CAI* pAI, CAIWMFact* pFact ) { // Sanity check. if( !( pAI && pFact ) ) { return; } // Record the existence of a disturbance in the AI's world state. pAI->GetAIWorldState()->SetWSProp( kWSK_DisturbanceExists, pAI->m_hObject, kWST_bool, true ); // Play a sound corresponding to the type of stimulus. EnumAIStimulusID eStimulusID; EnumAIStimulusType eStimulusType; pFact->GetStimulus( &eStimulusType, &eStimulusID ); switch( eStimulusType ) { case kStim_WeaponFireSound: case kStim_WeaponImpactSound: case kStim_WeaponReloadSound: case kStim_DisturbanceSound: case kStim_FootstepSound: case kStim_DeathSound: case kStim_PainSound: { HOBJECT hAlly = g_pAICoordinator->FindAlly( pAI->m_hObject, NULL ); if( hAlly ) { // "Check it out!" // "Roger!" g_pAISoundMgr->RequestAISound( pAI->m_hObject, kAIS_OrderInvestigate, kAISndCat_DisturbanceHeard, NULL, 1.f ); g_pAISoundMgr->RequestAISoundSequence( hAlly, kAIS_Affirmative, pAI->m_hObject, kAIS_OrderInvestigate, kAIS_OrderInvestigate, kAISndCat_Event, NULL, 0.3f ); } else { // "What was that?" g_pAISoundMgr->RequestAISound( pAI->m_hObject, kAIS_DisturbanceHeardAlarming, kAISndCat_DisturbanceHeard, NULL, 1.f ); } } break; // "Flashlight!" case kStim_FlashlightBeamVisible: { g_pAISoundMgr->RequestAISound( pAI->m_hObject, kAIS_DisturbanceSeenFlashlight, kAISndCat_Event, NULL, 0.5f ); HOBJECT hAlly = g_pAICoordinator->FindAlly( pAI->m_hObject, NULL ); if( hAlly ) { // "Check it out!" // "Roger!" g_pAISoundMgr->RequestAISoundSequence( hAlly, kAIS_OrderInvestigate, pAI->m_hObject, kAIS_DisturbanceSeenFlashlight, kAIS_DisturbanceSeenFlashlight, kAISndCat_DisturbanceHeard, NULL, 0.3f ); g_pAISoundMgr->RequestAISoundSequence( pAI->m_hObject, kAIS_Affirmative, hAlly, kAIS_OrderInvestigate, kAIS_DisturbanceSeenFlashlight, kAISndCat_Event, NULL, 0.3f ); } } break; } // Record new target on the BlackBoard. pAI->GetAIBlackBoard()->SetBBTargetType( kTarget_Disturbance ); pAI->GetAIBlackBoard()->SetBBTargetStimulusType( eStimulusType ); pAI->GetAIBlackBoard()->SetBBTargetStimulusID( eStimulusID ); pAI->GetAIBlackBoard()->SetBBTargetChangeTime( g_pLTServer->GetTime() ); pAI->GetAIBlackBoard()->SetBBTargetObject( pFact->GetTargetObject() ); // Record initial disturbance position. // If the stimulus is dynamic, AITarget will track its movement. LTVector vTargetPos = pFact->GetPos(); pAI->GetAIBlackBoard()->SetBBTargetPosition( vTargetPos ); // If the disturbance is coming from an ally's weapon fire sound, // then treat the disturbance position as the position of whatever // the ally is firing at. if( IsAI( pFact->GetTargetObject() ) ) { CAI* pOtherAI = (CAI*)g_pLTServer->HandleToObject( pFact->GetTargetObject() ); if( pOtherAI && pOtherAI->HasTarget( kTarget_Character ) && ( eStimulusType == kStim_WeaponFireSound ) && ( kCharStance_Like == g_pCharacterDB->GetStance( pAI->GetAlignment(), pOtherAI->GetAlignment() ) ) ) { LTVector vTargetPos = pOtherAI->GetAIBlackBoard()->GetBBTargetPosition(); pAI->GetAIBlackBoard()->SetBBTargetPosition( vTargetPos ); pFact->SetPos( vTargetPos, 1.f ); } } }
bool Alarm::OnTrigger(HOBJECT hSender, const CParsedMsg &cMsg) { static CParsedMsg::CToken s_cTok_Activate(s_szActivate); static CParsedMsg::CToken s_cTok_Lock(s_szLock); static CParsedMsg::CToken s_cTok_Unlock(s_szUnlock); if ( cMsg.GetArg(0) == s_cTok_Activate ) { // If the alarm is activated from a command, the sender is // NULL (dammit!). So treat it as player-activated. // If the alarm is activated by something other than AI // (e.g. a command object) consider it player activated. if( !IsAI( hSender ) ) { CPlayerObj *pPlayer = g_pCharacterMgr->FindPlayer(); hSender = pPlayer->m_hObject; } HOBJECT hStimulus = hSender; if( IsPlayer(hSender) ) { // Run the alarm's player-activate command. if( m_hstrPlayerActivateCommand ) { const char *szCmd = g_pLTServer->GetStringData( m_hstrPlayerActivateCommand ); if( g_pCmdMgr->IsValidCmd( szCmd ) ) { g_pCmdMgr->Process( szCmd, m_hObject, m_hObject ); } } } else { // The stimulus is the target of the AI who activated the alarm. CAI* pAI = (CAI*)g_pLTServer->HandleToObject(hSender); hStimulus = pAI->GetTarget()->GetObject(); } // Ensure that lists of Alert and Respond regions are set up. if( ( m_fRegionsGroupRadius == 0.f ) && ( ( m_lstAlertRegions.size() > 0 ) || ( m_lstRespondRegions.size() > 0 ) || ( m_lstSearchRegions.size() > 0 ) ) ) { CalculateRegionsGroupRadius(); } // Place an alarm stimulus. // The stimulus position and radius are set to values that encompass // all of the regions affected by the alarm. g_pAIStimulusMgr->RegisterStimulus(kStim_EnemyAlarmSound, hStimulus, m_hObject, m_vRegionsGroupCenter, m_fRegionsGroupRadius, m_fAlarmSoundTime); AITRACE( AIShowAlarms, ( m_hObject, "Triggering alarm" ) ); } else if ( cMsg.GetArg(0) == s_cTok_Lock ) { m_bLocked = LTTRUE; } else if ( cMsg.GetArg(0) == s_cTok_Unlock ) { m_bLocked = LTFALSE; } else return Prop::OnTrigger(hSender, cMsg); return true; }