Ejemplo n.º 1
0
        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());
        }
Ejemplo n.º 2
0
        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();
        }
Ejemplo n.º 3
0
        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());
        }
Ejemplo n.º 4
0
        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;
        }
Ejemplo n.º 5
0
        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);
                }
            }
        }
Ejemplo n.º 6
0
        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();
        }
Ejemplo n.º 7
0
        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();
        }
Ejemplo n.º 8
0
        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();
        }
Ejemplo n.º 9
0
        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);
        }
Ejemplo n.º 10
0
        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);
            }
        }
Ejemplo n.º 11
0
        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);
            }
        }
Ejemplo n.º 12
0
        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); });
                }
            }
        }
Ejemplo n.º 13
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();
            }
        }