コード例 #1
0
        public List <Task> CreateTasks()
        {
            List <Task> tasks = new List <Task>();

            if (Faction.Stockpiles.Count > 0)
            {
                tasks.AddRange(Faction.GatherDesignations.Select(i => new GatherItemTask(i)).Where(g => !TaskIsAssigned(g) && IsFeasible(g, Faction.Minions)));
            }

            foreach (CreatureAI creature in Faction.Minions)
            {
                if (creature.Status.Hunger.IsUnhappy())
                {
                    Task g = new SatisfyHungerTask();

                    if (IsFeasible(g, Faction.Minions))
                    {
                        tasks.Add(g);
                    }
                }
            }

            foreach (CreatureAI creature in Faction.Minions)
            {
                if (creature.Status.Energy.IsUnhappy() && PlayState.Time.IsNight())
                {
                    Task g = new SatisfyTirednessTask();

                    if (IsFeasible(g, Faction.Minions))
                    {
                        tasks.Add(g);
                    }
                }
            }

            List <Creature> threatsToRemove = new List <Creature>();

            foreach (Creature threat in Faction.Threats)
            {
                if (threat != null && !threat.IsDead)
                {
                    Task g = new KillEntityTask(threat.Physics, KillEntityTask.KillType.Auto);

                    if (!TaskIsAssigned(g) && IsFeasible(g, Faction.Minions))
                    {
                        tasks.Add(g);
                    }
                }
                else
                {
                    threatsToRemove.Add(threat);
                }
            }

            foreach (Creature threat in threatsToRemove)
            {
                Faction.Threats.Remove(threat);
            }

            foreach (BuildOrder i in Faction.DigDesignations)
            {
                if (i == null || i.Vox == null || i.Vox.Health <= 0)
                {
                    continue;
                }

                VoxelChunk chunk = PlayState.ChunkManager.ChunkData.GetVoxelChunkAtWorldLocation(i.Vox.Position);

                if (chunk != null)
                {
                    if (chunk.IsCompletelySurrounded(i.Vox))
                    {
                        continue;
                    }
                }


                Task g = new KillVoxelTask(i.Vox);

                if (!TaskIsAssigned(g) && IsFeasible(g, Faction.Minions))
                {
                    tasks.Add(g);
                }
            }

            tasks.AddRange(Faction.GuardDesignations.Select(i => new GuardVoxelTask(i.Vox)).Where(g => !TaskIsAssigned(g) && IsFeasible(g, Faction.Minions)));

            tasks.AddRange(Faction.ChopDesignations.Select(i => new KillEntityTask(i, KillEntityTask.KillType.Chop)).Where(g => !TaskIsAssigned(g) && IsFeasible(g, Faction.Minions)));

            if (Faction.Stockpiles.Count <= 0)
            {
                return(tasks);
            }

            foreach (WallBuilder put in Faction.WallBuilder.Designations)
            {
                if (Faction.HasResources(new List <ResourceAmount>()
                {
                    new ResourceAmount(put.Type.ResourceToRelease)
                }))
                {
                    Task g = (new BuildVoxelTask(put.Vox, put.Type));

                    if (!TaskIsAssigned(g) && IsFeasible(g, Faction.Minions))
                    {
                        tasks.Add(g);
                    }
                }
            }

            return(tasks);
        }
コード例 #2
0
ファイル: TaskManager.cs プロジェクト: scorvi/dwarfcorp
        public List<Task> CreateTasks()
        {
            List<Task> tasks = new List<Task>();

            if(Faction.Stockpiles.Count > 0)
            {
                tasks.AddRange(Faction.GatherDesignations.Select(i => new GatherItemTask(i)).Where(g => !TaskIsAssigned(g) && IsFeasible(g, Faction.Minions)));
            }

            foreach(CreatureAI creature in Faction.Minions)
            {
                if(creature.Status.Hunger.IsUnhappy())
                {
                    Task g = new SatisfyHungerTask();

                    if(IsFeasible(g, Faction.Minions))
                    {
                        tasks.Add(g);
                    }

                }
            }

            foreach (CreatureAI creature in Faction.Minions)
            {
                if (creature.Status.Energy.IsUnhappy() && PlayState.Time.IsNight())
                {
                    Task g = new SatisfyTirednessTask();

                    if (IsFeasible(g, Faction.Minions))
                    {
                        tasks.Add(g);
                    }

                }
            }

            List<Creature> threatsToRemove = new List<Creature>();
            foreach(Creature threat in Faction.Threats)
            {
                if(threat != null && !threat.IsDead)
                {
                    Task g = new KillEntityTask(threat.Physics, KillEntityTask.KillType.Auto);

                    if (!TaskIsAssigned(g) && IsFeasible(g, Faction.Minions))
                    {
                        tasks.Add(g);
                    }
                }
                else
                {
                    threatsToRemove.Add(threat);
                }
            }

            foreach (Creature threat in threatsToRemove)
            {
                Faction.Threats.Remove(threat);
            }

            foreach(BuildOrder i in Faction.DigDesignations)
            {
                if (i == null || i.Vox == null || i.Vox.Health <= 0)
                {
                    continue;
                }

                VoxelChunk chunk = PlayState.ChunkManager.ChunkData.GetVoxelChunkAtWorldLocation(i.Vox.Position);

                if(chunk != null)
                {
                    if(chunk.IsCompletelySurrounded(i.Vox))
                    {
                        continue;
                    }
                }

                Task g = new KillVoxelTask(i.Vox);

                if(!TaskIsAssigned(g) && IsFeasible(g, Faction.Minions))
                {
                    tasks.Add(g);
                }
            }

            tasks.AddRange(Faction.GuardDesignations.Select(i => new GuardVoxelTask(i.Vox)).Where(g => !TaskIsAssigned(g) && IsFeasible(g, Faction.Minions)));

            tasks.AddRange(Faction.ChopDesignations.Select(i => new KillEntityTask(i, KillEntityTask.KillType.Chop)).Where(g => !TaskIsAssigned(g) && IsFeasible(g, Faction.Minions)));

            if(Faction.Stockpiles.Count <= 0)
            {
                return tasks;
            }

            foreach(WallBuilder put in Faction.WallBuilder.Designations)
            {
                if(Faction.HasResources(new List<ResourceAmount>()
                {
                    new ResourceAmount(put.Type.ResourceToRelease)
                }))
                {

                    Task g = (new BuildVoxelTask(put.Vox, put.Type));

                    if(!TaskIsAssigned(g) && IsFeasible(g, Faction.Minions))
                    {
                        tasks.Add(g);
                    }
                }
            }

            foreach(ShipOrder ship in Faction.ShipDesignations)
            {
                List<Body> componentsToShip = new List<Body>();
                int remaining = ship.GetRemainingNumResources();

                if(remaining == 0)
                {
                    continue;
                }

                foreach(Stockpile s in Faction.Stockpiles)
                {
                    for(int i = componentsToShip.Count; i < remaining; i++)
                    {
                        // TODO: Reimplement
                        /*
                        Body r = s.FindItemWithTag(ship.Resource.ResourceType.ResourceName, componentsToShip);

                        if(r != null)
                        {
                            componentsToShip.Add(r);
                        }
                         */
                    }
                }

                foreach(Body loc in componentsToShip)
                {
                    // TODO: Reimplement
                    /*
                    if(ship.Port.ContainsItem(loc))
                    {
                        continue;
                    }
                     */

                    Task g = new PutItemInZoneTask(Item.FindItem(loc), ship.Port);

                    if(TaskIsAssigned(g) || !IsFeasible(g, Faction.Minions))
                    {
                        continue;
                    }

                    ship.Assignments.Add(g);
                    tasks.Add(g);
                }
            }

            return tasks;
        }
コード例 #3
0
ファイル: TaskManager.cs プロジェクト: chrisapril/dwarfcorp
        public List <Task> CreateTasks()
        {
            List <Task> tasks = new List <Task>();

            if (Faction.Stockpiles.Count > 0)
            {
                tasks.AddRange(Faction.GatherDesignations.Select(i => new GatherItemTask(i)).Where(g => !TaskIsAssigned(g) && IsFeasible(g, Faction.Minions)));
            }

            foreach (CreatureAI creature in Faction.Minions)
            {
                if (creature.Status.Hunger.IsUnhappy())
                {
                    Task g = new SatisfyHungerTask();

                    if (IsFeasible(g, Faction.Minions))
                    {
                        tasks.Add(g);
                    }
                }
            }

            foreach (CreatureAI creature in Faction.Minions)
            {
                if (creature.Status.Energy.IsUnhappy() && PlayState.Time.IsNight())
                {
                    Task g = new SatisfyTirednessTask();

                    if (IsFeasible(g, Faction.Minions))
                    {
                        tasks.Add(g);
                    }
                }
            }

            List <Creature> threatsToRemove = new List <Creature>();

            foreach (Creature threat in Faction.Threats)
            {
                if (threat != null && !threat.IsDead)
                {
                    Task g = new KillEntityTask(threat.Physics, KillEntityTask.KillType.Auto);

                    if (!TaskIsAssigned(g) && IsFeasible(g, Faction.Minions))
                    {
                        tasks.Add(g);
                    }
                }
                else
                {
                    threatsToRemove.Add(threat);
                }
            }

            foreach (Creature threat in threatsToRemove)
            {
                Faction.Threats.Remove(threat);
            }

            foreach (BuildOrder i in Faction.DigDesignations)
            {
                if (i == null || i.Vox == null || i.Vox.Health <= 0)
                {
                    continue;
                }

                VoxelChunk chunk = PlayState.ChunkManager.ChunkData.GetVoxelChunkAtWorldLocation(i.Vox.Position);

                if (chunk != null)
                {
                    if (chunk.IsCompletelySurrounded(i.Vox))
                    {
                        continue;
                    }
                }


                Task g = new KillVoxelTask(i.Vox);

                if (!TaskIsAssigned(g) && IsFeasible(g, Faction.Minions))
                {
                    tasks.Add(g);
                }
            }

            tasks.AddRange(Faction.GuardDesignations.Select(i => new GuardVoxelTask(i.Vox)).Where(g => !TaskIsAssigned(g) && IsFeasible(g, Faction.Minions)));

            tasks.AddRange(Faction.ChopDesignations.Select(i => new KillEntityTask(i, KillEntityTask.KillType.Chop)).Where(g => !TaskIsAssigned(g) && IsFeasible(g, Faction.Minions)));

            if (Faction.Stockpiles.Count <= 0)
            {
                return(tasks);
            }

            foreach (WallBuilder put in Faction.WallBuilder.Designations)
            {
                if (Faction.HasResources(new List <ResourceAmount>()
                {
                    new ResourceAmount(put.Type.ResourceToRelease)
                }))
                {
                    Task g = (new BuildVoxelTask(put.Vox, put.Type));

                    if (!TaskIsAssigned(g) && IsFeasible(g, Faction.Minions))
                    {
                        tasks.Add(g);
                    }
                }
            }

            foreach (ShipOrder ship in Faction.ShipDesignations)
            {
                List <Body> componentsToShip = new List <Body>();
                int         remaining        = ship.GetRemainingNumResources();

                if (remaining == 0)
                {
                    continue;
                }


                foreach (Stockpile s in Faction.Stockpiles)
                {
                    for (int i = componentsToShip.Count; i < remaining; i++)
                    {
                        // TODO: Reimplement

                        /*
                         * Body r = s.FindItemWithTag(ship.Resource.ResourceType.ResourceName, componentsToShip);
                         *
                         * if(r != null)
                         * {
                         *  componentsToShip.Add(r);
                         * }
                         */
                    }
                }

                foreach (Body loc in componentsToShip)
                {
                    // TODO: Reimplement

                    /*
                     * if(ship.Port.ContainsItem(loc))
                     * {
                     *  continue;
                     * }
                     */

                    Task g = new PutItemInZoneTask(Item.FindItem(loc), ship.Port);

                    if (TaskIsAssigned(g) || !IsFeasible(g, Faction.Minions))
                    {
                        continue;
                    }

                    ship.Assignments.Add(g);
                    tasks.Add(g);
                }
            }

            return(tasks);
        }
コード例 #4
0
        public override void Update(DwarfTime gameTime, ChunkManager chunks, Camera camera)
        {
            IdleTimer.Update(gameTime);
            SpeakTimer.Update(gameTime);

            OrderEnemyAttack();
            DeleteBadTasks();
            PreEmptTasks();

            if (Status.Energy.IsUnhappy() && PlayState.Time.IsNight())
            {
                Task toReturn = new SatisfyTirednessTask();
                toReturn.SetupScript(Creature);
                if (!Tasks.Contains(toReturn))
                {
                    Tasks.Add(toReturn);
                }
            }

            if (Status.Hunger.IsUnhappy() && Faction.CountResourcesWithTag(Resource.ResourceTags.Food) > 0)
            {
                Task toReturn = new SatisfyHungerTask();
                toReturn.SetupScript(Creature);
                if (!Tasks.Contains(toReturn))
                {
                    Tasks.Add(toReturn);
                }
            }


            if (CurrentTask != null && CurrentAct != null)
            {
                Act.Status status = CurrentAct.Tick();


                bool retried = false;
                if (status == Act.Status.Fail)
                {
                    if (CurrentTask.ShouldRetry(Creature))
                    {
                        if (!Tasks.Contains(CurrentTask))
                        {
                            CurrentTask.Priority = Task.PriorityType.Eventually;
                            Tasks.Add(CurrentTask);
                            CurrentTask.SetupScript(Creature);
                            retried = true;
                        }
                    }
                }

                if (status != Act.Status.Running && !retried)
                {
                    CurrentTask = null;
                }
            }
            else
            {
                bool tantrum = false;
                if (Status.Happiness.IsUnhappy())
                {
                    tantrum = MathFunctions.Rand(0, 1) < 0.25f;
                }

                Task goal = GetEasiestTask(Tasks);
                if (goal != null)
                {
                    if (tantrum)
                    {
                        Creature.DrawIndicator(IndicatorManager.StandardIndicators.Sad);
                        if (Creature.Allies == "Dwarf")
                        {
                            PlayState.AnnouncementManager.Announce(Stats.FullName + " (" + Stats.CurrentLevel.Name + ")" + " refuses to work!",
                                                                   "Our employee is unhappy, and would rather not work!", ZoomToMe);
                        }
                        CurrentTask = null;
                    }
                    else
                    {
                        IdleTimer.Reset(IdleTimer.TargetTimeSeconds);
                        goal.SetupScript(Creature);
                        CurrentTask = goal;
                        Tasks.Remove(goal);
                    }
                }
                else
                {
                    CurrentTask = ActOnIdle();
                }
            }


            PlannerTimer.Update(gameTime);
            UpdateThoughts();
            UpdateXP();

            base.Update(gameTime, chunks, camera);
        }
コード例 #5
0
ファイル: CreatureAI.cs プロジェクト: maroussil/dwarfcorp
        public override void Update(DwarfTime gameTime, ChunkManager chunks, Camera camera)
        {
            IdleTimer.Update(gameTime);
            SpeakTimer.Update(gameTime);

            OrderEnemyAttack();
            DeleteBadTasks();
            PreEmptTasks();

            if (Status.Energy.IsUnhappy() && PlayState.Time.IsNight())
            {
                Task toReturn = new SatisfyTirednessTask();
                toReturn.SetupScript(Creature);
                if (!Tasks.Contains(toReturn))
                    Tasks.Add(toReturn);
            }

            if (Status.Hunger.IsUnhappy() &&  Faction.CountResourcesWithTag(Resource.ResourceTags.Food) > 0)
            {
                Task toReturn = new SatisfyHungerTask();
                toReturn.SetupScript(Creature);
                if (!Tasks.Contains(toReturn))
                    Tasks.Add(toReturn);
            }

            if(CurrentTask != null && CurrentAct != null)
            {
                Act.Status status = CurrentAct.Tick();

                bool retried = false;
                if(status == Act.Status.Fail)
                {
                    if(CurrentTask.ShouldRetry(Creature))
                    {
                        if (!Tasks.Contains(CurrentTask))
                        {
                            CurrentTask.Priority = Task.PriorityType.Eventually;
                            Tasks.Add(CurrentTask);
                            CurrentTask.SetupScript(Creature);
                            retried = true;
                        }
                    }
                }

                if(status != Act.Status.Running && !retried)
                {
                    CurrentTask = null;
                }
            }
            else
            {
                bool tantrum = false;
                if (Status.Happiness.IsUnhappy())
                {
                    tantrum = MathFunctions.Rand(0, 1) < 0.25f;
                }

                Task goal = GetEasiestTask(Tasks);
                if (goal != null)
                {
                    if (tantrum)
                    {
                        Creature.DrawIndicator(IndicatorManager.StandardIndicators.Sad);
                        if (Creature.Allies == "Dwarf")
                        {
                            PlayState.AnnouncementManager.Announce(Stats.FullName +  " (" + Stats.CurrentLevel.Name + ")" + " refuses to work!",
                                "Our employee is unhappy, and would rather not work!", ZoomToMe);
                        }
                        CurrentTask = null;
                    }
                    else
                    {
                        IdleTimer.Reset(IdleTimer.TargetTimeSeconds);
                        goal.SetupScript(Creature);
                        CurrentTask = goal;
                        Tasks.Remove(goal);
                    }
                }
                else
                {
                    CurrentTask = ActOnIdle();
                }

            }

            PlannerTimer.Update(gameTime);
            UpdateThoughts();
            UpdateXP();

            base.Update(gameTime, chunks, camera);
        }
コード例 #6
0
        override public void Update(DwarfTime gameTime, ChunkManager chunks, Camera camera)
        {
            //base.Update(gameTime, chunks, camera);

            if (!Active)
            {
                return;
            }
            Creature.NoiseMaker.BasePitch = Stats.VoicePitch;

            AutoGatherTimer.Update(gameTime);
            IdleTimer.Update(gameTime);
            SpeakTimer.Update(gameTime);

            if (AutoGatherTimer.HasTriggered)
            {
                foreach (var body in World.EnumerateIntersectingObjects(Physics.BoundingBox.Expand(3.0f)).OfType <ResourceEntity>().Where(r => r.Active && r.AnimationQueue.Count == 0))
                {
                    Creature.GatherImmediately(body, Inventory.RestockType.RestockResource);
                }

                OrderEnemyAttack();
            }

            DeleteBadTasks();
            PreEmptTasks();

            if (CurrentTask != null)
            {
                Stats.Boredom.CurrentValue -= (float)(CurrentTask.BoredomIncrease * gameTime.ElapsedGameTime.TotalSeconds);
                if (Stats.Boredom.IsCritical())
                {
                    Creature.AddThought("I have been overworked recently.", new TimeSpan(0, 4, 0, 0), -2.0f);
                }

                Stats.Energy.CurrentValue += (float)(CurrentTask.EnergyDecrease * gameTime.ElapsedGameTime.TotalSeconds);
            }

            // Heal thyself
            if (Stats.Health.IsDissatisfied())
            {
                Task toReturn = new GetHealedTask();
                if (!Tasks.Contains(toReturn) && CurrentTask != toReturn)
                {
                    AssignTask(toReturn);
                }
            }

            // Try to go to sleep if we are low on energy and it is night time.
            if (Stats.Energy.IsCritical())
            {
                Task toReturn = new SatisfyTirednessTask();
                if (!Tasks.Contains(toReturn) && CurrentTask != toReturn)
                {
                    AssignTask(toReturn);
                }
            }

            // Try to find food if we are hungry.
            if (Stats.Hunger.IsDissatisfied() && World.CountResourcesWithTag(Resource.ResourceTags.Edible) > 0)
            {
                Task toReturn = new SatisfyHungerTask()
                {
                    MustPay = true
                };
                if (Stats.Hunger.IsCritical())
                {
                    toReturn.Priority = TaskPriority.Urgent;
                }
                if (!Tasks.Contains(toReturn) && CurrentTask != toReturn)
                {
                    AssignTask(toReturn);
                }
            }

            if (Stats.Boredom.IsDissatisfied())
            {
                if (!Tasks.Any(task => task.BoredomIncrease < 0))
                {
                    Task toReturn = SatisfyBoredom();
                    if (toReturn != null && !Tasks.Contains(toReturn) && CurrentTask != toReturn)
                    {
                        AssignTask(toReturn);
                    }
                }
            }

            restockTimer.Update(DwarfTime.LastTime);
            if (restockTimer.HasTriggered && Creature.Inventory.Resources.Count > 10)
            {
                Creature.RestockAllImmediately();
            }

            if (CurrentTask == null)               // We need something to do.
            {
                if (Stats.Happiness.IsSatisfied()) // We're happy, so make sure we aren't on strike.
                {
                    Stats.IsOnStrike = false;
                    UnhappinessTime  = 0.0f;
                }

                if (Stats.IsOnStrike) // We're on strike, so track how long this job has sucked.
                {
                    UnhappinessTime += gameTime.ElapsedGameTime.TotalMinutes;
                    if (UnhappinessTime > GameSettings.Default.HoursUnhappyBeforeQuitting) // If we've been unhappy long enough, quit.
                    {
                        var thoughts = GetRoot().GetComponent <DwarfThoughts>();
                        Manager.World.MakeAnnouncement( // Can't use a popup because the dwarf will soon not exist. Also - this is a serious event!
                            Message: String.Format("{0} has quit!{1}",
                                                   Stats.FullName,
                                                   (thoughts == null ? "" : (" The last straw: " + thoughts.Thoughts.Last(t => t.HappinessModifier < 0.0f).Description))),
                            ClickAction: null,
                            logEvent: true,
                            eventDetails: (thoughts == null ? "So sick of this place!" : String.Join("\n", thoughts.Thoughts.Where(t => t.HappinessModifier < 0.0f).Select(t => t.Description)))
                            );

                        LeaveWorld();

                        GetRoot().GetComponent <Inventory>().Die();
                        GetRoot().GetComponent <SelectionCircle>().Die();

                        if (thoughts != null)
                        {
                            thoughts.Thoughts.Clear();
                        }

                        Faction.Minions.Remove(this);
                        World.PersistentData.SelectedMinions.Remove(this);

                        return;
                    }
                }
                else if (Stats.Happiness.IsDissatisfied()) // We aren't on strike, but we hate this place.
                {
                    if (MathFunctions.Rand(0, 1) < 0.25f)  // We hate it so much that we might just go on strike! This can probably be tweaked. As it stands,
                                                           // dorfs go on strike almost immediately every time.
                    {
                        Manager.World.UserInterface.MakeWorldPopup(String.Format("{0} ({1}) refuses to work!",
                                                                                 Stats.FullName, Stats.CurrentClass.Name), Creature.Physics, -10, 10);
                        Manager.World.Tutorial("happiness");
                        SoundManager.PlaySound(ContentPaths.Audio.Oscar.sfx_gui_negative_generic, 0.25f);
                        Stats.IsOnStrike = true;
                    }
                }

                if (!Stats.IsOnStrike) // We aren't on strike, so find a new task.
                {
                    var goal = GetEasiestTask(Tasks);
                    if (goal == null)
                    {
                        goal = World.TaskManager.GetBestTask(this);
                    }

                    if (goal != null)
                    {
                        IdleTimer.Reset(IdleTimer.TargetTimeSeconds);
                        ChangeTask(goal);
                    }
                    else
                    {
                        var newTask = ActOnIdle();
                        if (newTask != null)
                        {
                            ChangeTask(newTask);
                        }
                    }
                }
                else
                {
                    ChangeTask(ActOnIdle());
                }
            }
            else
            {
                if (CurrentAct == null) // Should be impossible to have a current task and no current act.
                {
                    // Try and recover the correct act.
                    // <blecki> I always run with a breakpoint set here... just in case.
                    ChangeAct(CurrentTask.CreateScript(Creature));

                    // This is a bad situation!
                    if (CurrentAct == null)
                    {
                        ChangeTask(null);
                    }
                }

                if (CurrentAct != null)
                {
                    var  status  = CurrentAct.Tick();
                    bool retried = false;
                    if (CurrentAct != null && CurrentTask != null)
                    {
                        if (status == Act.Status.Fail)
                        {
                            LastFailedAct = CurrentAct.Name;

                            if (!FailedTasks.Any(task => task.TaskFailure.Equals(CurrentTask)))
                            {
                                FailedTasks.Add(new FailedTask()
                                {
                                    TaskFailure = CurrentTask, FailedTime = World.Time.CurrentDate
                                });
                            }

                            if (CurrentTask.ShouldRetry(Creature))
                            {
                                if (!Tasks.Contains(CurrentTask))
                                {
                                    ReassignCurrentTask();
                                    retried = true;
                                }
                            }
                        }
                    }

                    if (CurrentTask != null && CurrentTask.IsComplete(World))
                    {
                        ChangeTask(null);
                    }
                    else if (status != Act.Status.Running && !retried)
                    {
                        ChangeTask(null);
                    }
                }
            }

            // With a small probability, the creature will drown if its under water.
            if (MathFunctions.RandEvent(0.01f))
            {
                var  above       = VoxelHelpers.GetVoxelAbove(Physics.CurrentVoxel);
                var  below       = VoxelHelpers.GetVoxelBelow(Physics.CurrentVoxel);
                bool shouldDrown = (above.IsValid && (!above.IsEmpty || above.LiquidLevel > 0));
                if ((Physics.IsInLiquid || (!Movement.CanSwim && (below.IsValid && (below.LiquidLevel > 5)))) &&
                    (!Movement.CanSwim || shouldDrown))
                {
                    Creature.Damage(Movement.CanSwim ? 1.0f : 30.0f, Health.DamageType.Normal);
                }
            }

            if (PositionConstraint.Contains(Physics.LocalPosition) == ContainmentType.Disjoint)
            {
                Physics.LocalPosition = MathFunctions.Clamp(Physics.Position, PositionConstraint);
                Physics.PropogateTransforms();
            }
        }