mirror of https://github.com/FreeCol/freecol.git
Fixes colony tile production so that the values matches the classic.
This commit is contained in:
parent
73fcf5cf13
commit
d20dedb592
|
@ -144,6 +144,7 @@ public class Modifier extends Feature {
|
|||
public static final int RESOURCE_PRODUCTION_INDEX = 10;
|
||||
public static final int COLONY_PRODUCTION_INDEX = 20;
|
||||
public static final int EXPERT_PRODUCTION_INDEX = 30;
|
||||
public static final int COLONYTILE_PRODUCTION_INDEX = 35;
|
||||
public static final int FATHER_PRODUCTION_INDEX = 40;
|
||||
public static final int IMPROVEMENT_PRODUCTION_INDEX = 50;
|
||||
public static final int AUTO_PRODUCTION_INDEX = 60;
|
||||
|
|
|
@ -1788,10 +1788,12 @@ public final class Tile extends UnitLocation implements Named, Ownable {
|
|||
// Try applying all possible non-natural improvements.
|
||||
final List<TileImprovementType> improvements
|
||||
= getSpecification().getTileImprovementTypeList();
|
||||
for (TileImprovementType ti : transform(improvements, ti ->
|
||||
(!ti.isNatural() && ti.isTileTypeAllowed(tileType)
|
||||
&& ti.getBonus(goodsType) > 0))) {
|
||||
potential = ti.getProductionModifier(goodsType).applyTo(potential);
|
||||
if (canProduce(goodsType, unitType)) {
|
||||
for (TileImprovementType ti : transform(improvements, ti ->
|
||||
(!ti.isNatural() && ti.isTileTypeAllowed(tileType)
|
||||
&& ti.getBonus(goodsType) > 0))) {
|
||||
potential = ti.getProductionModifier(goodsType).applyTo(potential);
|
||||
}
|
||||
}
|
||||
return (int)potential;
|
||||
}
|
||||
|
|
|
@ -580,17 +580,37 @@ public class TileImprovement extends TileItem {
|
|||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Stream<Modifier> getProductionModifiers(GoodsType goodsType,
|
||||
UnitType unitType) {
|
||||
public Stream<Modifier> getProductionModifiers(GoodsType goodsType, UnitType unitType) {
|
||||
if (goodsType == null || !isComplete()) {
|
||||
return Stream.<Modifier>empty();
|
||||
}
|
||||
|
||||
final Specification spec = getSpecification();
|
||||
Modifier m;
|
||||
return (goodsType != null && isComplete()
|
||||
&& !(/* unattended */ !isNatural() && unitType == null
|
||||
|
||||
if (!isNatural()
|
||||
&& unitType == null
|
||||
&& !goodsType.isFoodType()
|
||||
&& spec.getBoolean(GameOptions.ONLY_NATURAL_IMPROVEMENTS))
|
||||
&& (m = getProductionModifier(goodsType)) != null)
|
||||
? Stream.of(m)
|
||||
: Stream.<Modifier>empty();
|
||||
&& spec.getBoolean(GameOptions.ONLY_NATURAL_IMPROVEMENTS)) {
|
||||
return Stream.<Modifier>empty();
|
||||
}
|
||||
|
||||
Modifier m = getProductionModifier(goodsType);
|
||||
if (m == null) {
|
||||
return Stream.<Modifier>empty();
|
||||
}
|
||||
|
||||
if (unitType != null
|
||||
&& unitType.getExpertProduction() != null
|
||||
&& unitType.getExpertProduction().equals(goodsType)) {
|
||||
final Stream<Modifier> expertMultiplicativeModifier = unitType.getModifiers(goodsType.getId(), tile.getType(), null)
|
||||
.filter(mod -> mod.getType() == Modifier.ModifierType.MULTIPLICATIVE);
|
||||
|
||||
final float expertBonus = FeatureContainer.applyModifiers(m.getValue(), null, expertMultiplicativeModifier);
|
||||
m = Modifier.makeModifier(m);
|
||||
m.setValue(expertBonus);
|
||||
}
|
||||
|
||||
return Stream.of(m);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -367,7 +367,7 @@ public class BuildingProductionCalculator {
|
|||
return (unitType != null)
|
||||
// With a unit, unit specific bonuses apply
|
||||
? concat(buildingType.getModifiers(id, unitType, turn),
|
||||
ProductionUtils.getRebelProductionModifiers(colonyProductionBonus, goodsType, buildingType),
|
||||
ProductionUtils.getRebelProductionModifiersForBuilding(buildingType, colonyProductionBonus, goodsType, unitType),
|
||||
buildingType.getCompetenceModifiers(id, unitType, turn),
|
||||
(owner == null) ? null : owner.getModifiers(id, unitType, turn))
|
||||
// With no unit, only the building-specific bonuses
|
||||
|
|
|
@ -3,9 +3,12 @@ package net.sf.freecol.common.model.production;
|
|||
import java.util.stream.Stream;
|
||||
|
||||
import net.sf.freecol.common.model.BuildingType;
|
||||
import net.sf.freecol.common.model.FeatureContainer;
|
||||
import net.sf.freecol.common.model.GoodsType;
|
||||
import net.sf.freecol.common.model.Modifier;
|
||||
import net.sf.freecol.common.model.Specification;
|
||||
import net.sf.freecol.common.model.Tile;
|
||||
import net.sf.freecol.common.model.UnitType;
|
||||
|
||||
public final class ProductionUtils {
|
||||
|
||||
|
@ -16,21 +19,58 @@ public final class ProductionUtils {
|
|||
* Gets the current production {@code Modifier}, which is
|
||||
* generated from the current production bonus.
|
||||
*
|
||||
* @param colonyProductionBonus The production bonus in the colony.
|
||||
* @param goodsType The {@code GoodsType} to produce.
|
||||
* @param buildingType A {@code BuildingType} for getting a rebel factor. Use {@code null}
|
||||
* for a tile.
|
||||
* @param colonyProductionBonus The production bonus in the colony.
|
||||
* @param goodsType The {@code GoodsType} to produce.
|
||||
* @param unitType The unit that is working in the building
|
||||
* @return A stream of suitable {@code Modifier}s.
|
||||
*/
|
||||
public static Stream<Modifier> getRebelProductionModifiers(int colonyProductionBonus,
|
||||
GoodsType goodsType, BuildingType buildingType) {
|
||||
public static Stream<Modifier> getRebelProductionModifiersForBuilding(BuildingType buildingType, int colonyProductionBonus, GoodsType goodsType, UnitType unitType) {
|
||||
if (colonyProductionBonus == 0) {
|
||||
return Stream.<Modifier>empty();
|
||||
}
|
||||
final float rebelFactor = (buildingType != null) ? buildingType.getRebelFactor() : 1.0F;
|
||||
if (colonyProductionBonus == 0) return Stream.<Modifier>empty();
|
||||
int bonus = (int)Math.floor(colonyProductionBonus * rebelFactor);
|
||||
final int bonus = (int) Math.floor(colonyProductionBonus * rebelFactor);
|
||||
Modifier mod = new Modifier(goodsType.getId(), bonus,
|
||||
Modifier.ModifierType.ADDITIVE,
|
||||
Specification.SOL_MODIFIER_SOURCE);
|
||||
mod.setModifierIndex(Modifier.COLONY_PRODUCTION_INDEX);
|
||||
return Stream.of(mod);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current production {@code Modifier}, which is
|
||||
* generated from the current production bonus.
|
||||
*
|
||||
* @param colonyProductionBonus The production bonus in the colony.
|
||||
* @param goodsType The {@code GoodsType} to produce.
|
||||
* @param unitType The unit that is working on the tile.
|
||||
* @return A stream of suitable {@code Modifier}s.
|
||||
*/
|
||||
public static Stream<Modifier> getRebelProductionModifiersForTile(Tile tile, int colonyProductionBonus, GoodsType goodsType, UnitType unitType) {
|
||||
if (colonyProductionBonus == 0) {
|
||||
return Stream.<Modifier>empty();
|
||||
}
|
||||
|
||||
float rebelFactor = 1.0F;
|
||||
if (unitType != null
|
||||
&& unitType.getExpertProduction() != null
|
||||
&& unitType.getExpertProduction().equals(goodsType)) {
|
||||
rebelFactor *= 2.0F;
|
||||
}
|
||||
if (tile.getResource() != null) {
|
||||
final Stream<Modifier> multiplicativeResourceModifiers = tile.getResource().getProductionModifiers(goodsType, unitType)
|
||||
.filter(m -> m.getType() == Modifier.ModifierType.MULTIPLICATIVE);
|
||||
|
||||
rebelFactor = FeatureContainer.applyModifiers(rebelFactor, tile.getGame().getTurn(), multiplicativeResourceModifiers);
|
||||
}
|
||||
|
||||
int bonus = (int) Math.max(colonyProductionBonus, Math.floor(colonyProductionBonus * rebelFactor));
|
||||
Modifier mod = new Modifier(goodsType.getId(), bonus,
|
||||
Modifier.ModifierType.ADDITIVE,
|
||||
Specification.SOL_MODIFIER_SOURCE);
|
||||
mod.setModifierIndex(Modifier.COLONYTILE_PRODUCTION_INDEX);
|
||||
return Stream.of(mod);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -179,10 +179,10 @@ public class TileProductionCalculator {
|
|||
}
|
||||
|
||||
return concat(tile.getProductionModifiers(goodsType, unitType),
|
||||
ProductionUtils.getRebelProductionModifiers(colonyProductionBonus, goodsType, null),
|
||||
unitType.getModifiers(goodsType.getId(), tile.getType(), turn),
|
||||
((owner == null) ? null
|
||||
: owner.getModifiers(goodsType.getId(), unitType, turn)));
|
||||
unitType.getModifiers(goodsType.getId(), tile.getType(), turn),
|
||||
((owner == null) ? null
|
||||
: owner.getModifiers(goodsType.getId(), unitType, turn)),
|
||||
ProductionUtils.getRebelProductionModifiersForTile(tile, colonyProductionBonus, goodsType, unitType));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -198,7 +198,7 @@ public class TileProductionCalculator {
|
|||
return Stream.<Modifier>empty();
|
||||
}
|
||||
return concat(tile.getProductionModifiers(goodsType, null),
|
||||
ProductionUtils.getRebelProductionModifiers(colonyProductionBonus, goodsType, null),
|
||||
ProductionUtils.getRebelProductionModifiersForTile(tile, colonyProductionBonus, goodsType, null),
|
||||
// This does not seem to influence center tile production, but was present in the old code.
|
||||
//colony.getModifiers(id, null, turn),
|
||||
((owner == null) ? null
|
||||
|
|
|
@ -23,9 +23,14 @@ import static net.sf.freecol.common.util.CollectionUtils.any;
|
|||
import static net.sf.freecol.common.util.CollectionUtils.count;
|
||||
import static net.sf.freecol.common.util.CollectionUtils.matchKeyEquals;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import net.sf.freecol.common.model.production.TileProductionCalculator;
|
||||
import net.sf.freecol.common.model.production.WorkerAssignment;
|
||||
import net.sf.freecol.util.test.FreeColTestCase;
|
||||
import net.sf.freecol.util.test.FreeColTestUtils;
|
||||
|
||||
|
@ -330,7 +335,7 @@ public class TileTest extends FreeColTestCase {
|
|||
tile2.getPotentialProduction(grain, colonistType));
|
||||
assertEquals("Plains/grain/colonist max", 6,
|
||||
tile2.getMaximumPotential(grain, colonistType));
|
||||
assertEquals("Plains/grain/expertFarmer", 8,
|
||||
assertEquals("Plains/grain/expertFarmer", 7,
|
||||
tile2.getPotentialProduction(grain, expertFarmerType));
|
||||
tile2.addResource(new Resource(game, tile2, grainResource));
|
||||
assertEquals("Plains+Resource/grain", 7,
|
||||
|
@ -341,9 +346,9 @@ public class TileTest extends FreeColTestCase {
|
|||
tile2.getPotentialProduction(grain, colonistType));
|
||||
assertEquals("Plains+Resource/grain/colonist max", 8,
|
||||
tile2.getMaximumPotential(grain, colonistType));
|
||||
assertEquals("Plains+Resource/grain/expertFarmer", 12,
|
||||
assertEquals("Plains+Resource/grain/expertFarmer", 11,
|
||||
tile2.getPotentialProduction(grain, expertFarmerType));
|
||||
assertEquals("Plains+Resource/grain/expertFarmer max", 13,
|
||||
assertEquals("Plains+Resource/grain/expertFarmer max", 12,
|
||||
tile2.getMaximumPotential(grain, expertFarmerType));
|
||||
|
||||
Tile tile3 = new Tile(game, plainsForest, 1, 1);
|
||||
|
@ -351,6 +356,14 @@ public class TileTest extends FreeColTestCase {
|
|||
tile3.getPotentialProduction(grain, null));
|
||||
assertEquals("Forest/grain max", 6,
|
||||
tile3.getMaximumPotential(grain, null));
|
||||
assertEquals("Forest/lumber/colonist", 6,
|
||||
tile3.getPotentialProduction(lumber, colonistType));
|
||||
assertEquals("Forest/lumber/colonist max", 8,
|
||||
tile3.getMaximumPotential(lumber, colonistType));
|
||||
assertEquals("Forest/lumber/expertLumberJack", 12,
|
||||
tile3.getPotentialProduction(lumber, expertLumberJack));
|
||||
assertEquals("Forest/lumber/expertLumberJack max", 14,
|
||||
tile3.getMaximumPotential(lumber, expertLumberJack));
|
||||
}
|
||||
|
||||
public void testIsTileTypeAllowed() {
|
||||
|
@ -677,8 +690,8 @@ public class TileTest extends FreeColTestCase {
|
|||
unit.setLocation(ct);
|
||||
unit.changeWorkType(lumber);
|
||||
int result = base * expertBonus;
|
||||
if (t.hasRiver()) result += riverBonus;
|
||||
if (t.hasRoad()) result += roadBonus;
|
||||
if (t.hasRiver()) result += riverBonus * expertBonus;
|
||||
if (t.hasRoad()) result += roadBonus * expertBonus;
|
||||
if (t.hasResource()) result += resourceBonus * expertBonus;
|
||||
assertEquals("Expert lumber production at tile " + i, result,
|
||||
ct.getTotalProductionOf(lumber));
|
||||
|
|
Loading…
Reference in New Issue