From: <ev...@us...> - 2010-08-10 19:39:06
|
Revision: 1374 http://rails.svn.sourceforge.net/rails/?rev=1374&view=rev Author: evos Date: 2010-08-10 19:39:00 +0000 (Tue, 10 Aug 2010) Log Message: ----------- Fixed bug that allowed 1835 share selling of unfloated companies. Modified Paths: -------------- trunk/18xx/LocalisedText.properties trunk/18xx/rails/game/ShareSellingRound.java trunk/18xx/rails/game/StockRound.java trunk/18xx/rails/game/TreasuryShareRound.java trunk/18xx/rails/game/specific/_1835/PrussianFormationRound.java Modified: trunk/18xx/LocalisedText.properties =================================================================== --- trunk/18xx/LocalisedText.properties 2010-08-08 15:20:50 UTC (rev 1373) +++ trunk/18xx/LocalisedText.properties 2010-08-10 19:39:00 UTC (rev 1374) @@ -495,6 +495,7 @@ RouteAwareness=support for tile and token lays RunsWithBorrowedTrain={0} runs with a borrowed {1}-train and must withhold revenue RustsTrains=Rusts {0}-trains +SaleNotAllowed=Selling shares of company {0} is not allowed SAVE=Save SAVEAS=Save As ... SaveFailed=Save failed, reason: {0} Modified: trunk/18xx/rails/game/ShareSellingRound.java =================================================================== --- trunk/18xx/rails/game/ShareSellingRound.java 2010-08-08 15:20:50 UTC (rev 1373) +++ trunk/18xx/rails/game/ShareSellingRound.java 2010-08-10 19:39:00 UTC (rev 1374) @@ -108,8 +108,8 @@ */ for (PublicCompanyI company : companyManager.getAllPublicCompanies()) { - // Can't sell shares that have no price - if (!company.hasStarted()) continue; + // Check if shares of this company can be sold at all + if (!mayPlayerSellShareOfCompany(company)) continue; share = maxShareToSell = playerPortfolio.getShare(company); if (maxShareToSell == 0) continue; @@ -231,6 +231,12 @@ 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"); Modified: trunk/18xx/rails/game/StockRound.java =================================================================== --- trunk/18xx/rails/game/StockRound.java 2010-08-08 15:20:50 UTC (rev 1373) +++ trunk/18xx/rails/game/StockRound.java 2010-08-10 19:39:00 UTC (rev 1374) @@ -358,13 +358,9 @@ */ for (PublicCompanyI company : companyManager.getAllPublicCompanies()) { - // Can't sell shares that have no price - if (!company.hasStarted() || !company.hasStockPrice()) continue; + // Check if shares of this company can be sold at all + if (!mayPlayerSellShareOfCompany(company)) continue; - // In some games, can't sell shares if not operated - if (company.mustHaveOperatedToTradeShares() - && !company.hasOperated()) continue; - share = maxShareToSell = playerPortfolio.getShare(company); if (maxShareToSell == 0) continue; @@ -957,6 +953,12 @@ 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"); @@ -1395,6 +1397,19 @@ return true; } + public boolean mayPlayerSellShareOfCompany(PublicCompanyI company) { + + // Can't sell shares that have no price + if (!company.hasStarted() || !company.hasStockPrice()) return false; + + // In some games, can't sell shares if not operated + if (noSaleIfNotOperated() + && !company.hasOperated()) return false; + + return true; + } + + /** * Can the current player do any buying? * @@ -1408,10 +1423,10 @@ protected boolean isPlayerOverLimits(Player player) { return (isPlayerOverLimitsDetail(player) != null); } - + protected String isPlayerOverLimitsDetail(Player player) { StringBuffer violations = new StringBuffer(); - + // Over the total certificate hold Limit? if (player.getPortfolio().getCertificateCount() > gameManager.getPlayerCertificateLimit(player)) { violations.append(LocalText.getText("ExceedCertificateLimitTotal", @@ -1423,7 +1438,7 @@ // Over the hold limit of any company? for (PublicCompanyI company : companyManager.getAllPublicCompanies()) { if (company.hasStarted() && company.hasStockPrice() - && !checkAgainstHoldLimit(player, company, 0)) { + && !checkAgainstHoldLimit(player, company, 0)) { violations.append(LocalText.getText("ExceedCertificateLimitCompany", company.getName(), player.getPortfolio().getShare(company), Modified: trunk/18xx/rails/game/TreasuryShareRound.java =================================================================== --- trunk/18xx/rails/game/TreasuryShareRound.java 2010-08-08 15:20:50 UTC (rev 1373) +++ trunk/18xx/rails/game/TreasuryShareRound.java 2010-08-10 19:39:00 UTC (rev 1374) @@ -71,7 +71,8 @@ possibleActions.clear(); - if (!operatingCompany.hasOperated()) return true; + if (operatingCompany.mustHaveOperatedToTradeShares() + && !operatingCompany.hasOperated()) return true; if (!hasSold.booleanValue()) setBuyableCerts(); if (!hasBought.booleanValue()) setSellableCerts(); Modified: trunk/18xx/rails/game/specific/_1835/PrussianFormationRound.java =================================================================== --- trunk/18xx/rails/game/specific/_1835/PrussianFormationRound.java 2010-08-08 15:20:50 UTC (rev 1373) +++ trunk/18xx/rails/game/specific/_1835/PrussianFormationRound.java 2010-08-10 19:39:00 UTC (rev 1374) @@ -1,8 +1,6 @@ package rails.game.specific._1835; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; +import java.util.*; import rails.common.GuiDef; import rails.game.*; @@ -23,7 +21,7 @@ private boolean forcedStart; private boolean mergePr; private boolean forcedMerge; - + private List<CompanyI> foldablePrePrussians; private enum Step { @@ -36,7 +34,7 @@ private static String PR_ID = GameManager_1835.PR_ID; private static String M2_ID = GameManager_1835.M2_ID; - + public PrussianFormationRound (GameManagerI gameManager) { super (gameManager); @@ -60,7 +58,7 @@ +" mergePr="+mergePr+" forcedMerge="+forcedMerge); step = startPr ? Step.START : Step.MERGE; - + if (step == Step.START) { m2 = companyManager.getPublicCompany(M2_ID); setCurrentPlayer(m2.getPresident()); @@ -70,7 +68,7 @@ step = Step.MERGE; } } - + if (step == Step.MERGE) { startingPlayer = ((GameManager_1835)gameManager).getPrussianFormationStartingPlayer(); @@ -116,9 +114,9 @@ } else if (step == Step.MERGE) { possibleActions.add(new FoldIntoPrussian(foldablePrePrussians)); - + } else if (step == Step.DISCARD_TRAINS) { - + if (prussian.getNumberOfTrains() > prussian.getTrainLimit(getCurrentPhase().getIndex())) { possibleActions.add(new DiscardTrain(prussian, prussian.getPortfolio().getUniqueTrains(), true)); @@ -149,14 +147,14 @@ } } } - + @Override protected boolean processGameSpecificAction(PossibleAction action) { if (action instanceof FoldIntoPrussian) { FoldIntoPrussian a = (FoldIntoPrussian) action; - + if (step == Step.START) { if (!startPrussian(a)) { finishRound(); @@ -164,29 +162,29 @@ step = Step.MERGE; findNextMergingPlayer(false); } - + } else if (step == Step.MERGE) { - + mergeIntoPrussian (a); - + } - + return true; - + } else if (action instanceof DiscardTrain) { - + discardTrain ((DiscardTrain) action); return true; - + } else { return false; } } protected boolean findNextMergingPlayer(boolean skipCurrentPlayer) { - + while (true) { - + if (skipCurrentPlayer) { setNextPlayer(); if (getCurrentPlayer() == startingPlayer) { @@ -198,13 +196,13 @@ return false; } } - + setFoldablePrePrussians(); if (!foldablePrePrussians.isEmpty()) return true; skipCurrentPlayer = true; } } - + private boolean startPrussian (FoldIntoPrussian action) { // Validate @@ -237,9 +235,9 @@ return folding; } - + private void executeStartPrussian (boolean display) { - + prussian.start(); String message = LocalText.getText("START_MERGED_COMPANY", PR_ID, @@ -259,7 +257,7 @@ List<CompanyI> folded = action.getFoldedCompanies(); boolean folding = folded != null && !folded.isEmpty(); - + while (folding) { // TODO Some validation needed break; @@ -277,7 +275,7 @@ // Execute if (folding) executeExchange (folded, false, false); - + findNextMergingPlayer(true); return folding; @@ -320,11 +318,11 @@ company.getName()); ReportBuffer.add(message); if (display) DisplayBuffer.add (message); - + if (company instanceof PublicCompanyI) { PublicCompanyI minor = (PublicCompanyI) company; - + // Replace the home token BaseToken token = (BaseToken) minor.getTokens().get(0); City city = (City) token.getHolder(); @@ -337,15 +335,15 @@ city.getName()); ReportBuffer.add(message); if (display) DisplayBuffer.add (message); - + prussian.layBaseToken(hex, 0); } - + // Move any cash if (minor.getCash() > 0) { new CashMove (minor, prussian, minor.getCash()); } - + // Move any trains List<TrainI> trains = new ArrayList<TrainI> (minor.getPortfolio().getTrainList()); for (TrainI train : trains) { @@ -411,24 +409,26 @@ // This always finished this type of round finishRound(); - + return true; } + @Override protected void finishRound() { if (prussian.hasStarted()) prussian.checkPresidency(); + prussian.setOperated(); // To allow immediate share selling super.finishRound(); } public static boolean prussianIsComplete(GameManagerI gameManager) { - + for (PublicCompanyI company : gameManager.getAllPublicCompanies()) { if (!company.getTypeName().equalsIgnoreCase("Minor")) continue; - if (!company.isClosed()) return false; + if (!company.isClosed()) return false; } return true; } - + @Override public String toString() { return "1835 PrussianFormationRound"; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |