From: <ev...@us...> - 2011-06-21 21:25:57
|
Revision: 1581 http://rails.svn.sourceforge.net/rails/?rev=1581&view=rev Author: evos Date: 2011-06-21 21:25:49 +0000 (Tue, 21 Jun 2011) Log Message: ----------- Train management refactoring II - game Major overhaul of train management. TrainCertificateType describes buyable trains, single or dual TrainType describes a singe train type Train describes separate train certificate objects. It contains a reference to the current TrainType, which is null as long as it is owned by the Bank. Modified Paths: -------------- trunk/18xx/LocalisedText.properties trunk/18xx/rails/algorithms/NetworkTrain.java trunk/18xx/rails/algorithms/RevenueAdapter.java trunk/18xx/rails/algorithms/RevenueBonus.java trunk/18xx/rails/algorithms/RevenueBonusTemplate.java trunk/18xx/rails/game/OperatingRound.java trunk/18xx/rails/game/Portfolio.java trunk/18xx/rails/game/PublicCompany.java trunk/18xx/rails/game/Train.java trunk/18xx/rails/game/TrainI.java trunk/18xx/rails/game/TrainManager.java trunk/18xx/rails/game/TrainType.java trunk/18xx/rails/game/action/BuyTrain.java trunk/18xx/rails/game/model/TrainsModel.java trunk/18xx/rails/game/specific/_1856/CGRFormationRound.java trunk/18xx/rails/game/specific/_1856/PublicCompany_1856.java trunk/18xx/rails/game/specific/_1856/PublicCompany_CGR.java trunk/18xx/rails/game/specific/_18AL/NameableTrain.java trunk/18xx/rails/game/specific/_18EU/OperatingRound_18EU.java trunk/18xx/rails/game/state/GenericState.java trunk/18xx/rails/ui/swing/ORPanel.java trunk/18xx/rails/ui/swing/ORUIManager.java Added Paths: ----------- trunk/18xx/rails/game/TrainCertificateType.java Removed Paths: ------------- trunk/18xx/rails/game/TrainTypeI.java Modified: trunk/18xx/LocalisedText.properties =================================================================== --- trunk/18xx/LocalisedText.properties 2011-06-21 21:21:43 UTC (rev 1580) +++ trunk/18xx/LocalisedText.properties 2011-06-21 21:25:49 UTC (rev 1581) @@ -322,13 +322,10 @@ InvalidAction=Invalid action in this game InvalidAllocationTypeIndex=Invalid allocation type index: {0} InvalidBid=Invalid bid by {0} on {1}: {2} -InvalidCost=Invalid or zero cost specified InvalidDoneAction=Invalid Done action InvalidParPriceSetting=Invalid par price {0} set by {1} for {2}: {3} InvalidPass=Invalid pass by {0}: {1} -InvalidQuantity=Invalid quantity specified: {0} InvalidStartPrice=Invalid start price {0} for {1} -InvalidStops=Invalid or zero major stops specified InvalidTileColourName=Invalid colour name {1} for tile {0} InvalidTileLay=Invalid tile lay InvalidTrackEnd=Invalid track end @@ -401,7 +398,6 @@ NoIncomeForPreviousOperation={0} gets no income for {1}% {2} shares as precursors have operated NoMapMode=No map mode (for ftf play) NoMoney=Not enough money -NoNameSpecified=No name specified None=None NoPriceToSet=No price to be set # Texts with lowercase keys are intended to be inserted into other messages Modified: trunk/18xx/rails/algorithms/NetworkTrain.java =================================================================== --- trunk/18xx/rails/algorithms/NetworkTrain.java 2011-06-21 21:21:43 UTC (rev 1580) +++ trunk/18xx/rails/algorithms/NetworkTrain.java 2011-06-21 21:25:49 UTC (rev 1581) @@ -3,7 +3,7 @@ import org.apache.log4j.Logger; import rails.game.TrainI; -import rails.game.TrainTypeI; +import rails.game.TrainType; public final class NetworkTrain { @@ -118,7 +118,7 @@ return railsTrain; } - public TrainTypeI getRailsTrainType() { + public TrainType getRailsTrainType() { if (railsTrain == null) return null; return railsTrain.getType(); Modified: trunk/18xx/rails/algorithms/RevenueAdapter.java =================================================================== --- trunk/18xx/rails/algorithms/RevenueAdapter.java 2011-06-21 21:21:43 UTC (rev 1580) +++ trunk/18xx/rails/algorithms/RevenueAdapter.java 2011-06-21 21:25:49 UTC (rev 1581) @@ -22,7 +22,7 @@ import rails.game.PhaseI; import rails.game.PublicCompanyI; import rails.game.TrainI; -import rails.game.TrainTypeI; +import rails.game.TrainType; import rails.ui.swing.hexmap.HexMap; import rails.util.LocalText; @@ -172,10 +172,10 @@ } public boolean addTrainByString(String trainString) { - TrainTypeI trainType = gameManager.getTrainManager().getTypeByName(trainString.trim()); + TrainType trainType = gameManager.getTrainManager().getTypeByName(trainString.trim()); if (trainType != null) { // string defines available trainType log.info("RA: found trainType" + trainType); - TrainI railsTrain = gameManager.getTrainManager().cloneTrain(trainType); + TrainI railsTrain = gameManager.getTrainManager().cloneTrain(trainType.getCertificateType()); return addTrain(railsTrain); } else { // otherwise interpret the train NetworkTrain train = NetworkTrain.createFromString(trainString); Modified: trunk/18xx/rails/algorithms/RevenueBonus.java =================================================================== --- trunk/18xx/rails/algorithms/RevenueBonus.java 2011-06-21 21:21:43 UTC (rev 1580) +++ trunk/18xx/rails/algorithms/RevenueBonus.java 2011-06-21 21:25:49 UTC (rev 1581) @@ -10,7 +10,7 @@ import rails.game.PhaseI; import rails.game.TrainI; -import rails.game.TrainTypeI; +import rails.game.TrainType; public final class RevenueBonus { @@ -25,7 +25,7 @@ // internal attributes private List<NetworkVertex> vertices; - private List<TrainTypeI> trainTypes; + private List<TrainType> trainTypes; private List<TrainI> trains; private List<PhaseI> phases; @@ -34,7 +34,7 @@ this.name = name; vertices = new ArrayList<NetworkVertex>(); - trainTypes = new ArrayList<TrainTypeI>(); + trainTypes = new ArrayList<TrainType>(); trains = new ArrayList<TrainI>(); phases = new ArrayList<PhaseI>(); } @@ -47,7 +47,7 @@ this.vertices.addAll(vertices); } - public void addTrainType(TrainTypeI trainType) { + public void addTrainType(TrainType trainType) { trainTypes.add(trainType); } @@ -71,7 +71,7 @@ return vertices; } - public List<TrainTypeI> getTrainTypes() { + public List<TrainType> getTrainTypes() { return trainTypes; } Modified: trunk/18xx/rails/algorithms/RevenueBonusTemplate.java =================================================================== --- trunk/18xx/rails/algorithms/RevenueBonusTemplate.java 2011-06-21 21:21:43 UTC (rev 1580) +++ trunk/18xx/rails/algorithms/RevenueBonusTemplate.java 2011-06-21 21:25:49 UTC (rev 1581) @@ -12,7 +12,7 @@ import rails.game.PhaseI; import rails.game.PhaseManager; import rails.game.TrainManager; -import rails.game.TrainTypeI; +import rails.game.TrainType; import rails.util.Tag; /** @@ -117,7 +117,7 @@ private void convertTrainTypes(RevenueBonus bonus, TrainManager tm) { for (String identTrainType:identTrainTypes) { - TrainTypeI trainType = tm.getTypeByName(identTrainType); + TrainType trainType = tm.getTypeByName(identTrainType); if (trainType != null) { bonus.addTrainType(trainType); } Modified: trunk/18xx/rails/game/OperatingRound.java =================================================================== --- trunk/18xx/rails/game/OperatingRound.java 2011-06-21 21:21:43 UTC (rev 1580) +++ trunk/18xx/rails/game/OperatingRound.java 2011-06-21 21:25:49 UTC (rev 1581) @@ -58,8 +58,8 @@ /** A List per player with owned companies that have excess trains */ protected Map<Player, List<PublicCompanyI>> excessTrainCompanies = null; - protected List<TrainTypeI> trainsBoughtThisTurn = - new ArrayList<TrainTypeI>(4); + protected List<TrainCertificateType> trainsBoughtThisTurn = + new ArrayList<TrainCertificateType>(4); protected Map<PublicCompanyI, Integer> loansThisRound = null; @@ -1763,7 +1763,7 @@ //exchangedTrain = operatingCompany.getObject().getPortfolio().getTrainList().get(0); //action.setExchangedTrain(exchangedTrain); break; - } else if (operatingCompany.get().getPortfolio().getTrainOfType(exchangedTrain.getType()) == null) { + } else if (operatingCompany.get().getPortfolio().getTrainOfType(exchangedTrain.getCertType()) == null) { errMsg = LocalText.getText("CompanyDoesNotOwnTrain", operatingCompany.get().getName(), exchangedTrain.getName()); @@ -1812,7 +1812,7 @@ if (exchangedTrain != null) { TrainI oldTrain = operatingCompany.get().getPortfolio().getTrainOfType( - exchangedTrain.getType()); + exchangedTrain.getCertType()); oldTrain.moveTo(train.isObsolete() ? scrapHeap : pool); ReportBuffer.add(LocalText.getText("ExchangesTrain", companyName, @@ -1835,18 +1835,20 @@ stb.getOriginalCompany().getName() )); } + train.setType(action.getType()); // Needed for dual trains bought from the Bank + operatingCompany.get().buyTrain(train, price); if (oldHolder == ipo) { - train.getType().addToBoughtFromIPO(); + train.getCertType().addToBoughtFromIPO(); trainManager.setAnyTrainBought(true); // Clone the train if infinitely available - if (train.getType().hasInfiniteQuantity()) { - ipo.addTrain(trainManager.cloneTrain(train.getType())); + if (train.getCertType().hasInfiniteQuantity()) { + ipo.addTrain(trainManager.cloneTrain(train.getCertType())); } } if (oldHolder.getOwner() instanceof Bank) { - trainsBoughtThisTurn.add(train.getType()); + trainsBoughtThisTurn.add(train.getCertType()); } if (stb != null) { @@ -1957,6 +1959,11 @@ // if (action.isForced()) moveStack.linkToPreviousMoveSet(); + // Reset type of dual trains + if (train.getCertType().getPotentialTrainTypes().size() > 1) { + train.setType(null); + } + train.moveTo(train.isObsolete() ? scrapHeap : pool); ReportBuffer.add(LocalText.getText("CompanyDiscardsTrain", companyName, @@ -2623,7 +2630,7 @@ int cash = operatingCompany.get().getCash(); - int cost; + int cost = 0; List<TrainI> trains; boolean hasTrains = @@ -2650,24 +2657,30 @@ for (TrainI train : trains) { if (!operatingCompany.get().mayBuyTrainType(train)) continue; if (!mayBuyMoreOfEachType - && trainsBoughtThisTurn.contains(train.getType())) { + && trainsBoughtThisTurn.contains(train.getCertType())) { continue; } - cost = train.getCost(); - if (cost <= cash) { - if (canBuyTrainNow) { - BuyTrain action = new BuyTrain(train, ipo, cost); - action.setForcedBuyIfNoRoute(presidentMayHelp); // TEMPORARY - possibleActions.add(action); + + // Allow dual trains (since jun 2011) + List<TrainType> types = train.getCertType().getPotentialTrainTypes(); + for (TrainType type : types) { + cost = type.getCost(); + if (cost <= cash) { + if (canBuyTrainNow) { + BuyTrain action = new BuyTrain(train, type, ipo, cost); + action.setForcedBuyIfNoRoute(presidentMayHelp); // TEMPORARY + possibleActions.add(action); + } + } else if (costOfCheapestTrain == 0 + || cost < costOfCheapestTrain) { + cheapestTrain = train; + costOfCheapestTrain = cost; } - } else if (costOfCheapestTrain == 0 - || cost < costOfCheapestTrain) { - cheapestTrain = train; - costOfCheapestTrain = cost; } + // Even at train limit, exchange is allowed (per 1856) if (train.canBeExchanged() && hasTrains) { - cost = train.getType().getExchangeCost(); + cost = train.getCertType().getExchangeCost(); if (cost <= cash) { List<TrainI> exchangeableTrains = operatingCompany.get().getPortfolio().getUniqueTrains(); @@ -2683,8 +2696,8 @@ // Can a special property be used? // N.B. Assume that this never occurs in combination with - // a train exchange, otherwise the below code must be duplicated - // above. + // dual trains or train exchanges, + // otherwise the below code must be duplicated above. for (SpecialTrainBuy stb : getSpecialProperties(SpecialTrainBuy.class)) { int reducedPrice = stb.getPrice(cost); if (reducedPrice > cash) continue; @@ -2701,7 +2714,7 @@ trains = pool.getUniqueTrains(); for (TrainI train : trains) { if (!mayBuyMoreOfEachType - && trainsBoughtThisTurn.contains(train.getType())) { + && trainsBoughtThisTurn.contains(train.getCertType())) { continue; } cost = train.getCost(); @@ -2895,7 +2908,7 @@ if (getGameParameterAsBoolean(GameDef.Parm.REMOVE_TRAIN_BEFORE_SR) && trainManager.isAnyTrainBought()) { TrainI train = trainManager.getAvailableNewTrains().get(0); - if (train.getType().hasInfiniteQuantity()) return; + if (train.getCertType().hasInfiniteQuantity()) return; new ObjectMove (train, ipo, scrapHeap); ReportBuffer.add(LocalText.getText("RemoveTrain", train.getName())); } Modified: trunk/18xx/rails/game/Portfolio.java =================================================================== --- trunk/18xx/rails/game/Portfolio.java 2011-06-21 21:21:43 UTC (rev 1580) +++ trunk/18xx/rails/game/Portfolio.java 2011-06-21 21:25:49 UTC (rev 1581) @@ -51,8 +51,10 @@ /** Owned trains */ protected List<TrainI> trains = new ArrayList<TrainI>(); - protected Map<TrainTypeI, List<TrainI>> trainsPerType = - new HashMap<TrainTypeI, List<TrainI>>(); + protected Map<TrainType, List<TrainI>> trainsPerType = + new HashMap<TrainType, List<TrainI>>(); + protected Map<TrainCertificateType, List<TrainI>> trainsPerCertType = + new HashMap<TrainCertificateType, List<TrainI>>(); protected TrainsModel trainsModel = new TrainsModel(this); /** Owned tokens */ @@ -73,6 +75,8 @@ protected String name; /** Unique name (including owner class name) */ protected String uniqueName; + + GameManagerI gameManager; /** Specific portfolio names */ public static final String IPO_NAME = "IPO"; @@ -88,7 +92,8 @@ this.owner = holder; this.uniqueName = holder.getClass().getSimpleName() + "_" + name; - GameManager.getInstance().addPortfolio(this); + gameManager = GameManager.getInstance(); + gameManager.addPortfolio(this); if (owner instanceof PublicCompanyI) { trainsModel.setOption(TrainsModel.FULL_LIST); @@ -390,24 +395,33 @@ } public void addTrain (TrainI train) { - addTrain (train, new int[] {-1,-1}); + addTrain (train, new int[] {-1,-1,-1}); } public void addTrain(TrainI train, int[] position) { Util.addToList(trains, train, position[0]); - TrainTypeI type = train.getType(); + + TrainType type = train.getType(); if (!trainsPerType.containsKey(type)) { trainsPerType.put(type, new ArrayList<TrainI>()); } - Util.addToList(trainsPerType.get(train.getType()), train, position[1]); + Util.addToList(trainsPerType.get(type), train, position[1]); + + TrainCertificateType certType = train.getCertType(); + if (!trainsPerCertType.containsKey(certType)) { + trainsPerCertType.put(certType, new ArrayList<TrainI>()); + } + Util.addToList(trainsPerCertType.get(certType), train, position[2]); + train.setHolder(this); trainsModel.update(); } public void removeTrain(TrainI train) { trains.remove(train); - trainsPerType.get(train.getType()).remove(train); + trainsPerType.get(train.getPreviousType()).remove(train); + trainsPerCertType.get(train.getCertType()).remove(train); train.setHolder(null); trainsModel.update(); } @@ -436,7 +450,7 @@ return trains; } - public TrainI[] getTrainsPerType(TrainTypeI type) { + public TrainI[] getTrainsPerType(TrainType type) { List<TrainI> trainsFound = new ArrayList<TrainI>(); for (TrainI train : trains) { @@ -454,8 +468,8 @@ public List<TrainI> getUniqueTrains() { List<TrainI> trainsFound = new ArrayList<TrainI>(); - Map<TrainTypeI, Object> trainTypesFound = - new HashMap<TrainTypeI, Object>(); + Map<TrainType, Object> trainTypesFound = + new HashMap<TrainType, Object>(); for (TrainI train : trains) { if (!trainTypesFound.containsKey(train.getType())) { trainsFound.add(train); @@ -466,9 +480,9 @@ } - public TrainI getTrainOfType(TrainTypeI type) { + public TrainI getTrainOfType(TrainCertificateType type) { for (TrainI train : trains) { - if (train.getType() == type) return train; + if (train.getCertType() == type) return train; } return null; } @@ -478,19 +492,19 @@ * IPO. */ - public String makeAbbreviatedListOfTrains() { + public String makeListOfTrainCertificates() { if (trains == null || trains.isEmpty()) return ""; - StringBuffer b = new StringBuffer(); + StringBuilder b = new StringBuilder(); List<TrainI> trainsOfType; - for (TrainTypeI type : GameManager.getInstance().getTrainManager().getTrainTypes()) { - trainsOfType = trainsPerType.get(type); + for (TrainCertificateType certType : gameManager.getTrainManager().getTrainCertTypes()) { + trainsOfType = trainsPerCertType.get(certType); if (trainsOfType != null && !trainsOfType.isEmpty()) { if (b.length() > 0) b.append(" "); - b.append(type.getName()).append("("); - if (type.hasInfiniteQuantity()) { + b.append(certType.getName()).append("("); + if (certType.hasInfiniteQuantity()) { b.append("+"); } else { b.append(trainsOfType.size()); @@ -506,14 +520,14 @@ * Make a full list of trains, like "2 2 3 3", to show in any field * describing train possessions, except the IPO. */ - public String makeFullListOfTrains() { + public String makeListOfTrains() { if (trains == null || trains.isEmpty()) return ""; List<TrainI> trainsOfType; - StringBuffer b = new StringBuffer(); + StringBuilder b = new StringBuilder(); - for (TrainTypeI type : GameManager.getInstance().getTrainManager().getTrainTypes()) { + for (TrainType type : gameManager.getTrainManager().getTrainTypes()) { trainsOfType = trainsPerType.get(type); if (trainsOfType != null && !trainsOfType.isEmpty()) { for (TrainI train : trainsOfType) { @@ -603,7 +617,7 @@ addPrivate((PrivateCompanyI) object, position == null ? -1 : position[0]); return true; } else if (object instanceof TrainI) { - if (position == null) position = new int[] {-1, -1}; + if (position == null) position = new int[] {-1, -1, -1}; addTrain((TrainI) object, position); return true; } else if (object instanceof SpecialPropertyI) { @@ -654,7 +668,8 @@ TrainI train = (TrainI) object; return new int[] { trains.indexOf(train), - trainsPerType.get(train.getType()).indexOf(train) + train.getPreviousType() != null ? trainsPerType.get(train.getPreviousType()).indexOf(train) : -1, + trainsPerCertType.get(train.getCertType()).indexOf(train) }; } else if (object instanceof SpecialPropertyI) { return new int[] {specialProperties.indexOf(object)}; Modified: trunk/18xx/rails/game/PublicCompany.java =================================================================== --- trunk/18xx/rails/game/PublicCompany.java 2011-06-21 21:21:43 UTC (rev 1580) +++ trunk/18xx/rails/game/PublicCompany.java 2011-06-21 21:25:49 UTC (rev 1581) @@ -973,7 +973,7 @@ if (initialTrainType != null) { TrainManager trainManager = gameManager.getTrainManager(); - TrainTypeI type = trainManager.getTypeByName(initialTrainType); + TrainCertificateType type = trainManager.getCertTypeByName(initialTrainType); TrainI train = bank.getIpo().getTrainOfType(type); buyTrain(train, initialTrainCost); train.setTradeable(initialTrainTradeable); Modified: trunk/18xx/rails/game/Train.java =================================================================== --- trunk/18xx/rails/game/Train.java 2011-06-21 21:21:43 UTC (rev 1580) +++ trunk/18xx/rails/game/Train.java 2011-06-21 21:25:49 UTC (rev 1581) @@ -6,10 +6,16 @@ import rails.game.move.MoveableHolder; import rails.game.move.ObjectMove; import rails.game.state.BooleanState; +import rails.game.state.GenericState; public class Train implements TrainI { - protected TrainTypeI type; + protected TrainCertificateType certificateType; + + protected GenericState<TrainType> type; + + /** Temporary variable, only used during moves. */ + protected TrainType previousType = null; /** Some specific trains cannot be traded between companies */ protected boolean tradeable = true; @@ -24,14 +30,36 @@ public Train() {} - public void init(TrainTypeI type, String uniqueId) { + public void init(TrainCertificateType certType, TrainType type, String uniqueId) { - this.type = type; + this.certificateType = certType; this.uniqueId = uniqueId; + this.type = new GenericState<TrainType>(certType.getName()+"_CurrentType", type); + this.previousType = type; obsolete = new BooleanState(uniqueId, false); } + + public void setType (TrainType type) { + previousType = this.type.get(); + this.type.set(type); + } + /** + * @return Returns the type. + */ + public TrainCertificateType getCertType() { + return certificateType; + } + + public TrainType getType() { + return isAssigned() ? type.get() : null; + } + + public TrainType getPreviousType() { + return previousType; + } + public String getUniqueId() { return uniqueId; } @@ -40,53 +68,54 @@ * @return Returns the cityScoreFactor. */ public int getCityScoreFactor() { - return type.getCityScoreFactor(); + return getType().getCityScoreFactor(); } /** * @return Returns the cost. */ public int getCost() { - return type.getCost(); + return getType().getCost(); } /** * @return Returns the majorStops. */ public int getMajorStops() { - return type.getMajorStops(); + return getType().getMajorStops(); } /** * @return Returns the minorStops. */ public int getMinorStops() { - return type.getMinorStops(); + return getType().getMinorStops(); } /** * @return Returns the townCountIndicator. */ public int getTownCountIndicator() { - return type.getTownCountIndicator(); + return getType().getTownCountIndicator(); } /** * @return Returns the townScoreFactor. */ public int getTownScoreFactor() { - return type.getTownScoreFactor(); + return getType().getTownScoreFactor(); } - /** - * @return Returns the type. - */ - public TrainTypeI getType() { - return type; + public boolean isAssigned() { + return type.get() != null; } - + + public boolean isPermanent() { + return certificateType.isPermanent(); + } + public String getName() { - return type.getName(); + return isAssigned() ? type.get().getName() : certificateType.getName(); } public Portfolio getHolder() { @@ -123,7 +152,7 @@ } public boolean canBeExchanged() { - return type.nextCanBeExchanged(); + return certificateType.nextCanBeExchanged(); } public String toDisplay() { @@ -138,4 +167,11 @@ this.tradeable = tradeable; } + public String toString() { + StringBuilder b = new StringBuilder(uniqueId); + b.append(" certType=").append(getCertType()); + b.append(" type=").append(getType()); + b.append(" holder=").append(holder.getName()); + return b.toString(); + } } Added: trunk/18xx/rails/game/TrainCertificateType.java =================================================================== --- trunk/18xx/rails/game/TrainCertificateType.java (rev 0) +++ trunk/18xx/rails/game/TrainCertificateType.java 2011-06-21 21:25:49 UTC (rev 1581) @@ -0,0 +1,316 @@ +package rails.game; + +import java.util.*; + +import org.apache.log4j.Logger; + +import rails.game.state.BooleanState; +import rails.game.state.IntegerState; +import rails.util.*; + +public class TrainCertificateType { + + protected String name; + protected int quantity = 0; + protected boolean infiniteQuantity = false; + + protected String startedPhaseName = null; + // Phase startedPhase; + + protected List<TrainType> potentialTrainTypes = new ArrayList<TrainType>(2); + + protected Map<Integer, String> rustedTrainTypeNames = null; + protected Map<Integer, TrainCertificateType> rustedTrainType = null; + + protected boolean permanent = true; + protected boolean obsoleting = false; + + protected String releasedTrainTypeNames = null; + protected List<TrainCertificateType> releasedTrainTypes = null; + + protected boolean canBeExchanged = false; + protected int cost; + protected int exchangeCost; + + protected String trainClassName = "rails.game.Train"; + protected Class<? extends Train> trainClass; + + + protected int lastIndex = 0; + + // State variables + protected IntegerState numberBoughtFromIPO; + protected BooleanState available; + protected BooleanState rusted; + + // References + protected TrainManager trainManager; + + /** In some cases, trains start their life in the Pool */ + protected String initialPortfolio = "IPO"; + + protected static Logger log = + Logger.getLogger(TrainCertificateType.class.getPackage().getName()); + + public TrainCertificateType () { + } + + public void configureFromXML(Tag tag) throws ConfigurationException { + + trainClassName = tag.getAttributeAsString("class", trainClassName); + try { + trainClass = Class.forName(trainClassName).asSubclass(Train.class); + } catch (ClassNotFoundException e) { + throw new ConfigurationException("Class " + trainClassName + + "not found", e); + } + + // Name + name = tag.getAttributeAsString("name"); + + // Quantity + quantity = tag.getAttributeAsInteger("quantity", quantity); + quantity += tag.getAttributeAsInteger("quantityIncrement", 0); + + // Phase started + startedPhaseName = tag.getAttributeAsString("startPhase", ""); + + // Train type rusted + String rustedTrainTypeName1 = tag.getAttributeAsString("rustedTrain"); + if (Util.hasValue(rustedTrainTypeName1)) { + rustedTrainTypeNames = new HashMap<Integer, String>(); + rustedTrainTypeNames.put(1, rustedTrainTypeName1); + } + + // Other train type released for buying + releasedTrainTypeNames = tag.getAttributeAsString("releasedTrain"); + + // From where is this type initially available + initialPortfolio = + tag.getAttributeAsString("initialPortfolio", + initialPortfolio); + + // Configure any actions on other than the first train of a type + List<Tag> subs = tag.getChildren("Sub"); + if (subs != null) { + for (Tag sub : tag.getChildren("Sub")) { + int index = sub.getAttributeAsInteger("index"); + rustedTrainTypeName1 = sub.getAttributeAsString("rustedTrain"); + if (rustedTrainTypeNames == null) { + rustedTrainTypeNames = new HashMap<Integer, String>(); + } + rustedTrainTypeNames.put(index, rustedTrainTypeName1); + } + } + + // Exchangeable + Tag swapTag = tag.getChild("Exchange"); + if (swapTag != null) { + exchangeCost = swapTag.getAttributeAsInteger("cost", 0); + canBeExchanged = (exchangeCost > 0); + } + + // Can run as obsolete train + obsoleting = tag.getAttributeAsBoolean("obsoleting"); + + // Final initialisations + numberBoughtFromIPO = new IntegerState(name + "-trains_Bought", 0); + available = new BooleanState(name + "-trains_Available", false); + rusted = new BooleanState(name + "-trains_Rusted", false); + + } + + public void finishConfiguration (GameManagerI gameManager) + throws ConfigurationException { + + trainManager = gameManager.getTrainManager(); + + if (name == null) { + throw new ConfigurationException("No name specified for TrainType"); + } + + if (quantity == -1) { + infiniteQuantity = true; + } else if (quantity <= 0) { + throw new ConfigurationException("Invalid quantity "+quantity+" for train cert type "+name); + } + } + + public TrainI createTrain () throws ConfigurationException { + + TrainI train; + try { + train = trainClass.newInstance(); + } catch (InstantiationException e) { + throw new ConfigurationException( + "Cannot instantiate class " + trainClassName, e); + } catch (IllegalAccessException e) { + throw new ConfigurationException("Cannot access class " + + trainClassName + + "constructor", e); + } + return train; + } + + public List<TrainType> getPotentialTrainTypes() { + return potentialTrainTypes; + } + + protected void addPotentialTrainType (TrainType type) { + potentialTrainTypes.add(type); + } + + /** + * @return Returns the available. + */ + public boolean isAvailable() { + return available.booleanValue(); + } + + /** + * Make a train type available for buying by public companies. + */ + public void setAvailable() { + available.set(true); + } + + public void setRusted() { + rusted.set(true); + } + + public boolean hasRusted() { + return rusted.booleanValue(); + } + + /** + * @return Returns the name. + */ + public String getName() { + return name; + } + + /** + * @return Returns the releasedTrainTypeName. + */ + public String getReleasedTrainTypeNames() { + return releasedTrainTypeNames; + } + + /** + * @return Returns the rustedTrainTypeName. + */ + public Map<Integer,String> getRustedTrainTypeNames() { + return rustedTrainTypeNames; + } + + /** + * @param releasedTrainType The releasedTrainType to set. + */ + public void setReleasedTrainTypes(List<TrainCertificateType> releasedTrainTypes) { + this.releasedTrainTypes = releasedTrainTypes; + } + + /** + * @param rustedTrainType The rustedTrainType to set. + */ + public void setRustedTrainType(int index, TrainCertificateType rustedTrainType) { + if (this.rustedTrainType == null) { + this.rustedTrainType = new HashMap<Integer, TrainCertificateType>(); + } + this.rustedTrainType.put(index, rustedTrainType); + } + + public boolean isPermanent() { + return permanent; + } + + public boolean isObsoleting() { + return obsoleting; + } + + public void setPermanent(boolean permanent) { + this.permanent = permanent; + } + + /** + * @return Returns the releasedTrainTypes. + */ + public List<TrainCertificateType> getReleasedTrainTypes() { + return releasedTrainTypes; + } + + /** + * @return Returns the rustedTrainType. + */ + public TrainCertificateType getRustedTrainType(int index) { + if (rustedTrainType == null) return null; + return rustedTrainType.get(index); + } + + /** + * @return Returns the startedPhaseName. + */ + public String getStartedPhaseName() { + return startedPhaseName; + } + + public int getQuantity() { + return quantity; + } + + public boolean hasInfiniteQuantity() { + return infiniteQuantity; + } + + public boolean nextCanBeExchanged() { + return canBeExchanged; + } + + public void addToBoughtFromIPO() { + numberBoughtFromIPO.add(1); + } + + public int getNumberBoughtFromIPO() { + return numberBoughtFromIPO.intValue(); + } + + public int getCost() { + return cost; + } + + public int getExchangeCost() { + return exchangeCost; + } + + public String getInitialPortfolio() { + return initialPortfolio; + } + + public String getInfo() { + StringBuilder b = new StringBuilder ("<html>"); + b.append(LocalText.getText("TrainInfo", name, Bank.format(cost), quantity)); + if (Util.hasValue(startedPhaseName)) { + appendInfoText(b, LocalText.getText("StartsPhase", startedPhaseName)); + } + if (rustedTrainTypeNames != null) { + appendInfoText(b, LocalText.getText("RustsTrains", rustedTrainTypeNames.get(1))); + // Ignore any 'Sub' cases for now + } + if (releasedTrainTypeNames != null) { + appendInfoText(b, LocalText.getText("ReleasesTrains", releasedTrainTypeNames)); + } + if (b.length() == 6) b.append(LocalText.getText("None")); + + return b.toString(); + } + + private void appendInfoText (StringBuilder b, String text) { + if (text == null || text.length() == 0) return; + if (b.length() > 6) b.append("<br>"); + b.append(text); + } + + public String toString() { + return name; + } +} Property changes on: trunk/18xx/rails/game/TrainCertificateType.java ___________________________________________________________________ Added: svn:mime-type + text/plain Modified: trunk/18xx/rails/game/TrainI.java =================================================================== --- trunk/18xx/rails/game/TrainI.java 2011-06-21 21:21:43 UTC (rev 1580) +++ trunk/18xx/rails/game/TrainI.java 2011-06-21 21:25:49 UTC (rev 1581) @@ -5,7 +5,7 @@ public interface TrainI extends Moveable { - public void init(TrainTypeI type, String uniqueId); + public void init(TrainCertificateType certType, TrainType type, String uniqueId); /** * @return Returns the cost. @@ -38,10 +38,13 @@ */ public int getTownScoreFactor(); + public void setType (TrainType type); /** * @return Returns the train type. */ - public TrainTypeI getType(); + public TrainType getType(); + public TrainCertificateType getCertType(); + public TrainType getPreviousType(); public String getName(); @@ -52,6 +55,7 @@ public CashHolder getOwner(); public boolean isObsolete(); + public boolean isPermanent(); public void setHolder(Portfolio newHolder); Modified: trunk/18xx/rails/game/TrainManager.java =================================================================== --- trunk/18xx/rails/game/TrainManager.java 2011-06-21 21:21:43 UTC (rev 1580) +++ trunk/18xx/rails/game/TrainManager.java 2011-06-21 21:25:49 UTC (rev 1581) @@ -5,6 +5,7 @@ import org.apache.log4j.Logger; +import rails.game.move.ObjectMove; import rails.game.state.BooleanState; import rails.game.state.IntegerState; import rails.util.LocalText; @@ -12,25 +13,32 @@ public class TrainManager implements ConfigurableComponentI { // Static attributes - protected List<TrainTypeI> lTrainTypes = new ArrayList<TrainTypeI>(); + protected List<TrainType> lTrainTypes = new ArrayList<TrainType>(); - protected Map<String, TrainTypeI> mTrainTypes = - new HashMap<String, TrainTypeI>(); + protected Map<String, TrainType> mTrainTypes + = new HashMap<String, TrainType>(); - protected Map<String, TrainI> trainMap = - new HashMap<String, TrainI>(); + protected List<TrainCertificateType> trainCertTypes + = new ArrayList<TrainCertificateType>(); + + protected Map<String, TrainCertificateType> trainCertTypeMap + = new HashMap<String, TrainCertificateType>(); + + protected Map<String, TrainI> trainMap + = new HashMap<String, TrainI>(); - protected Map<TrainTypeI, List<TrainI>> trainsPerType = new HashMap<TrainTypeI, List<TrainI>>(); + protected Map<TrainCertificateType, List<TrainI>> trainsPerCertType + = new HashMap<TrainCertificateType, List<TrainI>>(); + protected TrainType defaultType = null; // Only required locally and in ChoiceType + private boolean removeTrain = false; // Dynamic attributes - protected Portfolio unavailable = null; - protected IntegerState newTypeIndex; - protected Map<TrainTypeI, Integer> lastIndexPerType = new HashMap<TrainTypeI, Integer>(); + protected Map<String, Integer> lastIndexPerType = new HashMap<String, Integer>(); protected boolean trainsHaveRusted = false; protected boolean phaseHasChanged = false; @@ -46,7 +54,7 @@ protected BooleanState anyTrainBought = new BooleanState ("AnyTrainBought", false); // Non-game attributes - protected Portfolio ipo = null; + protected Portfolio ipo, pool, unavailable; // For initialisation only boolean trainPriceAtFaceValueIfDifferentPresidents = false; @@ -66,31 +74,43 @@ * @see rails.game.ConfigurableComponentI#configureFromXML(org.w3c.dom.Element) */ public void configureFromXML(Tag tag) throws ConfigurationException { - TrainType defaultType = null; + TrainType newType; Tag defaultsTag = tag.getChild("Defaults"); - if (defaultsTag != null) { - defaultType = new TrainType(false); - defaultType.configureFromXML(defaultsTag); - } + // We will use this tag later, to preconfigure TrainCertType and TrainType. - List<Tag> typeTags = tag.getChildren("Train"); + List<Tag> typeTags; - for (Tag typeTag : typeTags) { - if (defaultType != null) { - newType = (TrainType) defaultType.clone(); - if (newType == null) { - throw new ConfigurationException("Cannot clone traintype " - + defaultType.getName()); + // Choice train types (new style) + List<Tag> trainTypeTags = tag.getChildren("TrainType"); + + if (trainTypeTags != null) { + for (Tag trainTypeTag : trainTypeTags) { + TrainCertificateType certType = new TrainCertificateType(); + if (defaultsTag != null) certType.configureFromXML(defaultsTag); + certType.configureFromXML(trainTypeTag); + trainCertTypes.add(certType); + trainCertTypeMap.put(certType.getName(), certType); + + // The potential train types + typeTags = trainTypeTag.getChildren("Train"); + if (typeTags == null) { + // That's OK, all properties are in TrainType, to let's reuse that tag + typeTags = Arrays.asList(trainTypeTag); } - } else { - newType = new TrainType(true); + for (Tag typeTag : typeTags) { + newType = new TrainType(); + if (defaultsTag != null) newType.configureFromXML(defaultsTag); + newType.configureFromXML(trainTypeTag); + newType.configureFromXML(typeTag); + lTrainTypes.add(newType); + mTrainTypes.put(newType.getName(), newType); + certType.addPotentialTrainType(newType); + } } - lTrainTypes.add(newType); - newType.configureFromXML(typeTag); - mTrainTypes.put(newType.getName(), newType); } + // Special train buying rules Tag rulesTag = tag.getChild("TrainBuyingRules"); @@ -99,54 +119,63 @@ trainPriceAtFaceValueIfDifferentPresidents = rulesTag.getChild("FaceValueIfDifferentPresidents") != null; } + // Are trains sold to foreigners? + Tag removeTrainTag = tag.getChild("RemoveTrainBeforeSR"); + if (removeTrainTag != null) { + // Trains "bought by foreigners" (1844, 1824) + removeTrain = true; // completed in finishConfiguration() + } + + } + + public void finishConfiguration (GameManagerI gameManager) + throws ConfigurationException { + this.gameManager = gameManager; + bank = gameManager.getBank(); + ipo = bank.getIpo(); + pool = bank.getPool(); + unavailable = bank.getUnavailable(); + // Finish initialisation of the train types Map<Integer, String> rustedTrainTypeNames; - TrainTypeI rustedType; - for (TrainTypeI type : lTrainTypes) { + TrainCertificateType rustedType; + for (TrainCertificateType type : trainCertTypes) { if (type.getReleasedTrainTypeNames() != null) { - List<TrainTypeI> rtts = new ArrayList<TrainTypeI>(2); + List<TrainCertificateType> rtts = new ArrayList<TrainCertificateType>(2); for (String ttName : type.getReleasedTrainTypeNames().split(",")) { - rtts.add (mTrainTypes.get(ttName)); + rtts.add (trainCertTypeMap.get(ttName)); } type.setReleasedTrainTypes(rtts); } rustedTrainTypeNames = type.getRustedTrainTypeNames(); if (rustedTrainTypeNames != null) { for (int index : rustedTrainTypeNames.keySet()) { - rustedType = mTrainTypes.get(rustedTrainTypeNames.get(index)); + rustedType = trainCertTypeMap.get(rustedTrainTypeNames.get(index)); type.setRustedTrainType(index, rustedType); rustedType.setPermanent(false); } } } - // Are trains sold to foreigners? - Tag removeTrainTag = tag.getChild("RemoveTrainBeforeSR"); - if (removeTrainTag != null) { - // Trains "bought by foreigners" (1844, 1824) - removeTrain = true; // completed in finishConfiguration() - } - - } - - public void finishConfiguration (GameManagerI gameManager) - throws ConfigurationException { - this.gameManager = gameManager; - bank = gameManager.getBank(); - ipo = bank.getIpo(); - unavailable = bank.getUnavailable(); - - for (TrainTypeI type : lTrainTypes) { - type.finishConfiguration(gameManager); + for (TrainCertificateType certType : trainCertTypes) { + certType.finishConfiguration(gameManager); + List<TrainType> types = certType.getPotentialTrainTypes(); + for (TrainType type : types) { + type.finishConfiguration(gameManager, certType); + } + // Now create the trains of this type TrainI train; - /* If the amount is infinite, only one trains is created. + // Multi-train certificates cannot yet be assigned a type + TrainType initialType = types.size() == 1 ? types.get(0) : null; + + /* If the amount is infinite, only one train is created. * Each time this train is bought, another one is created. */ - for (int i = 0; i < (type.hasInfiniteQuantity() ? 1 : type.getQuantity()); i++) { - train = type.createTrain (); - train.init(type, getNewUniqueId(type)); + for (int i = 0; i < (certType.hasInfiniteQuantity() ? 1 : certType.getQuantity()); i++) { + train = certType.createTrain (); + train.init(certType, initialType, getNewUniqueId(certType.getName())); addTrain(train); unavailable.addTrain(train); } @@ -155,7 +184,7 @@ // By default, set the first train type to "available". newTypeIndex.set(0); - lTrainTypes.get(newTypeIndex.intValue()).setAvailable(bank); + makeTrainAvailable(trainCertTypes.get(newTypeIndex.intValue())); // Trains "bought by foreigners" (1844, 1824) if (removeTrain) { @@ -172,14 +201,16 @@ * i.e. in cloning infinitely available trains. */ - public TrainI cloneTrain (TrainTypeI type) { + public TrainI cloneTrain (TrainCertificateType certType) { TrainI train = null; + List<TrainType> types = certType.getPotentialTrainTypes(); + TrainType initialType = types.size() == 1 ? types.get(0) : null; try { - train = type.createTrain(); + train = certType.createTrain(); } catch (ConfigurationException e) { log.warn("Unexpected exception", e); } - train.init(type, getNewUniqueId(type)); + train.init(certType, initialType, getNewUniqueId(certType.getName())); addTrain(train); return train; } @@ -187,27 +218,23 @@ public void addTrain (TrainI train) { trainMap.put(train.getUniqueId(), train); - TrainTypeI type = train.getType(); - if (!trainsPerType.containsKey(type)) { - trainsPerType.put (type, new ArrayList<TrainI>()); + TrainCertificateType type = train.getCertType(); + if (!trainsPerCertType.containsKey(type)) { + trainsPerCertType.put (type, new ArrayList<TrainI>()); } - trainsPerType.get(type).add(train); + trainsPerCertType.get(type).add(train); } public TrainI getTrainByUniqueId(String id) { return trainMap.get(id); } - public String getNewUniqueId (TrainTypeI type) { - int newIndex = lastIndexPerType.containsKey(type) ? lastIndexPerType.get(type) + 1 : 0; - lastIndexPerType.put (type, newIndex); - return type.getName() + "_"+ newIndex; + public String getNewUniqueId (String typeName) { + int newIndex = lastIndexPerType.containsKey(typeName) ? lastIndexPerType.get(typeName) + 1 : 0; + lastIndexPerType.put (typeName, newIndex); + return typeName + "_"+ newIndex; } - public List<TrainI> getTrainsOfType (TrainTypeI type) { - return trainsPerType.get(type); - } - /** * This method handles any consequences of new train buying (from the IPO), * such as rusting and phase changes. It must be called <b>after</b> the @@ -220,17 +247,17 @@ phaseHasChanged = false; if (from != ipo) return; - TrainTypeI boughtType, nextType; - boughtType = train.getType(); - if (boughtType == (lTrainTypes.get(newTypeIndex.intValue())) + TrainCertificateType boughtType, nextType; + boughtType = train.getCertType(); + if (boughtType == (trainCertTypes.get(newTypeIndex.intValue())) && ipo.getTrainOfType(boughtType) == null) { // Last train bought, make a new type available. newTypeIndex.add(1); if (newTypeIndex.intValue() < lTrainTypes.size()) { - nextType = (lTrainTypes.get(newTypeIndex.intValue())); + nextType = (trainCertTypes.get(newTypeIndex.intValue())); if (nextType != null) { if (!nextType.isAvailable()) { - nextType.setAvailable(bank); + makeTrainAvailable(nextType); trainAvailabilityChanged = true; ReportBuffer.add("All " + boughtType.getName() + "-trains are sold out, " @@ -252,11 +279,11 @@ phaseHasChanged = true; } - List<TrainTypeI> releasedTypes = boughtType.getReleasedTrainTypes(); + List<TrainCertificateType> releasedTypes = boughtType.getReleasedTrainTypes(); if (releasedTypes != null) { - for (TrainTypeI releasedType : releasedTypes) { + for (TrainCertificateType releasedType : releasedTypes) { if (!releasedType.isAvailable()) { - releasedType.setAvailable(bank); + makeTrainAvailable(releasedType); ReportBuffer.add(LocalText.getText("TrainsAvailable", releasedType.getName())); } @@ -265,10 +292,9 @@ } } - TrainTypeI rustedType = boughtType.getRustedTrainType(trainIndex); + TrainCertificateType rustedType = boughtType.getRustedTrainType(trainIndex); if (rustedType != null && !rustedType.hasRusted()) { - rustedType.setRusted(train.getHolder()); // Or obsolete, - // where applicable + rustTrainType (rustedType, train.getHolder()); if (rustedType.isObsoleting()) { ReportBuffer.add(LocalText.getText("TrainsObsolete", rustedType.getName())); @@ -280,14 +306,46 @@ trainAvailabilityChanged = true; } -} + } + + protected void makeTrainAvailable (TrainCertificateType type) { + type.setAvailable(); + + Portfolio to = + (type.getInitialPortfolio().equalsIgnoreCase("Pool") ? bank.getPool() + : bank.getIpo()); + + for (TrainI train : trainsPerCertType.get(type)) { + new ObjectMove(train, unavailable, to); + } + } + + protected void rustTrainType (TrainCertificateType type, Portfolio lastBuyingCompany) { + type.setRusted(); + for (TrainI train : trainsPerCertType.get(type)) { + Portfolio holder = train.getHolder(); + if (type.isObsoleting() && holder.getOwner() instanceof PublicCompanyI + && holder != lastBuyingCompany) { + log.debug("Train " + train.getUniqueId() + " (owned by " + + holder.getName() + ") obsoleted"); + train.setObsolete(); + holder.getTrainsModel().update(); + } else { + log.debug("Train " + train.getUniqueId() + " (owned by " + + holder.getName() + ") rusted"); + train.setRusted(); + } + } + + } + public List<TrainI> getAvailableNewTrains() { List<TrainI> availableTrains = new ArrayList<TrainI>(); TrainI train; - for (TrainTypeI type : lTrainTypes) { + for (TrainCertificateType type : trainCertTypes) { if (type.isAvailable()) { train = ipo.getTrainOfType(type); if (train != null) { @@ -299,25 +357,40 @@ } public String getTrainCostOverview() { - StringBuffer b = new StringBuffer(); - for (TrainTypeI type : lTrainTypes) { - if (b.length() > 1) b.append(" "); - b.append(type.getName()).append(":").append(Bank.format(type.getCost())); - if (type.getExchangeCost() > 0) { - b.append("(").append(Bank.format(type.getExchangeCost())).append(")"); + StringBuilder b = new StringBuilder(); + for (TrainCertificateType certType : trainCertTypes) { + if (certType.getCost() > 0) { + if (b.length() > 1) b.append(" "); + b.append(certType.getName()).append(":").append(Bank.format(certType.getCost())); + if (certType.getExchangeCost() > 0) { + b.append("(").append(Bank.format(certType.getExchangeCost())).append(")"); + } + } else { + for (TrainType type : certType.getPotentialTrainTypes()) { + if (b.length() > 1) b.append(" "); + b.append(type.getName()).append(":").append(Bank.format(type.getCost())); + } } } return b.toString(); } - public TrainTypeI getTypeByName(String name) { + public TrainType getTypeByName(String name) { return mTrainTypes.get(name); } - public List<TrainTypeI> getTrainTypes() { + public List<TrainType> getTrainTypes() { return lTrainTypes; } + public List<TrainCertificateType> getTrainCertTypes() { + return trainCertTypes; + } + + public TrainCertificateType getCertTypeByName (String name) { + return trainCertTypeMap.get(name); + } + public boolean hasAvailabilityChanged() { return trainAvailabilityChanged; } Modified: trunk/18xx/rails/game/TrainType.java =================================================================== --- trunk/18xx/rails/game/TrainType.java 2011-06-21 21:21:43 UTC (rev 1580) +++ trunk/18xx/rails/game/TrainType.java 2011-06-21 21:25:49 UTC (rev 1581) @@ -1,67 +1,38 @@ /* $Header: /Users/blentz/rails_rcs/cvs/18xx/rails/game/TrainType.java,v 1.32 2010/05/11 21:47:21 stefanfrey Exp $ */ package rails.game; -import java.util.*; - import org.apache.log4j.Logger; -import rails.game.move.ObjectMove; import rails.game.state.BooleanState; -import rails.game.state.IntegerState; import rails.util.*; -public class TrainType implements TrainTypeI { +public class TrainType implements Cloneable { public final static int TOWN_COUNT_MAJOR = 2; public final static int TOWN_COUNT_MINOR = 1; public final static int NO_TOWN_COUNT = 0; - protected String trainClassName = "rails.game.Train"; - protected Class<? extends Train> trainClass; - protected String name; - protected int quantity; - protected boolean infiniteQuantity = false; + protected TrainCertificateType certificateType; - private String reachBasis = "stops"; + protected String reachBasis = "stops"; protected boolean countHexes = false; - private String countTowns = "major"; + protected String countTowns = "major"; protected int townCountIndicator = TOWN_COUNT_MAJOR; - private String scoreTowns = "yes"; + protected String scoreTowns = "yes"; protected int townScoreFactor = 1; - private String scoreCities = "single"; + protected String scoreCities = "single"; protected int cityScoreFactor = 1; - protected boolean canBeExchanged = false; - protected IntegerState numberBoughtFromIPO; - - protected boolean obsoleting = false; - - protected boolean permanent = true; - - private boolean real; // Only to determine if top-level attributes must be - // read. - protected int cost; protected int majorStops; protected int minorStops; - protected int exchangeCost; - protected String startedPhaseName = null; - // Phase startedPhase; - - private Map<Integer, String> rustedTrainTypeNames = null; - protected Map<Integer, TrainTypeI> rustedTrainType = null; - - private String releasedTrainTypeNames = null; - protected List<TrainTypeI> releasedTrainTypes = null; - protected int lastIndex = 0; - protected BooleanState available; protected BooleanState rusted; protected TrainManager trainManager; @@ -76,96 +47,26 @@ * @param real False for the default type, else real. The default type does * not have top-level attributes. */ - public TrainType(boolean real) { - this.real = real; + public TrainType() { } /** * @see rails.game.ConfigurableComponentI#configureFromXML(org.w3c.dom.Element) */ public void configureFromXML(Tag tag) throws ConfigurationException { - trainClassName = tag.getAttributeAsString("class", trainClassName); - try { - trainClass = Class.forName(trainClassName).asSubclass(Train.class); - } catch (ClassNotFoundException e) { - throw new ConfigurationException("Class " + trainClassName - + "not found", e); - } - if (real) { - // Name - name = tag.getAttributeAsString("name"); - if (name == null) { - throw new ConfigurationException( - LocalText.getText("NoNameSpecified")); - } + // Name + name = tag.getAttributeAsString("name"); - // Cost - cost = tag.getAttributeAsInteger("cost"); - if (cost == 0) { - throw new ConfigurationException( - LocalText.getText("InvalidCost")); - } + // Cost + cost = tag.getAttributeAsInteger("cost"); - // Amount - quantity = tag.getAttributeAsInteger("quantity"); - if (quantity == -1) { - infiniteQuantity = true; - } else if (quantity <= 0) { - throw new ConfigurationException( - LocalText.getText("InvalidQuantity", String.valueOf(quantity))); - } else { - quantity += tag.getAttributeAsInteger("quantityIncrement", 0); - } + // Major stops + majorStops = tag.getAttributeAsInteger("majorStops"); - // Major stops - majorStops = tag.getAttributeAsInteger("majorStops"); - if (majorStops == 0) { - throw new ConfigurationException( - LocalText.getText("InvalidStops")); - } + // Minor stops + minorStops = tag.getAttributeAsInteger("minorStops"); - // Minor stops - minorStops = tag.getAttributeAsInteger("minorStops"); - - // Phase started - startedPhaseName = tag.getAttributeAsString("startPhase", ""); - - // Train type rusted - String rustedTrainTypeName1 = tag.getAttributeAsString("rustedTrain"); - if (Util.hasValue(rustedTrainTypeName1)) { - rustedTrainTypeNames = new HashMap<Integer, String>(); - rustedTrainTypeNames.put(1, rustedTrainTypeName1); - } - - // Other train type released for buying - releasedTrainTypeNames = tag.get... [truncated message content] |