/// <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);
            }
        }
Exemple #2
0
            /// <summary>
            ///
            /// </summary>
            /// <param name="state"></param>
            /// <returns></returns>
            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 (WorldDefinition.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);
                    }
                }
            }
Exemple #3
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 = TrainStates.Moving;

            return(true);
        }
Exemple #4
0
            /// <summary>
            ///
            /// </summary>
            public override void invalidateVoxel()
            {
                if (sOrW == null || !(RailRoad.get(this.Location + sOrW) is TunnelRail))
                {
                    WorldDefinition.World.OnVoxelUpdated(this.Location);
                }

                // otherwise no need to update the voxel since a train will be hidden by this tunnel
            }
Exemple #5
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));
        }
Exemple #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);
            }
        }
Exemple #7
0
        /// <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);
            }
        }
Exemple #8
0
        /// <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);

            for (; here != to; here = here.toward(to))
            {
                TunnelRail trr = RailRoad.get(here) as TunnelRail;
                if (trr != null && trr.hasRail(d))
                {
                    trr.remove();       // destroy it
                }
            }
        }
Exemple #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 - WorldDefinition.World.WaterLevel));
        }
        /// <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);
            }
        }
Exemple #11
0
        /// <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)
                {
                    MountainVoxel mv = WorldDefinition.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));
                        }

                        WorldDefinition.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);
            }
        }
Exemple #12
0
            /// <summary>
            ///
            /// </summary>
            /// <param name="dc"></param>
            /// <param name="pt"></param>
            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);
                }
            }
Exemple #13
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));
        }
Exemple #14
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="loc"></param>
 /// <returns></returns>
 public static new RailRoadImpl get(Location loc)
 {
     return(RailRoad.get(loc) as RailRoadImpl);
 }
 /// <summary>
 ///
 /// </summary>
 /// <param name="loc"></param>
 /// <returns></returns>
 public static new JunctionRailRoad get(Location loc)
 {
     return(RailRoad.get(loc) as JunctionRailRoad);
 }