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