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