@@ -1124,11 +1124,11 @@ private HashSet<string> GetCountyHolderIds(Date date) {
1124
1124
}
1125
1125
1126
1126
public void ImportDevelopmentFromImperator ( ProvinceCollection ck3Provinces , Date date , double irCivilizationWorth ) {
1127
- static bool IsCountyOutsideImperatorMap ( Title county , IReadOnlyDictionary < string , int > impProvsPerCounty ) {
1128
- return impProvsPerCounty [ county . Id ] == 0 ;
1127
+ static bool IsCountyOutsideImperatorMap ( Title county , IReadOnlyDictionary < string , int > irProvsPerCounty ) {
1128
+ return irProvsPerCounty [ county . Id ] == 0 ;
1129
1129
}
1130
1130
1131
- double CalculateCountyDevelopment ( Title county , IReadOnlyDictionary < ulong , int > ck3ProvsPerIRProv ) {
1131
+ double CalculateCountyDevelopment ( Title county ) {
1132
1132
double dev = 0 ;
1133
1133
IEnumerable < ulong > countyProvinceIds = county . CountyProvinceIds ;
1134
1134
int provsCount = 0 ;
@@ -1137,44 +1137,48 @@ double CalculateCountyDevelopment(Title county, IReadOnlyDictionary<ulong, int>
1137
1137
Logger . Warn ( $ "CK3 province { ck3ProvId } not found!") ;
1138
1138
continue ;
1139
1139
}
1140
- ++ provsCount ;
1141
1140
var sourceProvinces = ck3Province . ImperatorProvinces ;
1142
1141
if ( sourceProvinces . Count == 0 ) {
1143
1142
continue ;
1144
1143
}
1145
-
1146
- dev += sourceProvinces . Sum ( srcProv => srcProv . CivilizationValue / ck3ProvsPerIRProv [ srcProv . Id ] ) ;
1144
+ ++ provsCount ;
1145
+
1146
+ var devFromProvince = sourceProvinces . Average ( srcProv => srcProv . CivilizationValue ) ;
1147
+ dev += devFromProvince ;
1147
1148
}
1148
1149
1150
+ dev = Math . Max ( 0 , dev - Math . Sqrt ( dev ) ) ;
1151
+ if ( provsCount > 0 ) {
1152
+ dev /= provsCount ;
1153
+ }
1149
1154
dev *= irCivilizationWorth ;
1150
- dev /= provsCount ;
1151
- dev -= Math . Sqrt ( dev ) ;
1152
1155
return dev ;
1153
1156
}
1154
1157
1155
1158
Logger . Info ( "Importing development from Imperator..." ) ;
1156
1159
1157
1160
var counties = this . Where ( t => t . Rank == TitleRank . county ) . ToList ( ) ;
1158
- var ( irProvsPerCounty , ck3ProvsPerImperatorProv ) = GetIRProvsPerCounty ( ck3Provinces , counties ) ;
1161
+ var irProvsPerCounty = GetIRProvsPerCounty ( ck3Provinces , counties ) ;
1159
1162
1160
1163
foreach ( var county in counties ) {
1161
1164
if ( IsCountyOutsideImperatorMap ( county , irProvsPerCounty ) ) {
1162
1165
// Don't change development for counties outside of Imperator map.
1163
1166
continue ;
1164
1167
}
1165
1168
1166
- double dev = CalculateCountyDevelopment ( county , ck3ProvsPerImperatorProv ) ;
1169
+ double dev = CalculateCountyDevelopment ( county ) ;
1167
1170
1168
1171
county . History . Fields . Remove ( "development_level" ) ;
1169
1172
county . History . AddFieldValue ( date , "development_level" , "change_development_level" , ( int ) dev ) ;
1170
1173
}
1174
+
1175
+ DistributeExcessDevelopment ( date ) ;
1171
1176
1172
1177
Logger . IncrementProgress ( ) ;
1173
1178
return ;
1174
1179
1175
- static ( Dictionary < string , int > , Dictionary < ulong , int > ) GetIRProvsPerCounty ( ProvinceCollection ck3Provinces , IEnumerable < Title > counties ) {
1176
- Dictionary < string , int > impProvsPerCounty = [ ] ;
1177
- Dictionary < ulong , int > ck3ProvsPerImperatorProv = [ ] ;
1180
+ static Dictionary < string , int > GetIRProvsPerCounty ( ProvinceCollection ck3Provinces , IEnumerable < Title > counties ) {
1181
+ Dictionary < string , int > irProvsPerCounty = [ ] ;
1178
1182
foreach ( var county in counties ) {
1179
1183
HashSet < ulong > imperatorProvs = [ ] ;
1180
1184
foreach ( ulong ck3ProvId in county . CountyProvinceIds ) {
@@ -1186,15 +1190,68 @@ double CalculateCountyDevelopment(Title county, IReadOnlyDictionary<ulong, int>
1186
1190
var sourceProvinces = ck3Province . ImperatorProvinces ;
1187
1191
foreach ( var irProvince in sourceProvinces ) {
1188
1192
imperatorProvs . Add ( irProvince . Id ) ;
1189
- ck3ProvsPerImperatorProv . TryGetValue ( irProvince . Id , out var currentValue ) ;
1190
- ck3ProvsPerImperatorProv [ irProvince . Id ] = currentValue + 1 ;
1191
1193
}
1192
1194
}
1193
1195
1194
- impProvsPerCounty [ county . Id ] = imperatorProvs . Count ;
1196
+ irProvsPerCounty [ county . Id ] = imperatorProvs . Count ;
1195
1197
}
1196
1198
1197
- return ( impProvsPerCounty , ck3ProvsPerImperatorProv ) ;
1199
+ return irProvsPerCounty ;
1200
+ }
1201
+ }
1202
+
1203
+ private void DistributeExcessDevelopment ( Date date ) {
1204
+ var topRealms = this
1205
+ . Where ( t => t . Rank > TitleRank . county && t . GetHolderId ( date ) != "0" && t . GetDeFactoLiege ( date ) is null )
1206
+ . ToList ( ) ;
1207
+
1208
+ // For every realm, get list of counties with over 100 development.
1209
+ // Distribute the excess development to the realm's least developed counties.
1210
+ foreach ( var realm in topRealms ) {
1211
+ var realmCounties = realm . GetDeFactoVassalsAndBelow ( date , "c" ) . Values
1212
+ . Select ( c => new { County = c , Development = c . GetOwnOrInheritedDevelopmentLevel ( date ) } )
1213
+ . Where ( c => c . Development . HasValue )
1214
+ . Select ( c => new { c . County , Development = c . Development ! . Value } )
1215
+ . ToList ( ) ;
1216
+ var excessDevCounties = realmCounties
1217
+ . Where ( c => c . Development > 100 )
1218
+ . OrderByDescending ( c => c . Development )
1219
+ . ToList ( ) ;
1220
+ if ( excessDevCounties . Count == 0 ) {
1221
+ continue ;
1222
+ }
1223
+
1224
+ var leastDevCounties = realmCounties
1225
+ . Where ( c => c . Development < 100 )
1226
+ . OrderBy ( c => c . Development )
1227
+ . Select ( c => c . County )
1228
+ . ToList ( ) ;
1229
+ if ( leastDevCounties . Count == 0 ) {
1230
+ continue ;
1231
+ }
1232
+
1233
+ var excessDevSum = excessDevCounties . Sum ( c => c . Development - 100 ) ;
1234
+ Logger . Debug ( $ "Top realm { realm . Id } has { excessDevSum } excess development to distribute among { leastDevCounties . Count } counties.") ;
1235
+
1236
+ // Now that we've calculated the excess dev, we can cap the county dev at 100.
1237
+ foreach ( var excessDevCounty in excessDevCounties ) {
1238
+ excessDevCounty . County . SetDevelopmentLevel ( 100 , date ) ;
1239
+ }
1240
+
1241
+ while ( excessDevSum > 0 && leastDevCounties . Count > 0 ) {
1242
+ var devPerCounty = excessDevSum / leastDevCounties . Count ;
1243
+ foreach ( var county in leastDevCounties . ToList ( ) ) {
1244
+ var currentDev = county . GetOwnOrInheritedDevelopmentLevel ( date ) ?? 0 ;
1245
+ var devToAdd = Math . Max ( devPerCounty , 100 - currentDev ) ;
1246
+ var newDevValue = currentDev + devToAdd ;
1247
+
1248
+ county . SetDevelopmentLevel ( newDevValue , date ) ;
1249
+ excessDevSum -= devToAdd ;
1250
+ if ( newDevValue >= 100 ) {
1251
+ leastDevCounties . Remove ( county ) ;
1252
+ }
1253
+ }
1254
+ }
1198
1255
}
1199
1256
}
1200
1257
0 commit comments