public IEnumerable <Status> PerformCurrentAction() { MoveAction action = Path.First(); float t = 0; int currentIndex = 0; if (!GetCurrentAction(ref action, ref t, ref currentIndex)) { yield break; } Trace.Assert(t >= 0); Trace.Assert(action.SourceVoxel.IsValid); int nextID = currentIndex + 1; bool hasNextAction = false; Vector3 half = GetBoundingBoxOffset(); Vector3 nextPosition = Vector3.Zero; Vector3 currPosition = action.SourceVoxel.WorldPosition + half; currPosition += RandomPositionOffsets[currentIndex]; if (nextID < Path.Count) { hasNextAction = true; nextPosition = Path[nextID].SourceVoxel.WorldPosition; nextPosition += RandomPositionOffsets[nextID] + half; } else { hasNextAction = true; nextPosition = action.DestinationVoxel.WorldPosition + half; } Matrix transform = Agent.Physics.LocalTransform; Vector3 diff = (nextPosition - currPosition); switch (action.MoveType) { case MoveType.Walk: Creature.OverrideCharacterMode = false; Creature.CurrentCharacterMode = CharacterMode.Walking; if (hasNextAction) { transform.Translation = diff * t + currPosition; Agent.Physics.Velocity = diff; } else { transform.Translation = currPosition; } break; case MoveType.Swim: Creature.NoiseMaker.MakeNoise("Swim", Agent.Position, true); Creature.OverrideCharacterMode = false; Creature.CurrentCharacterMode = CharacterMode.Swimming; if (hasNextAction) { transform.Translation = diff * t + currPosition + new Vector3(0, 0.5f, 0); Agent.Physics.Velocity = diff; } else { transform.Translation = currPosition; } break; case MoveType.Jump: if (t < 0.5f) { Creature.NoiseMaker.MakeNoise("Jump", Agent.Position, false); } Creature.OverrideCharacterMode = false; Creature.CurrentCharacterMode = Creature.Physics.Velocity.Y > 0 ? CharacterMode.Jumping : CharacterMode.Falling; if (hasNextAction) { float z = Easing.Ballistic(t, 1.0f, 1.0f); Vector3 start = currPosition; Vector3 end = nextPosition; Vector3 dx = (end - start) * t + start; dx.Y = start.Y * (1 - t) + end.Y * (t) + z; transform.Translation = dx; Agent.Physics.Velocity = new Vector3(diff.X, (dx.Y - Agent.Physics.Position.Y), diff.Z); } else { transform.Translation = currPosition; } break; case MoveType.Fall: Creature.OverrideCharacterMode = false; Creature.CurrentCharacterMode = CharacterMode.Falling; if (hasNextAction) { transform.Translation = diff * t + currPosition; Agent.Physics.Velocity = diff; } else { transform.Translation = currPosition; } break; case MoveType.Climb: case MoveType.ClimbWalls: if (((int)((t + 1) * 100)) % 50 == 0) { Creature.NoiseMaker.MakeNoise("Climb", Agent.Position, false); } Creature.OverrideCharacterMode = false; Creature.CurrentCharacterMode = CharacterMode.Climbing; Creature.OverrideCharacterMode = true; if (hasNextAction) { if (action.MoveType == MoveType.ClimbWalls && action.ActionVoxel.IsValid) { Agent.Physics.Velocity = (action.DestinationVoxel.WorldPosition + Vector3.One * 0.5f) - currPosition; transform.Translation = diff * t + currPosition; } else if (action.MoveType == MoveType.Climb && action.InteractObject != null) { var ladderPosition = action.InteractObject.GetRoot().GetComponent <Body>().Position; transform.Translation = diff * t + currPosition; Agent.Physics.Velocity = ladderPosition - currPosition; } } else { transform.Translation = currPosition; } break; case MoveType.Fly: if (((int)((t + 1) * 100)) % 2 == 0) { Creature.NoiseMaker.MakeNoise("Flap", Agent.Position, false); } Creature.OverrideCharacterMode = false; Creature.CurrentCharacterMode = CharacterMode.Flying; Creature.OverrideCharacterMode = true; if (hasNextAction) { transform.Translation = diff * t + currPosition; Agent.Physics.Velocity = diff; } else { transform.Translation = currPosition; } break; case MoveType.DestroyObject: var melee = new MeleeAct(Creature.AI, (Body)action.InteractObject); melee.Initialize(); foreach (var status in melee.Run()) { if (status == Act.Status.Fail) { yield return(Act.Status.Fail); } yield return(Act.Status.Running); } yield return(Act.Status.Success); yield break; } Agent.Physics.LocalTransform = transform; }
public IEnumerable <Status> PerformCurrentAction() { Creature.MoveAction action = Path.First(); float t = 0; int currentIndex = 0; if (!GetCurrentAction(ref action, ref t, ref currentIndex)) { yield break; } int nextID = currentIndex + 1; bool hasNextAction = false; Vector3 half = Vector3.One * 0.5f; half.Y = Creature.Physics.BoundingBox.Extents().Y * 2; Vector3 nextPosition = Vector3.Zero; Vector3 currPosition = action.Voxel.Position + half; Vector3 prevPosition = currPosition; if (currentIndex > 0 && Path.Count > 0) { prevPosition = Path.ElementAt(currentIndex - 1).Voxel.Position + half; } currPosition += RandomPositionOffsets[currentIndex]; if (nextID < Path.Count) { hasNextAction = true; nextPosition = Path[nextID].Voxel.Position; nextPosition += RandomPositionOffsets[nextID] + half; } Matrix transform = Agent.Physics.LocalTransform; Vector3 diff = (nextPosition - currPosition); switch (action.MoveType) { case Creature.MoveType.Walk: Creature.OverrideCharacterMode = false; Creature.CurrentCharacterMode = Creature.CharacterMode.Walking; if (hasNextAction) { transform.Translation = diff * t + currPosition; Agent.Physics.Velocity = diff; } else { transform.Translation = currPosition; } break; case Creature.MoveType.Swim: Creature.OverrideCharacterMode = false; Creature.CurrentCharacterMode = Creature.CharacterMode.Swimming; if (hasNextAction) { transform.Translation = diff * t + currPosition + new Vector3(0, 0.5f, 0); Agent.Physics.Velocity = diff; } else { transform.Translation = currPosition; } break; case Creature.MoveType.Jump: Creature.OverrideCharacterMode = false; Creature.CurrentCharacterMode = Creature.Physics.Velocity.Y > 0 ? Creature.CharacterMode.Jumping : Creature.CharacterMode.Falling; if (hasNextAction) { float z = Easing.Ballistic(t, 1.0f, 1.0f); Vector3 start = currPosition; Vector3 end = nextPosition; Vector3 dx = (end - start) * t + start; dx.Y = start.Y * (1 - t) + end.Y * (t) + z; transform.Translation = dx; Agent.Physics.Velocity = new Vector3(diff.X, (dx.Y - Agent.Physics.Position.Y), diff.Z); } else { transform.Translation = currPosition; } break; case Creature.MoveType.Fall: Creature.OverrideCharacterMode = false; Creature.CurrentCharacterMode = Creature.CharacterMode.Falling; if (hasNextAction) { transform.Translation = diff * t + currPosition; Agent.Physics.Velocity = diff; } else { transform.Translation = currPosition; } break; case Creature.MoveType.Climb: case Creature.MoveType.ClimbWalls: Creature.OverrideCharacterMode = false; Creature.CurrentCharacterMode = Creature.CharacterMode.Walking; Creature.OverrideCharacterMode = true; if (hasNextAction) { transform.Translation = diff * t + currPosition; Agent.Physics.Velocity = diff; } else { transform.Translation = currPosition; } break; case Creature.MoveType.Fly: Creature.OverrideCharacterMode = false; Creature.CurrentCharacterMode = Creature.CharacterMode.Flying; Creature.OverrideCharacterMode = true; if (hasNextAction) { transform.Translation = diff * t + currPosition; Agent.Physics.Velocity = diff; } else { transform.Translation = currPosition; } break; case Creature.MoveType.DestroyObject: if (action.InteractObject.IsDead) { Creature.OverrideCharacterMode = false; Creature.CurrentCharacterMode = Creature.CharacterMode.Walking; if (hasNextAction) { transform.Translation = diff * t + currPosition; Agent.Physics.Velocity = diff; } else { transform.Translation = currPosition; } } float current = (TrajectoryTimer.CurrentTimeSeconds); Matrix transformMatrix = Agent.Physics.LocalTransform; transformMatrix.Translation = prevPosition; var act = new MeleeAct(Creature.AI, action.InteractObject.GetEntityRootComponent().GetChildrenOfType <Body>(true).FirstOrDefault()); act.Initialize(); foreach (Status status in act.Run()) { Agent.Physics.LocalTransform = transformMatrix; TrajectoryTimer.StartTimeSeconds = (float)DwarfTime.LastTime.TotalGameTime.TotalSeconds - current; yield return(status); } break; } Agent.Physics.LocalTransform = transform; }
public IEnumerable <Status> PerformCurrentAction() { MoveAction action = Path.First(); float t = 0; int currentIndex = 0; if (!GetCurrentAction(ref action, ref t, ref currentIndex)) { CleanupMinecart(); yield break; } Trace.Assert(t >= 0); Trace.Assert(action.SourceVoxel.IsValid); int nextID = currentIndex + 1; bool hasNextAction = false; Vector3 half = GetBoundingBoxOffset(); Vector3 nextPosition = Vector3.Zero; Vector3 currPosition = action.SourceVoxel.WorldPosition + half; currPosition += RandomPositionOffsets[currentIndex]; if (nextID < Path.Count) { hasNextAction = true; nextPosition = Path[nextID].SourceVoxel.WorldPosition; nextPosition += RandomPositionOffsets[nextID] + half; } else { hasNextAction = true; nextPosition = action.DestinationVoxel.WorldPosition + half; } Matrix transform = Agent.Physics.LocalTransform; Vector3 diff = (nextPosition - currPosition); Agent.GetRoot().SetFlag(GameComponent.Flag.Visible, true); switch (action.MoveType) { case MoveType.EnterVehicle: if (t < 0.5f) { Creature.NoiseMaker.MakeNoise("Jump", Agent.Position, false); } Creature.OverrideCharacterMode = false; Creature.CurrentCharacterMode = Creature.Physics.Velocity.Y > 0 ? CharacterMode.Jumping : CharacterMode.Falling; if (hasNextAction) { float z = Easing.Ballistic(t, 1.0f, 1.0f); Vector3 start = currPosition; Vector3 end = nextPosition + Vector3.Up * 0.5f; Vector3 dx = (end - start) * t + start; dx.Y = start.Y * (1 - t) + end.Y * (t) + z; transform.Translation = dx; Agent.Physics.Velocity = new Vector3(diff.X, (dx.Y - Agent.Physics.Position.Y), diff.Z); } else { transform.Translation = currPosition; } if (t > 0.9f) { SetupMinecart(); } break; case MoveType.ExitVehicle: CleanupMinecart(); transform.Translation = currPosition; break; case MoveType.RideVehicle: SetupMinecart(); Creature.CurrentCharacterMode = CharacterMode.Minecart; var rail = action.SourceState.VehicleState.Rail; if (rail == null) { if (hasNextAction) { transform.Translation = diff * t + currPosition; Agent.Physics.Velocity = diff; } else { transform.Translation = currPosition; } } else { //Drawer3D.DrawBox(rail.GetContainingVoxel().GetBoundingBox(), Color.Green, 0.1f, true); var pos = rail.InterpolateSpline(t, action.SourceVoxel.WorldPosition + Vector3.One * 0.5f, action.DestinationVoxel.WorldPosition + Vector3.One * 0.5f); transform.Translation = pos + Vector3.Up * 0.5f; Agent.Physics.Velocity = diff; } break; case MoveType.Walk: CleanupMinecart(); Creature.OverrideCharacterMode = false; Creature.CurrentCharacterMode = CharacterMode.Walking; if (hasNextAction) { transform.Translation = diff * t + currPosition; Agent.Physics.Velocity = diff; } else { transform.Translation = currPosition; } break; case MoveType.Swim: CleanupMinecart(); Creature.NoiseMaker.MakeNoise("Swim", Agent.Position, true); Creature.OverrideCharacterMode = false; Creature.CurrentCharacterMode = CharacterMode.Swimming; if (hasNextAction) { transform.Translation = diff * t + currPosition; Agent.Physics.Velocity = diff; } else { transform.Translation = currPosition; } break; case MoveType.Jump: CleanupMinecart(); if (t < 0.5f) { Creature.NoiseMaker.MakeNoise("Jump", Agent.Position, false); } Creature.OverrideCharacterMode = false; Creature.CurrentCharacterMode = Creature.Physics.Velocity.Y > 0 ? CharacterMode.Jumping : CharacterMode.Falling; if (hasNextAction) { float z = Easing.Ballistic(t, 1.0f, 1.0f); Vector3 start = currPosition; Vector3 end = nextPosition; Vector3 dx = (end - start) * t + start; dx.Y = start.Y * (1 - t) + end.Y * (t) + z; transform.Translation = dx; Agent.Physics.Velocity = new Vector3(diff.X, (dx.Y - Agent.Physics.Position.Y), diff.Z); } else { transform.Translation = currPosition; } break; case MoveType.Fall: CleanupMinecart(); Creature.OverrideCharacterMode = false; Creature.CurrentCharacterMode = CharacterMode.Falling; if (hasNextAction) { transform.Translation = diff * t + currPosition; Agent.Physics.Velocity = diff; } else { transform.Translation = currPosition; } break; case MoveType.Climb: case MoveType.ClimbWalls: CleanupMinecart(); if (((int)((t + 1) * 100)) % 50 == 0) { Creature.NoiseMaker.MakeNoise("Climb", Agent.Position, false); } Creature.OverrideCharacterMode = false; Creature.CurrentCharacterMode = CharacterMode.Climbing; Creature.OverrideCharacterMode = true; if (hasNextAction) { if (action.MoveType == MoveType.ClimbWalls && action.ActionVoxel.IsValid) { Agent.Physics.Velocity = (action.DestinationVoxel.WorldPosition + Vector3.One * 0.5f) - currPosition; transform.Translation = diff * t + currPosition; } else if (action.MoveType == MoveType.Climb && action.InteractObject != null) { var ladderPosition = action.InteractObject.GetRoot().GetComponent <Body>().Position; transform.Translation = diff * t + currPosition; Agent.Physics.Velocity = ladderPosition - currPosition; } } else { transform.Translation = currPosition; } break; case MoveType.Fly: CleanupMinecart(); if (((int)((t + 1) * 100)) % 2 == 0) { Creature.NoiseMaker.MakeNoise("Flap", Agent.Position, false); } Creature.OverrideCharacterMode = false; Creature.CurrentCharacterMode = CharacterMode.Flying; Creature.OverrideCharacterMode = true; if (hasNextAction) { transform.Translation = diff * t + currPosition; Agent.Physics.Velocity = diff; } else { transform.Translation = currPosition; } break; case MoveType.DestroyObject: CleanupMinecart(); var melee = new MeleeAct(Creature.AI, (Body)action.InteractObject); melee.Initialize(); foreach (var status in melee.Run()) { if (status == Act.Status.Fail) { yield return(Act.Status.Fail); } yield return(Act.Status.Running); } yield return(Act.Status.Success); yield break; case MoveType.Teleport: if (lastMovement != MoveType.Teleport) { if (action.InteractObject != null) { var teleporter = action.InteractObject.GetComponent <MagicalObject>(); if (teleporter != null) { teleporter.CurrentCharges--; } } SoundManager.PlaySound(ContentPaths.Audio.Oscar.sfx_ic_dwarf_magic_research, currPosition, true, 1.0f); } Agent.GetRoot().SetFlagRecursive(GameComponent.Flag.Visible, false); Agent.World.ParticleManager.Trigger("star_particle", diff * t + currPosition, Color.White, 1); if (action.InteractObject != null) { Agent.World.ParticleManager.Trigger("green_flame", (action.InteractObject as Body).Position, Color.White, 1); } transform.Translation = action.DestinationVoxel.WorldPosition + Vector3.One * 0.5f; break; } Agent.Physics.LocalTransform = transform; lastMovement = action.MoveType; }
public IEnumerable <Status> PerformStep(MoveAction Step) { var actionSpeed = GetAgentSpeed(Step.MoveType); switch (Step.MoveType) { #region Ride Elevator case MoveType.RideElevator: var shafts = Step.DestinationState.Tag as Elevators.ElevatorMoveState; if (shafts == null || shafts.Entrance == null || shafts.Entrance.IsDead || shafts.Exit == null || shafts.Exit.IsDead) { yield return(Status.Fail); } var shaft = shafts.Entrance.Shaft; if (shaft == null || shaft.Invalid) { yield return(Status.Fail); } if (!shaft.EnqueuDwarf(Agent, shafts)) { yield return(Status.Fail); } while (!shaft.ReadyToBoard(Agent)) { if (DeltaTime > 30.0f) { yield return(Status.Fail); // We waited too long. } if (shaft.Invalid) { yield return(Status.Fail); } SetCharacterMode(CharacterMode.Idle); if (Debugger.Switches.DebugElevators) { Drawer3D.DrawBox(shafts.Entrance.GetBoundingBox(), Color.Red, 0.1f, false); Drawer3D.DrawBox(shafts.Exit.GetBoundingBox(), Color.Red, 0.1f, false); Drawer3D.DrawBox(Step.DestinationVoxel.GetBoundingBox(), Color.Red, 0.1f, false); } yield return(Status.Running); } DeltaTime = 0; foreach (var bit in Translate(Agent.Position, GetPathPoint(shafts.Entrance.GetContainingVoxel()), actionSpeed)) { if (shaft.Invalid) { yield return(Status.Fail); } shaft.WaitForMe(Agent); SetCharacterMode(CharacterMode.Walking); if (Debugger.Switches.DebugElevators) { Drawer3D.DrawBox(shafts.Entrance.GetBoundingBox(), Color.Green, 0.1f, false); Drawer3D.DrawBox(shafts.Exit.GetBoundingBox(), Color.Green, 0.1f, false); Drawer3D.DrawBox(Step.DestinationVoxel.GetBoundingBox(), Color.Green, 0.1f, false); } yield return(Status.Running); } shaft.StartMotion(Agent); var grav = Creature.Physics.Gravity; //Creature.Physics.Gravity = Vector3.Zero; while (!shaft.AtDestination(Agent)) { if (shaft.Invalid) { yield return(Status.Fail); } SetCharacterMode(CharacterMode.Idle); if (Debugger.Switches.DebugElevators) { Drawer3D.DrawBox(shafts.Entrance.GetBoundingBox(), Color.Red, 0.1f, false); Drawer3D.DrawBox(shafts.Exit.GetBoundingBox(), Color.Red, 0.1f, false); Drawer3D.DrawBox(Step.DestinationVoxel.GetBoundingBox(), Color.Red, 0.1f, false); } yield return(Status.Running); } DeltaTime = 0; foreach (var bit in Translate(Agent.Physics.LocalPosition, GetPathPoint(Step.DestinationVoxel), actionSpeed)) { if (shaft.Invalid) { yield return(Status.Fail); } shaft.WaitForMe(Agent); SetCharacterMode(CharacterMode.Walking); if (Debugger.Switches.DebugElevators) { Drawer3D.DrawBox(shafts.Entrance.GetBoundingBox(), Color.Green, 0.1f, false); Drawer3D.DrawBox(shafts.Exit.GetBoundingBox(), Color.Green, 0.1f, false); Drawer3D.DrawBox(Step.DestinationVoxel.GetBoundingBox(), Color.Green, 0.1f, false); } yield return(Status.Running); } Creature.Physics.Gravity = grav; shaft.Done(Agent); break; #endregion case MoveType.EnterVehicle: Creature.NoiseMaker.MakeNoise("Jump", Agent.Position, false); foreach (var bit in Jump(GetPathPoint(Step.SourceVoxel), GetPathPoint(Step.DestinationVoxel), Step.DestinationVoxel.Center - Step.SourceVoxel.Center, actionSpeed)) { SetCharacterMode(Creature.Physics.Velocity.Y > 0 ? CharacterMode.Jumping : CharacterMode.Falling); yield return(Status.Running); } DeltaTime = 0.0f; SetupMinecart(); break; case MoveType.ExitVehicle: CleanupMinecart(); SetAgentTranslation(GetPathPoint(Step.DestinationVoxel)); break; case MoveType.RideVehicle: SetupMinecart(); var rail = Step.SourceState.Rail; if (rail == null) { yield return(Status.Fail); } while (DeltaTime < 1.0f / actionSpeed) { var pos = rail.InterpolateSpline(DeltaTime, GetPathPoint(Step.SourceVoxel), GetPathPoint(Step.DestinationVoxel)); var transform = Agent.Physics.LocalTransform; transform.Translation = pos + Vector3.Up * 0.5f; Agent.Physics.LocalTransform = transform; Agent.Physics.Velocity = GetPathPoint(Step.DestinationVoxel) - GetPathPoint(Step.SourceVoxel); SetCharacterMode(CharacterMode.Minecart); yield return(Status.Running); } DeltaTime -= (1.0f / actionSpeed); break; case MoveType.Walk: // Todo: Fail if distance is too great. CleanupMinecart(); foreach (var bit in Translate(Agent.Position, GetPathPoint(Step.DestinationVoxel), actionSpeed)) { SetCharacterMode(CharacterMode.Walking); yield return(Status.Running); } break; case MoveType.Swim: CleanupMinecart(); foreach (var bit in Translate(GetPathPoint(Step.SourceVoxel), GetPathPoint(Step.DestinationVoxel) + (0.5f * Vector3.Up * Agent.Physics.BoundingBox.Extents().Y), actionSpeed)) { Creature.NoiseMaker.MakeNoise("Swim", Agent.Position, true); SetCharacterMode(CharacterMode.Swimming); yield return(Status.Running); } break; case MoveType.Jump: CleanupMinecart(); Creature.NoiseMaker.MakeNoise("Jump", Agent.Position, false); var dest = GetPathPoint(Step.DestinationVoxel); foreach (var bit in Jump(Agent.Position, dest, dest - Agent.Position, actionSpeed / 2.0f)) { Creature.OverrideCharacterMode = false; SetCharacterMode(Creature.Physics.Velocity.Y > 0 ? CharacterMode.Jumping : CharacterMode.Falling); yield return(Status.Running); } SetAgentTranslation(dest); break; case MoveType.Fall: CleanupMinecart(); foreach (var bit in Translate(Agent.Position, GetPathPoint(Step.DestinationVoxel), actionSpeed)) { SetCharacterMode(CharacterMode.Falling); yield return(Status.Running); } break; case MoveType.Climb: CleanupMinecart(); DeltaTime = 0.0f; foreach (var bit in Translate(GetPathPoint(Step.SourceVoxel), GetPathPoint(Step.DestinationVoxel), actionSpeed)) { if (Step.InteractObject == null || Step.InteractObject.IsDead) { yield return(Status.Fail); } if (DeltaTime - LastNoiseTime > 1.0f) { Creature.NoiseMaker.MakeNoise("Climb", Agent.Position, false); LastNoiseTime = DeltaTime; } SetCharacterMode(CharacterMode.Climbing); yield return(Status.Running); } break; case MoveType.ClimbWalls: CleanupMinecart(); DeltaTime = 0.0f; foreach (var bit in Translate(GetPathPoint(Step.SourceVoxel), GetPathPoint(Step.DestinationVoxel), actionSpeed)) { if (DeltaTime - LastNoiseTime > 1.0f) { Creature.NoiseMaker.MakeNoise("Climb", Agent.Position, false); LastNoiseTime = DeltaTime; } SetCharacterMode(CharacterMode.Climbing); if (Step.ActionVoxel.IsValid) { var voxelVector = new Vector3(Step.ActionVoxel.Coordinate.X + 0.5f, Agent.Physics.Position.Y, Step.ActionVoxel.Coordinate.Z + 0.5f); Agent.Physics.Velocity = Vector3.Normalize(voxelVector - Agent.Physics.Position) * actionSpeed; } yield return(Status.Running); } break; case MoveType.Fly: CleanupMinecart(); DeltaTime = 0.0f; foreach (var bit in Translate(GetPathPoint(Step.SourceVoxel), GetPathPoint(Step.DestinationVoxel), actionSpeed)) { if ((int)(DeltaTime * 100) % 2 == 0) { Creature.NoiseMaker.MakeNoise("Flap", Agent.Position, false); } SetCharacterMode(CharacterMode.Flying); yield return(Status.Running); } break; case MoveType.Dig: CleanupMinecart(); var destroy = new DigAct(Creature.AI, new KillVoxelTask(Step.DestinationVoxel)) { CheckOwnership = false }; destroy.Initialize(); foreach (var status in destroy.Run()) { if (status == Act.Status.Fail) { yield return(Act.Status.Fail); } yield return(Act.Status.Running); } yield return(Act.Status.Fail); // Abort the path so that they stop digging if a path has opened. break; case MoveType.DestroyObject: CleanupMinecart(); var melee = new MeleeAct(Creature.AI, (GameComponent)Step.InteractObject); melee.Initialize(); foreach (var status in melee.Run()) { if (status == Act.Status.Fail) { yield return(Act.Status.Fail); } yield return(Act.Status.Running); } yield return(Act.Status.Fail); // Abort the path so that they stop destroying things if a path has opened. break; case MoveType.Teleport: if (Step.InteractObject == null || Step.InteractObject.IsDead) { yield return(Status.Fail); } var teleporter = Step.InteractObject.GetComponent <MagicalObject>(); if (teleporter != null) { teleporter.CurrentCharges--; } SoundManager.PlaySound(ContentPaths.Audio.Oscar.sfx_ic_dwarf_magic_research, Agent.Position, true, 1.0f); Agent.World.ParticleManager.Trigger("green_flame", (Step.InteractObject as GameComponent).Position, Color.White, 1); Agent.GetRoot().SetFlagRecursive(GameComponent.Flag.Visible, false); foreach (var bit in Translate(GetPathPoint(Step.SourceVoxel), GetPathPoint(Step.DestinationVoxel), actionSpeed)) { Agent.World.ParticleManager.Trigger("star_particle", Agent.Position, Color.White, 1); yield return(Status.Running); } Agent.GetRoot().SetFlagRecursive(GameComponent.Flag.Visible, true); break; } }