1 /* ---------------------------------------------------------------------- *
2  * shanty.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 "mouse.h" /* XXX: fire_area! */
10 #include "shanty.h"
11 
12 extern void set_mappoint(int x, int y, short selected_type);
13 
14 
15 #include <stdlib.h>
16 static int spiral_find_2x2(int startx, int starty);
17 static int spiral_find_group(int startx, int starty, int group);
18 
add_a_shanty(void)19 void add_a_shanty(void)
20 {
21     int r, x, y;
22     x = rand() % WORLD_SIDE_LEN;
23     y = rand() % WORLD_SIDE_LEN;
24     if (numof_shanties > 0 && rand() % 8 != 0) {
25         r = spiral_find_group(x, y, GROUP_SHANTY);
26         if (r == -1) {
27             printf("Looked for a shanty, without any! x=%d y=%d\n", x, y);
28             return;
29         }
30         y = r / WORLD_SIDE_LEN;
31         x = r % WORLD_SIDE_LEN;
32         r = spiral_find_2x2(x, y);
33         if (r == -1) {
34             /* wck: These are annoying when the map is full */
35             fprintf(stderr,"Adding a shanty (s), no space for it?!\n");
36             return;
37         }
38         y = r / WORLD_SIDE_LEN;
39         x = r % WORLD_SIDE_LEN;
40     } else {
41         r = spiral_find_group(x, y, GROUP_MARKET);
42         if (r == -1)
43             return;             /* silently return, we havn't started yet. */
44 
45         y = r / WORLD_SIDE_LEN;
46         x = r % WORLD_SIDE_LEN;
47         r = spiral_find_2x2(x, y);
48         if (r == -1) {
49             /* see above */
50             fprintf(stderr,"Adding a shanty (r), no space for it?!\n");
51             return;
52         }
53         y = r / WORLD_SIDE_LEN;
54         x = r % WORLD_SIDE_LEN;
55     }
56     set_mappoint(x, y, CST_SHANTY);
57     numof_shanties++;
58 }
59 
remove_a_shanty(int x,int y)60 void remove_a_shanty(int x, int y)
61 {
62     numof_shanties--;
63     /* ATTENTION:
64      * fire_area calls bulldoze_item which calls remove shanty.
65      */
66     do_bulldoze_area(CST_FIRE_1, x, y);
67 }
68 
update_shanty(void)69 void update_shanty(void)
70 {
71     int i, pp;
72     pp = people_pool - (COMMUNE_POP * numof_communes);
73     i = (pp - SHANTY_MIN_PP) / SHANTY_POP;
74     if (i > numof_shanties) {
75         add_a_shanty();
76     } else if (numof_shanties > 0 && (i < (numof_shanties - 1) || rand() % 100 == 1)) {
77         int x, y, r;
78         x = rand() % WORLD_SIDE_LEN;
79         y = rand() % WORLD_SIDE_LEN;
80         r = spiral_find_group(x, y, GROUP_SHANTY);
81         if (r == -1) {
82             fprintf(stderr, "Can't find a shanty to remove!\n");
83             return;
84         }
85         y = r / WORLD_SIDE_LEN;
86         x = r % WORLD_SIDE_LEN;
87         remove_a_shanty(x, y);  /* this will fire_area */
88         /* now put the fire out: it becomes impossible to bulldoze */
89         MP_INFO(x, y).int_2 = FIRE_LENGTH + 1;
90         MP_INFO(x + 1, y).int_2 = FIRE_LENGTH + 1;
91         MP_INFO(x, y + 1).int_2 = FIRE_LENGTH + 1;
92         MP_INFO(x + 1, y + 1).int_2 = FIRE_LENGTH + 1;
93     }
94 }
95 
do_shanty(int x,int y)96 void do_shanty(int x, int y)
97 {                               /* just steal some stuff and make pollution. */
98 
99     get_food(x, y, SHANTY_GET_FOOD);
100     if (get_goods(x, y, SHANTY_GET_GOODS) != 0)
101         if ((goods_tax -= SHANTY_GET_GOODS * 2) < 0)
102             goods_tax = 0;
103     get_ore(x, y, SHANTY_GET_ORE);
104     get_steel(x, y, SHANTY_GET_STEEL);
105     if (get_jobs(x, y, SHANTY_GET_JOBS) != 0)
106         if ((income_tax -= SHANTY_GET_JOBS * 2) < 0)
107             income_tax = 0;
108     if (get_coal(x, y, SHANTY_GET_COAL) != 0)
109         if ((coal_tax -= SHANTY_GET_COAL * 2) < 0)
110             coal_tax = 0;
111     if ((total_time & 1) == 0)
112         MP_POL(x, y)++;
113     else
114         MP_POL(x + 1, y + 1)++;
115 }
116 
117 /*
118    // spiral round from startx,starty until we hit something of group group.
119    // return the x y coords encoded as x+y*WORLD_SIDE_LEN
120    // return -1 if we don't find one.
121  */
spiral_find_group(int startx,int starty,int group)122 static int spiral_find_group(int startx, int starty, int group)
123 {
124     int i, j, x, y;
125     x = startx;
126     y = starty;
127     /* let's just do a complete spiral for now, work out the bounds later */
128     for (i = 1; i < (WORLD_SIDE_LEN + WORLD_SIDE_LEN); i++) {
129         for (j = 0; j < i; j++) {
130             x--;
131             if (x > 0 && x < WORLD_SIDE_LEN && y > 0 && y < WORLD_SIDE_LEN)
132                 if (MP_GROUP(x, y) == group)
133                     return (x + y * WORLD_SIDE_LEN);
134         }
135         for (j = 0; j < i; j++) {
136             y--;
137             if (x > 0 && x < WORLD_SIDE_LEN && y > 0 && y < WORLD_SIDE_LEN)
138                 if (MP_GROUP(x, y) == group)
139                     return (x + y * WORLD_SIDE_LEN);
140         }
141         i++;
142         for (j = 0; j < i; j++) {
143             x++;
144             if (x > 0 && x < WORLD_SIDE_LEN && y > 0 && y < WORLD_SIDE_LEN)
145                 if (MP_GROUP(x, y) == group)
146                     return (x + y * WORLD_SIDE_LEN);
147         }
148         for (j = 0; j < i; j++) {
149             y++;
150             if (x > 0 && x < WORLD_SIDE_LEN && y > 0 && y < WORLD_SIDE_LEN)
151                 if (MP_GROUP(x, y) == group)
152                     return (x + y * WORLD_SIDE_LEN);
153         }
154     }
155     return (-1);
156 }
157 
158 /*
159    // spiral round from startx,starty until we hit a 2x2 space.
160    // return the x y coords encoded as x+y*WORLD_SIDE_LEN
161    // return -1 if we don't find one.
162  */
spiral_find_2x2(int startx,int starty)163 static int spiral_find_2x2(int startx, int starty)
164 {
165     int i, j, x, y;
166     x = startx;
167     y = starty;
168     /* let's just do a complete spiral for now, work out the bounds later */
169     for (i = 1; i < (WORLD_SIDE_LEN + WORLD_SIDE_LEN); i++) {
170         for (j = 0; j < i; j++) {
171             x--;
172             if (x > 1 && x < WORLD_SIDE_LEN - 2 && y > 1 && y < WORLD_SIDE_LEN - 2)
173                 if (GROUP_IS_BARE(MP_GROUP(x, y))
174                     && GROUP_IS_BARE(MP_GROUP(x + 1, y))
175                     && GROUP_IS_BARE(MP_GROUP(x, y + 1))
176                     && GROUP_IS_BARE(MP_GROUP(x + 1, y + 1)))
177                     return (x + y * WORLD_SIDE_LEN);
178         }
179         for (j = 0; j < i; j++) {
180             y--;
181             if (x > 1 && x < WORLD_SIDE_LEN - 2 && y > 1 && y < WORLD_SIDE_LEN - 2)
182                 if (GROUP_IS_BARE(MP_GROUP(x, y))
183                     && GROUP_IS_BARE(MP_GROUP(x + 1, y))
184                     && GROUP_IS_BARE(MP_GROUP(x, y + 1))
185                     && GROUP_IS_BARE(MP_GROUP(x + 1, y + 1)))
186                     return (x + y * WORLD_SIDE_LEN);
187         }
188         i++;
189         for (j = 0; j < i; j++) {
190             x++;
191             if (x > 1 && x < WORLD_SIDE_LEN - 2 && y > 1 && y < WORLD_SIDE_LEN - 2)
192                 if (GROUP_IS_BARE(MP_GROUP(x, y))
193                     && GROUP_IS_BARE(MP_GROUP(x + 1, y))
194                     && GROUP_IS_BARE(MP_GROUP(x, y + 1))
195                     && GROUP_IS_BARE(MP_GROUP(x + 1, y + 1)))
196                     return (x + y * WORLD_SIDE_LEN);
197         }
198         for (j = 0; j < i; j++) {
199             y++;
200             if (x > 1 && x < WORLD_SIDE_LEN - 2 && y > 1 && y < WORLD_SIDE_LEN - 2)
201                 if (GROUP_IS_BARE(MP_GROUP(x, y))
202                     && GROUP_IS_BARE(MP_GROUP(x + 1, y))
203                     && GROUP_IS_BARE(MP_GROUP(x, y + 1))
204                     && GROUP_IS_BARE(MP_GROUP(x + 1, y + 1)))
205                     return (x + y * WORLD_SIDE_LEN);
206         }
207     }
208     return (-1);
209 }
210