150 SetDParam(2, _patches.freight_trains); |
150 SetDParam(2, _patches.freight_trains); |
151 DrawString(x, y, FreightWagonMult(v->cargo_type) > 1 ? STR_CAPACITY_MULT : STR_013F_CAPACITY, 0); |
151 DrawString(x, y, FreightWagonMult(v->cargo_type) > 1 ? STR_CAPACITY_MULT : STR_013F_CAPACITY, 0); |
152 } |
152 } |
153 } |
153 } |
154 |
154 |
155 |
155 int GetTrainDetailsWndVScroll(VehicleID veh_id, byte det_tab) |
156 static void DrawTrainDetailsWindow(Window *w) |
156 { |
157 { |
|
158 byte det_tab = WP(w, traindetails_d).tab; |
|
159 const Vehicle *v; |
|
160 const Vehicle *u; |
|
161 AcceptedCargo act_cargo; |
157 AcceptedCargo act_cargo; |
162 AcceptedCargo max_cargo; |
158 AcceptedCargo max_cargo; |
163 int num; |
159 int num = 0; |
164 int x; |
160 |
165 int y; |
|
166 int sel; |
|
167 |
|
168 num = 0; |
|
169 u = v = GetVehicle(w->window_number); |
|
170 if (det_tab == 3) { // Total cargo tab |
161 if (det_tab == 3) { // Total cargo tab |
171 for (CargoID i = 0; i < lengthof(act_cargo); i++) { |
162 memset(max_cargo, 0, sizeof(max_cargo)); |
172 act_cargo[i] = 0; |
163 memset(act_cargo, 0, sizeof(act_cargo)); |
173 max_cargo[i] = 0; |
164 |
174 } |
165 for (const Vehicle *v = GetVehicle(veh_id) ; v != NULL ; v = v->Next()) { |
175 |
166 act_cargo[v->cargo_type] += v->cargo.Count(); |
176 do { |
167 max_cargo[v->cargo_type] += v->cargo_cap; |
177 act_cargo[u->cargo_type] += u->cargo.Count(); |
168 } |
178 max_cargo[u->cargo_type] += u->cargo_cap; |
|
179 } while ((u = u->Next()) != NULL); |
|
180 |
169 |
181 /* Set scroll-amount seperately from counting, as to not compute num double |
170 /* Set scroll-amount seperately from counting, as to not compute num double |
182 * for more carriages of the same type |
171 * for more carriages of the same type |
183 */ |
172 */ |
184 for (CargoID i = 0; i < NUM_CARGO; i++) { |
173 for (CargoID i = 0; i < NUM_CARGO; i++) { |
185 if (max_cargo[i] > 0) num++; // only count carriages that the train has |
174 if (max_cargo[i] > 0) num++; // only count carriages that the train has |
186 } |
175 } |
187 num++; // needs one more because first line is description string |
176 num++; // needs one more because first line is description string |
188 } else { |
177 } else { |
189 do { |
178 for (const Vehicle *v = GetVehicle(veh_id) ; v != NULL ; v = v->Next()) { |
190 if (!IsArticulatedPart(u) || u->cargo_cap != 0) num++; |
179 if (!IsArticulatedPart(v) || v->cargo_cap != 0) num++; |
191 } while ((u = u->Next()) != NULL); |
180 } |
192 } |
181 } |
193 |
182 |
194 SetVScrollCount(w, num); |
183 return num; |
195 |
184 } |
196 DisableWindowWidget(w, det_tab + 9); |
185 |
197 SetWindowWidgetDisabledState(w, 2, v->owner != _local_player); |
186 void DrawTrainDetails(const Vehicle *v, int x, int y, int vscroll_pos, uint16 vscroll_cap, byte det_tab) |
198 |
187 { |
199 /* disable service-scroller when interval is set to disabled */ |
|
200 SetWindowWidgetDisabledState(w, 6, !_patches.servint_trains); |
|
201 SetWindowWidgetDisabledState(w, 7, !_patches.servint_trains); |
|
202 |
|
203 SetDParam(0, v->index); |
|
204 DrawWindowWidgets(w); |
|
205 |
|
206 SetDParam(1, v->age / 366); |
|
207 |
|
208 x = 2; |
|
209 |
|
210 SetDParam(0, (v->age + 365 < v->max_age) ? STR_AGE : STR_AGE_RED); |
|
211 SetDParam(2, v->max_age / 366); |
|
212 SetDParam(3, v->GetDisplayRunningCost()); |
|
213 DrawString(x, 15, STR_885D_AGE_RUNNING_COST_YR, 0); |
|
214 |
|
215 SetDParam(2, v->GetDisplayMaxSpeed()); |
|
216 SetDParam(1, v->u.rail.cached_power); |
|
217 SetDParam(0, v->u.rail.cached_weight); |
|
218 SetDParam(3, v->u.rail.cached_max_te / 1000); |
|
219 DrawString(x, 25, (_patches.realistic_acceleration && v->u.rail.railtype != RAILTYPE_MAGLEV) ? |
|
220 STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE : |
|
221 STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED, 0); |
|
222 |
|
223 SetDParam(0, v->profit_this_year); |
|
224 SetDParam(1, v->profit_last_year); |
|
225 DrawString(x, 35, STR_885F_PROFIT_THIS_YEAR_LAST_YEAR, 0); |
|
226 |
|
227 SetDParam(0, 100 * (v->reliability>>8) >> 8); |
|
228 SetDParam(1, v->breakdowns_since_last_service); |
|
229 DrawString(x, 45, STR_8860_RELIABILITY_BREAKDOWNS, 0); |
|
230 |
|
231 SetDParam(0, v->service_interval); |
|
232 SetDParam(1, v->date_of_last_service); |
|
233 DrawString(x + 11, 57 + (w->vscroll.cap * 14), _patches.servint_ispercent ? STR_SERVICING_INTERVAL_PERCENT : STR_883C_SERVICING_INTERVAL_DAYS, 0); |
|
234 |
|
235 y = 57; |
|
236 sel = w->vscroll.pos; |
|
237 |
|
238 /* draw the first 3 details tabs */ |
188 /* draw the first 3 details tabs */ |
239 if (det_tab != 3) { |
189 if (det_tab != 3) { |
|
190 const Vehicle *u = v; |
240 x = 1; |
191 x = 1; |
241 for (;;) { |
192 for (;;) { |
242 if (--sel < 0 && sel >= -w->vscroll.cap) { |
193 if (--vscroll_pos < 0 && vscroll_pos >= -vscroll_cap) { |
243 int dx = 0; |
194 int dx = 0; |
244 int px; |
195 int px; |
245 int py; |
196 int py; |
246 |
197 |
247 u = v; |
198 u = v; |
275 } while (v != NULL && IsArticulatedPart(v) && v->cargo_cap == 0); |
226 } while (v != NULL && IsArticulatedPart(v) && v->cargo_cap == 0); |
276 } |
227 } |
277 if (v == NULL) return; |
228 if (v == NULL) return; |
278 } |
229 } |
279 } else { |
230 } else { |
|
231 AcceptedCargo act_cargo; |
|
232 AcceptedCargo max_cargo; |
|
233 |
|
234 memset(max_cargo, 0, sizeof(max_cargo)); |
|
235 memset(act_cargo, 0, sizeof(act_cargo)); |
|
236 |
|
237 for (const Vehicle *u = v; u != NULL ; u = u->Next()) { |
|
238 act_cargo[u->cargo_type] += u->cargo.Count(); |
|
239 max_cargo[u->cargo_type] += u->cargo_cap; |
|
240 } |
|
241 |
280 /* draw total cargo tab */ |
242 /* draw total cargo tab */ |
281 DrawString(x, y + 2, STR_013F_TOTAL_CAPACITY_TEXT, 0); |
243 DrawString(x, y + 2, STR_013F_TOTAL_CAPACITY_TEXT, 0); |
282 for (CargoID i = 0; i < NUM_CARGO; i++) { |
244 for (CargoID i = 0; i < NUM_CARGO; i++) { |
283 if (max_cargo[i] > 0 && --sel < 0 && sel > -w->vscroll.cap) { |
245 if (max_cargo[i] > 0 && --vscroll_pos < 0 && vscroll_pos > -vscroll_cap) { |
284 y += 14; |
246 y += 14; |
285 SetDParam(0, i); // {CARGO} #1 |
247 SetDParam(0, i); // {CARGO} #1 |
286 SetDParam(1, act_cargo[i]); // {CARGO} #2 |
248 SetDParam(1, act_cargo[i]); // {CARGO} #2 |
287 SetDParam(2, i); // {SHORTCARGO} #1 |
249 SetDParam(2, i); // {SHORTCARGO} #1 |
288 SetDParam(3, max_cargo[i]); // {SHORTCARGO} #2 |
250 SetDParam(3, max_cargo[i]); // {SHORTCARGO} #2 |
292 } |
254 } |
293 SetDParam(0, v->cargo.FeederShare()); |
255 SetDParam(0, v->cargo.FeederShare()); |
294 DrawString(x, y + 15, STR_FEEDER_CARGO_VALUE, 0); |
256 DrawString(x, y + 15, STR_FEEDER_CARGO_VALUE, 0); |
295 } |
257 } |
296 } |
258 } |
297 |
|
298 static void TrainDetailsWndProc(Window *w, WindowEvent *e) |
|
299 { |
|
300 switch (e->event) { |
|
301 case WE_PAINT: |
|
302 DrawTrainDetailsWindow(w); |
|
303 break; |
|
304 case WE_CLICK: { |
|
305 int mod; |
|
306 const Vehicle *v; |
|
307 switch (e->we.click.widget) { |
|
308 case 2: /* name train */ |
|
309 v = GetVehicle(w->window_number); |
|
310 SetDParam(0, v->index); |
|
311 ShowQueryString(STR_VEHICLE_NAME, STR_8865_NAME_TRAIN, 31, 150, w, CS_ALPHANUMERAL); |
|
312 break; |
|
313 case 6: /* inc serv interval */ |
|
314 mod = _ctrl_pressed? 5 : 10; |
|
315 goto do_change_service_int; |
|
316 |
|
317 case 7: /* dec serv interval */ |
|
318 mod = _ctrl_pressed? -5 : -10; |
|
319 do_change_service_int: |
|
320 v = GetVehicle(w->window_number); |
|
321 |
|
322 mod = GetServiceIntervalClamped(mod + v->service_interval); |
|
323 if (mod == v->service_interval) return; |
|
324 |
|
325 DoCommandP(v->tile, v->index, mod, NULL, CMD_CHANGE_SERVICE_INT | CMD_MSG(STR_018A_CAN_T_CHANGE_SERVICING)); |
|
326 break; |
|
327 /* details buttons*/ |
|
328 case 9: // Cargo |
|
329 case 10: // Information |
|
330 case 11: // Capacities |
|
331 case 12: // Total cargo |
|
332 EnableWindowWidget(w, 9); |
|
333 EnableWindowWidget(w, 10); |
|
334 EnableWindowWidget(w, 11); |
|
335 EnableWindowWidget(w, 12); |
|
336 EnableWindowWidget(w, e->we.click.widget); |
|
337 WP(w,traindetails_d).tab = e->we.click.widget - 9; |
|
338 SetWindowDirty(w); |
|
339 break; |
|
340 } |
|
341 } break; |
|
342 |
|
343 case WE_ON_EDIT_TEXT: |
|
344 if (e->we.edittext.str[0] != '\0') { |
|
345 _cmd_text = e->we.edittext.str; |
|
346 DoCommandP(0, w->window_number, 0, NULL, |
|
347 CMD_NAME_VEHICLE | CMD_MSG(STR_8866_CAN_T_NAME_TRAIN)); |
|
348 } |
|
349 break; |
|
350 |
|
351 case WE_RESIZE: |
|
352 if (e->we.sizing.diff.x != 0) ResizeButtons(w, 9, 12); |
|
353 if (e->we.sizing.diff.y == 0) break; |
|
354 |
|
355 w->vscroll.cap += e->we.sizing.diff.y / 14; |
|
356 w->widget[4].data = (w->vscroll.cap << 8) + 1; |
|
357 break; |
|
358 } |
|
359 } |
|
360 |
|
361 static const Widget _train_details_widgets[] = { |
|
362 { WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, |
|
363 { WWT_CAPTION, RESIZE_RIGHT, 14, 11, 329, 0, 13, STR_8802_DETAILS, STR_018C_WINDOW_TITLE_DRAG_THIS}, |
|
364 { WWT_PUSHTXTBTN, RESIZE_LR, 14, 330, 369, 0, 13, STR_01AA_NAME, STR_8867_NAME_TRAIN}, |
|
365 { WWT_PANEL, RESIZE_RIGHT, 14, 0, 369, 14, 55, 0x0, STR_NULL}, |
|
366 { WWT_MATRIX, RESIZE_RB, 14, 0, 357, 56, 139, 0x601, STR_NULL}, |
|
367 { WWT_SCROLLBAR, RESIZE_LRB, 14, 358, 369, 56, 139, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST}, |
|
368 { WWT_PUSHTXTBTN, RESIZE_TB, 14, 0, 10, 140, 145, STR_0188, STR_884D_INCREASE_SERVICING_INTERVAL}, |
|
369 { WWT_PUSHTXTBTN, RESIZE_TB, 14, 0, 10, 146, 151, STR_0189, STR_884E_DECREASE_SERVICING_INTERVAL}, |
|
370 { WWT_PANEL, RESIZE_RTB, 14, 11, 369, 140, 151, 0x0, STR_NULL}, |
|
371 { WWT_PUSHTXTBTN, RESIZE_TB, 14, 0, 89, 152, 163, STR_013C_CARGO, STR_884F_SHOW_DETAILS_OF_CARGO_CARRIED}, |
|
372 { WWT_PUSHTXTBTN, RESIZE_TB, 14, 90, 178, 152, 163, STR_013D_INFORMATION, STR_8850_SHOW_DETAILS_OF_TRAIN_VEHICLES}, |
|
373 { WWT_PUSHTXTBTN, RESIZE_TB, 14, 179, 268, 152, 163, STR_013E_CAPACITIES, STR_8851_SHOW_CAPACITIES_OF_EACH}, |
|
374 { WWT_PUSHTXTBTN, RESIZE_RTB, 14, 269, 357, 152, 163, STR_013E_TOTAL_CARGO, STR_8852_SHOW_TOTAL_CARGO}, |
|
375 { WWT_RESIZEBOX, RESIZE_LRTB, 14, 358, 369, 152, 163, 0x0, STR_RESIZE_BUTTON}, |
|
376 { WIDGETS_END}, |
|
377 }; |
|
378 |
|
379 |
|
380 static const WindowDesc _train_details_desc = { |
|
381 WDP_AUTO, WDP_AUTO, 370, 164, 370, 164, |
|
382 WC_VEHICLE_DETAILS,WC_VEHICLE_VIEW, |
|
383 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_RESIZABLE, |
|
384 _train_details_widgets, |
|
385 TrainDetailsWndProc |
|
386 }; |
|
387 |
|
388 |
|
389 void ShowTrainDetailsWindow(const Vehicle *v) |
|
390 { |
|
391 Window *w; |
|
392 VehicleID veh = v->index; |
|
393 |
|
394 DeleteWindowById(WC_VEHICLE_ORDERS, veh); |
|
395 DeleteWindowById(WC_VEHICLE_DETAILS, veh); |
|
396 |
|
397 w = AllocateWindowDescFront(&_train_details_desc, veh); |
|
398 |
|
399 w->caption_color = v->owner; |
|
400 w->vscroll.cap = 6; |
|
401 w->widget[4].data = (w->vscroll.cap << 8) + 1; |
|
402 |
|
403 w->resize.step_height = 14; |
|
404 w->resize.height = w->height - 14 * 2; /* Minimum of 4 wagons in the display */ |
|
405 |
|
406 WP(w,traindetails_d).tab = 0; |
|
407 } |
|