Esempio n. 1
0
            public object onInside(CarState.Inside state)
            {
                TrainCar head = owner.head;
                RailRoad rr   = RailRoad.get(state.location);

                Direction go     = rr.guide();                  // angle to go
                Location  newLoc = state.location + go;

                newLoc.z += rr.zdiff(state.direction);

                if (World.world.isBorderOfWorld(newLoc))
                {
                    // go outside the world
                    return(new CarState.Outside(newLoc, go, OUTSIDE_COUNTER_INITIAL_VALUE));
                }
                else
                {
                    if (isConnected(newLoc, go))
                    {
                        // the rail needs to be connected
                        return(new CarState.Inside(newLoc, go));
                    }
                    else
                    {
                        return(null);
                    }
                }
            }
Esempio n. 2
0
        public override void remove(Location here, Location to)
        {
            if (here == to)
            {
                return;
            }

            Direction d = here.getDirectionTo(to);

            while (true)
            {
                BridgeRail brr = RailRoad.get(here) as BridgeRail;
                if (brr != null && brr.hasRail(d))
                {
                    // destroy it
                    brr.voxel.railRoad = null;
                    // TODO: delete piers

                    BridgePierVoxel.teardownBridgeSupport(here, TrafficVoxel.get(here));
                }

                if (here == to)
                {
                    return;
                }
                here = here.toward(to);
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Obtains a reference to the RailRoadImpl of the specified index.
        /// </summary>
        private RailRoadImpl getRailRoad(int idx)
        {
            Location loc = location;

            loc.x += direction.offsetX * idx;
            loc.y += direction.offsetY * idx;

            return((RailRoadImpl)RailRoad.get(loc));
        }
Esempio n. 4
0
        /// <summary> Place a train to the specified location.</summary>
        /// <returns> false if it can't be done. </returns>
        public bool place(Location loc)
        {
            Debug.Assert(!isPlaced);

            Direction[] ds   = new Direction[length];
            Location[]  locs = new Location[length];

            int idx = length;

            Direction d = null;

            do
            {
                idx--;

                RailRoad rr = RailRoad.get(loc);
                if (rr == null || rr.voxel.isOccupied)
                {
                    // can't be placed here
                    return(false);
                }
                if (d == null)
                {
                    d = rr.dir1;                                        // set the initial direction
                }
                ds[idx] = d; locs[idx] = loc;

                // determine the next voxel
                cars[0].place(loc, d);
                d    = rr.guide();
                loc += d;
                cars[0].remove();
            } while(idx != 0);

            // make sure we are not forming cycles
            for (int i = 0; i < length - 1; i++)
            {
                for (int j = i + 1; j < length; j++)
                {
                    if (locs[i] == locs[j])
                    {
                        return(false);                          // can't be placed
                    }
                }
            }
            // can be placed. place all
            for (int i = 0; i < length; i++)
            {
                cars[i].place(locs[i], ds[i]);
            }

            stopCallCount = 0;
            registerTimer();
            state = State.Moving;

            return(true);
        }
Esempio n. 5
0
            public override void invalidateVoxel()
            {
                if (sOrW == null || !(RailRoad.get(this.location + sOrW) is TunnelRail))
                {
                    World.world.onVoxelUpdated(this.location);
                }

                // otherwise no need to update the voxel since a train will be hidden by this tunnel
            }
Esempio n. 6
0
        /// <summary>
        /// Gets the SlopeRailRoad object of the specified location, if any.
        /// Otherwise null.
        /// </summary>
        public static new SlopeRailRoad get(Location loc)
        {
            RailRoad rr = RailRoad.get(loc);

            if (rr is SlopeRailRoad)
            {
                return((SlopeRailRoad)rr);
            }
            else
            {
                return(null);
            }
        }
Esempio n. 7
0
        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);
            }
        }
Esempio n. 8
0
        public override void remove(Location here, Location to)
        {
            if (here == to)
            {
                return;
            }

            Direction d = here.getDirectionTo(to);

            for ( ; here != to; here = here.toward(to))
            {
                TunnelRail trr = RailRoad.get(here) as TunnelRail;
                if (trr != null && trr.hasRail(d))
                {
                    trr.remove();                       // destroy it
                }
            }
        }
Esempio n. 9
0
        /// <summary>
        /// Compute the cost of destructing a slope rail.
        /// </summary>
        /// <returns>If a destruction is impossible, return 0</returns>
        public static int calcCostOfTearDownSlope(Location loc, Direction dir)
        {
            // make sure the first voxel is not occupied by a car
            if (Car.get(loc) != null)
            {
                return(0);
            }

            // the 2nd block has a distinctive zangle and zdiff. check it.
            loc += dir;
            RailRoad rr = RailRoad.get(loc);

            if (!(rr is SlopeRailRoad))
            {
                return(0);
            }
            SlopeRailRoad srr = (SlopeRailRoad)rr;

            if (!(srr.pattern.zangle == dir && srr.pattern.zdiff == 1))
            {
                return(0);
            }

            // make sure the 2nd rail is not occupied by a car
            if (Car.get(loc) != null)
            {
                return(0);
            }

            // check 3rd and 4th rails.
            loc += dir;
            loc.z++;
            if (Car.get(loc) != null)
            {
                return(0);
            }
            loc += dir;
            if (Car.get(loc) != null)
            {
                return(0);
            }

            return(SLOPE_DESTRUCTION_UNIT_COST * Math.Max(1, loc.z - World.world.waterLevel));
        }
Esempio n. 10
0
        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);
            }
        }
Esempio n. 11
0
        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)
                {
                    MountainVoxel mv = World.world[here] as MountainVoxel;
                    if (mv != null)
                    {
                        // build a tunnel
                        byte[] heights = new byte[4];
                        for (int i = 0; i < 4; i++)
                        {
                            heights[i] = (byte)mv.getHeight(Direction.get(i * 2 + 1));
                        }

                        World.world.remove(here);                               // remove this mountain

                        create(TrafficVoxel.getOrCreate(here), d, heights);
                    }
                    else
                    {
                        // build a normal tunnel
                        new SingleRailRoad(TrafficVoxel.getOrCreate(here), RailPattern.get(d, d.opposite));
                    }
                }
                if (here == to)
                {
                    return;
                }
                here = here.toward(to);
            }
        }
Esempio n. 12
0
 public static new RailRoadImpl get(Location loc)
 {
     return(RailRoad.get(loc) as RailRoadImpl);
 }
Esempio n. 13
0
            public override void draw(DrawContext dc, Point pt)
            {
                Surface display = dc.surface;

                pt.Y -= 9;                      // offset

                CarState.Inside s = state.asInside();
                Debug.Assert(s != null);

                RailRoad rr = s.voxel.railRoad;

                if (rr is SlopeRailRoad)                  // slope rail
                {
                    SlopeRailRoad srr = (SlopeRailRoad)rr;

                    switch (srr.level)                     // apply slope height
                    {
                    case 0: break;

                    case 1: pt.Y -= 4; break;

                    case 2: pt.Y += 8;      break;

                    case 3: pt.Y += 4; break;
                    }

                    if (!parent.isReversed)
                    {
                        type.drawSlope(display, pt, s.direction, s.direction == srr.climbDir);
                    }
                    else
                    {
                        type.drawSlope(display, pt, s.direction.opposite, s.direction != srr.climbDir);
                    }
                }
                else                     // level rail road
                {
                    int d1 = s.direction.index;
                    int d2 = s.voxel.railRoad.guide().index;

                    int angle;
                    if (d1 == d2)
                    {
                        angle = d1 * 2;
                    }
                    else
                    {
                        int diff = (d2 - d1) & 7;
                        if (diff == 7)
                        {
                            diff = -1;
                        }

                        int dd = (d2 * 2 + diff * 3) & 15;                      // operation is on modulo 16.

                        if (2 < dd && dd < 10)
                        {
                            pt.X += 3;
                        }
                        else
                        {
                            pt.X -= 3;
                        }

                        if (6 < dd && dd <= 14)
                        {
                            pt.Y += 2;
                        }
                        else
                        {
                            pt.Y -= 2;
                        }

                        angle = (d1 * 2 + diff) & 15;
                    }

                    if (parent.isReversed)
                    {
                        angle ^= 8;
                    }

                    type.draw(display, pt, angle);
                }
            }
Esempio n. 14
0
        /// <summary>
        /// Returns true if a train car can proceed to the
        /// specified location by going the specified direction
        /// </summary>
        private static bool isConnected(Location loc, Direction d)
        {
            RailRoad rr = RailRoad.get(loc);

            return(rr != null && rr.hasRail(d.opposite));
        }
Esempio n. 15
0
 public static new JunctionRailRoad get(Location loc)
 {
     return(RailRoad.get(loc) as JunctionRailRoad);
 }