예제 #1
0
        public void UpdatePiece(JunctionPiece Piece, VoxelHandle Location)
        {
            DetachFromNeighbors();

            this.Piece    = Piece;
            this.Location = Location;

            LocalTransform = Matrix.CreateTranslation(Location.WorldPosition + new Vector3(Piece.Offset.X, 0, Piece.Offset.Y) + new Vector3(0.5f, 0.2f, 0.5f));

            if (Library.GetRailPiece(Piece.RailPiece).HasValue(out var piece))
            {
                Frame = piece.Tile;
            }

            ResetPrimitive();

            // Hack to make the listener update it's damn bounding box
            var deathTrigger = EnumerateChildren().OfType <GenericVoxelListener>().FirstOrDefault();

            if (deathTrigger != null)
            {
                deathTrigger.LocalTransform = Matrix.Identity;
            }

            AttachToNeighbors();
            PropogateTransforms();
        }
예제 #2
0
        private static Rail.RailCombination FindPossibleCombination(Rail.JunctionPiece Piece, IBoundedObject Entity)
        {
            if (Entity is RailPiece)
            {
                var baseJunction        = (Entity as RailPiece).Piece;
                var basePiece           = Rail.RailLibrary.GetRailPiece(baseJunction.RailPiece);
                var relativeOrientation = Rail.OrientationHelper.Relative(baseJunction.Orientation, Piece.Orientation);
                var matchingCombination = basePiece.CombinationTable.FirstOrDefault(c => c.Overlay == Piece.RailPiece && c.OverlayRelativeOrientation == relativeOrientation);
                return(matchingCombination);
            }

            return(null);
        }
예제 #3
0
        private bool CanPlace(VoxelHandle Location, Rail.JunctionPiece Piece, RailPiece PreviewEntity)
        {
            var actualPosition = new VoxelHandle(Location.Chunk.Manager.ChunkData, Location.Coordinate + new GlobalVoxelOffset(Piece.Offset.X, 0, Piece.Offset.Y));

            if (!actualPosition.IsValid)
            {
                return(false);
            }
            if (!actualPosition.IsEmpty)
            {
                return(false);
            }

            if (actualPosition.Coordinate.Y == 0)
            {
                return(false);                                  // ???
            }
            var local      = actualPosition.Coordinate.GetLocalVoxelCoordinate();
            var voxelUnder = new VoxelHandle(actualPosition.Chunk, new LocalVoxelCoordinate(local.X, local.Y - 1, local.Z));

            if (voxelUnder.IsEmpty)
            {
                return(false);
            }

            foreach (var entity in  Player.World.CollisionManager.EnumerateIntersectingObjects(actualPosition.GetBoundingBox().Expand(-0.2f), CollisionManager.CollisionType.Static))
            {
                if (Object.ReferenceEquals(entity, PreviewEntity))
                {
                    continue;
                }
                if (entity is NewVoxelListener)
                {
                    continue;
                }

                if (FindPossibleCombination(Piece, entity) != null)
                {
                    return(true);
                }

                if (GamePerformance.DebugVisualizationEnabled)
                {
                    Drawer3D.DrawBox(entity.GetBoundingBox(), Color.Yellow, 0.1f, false);
                }

                return(false);
            }

            return(true);
        }
예제 #4
0
        public void UpdatePiece(Rail.JunctionPiece Piece, VoxelHandle Location)
        {
            this.Piece = Piece;

            LocalTransform = Matrix.CreateTranslation(Location.WorldPosition + new Vector3(Piece.Offset.X, 0, Piece.Offset.Y) + new Vector3(0.5f, 0.2f, 0.5f));

            var    piece       = Rail.RailLibrary.GetRailPiece(Piece.RailPiece);
            var    spriteChild = EnumerateChildren().FirstOrDefault(c => c.Name == "Sprite") as SimpleSprite;
            Matrix transform   = Matrix.CreateRotationX((float)Math.PI * 0.5f) * Matrix.CreateRotationY((float)Math.PI * 0.5f * (float)Piece.Orientation);

            spriteChild.LocalTransform = transform;
            spriteChild.SetFrame(piece.Tile);

            // Hack to make the listener update it's damn bounding box
            EnumerateChildren().OfType <NewVoxelListener>().FirstOrDefault().LocalTransform = Matrix.Identity;
        }
예제 #5
0
        public RailPiece(
            ComponentManager Manager,
            VoxelHandle Location,
            Rail.JunctionPiece Piece) :

            base(Manager, "Fixture",
                 Matrix.CreateTranslation(Location.WorldPosition + new Vector3(Piece.Offset.X, 0, Piece.Offset.Y)),
                 Vector3.One,
                 Vector3.Zero,
                 true)
        {
            this.Piece = Piece;

            CollisionType = CollisionManager.CollisionType.Static;
            AddChild(new Health(Manager, "Hp", 100, 0, 100));

            PropogateTransforms();
            CreateCosmeticChildren(Manager);
        }
예제 #6
0
        public RailEntity(
            ComponentManager Manager,
            VoxelHandle Location,
            JunctionPiece Piece) :

            base(Manager, "Rail",
                 Matrix.CreateTranslation(Location.WorldPosition + new Vector3(Piece.Offset.X, 0, Piece.Offset.Y)),
                 Vector3.One,
                 Vector3.Zero,
                 new CraftDetails(Manager, "Rail", new List <ResourceAmount> { new ResourceAmount("Rail", 1) }))
        {
            this.Piece    = Piece;
            this.Location = Location;

            CollisionType = CollisionType.Static;
            AddChild(new Health(Manager, "Hp", 100, 0, 100));

            PropogateTransforms();
            CreateCosmeticChildren(Manager);
        }
예제 #7
0
        private int AddDiagonal(int bodyCounter, CompassOrientation B, JunctionPiece newPiece, int CoordinateRotation, int PieceRotation)
        {
            var firstEdgeOffset = CompassOrientationHelper.GetOffset(CompassOrientationHelper.Rotate(B, CoordinateRotation));
            var firstEdgePiece  = new JunctionPiece
            {
                Offset      = new Point(newPiece.Offset.X + firstEdgeOffset.X, newPiece.Offset.Y + firstEdgeOffset.Z),
                RailPiece   = "diag-edge-1",
                Orientation = (PieceOrientation)((int)CompassOrientationHelper.Rotate(B, PieceRotation) / 2)
            };

            if (PreviewBodies.Count <= bodyCounter)
            {
                PreviewBodies.Add(RailHelper.CreatePreviewBody(World.ComponentManager, DragStartVoxel, firstEdgePiece));
            }
            else
            {
                PreviewBodies[bodyCounter].UpdatePiece(firstEdgePiece, DragStartVoxel);
            }

            bodyCounter += 1;
            return(bodyCounter);
        }
예제 #8
0
        public override void OnVoxelsSelected(List <VoxelHandle> refs, InputManager.MouseButton button)
        {
            if (Command.Contains("Build/"))
            {
                if (Library.CreateZone(Command.Substring(6), World).HasValue(out var zone))
                {
                    World.AddZone(zone);
                    zone.CompleteRoomImmediately(refs);
                }
            }
            if (Command.Contains("Spawn/"))
            {
                string type = Command.Substring(6);
                foreach (var vox in refs.Where(vox => vox.IsValid))
                {
                    if (vox.IsEmpty)
                    {
                        var offset = Vector3.Zero;

                        if (Library.GetCraftable(type).HasValue(out var craftItem))
                        {
                            offset = craftItem.SpawnOffset;
                        }

                        var body = EntityFactory.CreateEntity <GameComponent>(type, vox.WorldPosition + new Vector3(0.5f, 0.0f, 0.5f) + offset);
                        if (body != null)
                        {
                            body.PropogateTransforms();

                            if (craftItem != null)
                            {
                                if (craftItem.AddToOwnedPool)
                                {
                                    World.PlayerFaction.OwnedObjects.Add(body);
                                }

                                if (craftItem.Deconstructable)
                                {
                                    body.Tags.Add("Deconstructable"); // Todo: Should not need to set tag every time item is created. Inherint?
                                }
                            }
                        }
                    }
                }
            }
            else if (Command.Contains("Resource/"))
            {
                string type = Command.Substring("Resource/".Length);
                foreach (var vox in refs.Where(vox => vox.IsValid))
                {
                    var body = World.ComponentManager.RootComponent.AddChild(new ResourceEntity(World.ComponentManager, new Resource(type), vox.WorldPosition + new Vector3(0.5f, 0.5f, 0.5f)));
                    body.PropogateTransforms();
                }
            }
            else if (Command.Contains("Rail/"))
            {
                string type     = Command.Substring("Rail/".Length);
                var    junction = new Rail.JunctionPiece
                {
                    RailPiece   = type,
                    Orientation = Rail.PieceOrientation.North,
                    Offset      = Point.Zero
                };

                foreach (var vox in refs.Where(vox => vox.IsValid))
                {
                    if (vox.IsEmpty)
                    {
                        var entity = new Rail.RailEntity(World.ComponentManager, vox, junction);
                        World.ComponentManager.RootComponent.AddChild(entity);
                    }
                }
            }
            else if (Command.Contains("Grass/"))
            {
                var type = Library.GetGrassType(Command.Substring(6));
                if (type != null)
                {
                    foreach (var vox in refs.Where(v => v.IsValid))
                    {
                        var v = vox;
                        if (!vox.IsEmpty)
                        {
                            v.GrassType  = type.ID;
                            v.GrassDecay = type.InitialDecayValue;
                        }
                    }
                }
            }
            else if (Command.Contains("Decal/"))
            {
                var type = Library.GetDecalType(Command.Substring(6));
                if (type != null)
                {
                    foreach (var vox in refs.Where(v => v.IsValid))
                    {
                        var v = vox;
                        if (!vox.IsEmpty)
                        {
                            v.DecalType = type.ID;
                        }
                    }
                }
            }
            else if (Command.Contains("Disease"))
            {
                foreach (var creature in World.EnumerateIntersectingObjects(VoxelHelpers.GetVoxelBoundingBox(refs), CollisionType.Both).OfType <Creature>())
                {
                    creature.Stats.AcquireDisease(DiseaseLibrary.GetRandomDisease());
                }
            }
            else
            {
                foreach (var vox in refs.Where(vox => vox.IsValid))
                {
                    if (Command.Contains("Place/"))
                    {
                        string type = Command.Substring(6);
                        var    v    = vox;
                        if (Library.GetVoxelType(type).HasValue(out VoxelType vType))
                        {
                            v.Type = vType;
                        }
                        v.QuickSetLiquid(LiquidType.None, 0);

                        if (type == "Magic")
                        {
                            World.ComponentManager.RootComponent.AddChild(
                                new DestroyOnTimer(World.ComponentManager, World.ChunkManager, vox)
                            {
                                DestroyTimer = new Timer(5.0f + MathFunctions.Rand(-0.5f, 0.5f), true)
                            });
                        }
                    }
                    else
                    {
                        switch (Command)
                        {
                        case "Delete Block":
                        {
                            var v = vox;
                            World.OnVoxelDestroyed(vox);
                            v.Type = Library.EmptyVoxelType;
                            v.QuickSetLiquid(LiquidType.None, 0);
                        }
                        break;

                        case "Nuke Column":
                        {
                            for (var y = 1; y < World.WorldSizeInVoxels.Y; ++y)
                            {
                                var v = World.ChunkManager.CreateVoxelHandle(new GlobalVoxelCoordinate(vox.Coordinate.X, y, vox.Coordinate.Z));
                                v.Type = Library.EmptyVoxelType;
                                v.QuickSetLiquid(LiquidType.None, 0);
                            }
                        }
                        break;

                        case "Kill Block":
                            foreach (var selected in refs)
                            {
                                if (!selected.IsEmpty)
                                {
                                    VoxelHelpers.KillVoxel(World, selected);
                                }
                            }
                            break;

                        case "Fill Water":
                        {
                            if (vox.IsEmpty)
                            {
                                var v = vox;
                                v.QuickSetLiquid(LiquidType.Water, WaterManager.maxWaterLevel);
                            }
                        }
                        break;

                        case "Fill Lava":
                        {
                            if (vox.IsEmpty)
                            {
                                var v = vox;
                                v.QuickSetLiquid(LiquidType.Lava, WaterManager.maxWaterLevel);
                            }
                        }
                        break;

                        case "Fire":
                        {
                            foreach (var flam2 in World.EnumerateIntersectingObjects(vox.GetBoundingBox(), CollisionType.Both).OfType <Flammable>())
                            {
                                flam2.Heat = flam2.Flashpoint + 1;
                            }
                        }
                        break;

                        default:
                            break;
                        }
                    }
                }
            }
        }
예제 #9
0
        public override void OnVoxelsSelected(List <VoxelHandle> refs, InputManager.MouseButton button)
        {
            if (Command.Contains("Build/"))
            {
                string         type = Command.Substring(6);
                BuildRoomOrder des  = new BuildRoomOrder(RoomLibrary.CreateRoom(Player.Faction, type, refs, false, Player.World), Player.Faction, Player.World);
                des.ToBuild.Designations = refs;
                Player.Faction.RoomBuilder.BuildDesignations.Add(des);
                Player.Faction.RoomBuilder.DesignatedRooms.Add(des.ToBuild);
                des.Build();
            }
            if (Command.Contains("Spawn/"))
            {
                string type = Command.Substring(6);
                foreach (var vox in refs.Where(vox => vox.IsValid))
                {
                    if (vox.IsEmpty)
                    {
                        var craftItem = CraftLibrary.GetCraftable(type);
                        var offset    = Vector3.Zero;

                        if (craftItem != null)
                        {
                            offset = craftItem.SpawnOffset;
                        }

                        var body = EntityFactory.CreateEntity <Body>(type, vox.WorldPosition + new Vector3(0.5f, 0.0f, 0.5f) + offset);
                        if (body != null)
                        {
                            body.PropogateTransforms();

                            if (craftItem != null)
                            {
                                if (craftItem.AddToOwnedPool)
                                {
                                    Player.Faction.OwnedObjects.Add(body);
                                }

                                if (craftItem.Moveable)
                                {
                                    body.Tags.Add("Moveable");
                                }

                                if (craftItem.Deconstructable)
                                {
                                    body.Tags.Add("Deconstructable");
                                }
                            }
                        }
                    }
                }
            }
            else if (Command.Contains("Rail/"))
            {
                string type     = Command.Substring("Rail/".Length);
                var    junction = new Rail.JunctionPiece
                {
                    RailPiece   = type,
                    Orientation = Rail.PieceOrientation.North,
                    Offset      = Point.Zero
                };

                foreach (var vox in refs.Where(vox => vox.IsValid))
                {
                    if (vox.IsEmpty)
                    {
                        var entity = new Rail.RailEntity(Player.World.ComponentManager, vox, junction);
                        Player.World.ComponentManager.RootComponent.AddChild(entity);
                    }
                }
            }
            else if (Command.Contains("Grass/"))
            {
                var type = GrassLibrary.GetGrassType(Command.Substring(6));
                foreach (var vox in refs.Where(v => v.IsValid))
                {
                    var v = vox;
                    if (!vox.IsEmpty)
                    {
                        v.GrassType = type.ID;
                    }
                }
            }
            else if (Command.Contains("Decal/"))
            {
                var type = DecalLibrary.GetGrassType(Command.Substring(6));
                foreach (var vox in refs.Where(v => v.IsValid))
                {
                    var v = vox;
                    if (!vox.IsEmpty)
                    {
                        v.Decal = DecalType.EncodeDecal(DecalOrientation, type.ID);
                    }
                }
            }
            else
            {
                foreach (var vox in refs.Where(vox => vox.IsValid))
                {
                    if (Command.Contains("Place/"))
                    {
                        string type = Command.Substring(6);
                        var    v    = vox;
                        v.Type = VoxelLibrary.GetVoxelType(type);
                        v.QuickSetLiquid(LiquidType.None, 0);

                        if (type == "Magic")
                        {
                            Player.World.ComponentManager.RootComponent.AddChild(
                                new DestroyOnTimer(Player.World.ComponentManager, Player.World.ChunkManager, vox)
                            {
                                DestroyTimer = new Timer(5.0f + MathFunctions.Rand(-0.5f, 0.5f), true)
                            });
                        }
                    }
                    else
                    {
                        switch (Command)
                        {
                        case "Delete Block":
                        {
                            var v = vox;
                            Player.World.Master.Faction.OnVoxelDestroyed(vox);
                            v.Type = VoxelLibrary.emptyType;
                            v.QuickSetLiquid(LiquidType.None, 0);
                        }
                        break;

                        case "Kill Block":
                            foreach (var selected in refs)
                            {
                                if (!selected.IsEmpty)
                                {
                                    Player.World.ChunkManager.KillVoxel(selected);
                                }
                            }
                            break;

                        case "Fill Water":
                        {
                            if (vox.IsEmpty)
                            {
                                var v = vox;
                                v.QuickSetLiquid(LiquidType.Water, WaterManager.maxWaterLevel);
                            }
                        }
                        break;

                        case "Fill Lava":
                        {
                            if (vox.IsEmpty)
                            {
                                var v = vox;
                                v.QuickSetLiquid(LiquidType.Lava, WaterManager.maxWaterLevel);
                            }
                        }
                        break;

                        case "Fire":
                        {
                            foreach (var flam2 in Player.World.EnumerateIntersectingObjects(vox.GetBoundingBox(), CollisionType.Both).OfType <Flammable>())
                            {
                                flam2.Heat = flam2.Flashpoint + 1;
                            }
                        }
                        break;

                        case "Kill Things":
                        {
                            foreach (var comp in Player.World.EnumerateIntersectingObjects(vox.GetBoundingBox(), CollisionType.Both))
                            {
                                comp.Die();
                            }
                        }
                        break;

                        case "Disease":
                        {
                            foreach (var creature in Player.World.EnumerateIntersectingObjects(vox.GetBoundingBox(), CollisionType.Both).OfType <Creature>())
                            {
                                var disease = Datastructures.SelectRandom(DiseaseLibrary.Diseases);
                                creature.AcquireDisease(disease.Name);
                            }
                            break;
                        }

                        default:
                            break;
                        }
                    }
                }
            }
        }
예제 #10
0
        public static RailEntity CreatePreviewBody(ComponentManager Manager, VoxelHandle Location, JunctionPiece Piece)
        {
            var r = new RailEntity(Manager, Location, Piece);

            Manager.RootComponent.AddChild(r);
            r.SetFlagRecursive(GameComponent.Flag.Active, false);

            foreach (var tinter in r.EnumerateAll().OfType <Tinter>())
            {
                tinter.Stipple = true;
            }

            r.SetFlag(GameComponent.Flag.ShouldSerialize, false);
            //Todo: Add craft details component.
            return(r);
        }
예제 #11
0
        public override void Update(DwarfGame game, DwarfTime time)
        {
            if (World.UserInterface.IsCameraRotationModeActive())
            {
                World.UserInterface.VoxSelector.Enabled = false;
                World.UserInterface.SetMouse(null);
                World.UserInterface.BodySelector.Enabled = false;
                return;
            }

            World.UserInterface.VoxSelector.Enabled       = true;
            World.UserInterface.BodySelector.Enabled      = false;
            World.UserInterface.VoxSelector.DrawBox       = false;
            World.UserInterface.VoxSelector.DrawVoxel     = true;
            World.UserInterface.VoxSelector.SelectionType = VoxelSelectionType.SelectEmpty;

            if (World.UserInterface.IsMouseOverGui)
            {
                World.UserInterface.SetMouse(World.UserInterface.MousePointer);
            }
            else
            {
                World.UserInterface.SetMouse(new Gui.MousePointer("mouse", 1, 4));
            }

            // Don't attempt any camera control if the user is trying to type intoa focus item.
            if (World.UserInterface.Gui.FocusItem != null && !World.UserInterface.Gui.FocusItem.IsAnyParentTransparent() && !World.UserInterface.Gui.FocusItem.IsAnyParentHidden())
            {
                return;
            }
            KeyboardState state    = Keyboard.GetState();
            bool          leftKey  = state.IsKeyDown(ControlSettings.Mappings.RotateObjectLeft);
            bool          rightKey = state.IsKeyDown(ControlSettings.Mappings.RotateObjectRight);

            if (LeftPressed && !leftKey)
            {
                if (PathVoxels.Count > 1)
                {
                    var matched         = false;
                    var firstDelta      = CompassOrientationHelper.GetVoxelDelta(PathVoxels[0], PathVoxels[1]);
                    var firstConnection = new CompassConnection(OverrideStartingOrientation ? StartingOppositeOrientation : CompassOrientationHelper.Opposite(firstDelta), firstDelta);

                    var orientationDelta = 1;

                    for (; orientationDelta < 8 && !matched; ++orientationDelta)
                    {
                        firstConnection.A = CompassOrientationHelper.Rotate(firstConnection.A, 1);
                        foreach (var piece in Library.EnumerateRailPieces().Where(p => p.CompassConnections.Count != 0))
                        {
                            for (int j = 0; j < 4 && !matched; ++j)
                            {
                                foreach (var compassConnection in piece.CompassConnections)
                                {
                                    if (compassConnection.RotateToPiece((PieceOrientation)j) == firstConnection)
                                    {
                                        matched = true;
                                    }
                                }
                            }
                            if (matched)
                            {
                                break;
                            }
                        }
                    }

                    if (matched)
                    {
                        StartingOppositeOrientation = firstConnection.A;
                    }

                    OverrideStartingOrientation = true;
                }
            }
            if (RightPressed && !rightKey)
            {
                if (PathVoxels.Count > 1)
                {
                    var matched        = false;
                    var lastDelta      = CompassOrientationHelper.GetVoxelDelta(PathVoxels[PathVoxels.Count - 1], PathVoxels[PathVoxels.Count - 2]);
                    var lastConnection = new CompassConnection(lastDelta, OverrideEndingOrientation ? EndingOppositeOrientation : CompassOrientationHelper.Opposite(lastDelta));

                    var orientationDelta = 1;

                    for (; orientationDelta < 8 && !matched; ++orientationDelta)
                    {
                        lastConnection.B = CompassOrientationHelper.Rotate(lastConnection.B, 1);
                        foreach (var piece in Library.EnumerateRailPieces().Where(p => p.CompassConnections.Count != 0))
                        {
                            for (int j = 0; j < 4 && !matched; ++j)
                            {
                                foreach (var compassConnection in piece.CompassConnections)
                                {
                                    if (compassConnection.RotateToPiece((PieceOrientation)j) == lastConnection)
                                    {
                                        matched = true;
                                    }
                                }
                            }
                            if (matched)
                            {
                                break;
                            }
                        }
                    }

                    if (matched)
                    {
                        EndingOppositeOrientation = lastConnection.B;
                    }

                    OverrideEndingOrientation = true;
                }
            }
            LeftPressed  = leftKey;
            RightPressed = rightKey;

            var tint = Color.White;

            if (!Dragging)
            {
            }
            else
            {
                var voxelUnderMouse = World.UserInterface.VoxSelector.VoxelUnderMouse;
                if (voxelUnderMouse == DragStartVoxel)
                {
                    // Create single straight preview piece
                }
                else
                {
                    var destinationPoint = voxelUnderMouse.Coordinate;

                    // Prevent path finding from attempting slopes - not supported yet.
                    destinationPoint = new GlobalVoxelCoordinate(destinationPoint.X, DragStartVoxel.Coordinate.Y, destinationPoint.Z);
                    var currentVoxel = DragStartVoxel.Coordinate;

                    PathVoxels.Clear();
                    PathVoxels.Add(currentVoxel);

                    while (true)
                    {
                        var   closestDirection = 0;
                        float closestDistance  = float.PositiveInfinity;
                        for (var i = 0; i < 8; ++i)
                        {
                            var offsetPos = currentVoxel + CompassOrientationHelper.GetOffset((CompassOrientation)i);
                            var distance  = (destinationPoint.ToVector3() - offsetPos.ToVector3()).LengthSquared();
                            if (distance < closestDistance)
                            {
                                closestDistance  = distance;
                                closestDirection = i;
                            }
                        }

                        var nextCoordinate = currentVoxel + CompassOrientationHelper.GetOffset((CompassOrientation)closestDirection);
                        PathVoxels.Add(nextCoordinate);
                        if (PathVoxels.Count >= 100)
                        {
                            break;
                        }

                        if (nextCoordinate == destinationPoint)
                        {
                            break;
                        }
                        currentVoxel = nextCoordinate;
                    }

                    // Iterate PathVoxels, determining deltas and using them to decide which piece to create.
                    var pathCompassConnections = new List <CompassConnection>();

                    if (PathVoxels.Count > 1)
                    {
                        var firstDelta = CompassOrientationHelper.GetVoxelDelta(PathVoxels[0], PathVoxels[1]);
                        pathCompassConnections.Add(new CompassConnection(OverrideStartingOrientation ? StartingOppositeOrientation : CompassOrientationHelper.Opposite(firstDelta), firstDelta));

                        for (var i = 1; i < PathVoxels.Count - 1; ++i)
                        {
                            pathCompassConnections.Add(new CompassConnection(
                                                           CompassOrientationHelper.GetVoxelDelta(PathVoxels[i], PathVoxels[i - 1]),
                                                           CompassOrientationHelper.GetVoxelDelta(PathVoxels[i], PathVoxels[i + 1])));
                        }

                        var lastDelta = CompassOrientationHelper.GetVoxelDelta(PathVoxels[PathVoxels.Count - 1], PathVoxels[PathVoxels.Count - 2]);
                        pathCompassConnections.Add(new CompassConnection(lastDelta, OverrideEndingOrientation ? EndingOppositeOrientation : CompassOrientationHelper.Opposite(lastDelta)));
                    }

                    var bodyCounter = 0;
                    var previousPieceAddedTrailingDiagonals = false;

                    for (var i = 0; i < pathCompassConnections.Count; ++i)
                    {
                        var pieceAdded = false;

                        foreach (var piece in Library.EnumerateRailPieces().Where(p => p.CompassConnections.Count != 0))
                        {
                            var matchedOrientation = PieceOrientation.North;
                            CompassConnection matchedConnection = new CompassConnection();
                            bool matched = false;
                            for (int j = 0; j < 4 && !matched; ++j)
                            {
                                foreach (var compassConnection in piece.CompassConnections)
                                {
                                    var rotated = compassConnection.RotateToPiece((PieceOrientation)j);
                                    if (rotated == pathCompassConnections[i])
                                    {
                                        matched            = true;
                                        matchedOrientation = (PieceOrientation)j;
                                        matchedConnection  = pathCompassConnections[i];
                                        break;
                                    }
                                }
                            }

                            if (matched)
                            {
                                var newPiece = new JunctionPiece
                                {
                                    Offset      = new Point(PathVoxels[i].X - DragStartVoxel.Coordinate.X, PathVoxels[i].Z - DragStartVoxel.Coordinate.Z),
                                    RailPiece   = piece.Name,
                                    Orientation = matchedOrientation
                                };

                                if (PreviewBodies.Count <= bodyCounter)
                                {
                                    PreviewBodies.Add(RailHelper.CreatePreviewBody(World.ComponentManager, DragStartVoxel, newPiece));
                                }
                                else
                                {
                                    PreviewBodies[bodyCounter].UpdatePiece(newPiece, DragStartVoxel);
                                }

                                bodyCounter += 1;
                                pieceAdded   = true;

                                if (!previousPieceAddedTrailingDiagonals &&
                                    (matchedConnection.A == CompassOrientation.Northeast || matchedConnection.A == CompassOrientation.Southeast || matchedConnection.A == CompassOrientation.Southwest ||
                                     matchedConnection.A == CompassOrientation.Northwest))
                                {
                                    bodyCounter = AddDiagonal(bodyCounter, matchedConnection.A, newPiece, 7, 5);
                                    bodyCounter = AddDiagonal(bodyCounter, matchedConnection.A, newPiece, 1, 1);
                                }

                                if (matchedConnection.B == CompassOrientation.Northeast || matchedConnection.B == CompassOrientation.Southeast || matchedConnection.B == CompassOrientation.Southwest ||
                                    matchedConnection.B == CompassOrientation.Northwest)
                                {
                                    previousPieceAddedTrailingDiagonals = true;

                                    bodyCounter = AddDiagonal(bodyCounter, matchedConnection.B, newPiece, 7, 5);
                                    bodyCounter = AddDiagonal(bodyCounter, matchedConnection.B, newPiece, 1, 1);
                                }
                                else
                                {
                                    previousPieceAddedTrailingDiagonals = false;
                                }

                                break;
                            }
                        }

                        if (!pieceAdded)
                        {
                            break;
                        }
                    }

                    // Clean up any excess preview entities.
                    var lineSize = bodyCounter;

                    while (bodyCounter < PreviewBodies.Count)
                    {
                        PreviewBodies[bodyCounter].GetRoot().Delete();
                        bodyCounter += 1;
                    }

                    PreviewBodies = PreviewBodies.Take(lineSize).ToList();
                }
            }

            CanPlace = RailHelper.CanPlace(World, PreviewBodies);
            if (CanPlace)
            {
                tint = GameSettings.Default.Colors.GetColor("Positive", Color.Green);
            }
            else
            {
                tint = GameSettings.Default.Colors.GetColor("Negative", Color.Red);
            }

            foreach (var body in PreviewBodies)
            {
                body.SetVertexColorRecursive(tint);
            }
        }
예제 #12
0
        private void Place(VoxelHandle Location)
        {
            var assignments = new List <Task>();

            for (var i = 0; i < PreviewBodies.Count; ++i)
            {
                var body              = PreviewBodies[i];
                var piece             = Pattern.Pieces[i];
                var actualPosition    = new VoxelHandle(Location.Chunk.Manager.ChunkData, Location.Coordinate + new GlobalVoxelOffset(piece.Offset.X, 0, piece.Offset.Y));
                var addNewDesignation = true;

                foreach (var entity in Player.World.CollisionManager.EnumerateIntersectingObjects(actualPosition.GetBoundingBox().Expand(-0.2f), CollisionManager.CollisionType.Static))
                {
                    if (!addNewDesignation)
                    {
                        break;
                    }
                    if (Object.ReferenceEquals(entity, body))
                    {
                        continue;
                    }

                    var possibleCombination = FindPossibleCombination(piece, entity);
                    if (possibleCombination != null)
                    {
                        var combinedPiece = new Rail.JunctionPiece
                        {
                            RailPiece   = possibleCombination.Result,
                            Orientation = Rail.OrientationHelper.Rotate((entity as RailPiece).Piece.Orientation, (int)possibleCombination.ResultRelativeOrientation),
                        };

                        var existingDesignation = Player.Faction.Designations.EnumerateEntityDesignations(DesignationType.Craft).FirstOrDefault(d => Object.ReferenceEquals(d.Body, entity));
                        if (existingDesignation != null)
                        {
                            (entity as RailPiece).UpdatePiece(combinedPiece, actualPosition);
                            (existingDesignation.Tag as CraftDesignation).Progress = 0.0f;
                            body.Delete();
                            addNewDesignation = false;
                        }
                        else
                        {
                            (entity as RailPiece).Die();
                            body.UpdatePiece(combinedPiece, actualPosition);
                        }
                    }
                }

                if (addNewDesignation)
                {
                    var startPos = body.Position + new Vector3(0.0f, -0.3f, 0.0f);
                    var endPos   = body.Position;

                    var designation = new CraftDesignation
                    {
                        Entity              = body,
                        WorkPile            = new WorkPile(Player.World.ComponentManager, startPos),
                        OverrideOrientation = false,
                        Valid                = true,
                        ItemType             = RailCraftItem,
                        SelectedResources    = SelectedResources,
                        Location             = new VoxelHandle(Player.World.ChunkManager.ChunkData, GlobalVoxelCoordinate.FromVector3(body.Position)),
                        HasResources         = false,
                        ResourcesReservedFor = null,
                        Orientation          = 0.0f,
                        Progress             = 0.0f,
                    };

                    Player.World.ComponentManager.RootComponent.AddChild(designation.WorkPile);
                    designation.WorkPile.AnimationQueue.Add(new EaseMotion(1.1f, Matrix.CreateTranslation(startPos), endPos));
                    Player.World.ParticleManager.Trigger("puff", endPos, Color.White, 10);
                    Player.Faction.Designations.AddEntityDesignation(body, DesignationType.Craft, designation);
                    assignments.Add(new CraftItemTask(designation));
                }
            }

            if (assignments.Count > 0)
            {
                Player.World.Master.TaskManager.AddTasks(assignments);
            }
        }