You can subscribe to this list here.
2008 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(3) |
Nov
(46) |
Dec
(57) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2009 |
Jan
(51) |
Feb
(10) |
Mar
|
Apr
|
May
(14) |
Jun
|
Jul
(13) |
Aug
(30) |
Sep
(83) |
Oct
(56) |
Nov
(148) |
Dec
(107) |
2010 |
Jan
(260) |
Feb
(164) |
Mar
(183) |
Apr
(99) |
May
(160) |
Jun
(40) |
Jul
(33) |
Aug
(48) |
Sep
(22) |
Oct
(24) |
Nov
(1) |
Dec
(12) |
2011 |
Jan
(6) |
Feb
(15) |
Mar
(13) |
Apr
(37) |
May
(27) |
Jun
(29) |
Jul
(33) |
Aug
(20) |
Sep
(17) |
Oct
(20) |
Nov
(33) |
Dec
(17) |
2012 |
Jan
(39) |
Feb
(38) |
Mar
(20) |
Apr
(21) |
May
(17) |
Jun
(22) |
Jul
(16) |
Aug
(3) |
Sep
(9) |
Oct
(10) |
Nov
|
Dec
|
From: Dr. M. B. <neu...@us...> - 2012-03-29 09:40:00
|
rails/game/specific/_1880/StockRound_1880.java | 195 ++++++++++++++++++++++--- 1 file changed, 178 insertions(+), 17 deletions(-) New commits: commit d7be1f2a041f83d75eb725395423c3701449f022 Author: Martin <dr....@t-...> Date: Thu Mar 29 11:39:29 2012 +0200 Implemented the handling of the Flotation Check at the end of a StockRound and the fact that only owned stocks by the director of a public Company count against the floatpercentage. Conflicts: rails/game/specific/_1880/StockRound_1880.java diff --git a/rails/game/specific/_1880/StockRound_1880.java b/rails/game/specific/_1880/StockRound_1880.java index ba422f6..8ed6669 100644 --- a/rails/game/specific/_1880/StockRound_1880.java +++ b/rails/game/specific/_1880/StockRound_1880.java @@ -393,8 +393,7 @@ public class StockRound_1880 extends StockRound { } } } - } - + } /* (non-Javadoc) * @see rails.game.StockRound#finishRound() @@ -479,7 +478,6 @@ public class StockRound_1880 extends StockRound { } /* (non-Javadoc) - * @see rails.game.StockRound#useSpecialProperty(rails.game.action.UseSpecialProperty) */ @Override @@ -726,5 +724,4 @@ public class StockRound_1880 extends StockRound { action.setStartPrice(action.getPrice()); return true; } - -} +} \ No newline at end of file commit 8dcb095b0fa0f9693ec22716916581b64919ef71 Merge: b8c0ada 2f4783b Author: Martin <dr....@t-...> Date: Thu Mar 29 11:34:20 2012 +0200 Merge branch 'specific_1880' of ssh://neu...@ra.../gitroot/rails/rails into specific_1880 Conflicts: rails/game/specific/_1880/StockRound_1880.java diff --cc LICENSE index 5b6e7c6,5b6e7c6..5b6e7c6 mode 100755,100755..100644 --- a/LICENSE +++ b/LICENSE diff --cc README index 97c5c5d,97c5c5d..97c5c5d mode 100755,100755..100644 --- a/README +++ b/README diff --cc data/1830/StockMarket.xml index 770d885,770d885..770d885 mode 100755,100755..100644 --- a/data/1830/StockMarket.xml +++ b/data/1830/StockMarket.xml diff --cc data/1856/StockMarket.xml index f9c9372,f9c9372..f9c9372 mode 100755,100755..100644 --- a/data/1856/StockMarket.xml +++ b/data/1856/StockMarket.xml diff --cc data/1870/StockMarket.xml index c69c8ee,c69c8ee..c69c8ee mode 100755,100755..100644 --- a/data/1870/StockMarket.xml +++ b/data/1870/StockMarket.xml diff --cc data/18AL/StockMarket.xml index 7747579,7747579..7747579 mode 100755,100755..100644 --- a/data/18AL/StockMarket.xml +++ b/data/18AL/StockMarket.xml diff --cc data/18EU/StockMarket.xml index 6c6d780,6c6d780..6c6d780 mode 100755,100755..100644 --- a/data/18EU/StockMarket.xml +++ b/data/18EU/StockMarket.xml diff --cc doc/18oo.vsd index bbb8b9b,bbb8b9b..bbb8b9b mode 100755,100755..100644 --- a/doc/18oo.vsd +++ b/doc/18oo.vsd diff --cc make_rails_pkg.sh index ee40072,ee40072..ee40072 mode 100755,100755..100644 --- a/make_rails_pkg.sh +++ b/make_rails_pkg.sh diff --cc rails/game/specific/_1880/StockRound_1880.java index 256a82c,2f54eac..ba422f6 --- a/rails/game/specific/_1880/StockRound_1880.java +++ b/rails/game/specific/_1880/StockRound_1880.java @@@ -393,256 -394,173 +395,336 @@@ public class StockRound_1880 extends St } } - /* (non-Javadoc) - * @see rails.game.StockRound#startCompany(java.lang.String, rails.game.action.StartCompany) - */ - public boolean startCompany(String playerName, StartCompany_1880 action) { - // TODO Auto-generated method stub - if (super.startCompany(playerName, action)){ - action.setBuildingRight((PublicCompany_1880) action.getCompany(), action.buildingRightToString(action.buildingRight)); - action.setStartPrice(action.getPrice()); - return true; - } else { - return false; - } - } + + /* (non-Javadoc) + * @see rails.game.StockRound#finishRound() + */ + @Override + protected void finishRound() { + ReportBuffer.add(" "); + ReportBuffer.add(LocalText.getText("END_SR", + String.valueOf(getStockRoundNumber()))); + + if (raiseIfSoldOut) { + /* Check if any companies are sold out. */ + for (PublicCompanyI company : gameManager.getCompaniesInRunningOrder()) { + if (company.hasStockPrice() && company.isSoldOut() && (!((PublicCompany_1880) company).isCommunistPhase())) { + StockSpaceI oldSpace = company.getCurrentSpace(); + stockMarket.soldOut(company); + StockSpaceI newSpace = company.getCurrentSpace(); + if (newSpace != oldSpace) { + ReportBuffer.add(LocalText.getText("SoldOut", + company.getName(), + Bank.format(oldSpace.getPrice()), + oldSpace.getName(), + Bank.format(newSpace.getPrice()), + newSpace.getName())); + } else { + ReportBuffer.add(LocalText.getText("SoldOutNoRaise", + company.getName(), + Bank.format(newSpace.getPrice()), + newSpace.getName())); + } + } + } + } ++ ++ for (PublicCompanyI c : companyManager.getAllPublicCompanies()) { ++ if (c.hasStarted() && !c.hasFloated()) { ++ checkFlotation(c); ++ } ++ } ++ + /** At the end of each Stockround the current amount of negative cash is subject to a fine of 50 percent + * + */ + for (Player p : playerManager.getPlayers()) { + if (p.getCash() <0 ) { + int fine = p.getCash()/2; + p.addCash(-fine); + } + } + + // Report financials + ReportBuffer.add(""); + for (PublicCompanyI c : companyManager.getAllPublicCompanies()) { + if (c.hasFloated() && !c.isClosed()) { + ReportBuffer.add(LocalText.getText("Has", c.getName(), + Bank.format(c.getCash()))); + } + } + for (Player p : playerManager.getPlayers()) { + ReportBuffer.add(LocalText.getText("Has", p.getName(), + Bank.format(p.getCash()))); + } + // Inform GameManager + gameManager.nextRound(this); + } + /* (non-Javadoc) - * @see rails.game.StockRound#startCompany(java.lang.String, rails.game.action.StartCompany) + * @see rails.game.StockRound#sellShares(rails.game.action.SellShares) */ @Override - public boolean startCompany(String playerName, StartCompany action) { + public boolean sellShares(SellShares action) { + // TODO Auto-generated method stub + if(super.sellShares(action)) { + int numberSold=action.getNumber(); + gameManager.getCurrentPlayer().addCash(-5*numberSold); //Deduct the Money for selling those Shares ! + return true; + } + else + { + return false; + } + } + + /* (non-Javadoc) ++ + * @see rails.game.StockRound#useSpecialProperty(rails.game.action.UseSpecialProperty) + */ + @Override + public boolean useSpecialProperty(UseSpecialProperty action) { + SpecialPropertyI sp = action.getSpecialProperty(); + + // TODO This should work for all subclasses, but not all have execute() + // yet. + if (sp instanceof ExchangeForCash_1880) { + + boolean result = executeExchangeForCash((ExchangeForCash_1880) sp); + if (result) hasActed.set(true); + return result; + + } else { + return super.useSpecialProperty(action); + } + + } + + private boolean executeExchangeForCash(ExchangeForCash_1880 sp) { + CompanyI privateCompany = sp.getOriginalCompany(); + Portfolio portfolio = privateCompany.getPortfolio(); + + Player player = null; + String errMsg = null; + + while (true) { + + /* Check if the private is owned by a player */ + if (!(portfolio.getOwner() instanceof Player)) { + errMsg = + LocalText.getText("PrivateIsNotOwnedByAPlayer", + privateCompany.getName()); + break; + } + player = (Player) portfolio.getOwner(); + break; + } + if (errMsg != null) { + DisplayBuffer.add(LocalText.getText( + "CannotSwapPrivateForCash", + player.getName(), + privateCompany.getName(), + errMsg )); + return false; + } + + moveStack.start(true); + int amount = sp.getPhaseAmount(); + if (amount >0 ) { + player.addCash(amount); + sp.setExercised(); + privateCompany.setClosed(); + return true; + } + return false; + } + + /* (non-Javadoc) + * @see rails.game.StockRound#process(rails.game.action.PossibleAction) + */ + @Override + public boolean process(PossibleAction action) { + boolean result; + String playerName = action.getPlayerName(); + + if (action instanceof StartCompany) { + + StartCompany_1880 startCompanyAction = (StartCompany_1880) action; + + result = startCompany(playerName, startCompanyAction); + + return result; + } else { + return super.process(action); + } + } ++ ++ /* ++ * @see rails.game.Round#checkFlotation(rails.game.PublicCompanyI) ++ */ ++ @Override ++ protected void checkFlotation(PublicCompanyI company) { ++ if (!company.hasStarted() || company.hasFloated()) return; ++ if (getOwnedPercentageByDirector(company) >= company.getFloatPercentage()) { ++ // Company floats ++ floatCompany(company); ++ } ++ ++ } ++ ++ /** Determine sold percentage for floating purposes */ ++ protected int getOwnedPercentageByDirector (PublicCompanyI company) { ++ ++ int soldPercentage = 0; ++ Player director = company.getPresident(); ++ for (PublicCertificateI cert : company.getCertificates()) { ++ if (certCountsAsSold(cert, director)) { ++ soldPercentage += cert.getShare(); ++ } ++ } ++ return soldPercentage; ++ } ++ ++ private boolean certCountsAsSold(PublicCertificateI cert, Player director) { ++ Portfolio holder = cert.getPortfolio(); ++ CashHolder owner = holder.getOwner(); ++ return owner.equals(director); ++ } ++ ++ public boolean startCompany(String playerName, StartCompany_1880 action) { ++ + PublicCompanyI company = action.getCompany(); + int price = action.getPrice(); + int shares = action.getNumberBought(); + + String errMsg = null; + StockSpaceI startSpace = null; + int numberOfCertsToBuy = 0; + PublicCertificateI cert = null; + String companyName = company.getName(); + int cost = 0; + + currentPlayer = getCurrentPlayer(); + + // Dummy loop to allow a quick jump out + while (true) { + + // Check everything + // Only the player that has the turn may buy + if (!playerName.equals(currentPlayer.getName())) { + errMsg = LocalText.getText("WrongPlayer", playerName, currentPlayer.getName()); + break; + } + + // The player may not have bought this turn. + if (companyBoughtThisTurnWrapper.get() != null) { + errMsg = LocalText.getText("AlreadyBought", playerName); + break; + } + + // Check company + if (company == null) { + errMsg = LocalText.getText("CompanyDoesNotExist", companyName); + break; + } + // The company may not have started yet. + if (company.hasStarted()) { + errMsg = + LocalText.getText("CompanyAlreadyStarted", companyName); + break; + } + + // Find the President's certificate + cert = ipo.findCertificate(company, true); + // Make sure that we buy at least one! + if (shares < cert.getShares()) shares = cert.getShares(); + + // Determine the number of Certificates to buy + // (shortcut: assume that any additional certs are one share each) + numberOfCertsToBuy = shares - (cert.getShares() - 1); + // Check if the player may buy that many certificates. + if (!mayPlayerBuyCertificate(currentPlayer, company, numberOfCertsToBuy)) { + errMsg = LocalText.getText("CantBuyMoreCerts"); + break; + } + + // Check if the company has a fixed par price (1835). + startSpace = company.getStartSpace(); + if (startSpace != null) { + // If so, it overrides whatever is given. + price = startSpace.getPrice(); + } else { + // Else the given price must be a valid start price + if ((startSpace = stockMarket.getStartSpace(price)) == null) { + errMsg = LocalText.getText("InvalidStartPrice", + Bank.format(price), + company.getName() ); + break; + } + } + + // Check if the Player has the money. + cost = shares * price; + if (currentPlayer.getCash() < cost) { + errMsg = LocalText.getText("NoMoney"); + break; + } + + break; + } + + if (errMsg != null) { + DisplayBuffer.add(LocalText.getText("CantStart", + playerName, + companyName, + Bank.format(price), + errMsg )); + return false; + } + + moveStack.start(true); + + // All is OK, now start the company + company.start(startSpace); + + CashHolder priceRecipient = getSharePriceRecipient (company, ipo, price); + + // Transfer the President's certificate + cert.moveTo(currentPlayer.getPortfolio()); + + + // If more than one certificate is bought at the same time, transfer + // these too. + for (int i = 1; i < numberOfCertsToBuy; i++) { + cert = ipo.findCertificate(company, false); + cert.moveTo(currentPlayer.getPortfolio()); + } + + // Pay for these shares + new CashMove (currentPlayer, priceRecipient, cost); + + ReportBuffer.add(LocalText.getText("START_COMPANY_LOG", + playerName, + companyName, + Bank.format(price), + Bank.format(cost), + shares, + cert.getShare(), + priceRecipient.getName() )); + ReportBuffer.getAllWaiting(); + + //checkFlotation(company); We need to check in finishRound + + companyBoughtThisTurnWrapper.set(company); + hasActed.set(true); + setPriority(); + + // Check for any game-specific consequences + // (such as making another company available in the IPO) + gameSpecificChecks(ipo, company); - ++ action.setBuildingRight((PublicCompany_1880) action.getCompany(), action.buildingRightToString(action.buildingRight)); ++ action.setStartPrice(action.getPrice()); + return true; + } - /* (non-Javadoc) - * @see rails.game.StockRound#finishRound() - */ - @Override - protected void finishRound() { - ReportBuffer.add(" "); - ReportBuffer.add(LocalText.getText("END_SR", - String.valueOf(getStockRoundNumber()))); - - if (raiseIfSoldOut) { - /* Check if any companies are sold out. */ - for (PublicCompanyI company : gameManager.getCompaniesInRunningOrder()) { - if (company.hasStockPrice() && company.isSoldOut() && (!((PublicCompany_1880) company).isCommunistPhase())) { - StockSpaceI oldSpace = company.getCurrentSpace(); - stockMarket.soldOut(company); - StockSpaceI newSpace = company.getCurrentSpace(); - if (newSpace != oldSpace) { - ReportBuffer.add(LocalText.getText("SoldOut", - company.getName(), - Bank.format(oldSpace.getPrice()), - oldSpace.getName(), - Bank.format(newSpace.getPrice()), - newSpace.getName())); - } else { - ReportBuffer.add(LocalText.getText("SoldOutNoRaise", - company.getName(), - Bank.format(newSpace.getPrice()), - newSpace.getName())); - } - } - } - } - - for (PublicCompanyI c : companyManager.getAllPublicCompanies()) { - if (c.hasStarted() && !c.hasFloated()) { - checkFlotation(c); - } - } - - /** At the end of each Stockround the current amount of negative cash is subject to a fine of 50 percent - * - */ - for (Player p : playerManager.getPlayers()) { - if (p.getCash() <0 ) { - int fine = p.getCash()/2; - p.addCash(-fine); - } - } - - // Report financials - ReportBuffer.add(""); - for (PublicCompanyI c : companyManager.getAllPublicCompanies()) { - if (c.hasFloated() && !c.isClosed()) { - ReportBuffer.add(LocalText.getText("Has", c.getName(), - Bank.format(c.getCash()))); - } - } - for (Player p : playerManager.getPlayers()) { - ReportBuffer.add(LocalText.getText("Has", p.getName(), - Bank.format(p.getCash()))); - } - // Inform GameManager - gameManager.nextRound(this); - } - - /* (non-Javadoc) - * @see rails.game.StockRound#sellShares(rails.game.action.SellShares) - */ - @Override - public boolean sellShares(SellShares action) { - // TODO Auto-generated method stub - if(super.sellShares(action)) { - int numberSold=action.getNumber(); - gameManager.getCurrentPlayer().addCash(-5*numberSold); //Deduct the Money for selling those Shares ! - return true; - } - else - { - return false; - } - } - - /* (non-Javadoc) - * @see rails.game.Round#checkFlotation(rails.game.PublicCompanyI) - */ - @Override - protected void checkFlotation(PublicCompanyI company) { - if (!company.hasStarted() || company.hasFloated()) return; - - if (getOwnedPercentageByDirector(company) >= company.getFloatPercentage()) { - // Company floats - floatCompany(company); - } - - } - - /** Determine sold percentage for floating purposes */ - protected int getOwnedPercentageByDirector (PublicCompanyI company) { - - int soldPercentage = 0; - Player director = company.getPresident(); - for (PublicCertificateI cert : company.getCertificates()) { - if (certCountsAsSold(cert, director)) { - soldPercentage += cert.getShare(); - } - } - return soldPercentage; - } - - private boolean certCountsAsSold(PublicCertificateI cert, Player director) { - Portfolio holder = cert.getPortfolio(); - CashHolder owner = holder.getOwner(); - return owner.equals(director); - } } diff --cc tiles/Create_TileDictionary_pdf.sh index 0c521fa,0c521fa..0c521fa mode 100755,100755..100644 --- a/tiles/Create_TileDictionary_pdf.sh +++ b/tiles/Create_TileDictionary_pdf.sh commit b8c0ada06fd0a4d5defbf3cfbc62df00a660aa83 Author: Martin <dr....@t-...> Date: Thu Mar 29 11:27:13 2012 +0200 Implemented the handling of the Flotation Check at the end of a StockRound and the fact that only owned stocks by the director of a public Company count against the floatpercentage. diff --git a/rails/game/specific/_1880/StockRound_1880.java b/rails/game/specific/_1880/StockRound_1880.java index 537f704..256a82c 100644 --- a/rails/game/specific/_1880/StockRound_1880.java +++ b/rails/game/specific/_1880/StockRound_1880.java @@ -9,6 +9,7 @@ import java.util.Arrays; import java.util.List; import java.util.Map; +import rails.common.DisplayBuffer; import rails.common.LocalText; import rails.game.*; import rails.game.action.BuyCertificate; @@ -138,7 +139,8 @@ public class StockRound_1880 extends StockRound { ((PublicCompany_1880) privComp).setDestinationHex(company.getHomeHexes().get(0)); privComp.setInfoText(privComp.getInfoText() + "<br>Destination: "+privComp.getDestinationHex().getInfo()); // Check if the company has floated - if (!company.hasFloated()) checkFlotation(company); + // if (!company.hasFloated()) checkFlotation(company); + // moved to finishRound return; } else { return; @@ -396,8 +398,137 @@ public class StockRound_1880 extends StockRound { */ @Override public boolean startCompany(String playerName, StartCompany action) { - // TODO Auto-generated method stub - return super.startCompany(playerName, action); + PublicCompanyI company = action.getCompany(); + int price = action.getPrice(); + int shares = action.getNumberBought(); + + String errMsg = null; + StockSpaceI startSpace = null; + int numberOfCertsToBuy = 0; + PublicCertificateI cert = null; + String companyName = company.getName(); + int cost = 0; + + currentPlayer = getCurrentPlayer(); + + // Dummy loop to allow a quick jump out + while (true) { + + // Check everything + // Only the player that has the turn may buy + if (!playerName.equals(currentPlayer.getName())) { + errMsg = LocalText.getText("WrongPlayer", playerName, currentPlayer.getName()); + break; + } + + // The player may not have bought this turn. + if (companyBoughtThisTurnWrapper.get() != null) { + errMsg = LocalText.getText("AlreadyBought", playerName); + break; + } + + // Check company + if (company == null) { + errMsg = LocalText.getText("CompanyDoesNotExist", companyName); + break; + } + // The company may not have started yet. + if (company.hasStarted()) { + errMsg = + LocalText.getText("CompanyAlreadyStarted", companyName); + break; + } + + // Find the President's certificate + cert = ipo.findCertificate(company, true); + // Make sure that we buy at least one! + if (shares < cert.getShares()) shares = cert.getShares(); + + // Determine the number of Certificates to buy + // (shortcut: assume that any additional certs are one share each) + numberOfCertsToBuy = shares - (cert.getShares() - 1); + // Check if the player may buy that many certificates. + if (!mayPlayerBuyCertificate(currentPlayer, company, numberOfCertsToBuy)) { + errMsg = LocalText.getText("CantBuyMoreCerts"); + break; + } + + // Check if the company has a fixed par price (1835). + startSpace = company.getStartSpace(); + if (startSpace != null) { + // If so, it overrides whatever is given. + price = startSpace.getPrice(); + } else { + // Else the given price must be a valid start price + if ((startSpace = stockMarket.getStartSpace(price)) == null) { + errMsg = LocalText.getText("InvalidStartPrice", + Bank.format(price), + company.getName() ); + break; + } + } + + // Check if the Player has the money. + cost = shares * price; + if (currentPlayer.getCash() < cost) { + errMsg = LocalText.getText("NoMoney"); + break; + } + + break; + } + + if (errMsg != null) { + DisplayBuffer.add(LocalText.getText("CantStart", + playerName, + companyName, + Bank.format(price), + errMsg )); + return false; + } + + moveStack.start(true); + + // All is OK, now start the company + company.start(startSpace); + + CashHolder priceRecipient = getSharePriceRecipient (company, ipo, price); + + // Transfer the President's certificate + cert.moveTo(currentPlayer.getPortfolio()); + + + // If more than one certificate is bought at the same time, transfer + // these too. + for (int i = 1; i < numberOfCertsToBuy; i++) { + cert = ipo.findCertificate(company, false); + cert.moveTo(currentPlayer.getPortfolio()); + } + + // Pay for these shares + new CashMove (currentPlayer, priceRecipient, cost); + + ReportBuffer.add(LocalText.getText("START_COMPANY_LOG", + playerName, + companyName, + Bank.format(price), + Bank.format(cost), + shares, + cert.getShare(), + priceRecipient.getName() )); + ReportBuffer.getAllWaiting(); + + //checkFlotation(company); We need to check in finishRound + + companyBoughtThisTurnWrapper.set(company); + hasActed.set(true); + setPriority(); + + // Check for any game-specific consequences + // (such as making another company available in the IPO) + gameSpecificChecks(ipo, company); + + return true; } /* (non-Javadoc) @@ -432,6 +563,13 @@ public class StockRound_1880 extends StockRound { } } } + + for (PublicCompanyI c : companyManager.getAllPublicCompanies()) { + if (c.hasStarted() && !c.hasFloated()) { + checkFlotation(c); + } + } + /** At the end of each Stockround the current amount of negative cash is subject to a fine of 50 percent * */ @@ -475,5 +613,36 @@ public class StockRound_1880 extends StockRound { } } + /* (non-Javadoc) + * @see rails.game.Round#checkFlotation(rails.game.PublicCompanyI) + */ + @Override + protected void checkFlotation(PublicCompanyI company) { + if (!company.hasStarted() || company.hasFloated()) return; + + if (getOwnedPercentageByDirector(company) >= company.getFloatPercentage()) { + // Company floats + floatCompany(company); + } + + } + /** Determine sold percentage for floating purposes */ + protected int getOwnedPercentageByDirector (PublicCompanyI company) { + + int soldPercentage = 0; + Player director = company.getPresident(); + for (PublicCertificateI cert : company.getCertificates()) { + if (certCountsAsSold(cert, director)) { + soldPercentage += cert.getShare(); + } + } + return soldPercentage; + } + + private boolean certCountsAsSold(PublicCertificateI cert, Player director) { + Portfolio holder = cert.getPortfolio(); + CashHolder owner = holder.getOwner(); + return owner.equals(director); + } } |
From: Erik V. <ev...@us...> - 2012-03-25 15:59:00
|
data/1830/Map.xml | 8 ++++++-- data/1830/TileSet.xml | 1 - data/1830/Tiles.xml | 5 ----- data/1856/Map.xml | 2 +- data/1856/TileSet.xml | 1 - data/1856/Tiles.xml | 6 ------ data/18EU/Map.xml | 2 +- data/18EU/TileSet.xml | 1 - data/18EU/Tiles.xml | 6 ------ 9 files changed, 8 insertions(+), 24 deletions(-) New commits: commit 9f3447e845563b218d7505bde4c88513b62e9bc4 Author: Erik Vos <eri...@xs...> Date: Sun Mar 25 17:57:05 2012 +0200 Final fix for routes through Goderich tile -939 XML description now uses tile -903, tile -939 is image only. So XML regeneration of Tiles.xml should no longer break correct working. Affects 1856, 18EU and 1830 Coalfields (etc) Bug reported by Arne Ãstlund for 1830 Coalfields (the other games had customized XML, but that is not a persistent solution) diff --git a/data/1830/Map.xml b/data/1830/Map.xml index ecc6404..d30dfa1 100644 --- a/data/1830/Map.xml +++ b/data/1830/Map.xml @@ -63,7 +63,9 @@ <Hex name="F2" tile="-903" orientation="5" value="40,70" city="Chicago"/> </IfOption> <IfOption name="Variant" value="Coalfields,Coalfields&Reading"> - <Hex name="F2" tile="-939" orientation="5" value="40,70" city="Chicago"/> + <Hex name="F2" tile="-903" pic="-939" orientation="5" value="40,70" city="Chicago"> + <Access runThrough="yes"/> + </Hex> </IfOption> <IfOption name="Variant" value="Wabash"> <Hex name="F2" tile="0"/> @@ -181,7 +183,9 @@ <Hex name="K11" tile="0" cost="120"/> <Hex name="K13" tile="-10" city="Richmond"/> <Hex name="K15" tile="0" cost="40"/> - <Hex name="L2" tile="-939" orientation="4" value="30,60" city="Gulf"/> + <Hex name="L2" tile="-903" pic="-939" orientation="4" value="30,60" city="Gulf"> + <Access runThrough="yes"/> + </Hex> <Hex name="L4" tile="0"/> <Hex name="L6" tile="0" cost="120"/> <Hex name="L8" tile="0" cost="120"/> diff --git a/data/1830/TileSet.xml b/data/1830/TileSet.xml index a50a2b0..75ed736 100644 --- a/data/1830/TileSet.xml +++ b/data/1830/TileSet.xml @@ -42,7 +42,6 @@ <Tile id="-902"/> <Tile id="-903"/> <Tile id="-908"/><!-- Coalfields: K1 --> - <Tile id="-939"/><!-- Coalfields: Chicago --> <Tile id="-25007"/><!-- Wabash: D20--> <Tile id="-30001"/><!-- Coalfields: N of Boston --> <Tile id="-30003" pic="-30002"/><!-- Coalfields: Altoona --> diff --git a/data/1830/Tiles.xml b/data/1830/Tiles.xml index c082f65..a5a52e2 100644 --- a/data/1830/Tiles.xml +++ b/data/1830/Tiles.xml @@ -88,11 +88,6 @@ <Tile colour="red" id="-908" name="OM wide curve"> <Track from="side0" gauge="normal" to="side2"/> </Tile> - <Tile colour="red" id="-939" name="Goderich"> - <Track from="side3" gauge="normal" to="side1"/> - <Track from="side3" gauge="normal" to="side2"/> - <Track from="side2" gauge="normal" to="side1"/> - </Tile> <Tile colour="fixed" id="-25007" name="Bournemouth"> <Station id="city1" position="0" slots="1" type="City" value="20"/> <Station id="city2" position="0" slots="1" type="City" value="20"/> diff --git a/data/1856/Map.xml b/data/1856/Map.xml index 2818de8..eb5cff6 100644 --- a/data/1856/Map.xml +++ b/data/1856/Map.xml @@ -18,7 +18,7 @@ <Hex name="E14" tile="0"/> <Hex name="E16" tile="0"/> <Hex name="E18" tile="-2" port="yes"/> - <Hex name="F9" tile="-939" port="yes" value="30,50,40" city="Goderich"> + <Hex name="F9" tile="-903" pic="-939" port="yes" value="30,50,40" city="Goderich"> <Access runThrough="yes"/> </Hex> <Hex name="F11" tile="0"/> diff --git a/data/1856/TileSet.xml b/data/1856/TileSet.xml index f926f6f..17fd4df 100644 --- a/data/1856/TileSet.xml +++ b/data/1856/TileSet.xml @@ -24,7 +24,6 @@ <Tile id="-901"/> <Tile id="-902"/> <Tile id="-903"/> - <Tile id="-939"/> <!-- Yellow tiles --> <Tile id="1" quantity="1"> diff --git a/data/1856/Tiles.xml b/data/1856/Tiles.xml index bd8a8d0..7edb9f7 100644 --- a/data/1856/Tiles.xml +++ b/data/1856/Tiles.xml @@ -41,12 +41,6 @@ <Track from="city1" gauge="normal" to="side2"/> <Track from="city1" gauge="normal" to="side1"/> </Tile> - <Tile colour="red" id="-939" name="Goderich"> - <Station id="city1" position="0" slots="0" type="City" value="-1"/> - <Track from="side1" gauge="normal" to="city1"/> - <Track from="side2" gauge="normal" to="city1"/> - <Track from="side3" gauge="normal" to="city1"/> - </Tile> <Tile colour="yellow" id="1" name="1"> <Station id="city1" position="408" type="Town" value="10"/> <Station id="city2" position="108" type="Town" value="10"/> diff --git a/data/18EU/Map.xml b/data/18EU/Map.xml index 30e6b19..3d4462c 100644 --- a/data/18EU/Map.xml +++ b/data/18EU/Map.xml @@ -2,7 +2,7 @@ <Image file="18EU/MapImage.svg" x="16" y="15" scale="0.955"/> <!-- Hex name="" tile="" orientation="" value="" impassable="" label="" cost="" value="" port="yes/no" --> <Hex name="A4" port="yes" value="10" tile="-800" orientation="0"/> - <Hex name="B7" value="30,50" tile="-939" orientation="1" city="Hamburg"> + <Hex name="B7" value="30,50" tile="-903" pic="-939" orientation="1" city="Hamburg"> <Access runThrough="yes"/> </Hex> <Hex name="C4" label="Y" tile="-3007" city="Amsterdam"/> diff --git a/data/18EU/TileSet.xml b/data/18EU/TileSet.xml index c439f20..773f132 100644 --- a/data/18EU/TileSet.xml +++ b/data/18EU/TileSet.xml @@ -17,7 +17,6 @@ <Tile id="-901"/> <Tile id="-902"/> <Tile id="-903"/> - <Tile id="-939"/> <Tile id="-3005"><!--Berlin/Vienna--> <Upgrade id="581"/> <AllowsMultipleBasesOfOneCompany/> diff --git a/data/18EU/Tiles.xml b/data/18EU/Tiles.xml index bd9cd81..083ec4f 100644 --- a/data/18EU/Tiles.xml +++ b/data/18EU/Tiles.xml @@ -34,12 +34,6 @@ <Track from="city1" gauge="normal" to="side2"/> <Track from="city1" gauge="normal" to="side1"/> </Tile> - <Tile colour="red" id="-939" name="Goderich"> - <Station id="city1" position="0" slots="0" type="City" value="-1"/> - <Track from="side1" gauge="normal" to="city1"/> - <Track from="side2" gauge="normal" to="city1"/> - <Track from="side3" gauge="normal" to="city1"/> - </Tile> <Tile colour="yellow" id="-3005" name="B/V"> <Station id="city1" position="102" slots="1" type="City" city="B/V" value="30"/> <Station id="city2" position="402" slots="1" type="City" city="B/V" value="30"/> |
From: Stefan F. <ste...@us...> - 2012-03-25 10:46:40
|
New branch 'rails1.7.x' available with the following commits: |
From: Dr. M. B. <neu...@us...> - 2012-03-22 22:00:38
|
rails/game/specific/_1880/StartCompany_1880.java | 46 +++++++++++++++++++++-- rails/game/specific/_1880/StockRound_1880.java | 11 ++++- 2 files changed, 51 insertions(+), 6 deletions(-) New commits: commit 2f4783bdf6d3f5f24f95c630fd8a26d2b6b64203 Author: Martin Brumm <Dr....@t-...> Date: Thu Mar 22 22:59:22 2012 +0100 Fixed Loading Process of saved games part II completing earlier commit. diff --git a/rails/game/specific/_1880/StartCompany_1880.java b/rails/game/specific/_1880/StartCompany_1880.java index c877e3a..df7927e 100644 --- a/rails/game/specific/_1880/StartCompany_1880.java +++ b/rails/game/specific/_1880/StartCompany_1880.java @@ -24,7 +24,9 @@ public class StartCompany_1880 extends StartCompany { */ private static final long serialVersionUID = 1L; - + BitSet buildingRight = new BitSet(4); + BitSet savedBuildingRight = new BitSet(4); + /** * @param company * @param prices @@ -70,7 +72,7 @@ public class StartCompany_1880 extends StartCompany { public void setBuildingRight(PublicCompany_1880 company, String buildingRightString ) { - BitSet buildingRight = new BitSet(5); + if (buildingRightString == "A") { buildingRight.set(0); @@ -135,7 +137,45 @@ public class StartCompany_1880 extends StartCompany { in.defaultReadObject(); - CompanyManagerI cmgr = getCompanyManager(); + if (!buildingRight.isEmpty()) { + savedBuildingRight = (BitSet) buildingRight.clone(); + } + + } + + public String buildingRightToString(BitSet buildingRight2) { + String buildingRightString = null; + if (! buildingRight.isEmpty()){ + if (buildingRight.get(0)== true) { + buildingRightString = "A"; + if (buildingRight.get(1) == true) { + buildingRightString = "A+B"; + if (buildingRight.get(2) == true) { + buildingRightString = "A+B+C"; + } + } + } + else if (buildingRight.get(1) == true) { + buildingRightString = "B"; + if (buildingRight.get(2) == true) { + buildingRightString = "B+C"; + if (buildingRight.get(3) == true){ + buildingRightString = "B+C+D"; + } + } + } + else if (buildingRight.get(2) == true){ + buildingRightString = "C"; + if (buildingRight.get(3) == true){ + buildingRightString = "C+D"; + } + } + else if (buildingRight.get(3) == true){ + buildingRightString= "D"; + } + return buildingRightString; + } + return "None"; } } diff --git a/rails/game/specific/_1880/StockRound_1880.java b/rails/game/specific/_1880/StockRound_1880.java index e878f56..2f54eac 100644 --- a/rails/game/specific/_1880/StockRound_1880.java +++ b/rails/game/specific/_1880/StockRound_1880.java @@ -397,10 +397,15 @@ public class StockRound_1880 extends StockRound { /* (non-Javadoc) * @see rails.game.StockRound#startCompany(java.lang.String, rails.game.action.StartCompany) */ - @Override - public boolean startCompany(String playerName, StartCompany action) { + public boolean startCompany(String playerName, StartCompany_1880 action) { // TODO Auto-generated method stub - return super.startCompany(playerName, action); + if (super.startCompany(playerName, action)){ + action.setBuildingRight((PublicCompany_1880) action.getCompany(), action.buildingRightToString(action.buildingRight)); + action.setStartPrice(action.getPrice()); + return true; + } else { + return false; + } } /* (non-Javadoc) commit 26484eeadd1fbf17b78c1fc04e4f973a7900518b Merge: 595fdeb 78a057a Author: Martin Brumm <Dr....@t-...> Date: Thu Mar 22 22:46:42 2012 +0100 Merge remote-tracking branch '1880/specific_1880' into specific_1880 commit 595fdeba8d6a07c089856ead32cc4f7a8e454651 Author: Martin Brumm <Dr....@t-...> Date: Thu Mar 22 22:46:03 2012 +0100 Revert "Fixing the bug that certain Informations and properties of an 1880 company arent read from a saved game" This reverts commit 5e59d430315b7d2228dcb01e098c414b698eaf09. diff --git a/rails/game/specific/_1880/StartCompany_1880.java b/rails/game/specific/_1880/StartCompany_1880.java index 8fd8938..616b8bb 100644 --- a/rails/game/specific/_1880/StartCompany_1880.java +++ b/rails/game/specific/_1880/StartCompany_1880.java @@ -3,11 +3,8 @@ */ package rails.game.specific._1880; -import java.io.IOException; -import java.io.ObjectInputStream; import java.util.BitSet; -import rails.game.CompanyManagerI; import rails.game.PublicCompanyI; import rails.game.StockSpace; import rails.game.StockSpaceI; @@ -24,9 +21,7 @@ public class StartCompany_1880 extends StartCompany { */ private static final long serialVersionUID = 1L; - BitSet buildingRight = new BitSet(4); - BitSet savedBuildingRight = new BitSet(4); - + /** * @param company * @param prices @@ -72,7 +67,7 @@ public class StartCompany_1880 extends StartCompany { public void setBuildingRight(PublicCompany_1880 company, String buildingRightString ) { - + BitSet buildingRight = new BitSet(5); if (buildingRightString == "A") { buildingRight.set(0); @@ -131,50 +126,4 @@ public class StartCompany_1880 extends StartCompany { ((StockMarket_1880) gameManager.getStockMarket()).setParSlot(startPrice); } - /** Deserialize */ - private void readObject(ObjectInputStream in) throws IOException, - ClassNotFoundException { - - in.defaultReadObject(); - - if (!buildingRight.isEmpty()) { - savedBuildingRight = (BitSet) buildingRight.clone(); - } - - } - public String buildingRightToString (BitSet buildingRight){ - String buildingRightString = null; - - if (! buildingRight.isEmpty()){ - if (buildingRight.get(0)== true) { - buildingRightString = "A"; - if (buildingRight.get(1) == true) { - buildingRightString = "A+B"; - if (buildingRight.get(2) == true) { - buildingRightString = "A+B+C"; - } - } - } - else if (buildingRight.get(1) == true) { - buildingRightString = "B"; - if (buildingRight.get(2) == true) { - buildingRightString = "B+C"; - if (buildingRight.get(3) == true){ - buildingRightString = "B+C+D"; - } - } - } - else if (buildingRight.get(2) == true){ - buildingRightString = "C"; - if (buildingRight.get(3) == true){ - buildingRightString = "C+D"; - } - } - else if (buildingRight.get(3) == true){ - buildingRightString= "D"; - } - return buildingRightString; - } - return "None"; - } } diff --git a/rails/game/specific/_1880/StockRound_1880.java b/rails/game/specific/_1880/StockRound_1880.java index 46b5758..537f704 100644 --- a/rails/game/specific/_1880/StockRound_1880.java +++ b/rails/game/specific/_1880/StockRound_1880.java @@ -9,16 +9,13 @@ import java.util.Arrays; import java.util.List; import java.util.Map; -import rails.common.DisplayBuffer; import rails.common.LocalText; import rails.game.*; import rails.game.action.BuyCertificate; import rails.game.action.PossibleAction; import rails.game.action.SellShares; import rails.game.action.StartCompany; -import rails.game.action.UseSpecialProperty; import rails.game.move.CashMove; -import rails.game.special.SpecialPropertyI; import rails.game.specific._1880.PublicCompany_1880; @@ -397,15 +394,10 @@ public class StockRound_1880 extends StockRound { /* (non-Javadoc) * @see rails.game.StockRound#startCompany(java.lang.String, rails.game.action.StartCompany) */ - public boolean startCompany(String playerName, StartCompany_1880 action) { + @Override + public boolean startCompany(String playerName, StartCompany action) { // TODO Auto-generated method stub - if (super.startCompany(playerName, action)){ - action.setBuildingRight((PublicCompany_1880) action.getCompany(), action.buildingRightToString(action.buildingRight)); - action.setStartPrice(action.getPrice()); - return true; - } else { - return false; - } + return super.startCompany(playerName, action); } /* (non-Javadoc) @@ -483,84 +475,5 @@ public class StockRound_1880 extends StockRound { } } - /* (non-Javadoc) - * @see rails.game.StockRound#useSpecialProperty(rails.game.action.UseSpecialProperty) - */ - @Override - public boolean useSpecialProperty(UseSpecialProperty action) { - SpecialPropertyI sp = action.getSpecialProperty(); - - // TODO This should work for all subclasses, but not all have execute() - // yet. - if (sp instanceof ExchangeForCash_1880) { - - boolean result = executeExchangeForCash((ExchangeForCash_1880) sp); - if (result) hasActed.set(true); - return result; - - } else { - return super.useSpecialProperty(action); - } - - } - - private boolean executeExchangeForCash(ExchangeForCash_1880 sp) { - CompanyI privateCompany = sp.getOriginalCompany(); - Portfolio portfolio = privateCompany.getPortfolio(); - - Player player = null; - String errMsg = null; - - while (true) { - - /* Check if the private is owned by a player */ - if (!(portfolio.getOwner() instanceof Player)) { - errMsg = - LocalText.getText("PrivateIsNotOwnedByAPlayer", - privateCompany.getName()); - break; - } - player = (Player) portfolio.getOwner(); - break; - } - if (errMsg != null) { - DisplayBuffer.add(LocalText.getText( - "CannotSwapPrivateForCash", - player.getName(), - privateCompany.getName(), - errMsg )); - return false; - } - - moveStack.start(true); - int amount = sp.getPhaseAmount(); - if (amount >0 ) { - player.addCash(amount); - sp.setExercised(); - privateCompany.setClosed(); - return true; - } - return false; - } - - /* (non-Javadoc) - * @see rails.game.StockRound#process(rails.game.action.PossibleAction) - */ - @Override - public boolean process(PossibleAction action) { - boolean result; - String playerName = action.getPlayerName(); - - if (action instanceof StartCompany) { - - StartCompany_1880 startCompanyAction = (StartCompany_1880) action; - - result = startCompany(playerName, startCompanyAction); - - return result; - } else { - return super.process(action); - } - } } commit 5e59d430315b7d2228dcb01e098c414b698eaf09 Author: Martin Brumm <Dr....@t-...> Date: Thu Mar 22 22:45:10 2012 +0100 Fixing the bug that certain Informations and properties of an 1880 company arent read from a saved game diff --git a/rails/game/specific/_1880/StartCompany_1880.java b/rails/game/specific/_1880/StartCompany_1880.java index 616b8bb..8fd8938 100644 --- a/rails/game/specific/_1880/StartCompany_1880.java +++ b/rails/game/specific/_1880/StartCompany_1880.java @@ -3,8 +3,11 @@ */ package rails.game.specific._1880; +import java.io.IOException; +import java.io.ObjectInputStream; import java.util.BitSet; +import rails.game.CompanyManagerI; import rails.game.PublicCompanyI; import rails.game.StockSpace; import rails.game.StockSpaceI; @@ -21,7 +24,9 @@ public class StartCompany_1880 extends StartCompany { */ private static final long serialVersionUID = 1L; - + BitSet buildingRight = new BitSet(4); + BitSet savedBuildingRight = new BitSet(4); + /** * @param company * @param prices @@ -67,7 +72,7 @@ public class StartCompany_1880 extends StartCompany { public void setBuildingRight(PublicCompany_1880 company, String buildingRightString ) { - BitSet buildingRight = new BitSet(5); + if (buildingRightString == "A") { buildingRight.set(0); @@ -126,4 +131,50 @@ public class StartCompany_1880 extends StartCompany { ((StockMarket_1880) gameManager.getStockMarket()).setParSlot(startPrice); } + /** Deserialize */ + private void readObject(ObjectInputStream in) throws IOException, + ClassNotFoundException { + + in.defaultReadObject(); + + if (!buildingRight.isEmpty()) { + savedBuildingRight = (BitSet) buildingRight.clone(); + } + + } + public String buildingRightToString (BitSet buildingRight){ + String buildingRightString = null; + + if (! buildingRight.isEmpty()){ + if (buildingRight.get(0)== true) { + buildingRightString = "A"; + if (buildingRight.get(1) == true) { + buildingRightString = "A+B"; + if (buildingRight.get(2) == true) { + buildingRightString = "A+B+C"; + } + } + } + else if (buildingRight.get(1) == true) { + buildingRightString = "B"; + if (buildingRight.get(2) == true) { + buildingRightString = "B+C"; + if (buildingRight.get(3) == true){ + buildingRightString = "B+C+D"; + } + } + } + else if (buildingRight.get(2) == true){ + buildingRightString = "C"; + if (buildingRight.get(3) == true){ + buildingRightString = "C+D"; + } + } + else if (buildingRight.get(3) == true){ + buildingRightString= "D"; + } + return buildingRightString; + } + return "None"; + } } diff --git a/rails/game/specific/_1880/StockRound_1880.java b/rails/game/specific/_1880/StockRound_1880.java index 537f704..46b5758 100644 --- a/rails/game/specific/_1880/StockRound_1880.java +++ b/rails/game/specific/_1880/StockRound_1880.java @@ -9,13 +9,16 @@ import java.util.Arrays; import java.util.List; import java.util.Map; +import rails.common.DisplayBuffer; import rails.common.LocalText; import rails.game.*; import rails.game.action.BuyCertificate; import rails.game.action.PossibleAction; import rails.game.action.SellShares; import rails.game.action.StartCompany; +import rails.game.action.UseSpecialProperty; import rails.game.move.CashMove; +import rails.game.special.SpecialPropertyI; import rails.game.specific._1880.PublicCompany_1880; @@ -394,10 +397,15 @@ public class StockRound_1880 extends StockRound { /* (non-Javadoc) * @see rails.game.StockRound#startCompany(java.lang.String, rails.game.action.StartCompany) */ - @Override - public boolean startCompany(String playerName, StartCompany action) { + public boolean startCompany(String playerName, StartCompany_1880 action) { // TODO Auto-generated method stub - return super.startCompany(playerName, action); + if (super.startCompany(playerName, action)){ + action.setBuildingRight((PublicCompany_1880) action.getCompany(), action.buildingRightToString(action.buildingRight)); + action.setStartPrice(action.getPrice()); + return true; + } else { + return false; + } } /* (non-Javadoc) @@ -475,5 +483,84 @@ public class StockRound_1880 extends StockRound { } } + /* (non-Javadoc) + * @see rails.game.StockRound#useSpecialProperty(rails.game.action.UseSpecialProperty) + */ + @Override + public boolean useSpecialProperty(UseSpecialProperty action) { + SpecialPropertyI sp = action.getSpecialProperty(); + + // TODO This should work for all subclasses, but not all have execute() + // yet. + if (sp instanceof ExchangeForCash_1880) { + + boolean result = executeExchangeForCash((ExchangeForCash_1880) sp); + if (result) hasActed.set(true); + return result; + + } else { + return super.useSpecialProperty(action); + } + + } + + private boolean executeExchangeForCash(ExchangeForCash_1880 sp) { + CompanyI privateCompany = sp.getOriginalCompany(); + Portfolio portfolio = privateCompany.getPortfolio(); + + Player player = null; + String errMsg = null; + + while (true) { + + /* Check if the private is owned by a player */ + if (!(portfolio.getOwner() instanceof Player)) { + errMsg = + LocalText.getText("PrivateIsNotOwnedByAPlayer", + privateCompany.getName()); + break; + } + player = (Player) portfolio.getOwner(); + break; + } + if (errMsg != null) { + DisplayBuffer.add(LocalText.getText( + "CannotSwapPrivateForCash", + player.getName(), + privateCompany.getName(), + errMsg )); + return false; + } + + moveStack.start(true); + int amount = sp.getPhaseAmount(); + if (amount >0 ) { + player.addCash(amount); + sp.setExercised(); + privateCompany.setClosed(); + return true; + } + return false; + } + + /* (non-Javadoc) + * @see rails.game.StockRound#process(rails.game.action.PossibleAction) + */ + @Override + public boolean process(PossibleAction action) { + boolean result; + String playerName = action.getPlayerName(); + + if (action instanceof StartCompany) { + + StartCompany_1880 startCompanyAction = (StartCompany_1880) action; + + result = startCompany(playerName, startCompanyAction); + + return result; + } else { + return super.process(action); + } + } } |
From: Dr. M. B. <neu...@us...> - 2012-03-22 20:07:57
|
data/1880/CompanyManager.xml | 6 + rails/game/specific/_1880/ExchangeForCash_1880.java | 85 ++++++++++++++++++++ rails/game/specific/_1880/OperatingRound_1880.java | 25 ++++- rails/game/specific/_1880/StartCompany_1880.java | 12 ++ rails/game/specific/_1880/StockRound_1880.java | 82 +++++++++++++++++++ 5 files changed, 206 insertions(+), 4 deletions(-) New commits: commit 78a057aefc72557a3dc5c8642470c2946f157326 Author: Martin Brumm <Dr....@t-...> Date: Thu Mar 22 19:08:18 2012 +0100 Fixing the bug that certain Informations and properties of an 1880 company arent read from a saved game diff --git a/rails/game/specific/_1880/StartCompany_1880.java b/rails/game/specific/_1880/StartCompany_1880.java index 616b8bb..c877e3a 100644 --- a/rails/game/specific/_1880/StartCompany_1880.java +++ b/rails/game/specific/_1880/StartCompany_1880.java @@ -3,8 +3,11 @@ */ package rails.game.specific._1880; +import java.io.IOException; +import java.io.ObjectInputStream; import java.util.BitSet; +import rails.game.CompanyManagerI; import rails.game.PublicCompanyI; import rails.game.StockSpace; import rails.game.StockSpaceI; @@ -126,4 +129,13 @@ public class StartCompany_1880 extends StartCompany { ((StockMarket_1880) gameManager.getStockMarket()).setParSlot(startPrice); } + /** Deserialize */ + private void readObject(ObjectInputStream in) throws IOException, + ClassNotFoundException { + + in.defaultReadObject(); + + CompanyManagerI cmgr = getCompanyManager(); + + } } diff --git a/rails/game/specific/_1880/StockRound_1880.java b/rails/game/specific/_1880/StockRound_1880.java index 537f704..e878f56 100644 --- a/rails/game/specific/_1880/StockRound_1880.java +++ b/rails/game/specific/_1880/StockRound_1880.java @@ -9,13 +9,16 @@ import java.util.Arrays; import java.util.List; import java.util.Map; +import rails.common.DisplayBuffer; import rails.common.LocalText; import rails.game.*; import rails.game.action.BuyCertificate; import rails.game.action.PossibleAction; import rails.game.action.SellShares; import rails.game.action.StartCompany; +import rails.game.action.UseSpecialProperty; import rails.game.move.CashMove; +import rails.game.special.SpecialPropertyI; import rails.game.specific._1880.PublicCompany_1880; @@ -475,5 +478,84 @@ public class StockRound_1880 extends StockRound { } } + /* (non-Javadoc) + * @see rails.game.StockRound#useSpecialProperty(rails.game.action.UseSpecialProperty) + */ + @Override + public boolean useSpecialProperty(UseSpecialProperty action) { + SpecialPropertyI sp = action.getSpecialProperty(); + + // TODO This should work for all subclasses, but not all have execute() + // yet. + if (sp instanceof ExchangeForCash_1880) { + + boolean result = executeExchangeForCash((ExchangeForCash_1880) sp); + if (result) hasActed.set(true); + return result; + + } else { + return super.useSpecialProperty(action); + } + + } + + private boolean executeExchangeForCash(ExchangeForCash_1880 sp) { + CompanyI privateCompany = sp.getOriginalCompany(); + Portfolio portfolio = privateCompany.getPortfolio(); + + Player player = null; + String errMsg = null; + + while (true) { + + /* Check if the private is owned by a player */ + if (!(portfolio.getOwner() instanceof Player)) { + errMsg = + LocalText.getText("PrivateIsNotOwnedByAPlayer", + privateCompany.getName()); + break; + } + player = (Player) portfolio.getOwner(); + break; + } + if (errMsg != null) { + DisplayBuffer.add(LocalText.getText( + "CannotSwapPrivateForCash", + player.getName(), + privateCompany.getName(), + errMsg )); + return false; + } + + moveStack.start(true); + int amount = sp.getPhaseAmount(); + if (amount >0 ) { + player.addCash(amount); + sp.setExercised(); + privateCompany.setClosed(); + return true; + } + return false; + } + + /* (non-Javadoc) + * @see rails.game.StockRound#process(rails.game.action.PossibleAction) + */ + @Override + public boolean process(PossibleAction action) { + boolean result; + String playerName = action.getPlayerName(); + + if (action instanceof StartCompany) { + + StartCompany_1880 startCompanyAction = (StartCompany_1880) action; + + result = startCompany(playerName, startCompanyAction); + + return result; + } else { + return super.process(action); + } + } } commit c0efbb3a9c4433b6afe986d130e84afcd826919d Author: Martin Brumm <Dr....@t-...> Date: Thu Mar 22 19:07:29 2012 +0100 Introducing Exchange for Cash as Special Property diff --git a/data/1880/CompanyManager.xml b/data/1880/CompanyManager.xml index b20e346..ff26af7 100644 --- a/data/1880/CompanyManager.xml +++ b/data/1880/CompanyManager.xml @@ -47,6 +47,12 @@ <Company name="WR" longname="Woosong Railway" type="Private" basePrice="5" revenue="0"> + <SpecialProperties> + <SpecialProperty condition="ifOwnedByPlayer" when="anyTurn" + class="rails.game.specific._1880.ExchangeForCash_1880"> + <ExchangeForCash/> + </SpecialProperty> + </SpecialProperties> <ClosingConditions> <SpecialProperties condition="ifExercised"/> </ClosingConditions> diff --git a/rails/game/specific/_1880/ExchangeForCash_1880.java b/rails/game/specific/_1880/ExchangeForCash_1880.java new file mode 100644 index 0000000..98c409f --- /dev/null +++ b/rails/game/specific/_1880/ExchangeForCash_1880.java @@ -0,0 +1,85 @@ +/** + * + */ +package rails.game.specific._1880; + +import rails.common.LocalText; +import rails.common.parser.ConfigurationException; +import rails.common.parser.Tag; +import rails.game.PhaseI; +import rails.game.Player; +import rails.game.special.SpecialProperty; + +/** + * @author Martin + * + */ +public class ExchangeForCash_1880 extends SpecialProperty { + + int[] phaseAmount = {40,70,100}; + + @Override + public void configureFromXML(Tag tag) throws ConfigurationException { + + super.configureFromXML(tag); + + Tag swapTag = tag.getChild("ExchangeForCash"); + if (swapTag == null) { + throw new ConfigurationException("<ExchangeForCash> tag missing"); + } + +// String amount = swapTag.getAttributeAsString("amount"); +// if (!Util.hasValue(amount)) +// throw new ConfigurationException( +// "ExchangeForCash: amounts are missing"); + + } + + /* (non-Javadoc) + * @see rails.game.special.SpecialPropertyI#isExecutionable() + */ + public boolean isExecutionable() { + + return originalCompany.getPortfolio().getOwner() instanceof Player; + } + + /* (non-Javadoc) + * @see rails.game.special.SpecialPropertyI#getName() + */ + public String getName() { + return toString(); + } + + @Override + public String toString() { + return "Swap " + originalCompany.getName() + " for " + "{40, 70, 100 }" + + "Yuan"; + } + + public int getPhaseAmount() { + String currentPhase; + + currentPhase = gameManager.getCurrentPhase().getName(); + if (currentPhase == "3") { + return phaseAmount[0]; + } else if (currentPhase == "3+3"){ + return phaseAmount[1]; + } else if (currentPhase == "4") { + return phaseAmount[2]; + }else { + return 0; + } + + } + + @Override + public String toMenu() { + return LocalText.getText("SwapPrivateForMoney", + originalCompany.getName(), + "40, 70, 100 Yuan depending on the active Train"); + } + + public String getInfo() { + return toMenu(); + } +} diff --git a/rails/game/specific/_1880/OperatingRound_1880.java b/rails/game/specific/_1880/OperatingRound_1880.java index f3c1bf9..adc4b3d 100644 --- a/rails/game/specific/_1880/OperatingRound_1880.java +++ b/rails/game/specific/_1880/OperatingRound_1880.java @@ -18,6 +18,7 @@ import rails.game.BaseToken; import rails.game.Bonus; import rails.game.CashHolder; import rails.game.GameDef; +import rails.game.GameManager; import rails.game.GameManagerI; import rails.game.MapHex; import rails.game.OperatingRound; @@ -46,6 +47,7 @@ import rails.game.special.SpecialTrainBuy; import rails.game.specific._1880.PublicCompany_1880; import rails.game.specific._1880.GameManager_1880; import rails.game.state.EnumState; +import rails.ui.swing.GameUIManager; import rails.util.SequenceUtil; /** @@ -737,10 +739,25 @@ public class OperatingRound_1880 extends OperatingRound { } private void askForPrivateRocket(PhaseI newPhase) { - TrainType actualTrainForRocket= gameManager.getTrainManager().getTypeByName(newPhase.getName()); - //ToDo: Make a Window Popup that is asking the operating Player on Behalf of the Rocket Paper Owner - //to Act, we might have to follow the path of 1835 there. - + + } + + /* (non-Javadoc) + * @see rails.game.OperatingRound#processGameSpecificAction(rails.game.action.PossibleAction) + */ + @Override + public boolean processGameSpecificAction(PossibleAction action) { + // TODO Auto-generated method stub + return super.processGameSpecificAction(action); + } + + /* (non-Javadoc) + * @see rails.game.OperatingRound#setGameSpecificPossibleActions() + */ + @Override + protected void setGameSpecificPossibleActions() { + // TODO Auto-generated method stub + super.setGameSpecificPossibleActions(); } } |
From: Stefan F. <ste...@us...> - 2012-03-20 12:35:33
|
New branch 'specific_1880' available with the following commits: |
From: Erik V. <ev...@us...> - 2012-03-19 10:07:26
|
rails/ui/swing/hexmap/GUITile.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) New commits: commit 5b0f187fd940b9162d9690793eed1e5d65883d24 Author: Erik Vos <eri...@xs...> Date: Mon Mar 19 11:06:27 2012 +0100 Fix to previous commit diff --git a/rails/ui/swing/hexmap/GUITile.java b/rails/ui/swing/hexmap/GUITile.java index 9f34078..e28e64c 100644 --- a/rails/ui/swing/hexmap/GUITile.java +++ b/rails/ui/swing/hexmap/GUITile.java @@ -54,7 +54,7 @@ public class GUITile { TileManager tileManager = guiHex.getHexMap().orUIManager.getTileManager(); tile = tileManager.getTile(tileId); - if (tile.getId() > 0) { + if (tile.getPictureId() > 0) { // Layable tiles can have a different picture ID, defined per tile only. picId = tile.getPictureId(); } else { |
From: Erik V. <ev...@us...> - 2012-03-19 09:55:24
|
rails/game/MapHex.java | 1 + rails/ui/swing/hexmap/GUITile.java | 9 ++++++++- 2 files changed, 9 insertions(+), 1 deletion(-) New commits: commit e64779a1880d43bd4c810cf981b80654ddaab3bb Author: Martin Brumm <Dr....@t-...> Date: Mon Mar 19 10:54:15 2012 +0100 Fixed picture ID determination, which did not work for upgrades. diff --git a/rails/game/MapHex.java b/rails/game/MapHex.java index f6225cf..f02a37a 100644 --- a/rails/game/MapHex.java +++ b/rails/game/MapHex.java @@ -470,6 +470,7 @@ StationHolder, TokenHolder { /** Return the current picture ID (i.e. the tile ID to be displayed, rather than used for route determination). * <p> Usually, the picture ID is equal to the tile ID. Different values may be defined per hex or per tile. + * Restriction: definitions per hex can apply to preprinted tiles only. * @return The current picture ID */ public int getPictureId () { diff --git a/rails/ui/swing/hexmap/GUITile.java b/rails/ui/swing/hexmap/GUITile.java index f7162f9..9f34078 100644 --- a/rails/ui/swing/hexmap/GUITile.java +++ b/rails/ui/swing/hexmap/GUITile.java @@ -53,7 +53,14 @@ public class GUITile { this.hex = (MapHex)guiHex.getModel(); TileManager tileManager = guiHex.getHexMap().orUIManager.getTileManager(); tile = tileManager.getTile(tileId); - picId = hex.getPictureId(); + + if (tile.getId() > 0) { + // Layable tiles can have a different picture ID, defined per tile only. + picId = tile.getPictureId(); + } else { + // Preprinted tiles can have a different picture ID, defined per hex or per tile. + picId = hex.getPictureId(); + } if (hex.getTileOrientation() == TileOrientation.EW) { baseRotation = 0.5 * DEG60; |
From: Erik V. <ev...@us...> - 2012-03-18 15:25:49
|
rails/game/specific/_1880/OffBoardRevenueModifier_1880.java | 2 rails/game/specific/_1880/StartRound_1880.java | 21 +++++- rails/ui/swing/gamespecific/_1880/StartRoundWindow_1880.java | 36 +++++------ 3 files changed, 37 insertions(+), 22 deletions(-) New commits: commit d351b1a60f95c4dd78ea0ddedc60e311b6b1f87b Author: Martin Brumm <Dr....@t-...> Date: Sun Mar 18 16:03:21 2012 +0100 1880: fixed the reported bugs by Phil Davies. diff --git a/rails/game/specific/_1880/OffBoardRevenueModifier_1880.java b/rails/game/specific/_1880/OffBoardRevenueModifier_1880.java index 7580a5c..d8cbf97 100644 --- a/rails/game/specific/_1880/OffBoardRevenueModifier_1880.java +++ b/rails/game/specific/_1880/OffBoardRevenueModifier_1880.java @@ -29,7 +29,7 @@ public class OffBoardRevenueModifier_1880 implements RevenueStaticModifier { // 1. get the two off-board type stations (Russia and Wladiwostok) Set<NetworkVertex> offBoard = new HashSet<NetworkVertex>(); for (NetworkVertex vertex:revenueAdapter.getVertices()) { // We just need the two offboard Cities - if (vertex.isStation() && ((vertex.getStation().getName().equals("Russia") ||(vertex.getStation().getName().equals("Wladiwostok"))))) { + if (vertex.isStation() && ((vertex.getStation().getName().equals("Russia") ||(vertex.getStation().getName().equals("Vladivostok"))))) { offBoard.add(vertex); } } diff --git a/rails/game/specific/_1880/StartRound_1880.java b/rails/game/specific/_1880/StartRound_1880.java index d906796..9c2ecde 100644 --- a/rails/game/specific/_1880/StartRound_1880.java +++ b/rails/game/specific/_1880/StartRound_1880.java @@ -240,8 +240,25 @@ public class StartRound_1880 extends StartRound { Bank.format(bidAmount), item.getName(), Bank.format(player.getCash()) )); + if ((item.getBidders() >0) && (numPasses.intValue()== getNumberOfPlayers()-1)) { + // All but the highest bidder have passed. + int price = item.getBid(); + + log.debug("Highest bidder is " + + item.getBidder().getName()); + if (item.needsPriceSetting() != null) { + item.setStatus(StartItem.NEEDS_SHARE_PRICE); + } else { + assignItem(item.getBidder(), item, price, 0); + } + auctionItemState.set(null); + numPasses.set(0); + setNextStartingPlayer(); + return true; + } else { setNextBiddingPlayer(item); return true; + } } @@ -294,17 +311,15 @@ public class StartRound_1880 extends StartRound { assignItem((Player)startingPlayer.get(), auctionItem, 0, 0); setNextStartingPlayer(); - // startPacket.getFirstItem().getName()); return true; } } else { numPasses.set(0); - //gameManager.nextRound(this); finishRound(); } } - // if ((numPasses.intValue() >= auctionItem.getBidders() - 1) && + if ((auctionItem.getBidders() >0) && (numPasses.intValue()== getNumberOfPlayers()-1)) { // All but the highest bidder have passed. int price = auctionItem.getBid(); diff --git a/rails/ui/swing/gamespecific/_1880/StartRoundWindow_1880.java b/rails/ui/swing/gamespecific/_1880/StartRoundWindow_1880.java index dc264d2..7683295 100644 --- a/rails/ui/swing/gamespecific/_1880/StartRoundWindow_1880.java +++ b/rails/ui/swing/gamespecific/_1880/StartRoundWindow_1880.java @@ -77,22 +77,22 @@ public class StartRoundWindow_1880 extends StartRoundWindow { // Get a sorted prices List // TODO: should be included in BuyStartItem - List<StockSpaceI> startSpaces = stockMarket.getStartSpaces(); - Map<Integer, StockSpaceI> spacePerPrice = - new HashMap<Integer, StockSpaceI>(); - startPrices = new int[startSpaces.size()]; - String[] options = new String[startSpaces.size()]; - for (int i = 0; i < startSpaces.size(); i++) { - if (((StockMarket_1880) stockMarket).getParSlot(startSpaces.get(i).getPrice())) { //Make sure we got a Parslot left over - startPrices[i] = startSpaces.get(i).getPrice(); - spacePerPrice.put(startPrices[i], startSpaces.get(i)); - } - } - Arrays.sort(startPrices); - for (int i = 0; i < startSpaces.size(); i++) { - options[i] = Bank.format(spacePerPrice.get(startPrices[i]).getPrice()); - } - +// List<StockSpaceI> startSpaces = stockMarket.getStartSpaces(); +// Map<Integer, StockSpaceI> spacePerPrice = +// new HashMap<Integer, StockSpaceI>(); +// startPrices = new int[startSpaces.size()]; + String[] options = {""}; +// for (int i = 0; i < startSpaces.size(); i++) { +// if (((StockMarket_1880) stockMarket).getParSlot(startSpaces.get(i).getPrice())) { //Make sure we got a Parslot left over +// startPrices[i] = startSpaces.get(i).getPrice(); +// spacePerPrice.put(startPrices[i], startSpaces.get(i)); +// } +// } +// Arrays.sort(startPrices); +// for (int i = 0; i < startSpaces.size(); i++) { +// options[i] = Bank.format(spacePerPrice.get(startPrices[i]).getPrice()); +// } + options[0] = "100"; RadioButtonDialog dialog = new RadioButtonDialog( COMPANY_START_PRICE_DIALOG, this, @@ -102,7 +102,7 @@ public class StartRoundWindow_1880 extends StartRoundWindow { activeItem.getPlayerName(), compName), options, - -1); + 0); setCurrentDialog (dialog, activeItem); } return true; @@ -143,7 +143,7 @@ public class StartRoundWindow_1880 extends StartRoundWindow { int index = dialog.getSelectedOption(); if (index >= 0) { - int price = startPrices[index]; + int price = 100; action.setAssociatedSharePrice(price); ((StockMarket_1880) stockMarket).setParSlot(price); |
From: Stefan F. <ste...@us...> - 2012-03-17 06:59:45
|
data/1851/Game.xml | 2 data/1880/Game.xml | 2 data/18EU/Game.xml | 2 rails/game/specific/_1851/OffBoardRevenueModifier.java | 54 ------- rails/game/specific/_1851/OffBoardRevenueModifier_1851.java | 54 +++++++ rails/game/specific/_1880/OffBoardRevenueModifier.java | 61 -------- rails/game/specific/_1880/OffBoardRevenueModifier_1880.java | 61 ++++++++ rails/game/specific/_1880/PublicCompany_1880.java | 16 +- rails/game/specific/_18EU/OffBoardRevenueModifier.java | 91 ------------ rails/game/specific/_18EU/OffBoardRevenueModifier_18EU.java | 91 ++++++++++++ 10 files changed, 218 insertions(+), 216 deletions(-) New commits: commit c04dd80f6970197d123f1493f4f3c0d5f602d560 Author: Stefan Frey <ste...@we...> Date: Sat Mar 17 07:58:42 2012 +0100 Added missing check for running company to 1880 public company modifier Changed OffBoardRevenueModifier names that the contain game name diff --git a/data/1851/Game.xml b/data/1851/Game.xml index b11fe1f..ea507f0 100644 --- a/data/1851/Game.xml +++ b/data/1851/Game.xml @@ -116,7 +116,7 @@ </Phase> </Component> <Component name="RevenueManager" class="rails.algorithms.RevenueManager"> - <Modifier class="rails.game.specific._1851.OffBoardRevenueModifier" /> + <Modifier class="rails.game.specific._1851.OffBoardRevenueModifier_1851" /> <Modifier class="rails.game.specific._1851.BirminghamTileModifier" /> </Component> </ComponentManager> \ No newline at end of file diff --git a/data/1880/Game.xml b/data/1880/Game.xml index 47f58c5..3e738ec 100644 --- a/data/1880/Game.xml +++ b/data/1880/Game.xml @@ -163,7 +163,7 @@ </Phase> </Component> <Component name="RevenueManager" class="rails.algorithms.RevenueManager"> - <Modifier class="rails.game.specific._1880.OffBoardRevenueModifier"/> + <Modifier class="rails.game.specific._1880.OffBoardRevenueModifier_1880"/> </Component> </ComponentManager> \ No newline at end of file diff --git a/data/18EU/Game.xml b/data/18EU/Game.xml index 01e39f5..4ac5fff 100644 --- a/data/18EU/Game.xml +++ b/data/18EU/Game.xml @@ -131,7 +131,7 @@ </Phase> </Component> <Component name="RevenueManager" class="rails.algorithms.RevenueManager"> - <Modifier class="rails.game.specific._18EU.OffBoardRevenueModifier"/> + <Modifier class="rails.game.specific._18EU.OffBoardRevenueModifier_18EU"/> <Modifier class="rails.game.specific._18EU.PullmanRevenueModifier"/> </Component> </ComponentManager> \ No newline at end of file diff --git a/rails/game/specific/_1851/OffBoardRevenueModifier.java b/rails/game/specific/_1851/OffBoardRevenueModifier.java deleted file mode 100644 index 6956f3c..0000000 --- a/rails/game/specific/_1851/OffBoardRevenueModifier.java +++ /dev/null @@ -1,54 +0,0 @@ -package rails.game.specific._1851; - -import java.util.HashSet; -import java.util.Set; - -import rails.algorithms.NetworkVertex; -import rails.algorithms.RevenueAdapter; -import rails.algorithms.RevenueBonus; -import rails.algorithms.RevenueStaticModifier; -import rails.game.Station; - -public class OffBoardRevenueModifier implements RevenueStaticModifier { - - private static final int BONUS_VALUE = 10; - - public boolean modifyCalculator(RevenueAdapter revenueAdapter) { - // 1. get all off-board type stations and all other stations - Set<NetworkVertex> offBoard = new HashSet<NetworkVertex>(); - Set<NetworkVertex> otherStations = new HashSet<NetworkVertex>(); - for (NetworkVertex vertex:revenueAdapter.getVertices()) { - if (vertex.isStation()) { - if (vertex.getStation().getType().equals(Station.OFF_MAP_AREA)){ - offBoard.add(vertex); - } else { - otherStations.add(vertex); - } - } - } - // 2. combine those to revenueBonuses - // always two offboard areas and one other - Set<NetworkVertex> destOffBoard = new HashSet<NetworkVertex>(offBoard); - RevenueBonus bonus; - for (NetworkVertex offA:offBoard) { - destOffBoard.remove(offA); - for (NetworkVertex offB:destOffBoard) { - bonus = new RevenueBonus(2*BONUS_VALUE, "Red-To-Red"); - bonus.addVertex(offA); bonus.addVertex(offB);; - revenueAdapter.addRevenueBonus(bonus); - for (NetworkVertex station:otherStations) { - bonus = new RevenueBonus(BONUS_VALUE, "Red-To-Red"); - bonus.addVertex(offA); bonus.addVertex(offB); bonus.addVertex(station); - revenueAdapter.addRevenueBonus(bonus); - } - } - } - // no additional text required - return false; - } - - public String prettyPrint(RevenueAdapter revenueAdapter) { - // nothing to print - return null; - } -} diff --git a/rails/game/specific/_1851/OffBoardRevenueModifier_1851.java b/rails/game/specific/_1851/OffBoardRevenueModifier_1851.java new file mode 100644 index 0000000..5b93edb --- /dev/null +++ b/rails/game/specific/_1851/OffBoardRevenueModifier_1851.java @@ -0,0 +1,54 @@ +package rails.game.specific._1851; + +import java.util.HashSet; +import java.util.Set; + +import rails.algorithms.NetworkVertex; +import rails.algorithms.RevenueAdapter; +import rails.algorithms.RevenueBonus; +import rails.algorithms.RevenueStaticModifier; +import rails.game.Station; + +public class OffBoardRevenueModifier_1851 implements RevenueStaticModifier { + + private static final int BONUS_VALUE = 10; + + public boolean modifyCalculator(RevenueAdapter revenueAdapter) { + // 1. get all off-board type stations and all other stations + Set<NetworkVertex> offBoard = new HashSet<NetworkVertex>(); + Set<NetworkVertex> otherStations = new HashSet<NetworkVertex>(); + for (NetworkVertex vertex:revenueAdapter.getVertices()) { + if (vertex.isStation()) { + if (vertex.getStation().getType().equals(Station.OFF_MAP_AREA)){ + offBoard.add(vertex); + } else { + otherStations.add(vertex); + } + } + } + // 2. combine those to revenueBonuses + // always two offboard areas and one other + Set<NetworkVertex> destOffBoard = new HashSet<NetworkVertex>(offBoard); + RevenueBonus bonus; + for (NetworkVertex offA:offBoard) { + destOffBoard.remove(offA); + for (NetworkVertex offB:destOffBoard) { + bonus = new RevenueBonus(2*BONUS_VALUE, "Red-To-Red"); + bonus.addVertex(offA); bonus.addVertex(offB);; + revenueAdapter.addRevenueBonus(bonus); + for (NetworkVertex station:otherStations) { + bonus = new RevenueBonus(BONUS_VALUE, "Red-To-Red"); + bonus.addVertex(offA); bonus.addVertex(offB); bonus.addVertex(station); + revenueAdapter.addRevenueBonus(bonus); + } + } + } + // no additional text required + return false; + } + + public String prettyPrint(RevenueAdapter revenueAdapter) { + // nothing to print + return null; + } +} diff --git a/rails/game/specific/_1880/OffBoardRevenueModifier.java b/rails/game/specific/_1880/OffBoardRevenueModifier.java deleted file mode 100644 index 28b34e8..0000000 --- a/rails/game/specific/_1880/OffBoardRevenueModifier.java +++ /dev/null @@ -1,61 +0,0 @@ -/** - * - */ -package rails.game.specific._1880; - -import java.util.HashSet; -import java.util.Set; - -import org.apache.log4j.Logger; - -import rails.algorithms.NetworkVertex; -import rails.algorithms.RevenueAdapter; -import rails.algorithms.RevenueBonus; -import rails.algorithms.RevenueStaticModifier; -import rails.game.Station; - -/** - * @author Martin - * - */ -public class OffBoardRevenueModifier implements RevenueStaticModifier { - - - protected static Logger log = - Logger.getLogger(OffBoardRevenueModifier.class.getPackage().getName()); - - public boolean modifyCalculator(RevenueAdapter revenueAdapter) { - - // 1. get the two off-board type stations (Russia and Wladiwostok) - Set<NetworkVertex> offBoard = new HashSet<NetworkVertex>(); - for (NetworkVertex vertex:revenueAdapter.getVertices()) { // We just need the two offboard Cities - if (vertex.isStation() && ((vertex.getStation().getName().equals("Russia") ||(vertex.getStation().getName().equals("Wladiwostok"))))) { - offBoard.add(vertex); - } - } - // 2. get all base tokens (=> start vertices) - Set<NetworkVertex> bases = revenueAdapter.getStartVertices(); - - // 3. combine those to revenueBonuses - // always two offboard areas and one base - Set<NetworkVertex> destOffBoard = new HashSet<NetworkVertex>(offBoard); - for (NetworkVertex offA:offBoard) { - destOffBoard.remove(offA); - for (NetworkVertex offB:destOffBoard) { - for (NetworkVertex base:bases) { - RevenueBonus bonus = new RevenueBonus(50, "Red-To-Red"); - bonus.addVertex(offA); bonus.addVertex(offB); bonus.addVertex(base); - revenueAdapter.addRevenueBonus(bonus); - } - } - } - - return false; - } - - public String prettyPrint(RevenueAdapter revenueAdapter) { - // TODO Auto-generated method stub - return null; - } - -} diff --git a/rails/game/specific/_1880/OffBoardRevenueModifier_1880.java b/rails/game/specific/_1880/OffBoardRevenueModifier_1880.java new file mode 100644 index 0000000..7580a5c --- /dev/null +++ b/rails/game/specific/_1880/OffBoardRevenueModifier_1880.java @@ -0,0 +1,61 @@ +/** + * + */ +package rails.game.specific._1880; + +import java.util.HashSet; +import java.util.Set; + +import org.apache.log4j.Logger; + +import rails.algorithms.NetworkVertex; +import rails.algorithms.RevenueAdapter; +import rails.algorithms.RevenueBonus; +import rails.algorithms.RevenueStaticModifier; +import rails.game.Station; + +/** + * @author Martin + * + */ +public class OffBoardRevenueModifier_1880 implements RevenueStaticModifier { + + + protected static Logger log = + Logger.getLogger(OffBoardRevenueModifier_1880.class.getPackage().getName()); + + public boolean modifyCalculator(RevenueAdapter revenueAdapter) { + + // 1. get the two off-board type stations (Russia and Wladiwostok) + Set<NetworkVertex> offBoard = new HashSet<NetworkVertex>(); + for (NetworkVertex vertex:revenueAdapter.getVertices()) { // We just need the two offboard Cities + if (vertex.isStation() && ((vertex.getStation().getName().equals("Russia") ||(vertex.getStation().getName().equals("Wladiwostok"))))) { + offBoard.add(vertex); + } + } + // 2. get all base tokens (=> start vertices) + Set<NetworkVertex> bases = revenueAdapter.getStartVertices(); + + // 3. combine those to revenueBonuses + // always two offboard areas and one base + Set<NetworkVertex> destOffBoard = new HashSet<NetworkVertex>(offBoard); + for (NetworkVertex offA:offBoard) { + destOffBoard.remove(offA); + for (NetworkVertex offB:destOffBoard) { + for (NetworkVertex base:bases) { + RevenueBonus bonus = new RevenueBonus(50, "Red-To-Red"); + bonus.addVertex(offA); bonus.addVertex(offB); bonus.addVertex(base); + revenueAdapter.addRevenueBonus(bonus); + } + } + } + + return false; + } + + public String prettyPrint(RevenueAdapter revenueAdapter) { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/rails/game/specific/_1880/PublicCompany_1880.java b/rails/game/specific/_1880/PublicCompany_1880.java index 0b8e369..887d362 100644 --- a/rails/game/specific/_1880/PublicCompany_1880.java +++ b/rails/game/specific/_1880/PublicCompany_1880.java @@ -220,19 +220,21 @@ public class PublicCompany_1880 extends PublicCompany implements RevenueStaticMo } public boolean modifyCalculator(RevenueAdapter revenueAdapter) { - // check if the running company is a minor - if (revenueAdapter.getCompany().getTypeName().equals("Minor")) { - - // add the current Available train from the IPO and not the last train in Use - TrainManager trainManager=gameManager.getTrainManager(); - revenueAdapter.addTrainByString(trainManager.getAvailableNewTrains().get(0).getName()); + // check if running company is this company, otherwise quit + if (revenueAdapter.getCompany() != this) return false; + + // check if company is a minor + if (this.getTypeName().equals("Minor")) { + // add the current Available train from the IPO and not the last train in Use + TrainManager trainManager=gameManager.getTrainManager(); + revenueAdapter.addTrainByString(trainManager.getAvailableNewTrains().get(0).getName()); } else { int additionalStockRevenue = revenueAdapter.getCompany().getCurrentSpace().getType().hasAddRevenue()*10; RevenueBonus bonus = new RevenueBonus(additionalStockRevenue, "StockPosition"); revenueAdapter.addRevenueBonus(bonus); } + // no text needed return false; - } /* (non-Javadoc) diff --git a/rails/game/specific/_18EU/OffBoardRevenueModifier.java b/rails/game/specific/_18EU/OffBoardRevenueModifier.java deleted file mode 100644 index ce0d0ae..0000000 --- a/rails/game/specific/_18EU/OffBoardRevenueModifier.java +++ /dev/null @@ -1,91 +0,0 @@ -package rails.game.specific._18EU; - -import java.util.HashSet; -import java.util.Set; - -import org.apache.log4j.Logger; - -import rails.algorithms.NetworkVertex; -import rails.algorithms.RevenueAdapter; -import rails.algorithms.RevenueBonus; -import rails.algorithms.RevenueStaticModifier; -import rails.algorithms.RevenueAdapter.VertexVisit; -import rails.game.PhaseI; -import rails.game.Station; -import rails.game.Tile; - -public class OffBoardRevenueModifier implements RevenueStaticModifier { - - protected static Logger log = - Logger.getLogger(OffBoardRevenueModifier.class.getPackage().getName()); - - - public boolean modifyCalculator(RevenueAdapter revenueAdapter) { - - // 1. define value - PhaseI phase = revenueAdapter.getPhase(); - int bonusValue; - if (phase.isTileColourAllowed(Tile.GREY_COLOUR_NAME)) { - bonusValue = 30; - } else if (phase.isTileColourAllowed(Tile.BROWN_COLOUR_NAME)) { - bonusValue = 20; - } else if (phase.isTileColourAllowed(Tile.GREEN_COLOUR_NAME)) { - bonusValue = 10; - } else { - return false; - } - - log.info("OffBoardRevenueModifier: bonusValue = " + bonusValue); - - // 2. get all off-board type stations and Hamburg - Set<NetworkVertex> offBoard = new HashSet<NetworkVertex>(); - for (NetworkVertex vertex:revenueAdapter.getVertices()) { - if (vertex.isStation() && vertex.getStation().getType().equals(Station.OFF_MAP_AREA)){ - offBoard.add(vertex); - } - } - - // 3. get Hamburg ... - NetworkVertex hamburgCity = NetworkVertex.getVertexByIdentifier(revenueAdapter.getVertices(), "B7.-1"); - if (hamburgCity != null) { - // ... and duplicate the vertex - NetworkVertex hamburgTerminal = NetworkVertex.duplicateVertex(revenueAdapter.getGraph(), hamburgCity, "B7", true); - hamburgTerminal.setSink(true); - offBoard.add(hamburgTerminal); - - // vertexVisitSet for the two Hamburgs - VertexVisit hamburgSet = revenueAdapter.new VertexVisit(); - hamburgSet.set.add(hamburgCity); - hamburgSet.set.add(hamburgTerminal); - revenueAdapter.addVertexVisitSet(hamburgSet); - } - - log.info("OffBoardRevenueModifier: offBoard = " + offBoard); - - // 4. get all base tokens (=> start vertices) - Set<NetworkVertex> bases = revenueAdapter.getStartVertices(); - - - // 5. combine those to revenueBonuses - // always two offboard areas and one base - Set<NetworkVertex> destOffBoard = new HashSet<NetworkVertex>(offBoard); - for (NetworkVertex offA:offBoard) { - destOffBoard.remove(offA); - for (NetworkVertex offB:destOffBoard) { - for (NetworkVertex base:bases) { - RevenueBonus bonus = new RevenueBonus(bonusValue, "Red-To-Red"); - bonus.addVertex(offA); bonus.addVertex(offB); bonus.addVertex(base); - revenueAdapter.addRevenueBonus(bonus); - } - } - } - // no additional text required - return false; - } - - - public String prettyPrint(RevenueAdapter revenueAdapter) { - // nothing to do - return null; - } -} diff --git a/rails/game/specific/_18EU/OffBoardRevenueModifier_18EU.java b/rails/game/specific/_18EU/OffBoardRevenueModifier_18EU.java new file mode 100644 index 0000000..ae2e2d7 --- /dev/null +++ b/rails/game/specific/_18EU/OffBoardRevenueModifier_18EU.java @@ -0,0 +1,91 @@ +package rails.game.specific._18EU; + +import java.util.HashSet; +import java.util.Set; + +import org.apache.log4j.Logger; + +import rails.algorithms.NetworkVertex; +import rails.algorithms.RevenueAdapter; +import rails.algorithms.RevenueBonus; +import rails.algorithms.RevenueStaticModifier; +import rails.algorithms.RevenueAdapter.VertexVisit; +import rails.game.PhaseI; +import rails.game.Station; +import rails.game.Tile; + +public class OffBoardRevenueModifier_18EU implements RevenueStaticModifier { + + protected static Logger log = + Logger.getLogger(OffBoardRevenueModifier_18EU.class.getPackage().getName()); + + + public boolean modifyCalculator(RevenueAdapter revenueAdapter) { + + // 1. define value + PhaseI phase = revenueAdapter.getPhase(); + int bonusValue; + if (phase.isTileColourAllowed(Tile.GREY_COLOUR_NAME)) { + bonusValue = 30; + } else if (phase.isTileColourAllowed(Tile.BROWN_COLOUR_NAME)) { + bonusValue = 20; + } else if (phase.isTileColourAllowed(Tile.GREEN_COLOUR_NAME)) { + bonusValue = 10; + } else { + return false; + } + + log.info("OffBoardRevenueModifier: bonusValue = " + bonusValue); + + // 2. get all off-board type stations and Hamburg + Set<NetworkVertex> offBoard = new HashSet<NetworkVertex>(); + for (NetworkVertex vertex:revenueAdapter.getVertices()) { + if (vertex.isStation() && vertex.getStation().getType().equals(Station.OFF_MAP_AREA)){ + offBoard.add(vertex); + } + } + + // 3. get Hamburg ... + NetworkVertex hamburgCity = NetworkVertex.getVertexByIdentifier(revenueAdapter.getVertices(), "B7.-1"); + if (hamburgCity != null) { + // ... and duplicate the vertex + NetworkVertex hamburgTerminal = NetworkVertex.duplicateVertex(revenueAdapter.getGraph(), hamburgCity, "B7", true); + hamburgTerminal.setSink(true); + offBoard.add(hamburgTerminal); + + // vertexVisitSet for the two Hamburgs + VertexVisit hamburgSet = revenueAdapter.new VertexVisit(); + hamburgSet.set.add(hamburgCity); + hamburgSet.set.add(hamburgTerminal); + revenueAdapter.addVertexVisitSet(hamburgSet); + } + + log.info("OffBoardRevenueModifier: offBoard = " + offBoard); + + // 4. get all base tokens (=> start vertices) + Set<NetworkVertex> bases = revenueAdapter.getStartVertices(); + + + // 5. combine those to revenueBonuses + // always two offboard areas and one base + Set<NetworkVertex> destOffBoard = new HashSet<NetworkVertex>(offBoard); + for (NetworkVertex offA:offBoard) { + destOffBoard.remove(offA); + for (NetworkVertex offB:destOffBoard) { + for (NetworkVertex base:bases) { + RevenueBonus bonus = new RevenueBonus(bonusValue, "Red-To-Red"); + bonus.addVertex(offA); bonus.addVertex(offB); bonus.addVertex(base); + revenueAdapter.addRevenueBonus(bonus); + } + } + } + // no additional text required + return false; + } + + + public String prettyPrint(RevenueAdapter revenueAdapter) { + // nothing to do + return null; + } +} |
From: Erik V. <ev...@us...> - 2012-03-14 10:41:27
|
data/1830/Map.xml | 4 rails/game/MapHex.java | 16 rails/game/specific/_1880/OffBoardRevenueModifier.java | 61 +++ rails/game/specific/_1880/ShareSellingRound_1880.java | 252 ++++++++++++++ rails/game/specific/_1880/SpecialTrainBuy_1880.java | 140 +++++++ rails/game/specific/_1880/StartCompany_1880.java | 129 +++++++ rails/ui/swing/gamespecific/_1880/GameUIManager_1880.java | 152 ++++++++ rails/ui/swing/hexmap/GUITile.java | 40 +- 8 files changed, 772 insertions(+), 22 deletions(-) New commits: commit d975e7487015fac50223998ccb613a458f52f4a6 Author: Martin Brumm <Dr....@t-...> Date: Wed Mar 14 11:38:07 2012 +0100 Added the missing new 1880-specific classes diff --git a/rails/game/specific/_1880/OffBoardRevenueModifier.java b/rails/game/specific/_1880/OffBoardRevenueModifier.java new file mode 100644 index 0000000..28b34e8 --- /dev/null +++ b/rails/game/specific/_1880/OffBoardRevenueModifier.java @@ -0,0 +1,61 @@ +/** + * + */ +package rails.game.specific._1880; + +import java.util.HashSet; +import java.util.Set; + +import org.apache.log4j.Logger; + +import rails.algorithms.NetworkVertex; +import rails.algorithms.RevenueAdapter; +import rails.algorithms.RevenueBonus; +import rails.algorithms.RevenueStaticModifier; +import rails.game.Station; + +/** + * @author Martin + * + */ +public class OffBoardRevenueModifier implements RevenueStaticModifier { + + + protected static Logger log = + Logger.getLogger(OffBoardRevenueModifier.class.getPackage().getName()); + + public boolean modifyCalculator(RevenueAdapter revenueAdapter) { + + // 1. get the two off-board type stations (Russia and Wladiwostok) + Set<NetworkVertex> offBoard = new HashSet<NetworkVertex>(); + for (NetworkVertex vertex:revenueAdapter.getVertices()) { // We just need the two offboard Cities + if (vertex.isStation() && ((vertex.getStation().getName().equals("Russia") ||(vertex.getStation().getName().equals("Wladiwostok"))))) { + offBoard.add(vertex); + } + } + // 2. get all base tokens (=> start vertices) + Set<NetworkVertex> bases = revenueAdapter.getStartVertices(); + + // 3. combine those to revenueBonuses + // always two offboard areas and one base + Set<NetworkVertex> destOffBoard = new HashSet<NetworkVertex>(offBoard); + for (NetworkVertex offA:offBoard) { + destOffBoard.remove(offA); + for (NetworkVertex offB:destOffBoard) { + for (NetworkVertex base:bases) { + RevenueBonus bonus = new RevenueBonus(50, "Red-To-Red"); + bonus.addVertex(offA); bonus.addVertex(offB); bonus.addVertex(base); + revenueAdapter.addRevenueBonus(bonus); + } + } + } + + return false; + } + + public String prettyPrint(RevenueAdapter revenueAdapter) { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/rails/game/specific/_1880/ShareSellingRound_1880.java b/rails/game/specific/_1880/ShareSellingRound_1880.java new file mode 100644 index 0000000..78c15f8 --- /dev/null +++ b/rails/game/specific/_1880/ShareSellingRound_1880.java @@ -0,0 +1,252 @@ +/** + * + */ +package rails.game.specific._1880; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import rails.common.DisplayBuffer; +import rails.common.LocalText; +import rails.common.parser.GameOption; +import rails.game.Bank; +import rails.game.GameDef; +import rails.game.GameManagerI; +import rails.game.Player; +import rails.game.Portfolio; +import rails.game.PublicCertificateI; +import rails.game.PublicCompanyI; +import rails.game.ReportBuffer; +import rails.game.RoundI; +import rails.game.ShareSellingRound; +import rails.game.StockSpaceI; +import rails.game.action.NullAction; +import rails.game.action.PossibleAction; +import rails.game.action.SellShares; + +/** + * @author Martin + * + */ +public class ShareSellingRound_1880 extends ShareSellingRound { + + /** + * @param gameManager + * @param parentRound + */ + public ShareSellingRound_1880(GameManagerI gameManager, RoundI parentRound) { + super(gameManager, parentRound); + // TODO Auto-generated constructor stub + } + + + @Override + public boolean setPossibleActions() { + + possibleActions.clear(); + + setSellableShares(); + + possibleActions.add(new NullAction(NullAction.DONE)); + + for (PossibleAction pa : possibleActions.getList()) { + log.debug(currentPlayer.getName() + " may: " + pa.toString()); + } + + return true; + } + + + /* (non-Javadoc) + * @see rails.game.StockRound#process(rails.game.action.PossibleAction) + */ + @Override + public boolean process(PossibleAction action) { + + currentPlayer = getCurrentPlayer(); + + if (action instanceof NullAction) { + + currentPlayer.addCash(-cashToRaise.intValue()); + gameManager.finishShareSellingRound(); + return true; + } else { + return super.process(action); + } + } + + + /* (non-Javadoc) + * @see rails.game.ShareSellingRound#sellShares(rails.game.action.SellShares) + */ + @Override + public boolean sellShares(SellShares action) { + Portfolio portfolio = currentPlayer.getPortfolio(); + String playerName = currentPlayer.getName(); + String errMsg = null; + String companyName = action.getCompanyName(); + PublicCompanyI company = + companyManager.getPublicCompany(action.getCompanyName()); + PublicCertificateI cert = null; + PublicCertificateI presCert = null; + List<PublicCertificateI> certsToSell = + new ArrayList<PublicCertificateI>(); + Player dumpedPlayer = null; + int presSharesToSell = 0; + int numberToSell = action.getNumber(); + int shareUnits = action.getShareUnits(); + int currentIndex = getCurrentPlayerIndex(); + + // Dummy loop to allow a quick jump out + while (true) { + + // Check everything + if (numberToSell <= 0) { + errMsg = LocalText.getText("NoSellZero"); + break; + } + + // Check company + if (company == null) { + errMsg = LocalText.getText("NoCompany"); + break; + } + + // May player sell this company + if (!mayPlayerSellShareOfCompany(company)) { + errMsg = LocalText.getText("SaleNotAllowed", companyName); + break; + } + + // The player must have the share(s) + if (portfolio.getShare(company) < numberToSell) { + errMsg = LocalText.getText("NoShareOwned"); + break; + } + + // The pool may not get over its limit. + if (pool.getShare(company) + numberToSell * company.getShareUnit() + > getGameParameterAsInt(GameDef.Parm.POOL_SHARE_LIMIT)) { + errMsg = LocalText.getText("PoolOverHoldLimit"); + break; + } + + // Find the certificates to sell + Iterator<PublicCertificateI> it = + portfolio.getCertificatesPerCompany(companyName).iterator(); + while (numberToSell > 0 && it.hasNext()) { + cert = it.next(); + if (cert.isPresidentShare()) { + // Remember the president's certificate in case we need it + if (cert.isPresidentShare()) presCert = cert; + continue; + } else if (shareUnits != cert.getShares()) { + // Wrong number of share units + continue; + } + // OK, we will sell this one + certsToSell.add(cert); + numberToSell--; + } + if (numberToSell == 0) presCert = null; + + if (numberToSell > 0 && presCert != null + && numberToSell <= presCert.getShares()) { + // Not allowed to dump the company that needs the train + if (company == cashNeedingCompany || !dumpOtherCompaniesAllowed) { + errMsg = + LocalText.getText("CannotDumpTrainBuyingPresidency"); + break; + } + // More to sell and we are President: see if we can dump it. + Player otherPlayer; + for (int i = currentIndex + 1; i < currentIndex + + numberOfPlayers; i++) { + otherPlayer = gameManager.getPlayerByIndex(i); + if (otherPlayer.getPortfolio().getShare(company) >= presCert.getShare()) { + // Check if he has the right kind of share + if (numberToSell > 1 + || otherPlayer.getPortfolio().ownsCertificates( + company, 1, false) >= 1) { + // The poor sod. + dumpedPlayer = otherPlayer; + presSharesToSell = numberToSell; + numberToSell = 0; + break; + } + } + } + } + // Check if we could sell them all + if (numberToSell > 0) { + if (presCert != null) { + errMsg = LocalText.getText("NoDumping"); + } else { + errMsg = LocalText.getText("NotEnoughShares"); + } + break; + } + + break; + } + + int numberSold = action.getNumber(); + if (errMsg != null) { + DisplayBuffer.add(LocalText.getText("CantSell", + playerName, + numberSold, + companyName, + errMsg )); + return false; + } + + // All seems OK, now do the selling. + StockSpaceI sellPrice; + int price; + + // Get the sell price (does not change within a turn) + if (sellPrices.containsKey(companyName) + && GameOption.convertValueToBoolean(getGameOption("SeparateSalesAtSamePrice"))) { + price = (sellPrices.get(companyName)).getPrice(); + } else { + sellPrice = company.getCurrentSpace(); + price = sellPrice.getPrice(); + sellPrices.put(companyName, sellPrice); + } + int cashAmount = ((numberSold * price * shareUnits)-(numberSold * 5)); //Deduct 5 Yuan per Sharecertificate Sold... + + moveStack.start(true).linkToPreviousMoveSet(); + + ReportBuffer.add(LocalText.getText("SELL_SHARES_LOG", + playerName, + numberSold, + company.getShareUnit(), + numberSold * company.getShareUnit(), + companyName, + Bank.format(cashAmount) )); + + boolean soldBefore = sellPrices.containsKey(companyName); + + pay (bank, currentPlayer, cashAmount); + adjustSharePrice (company, numberSold, soldBefore); + + if (!company.isClosed()) { + + executeShareTransfer (company, certsToSell, + dumpedPlayer, presSharesToSell, action.getPresidentExchange()); + } + + cashToRaise.add(-numberSold * price); + + if (cashToRaise.intValue() <= 0) { + gameManager.finishShareSellingRound(); + } else if (getSellableShares().isEmpty()) { + gameManager.finishShareSellingRound(); + } + + return true; // TODO Auto-generated method stub + } + + +} diff --git a/rails/game/specific/_1880/SpecialTrainBuy_1880.java b/rails/game/specific/_1880/SpecialTrainBuy_1880.java new file mode 100644 index 0000000..7dfbb3c --- /dev/null +++ b/rails/game/specific/_1880/SpecialTrainBuy_1880.java @@ -0,0 +1,140 @@ +package rails.game.specific._1880; + +import java.util.List; + +import rails.common.LocalText; +import rails.common.parser.ConfigurationException; +import rails.common.parser.Tag; +import rails.game.*; +import rails.game.special.SpecialProperty; +import rails.util.Util; + +/** + * Special private ability involving deductions in train buying. The deduction + * can be absolute (an amount) or relative (a percentage) + * + * @author Erik Voss + * @author Martin Brumm + * + */ +public class SpecialTrainBuy_1880 extends SpecialProperty { + + String name = "SpecialTrainBuy_1880"; + String trainTypeName = ""; // Default: all train types + List<TrainType> trainTypes =null; + boolean extra = false; + String deductionString; + boolean relativeDeduction = false; + boolean absoluteDeduction = false; + int deductionAmount; // Money or percentage + + public void configureFromXML(Tag tag) throws ConfigurationException { + + super.configureFromXML(tag); + + Tag trainBuyTag = tag.getChild("SpecialTrainBuy_1880"); + if (trainBuyTag == null) { + throw new ConfigurationException("<SpecialTrainBuy> tag missing"); + } + + trainTypeName = + trainBuyTag.getAttributeAsString("trainType", trainTypeName); + if (trainTypeName.equalsIgnoreCase("any")) trainTypeName = ""; + + deductionString = trainBuyTag.getAttributeAsString("deduction"); + if (!Util.hasValue(deductionString)) { + throw new ConfigurationException( + "No deduction found in <SpecialTrainBuy> tag"); + } + String deductionAmountString; + if (deductionString.endsWith("%")) { + relativeDeduction = true; + deductionAmountString = deductionString.replaceAll("%", ""); + } else { + deductionAmountString = deductionString; + } + try { + deductionAmount = Integer.parseInt(deductionAmountString); + } catch (NumberFormatException e) { + throw new ConfigurationException("Invalid deduction " + + deductionString, e); + } + + } + + @Override + public void finishConfiguration (GameManagerI gameManager) + throws ConfigurationException { + trainTypes=gameManager.getTrainManager().parseTrainTypes(trainTypeName); + } + + public int getPrice(int standardPrice) { + + if (absoluteDeduction) { + return standardPrice - deductionAmount; + } else if (relativeDeduction) { + return (int) (standardPrice * (0.01 * (100 - deductionAmount))); + } else { + return standardPrice; + } + } + + public boolean isValidForTrainType(String trainType) { + return trainTypeName.equals("") + || trainTypeName.equalsIgnoreCase(trainType); + } + + public boolean isExecutionable() { + return true; + } + + public boolean isExtra() { + return extra; + } + + public boolean isFree() { + return false; + } + + public String getName() { + return name; + } + + public boolean isAbsoluteDeduction() { + return absoluteDeduction; + } + + public int getDeductionAmount() { + return deductionAmount; + } + + public String getDeductionString() { + return deductionString; + } + + public boolean isRelativeDeduction() { + return relativeDeduction; + } + + public String getTrainTypeName() { + return trainTypeName; + } + + public String toString() { + return "SpecialTrainBuy comp=" + originalCompany.getName() + " extra=" + + extra + " deduction=" + deductionString; + } + + @Override + public String toMenu() { + + return LocalText.getText("SpecialTrainBuy_1880", + trainTypeName, + deductionString, + originalCompany.getName()); + } + + public String getInfo() { + return toMenu(); + } +} diff --git a/rails/game/specific/_1880/StartCompany_1880.java b/rails/game/specific/_1880/StartCompany_1880.java new file mode 100644 index 0000000..616b8bb --- /dev/null +++ b/rails/game/specific/_1880/StartCompany_1880.java @@ -0,0 +1,129 @@ +/** + * + */ +package rails.game.specific._1880; + +import java.util.BitSet; + +import rails.game.PublicCompanyI; +import rails.game.StockSpace; +import rails.game.StockSpaceI; +import rails.game.action.StartCompany; + +/** + * @author Martin + * + */ +public class StartCompany_1880 extends StartCompany { + + /** + * + */ + private static final long serialVersionUID = 1L; + + + /** + * @param company + * @param prices + * @param maximumNumber + */ + public StartCompany_1880(PublicCompanyI company, int[] prices, + int maximumNumber) { + super(company, prices, maximumNumber); + // TODO Auto-generated constructor stub + } + + /** + * @param company + * @param startPrice + */ + public StartCompany_1880(PublicCompanyI company, int[] startPrice) { + this(company, startPrice, 1); + // TODO Auto-generated constructor stub + + } + + /** + * @param company + * @param price + * @param maximumNumber + */ + public StartCompany_1880(PublicCompanyI company, int price, + int maximumNumber) { + super(company, price, maximumNumber); + StockSpaceI parPrice=gameManager.getStockMarket().getStartSpace(price); + this.getCompany().setParSpace(parPrice); + // TODO Auto-generated constructor stub + } + + /** + * @param company + * @param price + */ + public StartCompany_1880(PublicCompanyI company, int price) { + super(company, price); + // TODO Auto-generated constructor stub + } + + + public void setBuildingRight(PublicCompany_1880 company, String buildingRightString ) { + BitSet buildingRight = new BitSet(5); + + if (buildingRightString == "A") { + buildingRight.set(0); + } else if (buildingRightString == "B") { + buildingRight.set(1); + } else if (buildingRightString == "C") { + buildingRight.set(2); + } else if (buildingRightString == "D") { + buildingRight.set(3); + } else if (buildingRightString == "A+B") { + buildingRight.set(0); + buildingRight.set(1); + } else if (buildingRightString == "A+B+C") { + buildingRight.set(0); + buildingRight.set(1); + buildingRight.set(2); + } else if (buildingRightString == "B+C") { + buildingRight.set(1); + buildingRight.set(2); + } else if (buildingRightString == "B+C+D") { + buildingRight.set(1); + buildingRight.set(2); + buildingRight.set(3); + } else if (buildingRightString == "C+D") { + buildingRight.set(2); + buildingRight.set(3); + } + + company.setBuildingRights( buildingRight); + company.setRight("BuildingRight", buildingRightString); + } + + + public void setPresidentPercentage(PublicCompany_1880 company, int percentage) { + company.setPresidentShares(percentage); + } + + /* (non-Javadoc) + * @see rails.game.action.StartCompany#getStartPrices() + */ + @Override + public int[] getStartPrices() { + // TODO Auto-generated method stub + return super.getStartPrices(); + } + + /* (non-Javadoc) + * @see rails.game.action.StartCompany#setStartPrice(int) + */ + @Override + public void setStartPrice(int startPrice) { + // TODO Auto-generated method stub + price = startPrice; + StockSpaceI parPrice=gameManager.getStockMarket().getStartSpace(startPrice); + this.getCompany().setParSpace(parPrice); + ((StockMarket_1880) gameManager.getStockMarket()).setParSlot(startPrice); + } + +} diff --git a/rails/ui/swing/gamespecific/_1880/GameUIManager_1880.java b/rails/ui/swing/gamespecific/_1880/GameUIManager_1880.java new file mode 100644 index 0000000..279e534 --- /dev/null +++ b/rails/ui/swing/gamespecific/_1880/GameUIManager_1880.java @@ -0,0 +1,152 @@ +/** + * + */ +package rails.ui.swing.gamespecific._1880; + + + +import rails.ui.swing.GameUIManager; +import rails.common.LocalText; +import rails.game.action.PossibleORAction; +import rails.game.specific._1880.OperatingRound_1880; +import rails.game.specific._1880.PublicCompany_1880; +import rails.game.specific._1880.StartCompany_1880; +import rails.ui.swing.elements.NonModalDialog; +import rails.ui.swing.elements.RadioButtonDialog; + +/** + * @author Martin Brumm + * @date 5-2-2012 + * + */ +public class GameUIManager_1880 extends GameUIManager { + public static final String COMPANY_SELECT_BUILDING_RIGHT = "SelectBuildingRight"; + public static final String COMPANY_SELECT_PRESIDENT_SHARE_SIZE = "SelectPresidentShareSize"; + public static final String COMPANY_START_PRICE_DIALOG = "CompanyStartPrice"; + public static final String Investor_has_Destination = "Investor_at_Destination"; + + + @Override + public void dialogActionPerformed () { + + String key = ""; + String[] brights; + String[] brights2= {"A", "B", "C","D", "A+B", "A+B+C", "B+C", "B+C+D", "C+D"}; + String[] presidentShareSizes; + if (currentDialog instanceof NonModalDialog) key = ((NonModalDialog) currentDialog).getKey(); + + // Check for the dialogs that are postprocessed in this class. +/* + * The mechanismn for starting a company and getting the necessary decisions by a player + * is implemented with the following steps + * Player chooses Startprice + * | + * Player chooses President share percentage (20, 30 or 40 percent share) + * | + * Player chooses Building Right based on percentage of president share + * + * - 20 percent share will allow to choose from all Building Rights (A+B+C, B+C+D and 2 Phase and single Phase rights) + * - 30 percent share will allow to choose from 2 Phase Building Rights (A+B, B+C, C+D and all single Phase rights) + * - 40 percent share will limit the player to a building right for one Phase (A, B, C, D) + */ + + if (COMPANY_SELECT_PRESIDENT_SHARE_SIZE.equals(key)) { + + RadioButtonDialog dialog = (RadioButtonDialog) currentDialog; + StartCompany_1880 action = (StartCompany_1880) currentDialogAction; + + int index = dialog.getSelectedOption(); + if (index < 0) { + currentDialogAction = null; + return; + } + + if (index > 1) { // 40 Percent Share has been chosen + action.setPresidentPercentage((PublicCompany_1880) action.getCompany(), 40); + brights= new String[] {"A", "B", "C", "D"}; + + } else if ( index == 1) { + action.setPresidentPercentage((PublicCompany_1880) action.getCompany(), 30); + brights= new String[] {"A", "B", "C", "D", "A+B", "B+C", "C+D"}; + } else { // 20 Percent Share chosen + action.setPresidentPercentage((PublicCompany_1880) action.getCompany(), 20); + brights= new String[] {"A", "B", "C","D", "A+B", "A+B+C", "B+C", "B+C+D", "C+D"}; + } + + dialog = new RadioButtonDialog (COMPANY_SELECT_BUILDING_RIGHT, + this, + statusWindow, + LocalText.getText("PleaseSelect"), + LocalText.getText( + "WhichBuildingRight",action.getPlayerName(), + action.getCompanyName()), + brights, -1); + setCurrentDialog(dialog, action); + statusWindow.disableButtons(); + return; + + } else if (COMPANY_SELECT_BUILDING_RIGHT.equals(key)) { + + RadioButtonDialog dialog = (RadioButtonDialog) currentDialog; + StartCompany_1880 action = (StartCompany_1880) currentDialogAction; + + int index = dialog.getSelectedOption(); + if (index < 0) { + currentDialogAction = null; + return; + } + action.setBuildingRight((PublicCompany_1880) action.getCompany(), brights2[index]); + + } else if (COMPANY_START_PRICE_DIALOG.equals(key) + && currentDialogAction instanceof StartCompany_1880) { + + // A start price has been selected (or not) for a stating major company. + RadioButtonDialog dialog = (RadioButtonDialog) currentDialog; + StartCompany_1880 action = (StartCompany_1880) currentDialogAction; + + int index = dialog.getSelectedOption(); + if (index < 0) { + currentDialogAction = null; + return; + } + action.setStartPrice(action.getStartPrices()[index]); + + /* Set up another dialog for the next step + * need to setup Options based on the Presidents Certificate Size... + * The player should only get valid percentages presented to him for selection + * This leads to the check what amount of cash does the player have + */ + + int freePlayerCash = gameManager.getCurrentPlayer().getFreeCash(); + if (freePlayerCash >= (action.getStartPrices()[index]*4)) { //enough Cash for 40 Percent + presidentShareSizes = new String[] {"20 Percent", "30 Percent", "40 Percent"}; + } else if (freePlayerCash >= (action.getStartPrices()[index]*3)) { //enough Cash for 30 Percent + presidentShareSizes = new String[] {"20 Percent", "30 Percent"}; + } else { //enough Cash only for 20 Percent + presidentShareSizes = new String[] {"20 Percent"}; + } + dialog = new RadioButtonDialog (COMPANY_SELECT_PRESIDENT_SHARE_SIZE, + this, + statusWindow, + LocalText.getText("PleaseSelect"), + LocalText.getText( + "WhichPresidentShareSize", + action.getPlayerName(), + action.getCompanyName()), + presidentShareSizes, -1); + setCurrentDialog(dialog, action); + statusWindow.disableButtons(); + return; + } else { + // Current dialog not found yet, try the superclass. + super.dialogActionPerformed(false); + return; + } + + // Dialog action found and processed, let the superclass initiate processing. + super.dialogActionPerformed(true); + + } + +} + commit 3b3c740acc6c0113e53b170d6ca7b8bf268e7484 Author: Erik Vos <eri...@xs...> Date: Wed Mar 14 11:34:59 2012 +0100 Allow 'pic' attribute in Hex definition in Map.xml. To define per-hex alternative pictures, as needed in 1880. diff --git a/data/1830/Map.xml b/data/1830/Map.xml index 9a286e8..ecc6404 100644 --- a/data/1830/Map.xml +++ b/data/1830/Map.xml @@ -113,7 +113,7 @@ <Hex name="H12" tile="-101" city="Altoona" runThrough="tokenOnly"/> </IfOption> <IfOption name="Variant" value="Coalfields,Reading,Coalfields&Reading"> - <Hex name="H12" tile="-30003" pic="-30002" city="Altoona"> + <Hex name="H12" tile="-30003" city="Altoona"> <Access runThrough="tokenOnly"/> </Hex> </IfOption> @@ -121,7 +121,7 @@ <Hex name="H14" tile="0"/> </IfOption> <IfOption name="Variant" value="Reading,Coalfields&Reading"> - <Hex name="H14" tile="-30007" pic="-30006" city="Reading"> + <Hex name="H14" tile="-30007" city="Reading"> <Access runThrough="tokenOnly"/> </Hex> </IfOption> diff --git a/rails/game/MapHex.java b/rails/game/MapHex.java index 0e1af5c..f6225cf 100644 --- a/rails/game/MapHex.java +++ b/rails/game/MapHex.java @@ -64,6 +64,7 @@ StationHolder, TokenHolder { protected int number; protected String tileFileName; protected int preprintedTileId; + protected int preprintedPictureId = 0; protected TileI currentTile; protected int currentTileRotation; protected int preprintedTileRotation; @@ -229,6 +230,7 @@ StationHolder, TokenHolder { } preprintedTileId = tag.getAttributeAsInteger("tile", -999); + preprintedPictureId = tag.getAttributeAsInteger("pic", 0); preprintedTileRotation = tag.getAttributeAsInteger("orientation", 0); currentTileRotation = preprintedTileRotation; @@ -466,6 +468,20 @@ StationHolder, TokenHolder { return preprintedTileRotation; } + /** Return the current picture ID (i.e. the tile ID to be displayed, rather than used for route determination). + * <p> Usually, the picture ID is equal to the tile ID. Different values may be defined per hex or per tile. + * @return The current picture ID + */ + public int getPictureId () { + if (currentTile.getId() == preprintedTileId && preprintedPictureId != 0) { + return preprintedPictureId; + } else if (currentTile.getPictureId() != 0) { + return currentTile.getPictureId(); + } else { + return currentTile.getId(); + } + } + /** * @return Returns the image file name for the tile. */ diff --git a/rails/ui/swing/hexmap/GUITile.java b/rails/ui/swing/hexmap/GUITile.java index becbe56..f7162f9 100644 --- a/rails/ui/swing/hexmap/GUITile.java +++ b/rails/ui/swing/hexmap/GUITile.java @@ -45,7 +45,7 @@ public class GUITile { public static final double SVG_Y_CENTER_LOC = 0.426; protected static Logger log = - Logger.getLogger(GUITile.class.getPackage().getName()); + Logger.getLogger(GUITile.class.getPackage().getName()); public GUITile(int tileId, GUIHex guiHex) { this.guiHex = guiHex; @@ -53,7 +53,7 @@ public class GUITile { this.hex = (MapHex)guiHex.getModel(); TileManager tileManager = guiHex.getHexMap().orUIManager.getTileManager(); tile = tileManager.getTile(tileId); - picId = tile.getPictureId(); + picId = hex.getPictureId(); if (hex.getTileOrientation() == TileOrientation.EW) { baseRotation = 0.5 * DEG60; @@ -122,7 +122,7 @@ public class GUITile { // these must all be preserved. if (prevTile.hasTracks(prevTileSide)) { List<Track> newTracks = - tile.getTracksPerSide(tempTileSide); + tile.getTracksPerSide(tempTileSide); old: for (Track oldTrack : prevTile.getTracksPerSide(prevTileSide)) { if (oldTrack.getEndPoint(prevTileSide) >= 0) { // Old track ending in another side @@ -143,7 +143,7 @@ public class GUITile { //log.debug("[" + i + "," + j + "] Found " // + oldTrack.getEndPoint(prevTileSide)); oldCities.put(prevTileSide, - oldTrack.getEndPoint(prevTileSide)); + oldTrack.getEndPoint(prevTileSide)); } else { // Downgraded // Assume there are only two exits @@ -153,7 +153,7 @@ public class GUITile { int otherNewEndPoint = newTracks.get(0).getEndPoint(tempTileSide); // Calculate the corresponding old tile side number int otherOldEndPoint = (otherNewEndPoint + tempRot - prevTileRotation + 6) % 6; - // That old tile side must have track too + // That old tile side must have track too if (prevTile.getTracksPerSide(otherOldEndPoint) == null || prevTile.getTracksPerSide(otherOldEndPoint).isEmpty()) { continue rot; @@ -203,7 +203,7 @@ public class GUITile { //log.debug("Check " + newCities.get(kkk) + " & " // + newCities.get(ll)); if (newCities.get(kk) == null - || newCities.get(ll) == null) continue rot; + || newCities.get(ll) == null) continue rot; // If connected cities do not correspond, skip // (this is the "OO brown upgrade get-right" feature) // Only apply this check if the number of cities has not decreased @@ -285,7 +285,7 @@ public class GUITile { AffineTransform af = AffineTransform.getRotateInstance(radians, xCenter, yCenter); af.scale(tileScale, tileScale); - AffineTransformOp aop = new AffineTransformOp(af, + AffineTransformOp aop = new AffineTransformOp(af, getTileRenderingHints()); g2.drawImage(tileImage, aop, x - xCenter, y - yCenter); @@ -294,7 +294,7 @@ public class GUITile { log.error("No image for tile "+tileId+" on hex "+guiHex.getName()); } } - + /** * Provides the image of the tile based on the zoomStep. * tileScale is not considered for producing this image. @@ -314,32 +314,32 @@ public class GUITile { int narrowDiagonal = (int)Math.round( wideDiagonal * 0.5 * Math.sqrt(3) ); int border = wideDiagonal - narrowDiagonal; - + // STEP 2: CENTER TILE IN IMAGE - // apply the bottom border also the left / top / right + // apply the bottom border also the left / top / right //center tile by translation AffineTransform centeringAT = AffineTransform.getTranslateInstance( border, border ); AffineTransformOp centeringATOp = new AffineTransformOp(centeringAT, null); - + //centered tile image create manually since it also needs a border on the right - BufferedImage centeredTileImage = new BufferedImage( + BufferedImage centeredTileImage = new BufferedImage( uncenteredTileImage.getWidth() + border * 2, uncenteredTileImage.getHeight() + border, uncenteredTileImage.getType()); centeringATOp.filter(uncenteredTileImage, centeredTileImage); - + // STEP 3: ROTATE TILE IMAGE // feasible only now since there are enough margins to ensure tile won't exceed bounds double radians = baseRotation + rotation * DEG60; - int xCenter = (int) Math.round(centeredTileImage.getWidth() / 2 ); - int yCenter = (int) Math.round(centeredTileImage.getHeight() / 2 ); + int xCenter = Math.round(centeredTileImage.getWidth() / 2 ); + int yCenter = Math.round(centeredTileImage.getHeight() / 2 ); AffineTransform af = AffineTransform.getRotateInstance(radians, xCenter, yCenter); AffineTransformOp aop = new AffineTransformOp(af, getTileRenderingHints()); - + BufferedImage rotatedTileImage = aop.filter(centeredTileImage, null); // STEP 4: CROP ROTATED TILE IMAGE @@ -357,14 +357,14 @@ public class GUITile { } BufferedImage croppedTileImage = rotatedTileImage.getSubimage( - xCenter - croppedWidth / 2, - yCenter - croppedHeight / 2, + xCenter - croppedWidth / 2, + yCenter - croppedHeight / 2, croppedWidth, croppedHeight ); - + return croppedTileImage; } - + public TileI getTile() { return tile; } |
From: Erik V. <ev...@us...> - 2012-03-13 21:08:07
|
LocalisedText.properties | 5 data/1880/CompanyManager.xml | 54 data/1880/Game.xml | 21 data/1880/Map.xml | 32 data/1880/TileSet.xml | 1 data/1880/Tiles.xml | 2 data/GamesList.xml | 23 rails/game/Company.java | 7 rails/game/CompanyI.java | 4 rails/game/PhaseI.java | 1 rails/game/PublicCompany.java | 7 rails/game/Round.java | 1 rails/game/ShareSellingRound.java | 8 rails/game/Station.java | 1 rails/game/Tile.java | 1 rails/game/TrainManager.java | 2 rails/game/specific/_1880/BuyStartItem_1880.java | 23 rails/game/specific/_1880/GameManager_1880.java | 45 rails/game/specific/_1880/OperatingRound_1880.java | 786 ++++++++--- rails/game/specific/_1880/PublicCompany_1880.java | 201 ++ rails/game/specific/_1880/StartRound_1880.java | 208 ++ rails/game/specific/_1880/StockMarket_1880.java | 158 +- rails/game/specific/_1880/StockRound_1880.java | 359 ++++- rails/ui/swing/RemainingTilesWindow.java | 19 rails/ui/swing/StartRoundWindow.java | 12 rails/ui/swing/gamespecific/_1880/StartRoundWindow_1880.java | 134 + tiles/Tiles.xml | 4 tiles/svg/tile-9021.svg | 84 + tiles/svg/tile-9031.svg | 80 + tiles/svg/tile455.svg | 2 30 files changed, 1908 insertions(+), 377 deletions(-) New commits: commit 3f9305b21a19c4e254bf3552ca4ce1dfb0a16b6a Author: Martin Brumm <Dr....@t-...> Date: Tue Mar 13 22:04:47 2012 +0100 Added a new patch for 1880 by Martin Brumm. Also added the missing tile 455. diff --git a/LocalisedText.properties b/LocalisedText.properties index 059e471..4eb2d0a 100644 --- a/LocalisedText.properties +++ b/LocalisedText.properties @@ -755,12 +755,13 @@ Version=Version VersionOf=version of {0} WantToReplaceToken=Do you want to replace the {0} home token with one of {1}? WarningNeedCash=Warning: {0} will be deducted from the company revenue or from your personal cash -WHICH_BUILDING_RIGHT={0} please choose the Building Rights for {1} +WhichBuildingRight={0} please choose the Building Rights for {1} WHICH_PRICE=Which price? WHICH_PRIVATE=Which Private? WHICH_PRIVATE_PRICE=Buy {0} for which price (valid range {1} to {2})? WHICH_RIGHT=Which Building Right ? -WHICH_START_PRICE={0} please set the start price for {1} +WHICH_START_PRICE={0} please set the start price for {1} +WhichPresidentShareSize={0} please choose the Size of the Presidents share for {1} WhichStation=Which Station? WHICH_TRAIN=Which train WHICH_TRAIN_EXCHANGE_FOR=Which train to exchange for {0} diff --git a/data/1880/CompanyManager.xml b/data/1880/CompanyManager.xml index c4b55f7..b20e346 100644 --- a/data/1880/CompanyManager.xml +++ b/data/1880/CompanyManager.xml @@ -47,17 +47,14 @@ <Company name="WR" longname="Woosong Railway" type="Private" basePrice="5" revenue="0"> - - <!--SpecialProperty condition="ifOwnedByPlayer" Phasenwechsel-Freie Lok --> <ClosingConditions> - <Phase>4</Phase> <SpecialProperties condition="ifExercised"/> </ClosingConditions> </Company> <Company name="KR" longname="Kaiping Railway" type="Private" basePrice="10" revenue="5"> <ClosingConditions> - <Phase>4</Phase> + <Phase>4+4</Phase> </ClosingConditions> </Company> <Company name="YC" longname="Yanda Ferry Company" type="Private" @@ -65,7 +62,7 @@ <SpecialProperties> <SpecialProperty condition="ifOwnedByPlayer" when="revenueStep" class="rails.game.special.LocatedBonus" transfer="toCompany"> - <LocatedBonus name="Ferry" location="F12,F14,I15" value="10"/> + <LocatedBonus name="Ferry" location="F12,F14,I15,J16" value="10"/> </SpecialProperty> </SpecialProperties> </Company> @@ -81,9 +78,9 @@ <Company name="CC" longname="Chinese Rivers Ferry Company" type="Private" basePrice="70" revenue="20"> <SpecialProperties> - <SpecialProperty condition="ifOwnedByPlayer" when="tileLayingStep" + <SpecialProperty condition="ifOwnedByPlayer" when="tileLayingStep" permanent="true" class="rails.game.special.SpecialTileLay"> - <SpecialTileLay location="M15" extra="no" free="yes"/> + <SpecialTileLay location="G1,G3,G5,G11,H4,H10,I9,I7,I5,J2,I1,K1,O1,O3,N4,N6,M7,L8,L10,L12,K13,J14" extra="no" free="yes"/> </SpecialProperty> </SpecialProperties> </Company> @@ -101,78 +98,79 @@ </Company> <Company name="RC" longname="Rocket Company" type="Private" basePrice="70" revenue="0"> - <!-- SpecialProperties--> - <!-- SpecialProperty condition="ifOwnedByPlayer" when="trainBuyingStep" - class="rails.game.special.SpecialTrainBuy"/--> + <SpecialProperties> + <SpecialProperty condition="ifOwnedByPlayer" when="anyTurn" + class="rails.game.specific._1880.SpecialTrainBuy_1880"> + <SpecialTrainBuy_1880 traintype="2,2+2,3,3+3,4" deduction="100%"></SpecialTrainBuy_1880> <!-- Kostenfreie Lok bei Phasenwechsel durch Lokkauf --> - <!-- Can exchange Certificate for actual train in one phase 2,2+3,3,3+3,4 - as soon as train has been bought --> <!-- The train can be moved upon purchase into one company owned by the owner of the certificate --> <!-- Company must have space for the new train, but can hand back an older train to bank (2+2,3,3+3) --> - <!-- /SpecialProperties--> + </SpecialProperty> + </SpecialProperties> <ClosingConditions> - <Phase>5</Phase> + <SpecialProperties condition="ifExercised"/> + <Phase>4+4</Phase> </ClosingConditions> </Company> <Company name="BCR" longname="Baocheng Railway" type="Major" tokens="3" - fgColour="FFFFFF" bgColour="0000FF"> + fgColour="FFFFFF" bgColour="4A4A97"> <Home hex="M3"/> </Company> <Company name="JHA" longname="Jingha Railway" type="Major" tokens="3" - fgColour="FFFFFF" bgColour="FF0000"> + fgColour="000000" bgColour="E78B01"> <Home hex="F8" city="1"/> </Company> <Company name="JHU" longname="Jinghu Railway" type="Major" tokens="3" - fgColour="FFFFFF" bgColour="FF0000"> + fgColour="FFFFFF" bgColour="000000"> <Home hex="F8" city="2"/> </Company> <Company name="JGG" longname="Jingguang Railway" type="Major" tokens="3" - fgColour="FFFFFF" bgColour="FF0000"> + fgColour="FFFFFF" bgColour="92278A"> <Home hex="F8" city="3"/> </Company> <Company name="JLR" longname="Jinglan Railway" type="Major" tokens="3" - fgColour="FFFFFF" bgColour="FF0000"> + fgColour="000000" bgColour="60B495"> <Home hex="F8" city="4"/> </Company> <Company name="BZU" longname="Binzhou Railway" type="Major" tokens="3" - fgColour="FFFFFF" bgColour="FF0000"> + fgColour="000000" bgColour="EFEBC7"> <Home hex="B8"/> </Company> <Company name="LHR" longname="Longhai Railway" type="Major" tokens="3" - fgColour="FFFFFF" bgColour="FF0000"> + fgColour="000000" bgColour="C0B4B7"> <Home hex="J2"/> </Company> <Company name="SCR" longname="Schichang Railway" type="Major" tokens="3" - fgColour="FFFFFF" bgColour="FF0000"> + fgColour="FFFFFF" bgColour="71B622"> <Home hex="N12"/> </Company> <Company name="CKR" longname="Chengkun Railway" type="Major" tokens="3" - fgColour="FFFFFF" bgColour="FF0000"> + fgColour="000000" bgColour="D24026"> <Home hex="O5"/> </Company> <Company name="NXR" longname="Ningxi Railway" type="Major" tokens="3" - fgColour="FFFFFF" bgColour="FF0000"> + fgColour="000000" bgColour="CF8ABC"> <Home hex="J6"/> </Company> <Company name="HKR" longname="Hukun Railway" type="Major" tokens="3" - fgColour="FFFFFF" bgColour="FF0000"> + fgColour="FFFFFF" bgColour="A3CE06"> <Home hex="K15"/> </Company> <Company name="NJR" longname="Najiang Railway" type="Major" tokens="3" - fgColour="FFFFFF" bgColour="FF0000"> + fgColour="000000" bgColour="DBBC04"> <Home hex="K13"/> </Company> <Company name="QSR" longname="Qinshen Railway" type="Major" tokens="3" - fgColour="FFFFFF" bgColour="FF0000"> + fgColour="000000" bgColour="55B3D7"> <Home hex="D12"/> </Company> <Company name="WNR" longname="Wunan Railway" type="Major" tokens="3" - fgColour="FFFFFF" bgColour="FF0000"> + fgColour="000000" bgColour="EDE201"> <Home hex="L10"/> </Company> <Company name="1" longname="Chinese Eastern Railway" type="Minor" price="0" diff --git a/data/1880/Game.xml b/data/1880/Game.xml index 814f622..47f58c5 100644 --- a/data/1880/Game.xml +++ b/data/1880/Game.xml @@ -2,10 +2,8 @@ <ComponentManager> <Component name="GameManager" class="rails.game.specific._1880.GameManager_1880"> <Game name="1880"/> - <GameOption name="RouteAwareness" values="Highlight,Deactivate" - default="Deactivate"/> - <GameOption name="RevenueCalculation" values="Suggest,Deactivate" - default="Deactivate"/> + <GameOption name="RouteAwareness" values="Highlight,Deactivate" default="Highlight"/> + <GameOption name="RevenueCalculation" values="Suggest,Deactivate" default="Suggest"/> <GameOption name="UnlimitedTiles" values="No,Yellow Plain,Yes" default="No"/> <GameOption name="LeaveAuctionOnPass" type="toggle" default="no"/> <GameParameters> @@ -16,13 +14,17 @@ </StockRound> <OperatingRound class="rails.game.specific._1880.OperatingRound_1880"> - <EmergencyTrainBuying mayBuyFromCompany="no"/> + <EmergencyTrainBuying mayBuyFromCompany="yes"/> </OperatingRound> + <ShareSellingRound class="rails.game.specific._1880.ShareSellingRound_1880"> + </ShareSellingRound> </GameParameters> <GuiClasses> <StatusWindow class="rails.ui.swing.StatusWindow"/> <StartRoundWindow class="rails.ui.swing.gamespecific._1880.StartRoundWindow_1880"/> + <GameUIManager + class="rails.ui.swing.gamespecific._1880.GameUIManager_1880"/> </GuiClasses> <EndOfGame/> @@ -70,6 +72,8 @@ <TrainType name="6" majorStops="6" cost="600" quantity="5"> <NewPhase phaseName="6"/> </TrainType> + <TrainType name="2R" majorStops="2" cost="250" quantity="10"> + </TrainType> <TrainType name="6e" majorStops="-1" cost="700" quantity="5"> <NewPhase phaseName="6e"/> </TrainType> @@ -83,7 +87,6 @@ <NewPhase phaseName="8e"/> </TrainType> <!-- majorStops="-1" indicates that this not a normally running train--> - <!-- The e-type trains are express trains that can ignore towns/cities on their way for a maximum payout--> <TrainType name="10" majorStops="10" cost="1000" quantity="-1"> <NewPhase phaseName="8e"/> @@ -158,11 +161,9 @@ </Phase> <Phase name="8e" realName="D3"> </Phase> + </Component> <Component name="RevenueManager" class="rails.algorithms.RevenueManager"> - <Modifier class="rails.game.specific._1880.OffBoardRevenueModifier"/> - <Modifier - class="rails.game.specific._1880.ExpressTrainRevenueModifier"/> + <Modifier class="rails.game.specific._1880.OffBoardRevenueModifier"/> </Component> - </Component> </ComponentManager> \ No newline at end of file diff --git a/data/1880/Map.xml b/data/1880/Map.xml index a5f2214..bea9acd 100644 --- a/data/1880/Map.xml +++ b/data/1880/Map.xml @@ -5,8 +5,8 @@ <Hex name="A9" tile="0" /> <Hex name="A11" tile="0" /> <Hex name="A13" tile="0" /> - <Hex name="A15" tile="-902" orientation="2" value="10,20,30,40" /> - <Hex name="B4" tile="0" /> + <Hex name="A15" tile="-902" orientation="2" value="10,20,30,40" city="Vladivostok"/> + <Hex name="B4" tile="0" cost="30"/> <Hex name="B6" tile="0" /> <Hex name="B8" tile="-10" city="Harbin" /> <Hex name="B10" tile="0" /> @@ -32,12 +32,12 @@ <Hex name="E11" tile="0" impassable="E13" /> <Hex name="E13" tile="-10" city="Dalian" impassable="E11" /> <Hex name="F2" tile="0" /> - <Hex name="F4" tile="-80020" city="Hohhot,Datong" /> + <Hex name="F4" tile="-80020" city="Hohhot, Datong" /> <Hex name="F6" tile="-80001" city="Test8" cost="30" /> <Hex name="F8" tile="-80004" city="Beijing" orientation="5" label="Beijing"/> <Hex name="F10" tile="-10" city="Tianjin" /> - <Hex name="F12" tile="-4008" orientation="1"/> - <Hex name="F14" tile="-4008" orientation="6"/> + <Hex name="F12" tile="-4008" orientation="1" value="-10"/> + <Hex name="F14" tile="-4008" orientation="6" value="-10"/> <Hex name="G1" tile="0" cost="20" /> <Hex name="G3" tile="-10" city="Baotou" cost="20" /> <Hex name="G5" tile="0" cost="50" /> @@ -60,8 +60,8 @@ <Hex name="I9" tile="-80020" city="Kaifeng, Zhengzhou" cost="20" /> <Hex name="I11" tile="0" /> <Hex name="I13" tile="0" /> - <Hex name="I15" tile="-4009" orientation="2"/> - <Hex name="J2" tile="-10" city="Lhasa" cost="50"/> + <Hex name="I15" tile="-4009" orientation="2" value="-10"/> + <Hex name="J2" tile="-10" city="Lanzhou" cost="50"/> <Hex name="J4" tile="0" cost="30"/> <Hex name="J6" tile="-10" cost="30" city="Xian" /> <Hex name="J8" tile="-2" cost="30" /> @@ -76,10 +76,10 @@ <Hex name="K9" tile="0" cost="30" /> <Hex name="K11" tile="0" /> <Hex name="K13" tile="-10" cost="20" city="Nanjing" /> - <Hex name="K15" tile="-10" city="Shanghai" label="S"/> - <Hex name="L2" tile="0" /> - <Hex name="L4" tile="0" /> - <Hex name="L6" tile="0" /> + <Hex name="K15" tile="-80003" city="Shanghai" label="Shanghai"/> + <Hex name="L2" tile="0" cost="40"/> + <Hex name="L4" tile="0" cost="30"/> + <Hex name="L6" tile="0" cost="30"/> <Hex name="L8" tile="0" cost="50"/> <Hex name="L10" tile="-10" city="Wuhan" cost="20"/> <Hex name="L12" tile="-2" cost="20"/> @@ -100,7 +100,9 @@ <Hex name="N10" tile="-80001" city="Test3" /> <Hex name="N12" tile="-80020" city="Changsha, Nanchang" /> <Hex name="N14" tile="0" /> - <Hex name="N16" tile="-903" orientation="2" value="30,30,0,0" city="Taiwan" /> + <Hex name="N16" tile="-903" pic="-9031" orientation="2" value="30,30,0,0" city="Taiwan"> + <Access type="town" score="minor" /> + </Hex> <Hex name="O1" tile="0" cost="60" /> <Hex name="O3" tile="-2" cost="20"/> <Hex name="O5" tile="-10" city="Kunming" /> @@ -115,8 +117,10 @@ <Hex name="P8" tile="-10" city="Nanning" /> <Hex name="P10" tile="-1" cost="30" /> <Hex name="P12" tile="-10" city="Macau" /> - <Hex name="P14" tile="-10" city="Guangzhu" /> + <Hex name="P14" tile="-10" city="Guangzhou" /> <Hex name="Q7" tile="-902" orientation="4" value="30,40,50,60" city="French Indochina" /> - <Hex name="Q13" tile="-902" orientation="4" value="20,30,40,50" city="Haikou" /> + <Hex name="Q13" tile="-902" pic="-9021" orientation="4" value="20,30,40,50" city="Haikou" > + <Access type="town" score="minor"/> + </Hex> <Hex name="Q15" tile="-901" orientation="3" value="20,30,10,70" city="Hongkong"/> </Map> \ No newline at end of file diff --git a/data/1880/TileSet.xml b/data/1880/TileSet.xml index fdcf3a8..c894950 100644 --- a/data/1880/TileSet.xml +++ b/data/1880/TileSet.xml @@ -32,7 +32,6 @@ <Tile id="-901"/> <Tile id="-902"/> <Tile id="-903"/> - <!-- Yellow --> <Tile id="5" quantity="6"> <Upgrade id="14,15,619" /> diff --git a/data/1880/Tiles.xml b/data/1880/Tiles.xml index 6ed5fd7..6dcd97a 100644 --- a/data/1880/Tiles.xml +++ b/data/1880/Tiles.xml @@ -318,7 +318,7 @@ <Track from="city3" gauge="normal" to="side2"/> <Track from="city4" gauge="normal" to="side1"/> <Track from="city5" gauge="normal" to="side0"/> - </Tile><Tile colour="gray" id="455" name="495"> + </Tile><Tile colour="gray" id="455" name="455"> <Station id="city1" position="0" slots="3" type="City" value="50"/> <Track from="city1" gauge="normal" to="side3"/> <Track from="city1" gauge="normal" to="side4"/> diff --git a/data/GamesList.xml b/data/GamesList.xml index 3b6b2c5..488fe3f 100644 --- a/data/GamesList.xml +++ b/data/GamesList.xml @@ -299,14 +299,21 @@ Known Issues: <Players minimum="2" maximum="5" /> </Game> - <Game name="1880"> - <Note>Prototype</Note> - <Description>1880 - China - (c) 2010 Double O Games Mayfair Games, Inc. - Designed by Leonhard Ogler and Helmut Ohley - Limitations: - All aspects not present in 1880 have not been implemented yet.</Description> - <Players minimum="3" maximum="7"/> + <Game name="1880"> + <Note>Almost Playable</Note> + <Description>1880 - China + (c) 2010 Double O Games Mayfair Games, Inc. + Designed by Leonhard Ogler and Helmut Ohley + Limitations: + After the End of the StartRound the Playerorder in the Statuswindow is switched but not the Values + Workaround: Please save the game and reload it to fix this. + Not yet Implemented: + Automatic Deduction of Ferry Fees, please adjust manually or disable automatic RevenueCalculation + The Investor will be closed and the cash will go to the original company, the owner will receive 50 Yuan. + </Description> + <Players minimum="3" maximum="7"/> + <Option name="RouteAwareness" values="Highlight,Deactivate" default="Highlight" /> + <Option name="RevenueCalculation" values="Suggest,Deactivate" default="Suggest" /> </Game> <Game name="18Scan"> <Note>Prototype</Note> diff --git a/rails/game/Company.java b/rails/game/Company.java index 0b2aa2f..cc59d5f 100644 --- a/rails/game/Company.java +++ b/rails/game/Company.java @@ -260,4 +260,11 @@ Cloneable, Comparable<Company> { } return b.toString(); } + + /** + * @param infoText the infoText to set + */ + public void setInfoText(String infoText) { + this.infoText = infoText; + } } diff --git a/rails/game/CompanyI.java b/rails/game/CompanyI.java index 8759c8c..e7646f5 100644 --- a/rails/game/CompanyI.java +++ b/rails/game/CompanyI.java @@ -111,4 +111,8 @@ public interface CompanyI extends ConfigurableComponentI, MoveableHolder { public String toString(); public boolean equals(CompanyI company); + /** + * @param string + */ + public void setInfoText(String string); } diff --git a/rails/game/PhaseI.java b/rails/game/PhaseI.java index d877c4f..e6b548b 100644 --- a/rails/game/PhaseI.java +++ b/rails/game/PhaseI.java @@ -17,6 +17,7 @@ public interface PhaseI extends ConfigurableComponentI { public int getIndex(); public String getName(); + public String getRealName(); public boolean doPrivatesClose(); public void addObjectToClose(Closeable object); diff --git a/rails/game/PublicCompany.java b/rails/game/PublicCompany.java index 3a8377c..48c56ed 100644 --- a/rails/game/PublicCompany.java +++ b/rails/game/PublicCompany.java @@ -2100,4 +2100,11 @@ public class PublicCompany extends Company implements PublicCompanyI { return true; } + /** + * @param destinationHex the destinationHex to set + */ + public void setDestinationHex(MapHex destinationHex) { + this.destinationHex = destinationHex; + } + } diff --git a/rails/game/Round.java b/rails/game/Round.java index 0dcfd98..6e113ae 100644 --- a/rails/game/Round.java +++ b/rails/game/Round.java @@ -13,7 +13,6 @@ import rails.common.*; import rails.game.action.*; import rails.game.move.*; import rails.game.special.SpecialPropertyI; -import rails.game.specific._1880.PublicCompany_1880; import rails.game.state.BooleanState; /** diff --git a/rails/game/ShareSellingRound.java b/rails/game/ShareSellingRound.java index d8a015d..a5e9115 100644 --- a/rails/game/ShareSellingRound.java +++ b/rails/game/ShareSellingRound.java @@ -20,9 +20,9 @@ public class ShareSellingRound extends StockRound { RoundI parentRound; Player sellingPlayer; - IntegerState cashToRaise; - PublicCompanyI cashNeedingCompany; - boolean dumpOtherCompaniesAllowed; + protected IntegerState cashToRaise; + protected PublicCompanyI cashNeedingCompany; + protected boolean dumpOtherCompaniesAllowed; private List<SellShares> sellableShares; @@ -94,7 +94,7 @@ public class ShareSellingRound extends StockRound { * Create a list of certificates that a player may sell in an emergency * share selling round, taking all rules taken into account. */ - private List<SellShares> getSellableShares () { + protected List<SellShares> getSellableShares () { sellableShares = new ArrayList<SellShares> (); diff --git a/rails/game/Station.java b/rails/game/Station.java index 634fe2d..35c1e62 100644 --- a/rails/game/Station.java +++ b/rails/game/Station.java @@ -45,6 +45,7 @@ public class Station { private static final String[] types = { CITY, TOWN, HALT, OFF_MAP_AREA, PORT, PASS, JUNCTION }; private static final List<String> validTypes = Arrays.asList(types); + protected static Logger log = Logger.getLogger(Station.class.getPackage().getName()); diff --git a/rails/game/Tile.java b/rails/game/Tile.java index d36365e..a838490 100644 --- a/rails/game/Tile.java +++ b/rails/game/Tile.java @@ -92,6 +92,7 @@ public class Tile extends ModelObject implements TileI, StationHolder, Comparabl public static final String GREY_COLOUR_NAME = "grey"; public static final int GREY_COLOUR_NUMBER = 4; + protected static final List<String> VALID_COLOUR_NAMES = Arrays.asList(new String[] { RED_COLOUR_NAME, FIXED_COLOUR_NAME, WHITE_COLOUR_NAME, YELLOW_COLOUR_NAME, GREEN_COLOUR_NAME, diff --git a/rails/game/TrainManager.java b/rails/game/TrainManager.java index 2b18b83..cfa95f8 100644 --- a/rails/game/TrainManager.java +++ b/rails/game/TrainManager.java @@ -1 +1 @@ -/* $Header: /Users/blentz/rails_rcs/cvs/18xx/rails/game/TrainManager.java,v 1.28 2010/04/21 21:25:50 evos Exp $ */ package rails.game; import java.util.*; import org.apache.log4j.Logger; import rails.common.LocalText; import rails.common.parser.ConfigurableComponentI; import rails.common.parser.ConfigurationException; import rails.common.parser.Tag; import rails.game.move.ObjectMove; import rails.game.state.BooleanState; import rails.game.state.IntegerState; public class TrainManager implements ConfigurableComponentI { // Static attributes protected List<TrainType> lTrainTypes = new ArrayList<TrainType>(); protected Map<String, TrainType> mTrainTypes = new HashMap<String, TrainType>(); protected List<TrainCertificateType> trainCertTypes = new ArrayList<TrainCertificateType>(); protected Map<String, TrainCertificateType> trainCertTypeMap = new HashMap<String, TrainCertificateType>(); protected Map<String, TrainI> trainMap = new HashMap<String, TrainI>(); protected Map<TrainCertificateType, List<TrainI>> trainsPerCertType = new HashMap<TrainCertificateType, List<TrainI>>(); protected TrainType defaultType = null; // Only required locally and in ChoiceType private boolean removeTrain = false; // Dynamic attributes protected IntegerState newTypeIndex; protected Map<String, Integer> lastIndexPerType = new HashMap<String, Integer>(); protected boolean trainsHaveRusted = false; protected boolean phaseHasChanged = false; protected boolean trainAvailabilityChanged = false; protected List<PublicCompanyI> companiesWithExcessTrains; protected GameManagerI gameManager = null; protected Bank bank = null; /** Required for the sell-train-to-foreigners feature of some games */ protected BooleanState anyTrainBought = new BooleanState ("AnyTrainBought", false); // Triggered phase changes protected Map<TrainCertificateType, Map<Integer, |
From: Erik V. <ev...@us...> - 2012-03-13 14:41:28
|
rails/common/ConfigProfile.java | 115 +++++++++++++++++++--------------------- 1 file changed, 57 insertions(+), 58 deletions(-) New commits: commit 089e86da5284d15b956862b8de9ba9df3ba3b3b3 Author: Erik Vos <eri...@xs...> Date: Tue Mar 13 15:40:04 2012 +0100 Fixed Config.profile.SetParent() so it no longer crashes if parent is null. diff --git a/rails/common/ConfigProfile.java b/rails/common/ConfigProfile.java index c6bcb7d..ca418d3 100644 --- a/rails/common/ConfigProfile.java +++ b/rails/common/ConfigProfile.java @@ -2,10 +2,7 @@ package rails.common; import java.io.File; import java.io.FilenameFilter; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; +import java.util.*; import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOCase; @@ -22,13 +19,13 @@ import rails.util.Util; public final class ConfigProfile implements Comparable<ConfigProfile> { protected static Logger log = - Logger.getLogger(ConfigProfile.class.getPackage().getName()); - + Logger.getLogger(ConfigProfile.class.getPackage().getName()); + // available profile types public enum Type {SYSTEM(0), PREDEFINED(1), USER(2); - private Integer sort; Type(int sort) {this.sort = sort;} + private Integer sort; Type(int sort) {this.sort = sort;} }; - + // Filename extension of profiles public static final String PROFILE_EXTENSION = ".rails_profile"; private static final String PREDEFINED_EXTENSION = ".predefined"; @@ -38,57 +35,57 @@ public final class ConfigProfile implements Comparable<ConfigProfile> { private static final String PROFILE_FOLDER = "profiles/"; // predefined inside jar private static final String PREDEFINED_FOLDER = "data/profiles/"; - + // predefined default profiles private static final String ROOT_PROFILE = "root"; private static final String TEST_PROFILE = "test"; - + // the profile selected at the start ... private static final String STANDARD_PROFILE = "pbem"; // ... unless a cli option has been set private static final String CLI_AND_RECENT_OPTION ="profile"; - - + + // file that stores the list of predefined profiles private static final String LIST_OF_PROFILES = "LIST_OF_PROFILES"; - + // property key of predefined profile in user profile private static final String PARENT_KEY = "profile.parent"; private static final String FINAL_KEY = "profile.final"; // map of all profiles - private static final Map<String, ConfigProfile> profiles = new HashMap<String, ConfigProfile>(); - + private static final Map<String, ConfigProfile> profiles = new HashMap<String, ConfigProfile>(); + // root profile private static ConfigProfile root; - + // profile type private final Type type; - + // profile name private final String name; // profile properties private final Properties properties = new Properties(); - + // profile loaded private boolean loaded = false; - + // profile parent private ConfigProfile parent = null; - + static void loadRoot() { root = new ConfigProfile(Type.SYSTEM, ROOT_PROFILE); root.load(); } - + static ConfigProfile loadTest() { ConfigProfile test = new ConfigProfile(Type.SYSTEM, TEST_PROFILE); test.load(); return test; } - + static void readPredefined() { Properties list = new Properties(); String filePath = PREDEFINED_FOLDER + LIST_OF_PROFILES; @@ -97,7 +94,7 @@ public final class ConfigProfile implements Comparable<ConfigProfile> { new ConfigProfile(Type.PREDEFINED, name); } } - + static void readUser() { File userFolder = SystemOS.get().getConfigurationFolder(PROFILE_FOLDER, false); if (userFolder == null) return; @@ -106,30 +103,30 @@ public final class ConfigProfile implements Comparable<ConfigProfile> { new ConfigProfile(Type.USER, FilenameUtils.getBaseName(fileName)); } } - + static ConfigProfile getStartProfile() { // first checks cli String profile = System.getProperty(CLI_AND_RECENT_OPTION); if (Util.hasValue(profile) && profiles.containsKey(profile)) { return profiles.get(profile); - } + } // second check recent profile = Config.getRecent(CLI_AND_RECENT_OPTION); if (Util.hasValue(profile) && profiles.containsKey(profile)) { return profiles.get(profile); - } + } // third return standard profile return profiles.get(STANDARD_PROFILE); } - + static ConfigProfile getProfile(String name) { return profiles.get(name); } - + static Collection<ConfigProfile> getProfiles() { return profiles.values(); } - + private ConfigProfile(Type type, String name) { this.type = type; this.name = name; @@ -137,34 +134,36 @@ public final class ConfigProfile implements Comparable<ConfigProfile> { profiles.put(name, this); } } - + public Type getType() { return type; } - + public String getName() { return name; } - + boolean isLoaded() { return loaded; } - + boolean isFinal() { if (!loaded && type == Type.USER) return true; - + if (Util.hasValue(properties.getProperty(FINAL_KEY))) { return Util.parseBoolean(properties.getProperty(FINAL_KEY)); } return false; } - + ConfigProfile setParent(ConfigProfile parent) { - this.parent = parent; - properties.setProperty(PARENT_KEY, parent.getName()); + if (parent != null) { + this.parent = parent; + properties.setProperty(PARENT_KEY, parent.getName()); + } return this; } - + private ConfigProfile setParent(String name) { return setParent(profiles.get(name)); } @@ -172,7 +171,7 @@ public final class ConfigProfile implements Comparable<ConfigProfile> { ConfigProfile getParent() { return parent; } - + String getProperty(String key) { if (this == root || properties.containsKey(key)) { return properties.getProperty(key); @@ -180,7 +179,7 @@ public final class ConfigProfile implements Comparable<ConfigProfile> { return parent.getProperty(key); } } - + void setProperty(String key, String value) { if (!parent.getProperty(key).equals(value)) { properties.setProperty(key, value); @@ -188,8 +187,8 @@ public final class ConfigProfile implements Comparable<ConfigProfile> { properties.remove(key); } } - - + + void makeActive(){ // check if is already loaded if (!isLoaded()) { @@ -201,13 +200,13 @@ public final class ConfigProfile implements Comparable<ConfigProfile> { ConfigProfile deriveUserProfile(String name) { ConfigProfile newProfile = new ConfigProfile(Type.USER, name); - + ConfigProfile reference; if (isFinal()) { // set reference for final to the own parent reference = parent; - } else { - // otherwise to this + } else { + // otherwise to this reference = this; } newProfile.setParent(reference); @@ -218,16 +217,16 @@ public final class ConfigProfile implements Comparable<ConfigProfile> { newProfile.setProperty(key, properties.getProperty(key)); } } - + return newProfile; } - + boolean load() { // loaded is set independent of success loaded = true; // ... the same for clearing the current selection properties.clear(); - + // loading boolean result; if (type == Type.USER) { @@ -244,21 +243,21 @@ public final class ConfigProfile implements Comparable<ConfigProfile> { if (parent == null) { setParent(root); } - - // set save directory to the working directory for predefined values + + // set save directory to the working directory for predefined values // TODO: This is a hack as workaround to be replaced in the future if (type == Type.PREDEFINED && !Util.hasValue(properties.getProperty("save.directory"))) { properties.put("save.directory", System.getProperty("user.dir")); } - + // check if parent has been loaded, otherwise load parent if (!parent.isLoaded()) { result = result && parent.load(); } - + return result; } - + private boolean loadUser() { File folder = SystemOS.get().getConfigurationFolder(PROFILE_FOLDER, false); if (folder == null) { @@ -266,9 +265,9 @@ public final class ConfigProfile implements Comparable<ConfigProfile> { } else { File profile = new File(folder, name + PROFILE_EXTENSION); return Util.loadProperties(properties, profile); - } + } } - + private boolean loadResource(){ String filePath = null; switch(type) { @@ -281,13 +280,13 @@ public final class ConfigProfile implements Comparable<ConfigProfile> { } return Util.loadPropertiesFromResource(properties, filePath); } - + boolean store() { if (type != Type.USER) return false; loaded = true; File folder = SystemOS.get().getConfigurationFolder(PROFILE_FOLDER, true); if (folder == null) { - return false; + return false; } else { File profile = new File(folder, name + PROFILE_EXTENSION); return Util.storeProperties(properties, profile); @@ -295,7 +294,7 @@ public final class ConfigProfile implements Comparable<ConfigProfile> { } private int compare(ConfigProfile a, ConfigProfile b) { - if (a.type.sort != b.type.sort) { + if (a.type.sort != b.type.sort) { return a.type.sort.compareTo(b.type.sort); } else { return a.getName().compareTo(b.getName()); |
From: Stefan F. <ste...@us...> - 2012-03-06 22:20:26
|
buildRails.xml | 19 +++++++------ rails/util/Util.java | 2 - readme.txt | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++ version.number | 2 - 4 files changed, 87 insertions(+), 10 deletions(-) New commits: commit 576127100fc7d21af7640e3da872184b021cc9dd Author: Stefan Frey <ste...@we...> Date: Tue Mar 6 23:20:02 2012 +0100 fixed typo in railsBuild.xml that causes defect jar manifest diff --git a/buildRails.xml b/buildRails.xml index cc81b7a..aca719d 100644 --- a/buildRails.xml +++ b/buildRails.xml @@ -139,7 +139,7 @@ ./lib/batik-1.7/lib/batik-anim.jar ./lib/df_1.1.0/dockingFramesCommon.jar ./lib/df_1.1.0/dockingFramesCore.jar - -/lib/commons-io-2.1/commons-io-2.1.jar"/> + ./lib/commons-io-2.1/commons-io-2.1.jar"/> </manifest> </jar> <delete dir="jar"/> commit 0c43942fa04877a7de713cf2c632ea3e971fbfc3 Author: Stefan Frey <ste...@we...> Date: Tue Mar 6 14:23:47 2012 +0100 prepared for release 1.7.0 diff --git a/buildRails.xml b/buildRails.xml index 9878e88..cc81b7a 100644 --- a/buildRails.xml +++ b/buildRails.xml @@ -44,7 +44,8 @@ <exclude name="rails-*-${version}/**"/> <exclude name="rails.bat"/> <exclude name="rails.sh"/> - <exclude name="version.number" /> + <exclude name="version.number"/> + <exclude name="readme.txt"/> <exclude name=".project"/> <exclude name=".classpath"/> <exclude name=".git/**"/> @@ -67,10 +68,7 @@ <include name="log4j-1.2/log4j-1.2.14.jar" /> <include name="jgrapht-0.7.3/jgrapht-jdk1.5.jar" /> <include name="jgraph5/jgraph.jar" /> - <include name="junit-4.8.2/junit.jar" /> <include name="JLayer1.0.1/jl1.0.1.jar"/> - <include name="lib/df_1.1.0/dockingFramesCommon.jar"/> - <include name="lib/df_1.1.0/dockingFramesCore.jar"/> <include name="batik-1.7/lib/batik-transcoder.jar" /> <include name="batik-1.7/lib/batik-dom.jar" /> <include name="batik-1.7/lib/batik-swing.jar" /> @@ -90,6 +88,9 @@ <include name="batik-1.7/lib/xerces_2_5_0.jar" /> <include name="batik-1.7/lib/xml-apis-ext.jar" /> <include name="batik-1.7/lib/batik-anim.jar" /> + <include name="df_1.1.0/dockingFramesCommon.jar"/> + <include name="df_1.1.0/dockingFramesCore.jar"/> + <include name="commons-io-2.1/commons-io-2.1.jar"/> </fileset> </copy> <copy includeemptydirs="false" todir="rails-${version}"> @@ -97,6 +98,7 @@ <fileset dir="."> <include name="LICENSE"/> <include name="README"/> + <include name="readme.txt"/> <include name="AUTHORS"/> <include name="rails.bat"/> <include name="rails.sh"/> @@ -116,8 +118,6 @@ ./lib/jgraph5/jgraph.jar ./lib/junit-4.8.2/junit.jar ./lib/JLayer1.0.1/jl1.0.1.jar - ./lib/df_1.1.0/dockingFramesCommon.jar - ./lib/df_1.1.0/dockingFramesCore.jar ./lib/batik-1.7/lib/batik-transcoder.jar ./lib/batik-1.7/lib/batik-dom.jar ./lib/batik-1.7/lib/batik-swing.jar @@ -136,7 +136,10 @@ ./lib/batik-1.7/lib/js.jar ./lib/batik-1.7/lib/xerces_2_5_0.jar ./lib/batik-1.7/lib/xml-apis-ext.jar - ./lib/batik-1.7/lib/batik-anim.jar"/> + ./lib/batik-1.7/lib/batik-anim.jar + ./lib/df_1.1.0/dockingFramesCommon.jar + ./lib/df_1.1.0/dockingFramesCore.jar + -/lib/commons-io-2.1/commons-io-2.1.jar"/> </manifest> </jar> <delete dir="jar"/> @@ -161,7 +164,7 @@ <arg value="rails-${version}.tar.gz"/> <arg value="${sf.user},rails@${sf.uri}${sf.filedir}${version}/"/> </exec> - <exec executable="scp" dir="../../rails-${version}" failonerror="true"> + <exec executable="scp" dir="./" failonerror="true"> <arg value="readme.txt"/> <arg value="${sf.user},rails@${sf.uri}${sf.filedir}${version}/"/> </exec> diff --git a/rails/util/Util.java b/rails/util/Util.java index 813db49..e514969 100644 --- a/rails/util/Util.java +++ b/rails/util/Util.java @@ -16,7 +16,7 @@ import rails.game.move.MoveableHolder; public final class Util { - protected static Logger log; + protected static Logger log = Logger.getLogger(Util.class.getPackage().getName());; /** * No-args private constructor, to prevent (meaningless) construction of one diff --git a/readme.txt b/readme.txt new file mode 100644 index 0000000..0bac2d1 --- /dev/null +++ b/readme.txt @@ -0,0 +1,74 @@ +Rails release 1.7.0: + +A new release for Rails 1.x series + +This release celebrates many improvements to the UI due to the +work of Frederick Weld. + +Contributors: Erik Vos, Frederick Weld, Martin Brumm, Stefan Frey + +Includes all previously reported bug fixes of the 1.6.x branch. + +Please be aware that this release contains many changes, so bugs are more likely. +Any feedback is welcome. + +Many of the included changes are NOT activated by default: Either switch them off +using the configuration dialog or use one of the new predefined profiles: + +prettyUI --> all UI changes except docking activated +ORdocking --> only activates the docking framework +(currently only available for the OR window) + +Note: To show a background map, the option has to be switched on in Configuration => Map/Report => Display background map. +Background maps are only available for 1856, 1889, 18EU, 18GA (incl. Cotton Port) and 18AL so far. + +The following are the major changes by topic: + +General UI improvements: +* Interactive highlighting of hexes +* Enhanced highlighting of active table cells during Operating Round +* Adaptive rendering of token labels +* Lay Tile: Invalid tile lays are displayed (incl. the reason for +not being valid) +* Support for icons +* Splash screen with improvement startup behavior + +Added UI options: +* Map / Zoom Fit Option: Fit-to-window and more +* Map / Display Routes of Active Company +* Map / Highlight company locations +* Appearance / Display borders in grid layout +* Windows / Flexible panels for operating round: +Applies a docking framework to Operating Round Window + +Added Music/Sound Effects options (mp3 only): +* Music: Background music can be specified per round-type and phase +* Sound Effects: Sound effects can be associated to more than 20 game events +* Includes support of "intelligent" effects (eg., revenue +sound as in RailroadTycoon1) +* No music/sound files are provided by Rails + +Rails configuration: +* Added support for OS dependent centralized rails file storage +(UNIX: ~/rails, Windows: %APPDIR, MacOS: ~/Library/Preferences/net.sourceforge.rails) +* New configuration profile system based on profile hierachy +* Several predefined profiles can be distributed + +Further changes: +* Added StatusWindow File menu action to dump the (transposed) contents into a csv file +* Several changes to use non-modal dialogs +* Several updates to 1880 development +* Added user-friendly network info including keyboard shortcut +* Added highlighting of private companies' hexes triggered by mouse-over +* Added invalid tile lays to upgrade panel (grayed out & reason) +* Added option to play 1856 as a 2-player game. + + +Further bug fixes: +* Fix for 1835 bug: BY presidency not transferred during start round. +* Always address the company president when a home token must be relaid. +* Fixed 'Load Recent' by running it in a separate thread. +* Fixed the glitch of initially displaying map images in the wrong scale +* Fixed 1856 background map's mini-map (Windsor area) +* Added precise sizing and positioning of token labels + diff --git a/version.number b/version.number index 79c0ece..59d7603 100644 --- a/version.number +++ b/version.number @@ -1,5 +1,5 @@ #Property file that contains version number and the develop indicator -version=1.6.0 +version=1.7.0 # the following string "@DEVELOP@ is replaced by an empty string in the release version # this is done automatically by ant develop=@DEVELOP@ \ No newline at end of file |
From: Stefan F. <ste...@us...> - 2012-03-06 15:04:43
|
Tag 'v1.7.0' created by Stefan Frey <ste...@we...> at 2012-03-06 15:03 +0000 version 1.7.0 Changes since v1.5.0-224: --- 0 files changed --- |
From: Stefan F. <ste...@us...> - 2012-03-06 14:17:14
|
buildRails.xml | 14 ++++++++----- rails/common/ConfigManager.java | 6 ++--- rails/common/ConfigProfile.java | 43 +++------------------------------------- rails/util/Util.java | 42 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 58 insertions(+), 47 deletions(-) New commits: commit 2633abcb7e2722e82c0a0822d148d299c893650e Author: Stefan Frey <ste...@we...> Date: Tue Mar 6 15:16:52 2012 +0100 Updated mechanism for version.number diff --git a/buildRails.xml b/buildRails.xml index 07b6d96..9878e88 100644 --- a/buildRails.xml +++ b/buildRails.xml @@ -13,11 +13,8 @@ <!-- Define a filter to substitute version number --> <filterset id="versionFilter"> - <filter token="VERSION" value="${version}"/> - </filterset> - <!-- Define a filter to substitute develop tag to version number --> - <filterset id="developFilter"> - <filter token="DEVELOP" value=""/> + <filter token="VERSION" value="${version}"/> + <filter token="DEVELOP" value=""/> </filterset> <!-- Clean the current release --> @@ -47,6 +44,7 @@ <exclude name="rails-*-${version}/**"/> <exclude name="rails.bat"/> <exclude name="rails.sh"/> + <exclude name="version.number" /> <exclude name=".project"/> <exclude name=".classpath"/> <exclude name=".git/**"/> @@ -57,6 +55,12 @@ <exclude name="**/rails-${version}.jar"/> </fileset> </copy> + <copy todir="jar"> + <filterset refid="versionFilter"/> + <fileset dir="."> + <include name="version.number" /> + </fileset> + </copy> <mkdir dir="rails-${version}"/> <copy includeemptydirs="false" todir="rails-${version}/lib"> <fileset dir="./lib"> diff --git a/rails/common/ConfigManager.java b/rails/common/ConfigManager.java index ca4f7c9..e328aad 100644 --- a/rails/common/ConfigManager.java +++ b/rails/common/ConfigManager.java @@ -152,7 +152,7 @@ public class ConfigManager implements ConfigurableComponentI { // load recent data File recentFile = new File(SystemOS.get().getConfigurationFolder(false), RECENT_FILE); - ConfigProfile.loadProperties(recentData, recentFile.getAbsolutePath(), false); + Util.loadProperties(recentData, recentFile); // define profiles ConfigProfile.readPredefined(); @@ -177,7 +177,7 @@ public class ConfigManager implements ConfigurableComponentI { // TODO: Check if this is the right place for this /* Load version number and develop flag */ Properties versionNumber = new Properties(); - ConfigProfile.loadProperties(versionNumber, "version.number", true); + Util.loadPropertiesFromResource(versionNumber, "version.number"); String version = versionNumber.getProperty("version"); if (Util.hasValue("version")) { @@ -292,7 +292,7 @@ public class ConfigManager implements ConfigurableComponentI { recentData.setProperty(key, value); } File recentFile = new File(SystemOS.get().getConfigurationFolder(true), RECENT_FILE); - return ConfigProfile.storeProperties(recentData, recentFile); + return Util.storeProperties(recentData, recentFile); } // nothing has changed return true; diff --git a/rails/common/ConfigProfile.java b/rails/common/ConfigProfile.java index 1fed682..c6bcb7d 100644 --- a/rails/common/ConfigProfile.java +++ b/rails/common/ConfigProfile.java @@ -1,11 +1,7 @@ package rails.common; import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; import java.io.FilenameFilter; -import java.io.IOException; -import java.io.InputStream; import java.util.Collection; import java.util.HashMap; import java.util.Map; @@ -96,7 +92,7 @@ public final class ConfigProfile implements Comparable<ConfigProfile> { static void readPredefined() { Properties list = new Properties(); String filePath = PREDEFINED_FOLDER + LIST_OF_PROFILES; - loadProperties(list, filePath, true); + Util.loadPropertiesFromResource(list, filePath); for (String name:list.stringPropertyNames()) { new ConfigProfile(Type.PREDEFINED, name); } @@ -269,7 +265,7 @@ public final class ConfigProfile implements Comparable<ConfigProfile> { return false; } else { File profile = new File(folder, name + PROFILE_EXTENSION); - return loadProperties(properties, profile.getAbsolutePath(), false); + return Util.loadProperties(properties, profile); } } @@ -283,7 +279,7 @@ public final class ConfigProfile implements Comparable<ConfigProfile> { filePath = PREDEFINED_FOLDER + name + PREDEFINED_EXTENSION ; break; } - return loadProperties(properties, filePath, true); + return Util.loadPropertiesFromResource(properties, filePath); } boolean store() { @@ -294,41 +290,10 @@ public final class ConfigProfile implements Comparable<ConfigProfile> { return false; } else { File profile = new File(folder, name + PROFILE_EXTENSION); - return storeProperties(properties, profile); + return Util.storeProperties(properties, profile); } } - static boolean loadProperties(Properties properties, String filePath, boolean resource) { - try { - log.info("Loading properties from file " + filePath); - InputStream inFile; - if (resource) { - inFile = ConfigProfile.class.getClassLoader().getResourceAsStream(filePath); - } else { - inFile = new FileInputStream(filePath); - } - properties.load(inFile); - } catch (Exception e) { - log.error(e + " whilst loading properties file " - + filePath, e); - return false; - } - return true; - } - - static boolean storeProperties(Properties properties, File file) { - boolean result = true; - try { - properties.store(new FileOutputStream(file), "Automatically generated, do not edit"); - log.info("Storing properties to file " + file.getAbsolutePath()); - } catch (IOException e) { - log.error(e + " whilst storing properties file " - + file.getAbsolutePath()); - result = false; - } - return result; - } - private int compare(ConfigProfile a, ConfigProfile b) { if (a.type.sort != b.type.sort) { return a.type.sort.compareTo(b.type.sort); diff --git a/rails/util/Util.java b/rails/util/Util.java index 25c716a..813db49 100644 --- a/rails/util/Util.java +++ b/rails/util/Util.java @@ -5,9 +5,11 @@ import java.awt.Color; import java.io.*; import java.util.ArrayList; import java.util.List; +import java.util.Properties; import org.apache.log4j.Logger; +import rails.common.ConfigProfile; import rails.common.parser.ConfigurationException; import rails.game.move.Moveable; import rails.game.move.MoveableHolder; @@ -226,4 +228,44 @@ public final class Util { return null; } } + + public static boolean loadProperties(Properties properties, File file) { + try { + log.info("Loading properties from file " + file); + InputStream inFile = new FileInputStream(file); + properties.load(inFile); + } catch (Exception e) { + log.error(e + " whilst loading properties file " + + file, e); + return false; + } + return true; + } + + public static boolean loadPropertiesFromResource(Properties properties, String resourcePath) { + try { + log.info("Loading properties from resource " + resourcePath); + InputStream inFile; + inFile = ConfigProfile.class.getClassLoader().getResourceAsStream(resourcePath); + properties.load(inFile); + } catch (Exception e) { + log.error(e + " whilst loading properties file from resource at " + + resourcePath, e); + return false; + } + return true; + } + + public static boolean storeProperties(Properties properties, File file) { + boolean result = true; + try { + properties.store(new FileOutputStream(file), "Automatically generated, do not edit"); + log.info("Storing properties to file " + file.getAbsolutePath()); + } catch (IOException e) { + log.error(e + " whilst storing properties file " + + file.getAbsolutePath()); + result = false; + } + return result; + } } |
From: Stefan F. <ste...@us...> - 2012-03-04 07:44:58
|
rails/common/Config.java | 10 +++++ rails/common/ConfigManager.java | 66 +++++++++++++++++++++++++++++++-------- rails/common/ConfigProfile.java | 63 ++++++++++++++++++++++++++++--------- rails/ui/swing/ConfigWindow.java | 3 - rails/util/SystemOS.java | 33 ++++++++++++++++--- 5 files changed, 141 insertions(+), 34 deletions(-) New commits: commit f8a91a293dd23a4e5c763346a9c96b0b6ab4dd62 Author: Stefan Frey <ste...@we...> Date: Sun Mar 4 08:43:31 2012 +0100 Added recent file mechanism Added sorting to profile selection diff --git a/rails/common/Config.java b/rails/common/Config.java index bce5142..30af858 100644 --- a/rails/common/Config.java +++ b/rails/common/Config.java @@ -4,7 +4,7 @@ import rails.game.GameManager; import rails.util.Util; /** - * Proxy class to the ConfigManager + * Proxy class to the ConfigManager */ public class Config { @@ -42,6 +42,14 @@ public class Config { return getSpecific(key, GameManager.getInstance().getGameName()); } + public static String getRecent(String key) { + return ConfigManager.getInstance().getRecent(key); + } + public static boolean storeRecent(String key, String value) { + return ConfigManager.getInstance().storeRecent(key, value); + } } + + diff --git a/rails/common/ConfigManager.java b/rails/common/ConfigManager.java index c2420c9..ca4f7c9 100644 --- a/rails/common/ConfigManager.java +++ b/rails/common/ConfigManager.java @@ -1,11 +1,12 @@ package rails.common; +import java.io.File; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; -import java.util.Set; import org.apache.log4j.Logger; @@ -15,6 +16,7 @@ import rails.common.parser.ConfigurationException; import rails.common.parser.Tag; import rails.game.Game; import rails.game.GameManagerI; +import rails.util.SystemOS; import rails.util.Util; /** @@ -42,6 +44,9 @@ public class ConfigManager implements ConfigurableComponentI { private static final String SECTION_TAG = "Section"; private static final String ITEM_TAG = "Property"; + // Recent property file + private static final String RECENT_FILE = "rails.recent"; + // singleton configuration for ConfigManager private static final ConfigManager instance = new ConfigManager(); @@ -50,6 +55,9 @@ public class ConfigManager implements ConfigurableComponentI { // configuration items: replace with Multimap in Rails 2.0 private final Map<String, List<ConfigItem>> configSections = new HashMap<String, List<ConfigItem>>(); + // recent data + private final Properties recentData = new Properties(); + // profile storage private ConfigProfile activeProfile; @@ -142,13 +150,19 @@ public class ConfigManager implements ConfigurableComponentI { private void init() { + // load recent data + File recentFile = new File(SystemOS.get().getConfigurationFolder(false), RECENT_FILE); + ConfigProfile.loadProperties(recentData, recentFile.getAbsolutePath(), false); + // define profiles ConfigProfile.readPredefined(); ConfigProfile.readUser(); - // load root and default profile + // load root profile ConfigProfile.loadRoot(); - changeProfile(ConfigProfile.getDefault()); + + // change to start profile (cli, recent or default) + changeProfile(ConfigProfile.getStartProfile()); initVersion(); } @@ -195,8 +209,15 @@ public class ConfigManager implements ConfigurableComponentI { return activeProfile.getType() == ConfigProfile.Type.USER; } - public Set<String> getProfiles() { - return ConfigProfile.getListofProfiles(); + public List<String> getProfiles() { + // sort and convert to names + List<ConfigProfile> profiles = new ArrayList<ConfigProfile>(ConfigProfile.getProfiles()); + Collections.sort(profiles); + List<String> profileNames = new ArrayList<String>(); + for (ConfigProfile profile:profiles){ + profileNames.add(profile.getName()); + } + return profileNames; } public Map<String, List<ConfigItem>> getConfigSections() { @@ -213,12 +234,9 @@ public class ConfigManager implements ConfigurableComponentI { } private void changeProfile(ConfigProfile profile) { - // check if profiles have been loaded - if (!profile.isLoaded()) { - profile.load(); - } activeProfile = profile; - + activeProfile.makeActive(); + // define configItems for (List<ConfigItem> items:configSections.values()) { for (ConfigItem item:items) { @@ -254,6 +272,30 @@ public class ConfigManager implements ConfigurableComponentI { return saveProfile(applyInitMethods); } - - + String getRecent(String key) { + // get value from active profile (this escalates) + String value = recentData.getProperty(key); + if (Util.hasValue(value)) { + return value.trim(); + } else { + return null; + } + } + + boolean storeRecent(String key, String value) { + // check conditions + if (key == null) return false; + if (getRecent(key) == null || !getRecent(key).equals(value) ) { + if (value == null) { + recentData.remove(key); + } else { + recentData.setProperty(key, value); + } + File recentFile = new File(SystemOS.get().getConfigurationFolder(true), RECENT_FILE); + return ConfigProfile.storeProperties(recentData, recentFile); + } + // nothing has changed + return true; + } + } diff --git a/rails/common/ConfigProfile.java b/rails/common/ConfigProfile.java index dda3d13..1fed682 100644 --- a/rails/common/ConfigProfile.java +++ b/rails/common/ConfigProfile.java @@ -6,10 +6,10 @@ import java.io.FileOutputStream; import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStream; +import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Properties; -import java.util.Set; import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOCase; @@ -23,19 +23,24 @@ import rails.util.Util; * A profile storing configuration settings */ -public final class ConfigProfile { +public final class ConfigProfile implements Comparable<ConfigProfile> { protected static Logger log = Logger.getLogger(ConfigProfile.class.getPackage().getName()); // available profile types - public enum Type {SYSTEM, PREDEFINED, USER}; + public enum Type {SYSTEM(0), PREDEFINED(1), USER(2); + private Integer sort; Type(int sort) {this.sort = sort;} + }; // Filename extension of profiles public static final String PROFILE_EXTENSION = ".rails_profile"; private static final String PREDEFINED_EXTENSION = ".predefined"; - // Location of predefined profiles + // Locations + // user inside configuration folder + private static final String PROFILE_FOLDER = "profiles/"; + // predefined inside jar private static final String PREDEFINED_FOLDER = "data/profiles/"; // predefined default profiles @@ -45,7 +50,7 @@ public final class ConfigProfile { // the profile selected at the start ... private static final String STANDARD_PROFILE = "pbem"; // ... unless a cli option has been set - private static final String STANDARD_CLI_OPTION ="profile"; + private static final String CLI_AND_RECENT_OPTION ="profile"; // file that stores the list of predefined profiles @@ -98,7 +103,7 @@ public final class ConfigProfile { } static void readUser() { - File userFolder = SystemOS.get().getConfigurationFolder(false); + File userFolder = SystemOS.get().getConfigurationFolder(PROFILE_FOLDER, false); if (userFolder == null) return; FilenameFilter filter = new SuffixFileFilter(PROFILE_EXTENSION, IOCase.SYSTEM); for (String fileName:userFolder.list(filter)) { @@ -106,11 +111,18 @@ public final class ConfigProfile { } } - static ConfigProfile getDefault() { - String profile = System.getProperty(STANDARD_CLI_OPTION); + static ConfigProfile getStartProfile() { + // first checks cli + String profile = System.getProperty(CLI_AND_RECENT_OPTION); if (Util.hasValue(profile) && profiles.containsKey(profile)) { return profiles.get(profile); } + // second check recent + profile = Config.getRecent(CLI_AND_RECENT_OPTION); + if (Util.hasValue(profile) && profiles.containsKey(profile)) { + return profiles.get(profile); + } + // third return standard profile return profiles.get(STANDARD_PROFILE); } @@ -118,8 +130,8 @@ public final class ConfigProfile { return profiles.get(name); } - static Set<String> getListofProfiles() { - return profiles.keySet(); + static Collection<ConfigProfile> getProfiles() { + return profiles.values(); } private ConfigProfile(Type type, String name) { @@ -180,6 +192,16 @@ public final class ConfigProfile { properties.remove(key); } } + + + void makeActive(){ + // check if is already loaded + if (!isLoaded()) { + load(); + } + // and store it to recent + Config.storeRecent(CLI_AND_RECENT_OPTION, getName()); + } ConfigProfile deriveUserProfile(String name) { ConfigProfile newProfile = new ConfigProfile(Type.USER, name); @@ -242,7 +264,7 @@ public final class ConfigProfile { } private boolean loadUser() { - File folder = SystemOS.get().getConfigurationFolder(false); + File folder = SystemOS.get().getConfigurationFolder(PROFILE_FOLDER, false); if (folder == null) { return false; } else { @@ -267,7 +289,7 @@ public final class ConfigProfile { boolean store() { if (type != Type.USER) return false; loaded = true; - File folder = SystemOS.get().getConfigurationFolder(true); + File folder = SystemOS.get().getConfigurationFolder(PROFILE_FOLDER, true); if (folder == null) { return false; } else { @@ -306,8 +328,21 @@ public final class ConfigProfile { } return result; } - - + + private int compare(ConfigProfile a, ConfigProfile b) { + if (a.type.sort != b.type.sort) { + return a.type.sort.compareTo(b.type.sort); + } else { + return a.getName().compareTo(b.getName()); + } + } + + /** + * Compares first on Type.sort than on name + */ + public int compareTo(ConfigProfile other) { + return compare(this, other); + } } diff --git a/rails/ui/swing/ConfigWindow.java b/rails/ui/swing/ConfigWindow.java index e6c0842..7d0d061 100644 --- a/rails/ui/swing/ConfigWindow.java +++ b/rails/ui/swing/ConfigWindow.java @@ -10,7 +10,6 @@ import java.beans.PropertyChangeListener; import java.io.File; import java.util.Map; import java.util.List; -import java.util.Set; import rails.common.ConfigItem; import rails.common.LocalText; @@ -464,7 +463,7 @@ class ConfigWindow extends JFrame { private boolean saveAsConfig() { // get Names - Set<String> allProfileNames = cm.getProfiles(); + List<String> allProfileNames = cm.getProfiles(); String newProfile = null; do { newProfile = JOptionPane.showInputDialog(ConfigWindow.this, LocalText.getText("CONFIG_NEW_MESSAGE"), diff --git a/rails/util/SystemOS.java b/rails/util/SystemOS.java index 5f221cc..79b9d7a 100644 --- a/rails/util/SystemOS.java +++ b/rails/util/SystemOS.java @@ -41,6 +41,8 @@ public enum SystemOS { } /** + * Returns the folder that contains all rails specific user data + * Returns null if the operations fails * @param create set to true creates the folder if it does not exist * @return rails specific configuration folder */ public File getConfigurationFolder(boolean create) { @@ -63,14 +65,35 @@ public enum SystemOS { } // locate railsFolder - File railsFolder = new File(folder, appName); + return locateFolder(folder, appName, create); + } + + /** + * Returns a sub-folder inside the Rails configuration folder + * Returns null if the operations fails + * @param subFolder the folder inside + * @param create set to true creates the subFolder and/or + * configFolder if it does not exist + * @return rails specific configuration folder + */ + public File getConfigurationFolder(String subFolder, boolean create) { + File railsFolder = getConfigurationFolder(create); + + if (railsFolder == null) return null; + + // locate subFolder + return locateFolder(railsFolder, subFolder, create); + } + + private File locateFolder(File folder, String sub, boolean create) { + File subFolder = new File(folder, sub); - if (!railsFolder.exists() && create) { - createFolder(railsFolder); + if (!subFolder.exists() && create) { + createFolder(subFolder); } - if (railsFolder.exists() && railsFolder.isDirectory()) { - return railsFolder; + if (subFolder.exists() && subFolder.isDirectory()) { + return subFolder; } else { return null; } |
From: Erik V. <ev...@us...> - 2012-03-01 20:47:09
|
rails/ui/swing/GameSetupWindow.java | 73 +++++++++++++++++------------------- 1 file changed, 36 insertions(+), 37 deletions(-) New commits: commit c4ba582a4f59b45f182179c8e3c0d600df3bec40 Author: Erik Vos <eri...@xs...> Date: Thu Mar 1 21:45:10 2012 +0100 Fixed 'Load Recent' by running it in a separate thread. This is required since the new Splash Window. diff --git a/rails/ui/swing/GameSetupWindow.java b/rails/ui/swing/GameSetupWindow.java index 9282195..d948ff4 100644 --- a/rails/ui/swing/GameSetupWindow.java +++ b/rails/ui/swing/GameSetupWindow.java @@ -8,21 +8,13 @@ import java.util.List; import javax.swing.*; -import rails.common.parser.ConfigurationException; -import rails.common.parser.GameInfoParser; - import org.apache.log4j.Logger; -import rails.common.Config; -import rails.common.DisplayBuffer; -import rails.common.GuiDef; -import rails.common.LocalText; -import rails.common.ConfigManager; -import rails.common.parser.GameOption; -import rails.common.parser.GameInfo; +import rails.common.*; +import rails.common.parser.*; import rails.game.*; import rails.sound.SoundManager; -import rails.util.*; +import rails.util.Util; /** * The Game Setup Window displays the first window presented to the user. This @@ -34,7 +26,7 @@ public class GameSetupWindow extends JDialog implements ActionListener { GridBagConstraints gc; JPanel gameListPane, playersPane, buttonPane, optionsPane; JButton newButton, loadButton, recentButton, recoveryButton, quitButton, optionButton, infoButton, - creditsButton, randomizeButton, configureButton; + creditsButton, randomizeButton, configureButton; JComboBox configureBox; JComboBox gameNameBox = new JComboBox(); JComboBox[] playerBoxes = new JComboBox[Player.MAX_PLAYERS]; @@ -62,11 +54,11 @@ public class GameSetupWindow extends JDialog implements ActionListener { static final int AI_PLAYER = 2; protected static Logger log = - Logger.getLogger(GameSetupWindow.class.getPackage().getName()); + Logger.getLogger(GameSetupWindow.class.getPackage().getName()); public GameSetupWindow() { super(); - + GameInfoParser gip = new GameInfoParser(); try { gameInfoList = gip.processGameList(); @@ -113,7 +105,7 @@ public class GameSetupWindow extends JDialog implements ActionListener { this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); populateGameList(gameInfoList, gameNameBox); - + final ConfigManager cm = ConfigManager.getInstance(); configureBox = new JComboBox(cm.getProfiles().toArray()); configureBox.setSelectedItem(cm.getActiveProfile()); @@ -161,7 +153,7 @@ public class GameSetupWindow extends JDialog implements ActionListener { // This needs to happen after we have a valid gameName. fillPlayersPane(); - + // Notify the sound manager about having started the setup menu SoundManager.notifyOfGameSetup(); } @@ -263,6 +255,7 @@ public class GameSetupWindow extends JDialog implements ActionListener { if (arg0.getSource().equals(newButton)) { //start in new thread so that swing thread is not used for game setup new Thread() { + @Override public void run() { startNewGame(); } @@ -288,6 +281,7 @@ public class GameSetupWindow extends JDialog implements ActionListener { final File selectedFile = jfc.getSelectedFile(); //start in new thread so that swing thread is not used for game setup new Thread() { + @Override public void run() { loadAndStartGame(selectedFile.getPath(), selectedFile.getParent()); } @@ -297,7 +291,7 @@ public class GameSetupWindow extends JDialog implements ActionListener { } } else if (arg0.getSource().equals(recentButton)) { File saveDirectory = new File(Config.get("save.directory")); - + recentFiles = new TreeSet<File>(new Comparator<File> (){ public int compare (File a, File b) { return Math.round(b.lastModified() - a.lastModified()); @@ -321,12 +315,17 @@ public class GameSetupWindow extends JDialog implements ActionListener { } String text = LocalText.getText("Select"); String result = (String) JOptionPane.showInputDialog(this, text, text, - JOptionPane.OK_CANCEL_OPTION, + JOptionPane.OK_CANCEL_OPTION, null, options, options[0]); if (result == null) return; - File selectedFile = files[Arrays.asList(options).indexOf(result)]; + final File selectedFile = files[Arrays.asList(options).indexOf(result)]; if (selectedFile != null) { - loadAndStartGame(selectedFile.getPath(), selectedFile.getParent()); + new Thread() { + @Override + public void run() { + loadAndStartGame(selectedFile.getPath(), selectedFile.getParent()); + } + }.start(); } else { // cancel pressed return; } @@ -335,14 +334,14 @@ public class GameSetupWindow extends JDialog implements ActionListener { loadAndStartGame(filePath, null); } else if (arg0.getSource().equals(infoButton)) { GameInfo gameInfo = this.getSelectedGameInfo(); - JOptionPane.showMessageDialog(this, - gameInfo.getDescription(), + JOptionPane.showMessageDialog(this, + gameInfo.getDescription(), "Information about " + gameInfo.getName(), JOptionPane.INFORMATION_MESSAGE); } else if (arg0.getSource().equals(quitButton)) { System.exit(0); } else if (arg0.getSource().equals(creditsButton)) { - JOptionPane.showMessageDialog(this, + JOptionPane.showMessageDialog(this, new JLabel(credits), //enable html rendering LocalText.getText("CREDITS"), JOptionPane.INFORMATION_MESSAGE); @@ -381,9 +380,9 @@ public class GameSetupWindow extends JDialog implements ActionListener { List<String> playerList = new ArrayList<String>(); for (int i = 0; i < playerNameFields.length; i++) { if (playerNameFields[i] != null - && playerNameFields[i].getText().length() > 0) { - playerList.add(playerNameFields[i].getText()); - playerNameFields[i].setText(""); + && playerNameFields[i].getText().length() > 0) { + playerList.add(playerNameFields[i].getText()); + playerNameFields[i].setText(""); } } Collections.shuffle(playerList); @@ -394,7 +393,7 @@ public class GameSetupWindow extends JDialog implements ActionListener { } } } - + private void getRecentFiles (File dir) { if (!dir.exists() || !dir.isDirectory()) return; for (File entry : dir.listFiles()) { @@ -422,7 +421,7 @@ public class GameSetupWindow extends JDialog implements ActionListener { for (GameOption option : availableOptions) { if (option.isBoolean()) { JCheckBox checkbox = - new JCheckBox(option.getLocalisedName()); + new JCheckBox(option.getLocalisedName()); if (option.getDefaultValue().equalsIgnoreCase("yes")) { checkbox.setSelected(true); } @@ -460,14 +459,14 @@ public class GameSetupWindow extends JDialog implements ActionListener { for (int i = 0; i < playerBoxes.length; i++) { if (playerBoxes[i] != null - && playerBoxes[i].getSelectedIndex() == HUMAN_PLAYER - && !playerNameFields[i].getText().equals("")) { + && playerBoxes[i].getSelectedIndex() == HUMAN_PLAYER + && !playerNameFields[i].getText().equals("")) { playerNames.add(playerNameFields[i].getText()); } } if (playerNames.size() < Player.MIN_PLAYERS - || playerNames.size() > Player.MAX_PLAYERS) { + || playerNames.size() > Player.MAX_PLAYERS) { if (JOptionPane.showConfirmDialog(this, "Not enough players. Continue Anyway?", "Are you sure?", JOptionPane.YES_NO_OPTION) == JOptionPane.NO_OPTION) { @@ -477,7 +476,7 @@ public class GameSetupWindow extends JDialog implements ActionListener { } catch (NullPointerException e) { e.printStackTrace(); JOptionPane.showMessageDialog(this, - "Unable to load selected rails.game. Exiting..."); + "Unable to load selected rails.game. Exiting..."); System.exit(-1); } @@ -514,9 +513,9 @@ public class GameSetupWindow extends JDialog implements ActionListener { } String gameName = getSelectedGameInfo().getName(); - + SplashWindow splashWindow = new SplashWindow(false,gameName); - + game = new Game(gameName, playerNames, selectedOptions); if (!game.setup()) { @@ -541,12 +540,12 @@ public class GameSetupWindow extends JDialog implements ActionListener { } } - + private void prepareGameUIInit() { setVisible(false); if (configWindow != null) configWindow.setVisible(false); } - + private void completeGameUIInit(SplashWindow splashWindow) { if (configWindow != null) { configWindow.dispose(); @@ -584,7 +583,7 @@ public class GameSetupWindow extends JDialog implements ActionListener { // Remember names that have already been filled-in... for (int i = 0; i < playerNameFields.length; i++) { if (playerNameFields[i] != null - && playerNameFields[i].getText().length() > 0) { + && playerNameFields[i].getText().length() > 0) { playerList[i] = playerNameFields[i].getText(); } else if (i < testPlayers.length && testPlayers[i].length() > 0) { playerList[i] = testPlayers[i]; |
From: Stefan F. <ste...@us...> - 2012-02-29 22:39:01
|
rails/common/ConfigProfile.java | 9 +++++++++ 1 file changed, 9 insertions(+) New commits: commit 8b7e4d8addfe0a24f021fe7ae13a910a44ebe783 Author: Stefan Frey <ste...@we...> Date: Wed Feb 29 23:38:20 2012 +0100 added cli option for command line option diff --git a/rails/common/ConfigProfile.java b/rails/common/ConfigProfile.java index 2651ce2..dda3d13 100644 --- a/rails/common/ConfigProfile.java +++ b/rails/common/ConfigProfile.java @@ -41,7 +41,12 @@ public final class ConfigProfile { // predefined default profiles private static final String ROOT_PROFILE = "root"; private static final String TEST_PROFILE = "test"; + + // the profile selected at the start ... private static final String STANDARD_PROFILE = "pbem"; + // ... unless a cli option has been set + private static final String STANDARD_CLI_OPTION ="profile"; + // file that stores the list of predefined profiles private static final String LIST_OF_PROFILES = "LIST_OF_PROFILES"; @@ -102,6 +107,10 @@ public final class ConfigProfile { } static ConfigProfile getDefault() { + String profile = System.getProperty(STANDARD_CLI_OPTION); + if (Util.hasValue(profile) && profiles.containsKey(profile)) { + return profiles.get(profile); + } return profiles.get(STANDARD_PROFILE); } |
From: Stefan F. <ste...@us...> - 2012-02-27 10:00:32
|
rails/common/Config.java | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) New commits: commit 954bbd4b1d2f4c90fe4105fb68dfe743df83c260 Author: Stefan Frey <ste...@we...> Date: Mon Feb 27 11:00:03 2012 +0100 another fix: forgot to commit config diff --git a/rails/common/Config.java b/rails/common/Config.java new file mode 100644 index 0000000..bce5142 --- /dev/null +++ b/rails/common/Config.java @@ -0,0 +1,47 @@ +package rails.common; + +import rails.game.GameManager; +import rails.util.Util; + +/** + * Proxy class to the ConfigManager + */ + +public class Config { + + /** + * Configuration option (default value is empty string) + */ + public static String get(String key) { + return ConfigManager.getInstance().getValue(key, ""); + } + + /** + * Configuration option with default value + */ + public static String get(String key, String defaultValue) { + return ConfigManager.getInstance().getValue(key, defaultValue); + } + + /** + * Configuration option: First tries to return {key}.{appendix}, if undefined returns {key} + */ + public static String getSpecific(String key, String appendix) { + String value = get(key + "." + appendix); + if (Util.hasValue(value)) { + return value; + } else { + return get(key); + } + } + + /** + * Configuration option: First tries to return {key}.{gameName}, if undefined returns {key} + */ + public static String getGameSpecific(String key) { + return getSpecific(key, GameManager.getInstance().getGameName()); + } + + + +} |
From: Stefan F. <ste...@us...> - 2012-02-27 09:45:46
|
rails/common/ConfigProfile.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) New commits: commit 2b479e4cb646082b36e1936071a88eadf5d1f701 Author: Stefan Frey <ste...@we...> Date: Mon Feb 27 10:45:30 2012 +0100 fix that makes all user profiles final diff --git a/rails/common/ConfigProfile.java b/rails/common/ConfigProfile.java index 3ad6f20..2651ce2 100644 --- a/rails/common/ConfigProfile.java +++ b/rails/common/ConfigProfile.java @@ -134,7 +134,8 @@ public final class ConfigProfile { } boolean isFinal() { - if (!loaded) return true; + if (!loaded && type == Type.USER) return true; + if (Util.hasValue(properties.getProperty(FINAL_KEY))) { return Util.parseBoolean(properties.getProperty(FINAL_KEY)); } |
.classpath | 3 LocalisedText.properties | 6 build.xml | 72 +- data/profiles/LIST_OF_PROFILES | 6 data/profiles/ORDocking.predefined | 5 data/profiles/ORDocking.profile | 3 data/profiles/default.profile | 2 data/profiles/default.profiles | 7 data/profiles/pbem.predefined | 2 data/profiles/prettyUI.predefined | 11 data/profiles/prettyUI.profile | 9 data/profiles/root | 63 + data/profiles/root.profile | 63 - data/profiles/test | 15 data/profiles/test.profile | 15 lib/commons-io-2.1/commons-io-2.1.jar |binary rails/common/ConfigItem.java | 180 +++++ rails/common/ConfigManager.java | 259 ++++++++ rails/common/ConfigProfile.java | 303 +++++++++ rails/common/LocalText.java | 1 rails/common/MoneyFormatter.java | 1 rails/common/parser/Config.java | 606 ------------------- rails/common/parser/ConfigItem.java | 151 ---- rails/game/Bank.java | 2 rails/game/MapManager.java | 1 rails/game/ReportBuffer.java | 2 rails/sound/SoundConfig.java | 2 rails/ui/swing/AbstractReportWindow.java | 2 rails/ui/swing/ConfigWindow.java | 306 ++------- rails/ui/swing/GameSetupWindow.java | 21 rails/ui/swing/GameUIManager.java | 3 rails/ui/swing/GridPanel.java | 2 rails/ui/swing/ImageLoader.java | 2 rails/ui/swing/ORPanel.java | 2 rails/ui/swing/ORUIManager.java | 2 rails/ui/swing/ORWindow.java | 2 rails/ui/swing/ReportWindow.java | 2 rails/ui/swing/Scale.java | 2 rails/ui/swing/SplashWindow.java | 2 rails/ui/swing/StatusWindow.java | 17 rails/ui/swing/WindowSettings.java | 2 rails/ui/swing/elements/DockingFrame.java | 2 rails/ui/swing/elements/RailsIconButton.java | 2 rails/ui/swing/hexmap/HexHighlightMouseListener.java | 2 rails/ui/swing/hexmap/HexMap.java | 2 rails/ui/swing/hexmap/HexMapImage.java | 2 rails/util/RunGame.java | 4 rails/util/SystemOS.java | 94 ++ test/TestGame.java | 2 test/TestGameBuilder.java | 7 tools/ListAndFixSavedFiles.java | 5 51 files changed, 1126 insertions(+), 1153 deletions(-) New commits: commit 83e4a63c76f277e11ff75bf86f0dcb84d673c215 Author: Stefan Frey <ste...@we...> Date: Mon Feb 20 12:19:28 2012 +0100 New configuration system based on a profile tree. Added ConfigManager and ConfigProfile classes Refactored Config and ConfigWindow, Config is only a proxy to ConfigManager Added SystemOS class for os related functions Added common-io library for additional file i/o functions diff --git a/.classpath b/.classpath index 4dd2569..a1de363 100644 --- a/.classpath +++ b/.classpath @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <classpath> - <classpathentry excluding="lib/JLayer1.0.1/|lib/df_1.1.0/|lib/batik-1.7/|lib/batik-1.7/|lib/batik-1.7/lib/|lib/batik-1.7/lib/|lib/jgraph5/|lib/jgraph5/|lib/jgrapht-0.7.3/|lib/jgrapht-0.7.3/|lib/junit-4.8.2|lib/log4j-1.2/|lib/log4j-1.2/" kind="src" path=""/> + <classpathentry excluding="lib/JLayer1.0.1/|lib/batik-1.7/|lib/batik-1.7/|lib/batik-1.7/lib/|lib/batik-1.7/lib/|lib/commons-io-2.1/|lib/df_1.1.0/|lib/jgraph5/|lib/jgraph5/|lib/jgrapht-0.7.3/|lib/jgrapht-0.7.3/|lib/junit-4.8.2|lib/log4j-1.2/|lib/log4j-1.2/" kind="src" path=""/> <classpathentry exported="true" kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> <classpathentry exported="true" kind="lib" path="lib/log4j-1.2/log4j-1.2.14.jar"/> <classpathentry exported="true" kind="lib" path="lib/jgrapht-0.7.3/jgrapht-jdk1.5.jar"/> @@ -29,5 +29,6 @@ <classpathentry kind="lib" path="lib/batik-1.7/lib/batik-codec.jar"/> <classpathentry kind="lib" path="lib/df_1.1.0/dockingFramesCommon.jar"/> <classpathentry kind="lib" path="lib/df_1.1.0/dockingFramesCore.jar"/> + <classpathentry exported="true" kind="lib" path="lib/commons-io-2.1/commons-io-2.1.jar"/> <classpathentry kind="output" path="classes"/> </classpath> diff --git a/LocalisedText.properties b/LocalisedText.properties index ce07410..059e471 100644 --- a/LocalisedText.properties +++ b/LocalisedText.properties @@ -78,10 +78,8 @@ COMPANY_DETAILS=Company details CONFIG=Configuration CONFIG_APPLY_MESSAGE=<html>Current changes (will be) applied.<br>Be aware that some changes to be active require <br> UI redraws or a restart of Rails.</html> CONFIG_APPLY_TITLE=Apply confirmation -CONFIG_CURRENT_PATH=Active filepath = {0} -CONFIG_CURRENT_PROFILE=Active profile = {0} (based on = {1}) -CONFIG_DEFAULT_TITLE=Default profile -CONFIG_DEFAULT_MESSAGE=Select a template for settings +CONFIG_USER_PROFILE=Active user profile = {0} +CONFIG_PREDEFINED_PROFILE=Active predefined profile = {0} CONFIG_INFO_TITLE=Info text for {0} CONFIF_LOAD_ERROR_MESSAGE=An error occurred during load of the file {0}.\nProfile was not loaded. CONFIG_LOAD_TITLE=Load of profile diff --git a/build.xml b/build.xml index c098278..e832108 100644 --- a/build.xml +++ b/build.xml @@ -6,6 +6,7 @@ as the first entry and export the buildfile again. --> <project basedir="." default="build" name="Rails"> <property environment="env"/> + <property name="ECLIPSE_HOME" value="../../../installed/eclipse"/> <property name="junit.output.dir" value="junit"/> <property name="debuglevel" value="source,lines,vars"/> <property name="target" value="1.5"/> @@ -17,9 +18,6 @@ <pathelement location="lib/jgrapht-0.7.3/jgrapht-jdk1.5.jar"/> <pathelement location="lib/jgraph5/jgraph.jar"/> <pathelement location="lib/junit-4.8.2/junit.jar"/> - <pathelement location="lib/JLayer1.0.1/jl1.0.1.jar"/> - <pathelement location="lib/df_1.1.0/dockingFramesCommon.jar"/> - <pathelement location="lib/df_1.1.0/dockingFramesCore.jar"/> <pathelement location="lib/batik-1.7/lib/batik-transcoder.jar"/> <pathelement location="lib/batik-1.7/lib/batik-dom.jar"/> <pathelement location="lib/batik-1.7/lib/batik-swing.jar"/> @@ -36,23 +34,50 @@ <pathelement location="lib/batik-1.7/lib/batik-svg-dom.jar"/> <pathelement location="lib/batik-1.7/lib/batik-xml.jar"/> <pathelement location="lib/batik-1.7/lib/js.jar"/> + <pathelement location="lib/JLayer1.0.1/jl1.0.1.jar"/> <pathelement location="lib/batik-1.7/lib/xerces_2_5_0.jar"/> <pathelement location="lib/batik-1.7/lib/xml-apis-ext.jar"/> <pathelement location="lib/batik-1.7/lib/batik-anim.jar"/> <pathelement location="lib/batik-1.7/lib/batik-codec.jar"/> + <pathelement location="lib/df_1.1.0/dockingFramesCommon.jar"/> + <pathelement location="lib/df_1.1.0/dockingFramesCore.jar"/> + <pathelement location="lib/commons-io-2.1/commons-io-2.1.jar"/> </path> <target name="init"> <mkdir dir="classes"/> <copy includeemptydirs="false" todir="classes"> <fileset dir="."> - <exclude name="**/*.launch"/> + <exclude name="**/*.ucls"/> + <exclude name="**/*.uad"/> + <exclude name="**/*.ucd"/> + <exclude name="**/*.uld"/> + <exclude name="**/*.upd"/> + <exclude name="**/*.udd"/> + <exclude name="**/*.uod"/> + <exclude name="**/*.usd"/> + <exclude name="**/*.utd"/> + <exclude name="**/*.uud"/> + <exclude name="**/*.odd"/> + <exclude name="**/*.ead"/> + <exclude name="**/*.ecd"/> + <exclude name="**/*.eld"/> + <exclude name="**/*.epd"/> + <exclude name="**/*.edd"/> + <exclude name="**/*.eod"/> + <exclude name="**/*.esd"/> + <exclude name="**/*.etd"/> + <exclude name="**/*.eud"/> + <exclude name="**/*.urd"/> + <exclude name="**/*.uml"/> + <exclude name="**/*.ecore"/> <exclude name="**/*.java"/> + <exclude name="lib/JLayer1.0.1/"/> <exclude name="lib/batik-1.7/"/> <exclude name="lib/batik-1.7/"/> <exclude name="lib/batik-1.7/lib/"/> <exclude name="lib/batik-1.7/lib/"/> - <exclude name="lib/JLayer1.0.1"/> - <exclude name="lib/df_1.1.0"/> + <exclude name="lib/commons-io-2.1/"/> + <exclude name="lib/df_1.1.0/"/> <exclude name="lib/jgraph5/"/> <exclude name="lib/jgraph5/"/> <exclude name="lib/jgrapht-0.7.3/"/> @@ -71,14 +96,15 @@ <target name="build-subprojects"/> <target depends="init" name="build-project"> <echo message="${ant.project.name}: ${ant.file}"/> - <javac debug="true" debuglevel="${debuglevel}" destdir="classes" includeantruntime="false" source="${source}" target="${target}"> + <javac debug="true" debuglevel="${debuglevel}" destdir="classes" source="${source}" target="${target}"> <src path="."/> + <exclude name="lib/JLayer1.0.1/"/> <exclude name="lib/batik-1.7/"/> <exclude name="lib/batik-1.7/"/> <exclude name="lib/batik-1.7/lib/"/> <exclude name="lib/batik-1.7/lib/"/> - <exclude name="lib/JLayer1.0.1"/> - <exclude name="lib/df_1.1.0"/> + <exclude name="lib/commons-io-2.1/"/> + <exclude name="lib/df_1.1.0/"/> <exclude name="lib/jgraph5/"/> <exclude name="lib/jgraph5/"/> <exclude name="lib/jgrapht-0.7.3/"/> @@ -103,14 +129,31 @@ <property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/> <antcall target="build"/> </target> + <target name="Check Save File (ListAndFixSavedFiles)"> + <java classname="tools.ListAndFixSavedFiles" failonerror="true" fork="yes"> + <classpath refid="Rails.classpath"/> + </java> + </target> <target name="Start Rails (RunGame)"> <java classname="rails.util.RunGame" failonerror="true" fork="yes"> - <jvmarg line="-DRevenueCalculation=suggest -Dswing.defaultlaf=com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel"/> + <jvmarg line="-DRevenueCalculation=suggest -Dawt.useSystemAAFontSettings=on"/> <classpath refid="Rails.classpath"/> </java> </target> - <target name="Check Save File (ListAndFixSavedFiles)"> - <java classname="tools.ListAndFixSavedFiles" failonerror="true" fork="yes"> + <target name="Start Rails (RunGame) (Profiled)"> + <java classname="rails.util.RunGame" failonerror="true" fork="yes"> + <jvmarg line="-DRevenueCalculation=suggest -Dawt.useSystemAAFontSettings=on"/> + <classpath refid="Rails.classpath"/> + </java> + </target> + <target name="Delete and Update Test Game Reports (TestGameBuilder)"> + <java classname="test.TestGameBuilder" failonerror="true" fork="yes"> + <classpath refid="Rails.classpath"/> + </java> + </target> + <target name="Start Rails (RunGame) Nimbus LAF"> + <java classname="rails.util.RunGame" failonerror="true" fork="yes"> + <jvmarg line="-DRevenueCalculation=suggest -Dswing.defaultlaf=com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel"/> <classpath refid="Rails.classpath"/> </java> </target> @@ -122,11 +165,6 @@ <classpath refid="Rails.classpath"/> </junit> </target> - <target name="Delete and Update Test Game Reports (TestGameBuilder)"> - <java classname="test.TestGameBuilder" failonerror="true" fork="yes"> - <classpath refid="Rails.classpath"/> - </java> - </target> <target name="junitreport"> <junitreport todir="${junit.output.dir}"> <fileset dir="${junit.output.dir}"> diff --git a/data/profiles/LIST_OF_PROFILES b/data/profiles/LIST_OF_PROFILES new file mode 100644 index 0000000..d061833 --- /dev/null +++ b/data/profiles/LIST_OF_PROFILES @@ -0,0 +1,6 @@ +### List of predefined profiles +### available for user selection +### with extension .predefined +pbem +ORDocking +prettyUI diff --git a/data/profiles/ORDocking.predefined b/data/profiles/ORDocking.predefined new file mode 100644 index 0000000..aa4985d --- /dev/null +++ b/data/profiles/ORDocking.predefined @@ -0,0 +1,5 @@ +### ORDocking profile +### activates the docking framework +or.window.dockablePanels=yes +### cannot be derived +profile.final=yes diff --git a/data/profiles/ORDocking.profile b/data/profiles/ORDocking.profile deleted file mode 100644 index e5f8d80..0000000 --- a/data/profiles/ORDocking.profile +++ /dev/null @@ -1,3 +0,0 @@ -### ORDocking profile -### activates the docking framework -or.window.dockablePanels=yes diff --git a/data/profiles/default.profile b/data/profiles/default.profile deleted file mode 100644 index 122c1b7..0000000 --- a/data/profiles/default.profile +++ /dev/null @@ -1,2 +0,0 @@ -### Default profile currently is identical to root.profile -### so no change here diff --git a/data/profiles/default.profiles b/data/profiles/default.profiles deleted file mode 100644 index 9cedd38..0000000 --- a/data/profiles/default.profiles +++ /dev/null @@ -1,7 +0,0 @@ -### This is the list of (predefined) profiles and their file locations -### A dot (".") before the profilename prevents displaying those to the user selection -.root=data/profiles/root.profile -.test=data/profiles/test.profile -default=data/profiles/default.profile -prettyUI=data/profiles/prettyUI.profile -ORDocking=data/profiles/ORDocking.profile diff --git a/data/profiles/pbem.predefined b/data/profiles/pbem.predefined new file mode 100644 index 0000000..122c1b7 --- /dev/null +++ b/data/profiles/pbem.predefined @@ -0,0 +1,2 @@ +### Default profile currently is identical to root.profile +### so no change here diff --git a/data/profiles/prettyUI.predefined b/data/profiles/prettyUI.predefined new file mode 100644 index 0000000..f2e51b3 --- /dev/null +++ b/data/profiles/prettyUI.predefined @@ -0,0 +1,11 @@ +### prettyUI profile +### activates the new UI options of Frederick +button.iconPosition=left +button.iconText=text and icon +button.iconSize=small +gridPanel.tableBorders=enabled +map.image.display=yes +map.displayCurrentRoutes=yes +map.highlightHexes=yes +### cannot be derived +profile.final=yes diff --git a/data/profiles/prettyUI.profile b/data/profiles/prettyUI.profile deleted file mode 100644 index a537864..0000000 --- a/data/profiles/prettyUI.profile +++ /dev/null @@ -1,9 +0,0 @@ -### prettyUI profile -### activates the new UI options of Frederick -button.iconPosition=left -button.iconText=text and icon -button.iconSize=small -gridPanel.tableBorders=enabled -map.image.display=yes -map.displayCurrentRoutes=yes -map.highlightHexes=yes diff --git a/data/profiles/root b/data/profiles/root new file mode 100644 index 0000000..3e08d4d --- /dev/null +++ b/data/profiles/root @@ -0,0 +1,63 @@ +### Root profile defines the settings used for all (predefined) default profiles +### All others define only deviations + +### Panel General +locale=en_US +default_game=1830 +default_players= +local.player.names= + +### Panel Save +save.directory= +save.filename.date_time_pattern=yyyyMMdd_HHmm +save.filename.date_time_zone=UTC +save.filename.suffix=NEXT_PLAYER +save.filename.extension=rails +save.recovery.active=no +save.recovery.filepath=18xx_autosave.rails + +### Panel Font +font.ui.scale=1 +font.ui.name= +font.ui.style=bold + +### Panel Map +map.autoscroll=yes +map.defaultZoomFitOption=none +map.displayCurrentRoutes=no +map.highlightHexes=no +map.image.display=no +map.zoomstep=10 + +### Panel Windows +or.window.dockablePanels=no +report.window.type=dynamic +report.window.open=yes +report.window.editable=no +splash.window.open=yes +stockchart.window.open=yes + +### Panel Format +money_format= +or.number_format=composite + +### Panel Appearance +button.iconText=only text +button.iconSize=small +button.iconPosition=left +gridPanel.tableBorder=disabled +route.colour.1=00ffff +route.colour.2=ffc0cb +route.colour.3=ffa500 +route.colour.4=808080 + +### Panel Log +#report.directory=log +#report.filename.date_time_pattern=yyyyMMdd +#report.filename.extension=log + +### Panel Music +sound.backgroundMusic=disabled + +### Panel SFX +sound.sfx=disabled diff --git a/data/profiles/root.profile b/data/profiles/root.profile deleted file mode 100644 index 3e08d4d..0000000 --- a/data/profiles/root.profile +++ /dev/null @@ -1,63 +0,0 @@ -### Root profile defines the settings used for all (predefined) default profiles -### All others define only deviations - -### Panel General -locale=en_US -default_game=1830 -default_players= -local.player.names= - -### Panel Save -save.directory= -save.filename.date_time_pattern=yyyyMMdd_HHmm -save.filename.date_time_zone=UTC -save.filename.suffix=NEXT_PLAYER -save.filename.extension=rails -save.recovery.active=no -save.recovery.filepath=18xx_autosave.rails - -### Panel Font -font.ui.scale=1 -font.ui.name= -font.ui.style=bold - -### Panel Map -map.autoscroll=yes -map.defaultZoomFitOption=none -map.displayCurrentRoutes=no -map.highlightHexes=no -map.image.display=no -map.zoomstep=10 - -### Panel Windows -or.window.dockablePanels=no -report.window.type=dynamic -report.window.open=yes -report.window.editable=no -splash.window.open=yes -stockchart.window.open=yes - -### Panel Format -money_format= -or.number_format=composite - -### Panel Appearance -button.iconText=only text -button.iconSize=small -button.iconPosition=left -gridPanel.tableBorder=disabled -route.colour.1=00ffff -route.colour.2=ffc0cb -route.colour.3=ffa500 -route.colour.4=808080 - -### Panel Log -#report.directory=log -#report.filename.date_time_pattern=yyyyMMdd -#report.filename.extension=log - -### Panel Music -sound.backgroundMusic=disabled - -### Panel SFX -sound.sfx=disabled diff --git a/data/profiles/test b/data/profiles/test new file mode 100644 index 0000000..897ee6d --- /dev/null +++ b/data/profiles/test @@ -0,0 +1,15 @@ +####################### Test preferences ################################ +# +# Those are the settings used for automated testing +# +######################################################################## +locale=te_ST + +# An overriding format can be specified here, but then applies to all games. +# The @ character must be present and is replaced by the amount. +# Example: �@ to specify a pound sign prefix: �100. +money_format=@ + +save.directory=test/data +report.filename.extension=report +failed.filename.extension=failed diff --git a/data/profiles/test.profile b/data/profiles/test.profile deleted file mode 100644 index 897ee6d..0000000 --- a/data/profiles/test.profile +++ /dev/null @@ -1,15 +0,0 @@ -####################### Test preferences ################################ -# -# Those are the settings used for automated testing -# -######################################################################## -locale=te_ST - -# An overriding format can be specified here, but then applies to all games. -# The @ character must be present and is replaced by the amount. -# Example: �@ to specify a pound sign prefix: �100. -money_format=@ - -save.directory=test/data -report.filename.extension=report -failed.filename.extension=failed diff --git a/lib/commons-io-2.1/commons-io-2.1.jar b/lib/commons-io-2.1/commons-io-2.1.jar new file mode 100644 index 0000000..b5c7d69 Binary files /dev/null and b/lib/commons-io-2.1/commons-io-2.1.jar differ diff --git a/rails/common/ConfigItem.java b/rails/common/ConfigItem.java new file mode 100644 index 0000000..382d9a9 --- /dev/null +++ b/rails/common/ConfigItem.java @@ -0,0 +1,180 @@ +package rails.common; + +import java.util.Arrays; +import java.util.List; + +import org.apache.log4j.Logger; + +import rails.common.parser.ConfigurationException; +import rails.common.parser.Tag; +import rails.util.Util; + +/** + * Defines an item used for the configuration of rails + * T represents the value type + */ + +public final class ConfigItem { + + protected static Logger log = + Logger.getLogger(ConfigItem.class.getPackage().getName()); + + /** + * Defines possible types (Java classes used as types in ConfigItem below + */ + public static enum ConfigType { + BOOLEAN, INTEGER, PERCENT, STRING, LIST, FONT, DIRECTORY, FILE, COLOR; + } + + // static attributes + public final String name; + public final ConfigType type; + public final List<String> allowedValues; + public final String formatMask; + + // method call attributes + private final String initClass; + private final String initMethod; + private final boolean alwaysCallInit; + private final boolean initParameter; + + // dynamic attributes + private String newValue; + private String currentValue; + + ConfigItem(Tag tag) throws ConfigurationException { + // check name and type (required) + String name = tag.getAttributeAsString("name"); + if (Util.hasValue(name)) { + this.name = name; + } else { + throw new ConfigurationException("Missing name for configuration item"); + } + // optional: list of allowed values + String valueString = tag.getAttributeAsString("values"); + if (Util.hasValue(valueString)) { + allowedValues = Arrays.asList(valueString.split(",")); + this.type = ConfigType.LIST; + } else { + allowedValues = null; + String type = tag.getAttributeAsString("type"); + if (Util.hasValue(type)) { + try { + this.type = ConfigType.valueOf(type.toUpperCase()); + } catch (Exception e) { + throw new ConfigurationException("Missing or invalid type for configuration item, exception = " + e); + } + } else { + throw new ConfigurationException("Missing or invalid type for configuration item"); + } + if (this.type == ConfigType.LIST) { + throw new ConfigurationException("No values defined for LIST config item"); + } + } + + // optional: formatMask + formatMask = tag.getAttributeAsString("formatMask"); + + // optional: init method attributes + initClass = tag.getAttributeAsString("initClass"); + initMethod = tag.getAttributeAsString("initMethod"); + alwaysCallInit = tag.getAttributeAsBoolean("alwaysCallInit",false); + initParameter = tag.getAttributeAsBoolean("initParameter", false); + + // intialize values + currentValue = null; + newValue = null; + } + + + public boolean hasChanged() { + if (newValue == null) return false; + return !getCurrentValue().equals(newValue); + } + + public String getValue() { + if (hasChanged()) { + return getNewValue(); + } else { + return getCurrentValue(); + } + } + + public String getCurrentValue() { + if (currentValue == null) return ""; + return currentValue; + } + + public void setCurrentValue(String value) { + currentValue = value; + newValue = null; + } + + @Deprecated + public boolean hasNewValue() { + return (newValue != null); + } + + public String getNewValue() { + if (newValue == null) return ""; + return newValue; + } + + public void setNewValue(String value) { + if (value == null || value.equals("") || value.equals(currentValue)) { + newValue = null; + } else { + newValue = value; + } + log.debug("ConfigItem " + name + " set to new value " + newValue); + } + + public void resetValue() { + if (hasChanged()) { + currentValue = newValue; + newValue = null; + } + } + + /** + * @param applyInitMethod Specifies whether init should be called. Can be overruled + * by an additional tag alwaysCallInit + */ + void callInitMethod(boolean applyInitMethod) { + if (!applyInitMethod && !alwaysCallInit) return; + if (initClass == null || initMethod == null) return; + + // call without parameter + try { + Class<?> clazz = Class.forName(initClass); + + if (initParameter) { + clazz.getMethod(initMethod, String.class).invoke(null, newValue); + + } else { + clazz.getMethod(initMethod).invoke(null); + } + } catch (Exception e) { + log.error("Config profile: cannot call initMethod, Exception = " + e.toString()); + } + } + + + public String toString() { + StringBuffer s = new StringBuffer(); + s.append("Configuration Item: name = " + name + ", type = " + type); + s.append(", current value = " + getCurrentValue()) ; + s.append(", new value = " + getNewValue()); + if (allowedValues != null) { + s.append(", allowedValues = " + allowedValues); + } + if (formatMask != null) { + s.append(", formatMask = " + formatMask); + } + + return s.toString(); + } + + + +} diff --git a/rails/common/ConfigManager.java b/rails/common/ConfigManager.java new file mode 100644 index 0000000..c2420c9 --- /dev/null +++ b/rails/common/ConfigManager.java @@ -0,0 +1,259 @@ +package rails.common; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; + +import org.apache.log4j.Logger; + +import rails.common.ConfigManager; +import rails.common.parser.ConfigurableComponentI; +import rails.common.parser.ConfigurationException; +import rails.common.parser.Tag; +import rails.game.Game; +import rails.game.GameManagerI; +import rails.util.Util; + +/** + * ConfigManager is a utility class that collects all functions + * used to define and control configuration options + * + * It is a rewrite of the previouslsy used static class Config + */ + +public class ConfigManager implements ConfigurableComponentI { + + protected static Logger log; + + // STATIC CONSTANTS + + // Log4j command line option, compare log4j documentation + private static final String LOG4J_CLI_OPTION = "log4j.configuration"; + // Default Log4j configuration-file + private static final String LOG4J_CONFIG_FILE = "log4j.properties"; + + // XML setup + private static final String CONFIG_XML_DIR = "data"; + private static final String CONFIG_XML_FILE = "Properties.xml"; + private static final String CONFIG_TAG = "Properties"; + private static final String SECTION_TAG = "Section"; + private static final String ITEM_TAG = "Property"; + + // singleton configuration for ConfigManager + private static final ConfigManager instance = new ConfigManager(); + + // INSTANCE DATA + + // configuration items: replace with Multimap in Rails 2.0 + private final Map<String, List<ConfigItem>> configSections = new HashMap<String, List<ConfigItem>>(); + + // profile storage + private ConfigProfile activeProfile; + + /** + * Initial configuration immediately after startup: + * Setting of log4j and start logger + * @param test if true configurations are setup for integration tests, false for productive use + */ + private static void startlog4j() { + + // log4j settings + String log4jSelection = System.getProperty(LOG4J_CLI_OPTION); + if (!Util.hasValue(log4jSelection)) { + log4jSelection = LOG4J_CONFIG_FILE; + } + // Sets those settings + System.setProperty("log4j.configuration", log4jSelection); + System.out.println("log4j.configuration = " + log4jSelection); + + // Activate logger + log = Logger.getLogger(ConfigManager.class.getPackage().getName()); + log.debug("Activate log4j logging using configuration file = " + log4jSelection); + + } + + public static void initConfiguration(boolean test) { + startlog4j(); + + try { + List<String> directories = new ArrayList<String>(); + directories.add(CONFIG_XML_DIR); + // Find the config tag inside the the config xml file + Tag configTag = + Tag.findTopTagInFile(CONFIG_XML_FILE, directories, CONFIG_TAG); + log.debug("Opened config xml, filename = " + CONFIG_XML_FILE); + instance.configureFromXML(configTag); + } catch (ConfigurationException e) { + log.error("Configuration error in setup of " + CONFIG_XML_FILE + ", exception = " + e); + } + + if (test) { + instance.initTest(); + } else { + instance.init(); + } + } + + + /** + * @return singleton instance of ConfigManager + */ + public static ConfigManager getInstance() { + return instance; + } + + // private constructor to allow only creation of a singleton + private ConfigManager() {} + + /** + * Reads the config.xml file that defines all config items + */ + public void configureFromXML(Tag tag) throws ConfigurationException { + + // find sections + List<Tag> sectionTags = tag.getChildren(SECTION_TAG); + if (sectionTags != null) { + for (Tag sectionTag:sectionTags) { + // find name attribute + String sectionName = sectionTag.getAttributeAsString("name"); + if (!Util.hasValue(sectionName)) continue; + + // find items + List<Tag> itemTags = sectionTag.getChildren(ITEM_TAG); + if (itemTags == null || itemTags.size() == 0) continue; + List<ConfigItem> sectionItems = new ArrayList<ConfigItem>(); + for (Tag itemTag:itemTags) { + sectionItems.add(new ConfigItem(itemTag)); + } + configSections.put(sectionName, sectionItems); + } + } + + } + + + public void finishConfiguration(GameManagerI parent) + throws ConfigurationException { + // do nothing + } + + private void init() { + + // define profiles + ConfigProfile.readPredefined(); + ConfigProfile.readUser(); + + // load root and default profile + ConfigProfile.loadRoot(); + changeProfile(ConfigProfile.getDefault()); + + initVersion(); + } + + private void initTest() { + ConfigProfile.loadRoot(); + activeProfile = ConfigProfile.loadTest(); + initVersion(); + } + + private void initVersion() { + // TODO: Check if this is the right place for this + /* Load version number and develop flag */ + Properties versionNumber = new Properties(); + ConfigProfile.loadProperties(versionNumber, "version.number", true); + + String version = versionNumber.getProperty("version"); + if (Util.hasValue("version")) { + Game.setVersion(version); + } + + String develop = versionNumber.getProperty("develop"); + if (Util.hasValue(develop)) { + Game.setDevelop(develop != ""); + } + } + + String getValue(String key, String defaultValue) { + + // get value from active profile (this escalates) + String value = activeProfile.getProperty(key); + if (Util.hasValue(value)) { + return value.trim(); + } else { + return defaultValue; + } + } + + public String getActiveProfile() { + return activeProfile.getName(); + } + + public boolean IsActiveUserProfile() { + return activeProfile.getType() == ConfigProfile.Type.USER; + } + + public Set<String> getProfiles() { + return ConfigProfile.getListofProfiles(); + } + + public Map<String, List<ConfigItem>> getConfigSections() { + return configSections; + } + + public int getMaxElementsInPanels() { + int maxElements = 0; + for (List<ConfigItem> panel:configSections.values()) { + maxElements = Math.max(maxElements, panel.size()); + } + log.debug("Configuration sections with maximum elements of " + maxElements); + return maxElements; + } + + private void changeProfile(ConfigProfile profile) { + // check if profiles have been loaded + if (!profile.isLoaded()) { + profile.load(); + } + activeProfile = profile; + + // define configItems + for (List<ConfigItem> items:configSections.values()) { + for (ConfigItem item:items) { + item.setCurrentValue(getValue(item.name, null)); + } + } + } + + public void changeProfile(String profileName) { + changeProfile(ConfigProfile.getProfile(profileName)); + } + + /** + * updates the user profile according to the changes in configItems + */ + public boolean saveProfile(boolean applyInitMethods) { + for (List<ConfigItem> items:configSections.values()) { + for (ConfigItem item:items) { + // if item has changed ==> change profile and call init Method + if (item.hasChanged()) { + activeProfile.setProperty(item.name, item.getNewValue()); + log.debug("User properties for = " + item.name + " set to value = " + item.getCurrentValue()); + item.callInitMethod(applyInitMethods); + item.resetValue(); + } + } + } + return activeProfile.store(); + } + + public boolean saveNewProfile(String name, boolean applyInitMethods) { + activeProfile = activeProfile.deriveUserProfile(name); + return saveProfile(applyInitMethods); + } + + + +} diff --git a/rails/common/ConfigProfile.java b/rails/common/ConfigProfile.java new file mode 100644 index 0000000..3ad6f20 --- /dev/null +++ b/rails/common/ConfigProfile.java @@ -0,0 +1,303 @@ +package rails.common; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FilenameFilter; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.Set; + +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.io.IOCase; +import org.apache.commons.io.filefilter.SuffixFileFilter; +import org.apache.log4j.Logger; + +import rails.util.SystemOS; +import rails.util.Util; + +/** + * A profile storing configuration settings + */ + +public final class ConfigProfile { + + protected static Logger log = + Logger.getLogger(ConfigProfile.class.getPackage().getName()); + + // available profile types + public enum Type {SYSTEM, PREDEFINED, USER}; + + // Filename extension of profiles + public static final String PROFILE_EXTENSION = ".rails_profile"; + private static final String PREDEFINED_EXTENSION = ".predefined"; + + // Location of predefined profiles + private static final String PREDEFINED_FOLDER = "data/profiles/"; + + // predefined default profiles + private static final String ROOT_PROFILE = "root"; + private static final String TEST_PROFILE = "test"; + private static final String STANDARD_PROFILE = "pbem"; + + // file that stores the list of predefined profiles + private static final String LIST_OF_PROFILES = "LIST_OF_PROFILES"; + + // property key of predefined profile in user profile + private static final String PARENT_KEY = "profile.parent"; + private static final String FINAL_KEY = "profile.final"; + + // map of all profiles + private static final Map<String, ConfigProfile> profiles = new HashMap<String, ConfigProfile>(); + + // root profile + private static ConfigProfile root; + + // profile type + private final Type type; + + // profile name + private final String name; + + // profile properties + private final Properties properties = new Properties(); + + // profile loaded + private boolean loaded = false; + + // profile parent + private ConfigProfile parent = null; + + + static void loadRoot() { + root = new ConfigProfile(Type.SYSTEM, ROOT_PROFILE); + root.load(); + } + + static ConfigProfile loadTest() { + ConfigProfile test = new ConfigProfile(Type.SYSTEM, TEST_PROFILE); + test.load(); + return test; + } + + static void readPredefined() { + Properties list = new Properties(); + String filePath = PREDEFINED_FOLDER + LIST_OF_PROFILES; + loadProperties(list, filePath, true); + for (String name:list.stringPropertyNames()) { + new ConfigProfile(Type.PREDEFINED, name); + } + } + + static void readUser() { + File userFolder = SystemOS.get().getConfigurationFolder(false); + if (userFolder == null) return; + FilenameFilter filter = new SuffixFileFilter(PROFILE_EXTENSION, IOCase.SYSTEM); + for (String fileName:userFolder.list(filter)) { + new ConfigProfile(Type.USER, FilenameUtils.getBaseName(fileName)); + } + } + + static ConfigProfile getDefault() { + return profiles.get(STANDARD_PROFILE); + } + + static ConfigProfile getProfile(String name) { + return profiles.get(name); + } + + static Set<String> getListofProfiles() { + return profiles.keySet(); + } + + private ConfigProfile(Type type, String name) { + this.type = type; + this.name = name; + if (type != Type.SYSTEM) { + profiles.put(name, this); + } + } + + public Type getType() { + return type; + } + + public String getName() { + return name; + } + + boolean isLoaded() { + return loaded; + } + + boolean isFinal() { + if (!loaded) return true; + if (Util.hasValue(properties.getProperty(FINAL_KEY))) { + return Util.parseBoolean(properties.getProperty(FINAL_KEY)); + } + return false; + } + + ConfigProfile setParent(ConfigProfile parent) { + this.parent = parent; + properties.setProperty(PARENT_KEY, parent.getName()); + return this; + } + + private ConfigProfile setParent(String name) { + return setParent(profiles.get(name)); + } + + ConfigProfile getParent() { + return parent; + } + + String getProperty(String key) { + if (this == root || properties.containsKey(key)) { + return properties.getProperty(key); + } else { + return parent.getProperty(key); + } + } + + void setProperty(String key, String value) { + if (!parent.getProperty(key).equals(value)) { + properties.setProperty(key, value); + } else { + properties.remove(key); + } + } + + ConfigProfile deriveUserProfile(String name) { + ConfigProfile newProfile = new ConfigProfile(Type.USER, name); + + ConfigProfile reference; + if (isFinal()) { + // set reference for final to the own parent + reference = parent; + } else { + // otherwise to this + reference = this; + } + newProfile.setParent(reference); + + // copy properties + for (String key:properties.stringPropertyNames()){ + if (!key.equals(PARENT_KEY) && !key.equals(FINAL_KEY)) { + newProfile.setProperty(key, properties.getProperty(key)); + } + } + + return newProfile; + } + + boolean load() { + // loaded is set independent of success + loaded = true; + // ... the same for clearing the current selection + properties.clear(); + + // loading + boolean result; + if (type == Type.USER) { + result = loadUser(); + } else { + result = loadResource(); + } + + // post-load processing + // set parent according to properties or root + if (Util.hasValue(properties.getProperty(PARENT_KEY))) { + setParent(properties.getProperty(PARENT_KEY)); + } + if (parent == null) { + setParent(root); + } + + // set save directory to the working directory for predefined values + // TODO: This is a hack as workaround to be replaced in the future + if (type == Type.PREDEFINED && !Util.hasValue(properties.getProperty("save.directory"))) { + properties.put("save.directory", System.getProperty("user.dir")); + } + + // check if parent has been loaded, otherwise load parent + if (!parent.isLoaded()) { + result = result && parent.load(); + } + + return result; + } + + private boolean loadUser() { + File folder = SystemOS.get().getConfigurationFolder(false); + if (folder == null) { + return false; + } else { + File profile = new File(folder, name + PROFILE_EXTENSION); + return loadProperties(properties, profile.getAbsolutePath(), false); + } + } + + private boolean loadResource(){ + String filePath = null; + switch(type) { + case SYSTEM: + filePath = PREDEFINED_FOLDER + name; + break; + case PREDEFINED: + filePath = PREDEFINED_FOLDER + name + PREDEFINED_EXTENSION ; + break; + } + return loadProperties(properties, filePath, true); + } + + boolean store() { + if (type != Type.USER) return false; + loaded = true; + File folder = SystemOS.get().getConfigurationFolder(true); + if (folder == null) { + return false; + } else { + File profile = new File(folder, name + PROFILE_EXTENSION); + return storeProperties(properties, profile); + } + } + + static boolean loadProperties(Properties properties, String filePath, boolean resource) { + try { + log.info("Loading properties from file " + filePath); + InputStream inFile; + if (resource) { + inFile = ConfigProfile.class.getClassLoader().getResourceAsStream(filePath); + } else { + inFile = new FileInputStream(filePath); + } + properties.load(inFile); + } catch (Exception e) { + log.error(e + " whilst loading properties file " + + filePath, e); + return false; + } + return true; + } + + static boolean storeProperties(Properties properties, File file) { + boolean result = true; + try { + properties.store(new FileOutputStream(file), "Automatically generated, do not edit"); + log.info("Storing properties to file " + file.getAbsolutePath()); + } catch (IOException e) { + log.error(e + " whilst storing properties file " + + file.getAbsolutePath()); + result = false; + } + return result; + } + + +} + + diff --git a/rails/common/LocalText.java b/rails/common/LocalText.java index 88d93f4..6ea92e3 100644 --- a/rails/common/LocalText.java +++ b/rails/common/LocalText.java @@ -9,7 +9,6 @@ import java.util.ResourceBundle; import org.apache.log4j.Logger; -import rails.common.parser.Config; import rails.util.Util; public class LocalText extends ResourceBundle { diff --git a/rails/common/MoneyFormatter.java b/rails/common/MoneyFormatter.java index 30326a7..127d5c8 100644 --- a/rails/common/MoneyFormatter.java +++ b/rails/common/MoneyFormatter.java @@ -1,7 +1,6 @@ /* $Header: /Users/blentz/rails_rcs/cvs/18xx/rails/util/Format.java,v 1.3 2008/06/04 19:00:39 evos Exp $*/ package rails.common; -import rails.common.parser.Config; import rails.util.Util; public class MoneyFormatter { diff --git a/rails/common/parser/Config.java b/rails/common/parser/Config.java deleted file mode 100644 index 296fcb3..0000000 --- a/rails/common/parser/Config.java +++ /dev/null @@ -1,606 +0,0 @@ -/* $Header: /Users/blentz/rails_rcs/cvs/18xx/rails/util/Config.java,v 1.13 2010/06/24 21:48:08 stefanfrey Exp $*/ -package rails.common.parser; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Properties; - -import org.apache.log4j.Logger; - -import rails.game.Game; -import rails.game.GameManager; -import rails.util.Util; - -/** - * This is a simple utility class with a collection of static functions to load - * a property object from a property file, to retrieve a particular value from - * the property file etc. - * - * @author Ramiah Bala, - * @author Erik Vos - * @author Stefan Frey - * @version 2.0 - */ -public final class Config { - - protected static Logger log; - - /** Commandline options */ - private static final String CONFIGFILE_CMDLINE = "configfile"; - private static final String PROFILE_CMDLINE = "profile"; - - /** XML setup */ - private static final String CONFIG_XML_DIR = "data"; - private static final String CONFIG_XML_FILE = "Properties.xml"; - private static final String CONFIG_TAG = "Properties"; - private static final String SECTION_TAG = "Section"; - private static final String ITEM_TAG = "Property"; - - /** Log 4j configuration */ - private static final String LOG4J_CONFIG_FILE = "log4j.properties"; - - /** Rails profile configurations */ - private static String defaultProfilesFile = "data/profiles/default.profiles"; - private static Properties defaultProfiles = new Properties(); - private static String userProfilesFile = "user.profiles"; - private static Properties userProfiles = new Properties(); - private static boolean profilesLoaded = false; - private static String DEFAULT_PROFILE_SELECTION = "default"; // can be overwritten - private static final String ROOT_PROFILE_SELECTION = ".root"; // used for the 3-tier structure: ROOT-DEFAULT-USER - private static final String TEST_PROFILE_SELECTION = ".test"; // used as default profile for integration tests - private static final String STANDARD_PROFILE_SELECTION = "user"; - private static final String DEFAULTPROFILE_PROPERTY = "default.profile"; - private static final String PROFILENAME_PROPERTY = "profile.name"; - - /** selected profile */ - private static String selectedProfile; - private static boolean legacyConfigFile; - - /** properties storage. */ - private static Properties rootProperties = null; - private static Properties defaultProperties = null; - private static Properties userProperties = new Properties(); - private static boolean propertiesLoaded = false; - - /** Map that holds the panel, which contains config items */ - private static Map<String, List<ConfigItem>> configSections = null; - - /** - * Hidden constructor, the class is never instantiated, everything is static - */ - private Config() {} - - /** - * Reads the config.xml file that defines all config items - */ - public static void readConfigSetupXML() { - List<String> directories = new ArrayList<String>(); - directories.add(CONFIG_XML_DIR); - try { - // Find the config tag inside the the config xml file - Tag configTag = - Tag.findTopTagInFile(CONFIG_XML_FILE, directories, CONFIG_TAG); - log.debug("Opened config xml, filename = " + CONFIG_XML_FILE); - - // define sections - configSections = new LinkedHashMap<String, List<ConfigItem>>(); - - // find sections - List<Tag> sectionTags = configTag.getChildren(SECTION_TAG); - if (sectionTags != null) { - for (Tag sectionTag:sectionTags) { - // find name attribute - String sectionName = sectionTag.getAttributeAsString("name"); - if (!Util.hasValue(sectionName)) continue; - - // find items - List<Tag> itemTags = sectionTag.getChildren(ITEM_TAG); - if (itemTags == null || itemTags.size() == 0) continue; - List<ConfigItem> sectionItems = new ArrayList<ConfigItem>(); - for (Tag itemTag:itemTags) { - sectionItems.add(new ConfigItem(itemTag)); - } - configSections.put(sectionName, sectionItems); - } - } - - } catch (ConfigurationException e) { - log.error("Configuration error in setup of " + CONFIG_XML_FILE + ", exception = " + e); - } - } - - public static Map<String, List<ConfigItem>> getConfigSections() { - if (configSections == null) { - readConfigSetupXML(); - } - log.debug("Configuration setup = " + configSections); - return configSections; - } - - public static int getMaxElementsInPanels() { - int maxElements = 0; - for (List<ConfigItem> panel:configSections.values()) { - maxElements = Math.max(maxElements, panel.size()); - } - log.debug("Configuration sections with maximum elements of " + maxElements); - return maxElements; - } - - /** - * updates the profile according to the changes in configitems - */ - public static void updateProfile(boolean applyInitMethods) { - for (List<ConfigItem> items:configSections.values()) { - for (ConfigItem item:items) { - if (!item.hasNewValue()) continue; - if (item.getNewValue().equals(defaultProperties.get(item.name))) { - userProperties.remove(item.name); - continue; - } - userProperties.setProperty(item.name, item.getNewValue()); - item.callInitMethod(applyInitMethods); - log.debug("Changed property name = " + item.name + " to value = " + item.getNewValue()); - item.setNewValue(null); - } - } - } - - /** - * reverts all changes in configitems - */ - public static void revertProfile() { - for (List<ConfigItem> items:configSections.values()) { - for (ConfigItem item:items) { - item.setNewValue(null); - } - } - } - - /** - * First tries to return {key}.{gameName}, if undefined returns {key} - */ - public static String getGameSpecific(String key) { - return Config.getSpecific(key, GameManager.getInstance().getGameName()); - } - - /** - * First tries to return {key}.{appendix}, if undefined returns {key} - */ - public static String getSpecific(String key, String appendix) { - String value = Config.get(key + "." + appendix); - if (value == "") { - value = Config.get(key); - } - return value; - } - - public static String get(String key) { - return get(key, ""); - } - - public static String get(String key, String defaultValue) { - if (defaultProperties.isEmpty() || !propertiesLoaded) { - initialLoad(); - } - if (userProperties.containsKey(key)) return userProperties.getProperty(key).trim(); - if (defaultProperties.containsKey(key)) return defaultProperties.getProperty(key).trim(); - if (rootProperties.containsKey(key)) return rootProperties.getProperty(key).trim(); - - return defaultValue; - } - - - /** - * save active Profile - */ - public static boolean saveActiveProfile() { - String filepath = userProfiles.getProperty(selectedProfile); - if (Util.hasValue(filepath)) { - return storePropertyFile(userProperties, filepath); - } else { - return false; - } - } - - /** - * change active Profile - */ - public static boolean changeActiveProfile(String profileName) { - readConfigSetupXML(); - loadProfile(profileName); - selectedProfile = profileName; - return true; - } - - /** - * create new profile - */ - public static boolean createUserProfile(String profileName, String defaultProfile) { - userProperties = new Properties(); - defaultProperties = new Properties(); - - // add to list of user profiles - userProfiles.setProperty(profileName, ""); - - // define and load default profile - String defaultConfigFile = defaultProfiles.getProperty(defaultProfile); - userProperties.setProperty(PROFILENAME_PROPERTY, profileName); - userProperties.setProperty(DEFAULTPROFILE_PROPERTY, defaultProfile); - loadPropertyFile(defaultProperties, defaultConfigFile, true); - setSaveDirDefaults(); - - selectedProfile = profileName; - return true; - } - - - private static Map<String, String> convertProperties(Properties properties, boolean visibleOnly) { - Map<String, String> converted = new HashMap<String, String>(); - for (Object key:properties.keySet()) { - if (visibleOnly && ((String)key).substring(0,1).equals(".")) continue; - converted.put((String) key, (String) properties.get(key)); - } - return converted; - } - - /** - * get all default profiles - */ - public static List<String> getDefaultProfiles(boolean visibleOnly) { - List<String> profiles = new ArrayList<String>(convertProperties(defaultProfiles, visibleOnly).keySet()); - Collections.sort(profiles); - return profiles; - } - - public static String getDefaultProfileSelection() { - return DEFAULT_PROFILE_SELECTION; - } - - /** - * get all user profiles - */ - public static List<String> getUserProfiles() { - List<String> profiles = new ArrayList<String>(convertProperties(userProfiles, true).keySet()); - Collections.sort(profiles); - return profiles; - } - - /** - * get all (visible default + user) profiles - */ - public static List<String> getAllProfiles() { - List<String> profiles = getDefaultProfiles(true); - profiles.addAll(getUserProfiles()); - return profiles; - } - - /** - * checks if profile is default profile - */ - public static boolean isDefaultProfile(String profileName) { - return !(defaultProfiles.get(profileName) == null); - } - - /** - * returns name of (active) default profile - */ - public static String getDefaultProfileName() { - return userProperties.getProperty(DEFAULTPROFILE_PROPERTY); - } - - /** - * returns name of active profile - */ - public static String getActiveProfileName() { - return selectedProfile; - } - - /** - * returns true if legacy configfile is used - */ - public static boolean isLegacyConfigFile() { - return legacyConfigFile; - } - - /** - * sets filename for an active profile (and store list of profiles) - * @return false if list of profiles cannot be stored - */ - public static boolean setActiveFilepath(String filepath) { - userProfiles.setProperty(selectedProfile, filepath); - return storePropertyFile(userProfiles, userProfilesFile); - } - - /** - * returns filename of active profile, (null if undefined or default profile) - */ - public static String getActiveFilepath() { - return userProfiles.getProperty(selectedProfile); - } - - /** - * @return if user location is defined - */ - public static boolean isFilePathDefined() { - return Util.hasValue(userProfiles.getProperty(selectedProfile)); - } - - - /** - * activates settings used for testing - */ - public static void setConfigTest() { - /* - * Set the system property that tells log4j to use this file. (Note: - * this MUST be done before updating Config) - */ - String log4jSelection = System.getProperty("log4j.configuration"); - if (!Util.hasValue(log4jSelection)) { - log4jSelection = LOG4J_CONFIG_FILE; - } - System.setProperty("log4j.configuration", log4jSelection); - System.out.println("log4j.configuration = " + log4jSelection); - - // delayed setting of logger - log = Logger.getLogger(Config.class.getPackage().getName()); - - // define settings for testing - legacyConfigFile = false; - DEFAULT_PROFILE_SELECTION = TEST_PROFILE_SELECTION; - selectedProfile = null; - - initialLoad(); - } - - - /** - * activates configuration settings based on default settings - */ - public static void setConfigSelection() { - /* - * Set the system property that tells log4j to use this file. (Note: - * this MUST be done before updating Config) - */ - String log4jSelection = System.getProperty("log4j.configuration"); - if (!Util.hasValue(log4jSelection)) { - log4jSelection = LOG4J_CONFIG_FILE; - } - System.setProperty("log4j.configuration", log4jSelection); - System.out.println("log4j.configuration = " + log4jSelection); - - // delayed setting of logger - log = Logger.getLogger(Config.class.getPackage().getName()); - - /* - * Check if the profile has been set from the command line - * to do this is adding an option to the java command: -Dprofile=<profile-name> - */ - String configSelection = System.getProperty(PROFILE_CMDLINE); - System.out.println("Cmdline profile selection = " + configSelection); - - legacyConfigFile = false; - if (configSelection == null) { - /* - * Check if the property file has been set on the command line. The way - * to do this is adding an option to the java command: -Dconfigfile=<property-filename> - * - * This is for legacy reasons only - */ - configSelection = System.getProperty(CONFIGFILE_CMDLINE); - - if (Util.hasValue(configSelection)) { - System.out.println("Cmdline configfile selection (legacy!) = " + configSelection); - ... [truncated message content] |
From: Erik V. <ev...@us...> - 2012-02-23 14:37:48
|
LocalisedText.properties | 1 rails/ui/swing/GameUIManager.java | 48 ++++++++++++++++++++++++++++++-------- rails/ui/swing/GridPanel.java | 32 +++++++++++++++++++++++++ rails/ui/swing/StatusWindow.java | 18 ++++++++++++-- 4 files changed, 87 insertions(+), 12 deletions(-) New commits: commit 2f42c466d42059702851c5fc5130a732ccfd73c3 Author: Erik Vos <eri...@xs...> Date: Thu Feb 23 15:37:14 2012 +0100 Added StatusWindow File menu action to dump the (transposed) contents of the GameStatus panel into a semicolon-separated text file with ".status" extension. Any tooltips (with additional info) are included between braces. diff --git a/LocalisedText.properties b/LocalisedText.properties index ac4899b..ce07410 100644 --- a/LocalisedText.properties +++ b/LocalisedText.properties @@ -616,6 +616,7 @@ SAVE_AND_APPLY=Save/Apply SAVEAS=Save As ... SaveDialogTitle=Save Game. Info: Report of current players action copied to Clipboard. SaveFailed=Save failed, reason: {0} +SaveGameStatus=Save game status Select=Select SelectCompanyToMergeMinorInto=Select major company to merge minor {0} into SelectLoansToRepay=Select number of loans of {0} to repay diff --git a/rails/ui/swing/GameUIManager.java b/rails/ui/swing/GameUIManager.java index 7e59194..1c25557 100644 --- a/rails/ui/swing/GameUIManager.java +++ b/rails/ui/swing/GameUIManager.java @@ -1,13 +1,12 @@ package rails.ui.swing; -import java.awt.Font; -import java.awt.Rectangle; -import java.awt.Toolkit; +import java.awt.*; import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.StringSelection; import java.io.*; import java.text.SimpleDateFormat; import java.util.*; +import java.util.List; import javax.swing.*; import javax.swing.plaf.FontUIResource; @@ -100,7 +99,7 @@ public class GameUIManager implements DialogOwner { Logger.getLogger(GameUIManager.class.getPackage().getName()); private SplashWindow splashWindow = null; - + public GameUIManager() { } @@ -109,7 +108,7 @@ public class GameUIManager implements DialogOwner { this.splashWindow = splashWindow; splashWindow.notifyOfStep(SplashWindow.STEP_INIT_UI); - + instance = this; this.gameManager = gameManager; uiHints = gameManager.getUIHints(); @@ -207,7 +206,7 @@ public class GameUIManager implements DialogOwner { } else { reportWindow = new ReportWindowDynamic(this); } - + orWindow = new ORWindow(this, splashWindow); orUIManager = orWindow.getORUIManager(); @@ -250,7 +249,7 @@ public class GameUIManager implements DialogOwner { public void startLoadedGame() { gameUIInit(false); // false indicates reload - + splashWindow.notifyOfStep(SplashWindow.STEP_INIT_LOADED_GAME); processAction(new NullAction(NullAction.START_GAME)); statusWindow.setGameActions(); @@ -1019,6 +1018,34 @@ public class GameUIManager implements DialogOwner { } + public void saveGameStatus() { + + List<String> status = statusWindow.getGameStatus().getTextContents(); + + JFileChooser jfc = new JFileChooser(); + String filename = saveDirectory + "/" + savePrefix + "_" + + saveDateTimeFormat.format(new Date())+ ".status"; + + File proposedFile = new File(filename); + jfc.setSelectedFile(proposedFile); + + if (jfc.showSaveDialog(statusWindow) == JFileChooser.APPROVE_OPTION) { + File selectedFile = jfc.getSelectedFile(); + } + + try { + PrintWriter pw = new PrintWriter(filename); + + for (String line : status) pw.println(line) ; + + pw.close(); + + } catch (IOException e) { + log.error("Save failed", e); + DisplayBuffer.add(LocalText.getText("SaveFailed", e.getMessage())); + } + } + public void setSaveDirectory(String saveDirectory) { this.saveDirectory = saveDirectory; } @@ -1131,7 +1158,7 @@ public class GameUIManager implements DialogOwner { instance.initFontSettings(); instance.updateWindowsLookAndFeel(); } - + /** * Only set frame directly to visible if the splash phase is already over. * Otherwise, the splash framework remembers this visibility request and @@ -1159,7 +1186,7 @@ public class GameUIManager implements DialogOwner { } /** - * called when the splash process is completed + * called when the splash process is completed * (and visibility changes are not to be deferred any more) */ public void notifyOfSplashFinalization() { @@ -1174,9 +1201,10 @@ public class GameUIManager implements DialogOwner { public void packAndApplySizing(JFrame frame) { final JFrame finalFrame = frame; SwingUtilities.invokeLater(new Thread() { + @Override public void run() { finalFrame.pack(); - + WindowSettings ws = getWindowSettings(); Rectangle bounds = ws.getBounds(finalFrame); if (bounds.x != -1 && bounds.y != -1) finalFrame.setLocation(bounds.getLocation()); diff --git a/rails/ui/swing/GridPanel.java b/rails/ui/swing/GridPanel.java index ddc4582..a835007 100644 --- a/rails/ui/swing/GridPanel.java +++ b/rails/ui/swing/GridPanel.java @@ -16,6 +16,7 @@ import rails.game.*; import rails.game.model.ModelObject; import rails.game.state.BooleanState; import rails.ui.swing.elements.*; +import rails.util.Util; public abstract class GridPanel extends JPanel implements ActionListener, KeyListener { @@ -166,6 +167,37 @@ implements ActionListener, KeyListener { highlightedComps.clear(); } + /** Returns a string array, each element of which contains the text contents + * of one row, separated by semicolons. + */ + public List<String> getTextContents () { + + List<String> result = new ArrayList<String>(32); + StringBuilder b; + String text, tip; + if (fields == null || fields.length == 0) return result; + + for (int i=0; i<fields.length; i++) { + b = new StringBuilder(); + for (int j=0; j<fields[i].length; j++) { + if (j > 0) b.append(";"); + if (fields[i][j] instanceof JLabel) { + text = ((JLabel)fields[i][j]).getText(); + b.append (text == null ? "" : text); + if (fields[i][j] instanceof Field) { + tip = fields[i][j].getToolTipText(); + if (Util.hasValue(tip)) { + b.append("{").append(tip).append("}"); + } + } + } + } + result.add(b.toString().replaceAll("</?html>", "").replaceAll("<br>",",").replaceAll(" x ", "x")); + } + + return result; + } + public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_F1) { HelpWindow.displayHelp(GameManager.getInstance().getHelp()); diff --git a/rails/ui/swing/StatusWindow.java b/rails/ui/swing/StatusWindow.java index 48ee3bd..c0b6640 100644 --- a/rails/ui/swing/StatusWindow.java +++ b/rails/ui/swing/StatusWindow.java @@ -1,10 +1,10 @@ /* $Header: /Users/blentz/rails_rcs/cvs/18xx/rails/ui/swing/StatusWindow.java,v 1.46 2010/06/15 20:16:54 evos Exp $*/ package rails.ui.swing; -import java.awt.*; +import java.awt.BorderLayout; +import java.awt.Color; import java.awt.event.*; import java.util.*; -import java.util.List; import javax.swing.*; @@ -34,6 +34,8 @@ KeyListener, ActionPerformer { protected static final String AUTOSAVELOAD_CMD = "AutoSaveLoad"; + protected static final String SAVESTATUS_CMD = "SaveGameStatus"; + protected static final String EXPORT_CMD = "Export"; protected static final String UNDO_CMD = "Undo"; @@ -139,6 +141,15 @@ KeyListener, ActionPerformer { menuItem.setEnabled(true); fileMenu.add(menuItem); + menuItem = new JMenuItem(LocalText.getText("SaveGameStatus")); + menuItem.setActionCommand(SAVESTATUS_CMD); + menuItem.setMnemonic(KeyEvent.VK_G); + menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_G, + ActionEvent.ALT_MASK)); + menuItem.addActionListener(this); + menuItem.setEnabled(true); + fileMenu.add(menuItem); + // export menu item // exportItem = new ActionMenuItem(LocalText.getText("EXPORT")); // exportItem.setActionCommand(EXPORT_CMD); @@ -148,6 +159,7 @@ KeyListener, ActionPerformer { // fileMenu.add(exportItem); // fileMenu.addSeparator(); + menuItem = new JMenuItem(LocalText.getText("QUIT")); menuItem.setActionCommand(QUIT_CMD); menuItem.setMnemonic(KeyEvent.VK_Q); @@ -643,6 +655,8 @@ KeyListener, ActionPerformer { gameUIManager.configWindow.setVisible(((JMenuItem) actor.getSource()).isSelected()); } else if (command.equals(AUTOSAVELOAD_CMD)) { gameUIManager.autoSaveLoadGame(); + } else if (command.equals(SAVESTATUS_CMD)) { + gameUIManager.saveGameStatus(); } else if (executedAction == null) { ; } else if (executedAction instanceof GameAction) { |
From: Erik V. <ev...@us...> - 2012-02-23 13:25:24
|
rails/game/Game.java | 23 +++++++++++------------ rails/util/Util.java | 3 ++- 2 files changed, 13 insertions(+), 13 deletions(-) New commits: commit 96df44d6455bdc191cc5a19d794d9a7f2dc0260c Author: Erik Vos <eri...@xs...> Date: Thu Feb 23 14:23:15 2012 +0100 Fixed JUnit testing issue caused by NDC removal. The initial "GameIs" report message has been moved from the Game constructor to its setup() method. Also fixed a problem in Util.joinWithDelimiter that has surfaced by adding a new usage to display tile colour restrictions in LayTile.toString(). diff --git a/rails/game/Game.java b/rails/game/Game.java index a882493..393040f 100644 --- a/rails/game/Game.java +++ b/rails/game/Game.java @@ -14,7 +14,7 @@ import rails.game.action.PossibleAction; import rails.util.GameFileIO; public class Game { - // the correct version number and develop status + // the correct version number and develop status // is set during initialLoad in Config class private static String version = "unknown"; private static boolean develop = false; @@ -22,11 +22,11 @@ public class Game { public static void setVersion(String version) { Game.version = version; } - + public static String getVersion() { return version; } - + public static String getFullVersion() { if (develop) { return version + "+"; @@ -34,17 +34,17 @@ public class Game { return version; } } - + public static void setDevelop(boolean develop) { Game.develop = develop; } - + public static boolean getDevelop() { return develop; } - + // in the following the Game objects are defined - + /** The component Manager */ protected GameManager gameManager; protected CompanyManagerI companyManager; @@ -85,11 +85,6 @@ public class Game { this.players = players; - - log.info("========== Start of rails.game " + name + " =========="); - log.info("Rails version "+version); - ReportBuffer.add(LocalText.getText("GameIs", name)); - } public String start() { @@ -118,6 +113,10 @@ public class Game { bank = gfp.getBank(); gameManager = gfp.getGameManager(); + log.info("========== Start of rails.game " + name + " =========="); + log.info("Rails version "+version); + ReportBuffer.add(LocalText.getText("GameIs", name)); + /* * Initializations that involve relations between components can * only be done after all XML has been processed. diff --git a/rails/util/Util.java b/rails/util/Util.java index e558719..25c716a 100644 --- a/rails/util/Util.java +++ b/rails/util/Util.java @@ -35,9 +35,10 @@ public final class Util { } public static String joinWithDelimiter (String[] sa, String delimiter) { + if (sa == null || sa.length == 0) return ""; StringBuilder b = new StringBuilder(); for (String s : sa) { - if (b.length() > 0) b.append(delimiter); + if (Util.hasValue(delimiter) && b.length() > 0) b.append(delimiter); b.append(s); } return b.toString(); |
From: Erik V. <ev...@us...> - 2012-02-21 22:26:28
|
data/1835/CompanyManager.xml | 3 --- rails/game/special/SpecialTileLay.java | 2 +- rails/ui/swing/ORUIManager.java | 11 ++++++++++- 3 files changed, 11 insertions(+), 5 deletions(-) New commits: commit d34b91f49c0ddbb9ffab3273bbe5af025652bfdd Author: Erik Vos <eri...@xs...> Date: Tue Feb 21 23:25:10 2012 +0100 Always address the company president when a home token must be relaid. This is a provisional fix for the issue that arises when in 1835 the BA has started but not yet operated, and another company uses the PfB to lay a green tile in the BA home hex L6. In this case the BA president must lay the home token in the turn of that other company. The fix is to always address the token company president instead of the acting player during a token relay. WARNING: this fix breaks the intended client/server architecture, because the UI is not supposed to have direct access to the president's identity, as this is a state variable. So this is a provisional fix only. diff --git a/data/1835/CompanyManager.xml b/data/1835/CompanyManager.xml index 58db0e2..baa4fd8 100644 --- a/data/1835/CompanyManager.xml +++ b/data/1835/CompanyManager.xml @@ -171,9 +171,6 @@ <Company name="BA" longname="Badische Eisenbahn" type="Major" startspace="B4" available="no" tokens="2" fgColour="FFFFFF" bgColour="808000" alias="Bad"> <Home hex="L6" city="0"/> - <BaseTokens> - <HomeBase lay="firstOR"/> - </BaseTokens> <Certificate type="President" shares="2"/> <Certificate shares="1" number="6"/> <Certificate shares="2" number="1"/> diff --git a/rails/game/special/SpecialTileLay.java b/rails/game/special/SpecialTileLay.java index 3e1dea6..859f7fe 100644 --- a/rails/game/special/SpecialTileLay.java +++ b/rails/game/special/SpecialTileLay.java @@ -143,7 +143,7 @@ public class SpecialTileLay extends SpecialProperty { public String toString() { return "SpecialTileLay comp=" + originalCompany.getName() + " hex=" + locationCodes - + " colour="+tileColours + + " colour="+Util.joinWithDelimiter(tileColours, ",") + " extra=" + extra + " cost=" + free + " connected=" + connected; } diff --git a/rails/ui/swing/ORUIManager.java b/rails/ui/swing/ORUIManager.java index ea2d561..e3b7a3a 100644 --- a/rails/ui/swing/ORUIManager.java +++ b/rails/ui/swing/ORUIManager.java @@ -970,7 +970,16 @@ public class ORUIManager implements DialogOwner { String selected = (String) JOptionPane.showInputDialog(orWindow, LocalText.getText("SelectStationForToken", - action.getPlayerName(), + //action.getPlayerName(), + /* In some cases, it's not the acting player that must take this action, + * but it's always the president. + * TODO WARNING: THE NEXT LINE BREAKS THE CLIENT/SERVER SEPARATION + * so this is a provisional fix only. + * It is for 1835, and intends to address the BA president if the BA home token + * must be laid in case another company, having the turn, lays a green tile in L6 + * using the PfB when the BA has started but not yet operated. + */ + company.getPresident().getName(), hex.getName(), company.getName() ), |