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); } } }
/// <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); }