1 /* ---------------------------------------------------------------------- *
2  * rocket_pad.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 <lin-city.h>
10 #include <lctypes.h>
11 #include <lcintl.h>
12 #include <lcconfig.h>
13 #include <engglobs.h>
14 #include <cliglobs.h>
15 #include <stats.h>
16 #include <screen.h>
17 #include <mouse.h> /* XXX: for fire_area! */
18 #include <mps.h>
19 #include <rocket_pad.h>
20 
21 
22 void
do_rocket_pad(int x,int y)23 do_rocket_pad (int x, int y)
24 {
25     /*
26       // You need ROCKET_PAD_JOBS, ROCKET_PAD_GOODS and ROCKET_PAD_STEEL
27       // to add 1 to % of ready to fire.
28       // int_1 is the stored jobs
29       // int_2 is the stored goods
30       // int_3 is the stored steel
31       // int_4 is the count which gets to ROCKET_PAD_LAUNCH to fire.
32       // int_5 is the time of the next animation frame, when waiting for launch.
33       */
34     if (MP_TYPE(x,y) == CST_ROCKET_FLOWN)
35 	return;			/* The rocket has been launched. */
36 
37     /* get some jobs */
38     if (MP_INFO(x,y).int_1 < ROCKET_PAD_JOBS_STORE)
39     {
40 	if (get_jobs (x, y, ROCKET_PAD_JOBS + 10) != 0)
41 	    MP_INFO(x,y).int_1 += ROCKET_PAD_JOBS;
42     }
43     /* get goods */
44     if (MP_INFO(x,y).int_2 < ROCKET_PAD_GOODS_STORE)
45     {
46 	if (get_goods (x, y, ROCKET_PAD_GOODS + 10) != 0)
47 	    MP_INFO(x,y).int_2 += ROCKET_PAD_GOODS;
48 	else if (get_goods (x, y, ROCKET_PAD_GOODS / 10) != 0)
49 	    MP_INFO(x,y).int_2 += ROCKET_PAD_GOODS / 5;
50 	else if (get_goods (x, y, ROCKET_PAD_GOODS / 50) != 0)
51 	    MP_INFO(x,y).int_2 += ROCKET_PAD_GOODS / 20;
52     }
53     /* get steel */
54     if (MP_INFO(x,y).int_3 < ROCKET_PAD_STEEL_STORE)
55     {
56 	if (get_steel (x, y, ROCKET_PAD_STEEL + 10) != 0)
57 	    MP_INFO(x,y).int_3 += ROCKET_PAD_STEEL + 10;
58 	else if (get_steel (x, y, ROCKET_PAD_STEEL / 5) != 0)
59 	    MP_INFO(x,y).int_3 += ROCKET_PAD_STEEL / 5;
60 	else if (get_steel (x, y, ROCKET_PAD_STEEL / 20) != 0)
61 	    MP_INFO(x,y).int_3 += ROCKET_PAD_STEEL / 20;
62     }
63 #ifdef DEBUG_ROCKETS
64     MP_INFO(x,y).int_4++;
65 #else
66     /* now build the rocket.  Unlike uni's need a full store to make +1% */
67     if (MP_TYPE(x,y) < CST_ROCKET_5
68 	&& MP_INFO(x,y).int_1 >= ROCKET_PAD_JOBS_STORE
69 	&& MP_INFO(x,y).int_2 >= ROCKET_PAD_GOODS_STORE
70 	&& MP_INFO(x,y).int_3 >= ROCKET_PAD_STEEL_STORE)
71     {
72 	MP_INFO(x,y).int_1 -= ROCKET_PAD_JOBS_STORE;
73 	MP_INFO(x,y).int_2 -= ROCKET_PAD_GOODS_STORE;
74 	MP_INFO(x,y).int_3 -= ROCKET_PAD_STEEL_STORE;
75 	MP_INFO(x,y).int_4++;
76 	goods_used += ROCKET_PAD_GOODS_STORE;
77 
78     }
79 #endif
80     rocket_pad_cost += ROCKET_PAD_RUNNING_COST;
81     /* animate and return if already said no to launch */
82     if (MP_TYPE(x,y) >= CST_ROCKET_5
83 	&& MP_INFO(x,y).int_4 >= (100 * ROCKET_PAD_LAUNCH) / 100)
84     {
85 	if (real_time >= MP_INFO(x,y).int_5)
86 	{
87 	    MP_INFO(x,y).int_5 = real_time + ROCKET_ANIMATION_SPEED;
88 	    switch (MP_TYPE(x,y))
89 	    {
90 	    case (CST_ROCKET_5):
91 		MP_TYPE(x,y) = CST_ROCKET_6;
92 		break;
93 	    case (CST_ROCKET_6):
94 		MP_TYPE(x,y) = CST_ROCKET_7;
95 		break;
96 	    case (CST_ROCKET_7):
97 		MP_TYPE(x,y) = CST_ROCKET_5;
98 		break;
99 	    }
100 	}
101 	return;
102     }
103     /* now choose a graphic */
104     if (MP_INFO(x,y).int_4 < (25 * ROCKET_PAD_LAUNCH) / 100)
105 	MP_TYPE(x,y) = CST_ROCKET_1;
106     else if (MP_INFO(x,y).int_4 < (60 * ROCKET_PAD_LAUNCH) / 100)
107 	MP_TYPE(x,y) = CST_ROCKET_2;
108     else if (MP_INFO(x,y).int_4 < (90 * ROCKET_PAD_LAUNCH) / 100)
109 	MP_TYPE(x,y) = CST_ROCKET_3;
110     else if (MP_INFO(x,y).int_4 < (100 * ROCKET_PAD_LAUNCH) / 100)
111 	MP_TYPE(x,y) = CST_ROCKET_4;
112     else if (MP_INFO(x,y).int_4 >= (100 * ROCKET_PAD_LAUNCH) / 100) {
113 	MP_TYPE(x,y) = CST_ROCKET_5;
114 	update_main_screen (0);
115 	if (ask_launch_rocket_now (x,y)) {
116 	    launch_rocket (x,y);
117 	}
118 	/* so we don't get get our money back when we bulldoze. */
119 	if (x == last_built_x && y == last_built_y) {
120 	    x = 0;
121 	    y = 0;
122 	}
123     }
124 }
125 
126 void
launch_rocket(int x,int y)127 launch_rocket (int x, int y)
128 {
129     int i, r, xx, yy, xxx, yyy;
130     rockets_launched++;
131     MP_TYPE(x,y) = CST_ROCKET_FLOWN;
132     update_main_screen (0);
133     r = rand () % MAX_TECH_LEVEL;
134     if (r > tech_level || rand () % 100 > (rockets_launched * 15 + 25)) {
135 	/* the launch failed */
136 	display_rocket_result_dialog (ROCKET_LAUNCH_BAD);
137 	rockets_launched_success = 0;
138 	xx = ((rand () % 40) - 20) + x;
139 	yy = ((rand () % 40) - 20) + y;
140 	for (i = 0; i < 20; i++) {
141 	    xxx = ((rand () % 20) - 10) + xx;
142 	    yyy = ((rand () % 20) - 10) + yy;
143 	    if (xxx > 0 && xxx < WORLD_SIDE_LEN
144 		&& yyy > 0 && yyy < WORLD_SIDE_LEN) {
145 		/* don't crash on it's own area */
146 		if (xxx >= x && xxx < (x + 4) && yyy >= y && yyy < (y + 4))
147 		    continue;
148 		fire_area (xxx, yyy);
149 		/* make a sound perhaps */
150 	    }
151 	}
152     } else {
153 	rockets_launched_success++;
154 	if (rockets_launched_success > 5) {
155 	    remove_people (1000);
156 	    if (people_pool || housed_population)
157 	      display_rocket_result_dialog (ROCKET_LAUNCH_EVAC);
158 	} else {
159 	    display_rocket_result_dialog (ROCKET_LAUNCH_GOOD);
160 	}
161     }
162 }
163 
164 void
mps_rocket(int x,int y)165 mps_rocket (int x, int y)
166 {
167     int i = 0;
168 
169     mps_store_title(i++,_("Rocket Pad"));
170     i++;
171 
172     mps_store_title(i++,_("Completion"));
173     mps_store_fp(i++, MP_INFO(x,y).int_4 * 100.0 / ROCKET_PAD_LAUNCH);
174     i++;
175     mps_store_title(i++,_("Inventory"));
176     mps_store_sfp(i++,_("Jobs"),
177 		  MP_INFO(x,y).int_1 * 100.0 / ROCKET_PAD_JOBS_STORE);
178     mps_store_sfp(i++,_("Goods"),
179 		  MP_INFO(x,y).int_2 * 100.0 / ROCKET_PAD_GOODS_STORE);
180     mps_store_sfp(i++,_("Steel"),
181 		  MP_INFO(x,y).int_3 * 100.0 / ROCKET_PAD_STEEL_STORE);
182 
183 }
184