1 /* ---------------------------------------------------------------------- *
2 * residence.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 "residence.h"
10 #include "waterwell.h"
11 #include <stdlib.h>
12
do_residence(int x,int y)13 void do_residence(int x, int y)
14 {
15 /*
16 // int_1 is a job swingometer to choose +/- JOB_SWING% of normal
17 // int_2 is the date of the last starve
18 // int_3 unused
19 // int_4 is the birth rate modifier.
20 // int_5 is the death rate modifier.
21 // int_6 unused
22 // int_7 unused Could be FLAG_HAD_POWER which is specific to residences, and will free 1 flag.
23 // btw, FLAG_POWERED and FLAG_GOT_POWER means the same thing. => free 1 more flag.
24 //
25 */
26 int p; /* population */
27 int bad = 35, good = 30; /* (un)desirability of living here */
28 int r, po, swing;
29 int hc = 0; /* have health cover ? */
30 int brm = 0, drm = 0; /* birth/death rate modifier */
31 int cc = 0;
32 int birth_flag = 0;
33
34 p = MP_INFO(x, y).population;
35 if ((MP_INFO(x, y).flags & FLAG_HEALTH_COVER) != 0) {
36 brm += RESIDENCE_BRM_HEALTH;
37 good += 15;
38 hc = 1;
39 }
40 if ((MP_INFO(x, y).flags & FLAG_FIRE_COVER) == 0)
41 bad += 5;
42 else
43 good += 15;
44 if ((MP_INFO(x, y).flags & FLAG_CRICKET_COVER) != 0) {
45 good += 20;
46 cc = CRICKET_JOB_SWING;
47 }
48 /* normal deaths + pollution deaths */
49 po = ((MP_POL(x, y) / 50) + 1);
50 if ((RESIDENCE_BASE_DR - MP_INFO(x, y).int_5 - po) > 1)
51 r = rand() % (RESIDENCE_BASE_DR - MP_INFO(x, y).int_5 - po);
52 else
53 r = 2;
54 if (p > 0 && (r < po)) {
55 if (r == 0 || hc == 0)
56 p--;
57 else if (hc != 0 && po > 10 && rand() % 4 == 0) {
58 p--;
59 unnat_deaths++;
60 total_pollution_deaths++;
61 pollution_deaths_history += 1.0;
62 bad += 100;
63 }
64 if (r > 0 && hc == 0) {
65 unnat_deaths++;
66 total_pollution_deaths++;
67 pollution_deaths_history += 1.0;
68 bad += 100;
69 }
70 }
71 /* normal births - must have food, water and jobs... and people */
72 if (use_waterwell && (total_time >= deadline) )
73 birth_flag = FLAG_FED + FLAG_WATERWELL_COVER + FLAG_EMPLOYED;
74 else
75 birth_flag = FLAG_FED + FLAG_EMPLOYED;
76
77 if (((MP_INFO(x, y).flags & birth_flag) == birth_flag)
78 && (rand() % (RESIDENCE_BASE_BR + MP_INFO(x, y).int_4) == 1)
79 && (p > 0)) {
80 #ifdef DEBUG_WATERWELL
81 fprintf(stderr, " birth ok, we are fed. use_waterwell= %i\n", use_waterwell);
82 #endif
83 p++;
84 total_births++;
85 good += 50;
86 }
87 /* are people starving or lacking water ? */
88 if (((MP_INFO(x, y).flags & FLAG_FED) == 0)
89 | (use_waterwell & ((MP_INFO(x, y).flags & FLAG_WATERWELL_COVER) == 0))
90 && p > 0) {
91 if (total_time > deadline) {
92 #ifdef DEBUG_WATERWELL
93 fprintf(stderr, " hey, we are dying: lack of food or water!, use_waterwell=%i\n", use_waterwell);
94 #endif
95
96 if (rand() % DAYS_PER_STARVE == 1) {
97 p--;
98 unnat_deaths++;
99 total_starve_deaths++;
100 starve_deaths_history += 1.0;
101 }
102 starving_population += p;
103 bad += 250;
104 drm += 100;
105 }
106 MP_INFO(x, y).int_2 = total_time; /* for the starve screen */
107 }
108 /* kick one out if overpopulated */
109 if (MP_TYPE(x, y) == CST_RESIDENCE_LL) {
110 brm += RESIDENCE1_BRM;
111 drm += p * 8;
112 if (p > 50) {
113 p--;
114 people_pool++;
115 brm += 20;
116 }
117 } else if (MP_TYPE(x, y) == CST_RESIDENCE_ML) {
118 brm += RESIDENCE2_BRM;
119 drm += p * 3;
120 if (p > 100) {
121 p--;
122 people_pool++;
123 brm += 10;
124 }
125 } else if (MP_TYPE(x, y) == CST_RESIDENCE_HL) {
126 brm += RESIDENCE3_BRM;
127 drm += p;
128 good += 40;
129 if (p > 200) {
130 p--;
131 people_pool++;
132 brm += 10;
133 }
134 } else if (MP_TYPE(x, y) == CST_RESIDENCE_LH) {
135 brm += RESIDENCE4_BRM;
136 drm += p * 5;
137 if (p > 100) {
138 p--;
139 people_pool++;
140 brm += 20;
141 }
142 } else if (MP_TYPE(x, y) == CST_RESIDENCE_MH) {
143 brm += RESIDENCE5_BRM;
144 drm += p / 2;
145 if (p > 200) {
146 p--;
147 people_pool++;
148 brm += 10;
149 }
150 } else if (MP_TYPE(x, y) == CST_RESIDENCE_HH) {
151 good += 100;
152 brm += RESIDENCE6_BRM;
153 drm += p;
154 if (p > 400) {
155 p--;
156 people_pool++;
157 brm += 10;
158 }
159 }
160
161 /* XXX AL1: this is daily accumulator used stats.cpp, and maybe pop graph */
162 population += p;
163
164 /* now get power */
165 if (get_power(x, y, POWER_RES_OVERHEAD + (POWER_USE_PER_PERSON * p), 0) != 0) {
166 MP_INFO(x, y).flags |= FLAG_POWERED;
167 MP_INFO(x, y).flags |= FLAG_HAD_POWER;
168 good += 10;
169 } else {
170 MP_INFO(x, y).flags &= (0xffffffff - FLAG_POWERED);
171 bad += 15;
172 if ((MP_INFO(x, y).flags & FLAG_HAD_POWER) != 0)
173 bad += 50;
174 }
175 /* now get fed */
176 /* AL1: could be done earlier, before check for starvation */
177 /* this will be taken into account at next turn */
178 if ( get_food(x, y, p) != 0 ) {
179 if (p>0)
180 MP_INFO(x, y).flags |= FLAG_FED;
181 good += 10;
182 } else {
183 MP_INFO(x, y).flags &= (0xffffffff - FLAG_FED);
184 //MP_INFO(x,y).int_2 = total_time;
185 }
186
187 /* now supply jobs and buy goods if employed */
188 if (MP_INFO(x, y).int_1 > 0)
189 swing = JOB_SWING + (hc * HC_JOB_SWING) + cc;
190 else
191 swing = -(JOB_SWING + (hc * HC_JOB_SWING) + cc);
192
193 if (put_jobs(x, y, ((p * (WORKING_POP_PERCENT + swing)) / 100)) != 0) {
194 MP_INFO(x, y).flags |= FLAG_EMPLOYED;
195 MP_INFO(x, y).int_1++;
196 if (MP_INFO(x, y).int_1 > 10)
197 MP_INFO(x, y).int_1 = 10;
198 good += 20;
199 if (get_goods(x, y, p / 4) != 0) {
200 good += 10;
201 if (get_power(x, y, p / 2, 0) != 0) {
202 good += 5;
203 brm += 10;
204 /* buy more goods if got power for them */
205 if (get_goods(x, y, p / 4) != 0)
206 good += 5;
207 } else
208 bad += 5;
209 }
210 } else if (MP_INFO(x, y).int_1 < 10) {
211 MP_INFO(x, y).flags &= (0xffffffff - FLAG_EMPLOYED);
212 MP_INFO(x, y).int_1 -= 11;
213 if (MP_INFO(x, y).int_1 < -300)
214 MP_INFO(x, y).int_1 = -300;
215 unemployed_population += p;
216 total_unemployed_days += p;
217 if (total_unemployed_days >= NUMOF_DAYS_IN_YEAR) {
218 total_unemployed_years++;
219 /* think we're ok doing this, max of about 120 added each time. */
220 total_unemployed_days -= NUMOF_DAYS_IN_YEAR;
221 unemployed_history += 1.0;
222 }
223 unemployment_cost += p; /* hmmm */
224 bad += 70;
225 } else {
226 MP_INFO(x, y).int_1 -= 20;
227 bad += 50;
228 }
229 drm += p / 4;
230 /* people_pool stuff */
231 bad += p / 2;
232 bad += MP_POL(x, y) / 20;
233 good += people_pool / 27;
234 r = rand() % ((good + bad) * RESIDENCE_PPM);
235 if (r < bad) {
236 if (p > MIN_RES_POPULATION) {
237 p--;
238 people_pool++;
239 }
240 } else if (people_pool > 0
241 && r > ((good + bad) * (RESIDENCE_PPM - 1) + bad)) { /* r > (rmax - good) */
242 p++;
243 people_pool--;
244 }
245 MP_INFO(x, y).population = p;
246 MP_INFO(x, y).int_4 = brm;
247 MP_INFO(x, y).int_5 = drm;
248 }
249
mps_residence(int x,int y)250 void mps_residence(int x, int y)
251 {
252 int i = 0;
253 const char *p;
254
255 mps_store_title(i++, _("Residence"));
256
257 i++;
258
259 mps_store_sd(i++, _("People"), MP_INFO(x, y).population);
260
261 if (use_waterwell) {
262 p = ((MP_INFO(x, y).flags & FLAG_WATERWELL_COVER) != 0)
263 ? _("YES") : _("NO");
264 mps_store_ss(i++, _("Water"), p);
265 }
266
267 p = ((MP_INFO(x, y).flags & FLAG_FED) != 0) ? _("YES") : _("NO");
268 mps_store_ss(i++, _("Fed"), p);
269
270 p = ((MP_INFO(x, y).flags & FLAG_POWERED) != 0) ? _("YES") : _("NO");
271 mps_store_ss(i++, _("Power"), p);
272
273 p = ((MP_INFO(x, y).flags & FLAG_EMPLOYED) != 0) ? _("YES") : _("NO");
274 mps_store_ss(i++, _("Employed"), p);
275
276 p = (MP_INFO(x, y).int_1 >= 10) ? _("good") : _("poor");
277 mps_store_ss(i++, _("Job"), p);
278
279 p = ((MP_INFO(x, y).flags & FLAG_HEALTH_COVER) != 0) ? _("YES") : _("NO");
280 mps_store_ss(i++, _("Health Cvr"), p);
281
282 p = ((MP_INFO(x, y).flags & FLAG_FIRE_COVER) != 0) ? _("YES") : _("NO");
283 mps_store_ss(i++, _("Fire"), p);
284
285 p = ((MP_INFO(x, y).flags & FLAG_CRICKET_COVER) != 0) ? _("YES") : _("NO");
286 mps_store_ss(i++, _("Sport"), p);
287
288 mps_store_sd(i++, _("Pollution"), MP_POL(x, y));
289
290 }
291