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