mirror of
https://github.com/nolen777/eagle0.git
synced 2026-07-28 20:55:44 +00:00
Base province hero cap on infrastructure (#8757)
This commit is contained in:
@@ -235,7 +235,7 @@ minimumTrustToOfferTruce 0 Int
|
||||
minimumTrustToInvite 20 Int
|
||||
minimumTrustToOfferAlliance 30 Int
|
||||
requiredPowerMultiplierForDismiss 1.5 Double
|
||||
heroCapPerCastle 5 Int
|
||||
heroCapDivisor 3.0 Double
|
||||
overHeroCapLoyaltyDelta -1 Double
|
||||
minimumAgilityForArchery 75 Double
|
||||
minimumAgilityForStartFire 70 Double
|
||||
|
||||
|
@@ -24,6 +24,7 @@ scala_library(
|
||||
"//src/main/scala/net/eagle0/eagle:eagle_pkg",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util:eagle_require",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util/hero:hero_utils",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util/province",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result/changed_province/concrete",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state:army",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/game_state",
|
||||
|
||||
+11
-3
@@ -2,6 +2,7 @@ package net.eagle0.eagle.library.actions.applier
|
||||
|
||||
import net.eagle0.eagle.*
|
||||
import net.eagle0.eagle.library.util.hero.HeroUtils
|
||||
import net.eagle0.eagle.library.util.province.ProvinceUtils
|
||||
import net.eagle0.eagle.library.util.EagleRequire.internalRequire
|
||||
import net.eagle0.eagle.model.action_result.changed_province.concrete.{ChangedProvinceC, HostileArmyStatusChange}
|
||||
import net.eagle0.eagle.model.state.{HostileArmyGroup, MovingArmy}
|
||||
@@ -74,6 +75,13 @@ object ProvinceUpdateHelpers {
|
||||
val newFood = p.food + cp.foodDelta.getOrElse(0)
|
||||
internalRequire(newFood >= 0, s"Got a foodDelta of ${cp.foodDelta} but only ${p.food} available")
|
||||
|
||||
val newInfrastructure =
|
||||
(p.infrastructure + cp.infrastructureDelta.getOrElse(0.0)).max(0.0).min(100.0)
|
||||
val newInfrastructureDevastation =
|
||||
(p.infrastructureDevastation + cp.infrastructureDevastationDelta.getOrElse(0.0))
|
||||
.max(0.0)
|
||||
.min(p.infrastructure)
|
||||
|
||||
p.copy(
|
||||
incomingShipments = incomingShipments,
|
||||
defendingArmy = defendingArmy,
|
||||
@@ -82,12 +90,12 @@ object ProvinceUpdateHelpers {
|
||||
priceIndex = cp.newPriceIndex.getOrElse(p.priceIndex),
|
||||
economy = (p.economy + cp.economyDelta.getOrElse(0.0)).max(0.0).min(100.0),
|
||||
agriculture = (p.agriculture + cp.agricultureDelta.getOrElse(0.0)).max(0.0).min(100.0),
|
||||
infrastructure = (p.infrastructure + cp.infrastructureDelta.getOrElse(0.0)).max(0.0).min(100.0),
|
||||
infrastructure = newInfrastructure,
|
||||
economyDevastation = (p.economyDevastation + cp.economyDevastationDelta.getOrElse(0.0)).max(0.0).min(p.economy),
|
||||
agricultureDevastation =
|
||||
(p.agricultureDevastation + cp.agricultureDevastationDelta.getOrElse(0.0)).max(0.0).min(p.agriculture),
|
||||
infrastructureDevastation =
|
||||
(p.infrastructureDevastation + cp.infrastructureDevastationDelta.getOrElse(0.0)).max(0.0).min(p.infrastructure),
|
||||
infrastructureDevastation = newInfrastructureDevastation,
|
||||
heroCap = ProvinceUtils.heroCap(newInfrastructure - newInfrastructureDevastation),
|
||||
support = (p.support + cp.supportDelta.getOrElse(0.0)).max(0.0).min(100.0)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3097,10 +3097,10 @@ scala_setting_library(
|
||||
)
|
||||
|
||||
scala_setting_library(
|
||||
name = "hero_cap_per_castle",
|
||||
setting_name = "HeroCapPerCastle",
|
||||
setting_type = "Int",
|
||||
setting_value = "5",
|
||||
name = "hero_cap_divisor",
|
||||
setting_name = "HeroCapDivisor",
|
||||
setting_type = "Double",
|
||||
setting_value = "3.0",
|
||||
visibility = [
|
||||
"//src/main/scala/net/eagle0/eagle:__subpackages__",
|
||||
"//src/main/scala/net/eagle0/util:__subpackages__",
|
||||
|
||||
@@ -124,7 +124,7 @@ scala_library(
|
||||
"//src/main/scala/net/eagle0/eagle/library/settings:gold_cost_for_divine",
|
||||
"//src/main/scala/net/eagle0/eagle/library/settings:gold_increase_per_economy",
|
||||
"//src/main/scala/net/eagle0/eagle/library/settings:gold_per_hero_held_back",
|
||||
"//src/main/scala/net/eagle0/eagle/library/settings:hero_cap_per_castle",
|
||||
"//src/main/scala/net/eagle0/eagle/library/settings:hero_cap_divisor",
|
||||
"//src/main/scala/net/eagle0/eagle/library/settings:history_backend",
|
||||
"//src/main/scala/net/eagle0/eagle/library/settings:improvement_per_stat",
|
||||
"//src/main/scala/net/eagle0/eagle/library/settings:improvement_reduction_max",
|
||||
|
||||
@@ -191,7 +191,6 @@ scala_library(
|
||||
deps = [
|
||||
"//src/main/scala/net/eagle0/common:tsv_utils",
|
||||
"//src/main/scala/net/eagle0/eagle:eagle_pkg",
|
||||
"//src/main/scala/net/eagle0/eagle/library/settings:hero_cap_per_castle",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util:eagle_require",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/province",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/province/concrete",
|
||||
|
||||
@@ -3,7 +3,6 @@ package net.eagle0.eagle.library.util
|
||||
import java.net.URL
|
||||
|
||||
import net.eagle0.common.TsvUtils
|
||||
import net.eagle0.eagle.library.settings.HeroCapPerCastle
|
||||
import net.eagle0.eagle.library.util.EagleRequire.internalRequire
|
||||
import net.eagle0.eagle.model.state.province.{Neighbor, ProvinceT}
|
||||
import net.eagle0.eagle.model.state.province.concrete.ProvinceC
|
||||
@@ -23,8 +22,7 @@ object MapGenerator {
|
||||
name = map("name"),
|
||||
neighbors = neighborsFromMap(map),
|
||||
hexMapName = map("hexMapName"),
|
||||
castleCount = map("castleCount").toInt,
|
||||
heroCap = map("castleCount").toInt * HeroCapPerCastle.intValue
|
||||
castleCount = map("castleCount").toInt
|
||||
)
|
||||
|
||||
def neighborsFromMap(map: Map[String, String]): Vector[Neighbor] = {
|
||||
|
||||
@@ -17,6 +17,7 @@ scala_library(
|
||||
"//src/main/scala/net/eagle0/eagle/library/settings:focus_province_storage_multiplier",
|
||||
"//src/main/scala/net/eagle0/eagle/library/settings:food_increase_per_agriculture",
|
||||
"//src/main/scala/net/eagle0/eagle/library/settings:gold_increase_per_economy",
|
||||
"//src/main/scala/net/eagle0/eagle/library/settings:hero_cap_divisor",
|
||||
"//src/main/scala/net/eagle0/eagle/library/settings:min_support_for_taxes",
|
||||
"//src/main/scala/net/eagle0/eagle/library/settings:per_development_resource_limit",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util:battalion_utils",
|
||||
|
||||
@@ -6,6 +6,7 @@ import net.eagle0.eagle.library.settings.{
|
||||
FocusProvinceStorageMultiplier,
|
||||
FoodIncreasePerAgriculture,
|
||||
GoldIncreasePerEconomy,
|
||||
HeroCapDivisor,
|
||||
MinSupportForTaxes,
|
||||
PerDevelopmentResourceLimit
|
||||
}
|
||||
@@ -67,6 +68,15 @@ object ProvinceUtils {
|
||||
def effectiveInfrastructure(province: ProvinceT): Double =
|
||||
(province.infrastructure - province.infrastructureDevastation).max(0.0)
|
||||
|
||||
def heroCap(province: ProvinceT): Int =
|
||||
heroCap(effectiveInfrastructure(province))
|
||||
|
||||
def heroCap(effectiveInfrastructure: Double): Int = {
|
||||
val divisor = HeroCapDivisor.doubleValue
|
||||
if !(divisor > 0.0) then throw new EagleInternalException(s"HeroCapDivisor must be positive, but was $divisor")
|
||||
(effectiveInfrastructure.max(0.0) / divisor).floor.toInt.max(1)
|
||||
}
|
||||
|
||||
def goldCap(province: ProvinceT, isFocusProvince: Boolean): Int =
|
||||
resourceCap(effectiveEconomy(province), effectiveInfrastructure(province), isFocusProvince)
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ scala_library(
|
||||
"//src/main/protobuf/net/eagle0/eagle/common:command_type_scala_proto",
|
||||
"//src/main/protobuf/net/eagle0/eagle/internal:province_scala_proto",
|
||||
"//src/main/scala/net/eagle0/eagle:eagle_pkg",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util/province",
|
||||
"//src/main/scala/net/eagle0/eagle/model/proto_converters:army_converter",
|
||||
"//src/main/scala/net/eagle0/eagle/model/proto_converters:battalion_type_id_converter",
|
||||
"//src/main/scala/net/eagle0/eagle/model/proto_converters:battle_revelation_converter",
|
||||
|
||||
+5
-4
@@ -24,6 +24,7 @@ import net.eagle0.eagle.internal.unaffiliated_hero.{
|
||||
CapturedHero as CapturedHeroProto,
|
||||
UnaffiliatedHero as UnaffiliatedHeroProto
|
||||
}
|
||||
import net.eagle0.eagle.library.util.province.ProvinceUtils
|
||||
import net.eagle0.eagle.model.proto_converters.{
|
||||
ArmyConverter,
|
||||
BattalionTypeIdConverter,
|
||||
@@ -101,7 +102,7 @@ object ProvinceConverter {
|
||||
pendingConquestInfo: Option[PendingConquestInfo],
|
||||
hexMapName: String,
|
||||
castleCount: Int,
|
||||
heroCap: Int,
|
||||
_ /* stored hero cap */,
|
||||
lastCommand: Option[CommandType]
|
||||
) =>
|
||||
ProvinceProto(
|
||||
@@ -148,7 +149,7 @@ object ProvinceConverter {
|
||||
pendingConquestInfo = pendingConquestInfo.map(PendingConquestInfoConverter.toProto),
|
||||
hexMapName = hexMapName,
|
||||
castleCount = castleCount,
|
||||
heroCap = heroCap
|
||||
heroCap = ProvinceUtils.heroCap((infrastructure - infrastructureDevastation).max(0.0))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -189,7 +190,7 @@ object ProvinceConverter {
|
||||
lastRiotDate: Option[DateProto],
|
||||
lastCommand: CommandTypeProto,
|
||||
castleCount: Int,
|
||||
heroCap: Int,
|
||||
_ /* stored hero cap */,
|
||||
deferredChanges: Seq[DeferredChangeProto],
|
||||
battleRevelations: Seq[BattleRevelationProto],
|
||||
pendingConquestInfoProto,
|
||||
@@ -241,7 +242,7 @@ object ProvinceConverter {
|
||||
pendingConquestInfo = pendingConquestInfoProto.map(PendingConquestInfoConverter.fromProto),
|
||||
hexMapName = hexMapName,
|
||||
castleCount = castleCount,
|
||||
heroCap = heroCap
|
||||
heroCap = ProvinceUtils.heroCap((infrastructure - infrastructureDevastation).max(0.0))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,6 +66,7 @@ scala_library(
|
||||
"//src/main/scala/net/eagle0/eagle/library/util:map_generator",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util:price_index_utils",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util/hero_generator/hero_with_name",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util/province",
|
||||
"//src/main/scala/net/eagle0/eagle/model/proto_converters:battalion_type_id_converter",
|
||||
"//src/main/scala/net/eagle0/eagle/model/proto_converters/province:order_type",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/province",
|
||||
@@ -181,6 +182,7 @@ scala_library(
|
||||
"//src/main/scala/net/eagle0/eagle/library:engine",
|
||||
"//src/main/scala/net/eagle0/eagle/library:engine_impl",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util/hero_generator",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util/province",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result/concrete:action_result_concrete",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result/types",
|
||||
"//src/main/scala/net/eagle0/eagle/model/proto_converters:battalion_converter",
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.eagle0.eagle.internal.hero.Hero
|
||||
import net.eagle0.eagle.internal.province.Province
|
||||
import net.eagle0.eagle.library.util.{MapGenerator, PriceIndexUtils}
|
||||
import net.eagle0.eagle.library.util.hero_generator.hero_with_name.HeroWithName
|
||||
import net.eagle0.eagle.library.util.province.ProvinceUtils
|
||||
import net.eagle0.eagle.library.EagleInternalException
|
||||
import net.eagle0.eagle.model.proto_converters.province.ProvinceOrderTypeConverter
|
||||
import net.eagle0.eagle.model.proto_converters.BattalionTypeIdConverter
|
||||
@@ -173,6 +174,7 @@ object GameParametersUtils {
|
||||
_.economy := provinceOverrides.economy,
|
||||
_.agriculture := provinceOverrides.agriculture,
|
||||
_.infrastructure := provinceOverrides.infrastructure,
|
||||
_.heroCap := ProvinceUtils.heroCap(provinceOverrides.infrastructure),
|
||||
_.priceIndex := PriceIndexUtils.steadyState(
|
||||
provinceOverrides.economy,
|
||||
provinceOverrides.agriculture,
|
||||
@@ -206,6 +208,7 @@ object GameParametersUtils {
|
||||
economy = provinceOverrides.economy,
|
||||
agriculture = provinceOverrides.agriculture,
|
||||
infrastructure = provinceOverrides.infrastructure,
|
||||
heroCap = ProvinceUtils.heroCap(provinceOverrides.infrastructure),
|
||||
priceIndex = PriceIndexUtils.steadyState(
|
||||
provinceOverrides.economy,
|
||||
provinceOverrides.agriculture,
|
||||
@@ -246,6 +249,7 @@ object GameParametersUtils {
|
||||
economy = overrides.economy,
|
||||
agriculture = overrides.agriculture,
|
||||
infrastructure = overrides.infrastructure,
|
||||
heroCap = ProvinceUtils.heroCap(overrides.infrastructure),
|
||||
priceIndex = PriceIndexUtils.steadyState(
|
||||
overrides.economy,
|
||||
overrides.agriculture,
|
||||
|
||||
+4
-1
@@ -6,6 +6,7 @@ import net.eagle0.common.SeededRandom
|
||||
import net.eagle0.eagle.internal.game_parameters.SetFaction.StartingTrust
|
||||
import net.eagle0.eagle.library.{EngineAndResults, EngineAndResultsImpl, EngineImpl}
|
||||
import net.eagle0.eagle.library.util.hero_generator.HeroGenerator
|
||||
import net.eagle0.eagle.library.util.province.ProvinceUtils
|
||||
import net.eagle0.eagle.model.action_result.concrete.ActionResultC
|
||||
import net.eagle0.eagle.model.action_result.types.ActionResultType
|
||||
import net.eagle0.eagle.model.proto_converters.faction.FactionConverter
|
||||
@@ -299,6 +300,7 @@ object TutorialGameCreation {
|
||||
)
|
||||
)
|
||||
val baseProvince = arWithBatts.provinceMap(po.provinceId)
|
||||
val infrastructure = if po.infrastructure > 0 then po.infrastructure else baseProvince.infrastructure
|
||||
arWithBatts.withProvince(
|
||||
baseProvince
|
||||
.updateWith(
|
||||
@@ -312,7 +314,8 @@ object TutorialGameCreation {
|
||||
support = po.support,
|
||||
economy = if po.economy > 0 then po.economy else baseProvince.economy,
|
||||
agriculture = if po.agriculture > 0 then po.agriculture else baseProvince.agriculture,
|
||||
infrastructure = if po.infrastructure > 0 then po.infrastructure else baseProvince.infrastructure
|
||||
infrastructure = infrastructure,
|
||||
heroCap = ProvinceUtils.heroCap(infrastructure)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ scala_test(
|
||||
deps = [
|
||||
"//src/main/protobuf/net/eagle0/shardok/common:hex_map_scala_proto",
|
||||
"//src/main/scala/net/eagle0/eagle:eagle_pkg",
|
||||
"//src/main/scala/net/eagle0/eagle/library/settings:hero_cap_per_castle",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util:map_generator",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/province",
|
||||
"//src/main/scala/net/eagle0/util:hex_map_utils",
|
||||
|
||||
@@ -1,20 +1,15 @@
|
||||
package net.eagle0.eagle.shardok.maps
|
||||
|
||||
import net.eagle0.eagle.library.settings.HeroCapPerCastle
|
||||
import net.eagle0.eagle.library.util.MapGenerator
|
||||
import net.eagle0.eagle.model.state.province.{Neighbor, ProvinceT}
|
||||
import net.eagle0.eagle.ProvinceId
|
||||
import net.eagle0.shardok.common.hex_map.{HexMap, MonthlyWeather}
|
||||
import org.scalatest.flatspec.AnyFlatSpec
|
||||
import org.scalatest.matchers.should.Matchers
|
||||
import org.scalatest.BeforeAndAfterEach
|
||||
|
||||
class MapValidationTest extends AnyFlatSpec with BeforeAndAfterEach with Matchers {
|
||||
class MapValidationTest extends AnyFlatSpec with Matchers {
|
||||
import net.eagle0.util.HexMapUtils.hexMap
|
||||
|
||||
override def beforeEach(): Unit =
|
||||
HeroCapPerCastle.setIntValue(3)
|
||||
|
||||
private def checkNeighbor(
|
||||
provinceName: String,
|
||||
neighbor: Neighbor,
|
||||
|
||||
+29
-1
@@ -1,6 +1,6 @@
|
||||
package net.eagle0.eagle.library.actions.applier
|
||||
|
||||
import net.eagle0.eagle.library.settings.{ExtraXpForStatBumpOver100, XpForStatBump}
|
||||
import net.eagle0.eagle.library.settings.{ExtraXpForStatBumpOver100, HeroCapDivisor, XpForStatBump}
|
||||
import net.eagle0.eagle.model.action_result.{NotificationDetails, NotificationT}
|
||||
import net.eagle0.eagle.model.action_result.changed_province.concrete.ChangedProvinceC
|
||||
import net.eagle0.eagle.model.action_result.concrete.{
|
||||
@@ -43,6 +43,7 @@ class ActionResultApplierImplTest extends AnyFlatSpec with Matchers with BeforeA
|
||||
override def beforeEach(): Unit = {
|
||||
XpForStatBump.setIntValue(100)
|
||||
ExtraXpForStatBumpOver100.setIntValue(50)
|
||||
HeroCapDivisor.setDoubleValue(3.0)
|
||||
}
|
||||
|
||||
private val applier = ActionResultApplierImpl(None)
|
||||
@@ -119,6 +120,33 @@ class ActionResultApplierImplTest extends AnyFlatSpec with Matchers with BeforeA
|
||||
result.resultingState.actionResultCount shouldBe 8
|
||||
}
|
||||
|
||||
it should "recalculate the hero cap after infrastructure devastation changes" in {
|
||||
val provinceId = 13
|
||||
val startingState = baseGameState.copy(
|
||||
provinces = Map(
|
||||
provinceId -> ProvinceC(
|
||||
id = provinceId,
|
||||
infrastructure = 45,
|
||||
infrastructureDevastation = 12,
|
||||
heroCap = 99
|
||||
)
|
||||
)
|
||||
)
|
||||
val actionResult = ActionResultC(
|
||||
actionResultType = ActionResultType.UnknownActionUnspecified,
|
||||
changedProvinces = Vector(
|
||||
ChangedProvinceC(
|
||||
provinceId = provinceId,
|
||||
infrastructureDevastationDelta = Some(6)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
val result = applier.applyActionResult(startingState, actionResult)
|
||||
|
||||
result.resultingState.provinces(provinceId).heroCap shouldBe 9
|
||||
}
|
||||
|
||||
it should "not advance command tokens for automatic results with an acting faction" in {
|
||||
val startingState = gameStateWithReturnCommand
|
||||
val actionResult = ActionResultC(
|
||||
|
||||
@@ -7,6 +7,7 @@ scala_test(
|
||||
"//src/main/scala/net/eagle0/eagle:eagle_pkg",
|
||||
"//src/main/scala/net/eagle0/eagle/library/actions/applier:action_result_applier_impl",
|
||||
"//src/main/scala/net/eagle0/eagle/library/settings:extra_xp_for_stat_bump_over100",
|
||||
"//src/main/scala/net/eagle0/eagle/library/settings:hero_cap_divisor",
|
||||
"//src/main/scala/net/eagle0/eagle/library/settings:xp_for_stat_bump",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result:notification_trait",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result/changed_province/concrete",
|
||||
|
||||
@@ -121,6 +121,7 @@ scala_test(
|
||||
"//src/main/scala/net/eagle0/eagle/library/settings:base_resource_limit",
|
||||
"//src/main/scala/net/eagle0/eagle/library/settings:focus_province_storage_multiplier",
|
||||
"//src/main/scala/net/eagle0/eagle/library/settings:food_increase_per_agriculture",
|
||||
"//src/main/scala/net/eagle0/eagle/library/settings:hero_cap_divisor",
|
||||
"//src/main/scala/net/eagle0/eagle/library/settings:improvement_per_stat",
|
||||
"//src/main/scala/net/eagle0/eagle/library/settings:improvement_reduction_max",
|
||||
"//src/main/scala/net/eagle0/eagle/library/settings:improvement_support_gain",
|
||||
@@ -168,7 +169,6 @@ scala_test(
|
||||
srcs = ["ShardokMapInfoTest.scala"],
|
||||
scalacopts = ["-deprecation"],
|
||||
deps = [
|
||||
"//src/main/scala/net/eagle0/eagle/library/settings:hero_cap_per_castle",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util:shardok_map_info",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -6,6 +6,7 @@ import net.eagle0.eagle.library.settings.{
|
||||
BaseResourceLimit,
|
||||
FocusProvinceStorageMultiplier,
|
||||
FoodIncreasePerAgriculture,
|
||||
HeroCapDivisor,
|
||||
ImprovementPerStat,
|
||||
ImprovementReductionMax,
|
||||
ImprovementSupportGain,
|
||||
@@ -82,6 +83,7 @@ class ProvinceUtilsTest extends AnyFlatSpec with Matchers with BeforeAndAfterEac
|
||||
BaseResourceLimit.setIntValue(5000)
|
||||
PerDevelopmentResourceLimit.setIntValue(50)
|
||||
FocusProvinceStorageMultiplier.setDoubleValue(1.5)
|
||||
HeroCapDivisor.setDoubleValue(3.0)
|
||||
}
|
||||
|
||||
"provinceLeader" should "return the faction head if present" in {
|
||||
@@ -374,6 +376,22 @@ class ProvinceUtilsTest extends AnyFlatSpec with Matchers with BeforeAndAfterEac
|
||||
ProvinceUtils.containsFactionLeader(province, Vector(actingFaction)) shouldBe false
|
||||
}
|
||||
|
||||
"heroCap" should "use effective infrastructure divided by the configured divisor" in {
|
||||
val province = ProvinceC(
|
||||
id = 7,
|
||||
infrastructure = 45,
|
||||
infrastructureDevastation = 12
|
||||
)
|
||||
|
||||
ProvinceUtils.heroCap(province) shouldBe 11
|
||||
}
|
||||
|
||||
it should "floor fractional values and enforce a minimum cap of one" in {
|
||||
ProvinceUtils.heroCap(effectiveInfrastructure = 100) shouldBe 33
|
||||
ProvinceUtils.heroCap(effectiveInfrastructure = 8.99) shouldBe 2
|
||||
ProvinceUtils.heroCap(effectiveInfrastructure = 0) shouldBe 1
|
||||
}
|
||||
|
||||
"foodCap / goldCap" should "use the base resource cap when the province is not a focus province" in {
|
||||
val province = ProvinceC(
|
||||
id = 7,
|
||||
|
||||
@@ -1,14 +1,9 @@
|
||||
package net.eagle0.eagle.library.util
|
||||
|
||||
import net.eagle0.eagle.library.settings.HeroCapPerCastle
|
||||
import org.scalatest.flatspec.AnyFlatSpec
|
||||
import org.scalatest.matchers.should.Matchers
|
||||
import org.scalatest.BeforeAndAfterEach
|
||||
|
||||
class ShardokMapInfoTest extends AnyFlatSpec with BeforeAndAfterEach with Matchers {
|
||||
|
||||
override def beforeEach(): Unit =
|
||||
HeroCapPerCastle.setIntValue(3)
|
||||
class ShardokMapInfoTest extends AnyFlatSpec with Matchers {
|
||||
|
||||
"mapInfos" should "have Shumal's info in position 1" in {
|
||||
val mapInfos = ShardokMapInfo.shardokMapInfos
|
||||
|
||||
-2
@@ -5,7 +5,6 @@ import net.eagle0.eagle.library.settings.{
|
||||
AlmsSupportIncreasePerFood,
|
||||
BaseFoodBuyPrice,
|
||||
GoldPerHeroHeldBack,
|
||||
HeroCapPerCastle,
|
||||
MaxCombatUnitCountPerSide,
|
||||
MinSupportForTaxes,
|
||||
MinVigorForMarch,
|
||||
@@ -71,7 +70,6 @@ class AttackCommandChooserTest extends AnyFlatSpec with Matchers with BeforeAndA
|
||||
VassalMinimumGoldToSendSupplies.setIntValue(100)
|
||||
MaxCombatUnitCountPerSide.setIntValue(10)
|
||||
MinVigorForMarch.setDoubleValue(50)
|
||||
HeroCapPerCastle.setIntValue(3)
|
||||
RequiredRatioToAttack.setDoubleValue(1.5)
|
||||
RequiredRatioToAttackWithoutTakingCastles.setDoubleValue(2.5)
|
||||
}
|
||||
|
||||
@@ -54,7 +54,6 @@ scala_test(
|
||||
"//src/main/scala/net/eagle0/eagle/library/settings:alms_support_increase_per_food",
|
||||
"//src/main/scala/net/eagle0/eagle/library/settings:base_food_buy_price",
|
||||
"//src/main/scala/net/eagle0/eagle/library/settings:gold_per_hero_held_back",
|
||||
"//src/main/scala/net/eagle0/eagle/library/settings:hero_cap_per_castle",
|
||||
"//src/main/scala/net/eagle0/eagle/library/settings:max_combat_unit_count_per_side",
|
||||
"//src/main/scala/net/eagle0/eagle/library/settings:min_support_for_taxes",
|
||||
"//src/main/scala/net/eagle0/eagle/library/settings:min_vigor_for_march",
|
||||
|
||||
@@ -1902,7 +1902,7 @@ class SqliteHistoryTest extends AnyFlatSpec with Matchers with BeforeAndAfterEac
|
||||
// ---------------- newProvinces "new entity" decomposition (v11 — RED until implemented) ----------------
|
||||
|
||||
private def province(id: Int, name: String): ProvinceC =
|
||||
ProvinceC(id = id, name = name, gold = 100, food = 50)
|
||||
ProvinceC(id = id, name = name, gold = 100, food = 50, heroCap = 1)
|
||||
|
||||
"newProvinces v11 live write + reader" should "round-trip a new province via withNewResults" in {
|
||||
// newProvinces holds full ProvinceT snapshots (no Changed* wrapper) — the deepest entity. Stored as one proto blob.
|
||||
|
||||
@@ -25,6 +25,7 @@ scala_test(
|
||||
],
|
||||
deps = [
|
||||
"//src/main/scala/net/eagle0/eagle/library:engine",
|
||||
"//src/main/scala/net/eagle0/eagle/library/settings:hero_cap_divisor",
|
||||
"//src/main/scala/net/eagle0/eagle/library/settings:history_backend",
|
||||
"//src/main/scala/net/eagle0/eagle/library/settings/loaders:battalion_type_loader",
|
||||
"//src/main/scala/net/eagle0/eagle/service:in_memory_history",
|
||||
|
||||
+10
-1
@@ -2,8 +2,8 @@ package net.eagle0.eagle.service.new_game_creation
|
||||
|
||||
import java.nio.file.Files
|
||||
|
||||
import net.eagle0.eagle.library.settings.{HeroCapDivisor, HistoryBackend}
|
||||
import net.eagle0.eagle.library.settings.loaders.BattalionTypeLoader
|
||||
import net.eagle0.eagle.library.settings.HistoryBackend
|
||||
import net.eagle0.eagle.service.{GameHistoryFactory, InMemoryHistory}
|
||||
import org.scalatest.flatspec.AnyFlatSpec
|
||||
import org.scalatest.matchers.should.Matchers
|
||||
@@ -104,6 +104,15 @@ class FixedNewGameCreationTest extends AnyFlatSpec with Matchers {
|
||||
}
|
||||
}
|
||||
|
||||
"GameParametersUtils.provincesWithoutPlayers" should "derive hero caps from generic province infrastructure" in {
|
||||
HeroCapDivisor.setDoubleValue(3.0)
|
||||
val provinces =
|
||||
GameParametersUtils.provincesWithoutPlayers(GameParametersUtils.defaultExpandedGameParameters.gameParameters)
|
||||
|
||||
all(provinces.map(_.infrastructure)) shouldBe 20.0
|
||||
all(provinces.map(_.heroCap)) shouldBe 6
|
||||
}
|
||||
|
||||
"FixedNewGameCreation" should "create the warmup-sized default game" in {
|
||||
val params = GameParametersUtils.defaultExpandedGameParameters
|
||||
|
||||
|
||||
Reference in New Issue
Block a user