1- using TaleWorlds . CampaignSystem ;
1+ using System ;
2+ using System . Linq ;
3+
4+ using TaleWorlds . CampaignSystem ;
25using TaleWorlds . CampaignSystem . Actions ;
6+ using TaleWorlds . CampaignSystem . Settlements ;
37using TaleWorlds . Library ;
48
59namespace Diplomacy . Actions
610{
711 public static class GiveGoldToKingdomAction
812 {
13+ private const int MinRequiredBudgetWalletSize = 2000000 ;
14+ private const int MaxRequiredClanGold = 50000 ;
15+ private const int MinRequiredShortfall = 100000 ;
16+ private const int GoldPerProsperity = 1000 ;
17+ private const int MaxRevenuePerMercenaryTier = 10000 ;
18+
919 private static void ApplyInternal ( Kingdom ? giverKingdom , Kingdom ? receiverKingdom , int amount , WalletType giverWallet , WalletType receiverWallet )
1020 {
1121 if ( amount == 0 )
1222 return ;
1323
1424 if ( giverKingdom != null )
1525 {
16- switch ( giverWallet )
17- {
18- case WalletType . TributeWallet :
19- giverKingdom . TributeWallet -= amount ;
20- break ;
21- case WalletType . BudgetWallet :
22- //Leaders should benefit from those payments too
23- var leaderAmount = amount < 0 ? amount / 3 : 0 ;
24- if ( leaderAmount > 0 ) GiveGoldAction . ApplyBetweenCharacters ( null , giverKingdom . Leader , leaderAmount ) ;
25- giverKingdom . KingdomBudgetWallet -= ( amount - leaderAmount ) ;
26- break ;
27- default :
28- break ;
29- }
26+ GetMoneyFromGiver ( giverKingdom , amount , giverWallet ) ;
3027 }
3128 if ( receiverKingdom != null )
3229 {
33- switch ( receiverWallet )
34- {
35- case WalletType . TributeWallet :
36- receiverKingdom . TributeWallet += amount ;
37- break ;
38- case WalletType . BudgetWallet :
39- //Leaders should benefit from those payments too
40- var leaderAmount = amount > 0 ? amount / 3 : 0 ;
41- if ( leaderAmount > 0 ) GiveGoldAction . ApplyBetweenCharacters ( null , receiverKingdom . Leader , leaderAmount ) ;
42- receiverKingdom . KingdomBudgetWallet += ( amount - leaderAmount ) ;
43- break ;
44- default :
45- break ;
46- }
30+ GiveMoneyToReceiver ( receiverKingdom , amount , receiverWallet ) ;
31+ }
32+ }
33+
34+ private static void GetMoneyFromGiver ( Kingdom giverKingdom , int amount , WalletType giverWallet )
35+ {
36+ switch ( giverWallet )
37+ {
38+ case WalletType . TributeWallet :
39+ giverKingdom . TributeWallet -= amount ;
40+ return ;
41+ case WalletType . BudgetWallet :
42+ giverKingdom . KingdomBudgetWallet -= amount ;
43+ return ;
44+ case WalletType . ReparationsWallet :
45+ //Cover from the kingdom budget
46+ var availableBudgetAmount = Math . Max ( giverKingdom . KingdomBudgetWallet - MinRequiredBudgetWalletSize , 0 ) ;
47+ if ( availableBudgetAmount > 0 )
48+ {
49+ var budgetCoveredAmount = Math . Min ( availableBudgetAmount , amount ) ;
50+ giverKingdom . KingdomBudgetWallet -= budgetCoveredAmount ;
51+ amount -= budgetCoveredAmount ;
52+ }
53+ if ( amount <= 0 )
54+ return ;
55+
56+ //Cover from the kingdom prosperity
57+ var tolerableAmount = giverKingdom . Clans . Where ( c => ! c . IsUnderMercenaryService && ! c . IsEliminated ) . Sum ( c => c . Gold - Math . Min ( c . Gold / 4 , MaxRequiredClanGold ) ) ;
58+ if ( tolerableAmount < amount )
59+ {
60+ var amountToCover = amount - tolerableAmount ;
61+ if ( amountToCover >= MinRequiredShortfall )
62+ {
63+ foreach ( ( var settlement , var amountToCoverBySettlement ) in MBMath . DistributeShares ( amountToCover , giverKingdom . Settlements . Where ( s => s . IsCastle || s . IsTown ) , CalculateSettlementShare ) )
64+ {
65+ settlement . Prosperity -= amountToCoverBySettlement / GoldPerProsperity ;
66+ }
67+ amount = tolerableAmount ;
68+ }
69+ }
70+
71+ giverKingdom . TributeWallet -= amount ;
72+ return ;
73+ default :
74+ return ;
75+ }
76+ }
77+
78+ private static void GiveMoneyToReceiver ( Kingdom receiverKingdom , int amount , WalletType receiverWallet )
79+ {
80+ switch ( receiverWallet )
81+ {
82+ case WalletType . TributeWallet :
83+ receiverKingdom . TributeWallet += amount ;
84+ return ;
85+ case WalletType . BudgetWallet :
86+ receiverKingdom . KingdomBudgetWallet += amount ;
87+ return ;
88+ case WalletType . ReparationsWallet :
89+ //Leaders should benefit from those payments too
90+ var leaderAmount = amount / 3 ;
91+ if ( leaderAmount > 0 ) GiveGoldAction . ApplyBetweenCharacters ( null , receiverKingdom . Leader , leaderAmount ) ;
92+ //Mercenaries
93+ var mercenaryAmount = amount / 6 ;
94+ int mercenaryAmountFact = 0 ;
95+ foreach ( ( var recipientMercClan , var amountForMercClan ) in MBMath . DistributeShares ( mercenaryAmount , receiverKingdom . Clans . Where ( c => c . IsUnderMercenaryService && ! c . IsEliminated ) , CalculateMercenaryShare ) )
96+ {
97+ var amountForMercClanFact = Math . Min ( amountForMercClan , recipientMercClan . Tier * MaxRevenuePerMercenaryTier ) ;
98+ GiveGoldAction . ApplyBetweenCharacters ( null , recipientMercClan . Leader , amountForMercClanFact ) ;
99+ mercenaryAmountFact += amountForMercClanFact ;
100+ }
101+ //Reassess
102+ amount = amount - leaderAmount - mercenaryAmountFact ;
103+ //Player
104+ var playerClan = Clan . PlayerClan ;
105+ if ( playerClan . Kingdom == receiverKingdom && ! playerClan . IsUnderMercenaryService && playerClan . Leader != receiverKingdom . Leader )
106+ {
107+ var playerAmount = MBMath . DistributeShares ( amount , receiverKingdom . Clans . Where ( c => ! c . IsUnderMercenaryService && ! c . IsEliminated ) , CalculateShare ) . FirstOrDefault ( x => x . Item1 == playerClan ) ;
108+ if ( playerAmount != default && playerAmount . Item2 > 0 )
109+ {
110+ GiveGoldAction . ApplyBetweenCharacters ( null , playerClan . Leader , playerAmount . Item2 ) ;
111+ amount -= playerAmount . Item2 ;
112+ }
113+ }
114+
115+ receiverKingdom . KingdomBudgetWallet += amount ;
116+ return ;
117+ default :
118+ return ;
47119 }
48120 }
49121
@@ -61,16 +133,15 @@ private static void ApplyInternal(Hero? giverHero, Kingdom? kingdom, int goldAmo
61133
62134 private static void GiveGoldToKingdom ( int gold , Kingdom kingdom )
63135 {
64- foreach ( ( var recipientClan , var amount ) in MBMath . DistributeShares ( gold , kingdom . Clans , CalculateShare ) )
136+ foreach ( ( var recipientClan , var amount ) in MBMath . DistributeShares ( gold , kingdom . Clans . Where ( c => ! c . IsUnderMercenaryService && ! c . IsEliminated ) , CalculateShare ) )
65137 {
66138 GiveGoldToClanAction . ApplyToClan ( recipientClan , amount ) ;
67139 }
68140 }
69141
70- private static int CalculateShare ( Clan clan )
71- {
72- return ( int ) clan . TotalStrength + ( clan == clan . Kingdom ? . Leader ? . Clan ? 1000 : 10 ) ;
73- }
142+ private static int CalculateShare ( Clan clan ) => Math . Max ( clan . Tier / 2 , 1 ) + ( clan == clan . Kingdom ? . Leader ? . Clan ? 1 : 0 ) ;
143+ private static int CalculateMercenaryShare ( Clan clan ) => Math . Max ( ( int ) clan . Influence , 1 ) ;
144+ private static int CalculateSettlementShare ( Settlement settlement ) => Math . Max ( ( int ) settlement . Prosperity , 1 ) ;
74145
75146 public static void ApplyFromHeroToKingdom ( Hero giverHero , Kingdom kingdom , int amount )
76147 {
@@ -88,6 +159,7 @@ public enum WalletType : byte
88159 MercenaryWallet = 1 ,
89160 TributeWallet = 2 ,
90161 BudgetWallet = 3 ,
162+ ReparationsWallet = 4
91163 }
92164 }
93165}
0 commit comments