public override IEnumerable <Status> Run() { Vector3 oldPosition = Agent.Position; bool firstIter = true; Creature.Controller.Reset(); while (!WanderTime.HasTriggered) { Creature.OverrideCharacterMode = false; Creature.Physics.Orientation = Physics.OrientMode.RotateY; Creature.CurrentCharacterMode = Creature.CharacterMode.Walking; WanderTime.Update(DwarfTime.LastTime); if (!Creature.IsOnGround) { yield return(Status.Fail); yield break; } if (TurnTime.Update(DwarfTime.LastTime) || TurnTime.HasTriggered || firstIter) { Vector2 randTarget = MathFunctions.RandVector2Circle() * Radius; LocalTarget = new Vector3(randTarget.X, 0, randTarget.Y) + oldPosition; firstIter = false; TurnTime.Reset(TurnTime.TargetTimeSeconds + MathFunctions.Rand(-0.1f, 0.1f)); } float dist = (LocalTarget - Agent.Position).Length(); if (dist < 0.5f) { Creature.Physics.Velocity *= 0.0f; Creature.CurrentCharacterMode = Creature.CharacterMode.Idle; yield return(Status.Running); break; } else { Vector3 output = Creature.Controller.GetOutput((float)DwarfTime.LastTime.ElapsedGameTime.TotalSeconds, LocalTarget, Agent.Position); output.Y = 0.0f; Creature.Physics.ApplyForce(output * 0.5f, (float)DwarfTime.LastTime.ElapsedGameTime.TotalSeconds); Creature.CurrentCharacterMode = Creature.CharacterMode.Walking; } yield return(Status.Running); } Creature.CurrentCharacterMode = Creature.CharacterMode.Idle; yield return(Status.Success); }
public override IEnumerable <Status> Run() { Vector3 oldPosition = Agent.Position; bool firstIter = true; Creature.Controller.Reset(); WanderTime.Reset(); TurnTime.Reset(); while (!WanderTime.HasTriggered) { Creature.OverrideCharacterMode = false; Creature.Physics.Orientation = Physics.OrientMode.RotateY; Creature.CurrentCharacterMode = CharacterMode.Walking; WanderTime.Update(DwarfTime.LastTime); if (!Creature.IsOnGround) { yield return(Status.Success); yield break; } if (TurnTime.Update(DwarfTime.LastTime) || TurnTime.HasTriggered || firstIter) { int iters = 0; while (iters < 100) { iters++; Vector2 randTarget = MathFunctions.RandVector2Circle() * Radius; LocalTarget = new Vector3(randTarget.X, 0, randTarget.Y) + oldPosition; VoxelHandle voxel = new VoxelHandle(Agent.World.ChunkManager.ChunkData, GlobalVoxelCoordinate.FromVector3(LocalTarget)); bool foundLava = false; foreach (VoxelHandle neighbor in VoxelHelpers.EnumerateAllNeighbors(voxel.Coordinate).Select(coord => new VoxelHandle(Agent.World.ChunkManager.ChunkData, coord))) { if (neighbor.IsValid && neighbor.Chunk != null) { if (neighbor.LiquidType == LiquidType.Lava) { foundLava = true; } } } if (!foundLava) { break; } } if (iters == 100) { yield return(Act.Status.Fail); yield break; } firstIter = false; TurnTime.Reset(TurnTime.TargetTimeSeconds + MathFunctions.Rand(-0.1f, 0.1f)); } float dist = (LocalTarget - Agent.Position).Length(); if (dist < 0.5f) { Creature.Physics.Velocity *= 0.0f; Creature.CurrentCharacterMode = CharacterMode.Idle; yield return(Status.Running); } else { Vector3 output = Creature.Controller.GetOutput((float)DwarfTime.LastTime.ElapsedGameTime.TotalSeconds, LocalTarget, Agent.Position); output.Y = 0.0f; Creature.Physics.ApplyForce(output * 0.5f, (float)DwarfTime.LastTime.ElapsedGameTime.TotalSeconds); Creature.CurrentCharacterMode = CharacterMode.Walking; } yield return(Status.Running); } Creature.CurrentCharacterMode = CharacterMode.Idle; yield return(Status.Success); }
public override IEnumerable <Status> Run() { // Store the last position of the bird to sample from Vector3 oldPosition = Agent.Position; // Get the height of the terrain beneath the bird. float surfaceHeight = Agent.Chunks.ChunkData.GetFilledVoxelGridHeightAt(oldPosition.X, oldPosition.Y, oldPosition.Z); // Immediately start flying. Agent.Creature.CurrentCharacterMode = Creature.CharacterMode.Flying; // Use this to determine when to start turning. float currentDistance = 999; { // Pick a target within a box floating some distance above the surface. float randomX = MathFunctions.Rand() * Radius - Radius / 2.0f; float randomZ = MathFunctions.Rand() * Radius - Radius / 2.0f; float randomY = (float)PlayState.Random.NextDouble() * YRadius + Altitude + surfaceHeight; // Set the target to that random location. LocalTarget = new Vector3(randomX + oldPosition.X, randomY, randomZ + oldPosition.Z); } // Keep flying until a timer has trigerred. while (!WanderTime.HasTriggered) { // If we hit the ground, switch to walking, otherwise switch to flying. Agent.Creature.CurrentCharacterMode = Creature.IsOnGround ? Creature.CharacterMode.Walking : Creature.CharacterMode.Flying; WanderTime.Update(DwarfTime.LastTime); // If we're near a target, or a timeout occured, pick a new ranodm target. if (TurnTime.Update(DwarfTime.LastTime) || TurnTime.HasTriggered || currentDistance < TurnThreshold) { // Pick a target within a box floating some distance above the surface. float randomX = MathFunctions.Rand() * Radius - Radius / 2.0f; float randomZ = MathFunctions.Rand() * Radius - Radius / 2.0f; float randomY = (float)PlayState.Random.NextDouble() * YRadius + Altitude + surfaceHeight; // Set the target to that random location. LocalTarget = new Vector3(randomX + oldPosition.X, randomY, randomZ + oldPosition.Z); } // Set the current distance to the target so we know when to go to a new target. currentDistance = (Agent.Position - LocalTarget).Length(); // Output from the force controller. Vector3 output = Creature.Controller.GetOutput((float)DwarfTime.LastTime.ElapsedGameTime.TotalSeconds, LocalTarget, Creature.Physics.GlobalTransform.Translation); // Feed forward term to cancel gravity. Vector3 feedForward = -Agent.Physics.Gravity; // We apply a linear combination of the force controller and the // feed forward force to the bird to make it lazily turn around and fly. Creature.Physics.ApplyForce(output * Damping + feedForward * GravityCompensation, (float)DwarfTime.LastTime.ElapsedGameTime.TotalSeconds); yield return(Status.Running); } // When we're done flying, go back to walking and just fall. Agent.Creature.CurrentCharacterMode = Creature.CharacterMode.Walking; yield return(Status.Success); }
public override IEnumerable <Status> Run() { PerchTime.Reset(); WanderTime.Reset(); TurnTime.Reset(); while (true) { if (State == FlyState.Perching) { PerchTime.Reset(); while (!PerchTime.HasTriggered) { Agent.Creature.Physics.Velocity = Vector3.Zero; Agent.Creature.CurrentCharacterMode = CharacterMode.Idle; PerchTime.Update(DwarfTime.LastTime); yield return(Act.Status.Running); } // When we're done flying, go back to walking and just fall. Agent.Creature.CurrentCharacterMode = CharacterMode.Walking; Agent.Creature.Physics.Gravity = OriginalGravity; yield return(Act.Status.Success); } Agent.Creature.Physics.Gravity = Vector3.Zero; // Store the last position of the bird to sample from Vector3 oldPosition = Agent.Position; // Get the height of the terrain beneath the bird. var surfaceHeight = VoxelHelpers.FindFirstVoxelBelow(new VoxelHandle( Agent.Chunks.ChunkData, GlobalVoxelCoordinate.FromVector3(oldPosition))) .Coordinate.Y + 1; // Immediately start flying. Agent.Creature.CurrentCharacterMode = CharacterMode.Flying; // Use this to determine when to start turning. float currentDistance = 999; { // Pick a target within a box floating some distance above the surface. float randomX = MathFunctions.Rand() * Radius - Radius / 2.0f; float randomZ = MathFunctions.Rand() * Radius - Radius / 2.0f; float randomY = (float)MathFunctions.Random.NextDouble() * YRadius + Altitude + surfaceHeight; // Set the target to that random location. LocalTarget = new Vector3(randomX + oldPosition.X, randomY, randomZ + oldPosition.Z); } // Keep flying until a timer has trigerred. while ((!WanderTime.HasTriggered && State == FlyState.Wandering) || (State == FlyState.SearchingForPerch)) { // If we hit the ground, switch to walking, otherwise switch to flying. Agent.Creature.CurrentCharacterMode = CharacterMode.Flying; WanderTime.Update(DwarfTime.LastTime); // If we're near a target, or a timeout occured, pick a new ranodm target. if (TurnTime.Update(DwarfTime.LastTime) || TurnTime.HasTriggered || currentDistance < TurnThreshold) { // Pick a target within a box floating some distance above the surface. float randomX = MathFunctions.Rand() * Radius - Radius / 2.0f; float randomZ = MathFunctions.Rand() * Radius - Radius / 2.0f; float randomY = (float)MathFunctions.Random.NextDouble() * YRadius + Altitude + surfaceHeight; // Set the target to that random location. LocalTarget = new Vector3(randomX + oldPosition.X, randomY, randomZ + oldPosition.Z); } // Set the current distance to the target so we know when to go to a new target. currentDistance = (Agent.Position - LocalTarget).Length(); // Output from the force controller. Vector3 output = Creature.Controller.GetOutput((float)DwarfTime.LastTime.ElapsedGameTime.TotalSeconds, LocalTarget, Creature.Physics.GlobalTransform.Translation); // We apply a linear combination of the force controller and the // feed forward force to the bird to make it lazily turn around and fly. Creature.Physics.ApplyForce(output * Damping * GravityCompensation, (float)DwarfTime.LastTime.ElapsedGameTime.TotalSeconds); if (State == FlyState.Wandering && WanderTime.HasTriggered) { State = FlyState.SearchingForPerch; } if (State == FlyState.SearchingForPerch) { var vox = Creature.Physics.CurrentVoxel; if (!vox.IsValid) { yield return(Act.Status.Running); continue; } if (vox.IsValid && vox.WaterCell.WaterLevel > 0) { yield return(Act.Status.Running); continue; } if (CanPerchOnGround) { Creature.Physics.ApplyForce(OriginalGravity, (float)DwarfTime.LastTime.ElapsedGameTime.TotalSeconds); var below = new VoxelHandle(Creature.World.ChunkManager.ChunkData, vox.Coordinate + new GlobalVoxelOffset(0, -1, 0)); if (below.IsValid && !below.IsEmpty && below.WaterCell.WaterLevel == 0) { State = FlyState.Perching; continue; } } if (CanPerchOnWalls) { foreach (var n in VoxelHelpers.EnumerateManhattanNeighbors(Creature.Physics.CurrentVoxel.Coordinate) .Select(c => new VoxelHandle(Creature.World.ChunkManager.ChunkData, c))) { if (n.IsValid && n.Coordinate.Y >= vox.Coordinate.Y && !n.IsEmpty) { State = FlyState.Perching; } } } /* * if (CanPerchOnObjects) * { * List<Body> objetcs = new List<Body>(); * PlayState.ComponentManager.GetBodiesIntersecting(Creature.Physics.BoundingBox, objetcs, CollisionManager.CollisionType.Static); * * if (objetcs.Count > 0) * { * State = FlyState.Perching; * continue; * } * } */ } yield return(Status.Running); } yield return(Status.Running); } }
public override IEnumerable <Status> Run() { Vector3 oldPosition = Agent.Position; bool firstIter = true; Creature.Controller.Reset(); while (!WanderTime.HasTriggered) { Creature.OverrideCharacterMode = false; Creature.Physics.Orientation = Physics.OrientMode.RotateY; Creature.CurrentCharacterMode = Creature.CharacterMode.Idle; WanderTime.Update(DwarfTime.LastTime); if (!Creature.IsOnGround) { yield return(Status.Running); continue; } if (TurnTime.Update(DwarfTime.LastTime) || TurnTime.HasTriggered || firstIter) { LocalTarget = new Vector3(MathFunctions.Rand() * Radius - Radius / 2.0f, 0.0f, MathFunctions.Rand() * Radius - Radius / 2.0f) + oldPosition; /* * List<Creature.MoveAction> neighbors = Agent.Chunks.ChunkData.GetMovableNeighbors(Agent.Position); * neighbors.RemoveAll( * a => a.MoveType == Creature.MoveType.Jump || a.MoveType == DwarfCorp.Creature.MoveType.Climb); * * if (neighbors.Count > 0) * { * LocalTarget = neighbors[PlayState.Random.Next(0, neighbors.Count)].Voxel.Position + * Vector3.One*0.5f; * } */ firstIter = false; } float origDist = (oldPosition - LocalTarget).Length(); if (origDist > Radius) { Creature.Physics.Velocity *= 0.9f; yield return(Status.Running); continue; } float dist = (LocalTarget - Agent.Position).Length(); if (dist < Radius * 0.25f) { Creature.Physics.Velocity *= 0.9f; } else { Vector3 output = Creature.Controller.GetOutput((float)DwarfTime.LastTime.ElapsedGameTime.TotalSeconds, LocalTarget, Agent.Position); output.Y = 0.0f; Creature.Physics.ApplyForce(output * 0.5f, (float)DwarfTime.LastTime.ElapsedGameTime.TotalSeconds); } yield return(Status.Running); } yield return(Status.Success); }