BuildableType's and Colony's are often checked for whether they are able to build certain BuildableType in general (different from whether a Colony can do it right now, eg. required resources available).
Instead of directly going to the low-level ability test, introduce an semantic interface, se we can change implementation beind easily (eg. add some caching in front of the expensive ability computations) --- .../sf/freecol/client/gui/panel/BuildQueuePanel.java | 4 ++-- src/net/sf/freecol/common/model/BuildableType.java | 20 ++++++++++++++++++++ src/net/sf/freecol/common/model/BuildingType.java | 2 +- src/net/sf/freecol/common/model/Colony.java | 20 ++++++++++++++++++++ .../sf/freecol/common/model/FeatureContainer.java | 11 +++++++++++ src/net/sf/freecol/common/model/UnitType.java | 8 ++++---- src/net/sf/freecol/server/ai/ColonyPlan.java | 2 +- 7 files changed, 59 insertions(+), 8 deletions(-) diff --git a/src/net/sf/freecol/client/gui/panel/BuildQueuePanel.java b/src/net/sf/freecol/client/gui/panel/BuildQueuePanel.java index f1b6237fbd9..414e1f2ca23 100644 --- a/src/net/sf/freecol/client/gui/panel/BuildQueuePanel.java +++ b/src/net/sf/freecol/client/gui/panel/BuildQueuePanel.java @@ -869,8 +869,8 @@ public class BuildQueuePanel extends FreeColPanel implements ItemListener { if (!checkAbilities(ut, reasons)) unbuildableTypes.add(ut); // Missing unit build ability? - if (!this.featureContainer.hasAbility(Ability.BUILD, ut, Turn.UNDEFINED) - && !this.colony.hasAbility(Ability.BUILD, ut, turn)) { + if (!this.featureContainer.ableToBuild(ut) + && !this.colony.ableToBuild(ut, turn)) { Ability buildAbility = find(spec.getAbilities(Ability.BUILD), a -> (a.appliesTo(ut) && a.getValue() diff --git a/src/net/sf/freecol/common/model/BuildableType.java b/src/net/sf/freecol/common/model/BuildableType.java index f8d55245006..ed99077e876 100644 --- a/src/net/sf/freecol/common/model/BuildableType.java +++ b/src/net/sf/freecol/common/model/BuildableType.java @@ -235,6 +235,26 @@ public abstract class BuildableType extends FreeColSpecObjectType { } /** + * Returns true if this Object is in general able to build the given + * BuildableType. This is different to canBuild() in that it just + * checks the general ability, not other factors, eg. available goods etc. + * + * @param buildableType a {@code BuildableType} value + * @return a {@code boolean} value + */ + public final boolean ableToBuild(BuildableType buildableType) { + return hasAbility(Ability.BUILD, buildableType); + } + + public final boolean ableToBuild(BuildableType buildableType, int turn) { + return hasAbility(Ability.BUILD, buildableType, turn); + } + + public final boolean ableToBuild() { + return hasAbility(Ability.BUILD); + } + + /** * Check to see if this buildable type can be built in a colony * based on the buildings or units available. * diff --git a/src/net/sf/freecol/common/model/BuildingType.java b/src/net/sf/freecol/common/model/BuildingType.java index d8ab71471d6..72375ef7576 100644 --- a/src/net/sf/freecol/common/model/BuildingType.java +++ b/src/net/sf/freecol/common/model/BuildingType.java @@ -428,7 +428,7 @@ public final class BuildingType extends BuildableType && upgradesTo.equals(toBuild)) return index; // Don't go past a unit this building can build. - if (this.hasAbility(Ability.BUILD, toBuild)) { + if (this.ableToBuild(toBuild)) { return index; } } diff --git a/src/net/sf/freecol/common/model/Colony.java b/src/net/sf/freecol/common/model/Colony.java index ccbdef04374..d9c59d3e725 100644 --- a/src/net/sf/freecol/common/model/Colony.java +++ b/src/net/sf/freecol/common/model/Colony.java @@ -980,6 +980,26 @@ public class Colony extends Settlement implements Nameable, TradeLocation { } /** + * Returns true if this Colony is in general able to build the given + * BuildableType. This is different to canBuild() in that it just + * checks the general ability, not other factors, eg. available goods etc. + * + * @param buildableType a {@code BuildableType} value + * @return a {@code boolean} value + */ + public final boolean ableToBuild(BuildableType buildableType) { + // FIXME: we could add some caching here, but for that we'd have to + // work out the actual keys and invalidation criteria. Hopefully, + // that should be a global cache, not per Colony. But that really + // needs some deeper thoughts + return hasAbility(Ability.BUILD, buildableType); + } + + public final boolean ableToBuild(BuildableType buildableType, int turn) { + return hasAbility(Ability.BUILD, buildableType, turn); + } + + /** * Return the reason why the give {@code BuildableType} can * not be built. * diff --git a/src/net/sf/freecol/common/model/FeatureContainer.java b/src/net/sf/freecol/common/model/FeatureContainer.java index ca2de20a884..a08f8971bd0 100644 --- a/src/net/sf/freecol/common/model/FeatureContainer.java +++ b/src/net/sf/freecol/common/model/FeatureContainer.java @@ -250,6 +250,17 @@ public final class FeatureContainer { } } + /** + * Returns true if this Object is in general able to build the given + * BuildableType. This is different to canBuild() in that it just + * checks the general ability, not other factors, eg. available goods etc. + * + * @param buildableType a {@code BuildableType} value + * @return a {@code boolean} value + */ + public final boolean ableToBuild(BuildableType buildableType) { + return hasAbility(Ability.BUILD, buildableType, Turn.UNDEFINED); + } /** * Gets the set of modifiers with the given identifier from this diff --git a/src/net/sf/freecol/common/model/UnitType.java b/src/net/sf/freecol/common/model/UnitType.java index d386854b203..25d32371666 100644 --- a/src/net/sf/freecol/common/model/UnitType.java +++ b/src/net/sf/freecol/common/model/UnitType.java @@ -536,8 +536,8 @@ public final class UnitType extends BuildableType implements Consumer { List<BuildableType> assumeBuilt) { // Non-person units need a BUILD ability, present or assumed. if (!hasAbility(Ability.PERSON) - && !colony.hasAbility(Ability.BUILD, this) - && none(assumeBuilt, bt -> bt.hasAbility(Ability.BUILD, this))) { + && !colony.ableToBuild(this) + && none(assumeBuilt, bt -> bt.ableToBuild(this))) { return Colony.NoBuildReason.MISSING_BUILD_ABILITY; } return Colony.NoBuildReason.NONE; @@ -548,7 +548,7 @@ public final class UnitType extends BuildableType implements Consumer { ListModel<BuildableType> buildQueue = buildQueueList.getModel(); if (colony.canBuild(this)) return 0; for (int index = 0; index < buildQueue.getSize(); index++) { - if (buildQueue.getElementAt(index).hasAbility(Ability.BUILD, this)) return index + 1; + if (buildQueue.getElementAt(index).ableToBuild(this)) return index + 1; } return UNABLE_TO_BUILD; } @@ -570,7 +570,7 @@ public final class UnitType extends BuildableType implements Consumer { for (int index = 0; index < buildQueue.getSize(); index++) { BuildableType toBuild = buildQueue.getElementAt(index); if (toBuild == this) continue; - if (toBuild.hasAbility(Ability.BUILD, this)) { + if (toBuild.ableToBuild(this)) { return buildQueueLastPos; } } diff --git a/src/net/sf/freecol/server/ai/ColonyPlan.java b/src/net/sf/freecol/server/ai/ColonyPlan.java index f0d0232012d..bdd7733831a 100644 --- a/src/net/sf/freecol/server/ai/ColonyPlan.java +++ b/src/net/sf/freecol/server/ai/ColonyPlan.java @@ -722,7 +722,7 @@ public class ColonyPlan { prioritize(type, FISH_WEIGHT, factor); } - if (type.hasAbility(Ability.BUILD)) { + if (type.ableToBuild()) { double factor = ("building".equals(advantage)) ? 1.1 : 1.0; double support = (any(type.getAbilities(Ability.BUILD), Ability::hasScope)) ? 0.1 : 1.0; -- 2.11.0.rc0.7.gbe5a750 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot _______________________________________________ Freecol-developers mailing list Freecol-developers@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/freecol-developers