public YardRailRoad(TrafficVoxel v, Platform _owner, int _idx) : base(v, _owner.direction) { Debug.Assert(dir1.isSharp); Debug.Assert(dir2.isSharp); this.owner = _owner; this.index = _idx; }
// remove any passageway private static void removePassageway(Location loc1, Location loc2) { // on each voxel along the way for (Location loc = loc1; ; loc = loc.toward(loc2)) { TrafficVoxel tv = TrafficVoxel.get(loc); if (tv != null && tv.railRoad is ThinPlatform.RailRoadImpl) { ThinPlatform.RailRoadImpl rr = (ThinPlatform.RailRoadImpl)tv.railRoad; if (rr.outlook is ThinPlatform.PassagewayPlatform) { // retore the normal platform. rr.outlook = ThinPlatform.plainPlatform; } } else { // TODO: open-ended bridge } if (loc == loc2) { // TODO: correctly updated voxels World.world.onAllVoxelUpdated(); return; } } }
public override void onClick(MapViewWindow view, Location loc, Point ab) { if (isPlacing) { TrafficVoxel tv = TrafficVoxel.getOrCreate(loc); if (tv == null) { MainWindow.showError("There are obstacles"); //! MainWindow.showError("障害物があります"); return; } if (tv.railRoad == null || tv.railRoad is SingleRailRoad) { new SignalRailRoad(tv, currentType, currentDirection); } else { MainWindow.showError("Can not place on this rail"); } //! MainWindow.showError("設置できない線路です"); } else { SignalRailRoad srr = RailRoad.get(loc) as SignalRailRoad; if (srr != null) { srr.remove(); } } }
/// <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); } }
private static bool canAddLane(Location loc, Direction direction, int length) { for (int i = 0; i < length; i++, loc += direction) { Voxel v = World.world[loc]; if (v == null) { continue; // OK } if (v is TrafficVoxel) { TrafficVoxel tv = (TrafficVoxel)v; // TODO can't add a lane if there is a car road if (tv.car != null) { return(false); // there is a obstacle } if (tv.railRoad is SingleRailRoad) { if (Direction.angle(tv.railRoad.dir1, direction) % 4 == 0 && Direction.angle(tv.railRoad.dir2, direction) % 4 == 0) { continue; // this RR can be converted to a platform } } } // otherwise there is an obstacle return(false); } return(true); }
protected override void onLocationSelected(Location loc) { if (remove) { if (contribution.canBeBuilt(loc)) { if (TrafficVoxel.get(loc).accessory != null) { TrafficVoxel.get(loc).accessory = null; } } else { MainWindow.showError("Can not remove"); } //! MainWindow.showError("撤去できません"); } else { if (contribution.canBeBuilt(loc)) { contribution.create(loc); } else { MainWindow.showError("Can not place"); } //! MainWindow.showError("設置できません"); } }
/// <summary> /// Removes this platform from the world. /// </summary> public override void remove() { World world = World.world; onHostDisconnected(); foreach (YardRailRoad[] yrrs in lanes) { if (yrrs != null) { foreach (YardRailRoad yrr in yrrs) { // canRemove must be true before this method is called. Debug.Assert(yrr.voxel.car == null); Location loc = yrr.location; yrr.voxel.railRoad = null; new SingleRailRoad( TrafficVoxel.getOrCreate(loc), RailPattern.get(direction, direction.opposite)); world.onVoxelUpdated(loc); } } } // remove the platform itself foreach (FatPlatformVoxel pv in voxels) { world.remove(pv.location); world.onVoxelUpdated(pv.location); } base.remove(); }
public DummyCar(TrafficVoxel target, DummyCarContribution _contrib, int _color, int _index) { this.index = (byte)_index; this.contrib = _contrib; this.color = _color; target.accessory = this; }
/// <summary> /// Returns true if a platform can be built under the specified condition. /// This includes room for lane 0. /// </summary> public static bool canBeBuilt(Location loc, Direction dir, int length) { if (!dir.isSharp) { return(false); // incorrect direction } for ( ; length > 0; length--, loc += dir) { if (World.world[loc] == null) { continue; // this voxel is empty.OK. } TrafficVoxel tv = TrafficVoxel.get(loc); if (tv == null) { return(false); // this voxel is occupied by something else. } if (tv.car != null) { return(false); // there is a car on RR } if (tv.railRoad is SingleRailRoad) { if (Direction.angle(tv.railRoad.dir1, dir) % 4 == 0 && Direction.angle(tv.railRoad.dir2, dir) % 4 == 0) { continue; // this RR can be converted to a platform } } return(false); // other RRs are not acceptable } return(true); // enough space }
public bool canBeBuilt(Location loc) { TrafficVoxel voxel = TrafficVoxel.get(loc); if (voxel == null) { return(false); } RailRoad rr = voxel.railRoad; if (rr == null) { return(false); } RailPattern rp = rr.getPattern(); if (rp.numberOfRails != 2) { return(false); } if (!rp.hasRail(rr.dir1.opposite)) { return(false); } return(rr.dir1.isSharp); }
/// <summary> /// /// </summary> public void remove() { foreach (Voxel v in cube.Voxels) { if (v.Entity == this && !(v is BridgePierVoxel)) { WorldDefinition.World.remove(v); } else { TrafficVoxel tv = v as TrafficVoxel; if (tv != null) { SlopeRailRoad srr = tv.railRoad as SlopeRailRoad; if (srr != null && srr.entity == this) { tv.remove(); } } } // if(v.location.z==cube.z1) // BridgePierVoxel.teardownBridgeSupport(v.location,this); } if (onEntityRemoved != null) { onEntityRemoved(this, null); } }
/// <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" World world = World.world; int cost; if (comupteRoute(here, there, out cost) == null) { return(false); } Direction d = here.getDirectionTo(there); while (true) { TrafficVoxel v = TrafficVoxel.getOrCreate(here); if (v == null) { Voxel vv = World.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); World.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.RAIL_SERVICE.spend(cost); // charge the cost return(true); }
public override void drawVoxel(QuarterViewDrawer view, DrawContextEx canvas, Location loc, Point pt) { if (base.currentPos != loc) { return; } if (!contribution.canBeBuilt(loc)) { return; } int x; RoadPattern rp = TrafficVoxel.get(loc).road.pattern; if (rp.hasRoad(Direction.NORTH)) { x = 0; } else { x = 1; } contribution.sprites[color, x].drawAlpha(canvas.surface, pt); }
/// <summary> /// /// </summary> /// <param name="loc"></param> protected override void OnLocationSelected(Location loc) { if (remove) { if (contribution.CanBeBuilt(loc)) { if (TrafficVoxel.get(loc).accessory != null) { TrafficVoxel.get(loc).accessory = null; } } else { MessageBox.Show("Cannot remove"); } //! MessageBox.Show("撤去できません"); } else { if (contribution.CanBeBuilt(loc)) { contribution.Create(loc); } else { MessageBox.Show("Cannot place"); } } }
/// <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; } }
public SignalRailRoad(TrafficVoxel v, RailSignalContribution _type, Direction _dir) : base(v, _dir) { this.direction = _dir; this.type = _type; pattern = RailPattern.get(direction, direction.opposite); Debug.Assert(dir1.isSharp); Debug.Assert(dir2.isSharp); }
protected override void onLocationSelected(Location loc) { ElectricPole e = ElectricPole.get(loc); if (e != null) { TrafficVoxel.get(loc).accessory = null; } }
/// <summary> /// Gets the Road object of the specified location, if any. /// Otherwise null. /// </summary> public static BaseRoad get(Location loc) { TrafficVoxel v = WorldDefinition.World[loc] as TrafficVoxel; if (v == null) { return(null); } return(v.road); }
/// <summary> /// /// </summary> /// <param name="tv"></param> /// <param name="pattern"></param> /// <param name="style"></param> protected BaseRoad(TrafficVoxel tv, RoadPattern pattern, RoadStyle style) { this._style = style; this.voxel = tv; this._pattern = pattern; voxel.road = this; // voxel.roadを設定してからOnVoxelChangedイベントを投げないと // 地価の係数計算が正しくできない。(477) WorldDefinition.World.fireOnVoxelChanged(tv.Location); }
public static ElectricPole get(Location loc) { TrafficVoxel v = TrafficVoxel.get(loc); if (v == null) { return(null); } return(v.accessory as ElectricPole); }
/// <summary> /// Gets the Road object of the specified location, if any. /// Otherwise null. /// </summary> public static Road get(Location loc) { TrafficVoxel v = World.world[loc] as TrafficVoxel; if (v == null) { return(null); } return(v.road); }
public ThinPlatform(Location loc, Direction dir, int len) : base(loc, dir, len) { Debug.Assert(canBeBuilt(loc, dir, length)); for (int i = 0; i < len; i++, loc += dir) { bool hasRoof = (length / 4 <= i && i < length - length / 4); new RailRoadImpl(TrafficVoxel.getOrCreate(loc), this, i, hasRoof, plainPlatform); } }
private static void buildPassageway(Location loc1, Location loc2) { Direction dd = loc1.getDirectionTo(loc2); // direction Debug.Assert(dd.isSharp); // on each voxel along the way for (Location loc = loc1; ; loc = loc.toward(loc2)) { TrafficVoxel tv = TrafficVoxel.get(loc); if (tv != null) { if (tv.railRoad is ThinPlatform.RailRoadImpl) { ThinPlatform.RailRoadImpl rr = (ThinPlatform.RailRoadImpl)tv.railRoad; if (rr.outlook is ThinPlatform.PassagewayPlatform) { ThinPlatform.PassagewayPlatform ppp = (ThinPlatform.PassagewayPlatform)rr.outlook; if (ppp.hasBridge) { // if the passageway always has a bridge, keep it. } else { // if it has a partial passageway, make a bridge for it. rr.outlook = new ThinPlatform.PassagewayPlatform(true); } } else { // leave the end un-bridged. rr.outlook = new ThinPlatform.PassagewayPlatform( !((loc == loc1) && (dd.right90 == rr.direction) || (loc == loc2) && (dd.left90 == rr.direction))); } } else { // TODO: open-ended bridge } } else { // TODO: allow passageway to go over unused grounds } if (loc == loc2) { return; } } }
private void create(TrafficVoxel v, Direction d, byte[] heights) { Debug.Assert(d.isSharp); if (d.isParallelToY) { new TunnelRail(v, d, 1, heights); } else { new TunnelRail(v, d, 0, heights); } }
/// <summary> /// /// </summary> /// <param name="from"></param> /// <param name="to"></param> /// <returns></returns> public override bool CanBeBuilt(Location from, Location to) { if (from == to) { return(false); } if (from.z < WorldDefinition.World.WaterLevel) { return(false); // below the water level } Debug.Assert(from.z == to.z); Direction d = from.getDirectionTo(to); Location here = from; bool atLeastOneMountain = false; // there must be at least one water between two locations while (true) { if (WorldDefinition.World[here] != null) { if ((WorldDefinition.World[here] as MountainVoxel) != null) { atLeastOneMountain = true; } else { TrafficVoxel v = TrafficVoxel.get(here); if (v == null) { return(false); // occupied } if (v.railRoad == null) { return(false); // occupied by something other than RR } if (!v.railRoad.hasRail(d) || !v.railRoad.hasRail(d.opposite)) { return(false); // rail is running } } } if (here == to) { return(atLeastOneMountain); } here = here.toward(to); } }
internal TunnelRail(TrafficVoxel tv, Direction d, byte pictIdx, byte[] _heights) : base(tv, d) { this.pictureIndex = pictIdx; this.heights = _heights; if (d.index < 4) { sOrW = d.opposite; } else { sOrW = d; } }
/// <summary> Adds a new lane to this railroad. </summary> public void addLane(int idx) { Debug.Assert(canAddLane(idx)); YardRailRoad[] rr = new YardRailRoad[length]; lanes[idx] = rr; Location loc = getLaneBaseLocation(idx); for (int i = 0; i < length; i++, loc += direction) { // change to the new rail. rr[i] = new RailRoadImpl(TrafficVoxel.getOrCreate(loc), this, i); } }
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> /// Removes this platform from the world. /// </summary> public override void remove() { World world = World.world; onHostDisconnected(); Location loc = this.location; for (int i = 0; i < length; i++, loc += direction) { new SingleRailRoad( TrafficVoxel.get(loc), RailPattern.get(direction, direction.opposite)); } base.remove(); }
public new static Platform get(Location loc) { TrafficVoxel v = TrafficVoxel.get(loc); if (v == null) { return(null); } if (v.railRoad is RailRoadImpl) { return(((RailRoadImpl)v.railRoad).owner); } else { return(null); } }