1 /* ---------------------------------------------------------------------- *
2 * port.c
3 * This file is part of lincity.
4 * Lincity is copyright (c) I J Peters 1995-1997, (c) Greg Sharp 1997-2001.
5 * (c) Corey Keasling, 2004
6 * ---------------------------------------------------------------------- */
7
8 #include "modules.h"
9 #include "port.h"
10
buy_food(int xt,int yt)11 static int buy_food(int xt, int yt)
12 {
13 int i = 0;
14 if (MP_GROUP(xt, yt) == GROUP_TRACK) {
15 if (MP_INFO(xt, yt).int_1 < MAX_FOOD_ON_TRACK)
16 i = MAX_FOOD_ON_TRACK - MP_INFO(xt, yt).int_1;
17 } else if (MP_GROUP(xt, yt) == GROUP_ROAD) {
18 if (MP_INFO(xt, yt).int_1 < MAX_FOOD_ON_ROAD)
19 i = MAX_FOOD_ON_ROAD - MP_INFO(xt, yt).int_1;
20 } else if (MP_GROUP(xt, yt) == GROUP_RAIL) {
21 if (MP_INFO(xt, yt).int_1 < MAX_FOOD_ON_RAIL)
22 i = MAX_FOOD_ON_RAIL - MP_INFO(xt, yt).int_1;
23 }
24 i = (i * PORT_IMPORT_RATE) / 1000;
25 MP_INFO(xt, yt).int_1 += i;
26 return (i * PORT_FOOD_RATE);
27 }
28
buy_coal(int xt,int yt)29 static int buy_coal(int xt, int yt)
30 {
31 int i = 0;
32 if (MP_GROUP(xt, yt) == GROUP_TRACK) {
33 if (MP_INFO(xt, yt).int_3 < MAX_COAL_ON_TRACK)
34 i = MAX_COAL_ON_TRACK - MP_INFO(xt, yt).int_3;
35 } else if (MP_GROUP(xt, yt) == GROUP_ROAD) {
36 if (MP_INFO(xt, yt).int_3 < MAX_COAL_ON_ROAD)
37 i = MAX_COAL_ON_ROAD - MP_INFO(xt, yt).int_3;
38 } else if (MP_GROUP(xt, yt) == GROUP_RAIL) {
39 if (MP_INFO(xt, yt).int_3 < MAX_COAL_ON_RAIL)
40 i = MAX_COAL_ON_RAIL - MP_INFO(xt, yt).int_3;
41 }
42 i = (i * PORT_IMPORT_RATE) / 1000;
43 MP_INFO(xt, yt).int_3 += i;
44 return (i * PORT_COAL_RATE);
45 }
46
buy_ore(int xt,int yt)47 static int buy_ore(int xt, int yt)
48 {
49 int i = 0;
50 if (MP_GROUP(xt, yt) == GROUP_TRACK) {
51 if (MP_INFO(xt, yt).int_5 < MAX_ORE_ON_TRACK)
52 i = MAX_ORE_ON_TRACK - MP_INFO(xt, yt).int_5;
53 } else if (MP_GROUP(xt, yt) == GROUP_ROAD) {
54 if (MP_INFO(xt, yt).int_5 < MAX_ORE_ON_ROAD)
55 i = MAX_ORE_ON_ROAD - MP_INFO(xt, yt).int_5;
56 } else if (MP_GROUP(xt, yt) == GROUP_RAIL) {
57 if (MP_INFO(xt, yt).int_5 < MAX_ORE_ON_RAIL)
58 i = MAX_ORE_ON_RAIL - MP_INFO(xt, yt).int_5;
59 }
60 i = (i * PORT_IMPORT_RATE) / 1000;
61 MP_INFO(xt, yt).int_5 += i;
62 return (i * PORT_ORE_RATE);
63 }
64
buy_goods(int xt,int yt)65 static int buy_goods(int xt, int yt)
66 {
67 int i = 0;
68 if (MP_GROUP(xt, yt) == GROUP_TRACK) {
69 if (MP_INFO(xt, yt).int_4 < MAX_GOODS_ON_TRACK)
70 i = MAX_GOODS_ON_TRACK - MP_INFO(xt, yt).int_4;
71 } else if (MP_GROUP(xt, yt) == GROUP_ROAD) {
72 if (MP_INFO(xt, yt).int_4 < MAX_GOODS_ON_ROAD)
73 i = MAX_GOODS_ON_ROAD - MP_INFO(xt, yt).int_4;
74 } else if (MP_GROUP(xt, yt) == GROUP_RAIL) {
75 if (MP_INFO(xt, yt).int_4 < MAX_GOODS_ON_RAIL)
76 i = MAX_GOODS_ON_RAIL - MP_INFO(xt, yt).int_4;
77 }
78 i = (i * PORT_IMPORT_RATE) / 1000;
79 MP_INFO(xt, yt).int_4 += i;
80 return (i * PORT_GOODS_RATE);
81 }
82
buy_steel(int xt,int yt)83 static int buy_steel(int xt, int yt)
84 {
85 int i = 0;
86 if (MP_GROUP(xt, yt) == GROUP_TRACK) {
87 if (MP_INFO(xt, yt).int_6 < MAX_STEEL_ON_TRACK)
88 i = MAX_STEEL_ON_TRACK - MP_INFO(xt, yt).int_6;
89 } else if (MP_GROUP(xt, yt) == GROUP_ROAD) {
90 if (MP_INFO(xt, yt).int_6 < MAX_STEEL_ON_ROAD)
91 i = MAX_STEEL_ON_ROAD - MP_INFO(xt, yt).int_6;
92 } else if (MP_GROUP(xt, yt) == GROUP_RAIL) {
93 if (MP_INFO(xt, yt).int_6 < MAX_STEEL_ON_RAIL)
94 i = MAX_STEEL_ON_RAIL - MP_INFO(xt, yt).int_6;
95 }
96 i = (i * PORT_IMPORT_RATE) / 1000;
97 MP_INFO(xt, yt).int_6 += i;
98 return (i * PORT_STEEL_RATE);
99 }
100
sell_food(int xt,int yt)101 static int sell_food(int xt, int yt)
102 {
103 int i = 0;
104 i = (MP_INFO(xt, yt).int_1 * PORT_EXPORT_RATE) / 1000;
105 MP_INFO(xt, yt).int_1 -= i;
106 return (i * PORT_FOOD_RATE);
107 }
108
sell_coal(int xt,int yt)109 static int sell_coal(int xt, int yt)
110 {
111 int i = 0;
112 i = (MP_INFO(xt, yt).int_3 * PORT_EXPORT_RATE) / 1000;
113 MP_INFO(xt, yt).int_3 -= i;
114 return (i * PORT_COAL_RATE);
115 }
116
sell_ore(int xt,int yt)117 static int sell_ore(int xt, int yt)
118 {
119 int i = 0;
120 i = (MP_INFO(xt, yt).int_5 * PORT_EXPORT_RATE) / 1000;
121 MP_INFO(xt, yt).int_5 -= i;
122 return (i * PORT_ORE_RATE);
123 }
124
sell_goods(int xt,int yt)125 static int sell_goods(int xt, int yt)
126 {
127 int i = 0;
128 i = (MP_INFO(xt, yt).int_4 * PORT_EXPORT_RATE) / 1000;
129 MP_INFO(xt, yt).int_4 -= i;
130 return (i * PORT_GOODS_RATE);
131 }
132
sell_steel(int xt,int yt)133 static int sell_steel(int xt, int yt)
134 {
135 int i = 0;
136 i = (MP_INFO(xt, yt).int_6 * PORT_EXPORT_RATE) / 1000;
137 MP_INFO(xt, yt).int_6 -= i;
138 return (i * PORT_STEEL_RATE);
139 }
140
141 /* Trade with a transport.
142 * Port is at x/y, transport at u/v. */
trade_connection(const int x,const int y,const int u,const int v,int * ic_ptr,int * et_ptr)143 static void trade_connection(const int x, const int y, const int u, const int v, int *ic_ptr, int *et_ptr)
144 {
145 if (u >= 0 && v >= 0 && (MP_INFO(u, v).flags & FLAG_IS_TRANSPORT) != 0) {
146 //printf("Port %i/%i trading with transport %i/%i\n", x,y,u,v);
147 int i, flags;
148 int ic = 0;
149 int et = 0;
150 flags = MP_INFO(x, y).flags;
151 if ((flags & FLAG_MB_FOOD) != 0) {
152 i = buy_food(u, v);
153 ic += i;
154 MP_INFO(x + 1, y).int_3 += i;
155 }
156 if ((flags & FLAG_MS_FOOD) != 0) {
157 i = sell_food(u, v);
158 et += i;
159 MP_INFO(x + 2, y).int_3 += i;
160 }
161 if ((flags & FLAG_MB_COAL) != 0) {
162 i = buy_coal(u, v);
163 ic += i;
164 MP_INFO(x + 1, y).int_4 += i;
165 }
166 if ((flags & FLAG_MS_COAL) != 0) {
167 i = sell_coal(u, v);
168 et += i;
169 MP_INFO(x + 2, y).int_4 += i;
170 }
171 if ((flags & FLAG_MB_ORE) != 0) {
172 i = buy_ore(u, v);
173 ic += i;
174 MP_INFO(x + 1, y).int_5 += i;
175 }
176 if ((flags & FLAG_MS_ORE) != 0) {
177 i = sell_ore(u, v);
178 et += i;
179 MP_INFO(x + 2, y).int_5 += i;
180 }
181 if ((flags & FLAG_MB_GOODS) != 0) {
182 i = buy_goods(u, v);
183 ic += i;
184 MP_INFO(x + 1, y).int_6 += i;
185 }
186 if ((flags & FLAG_MS_GOODS) != 0) {
187 i = sell_goods(u, v);
188 et += i;
189 MP_INFO(x + 2, y).int_6 += i;
190 }
191 if ((flags & FLAG_MB_STEEL) != 0) {
192 i = buy_steel(u, v);
193 ic += i;
194 MP_INFO(x + 1, y).int_7 += i;
195 }
196 if ((flags & FLAG_MS_STEEL) != 0) {
197 i = sell_steel(u, v);
198 et += i;
199 MP_INFO(x + 2, y).int_7 += i;
200 }
201 *ic_ptr += ic;
202 *et_ptr += et;
203 }
204 }
205
do_port(int x,int y)206 void do_port(int x, int y)
207 {
208 /*
209 // int_1 is the money made so far this month
210 // int_2 is the money made last month
211 // int_3 holds the 'pence/pennies/bits' to add next time round.
212 // int_4 is the import costs so far this month
213 // int_5 is the import costs for last month
214 // Use int_3 to int_7 of (x+1,y) to hold the individual buy values
215 // (x,y+1) is last month's
216 // Use int_3 to int_7 of (x+2,y) to hold the individual sell values
217 // (x,y+2) is last month's
218 */
219 int i, et = 0, ic = 0, *b1, *b2, *s1, *s2, a;
220
221 /* left connection first */
222 for (a = 0; a < 4; a++) //try anywhere on the west side.
223 if (x >= 0 && y >= 0 && (MP_INFO(x - 1, y + a).flags & FLAG_IS_TRANSPORT) != 0) {
224 trade_connection(x, y, x - 1, y + a, &ic, &et);
225 break;
226 }
227 /* upper gate next */
228 bool deal = false;
229 for (a = 0; a < 3; a++) //try north
230 if (x >= 0 && y >= 0 && (MP_INFO(x + a, y - 1).flags & FLAG_IS_TRANSPORT) != 0) {
231 trade_connection(x, y, x + a, y - 1, &ic, &et);
232 deal = false;
233 break;
234 }
235 if (!deal)
236 for (a = 0; a < 3; a++) //try south
237 if (x >= 0 && y >= 0 && (MP_INFO(x + a, y + 4).flags & FLAG_IS_TRANSPORT) != 0) {
238 trade_connection(x, y, x + a, y + 4, &ic, &et);
239 break;
240 }
241
242 MP_INFO(x, y).int_1 += et;
243 MP_INFO(x, y).int_4 += ic;
244 if (total_time % 100 == 0) {
245 MP_INFO(x, y).int_2 = MP_INFO(x, y).int_1;
246 MP_INFO(x, y).int_1 = 0;
247 MP_INFO(x, y).int_5 = MP_INFO(x, y).int_4;
248 MP_INFO(x, y).int_4 = 0;
249 b1 = &(MP_INFO(x + 1, y).int_3);
250 s1 = &(MP_INFO(x + 2, y).int_3);
251 b2 = &(MP_INFO(x, y + 1).int_3);
252 s2 = &(MP_INFO(x, y + 2).int_3);
253 /* GCS FIX -- This obfuscation is unnecessary. */
254 for (i = 0; i < 5; i++) {
255 *(b2++) = *b1;
256 *(s2++) = *s1;
257 *(b1++) = 0;
258 *(s1++) = 0;
259 }
260 }
261 if (et > 0) {
262 sust_port_flag = 0;
263 tech_level++;
264 }
265 if (ic > 0) {
266 sust_port_flag = 0;
267 tech_level++;
268 }
269 et += MP_INFO(x, y).int_3; /* int_3 holds the 'pence' */
270
271 export_tax += et / 100;
272 MP_INFO(x, y).int_3 = et % 100;
273 import_cost += ic;
274 }
275
mps_port(int x,int y)276 void mps_port(int x, int y)
277 {
278 int i = 0;
279 char buy[12], sell[12];
280
281 mps_store_title(i++, _("Port"));
282 i++;
283
284 num_to_ansi(buy, sizeof(buy), MP_INFO(x, y + 1).int_3 / 100);
285 num_to_ansi(sell, sizeof(sell), MP_INFO(x, y + 2).int_3 / 100);
286 mps_store_sss(i++, _("Food"), buy, sell);
287
288 num_to_ansi(buy, sizeof(buy), MP_INFO(x, y + 1).int_4 / 100);
289 num_to_ansi(sell, sizeof(sell), MP_INFO(x, y + 2).int_4 / 100);
290 mps_store_sss(i++, _("Coal"), buy, sell);
291
292 num_to_ansi(buy, sizeof(buy), MP_INFO(x, y + 1).int_5 / 100);
293 num_to_ansi(sell, sizeof(sell), MP_INFO(x, y + 2).int_5 / 100);
294 mps_store_sss(i++, _("Ore"), buy, sell);
295
296 num_to_ansi(buy, sizeof(buy), MP_INFO(x, y + 1).int_6 / 100);
297 num_to_ansi(sell, sizeof(sell), MP_INFO(x, y + 2).int_6 / 100);
298 mps_store_sss(i++, _("Goods"), buy, sell);
299
300 num_to_ansi(buy, sizeof(buy), MP_INFO(x, y + 1).int_7 / 100);
301 num_to_ansi(sell, sizeof(sell), MP_INFO(x, y + 2).int_7 / 100);
302 mps_store_sss(i++, _("Steel"), buy, sell);
303
304 num_to_ansi(buy, sizeof(buy), MP_INFO(x, y).int_5 / 100);
305 num_to_ansi(sell, sizeof(sell), MP_INFO(x, y).int_2 / 100);
306 mps_store_sss(i++, _("Total"), buy, sell);
307
308 }
309