1 #include "building/caravanserai.h"
2 #include "building/lighthouse.h"
3 #include "building/model.h"
4 #include "building/monument.h"
5 #include "city/buildings.h"
6 #include "city/resource.h"
7 #include "city/trade_policy.h"
8 #include "core/calc.h"
9 #include "trade_prices.h"
10 
11 struct trade_price {
12     int32_t buy;
13     int32_t sell;
14 };
15 
16 static const struct trade_price DEFAULT_PRICES[RESOURCE_MAX] = {
17     {0, 0}, {28, 22}, {38, 30}, {38, 30}, // wheat, vegetables, fruit
18     {42, 34}, {44, 36}, {44, 36}, {215, 160}, // olives, vines, meat, wine
19     {180, 140}, {60, 40}, {50, 35}, {40, 30}, // oil, iron, timber, clay
20     {200, 140}, {250, 180}, {200, 150}, {180, 140} // marble, weapons, furniture, pottery
21 };
22 
23 static struct trade_price prices[RESOURCE_MAX];
24 
trade_percentage_from_laborers(int percent,building * b)25 static int trade_percentage_from_laborers(int percent, building *b)
26 {
27     int percent_laborers = 0;
28     // get workers percentage
29     int pct_workers = calc_percentage(b->num_workers, model_get_building(b->type)->laborers);
30     if (pct_workers >= 100) { // full laborers
31         percent_laborers = percent;
32     } else if (pct_workers > 0) {
33         percent_laborers = percent / 2;
34     }
35     return percent_laborers;
36 }
37 
trade_get_caravanserai_factor(int percent)38 static int trade_get_caravanserai_factor(int percent)
39 {
40     int caravanserai_percent = 0;
41     if (building_caravanserai_is_fully_functional()) {
42         building *b = building_get(city_buildings_get_caravanserai());
43         caravanserai_percent = trade_percentage_from_laborers(percent, b);
44     }
45     return caravanserai_percent;
46 }
47 
trade_get_lighthouse_factor(int percent)48 static int trade_get_lighthouse_factor(int percent)
49 {
50     int lighthouse_percent = 0;
51 
52     if (building_lighthouse_is_fully_functional()) {
53         building *b = building_get(building_find(BUILDING_LIGHTHOUSE));
54         lighthouse_percent = trade_percentage_from_laborers(percent, b);
55     }
56     return lighthouse_percent;
57 }
58 
trade_factor_sell(int land_trader)59 static int trade_factor_sell(int land_trader)
60 {
61     int percent = 0;
62     if (land_trader && city_buildings_has_caravanserai()) {
63         trade_policy policy = city_trade_policy_get(LAND_TRADE_POLICY);
64 
65         if (policy == TRADE_POLICY_1) {
66             percent = trade_get_caravanserai_factor(POLICY_1_BONUS_PERCENT); // trader buy 20% more
67         } else if (policy == TRADE_POLICY_2) {
68             percent -= trade_get_caravanserai_factor(POLICY_2_MALUS_PERCENT); // trader buy 10% less
69         }
70     } else if (!land_trader && building_find(BUILDING_LIGHTHOUSE)) {
71         trade_policy policy = city_trade_policy_get(SEA_TRADE_POLICY);
72 
73         if (policy == TRADE_POLICY_1) {
74             percent = trade_get_lighthouse_factor(POLICY_1_BONUS_PERCENT); // trader buy 20% more
75         } else if (policy == TRADE_POLICY_2) {
76             percent -= trade_get_lighthouse_factor(POLICY_2_MALUS_PERCENT); // trader buy 10% less
77         }
78     }
79     return percent;
80 }
81 
trade_factor_buy(int land_trader)82 static int trade_factor_buy(int land_trader)
83 {
84     int percent = 0;
85     if (land_trader && city_buildings_has_caravanserai()) {
86         trade_policy policy = city_trade_policy_get(LAND_TRADE_POLICY);
87 
88         if (policy == TRADE_POLICY_1) {
89             percent = trade_get_caravanserai_factor(POLICY_1_MALUS_PERCENT); // player buy 10% more
90         } else if (policy == TRADE_POLICY_2) {
91             percent -= trade_get_caravanserai_factor(POLICY_2_BONUS_PERCENT); // player buy 20% less
92         }
93     } else if (!land_trader && building_find(BUILDING_LIGHTHOUSE)) {
94         trade_policy policy = city_trade_policy_get(SEA_TRADE_POLICY);
95 
96         if (policy == TRADE_POLICY_1) {
97             percent = trade_get_lighthouse_factor(POLICY_1_MALUS_PERCENT); // player buy 10% more
98         } else if (policy == TRADE_POLICY_2) {
99             percent -= trade_get_lighthouse_factor(POLICY_2_BONUS_PERCENT); // player buy 20% less
100         }
101     }
102     return percent;
103 }
104 
trade_prices_reset(void)105 void trade_prices_reset(void)
106 {
107     for (int i = 0; i < RESOURCE_MAX; i++) {
108         prices[i] = DEFAULT_PRICES[i];
109     }
110 }
111 
trade_price_buy(resource_type resource,int land_trader)112 int trade_price_buy(resource_type resource, int land_trader)
113 {
114     return calc_adjust_with_percentage(prices[resource].buy, 100 + trade_factor_buy(land_trader));
115 }
116 
trade_price_sell(resource_type resource,int land_trader)117 int trade_price_sell(resource_type resource, int land_trader)
118 {
119     return calc_adjust_with_percentage(prices[resource].sell, 100 + trade_factor_sell(land_trader));
120 }
121 
trade_price_change(resource_type resource,int amount)122 int trade_price_change(resource_type resource, int amount)
123 {
124     if (amount < 0 && prices[resource].sell <= 0) {
125         // cannot lower the price to negative
126         return 0;
127     }
128     if (amount < 0 && prices[resource].sell <= -amount) {
129         prices[resource].buy = 2;
130         prices[resource].sell = 0;
131     } else {
132         prices[resource].buy += amount;
133         prices[resource].sell += amount;
134     }
135     return 1;
136 }
137 
trade_prices_save_state(buffer * buf)138 void trade_prices_save_state(buffer *buf)
139 {
140     for (int i = 0; i < RESOURCE_MAX; i++) {
141         buffer_write_i32(buf, prices[i].buy);
142         buffer_write_i32(buf, prices[i].sell);
143     }
144 }
145 
trade_prices_load_state(buffer * buf)146 void trade_prices_load_state(buffer *buf)
147 {
148     for (int i = 0; i < RESOURCE_MAX; i++) {
149         prices[i].buy = buffer_read_i32(buf);
150         prices[i].sell = buffer_read_i32(buf);
151     }
152 }
153