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