Hey,
Thanks a lot for getting back to us. as you know, we are students and this is 
our first big project. We really appreciate all the helpwe're getting.


>> There is no need to add a GUI to BuildQueuePanel.  It is a FreeColPanel, so 
>> it can get the GUI by calling getGUI().You're right. We over looked that. It 
>> has been fixed.
 
>> Correct me if I am wrong, but does this patch only handle the case of 
>> removing the first item in the build queue?  If so, it can be subverted by 
>> inserting a new item at position zero.  Should this >> be allowed?We over 
>> looked that We have changed it. Now we have extended DefaultListModel and 
>> set the model of the buildQueue JList to that. Now anytime the player 
>> changesthe list through the GUI (mouse, keyboard or whatever) we check 
>> whether or not the currently building object is changed.
 
>>The arguments to showConfirmDialog need to be references to messages defined 
>>in FreeColMessages.properties (see FreeColClient.askToQuit() for a simple 
>>example).
 Fixed

>>In BuildQueuePanel.java there is a comment that it would be better not to 
>>have to hard code the reference to model.goods.hammers.  I agree.  The way I 
>>did this in the AI planning code was to >>select goods types such that 
>>isBuildingMaterial is true and isStorable is false.Fixed. thanks, we were 
>>wondering about that.
 
>>Please do not use tabs.Apologies. Fixed.

>> Look at similar options like saveProductionOverflow.  IMHO clearHammers* 
>> belongs right there with it, in the game options colony group.  Note that 
>> clearHammers* should be off by default in the classic rules.
This we still had a bit of trouble with. From what we can see, we implemented 
the option exactly like saveProductionOverflow, but we're not getting the 
samebehavior. 

>>You should use the CLEAR_HAMMERS_ON... constant you define in 
>>GameOptions.java when evaluating that option.Were we not doing this before? I 
>>think we were. Let us know if you mean something else but I think we fixed it.
   
>>This not a good idea.  The purpose of ColonyWas is to fire client property 
>>changes when a colony changes state, not to change the state itself.  Please 
>>do not do this.We have reverted ColonyWas as...it was.
  
>>FreeCol is a client-server application.  In BuildQueuePanel and ColonyWas you 
>>are manipulating the client.  Real changes only happen in the server.
>>With your patch, if I bring up a colony with non-zero hammers, and remove the 
>>current buildable, the hammers appear to be zero, but this is an illusion:-). 
>> Do something that causes the colony >>to be updated from the server (like 
>>moving a unit to a different building) and the hammers count goes back to 
>>what it was originally.  It is never changed in the server.Interesting. We 
>>had no idea this is how the system worked. We are still changing the colony 
>>in the UI (so that the change can be reflected in the UI, but now also 
>>changing it in the server as you recommed below. Let us know if this is not 
>>the proper way to do it.

>>The line that is critical here in BuildQueuePanel.java is this:
>>
>>getController().setBuildQueue(colony, buildables);
>>
>>When that fires, the client InGameController sends a SetBuildQueue message to 
>>the server, and receives an update back that modifies the client values.  On 
>>the server side, SetBuildQueue >>messages are ultimately handled by 
>>setBuildQueue() in the server InGameController.  That is where you need to 
>>put the logic to clear the hammers.
>>
>>What you are currently doing is clearing the hammers once on the client side 
>>in the mouse handler, but this is reverted when you quit the panel and the 
>>server is called to update the build >>queue, however hooking into ColonyWas 
>>allows you in turn to undo the effect of the server update.  Temporarily at 
>>least.Ok. I think we have fixed this. Let us know if something is still 
>>wrong. And thanks again for your help.

Thanks,-Saagar and Charlie
                                          
Index: src/net/sf/freecol/server/control/InGameController.java
===================================================================
--- src/net/sf/freecol/server/control/InGameController.java     (revision 10243)
+++ src/net/sf/freecol/server/control/InGameController.java     (working copy)
@@ -3528,6 +3528,32 @@
      */
     public Element setBuildQueue(ServerPlayer serverPlayer, Colony colony,
                                  List<BuildableType> queue) {
+       List<BuildableType> oldQueue = colony.getBuildQueue();
+       
+        /*
+         * If we removed the first thing in our queue, then we should reset to 
+         * 0 hammers. But only if the option is set. 
+         * 
+         * we have to do this twice, once here, and once in BuildQueuePanel. 
+         * 
+         * If we don't do it here, than the changes to hammers won't be saved 
+         * after editing the build queue. If we don't do it in BuildQueuePanel,
+         * then the changes in hammers won't be displayed until after you exit 
+         * the buildqueue window. 
+         */
+        if (colony.getGame().getSpecification().getBoolean(
+                "model.option.clearHammersOnConstructionSwitch")) {
+            if (queue.size() == 0 || oldQueue.size() == 0 || 
+                    !queue.get(0).equals(oldQueue.get(0))) {
+                for (Goods good : colony.getGoods()) {
+                    GoodsType goodType = good.getType();
+                    if (goodType.isBuildingMaterial() && 
!goodType.isStorable()) {
+                        //should be hammers
+                        colony.removeGoods(good.getType(), good.getAmount());
+                    }
+                }
+            }
+        }
         colony.setBuildQueue(queue);
 
         // Only visible to player.
Index: src/net/sf/freecol/server/FreeColServer.java
===================================================================
--- src/net/sf/freecol/server/FreeColServer.java        (revision 10243)
+++ src/net/sf/freecol/server/FreeColServer.java        (working copy)
@@ -1233,6 +1233,8 @@
             "gameOptions.colony", false, false);
         addIntegerOption(GameOptions.NATURAL_DISASTERS,
             "gameOptions.colony", 0, false);
+        addBooleanOption(GameOptions.CLEAR_HAMMERS_ON_CONSTRUCTION_SWITCH,
+            "gameOptions.colony", false, false);
         // Introduced: SAVEGAME_VERSION == 12
         addOptionGroup("model.difficulty.cheat", true);
         addIntegerOption("model.option.liftBoycottCheat",
Index: src/net/sf/freecol/common/model/GameOptions.java
===================================================================
--- src/net/sf/freecol/common/model/GameOptions.java    (revision 10243)
+++ src/net/sf/freecol/common/model/GameOptions.java    (working copy)
@@ -133,4 +133,7 @@
     public static final String ENABLE_UPKEEP = "model.option.enableUpkeep";
 
     public static final String NATURAL_DISASTERS = 
"model.option.naturalDisasters";
+    
+    public static final String CLEAR_HAMMERS_ON_CONSTRUCTION_SWITCH = 
+                               "model.option.clearHammersOnConstructionSwitch";
 }
Index: src/net/sf/freecol/client/gui/panel/BuildQueuePanel.java
===================================================================
--- src/net/sf/freecol/client/gui/panel/BuildQueuePanel.java    (revision 10243)
+++ src/net/sf/freecol/client/gui/panel/BuildQueuePanel.java    (working copy)
@@ -73,6 +73,9 @@
 import net.sf.freecol.common.model.Colony;
 import net.sf.freecol.common.model.FeatureContainer;
 import net.sf.freecol.common.model.FreeColGameObjectType;
+import net.sf.freecol.common.model.GameOptions;
+import net.sf.freecol.common.model.Goods;
+import net.sf.freecol.common.model.GoodsType;
 import net.sf.freecol.common.model.Limit;
 import net.sf.freecol.common.model.StringTemplate;
 import net.sf.freecol.common.model.UnitType;
@@ -100,6 +103,9 @@
     private JButton buyBuilding;
     private Colony colony;
     private int unitCount;
+    //remember the state of the build-queue upon entering
+    private final BuildableType currentlyBuilding;
+    private final List<Goods> currentlyBuildingGoods;
 
     private FeatureContainer featureContainer;
 
@@ -120,6 +126,9 @@
         this.unitCount = colony.getUnitCount();
         featureContainer = new FeatureContainer();
 
+        currentlyBuilding = colony.getCurrentlyBuilding();
+        currentlyBuildingGoods = colony.getGoods();
+        
         for (UnitType unitType : getSpecification().getUnitTypeList()) {
             if (!(unitType.getGoodsRequired().isEmpty()
                   || unitType.hasAbility(Ability.BORN_IN_COLONY))) {
@@ -128,7 +137,33 @@
             }
         }
 
-        DefaultListModel current = new DefaultListModel();
+        /**
+         * Use the decorator pattern to make sure the displayed amount of
+         * hammers stays up to date with what will happen when they click ok.
+         */
+        DefaultListModel current = new DefaultListModel() {
+            @Override
+            public void addElement(Object elt) {
+                if (this.size() == 0) { //it's empty, so we're adding to the 
front
+                    maybeRestoreGoods(this, (BuildableType)elt);
+                }
+                super.addElement(elt);
+            }
+            @Override
+            public boolean removeElement(Object elt) {
+                if (this.indexOf(elt) != -1 && maybeRemoveGoods(this, 
this.indexOf(elt))) {
+                    return super.removeElement(elt);
+                }
+                return false;
+            }
+            @Override
+            public void removeElementAt(int i) {
+                if (maybeRemoveGoods(this, i)) {
+                    super.removeElementAt(i);
+                }
+            }
+            
+        };
         for (BuildableType type : colony.getBuildQueue()) {
             current.addElement(type);
             FeatureContainer.addFeatures(featureContainer, type);
@@ -169,7 +204,7 @@
 
         buildQueueList.getInputMap().put(KeyStroke.getKeyStroke("DELETE"), 
"delete");
         buildQueueList.getActionMap().put("delete", deleteAction);
-
+        
         Action addAction = new AbstractAction() {
                 @SuppressWarnings("deprecation") // FIXME in Java7
                 public void actionPerformed(ActionEvent e) {
@@ -312,6 +347,8 @@
     private void updateBuildingList() {
         DefaultListModel buildings = (DefaultListModel) 
buildingList.getModel();
         DefaultListModel current = (DefaultListModel) 
buildQueueList.getModel();
+        
+        
         buildings.clear();
         loop: for (BuildingType buildingType : 
getSpecification().getBuildingTypeList()) {
             // compare colony.getNoBuildReason()
@@ -379,6 +416,58 @@
         }
     }
 
+    /**
+     * 
+     */
+    private void maybeRestoreGoods(DefaultListModel model, BuildableType 
addedType) {
+        if (colony.getGame().getSpecification().getBoolean(
+                GameOptions.CLEAR_HAMMERS_ON_CONSTRUCTION_SWITCH)) {
+            if (addedType.equals(currentlyBuilding)) {
+                for (Goods oldGood : currentlyBuildingGoods) {
+                    if (!colony.getGoods().contains(oldGood)) {
+                        colony.addGoods(oldGood.getType(), 
oldGood.getAmount());
+                    }
+                }
+            }
+        }
+    }
+    
+    /**
+     * Reminds the user that removing the first thing in the queue will reset
+     * their hammers (build progress) back to zero. 
+     * @param model
+     * @param i
+     * @return if they actually wanted to remove it
+     */
+    private boolean maybeRemoveGoods(DefaultListModel model, int i) {
+        boolean removed = true;
+        if (colony.getGame().getSpecification().getBoolean(
+                GameOptions.CLEAR_HAMMERS_ON_CONSTRUCTION_SWITCH)) {
+            if (i == 0) { //trying to remove the first thing
+                boolean confirm = getGUI().showConfirmDialog(
+                        "buildQueueDialog.clearHammersWarning", 
+                        "REMOVE", "CANCEL");
+                if (confirm) {
+                    for (Goods good : colony.getGoods()) {
+                        GoodsType goodType = good.getType();
+                        if (goodType.isBuildingMaterial() && 
!goodType.isStorable()) {
+                            //should only be hammers
+                            colony.removeGoods(good.getType(), 
good.getAmount());
+                        }
+                    }
+                }else {
+                    removed = false; // they cancelled
+                }
+            }
+        }
+        if (model.size() > 1) { //something else goes into the first slot
+            maybeRestoreGoods(model, (BuildableType)model.get(1));
+        }
+        return removed;
+        
+    }
+        
+
     private void updateAllLists() {
         DefaultListModel current = (DefaultListModel) 
buildQueueList.getModel();
         featureContainer = new FeatureContainer();
@@ -390,6 +479,7 @@
                 current.removeElement(type);
             }
         }
+        
         // ATTENTION: buildings must be updated first, since units
         // might depend on the build ability of an unbuildable
         // building
@@ -1024,11 +1114,12 @@
                         if (source.getSelectedIndex() == -1) {
                             
source.setSelectedIndex(source.locationToIndex(e.getPoint()));
                         }
-                        for (Object type : source.getSelectedValues()) {
+                        for (int i : source.getSelectedIndices()) {
+                            Object type = source.getModel().getElementAt(i);
                             if (add) {
                                 model.addElement(type);
-                            } else {
-                                model.removeElement(type);
+                            }else {
+                                model.removeElementAt(i);                      
         
                             }
                         }
                         updateAllLists();
Index: data/strings/FreeColMessages.properties
===================================================================
--- data/strings/FreeColMessages.properties     (revision 10243)
+++ data/strings/FreeColMessages.properties     (working copy)
@@ -186,6 +186,8 @@
 quitDialog.areYouSure.text=Are you sure you want to quit?
 retireDialog.areYouSure.text=Are you sure you want to retire?
 
+buildQueueDialog.clearHammersWarning=Warning: By removing this from your build 
queue you will forfeit all hammers that went towards building it. Are you sure 
you want to remove it?
+
 foundingFatherDialog.nominate=Nominate Founding Father
 errorMessage.showLogFile=Show log file
 
@@ -444,6 +446,8 @@
 model.option.expertsHaveConnections.shortDescription=Experts can use their 
connections to provide minimal amounts of resources for production in factories.
 model.option.saveProductionOverflow.name=Save production overflow
 model.option.saveProductionOverflow.shortDescription=Save overflow of hammers, 
bells and crosses.
+model.option.clearHammersOnConstructionSwitch.name=Clear hammers on 
construction switch
+model.option.clearHammersOnConstructionSwitch.shortDescription=Reset the 
hammers upon switching build project
 model.option.allowStudentSelection.name=Allow student selection
 model.option.allowStudentSelection.shortDescription=Allows manual rather than 
automatic assignment of students.
 model.option.enableUpkeep.name=Buildings require upkeep
Index: data/rules/freecol/specification.xml
===================================================================
--- data/rules/freecol/specification.xml        (revision 10243)
+++ data/rules/freecol/specification.xml        (working copy)
@@ -106,6 +106,8 @@
         <booleanOption id="model.option.saveProductionOverflow" 
defaultValue="false"/>
         <!-- Whether to educate the least skilled unit first -->
         <booleanOption id="model.option.allowStudentSelection" 
defaultValue="true"/>
+        <booleanOption id="model.option.clearHammersOnConstructionSwitch"
+                       defaultValue="true" />
       </optionGroup>
     </optionGroup>
   </options>
Index: data/rules/classic/specification.xml
===================================================================
--- data/rules/classic/specification.xml        (revision 10243)
+++ data/rules/classic/specification.xml        (working copy)
@@ -2731,6 +2731,8 @@
         <booleanOption id="model.option.enableUpkeep" defaultValue="false"/>
         <integerOption id="model.option.naturalDisasters" defaultValue="0"
                        minimumValue="0" maximumValue="100" />
+        <booleanOption id="model.option.clearHammersOnConstructionSwitch"
+                       defaultValue="false" />
       </optionGroup>
       <optionGroup id="gameOptions.victoryConditions">
         <!-- Victory condition: Should the player who first defeats the Royal 
Expeditionary Force win the game? -->
------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_sfd2d_oct
_______________________________________________
Freecol-developers mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/freecol-developers

Reply via email to