Only in cmclient/bin/ai/regression: regression.nut
Only in cmclient/bin/ai/regression: regression.sav
Only in cmclient/bin/ai/regression: regression.txt
Only in cmclient/bin/ai/regression: require.nut
Only in cmclient/bin: data
Only in cmclient/bin/scripts: autoexec.scr
Only in cmclient/bin/scripts: on_client.scr
diff -r -B -X .diff-exclude vanilla/.changelog cmclient/.changelog
1c1
< 1.10.1 (2020-04-13)
---
> 1.10.0 (2020-04-01)
3,7c3,137
< Fix #8081: Crash when placing a ship depot next to a dock (#8082)
< Fix: [GS] A Goal's QuestionID was getting truncated (#8072)
< Fix #8064: Refit capacity could be displayed incorrectly in extreme edgecases (#8065)
< Fix #8060: Restore admin network API compatibility (#8061)
< Fix #8055: Crash when roadtype availability changes with the road construction toolbar open (#8058)
---
> Change: Open company window when clicking on a company goal (#8033)
> Change: [SDL2] Support pasting from clipboard on Linux (#8004)
> Fix: [Script] Random deviation upper bound range should be inclusive (#8052)
> Fix #8043: Incorrect handling of global road/tram hotkeys caused a crash (#8044)
> Fix #8039: [Script] SetOrderFlags and GetOrderDestination didn't work for oil rigs (#8040)
> Fix: [Script] CanBuildConnectedRoadPartsHere neighbours tiles were incorrect if you started a new game with a different world size (#8036)
> Fix: Ignore clicks on non-applicable global goals (#8035)
> Fix #7613: Limit News Window to 1024 messages to keep it usable and avoid overflowing scrollbars (#8026)
> Fix #7644: [OSX] Hopefully improve performance by manually set colorspace to sRGB (#8023)
> Fix #8020: Add missing docking tiles around industry neutral stations (#8021)
> Fix: GUI tramway icon only contained a single set of tram tracks (#8015)
> Fix: Station with multiple docks had the wrong tile area (#8014)
> Fix #8011: Crash when loading TTD scenario containing a dock (#8012)
> Fix #7998: Crash when scripts tried to access companies with invalid IDs (#8010)
> Fix: Crash when attempting to draw a string containing nonprintable characters (#8005)
> Fix #6399: Directory ~/.local/share not created if it didn't already exist (#8003)
> Fix #7958: Custom catenary missing on road bridges (#7991)
> Fix #7944: Demolishing locks built on rivers didn't always restore the river (#7946)
>
>
> 1.10.0-RC1 (2020-02-09)
> ------------------------------------------------------------------------
> Feature: Allow server to supply a reason to kicked/banned clients (#7859)
> Feature: [NewGRF] Station variable 6A, querying GRFID of nearby station tiles (#7956)
> Feature: Improved logic of sharing industry production between 3 or more stations (#7922)
> Feature: Highlight the item under mouse cursor in file browser (#7900)
> Feature: [GS] Methods to change town rating of companies (#7898)
> Feature: [NewGRF] Callback profiling command (#7868)
> Feature: Add a setting to show the name of the NewGRF of a vehicle in the build window (#7852)
> Feature: Ability to filter industry directory window by cargo (#7843)
> Feature: Minimap screenshot type (#7817)
> Feature: [GS] Methods to control engine availability of a specific company (#7791)
> Feature: Configurable game ending year (#7747)
> Feature: Separate window for taking screenshots (#7550)
> Change: Move autorenew setting to basic category (#7984)
> Change: Improved algorithm for transfer feeder payments (#7935)
> Change: Show volume sliders with wedges instead of boxy slider (#7902)
> Change: Auto-restart loads the original resources (e.g. save or scenario) again (#7688)
> Change: Improve readability of integer lists saved to config files (#7396)
> Fix #7976: Crash when attempting to kick the host via rcon (#7985)
> Fix #7592: Road vehicles no longer balanced between multiple road stop stations (#7979)
> Fix: Station rating effects affecting too large area (#7977)
> Fix #7974: Crash when Ctrl+click to show a collapsed vehicle group (#7975)
> Fix #7969: Crash when executing a recursive console alias (#7973)
> Fix #6566: Very long loading of the maximum "zoom out" level at high resolutions (#7968)
> Fix #7952: Crash when switching input languages (#7953)
> Fix: [OSX] Don't show a crash/assertion message box for a GUI-less video driver (#7934)
> Fix #7925: Corrupt savegames could lead to corruption of the titlegame (#7932)
> Fix: [Fluidsynth] Music notes from previous song were not properly reset (#7930)
> Fix: Invalid string usage within music window (#7928)
> Fix: Non-deterministic name sorting in industry directory window (#7915)
> Fix #7899: Various issues with town list window sorting (#7906, #7916)
> Fix #7587: Fix possible crashes when loading old save games with invalid waypoint positions (#7894)
> Fix: Avoid a crash by properly resetting timetable duration when loading old savegames (#7894)
> Fix: Possible crash when post road-works cleanup removes all road pieces (#7903)
> Fix #7891: Fix crash when loading save from 1.7.2 (#7892)
> Fix #7887: Missing sound effects for some main toolbar buttons (#7888)
> Fix #6667: Avoid confusion by also recalculating bridge costs for 'spectated' AI companies (#7884)
> Fix: Allow old NewGRF industries to hide in/out cargo slots (#7882)
> Fix: [Windows] Fix bootstrap GUI with Uniscribe but no Freetype (#7878)
> Fix: Missing keycodes for hotkeys.cfg (#7850)
> Fix #7625: Ensure road infrastructure cost is correctly updated when upgrading your own roads (#7628)
> Fix #7088: Avoid crash by closing AI/GS textfile windows when changing their in-game slot (#7094)
>
>
> 1.10.0-beta2 (2019-12-25)
> ------------------------------------------------------------------------
> - Feature: [Script] More error mappings (#7857)
> - Feature: Ctrl+Click on a vehicle in the vehicle group window selects and scrolls to the vehicle's group (#7800)
> - Feature: Ctrl+Click on the vehicle details button in the vehicle view window opens the vehicle group window focused on the vehicle (#7800)
> - Feature: Add a button to the vehicle advisory news window to open the vehicle's group window (#7800)
> - Feature: Ctrl+Click on a vehicle in the vehicle list window opens the vehicle group window focused on the vehicle's group (#7800)
> - Fix: Custom sea level default value is now equal to minimum value (#7866)
> - Fix: [NewGRF] Various tracktype fixes (#7863)
> - Fix: Infrastructure total update when removing tram road stop (#7856)
> - Fix #7847: Use ViewportSign coordinates for sign Kdtree coordinates (#7849)
> - Fix #7836: Check coherency of NewGRF parameter min/max (#7840)
> - Fix #7673: [Script] Allow removal of custom town text (#7834)
> - Fix: Crash when displaying an error message at map edges (#7833)
> - Fix #7783, #7816: [SDL2] Fix input handling in edit context (#7825)
> - Fix #7697: Tile query on HQs did not display cargo correctly (#7824)
> - Fix #7820: Possible game crash when removing oil rig (#7821)
> - Fix #7606: Rare crash when trying to clean up a crashed script (#7819)
> - Fix #7784: [SDL2] up/down/home/end key behaviour (#7815)
> - Fix #7631: 16 out cargo support for industry directory (#7809)
> - Fix #7646: Crash on random map generation failure (#7805)
> - Fix #7430: Only reset time since pickup when train visits station if it has room to load (#7595)
> - Fix #5405: Aircraft could route to depots outside their range (#7104)
>
>
> 1.10.0-beta1 (2019-10-29)
> ------------------------------------------------------------------------
> - Feature: Configurable minimum age for companies before allowing share trading (#7780)
> - Feature: Filter on town list window (#7621)
> - Feature: Ability to show Newspaper and Ticker messages in parallel (#7612)
> - Feature: Show coverage area for stations and towns (#7446)
> - Feature: Collapsible vehicle groups (#7417)
> - Feature: More flexible docks - can now have multiple per station, ships can use any part of dock (#7380)
> - Feature: [NewGRF] Railtype flags to allow/disallow 90 degree curves (#7352)
> - Feature/Change: Non-rectangular catchment area for sparse stations (#7235)
> - Feature: Improved performance for road vehicle pathfinding (#7261)
> - Feature: Option to show local authority boundary of towns (#7025)
> - Feature: Experimental method of town cargo generation that scales linearly with population (#6965)
> - Feature: [NewGRF] RoadTypes (NRT) (#6811)
> - Add: [Win32] Select MIDI device by port name (#7666)
> - Add: 'getsysdate' console command (#7658)
> - Add: Currencies NTD, CNY, HKD (#7596)
> - Add: Icons to vehicle construction drop down lists (#7358, #7485)
> - Add: Security warning to players that company passwords are not truly secure (#7351)
> - Add: [Script] Various API functions for managing vehicle groups (#7225, #7336, #7716)
> - Add: SDL2 video driver (#7086)
> - Change: Inactive industries do not make sound effects (#7752)
> - Change: [Win32] Use native GDI engine for rendering fonts (#7572)
> - Change: Scale oil refinery edge distance limit by map size (#7514)
> - Change: Do not display a news message about old vehicles when a replacement for it is activated (#7401)
> - Change: When filtering purchase list by cargo type, buy button now performs a refit if required (#7301)
> - Change: Don't apply forbid 90 deg turn settings to ships, and make penalties for turns configurable (#7289, #7372)
> - Change: Make the chance of an aeroplane crashing at an airport with a short runway independent of plane crash setting (#7302)
> - Change: Keep town growth rate in sync with house count (#6777)
> - Fix #6219: Improve helicopter's ability to takeoff from commuter and international airports (#7710)
> - Fix #6407: Show snowy ground sprites for train depots (#7671)
> - Fix: Power/running cost sorting algorithm was not correct when power was higher than running cost (#7561)
> - Fix: Tweaks to small-map colours to make dark blue company more visible (#7436, #7450)
> - Fix: [SDL] Do not offer video smaller than 640x480 (#7442)
> - Fix: Incorrect display of industry production around tiles (#7426)
> - Fix: Show industry name in Land Area Information window for industries with neutral stations instead of just 'Oil Rig' (#7349)
> - Fix: Remove redundant and broken file lookups when loading base sets (#7348)
> - Fix: Always report error when ordering a road vehicle to wrong type of road stop (#7316)
> - Fix #7043, #7274: Improve performance when creating towns during world creation (#7284)
> - Fix #7062: Remove ship max order distance (#7279)
> - Fix #7189: Fluidsynth volume gain too high (#7253)
> - Fix: Add setting for whether industries with neutral stations (e.g. Oil rigs) accept and supply cargo to/from surrounding stations to fix exploit as old as TTO (#7234)
> - Fix: Properly reset dropdown menu windows after changing AI/GS settings (#7092)
> - Remove: DOS, MorphOS, AmigaOS & BeOS support (#7326, #7388)
> - Remove: Original Path Finder (#7245)
Only in cmclient: .clang-format
Only in cmclient: cm_changelog.txt
Only in cmclient: cmclient.sublime-project
Only in cmclient: .diff-exclude
Only in cmclient/docs: Readme_Windows_MSVC.txt
Only in cmclient: gen_newgrf_revisions.py
diff -r -B -X .diff-exclude vanilla/Makefile.bundle.in cmclient/Makefile.bundle.in
26a27
> DATA_DIR = $(BUNDLE_DIR)/$(OSXAPP)/Contents/Resources/data
32a34
> DATA_DIR = $(BUNDLE_DIR)/data
47a50
> $(Q)mkdir -p "$(DATA_DIR)"
62a66
> $(Q)cp "$(BIN_DIR)/data/"*.grf "$(DATA_DIR)/"
diff -r -B -X .diff-exclude vanilla/.ottdrev cmclient/.ottdrev
1c1
< 1.10.1 20200413 0 7f77b8c1e27f3d102b1f665d2a3c500598245c3b 1 1
---
> 1.10.0-RC1 20200209 0 49d2a07f667b8e9a8d984b35b2a41302c70c3c1e 1 0
Only in cmclient/projects: Debug
Only in cmclient/projects: generate_vs100.vcxproj
Only in cmclient/projects: generate_vs80.vcproj
Only in cmclient/projects: generate_vs90.vcproj
Only in cmclient/projects: langs_vs100.vcxproj
Only in cmclient/projects: langs_vs100.vcxproj.filters
Only in cmclient/projects: langs_vs100.vcxproj.filters.in
Only in cmclient/projects: langs_vs100.vcxproj.in
Only in cmclient/projects: langs_vs80.vcproj
Only in cmclient/projects: langs_vs80.vcproj.in
Only in cmclient/projects: langs_vs90.vcproj
Only in cmclient/projects: langs_vs90.vcproj.in
Only in cmclient/projects: openttd_vs100.sln
Only in cmclient/projects: openttd_vs100.v11.suo
Only in cmclient/projects: openttd_vs100.vcxproj
Only in cmclient/projects: openttd_vs100.vcxproj.filters
Only in cmclient/projects: openttd_vs100.vcxproj.filters.in
Only in cmclient/projects: openttd_vs100.vcxproj.in
Only in cmclient/projects: openttd_vs100.vcxproj.my
Only in cmclient/projects: openttd_vs100.vcxproj.user
diff -r -B -X .diff-exclude vanilla/projects/openttd_vs140.vcxproj cmclient/projects/openttd_vs140.vcxproj
451a452
>
454a456
>
709a712
>
721a725
>
757a762
>
758a764
>
807a814
>
809a817
>
815a824
>
894a904,912
>
>
>
>
>
>
>
>
>
901a920,921
>
>
1215a1236
>
diff -r -B -X .diff-exclude vanilla/projects/openttd_vs140.vcxproj.filters cmclient/projects/openttd_vs140.vcxproj.filters
22c22
<
---
>
25c25
<
---
>
28c28
<
---
>
31c31
<
---
>
34c34
<
---
>
37c37
<
---
>
40c40
<
---
>
43c43
<
---
>
46c46
<
---
>
49c49
<
---
>
52c52
<
---
>
55c55
<
---
>
58c58
<
---
>
61c61
<
---
>
64c64
<
---
>
67c67
<
---
>
70c70
<
---
>
73c73
<
---
>
76c76
<
---
>
79c79
<
---
>
82c82
<
---
>
85c85
<
---
>
88c88
<
---
>
91c91
<
---
>
94c94
<
---
>
97c97
<
---
>
100c100
<
---
>
102a103,105
>
> {c76ff9f1-1e62-46d8-8d55-000000000033}
>
437a441,443
>
> Header Files
>
446a453,455
>
> Header Files
>
1211a1221,1223
>
> Header Files
>
1247a1260,1262
>
> Header Files
>
1355a1371,1373
>
> GUI Source Code
>
1358a1377,1379
>
> GUI Source Code
>
1505a1527,1529
>
> GUI Source Code
>
1511a1536,1538
>
> GUI Source Code
>
1529a1557,1559
>
> Widgets
>
1766a1797,1823
>
> Command handlers
>
>
> CityMania files
>
>
> CityMania files
>
>
> CityMania files
>
>
> CityMania files
>
>
> CityMania files
>
>
> CityMania files
>
>
> CityMania files
>
>
> CityMania files
>
1787a1845,1850
>
> Save/Load handlers
>
>
> Save/Load handlers
>
2729a2793,2795
>
> Blitters
>
diff -r -B -X .diff-exclude vanilla/projects/openttd_vs141.vcxproj cmclient/projects/openttd_vs141.vcxproj
451a452
>
454a456
>
709a712
>
721a725
>
757a762
>
758a764
>
807a814
>
809a817
>
815a824
>
894a904,912
>
>
>
>
>
>
>
>
>
901a920,921
>
>
1215a1236
>
diff -r -B -X .diff-exclude vanilla/projects/openttd_vs141.vcxproj.filters cmclient/projects/openttd_vs141.vcxproj.filters
22c22
<
---
>
25c25
<
---
>
28c28
<
---
>
31c31
<
---
>
34c34
<
---
>
37c37
<
---
>
40c40
<
---
>
43c43
<
---
>
46c46
<
---
>
49c49
<
---
>
52c52
<
---
>
55c55
<
---
>
58c58
<
---
>
61c61
<
---
>
64c64
<
---
>
67c67
<
---
>
70c70
<
---
>
73c73
<
---
>
76c76
<
---
>
79c79
<
---
>
82c82
<
---
>
85c85
<
---
>
88c88
<
---
>
91c91
<
---
>
94c94
<
---
>
97c97
<
---
>
100c100
<
---
>
102a103,105
>
> {c76ff9f1-1e62-46d8-8d55-000000000033}
>
437a441,443
>
> Header Files
>
446a453,455
>
> Header Files
>
1211a1221,1223
>
> Header Files
>
1247a1260,1262
>
> Header Files
>
1355a1371,1373
>
> GUI Source Code
>
1358a1377,1379
>
> GUI Source Code
>
1505a1527,1529
>
> GUI Source Code
>
1511a1536,1538
>
> GUI Source Code
>
1529a1557,1559
>
> Widgets
>
1766a1797,1823
>
> Command handlers
>
>
> CityMania files
>
>
> CityMania files
>
>
> CityMania files
>
>
> CityMania files
>
>
> CityMania files
>
>
> CityMania files
>
>
> CityMania files
>
>
> CityMania files
>
1787a1845,1850
>
> Save/Load handlers
>
>
> Save/Load handlers
>
2729a2793,2795
>
> Blitters
>
diff -r -B -X .diff-exclude vanilla/projects/openttd_vs142.vcxproj cmclient/projects/openttd_vs142.vcxproj
451a452
>
454a456
>
709a712
>
721a725
>
757a762
>
758a764
>
807a814
>
809a817
>
815a824
>
894a904,912
>
>
>
>
>
>
>
>
>
901a920,921
>
>
1215a1236
>
diff -r -B -X .diff-exclude vanilla/projects/openttd_vs142.vcxproj.filters cmclient/projects/openttd_vs142.vcxproj.filters
22c22
<
---
>
25c25
<
---
>
28c28
<
---
>
31c31
<
---
>
34c34
<
---
>
37c37
<
---
>
40c40
<
---
>
43c43
<
---
>
46c46
<
---
>
49c49
<
---
>
52c52
<
---
>
55c55
<
---
>
58c58
<
---
>
61c61
<
---
>
64c64
<
---
>
67c67
<
---
>
70c70
<
---
>
73c73
<
---
>
76c76
<
---
>
79c79
<
---
>
82c82
<
---
>
85c85
<
---
>
88c88
<
---
>
91c91
<
---
>
94c94
<
---
>
97c97
<
---
>
100c100
<
---
>
102a103,105
>
> {c76ff9f1-1e62-46d8-8d55-000000000033}
>
437a441,443
>
> Header Files
>
446a453,455
>
> Header Files
>
1211a1221,1223
>
> Header Files
>
1247a1260,1262
>
> Header Files
>
1355a1371,1373
>
> GUI Source Code
>
1358a1377,1379
>
> GUI Source Code
>
1505a1527,1529
>
> GUI Source Code
>
1511a1536,1538
>
> GUI Source Code
>
1529a1557,1559
>
> Widgets
>
1766a1797,1823
>
> Command handlers
>
>
> CityMania files
>
>
> CityMania files
>
>
> CityMania files
>
>
> CityMania files
>
>
> CityMania files
>
>
> CityMania files
>
>
> CityMania files
>
>
> CityMania files
>
1787a1845,1850
>
> Save/Load handlers
>
>
> Save/Load handlers
>
2729a2793,2795
>
> Blitters
>
Only in cmclient/projects: openttd_vs80.sln
Only in cmclient/projects: openttd_vs80.vcproj
Only in cmclient/projects: openttd_vs80.vcproj.in
Only in cmclient/projects: openttd_vs80.vcproj.user
Only in cmclient/projects: openttd_vs90.sln
Only in cmclient/projects: openttd_vs90.vcproj
Only in cmclient/projects: openttd_vs90.vcproj.in
Only in cmclient/projects: openttd_vs90.vcproj.user
Only in cmclient/projects: settingsgen_vs100.vcxproj
Only in cmclient/projects: settingsgen_vs100.vcxproj.filters
Only in cmclient/projects: settingsgen_vs80.vcproj
Only in cmclient/projects: settingsgen_vs90.vcproj
Only in cmclient/projects: settings_vs100.vcxproj
Only in cmclient/projects: settings_vs100.vcxproj.filters
Only in cmclient/projects: settings_vs100.vcxproj.filters.in
Only in cmclient/projects: settings_vs100.vcxproj.in
Only in cmclient/projects: settings_vs100.vcxproj.user
Only in cmclient/projects: settings_vs80.vcproj
Only in cmclient/projects: settings_vs80.vcproj.in
Only in cmclient/projects: settings_vs90.vcproj
Only in cmclient/projects: settings_vs90.vcproj.in
Only in cmclient/projects: strgen_vs100.vcxproj
Only in cmclient/projects: strgen_vs100.vcxproj.filters
Only in cmclient/projects: strgen_vs100.vcxproj.user
Only in cmclient/projects: strgen_vs80.vcproj
Only in cmclient/projects: strgen_vs90.vcproj
Only in cmclient/projects: version_vs100.vcxproj
Only in cmclient/projects: version_vs80.vcproj
Only in cmclient/projects: version_vs90.vcproj
Only in cmclient: readme.txt
diff -r -B -X .diff-exclude vanilla/.release_date cmclient/.release_date
1c1
< 2020-04-13 19:02 UTC
---
> 2020-02-09 12:28 UTC
diff -r -B -X .diff-exclude vanilla/source.list cmclient/source.list
138a139
> bitstream.h
141a143
> cargo_table_gui.h
396a399
> watch_gui.h
408a412
> zoning.h
464a469
> cargo_table_gui.cpp
465a471
> commands_gui.cpp
514a521
> watch_gui.cpp
516a524
> zoning_gui.cpp
524a533
> widgets/cargo_table_widget.h
605a615,625
> zoning_cmd.cpp
>
> # CityMania files
> bitstream.cpp
> citymania/base64.h
> citymania/base64.cpp
> citymania/highlight.hpp
> citymania/highlight.cpp
> citymania/station_ui.hpp
> citymania/station_ui.cpp
> newgrf_revisions.hpp
614a635,636
> saveload/citymania_sl.cpp
> saveload/citymania_sl.h
959a982
> blitter/base.cpp
Only in cmclient/src/3rdparty/squirrel: COMPILE
Only in cmclient/src/3rdparty/squirrel: doc
Only in cmclient/src/3rdparty/squirrel: etc
Only in cmclient/src/3rdparty/squirrel: HISTORY
Only in cmclient/src/3rdparty/squirrel/include: sqstdblob.h
Only in cmclient/src/3rdparty/squirrel/include: sqstdio.h
Only in cmclient/src/3rdparty/squirrel/include: sqstdsystem.h
Only in cmclient/src/3rdparty/squirrel: Makefile
Only in cmclient/src/3rdparty/squirrel: README
Only in cmclient/src/3rdparty/squirrel: samples
Only in cmclient/src/3rdparty/squirrel: sq
Only in cmclient/src/3rdparty/squirrel/sqstdlib: Makefile
Only in cmclient/src/3rdparty/squirrel/sqstdlib: sqstdblob.cpp
Only in cmclient/src/3rdparty/squirrel/sqstdlib: sqstdblobimpl.h
Only in cmclient/src/3rdparty/squirrel/sqstdlib: sqstdio.cpp
Only in cmclient/src/3rdparty/squirrel/sqstdlib: sqstdlib.dsp
Only in cmclient/src/3rdparty/squirrel/sqstdlib: sqstdstream.cpp
Only in cmclient/src/3rdparty/squirrel/sqstdlib: sqstdstream.h
Only in cmclient/src/3rdparty/squirrel/sqstdlib: sqstdsystem.cpp
Only in cmclient/src/3rdparty/squirrel/squirrel: Makefile
Only in cmclient/src/3rdparty/squirrel/squirrel: squirrel.dsp
Only in cmclient/src/3rdparty/squirrel: squirrel.dsw
diff -r -B -X .diff-exclude vanilla/src/aircraft_cmd.cpp cmclient/src/aircraft_cmd.cpp
2071c2071
< PerformanceAccumulator framerate(PFE_GL_AIRCRAFT);
---
> // PerformanceAccumulator framerate(PFE_GL_AIRCRAFT);
diff -r -B -X .diff-exclude vanilla/src/airport_gui.cpp cmclient/src/airport_gui.cpp
31a32,33
> #include "citymania/station_ui.hpp"
>
35,37c37,39
< static AirportClassID _selected_airport_class; ///< the currently visible airport class
< static int _selected_airport_index; ///< the index of the selected airport in the current class or -1
< static byte _selected_airport_layout; ///< selected airport layout number.
---
> AirportClassID _selected_airport_class; ///< the currently visible airport class
> int _selected_airport_index; ///< the index of the selected airport in the current class or -1
> byte _selected_airport_layout; ///< selected airport layout number.
56a59,63
> if (_settings_client.gui.cm_use_improved_station_join) {
> citymania::PlaceAirport(tile);
> return;
> }
>
150a158,159
>
> citymania::AbortStationPlacement();
422a432
> top = DrawStationAuthorityText(panel_nwi->pos_x + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, top) + WD_PAR_VSEP_NORMAL;
462c472,473
< if (_settings_client.gui.station_show_coverage) SetTileSelectBigSize(-rad, -rad, 2 * rad, 2 * rad);
---
> //if (_settings_client.gui.station_show_coverage) SetTileSelectBigSize(-rad, -rad, 2 * rad, 2 * rad);
> SetTileSelectBigSize(-rad, -rad, 2 * rad, 2 * rad);
Only in cmclient/src: bitstream.cpp
Only in cmclient/src: bitstream.h
Only in cmclient/src/blitter: base.cpp
diff -r -B -X .diff-exclude vanilla/src/bridge_gui.cpp cmclient/src/bridge_gui.cpp
25a26
> #include "tilehighlight_func.h"
74a76,77
>
> StoreRailPlacementEndpoints(p1, end_tile, (TileX(p1) == TileX(end_tile)) ? TRACK_Y : TRACK_X, false);
diff -r -B -X .diff-exclude vanilla/src/build_vehicle_gui.cpp cmclient/src/build_vehicle_gui.cpp
35c35
<
---
> #include "hotkeys.h"
1641a1642,1654
>
> virtual EventState OnHotkey(int hotkey)
> {
> if (this->owner != _local_company) return ES_NOT_HANDLED;
> return Window::OnHotkey(hotkey);
> }
>
> static HotkeyList hotkeys;
> };
>
> static Hotkey build_vehicle_hotkeys[] = {
> Hotkey('R', "build_vehicle", WID_BV_BUILD),
> HOTKEY_LIST_END
1642a1656
> HotkeyList BuildVehicleWindow::hotkeys("build_vehicle", build_vehicle_hotkeys);
1648c1662,1663
< _nested_build_vehicle_widgets, lengthof(_nested_build_vehicle_widgets)
---
> _nested_build_vehicle_widgets, lengthof(_nested_build_vehicle_widgets),
> &BuildVehicleWindow::hotkeys
Only in cmclient/src: cargo_table_gui.cpp
Only in cmclient/src: cargo_table_gui.h
Only in cmclient/src: citymania
diff -r -B -X .diff-exclude vanilla/src/command.cpp cmclient/src/command.cpp
26a27,30
> #include "window_func.h"
> #include "watch_gui.h"
> #include "network/network_base.h"
> #include "window_func.h"
566c570,571
< !(GetCommandFlags(cmd) & CMD_NO_EST);
---
> !(GetCommandFlags(cmd) & CMD_NO_EST) &&
> !(cmd & CMD_NO_ESTIMATE);
758a764,779
> }
>
> /* Send Tile Number to Watching Company Windows */
> WatchCompany *wc;
> for(int watching_window = 0; ; watching_window++){
> wc = dynamic_cast(FindWindowById(WC_WATCH_COMPANY, watching_window));
> if(wc != NULL) wc->OnDoCommand(_current_company, tile);
> else break;
> }
>
> for (const NetworkClientInfo *ci : NetworkClientInfo::Iterate()) {
> if (ci->client_playas == _current_company) {
> wc = dynamic_cast(FindWindowById(WC_WATCH_COMPANYA, ci->client_id));
> if (wc != NULL) wc->OnDoCommand(_current_company, tile);
> break;
> }
Only in cmclient/src: commands_gui.cpp
diff -r -B -X .diff-exclude vanilla/src/command_type.h cmclient/src/command_type.h
370c370
< #define CMD_MSG(x) ((x) << 16)
---
> #define CMD_MSG(x) ((uint32)((x) << 16))
378a379
> CMD_NO_ESTIMATE = 0x0200, ///< execute command instead of doing estimate even if shift is pressed
diff -r -B -X .diff-exclude vanilla/src/company_base.h cmclient/src/company_base.h
17a18
> #include "cargo_type.h"
26a28
> Money cargo_income[NUM_CARGO]; ///< Cargo income from each cargo type
131a134,139
>
> uint32 cargo_units[NUM_CARGO]; ///< Total amount of transported cargo for each cargo ID
> Money cargo_income[NUM_CARGO]; ///< Total income from transported cargo for each cargo ID
>
> uint32 cargo_units_period[2][NUM_CARGO]; ///< Monthly amount of transported cargo for each cargo ID
> Money cargo_income_period[2][NUM_CARGO]; ///< Monthly income from transported cargo for each cargo ID
diff -r -B -X .diff-exclude vanilla/src/company_cmd.cpp cmclient/src/company_cmd.cpp
38a39
> #include "cargo_type.h"
69a71,72
> InvalidateWindowClassesData(WC_WATCH_COMPANY, 0);
> InvalidateWindowClassesData(WC_WATCH_COMPANYA, 1);
91a95,96
> InvalidateWindowClassesData(WC_WATCH_COMPANY, 0);
> InvalidateWindowClassesData(WC_WATCH_COMPANYA, 1);
581a587,594
> if (!is_ai) UpdateAllTownVirtCoords(); //coloured rating
>
> for (uint j = 0; j < NUM_CARGO; j++) {
> c->cargo_income[j] = 0;
> c->cargo_units[j] = 0;
> }
> CargoResetPeriods(c);
>
584a598,603
> void CargoResetPeriods(Company *c){
> memmove(&c->cargo_income_period[1], &c->cargo_income_period[0], sizeof(c->cargo_income_period[0]));
> memset(&c->cargo_income_period, 0, sizeof(c->cargo_income_period[0]));
> memmove(&c->cargo_units_period[1], &c->cargo_units_period[0], sizeof(c->cargo_units_period[0]));
> memset(&c->cargo_units_period, 0, sizeof(c->cargo_units_period[0]));
> }
1074a1094
> InvalidateWindowClassesData(WC_WATCH_COMPANY, 0);
diff -r -B -X .diff-exclude vanilla/src/company_func.h cmclient/src/company_func.h
31a32
> void CargoResetPeriods(Company *c);
diff -r -B -X .diff-exclude vanilla/src/company_gui.cpp cmclient/src/company_gui.cpp
2185c2185,2192
< NWidget(NWID_SPACER), SetFill(0, 1),
---
> NWidget(NWID_SELECTION, INVALID_COLOUR, WID_C_SELECT_MOD),
> NWidget(NWID_SPACER), SetMinimalSize(0, 0), SetFill(0, 1),
> NWidget(NWID_VERTICAL), SetPIP(4, 2, 4),
> NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_C_MOD_COMPANY_JOIN), SetFill(1, 0), SetDataTip(STR_MOD_COMPANY_JOIN_BUTTON, STR_NULL),
> NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_C_MOD_COMPANY_TOGGLE_LOCK), SetFill(1, 0), SetDataTip(STR_MOD_TOGGLE_LOCK_BUTTON, STR_NULL),
> NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_C_MOD_COMPANY_RESET), SetFill(1, 0), SetDataTip(STR_MOD_COMPANY_RESET_BUTTON, STR_NULL),
> EndContainer(),
> EndContainer(),
2254a2262,2271
> static void ResetCallback(Window *w, bool confirmed)
> {
> if (confirmed) {
> CompanyID company2 = (CompanyID)w->window_number;
> char msg[128];
> seprintf(msg, lastof(msg), "!reset %i", company2 + 1);
> NetworkClientSendChatToServer(msg);
> }
> }
>
2275a2293,2295
>
> CWP_BUTTONS_PLAYER = 0,
> CWP_BUTTONS_MOD,
2344a2365,2371
> plane = (int)(_networking && _novarole ? CWP_BUTTONS_MOD: CWP_BUTTONS_PLAYER);
> wi = this->GetWidget(WID_C_SELECT_MOD);
> if (plane != wi->shown_plane) {
> wi->SetDisplayedPlane(plane);
> reinit = true;
> }
>
2350a2378,2384
> // if(!_networking) {
> // this->SetWidgetDisabledState(CW_WIDGET_COMPANY_RESUME, true);
> // this->SetWidgetDisabledState(CW_WIDGET_COMPANY_SUSPEND, true);
> // this->SetWidgetDisabledState(CW_WIDGET_COMPANY_RESET, true);
> // this->SetWidgetDisabledState(CW_WIDGET_COMPANY_JOIN2, true);
> // }
>
2404a2439,2447
> // case CW_WIDGET_COMPANY_RESUME:
> // case CW_WIDGET_COMPANY_SUSPEND:
> // case CW_WIDGET_COMPANY_RESET:
> // case CW_WIDGET_COMPANY_JOIN2:
> // if(!_novarole){
> // size->width = 0;
> // size->height = 0;
> // }
> // break;
2623a2667,2694
> MarkWholeScreenDirty();
> break;
> }
>
> case WID_C_MOD_COMPANY_JOIN: {
> if (!_novarole) return;
> CompanyID company2 = (CompanyID)this->window_number;
> // this->query_widget = WID_C_MOD_COMPANY_JOIN;
> char msg[128];
> seprintf(msg, lastof(msg), "!move %i", company2 + 1);
> NetworkClientSendChatToServer(msg);
> MarkWholeScreenDirty();
> break;
> }
> case WID_C_MOD_COMPANY_RESET: {
> if (!_networking) return;
> this->query_widget = WID_C_MOD_COMPANY_RESET;
> ShowQuery(STR_XI_RESET_CAPTION, STR_XI_REALY_RESET, this, ResetCallback);
> MarkWholeScreenDirty();
> break;
> }
> case WID_C_MOD_COMPANY_TOGGLE_LOCK: {
> if (!_novarole) return;
> CompanyID company2 = (CompanyID)this->window_number;
> char msg[128];
> seprintf(msg, lastof(msg), "!lockp %i", company2 + 1);
> NetworkClientSendChatToServer(msg);
> MarkWholeScreenDirty();
diff -r -B -X .diff-exclude vanilla/src/crashlog.cpp cmclient/src/crashlog.cpp
120c120
< "OpenTTD version:\n"
---
> "OpenTTD version: CityMania patched client http://citymania.org\n\n"
337c337
< buffer += seprintf(buffer, last, "*** OpenTTD Crash Report ***\n\n");
---
> buffer += seprintf(buffer, last, "*** OpenTTD Crash Report ***\nCityMania patched client http://citymania.org\nPlease, unless you encounter this bug with unpatched OpenTTD version, report bug to CityMania team\n\n");
diff -r -B -X .diff-exclude vanilla/src/depot_gui.cpp cmclient/src/depot_gui.cpp
29c29
<
---
> #include "hotkeys.h"
82,109d81
< static WindowDesc _train_depot_desc(
< WDP_AUTO, "depot_train", 362, 123,
< WC_VEHICLE_DEPOT, WC_NONE,
< 0,
< _nested_train_depot_widgets, lengthof(_nested_train_depot_widgets)
< );
<
< static WindowDesc _road_depot_desc(
< WDP_AUTO, "depot_roadveh", 316, 97,
< WC_VEHICLE_DEPOT, WC_NONE,
< 0,
< _nested_train_depot_widgets, lengthof(_nested_train_depot_widgets)
< );
<
< static WindowDesc _ship_depot_desc(
< WDP_AUTO, "depot_ship", 306, 99,
< WC_VEHICLE_DEPOT, WC_NONE,
< 0,
< _nested_train_depot_widgets, lengthof(_nested_train_depot_widgets)
< );
<
< static WindowDesc _aircraft_depot_desc(
< WDP_AUTO, "depot_aircraft", 332, 99,
< WC_VEHICLE_DEPOT, WC_NONE,
< 0,
< _nested_train_depot_widgets, lengthof(_nested_train_depot_widgets)
< );
<
126a99,101
>
> if (_settings_client.gui.cm_open_orders_for_new_vehicles)
> ShowOrdersWindow(v);
329,331c304,313
< SetDParam(0, CeilDiv(u->gcache.cached_total_length * 10, TILE_SIZE));
< SetDParam(1, 1);
< DrawString(rtl ? left + WD_FRAMERECT_LEFT : right - this->count_width, rtl ? left + this->count_width : right - WD_FRAMERECT_RIGHT, y + (this->resize.step_height - FONT_HEIGHT_SMALL) / 2, STR_TINY_BLACK_DECIMAL, TC_FROMSTRING, SA_RIGHT); // Draw the counter
---
> if (_settings_client.gui.old_depot_train_length_calc) {
> SetDParam(0, CeilDiv(u->gcache.cached_total_length, 8));
> SetDParam(1, 1);
> DrawString(rtl ? left + WD_FRAMERECT_LEFT : right - this->count_width, rtl ? left + this->count_width : right - WD_FRAMERECT_RIGHT, y + (this->resize.step_height - FONT_HEIGHT_SMALL) / 2, STR_TINY_BLACK_COMA, TC_FROMSTRING, SA_RIGHT); // Draw the counter
> }
> else {
> SetDParam(0, CeilDiv(u->gcache.cached_total_length * 10, TILE_SIZE));
> SetDParam(1, 1);
> DrawString(rtl ? left + WD_FRAMERECT_LEFT : right - this->count_width, rtl ? left + this->count_width : right - WD_FRAMERECT_RIGHT, y + (this->resize.step_height - FONT_HEIGHT_SMALL) / 2, STR_TINY_BLACK_DECIMAL, TC_FROMSTRING, SA_RIGHT); // Draw the counter
> }
907a890,895
> if (_settings_client.gui.cm_open_vehicle_for_shared_clone) { // CM
> if (DoCommandP(this->window_number, v->index, _ctrl_pressed ? 1 : 0, CMD_CLONE_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_BUY_TRAIN + v->type), CcCloneVehicle))
> ResetObjectToPlace();
> return true;
> }
>
1078a1067,1081
>
> virtual EventState OnHotkey(int hotkey)
> {
> if (this->owner != _local_company) return ES_NOT_HANDLED;
> return Window::OnHotkey(hotkey);
> }
>
> static HotkeyList hotkeys;
> };
>
> static Hotkey depot_hotkeys[] = {
> Hotkey(WKC_CTRL | 'F', "depot_go_all", WID_D_START_ALL),
> Hotkey('R', "depot_build_vehicle", WID_D_BUILD),
> Hotkey(WKC_NONE, "depot_clone_vehicle", WID_D_CLONE),
> HOTKEY_LIST_END
1079a1083
> HotkeyList DepotWindow::hotkeys("depot_gui", depot_hotkeys);
1089a1094,1125
>
> static WindowDesc _train_depot_desc(
> WDP_AUTO, "depot_train", 362, 123,
> WC_VEHICLE_DEPOT, WC_NONE,
> 0,
> _nested_train_depot_widgets, lengthof(_nested_train_depot_widgets),
> &DepotWindow::hotkeys
> );
>
> static WindowDesc _road_depot_desc(
> WDP_AUTO, "depot_roadveh", 316, 97,
> WC_VEHICLE_DEPOT, WC_NONE,
> 0,
> _nested_train_depot_widgets, lengthof(_nested_train_depot_widgets),
> &DepotWindow::hotkeys
> );
>
> static WindowDesc _ship_depot_desc(
> WDP_AUTO, "depot_ship", 306, 99,
> WC_VEHICLE_DEPOT, WC_NONE,
> 0,
> _nested_train_depot_widgets, lengthof(_nested_train_depot_widgets),
> &DepotWindow::hotkeys
> );
>
> static WindowDesc _aircraft_depot_desc(
> WDP_AUTO, "depot_aircraft", 332, 99,
> WC_VEHICLE_DEPOT, WC_NONE,
> 0,
> _nested_train_depot_widgets, lengthof(_nested_train_depot_widgets),
> &DepotWindow::hotkeys
> );
diff -r -B -X .diff-exclude vanilla/src/dock_gui.cpp cmclient/src/dock_gui.cpp
33a34,35
> #include "citymania/station_ui.hpp"
>
191a194,195
> if (_ctrl_pressed == _settings_client.gui.persistent_depottools)
> ResetObjectToPlace();
194a199,204
>
> if (_settings_client.gui.cm_use_improved_station_join) {
> citymania::PlaceDock(tile);
> break;
> }
>
257a268,269
>
> citymania::AbortStationPlacement();
419a432,434
> SetTileSelectSize(1, 1);
> SetTileSelectBigSize(-rad, -rad, 2 * rad, 2 * rad);
> #if 0
424a440
> #endif
432a449
> top = DrawStationAuthorityText(back_nwi->pos_x + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, top) + WD_PAR_VSEP_NORMAL;
450a468
> citymania::MarkCoverageHighlightDirty();
diff -r -B -X .diff-exclude vanilla/src/economy.cpp cmclient/src/economy.cpp
53a54
> #include "cargo_table_gui.h"
374a376,377
> ClrBit(t->advertise_regularly, old_owner);
> ClrBit(t->do_powerfund, old_owner);
1099a1103,1110
> /* Increase town's counter for all goods types only if delivered near town*/
> if(CB_Enabled()){
> if (_settings_client.gui.cb_distance_check == 0 || (DistanceManhattan(st->town->xy, st->xy) <= _settings_client.gui.cb_distance_check)) {
> st->town->new_act_cargo[cargo_type] += accepted_total;
> InvalidateWindowData(WC_CB_TOWN, st->town->index);
> }
> }
>
1115a1127,1136
> company->cargo_income[cargo_type] += profit;
> company->cargo_units[cargo_type] += num_pieces;
>
> company->cargo_income_period[0][cargo_type] += profit;
> company->cargo_units_period[0][cargo_type] += num_pieces;
>
> company->cur_economy.cargo_income[cargo_type] += profit;
>
> InvalidateCargosWindows(company->index);
>
1957a1979,1982
>
> for (Company *c : Company::Iterate()) {
> CargoResetPeriods(c);
> }
Only in cmclient/src: endian_check.cpp
diff -r -B -X .diff-exclude vanilla/src/fontdetection.cpp cmclient/src/fontdetection.cpp
641c641
< FcFini();
---
> // FcFini();
diff -r -B -X .diff-exclude vanilla/src/framerate_gui.cpp cmclient/src/framerate_gui.cpp
309c309
< static const PerformanceElement DISPLAY_ORDER_PFE[PFE_MAX] = {
---
> static const PerformanceElement DISPLAY_ORDER_PFE[PFE_MAX - 4] = {
312,315c312,315
< PFE_GL_TRAINS,
< PFE_GL_ROADVEHS,
< PFE_GL_SHIPS,
< PFE_GL_AIRCRAFT,
---
> // PFE_GL_TRAINS,
> // PFE_GL_ROADVEHS,
> // PFE_GL_SHIPS,
> // PFE_GL_AIRCRAFT,
diff -r -B -X .diff-exclude vanilla/src/gfx.cpp cmclient/src/gfx.cpp
35a36
> bool _alt_pressed; ///< Is Alt pressed?
diff -r -B -X .diff-exclude vanilla/src/gfx_func.h cmclient/src/gfx_func.h
55a56
> extern bool _alt_pressed; ///< Is Alt pressed?
diff -r -B -X .diff-exclude vanilla/src/gfxinit.cpp cmclient/src/gfxinit.cpp
192a193,194
> // LoadGrfFile("innerhighlight.grf", SPR_INNER_HIGHLIGHT_BASE, i++);
> LoadGrfFile("cmclient-2.grf", SPR_INNER_HIGHLIGHT_BASE - 4, i++);
diff -r -B -X .diff-exclude vanilla/src/gfx_type.h cmclient/src/gfx_type.h
104a105,114
>
> WKC_L_BRACE = 154, ///< { Left brace
> WKC_R_BRACE = 155, ///< } Right brace
>
> WKC_L_PAREN = 157, ///< ( Left parentheses
> WKC_R_PAREN = 158, ///< ) Right parentheses
> WKC_PLUS = 159, ///< + Plus
> WKC_EXCLAIM = 160, ///< ! Exclamation mark
> WKC_ASTERISK = 161, ///< * Asterisk
> WKC_DOLLAR = 162, ///< $ Dollar sign
diff -r -B -X .diff-exclude vanilla/src/goal_gui.cpp cmclient/src/goal_gui.cpp
189c189,196
< d.height *= 5;
---
> uint num = 0;
> for (const Goal *s : Goal::Iterate()) {
> if (s->company == INVALID_COMPANY || s->company == this->window_number) {
> num++;
> }
> }
>
> d.height *= (5 + num);
diff -r -B -X .diff-exclude vanilla/src/graph_gui.cpp cmclient/src/graph_gui.cpp
609a610,759
> struct ExcludingCargoBaseGraphWindow : BaseGraphWindow {
> ExcludingCargoBaseGraphWindow(WindowDesc *desc, int widget, StringID format_str_y_axis):
> BaseGraphWindow(desc, widget, format_str_y_axis)
> {
> }
>
> uint line_height; ///< Pixel height of each cargo type row.
> uint icon_size; ///< Size of the cargo color icon.
> Scrollbar *vscroll; ///< Cargo list scrollbar.
>
> virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
> {
> if (widget != WID_CPR_MATRIX) {
> BaseGraphWindow::UpdateWidgetSize(widget, size, padding, fill, resize);
> return;
> }
>
> Dimension max_cargo_dim = {0, 0};
> const CargoSpec *cs;
> FOR_ALL_SORTED_STANDARD_CARGOSPECS(cs) {
> SetDParam(0, cs->name);
> max_cargo_dim = maxdim(max_cargo_dim, GetStringBoundingBox(STR_GRAPH_CARGO_PAYMENT_CARGO));
> }
>
> this->icon_size = max(max_cargo_dim.height, 6);
> this->line_height = this->icon_size + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
> size->width = (max_cargo_dim.width + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT + 1
> + this->icon_size + WD_PAR_VSEP_NORMAL);
> // fprintf(stderr, "HEIGHT %u \n", size->height, size->height / this->line_height);
> // uint lines = min(max(1, size->height / this->line_height), _sorted_standard_cargo_specs_size);
> // fprintf(stderr, "LINES %u\n", lines);
> size->height = max(size->height, this->line_height * _sorted_standard_cargo_specs_size);
> resize->width = 0;
> resize->height = this->line_height;
> fill->width = 0;
> fill->height = this->line_height;
> }
>
> virtual void DrawWidget(const Rect &r, int widget) const
> {
> if (widget != WID_CPR_MATRIX) {
> BaseGraphWindow::DrawWidget(r, widget);
> return;
> }
>
> bool rtl = _current_text_dir == TD_RTL;
>
> int x = r.left + WD_FRAMERECT_LEFT;
> int y = r.top;
>
> int pos = this->vscroll->GetPosition();
> int max = pos + this->vscroll->GetCapacity();
>
> const CargoSpec *cs;
> FOR_ALL_SORTED_STANDARD_CARGOSPECS(cs) {
> if (pos-- > 0) continue;
> if (--max < 0) break;
>
> bool lowered = !HasBit(_legend_excluded_cargo, cs->Index());
>
> /* Redraw box if lowered */
> if (lowered) DrawFrameRect(r.left, y, r.right, y + this->line_height - 1, COLOUR_ORANGE, lowered ? FR_LOWERED : FR_NONE);
>
> byte clk_dif = lowered ? 1 : 0;
> int rect_x = clk_dif + 1 + (rtl ? r.right - 12 : r.left + WD_FRAMERECT_LEFT);
>
> GfxFillRect(rect_x, y + 1 + clk_dif, rect_x + this->icon_size - 2, y + this->icon_size - 2 + clk_dif, PC_BLACK);
> GfxFillRect(rect_x + 1, y + 2 + clk_dif, rect_x + this->icon_size - 3, y + this->icon_size - 3 + clk_dif, cs->legend_colour);
> SetDParam(0, cs->name);
> uint icon_offset = this->icon_size + WD_PAR_VSEP_NORMAL;
> DrawString(rtl ? r.left : x + icon_offset + clk_dif, (rtl ? r.right - icon_offset + clk_dif : r.right), y + clk_dif, STR_GRAPH_CARGO_PAYMENT_CARGO);
>
> y += this->line_height;
> }
> }
>
> void UpdateExcludedData()
> {
> this->excluded_data = 0;
>
> int i = 0;
> const CargoSpec *cs;
> FOR_ALL_SORTED_STANDARD_CARGOSPECS(cs) {
> if (HasBit(_legend_excluded_cargo, cs->Index())) SetBit(this->excluded_data, i);
> i++;
> }
> }
>
> virtual void OnClick(Point pt, int widget, int click_count)
> {
> switch (widget) {
> case WID_CPR_KEY_BUTTON:
> ShowGraphLegend();
> break;
>
> case WID_CPR_ENABLE_CARGOES:
> /* Remove all cargoes from the excluded lists. */
> _legend_excluded_cargo = 0;
> this->excluded_data = 0;
> this->SetDirty();
> break;
>
> case WID_CPR_DISABLE_CARGOES: {
> /* Add all cargoes to the excluded lists. */
> int i = 0;
> const CargoSpec *cs;
> FOR_ALL_SORTED_STANDARD_CARGOSPECS(cs) {
> SetBit(_legend_excluded_cargo, cs->Index());
> SetBit(this->excluded_data, i);
> i++;
> }
> this->SetDirty();
> break;
> }
>
> case WID_CPR_MATRIX: {
> uint row = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_CPR_MATRIX, 0, this->line_height);
> if (row >= this->vscroll->GetCount()) return;
>
> const CargoSpec *cs;
> FOR_ALL_SORTED_STANDARD_CARGOSPECS(cs) {
> if (row-- > 0) continue;
>
> ToggleBit(_legend_excluded_cargo, cs->Index());
> this->UpdateExcludedData();
> this->SetDirty();
> break;
> }
> break;
> }
> }
> }
>
> virtual void OnResize()
> {
> this->vscroll->SetCapacityFromWidget(this, WID_CPR_MATRIX);
> }
>
> /**
> * Some data on this window has become invalid.
> * @param data Information about the changed data.
> * @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details.
> */
> virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
> {
> if (!gui_scope) return;
> this->UpdateExcludedData();
> }
> };
>
665c815
< struct IncomeGraphWindow : BaseGraphWindow {
---
> struct IncomeGraphWindow : ExcludingCargoBaseGraphWindow {
667c817
< BaseGraphWindow(desc, WID_CV_GRAPH, STR_JUST_CURRENCY_SHORT)
---
> ExcludingCargoBaseGraphWindow(desc, WID_CPR_GRAPH, STR_JUST_CURRENCY_SHORT)
669c819,823
< this->InitializeWindow(window_number);
---
> this->CreateNestedTree();
> this->vscroll = this->GetScrollbar(WID_CPR_MATRIX_SCROLLBAR);
> this->vscroll->SetCount(_sorted_standard_cargo_specs_size);
> this->UpdateExcludedData();
> this->FinishInitNested(window_number);
673a828
> if(_legend_excluded_cargo == 0){
675a831,839
> uint total_income = 0;
> const CargoSpec *cs;
> FOR_ALL_SORTED_STANDARD_CARGOSPECS(cs) {
> if (!HasBit(_legend_excluded_cargo, cs->Index())){
> total_income += c->old_economy[j].cargo_income[cs->Index()];
> }
> }
> return total_income;
> }
682c846
< NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_CV_KEY_BUTTON), SetMinimalSize(50, 0), SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP),
---
> NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_CPR_KEY_BUTTON), SetMinimalSize(50, 0), SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP),
687c851
< NWidget(WWT_PANEL, COLOUR_GREY, WID_CV_BACKGROUND),
---
> NWidget(WWT_PANEL, COLOUR_GREY, WID_CPR_BACKGROUND),
689c853
< NWidget(WWT_EMPTY, COLOUR_GREY, WID_CV_GRAPH), SetMinimalSize(576, 128), SetFill(1, 1), SetResize(1, 1),
---
> NWidget(WWT_EMPTY, COLOUR_GREY, WID_CPR_GRAPH), SetMinimalSize(576, 128), SetFill(1, 1), SetResize(1, 1),
691,692c855,863
< NWidget(NWID_SPACER), SetFill(0, 1), SetResize(0, 1),
< NWidget(WWT_RESIZEBOX, COLOUR_GREY, WID_CV_RESIZE),
---
> NWidget(NWID_SPACER), SetMinimalSize(0, 4),
> NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_CPR_ENABLE_CARGOES), SetDataTip(STR_GRAPH_CARGO_ENABLE_ALL, STR_GRAPH_CARGO_TOOLTIP_ENABLE_ALL), SetFill(1, 0),
> NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_CPR_DISABLE_CARGOES), SetDataTip(STR_GRAPH_CARGO_DISABLE_ALL, STR_GRAPH_CARGO_TOOLTIP_DISABLE_ALL), SetFill(1, 0),
> NWidget(NWID_SPACER), SetMinimalSize(0, 4),
> NWidget(NWID_HORIZONTAL),
> NWidget(WWT_MATRIX, COLOUR_ORANGE, WID_CPR_MATRIX), SetFill(0, 2), SetResize(0, 2), SetMatrixDataTip(1, 0, STR_GRAPH_CARGO_PAYMENT_TOGGLE_CARGO), SetScrollbar(WID_CPR_MATRIX_SCROLLBAR),
> NWidget(NWID_VSCROLLBAR, COLOUR_ORANGE, WID_CPR_MATRIX_SCROLLBAR),
> EndContainer(),
> NWidget(NWID_SPACER), SetMinimalSize(0, 4),
693a865,871
> NWidget(NWID_SPACER), SetMinimalSize(5, 0), SetFill(0, 1), SetResize(0, 1),
> EndContainer(),
> NWidget(NWID_HORIZONTAL),
> NWidget(NWID_SPACER), SetMinimalSize(WD_RESIZEBOX_WIDTH, 0), SetFill(1, 0), SetResize(1, 0),
> NWidget(WWT_TEXT, COLOUR_GREY, WID_CPR_FOOTER), SetMinimalSize(0, 6), SetPadding(2, 0, 2, 0), SetDataTip(STR_GRAPH_CARGO_PAYMENT_RATES_X_LABEL, STR_NULL),
> NWidget(NWID_SPACER), SetFill(1, 0), SetResize(1, 0),
> NWidget(WWT_RESIZEBOX, COLOUR_GREY, WID_CPR_RESIZE),
714c892
< struct DeliveredCargoGraphWindow : BaseGraphWindow {
---
> struct DeliveredCargoGraphWindow : ExcludingCargoBaseGraphWindow {
716c894
< BaseGraphWindow(desc, WID_CV_GRAPH, STR_JUST_COMMA)
---
> ExcludingCargoBaseGraphWindow(desc, WID_CPR_GRAPH, STR_JUST_CURRENCY_SHORT)
718c896,900
< this->InitializeWindow(window_number);
---
> this->CreateNestedTree();
> this->vscroll = this->GetScrollbar(WID_CPR_MATRIX_SCROLLBAR);
> this->vscroll->SetCount(_sorted_standard_cargo_specs_size);
> this->OnHundredthTick();
> this->FinishInitNested(window_number);
722a905
> if(_legend_excluded_cargo == 0){
724a908,916
> uint total_delivered = 0;
> const CargoSpec *cs;
> FOR_ALL_SORTED_STANDARD_CARGOSPECS(cs) {
> if (!HasBit(_legend_excluded_cargo, cs->Index())){
> total_delivered += c->old_economy[j].delivered_cargo[cs->Index()];
> }
> }
> return total_delivered;
> }
731c923
< NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_CV_KEY_BUTTON), SetMinimalSize(50, 0), SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP),
---
> NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_CPR_KEY_BUTTON), SetMinimalSize(50, 0), SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP),
736c928
< NWidget(WWT_PANEL, COLOUR_GREY, WID_CV_BACKGROUND),
---
> NWidget(WWT_PANEL, COLOUR_GREY, WID_CPR_BACKGROUND),
738c930
< NWidget(WWT_EMPTY, COLOUR_GREY, WID_CV_GRAPH), SetMinimalSize(576, 128), SetFill(1, 1), SetResize(1, 1),
---
> NWidget(WWT_EMPTY, COLOUR_GREY, WID_CPR_GRAPH), SetMinimalSize(576, 128), SetFill(1, 1), SetResize(1, 1),
740,741c932,940
< NWidget(NWID_SPACER), SetFill(0, 1), SetResize(0, 1),
< NWidget(WWT_RESIZEBOX, COLOUR_GREY, WID_CV_RESIZE),
---
> NWidget(NWID_SPACER), SetMinimalSize(0, 4), SetFill(0, 0),
> NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_CPR_ENABLE_CARGOES), SetDataTip(STR_GRAPH_CARGO_ENABLE_ALL, STR_GRAPH_CARGO_TOOLTIP_ENABLE_ALL), SetFill(1, 0),
> NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_CPR_DISABLE_CARGOES), SetDataTip(STR_GRAPH_CARGO_DISABLE_ALL, STR_GRAPH_CARGO_TOOLTIP_DISABLE_ALL), SetFill(1, 0),
> NWidget(NWID_SPACER), SetMinimalSize(0, 4),
> NWidget(NWID_HORIZONTAL),
> NWidget(WWT_MATRIX, COLOUR_ORANGE, WID_CPR_MATRIX), SetFill(0, 2), SetResize(0, 2), SetMatrixDataTip(1, 0, STR_GRAPH_CARGO_PAYMENT_TOGGLE_CARGO), SetScrollbar(WID_CPR_MATRIX_SCROLLBAR),
> NWidget(NWID_VSCROLLBAR, COLOUR_ORANGE, WID_CPR_MATRIX_SCROLLBAR),
> EndContainer(),
> NWidget(NWID_SPACER), SetMinimalSize(0, 4),
742a942,948
> NWidget(NWID_SPACER), SetMinimalSize(5, 0), SetFill(0, 1), SetResize(0, 1),
> EndContainer(),
> NWidget(NWID_HORIZONTAL),
> NWidget(NWID_SPACER), SetMinimalSize(WD_RESIZEBOX_WIDTH, 0), SetFill(1, 0), SetResize(1, 0),
> NWidget(WWT_TEXT, COLOUR_GREY, WID_CPR_FOOTER), SetMinimalSize(0, 6), SetPadding(2, 0, 2, 0), SetDataTip(STR_GRAPH_CARGO_PAYMENT_RATES_X_LABEL, STR_NULL),
> NWidget(NWID_SPACER), SetFill(1, 0), SetResize(1, 0),
> NWidget(WWT_RESIZEBOX, COLOUR_GREY, WID_CPR_RESIZE),
868,871c1074
< struct PaymentRatesGraphWindow : BaseGraphWindow {
< uint line_height; ///< Pixel height of each cargo type row.
< Scrollbar *vscroll; ///< Cargo list scrollbar.
<
---
> struct PaymentRatesGraphWindow : ExcludingCargoBaseGraphWindow {
873c1076
< BaseGraphWindow(desc, WID_CPR_GRAPH, STR_JUST_CURRENCY_SHORT)
---
> ExcludingCargoBaseGraphWindow(desc, WID_CPR_GRAPH, STR_JUST_CURRENCY_SHORT)
891,1008d1093
< void UpdateExcludedData()
< {
< this->excluded_data = 0;
<
< int i = 0;
< const CargoSpec *cs;
< FOR_ALL_SORTED_STANDARD_CARGOSPECS(cs) {
< if (HasBit(_legend_excluded_cargo, cs->Index())) SetBit(this->excluded_data, i);
< i++;
< }
< }
<
< void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
< {
< if (widget != WID_CPR_MATRIX) {
< BaseGraphWindow::UpdateWidgetSize(widget, size, padding, fill, resize);
< return;
< }
<
< const CargoSpec *cs;
< FOR_ALL_SORTED_STANDARD_CARGOSPECS(cs) {
< SetDParam(0, cs->name);
< Dimension d = GetStringBoundingBox(STR_GRAPH_CARGO_PAYMENT_CARGO);
< d.width += 14; // colour field
< d.width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
< d.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
< *size = maxdim(d, *size);
< }
<
< this->line_height = size->height;
< size->height = this->line_height * 11; /* Default number of cargo types in most climates. */
< resize->width = 0;
< resize->height = this->line_height;
< }
<
< void DrawWidget(const Rect &r, int widget) const override
< {
< if (widget != WID_CPR_MATRIX) {
< BaseGraphWindow::DrawWidget(r, widget);
< return;
< }
<
< bool rtl = _current_text_dir == TD_RTL;
<
< int x = r.left + WD_FRAMERECT_LEFT;
< int y = r.top;
<
< int pos = this->vscroll->GetPosition();
< int max = pos + this->vscroll->GetCapacity();
<
< const CargoSpec *cs;
< FOR_ALL_SORTED_STANDARD_CARGOSPECS(cs) {
< if (pos-- > 0) continue;
< if (--max < 0) break;
<
< bool lowered = !HasBit(_legend_excluded_cargo, cs->Index());
<
< /* Redraw box if lowered */
< if (lowered) DrawFrameRect(r.left, y, r.right, y + this->line_height - 1, COLOUR_ORANGE, lowered ? FR_LOWERED : FR_NONE);
<
< byte clk_dif = lowered ? 1 : 0;
< int rect_x = clk_dif + (rtl ? r.right - 12 : r.left + WD_FRAMERECT_LEFT);
<
< GfxFillRect(rect_x, y + clk_dif, rect_x + 8, y + 5 + clk_dif, PC_BLACK);
< GfxFillRect(rect_x + 1, y + 1 + clk_dif, rect_x + 7, y + 4 + clk_dif, cs->legend_colour);
< SetDParam(0, cs->name);
< DrawString(rtl ? r.left : x + 14 + clk_dif, (rtl ? r.right - 14 + clk_dif : r.right), y + clk_dif, STR_GRAPH_CARGO_PAYMENT_CARGO);
<
< y += this->line_height;
< }
< }
<
< void OnClick(Point pt, int widget, int click_count) override
< {
< switch (widget) {
< case WID_CPR_ENABLE_CARGOES:
< /* Remove all cargoes from the excluded lists. */
< _legend_excluded_cargo = 0;
< this->excluded_data = 0;
< this->SetDirty();
< break;
<
< case WID_CPR_DISABLE_CARGOES: {
< /* Add all cargoes to the excluded lists. */
< int i = 0;
< const CargoSpec *cs;
< FOR_ALL_SORTED_STANDARD_CARGOSPECS(cs) {
< SetBit(_legend_excluded_cargo, cs->Index());
< SetBit(this->excluded_data, i);
< i++;
< }
< this->SetDirty();
< break;
< }
<
< case WID_CPR_MATRIX: {
< uint row = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_CPR_MATRIX, 0, this->line_height);
< if (row >= this->vscroll->GetCount()) return;
<
< const CargoSpec *cs;
< FOR_ALL_SORTED_STANDARD_CARGOSPECS(cs) {
< if (row-- > 0) continue;
<
< ToggleBit(_legend_excluded_cargo, cs->Index());
< this->UpdateExcludedData();
< this->SetDirty();
< break;
< }
< break;
< }
< }
< }
<
< void OnResize() override
< {
< this->vscroll->SetCapacityFromWidget(this, WID_CPR_MATRIX);
< }
<
1014,1024d1098
< /**
< * Some data on this window has become invalid.
< * @param data Information about the changed data.
< * @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details.
< */
< void OnInvalidateData(int data = 0, bool gui_scope = true) override
< {
< if (!gui_scope) return;
< this->OnHundredthTick();
< }
<
1059c1133
< NWidget(NWID_SPACER), SetMinimalSize(0, 24), SetFill(0, 1),
---
> NWidget(NWID_SPACER), SetMinimalSize(0, 4),
1064c1138
< NWidget(WWT_MATRIX, COLOUR_ORANGE, WID_CPR_MATRIX), SetResize(0, 2), SetMatrixDataTip(1, 0, STR_GRAPH_CARGO_PAYMENT_TOGGLE_CARGO), SetScrollbar(WID_CPR_MATRIX_SCROLLBAR),
---
> NWidget(WWT_MATRIX, COLOUR_ORANGE, WID_CPR_MATRIX), SetFill(0, 2), SetResize(0, 2), SetMatrixDataTip(1, 0, STR_GRAPH_CARGO_PAYMENT_TOGGLE_CARGO), SetScrollbar(WID_CPR_MATRIX_SCROLLBAR),
1067c1141
< NWidget(NWID_SPACER), SetMinimalSize(0, 24), SetFill(0, 1),
---
> NWidget(NWID_SPACER), SetMinimalSize(0, 4),
diff -r -B -X .diff-exclude vanilla/src/gui.h cmclient/src/gui.h
39a40,43
> /* commands_gui.cpp */
> void ShowCommandsToolbar();
> void ShowLoginWindow();
>
45c49
< void ShowLandInfo(TileIndex tile);
---
> void ShowLandInfo(TileIndex tile, TileIndex end_tile=INVALID_TILE);
diff -r -B -X .diff-exclude vanilla/src/hotkeys.cpp cmclient/src/hotkeys.cpp
80a81,96
>
> {"BACKSPACE", WKC_BACKSPACE},
> {"SLASH", WKC_SLASH},
> {"SEMICOLON", WKC_SEMICOLON},
> {"L_BRACKET", WKC_L_BRACKET},
> {"BACKSLASH", WKC_BACKSLASH},
> {"R_BRACKET", WKC_R_BRACKET},
> {"SINGLEQUOTE", WKC_SINGLEQUOTE},
> {"PERIOD", WKC_PERIOD},
>
> {"L_BRACE", WKC_L_BRACE},
> {"R_BRACE", WKC_R_BRACE},
> {"L_PAREN", WKC_L_PAREN},
> {"R_PAREN", WKC_R_PAREN},
> {"EXCLAIM", WKC_EXCLAIM},
> {"ASTERISK", WKC_ASTERISK},
diff -r -B -X .diff-exclude vanilla/src/industry_cmd.cpp cmclient/src/industry_cmd.cpp
356a357
> // DrawGroundSprite(image, GroundSpritePaletteTransform(image, dits->ground.pal, GENERAL_SPRITE_COLOUR(ind->random_colour)));
1968a1970,2003
> }
>
> /**
> * Return whether industry can be built on tile or not
> * regardless of terrain
> */
> bool CanBuildIndustryOnTile(IndustryType type, TileIndex tile) {
> const IndustrySpec *indspec = GetIndustrySpec(type);
> CommandCost ret;
>
> if (HasBit(indspec->callback_mask, CBM_IND_LOCATION)) {
> ret = CheckIfCallBackAllowsCreation(
> tile, type, 0, 0, 0, _current_company,
> _current_company == OWNER_DEITY ? IACT_RANDOMCREATION : IACT_USERCREATION);
> } else {
> ret = _check_new_industry_procs[GetIndustrySpec(type)->check_proc](tile);
> }
> if (ret.Failed())
> return false;
>
> ret = CheckIfFarEnoughFromConflictingIndustry(tile, type);
> if (ret.Failed())
> return false;
>
> Town *t = NULL;
> ret = FindTownForIndustry(tile, type, &t);
> if (ret.Failed())
> return false;
>
> ret = CheckIfIndustryIsAllowed(tile, type, t);
> if (ret.Failed())
> return false;
>
> return true;
diff -r -B -X .diff-exclude vanilla/src/industry_gui.cpp cmclient/src/industry_gui.cpp
41a42
> #include "hotkeys.h"
44a46,47
> #include "citymania/highlight.hpp"
>
252a256,270
> NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetResize(1, 0),
> NWidget(NWID_HORIZONTAL), SetPIP(2, 0, 2),
> NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(140, 14), SetDataTip(STR_FUND_INDUSTRY_FORBIDDEN_TILES_TITLE, STR_NULL),
> NWidget(NWID_SPACER), SetFill(1, 0),
> EndContainer(),
> NWidget(NWID_HORIZONTAL), SetPIP(2, 0, 2),
> NWidget(NWID_SPACER), SetFill(1, 0),
> NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_DPI_FT_OFF), SetMinimalSize(60, 12),
> SetDataTip(STR_FUND_INDUSTRY_FORBIDDEN_TILES_OFF, STR_FUND_INDUSTRY_FORBIDDEN_TILES_OFF_TOOLTIP),
> NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_DPI_FT_ON), SetMinimalSize(60, 12),
> SetDataTip(STR_FUND_INDUSTRY_FORBIDDEN_TILES_ON, STR_FUND_INDUSTRY_FORBIDDEN_TILES_ON_TOOLTIP),
> NWidget(NWID_SPACER), SetFill(1, 0),
> EndContainer(),
> NWidget(NWID_SPACER), SetMinimalSize(0, 2),
> EndContainer(),
260a279
> #if 0 // CM defined later
267a287
> #endif
278a299
> bool funding_enabled;
327a349
> citymania::SetIndustryForbiddenTilesHighlight(this->selected_type);
330a353,354
>
> this->funding_enabled = (_game_mode == GM_EDITOR || Company::IsValidID(_local_company));
336c360
< this->SetWidgetDisabledState(WID_DPI_FUND_WIDGET, this->selected_type != INVALID_INDUSTRYTYPE && !this->enabled[this->selected_index]);
---
> this->SetWidgetDisabledState(WID_DPI_FUND_WIDGET, !this->funding_enabled || (this->selected_type != INVALID_INDUSTRYTYPE && !this->enabled[this->selected_index]));
337a362
> this->LowerWidget(_settings_client.gui.show_industry_forbidden_tiles + WID_DPI_FT_OFF);
388c413
< BuildIndustryWindow() : Window(&_build_industry_desc)
---
> BuildIndustryWindow(WindowDesc *desc) : Window(desc)
395a421
> this->funding_enabled = false;
403a430,434
> ~BuildIndustryWindow()
> {
> citymania::SetIndustryForbiddenTilesHighlight(INVALID_INDUSTRYTYPE);
> }
>
589a621
> citymania::SetIndustryForbiddenTilesHighlight(this->selected_type);
632a665,674
>
> case WID_DPI_FT_OFF:
> case WID_DPI_FT_ON:
> this->RaiseWidget(_settings_client.gui.show_industry_forbidden_tiles + WID_DPI_FT_OFF);
> _settings_client.gui.show_industry_forbidden_tiles = (widget != WID_DPI_FT_OFF);
> this->LowerWidget(_settings_client.gui.show_industry_forbidden_tiles + WID_DPI_FT_OFF);
> if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP);
> this->SetDirty();
> MarkWholeScreenDirty();
> break;
701c743
< this->RaiseButtons();
---
> this->RaiseWidget(WID_DPI_FUND_WIDGET);
706c748
< this->RaiseButtons();
---
> this->RaiseWidget(WID_DPI_FUND_WIDGET);
722a765,771
>
> virtual EventState OnHotkey(int hotkey)
> {
> return Window::OnHotkey(hotkey);
> }
>
> static HotkeyList hotkeys;
724a774,791
> static Hotkey build_industry_hotkeys[] = {
> Hotkey((uint16)0, "display_chain", WID_DPI_DISPLAY_WIDGET),
> Hotkey((uint16)0, "build_button", WID_DPI_FUND_WIDGET),
> HOTKEY_LIST_END
> };
>
> HotkeyList BuildIndustryWindow::hotkeys("industry_fund_gui", build_industry_hotkeys);
>
> /** Window definition of the dynamic place industries gui */
> static WindowDesc _build_industry_desc(
> WDP_AUTO, "build_industry", 170, 212,
> WC_BUILD_INDUSTRY, WC_NONE,
> WDF_CONSTRUCTION,
> _nested_build_industry_widgets, lengthof(_nested_build_industry_widgets),
> &BuildIndustryWindow::hotkeys
> );
>
>
727c794,795
< if (_game_mode != GM_EDITOR && !Company::IsValidID(_local_company)) return;
---
> // CM always enable window to allow checking stuff as a spectator
> // if (_game_mode != GM_EDITOR && !Company::IsValidID(_local_company)) return;
729c797
< new BuildIndustryWindow();
---
> new BuildIndustryWindow(&_build_industry_desc);
diff -r -B -X .diff-exclude vanilla/src/industry_type.h cmclient/src/industry_type.h
12a13,14
> #include "tile_type.h"
>
42a45
> bool CanBuildIndustryOnTile(IndustryType type, TileIndex tile);
diff -r -B -X .diff-exclude vanilla/src/lang/english_AU.txt cmclient/src/lang/english_AU.txt
247a248
> STR_TOOLTIP_DEMOLISH_TREES :{BLACK}Demolish only trees on a square of land. Ctrl selects the area diagonally.
diff -r -B -X .diff-exclude vanilla/src/lang/english.txt cmclient/src/lang/english.txt
234a235,237
> STR_BUTTON_FILTER :{BLACK}Filter
> STR_BUTTON_FILTER_SELECT_ALL :Select All
> STR_BUTTON_FILTER_SELECT_NONE :Select None
251a255
> STR_TOOLTIP_DEMOLISH_TREES :{BLACK}Demolish only trees on a square of land. Ctrl selects the area diagonally.
279c283
<
---
> STR_MEASURE_DIST_HEIGHTDIFF :{BLACK}Area: {NUM} x {NUM}{}Distance: {NUM}{}Height difference: {HEIGHT}
327a332
> STR_TOOLBAR_TOOLTIP_DISPLAY_COMPANY_CARGOS :{BLACK}Display company cargos information
330a336
> STR_TOOLBAR_TOOLTIP_DISPLAY_WATCH :{BLACK}Watch company's actions
383a390
> STR_SETTINGS_MENU_ZONING :Zoning
407a415
> STR_MAP_MENU_WATCH_COMPANY :Watch Company
477c485,486
< STR_ABOUT_MENU_SEPARATOR :
---
> STR_ABOUT_MENU_SEPARATOR :CityMania
> STR_ABOUT_MENU_LOGIN_WINDOW :Server Login
1439a1449,1452
> STR_CONFIG_SETTING_PERSISTENT_DEPOTTOOLS :Keep depot building tools active after usage: {STRING2}
> STR_CONFIG_SETTING_PERSISTENT_DEPOTTOOLS_HELPTEXT :Keep the building tools for road, train and ship depots (reversible by placing with Ctrl).
> STR_CM_CONFIG_SETTING_IMPROVED_STATION_JOIN :Use improved station joining controls: {STRING2}
> STR_CM_CONFIG_SETTING_IMPROVED_STATION_JOIN_HELPTEXT :Use Ctrl-click on station tile to select or deselect station to join. If station has no tiles Ctrl-click its sign. Ctrl-click empty tile for a new station. Also recently built station is automatically selected as a station to join.
1745a1759,1778
> STR_CONFIG_SETTING_VEHICLES_CTRL :{ORANGE}Controls & Orders
> STR_CONFIG_SETTING_ORDER_SHORTCUTS :{ORANGE}Order's Shortcuts
> STR_CONFIG_SETTING_CTRL_ENABLE_CTRLCLICK_STARTSTOP :Allow ctrl+left-click vehicles to start or stop them: {STRING2}
> STR_CONFIG_SETTING_AUTOSET_NOLOAD_ON_TRANSFER :"Transfer" orders are "No Loading" by default: {STRING2}
> STR_CONFIG_SETTING_AUTOSET_NOLOAD_ON_UNLOAD :"Unload all" orders are "No Loading" by default: {STRING2}
>
> STR_CONFIG_SETTING_CTRL_GOTOSHORTCUT_CTRLLCLICK :ctrl+left-click: {STRING2}
> STR_CONFIG_SETTING_CTRL_GOTOSHORTCUT_CTRLSHIFTLCLICK :ctrl+shift+left-click: {STRING2}
> STR_CONFIG_SETTING_CTRL_GOTOSHORTCUT_SHIFTLCLICK :shift+left-click: {STRING2}
> STR_CONFIG_SETTING_CTRL_GOTOSHORTCUT_ALTLCLICK :alt+left-click: {STRING2}
> STR_CONFIG_SETTING_CTRL_GOTOSHORTCUT_ALTSHIFTCLICK :alt+shift+left-click: {STRING2}
> STR_CONFIG_SETTING_CTRL_GOTOSHORTCUT_CTRLALTLCLICK :ctrl+alt+left-click: {STRING2}
> STR_CONFIG_SETTING_CTRL_GOTOSHORTOPTS_NONE :do nothing
> STR_CONFIG_SETTING_CTRL_GOTOSHORTOPTS_FULL_LOAD_ANY :Full load any cargo
> STR_CONFIG_SETTING_CTRL_GOTOSHORTOPTS_TRANSFER_CARGO :Transfer cargo
> STR_CONFIG_SETTING_CTRL_GOTOSHORTOPTS_UNLOAD_ALL :Force unload of all cargo
> STR_CONFIG_SETTING_CTRL_GOTOSHORTOPTS_FEEDERLOAD :Feeder Load (replace first order)
> STR_CONFIG_SETTING_CTRL_GOTOSHORTOPTS_FEEDERDROP :Feeder Unload (replace last order)
> STR_CONFIG_SETTING_CTRL_GOTOSHORTOPTS_NO_LOAD :Do not load any cargo
>
2354a2388
> STR_RAIL_TOOLBAR_TOOLTIP_BUILD_POLYRAIL :{BLACK}Build railway track using the Polyline mode. Ctrl toggles build/remove for railway construction. Shift toggles building/showing cost estimate
2371a2406
> STR_BUILD_DEPOT_TRAIN_ORIENTATION_AUTO_TOOLTIP :{BLACK}Automatically select railway depot orientation based on environment
2379a2415,2416
> STR_STATION_BUILD_ORIENTATION_AUTO :{BLACK}Auto
> STR_STATION_BUILD_ORIENTATION_AUTO_TOOLTIP :{BLACK}Automatically select station orientation based on environment
2459a2497
> STR_BUILD_DEPOT_ROAD_ORIENTATION_AUTO_TOOLTIP :{BLACK}Automatically select road depot orientation based on environment
5062a5101,5103
> STR_VIEWPORT_TOWN_POP_VERY_POOR_RATING :{WHITE}{TOWN} {RED}({COMMA})
> STR_VIEWPORT_TOWN_POP_MEDIOCRE_RATING :{WHITE}{TOWN} {ORANGE}({COMMA})
> STR_VIEWPORT_TOWN_POP_GOOD_RATING :{WHITE}{TOWN} {YELLOW}({COMMA})
5063a5105
> STR_VIEWPORT_TOWN_POP_EXCELLENT_RATING :{WHITE}{TOWN} {GREEN}({COMMA})
5065a5108,5110
> STR_VIEWPORT_TOWN_TINY_VERY_POOR_RATING :{TINY_FONT}{RED}{TOWN}
> STR_VIEWPORT_TOWN_TINY_MEDIOCRE_RATING :{TINY_FONT}{ORANGE}{TOWN}
> STR_VIEWPORT_TOWN_TINY_GOOD_RATING :{TINY_FONT}{YELLOW}{TOWN}
5066a5112
> STR_VIEWPORT_TOWN_TINY_EXCELLENT_RATING :{TINY_FONT}{GREEN}{TOWN}
5151a5198,5518
>
> ### PATCH
> STR_TOWN_DIRECTORY_CAPTION_EXTRA :{WHITE}Towns ({YELLOW}{COMMA}{WHITE} / {ORANGE}{COMMA}{WHITE})
> STR_LOCAL_AUTHORITY_COMPANY_RATING_NUM :{YELLOW}{COMPANY} {COMPANY_NUM}: {ORANGE}{STRING} {BLACK}({COMMA})
> STR_TOWN_VIEW_GROWTH :{BLACK}GR: {ORANGE}{COMMA}{STRING} {BLACK}Next: {ORANGE}{COMMA} {BLACK}RH: {ORANGE}{COMMA} {BLACK}Flag {ORANGE}{NUM} {BLACK}FB: {ORANGE}{NUM} {BLACK}month{P "" s}
> STR_TOWN_VIEW_GROWTH_RATE_CUSTOM :*
> STR_TOWN_VIEW_GROWTH_TILES :{BLACK}HS: {ORANGE}{COMMA}(+{COMMA}) {BLACK}CS: {ORANGE}{COMMA}(+{COMMA}) {BLACK}HR: {ORANGE}{COMMA}(+{COMMA})
> STR_TOWN_VIEW_REALPOP_RATE :{BLACK}Real Population: {YELLOW}{COMMA} {BLACK}Rating: {YELLOW}{COMMA}
> STR_TOWN_VIEW_HOUSE_STATE :{BLACK}Houses: UC {ORANGE}{COMMA} {BLACK}RTM: {ORANGE}{COMMA} {BLACK}DTM: {ORANGE}{COMMA}
> STR_CB_DISTANCE_CHECK :CB town acceptance: {STRING2}
>
> ###ADMIN
> STR_WATCH_WINDOW_TITLE :{WHITE}Watching {RAW_STRING}.
> STR_WATCH_CLICK_TO_WATCH_COMPANY :{BLACK}Click here to watch company building
> STR_WATCH_CLICK_NEW_WINDOW :{BLACK}Click here to open new watching window
>
> STR_WATCH_WINDOW_TITLE_CLIENT :{WHITE}{RAW_STRING} in {RAW_STRING}({NUM}).
> STR_XI_KICK :{BLACK}Kick
> STR_XI_KICKC :{BLACK}Kick from cp
> STR_XI_BAN :{BLACK}Ban
> STR_XI_BAN1 :{BLACK}Ban (1 day)
> STR_XI_LOCK :{BLACK}Lock
> STR_XI_UNLOCK :{BLACK}UNLock
> STR_XI_JOIN :{BLACK}Join company
> STR_XI_RESET :{BLACK}Reset company
> STR_XI_WATCH :Watch
> STR_MOD_COMPANY_RESET_BUTTON :{BLACK}Reset
> STR_MOD_COMPANY_JOIN_BUTTON :{BLACK}Join as mod
> STR_MOD_TOGGLE_LOCK_BUTTON :{BLACK}Lock/unlock
> STR_XI_ENABLE :{BLACK}En/Dis
> STR_XI_SIGN_TOOLTIP :{BLACK}Put a sign to attract player
> STR_XI_PLAYERS_TOOLTIP :{BLACK}Show clients
> STR_XI_COMPANYW_TOOLTIP :{BLACK}Open Company window
> STR_XI_COMPANYHQ :{BLACK}HQ
> STR_XI_COMPANYHQ_TOOLTIP :{BLACK}Go to company's HQ
> STR_XI_PRIVATE_PLAYER_MESSAGE :{BLACK}.{GREEN}P{BLACK}.
> STR_XI_PRIVATE_PLAYER_MESSAGE_TOOLTIP :{BLACK}Send a Custom private message to this player
> STR_XI_PRIVATE_COMPANY_MESSAGE :{BLACK}.{GREEN}C{BLACK}.
> STR_XI_PRIVATE_COMPANY_MESSAGE_TOOLTIP :{BLACK}Send a Custom private message to this company
>
> STR_XI_BAN_QUERY :{WHITE}
> STR_XI_BAN_DAYSDEFAULT :1
> STR_XI_REALY_RESET :{WHITE}Are you sure?.
> STR_XI_RESET_CAPTION :{WHITE}Reset
>
> STR_NETWORK_CLIENT_EXTRA :{WHITE}(#{NUM} in c#{NUM})
>
> ######## Zoning toolbar
>
> STR_ZONING_TOOLBAR :{WHITE}Zoning toolbar
> STR_ZONING_OUTER :{BLACK}Outer tile borders:
> STR_ZONING_INNER :{BLACK}Inner tile borders:
> STR_ZONING_OUTER_INFO :{BLACK}Select which type of zoning you want on the outer border of a tile.
> STR_ZONING_INNER_INFO :{BLACK}Select which type of zoning you want on the inner border of a tile.
>
> STR_ZONING_NO_ZONING :{BLACK}Nothing
> STR_ZONING_AUTHORITY :{BLACK}Authority
> STR_ZONING_CAN_BUILD :{BLACK}Where I can't build
> STR_ZONING_STA_CATCH :{BLACK}Station catchment
> STR_ZONING_IND_CATCH :{BLACK}Industry catchment
> STR_ZONING_BUL_CATCH :{BLACK}City catchment
> STR_ZONING_BUL_UNSER :{BLACK}Unserved buildings
> STR_ZONING_IND_UNSER :{BLACK}Unserved industries
> STR_ZONING_TOWN_ZONES :{BLACK}Town zones
> STR_ZONING_CB_TOWN_BORDERS :{BLACK}CB town borders
> STR_ZONING_CB_BORDERS :{BLACK}CB borders
> STR_ZONING_NEW_CB_BORDERS :{BLACK}New CB borders
> STR_ZONING_ADVERTISEMENT_ZONES :{BLACK}Advertisement
> STR_ZONING_TOWN_GROWTH_TILES :{BLACK}Town growth tiles
> STR_ZONING_ACTIVE_STATIONS :{BLACK}Active stations
>
> # Commands toolbar
> STR_TOOLBAR_COMMANDS_CAPTION :{WHITE}Commands
> STR_TOOLBAR_COMMANDS_GOAL_CAPTION :{BLACK}Goal
> STR_TOOLBAR_COMMANDS_GOAL_TOOLTIP :{BLACK}Send !goal command to server.
> STR_TOOLBAR_COMMANDS_QUEST_CAPTION :{BLACK}Quest list
> STR_TOOLBAR_COMMANDS_QUEST_TOOLTIP :{BLACK}Send !quest command to server.
> STR_TOOLBAR_COMMANDS_SCORE_CAPTION :{BLACK}Score
> STR_TOOLBAR_COMMANDS_SCORE_TOOLTIP :{BLACK}Send !score command to server.
> STR_TOOLBAR_COMMANDS_TOWN_CAPTION :{BLACK}Town
> STR_TOOLBAR_COMMANDS_TOWN_TOOLTIP :{BLACK}Send !town command to server.
> STR_TOOLBAR_COMMANDS_TOWN_ID_CAPTION :{BLACK}Town ID
> STR_TOOLBAR_COMMANDS_TOWN_ID_TOOLTIP :{BLACK}Send !town c-id command to server.
> STR_TOOLBAR_COMMANDS_HINT_CAPTION :{BLACK}CB Hint
> STR_TOOLBAR_COMMANDS_HINT_TOOLTIP :{BLACK}Send !hint command to server(Shows town demand in CB mode).
> STR_TOOLBAR_COMMANDS_LOGIN_CAPTION :{BLACK}Login
> STR_TOOLBAR_COMMANDS_LOGIN_TOOLTIP :{BLACK}Send !login command to server.
> STR_TOOLBAR_COMMANDS_TIMELEFT_CAPTION :{BLACK}Timeleft
> STR_TOOLBAR_COMMANDS_TIMELEFT_TOOLTIP :{BLACK}Send !timeleft command to server.
> STR_TOOLBAR_COMMANDS_NS_CAPTION :{BLACK}CM{NUM}
> STR_TOOLBAR_COMMANDS_NS_TOOLTIP :{BLACK}Join CM{NUM}
> STR_TOOLBAR_COMMANDS_RESETME_CAPTION :{BLACK}ResetMe
> STR_TOOLBAR_COMMANDS_RESETME_TOOLTIP :{BLACK}Send !resetme command to server.
> STR_TOOLBAR_COMMANDS_SAVEME_CAPTION :{BLACK}SaveMe
> STR_TOOLBAR_COMMANDS_SAVEME_TOOLTIP :{BLACK}Send !saveme command to server.
> STR_TOOLBAR_COMMANDS_NAME_CAPTION :{BLACK}New name
> STR_TOOLBAR_COMMANDS_NAME_TOOLTIP :{BLACK}Send !name command to server.
> STR_TOOLBAR_COMMANDS_INFO_CAPTION :{BLACK}Info
> STR_TOOLBAR_COMMANDS_INFO_TOOLTIP :{BLACK}Send !info command to server.
>
> STR_TOOLBAR_COMMANDS_OPTION_CARGO_CAPTION :{BLACK}Both
> STR_TOOLBAR_COMMANDS_OPTION_CARGO_TOOLTIP :{BLACK}Switch cargo buttons to both amount and income
> STR_TOOLBAR_COMMANDS_OPTION_CARGO_I_CAPTION :{BLACK}Income
> STR_TOOLBAR_COMMANDS_OPTION_CARGO_A_CAPTION :{BLACK}Amount
> STR_TOOLBAR_COMMANDS_OPTION_CARGO_A_TOOLTIP :{BLACK}Switch cargo buttons to amount
> STR_TOOLBAR_COMMANDS_OPTION_CARGO_I_TOOLTIP :{BLACK}Switch cargo buttons to income
>
>
> STR_TOOLBAR_COMMANDS_TOWN_QUERY :{WHITE}Company ID:
> STR_TOOLBAR_COMMANDS_LOGIN_NAME_QUERY :{WHITE}
> STR_TOOLBAR_COMMANDS_LOGIN_PASSWORD_QUERY :{WHITE}Password:
> STR_TOOLBAR_COMMANDS_NAME_NEWNAME_QUERY :{WHITE}New name:
>
> STR_TOOLBAR_COMMANDS_TOPICS_CAPTION :{BLACK}Topics
> STR_TOOLBAR_COMMANDS_TOPICS_TOOLTIP :{BLACK}Display help topics
> STR_TOOLBAR_COMMANDS_TOPIC1_CAPTION :{BLACK}HELP Login
> STR_TOOLBAR_COMMANDS_TOPIC1_TOOLTIP :{BLACK}How to use login
> STR_TOOLBAR_COMMANDS_TOPIC2_CAPTION :{BLACK}HELP Coal Accept
> STR_TOOLBAR_COMMANDS_TOPIC2_TOOLTIP :{BLACK}What to do when town does not accept Coal
> STR_TOOLBAR_COMMANDS_TOPIC3_CAPTION :{BLACK}HELP Food accept
> STR_TOOLBAR_COMMANDS_TOPIC3_TOOLTIP :{BLACK}What to do when town does not accept Food
> STR_TOOLBAR_COMMANDS_TOPIC4_CAPTION :{BLACK}HELP energy
> STR_TOOLBAR_COMMANDS_TOPIC4_TOOLTIP :{BLACK}What are tourists, business mail or energy?
> STR_TOOLBAR_COMMANDS_TOPIC5_CAPTION :{BLACK}HELP admin
> STR_TOOLBAR_COMMANDS_TOPIC5_TOOLTIP :{BLACK}How to use admin command?
> STR_TOOLBAR_COMMANDS_TOPIC6_CAPTION :{BLACK}HELP New Comp.
> STR_TOOLBAR_COMMANDS_TOPIC6_TOOLTIP :{BLACK}Why new company can not be starter?
>
> STR_TOOLBAR_COMMANDS_HELP_CAPTION :{BLACK}Help
> STR_TOOLBAR_COMMANDS_HELP_TOOLTIP :{BLACK}Display Help
> STR_TOOLBAR_COMMANDS_RULES_CAPTION :{BLACK}RULES
> STR_TOOLBAR_COMMANDS_RULES_TOOLTIP :{BLACK}Show Rules
> STR_TOOLBAR_COMMANDS_CBHINT_CAPTION :{BLACK}CB Hint
> STR_TOOLBAR_COMMANDS_CBHINT_TOOLTIP :{BLACK}Display help for City builder
> STR_TOOLBAR_COMMANDS_BEST_CAPTION :{BLACK}Best
> STR_TOOLBAR_COMMANDS_BEST_TOOLTIP :{BLACK}Show 5 best games
> STR_TOOLBAR_COMMANDS_RANK_CAPTION :{BLACK}Rank
> STR_TOOLBAR_COMMANDS_RANK_TOOLTIP :{BLACK}Show top 10 players
> STR_TOOLBAR_COMMANDS_ME_CAPTION :{BLACK}My Rank
> STR_TOOLBAR_COMMANDS_ME_TOOLTIP :{BLACK}Show your ranking position
>
> #login window
> STR_LOGINWINDOW_CAPTION :{WHITE}Login Window
> STR_LOGINWINDOW_CITYMANIA :{BLACK}CityMania
> STR_LOGINWINDOW_NICE :{BLACK}N-ice
> STR_LOGINWINDOW_BTPRO :{BLACK}BTPro
> STR_LOGINERROR_NOCONNECT :{WHITE}Failed to connect
> STR_LOGINERROR_BADINPUT :{WHITE}Bad username or password
> STR_LOGIN_USERNAME :{WHITE}Username
> STR_LOGIN_PASSWORD :{WHITE}Password
> STR_LOGIN_SET :{WHITE}Set
> STR_LOGIN_NOTSET :{WHITE}Not Set
> STR_LOGIN_CHANGE_USERNAME :{WHITE}Change username
> STR_LOGIN_CHANGE_PASSWORD :{WHITE}Change password
> STR_LOGIN_SEND_LOGIN_TT :{WHITE}Send Login - you must but on the correct community server
> STR_LOGIN_USERNAME_DISPLAY :{WHITE}{RAW_STRING}
> STR_LOGIN_PASSWORD_DISPLAY :{WHITE}{STRING}
>
> #cargo table
> STR_TOOLBAR_CARGOS_HEADER_CARGO :{BLACK}Cargo Name
> STR_TOOLBAR_CARGOS_HEADER_AMOUNT :{BLACK}Amount
> STR_TOOLBAR_CARGOS_HEADER_INCOME :{BLACK}Income
> STR_TOOLBAR_CARGOS_HEADER_TOTAL :{BLACK}Total
> STR_TOOLBAR_CARGOS_HEADER_TOTAL_MONTH :{BLACK}Total this Month
>
> STR_TOOLBAR_CARGOS_UNITS :{BLACK}{COMMA}
> STR_TOOLBAR_CARGOS_UNITS_TOTAL :{BLACK}{COMMA}
> STR_TOOLBAR_CARGOS_CAPTION :{WHITE}{COMPANY} Cargo Transported {BLACK}{COMPANY_NUM}
> STR_TOOLBAR_CARGOS_NAME :{BLACK}{STRING}
>
> #towns
> STR_TOWN_DIRECTORY_TOWN_COLOUR :{ORANGE}{TOWN}{BLACK} ({COMMA}->{COMMA}) {YELLOW}{COMMA} {P "house" "houses"}
> STR_TOWN_DIRECTORY_CITY_COLOUR :{YELLOW}{TOWN}{BLACK} ({COMMA}->{COMMA}) {YELLOW}{COMMA} {P "house" "houses"}
> STR_OLD_DEPOT_TRAINT_LENGTH :Old depot length format: {STRING2}
> STR_SMALLMAP_TOWN_LARGE :{TINY_FONT}{YELLOW}{TOWN}
>
> STR_SORT_BY_HOUSES :Houses
> STR_SORT_BY_REAL_POPULATION :Real population
> STR_ORDER_DIST :{NUM}, {NUM}
>
> #server list
> STR_NETWORK_SELECT_CITYMANIA :{BLACK}CityMania
> STR_NETWORK_SELECT_NICE :{BLACK}N-ice
> STR_NETWORK_SELECT_BTPRO :{BLACK}BTPro
> STR_NETWORK_SELECT_REDDIT :{BLACK}reddit
> STR_NETWORK_SELECT_SERVER_TOOLTIP :{BLACK}Filter this one
>
> ### Town CB gui
> STR_BUTTON_CB :{STRING}
> STR_BUTTON_CB_YES :{BLACK}CB
> STR_TOWN_VIEW_CB_CAPTION :{WHITE}{TOWN}
>
> STR_CB_LARGE_ADVERTISING_CAMPAIGN :{BLACK}Large Advertising
> STR_CB_NEW_BUILDINGS :{BLACK}Fund Buildings
> STR_CB_FUND_REGULAR :{BLACK}Fund Regularly
> STR_CB_FUND_REGULAR_TT :{BLACK}Every time fund buildings is zero and company has enough money, buildings will be funded automatically
> STR_CB_FUNDED_REGULARLY :{GREEN}Town is funded regularly
> STR_CB_ADVERT_REGULAR :{BLACK}Adv. Regularly
> STR_CB_ADVERT_REGULAR_TT :{BLACK}Automatically advertise town whenever stations rating drops below a certain point
> STR_CB_POWERFUND :{BLACK}Powerfund
> STR_CB_ADVERT_REGULAR_RATING_TO_KEEP :{BLACK}Keep station rating at
> STR_CB_POWERFUND_TT :{BLACK}Continiously funds town with maximum speed possible
>
> STR_TOWN_CB_FUNDING :{ORANGE}Funded for {YELLOW}{COMMA}{ORANGE} month{P "" s}
> STR_TOWN_CB_GROWING :{GREEN}Town is growing!
> STR_TOWN_CB_NOT_GROWING :{WHITE}Town is not growing
> STR_TOWN_CB_GROWING_DETAIL :{ORANGE}1 house in {YELLOW}{COMMA} {ORANGE}days ({YELLOW}{COMMA}%{ORANGE}). Next House in {YELLOW}{COMMA} {ORANGE}days
>
> STR_TOWN_GROWTH_HEADER_CARGO :{BLACK}Cargo
> STR_TOWN_GROWTH_HEADER_AMOUNT :{BLACK}Delivered
> STR_TOWN_GROWTH_HEADER_REQ :{BLACK}Required
> STR_TOWN_GROWTH_HEADER_LAST :{BLACK}Last Month
> STR_TOWN_GROWTH_HEADER_STORE :{BLACK}Stored
> STR_TOWN_GROWTH_HEADER_STORE_PCT :{BLACK}Use%
> STR_TOWN_GROWTH_HEADER_FROM :{BLACK}From
>
> STR_TOWN_CB_CARGO_NAME :{BLACK}{STRING}:
>
> STR_TOWN_CB_CARGO_AMOUNT_GOOD :{GREEN}{COMMA}
> STR_TOWN_CB_CARGO_AMOUNT_BAD :{YELLOW}{COMMA}
> STR_TOWN_CB_CARGO_AMOUNT_NOT :{SILVER}{COMMA}
>
> STR_TOWN_CB_CARGO_REQ_YES :{ORANGE}{COMMA}
> STR_TOWN_CB_CARGO_REQ_NOT :{SILVER}{COMMA}
>
> STR_TOWN_CB_CARGO_STORE_YES :{LTBLUE}{COMMA}
> STR_TOWN_CB_CARGO_STORE_NOT :{SILVER}{COMMA}
> STR_TOWN_CB_CARGO_STORE_DECAY :{BLACK}-
>
> STR_TOWN_CB_CARGO_STORE_PCT_YES :{LTBLUE}{COMMA}%
> STR_TOWN_CB_CARGO_STORE_PCT_NOT :{SILVER}{COMMA}%
>
> STR_TOWN_CB_CARGO_PREVIOUS_YES :{GREEN}{COMMA}
> STR_TOWN_CB_CARGO_PREVIOUS_EDGE :{YELLOW}{COMMA}
> STR_TOWN_CB_CARGO_PREVIOUS_BAD :{RED}{COMMA}
> STR_TOWN_CB_CARGO_PREVIOUS_NOT :{SILVER}{COMMA}
>
> STR_TOWN_CB_CARGO_FROM_YES :{YELLOW}{COMMA}
> STR_TOWN_CB_CARGO_FROM_NOT :{SILVER}{COMMA}
>
> #polyrail double click option
> STR_CONFIG_SETTING_POLYRAIL_DOUBLECLICK_TOOLTIPS :Enable finishing polyrail with mouse double click{STRING2}
>
> #tooltips extra
> STR_CONFIG_SETTING_ENABLE_EXTRA_TOOLTIPS :Enable extra tooltips{STRING2}
> STR_TTE_HOUSE_NAME :{LTBLUE}{STRING}
> STR_TTE_HOUSE :{BLACK}Population: {NUM}
> STR_TTE_INDUSTRY_NAME :{LTBLUE}{INDUSTRY}
> STR_TTE_INDUSTRY :{WHITE}{STRING} {BLACK}{CARGO_SHORT} {YELLOW}{NUM} %
> STR_TTE_STATION_NAME :{LTBLUE}{STATION}
> STR_TTE_STATION :{WHITE}{STRING} {BLACK}{CARGO_SHORT} {YELLOW}{NUM} %
> STR_LAND_AREA_INFORMATION_POP :{BLACK}Population: {LTBLUE}{NUM}
>
> # Industry funding forbidden tiles
> STR_FUND_INDUSTRY_FORBIDDEN_TILES_TITLE :{BLACK}Forbidden areas highlight
> STR_FUND_INDUSTRY_FORBIDDEN_TILES_OFF :{BLACK}Off
> STR_FUND_INDUSTRY_FORBIDDEN_TILES_ON :{BLACK}On
> STR_FUND_INDUSTRY_FORBIDDEN_TILES_OFF_TOOLTIP :{BLACK}Don't highlight areas where particular industry can not be funded
> STR_FUND_INDUSTRY_FORBIDDEN_TILES_ON_TOOLTIP :{BLACK}Highlight areas where particular industry can not be funded
>
> STR_CB_GUI_TOWN_VIEW_BUTTON :{BLACK}Town view
> STR_CB_GUI_TOWN_VIEW_TOOLTIP :{BLACK}Show information on town
>
> STR_CONFIG_SETTING_WARN_IF_RUNWAY_IS_TOO_SHORT :Warn if airplane has in its orders an airport whose runway is too short
>
> STR_CONFIG_SETTING_POWERFUND_MONEY :Powerfund minimum needed money for fund: {STRING2}
> STR_CONFIG_SETTING_POWERFUND_HOUSES :Maximum amount of houses to powerfund up to: {STRING2}
>
> STR_STATION_RATING_TOOLTIP_RATING_DETAILS :{STRING} Rating Details
> STR_STATION_RATING_TOOLTIP_TOTAL_RATING :Total target rating: {LTBLUE}{NUM}%
> STR_STATION_RATING_TOOLTIP_NEWGRF_RATING :NewGRF station rating: {STRING1} {BLACK}based on
> STR_STATION_RATING_TOOLTIP_NEWGRF_RATING_0 :{GOLD}{NUM}%
> STR_STATION_RATING_TOOLTIP_NEWGRF_RATING_1 :{LTBLUE}+{NUM}%
> STR_STATION_RATING_TOOLTIP_NEWGRF_SPEED :Max speed of last vehicle: {LTBLUE}{VELOCITY}
> STR_STATION_RATING_TOOLTIP_NEWGRF_WAITUNITS :Units of cargo waiting: {LTBLUE}{NUM}
> STR_STATION_RATING_TOOLTIP_NEWGRF_WAITTIME :Time since last pickup: {LTBLUE}{NUM} days
>
> STR_STATION_RATING_TOOLTIP_SPEED :Max speed of last vehicle (max 17%): {STRING2}
> STR_STATION_RATING_TOOLTIP_SPEED_MAX :{GREEN}{VELOCITY} or more, +{NUM}%
> STR_STATION_RATING_TOOLTIP_SPEED_ZERO :{RED}{VELOCITY}, {NUM}%
> STR_STATION_RATING_TOOLTIP_SPEED_0 :{ORANGE}{VELOCITY}, +{NUM}%
> STR_STATION_RATING_TOOLTIP_SPEED_1 :{GOLD}{VELOCITY}, +{NUM}%
> STR_STATION_RATING_TOOLTIP_SPEED_2 :{YELLOW}{VELOCITY}, +{NUM}%
> STR_STATION_RATING_TOOLTIP_SPEED_3 :{GREEN}{VELOCITY}, +{NUM}%
>
> STR_STATION_RATING_TOOLTIP_AGE :Age of last vehicle (max 13%): {STRING2}
> STR_STATION_RATING_TOOLTIP_AGE_0 :{ORANGE}{NUM} years, {NUM}%
> STR_STATION_RATING_TOOLTIP_AGE_1 :{GOLD}{NUM} years, +{NUM}%
> STR_STATION_RATING_TOOLTIP_AGE_2 :{YELLOW}{NUM} year, +{NUM}%
> STR_STATION_RATING_TOOLTIP_AGE_3 :{GREEN}{NUM} years, +{NUM}%
>
> STR_STATION_RATING_TOOLTIP_WAITTIME :Time since last pickup (max 51%): {STRING2}
> STR_STATION_RATING_TOOLTIP_WAITTIME_SHIP :Time since last pickup (max 51%): {STRING2} (by ship)
> STR_STATION_RATING_TOOLTIP_WAITTIME_0 :{RED}{NUM} days, {NUM}%
> STR_STATION_RATING_TOOLTIP_WAITTIME_1 :{ORANGE}{NUM} days, +{NUM}%
> STR_STATION_RATING_TOOLTIP_WAITTIME_2 :{GOLD}{NUM} days, +{NUM}%
> STR_STATION_RATING_TOOLTIP_WAITTIME_3 :{YELLOW}{NUM} days, +{NUM}%
> STR_STATION_RATING_TOOLTIP_WAITTIME_4 :{GREEN}{NUM} day{P "" s}, +{NUM}%
>
> STR_STATION_RATING_TOOLTIP_WAITUNITS :Units of cargo waiting (max 16%): {STRING2}
> STR_STATION_RATING_TOOLTIP_WAITUNITS_0 :{RED}{NUM}, {NUM}%
> STR_STATION_RATING_TOOLTIP_WAITUNITS_1 :{ORANGE}{NUM}, {NUM}%
> STR_STATION_RATING_TOOLTIP_WAITUNITS_2 :{GOLD}{NUM}, {NUM}%
> STR_STATION_RATING_TOOLTIP_WAITUNITS_3 :{YELLOW}{NUM}, +{NUM}%
> STR_STATION_RATING_TOOLTIP_WAITUNITS_4 :{YELLOW}{NUM}, +{NUM}%
> STR_STATION_RATING_TOOLTIP_WAITUNITS_5 :{GREEN}{NUM}, +{NUM}%
>
> STR_STATION_RATING_TOOLTIP_STATUE :Statue in town (max 10%): {STRING}
> STR_STATION_RATING_TOOLTIP_STATUE_NO :{GOLD}no, 0%
> STR_STATION_RATING_TOOLTIP_STATUE_YES :{GREEN}yes, +10%
>
> STR_IGNORE_VERSION_CHECK_WARNING : WARNING! You're about to join server running a different version of the game!
> STR_IGNORE_VERSION_CHECK_WARNING_DETAILS : OpenTTD was never indended to work in such way. If you're lucky you may be able to play it but most likely something is going to break sooner or later. Desyncs or crashes are to be expected. So proceed at your own risk and don't report any errors you encounter there.
> STR_CM_STATION_BUILD_TOWN :{BLACK}Town: {GOLD}{TOWN}
> STR_CM_STATION_BUILD_TOWN_LARGE :{BLACK}Town: {GOLD}{TOWN} (L)
> STR_CM_STATION_BUILD_TOWN_MEDIUM :{BLACK}Town: {GOLD}{TOWN} (M)
> STR_CM_STATION_BUILD_TOWN_SMALL :{BLACK}Town: {GOLD}{TOWN} (S)
> STR_CM_CONFIG_SETTING_OPEN_VEHICLE_FOR_SHARED_CLONE :Open vehicle window for shared clones: {STRING2}
> STR_CM_CONFIG_SETTING_OPEN_VEHICLE_FOR_SHARED_CLONE_HELPTEXT :Open vehicle window when cloning vehicles with shared orders (as it does for non-shared ones)
> STR_CM_CONFIG_SETTING_OPEN_ORDERS_FOR_NEW_VEHICLES :Open orders window for new vehicles: {STRING2}
> STR_CM_CONFIG_SETTING_OPEN_ORDERS_FOR_NEW_VEHICLES_HELPTEXT :Automatically open oreders windown along with a vehicle window for a new vehicles
\ No newline at end of file
diff -r -B -X .diff-exclude vanilla/src/lang/english_US.txt cmclient/src/lang/english_US.txt
251a252
> STR_TOOLTIP_DEMOLISH_TREES :{BLACK}Demolish only trees on a square of land. Ctrl selects the area diagonally.
diff -r -B -X .diff-exclude vanilla/src/main_gui.cpp cmclient/src/main_gui.cpp
105c105
< if (w->IsWidgetLowered(widget)) {
---
> if (w->IsWidgetLowered(widget) && mode == _thd.place_mode) {
233a234
> GHK_BORROW_ALL,
401a403,406
> case GHK_BORROW_ALL:
> DoCommandP(0, 0, 1, CMD_INCREASE_LOAN | CMD_MSG(STR_ERROR_CAN_T_BORROW_ANY_MORE_MONEY));
> break;
>
471a477,481
> virtual void OnMouseOver(Point pt, int widget)
> {
> if (_game_mode != GM_MENU && _settings_client.gui.enable_extra_tooltips && pt.x != -1) GuiPrepareTooltipsExtra(this);
> }
>
518a529
> Hotkey(WKC_NONE, "borrow_all", GHK_BORROW_ALL),
diff -r -B -X .diff-exclude vanilla/src/map.cpp cmclient/src/map.cpp
14a15
> #include "citymania/highlight.hpp"
63a65
> citymania::AllocateZoningMap(_map_size);
diff -r -B -X .diff-exclude vanilla/src/misc.cpp cmclient/src/misc.cpp
122a123
> ResetRailPlacementEndpoints();
diff -r -B -X .diff-exclude vanilla/src/misc_gui.cpp cmclient/src/misc_gui.cpp
25a26
> #include "newgrf_cargo.h"
32a34,39
> #include "house.h"
> #include "town_map.h"
> #include "station_base.h"
> #include "viewport_func.h"
> #include "industry.h"
>
34a42,45
> extern const Station *_viewport_highlight_station; // CM
>
> void GuiShowTooltipsExtra(Window *parent, uint param, TooltipCloseCondition close_tooltip);
>
45,50c56
< NWidget(NWID_HORIZONTAL),
< NWidget(WWT_CLOSEBOX, COLOUR_GREY),
< NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_LAND_AREA_INFORMATION_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
< NWidget(WWT_DEBUGBOX, COLOUR_GREY),
< EndContainer(),
< NWidget(WWT_PANEL, COLOUR_GREY, WID_LI_BACKGROUND), EndContainer(),
---
> NWidget(WWT_PANEL, COLOUR_GREY, WID_LI_BACKGROUND), SetMinimalSize(64, 32), EndContainer(),
54c60
< WDP_AUTO, "land_info", 0, 0,
---
> WDP_MANUAL, "land_info", 0, 0,
71a78,89
> TileIndex end_tile; ///< For use in ruler(dragdrop) mode
>
> virtual Point OnInitialPosition(int16 sm_width, int16 sm_height, int window_number)
> {
> int scr_top = GetMainViewTop() + 2;
> int scr_bot = GetMainViewBottom() - 2;
> Point pt;
> pt.y = Clamp(_cursor.pos.y + _cursor.total_size.y + _cursor.total_offs.y + 5, scr_top, scr_bot);
> if (pt.y + sm_height > scr_bot) pt.y = min(_cursor.pos.y + _cursor.total_offs.y - 5, scr_bot) - sm_height;
> pt.x = sm_width >= _screen.width ? 0 : Clamp(_cursor.pos.x - (sm_width >> 1), 0, _screen.width - sm_width);
> return pt;
> }
76a95,99
> GfxDrawLine(r.left, r.top, r.right, r.top, PC_BLACK);
> GfxDrawLine(r.left, r.bottom, r.right, r.bottom, PC_BLACK);
> GfxDrawLine(r.left, r.top, r.left, r.bottom, PC_BLACK);
> GfxDrawLine(r.right, r.top, r.right, r.bottom, PC_BLACK);
>
115c138,139
< LandInfoWindow(TileIndex tile) : Window(&_land_info_desc), tile(tile)
---
> LandInfoWindow(TileIndex tile, TileIndex end_tile=INVALID_TILE) :
> Window(&_land_info_desc), tile(tile), end_tile(end_tile)
117a142
> CLRBITS(this->flags, WF_WHITE_BORDER);
170a196
> td.population = 0;
324a351,357
> /* House pop */
> if (td.population != 0) {
> SetDParam(0, td.population);
> GetString(this->landinfo_data[line_nr], STR_LAND_AREA_INFORMATION_POP, lastof(this->landinfo_data[line_nr]));
> line_nr++;
> }
>
377a411,428
>
> virtual void OnMouseLoop()
> {
> /* Always close tooltips when the cursor is not in our window. */
> if (!_cursor.in_window) {
> delete this;
> return;
> }
> if (!_mouse_hovering) delete this;
>
> /* We can show tooltips while dragging tools. These are shown as long as
> * we are dragging the tool. Normal tooltips work with hover or rmb. */
> // switch (this->close_cond) {
> // case TCC_RIGHT_CLICK: if (!_right_button_down) delete this; break;
> // case TCC_LEFT_CLICK: if (!_left_button_down) delete this; break;
> // case TCC_HOVER: if (!_mouse_hovering) delete this; break;
> // }
> }
384c435
< void ShowLandInfo(TileIndex tile)
---
> void ShowLandInfo(TileIndex tile, TileIndex end_tile)
387c438
< new LandInfoWindow(tile);
---
> new LandInfoWindow(tile, end_tile);
1275a1327,1813
> }
>
> /** Window for displaying a tooltip. */
> void GuiPrepareTooltipsExtra(Window *parent){
> const Point p = GetTileBelowCursor();
> if (p.x == -1) return;
> const TileIndex tile = TileVirtXY(p.x, p.y);
>
> if (_cursor.sprite_seq[0].sprite == SPR_CURSOR_QUERY) {
> // Land info tool active
> ShowLandInfo(tile);
> return;
> }
>
> if (!_settings_client.gui.enable_extra_tooltips)
> return;
>
> if (tile >= MapSize()) return;
> uint param = 0;
> switch (GetTileType(tile)) {
> /*case MP_HOUSE: {
> const HouseID house = GetHouseType(tile);
> param = ((house & 0xFFFF) << 16) | MP_HOUSE;
> break;
> }*/
> case MP_INDUSTRY: {
> const Industry *ind = Industry::GetByTile(tile);
> if(ind->produced_cargo[0] == CT_INVALID && ind->produced_cargo[1] == CT_INVALID) return;
> param = ((ind->index & 0xFFFF) << 16) | MP_INDUSTRY;
> break;
> }
> case MP_STATION: {
> if (IsRailWaypoint(tile) || HasTileWaterGround(tile)) break;
> const Station *st = Station::GetByTile(tile);
> param |= ((st->index & 0xFFFF) << 16) | MP_STATION;
> break;
> }
> default:
> return;
> }
> if(param != 0) GuiShowTooltipsExtra(parent, param, TCC_HOVER);
> }
>
> static const NWidgetPart _nested_tooltips_extra_widgets[] = {
> NWidget(WWT_PANEL, COLOUR_GREY, WID_TT_BACKGROUND), SetMinimalSize(64, 32), EndContainer(),
> };
>
> static WindowDesc _tool_tips_extra_desc(
> WDP_MANUAL, NULL, 0, 0,
> WC_TOOLTIPS_EXTRA, WC_NONE,
> 0,
> _nested_tooltips_extra_widgets, lengthof(_nested_tooltips_extra_widgets)
> );
>
> struct TooltipsExtraWindow : public Window
> {
> TileType tiletype;
> uint16 objIndex;
> TooltipCloseCondition close_cond;
>
> TooltipsExtraWindow(Window *parent, uint param, TooltipCloseCondition close_tooltip) : Window(&_tool_tips_extra_desc)
> {
> this->parent = parent;
> this->tiletype = (TileType)(param & 0xFFFF);
> this->objIndex = (uint16)((param >> 16) & 0xFFFF);
> this->close_cond = close_tooltip;
> this->InitNested();
> CLRBITS(this->flags, WF_WHITE_BORDER);
> }
>
> virtual Point OnInitialPosition(int16 sm_width, int16 sm_height, int window_number)
> {
> int scr_top = GetMainViewTop() + 2;
> int scr_bot = GetMainViewBottom() - 2;
> Point pt;
> pt.y = Clamp(_cursor.pos.y + _cursor.total_size.y + _cursor.total_offs.y + 5, scr_top, scr_bot);
> if (pt.y + sm_height > scr_bot) pt.y = min(_cursor.pos.y + _cursor.total_offs.y - 5, scr_bot) - sm_height;
> pt.x = sm_width >= _screen.width ? 0 : Clamp(_cursor.pos.x - (sm_width >> 1), 0, _screen.width - sm_width);
> return pt;
> }
>
> virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
> {
> uint icon_size = ScaleGUITrad(10);
> uint line_height = max((uint)FONT_HEIGHT_NORMAL, icon_size) + 2;
> uint icons_width = icon_size * 3 + 20;
> size->width = 200;
> size->height = FONT_HEIGHT_NORMAL + 6;
> switch(this->tiletype) {
> /*case MP_HOUSE: {
> size->height += LINE_HEIGHT;
> SetDParam(0, 1000);
> size->width = GetStringBoundingBox(STR_TTE_HOUSE).width;
> break;
> }*/
> case MP_INDUSTRY: {
> const Industry *ind = Industry::GetIfValid((IndustryID)this->objIndex);
> if(ind == NULL) break;
>
> for (CargoID i = 0; i < lengthof(ind->produced_cargo); i++) {
> if (ind->produced_cargo[i] == CT_INVALID) continue;
> const CargoSpec *cs = CargoSpec::Get(ind->produced_cargo[i]);
> if(cs == NULL) continue;
> size->height += line_height;
> SetDParam(0, cs->name);
> SetDParam(1, cs->Index());
> SetDParam(2, ind->last_month_production[i]);
> SetDParam(3, ToPercent8(ind->last_month_pct_transported[i]));
> size->width = max(GetStringBoundingBox(STR_TTE_INDUSTRY).width + icons_width, size->width);
> }
> break;
> }
> case MP_STATION: {
> const Station *st = Station::GetIfValid((StationID)this->objIndex);
> if(st == NULL) break;
>
> for (int i = 0; i < _sorted_standard_cargo_specs_size; i++) {
> const CargoSpec *cs = _sorted_cargo_specs[i];
> if(cs == NULL) continue;
> int cargoid = cs->Index();
> if (HasBit(st->goods[cargoid].status, GoodsEntry::GES_RATING)) {
> size->height += line_height;
> SetDParam(0, cs->name);
> SetDParam(1, cargoid);
> SetDParam(2, st->goods[cargoid].cargo.TotalCount());
> SetDParam(3, ToPercent8(st->goods[cargoid].rating));
> size->width = max(GetStringBoundingBox(STR_TTE_STATION).width + icons_width, size->width);
> }
> }
> break;
> }
> default:
> break;
> }
> size->width += 2 + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
> size->height += 2 + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
> }
>
> virtual void DrawWidget(const Rect &r, int widget) const
> {
> uint icon_size = ScaleGUITrad(10);
> uint line_height = max((uint)FONT_HEIGHT_NORMAL, icon_size) + 2;
> uint icons_width = icon_size * 3 + 10;
> uint text_ofs = (line_height - FONT_HEIGHT_NORMAL) >> 1;
> uint icon_ofs = (line_height - icon_size) >> 1;
>
> GfxDrawLine(r.left, r.top, r.right, r.top, PC_BLACK);
> GfxDrawLine(r.left, r.bottom, r.right, r.bottom, PC_BLACK);
> GfxDrawLine(r.left, r.top, r.left, r.bottom, PC_BLACK);
> GfxDrawLine(r.right, r.top, r.right, r.bottom, PC_BLACK);
>
> int y = r.top + WD_FRAMERECT_TOP + 4;
> int left = r.left + WD_FRAMERECT_LEFT + 4;
>
> switch(this->tiletype) {
> /*case MP_HOUSE: {
> const HouseID house = (HouseID)this->objIndex;
> const HouseSpec *hs = HouseSpec::Get(house);
> if(hs == NULL) break;
>
> SetDParam(0, hs->building_name);
> DrawString(left, r.right - WD_FRAMERECT_RIGHT, y, STR_TTE_HOUSE_NAME, TC_BLACK, SA_CENTER);
> y += LINE_HEIGHT;
> SetDParam(0, hs->population);
> DrawString(left, r.right - WD_FRAMERECT_RIGHT, y, STR_TTE_HOUSE);
> break;
> }*/
> case MP_INDUSTRY: {
> const Industry *ind = Industry::GetIfValid((IndustryID)this->objIndex);
> if(ind == NULL) break;
>
> SetDParam(0, ind->index);
> DrawString(left, r.right - WD_FRAMERECT_RIGHT, y, STR_TTE_INDUSTRY_NAME, TC_BLACK, SA_CENTER);
> y += FONT_HEIGHT_NORMAL + 2;
>
> for (CargoID i = 0; i < lengthof(ind->produced_cargo); i++) {
> if (ind->produced_cargo[i] == CT_INVALID) continue;
> const CargoSpec *cs = CargoSpec::Get(ind->produced_cargo[i]);
> if(cs == NULL) continue;
> SetDParam(0, cs->name);
> SetDParam(1, cs->Index());
> SetDParam(2, ind->last_month_production[i]);
> SetDParam(3, ToPercent8(ind->last_month_pct_transported[i]));
>
> this->DrawSpriteIcons(cs->GetCargoIcon(), left, y + icon_ofs);
> DrawString(left + icons_width, r.right - WD_FRAMERECT_RIGHT, y + text_ofs, STR_TTE_INDUSTRY);
> y += line_height;
> }
> break;
> }
> case MP_STATION: {
> const Station *st = Station::GetIfValid((StationID)this->objIndex);
> if(st == NULL) break;
>
> SetDParam(0, st->index);
> DrawString(left, r.right - WD_FRAMERECT_RIGHT, y, STR_TTE_STATION_NAME, TC_BLACK, SA_CENTER);
> y += FONT_HEIGHT_NORMAL + 2;
>
> for (int i = 0; i < _sorted_standard_cargo_specs_size; i++) {
> const CargoSpec *cs = _sorted_cargo_specs[i];
> if(cs == NULL) continue;
> int cargoid = cs->Index();
> if (HasBit(st->goods[cargoid].status, GoodsEntry::GES_RATING)) {
> SetDParam(0, cs->name);
> SetDParam(1, cargoid);
> SetDParam(2, st->goods[cargoid].cargo.TotalCount());
> SetDParam(3, ToPercent8(st->goods[cargoid].rating));
>
> this->DrawSpriteIcons(cs->GetCargoIcon(), left, y + icon_ofs);
> DrawString(left + icons_width, r.right - WD_FRAMERECT_RIGHT, y + text_ofs, STR_TTE_STATION);
> y += line_height;
> }
> }
> break;
> }
> default:
> break;
> }
> }
>
> virtual void OnMouseLoop()
> {
> if (!_cursor.in_window) {
> delete this;
> return;
> }
>
> switch (this->close_cond) {
> case TCC_RIGHT_CLICK: if (!_right_button_down) delete this; break;
> case TCC_HOVER: if (!_mouse_hovering) delete this; break;
> case TCC_NONE: break;
> }
> }
>
> void DrawSpriteIcons(SpriteID sprite, int left, int top) const
> {
> uint step = ScaleGUITrad(10);
> for(int i = 0; i < 3; i++) {
> DrawSprite(sprite, PAL_NONE, left + i * step, top);
> }
> }
> };
>
> static const NWidgetPart _nested_station_rating_tooltip_widgets[] = {
> NWidget(WWT_PANEL, COLOUR_GREY, WID_TT_BACKGROUND), SetMinimalSize(64, 32), EndContainer(),
> };
>
> static WindowDesc _station_rating_tooltip_desc(
> WDP_MANUAL, NULL, 0, 0,
> WC_STATION_RATING_TOOLTIP, WC_NONE,
> 0,
> _nested_tooltips_extra_widgets, lengthof(_nested_station_rating_tooltip_widgets)
> );
>
> static const int STATION_RATING_AGE[] = {0, 10, 20, 33};
> static const int STATION_RATING_WAITTIME[] = {0, 25, 50, 95, 130};
> static const int STATION_RATING_WAITUNITS[] = {-90, -35, 0, 10, 30, 40};
>
>
> struct StationRatingTooltipWindow : public Window
> {
> TileType tiletype;
> uint16 objIndex;
> TooltipCloseCondition close_cond;
> const Station *st;
> const CargoSpec *cs;
> bool newgrf_rating_used;
>
> static const uint RATING_TOOLTIP_LINE_BUFF_SIZE = 512;
> static const uint RATING_TOOLTIP_MAX_LINES = 8;
> static const uint RATING_TOOLTIP_NEWGRF_INDENT = 20;
>
> public:
> char data[RATING_TOOLTIP_MAX_LINES + 1][RATING_TOOLTIP_LINE_BUFF_SIZE];
>
> StationRatingTooltipWindow(Window *parent, const Station *st, const CargoSpec *cs) : Window(&_station_rating_tooltip_desc)
> {
> this->parent = parent;
> this->st = st;
> this->cs = cs;
> this->InitNested();
> CLRBITS(this->flags, WF_WHITE_BORDER);
> }
>
> virtual Point OnInitialPosition(int16 sm_width, int16 sm_height, int window_number)
> {
> int scr_top = GetMainViewTop() + 2;
> int scr_bot = GetMainViewBottom() - 2;
> Point pt;
> pt.y = Clamp(_cursor.pos.y + _cursor.total_size.y + _cursor.total_offs.y + 5, scr_top, scr_bot);
> if (pt.y + sm_height > scr_bot) pt.y = min(_cursor.pos.y + _cursor.total_offs.y - 5, scr_bot) - sm_height;
> pt.x = sm_width >= _screen.width ? 0 : Clamp(_cursor.pos.x - (sm_width >> 1), 0, _screen.width - sm_width);
> return pt;
> }
>
> int RoundRating(int rating) {
> // if (rating >= 0) {
> // return rating * 101 +
> // }
> return RoundDivSU(rating * 101, 256);
> }
>
> virtual void OnInit() {
> const GoodsEntry *ge = &this->st->goods[this->cs->Index()];
>
> SetDParam(0, this->cs->name);
> GetString(this->data[0], STR_STATION_RATING_TOOLTIP_RATING_DETAILS, lastof(this->data[0]));
> if (!ge->HasRating()) {
> this->data[1][0] = '\0';
> return;
> }
>
> uint line_nr = 1;
> int total_rating = 0;
>
> if (HasBit(cs->callback_mask, CBM_CARGO_STATION_RATING_CALC)) {
> uint last_speed = ge->HasVehicleEverTriedLoading() ? ge->last_speed : 0xFF;
>
> uint32 var18 = min(ge->time_since_pickup, 0xFF) | (min(ge->max_waiting_cargo, 0xFFFF) << 8) | (min(last_speed, 0xFF) << 24);
> uint32 var10 = (this->st->last_vehicle_type == VEH_INVALID) ? 0x0 : (this->st->last_vehicle_type + 0x10);
> uint16 callback = GetCargoCallback(CBID_CARGO_STATION_RATING_CALC, var10, var18, this->cs);
> int newgrf_rating = 0;
> if (callback != CALLBACK_FAILED) {
> newgrf_rating = GB(callback, 0, 14);
> if (HasBit(callback, 14)) newgrf_rating -= 0x4000;
>
> this->newgrf_rating_used = true;
>
> total_rating += newgrf_rating;
> newgrf_rating = this->RoundRating(newgrf_rating);
>
> SetDParam(0, STR_STATION_RATING_TOOLTIP_NEWGRF_RATING_0 + (newgrf_rating <= 0 ? 0 : 1));
> SetDParam(1, newgrf_rating);
> GetString(this->data[line_nr], STR_STATION_RATING_TOOLTIP_NEWGRF_RATING, lastof(this->data[line_nr]));
> line_nr++;
>
> SetDParam(0, min(last_speed, 0xFF));
> GetString(this->data[line_nr], STR_STATION_RATING_TOOLTIP_NEWGRF_SPEED, lastof(this->data[line_nr]));
> line_nr++;
>
> SetDParam(0, min(ge->max_waiting_cargo, 0xFFFF));
> GetString(this->data[line_nr], STR_STATION_RATING_TOOLTIP_NEWGRF_WAITUNITS, lastof(this->data[line_nr]));
> line_nr++;
>
> SetDParam(0, (min(ge->time_since_pickup, 0xFF) * 5 + 1) / 2);
> GetString(this->data[line_nr], STR_STATION_RATING_TOOLTIP_NEWGRF_WAITTIME, lastof(this->data[line_nr]));
> line_nr++;
> }
> }
>
> if (!this->newgrf_rating_used) {
>
> byte waittime = ge->time_since_pickup;
> if (this->st->last_vehicle_type == VEH_SHIP) waittime >>= 2;
> int waittime_stage = 0;
> (waittime > 21) ||
> (waittime_stage = 1, waittime > 12) ||
> (waittime_stage = 2, waittime > 6) ||
> (waittime_stage = 3, waittime > 3) ||
> (waittime_stage = 4, true);
> total_rating += STATION_RATING_WAITTIME[waittime_stage];
>
> SetDParam(0, STR_STATION_RATING_TOOLTIP_WAITTIME_0 + waittime_stage);
> SetDParam(1, (ge->time_since_pickup * 5 + 1) / 2);
> SetDParam(2, this->RoundRating(STATION_RATING_WAITTIME[waittime_stage]));
> GetString(this->data[line_nr], this->st->last_vehicle_type == VEH_SHIP ? STR_STATION_RATING_TOOLTIP_WAITTIME_SHIP : STR_STATION_RATING_TOOLTIP_WAITTIME, lastof(this->data[line_nr]));
> line_nr++;
>
> uint waitunits = ge->max_waiting_cargo;
> int waitunits_stage = 0;
> (waitunits > 1500) ||
> (waitunits_stage = 1, waitunits > 1000) ||
> (waitunits_stage = 2, waitunits > 600) ||
> (waitunits_stage = 3, waitunits > 300) ||
> (waitunits_stage = 4, waitunits > 100) ||
> (waitunits_stage = 5, true);
> total_rating += STATION_RATING_WAITUNITS[waitunits_stage];
>
> SetDParam(0, STR_STATION_RATING_TOOLTIP_WAITUNITS_0 + waitunits_stage);
> SetDParam(1, ge->max_waiting_cargo);
> SetDParam(2, this->RoundRating(STATION_RATING_WAITUNITS[waitunits_stage]));
> GetString(this->data[line_nr], STR_STATION_RATING_TOOLTIP_WAITUNITS, lastof(this->data[line_nr]));
> line_nr++;
>
> int b = ge->last_speed - 85;
> int r_speed = b >= 0 ? b >> 2 : 0;
> int r_speed_round = this->RoundRating(r_speed);
> total_rating += r_speed;
> if (ge->last_speed == 255) {
> SetDParam(0, STR_STATION_RATING_TOOLTIP_SPEED_MAX);
> } else if (r_speed_round == 0) {
> SetDParam(0, STR_STATION_RATING_TOOLTIP_SPEED_ZERO);
> } else {
> SetDParam(0, STR_STATION_RATING_TOOLTIP_SPEED_0 + r_speed / 11);
> }
> SetDParam(0, ge->last_speed == 255 ? STR_STATION_RATING_TOOLTIP_SPEED_MAX : STR_STATION_RATING_TOOLTIP_SPEED_0 + r_speed / 11);
> SetDParam(1, ge->last_speed);
> SetDParam(2, r_speed_round);
> GetString(this->data[line_nr], STR_STATION_RATING_TOOLTIP_SPEED, lastof(this->data[line_nr]));
> line_nr++;
> }
>
> int age_stage = (ge->last_age >= 3 ? 0 : 3 - ge->last_age);
> total_rating += STATION_RATING_AGE[age_stage];
> SetDParam(0, STR_STATION_RATING_TOOLTIP_AGE_0 + age_stage);
> SetDParam(1, ge->last_age);
> SetDParam(2, this->RoundRating(STATION_RATING_AGE[age_stage]));
> GetString(this->data[line_nr], STR_STATION_RATING_TOOLTIP_AGE, lastof(this->data[line_nr]));
> line_nr++;
>
> if (Company::IsValidID(st->owner) && HasBit(st->town->statues, st->owner)) {
> SetDParam(0, STR_STATION_RATING_TOOLTIP_STATUE_YES);
> total_rating += 26;
> } else {
> SetDParam(0, STR_STATION_RATING_TOOLTIP_STATUE_NO);
> }
> GetString(this->data[line_nr], STR_STATION_RATING_TOOLTIP_STATUE, lastof(this->data[line_nr]));
> line_nr++;
>
> SetDParam(0, ToPercent8(Clamp(total_rating, 0, 255)));
> GetString(this->data[line_nr], STR_STATION_RATING_TOOLTIP_TOTAL_RATING, lastof(this->data[line_nr]));
> line_nr++;
>
> this->data[line_nr][0] = '\0';
> }
>
> virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
> {
> if (widget != WID_LI_BACKGROUND) return;
>
> size->height = WD_FRAMETEXT_TOP + WD_FRAMETEXT_BOTTOM + 2;
> for (uint i = 0; i <= RATING_TOOLTIP_MAX_LINES; i++) {
> if (StrEmpty(this->data[i])) break;
>
> uint width = GetStringBoundingBox(this->data[i]).width + WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT + 2;
> if (this->newgrf_rating_used && i >= 2 && i <= 4)
> width += RATING_TOOLTIP_NEWGRF_INDENT;
> size->width = max(size->width, width);
> size->height += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL;
> }
> size->height -= WD_PAR_VSEP_NORMAL;
> }
>
> virtual void DrawWidget(const Rect &r, int widget) const
> {
> GfxDrawLine(r.left, r.top, r.right, r.top, PC_BLACK);
> GfxDrawLine(r.left, r.bottom, r.right, r.bottom, PC_BLACK);
> GfxDrawLine(r.left, r.top, r.left, r.bottom, PC_BLACK);
> GfxDrawLine(r.right, r.top, r.right, r.bottom, PC_BLACK);
>
> int y = r.top + WD_FRAMETEXT_TOP + 1;
> int left0 = r.left + WD_FRAMETEXT_LEFT + 1;
> int right0 = r.right - WD_FRAMETEXT_RIGHT - 1;
> DrawString(left0, right0, y, this->data[0], TC_LIGHT_BLUE, SA_CENTER);
> y += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL;
> for (uint i = 1; i <= RATING_TOOLTIP_MAX_LINES; i++) {
> if (StrEmpty(this->data[i])) break;
> int left = left0, right = right0;
> if (this->newgrf_rating_used && i >= 2 && i <= 4) {
> if (_current_text_dir == TD_RTL) {
> right -= RATING_TOOLTIP_NEWGRF_INDENT;
> } else {
> left += RATING_TOOLTIP_NEWGRF_INDENT;
> }
> }
> DrawString(left, right, y, this->data[i], TC_BLACK);
> y += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL;
> }
> }
>
> virtual void OnMouseLoop()
> {
> if (!_cursor.in_window || !_mouse_hovering) {
> delete this;
> }
> }
> };
>
> void GuiShowTooltipsExtra(Window *parent, uint param, TooltipCloseCondition close_tooltip)
> {
> DeleteWindowById(WC_TOOLTIPS_EXTRA, 0);
> new TooltipsExtraWindow(parent, param, close_tooltip);
> }
>
> void GuiShowStationRatingTooltip(Window *parent, const Station *st, const CargoSpec *cs) {
> DeleteWindowById(WC_STATION_RATING_TOOLTIP, 0);
> new StationRatingTooltipWindow(parent, st, cs);
diff -r -B -X .diff-exclude vanilla/src/network/network_client.cpp cmclient/src/network/network_client.cpp
34c33,35
< #include "../safeguards.h"
---
> #include "../town.h"
> #include "network_func.h"
> #include "../newgrf_revisions.hpp"
35a37
> #include "../safeguards.h"
37a40,43
> void SyncCMUser(const char *msg);
> // extern const std::map OPENTTD_NEWGRF_VERSIONS;
> // extern const std::map OPENTTD_RELEASE_REVISIONS;
> static const uint32 OPENTTD_NEWGRF_REVISION_MASK = (1 << 19) - 1;
323a330,331
> /** Server revision to use when fooling revision check */
> const char *_network_join_server_revision = NULL;
353,354c361,384
< p->Send_string(GetNetworkRevisionString());
< p->Send_uint32(_openttd_newgrf_version);
---
> if (_network_join_server_revision) {
> auto r = _network_join_server_revision;
> p->Send_string(r);
> auto nr = OPENTTD_NEWGRF_VERSIONS.find(r);
> uint32 rev;
> if (nr != OPENTTD_NEWGRF_VERSIONS.end()) {
> p->Send_uint32(nr->second);
> } else if (r[0] == 'r' && r[6] == 0 && (rev = strtoul(r + 1, nullptr, 10)) > 0) {
> // assume it's nightly
> uint32 max_rev = 0;
> // find release closest to the nightly
> for (auto &kv: OPENTTD_RELEASE_REVISIONS) {
> if (kv.first > max_rev && kv.first <= rev)
> max_rev = kv.first;
> }
> p->Send_uint32(OPENTTD_RELEASE_REVISIONS.at(max_rev) |
> (rev & OPENTTD_NEWGRF_REVISION_MASK));
> } else {
> p->Send_uint32(_openttd_newgrf_version);
> }
> } else {
> p->Send_string(GetNetworkRevisionString());
> p->Send_uint32(_openttd_newgrf_version);
> }
636a667,670
> InvalidateWindowClassesData(WC_WATCH_COMPANY, 0);
> SetWindowClassesDirty(WC_WATCH_COMPANY);
> InvalidateWindowData(WC_WATCH_COMPANYA, ci->client_id, 1);
> SetWindowClassesDirty(WC_WATCH_COMPANYA);
655a690,693
> InvalidateWindowClassesData(WC_WATCH_COMPANY, 0);
> SetWindowClassesDirty(WC_WATCH_COMPANY);
> InvalidateWindowData(WC_WATCH_COMPANYA, ci->client_id, 1);
> SetWindowClassesDirty(WC_WATCH_COMPANYA);
1018c1056,1057
< NetworkTextMessage(action, GetDrawStringCompanyColour(ci->client_playas), self_send, name, msg, data);
---
> if (strncmp(msg, "synccmuser", 10) == 0) SyncCMUser(msg);
> else NetworkTextMessage(action, GetDrawStringCompanyColour(ci->client_playas), self_send, name, msg, data);
1054a1094,1095
> InvalidateWindowClassesData( WC_WATCH_COMPANYA, 0 );
> SetWindowClassesDirty( WC_WATCH_COMPANYA );
1144a1186,1187
> InvalidateWindowClassesData( WC_WATCH_COMPANYA, 0 );
> SetWindowClassesDirty( WC_WATCH_COMPANYA );
1288a1332,1335
> void NetworkClientSendChatToServer(const char * msg)
> {
> NetworkClientSendChat(NETWORK_ACTION_CHAT_CLIENT, DESTTYPE_CLIENT, CLIENT_ID_SERVER, msg);
> }
1331a1379,1386
>
> void SyncCMUser(const char *msg) {
> uint user_id, role;
> sscanf(msg + 10, "%u %u", &user_id, &role);
> _novarole = (role >= 50);
> DEBUG(net, 1, "CityMania user synchronized: %u %u", user_id, role);
> }
>
diff -r -B -X .diff-exclude vanilla/src/network/network_client.h cmclient/src/network/network_client.h
115a116
> extern const char *_network_join_server_revision;
diff -r -B -X .diff-exclude vanilla/src/network/network.cpp cmclient/src/network/network.cpp
81c81
<
---
> bool _novarole = false;
111a112
> InvalidateWindowData(WC_WATCH_COMPANYA, this->client_id, 2);
diff -r -B -X .diff-exclude vanilla/src/network/network_func.h cmclient/src/network/network_func.h
37c37
<
---
> extern bool _novarole;
55a56
> void NetworkClientSendChatToServer(const char * msg);
diff -r -B -X .diff-exclude vanilla/src/network/network_gui.cpp cmclient/src/network/network_gui.cpp
39a40,43
> #include "../error.h"
> #include "../zoom_func.h"
> #include "../watch_gui.h"
>
235a240
> bool UDP_CC_queried;
389a395
> int lock_y_offset = (this->resize.step_height - GetSpriteSize(SPR_LOCK).height) / 2;
434c440
< if (cur_item->info.use_password) DrawSprite(SPR_LOCK, PAL_NONE, nwi_info->pos_x + this->lock_offset, y + icon_y_offset - 1);
---
> if (cur_item->info.use_password) DrawSprite(SPR_LOCK, PAL_NONE, nwi_info->pos_x + this->lock_offset, y + lock_y_offset);
437c443
< DrawSprite(SPR_BLOT, (cur_item->info.compatible ? PALETTE_TO_GREEN : (cur_item->info.version_compatible ? PALETTE_TO_YELLOW : PALETTE_TO_RED)), nwi_info->pos_x + this->blot_offset, y + icon_y_offset);
---
> DrawSprite(SPR_BLOT, (cur_item->info.compatible ? PALETTE_TO_GREEN : (cur_item->info.version_compatible ? PALETTE_TO_YELLOW : PALETTE_TO_RED)), nwi_info->pos_x + this->blot_offset, y + icon_y_offset + 1);
440c446
< DrawSprite(SPR_FLAGS_BASE + cur_item->info.server_lang, PAL_NONE, nwi_info->pos_x + this->flag_offset, y + icon_y_offset);
---
> DrawSprite(SPR_FLAGS_BASE + cur_item->info.server_lang, PAL_NONE, nwi_info->pos_x + this->flag_offset, y + (this->resize.step_height - GetSpriteSize(SPR_FLAGS_BASE + cur_item->info.server_lang).height) / 2);
475a482
> this->UDP_CC_queried = false;
612c619
< !sel->info.compatible); // Revision mismatch
---
> (!sel->info.compatible && !_ctrl_pressed)); // Revision mismatch
770a778,788
> if (this->server->info.compatible) {
> _network_join_server_revision = NULL;
> } else {
> _network_join_server_revision = this->server->info.server_revision;
> ShowErrorMessage(STR_IGNORE_VERSION_CHECK_WARNING,
> STR_IGNORE_VERSION_CHECK_WARNING_DETAILS,
> WL_WARNING,
> 0, 0,
> NULL, 0, NULL);
> // ShowGoalQuestion(0, 2 /* WARNING */, 2 /* OK */, "Full-tile autoroad tool is deprecated and will be removed in next release.\n Use regular autoroad tool instead.");
> }
785a804,820
> case WID_NG_NICE:
> case WID_NG_BTPRO:
> case WID_NG_REDDIT:
> case WID_NG_CITYMANIA:
> if(!UDP_CC_queried){
> NetworkUDPQueryMasterServer();
> UDP_CC_queried = true;
> }
> if(widget == WID_NG_NICE) this->filter_editbox.text.Assign("n-ice");
> else if(widget == WID_NG_BTPRO) this->filter_editbox.text.Assign("BTPro");
> else if(widget == WID_NG_CITYMANIA) this->filter_editbox.text.Assign("citymania");
> else if(widget == WID_NG_REDDIT) this->filter_editbox.text.Assign("reddit");
> this->servers.ForceRebuild();
> this->BuildGUINetworkGameList();
> this->ScrollToSelectedServer();
> this->SetDirty();
> break;
916c951
< Listing NetworkGameWindow::last_sorting = {false, 5};
---
> Listing NetworkGameWindow::last_sorting = {false, 0};
952a988,991
> NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NG_CITYMANIA), SetFill(1, 0), SetDataTip(STR_NETWORK_SELECT_CITYMANIA, STR_NETWORK_SELECT_SERVER_TOOLTIP),
> NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NG_BTPRO), SetFill(1, 0), SetDataTip(STR_NETWORK_SELECT_BTPRO, STR_NETWORK_SELECT_SERVER_TOOLTIP),
> NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NG_NICE), SetFill(1, 0), SetDataTip(STR_NETWORK_SELECT_NICE, STR_NETWORK_SELECT_SERVER_TOOLTIP),
> NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NG_REDDIT), SetFill(1, 0), SetDataTip(STR_NETWORK_SELECT_REDDIT, STR_NETWORK_SELECT_SERVER_TOOLTIP),
1393c1432
< resize->height = WD_MATRIX_TOP + FONT_HEIGHT_NORMAL + WD_MATRIX_BOTTOM;
---
> resize->height = WD_MATRIX_TOP + max(max(GetSpriteSize(SPR_LOCK).height, GetSpriteSize(SPR_PROFIT_LOT).height), (uint)FONT_HEIGHT_NORMAL) + WD_MATRIX_BOTTOM;
1394a1434
> size->width = ScaleGUITrad(146);
1446a1487
> uint text_offset = (this->resize.step_height - WD_MATRIX_TOP - WD_MATRIX_BOTTOM - FONT_HEIGHT_NORMAL) / 2 + WD_MATRIX_TOP;
1450c1491
< int lock_y_offset = (this->resize.step_height - WD_MATRIX_TOP - WD_MATRIX_BOTTOM - lock_size.height) / 2;
---
> int lock_y_offset = (this->resize.step_height - lock_size.height) / 2;
1454c1495
< int profit_y_offset = (this->resize.step_height - WD_MATRIX_TOP - WD_MATRIX_BOTTOM - profit_size.height) / 2;
---
> int profit_y_offset = (this->resize.step_height - profit_size.height) / 2;
1461c1502
< int y = r.top + WD_MATRIX_TOP;
---
> int y = r.top;
1468c1509
< GfxFillRect(r.left + 1, y - 2, r.right - 1, y + FONT_HEIGHT_NORMAL, PC_GREY); // show highlighted item with a different colour
---
> GfxFillRect(r.left + 1, y + 1, r.right - 1, y + this->resize.step_height - 1, PC_GREY); // show highlighted item with a different colour
1471c1512
< DrawString(text_left, text_right, y, this->company_info[company].company_name, TC_BLACK);
---
> DrawString(text_left, text_right, y + text_offset, this->company_info[company].company_name, TC_BLACK);
1697a1739,1746
> static void ClientList_Watch(const NetworkClientInfo *ci)
> {
> if (ci != NULL){
> CompanyID cid = (CompanyID)ci->client_id;
> ShowWatchWindow(cid, 1);
> }
> }
>
1771a1821,1823
> if (_network_own_client_id != ci->client_id && ci->client_id != CLIENT_ID_SERVER && _novarole) {
> this->AddAction(STR_XI_WATCH, &ClientList_Watch);
> }
1915,1916c1967,1970
<
< size->width = WD_FRAMERECT_LEFT + this->server_client_width + this->icon_size.width + WD_FRAMERECT_LEFT + width + WD_FRAMERECT_RIGHT;
---
> SetDParam(0, 0xFFFF);
> SetDParam(1, INVALID_COMPANY);
> uint width2 = GetStringBoundingBox(STR_NETWORK_CLIENT_EXTRA).width;
> size->width = WD_FRAMERECT_LEFT + this->server_client_width + this->icon_size.width + WD_FRAMERECT_LEFT + width + WD_FRAMERECT_RIGHT + width2;
1966a2021,2025
>
> uint extra = GetStringBoundingBox(ci->client_name).width + 15;
> SetDParam(0, ci->client_id);
> SetDParam(1, ci->client_playas == INVALID_COMPANY ? ci->client_playas : ci->client_playas + 1);
> DrawString(rtl ? left : name_left + extra, rtl ? name_right - extra : right, y + text_offset, STR_NETWORK_CLIENT_EXTRA, TC_FROMSTRING, SA_RIGHT);
diff -r -B -X .diff-exclude vanilla/src/newgrf_debug_gui.cpp cmclient/src/newgrf_debug_gui.cpp
459a460
> this->DrawString(r, i++, "Industry type: %d", (int)((const Industry *)base)->type);
Only in cmclient/src: newgrf_revisions.hpp
diff -r -B -X .diff-exclude vanilla/src/newgrf_spritegroup.cpp cmclient/src/newgrf_spritegroup.cpp
180,183c180,184
< case DSGA_OP_SDIV: return value == 0 ? (S)last_value : (S)last_value / (S)value;
< case DSGA_OP_SMOD: return value == 0 ? (S)last_value : (S)last_value % (S)value;
< case DSGA_OP_UDIV: return value == 0 ? (U)last_value : (U)last_value / (U)value;
< case DSGA_OP_UMOD: return value == 0 ? (U)last_value : (U)last_value % (U)value;
---
> // replaced ?: with if to avoid VS2015U3 optimizator bug
> case DSGA_OP_SDIV: if (value == 0) return (S)last_value; else return (S)last_value / (S)value;
> case DSGA_OP_SMOD: if (value == 0) return (S)last_value; else return (S)last_value % (S)value;
> case DSGA_OP_UDIV: if (value == 0) return (U)last_value; else return (U)last_value / (U)value;
> case DSGA_OP_UMOD: if (value == 0) return (U)last_value; else return (U)last_value % (U)value;
diff -r -B -X .diff-exclude vanilla/src/openttd.cpp cmclient/src/openttd.cpp
69a70,71
> #include "citymania/highlight.hpp"
>
962a965
> citymania::InitializeZoningMap();
978a982
> citymania::InitializeZoningMap();
diff -r -B -X .diff-exclude vanilla/src/order_cmd.cpp cmclient/src/order_cmd.cpp
1773a1774
> _settings_client.gui.runway_too_short_warn &&
diff -r -B -X .diff-exclude vanilla/src/order_gui.cpp cmclient/src/order_gui.cpp
173a174,245
> struct OrdersFromSettings
> {
> enum OrderUnloadFlags unload;
> enum OrderLoadFlags load;
> };
>
> typedef enum {
> GOFS_NONE = 0,
> GOFS_FULL,
> GOFS_XFER,
> GOFS_UNLOAD,
> GOFS_FEEDLOAD,
> GOFS_FEEDUNLOAD,
> GOFS_NOLOAD
> } GetOrderFromSettingsTypes;
>
> static enum {
> GOFS_FEEDER_NULL,
> GOFS_FEEDER_LOAD,
> GOFS_FEEDER_UNLOAD
> } gofsfeeder_ordermod = GOFS_FEEDER_NULL;
>
> #define GOFSFEEDER_ORDERMOD_RESET gofsfeeder_ordermod = GOFS_FEEDER_NULL
>
>
> /* fetch and compute orders set from settings */
>
> static void GetOrdersFromSettings(const Vehicle *v, uint8 setting, struct OrdersFromSettings *rv)
> {
> rv->load = (enum OrderLoadFlags)-1;
> rv->unload = (enum OrderUnloadFlags)-1;
>
> switch(setting) {
>
> case GOFS_FEEDLOAD:
> if (v->GetNumOrders()) gofsfeeder_ordermod = GOFS_FEEDER_LOAD;
> rv->unload = OUFB_NO_UNLOAD;
> rv->load = OLF_FULL_LOAD_ANY;
> break;
> case GOFS_FULL:
> rv->load = OLF_FULL_LOAD_ANY;
> break;
>
> case GOFS_UNLOAD:
> rv->unload = OUFB_UNLOAD;
> if (_settings_client.gui.auto_noload_on_unloadall)
> rv->load = OLFB_NO_LOAD;
> break;
>
> case GOFS_FEEDUNLOAD:
> if (v->GetNumOrders()) gofsfeeder_ordermod = GOFS_FEEDER_UNLOAD;
> rv->unload = OUFB_TRANSFER;
> rv->load = OLFB_NO_LOAD;
> break;
>
> case GOFS_XFER:
> rv->unload = OUFB_TRANSFER;
> if (_settings_client.gui.auto_noload_on_transfer)
> rv->load = OLFB_NO_LOAD;
> break;
>
> case GOFS_NOLOAD:
> rv->load = OLFB_NO_LOAD;
> break;
>
> case GOFS_NONE:
> break;
>
> default: NOT_REACHED();
> }
> }
>
348a421,433
>
> uint order_dist_sq = 0;
> uint order_dist_mh = 0;
> const Order *next2 = order->next != NULL ? order->next : v->GetFirstOrder();
> TileIndex prev_tile = order->GetLocation(v, true);
> TileIndex cur_tile = next2->GetLocation(v, true);
> if (prev_tile != INVALID_TILE && cur_tile != INVALID_TILE){
> order_dist_sq = IntSqrt(DistanceSquare(prev_tile, cur_tile));
> order_dist_mh = DistanceManhattan(prev_tile, cur_tile);
> }
> SetDParam(0, order_dist_sq);
> SetDParam(1, order_dist_mh);
> DrawString(middle, right, y, STR_ORDER_DIST, TC_WHITE, SA_RIGHT);
412c497,524
< if (_ctrl_pressed) order.SetLoadType(OLF_FULL_LOAD_ANY);
---
>
> uint8 os = 0xff;
> if (_ctrl_pressed) {
> if (_shift_pressed)
> os = _settings_client.gui.goto_shortcuts_ctrlshift_lclick;
> else if (_alt_pressed)
> os = _settings_client.gui.goto_shortcuts_altctrl_lclick;
> else
> os = _settings_client.gui.goto_shortcuts_ctrl_lclick;
> }
> else if (_shift_pressed) {
> if (_alt_pressed)
> os = _settings_client.gui.goto_shortcuts_altshift_lclick;
> else
> os = _settings_client.gui.goto_shortcuts_shift_lclick;
> }
> else if (_alt_pressed)
> os = _settings_client.gui.goto_shortcuts_alt_lclick;
>
> if (os != 0xff) {
> struct OrdersFromSettings ofs;
> GetOrdersFromSettings(v, os, &ofs);
> if (ofs.load != (enum OrderLoadFlags)-1)
> order.SetLoadType(ofs.load);
> if (ofs.unload != (enum OrderUnloadFlags)-1)
> order.SetUnloadType(ofs.unload);
> }
>
437a550
> OHK_CLOSE,
645a759,765
> bool set_no_load = false;
> if (unload_type == OUFB_TRANSFER){
> set_no_load = _settings_client.gui.auto_noload_on_transfer;
> }
> else if (unload_type == OUFB_UNLOAD){
> set_no_load = _settings_client.gui.auto_noload_on_unloadall;
> }
647c767
< if (unload_type == OUFB_TRANSFER) {
---
> if (set_no_load) {
1433a1554,1558
> if(hotkey == OHK_GOTO && this->goto_type != OPOS_NONE){
> this->RaiseWidget(WID_O_GOTO);
> ResetObjectToPlace();
> return ES_NOT_HANDLED;
> }
1446a1572
> case OHK_CLOSE: delete this; break;
1458c1584,1598
< if (DoCommandP(this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), cmd.Pack(), CMD_INSERT_ORDER | CMD_MSG(STR_ERROR_CAN_T_INSERT_NEW_ORDER))) {
---
> if (gofsfeeder_ordermod != GOFS_FEEDER_NULL) {
> if (gofsfeeder_ordermod == GOFS_FEEDER_LOAD) {
> if (DoCommandP(this->vehicle->tile, this->vehicle->index + ((1) << 20), cmd.Pack(), CMD_INSERT_ORDER | CMD_NO_ESTIMATE | CMD_MSG(STR_ERROR_CAN_T_INSERT_NEW_ORDER))) {
> DoCommandP(this->vehicle->tile, this->vehicle->index, 0, CMD_DELETE_ORDER | CMD_NO_ESTIMATE | CMD_MSG(STR_ERROR_CAN_T_DELETE_THIS_ORDER));
> }
>
> }
> else if (gofsfeeder_ordermod == GOFS_FEEDER_UNLOAD) { // still flushes the whole order table
> if (DoCommandP(this->vehicle->tile, this->vehicle->index + ((this->vehicle->GetNumOrders()) << 20), cmd.Pack(), CMD_INSERT_ORDER | CMD_NO_ESTIMATE | CMD_MSG(STR_ERROR_CAN_T_INSERT_NEW_ORDER))) {
> DoCommandP(this->vehicle->tile, this->vehicle->index, (this->vehicle->GetNumOrders()-2+(int)_networking) , CMD_DELETE_ORDER | CMD_NO_ESTIMATE | CMD_MSG(STR_ERROR_CAN_T_DELETE_THIS_ORDER));
> }
> }
> gofsfeeder_ordermod = GOFS_FEEDER_NULL;
> }
> else if (DoCommandP(this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), cmd.Pack(), CMD_INSERT_ORDER | CMD_NO_ESTIMATE | CMD_MSG(STR_ERROR_CAN_T_INSERT_NEW_ORDER))) {
1535a1676
> Hotkey('Q', "close", OHK_CLOSE),
diff -r -B -X .diff-exclude vanilla/src/os/macosx/osx_stdafx.h cmclient/src/os/macosx/osx_stdafx.h
85a86
> #include
Only in cmclient/src/os/windows: ottdres.rc
diff -r -B -X .diff-exclude vanilla/src/rail_cmd.cpp cmclient/src/rail_cmd.cpp
45a46,47
> uint8 _sorted_railtypes_size;
> TileIndex _rail_track_endtile; ///< The end of a rail track; as hidden return from the rail build/remove command for GUI purposes.
448a451,452
> _rail_track_endtile = INVALID_TILE;
>
465c469,472
< if (ret.Failed()) return ret;
---
> if (ret.Failed()) {
> if (ret.GetErrorMessage() == STR_ERROR_ALREADY_BUILT) _rail_track_endtile = tile;
> return ret;
> }
562a570
> _rail_track_endtile = tile;
605a614
> _rail_track_endtile = tile;
623a633,634
> _rail_track_endtile = INVALID_TILE;
>
752a764
> _rail_track_endtile = tile;
885a898,899
> _rail_track_endtile = INVALID_TILE;
>
896a911
> TileIndex last_endtile = _rail_track_endtile;
900a916
> if (_rail_track_endtile == INVALID_TILE) _rail_track_endtile = last_endtile;
diff -r -B -X .diff-exclude vanilla/src/rail_gui.cpp cmclient/src/rail_gui.cpp
40a41,42
> #include "citymania/station_ui.hpp"
>
44c46
< static RailType _cur_railtype; ///< Rail type of the current build-rail toolbar.
---
> RailType _cur_railtype; ///< Rail type of the current build-rail toolbar.
52a55,56
> extern TileIndex _rail_track_endtile; // rail_cmd.cpp
>
55a60,64
> static const int HOTKEY_POLYRAIL = 0x1000;
> static const int HOTKEY_NEW_POLYRAIL = 0x1001;
> static const int HOTKEY_BUILD_STATION_SIZED = 0x1010; ///< Build a station in fixed size mode.
> static const int HOTKEY_BUILD_STATION_DRAGDROP = 0x1011; ///< Build a station in dragdrop mode.
>
64c73
< static RailStationGUISettings _railstation; ///< Settings of the station builder GUI
---
> RailStationGUISettings _railstation; ///< Settings of the station builder GUI
92c101
< static void GenericPlaceRail(TileIndex tile, int cmd)
---
> static CommandContainer GenericPlaceRailCmd(TileIndex tile, Track track)
94,98c103,114
< DoCommandP(tile, _cur_railtype, cmd,
< _remove_button_clicked ?
< CMD_REMOVE_SINGLE_RAIL | CMD_MSG(STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK) :
< CMD_BUILD_SINGLE_RAIL | CMD_MSG(STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK),
< CcPlaySound_SPLAT_RAIL);
---
> CommandContainer ret = {
> tile, // tile
> _cur_railtype, // p1
> track, // p2
> _remove_button_clicked ?
> CMD_REMOVE_SINGLE_RAIL | CMD_MSG(STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK) :
> CMD_BUILD_SINGLE_RAIL | CMD_MSG(STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK), // cmd
> CcPlaySound_SPLAT_RAIL, // callback
> "" // text
> };
>
> return ret;
277a294
> StoreRailPlacementEndpoints(tile, _build_tunnel_endtile, TileX(tile) == TileX(_build_tunnel_endtile) ? TRACK_Y : TRACK_X, false);
307c324
< if ((i <= WID_RAT_AUTORAIL || i >= WID_RAT_BUILD_WAYPOINT) && w->IsWidgetLowered(i)) {
---
> if ((i <= WID_RAT_POLYRAIL || i >= WID_RAT_BUILD_WAYPOINT) && w->IsWidgetLowered(i)) {
351c368
< static void DoRailroadTrack(int mode)
---
> static CommandContainer DoRailroadTrackCmd(TileIndex start_tile, TileIndex end_tile, Track track)
353,357c370,381
< DoCommandP(TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), _cur_railtype | (mode << 6),
< _remove_button_clicked ?
< CMD_REMOVE_RAILROAD_TRACK | CMD_MSG(STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK) :
< CMD_BUILD_RAILROAD_TRACK | CMD_MSG(STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK),
< CcPlaySound_SPLAT_RAIL);
---
> CommandContainer ret = {
> start_tile, // tile
> end_tile, // p1
> (uint32)(_cur_railtype | (track << 6)), // p2
> _remove_button_clicked ?
> CMD_REMOVE_RAILROAD_TRACK | CMD_MSG(STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK) :
> CMD_BUILD_RAILROAD_TRACK | CMD_MSG(STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK), // cmd
> CcPlaySound_SPLAT_RAIL, // callback
> "" // text
> };
>
> return ret;
362,366c386,408
< int trackstat = _thd.drawstyle & HT_DIR_MASK; // 0..5
<
< if (_thd.drawstyle & HT_RAIL) { // one tile case
< GenericPlaceRail(TileVirtXY(_thd.selend.x, _thd.selend.y), trackstat);
< return;
---
> Track track = (Track)(_thd.drawstyle & HT_DIR_MASK); // 0..5
> TileIndex start_tile = TileVirtXY(_thd.selstart.x, _thd.selstart.y);
> TileIndex end_tile = TileVirtXY(_thd.selend.x, _thd.selend.y);
>
> CommandContainer cmd = (_thd.drawstyle & HT_RAIL) ?
> GenericPlaceRailCmd(end_tile, track) : // one tile case
> DoRailroadTrackCmd(start_tile, end_tile, track); // multitile selection
>
> /* When overbuilding existing tracks in polyline mode we want to move the
> * snap point over the last overbuilt track piece. In such case we don't
> * wan't to show any errors to the user. Don't execute the command right
> * away, first check if overbuilding. */
> if (_shift_pressed || !(_thd.place_mode & HT_POLY) ||
> DoCommand(&cmd, DC_AUTO | DC_NO_WATER).GetErrorMessage() != STR_ERROR_ALREADY_BUILT ||
> _rail_track_endtile == INVALID_TILE) {
> /* Execute. */
> if (!DoCommandP(&cmd)) return;
> }
>
> /* Save new snap points for the polyline tool, no matter if the command
> * succeeded, the snapping will be extended over overbuilt track pieces. */
> if (!_shift_pressed && _rail_track_endtile != INVALID_TILE) {
> StoreRailPlacementEndpoints(start_tile, _rail_track_endtile, track, true);
368,369d409
<
< DoRailroadTrack(trackstat);
415a456,522
> // FIXME duplicate from road_gui.cpp
> static DiagDirection TileFractCoordsToDiagDir() {
> bool diag = (_tile_fract_coords.x + _tile_fract_coords.y) < 16;
> if (_tile_fract_coords.x < _tile_fract_coords.y) {
> return diag ? DIAGDIR_NE : DIAGDIR_SE;
> }
> return diag ? DIAGDIR_NW : DIAGDIR_SW;
> }
>
> // FIXME duplicate from road_gui.cpp
> static DiagDirection RoadBitsToDiagDir(RoadBits bits) {
> if (bits < ROAD_SE) {
> return bits == ROAD_NW ? DIAGDIR_NW : DIAGDIR_SW;
> }
> return bits == ROAD_SE ? DIAGDIR_SE : DIAGDIR_NE;
> }
>
> RoadBits FindRailsToConnect(TileIndex tile) {
> RoadBits directed = ROAD_NONE;
> RoadBits passing = ROAD_NONE;
> DiagDirection ddir;
> for (ddir = DIAGDIR_BEGIN; ddir < DIAGDIR_END; ddir++) {
> TileIndex cur_tile = TileAddByDiagDir(tile, ddir);
> if (HasStationTileRail(cur_tile)) {
> if (GetRailStationTrackBits(cur_tile) & DiagdirReachesTracks(ddir)) {
> directed |= DiagDirToRoadBits(ddir);
> }
> continue;
> }
> if (!IsTileType(cur_tile, MP_RAILWAY)) continue;
> if (!IsPlainRail(cur_tile)) continue;
> passing |= DiagDirToRoadBits(ddir);
> if (GetTrackBits(cur_tile) & DiagdirReachesTracks(ddir)) {
> directed |= DiagDirToRoadBits(ddir);
> }
> }
> // Prioritize track bits that head in this direction
> if (directed != ROAD_NONE) {
> return directed;
> }
> return passing;
> }
>
> /*
> * Selects orientation for rail object (depot)
> */
> static DiagDirection AutodetectRailObjectDirection(TileIndex tile) {
> RoadBits bits = FindRailsToConnect(tile);
> // FIXME after this point repeats road autodetection
> if (HasExactlyOneBit(bits)) return RoadBitsToDiagDir(bits);
> if (bits == ROAD_NONE) bits = ROAD_ALL;
> RoadBits frac_bits = DiagDirToRoadBits(TileFractCoordsToDiagDir());
> if (HasExactlyOneBit(frac_bits & bits)) {
> return RoadBitsToDiagDir(frac_bits & bits);
> }
> frac_bits |= MirrorRoadBits(frac_bits);
> if (HasExactlyOneBit(frac_bits & bits)) {
> return RoadBitsToDiagDir(frac_bits & bits);
> }
> for (DiagDirection ddir = DIAGDIR_BEGIN; ddir < DIAGDIR_END; ddir++) {
> if (DiagDirToRoadBits(ddir) & bits) {
> return ddir;
> }
> }
> NOT_REACHED();
> }
>
463a571
> this->GetWidget(WID_RAT_POLYRAIL)->widget_data = rti->gui_sprites.auto_rail;
491a600
> case WID_RAT_POLYRAIL:
522a632,640
> virtual void DrawWidget(const Rect &r, int widget) const
> {
> if (widget == WID_RAT_POLYRAIL) {
> Dimension d = GetSpriteSize(SPR_BLOT);
> uint offset = this->IsWidgetLowered(WID_RAT_POLYRAIL) ? 1 : 0;
> DrawSprite(SPR_BLOT, PALETTE_TO_GREY, (r.left + r.right - d.width) / 2 + offset, (r.top + r.bottom - d.height) / 2 + offset);
> }
> }
>
525a644
> bool remove_on_ctrl = true; /* do not check ctrl for hotkeys */
553a673,704
> case WID_RAT_POLYRAIL: {
> bool was_snap = GetRailSnapMode() == RSM_SNAP_TO_RAIL;
> bool was_open = this->IsWidgetLowered(WID_RAT_POLYRAIL);
> bool do_snap;
> bool do_open;
> /* "polyrail" hotkey - activate polyline tool in snapping mode, close the tool if snapping mode is already active
> * "new_polyrail" hotkey - activate polyline tool in non-snapping (new line) mode, close the tool if non-snapping mode is already active
> * button ctrl-clicking - switch between snapping and non-snapping modes, open the tool in non-snapping mode if it is closed
> * button clicking - open the tool in non-snapping mode, close the tool if it is opened */
> if (this->last_user_action == HOTKEY_POLYRAIL) {
> do_snap = true;
> do_open = !was_open || !was_snap;
> } else if (this->last_user_action == HOTKEY_NEW_POLYRAIL) {
> do_snap = false;
> do_open = !was_open || was_snap;
> } else if (_ctrl_pressed) {
> do_snap = !was_open || !was_snap;
> do_open = true;
> } else {
> do_snap = false;
> do_open = !was_open;
> }
> /* close/open the tool */
> if (was_open != do_open) HandlePlacePushButton(this, WID_RAT_POLYRAIL, GetRailTypeInfo(railtype)->cursor.autorail, HT_RAIL | HT_POLY);
> /* set snapping mode */
> if (do_open) SetRailSnapMode(do_snap ? RSM_SNAP_TO_RAIL : RSM_NO_SNAP);
>
> this->last_user_action = WID_RAT_POLYRAIL;
> if (was_open == do_open) return; // prevent switching the "remove" button state
> break;
> }
>
574,577c725,743
< case WID_RAT_BUILD_STATION:
< if (HandlePlacePushButton(this, WID_RAT_BUILD_STATION, SPR_CURSOR_RAIL_STATION, HT_RECT)) {
< ShowStationBuilder(this);
< this->last_user_action = widget;
---
> case WID_RAT_BUILD_STATION: {
> bool dragdrop = (this->last_user_action == HOTKEY_BUILD_STATION_DRAGDROP);
>
> if (dragdrop || this->last_user_action == HOTKEY_BUILD_STATION_SIZED) { /* hotkey */
> bool was_open = this->IsWidgetLowered(WID_RAT_BUILD_STATION);
> /* close the tool explicitly so it can be re-opened in different snapping mode */
> if (was_open) ResetObjectToPlace();
> if (!was_open || dragdrop != _settings_client.gui.station_dragdrop) {
> _settings_client.gui.station_dragdrop = dragdrop;
> if (HandlePlacePushButton(this, WID_RAT_BUILD_STATION, SPR_CURSOR_RAIL_STATION, HT_RECT))
> ShowStationBuilder(this);
> }
> this->last_user_action = WID_RAT_BUILD_STATION;
> remove_on_ctrl = false;
> } else { /* button */
> if (HandlePlacePushButton(this, WID_RAT_BUILD_STATION, SPR_CURSOR_RAIL_STATION, HT_RECT)) {
> ShowStationBuilder(this);
> this->last_user_action = WID_RAT_BUILD_STATION;
> }
579a746
> }
612c779
< if (_ctrl_pressed) RailToolbar_CtrlChanged(this);
---
> if (_ctrl_pressed && remove_on_ctrl) RailToolbar_CtrlChanged(this);
616a784
> // EventState es;
617a786,800
>
> switch (hotkey) {
> /* Indicate to the OnClick that the action comes from a hotkey rather
> * then from a click and that the CTRL state should be ignored. */
> case HOTKEY_POLYRAIL:
> case HOTKEY_NEW_POLYRAIL:
> this->last_user_action = hotkey;
> return this->Window::OnHotkey(WID_RAT_POLYRAIL);
>
> case HOTKEY_BUILD_STATION_SIZED:
> case HOTKEY_BUILD_STATION_DRAGDROP:
> this->last_user_action = hotkey;
> return this->Window::OnHotkey(WID_RAT_BUILD_STATION);
> }
>
622a806
> DiagDirection ddir;
640a825
> case WID_RAT_POLYRAIL:
649c834,838
< DoCommandP(tile, _cur_railtype, _build_depot_direction,
---
> ddir = _build_depot_direction;
> if (ddir == DIAGDIR_NW + 1) {
> ddir = AutodetectRailObjectDirection(tile);
> }
> DoCommandP(tile, _cur_railtype, ddir,
651a841,842
> if (_ctrl_pressed == _settings_client.gui.persistent_depottools)
> ResetObjectToPlace();
756a948,949
>
> citymania::AbortStationPlacement();
789a983,984
> const uint16 _railtoolbar_polyrail_keys[] = {'5' | WKC_CTRL, 'A' | WKC_CTRL | WKC_GLOBAL_HOTKEY, 0};
> const uint16 _railtoolbar_new_poly_keys[] = {'5' | WKC_CTRL | WKC_SHIFT, 'A' | WKC_CTRL | WKC_SHIFT | WKC_GLOBAL_HOTKEY, 0};
796a992,993
> Hotkey(_railtoolbar_polyrail_keys, "polyrail", HOTKEY_POLYRAIL),
> Hotkey(_railtoolbar_new_poly_keys, "new_polyrail", HOTKEY_NEW_POLYRAIL),
799a997,998
> Hotkey((uint16)0, "station_sized", HOTKEY_BUILD_STATION_SIZED), // has to go before station hotkey to override it
> Hotkey((uint16)0, "station_dragdrop", HOTKEY_BUILD_STATION_DRAGDROP),
826a1026,1027
> NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_RAT_POLYRAIL),
> SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_AUTORAIL, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_POLYRAIL),
883a1085,1089
> if (_settings_client.gui.cm_use_improved_station_join) {
> citymania::HandleStationPlacement(start, end);
> return;
> }
>
1018c1224,1225
< if (_settings_client.gui.station_show_coverage) SetTileSelectBigSize(-rad, -rad, 2 * rad, 2 * rad);
---
> if (_settings_client.gui.cm_use_improved_station_join || _settings_client.gui.station_show_coverage)
> SetTileSelectBigSize(-rad, -rad, 2 * rad, 2 * rad);
1041a1249
> top = DrawStationAuthorityText(left, right, top) + WD_PAR_VSEP_NORMAL;
1321a1530
> citymania::MarkCoverageHighlightDirty();
1710c1919,1926
< if (!IsInsideMM(widget, WID_BRAD_DEPOT_NE, WID_BRAD_DEPOT_NW + 1)) return;
---
> switch (widget) {
> case WID_BRAD_DEPOT_NE:
> case WID_BRAD_DEPOT_SE:
> case WID_BRAD_DEPOT_SW:
> case WID_BRAD_DEPOT_NW:
> size->width = ScaleGUITrad(64) + 2;
> size->height = ScaleGUITrad(48) + 2;
> break;
1712,1713c1928,1931
< size->width = ScaleGUITrad(64) + 2;
< size->height = ScaleGUITrad(48) + 2;
---
> case WID_BRAD_DEPOT_AUTO:
> size->width = ScaleGUITrad(128) + 6;
> break;
> }
1729a1948
> case WID_BRAD_DEPOT_AUTO:
1766a1986,1991
> NWidget(NWID_SPACER), SetMinimalSize(0, 2),
> NWidget(NWID_HORIZONTAL), SetPIP(2, 2, 2),
> NWidget(NWID_SPACER), SetFill(1, 0),
> NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BRAD_DEPOT_AUTO), SetMinimalSize(134, 12), SetDataTip(STR_STATION_BUILD_ORIENTATION_AUTO, STR_BUILD_DEPOT_TRAIN_ORIENTATION_AUTO_TOOLTIP),
> NWidget(NWID_SPACER), SetFill(1, 0),
> EndContainer(),
1887c2112
< _build_depot_direction = DIAGDIR_NW;
---
> _build_depot_direction = (DiagDirection)(DIAGDIR_NW + 1);
Only in cmclient/src: rev.cpp
diff -r -B -X .diff-exclude vanilla/src/rev.cpp.in cmclient/src/rev.cpp.in
22c22
< return HasBit(_openttd_newgrf_version, 19);
---
> return HasBit(_openttd_newgrf_version, 19);
38c38
< const char _openttd_revision[] = "!!VERSION!!";
---
> const char _openttd_revision[] = "1.10.1";
51c51
< const char _openttd_revision_hash[] = "!!GITHASH!!";
---
> const char _openttd_revision_hash[] = "7f77b8c1e27f3d102b1f665d2a3c500598245c3b";
61c61
< const byte _openttd_revision_modified = !!MODIFIED!!;
---
> const byte _openttd_revision_modified = 0;
68c68
< const byte _openttd_revision_tagged = !!ISTAG!!;
---
> const byte _openttd_revision_tagged = 1;
83c83,86
< const uint32 _openttd_newgrf_version = 1 << 28 | 10 << 24 | 0 << 20 | !!ISSTABLETAG!! << 19 | 28004;
---
> const uint32 _openttd_newgrf_version = 1 << 28 | 10 << 24 | 0 << 20 | 1 << 19 | 28004;
>
>
> const char _citymania_version[] = "!!VERSION!! !!DATE!!";
diff -r -B -X .diff-exclude vanilla/src/road_cmd.cpp cmclient/src/road_cmd.cpp
953c953
< static bool CanConnectToRoad(TileIndex tile, RoadType rt, DiagDirection dir)
---
> bool CanConnectToRoad(TileIndex tile, RoadType rt, DiagDirection dir)
diff -r -B -X .diff-exclude vanilla/src/road_func.h cmclient/src/road_func.h
161a162,163
> bool CanConnectToRoad(TileIndex tile, RoadType rt, DiagDirection dir);
>
diff -r -B -X .diff-exclude vanilla/src/road_gui.cpp cmclient/src/road_gui.cpp
11a12
> #include "cmd_helper.h"
12a14
> #include "station_func.h"
29a32
> #include "industry.h"
38a42,43
> #include "citymania/station_ui.hpp"
>
67c72
< static DiagDirection _road_station_picker_orientation;
---
> DiagDirection _road_station_picker_orientation;
172a178,278
>
> static RoadBits FindRoadsToConnect(TileIndex tile) {
> RoadBits bits = ROAD_NONE;
> DiagDirection ddir;
> auto cur_rtt = GetRoadTramType(_cur_roadtype);
> // Prioritize roadbits that head in this direction
> for (ddir = DIAGDIR_BEGIN; ddir < DIAGDIR_END; ddir++) {
> TileIndex cur_tile = TileAddByDiagDir(tile, ddir);
> if (GetAnyRoadBits(cur_tile, cur_rtt, true) &
> DiagDirToRoadBits(ReverseDiagDir(ddir)))
> {
> bits |= DiagDirToRoadBits(ddir);
> }
> }
> if (bits != ROAD_NONE) {
> return bits;
> }
> // Try to connect to any road passing by
> for (ddir = DIAGDIR_BEGIN; ddir < DIAGDIR_END; ddir++) {
> TileIndex cur_tile = TileAddByDiagDir(tile, ddir);
> if (GetTileType(cur_tile) == MP_ROAD && HasTileRoadType(cur_tile, cur_rtt) &&
> (GetRoadTileType(cur_tile) == ROAD_TILE_NORMAL)) {
> bits |= DiagDirToRoadBits(ddir);
> }
> }
> return bits;
> }
>
> static DiagDirection RoadBitsToDiagDir(RoadBits bits) {
> if (bits < ROAD_SE) {
> return bits == ROAD_NW ? DIAGDIR_NW : DIAGDIR_SW;
> }
> return bits == ROAD_SE ? DIAGDIR_SE : DIAGDIR_NE;
> }
>
> static DiagDirection TileFractCoordsToDiagDir() {
> bool diag = (_tile_fract_coords.x + _tile_fract_coords.y) < 16;
> if (_tile_fract_coords.x < _tile_fract_coords.y) {
> return diag ? DIAGDIR_NE : DIAGDIR_SE;
> }
> return diag ? DIAGDIR_NW : DIAGDIR_SW;
> }
> /*
> * Selects orientation for road object (depot, terminal station)
> */
> DiagDirection AutodetectRoadObjectDirection(TileIndex tile) {
> RoadBits bits = FindRoadsToConnect(tile);
> if (HasExactlyOneBit(bits)) {
> return RoadBitsToDiagDir(bits);
> }
> if (bits == ROAD_NONE){
> bits = ROAD_ALL;
> }
> RoadBits frac_bits = DiagDirToRoadBits(TileFractCoordsToDiagDir());
> if (HasExactlyOneBit(frac_bits & bits)) {
> return RoadBitsToDiagDir(frac_bits & bits);
> }
> frac_bits |= MirrorRoadBits(frac_bits);
> if (HasExactlyOneBit(frac_bits & bits)) {
> return RoadBitsToDiagDir(frac_bits & bits);
> }
> for (DiagDirection ddir = DIAGDIR_BEGIN; ddir < DIAGDIR_END; ddir++) {
> if (DiagDirToRoadBits(ddir) & bits) {
> return ddir;
> }
> }
> NOT_REACHED();
> }
>
> bool CheckDriveThroughRoadStopDirection(TileArea area, RoadBits r) {
> TILE_AREA_LOOP(tile, area) {
> if (GetTileType(tile) != MP_ROAD) continue;
> if (GetRoadTileType(tile) != ROAD_TILE_NORMAL) continue;
> if (GetAllRoadBits(tile) & ~r) return false;
> }
> return true;
> }
>
>
> /*
> * Automaticaly selects direction to use for road stop.
> * @param area road stop area
> * @return selected direction
> */
> DiagDirection AutodetectDriveThroughRoadStopDirection(TileArea area) {
> bool se_suits, ne_suits;
>
> // Check which direction is available
> // If both are not use SE, building will fail anyway
> se_suits = CheckDriveThroughRoadStopDirection(area, ROAD_Y);
> ne_suits = CheckDriveThroughRoadStopDirection(area, ROAD_X);
> if (!ne_suits) return DIAGDIR_SE;
> if (!se_suits) return DIAGDIR_NE;
>
> // Build station along the longer direction
> if (area.w > area.h) return DIAGDIR_NE;
> if (area.w < area.h) return DIAGDIR_SE;
>
> return AutodetectRoadObjectDirection(area.tile);
> }
>
184a291,295
> if (_settings_client.gui.cm_use_improved_station_join) {
> citymania::PlaceRoadStop(start_tile, end_tile, p2, cmd);
> return;
> }
>
186a298
> TileArea ta(start_tile, end_tile);
189,190c301,319
< SetBit(p2, 1); // It's a drive-through stop.
< ddir -= DIAGDIR_END; // Adjust picker result to actual direction.
---
> if (ddir < DIAGDIR_END + 2) {
> SetBit(p2, 1); // It's a drive-through stop.
> ddir -= DIAGDIR_END; // Adjust picker result to actual direction.
> // When placed on road autorotate anyway
> if (ddir == DIAGDIR_SE) {
> if (!CheckDriveThroughRoadStopDirection(ta, ROAD_Y))
> ddir = DIAGDIR_NE;
> } else {
> if (!CheckDriveThroughRoadStopDirection(ta, ROAD_X))
> ddir = DIAGDIR_SE;
> }
> }
> else if (ddir == DIAGDIR_END + 2) {
> ddir = AutodetectRoadObjectDirection(start_tile);
> }
> else if (ddir == DIAGDIR_END + 3) {
> SetBit(p2, 1); // It's a drive-through stop.
> ddir = AutodetectDriveThroughRoadStopDirection(ta);
> }
194d322
< TileArea ta(start_tile, end_tile);
260c388
< if (w->IsWidgetLowered(i)) {
---
> if (w->GetWidget(i) && w->IsWidgetLowered(i)) {
503a632
> DiagDirection ddir;
531c660,664
< DoCommandP(tile, _cur_roadtype << 2 | _road_depot_orientation, 0,
---
> ddir = _road_depot_orientation;
> if (ddir == DIAGDIR_NW + 1) {
> ddir = AutodetectRoadObjectDirection(tile);
> }
> DoCommandP(tile, _cur_roadtype << 2 | ddir, 0,
532a666,667
> if (_ctrl_pressed == _settings_client.gui.persistent_depottools)
> ResetObjectToPlace();
577a713,714
>
> citymania::AbortStationPlacement();
622a760,773
> void TryToRemoveExtraRoadBits(TileIndex tile, RoadBits &rb) {
> for (DiagDirection dir = DIAGDIR_BEGIN; dir != DIAGDIR_END; dir++) {
> RoadBits dir_rb = DiagDirToRoadBits(dir);
> if (!(rb & dir_rb)) continue;
> if (CanConnectToRoad(tile, _cur_roadtype, dir)) continue;
> DoCommandP(tile, tile,
> (dir_rb == ROAD_NW || dir_rb == ROAD_NE ? 0 : 3) |
> (dir_rb & ROAD_X ? 0 : 4) |
> (_cur_roadtype << 3),
> CMD_REMOVE_LONG_ROAD);
> rb &= ~dir_rb;
> }
> }
>
971c1122
< for (int i = WID_BROD_DEPOT_NE; i <= WID_BROD_DEPOT_NW; i++) this->GetWidget(i)->tool_tip = STR_BUILD_DEPOT_TRAM_ORIENTATION_SELECT_TOOLTIP;
---
> for (int i = WID_BROD_DEPOT_NE; i <= WID_BROD_DEPOT_AUTO; i++) this->GetWidget(i)->tool_tip = STR_BUILD_DEPOT_TRAM_ORIENTATION_SELECT_TOOLTIP;
979,982c1130,1143
< if (!IsInsideMM(widget, WID_BROD_DEPOT_NE, WID_BROD_DEPOT_NW + 1)) return;
<
< size->width = ScaleGUITrad(64) + 2;
< size->height = ScaleGUITrad(48) + 2;
---
> switch (widget) {
> case WID_BROD_DEPOT_NW:
> case WID_BROD_DEPOT_NE:
> case WID_BROD_DEPOT_SW:
> case WID_BROD_DEPOT_SE:
> size->width = ScaleGUITrad(64) + 2;
> size->height = ScaleGUITrad(48) + 2;
> break;
> case WID_BROD_DEPOT_AUTO:
> size->width = ScaleGUITrad(128) + 6;
> break;
> default:
> break;
> }
998a1160
> case WID_BROD_DEPOT_AUTO:
1037a1200,1205
> NWidget(NWID_SPACER), SetMinimalSize(0, 2),
> NWidget(NWID_HORIZONTAL), SetPIP(2, 2, 2),
> NWidget(NWID_SPACER), SetFill(1, 0),
> NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROD_DEPOT_AUTO), SetMinimalSize(134, 12), SetDataTip(STR_STATION_BUILD_ORIENTATION_AUTO, STR_BUILD_DEPOT_ROAD_ORIENTATION_AUTO_TOOLTIP),
> NWidget(NWID_SPACER), SetFill(1, 0),
> EndContainer(),
1062a1231,1233
> if (RoadTypeIsTram(_cur_roadtype) && _road_station_picker_orientation == (DiagDirection)(DIAGDIR_END + 2)) {
> _road_station_picker_orientation = (DiagDirection)(DIAGDIR_END + 3);
> }
1088c1259,1260
< if (_settings_client.gui.station_show_coverage) {
---
> SetTileSelectSize(1, 1);
> if (_settings_client.gui.cm_use_improved_station_join || _settings_client.gui.station_show_coverage)
1090,1092d1261
< } else {
< SetTileSelectSize(1, 1);
< }
1101a1271
> top = DrawStationAuthorityText(back_nwi->pos_x + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, top) + WD_PAR_VSEP_NORMAL;
1112,1115c1282,1303
< if (!IsInsideMM(widget, WID_BROS_STATION_NE, WID_BROS_STATION_Y + 1)) return;
<
< size->width = ScaleGUITrad(64) + 2;
< size->height = ScaleGUITrad(48) + 2;
---
> switch (widget) {
> case WID_BROS_STATION_NE:
> case WID_BROS_STATION_SE:
> case WID_BROS_STATION_SW:
> case WID_BROS_STATION_NW:
> case WID_BROS_STATION_X:
> case WID_BROS_STATION_Y:
> size->width = ScaleGUITrad(64) + 2;
> size->height = ScaleGUITrad(48) + 2;
> break;
> case WID_BROS_STATION_AUTO:
> size->width = ScaleGUITrad(128) + 6;
> break;
> case WID_BROS_STATION_XY_AUTO:
> if (RoadTypeIsTram(_cur_roadtype))
> size->width = ScaleGUITrad(128) + 6;
> else
> size->width = ScaleGUITrad(64) + 2;
> break;
> default:
> break;
> }
1134a1323,1324
> case WID_BROS_STATION_AUTO:
> case WID_BROS_STATION_XY_AUTO:
1149a1340
> citymania::MarkCoverageHighlightDirty();
1185a1377,1383
> NWidget(NWID_SPACER), SetMinimalSize(0, 2),
> NWidget(NWID_HORIZONTAL), SetPIP(0, 2, 0),
> NWidget(NWID_SPACER), SetFill(1, 0),
> NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROS_STATION_AUTO), SetMinimalSize(134, 12), SetDataTip(STR_STATION_BUILD_ORIENTATION_AUTO, STR_STATION_BUILD_ORIENTATION_AUTO_TOOLTIP),
> NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROS_STATION_XY_AUTO), SetMinimalSize(66, 12), SetDataTip(STR_STATION_BUILD_ORIENTATION_AUTO, STR_STATION_BUILD_ORIENTATION_AUTO_TOOLTIP),
> NWidget(NWID_SPACER), SetFill(1, 0),
> EndContainer(),
1223a1422,1427
> NWidget(NWID_SPACER), SetMinimalSize(0, 2),
> NWidget(NWID_HORIZONTAL), SetPIP(0, 2, 0),
> NWidget(NWID_SPACER), SetFill(1, 0),
> NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROS_STATION_XY_AUTO), SetMinimalSize(274, 12), SetDataTip(STR_STATION_BUILD_ORIENTATION_AUTO, STR_STATION_BUILD_ORIENTATION_AUTO_TOOLTIP),
> NWidget(NWID_SPACER), SetFill(1, 0),
> EndContainer(),
1226c1430
< NWidget(WWT_LABEL, COLOUR_DARK_GREEN, WID_BROS_INFO), SetMinimalSize(140, 14), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL),
---
> NWidget(WWT_LABEL, COLOUR_DARK_GREEN, WID_BROS_INFO), SetMinimalSize(134, 14), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL),
1255,1256c1459,1460
< _road_depot_orientation = DIAGDIR_NW;
< _road_station_picker_orientation = DIAGDIR_NW;
---
> _road_depot_orientation = (DiagDirection)(DIAGDIR_NW + 1);
> _road_station_picker_orientation = (DiagDirection)(DIAGDIR_END + 3);
diff -r -B -X .diff-exclude vanilla/src/roadveh_cmd.cpp cmclient/src/roadveh_cmd.cpp
1633c1633
< PerformanceAccumulator framerate(PFE_GL_ROADVEHS);
---
> // PerformanceAccumulator framerate(PFE_GL_ROADVEHS);
diff -r -B -X .diff-exclude vanilla/src/saveload/afterload.cpp cmclient/src/saveload/afterload.cpp
59a60,64
> #include "../story_base.h"
> #include "../game/game_text.hpp"
> #include "../table/control_codes.h"
>
> #include "../citymania/highlight.hpp"
536a542,580
> extern GameStrings *_current_data;
>
> void AfterLoadFindBTProCBInfo() {
> if (_current_data == NULL) return;
>
> char buf[15];
> char *p = buf;
> int pn;
> p += Utf8Encode(p, SCC_ENCODED);
> for (uint i = 0; i < _current_data->raw_strings.size(); i++) {
> auto ls = _current_data->raw_strings[i].get();
> if (!ls) continue;
> int string_id = 0;
> for (uint j = 0; j < ls->lines.size(); j++) {
> auto &s = ls->lines[j];
> if (!s.size() || s[0] == ';' || s[0] == '#' || s[0] == ' ' || s[0] == '\0') continue;
> if (strncmp(s.c_str(), "STR_TOWN_CLAIMED_CARGOS", strlen("STR_TOWN_CLAIMED_CARGOS")) == 0 ||
> strncmp(s.c_str(), "STR_TOWN_CARGOS_NEEDED_CB", strlen("STR_TOWN_CARGOS_NEEDED_CB")) == 0) {
> pn = p - buf + seprintf(p, lastof(buf), "%X:", string_id);
> bool with_decay = (strncmp(s.c_str(), "STR_TOWN_CLAIMED_CARGOS_DECAY",
> strlen("STR_TOWN_CLAIMED_CARGOS_DECAY")) == 0);
> for (StoryPageElement *se : StoryPageElement::Iterate()) {
> if (!se->text || strncmp(se->text, buf, pn) != 0) continue;
> uint req, cargomask, from, decay=0;
> if (with_decay) {
> sscanf(se->text + pn, "%X:%X:%X:%X", &req, &cargomask, &from, &decay);
> } else {
> sscanf(se->text + pn, "%X:%X:%X", &req, &cargomask, &from);
> }
> uint cargo_id = FindFirstBit(cargomask);
> if (!CB_Enabled()) CB_SetCB(true);
> CB_SetRequirements(cargo_id, req, from, decay);
> }
> }
> string_id++;
> }
> }
> }
>
3144a3189,3190
> AfterLoadFindBTProCBInfo();
> citymania::InitializeZoningMap();
Only in cmclient/src/saveload: citymania_sl.cpp
Only in cmclient/src/saveload: citymania_sl.h
diff -r -B -X .diff-exclude vanilla/src/saveload/storage_sl.cpp cmclient/src/saveload/storage_sl.cpp
10a11
> #include "../debug.h"
11a13
> #include "citymania_sl.h"
15a18,20
> // Luukland_Citybuilder grf id actually
> #define CITYMANIA_GRFID 0x534B0501U
>
23a29,37
> // static void hexdump(uint8 *data) {
> // uint i;
> // for (i = 0; i < 20; i++) {
> // if (i) fprintf(stderr, " : ");
> // fprintf(stderr, "%02x", data[i]);
> // }
> // fprintf(stderr, i >= 20 ? " ...\n" : "\n");
> // }
>
28a43,51
> /*
> CITYMANIA_GRFID is used to hide extra data in persitant storages.
> To save a bit of memory we only keep at most one PS with this
> grfid and it is later discarded on save.
> */
> PersistentStorage *ps = NULL;
> u8vector cmdata;
> uint chunk_size = IsSavegameVersionBefore(SLV_EXTEND_PERSISTENT_STORAGE) ? 64 : 1024;
> DEBUG(sl, 2, "CityMania savegame data chunk size: %u", chunk_size);
30,31c53,56
< assert(PersistentStorage::CanAllocateItem());
< PersistentStorage *ps = new (index) PersistentStorage(0, 0, 0);
---
> if (ps == NULL) {
> assert(PersistentStorage::CanAllocateItem());
> ps = new (index) PersistentStorage(0, 0, 0);
> }
32a58,91
>
> if (ps->grfid == CITYMANIA_GRFID) {
> uint8 *data = (uint8 *)(ps->storage);
> cmdata.insert(cmdata.end(), data, data + chunk_size);
> } else {
> ps = NULL;
> }
> }
>
> CM_DecodeData(cmdata);
> }
>
> static void Save_CMDataAsPSAC() {
> uint32 grfid = CITYMANIA_GRFID;
> u8vector data = CM_EncodeData();
> int n_chunks = (data.size() + 1023) / 1024;
> data.resize(n_chunks * 1024);
> uint8 *ptr = &data[0];
> SaveLoadGlobVarList _desc[] = {
> SLEG_CONDVAR(grfid, SLE_UINT32, SLV_6, SL_MAX_VERSION),
> SLEG_CONDARR(*ptr, SLE_UINT32, 256, SLV_EXTEND_PERSISTENT_STORAGE, SL_MAX_VERSION),
> SLEG_END()
> };
>
> uint index = 0;
> for (PersistentStorage *ps : PersistentStorage::Iterate()) {
> if (ps->grfid != CITYMANIA_GRFID)
> index = max(index, ps->index + 1);
> }
>
> for (int i = 0; i < n_chunks; i++, ptr += 1024) {
> _desc[1].address = (void *)ptr;
> SlSetArrayIndex(index + i);
> SlGlobList(_desc);
40a100,101
> if (ps->grfid == CITYMANIA_GRFID)
> continue;
44a106,107
>
> Save_CMDataAsPSAC();
diff -r -B -X .diff-exclude vanilla/src/saveload/town_sl.cpp cmclient/src/saveload/town_sl.cpp
33a34
> town->cache.potential_pop = 0;
42a44,45
> else town->houses_construction++;
> town->cache.potential_pop += HouseSpec::Get(house_id)->population;
diff -r -B -X .diff-exclude vanilla/src/script/api/game/game_window.hpp.sq cmclient/src/script/api/game/game_window.hpp.sq
940a941
> SQGSWindow.DefSQConst(engine, ScriptWindow::WID_RAT_POLYRAIL, "WID_RAT_POLYRAIL");
diff -r -B -X .diff-exclude vanilla/src/script/api/script_window.hpp cmclient/src/script/api/script_window.hpp
2046a2047
> WID_RAT_POLYRAIL = ::WID_RAT_POLYRAIL, ///< Polyline rail tool.
diff -r -B -X .diff-exclude vanilla/src/settings_gui.cpp cmclient/src/settings_gui.cpp
36a37
> #include "hotkeys.h"
592a594,595
>
> static HotkeyList hotkeys;
678a682,694
> static EventState GameOptionsWindowGlobalHotkeys(int hotkey) {
> if (!ToggleFullScreen(!_fullscreen)) {
> ShowErrorMessage(STR_ERROR_FULLSCREEN_FAILED, INVALID_STRING_ID, WL_ERROR);
> }
> return ES_HANDLED;
> }
>
> static Hotkey game_options_hotkeys[] = {
> Hotkey((uint16)0, "toggle_fullscreen", WID_GO_FULLSCREEN_BUTTON),
> HOTKEY_LIST_END
> };
> HotkeyList GameOptionsWindow::hotkeys("game_options", game_options_hotkeys, GameOptionsWindowGlobalHotkeys);
>
683c699,700
< _nested_game_options_widgets, lengthof(_nested_game_options_widgets)
---
> _nested_game_options_widgets, lengthof(_nested_game_options_widgets),
> &GameOptionsWindow::hotkeys
1549a1567,1570
> viewports->Add(new SettingEntry("gui.cb_distance_check"));
> viewports->Add(new SettingEntry("gui.old_depot_train_length_calc"));
> viewports->Add(new SettingEntry("gui.enable_extra_tooltips"));
> // viewports->Add(new SettingEntry("gui.polyrail_double_click"));
1556a1578,1580
> construction->Add(new SettingEntry("gui.persistent_depottools"));
> construction->Add(new SettingEntry("gui.cm_open_vehicle_for_shared_clone"));
> construction->Add(new SettingEntry("gui.cm_open_orders_for_new_vehicles"));
1559a1584
> construction->Add(new SettingEntry("gui.cm_use_improved_station_join"));
1569a1595,1596
> interface->Add(new SettingEntry("gui.powerfund_money"));
> interface->Add(new SettingEntry("gui.powerfund_houses"));
1586a1614
> advisors->Add(new SettingEntry("gui.runway_too_short_warn"));
1629a1658,1677
> /** Vehicle control page */
> SettingsPage *veh_control = vehicles->Add(new SettingsPage(STR_CONFIG_SETTING_VEHICLES_CTRL));
> {
> veh_control->Add(new SettingEntry("gui.enable_ctrl_click_start_stop"));
> veh_control->Add(new SettingEntry("gui.new_nonstop"));
> veh_control->Add(new SettingEntry("gui.auto_noload_on_transfer"));
> veh_control->Add(new SettingEntry("gui.auto_noload_on_unloadall"));
> }
>
> /** Order Shorcuts page */
> SettingsPage *orders = veh_control->Add(new SettingsPage(STR_CONFIG_SETTING_ORDER_SHORTCUTS));
> {
> orders->Add(new SettingEntry("gui.goto_shortcuts_ctrl_lclick"));
> orders->Add(new SettingEntry("gui.goto_shortcuts_shift_lclick"));
> orders->Add(new SettingEntry("gui.goto_shortcuts_ctrlshift_lclick"));
> orders->Add(new SettingEntry("gui.goto_shortcuts_alt_lclick"));
> orders->Add(new SettingEntry("gui.goto_shortcuts_altshift_lclick"));
> orders->Add(new SettingEntry("gui.goto_shortcuts_altctrl_lclick"));
> }
>
diff -r -B -X .diff-exclude vanilla/src/settings_type.h cmclient/src/settings_type.h
88a89,97
> bool enable_ctrl_click_start_stop; ///< allow ctrl+click to start or stop vehicles
> uint8 goto_shortcuts_ctrl_lclick; ///< goto action shortcut CTRL+LEFT-CLICK
> uint8 goto_shortcuts_shift_lclick; ///< goto action shortcut SHIFT+LEFT-CLICK
> uint8 goto_shortcuts_ctrlshift_lclick; ///< goto action shortcut CTRL+SHIFT+LEFT-CLICK
> uint8 goto_shortcuts_alt_lclick; ///< goto action shortcut ALT+LEFT-CLICK
> uint8 goto_shortcuts_altshift_lclick; ///< goto action shortcut ALT+SHIFT+LEFT-CLICK
> uint8 goto_shortcuts_altctrl_lclick; ///< goto action shortcut ALT+CTRL+LEFT-CLICK
> bool auto_noload_on_transfer; ///< automatically set no-loading when ordering to transfer all cargo
> bool auto_noload_on_unloadall; ///< automatically set no-loading when ordering to unload all cargo
127a137,138
> bool cm_open_vehicle_for_shared_clone;
> bool cm_open_orders_for_new_vehicles;
141a153,154
> bool persistent_depottools; ///< keep the depot building tools active after usage
> bool cm_use_improved_station_join; ///< use ctrl-clicking station tiles to join instead of popup window
167a181,190
>
> bool old_depot_train_length_calc; ///< display vehicle length in whole numbers - old style
> uint8 cb_distance_check; ///< zoning cb distance
> bool enable_extra_tooltips; ///< enable extra tooltips when hovering over various elements
> bool polyrail_double_click; ///< finish polyrail with mouse double click
> bool show_industry_forbidden_tiles; ///< higlight areas where industry placement is forbidden regardless of terrain
> bool runway_too_short_warn; ///< warn about aircrafts using too short runways
>
> uint32 powerfund_money; ///< minimum amount of money for powerfund to work
> uint16 powerfund_houses; ///< powerfunding maximum houses limit
diff -r -B -X .diff-exclude vanilla/src/ship_cmd.cpp cmclient/src/ship_cmd.cpp
800c800
< PerformanceAccumulator framerate(PFE_GL_SHIPS);
---
> // PerformanceAccumulator framerate(PFE_GL_SHIPS);
diff -r -B -X .diff-exclude vanilla/src/smallmap_gui.cpp cmclient/src/smallmap_gui.cpp
923c923
< DrawString(x, x + t->cache.sign.width_small, y, STR_SMALLMAP_TOWN);
---
> DrawString(x, x + t->cache.sign.width_small, y, t->larger_town ? STR_SMALLMAP_TOWN_LARGE : STR_SMALLMAP_TOWN);
diff -r -B -X .diff-exclude vanilla/src/station_cmd.cpp cmclient/src/station_cmd.cpp
60a61,62
> #include "citymania/station_ui.hpp"
>
769a772
> citymania::OnStationTileSetChange(this, adding, type);
1954a1958
> citymania::OnStationPartBuilt(st, tile, p1, p2);
diff -r -B -X .diff-exclude vanilla/src/station.cpp cmclient/src/station.cpp
20a21
> #include "town.h"
38a40,41
> Kdtree_StationXYFunc kd_station_func;
> StationKdtree _station_kdtree(kd_station_func);
40c43,45
< StationKdtree _station_kdtree(Kdtree_StationXYFunc);
---
> uint16 Kdtree_StationXYFunc::operator()(StationID stid, int dim) const {
> return (dim == 0) ? TileX(BaseStation::Get(stid)->xy) : TileY(BaseStation::Get(stid)->xy);
> }
88a94,101
> for (Town *t : Town::Iterate()) {
> // Using poiter comparison instead of cycling cargos
> if (t->ad_ref_goods_entry >= this->goods &&
> t->ad_ref_goods_entry < this->goods + NUM_CARGO) {
> t->ad_ref_goods_entry = NULL;
> }
> }
>
diff -r -B -X .diff-exclude vanilla/src/station_gui.cpp cmclient/src/station_gui.cpp
41a42,43
> #include "citymania/station_ui.hpp"
>
80a83,99
> int DrawStationAuthorityText(int left, int right, int top) {
> TileIndex tile = TileVirtXY(_thd.pos.x, _thd.pos.y);
> Town *town = ClosestTownFromTile(tile, UINT_MAX);
> auto dist = DistanceManhattan(town->xy, tile);
>
> SetDParam(0, town ? town->index : INVALID_TOWN);
> if (dist <= 10) {
> return DrawStringMultiLine(left, right, top, INT32_MAX, STR_CM_STATION_BUILD_TOWN_SMALL);
> } else if (dist <= 15) {
> return DrawStringMultiLine(left, right, top, INT32_MAX, STR_CM_STATION_BUILD_TOWN_MEDIUM);
> } else if (dist <= 20) {
> return DrawStringMultiLine(left, right, top, INT32_MAX, STR_CM_STATION_BUILD_TOWN_LARGE);
> } else {
> return DrawStringMultiLine(left, right, top, INT32_MAX, STR_CM_STATION_BUILD_TOWN);
> }
> }
>
127a147,150
> if (_settings_client.gui.cm_use_improved_station_join) {
> citymania::CheckRedrawStationCoverage();
> return;
> }
1306a1330
> int ratings_list_y = 0; ///< Y coordinate of first line in station ratings panel.
1844c1868
< int DrawCargoRatings(const Rect &r) const
---
> int DrawCargoRatings(const Rect &r)
1857a1882
> this->ratings_list_y = y;
2094a2120,2141
> virtual void OnHover(Point pt, int widget)
> {
> if (widget != WID_SV_ACCEPT_RATING_LIST ||
> this->GetWidget(WID_SV_ACCEPTS_RATINGS)->widget_data == STR_STATION_VIEW_RATINGS_BUTTON)
> Window::OnHover(pt, widget);
>
> int ofs_y = pt.y - this->ratings_list_y;
> if (ofs_y < 0) return;
>
> const Station *st = Station::Get(this->window_number);
> const CargoSpec *cs;
> FOR_ALL_SORTED_STANDARD_CARGOSPECS(cs) {
> const GoodsEntry *ge = &st->goods[cs->Index()];
> if (!ge->HasRating()) continue;
> ofs_y -= FONT_HEIGHT_NORMAL;
> if (ofs_y < 0) {
> GuiShowStationRatingTooltip(this, st, cs);
> break;
> }
> }
> }
>
2266c2313
< struct SelectStationWindow : Window {
---
> struct SelectStationWindow : WindowPopup {
2272c2319
< Window(desc),
---
> WindowPopup(desc, WPUT_WIDGET_RELATIVE),
2275a2323
> this->wpu_widget = WID_JS_PANEL;
diff -r -B -X .diff-exclude vanilla/src/station_gui.h cmclient/src/station_gui.h
25a26
> int DrawStationAuthorityText(int left, int right, int top);
diff -r -B -X .diff-exclude vanilla/src/station_kdtree.h cmclient/src/station_kdtree.h
18,19c18,23
< inline uint16 Kdtree_StationXYFunc(StationID stid, int dim) { return (dim == 0) ? TileX(BaseStation::Get(stid)->xy) : TileY(BaseStation::Get(stid)->xy); }
< typedef Kdtree StationKdtree;
---
> class Kdtree_StationXYFunc {
> public:
> uint16 operator()(StationID stid, int dim) const;
> };
>
> typedef Kdtree StationKdtree;
diff -r -B -X .diff-exclude vanilla/src/table/settings.ini cmclient/src/table/settings.ini
2926a2927,2942
> var = gui.cm_open_vehicle_for_shared_clone
> flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
> def = false
> str = STR_CM_CONFIG_SETTING_OPEN_VEHICLE_FOR_SHARED_CLONE
> strhelp = STR_CM_CONFIG_SETTING_OPEN_VEHICLE_FOR_SHARED_CLONE_HELPTEXT
> cat = SC_BASIC
>
> [SDTC_BOOL]
> var = gui.cm_open_orders_for_new_vehicles
> flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
> def = false
> str = STR_CM_CONFIG_SETTING_OPEN_ORDERS_FOR_NEW_VEHICLES
> strhelp = STR_CM_CONFIG_SETTING_OPEN_ORDERS_FOR_NEW_VEHICLES_HELPTEXT
> cat = SC_BASIC
>
> [SDTC_BOOL]
3187a3204,3219
> var = gui.persistent_depottools
> flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
> def = false
> str = STR_CONFIG_SETTING_PERSISTENT_DEPOTTOOLS
> strhelp = STR_CONFIG_SETTING_PERSISTENT_DEPOTTOOLS_HELPTEXT
> cat = SC_BASIC
>
> [SDTC_BOOL]
> var = gui.cm_use_improved_station_join
> flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
> def = false
> str = STR_CM_CONFIG_SETTING_IMPROVED_STATION_JOIN
> strhelp = STR_CM_CONFIG_SETTING_IMPROVED_STATION_JOIN_HELPTEXT
> cat = SC_BASIC
>
> [SDTC_BOOL]
4011a4044,4210
>
> ; //MODGUI *********************************
> [SDTC_BOOL]
> var = gui.enable_ctrl_click_start_stop
> flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
> def = true
> str = STR_CONFIG_SETTING_CTRL_ENABLE_CTRLCLICK_STARTSTOP
>
> [SDTC_BOOL]
> var = gui.auto_noload_on_transfer
> flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
> def = true
> str = STR_CONFIG_SETTING_AUTOSET_NOLOAD_ON_TRANSFER
>
> [SDTC_BOOL]
> var = gui.auto_noload_on_unloadall
> flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
> def = false
> str = STR_CONFIG_SETTING_AUTOSET_NOLOAD_ON_UNLOAD
>
> [SDTC_VAR]
> var = gui.goto_shortcuts_ctrl_lclick
> type = SLE_UINT8
> flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
> guiflags = SGF_MULTISTRING
> def = 1
> min = 0
> max = 6
> interval = 1
> str = STR_CONFIG_SETTING_CTRL_GOTOSHORTCUT_CTRLLCLICK
> strval = STR_CONFIG_SETTING_CTRL_GOTOSHORTOPTS_NONE
> proc = RedrawScreen
> cat = SC_BASIC
>
> [SDTC_VAR]
> var = gui.goto_shortcuts_shift_lclick
> type = SLE_UINT8
> flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
> guiflags = SGF_MULTISTRING
> def = 0
> min = 0
> max = 6
> interval = 1
> str = STR_CONFIG_SETTING_CTRL_GOTOSHORTCUT_SHIFTLCLICK
> strval = STR_CONFIG_SETTING_CTRL_GOTOSHORTOPTS_NONE
> proc = RedrawScreen
> cat = SC_BASIC
>
> [SDTC_VAR]
> var = gui.goto_shortcuts_ctrlshift_lclick
> type = SLE_UINT8
> flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
> guiflags = SGF_MULTISTRING
> def = 0
> min = 0
> max = 6
> interval = 1
> str = STR_CONFIG_SETTING_CTRL_GOTOSHORTCUT_CTRLSHIFTLCLICK
> strval = STR_CONFIG_SETTING_CTRL_GOTOSHORTOPTS_NONE
> proc = RedrawScreen
> cat = SC_BASIC
>
> [SDTC_VAR]
> var = gui.goto_shortcuts_alt_lclick
> type = SLE_UINT8
> flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
> guiflags = SGF_MULTISTRING
> def = 0
> min = 0
> max = 6
> interval = 1
> str = STR_CONFIG_SETTING_CTRL_GOTOSHORTCUT_ALTLCLICK
> strval = STR_CONFIG_SETTING_CTRL_GOTOSHORTOPTS_NONE
> proc = RedrawScreen
> cat = SC_BASIC
>
> [SDTC_VAR]
> var = gui.goto_shortcuts_altshift_lclick
> type = SLE_UINT8
> flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
> guiflags = SGF_MULTISTRING
> def = 0
> min = 0
> max = 6
> interval = 1
> str = STR_CONFIG_SETTING_CTRL_GOTOSHORTCUT_ALTSHIFTCLICK
> strval = STR_CONFIG_SETTING_CTRL_GOTOSHORTOPTS_NONE
> proc = RedrawScreen
> cat = SC_BASIC
>
> [SDTC_VAR]
> var = gui.goto_shortcuts_altctrl_lclick
> type = SLE_UINT8
> flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
> guiflags = SGF_MULTISTRING
> def = 0
> min = 0
> max = 6
> interval = 1
> str = STR_CONFIG_SETTING_CTRL_GOTOSHORTCUT_CTRLALTLCLICK
> strval = STR_CONFIG_SETTING_CTRL_GOTOSHORTOPTS_NONE
> proc = RedrawScreen
> cat = SC_BASIC
>
> [SDTC_BOOL]
> var = gui.old_depot_train_length_calc
> flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
> def = true
> str = STR_OLD_DEPOT_TRAINT_LENGTH
>
> [SDTC_VAR]
> var = gui.cb_distance_check
> type = SLE_UINT8
> flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
> def = 25
> min = 0
> max = 100
> interval = 5
> str = STR_CB_DISTANCE_CHECK
> strval = STR_JUST_COMMA
> proc = RedrawScreen
>
> [SDTC_BOOL]
> var = gui.enable_extra_tooltips
> flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
> def = true
> str = STR_CONFIG_SETTING_ENABLE_EXTRA_TOOLTIPS
>
> [SDTC_BOOL]
> var = gui.polyrail_double_click
> flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
> def = false
> str = STR_CONFIG_SETTING_POLYRAIL_DOUBLECLICK_TOOLTIPS
>
> [SDTC_BOOL]
> var = gui.show_industry_forbidden_tiles
> flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
> def = false
> cat = SC_BASIC
>
> [SDTC_BOOL]
> var = gui.runway_too_short_warn
> flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
> def = true
> str = STR_CONFIG_SETTING_WARN_IF_RUNWAY_IS_TOO_SHORT
>
> [SDTC_VAR]
> var = gui.powerfund_money
> type = SLE_UINT
> flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
> guiflags = SGF_CURRENCY
> def = 200000
> min = 0
> max = 2000000
> str = STR_CONFIG_SETTING_POWERFUND_MONEY
> strval = STR_JUST_CURRENCY_LONG
>
> [SDTC_VAR]
> var = gui.powerfund_houses
> type = SLE_UINT16
> flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
> def = 10000
> min = 0
> max = 10000
> interval = 10
> str = STR_CONFIG_SETTING_POWERFUND_HOUSES
> strval = STR_JUST_COMMA
diff -r -B -X .diff-exclude vanilla/src/table/sprites.h cmclient/src/table/sprites.h
303a304,336
> /* zoning stuff */
> static const SpriteID SPR_INNER_HIGHLIGHT_BASE = SPR_PALETTE_BASE + PALETTE_SPRITE_COUNT;
> static const SpriteID SPR_IMG_COMPANY_CARGO = SPR_INNER_HIGHLIGHT_BASE + 19;
> static const SpriteID SPR_IMG_COMPANY_GOAL = SPR_INNER_HIGHLIGHT_BASE + 20;
> static const SpriteID SPR_IMG_HOUSE_NEW = SPR_INNER_HIGHLIGHT_BASE + 21;
> static const SpriteID SPR_PALETTE_ZONING_RED = SPR_INNER_HIGHLIGHT_BASE + 22;
> static const SpriteID SPR_PALETTE_ZONING_GREEN = SPR_INNER_HIGHLIGHT_BASE + 23;
> static const SpriteID SPR_PALETTE_ZONING_BLACK = SPR_INNER_HIGHLIGHT_BASE + 24;
> static const SpriteID SPR_PALETTE_ZONING_LIGHT_BLUE = SPR_INNER_HIGHLIGHT_BASE + 25;
> static const SpriteID SPR_PALETTE_ZONING_ORANGE = SPR_INNER_HIGHLIGHT_BASE + 26;
> static const SpriteID SPR_PALETTE_ZONING_WHITE = SPR_INNER_HIGHLIGHT_BASE + 27;
> static const SpriteID SPR_PALETTE_ZONING_YELLOW = SPR_INNER_HIGHLIGHT_BASE + 28;
> static const SpriteID SPR_PALETTE_ZONING_PURPLE = SPR_INNER_HIGHLIGHT_BASE + 29;
> static const SpriteID SPR_INNER_HIGHLIGHT_COUNT = 30;
>
> static const SpriteID SPR_BORDER_HIGHLIGHT_BASE = SPR_INNER_HIGHLIGHT_BASE + SPR_INNER_HIGHLIGHT_COUNT + 1;
> static const SpriteID SPR_BORDER_HIGHLIGHT_COUNT = 19 * 19;
> static const SpriteID PALETTE_TINT_BASE = SPR_BORDER_HIGHLIGHT_BASE + SPR_BORDER_HIGHLIGHT_COUNT;
> static const SpriteID PALETTE_TINT_RED_DEEP = PALETTE_TINT_BASE;
> static const SpriteID PALETTE_TINT_ORANGE_DEEP = PALETTE_TINT_BASE + 1;
> static const SpriteID PALETTE_TINT_GREEN_DEEP = PALETTE_TINT_BASE + 2;
> static const SpriteID PALETTE_TINT_CYAN_DEEP = PALETTE_TINT_BASE + 3;
> static const SpriteID PALETTE_TINT_RED = PALETTE_TINT_BASE + 4;
> static const SpriteID PALETTE_TINT_ORANGE = PALETTE_TINT_BASE + 5;
> static const SpriteID PALETTE_TINT_YELLOW = PALETTE_TINT_BASE + 6;
> static const SpriteID PALETTE_TINT_YELLOW_WHITE = PALETTE_TINT_BASE + 7;
> static const SpriteID PALETTE_TINT_WHITE = PALETTE_TINT_BASE + 8;
> static const SpriteID PALETTE_TINT_GREEN = PALETTE_TINT_BASE + 9;
> static const SpriteID PALETTE_TINT_CYAN = PALETTE_TINT_BASE + 10;
> static const SpriteID PALETTE_TINT_CYAN_WHITE = PALETTE_TINT_BASE + 11;
> static const SpriteID PALETTE_TINT_BLUE = PALETTE_TINT_BASE + 12;
> static const SpriteID PALETTE_TINT_COUNT = 13;
>
305c338
< static const SpriteID SPR_NEWGRFS_BASE = SPR_PALETTE_BASE + PALETTE_SPRITE_COUNT;
---
> static const SpriteID SPR_NEWGRFS_BASE = PALETTE_TINT_BASE + PALETTE_TINT_COUNT;
diff -r -B -X .diff-exclude vanilla/src/terraform_gui.cpp cmclient/src/terraform_gui.cpp
118a119,175
> case DDSP_DEMOLISH_TREES:
> // loop through every tile and send a demolish command for each tree
> // orthogonal area
> TileIndex tree_start_tile, tree_recent_tile, prev_tile;
> tree_start_tile = tree_recent_tile = prev_tile = 0;
> if (!_ctrl_pressed) {
> OrthogonalTileArea square_area = OrthogonalTileArea(start_tile, end_tile);
> TILE_AREA_LOOP(curr_tile, square_area) {
> // if we're on a non-consecutive tile or we've hit a black-marked tile
> // safe tiles are: TREES or non-FIELD clear tiles (because they're expensive to demolish)
> if (tree_start_tile != 0 &&
> (curr_tile != prev_tile + 1 ||
> (!IsTileType(curr_tile, MP_TREES) && (!IsTileType(curr_tile, MP_CLEAR) || IsClearGround(curr_tile, CLEAR_FIELDS))))) {
> DoCommandP(tree_start_tile, tree_recent_tile, 0, CMD_CLEAR_AREA | CMD_MSG(STR_ERROR_CAN_T_CLEAR_THIS_AREA), CcPlaySound_EXPLOSION);
> tree_start_tile = tree_recent_tile = 0;
> }
> // if current tile is a tree
> if (IsTileType(curr_tile, MP_TREES)) {
> if (tree_start_tile == 0) {
> tree_start_tile = curr_tile;
> }
> tree_recent_tile = curr_tile;
> }
> prev_tile = curr_tile;
> }
> // one last ride to flavortown
> if (tree_start_tile != 0) {
> DoCommandP(tree_start_tile, tree_recent_tile, 0, CMD_CLEAR_AREA | CMD_MSG(STR_ERROR_CAN_T_CLEAR_THIS_AREA), CcPlaySound_EXPLOSION);
> }
> } else { // diagonal area
> DiagonalTileArea diagonal_area = DiagonalTileArea(start_tile, end_tile);
> DIAGONAL_TILE_AREA_LOOP(curr_tile, diagonal_area) {
> // same as above but with a different criteria for consecutive tiles
> TileIndexDiffC tile_diff = TileIndexToTileIndexDiffC(curr_tile, prev_tile);
> // if we're on a non-consecutive tile or we've hit a black-marked tile
> // safe tiles are: TREES or non-FIELD clear tiles (because they're expensive to demolish)
> if (tree_start_tile != 0 &&
> (!((tile_diff.x == 1 && tile_diff.y == 1) || (tile_diff.x == -1 && tile_diff.y == -1)) ||
> (!IsTileType(curr_tile, MP_TREES) && (!IsTileType(curr_tile, MP_CLEAR) || IsClearGround(curr_tile, CLEAR_FIELDS))))) {
> DoCommandP(tree_start_tile, tree_recent_tile, 1, CMD_CLEAR_AREA | CMD_MSG(STR_ERROR_CAN_T_CLEAR_THIS_AREA), CcPlaySound_EXPLOSION);
> tree_start_tile = tree_recent_tile = 0;
> }
> // if current tile is a tree
> if (IsTileType(curr_tile, MP_TREES)) {
> if (tree_start_tile == 0) {
> tree_start_tile = curr_tile;
> }
> tree_recent_tile = curr_tile;
> }
> prev_tile = curr_tile;
> }
> // one last ride to flavortown
> if (tree_start_tile != 0) {
> DoCommandP(tree_start_tile, tree_recent_tile, 1, CMD_CLEAR_AREA | CMD_MSG(STR_ERROR_CAN_T_CLEAR_THIS_AREA), CcPlaySound_EXPLOSION);
> }
> }
> break;
165a223,246
> void DrawWidget(const Rect &r, int widget) const override
> {
> if (widget == WID_TT_DEMOLISH_TREES) {
> uint offset = this->IsWidgetLowered(WID_TT_DEMOLISH_TREES) ? 1 : 0;
> ZoomLevel temp_zoom;
> switch (_gui_zoom) {
> case ZOOM_LVL_NORMAL:
> temp_zoom = ZOOM_LVL_OUT_2X;
> break;
> case ZOOM_LVL_OUT_2X:
> temp_zoom = ZOOM_LVL_OUT_4X;
> break;
> case ZOOM_LVL_OUT_4X:
> temp_zoom = ZOOM_LVL_OUT_8X;
> break;
> default:
> temp_zoom = ZOOM_LVL_OUT_8X;
> break;
> }
> Dimension d = GetSpriteSize(SPR_IMG_PLANTTREES, (Point *)0, temp_zoom);
> DrawSprite(SPR_IMG_PLANTTREES, PAL_NONE, (r.left + r.right - d.width) / 2 + offset, (r.top + r.bottom - d.height) / 2 + offset, nullptr, temp_zoom);
> }
> }
>
197a279,283
> case WID_TT_DEMOLISH_TREES: // Demolish aka dynamite button
> HandlePlacePushButton(this, WID_TT_DEMOLISH_TREES, ANIMCURSOR_DEMOLISH, HT_RECT | HT_DIAGONAL);
> this->last_user_action = widget;
> break;
>
238a325,328
> case WID_TT_DEMOLISH_TREES: // Demolish trees only
> VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_DEMOLISH_TREES);
> break;
>
268a359
> case DDSP_DEMOLISH_TREES:
303a395
> Hotkey('D' | WKC_CTRL | WKC_GLOBAL_HOTKEY, "treedozer", WID_TT_DEMOLISH_TREES),
329a422,423
> NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_TT_DEMOLISH_TREES), SetMinimalSize(22, 22),
> SetFill(0, 1), SetDataTip(SPR_IMG_DYNAMITE, STR_TOOLTIP_DEMOLISH_TREES),
diff -r -B -X .diff-exclude vanilla/src/tilearea_type.h cmclient/src/tilearea_type.h
233a234,235
> #define DIAGONAL_TILE_AREA_LOOP(var, ta) for (DiagonalTileIterator var(ta); var != INVALID_TILE; ++var)
>
diff -r -B -X .diff-exclude vanilla/src/tile_cmd.h cmclient/src/tile_cmd.h
64a65
> uint16 population; ///< CM
diff -r -B -X .diff-exclude vanilla/src/tilehighlight_func.h cmclient/src/tilehighlight_func.h
13a14
> #include "tilearea_type.h"
14a16,17
> #include "track_type.h"
> #include "industry_type.h"
29a33,39
>
> RailSnapMode GetRailSnapMode();
> void SetRailSnapMode(RailSnapMode mode);
>
> void StoreRailPlacementEndpoints(TileIndex start_tile, TileIndex end_tile, Track start_track, bool bidirectional = true);
> void StoreRailStationPlacementEndpoints(const TileArea &ta, Axis station_axis);
> void ResetRailPlacementEndpoints();
diff -r -B -X .diff-exclude vanilla/src/tilehighlight_type.h cmclient/src/tilehighlight_type.h
28a29
> HT_POLY = 0x400, ///< polyline mode; connect highlighted track with previous one
43a45,50
> /** Methods of rail track snapping. */
> enum RailSnapMode {
> RSM_NO_SNAP, ///< Not snapping.
> RSM_SNAP_TO_TILE, ///< Snap to a tile.
> RSM_SNAP_TO_RAIL, ///< Snap to other rail tracks.
> };
56a64
> Point new_offs; ///< New value for \a offs; used to determine whether to redraw the selection.
61a70,72
> Point selstart2; ///< The location where the second segment of a polyline track starts.
> Point selend2; ///< The location where the second segment of a polyline track ends.
> HighLightStyle dir2; ///< Direction of the second segment of a polyline track, HT_DIR_END if second segment is not selected. HT_LINE drawstyle.
diff -r -B -X .diff-exclude vanilla/src/toolbar_gui.cpp cmclient/src/toolbar_gui.cpp
57a58,61
> #include "cargo_table_gui.h"
> #include "object_type.h"
> #include "zoning.h"
> #include "watch_gui.h"
82a87
> CBF_BUILD_HQ,
87c92
<
---
> #if 0 // CM
114a120
> #endif
267a274,285
> /* hq hotkey */
> static CallBackFunction BuildCompanyHQ(){
> if (_last_started_action == CBF_BUILD_HQ) {
> ResetObjectToPlace();
> return CBF_NONE;
> } else {
> SetObjectToPlace(SPR_CURSOR_HQ, PAL_NONE, HT_RECT, WC_MAIN_TOOLBAR, 0);
> SetTileSelectSize(2, 2);
> return CBF_BUILD_HQ;
> }
> }
>
300a319
> OME_ZONING,
328a348
> list.emplace_back(new DropDownListStringItem(STR_SETTINGS_MENU_ZONING, OME_ZONING, false));
358a379
> case OME_ZONING: ShowZoningToolbar(); break;
593a615,645
> /* --- CARGOS button menu --- */
>
> static CallBackFunction ToolbarCargosClick(Window *w)
> {
> PopupMainCompanyToolbMenu(w, WID_TN_CARGOS);
> return CBF_NONE;
> }
>
> static CallBackFunction MenuClickCargos(int index)
> {
> ShowCompanyCargos((CompanyID)index);
> return CBF_NONE;
> }
>
> /* --- WATCH button menu --- */
>
> static CallBackFunction ToolbarWatchClick(Window *w)
> {
> PopupMainCompanyToolbMenu(w, WID_TN_WATCH);
> return CBF_NONE;
> }
>
> static CallBackFunction MenuClickWatch(int index)
> {
> if(Company::IsValidID((CompanyID)index)){
> ShowWatchWindow((CompanyID)index, 0);
> }
> else ShowWatchWindow(INVALID_COMPANY, 0);
> return CBF_NONE;
> }
>
1070c1122
< PopupMainToolbMenu(w, _game_mode == GM_EDITOR ? (int)WID_TE_HELP : (int)WID_TN_HELP, STR_ABOUT_MENU_LAND_BLOCK_INFO, _settings_client.gui.newgrf_developer_tools ? 10 : 7);
---
> PopupMainToolbMenu(w, _game_mode == GM_EDITOR ? (int)WID_TE_HELP : (int)WID_TN_HELP, STR_ABOUT_MENU_LAND_BLOCK_INFO, _settings_client.gui.newgrf_developer_tools ? 11 : 8);
1160,1168c1212,1227
< case 0: return PlaceLandBlockInfo();
< case 2: IConsoleSwitch(); break;
< case 3: ShowAIDebugWindow(); break;
< case 4: ShowScreenshotWindow(); break;
< case 5: ShowFramerateWindow(); break;
< case 6: ShowAboutWindow(); break;
< case 7: ShowSpriteAlignerWindow(); break;
< case 8: ToggleBoundingBoxes(); break;
< case 9: ToggleDirtyBlocks(); break;
---
> case 0: return PlaceLandBlockInfo();
> case 1:
> extern bool _novahost;
> if (_networking && _novahost){
> ShowCommandsToolbar();
> }
> break;
> case 2: ShowLoginWindow(); break;
> case 3: IConsoleSwitch(); break;
> case 4: ShowAIDebugWindow(); break;
> case 5: ShowScreenshotWindow(); break;
> case 6: ShowFramerateWindow(); break;
> case 7: ShowAboutWindow(); break;
> case 8: ShowSpriteAlignerWindow(); break;
> case 9: ToggleBoundingBoxes(); break;
> case 10: ToggleDirtyBlocks(); break;
1333a1393
> MenuClickCargos, // 8.5
1336a1397
> MenuClickWatch, // 11.5
1795a1857
> WID_TN_CARGOS,
1798a1861
> WID_TN_WATCH,
1966a2030
> ToolbarCargosClick,
1969a2034
> ToolbarWatchClick,
2030a2096,2104
> MTHK_BUILD_HQ,
> MTHK_COMMANDS_GUI,
> MTHK_CARGOTABLE,
> MTHK_TREES,
> MTHK_ZONING,
> MTHK_LOGINWINDOW,
> MTHK_SETTINGS_ADV,
> MTHK_NEWGRF,
> MTHK_LANDINFO,
2063c2137
< this->SetWidgetsDisabledState(Company::GetNumItems() == 0, WID_TN_STATIONS, WID_TN_FINANCES, WID_TN_TRAINS, WID_TN_ROADVEHS, WID_TN_SHIPS, WID_TN_AIRCRAFT, WIDGET_LIST_END);
---
> this->SetWidgetsDisabledState(Company::GetNumItems() == 0, WID_TN_STATIONS, WID_TN_FINANCES, WID_TN_CARGOS, WID_TN_WATCH, WID_TN_TRAINS, WID_TN_ROADVEHS, WID_TN_SHIPS, WID_TN_AIRCRAFT, WIDGET_LIST_END);
2075a2150,2157
> void DrawWidget(const Rect &r, int widget) const override {
> if (widget == WID_TN_WATCH) {
> Dimension d = GetSpriteSize(SPR_CENTRE_VIEW_VEHICLE);
> uint offset = this->IsWidgetLowered(WID_TN_WATCH) ? 1 : 0;
> DrawSprite(SPR_CENTRE_VIEW_VEHICLE, PAL_NONE, (r.left + r.right - d.width) / 2 + offset, (r.top + r.bottom - d.height) / 2 + offset);
> }
> }
>
2124c2206
< case MTHK_CHEATS: if (!_networking) ShowCheatWindow(); break;
---
> case MTHK_CHEATS: ShowCheatWindow(); break;
2127a2210,2213
> case MTHK_COMMANDS_GUI: extern bool _novahost; if (_networking && _novahost){ ShowCommandsToolbar(); } break;
> case MTHK_BUILD_HQ: if(_current_company != COMPANY_SPECTATOR){ _last_started_action = BuildCompanyHQ(); } break;
> case MTHK_CARGOTABLE: if(_current_company != COMPANY_SPECTATOR){ ShowCompanyCargos(_current_company); } break;
> case MTHK_TREES: if(_current_company != COMPANY_SPECTATOR){ BuildTreesWindow(); } break;
2128a2215,2219
> case MTHK_ZONING: ShowZoningToolbar(); break;
> case MTHK_LOGINWINDOW: ShowLoginWindow(); break;
> case MTHK_SETTINGS_ADV: ShowGameSettings(); break;
> case MTHK_NEWGRF: ShowNewGRFSettings(!_networking && _settings_client.gui.UserIsAllowedToChangeNewGRFs(), true, true, &_grfconfig); break;
> case MTHK_LANDINFO: _last_started_action = PlaceLandBlockInfo(); break;
2133a2225,2242
> virtual void BuildTreesWindow(){
> ShowBuildTreesToolbar();
> Window *w = FindWindowById(WC_BUILD_TREES, 0);
> if(w != NULL){
> if(w->IsWidgetLowered(WID_BT_TYPE_RANDOM)){
> w->RaiseWidget(WID_BT_TYPE_RANDOM);
> ResetObjectToPlace();
> }
> else{
> w->OnHotkey(WID_BT_TYPE_RANDOM);
> }
>
> }
> /*
> if (!w->IsWidgetLowered(WID_BT_TYPE_RANDOM))
> w->OnClick(Point(), WID_BT_TYPE_RANDOM, 1);*/
> }
>
2142c2251,2258
< ShowLandInfo(tile);
---
> VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_MEASURE);
> break;
>
> case CBF_BUILD_HQ:
> if(DoCommandP(tile, OBJECT_HQ, 0, CMD_BUILD_OBJECT | CMD_MSG(STR_ERROR_CAN_T_BUILD_COMPANY_HEADQUARTERS))){
> ResetObjectToPlace();
> this->RaiseButtons();
> }
2153a2270,2275
> void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) override
> {
> VpSelectTilesWithMethod(pt.x, pt.y, select_method);
> }
>
>
2239a2362,2369
> Hotkey('N', "nova_commands", MTHK_COMMANDS_GUI),
> Hotkey(WKC_CTRL | WKC_F2, "cargo_table", MTHK_CARGOTABLE),
> Hotkey(WKC_CTRL | 'H', "build_hq", MTHK_BUILD_HQ),
> Hotkey('I', "trees", MTHK_TREES),
> Hotkey((uint16)0, "zoning", MTHK_ZONING),
> Hotkey((uint16)0, "login_window", MTHK_LOGINWINDOW),
> Hotkey((uint16)0, "settings_adIanced", MTHK_SETTINGS_ADV),
> Hotkey((uint16)0, "newgrf_window", MTHK_NEWGRF),
2240a2371
> Hotkey((uint16)0, "land_info", MTHK_LANDINFO),
2257a2389
> SPR_IMG_COMPANY_CARGO, // WID_TN_CARGOS
2260a2393
> 0, // WID_TN_WATCH
2515c2648
< ShowLandInfo(tile);
---
> VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_MEASURE);
diff -r -B -X .diff-exclude vanilla/src/town_cmd.cpp cmclient/src/town_cmd.cpp
54a55,56
> #include "citymania/highlight.hpp"
>
56a59,70
> bool _cb_enabled = false;
> uint _cb_storage = 0;
> uint CBREQ[NUM_CARGO] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};//CB
> uint CBFROM[NUM_CARGO] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};//CB
> uint CBDECAY[NUM_CARGO] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};//CB
> uint days_in_month[] = {31, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};//CB
> void CB_UpdateTownStorage(Town *t); //CB
>
> const Money NOVAPOLIS_COMPANY_MONEY_THRESHOLD = INT64_MAX >> 4;
> TownsGrowthTilesIndex _towns_growth_tiles_last_month;
> TownsGrowthTilesIndex _towns_growth_tiles;
>
201a216,235
> /**
> * Updates the town label of the town after changes in rating. The colour scheme is:
> * Red: Appalling and Very poor ratings.
> * Orange: Poor and mediocre ratings.
> * Yellow: Good rating.
> * White: Very good rating (standard).
> * Green: Excellent and outstanding ratings.
> */
> void Town::UpdateLabel()
> {
> if (!(_game_mode == GM_EDITOR) && (_local_company < MAX_COMPANIES)) {
> int r = this->ratings[_local_company];
> if (r < RATING_VERYPOOR) this->town_label = 0; // Appalling and Very Poor, RED
> else if(r < RATING_MEDIOCRE) this->town_label = 1; // Poor and Mediocre, ORANGE
> else if(r < RATING_GOOD) this->town_label = 2; // Good, YELLOW
> else if(r < RATING_VERYGOOD) this->town_label = 3; // Very Good, WHITE
> else this->town_label = 4; // Excellent and Outstanding, GREEN
> }
> }
>
398a433
> this->UpdateLabel();
411a447
> SetWindowDirty(WC_CB_TOWN, this->index);
435a472,473
> // if(mod > 0 && t->houses_construction > 0) t->houses_construction--;
>
488c526,529
< ChangePopulation(Town::GetByTile(tile), HouseSpec::Get(GetHouseType(tile))->population);
---
> HouseID house_id = GetHouseType(tile);
> Town *town = Town::GetByTile(tile);
> const HouseSpec *hs = HouseSpec::Get(house_id);
> ChangePopulation(town, hs->population);
489a531,532
> if (hs->building_flags & BUILDING_HAS_1_TILE)
> town->houses_construction--;
627a671,675
> t->houses_demolished++;
> UpdateTownGrowthTile(tile, TGTS_RH_REMOVED);
> } else {
> t->houses_reconstruction++;
> UpdateTownGrowthTile(tile, TGTS_RH_REBUILT);
655a704,708
> if (_current_company == COMPANY_FIRST &&
> Company::Get(_current_company)->money > NOVAPOLIS_COMPANY_MONEY_THRESHOLD) {
> if (t->growing) t->cb_houses_removed++;
> UpdateTownGrowthTile(tile, t->growing ? TGTS_CB_HOUSE_REMOVED: TGTS_CB_HOUSE_REMOVED_NOGROW);
> }
746a800
> td->population = hs->population;
864a919,990
> static void DoRegularFunding(Town *t)
> {
> bool fund_regularly = HasBit(t->fund_regularly, _local_company);
> bool do_powerfund = HasBit(t->do_powerfund, _local_company);
>
> if (do_powerfund && (_settings_client.gui.powerfund_money > Company::Get(_local_company)->money ||
> _settings_client.gui.powerfund_houses < t->cache.num_houses)) {
> do_powerfund = false;
> }
>
> if (!fund_regularly && !do_powerfund)
> return;
>
> if (_local_company == COMPANY_SPECTATOR)
> return;
>
> if (CB_Enabled() && !t->growing)
> return;
>
>
> // Funding with grow_counter == 1 doesn't speed up next house building,
> // so trying to avoid it. This means no powerfunding with gr <= 1, and no
> // regular funding with grow_counter == 1 unless gr is also 1
> // (we need to fund anyway even if it doesn't speed up next house)
> // And in case town is not growing ignore grow_counter and growth_rate
> // completely (it will start growing once we fund it)
> bool is_growing = !HasBit(t->flags, TOWN_IS_GROWING);
> if (fund_regularly) {
> if (t->fund_buildings_months > 0) return;
> if (is_growing
> && t->growth_rate > 2 * TOWN_GROWTH_TICKS
> && t->grow_counter <= 2 * TOWN_GROWTH_TICKS) return;
> } else if (do_powerfund) {
> if (t->growth_rate <= 2 * TOWN_GROWTH_TICKS) return;
> if (t->grow_counter != t->growth_rate && is_growing) return;
> } else return;
>
> CompanyID old = _current_company;
> _current_company = _local_company;
> DoCommandP(t->xy, t->index, HK_FUND, CMD_DO_TOWN_ACTION | CMD_NO_ESTIMATE);
> _current_company = old;
> }
>
> static void DoRegularAdvertising(Town *t) {
> if (!HasBit(t->advertise_regularly, _local_company))
> return;
>
> if (t->ad_ref_goods_entry == NULL) {
> // Pick as ref station and cargo with min rating
> for (Station *st : Station::Iterate()) {
> if (st->owner == _local_company && DistanceManhattan(t->xy, st->xy) <= 20) {
> for (CargoID i = 0; i < NUM_CARGO; i++)
> if (st->goods[i].HasRating() && (t->ad_ref_goods_entry == NULL ||
> t->ad_ref_goods_entry->rating < st->goods[i].rating)) {
> t->ad_ref_goods_entry = &st->goods[i];
> }
> }
> }
>
> if (t->ad_ref_goods_entry == NULL)
> return;
> }
>
> if (t->ad_ref_goods_entry->rating >= t->ad_rating_goal)
> return;
>
> CompanyID old = _current_company;
> _current_company = _local_company;
> DoCommandP(t->xy, t->index, HK_LADVERT, CMD_DO_TOWN_ACTION | CMD_NO_ESTIMATE);
> _current_company = old;
> }
>
868a995
> uint16 houses_prev = t->cache.num_houses;
871a999,1001
> if (t->cache.num_houses <= houses_prev && (t->growing || !CB_Enabled())){
> t->houses_skipped++;
> }
872a1003,1005
> if (t->growing || !CB_Enabled()){
> t->cycles_skipped++;
> }
878a1012,1013
> DoRegularFunding(t);
> DoRegularAdvertising(t);
1529c1664
< static bool GrowTownAtRoad(Town *t, TileIndex tile)
---
> static bool GrowTownAtRoad(Town *t, TileIndex start_tile, TileIndex &tile)
1533a1669
> tile = start_tile;
1652c1788,1790
< bool success = GrowTownAtRoad(t, tile);
---
> uint16 houses_prev = t->cache.num_houses;
> TileIndex end_tile;
> bool success = GrowTownAtRoad(t, tile, end_tile);
1653a1792,1795
> if (!success)
> UpdateTownGrowthTile(end_tile, TGTS_CYCLE_SKIPPED);
> else if (t->cache.num_houses <= houses_prev)
> UpdateTownGrowthTile(end_tile, TGTS_HOUSE_SKIPPED);
1668a1811
> UpdateTownGrowthTile(tile, TGTS_HOUSE_SKIPPED);
1676a1820
> UpdateTownGrowthTile(tile, TGTS_CYCLE_SKIPPED);
1682a1827
> auto prev_tz0 = t->cache.squared_town_zone_radius[0];
1721a1867,1868
> if (!_generating_world)
> citymania::UpdateTownZoning(t, prev_tz0);
1732a1880,1999
> //CB
>
> bool CB_Enabled(){
> return _cb_enabled;
> }
> void CB_SetCB(bool cb){
> _cb_enabled = cb;
> if(!_cb_enabled){
> CB_ResetRequirements();
> }
> }
>
> uint CB_GetStorage() {
> return _cb_storage;
> }
>
> void CB_SetStorage(uint storage){
> _cb_storage = storage;
> }
>
> void CB_SetRequirements(CargoID cargo, uint req, uint from, uint decay){
> CBREQ[cargo] = req;
> CBFROM[cargo] = from;
> CBDECAY[cargo] = decay;
> }
> void CB_ResetRequirements() {
> for(CargoID cargo = 0; cargo < NUM_CARGO; cargo++){
> CB_SetRequirements(cargo, 0, 0, 0);
> }
> }
> uint CB_GetReq(CargoID cargo){
> return CBREQ[cargo];
> }
> uint CB_GetFrom(CargoID cargo){
> return CBFROM[cargo];
> }
> uint CB_GetDecay(CargoID cargo){
> return CBDECAY[cargo];
> }
> int CB_GetTownReq(uint population, uint req, uint from, bool from_non_important, bool prev_month)
> {
> if (req > 0 && (population >= from || from_non_important)) {
> uint leap = 0;
> Month month = _cur_month;
> if (!prev_month) month++;
> if(month == 2){
> if((_cur_year % 4 == 0 && _cur_year % 100 != 0) || _cur_year % 400 == 0) leap = 1;
> }
> uint days_this_month = days_in_month[month] + leap;
> // x cargo for 1000 people
> return population * req * days_this_month / 31000; // 31 days divide by 1000 (pop)
> }
> return 0;
> }
> uint CB_GetMaxTownStorage(uint32 population, uint req)
> {
> return req > 0 ? (population * req * _cb_storage / 1000) : 0;
> }
>
> uint CB_GetMaxTownStorage(Town *town, uint cargo) {
> return CBREQ[cargo] > 0 ? (town->cache.population * CBREQ[cargo] * _cb_storage / 1000) : 0;
> }
>
> void CB_UpdateTownStorage(Town *t)
> {
> InvalidateWindowData(WC_CB_TOWN, t->index);
> t->growing = true;
> if (!HasBit(t->flags, TOWN_IS_GROWING)) { //dont grow if not funded or missing transportation
> t->growing = false;
> }
> for (uint i = 0; i < NUM_CARGO ; i++) {
> if(CBREQ[i] == 0) continue;
>
> t->storage[i] += t->new_act_cargo[i]; // add accumulated last month
> t->storage[i] -= CB_GetTownReq(t->cache.population, CBREQ[i], CBFROM[i], false, true); //subtract monthly req
> t->storage[i] = min((int)CB_GetMaxTownStorage(t->cache.population, CBREQ[i]), t->storage[i]); //check max storage
>
> if (t->storage[i] < 0) {
> t->growing = false;
> t->delivered_enough[i] = false;
> t->storage[i] = 0;
> }
> else t->delivered_enough[i] = true;
>
> if (CBDECAY[i] == 100 && t->storage[i] > 0) {
> t->storage[i] = 0;
> }
> else {
> t->storage[i] *= (100 - CBDECAY[i]);
> t->storage[i] /= 100;
> }
> t->act_cargo[i] = t->new_act_cargo[i];
> t->new_act_cargo[i] = 0;
> }
>
> if (_settings_game.game_creation.landscape == LT_TROPIC) {
> if (GetTropicZone(t->xy) == TROPICZONE_DESERT && (t->received[TE_FOOD].old_act <= 0 || t->received[TE_WATER].old_act <= 0) && t->cache.population > 60) {
> t->growing = false;
> }
> }
> else if (_settings_game.game_creation.landscape == LT_ARCTIC) {
> if (TilePixelHeight(t->xy) >= GetSnowLine() && t->received[TE_FOOD].old_act <= 0 && t->cache.population > 90) {
> t->growing = false;
> }
> }
> }
> //CB
>
> void UpdateTownGrowthTile(TileIndex tile, TownGrowthTileState state) {
> _towns_growth_tiles[tile] = max(_towns_growth_tiles[tile], state);
> }
>
> void ResetTownsGrowthTiles() {
> _towns_growth_tiles_last_month.clear();
> _towns_growth_tiles.clear();
> }
>
>
> extern TileIndex _closest_cache_ref;
>
1772a2040,2056
> //CB
> t->growing = false;
> for (uint i = 0; i < NUM_CARGO ; i++) {
> t->storage[i] = 0;
> t->act_cargo[i] = 0;
> t->new_act_cargo[i] = 0;
> t->delivered_enough[i] = false;
> }
> t->houses_construction = 0;
> t->houses_reconstruction = 0;
> t->houses_demolished = 0;
> t->fund_regularly = 0;
> t->do_powerfund = 0;
> t->advertise_regularly = 0;
> t->ad_rating_goal = 95;
> t->ad_ref_goods_entry = NULL;
> //CB
1792a2077
> t->town_label = 3;
1813a2099
> _closest_cache_ref = INVALID_TILE;
2563a2850,2851
> t->cache.potential_pop += hs->population;
> t->houses_construction++;
2578a2867
> t->houses_construction--;
2584a2874
> UpdateTownGrowthTile(tile, TGTS_NEW_HOUSE);
2651a2942,2943
> } else {
> t->houses_construction--;
2654a2947
> t->cache.potential_pop -= hs->population;
2818a3112
> InvalidateWindowData(WC_CB_TOWN, p1);
3154a3449
> SetWindowDirty(WC_CB_TOWN, t->index);
3209a3505
> t->UpdateVirtCoord();
3352a3649
> t->UpdateVirtCoord();
3439a3737
> t->growing_by_chance = false;
3440a3739
> SetWindowDirty(WC_CB_TOWN, t->index);
3463a3763
> SetWindowDirty(WC_CB_TOWN, t->index);
3467c3767,3770
< if (t->fund_buildings_months == 0 && CountActiveStations(t) == 0 && !Chance16(1, 12)) return;
---
> if (t->fund_buildings_months == 0 && CountActiveStations(t) == 0) {
> if(!Chance16(1, 12)) return;
> t->growing_by_chance = true;
> }
3470a3774
> SetWindowDirty(WC_CB_TOWN, t->index);
3479a3784
> SetWindowDirty(WC_CB_TOWN, t->index);
3638a3944
> t->UpdateVirtCoord();
3681a3988,3990
> _towns_growth_tiles_last_month = _towns_growth_tiles;
> _towns_growth_tiles.clear();
>
3688a3998,3999
> if (CB_Enabled() && !t->larger_town) CB_UpdateTownStorage(t); //CB
>
3693a4005,4015
>
> DoRegularFunding(t);
>
> t->houses_demolished = 0;
> t->houses_reconstruction = 0;
> t->houses_skipped_last_month = t->houses_skipped - t->houses_skipped_prev;
> t->houses_skipped_prev = t->houses_skipped;
> t->cycles_skipped_last_month = t->cycles_skipped - t->cycles_skipped_prev;
> t->cycles_skipped_prev = t->cycles_skipped;
> t->cb_houses_removed_last_month = t->cb_houses_removed - t->cb_houses_removed_prev;
> t->cb_houses_removed_prev = t->cb_houses_removed;
diff -r -B -X .diff-exclude vanilla/src/town_gui.cpp cmclient/src/town_gui.cpp
18a19
> #include "goal_base.h"
41a43,60
> #include "hotkeys.h"
> #include
> #include "console_func.h"
>
> struct CargoX {
> int id;
> int from;
> };
> void ShowCBTownWindow(uint town);
> static void DrawExtraTownInfo (const Rect &r, uint &y, Town *town, uint line, bool show_house_states_info=false);
>
> bool TownExecuteAction(const Town *town, uint action){
> if(!(action == HK_STATUE && HasBit(town->statues, _current_company))){ //don't built statue when there is one
> return DoCommandP(town->xy, town->index, action, CMD_DO_TOWN_ACTION | CMD_MSG(STR_ERROR_CAN_T_DO_THIS));
> }
> return false;
> }
>
169a189
> SetDParam(3, this->town->ratings[c->index]);
174c194
< DrawString(text_left, text_right, y, STR_LOCAL_AUTHORITY_COMPANY_RATING);
---
> DrawString(text_left, text_right, y, STR_LOCAL_AUTHORITY_COMPANY_RATING_NUM);
298a319,326
>
> virtual EventState OnHotkey(int hotkey)
> {
> TownExecuteAction(this->town, hotkey);
> return ES_HANDLED;
> }
>
> static HotkeyList hotkeys;
300a329,338
> static Hotkey town_hotkeys[] = {
> Hotkey((uint16)0, "small_advert", HK_SADVERT),
> Hotkey((uint16)0, "medium_advert", HK_MADVERT),
> Hotkey(WKC_CTRL | 'D', "large_advert", HK_LADVERT),
> Hotkey(WKC_CTRL | 'S', "build_statue", HK_STATUE),
> Hotkey(WKC_CTRL | 'F', "fund_buildings", HK_FUND),
> HOTKEY_LIST_END
> };
> HotkeyList TownAuthorityWindow::hotkeys("town_gui", town_hotkeys);
>
305c343,344
< _nested_town_authority_widgets, lengthof(_nested_town_authority_widgets)
---
> _nested_town_authority_widgets, lengthof(_nested_town_authority_widgets),
> &TownAuthorityWindow::hotkeys
312a352,354
> // static int TownTicksToDays(int ticks) {
> // return (ticks * TOWN_GROWTH_TICKS + DAY_TICKS / 2) / DAY_TICKS;
> // }
320a363
> bool wcb_disable;
336a380,383
> // extern bool _novahost;
> // this->wcb_disable = !_networking || !_novahost || this->town->larger_town || _game_mode == GM_EDITOR;
> // this->wcb_disable = (_game_mode == GM_EDITOR);
> this->SetWidgetDisabledState(WID_TV_CB, _game_mode == GM_EDITOR);
346c393,404
< if (widget == WID_TV_CAPTION) SetDParam(0, this->town->index);
---
> if (widget == WID_TV_CAPTION){
> SetDParam(0, this->town->index);
> }
> if (widget == WID_TV_CB){
> // if(this->wcb_disable) SetDParam(0, STR_EMPTY);
> // else
> SetDParam(0, STR_BUTTON_CB_YES);
> }
> }
>
> virtual void OnHundrethTick() {
> this->SetDirty();
376a435,436
> DrawExtraTownInfo(r, y, this->town, FONT_HEIGHT_NORMAL, true); //CB
>
479a540,544
> case WID_TV_CB:
> // if(_networking)
> ShowCBTownWindow(this->window_number);
> break;
>
491a557,559
> // case WID_TV_CB:
> // if(this->wcb_disable || !CB_Enabled()) size->width = 0;
> // break;
501c569
< uint aimed_height = 3 * FONT_HEIGHT_NORMAL + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
---
> uint aimed_height = 8 * FONT_HEIGHT_NORMAL + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
564a633,644
>
> virtual EventState OnHotkey(int hotkey)
> {
> if(hotkey == WID_TV_CB) ShowCBTownWindow(this->window_number);
> else if (hotkey == HK_STATUE + 0x80){
> TownExecuteAction(this->town, HK_STATUE);
> return ES_NOT_HANDLED;
> }
> return Window::OnHotkey(hotkey);
> }
>
> static HotkeyList hotkeys;
566a647,655
> static Hotkey town_window_hotkeys[] = {
> Hotkey((uint16)0, "location", WID_TV_CENTER_VIEW),
> Hotkey((uint16)0, "local_authority", WID_TV_SHOW_AUTHORITY),
> Hotkey((uint16)0, "cb_window", WID_TV_CB),
> Hotkey(WKC_CTRL | 'S', "build_statue", HK_STATUE + 0x80),
> HOTKEY_LIST_END
> };
> HotkeyList TownViewWindow::hotkeys("town_window", town_window_hotkeys);
>
582,583c671,672
< NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
< NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_TV_CENTER_VIEW), SetMinimalSize(80, 12), SetFill(1, 1), SetResize(1, 0), SetDataTip(STR_BUTTON_LOCATION, STR_TOWN_VIEW_CENTER_TOOLTIP),
---
> NWidget(NWID_HORIZONTAL), //, NC_EQUALSIZE
> NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_TV_CENTER_VIEW), SetMinimalSize(60, 12), SetFill(1, 1), SetResize(1, 0), SetDataTip(STR_BUTTON_LOCATION, STR_TOWN_VIEW_CENTER_TOOLTIP),
585c674,675
< NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_TV_CHANGE_NAME), SetMinimalSize(80, 12), SetFill(1, 1), SetResize(1, 0), SetDataTip(STR_BUTTON_RENAME, STR_TOWN_VIEW_RENAME_TOOLTIP),
---
> NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_TV_CHANGE_NAME), SetMinimalSize(60, 12), SetFill(1, 1), SetResize(1, 0), SetDataTip(STR_BUTTON_RENAME, STR_TOWN_VIEW_RENAME_TOOLTIP),
> NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_TV_CB), SetMinimalSize(20, 12), SetFill(1, 1), SetResize(1, 0), SetDataTip(STR_BUTTON_CB, 0),
596c686,687
< _nested_town_game_view_widgets, lengthof(_nested_town_game_view_widgets)
---
> _nested_town_game_view_widgets, lengthof(_nested_town_game_view_widgets),
> &TownViewWindow::hotkeys
618a710
> NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_TV_CB), SetMinimalSize(20, 12), SetFill(1, 1), SetResize(1, 0), SetDataTip(STR_BUTTON_CB, 0),
644c736
< NWidget(WWT_CAPTION, COLOUR_BROWN), SetDataTip(STR_TOWN_DIRECTORY_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
---
> NWidget(WWT_CAPTION, COLOUR_BROWN, TDW_CAPTION_TEXT), SetDataTip(STR_TOWN_DIRECTORY_CAPTION_EXTRA, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
724a817,834
> /** Sort by real population (default descending, as big towns are of the most interest). */
> static bool TownRealPopulationSorter(const Town * const &a, const Town * const &b)
> {
> uint32 a_population = a->cache.potential_pop;
> uint32 b_population = b->cache.potential_pop;
> if (a_population == b_population) return TownDirectoryWindow::TownNameSorter(a, b);
> return a_population < b_population;
> }
>
> /** Sort by number of houses (default descending, as big towns are of the most interest). */
> static bool TownHousesSorter(const Town * const &a, const Town * const &b)
> {
> uint32 a_houses = a->cache.num_houses;
> uint32 b_houses = b->cache.num_houses;
> if (a_houses == b_houses) return TownDirectoryWindow::TownPopulationSorter(a, b);
> return a_houses < b_houses;
> }
>
774a885,895
> case TDW_CAPTION_TEXT: {
> uint16 town_number = 0;
> uint16 city_number = 0;
> for (Town *t : Town::Iterate()) {
> if(t->larger_town) city_number++;
> town_number++;
> }
> SetDParam(0, city_number);
> SetDParam(1, town_number);
> break;
> }
826c947,950
< DrawString(text_left, text_right, y + (this->resize.step_height - FONT_HEIGHT_NORMAL) / 2, GetTownString(t));
---
> SetDParam(2, t->cache.potential_pop);
> SetDParam(3, t->cache.num_houses);
> /* CITIES DIFFERENT COLOUR*/
> DrawString(text_left, text_right, y + (this->resize.step_height - FONT_HEIGHT_NORMAL) / 2, t->larger_town ? STR_TOWN_DIRECTORY_CITY_COLOUR : STR_TOWN_DIRECTORY_TOWN_COLOUR);
865c989,990
< d = maxdim(d, GetStringBoundingBox(GetTownString(t)));
---
> SetDParamMaxDigits(2, 5);
> d = maxdim(d, GetStringBoundingBox(STR_TOWN_DIRECTORY_TOWN_COLOUR));
989a1115,1116
> STR_SORT_BY_REAL_POPULATION,
> STR_SORT_BY_HOUSES,
997a1125,1126
> &TownRealPopulationSorter,
> &TownHousesSorter,
1258a1388,1829
> }
>
> //CB
> static void DrawExtraTownInfo (const Rect &r, uint &y, Town *town, uint line, bool show_house_states_info) {
> //real pop and rating
> SetDParam(0, town->cache.potential_pop);
> SetDParam(1, town->ratings[_current_company]);
> DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y += line, STR_TOWN_VIEW_REALPOP_RATE);
> //town stats
> // int grow_rate = 0;
> // if(town->growth_rate == TOWN_GROW_RATE_CUSTOM_NONE) grow_rate = 0;
> // else grow_rate = TownTicksToDays((town->growth_rate & ~TOWN_GROW_RATE_CUSTOM) + 1);
>
> SetDParam(0, town->growth_rate);
> SetDParam(1, HasBit(town->flags, TOWN_CUSTOM_GROWTH) ? STR_TOWN_VIEW_GROWTH_RATE_CUSTOM : STR_EMPTY);
> // SetDParam(2, town->grow_counter < 16000 ? TownTicksToDays(town->grow_counter + 1) : -1);
> SetDParam(2, town->grow_counter);
> SetDParam(3, town->time_until_rebuild);
> SetDParam(4, HasBit(town->flags, TOWN_IS_GROWING) ? 1 : 0);
> SetDParam(5, town->fund_buildings_months);
> DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y += line, STR_TOWN_VIEW_GROWTH);
>
> if (show_house_states_info) {
> SetDParam(0, town->houses_construction);
> SetDParam(1, town->houses_reconstruction);
> SetDParam(2, town->houses_demolished);
> DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y += line, STR_TOWN_VIEW_HOUSE_STATE);
> }
>
> ///houses stats
> SetDParam(0, town->houses_skipped);
> SetDParam(1, town->houses_skipped_last_month);
> SetDParam(2, town->cycles_skipped);
> SetDParam(3, town->cycles_skipped_last_month);
> SetDParam(4, town->cb_houses_removed);
> SetDParam(5, town->cb_houses_removed_last_month);
> DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y += line, STR_TOWN_VIEW_GROWTH_TILES);
> }
>
> bool CB_sortCargoesByFrom(CargoX first, CargoX second){
> return (first.from < second.from) ? true : false;
> }
>
> struct CBTownWindow : Window {
> private:
> Town *town;
> std::list cargoes;
>
> enum CBTownWindowPlanes {
> CBTWP_MP_GOALS = 0,
> CBTWP_MP_CB,
> };
>
> public:
> CBTownWindow(WindowDesc *desc, WindowNumber window_number) : Window(desc)
> {
> for (uint i = 0; i < NUM_CARGO ; i++) {
> CargoX c;
> c.id = i;
> c.from = CB_GetFrom(i);
> this->cargoes.push_back(c);
> }
> cargoes.sort(CB_sortCargoesByFrom);
> this->town = Town::Get(window_number);
> this->InitNested(window_number);
>
> if(HasBit(this->town->fund_regularly, _local_company)) this->LowerWidget(WID_CB_FUND_REGULAR);
> if(HasBit(this->town->do_powerfund, _local_company)) this->LowerWidget(WID_CB_POWERFUND);
> if(HasBit(this->town->advertise_regularly, _local_company)) this->LowerWidget(WID_CB_ADVERT_REGULAR);
> }
>
> virtual void OnClick(Point pt, int widget, int click_count)
> {
> switch (widget) {
> case WID_CB_LOCATION:
> case WID_CB_CENTER_VIEW: // scroll to location
> if (_ctrl_pressed) {
> ShowExtraViewPortWindow(this->town->xy);
> }
> else {
> ScrollMainWindowToTile(this->town->xy);
> }
> break;
> case WID_CB_ADVERT:
> TownExecuteAction(this->town, HK_LADVERT);
> break;
> case WID_CB_FUND:
> TownExecuteAction(this->town, HK_FUND);
> break;
> case WID_CB_FUND_REGULAR:
> ToggleBit(this->town->fund_regularly, _local_company);
> this->SetWidgetLoweredState(widget, HasBit(this->town->fund_regularly, _local_company));
> this->SetWidgetDirty(widget);
> break;
> case WID_CB_POWERFUND:
> ToggleBit(this->town->do_powerfund, _local_company);
> this->SetWidgetLoweredState(widget, HasBit(this->town->do_powerfund, _local_company));
> this->SetWidgetDirty(widget);
> break;
> case WID_CB_ADVERT_REGULAR:
> if (!this->town->advertise_regularly) {
> SetDParam(0, ToPercent8(this->town->ad_rating_goal));
> ShowQueryString(STR_JUST_INT, STR_CB_ADVERT_REGULAR_RATING_TO_KEEP,
> 4, this, CS_NUMERAL, QSF_ACCEPT_UNCHANGED);
> } else this->OnQueryTextFinished(NULL);
> break;
> case WID_CB_TOWN_VIEW: // Town view window
> ShowTownViewWindow(this->window_number);
> break;
> case WID_CB_SHOW_AUTHORITY: // town authority
> ShowTownAuthorityWindow(this->window_number);
> break;
> }
> }
>
> virtual void OnQueryTextFinished(char *str)
> {
> if (str != NULL) SetBit(this->town->advertise_regularly, _local_company);
> else ClrBit(this->town->advertise_regularly, _local_company);
> this->town->ad_ref_goods_entry = NULL;
> this->SetWidgetLoweredState(WID_CB_ADVERT_REGULAR, HasBit(this->town->advertise_regularly, _local_company));
> this->SetWidgetDirty(WID_CB_ADVERT_REGULAR);
>
> if (str == NULL)
> return;
> uint val = Clamp(StrEmpty(str) ? 0 : strtol(str, NULL, 10), 1, 100);
> this->town->ad_rating_goal = ((val << 8) + 255) / 101;
> }
>
> virtual void SetStringParameters(int widget) const
> {
> if (widget == WID_TV_CAPTION){
> SetDParam(0, this->town->index);
> }
> }
>
> const Company *GetCompany() const {
> for (Company *c : Company::Iterate()) {
> if (c->location_of_HQ != INVALID_TILE
> && DistanceMax(c->location_of_HQ, this->town->xy) < 11)
> return c;
> }
> return nullptr;
> }
>
> void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
> {
> static const uint EXP_TOPPADDING = 5;
> static const uint EXP_LINESPACE = 2; // Amount of vertical space for a horizontal (sub-)total line.
>
> switch(widget){
> case WID_CB_DETAILS:
> size->height = (FONT_HEIGHT_NORMAL + EXP_LINESPACE) * 5;
> break;
> case WID_CB_GOALS: {
> uint desired_height = 0;
> auto company = GetCompany();
> if (company) {
> for(const Goal *g : Goal::Iterate()) {
> if (g->company == company->index) {
> desired_height++;
> }
> }
> }
> if (desired_height > 0)
> size->height = desired_height * (FONT_HEIGHT_NORMAL + EXP_LINESPACE) + EXP_TOPPADDING - EXP_LINESPACE;
> break;
> }
> case WID_CB_CARGO_NAME:
> case WID_CB_CARGO_AMOUNT:
> case WID_CB_CARGO_REQ:
> case WID_CB_CARGO_STORE:
> case WID_CB_CARGO_STORE_PCT:
> case WID_CB_CARGO_FROM:
> case WID_CB_CARGO_PREVIOUS: {
> uint desired_height = 0;
> for(CargoID cargo = 0; cargo < NUM_CARGO; cargo++){
> if(CB_GetReq(cargo) > 0) desired_height++;
> }
> if (desired_height > 0)
> size->height = desired_height * (FONT_HEIGHT_NORMAL + EXP_LINESPACE) + EXP_TOPPADDING - EXP_LINESPACE;
> break;
> }
> }
> }
>
> void DrawWidget(const Rect &r, int widget) const
> {
> static const uint EXP_LINESPACE = FONT_HEIGHT_NORMAL + 2;
> uint y = r.top + WD_FRAMERECT_TOP;
> switch(widget){
> case WID_CB_DETAILS:{
> //growing
> if(this->town->growing) DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y, STR_TOWN_CB_GROWING );
> else DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y, STR_TOWN_CB_NOT_GROWING );
> //population
> SetDParam(0, this->town->cache.population);
> SetDParam(1, this->town->cache.num_houses);
> DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y += EXP_LINESPACE, STR_TOWN_VIEW_POPULATION_HOUSES);
>
> DrawExtraTownInfo(r, y, this->town, EXP_LINESPACE, false);
> //regular funding
> if(this->town->fund_regularly != 0){
> DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y += EXP_LINESPACE, STR_CB_FUNDED_REGULARLY);
> }
> break;
> }
> case WID_CB_GOALS: {
> auto company = GetCompany();
> if (!company) break;
> for(const Goal *g : Goal::Iterate()) {
> if (g->company != company->index)
> continue;
> SetDParamStr(0, g->text);
> DrawString(r.left + WD_FRAMERECT_LEFT,
> r.right - WD_FRAMERECT_RIGHT,
> y, STR_GOALS_TEXT);
> y += EXP_LINESPACE;
> }
> break;
> }
> /* Citybuilder things*/
> case WID_CB_CARGO_NAME:
> case WID_CB_CARGO_AMOUNT:
> case WID_CB_CARGO_REQ:
> case WID_CB_CARGO_STORE:
> case WID_CB_CARGO_STORE_PCT:
> case WID_CB_CARGO_FROM:
> case WID_CB_CARGO_PREVIOUS: {
> if (this->town->larger_town) break;
> uint delivered;
> uint requirements;
> uint from;
> StringID string_to_draw;
>
> //for cycle
> std::list cargoes2 = this->cargoes;
> std::list::iterator it2;
> for (it2 = cargoes2.begin(); it2 != cargoes2.end(); ++it2) {
> CargoX cargox;
> cargox = *it2;
> if (it2 == cargoes2.begin()) { //header
> DrawString(r.left + WD_FRAMERECT_LEFT + 14, r.right - WD_FRAMERECT_LEFT, y,
> (STR_TOWN_GROWTH_HEADER_CARGO + widget - WID_CB_CARGO_NAME), TC_FROMSTRING,
> (widget == WID_CB_CARGO_NAME) ? SA_LEFT : SA_RIGHT);
>
> y += (FONT_HEIGHT_NORMAL + 2);
> }
>
> const CargoSpec *cargos = CargoSpec::Get(cargox.id);
> //cargo needed?
> if (!cargos->IsValid() || CB_GetReq(cargos->Index()) == 0) continue;
>
> from = CB_GetFrom(cargos->Index());
>
> switch(widget) {
> case WID_CB_CARGO_NAME: {
> int rect_x = (r.left + WD_FRAMERECT_LEFT);
> GfxFillRect(rect_x, y + 1, rect_x + 8, y + 6, 0);
> GfxFillRect(rect_x + 1, y + 2, rect_x + 7, y + 5, cargos->legend_colour);
>
> SetDParam(0, cargos->name);
> DrawString(r.left + WD_FRAMERECT_LEFT + 14, r.right - WD_FRAMERECT_LEFT, y, STR_TOWN_CB_CARGO_NAME);
> break;
> }
> case WID_CB_CARGO_AMOUNT: {
> delivered = this->town->new_act_cargo[cargos->Index()];
> requirements = CB_GetTownReq(this->town->cache.population, CB_GetReq(cargos->Index()), from, true);
> SetDParam(0, delivered);
>
> //when required
> if (this->town->cache.population >= from) {
> if((delivered + (uint)this->town->storage[cargos->Index()]) >= requirements) string_to_draw = STR_TOWN_CB_CARGO_AMOUNT_GOOD;
> else string_to_draw = STR_TOWN_CB_CARGO_AMOUNT_BAD;
> }
> //when not required -> all faded
> else string_to_draw = STR_TOWN_CB_CARGO_AMOUNT_NOT;
>
> DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y, string_to_draw, TC_FROMSTRING, SA_RIGHT);
> break;
> }
> case WID_CB_CARGO_REQ: {
> requirements = CB_GetTownReq(this->town->cache.population, CB_GetReq(cargos->Index()), from, true);
> SetDParam(0, requirements);
> //when required
> string_to_draw = (this->town->cache.population >= from) ? STR_TOWN_CB_CARGO_REQ_YES : STR_TOWN_CB_CARGO_REQ_NOT;
> DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y, string_to_draw, TC_FROMSTRING, SA_RIGHT);
> break;
> }
> case WID_CB_CARGO_PREVIOUS: {
> requirements = CB_GetTownReq(this->town->cache.population, CB_GetReq(cargos->Index()), from, true);
> SetDParam(0, this->town->act_cargo[cargos->Index()]);
> if (this->town->cache.population >= from){
> if (this->town->delivered_enough[cargos->Index()]) {
> string_to_draw = (this->town->act_cargo[cargos->Index()] >= requirements) ? STR_TOWN_CB_CARGO_PREVIOUS_YES : STR_TOWN_CB_CARGO_PREVIOUS_EDGE;
> }
> else string_to_draw = STR_TOWN_CB_CARGO_PREVIOUS_BAD;
> }
> else string_to_draw = STR_TOWN_CB_CARGO_PREVIOUS_NOT;
>
> DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y, string_to_draw, TC_FROMSTRING, SA_RIGHT);
> break;
> }
> case WID_CB_CARGO_STORE: {
> SetDParam(0, this->town->storage[cargos->Index()]);
> if (CB_GetDecay(cargos->Index()) == 100) string_to_draw = STR_TOWN_CB_CARGO_STORE_DECAY; //when 100% decay
> else {
> if (this->town->cache.population >= from) string_to_draw = STR_TOWN_CB_CARGO_STORE_YES; //when required
> else string_to_draw = STR_TOWN_CB_CARGO_STORE_NOT;
> }
>
> DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y, string_to_draw, TC_FROMSTRING, SA_RIGHT);
> break;
> }
> case WID_CB_CARGO_STORE_PCT: {
> uint max_storage = CB_GetMaxTownStorage(this->town, cargos->Index());
> if (CB_GetDecay(cargos->Index()) == 100 || !max_storage) string_to_draw = STR_TOWN_CB_CARGO_STORE_DECAY; //when 100% decay
> else {
> SetDParam(0, 100 * this->town->storage[cargos->Index()] / max_storage);
> if (this->town->cache.population >= from) string_to_draw = STR_TOWN_CB_CARGO_STORE_PCT_YES; //when required
> else string_to_draw = STR_TOWN_CB_CARGO_STORE_PCT_NOT;
> }
>
> DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y, string_to_draw, TC_FROMSTRING, SA_RIGHT);
> break;
> }
> case WID_CB_CARGO_FROM: {
> SetDParam(0, from);
> string_to_draw = (this->town->cache.population >= from) ? STR_TOWN_CB_CARGO_FROM_YES : STR_TOWN_CB_CARGO_FROM_NOT; //when required
>
> DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, string_to_draw, TC_FROMSTRING, SA_RIGHT);
> break;
> }
> //last case
> }
> //switch
> y += (FONT_HEIGHT_NORMAL + 2);
> //cargo needed?
> }
> //for cycle
> }
> break;
> }
> /* Citybuilder things enabled*/
> }
>
> virtual void OnPaint() {
> if (!this->IsShaded()) {
> int plane = CB_Enabled() ? CBTWP_MP_CB : CBTWP_MP_GOALS;
> NWidgetStacked *wi = this->GetWidget(WID_CB_SELECT_REQUIREMENTS);
> if (plane != wi->shown_plane) {
> wi->SetDisplayedPlane(plane);
> this->InvalidateData();
> return;
> }
> }
> this->DrawWidgets();
> }
>
>
> virtual EventState OnHotkey(int hotkey)
> {
> TownExecuteAction(this->town, hotkey);
> return ES_HANDLED;
> }
>
> static HotkeyList hotkeys;
> };
>
> HotkeyList CBTownWindow::hotkeys("town_gui", town_hotkeys);
>
> static const NWidgetPart _nested_cb_town_widgets[] = {
> NWidget(NWID_HORIZONTAL),
> NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
> NWidget(WWT_CAPTION, COLOUR_BROWN, WID_TV_CAPTION), SetDataTip(STR_TOWN_VIEW_CB_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
> NWidget(WWT_SHADEBOX, COLOUR_BROWN),
> NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN),
> NWidget(WWT_STICKYBOX, COLOUR_BROWN),
> EndContainer(),
> NWidget(WWT_PANEL, COLOUR_BROWN),
> NWidget(NWID_VERTICAL),
> NWidget(NWID_SPACER), SetMinimalSize(0, 5), SetResize(1, 0), SetFill(1, 0),
> NWidget(NWID_HORIZONTAL),
> NWidget(WWT_EMPTY, COLOUR_BROWN, WID_CB_DETAILS), SetMinimalSize(66, 0), SetResize(1, 0), SetFill(1, 0),
> NWidget(NWID_VERTICAL),
> NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
> NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_CB_ADVERT),SetMinimalSize(33, 12),SetFill(1, 0), SetDataTip(STR_CB_LARGE_ADVERTISING_CAMPAIGN, 0),
> NWidget(NWID_SPACER), SetMinimalSize(2, 0),
> NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_CB_FUND),SetMinimalSize(33, 12),SetFill(1, 0), SetDataTip(STR_CB_NEW_BUILDINGS, 0),
> NWidget(NWID_SPACER), SetMinimalSize(4, 0),
> EndContainer(),
> NWidget(NWID_SPACER), SetMinimalSize(0, 2),
> NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
> NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_CB_ADVERT_REGULAR),SetMinimalSize(33, 12),SetFill(1, 0), SetDataTip(STR_CB_ADVERT_REGULAR, STR_CB_ADVERT_REGULAR_TT),
> NWidget(NWID_SPACER), SetMinimalSize(2, 0),
> NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_CB_FUND_REGULAR),SetMinimalSize(33, 12),SetFill(1, 0), SetDataTip(STR_CB_FUND_REGULAR, STR_CB_FUND_REGULAR_TT),
> NWidget(NWID_SPACER), SetMinimalSize(4, 0),
> EndContainer(),
> NWidget(NWID_SPACER), SetMinimalSize(0, 2),
> NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
> NWidget(NWID_SPACER), SetMinimalSize(33, 0), SetFill(1, 0),
> NWidget(NWID_SPACER), SetMinimalSize(2, 0),
> NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_CB_POWERFUND),SetMinimalSize(33, 12),SetFill(1, 0), SetDataTip(STR_CB_POWERFUND, STR_CB_POWERFUND_TT),
> NWidget(NWID_SPACER), SetMinimalSize(4, 0),
> EndContainer(),
> EndContainer(),
> EndContainer(),
> NWidget(NWID_SPACER), SetMinimalSize(0, 5), SetResize(1, 0), SetFill(1, 0),
> NWidget(NWID_SELECTION, INVALID_COLOUR, WID_CB_SELECT_REQUIREMENTS),
> NWidget(WWT_EMPTY, COLOUR_BROWN, WID_CB_GOALS),SetMinimalSize(50 + 35 + 35 + 40 + 35 + 30, 0), SetResize(1, 0), SetFill(1, 0),
> NWidget(NWID_HORIZONTAL),
> NWidget(WWT_EMPTY, COLOUR_BROWN, WID_CB_CARGO_NAME),SetMinimalSize(50, 0), SetResize(0, 0), SetFill(1, 0),
> NWidget(WWT_EMPTY, COLOUR_BROWN, WID_CB_CARGO_AMOUNT),SetMinimalSize(35, 0), SetResize(1, 0), SetFill(0, 0),
> NWidget(WWT_EMPTY, COLOUR_BROWN, WID_CB_CARGO_REQ),SetMinimalSize(35, 0), SetResize(1, 0), SetFill(0, 0),
> NWidget(WWT_EMPTY, COLOUR_BROWN, WID_CB_CARGO_PREVIOUS),SetMinimalSize(40, 0), SetResize(1, 0), SetFill(0, 0),
> NWidget(WWT_EMPTY, COLOUR_BROWN, WID_CB_CARGO_STORE),SetMinimalSize(35, 0), SetResize(1, 0), SetFill(0, 0),
> NWidget(WWT_EMPTY, COLOUR_BROWN, WID_CB_CARGO_STORE_PCT),SetMinimalSize(30, 0), SetResize(1, 0), SetFill(0, 0),
> EndContainer(),
> EndContainer(),
> NWidget(NWID_SPACER), SetMinimalSize(0, 0), SetResize(1, 0), SetFill(1, 1),
> EndContainer(),
> EndContainer(),
> NWidget(NWID_HORIZONTAL),
> NWidget(NWID_HORIZONTAL),
> NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_CB_CENTER_VIEW), SetMinimalSize(30, 12), SetFill(1, 1), SetResize(1, 0), SetDataTip(STR_BUTTON_LOCATION, STR_TOWN_VIEW_CENTER_TOOLTIP),
> NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_CB_TOWN_VIEW), SetMinimalSize(40, 12), SetFill(1, 1), SetResize(1, 0), SetDataTip(STR_CB_GUI_TOWN_VIEW_BUTTON, STR_CB_GUI_TOWN_VIEW_TOOLTIP),
> NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_CB_SHOW_AUTHORITY), SetMinimalSize(40, 12), SetFill(1, 1), SetResize(1, 0), SetDataTip(STR_TOWN_VIEW_LOCAL_AUTHORITY_BUTTON, STR_TOWN_VIEW_LOCAL_AUTHORITY_TOOLTIP),
> EndContainer(),
> NWidget(WWT_RESIZEBOX, COLOUR_BROWN),
> EndContainer(),
> };
>
> static WindowDesc _cb_town_desc(
> WDP_AUTO, "cb_town", 160, 30,
> WC_CB_TOWN, WC_NONE,
> 0,
> _nested_cb_town_widgets, lengthof(_nested_cb_town_widgets),
> &CBTownWindow::hotkeys
> );
>
> void ShowCBTownWindow(uint town) {
> AllocateWindowDescFront(&_cb_town_desc, town);
diff -r -B -X .diff-exclude vanilla/src/town.h cmclient/src/town.h
15a16,19
> #include "station_base.h"
> #include "openttd.h"
> #include "table/strings.h"
> #include "company_func.h"
19a24
> #include