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