public virtual void Build(bool silent = false) { if (IsBuilt) { return; } IsBuilt = true; RoomLibrary.CompleteRoomImmediately(ToBuild, VoxelOrders.Select(o => o.Voxel).ToList()); if (!silent) { World.MakeAnnouncement(String.Format("{0} was built", ToBuild.RoomData.Name), null); SoundManager.PlaySound(ContentPaths.Audio.Oscar.sfx_gui_positive_generic, 0.15f); World.GoalManager.OnGameEvent(new Goals.Triggers.BuiltRoom(ToBuild.ID)); } foreach (GameComponent fence in WorkObjects) { fence.Die(); } }
/// <summary> /// Creates a flat, wooden balloon port for the balloon to land on, and Dwarves to sit on. /// </summary> /// <param name="roomDes">The player's BuildRoom designator (so that we can create a balloon port)</param> /// <param name="chunkManager">The terrain handler</param> /// <param name="x">The position of the center of the balloon port</param> /// <param name="z">The position of the center of the balloon port</param> /// <param name="size">The size of the (square) balloon port in voxels on a side</param> public Room GenerateInitialBalloonPort(RoomBuilder roomDes, ChunkManager chunkManager, float x, float z, int size) { var centerCoordinate = GlobalVoxelCoordinate.FromVector3(new Vector3(x, VoxelConstants.ChunkSizeY - 1, z)); var accumulator = 0; var count = 0; for (var offsetX = -size; offsetX <= size; ++offsetX) { for (var offsetY = -size; offsetY <= size; ++offsetY) { var topVoxel = VoxelHelpers.FindFirstVoxelBelowIncludeWater( new VoxelHandle(chunkManager.ChunkData, centerCoordinate + new GlobalVoxelOffset(offsetX, 0, offsetY))); if (topVoxel.Coordinate.Y > 0) { accumulator += topVoxel.Coordinate.Y + 1; count += 1; } } } var averageHeight = (int)Math.Round(((float)accumulator / (float)count)); if (StartUnderground) { accumulator = 0; count = 0; List <string> illegalTypes = new List <string>() { "Sand", "Dirt", "DarkDirt", "Ice" }; for (var offsetX = -size; offsetX <= size; ++offsetX) { for (var offsetY = -size; offsetY <= size; ++offsetY) { var topVoxel = VoxelHelpers.FindFirstVoxelBelow( new VoxelHandle(chunkManager.ChunkData, centerCoordinate + new GlobalVoxelOffset(offsetX, 0, offsetY))); if (topVoxel.Coordinate.Y > 0) { var vox = topVoxel; for (int dy = topVoxel.Coordinate.Y; dy > 0; dy--) { vox = new VoxelHandle(chunkManager.ChunkData, new GlobalVoxelCoordinate(topVoxel.Coordinate.X, dy, topVoxel.Coordinate.Z)); if (vox.IsValid && !vox.IsEmpty && !illegalTypes.Contains(vox.Type.Name)) { break; } } accumulator += vox.Coordinate.Y + 1; count += 1; } } } averageHeight = Math.Max((int)Math.Round(((float)accumulator / (float)count)) - 5, 0); } // Next, create the balloon port by deciding which voxels to fill. var balloonPortDesignations = new List <VoxelHandle>(); var treasuryDesignations = new List <VoxelHandle>(); for (int dx = -size; dx <= size; dx++) { for (int dz = -size; dz <= size; dz++) { Vector3 worldPos = new Vector3(centerCoordinate.X + dx, centerCoordinate.Y, centerCoordinate.Z + dz); var baseVoxel = VoxelHelpers.FindFirstVoxelBelow(new VoxelHandle( chunkManager.ChunkData, GlobalVoxelCoordinate.FromVector3(worldPos))); if (!baseVoxel.IsValid) { continue; } var h = baseVoxel.Coordinate.Y + 1; var localCoord = baseVoxel.Coordinate.GetLocalVoxelCoordinate(); for (int y = averageHeight; y < (StartUnderground ? averageHeight + 2 : h); y++) { var v = new VoxelHandle(baseVoxel.Chunk, new LocalVoxelCoordinate((int)localCoord.X, y, (int)localCoord.Z)); v.RawSetType(VoxelLibrary.GetVoxelType(0)); v.RawSetIsExplored(); v.QuickSetLiquid(LiquidType.None, 0); } if (averageHeight < h) { h = averageHeight; } bool isPosX = (dx == size && dz == 0); bool isPosZ = (dz == size & dx == 0); bool isNegX = (dx == -size && dz == 0); bool isNegZ = (dz == -size && dz == 0); bool isSide = (isPosX || isNegX || isPosZ || isNegZ); Vector3 offset = Vector3.Zero; if (isSide) { if (isPosX) { offset = Vector3.UnitX; } else if (isPosZ) { offset = Vector3.UnitZ; } else if (isNegX) { offset = -Vector3.UnitX; } else if (isNegZ) { offset = -Vector3.UnitZ; } } bool encounteredFilled = false; // Fill from the top height down to the bottom. for (int y = Math.Min(0, h - 1); y < averageHeight && y < VoxelConstants.ChunkSizeY; y++) { var v = new VoxelHandle(baseVoxel.Chunk, new LocalVoxelCoordinate((int)localCoord.X, y, (int)localCoord.Z)); if (!v.IsValid) { throw new InvalidProgramException("Voxel was invalid while creating a new game's initial zones. This should not happen."); } v.RawSetType(VoxelLibrary.GetVoxelType("Scaffold")); v.IsPlayerBuilt = true; v.QuickSetLiquid(LiquidType.None, 0); if (y == averageHeight - 1) { v.RawSetIsExplored(); if (dz >= 0) { balloonPortDesignations.Add(v); } else { treasuryDesignations.Add(v); } } if (isSide && !encounteredFilled) { var ladderPos = new Vector3(worldPos.X, y, worldPos.Z) + offset + Vector3.One * 0.5f; var ladderVox = new VoxelHandle(chunkManager.ChunkData, GlobalVoxelCoordinate.FromVector3(ladderPos)); if (ladderVox.IsValid && ladderVox.IsEmpty) { var ladder = EntityFactory.CreateEntity <Ladder>("Ladder", ladderPos); Master.Faction.OwnedObjects.Add(ladder); ladder.Tags.Add("Moveable"); ladder.Tags.Add("Deconstructable"); } else { encounteredFilled = true; } } } } } // Actually create the BuildRoom. var toBuild = RoomLibrary.CreateRoom(PlayerFaction, "Balloon Port", this); roomDes.DesignatedRooms.Add(toBuild); RoomLibrary.CompleteRoomImmediately(toBuild, balloonPortDesignations); // Also add a treasury var treasury = RoomLibrary.CreateRoom(PlayerFaction, "Treasury", this); roomDes.DesignatedRooms.Add(treasury); RoomLibrary.CompleteRoomImmediately(treasury, treasuryDesignations); return(toBuild); }
public override void OnVoxelsSelected(List <VoxelHandle> refs, InputManager.MouseButton button) { if (Command.Contains("Build/")) { string type = Command.Substring(6); var room = RoomLibrary.CreateRoom(Player.Faction, type, Player.World); Player.Faction.RoomBuilder.DesignatedRooms.Add(room); RoomLibrary.CompleteRoomImmediately(room, refs); } 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; v.GrassDecay = type.InitialDecayValue; } } } 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; } } } } }