From: Erik V. <ev...@us...> - 2009-09-23 21:39:06
|
Update of /cvsroot/rails/18xx/rails/game In directory 23jxhf1.ch3.sourceforge.com:/tmp/cvs-serv15188/rails/game Modified Files: Portfolio.java PublicCompany.java GameManager.java PublicCompanyI.java BonusToken.java OperatingRound.java GameManagerI.java PrivateCompany.java Added Files: Bonus.java Log Message: Implemented 1856 Bridge and Tunnel tokens Index: Portfolio.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/Portfolio.java,v retrieving revision 1.34 retrieving revision 1.35 diff -C2 -d -r1.34 -r1.35 *** Portfolio.java 30 Aug 2009 18:15:18 -0000 1.34 --- Portfolio.java 23 Sep 2009 21:38:57 -0000 1.35 *************** *** 13,16 **** --- 13,17 ---- import rails.game.model.*; import rails.game.move.*; + import rails.game.special.LocatedBonus; import rails.game.special.SpecialPropertyI; import rails.util.LocalText; *************** *** 98,143 **** } - public void buyPrivate(PrivateCompanyI privateCompany, Portfolio from, - int price) { - - if (from != Bank.getIpo()) - /* - * The initial buy is reported from StartRound. This message should also - * move to elsewhere. - */ - { - ReportBuffer.add(LocalText.getText("BuysPrivateFromFor", - name, - privateCompany.getName(), - from.getName(), - Bank.format(price) )); - } - - // Move the private certificate - privateCompany.moveTo(this); - - // Move the money - if (price > 0) new CashMove(owner, from.owner, price); - - // Move any special abilities, if configured so - List<SpecialPropertyI> sps = privateCompany.getSpecialProperties(); - if (sps != null) { - // Need intermediate List to avoid ConcurrentModificationException - List<SpecialPropertyI> spsToMove = - new ArrayList<SpecialPropertyI>(2); - for (SpecialPropertyI sp : sps) { - if (sp.getTransferText().equalsIgnoreCase("toCompany") - && owner instanceof PublicCompanyI - || sp.getTransferText().equalsIgnoreCase("toPlayer") - && owner instanceof Player) { - spsToMove.add(sp); - } - } - for (SpecialPropertyI sp : spsToMove) { - sp.moveTo(this); - } - } - } - public void transferAssetsFrom(Portfolio otherPortfolio) { --- 99,102 ---- *************** *** 501,512 **** */ public boolean addSpecialProperty(SpecialPropertyI property) { if (specialProperties == null) { specialProperties = new ArrayList<SpecialPropertyI>(2); } ! return specialProperties.add(property); } /** ! * Remove a special property. Not currently used. * * @param property The special property object to remove. --- 460,491 ---- */ public boolean addSpecialProperty(SpecialPropertyI property) { + + boolean result = false; + if (specialProperties == null) { specialProperties = new ArrayList<SpecialPropertyI>(2); } ! result = specialProperties.add(property); ! ! // Special case for bonuses with predefined locations ! // TODO Does this belong here? ! if (owner instanceof PublicCompanyI && property instanceof LocatedBonus) { ! PublicCompanyI company = (PublicCompanyI)owner; ! LocatedBonus locBonus = (LocatedBonus)property; ! Bonus bonus = new Bonus(company, locBonus.getName(), locBonus.getValue(), ! locBonus.getLocationNameString()); ! company.addBonus(bonus); ! ReportBuffer.add(LocalText.getText("AcquiresBonus", ! owner.getName(), ! locBonus.getName(), ! Bank.format(locBonus.getValue()), ! locBonus.getLocationNameString())); ! } ! ! return result; } /** ! * Remove a special property. * * @param property The special property object to remove. *************** *** 514,522 **** */ public boolean removeSpecialProperty(SpecialPropertyI property) { if (specialProperties != null) { ! return specialProperties.remove(property); ! } else { ! return false; } } --- 493,512 ---- */ public boolean removeSpecialProperty(SpecialPropertyI property) { + + boolean result = false; + if (specialProperties != null) { ! result = specialProperties.remove(property); ! ! // Special case for bonuses with predefined locations ! // TODO Does this belong here? ! if (owner instanceof PublicCompanyI && property instanceof LocatedBonus) { ! PublicCompanyI company = (PublicCompanyI)owner; ! LocatedBonus locBonus = (LocatedBonus)property; ! company.removeBonus(locBonus.getName()); ! } } + + return result; } *************** *** 545,549 **** /** ! * Remove an object. Not currently used. * * @param object The object to remove. --- 535,539 ---- /** ! * Remove an object. * * @param object The object to remove. --- NEW FILE: Bonus.java --- /* $Header: /cvsroot/rails/18xx/rails/game/Bonus.java,v 1.1 2009/09/23 21:38:57 evos Exp $ */ package rails.game; import java.util.ArrayList; import java.util.List; /** * An object of class Bonus represent extra income for the owning company, * usually connected to certain map locations. * <p>Currently, Bonus objects will be created in the following cases: * <br>1. when a SpecialTokenLay containing a BonusToken * is exercised, * <br>2. when a private having a LocatedBonus special property is bought by * a public company, * <br>3. when a sellable bonus is bought from such a public company by another company. * @author VosE * */ public class Bonus implements Closeable { private PublicCompanyI owner; private String locationCodes = null; private List<MapHex> locations = null; private String name; private int value; private String removingObjectDesc = null; private Object removingObject = null; public Bonus (PublicCompanyI owner, String name, int value, String locationCodes) { this.owner = owner; this.name = name; this.value = value; this.locationCodes = locationCodes; parseLocations(); } public boolean isExecutionable() { return false; } public PublicCompanyI getOwner() { return owner; } public List<MapHex> getLocations() { return locations; } public String getLocationNameString() { return locationCodes; } public String getName() { return name; } public int getValue() { return value; } private void parseLocations () { MapManager mmgr = MapManager.getInstance(); MapHex hex; locations = new ArrayList<MapHex>(); for (String hexName : locationCodes.split(",")) { hex = mmgr.getHex(hexName); if (hex != null) locations.add(hex); } } /** * Remove the token. * This method can be called by a certain phase when it starts. * See prepareForRemovel(). */ public void close() { owner.removeBonus(name); } /** * Prepare the bonus token for removal, if so configured. * The only case currently implemented to trigger removal * is the start of a given phase. */ public void prepareForRemoval (PhaseManager phaseManager) { if (removingObjectDesc == null) return; if (removingObject == null) { String[] spec = removingObjectDesc.split(":"); if (spec[0].equalsIgnoreCase("Phase")) { removingObject = phaseManager.getPhaseByName(spec[1]); } } if (removingObject instanceof Phase) { ((Phase) removingObject).addObjectToClose(this); } } @Override public String toString() { return "Bonus "+name+" hex=" + locationCodes + " value=" + value; } } Index: PublicCompany.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/PublicCompany.java,v retrieving revision 1.59 retrieving revision 1.60 diff -C2 -d -r1.59 -r1.60 *** PublicCompany.java 12 Sep 2009 09:40:56 -0000 1.59 --- PublicCompany.java 23 Sep 2009 21:38:57 -0000 1.60 *************** *** 7,12 **** import rails.game.action.SetDividend; import rails.game.model.*; ! import rails.game.move.CashMove; ! import rails.game.move.Moveable; import rails.game.state.*; import rails.util.*; --- 7,12 ---- import rails.game.action.SetDividend; import rails.game.model.*; ! import rails.game.move.*; ! import rails.game.special.*; import rails.game.state.*; import rails.util.*; *************** *** 91,95 **** /** Total bonus tokens amount */ ! protected MoneyModel bonusTokensValue = null; /** Most recent revenue earned. */ --- 91,98 ---- /** Total bonus tokens amount */ ! protected BonusModel bonusValue = null; ! ! /** Acquires Bonus objects */ ! protected List<Bonus> bonuses = null; /** Most recent revenue earned. */ *************** *** 596,602 **** trainsCostThisTurn = new MoneyModel(name + "_spentOnTrains"); trainsCostThisTurn.setOption(MoneyModel.SUPPRESS_ZERO); ! bonusTokensValue = new MoneyModel(name + "_bonusValue"); ! bonusTokensValue.setOption(MoneyModel.SUPPRESS_ZERO ! + MoneyModel.ADD_PLUS); if (hasStockPrice) { parPrice = new PriceModel(this, name + "_ParPrice"); --- 599,604 ---- trainsCostThisTurn = new MoneyModel(name + "_spentOnTrains"); trainsCostThisTurn.setOption(MoneyModel.SUPPRESS_ZERO); ! bonusValue = new BonusModel(name + "_bonusValue"); ! if (hasStockPrice) { parPrice = new PriceModel(this, name + "_ParPrice"); *************** *** 956,962 **** } } ! ! /** Return the price per share at game end. ! * Normally, it is equal to the market price, * but in some games (e.g. 1856) deductions may apply. * @return --- 958,964 ---- } } ! ! /** Return the price per share at game end. ! * Normally, it is equal to the market price, * but in some games (e.g. 1856) deductions may apply. * @return *************** *** 1232,1236 **** CashHolder beneficiary = holder.getOwner(); // Special cases apply if the holder is the IPO or the Pool ! if (holder == Bank.getIpo() && ipoPaysOut || holder == Bank.getPool() && poolPaysOut) { beneficiary = this; --- 1234,1238 ---- CashHolder beneficiary = holder.getOwner(); // Special cases apply if the holder is the IPO or the Pool ! if (holder == Bank.getIpo() && ipoPaysOut || holder == Bank.getPool() && poolPaysOut) { beneficiary = this; *************** *** 1465,1471 **** public void buyPrivate(PrivateCompanyI privateCompany, Portfolio from, int price) { - portfolio.buyPrivate(privateCompany, from, price); privatesCostThisTurn.add(price); } --- 1467,1516 ---- public void buyPrivate(PrivateCompanyI privateCompany, Portfolio from, int price) { + //portfolio.buyPrivate(privateCompany, from, price); + if (from != Bank.getIpo()) { + // The initial buy is reported from StartRound. This message should also + // move to elsewhere. + ReportBuffer.add(LocalText.getText("BuysPrivateFromFor", + name, + privateCompany.getName(), + from.getName(), + Bank.format(price) )); + } + + // Move the private certificate + privateCompany.moveTo(portfolio); + + // Move the money + if (price > 0) new CashMove(this, from.owner, price); privatesCostThisTurn.add(price); + + // Move any special abilities to the portfolio, if configured so + List<SpecialPropertyI> sps = privateCompany.getSpecialProperties(); + if (sps != null) { + // Need intermediate List to avoid ConcurrentModificationException + List<SpecialPropertyI> spsToMoveHere = + new ArrayList<SpecialPropertyI>(2); + List<SpecialPropertyI> spsToMoveToGM = + new ArrayList<SpecialPropertyI>(2); + for (SpecialPropertyI sp : sps) { + if (sp.getTransferText().equalsIgnoreCase("toCompany")) { + spsToMoveHere.add(sp); + } else if (sp.getTransferText().equalsIgnoreCase("toGameManager")) { + // This must be SellBonusToken - remember the owner! + if (sp instanceof SellBonusToken) { + ((SellBonusToken)sp).setSeller(this); + } + spsToMoveToGM.add(sp); + } + } + for (SpecialPropertyI sp : spsToMoveHere) { + sp.moveTo(portfolio); + } + for (SpecialPropertyI sp : spsToMoveToGM) { + sp.moveTo(gameManager); + } + } + } *************** *** 1537,1553 **** } ! public void layBonusToken(MapHex hex, int cost, BonusToken token) { ! // TODO for now we only add the bonus value. ! // We must be prepared though, that tokens may be removed later. ! bonusTokensValue.add(token.getValue()); } ! public void removeBonusToken(BonusToken token) { ! bonusTokensValue.add(-token.getValue()); } ! public MoneyModel getBonusTokensModel() { ! return bonusTokensValue; } --- 1582,1614 ---- } ! public boolean addBonus(Bonus bonus) { ! if (bonuses == null) { ! bonuses = new ArrayList<Bonus>(2); ! bonusValue.set(bonuses); ! } ! new AddToList<Bonus> (bonuses, bonus, name+"_Bonuses", bonusValue); ! return true; ! } + public boolean removeBonus(Bonus bonus) { + new RemoveFromList<Bonus> (bonuses, bonus, name+"_Bonuses", bonusValue); + return true; } ! public boolean removeBonus (String name) { ! if (bonuses != null && !bonuses.isEmpty()) { ! for(Bonus bonus : bonuses) { ! if (bonus.getName().equals(name)) return removeBonus(bonus); ! } ! } ! return false; } ! public List<Bonus> getBonuses() { ! return bonuses; ! } ! ! public BonusModel getBonusTokensModel() { ! return bonusValue; } *************** *** 1636,1639 **** --- 1697,1702 ---- if (object instanceof TokenI) { return addToken((TokenI) object); + } else if (object instanceof LocatedBonus) { + return addBonus ((Bonus) object); } else { return false; *************** *** 1644,1649 **** if (object instanceof BaseToken) { return removeToken((TokenI) object); ! } else if (object instanceof BonusToken) { ! removeBonusToken((BonusToken) object); return true; } else { --- 1707,1712 ---- if (object instanceof BaseToken) { return removeToken((TokenI) object); ! } else if (object instanceof Bonus) { ! removeBonus((Bonus) object); return true; } else { Index: PrivateCompany.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/PrivateCompany.java,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** PrivateCompany.java 15 Jan 2009 20:53:28 -0000 1.20 --- PrivateCompany.java 23 Sep 2009 21:38:57 -0000 1.21 *************** *** 6,9 **** --- 6,10 ---- import rails.game.move.*; + import rails.game.special.SellBonusToken; import rails.game.special.SpecialPropertyI; import rails.util.*; *************** *** 163,173 **** @Override public void setClosed() { ! if (!isClosed()) { ! super.setClosed(); ! unblockHexes(); ! // new CertificateMove (getPortfolio(), Bank.getScrapHeap(), ! // (Certificate)this); ! moveTo(Bank.getScrapHeap()); ! ReportBuffer.add(LocalText.getText("PrivateCloses", name)); } } --- 164,180 ---- @Override public void setClosed() { ! ! if (isClosed()) return; ! ! super.setClosed(); ! unblockHexes(); ! moveTo(Bank.getScrapHeap()); ! ReportBuffer.add(LocalText.getText("PrivateCloses", name)); ! ! // For 1856: buyable tokens move to Bank ! for (SpecialPropertyI sp : specialProperties) { ! if (sp instanceof SellBonusToken) { ! ((SellBonusToken)sp).setSeller(Bank.getInstance()); ! } } } Index: GameManager.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/GameManager.java,v retrieving revision 1.52 retrieving revision 1.53 diff -C2 -d -r1.52 -r1.53 *** GameManager.java 12 Sep 2009 19:48:39 -0000 1.52 --- GameManager.java 23 Sep 2009 21:38:57 -0000 1.53 *************** *** 10,15 **** import rails.common.Defs; import rails.game.action.*; ! import rails.game.move.AddToList; ! import rails.game.move.MoveSet; import rails.game.special.SpecialPropertyI; import rails.game.special.SpecialTokenLay; --- 10,14 ---- import rails.common.Defs; import rails.game.action.*; ! import rails.game.move.*; import rails.game.special.SpecialPropertyI; import rails.game.special.SpecialTokenLay; *************** *** 87,91 **** protected boolean gameOver = false; protected boolean endedByBankruptcy = false; ! /** Flags to be passed to the UI, aiding the layout definition */ protected EnumMap<Defs.Parm, Boolean> gameParameters = --- 86,90 ---- protected boolean gameOver = false; protected boolean endedByBankruptcy = false; ! /** Flags to be passed to the UI, aiding the layout definition */ protected EnumMap<Defs.Parm, Boolean> gameParameters = *************** *** 105,111 **** protected StartPacket startPacket; ! PossibleActions possibleActions = PossibleActions.getInstance(); ! List<PossibleAction> executedActions = new ArrayList<PossibleAction>(); /** A List of available game options */ --- 104,115 ---- protected StartPacket startPacket; ! protected PossibleActions possibleActions = PossibleActions.getInstance(); ! protected List<PossibleAction> executedActions = new ArrayList<PossibleAction>(); ! ! /** Special properties that can be used by other players or companies ! * than just the owner (such as buyable bonus tokens as in 1856). ! */ ! protected List<SpecialPropertyI> commonSpecialProperties = null; /** A List of available game options */ *************** *** 1038,1040 **** --- 1042,1123 ---- } + /** + * Add an object. + * + * @param object The object to add. + * @return True if successful. + */ + public boolean addObject(Moveable object) { + if (object instanceof SpecialPropertyI) { + return addSpecialProperty((SpecialPropertyI) object); + } else { + return false; + } + } + + /** + * Remove an object. + * + * @param object The object to remove. + * @return True if successful. + */ + public boolean removeObject(Moveable object) { + if (object instanceof SpecialPropertyI) { + return removeSpecialProperty((SpecialPropertyI) object); + } else { + return false; + } + } + + public boolean addSpecialProperty(SpecialPropertyI property) { + + if (commonSpecialProperties == null) { + commonSpecialProperties = new ArrayList<SpecialPropertyI>(2); + } + return commonSpecialProperties.add(property); + } + + /** + * Remove a special property. + * + * @param property The special property object to remove. + * @return True if successful. + */ + public boolean removeSpecialProperty(SpecialPropertyI property) { + + if (commonSpecialProperties != null) { + return commonSpecialProperties.remove(property); + } + + return false; + } + + public List<SpecialPropertyI> getCommonSpecialProperties () { + return getSpecialProperties (null, false); + } + + @SuppressWarnings("unchecked") + public <T extends SpecialPropertyI> List<T> getSpecialProperties( + Class<T> clazz, boolean includeExercised) { + + List<T> result = new ArrayList<T>(); + + if (commonSpecialProperties != null) { + for (SpecialPropertyI sp : commonSpecialProperties) { + if ((clazz == null || clazz.isAssignableFrom(sp.getClass())) + && sp.isExecutionable() + && (!sp.isExercised() || includeExercised)) { + log.debug("Adding common SP: " + sp); + result.add((T) sp); + } + } + } + + return result; + } + + public String getName () { + return "GameManager"; + } + } Index: PublicCompanyI.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/PublicCompanyI.java,v retrieving revision 1.35 retrieving revision 1.36 diff -C2 -d -r1.35 -r1.36 *** PublicCompanyI.java 12 Sep 2009 09:40:56 -0000 1.35 --- PublicCompanyI.java 23 Sep 2009 21:38:57 -0000 1.36 *************** *** 146,150 **** public int getMarketPrice (); public int getGameEndPrice(); ! public int getPublicNumber(); --- 146,150 ---- public int getMarketPrice (); public int getGameEndPrice(); ! public int getPublicNumber(); *************** *** 252,256 **** public void adjustSharePrice (int actionPerformed, int numberOfSharesSold, StockMarketI stockMarket); ! public boolean isSplitAllowed(); --- 252,256 ---- public void adjustSharePrice (int actionPerformed, int numberOfSharesSold, StockMarketI stockMarket); ! public boolean isSplitAllowed(); *************** *** 311,319 **** public BaseTokensModel getBaseTokensModel(); ! public MoneyModel getBonusTokensModel(); ! public void layBonusToken(MapHex hex, int cost, BonusToken token); ! public void removeBonusToken(BonusToken token); public MapHex getHomeHex(); --- 311,321 ---- public BaseTokensModel getBaseTokensModel(); ! public BonusModel getBonusTokensModel(); ! public boolean addBonus(Bonus bonus); ! public boolean removeBonus(Bonus bonus); ! public boolean removeBonus (String name); ! public List<Bonus> getBonuses(); public MapHex getHomeHex(); Index: OperatingRound.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/OperatingRound.java,v retrieving revision 1.67 retrieving revision 1.68 diff -C2 -d -r1.67 -r1.68 *** OperatingRound.java 8 Sep 2009 21:48:59 -0000 1.67 --- OperatingRound.java 23 Sep 2009 21:38:57 -0000 1.68 *************** *** 218,221 **** --- 218,225 ---- result = layBonusToken((LayBonusToken) selectedAction); + } else if (selectedAction instanceof BuyBonusToken) { + + result = buyBonusToken((BuyBonusToken) selectedAction); + } else if (selectedAction instanceof SetDividend) { *************** *** 670,674 **** /* TODO: the false return value must be impossible. */ ! operatingCompany.layBonusToken(hex, cost, token); token.setUser(operatingCompany); --- 674,680 ---- /* TODO: the false return value must be impossible. */ ! operatingCompany.addBonus(new Bonus(operatingCompany, ! token.getName(), ! token.getValue(), hex.getName())); token.setUser(operatingCompany); *************** *** 693,696 **** --- 699,755 ---- } + public boolean buyBonusToken(BuyBonusToken action) { + + String errMsg = null; + int cost; + SellBonusToken sbt = null; + CashHolder seller = null; + + // Dummy loop to enable a quick jump out. + while (true) { + + // Checks + sbt = action.getSpecialProperty(); + cost = sbt.getPrice(); + seller = sbt.getSeller(); + + // Does the company have the money? + if (cost > operatingCompany.getCash()) { + errMsg = + LocalText.getText("NotEnoughMoney", + operatingCompany.getName()); + break; + } + break; + } + if (errMsg != null) { + DisplayBuffer.add(LocalText.getText("CannotBuyBonusToken", + operatingCompany.getName(), + sbt.getName(), + seller.getName(), + Bank.format(cost), + errMsg )); + return false; + } + + /* End of validation, start of execution */ + MoveSet.start(true); + + new CashMove (operatingCompany, seller, cost); + operatingCompany.addBonus(new Bonus(operatingCompany, + sbt.getName(), + sbt.getValue(), sbt.getLocationNameString())); + + ReportBuffer.add(LocalText.getText("BuysBonusTokenFrom", + operatingCompany.getName(), + sbt.getName(), + Bank.format(sbt.getValue()), + seller.getName(), + Bank.format(sbt.getValue()))); + + sbt.setExercised(); + + return true; + } public boolean setRevenueAndDividend(SetDividend action) { *************** *** 976,980 **** if (step == STEP_LAY_TRACK) { getNormalTileLays(); ! } else if (step == STEP_LAY_TOKEN) {} else { currentSpecialProperties = null; } --- 1035,1041 ---- if (step == STEP_LAY_TRACK) { getNormalTileLays(); ! } else if (step == STEP_LAY_TOKEN) { ! ! } else { currentSpecialProperties = null; } *************** *** 1933,1936 **** --- 1994,2016 ---- } + // Are there any "common" special properties, + // i.e. properties that are available to everyone? + List<SpecialPropertyI> commonSP = gameManager.getCommonSpecialProperties(); + if (commonSP != null) { + SellBonusToken sbt; + loop: for (SpecialPropertyI sp : commonSP) { + if (sp instanceof SellBonusToken) { + sbt = (SellBonusToken) sp; + // Can't buy if already owned + if (operatingCompany.getBonuses() != null) { + for (Bonus bonus : operatingCompany.getBonuses()) { + if (bonus.getName().equals(sp.getName())) continue loop; + } + } + possibleActions.add (new BuyBonusToken (sbt)); + } + } + } + if (doneAllowed) { possibleActions.add(new NullAction(NullAction.DONE)); Index: BonusToken.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/BonusToken.java,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** BonusToken.java 8 Sep 2009 21:48:58 -0000 1.9 --- BonusToken.java 23 Sep 2009 21:38:57 -0000 1.10 *************** *** 64,68 **** new ObjectMove(this, holder, Bank.getScrapHeap()); ! user.removeBonusToken(this); } --- 64,68 ---- new ObjectMove(this, holder, Bank.getScrapHeap()); ! user.removeBonus(name); } Index: GameManagerI.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/GameManagerI.java,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** GameManagerI.java 12 Sep 2009 19:48:39 -0000 1.10 --- GameManagerI.java 23 Sep 2009 21:38:57 -0000 1.11 *************** *** 6,12 **** import rails.game.action.PossibleAction; import rails.game.model.ModelObject; import rails.util.Tag; ! public interface GameManagerI { /** --- 6,14 ---- import rails.game.action.PossibleAction; import rails.game.model.ModelObject; + import rails.game.move.MoveableHolderI; + import rails.game.special.SpecialPropertyI; import rails.util.Tag; ! public interface GameManagerI extends MoveableHolderI { /** *************** *** 171,173 **** --- 173,179 ---- public RoundI getInterruptedRound(); + + public List<SpecialPropertyI> getCommonSpecialProperties (); + public <T extends SpecialPropertyI> List<T> getSpecialProperties( + Class<T> clazz, boolean includeExercised); } \ No newline at end of file |