Esempio n. 1
0
        public override void Render(DwarfGame game, GraphicsDevice graphics, DwarfTime time)
        {
            foreach (BuildOrder d in Player.Faction.GuardDesignations)
            {
                Voxel v = d.Vox;

                if (v.IsEmpty)
                {
                    continue;
                }

                BoundingBox box = v.GetBoundingBox();


                Color drawColor = GuardDesignationColor;

                if (d.NumCreaturesAssigned == 0)
                {
                    drawColor = UnreachableColor;
                }

                drawColor.R = (byte)(Math.Min(drawColor.R * Math.Abs(Math.Sin(time.TotalGameTime.TotalSeconds * GuardDesignationGlowRate)) + 50, 255));
                drawColor.G = (byte)(Math.Min(drawColor.G * Math.Abs(Math.Sin(time.TotalGameTime.TotalSeconds * GuardDesignationGlowRate)) + 50, 255));
                drawColor.B = (byte)(Math.Min(drawColor.B * Math.Abs(Math.Sin(time.TotalGameTime.TotalSeconds * GuardDesignationGlowRate)) + 50, 255));
                Drawer3D.DrawBox(box, drawColor, 0.05f, true);
            }
        }
Esempio n. 2
0
        public void Put(ChunkManager manager)
        {
            VoxelChunk chunk = manager.ChunkData.ChunkMap[Vox.ChunkID];

            Voxel v = chunk.MakeVoxel((int)Vox.GridPosition.X, (int)Vox.GridPosition.Y, (int)Vox.GridPosition.Z);

            v.Type   = Type;
            v.Water  = new WaterCell();
            v.Health = Type.StartingHealth;
            chunk.NotifyTotalRebuild(!v.IsInterior);

            PlayState.ParticleManager.Trigger("puff", v.Position, Color.White, 20);

            List <Body> components = new List <Body>();

            manager.Components.GetBodiesIntersecting(Vox.GetBoundingBox(), components, CollisionManager.CollisionType.Dynamic);

            foreach (Physics phys in components.OfType <Physics>())
            {
                phys.ApplyForce((phys.GlobalTransform.Translation - (Vox.Position + new Vector3(0.5f, 0.5f, 0.5f))) * 100, 0.01f);
                BoundingBox     box     = v.GetBoundingBox();
                Physics.Contact contact = new Physics.Contact();
                Physics.TestStaticAABBAABB(box, phys.GetBoundingBox(), ref contact);

                if (!contact.IsIntersecting)
                {
                    continue;
                }

                Vector3 diff = contact.NEnter * contact.Penetration;
                Matrix  m    = phys.LocalTransform;
                m.Translation      += diff;
                phys.LocalTransform = m;
            }
        }
Esempio n. 3
0
        public BuildRoomOrder GetMostLikelyDesignation(Voxel v)
        {
            BoundingBox larger = new BoundingBox(v.GetBoundingBox().Min - new Vector3(0.5f, 0.5f, 0.5f), v.GetBoundingBox().Max + new Vector3(0.5f, 0.5f, 0.5f));

            return((from room in BuildDesignations
                    from buildDesignation in room.VoxelOrders
                    where larger.Intersects(buildDesignation.Voxel.GetBoundingBox())
                    select room).FirstOrDefault());
        }
Esempio n. 4
0
        public override void Render(DwarfTime time)
        {
            BoundingBox box = VoxelToGuard.GetBoundingBox();


            Color drawColor = Color.LightBlue;



            drawColor.R = (byte)(Math.Min(drawColor.R * Math.Abs(Math.Sin(time.TotalGameTime.TotalSeconds * 0.5f)) + 50, 255));
            drawColor.G = (byte)(Math.Min(drawColor.G * Math.Abs(Math.Sin(time.TotalGameTime.TotalSeconds * 0.5f)) + 50, 255));
            drawColor.B = (byte)(Math.Min(drawColor.B * Math.Abs(Math.Sin(time.TotalGameTime.TotalSeconds * 0.5f)) + 50, 255));
            Drawer3D.DrawBox(box, drawColor, 0.05f, true);
            base.Render(time);
        }
Esempio n. 5
0
        public Room GetMostLikelyRoom(Voxel v)
        {
            Voxel vRef = v;

            foreach (Room r in DesignatedRooms.Where(r => r.ContainsVoxel(vRef)))
            {
                return(r);
            }

            BoundingBox larger = new BoundingBox(v.GetBoundingBox().Min - new Vector3(0.5f, 0.5f, 0.5f), v.GetBoundingBox().Max + new Vector3(0.5f, 0.5f, 0.5f));

            return((from room in BuildDesignations
                    from buildDesignation in room.VoxelOrders
                    where larger.Intersects(buildDesignation.Voxel.GetBoundingBox())
                    select buildDesignation.ToBuild).FirstOrDefault());
        }
Esempio n. 6
0
        public override void Render(DwarfGame game, GraphicsDevice graphics, DwarfTime time)
        {
            foreach (KeyValuePair <ulong, BuildOrder> kvp in Player.Faction.DigDesignations)
            {
                Voxel v = kvp.Value.Vox;

                BoundingBox box = v.GetBoundingBox();


                Color drawColor = DigDesignationColor;

                if (kvp.Value.NumCreaturesAssigned == 0)
                {
                    drawColor = UnreachableColor;
                }

                drawColor.R = (byte)(drawColor.R * Math.Abs(Math.Sin(time.TotalGameTime.TotalSeconds * DigDesignationGlowRate)) + 50);
                drawColor.G = (byte)(drawColor.G * Math.Abs(Math.Sin(time.TotalGameTime.TotalSeconds * DigDesignationGlowRate)) + 50);
                drawColor.B = (byte)(drawColor.B * Math.Abs(Math.Sin(time.TotalGameTime.TotalSeconds * DigDesignationGlowRate)) + 50);
                Drawer3D.DrawBox(box, drawColor, 0.05f, true);
            }
        }
Esempio n. 7
0
        public void Update()
        {
            MouseState    mouse    = Mouse.GetState();
            KeyboardState keyboard = Keyboard.GetState();

            Voxel underMouse = GetVoxelUnderMouse();
            bool  newVoxel   = underMouse != null && !underMouse.Equals(VoxelUnderMouse);

            if (underMouse != null)
            {
                VoxelUnderMouse          = underMouse;
                PlayState.CursorLightPos = underMouse.Position + new Vector3(0.5f, 0.5f, 0.5f);

                if (Enabled && underMouse.TypeName != "empty" && underMouse.IsExplored)
                {
                    string info = underMouse.TypeName;


                    if (PlayState.PlayerFaction.RoomBuilder.IsInRoom(underMouse))
                    {
                        Room room = PlayState.PlayerFaction.RoomBuilder.GetMostLikelyRoom(underMouse);

                        if (room != null)
                        {
                            info += " (" + room.ID + ")";
                        }
                    }
                    PlayState.GUI.ToolTipManager.PopupInfo(info);
                }
            }

            if (!Enabled)
            {
                return;
            }

            if (keyboard.IsKeyDown(Keys.LeftAlt) || keyboard.IsKeyDown(Keys.RightAlt))
            {
                BoxYOffset    += (float)(mouse.ScrollWheelValue - LastMouseWheel) * 0.01f;
                LastMouseWheel = mouse.ScrollWheelValue;
                newVoxel       = true;
            }
            else
            {
                LastMouseWheel = mouse.ScrollWheelValue;
            }


            if (underMouse != null)
            {
                BoundingBox box = underMouse.GetBoundingBox().Expand(0.05f);
                Drawer3D.DrawBox(box, CurrentColor, CurrentWidth, true);
            }

            if (isLeftPressed)
            {
                if (mouse.LeftButton == ButtonState.Released)
                {
                    isLeftPressed = false;
                    LeftReleasedCallback();
                    BoxYOffset = 0;
                }
                else
                {
                    if (SelectionBuffer.Count == 0)
                    {
                        FirstVoxel = underMouse;
                        SelectionBuffer.Add(underMouse);
                    }
                    else
                    {
                        SelectionBuffer.Clear();
                        SelectionBuffer.Add(FirstVoxel);
                        SelectionBuffer.Add(underMouse);
                        BoundingBox buffer = GetSelectionBox();


                        if (BoxYOffset > 0)
                        {
                            buffer.Max.Y += BoxYOffset;
                        }
                        else if (BoxYOffset < 0)
                        {
                            buffer.Min.Y += BoxYOffset;
                        }

                        SelectionBuffer = Chunks.GetVoxelsIntersecting(buffer);

                        if (newVoxel)
                        {
                            Dragged.Invoke(SelectionBuffer, InputManager.MouseButton.Left);
                        }
                    }
                }
            }
            else if (mouse.LeftButton == ButtonState.Pressed)
            {
                LeftPressedCallback();
                isLeftPressed = true;
                BoxYOffset    = 0;
            }


            if (isRightPressed)
            {
                if (mouse.RightButton == ButtonState.Released)
                {
                    isRightPressed = false;
                    RightReleasedCallback();
                    BoxYOffset = 0;
                }
                else
                {
                    if (SelectionBuffer.Count == 0)
                    {
                        SelectionBuffer.Add(underMouse);
                        FirstVoxel = underMouse;
                    }
                    else
                    {
                        SelectionBuffer.Clear();
                        SelectionBuffer.Add(FirstVoxel);
                        SelectionBuffer.Add(underMouse);
                        BoundingBox buffer = GetSelectionBox();
                        if (BoxYOffset > 0)
                        {
                            buffer.Max.Y += BoxYOffset;
                        }
                        else if (BoxYOffset < 0)
                        {
                            buffer.Min.Y += BoxYOffset;
                        }


                        SelectionBuffer = Chunks.GetVoxelsIntersecting(buffer);
                        if (newVoxel)
                        {
                            Dragged.Invoke(SelectionBuffer, InputManager.MouseButton.Right);
                        }
                    }
                }
            }
            else if (mouse.RightButton == ButtonState.Pressed)
            {
                RightPressedCallback();
                BoxYOffset     = 0;
                isRightPressed = true;
            }
        }
Esempio n. 8
0
        public Room GetMostLikelyRoom(Voxel v)
        {
            Voxel vRef = v;
            foreach(Room r in DesignatedRooms.Where(r => r.ContainsVoxel(vRef)))
            {
                return r;
            }

            BoundingBox larger = new BoundingBox(v.GetBoundingBox().Min - new Vector3(0.5f, 0.5f, 0.5f), v.GetBoundingBox().Max + new Vector3(0.5f, 0.5f, 0.5f));

            return (from room in BuildDesignations
                from buildDesignation in room.VoxelOrders
                where larger.Intersects(buildDesignation.Voxel.GetBoundingBox())
                select buildDesignation.ToBuild).FirstOrDefault();
        }
Esempio n. 9
0
        public BuildRoomOrder GetMostLikelyDesignation(Voxel v)
        {
            BoundingBox larger = new BoundingBox(v.GetBoundingBox().Min - new Vector3(0.5f, 0.5f, 0.5f), v.GetBoundingBox().Max + new Vector3(0.5f, 0.5f, 0.5f));

            return (from room in BuildDesignations
                from buildDesignation in room.VoxelOrders
                where larger.Intersects(buildDesignation.Voxel.GetBoundingBox())
                select room).FirstOrDefault();
        }
Esempio n. 10
0
 public bool Intersects(Voxel v)
 {
     return(Intersects(v.GetBoundingBox()));
 }
Esempio n. 11
0
        public override void Update(DwarfTime gameTime, ChunkManager chunks, Camera camera)
        {
            ParticleEmitter._camera = camera;

            List <Particle> toRemove = new List <Particle>();

            TriggerTimer.Update(gameTime);
            if (TriggerTimer.HasTriggered && Data.ParticlesPerFrame > 0)
            {
                Trigger(Data.ParticlesPerFrame, Vector3.Zero, Tint);
            }


            bool  particlePhysics = GameSettings.Default.ParticlePhysics;
            Voxel v = new Voxel();

            foreach (Particle p in Particles)
            {
                float vel = p.Velocity.LengthSquared();
                if (!Data.Sleeps || vel > 0.2f)
                {
                    if (Data.EmitsLight && p.Scale > 0.1f)
                    {
                        DynamicLight.TempLights.Add(new DynamicLight(10.0f, 255.0f, false)
                        {
                            Position = p.Position
                        });
                    }
                    p.Position += p.Velocity * (float)gameTime.ElapsedGameTime.TotalSeconds;

                    if (Data.RotatesWithVelocity)
                    {
                        Vector3 cameraVel   = camera.Project(p.Velocity + camera.Position);
                        float   projectionX = cameraVel.X;
                        float   projectionY = cameraVel.Y;

                        p.Angle = (float)Math.Atan2(projectionY, projectionX);
                    }
                    else
                    {
                        p.Angle += (float)(p.AngularVelocity * gameTime.ElapsedGameTime.TotalSeconds);
                    }
                    p.Velocity        += Data.ConstantAccel * (float)gameTime.ElapsedGameTime.TotalSeconds;
                    p.Velocity        *= Data.LinearDamping;
                    p.AngularVelocity *= Data.AngularDamping;
                }
                else if (Data.Sleeps && vel < 0.2f)
                {
                    p.Velocity = Vector3.Zero;
                }


                if (!Data.UseManualControl)
                {
                    p.LifeRemaining -= Data.ParticleDecay * (float)gameTime.ElapsedGameTime.TotalSeconds;
                }

                p.Scale += Data.GrowthSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds;

                p.Scale = Math.Max(p.Scale, 0.0f);
                bool success = false;


                if (Data.HasLighting)
                {
                    success = chunks.ChunkData.GetVoxel(p.Position, ref v);

                    if (success && v.IsEmpty)
                    {
                        p.Tint = new Color(v.SunColor, 255, 0);
                    }
                }

                if (Data.CollidesWorld && particlePhysics && vel > 0.2f)
                {
                    if (!Data.HasLighting)
                    {
                        success = chunks.ChunkData.GetVoxel(p.Position, ref v);
                    }
                    BoundingBox b = new BoundingBox(p.Position - Vector3.One * p.Scale * 0.5f, p.Position + Vector3.One * p.Scale * 0.5f);
                    if (success && !v.IsEmpty)
                    {
                        Physics.Contact contact = new Physics.Contact();
                        if (Physics.TestStaticAABBAABB(b, v.GetBoundingBox(), ref contact))
                        {
                            p.Position += contact.NEnter * contact.Penetration;
                            Vector3 newVelocity = Vector3.Reflect(p.Velocity, -contact.NEnter);
                            p.Velocity         = newVelocity * Data.Damping;
                            p.AngularVelocity *= 0.5f;
                        }
                    }
                }

                if (p.LifeRemaining < 0)
                {
                    if (p.InstanceData != null)
                    {
                        p.InstanceData.ShouldDraw = false;
                        p.InstanceData.Transform  = Matrix.CreateTranslation(camera.Position + new Vector3(-1000, -1000, -1000));
                        Sprites.Remove(p.InstanceData);
                    }

                    toRemove.Add(p);
                }

                else if (p.InstanceData != null)
                {
                    p.InstanceData.ShouldDraw = true;
                    p.InstanceData.Transform  = MatrixFromParticle(p);
                    p.InstanceData.Color      = p.Tint;
                }
            }

            foreach (Particle p in toRemove)
            {
                Particles.Remove(p);
            }


            Sprites.Update(gameTime, camera, chunks.Graphics);
            base.Update(gameTime, chunks, camera);
        }
Esempio n. 12
0
        public override void Update(DwarfTime gameTime, ChunkManager chunks, Camera camera)
        {
            ParticleEmitter._camera = camera;

            List<Particle> toRemove = new List<Particle>();

            TriggerTimer.Update(gameTime);
            if(TriggerTimer.HasTriggered && Data.ParticlesPerFrame > 0)
            {
                Trigger(Data.ParticlesPerFrame, Vector3.Zero, Tint);
            }

            bool particlePhysics = GameSettings.Default.ParticlePhysics;
            Voxel v = new Voxel();
            foreach(Particle p in Particles)
            {
                float vel = p.Velocity.LengthSquared();
                if(!Data.Sleeps || vel > 0.2f)
                {
                    if (Data.EmitsLight && p.Scale > 0.1f)
                    {
                        DynamicLight.TempLights.Add(new DynamicLight(10.0f, 255.0f, false) { Position = p.Position});
                    }
                    p.Position += p.Velocity * (float)gameTime.ElapsedGameTime.TotalSeconds;

                    if (Data.RotatesWithVelocity)
                    {
                        Vector3 cameraVel = camera.Project(p.Velocity + camera.Position);
                        float projectionX = cameraVel.X;
                        float projectionY = cameraVel.Y;

                        p.Angle = (float)Math.Atan2(projectionY, projectionX);
                    }
                    else
                    {
                        p.Angle += (float)(p.AngularVelocity * gameTime.ElapsedGameTime.TotalSeconds);
                    }
                    p.Velocity += Data.ConstantAccel * (float)gameTime.ElapsedGameTime.TotalSeconds;
                    p.Velocity *= Data.LinearDamping;
                    p.AngularVelocity *= Data.AngularDamping;
                }
                else if (Data.Sleeps && vel < 0.2f)
                {
                    p.Velocity = Vector3.Zero;
                }

                p.LifeRemaining -= Data.ParticleDecay * (float)gameTime.ElapsedGameTime.TotalSeconds;
                p.Scale += Data.GrowthSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds;

                p.Scale = Math.Max(p.Scale, 0.0f);
                bool success = false;

                if (Data.HasLighting)
                {
                    success = chunks.ChunkData.GetVoxel(p.Position, ref v);

                    if (success && v.IsEmpty)
                    {
                        p.Tint = new Color(v.SunColor, 255, 0);
                    }
                }

                if(Data.CollidesWorld && particlePhysics && vel > 0.2f)
                {
                    if (!Data.HasLighting)
                    {
                        success = chunks.ChunkData.GetVoxel(p.Position, ref v);
                    }
                    BoundingBox b = new BoundingBox(p.Position - Vector3.One * p.Scale * 0.5f, p.Position + Vector3.One * p.Scale * 0.5f);
                    if(success && !v.IsEmpty)
                    {
                        Physics.Contact contact = new Physics.Contact();
                        if(Physics.TestStaticAABBAABB(b, v.GetBoundingBox(), ref contact))
                        {
                            p.Position += contact.NEnter * contact.Penetration;
                            Vector3 newVelocity = Vector3.Reflect(p.Velocity, -contact.NEnter);
                            p.Velocity = newVelocity * Data.Damping;
                            p.AngularVelocity *= 0.5f;
                        }
                    }
                }

                if(p.LifeRemaining < 0)
                {
                    if(p.InstanceData != null)
                    {//
                        p.InstanceData.ShouldDraw = false;
                        p.InstanceData.Transform = Matrix.CreateTranslation(camera.Position + new Vector3(-1000, -1000, -1000));
                        Sprites.Remove(p.InstanceData);
                    }

                    toRemove.Add(p);
                }

                else if(p.InstanceData != null)
                {
                    p.InstanceData.ShouldDraw = true;
                    p.InstanceData.Transform = MatrixFromParticle(p);
                    p.InstanceData.Color = p.Tint;
                }
            }

            foreach(Particle p in toRemove)
            {
                Particles.Remove(p);
            }

            Sprites.Update(gameTime, camera, chunks.Graphics);
            base.Update(gameTime, chunks, camera);
        }
Esempio n. 13
0
        public void Update()
        {
            MouseState    mouse    = Mouse.GetState();
            KeyboardState keyboard = Keyboard.GetState();

            Voxel underMouse = GetVoxelUnderMouse();
            // Keep track of whether a new voxel has been selected.
            bool newVoxel = underMouse != null && !underMouse.Equals(VoxelUnderMouse);

            // If there is a voxel under the mouse...
            if (underMouse != null)
            {
                VoxelUnderMouse = underMouse;
                // Update the cursor light.
                PlayState.CursorLightPos = underMouse.Position + new Vector3(0.5f, 0.5f, 0.5f);

                // Get the type of the voxel and display it to the player.
                if (Enabled && !underMouse.IsEmpty && underMouse.IsExplored)
                {
                    string info = underMouse.TypeName;

                    // If it belongs to a room, display that information.
                    if (PlayState.PlayerFaction.RoomBuilder.IsInRoom(underMouse))
                    {
                        Room room = PlayState.PlayerFaction.RoomBuilder.GetMostLikelyRoom(underMouse);

                        if (room != null)
                        {
                            info += " (" + room.ID + ")";
                        }
                    }
                    PlayState.GUI.ToolTipManager.PopupInfo(info);
                }
            }

            // Do nothing if not enabled.
            if (!Enabled)
            {
                return;
            }
            bool altPressed = false;

            // If the left or right ALT keys are pressed, we can adjust the height of the selection
            // for building pits and tall walls using the mouse wheel.
            if (keyboard.IsKeyDown(Keys.LeftAlt) || keyboard.IsKeyDown(Keys.RightAlt))
            {
                BoxYOffset    += (mouse.ScrollWheelValue - LastMouseWheel) * 0.01f;
                LastMouseWheel = mouse.ScrollWheelValue;
                newVoxel       = true;
                altPressed     = true;
            }
            else
            {
                LastMouseWheel = mouse.ScrollWheelValue;
            }

            // Draw a box around the current voxel under the mouse.
            if (underMouse != null)
            {
                BoundingBox box = underMouse.GetBoundingBox().Expand(0.05f);
                Drawer3D.DrawBox(box, CurrentColor, CurrentWidth, true);
            }

            // If the left mouse button is pressed, update the slection buffer.
            if (isLeftPressed)
            {
                // On release, select voxels.
                if (mouse.LeftButton == ButtonState.Released)
                {
                    isLeftPressed = false;
                    LeftReleasedCallback();
                    BoxYOffset = 0;
                }
                // Otherwise, update the selection buffer
                else
                {
                    if (SelectionBuffer.Count == 0)
                    {
                        FirstVoxel = underMouse;
                        SelectionBuffer.Add(underMouse);
                    }
                    else
                    {
                        SelectionBuffer.Clear();
                        SelectionBuffer.Add(FirstVoxel);
                        SelectionBuffer.Add(underMouse);
                        BoundingBox buffer = GetSelectionBox();

                        // Update the selection box to account for offsets from mouse wheel.
                        if (BoxYOffset > 0)
                        {
                            buffer.Max.Y += BoxYOffset;
                        }
                        else if (BoxYOffset < 0)
                        {
                            buffer.Min.Y += BoxYOffset;
                        }

                        SelectionBuffer = Chunks.GetVoxelsIntersecting(buffer);

                        if (!altPressed)
                        {
                            SelectionBuffer.RemoveAll(
                                voxel =>
                                (!voxel.Equals(underMouse) && Chunks.ChunkData.IsVoxelOccluded(voxel)));
                        }

                        if (newVoxel)
                        {
                            Dragged.Invoke(SelectionBuffer, InputManager.MouseButton.Left);
                        }
                    }
                }
            }
            // If the mouse was not previously pressed, but is now pressed, then notify us of that.
            else if (mouse.LeftButton == ButtonState.Pressed)
            {
                LeftPressedCallback();
                isLeftPressed = true;
                BoxYOffset    = 0;
            }

            // Case where the right mouse button is pressed (mirrors left mouse button)
            // TODO(Break this into a function)
            if (isRightPressed)
            {
                if (mouse.RightButton == ButtonState.Released)
                {
                    isRightPressed = false;
                    RightReleasedCallback();
                    BoxYOffset = 0;
                }
                else
                {
                    if (SelectionBuffer.Count == 0)
                    {
                        SelectionBuffer.Add(underMouse);
                        FirstVoxel = underMouse;
                    }
                    else
                    {
                        SelectionBuffer.Clear();
                        SelectionBuffer.Add(FirstVoxel);
                        SelectionBuffer.Add(underMouse);
                        BoundingBox buffer = GetSelectionBox();
                        if (BoxYOffset > 0)
                        {
                            buffer.Max.Y += BoxYOffset;
                        }
                        else if (BoxYOffset < 0)
                        {
                            buffer.Min.Y += BoxYOffset;
                        }


                        SelectionBuffer = Chunks.GetVoxelsIntersecting(buffer);
                        if (!altPressed)
                        {
                            SelectionBuffer.RemoveAll(
                                voxel =>
                                (!voxel.Equals(underMouse) && Chunks.ChunkData.IsVoxelOccluded(voxel)));
                        }
                        if (newVoxel)
                        {
                            Dragged.Invoke(SelectionBuffer, InputManager.MouseButton.Right);
                        }
                    }
                }
            }
            else if (mouse.RightButton == ButtonState.Pressed)
            {
                RightPressedCallback();
                BoxYOffset     = 0;
                isRightPressed = true;
            }
        }
Esempio n. 14
0
        public override IEnumerable <Status> Run()
        {
            if (!Creature.Faction.WallBuilder.IsDesignation(Voxel))
            {
                yield return(Status.Fail);

                yield break;
            }

            foreach (Status status in Creature.HitAndWait(1.0f, true, Voxel.Position))
            {
                if (status == Status.Running)
                {
                    yield return(status);
                }
            }

            Body grabbed = Creature.Inventory.RemoveAndCreate(Resource).FirstOrDefault();

            if (grabbed == null)
            {
                yield return(Status.Fail);

                yield break;
            }
            else
            {
                if (Creature.Faction.WallBuilder.IsDesignation(Voxel))
                {
                    // If the creature intersects the box, find a voxel adjacent to it that is free, and jump there to avoid getting crushed.
                    if (Creature.Physics.BoundingBox.Intersects(Voxel.GetBoundingBox()))
                    {
                        List <Voxel> neighbors   = Voxel.Chunk.GetNeighborsEuclidean(Voxel);
                        Voxel        closest     = null;
                        float        closestDist = float.MaxValue;
                        foreach (Voxel voxel in neighbors)
                        {
                            float dist = (voxel.Position - Creature.Physics.Position).LengthSquared();
                            if (dist < closestDist && voxel.IsEmpty)
                            {
                                closestDist = dist;
                                closest     = voxel;
                            }
                        }

                        if (closest != null)
                        {
                            TossMotion teleport = new TossMotion(0.5f, 1.0f, Creature.Physics.GlobalTransform, closest.Position + Vector3.One * 0.5f);
                            Creature.Physics.AnimationQueue.Add(teleport);
                        }
                    }
                    TossMotion motion = new TossMotion(1.0f, 2.0f, grabbed.LocalTransform, Voxel.Position + new Vector3(0.5f, 0.5f, 0.5f));
                    motion.OnComplete += grabbed.Die;
                    grabbed.GetComponent <Physics>().CollideMode = Physics.CollisionMode.None;
                    grabbed.AnimationQueue.Add(motion);

                    WallBuilder put = Creature.Faction.WallBuilder.GetDesignation(Voxel);
                    put.Put(Creature.Manager.World.ChunkManager);


                    Creature.Faction.WallBuilder.Designations.Remove(put);
                    Creature.Stats.NumBlocksPlaced++;
                    Creature.AI.AddXP(1);
                    yield return(Status.Success);
                }
                else
                {
                    Creature.Inventory.Resources.AddItem(grabbed);
                    grabbed.Die();

                    yield return(Status.Fail);
                }
            }
        }