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