public void releaseAI() { state = AIState.free; guardPos.parent = transform; guardPos.localPosition = Vector3.zero; ai.followTranform = null; }
void Follower() { i_curWaypoint = c_terraingen.i_waypoint[i_kartRef]; i_nextWaypoint = i_curWaypoint+1; v2_nextWaypointPos = c_waypoint.l_waypoints[i_nextWaypoint]; if(c_terraingen.go_focalPoint[c_terraingen.i_lead].transform == transform){ c_kartcontroller.f_mMaxVelocity=c_kartcontroller.f_mMaxVelocity*0.9f; state = AIState.leader; } if(c_terraingen.i_placement[i_kartRef] == 1){ state = AIState.challenger; } if(i_curWaypoint < c_terraingen.i_waypoint[c_terraingen.i_lead]) { if(Vector3.Cross(new Vector2(transform.TransformPoint(0,0,1).x,transform.TransformPoint(0,0,1).z)-new Vector2(transform.position.x,transform.position.z),(c_waypoint.l_waypoints[i_nextWaypoint])-new Vector2(transform.position.x,transform.position.z)).z > 0) i_waypointDirection = 0; //left else i_waypointDirection = 1; //right f_angle = Vector2.Angle(new Vector2(transform.TransformPoint(0,0,1).x,transform.TransformPoint(0,0,1).z)-new Vector2(transform.position.x,transform.position.z),c_waypoint.l_waypoints[i_nextWaypoint]-new Vector2(transform.position.x,transform.position.z)); if(f_angle > f_angleLenience ) { c_kartcontroller.i_AIDirection = i_waypointDirection; } else c_kartcontroller.i_AIDirection = -1; if(f_angle > f_anglePanic) { if(c_kartcontroller.f_mVelocity > c_kartcontroller.f_mMaxVelocity*0.75f) c_kartcontroller.b_AIForward = false; else c_kartcontroller.b_AIForward = true; } else c_kartcontroller.b_AIForward = true; } else c_kartcontroller.b_AIForward = true; }
/// <summary> /// Determines whether this instance is satisfied. /// </summary> /// <param name="state">The state of the AI.</param> /// <returns></returns> /// <exception cref="System.Exception">Invalid equality type in IntCondtion.IsSatisfied().</exception> public override bool IsSatisfied(AIState state) { var value = state.GetInt(ID); if (!value.HasValue) { return false; } switch (Equality) { case EqualityType.Equals: return value == Value; case EqualityType.NotEquals: return value != Value; case EqualityType.GreaterThan: return value > Value; case EqualityType.LessThan: return value < Value; case EqualityType.GreaterThanOrEqual: return value >= Value; case EqualityType.LessThanOrEqual: return value <= Value; default: throw new Exception("Invalid equality type in IntCondtion.IsSatisfied()."); } }
public Enemy(String aiName, Vector2 position) : base(position, Vector2.Zero, Vector2.Zero, new Vector2(MAX_VELOCITY_X, MAX_VELOCITY_Y), new Vector2(ACCELERATION_X, ACCELERATION_Y), new Vector2(DECELERATION_X, DECELERATION_Y), TextureManager.GetTexture(TextureNames.PLAYER_TWO_IDLE)) { behaviour = new AIStateMachine(XMLFILE, aiName); currentState = behaviour.GetCurrentState(); // These should be loaded from either XML // or be statics in child-classes specific // to types of AIs. moveTime = new ParameterDouble(); moveTime.alpha = 500; moveTime.beta = 500; moveTime.distribution = Distribution.Normal; // Temporary: timeBetweenFire = new ParameterDouble(); timeBetweenFire.alpha = 1000; timeBetweenFire.beta = 1000; timeBetweenFire.distribution = Distribution.Normal; }
public void Reset() { transform.position = m_Player.transform.position + (-m_Player.transform.forward * m_DistanceFromPlayer); m_Activated = false; m_IsMoving = false; m_State = AIState.IDLE; }
// Use this for initialization void Start () { initPos = transform.position; anim = gameObject.GetComponent<Animation> (); aiState = AIState.Idle; }
public void guard() { releaseAI(); state = AIState.guard; guardPos.parent = null; ai.followTranform = guardPos; }
//couroutine change AI state with a delay time IEnumerator ChangeAIStateDelay(AIState state, float time) { yield return new WaitForSeconds(time); currentState = state; iceChunkTimer = 1.0f; StopCoroutine("ChangeAIStateDelay"); }
public override void Collided() { switch (State) { case AIState.Patrolling: Target = Position; break; case AIState.Chasing: Target = Position; State = AIState.FollowingPath; break; case AIState.FollowingPath: Target = Position; regeneratePath = true; break; case AIState.Attacking: Target = Position; //if ((Target - Position).Length() > 100f) //{ // Target = Position; // State = AIState.FollowingPath; // regeneratePath = true; //} break; } base.Collided(); }
/** * Constructor for manually-initialized AISMs **/ public AIStateMachine(String aiName, int numStates, AIState[] stateNames, double[][] tmatrix) { machineName = aiName; rtransition = new Random(); StateNames = new List<AIState>(numStates); TransitionMatrix = new Double[numStates][]; Initialize(numStates, stateNames, tmatrix); }
public Gateway(Game game, GraphicsDeviceManager graphics, Vector2 location) : base(game, graphics, "content/gateway", true) { this.mLocation = location; Random r = new Random(); mCurrentState = (AIState)r.Next(0, 2); }
public void PuckCollision() { if (state == AIState.Attack) { state = AIState.Defense; thinkTimer = 0.0f; } }
/// <summary> /// Forgets the old state and starts a new one. /// </summary> public void SwitchState(AIState state) { if (CurrentState != null) stateStack.Pop().OnStop(actor); stateStack.Push(state); state.OnStart(actor); }
public AICohere(AIState state, Transform obj, float weight){ trans = obj; go = new GameObject(); average = go.transform; this.State = state; this.Weight = weight; Targets = new Transform[]{}; }
public void Initialize(int spookPrototypeIndex, GameLevel level, JsonNPC jsonNPC) { BaseInitialize(spookPrototypeIndex, level); avatar.Initialize(this, jsonNPC.Avatar); state = jsonNPC.State; NextAction(); }
public void Initialize(int spookPrototypeIndex, GameLevel level) { BaseInitialize(spookPrototypeIndex, level); avatar.Initialize(this); state = AIState.FirstWalk; NextAction(); }
//init upon enabled, called faster than Start func void Awake() { origPos = transform.position; iceChunkArr = new GameObject[3]; currentState = AIState.state_Spawn_Self; iceChunkTimer = 1.0f; iceChunkPooler = transform.FindChild("iceChunkPooler"); }
// Use this for initialization void Start () { initPos = transform.position; anim = gameObject.GetComponent<Animation> (); aiState = AIState.Idle; anim["Jump1"].speed = 2; anim["Jump2"].speed = 2; anim["Jump3"].speed = 2; }
public AiStateMachine(Enemy owner, AIState constState, AIState startState) { this.owner = owner; this.constState = constState; this.dynamicState = startState; constState.Enter(owner); dynamicState.Enter(owner); }
void Awake() { currentState = AIState.state_Spawn_self; leafPadPooler = transform.FindChild("leafPadPooler"); leafPadArr = new GameObject[4]; cannabisController = GetComponent<Animator>(); theSmoke = Instantiate(smoke, Vector2.zero, Quaternion.identity) as GameObject; theSmoke.SetActive (false); }
public ShipAI(Vector2 position, BulletManager bulletManager) : base(position, bulletManager) { _state = AIState.Wandering; MovementController.Rotation = _gen.Next(0, 360); StatRecorder = new AIShipStatRecorder(this); SeekingShip = -1; Name = "CPU" + ID; LevelManager.OnLevel += CheckReset; }
public static AISubstate[] GetSubstates(AIState parent) { AISubstate[] substates = new AISubstate[3]; substates[0] = new AISubstate_GetSpace(parent); substates[1] = new AISubstate_GetBehind(parent); substates[2] = new AISubstate_Chase(parent); //maybe add missile lock state, maybe make it parallel //substates[3] = new AISubstate_AttackEvade --> if shit hits the fan can add a straight up evasion goal, cancelling attack. //if threat is tolerable blend attack vector with evasion vector. contains substates //substates[4] = new AISubstate_AttackAvoidCollision --> similar to AttackEvade return substates; }
public AISubstate(AIState parentState) { this.parentState = parentState; this.pilot = parentState.pilot; this.entity = parentState.pilot.entity; this.transform = entity.transform; this.sensorSystem = entity.sensorSystem; this.engineSystem = entity.engineSystem; this.weaponSystem = entity.weaponSystem; this.commSystem = entity.commSystem; this.navSystem = entity.navSystem; }
/// <summary> /// Determines whether this instance is satisfied. /// </summary> /// <param name="state">The state of the AI.</param> /// <returns></returns> public override bool IsSatisfied(AIState state) { foreach (var condition in Conditions) { if (!condition.IsSatisfied(state)) { return false; } } return true; }
}//END of Start() // Update is called once per frame void Update () { //Change AI state based on ammo count ~Adam if(mAmmoRemaining > 0) { mAIState = AIState.ATTACKING; } else { if (GetComponent<SpriteRenderer>().color == Color.blue) { GetComponent<SpriteRenderer>().color = Color.black; } mAIState = AIState.RELOADING; } //If attacking, move around and throw tomatos if(mAIState == AIState.ATTACKING) { mLookTarget = mTargetPlayer.gameObject; mAttackTimer -= Time.deltaTime; mMoveTimer -= Time.deltaTime; if(mAttackTimer <= 0f) { ThrowTomato(); } if(mMoveTimer <= 0f || Vector2.Distance (transform.position,mTargetPos) <= 1f) { SetMoveTarget(); } } else if (mAIState == AIState.RELOADING) { FindNearestStand(); } MoveToTarget(); LookAtTarget(); }//END of Update
void checkState() { float distance = (target.transform.position - transform.position).magnitude; if (distance < attackDistance && target.alive) { state = AIState.Attack; return; } else { state = AIState.Idle; } }
public Enemy(Vector2f _position, String _file, Entity _target, GameWorld _world, uint _layer = 2) { create(_position, _file, _layer); mTimer.Start(); mDie.Start(); mWorld = _world; mEntityType = EntityType.Enemy; mState = AIState.Chase; mTarget = _target; mMovement = new Vector2f(); mHealth = 3; }
// Constructor public PlayerAI(string name = "") : base(name) { state = AIState.Waiting; map = null; turnActions = new Queue<NotifyArgs>(); waitingToSend = false; pushedState = false; departureTime = 0; friendlyPrograms = new List<Haxxit.Maps.ProgramHeadNode>(); enemyPrograms = new List<Haxxit.Maps.ProgramHeadNode>(); mapData = null; backgroundState = null; }
// Use this for initialization void Start () { anim = gameObject.GetComponent<Animation> (); audioSource = gameObject.GetComponent<AudioSource> (); anim["Shoot"].speed =animSpeed; anim["idle"].speed =animSpeed; anim["Seleb_berdiri"].speed =animSpeed; anim["Seleb_tepuk tangan"].speed =animSpeed; anim["Seleb_duduk"].speed =animSpeed; aiState = AIState.Idle; }
public void SendToTarget() { m_State = AIState.TRIGGERED; m_Target = FindTarget(); if (m_Target == null) { m_State = AIState.IDLE; Debug.Log("No Traps in range"); return; } m_Activated = true; m_State = AIState.ACTIVE; StartCoroutine(MoveToTarget(m_Target)); }
public override void TakeTurn() { switch (CurState) { case (AIState.Wander): //If the current direction is walkable, do it! if (LinkedCreature.Level.CheckWalkable(Utilities.GeneralMethods.AddPoints(LinkedCreature.Position, CurWanderDirection))) { LinkedCreature.Move(CurWanderDirection); if (RndGen.Next(0, 100) < 25) //Maybe decide on a new direction { do { CurWanderDirection.X = RndGen.Next(-1, 1); CurWanderDirection.Y = RndGen.Next(-1, 1); } while (CurWanderDirection.X == 0 && CurWanderDirection.Y == 0); } } else //Not walkable, decide on a new one. { do { CurWanderDirection.X = RndGen.Next(-1, 1); CurWanderDirection.Y = RndGen.Next(-1, 1); } while (CurWanderDirection.X == 0 && CurWanderDirection.Y == 0); } FOVHandler.CalculateFOV(LinkedCreature.Position.X, LinkedCreature.Position.Y, 0, false, libtcodWrapper.FovAlgorithm.Basic); if (FOVHandler.CheckTileFOV(Player.Position.X, Player.Position.Y)) //If can see player { PlayerLastSeenAt = Player.Position; //Remember where CurState = AIState.Follow; //Follow him! CurFollowPath = ComputePath(LinkedCreature.Position, PlayerLastSeenAt); //How do we get there? CurFollowPathIndex = 0; //Start from the beginning } if (LinkedCreature.Limbs[0].HP <= 33) //OH NO! { CurState = AIState.Flee; } break; case (AIState.Follow): FOVHandler.CalculateFOV(LinkedCreature.Position.X, LinkedCreature.Position.Y, 0, false, libtcodWrapper.FovAlgorithm.Basic); if (PlayerLastSeenAt != Player.Position) //If player isn't in the same place still... { if (FOVHandler.CheckTileFOV(Player.Position.X, Player.Position.Y)) //And we can see player { PlayerLastSeenAt = Player.Position; //Update our memory CurFollowPath = ComputePath(LinkedCreature.Position, PlayerLastSeenAt); //And figure out a new path. CurFollowPathIndex = 0; //And start from the beginning of it! } } if (CurFollowPathIndex >= 0 && CurFollowPathIndex < CurFollowPath.Count - 1) //We're on the way to the player (Or where we saw him last) { LinkedCreature.Move(CurFollowPath[CurFollowPathIndex].X - LinkedCreature.Position.X, CurFollowPath[CurFollowPathIndex].Y - LinkedCreature.Position.Y); } CurFollowPathIndex++; if (Utilities.GeneralMethods.Distance(LinkedCreature.Position, Player.Position) == 1) //We're in stabby range! { CurState = AIState.Attack; //ATTACK!!!! } if (CurFollowPathIndex == CurFollowPath.Count - 1 && !FOVHandler.CheckTileFOV(Player.Position.X, Player.Position.Y)) //We're there but he's gone! We can't see him! { CurState = AIState.Wander; } if (LinkedCreature.Limbs[0].HP <= 33) //Ack! We've been wounded! { CurState = AIState.Flee; } break; case (AIState.Attack): Utilities.MessageLog.AddMsg(LinkedCreature.FirstName + " swings at you!"); LinkedCreature.Attack(Player); if (Utilities.GeneralMethods.Distance(LinkedCreature.Position, Player.Position) != 1) { CurState = AIState.Follow; } if (LinkedCreature.Limbs[0].HP <= 33) { CurState = AIState.Flee; } break; case (AIState.Flee): Point Diff = Utilities.GeneralMethods.SubtractPoints(LinkedCreature.Position, Player.Position); Point FleeDir = new Point(); if (Diff.X > 0) { FleeDir.X = 1; } else if (Diff.X < 0) { FleeDir.X = -1; } else { FleeDir.X = 0; } if (Diff.Y > 0) { FleeDir.Y = 1; } else if (Diff.Y < 0) { FleeDir.Y = -1; } else { FleeDir.Y = 0; } LinkedCreature.Move(FleeDir); break; } }
/********************* * Attacks intensity * *********************/ /** * Method : ChangeStateRoaming * Param : void * Desc : Set the CurrentState to Roaming * Return : Void **/ void ChangeStateRoaming() { CurrentState = AIState.Roaming; KeepDirectionTimer = KeepDirection_time; }
// Update is called once per frame void FixedUpdate() { //Wait for the next course of action if (actionTimer > 0) { actionTimer -= Time.deltaTime; } else { switchAction = true; } if (currentState == AIState.Idle) { if (switchAction) { if (enemy) { //Run to agent.SetDestination(enemy.transform.position); currentState = AIState.Running; SwitchAnimationState(currentState); } else { //No enemies nearby, start eating actionTimer = Random.Range(2, 5); currentState = AIState.growling; SwitchAnimationState(currentState); //Keep last 5 Idle positions for future reference previousIdlePoints.Add(transform.position); if (previousIdlePoints.Count > 5) { previousIdlePoints.RemoveAt(0); } } } } else if (currentState == AIState.Walking) { //Set NavMesh Agent Speed agent.speed = walkingSpeed; // Check if we've reached the destination if (DoneReachingDestination()) { currentState = AIState.Idle; } } else if (currentState == AIState.growling) { if (switchAction) { //Wait for current animation to finish playing //Maybe use this for attack also if (!animator || animator.GetCurrentAnimatorStateInfo(0).normalizedTime - Mathf.Floor(animator.GetCurrentAnimatorStateInfo(0).normalizedTime) > 0.99f) { //Walk to another random destination agent.destination = RandomNavSphere(transform.position, Random.Range(3, 10)); currentState = AIState.Walking; SwitchAnimationState(currentState); } } } else if (currentState == AIState.Running) { //Set NavMesh Agent Speed agent.speed = runningSpeed; //Run to enemy if (enemy) { if (reverseFlee) { if (DoneReachingDestination() && timeStuck < 0) { SwitchAnimationState(AIState.Hit); } else { timeStuck -= Time.deltaTime; } } else { Vector3 runTo = enemy.position; distance = (transform.position - enemy.position).sqrMagnitude; if (enemy) { agent.SetDestination(runTo); } else { enemy = null; } } //Temporarily switch to Idle if the Agent stopped if (agent.velocity.sqrMagnitude < 0.1f * 0.1f) { SwitchAnimationState(AIState.Idle); } //if dead then dont do more damage if (distance < 2) { SwitchAnimationState(AIState.Hit); // Attack(); } else { agent.isStopped = false; SwitchAnimationState(AIState.Running); if (!enemy.gameObject.activeSelf) { enemy = null; //go back to do what u did at the start //must do so it doesnt get stuck here //for now it just waits for enemy and then goes after it agent.destination = RandomNavSphere(transform.position, Random.Range(3, 10)); SwitchAnimationState(AIState.Walking); return; } } //then growl cuz u won battle } else { //Check if we've reached the destination then stop running if (DoneReachingDestination()) { actionTimer = Random.Range(2f, 5f); } } } switchAction = false; }
public void SetState(AIState newState, AIState previousState) { Destroy(AIState); AIState = newState; AIState.Initialize(previousState); }
public override void OnEnter(AIState lastState) { base.OnEnter(lastState); match = m_match; }
public BehaviorState(AIState state) { State = state; }
void Update() { if (!flight) { return; } battleposition = Vector3.zero; if (CenterOfBattle) { battleposition = CenterOfBattle.transform.position; } TargetBehaviorCal(); switch (AIstate) { case AIState.Patrol: for (int t = 0; t < TargetTag.Length; t++) { if (GameObject.FindGameObjectsWithTag(TargetTag [t]).Length > 0) { GameObject[] objs = GameObject.FindGameObjectsWithTag(TargetTag [t]); float distance = int.MaxValue; for (int i = 0; i < objs.Length; i++) { if (objs [i]) { if (timetolockcount + TimeToLock < Time.time) { float dis = Vector3.Distance(objs [i].transform.position, transform.position); if (DistanceLock > dis) { if (!Target) { if (distance > dis && Random.Range(0, 100) > 80) { distance = dis; Target = objs [i]; flight.FollowTarget = true; AIstate = AIState.Attacking; timestatetemp = Time.time; WeaponSelected = Random.Range(0, flight.WeaponControl.WeaponLists.Length); } } } } shootTarget(objs [i].transform.position); } } } } break; case AIState.Idle: if (Vector3.Distance(flight.PositionTarget, this.transform.position) <= FlyDistance) { AIstate = AIState.Patrol; timestatetemp = Time.time; } break; case AIState.Attacking: if (Target) { flight.PositionTarget = Target.transform.position; if (!shootTarget(flight.PositionTarget)) { if (attacking) { if (Time.time > timestatetemp + 5) { turnPosition(); } } else { if (Time.time > timestatetemp + 7) { turnPosition(); } } } } else { AIstate = AIState.Patrol; timestatetemp = Time.time; } if (Vector3.Distance(battleposition, this.transform.position) > FlyDistance) { gotoCenter(); } break; case AIState.TurnPosition: if (Time.time > timestatetemp + 7) { timestatetemp = Time.time; AIstate = AIState.Attacking; } if (Vector3.Distance(battleposition, this.transform.position) > FlyDistance) { gotoCenter(); } float height = flight.PositionTarget.y; if (targetHavior == TargetBehavior.Static) { directionTurn.y = 0; flight.PositionTarget += (this.transform.forward + directionTurn) * flight.Speed; flight.PositionTarget.y = height; flight.PositionTarget.y += flight.Speed / 2; } else { flight.PositionTarget += (this.transform.forward + directionTurn) * flight.Speed; flight.PositionTarget.y = height; flight.PositionTarget.y += flight.Speed / 2; //flight.PositionTarget = battleposition + new Vector3 (Random.Range (-FlyDistance, FlyDistance), Random.Range (0, FlyDistance / 2), Random.Range (-FlyDistance, FlyDistance)); } break; } }
/******************** * flee intensity * ********************/ /** * Method : ChangeStateRunningAway * Param : void * Desc : Set the CurrentState to RunningAway * Return : Void **/ void ChangeStateRunningAway() { CurrentState = AIState.RunningAway; }
public virtual void Reset() => State = AIState.AI_DO_NOTHING;
public AISeek(AIState state, Transform obj, float weight) { trans = obj; this.State = state; this.Weight = weight; }
void Update() { StatusC stat = GetComponent <StatusC>(); CharacterController controller = GetComponent <CharacterController>(); gos = GameObject.FindGameObjectsWithTag("Player"); if (gos.Length > 0) { followTarget = FindClosest().transform; } if (flinch) { controller.Move(knock * 6 * Time.deltaTime); return; } if (freeze || stat.freeze) { return; } if (!followTarget) { return; } //----------------------------------- if (followState == AIState.Moving) { if ((followTarget.position - transform.position).magnitude <= approachDistance) { followState = AIState.Pausing; mainModel.animation.CrossFade(idleAnimation.name, 0.2f); //----Attack---- //Attack(); StartCoroutine(Attack()); } else if ((followTarget.position - transform.position).magnitude >= lostSight) { //Lost Sight GetComponent <StatusC>().health = GetComponent <StatusC>().maxHealth; followState = AIState.Idle; mainModel.animation.CrossFade(idleAnimation.name, 0.2f); } else { Vector3 forward = transform.TransformDirection(Vector3.forward); controller.Move(forward * speed * Time.deltaTime); Vector3 destiny = followTarget.position; destiny.y = transform.position.y; transform.LookAt(destiny); } } else if (followState == AIState.Pausing) { Vector3 destinya = followTarget.position; destinya.y = transform.position.y; transform.LookAt(destinya); distance = (transform.position - GetDestination()).magnitude; if (distance > approachDistance) { followState = AIState.Moving; mainModel.animation.CrossFade(movingAnimation.name, 0.2f); } } //----------------Idle Mode-------------- else if (followState == AIState.Idle) { Vector3 destinyheight = followTarget.position; destinyheight.y = transform.position.y - destinyheight.y; int getHealth = GetComponent <StatusC>().maxHealth - GetComponent <StatusC>().health; distance = (transform.position - GetDestination()).magnitude; if (distance < detectRange && Mathf.Abs(destinyheight.y) <= 4 || getHealth > 0) { followState = AIState.Moving; mainModel.animation.CrossFade(movingAnimation.name, 0.2f); } } //----------------------------------- }
void changeAIState(AIState newState) { aiState = newState; }
// Use this for initialization void Start() { currentHealth = SharkMaxHealth; player = GameObject.FindGameObjectsWithTag("Player")[0]; currentState = AIState.Idle; }
/** * Method : ChangeStateLowFight * Param : void * Desc : Set the CurrentState to LowFight * Return : Void **/ void ChangeStateLowFight() { CurrentState = AIState.FightingLongRange; }
//Handles the AI attacking the player private void AttackBehavoir() { m_Combat.Attack(m_Player); m_CurrentState = AIState.ATTACK; }
/** * Method : ChangeStateFightForDeath * Param : void * Desc : Set the CurrentState to FightForDeath * Return : Void **/ void ChangeStateFightForDeath() { CurrentState = AIState.FightingCloseRange; }
///////////////////////////// PUBLIC METHODS //////////////////////////////////////////// //Is called from the take damage event public void Aggrevate() { m_TimeSinceAggrevated = 0; m_CurrentState = AIState.AGGRO; AggrevateNearbyEnemies(); }
public TargetParams(string tag, AIState state, float priority, CharacterParams character) : base(CreateNewElement(tag, state, priority), character) { }
// Start is called before the first frame update void Start() { m_StartPosition.ForceInit(); m_CurrentState = AIState.PATROL; }
private void Awake() { mover = GetComponent <SnowballMover>(); state = AIState.NONE; }
/// <summary> /// Returns true if the current selected state is still valid. /// </summary> private bool isStateStillValid(AIState state, float time, AISituation previous, AISituation next) { var hasEnemyMoved = Vector3.Distance(previous.ThreatGroundPosition, next.ThreatGroundPosition) > 4 || (previous.IsThreatInCover != next.IsThreatInCover); var canUseCover = (next.IsRetreating && Behaviour.IsRetreatingUsingCovers) || (!next.IsRetreating && Behaviour.IsApproachingUsingCovers); var isTargetPositionUseful = next.CanSeeFromTargetPosition || next.IsRetreating; var burst = Behaviour.IsFightingUsingCovers ? CoveredFightingBursts : CoveredApproachBursts; if (next.IsNearGrenade) { return(state == AIState.avoidGrenade); } else { switch (state) { case AIState.avoidGrenade: return(time < 2 || next.IsNearGrenade); case AIState.investigate: return(next.IsAlerted && !next.HasInvestigatedTheLatestAlert && next.Threat == null && Vector3.Distance(next.ThreatGroundPosition, previous.TargetPosition) < Distances.ThreatInvestigation); case AIState.approach: if (next.DidntFindCover && time < 4) { return(true); } return(!next.IsRetreating && (!Behaviour.IsFightingUsingCovers || !Behaviour.IsApproachingUsingCovers) && isTargetPositionUseful); case AIState.fireInCover: return(next.IsAllowedToBeAggressive && canUseCover && !hasEnemyMoved && time <= burst.TotalPeekDuration && next.IsTargetCoverGood && isTargetPositionUseful); case AIState.hideInCover: return(canUseCover && !hasEnemyMoved && time <= burst.Wait && next.IsTargetCoverGood && isTargetPositionUseful); case AIState.retreat: return(next.IsRetreating && Behaviour.IsRetreatingUsingCovers && isTargetPositionUseful); case AIState.reloadInCover: return(!next.IsGunReady); case AIState.none: return(false); case AIState.patrol: { if (!next.IsAlerted && Waypoints != null && Waypoints.Length > 0 && _situation.PatrolPoint < Waypoints.Length) { if (Waypoints[_situation.PatrolPoint].Pause < float.Epsilon && Vector3.Distance(next.TargetPosition, next.CurrentPosition) < 0.5f) { return(false); } else if (Vector3.Distance(transform.position, _situation.TargetPosition) > 1) { return(true); } else { return(false); } } else { return(false); } } case AIState.patrolPause: return(!next.IsAlerted && Waypoints != null && Waypoints.Length > 0 && _situation.PatrolPoint < Waypoints.Length && time <= Waypoints[_situation.PatrolPoint].Pause); case AIState.takeCover: if (next.Threat == null || !next.Threat.IsAttacking) { return(false); } return(canUseCover && !hasEnemyMoved && next.IsTargetCoverGood && isTargetPositionUseful && next.CurrentCover != next.TargetCover); } } return(false); }