src/industry_gui.cpp
changeset 7776 aa072bd88690
parent 7775 982e208b42c3
child 7778 e8ccdf216de1
equal deleted inserted replaced
7775:982e208b42c3 7776:aa072bd88690
    56 	DYNA_INDU_INFOPANEL = 4,
    56 	DYNA_INDU_INFOPANEL = 4,
    57 	DYNA_INDU_FUND_WIDGET,
    57 	DYNA_INDU_FUND_WIDGET,
    58 	DYNA_INDU_RESIZE_WIDGET,
    58 	DYNA_INDU_RESIZE_WIDGET,
    59 };
    59 };
    60 
    60 
       
    61 /** Helper struct holding the available industries for current situation */
    61 static struct IndustryData {
    62 static struct IndustryData {
    62 	uint16 count;
    63 	uint16 count;                               ///< How many industries are loaded
    63 	IndustryType select;
    64 	IndustryType select;
    64 	byte index[NUM_INDUSTRYTYPES + 1];
    65 	byte index[NUM_INDUSTRYTYPES + 1];          ///< Type of industry, in the order it was loaded
    65 	StringID additional_text[NUM_INDUSTRYTYPES + 1];
    66 	StringID text[NUM_INDUSTRYTYPES + 1];       ///< Text coming from CBM_IND_FUND_MORE_TEXT (if ever)
    66 } _industrydata;
    67 } _fund_gui;
    67 
    68 
    68 static void BuildDynamicIndustryWndProc(Window *w, WindowEvent *e)
    69 static void BuildDynamicIndustryWndProc(Window *w, WindowEvent *e)
    69 {
    70 {
    70 	switch (e->event) {
    71 	switch (e->event) {
    71 		case WE_CREATE: {
    72 		case WE_CREATE: {
    83 				w->widget[DYNA_INDU_RESIZE_WIDGET].top -= 44;
    84 				w->widget[DYNA_INDU_RESIZE_WIDGET].top -= 44;
    84 				w->resize.height = w->height -= 44;
    85 				w->resize.height = w->height -= 44;
    85 			}
    86 			}
    86 
    87 
    87 			/* Initilialize structures */
    88 			/* Initilialize structures */
    88 			memset(&_industrydata.index, 0xFF, NUM_INDUSTRYTYPES);
    89 			memset(&_fund_gui.index, 0xFF, NUM_INDUSTRYTYPES);
    89 			memset(&_industrydata.additional_text, STR_NULL, NUM_INDUSTRYTYPES);
    90 			memset(&_fund_gui.text, STR_NULL, NUM_INDUSTRYTYPES);
    90 			_industrydata.count = 0;
    91 			_fund_gui.count = 0;
    91 
    92 
    92 			/* first indutry type is selected.
    93 			/* first indutry type is selected.
    93 			 * I'll be damned if there are none available ;) */
    94 			 * I'll be damned if there are none available ;) */
    94 			_industrydata.select = 0;
    95 			_fund_gui.select = 0;
    95 			w->vscroll.cap = 8; // rows in grid, same in scroller
    96 			w->vscroll.cap = 8; // rows in grid, same in scroller
    96 			w->resize.step_height = 13;
    97 			w->resize.step_height = 13;
    97 
    98 
    98 			if (_game_mode == GM_EDITOR) { // give room for the Many Random "button"
    99 			if (_game_mode == GM_EDITOR) { // give room for the Many Random "button"
    99 				_industrydata.index[_industrydata.count] = INVALID_INDUSTRYTYPE;
   100 				_fund_gui.index[_fund_gui.count] = INVALID_INDUSTRYTYPE;
   100 				_industrydata.count++;
   101 				_fund_gui.count++;
   101 			}
   102 			}
   102 
   103 
   103 			/* We'll perform two distinct loops, one for secondary industries, and the other one for
   104 			/* 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 			 * primary ones. Each loop will fill the _fund_gui structure. */
   105 			for (ind = IT_COAL_MINE; ind < NUM_INDUSTRYTYPES; ind++) {
   106 			for (ind = IT_COAL_MINE; ind < NUM_INDUSTRYTYPES; ind++) {
   106 				indsp = GetIndustrySpec(ind);
   107 				indsp = GetIndustrySpec(ind);
   107 				if (indsp->enabled && (!indsp->IsRawIndustry() || _game_mode == GM_EDITOR)) {
   108 				if (indsp->enabled && (!indsp->IsRawIndustry() || _game_mode == GM_EDITOR)) {
   108 					_industrydata.index[_industrydata.count] = ind;
   109 					_fund_gui.index[_fund_gui.count] = ind;
   109 					_industrydata.count++;
   110 					_fund_gui.count++;
   110 				}
   111 				}
   111 			}
   112 			}
   112 
   113 
   113 			if (_patches.raw_industry_construction != 0 && _game_mode != GM_EDITOR) {
   114 			if (_patches.raw_industry_construction != 0 && _game_mode != GM_EDITOR) {
   114 				for (ind = IT_COAL_MINE; ind < NUM_INDUSTRYTYPES; ind++) {
   115 				for (ind = IT_COAL_MINE; ind < NUM_INDUSTRYTYPES; ind++) {
   115 					indsp = GetIndustrySpec(ind);
   116 					indsp = GetIndustrySpec(ind);
   116 					if (indsp->enabled && indsp->IsRawIndustry()) {
   117 					if (indsp->enabled && indsp->IsRawIndustry()) {
   117 						_industrydata.index[_industrydata.count] = ind;
   118 						_fund_gui.index[_fund_gui.count] = ind;
   118 						_industrydata.count++;
   119 						_fund_gui.count++;
   119 					}
   120 					}
   120 				}
   121 				}
   121 			}
   122 			}
   122 		} break;
   123 		} break;
   123 
   124 
   124 		case WE_PAINT: {
   125 		case WE_PAINT: {
   125 			const IndustrySpec *indsp = (_industrydata.index[_industrydata.select] == INVALID_INDUSTRYTYPE) ? NULL : GetIndustrySpec(_industrydata.index[_industrydata.select]);
   126 			const IndustrySpec *indsp = (_fund_gui.index[_fund_gui.select] == INVALID_INDUSTRYTYPE) ? NULL : GetIndustrySpec(_fund_gui.index[_fund_gui.select]);
   126 			StringID str = STR_4827_REQUIRES;
   127 			StringID str = STR_4827_REQUIRES;
   127 			int x_str = w->widget[DYNA_INDU_INFOPANEL].left + 3;
   128 			int x_str = w->widget[DYNA_INDU_INFOPANEL].left + 3;
   128 			int y_str = w->widget[DYNA_INDU_INFOPANEL].top + 3;
   129 			int y_str = w->widget[DYNA_INDU_INFOPANEL].top + 3;
   129 			const Widget *wi = &w->widget[DYNA_INDU_INFOPANEL];
   130 			const Widget *wi = &w->widget[DYNA_INDU_INFOPANEL];
   130 			int max_width = wi->right - wi->left - 4;
   131 			int max_width = wi->right - wi->left - 4;
   131 
   132 
   132 			/* Raw industries might be prospected. Show this fact by changing the string */
   133 			/* Raw industries might be prospected. Show this fact by changing the string
       
   134 			 * In Editor, you just build, while ingame, or you fund or you prospect */
   133 			if (_game_mode == GM_EDITOR) {
   135 			if (_game_mode == GM_EDITOR) {
   134 				w->widget[DYNA_INDU_FUND_WIDGET].data = STR_BUILD_NEW_INDUSTRY;
   136 				w->widget[DYNA_INDU_FUND_WIDGET].data = STR_BUILD_NEW_INDUSTRY;
   135 			} else {
   137 			} else {
   136 				w->widget[DYNA_INDU_FUND_WIDGET].data = (_patches.raw_industry_construction == 2 && indsp->IsRawIndustry()) ? STR_PROSPECT_NEW_INDUSTRY : STR_FUND_NEW_INDUSTRY;
   138 				w->widget[DYNA_INDU_FUND_WIDGET].data = (_patches.raw_industry_construction == 2 && indsp->IsRawIndustry()) ? STR_PROSPECT_NEW_INDUSTRY : STR_FUND_NEW_INDUSTRY;
   137 			}
   139 			}
   138 
   140 
   139 			SetVScrollCount(w, _industrydata.count);
   141 			SetVScrollCount(w, _fund_gui.count);
   140 
   142 
   141 			DrawWindowWidgets(w);
   143 			DrawWindowWidgets(w);
   142 
   144 
   143 			/* and now with the matrix painting */
   145 			/* and now with the matrix painting */
   144 			for (byte i = 0; i < w->vscroll.cap && ((i + w->vscroll.pos) < _industrydata.count); i++) {
   146 			for (byte i = 0; i < w->vscroll.cap && ((i + w->vscroll.pos) < _fund_gui.count); i++) {
   145 				int offset = i * 13;
   147 				int offset = i * 13;
   146 				int x = 3;
   148 				int x = 3;
   147 				int y = 16;
   149 				int y = 16;
   148 				bool selected = _industrydata.select == i + w->vscroll.pos;
   150 				bool selected = _fund_gui.select == i + w->vscroll.pos;
   149 
   151 
   150 				if (_industrydata.index[i + w->vscroll.pos] == INVALID_INDUSTRYTYPE) {
   152 				if (_fund_gui.index[i + w->vscroll.pos] == INVALID_INDUSTRYTYPE) {
   151 					DrawString(21, y + offset, STR_MANY_RANDOM_INDUSTRIES, selected ? 12 : 6);
   153 					DrawString(21, y + offset, STR_MANY_RANDOM_INDUSTRIES, selected ? 12 : 6);
   152 					continue;
   154 					continue;
   153 				}
   155 				}
   154 				const IndustrySpec *indsp = GetIndustrySpec(_industrydata.index[i + w->vscroll.pos]);
   156 				const IndustrySpec *indsp = GetIndustrySpec(_fund_gui.index[i + w->vscroll.pos]);
   155 
   157 
   156 				/* Draw the name of the industry in white is selected, otherwise, in orange */
   158 				/* Draw the name of the industry in white is selected, otherwise, in orange */
   157 				DrawString(20,     y + offset, indsp->name, selected ? 12 : 6);
   159 				DrawString(20,     y + offset, indsp->name, selected ? 12 : 6);
   158 				GfxFillRect(x,     y + 1 + offset,  x + 10, y + 7 + offset, selected ? 15 : 0);
   160 				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);
   161 				GfxFillRect(x + 1, y + 2 + offset,  x +  9, y + 6 + offset, indsp->map_colour);
   160 			}
   162 			}
   161 
   163 
   162 			if (_industrydata.index[_industrydata.select] == INVALID_INDUSTRYTYPE) {
   164 			if (_fund_gui.index[_fund_gui.select] == INVALID_INDUSTRYTYPE) {
   163 				DrawStringMultiLine(x_str, y_str, STR_RANDOM_INDUSTRIES_TIP, max_width, wi->bottom - wi->top - 40);
   165 				DrawStringMultiLine(x_str, y_str, STR_RANDOM_INDUSTRIES_TIP, max_width, wi->bottom - wi->top - 40);
   164 				break;
   166 				break;
   165 			}
   167 			}
   166 
   168 
   167 			if (_game_mode != GM_EDITOR) {
   169 			if (_game_mode != GM_EDITOR) {
   199 				SetDParam(0, STR_00D0_NOTHING);
   201 				SetDParam(0, STR_00D0_NOTHING);
   200 			}
   202 			}
   201 			DrawStringTruncated(x_str, y_str, str, 0, max_width);
   203 			DrawStringTruncated(x_str, y_str, str, 0, max_width);
   202 
   204 
   203 			/* Get the additional purchase info text, if it has not already been */
   205 			/* 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?
   206 			if (_fund_gui.text[_fund_gui.select] == STR_NULL) {   // Have i been called already?
   205 				if (HASBIT(indsp->callback_flags, CBM_IND_FUND_MORE_TEXT)) {          // No. Can it be called?
   207 				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);
   208 					uint16 callback_res = GetIndustryCallback(CBID_INDUSTRY_FUND_MORE_TEXT, 0, 0, NULL, _fund_gui.index[_fund_gui.select], INVALID_TILE);
   207 					if (callback_res != CALLBACK_FAILED) {  // Did it failed?
   209 					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
   210 						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
   211 						_fund_gui.text[_fund_gui.select] = newtxt;   // Store it for further usage
   210 					}
   212 					}
   211 				}
   213 				}
   212 			}
   214 			}
   213 
   215 
   214 			y_str += 11;
   216 			y_str += 11;
   215 			/* Draw the Additional purchase text, provided by newgrf callback, if any.
   217 			/* Draw the Additional purchase text, provided by newgrf callback, if any.
   216 			 * Otherwhise, will print Nothing */
   218 			 * Otherwhise, will print Nothing */
   217 			if (_industrydata.additional_text[_industrydata.select] != STR_NULL &&
   219 			str = _fund_gui.text[_fund_gui.select];
   218 					_industrydata.additional_text[_industrydata.select] != STR_UNDEFINED) {
   220 			if (str != STR_NULL && str != STR_UNDEFINED) {
   219 
   221 				SetDParam(0, str);
   220 				SetDParam(0, _industrydata.additional_text[_industrydata.select]);
   222 				DrawStringMultiLine(x_str, y_str, STR_JUST_STRING, max_width, wi->bottom - wi->top - 40);
   221 				DrawStringMultiLine(x_str, y_str, STR_JUST_STRING, max_width, wi->bottom - wi->top - 40);  // text is white, for now
       
   222 			}
   223 			}
   223 		} break;
   224 		} break;
   224 
   225 
   225 		case WE_CLICK:
   226 		case WE_CLICK:
   226 			switch (e->we.click.widget) {
   227 			switch (e->we.click.widget) {
   227 				case DYNA_INDU_MATRIX_WIDGET: {
   228 				case DYNA_INDU_MATRIX_WIDGET: {
   228 					IndustryType type;
   229 					IndustryType type;
   229 					int y = (e->we.click.pt.y - w->widget[DYNA_INDU_MATRIX_WIDGET].top) / 13 + w->vscroll.pos ;
   230 					int y = (e->we.click.pt.y - w->widget[DYNA_INDU_MATRIX_WIDGET].top) / 13 + w->vscroll.pos ;
   230 
   231 
   231 					if (y >= 0 && y < _industrydata.count) { //Isit within the boundaries of available data?
   232 					if (y >= 0 && y < _fund_gui.count) { // Is it within the boundaries of available data?
   232 						_industrydata.select = y;
   233 						_fund_gui.select = y;
   233 						type = _industrydata.index[_industrydata.select];
   234 						type = _fund_gui.index[_fund_gui.select];
   234 
   235 
   235 						SetWindowDirty(w);
   236 						SetWindowDirty(w);
       
   237 
   236 						if ((_game_mode != GM_EDITOR && _patches.raw_industry_construction == 2 && GetIndustrySpec(type)->IsRawIndustry()) ||
   238 						if ((_game_mode != GM_EDITOR && _patches.raw_industry_construction == 2 && GetIndustrySpec(type)->IsRawIndustry()) ||
   237 								type == INVALID_INDUSTRYTYPE) {
   239 								type == INVALID_INDUSTRYTYPE) {
   238 							/* Reset the button state if going to prospecting or "build many industries" */
   240 							/* Reset the button state if going to prospecting or "build many industries" */
   239 							RaiseWindowButtons(w);
   241 							RaiseWindowButtons(w);
   240 							ResetObjectToPlace();
   242 							ResetObjectToPlace();
   241 						}
   243 						}
   242 					}
   244 					}
   243 				} break;
   245 				} break;
   244 
   246 
   245 				case DYNA_INDU_FUND_WIDGET: {
   247 				case DYNA_INDU_FUND_WIDGET: {
   246 					IndustryType type = _industrydata.index[_industrydata.select];
   248 					IndustryType type = _fund_gui.index[_fund_gui.select];
   247 
   249 
   248 					if (type == INVALID_INDUSTRYTYPE) {
   250 					if (type == INVALID_INDUSTRYTYPE) {
   249 						HandleButtonClick(w, DYNA_INDU_FUND_WIDGET);
   251 						HandleButtonClick(w, DYNA_INDU_FUND_WIDGET);
   250 						WP(w, def_d).data_1 = -1;
   252 						WP(w, def_d).data_1 = -1;
   251 
   253 
   260 					} else if (_game_mode != GM_EDITOR && _patches.raw_industry_construction == 2 && GetIndustrySpec(type)->IsRawIndustry()) {
   262 					} 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));
   263 						DoCommandP(0, type, 0, NULL, CMD_BUILD_INDUSTRY | CMD_MSG(STR_4830_CAN_T_CONSTRUCT_THIS_INDUSTRY));
   262 						HandleButtonClick(w, DYNA_INDU_FUND_WIDGET);
   264 						HandleButtonClick(w, DYNA_INDU_FUND_WIDGET);
   263 						WP(w, def_d).data_1 = -1;
   265 						WP(w, def_d).data_1 = -1;
   264 					} else if (HandlePlacePushButton(w, DYNA_INDU_FUND_WIDGET, SPR_CURSOR_INDUSTRY, 1, NULL)) {
   266 					} else if (HandlePlacePushButton(w, DYNA_INDU_FUND_WIDGET, SPR_CURSOR_INDUSTRY, 1, NULL)) {
   265 							WP(w, def_d).data_1 = _industrydata.select;
   267 							WP(w, def_d).data_1 = _fund_gui.select;
   266 					}
   268 					}
   267 				} break;
   269 				} break;
   268 			}
   270 			}
   269 			break;
   271 			break;
   270 
   272 
   271 		case WE_RESIZE: {
   273 		case WE_RESIZE: {
       
   274 			/* Adjust the number of items in the matrix depending of the rezise */
   272 			w->vscroll.cap  += e->we.sizing.diff.y / (int)w->resize.step_height;
   275 			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;
   276 			w->widget[DYNA_INDU_MATRIX_WIDGET].data = (w->vscroll.cap << 8) + 1;
   274 		} break;
   277 		} break;
   275 
   278 
   276 		case WE_PLACE_OBJ: {
   279 		case WE_PLACE_OBJ: {
   277 			IndustryType type = _industrydata.index[_industrydata.select];
   280 			/* We do not need to protect ourselves against "Random Many Industries" in this mode */
       
   281 			IndustryType type = _fund_gui.index[_fund_gui.select];
   278 
   282 
   279 			if (WP(w, def_d).data_1 == -1) break;
   283 			if (WP(w, def_d).data_1 == -1) break;
   280 			if (_game_mode == GM_EDITOR) {
   284 			if (_game_mode == GM_EDITOR) {
   281 				/* Show error if no town exists at all */
   285 				/* Show error if no town exists at all */
   282 				if (GetNumTowns() == 0) {
   286 				if (GetNumTowns() == 0) {