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(); }
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); }
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); }
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; }
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); }
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); }
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); }
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; } } } } }
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; } } } } }
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); }
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); } }
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); } }