307 static void BuildRailClick_Landscaping(Window *w) |
307 static void BuildRailClick_Landscaping(Window *w) |
308 { |
308 { |
309 ShowTerraformToolbar(); |
309 ShowTerraformToolbar(); |
310 } |
310 } |
311 |
311 |
312 |
|
313 static void DoRailroadTrack(int mode) |
312 static void DoRailroadTrack(int mode) |
314 { |
313 { |
315 DoCommandP(TILE_FROM_XY(_thd.selstart.x, _thd.selstart.y), PACK_POINT(_thd.selend.x, _thd.selend.y), (mode << 4) | _cur_railtype, NULL, |
314 DoCommandP(TILE_FROM_XY(_thd.selstart.x, _thd.selstart.y), TILE_FROM_XY(_thd.selend.x, _thd.selend.y), _cur_railtype | (mode << 4), NULL, |
316 _remove_button_clicked ? |
315 _remove_button_clicked ? |
317 CMD_REMOVE_RAILROAD_TRACK | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1012_CAN_T_REMOVE_RAILROAD_TRACK) : |
316 CMD_REMOVE_RAILROAD_TRACK | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1012_CAN_T_REMOVE_RAILROAD_TRACK) : |
318 CMD_BUILD_RAILROAD_TRACK | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1011_CAN_T_BUILD_RAILROAD_TRACK) |
317 CMD_BUILD_RAILROAD_TRACK | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1011_CAN_T_BUILD_RAILROAD_TRACK) |
319 ); |
318 ); |
320 } |
319 } |
321 |
320 |
322 |
321 static void HandleAutodirPlacement(void) |
323 // This function is more or less a hack because DoRailroadTrack() would otherwise screw up |
|
324 static void SwapSelection(void) |
|
325 { |
322 { |
326 TileHighlightData *thd = &_thd; |
323 TileHighlightData *thd = &_thd; |
327 Point pt = thd->selstart; |
324 int trackstat = thd->drawstyle & 0xF; // 0..5 |
328 thd->selstart.x = thd->selend.x & ~0xF; |
325 |
329 thd->selstart.y = thd->selend.y & ~0xF; |
326 if (thd->drawstyle & HT_RAIL) { // one tile case |
330 thd->selend = pt; |
327 GenericPlaceRail(TILE_FROM_XY(thd->selend.x, thd->selend.y), trackstat); |
331 } |
328 return; |
332 |
329 } |
333 |
330 |
334 static void HandleAutodirPlacement(void) |
331 DoRailroadTrack(trackstat); |
|
332 } |
|
333 |
|
334 static void HandleAutoSignalPlacement(void) |
335 { |
335 { |
336 TileHighlightData *thd = &_thd; |
336 TileHighlightData *thd = &_thd; |
337 int bit; |
337 byte trackstat = thd->drawstyle & 0xF; // 0..5 |
338 int dx = thd->selstart.x - (thd->selend.x&~0xF); |
|
339 int dy = thd->selstart.y - (thd->selend.y&~0xF); |
|
340 |
|
341 if (thd->drawstyle & HT_RAIL) { // one tile case |
|
342 bit = thd->drawstyle & 0xF; |
|
343 GenericPlaceRail(TILE_FROM_XY(thd->selend.x, thd->selend.y), bit); |
|
344 } else if ( !(thd->drawstyle & 0xE) ) { // x/y dir |
|
345 if (dx == 0) { // Y dir |
|
346 DoRailroadTrack(1); |
|
347 } else { |
|
348 DoRailroadTrack(2); |
|
349 } |
|
350 } else if (myabs(dx)+myabs(dy) >= 32) { // long line (more than 2 tiles) |
|
351 if(thd->drawstyle == (HT_LINE | HT_DIR_HU)) |
|
352 DoRailroadTrack(0); |
|
353 if(thd->drawstyle == (HT_LINE | HT_DIR_HL)) |
|
354 DoRailroadTrack(3); |
|
355 if(thd->drawstyle == (HT_LINE | HT_DIR_VL)) |
|
356 DoRailroadTrack(3); |
|
357 if(thd->drawstyle == (HT_LINE | HT_DIR_VR)) |
|
358 DoRailroadTrack(0); |
|
359 } else { // 2x1 pieces line |
|
360 if(thd->drawstyle == (HT_LINE | HT_DIR_HU)) { |
|
361 DoRailroadTrack(0); |
|
362 } else if (thd->drawstyle == (HT_LINE | HT_DIR_HL)) { |
|
363 SwapSelection(); |
|
364 DoRailroadTrack(0); |
|
365 SwapSelection(); |
|
366 } else if (thd->drawstyle == (HT_LINE | HT_DIR_VL)) { |
|
367 if(dx == 0) { |
|
368 SwapSelection(); |
|
369 DoRailroadTrack(0); |
|
370 SwapSelection(); |
|
371 } else { |
|
372 DoRailroadTrack(3); |
|
373 } |
|
374 } else if (thd->drawstyle == (HT_LINE | HT_DIR_VR)) { |
|
375 if(dx == 0) { |
|
376 DoRailroadTrack(0); |
|
377 } else { |
|
378 SwapSelection(); |
|
379 DoRailroadTrack(3); |
|
380 SwapSelection(); |
|
381 } |
|
382 } |
|
383 } |
|
384 } |
|
385 |
|
386 static void HandleAutoSignalPlacement(void) |
|
387 { |
|
388 TileHighlightData *thd = &_thd; |
|
389 int mode = 0; |
|
390 uint trackstat = 0; |
|
391 |
|
392 int dx = thd->selstart.x - (thd->selend.x&~0xF); |
|
393 int dy = thd->selstart.y - (thd->selend.y&~0xF); |
|
394 |
338 |
395 if (thd->drawstyle == HT_RECT) { // one tile case |
339 if (thd->drawstyle == HT_RECT) { // one tile case |
396 GenericPlaceSignals(TILE_FROM_XY(thd->selend.x, thd->selend.y)); |
340 GenericPlaceSignals(TILE_FROM_XY(thd->selend.x, thd->selend.y)); |
397 return; |
341 return; |
398 } |
342 } |
399 |
343 |
400 if (!(thd->drawstyle & 0xE)) { // X/Y direction |
|
401 mode = (dx == 0) ? VPM_FIX_X : VPM_FIX_Y; |
|
402 trackstat = 0xC0; |
|
403 } else if (myabs(dx) + myabs(dy) >= 32) { // long line (more than 2 tiles) |
|
404 mode = ((thd->drawstyle & 0xF) == HT_DIR_HU || (thd->drawstyle & 0xF) == HT_DIR_VR) ? 0 : 3; |
|
405 |
|
406 if (dx == dy || abs(dx - dy) == 16) // North<->South track | |
|
407 trackstat = (thd->drawstyle & 1) ? 0x20 : 0x10; |
|
408 else if (dx == -dy || abs(dx + dy) == 16) // East<->West track -- |
|
409 trackstat = (thd->drawstyle & 1) ? 8 : 4; |
|
410 |
|
411 } else { // 2x1 pieces line |
|
412 GenericPlaceSignals(TILE_FROM_XY(thd->selstart.x, thd->selstart.y)); |
|
413 return; |
|
414 } |
|
415 |
|
416 // _patches.drag_signals_density is given as a parameter such that each user in a network |
344 // _patches.drag_signals_density is given as a parameter such that each user in a network |
417 // game can specify his/her own signal density |
345 // game can specify his/her own signal density |
418 DoCommandP(TILE_FROM_XY(thd->selstart.x, thd->selstart.y), TILE_FROM_XY(thd->selend.x, thd->selend.y), |
346 DoCommandP(TILE_FROM_XY(thd->selstart.x, thd->selstart.y), TILE_FROM_XY(thd->selend.x, thd->selend.y), |
419 (mode << 4) | (_remove_button_clicked | _ctrl_pressed) | (trackstat << 8) | (_patches.drag_signals_density << 24), |
347 (_ctrl_pressed ? 1 << 3 : 0) | (trackstat << 4) | (_patches.drag_signals_density << 24), |
420 CcPlaySound1E, |
348 CcPlaySound1E, |
421 (_remove_button_clicked ? CMD_BUILD_MANY_SIGNALS | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1013_CAN_T_REMOVE_SIGNALS_FROM) : |
349 (_remove_button_clicked ? CMD_REMOVE_SIGNAL_TRACK | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1013_CAN_T_REMOVE_SIGNALS_FROM) : |
422 CMD_BUILD_MANY_SIGNALS | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1010_CAN_T_BUILD_SIGNALS_HERE) ) ); |
350 CMD_BUILD_SIGNAL_TRACK | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1010_CAN_T_BUILD_SIGNALS_HERE) ) ); |
423 } |
351 } |
424 |
352 |
425 static OnButtonClick * const _build_railroad_button_proc[] = { |
353 static OnButtonClick * const _build_railroad_button_proc[] = { |
426 BuildRailClick_N, |
354 BuildRailClick_N, |
427 BuildRailClick_NE, |
355 BuildRailClick_NE, |
525 DoCommandP(end_tile, start_tile, _cur_railtype, CcPlaySound10, CMD_CONVERT_RAIL | CMD_MSG(STR_CANT_CONVERT_RAIL)); |
453 DoCommandP(end_tile, start_tile, _cur_railtype, CcPlaySound10, CMD_CONVERT_RAIL | CMD_MSG(STR_CANT_CONVERT_RAIL)); |
526 } else if (e->place.userdata == (VPM_X_AND_Y | (2<<4))) { |
454 } else if (e->place.userdata == (VPM_X_AND_Y | (2<<4))) { |
527 DoCommandP(end_tile, start_tile, _cur_railtype, CcPlaySound10, CMD_LEVEL_LAND | CMD_AUTO); |
455 DoCommandP(end_tile, start_tile, _cur_railtype, CcPlaySound10, CMD_LEVEL_LAND | CMD_AUTO); |
528 } else if (e->place.userdata == VPM_X_AND_Y_LIMITED) { |
456 } else if (e->place.userdata == VPM_X_AND_Y_LIMITED) { |
529 HandleStationPlacement(start_tile, end_tile); |
457 HandleStationPlacement(start_tile, end_tile); |
530 } else { |
458 } else |
531 DoRailroadTrack(e->place.userdata); |
459 DoRailroadTrack(e->place.userdata & 1); |
532 } |
|
533 } |
460 } |
534 break; |
461 break; |
535 |
462 |
536 case WE_ABORT_PLACE_OBJ: |
463 case WE_ABORT_PLACE_OBJ: |
537 UnclickWindowButtons(w); |
464 UnclickWindowButtons(w); |