void SmartChaseState::Update(float _deltaTime) { if (!m_zombie->m_pathToTake.empty()) { FollowPath(_deltaTime); } else { if (!m_requestedPath) { FindPath(); } } if (!m_zombie->CollideWithAgent(m_zombie->m_player.lock().get())) { //collision handle } if (m_zombie->m_health <= 50.0f) { //The zombie is low health, he wants to run ! if (!m_requestedPath) { //only switch states if there is no path requested (or the callback will try to access deleted memory) m_zombie->m_stateManager.SetState(new RetreatState(m_zombie)); } } else if (!CheckForPlayer()) { //The player is out of zombie chase range if (!m_requestedPath) { //only switch states if there is no path requested (or the callback will try to access deleted memory) m_zombie->m_stateManager.SetState(new SmartPatrolState(m_zombie)); } } }
void Entity::Update(void) { if( Path ) FollowPath(); }
//---------------------- CalculateWeightedSum ---------------------------- // // this simply sums up all the active behaviors X their weights and // truncates the result to the max available steering force before // returning //------------------------------------------------------------------------ ofVec3f SteeringBehaviors::CalculateWeightedSum() { if (On(wall_avoidance)) { m_SteeringForce += WallAvoidance(m_Vehicle->GameWorld()->getWalls()) * m_WeightObstacleAvoidance; } if (On(obstacle_avoidance)) { m_SteeringForce += ObstacleAvoidance( m_Vehicle->GameWorld()->getObstacles() ) * m_WeightObstacleAvoidance; } if (On(seek)) { m_SteeringForce += Seek(m_Vehicle->Target()->Pos()) * m_WeightSeek; } if (On(flee)) { m_SteeringForce += Flee(m_Vehicle->Target()->Pos()) * m_WeightFlee; } if (On(arrive)) { m_SteeringForce += Arrive(m_Vehicle->Target()->Pos(), normal) * m_WeightArrive; } if (!isSpacePartioningOn()) { if (On(separation)) { m_SteeringForce += Separation(m_Vehicle->rGroup()) * m_WeightSeparation; } if (On(alignment)) { m_SteeringForce += Alignment(m_Vehicle->rGroup()) * m_WeightAlignment; } if (On(cohesion)) { m_SteeringForce += Cohesion(m_Vehicle->rGroup()) * m_WeightCohesion; } } else { if (On(separation)) { m_SteeringForce += SeparationPlus(m_Vehicle->rGroup()) * m_WeightSeparation; } if (On(alignment)) { m_SteeringForce += AlignmentPlus(m_Vehicle->rGroup()) * m_WeightAlignment; } if (On(cohesion)) { m_SteeringForce += CohesionPlus(m_Vehicle->rGroup()) * m_WeightCohesion; } } if (On(repulsion)) { //need to retag the guys! m_SteeringForce += Repulsion(m_Vehicle->oGroup()) * m_WeightRepulsion; } if (On(wander)) { m_SteeringForce += Wander() * m_WeightWander; } if (On(follow_path)) { m_SteeringForce += FollowPath() * m_WeightFollowPath; } m_SteeringForce.limit(m_Vehicle->MaxForce()); return m_SteeringForce; }
//---------------------- CalculatePrioritized ---------------------------- // // this method calls each active steering behavior in order of priority // and acumulates their forces until the max steering force magnitude // is reached, at which time the function returns the steering force // accumulated to that point //------------------------------------------------------------------------ ofVec3f SteeringBehaviors::CalculatePrioritized() { ofVec3f force; if (On(wall_avoidance)) { force = WallAvoidance(m_Vehicle->GameWorld()->getWalls()) * m_WeightObstacleAvoidance; if (!AccumulateForce(m_SteeringForce, force)) return m_SteeringForce; } if (On(obstacle_avoidance)) { force = ObstacleAvoidance(m_Vehicle->GameWorld()->getObstacles()) * m_WeightObstacleAvoidance; if (!AccumulateForce(m_SteeringForce, force)) return m_SteeringForce; } if (On(flee)) { force = Flee(m_Vehicle->Target()->Pos()) * m_WeightFlee; if (!AccumulateForce(m_SteeringForce, force)) return m_SteeringForce; } if (On(repulsion)) { //need to retage the guys! force = Repulsion(m_Vehicle->oGroup()) * m_WeightRepulsion; if (!AccumulateForce(m_SteeringForce, force)) return m_SteeringForce; } if (!isSpacePartioningOn()) { if (On(separation)) { force = Separation(m_Vehicle->rGroup()) * m_WeightSeparation; if (!AccumulateForce(m_SteeringForce, force)) return m_SteeringForce; } if (On(alignment)) { force = Alignment(m_Vehicle->rGroup()) * m_WeightAlignment; if (!AccumulateForce(m_SteeringForce, force)) return m_SteeringForce; } if (On(cohesion)) { force = Cohesion(m_Vehicle->rGroup()) * m_WeightCohesion; if (!AccumulateForce(m_SteeringForce, force)) return m_SteeringForce; } } else { if (On(separation)) { force = SeparationPlus(m_Vehicle->rGroup()) * m_WeightSeparation; if (!AccumulateForce(m_SteeringForce, force)) return m_SteeringForce; } if (On(alignment)) { force = AlignmentPlus(m_Vehicle->rGroup()) * m_WeightAlignment; if (!AccumulateForce(m_SteeringForce, force)) return m_SteeringForce; } if (On(cohesion)) { force = CohesionPlus(m_Vehicle->rGroup()) * m_WeightCohesion; if (!AccumulateForce(m_SteeringForce, force)) return m_SteeringForce; } } if (On(seek)) { force = Seek(m_Vehicle->Target()->Pos()) * m_WeightSeek; if (!AccumulateForce(m_SteeringForce, force)) return m_SteeringForce; } if (On(arrive)) { force = Arrive(m_Vehicle->Target()->Pos(), normal) * m_WeightArrive; if (!AccumulateForce(m_SteeringForce, force)) return m_SteeringForce; } if (On(wander)) { force = Wander() * m_WeightWander; if (!AccumulateForce(m_SteeringForce, force)) return m_SteeringForce; } if (On(follow_path)) { force = FollowPath() * m_WeightFollowPath; if (!AccumulateForce(m_SteeringForce, force)) return m_SteeringForce; } return m_SteeringForce; }
bool UGridMovementComponent::MoveTo(const ATile &Target) { bool PathExists = CreatePath(Target); if (PathExists) { FollowPath(); } return PathExists; }
HRESULT CAdActor::Update() { m_CurrentSprite = NULL; if(m_State==STATE_READY) { if(m_AnimSprite) { SAFE_DELETE(m_AnimSprite); } if(m_AnimSprite2) { m_AnimSprite2 = NULL; } } // finished playing animation? if(m_State==STATE_PLAYING_ANIM && m_AnimSprite!=NULL && m_AnimSprite->m_Finished) { m_State = m_NextState; m_NextState = STATE_READY; m_CurrentSprite = m_AnimSprite; } if(m_State==STATE_PLAYING_ANIM_SET && m_AnimSprite2!=NULL && m_AnimSprite2->m_Finished) { m_State = m_NextState; m_NextState = STATE_READY; m_CurrentSprite = m_AnimSprite2; } if(m_Sentence && m_State!=STATE_TALKING) m_Sentence->Finish(); bool already_moved = false; switch(m_State) { ////////////////////////////////////////////////////////////////////////// case STATE_PLAYING_ANIM: m_CurrentSprite = m_AnimSprite; break; ////////////////////////////////////////////////////////////////////////// case STATE_PLAYING_ANIM_SET: m_CurrentSprite = m_AnimSprite2; break; ////////////////////////////////////////////////////////////////////////// case STATE_TURNING_LEFT: if(m_TempSprite2==NULL || m_TempSprite2->m_Finished) { m_Dir = (TDirection)(m_Dir - 1); if(m_Dir<0) m_Dir = (TDirection)(NUM_DIRECTIONS - 1); if(m_Dir==m_TargetDir) { m_TempSprite2 = NULL; m_State = m_NextState; m_NextState = STATE_READY; } else { if(m_TurnLeftSprite) { m_TempSprite2 = m_TurnLeftSprite->GetSprite(m_Dir); } else { CAdSpriteSet* Anim = GetAnimByName(m_TurnLeftAnimName); if(Anim) m_TempSprite2 = Anim->GetSprite(m_Dir); } if(m_TempSprite2) { m_TempSprite2->Reset(); if(m_TempSprite2->m_Looping) m_TempSprite2->m_Looping = false; } m_CurrentSprite = m_TempSprite2; } } else m_CurrentSprite = m_TempSprite2; break; ////////////////////////////////////////////////////////////////////////// case STATE_TURNING_RIGHT: if(m_TempSprite2==NULL || m_TempSprite2->m_Finished) { m_Dir = (TDirection)(m_Dir + 1); if(m_Dir>=NUM_DIRECTIONS) m_Dir = (TDirection)(0); if(m_Dir==m_TargetDir) { m_TempSprite2 = NULL; m_State = m_NextState; m_NextState = STATE_READY; } else { if(m_TurnRightSprite) { m_TempSprite2 = m_TurnRightSprite->GetSprite(m_Dir); } else { CAdSpriteSet* Anim = GetAnimByName(m_TurnRightAnimName); if(Anim) m_TempSprite2 = Anim->GetSprite(m_Dir); } if(m_TempSprite2) { m_TempSprite2->Reset(); if(m_TempSprite2->m_Looping) m_TempSprite2->m_Looping = false; } m_CurrentSprite = m_TempSprite2; } } else m_CurrentSprite = m_TempSprite2; break; ////////////////////////////////////////////////////////////////////////// case STATE_SEARCHING_PATH: // keep asking scene for the path if(((CAdGame*)Game)->m_Scene->GetPath(CBPoint(m_PosX, m_PosY), *m_TargetPoint, m_Path, this)) m_State = STATE_WAITING_PATH; break; ////////////////////////////////////////////////////////////////////////// case STATE_WAITING_PATH: // wait until the scene finished the path if(m_Path->m_Ready) FollowPath(); break; ////////////////////////////////////////////////////////////////////////// case STATE_FOLLOWING_PATH: GetNextStep(); already_moved = true; break; ////////////////////////////////////////////////////////////////////////// case STATE_TALKING: { m_Sentence->Update(m_Dir); if(m_Sentence->m_CurrentSprite) m_TempSprite2 = m_Sentence->m_CurrentSprite; bool TimeIsUp = (m_Sentence->m_Sound && m_Sentence->m_SoundStarted && (!m_Sentence->m_Sound->IsPlaying()&&!m_Sentence->m_Sound->IsPaused())) || (!m_Sentence->m_Sound && m_Sentence->m_Duration <= Game->m_Timer - m_Sentence->m_StartTime); if(m_TempSprite2==NULL || m_TempSprite2->m_Finished || (/*m_TempSprite2->m_Looping &&*/ TimeIsUp)) { if(TimeIsUp) { m_Sentence->Finish(); m_TempSprite2 = NULL; m_State = m_NextState; m_NextState = STATE_READY; } else { m_TempSprite2 = GetTalkStance(m_Sentence->GetNextStance()); if(m_TempSprite2) { m_TempSprite2->Reset(); m_CurrentSprite = m_TempSprite2; ((CAdGame*)Game)->AddSentence(m_Sentence); } } } else { m_CurrentSprite = m_TempSprite2; ((CAdGame*)Game)->AddSentence(m_Sentence); } } break; ////////////////////////////////////////////////////////////////////////// case STATE_READY: if(!m_AnimSprite && !m_AnimSprite2) { if(m_Sprite) m_CurrentSprite = m_Sprite; else { if(m_StandSprite) { m_CurrentSprite = m_StandSprite->GetSprite(m_Dir); } else { CAdSpriteSet* Anim = GetAnimByName(m_IdleAnimName); if(Anim) m_CurrentSprite = Anim->GetSprite(m_Dir); } } } break; } // default: stand animation if(!m_CurrentSprite) { if(m_Sprite) m_CurrentSprite = m_Sprite; else { if(m_StandSprite) { m_CurrentSprite = m_StandSprite->GetSprite(m_Dir); } else { CAdSpriteSet* Anim = GetAnimByName(m_IdleAnimName); if(Anim) m_CurrentSprite = Anim->GetSprite(m_Dir); } } } if(m_CurrentSprite && !already_moved) { m_CurrentSprite->GetCurrentFrame(m_Zoomable?((CAdGame*)Game)->m_Scene->GetZoomAt(m_PosX, m_PosY):100, m_Zoomable?((CAdGame*)Game)->m_Scene->GetZoomAt(m_PosX, m_PosY):100); if(m_CurrentSprite->m_Changed) { m_PosX += m_CurrentSprite->m_MoveX; m_PosY += m_CurrentSprite->m_MoveY; AfterMove(); } } //Game->QuickMessageForm("%s", m_CurrentSprite->m_Filename); UpdateBlockRegion(); m_Ready = (m_State == STATE_READY); UpdatePartEmitter(); UpdateSpriteAttachments(); return S_OK; }
void NPCAI(int NpcIndex) { /* '************************************************************** */ /* 'Author: Unknown */ /* 'Last Modify by: ZaMa */ /* 'Last Modify Date: 15/11/2009 */ /* '08/16/2008: MarKoxX - Now pets that do mel� attacks have to be near the enemy to attack. */ /* '15/11/2009: ZaMa - Implementacion de npc objetos ai. */ /* '************************************************************** */ /* '<<<<<<<<<<< Ataques >>>>>>>>>>>>>>>> */ if (Npclist[NpcIndex].MaestroUser == 0) { /* 'Busca a alguien para atacar */ /* '�Es un guardia? */ if (Npclist[NpcIndex].NPCtype == eNPCType_GuardiaReal) { GuardiasAI(NpcIndex, false); } else if (Npclist[NpcIndex].NPCtype == eNPCType_Guardiascaos) { GuardiasAI(NpcIndex, true); } else if (Npclist[NpcIndex].Hostile && Npclist[NpcIndex].Stats.Alineacion != 0) { HostilMalvadoAI(NpcIndex); } else if (Npclist[NpcIndex].Hostile && Npclist[NpcIndex].Stats.Alineacion == 0) { HostilBuenoAI(NpcIndex); } } else { /* 'Evitamos que ataque a su amo, a menos */ /* 'que el amo lo ataque. */ /* 'Call HostilBuenoAI(NpcIndex) */ } /* '<<<<<<<<<<<Movimiento>>>>>>>>>>>>>>>> */ switch (Npclist[NpcIndex].Movement) { case TipoAI_MueveAlAzar: if (Npclist[NpcIndex].flags.Inmovilizado == 1) { return; } if (Npclist[NpcIndex].NPCtype == eNPCType_GuardiaReal) { if (RandomNumber(1, 12) == 3) { MoveNPCChar(NpcIndex, vb6::CByte( RandomNumber(eHeading_NORTH, eHeading_WEST))); } PersigueCriminal(NpcIndex); } else if (Npclist[NpcIndex].NPCtype == eNPCType_Guardiascaos) { if (RandomNumber(1, 12) == 3) { MoveNPCChar(NpcIndex, vb6::CByte( RandomNumber(eHeading_NORTH, eHeading_WEST))); } PersigueCiudadano(NpcIndex); } else { if (RandomNumber(1, 12) == 3) { MoveNPCChar(NpcIndex, vb6::CByte( RandomNumber(eHeading_NORTH, eHeading_WEST))); } } /* 'Va hacia el usuario cercano */ break; case TipoAI_NpcMaloAtacaUsersBuenos: IrUsuarioCercano(NpcIndex); /* 'Va hacia el usuario que lo ataco(FOLLOW) */ break; case TipoAI_NPCDEFENSA: SeguirAgresor(NpcIndex); /* 'Persigue criminales */ break; case TipoAI_GuardiasAtacanCriminales: PersigueCriminal(NpcIndex); break; case TipoAI_SigueAmo: if (Npclist[NpcIndex].flags.Inmovilizado == 1) { return; } SeguirAmo(NpcIndex); if (RandomNumber(1, 12) == 3) { MoveNPCChar(NpcIndex, vb6::CByte(RandomNumber(eHeading_NORTH, eHeading_WEST))); } break; case TipoAI_NpcAtacaNpc: AiNpcAtacaNpc(NpcIndex); break; case TipoAI_NpcObjeto: AiNpcObjeto(NpcIndex); break; case TipoAI_NpcPathfinding: if (Npclist[NpcIndex].flags.Inmovilizado == 1) { return; } if (ReCalculatePath(NpcIndex)) { PathFindingAI(NpcIndex); /* 'Existe el camino? */ /* 'Si no existe nos movemos al azar */ if (Npclist[NpcIndex].PFINFO.NoPath) { /* 'Move randomly */ MoveNPCChar(NpcIndex, RandomNumber(eHeading_NORTH, eHeading_WEST)); } } else { if (!PathEnd(NpcIndex)) { FollowPath(NpcIndex); } else { Npclist[NpcIndex].PFINFO.PathLenght = 0; } } break; default: break; } return; }