1 /* ---------------------------------------------------------------------- *
2 * market.c
3 * This file is part of lincity.
4 * Lincity is copyright (c) I J Peters 1995-1997, (c) Greg Sharp 1997-2001.
5 * ---------------------------------------------------------------------- */
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include "common.h"
9 #include "lctypes.h"
10 #include "lin-city.h"
11 #include "stats.h"
12 #include <mps.h>
13 #include <lcintl.h>
14 #include <lcconfig.h>
15
16 #include <market.h>
17
18
19
20 int
get_jobs(int x,int y,int jobs)21 get_jobs (int x, int y, int jobs)
22 {
23 int q;
24 if (numof_markets > 0)
25 {
26 for (q = 0; q < numof_markets; q++)
27 {
28 if ((abs (marketx[q] - x) < MARKET_RANGE
29 && abs (markety[q] - y) < MARKET_RANGE
30 && (MP_INFO(marketx[q],markety[q]).int_2 > (3 * jobs / 2))))
31 {
32 MP_INFO(marketx[q],markety[q]).int_2 -= jobs;
33 income_tax += jobs;
34 return (1);
35 }
36 }
37 }
38 if (get_stuff (x, y, jobs, T_JOBS) != 0)
39 {
40 income_tax += jobs;
41 return (1);
42 }
43 return (0);
44 }
45
46 int
put_jobs(int x,int y,int jobs)47 put_jobs (int x, int y, int jobs)
48 {
49 int q;
50 if (numof_markets > 0) {
51 for (q = 0; q < numof_markets; q++) {
52 if (MP_INFO(marketx[q],markety[q]).int_2
53 >= (MAX_JOBS_IN_MARKET - jobs))
54 continue;
55 if (abs (marketx[q] - x) < EMPLOYER_RANGE
56 && abs (markety[q] - y) < EMPLOYER_RANGE)
57 {
58 MP_INFO(marketx[q],markety[q]).int_2 += jobs;
59 return (1);
60 }
61 }
62 }
63 if (put_stuff (x, y, jobs, T_JOBS) != 0) {
64 return (1);
65 }
66 return (0);
67 }
68
69 int
get_food(int x,int y,int food)70 get_food (int x, int y, int food)
71 {
72 int q;
73 if (numof_markets > 0)
74 {
75 for (q = 0; q < numof_markets; q++)
76 {
77 if ((abs (marketx[q] - x) < MARKET_RANGE)
78 && (abs (markety[q] - y) < MARKET_RANGE)
79 && (MP_INFO(marketx[q],markety[q]).int_1
80 > food))
81 {
82 MP_INFO(marketx[q],markety[q]).int_1 -= food;
83 return (1);
84 }
85 }
86 }
87 if (get_stuff (x, y, food, T_FOOD) != 0)
88 return (1);
89 return (0);
90 }
91
92 int
put_food(int x,int y,int food)93 put_food (int x, int y, int food)
94 {
95 int q;
96 if (numof_markets > 0)
97 {
98 for (q = 0; q < numof_markets; q++)
99 {
100 if (MP_INFO(marketx[q],markety[q]).int_1
101 >= (MAX_FOOD_IN_MARKET - food))
102 continue;
103 if ((abs (marketx[q] - x) < ORG_FARM_RANGE)
104 && (abs (markety[q] - y) < ORG_FARM_RANGE))
105 {
106 MP_INFO(marketx[q],markety[q]).int_1 += food;
107 return (1);
108 }
109 }
110 }
111 if (put_stuff (x, y, food, T_FOOD) != 0)
112 return (1);
113 return (0);
114 }
115
116
117 int
get_goods(int x,int y,int goods)118 get_goods (int x, int y, int goods)
119 {
120 int q;
121 if (numof_markets > 0)
122 {
123 for (q = 0; q < numof_markets; q++)
124 {
125 if (abs (marketx[q] - x) < MARKET_RANGE
126 && abs (markety[q] - y) < MARKET_RANGE
127 && (MP_INFO(marketx[q],markety[q]).int_4
128 > goods))
129 {
130 MP_INFO(marketx[q],markety[q]).int_4 -= goods;
131 goods_tax += goods;
132 goods_used += goods;
133 /* make the waste here. */
134 MP_INFO(marketx[q],markety[q]).int_7 += goods / 3;
135 return (1);
136 }
137 }
138 }
139 if (get_stuff (x, y, goods, T_GOODS) != 0)
140 {
141 put_stuff (x, y, goods / 3, T_WASTE);
142 goods_tax += goods;
143 goods_used += goods;
144 return (1);
145 }
146 return (0);
147 }
148
149 int
put_goods(int x,int y,int goods)150 put_goods (int x, int y, int goods)
151 {
152 int q;
153 if (numof_markets > 0)
154 {
155 for (q = 0; q < numof_markets; q++)
156 {
157 if (MP_INFO(marketx[q],markety[q]).int_4
158 >= (MAX_GOODS_IN_MARKET - goods))
159 continue;
160 if ((abs (marketx[q] - x) < MARKET_RANGE)
161 && (abs (markety[q] - y) < MARKET_RANGE))
162 {
163 MP_INFO(marketx[q],markety[q]).int_4 += goods;
164 return (1);
165 }
166 }
167 }
168 if (put_stuff (x, y, goods, T_GOODS) != 0)
169 return (1);
170 return (0);
171 }
172
173 int
put_waste(int x,int y,int waste)174 put_waste (int x, int y, int waste)
175 {
176 int q;
177 if (numof_markets > 0)
178 {
179 for (q = 0; q < numof_markets; q++)
180 {
181 if (MP_INFO(marketx[q],markety[q]).int_7
182 >= (MAX_WASTE_IN_MARKET - waste))
183 continue;
184 if ((abs (marketx[q] - x) < MARKET_RANGE)
185 && (abs (markety[q] - y) < MARKET_RANGE))
186 {
187 MP_INFO(marketx[q],markety[q]).int_7 += waste;
188 return (1);
189 }
190 }
191 }
192 if (put_stuff (x, y, waste, T_WASTE) != 0)
193 return (1);
194 return (0);
195 }
196
197 int
get_waste(int x,int y,int waste)198 get_waste (int x, int y, int waste)
199 {
200 int q;
201 if (numof_markets > 0)
202 {
203 for (q = 0; q < numof_markets; q++)
204 {
205 if ((abs (marketx[q] - x) < MARKET_RANGE)
206 && (abs (markety[q] - y) < MARKET_RANGE)
207 && (MP_INFO(marketx[q],markety[q]).int_7
208 > waste))
209 {
210 MP_INFO(marketx[q],markety[q]).int_7 -= waste;
211 return (1);
212 }
213 }
214 }
215 if (get_stuff (x, y, waste, T_WASTE) != 0)
216 return (1);
217 return (0);
218 }
219
220
221 int
get_steel(int x,int y,int steel)222 get_steel (int x, int y, int steel)
223 {
224 int q;
225 if (numof_markets > 0)
226 {
227 for (q = 0; q < numof_markets; q++)
228 {
229 if ((abs (marketx[q] - x) < MARKET_RANGE)
230 && (abs (markety[q] - y) < MARKET_RANGE)
231 && (MP_INFO(marketx[q],markety[q]).int_6
232 > steel))
233 {
234 MP_INFO(marketx[q],markety[q]).int_6 -= steel;
235 return (1);
236 }
237 }
238 }
239 if (get_stuff (x, y, steel, T_STEEL) != 0)
240 return (1);
241 return (0);
242 }
243
244 int
put_steel(int x,int y,int steel)245 put_steel (int x, int y, int steel)
246 {
247 int q;
248 if (numof_markets > 0)
249 {
250 for (q = 0; q < numof_markets; q++)
251 {
252 if (MP_INFO(marketx[q],markety[q]).int_6
253 >= (MAX_STEEL_IN_MARKET - steel))
254 continue;
255 if ((abs (marketx[q] - x) < MARKET_RANGE)
256 && (abs (markety[q] - y) < MARKET_RANGE))
257 {
258 MP_INFO(marketx[q],markety[q]).int_6 += steel;
259 return (1);
260 }
261 }
262 }
263 if (put_stuff (x, y, steel, T_STEEL) != 0)
264 return (1);
265 return (0);
266 }
267
268
269 int
get_ore(int x,int y,int ore)270 get_ore (int x, int y, int ore)
271 {
272 int q;
273 if (numof_markets > 0)
274 {
275 for (q = 0; q < numof_markets; q++)
276 {
277 if ((abs (marketx[q] - x) < MARKET_RANGE)
278 && (abs (markety[q] - y) < MARKET_RANGE)
279 && (MP_INFO(marketx[q],markety[q]).int_5
280 > ore))
281 {
282 MP_INFO(marketx[q],markety[q]).int_5 -= ore;
283 return (1);
284 }
285 }
286 }
287 if (get_stuff (x, y, ore, T_ORE) != 0)
288 return (1);
289 return (0);
290 }
291
292 int
put_ore(int x,int y,int ore)293 put_ore (int x, int y, int ore)
294 {
295 int q;
296 if (numof_markets > 0)
297 {
298 for (q = 0; q < numof_markets; q++)
299 {
300 if (MP_INFO(marketx[q],markety[q]).int_5
301 >= (MAX_ORE_IN_MARKET - ore))
302 continue;
303 if ((abs (marketx[q] - x) < MARKET_RANGE)
304 && (abs (markety[q] - y) < MARKET_RANGE))
305 {
306 MP_INFO(marketx[q],markety[q]).int_5 += ore;
307 return (1);
308 }
309 }
310 }
311 if (put_stuff (x, y, ore, T_ORE) != 0)
312 return (1);
313 return (0);
314 }
315
316
317 int
get_coal(int x,int y,int coal)318 get_coal (int x, int y, int coal)
319 {
320 int q;
321 if (numof_markets > 0)
322 {
323 for (q = 0; q < numof_markets; q++)
324 {
325 if ((abs (marketx[q] - x) < MARKET_RANGE)
326 && (abs (markety[q] - y) < MARKET_RANGE)
327 && (MP_INFO(marketx[q],markety[q]).int_3
328 > coal))
329 {
330 MP_INFO(marketx[q],markety[q]).int_3 -= coal;
331 return (1);
332 }
333 }
334 }
335 if (get_stuff (x, y, coal, T_COAL) != 0)
336 return (1);
337 return (0);
338 }
339
340 int
put_coal(int x,int y,int coal)341 put_coal (int x, int y, int coal)
342 {
343 int q;
344 if (numof_markets > 0)
345 {
346 for (q = 0; q < numof_markets; q++)
347 {
348 if (MP_INFO(marketx[q],markety[q]).int_3
349 >= (MAX_COAL_IN_MARKET - coal))
350 continue;
351 if ((abs (marketx[q] - x) < MARKET_RANGE)
352 && (abs (markety[q] - y) < MARKET_RANGE))
353 {
354 MP_INFO(marketx[q],markety[q]).int_3 += coal;
355 return (1);
356 }
357 }
358 }
359 if (put_stuff (x, y, coal, T_COAL) != 0)
360 return (1);
361 return (0);
362 }
363
364
365 int
add_a_market(int x,int y)366 add_a_market (int x, int y) /* add to marketx markety to list */
367 {
368 if (numof_markets >= MAX_NUMOF_MARKETS)
369 return (0);
370 marketx[numof_markets] = x;
371 markety[numof_markets] = y;
372 numof_markets++;
373 /* oh dear. Got to bootstap markets with jobs, otherwise power won't work */
374 /* GCS: Is this still true? */
375 MP_INFO(x,y).int_2 = 2000;
376 return (1);
377 }
378
379 void
remove_a_market(int x,int y)380 remove_a_market (int x, int y)
381 {
382 int q;
383 for (q = 0; q < numof_markets; q++)
384 if (marketx[q] == x && markety[q] == y)
385 break;
386 for (; q < numof_markets; q++)
387 {
388 marketx[q] = marketx[q + 1];
389 markety[q] = markety[q + 1];
390 }
391 numof_markets--;
392 }
393
394 void
do_market(int x,int y)395 do_market (int x, int y)
396 {
397 /*
398 // int_1 contains the food it holds
399 // int_2 contains the jobs
400 // int_3 contains the coal
401 // int_4 contains the goods
402 // int_5 contains the ore
403 // int_6 contains the steel
404 // int_7 contains the waste
405 */
406
407 int extra_jobs = 0;
408
409 shuffle_markets ();
410
411 if (x > 0 && (MP_INFO(x - 1,y).flags & FLAG_IS_TRANSPORT) != 0)
412 extra_jobs += deal_with_transport (x, y, x - 1, y);
413 if (x > 0 && (MP_INFO(x - 1,y + 1).flags & FLAG_IS_TRANSPORT) != 0)
414 extra_jobs += deal_with_transport (x, y, x - 1, y + 1);
415 if (y > 0 && (MP_INFO(x,y - 1).flags & FLAG_IS_TRANSPORT) != 0)
416 extra_jobs += deal_with_transport (x, y, x, y - 1);
417 if (y > 0 && (MP_INFO(x + 1,y - 1).flags & FLAG_IS_TRANSPORT) != 0)
418 extra_jobs += deal_with_transport (x, y, x + 1, y - 1);
419 if (x < WORLD_SIDE_LEN - 2
420 && (MP_INFO(x + 2,y).flags & FLAG_IS_TRANSPORT) != 0)
421 extra_jobs += deal_with_transport (x, y, x + 2, y);
422 if (x < WORLD_SIDE_LEN - 2
423 && (MP_INFO(x + 2,y + 1).flags & FLAG_IS_TRANSPORT) != 0)
424 extra_jobs += deal_with_transport (x, y, x + 2, y + 1);
425 if (y < WORLD_SIDE_LEN - 2
426 && (MP_INFO(x,y + 2).flags & FLAG_IS_TRANSPORT) != 0)
427 extra_jobs += deal_with_transport (x, y, x, y + 2);
428 if (y < WORLD_SIDE_LEN - 2
429 && (MP_INFO(x + 1,y + 2).flags & FLAG_IS_TRANSPORT) != 0)
430 extra_jobs += deal_with_transport (x, y, x + 1, y + 2);
431
432 if (MP_INFO(x,y).int_1 > MAX_FOOD_IN_MARKET)
433 MP_INFO(x,y).int_1 = MAX_FOOD_IN_MARKET;
434 if (MP_INFO(x,y).int_2 > MAX_JOBS_IN_MARKET)
435 MP_INFO(x,y).int_2 = MAX_JOBS_IN_MARKET;
436 if (MP_INFO(x,y).int_4 > MAX_GOODS_IN_MARKET)
437 MP_INFO(x,y).int_4 = MAX_GOODS_IN_MARKET;
438
439 /* now choose a graphic only dependent on food (for now anyway) */
440 if (total_time % 25 == 17)
441 {
442 if (MP_INFO(x,y).int_1 <= 0)
443 {
444 if (MP_INFO(x,y).int_2 > 0)
445 MP_TYPE(x,y) = CST_MARKET_LOW;
446 else
447 MP_TYPE(x,y) = CST_MARKET_EMPTY;
448 }
449 else if (MP_INFO(x,y).int_1 < (MARKET_FOOD_SEARCH_TRIGGER / 2))
450 MP_TYPE(x,y) = CST_MARKET_LOW;
451 else if (MP_INFO(x,y).int_1
452 < (MAX_FOOD_IN_MARKET - MAX_FOOD_IN_MARKET / 4))
453 MP_TYPE(x,y) = CST_MARKET_MED;
454 else
455 MP_TYPE(x,y) = CST_MARKET_FULL;
456 }
457
458 /* now employ some people */
459 get_jobs (x, y, 1 + (extra_jobs / 5));
460
461 /* keep the pbars accurate */
462 inventory(x,y);
463 }
464
465 void
shuffle_markets(void)466 shuffle_markets (void)
467 {
468 register int x;
469 int q, r, m;
470 m = (numof_markets / 4) + 1;
471 for (x = 0; x < m; x++)
472 {
473 r = rand () % numof_markets;
474 if (r == x)
475 continue;
476 q = marketx[x];
477 marketx[x] = marketx[r];
478 marketx[r] = q;
479 q = markety[x];
480 markety[x] = markety[r];
481 markety[r] = q;
482 }
483 }
484
485
486 int
deal_with_transport(int x,int y,int tx,int ty)487 deal_with_transport (int x, int y, int tx, int ty)
488 {
489 int i, r, extra_jobs = 3, flags;
490 flags = MP_INFO(x,y).flags;
491 /* tracks */
492 if (MP_GROUP(tx,ty) == GROUP_TRACK)
493 {
494 /* food */
495 if ((flags & FLAG_MB_FOOD) != 0)
496 {
497 r = (MAX_FOOD_IN_MARKET * 1000)
498 / (MAX_FOOD_ON_TRACK + MAX_FOOD_IN_MARKET);
499 i = MP_INFO(x,y).int_1 + MP_INFO(tx,ty).int_1;
500 MP_INFO(x,y).int_1 = (i * r) / 1000;
501 MP_INFO(tx,ty).int_1 = i - MP_INFO(x,y).int_1;
502 }
503
504 /* jobs */
505 if ((flags & FLAG_MB_JOBS) != 0)
506 {
507 r = (MAX_JOBS_IN_MARKET * 1000)
508 / (MAX_JOBS_ON_TRACK + MAX_JOBS_IN_MARKET);
509 i = MP_INFO(x,y).int_2 + MP_INFO(tx,ty).int_2;
510 MP_INFO(x,y).int_2 = (i * r) / 1000;
511 MP_INFO(tx,ty).int_2 = i - MP_INFO(x,y).int_2;
512 }
513
514 /* coal */
515 if ((flags & FLAG_MB_COAL) != 0)
516 {
517 r = (MAX_COAL_IN_MARKET * 1000)
518 / (MAX_COAL_ON_TRACK + MAX_COAL_IN_MARKET);
519 i = MP_INFO(x,y).int_3 + MP_INFO(tx,ty).int_3;
520 MP_INFO(x,y).int_3 = (i * r) / 1000;
521 MP_INFO(tx,ty).int_3 = i - MP_INFO(x,y).int_3;
522 }
523
524 /* goods */
525 if ((flags & FLAG_MB_GOODS) != 0)
526 {
527 r = (MAX_GOODS_IN_MARKET * 1000)
528 / (MAX_GOODS_ON_TRACK + MAX_GOODS_IN_MARKET);
529 i = MP_INFO(x,y).int_4 + MP_INFO(tx,ty).int_4;
530 MP_INFO(x,y).int_4 = (i * r) / 1000;
531 MP_INFO(tx,ty).int_4 = i - MP_INFO(x,y).int_4;
532 }
533
534 /* ore */
535 if ((flags & FLAG_MB_ORE) != 0)
536 {
537 r = (MAX_ORE_IN_MARKET * 1000)
538 / (MAX_ORE_ON_TRACK + MAX_ORE_IN_MARKET);
539 i = MP_INFO(x,y).int_5 + MP_INFO(tx,ty).int_5;
540 MP_INFO(x,y).int_5 = (i * r) / 1000;
541 MP_INFO(tx,ty).int_5 = i - MP_INFO(x,y).int_5;
542 }
543
544
545 /* steel */
546 if ((flags & FLAG_MB_STEEL) != 0)
547 {
548 r = (MAX_STEEL_IN_MARKET * 1000)
549 / (MAX_STEEL_ON_TRACK + MAX_STEEL_IN_MARKET);
550 i = MP_INFO(x,y).int_6 + MP_INFO(tx,ty).int_6;
551 MP_INFO(x,y).int_6 = (i * r) / 1000;
552 MP_INFO(tx,ty).int_6 = i - MP_INFO(x,y).int_6;
553 }
554
555 /* waste */
556 r = (MAX_WASTE_IN_MARKET * 1000)
557 / (MAX_WASTE_ON_TRACK + MAX_WASTE_IN_MARKET);
558 i = MP_INFO(x,y).int_7 + MP_INFO(tx,ty).int_7;
559 MP_INFO(x,y).int_7 = (i * r) / 1000;
560 MP_INFO(tx,ty).int_7 = i - MP_INFO(x,y).int_7;
561
562
563 /* if it's full of waste, burn some to make pollution. */
564 if (MP_INFO(x,y).int_7 >= (99 * MAX_WASTE_IN_MARKET / 100))
565 {
566 MP_POL(x,y) += 3000;
567 MP_INFO(x,y).int_7 -= (7 * MAX_WASTE_IN_MARKET) / 10;
568 #if defined (commentout)
569 /* this should fire up the pollution mini screen within a second. */
570 mini_screen_flags = MINI_SCREEN_POL_FLAG;
571 #endif
572 }
573 }
574
575
576 /* do rail traffic */
577 else if (MP_GROUP(tx,ty) == GROUP_RAIL)
578 {
579 /* food */
580 if ((flags & FLAG_MB_FOOD) != 0)
581 {
582 r = (MAX_FOOD_IN_MARKET * 1000)
583 / (MAX_FOOD_ON_RAIL + MAX_FOOD_IN_MARKET);
584 i = MP_INFO(x,y).int_1 + MP_INFO(tx,ty).int_1;
585 MP_INFO(x,y).int_1 = (i * r) / 1000;
586 MP_INFO(tx,ty).int_1 = i - MP_INFO(x,y).int_1;
587 }
588
589 /* jobs */
590 if ((flags & FLAG_MB_JOBS) != 0)
591 {
592 r = (MAX_JOBS_IN_MARKET * 1000)
593 / (MAX_JOBS_ON_RAIL + MAX_JOBS_IN_MARKET);
594 i = MP_INFO(x,y).int_2 + MP_INFO(tx,ty).int_2;
595 MP_INFO(x,y).int_2 = (i * r) / 1000;
596 MP_INFO(tx,ty).int_2 = i - MP_INFO(x,y).int_2;
597 }
598
599 /* coal */
600 if ((flags & FLAG_MB_COAL) != 0)
601 {
602 r = (MAX_COAL_IN_MARKET * 1000)
603 / (MAX_COAL_ON_RAIL + MAX_COAL_IN_MARKET);
604 i = MP_INFO(x,y).int_3 + MP_INFO(tx,ty).int_3;
605 MP_INFO(x,y).int_3 = (i * r) / 1000;
606 MP_INFO(tx,ty).int_3 = i - MP_INFO(x,y).int_3;
607 }
608
609 /* goods */
610 if ((flags & FLAG_MB_GOODS) != 0)
611 {
612 r = (MAX_GOODS_IN_MARKET * 1000)
613 / (MAX_GOODS_ON_RAIL + MAX_GOODS_IN_MARKET);
614 i = MP_INFO(x,y).int_4 + MP_INFO(tx,ty).int_4;
615 MP_INFO(x,y).int_4 = (i * r) / 1000;
616 MP_INFO(tx,ty).int_4 = i - MP_INFO(x,y).int_4;
617 }
618
619 /* ore */
620 if ((flags & FLAG_MB_ORE) != 0)
621 {
622 r = (MAX_ORE_IN_MARKET * 1000)
623 / (MAX_ORE_ON_RAIL + MAX_ORE_IN_MARKET);
624 i = MP_INFO(x,y).int_5 + MP_INFO(tx,ty).int_5;
625 MP_INFO(x,y).int_5 = (i * r) / 1000;
626 MP_INFO(tx,ty).int_5 = i - MP_INFO(x,y).int_5;
627 }
628
629 /* steel */
630 if ((flags & FLAG_MB_STEEL) != 0)
631 {
632 r = (MAX_STEEL_IN_MARKET * 1000)
633 / (MAX_STEEL_ON_RAIL + MAX_STEEL_IN_MARKET);
634 i = MP_INFO(x,y).int_6 + MP_INFO(tx,ty).int_6;
635 MP_INFO(x,y).int_6 = (i * r) / 1000;
636 MP_INFO(tx,ty).int_6 = i - MP_INFO(x,y).int_6;
637 }
638
639 /* waste */
640 r = (MAX_WASTE_IN_MARKET * 1000)
641 / (MAX_WASTE_ON_RAIL + MAX_WASTE_IN_MARKET);
642 i = MP_INFO(x,y).int_7 + MP_INFO(tx,ty).int_7;
643 MP_INFO(x,y).int_7 = (i * r) / 1000;
644 MP_INFO(tx,ty).int_7 = i - MP_INFO(x,y).int_7;
645
646 }
647
648 /* do road traffic */
649 else if (MP_GROUP(tx,ty) == GROUP_ROAD)
650 {
651 /* food */
652 if ((flags & FLAG_MB_FOOD) != 0)
653 {
654 r = (MAX_FOOD_IN_MARKET * 1000)
655 / (MAX_FOOD_ON_ROAD + MAX_FOOD_IN_MARKET);
656 i = MP_INFO(x,y).int_1 + MP_INFO(tx,ty).int_1;
657 MP_INFO(x,y).int_1 = (i * r) / 1000;
658 MP_INFO(tx,ty).int_1 = i - MP_INFO(x,y).int_1;
659 }
660
661 /* jobs */
662 if ((flags & FLAG_MB_JOBS) != 0)
663 {
664 r = (MAX_JOBS_IN_MARKET * 1000)
665 / (MAX_JOBS_ON_ROAD + MAX_JOBS_IN_MARKET);
666 i = MP_INFO(x,y).int_2 + MP_INFO(tx,ty).int_2;
667 MP_INFO(x,y).int_2 = (i * r) / 1000;
668 MP_INFO(tx,ty).int_2 = i - MP_INFO(x,y).int_2;
669 }
670
671 /* coal */
672 if ((flags & FLAG_MB_COAL) != 0)
673 {
674 r = (MAX_COAL_IN_MARKET * 1000)
675 / (MAX_COAL_ON_ROAD + MAX_COAL_IN_MARKET);
676 i = MP_INFO(x,y).int_3 + MP_INFO(tx,ty).int_3;
677 MP_INFO(x,y).int_3 = (i * r) / 1000;
678 MP_INFO(tx,ty).int_3 = i - MP_INFO(x,y).int_3;
679 }
680
681 /* goods */
682 if ((flags & FLAG_MB_GOODS) != 0)
683 {
684 r = (MAX_GOODS_IN_MARKET * 1000)
685 / (MAX_GOODS_ON_ROAD + MAX_GOODS_IN_MARKET);
686 i = MP_INFO(x,y).int_4 + MP_INFO(tx,ty).int_4;
687 MP_INFO(x,y).int_4 = (i * r) / 1000;
688 MP_INFO(tx,ty).int_4 = i - MP_INFO(x,y).int_4;
689 }
690
691 /* ore */
692 if ((flags & FLAG_MB_ORE) != 0)
693 {
694 r = (MAX_ORE_IN_MARKET * 1000)
695 / (MAX_ORE_ON_ROAD + MAX_ORE_IN_MARKET);
696 i = MP_INFO(x,y).int_5 + MP_INFO(tx,ty).int_5;
697 MP_INFO(x,y).int_5 = (i * r) / 1000;
698 MP_INFO(tx,ty).int_5 = i - MP_INFO(x,y).int_5;
699 }
700
701 /* steel */
702 if ((flags & FLAG_MB_STEEL) != 0)
703 {
704 r = (MAX_STEEL_IN_MARKET * 1000)
705 / (MAX_STEEL_ON_ROAD + MAX_STEEL_IN_MARKET);
706 i = MP_INFO(x,y).int_6 + MP_INFO(tx,ty).int_6;
707 MP_INFO(x,y).int_6 = (i * r) / 1000;
708 MP_INFO(tx,ty).int_6 = i - MP_INFO(x,y).int_6;
709 }
710
711 /* waste */
712 r = (MAX_WASTE_IN_MARKET * 1000)
713 / (MAX_WASTE_ON_ROAD + MAX_WASTE_IN_MARKET);
714 i = MP_INFO(x,y).int_7 + MP_INFO(tx,ty).int_7;
715 MP_INFO(x,y).int_7 = (i * r) / 1000;
716 MP_INFO(tx,ty).int_7 = i - MP_INFO(x,y).int_7;
717 }
718 else
719 extra_jobs = 0;
720
721 return (extra_jobs);
722 }
723
724 int
get_stuff(int x,int y,int stuff,int stuff_type)725 get_stuff (int x, int y, int stuff, int stuff_type)
726 {
727 int res = 0;
728 Map_Point_Info *minfo = &MP_INFO(x,y);
729
730 switch (MP_SIZE(x,y))
731 {
732 case 2:
733 res = get_stuff2 (minfo, stuff, stuff_type);
734 break;
735 case 3:
736 res = get_stuff3 (minfo, stuff, stuff_type);
737 break;
738 case 4:
739 res = get_stuff4 (minfo, stuff, stuff_type);
740 break;
741 default:
742 do_error ("Bad area size in get_stuff()");
743 }
744 return (res);
745 }
746
747 static const int
748 t2[8] =
749 {
750 -1,
751 WORLD_SIDE_LEN - 1,
752 2 * WORLD_SIDE_LEN,
753 2 * WORLD_SIDE_LEN + 1,
754 WORLD_SIDE_LEN + 2,
755 2,
756 1 - WORLD_SIDE_LEN,
757 -WORLD_SIDE_LEN
758 };
759
760 /* worth inlining -- (ThMO) */
761 int
get_stuff2(Map_Point_Info * map,int stuff,int stuff_type)762 get_stuff2 (Map_Point_Info *map, int stuff, int stuff_type)
763 {
764 static int tstart2 = 0;
765 int i, st, tst, *ip, *stack[8], **ssp; /* stack is a pipe -- (ThMO) */
766
767 /* we'll stack our found pointers so to avoid re-looping and
768 * testing again (ThMO) */
769
770 tst = tstart2;
771
772 /* can we find enough on the transport? */
773
774 for (ssp = stack, st = 0, i = 0; i < 8; i++)
775 {
776 if (map[t2[tst]].flags & FLAG_IS_TRANSPORT)
777 {
778 ip = &map[t2[tst]].int_1;
779 ip += stuff_type;
780 st += *ip;
781 *ssp++ = ip; /* push it -- (ThMO) */
782 if (st >= stuff)
783 {
784 ssp = stack;
785 do
786 {
787 ip = *ssp++; /* pop it -- (ThMO) */
788 *ip = (stuff -= *ip) < 0 ? -stuff : 0;
789 }
790 while (stuff > 0);
791 tstart2 = ++tst & 7;
792 return (1);
793 }
794 }
795 if (++tst >= 8)
796 tst = 0;
797 }
798 return (0);
799 }
800
801 static const int
802 t3[12] =
803 {
804 -1,
805 WORLD_SIDE_LEN - 1,
806 2 * WORLD_SIDE_LEN - 1,
807 3 * WORLD_SIDE_LEN,
808 3 * WORLD_SIDE_LEN + 1,
809 3 * WORLD_SIDE_LEN + 2,
810 2 * WORLD_SIDE_LEN + 3,
811 WORLD_SIDE_LEN + 3,
812 3,
813 2 - WORLD_SIDE_LEN,
814 1 - WORLD_SIDE_LEN,
815 -WORLD_SIDE_LEN
816 };
817
818 /* worth inlining -- (ThMO) */
819 int
get_stuff3(Map_Point_Info * map,int stuff,int stuff_type)820 get_stuff3 (Map_Point_Info *map, int stuff, int stuff_type)
821 {
822 static int tstart3 = 0;
823
824 int i, st, tst, *ip, *stack[12], **ssp; /* stack is a pipe -- (ThMO) */
825
826 /* we'll stack our found pointers so to avoid re-looping and
827 * testing again
828 * (ThMO)
829 */
830
831 tst = tstart3;
832
833 /* can we find enough on the transport? */
834
835 for (ssp = stack, st = 0, i = 0; i < 12; i++)
836 {
837 if (map[t3[tst]].flags & FLAG_IS_TRANSPORT)
838 {
839 ip = &map[t3[tst]].int_1;
840 ip += stuff_type;
841 st += *ip;
842 *ssp++ = ip; /* push it -- (ThMO) */
843 if (st >= stuff)
844 {
845 ssp = stack;
846 do
847 {
848 ip = *ssp++; /* pop it -- (ThMO) */
849 *ip = (stuff -= *ip) < 0 ? -stuff : 0;
850 }
851 while (stuff > 0);
852 ++tst;
853 tstart3 = tst >= 12 ? 0 : tst;
854 return (1);
855 }
856 }
857 if (++tst >= 12)
858 tst = 0;
859 }
860 return (0);
861 }
862
863 static const int
864 t4[16] =
865 {
866 -1,
867 WORLD_SIDE_LEN - 1,
868 2 * WORLD_SIDE_LEN - 1,
869 3 * WORLD_SIDE_LEN - 1,
870 4 * WORLD_SIDE_LEN,
871 4 * WORLD_SIDE_LEN + 1,
872 4 * WORLD_SIDE_LEN + 2,
873 4 * WORLD_SIDE_LEN + 3,
874 3 * WORLD_SIDE_LEN + 4,
875 2 * WORLD_SIDE_LEN + 4,
876 WORLD_SIDE_LEN + 4,
877 4,
878 3 - WORLD_SIDE_LEN,
879 2 - WORLD_SIDE_LEN,
880 1 - WORLD_SIDE_LEN,
881 -WORLD_SIDE_LEN
882 };
883
884 /* worth inlining -- (ThMO) */
885 int
get_stuff4(Map_Point_Info * map,int stuff,int stuff_type)886 get_stuff4 (Map_Point_Info *map, int stuff, int stuff_type)
887 {
888 static int
889 tstart4 = 0;
890
891 int i, st, tst, *ip, *stack[16], **ssp; /* stack is a pipe -- (ThMO) */
892
893 /* we'll stack our found pointers so to avoid re-looping and
894 * testing again
895 * (ThMO)
896 */
897
898 tst = tstart4;
899
900 /* can we find enough on the transport? */
901
902 for (ssp = stack, st = 0, i = 0; i < 16; i++)
903 {
904 if (map[t4[tst]].flags & FLAG_IS_TRANSPORT)
905 {
906 ip = &map[t4[tst]].int_1;
907 ip += stuff_type;
908 st += *ip;
909 *ssp++ = ip; /* push it -- (ThMO) */
910 if (st >= stuff)
911 {
912 ssp = stack;
913 do
914 {
915 ip = *ssp++; /* pop it -- (ThMO) */
916 *ip = (stuff -= *ip) < 0 ? -stuff : 0;
917 }
918 while (stuff > 0);
919 tstart4 = ++tst & 15;
920 return (1);
921 }
922 }
923 if (++tst >= 16)
924 tst = 0;
925 }
926 return (0);
927 }
928
929 int
put_stuff(int x,int y,int stuff,int stuff_type)930 put_stuff (int x, int y, int stuff, int stuff_type)
931 {
932 int res = 0;
933 short *type = &MP_TYPE(x,y);
934 Map_Point_Info *minfo = &MP_INFO(x,y);
935 switch (MP_SIZE(x,y))
936 {
937 case 2:
938 res = put_stuff2 (minfo, type, stuff, stuff_type);
939 break;
940 case 3:
941 res = put_stuff3 (minfo, type, stuff, stuff_type);
942 break;
943 case 4:
944 res = put_stuff4 (minfo, type, stuff, stuff_type);
945 break;
946 default:
947 do_error ("Bad area size in put_stuff()");
948 }
949 return res;
950 }
951
952
953 int tmax[3][7] =
954 {
955 {MAX_FOOD_ON_TRACK, MAX_JOBS_ON_TRACK
956 ,MAX_COAL_ON_TRACK, MAX_GOODS_ON_TRACK, MAX_ORE_ON_TRACK
957 ,MAX_STEEL_ON_TRACK, MAX_WASTE_ON_TRACK},
958 {MAX_FOOD_ON_ROAD, MAX_JOBS_ON_ROAD
959 ,MAX_COAL_ON_ROAD, MAX_GOODS_ON_ROAD, MAX_ORE_ON_ROAD
960 ,MAX_STEEL_ON_ROAD, MAX_WASTE_ON_ROAD},
961 {MAX_FOOD_ON_RAIL, MAX_JOBS_ON_RAIL
962 ,MAX_COAL_ON_RAIL, MAX_GOODS_ON_RAIL, MAX_ORE_ON_RAIL
963 ,MAX_STEEL_ON_RAIL, MAX_WASTE_ON_RAIL}
964 };
965
966 struct stack
967 {
968 int *ip, max_val;
969 };
970
971 /* worth inlining -- (ThMO) */
972 int
put_stuff2(Map_Point_Info * minfo,short * type,int stuff,int stuff_type)973 put_stuff2 (Map_Point_Info *minfo, short *type, int stuff, int stuff_type)
974 {
975 static int tstart2 = 0;
976 int i, st, tst, *ip, tp = 0;
977 struct stack stack[8], *ssp; /* stack is really a pipe -- (ThMO) */
978
979 /* we'll stack our found pointers so to avoid re-looping and
980 * testing again (ThMO) */
981
982 tst = tstart2;
983
984 /* can we put enough on the transport? */
985
986 for (ssp = stack, st = 0, i = 0; i < 8; i++) {
987 int map_index = t2[tst];
988 if (minfo[map_index].flags & FLAG_IS_TRANSPORT) {
989 switch (get_group_of_type(type[map_index]))
990 {
991 case GROUP_TRACK:
992 tp = tmax[0][stuff_type];
993 break;
994 case GROUP_ROAD:
995 tp = tmax[1][stuff_type];
996 break;
997 case GROUP_RAIL:
998 tp = tmax[2][stuff_type];
999 break;
1000 default:
1001 do_error ("Bad transport type in put_stuff2");
1002 }
1003 ip = &minfo[map_index].int_1;
1004 ssp->ip = ip += stuff_type; /* push it -- (ThMO) */
1005 ssp++->max_val = tp;
1006 st += tp - *ip;
1007 if (st >= stuff) {
1008 ssp = stack;
1009 do {
1010 tp = ssp->max_val - *ssp->ip; /* pop it -- (ThMO) */
1011 if ((stuff -= tp) < 0)
1012 *ssp->ip += tp + stuff; /* == orig. stuff -- (ThMO) */
1013 else
1014 *ssp->ip = ssp->max_val;
1015 ++ssp;
1016 } while (stuff > 0);
1017 tstart2 = ++tst & 7;
1018 return (1);
1019 }
1020 }
1021 if (++tst >= 8)
1022 tst = 0;
1023 }
1024 return (0);
1025 }
1026
1027 /* worth inlining -- (ThMO) */
1028 int
put_stuff3(Map_Point_Info * minfo,short * type,int stuff,int stuff_type)1029 put_stuff3 (Map_Point_Info *minfo, short *type, int stuff, int stuff_type)
1030 {
1031 static int tstart3 = 0;
1032 int i, st, tst, *ip, tp = 0;
1033 struct stack stack[12], *ssp; /* stack is really a pipe -- (ThMO)
1034 we'll stack our found pointers so
1035 to avoid re-looping and
1036 testing again (ThMO) */
1037
1038 tst = tstart3;
1039
1040 /* can we put enough on the transport? */
1041
1042 for (ssp = stack, st = 0, i = 0; i < 12; i++) {
1043 int map_index = t3[tst];
1044 if (minfo[map_index].flags & FLAG_IS_TRANSPORT) {
1045 switch (get_group_of_type(type[map_index]))
1046 {
1047 case GROUP_TRACK:
1048 tp = tmax[0][stuff_type];
1049 break;
1050 case GROUP_ROAD:
1051 tp = tmax[1][stuff_type];
1052 break;
1053 case GROUP_RAIL:
1054 tp = tmax[2][stuff_type];
1055 break;
1056 default:
1057 do_error ("Bad transport type in put_stuff3");
1058 }
1059 ip = &minfo[map_index].int_1;
1060 ssp->ip = ip += stuff_type; /* push it -- (ThMO) */
1061 ssp++->max_val = tp;
1062 st += tp - *ip;
1063 if (st >= stuff) {
1064 ssp = stack;
1065 do {
1066 tp = ssp->max_val - *ssp->ip; /* pop it -- (ThMO) */
1067 if ((stuff -= tp) < 0)
1068 *ssp->ip += tp + stuff; /* == orig. stuff -- (ThMO) */
1069 else
1070 *ssp->ip = ssp->max_val;
1071 ++ssp;
1072 } while (stuff > 0);
1073 ++tst;
1074 tstart3 = tst >= 12 ? 0 : tst;
1075 return (1);
1076 }
1077 }
1078 if (++tst >= 12)
1079 tst = 0;
1080 }
1081 return (0);
1082 }
1083
1084 /* worth inlining -- (ThMO) */
1085 int
put_stuff4(Map_Point_Info * minfo,short * type,int stuff,int stuff_type)1086 put_stuff4 (Map_Point_Info *minfo, short *type, int stuff, int stuff_type)
1087 {
1088 static int tstart4 = 0;
1089 int i, st, tst, *ip, tp = 0;
1090 struct stack stack[16], *ssp; /* stack is really a pipe -- (ThMO)
1091 */
1092 /* we'll stack our found pointers so to avoid re-looping and
1093 * testing again (ThMO) */
1094
1095 tst = tstart4;
1096
1097 /* can we put enough on the transport? */
1098
1099 for (ssp = stack, st = 0, i = 0; i < 16; i++) {
1100 int map_index = t4[tst];
1101 if (minfo[map_index].flags & FLAG_IS_TRANSPORT) {
1102 switch (get_group_of_type(type[map_index]))
1103 {
1104 case GROUP_TRACK:
1105 tp = tmax[0][stuff_type];
1106 break;
1107 case GROUP_ROAD:
1108 tp = tmax[1][stuff_type];
1109 break;
1110 case GROUP_RAIL:
1111 tp = tmax[2][stuff_type];
1112 break;
1113 default:
1114 do_error ("Bad transport type in put_stuff4");
1115 }
1116 ip = &minfo[map_index].int_1;
1117 ssp->ip = ip += stuff_type; /* push it -- (ThMO) */
1118 ssp++->max_val = tp;
1119 st += tp - *ip;
1120 if (st >= stuff) {
1121 ssp = stack;
1122 do {
1123 tp = ssp->max_val - *ssp->ip; /* pop it -- (ThMO) */
1124 if ((stuff -= tp) < 0)
1125 *ssp->ip += tp + stuff; /* == orig. stuff -- (ThMO) */
1126 else
1127 *ssp->ip = ssp->max_val;
1128 ++ssp;
1129 } while (stuff > 0);
1130 tstart4 = ++tst & 15;
1131 return (1);
1132 }
1133 }
1134 if (++tst >= 16)
1135 tst = 0;
1136 }
1137 return (0);
1138 }
1139
1140 void
mps_market(int x,int y)1141 mps_market (int x, int y)
1142 {
1143 int i = 0;
1144
1145 mps_store_title(i++,_("Market"));
1146
1147 i++;
1148
1149 mps_store_sfp(i++,_("Food"),
1150 MP_INFO(x,y).int_1 * 100.0 / MAX_FOOD_IN_MARKET);
1151 mps_store_sfp(i++,_("Jobs"),
1152 MP_INFO(x,y).int_2 * 100.0 / MAX_JOBS_IN_MARKET);
1153 mps_store_sfp(i++,_("Coal"),
1154 MP_INFO(x,y).int_3 * 100.0 / MAX_COAL_IN_MARKET);
1155 mps_store_sfp(i++,_("Goods"),
1156 MP_INFO(x,y).int_4 * 100.0 / MAX_GOODS_IN_MARKET);
1157 mps_store_sfp(i++,_("Ore"),
1158 MP_INFO(x,y).int_5 * 100.0 / MAX_ORE_IN_MARKET);
1159 mps_store_sfp(i++,_("Steel"),
1160 MP_INFO(x,y).int_6 * 100.0 / MAX_STEEL_IN_MARKET);
1161 mps_store_sfp(i++,_("Waste"),
1162 MP_INFO(x,y).int_7 * 100.0 / MAX_WASTE_IN_MARKET);
1163
1164 }
1165
1166
1167