コード例 #1
0
ファイル: BirdAI.cs プロジェクト: scorvi/dwarfcorp
        IEnumerable<Act.Status> ChirpRandomly()
        {
            Timer chirpTimer = new Timer(MathFunctions.Rand(6f, 10f), false);
            while (true)
            {
                chirpTimer.Update(DwarfTime.LastTime);
                if (chirpTimer.HasTriggered)
                {
                    Creature.NoiseMaker.MakeNoise("chirp", Creature.AI.Position, true, 0.5f);
                }
                yield return Act.Status.Running;
            }

            yield return Act.Status.Success;
        }
コード例 #2
0
        override public void Update(DwarfTime gameTime, ChunkManager chunks, Camera camera)
        {
            base.Update(gameTime, chunks, camera);

            if (!Active)
            {
                return;
            }

            SenseTimer.Update(gameTime);

            if (SenseTimer.HasTriggered)
            {
                Creatures.Clear();

                var myRoot = GetRoot();

                foreach (var body in Manager.World.EnumerateIntersectingObjects(BoundingBox, b => b.Active && !Object.ReferenceEquals(b, myRoot) && b.IsRoot()))
                {
                    var minion = body.GetComponent <Creature>();
                    if (minion == null)
                    {
                        continue;
                    }

                    float dist = (body.Position - GlobalTransform.Translation).LengthSquared();

                    if (dist > SenseRadius)
                    {
                        continue;
                    }

                    if (CheckLineOfSight && VoxelHelpers.DoesRayHitSolidVoxel(Manager.World.ChunkManager, Position, body.Position))
                    {
                        continue;
                    }

                    Creatures.Add(minion);
                }
            }

            Creatures.RemoveAll(ai => ai.IsDead);
        }
コード例 #3
0
        public override void Update(DwarfTime Time, ChunkManager Chunks, Camera Camera)
        {
            if (Active)
            {
                ParticleTimer.Update(Time);
                if (ParticleTimer.HasTriggered)
                {
                    float       t          = (float)Time.TotalGameTime.TotalSeconds * 0.5f;
                    Vector3     pos        = new Vector3((float)Math.Sin(t) * TeleportDistance, 0, (float)Math.Cos(t) * TeleportDistance) + Position;
                    VoxelHandle voxelBelow = VoxelHelpers.FindFirstVoxelBelow(new VoxelHandle(World.ChunkManager.ChunkData, GlobalVoxelCoordinate.FromVector3(pos)));

                    if (voxelBelow.IsValid)
                    {
                        World.ParticleManager.Trigger("green_flame", voxelBelow.WorldPosition + Vector3.Up * 1.5f, Color.White, 1);
                    }
                }
            }
            base.Update(Time, Chunks, Camera);
        }
コード例 #4
0
ファイル: Creature.cs プロジェクト: jeason1997/dwarfcorp
        /// <summary>
        /// Basic Act that causes the creature to wait for the specified time.
        /// Also draws a loading bar above the creature's head when relevant.
        /// </summary>
        public IEnumerable <Act.Status> HitAndWait(float f, bool loadBar, Func <Vector3> pos, string playSound = "", Func <bool> continueHitting = null)
        {
            var waitTimer = new Timer(f, true);

            CurrentCharacterMode = CharacterMode.Attacking;
            Sprite.ResetAnimations(CharacterMode.Attacking);
            Sprite.PlayAnimations(CharacterMode.Attacking);

            CurrentCharacterMode = CharacterMode.Attacking;

            while (!waitTimer.HasTriggered)
            {
                waitTimer.Update(DwarfTime.LastTime);

                if (continueHitting != null && !continueHitting())
                {
                    yield break;
                }
                Physics.Active = false;
                if (loadBar)
                {
                    Drawer2D.DrawLoadBar(Manager.World.Camera, AI.Position + Vector3.Up, Color.LightGreen, Color.Black, 64, 4,
                                         waitTimer.CurrentTimeSeconds / waitTimer.TargetTimeSeconds);
                }

                Attacks[0].PerformNoDamage(this, DwarfTime.LastTime, pos());
                Physics.Velocity = Vector3.Zero;
                Sprite.ReloopAnimations(CharacterMode.Attacking);

                if (!String.IsNullOrEmpty(playSound))
                {
                    NoiseMaker.MakeNoise(playSound, AI.Position, true);
                }

                yield return(Act.Status.Running);
            }
            Sprite.PauseAnimations(CharacterMode.Attacking);
            CurrentCharacterMode = CharacterMode.Idle;
            Physics.Active       = true;
            yield return(Act.Status.Success);

            yield break;
        }
コード例 #5
0
        public void Update(DwarfTime gameTime, ChunkManager chunks, Camera camera)
        {
            if (firstIter)
            {
                if (!Voxel.IsValid || Voxel.TypeID == 0)
                {
                    Delete();
                }
                firstIter = false;
            }

            DestroyTimer.Update(gameTime);

            if (DestroyTimer.HasTriggered)
            {
                Die();
                chunks.KillVoxel(Voxel);
            }
        }
コード例 #6
0
        public virtual void Update(DwarfTime time)
        {
            float growTime   = CurrentTime.TargetTimeSeconds * 0.5f;
            float shrinkTime = CurrentTime.TargetTimeSeconds * 0.5f;

            if (CurrentTime.CurrentTimeSeconds < growTime)
            {
                Scale = Easing.CubeInOut(CurrentTime.CurrentTimeSeconds, 0.0f, MaxScale, growTime);
            }
            else if (CurrentTime.CurrentTimeSeconds > shrinkTime)
            {
                Scale = Easing.CubeInOut(CurrentTime.CurrentTimeSeconds - shrinkTime, MaxScale, -MaxScale, CurrentTime.TargetTimeSeconds - shrinkTime);
            }

            if (!Grow)
            {
                Scale = MaxScale;
            }
            CurrentTime.Update(time);
        }
コード例 #7
0
        private void UpdateEggs(DwarfTime gameTime)
        {
            if (Stats.Species.LaysEggs)
            {
                if (EggTimer == null)
                {
                    EggTimer = new Timer(3600f + MathFunctions.Rand(-120, 120), false);
                }
                EggTimer.Update(gameTime);

                if (EggTimer.HasTriggered)
                {
                    if (World.GetSpeciesPopulation(Stats.CurrentClass) < Stats.Species.SpeciesLimit)
                    {
                        LayEgg(); // Todo: Egg rate in species
                        EggTimer = new Timer(3600f + MathFunctions.Rand(-120, 120), false);
                    }
                }
            }
        }
コード例 #8
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();
        }
コード例 #9
0
        public IEnumerable <Act.Status> SwimUp(Creature creature)
        {
            Timer timer = new Timer(10.0f, false, Timer.TimerMode.Game);

            while (!timer.HasTriggered)
            {
                timer.Update(DwarfTime.LastTime);

                creature.Physics.ApplyForce(Vector3.Up * 25, DwarfTime.Dt);

                if (!creature.Physics.IsInLiquid)
                {
                    yield return(Act.Status.Success);

                    yield break;
                }
                yield return(Act.Status.Running);
            }
            yield return(Act.Status.Fail);
        }
コード例 #10
0
ファイル: GremlinAI.cs プロジェクト: sodomon2/dwarfcorp
        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());
        }
コード例 #11
0
        private void UpdateEggs(DwarfTime gameTime)
        {
            if (Stats.Species.LaysEggs)
            {
                if (EggTimer == null)
                {
                    EggTimer = new Timer(Stats.Species.EggTime + MathFunctions.Rand(-120, 120), false);
                }

                EggTimer.Update(gameTime);

                if (EggTimer.HasTriggered)
                {
                    if (World.CanSpawnWithoutExceedingSpeciesLimit(Stats.Species))
                    {
                        LayEgg(); // Todo: Egg rate in species
                    }
                    EggTimer = new Timer(Stats.Species.EggTime + MathFunctions.Rand(-120, 120), false);
                }
            }
        }
コード例 #12
0
ファイル: Creature.cs プロジェクト: svifylabs/dwarfcorp
        public IEnumerable <Act.Status> HitAndWait(float f, bool loadBar)
        {
            Timer waitTimer = new Timer(f, true);

            CurrentCharacterMode = CharacterMode.Attacking;
            while (!waitTimer.HasTriggered)
            {
                waitTimer.Update(DwarfTime.LastTime);

                if (loadBar)
                {
                    Drawer2D.DrawLoadBar(AI.Position + Vector3.Up, Color.White, Color.Black, 100, 16, waitTimer.CurrentTimeSeconds / waitTimer.TargetTimeSeconds);
                }

                Attacks[0].PerformNoDamage(this, DwarfTime.LastTime, AI.Position);
                Physics.Velocity = Vector3.Zero;
                yield return(Act.Status.Running);
            }
            CurrentCharacterMode = CharacterMode.Idle;
            yield return(Act.Status.Success);
        }
コード例 #13
0
        // This hack exists to find orphaned tasks not assigned to any dwarf, and to then
        // put them on the task list.
        public void UpdateOrphanedTasks()
        {
            orphanedTaskRateLimiter.Update(DwarfTime.LastTime);
            if (orphanedTaskRateLimiter.HasTriggered)
            {
                List <Task> orphanedTasks = new List <Task>();

                foreach (var ent in Faction.Designations.EnumerateEntityDesignations())
                {
                    if (ent.Type == DesignationType.Attack)
                    {
                        var task = new KillEntityTask(ent.Body, KillEntityTask.KillType.Attack);
                        if (!TaskManager.HasTask(task) &&
                            !Faction.Minions.Any(minion => minion.Tasks.Contains(task)))
                        {
                            orphanedTasks.Add(task);
                        }
                    }


                    else if (ent.Type == DesignationType.Craft)
                    {
                        var task = new CraftItemTask(ent.Tag as CraftDesignation);
                        if (!TaskManager.HasTask(task) &&
                            !Faction.Minions.Any(minion => minion.Tasks.Contains(task)))
                        {
                            orphanedTasks.Add(task);
                        }
                    }

                    // TODO ... other entity task types
                }

                if (orphanedTasks.Count > 0)
                {
                    //TaskManager.AssignTasksGreedy(orphanedTasks, Faction.Minions);
                    TaskManager.AddTasks(orphanedTasks);
                }
            }
        }
コード例 #14
0
ファイル: Deer.cs プロジェクト: svifylabs/dwarfcorp
        public IEnumerable <Act.Status> GoToRandomTarget(float radius)
        {
            Vector3 randomVector = MathFunctions.RandVector3Cube() * radius;
            Vector3 target       = Physics.ClampToBounds(Position + randomVector);
            float   dist         = (target - Position).Length();
            Timer   timout       = new Timer(3.0f, false);

            while (dist > 3.0f)
            {
                timout.Update(DwarfTime.LastTime);
                if (timout.HasTriggered)
                {
                    break;
                }
                Vector3 output = Creature.Controller.GetOutput(DwarfTime.Dt, target, Position);
                output.Normalize();
                output *= 10;
                Physics.ApplyForce(new Vector3(output.X, 0.0f, output.Z), DwarfTime.Dt);
                dist = (target - Position).Length();
                yield return(Act.Status.Running);
            }
            yield return(Act.Status.Success);
        }
コード例 #15
0
        public IEnumerable <Act.Status> HealAlly()
        {
            Timer healTimer = new Timer(5.0f, false);

            while (!Ally.IsDead && Ally.Stats.Health.IsDissatisfied())
            {
                Agent.Physics.Face(Ally.Position);
                Agent.Creature.CurrentCharacterMode = CharacterMode.Sitting;
                healTimer.Update(DwarfTime.LastTime);
                if (healTimer.HasTriggered)
                {
                    int amount = MathFunctions.RandInt(1, (int)Agent.Stats.Wisdom);
                    Ally.Creature.Heal(amount);
                    IndicatorManager.DrawIndicator((amount).ToString() + " HP",
                                                   Ally.Position, 1.0f,
                                                   GameSettings.Current.Colors.GetColor("Positive", Microsoft.Xna.Framework.Color.Green));
                    Ally.Creature.DrawLifeTimer.Reset();
                }
                yield return(Act.Status.Running);
            }
            Ally.ResetPositionConstraint();
            yield return(Act.Status.Success);
        }
コード例 #16
0
ファイル: HealingTower.cs プロジェクト: johan74/dwarfcorp
        public override void Update(DwarfTime Time, ChunkManager Chunks, Camera Camera)
        {
            if (Active)
            {
                HealTimer.Update(Time);
                if (HealTimer.HasTriggered)
                {
                    var objects = World.EnumerateIntersectingObjects(new BoundingBox(-Vector3.One * HealRadius + Position, Vector3.One * HealRadius + Position), CollisionType.Dynamic);
                    foreach (var obj in objects)
                    {
                        var creature = obj.GetRoot().GetComponent <Creature>();
                        if (creature == null || creature.AI == null || creature.AI.Faction != creature.World.PlayerFaction || creature.Hp == creature.MaxHealth)
                        {
                            continue;
                        }
                        if (MathFunctions.RandEvent(0.5f))
                        {
                            creature.Heal(HealIncrease);
                            IndicatorManager.DrawIndicator((HealIncrease).ToString() + " HP",
                                                           creature.Physics.Position, 1.0f,
                                                           GameSettings.Default.Colors.GetColor("Positive", Microsoft.Xna.Framework.Color.Green));
                            creature.DrawLifeTimer.Reset();
                            World.ParticleManager.Trigger("star_particle", obj.Position, Color.Red, 10);
                            World.ParticleManager.TriggerRay("star_particle", Position, obj.Position);
                            SoundManager.PlaySound(ContentPaths.Audio.tinkle, obj.Position, true, 1.0f);
                            GetComponent <MagicalObject>().CurrentCharges--;
                            if (GetComponent <MagicalObject>().CurrentCharges == 0)
                            {
                                return;
                            }
                        }
                    }
                }
            }

            base.Update(Time, Chunks, Camera);
        }
コード例 #17
0
        public override IEnumerable <Status> Run()
        {
            Timer waitTimer = new Timer(1.0f, true);
            bool  removed   = Agent.Faction.RemoveResources(Resources, Agent.Position);

            if (!removed)
            {
                yield return(Status.Fail);
            }
            else
            {
                foreach (ResourceAmount resource in Resources)
                {
                    Agent.Creature.Inventory.Resources.AddResource(resource.CloneResource());
                }

                while (!waitTimer.HasTriggered)
                {
                    waitTimer.Update(DwarfTime.LastTime);
                    yield return(Status.Running);
                }
                yield return(Status.Success);
            }
        }
コード例 #18
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;
        }
コード例 #19
0
        public bool Begin(GraphicsDevice device)
        {
            lock (ColorBufferMutex)
            {
                if (!ValidateBuffer(device))
                {
                    return(false);
                }

                ValidateColorBuffer(device);
                switch (State)
                {
                case SelectionBufferState.Idle:
                    renderTimer.Update(DwarfTime.LastTime);
                    renderThisFrame = (renderTimer.HasTriggered || colorBuffer == null);
                    if (!renderThisFrame)
                    {
                        return(false);
                    }
                    ValidateBuffer(device);
                    device.SetRenderTarget(Buffer);
                    device.Clear(Color.Transparent);
                    State = SelectionBufferState.Rendering;
                    return(true);

                case SelectionBufferState.Rendering:
                    ValidateColorBuffer(device);
                    Buffer.GetData(colorBuffer);
                    State = SelectionBufferState.Idle;
                    return(false);

                default:
                    return(false);
                }
            }
        }
コード例 #20
0
ファイル: PlanAct.cs プロジェクト: sodomon2/dwarfcorp
        public override IEnumerable <Status> Run()
        {
            while (true)
            {
                Creature.AI.Blackboard.Erase(PathName);
                Agent.Blackboard.SetData <bool>("NoPath", false);
                PlanAct planAct = new PlanAct(Creature.AI, PathName, VoxelName, PlanType)
                {
                    Radius = Radius, MaxTimeouts = MaxTimeouts
                };
                planAct.Initialize();

                bool planSucceeded = false;
                while (true)
                {
                    Act.Status planStatus = planAct.Tick();

                    if (planStatus == Status.Fail)
                    {
                        yield return(Act.Status.Running);

                        break;
                    }

                    else if (planStatus == Status.Running)
                    {
                        yield return(Act.Status.Running);
                    }

                    else if (planStatus == Status.Success)
                    {
                        planSucceeded = true;
                        break;
                    }
                    yield return(Act.Status.Running);
                }

                if (!planSucceeded && planAct.LastResult == AStarPlanner.PlanResultCode.MaxExpansionsReached)
                {
                    yield return(Act.Status.Running);

                    Creature.CurrentCharacterMode = CharacterMode.Idle;
                    Creature.Physics.Velocity     = Vector3.Zero;
                    Timer planTimeout = new Timer(MathFunctions.Rand(30.0f, 120.0f), false, Timer.TimerMode.Real);
                    List <VoxelHandle> exploredVoxels = new List <VoxelHandle>();
                    Color debugColor = new Color(MathFunctions.RandVector3Cube() + Vector3.One * 0.5f);
                    float debugScale = MathFunctions.Rand() * 0.5f + 0.5f;
                    while (!planTimeout.HasTriggered)
                    {
                        // In this case, try to follow a greedy path toward the entity instead of just failing.
                        var greedyPath = planAct.ComputeGreedyFallback(20, exploredVoxels);
                        var goal       = planAct.GetGoal();
                        Creature.AI.Blackboard.SetData("GreedyPath", greedyPath);
                        var greedyPathFollow = new FollowPathAct(Creature.AI, "GreedyPath")
                        {
                            //BlendEnd = true,
                            //BlendStart = false
                        };
                        greedyPathFollow.Initialize();

                        foreach (var currStatus in greedyPathFollow.Run())
                        {
                            if (Debugger.Switches.DrawPaths)
                            {
                                foreach (var voxel in exploredVoxels)
                                {
                                    Drawer3D.DrawBox(voxel.GetBoundingBox().Expand(-debugScale), debugColor, 0.05f, false);
                                }
                            }
                            if (!exploredVoxels.Contains(Agent.Physics.CurrentVoxel))
                            {
                                exploredVoxels.Add(Agent.Physics.CurrentVoxel);
                            }
                            if (Debugger.Switches.DrawPaths)
                            {
                                Drawer3D.DrawLine(Agent.Position, goal.GetVoxel().WorldPosition, debugColor, 0.1f);
                            }
                            if (goal.IsInGoalRegion(Agent.Physics.CurrentVoxel))
                            {
                                yield return(Act.Status.Success);

                                yield break;
                            }
                            yield return(Act.Status.Running);
                        }
                        planTimeout.Update(DwarfTime.LastTime);
                    }
                    continue;
                }
                else if (!planSucceeded)
                {
                    Agent.Blackboard.SetData <bool>("NoPath", true);
                    yield return(Act.Status.Fail);

                    yield break;
                }
                yield return(Act.Status.Success);

                yield break;
            }
        }
コード例 #21
0
ファイル: PlanAct.cs プロジェクト: sodomon2/dwarfcorp
        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);
                }
            }
        }
コード例 #22
0
ファイル: Disease.cs プロジェクト: blokedlord/dwarfcorp
        public override void Update(DwarfTime time, Creature creature)
        {
            float hungerChange = creature.Stats.Hunger.CurrentValue - LastHunger;

            LastHunger = creature.Stats.Hunger.CurrentValue;

            switch (Type)
            {
            case HealType.Food:
                if (creature.Stats.IsAsleep)
                {
                    break;
                }

                FoodValueUntilHealed -= hungerChange;
                if (FoodValueUntilHealed > 0)
                {
                    DoDamage(DwarfTime.Dt, creature);
                }
                else
                {
                    EffectTime.Reset(0);
                }
                break;

            case HealType.Sleep:
                if (!creature.Stats.IsAsleep)
                {
                    DoDamage(DwarfTime.Dt, creature);
                }
                else
                {
                    EffectTime.Reset(0);
                }
                break;

            case HealType.Time:
                DoDamage(DwarfTime.Dt, creature);
                break;
            }

            if (IsContagious)
            {
                SpreadTimer.Update(time);
                if (SpreadTimer.HasTriggered && MathFunctions.RandEvent(LikelihoodOfSpread))
                {
                    foreach (CreatureAI other in creature.Faction.Minions)
                    {
                        if (other == creature.AI)
                        {
                            continue;
                        }
                        if ((other.Position - creature.AI.Position).LengthSquared() > 2)
                        {
                            continue;
                        }
                        other.Creature.Stats.AcquireDisease(DiseaseLibrary.GetDisease(Name));
                    }
                }
            }
            base.Update(time, creature);
        }
コード例 #23
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();
        }
コード例 #24
0
ファイル: OrbitCamera.cs プロジェクト: hhy5277/dwarfcorp
        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();
        }
コード例 #25
0
ファイル: CraftItemAct.cs プロジェクト: scorvi/dwarfcorp
        public IEnumerable<Status> WaitAndHit(float time)
        {
            Body objectToHit = Creature.AI.Blackboard.GetData<Body>("Anvil");
            Timer timer = new Timer(time, true);
            while (!timer.HasTriggered)
            {
                timer.Update(DwarfTime.LastTime);

                Creature.CurrentCharacterMode = Creature.CharacterMode.Attacking;
                Creature.Physics.Velocity *= 0.1f;
                Creature.Attacks[0].PerformNoDamage(DwarfTime.LastTime, Creature.AI.Position);
                Drawer2D.DrawLoadBar(Agent.Position + Vector3.Up, Color.White, Color.Black, 100, 16, timer.CurrentTimeSeconds / time);

                yield return Status.Running;
            }

            Creature.CurrentCharacterMode = Creature.CharacterMode.Idle;
            Creature.AI.AddThought(Thought.ThoughtType.Crafted);
            Creature.AI.AddXP((int)(time * 5));

            if (objectToHit != null)
            {
                objectToHit.IsReserved = false;
                objectToHit.ReservedFor = null;
            }
            yield return Status.Success;
        }
コード例 #26
0
        public override IEnumerable <Act.Status> Run()
        {
            List <ResourceAmount> foods =
                Agent.Creature.Inventory.GetResources(new Quantitiy <Resource.ResourceTags>(Resource.ResourceTags.Edible), Inventory.RestockType.Any);

            if (foods.Count == 0 && Agent.Creature.Faction == Agent.World.PlayerFaction)
            {
                yield return(Act.Status.Fail);

                yield break;
            }

            FoodBody = null;
            Timer eatTimer = new Timer(3.0f, true);

            foreach (ResourceAmount resourceAmount in foods)
            {
                if (resourceAmount.NumResources > 0)
                {
                    List <Body> bodies = Agent.Creature.Inventory.RemoveAndCreate(new ResourceAmount(resourceAmount.ResourceType, 1),
                                                                                  Inventory.RestockType.Any);
                    var resource = ResourceLibrary.GetResourceByName(resourceAmount.ResourceType);
                    Agent.Creature.NoiseMaker.MakeNoise("Chew", Agent.Creature.AI.Position);
                    if (bodies.Count == 0)
                    {
                        yield return(Act.Status.Fail);
                    }
                    else
                    {
                        FoodBody = bodies[0];


                        while (!eatTimer.HasTriggered)
                        {
                            eatTimer.Update(DwarfTime.LastTime);
                            Matrix rot = Agent.Creature.Physics.LocalTransform;
                            rot.Translation         = Vector3.Zero;
                            FoodBody.LocalTransform = Agent.Creature.Physics.LocalTransform;
                            Vector3 foodPosition = Agent.Creature.Physics.Position + Vector3.Up * 0.05f + Vector3.Transform(Vector3.Forward, rot) * 0.5f;
                            FoodBody.LocalPosition = foodPosition;
                            FoodBody.PropogateTransforms();
                            FoodBody.Active = false;
                            Agent.Creature.Physics.Velocity     = Vector3.Zero;
                            Agent.Creature.CurrentCharacterMode = CharacterMode.Sitting;
                            if (MathFunctions.RandEvent(0.05f))
                            {
                                Agent.Creature.World.ParticleManager.Trigger("crumbs", foodPosition, Color.White, 3);
                            }
                            yield return(Act.Status.Running);
                        }

                        Agent.Creature.Status.Hunger.CurrentValue += resource.FoodContent;
                        Agent.Creature.AddThought(Thought.ThoughtType.AteFood);
                        if (resource.Tags.Contains(Resource.ResourceTags.Alcohol))
                        {
                            Agent.Creature.AddThought(Thought.ThoughtType.HadAle);
                        }
                        FoodBody.GetRoot().Delete();
                        yield return(Act.Status.Success);
                    }
                    yield break;
                }
            }
        }
コード例 #27
0
        public IEnumerable <Status> WaitUntilBored()
        {
            Timer waitTimer = new Timer(SitTime, false);
            var   body      = Creature.AI.Blackboard.GetData <GameComponent>("reserved-chair");

            // Snap relative the chair's position, not their own...
            Vector3 snapPosition = body.Position + new Vector3(0, 0.4f, 0);

            if (body == null || body.IsDead)
            {
                Creature.OverrideCharacterMode = false;
                yield return(Status.Success);

                yield break;
            }

            while (true)
            {
                if (Creature.AI.Tasks.Count > 1)
                {
                    Creature.OverrideCharacterMode = false;
                    yield return(Status.Success);
                }

                if (Creature.AI.Stats.Energy.IsDissatisfied())
                {
                    Creature.OverrideCharacterMode = false;
                    yield return(Status.Success);
                }

                if (Creature.AI.Stats.Hunger.IsDissatisfied())
                {
                    Creature.OverrideCharacterMode = false;
                    yield return(Status.Success);
                }

                if (Creature.AI.Sensor.Enemies.Count > 0)
                {
                    Creature.OverrideCharacterMode = false;
                    yield return(Status.Success);
                }

                waitTimer.Update(DwarfTime.LastTime);

                if (waitTimer.HasTriggered)
                {
                    Creature.OverrideCharacterMode = false;
                    yield return(Status.Success);
                }

                ConverseFriends();


                Agent.Position = snapPosition;
                Agent.Physics.PropogateTransforms();
                Agent.Physics.IsSleeping       = true;
                Agent.Physics.Velocity         = Vector3.Zero;
                Creature.CurrentCharacterMode  = CharacterMode.Sitting;
                Creature.OverrideCharacterMode = true;
                yield return(Status.Running);
            }
        }
コード例 #28
0
        public IEnumerable<Status> WaitUntilBored()
        {
            Timer waitTimer = new Timer(SitTime, false);
            Timer eatTimer = new Timer(10.0f + MathFunctions.Rand(0, 1), false);
            Vector3 snapPosition = Agent.Position + new Vector3(0, 0.2f, 0);
            Body body = Creature.AI.Blackboard.GetData<Body>("Chair");

            if (body == null || body.IsDead)
            {
                Creature.OverrideCharacterMode = false;
                yield return Status.Success;
                yield break;
            }

            while (true)
            {
                if (Creature.AI.Tasks.Count > 1)
                {
                    Creature.OverrideCharacterMode = false;
                    yield return Status.Success;
                }

                if (Creature.AI.Status.Energy.IsUnhappy())
                {
                    Creature.OverrideCharacterMode = false;
                    yield return Status.Success;
                }

                if (Creature.AI.Status.Hunger.IsUnhappy())
                {
                    Creature.OverrideCharacterMode = false;
                    yield return Status.Success;
                }

                if (Creature.AI.Sensor.Enemies.Count > 0)
                {
                    Creature.OverrideCharacterMode = false;
                    yield return Status.Success;
                }

                waitTimer.Update(DwarfTime.LastTime);

                if (waitTimer.HasTriggered)
                {
                    Creature.OverrideCharacterMode = false;
                    yield return Status.Success;
                }

                ConverseFriends();

                eatTimer.Update(DwarfTime.LastTime);

                if(eatTimer.HasTriggered)
                    foreach (Act.Status status in EatFood())
                    {
                        if (status == Act.Status.Running)
                        {
                            Creature.OverrideCharacterMode = false;
                            yield return Act.Status.Running;
                        }
                    }

                Agent.Position = snapPosition;
                Agent.Physics.IsSleeping = true;
                Creature.CurrentCharacterMode = Creature.CharacterMode.Sitting;
                Creature.OverrideCharacterMode = true;
                yield return Status.Running;
            }
        }
コード例 #29
0
        public IEnumerable <Act.Status> GreedyFallbackBehavior(Creature agent)
        {
            var edgeGoal = new EdgeGoalRegion();

            while (true)
            {
                DieTimer.Update(DwarfTime.LastTime);
                if (DieTimer.HasTriggered)
                {
                    foreach (var status in Die(agent))
                    {
                        continue;
                    }
                    yield break;
                }
                var creatureVoxel      = agent.Physics.CurrentVoxel;
                List <MoveAction> path = new List <MoveAction>();
                var storage            = new MoveActionTempStorage();
                for (int i = 0; i < 10; i++)
                {
                    if (edgeGoal.IsInGoalRegion(creatureVoxel))
                    {
                        foreach (var status in Die(agent))
                        {
                            continue;
                        }
                        yield return(Act.Status.Success);

                        yield break;
                    }

                    var actions = agent.AI.Movement.GetMoveActions(new MoveState {
                        Voxel = creatureVoxel
                    }, new List <GameComponent>(), storage);

                    float minCost      = float.MaxValue;
                    var   minAction    = new MoveAction();
                    bool  hasMinAction = false;
                    foreach (var action in actions)
                    {
                        var vox = action.DestinationVoxel;

                        float cost = edgeGoal.Heuristic(vox) * 10 + MathFunctions.Rand(0.0f, 0.1f) + agent.AI.Movement.Cost(action.MoveType);

                        if (cost < minCost)
                        {
                            minAction    = action;
                            minCost      = cost;
                            hasMinAction = true;
                        }
                    }

                    if (hasMinAction)
                    {
                        path.Add(minAction);
                        creatureVoxel = minAction.DestinationVoxel;
                    }
                    else
                    {
                        foreach (var status in Die(agent))
                        {
                            continue;
                        }
                        yield return(Act.Status.Success);

                        yield break;
                    }
                }
                if (path.Count == 0)
                {
                    foreach (var status in Die(agent))
                    {
                        continue;
                    }
                    yield return(Act.Status.Success);

                    yield break;
                }
                agent.AI.Blackboard.SetData("GreedyPath", path);
                var pathAct = new FollowPathAct(agent.AI, "GreedyPath");
                pathAct.Initialize();

                foreach (Act.Status status in pathAct.Run())
                {
                    yield return(Act.Status.Running);
                }
                yield return(Act.Status.Running);
            }
        }
コード例 #30
0
ファイル: Deer.cs プロジェクト: scorvi/dwarfcorp
 public IEnumerable<Act.Status> GoToRandomTarget(float radius)
 {
     Vector3 randomVector = MathFunctions.RandVector3Cube()*radius;
     Vector3 target = Physics.ClampToBounds(Position + randomVector);
     float dist = (target - Position).Length();
     Timer timout = new Timer(3.0f, false);
     while (dist > 3.0f)
     {
         timout.Update(DwarfTime.LastTime);
         if (timout.HasTriggered)
         {
             break;
         }
         Vector3 output = Creature.Controller.GetOutput(DwarfTime.Dt, target, Position);
         output.Normalize();
         output *= 10;
         Physics.ApplyForce(new Vector3(output.X, 0.0f, output.Z), DwarfTime.Dt);
         dist = (target - Position).Length();
         yield return Act.Status.Running;
     }
     yield return Act.Status.Success;
 }
コード例 #31
0
        public void Update(DwarfTime gameTime, Camera camera, GraphicsDevice g)
        {
            UpdateRenderList(camera);

            if (waterUpdateTimer.Update(gameTime))
            {
                WaterUpdateEvent.Set();
            }

            UpdateRebuildList();

            generateChunksTimer.Update(gameTime);
            if (generateChunksTimer.HasTriggered)
            {
                if (ToGenerate.Count > 0)
                {
                    NeedsGenerationEvent.Set();
                    ChunkData.RecomputeNeighbors();
                }

                foreach (VoxelChunk chunk in GeneratedChunks)
                {
                    if (!ChunkData.ChunkMap.ContainsKey(chunk.ID))
                    {
                        ChunkData.AddChunk(chunk);
                        ChunkGen.GenerateVegetation(chunk, Components, Content, Graphics);
                        ChunkGen.GenerateFauna(chunk, Components, Content, Graphics, PlayState.ComponentManager.Factions);
                        List <VoxelChunk> adjacents = ChunkData.GetAdjacentChunks(chunk);
                        foreach (VoxelChunk c in adjacents)
                        {
                            c.ShouldRecalculateLighting = true;
                            c.ShouldRebuild             = true;
                        }
                        RecalculateBounds();
                    }
                }

                while (GeneratedChunks.Count > 0)
                {
                    VoxelChunk gen = null;
                    if (!GeneratedChunks.TryDequeue(out gen))
                    {
                        break;
                    }
                }
            }


            visibilityChunksTimer.Update(gameTime);
            if (visibilityChunksTimer.HasTriggered)
            {
                visibleSet.Clear();
                GetChunksIntersecting(camera.GetFrustrum(), visibleSet);
                //RemoveDistantBlocks(camera);
            }


            foreach (VoxelChunk chunk in ChunkData.ChunkMap.Values)
            {
                chunk.Update(gameTime);
            }

            Water.Splash(gameTime);
            Water.HandleTransfers(gameTime);

            HashSet <VoxelChunk> affectedChunks = new HashSet <VoxelChunk>();

            foreach (Voxel voxel in KilledVoxels)
            {
                affectedChunks.Add(voxel.Chunk);
                voxel.Chunk.NotifyDestroyed(new Point3(voxel.GridPosition));
                if (!voxel.IsInterior)
                {
                    foreach (KeyValuePair <Point3, VoxelChunk> n in voxel.Chunk.Neighbors)
                    {
                        affectedChunks.Add(n.Value);
                    }
                }
            }

            if (GameSettings.Default.FogofWar)
            {
                ChunkData.Reveal(KilledVoxels);
            }

            lock (RebuildList)
            {
                foreach (VoxelChunk affected in affectedChunks)
                {
                    affected.NotifyTotalRebuild(false);
                }
            }
            KilledVoxels.Clear();
        }
コード例 #32
0
        override public void Update(DwarfTime gameTime, ChunkManager chunks, Camera camera)
        {
            base.Update(gameTime, chunks, camera);

            if (!Active)
            {
                return;
            }

            Creature.NoiseMaker.BasePitch = Stats.VoicePitch;

            // Non-dwarves are always at full energy.
            Stats.Energy.CurrentValue = 100.0f;

            AutoGatherTimer.Update(gameTime);

            if (AutoGatherTimer.HasTriggered)
            {
                if (!String.IsNullOrEmpty(Faction.Race.BecomeWhenEvil) && MathFunctions.RandEvent(0.01f))
                {
                    Faction.Minions.Remove(this);
                    Faction = World.Factions.Factions[Faction.Race.BecomeWhenEvil];
                    Faction.AddMinion(this);
                }
                else if (!String.IsNullOrEmpty(Faction.Race.BecomeWhenNotEvil) && MathFunctions.RandEvent(0.01f))
                {
                    Faction.Minions.Remove(this);
                    Faction = World.Factions.Factions[Faction.Race.BecomeWhenNotEvil];
                    Faction.AddMinion(this);
                }

                foreach (var body in World.EnumerateIntersectingObjects(Physics.BoundingBox.Expand(3.0f)).OfType <ResourceEntity>().Where(r => r.Active && r.AnimationQueue.Count == 0))
                {
                    var resource = Library.GetResourceType(body.Resource.Type);
                    if (resource.Tags.Contains(Resource.ResourceTags.Edible))
                    {
                        if ((Faction.Race.EatsMeat && resource.Tags.Contains(Resource.ResourceTags.AnimalProduct)) ||
                            (Faction.Race.EatsPlants && !resource.Tags.Contains(Resource.ResourceTags.AnimalProduct)))
                        {
                            Creature.GatherImmediately(body);
                            AssignTask(new ActWrapperTask(new EatFoodAct(this, false)));
                        }
                    }
                }

                OrderEnemyAttack();
            }

            DeleteBadTasks();
            PreEmptTasks();
            HandleReproduction();

            // Try to find food if we are hungry. Wait - doesn't this rob the player?
            if (Stats.Hunger.IsDissatisfied() && World.CountResourcesWithTag(Resource.ResourceTags.Edible) > 0)
            {
                Task toReturn = new SatisfyHungerTask();
                if (Stats.Hunger.IsCritical())
                {
                    toReturn.Priority = TaskPriority.Urgent;
                }
                if (!Tasks.Contains(toReturn) && CurrentTask != toReturn)
                {
                    AssignTask(toReturn);
                }
            }

            if (CurrentTask == null) // We need something to do.
            {
                var goal = GetEasiestTask(Tasks);

                if (goal != null)
                {
                    ChangeTask(goal);
                }
                else
                {
                    var newTask = ActOnIdle();
                    if (newTask != null)
                    {
                        ChangeTask(newTask);
                    }
                }
            }
            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(GameSettings.Default.DrownChance))
            {
                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();
            }
        }
コード例 #33
0
ファイル: ResearchSpellAct.cs プロジェクト: scorvi/dwarfcorp
        public override IEnumerable<Act.Status> Run()
        {
            if (Spell.IsResearched)
            {
                Creature.CurrentCharacterMode = Creature.CharacterMode.Idle;
                Creature.OverrideCharacterMode = false;
                yield return Status.Success;
                yield break;
            }
            Timer starParitcle = new Timer(0.5f, false);
            float totalResearch = 0.0f;
            while (!Spell.IsResearched)
            {
                Creature.CurrentCharacterMode = Creature.CharacterMode.Attacking;
                Creature.OverrideCharacterMode = true;
                float research = Creature.Stats.BuffedInt * 0.25f * DwarfTime.Dt;
                Spell.ResearchProgress += research;
                totalResearch += research;
                Creature.Physics.Velocity *= 0;
                if ((int) totalResearch > 0)
                {
                    SoundManager.PlaySound(ContentPaths.Audio.tinkle, Creature.AI.Position, true);
                    Creature.AI.AddXP((int)(totalResearch));
                    totalResearch = 0.0f;
                }

                if (Spell.ResearchProgress >= Spell.ResearchTime)
                {
                    PlayState.AnnouncementManager.Announce("Researched " + Spell.Spell.Name, Creature.Stats.FullName + " (" + Creature.Stats.CurrentLevel.Name + ")" + " discovered the " + Spell.Spell.Name + " spell!", Agent.ZoomToMe);
                }

                starParitcle.Update(DwarfTime.LastTime);
                if(starParitcle.HasTriggered)
                    PlayState.ParticleManager.Trigger("star_particle", Creature.AI.Position, Color.White, 3);
                yield return Status.Running;
            }
            Creature.AI.AddThought(Thought.ThoughtType.Researched);
            Creature.OverrideCharacterMode = false;
            Creature.CurrentCharacterMode = Creature.CharacterMode.Idle;
            yield return Status.Success;
            yield break;
        }
コード例 #34
0
        public void Update()
        {
            if (!Enabled)
            {
                return;
            }

            var mouse    = Mouse.GetState();
            var keyboard = Keyboard.GetState();

            // Select bodies under the mouse if it is hovering.
            MouseOverTimer.Update(DwarfTime.LastTime);
            if (MouseOverTimer.HasTriggered)
            {
                SelectedEntities = Components.FindRootBodiesInsideScreenRectangle(new Rectangle(mouse.X - 2, mouse.Y - 2, 4, 4), CameraController);

                if (SelectedEntities.Count > 0)
                {
                    OnMouseOver(SelectedEntities);
                }
                else
                {
                    OnMouseOver(new List <GameComponent>());
                }
            }

            // If the left mouse button is pressed, update the selection rectangle.
            if (isLeftPressed)
            {
                if (mouse.LeftButton == ButtonState.Released)
                {
                    isLeftPressed   = false;
                    SelectionBuffer = Components.FindRootBodiesInsideScreenRectangle(SelectionRectangle, CameraController);
                    LeftReleased.Invoke();
                }
                else
                {
                    UpdateSelectionRectangle(mouse.X, mouse.Y);
                }
            }
            // Otherwise, if the mouse has first been pressed, initialize selection
            else if (mouse.LeftButton == ButtonState.Pressed)
            {
                isLeftPressed      = true;
                ClickPoint         = new Point(mouse.X, mouse.Y);
                ClickPoint3D       = World.Renderer.CursorLightPos;
                SelectionRectangle = new Rectangle(mouse.X, mouse.Y, 0, 0);
            }

            if (AllowRightClickSelection)
            {
                // If the right mouse button has been sustained-pressed, update
                // the selection rectangle.
                if (isRightPressed)
                {
                    if (mouse.RightButton == ButtonState.Released)
                    {
                        isRightPressed  = false;
                        SelectionBuffer = Components.FindRootBodiesInsideScreenRectangle(SelectionRectangle, CameraController);
                        RightReleased.Invoke();
                    }
                    else
                    {
                        UpdateSelectionRectangle(mouse.X, mouse.Y);
                    }
                }
                // Otherwise if the mouse has been first pressed, initialize selection
                else if (mouse.RightButton == ButtonState.Pressed)
                {
                    isRightPressed     = true;
                    ClickPoint         = new Point(mouse.X, mouse.Y);
                    ClickPoint3D       = World.Renderer.CursorLightPos;
                    SelectionRectangle = new Rectangle(mouse.X, mouse.Y, 0, 0);
                }
            }

            // If no mouse button has been pressed, there are no bodies currently being selected.
            if (!isLeftPressed && !isRightPressed)
            {
                CurrentBodies.Clear();
            }
        }
コード例 #35
0
ファイル: Creature.cs プロジェクト: maroussil/dwarfcorp
        public IEnumerable<Act.Status> HitAndWait(float f, bool loadBar)
        {
            Timer waitTimer = new Timer(f, true);

            CurrentCharacterMode = CharacterMode.Attacking;
            while(!waitTimer.HasTriggered)
            {
                waitTimer.Update(DwarfTime.LastTime);

                if(loadBar)
                {
                    Drawer2D.DrawLoadBar(AI.Position + Vector3.Up, Color.White, Color.Black, 100, 16, waitTimer.CurrentTimeSeconds / waitTimer.TargetTimeSeconds);
                }

                Attacks[0].PerformNoDamage(DwarfTime.LastTime, AI.Position);
                Physics.Velocity = Vector3.Zero;
                yield return Act.Status.Running;
            }
            CurrentCharacterMode = CharacterMode.Idle;
            yield return Act.Status.Success;
        }
コード例 #36
0
ファイル: StashResourcesAct.cs プロジェクト: scorvi/dwarfcorp
        public override IEnumerable<Status> Run()
        {
            Timer waitTimer = new Timer(1.0f, true);
            bool removed = Agent.Faction.RemoveResources(Resources, Agent.Position);

            if(!removed)
            {
                yield return Status.Fail;
            }
            else
            {
                foreach(ResourceAmount resource in Resources)
                {
                    Agent.Creature.Inventory.Resources.AddResource(resource.CloneResource());
                }

                while (!waitTimer.HasTriggered)
                {
                    waitTimer.Update(DwarfTime.LastTime);
                    yield return Status.Running;
                }
                yield return Status.Success;
            }
        }
コード例 #37
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();
        }