From: <ev...@us...> - 2010-10-12 18:50:39
|
Revision: 1449 http://rails.svn.sourceforge.net/rails/?rev=1449&view=rev Author: evos Date: 2010-10-12 18:50:32 +0000 (Tue, 12 Oct 2010) Log Message: ----------- 1. Added reserved hexes facility, and applied to 18EU and 1825 maps. 2. Removed the "no train - no income" popup. 3. Allow (temporary) >60% share ownership in certain cases. Applied to 18EU mergers. Modified Paths: -------------- trunk/18xx/data/1825/Map.xml trunk/18xx/data/18EU/Map.xml trunk/18xx/rails/game/MapHex.java trunk/18xx/rails/game/OperatingRound.java trunk/18xx/rails/game/StockRound.java trunk/18xx/rails/game/specific/_18EU/StockRound_18EU.java trunk/18xx/rails/game/state/HashSetState.java trunk/18xx/rails/ui/swing/hexmap/GUIHex.java Modified: trunk/18xx/data/1825/Map.xml =================================================================== --- trunk/18xx/data/1825/Map.xml 2010-10-12 17:39:08 UTC (rev 1448) +++ trunk/18xx/data/1825/Map.xml 2010-10-12 18:50:32 UTC (rev 1449) @@ -25,7 +25,7 @@ <Hex name="G7" tile="-2" city="Coatbridge, Airdrie"/> <Hex name="G9" tile="-20" city="Edinburgh, Leith"/> <Hex name="G11" tile="0"/> - <Hex name="H4" tile="-2" city="Ayr, Kilmarnock"/> + <Hex name="H4" tile="-2" city="Ayr, Kilmarnock" reserved="GSWR"/> <Hex name="H6" tile="-10" city="Motherwell"/> <Hex name="H8" tile="0" cost="100"/> <Hex name="H10" tile="0" cost="100"/> @@ -54,7 +54,7 @@ <Hex name="L8" tile="0" open="2,3"/> <Hex name="L10" tile="0" open="2,3"/> <Hex name="L12" tile="0" cost="100" open="2,3"/> - <Hex name="L14" tile="-10" city="Darlington" open="2,3"/> + <Hex name="L14" tile="-10" city="Darlington" open="2,3" reserved="NER"/> <Hex name="L16" tile="0" open="2"/> <Hex name="L18" tile="-1" city="Scarborough"/> <Hex name="M9" tile="-25008" city="Barrow"/> @@ -63,7 +63,7 @@ <Hex name="M15" tile="-2" city="Harrogate, York"/> <Hex name="M17" tile="0"/> <Hex name="M19" tile="0"/> - <Hex name="N10" tile="-10" city="Preston"/> + <Hex name="N10" tile="-10" city="Preston" reserved="L&Y"/> <Hex name="N12" tile="-2" city="Burnley, Halifax"/> <Hex name="N14" tile="-20" city="Bradford, Leeds"/> <Hex name="N16" tile="0"/> @@ -84,7 +84,7 @@ <Hex name="Q9" tile="0" open="0,5"/> <Hex name="Q11" tile="-25004" city="Wolverton"/> <Hex name="Q13" tile="-2" city="Newcastle u/L, Hanley" open="0,5"/> - <Hex name="Q15" tile="-10" city="Derby" open="0,5"/> + <Hex name="Q15" tile="-10" city="Derby" open="0,5" reserved="MR"/> <Hex name="Q17" tile="-10" city="Nottingham" open="0,5"/> <Hex name="Q19" tile="0" open="0,5"/> </IfOption> @@ -92,7 +92,11 @@ <Hex name="R8" tile="0" open="0,1,2,3"/> <Hex name="R10" tile="-1" city="Shrewsbury" orientation="3" open="2"/> <Hex name="R12" tile="-20" orientation="1" city="Wolverhampton, Walsall" open="2,3"/> - <Hex name="R14" tile="0" open="2,3"/> + <Hex name="R14" tile="0" open="2,3"> + <IfOption name="Include" parm="Unit1" value="yes"> + <Attributes reserved="MR"/> + </IfOption> + </Hex> <Hex name="R16" tile="-10" city="Leicester" open="2,3"/> <Hex name="R18" tile="0" open="2,3"/> <Hex name="R20" tile="-1" city="Peterborough" orientation="3" open="2"/> @@ -122,17 +126,17 @@ orientation="1" ></Hex> <Hex name="U13" tile="0"/> <Hex name="U15" tile="0"/> - <Hex name="U17" tile="0"/> + <Hex name="U17" tile="0" reserved="LNWR"/> <Hex name="U19" tile="0"/> <Hex name="U21" tile="0"/> - <Hex name="U23" tile="-1" city="Colchester" /> + <Hex name="U23" tile="-1" city="Colchester" reserved="GER"/> <Hex name="U25" tile="-104" orientation="2" city="Harwich"/> <Hex name="V8" tile="-20" city="Cardiff, Newport" open="1,2"/> <Hex name="V10" tile="-25003" city="Bristol"/> <Hex name="V12" tile="0"/> <Hex name="V14" tile="-25005" city="Swindon"/> <Hex name="V16" tile="-1" city="Reading" orientation="1"/> - <Hex name="V18" tile="0"/> + <Hex name="V18" tile="0" reserved="GWR"/> <Hex name="V20" tile="-25001" city="London"/> <Hex name="V22" tile="-25006" value="20" city="Southend"/> <IfOption name="Include" parm="R2" value="no"> @@ -146,7 +150,7 @@ <Hex name="W15" tile="0"/> <Hex name="W17" tile="0"/> <Hex name="W19" tile="-2" city="Kingston on Thames, Reigate" - orientation="4" /> + orientation="4" reserved="LSWR"/> <Hex name="W21" tile="0"/> <Hex name="W23" tile="-10" city="Ashford" orientation="5" /> <Hex name="W25" tile="-5" orientation="2" city="Dover"/> @@ -157,7 +161,7 @@ <Hex name="X16" tile="-20" city="Gosport, Portsmouth" orientation="1" /> <Hex name="X18" tile="0"/> - <Hex name="X20" tile="-10" city="Brighton" orientation="5" /> + <Hex name="X20" tile="-10" city="Brighton" orientation="5" reserved="LBSC"/> <Hex name="X22" tile="-1" city="Hastings" orientation="2" /> <Hex name="X24" tile="0"/> <Hex name="Y9" tile="0" open="1"/> Modified: trunk/18xx/data/18EU/Map.xml =================================================================== --- trunk/18xx/data/18EU/Map.xml 2010-10-12 17:39:08 UTC (rev 1448) +++ trunk/18xx/data/18EU/Map.xml 2010-10-12 18:50:32 UTC (rev 1449) @@ -21,7 +21,7 @@ <Hex name="F3" tile="-1" city="Antwerp"/> <Hex name="F5" tile="-3008" city="Dortmund"/> <Hex name="F7" tile="-1" city="Hannover"/> - <Hex name="F9" tile="0" /> + <Hex name="F9" tile="0" reserved="7"/> <Hex name="F11" tile="0" /> <Hex name="F13" tile="0" /> <Hex name="G2" tile="-1" city="Lille"/> @@ -31,7 +31,7 @@ <Hex name="G10" label="Y" tile="-3007" city="Dresden"/> <Hex name="G12" tile="0" /> <Hex name="H1" tile="0" /> - <Hex name="H3" label="Y" tile="-3007" city="Brussels"/> + <Hex name="H3" label="Y" tile="-3007" city="Brussels" reserved="2"/> <Hex name="H5" tile="0" /> <Hex name="H7" tile="0" /> <Hex name="H9" tile="-1" city="Leipzig"/> @@ -50,7 +50,7 @@ <Hex name="J9" cost="60" tile="0" /> <Hex name="J11" tile="0" /> <Hex name="J13" cost="60" tile="-1" city="Krakau"/> - <Hex name="K2" tile="0" /> + <Hex name="K2" tile="0" reserved="3"/> <Hex name="K4" cost="60" tile="0" /> <Hex name="K6" tile="-1" city="Augsburg"/> <Hex name="K8" tile="0" /> @@ -107,7 +107,7 @@ <Hex name="R11" tile="0" /> <Hex name="S2" tile="-3008" city="Marseille"/> <Hex name="S4" tile="-3008" city="Turin"/> - <Hex name="S6" tile="0" /> + <Hex name="S6" tile="0" reserved="10"/> <Hex name="S8" label="Y" tile="-3007" city="Venice"/> <Hex name="S10" tile="0" /> <Hex name="T1" tile="0" /> @@ -117,7 +117,7 @@ <Hex name="T9" port="yes" value="10" tile="-800" orientation="3"/> <Hex name="U2" port="yes" value="10" tile="-800" orientation="3"/> <Hex name="U4" tile="0" /> - <Hex name="U6" tile="-1" city="Florence"/> + <Hex name="U6" tile="-1" city="Florence" reserved="10"/> <Hex name="U8" tile="0" /> <Hex name="V5" port="yes" value="10" tile="-800" orientation="3"/> <Hex name="V7" label="V" value="30,50" tile="-903" orientation="4" city="Rome"/> Modified: trunk/18xx/rails/game/MapHex.java =================================================================== --- trunk/18xx/rails/game/MapHex.java 2010-10-12 17:39:08 UTC (rev 1448) +++ trunk/18xx/rails/game/MapHex.java 2010-10-12 18:50:32 UTC (rev 1449) @@ -66,6 +66,7 @@ protected int[] tileCost; protected String cityName; protected String infoText; + protected String reservedForCompany = null; /** Neighbouring hexes <i>to which track may be laid</i>. */ protected MapHex[] neighbours = new MapHex[6]; @@ -114,7 +115,7 @@ /** Any open sides against which track may be laid even at board edges (1825) */ protected boolean[] openHexSides; - + protected MapManager mapManager = null; protected static Logger log = @@ -206,6 +207,8 @@ setBlockedForTokenLays(tag.getAttributeAsBoolean("unlaidHomeBlocksTokens", false)); } + reservedForCompany = tag.getAttributeAsString("reserved"); + // revenue bonus List<Tag> bonusTags = tag.getChildren("RevenueBonus"); if (bonusTags != null) { @@ -272,7 +275,7 @@ return true; } - + public boolean isOpenSide (int side) { return openHexSides != null && openHexSides[side%6]; } @@ -1144,7 +1147,15 @@ return infoText; } - public List<RevenueBonusTemplate> getRevenueBonuses() { + public String getReservedForCompany() { + return reservedForCompany; + } + + public boolean isReservedForCompany () { + return reservedForCompany != null; + } + + public List<RevenueBonusTemplate> getRevenueBonuses() { return revenueBonuses; } Modified: trunk/18xx/rails/game/OperatingRound.java =================================================================== --- trunk/18xx/rails/game/OperatingRound.java 2010-10-12 17:39:08 UTC (rev 1448) +++ trunk/18xx/rails/game/OperatingRound.java 2010-10-12 18:50:32 UTC (rev 1449) @@ -909,11 +909,13 @@ operatingCompany.get().setLastRevenue(amount); operatingCompany.get().setLastRevenueAllocation(revenueAllocation); + /* Seems people don't like this popup... if (amount == 0 && operatingCompany.get().getNumberOfTrains() == 0) { DisplayBuffer.add(LocalText.getText("RevenueWithNoTrains", operatingCompany.get().getName(), Bank.format(0) )); } + */ // Pay any debts from treasury, revenue and/or president's cash // The remaining dividend may be less that the original income @@ -1530,9 +1532,10 @@ PublicCompanyI company; for (int i=0; i<newOperatingCompanies.size(); i++) { company = newOperatingCompanies.get(i); - log.debug("+++ Index "+i+" new company="+company.getName()); if (company != operatingCompanies.get(i)) { - log.debug("+++ Index "+i+" old company="+operatingCompanies.get(i).getName()); + log.debug("Company "+company.getName() + +" replaces "+operatingCompanies.get(i).getName() + +" in operating sequence"); operatingCompanies.move(company, i); } } Modified: trunk/18xx/rails/game/StockRound.java =================================================================== --- trunk/18xx/rails/game/StockRound.java 2010-10-12 17:39:08 UTC (rev 1448) +++ trunk/18xx/rails/game/StockRound.java 2010-10-12 18:50:32 UTC (rev 1449) @@ -35,6 +35,11 @@ protected Map<String, StockSpaceI> sellPrices = new HashMap<String, StockSpaceI>(); + /** Records lifted share selling obligations in the current round<p> + * Example: >60% ownership allowed after a merger in 18EU. + */ + protected HashSetState<PublicCompanyI> sellObligationLifted = null; + /* Transient data needed for rule enforcing */ /** HashMap per player containing a HashMap per company */ protected HashMap<Player, HashMap<PublicCompanyI, Object>> playersThatSoldThisRound = @@ -1013,9 +1018,6 @@ } } } - if (potentialDirector == null) { - //TODO: No one to dump the Presidency onto, work out how to handle the receivership - } // The poor sod. dumpedPlayer = potentialDirector; presSharesToSell = numberToSell; @@ -1463,7 +1465,6 @@ player.getPortfolio().getCertificateCount(), gameManager.getPlayerCertificateLimit(player))); } - ; // Over the hold limit of any company? for (PublicCompanyI company : companyManager.getAllPublicCompanies()) { @@ -1514,7 +1515,8 @@ if (player.getPortfolio().getShare(company) + number * company.getShareUnit() > getGameParameterAsInt(GameDef.Parm.PLAYER_SHARE_LIMIT) - && !company.getCurrentSpace().isNoHoldLimit()) return false; + && !company.getCurrentSpace().isNoHoldLimit() + && !isSellObligationLifted(company)) return false; return true; } @@ -1572,4 +1574,16 @@ return toString(); } + public boolean isSellObligationLifted(PublicCompanyI company) { + return sellObligationLifted != null + && sellObligationLifted.contains(company); + } + + public void setSellObligationLifted (PublicCompanyI company) { + if (sellObligationLifted == null) { + sellObligationLifted = new HashSetState<PublicCompanyI>("SellObligationLifted"); + } + sellObligationLifted.add(company); + } + } Modified: trunk/18xx/rails/game/specific/_18EU/StockRound_18EU.java =================================================================== --- trunk/18xx/rails/game/specific/_18EU/StockRound_18EU.java 2010-10-12 17:39:08 UTC (rev 1448) +++ trunk/18xx/rails/game/specific/_18EU/StockRound_18EU.java 2010-10-12 18:50:32 UTC (rev 1449) @@ -604,6 +604,13 @@ if (!(this instanceof FinalMinorExchangeRound)) { companyBoughtThisTurnWrapper.set(major); + + // If >60% shares owned, lift sell obligation this round. + if (currentPlayer.getPortfolio().getShare(major) + > getGameParameterAsInt(GameDef.Parm.PLAYER_SHARE_LIMIT)) { + setSellObligationLifted (major); + } + setPriority(); } Modified: trunk/18xx/rails/game/state/HashSetState.java =================================================================== --- trunk/18xx/rails/game/state/HashSetState.java 2010-10-12 17:39:08 UTC (rev 1448) +++ trunk/18xx/rails/game/state/HashSetState.java 2010-10-12 18:50:32 UTC (rev 1449) @@ -1,9 +1,6 @@ package rails.game.state; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; +import java.util.*; import rails.game.move.SetChange; /** @@ -12,14 +9,14 @@ * * Remark: Does not extend State or implements StateI do avoid additional overhead * All state/move mechanisms already contained in Move objects - * + * * TODO: Replace all stateful sets by this class and simplify according move objects */ public class HashSetState<E> { - + private final HashSet<E> set = new HashSet<E>(); private final String setName; - + /** * constructor for an empty set * @param name @@ -35,11 +32,11 @@ this(setName); set.addAll(collection); } - + public void add(E element) { new SetChange<E>(set, element, true); } - + public boolean remove(E element) { if (set.contains(element)) { new SetChange<E>(set, element, false); @@ -48,22 +45,26 @@ return false; } } - + + public boolean contains (E element) { + return set.contains(element); + } + public void clear() { for (E element:set) { remove(element); } } - - /** + + /** * returns unmodifiable view of set */ public Set<E> viewSet() { return Collections.unmodifiableSet(set); } - + public int size() { return set.size(); } - + } Modified: trunk/18xx/rails/ui/swing/hexmap/GUIHex.java =================================================================== --- trunk/18xx/rails/ui/swing/hexmap/GUIHex.java 2010-10-12 17:39:08 UTC (rev 1448) +++ trunk/18xx/rails/ui/swing/hexmap/GUIHex.java 2010-10-12 18:50:32 UTC (rev 1449) @@ -8,7 +8,6 @@ import org.apache.log4j.Logger; -import rails.algorithms.RevenueBonus; import rails.algorithms.RevenueBonusTemplate; import rails.game.*; import rails.game.model.ModelObject; @@ -161,9 +160,9 @@ innerHexagonSelected = defineInnerHexagon(0.8, center2D); innerHexagonSelectable = defineInnerHexagon(0.9, center2D); } - + private GeneralPath defineInnerHexagon(double innerScale, Point2D.Double center2D) { - + AffineTransform at = AffineTransform.getScaleInstance(innerScale, innerScale); GeneralPath innerHexagon = (GeneralPath) hexagon.createTransformedShape(at); @@ -182,7 +181,7 @@ return innerHexagon; } - + /** * returns point that corresponds to the definition as networkvertex */ @@ -208,14 +207,14 @@ } public Point2D getSidePoint2D(int side){ - return new Point2D.Double((xVertex[side] + xVertex[(side+1)%6])/2, + return new Point2D.Double((xVertex[side] + xVertex[(side+1)%6])/2, (yVertex[side] + yVertex[(side+1)%6])/2); } - + public Point2D getCenterPoint2D() { return center; } - + public void setHexModel(MapHex model) { this.model = model; currentTile = model.getCurrentTile(); @@ -280,7 +279,7 @@ provisionalGUITile = null; } } - + public boolean isSelectable() { return selectable; } @@ -418,12 +417,11 @@ if (blocked != null) { for (MapHex hex : blocked) { if (getHexModel().equals(hex)) { + String text = "(" + p.getName() + ")"; g2.drawString( - "(" + p.getName() + ")", + text, rectBound.x - + (rectBound.width - fontMetrics.stringWidth("(" - + p.getName() - + ")")) + + (rectBound.width - fontMetrics.stringWidth(text)) * 1 / 2, rectBound.y + ((fontMetrics.getHeight() + rectBound.height) * 5 / 15)); @@ -433,6 +431,18 @@ } } + if (model.isReservedForCompany() + && currentTileId == model.getPreprintedTileId() ) { + String text = "[" + model.getReservedForCompany() + "]"; + g2.drawString( + text, + rectBound.x + + (rectBound.width - fontMetrics.stringWidth(text)) + * 1 / 2, + rectBound.y + + ((fontMetrics.getHeight() + rectBound.height) * 5 / 25)); + } + } private void paintOverlay(Graphics2D g2) { @@ -468,7 +478,7 @@ } private void paintStationTokens(Graphics2D g2) { - + if (getHexModel().getCities().size() > 1) { paintSplitStations(g2); return; @@ -575,7 +585,7 @@ provisionalGUITile.rotate(1, currentGUITile, upgradeMustConnect); } } - + public void forcedRotateTile() { provisionalGUITile.setRotation(provisionalGUITile.getRotation() + 1); } @@ -663,11 +673,11 @@ public String getToolTip() { if (toolTip != null) return toolTip; - else + else return getDefaultToolTip(); } - + private String bonusToolTipText(List<RevenueBonusTemplate> bonuses) { StringBuffer tt = new StringBuffer(); if (bonuses != null) { @@ -684,7 +694,7 @@ } return tt.toString(); } - + private String getDefaultToolTip() { StringBuffer tt = new StringBuffer("<html>"); tt.append("<b>Hex</b>: ").append(hexName); @@ -736,7 +746,7 @@ // revenueBonuses tt.append(bonusToolTipText(model.getRevenueBonuses())); - + String upgrades = currentTile.getUpgradesString(model); if (upgrades.equals("")) { tt.append("<br>No upgrades"); @@ -754,8 +764,8 @@ tt.append(dest.getName()); } } - - + + tt.append("</html>"); return tt.toString(); } @@ -777,7 +787,7 @@ } } - + /** forces the tile to drop */ public void forcedDropTile(int tileId, int orientation) { provisionalGUITile = new GUITile(tileId, this); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |