public override Task ActOnIdle() { if (StealFromPlayerProbability > 0 && MathFunctions.RandEvent(StealFromPlayerProbability)) { bool stealMoney = MathFunctions.RandEvent(0.5f); if (World.PlayerFaction.Economy.CurrentMoney > 0 && stealMoney) { AssignTask(new ActWrapperTask(new GetMoneyAct(this, 100m, World.PlayerFaction)) { Name = "Steal money", Priority = Task.PriorityType.High }); } else { var resources = World.PlayerFaction.ListResources(); if (resources.Count > 0) { var resource = Datastructures.SelectRandom(resources); if (resource.Value.NumResources > 0) { AssignTask(new ActWrapperTask(new GetResourcesAct(this, new List <ResourceAmount>() { new ResourceAmount(resource.Value.ResourceType, 1) }) { Faction = World.PlayerFaction }) { Name = "Steal stuff", Priority = Task.PriorityType.High }); } } } } LeaveWorldTimer.Update(DwarfTime.LastTime); if (LeaveWorldTimer.HasTriggered) { LeaveWorld(); LeaveWorldTimer.Reset(); } return(base.ActOnIdle()); }
public void Update(DwarfTime time, Camera cam, GraphicsDevice graphics) { if (DwarfGame.ExitGame) { return; } DeleteNulls(); sortTimer.Update(time); if (sortTimer.HasTriggered) { SortDistances(); sortTimer.Reset(sortTimer.TargetTimeSeconds); } //RebuildVertices(); //InstanceBuffer.SetData(Vertices); AddRemove(); }
public override Task ActOnIdle() { if (DestroyPlayerObjectProbability > 0 && MathFunctions.RandEvent(DestroyPlayerObjectProbability)) { bool plantBomb = !String.IsNullOrEmpty(PlantBomb) && MathFunctions.RandEvent(0.5f); if (!plantBomb && World.PlayerFaction.OwnedObjects.Count > 0) { var thing = Datastructures.SelectRandom <GameComponent>(World.PlayerFaction.OwnedObjects); AssignTask(new KillEntityTask(thing, KillEntityTask.KillType.Auto)); } else if (plantBomb) { var room = World.FindNearestZone(Position); if (room != null) { AssignTask(new ActWrapperTask(new Sequence(new GoToZoneAct(this, room), new Do(() => { EntityFactory.CreateEntity <GameComponent>(PlantBomb, Position); return(true); }))) { Priority = TaskPriority.High }); } else if (World.PlayerFaction.OwnedObjects.Count > 0) { var thing = Datastructures.SelectRandom <GameComponent>(World.PlayerFaction.OwnedObjects); AssignTask(new ActWrapperTask(new Sequence(new GoToEntityAct(thing, this), new Do(() => { EntityFactory.CreateEntity <GameComponent>(PlantBomb, Position); return(true); }))) { Priority = TaskPriority.High }); } } } LeaveWorldTimer.Update(DwarfTime.LastTime); if (LeaveWorldTimer.HasTriggered) { LeaveWorld(); LeaveWorldTimer.Reset(); } return(base.ActOnIdle()); }
public void Update(DwarfTime time, Camera cam, GraphicsDevice graphics) { if (DwarfGame.ExitGame) { return; } DeleteNulls(); sortTimer.Update(time); if (sortTimer.HasTriggered) { SortDistances(); sortTimer.Reset(sortTimer.TargetTimeSeconds); } AddRemove(); if (instanceVertexes == null) { instanceVertexes = new InstancedVertex[numInstances]; } int j = 0; foreach (InstanceData t in SortedData.Data) { if (t.ShouldDraw) { instanceVertexes[j].Transform = t.Transform; instanceVertexes[j].Color = t.Color; j++; } } numActiveInstances = j; }
public override IEnumerable <Status> Run() { Path = null; Timeouts = 0; PlannerTimer.Reset(PlannerTimer.TargetTimeSeconds); var lastId = -1; Vector3 goalPos = Vector3.Zero; Agent.Blackboard.SetData <bool>("NoPath", false); while (true) { if (Path != null) { yield return(Status.Success); break; } if (Timeouts > MaxTimeouts) { Agent.Blackboard.SetData <bool>("NoPath", true); yield return(Status.Fail); break; } if (WaitingOnResponse && Debugger.Switches.DrawPaths) { Drawer3D.DrawLine(Creature.AI.Position, goalPos, Color.Blue, 0.25f); } PlannerTimer.Update(DwarfTime.LastTime); ChunkManager chunks = Creature.Manager.World.ChunkManager; if (PlannerTimer.HasTriggered || Timeouts == 0) { if (!Target.IsValid && Type != PlanType.Edge) { Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question); Agent.Blackboard.SetData <bool>("NoPath", true); yield return(Status.Fail); break; } var voxUnder = VoxelHelpers.FindValidVoxelNear(chunks, Agent.Position); if (!voxUnder.IsValid) { if (Debugger.Switches.DrawPaths) { Creature.World.UserInterface.MakeWorldPopup(String.Format("Invalid request"), Creature.Physics, -10, 1); } Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question); Agent.Blackboard.SetData <bool>("NoPath", true); yield return(Status.Fail); break; } Path = null; AstarPlanRequest aspr = new AstarPlanRequest { Subscriber = Agent.PlanSubscriber, Start = voxUnder, MaxExpansions = MaxExpansions, Sender = Agent, HeuristicWeight = Weights[Timeouts] }; lastId = aspr.ID; aspr.GoalRegion = GetGoal(); goalPos = GetGoal().GetVoxel().GetBoundingBox().Center(); Agent.PlanSubscriber.Clear(); if (!Agent.PlanSubscriber.SendRequest(aspr, aspr.ID)) { yield return(Status.Fail); yield break; } PlannerTimer.Reset(PlannerTimer.TargetTimeSeconds); WaitingOnResponse = true; yield return(Status.Running); Timeouts++; } else { Status statusResult = Status.Running; while (Agent.PlanSubscriber.Responses.Count > 0) { AStarPlanResponse response; if (!Agent.PlanSubscriber.Responses.TryDequeue(out response)) { yield return(Status.Running); continue; } LastResult = response.Result; if (response.Success && response.Request.ID == lastId) { Path = response.Path; WaitingOnResponse = false; statusResult = Status.Success; } else if (response.Request.ID != lastId && response.Path != null && response.Path.Count > 0) { var goal = GetGoal(); bool obeysGoal = goal == null ? false : (response.Success && (goal.IsInGoalRegion(response.Path.Last().DestinationVoxel))); if (Debugger.Switches.DrawPaths) { if (obeysGoal) { Creature.World.UserInterface.MakeWorldPopup(String.Format("Using Old Path", response.Result), Creature.Physics, -10, 1); } else { Creature.World.UserInterface.MakeWorldPopup(String.Format("Old Path Dropped", response.Result), Creature.Physics, -10, 1); } } if (obeysGoal) { Path = response.Path; WaitingOnResponse = false; statusResult = Status.Success; } else { continue; } } else if (response.Result == AStarPlanner.PlanResultCode.Invalid || response.Result == AStarPlanner.PlanResultCode.NoSolution || response.Result == AStarPlanner.PlanResultCode.Cancelled || response.Result == AStarPlanner.PlanResultCode.Invalid) { if (Debugger.Switches.DrawPaths) { Creature.World.UserInterface.MakeWorldPopup(String.Format("Path: {0}", response.Result), Creature.Physics, -10, 1); } Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question); Agent.Blackboard.SetData <bool>("NoPath", true); statusResult = Status.Fail; yield return(Status.Fail); } else if (Timeouts <= MaxTimeouts) { Timeouts++; yield return(Status.Running); } else { if (Debugger.Switches.DrawPaths) { Creature.World.UserInterface.MakeWorldPopup(String.Format("Max timeouts reached", response.Result), Creature.Physics, -10, 1); } Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question); Agent.Blackboard.SetData <bool>("NoPath", true); statusResult = Status.Fail; } } yield return(statusResult); } } }
public void OverheadUpdate(DwarfTime time, ChunkManager chunks) { Voxel currentVoxel = new Voxel(); float diffPhi = 0; float diffTheta = 0; float diffRadius = 0; Vector3 forward = (Target - Position); forward.Normalize(); Vector3 right = Vector3.Cross(forward, UpVector); Vector3 up = Vector3.Cross(right, forward); right.Normalize(); up.Normalize(); MouseState mouse = Mouse.GetState(); KeyboardState keys = Keyboard.GetState(); if (ZoomTargets.Count > 0) { Vector3 currTarget = ProjectToSurface(ZoomTargets.First()); if (Vector3.DistanceSquared(Target, currTarget) > 5) { Vector3 newTarget = 0.8f * Target + 0.2f * currTarget; Vector3 d = newTarget - Target; Target += d; Position += d; } else { ZoomTargets.RemoveAt(0); } } int edgePadding = -10000; if (GameSettings.Default.EnableEdgeScroll) { edgePadding = 100; } float diffX, diffY = 0; bool stateChanged = false; float dt = (float)time.ElapsedRealTime.TotalSeconds; SnapToBounds(new BoundingBox(World.ChunkManager.Bounds.Min, World.ChunkManager.Bounds.Max + Vector3.UnitY * 20)); if (KeyManager.RotationEnabled()) { if (!shiftPressed) { shiftPressed = true; mouse = Mouse.GetState(); stateChanged = true; } if (!isLeftPressed && mouse.LeftButton == ButtonState.Pressed) { isLeftPressed = true; stateChanged = true; } else if (mouse.LeftButton == ButtonState.Released) { isLeftPressed = false; } if (!isRightPressed && mouse.RightButton == ButtonState.Pressed) { isRightPressed = true; stateChanged = true; } else if (mouse.RightButton == ButtonState.Released) { isRightPressed = false; } if (stateChanged) { Mouse.SetPosition(GameState.Game.GraphicsDevice.Viewport.Width / 2, GameState.Game.GraphicsDevice.Viewport.Height / 2); mouse = Mouse.GetState(); } diffX = mouse.X - GameState.Game.GraphicsDevice.Viewport.Width / 2; diffY = mouse.Y - GameState.Game.GraphicsDevice.Viewport.Height / 2; if (!isRightPressed) { float filterDiffX = (float)(diffX * dt); float filterDiffY = (float)(diffY * dt); diffTheta = (filterDiffX); diffPhi = -(filterDiffY); } } else { shiftPressed = false; } bool goingBackward = false; Vector3 velocityToSet = Vector3.Zero; if (keys.IsKeyDown(ControlSettings.Mappings.Forward) || keys.IsKeyDown(Keys.Up)) { Vector3 mov = forward; mov.Y = 0; mov.Normalize(); velocityToSet += mov * CameraMoveSpeed * dt; } else if (keys.IsKeyDown(ControlSettings.Mappings.Back) || keys.IsKeyDown(Keys.Down)) { goingBackward = true; Vector3 mov = forward; mov.Y = 0; mov.Normalize(); velocityToSet += -mov * CameraMoveSpeed * dt; } if (keys.IsKeyDown(ControlSettings.Mappings.Left) || keys.IsKeyDown(Keys.Left)) { Vector3 mov = right; mov.Y = 0; mov.Normalize(); velocityToSet += -mov * CameraMoveSpeed * dt; } else if (keys.IsKeyDown(ControlSettings.Mappings.Right) || keys.IsKeyDown(Keys.Right)) { Vector3 mov = right; mov.Y = 0; mov.Normalize(); velocityToSet += mov * CameraMoveSpeed * dt; } if (velocityToSet.LengthSquared() > 0) { Velocity = velocityToSet; } if (!KeyManager.RotationEnabled()) { World.GUI.IsMouseVisible = true; if (!World.IsMouseOverGui) { if (mouse.X < edgePadding || mouse.X > GameState.Game.GraphicsDevice.Viewport.Width - edgePadding) { moveTimer.Update(time); if (moveTimer.HasTriggered) { float dir = 0.0f; if (mouse.X < edgePadding) { dir = edgePadding - mouse.X; } else { dir = (GameState.Game.GraphicsDevice.Viewport.Width - edgePadding) - mouse.X; } dir *= 0.01f; Vector3 delta = right * CameraMoveSpeed * dir * dt; delta.Y = 0; Velocity = -delta; } } else if (mouse.Y < edgePadding || mouse.Y > GameState.Game.GraphicsDevice.Viewport.Height - edgePadding) { moveTimer.Update(time); if (moveTimer.HasTriggered) { float dir = 0.0f; if (mouse.Y < edgePadding) { dir = -(edgePadding - mouse.Y); } else { dir = -((GameState.Game.GraphicsDevice.Viewport.Height - edgePadding) - mouse.Y); } dir *= 0.01f; Vector3 delta = up * CameraMoveSpeed * dir * dt; delta.Y = 0; Velocity = -delta; } } else { moveTimer.Reset(moveTimer.TargetTimeSeconds); } } } else { World.GUI.IsMouseVisible = false; } int scroll = mouse.ScrollWheelValue; if (isRightPressed && KeyManager.RotationEnabled()) { scroll = (int)(diffY * 10) + LastWheel; } if (scroll != LastWheel && !World.IsMouseOverGui) { int change = scroll - LastWheel; if (!(keys.IsKeyDown(Keys.LeftAlt) || keys.IsKeyDown(Keys.RightAlt))) { if (!keys.IsKeyDown(Keys.LeftControl)) { var delta = change * -1; if (GameSettings.Default.InvertZoom) { delta *= -1; } diffRadius = delta * CameraZoomSpeed * dt; if (diffRadius < 0) { float diffxy = (new Vector3(Target.X, 0, Target.Z) - new Vector3(World.CursorPos.X, 0, World.CursorPos.Z)).Length(); if (diffxy > 5) { Vector3 slewTarget = Target * 0.9f + World.CursorPos * 0.1f; Vector3 slewDiff = slewTarget - Target; Target += slewDiff; Position += slewDiff; } } } else { chunks.ChunkData.SetMaxViewingLevel(chunks.ChunkData.MaxViewingLevel + (int)((float)change * 0.01f), ChunkManager.SliceMode.Y); } } } LastWheel = mouse.ScrollWheelValue; if (!CollidesWithChunks(World.ChunkManager, Position + Velocity, false)) { MoveTarget(Velocity); PushVelocity = Vector3.Zero; } else { PushVelocity += Vector3.Up * 0.1f; Position += PushVelocity; } Velocity *= 0.8f; UpdateBasisVectors(); Vector3 projectedTarget = ProjectToSurface(Target); Vector3 diffTarget = projectedTarget - Target; Position = (Position + diffTarget) * 0.05f + Position * 0.95f; Target = projectedTarget * 0.05f + Target * 0.95f; float currRadius = (Position - Target).Length(); float newRadius = Math.Max(currRadius + diffRadius, 3.0f); Position = MathFunctions.ProjectOutOfHalfPlane(MathFunctions.ProjectOutOfCylinder(MathFunctions.ProjectToSphere(Position - right * diffTheta * 2 - up * diffPhi * 2, newRadius, Target), Target, 3.0f), Target, 2.0f); UpdateViewMatrix(); }
public void OverheadUpdate(DwarfTime time, ChunkManager chunks, float diffPhi, float diffTheta, float diffRadius) { Vector3 forward = (Target - Position); forward.Normalize(); Vector3 right = Vector3.Cross(forward, UpVector); Vector3 up = Vector3.Cross(right, forward); right.Normalize(); up.Normalize(); MouseState mouse = Mouse.GetState(); KeyboardState keys = Keyboard.GetState(); var bounds = new BoundingBox(World.ChunkManager.Bounds.Min, World.ChunkManager.Bounds.Max + Vector3.UnitY * 20); if (ZoomTargets.Count > 0) { Vector3 currTarget = MathFunctions.Clamp(ProjectToSurface(ZoomTargets.First()), bounds); if (MathFunctions.Dist2D(Target, currTarget) > 5 && _zoomTime < 3) { Vector3 newTarget = 0.8f * Target + 0.2f * currTarget; Vector3 d = newTarget - Target; if (bounds.Contains(Target + d) != ContainmentType.Contains) { _zoomTime = 0; ZoomTargets.RemoveAt(0); } else { Target += d; Position += d; _zoomTime += (float)time.ElapsedRealTime.TotalSeconds; } } else { _zoomTime = 0; ZoomTargets.RemoveAt(0); } } Target = MathFunctions.Clamp(Target, bounds); int edgePadding = -10000; if (GameSettings.Default.EnableEdgeScroll) { edgePadding = 100; } float diffX, diffY = 0; float dt = (float)time.ElapsedRealTime.TotalSeconds; SnapToBounds(new BoundingBox(World.ChunkManager.Bounds.Min, World.ChunkManager.Bounds.Max + Vector3.UnitY * 20)); if (KeyManager.RotationEnabled(this)) { World.UserInterface.Gui.MouseVisible = false; if (!shiftPressed) { shiftPressed = true; mouseOnRotate = new Point(mouse.X, mouse.Y); mousePrerotate = new Point(mouse.X, mouse.Y); } if (!isLeftPressed && mouse.LeftButton == ButtonState.Pressed) { isLeftPressed = true; } else if (mouse.LeftButton == ButtonState.Released) { isLeftPressed = false; } if (!isRightPressed && mouse.RightButton == ButtonState.Pressed) { isRightPressed = true; } else if (mouse.RightButton == ButtonState.Released) { isRightPressed = false; } Mouse.SetPosition(mouseOnRotate.X, mouseOnRotate.Y); diffX = mouse.X - mouseOnRotate.X; diffY = mouse.Y - mouseOnRotate.Y; if (!isRightPressed) { float filterDiffX = (float)(diffX * dt); float filterDiffY = (float)(diffY * dt); diffTheta = (filterDiffX); diffPhi = -(filterDiffY); } KeyManager.TrueMousePos = mousePrerotate; } else { if (shiftPressed) { Mouse.SetPosition(mousePrerotate.X, mousePrerotate.Y); KeyManager.TrueMousePos = new Point(mousePrerotate.X, mousePrerotate.Y); } else { KeyManager.TrueMousePos = new Point(mouse.X, mouse.Y); } shiftPressed = false; World.UserInterface.Gui.MouseVisible = true; } Vector3 velocityToSet = Vector3.Zero; //if (EnableControl) { if (keys.IsKeyDown(ControlSettings.Mappings.Forward) || keys.IsKeyDown(Keys.Up)) { Vector3 mov = forward; mov.Y = 0; mov.Normalize(); velocityToSet += mov * CameraMoveSpeed * dt; } else if (keys.IsKeyDown(ControlSettings.Mappings.Back) || keys.IsKeyDown(Keys.Down)) { Vector3 mov = forward; mov.Y = 0; mov.Normalize(); velocityToSet += -mov * CameraMoveSpeed * dt; } if (keys.IsKeyDown(ControlSettings.Mappings.Left) || keys.IsKeyDown(Keys.Left)) { Vector3 mov = right; mov.Y = 0; mov.Normalize(); velocityToSet += -mov * CameraMoveSpeed * dt; } else if (keys.IsKeyDown(ControlSettings.Mappings.Right) || keys.IsKeyDown(Keys.Right)) { Vector3 mov = right; mov.Y = 0; mov.Normalize(); velocityToSet += mov * CameraMoveSpeed * dt; } } //else if (FollowAutoTarget) { Vector3 prevTarget = Target; float damper = MathFunctions.Clamp((Target - AutoTarget).Length() - 5, 0, 1); float smooth = 0.1f * damper; Target = AutoTarget * (smooth) + Target * (1.0f - smooth); Position += (Target - prevTarget); } if (velocityToSet.LengthSquared() > 0) { World.Tutorial("camera"); Velocity = velocityToSet; } if (!KeyManager.RotationEnabled(this)) { if (!World.UserInterface.IsMouseOverGui) { if (mouse.X < edgePadding || mouse.X > GameState.Game.GraphicsDevice.Viewport.Width - edgePadding) { moveTimer.Update(time); if (moveTimer.HasTriggered) { float dir = 0.0f; if (mouse.X < edgePadding) { dir = edgePadding - mouse.X; } else { dir = (GameState.Game.GraphicsDevice.Viewport.Width - edgePadding) - mouse.X; } dir *= 0.01f; Vector3 delta = right * CameraMoveSpeed * dir * dt; delta.Y = 0; Velocity = -delta; } } else if (mouse.Y < edgePadding || mouse.Y > GameState.Game.GraphicsDevice.Viewport.Height - edgePadding) { moveTimer.Update(time); if (moveTimer.HasTriggered) { float dir = 0.0f; if (mouse.Y < edgePadding) { dir = -(edgePadding - mouse.Y); } else { dir = -((GameState.Game.GraphicsDevice.Viewport.Height - edgePadding) - mouse.Y); } dir *= 0.01f; Vector3 delta = up * CameraMoveSpeed * dir * dt; delta.Y = 0; Velocity = -delta; } } else { moveTimer.Reset(moveTimer.TargetTimeSeconds); } } } int scroll = mouse.ScrollWheelValue; if (isRightPressed && KeyManager.RotationEnabled(this)) { scroll = (int)(diffY * 10) + LastWheel; } if (scroll != LastWheel && !World.UserInterface.IsMouseOverGui) { int change = scroll - LastWheel; if (!(keys.IsKeyDown(Keys.LeftAlt) || keys.IsKeyDown(Keys.RightAlt))) { if (!keys.IsKeyDown(Keys.LeftControl)) { var delta = change * -1; if (GameSettings.Default.InvertZoom) { delta *= -1; } diffRadius = delta * CameraZoomSpeed * dt; if (diffRadius < 0 && !FollowAutoTarget && GameSettings.Default.ZoomCameraTowardMouse && !shiftPressed) { float diffxy = (new Vector3(Target.X, 0, Target.Z) - new Vector3(World.Renderer.CursorLightPos.X, 0, World.Renderer.CursorLightPos.Z)).Length(); if (diffxy > 5) { Vector3 slewTarget = Target * 0.9f + World.Renderer.CursorLightPos * 0.1f; Vector3 slewDiff = slewTarget - Target; Target += slewDiff; Position += slewDiff; } } } else { World.Renderer.SetMaxViewingLevel(World.Renderer.PersistentSettings.MaxViewingLevel + (int)((float)change * 0.01f)); } } } LastWheel = mouse.ScrollWheelValue; if (!CollidesWithChunks(World.ChunkManager, Position + Velocity, false, false, 0.5f, 1.0f)) { MoveTarget(Velocity); PushVelocity = Vector3.Zero; } else { PushVelocity += Vector3.Up * 0.1f; Position += PushVelocity; } Velocity *= 0.8f; UpdateBasisVectors(); bool projectTarget = GameSettings.Default.CameraFollowSurface || (!GameSettings.Default.CameraFollowSurface && (keys.IsKeyDown(Keys.LeftControl) || keys.IsKeyDown(Keys.RightControl))); Vector3 projectedTarget = projectTarget ? ProjectToSurface(Target) : Target; Vector3 diffTarget = projectedTarget - Target; if (diffTarget.LengthSquared() > 25) { diffTarget.Normalize(); diffTarget *= 5; } Position = (Position + diffTarget) * 0.05f + Position * 0.95f; Target = (Target + diffTarget) * 0.05f + Target * 0.95f; float currRadius = (Position - Target).Length(); float newRadius = Math.Max(currRadius + diffRadius, 3.0f); Position = MathFunctions.ProjectOutOfHalfPlane(MathFunctions.ProjectOutOfCylinder(MathFunctions.ProjectToSphere(Position - right * diffTheta * 2 - up * diffPhi * 2, newRadius, Target), Target, 3.0f), Target, 2.0f); UpdateViewMatrix(); }
public void OverheadUpdate(DwarfTime time, ChunkManager chunks) { MouseState mouse = Mouse.GetState(); KeyboardState keys = Keyboard.GetState(); if (ZoomTargets.Count > 0) { Vector3 currTarget = ZoomTargets.First(); if (Vector3.DistanceSquared(Target, currTarget) > 5) { Target = 0.8f * Target + 0.2f * currTarget; } else { ZoomTargets.RemoveAt(0); } } int edgePadding = -10000; if (GameSettings.Default.EnableEdgeScroll) { edgePadding = 100; } bool stateChanged = false; float dt = (float)time.ElapsedRealTime.TotalSeconds; SnapToBounds(new BoundingBox(PlayState.ChunkManager.Bounds.Min, PlayState.ChunkManager.Bounds.Max + Vector3.UnitY * 20)); if (KeyManager.RotationEnabled()) { if (!shiftPressed) { shiftPressed = true; mouse = Mouse.GetState(); stateChanged = true; } if (!isLeftPressed && mouse.LeftButton == ButtonState.Pressed) { isLeftPressed = true; stateChanged = true; } else if (mouse.LeftButton == ButtonState.Released) { isLeftPressed = false; } if (!isRightPressed && mouse.RightButton == ButtonState.Pressed) { isRightPressed = true; stateChanged = true; } else if (mouse.RightButton == ButtonState.Released) { isRightPressed = false; } if (stateChanged) { Mouse.SetPosition(GameState.Game.GraphicsDevice.Viewport.Width / 2, GameState.Game.GraphicsDevice.Viewport.Height / 2); mouse = Mouse.GetState(); } float diffX = mouse.X - GameState.Game.GraphicsDevice.Viewport.Width / 2; float diffY = mouse.Y - GameState.Game.GraphicsDevice.Viewport.Height / 2; float filterDiffX = (float)(diffX * dt); float filterDiffY = (float)(diffY * dt); if (Math.Abs(filterDiffX) > 1.0f) { filterDiffX = 1.0f * Math.Sign(filterDiffX); } if (Math.Abs(filterDiffY) > 1.0f) { filterDiffY = 1.0f * Math.Sign(filterDiffY); } targetTheta = Theta - (filterDiffX); targetPhi = Phi - (filterDiffY); Theta = targetTheta * 0.5f + Theta * 0.5f; Phi = targetPhi * 0.5f + Phi * 0.5f; if (Phi < -1.5f) { Phi = -1.5f; } else if (Phi > 1.5f) { Phi = 1.5f; } } else { shiftPressed = false; } bool goingBackward = false; Vector3 velocityToSet = Vector3.Zero; if (keys.IsKeyDown(ControlSettings.Mappings.Forward) || keys.IsKeyDown(Keys.Up)) { Vector3 forward = (Target - Position); forward.Normalize(); if (!KeyManager.RotationEnabled()) { forward.Y = 0; } forward.Normalize(); velocityToSet += forward * CameraMoveSpeed * dt; } else if (keys.IsKeyDown(ControlSettings.Mappings.Back) || keys.IsKeyDown(Keys.Down)) { Vector3 forward = (Target - Position); forward.Normalize(); goingBackward = true; if (!KeyManager.RotationEnabled()) { forward.Y = 0; } forward.Normalize(); velocityToSet += -forward * CameraMoveSpeed * dt; } if (keys.IsKeyDown(ControlSettings.Mappings.Left) || keys.IsKeyDown(Keys.Left)) { Vector3 forward = (Target - Position); forward.Normalize(); Vector3 right = Vector3.Cross(forward, UpVector); right.Normalize(); if (goingBackward) { //right *= -1; } velocityToSet += -right * CameraMoveSpeed * dt; } else if (keys.IsKeyDown(ControlSettings.Mappings.Right) || keys.IsKeyDown(Keys.Right)) { Vector3 forward = (Target - Position); forward.Normalize(); Vector3 right = Vector3.Cross(forward, UpVector); right.Normalize(); if (goingBackward) { //right *= -1; } velocityToSet += right * CameraMoveSpeed * dt; } if (velocityToSet.LengthSquared() > 0) { Velocity = velocityToSet; } if (!KeyManager.RotationEnabled()) { if (mouse.X < edgePadding || mouse.X > GameState.Game.GraphicsDevice.Viewport.Width - edgePadding) { moveTimer.Update(time); if (moveTimer.HasTriggered) { float dir = 0.0f; if (mouse.X < edgePadding) { dir = edgePadding - mouse.X; } else { dir = (GameState.Game.GraphicsDevice.Viewport.Width - edgePadding) - mouse.X; } dir *= 0.05f; Vector3 forward = (Target - Position); forward.Normalize(); Vector3 right = Vector3.Cross(forward, UpVector); Vector3 delta = right * CameraMoveSpeed * dir * dt; delta.Y = 0; Velocity = -delta; } } else if (mouse.Y < edgePadding || mouse.Y > GameState.Game.GraphicsDevice.Viewport.Height - edgePadding) { moveTimer.Update(time); if (moveTimer.HasTriggered) { float dir = 0.0f; if (mouse.Y < edgePadding) { dir = -(edgePadding - mouse.Y); } else { dir = -((GameState.Game.GraphicsDevice.Viewport.Height - edgePadding) - mouse.Y); } dir *= 0.1f; Vector3 forward = (Target - Position); forward.Normalize(); Vector3 right = Vector3.Cross(forward, UpVector); Vector3 up = Vector3.Cross(right, forward); Vector3 delta = up * CameraMoveSpeed * dir * dt; delta.Y = 0; Velocity = -delta; } } else { moveTimer.Reset(moveTimer.TargetTimeSeconds); } } if (mouse.ScrollWheelValue != LastWheel && !PlayState.GUI.IsMouseOver()) { int change = mouse.ScrollWheelValue - LastWheel; if (!(keys.IsKeyDown(Keys.LeftAlt) || keys.IsKeyDown(Keys.RightAlt))) { if (!keys.IsKeyDown(Keys.LeftControl)) { Vector3 delta = new Vector3(0, change, 0); if (GameSettings.Default.InvertZoom) { delta *= -1; } Velocity = delta * CameraZoomSpeed * dt; } else { chunks.ChunkData.SetMaxViewingLevel(chunks.ChunkData.MaxViewingLevel + (int)((float)change * 0.01f), ChunkManager.SliceMode.Y); } } } LastWheel = mouse.ScrollWheelValue; if (!CollidesWithChunks(PlayState.ChunkManager, Target + Velocity, false)) { Target += Velocity; PushVelocity = Vector3.Zero; } else { PushVelocity += Vector3.Up * 0.05f; Target += PushVelocity; } Velocity *= 0.8f; UpdateBasisVectors(); }
public void Update(DwarfGame game, DwarfTime time) { GamblingState.Update(time); TaskManager.Update(Faction.Minions); CurrentTool.Update(game, time); Faction.RoomBuilder.Update(); UpdateOrphanedTasks(); if (!World.Paused) { } else { CameraController.LastWheel = Mouse.GetState().ScrollWheelValue; } UpdateInput(game, time); if (Faction.Minions.Any(m => m.IsDead && m.TriggersMourning)) { foreach (CreatureAI minion in Faction.Minions) { minion.Creature.AddThought(Thought.ThoughtType.FriendDied); if (!minion.IsDead) { continue; } World.MakeAnnouncement( String.Format("{0} ({1}) died!", minion.Stats.FullName, minion.Stats.CurrentClass.Name)); SoundManager.PlaySound(ContentPaths.Audio.Oscar.sfx_gui_negative_generic); World.Tutorial("death"); } } Faction.Minions.RemoveAll(m => m.IsDead); UpdateRooms(); HandlePosessedDwarf(); if (sliceDownheld) { sliceDownTimer.Update(time); if (sliceDownTimer.HasTriggered) { SetMaxViewingLevel(MaxViewingLevel - 1); sliceDownTimer.Reset(sliceDownTimer.TargetTimeSeconds * 0.6f); } } else if (sliceUpheld) { sliceUpTimer.Update(time); if (sliceUpTimer.HasTriggered) { SetMaxViewingLevel(MaxViewingLevel + 1); sliceUpTimer.Reset(sliceUpTimer.TargetTimeSeconds * 0.6f); } } // Make sure that the faction's money is identical to the money in treasuries. Faction.Economy.CurrentMoney = Faction.Treasurys.Sum(treasury => treasury.Money); checkFoodTimer.Update(time); if (checkFoodTimer.HasTriggered) { var food = Faction.CountResourcesWithTag(Resource.ResourceTags.Edible); if (food == 0) { Faction.World.MakeAnnouncement("We're out of food!", null, () => { return(Faction.CountResourcesWithTag(Resource.ResourceTags.Edible) == 0); }); } } foreach (var minion in Faction.Minions) { if (minion == null) { throw new InvalidProgramException("Null minion?"); } if (minion.Status == null) { throw new InvalidProgramException("Minion has null status?"); } if (minion.Status.IsAsleep) { continue; } if (minion.CurrentTask == null) { continue; } if (minion.Stats.IsTaskAllowed(Task.TaskCategory.Dig)) { minion.Movement.SetCan(MoveType.Dig, GameSettings.Default.AllowAutoDigging); } minion.ResetPositionConstraint(); } foreach (var applicant in NewArrivals) { if (World.Time.CurrentDate >= applicant.ArrivalTime) { Faction.HireImmediately(applicant.Applicant); } } NewArrivals.RemoveAll(a => World.Time.CurrentDate >= a.ArrivalTime); }
public override IEnumerable <Status> Run() { Creature.IsCloaked = false; if (CurrentAttack == null) { yield return(Status.Fail); yield break; } Timeout.Reset(); FailTimer.Reset(); if (Target == null && TargetName != null) { Target = Agent.Blackboard.GetData <GameComponent>(TargetName); if (Target == null) { yield return(Status.Fail); yield break; } } if (Agent.Faction.Race.IsIntelligent) { var targetInventory = Target.GetRoot().GetComponent <Inventory>(); if (targetInventory != null) { targetInventory.SetLastAttacker(Agent); } } CharacterMode defaultCharachterMode = Creature.AI.Movement.CanFly ? CharacterMode.Flying : CharacterMode.Walking; bool avoided = false; while (true) { Timeout.Update(DwarfTime.LastTime); FailTimer.Update(DwarfTime.LastTime); if (FailTimer.HasTriggered) { Creature.Physics.Orientation = Physics.OrientMode.RotateY; Creature.OverrideCharacterMode = false; Creature.CurrentCharacterMode = defaultCharachterMode; yield return(Status.Fail); yield break; } if (Timeout.HasTriggered) { if (Training) { Agent.AddXP(1); Creature.Physics.Orientation = Physics.OrientMode.RotateY; Creature.OverrideCharacterMode = false; Creature.CurrentCharacterMode = defaultCharachterMode; yield return(Status.Success); yield break; } else { Creature.Physics.Orientation = Physics.OrientMode.RotateY; Creature.OverrideCharacterMode = false; Creature.CurrentCharacterMode = defaultCharachterMode; yield return(Status.Fail); yield break; } } if (Target == null || Target.IsDead) { Creature.CurrentCharacterMode = defaultCharachterMode; Creature.Physics.Orientation = Physics.OrientMode.RotateY; yield return(Status.Success); } // Find the location of the melee target Vector3 targetPos = new Vector3(Target.GlobalTransform.Translation.X, Target.GetBoundingBox().Min.Y, Target.GlobalTransform.Translation.Z); Vector2 diff = new Vector2(targetPos.X, targetPos.Z) - new Vector2(Creature.AI.Position.X, Creature.AI.Position.Z); Creature.Physics.Face(targetPos); bool intersectsbounds = Creature.Physics.BoundingBox.Intersects(Target.BoundingBox); float dist = diff.Length(); // If we are really far from the target, something must have gone wrong. if (DefensiveStructure == null && !intersectsbounds && dist > CurrentAttack.Weapon.Range * 4) { Creature.Physics.Orientation = Physics.OrientMode.RotateY; Creature.OverrideCharacterMode = false; Creature.CurrentCharacterMode = defaultCharachterMode; yield return(Status.Fail); yield break; } if (DefensiveStructure != null) { if (Creature.Hp < LastHp) { float damage = LastHp - Creature.Hp; Creature.Heal(Math.Min(5.0f, damage)); var health = DefensiveStructure.GetRoot().GetComponent <Health>(); if (health != null) { health.Damage(damage); Drawer2D.DrawLoadBar(health.World.Renderer.Camera, DefensiveStructure.Position, Color.White, Color.Black, 32, 1, health.Hp / health.MaxHealth, 0.1f); } LastHp = Creature.Hp; } if (dist > CurrentAttack.Weapon.Range) { float sqrDist = dist * dist; foreach (var threat in Creature.AI.Faction.Threats) { float threatDist = (threat.AI.Position - Creature.AI.Position).LengthSquared(); if (threatDist < sqrDist) { sqrDist = threatDist; Target = threat.Physics; break; } } dist = (float)Math.Sqrt(sqrDist); } if (dist > CurrentAttack.Weapon.Range * 4) { yield return(Status.Fail); yield break; } if (DefensiveStructure.IsDead) { DefensiveStructure = null; } } LastHp = Creature.Hp; // If we're out of attack range, run toward the target. if (DefensiveStructure == null && !Creature.AI.Movement.IsSessile && !intersectsbounds && diff.Length() > CurrentAttack.Weapon.Range) { Creature.CurrentCharacterMode = defaultCharachterMode; var greedyPath = new GreedyPathAct(Creature.AI, Target, CurrentAttack.Weapon.Range * 0.75f) { PathLength = 5 }; greedyPath.Initialize(); foreach (Act.Status stat in greedyPath.Run()) { if (stat == Act.Status.Running) { yield return(Status.Running); } else { break; } } } // If we have a ranged weapon, try avoiding the target for a few seconds to get within range. else if (DefensiveStructure == null && !Creature.AI.Movement.IsSessile && !intersectsbounds && !avoided && (CurrentAttack.Weapon.Mode == Weapon.AttackMode.Ranged && dist < CurrentAttack.Weapon.Range * 0.15f)) { FailTimer.Reset(); foreach (Act.Status stat in AvoidTarget(CurrentAttack.Weapon.Range, 3.0f)) { yield return(Status.Running); } avoided = true; } // Else, stop and attack else if ((DefensiveStructure == null && dist < CurrentAttack.Weapon.Range) || (DefensiveStructure != null && dist < CurrentAttack.Weapon.Range * 2.0)) { if (CurrentAttack.Weapon.Mode == Weapon.AttackMode.Ranged && VoxelHelpers.DoesRayHitSolidVoxel(Creature.World.ChunkManager, Creature.AI.Position, Target.Position)) { yield return(Status.Fail); yield break; } FailTimer.Reset(); avoided = false; Creature.Physics.Orientation = Physics.OrientMode.Fixed; Creature.Physics.Velocity = new Vector3(Creature.Physics.Velocity.X * 0.9f, Creature.Physics.Velocity.Y, Creature.Physics.Velocity.Z * 0.9f); CurrentAttack.RechargeTimer.Reset(CurrentAttack.Weapon.RechargeRate); Creature.Sprite.ResetAnimations(Creature.Stats.CurrentClass.AttackMode); Creature.Sprite.PlayAnimations(Creature.Stats.CurrentClass.AttackMode); Creature.CurrentCharacterMode = Creature.Stats.CurrentClass.AttackMode; Creature.OverrideCharacterMode = true; Timer timeout = new Timer(10.0f, true); while (!CurrentAttack.Perform(Creature, Target, DwarfTime.LastTime, Creature.Stats.Strength + Creature.Stats.Size, Creature.AI.Position, Creature.Faction.ParentFaction.Name)) { timeout.Update(DwarfTime.LastTime); if (timeout.HasTriggered) { break; } Creature.Physics.Velocity = new Vector3(Creature.Physics.Velocity.X * 0.9f, Creature.Physics.Velocity.Y, Creature.Physics.Velocity.Z * 0.9f); if (Creature.AI.Movement.CanFly) { Creature.Physics.ApplyForce(-Creature.Physics.Gravity * 0.1f, DwarfTime.Dt); } yield return(Status.Running); } timeout.Reset(); while (!Agent.Creature.Sprite.AnimPlayer.IsDone()) { timeout.Update(DwarfTime.LastTime); if (timeout.HasTriggered) { break; } if (Creature.AI.Movement.CanFly) { Creature.Physics.ApplyForce(-Creature.Physics.Gravity * 0.1f, DwarfTime.Dt); } yield return(Status.Running); } var targetCreature = Target.GetRoot().GetComponent <CreatureAI>(); if (targetCreature != null && Creature.AI.FightOrFlight(targetCreature) == CreatureAI.FightOrFlightResponse.Flee) { yield return(Act.Status.Fail); yield break; } Creature.CurrentCharacterMode = CharacterMode.Attacking; Vector3 dogfightTarget = Vector3.Zero; while (!CurrentAttack.RechargeTimer.HasTriggered && !Target.IsDead) { CurrentAttack.RechargeTimer.Update(DwarfTime.LastTime); if (CurrentAttack.Weapon.Mode == Weapon.AttackMode.Dogfight) { dogfightTarget += MathFunctions.RandVector3Cube() * 0.1f; Vector3 output = Creature.Controller.GetOutput(DwarfTime.Dt, dogfightTarget + Target.Position, Creature.Physics.GlobalTransform.Translation) * 0.9f; Creature.Physics.ApplyForce(output - Creature.Physics.Gravity, DwarfTime.Dt); } else { Creature.Physics.Velocity = Vector3.Zero; if (Creature.AI.Movement.CanFly) { Creature.Physics.ApplyForce(-Creature.Physics.Gravity, DwarfTime.Dt); } } yield return(Status.Running); } Creature.CurrentCharacterMode = defaultCharachterMode; Creature.Physics.Orientation = Physics.OrientMode.RotateY; if (Target.IsDead) { Target = null; Agent.AddXP(10); Creature.Physics.Face(Creature.Physics.Velocity + Creature.Physics.GlobalTransform.Translation); Creature.Stats.NumThingsKilled++; Creature.AddThought("I killed somehing!", new TimeSpan(0, 8, 0, 0), 1.0f); Creature.Physics.Orientation = Physics.OrientMode.RotateY; Creature.OverrideCharacterMode = false; Creature.CurrentCharacterMode = defaultCharachterMode; yield return(Status.Success); break; } } yield return(Status.Running); } }
public override IEnumerable <Status> Run() { Creature.IsCloaked = false; if (CurrentAttack == null) { yield return(Status.Fail); yield break; } Timeout.Reset(); FailTimer.Reset(); if (Target == null && TargetName != null) { Target = Agent.Blackboard.GetData <Body>(TargetName); if (Target == null) { yield return(Status.Fail); yield break; } } if (Agent.Faction.Race.IsIntelligent) { var targetInventory = Target.GetRoot().GetComponent <Inventory>(); if (targetInventory != null) { targetInventory.SetLastAttacker(Agent); } } CharacterMode defaultCharachterMode = Creature.AI.Movement.CanFly ? CharacterMode.Flying : CharacterMode.Walking; bool avoided = false; while (true) { Timeout.Update(DwarfTime.LastTime); FailTimer.Update(DwarfTime.LastTime); if (FailTimer.HasTriggered) { Creature.Physics.Orientation = Physics.OrientMode.RotateY; Creature.OverrideCharacterMode = false; Creature.CurrentCharacterMode = defaultCharachterMode; yield return(Status.Fail); yield break; } if (Timeout.HasTriggered) { if (Training) { Agent.AddXP(1); Creature.Physics.Orientation = Physics.OrientMode.RotateY; Creature.OverrideCharacterMode = false; Creature.CurrentCharacterMode = defaultCharachterMode; yield return(Status.Success); yield break; } else { Creature.Physics.Orientation = Physics.OrientMode.RotateY; Creature.OverrideCharacterMode = false; Creature.CurrentCharacterMode = defaultCharachterMode; yield return(Status.Fail); yield break; } } if (Target == null || Target.IsDead) { Creature.CurrentCharacterMode = defaultCharachterMode; Creature.Physics.Orientation = Physics.OrientMode.RotateY; yield return(Status.Success); } // Find the location of the melee target Vector3 targetPos = new Vector3(Target.GlobalTransform.Translation.X, Target.GetBoundingBox().Min.Y, Target.GlobalTransform.Translation.Z); Vector2 diff = new Vector2(targetPos.X, targetPos.Z) - new Vector2(Creature.AI.Position.X, Creature.AI.Position.Z); Creature.Physics.Face(targetPos); bool intersectsbounds = Creature.Physics.BoundingBox.Intersects(Target.BoundingBox); // If we are really far from the target, something must have gone wrong. if (!intersectsbounds && diff.Length() > CurrentAttack.Range * 4) { Creature.Physics.Orientation = Physics.OrientMode.RotateY; Creature.OverrideCharacterMode = false; Creature.CurrentCharacterMode = defaultCharachterMode; yield return(Status.Fail); yield break; } // If we're out of attack range, run toward the target. if (!Creature.AI.Movement.IsSessile && !intersectsbounds && diff.Length() > CurrentAttack.Range) { Creature.CurrentCharacterMode = defaultCharachterMode; /* * Vector3 output = Creature.Controller.GetOutput(DwarfTime.Dt, targetPos, Creature.Physics.GlobalTransform.Translation) * 0.9f; * output.Y = 0.0f; * if (Creature.AI.Movement.CanFly) * { * Creature.Physics.ApplyForce(-Creature.Physics.Gravity, DwarfTime.Dt); * } * if (Creature.AI.Movement.IsSessile) * { * output *= 0.0f; * } * Creature.Physics.ApplyForce(output, DwarfTime.Dt); * Creature.Physics.Orientation = Physics.OrientMode.RotateY; */ GreedyPathAct greedyPath = new GreedyPathAct(Creature.AI, Target, CurrentAttack.Range * 0.75f) { PathLength = 5 }; greedyPath.Initialize(); foreach (Act.Status stat in greedyPath.Run()) { if (stat == Act.Status.Running) { yield return(Status.Running); } else { break; } } } // If we have a ranged weapon, try avoiding the target for a few seconds to get within range. else if (!Creature.AI.Movement.IsSessile && !intersectsbounds && !avoided && (CurrentAttack.Mode == Attack.AttackMode.Ranged && diff.Length() < CurrentAttack.Range * 0.15f)) { FailTimer.Reset(); foreach (Act.Status stat in AvoidTarget(CurrentAttack.Range, 3.0f)) { yield return(Status.Running); } avoided = true; } // Else, stop and attack else { if (CurrentAttack.Mode == Attack.AttackMode.Ranged && VoxelHelpers.DoesRayHitSolidVoxel(Creature.World.ChunkManager.ChunkData, Creature.AI.Position, Target.Position)) { yield return(Status.Fail); yield break; } FailTimer.Reset(); avoided = false; Creature.Physics.Orientation = Physics.OrientMode.Fixed; Creature.Physics.Velocity = new Vector3(Creature.Physics.Velocity.X * 0.9f, Creature.Physics.Velocity.Y, Creature.Physics.Velocity.Z * 0.9f); CurrentAttack.RechargeTimer.Reset(CurrentAttack.RechargeRate); Creature.Sprite.ResetAnimations(Creature.AttackMode); Creature.Sprite.PlayAnimations(Creature.AttackMode); Creature.CurrentCharacterMode = Creature.AttackMode; Creature.OverrideCharacterMode = true; Timer timeout = new Timer(10.0f, true); while (!CurrentAttack.Perform(Creature, Target, DwarfTime.LastTime, Creature.Stats.BuffedStr + Creature.Stats.BuffedSiz, Creature.AI.Position, Creature.Faction.Name)) { timeout.Update(DwarfTime.LastTime); if (timeout.HasTriggered) { break; } Creature.Physics.Velocity = new Vector3(Creature.Physics.Velocity.X * 0.9f, Creature.Physics.Velocity.Y, Creature.Physics.Velocity.Z * 0.9f); if (Creature.AI.Movement.CanFly) { Creature.Physics.ApplyForce(-Creature.Physics.Gravity * 0.1f, DwarfTime.Dt); } yield return(Status.Running); } timeout.Reset(); while (!Agent.Creature.Sprite.AnimPlayer.IsDone()) { timeout.Update(DwarfTime.LastTime); if (timeout.HasTriggered) { break; } if (Creature.AI.Movement.CanFly) { Creature.Physics.ApplyForce(-Creature.Physics.Gravity * 0.1f, DwarfTime.Dt); } yield return(Status.Running); } var targetCreature = Target.GetRoot().GetComponent <CreatureAI>(); if (targetCreature != null && !Creature.AI.FightOrFlight(targetCreature)) { yield return(Act.Status.Fail); yield break; } Creature.CurrentCharacterMode = CharacterMode.Attacking; Vector3 dogfightTarget = Vector3.Zero; while (!CurrentAttack.RechargeTimer.HasTriggered && !Target.IsDead) { CurrentAttack.RechargeTimer.Update(DwarfTime.LastTime); if (CurrentAttack.Mode == Attack.AttackMode.Dogfight) { dogfightTarget += MathFunctions.RandVector3Cube() * 0.1f; Vector3 output = Creature.Controller.GetOutput(DwarfTime.Dt, dogfightTarget + Target.Position, Creature.Physics.GlobalTransform.Translation) * 0.9f; Creature.Physics.ApplyForce(output - Creature.Physics.Gravity, DwarfTime.Dt); } else { Creature.Physics.Velocity = Vector3.Zero; if (Creature.AI.Movement.CanFly) { Creature.Physics.ApplyForce(-Creature.Physics.Gravity, DwarfTime.Dt); } } yield return(Status.Running); } Creature.CurrentCharacterMode = defaultCharachterMode; Creature.Physics.Orientation = Physics.OrientMode.RotateY; if (Target.IsDead) { Target = null; Agent.AddXP(10); Creature.Physics.Face(Creature.Physics.Velocity + Creature.Physics.GlobalTransform.Translation); Creature.Stats.NumThingsKilled++; Creature.AddThought(Thought.ThoughtType.KilledThing); Creature.Physics.Orientation = Physics.OrientMode.RotateY; Creature.OverrideCharacterMode = false; Creature.CurrentCharacterMode = defaultCharachterMode; yield return(Status.Success); break; } } yield return(Status.Running); } }
public void Update(DwarfGame game, DwarfTime time) { GamblingState.Update(time); TaskManager.Update(Faction.Minions); CurrentTool.Update(game, time); Faction.RoomBuilder.Update(); UpdateOrphanedTasks(); if (!World.Paused) { } else { CameraController.LastWheel = Mouse.GetState().ScrollWheelValue; } UpdateInput(game, time); if (Faction.Minions.Any(m => m.IsDead && m.TriggersMourning)) { foreach (CreatureAI minion in Faction.Minions) { minion.Creature.AddThought(Thought.ThoughtType.FriendDied); if (!minion.IsDead) { continue; } World.MakeAnnouncement( String.Format("{0} ({1}) died!", minion.Stats.FullName, minion.Stats.CurrentClass.Name)); SoundManager.PlaySound(ContentPaths.Audio.Oscar.sfx_gui_negative_generic); World.Tutorial("death"); } } Faction.Minions.RemoveAll(m => m.IsDead); UpdateRooms(); HandlePosessedDwarf(); if (sliceDownheld) { sliceDownTimer.Update(time); if (sliceDownTimer.HasTriggered) { SetMaxViewingLevel(MaxViewingLevel - 1); sliceDownTimer.Reset(sliceDownTimer.TargetTimeSeconds * 0.6f); } } else if (sliceUpheld) { sliceUpTimer.Update(time); if (sliceUpTimer.HasTriggered) { SetMaxViewingLevel(MaxViewingLevel + 1); sliceUpTimer.Reset(sliceUpTimer.TargetTimeSeconds * 0.6f); } } // Make sure that the faction's money is identical to the money in treasuries. Faction.Economy.CurrentMoney = Faction.Treasurys.Sum(treasury => treasury.Money); checkFoodTimer.Update(time); if (checkFoodTimer.HasTriggered) { var food = Faction.CountResourcesWithTag(Resource.ResourceTags.Edible); if (food == 0) { Faction.World.MakeAnnouncement("We're out of food!", null, () => { return(Faction.CountResourcesWithTag(Resource.ResourceTags.Edible) == 0); }); } } }
override public void Update(DwarfTime gameTime, ChunkManager chunks, Camera camera) { //base.Update(gameTime, chunks, camera); if (!Active) { return; } Creature.NoiseMaker.BasePitch = Stats.VoicePitch; AutoGatherTimer.Update(gameTime); IdleTimer.Update(gameTime); SpeakTimer.Update(gameTime); if (AutoGatherTimer.HasTriggered) { foreach (var body in World.EnumerateIntersectingObjects(Physics.BoundingBox.Expand(3.0f)).OfType <ResourceEntity>().Where(r => r.Active && r.AnimationQueue.Count == 0)) { Creature.GatherImmediately(body, Inventory.RestockType.RestockResource); } OrderEnemyAttack(); } DeleteBadTasks(); PreEmptTasks(); if (CurrentTask != null) { Stats.Boredom.CurrentValue -= (float)(CurrentTask.BoredomIncrease * gameTime.ElapsedGameTime.TotalSeconds); if (Stats.Boredom.IsCritical()) { Creature.AddThought("I have been overworked recently.", new TimeSpan(0, 4, 0, 0), -2.0f); } Stats.Energy.CurrentValue += (float)(CurrentTask.EnergyDecrease * gameTime.ElapsedGameTime.TotalSeconds); } // Heal thyself if (Stats.Health.IsDissatisfied()) { Task toReturn = new GetHealedTask(); if (!Tasks.Contains(toReturn) && CurrentTask != toReturn) { AssignTask(toReturn); } } // Try to go to sleep if we are low on energy and it is night time. if (Stats.Energy.IsCritical()) { Task toReturn = new SatisfyTirednessTask(); if (!Tasks.Contains(toReturn) && CurrentTask != toReturn) { AssignTask(toReturn); } } // Try to find food if we are hungry. if (Stats.Hunger.IsDissatisfied() && World.CountResourcesWithTag(Resource.ResourceTags.Edible) > 0) { Task toReturn = new SatisfyHungerTask() { MustPay = true }; if (Stats.Hunger.IsCritical()) { toReturn.Priority = TaskPriority.Urgent; } if (!Tasks.Contains(toReturn) && CurrentTask != toReturn) { AssignTask(toReturn); } } if (Stats.Boredom.IsDissatisfied()) { if (!Tasks.Any(task => task.BoredomIncrease < 0)) { Task toReturn = SatisfyBoredom(); if (toReturn != null && !Tasks.Contains(toReturn) && CurrentTask != toReturn) { AssignTask(toReturn); } } } restockTimer.Update(DwarfTime.LastTime); if (restockTimer.HasTriggered && Creature.Inventory.Resources.Count > 10) { Creature.RestockAllImmediately(); } if (CurrentTask == null) // We need something to do. { if (Stats.Happiness.IsSatisfied()) // We're happy, so make sure we aren't on strike. { Stats.IsOnStrike = false; UnhappinessTime = 0.0f; } if (Stats.IsOnStrike) // We're on strike, so track how long this job has sucked. { UnhappinessTime += gameTime.ElapsedGameTime.TotalMinutes; if (UnhappinessTime > GameSettings.Default.HoursUnhappyBeforeQuitting) // If we've been unhappy long enough, quit. { var thoughts = GetRoot().GetComponent <DwarfThoughts>(); Manager.World.MakeAnnouncement( // Can't use a popup because the dwarf will soon not exist. Also - this is a serious event! Message: String.Format("{0} has quit!{1}", Stats.FullName, (thoughts == null ? "" : (" The last straw: " + thoughts.Thoughts.Last(t => t.HappinessModifier < 0.0f).Description))), ClickAction: null, logEvent: true, eventDetails: (thoughts == null ? "So sick of this place!" : String.Join("\n", thoughts.Thoughts.Where(t => t.HappinessModifier < 0.0f).Select(t => t.Description))) ); LeaveWorld(); GetRoot().GetComponent <Inventory>().Die(); GetRoot().GetComponent <SelectionCircle>().Die(); if (thoughts != null) { thoughts.Thoughts.Clear(); } Faction.Minions.Remove(this); World.PersistentData.SelectedMinions.Remove(this); return; } } else if (Stats.Happiness.IsDissatisfied()) // We aren't on strike, but we hate this place. { if (MathFunctions.Rand(0, 1) < 0.25f) // We hate it so much that we might just go on strike! This can probably be tweaked. As it stands, // dorfs go on strike almost immediately every time. { Manager.World.UserInterface.MakeWorldPopup(String.Format("{0} ({1}) refuses to work!", Stats.FullName, Stats.CurrentClass.Name), Creature.Physics, -10, 10); Manager.World.Tutorial("happiness"); SoundManager.PlaySound(ContentPaths.Audio.Oscar.sfx_gui_negative_generic, 0.25f); Stats.IsOnStrike = true; } } if (!Stats.IsOnStrike) // We aren't on strike, so find a new task. { var goal = GetEasiestTask(Tasks); if (goal == null) { goal = World.TaskManager.GetBestTask(this); } if (goal != null) { IdleTimer.Reset(IdleTimer.TargetTimeSeconds); ChangeTask(goal); } else { var newTask = ActOnIdle(); if (newTask != null) { ChangeTask(newTask); } } } else { ChangeTask(ActOnIdle()); } } else { if (CurrentAct == null) // Should be impossible to have a current task and no current act. { // Try and recover the correct act. // <blecki> I always run with a breakpoint set here... just in case. ChangeAct(CurrentTask.CreateScript(Creature)); // This is a bad situation! if (CurrentAct == null) { ChangeTask(null); } } if (CurrentAct != null) { var status = CurrentAct.Tick(); bool retried = false; if (CurrentAct != null && CurrentTask != null) { if (status == Act.Status.Fail) { LastFailedAct = CurrentAct.Name; if (!FailedTasks.Any(task => task.TaskFailure.Equals(CurrentTask))) { FailedTasks.Add(new FailedTask() { TaskFailure = CurrentTask, FailedTime = World.Time.CurrentDate }); } if (CurrentTask.ShouldRetry(Creature)) { if (!Tasks.Contains(CurrentTask)) { ReassignCurrentTask(); retried = true; } } } } if (CurrentTask != null && CurrentTask.IsComplete(World)) { ChangeTask(null); } else if (status != Act.Status.Running && !retried) { ChangeTask(null); } } } // With a small probability, the creature will drown if its under water. if (MathFunctions.RandEvent(0.01f)) { var above = VoxelHelpers.GetVoxelAbove(Physics.CurrentVoxel); var below = VoxelHelpers.GetVoxelBelow(Physics.CurrentVoxel); bool shouldDrown = (above.IsValid && (!above.IsEmpty || above.LiquidLevel > 0)); if ((Physics.IsInLiquid || (!Movement.CanSwim && (below.IsValid && (below.LiquidLevel > 5)))) && (!Movement.CanSwim || shouldDrown)) { Creature.Damage(Movement.CanSwim ? 1.0f : 30.0f, Health.DamageType.Normal); } } if (PositionConstraint.Contains(Physics.LocalPosition) == ContainmentType.Disjoint) { Physics.LocalPosition = MathFunctions.Clamp(Physics.Position, PositionConstraint); Physics.PropogateTransforms(); } }