diff --git a/Changelog.md b/Changelog.md index 79c61f3c1..600a84bdc 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,4 +1,4 @@ -# Rails-18xx 2.3 Release +# Rails-18xx 2.4 Release This release is meant to show the current state of the Rails-18xx implementation. Due to different reasons Rails-18xx 2.0 and 2.1 have not been release as production releases. We hope that the audience @@ -6,28 +6,31 @@ finds the release usefull. As usual we welcome bug reports and save games that s We would like to **thank** the various bug reporters and the developers who have contributed over the years for one feature or ground breaking work. +Please take note that to run Rails-18xx as a JAR directly you need to install a JDK with Java V11 as minimum. The game comes with its own JRE compiled in. +Please dont use the .bat from earlier versions. -## New Features +**Using the installer on Windows and the same directory as previous installations, will overwrite everything in that directory.** -* Notification of Moves via Slack -* Notification of Moves via Discord -* Autoloading and Autopolling for near time gaming allowing you to reload the save game that has changed during turns -* Direct Revenue Allocation for various Contracts possible - * State of Direct Revenue Allocation is static towards company operations budget (no Half pay) - Workaround you half the allocation and add the rest to normal revenue distribution - * Installers for Windows, Mac OS, Linux (Redhat) +We would like to **thank** the varios bug reporters and the developers who have contributed over the years for one feature or ground breaking work. ## New games * 18Scan -* Steam over Holland +* Steam over Holland implemented by Erik Vos. ## Status of Games - +* Implementation of 18Chesapeake started, needs playtesting, bug reports welcome +* Implementation of 1837 - Have a look but be prepared that it might break... + * Open Topics in 1837 Implementation: + * Coal Minors merging round implementation not always working as intended.. ## Bug Fixes - -* 1856 : Various Bugs -* 1835 : Berlin to Berlin not counts for revenue anymore -* 1880 : Fix for tile #235, Fix for Investor display, broken in 2.2.2 - +* Various svg-Tiles werent configured correctly which lead to graphic error while resizing or moving the map. Issue reported for 18NL/18TN by Lou Jerkich; Fixes done for 1837 1880 and 18Chesapeake + +## Issues fixed: + * #342 + * #338 + * #329 + * #326 + * #320 diff --git a/build.gradle b/build.gradle index 890275560..6ee37dd50 100644 --- a/build.gradle +++ b/build.gradle @@ -15,7 +15,7 @@ plugins { // https://openjfx.io/openjfx-docs/#gradle id 'org.openjfx.javafxplugin' version '0.0.9' // https://docs.sonarqube.org/latest/analysis/scan/sonarscanner-for-gradle/ - id 'org.sonarqube' version '3.0' + id 'org.sonarqube' version '3.1.1' // used by SonarQube for code coverage id 'jacoco' } diff --git a/src/main/java/net/sf/rails/algorithms/NetworkVertex.java b/src/main/java/net/sf/rails/algorithms/NetworkVertex.java index a4d616daa..4ed27ea0e 100644 --- a/src/main/java/net/sf/rails/algorithms/NetworkVertex.java +++ b/src/main/java/net/sf/rails/algorithms/NetworkVertex.java @@ -7,6 +7,7 @@ import net.sf.rails.game.*; import net.sf.rails.ui.swing.hexmap.*; +import net.sf.rails.util.Util; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -94,8 +95,7 @@ private NetworkVertex(VertexType type, String name) { /** factory method for virtual vertex */ public static NetworkVertex getVirtualVertex(VertexType type, String name) { - NetworkVertex vertex = new NetworkVertex(type, name); - return vertex; + return new NetworkVertex(type, name); } void addToRevenueCalculator(RevenueCalculator rc, int vertexId) { diff --git a/src/main/java/net/sf/rails/algorithms/RevenueAdapter.java b/src/main/java/net/sf/rails/algorithms/RevenueAdapter.java index ce2f0f74a..7c2a0e772 100644 --- a/src/main/java/net/sf/rails/algorithms/RevenueAdapter.java +++ b/src/main/java/net/sf/rails/algorithms/RevenueAdapter.java @@ -31,6 +31,9 @@ * RevenueAdapter links the revenue algorithm to Rails. */ public final class RevenueAdapter implements Runnable { + + int specialRevenue; + private static final Logger log = LoggerFactory.getLogger(RevenueAdapter.class); // define VertexVisitSet @@ -589,14 +592,22 @@ private List convertRcRun(int[][] rcRun) { public int calculateRevenue() { // allows (one) dynamic modifiers to have their own revenue calculation method - // TODO: Still to be added + // TODO: Still to be added - beware: it is used differently in 1837 + // (see RunToCoalMineModifier). // if (hasDynamicCalculator) { // return revenueManager.revenueFromDynamicCalculator(this); + // For 1837 we need to do both! + specialRevenue = revenueManager.revenueFromDynamicCalculator(this); // } else { // otherwise standard calculation - return calculateRevenue(0, trains.size() - 1); + return calculateRevenue(0, trains.size() - 1); // } } + // Another way to get the special revenue + public void setSpecialRevenue (int value) { + specialRevenue = value; + } + public int calculateRevenue(int startTrain, int finalTrain) { if (startTrain < 0 || finalTrain >= trains.size() || startTrain > finalTrain) { return 0; @@ -606,10 +617,15 @@ public int calculateRevenue(int startTrain, int finalTrain) { rc.initRuns(startTrain, finalTrain); rc.executePredictions(startTrain, finalTrain); int value = rc.calculateRevenue(startTrain, finalTrain); + return value; } - public List getOptimalRun() { + public int getSpecialRevenue() { + return specialRevenue; + } + + public List getOptimalRun() { if (optimalRun == null) { optimalRun = convertRcRun(rc.getOptimalRun()); if (hasDynamicModifiers) { @@ -630,6 +646,7 @@ int dynamicEvaluation() { int value = 0; if (hasDynamicModifiers) { value = revenueManager.evaluationValue(this.getCurrentRun(), false); + specialRevenue = revenueManager.getSpecialRevenue(); } return value; } @@ -649,14 +666,16 @@ public void addRevenueListener(RevenueListener listener) { this.revenueListener = listener; } - void notifyRevenueListener(final int revenue, final boolean finalResult) { + void notifyRevenueListener(final int revenue, final int specialRevenue, final boolean finalResult) { if (revenueListener == null) return; EventQueue.invokeLater( new Runnable() { public void run() { //listener could have deregistered himself in the meantime - if (revenueListener != null) revenueListener.revenueUpdate(revenue, finalResult); + if (revenueListener != null) { + revenueListener.revenueUpdate(revenue, specialRevenue, finalResult); + } } }); } diff --git a/src/main/java/net/sf/rails/algorithms/RevenueCalculator.java b/src/main/java/net/sf/rails/algorithms/RevenueCalculator.java index 1ddd01098..bf2bb4f33 100644 --- a/src/main/java/net/sf/rails/algorithms/RevenueCalculator.java +++ b/src/main/java/net/sf/rails/algorithms/RevenueCalculator.java @@ -53,6 +53,8 @@ abstract class RevenueCalculator { protected final int [] trainStartEdge; protected final int[] trainDistance; // keeps track of distance travelled (for H-trains) + int specialRevenue; + // static bonus data protected final int [] bonusValue; protected final boolean [][] bonusActiveForTrain; // dimensions: bonus x train @@ -264,14 +266,14 @@ final String getStatistics() { return statistics.toString(); } - private void notifyRevenueAdapter(final int revenue, final boolean finalResult) { + private void notifyRevenueAdapter(final int revenue, final int specialRevenue, final boolean finalResult) { String modifier; if (finalResult) modifier = "final"; else modifier = "new best"; log.debug("Report {} result of {} after {}", modifier, revenue, getStatistics()); - revenueAdapter.notifyRevenueListener(revenue, finalResult); + revenueAdapter.notifyRevenueListener(revenue, specialRevenue, finalResult); } private int[] bestRevenues(final int[] values, final int length) { @@ -399,7 +401,7 @@ final int calculateRevenue(final int startTrain, final int finalTrain) { runTrain(startTrain); // inform revenue listener via adapter - notifyRevenueAdapter(currentBestValue, true); + notifyRevenueAdapter(currentBestValue, specialRevenue, true); return currentBestValue; } @@ -526,7 +528,10 @@ protected final void evaluateResults() { // } } - if (callDynamicModifiers) totalValue += revenueAdapter.dynamicEvaluation(); + if (callDynamicModifiers) { + totalValue += revenueAdapter.dynamicEvaluation(); + specialRevenue = revenueAdapter.getSpecialRevenue(); + } nbEvaluations++; log.debug("RC: current total value {}", totalValue); @@ -547,7 +552,8 @@ protected final void evaluateResults() { } log.debug("RC: Found better run with {}", totalValue); // inform revenue listener via adapter - notifyRevenueAdapter(currentBestValue, false); + // special revenue only to be reported with the final result + notifyRevenueAdapter(currentBestValue, specialRevenue, false); } } diff --git a/src/main/java/net/sf/rails/algorithms/RevenueCalculatorModifier.java b/src/main/java/net/sf/rails/algorithms/RevenueCalculatorModifier.java index a8de246db..ad2c44cc3 100644 --- a/src/main/java/net/sf/rails/algorithms/RevenueCalculatorModifier.java +++ b/src/main/java/net/sf/rails/algorithms/RevenueCalculatorModifier.java @@ -7,8 +7,8 @@ public interface RevenueCalculatorModifier { * If several dynamic modifier have their own method, their prediction values are added up. * @return optimal value */ - public int calculateRevenue(RevenueAdapter revenueAdpater); + public int calculateRevenue(RevenueAdapter revenueAdapter); - + public int getSpecialRevenue(); } diff --git a/src/main/java/net/sf/rails/algorithms/RevenueListener.java b/src/main/java/net/sf/rails/algorithms/RevenueListener.java index 01fbd338b..2b3bc1204 100644 --- a/src/main/java/net/sf/rails/algorithms/RevenueListener.java +++ b/src/main/java/net/sf/rails/algorithms/RevenueListener.java @@ -1,5 +1,5 @@ package net.sf.rails.algorithms; public interface RevenueListener { - public void revenueUpdate(int revenue, boolean finalResult); + public void revenueUpdate(int revenue, int specialRevenue, boolean finalResult); } diff --git a/src/main/java/net/sf/rails/algorithms/RevenueManager.java b/src/main/java/net/sf/rails/algorithms/RevenueManager.java index b07d0a4b5..8e016c38c 100644 --- a/src/main/java/net/sf/rails/algorithms/RevenueManager.java +++ b/src/main/java/net/sf/rails/algorithms/RevenueManager.java @@ -25,6 +25,8 @@ */ public final class RevenueManager extends RailsManager implements Configurable { + private int specialRevenue; + private static final Logger log = LoggerFactory.getLogger(RevenueManager.class); // Modifiers that are configurable @@ -200,6 +202,8 @@ boolean initDynamicModifiers(RevenueAdapter revenueAdapter) { * @return revenue from active calculator */ // FIXME: This does not fully cover all cases that needs the revenue from the calculator + // EV: indeed, it used in a different way in 1837, so beware! + // See RunToCoalMineModifier. int revenueFromDynamicCalculator(RevenueAdapter revenueAdapter) { return calculatorModifier.calculateRevenue(revenueAdapter); @@ -229,9 +233,16 @@ int evaluationValue(List run, boolean optimal) { for (RevenueDynamicModifier modifier : activeDynamicModifiers) { value += modifier.evaluationValue(run, optimal); } + if (calculatorModifier != null) { + specialRevenue = calculatorModifier.getSpecialRevenue(); + } return value; } + public int getSpecialRevenue () { + return specialRevenue; + } + /** * @return total prediction value of dynamic modifiers */ diff --git a/src/main/java/net/sf/rails/common/GuiDef.java b/src/main/java/net/sf/rails/common/GuiDef.java index 51fc24c06..f84280aa9 100644 --- a/src/main/java/net/sf/rails/common/GuiDef.java +++ b/src/main/java/net/sf/rails/common/GuiDef.java @@ -42,7 +42,8 @@ public enum Parm { NO_MAP_MODE, REVENUE_SUGGEST, ROUTE_HIGHLIGHT, - PLAYER_ORDER_VARIES, HAS_SPECIAL_COMPANY_INCOME + PLAYER_ORDER_VARIES, + HAS_SPECIAL_COMPANY_INCOME } /** diff --git a/src/main/java/net/sf/rails/common/parser/Tag.java b/src/main/java/net/sf/rails/common/parser/Tag.java index f54e3bd7f..9011c0266 100644 --- a/src/main/java/net/sf/rails/common/parser/Tag.java +++ b/src/main/java/net/sf/rails/common/parser/Tag.java @@ -276,18 +276,24 @@ private void parseSubTags(Element element) throws ConfigurationException { value = attribute.getNodeValue(); attributes.put(name, value); } - } else if ( "IfOption".equalsIgnoreCase(childTagName)) { - Node nameAttr = nnp.getNamedItem("name"); - if (nameAttr == null) - throw new ConfigurationException( - "IfOption has no optionName attribute"); - name = nameAttr.getNodeValue(); - - Node parmAttr = nnp.getNamedItem("parm"); - if (parmAttr != null) { - value = parmAttr.getNodeValue(); - Iterable parameters = Splitter.on(XMLTags.VALUES_DELIM).split(value); - name = GameOption.constructParameterisedName(name, ImmutableList.copyOf(parameters)); + } else if ("IfOption".equalsIgnoreCase(childTagName) + || "IfVariant".equalsIgnoreCase(childTagName)) { + + if ("IfOption".equalsIgnoreCase(childTagName)) { + Node nameAttr = nnp.getNamedItem("name"); + if (nameAttr == null) + throw new ConfigurationException( + "IfOption has no optionName attribute"); + name = nameAttr.getNodeValue(); + + Node parmAttr = nnp.getNamedItem("parm"); + if (parmAttr != null) { + value = parmAttr.getNodeValue(); + Iterable parameters = Splitter.on(XMLTags.VALUES_DELIM).split(value); + name = GameOption.constructParameterisedName(name, ImmutableList.copyOf(parameters)); + } + } else { // IfVariant + name = "Variant"; } Node valueAttr = nnp.getNamedItem("value"); diff --git a/src/main/java/net/sf/rails/game/GameManager.java b/src/main/java/net/sf/rails/game/GameManager.java index 18963f0e7..15e54d455 100644 --- a/src/main/java/net/sf/rails/game/GameManager.java +++ b/src/main/java/net/sf/rails/game/GameManager.java @@ -591,9 +591,9 @@ protected void beginStartRound() { protected void createStartRound(StartPacket startPacket) { String startRoundClassName = startPacket.getRoundClassName(); + startRoundNumber.add(1); StartRound startRound = createRound(startRoundClassName, "startRound_" + startRoundNumber.value()); - startRoundNumber.add(1); startRound.start(); } diff --git a/src/main/java/net/sf/rails/game/OperatingRound.java b/src/main/java/net/sf/rails/game/OperatingRound.java index 8e427c383..bd4febc4b 100644 --- a/src/main/java/net/sf/rails/game/OperatingRound.java +++ b/src/main/java/net/sf/rails/game/OperatingRound.java @@ -2546,68 +2546,89 @@ protected void executeSetRevenueAndDividend(SetDividend action) { protected void executeSetRevenueAndDividend(SetDividend action, String report) { - int amount = action.getActualRevenue(); + int earnings = action.getActualRevenue(); + int specialRevenue = action.getActualCompanyTreasuryRevenue(); + + PublicCompany company = operatingCompany.value(); // Sometimes there still is a payout; if so, the action will be updated - //if (amount == 0) action = checkZeroRevenue(action); + // TODO: no need to comment this out? See 18Scan. + //if (earnings == 0) action = checkZeroRevenue(action); int revenueAllocation = action.getRevenueAllocation(); - operatingCompany.value().setLastRevenue(amount); - operatingCompany.value().setLastRevenueAllocation(revenueAllocation); + company.setLastRevenue(earnings); + company.setLastRevenueAllocation(revenueAllocation); // Pay any debts from treasury, revenue and/or president's cash // The remaining dividend may be less that the original income - amount = executeDeductions(action); + earnings = executeDeductions(action); - if (amount == 0) { + // Assign any income that goes to the company. + // The dividend may be changed! + int dividend = processSpecialRevenue(earnings, specialRevenue); + company.setLastRevenue(earnings); + + if (dividend == 0) { if (report == null) report = LocalText.getText ( "CompanyDoesNotPayDividend", - operatingCompany.value().getId()); + company.getId()); ReportBuffer.add(this, report); - withhold(amount); + withhold(dividend); } else if (revenueAllocation == SetDividend.PAYOUT) { if (report == null) report = LocalText.getText ( "CompanyPaysOutFull", - operatingCompany.value().getId(), - Bank.format(this, amount)); + company.getId(), + Bank.format(this, dividend)); ReportBuffer.add(this, report); - payout(amount); + payout(dividend); } else if (revenueAllocation == SetDividend.SPLIT) { if (report == null) report = LocalText.getText ( "CompanySplits", - operatingCompany.value().getId(), - Bank.format(this, amount)); + company.getId(), + Bank.format(this, dividend)); ReportBuffer.add(this, report); - splitRevenue(amount); + splitRevenue(dividend); } else if (revenueAllocation == SetDividend.WITHHOLD) { if (report == null) report = LocalText.getText ( "CompanyWithholds", - operatingCompany.value().getId(), - Bank.format(this, amount)); + company.getId(), + Bank.format(this, dividend)); ReportBuffer.add(this, report); - withhold(amount); + withhold(dividend); } // Rust any obsolete trains - operatingCompany.value().getPortfolioModel().rustObsoleteTrains(); + company.getPortfolioModel().rustObsoleteTrains(); // We have done the payout step, so continue from there nextStep(GameDef.OrStep.PAYOUT); } /** - * Distribute the dividend amongst the shareholders. - * - * @param amount The dividend to be payed out + * Process any special revenue, adapting the dividend as required. + * Default version: dividend = earnings. + * To be overridden if any special revenue must be processed. + * @param earnings The total income from train runs. + * @param specialRevenue Any income that needs special processing. + * @return The resulting dividend (default: equal to the earnings). */ + protected int processSpecialRevenue(int earnings, int specialRevenue) { + return earnings; + } + + /** + * Distribute the dividend amongst the shareholders. + * + * @param amount The dividend to be payed out + */ public void payout(int amount) { if (amount == 0) return; @@ -3348,9 +3369,16 @@ public void setBuyableTrains() { action.setTrainsForExchange(exchangeableTrains); // if (atTrainLimit) action.setForcedExchange(true); possibleActions.add(action); - canBuyTrainNow = true; } } + + // In some games (e.g. 1837) trains can be voluntary discarded + // at train limit by a different mechanism. + // Assumption: restricted to when buying new trains. + if (hasTrains && !train.canBeExchanged() && !isBelowTrainLimit()) { + addOtherExchangesAtTrainLimit(company, train); + } + } if (!canBuyTrainNow) return; @@ -3505,6 +3533,9 @@ public void setBuyableTrains() { } } + protected void addOtherExchangesAtTrainLimit(PublicCompany company, Train train) { + } + /** * Calculate the potential contribution of selling any treasury * shares of a given company to pay for an "emergency" train. diff --git a/src/main/java/net/sf/rails/game/PublicCompany.java b/src/main/java/net/sf/rails/game/PublicCompany.java index 602a82edf..8bd51e594 100644 --- a/src/main/java/net/sf/rails/game/PublicCompany.java +++ b/src/main/java/net/sf/rails/game/PublicCompany.java @@ -157,6 +157,8 @@ public class PublicCompany extends RailsAbstractItem implements Company, RailsMo public final CountingMoneyModel directIncomeRevenue = CountingMoneyModel.create(this, "directIncome", false); + public final CountingMoneyModel lastDividend = CountingMoneyModel.create (this, "lastDividend", false); + /** * Most recent Direct Company Treasury income earned. */ @@ -423,6 +425,8 @@ public PublicCompany(RailsItem parent, String id) { public PublicCompany(RailsItem parent, String id, boolean hasStockPrice) { super(parent, id); lastRevenue.setSuppressInitialZero(true); + lastDirectIncome.setSuppressZero(true); + lastDividend.setSuppressZero(true); /* Spendings in the current operating turn */ privatesCostThisTurn.setSuppressZero(true); @@ -1368,10 +1372,14 @@ public PublicCertificate getPresidentsShare() { /** * Store the last revenue earned by this company. * - * @param i The last revenue amount. + * @param amount The last revenue amount. */ - public void setLastRevenue(int i) { - lastRevenue.set(i); + public void setLastRevenue(int amount) { + lastRevenue.set(amount); + } + + public void setLastDividend (int amount) { + lastDividend.set (amount); } /** @@ -1387,6 +1395,14 @@ public Model getLastRevenueModel() { return lastRevenue; } + public int getLastDividend() { + return lastDividend.value(); + } + + public Model getLastDividendModel () { + return lastDividend; + } + /** * Last revenue allocation (payout, split, withhold) */ @@ -2278,10 +2294,10 @@ public Model getLastDirectIncomeModel() { /** * Store the last direct Income earned by this company. * - * @param i The last revenue amount. + * @param amount The last revenue amount. */ - public void setLastDirectIncome(int i) { - lastDirectIncome.set(i); + public void setLastDirectIncome(int amount) { + lastDirectIncome.set(amount); } /** diff --git a/src/main/java/net/sf/rails/game/StartItem.java b/src/main/java/net/sf/rails/game/StartItem.java index 3ecae4193..463e2106f 100644 --- a/src/main/java/net/sf/rails/game/StartItem.java +++ b/src/main/java/net/sf/rails/game/StartItem.java @@ -37,6 +37,10 @@ public class StartItem extends RailsAbstractItem { protected int column = 0; protected int index; + // To allow the displayed name to include both primary and secondary. + // Default is the primary name (id) only. + protected String displayName = null; + // Bids protected final GenericState lastBidder = new GenericState<>(this, "lastBidder"); protected final Map bids = Maps.newHashMap(); @@ -271,6 +275,14 @@ public Certificate getSecondary() { return secondary; } + public String getDisplayName() { + return (displayName != null ? displayName : getId()); + } + + public void setDisplayName(String displayName) { + this.displayName = displayName; + } + /** * Get the start item base price. * diff --git a/src/main/java/net/sf/rails/game/StartPacket.java b/src/main/java/net/sf/rails/game/StartPacket.java index 55352d925..f24a16b73 100644 --- a/src/main/java/net/sf/rails/game/StartPacket.java +++ b/src/main/java/net/sf/rails/game/StartPacket.java @@ -30,6 +30,14 @@ public class StartPacket extends RailsAbstractItem { protected int minimumIncrement = 5; /** The modulus of all bids (i.e. of which value the bid must be a multiple) */ protected int modulus = 5; + /** Is multiple-column display enabled? + * If so, row and col attributes become mandatory for all start items + * (if the tag precedes all start items).*/ + protected boolean multipleColumns = false; + /** The number of columns. Will be derived from the column attributes. */ + protected int numberOfColumns = 1; + /** The number of rows. Will be derived from the row attributes, if multipleColumns is true. */ + protected int numberOfRows; /** Default name */ public static final String DEFAULT_ID = "Initial"; @@ -56,6 +64,12 @@ public static StartPacket create(RailsItem parent, String id, String roundClassN * @throws ConfigurationException if anything goes wrong. */ public void configureFromXML(Tag tag) throws ConfigurationException { + + // Multiple column display? + Tag columnsTag = tag.getChild("MultipleColumns"); + multipleColumns = columnsTag != null; + + // Bidding parameters, if applicable Tag biddingTag = tag.getChild("Bidding"); if (biddingTag != null) { minimumInitialIncrement = @@ -83,14 +97,27 @@ public void configureFromXML(Tag tag) throws ConfigurationException { int basePrice = itemTag.getAttributeAsInteger("basePrice", 0); boolean reduceable = itemTag.getAttributeAsBoolean("reduceable", false); - StartItem item = StartItem.create(this, itemName, itemType, basePrice, reduceable, index++, president); + StartItem item = StartItem.create(this, itemName, itemType, + basePrice, reduceable, index++, president); items.add(item); // Optional attributes int row = itemTag.getAttributeAsInteger("row", 0); - if (row > 0) item.setRow(row); + item.setRow(row); int column = itemTag.getAttributeAsInteger("column", 0); - if (column > 0) item.setColumn(column); + if (multipleColumns) { + if (!(row > 0 && column > 0)) { + throw new ConfigurationException( + "With multiple columns, both row and column attributes are required"); + } + item.setColumn(column); + numberOfRows = Math.max (numberOfRows, row); + numberOfColumns = Math.max (numberOfColumns, column); + } + + // Displayed name + String displayName = itemTag.getAttributeAsString("displayName", null); + if (displayName != null) item.setDisplayName(displayName); // Check if there is another certificate List subItemTags = itemTag.getChildren("SubItem"); @@ -241,4 +268,15 @@ public int getModulus() { return modulus; } + public boolean isMultipleColumns() { + return multipleColumns; + } + + public int getNumberOfColumns() { + return numberOfColumns; + } + + public int getNumberOfRows() { + return numberOfRows; + } } diff --git a/src/main/java/net/sf/rails/game/StartRound.java b/src/main/java/net/sf/rails/game/StartRound.java index c2022d374..6d3248d1d 100644 --- a/src/main/java/net/sf/rails/game/StartRound.java +++ b/src/main/java/net/sf/rails/game/StartRound.java @@ -106,6 +106,10 @@ public void start() { startPlayer.getId())); } + public int getStartRoundNumber() { + return gameManager.getStartRoundNumber(); + } + @Override public boolean process(PossibleAction action) { boolean result = false; diff --git a/src/main/java/net/sf/rails/game/Stop.java b/src/main/java/net/sf/rails/game/Stop.java index d5279c7fa..10e8b6f80 100644 --- a/src/main/java/net/sf/rails/game/Stop.java +++ b/src/main/java/net/sf/rails/game/Stop.java @@ -294,7 +294,7 @@ public boolean isRunThroughAllowedFor(PublicCompany company) { public int getValueForPhase(Phase phase) { int fixedValue = relatedStation.value().getValue(); - if (getParent().hasValuesPerPhase() && fixedValue == 0) { + if (getParent().hasValuesPerPhase() && fixedValue <= 0) { // Don't override a fixed value defined on the tile. // This matters for 1837 hex J34, which has // a fixed town value and a phase-dependent mine value (ZKB). diff --git a/src/main/java/net/sf/rails/game/TileUpgrade.java b/src/main/java/net/sf/rails/game/TileUpgrade.java index bbc3db665..72d424246 100644 --- a/src/main/java/net/sf/rails/game/TileUpgrade.java +++ b/src/main/java/net/sf/rails/game/TileUpgrade.java @@ -104,7 +104,7 @@ public boolean isSymmetric() { @Override public String toString() { - return new StringBuilder().append("rotation = ").append(rotation).append(", connectedSides = "). + return new StringBuilder("rotation = ").append(rotation).append(", connectedSides = "). append(connectedSides.toString()).append(", sidesWithNewTrack = ").append(sidesWithNewTrack.toString()). append(", stationMapping = ").append(stationMapping).append(", stationsWithNewTrack = ").append(stationsWithNewTrack).toString(); } @@ -231,8 +231,7 @@ public boolean isAllowedForHex(MapHex hex) { } public boolean isAllowedForPhase(Phase phase) { - if (allowedPhases != null - && !allowedPhases.contains(phase)) { + if (allowedPhases != null && !allowedPhases.contains(phase)) { return false; } else { return true; @@ -384,12 +383,13 @@ private Rotation processRotations(HexSide side) { log.debug("base={} target={}", base, target); } // check if there are stations to map - Map stationMapping = assignStations(base, target); + Map stationMapping = assignStations(base, target); // Try something else: match sides with old and new Stations in a simple way // Each pair of stations that matches with the same side is connected. // This finally appears to work for the 1837 green Vienna upgrade. // Though it may only work where both base and target tiles have a fixed orientation. + // (may be obsolete, now that automatic relay works better (see issue #341). if (stationMapping == null) { stationMapping = new HashMap<>(6); Station b, t; @@ -507,8 +507,11 @@ private Map assignStations(TrackConfig base, TrackConfig targe } } // check if all base and target stations are assigned - if (stationMap.keySet().size() != baseNb || - Sets.newHashSet(stationMap.values()).size() != targetNb) { + if (stationMap.keySet().size() != baseNb + /* Unclear why the all-stations-mapped check was applied to the new tile. + It inhibited upgrading 1837 Vienna to green (4 -> 6 stations). + || Sets.newHashSet(stationMap.values()).size() != targetNb*/ + ) { stationMap = null; log.debug("Mapping: Not all stations assigned, set stationMap to null"); } @@ -518,13 +521,13 @@ private Map assignStations(TrackConfig base, TrackConfig targe private boolean checkTrackConnectivity(Set baseTrack, Set targetTrack) { SetView diffTrack = Sets.difference(baseTrack, targetTrack); - log.info("BaseTrack={} TargetTrack={} DiffTrack={}", baseTrack, baseTrack,diffTrack); + log.debug("BaseTrack={} TargetTrack={} DiffTrack={}", baseTrack, baseTrack,diffTrack); if (diffTrack.isEmpty()) { // target maintains connectivity return true; } else { // if not all connections are maintained, - Predicate checkForStation = new Predicate() { + Predicate checkForStation = new Predicate<>() { public boolean apply(TrackPoint p) { return (p.getTrackPointType() == TrackPoint.Type.SIDE); } diff --git a/src/main/java/net/sf/rails/game/specific/_1837/OperatingRound_1837.java b/src/main/java/net/sf/rails/game/specific/_1837/OperatingRound_1837.java index 4901144a4..94f3dc357 100644 --- a/src/main/java/net/sf/rails/game/specific/_1837/OperatingRound_1837.java +++ b/src/main/java/net/sf/rails/game/specific/_1837/OperatingRound_1837.java @@ -8,21 +8,13 @@ import java.util.Map; import java.util.Set; +import net.sf.rails.game.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import net.sf.rails.common.DisplayBuffer; import net.sf.rails.common.LocalText; import net.sf.rails.common.ReportBuffer; -import net.sf.rails.game.GameDef; -import net.sf.rails.game.GameManager; -import net.sf.rails.game.MapHex; -import net.sf.rails.game.OperatingRound; -import net.sf.rails.game.Phase; -import net.sf.rails.game.Player; -import net.sf.rails.game.PrivateCompany; -import net.sf.rails.game.PublicCompany; -import net.sf.rails.game.RailsRoot; import net.sf.rails.game.financial.Bank; import net.sf.rails.game.financial.NationalFormationRound; import net.sf.rails.game.special.ExchangeForShare; @@ -301,6 +293,7 @@ protected String validateSetRevenueAndDividend(SetDividend action) { * @see net.sf.rails.game.OperatingRound#splitRevenue(int) */ + // TODO: perhaps make roundUp generic? public void splitRevenue(int amount, boolean roundUp) { int withheld = 0; if (amount > 0) { @@ -364,10 +357,17 @@ public void payout(int amount, boolean roundUp, boolean b) { /** * payout the direct Income from the Coal Mine if any */ + /* EV: I don't think this belongs here. + * What if the company withholds? + * Paying out direct income is a separate process, + * and is now done in processSpecialRevenue() + */ + /* String partText = Currency.fromBank( operatingCompany.value().getDirectIncomeRevenue(), operatingCompany.value()); ReportBuffer.add(this, LocalText.getText("ReceivedDirectIncomeFromMine", operatingCompany.value().getId(), partText)); + */ // Move the token ((PublicCompany_1837) operatingCompany.value()).payout(amount, b); @@ -375,9 +375,9 @@ public void payout(int amount, boolean roundUp, boolean b) { - /* (non-Javadoc) - * @see net.sf.rails.game.OperatingRound#executeSetRevenueAndDividend(rails.game.action.SetDividend) - */ + /* Outcommented for now, as the mine revenue code has been put + * into a separate method (processSpecialRevenue()). + */ /* @Override protected void executeSetRevenueAndDividend(SetDividend action) { @@ -431,10 +431,26 @@ protected void executeSetRevenueAndDividend(SetDividend action) { nextStep(GameDef.OrStep.PAYOUT); } - /* (non-Javadoc) * @see net.sf.rails.game.OperatingRound#gameSpecificTileLayAllowed(net.sf.rails.game.PublicCompany, net.sf.rails.game.MapHex, int) */ + @Override + protected int processSpecialRevenue(int earnings, int specialRevenue) { + int dividend = earnings; + PublicCompany company = operatingCompany.value(); + if (specialRevenue > 0) { + dividend -= specialRevenue; + company.setLastDirectIncome(specialRevenue); + ReportBuffer.add(this, LocalText.getText("CompanyDividesEarnings", + company, + Bank.format(this, earnings), + Bank.format(this, dividend), + Bank.format(this, specialRevenue))); + Currency.fromBank(specialRevenue, company); + } + company.setLastDividend(dividend); + return dividend; + } @Override protected boolean gameSpecificTileLayAllowed(PublicCompany company, @@ -492,6 +508,39 @@ protected void prepareRevenueAndDividendAction() { } } + /** + * Can the operating company buy a train now? + * In 1837 it is allowed if another (different) train is scrapped. + * + * @return True if the company is allowed to buy a train + */ + protected boolean canBuyTrainNow() { + return isBelowTrainLimit(); + } + + /** + * New standard method to allow discarding trains when at the train limit. + * Note: 18EU has a different procedure for discarding Pullmann trains. + * @param company + * @param newTrain + */ + @Override + protected void addOtherExchangesAtTrainLimit(PublicCompany company, Train newTrain) { + // May only discard train if at train limit. + if (isBelowTrainLimit()) return; + + Set oldTrains = company.getPortfolioModel().getUniqueTrains(); + + for (Train oldTrain : oldTrains) { + // May not exchange for same type + if (oldTrain.getType().equals(newTrain.getType())) continue; + // New train cost is raised with half the old train cost + int price = newTrain.getCost() + oldTrain.getCost() / 2; + BuyTrain buyTrain = new BuyTrain (newTrain, bank.getIpo(), price); + buyTrain.setTrainForExchange(oldTrain); + possibleActions.add(buyTrain); + } + } /* (non-Javadoc) * @see net.sf.rails.game.OperatingRound#buyTrain(rails.game.action.BuyTrain) @@ -511,6 +560,8 @@ public boolean buyTrain(BuyTrain action) { return result; } + + @Override protected void finishRound() { ReportBuffer.add(this, " "); diff --git a/src/main/java/net/sf/rails/game/specific/_1837/RunToCoalMineModifier.java b/src/main/java/net/sf/rails/game/specific/_1837/RunToCoalMineModifier.java index b68cc083f..ac40d4283 100644 --- a/src/main/java/net/sf/rails/game/specific/_1837/RunToCoalMineModifier.java +++ b/src/main/java/net/sf/rails/game/specific/_1837/RunToCoalMineModifier.java @@ -4,19 +4,34 @@ import java.util.List; import net.sf.rails.algorithms.RevenueAdapter; +import net.sf.rails.algorithms.RevenueCalculatorModifier; import net.sf.rails.algorithms.RevenueDynamicModifier; import net.sf.rails.algorithms.RevenueTrainRun; import net.sf.rails.game.Access; +import net.sf.rails.game.Phase; import net.sf.rails.game.Station; import net.sf.rails.game.Stop; import net.sf.rails.util.Util; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +/** + * This modifier enforces the rules for accessing mines: + * - goods trains must run from or to exactly one mine, + * - passenger trains may not run from or to any mine. + */ +public class RunToCoalMineModifier + implements RevenueDynamicModifier, RevenueCalculatorModifier { -public class RunToCoalMineModifier implements RevenueDynamicModifier { + private static final Logger log = LoggerFactory.getLogger(RunToCoalMineModifier.class); + + private int directRevenueFromMines; + //private boolean evaluateMine; @Override public boolean prepareModifier(RevenueAdapter revenueAdapter) { - // always active + //evaluateMine = true; + directRevenueFromMines = 0; return true; } @@ -27,40 +42,74 @@ public int predictionValue(List runs) { } private List identifyInvalidRuns(List runs) { + + //if (evaluateMine) directRevenueFromMines = 0; // Prevent later overwriting by 0 + int totalMineRevenue = 0; + List invalidRuns = new ArrayList<>(); + int i = 0; + log.debug ("--------------------------------------------------"); for (RevenueTrainRun run:runs) { - if (!run.hasAValidRun()) continue; + log.debug ("Run {}: {}", ++i, + run.prettyPrint(true) + .replaceAll("\\n+", "") + .replaceAll("\\s+", " ")); + if (!run.hasAValidRun()) { + log.debug ("Invalid run"); + continue; + } String trainCategory = run.getTrain().getRailsTrain().getCategory(); - if (!Util.hasValue(trainCategory)) continue; + if (!Util.hasValue(trainCategory)) { + log.debug("No category"); + continue; + } // check if runs do not start or end at a coal mine // for a train category that is not allowed to do so // (this part of the modifier is not specific for 1837) - Station firstStation = run.getFirstVertex().getStop().getRelatedStation(); + Stop firstStop = run.getFirstVertex().getStop(); + Station firstStation = firstStop.getRelatedStation(); boolean firstStationIsMine = firstStation.getType() == Stop.Type.MINE; Access firstStationAccess = firstStation.getAccess(); - Station lastStation = run.getLastVertex().getStop().getRelatedStation(); + Stop lastStop = run.getLastVertex().getStop(); + Station lastStation = lastStop.getRelatedStation(); boolean lastStationIsMine = lastStation.getType() == Stop.Type.MINE; Access lastStationAccess = lastStation.getAccess(); if (firstStationIsMine && !(firstStationAccess == null || firstStationAccess.getRunToTrainCategories().contains(trainCategory))) { invalidRuns.add(run); + log.debug("Invalid first stop: access={} or wrong category"); continue; } if (lastStationIsMine && !(lastStationAccess == null || lastStationAccess.getRunToTrainCategories().contains(trainCategory))) { invalidRuns.add(run); + log.debug("Invalid last stop: access={} or wrong category"); continue; } // Coal train runs must include just one mine // (note: this makes the mutexId check redundant) // "goods" may be 1837-specific - if (trainCategory.equalsIgnoreCase("goods") - && firstStationIsMine == lastStationIsMine) { - invalidRuns.add(run); + if (trainCategory.equalsIgnoreCase("goods")) { + if (firstStationIsMine == lastStationIsMine) { + log.debug("Invalid, GT mines: {}, {}",firstStationIsMine,lastStationIsMine); + invalidRuns.add(run); + } else /*if (evaluateMine)*/ { + // Save the revenue from the mine(s), which in 1837 + // becomes 'direct revenue' into the company treasury. + Stop mine = (firstStationIsMine ? firstStop : lastStop); + Phase phase = run.getTrain().getRailsTrain().getRoot().getPhaseManager().getCurrentPhase(); + int mineRevenue = mine.getParent().getCurrentValueForPhase(phase); + //directRevenueFromMines += mineRevenue; + totalMineRevenue += mineRevenue; + } } + } + //evaluateMine = false; + // Maximize the mine revenue (not sure if this is optimal). + directRevenueFromMines = Math.max (directRevenueFromMines, totalMineRevenue); return invalidRuns; } @@ -83,16 +132,37 @@ public void adjustOptimalRun(List optimalRuns) { run.getRunVertices().clear(); } } - public boolean providesOwnCalculateRevenue() { + + public boolean providesOwnCalculateRevenue() { // not used?? // does not return false; } - public int calculateRevenue(RevenueAdapter revenueAdpater) { - // zero does no change + /** + * Here used to separately report the revenue from mines. + * The engine will later subtract that from the total revenue. + * @param revenueAdapter + * @return The revenue gathered by the mine(s) + */ + @Override + public int calculateRevenue(RevenueAdapter revenueAdapter) { + // EV: it appears that this method is never called, + // so I could not use to report just the mines revenue. + // It was also intended for a different purpose, as it seems. + // It has been replaced with a new method, see getSpecialRevenue(). + /* + revenueAdapter.setSpecialRevenue(directRevenueFromMines); + return directRevenueFromMines; + */ return 0; } + // The above method is never called, do it another way. + // This method has been added to the RevenueCalculatorModifier. + public int getSpecialRevenue () { + return directRevenueFromMines; + } + @Override public String prettyPrint(RevenueAdapter adapter) { // nothing to do diff --git a/src/main/java/net/sf/rails/tools/ListAndFixSavedFiles.java b/src/main/java/net/sf/rails/tools/ListAndFixSavedFiles.java index 3f9a106fa..a239d4cce 100644 --- a/src/main/java/net/sf/rails/tools/ListAndFixSavedFiles.java +++ b/src/main/java/net/sf/rails/tools/ListAndFixSavedFiles.java @@ -23,10 +23,7 @@ import net.sf.rails.util.GameLoader; import net.sf.rails.util.GameSaver; import net.sf.rails.util.Util; -import rails.game.action.BuyCertificate; -import rails.game.action.BuyTrain; -import rails.game.action.LayTile; -import rails.game.action.PossibleAction; +import rails.game.action.*; public class ListAndFixSavedFiles extends JFrame implements ActionListener, KeyListener { @@ -343,6 +340,8 @@ private void correct (int index) { new LayTileDialog((LayTile) correctedAction); } else if (correctedAction instanceof BuyCertificate) { new BuyCertificateDialog ((BuyCertificate) correctedAction); + } else if (correctedAction instanceof SetDividend) { + new SetDividendDialog ((SetDividend) correctedAction); } else { JOptionPane.showMessageDialog(this, "Action type '" + correctedAction.getClass().getSimpleName() + "' cannot yet be edited"); @@ -537,6 +536,39 @@ PossibleAction processInput() { } } + private class SetDividendDialog extends EditDialog { + private static final long serialVersionUID = 1L; + private SetDividend action; + + SetDividendDialog(SetDividend action) { + super("Edit SetDividend"); + this.action = action; + addTextField(this, "Preset revenue", + action.getPresetRevenue(), + String.valueOf(action.getPresetRevenue())); // 0 + finish(); + } + + @Override + PossibleAction processInput() { + log.info("Action was {}", action); + String input = ""; + try { + input = ((JTextField)inputElements.get(0)).getText(); + int presetRevenue = Integer.valueOf(input); + action.setPresetRevenue(presetRevenue); + } catch (NumberFormatException e) { + log.error ("Error in president: {}", input, e); + } + + log.info("Action is {}", action); + return action; + + } + } + + + protected void addLabel (EditDialog owner, String caption, Object initialObject, String initialValue) { JComponent element = new JLabel (initialValue); int index = owner.length++; diff --git a/src/main/java/net/sf/rails/ui/swing/ORPanel.java b/src/main/java/net/sf/rails/ui/swing/ORPanel.java index 82c2335a9..4e22653d8 100644 --- a/src/main/java/net/sf/rails/ui/swing/ORPanel.java +++ b/src/main/java/net/sf/rails/ui/swing/ORPanel.java @@ -6,7 +6,6 @@ import net.sf.rails.common.GuiDef; import net.sf.rails.common.LocalText; import net.sf.rails.game.*; -import net.sf.rails.game.financial.Bank; import net.sf.rails.ui.swing.elements.*; import net.sf.rails.ui.swing.hexmap.HexHighlightMouseListener; import net.sf.rails.util.Util; @@ -96,7 +95,9 @@ public class ORPanel extends GridPanel private Field[] rights; /** * For the direct Income to be entered during the OR Phase + * and the (remaining) dividend */ + private Field[] dividend; private Spinner[] directIncomeSelect; private Field[] directIncomeRevenue; private int bonusRevXOffset, bonusRevYOffset; @@ -105,7 +106,7 @@ public class ORPanel extends GridPanel private boolean bonusTokensExist; private boolean hasCompanyLoans; private boolean hasRights; - private boolean hasDirectCompanyIncomeInOr; + private boolean hasDirectCompanyIncomeInOR; // Configured properties private boolean showAllCompanies = "always".equalsIgnoreCase( @@ -161,7 +162,7 @@ public ORPanel(ORWindow parent, ORUIManager orUIManager) { bonusTokensExist = gameUIManager.getGameParameterAsBoolean(GuiDef.Parm.DO_BONUS_TOKENS_EXIST); hasCompanyLoans = gameUIManager.getGameParameterAsBoolean(GuiDef.Parm.HAS_ANY_COMPANY_LOANS); hasRights = gameUIManager.getGameParameterAsBoolean(GuiDef.Parm.HAS_ANY_RIGHTS); - hasDirectCompanyIncomeInOr= gameUIManager.getGameParameterAsBoolean(GuiDef.Parm.HAS_SPECIAL_COMPANY_INCOME); + hasDirectCompanyIncomeInOR = gameUIManager.getGameParameterAsBoolean(GuiDef.Parm.HAS_SPECIAL_COMPANY_INCOME); initButtonPanel(); gbc = new GridBagConstraints(); @@ -441,7 +442,8 @@ private void initFields() { if (hasRights) rights = new Field[nc]; revenue = new Field[nc]; revenueSelect = new Spinner[nc]; - if (hasDirectCompanyIncomeInOr) { + if (hasDirectCompanyIncomeInOR) { + dividend = new Field[nc]; directIncomeRevenue = new Field[nc]; directIncomeSelect = new Spinner[nc]; } @@ -467,7 +469,7 @@ private void initFields() { sharePriceXOffset = currentXOffset += lastXWidth; sharePriceYOffset = leftCompNameYOffset; - addField(new Caption("Share
value"), sharePriceXOffset, + addField(new Caption("
Share
value
"), sharePriceXOffset, 0, lastXWidth = 1, 2, WIDE_BOTTOM); cashXOffset = currentXOffset += lastXWidth; @@ -524,15 +526,20 @@ private void initFields() { revXOffset = currentXOffset += lastXWidth; revYOffset = leftCompNameYOffset; - addField(revenueCaption = new Caption("Revenue"), revXOffset, 0, lastXWidth = 2, 1, WIDE_RIGHT); - addField(new Caption("earned"), revXOffset, 1, 1, 1, WIDE_BOTTOM); - addField(new Caption("payout"), revXOffset + 1, 1, 1, 1, WIDE_BOTTOM + WIDE_RIGHT); - if (hasDirectCompanyIncomeInOr) { + if (hasDirectCompanyIncomeInOR) { + addField(revenueCaption = new Caption("Revenue"), revXOffset, 0, lastXWidth = 3, 1, 0); + addField(new Caption("earned"), revXOffset, 1, 1, 1, WIDE_BOTTOM); + addField(new Caption("payout"), revXOffset + 1, 1, 1, 1, WIDE_BOTTOM ); + addField(new Caption("dividend"), revXOffset + 2, 1, 1, 1, WIDE_BOTTOM ); bonusRevXOffset = currentXOffset += lastXWidth; bonusRevYOffset =leftCompNameYOffset; - addField(directIncomeCaption = new Caption("CompanyIncome"), bonusRevXOffset, 0, lastXWidth = 3, 1, WIDE_RIGHT); - addField(new Caption("income"), revXOffset, 1, 1, 1, WIDE_BOTTOM + WIDE_RIGHT); + addField(directIncomeCaption = new Caption("
Company
direct
income
"), + bonusRevXOffset, 0, lastXWidth = 1, 2, WIDE_BOTTOM + WIDE_RIGHT); + } else { + addField(revenueCaption = new Caption("Revenue"), revXOffset, 0, lastXWidth = 2, 1, WIDE_RIGHT); + addField(new Caption("earned"), revXOffset, 1, 1, 1, WIDE_BOTTOM); + addField(new Caption("payout"), revXOffset + 1, 1, 1, 1, WIDE_BOTTOM + WIDE_RIGHT); } trainsXOffset = currentXOffset += lastXWidth; @@ -580,17 +587,12 @@ private void initFields() { addField(f, cashXOffset, cashYOffset + i, 1, 1, WIDE_RIGHT, visible); if (privatesCanBeBought) { - f = - privates[i] = - new Field( - c.getPortfolioModel().getPrivatesOwnedModel()); - HexHighlightMouseListener.addMouseListener(f, - orUIManager, c.getPortfolioModel()); + f = privates[i] = new Field (c.getPortfolioModel().getPrivatesOwnedModel()); + HexHighlightMouseListener.addMouseListener(f, orUIManager, c.getPortfolioModel()); addField(f, privatesXOffset, privatesYOffset + i, 1, 1, 0, visible); - f = - newPrivatesCost[i] = + f = newPrivatesCost[i] = new Field(c.getPrivatesSpentThisTurnModel()); addField(f, privatesXOffset + 1, privatesYOffset + i, 1, 1, WIDE_RIGHT, visible); @@ -633,30 +635,48 @@ private void initFields() { WIDE_RIGHT, visible); } - f = revenue[i] = new Field(c.getLastRevenueModel()); - addField(f, revXOffset, revYOffset + i, 1, 1, 0, visible); + if(hasDirectCompanyIncomeInOR) { + f = revenue[i] = new Field(c.getLastRevenueModel()); + addField(f, revXOffset, revYOffset + i, 1, 1, 0, visible); + + f = revenueSelect[i] = new Spinner(0, 0, 0, + orUIManager.getGameUIManager().getGameManager().getRevenueSpinnerIncrement()); + //align spinner size with field size + //(so that changes to visibility don't affect panel sizing) + f.setPreferredSize(revenue[i].getPreferredSize()); + addField(f, revXOffset, revYOffset + i, 1, 1, 0, false); + // deactivated below, as this caused problems by gridpanel rowvisibility function -- sfy + // revenue[i].addDependent(revenueSelect[i]); - f = revenueSelect[i] = new Spinner(0, 0, 0, - orUIManager.getGameUIManager().getGameManager().getRevenueSpinnerIncrement()); - //align spinner size with field size - //(so that changes to visibility don't affect panel sizing) - f.setPreferredSize(revenue[i].getPreferredSize()); - addField(f, revXOffset, revYOffset + i, 1, 1, 0, false); - // deactived below, as this caused problems by gridpanel rowvisibility function -- sfy - // revenue[i].addDependent(revenueSelect[i]); + f = decision[i] = new Field(c.getLastRevenueAllocationModel()); + addField(f, revXOffset + 1, revYOffset + i, 1, 1, 0, visible); - f = decision[i] = new Field(c.getLastRevenueAllocationModel()); - addField(f, revXOffset + 1, revYOffset + i, 1, 1, WIDE_RIGHT, visible); + f = dividend[i] = new Field(c.getLastDividendModel()); + addField (f, revXOffset + 2, revYOffset + i, 1, 1, 0, visible); - if(hasDirectCompanyIncomeInOr) { f = directIncomeRevenue[i] = new Field(c.getLastDirectIncomeModel()); - addField(f, bonusRevXOffset, bonusRevYOffset + i, 1, 1, 0, visible); + addField(f, bonusRevXOffset, bonusRevYOffset + i, 1, 1, WIDE_RIGHT, visible); f = directIncomeSelect[i] = new Spinner(0, 0, 0, orUIManager.getGameUIManager().getGameManager().getRevenueSpinnerIncrement()); - f.setPreferredSize(directIncomeRevenue[i].getPreferredSize()); - addField(f, bonusRevXOffset, bonusRevYOffset + i, 1, 1, 0, false); + addField(f, bonusRevXOffset, bonusRevYOffset + i, 1, 1, + WIDE_RIGHT, false); + } else { + f = revenue[i] = new Field(c.getLastRevenueModel()); + addField(f, revXOffset, revYOffset + i, 1, 1, 0, visible); + + f = revenueSelect[i] = new Spinner(0, 0, 0, + orUIManager.getGameUIManager().getGameManager().getRevenueSpinnerIncrement()); + //align spinner size with field size + //(so that changes to visibility don't affect panel sizing) + f.setPreferredSize(revenue[i].getPreferredSize()); + addField(f, revXOffset, revYOffset + i, 1, 1, 0, false); + // deactived below, as this caused problems by gridpanel rowvisibility function -- sfy + // revenue[i].addDependent(revenueSelect[i]); + + f = decision[i] = new Field(c.getLastRevenueAllocationModel()); + addField(f, revXOffset + 1, revYOffset + i, 1, 1, WIDE_RIGHT, visible); } f = trains[i] = new Field(c.getPortfolioModel().getTrainsModel()); @@ -861,7 +881,8 @@ protected void executeNetworkInfo(String companyName) { * 1822CA: Mail Contract * 1854 old/new : Mail Contract ? */ - + int specialRevenue = ra.getSpecialRevenue(); + log.debug("Special revenue: {}", specialRevenue); if (!Config.isDevelop()) { //parent component is ORPanel so that dialog won't hide the routes painted on the map @@ -1051,11 +1072,17 @@ public void setRevenue(int orCompIndex, int amount) { revenue[orCompIndex].setText(format(amount)); } + public void setDividend (int orCompIndex, int amount) { + if (hasDirectCompanyIncomeInOR) { + dividend[orCompIndex].setText(format(amount)); + } + } + public void resetActions() { tileCaption.setHighlight(false); tokenCaption.setHighlight(false); revenueCaption.setHighlight(false); - if(hasDirectCompanyIncomeInOr) { + if(hasDirectCompanyIncomeInOR) { directIncomeCaption.setHighlight(false); } trainCaption.setHighlight(false); @@ -1093,7 +1120,7 @@ public void resetORCompanyTurn(int orCompIndex) { // No longer used? public void resetCurrentRevenueDisplay() { - if (hasDirectCompanyIncomeInOr) { + if (hasDirectCompanyIncomeInOR) { setSelect(revenue[orCompIndex], revenueSelect[orCompIndex], directIncomeSelect[orCompIndex], directIncomeRevenue[orCompIndex], false); } else { @@ -1247,16 +1274,18 @@ public void initRevenueEntryStep(int orCompIndex, SetDividend action) { } @Override - public void revenueUpdate(int bestRevenue, boolean finalResult) { + public void revenueUpdate(int bestRevenue, int specialRevenue, boolean finalResult) { if (isRevenueValueToBeSet) { setRevenue (orCompIndex, bestRevenue); + + //setTreasuryBonusRevenue (orCompIndex, specialRevenue); //revenueSelect[orCompIndex].setValue(bestRevenue); //revenue[orCompIndex].setText(format(bestRevenue)); /* * This needs to have another value for the automatic setting of a Direct Income for a Company */ - if(hasDirectCompanyIncomeInOr) { - directIncomeSelect[orCompIndex].setValue(0); + if(hasDirectCompanyIncomeInOR) { + directIncomeSelect[orCompIndex].setValue(specialRevenue); } } if (finalResult) { @@ -1499,7 +1528,7 @@ private void selectRevenueSpinner (int compIndex, boolean active) { revenueSelect[compIndex].setValue(oldValue); } boolean dciActive = !active && showSpinner; - if (hasDirectCompanyIncomeInOr) { + if (hasDirectCompanyIncomeInOR) { directIncomeRevenue[compIndex].setVisible(dciActive); directIncomeSelect[compIndex].setVisible(!dciActive); if (!dciActive) { @@ -1571,8 +1600,10 @@ public int getCompanyTreasuryBonusRevenue(int orCompIndex) { } public void setTreasuryBonusRevenue(int orCompIndex2, int bonusAmount) { - directIncomeRevenue[orCompIndex2].setText(orUIManager.getGameUIManager().format(bonusAmount)); - + directIncomeRevenue[orCompIndex2] + .setText(orUIManager + .getGameUIManager() + .format(bonusAmount)); } public void dispose() { diff --git a/src/main/java/net/sf/rails/ui/swing/ORUIManager.java b/src/main/java/net/sf/rails/ui/swing/ORUIManager.java index cf4f344d9..0365cf276 100644 --- a/src/main/java/net/sf/rails/ui/swing/ORUIManager.java +++ b/src/main/java/net/sf/rails/ui/swing/ORUIManager.java @@ -19,17 +19,7 @@ import net.sf.rails.common.GameOption; import net.sf.rails.common.GuiDef; import net.sf.rails.common.LocalText; -import net.sf.rails.game.BaseToken; -import net.sf.rails.game.GameDef; -import net.sf.rails.game.HexSidesSet; -import net.sf.rails.game.MapHex; -import net.sf.rails.game.OperatingRound; -import net.sf.rails.game.PublicCompany; -import net.sf.rails.game.Station; -import net.sf.rails.game.Stop; -import net.sf.rails.game.Tile; -import net.sf.rails.game.TrackConfig; -import net.sf.rails.game.Train; +import net.sf.rails.game.*; import net.sf.rails.game.financial.ShareSellingRound; import net.sf.rails.game.round.RoundFacade; import net.sf.rails.game.special.SpecialProperty; @@ -256,6 +246,7 @@ private void addConnectedTileLays(LayTile layTile) { NetworkGraph graph = networkAdapter.getRouteGraph(layTile.getCompany(), true, false); Map mapHexSides = graph.getReachableSides(); Multimap mapHexStations = graph.getPassableStations(); + Phase currentPhase = gameUIManager.getCurrentPhase(); boolean allLocations = (layTile.getLocations() == null || layTile.getLocations().isEmpty()); @@ -268,8 +259,8 @@ private void addConnectedTileLays(LayTile layTile) { Set upgrades = TileHexUpgrade.create(guiHex, mapHexSides.get(hex), mapHexStations.get(hex), layTile, routeAlgorithm); - TileHexUpgrade.validates(upgrades, gameUIManager.getCurrentPhase()); - gameSpecificTileUpgradeValidation (upgrades, layTile); + TileHexUpgrade.validates(upgrades, currentPhase); + gameSpecificTileUpgradeValidation (upgrades, layTile, currentPhase); hexUpgrades.putAll(guiHex, upgrades); } } @@ -292,7 +283,8 @@ private void addConnectedTileLays(LayTile layTile) { * @param layTile */ protected void gameSpecificTileUpgradeValidation (Set upgrades, - LayTile layTile) { + LayTile layTile, + Phase currentPhase) { } private void addLocatedTileLays(LayTile layTile) { @@ -796,8 +788,9 @@ private void relayBaseTokens (LayTile action) { Tile newTile = action.getLaidTile(); Tile oldTile = hex.getCurrentTile(); - // Why does that need to be configured? - // Shouldn't tokens always be relaid?? + // Check if manual token relay is required. + // This was an emergency measure in cases where automatic relay + // did not work (e.g. 1837 tile 427). Now probably obsolete. if (!action.isRelayBaseTokens() && !oldTile.relayBaseTokensOnUpgrade()) return; // is deprecated @@ -806,7 +799,6 @@ private void relayBaseTokens (LayTile action) { /* Check which tokens must be relaid, and in which sequence. * Ideally, the game engine should instruct the UI what to do * if there is more than one stop and more than one token. - * TODO LayTile does not yet allow that. * * For now, the only case that needs special handling is the 1835 BA home hex L6, * where it it possible to have two tokens laid before even one tile. @@ -1014,8 +1006,11 @@ public void buyTrain() { bTrain.getType(), from.getId() )); if (bTrain.isForExchange()) { - b.append(" (").append(LocalText.getText("EXCHANGED")).append( - ")"); + String exchTrainTypes = bTrain.getTrainsForExchange().toString() + // Replacing e.g. "[4_0]" by "4", or "[4_0, 5_0, 6_0]" by "4,5 or 6" + .replaceAll("[\\[ ]?(\\w+)_\\d+(,)?\\s?]?", "$1$2") + .replaceFirst(",(\\w+)$"," or $1"); + b.append(" (").append(LocalText.getText("DiscardingTrain", exchTrainTypes)).append(")"); } if (cost > 0) { b.append(" ").append( diff --git a/src/main/java/net/sf/rails/ui/swing/StartRoundWindow.java b/src/main/java/net/sf/rails/ui/swing/StartRoundWindow.java index 5d4245030..64ec9db51 100644 --- a/src/main/java/net/sf/rails/ui/swing/StartRoundWindow.java +++ b/src/main/java/net/sf/rails/ui/swing/StartRoundWindow.java @@ -11,11 +11,8 @@ import net.sf.rails.common.LocalText; import net.sf.rails.game.*; -import net.sf.rails.game.financial.Bank; -import net.sf.rails.game.financial.StockMarket; -import net.sf.rails.game.financial.StockSpace; +import net.sf.rails.game.financial.*; import net.sf.rails.game.round.RoundFacade; -import net.sf.rails.game.special.SpecialProperty; import net.sf.rails.sound.SoundManager; import net.sf.rails.ui.swing.elements.*; import net.sf.rails.ui.swing.hexmap.HexHighlightMouseListener; @@ -66,26 +63,34 @@ public class StartRoundWindow extends JFrame implements ActionListener, KeyListe private GridBagConstraints gbc; // Grid elements per function - private Caption itemName[]; - private ClickField itemNameButton[]; - private int itemNameXOffset, itemNameYOffset; - private Field basePrice[]; - private int basePriceXOffset, basePriceYOffset; - private Field minBid[]; - private int minBidXOffset, minBidYOffset; - private Field bidPerPlayer[][]; - private int bidPerPlayerXOffset, bidPerPlayerYOffset; - private Field playerBids[]; - private int playerBidsXOffset, playerBidsYOffset; - private Field playerFree[]; - private int playerFreeCashXOffset, playerFreeCashYOffset; - private Field info[]; - private int infoXOffset, infoYOffset; - private Field itemStatus[]; // Remains invisible, only used for status tooltip - - private int playerCaptionXOffset, upperPlayerCaptionYOffset, lowerPlayerCaptionYOffset; - private Field upperPlayerCaption[]; - private Field lowerPlayerCaption[]; + private Caption[] itemName; + private ClickField[] itemNameButton; + private int[] itemNameXOffset; + private int itemNameYOffset; + private Field[] basePrice; + private int[] basePriceXOffset; + private int basePriceYOffset; + private Field[] minBid; + private int[] minBidXOffset; + private int minBidYOffset; + private Field[][] bidPerPlayer; + private int[] bidPerPlayerXOffset; + private int bidPerPlayerYOffset; + private Field[] playerBids; + private int[] playerBidsXOffset; + private int playerBidsYOffset; + private Field[] playerFree; + private int[] playerFreeCashXOffset; + private int playerFreeCashYOffset; + private Field[] info; + private int[] infoXOffset; + private int infoYOffset; + private Field[] itemStatus; // Remains invisible, only used for status tooltip + + private int[] playerCaptionXOffset; + private int upperPlayerCaptionYOffset, lowerPlayerCaptionYOffset; + private Field[][] upperPlayerCaption; + private Field[] lowerPlayerCaption; private JComponent[][] fields; private ActionButton bidButton; @@ -101,6 +106,11 @@ public class StartRoundWindow extends JFrame implements ActionListener, KeyListe private int[] crossIndex; protected StartRound round; private GameUIManager gameUIManager; + protected StartPacket startPacket; + protected boolean multipleColumns; + protected int numberOfColumns; + protected int numberOfRows; + protected int columnWidth = 0; // For the non-modal dialog to ask for a company starting share price. protected JDialog currentDialog; @@ -120,13 +130,23 @@ public class StartRoundWindow extends JFrame implements ActionListener, KeyListe public void init(StartRound round, GameUIManager parent) { //super(); this.round = round; + startPacket = round.getStartPacket(); + multipleColumns = startPacket.isMultipleColumns(); + if (multipleColumns) { + numberOfColumns = startPacket.getNumberOfColumns(); + numberOfRows = startPacket.getNumberOfRows(); + } else { + numberOfRows = round.getNumberOfStartItems(); + numberOfColumns = 1; + } includeBidding = round.hasBidding(); includeBuying = round.hasBuying(); showBasePrices = round.hasBasePrices(); gameUIManager = parent; possibleActions = gameUIManager.getGameManager().getPossibleActions(); - setTitle(LocalText.getText("START_ROUND_TITLE")); + setTitle(LocalText.getText("START_ROUND_TITLE", + String.valueOf(round.getStartRoundNumber()))); getContentPane().setLayout(new BorderLayout()); statusPanel = new JPanel(); @@ -185,7 +205,7 @@ public void init(StartRound round, GameUIManager parent) { getContentPane().add(statusPanel, BorderLayout.NORTH); getContentPane().add(buttonPanel, BorderLayout.SOUTH); - setTitle("Rails: Start Round"); + //setTitle("Rails: Start Round"); setLocation(300, 150); setSize(275, 325); gameUIManager.setMeVisible(this, true); @@ -228,6 +248,7 @@ private void initCells() { int np = players.getNumberOfPlayers(); int ni = round.getNumberOfStartItems(); + itemName = new Caption[ni]; itemNameButton = new ClickField[ni]; basePrice = new Field[ni]; @@ -235,93 +256,140 @@ private void initCells() { bidPerPlayer = new Field[ni][np]; info = new Field[ni]; itemStatus = new Field[ni]; - upperPlayerCaption = new Field[np]; + upperPlayerCaption = new Field[numberOfColumns][np]; lowerPlayerCaption = new Field[np]; playerBids = new Field[np]; playerFree = new Field[np]; + itemNameXOffset = new int[numberOfColumns]; + if (showBasePrices) basePriceXOffset = new int[numberOfColumns]; + if (includeBidding == StartRound.Bidding.ON_ITEMS) minBidXOffset = new int[numberOfColumns]; + bidPerPlayerXOffset = new int[numberOfColumns]; + playerCaptionXOffset = new int[numberOfColumns]; + infoXOffset = new int[numberOfColumns]; + if (includeBidding != StartRound.Bidding.NO) playerBidsXOffset = new int[numberOfColumns]; + playerFreeCashXOffset = new int[numberOfColumns]; + upperPlayerCaptionYOffset = ++lastY; - itemNameXOffset = ++lastX; - itemNameYOffset = ++lastY; - if (showBasePrices) { - basePriceXOffset = ++lastX; - basePriceYOffset = lastY; - } - if (includeBidding == StartRound.Bidding.ON_ITEMS) { - minBidXOffset = ++lastX; - minBidYOffset = lastY; - } - bidPerPlayerXOffset = playerCaptionXOffset = ++lastX; - bidPerPlayerYOffset = lastY; + for (int col = 0; col < numberOfColumns; col++) { + itemNameXOffset[col] = ++lastX; + if (col == 0) itemNameYOffset = ++lastY; + if (showBasePrices) { + basePriceXOffset[col] = ++lastX; + if (col == 0) basePriceYOffset = lastY; + } + if (includeBidding == StartRound.Bidding.ON_ITEMS) { + minBidXOffset[col] = ++lastX; + if (col == 0) minBidYOffset = lastY; + } + bidPerPlayerXOffset[col] = playerCaptionXOffset[col] = ++lastX; + if (col == 0) bidPerPlayerYOffset = lastY; + + infoXOffset[col] = bidPerPlayerXOffset[col] + np; + lastX += np; + if (col == 0) { + infoYOffset = lastY; + columnWidth = lastX + 1; + } - infoXOffset = bidPerPlayerXOffset + np; - infoYOffset = lastY; - // Bottom rows - lastY += (ni - 1); - if (includeBidding != StartRound.Bidding.NO) { - playerBidsXOffset = bidPerPlayerXOffset; - playerBidsYOffset = ++lastY; - } - playerFreeCashXOffset = bidPerPlayerXOffset; - playerFreeCashYOffset = ++lastY; + // Bottom rows + lastY += (numberOfRows - 1); + if (includeBidding != StartRound.Bidding.NO) { + playerBidsXOffset[col] = bidPerPlayerXOffset[col]; + if (col == 0) playerBidsYOffset = ++lastY; + } + playerFreeCashXOffset[col] = bidPerPlayerXOffset[col]; - lowerPlayerCaptionYOffset = ++lastY; + if (col == 0) { + playerFreeCashYOffset = ++lastY; + lowerPlayerCaptionYOffset = ++lastY; - fields = new JComponent[1 + infoXOffset][2 + lastY]; + fields = new JComponent[columnWidth * numberOfColumns][2 + lastY]; + log.debug("Columns={} (width/col={} nbOfCol={}) rows={}", columnWidth * numberOfColumns, + columnWidth, numberOfColumns, 2 + lastY); + } - addField(new Caption(LocalText.getText("ITEM")), 0, 0, 1, 2, - WIDE_RIGHT + WIDE_BOTTOM); - if (showBasePrices) { - addField(new Caption(LocalText.getText(includeBidding == StartRound.Bidding.ON_ITEMS - ? "BASE_PRICE" : "PRICE")), basePriceXOffset, 0, 1, 2, - WIDE_BOTTOM); - } - if (includeBidding == StartRound.Bidding.ON_ITEMS) { - addField(new Caption(LocalText.getText("MINIMUM_BID")), - minBidXOffset, 0, 1, 2, WIDE_BOTTOM + WIDE_RIGHT); - } - addField(new Caption(LocalText.getText("PLAYERS")), - playerCaptionXOffset, 0, np, 1, 0); - for (int i = 0; i < np; i++) { - upperPlayerCaption[i] = new Field(players.getPlayerByPosition(i).getPlayerNameModel()); - addField(upperPlayerCaption[i], playerCaptionXOffset + i, upperPlayerCaptionYOffset, 1, 1, WIDE_BOTTOM); + addField(new Caption(LocalText.getText("ITEM")), + itemNameXOffset[col], 0, 1, 2, + WIDE_LEFT + WIDE_RIGHT + WIDE_BOTTOM); + + if (showBasePrices) { + addField(new Caption(LocalText.getText(includeBidding == StartRound.Bidding.ON_ITEMS + ? "BASE_PRICE" : "PRICE")), basePriceXOffset[col], 0, 1, 2, + WIDE_BOTTOM); + } + if (includeBidding == StartRound.Bidding.ON_ITEMS) { + addField(new Caption(LocalText.getText("MINIMUM_BID")), + minBidXOffset[col], 0, 1, 2, WIDE_BOTTOM + WIDE_RIGHT); + } + addField(new Caption(LocalText.getText("PLAYERS")), + playerCaptionXOffset[col], 0, np, 1, 0); + for (int i = 0; i < np; i++) { + upperPlayerCaption[col][i] = new Field(players.getPlayerByPosition(i).getPlayerNameModel()); + addField(upperPlayerCaption[col][i], playerCaptionXOffset[col] + i, + upperPlayerCaptionYOffset, 1, 1, WIDE_BOTTOM); + } } + int row, col; for (int i = 0; i < ni; i++) { final StartItem si = round.getStartItem(i); - itemName[i] = new Caption(si.getId()); + if (multipleColumns) { + row = si.getRow() - 1; + col = si.getColumn() - 1; + } else { + row = i; + col = 0; + } + + itemName[i] = new Caption(si.getDisplayName()); HexHighlightMouseListener.addMouseListener(itemName[i], gameUIManager.getORUIManager(), si); - addField(itemName[i], itemNameXOffset, itemNameYOffset + i, 1, 1, WIDE_RIGHT); + addField(itemName[i], itemNameXOffset[col], itemNameYOffset + row, + 1, 1, WIDE_LEFT + WIDE_RIGHT); - itemNameButton[i] = new ClickField(si.getId(), "", "", this, itemGroup); + itemNameButton[i] = new ClickField(si.getDisplayName(), "", "", this, itemGroup); HexHighlightMouseListener.addMouseListener(itemNameButton[i], gameUIManager.getORUIManager(), si); - addField(itemNameButton[i], itemNameXOffset, itemNameYOffset + i, 1, 1, WIDE_RIGHT); + addField(itemNameButton[i], itemNameXOffset[col], itemNameYOffset + row, + 1, 1, WIDE_LEFT + WIDE_RIGHT); // Prevent row height resizing after every buy action itemName[i].setPreferredSize(itemNameButton[i].getPreferredSize()); if (showBasePrices) { basePrice[i] = new Field(si.getBasePriceModel()); - addField(basePrice[i], basePriceXOffset, basePriceYOffset + i, 1, 1, 0); + addField(basePrice[i], basePriceXOffset[col], basePriceYOffset + row, + 1, 1, 0); } if (includeBidding == StartRound.Bidding.ON_ITEMS) { minBid[i] = new Field(round.getMinimumBidModel(i)); - addField(minBid[i], minBidXOffset, minBidYOffset + i, 1, 1, WIDE_RIGHT); + addField(minBid[i], minBidXOffset[col], minBidYOffset + row, + 1, 1, WIDE_RIGHT); } for (int j = 0; j < np; j++) { bidPerPlayer[i][j] = new Field(round.getBidModel(i, players.getPlayerByPosition(j))); - addField(bidPerPlayer[i][j], bidPerPlayerXOffset + j, bidPerPlayerYOffset + i, 1, 1, 0); + addField(bidPerPlayer[i][j], bidPerPlayerXOffset[col] + j, bidPerPlayerYOffset + row, + 1, 1, 0); } info[i] = new Field(infoIcon); - info[i].setToolTipText(getStartItemDescription(si)); + + Certificate cert = si.getPrimary(); + Company comp = null; + if (cert instanceof PublicCertificate) { + comp = (PublicCompany) cert.getParent(); + } else if (cert instanceof PrivateCompany) { + comp = (PrivateCompany) cert; + } + String infoText = comp.getInfoText().replaceFirst("^", + "" + comp.getType().getId() + " company: "); + info[i].setToolTipText(infoText); HexHighlightMouseListener.addMouseListener(info[i], gameUIManager.getORUIManager(), si); - addField(info[i], infoXOffset, infoYOffset + i, 1, 1, WIDE_LEFT); + addField(info[i], infoXOffset[col], infoYOffset + row, 1, 1, WIDE_LEFT + WIDE_RIGHT); // Invisible field, only used to hold current item status. itemStatus[i] = new Field(si.getStatusModel()); @@ -330,11 +398,13 @@ private void initCells() { // Player money boolean firstBelowTable = true; if (includeBidding != StartRound.Bidding.NO) { - addField(new Caption(LocalText.getText("BID")), playerBidsXOffset - 1, playerBidsYOffset, 1, 1, WIDE_TOP + WIDE_RIGHT); + addField(new Caption(LocalText.getText("BID")), playerBidsXOffset[0] - 1, playerBidsYOffset, + 1, 1, WIDE_TOP + WIDE_RIGHT); for (int i = 0; i < np; i++) { playerBids[i] = new Field(round.getBlockedCashModel(players.getPlayerByPosition(i))); - addField(playerBids[i], playerBidsXOffset + i, playerBidsYOffset, 1, 1, WIDE_TOP); + addField(playerBids[i], playerBidsXOffset[0] + i, playerBidsYOffset, + 1, 1, WIDE_TOP); } firstBelowTable = false; @@ -342,18 +412,18 @@ private void initCells() { addField(new Caption( LocalText.getText(includeBidding != StartRound.Bidding.NO ? "FREE" : "CASH")), - playerFreeCashXOffset - 1, playerFreeCashYOffset, 1, 1, + playerFreeCashXOffset[0] - 1, playerFreeCashYOffset, 1, 1, WIDE_RIGHT + (firstBelowTable ? WIDE_TOP : 0)); for (int i = 0; i < np; i++) { playerFree[i] = new Field(includeBidding != StartRound.Bidding.NO ? round.getFreeCashModel(players.getPlayerByPosition(i)) : players.getPlayerByPosition(i).getWallet()); - addField(playerFree[i], playerFreeCashXOffset + i, playerFreeCashYOffset, 1, 1, firstBelowTable ? WIDE_TOP : 0); + addField(playerFree[i], playerFreeCashXOffset[0] + i, playerFreeCashYOffset, 1, 1, firstBelowTable ? WIDE_TOP : 0); } for (int i = 0; i < np; i++) { lowerPlayerCaption[i] = new Field(players.getPlayerByPosition(i).getPlayerNameModel()); - addField(lowerPlayerCaption[i], playerFreeCashXOffset + i, playerFreeCashYOffset + 1, 1, 1, WIDE_TOP); + addField(lowerPlayerCaption[i], playerFreeCashXOffset[0] + i, playerFreeCashYOffset + 1, 1, 1, WIDE_TOP); } dummyButton = new ClickField("", "", "", this, itemGroup); @@ -713,13 +783,13 @@ public void close() { } public void setSRPlayerTurn() { + int playerIndex = players.getCurrentPlayer().getIndex(); for (int i = 0; i < players.getNumberOfPlayers(); i++) { - upperPlayerCaption[i].setHighlight(false); - lowerPlayerCaption[i].setHighlight(false); + for (int j = 0; j < numberOfColumns; j++) { + upperPlayerCaption[j][i].setHighlight(i == playerIndex); + } + lowerPlayerCaption[i].setHighlight(i == playerIndex); } - - upperPlayerCaption[players.getCurrentPlayer().getIndex()].setHighlight(true); - lowerPlayerCaption[players.getCurrentPlayer().getIndex()].setHighlight(true); } private void setItemNameButton(int i, boolean clickable) { @@ -736,6 +806,7 @@ private void setItemNameButton(int i, boolean clickable) { itemNameButton[i].setForeground(status == StartItem.BUYABLE ? buyableColour : defaultColour); } + /* Replaced by the texts from the Info menu. private String getStartItemDescription(StartItem item) { StringBuilder b = new StringBuilder(""); b.append(item.getPrimary().toText()); @@ -773,7 +844,7 @@ private String getStartItemDescription(StartItem item) { b.append(item.getSecondary().toText()); } return b.toString(); - } + }*/ private ImageIcon createInfoIcon() { return RailsIcon.INFO.smallIcon; @@ -797,6 +868,9 @@ public boolean process(PossibleAction action) { } public void updatePlayerOrder(List newPlayerNames) { + + // Multiple columns are here ignored for now. + // When is this called? int np = players.getNumberOfPlayers(); int[] xref = new int[np]; @@ -812,18 +886,20 @@ public void updatePlayerOrder(List newPlayerNames) { GridBagConstraints[] constraints = new GridBagConstraints[np]; JComponent f; for (int y = upperPlayerCaptionYOffset; y <= lowerPlayerCaptionYOffset; y++) { - for (int i = 0, x = playerCaptionXOffset; i < np; i++, x++) { + for (int i = 0, x = playerCaptionXOffset[0]; i < np; i++, x++) { cells[i] = fields[x][y]; constraints[i] = gb.getConstraints(cells[i]); statusPanel.remove(cells[i]); } - for (int i = 0, x = playerCaptionXOffset; i < np; i++, x++) { + for (int i = 0, x = playerCaptionXOffset[0]; i < np; i++, x++) { f = fields[x][y] = cells[xref[i]]; statusPanel.add(f, constraints[i]); } } - for (int i = 0, x = playerCaptionXOffset; i < np; i++, x++) { - upperPlayerCaption[i] = (Field) fields[x][upperPlayerCaptionYOffset]; + for (int i = 0, x = playerCaptionXOffset[0]; i < np; i++, x++) { + for (int col = 0; col < numberOfColumns; col++) { + upperPlayerCaption[col][i] = (Field) fields[x][upperPlayerCaptionYOffset]; + } lowerPlayerCaption[i] = (Field) fields[x][lowerPlayerCaptionYOffset]; } diff --git a/src/main/java/net/sf/rails/ui/swing/gamespecific/_1837/ORUIManager_1837.java b/src/main/java/net/sf/rails/ui/swing/gamespecific/_1837/ORUIManager_1837.java index f43195afd..89f6e2ef0 100644 --- a/src/main/java/net/sf/rails/ui/swing/gamespecific/_1837/ORUIManager_1837.java +++ b/src/main/java/net/sf/rails/ui/swing/gamespecific/_1837/ORUIManager_1837.java @@ -1,22 +1,25 @@ -/** - * - */ package net.sf.rails.ui.swing.gamespecific._1837; +import net.sf.rails.common.GuiDef; +import net.sf.rails.game.*; +import net.sf.rails.ui.swing.hexmap.TileHexUpgrade; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import net.sf.rails.sound.SoundManager; import net.sf.rails.ui.swing.ORPanel; import net.sf.rails.ui.swing.ORUIManager; -import net.sf.rails.ui.swing.gamespecific._1880.StartRoundWindow_1880; +import rails.game.action.LayTile; import rails.game.action.SetDividend; +import java.util.Set; + /** * @author Martin * */ public class ORUIManager_1837 extends ORUIManager { + private static final Logger log = LoggerFactory.getLogger(ORUIManager_1837.class); /** @@ -30,11 +33,19 @@ public ORUIManager_1837() { * @see net.sf.rails.ui.swing.ORUIManager#setDividend(java.lang.String, rails.game.action.SetDividend) */ protected void setDividend(String command, SetDividend action) { - int amount, bonusAmount; + + boolean hasDirectCompanyIncomeInOR + = gameUIManager.getGameParameterAsBoolean(GuiDef.Parm.HAS_SPECIAL_COMPANY_INCOME); + + int amount, bonusAmount, dividend; if (command.equals(ORPanel.SET_REVENUE_CMD)) { amount = orPanel.getRevenue(orCompIndex); bonusAmount = orPanel.getCompanyTreasuryBonusRevenue(orCompIndex); + if (hasDirectCompanyIncomeInOR) { + dividend = amount - bonusAmount; + orPanel.setDividend(orCompIndex, dividend); + } orPanel.stopRevenueUpdate(); log.debug("Set revenue amount is {}", amount); log.debug("The Bonus for the company treasury is {}", bonusAmount); @@ -64,4 +75,31 @@ protected void setDividend(String command, SetDividend action) { } } + /** + * Additional TileLay validation: + * Prevent laying a tile on a blocked hex for + * a non-owner of the blocking private + * @param upgrades Upgrades validated so far + * @param layTile LayTyle action + */ + protected void gameSpecificTileUpgradeValidation (Set upgrades, + LayTile layTile, + Phase currentPhase) { + if (!currentPhase.getId().equals("2")) return; + + if (layTile.getType() == LayTile.GENERIC) { + for (TileHexUpgrade upgrade : upgrades) { + MapHex hex = upgrade.getHex().getHex(); + PrivateCompany blockingPrivate = hex.getBlockingPrivateCompany(); + if (upgrade.hexIsBlocked() + && blockingPrivate != null + // The below check may break the client/server separation. + && !layTile.getPlayer().equals(blockingPrivate.getOwner())) { + upgrade.setVisible(false); + // Note: the private owner gets a separate LayTile instance, + // type = SPECIAL_PROPERTY, allowing to lay that tile anyway. + } + } + } + } } diff --git a/src/main/java/net/sf/rails/util/Util.java b/src/main/java/net/sf/rails/util/Util.java index 5c08c4b30..23fb53153 100644 --- a/src/main/java/net/sf/rails/util/Util.java +++ b/src/main/java/net/sf/rails/util/Util.java @@ -6,6 +6,7 @@ import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; +import java.util.Arrays; import java.util.List; import java.util.Properties; @@ -249,4 +250,12 @@ public static boolean storeProperties(Properties properties, File file) { } return result; } + + /** Quickly set a conditional breakpoint */ + public static void breakIf (String a, String list) { + if (Arrays.asList(list.split(",")).contains(a)) { + return; // Set a permanent breakpoint on this line. + } + return; + } } diff --git a/src/main/java/rails/game/action/BuyTrain.java b/src/main/java/rails/game/action/BuyTrain.java index 3c27296d9..17273b0c1 100644 --- a/src/main/java/rails/game/action/BuyTrain.java +++ b/src/main/java/rails/game/action/BuyTrain.java @@ -29,6 +29,7 @@ public class BuyTrain extends PossibleORAction { private String fromName; private int fixedCost; + /** In 1837 also used for volutary train scrapping */ private transient Set trainsForExchange = null; private String[] trainsForExchangeUniqueIds; @@ -115,6 +116,13 @@ public BuyTrain setTrainsForExchange(Set trains) { return this; } + public BuyTrain setTrainForExchange(Train train) { + Set trains = new HashSet<>(); + trains.add (train); + setTrainsForExchange (trains); + return this; + } + public BuyTrain setPresidentMustAddCash(int amount) { presidentMustAddCash = amount > 0; presidentCashToAdd = amount; diff --git a/src/main/java/rails/game/action/SetDividend.java b/src/main/java/rails/game/action/SetDividend.java index cc828f0f9..4047295dc 100644 --- a/src/main/java/rails/game/action/SetDividend.java +++ b/src/main/java/rails/game/action/SetDividend.java @@ -113,6 +113,10 @@ protected SetDividend(SetDividend action) { action.requiredCash); } + public void setPresetRevenue(int presetRevenue) { + this.presetRevenue = presetRevenue; + } + public int getPresetRevenue() { return presetRevenue; } @@ -201,13 +205,13 @@ protected boolean equalsAs(PossibleAction pa, boolean asOption) { // check asAction attributes // EV 2020/07/18: Disabled. In 18Scan the revenue and allocation // may sometimes be changed afterwards (e.g. minors pay out even if no route) - return true; - /* + return options && Objects.equal(this.actualRevenue, action.actualRevenue) && Objects.equal(this.actualCompanyTreasuryRevenue, action.actualCompanyTreasuryRevenue) && Objects.equal(this.revenueAllocation, action.revenueAllocation); - */ + + //return true; } @Override diff --git a/src/main/resources/LocalisedText.properties b/src/main/resources/LocalisedText.properties index cd743a9aa..2f00f3374 100644 --- a/src/main/resources/LocalisedText.properties +++ b/src/main/resources/LocalisedText.properties @@ -168,6 +168,7 @@ CompanyAlreadyStarted={0} has already been started. CompanyCloses={0} closes CompanyClosesAt={0} closes because price token reaches square {1} CompanyDiscardsTrain={0} discards a {1}-train to {2} +CompanyDividesEarnings={0} divides earnings of {1}: {2} as dividend, {3} to treasury CompanyDoesNotExist=Company {0} does not exist CompanyDoesNotOwnTrain=Company {0} does not own a {1}-train CompanyDoesNotPayDividend={0} does not pay a dividend @@ -181,6 +182,7 @@ CompanyMustPayLoanInterest={0} must pay {1} loan interest CompanyOperates={0} ({1}) operates. CompanyPaysLoanInterest={0} pays {1} as {2}% interest over {3} loans of {4} CompanyPaysOutFull={0} pays out full dividend of {1} +CompanyDirectRevenue={0} receives {1} direct revenue from mines CompanyRepaysBankLoan={0} repays {1} of bank loan, remaining {2} CompanyRepaysLoans={0} pays {1} (of {2}) to repay {3} loan(s) of {4} from its treasury CompanyRepaysLoansWithPresCash={0} pays {1} (of {2}) to repay {3} loan(s) of {4} from {5}'s personal cash @@ -345,6 +347,7 @@ DestinationRunRevenue=Minor {0} destination run earns {1}, bank adds {2}, total DestinationRoundEnd=End of Bonus Run of minor {0} DIRECT_INCOME=Direct Rev. DiscardsBaseToken={0} discards a {1} base token on {2} +DiscardingTrain=discarding {0}-train discount=discount of {0} DoesNotExist=Item does not exist DoesNotForm={0} does not form @@ -784,7 +787,7 @@ START_COMPANY={0} starts {1} at {2}. START_MERGED_COMPANY={0} starts at {1} ({2}) START_COMPANY_LOG={0} starts {1} at {2} and pays {3} for {4} shares ({5}%) to {6} START_OR=\n=======================\nStart of Operating Round {0}\n======================= -START_ROUND_TITLE=Rails: Start Round +START_ROUND_TITLE=Rails: START ROUND {0} STOCK_ROUND_TITLE=Rails: Game Status - STOCK ROUND {0} StartRound=start round SELECT_HEX=Select a hex diff --git a/src/main/resources/data/1830/Game.xml b/src/main/resources/data/1830/Game.xml index ebc6bfea3..80d41bc23 100644 --- a/src/main/resources/data/1830/Game.xml +++ b/src/main/resources/data/1830/Game.xml @@ -177,7 +177,7 @@ - + diff --git a/src/main/resources/data/1830/Map.xml b/src/main/resources/data/1830/Map.xml index 27879c8b6..08066de36 100644 --- a/src/main/resources/data/1830/Map.xml +++ b/src/main/resources/data/1830/Map.xml @@ -41,12 +41,7 @@ - - - - - - + diff --git a/src/main/resources/data/1835/CompanyManager.xml b/src/main/resources/data/1835/CompanyManager.xml index a8b7405c4..1e29c0a34 100644 --- a/src/main/resources/data/1835/CompanyManager.xml +++ b/src/main/resources/data/1835/CompanyManager.xml @@ -230,25 +230,26 @@ - + + - - + + - - - - - - - - - + + + + + + + + + - + diff --git a/src/main/resources/data/1837/CompanyManager.xml b/src/main/resources/data/1837/CompanyManager.xml index 6612482dc..f88c67aae 100644 --- a/src/main/resources/data/1837/CompanyManager.xml +++ b/src/main/resources/data/1837/CompanyManager.xml @@ -1,519 +1,503 @@ - - - 5 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + 5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/src/main/resources/data/1837/Game.xml b/src/main/resources/data/1837/Game.xml index afdbeb3e1..950929304 100644 --- a/src/main/resources/data/1837/Game.xml +++ b/src/main/resources/data/1837/Game.xml @@ -1,238 +1,220 @@ - - - - - - - - - - - - - - - - - --> - - - --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // --> - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/data/1837/Map.xml b/src/main/resources/data/1837/Map.xml index e64a87a8b..7aeeef9c0 100644 --- a/src/main/resources/data/1837/Map.xml +++ b/src/main/resources/data/1837/Map.xml @@ -5,6 +5,7 @@ + diff --git a/src/main/resources/data/1837/TileSet.xml b/src/main/resources/data/1837/TileSet.xml index 46bd368e1..2f7d82c2f 100644 --- a/src/main/resources/data/1837/TileSet.xml +++ b/src/main/resources/data/1837/TileSet.xml @@ -49,13 +49,13 @@ - + - + diff --git a/src/main/resources/data/GamesList.xml b/src/main/resources/data/GamesList.xml index debced767..8bc01bbca 100644 --- a/src/main/resources/data/GamesList.xml +++ b/src/main/resources/data/GamesList.xml @@ -214,6 +214,19 @@ Published 2004 by Deep Thought Games, LLC + + In progress + 1837 - Austria + (c) 1994 Leonhard Orgler (self-published) + + Known limitations: + - Buying the KK and Ug minors in subsequent Start rounds does not work well. + These rounds should be changed to Stock Rounds. + - Not yet tested beyond the 3-train phase. + + + + Not yet playable 1870 - Railroading across the Trans Mississippi @@ -279,13 +292,6 @@ Known Issues: - - Prototype - 1837 - Austria - (c) 199x Leonhard Orgler - - - Prototype - Not Playable 1862 diff --git a/src/main/resources/tiles/svg/tile-10001.svg b/src/main/resources/tiles/svg/tile-10001.svg index 6e716ebc7..a93a96378 100644 --- a/src/main/resources/tiles/svg/tile-10001.svg +++ b/src/main/resources/tiles/svg/tile-10001.svg @@ -1,2 +1,152 @@ - -30 + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + 30 + + diff --git a/src/main/resources/tiles/svg/tile-1059.svg b/src/main/resources/tiles/svg/tile-1059.svg index 83de217fd..170f1574b 100644 --- a/src/main/resources/tiles/svg/tile-1059.svg +++ b/src/main/resources/tiles/svg/tile-1059.svg @@ -1,2 +1,180 @@ - -4040X + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + 40 + + + 40 + X + + diff --git a/src/main/resources/tiles/svg/tile-1101.svg b/src/main/resources/tiles/svg/tile-1101.svg index 4acf08708..ee1201d8c 100644 --- a/src/main/resources/tiles/svg/tile-1101.svg +++ b/src/main/resources/tiles/svg/tile-1101.svg @@ -1,2 +1,167 @@ - -20 + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + 20 + + diff --git a/src/main/resources/tiles/svg/tile-1759.svg b/src/main/resources/tiles/svg/tile-1759.svg index d372f3f5d..78e04eed7 100644 --- a/src/main/resources/tiles/svg/tile-1759.svg +++ b/src/main/resources/tiles/svg/tile-1759.svg @@ -1,2 +1,129 @@ - -10Z + + + + + + image/svg+xml + + + + + + + + + + + + + + 10 + Z + + diff --git a/src/main/resources/tiles/svg/tile-18CH01.svg b/src/main/resources/tiles/svg/tile-18CH01.svg index 3bba56ff6..03eb1e542 100644 --- a/src/main/resources/tiles/svg/tile-18CH01.svg +++ b/src/main/resources/tiles/svg/tile-18CH01.svg @@ -7,10 +7,12 @@ xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - version="1.1" - id="svg3745" + height="357" + width="393" + inkscape:version="1.0 (4035a4fb49, 2020-05-01)" sodipodi:docname="tile-18CH01.svg" - inkscape:version="0.92.4 (5da689c313, 2019-01-14)"> + id="svg3745" + version="1.1"> @@ -26,66 +28,73 @@ + inkscape:window-y="-9" + inkscape:window-x="-9" + inkscape:cy="51.133735" + inkscape:cx="50.717293" + inkscape:zoom="0.89" + showgrid="false" + id="namedview3747" + inkscape:window-height="2081" + inkscape:window-width="3840" + inkscape:pageshadow="2" + inkscape:pageopacity="0" + guidetolerance="10" + gridtolerance="10" + objecttolerance="10" + borderopacity="1" + bordercolor="#666666" + pagecolor="#ffffff" /> + inkscape:groupmode="layer" /> + inkscape:groupmode="layer"> + id="path3733" + d="M 295.1035,339.35907 99.107645,340.63374 0.00414318,171.27466 96.896497,0.64092284 292.89235,-0.6337351 391.99586,168.72534 Z" /> - + + style="fill:none;stroke:#000000;stroke-width:1;stroke-linejoin:round" + inkscape:connector-curvature="0" /> + transform="rotate(-120.44825,196,170)" + id="g3761"> - + + inkscape:connector-curvature="0" + style="fill:none;stroke:#000000;stroke-width:26;stroke-linecap:butt;stroke-linejoin:round" /> + inkscape:connector-curvature="0" + style="fill:none;stroke:#000000;stroke-width:26;stroke-linecap:butt;stroke-linejoin:round" /> diff --git a/src/main/resources/tiles/svg/tile-18CH02.svg b/src/main/resources/tiles/svg/tile-18CH02.svg index 1a8e34af7..8a1f6b7ed 100644 --- a/src/main/resources/tiles/svg/tile-18CH02.svg +++ b/src/main/resources/tiles/svg/tile-18CH02.svg @@ -7,10 +7,12 @@ xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - version="1.1" - id="svg3919" + height="357" + width="393" + inkscape:version="1.0 (4035a4fb49, 2020-05-01)" sodipodi:docname="tile-18CH02.svg" - inkscape:version="0.92.4 (5da689c313, 2019-01-14)"> + id="svg3919" + version="1.1"> @@ -26,101 +28,106 @@ + inkscape:window-y="0" + inkscape:window-x="0" + inkscape:cy="50.5" + inkscape:cx="50.499992" + inkscape:zoom="0.96" + showgrid="false" + id="namedview3921" + inkscape:window-height="834" + inkscape:window-width="1229" + inkscape:pageshadow="2" + inkscape:pageopacity="0" + guidetolerance="10" + gridtolerance="10" + objecttolerance="10" + borderopacity="1" + bordercolor="#666666" + pagecolor="#ffffff" /> + stroke-width="1" + stroke="#c0c0c0" + fill="#c0c0c0" + d="M 98.499992,0.5 H 294.49999 l 98,170 -98,170 H 98.499992 L 0.49999229,170.5 Z" /> - + stroke="#ffffff" + y2="229.5" + x2="162.49998" + y1="281.5" + x1="132.49998" /> - - + + - + + + stroke-width="26" + stroke="#000000" + y2="232.5" + x2="160.49998" + y1="278.5" + x1="134.49998" /> + stroke-width="1" + stroke="#000000" + fill="none" + d="M 98.499992,0.5 H 294.49999 l 98,170 -98,170 H 98.499992 L 0.49999229,170.5 Z" /> + rx="38" + style="fill:#ffffff;stroke:#000000;stroke-width:2;stroke-linejoin:round" /> 30 + dy="15.3" + y="83.833336" + x="265.08334" + style="font-size:51px;font-family:'Bookman Old Style';text-anchor:middle;fill:#000000;stroke:#000000">30 diff --git a/src/main/resources/tiles/svg/tile-18CH03.svg b/src/main/resources/tiles/svg/tile-18CH03.svg index 2f7a8eb68..28f14a05f 100644 --- a/src/main/resources/tiles/svg/tile-18CH03.svg +++ b/src/main/resources/tiles/svg/tile-18CH03.svg @@ -7,10 +7,12 @@ xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - version="1.1" - id="svg3869" + height="357" + width="393" + inkscape:version="1.0 (4035a4fb49, 2020-05-01)" sodipodi:docname="tile-18CH03.svg" - inkscape:version="0.92.4 (5da689c313, 2019-01-14)"> + id="svg3869" + version="1.1"> @@ -26,112 +28,117 @@ + inkscape:window-y="0" + inkscape:window-x="0" + inkscape:cy="50.5" + inkscape:cx="50.499992" + inkscape:zoom="0.71808822" + showgrid="false" + id="namedview3871" + inkscape:window-height="919" + inkscape:window-width="1487" + inkscape:pageshadow="2" + inkscape:pageopacity="0" + guidetolerance="10" + gridtolerance="10" + objecttolerance="10" + borderopacity="1" + bordercolor="#666666" + pagecolor="#ffffff" /> + stroke-width="1" + stroke="#c0c0c0" + fill="#c0c0c0" + d="M 98.499992,0.5 H 294.49999 l 98,170 -98,170 H 98.499992 L 0.49999229,170.5 Z" /> - + stroke="#ffffff" + y2="162.5" + x2="183.49998" + y1="132.5" + x1="131.49998" /> - - + + - + + - + - + - 30 - + font-size="51" + font-family="Bookman Old Style" + text-anchor="middle" + stroke="#000000" + fill="#000000" + dy="12" + y="43.5" + x="269.5">30 + stroke-width="1" + stroke="#000000" + fill="none" + d="M 98.499992,0.5 H 294.49999 l 98,170 -98,170 H 98.499992 L 0.49999229,170.5 Z" /> diff --git a/src/main/resources/tiles/svg/tile-18CHOO.svg b/src/main/resources/tiles/svg/tile-18CHOO.svg index 0f3ec7708..ba0eaec8b 100644 --- a/src/main/resources/tiles/svg/tile-18CHOO.svg +++ b/src/main/resources/tiles/svg/tile-18CHOO.svg @@ -7,10 +7,12 @@ xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - version="1.1" - id="svg3781" + height="357" + width="393" + inkscape:version="1.0 (4035a4fb49, 2020-05-01)" sodipodi:docname="tile-18CHOO.svg" - inkscape:version="0.92.4 (5da689c313, 2019-01-14)"> + id="svg3781" + version="1.1"> @@ -26,168 +28,171 @@ + inkscape:window-y="-9" + inkscape:window-x="-9" + inkscape:cy="50.5" + inkscape:cx="50.499992" + inkscape:zoom="0.95375" + showgrid="false" + id="namedview3783" + inkscape:window-height="2081" + inkscape:window-width="3840" + inkscape:pageshadow="2" + inkscape:pageopacity="0" + guidetolerance="10" + gridtolerance="10" + objecttolerance="10" + borderopacity="1" + bordercolor="#666666" + pagecolor="#ffffff" /> + stroke-width="1" + stroke="#ffff00" + fill="#ffff00" + d="M 98.499992,0.5 H 294.49999 l 98,170 -98,170 H 98.499992 L 0.49999229,170.5 Z" /> - + + stroke="#ffffff" + fill="#ffffff" + r="51" + cy="212.5" + cx="123.49999" /> - - + d="m 196.49999,340.5 a 98,98 0 0 0 -49,-85 l -24,-43" /> + + - + - + - + 30 - 30 + - + - 30 + fill="#ffffff" + cy="107.5" + cx="86.499992" + ry="34" + rx="38" /> 30 + - OO - + sodipodi:role="line">OO + stroke-width="1" + stroke="#000000" + fill="none" + d="M 98.499992,0.5 H 294.49999 l 98,170 -98,170 H 98.499992 L 0.49999229,170.5 Z" /> + rx="38" + style="fill:#ffffff;stroke:#000000;stroke-width:2;stroke-linejoin:round" /> 30 + dy="15.3" + y="216.8551" + x="313.03799" + style="font-size:51px;font-family:'Bookman Old Style';text-anchor:middle;fill:#000000;stroke:#000000">30 diff --git a/src/main/resources/tiles/svg/tile-2059.svg b/src/main/resources/tiles/svg/tile-2059.svg index 8d77c7f1f..e2d81355b 100644 --- a/src/main/resources/tiles/svg/tile-2059.svg +++ b/src/main/resources/tiles/svg/tile-2059.svg @@ -1,2 +1,180 @@ - -3030X + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + 30 + + + 30 + X + + diff --git a/src/main/resources/tiles/svg/tile-3059.svg b/src/main/resources/tiles/svg/tile-3059.svg index 21313efab..173d3a0cc 100644 --- a/src/main/resources/tiles/svg/tile-3059.svg +++ b/src/main/resources/tiles/svg/tile-3059.svg @@ -1,2 +1,180 @@ - -3030X + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + 30 + + + 30 + X + + diff --git a/src/main/resources/tiles/svg/tile-37001.svg b/src/main/resources/tiles/svg/tile-37001.svg index 055eeace8..30d7b3044 100644 --- a/src/main/resources/tiles/svg/tile-37001.svg +++ b/src/main/resources/tiles/svg/tile-37001.svg @@ -1,2 +1,102 @@ - - + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/src/main/resources/tiles/svg/tile-37002.svg b/src/main/resources/tiles/svg/tile-37002.svg index 5ba89d4a5..d7ab90c06 100644 --- a/src/main/resources/tiles/svg/tile-37002.svg +++ b/src/main/resources/tiles/svg/tile-37002.svg @@ -1,2 +1,172 @@ - -10 + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + 10 + + diff --git a/src/main/resources/tiles/svg/tile-37003.svg b/src/main/resources/tiles/svg/tile-37003.svg index 910c6eafb..48e78e2cd 100644 --- a/src/main/resources/tiles/svg/tile-37003.svg +++ b/src/main/resources/tiles/svg/tile-37003.svg @@ -1,2 +1,114 @@ - - + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/src/main/resources/tiles/svg/tile-37007.svg b/src/main/resources/tiles/svg/tile-37007.svg index 45fb4a528..b6b7a68a1 100644 --- a/src/main/resources/tiles/svg/tile-37007.svg +++ b/src/main/resources/tiles/svg/tile-37007.svg @@ -1,2 +1,94 @@ - -T + + + + + + image/svg+xml + + + + + + + + + + + T + + diff --git a/src/main/resources/tiles/svg/tile-37008.svg b/src/main/resources/tiles/svg/tile-37008.svg index 831cb6c02..8cf098fba 100644 --- a/src/main/resources/tiles/svg/tile-37008.svg +++ b/src/main/resources/tiles/svg/tile-37008.svg @@ -1,2 +1,94 @@ - -X + + + + + + image/svg+xml + + + + + + + + + + + X + + diff --git a/src/main/resources/tiles/svg/tile-37009.svg b/src/main/resources/tiles/svg/tile-37009.svg index 9cd7f32f6..06dbf5ee0 100644 --- a/src/main/resources/tiles/svg/tile-37009.svg +++ b/src/main/resources/tiles/svg/tile-37009.svg @@ -1,2 +1,120 @@ - -20 + + + + + + image/svg+xml + + + + + + + + + + + + + + 20 + + diff --git a/src/main/resources/tiles/svg/tile-37010.svg b/src/main/resources/tiles/svg/tile-37010.svg index 3fe8f4c20..faec6a56c 100644 --- a/src/main/resources/tiles/svg/tile-37010.svg +++ b/src/main/resources/tiles/svg/tile-37010.svg @@ -1,2 +1,200 @@ - -4040 + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + 40 + + + 40 + + diff --git a/src/main/resources/tiles/svg/tile-37011.svg b/src/main/resources/tiles/svg/tile-37011.svg index 9c133c75e..c3f2fd381 100644 --- a/src/main/resources/tiles/svg/tile-37011.svg +++ b/src/main/resources/tiles/svg/tile-37011.svg @@ -1,2 +1,130 @@ - -30X + + + + + + image/svg+xml + + + + + + + + + + + + + + 30 + X + + diff --git a/src/main/resources/tiles/svg/tile-37012.svg b/src/main/resources/tiles/svg/tile-37012.svg index 47035f28c..e8ee51980 100644 --- a/src/main/resources/tiles/svg/tile-37012.svg +++ b/src/main/resources/tiles/svg/tile-37012.svg @@ -1,2 +1,286 @@ - -40404040Wien + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + 40 + + + 40 + + + 40 + + + 40 + Wien + + diff --git a/src/main/resources/tiles/svg/tile-37103.svg b/src/main/resources/tiles/svg/tile-37103.svg index 74cc31601..e9b70a942 100644 --- a/src/main/resources/tiles/svg/tile-37103.svg +++ b/src/main/resources/tiles/svg/tile-37103.svg @@ -1,2 +1,138 @@ - -10 + + + + + + image/svg+xml + + + + + + + + + + + + + + + + 10 + + diff --git a/src/main/resources/tiles/svg/tile-37109.svg b/src/main/resources/tiles/svg/tile-37109.svg index b68355b16..ba14549a2 100644 --- a/src/main/resources/tiles/svg/tile-37109.svg +++ b/src/main/resources/tiles/svg/tile-37109.svg @@ -1,2 +1,84 @@ - - + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/src/main/resources/tiles/svg/tile-37123.svg b/src/main/resources/tiles/svg/tile-37123.svg index a3b36426a..a6eba5246 100644 --- a/src/main/resources/tiles/svg/tile-37123.svg +++ b/src/main/resources/tiles/svg/tile-37123.svg @@ -1,2 +1,100 @@ - - + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/src/main/resources/tiles/svg/tile-37156.svg b/src/main/resources/tiles/svg/tile-37156.svg index 1e8b5ba62..cb3f8a6d5 100644 --- a/src/main/resources/tiles/svg/tile-37156.svg +++ b/src/main/resources/tiles/svg/tile-37156.svg @@ -1,2 +1,208 @@ - -1010 + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + 10 + + + 10 + + diff --git a/src/main/resources/tiles/svg/tile-37158.svg b/src/main/resources/tiles/svg/tile-37158.svg index f4948a80e..cacfec9d6 100644 --- a/src/main/resources/tiles/svg/tile-37158.svg +++ b/src/main/resources/tiles/svg/tile-37158.svg @@ -1,2 +1,138 @@ - -10 + + + + + + image/svg+xml + + + + + + + + + + + + + + + + 10 + + diff --git a/src/main/resources/tiles/svg/tile-37206.svg b/src/main/resources/tiles/svg/tile-37206.svg index 06ac7087c..851fc34e6 100644 --- a/src/main/resources/tiles/svg/tile-37206.svg +++ b/src/main/resources/tiles/svg/tile-37206.svg @@ -1,2 +1,152 @@ - -30 + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + 30 + + diff --git a/src/main/resources/tiles/svg/tile-37402.svg b/src/main/resources/tiles/svg/tile-37402.svg index 1b7f88116..bd1c3accb 100644 --- a/src/main/resources/tiles/svg/tile-37402.svg +++ b/src/main/resources/tiles/svg/tile-37402.svg @@ -1,2 +1,146 @@ - -20X + + + + + + image/svg+xml + + + + + + + + + + + + + + + + 20 + X + + diff --git a/src/main/resources/tiles/svg/tile-80001.svg b/src/main/resources/tiles/svg/tile-80001.svg index 7b6504c17..c5dee0db2 100644 --- a/src/main/resources/tiles/svg/tile-80001.svg +++ b/src/main/resources/tiles/svg/tile-80001.svg @@ -1,7 +1,90 @@ - - - - - - - + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/src/main/resources/tiles/svg/tile-80002.svg b/src/main/resources/tiles/svg/tile-80002.svg index 1c091a798..2533a2abb 100644 --- a/src/main/resources/tiles/svg/tile-80002.svg +++ b/src/main/resources/tiles/svg/tile-80002.svg @@ -1,10 +1,112 @@ - - - - - - - - - - + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/src/main/resources/tiles/svg/tile-80003.svg b/src/main/resources/tiles/svg/tile-80003.svg index 5f4db2680..8e83a6f41 100644 --- a/src/main/resources/tiles/svg/tile-80003.svg +++ b/src/main/resources/tiles/svg/tile-80003.svg @@ -1,2 +1,94 @@ - -S + + + + + + image/svg+xml + + + + + + + + + + + S + + diff --git a/src/main/resources/tiles/svg/tile-80004.svg b/src/main/resources/tiles/svg/tile-80004.svg index 54fbae8f9..ebbac2df4 100644 --- a/src/main/resources/tiles/svg/tile-80004.svg +++ b/src/main/resources/tiles/svg/tile-80004.svg @@ -1,2 +1,295 @@ - -20202020Beijing + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + 20 + + + 20 + + + 20 + + + 20 + Beijing + + diff --git a/src/main/resources/tiles/svg/tile-80020.svg b/src/main/resources/tiles/svg/tile-80020.svg index 5f6593142..649a2562d 100644 --- a/src/main/resources/tiles/svg/tile-80020.svg +++ b/src/main/resources/tiles/svg/tile-80020.svg @@ -1,2 +1,100 @@ - - + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/src/main/resources/tiles/svg/tile-9021.svg b/src/main/resources/tiles/svg/tile-9021.svg index c1934b47b..aaf98b680 100644 --- a/src/main/resources/tiles/svg/tile-9021.svg +++ b/src/main/resources/tiles/svg/tile-9021.svg @@ -7,12 +7,12 @@ xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - version="1.1" + sodipodi:docname="tile-9021.svg" + height="357" + width="393" + inkscape:version="1.0 (4035a4fb49, 2020-05-01)" id="svg2" - inkscape:version="0.48.2 r9819" - width="100%" - height="100%" - sodipodi:docname="tile-902.svg"> + version="1.1"> @@ -28,33 +28,38 @@ + showgrid="false" + id="namedview10" + inkscape:window-height="2081" + inkscape:window-width="3840" + inkscape:pageshadow="2" + inkscape:pageopacity="0" + guidetolerance="10" + gridtolerance="10" + objecttolerance="10" + borderopacity="1" + bordercolor="#666666" + pagecolor="#ffffff" /> + stroke-linejoin="round" + stroke-width="1" + stroke="#ff0000" + fill="#FF0000" + d="M 98.499992,0.5 H 294.49999 l 98,170 -98,170 H 98.499992 L 0.49999229,170.5 Z" /> @@ -67,18 +72,18 @@ + stroke-width="1" + stroke="#000000" + fill="none" + d="M 98.499992,0.5 H 294.49999 l 98,170 -98,170 H 98.499992 L 0.49999229,170.5 Z" /> + id="path2565" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:4.50927;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 356.18998,234.07739 -112.44692,-35.88453 87.88082,78.26613" /> + id="path2577" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:4.50927;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 356.18998,107.89027 243.74306,143.7748 331.62388,65.508666" /> diff --git a/src/main/resources/tiles/svg/tile-9031.svg b/src/main/resources/tiles/svg/tile-9031.svg index 157422cf9..5e8e95cba 100644 --- a/src/main/resources/tiles/svg/tile-9031.svg +++ b/src/main/resources/tiles/svg/tile-9031.svg @@ -7,12 +7,12 @@ xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - version="1.1" + sodipodi:docname="tile-9031.svg" + height="357" + width="393" + inkscape:version="1.0 (4035a4fb49, 2020-05-01)" id="svg2" - inkscape:version="0.48.2 r9819" - width="100%" - height="100%" - sodipodi:docname="tile-903.svg"> + version="1.1"> @@ -28,53 +28,58 @@ + showgrid="false" + id="namedview11" + inkscape:window-height="2081" + inkscape:window-width="3840" + inkscape:pageshadow="2" + inkscape:pageopacity="0" + guidetolerance="10" + gridtolerance="10" + objecttolerance="10" + borderopacity="1" + bordercolor="#666666" + pagecolor="#ffffff" /> + stroke-linejoin="round" + stroke-width="1" + stroke="#ff0000" + fill="#FF0000" + d="M 98.499992,0.5 H 294.49999 l 98,170 -98,170 H 98.499992 L 0.49999229,170.5 Z" /> + stroke-width="1" + stroke="#000000" + fill="none" + d="M 98.499992,0.5 H 294.49999 l 98,170 -98,170 H 98.499992 L 0.49999229,170.5 Z" /> + id="path2565" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:4.50927;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 356.18998,234.07739 -112.44692,-35.88453 87.88082,78.26613" /> + id="path2577" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:4.50927;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 356.18998,107.89027 243.74306,143.7748 331.62388,65.508666" /> + id="path2639" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:4.50927;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 223.45925,340.67143 198.3127,225.34727 174.47266,340.58736" /> diff --git a/src/main/resources/tiles/svg/tile1012.svg b/src/main/resources/tiles/svg/tile1012.svg index 1b82ce618..9acdde68f 100644 --- a/src/main/resources/tiles/svg/tile1012.svg +++ b/src/main/resources/tiles/svg/tile1012.svg @@ -1,2 +1,191 @@ - -50X + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + 50 + X + + diff --git a/src/main/resources/tiles/svg/tile1013.svg b/src/main/resources/tiles/svg/tile1013.svg index 84a832b1a..a7b43772b 100644 --- a/src/main/resources/tiles/svg/tile1013.svg +++ b/src/main/resources/tiles/svg/tile1013.svg @@ -1,2 +1,191 @@ - -50X + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + 50 + X + + diff --git a/src/main/resources/tiles/svg/tile1091.svg b/src/main/resources/tiles/svg/tile1091.svg new file mode 100644 index 000000000..21bcf54c0 --- /dev/null +++ b/src/main/resources/tiles/svg/tile1091.svg @@ -0,0 +1,203 @@ + + + + + + image/svg+xml + + + + + + + + + 1091 + + + + + + + + + + + + + + 50 + X + + diff --git a/src/main/resources/tiles/svg/tile1092.svg b/src/main/resources/tiles/svg/tile1092.svg new file mode 100644 index 000000000..61522f1f7 --- /dev/null +++ b/src/main/resources/tiles/svg/tile1092.svg @@ -0,0 +1,203 @@ + + + + + + image/svg+xml + + + + + + + + + 1092 + + + + + + + + + + + + + + 50 + X + + diff --git a/src/main/resources/tiles/svg/tile1093.svg b/src/main/resources/tiles/svg/tile1093.svg new file mode 100644 index 000000000..6a31a1468 --- /dev/null +++ b/src/main/resources/tiles/svg/tile1093.svg @@ -0,0 +1,157 @@ + + + + + + image/svg+xml + + + + + + + + + 1093 + + + + + + + + 70 + Z + + diff --git a/src/main/resources/tiles/svg/tile1205.svg b/src/main/resources/tiles/svg/tile1205.svg index 9289e6d48..8c503135c 100644 --- a/src/main/resources/tiles/svg/tile1205.svg +++ b/src/main/resources/tiles/svg/tile1205.svg @@ -1,2 +1,191 @@ - -50X + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + 50 + X + + diff --git a/src/main/resources/tiles/svg/tile1219.svg b/src/main/resources/tiles/svg/tile1219.svg index 179a4d0b3..3bcd833b7 100644 --- a/src/main/resources/tiles/svg/tile1219.svg +++ b/src/main/resources/tiles/svg/tile1219.svg @@ -1,2 +1,207 @@ - -70X + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + 70 + X + + diff --git a/src/main/resources/tiles/svg/tile1336.svg b/src/main/resources/tiles/svg/tile1336.svg index 1e5b4659c..45c59e9ab 100644 --- a/src/main/resources/tiles/svg/tile1336.svg +++ b/src/main/resources/tiles/svg/tile1336.svg @@ -1,2 +1,145 @@ - -70Z + + + + + + image/svg+xml + + + + + + + + + + + + + + + + 70 + Z + + diff --git a/src/main/resources/tiles/svg/tile18CHX1.svg b/src/main/resources/tiles/svg/tile18CHX1.svg index 1119ba225..53430e66b 100644 --- a/src/main/resources/tiles/svg/tile18CHX1.svg +++ b/src/main/resources/tiles/svg/tile18CHX1.svg @@ -7,10 +7,12 @@ xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - version="1.1" - id="svg6105" + height="357" + width="393" + inkscape:version="1.0 (4035a4fb49, 2020-05-01)" sodipodi:docname="tile18CHX1.svg" - inkscape:version="0.92.4 (5da689c313, 2019-01-14)"> + id="svg6105" + version="1.1"> @@ -26,136 +28,141 @@ + inkscape:window-y="-9" + inkscape:window-x="-9" + inkscape:cy="50.5" + inkscape:cx="50.499992" + inkscape:zoom="1" + showgrid="false" + id="namedview6107" + inkscape:window-height="2081" + inkscape:window-width="3840" + inkscape:pageshadow="2" + inkscape:pageopacity="0" + guidetolerance="10" + gridtolerance="10" + objecttolerance="10" + borderopacity="1" + bordercolor="#666666" + pagecolor="#ffffff" /> + stroke-width="1" + stroke="#ffff00" + fill="#ffff00" + d="M 98.499992,0.5 H 294.49999 l 98,170 -98,170 H 98.499992 L 0.49999229,170.5 Z" /> - X1 - + font-weight="bold" + font-size="31" + font-family="Arial" + text-anchor="middle" + stroke="#000000" + fill="#000000" + dy="9.3000002" + y="318.5" + x="245.49998">X1 + stroke="#ffffff" + fill="#ffffff" + r="51" + cy="170.5" + cx="196.49998" /> - - + d="M 196.49999,170.5 V 0.5" /> + + - + - + - 30 + fill="#ffffff" + cy="43.5" + cx="123.49999" + ry="30" + rx="31" /> 30 + - DC - + font-size="54" + font-family="TimpaniHeavy" + text-anchor="middle" + stroke="#000000" + fill="#000000" + dy="16.200001" + y="43.5" + x="269.5">DC + stroke-width="1" + stroke="#000000" + fill="none" + d="M 98.499992,0.5 H 294.49999 l 98,170 -98,170 H 98.499992 L 0.49999229,170.5 Z" /> diff --git a/src/main/resources/tiles/svg/tile18CHX2.svg b/src/main/resources/tiles/svg/tile18CHX2.svg index e719a8674..2dece1653 100644 --- a/src/main/resources/tiles/svg/tile18CHX2.svg +++ b/src/main/resources/tiles/svg/tile18CHX2.svg @@ -7,10 +7,12 @@ xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - version="1.1" - id="svg6029" + height="357" + width="393" + inkscape:version="1.0 (4035a4fb49, 2020-05-01)" sodipodi:docname="tile18CHX2.svg" - inkscape:version="0.92.4 (5da689c313, 2019-01-14)"> + id="svg6029" + version="1.1"> @@ -26,212 +28,219 @@ + inkscape:window-y="-9" + inkscape:window-x="-9" + inkscape:cy="50.5" + inkscape:cx="50.499992" + inkscape:zoom="1" + showgrid="false" + id="namedview6031" + inkscape:window-height="2081" + inkscape:window-width="3840" + inkscape:pageshadow="2" + inkscape:pageopacity="0" + guidetolerance="10" + gridtolerance="10" + objecttolerance="10" + borderopacity="1" + bordercolor="#666666" + pagecolor="#ffffff" /> + stroke-width="1" + stroke="#38ac00" + fill="#38ac00" + d="M 98.499992,0.5 H 294.49999 l 98,170 -98,170 H 98.499992 L 0.49999229,170.5 Z" /> - X2 - + font-weight="bold" + font-size="31" + font-family="Arial" + text-anchor="middle" + stroke="#000000" + fill="#000000" + dy="9.3000002" + y="318.5" + x="245.49998">X2 + stroke="#ffffff" + fill="#ffffff" + points="145,119 247,119 247,221 145,221 " /> - + + stroke="#ffffff" + fill="#ffffff" + r="51" + cy="170.5" + cx="247.49998" /> - - - + d="m 196.49999,170.5 147,-85" /> - - + d="m 196.49999,170.5 147,85" /> - + + + stroke-linecap="butt" + stroke-width="34" + stroke="#ffffff" + fill="none" + d="M 196.49999,170.5 49.499992,85.5" /> + + + + - + - + fill="#ffffff" + points="145,119 247,119 247,221 145,221 " /> + - + - 40 + fill="#ffffff" + cy="43.5" + cx="123.49999" + ry="30" + rx="31" /> 40 + - DC - + font-size="54" + font-family="TimpaniHeavy" + text-anchor="middle" + stroke="#000000" + fill="#000000" + dy="16.200001" + y="85.5" + x="196.49998">DC + stroke-width="1" + stroke="#000000" + fill="none" + d="M 98.499992,0.5 H 294.49999 l 98,170 -98,170 H 98.499992 L 0.49999229,170.5 Z" /> diff --git a/src/main/resources/tiles/svg/tile18CHX3.svg b/src/main/resources/tiles/svg/tile18CHX3.svg index 22fc3c5a2..1d558e41f 100644 --- a/src/main/resources/tiles/svg/tile18CHX3.svg +++ b/src/main/resources/tiles/svg/tile18CHX3.svg @@ -7,10 +7,12 @@ xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - version="1.1" - id="svg3801" + height="357" + width="393" + inkscape:version="1.0 (4035a4fb49, 2020-05-01)" sodipodi:docname="tile18CHX3.svg" - inkscape:version="0.92.4 (5da689c313, 2019-01-14)"> + id="svg3801" + version="1.1"> @@ -19,161 +21,165 @@ image/svg+xml + + inkscape:window-y="-9" + inkscape:window-x="-9" + inkscape:cy="-214.75888" + inkscape:cx="155.35766" + inkscape:zoom="1" + showgrid="false" + id="namedview3803" + inkscape:window-height="2081" + inkscape:window-width="3840" + inkscape:pageshadow="2" + inkscape:pageopacity="0" + guidetolerance="10" + gridtolerance="10" + objecttolerance="10" + borderopacity="1" + bordercolor="#666666" + pagecolor="#ffffff" /> + id="path3761" + d="M 0.49999227,176.32374 94.871871,4.539139 291.05466,0.49999942 392.86557,168.24546 298.49369,340.03006 102.3109,344.0692 Z" /> - X3 - + sodipodi:role="line">X3 - + + id="circle3767" + r="51" + cy="279.33618" + cx="25.701441" /> + id="path3769" + d="M 345.67963,254.13776 A 294,294 0 0 0 274.25438,226.3091" /> + id="path3771" + d="M 274.25438,226.3091 A 294,294 0 0 0 51.405446,260.19647" /> + id="path3773" + d="M 47.685932,90.431439 A 294,294 0 0 0 119.11118,118.2601" /> + id="path3775" + d="M 119.11118,118.2601 A 294,294 0 0 0 341.96011,84.37273" /> + id="path3777" + d="M 345.67963,254.13776 A 294,294 0 0 0 274.25438,226.3091" /> + id="path3779" + d="M 274.25438,226.3091 A 294,294 0 0 0 51.405446,260.19647" /> + id="path3781" + d="M 47.685932,90.431439 A 294,294 0 0 0 119.11118,118.2601" /> + id="path3783" + d="M 119.11118,118.2601 A 294,294 0 0 0 341.96011,84.37273" /> + id="circle3785" + r="51" + cy="221.33618" + cx="-144.29855" /> + id="ellipse3787" + cy="173.47737" + cx="55.622807" + ry="34" + rx="38" /> 40 + id="text3789" + font-size="51" + dy="15.3" + y="173.47737" + x="55.622807">40 + id="circle3791" + r="51" + cy="279.33618" + cx="25.701441" /> + id="ellipse3793" + cy="175.53395" + cx="334.39041" + ry="34" + rx="38" /> 40 - 40 + OO + id="text3797" + font-size="51" + dy="15.3" + y="44.213486" + x="136.55901">OO + id="path3799" + d="M 0.49999227,176.32374 94.871871,4.539139 291.05466,0.49999942 392.86557,168.24546 298.49369,340.03006 102.3109,344.0692 Z" /> diff --git a/src/main/resources/tiles/svg/tile18CHX4.svg b/src/main/resources/tiles/svg/tile18CHX4.svg index 86b6c22a7..0a528bd0b 100644 --- a/src/main/resources/tiles/svg/tile18CHX4.svg +++ b/src/main/resources/tiles/svg/tile18CHX4.svg @@ -1,2 +1,214 @@ - -88624040OO + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + 40 + + + 40 + OO + + diff --git a/src/main/resources/tiles/svg/tile18CHX5.svg b/src/main/resources/tiles/svg/tile18CHX5.svg index 9769dee5a..6c8e153f3 100644 --- a/src/main/resources/tiles/svg/tile18CHX5.svg +++ b/src/main/resources/tiles/svg/tile18CHX5.svg @@ -7,10 +7,12 @@ xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - version="1.1" - id="svg5915" + height="357" + width="393" + inkscape:version="1.0 (4035a4fb49, 2020-05-01)" sodipodi:docname="tile18CHX5.svg" - inkscape:version="0.92.4 (5da689c313, 2019-01-14)"> + id="svg5915" + version="1.1"> @@ -26,188 +28,192 @@ + inkscape:window-y="-9" + inkscape:window-x="-9" + inkscape:cy="-135.61331" + inkscape:cx="156.28635" + inkscape:zoom="1.26" + showgrid="false" + id="namedview5917" + inkscape:window-height="2081" + inkscape:window-width="3840" + inkscape:pageshadow="2" + inkscape:pageopacity="0" + guidetolerance="10" + gridtolerance="10" + objecttolerance="10" + borderopacity="1" + bordercolor="#666666" + pagecolor="#ffffff" /> + inkscape:groupmode="layer"> + id="path5875" + d="M 293.9794,-0.01187 97.97941,0.01187 0,170.02374 l 98.02059,169.98813 196,-0.0237 L 392,169.97626 Z" /> - X5 - + id="tspan5923" + sodipodi:role="line">X5 + id="circle5879" + r="51" + cy="133.51494" + cx="-286.69855" /> + id="path5883" + d="m 196.02059,339.99999 a 294,294 0 0 1 9.99079,-76.0012" /> + id="path5885" + d="M 206.01138,263.99879 A 294,294 0 0 1 342.9897,84.9822" /> + id="path5891" + d="m 196.02059,339.99999 a 294,294 0 0 1 9.99079,-76.0012" /> + id="path5893" + d="M 206.01138,263.99879 A 294,294 0 0 1 342.9897,84.9822" /> + transform="matrix(0.25077529,0.96804533,0.96804533,-0.25077529,-258.84606,113.52913)" + id="g3881"> - + + inkscape:connector-curvature="0" + style="fill:none;stroke:#000000;stroke-width:26;stroke-linecap:butt;stroke-linejoin:round" /> + id="circle5899" + r="51" + cy="133.51494" + cx="-286.69855" /> + transform="rotate(-177.21392,76.033944,194.61998)" + id="g3885"> + cx="75.409348" + cy="248.70329" + id="ellipse5901" + style="fill:#ffffff;stroke:#000000;stroke-width:2;stroke-linejoin:round" + transform="rotate(-2.9323425)" /> 40 + dy="15.3" + font-size="51" + id="text5903" + style="font-size:51px;font-family:'Bookman Old Style';text-anchor:middle;fill:#000000;stroke:#000000" + transform="rotate(-2.9323425)">40 + transform="matrix(-0.99985321,-0.01713387,-0.01713387,0.99985321,485.76684,121.46733)" + id="g3889"> + transform="matrix(0.99804543,0.06249257,0.06249257,-0.99804543,-22.761253,194.59874)" + id="g3922"> + id="ellipse5907" + cy="278.9137" + cx="256.92569" + ry="34" + rx="38" /> 40 + id="text5909" + font-size="51" + dy="15.3" + y="279.71207" + x="255.34076">40 OO + id="text5911" + font-size="51" + dy="15.3" + y="300.58749" + x="-267.23343">OO + id="path5913" + d="M 293.9794,-0.01187 97.97941,0.01187 0,170.02374 l 98.02059,169.98813 196,-0.0237 L 392,169.97626 Z" /> + transform="matrix(0.96574948,0.2594763,0.2594763,-0.96574948,-33.42512,467.39253)" + id="g3914"> - + + inkscape:connector-curvature="0" + style="fill:none;stroke:#000000;stroke-width:26.4907;stroke-linecap:butt;stroke-linejoin:round" /> + transform="matrix(0.99990015,-0.01413148,-0.01413148,-0.99990015,-71.17077,493.03119)" + id="g3877"> - + + r="51" + id="circle5905" + style="fill:#ffffff;stroke:#000000;stroke-width:4" + transform="rotate(179.19724)" /> diff --git a/src/main/resources/tiles/svg/tile18CHX51.svg b/src/main/resources/tiles/svg/tile18CHX51.svg index 0d528c3e6..c59f37a46 100644 --- a/src/main/resources/tiles/svg/tile18CHX51.svg +++ b/src/main/resources/tiles/svg/tile18CHX51.svg @@ -7,10 +7,12 @@ xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - version="1.1" + height="357" + width="393" + inkscape:version="1.0 (4035a4fb49, 2020-05-01)" + sodipodi:docname="tile18CHX51.svg" id="svg5915" - sodipodi:docname="tile18CHX5.svg" - inkscape:version="0.92.4 (5da689c313, 2019-01-14)"> + version="1.1"> @@ -19,195 +21,199 @@ image/svg+xml - + + inkscape:window-y="-9" + inkscape:window-x="-9" + inkscape:cy="-135.61331" + inkscape:cx="156.28635" + inkscape:zoom="1.26" + showgrid="false" + id="namedview5917" + inkscape:window-height="2081" + inkscape:window-width="3840" + inkscape:pageshadow="2" + inkscape:pageopacity="0" + guidetolerance="10" + gridtolerance="10" + objecttolerance="10" + borderopacity="1" + bordercolor="#666666" + pagecolor="#ffffff" /> + inkscape:groupmode="layer"> + id="path5875" + d="M 98.0206,340.01187 294.02059,339.98813 392,169.97626 293.97941,-0.01187 97.97941,0.01187 0,170.02374 Z" /> - X5 - + id="tspan5923" + sodipodi:role="line">X5 + id="circle5879" + r="51" + cy="-206.53255" + cx="105.26026" /> + id="path5883" + d="m 195.97941,1e-5 a 294,294 0 0 1 -9.99079,76.0012" /> + id="path5885" + d="M 185.98862,76.00121 A 294,294 0 0 1 49.0103,255.0178" /> + id="path5891" + d="m 195.97941,1e-5 a 294,294 0 0 1 -9.99079,76.0012" /> + id="path5893" + d="M 185.98862,76.00121 A 294,294 0 0 1 49.0103,255.0178" /> + transform="matrix(-0.25077529,-0.96804533,-0.96804533,0.25077529,650.84606,226.47087)" + id="g3881"> - + + inkscape:connector-curvature="0" + style="fill:none;stroke:#000000;stroke-width:26;stroke-linecap:butt;stroke-linejoin:round" /> + id="circle5899" + r="51" + cy="-206.53255" + cx="105.26026" /> + transform="rotate(2.78608,1208.421,5103.2354)" + id="g3885"> + cx="75.409348" + cy="248.70329" + id="ellipse5901" + style="fill:#ffffff;stroke:#000000;stroke-width:2;stroke-linejoin:round" + transform="rotate(-2.9323425)" /> 40 + dy="15.3" + font-size="51" + id="text5903" + style="font-size:51px;font-family:'Bookman Old Style';text-anchor:middle;fill:#000000;stroke:#000000" + transform="rotate(-2.9323425)">40 + transform="matrix(0.99985321,0.01713387,0.01713387,-0.99985321,-93.76684,218.53267)" + id="g3889"> + transform="matrix(0.99804543,0.06249257,0.06249257,-0.99804543,-22.761253,194.59874)" + id="g3922"> + id="ellipse5907" + cy="278.9137" + cx="256.92569" + ry="34" + rx="38" /> 40 + id="text5909" + font-size="51" + dy="15.3" + y="279.71207" + x="255.34076">40 OO + id="text5911" + font-size="51" + dy="15.3" + y="-39.459984" + x="124.72537">OO + id="path5913" + d="M 98.0206,340.01187 294.02059,339.98813 392,169.97626 293.97941,-0.01187 97.97941,0.01187 0,170.02374 Z" /> + transform="matrix(-0.96574948,-0.2594763,-0.2594763,0.96574948,425.42512,-127.39253)" + id="g3914"> - + + inkscape:connector-curvature="0" + style="fill:none;stroke:#000000;stroke-width:26.4907;stroke-linecap:butt;stroke-linejoin:round" /> + transform="matrix(-0.99990015,0.01413148,0.01413148,0.99990015,463.17077,-153.03119)" + id="g3877"> - + + r="51" + id="circle5905" + style="fill:#ffffff;stroke:#000000;stroke-width:4" + transform="rotate(179.19724)" /> diff --git a/src/main/resources/tiles/svg/tile18CHX6.svg b/src/main/resources/tiles/svg/tile18CHX6.svg index b01fee2b2..bf539e966 100644 --- a/src/main/resources/tiles/svg/tile18CHX6.svg +++ b/src/main/resources/tiles/svg/tile18CHX6.svg @@ -7,10 +7,12 @@ xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - version="1.1" - id="svg5805" + height="357" + width="393" + inkscape:version="1.0 (4035a4fb49, 2020-05-01)" sodipodi:docname="tile18CHX6.svg" - inkscape:version="0.92.4 (5da689c313, 2019-01-14)"> + id="svg5805" + version="1.1"> @@ -26,248 +28,255 @@ + inkscape:window-y="-9" + inkscape:window-x="-9" + inkscape:cy="50.5" + inkscape:cx="50.499992" + inkscape:zoom="1" + showgrid="false" + id="namedview5807" + inkscape:window-height="2081" + inkscape:window-width="3840" + inkscape:pageshadow="2" + inkscape:pageopacity="0" + guidetolerance="10" + gridtolerance="10" + objecttolerance="10" + borderopacity="1" + bordercolor="#666666" + pagecolor="#ffffff" /> + stroke-width="1" + stroke="#b46301" + fill="#b46301" + d="M 98.499992,0.5 H 294.49999 l 98,170 -98,170 H 98.499992 L 0.49999229,170.5 Z" /> - X6 - + font-size="34" + font-family="Arial" + text-anchor="middle" + stroke="#000000" + fill="#000000" + dy="10.200001" + y="318.5" + x="245.49998">X6 + stroke="#ffffff" + fill="#ffffff" + points="152,255 101,167 145,90 247,90 291,167 240,255 " /> - + cy="141.5" + cx="145.49998" /> + + stroke="#ffffff" + fill="#ffffff" + r="51" + cy="229.5" + cx="196.49998" /> - - - + d="m 196.49999,170.5 v 170" /> - - + d="m 196.49999,170.5 -146.999998,85" /> - - + + stroke-linecap="butt" + stroke-width="34" + stroke="#ffffff" + fill="none" + d="M 196.49999,170.5 V 0.5" /> + + + stroke-linecap="butt" + stroke-width="26" + stroke="#000000" + fill="none" + d="m 196.49999,170.5 v 170" /> + + + + - + - + fill="#ffffff" + points="152,255 101,167 145,90 247,90 291,167 240,255 " /> - + + - + - - 70 - + fill="#ffffff" + cy="43.5" + cx="123.49999" + ry="34" + rx="38" /> 70 + - DC - + font-size="51" + font-family="TimpaniHeavy" + text-anchor="middle" + stroke="#000000" + fill="#000000" + dy="15.3" + y="43.5" + x="269.5">DC + stroke-width="1" + stroke="#000000" + fill="none" + d="M 98.499992,0.5 H 294.49999 l 98,170 -98,170 H 98.499992 L 0.49999229,170.5 Z" /> diff --git a/src/main/resources/tiles/svg/tile18CHX7.svg b/src/main/resources/tiles/svg/tile18CHX7.svg index 7ff80fcac..686193e3d 100644 --- a/src/main/resources/tiles/svg/tile18CHX7.svg +++ b/src/main/resources/tiles/svg/tile18CHX7.svg @@ -7,10 +7,12 @@ xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - version="1.1" - id="svg5667" + height="357" + width="393" + inkscape:version="1.0 (4035a4fb49, 2020-05-01)" sodipodi:docname="tile18CHX7.svg" - inkscape:version="0.92.4 (5da689c313, 2019-01-14)"> + id="svg5667" + version="1.1"> @@ -26,206 +28,215 @@ + inkscape:window-y="-9" + inkscape:window-x="-9" + inkscape:cy="50.5" + inkscape:cx="50.499992" + inkscape:zoom="1" + showgrid="false" + id="namedview5669" + inkscape:window-height="2081" + inkscape:window-width="3840" + inkscape:pageshadow="2" + inkscape:pageopacity="0" + guidetolerance="10" + gridtolerance="10" + objecttolerance="10" + borderopacity="1" + bordercolor="#666666" + pagecolor="#ffffff" /> + stroke-width="1" + stroke="#b46301" + fill="#b46301" + d="M 98.499992,0.5 H 294.49999 l 98,170 -98,170 H 98.499992 L 0.49999229,170.5 Z" /> + stroke="#ffffff" + fill="#ffffff" + points="145,119 247,119 247,221 145,221 " /> - + + stroke="#ffffff" + fill="#ffffff" + r="51" + cy="170.5" + cx="247.49998" /> - - - + d="m 196.49999,170.5 147,-85" /> - - + d="m 196.49999,170.5 147,85" /> - + + + stroke-linecap="butt" + stroke-width="34" + stroke="#ffffff" + fill="none" + d="M 196.49999,170.5 49.499992,85.5" /> + + + + - + - + fill="#ffffff" + points="145,119 247,119 247,221 145,221 " /> + - + - 50 + fill="#ffffff" + cy="297.5" + cx="123.49999" + ry="34" + rx="38" /> 50 + - OO - + font-size="51" + font-family="TimpaniHeavy" + text-anchor="middle" + stroke="#000000" + fill="#000000" + dy="15.3" + y="43.5" + x="196.49998">OO + stroke-width="1" + stroke="#000000" + fill="none" + d="M 98.499992,0.5 H 294.49999 l 98,170 -98,170 H 98.499992 L 0.49999229,170.5 Z" /> X7 + height="51" + width="64" + id="rect5681" />X7 + diff --git a/src/main/resources/tiles/svg/tile18CHX8.svg b/src/main/resources/tiles/svg/tile18CHX8.svg index 3c96278f0..ea150ac7d 100644 --- a/src/main/resources/tiles/svg/tile18CHX8.svg +++ b/src/main/resources/tiles/svg/tile18CHX8.svg @@ -7,10 +7,12 @@ xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - version="1.1" - id="svg5445" + height="357" + width="393" + inkscape:version="1.0 (4035a4fb49, 2020-05-01)" sodipodi:docname="tile18CHX8.svg" - inkscape:version="0.92.4 (5da689c313, 2019-01-14)"> + id="svg5445" + version="1.1"> @@ -26,245 +28,245 @@ + inkscape:window-y="-9" + inkscape:window-x="-9" + inkscape:cy="50.5" + inkscape:cx="54.710518" + inkscape:zoom="0.95" + showgrid="false" + id="namedview5447" + inkscape:window-height="2081" + inkscape:window-width="3840" + inkscape:pageshadow="2" + inkscape:pageopacity="0" + guidetolerance="10" + gridtolerance="10" + objecttolerance="10" + borderopacity="1" + bordercolor="#666666" + pagecolor="#ffffff" /> + stroke-width="1" + stroke="#808080" + fill="#808080" + d="M 98.499992,0.5 H 294.49999 l 98,170 -98,170 H 98.499992 L 0.49999229,170.5 Z" /> - X8 - + font-family="Arial" + text-anchor="middle" + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:31px;font-family:Arial;-inkscape-font-specification:'Arial, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;writing-mode:lr-tb;text-anchor:middle" + id="text5395" + font-weight="bold" + font-size="31" + dy="9.3000002" + y="318.5" + x="245.49998">X8 + - + d="m 196.49999,170.5 147,-85" /> - + stroke-linejoin="round" + id="path5411" + d="m 196.49999,170.5 147,85" /> + id="path5413" + d="m 196.49999,170.5 v 170" /> + + id="path5419" + d="m 196.49999,170.5 147,-85" /> + stroke-width="2" + stroke="#000000" + fill="#ffffff" + cy="43.5" + cx="269.5" + ry="30" + rx="46" /> - DC - + sodipodi:role="line">DC + stroke-width="1" + stroke="#000000" + fill="none" + d="M 98.499992,0.5 H 294.49999 l 98,170 -98,170 H 98.499992 L 0.49999229,170.5 Z" /> + inkscape:connector-curvature="0" /> + inkscape:groupmode="layer"> - - + style="fill:none;stroke:#000000;stroke-width:26;stroke-linecap:butt;stroke-linejoin:round" + inkscape:connector-curvature="0" /> + id="path5423" + d="M 196,170 V 340" /> + id="path5421" + d="m 196,170 147,85" /> + + + transform="translate(-5.2631574,1.0526342)" + id="g5492"> + points="94,119 145,68 247,68 298,119 298,221 247,272 145,272 94,221 " /> - - + id="circle5399" /> + + + cy="221" + r="51" + id="circle5405" /> + style="fill:#ffffff;stroke:#000000;stroke-width:4" + points="94,119 145,68 247,68 298,119 298,221 247,272 145,272 94,221 " + id="polygon5427" /> - + cy="119" + cx="145" /> + cy="119" + cx="247" /> + + r="51" + cy="221" + cx="145" /> 100 + y="43" + dy="0.30000001em" + font-size="43" + id="text5439">100 diff --git a/src/main/resources/tiles/svg/tile18CHX9.svg b/src/main/resources/tiles/svg/tile18CHX9.svg index 316692371..dfe0cd0a3 100644 --- a/src/main/resources/tiles/svg/tile18CHX9.svg +++ b/src/main/resources/tiles/svg/tile18CHX9.svg @@ -7,10 +7,12 @@ xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - version="1.1" - id="svg4626" + height="357" + width="393" + inkscape:version="1.0 (4035a4fb49, 2020-05-01)" sodipodi:docname="tile18CHX9.svg" - inkscape:version="0.92.4 (5da689c313, 2019-01-14)"> + id="svg4626" + version="1.1"> @@ -26,223 +28,230 @@ + inkscape:window-y="-9" + inkscape:window-x="-9" + inkscape:cy="-5.0555556" + inkscape:cx="50.499992" + inkscape:zoom="1.44" + showgrid="false" + id="namedview4628" + inkscape:window-height="2081" + inkscape:window-width="3840" + inkscape:pageshadow="2" + inkscape:pageopacity="0" + guidetolerance="10" + gridtolerance="10" + objecttolerance="10" + borderopacity="1" + bordercolor="#666666" + pagecolor="#ffffff" /> + stroke-width="1" + stroke-linejoin="round" + id="path4576" + d="M 98.499992,0.5 H 294.49999 l 98,170 -98,170 H 98.499992 L 0.49999229,170.5 Z" /> + stroke="#ffffff" + fill="#ffffff" + points="152,255 101,167 145,90 247,90 291,167 240,255 " /> - + cy="141.5" + cx="145.49998" /> + + stroke="#ffffff" + fill="#ffffff" + r="51" + cy="229.5" + cx="196.49998" /> - - - + d="m 196.49999,170.5 v 170" /> - - + d="m 196.49999,170.5 -146.999998,85" /> - + + + stroke-linecap="butt" + stroke-width="34" + stroke="#ffffff" + fill="none" + d="m 196.49999,170.5 147,85" /> + + + + - + - + fill="#ffffff" + points="152,255 101,167 145,90 247,90 291,167 240,255 " /> - + + + stroke="#000000" + fill="#ffffff" + r="51" + cy="229.5" + cx="196.49998" /> + cy="167.5" + cx="343.5" + ry="34" + rx="38" /> - 70 - + sodipodi:role="line">70 + stroke-width="1" + stroke="#000000" + fill="none" + d="M 98.499992,0.5 H 294.49999 l 98,170 -98,170 H 98.499992 L 0.49999229,170.5 Z" /> X9 X9 + OO + x="146.52777" + height="49.305557" + width="96.527779" + id="rect5321" />OO + diff --git a/src/main/resources/tiles/svg/tile2206.svg b/src/main/resources/tiles/svg/tile2206.svg index 13548b4b1..5c852ffad 100644 --- a/src/main/resources/tiles/svg/tile2206.svg +++ b/src/main/resources/tiles/svg/tile2206.svg @@ -1,2 +1,191 @@ - -50X + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + 50 + X + + diff --git a/src/main/resources/tiles/svg/tile2218.svg b/src/main/resources/tiles/svg/tile2218.svg index d795b61a8..f710656c8 100644 --- a/src/main/resources/tiles/svg/tile2218.svg +++ b/src/main/resources/tiles/svg/tile2218.svg @@ -1,2 +1,207 @@ - -70X + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + 70 + X + + diff --git a/src/main/resources/tiles/svg/tile8850.svg b/src/main/resources/tiles/svg/tile8850.svg index 139e4d44f..308ba5deb 100644 --- a/src/main/resources/tiles/svg/tile8850.svg +++ b/src/main/resources/tiles/svg/tile8850.svg @@ -1,2 +1,150 @@ - -885020 + + + + + + image/svg+xml + + + + + + + + + 8850 + + + + + + + + 20 + + diff --git a/src/main/resources/tiles/svg/tile8851.svg b/src/main/resources/tiles/svg/tile8851.svg index 0afc16580..40f3ff844 100644 --- a/src/main/resources/tiles/svg/tile8851.svg +++ b/src/main/resources/tiles/svg/tile8851.svg @@ -1,2 +1,148 @@ - -885120 + + + + + + image/svg+xml + + + + + + + + + 8851 + + + + + + + + 20 + + diff --git a/src/main/resources/tiles/svg/tile8852.svg b/src/main/resources/tiles/svg/tile8852.svg index 3f59aebe5..2a3238730 100644 --- a/src/main/resources/tiles/svg/tile8852.svg +++ b/src/main/resources/tiles/svg/tile8852.svg @@ -1,2 +1,148 @@ - -885220 + + + + + + image/svg+xml + + + + + + + + + 8852 + + + + + + + + 20 + + diff --git a/src/main/resources/tiles/svg/tile8854.svg b/src/main/resources/tiles/svg/tile8854.svg index 2bfcd8e6d..6a568ef85 100644 --- a/src/main/resources/tiles/svg/tile8854.svg +++ b/src/main/resources/tiles/svg/tile8854.svg @@ -1,2 +1,218 @@ - -88542020 + + + + + + image/svg+xml + + + + + + + + + 8854 + + + + + + + + + + + + + 20 + + + 20 + + diff --git a/src/main/resources/tiles/svg/tile8855.svg b/src/main/resources/tiles/svg/tile8855.svg index 785b69504..056002896 100644 --- a/src/main/resources/tiles/svg/tile8855.svg +++ b/src/main/resources/tiles/svg/tile8855.svg @@ -1,2 +1,226 @@ - -88552020 + + + + + + image/svg+xml + + + + + + + + + 8855 + + + + + + + + + + + + + + 20 + + + + + 20 + + + diff --git a/src/main/resources/tiles/svg/tile8856.svg b/src/main/resources/tiles/svg/tile8856.svg index 2bda48edf..b4f5f4a25 100644 --- a/src/main/resources/tiles/svg/tile8856.svg +++ b/src/main/resources/tiles/svg/tile8856.svg @@ -1,2 +1,222 @@ - -88562020 + + + + + + image/svg+xml + + + + + + + + + 8856 + + + + + + + + + + + + + 20 + + + + 20 + + + diff --git a/src/main/resources/tiles/svg/tile8857.svg b/src/main/resources/tiles/svg/tile8857.svg index 63b849b89..a90faf812 100644 --- a/src/main/resources/tiles/svg/tile8857.svg +++ b/src/main/resources/tiles/svg/tile8857.svg @@ -1,2 +1,218 @@ - -88572020 + + + + + + image/svg+xml + + + + + + + + + 8857 + + + + + + + + + + + + + 20 + + + 20 + + diff --git a/src/main/resources/tiles/svg/tile8858.svg b/src/main/resources/tiles/svg/tile8858.svg index c50e9e356..b8405b4ed 100644 --- a/src/main/resources/tiles/svg/tile8858.svg +++ b/src/main/resources/tiles/svg/tile8858.svg @@ -1,2 +1,218 @@ - -88582020 + + + + + + image/svg+xml + + + + + + + + + 8858 + + + + + + + + + + + + + 20 + + + 20 + + diff --git a/src/main/resources/tiles/svg/tile8860.svg b/src/main/resources/tiles/svg/tile8860.svg index 1d26cdb33..63c70dd1a 100644 --- a/src/main/resources/tiles/svg/tile8860.svg +++ b/src/main/resources/tiles/svg/tile8860.svg @@ -1,2 +1,224 @@ - -88604040OO + + + + + + image/svg+xml + + + + + + + + + 8860 + + + + + + + + + + + + + 40 + + + 40 + OO + + diff --git a/src/main/resources/tiles/svg/tile8861.svg b/src/main/resources/tiles/svg/tile8861.svg index d6504e30e..bffe80b69 100644 --- a/src/main/resources/tiles/svg/tile8861.svg +++ b/src/main/resources/tiles/svg/tile8861.svg @@ -1,2 +1,224 @@ - -88614040OO + + + + + + image/svg+xml + + + + + + + + + 8861 + + + + + + + + + + + + + 40 + + + 40 + OO + + diff --git a/src/main/resources/tiles/svg/tile8862.svg b/src/main/resources/tiles/svg/tile8862.svg index 86b6c22a7..3c63e1b94 100644 --- a/src/main/resources/tiles/svg/tile8862.svg +++ b/src/main/resources/tiles/svg/tile8862.svg @@ -1,2 +1,224 @@ - -88624040OO + + + + + + image/svg+xml + + + + + + + + + 8862 + + + + + + + + + + + + + 40 + + + 40 + OO + + diff --git a/src/main/resources/tiles/svg/tile8863.svg b/src/main/resources/tiles/svg/tile8863.svg index a2d6403d3..5dd580cd5 100644 --- a/src/main/resources/tiles/svg/tile8863.svg +++ b/src/main/resources/tiles/svg/tile8863.svg @@ -1,2 +1,227 @@ - -88634040OO + + + + + + image/svg+xml + + + + + + + + + 8863 + + + + + + + + + + + + + 40 + + + 40 + OO + + diff --git a/src/main/resources/tiles/svg/tile8864.svg b/src/main/resources/tiles/svg/tile8864.svg index 5acdbd615..9f1dabad7 100644 --- a/src/main/resources/tiles/svg/tile8864.svg +++ b/src/main/resources/tiles/svg/tile8864.svg @@ -1,2 +1,224 @@ - -88644040OO + + + + + + image/svg+xml + + + + + + + + + 8864 + + + + + + + + + + + + + 40 + + + 40 + OO + + diff --git a/src/main/resources/tiles/svg/tile8865.svg b/src/main/resources/tiles/svg/tile8865.svg index 6dd94d800..17b6276ec 100644 --- a/src/main/resources/tiles/svg/tile8865.svg +++ b/src/main/resources/tiles/svg/tile8865.svg @@ -1,2 +1,226 @@ - -88654040OO + + + + + + image/svg+xml + + + + + + + + + 8865 + + + + + + + + + + + + + 40 + + + 40 + OO + + diff --git a/src/main/resources/tiles/svg/tile8866.svg b/src/main/resources/tiles/svg/tile8866.svg index 77acbd403..5da611ec1 100644 --- a/src/main/resources/tiles/svg/tile8866.svg +++ b/src/main/resources/tiles/svg/tile8866.svg @@ -1,2 +1,170 @@ - -886620 + + + + + + image/svg+xml + + + + + + + + + 8866 + + + + + + + + + + + 20 + + diff --git a/src/main/resources/tiles/svg/tile8871.svg b/src/main/resources/tiles/svg/tile8871.svg index 34a2592c4..95b3c336b 100644 --- a/src/main/resources/tiles/svg/tile8871.svg +++ b/src/main/resources/tiles/svg/tile8871.svg @@ -1,2 +1,202 @@ - -887120 + + + + + + image/svg+xml + + + + + + + + + 8871 + + + + + + + + + + + + + + + 20 + + diff --git a/src/main/resources/tiles/svg/tile8872.svg b/src/main/resources/tiles/svg/tile8872.svg index c48ad37f7..5ad37b2a5 100644 --- a/src/main/resources/tiles/svg/tile8872.svg +++ b/src/main/resources/tiles/svg/tile8872.svg @@ -1,2 +1,218 @@ - -887250OO + + + + + + image/svg+xml + + + + + + + + + 8872 + + + + + + + + + + + + + + + + 50 + OO + + diff --git a/src/main/resources/tiles/svg/tile8873.svg b/src/main/resources/tiles/svg/tile8873.svg index 9a5cb2440..af6a8e4cf 100644 --- a/src/main/resources/tiles/svg/tile8873.svg +++ b/src/main/resources/tiles/svg/tile8873.svg @@ -1,2 +1,218 @@ - -887350OO + + + + + + image/svg+xml + + + + + + + + + 8873 + + + + + + + + + + + + + + + + 50 + OO + + diff --git a/src/main/resources/tiles/svg/tile8874.svg b/src/main/resources/tiles/svg/tile8874.svg index 3c5842a05..492de2bed 100644 --- a/src/main/resources/tiles/svg/tile8874.svg +++ b/src/main/resources/tiles/svg/tile8874.svg @@ -1,2 +1,218 @@ - -887450OO + + + + + + image/svg+xml + + + + + + + + + 8874 + + + + + + + + + + + + + + + + 50 + OO + + diff --git a/src/main/resources/tiles/svg/tile8875.svg b/src/main/resources/tiles/svg/tile8875.svg index 288365f72..6b3ea564d 100644 --- a/src/main/resources/tiles/svg/tile8875.svg +++ b/src/main/resources/tiles/svg/tile8875.svg @@ -1,2 +1,250 @@ - -887560OO + + + + + + image/svg+xml + + + + + + + + + 8875 + + + + + + + + + + + + + + + + + + + + 60 + OO + + diff --git a/src/main/resources/tiles/svg/tile8877.svg b/src/main/resources/tiles/svg/tile8877.svg index 27345dcdb..72e5c06a4 100644 --- a/src/main/resources/tiles/svg/tile8877.svg +++ b/src/main/resources/tiles/svg/tile8877.svg @@ -1,2 +1,156 @@ - -887730S + + + + + + image/svg+xml + + + + + + + + + 8877 + + + + + + + + 30 + S + + diff --git a/src/main/resources/tiles/svg/tile8878.svg b/src/main/resources/tiles/svg/tile8878.svg index aa48dca14..d9a8bb6e1 100644 --- a/src/main/resources/tiles/svg/tile8878.svg +++ b/src/main/resources/tiles/svg/tile8878.svg @@ -1,2 +1,218 @@ - -887840S + + + + + + image/svg+xml + + + + + + + + + 8878 + + + + + + + + + + + + + + + + 40 + S + + diff --git a/src/main/resources/tiles/svg/tile8879.svg b/src/main/resources/tiles/svg/tile8879.svg index 382a825e7..9e52706ee 100644 --- a/src/main/resources/tiles/svg/tile8879.svg +++ b/src/main/resources/tiles/svg/tile8879.svg @@ -1,2 +1,234 @@ - -887960S + + + + + + image/svg+xml + + + + + + + + + 8879 + + + + + + + + + + + + + + + + + + 60 + S + + diff --git a/src/main/resources/tiles/svg/tile8880.svg b/src/main/resources/tiles/svg/tile8880.svg index 90ecd147a..c776efe4f 100644 --- a/src/main/resources/tiles/svg/tile8880.svg +++ b/src/main/resources/tiles/svg/tile8880.svg @@ -1,2 +1,254 @@ - -888070S + + + + + + image/svg+xml + + + + + + + + + + 8880 + + + + + + + + + + + + + + + + + + + + 70 + S + + + diff --git a/src/main/resources/tiles/svg/tile8886.svg b/src/main/resources/tiles/svg/tile8886.svg index 22c780bb4..2d895f00d 100644 --- a/src/main/resources/tiles/svg/tile8886.svg +++ b/src/main/resources/tiles/svg/tile8886.svg @@ -1,2 +1,432 @@ - -8886404040404040B + + + + + + image/svg+xml + + + + + + + + + 8886 + + + + + + + + + + + + + + + + + + + + + + + 40 + + + 40 + + + 40 + + + 40 + + + 40 + + + 40 + B + + diff --git a/src/main/resources/tiles/svg/tile8887.svg b/src/main/resources/tiles/svg/tile8887.svg index 99ade952a..98f9baded 100644 --- a/src/main/resources/tiles/svg/tile8887.svg +++ b/src/main/resources/tiles/svg/tile8887.svg @@ -7,12 +7,12 @@ xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - version="1.1" - id="svg2" - inkscape:version="0.48.4 r9939" - width="393" + sodipodi:docname="tile8887.svg" height="357.5" - sodipodi:docname="tile8887.svg"> + width="393" + inkscape:version="1.0 (4035a4fb49, 2020-05-01)" + id="svg2" + version="1.1"> @@ -21,291 +21,293 @@ image/svg+xml + + fit-margin-left="0" + fit-margin-top="0" + inkscape:current-layer="svg2" + inkscape:window-maximized="1" + inkscape:window-y="-9" + inkscape:window-x="-9" + inkscape:cy="-169.18109" + inkscape:cx="372.54724" + inkscape:zoom="0.80485598" + showgrid="false" + id="namedview44" + inkscape:window-height="2081" + inkscape:window-width="3840" + inkscape:pageshadow="2" + inkscape:pageopacity="0" + guidetolerance="10" + gridtolerance="10" + objecttolerance="10" + borderopacity="1" + bordercolor="#666666" + pagecolor="#ffffff" /> + id="path4" + d="m 98.5,0.5 196,0 98,170 -98,170 -196,0 -98,-170 z" /> 8887 + font-size="34" + dy="318" + y="19.067551" + x="267.86426">8887 + sodipodi:ry="153" + sodipodi:rx="153" + sodipodi:cy="170" + sodipodi:cx="196" + id="circle8" + r="153" + cy="170" + cx="196" /> + id="path10" + d="m 86.5,107.5 -37,-22" /> + id="path12" + d="m 86.5,233.5 -37,22" /> + id="path14" + d="m 196.5,297.5 0,43" /> + id="path16" + d="m 306.5,233.5 37,22" /> + id="path18" + d="m 306.5,107.5 37,-22" /> + id="path20" + d="m 196.5,43.5 0,-43" /> + id="path22" + d="m 86.5,107.5 -37,-22" /> + id="path24" + d="m 86.5,233.5 -37,22" /> + id="path26" + d="m 196.5,297.5 0,43" /> + id="path28" + d="m 306.5,233.5 37,22" /> + id="path30" + d="m 306.5,107.5 37,-22" /> + id="path32" + d="m 196.5,43.5 0,-43" /> - + + sodipodi:ry="34" + sodipodi:rx="38" + sodipodi:cy="170" + sodipodi:cx="196" + id="ellipse36" + cy="170" + cx="196" + ry="34" + rx="38" /> 60 - 60 + B + id="text40" + font-size="51" + dy="132.91324" + y="68.422195" + x="26.238316">B + id="path42" + d="m 98.5,0.5 196,0 98,170 -98,170 -196,0 -98,-170 z" /> - - - - - - + cx="306" /> - - - + + + + sodipodi:rx="51" + sodipodi:cy="233" + sodipodi:cx="306" + id="circle12-4" + r="51" + cy="233" + cx="306" /> + + + + + + + sodipodi:ry="51" + sodipodi:rx="51" + sodipodi:cy="233" + sodipodi:cx="306" + id="circle180-8" + r="51" + cy="233" + cx="306" /> diff --git a/src/main/resources/tiles/svg/tile8888.svg b/src/main/resources/tiles/svg/tile8888.svg index 69ce101c7..3cf5111c4 100644 --- a/src/main/resources/tiles/svg/tile8888.svg +++ b/src/main/resources/tiles/svg/tile8888.svg @@ -7,12 +7,12 @@ xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - version="1.1" - id="svg2" - inkscape:version="0.48.4 r9939" - width="393" + sodipodi:docname="tile8888.svg" height="357.5" - sodipodi:docname="tile8888.svg"> + width="393" + inkscape:version="1.0 (4035a4fb49, 2020-05-01)" + id="svg2" + version="1.1"> @@ -27,641 +27,642 @@ + fit-margin-left="0" + fit-margin-top="0" + inkscape:current-layer="svg2" + inkscape:window-maximized="1" + inkscape:window-y="-9" + inkscape:window-x="-9" + inkscape:cy="-169.18109" + inkscape:cx="372.54724" + inkscape:zoom="0.80485598" + showgrid="false" + id="namedview208" + inkscape:window-height="2081" + inkscape:window-width="3840" + inkscape:pageshadow="2" + inkscape:pageopacity="0" + guidetolerance="10" + gridtolerance="10" + objecttolerance="10" + borderopacity="1" + bordercolor="#666666" + pagecolor="#ffffff" /> + id="path4" + d="m 98.5,0.5 196,0 98,170 -98,170 -196,0 -98,-170 z" /> 8888 + font-size="34" + dy="318" + y="19.067551" + x="261.65195">8888 + id="path20" + d="m 306.5,233.5 37,22" /> + id="path22" + d="m 306.5,107.5 37,-22" /> + id="path24" + d="m 196.5,43.5 0,-43" /> + id="path26" + d="m 86.5,107.5 -37,-22" /> + id="path28" + d="m 86.5,233.5 -37,22" /> + id="path30" + d="m 196.5,297.5 0,43" /> + id="path32" + d="m 343.5,255.5 -147,-85 0,0" /> + id="path34" + d="m 343.5,85.5 -147,85 0,0" /> + id="path36" + d="m 196.5,297.5 0,-297" /> + id="path38" + d="m 49.5,85.5 147,85 0,0" /> + id="path40" + d="m 49.5,255.5 147,-85 0,0" /> + id="path42" + d="m 343.5,85.5 -147,85 0,0" /> + id="path44" + d="m 196.5,0.5 0,170 0,0" /> + id="path46" + d="M 306.5,233.5 49.5,85.5" /> + id="path48" + d="m 49.5,255.5 147,-85 0,0" /> + id="path50" + d="m 49.5,255.5 147,-85 0,0" /> + id="path52" + d="m 196.5,340.5 0,-170 0,0" /> + id="path54" + d="m 343.5,255.5 -147,-85 0,0" /> + id="path56" + d="m 196.5,0.5 0,170 0,0" /> + id="path58" + d="m 49.5,85.5 147,85 0,0" /> + id="path60" + d="m 306.5,107.5 -257,148" /> + id="path62" + d="m 196.5,340.5 0,-170 0,0" /> + id="path64" + d="m 343.5,85.5 -147,85 0,0" /> + id="path66" + d="m 343.5,255.5 -147,-85 0,0" /> + id="path68" + d="m 196.5,43.5 0,297" /> + id="path70" + d="m 49.5,255.5 147,-85 0,0" /> + id="path72" + d="m 49.5,85.5 147,85 0,0" /> + id="path74" + d="m 49.5,255.5 147,-85 0,0" /> + id="path76" + d="m 196.5,340.5 0,-170 0,0" /> + id="path78" + d="m 86.5,107.5 257,148" /> + id="path80" + d="m 343.5,85.5 -147,85 0,0" /> + id="path82" + d="m 196.5,0.5 0,170 0,0" /> + id="path84" + d="m 196.5,340.5 0,-170 0,0" /> + id="path86" + d="m 343.5,255.5 -147,-85 0,0" /> + id="path88" + d="m 86.5,233.5 257,-148" /> + id="path90" + d="m 196.5,0.5 0,170 0,0" /> + id="path92" + d="m 49.5,85.5 147,85 0,0" /> + id="path94" + d="m 306.5,233.5 37,22" /> + id="path96" + d="m 306.5,107.5 37,-22" /> + id="path98" + d="m 196.5,43.5 0,-43" /> + id="path100" + d="m 86.5,107.5 -37,-22" /> + id="path102" + d="m 86.5,233.5 -37,22" /> + id="path104" + d="m 196.5,297.5 0,43" /> + id="path106" + d="m 343.5,255.5 -147,-85 0,0" /> + id="path108" + d="m 343.5,85.5 -147,85 0,0" /> + id="path110" + d="m 196.5,297.5 0,-297" /> + id="path112" + d="m 49.5,85.5 147,85 0,0" /> + id="path114" + d="m 49.5,255.5 147,-85 0,0" /> + id="path116" + d="m 343.5,85.5 -147,85 0,0" /> + id="path118" + d="m 196.5,0.5 0,170 0,0" /> + id="path120" + d="M 306.5,233.5 49.5,85.5" /> + id="path122" + d="m 49.5,255.5 147,-85 0,0" /> + id="path124" + d="m 49.5,255.5 147,-85 0,0" /> + id="path126" + d="m 196.5,340.5 0,-170 0,0" /> + id="path128" + d="m 343.5,255.5 -147,-85 0,0" /> + id="path130" + d="m 196.5,0.5 0,170 0,0" /> + id="path132" + d="m 49.5,85.5 147,85 0,0" /> + id="path134" + d="m 306.5,107.5 -257,148" /> + id="path136" + d="m 196.5,340.5 0,-170 0,0" /> + id="path138" + d="m 343.5,85.5 -147,85 0,0" /> + id="path140" + d="m 343.5,255.5 -147,-85 0,0" /> + id="path142" + d="m 196.5,43.5 0,297" /> + id="path144" + d="m 49.5,255.5 147,-85 0,0" /> + id="path146" + d="m 49.5,85.5 147,85 0,0" /> + id="path148" + d="m 49.5,255.5 147,-85 0,0" /> + id="path150" + d="m 196.5,340.5 0,-170 0,0" /> + id="path152" + d="m 86.5,107.5 257,148" /> + id="path154" + d="m 343.5,85.5 -147,85 0,0" /> + id="path156" + d="m 196.5,0.5 0,170 0,0" /> + id="path158" + d="m 196.5,340.5 0,-170 0,0" /> + id="path160" + d="m 343.5,255.5 -147,-85 0,0" /> + id="path162" + d="m 86.5,233.5 257,-148" /> + id="path164" + d="m 196.5,0.5 0,170 0,0" /> + id="path166" + d="m 49.5,85.5 147,85 0,0" /> B + font-size="51" + dy="170" + y="20.162544" + x="29.620667">B + id="path206" + d="m 98.5,0.5 196,0 98,170 -98,170 -196,0 -98,-170 z" /> + transform="translate(-239.29446,-395.8442)" + id="g3235"> - + + cy="170" + r="153" + id="circle34" + sodipodi:cx="196" + sodipodi:cy="170" + sodipodi:rx="153" + sodipodi:ry="153" + transform="matrix(0.91389414,0,0,0.92982309,254.24554,402.19159)" + style="fill:#ffffff;stroke:#000000;stroke-width:4" /> + transform="translate(98.654206,-382.17716)" + id="g3231"> + ry="34" + cx="123" + cy="43" + id="ellipse200" + sodipodi:cx="123" + sodipodi:cy="43" + sodipodi:rx="38" + sodipodi:ry="34" + transform="translate(-26.091625,503.19562)" + style="fill:#ffffff;stroke:#000000;stroke-width:2;stroke-linejoin:round" /> 80 + dy="43" + font-size="51" + id="text202" + style="font-size:51px;line-height:0%;font-family:'Bookman Old Style';text-anchor:middle;fill:#000000;stroke:#000000">80 + transform="matrix(0.73842983,0,0,0.78202486,-139.95944,-0.925725)" + id="g3239"> - + + cy="107" + r="51" + id="circle186" + sodipodi:cx="306" + sodipodi:cy="107" + sodipodi:rx="51" + sodipodi:ry="51" + transform="translate(246.00674,172.7017)" + style="fill:#ffffff;stroke:#000000;stroke-width:4" /> + transform="matrix(0.73842983,0,0,0.78202486,-213.61975,38.684357)" + id="g3239-2"> - + + cy="107" + r="51" + id="circle186-3" + sodipodi:cx="306" + sodipodi:cy="107" + sodipodi:rx="51" + sodipodi:ry="51" + transform="translate(246.00674,172.7017)" + style="fill:#ffffff;stroke:#000000;stroke-width:4" /> + transform="matrix(0.73842983,0,0,0.78202486,-294.37953,-8.5290607)" + id="g3239-9"> - + + cy="107" + r="51" + id="circle186-2" + sodipodi:cx="306" + sodipodi:cy="107" + sodipodi:rx="51" + sodipodi:ry="51" + transform="translate(246.00674,172.7017)" + style="fill:#ffffff;stroke:#000000;stroke-width:4" /> + transform="matrix(0.73842983,0,0,0.78202486,-294.37953,-99.228517)" + id="g3239-0"> - + + cy="107" + r="51" + id="circle186-0" + sodipodi:cx="306" + sodipodi:cy="107" + sodipodi:rx="51" + sodipodi:ry="51" + transform="translate(246.00674,172.7017)" + style="fill:#ffffff;stroke:#000000;stroke-width:4" /> + transform="matrix(0.73842983,0,0,0.78202486,-213.61975,-150.16931)" + id="g3239-8"> - + + cy="107" + r="51" + id="circle186-6" + sodipodi:cx="306" + sodipodi:cy="107" + sodipodi:rx="51" + sodipodi:ry="51" + transform="translate(246.00674,172.7017)" + style="fill:#ffffff;stroke:#000000;stroke-width:4" /> + transform="matrix(0.73842983,0,0,0.78202486,-132.85996,-101.71344)" + id="g3239-4"> - + + cy="107" + r="51" + id="circle186-1" + sodipodi:cx="306" + sodipodi:cy="107" + sodipodi:rx="51" + sodipodi:ry="51" + transform="translate(246.00674,172.7017)" + style="fill:#ffffff;stroke:#000000;stroke-width:4" /> diff --git a/src/test/resources/data/bugs/1856_Bridge+TunnelBonusBug.rails b/src/test/resources/data/bugs/1856_Bridge+TunnelBonusBug.rails index e9ed1e3f5..a2c5b9545 100644 Binary files a/src/test/resources/data/bugs/1856_Bridge+TunnelBonusBug.rails and b/src/test/resources/data/bugs/1856_Bridge+TunnelBonusBug.rails differ diff --git a/src/test/resources/data/real/1856_A.rails b/src/test/resources/data/real/1856_A.rails index e07337d44..6371551ee 100644 Binary files a/src/test/resources/data/real/1856_A.rails and b/src/test/resources/data/real/1856_A.rails differ diff --git a/src/test/resources/data/real/1856_CGR-10Shares-Test.rails b/src/test/resources/data/real/1856_CGR-10Shares-Test.rails index bdf070e72..309bfca40 100644 Binary files a/src/test/resources/data/real/1856_CGR-10Shares-Test.rails and b/src/test/resources/data/real/1856_CGR-10Shares-Test.rails differ