|
1 /* $Id$ */ |
|
2 |
|
3 #include "stdafx.h" |
|
4 #include "openttd.h" |
|
5 #include "debug.h" |
|
6 #include "functions.h" |
|
7 #include "strings.h" |
|
8 #include "table/strings.h" |
|
9 #include "table/sprites.h" |
|
10 #include "map.h" |
|
11 #include "gui.h" |
|
12 #include "window.h" |
|
13 #include "gfx.h" |
|
14 #include "command.h" |
|
15 #include "viewport.h" |
|
16 #include "industry.h" |
|
17 #include "town.h" |
|
18 #include "variables.h" |
|
19 |
|
20 const byte _build_industry_types[4][12] = { |
|
21 { 1, 2, 4, 6, 8, 0, 3, 5, 9, 11, 18 }, |
|
22 { 1, 14, 4, 13, 7, 0, 3, 9, 11, 15 }, |
|
23 { 25, 13, 4, 23, 22, 11, 17, 10, 24, 19, 20, 21 }, |
|
24 { 27, 30, 31, 33, 26, 28, 29, 32, 34, 35, 36 }, |
|
25 }; |
|
26 |
|
27 static void UpdateIndustryProduction(Industry *i); |
|
28 |
|
29 static void BuildIndustryWndProc(Window *w, WindowEvent *e) |
|
30 { |
|
31 switch (e->event) { |
|
32 case WE_PAINT: |
|
33 DrawWindowWidgets(w); |
|
34 if (_thd.place_mode == 1 && _thd.window_class == WC_BUILD_INDUSTRY) { |
|
35 int ind_type = _build_industry_types[_opt_ptr->landscape][WP(w,def_d).data_1]; |
|
36 |
|
37 SetDParam(0, (_price.build_industry >> 5) * GetIndustrySpec(ind_type)->cost_multiplier); |
|
38 DrawStringCentered(85, w->height - 21, STR_482F_COST, 0); |
|
39 } |
|
40 break; |
|
41 |
|
42 case WE_CLICK: { |
|
43 int wid = e->we.click.widget; |
|
44 if (wid >= 3) { |
|
45 if (HandlePlacePushButton(w, wid, SPR_CURSOR_INDUSTRY, 1, NULL)) |
|
46 WP(w,def_d).data_1 = wid - 3; |
|
47 } |
|
48 } break; |
|
49 |
|
50 case WE_PLACE_OBJ: |
|
51 if (DoCommandP(e->we.place.tile, _build_industry_types[_opt_ptr->landscape][WP(w,def_d).data_1], 0, NULL, CMD_BUILD_INDUSTRY | CMD_MSG(STR_4830_CAN_T_CONSTRUCT_THIS_INDUSTRY))) |
|
52 ResetObjectToPlace(); |
|
53 break; |
|
54 |
|
55 case WE_ABORT_PLACE_OBJ: |
|
56 RaiseWindowButtons(w); |
|
57 break; |
|
58 } |
|
59 } |
|
60 |
|
61 static const Widget _build_industry_land0_widgets[] = { |
|
62 { WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, |
|
63 { WWT_CAPTION, RESIZE_NONE, 7, 11, 169, 0, 13, STR_0314_FUND_NEW_INDUSTRY, STR_018C_WINDOW_TITLE_DRAG_THIS}, |
|
64 { WWT_PANEL, RESIZE_NONE, 7, 0, 169, 14, 115, 0x0, STR_NULL}, |
|
65 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 16, 27, STR_0241_POWER_STATION, STR_0263_CONSTRUCT_POWER_STATION}, |
|
66 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 29, 40, STR_0242_SAWMILL, STR_0264_CONSTRUCT_SAWMILL}, |
|
67 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 42, 53, STR_0244_OIL_REFINERY, STR_0266_CONSTRUCT_OIL_REFINERY}, |
|
68 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 55, 66, STR_0246_FACTORY, STR_0268_CONSTRUCT_FACTORY}, |
|
69 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 68, 79, STR_0247_STEEL_MILL, STR_0269_CONSTRUCT_STEEL_MILL}, |
|
70 { WIDGETS_END}, |
|
71 }; |
|
72 |
|
73 static const Widget _build_industry_land1_widgets[] = { |
|
74 { WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, |
|
75 { WWT_CAPTION, RESIZE_NONE, 7, 11, 169, 0, 13, STR_0314_FUND_NEW_INDUSTRY, STR_018C_WINDOW_TITLE_DRAG_THIS}, |
|
76 { WWT_PANEL, RESIZE_NONE, 7, 0, 169, 14, 115, 0x0, STR_NULL}, |
|
77 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 16, 27, STR_0241_POWER_STATION, STR_0263_CONSTRUCT_POWER_STATION}, |
|
78 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 29, 40, STR_024C_PAPER_MILL, STR_026E_CONSTRUCT_PAPER_MILL}, |
|
79 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 42, 53, STR_0244_OIL_REFINERY, STR_0266_CONSTRUCT_OIL_REFINERY}, |
|
80 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 55, 66, STR_024D_FOOD_PROCESSING_PLANT, STR_026F_CONSTRUCT_FOOD_PROCESSING}, |
|
81 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 68, 79, STR_024E_PRINTING_WORKS, STR_0270_CONSTRUCT_PRINTING_WORKS}, |
|
82 { WIDGETS_END}, |
|
83 }; |
|
84 |
|
85 static const Widget _build_industry_land2_widgets[] = { |
|
86 { WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, |
|
87 { WWT_CAPTION, RESIZE_NONE, 7, 11, 169, 0, 13, STR_0314_FUND_NEW_INDUSTRY, STR_018C_WINDOW_TITLE_DRAG_THIS}, |
|
88 { WWT_PANEL, RESIZE_NONE, 7, 0, 169, 14, 115, 0x0, STR_NULL}, |
|
89 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 16, 27, STR_0250_LUMBER_MILL, STR_0273_CONSTRUCT_LUMBER_MILL_TO}, |
|
90 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 29, 40, STR_024D_FOOD_PROCESSING_PLANT, STR_026F_CONSTRUCT_FOOD_PROCESSING}, |
|
91 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 42, 53, STR_0244_OIL_REFINERY, STR_0266_CONSTRUCT_OIL_REFINERY}, |
|
92 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 55, 66, STR_0246_FACTORY, STR_0268_CONSTRUCT_FACTORY}, |
|
93 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 68, 79, STR_0254_WATER_TOWER, STR_0277_CONSTRUCT_WATER_TOWER_CAN}, |
|
94 { WIDGETS_END}, |
|
95 }; |
|
96 |
|
97 static const Widget _build_industry_land3_widgets[] = { |
|
98 { WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, |
|
99 { WWT_CAPTION, RESIZE_NONE, 7, 11, 169, 0, 13, STR_0314_FUND_NEW_INDUSTRY, STR_018C_WINDOW_TITLE_DRAG_THIS}, |
|
100 { WWT_PANEL, RESIZE_NONE, 7, 0, 169, 14, 115, 0x0, STR_NULL}, |
|
101 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 16, 27, STR_0258_CANDY_FACTORY, STR_027B_CONSTRUCT_CANDY_FACTORY}, |
|
102 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 29, 40, STR_025B_TOY_SHOP, STR_027E_CONSTRUCT_TOY_SHOP}, |
|
103 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 42, 53, STR_025C_TOY_FACTORY, STR_027F_CONSTRUCT_TOY_FACTORY}, |
|
104 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 55, 66, STR_025E_FIZZY_DRINK_FACTORY, STR_0281_CONSTRUCT_FIZZY_DRINK_FACTORY}, |
|
105 { WIDGETS_END}, |
|
106 }; |
|
107 |
|
108 static const Widget _build_industry_land0_widgets_extra[] = { |
|
109 { WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, |
|
110 { WWT_CAPTION, RESIZE_NONE, 7, 11, 169, 0, 13, STR_0314_FUND_NEW_INDUSTRY, STR_018C_WINDOW_TITLE_DRAG_THIS}, |
|
111 { WWT_PANEL, RESIZE_NONE, 7, 0, 169, 14, 187, 0x0, STR_NULL}, |
|
112 |
|
113 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 16, 27, STR_0241_POWER_STATION, STR_0263_CONSTRUCT_POWER_STATION}, |
|
114 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 29, 40, STR_0242_SAWMILL, STR_0264_CONSTRUCT_SAWMILL}, |
|
115 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 42, 53, STR_0244_OIL_REFINERY, STR_0266_CONSTRUCT_OIL_REFINERY}, |
|
116 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 55, 66, STR_0246_FACTORY, STR_0268_CONSTRUCT_FACTORY}, |
|
117 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 68, 79, STR_0247_STEEL_MILL, STR_0269_CONSTRUCT_STEEL_MILL}, |
|
118 |
|
119 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 84, 95, STR_0240_COAL_MINE, STR_CONSTRUCT_COAL_MINE_TIP}, |
|
120 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 97, 108, STR_0243_FOREST, STR_CONSTRUCT_FOREST_TIP}, |
|
121 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 110, 121, STR_0245_OIL_RIG, STR_CONSTRUCT_OIL_RIG_TIP}, |
|
122 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 123, 134, STR_0248_FARM, STR_CONSTRUCT_FARM_TIP}, |
|
123 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 136, 147, STR_024A_OIL_WELLS, STR_CONSTRUCT_OIL_WELLS_TIP}, |
|
124 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 149, 160, STR_0249_IRON_ORE_MINE, STR_CONSTRUCT_IRON_ORE_MINE_TIP}, |
|
125 |
|
126 { WIDGETS_END}, |
|
127 }; |
|
128 |
|
129 static const Widget _build_industry_land1_widgets_extra[] = { |
|
130 { WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, |
|
131 { WWT_CAPTION, RESIZE_NONE, 7, 11, 169, 0, 13, STR_0314_FUND_NEW_INDUSTRY, STR_018C_WINDOW_TITLE_DRAG_THIS}, |
|
132 { WWT_PANEL, RESIZE_NONE, 7, 0, 169, 14, 174, 0x0, STR_NULL}, |
|
133 |
|
134 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 16, 27, STR_0241_POWER_STATION, STR_0263_CONSTRUCT_POWER_STATION}, |
|
135 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 29, 40, STR_024C_PAPER_MILL, STR_026E_CONSTRUCT_PAPER_MILL}, |
|
136 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 42, 53, STR_0244_OIL_REFINERY, STR_0266_CONSTRUCT_OIL_REFINERY}, |
|
137 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 55, 66, STR_024D_FOOD_PROCESSING_PLANT, STR_026F_CONSTRUCT_FOOD_PROCESSING}, |
|
138 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 68, 79, STR_024E_PRINTING_WORKS, STR_0270_CONSTRUCT_PRINTING_WORKS}, |
|
139 |
|
140 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 84, 95, STR_0240_COAL_MINE, STR_CONSTRUCT_COAL_MINE_TIP}, |
|
141 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 97, 108, STR_0243_FOREST, STR_CONSTRUCT_FOREST_TIP}, |
|
142 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 110, 121, STR_0248_FARM, STR_CONSTRUCT_FARM_TIP}, |
|
143 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 123, 134, STR_024A_OIL_WELLS, STR_CONSTRUCT_OIL_WELLS_TIP}, |
|
144 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 136, 147, STR_024F_GOLD_MINE, STR_CONSTRUCT_GOLD_MINE_TIP}, |
|
145 { WIDGETS_END}, |
|
146 }; |
|
147 |
|
148 static const Widget _build_industry_land2_widgets_extra[] = { |
|
149 { WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, |
|
150 { WWT_CAPTION, RESIZE_NONE, 7, 11, 169, 0, 13, STR_0314_FUND_NEW_INDUSTRY, STR_018C_WINDOW_TITLE_DRAG_THIS}, |
|
151 { WWT_PANEL, RESIZE_NONE, 7, 0, 169, 14, 200, 0x0, STR_NULL}, |
|
152 |
|
153 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 16, 27, STR_0250_LUMBER_MILL, STR_0273_CONSTRUCT_LUMBER_MILL_TO}, |
|
154 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 29, 40, STR_024D_FOOD_PROCESSING_PLANT, STR_026F_CONSTRUCT_FOOD_PROCESSING}, |
|
155 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 42, 53, STR_0244_OIL_REFINERY, STR_0266_CONSTRUCT_OIL_REFINERY}, |
|
156 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 55, 66, STR_0246_FACTORY, STR_0268_CONSTRUCT_FACTORY}, |
|
157 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 68, 79, STR_0254_WATER_TOWER, STR_0277_CONSTRUCT_WATER_TOWER_CAN}, |
|
158 |
|
159 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 84, 95, STR_024A_OIL_WELLS, STR_CONSTRUCT_OIL_WELLS_TIP}, |
|
160 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 97, 108, STR_0255_DIAMOND_MINE, STR_CONSTRUCT_DIAMOND_MINE_TIP}, |
|
161 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 110, 121, STR_0256_COPPER_ORE_MINE, STR_CONSTRUCT_COPPER_ORE_MINE_TIP}, |
|
162 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 123, 134, STR_0248_FARM, STR_CONSTRUCT_FARM_TIP}, |
|
163 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 136, 147, STR_0251_FRUIT_PLANTATION, STR_CONSTRUCT_FRUIT_PLANTATION_TIP}, |
|
164 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 149, 160, STR_0252_RUBBER_PLANTATION, STR_CONSTRUCT_RUBBER_PLANTATION_TIP}, |
|
165 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 162, 173, STR_0253_WATER_SUPPLY, STR_CONSTRUCT_WATER_SUPPLY_TIP}, |
|
166 { WIDGETS_END}, |
|
167 }; |
|
168 |
|
169 static const Widget _build_industry_land3_widgets_extra[] = { |
|
170 { WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, |
|
171 { WWT_CAPTION, RESIZE_NONE, 7, 11, 169, 0, 13, STR_0314_FUND_NEW_INDUSTRY, STR_018C_WINDOW_TITLE_DRAG_THIS}, |
|
172 { WWT_PANEL, RESIZE_NONE, 7, 0, 169, 14, 187, 0x0, STR_NULL}, |
|
173 |
|
174 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 16, 27, STR_0258_CANDY_FACTORY, STR_027B_CONSTRUCT_CANDY_FACTORY}, |
|
175 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 29, 40, STR_025B_TOY_SHOP, STR_027E_CONSTRUCT_TOY_SHOP}, |
|
176 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 42, 53, STR_025C_TOY_FACTORY, STR_027F_CONSTRUCT_TOY_FACTORY}, |
|
177 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 55, 66, STR_025E_FIZZY_DRINK_FACTORY, STR_0281_CONSTRUCT_FIZZY_DRINK_FACTORY}, |
|
178 |
|
179 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 71, 82, STR_0257_COTTON_CANDY_FOREST, STR_CONSTRUCT_COTTON_CANDY_TIP}, |
|
180 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 84, 95, STR_0259_BATTERY_FARM, STR_CONSTRUCT_BATTERY_FARM_TIP}, |
|
181 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 97, 108, STR_025A_COLA_WELLS, STR_CONSTRUCT_COLA_WELLS_TIP}, |
|
182 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 110, 121, STR_025D_PLASTIC_FOUNTAINS, STR_CONSTRUCT_PLASTIC_FOUNTAINS_TIP}, |
|
183 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 123, 134, STR_025F_BUBBLE_GENERATOR, STR_CONSTRUCT_BUBBLE_GENERATOR_TIP}, |
|
184 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 136, 147, STR_0260_TOFFEE_QUARRY, STR_CONSTRUCT_TOFFEE_QUARRY_TIP}, |
|
185 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 149, 160, STR_0261_SUGAR_MINE, STR_CONSTRUCT_SUGAR_MINE_TIP}, |
|
186 { WIDGETS_END}, |
|
187 }; |
|
188 |
|
189 |
|
190 static const WindowDesc _build_industry_land0_desc = { |
|
191 WDP_AUTO, WDP_AUTO, 170, 116, |
|
192 WC_BUILD_INDUSTRY,0, |
|
193 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET, |
|
194 _build_industry_land0_widgets, |
|
195 BuildIndustryWndProc |
|
196 }; |
|
197 |
|
198 static const WindowDesc _build_industry_land1_desc = { |
|
199 WDP_AUTO, WDP_AUTO, 170, 116, |
|
200 WC_BUILD_INDUSTRY,0, |
|
201 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET, |
|
202 _build_industry_land1_widgets, |
|
203 BuildIndustryWndProc |
|
204 }; |
|
205 |
|
206 static const WindowDesc _build_industry_land2_desc = { |
|
207 WDP_AUTO, WDP_AUTO, 170, 116, |
|
208 WC_BUILD_INDUSTRY,0, |
|
209 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET, |
|
210 _build_industry_land2_widgets, |
|
211 BuildIndustryWndProc |
|
212 }; |
|
213 |
|
214 static const WindowDesc _build_industry_land3_desc = { |
|
215 WDP_AUTO, WDP_AUTO, 170, 116, |
|
216 WC_BUILD_INDUSTRY,0, |
|
217 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET, |
|
218 _build_industry_land3_widgets, |
|
219 BuildIndustryWndProc |
|
220 }; |
|
221 |
|
222 static const WindowDesc _build_industry_land0_desc_extra = { |
|
223 WDP_AUTO, WDP_AUTO, 170, 188, |
|
224 WC_BUILD_INDUSTRY,0, |
|
225 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET, |
|
226 _build_industry_land0_widgets_extra, |
|
227 BuildIndustryWndProc |
|
228 }; |
|
229 |
|
230 static const WindowDesc _build_industry_land1_desc_extra = { |
|
231 WDP_AUTO, WDP_AUTO, 170, 175, |
|
232 WC_BUILD_INDUSTRY,0, |
|
233 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET, |
|
234 _build_industry_land1_widgets_extra, |
|
235 BuildIndustryWndProc |
|
236 }; |
|
237 |
|
238 static const WindowDesc _build_industry_land2_desc_extra = { |
|
239 WDP_AUTO, WDP_AUTO, 170, 201, |
|
240 WC_BUILD_INDUSTRY,0, |
|
241 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET, |
|
242 _build_industry_land2_widgets_extra, |
|
243 BuildIndustryWndProc |
|
244 }; |
|
245 |
|
246 static const WindowDesc _build_industry_land3_desc_extra = { |
|
247 WDP_AUTO, WDP_AUTO, 170, 188, |
|
248 WC_BUILD_INDUSTRY,0, |
|
249 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET, |
|
250 _build_industry_land3_widgets_extra, |
|
251 BuildIndustryWndProc |
|
252 }; |
|
253 |
|
254 static const WindowDesc * const _industry_window_desc[2][4] = { |
|
255 { |
|
256 &_build_industry_land0_desc, |
|
257 &_build_industry_land1_desc, |
|
258 &_build_industry_land2_desc, |
|
259 &_build_industry_land3_desc, |
|
260 }, |
|
261 { |
|
262 &_build_industry_land0_desc_extra, |
|
263 &_build_industry_land1_desc_extra, |
|
264 &_build_industry_land2_desc_extra, |
|
265 &_build_industry_land3_desc_extra, |
|
266 }, |
|
267 }; |
|
268 |
|
269 void ShowBuildIndustryWindow(void) |
|
270 { |
|
271 if (!IsValidPlayer(_current_player)) return; |
|
272 AllocateWindowDescFront(_industry_window_desc[_patches.build_rawmaterial_ind][_opt_ptr->landscape],0); |
|
273 } |
|
274 |
|
275 static inline bool isProductionMinimum(const Industry *i, int pt) { |
|
276 return i->production_rate[pt] == 1; |
|
277 } |
|
278 |
|
279 static inline bool isProductionMaximum(const Industry *i, int pt) { |
|
280 return i->production_rate[pt] == 255; |
|
281 } |
|
282 |
|
283 static inline bool IsProductionAlterable(const Industry *i) |
|
284 { |
|
285 return ((_game_mode == GM_EDITOR || _cheats.setup_prod.value) && |
|
286 (i->accepts_cargo[0] == CT_INVALID || i->accepts_cargo[0] == CT_VALUABLES)); |
|
287 } |
|
288 |
|
289 static void IndustryViewWndProc(Window *w, WindowEvent *e) |
|
290 { |
|
291 // WP(w,vp2_d).data_1 is for the editbox line |
|
292 // WP(w,vp2_d).data_2 is for the clickline |
|
293 // WP(w,vp2_d).data_3 is for the click pos (left or right) |
|
294 |
|
295 switch (e->event) { |
|
296 case WE_PAINT: { |
|
297 const Industry *i = GetIndustry(w->window_number); |
|
298 |
|
299 SetDParam(0, w->window_number); |
|
300 DrawWindowWidgets(w); |
|
301 |
|
302 if (i->accepts_cargo[0] != CT_INVALID) { |
|
303 StringID str; |
|
304 |
|
305 SetDParam(0, _cargoc.names_s[i->accepts_cargo[0]]); |
|
306 str = STR_4827_REQUIRES; |
|
307 if (i->accepts_cargo[1] != CT_INVALID) { |
|
308 SetDParam(1, _cargoc.names_s[i->accepts_cargo[1]]); |
|
309 str = STR_4828_REQUIRES; |
|
310 if (i->accepts_cargo[2] != CT_INVALID) { |
|
311 SetDParam(2, _cargoc.names_s[i->accepts_cargo[2]]); |
|
312 str = STR_4829_REQUIRES; |
|
313 } |
|
314 } |
|
315 DrawString(2, 107, str, 0); |
|
316 } |
|
317 |
|
318 if (i->produced_cargo[0] != CT_INVALID) { |
|
319 DrawString(2, 117, STR_482A_PRODUCTION_LAST_MONTH, 0); |
|
320 |
|
321 SetDParam(0, i->produced_cargo[0]); |
|
322 SetDParam(1, i->total_production[0]); |
|
323 |
|
324 SetDParam(2, i->pct_transported[0] * 100 >> 8); |
|
325 DrawString(4 + (IsProductionAlterable(i) ? 30 : 0), 127, STR_482B_TRANSPORTED, 0); |
|
326 // Let's put out those buttons.. |
|
327 if (IsProductionAlterable(i)) { |
|
328 DrawArrowButtons(5, 127, 3, (WP(w,vp2_d).data_2 == 1) ? WP(w,vp2_d).data_3 : 0, |
|
329 !isProductionMinimum(i, 0), !isProductionMaximum(i, 0)); |
|
330 } |
|
331 |
|
332 if (i->produced_cargo[1] != CT_INVALID) { |
|
333 SetDParam(0, i->produced_cargo[1]); |
|
334 SetDParam(1, i->total_production[1]); |
|
335 SetDParam(2, i->pct_transported[1] * 100 >> 8); |
|
336 DrawString(4 + (IsProductionAlterable(i) ? 30 : 0), 137, STR_482B_TRANSPORTED, 0); |
|
337 // Let's put out those buttons.. |
|
338 if (IsProductionAlterable(i)) { |
|
339 DrawArrowButtons(5, 137, 3, (WP(w,vp2_d).data_2 == 2) ? WP(w,vp2_d).data_3 : 0, |
|
340 !isProductionMinimum(i, 1), !isProductionMaximum(i, 1)); |
|
341 } |
|
342 } |
|
343 } |
|
344 |
|
345 DrawWindowViewport(w); |
|
346 } |
|
347 break; |
|
348 |
|
349 case WE_CLICK: { |
|
350 Industry *i; |
|
351 |
|
352 switch (e->we.click.widget) { |
|
353 case 5: { |
|
354 int line, x; |
|
355 |
|
356 i = GetIndustry(w->window_number); |
|
357 |
|
358 // We should work if needed.. |
|
359 if (!IsProductionAlterable(i)) return; |
|
360 |
|
361 x = e->we.click.pt.x; |
|
362 line = (e->we.click.pt.y - 127) / 10; |
|
363 if (e->we.click.pt.y >= 127 && IS_INT_INSIDE(line, 0, 2) && i->produced_cargo[line] != CT_INVALID) { |
|
364 if (IS_INT_INSIDE(x, 5, 25) ) { |
|
365 /* Clicked buttons, decrease or increase production */ |
|
366 if (x < 15) { |
|
367 if (isProductionMinimum(i, line)) return; |
|
368 i->production_rate[line] = maxu(i->production_rate[line] / 2, 1); |
|
369 } else { |
|
370 if (isProductionMaximum(i, line)) return; |
|
371 i->production_rate[line] = minu(i->production_rate[line] * 2, 255); |
|
372 } |
|
373 |
|
374 UpdateIndustryProduction(i); |
|
375 SetWindowDirty(w); |
|
376 w->flags4 |= 5 << WF_TIMEOUT_SHL; |
|
377 WP(w,vp2_d).data_2 = line+1; |
|
378 WP(w,vp2_d).data_3 = (x < 15 ? 1 : 2); |
|
379 } else if (IS_INT_INSIDE(x, 34, 160)) { |
|
380 // clicked the text |
|
381 WP(w,vp2_d).data_1 = line; |
|
382 SetDParam(0, i->production_rate[line] * 8); |
|
383 ShowQueryString(STR_CONFIG_PATCHES_INT32, STR_CONFIG_GAME_PRODUCTION, 10, 100, w, CS_ALPHANUMERAL); |
|
384 } |
|
385 } |
|
386 } break; |
|
387 case 6: |
|
388 i = GetIndustry(w->window_number); |
|
389 ScrollMainWindowToTile(i->xy + TileDiffXY(1, 1)); |
|
390 } break; |
|
391 |
|
392 } |
|
393 break; |
|
394 case WE_TIMEOUT: |
|
395 WP(w,vp2_d).data_2 = 0; |
|
396 WP(w,vp2_d).data_3 = 0; |
|
397 SetWindowDirty(w); |
|
398 break; |
|
399 |
|
400 case WE_ON_EDIT_TEXT: |
|
401 if (e->we.edittext.str[0] != '\0') { |
|
402 Industry* i = GetIndustry(w->window_number); |
|
403 int line = WP(w,vp2_d).data_1; |
|
404 |
|
405 i->production_rate[line] = clampu(atoi(e->we.edittext.str), 0, 255); |
|
406 UpdateIndustryProduction(i); |
|
407 SetWindowDirty(w); |
|
408 } |
|
409 } |
|
410 } |
|
411 |
|
412 static void UpdateIndustryProduction(Industry *i) |
|
413 { |
|
414 if (i->produced_cargo[0] != CT_INVALID) |
|
415 i->total_production[0] = 8 * i->production_rate[0]; |
|
416 |
|
417 if (i->produced_cargo[1] != CT_INVALID) |
|
418 i->total_production[1] = 8 * i->production_rate[1]; |
|
419 } |
|
420 |
|
421 static const Widget _industry_view_widgets[] = { |
|
422 { WWT_CLOSEBOX, RESIZE_NONE, 9, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, |
|
423 { WWT_CAPTION, RESIZE_NONE, 9, 11, 247, 0, 13, STR_4801, STR_018C_WINDOW_TITLE_DRAG_THIS}, |
|
424 { WWT_STICKYBOX, RESIZE_NONE, 9, 248, 259, 0, 13, 0x0, STR_STICKY_BUTTON}, |
|
425 { WWT_PANEL, RESIZE_NONE, 9, 0, 259, 14, 105, 0x0, STR_NULL}, |
|
426 { WWT_INSET, RESIZE_NONE, 9, 2, 257, 16, 103, 0x0, STR_NULL}, |
|
427 { WWT_PANEL, RESIZE_NONE, 9, 0, 259, 106, 147, 0x0, STR_NULL}, |
|
428 { WWT_PUSHTXTBTN, RESIZE_NONE, 9, 0, 129, 148, 159, STR_00E4_LOCATION, STR_482C_CENTER_THE_MAIN_VIEW_ON}, |
|
429 { WWT_PANEL, RESIZE_NONE, 9, 130, 259, 148, 159, 0x0, STR_NULL}, |
|
430 { WIDGETS_END}, |
|
431 }; |
|
432 |
|
433 static const WindowDesc _industry_view_desc = { |
|
434 WDP_AUTO, WDP_AUTO, 260, 160, |
|
435 WC_INDUSTRY_VIEW,0, |
|
436 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON, |
|
437 _industry_view_widgets, |
|
438 IndustryViewWndProc |
|
439 }; |
|
440 |
|
441 void ShowIndustryViewWindow(int industry) |
|
442 { |
|
443 Window *w = AllocateWindowDescFront(&_industry_view_desc, industry); |
|
444 |
|
445 if (w != NULL) { |
|
446 w->flags4 |= WF_DISABLE_VP_SCROLL; |
|
447 WP(w,vp2_d).data_1 = 0; |
|
448 WP(w,vp2_d).data_2 = 0; |
|
449 WP(w,vp2_d).data_3 = 0; |
|
450 AssignWindowViewport(w, 3, 17, 0xFE, 0x56, GetIndustry(w->window_number)->xy + TileDiffXY(1, 1), 1); |
|
451 } |
|
452 } |
|
453 |
|
454 static const Widget _industry_directory_widgets[] = { |
|
455 { WWT_CLOSEBOX, RESIZE_NONE, 13, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, |
|
456 { WWT_CAPTION, RESIZE_NONE, 13, 11, 495, 0, 13, STR_INDUSTRYDIR_CAPTION, STR_018C_WINDOW_TITLE_DRAG_THIS}, |
|
457 { WWT_STICKYBOX, RESIZE_NONE, 13, 496, 507, 0, 13, 0x0, STR_STICKY_BUTTON}, |
|
458 { WWT_PUSHTXTBTN, RESIZE_NONE, 13, 0, 100, 14, 25, STR_SORT_BY_NAME, STR_SORT_ORDER_TIP}, |
|
459 { WWT_PUSHTXTBTN, RESIZE_NONE, 13, 101, 200, 14, 25, STR_SORT_BY_TYPE, STR_SORT_ORDER_TIP}, |
|
460 { WWT_PUSHTXTBTN, RESIZE_NONE, 13, 201, 300, 14, 25, STR_SORT_BY_PRODUCTION, STR_SORT_ORDER_TIP}, |
|
461 { WWT_PUSHTXTBTN, RESIZE_NONE, 13, 301, 400, 14, 25, STR_SORT_BY_TRANSPORTED, STR_SORT_ORDER_TIP}, |
|
462 { WWT_PANEL, RESIZE_NONE, 13, 401, 495, 14, 25, 0x0, STR_NULL}, |
|
463 { WWT_PANEL, RESIZE_BOTTOM, 13, 0, 495, 26, 189, 0x0, STR_200A_TOWN_NAMES_CLICK_ON_NAME}, |
|
464 { WWT_SCROLLBAR, RESIZE_BOTTOM, 13, 496, 507, 14, 177, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST}, |
|
465 { WWT_RESIZEBOX, RESIZE_TB, 13, 496, 507, 178, 189, 0x0, STR_RESIZE_BUTTON}, |
|
466 { WIDGETS_END}, |
|
467 }; |
|
468 |
|
469 static uint _num_industry_sort; |
|
470 |
|
471 static char _bufcache[96]; |
|
472 static const Industry* _last_industry; |
|
473 |
|
474 static byte _industry_sort_order; |
|
475 |
|
476 static int CDECL GeneralIndustrySorter(const void *a, const void *b) |
|
477 { |
|
478 const Industry* i = *(const Industry**)a; |
|
479 const Industry* j = *(const Industry**)b; |
|
480 int r; |
|
481 |
|
482 switch (_industry_sort_order >> 1) { |
|
483 default: NOT_REACHED(); |
|
484 case 0: /* Sort by Name (handled later) */ |
|
485 r = 0; |
|
486 break; |
|
487 |
|
488 case 1: /* Sort by Type */ |
|
489 r = i->type - j->type; |
|
490 break; |
|
491 |
|
492 case 2: /* Sort by Production */ |
|
493 if (i->produced_cargo[0] == CT_INVALID) { |
|
494 r = (j->produced_cargo[0] == CT_INVALID ? 0 : -1); |
|
495 } else { |
|
496 if (j->produced_cargo[0] == CT_INVALID) { |
|
497 r = 1; |
|
498 } else { |
|
499 r = |
|
500 (i->total_production[0] + i->total_production[1]) - |
|
501 (j->total_production[0] + j->total_production[1]); |
|
502 } |
|
503 } |
|
504 break; |
|
505 |
|
506 case 3: /* Sort by transported fraction */ |
|
507 if (i->produced_cargo[0] == CT_INVALID) { |
|
508 r = (j->produced_cargo[0] == CT_INVALID ? 0 : -1); |
|
509 } else { |
|
510 if (j->produced_cargo[0] == CT_INVALID) { |
|
511 r = 1; |
|
512 } else { |
|
513 int pi; |
|
514 int pj; |
|
515 |
|
516 pi = i->pct_transported[0] * 100 >> 8; |
|
517 if (i->produced_cargo[1] != CT_INVALID) { |
|
518 int p = i->pct_transported[1] * 100 >> 8; |
|
519 if (p < pi) pi = p; |
|
520 } |
|
521 |
|
522 pj = j->pct_transported[0] * 100 >> 8; |
|
523 if (j->produced_cargo[1] != CT_INVALID) { |
|
524 int p = j->pct_transported[1] * 100 >> 8; |
|
525 if (p < pj) pj = p; |
|
526 } |
|
527 |
|
528 r = pi - pj; |
|
529 } |
|
530 } |
|
531 break; |
|
532 } |
|
533 |
|
534 // default to string sorting if they are otherwise equal |
|
535 if (r == 0) { |
|
536 char buf1[96]; |
|
537 |
|
538 SetDParam(0, i->town->index); |
|
539 GetString(buf1, STR_TOWN, lastof(buf1)); |
|
540 |
|
541 if (j != _last_industry) { |
|
542 _last_industry = j; |
|
543 SetDParam(0, j->town->index); |
|
544 GetString(_bufcache, STR_TOWN, lastof(_bufcache)); |
|
545 } |
|
546 r = strcmp(buf1, _bufcache); |
|
547 } |
|
548 |
|
549 if (_industry_sort_order & 1) r = -r; |
|
550 return r; |
|
551 } |
|
552 |
|
553 static void MakeSortedIndustryList(void) |
|
554 { |
|
555 const Industry* i; |
|
556 int n = 0; |
|
557 |
|
558 /* Don't attempt a sort if there are no industries */ |
|
559 if (GetNumIndustries() == 0) return; |
|
560 |
|
561 /* Create array for sorting */ |
|
562 _industry_sort = realloc((void *)_industry_sort, (GetMaxIndustryIndex() + 1) * sizeof(_industry_sort[0])); |
|
563 if (_industry_sort == NULL) error("Could not allocate memory for the industry-sorting-list"); |
|
564 |
|
565 FOR_ALL_INDUSTRIES(i) _industry_sort[n++] = i; |
|
566 |
|
567 _num_industry_sort = n; |
|
568 _last_industry = NULL; // used for "cache" |
|
569 |
|
570 qsort((void*)_industry_sort, n, sizeof(_industry_sort[0]), GeneralIndustrySorter); |
|
571 |
|
572 DEBUG(misc, 3, "Resorting industries list"); |
|
573 } |
|
574 |
|
575 |
|
576 static void IndustryDirectoryWndProc(Window *w, WindowEvent *e) |
|
577 { |
|
578 switch (e->event) { |
|
579 case WE_PAINT: { |
|
580 int n; |
|
581 uint p; |
|
582 static const uint16 _indicator_positions[4] = {88, 187, 284, 387}; |
|
583 |
|
584 if (_industry_sort_dirty) { |
|
585 _industry_sort_dirty = false; |
|
586 MakeSortedIndustryList(); |
|
587 } |
|
588 |
|
589 SetVScrollCount(w, _num_industry_sort); |
|
590 |
|
591 DrawWindowWidgets(w); |
|
592 DoDrawString(_industry_sort_order & 1 ? DOWNARROW : UPARROW, _indicator_positions[_industry_sort_order>>1], 15, 0x10); |
|
593 |
|
594 p = w->vscroll.pos; |
|
595 n = 0; |
|
596 |
|
597 while (p < _num_industry_sort) { |
|
598 const Industry* i = _industry_sort[p]; |
|
599 |
|
600 SetDParam(0, i->index); |
|
601 if (i->produced_cargo[0] != CT_INVALID) { |
|
602 SetDParam(1, i->produced_cargo[0]); |
|
603 SetDParam(2, i->total_production[0]); |
|
604 |
|
605 if (i->produced_cargo[1] != CT_INVALID) { |
|
606 SetDParam(3, i->produced_cargo[1]); |
|
607 SetDParam(4, i->total_production[1]); |
|
608 SetDParam(5, i->pct_transported[0] * 100 >> 8); |
|
609 SetDParam(6, i->pct_transported[1] * 100 >> 8); |
|
610 DrawString(4, 28+n*10, STR_INDUSTRYDIR_ITEM_TWO, 0); |
|
611 } else { |
|
612 SetDParam(3, i->pct_transported[0] * 100 >> 8); |
|
613 DrawString(4, 28+n*10, STR_INDUSTRYDIR_ITEM, 0); |
|
614 } |
|
615 } else { |
|
616 DrawString(4, 28+n*10, STR_INDUSTRYDIR_ITEM_NOPROD, 0); |
|
617 } |
|
618 p++; |
|
619 if (++n == w->vscroll.cap) break; |
|
620 } |
|
621 } break; |
|
622 |
|
623 case WE_CLICK: |
|
624 switch (e->we.click.widget) { |
|
625 case 3: { |
|
626 _industry_sort_order = _industry_sort_order==0 ? 1 : 0; |
|
627 _industry_sort_dirty = true; |
|
628 SetWindowDirty(w); |
|
629 } break; |
|
630 |
|
631 case 4: { |
|
632 _industry_sort_order = _industry_sort_order==2 ? 3 : 2; |
|
633 _industry_sort_dirty = true; |
|
634 SetWindowDirty(w); |
|
635 } break; |
|
636 |
|
637 case 5: { |
|
638 _industry_sort_order = _industry_sort_order==4 ? 5 : 4; |
|
639 _industry_sort_dirty = true; |
|
640 SetWindowDirty(w); |
|
641 } break; |
|
642 |
|
643 case 6: { |
|
644 _industry_sort_order = _industry_sort_order==6 ? 7 : 6; |
|
645 _industry_sort_dirty = true; |
|
646 SetWindowDirty(w); |
|
647 } break; |
|
648 |
|
649 case 8: { |
|
650 int y = (e->we.click.pt.y - 28) / 10; |
|
651 uint16 p; |
|
652 |
|
653 if (!IS_INT_INSIDE(y, 0, w->vscroll.cap)) return; |
|
654 p = y + w->vscroll.pos; |
|
655 if (p < _num_industry_sort) { |
|
656 ScrollMainWindowToTile(_industry_sort[p]->xy); |
|
657 } |
|
658 } break; |
|
659 } |
|
660 break; |
|
661 |
|
662 case WE_4: |
|
663 SetWindowDirty(w); |
|
664 break; |
|
665 |
|
666 case WE_RESIZE: |
|
667 w->vscroll.cap += e->we.sizing.diff.y / 10; |
|
668 break; |
|
669 } |
|
670 } |
|
671 |
|
672 |
|
673 /* Industry List */ |
|
674 static const WindowDesc _industry_directory_desc = { |
|
675 WDP_AUTO, WDP_AUTO, 508, 190, |
|
676 WC_INDUSTRY_DIRECTORY,0, |
|
677 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE, |
|
678 _industry_directory_widgets, |
|
679 IndustryDirectoryWndProc |
|
680 }; |
|
681 |
|
682 |
|
683 void ShowIndustryDirectory(void) |
|
684 { |
|
685 Window *w = AllocateWindowDescFront(&_industry_directory_desc, 0); |
|
686 |
|
687 if (w != NULL) { |
|
688 w->vscroll.cap = 16; |
|
689 w->resize.height = w->height - 6 * 10; // minimum 10 items |
|
690 w->resize.step_height = 10; |
|
691 SetWindowDirty(w); |
|
692 } |
|
693 } |