23 #include "newgrf.h" |
23 #include "newgrf.h" |
24 #include "newgrf_callbacks.h" |
24 #include "newgrf_callbacks.h" |
25 #include "newgrf_industries.h" |
25 #include "newgrf_industries.h" |
26 #include "newgrf_text.h" |
26 #include "newgrf_text.h" |
27 |
27 |
28 /* industries per climate, according to the different construction windows */ |
28 extern Industry *CreateNewIndustry(TileIndex tile, IndustryType type); |
29 const byte _build_industry_types[4][12] = { |
29 |
30 { 1, 2, 4, 6, 8, 0, 3, 5, 9, 11, 18 }, |
30 /** |
31 { 1, 14, 4, 13, 7, 0, 3, 9, 11, 15 }, |
31 * Search callback function for TryBuildIndustry |
32 { 25, 13, 4, 23, 22, 11, 17, 10, 24, 19, 20, 21 }, |
32 * @param tile to test |
33 { 27, 30, 31, 33, 26, 28, 29, 32, 34, 35, 36 }, |
33 * @param data that is passed by the caller. In this case, the type of industry been tested |
|
34 * @return the success (or not) of the operation |
|
35 */ |
|
36 static bool SearchTileForIndustry(TileIndex tile, uint32 data) |
|
37 { |
|
38 return CreateNewIndustry(tile, data) != NULL; |
|
39 } |
|
40 |
|
41 /** |
|
42 * Perform a 9*9 tiles circular search around a tile |
|
43 * in order to find a suitable zone to create the desired industry |
|
44 * @param tile to start search for |
|
45 * @param type of the desired industry |
|
46 * @return the success (or not) of the operation |
|
47 */ |
|
48 static bool TryBuildIndustry(TileIndex tile, int type) |
|
49 { |
|
50 return CircularTileSearch(tile, 9, SearchTileForIndustry, type); |
|
51 } |
|
52 bool _ignore_restrictions; |
|
53 |
|
54 enum { |
|
55 DYNA_INDU_MATRIX_WIDGET = 2, |
|
56 DYNA_INDU_INFOPANEL = 4, |
|
57 DYNA_INDU_FUND_WIDGET, |
|
58 DYNA_INDU_RESIZE_WIDGET, |
34 }; |
59 }; |
35 |
60 |
36 static void UpdateIndustryProduction(Industry *i); |
61 static struct IndustryData { |
37 |
62 uint16 count; |
38 static void BuildIndustryWndProc(Window *w, WindowEvent *e) |
63 IndustryType select; |
|
64 byte index[NUM_INDUSTRYTYPES + 1]; |
|
65 StringID additional_text[NUM_INDUSTRYTYPES + 1]; |
|
66 } _industrydata; |
|
67 |
|
68 static void BuildDynamicIndustryWndProc(Window *w, WindowEvent *e) |
39 { |
69 { |
40 switch (e->event) { |
70 switch (e->event) { |
41 case WE_PAINT: |
71 case WE_CREATE: { |
42 DrawWindowWidgets(w); |
72 IndustryType ind; |
43 if (_thd.place_mode == 1 && _thd.window_class == WC_BUILD_INDUSTRY) { |
73 const IndustrySpec *indsp; |
44 int ind_type = _build_industry_types[_opt_ptr->landscape][WP(w, def_d).data_1]; |
74 |
45 |
75 /* Shorten the window to the equivalant of the additionnal purchase |
46 SetDParam(0, GetIndustrySpec(ind_type)->GetConstructionCost()); |
76 * info coming from the callback. SO it will only be available to tis full |
47 DrawStringCentered(85, w->height - 21, STR_482F_COST, 0); |
77 * height when newindistries are loaded */ |
48 } |
78 if (!_loaded_newgrf_features.has_newindustries) { |
49 break; |
79 w->widget[DYNA_INDU_INFOPANEL].bottom -= 44; |
50 |
80 w->widget[DYNA_INDU_FUND_WIDGET].bottom -= 44; |
51 case WE_CLICK: { |
81 w->widget[DYNA_INDU_FUND_WIDGET].top -= 44; |
52 int wid = e->we.click.widget; |
82 w->widget[DYNA_INDU_RESIZE_WIDGET].bottom -= 44; |
53 if (wid >= 3) { |
83 w->widget[DYNA_INDU_RESIZE_WIDGET].top -= 44; |
54 if (HandlePlacePushButton(w, wid, SPR_CURSOR_INDUSTRY, 1, NULL)) |
84 w->resize.height = w->height -= 44; |
55 WP(w, def_d).data_1 = wid - 3; |
85 } |
56 } |
86 |
|
87 /* Initilialize structures */ |
|
88 memset(&_industrydata.index, 0xFF, NUM_INDUSTRYTYPES); |
|
89 memset(&_industrydata.additional_text, STR_NULL, NUM_INDUSTRYTYPES); |
|
90 _industrydata.count = 0; |
|
91 |
|
92 /* first indutry type is selected. |
|
93 * I'll be damned if there are none available ;) */ |
|
94 _industrydata.select = 0; |
|
95 w->vscroll.cap = 8; // rows in grid, same in scroller |
|
96 w->resize.step_height = 13; |
|
97 |
|
98 if (_game_mode == GM_EDITOR) { // give room for the Many Random "button" |
|
99 _industrydata.index[_industrydata.count] = INVALID_INDUSTRYTYPE; |
|
100 _industrydata.count++; |
|
101 } |
|
102 |
|
103 /* We'll perform two distinct loops, one for secondary industries, and the other one for |
|
104 * primary ones. Each loop will fill the _industrydata structure. */ |
|
105 for (ind = IT_COAL_MINE; ind < NUM_INDUSTRYTYPES; ind++) { |
|
106 indsp = GetIndustrySpec(ind); |
|
107 if (indsp->enabled && (!indsp->IsRawIndustry() || _game_mode == GM_EDITOR)) { |
|
108 _industrydata.index[_industrydata.count] = ind; |
|
109 _industrydata.count++; |
|
110 } |
|
111 } |
|
112 |
|
113 if (_patches.raw_industry_construction != 0 && _game_mode != GM_EDITOR) { |
|
114 for (ind = IT_COAL_MINE; ind < NUM_INDUSTRYTYPES; ind++) { |
|
115 indsp = GetIndustrySpec(ind); |
|
116 if (indsp->enabled && indsp->IsRawIndustry()) { |
|
117 _industrydata.index[_industrydata.count] = ind; |
|
118 _industrydata.count++; |
|
119 } |
|
120 } |
|
121 } |
|
122 } break; |
|
123 |
|
124 case WE_PAINT: { |
|
125 const IndustrySpec *indsp = (_industrydata.index[_industrydata.select] == INVALID_INDUSTRYTYPE) ? NULL : GetIndustrySpec(_industrydata.index[_industrydata.select]); |
|
126 StringID str = STR_4827_REQUIRES; |
|
127 int x_str = w->widget[DYNA_INDU_INFOPANEL].left + 3; |
|
128 int y_str = w->widget[DYNA_INDU_INFOPANEL].top + 3; |
|
129 const Widget *wi = &w->widget[DYNA_INDU_INFOPANEL]; |
|
130 int max_width = wi->right - wi->left - 4; |
|
131 |
|
132 /* Raw industries might be prospected. Show this fact by changing the string */ |
|
133 if (_game_mode == GM_EDITOR) { |
|
134 w->widget[DYNA_INDU_FUND_WIDGET].data = STR_BUILD_NEW_INDUSTRY; |
|
135 } else { |
|
136 w->widget[DYNA_INDU_FUND_WIDGET].data = (_patches.raw_industry_construction == 2 && indsp->IsRawIndustry()) ? STR_PROSPECT_NEW_INDUSTRY : STR_FUND_NEW_INDUSTRY; |
|
137 } |
|
138 |
|
139 SetVScrollCount(w, _industrydata.count); |
|
140 |
|
141 DrawWindowWidgets(w); |
|
142 |
|
143 /* and now with the matrix painting */ |
|
144 for (byte i = 0; i < w->vscroll.cap && ((i + w->vscroll.pos) < _industrydata.count); i++) { |
|
145 int offset = i * 13; |
|
146 int x = 3; |
|
147 int y = 16; |
|
148 bool selected = _industrydata.select == i + w->vscroll.pos; |
|
149 |
|
150 if (_industrydata.index[i + w->vscroll.pos] == INVALID_INDUSTRYTYPE) { |
|
151 DrawString(21, y + offset, STR_MANY_RANDOM_INDUSTRIES, selected ? 12 : 6); |
|
152 continue; |
|
153 } |
|
154 const IndustrySpec *indsp = GetIndustrySpec(_industrydata.index[i + w->vscroll.pos]); |
|
155 |
|
156 /* Draw the name of the industry in white is selected, otherwise, in orange */ |
|
157 DrawString(20, y + offset, indsp->name, selected ? 12 : 6); |
|
158 GfxFillRect(x, y + 1 + offset, x + 10, y + 7 + offset, selected ? 15 : 0); |
|
159 GfxFillRect(x + 1, y + 2 + offset, x + 9, y + 6 + offset, indsp->map_colour); |
|
160 } |
|
161 |
|
162 if (_industrydata.index[_industrydata.select] == INVALID_INDUSTRYTYPE) { |
|
163 DrawStringMultiLine(x_str, y_str, STR_RANDOM_INDUSTRIES_TIP, max_width, wi->bottom - wi->top - 40); |
|
164 break; |
|
165 } |
|
166 |
|
167 if (_game_mode != GM_EDITOR) { |
|
168 SetDParam(0, indsp->GetConstructionCost()); |
|
169 DrawStringTruncated(x_str, y_str, STR_482F_COST, 0, max_width); |
|
170 y_str += 11; |
|
171 } |
|
172 |
|
173 /* Draw the accepted cargos, if any. Otherwhise, will print "Nothing" */ |
|
174 if (indsp->accepts_cargo[0] != CT_INVALID) { |
|
175 SetDParam(0, GetCargo(indsp->accepts_cargo[0])->name); |
|
176 if (indsp->accepts_cargo[1] != CT_INVALID) { |
|
177 SetDParam(1, GetCargo(indsp->accepts_cargo[1])->name); |
|
178 str = STR_4828_REQUIRES; |
|
179 if (indsp->accepts_cargo[2] != CT_INVALID) { |
|
180 SetDParam(2, GetCargo(indsp->accepts_cargo[2])->name); |
|
181 str = STR_4829_REQUIRES; |
|
182 } |
|
183 } |
|
184 } else { |
|
185 SetDParam(0, STR_00D0_NOTHING); |
|
186 } |
|
187 DrawStringTruncated(x_str, y_str, str, 0, max_width); |
|
188 |
|
189 y_str += 11; |
|
190 /* Draw the produced cargos, if any. Otherwhise, will print "Nothing" */ |
|
191 str = STR_4827_PRODUCES; |
|
192 if (indsp->produced_cargo[0] != CT_INVALID) { |
|
193 SetDParam(0, GetCargo(indsp->produced_cargo[0])->name); |
|
194 if (indsp->produced_cargo[1] != CT_INVALID) { |
|
195 SetDParam(1, GetCargo(indsp->produced_cargo[1])->name); |
|
196 str = STR_4828_PRODUCES; |
|
197 } |
|
198 } else { |
|
199 SetDParam(0, STR_00D0_NOTHING); |
|
200 } |
|
201 DrawStringTruncated(x_str, y_str, str, 0, max_width); |
|
202 |
|
203 /* Get the additional purchase info text, if it has not already been */ |
|
204 if (_industrydata.additional_text[_industrydata.select] == STR_NULL) { // Have i been called already? |
|
205 if (HASBIT(indsp->callback_flags, CBM_IND_FUND_MORE_TEXT)) { // No. Can it be called? |
|
206 uint16 callback_res = GetIndustryCallback(CBID_INDUSTRY_FUND_MORE_TEXT, 0, 0, NULL, _industrydata.index[_industrydata.select], INVALID_TILE); |
|
207 if (callback_res != CALLBACK_FAILED) { // Did it failed? |
|
208 StringID newtxt = GetGRFStringID(indsp->grf_prop.grffile->grfid, 0xD000 + callback_res); // No. here's the new string |
|
209 _industrydata.additional_text[_industrydata.select] = newtxt; // Store it for further usage |
|
210 } |
|
211 } |
|
212 } |
|
213 |
|
214 y_str += 11; |
|
215 /* Draw the Additional purchase text, provided by newgrf callback, if any. |
|
216 * Otherwhise, will print Nothing */ |
|
217 if (_industrydata.additional_text[_industrydata.select] != STR_NULL && |
|
218 _industrydata.additional_text[_industrydata.select] != STR_UNDEFINED) { |
|
219 |
|
220 SetDParam(0, _industrydata.additional_text[_industrydata.select]); |
|
221 DrawStringMultiLine(x_str, y_str, STR_JUST_STRING, max_width, wi->bottom - wi->top - 40); // text is white, for now |
|
222 } |
|
223 } break; |
|
224 |
|
225 case WE_CLICK: |
|
226 switch (e->we.click.widget) { |
|
227 case DYNA_INDU_MATRIX_WIDGET: { |
|
228 IndustryType type; |
|
229 int y = (e->we.click.pt.y - w->widget[DYNA_INDU_MATRIX_WIDGET].top) / 13 + w->vscroll.pos ; |
|
230 |
|
231 if (y >= 0 && y < _industrydata.count) { //Isit within the boundaries of available data? |
|
232 _industrydata.select = y; |
|
233 type = _industrydata.index[_industrydata.select]; |
|
234 |
|
235 SetWindowDirty(w); |
|
236 if ((_game_mode != GM_EDITOR && _patches.raw_industry_construction == 2 && GetIndustrySpec(type)->IsRawIndustry()) || |
|
237 type == INVALID_INDUSTRYTYPE) { |
|
238 /* Reset the button state if going to prospecting or "build many industries" */ |
|
239 RaiseWindowButtons(w); |
|
240 ResetObjectToPlace(); |
|
241 } |
|
242 } |
|
243 } break; |
|
244 |
|
245 case DYNA_INDU_FUND_WIDGET: { |
|
246 IndustryType type = _industrydata.index[_industrydata.select]; |
|
247 |
|
248 if (type == INVALID_INDUSTRYTYPE) { |
|
249 HandleButtonClick(w, DYNA_INDU_FUND_WIDGET); |
|
250 WP(w, def_d).data_1 = -1; |
|
251 |
|
252 if (GetNumTowns() == 0) { |
|
253 ShowErrorMessage(STR_0286_MUST_BUILD_TOWN_FIRST, STR_CAN_T_GENERATE_INDUSTRIES, 0, 0); |
|
254 } else { |
|
255 extern void GenerateIndustries(); |
|
256 _generating_world = true; |
|
257 GenerateIndustries(); |
|
258 _generating_world = false; |
|
259 } |
|
260 } else if (_game_mode != GM_EDITOR && _patches.raw_industry_construction == 2 && GetIndustrySpec(type)->IsRawIndustry()) { |
|
261 DoCommandP(0, type, 0, NULL, CMD_BUILD_INDUSTRY | CMD_MSG(STR_4830_CAN_T_CONSTRUCT_THIS_INDUSTRY)); |
|
262 HandleButtonClick(w, DYNA_INDU_FUND_WIDGET); |
|
263 WP(w, def_d).data_1 = -1; |
|
264 } else if (HandlePlacePushButton(w, DYNA_INDU_FUND_WIDGET, SPR_CURSOR_INDUSTRY, 1, NULL)) { |
|
265 WP(w, def_d).data_1 = _industrydata.select; |
|
266 } |
|
267 } |
|
268 break; |
57 } break; |
269 } break; |
58 |
270 |
59 case WE_PLACE_OBJ: |
271 case WE_RESIZE: { |
60 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))) |
272 w->vscroll.cap += e->we.sizing.diff.y / (int)w->resize.step_height; |
|
273 w->widget[DYNA_INDU_MATRIX_WIDGET].data = (w->vscroll.cap << 8) + 1; |
|
274 } break; |
|
275 |
|
276 case WE_PLACE_OBJ: { |
|
277 IndustryType type = _industrydata.index[_industrydata.select]; |
|
278 |
|
279 if (WP(w, def_d).data_1 == -1) break; |
|
280 if (_game_mode == GM_EDITOR) { |
|
281 /* Show error if no town exists at all */ |
|
282 if (GetNumTowns() == 0) { |
|
283 SetDParam(0, GetIndustrySpec(type)->name); |
|
284 ShowErrorMessage(STR_0286_MUST_BUILD_TOWN_FIRST, STR_0285_CAN_T_BUILD_HERE, e->we.place.pt.x, e->we.place.pt.y); |
|
285 return; |
|
286 } |
|
287 |
|
288 _current_player = OWNER_NONE; |
|
289 _generating_world = true; |
|
290 _ignore_restrictions = true; |
|
291 if (!TryBuildIndustry(e->we.place.tile, type)) { |
|
292 SetDParam(0, GetIndustrySpec(type)->name); |
|
293 ShowErrorMessage(_error_message, STR_0285_CAN_T_BUILD_HERE, e->we.place.pt.x, e->we.place.pt.y); |
|
294 } else { |
|
295 ResetObjectToPlace(); |
|
296 } |
|
297 _ignore_restrictions = false; |
|
298 _generating_world = false; |
|
299 } else if (DoCommandP(e->we.place.tile, type, 0, NULL, CMD_BUILD_INDUSTRY | CMD_MSG(STR_4830_CAN_T_CONSTRUCT_THIS_INDUSTRY))) { |
61 ResetObjectToPlace(); |
300 ResetObjectToPlace(); |
62 break; |
301 } |
|
302 } break; |
63 |
303 |
64 case WE_ABORT_PLACE_OBJ: |
304 case WE_ABORT_PLACE_OBJ: |
65 RaiseWindowButtons(w); |
305 RaiseWindowButtons(w); |
66 break; |
306 break; |
|
307 |
|
308 case WE_TIMEOUT: |
|
309 if (WP(w, def_d).data_1 == -1) { |
|
310 RaiseWindowButtons(w); |
|
311 WP(w, def_d).data_1 = 0; |
|
312 } |
|
313 break; |
67 } |
314 } |
68 } |
315 } |
69 |
316 |
70 static const Widget _build_industry_land0_widgets[] = { |
317 static const Widget _build_dynamic_industry_widgets[] = { |
71 { WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, |
318 { WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, |
72 { WWT_CAPTION, RESIZE_NONE, 7, 11, 169, 0, 13, STR_0314_FUND_NEW_INDUSTRY, STR_018C_WINDOW_TITLE_DRAG_THIS}, |
319 { WWT_CAPTION, RESIZE_RIGHT, 7, 11, 169, 0, 13, STR_0314_FUND_NEW_INDUSTRY, STR_018C_WINDOW_TITLE_DRAG_THIS}, |
73 { WWT_PANEL, RESIZE_NONE, 7, 0, 169, 14, 115, 0x0, STR_NULL}, |
320 { WWT_MATRIX, RESIZE_RB, 7, 0, 157, 14, 118, 0x801, STR_INDUSTRY_SELECTION_HINT}, |
74 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 16, 27, STR_0241_POWER_STATION, STR_0263_CONSTRUCT_POWER_STATION}, |
321 { WWT_SCROLLBAR, RESIZE_LRB, 7, 158, 169, 14, 118, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST}, |
75 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 29, 40, STR_0242_SAWMILL, STR_0264_CONSTRUCT_SAWMILL}, |
322 { WWT_PANEL, RESIZE_RTB, 7, 0, 169, 119, 199, 0x0, STR_NULL}, |
76 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 42, 53, STR_0244_OIL_REFINERY, STR_0266_CONSTRUCT_OIL_REFINERY}, |
323 { WWT_TEXTBTN, RESIZE_RTB, 7, 0, 157, 200, 211, STR_FUND_NEW_INDUSTRY, STR_NULL}, |
77 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 55, 66, STR_0246_FACTORY, STR_0268_CONSTRUCT_FACTORY}, |
324 { WWT_RESIZEBOX, RESIZE_LRTB, 7, 158, 169, 200, 211, 0x0, STR_RESIZE_BUTTON}, |
78 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 68, 79, STR_0247_STEEL_MILL, STR_0269_CONSTRUCT_STEEL_MILL}, |
|
79 { WIDGETS_END}, |
325 { WIDGETS_END}, |
80 }; |
326 }; |
81 |
327 |
82 static const Widget _build_industry_land1_widgets[] = { |
328 static const WindowDesc _build_industry_dynamic_desc = { |
83 { WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, |
329 WDP_AUTO, WDP_AUTO, 170, 212, |
84 { WWT_CAPTION, RESIZE_NONE, 7, 11, 169, 0, 13, STR_0314_FUND_NEW_INDUSTRY, STR_018C_WINDOW_TITLE_DRAG_THIS}, |
330 WC_BUILD_INDUSTRY, WC_NONE, |
85 { WWT_PANEL, RESIZE_NONE, 7, 0, 169, 14, 115, 0x0, STR_NULL}, |
331 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_RESIZABLE, |
86 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 16, 27, STR_0241_POWER_STATION, STR_0263_CONSTRUCT_POWER_STATION}, |
332 _build_dynamic_industry_widgets, |
87 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 29, 40, STR_024C_PAPER_MILL, STR_026E_CONSTRUCT_PAPER_MILL}, |
333 BuildDynamicIndustryWndProc, |
88 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 42, 53, STR_0244_OIL_REFINERY, STR_0266_CONSTRUCT_OIL_REFINERY}, |
|
89 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 55, 66, STR_024D_FOOD_PROCESSING_PLANT, STR_026F_CONSTRUCT_FOOD_PROCESSING}, |
|
90 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 68, 79, STR_024E_PRINTING_WORKS, STR_0270_CONSTRUCT_PRINTING_WORKS}, |
|
91 { WIDGETS_END}, |
|
92 }; |
334 }; |
93 |
335 |
94 static const Widget _build_industry_land2_widgets[] = { |
|
95 { WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, |
|
96 { WWT_CAPTION, RESIZE_NONE, 7, 11, 169, 0, 13, STR_0314_FUND_NEW_INDUSTRY, STR_018C_WINDOW_TITLE_DRAG_THIS}, |
|
97 { WWT_PANEL, RESIZE_NONE, 7, 0, 169, 14, 115, 0x0, STR_NULL}, |
|
98 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 16, 27, STR_0250_LUMBER_MILL, STR_0273_CONSTRUCT_LUMBER_MILL_TO}, |
|
99 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 29, 40, STR_024D_FOOD_PROCESSING_PLANT, STR_026F_CONSTRUCT_FOOD_PROCESSING}, |
|
100 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 42, 53, STR_0244_OIL_REFINERY, STR_0266_CONSTRUCT_OIL_REFINERY}, |
|
101 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 55, 66, STR_0246_FACTORY, STR_0268_CONSTRUCT_FACTORY}, |
|
102 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 68, 79, STR_0254_WATER_TOWER, STR_0277_CONSTRUCT_WATER_TOWER_CAN}, |
|
103 { WIDGETS_END}, |
|
104 }; |
|
105 |
|
106 static const Widget _build_industry_land3_widgets[] = { |
|
107 { WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, |
|
108 { WWT_CAPTION, RESIZE_NONE, 7, 11, 169, 0, 13, STR_0314_FUND_NEW_INDUSTRY, STR_018C_WINDOW_TITLE_DRAG_THIS}, |
|
109 { WWT_PANEL, RESIZE_NONE, 7, 0, 169, 14, 115, 0x0, STR_NULL}, |
|
110 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 16, 27, STR_0258_CANDY_FACTORY, STR_027B_CONSTRUCT_CANDY_FACTORY}, |
|
111 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 29, 40, STR_025B_TOY_SHOP, STR_027E_CONSTRUCT_TOY_SHOP}, |
|
112 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 42, 53, STR_025C_TOY_FACTORY, STR_027F_CONSTRUCT_TOY_FACTORY}, |
|
113 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 55, 66, STR_025E_FIZZY_DRINK_FACTORY, STR_0281_CONSTRUCT_FIZZY_DRINK_FACTORY}, |
|
114 { WIDGETS_END}, |
|
115 }; |
|
116 |
|
117 static const Widget _build_industry_land0_widgets_extra[] = { |
|
118 { WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, |
|
119 { WWT_CAPTION, RESIZE_NONE, 7, 11, 169, 0, 13, STR_0314_FUND_NEW_INDUSTRY, STR_018C_WINDOW_TITLE_DRAG_THIS}, |
|
120 { WWT_PANEL, RESIZE_NONE, 7, 0, 169, 14, 187, 0x0, STR_NULL}, |
|
121 |
|
122 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 16, 27, STR_0241_POWER_STATION, STR_0263_CONSTRUCT_POWER_STATION}, |
|
123 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 29, 40, STR_0242_SAWMILL, STR_0264_CONSTRUCT_SAWMILL}, |
|
124 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 42, 53, STR_0244_OIL_REFINERY, STR_0266_CONSTRUCT_OIL_REFINERY}, |
|
125 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 55, 66, STR_0246_FACTORY, STR_0268_CONSTRUCT_FACTORY}, |
|
126 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 68, 79, STR_0247_STEEL_MILL, STR_0269_CONSTRUCT_STEEL_MILL}, |
|
127 |
|
128 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 84, 95, STR_0240_COAL_MINE, STR_CONSTRUCT_COAL_MINE_TIP}, |
|
129 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 97, 108, STR_0243_FOREST, STR_CONSTRUCT_FOREST_TIP}, |
|
130 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 110, 121, STR_0245_OIL_RIG, STR_CONSTRUCT_OIL_RIG_TIP}, |
|
131 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 123, 134, STR_0248_FARM, STR_CONSTRUCT_FARM_TIP}, |
|
132 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 136, 147, STR_024A_OIL_WELLS, STR_CONSTRUCT_OIL_WELLS_TIP}, |
|
133 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 149, 160, STR_0249_IRON_ORE_MINE, STR_CONSTRUCT_IRON_ORE_MINE_TIP}, |
|
134 |
|
135 { WIDGETS_END}, |
|
136 }; |
|
137 |
|
138 static const Widget _build_industry_land1_widgets_extra[] = { |
|
139 { WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, |
|
140 { WWT_CAPTION, RESIZE_NONE, 7, 11, 169, 0, 13, STR_0314_FUND_NEW_INDUSTRY, STR_018C_WINDOW_TITLE_DRAG_THIS}, |
|
141 { WWT_PANEL, RESIZE_NONE, 7, 0, 169, 14, 174, 0x0, STR_NULL}, |
|
142 |
|
143 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 16, 27, STR_0241_POWER_STATION, STR_0263_CONSTRUCT_POWER_STATION}, |
|
144 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 29, 40, STR_024C_PAPER_MILL, STR_026E_CONSTRUCT_PAPER_MILL}, |
|
145 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 42, 53, STR_0244_OIL_REFINERY, STR_0266_CONSTRUCT_OIL_REFINERY}, |
|
146 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 55, 66, STR_024D_FOOD_PROCESSING_PLANT, STR_026F_CONSTRUCT_FOOD_PROCESSING}, |
|
147 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 68, 79, STR_024E_PRINTING_WORKS, STR_0270_CONSTRUCT_PRINTING_WORKS}, |
|
148 |
|
149 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 84, 95, STR_0240_COAL_MINE, STR_CONSTRUCT_COAL_MINE_TIP}, |
|
150 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 97, 108, STR_0243_FOREST, STR_CONSTRUCT_FOREST_TIP}, |
|
151 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 110, 121, STR_0248_FARM, STR_CONSTRUCT_FARM_TIP}, |
|
152 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 123, 134, STR_024A_OIL_WELLS, STR_CONSTRUCT_OIL_WELLS_TIP}, |
|
153 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 136, 147, STR_024F_GOLD_MINE, STR_CONSTRUCT_GOLD_MINE_TIP}, |
|
154 { WIDGETS_END}, |
|
155 }; |
|
156 |
|
157 static const Widget _build_industry_land2_widgets_extra[] = { |
|
158 { WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, |
|
159 { WWT_CAPTION, RESIZE_NONE, 7, 11, 169, 0, 13, STR_0314_FUND_NEW_INDUSTRY, STR_018C_WINDOW_TITLE_DRAG_THIS}, |
|
160 { WWT_PANEL, RESIZE_NONE, 7, 0, 169, 14, 200, 0x0, STR_NULL}, |
|
161 |
|
162 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 16, 27, STR_0250_LUMBER_MILL, STR_0273_CONSTRUCT_LUMBER_MILL_TO}, |
|
163 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 29, 40, STR_024D_FOOD_PROCESSING_PLANT, STR_026F_CONSTRUCT_FOOD_PROCESSING}, |
|
164 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 42, 53, STR_0244_OIL_REFINERY, STR_0266_CONSTRUCT_OIL_REFINERY}, |
|
165 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 55, 66, STR_0246_FACTORY, STR_0268_CONSTRUCT_FACTORY}, |
|
166 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 68, 79, STR_0254_WATER_TOWER, STR_0277_CONSTRUCT_WATER_TOWER_CAN}, |
|
167 |
|
168 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 84, 95, STR_024A_OIL_WELLS, STR_CONSTRUCT_OIL_WELLS_TIP}, |
|
169 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 97, 108, STR_0255_DIAMOND_MINE, STR_CONSTRUCT_DIAMOND_MINE_TIP}, |
|
170 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 110, 121, STR_0256_COPPER_ORE_MINE, STR_CONSTRUCT_COPPER_ORE_MINE_TIP}, |
|
171 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 123, 134, STR_0248_FARM, STR_CONSTRUCT_FARM_TIP}, |
|
172 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 136, 147, STR_0251_FRUIT_PLANTATION, STR_CONSTRUCT_FRUIT_PLANTATION_TIP}, |
|
173 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 149, 160, STR_0252_RUBBER_PLANTATION, STR_CONSTRUCT_RUBBER_PLANTATION_TIP}, |
|
174 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 162, 173, STR_0253_WATER_SUPPLY, STR_CONSTRUCT_WATER_SUPPLY_TIP}, |
|
175 { WIDGETS_END}, |
|
176 }; |
|
177 |
|
178 static const Widget _build_industry_land3_widgets_extra[] = { |
|
179 { WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, |
|
180 { WWT_CAPTION, RESIZE_NONE, 7, 11, 169, 0, 13, STR_0314_FUND_NEW_INDUSTRY, STR_018C_WINDOW_TITLE_DRAG_THIS}, |
|
181 { WWT_PANEL, RESIZE_NONE, 7, 0, 169, 14, 187, 0x0, STR_NULL}, |
|
182 |
|
183 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 16, 27, STR_0258_CANDY_FACTORY, STR_027B_CONSTRUCT_CANDY_FACTORY}, |
|
184 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 29, 40, STR_025B_TOY_SHOP, STR_027E_CONSTRUCT_TOY_SHOP}, |
|
185 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 42, 53, STR_025C_TOY_FACTORY, STR_027F_CONSTRUCT_TOY_FACTORY}, |
|
186 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 55, 66, STR_025E_FIZZY_DRINK_FACTORY, STR_0281_CONSTRUCT_FIZZY_DRINK_FACTORY}, |
|
187 |
|
188 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 71, 82, STR_0257_COTTON_CANDY_FOREST, STR_CONSTRUCT_COTTON_CANDY_TIP}, |
|
189 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 84, 95, STR_0259_BATTERY_FARM, STR_CONSTRUCT_BATTERY_FARM_TIP}, |
|
190 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 97, 108, STR_025A_COLA_WELLS, STR_CONSTRUCT_COLA_WELLS_TIP}, |
|
191 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 110, 121, STR_025D_PLASTIC_FOUNTAINS, STR_CONSTRUCT_PLASTIC_FOUNTAINS_TIP}, |
|
192 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 123, 134, STR_025F_BUBBLE_GENERATOR, STR_CONSTRUCT_BUBBLE_GENERATOR_TIP}, |
|
193 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 136, 147, STR_0260_TOFFEE_QUARRY, STR_CONSTRUCT_TOFFEE_QUARRY_TIP}, |
|
194 { WWT_TEXTBTN, RESIZE_NONE, 14, 2, 167, 149, 160, STR_0261_SUGAR_MINE, STR_CONSTRUCT_SUGAR_MINE_TIP}, |
|
195 { WIDGETS_END}, |
|
196 }; |
|
197 |
|
198 |
|
199 static const WindowDesc _build_industry_land0_desc = { |
|
200 WDP_AUTO, WDP_AUTO, 170, 116, |
|
201 WC_BUILD_INDUSTRY, WC_NONE, |
|
202 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET, |
|
203 _build_industry_land0_widgets, |
|
204 BuildIndustryWndProc |
|
205 }; |
|
206 |
|
207 static const WindowDesc _build_industry_land1_desc = { |
|
208 WDP_AUTO, WDP_AUTO, 170, 116, |
|
209 WC_BUILD_INDUSTRY, WC_NONE, |
|
210 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET, |
|
211 _build_industry_land1_widgets, |
|
212 BuildIndustryWndProc |
|
213 }; |
|
214 |
|
215 static const WindowDesc _build_industry_land2_desc = { |
|
216 WDP_AUTO, WDP_AUTO, 170, 116, |
|
217 WC_BUILD_INDUSTRY, WC_NONE, |
|
218 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET, |
|
219 _build_industry_land2_widgets, |
|
220 BuildIndustryWndProc |
|
221 }; |
|
222 |
|
223 static const WindowDesc _build_industry_land3_desc = { |
|
224 WDP_AUTO, WDP_AUTO, 170, 116, |
|
225 WC_BUILD_INDUSTRY, WC_NONE, |
|
226 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET, |
|
227 _build_industry_land3_widgets, |
|
228 BuildIndustryWndProc |
|
229 }; |
|
230 |
|
231 static const WindowDesc _build_industry_land0_desc_extra = { |
|
232 WDP_AUTO, WDP_AUTO, 170, 188, |
|
233 WC_BUILD_INDUSTRY, WC_NONE, |
|
234 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET, |
|
235 _build_industry_land0_widgets_extra, |
|
236 BuildIndustryWndProc |
|
237 }; |
|
238 |
|
239 static const WindowDesc _build_industry_land1_desc_extra = { |
|
240 WDP_AUTO, WDP_AUTO, 170, 175, |
|
241 WC_BUILD_INDUSTRY, WC_NONE, |
|
242 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET, |
|
243 _build_industry_land1_widgets_extra, |
|
244 BuildIndustryWndProc |
|
245 }; |
|
246 |
|
247 static const WindowDesc _build_industry_land2_desc_extra = { |
|
248 WDP_AUTO, WDP_AUTO, 170, 201, |
|
249 WC_BUILD_INDUSTRY, WC_NONE, |
|
250 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET, |
|
251 _build_industry_land2_widgets_extra, |
|
252 BuildIndustryWndProc |
|
253 }; |
|
254 |
|
255 static const WindowDesc _build_industry_land3_desc_extra = { |
|
256 WDP_AUTO, WDP_AUTO, 170, 188, |
|
257 WC_BUILD_INDUSTRY, WC_NONE, |
|
258 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET, |
|
259 _build_industry_land3_widgets_extra, |
|
260 BuildIndustryWndProc |
|
261 }; |
|
262 |
|
263 static const WindowDesc * const _industry_window_desc[2][4] = { |
|
264 { |
|
265 &_build_industry_land0_desc, |
|
266 &_build_industry_land1_desc, |
|
267 &_build_industry_land2_desc, |
|
268 &_build_industry_land3_desc, |
|
269 }, |
|
270 { |
|
271 &_build_industry_land0_desc_extra, |
|
272 &_build_industry_land1_desc_extra, |
|
273 &_build_industry_land2_desc_extra, |
|
274 &_build_industry_land3_desc_extra, |
|
275 }, |
|
276 }; |
|
277 |
|
278 void ShowBuildIndustryWindow() |
336 void ShowBuildIndustryWindow() |
279 { |
337 { |
280 if (!IsValidPlayer(_current_player)) return; |
338 if (_game_mode != GM_EDITOR && !IsValidPlayer(_current_player)) return; |
281 AllocateWindowDescFront(_industry_window_desc[(_patches.raw_industry_construction == 0) ? 0 : 1][_opt_ptr->landscape], 0); |
339 AllocateWindowDescFront(&_build_industry_dynamic_desc, 0); |
282 } |
340 } |
|
341 |
|
342 static void UpdateIndustryProduction(Industry *i); |
283 |
343 |
284 static inline bool isProductionMinimum(const Industry *i, int pt) { |
344 static inline bool isProductionMinimum(const Industry *i, int pt) { |
285 return i->production_rate[pt] == 1; |
345 return i->production_rate[pt] == 1; |
286 } |
346 } |
287 |
347 |