/// <summary> /// /// </summary> /// <param name="here"></param> /// <param name="to"></param> public override void Remove(Location here, Location to) { if (here == to) { return; } Direction d = here.getDirectionTo(to); while (true) { RailImpl rr = RailRoad.get(here) as RailImpl; if (rr != null && rr.hasRail(d)) { // destroy it rr.Voxel.railRoad = null; // TODO: delete piers BridgePierVoxel.teardownBridgeSupport(here, TrafficVoxel.get(here)); } if (here == to) { return; } here = here.toward(to); } }
/// <summary> /// Builds normal RR between two specified locations /// </summary> /// <returns>false if the operation was unsuccessful</returns> public static bool Build(Location here, Location there) { // ensure that nothing is on our way between "from" and "to" WorldDefinition world = WorldDefinition.World; int cost; if (ComputeRoute(here, there, out cost) == null) { return(false); } Direction d = here.getDirectionTo(there); while (true) { TrafficVoxel v = TrafficVoxel.getOrCreate(here); if (v == null) { Voxel vv = WorldDefinition.World[here]; Debug.Assert(vv.Entity.isSilentlyReclaimable); vv.Entity.remove(); v = TrafficVoxel.getOrCreate(here); } Direction dd; if (here != there) { dd = here.getDirectionTo(there); } else { dd = d; } if (v.railRoad != null) { v.railRoad.Attach(here == there ? d.opposite : d); WorldDefinition.World.OnVoxelUpdated(here); } else { v.railRoad = new SingleRailRoad(v, RailPattern.get(d.opposite, dd)); // if this RR is elevated, elect a bridge support. // if((++cycle%2)==0) BridgePierVoxel.electBridgeSupport(here, typeof(BridgePierVoxel.DefaultImpl), v); } if (here == there) { break; } d = dd; here = here.toward(there); } Accounting.AccountGenre.RailService.Spend(cost); // charge the cost return(true); }
/// <summary> /// Creates a new slope. A slope consists of four consective /// blocks of railroads. The base parameter specifies the location /// of the lowest railroad and the direction parameter /// specifies the direction to climb. /// /// The caller must use the canCreateSlope method to check /// if this method can be invoked. /// </summary> public static void createSlope(Location _base, Direction dir) { Debug.Assert(canCreateSlope(_base, dir)); // charge the cost before we alter something Accounting.AccountGenre.RailService.Spend(calcCostOfNewSlope(_base, dir)); SlopeEntity entity = new SlopeEntity(_base, dir); for (int i = 0; i < 4; i++) { if (_base.z < WorldDefinition.World.GetGroundLevel(_base)) { new SlopeRailRoad(entity, TrafficVoxel.getOrCreate( _base.x, _base.y, _base.z + (i / 2)), RailPattern.getUGSlope(dir, i)); if (i < 2) { // space filler new SlopeFillerVoxel(entity, _base.x, _base.y, _base.z + 1, i); } else { new SlopeSupportVoxel(entity, _base.x, _base.y, _base.z, i, RailPattern.slopeWalls[dir.index + i - 2]); } } else { new SlopeRailRoad(entity, TrafficVoxel.getOrCreate( _base.x, _base.y, _base.z + (i / 2)), RailPattern.getSlope(dir, i)); if (i < 2) { // space filler new SlopeFillerVoxel(entity, _base.x, _base.y, _base.z + 1, i); } else { new SlopeSupportVoxel(entity, _base.x, _base.y, _base.z, i, RailPattern.slopeSupports[dir.index + (i - 2)]); } } Type bridgeStyle; if (dir == Direction.NORTH || dir == Direction.EAST) { bridgeStyle = typeof(BridgePierVoxel.DefaultImpl); } else { bridgeStyle = typeof(BridgePierVoxel.SlopeNEImpl); } BridgePierVoxel.electBridgeSupport(_base, bridgeStyle, entity); _base += dir; } }
///// <summary> ///// Elects a bridge support from the surface level to the given location, ///// if it can be done. ///// </summary> ///// <param name="loc">The location of the elevated RR.</param> // public static void electBridgeSupport( Location loc, Type topBridgeType, Type otherBridgeType ) { // // // check if a support is buildable // // TODO: start from the surface level // for( int z=0; z<loc.z; z++ ) // if(World.world[loc.x,loc.y,z]!=null) // return; // // // if we can, do it // for( int z=World.world.getGroundLevel(loc); z<loc.z; z++ ) { // Activator.CreateInstance( // (z==loc.z-1)?topBridgeType:otherBridgeType, // new object[]{ loc.x, loc.y, z }); // } // } /// <summary> /// Tears down a bridge support if any. /// </summary> public static void teardownBridgeSupport(Location loc, IEntity owner) { for (int z = 0; z < loc.z; z++) { BridgePierVoxel v = WorldDefinition.World[loc.x, loc.y, z] as BridgePierVoxel; if (v != null) { WorldDefinition.World.remove(loc.x, loc.y, z); } } }
/// <summary> /// /// </summary> /// <param name="here"></param> /// <param name="to"></param> public override void Build(Location here, Location to) { Debug.Assert(CanBeBuilt(here, to)); Direction d = here.getDirectionTo(to); bool building = false; bool pier = true; while (true) { if (RailRoad.get(here) == null) { TrafficVoxel v = TrafficVoxel.getOrCreate(here); if (!building) { building = true; create(v, d, BridgeRailMode.Begin); } else { create(v, d, (here == to || RailRoad.get(here + d) != null) ? BridgeRailMode.End : BridgeRailMode.Middle); } if (pier) { BridgePierVoxel.electBridgeSupport(here, d.isParallelToX ? typeof(PierTop1Impl) : typeof(PierTop2Impl), d.isParallelToX ? typeof(PierBody1Impl) : typeof(PierBody2Impl), v); } pier = !pier; } else { building = false; } if (here == to) { return; } here = here.toward(to); } }
/// <summary> /// /// </summary> /// <param name="here"></param> /// <param name="to"></param> public override void Build(Location here, Location to) { Debug.Assert(CanBeBuilt(here, to)); Direction d = here.getDirectionTo(to); while (true) { if (RailRoad.get(here) == null) { TrafficVoxel tv = TrafficVoxel.getOrCreate(here); new RailImpl(tv, d); BridgePierVoxel.electBridgeSupport(here, tv); } if (here == to) { return; } here = here.toward(to); } }
/// <summary> /// Removes a slope. The format of the parameters are the same /// as the createSlope method. Ut us /// </summary> public static void removeSlope(Location loc, Direction dir) { Debug.Assert(canRemoveSlope(loc, dir)); // charge the cost before we alter something Accounting.AccountGenre.RailService.Spend(calcCostOfTearDownSlope(loc, dir)); for (int i = 0; i < 4; i++) { TrafficVoxel v = TrafficVoxel.get(loc.x, loc.y, loc.z + (i / 2)); v.railRoad = null; Location l = loc; l.z += -(i / 2) + 1; Debug.Assert(WorldDefinition.World[l] is EmptyVoxel); WorldDefinition.World.remove(l); BridgePierVoxel.teardownBridgeSupport(loc, v); loc += dir; } }
/// <summary> /// Removes normal RR between two specified locations /// </summary> /// <returns>false if the operation was unsuccessful</returns> public static void Remove(Location here, Location there) { WorldDefinition world = WorldDefinition.World; Direction d = here.getDirectionTo(there); // charge the cost first. Accounting.AccountGenre.RailService.Spend(CalcCostOfRemoving(here, there)); while (true) { Direction dd; if (here != there) { dd = here.getDirectionTo(there); } else { dd = d; } TrafficVoxel v = TrafficVoxel.get(here); if (v != null && v.railRoad != null && !v.isOccupied) { v.railRoad.Detach(d.opposite, dd); } BridgePierVoxel.teardownBridgeSupport(here, v); if (here == there) { break; } d = dd; here = here.toward(there); } }